## Automatically generated incremental diff
## From:   linux-2.4.25-pre4
## To:     linux-2.4.25-pre5
## Robot:  $Id: make-incremental-diff,v 1.12 2004/01/06 07:19:36 hpa Exp $

diff -urN linux-2.4.25-pre4/Documentation/Configure.help linux-2.4.25-pre5/Documentation/Configure.help
--- linux-2.4.25-pre4/Documentation/Configure.help	2004-01-15 12:10:14.000000000 -0800
+++ linux-2.4.25-pre5/Documentation/Configure.help	2004-01-15 12:10:22.000000000 -0800
@@ -11155,9 +11155,6 @@
   You must say Y to "/proc file system support" (CONFIG_PROC_FS) to
   use this driver.
 
-  If you want to compile this as a module, say M and read
-  <file:Documentation/modules.txt>.  The module will be called comx.o.
-
 Support for COMX/CMX/HiCOMX boards
 CONFIG_COMX_HW_COMX
   Hardware driver for the 'CMX', 'COMX' and 'HiCOMX' boards from the
@@ -23900,7 +23897,7 @@
              PCMCIA interface (example: IDIF860 systems)
 
 Use SMC2 for UART
-CONFIG_SMC2_UART
+CONFIG_8xx_SMC2
   If you would like to use SMC2 as a serial port, say Y here.
 
   If in doubt, say Y here.
@@ -27311,16 +27308,11 @@
   will run on any supported IA-64 system.  However, if you configure
   a kernel for your specific system, it will be faster and smaller.
 
-  To find out what type of IA-64 system you have, you may want to
-  check the IA-64 Linux web site at <http://www.linux-ia64.org/>.
-  As of the time of this writing, most hardware is DIG compliant,
-  so the "DIG-compliant" option is usually the right choice.
-
-  HP-simulator   For the HP simulator (<http://software.hp.com/ia64linux/>).
-  HP-zx1	 For HP zx1 Platforms.
-  SN1            For SGI SN1 Platforms.
-  SN2            For SGI SN2 Platforms.
-  DIG-compliant  For DIG ("Developer's Interface Guide") compliant systems.
+  generic        For any supported IA-64 system
+  DIG-compliant  For DIG ("Developer's Interface Guide") compliant systems
+  HP             For HP systems
+  SGI-SN2        For SGI SN2 systems
+  Ski-simulator  For the HP simulator (<http://www.hpl.hp.com/research/linux/ski/>)
 
   If you don't know what to do, choose "generic".
 
diff -urN linux-2.4.25-pre4/Makefile linux-2.4.25-pre5/Makefile
--- linux-2.4.25-pre4/Makefile	2004-01-15 12:10:14.000000000 -0800
+++ linux-2.4.25-pre5/Makefile	2004-01-15 12:10:22.000000000 -0800
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
 SUBLEVEL = 25
-EXTRAVERSION = -pre4
+EXTRAVERSION = -pre5
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
diff -urN linux-2.4.25-pre4/arch/i386/kernel/microcode.c linux-2.4.25-pre5/arch/i386/kernel/microcode.c
--- linux-2.4.25-pre4/arch/i386/kernel/microcode.c	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.25-pre5/arch/i386/kernel/microcode.c	2004-01-15 12:10:22.000000000 -0800
@@ -57,351 +57,456 @@
  *		nature of implementation.
  *	1.11	22 Mar 2002 Tigran Aivazian <tigran@veritas.com>
  *		Fix the panic when writing zero-length microcode chunk.
+ *	1.12	29 Sep 2003 Nitin Kamble <nitin.a.kamble@intel.com>, 
+ *		Jun Nakajima <jun.nakajima@intel.com>
+ *		Support for the microcode updates in the new format.
+ *	1.13	10 Oct 2003 Tigran Aivazian <tigran@veritas.com>
+ *		Removed ->read() method and obsoleted MICROCODE_IOCFREE ioctl
+ *		because we no longer hold a copy of applied microcode 
+ *		in kernel memory.
  */
 
+
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/miscdevice.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/spinlock.h>
+#include <linux/mm.h>
 
 #include <asm/msr.h>
 #include <asm/uaccess.h>
 #include <asm/processor.h>
 
-
-static spinlock_t microcode_update_lock = SPIN_LOCK_UNLOCKED;
-
-#define MICROCODE_VERSION 	"1.11"
-
 MODULE_DESCRIPTION("Intel CPU (IA-32) microcode update driver");
 MODULE_AUTHOR("Tigran Aivazian <tigran@veritas.com>");
 MODULE_LICENSE("GPL");
-EXPORT_NO_SYMBOLS;
-
-#define MICRO_DEBUG 0
 
+#define MICROCODE_VERSION 	"1.13"
+#define MICRO_DEBUG 		1
 #if MICRO_DEBUG
-#define printf(x...) printk(##x)
+#define dprintk(x...) printk(KERN_INFO x)
 #else
-#define printf(x...)
+#define dprintk(x...)
 #endif
 
-/* VFS interface */
-static int microcode_open(struct inode *, struct file *);
-static ssize_t microcode_read(struct file *, char *, size_t, loff_t *);
-static ssize_t microcode_write(struct file *, const char *, size_t, loff_t *);
-static int microcode_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
-
-static int do_microcode_update(void);
-static void do_update_one(void *);
-
-/* read()/write()/ioctl() are serialized on this */
-static DECLARE_RWSEM(microcode_rwsem);
-
-static struct microcode *microcode; /* array of 2048byte microcode blocks */
-static unsigned int microcode_num;  /* number of chunks in microcode */
-static char *mc_applied;            /* array of applied microcode blocks */
-static unsigned int mc_fsize;       /* file size of /dev/cpu/microcode */
+#define DEFAULT_UCODE_DATASIZE 	(2000) 	  /* 2000 bytes */
+#define MC_HEADER_SIZE		(sizeof (microcode_header_t))  	  /* 48 bytes */
+#define DEFAULT_UCODE_TOTALSIZE (DEFAULT_UCODE_DATASIZE + MC_HEADER_SIZE) /* 2048 bytes */
+#define EXT_HEADER_SIZE		(sizeof (struct extended_sigtable)) /* 20 bytes */
+#define EXT_SIGNATURE_SIZE	(sizeof (struct extended_signature)) /* 12 bytes */
+#define DWSIZE			(sizeof (u32))
+#define get_totalsize(mc) \
+	(((microcode_t *)mc)->hdr.totalsize ? \
+	 ((microcode_t *)mc)->hdr.totalsize : DEFAULT_UCODE_TOTALSIZE)
+#define get_datasize(mc) \
+	(((microcode_t *)mc)->hdr.datasize ? \
+	 ((microcode_t *)mc)->hdr.datasize : DEFAULT_UCODE_DATASIZE)
+#define sigmatch(s1, s2, p1, p2) (((s1) == (s2)) && ((p1) & (p2)))
+#define exttable_size(et) ((et)->count * EXT_SIGNATURE_SIZE + EXT_HEADER_SIZE)
 
-/* we share file_operations between misc and devfs mechanisms */
-static struct file_operations microcode_fops = {
-	owner:		THIS_MODULE,
-	read:		microcode_read,
-	write:		microcode_write,
-	ioctl:		microcode_ioctl,
-	open:		microcode_open,
-};
+/* serialize access to the physical write to MSR 0x79 */
+static spinlock_t microcode_update_lock = SPIN_LOCK_UNLOCKED;
 
-static struct miscdevice microcode_dev = {
-	minor: MICROCODE_MINOR,
-	name:	"microcode",
-	fops:	&microcode_fops,
-};
+/* no concurrent ->write()s are allowed on /dev/cpu/microcode */
+static DECLARE_MUTEX(microcode_sem);
 
-static devfs_handle_t devfs_handle;
+static void *user_buffer;		/* user area microcode data buffer */
+static unsigned int user_buffer_size;	/* it's size */
 
-static int __init microcode_init(void)
+typedef enum mc_error_code {
+	MC_SUCCESS 	= 0,
+	MC_NOTFOUND 	= 1,
+	MC_MARKED 	= 2,
+	MC_ALLOCATED 	= 3,
+} mc_error_code_t;
+
+static struct ucode_cpu_info {
+	unsigned int sig;
+	unsigned int pf;
+	unsigned int rev;
+	unsigned int cksum;
+	mc_error_code_t err;
+	microcode_t *mc;
+} ucode_cpu_info[NR_CPUS];
+				
+static int microcode_open (struct inode *unused1, struct file *unused2)
 {
-	int error;
+	return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
+}
 
-	error = misc_register(&microcode_dev);
-	if (error)
-		printk(KERN_WARNING 
-			"microcode: can't misc_register on minor=%d\n",
-			MICROCODE_MINOR);
+static void collect_cpu_info (void *unused)
+{
+	int cpu_num = smp_processor_id();
+	struct cpuinfo_x86 *c = cpu_data + cpu_num;
+	struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;
+	unsigned int val[2];
+
+	uci->sig = uci->pf = uci->rev = uci->cksum = 0;
+	uci->err = MC_NOTFOUND; 
+	uci->mc = NULL;
+
+	if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6 ||
+	    	cpu_has(c, X86_FEATURE_IA64)) {
+		printk(KERN_ERR "microcode: CPU%d not a capable Intel processor\n", cpu_num);
+		return;
+	} else {
+		uci->sig = cpuid_eax(0x00000001);
 
-	devfs_handle = devfs_register(NULL, "cpu/microcode",
-			DEVFS_FL_DEFAULT, 0, 0, S_IFREG | S_IRUSR | S_IWUSR, 
-			&microcode_fops, NULL);
-	if (devfs_handle == NULL && error) {
-		printk(KERN_ERR "microcode: failed to devfs_register()\n");
+		if ((c->x86_model >= 5) || (c->x86 > 6)) {
+			/* get processor flags from MSR 0x17 */
+			rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]);
+			uci->pf = 1 << ((val[1] >> 18) & 7);
+		}
+	}
+
+	wrmsr(MSR_IA32_UCODE_REV, 0, 0);
+	__asm__ __volatile__ ("cpuid" : : : "ax", "bx", "cx", "dx");
+	/* get the current revision from MSR 0x8B */
+	rdmsr(MSR_IA32_UCODE_REV, val[0], uci->rev);
+	dprintk("microcode: collect_cpu_info : sig=0x%x, pf=0x%x, rev=0x%x\n", 
+			uci->sig, uci->pf, uci->rev);
+}
+
+static inline void mark_microcode_update (int cpu_num, microcode_header_t *mc_header, int sig, int pf, int cksum)
+{
+	struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;
+
+	dprintk("Microcode Found.\n");
+	dprintk("   Header Revision 0x%x\n", mc_header->hdrver);
+	dprintk("   Loader Revision 0x%x\n", mc_header->ldrver);
+	dprintk("   Revision 0x%x \n", mc_header->rev);
+	dprintk("   Date %x/%x/%x\n",
+		((mc_header->date >> 24 ) & 0xff),
+		((mc_header->date >> 16 ) & 0xff),
+		(mc_header->date & 0xFFFF));
+	dprintk("   Signature 0x%x\n", sig);
+	dprintk("   Type 0x%x Family 0x%x Model 0x%x Stepping 0x%x\n",
+		((sig >> 12) & 0x3),
+		((sig >> 8) & 0xf),
+		((sig >> 4) & 0xf),
+		((sig & 0xf)));
+	dprintk("   Processor Flags 0x%x\n", pf);
+	dprintk("   Checksum 0x%x\n", cksum);
+
+	if (mc_header->rev < uci->rev) {
+		printk(KERN_ERR "microcode: CPU%d not 'upgrading' to earlier revision"
+		       " 0x%x (current=0x%x)\n", cpu_num, mc_header->rev, uci->rev);
+		goto out;
+	} else if (mc_header->rev == uci->rev) {
+		/* notify the caller of success on this cpu */
+		uci->err = MC_SUCCESS;
+		printk(KERN_ERR "microcode: CPU%d already at revision"
+			" 0x%x (current=0x%x)\n", cpu_num, mc_header->rev, uci->rev);
 		goto out;
 	}
-	error = 0;
-	printk(KERN_INFO 
-		"IA-32 Microcode Update Driver: v%s <tigran@veritas.com>\n", 
-		MICROCODE_VERSION);
 
+	dprintk("microcode: CPU%d found a matching microcode update with "
+		" revision 0x%x (current=0x%x)\n", cpu_num, mc_header->rev, uci->rev);
+	uci->cksum = cksum;
+	uci->pf = pf; /* keep the original mc pf for cksum calculation */
+	uci->err = MC_MARKED; /* found the match */
 out:
-	return error;
+	return;
 }
 
-static void __exit microcode_exit(void)
+static int find_matching_ucodes (void) 
 {
-	misc_deregister(&microcode_dev);
-	devfs_unregister(devfs_handle);
-	if (mc_applied)
-		kfree(mc_applied);
-	printk(KERN_INFO "IA-32 Microcode Update Driver v%s unregistered\n", 
-			MICROCODE_VERSION);
-}
+	int cursor = 0;
+	int error = 0;
 
-module_init(microcode_init)
-module_exit(microcode_exit)
+	while (cursor + MC_HEADER_SIZE < user_buffer_size) {
+		microcode_header_t mc_header;
+		void *newmc = NULL;
+		int i, sum, cpu_num, allocated_flag, total_size, data_size, ext_table_size;
+
+		if (copy_from_user(&mc_header, user_buffer + cursor, MC_HEADER_SIZE)) {
+			printk(KERN_ERR "microcode: error! Can not read user data\n");
+			error = -EFAULT;
+			goto out;
+		}
 
-static int microcode_open(struct inode *unused1, struct file *unused2)
-{
-	return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
-}
+		total_size = get_totalsize(&mc_header);
+		if ((cursor + total_size > user_buffer_size) || (total_size < DEFAULT_UCODE_TOTALSIZE)) {
+			printk(KERN_ERR "microcode: error! Bad data in microcode data file\n");
+			error = -EINVAL;
+			goto out;
+		}
 
-/*
- * update_req[cpu].err is set to 1 if update failed on 'cpu', 0 otherwise
- * if err==0, microcode[update_req[cpu].slot] points to applied block of microcode
- */
-struct update_req {
-	int err;
-	int slot;
-} update_req[NR_CPUS];
+		data_size = get_datasize(&mc_header);
+		if ((data_size + MC_HEADER_SIZE > total_size) || (data_size < DEFAULT_UCODE_DATASIZE)) {
+			printk(KERN_ERR "microcode: error! Bad data in microcode data file\n");
+			error = -EINVAL;
+			goto out;
+		}
 
-static int do_microcode_update(void)
-{
-	int i, error = 0, err;
-	struct microcode *m;
+		if (mc_header.ldrver != 1 || mc_header.hdrver != 1) {
+			printk(KERN_ERR "microcode: error! Unknown microcode update format\n");
+			error = -EINVAL;
+			goto out;
+		}
+		
+		for (cpu_num = 0; cpu_num < smp_num_cpus; cpu_num++) {
+			struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;
+			if (uci->err != MC_NOTFOUND) /* already found a match or not an online cpu*/
+				continue;
 
-	if (smp_call_function(do_update_one, NULL, 1, 1) != 0) {
-		printk(KERN_ERR "microcode: IPI timeout, giving up\n");
-		return -EIO;
-	}
-	do_update_one(NULL);
+			if (sigmatch(mc_header.sig, uci->sig, mc_header.pf, uci->pf))
+				mark_microcode_update(cpu_num, &mc_header, mc_header.sig, mc_header.pf, mc_header.cksum);
+		}
 
-	for (i=0; i<smp_num_cpus; i++) {
-		err = update_req[i].err;
-		error += err;
-		if (!err) {
-			m = (struct microcode *)mc_applied + i;
-			memcpy(m, &microcode[update_req[i].slot], sizeof(struct microcode));
+		ext_table_size = total_size - (MC_HEADER_SIZE + data_size);
+		if (ext_table_size) {
+			struct extended_sigtable ext_header;
+			struct extended_signature ext_sig;
+			int ext_sigcount;
+
+			if ((ext_table_size < EXT_HEADER_SIZE) 
+					|| ((ext_table_size - EXT_HEADER_SIZE) % EXT_SIGNATURE_SIZE)) {
+				printk(KERN_ERR "microcode: error! Bad data in microcode data file\n");
+				error = -EINVAL;
+				goto out;
+			}
+			if (copy_from_user(&ext_header, user_buffer + cursor 
+					+ MC_HEADER_SIZE + data_size, EXT_HEADER_SIZE)) {
+				printk(KERN_ERR "microcode: error! Can not read user data\n");
+				error = -EFAULT;
+				goto out;
+			}
+			if (ext_table_size != exttable_size(&ext_header)) {
+				printk(KERN_ERR "microcode: error! Bad data in microcode data file\n");
+				error = -EFAULT;
+				goto out;
+			}
+
+			ext_sigcount = ext_header.count;
+			
+			for (i = 0; i < ext_sigcount; i++) {
+				if (copy_from_user(&ext_sig, user_buffer + cursor + MC_HEADER_SIZE + data_size + EXT_HEADER_SIZE 
+						+ EXT_SIGNATURE_SIZE * i, EXT_SIGNATURE_SIZE)) {
+					printk(KERN_ERR "microcode: error! Can not read user data\n");
+					error = -EFAULT;
+					goto out;
+				}
+				for (cpu_num = 0; cpu_num < smp_num_cpus; cpu_num++) {
+					struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;
+					if (uci->err != MC_NOTFOUND) /* already found a match or not an online cpu*/
+						continue;
+					if (sigmatch(ext_sig.sig, uci->sig, ext_sig.pf, uci->pf)) {
+						mark_microcode_update(cpu_num, &mc_header, ext_sig.sig, ext_sig.pf, ext_sig.cksum);
+					}
+				}
+			}
 		}
-	}
+		/* now check if any cpu has matched */
+		for (cpu_num = 0, allocated_flag = 0, sum = 0; cpu_num < smp_num_cpus; cpu_num++) {
+			if (ucode_cpu_info[cpu_num].err == MC_MARKED) { 
+				struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;
+				if (!allocated_flag) {
+					allocated_flag = 1;
+					newmc = vmalloc(total_size);
+					if (!newmc) {
+						printk(KERN_ERR "microcode: error! Can not allocate memory\n");
+						error = -ENOMEM;
+						goto out;
+					}
+					if (copy_from_user(newmc + MC_HEADER_SIZE, 
+								user_buffer + cursor + MC_HEADER_SIZE, 
+								total_size - MC_HEADER_SIZE)) {
+						printk(KERN_ERR "microcode: error! Can not read user data\n");
+						vfree(newmc);
+						error = -EFAULT;
+						goto out;
+					}
+					memcpy(newmc, &mc_header, MC_HEADER_SIZE);
+					/* check extended table checksum */
+					if (ext_table_size) {
+						int * ext_tablep;
+						int ext_table_sum = 0;
+						i = ext_table_size / DWSIZE;
+						ext_tablep = (((void *) newmc) + MC_HEADER_SIZE + data_size);
+						while (i--) ext_table_sum += ext_tablep[i];
+						if (ext_table_sum) {
+							printk(KERN_WARNING "microcode: aborting, bad extended signature table checksum\n");
+							vfree(newmc);
+							error = -EINVAL;
+							goto out;
+						}
+					}
+
+					/* calculate the checksum */
+					i = (MC_HEADER_SIZE + data_size) / DWSIZE;
+					while (i--) sum += ((int *)newmc)[i];
+					sum -= (mc_header.sig + mc_header.pf + mc_header.cksum);
+				}
+				ucode_cpu_info[cpu_num].mc = newmc;
+				ucode_cpu_info[cpu_num].err = MC_ALLOCATED; /* mc updated */
+				if (sum + uci->sig + uci->pf + uci->cksum != 0) {
+					printk(KERN_ERR "microcode: CPU%d aborting, bad checksum\n", cpu_num);
+					error = -EINVAL;
+					goto out;
+				}
+			}
+		}
+		cursor += total_size; /* goto the next update patch */
+	} /* end of while */
+out:
 	return error;
 }
 
-static void do_update_one(void *unused)
+static void do_update_one (void * unused)
 {
-	int cpu_num = smp_processor_id();
-	struct cpuinfo_x86 *c = cpu_data + cpu_num;
-	struct update_req *req = update_req + cpu_num;
-	unsigned int pf = 0, val[2], rev, sig;
 	unsigned long flags;
-	int i;
-
-	req->err = 1; /* assume update will fail on this cpu */
+	unsigned int val[2];
+	int cpu_num = smp_processor_id();
+	struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;
 
-	if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6 ||
-		test_bit(X86_FEATURE_IA64, &c->x86_capability)){
-		printk(KERN_ERR "microcode: CPU%d not a capable Intel processor\n", cpu_num);
+	if (uci->mc == NULL) {
+		printk(KERN_INFO "microcode: No suitable data for cpu %d\n", cpu_num);
 		return;
 	}
 
-	sig = c->x86_mask + (c->x86_model<<4) + (c->x86<<8);
+	/* serialize access to the physical write to MSR 0x79 */
+	spin_lock_irqsave(&microcode_update_lock, flags);          
 
-	if ((c->x86_model >= 5) || (c->x86 > 6)) {
-		/* get processor flags from MSR 0x17 */
-		rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]);
-		pf = 1 << ((val[1] >> 18) & 7);
-	}
-
-	for (i=0; i<microcode_num; i++)
-		if (microcode[i].sig == sig && microcode[i].pf == pf &&
-		    microcode[i].ldrver == 1 && microcode[i].hdrver == 1) {
-			int sum = 0;
-			struct microcode *m = &microcode[i];
-			unsigned int *sump = (unsigned int *)(m+1);
-
-			printf("Microcode\n");
-			printf("   Header Revision %d\n",microcode[i].hdrver);
-			printf("   Date %x/%x/%x\n",
-				((microcode[i].date >> 24 ) & 0xff),
-				((microcode[i].date >> 16 ) & 0xff),
-				(microcode[i].date & 0xFFFF));
-			printf("   Type %x Family %x Model %x Stepping %x\n",
-				((microcode[i].sig >> 12) & 0x3),
-				((microcode[i].sig >> 8) & 0xf),
-				((microcode[i].sig >> 4) & 0xf),
-				((microcode[i].sig & 0xf)));
-			printf("   Checksum %x\n",microcode[i].cksum);
-			printf("   Loader Revision %x\n",microcode[i].ldrver);
-			printf("   Processor Flags %x\n\n",microcode[i].pf);
-
-			req->slot = i;
-
-			/* serialize access to update decision */
-			spin_lock_irqsave(&microcode_update_lock, flags);          
-
-			/* trick, to work even if there was no prior update by the BIOS */
-			wrmsr(MSR_IA32_UCODE_REV, 0, 0);
-			__asm__ __volatile__ ("cpuid" : : : "ax", "bx", "cx", "dx");
+	/* write microcode via MSR 0x79 */
+	wrmsr(MSR_IA32_UCODE_WRITE, (unsigned int)(uci->mc->bits), 0);
+	wrmsr(MSR_IA32_UCODE_REV, 0, 0);
+
+	__asm__ __volatile__ ("cpuid" : : : "ax", "bx", "cx", "dx");
+	/* get the current revision from MSR 0x8B */
+	rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]);
+
+	/* notify the caller of success on this cpu */
+	uci->err = MC_SUCCESS;
+	spin_unlock_irqrestore(&microcode_update_lock, flags);
+	printk(KERN_INFO "microcode: CPU%d updated from revision "
+	       "0x%x to 0x%x, date = %08x \n", 
+	       cpu_num, uci->rev, val[1], uci->mc->hdr.date);
+	return;
+}
 
-			/* get current (on-cpu) revision into rev (ignore val[0]) */
-			rdmsr(MSR_IA32_UCODE_REV, val[0], rev);
-			
-			if (microcode[i].rev < rev) {
-				spin_unlock_irqrestore(&microcode_update_lock, flags);
-				printk(KERN_ERR 
-				       "microcode: CPU%d not 'upgrading' to earlier revision"
-				       " %d (current=%d)\n", cpu_num, microcode[i].rev, rev);
-				return;
-			} else if (microcode[i].rev == rev) {
-				/* notify the caller of success on this cpu */
-				req->err = 0;
-				spin_unlock_irqrestore(&microcode_update_lock, flags);
-				printk(KERN_ERR 
-					"microcode: CPU%d already at revision"
-					" %d (current=%d)\n", cpu_num, microcode[i].rev, rev);
-				return;
-			}
+static int do_microcode_update (void)
+{
+	int i, error;
 
-			/* Verify the checksum */
-			while (--sump >= (unsigned int *)m)
-				sum += *sump;
-			if (sum != 0) {
-				req->err = 1;
-				spin_unlock_irqrestore(&microcode_update_lock, flags);
-				printk(KERN_ERR "microcode: CPU%d aborting, "
-				       "bad checksum\n", cpu_num);
-				return;
-			}
-			
-			/* write microcode via MSR 0x79 */
-			wrmsr(MSR_IA32_UCODE_WRITE, (unsigned int)(m->bits), 0);
+	if (smp_call_function(collect_cpu_info, NULL, 1, 1) != 0) {
+		printk(KERN_ERR "microcode: Error! Could not run on all processors\n");
+		error = -EIO;
+		goto out;
+	}
+	collect_cpu_info(NULL);
 
-			/* serialize */
-			__asm__ __volatile__ ("cpuid" : : : "ax", "bx", "cx", "dx");
+	if ((error = find_matching_ucodes())) {
+		printk(KERN_ERR "microcode: Error in the microcode data\n");
+		goto out_free;
+	}
 
-			/* get the current revision from MSR 0x8B */
-			rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]);
+	if (smp_call_function(do_update_one, NULL, 1, 1) != 0) {
+		printk(KERN_ERR "microcode: Error! Could not run on all processors\n");
+		error = -EIO;
+	}
+	do_update_one(NULL);
 
-			/* notify the caller of success on this cpu */
-			req->err = 0;
-			spin_unlock_irqrestore(&microcode_update_lock, flags);
-			printk(KERN_INFO "microcode: CPU%d updated from revision "
-			       "%d to %d, date=%08x\n", 
-			       cpu_num, rev, val[1], microcode[i].date);
-			return;
+out_free:
+	for (i = 0; i < smp_num_cpus; i++) {
+		if (ucode_cpu_info[i].mc) {
+			int j;
+			void *tmp = ucode_cpu_info[i].mc;
+			vfree(tmp);
+			for (j = i; j < smp_num_cpus; j++) {
+				if (ucode_cpu_info[j].mc == tmp)
+					ucode_cpu_info[j].mc = NULL;
+			}
 		}
-	
-	printk(KERN_ERR
-	       "microcode: CPU%d no microcode found! (sig=%x, pflags=%d)\n", 
-	       cpu_num, sig, pf);
-}
-
-
-static ssize_t microcode_read(struct file *file, char *buf, size_t len, loff_t *ppos)
-{
-	ssize_t ret = 0;
-
-	down_read(&microcode_rwsem);
-	if (*ppos >= mc_fsize)
-		goto out;
-	if (*ppos + len > mc_fsize)
-		len = mc_fsize - *ppos;
-	ret = -EFAULT;
-	if (copy_to_user(buf, mc_applied + *ppos, len))
-		goto out;
-	*ppos += len;
-	ret = len;
+	}
 out:
-	up_read(&microcode_rwsem);
-	return ret;
+	return error;
 }
 
-static ssize_t microcode_write(struct file *file, const char *buf, size_t len, loff_t *ppos)
+static ssize_t microcode_write (struct file *file, const char *buf, size_t len, loff_t *ppos)
 {
 	ssize_t ret;
 
-	if (!len || len % sizeof(struct microcode) != 0) {
-		printk(KERN_ERR "microcode: can only write in N*%d bytes units\n", 
-			sizeof(struct microcode));
+	if (len < DEFAULT_UCODE_TOTALSIZE) {
+		printk(KERN_ERR "microcode: not enough data\n"); 
 		return -EINVAL;
 	}
+
 	if ((len >> PAGE_SHIFT) > num_physpages) {
 		printk(KERN_ERR "microcode: too much data (max %ld pages)\n", num_physpages);
 		return -EINVAL;
 	}
-	down_write(&microcode_rwsem);
-	if (!mc_applied) {
-		mc_applied = kmalloc(smp_num_cpus*sizeof(struct microcode),
-				GFP_KERNEL);
-		if (!mc_applied) {
-			up_write(&microcode_rwsem);
-			printk(KERN_ERR "microcode: out of memory for saved microcode\n");
-			return -ENOMEM;
-		}
-	}
-	
-	microcode_num = len/sizeof(struct microcode);
-	microcode = vmalloc(len);
-	if (!microcode) {
-		ret = -ENOMEM;
-		goto out_unlock;
-	}
-
-	if (copy_from_user(microcode, buf, len)) {
-		ret = -EFAULT;
-		goto out_fsize;
-	}
-
-	if(do_microcode_update()) {
-		ret = -EIO;
-		goto out_fsize;
-	} else {
-		mc_fsize = smp_num_cpus * sizeof(struct microcode);
+
+	down(&microcode_sem);
+
+	user_buffer = (void *) buf;
+	user_buffer_size = (int) len;
+
+	ret = do_microcode_update();
+	if (!ret)
 		ret = (ssize_t)len;
-	}
-out_fsize:
-	devfs_set_file_size(devfs_handle, mc_fsize);
-	vfree(microcode);
-out_unlock:
-	up_write(&microcode_rwsem);
+
+	up(&microcode_sem);
+
 	return ret;
 }
 
-static int microcode_ioctl(struct inode *inode, struct file *file, 
+static int microcode_ioctl (struct inode *inode, struct file *file, 
 		unsigned int cmd, unsigned long arg)
 {
-	switch(cmd) {
+	switch (cmd) {
+		/* 
+		 *  XXX: will be removed after microcode_ctl 
+		 *  is updated to ignore failure of this ioctl()
+		 */
 		case MICROCODE_IOCFREE:
-			down_write(&microcode_rwsem);
-			if (mc_applied) {
-				int bytes = smp_num_cpus * sizeof(struct microcode);
-
-				devfs_set_file_size(devfs_handle, 0);
-				kfree(mc_applied);
-				mc_applied = NULL;
-				printk(KERN_INFO "microcode: freed %d bytes\n", bytes);
-				mc_fsize = 0;
-				up_write(&microcode_rwsem);
-				return 0;
-			}
-			up_write(&microcode_rwsem);
-			return -ENODATA;
-
+			return 0;
 		default:
-			printk(KERN_ERR "microcode: unknown ioctl cmd=%d\n", cmd);
 			return -EINVAL;
 	}
 	return -EINVAL;
 }
+
+static struct file_operations microcode_fops = {
+	.owner		= THIS_MODULE,
+	.write		= microcode_write,
+	.ioctl		= microcode_ioctl,
+	.open		= microcode_open,
+};
+
+static struct miscdevice microcode_dev = {
+	.minor		= MICROCODE_MINOR,
+	.name		= "microcode",
+	.fops		= &microcode_fops,
+};
+
+static int __init microcode_init (void)
+{
+	int error;
+
+	error = misc_register(&microcode_dev);
+	if (error) {
+		printk(KERN_ERR
+			"microcode: can't misc_register on minor=%d\n",
+			MICROCODE_MINOR);
+		return error;
+	}
+
+	printk(KERN_INFO 
+		"IA-32 Microcode Update Driver: v%s <tigran@veritas.com>\n", 
+		MICROCODE_VERSION);
+	return 0;
+}
+
+static void __exit microcode_exit (void)
+{
+	misc_deregister(&microcode_dev);
+	printk(KERN_INFO "IA-32 Microcode Update Driver v%s unregistered\n", 
+			MICROCODE_VERSION);
+}
+
+module_init(microcode_init)
+module_exit(microcode_exit)
diff -urN linux-2.4.25-pre4/arch/i386/kernel/smpboot.c linux-2.4.25-pre5/arch/i386/kernel/smpboot.c
--- linux-2.4.25-pre4/arch/i386/kernel/smpboot.c	2004-01-15 12:10:14.000000000 -0800
+++ linux-2.4.25-pre5/arch/i386/kernel/smpboot.c	2004-01-15 12:10:22.000000000 -0800
@@ -1106,7 +1106,7 @@
 	 */
 	Dprintk("CPU present map: %lx\n", phys_cpu_present_map);
 
-	for (bit = 0; bit < MAX_APICS; bit++) {
+	for (bit = 0; bit < BITS_PER_LONG; bit++) {
 		apicid = cpu_present_to_apicid(bit);
 		
 		/* don't try to boot BAD_APICID */
diff -urN linux-2.4.25-pre4/arch/ppc/8xx_io/Config.in linux-2.4.25-pre5/arch/ppc/8xx_io/Config.in
--- linux-2.4.25-pre4/arch/ppc/8xx_io/Config.in	2003-11-28 10:26:19.000000000 -0800
+++ linux-2.4.25-pre5/arch/ppc/8xx_io/Config.in	2004-01-15 12:10:22.000000000 -0800
@@ -27,8 +27,8 @@
 if [ "$CONFIG_SCC3_ENET" != "y" ]; then
   bool 'Use SMC1 for UART' CONFIG_8xx_SMC1
 fi
-bool 'Use SMC2 for UART' CONFIG_SMC2_UART
-if [ "$CONFIG_SMC2_UART" = "y" ]; then
+bool 'Use SMC2 for UART' CONFIG_8xx_SMC2
+if [ "$CONFIG_8xx_SMC2" = "y" ]; then
   bool 'Use Alternate SMC2 I/O (823/850)' CONFIG_ALTSMC2
   bool 'Use SMC2 for Console' CONFIG_CONS_SMC2
 fi
diff -urN linux-2.4.25-pre4/arch/ppc/boot/utils/mkbugboot.c linux-2.4.25-pre5/arch/ppc/boot/utils/mkbugboot.c
--- linux-2.4.25-pre4/arch/ppc/boot/utils/mkbugboot.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.25-pre5/arch/ppc/boot/utils/mkbugboot.c	2004-01-15 12:10:22.000000000 -0800
@@ -51,29 +51,22 @@
 /* size of read buffer */
 #define SIZE 0x1000
 
-#ifndef __sun__
-/* typedef long int32_t; */
-typedef unsigned long uint32_t;
-typedef unsigned short uint16_t;
-typedef unsigned char uint8_t;
-#endif
-
 /* PPCBUG ROM boot header */
 typedef struct bug_boot_header {
-  uint8_t	magic_word[4];		/* "BOOT" */
-  uint32_t	entry_offset;		/* Offset from top of header to code */
-  uint32_t	routine_length;		/* Length of code */
-  uint8_t	routine_name[8];	/* Name of the boot code */
+  unsigned char	magic_word[4];		/* "BOOT" */
+  unsigned long	entry_offset;		/* Offset from top of header to code */
+  unsigned long	routine_length;		/* Length of code */
+  unsigned char	routine_name[8];	/* Name of the boot code */
 } bug_boot_header_t;
 
 #define HEADER_SIZE	sizeof(bug_boot_header_t)
 
-uint32_t copy_image(int32_t in_fd, int32_t out_fd)
+unsigned long copy_image(int32_t in_fd, int32_t out_fd)
 {
-  uint8_t buf[SIZE];
+  unsigned char buf[SIZE];
   int n;
-  uint32_t image_size = 0;
-  uint8_t zero = 0;
+  unsigned long image_size = 0;
+  unsigned char zero = 0;
 
   lseek(in_fd, ELF_HEADER_SIZE, SEEK_SET);
 
@@ -95,9 +88,9 @@
   return image_size;
 }
 
-void write_bugboot_header(int32_t out_fd, uint32_t boot_size)
+void write_bugboot_header(int32_t out_fd, unsigned long boot_size)
 {
-  uint8_t header_block[HEADER_SIZE];
+  unsigned char header_block[HEADER_SIZE];
   bug_boot_header_t *bbh = (bug_boot_header_t *)&header_block[0];
 
   memset(header_block, 0, HEADER_SIZE);
@@ -112,16 +105,16 @@
   write(out_fd, header_block, HEADER_SIZE);
 }
 
-uint16_t calc_checksum(int32_t bug_fd)
+unsigned short calc_checksum(int32_t bug_fd)
 {
-  uint32_t checksum_var = 0;
-  uint8_t buf[2];
+  unsigned long checksum_var = 0;
+  unsigned char buf[2];
   int n;
 
   /* Checksum loop */
   while ( (n = read(bug_fd, buf, 2) ) )
   {
-    checksum_var = checksum_var + *(uint16_t *)buf;
+    checksum_var = checksum_var + *(unsigned short *)buf;
 
     /* If we carry out, mask it and add one to the checksum */
     if (checksum_var >> 16)
@@ -135,9 +128,9 @@
 {
   int32_t image_fd, bugboot_fd;
   int argptr = 1;
-  uint32_t kernel_size = 0;
-  uint16_t checksum = 0;
-  uint8_t bugbootname[256];
+  unsigned long kernel_size = 0;
+  unsigned short checksum = 0;
+  unsigned char bugbootname[256];
 
   if ( (argc != 3) )
   {
diff -urN linux-2.4.25-pre4/arch/ppc/config.in linux-2.4.25-pre5/arch/ppc/config.in
--- linux-2.4.25-pre4/arch/ppc/config.in	2004-01-15 12:10:14.000000000 -0800
+++ linux-2.4.25-pre5/arch/ppc/config.in	2004-01-15 12:10:22.000000000 -0800
@@ -62,7 +62,8 @@
 
 if [ "$CONFIG_40x" = "y" ]; then
     choice 'Machine Type'			\
-	 "Oak		CONFIG_OAK		\
+	 "CPCI405	CONFIG_CPCI405 		\
+	 Oak		CONFIG_OAK		\
 	 Walnut		CONFIG_WALNUT"		Walnut
 fi
 
@@ -188,6 +189,11 @@
 #
 # Set processor implementation based on board
 #
+
+  if [ "$CONFIG_CPCI405" = "y" ]; then
+    define_bool CONFIG_405GP y
+  fi
+
   if [ "$CONFIG_OAK" = "y" -o "$CONFIG_TIVO" = "y" ]; then
     define_bool CONFIG_403GCX y
   fi
diff -urN linux-2.4.25-pre4/arch/ppc/configs/IVMS8_defconfig linux-2.4.25-pre5/arch/ppc/configs/IVMS8_defconfig
--- linux-2.4.25-pre4/arch/ppc/configs/IVMS8_defconfig	2004-01-15 12:10:14.000000000 -0800
+++ linux-2.4.25-pre5/arch/ppc/configs/IVMS8_defconfig	2004-01-15 12:10:22.000000000 -0800
@@ -532,7 +532,7 @@
 # CONFIG_FEC_DP83846A is not set
 CONFIG_ENET_BIG_BUFFERS=y
 CONFIG_8xx_SMC1=y
-# CONFIG_SMC2_UART is not set
+# CONFIG_8xx_SMC2 is not set
 # CONFIG_8xx_SCC1 is not set
 # CONFIG_8xx_SCC2 is not set
 # CONFIG_8xx_SCC3 is not set
diff -urN linux-2.4.25-pre4/arch/ppc/configs/SM850_defconfig linux-2.4.25-pre5/arch/ppc/configs/SM850_defconfig
--- linux-2.4.25-pre4/arch/ppc/configs/SM850_defconfig	2004-01-15 12:10:14.000000000 -0800
+++ linux-2.4.25-pre5/arch/ppc/configs/SM850_defconfig	2004-01-15 12:10:22.000000000 -0800
@@ -490,7 +490,7 @@
 CONFIG_SCC3_ENET=y
 # CONFIG_FEC_ENET is not set
 CONFIG_ENET_BIG_BUFFERS=y
-CONFIG_SMC2_UART=y
+CONFIG_8xx_SMC2=y
 CONFIG_ALTSMC2=y
 CONFIG_CONS_SMC2=y
 # CONFIG_8xx_SCC1 is not set
diff -urN linux-2.4.25-pre4/arch/ppc/configs/SPD823TS_defconfig linux-2.4.25-pre5/arch/ppc/configs/SPD823TS_defconfig
--- linux-2.4.25-pre4/arch/ppc/configs/SPD823TS_defconfig	2004-01-15 12:10:14.000000000 -0800
+++ linux-2.4.25-pre5/arch/ppc/configs/SPD823TS_defconfig	2004-01-15 12:10:22.000000000 -0800
@@ -490,7 +490,7 @@
 # CONFIG_FEC_ENET is not set
 CONFIG_ENET_BIG_BUFFERS=y
 CONFIG_8xx_SMC1=y
-CONFIG_SMC2_UART=y
+CONFIG_8xx_SMC2=y
 CONFIG_ALTSMC2=y
 # CONFIG_CONS_SMC2 is not set
 # CONFIG_8xx_SCC1 is not set
diff -urN linux-2.4.25-pre4/arch/ppc/configs/TQM823L_defconfig linux-2.4.25-pre5/arch/ppc/configs/TQM823L_defconfig
--- linux-2.4.25-pre4/arch/ppc/configs/TQM823L_defconfig	2004-01-15 12:10:14.000000000 -0800
+++ linux-2.4.25-pre5/arch/ppc/configs/TQM823L_defconfig	2004-01-15 12:10:22.000000000 -0800
@@ -491,7 +491,7 @@
 # CONFIG_FEC_ENET is not set
 CONFIG_ENET_BIG_BUFFERS=y
 CONFIG_8xx_SMC1=y
-CONFIG_SMC2_UART=y
+CONFIG_8xx_SMC2=y
 CONFIG_ALTSMC2=y
 # CONFIG_CONS_SMC2 is not set
 # CONFIG_8xx_SCC1 is not set
diff -urN linux-2.4.25-pre4/arch/ppc/configs/TQM850L_defconfig linux-2.4.25-pre5/arch/ppc/configs/TQM850L_defconfig
--- linux-2.4.25-pre4/arch/ppc/configs/TQM850L_defconfig	2004-01-15 12:10:14.000000000 -0800
+++ linux-2.4.25-pre5/arch/ppc/configs/TQM850L_defconfig	2004-01-15 12:10:22.000000000 -0800
@@ -490,7 +490,7 @@
 # CONFIG_SCC3_ENET is not set
 # CONFIG_FEC_ENET is not set
 CONFIG_ENET_BIG_BUFFERS=y
-CONFIG_SMC2_UART=y
+CONFIG_8xx_SMC2=y
 CONFIG_ALTSMC2=y
 # CONFIG_CONS_SMC2 is not set
 # CONFIG_USE_SCC_IO is not set
diff -urN linux-2.4.25-pre4/arch/ppc/configs/TQM860L_defconfig linux-2.4.25-pre5/arch/ppc/configs/TQM860L_defconfig
--- linux-2.4.25-pre4/arch/ppc/configs/TQM860L_defconfig	2004-01-15 12:10:14.000000000 -0800
+++ linux-2.4.25-pre5/arch/ppc/configs/TQM860L_defconfig	2004-01-15 12:10:22.000000000 -0800
@@ -532,7 +532,7 @@
 # CONFIG_FEC_ENET is not set
 CONFIG_ENET_BIG_BUFFERS=y
 CONFIG_8xx_SMC1=y
-CONFIG_SMC2_UART=y
+CONFIG_8xx_SMC2=y
 # CONFIG_ALTSMC2 is not set
 # CONFIG_CONS_SMC2 is not set
 # CONFIG_8xx_SCC2 is not set
diff -urN linux-2.4.25-pre4/arch/ppc/configs/bseip_defconfig linux-2.4.25-pre5/arch/ppc/configs/bseip_defconfig
--- linux-2.4.25-pre4/arch/ppc/configs/bseip_defconfig	2004-01-15 12:10:14.000000000 -0800
+++ linux-2.4.25-pre5/arch/ppc/configs/bseip_defconfig	2004-01-15 12:10:22.000000000 -0800
@@ -490,7 +490,7 @@
 # CONFIG_FEC_ENET is not set
 # CONFIG_ENET_BIG_BUFFERS is not set
 CONFIG_8xx_SMC1=y
-CONFIG_SMC2_UART=y
+CONFIG_8xx_SMC2=y
 # CONFIG_ALTSMC2 is not set
 # CONFIG_CONS_SMC2 is not set
 # CONFIG_8xx_SCC1 is not set
diff -urN linux-2.4.25-pre4/arch/ppc/configs/cpci405_defconfig linux-2.4.25-pre5/arch/ppc/configs/cpci405_defconfig
--- linux-2.4.25-pre4/arch/ppc/configs/cpci405_defconfig	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.25-pre5/arch/ppc/configs/cpci405_defconfig	2004-01-15 12:10:22.000000000 -0800
@@ -0,0 +1,639 @@
+#
+# Automatically generated make config: don't edit
+#
+# CONFIG_UID16 is not set
+# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_HAVE_DEC_LOCK=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
+# Platform support
+#
+CONFIG_PPC=y
+CONFIG_PPC32=y
+# CONFIG_6xx is not set
+CONFIG_40x=y
+# CONFIG_44x is not set
+# CONFIG_POWER3 is not set
+# CONFIG_POWER4 is not set
+# CONFIG_8xx is not set
+CONFIG_4xx=y
+CONFIG_CPCI405=y
+# CONFIG_OAK is not set
+# CONFIG_WALNUT is not set
+# CONFIG_SMP is not set
+# CONFIG_MATH_EMULATION is not set
+# CONFIG_PPC4xx_DMA is not set
+CONFIG_NOT_COHERENT_CACHE=y
+CONFIG_UART0_TTYS0=y
+# CONFIG_UART0_TTYS1 is not set
+CONFIG_405GP=y
+CONFIG_IBM_OCP=y
+CONFIG_405=y
+CONFIG_IBM405_ERR51=y
+CONFIG_IBM405_ERR77=y
+
+#
+# General setup
+#
+# CONFIG_HIGHMEM is not set
+CONFIG_HIGHMEM_START=0xfe000000
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_TASK_SIZE=0x80000000
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_PCI=y
+# CONFIG_PC_KEYBOARD is not set
+CONFIG_NET=y
+CONFIG_SYSCTL=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_KCORE_ELF=y
+CONFIG_BINFMT_ELF=y
+CONFIG_KERNEL_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
+# CONFIG_PCI_NAMES is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+CONFIG_GEN_RTC=y
+# CONFIG_CMDLINE_BOOL is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_CISS_MONITOR_THREAD is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_BLK_STATS is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+
+#
+#    SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IPV6_SCTP__=y
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+CONFIG_IDE=y
+
+#
+# IDE, ATA and ATAPI Block devices
+#
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_IDE is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_IDEDISK_STROKE is not set
+# CONFIG_BLK_DEV_IDECS is not set
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
+# CONFIG_BLK_DEV_ISAPNP is not set
+CONFIG_BLK_DEV_IDEPCI=y
+# CONFIG_BLK_DEV_GENERIC is not set
+# CONFIG_IDEPCI_SHARE_IRQ is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+# CONFIG_IDEDMA_PCI_AUTO is not set
+# CONFIG_IDEDMA_ONLYDISK is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_PCI_WIP is not set
+# CONFIG_BLK_DEV_ADMA100 is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_WDC_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_AMD74XX_OVERRIDE is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_HPT34X_AUTODMA is not set
+CONFIG_BLK_DEV_HPT366=y
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_OPTI621 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_PDC202XX_BURST is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_BLK_DEV_RZ1000 is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIIMAGE is not set
+# CONFIG_BLK_DEV_SIS5513 is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_BLK_DEV_SL82C105 is not set
+CONFIG_BLK_DEV_CPCI405_IDE=y
+# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_IDEDMA_IVB is not set
+# CONFIG_DMA_NONPCI is not set
+CONFIG_BLK_DEV_IDE_MODES=y
+# CONFIG_BLK_DEV_ATARAID is not set
+# CONFIG_BLK_DEV_ATARAID_PDC is not set
+# CONFIG_BLK_DEV_ATARAID_HPT is not set
+# CONFIG_BLK_DEV_ATARAID_SII is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# IEEE 1394 (FireWire) support (EXPERIMENTAL)
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+# CONFIG_NET_ETHERNET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+
+#
+# On-chip net devices
+#
+CONFIG_IBM_OCP_ENET=y
+# CONFIG_IBM_OCP_ENET_ERROR_MSG is not set
+CONFIG_IBM_OCP_ENET_RX_BUFF=64
+CONFIG_IBM_OCP_ENET_TX_BUFF=8
+CONFIG_IBM_OCP_ENET_GAP=8
+CONFIG_IBM_OCP_ENET_SKB_RES=0
+CONFIG_OCP_NET=y
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Console drivers
+#
+
+#
+# Frame-buffer support
+#
+# CONFIG_FB is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_UINPUT is not set
+
+#
+# Macintosh device drivers
+#
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_UNIX98_PTYS is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_SCx200_ACB is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_PPC405_ALGO is not set
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_PROC=y
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_IPMI_PANIC_EVENT is not set
+# CONFIG_IPMI_DEVICE_INTERFACE is not set
+# CONFIG_IPMI_KCS is not set
+# CONFIG_IPMI_WATCHDOG is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_SCx200 is not set
+# CONFIG_SCx200_GPIO is not set
+# CONFIG_AMD_PM768 is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+
+#
+# Direct Rendering Manager (XFree86 DRI support)
+#
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_QFMT_V2 is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+# CONFIG_UMSDOS_FS is not set
+CONFIG_VFAT_FS=y
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+CONFIG_TMPFS=y
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+# CONFIG_DEVPTS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Support for USB gadgets
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+# CONFIG_CRC32 is not set
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=0
diff -urN linux-2.4.25-pre4/arch/ppc/configs/mbx_defconfig linux-2.4.25-pre5/arch/ppc/configs/mbx_defconfig
--- linux-2.4.25-pre4/arch/ppc/configs/mbx_defconfig	2004-01-15 12:10:14.000000000 -0800
+++ linux-2.4.25-pre5/arch/ppc/configs/mbx_defconfig	2004-01-15 12:10:22.000000000 -0800
@@ -486,7 +486,7 @@
 # CONFIG_FEC_ENET is not set
 CONFIG_ENET_BIG_BUFFERS=y
 CONFIG_8xx_SMC1=y
-CONFIG_SMC2_UART=y
+CONFIG_8xx_SMC2=y
 # CONFIG_ALTSMC2 is not set
 # CONFIG_CONS_SMC2 is not set
 # CONFIG_8xx_SCC2 is not set
diff -urN linux-2.4.25-pre4/arch/ppc/configs/rpxcllf_defconfig linux-2.4.25-pre5/arch/ppc/configs/rpxcllf_defconfig
--- linux-2.4.25-pre4/arch/ppc/configs/rpxcllf_defconfig	2004-01-15 12:10:14.000000000 -0800
+++ linux-2.4.25-pre5/arch/ppc/configs/rpxcllf_defconfig	2004-01-15 12:10:22.000000000 -0800
@@ -526,7 +526,7 @@
 # CONFIG_USE_MDIO is not set
 CONFIG_ENET_BIG_BUFFERS=y
 CONFIG_8xx_SMC1=y
-CONFIG_SMC2_UART=y
+CONFIG_8xx_SMC2=y
 # CONFIG_ALTSMC2 is not set
 # CONFIG_CONS_SMC2 is not set
 # CONFIG_8xx_SCC2 is not set
diff -urN linux-2.4.25-pre4/arch/ppc/configs/rpxlite_defconfig linux-2.4.25-pre5/arch/ppc/configs/rpxlite_defconfig
--- linux-2.4.25-pre4/arch/ppc/configs/rpxlite_defconfig	2004-01-15 12:10:14.000000000 -0800
+++ linux-2.4.25-pre5/arch/ppc/configs/rpxlite_defconfig	2004-01-15 12:10:22.000000000 -0800
@@ -525,7 +525,7 @@
 # CONFIG_FEC_ENET is not set
 # CONFIG_ENET_BIG_BUFFERS is not set
 CONFIG_8xx_SMC1=y
-# CONFIG_SMC2_UART is not set
+# CONFIG_8xx_SMC2 is not set
 # CONFIG_8xx_SCC1 is not set
 # CONFIG_8xx_SCC3 is not set
 # CONFIG_8xx_SCC4 is not set
diff -urN linux-2.4.25-pre4/arch/ppc/platforms/Makefile linux-2.4.25-pre5/arch/ppc/platforms/Makefile
--- linux-2.4.25-pre4/arch/ppc/platforms/Makefile	2004-01-15 12:10:14.000000000 -0800
+++ linux-2.4.25-pre5/arch/ppc/platforms/Makefile	2004-01-15 12:10:22.000000000 -0800
@@ -32,6 +32,7 @@
 obj-$(CONFIG_440GP)		+= ibm440gp.o
 obj-$(CONFIG_440GX)		+= ibm440gx.o
 
+obj-$(CONFIG_CPCI405)		+= cpci405.o
 obj-$(CONFIG_EBONY)		+= ebony.o
 obj-$(CONFIG_OCOTEA)		+= ocotea.o
 obj-$(CONFIG_WALNUT)		+= walnut.o
diff -urN linux-2.4.25-pre4/arch/ppc/platforms/cpci405.c linux-2.4.25-pre5/arch/ppc/platforms/cpci405.c
--- linux-2.4.25-pre4/arch/ppc/platforms/cpci405.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.25-pre5/arch/ppc/platforms/cpci405.c	2004-01-15 12:10:22.000000000 -0800
@@ -0,0 +1,141 @@
+/*
+ * arch/ppc/platforms/cpci405.c
+ *
+ * Board setup routines for the esd CPCI-405 cPCI Board.
+ *
+ * Author: Stefan Roese
+ *         stefan.roese@esd-electronics.com
+ *
+ * Copyright 2001-2003 esd electronic system design - hannover germany
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ *	History: 11/09/2001 - armin
+ *       added board_init to add in additional instuctions needed during platfrom_init
+ *
+ * 		: 03/26/03 - stefan
+ *		Added cpci405_early_serial_map (cloned from evb405ep) to generate
+ *		BASE_BAUD dynamically from the UDIV settings (configured by U-Boot).
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <asm/system.h>
+#include <asm/pci-bridge.h>
+#include <asm/machdep.h>
+#include <asm/todc.h>
+#include <linux/serial.h>
+
+void *cpci405_nvram;
+
+/*
+ * Some IRQs unique to CPCI-405.
+ */
+int __init
+ppc405_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
+{
+	static char pci_irq_table[][4] =
+	/*
+	 *      PCI IDSEL/INTPIN->INTLINE
+	 *      A       B       C       D
+	 */
+	{
+		{28,	28,	28,	28},	/* IDSEL 15 - cPCI slot 8 */
+		{29,	29,	29,	29},	/* IDSEL 16 - cPCI slot 7 */
+		{30,	30,	30,	30},	/* IDSEL 17 - cPCI slot 6 */
+		{27,	27,	27,	27},	/* IDSEL 18 - cPCI slot 5 */
+		{28,	28,	28,	28},	/* IDSEL 19 - cPCI slot 4 */
+		{29,	29,	29,	29},	/* IDSEL 20 - cPCI slot 3 */
+		{30,	30,	30,	30},	/* IDSEL 21 - cPCI slot 2 */
+	};
+	const long min_idsel = 15, max_idsel = 21, irqs_per_slot = 4;
+	return PCI_IRQ_TABLE_LOOKUP;
+};
+
+/* The serial clock for the chip is an internal clock determined by
+ * different clock speeds/dividers.
+ * Calculate the proper input baud rate and setup the serial driver.
+ */
+static void __init
+cpci405_early_serial_map(void)
+{
+	u32 uart_div;
+	int serial_baud_405;
+	bd_t *bip = (bd_t *) __res;
+	struct serial_struct serialreq = {0};
+
+	/* Calculate the serial clock input frequency
+	 *
+	 * The base baud is the PLL OUTA (provided in the board info
+	 * structure) divided by the external UART Divisor, divided
+	 * by 16.
+	 */
+	uart_div = ((mfdcr(DCRN_CHCR_BASE) & CHR0_UDIV) >> 1) + 1;
+	serial_baud_405 = bip->bi_procfreq / uart_div / 16;
+
+	/* Update the serial port attributes */
+	serialreq.baud_base = serial_baud_405;
+	serialreq.flags = (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST);
+	serialreq.io_type = SERIAL_IO_MEM;
+
+	serialreq.line = 0;
+	serialreq.port = 0;
+	serialreq.irq = ACTING_UART0_INT;
+	serialreq.iomem_base = (void*)ACTING_UART0_IO_BASE;
+
+#if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
+	/* Configure debug serial access */
+	gen550_init(0, &serialreq);
+#endif
+
+	if (early_serial_setup(&serialreq) != 0) {
+		printk("Early serial init of port 0 failed\n");
+	}
+
+	serialreq.line = 1;
+	serialreq.port = 1;
+	serialreq.irq = ACTING_UART1_INT;
+	serialreq.iomem_base = (void*)ACTING_UART1_IO_BASE;
+
+#if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
+	/* Configure debug serial access */
+	gen550_init(1, &serialreq);
+#endif
+
+	if (early_serial_setup(&serialreq) != 0) {
+		printk("Early serial init of port 1 failed\n");
+	}
+}
+
+void __init
+board_setup_arch(void)
+{
+	cpci405_early_serial_map();
+	TODC_INIT(TODC_TYPE_MK48T35, cpci405_nvram, cpci405_nvram, cpci405_nvram, 8);
+}
+
+void __init
+board_io_mapping(void)
+{
+	cpci405_nvram = ioremap(CPCI405_NVRAM_PADDR, CPCI405_NVRAM_SIZE);
+}
+
+void __init
+board_setup_irq(void)
+{
+}
+
+void __init
+board_init(void)
+{
+	ppc_md.time_init = todc_time_init;
+	ppc_md.set_rtc_time = todc_set_rtc_time;
+	ppc_md.get_rtc_time = todc_get_rtc_time;
+	ppc_md.nvram_read_val = todc_direct_read_val;
+	ppc_md.nvram_write_val = todc_direct_write_val;
+}
diff -urN linux-2.4.25-pre4/arch/ppc/platforms/cpci405.h linux-2.4.25-pre5/arch/ppc/platforms/cpci405.h
--- linux-2.4.25-pre4/arch/ppc/platforms/cpci405.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.25-pre5/arch/ppc/platforms/cpci405.h	2004-01-15 12:10:22.000000000 -0800
@@ -0,0 +1,52 @@
+/*
+ * CPCI-405 board specific definitions
+ *
+ * Copyright (c) 2001 Stefan Roese (stefan.roese@esd-electronics.com)
+ */
+
+#ifdef __KERNEL__
+#ifndef __ASM_CPCI405_H__
+#define __ASM_CPCI405_H__
+
+#include <linux/config.h>
+
+/* We have a 405GP core */
+#include <platforms/ibm405gp.h>
+
+#include <asm/ppcboot.h>
+
+#ifndef __ASSEMBLY__
+/* Some 4xx parts use a different timebase frequency from the internal clock.
+*/
+#define bi_tbfreq bi_intfreq
+
+/* Map for the NVRAM space */
+#define CPCI405_NVRAM_PADDR	((uint)0xf0200000)
+#define CPCI405_NVRAM_SIZE	((uint)32*1024)
+
+#if defined(CONFIG_UART0_TTYS0)
+#define ACTING_UART0_IO_BASE	UART0_IO_BASE
+#define ACTING_UART1_IO_BASE	UART1_IO_BASE
+#define ACTING_UART0_INT	UART0_INT
+#define ACTING_UART1_INT	UART1_INT
+#else
+#define ACTING_UART0_IO_BASE	UART1_IO_BASE
+#define ACTING_UART1_IO_BASE	UART0_IO_BASE
+#define ACTING_UART0_INT	UART1_INT
+#define ACTING_UART1_INT	UART0_INT
+#endif
+
+/* The UART clock is based off an internal clock -
+ * define BASE_BAUD based on the internal clock and divider(s).
+ * Since BASE_BAUD must be a constant, we will initialize it
+ * using clock/divider values which U-Boot initializes
+ * for typical configurations at various CPU speeds.
+ * The base baud is calculated as (FWDA / EXT UART DIV / 16)
+ */
+#define BASE_BAUD       0
+
+#define PPC4xx_MACHINE_NAME "esd CPCI-405"
+
+#endif /* !__ASSEMBLY__ */
+#endif	/* __ASM_CPCI405_H__ */
+#endif /* __KERNEL__ */
diff -urN linux-2.4.25-pre4/arch/ppc64/configs/iSeries_devfs_defconfig linux-2.4.25-pre5/arch/ppc64/configs/iSeries_devfs_defconfig
--- linux-2.4.25-pre4/arch/ppc64/configs/iSeries_devfs_defconfig	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.25-pre5/arch/ppc64/configs/iSeries_devfs_defconfig	2004-01-15 12:10:22.000000000 -0800
@@ -21,9 +21,13 @@
 CONFIG_SERIAL_CONSOLE=y
 # CONFIG_PPC_PSERIES is not set
 CONFIG_PPC_ISERIES=y
+# CONFIG_ALTIVEC is not set
 CONFIG_SMP=y
 CONFIG_IRQ_ALL_CPUS=y
+CONFIG_NR_CPUS=32
 CONFIG_MSCHUNKS=y
+# CONFIG_SHARED_MEMORY_ADDRESSING is not set
+CONFIG_LPARCFG=y
 
 #
 # Loadable module support
@@ -40,6 +44,7 @@
 # CONFIG_MCA is not set
 # CONFIG_EISA is not set
 CONFIG_PCI=y
+# CONFIG_PCMCIA is not set
 CONFIG_NET=y
 CONFIG_SYSCTL=y
 CONFIG_SYSVIPC=y
@@ -50,7 +55,6 @@
 CONFIG_BINFMT_MISC=y
 CONFIG_PCI_NAMES=y
 # CONFIG_HOTPLUG is not set
-# CONFIG_PCMCIA is not set
 
 #
 # Parallel port support
@@ -58,18 +62,6 @@
 # CONFIG_PARPORT is not set
 
 #
-# Memory Technology Devices (MTD)
-#
-# CONFIG_MTD is not set
-
-#
-# Plug and Play configuration
-#
-# CONFIG_PNP is not set
-# CONFIG_ISAPNP is not set
-# CONFIG_PNPBIOS is not set
-
-#
 # Block devices
 #
 # CONFIG_BLK_DEV_FD is not set
@@ -77,12 +69,16 @@
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=8192
 CONFIG_BLK_DEV_INITRD=y
+# CONFIG_BLK_STATS is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -101,8 +97,6 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK=y
-# CONFIG_RTNETLINK is not set
 # CONFIG_NETLINK_DEV is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
@@ -117,17 +111,30 @@
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
 # CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
 # CONFIG_INET_ECN is not set
 CONFIG_SYN_COOKIES=y
 # CONFIG_IPV6 is not set
 # CONFIG_KHTTPD is not set
+
+#
+#    SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IPV6_SCTP__=y
+# CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
 
 #
 #  
 #
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -143,6 +150,16 @@
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
 # CONFIG_BLK_DEV_IDE_MODES is not set
 # CONFIG_BLK_DEV_HD is not set
 
@@ -180,13 +197,16 @@
 # CONFIG_SCSI_AHA152X is not set
 # CONFIG_SCSI_AHA1542 is not set
 # CONFIG_SCSI_AHA1740 is not set
+# CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC79XX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_IN2000 is not set
 # CONFIG_SCSI_AM53C974 is not set
 # CONFIG_SCSI_MEGARAID is not set
+# CONFIG_SCSI_MEGARAID2 is not set
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_CPQFCTS is not set
 # CONFIG_SCSI_DMX3191D is not set
@@ -201,6 +221,7 @@
 # CONFIG_SCSI_INIA100 is not set
 # CONFIG_SCSI_NCR53C406A is not set
 # CONFIG_SCSI_NCR53C7xx is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
 # CONFIG_SCSI_NCR53C8XX is not set
 # CONFIG_SCSI_SYM53C8XX is not set
 # CONFIG_SCSI_PAS16 is not set
@@ -216,9 +237,8 @@
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_T128 is not set
 # CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
-# CONFIG_SCSI_MESH is not set
-# CONFIG_SCSI_MAC53C94 is not set
 
 #
 # IEEE 1394 (FireWire) support (EXPERIMENTAL)
@@ -247,12 +267,10 @@
 # CONFIG_MACE is not set
 # CONFIG_BMAC is not set
 # CONFIG_GMAC is not set
-# CONFIG_OAKNET is not set
 # CONFIG_SUNLANCE is not set
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNBMAC is not set
 # CONFIG_SUNQE is not set
-# CONFIG_SUNLANCE is not set
 # CONFIG_SUNGEM is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_LANCE is not set
@@ -262,14 +280,18 @@
 # CONFIG_NET_ISA is not set
 CONFIG_NET_PCI=y
 CONFIG_PCNET32=m
+# CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
 # CONFIG_APRICOT is not set
+# CONFIG_B44 is not set
 # CONFIG_CS89x0 is not set
 # CONFIG_TULIP is not set
 # CONFIG_DE4X5 is not set
 # CONFIG_DGRS is not set
 # CONFIG_DM9102 is not set
 # CONFIG_EEPRO100 is not set
+# CONFIG_EEPRO100_PIO is not set
+# CONFIG_E100 is not set
 # CONFIG_LNE390 is not set
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
@@ -281,11 +303,14 @@
 # CONFIG_8139TOO_PIO is not set
 # CONFIG_8139TOO_TUNE_TWISTER is not set
 # CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_OLD_RX_RESET is not set
 # CONFIG_SIS900 is not set
 # CONFIG_EPIC100 is not set
 # CONFIG_SUNDANCE is not set
+# CONFIG_SUNDANCE_MMIO is not set
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
+# CONFIG_VIA_RHINE_MMIO is not set
 # CONFIG_WINBOND_840 is not set
 # CONFIG_NET_POCKET is not set
 
@@ -295,11 +320,15 @@
 CONFIG_ACENIC=m
 # CONFIG_ACENIC_OMIT_TIGON_I is not set
 # CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
 # CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+CONFIG_VETH=y
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
 # CONFIG_PLIP is not set
@@ -317,7 +346,12 @@
 CONFIG_TR=y
 CONFIG_IBMOL=m
 # CONFIG_IBMLS is not set
+# CONFIG_3C359 is not set
 # CONFIG_TMS380TR is not set
+# CONFIG_TMSPCI is not set
+# CONFIG_TMSISA is not set
+# CONFIG_ABYSS is not set
+# CONFIG_MADGEMC is not set
 # CONFIG_NET_FC is not set
 # CONFIG_RCPCI is not set
 # CONFIG_SHAPER is not set
@@ -333,11 +367,6 @@
 # CONFIG_HAMRADIO is not set
 
 #
-# IrDA (infrared) support
-#
-# CONFIG_IRDA is not set
-
-#
 # ISDN subsystem
 #
 # CONFIG_ISDN is not set
@@ -348,15 +377,6 @@
 # CONFIG_CD_NO_IDESCSI is not set
 
 #
-# Console drivers
-#
-
-#
-# Frame-buffer support
-#
-# CONFIG_FB is not set
-
-#
 # iSeries device drivers
 #
 CONFIG_VIOCONS=y
@@ -386,6 +406,7 @@
 # CONFIG_MOXA_SMARTIO is not set
 # CONFIG_ISI is not set
 # CONFIG_SYNCLINK is not set
+# CONFIG_SYNCLINKMP is not set
 # CONFIG_N_HDLC is not set
 # CONFIG_RISCOM8 is not set
 # CONFIG_SPECIALIX is not set
@@ -442,12 +463,19 @@
 # CONFIG_INPUT_GAMECON is not set
 # CONFIG_INPUT_TURBOGRAFX is not set
 # CONFIG_QIC02_TAPE is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_IPMI_PANIC_EVENT is not set
+# CONFIG_IPMI_DEVICE_INTERFACE is not set
+# CONFIG_IPMI_KCS is not set
+# CONFIG_IPMI_WATCHDOG is not set
 
 #
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
-# CONFIG_INTEL_RNG is not set
+# CONFIG_SCx200 is not set
+# CONFIG_SCx200_GPIO is not set
+# CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
 # CONFIG_DTLK is not set
@@ -459,22 +487,33 @@
 #
 # CONFIG_FTAPE is not set
 # CONFIG_AGP is not set
+
+#
+# Direct Rendering Manager (XFree86 DRI support)
+#
 # CONFIG_DRM is not set
-# CONFIG_MWAVE is not set
 
 #
 # File systems
 #
 # CONFIG_QUOTA is not set
+# CONFIG_QFMT_V2 is not set
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 CONFIG_REISERFS_FS=y
 # CONFIG_REISERFS_CHECK is not set
+CONFIG_REISERFS_PROC_INFO=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
+CONFIG_EXT3_FS=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
 # CONFIG_FAT_FS is not set
 # CONFIG_MSDOS_FS is not set
 # CONFIG_UMSDOS_FS is not set
@@ -484,11 +523,14 @@
 # CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_TMPFS is not set
-# CONFIG_RAMFS is not set
+CONFIG_RAMFS=y
 CONFIG_ISO9660_FS=y
 CONFIG_JOLIET=y
-# CONFIG_MINIX_FS is not set
+# CONFIG_ZISOFS is not set
 # CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+# CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
 # CONFIG_NTFS_RW is not set
@@ -507,16 +549,24 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
 #
 # CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
+# CONFIG_NFS_DIRECTIO is not set
 # CONFIG_ROOT_NFS is not set
 CONFIG_NFSD=m
 CONFIG_NFSD_V3=y
+CONFIG_NFSD_TCP=y
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
@@ -530,6 +580,7 @@
 # CONFIG_NCPFS_SMALLDOS is not set
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
 
 #
 # Partition Types
@@ -564,6 +615,7 @@
 # CONFIG_NLS_CODEPAGE_949 is not set
 # CONFIG_NLS_CODEPAGE_874 is not set
 # CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
 # CONFIG_NLS_CODEPAGE_1251 is not set
 CONFIG_NLS_ISO8859_1=y
 # CONFIG_NLS_ISO8859_2 is not set
@@ -581,114 +633,16 @@
 # CONFIG_NLS_UTF8 is not set
 
 #
-# Sound
-#
-# CONFIG_SOUND is not set
-
-#
-# USB support
-#
-# CONFIG_USB is not set
-
-#
-# USB Controllers
-#
-# CONFIG_USB_UHCI is not set
-# CONFIG_USB_UHCI_ALT is not set
-# CONFIG_USB_OHCI is not set
-
-#
-# USB Device Class drivers
-#
-# CONFIG_USB_AUDIO is not set
-# CONFIG_USB_BLUETOOTH is not set
-# CONFIG_USB_STORAGE is not set
-# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_DATAFAB is not set
-# CONFIG_USB_STORAGE_FREECOM is not set
-# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_HP8200e is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_STORAGE_JUMPSHOT is not set
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
-
-#
-# USB Human Interface Devices (HID)
-#
-# CONFIG_USB_HID is not set
-# CONFIG_USB_HIDDEV is not set
-# CONFIG_USB_KBD is not set
-# CONFIG_USB_MOUSE is not set
-# CONFIG_USB_WACOM is not set
-
-#
-# USB Imaging devices
-#
-# CONFIG_USB_DC2XX is not set
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_SCANNER is not set
-# CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_HPUSBSCSI is not set
-
-#
-# USB Multimedia devices
-#
-# CONFIG_USB_IBMCAM is not set
-# CONFIG_USB_OV511 is not set
-# CONFIG_USB_PWC is not set
-# CONFIG_USB_SE401 is not set
-# CONFIG_USB_DSBR is not set
-# CONFIG_USB_DABUSB is not set
-
-#
-# USB Network adaptors
-#
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_CATC is not set
-# CONFIG_USB_CDCETHER is not set
-# CONFIG_USB_USBNET is not set
-
-#
-# USB port drivers
-#
-# CONFIG_USB_USS720 is not set
-
-#
-# USB Serial Converter support
+# Library routines
 #
-# CONFIG_USB_SERIAL is not set
-# CONFIG_USB_SERIAL_GENERIC is not set
-# CONFIG_USB_SERIAL_BELKIN is not set
-# CONFIG_USB_SERIAL_WHITEHEAT is not set
-# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
-# CONFIG_USB_SERIAL_EMPEG is not set
-# CONFIG_USB_SERIAL_FTDI_SIO is not set
-# CONFIG_USB_SERIAL_VISOR is not set
-# CONFIG_USB_SERIAL_IR is not set
-# CONFIG_USB_SERIAL_EDGEPORT is not set
-# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
-# CONFIG_USB_SERIAL_KEYSPAN is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
-# CONFIG_USB_SERIAL_MCT_U232 is not set
-# CONFIG_USB_SERIAL_PL2303 is not set
-# CONFIG_USB_SERIAL_CYBERJACK is not set
-# CONFIG_USB_SERIAL_XIRCOM is not set
-# CONFIG_USB_SERIAL_OMNINET is not set
+# CONFIG_CRC32 is not set
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
 
 #
-# USB Miscellaneous drivers
+# Cryptographic options
 #
-# CONFIG_USB_RIO500 is not set
+# CONFIG_CRYPTO is not set
 
 #
 # Kernel hacking
@@ -696,10 +650,7 @@
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_KGDB is not set
 # CONFIG_XMON is not set
-# CONFIG_KDB is not set
-# CONFIG_KDB_OFF is not set
-# CONFIG_KALLSYMS is not set
+# CONFIG_DEBUG_SLAB is not set
 # CONFIG_PPCDBG is not set
 # CONFIG_DUMP is not set
-# CONFIG_DUMP_COMPRESS_RLE is not set
-# CONFIG_DUMP_COMPRESS_GZIP is not set
+CONFIG_LOG_BUF_SHIFT=0
diff -urN linux-2.4.25-pre4/arch/ppc64/configs/iSeries_nodevfs_ideemul_defconfig linux-2.4.25-pre5/arch/ppc64/configs/iSeries_nodevfs_ideemul_defconfig
--- linux-2.4.25-pre4/arch/ppc64/configs/iSeries_nodevfs_ideemul_defconfig	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.25-pre5/arch/ppc64/configs/iSeries_nodevfs_ideemul_defconfig	2004-01-15 12:10:22.000000000 -0800
@@ -21,9 +21,13 @@
 CONFIG_SERIAL_CONSOLE=y
 # CONFIG_PPC_PSERIES is not set
 CONFIG_PPC_ISERIES=y
+# CONFIG_ALTIVEC is not set
 CONFIG_SMP=y
 CONFIG_IRQ_ALL_CPUS=y
+CONFIG_NR_CPUS=32
 CONFIG_MSCHUNKS=y
+# CONFIG_SHARED_MEMORY_ADDRESSING is not set
+CONFIG_LPARCFG=y
 
 #
 # Loadable module support
@@ -40,6 +44,7 @@
 # CONFIG_MCA is not set
 # CONFIG_EISA is not set
 CONFIG_PCI=y
+# CONFIG_PCMCIA is not set
 CONFIG_NET=y
 CONFIG_SYSCTL=y
 CONFIG_SYSVIPC=y
@@ -50,7 +55,6 @@
 CONFIG_BINFMT_MISC=y
 CONFIG_PCI_NAMES=y
 # CONFIG_HOTPLUG is not set
-# CONFIG_PCMCIA is not set
 
 #
 # Parallel port support
@@ -58,17 +62,6 @@
 # CONFIG_PARPORT is not set
 
 #
-# Memory Technology Devices (MTD)
-#
-# CONFIG_MTD is not set
-
-#
-# Plug and Play configuration
-#
-# CONFIG_PNP is not set
-# CONFIG_ISAPNP is not set
-
-#
 # Block devices
 #
 # CONFIG_BLK_DEV_FD is not set
@@ -77,12 +70,15 @@
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
 # CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=64000
 CONFIG_BLK_DEV_INITRD=y
+# CONFIG_BLK_STATS is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -113,7 +109,6 @@
 CONFIG_IP_ROUTE_MULTIPATH=y
 CONFIG_IP_ROUTE_TOS=y
 CONFIG_IP_ROUTE_VERBOSE=y
-CONFIG_IP_ROUTE_LARGE_TABLES=y
 CONFIG_IP_PNP=y
 # CONFIG_IP_PNP_DHCP is not set
 # CONFIG_IP_PNP_BOOTP is not set
@@ -129,6 +124,12 @@
 CONFIG_SYN_COOKIES=y
 # CONFIG_IPV6 is not set
 # CONFIG_KHTTPD is not set
+
+#
+#    SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IPV6_SCTP__=y
+# CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
 
@@ -206,12 +207,14 @@
 # CONFIG_SCSI_AHA1740 is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC79XX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_IN2000 is not set
 # CONFIG_SCSI_AM53C974 is not set
 # CONFIG_SCSI_MEGARAID is not set
+# CONFIG_SCSI_MEGARAID2 is not set
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_CPQFCTS is not set
 # CONFIG_SCSI_DMX3191D is not set
@@ -242,6 +245,7 @@
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_T128 is not set
 # CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 
 #
@@ -284,15 +288,18 @@
 # CONFIG_NET_ISA is not set
 CONFIG_NET_PCI=y
 CONFIG_PCNET32=m
+# CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
 # CONFIG_APRICOT is not set
+# CONFIG_B44 is not set
 # CONFIG_CS89x0 is not set
 # CONFIG_TULIP is not set
-# CONFIG_TC35815 is not set
 # CONFIG_DE4X5 is not set
 # CONFIG_DGRS is not set
 # CONFIG_DM9102 is not set
 # CONFIG_EEPRO100 is not set
+# CONFIG_EEPRO100_PIO is not set
+# CONFIG_E100 is not set
 # CONFIG_LNE390 is not set
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
@@ -304,10 +311,11 @@
 # CONFIG_8139TOO_PIO is not set
 # CONFIG_8139TOO_TUNE_TWISTER is not set
 # CONFIG_8139TOO_8129 is not set
-# CONFIG_8139_NEW_RX_RESET is not set
+# CONFIG_8139_OLD_RX_RESET is not set
 # CONFIG_SIS900 is not set
 # CONFIG_EPIC100 is not set
 # CONFIG_SUNDANCE is not set
+# CONFIG_SUNDANCE_MMIO is not set
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
 # CONFIG_VIA_RHINE_MMIO is not set
@@ -320,12 +328,15 @@
 CONFIG_ACENIC=m
 # CONFIG_ACENIC_OMIT_TIGON_I is not set
 # CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_TIGON3 is not set
+CONFIG_VETH=y
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
 # CONFIG_PLIP is not set
@@ -345,6 +356,10 @@
 # CONFIG_IBMLS is not set
 # CONFIG_3C359 is not set
 # CONFIG_TMS380TR is not set
+# CONFIG_TMSPCI is not set
+# CONFIG_TMSISA is not set
+# CONFIG_ABYSS is not set
+# CONFIG_MADGEMC is not set
 # CONFIG_NET_FC is not set
 # CONFIG_RCPCI is not set
 # CONFIG_SHAPER is not set
@@ -360,11 +375,6 @@
 # CONFIG_HAMRADIO is not set
 
 #
-# IrDA (infrared) support
-#
-# CONFIG_IRDA is not set
-
-#
 # ISDN subsystem
 #
 # CONFIG_ISDN is not set
@@ -386,24 +396,6 @@
 # CONFIG_CDU535 is not set
 
 #
-# Console drivers
-#
-
-#
-# Frame-buffer support
-#
-# CONFIG_FB is not set
-
-#
-# Input core support
-#
-# CONFIG_INPUT is not set
-# CONFIG_INPUT_KEYBDEV is not set
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-
-#
 # iSeries device drivers
 #
 CONFIG_VIOCONS=y
@@ -432,8 +424,8 @@
 # CONFIG_MOXA_INTELLIO is not set
 # CONFIG_MOXA_SMARTIO is not set
 # CONFIG_ISI is not set
-CONFIG_ICOM=m
 # CONFIG_SYNCLINK is not set
+# CONFIG_SYNCLINKMP is not set
 # CONFIG_N_HDLC is not set
 # CONFIG_RISCOM8 is not set
 # CONFIG_SPECIALIX is not set
@@ -468,11 +460,19 @@
 # Input core support is needed for joysticks
 #
 # CONFIG_QIC02_TAPE is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_IPMI_PANIC_EVENT is not set
+# CONFIG_IPMI_DEVICE_INTERFACE is not set
+# CONFIG_IPMI_KCS is not set
+# CONFIG_IPMI_WATCHDOG is not set
 
 #
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
+# CONFIG_SCx200 is not set
+# CONFIG_SCx200_GPIO is not set
+# CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
 # CONFIG_DTLK is not set
@@ -484,12 +484,17 @@
 #
 # CONFIG_FTAPE is not set
 # CONFIG_AGP is not set
+
+#
+# Direct Rendering Manager (XFree86 DRI support)
+#
 # CONFIG_DRM is not set
 
 #
 # File systems
 #
 CONFIG_QUOTA=y
+# CONFIG_QFMT_V2 is not set
 CONFIG_AUTOFS_FS=y
 CONFIG_AUTOFS4_FS=y
 CONFIG_REISERFS_FS=y
@@ -499,6 +504,9 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
 CONFIG_EXT3_FS=y
 CONFIG_JBD=y
@@ -516,9 +524,10 @@
 CONFIG_ISO9660_FS=y
 CONFIG_JOLIET=y
 # CONFIG_ZISOFS is not set
-# CONFIG_MINIX_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+# CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
 # CONFIG_NTFS_RW is not set
@@ -537,6 +546,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
@@ -545,9 +559,11 @@
 # CONFIG_INTERMEZZO_FS is not set
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
+# CONFIG_NFS_DIRECTIO is not set
 # CONFIG_ROOT_NFS is not set
 CONFIG_NFSD=y
 CONFIG_NFSD_V3=y
+CONFIG_NFSD_TCP=y
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
@@ -563,7 +579,6 @@
 CONFIG_NCPFS_NLS=y
 CONFIG_NCPFS_EXTRAS=y
 # CONFIG_ZISOFS_FS is not set
-# CONFIG_ZLIB_FS_INFLATE is not set
 
 #
 # Partition Types
@@ -616,14 +631,16 @@
 CONFIG_NLS_UTF8=y
 
 #
-# Sound
+# Library routines
 #
-# CONFIG_SOUND is not set
+# CONFIG_CRC32 is not set
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
 
 #
-# USB support
+# Cryptographic options
 #
-# CONFIG_USB is not set
+# CONFIG_CRYPTO is not set
 
 #
 # Kernel hacking
@@ -631,10 +648,7 @@
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_KGDB is not set
 # CONFIG_XMON is not set
-# CONFIG_KDB is not set
-# CONFIG_KDB_OFF is not set
-# CONFIG_KALLSYMS is not set
+# CONFIG_DEBUG_SLAB is not set
 # CONFIG_PPCDBG is not set
 # CONFIG_DUMP is not set
-# CONFIG_DUMP_COMPRESS_RLE is not set
-# CONFIG_DUMP_COMPRESS_GZIP is not set
+CONFIG_LOG_BUF_SHIFT=0
diff -urN linux-2.4.25-pre4/arch/ppc64/configs/pSeries_defconfig linux-2.4.25-pre5/arch/ppc64/configs/pSeries_defconfig
--- linux-2.4.25-pre4/arch/ppc64/configs/pSeries_defconfig	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.25-pre5/arch/ppc64/configs/pSeries_defconfig	2004-01-15 12:10:22.000000000 -0800
@@ -21,8 +21,10 @@
 CONFIG_SERIAL_CONSOLE=y
 CONFIG_PPC_PSERIES=y
 # CONFIG_PPC_ISERIES is not set
+CONFIG_ALTIVEC=y
 CONFIG_SMP=y
 CONFIG_IRQ_ALL_CPUS=y
+CONFIG_NR_CPUS=32
 # CONFIG_HMT is not set
 # CONFIG_MSCHUNKS is not set
 CONFIG_RTAS_FLASH=m
@@ -30,6 +32,7 @@
 CONFIG_PPC_RTAS=y
 # CONFIG_RTAS_ERRINJCT is not set
 # CONFIG_SHARED_MEMORY_ADDRESSING is not set
+CONFIG_LPARCFG=y
 
 #
 # Loadable module support
@@ -76,6 +79,7 @@
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
 # CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
 CONFIG_BLK_DEV_LOOP=y
@@ -118,6 +122,12 @@
 CONFIG_SYN_COOKIES=y
 # CONFIG_IPV6 is not set
 # CONFIG_KHTTPD is not set
+
+#
+#    SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IPV6_SCTP__=y
+# CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
 
@@ -176,7 +186,6 @@
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
 # CONFIG_BLK_DEV_IDESCSI is not set
 # CONFIG_IDE_TASK_IOCTL is not set
-# CONFIG_IDE_TASKFILE_IO is not set
 
 #
 # IDE chipset support/bugfixes
@@ -194,7 +203,7 @@
 # CONFIG_IDEDMA_ONLYDISK is not set
 CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_IDEDMA_PCI_WIP is not set
-CONFIG_BLK_DEV_ADMA=y
+# CONFIG_BLK_DEV_ADMA100 is not set
 # CONFIG_BLK_DEV_AEC62XX is not set
 # CONFIG_BLK_DEV_ALI15X3 is not set
 # CONFIG_WDC_ALI15X3 is not set
@@ -208,13 +217,11 @@
 # CONFIG_HPT34X_AUTODMA is not set
 # CONFIG_BLK_DEV_HPT366 is not set
 # CONFIG_BLK_DEV_PIIX is not set
-# CONFIG_BLK_DEV_NFORCE is not set
 # CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_OPTI621 is not set
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
 # CONFIG_PDC202XX_BURST is not set
 # CONFIG_BLK_DEV_PDC202XX_NEW is not set
-# CONFIG_PDC202XX_FORCE is not set
 # CONFIG_BLK_DEV_RZ1000 is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 # CONFIG_BLK_DEV_SVWKS is not set
@@ -270,12 +277,14 @@
 # CONFIG_SCSI_AHA1740 is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC79XX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_IN2000 is not set
 # CONFIG_SCSI_AM53C974 is not set
 # CONFIG_SCSI_MEGARAID is not set
+# CONFIG_SCSI_MEGARAID2 is not set
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_CPQFCTS is not set
 # CONFIG_SCSI_DMX3191D is not set
@@ -359,12 +368,14 @@
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
 # CONFIG_APRICOT is not set
+# CONFIG_B44 is not set
 # CONFIG_CS89x0 is not set
 # CONFIG_TULIP is not set
 # CONFIG_DE4X5 is not set
 # CONFIG_DGRS is not set
 # CONFIG_DM9102 is not set
 # CONFIG_EEPRO100 is not set
+# CONFIG_EEPRO100_PIO is not set
 CONFIG_E100=y
 # CONFIG_LNE390 is not set
 # CONFIG_FEALNX is not set
@@ -383,7 +394,6 @@
 # CONFIG_SUNDANCE is not set
 # CONFIG_SUNDANCE_MMIO is not set
 # CONFIG_TLAN is not set
-# CONFIG_TC35815 is not set
 # CONFIG_VIA_RHINE is not set
 # CONFIG_VIA_RHINE_MMIO is not set
 # CONFIG_WINBOND_840 is not set
@@ -396,6 +406,7 @@
 CONFIG_ACENIC_OMIT_TIGON_I=y
 # CONFIG_DL2K is not set
 CONFIG_E1000=y
+CONFIG_E1000_NAPI=y
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
@@ -422,6 +433,10 @@
 # CONFIG_IBMLS is not set
 # CONFIG_3C359 is not set
 # CONFIG_TMS380TR is not set
+# CONFIG_TMSPCI is not set
+# CONFIG_TMSISA is not set
+# CONFIG_ABYSS is not set
+# CONFIG_MADGEMC is not set
 # CONFIG_NET_FC is not set
 # CONFIG_RCPCI is not set
 # CONFIG_SHAPER is not set
@@ -471,12 +486,15 @@
 CONFIG_FB_MATROX=y
 CONFIG_FB_MATROX_MILLENIUM=y
 CONFIG_FB_MATROX_MYSTIQUE=y
-CONFIG_FB_MATROX_G100=y
 # CONFIG_FB_MATROX_G450 is not set
+CONFIG_FB_MATROX_G100A=y
+CONFIG_FB_MATROX_G100=y
+CONFIG_FB_MATROX_PROC=y
 # CONFIG_FB_MATROX_MULTIHEAD is not set
 # CONFIG_FB_ATY is not set
 # CONFIG_FB_RADEON is not set
 # CONFIG_FB_ATY128 is not set
+# CONFIG_FB_INTEL is not set
 # CONFIG_FB_SIS is not set
 # CONFIG_FB_NEOMAGIC is not set
 # CONFIG_FB_3DFX is not set
@@ -504,6 +522,7 @@
 # CONFIG_INPUT_MOUSEDEV is not set
 # CONFIG_INPUT_JOYDEV is not set
 # CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_UINPUT is not set
 CONFIG_VIOPATH=y
 
 #
@@ -557,6 +576,7 @@
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
+# CONFIG_SCx200 is not set
 # CONFIG_SCx200_GPIO is not set
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
@@ -570,12 +590,17 @@
 #
 # CONFIG_FTAPE is not set
 # CONFIG_AGP is not set
+
+#
+# Direct Rendering Manager (XFree86 DRI support)
+#
 # CONFIG_DRM is not set
 
 #
 # File systems
 #
 # CONFIG_QUOTA is not set
+# CONFIG_QFMT_V2 is not set
 CONFIG_AUTOFS_FS=y
 # CONFIG_AUTOFS4_FS is not set
 CONFIG_REISERFS_FS=y
@@ -585,6 +610,7 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
 # CONFIG_BEFS_FS is not set
 # CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
@@ -626,6 +652,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
@@ -634,6 +665,7 @@
 # CONFIG_INTERMEZZO_FS is not set
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
+# CONFIG_NFS_DIRECTIO is not set
 # CONFIG_ROOT_NFS is not set
 CONFIG_NFSD=y
 CONFIG_NFSD_V3=y
@@ -720,22 +752,29 @@
 # CONFIG_USB is not set
 
 #
+# Support for USB gadgets
+#
+# CONFIG_USB_GADGET is not set
+
+#
 # Library routines
 #
+# CONFIG_CRC32 is not set
 # CONFIG_ZLIB_INFLATE is not set
 # CONFIG_ZLIB_DEFLATE is not set
 
 #
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
 # Kernel hacking
 #
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_KGDB is not set
 # CONFIG_XMON is not set
-# CONFIG_KDB  is not set
 # CONFIG_DEBUG_SLAB is not set
-# CONFIG_KDB_OFF is not set
-CONFIG_KALLSYMS=y
 CONFIG_PPCDBG=y
 # CONFIG_DUMP is not set
-# CONFIG_DUMP_COMPRESS_RLE is not set
-# CONFIG_DUMP_COMPRESS_GZIP is not set
+CONFIG_LOG_BUF_SHIFT=0
diff -urN linux-2.4.25-pre4/arch/ppc64/defconfig linux-2.4.25-pre5/arch/ppc64/defconfig
--- linux-2.4.25-pre4/arch/ppc64/defconfig	2003-11-28 10:26:19.000000000 -0800
+++ linux-2.4.25-pre5/arch/ppc64/defconfig	2004-01-15 12:10:22.000000000 -0800
@@ -21,9 +21,10 @@
 CONFIG_SERIAL_CONSOLE=y
 CONFIG_PPC_PSERIES=y
 # CONFIG_PPC_ISERIES is not set
+CONFIG_ALTIVEC=y
 CONFIG_SMP=y
-CONFIG_NR_CPUS=32
 CONFIG_IRQ_ALL_CPUS=y
+CONFIG_NR_CPUS=32
 # CONFIG_HMT is not set
 # CONFIG_MSCHUNKS is not set
 CONFIG_RTAS_FLASH=m
@@ -31,6 +32,7 @@
 CONFIG_PPC_RTAS=y
 # CONFIG_RTAS_ERRINJCT is not set
 # CONFIG_SHARED_MEMORY_ADDRESSING is not set
+CONFIG_LPARCFG=y
 
 #
 # Loadable module support
@@ -77,6 +79,7 @@
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
 # CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
 CONFIG_BLK_DEV_LOOP=y
@@ -119,6 +122,12 @@
 CONFIG_SYN_COOKIES=y
 # CONFIG_IPV6 is not set
 # CONFIG_KHTTPD is not set
+
+#
+#    SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IPV6_SCTP__=y
+# CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
 
@@ -275,6 +284,7 @@
 # CONFIG_SCSI_IN2000 is not set
 # CONFIG_SCSI_AM53C974 is not set
 # CONFIG_SCSI_MEGARAID is not set
+# CONFIG_SCSI_MEGARAID2 is not set
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_CPQFCTS is not set
 # CONFIG_SCSI_DMX3191D is not set
@@ -358,6 +368,7 @@
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
 # CONFIG_APRICOT is not set
+# CONFIG_B44 is not set
 # CONFIG_CS89x0 is not set
 # CONFIG_TULIP is not set
 # CONFIG_DE4X5 is not set
@@ -383,7 +394,6 @@
 # CONFIG_SUNDANCE is not set
 # CONFIG_SUNDANCE_MMIO is not set
 # CONFIG_TLAN is not set
-# CONFIG_TC35815 is not set
 # CONFIG_VIA_RHINE is not set
 # CONFIG_VIA_RHINE_MMIO is not set
 # CONFIG_WINBOND_840 is not set
@@ -396,6 +406,7 @@
 CONFIG_ACENIC_OMIT_TIGON_I=y
 # CONFIG_DL2K is not set
 CONFIG_E1000=y
+CONFIG_E1000_NAPI=y
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
@@ -422,6 +433,10 @@
 # CONFIG_IBMLS is not set
 # CONFIG_3C359 is not set
 # CONFIG_TMS380TR is not set
+# CONFIG_TMSPCI is not set
+# CONFIG_TMSISA is not set
+# CONFIG_ABYSS is not set
+# CONFIG_MADGEMC is not set
 # CONFIG_NET_FC is not set
 # CONFIG_RCPCI is not set
 # CONFIG_SHAPER is not set
@@ -472,8 +487,9 @@
 CONFIG_FB_MATROX_MILLENIUM=y
 CONFIG_FB_MATROX_MYSTIQUE=y
 # CONFIG_FB_MATROX_G450 is not set
-# CONFIG_FB_MATROX_G100A is not set
-# CONFIG_FB_MATROX_PROC is not set
+CONFIG_FB_MATROX_G100A=y
+CONFIG_FB_MATROX_G100=y
+CONFIG_FB_MATROX_PROC=y
 # CONFIG_FB_MATROX_MULTIHEAD is not set
 # CONFIG_FB_ATY is not set
 # CONFIG_FB_RADEON is not set
@@ -506,6 +522,7 @@
 # CONFIG_INPUT_MOUSEDEV is not set
 # CONFIG_INPUT_JOYDEV is not set
 # CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_UINPUT is not set
 CONFIG_VIOPATH=y
 
 #
@@ -559,6 +576,7 @@
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
+# CONFIG_SCx200 is not set
 # CONFIG_SCx200_GPIO is not set
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
@@ -572,12 +590,17 @@
 #
 # CONFIG_FTAPE is not set
 # CONFIG_AGP is not set
+
+#
+# Direct Rendering Manager (XFree86 DRI support)
+#
 # CONFIG_DRM is not set
 
 #
 # File systems
 #
 # CONFIG_QUOTA is not set
+# CONFIG_QFMT_V2 is not set
 CONFIG_AUTOFS_FS=y
 # CONFIG_AUTOFS4_FS is not set
 CONFIG_REISERFS_FS=y
@@ -587,6 +610,7 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
 # CONFIG_BEFS_FS is not set
 # CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
@@ -628,6 +652,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
@@ -636,6 +665,7 @@
 # CONFIG_INTERMEZZO_FS is not set
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
+# CONFIG_NFS_DIRECTIO is not set
 # CONFIG_ROOT_NFS is not set
 CONFIG_NFSD=y
 CONFIG_NFSD_V3=y
@@ -722,18 +752,29 @@
 # CONFIG_USB is not set
 
 #
+# Support for USB gadgets
+#
+# CONFIG_USB_GADGET is not set
+
+#
 # Library routines
 #
+# CONFIG_CRC32 is not set
 # CONFIG_ZLIB_INFLATE is not set
 # CONFIG_ZLIB_DEFLATE is not set
 
 #
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
 # Kernel hacking
 #
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_KGDB is not set
 # CONFIG_XMON is not set
-# CONFIG_KDB is not set
 # CONFIG_DEBUG_SLAB is not set
 CONFIG_PPCDBG=y
 # CONFIG_DUMP is not set
+CONFIG_LOG_BUF_SHIFT=0
diff -urN linux-2.4.25-pre4/arch/ppc64/kernel/Makefile linux-2.4.25-pre5/arch/ppc64/kernel/Makefile
--- linux-2.4.25-pre4/arch/ppc64/kernel/Makefile	2004-01-15 12:10:14.000000000 -0800
+++ linux-2.4.25-pre5/arch/ppc64/kernel/Makefile	2004-01-15 12:10:22.000000000 -0800
@@ -38,7 +38,7 @@
 ifeq ($(CONFIG_PPC_PSERIES),y)
 obj-$(CONFIG_PCI) += pSeries_pci.o eeh.o
 
-obj-y += rtasd.o nvram.o
+obj-y += nvram.o rtasd.o
 endif
 
 obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o
diff -urN linux-2.4.25-pre4/arch/ppc64/kernel/chrp_setup.c linux-2.4.25-pre5/arch/ppc64/kernel/chrp_setup.c
--- linux-2.4.25-pre4/arch/ppc64/kernel/chrp_setup.c	2004-01-15 12:10:14.000000000 -0800
+++ linux-2.4.25-pre5/arch/ppc64/kernel/chrp_setup.c	2004-01-15 12:10:22.000000000 -0800
@@ -158,7 +158,7 @@
 		ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
 	else
 #endif
-	ROOT_DEV = to_kdev_t(0x0802); /* sda2 (sda1 is for the kernel) */
+	ROOT_DEV = to_kdev_t(0x0803); /* sda3 (sda1 is for the kernel or the bootloader) */
 
 	machine_check_init();
 
@@ -282,9 +282,11 @@
 
  	#ifndef CONFIG_PPC_ISERIES
  		ppc_md.pcibios_fixup = pSeries_pcibios_fixup;
+		ppc_md.log_error     = pSeries_log_error;
  	#else 
  		ppc_md.pcibios_fixup = NULL;
  		// ppc_md.pcibios_fixup = iSeries_pcibios_fixup;
+		ppc_md.log_error     = NULL;
  	#endif
 
 
diff -urN linux-2.4.25-pre4/arch/ppc64/kernel/eeh.c linux-2.4.25-pre5/arch/ppc64/kernel/eeh.c
--- linux-2.4.25-pre4/arch/ppc64/kernel/eeh.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.25-pre5/arch/ppc64/kernel/eeh.c	2004-01-15 12:10:22.000000000 -0800
@@ -30,6 +30,7 @@
 #include <asm/processor.h>
 #include <asm/naca.h>
 #include <asm/io.h>
+#include <asm/machdep.h>
 #include "pci.h"
 
 #define BUID_HI(buid) ((buid) >> 32)
@@ -114,6 +115,18 @@
 		ret = rtas_call(ibm_read_slot_reset_state, 3, 3, rets,
 				dn->eeh_config_addr, BUID_HI(dn->phb->buid), BUID_LO(dn->phb->buid));
 		if (ret == 0 && rets[1] == 1 && rets[0] >= 2) {
+			unsigned char   slot_err_buf[RTAS_ERROR_LOG_MAX];
+			unsigned long   slot_err_ret;
+
+			memset(slot_err_buf, 0, RTAS_ERROR_LOG_MAX);
+			slot_err_ret = rtas_call(rtas_token("ibm,slot-error-detail"),
+						 8, 1, dn->eeh_config_addr,
+						 BUID_HI(dn->phb->buid), BUID_LO(dn->phb->buid),
+						 NULL, 0, __pa(slot_err_buf), RTAS_ERROR_LOG_MAX,
+						 2 /* Permanent Error */);
+			if (slot_err_ret == 0)
+				log_error(slot_err_buf, ERR_TYPE_RTAS_LOG, 1 /* Fatal */);
+
 			panic("EEH:  MMIO failure (%ld) on device:\n  %s %s\n",
 			      rets[0], dev->slot_name, dev->name);
 		}
diff -urN linux-2.4.25-pre4/arch/ppc64/kernel/iSeries_setup.c linux-2.4.25-pre5/arch/ppc64/kernel/iSeries_setup.c
--- linux-2.4.25-pre4/arch/ppc64/kernel/iSeries_setup.c	2004-01-15 12:10:14.000000000 -0800
+++ linux-2.4.25-pre5/arch/ppc64/kernel/iSeries_setup.c	2004-01-15 12:10:22.000000000 -0800
@@ -704,6 +704,9 @@
 	systemcfg->processor = xIoHriProcessorVpd[procIx].xPVR;
 	printk("Processor version = %x\n", systemcfg->processor);
 
+#if defined(CONFIG_IRQ_ALL_CPUS)
+	do_spread_lpevents(MAX_PACAS);
+#endif
 }
 
 /*
diff -urN linux-2.4.25-pre4/arch/ppc64/kernel/nvram.c linux-2.4.25-pre5/arch/ppc64/kernel/nvram.c
--- linux-2.4.25-pre4/arch/ppc64/kernel/nvram.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.25-pre5/arch/ppc64/kernel/nvram.c	2004-01-15 12:10:22.000000000 -0800
@@ -20,16 +20,44 @@
 #include <linux/fcntl.h>
 #include <linux/nvram.h>
 #include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
 #include <asm/uaccess.h>
 #include <asm/nvram.h>
 #include <asm/rtas.h>
 #include <asm/prom.h>
 
-static unsigned int rtas_nvram_size;
+#include <linux/string.h>
+
+/*#define DEBUG_NVRAM*/
+
+static int scan_nvram_partitions(void);
+static int setup_nvram_partition(void);
+static int create_os_nvram_partition(void);
+static int remove_os_nvram_partition(void);
+static unsigned char nvram_checksum(struct nvram_header *p);
+static int write_nvram_header(struct nvram_partition * part);
+static ssize_t __read_nvram(char *buf, size_t count, loff_t *index);
+static ssize_t __write_nvram(char *buf, size_t count, loff_t *index);
+
+static unsigned int rtas_nvram_size = 0;
 static unsigned int nvram_fetch, nvram_store;
-static char nvram_buf[4];	/* assume this is in the first 4GB */
+static char nvram_buf[NVRW_CNT];	/* assume this is in the first 4GB */
+static struct nvram_partition * nvram_part;
+static long error_log_nvram_index = -1;
+static long error_log_nvram_size = 0;
+static spinlock_t nvram_lock = SPIN_LOCK_UNLOCKED;
+
+volatile int no_more_logging = 1;
+
+extern volatile int error_log_cnt;
+
+struct err_log_info {
+	int error_type;
+	unsigned int seq_num;
+};
 
-static loff_t nvram_llseek(struct file *file, loff_t offset, int origin)
+static loff_t dev_ppc64_nvram_llseek(struct file *file, loff_t offset, int origin)
 {
 	switch (origin) {
 	case 1:
@@ -46,53 +74,72 @@
 }
 
 
-static ssize_t read_nvram(struct file *file, char *buf,
+static ssize_t dev_ppc64_read_nvram(struct file *file, char *buf,
 			  size_t count, loff_t *ppos)
 {
-	unsigned int i;
 	unsigned long len;
-	char *p = buf;
+	char *tmp_buffer;
 
 	if (verify_area(VERIFY_WRITE, buf, count))
 		return -EFAULT;
 	if (*ppos >= rtas_nvram_size)
 		return 0;
-	for (i = *ppos; count > 0 && i < rtas_nvram_size; ++i, ++p, --count) {
-		if ((rtas_call(nvram_fetch, 3, 2, &len, i, __pa(nvram_buf), 1) != 0) ||
-		    len != 1)
-			return -EIO;
-		if (__put_user(nvram_buf[0], p))
-			return -EFAULT;
+	if (count > rtas_nvram_size)
+		count = rtas_nvram_size;
+
+	tmp_buffer = kmalloc(count, GFP_KERNEL);
+	if (!tmp_buffer) {
+		printk(KERN_ERR "dev_ppc64_read_nvram: kmalloc failed\n");
+		return 0;
 	}
-	*ppos = i;
-	return p - buf;
+
+	len = read_nvram(tmp_buffer, count, ppos);
+	if ((long)len <= 0) {
+		kfree(tmp_buffer);
+		return len;
+	}
+
+	if (copy_to_user(buf, tmp_buffer, len)) {
+		kfree(tmp_buffer);
+		return -EFAULT;
+	}
+
+	kfree(tmp_buffer);
+	return len;
+
 }
 
-static ssize_t write_nvram(struct file *file, const char *buf,
+static ssize_t dev_ppc64_write_nvram(struct file *file, const char *buf,
 			   size_t count, loff_t *ppos)
 {
-	unsigned int i;
 	unsigned long len;
-	const char *p = buf;
-	char c;
+	char * tmp_buffer;
 
 	if (verify_area(VERIFY_READ, buf, count))
 		return -EFAULT;
 	if (*ppos >= rtas_nvram_size)
 		return 0;
-	for (i = *ppos; count > 0 && i < rtas_nvram_size; ++i, ++p, --count) {
-		if (__get_user(c, p))
-			return -EFAULT;
-		nvram_buf[0] = c;
-		if ((rtas_call(nvram_store, 3, 2, &len, i, __pa(nvram_buf), 1) != 0) ||
-		    len != 1)
-			return -EIO;
+	if (count > rtas_nvram_size)
+		count = rtas_nvram_size;
+
+	tmp_buffer = kmalloc(count, GFP_KERNEL);
+	if (!tmp_buffer) {
+		printk(KERN_ERR "dev_ppc64_write_nvram: kmalloc failed\n");
+		return 0;
 	}
-	*ppos = i;
-	return p - buf;
+
+	if (copy_from_user(tmp_buffer, buf, count)) {
+		kfree(tmp_buffer);
+		return -EFAULT;
+	}
+
+	len = write_nvram(tmp_buffer, count, ppos);
+
+	kfree(tmp_buffer);
+	return len;
 }
 
-static int nvram_ioctl(struct inode *inode, struct file *file,
+static int dev_ppc64_nvram_ioctl(struct inode *inode, struct file *file,
 	unsigned int cmd, unsigned long arg)
 {
 	return -EINVAL;
@@ -100,10 +147,10 @@
 
 struct file_operations nvram_fops = {
 	.owner =	THIS_MODULE,
-	.llseek =	nvram_llseek,
-	.read =		read_nvram,
-	.write =	write_nvram,
-	.ioctl =	nvram_ioctl,
+	.llseek =	dev_ppc64_nvram_llseek,
+	.read =		dev_ppc64_read_nvram,
+	.write =	dev_ppc64_write_nvram,
+	.ioctl =	dev_ppc64_nvram_ioctl
 };
 
 static struct miscdevice nvram_dev = {
@@ -112,26 +159,613 @@
 	&nvram_fops
 };
 
+ssize_t read_nvram(char *buf, size_t count, loff_t *index)
+{
+	unsigned long	s;
+	ssize_t		rc;
+
+	spin_lock_irqsave(&nvram_lock, s);
+	rc = __read_nvram(buf, count, index);
+	spin_unlock_irqrestore(&nvram_lock, s);
+
+	return rc;
+}
+static ssize_t __read_nvram(char *buf, size_t count, loff_t *index)
+{
+	unsigned int i;
+	unsigned long len;
+	unsigned long remainder;
+	char *p = buf;
+
+	if (((*index + count) > rtas_nvram_size) || (count < 0))
+		return 0;
+
+	if (count <= NVRW_CNT) {
+		remainder = count;
+	} else {
+		remainder = count % NVRW_CNT;
+	}
+
+	if (remainder) {
+		if((rtas_call(nvram_fetch, 3, 2, &len, *index, __pa(nvram_buf),
+			      remainder) != 0) || len != remainder) {
+			return -EIO;
+		}
+
+		count -= remainder;
+		memcpy(p, nvram_buf, remainder);
+		p += remainder;
+	}
+
+	for (i = *index + remainder; count > 0 && i < rtas_nvram_size;
+	     count -= NVRW_CNT) {
+		if ((rtas_call(nvram_fetch, 3, 2, &len, i, __pa(nvram_buf),
+			       NVRW_CNT) != 0) || len != NVRW_CNT) {
+			return -EIO;
+		}
+
+		memcpy(p, nvram_buf, NVRW_CNT);
+
+		p += NVRW_CNT;
+		i += NVRW_CNT;
+	}
+
+	*index = i;
+	return p - buf;
+}
+
+ssize_t write_nvram(char *buf, size_t count, loff_t *index)
+{
+	unsigned long	s;
+	ssize_t		rc;
+
+	spin_lock_irqsave(&nvram_lock, s);
+	rc = __write_nvram(buf, count, index);
+	spin_unlock_irqrestore(&nvram_lock, s);
+
+	return rc;
+}
+static ssize_t __write_nvram(char *buf, size_t count, loff_t *index)
+{
+	unsigned int i;
+	unsigned long len;
+	const char *p = buf;
+	unsigned long remainder;
+
+	if (((*index + count) > rtas_nvram_size) || (count < 0))
+		return 0;
+
+	if (count <= NVRW_CNT) {
+		remainder = count;
+	} else {
+		remainder = count % NVRW_CNT;
+	}
+
+	if (remainder) {
+		memcpy(nvram_buf, p, remainder);
+
+		if((rtas_call(nvram_store, 3, 2, &len, *index, __pa(nvram_buf),
+			      remainder) != 0) || len != remainder) {
+			return -EIO;
+		}
+
+		count -= remainder;
+		p += remainder;
+	}
+
+	for (i = *index + remainder; count > 0 && i < rtas_nvram_size;
+	     count -= NVRW_CNT) {
+
+		memcpy(nvram_buf, p, NVRW_CNT);
+
+		if ((rtas_call(nvram_store, 3, 2, &len, i, __pa(nvram_buf),
+			       NVRW_CNT) != 0) || len != NVRW_CNT) {
+			return -EIO;
+		}
+
+		p += NVRW_CNT;
+		i += NVRW_CNT;
+	}
+
+	*index = i;
+	return p - buf;
+}
+
 int __init nvram_init(void)
 {
 	struct device_node *nvram;
 	unsigned int *nbytes_p, proplen;
+	int error;
+	int rc;
+
 	if ((nvram = find_type_devices("nvram")) != NULL) {
 		nbytes_p = (unsigned int *)get_property(nvram, "#bytes", &proplen);
 		if (nbytes_p && proplen == sizeof(unsigned int)) {
 			rtas_nvram_size = *nbytes_p;
+		} else {
+			return -EIO;
 		}
+	} else {
+		/* If we don't know how big NVRAM is then we shouldn't touch
+		   the nvram partitions */
+		return -EIO;
 	}
+
 	nvram_fetch = rtas_token("nvram-fetch");
+	if (nvram_fetch == RTAS_UNKNOWN_SERVICE) {
+		printk("nvram_init: Does not support nvram-fetch\n");
+		return -EIO;
+	}
+
 	nvram_store = rtas_token("nvram-store");
+	if (nvram_store == RTAS_UNKNOWN_SERVICE) {
+		printk("nvram_init: Does not support nvram-store\n");
+		return -EIO;
+	}
 	printk(KERN_INFO "PPC64 nvram contains %d bytes\n", rtas_nvram_size);
 
-	return misc_register(&nvram_dev);
+	rc = misc_register(&nvram_dev);
+	if (rc) {
+		printk(KERN_ERR "nvram_init: Failed misc_register (%d)\n", rc);
+		/* Going to continue to setup nvram for internal
+		 * kernel services */
+	}
+
+
+	/* initialize our anchor for the nvram partition list */
+	nvram_part = kmalloc(sizeof(struct nvram_partition), GFP_KERNEL);
+	if (!nvram_part) {
+		printk(KERN_ERR "nvram_init: Failed kmalloc\n");
+		return -ENOMEM;
+	}
+	INIT_LIST_HEAD(&nvram_part->partition);
+
+	/* Get all the NVRAM partitions */
+	error = scan_nvram_partitions();
+	if (error) {
+		printk(KERN_ERR "nvram_init: Failed scan_nvram_partitions\n");
+		return error;
+	}
+
+	error = setup_nvram_partition();
+	if (error) {
+		printk(KERN_WARNING "nvram_init: Could not find nvram partition"
+		       " for nvram buffered error logging.\n");
+		return error;
+	}
+
+#ifdef DEBUG_NVRAM
+	print_nvram_partitions("NVRAM Partitions");
+#endif
+
+	return rc;
 }
 
 void __exit nvram_cleanup(void)
 {
-        misc_deregister( &nvram_dev );
+	misc_deregister( &nvram_dev );
+}
+
+static int scan_nvram_partitions(void)
+{
+	loff_t cur_index = 0;
+	struct nvram_header phead;
+	struct nvram_partition * tmp_part;
+	unsigned char c_sum;
+	long size;
+
+	while (cur_index < rtas_nvram_size) {
+
+		size = read_nvram((char *)&phead, NVRAM_HEADER_LEN, &cur_index);
+		if (size != NVRAM_HEADER_LEN) {
+			printk(KERN_ERR "scan_nvram_partitions: Error parsing "
+			       "nvram partitions\n");
+			return size;
+		}
+
+		cur_index -= NVRAM_HEADER_LEN; /* read_nvram will advance us */
+
+		c_sum = nvram_checksum(&phead);
+		if (c_sum != phead.checksum)
+			printk(KERN_WARNING "WARNING: nvram partition checksum "
+			       "was %02x, should be %02x!\n", phead.checksum, c_sum);
+
+		tmp_part = kmalloc(sizeof(struct nvram_partition), GFP_KERNEL);
+		if (!tmp_part) {
+			printk(KERN_ERR "scan_nvram_partitions: kmalloc failed\n");
+			return -ENOMEM;
+		}
+
+		memcpy(&tmp_part->header, &phead, NVRAM_HEADER_LEN);
+		tmp_part->index = cur_index;
+		list_add_tail(&tmp_part->partition, &nvram_part->partition);
+
+		cur_index += phead.length * NVRAM_BLOCK_LEN;
+	}
+
+	return 0;
+}
+
+/* setup_nvram_partition
+ *
+ * This will setup the partition we need for buffering the
+ * error logs and cleanup partitions if needed.
+ *
+ * The general strategy is the following:
+ * 1.) If there is ppc64,linux partition large enough then use it.
+ * 2.) If there is not a ppc64,linux partition large enough, search
+ * for a free partition that is large enough.
+ * 3.) If there is not a free partition large enough remove
+ * _all_ OS partitions and consolidate the space.
+ * 4.) Will first try getting a chunk that will satisfy the maximum
+ * error log size (NVRAM_MAX_REQ).
+ * 5.) If the max chunk cannot be allocated then try finding a chunk
+ * that will satisfy the minum needed (NVRAM_MIN_REQ).
+ */
+static int setup_nvram_partition(void)
+{
+	struct list_head * p;
+	struct nvram_partition * part;
+	int rc;
+
+	/* see if we have an OS partition that meets our needs.
+	   will try getting the max we need.  If not we'll delete
+	   partitions and try again. */
+	list_for_each(p, &nvram_part->partition) {
+		part = list_entry(p, struct nvram_partition, partition);
+		if (part->header.signature != NVRAM_SIG_OS)
+			continue;
+
+		if (strcmp(part->header.name, "ppc64,linux"))
+			continue;
+
+		if (part->header.length >= NVRAM_MIN_REQ) {
+			/* found our partition */
+			error_log_nvram_index = part->index + NVRAM_HEADER_LEN;
+			error_log_nvram_size = (part->header.length * NVRAM_BLOCK_LEN) -
+						NVRAM_HEADER_LEN - sizeof(struct err_log_info);
+			return 0;
+		}
+	}
+
+	/* try creating a partition with the free space we have */
+	rc = create_os_nvram_partition();
+	if (!rc) {
+		return 0;
+	}
+
+	/* need to free up some space */
+	rc = remove_os_nvram_partition();
+	if (rc) {
+		return rc;
+	}
+
+	/* create a partition in this new space */
+	rc = create_os_nvram_partition();
+	if (rc) {
+		printk(KERN_ERR "create_os_nvram_partition: Could not find a "
+		       "NVRAM partition large enough (%d)\n", rc);
+		return rc;
+	}
+
+	return 0;
+}
+
+static int remove_os_nvram_partition(void)
+{
+	struct list_head *i;
+	struct list_head *j;
+	struct nvram_partition * part;
+	struct nvram_partition * cur_part;
+	int rc;
+
+	list_for_each(i, &nvram_part->partition) {
+		part = list_entry(i, struct nvram_partition, partition);
+		if (part->header.signature != NVRAM_SIG_OS)
+			continue;
+
+		/* Make os partition a free partition */
+		part->header.signature = NVRAM_SIG_FREE;
+		sprintf(part->header.name, "wwwwwwwwwwww");
+		part->header.checksum = nvram_checksum(&part->header);
+
+		/* Merge contiguous free partitions backwards */
+		list_for_each_prev(j, &part->partition) {
+			cur_part = list_entry(j, struct nvram_partition, partition);
+			if (cur_part == nvram_part || cur_part->header.signature != NVRAM_SIG_FREE) {
+				break;
+			}
+
+			part->header.length += cur_part->header.length;
+			part->header.checksum = nvram_checksum(&part->header);
+			part->index = cur_part->index;
+
+			list_del(&cur_part->partition);
+			kfree(cur_part);
+			j = &part->partition; /* fixup our loop */
+		}
+
+		/* Merge contiguous free partitions forwards */
+		list_for_each(j, &part->partition) {
+			cur_part = list_entry(j, struct nvram_partition, partition);
+			if (cur_part == nvram_part || cur_part->header.signature != NVRAM_SIG_FREE) {
+				break;
+			}
+
+			part->header.length += cur_part->header.length;
+			part->header.checksum = nvram_checksum(&part->header);
+
+			list_del(&cur_part->partition);
+			kfree(cur_part);
+			j = &part->partition; /* fixup our loop */
+		}
+
+		rc = write_nvram_header(part);
+		if (rc <= 0) {
+			printk(KERN_ERR "remove_os_nvram_partition: write_nvram failed (%d)\n", rc);
+			return rc;
+		}
+
+	}
+
+	return 0;
+}
+
+/* create_os_nvram_partition
+ *
+ * Create a OS linux partition to buffer error logs.
+ * Will create a partition starting at the first free
+ * space found if space has enough room.
+ */
+static int create_os_nvram_partition(void)
+{
+	struct list_head * p;
+	struct nvram_partition * part;
+	struct nvram_partition * new_part = NULL;
+	struct nvram_partition * free_part;
+	struct err_log_info seq_init = { 0, 0 };
+	loff_t tmp_index;
+	long size = 0;
+	int rc;
+
+	/* Find a free partition that will give us the maximum needed size
+	   If can't find one that will give us the minimum size needed */
+	list_for_each(p, &nvram_part->partition) {
+		part = list_entry(p, struct nvram_partition, partition);
+		if (part->header.signature != NVRAM_SIG_FREE)
+			continue;
+
+		if (part->header.length >= NVRAM_MAX_REQ) {
+			size = NVRAM_MAX_REQ;
+			free_part = part;
+			break;
+		}
+		if (!size && part->header.length >= NVRAM_MIN_REQ) {
+			size = NVRAM_MIN_REQ;
+			free_part = part;
+		}
+	}
+	if (!size) {
+		return -ENOSPC;
+	}
+
+	/* Create our OS partition */
+	new_part = kmalloc(sizeof(struct nvram_partition), GFP_KERNEL);
+	if (!new_part) {
+		printk(KERN_ERR "create_os_nvram_partition: kmalloc failed\n");
+		return -ENOMEM;
+	}
+
+	new_part->index = free_part->index;
+	new_part->header.signature = NVRAM_SIG_OS;
+	new_part->header.length = size;
+	sprintf(new_part->header.name, "ppc64,linux");
+	new_part->header.checksum = nvram_checksum(&new_part->header);
+
+	rc = write_nvram_header(new_part);
+	if (rc <= 0) {
+		printk(KERN_ERR "create_os_nvram_partition: write_nvram_header \
+				failed (%d)\n", rc);
+		kfree(new_part);
+		return rc;
+	}
+
+	/* make sure and initialize to zero the sequence number and the error
+	   type logged */
+	tmp_index = new_part->index + NVRAM_HEADER_LEN;
+	rc = write_nvram((char *)&seq_init, sizeof(seq_init), &tmp_index);
+	if (rc <= 0) {
+		printk(KERN_ERR "create_os_nvram_partition: write_nvram failed (%d)\n", rc);
+		kfree(new_part);
+		return rc;
+	}
+
+	error_log_nvram_index = new_part->index + NVRAM_HEADER_LEN;
+	error_log_nvram_size = (new_part->header.length * NVRAM_BLOCK_LEN) -
+		NVRAM_HEADER_LEN - sizeof(struct err_log_info);
+
+	list_add_tail(&new_part->partition, &free_part->partition);
+
+	if (free_part->header.length <= size) {
+		list_del(&free_part->partition);
+		kfree(free_part);
+		return 0;
+	}
+
+	/* Adjust the partition we stole the space from */
+	free_part->index += size * NVRAM_BLOCK_LEN;
+	free_part->header.length -= size;
+	free_part->header.checksum = nvram_checksum(&free_part->header);
+
+	rc = write_nvram_header(free_part);
+	if (rc <= 0) {
+		printk(KERN_ERR "create_os_nvram_partition: write_nvram_header "
+		       "failed (%d)\n", rc);
+		error_log_nvram_index = -1;
+		error_log_nvram_size = 0;
+		return rc;
+	}
+
+	return 0;
+}
+
+
+void print_nvram_partitions(char * label)
+{
+	struct list_head * p;
+	struct nvram_partition * tmp_part;
+
+	printk(KERN_WARNING "--------%s---------\n", label);
+	printk(KERN_WARNING "indx\t\tsig\tchks\tlen\tname\n");
+	list_for_each(p, &nvram_part->partition) {
+		tmp_part = list_entry(p, struct nvram_partition, partition);
+		printk(KERN_WARNING "%d    \t%02x\t%02x\t%d\t%s\n",
+		       tmp_part->index, tmp_part->header.signature,
+		       tmp_part->header.checksum, tmp_part->header.length,
+		       tmp_part->header.name);
+	}
+}
+
+/* write_error_log_nvram
+ * In NVRAM the partition containing the error log buffer will looks like:
+ * Header (in bytes):
+ * +-----------+----------+--------+------------+------------------+
+ * | signature | checksum | length | name       | data             |
+ * |0          |1         |2      3|4         15|16        length-1|
+ * +-----------+----------+--------+------------+------------------+
+ * NOTE: length is in NVRAM_BLOCK_LEN
+ *
+ * The 'data' section would look like (in bytes):
+ * +--------------+------------+-----------------------------------+
+ * | event_logged | sequence # | error log                         |
+ * |0            3|4          7|8            error_log_nvram_size-1|
+ * +--------------+------------+-----------------------------------+
+ *
+ * event_logged: 0 if event has not been logged to syslog, 1 if it has
+ * sequence #: The unique sequence # for each event. (until it wraps)
+ * error log: The error log from event_scan
+ */
+int write_error_log_nvram(char * buff, int num_bytes, unsigned int err_type)
+{
+	int rc;
+	loff_t tmp_index;
+	struct err_log_info info;
+
+	if (no_more_logging) {
+		return -EPERM;
+	}
+
+	if (error_log_nvram_index == -1) {
+		return -ESPIPE;
+	}
+
+	if (num_bytes > error_log_nvram_size) {
+		num_bytes = error_log_nvram_size;
+	}
+
+	info.error_type = err_type;
+	info.seq_num = error_log_cnt;
+
+	tmp_index = error_log_nvram_index;
+
+	rc = write_nvram((char *)&info, sizeof(struct err_log_info), &tmp_index);
+	if (rc <= 0) {
+		printk(KERN_ERR "write_error_log_nvram: Failed write_nvram (%d)\n", rc);
+		return rc;
+	}
+
+	rc = write_nvram(buff, num_bytes, &tmp_index);
+	if (rc <= 0) {
+		printk(KERN_ERR "write_error_log_nvram: Failed write_nvram (%d)\n", rc);
+		return rc;
+	}
+
+	return 0;
+}
+
+/* read_error_log_nvram
+ *
+ * Reads nvram for error log for at most 'num_bytes'
+ */
+int read_error_log_nvram(char * buff, int num_bytes, unsigned int * err_type)
+{
+	int rc;
+	loff_t tmp_index;
+	struct err_log_info info;
+
+	if (error_log_nvram_index == -1)
+		return -1;
+
+	if (num_bytes > error_log_nvram_size)
+		num_bytes = error_log_nvram_size;
+
+	tmp_index = error_log_nvram_index;
+
+	rc = read_nvram((char *)&info, sizeof(struct err_log_info), &tmp_index);
+	if (rc <= 0) {
+		printk(KERN_ERR "read_error_log_nvram: Failed read_nvram (%d)\n", rc);
+		return rc;
+	}
+
+	rc = read_nvram(buff, num_bytes, &tmp_index);
+	if (rc <= 0) {
+		printk(KERN_ERR "read_error_log_nvram: Failed read_nvram (%d)\n", rc);
+		return rc;
+	}
+
+	error_log_cnt = info.seq_num;
+	*err_type = info.error_type;
+
+	return 0;
+}
+
+/* This doesn't actually zero anything, but it sets the event_logged
+ * word to tell that this event is safely in syslog.
+ */
+int clear_error_log_nvram()
+{
+	loff_t tmp_index;
+	int clear_word = ERR_FLAG_ALREADY_LOGGED;
+	int rc;
+
+	if (error_log_nvram_index == -1) {
+		return -ESPIPE;
+	}
+
+	tmp_index = error_log_nvram_index;
+
+	rc = write_nvram((char *)&clear_word, sizeof(int), &tmp_index);
+	if (rc <= 0) {
+		printk(KERN_ERR "clear_error_log_nvram: Failed write_nvram (%d)\n", rc);
+		return rc;
+	}
+
+	return 0;
+}
+
+static int write_nvram_header(struct nvram_partition * part)
+{
+	loff_t tmp_index;
+	int rc;
+
+	tmp_index = part->index;
+	rc = write_nvram((char *)&part->header, NVRAM_HEADER_LEN, &tmp_index);
+
+	return rc;
+}
+
+static unsigned char nvram_checksum(struct nvram_header *p)
+{
+	unsigned int c_sum, c_sum2;
+	unsigned short *sp = (unsigned short *)p->name; /* assume 6 shorts */
+	c_sum = p->signature + p->length + sp[0] + sp[1] + sp[2] + sp[3] + sp[4] + sp[5];
+
+	/* The sum may have spilled into the 3rd byte.  Fold it back. */
+	c_sum = ((c_sum & 0xffff) + (c_sum >> 16)) & 0xffff;
+	/* The sum cannot exceed 2 bytes.  Fold it into a checksum */
+	c_sum2 = (c_sum >> 8) + (c_sum << 8);
+	c_sum = ((c_sum + c_sum2) >> 8) & 0xff;
+	return c_sum;
 }
 
 module_init(nvram_init);
diff -urN linux-2.4.25-pre4/arch/ppc64/kernel/perfmon.c linux-2.4.25-pre5/arch/ppc64/kernel/perfmon.c
--- linux-2.4.25-pre4/arch/ppc64/kernel/perfmon.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.25-pre5/arch/ppc64/kernel/perfmon.c	2004-01-15 12:10:22.000000000 -0800
@@ -420,6 +420,33 @@
 
 	return(0); 
 }
+
+static long plpar_perfmon(int mode)
+{
+        return plpar_hcall_norets(H_PERFMON, mode, 0); 
+}
+
+static void pmc_configure_hardware() {
+	/* 
+	 * Debug bus enabled is required on GP for timeslice mode.
+	 * Flood enabled is required on GP for PMC cycle profile mode
+	 *   iSeries SP sets this by default.  pSeries requires the OS to enable.
+	 */
+	if (cur_cpu_spec->cpu_features & CPU_FTR_SLB) {
+		/* Set up the debug bus to pmc mode - a feature of GP */
+		switch(systemcfg->platform) {
+		case PLATFORM_ISERIES_LPAR:
+			HvCall_setDebugBus(1);
+			break;
+		case PLATFORM_PSERIES_LPAR:
+			plpar_perfmon(1);
+			break;
+		case PLATFORM_PSERIES:
+			mtspr(HID0, mfspr(HID0) | 0x0000080000000000);
+		} 
+	} 
+}
+
 /*
  * pmc_profile
  *
@@ -783,29 +810,3 @@
 	}
 	spin_unlock(&pmc_lock);
 }
-
-long plpar_perfmon(int mode)
-{
-        return plpar_hcall_norets(H_PERFMON, mode, 0); 
-}
-
-void pmc_configure_hardware() {
-	/* 
-	 * Debug bus enabled is required on GP for timeslice mode.
-	 * Flood enabled is required on GP for PMC cycle profile mode
-	 *   iSeries SP sets this by default.  pSeries requires the OS to enable.
-	 */
-	if (cur_cpu_spec->cpu_features & CPU_FTR_SLB) {
-		/* Set up the debug bus to pmc mode - a feature of GP */
-		switch(systemcfg->platform) {
-		case PLATFORM_ISERIES_LPAR:
-			HvCall_setDebugBus(1);
-			break;
-		case PLATFORM_PSERIES_LPAR:
-			plpar_perfmon(1);
-			break;
-		case PLATFORM_PSERIES:
-			mtspr(HID0, mfspr(HID0) | 0x0000080000000000);
-		} 
-	} 
-}
diff -urN linux-2.4.25-pre4/arch/ppc64/kernel/prom.c linux-2.4.25-pre5/arch/ppc64/kernel/prom.c
--- linux-2.4.25-pre4/arch/ppc64/kernel/prom.c	2004-01-15 12:10:14.000000000 -0800
+++ linux-2.4.25-pre5/arch/ppc64/kernel/prom.c	2004-01-15 12:10:22.000000000 -0800
@@ -168,7 +168,6 @@
 
 extern struct rtas_t rtas;
 extern unsigned long klimit;
-extern unsigned long embedded_sysmap_end;
 extern struct lmb lmb;
 #ifdef CONFIG_MSCHUNKS
 extern struct msChunks msChunks;
@@ -1482,9 +1481,6 @@
 
 	/* Default machine type. */
 	_systemcfg->platform = PLATFORM_PSERIES;
-	/* Reset klimit to take into account the embedded system map */
-	if (RELOC(embedded_sysmap_end))
-		RELOC(klimit) = __va(PAGE_ALIGN(RELOC(embedded_sysmap_end)));
 
 	/* Get a handle to the prom entry point before anything else */
 	_prom->entry = pp;
diff -urN linux-2.4.25-pre4/arch/ppc64/kernel/ras.c linux-2.4.25-pre5/arch/ppc64/kernel/ras.c
--- linux-2.4.25-pre4/arch/ppc64/kernel/ras.c	2004-01-15 12:10:14.000000000 -0800
+++ linux-2.4.25-pre5/arch/ppc64/kernel/ras.c	2004-01-15 12:10:22.000000000 -0800
@@ -116,6 +116,9 @@
 		    *((unsigned long *)&log_entry), status); 
 	printk(KERN_WARNING 
 	       "EPOW <0x%lx 0x%lx>\n",*((unsigned long *)&log_entry), status);
+
+	/* format and print the extended information */
+	log_error((char *)&log_entry, ERR_TYPE_RTAS_LOG, 0);
 }
 
 /*
@@ -132,6 +135,7 @@
 	struct rtas_error_log log_entry;
 	unsigned int size = sizeof(log_entry);
 	long status = 0xdeadbeef;
+	int fatal;
 
 	status = rtas_call(rtas_token("check-exception"), 6, 1, NULL, 
 			   0x500, irq, 
@@ -139,8 +143,15 @@
 			   1, /* Time Critical */
 			   __pa(&log_entry), size);
 
-	if((status != 1) && 
-	   (log_entry.severity >= SEVERITY_ERROR_SYNC)) {
+	if ((status == 0) && (log_entry.severity >= SEVERITY_ERROR_SYNC))
+		fatal = 1;
+	else
+		fatal = 0;
+
+	/* format and print the extended information */
+	log_error((char *)&log_entry, ERR_TYPE_RTAS_LOG, fatal);
+
+	if (fatal) {
 		udbg_printf("HW Error <0x%lx 0x%lx>\n",
 			    *((unsigned long *)&log_entry), status);
 		printk(KERN_EMERG 
@@ -150,6 +161,7 @@
 #ifndef DEBUG
 		/* Don't actually power off when debugging so we can test
 		 * without actually failing while injecting errors.
+		 * Error data will not be logged to syslog.
 		 */
 		ppc_md.power_off();
 #endif
diff -urN linux-2.4.25-pre4/arch/ppc64/kernel/rtas.c linux-2.4.25-pre5/arch/ppc64/kernel/rtas.c
--- linux-2.4.25-pre4/arch/ppc64/kernel/rtas.c	2004-01-15 12:10:14.000000000 -0800
+++ linux-2.4.25-pre5/arch/ppc64/kernel/rtas.c	2004-01-15 12:10:22.000000000 -0800
@@ -228,7 +228,8 @@
 	rtas_firmware_flash_list.num_blocks = 0;
 	flist = (struct flash_block_list *)&rtas_firmware_flash_list;
 	rtas_block_list = virt_to_absolute((unsigned long)flist);
-	if (rtas_block_list >= (4UL << 20)) {
+
+	if (rtas_block_list >= 4UL*1024*1024*1024) {
 		printk(KERN_ALERT "FLASH: kernel bug...flash list header addr above 4GB\n");
 		return;
 	}
diff -urN linux-2.4.25-pre4/arch/ppc64/kernel/rtas_flash.c linux-2.4.25-pre5/arch/ppc64/kernel/rtas_flash.c
--- linux-2.4.25-pre4/arch/ppc64/kernel/rtas_flash.c	2002-11-28 15:53:11.000000000 -0800
+++ linux-2.4.25-pre5/arch/ppc64/kernel/rtas_flash.c	2004-01-15 12:10:22.000000000 -0800
@@ -25,6 +25,52 @@
 #define MODULE_NAME "rtas_flash"
 
 #define FIRMWARE_FLASH_NAME "firmware_flash"
+#define FIRMWARE_UPDATE_NAME "firmware_update"
+#define MANAGE_FLASH_NAME "manage_flash"
+#define VALIDATE_FLASH_NAME "validate_flash"
+
+/* General RTAS Status Codes */
+#define RTAS_RC_SUCCESS  0
+#define RTAS_RC_HW_ERR	-1
+#define RTAS_RC_BUSY	-2
+
+/* Flash image status values */
+#define FLASH_AUTH           -9002 /* RTAS Not Service Authority Partition */
+#define FLASH_NO_OP          -1099 /* No operation initiated by user */
+#define FLASH_IMG_SHORT	     -1005 /* Flash image shorter than expected */
+#define FLASH_IMG_BAD_LEN    -1004 /* Bad length value in flash list block */
+#define FLASH_IMG_NULL_DATA  -1003 /* Bad data value in flash list block */
+#define FLASH_IMG_READY      0     /* Firmware img ready for flash on reboot */
+
+/* Manage image status values */
+#define MANAGE_AUTH          -9002 /* RTAS Not Service Authority Partition */
+#define MANAGE_ACTIVE_ERR    -9001 /* RTAS Cannot Overwrite Active Img */
+#define MANAGE_NO_OP         -1099 /* No operation initiated by user */
+#define MANAGE_PARAM_ERR     -3    /* RTAS Parameter Error */
+#define MANAGE_HW_ERR        -1    /* RTAS Hardware Error */
+
+/* Validate image status values */
+#define VALIDATE_AUTH          -9002 /* RTAS Not Service Authority Partition */
+#define VALIDATE_NO_OP         -1099 /* No operation initiated by the user */
+#define VALIDATE_INCOMPLETE    -1002 /* User copied < VALIDATE_BUF_SIZE */
+#define VALIDATE_READY	       -1001 /* Firmware image ready for validation */
+#define VALIDATE_PARAM_ERR     -3    /* RTAS Parameter Error */
+#define VALIDATE_HW_ERR        -1    /* RTAS Hardware Error */
+#define VALIDATE_TMP_UPDATE    0     /* Validate Return Status */
+#define VALIDATE_FLASH_AUTH    1     /* Validate Return Status */
+#define VALIDATE_INVALID_IMG   2     /* Validate Return Status */
+#define VALIDATE_CUR_UNKNOWN   3     /* Validate Return Status */
+#define VALIDATE_TMP_COMMIT_DL 4     /* Validate Return Status */
+#define VALIDATE_TMP_COMMIT    5     /* Validate Return Status */
+#define VALIDATE_TMP_UPDATE_DL 6     /* Validate Return Status */
+
+/* ibm,manage-flash-image operation tokens */
+#define RTAS_REJECT_TMP_IMG   0
+#define RTAS_COMMIT_TMP_IMG   1
+
+/* Array sizes */
+#define VALIDATE_BUF_SIZE 4096
+#define RTAS_MSG_MAXLEN   64
 
 /* Local copy of the flash block list.
  * We only allow one open of the flash proc file and create this
@@ -36,21 +82,35 @@
  * is treated as the number of entries currently in the block
  * (i.e. not a byte count).  This is all fixed on release.
  */
-static struct flash_block_list *flist;
-static char *flash_msg;
-static int flash_possible;
-
-static int rtas_flash_open(struct inode *inode, struct file *file)
-{
-	if ((file->f_mode & FMODE_WRITE) && flash_possible) {
-		if (flist)
-			return -EBUSY;
-		flist = (struct flash_block_list *)get_free_page(GFP_KERNEL);
-		if (!flist)
-			return -ENOMEM;
-	}
-	return 0;
-}
+
+/* Status int must be first member of struct */
+struct rtas_update_flash_t
+{
+	int status;			/* Flash update status */
+	struct flash_block_list *flist; /* Local copy of flash block list */
+};
+
+/* Status int must be first member of struct */
+struct rtas_manage_flash_t
+{
+	int status;			/* Returned status */
+	unsigned int op;		/* Reject or commit image */
+};
+
+/* Status int must be first member of struct */
+struct rtas_validate_flash_t
+{
+	int status;		 	/* Returned status */
+	char buf[VALIDATE_BUF_SIZE]; 	/* Candidate image buffer */
+	unsigned int buf_size;		/* Size of image buf */
+	unsigned int update_results;	/* Update results token */
+};
+
+static spinlock_t flash_file_open_lock = SPIN_LOCK_UNLOCKED;
+static struct proc_dir_entry *firmware_flash_pde = NULL;
+static struct proc_dir_entry *firmware_update_pde = NULL;
+static struct proc_dir_entry *validate_pde = NULL;
+static struct proc_dir_entry *manage_pde = NULL;
 
 /* Do simple sanity checks on the flash image. */
 static int flash_list_valid(struct flash_block_list *flist)
@@ -59,32 +119,27 @@
 	int i;
 	unsigned long block_size, image_size;
 
-	flash_msg = NULL;
 	/* Paranoid self test here.  We also collect the image size. */
 	image_size = 0;
 	for (f = flist; f; f = f->next) {
 		for (i = 0; i < f->num_blocks; i++) {
 			if (f->blocks[i].data == NULL) {
-				flash_msg = "error: internal error null data\n";
-				return 0;
+				return FLASH_IMG_NULL_DATA;
 			}
 			block_size = f->blocks[i].length;
 			if (block_size <= 0 || block_size > PAGE_SIZE) {
-				flash_msg = "error: internal error bad length\n";
-				return 0;
+				return FLASH_IMG_BAD_LEN;
 			}
 			image_size += block_size;
 		}
 	}
-	if (image_size < (256 << 10)) {
-		if (image_size < 2)
-			flash_msg = NULL;	/* allow "clear" of image */
-		else
-			flash_msg = "error: flash image short\n";
-		return 0;
-	}
+
+	if (image_size < 2)
+		return FLASH_NO_OP;
+
 	printk(KERN_INFO "FLASH: flash image with %ld bytes stored for hardware flash on reboot\n", image_size);
-	return 1;
+
+	return FLASH_IMG_READY;
 }
 
 static void free_flash_list(struct flash_block_list *f)
@@ -103,40 +158,80 @@
 
 static int rtas_flash_release(struct inode *inode, struct file *file)
 {
-	if (flist) {
-		/* Always clear saved list on a new attempt. */
+	struct proc_dir_entry *dp = file->f_dentry->d_inode->u.generic_ip;
+	struct rtas_update_flash_t *uf;
+
+	uf = (struct rtas_update_flash_t *) dp->data;
+	if (uf->flist) {
+		/* File was opened in write mode for a new flash attempt */
+		/* Clear saved list */
 		if (rtas_firmware_flash_list.next) {
 			free_flash_list(rtas_firmware_flash_list.next);
 			rtas_firmware_flash_list.next = NULL;
 		}
 
-		if (flash_list_valid(flist))
-			rtas_firmware_flash_list.next = flist;
+		if (uf->status != FLASH_AUTH)
+			uf->status = flash_list_valid(uf->flist);
+
+		if (uf->status == FLASH_IMG_READY)
+			rtas_firmware_flash_list.next = uf->flist;
 		else
-			free_flash_list(flist);
-		flist = NULL;
+			free_flash_list(uf->flist);
+
+		uf->flist = NULL;
 	}
+
+	atomic_dec(&dp->count);
 	return 0;
 }
 
+static void get_flash_status_msg(int status, char *buf)
+{
+	char *msg;
+
+	switch (status) {
+	case FLASH_AUTH:
+		msg = "error: this partition does not have service authority\n";
+		break;
+	case FLASH_NO_OP:
+		msg = "info: no firmware image for flash\n";
+		break;
+	case FLASH_IMG_SHORT:
+		msg = "error: flash image short\n";
+		break;
+	case FLASH_IMG_BAD_LEN:
+		msg = "error: internal error bad length\n";
+		break;
+	case FLASH_IMG_NULL_DATA:
+		msg = "error: internal error null data\n";
+		break;
+	case FLASH_IMG_READY:
+		msg = "ready: firmware image ready for flash on reboot\n";
+		break;
+	default:
+		sprintf(buf, "error: unexpected status value %d\n", status);
+		return;
+	}
+
+	strcpy(buf, msg);
+}
+
 /* Reading the proc file will show status (not the firmware contents) */
 static ssize_t rtas_flash_read(struct file *file, char *buf,
 			       size_t count, loff_t *ppos)
 {
+	struct proc_dir_entry *dp = file->f_dentry->d_inode->u.generic_ip;
+	struct rtas_update_flash_t *uf;
+	char msg[RTAS_MSG_MAXLEN];
 	int error;
-	char *msg;
 	int msglen;
 
-	if (!flash_possible) {
-		msg = "error: this partition does not have service authority\n";
-	} else if (flist) {
-		msg = "info: this file is busy for write by some process\n";
-	} else if (flash_msg) {
-		msg = flash_msg;	/* message from last flash attempt */
-	} else if (rtas_firmware_flash_list.next) {
-		msg = "ready: firmware image ready for flash on reboot\n";
-	} else {
-		msg = "info: no firmware image for flash\n";
+	uf = (struct rtas_update_flash_t *) dp->data;
+
+	if (!strcmp(dp->name, FIRMWARE_FLASH_NAME)) {
+		get_flash_status_msg(uf->status, msg);
+	} else {	   /* FIRMWARE_UPDATE_NAME */
+		sprintf(msg, "%d\n", uf->status);
 	}
 	msglen = strlen(msg);
 	if (msglen > count)
@@ -149,7 +244,8 @@
 	if (error)
 		return -EINVAL;
 
-	copy_to_user(buf, msg, msglen);
+	if (copy_to_user(buf, msg, msglen))
+		return -EFAULT;
 
 	if (ppos)
 		*ppos = msglen;
@@ -164,14 +260,28 @@
 static ssize_t rtas_flash_write(struct file *file, const char *buffer,
 				size_t count, loff_t *off)
 {
-	size_t len = count;
+	struct proc_dir_entry *dp = file->f_dentry->d_inode->u.generic_ip;
+	struct rtas_update_flash_t *uf;
 	char *p;
 	int next_free;
-	struct flash_block_list *fl = flist;
+	struct flash_block_list *fl;
 
-	if (!flash_possible || len == 0)
-		return len;	/* discard data */
+	uf = (struct rtas_update_flash_t *) dp->data;
 
+	if (uf->status == FLASH_AUTH || count == 0)
+		return count;	/* discard data */
+
+	/* In the case that the image is not ready for flashing, the memory
+	 * allocated for the block list will be freed upon the release of the
+	 * proc file
+	 */
+	if (uf->flist == NULL) {
+		uf->flist = (struct flash_block_list *) get_free_page(GFP_KERNEL);
+		if (!uf->flist)
+			return -ENOMEM;
+	}
+
+	fl = uf->flist;
 	while (fl->next)
 		fl = fl->next; /* seek to last block_list for append */
 	next_free = fl->num_blocks;
@@ -184,47 +294,392 @@
 		next_free = 0;
 	}
 
-	if (len > PAGE_SIZE)
-		len = PAGE_SIZE;
+	if (count > PAGE_SIZE)
+		count = PAGE_SIZE;
 	p = (char *)get_free_page(GFP_KERNEL);
 	if (!p)
 		return -ENOMEM;
-	if(copy_from_user(p, buffer, len)) {
+
+	if(copy_from_user(p, buffer, count)) {
 		free_page((unsigned long)p);
 		return -EFAULT;
 	}
 	fl->blocks[next_free].data = p;
-	fl->blocks[next_free].length = len;
+	fl->blocks[next_free].length = count;
 	fl->num_blocks++;
 
-	return len;
+	return count;
+}
+
+static int rtas_excl_open(struct inode *inode, struct file *file)
+{
+	struct proc_dir_entry *dp = file->f_dentry->d_inode->u.generic_ip;
+
+	/* Enforce exclusive open with use count of PDE */
+	spin_lock(&flash_file_open_lock);
+	if (atomic_read(&dp->count) > 1) {
+		spin_unlock(&flash_file_open_lock);
+		return -EBUSY;
+	}
+
+	atomic_inc(&dp->count);
+	spin_unlock(&flash_file_open_lock);
+
+	return 0;
+}
+
+static int rtas_excl_release(struct inode *inode, struct file *file)
+{
+	struct proc_dir_entry *dp = file->f_dentry->d_inode->u.generic_ip;
+
+	atomic_dec(&dp->count);
+
+	return 0;
+}
+
+static void manage_flash(struct rtas_manage_flash_t *args_buf)
+{
+	unsigned int wait_time;
+	s32 rc;
+
+	while (1) {
+		rc = (s32) rtas_call(rtas_token("ibm,manage-flash-image"), 1,
+				1, NULL, (long) args_buf->op);
+		if (rc == RTAS_RC_BUSY)
+			udelay(1);
+		else if (rtas_is_extended_busy(rc)) {
+			wait_time = rtas_extended_busy_delay_time(rc);
+			udelay(wait_time * 1000);
+		} else
+			break;
+	}
+
+	args_buf->status = rc;
+}
+
+static ssize_t manage_flash_read(struct file *file, char *buf,
+			       size_t count, loff_t *ppos)
+{
+	struct proc_dir_entry *dp = file->f_dentry->d_inode->u.generic_ip;
+	struct rtas_manage_flash_t *args_buf;
+	char msg[RTAS_MSG_MAXLEN];
+	int msglen;
+	int error;
+
+	args_buf = (struct rtas_manage_flash_t *) dp->data;
+	if (args_buf == NULL)
+		return 0;
+
+	msglen = sprintf(msg, "%d\n", args_buf->status);
+	if (msglen > count)
+		msglen = count;
+
+	if (ppos && *ppos != 0)
+		return 0;	/* be cheap */
+
+	error = verify_area(VERIFY_WRITE, buf, msglen);
+	if (error)
+		return -EINVAL;
+
+	if (copy_to_user(buf, msg, msglen))
+		return -EFAULT;
+
+	if (ppos)
+		*ppos = msglen;
+	return msglen;
+}
+
+static ssize_t manage_flash_write(struct file *file, const char *buf,
+				size_t count, loff_t *off)
+{
+	struct proc_dir_entry *dp = file->f_dentry->d_inode->u.generic_ip;
+	struct rtas_manage_flash_t *args_buf;
+	const char reject_str[] = "0";
+	const char commit_str[] = "1";
+	char stkbuf[10];
+	int op;
+
+	args_buf = (struct rtas_manage_flash_t *) dp->data;
+	if ((args_buf->status == MANAGE_AUTH) || (count == 0))
+		return count;
+
+	op = -1;
+	if (buf) {
+		if (count > 9) count = 9;
+		if (copy_from_user (stkbuf, buf, count)) {
+			return -EFAULT;
+		}
+		if (strncmp(stkbuf, reject_str, strlen(reject_str)) == 0)
+			op = RTAS_REJECT_TMP_IMG;
+		else if (strncmp(stkbuf, commit_str, strlen(commit_str)) == 0)
+			op = RTAS_COMMIT_TMP_IMG;
+	}
+
+	if (op == -1)   /* buf is empty, or contains invalid string */
+		return -EINVAL;
+
+	args_buf->op = op;
+	manage_flash(args_buf);
+
+	return count;
+}
+
+static void validate_flash(struct rtas_validate_flash_t *args_buf)
+{
+	int token = rtas_token("ibm,validate-flash-image");
+	unsigned int wait_time;
+	long update_results;
+	s32 rc;
+
+	rc = 0;
+	while(1) {
+		spin_lock(&rtas_data_buf_lock);
+		memcpy(rtas_data_buf, args_buf->buf, VALIDATE_BUF_SIZE);
+		rc = (s32) rtas_call(token, 2, 2, &update_results,
+				     __pa(rtas_data_buf), args_buf->buf_size);
+		memcpy(args_buf->buf, rtas_data_buf, VALIDATE_BUF_SIZE);
+		spin_unlock(&rtas_data_buf_lock);
+
+		if (rc == RTAS_RC_BUSY)
+			udelay(1);
+		else if (rtas_is_extended_busy(rc)) {
+			wait_time = rtas_extended_busy_delay_time(rc);
+			udelay(wait_time * 1000);
+		} else
+			break;
+	}
+
+	args_buf->status = rc;
+	args_buf->update_results = (u32) update_results;
+}
+
+static int get_validate_flash_msg(struct rtas_validate_flash_t *args_buf,
+				   char *msg)
+{
+	int n;
+
+	if (args_buf->status >= VALIDATE_TMP_UPDATE) {
+		n = sprintf(msg, "%d\n", args_buf->update_results);
+		if ((args_buf->update_results >= VALIDATE_CUR_UNKNOWN) ||
+		    (args_buf->update_results == VALIDATE_TMP_UPDATE))
+			n += sprintf(msg + n, "%s\n", args_buf->buf);
+	} else {
+		n = sprintf(msg, "%d\n", args_buf->status);
+	}
+	return n;
+}
+
+static ssize_t validate_flash_read(struct file *file, char *buf,
+			       size_t count, loff_t *ppos)
+{
+	struct proc_dir_entry *dp = file->f_dentry->d_inode->u.generic_ip;
+	struct rtas_validate_flash_t *args_buf;
+	char msg[RTAS_MSG_MAXLEN];
+	int msglen;
+	int error;
+
+	args_buf = (struct rtas_validate_flash_t *) dp->data;
+
+	if (ppos && *ppos != 0)
+		return 0;	/* be cheap */
+
+	msglen = get_validate_flash_msg(args_buf, msg);
+	if (msglen > count)
+		msglen = count;
+
+	error = verify_area(VERIFY_WRITE, buf, msglen);
+	if (error)
+		return -EINVAL;
+
+	if (copy_to_user(buf, msg, msglen))
+		return -EFAULT;
+
+	if (ppos)
+		*ppos = msglen;
+	return msglen;
+}
+
+static ssize_t validate_flash_write(struct file *file, const char *buf,
+				size_t count, loff_t *off)
+{
+	struct proc_dir_entry *dp = file->f_dentry->d_inode->u.generic_ip;
+	struct rtas_validate_flash_t *args_buf;
+	int rc;
+
+	args_buf = (struct rtas_validate_flash_t *) dp->data;
+
+	if (dp->data == NULL) {
+		dp->data = kmalloc(sizeof(struct rtas_validate_flash_t),
+				GFP_KERNEL);
+		if (dp->data == NULL)
+			return -ENOMEM;
+	}
+
+	/* We are only interested in the first 4K of the
+	 * candidate image */
+	if ((*off >= VALIDATE_BUF_SIZE) ||
+		(args_buf->status == VALIDATE_AUTH)) {
+		*off += count;
+		return count;
+	}
+
+	if (*off + count >= VALIDATE_BUF_SIZE)  {
+		count = VALIDATE_BUF_SIZE - *off;
+		args_buf->status = VALIDATE_READY;
+	} else {
+		args_buf->status = VALIDATE_INCOMPLETE;
+	}
+
+	if (verify_area(VERIFY_READ, buf, count)) {
+		rc = -EFAULT;
+		goto done;
+	}
+	if (copy_from_user(args_buf->buf + *off, buf, count)) {
+		rc = -EFAULT;
+		goto done;
+	}
+
+	*off += count;
+	rc = count;
+done:
+	if (rc < 0) {
+		kfree(dp->data);
+		dp->data = NULL;
+	}
+	return rc;
+}
+
+static int validate_flash_release(struct inode *inode, struct file *file)
+{
+	struct proc_dir_entry *dp = file->f_dentry->d_inode->u.generic_ip;
+	struct rtas_validate_flash_t *args_buf;
+
+	args_buf = (struct rtas_validate_flash_t *) dp->data;
+
+	if (args_buf->status == VALIDATE_READY) {
+		args_buf->buf_size = VALIDATE_BUF_SIZE;
+		validate_flash(args_buf);
+	}
+
+	atomic_dec(&dp->count);
+
+	return 0;
+}
+
+static inline void remove_flash_pde(struct proc_dir_entry *dp)
+{
+	if (dp) {
+		if (dp->data != NULL)
+			kfree(dp->data);
+		remove_proc_entry(dp->name, rtas_proc_dir);
+	}
+}
+
+static inline int initialize_flash_pde_data(const char *rtas_call_name,
+					    size_t buf_size,
+					    struct proc_dir_entry *dp)
+{
+	int *status;
+	int token;
+
+	dp->data = kmalloc(buf_size, GFP_KERNEL);
+	if (dp->data == NULL) {
+		remove_flash_pde(dp);
+		return -ENOMEM;
+	}
+
+	memset(dp->data, 0, buf_size);
+
+	/* This code assumes that the status int is the first member of the
+	 * struct
+	 */
+	status = (int *) dp->data;
+	token = rtas_token(rtas_call_name);
+	if (token == RTAS_UNKNOWN_SERVICE)
+		*status = FLASH_AUTH;
+	else
+		*status = FLASH_NO_OP;
+
+	return 0;
+}
+
+static inline struct proc_dir_entry * create_flash_pde(const char *filename,
+					struct file_operations *fops)
+{
+	struct proc_dir_entry *ent = NULL;
+
+	ent = create_proc_entry(filename, S_IRUSR | S_IWUSR, rtas_proc_dir);
+	if (ent != NULL) {
+		ent->nlink = 1;
+		ent->proc_fops = fops;
+		ent->owner = THIS_MODULE;
+	}
+
+	return ent;
 }
 
 static struct file_operations rtas_flash_operations = {
 	read:		rtas_flash_read,
 	write:		rtas_flash_write,
-	open:		rtas_flash_open,
+	open:		rtas_excl_open,
 	release:	rtas_flash_release,
 };
 
+static struct file_operations manage_flash_operations = {
+	read:		manage_flash_read,
+	write:		manage_flash_write,
+	open:		rtas_excl_open,
+	release:	rtas_excl_release,
+};
+
+static struct file_operations validate_flash_operations = {
+	read:		validate_flash_read,
+	write:		validate_flash_write,
+	open:		rtas_excl_open,
+	release:	validate_flash_release,
+};
 
 int __init rtas_flash_init(void)
 {
-	struct proc_dir_entry *ent = NULL;
+	int rc;
 
 	if (!rtas_proc_dir) {
 		printk(KERN_WARNING "rtas proc dir does not already exist");
 		return -ENOENT;
 	}
 
-	if (rtas_token("ibm,update-flash-64-and-reboot") != RTAS_UNKNOWN_SERVICE)
-		flash_possible = 1;
+	firmware_flash_pde = create_flash_pde(FIRMWARE_FLASH_NAME,
+					      &rtas_flash_operations);
+	rc = initialize_flash_pde_data("ibm,update-flash-64-and-reboot",
+				       sizeof(struct rtas_update_flash_t),
+				       firmware_flash_pde);
+	if (rc != 0)
+		return rc;
+
+	firmware_update_pde = create_flash_pde(FIRMWARE_UPDATE_NAME,
+					       &rtas_flash_operations);
+	rc = initialize_flash_pde_data("ibm,update-flash-64-and-reboot",
+				       sizeof(struct rtas_update_flash_t),
+				       firmware_update_pde);
+	if (rc != 0)
+		return rc;
+
+	validate_pde = create_flash_pde(VALIDATE_FLASH_NAME,
+					&validate_flash_operations);
+	rc = initialize_flash_pde_data("ibm,validate-flash-image",
+				       sizeof(struct rtas_validate_flash_t),
+				       validate_pde);
+	if (rc != 0)
+		return rc;
+
+	manage_pde = create_flash_pde(MANAGE_FLASH_NAME,
+				      &manage_flash_operations);
+	rc = initialize_flash_pde_data("ibm,manage-flash-image",
+				       sizeof(struct rtas_manage_flash_t),
+				       manage_pde);
+	if (rc != 0)
+		return rc;
 
-	if ((ent = create_proc_entry(FIRMWARE_FLASH_NAME, S_IRUSR | S_IWUSR, rtas_proc_dir)) != NULL) {
-		ent->nlink = 1;
-		ent->proc_fops = &rtas_flash_operations;
-		ent->owner = THIS_MODULE;
-	}
 	return 0;
 }
 
@@ -232,7 +687,10 @@
 {
 	if (!rtas_proc_dir)
 		return;
-	remove_proc_entry(FIRMWARE_FLASH_NAME, rtas_proc_dir);
+	remove_flash_pde(firmware_flash_pde);
+	remove_flash_pde(firmware_update_pde);
+	remove_flash_pde(validate_pde);
+	remove_flash_pde(manage_pde);
 }
 
 module_init(rtas_flash_init);
diff -urN linux-2.4.25-pre4/arch/ppc64/kernel/rtasd.c linux-2.4.25-pre5/arch/ppc64/kernel/rtasd.c
--- linux-2.4.25-pre4/arch/ppc64/kernel/rtasd.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.25-pre5/arch/ppc64/kernel/rtasd.c	2004-01-15 12:10:22.000000000 -0800
@@ -17,11 +17,14 @@
 #include <linux/proc_fs.h>
 #include <linux/init.h>
 #include <linux/vmalloc.h>
+#include <linux/spinlock.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
 #include <asm/rtas.h>
 #include <asm/prom.h>
+#include <asm/nvram.h>
+#include <asm/atomic.h>
 
 #if 0
 #define DEBUG(A...)	printk(KERN_ERR A)
@@ -29,37 +32,181 @@
 #define DEBUG(A...)
 #endif
 
-static spinlock_t rtas_log_lock = SPIN_LOCK_UNLOCKED;
+static spinlock_t log_lock = SPIN_LOCK_UNLOCKED;
 
 DECLARE_WAIT_QUEUE_HEAD(rtas_log_wait);
 
-#define LOG_NUMBER		64		/* must be a power of two */
-#define LOG_NUMBER_MASK		(LOG_NUMBER-1)
-
 static char *rtas_log_buf;
 static unsigned long rtas_log_start;
 static unsigned long rtas_log_size;
 
-static int surveillance_requested;
+static int surveillance_timeout = -1;
 static unsigned int rtas_event_scan_rate;
 static unsigned int rtas_error_log_max;
 
-#define EVENT_SCAN_ALL_EVENTS	0xf0000000
-#define SURVEILLANCE_TOKEN	9000
-#define SURVEILLANCE_TIMEOUT	1
-#define SURVEILLANCE_SCANRATE	1
+static unsigned int rtas_error_log_buffer_max;
 
 extern struct proc_dir_entry *proc_ppc64_root;
 extern struct proc_dir_entry *rtas_proc_dir;
 extern spinlock_t proc_ppc64_lock;
+extern volatile int no_more_logging;
+
+volatile int error_log_cnt = 0;
+
 /*
  * Since we use 32 bit RTAS, the physical address of this must be below
  * 4G or else bad things happen. Allocate this in the kernel data and
  * make it big enough.
  */
-#define RTAS_ERROR_LOG_MAX 1024
 static unsigned char logdata[RTAS_ERROR_LOG_MAX];
 
+/* To see this info, grep RTAS /var/log/messages and each entry
+ * will be collected together with obvious begin/end.
+ * There will be a unique identifier on the begin and end lines.
+ * This will persist across reboots.
+ *
+ * format of error logs returned from RTAS:
+ * bytes 	(size)	: contents
+ * --------------------------------------------------------
+ * 0-7		(8)	: rtas_error_log
+ * 8-47		(40) 	: extended info
+ * 48-51	(4)	: vendor id
+ * 52-1023 (vendor specific) : location code and debug data
+ */
+static void printk_log_rtas(char *buf, int len)
+{
+
+	int i,j,n;
+	int perline = 16;
+	char buffer[64];
+	char * str = "RTAS event";
+
+	printk(RTAS_ERR "%d -------- %s begin --------\n", error_log_cnt, str);
+
+	/*
+	 * Print perline bytes on each line, each line will start
+	 * with RTAS and a changing number, so syslogd will
+	 * print lines that are otherwise the same.  Separate every
+	 * 4 bytes with a space.
+	 */
+	for (i=0; i < len; i++) {
+		j = i % perline;
+		if (j == 0) {
+			memset(buffer, 0, sizeof(buffer));
+			n = sprintf(buffer, "RTAS %d:", i/perline);
+		}
+
+		if ((i % 4) == 0)
+			n += sprintf(buffer+n, " ");
+
+		n += sprintf(buffer+n, "%02x", (unsigned char)buf[i]);
+
+		if (j == (perline-1))
+			printk(KERN_ERR "%s\n", buffer);
+	}
+	if ((i % perline) != 0)
+		printk(KERN_ERR "%s\n", buffer);
+
+	printk(RTAS_ERR "%d -------- %s end ----------\n", error_log_cnt, str);
+}
+
+static int log_rtas_len(char * buf)
+{
+	int len;
+	struct rtas_error_log *err;
+
+	/* rtas fixed header */
+	len = 8;
+	err = (struct rtas_error_log *)buf;
+	if (err->extended_log_length) {
+
+		/* extended header */
+		len += err->extended_log_length;
+
+		if (len > RTAS_ERROR_LOG_MAX)
+			len = RTAS_ERROR_LOG_MAX;
+	}
+	return len;
+}
+
+/*
+ * First write to nvram, if fatal error, that is the only
+ * place we log the info.  The error will be picked up
+ * on the next reboot by rtasd.  If not fatal, run the
+ * method for the type of error.  Currently, only RTAS
+ * errors have methods implemented, but in the future
+ * there might be a need to store data in nvram before a
+ * call to panic().
+*/
+void pSeries_log_error(char *buf, unsigned int err_type, int fatal)
+{
+	unsigned long offset;
+	unsigned long s;
+	int len = 0;
+
+	DEBUG("logging event\n");
+
+	if (buf == NULL)
+		return;
+
+	spin_lock_irqsave(&log_lock, s);
+
+	/* get length and increase count */
+	switch (err_type & ERR_TYPE_MASK) {
+	case ERR_TYPE_RTAS_LOG:
+		len = log_rtas_len(buf);
+		if (!(err_type & ERR_FLAG_BOOT))
+			error_log_cnt++;
+		break;
+	case ERR_TYPE_KERNEL_PANIC:
+	default:
+		spin_unlock_irqrestore(&log_lock, s);
+		return;
+	}
+
+	/* Write error to NVRAM */
+	if (!no_more_logging && !(err_type & ERR_FLAG_BOOT)) {
+		write_error_log_nvram(buf, len, err_type);
+	}
+
+	/* Check to see if we need to or have stopped logging */
+	if (fatal || no_more_logging) {
+		no_more_logging = 1;
+		spin_unlock_irqrestore(&log_lock, s);
+		return;
+	}
+
+	/* call type specific method for error */
+	switch (err_type & ERR_TYPE_MASK) {
+	case ERR_TYPE_RTAS_LOG:
+		/* put into syslog and error_log file */
+		printk_log_rtas(buf, len);
+
+		offset = rtas_error_log_buffer_max *
+			((rtas_log_start+rtas_log_size) & LOG_NUMBER_MASK);
+
+		/* First copy over sequence number */
+		memcpy(&rtas_log_buf[offset], &error_log_cnt, sizeof(int));
+
+		/* Second copy over error log data */
+		offset += sizeof(int);
+		memcpy(&rtas_log_buf[offset], buf, len);
+
+		if (rtas_log_size < LOG_NUMBER)
+			rtas_log_size += 1;
+		else
+			rtas_log_start += 1;
+
+		spin_unlock_irqrestore(&log_lock, s);
+		wake_up_interruptible(&rtas_log_wait);
+		break;
+	case ERR_TYPE_KERNEL_PANIC:
+	default:
+		spin_unlock_irqrestore(&log_lock, s);
+		return;
+	}
+
+}
 static int rtas_log_open(struct inode * inode, struct file * file)
 {
 	return 0;
@@ -70,36 +217,50 @@
 	return 0;
 }
 
+/* This will check if all events are logged, if they are then, we
+ * know that we can safely clear the events in NVRAM.
+ * Next we'll sit and wait for something else to log.
+ */
 static ssize_t rtas_log_read(struct file * file, char * buf,
 			 size_t count, loff_t *ppos)
 {
 	int error;
 	char *tmp;
+	unsigned long s;
 	unsigned long offset;
 
-	if (!buf || count < rtas_error_log_max)
+	if (!buf || count < rtas_error_log_buffer_max)
 		return -EINVAL;
 
-	count = rtas_error_log_max;
+	count = rtas_error_log_buffer_max;
 
 	error = verify_area(VERIFY_WRITE, buf, count);
 	if (error)
-		return -EINVAL;
+		return -EFAULT;
 
-	tmp = kmalloc(rtas_error_log_max, GFP_KERNEL);
+	tmp = kmalloc(count, GFP_KERNEL);
 	if (!tmp)
 		return -ENOMEM;
 
+
+	spin_lock_irqsave(&log_lock, s);
+	/* if it's 0, then we know we got the last one (the one in NVRAM) */
+	if (rtas_log_size == 0 && !no_more_logging)
+		clear_error_log_nvram();
+	spin_unlock_irqrestore(&log_lock, s);
+
+
 	error = wait_event_interruptible(rtas_log_wait, rtas_log_size);
 	if (error)
 		goto out;
 
-	spin_lock(&rtas_log_lock);
-	offset = rtas_error_log_max * (rtas_log_start & LOG_NUMBER_MASK);
+	spin_lock_irqsave(&log_lock, s);
+	offset = rtas_error_log_buffer_max * (rtas_log_start & LOG_NUMBER_MASK);
 	memcpy(tmp, &rtas_log_buf[offset], count);
+
 	rtas_log_start += 1;
 	rtas_log_size -= 1;
-	spin_unlock(&rtas_log_lock);
+	spin_unlock_irqrestore(&log_lock, s);
 
 	error = copy_to_user(buf, tmp, count) ? -EFAULT : count;
 out:
@@ -122,607 +283,18 @@
 	.release =	rtas_log_release,
 };
 
-
-#define RTAS_ERR KERN_ERR "RTAS: "
-
-/* Extended error log header (12 bytes) */
-struct exthdr {
-	unsigned int valid:1;
-	unsigned int unrecoverable:1;
-	unsigned int recoverable:1;
-	unsigned int unrecoverable_bypassed:1;	/* i.e. degraded performance */
-	unsigned int predictive:1;
-	unsigned int newlog:1;
-	unsigned int bigendian:1;		/* always 1 */
-	unsigned int /* reserved */:1;
-
-	unsigned int platform_specific:1;	/* only in version 3+ */
-	unsigned int /* reserved */:3;
-	unsigned int platform_value:4;		/* valid iff platform_specific */
-
-	unsigned int power_pc:1;		/* always 1 */
-	unsigned int /* reserved */:2;
-	unsigned int addr_invalid:1;		/* failing_address is invalid */
-	unsigned int format_type:4;
-#define EXTLOG_FMT_CPU 1
-#define EXTLOG_FMT_MEMORY 2
-#define EXTLOG_FMT_IO 3
-#define EXTLOG_FMT_POST 4
-#define EXTLOG_FMT_ENV 5
-#define EXTLOG_FMT_POW 6
-#define EXTLOG_FMT_IBMDIAG 12
-#define EXTLOG_FMT_IBMSP 13
-
-	/* This group is in version 3+ only */
-	unsigned int non_hardware:1;		/* Firmware or software is suspect */
-	unsigned int hot_plug:1;		/* Failing component may be hot plugged */
-	unsigned int group_failure:1;		/* Group of components should be replaced */
-	unsigned int /* reserved */:1;
-
-	unsigned int residual:1;		/* Residual error from previous boot (maybe a crash) */
-	unsigned int boot:1;			/* Error during boot */
-	unsigned int config_change:1;		/* Configuration changed since last boot */
-	unsigned int post:1;			/* Error during POST */
-
-	unsigned int bcdtime:32;		/* Time of error in BCD HHMMSS00 */
-	unsigned int bcddate:32;		/* Time of error in BCD YYYYMMDD */
-};
-
-struct cpuhdr {
-	unsigned int internal:1;
-	unsigned int intcache:1;
-	unsigned int extcache_parity:1;	/* or multi-bit ECC */
-	unsigned int extcache_ecc:1;
-	unsigned int sysbus_timeout:1;
-	unsigned int io_timeout:1;
-	unsigned int sysbus_parity:1;
-	unsigned int sysbus_protocol:1;
-	unsigned int cpuid:8;
-	unsigned int element:16;
-	unsigned int failing_address_hi:32;
-	unsigned int failing_address_lo:32;
-
-	/* These are version 4+ */
-	unsigned int try_reboot:1;	/* 1 => fault may be fixed by reboot */
-	unsigned int /* reserved */:7;
-	/* 15 bytes reserved here */
-};
-
-struct memhdr {
-	unsigned int uncorrectable:1;
-	unsigned int ECC:1;
-	unsigned int threshold_exceeded:1;
-	unsigned int control_internal:1;
-	unsigned int bad_address:1;
-	unsigned int bad_data:1;
-	unsigned int bus:1;
-	unsigned int timeout:1;
-	unsigned int sysbus_parity:1;
-	unsigned int sysbus_timeout:1;
-	unsigned int sysbus_protocol:1;
-	unsigned int hostbridge_timeout:1;
-	unsigned int hostbridge_parity:1;
-	unsigned int reserved1:1;
-	unsigned int support:1;
-	unsigned int sysbus_internal:1;
-	unsigned int mem_controller_detected:8;	/* who detected fault? */
-	unsigned int mem_controller_faulted:8;	/* who caused fault? */
-	unsigned int failing_address_hi:32;
-	unsigned int failing_address_lo:32;
-	unsigned int ecc_syndrome:16;
-	unsigned int memory_card:8;
-	unsigned int reserved2:8;
-	unsigned int sub_elements:32;		/* one bit per element */
-	unsigned int element:16;
-};
-
-struct iohdr {
-	unsigned int bus_addr_parity:1;
-	unsigned int bus_data_parity:1;
-	unsigned int bus_timeout:1;
-	unsigned int bridge_internal:1;
-	unsigned int non_pci:1;		/* i.e. secondary bus such as ISA */
-	unsigned int mezzanine_addr_parity:1;
-	unsigned int mezzanine_data_parity:1;
-	unsigned int mezzanine_timeout:1;
-
-	unsigned int bridge_via_sysbus:1;
-	unsigned int bridge_via_mezzanine:1;
-	unsigned int bridge_via_expbus:1;
-	unsigned int detected_by_expbus:1;
-	unsigned int expbus_data_parity:1;
-	unsigned int expbus_timeout:1;
-	unsigned int expbus_connection_failure:1;
-	unsigned int expbus_not_operating:1;
-
-	/* IOA signalling the error */
-	unsigned int pci_sig_busno:8;
-	unsigned int pci_sig_devfn:8;
-	unsigned int pci_sig_deviceid:16;
-	unsigned int pci_sig_vendorid:16;
-	unsigned int pci_sig_revisionid:8;
-	unsigned int pci_sig_slot:8;	/* 00 => system board, ff => multiple */
-
-	/* IOA sending at time of error */
-	unsigned int pci_send_busno:8;
-	unsigned int pci_send_devfn:8;
-	unsigned int pci_send_deviceid:16;
-	unsigned int pci_send_vendorid:16;
-	unsigned int pci_send_revisionid:8;
-	unsigned int pci_send_slot:8;	/* 00 => system board, ff => multiple */
-};
-
-struct posthdr {
-	unsigned int firmware:1;
-	unsigned int config:1;
-	unsigned int cpu:1;
-	unsigned int memory:1;
-	unsigned int io:1;
-	unsigned int keyboard:1;
-	unsigned int mouse:1;
-	unsigned int display:1;
-
-	unsigned int ipl_floppy:1;
-	unsigned int ipl_controller:1;
-	unsigned int ipl_cdrom:1;
-	unsigned int ipl_disk:1;
-	unsigned int ipl_net:1;
-	unsigned int ipl_other:1;
-	unsigned int /* reserved */:1;
-	unsigned int firmware_selftest:1;
-
-	char         devname[12];
-	unsigned int post_code:4;
-	unsigned int firmware_rev:2;
-	unsigned int loc_code:8;	/* currently unused */
-};
-
-struct epowhdr {
-	unsigned int epow_sensor_value:32;
-	unsigned int sensor:1;
-	unsigned int power_fault:1;
-	unsigned int fan:1;
-	unsigned int temp:1;
-	unsigned int redundancy:1;
-	unsigned int CUoD:1;
-	unsigned int /* reserved */:2;
-
-	unsigned int general:1;
-	unsigned int power_loss:1;
-	unsigned int power_supply:1;
-	unsigned int power_switch:1;
-	unsigned int /* reserved */:4;
-
-	unsigned int /* reserved */:16;
-	unsigned int sensor_token:32;
-	unsigned int sensor_index:32;
-	unsigned int sensor_value:32;
-	unsigned int sensor_status:32;
-};
-
-struct pm_eventhdr {
-	unsigned int event_id:32;
-};
-
-struct sphdr {
-	unsigned int ibm:32;	/* "IBM\0" */
-
-	unsigned int timeout:1;
-	unsigned int i2c_bus:1;
-	unsigned int i2c_secondary_bus:1;
-	unsigned int sp_memory:1;
-	unsigned int sp_registers:1;
-	unsigned int sp_communication:1;
-	unsigned int sp_firmware:1;
-	unsigned int sp_hardware:1;
-
-	unsigned int vpd_eeprom:1;
-	unsigned int op_panel:1;
-	unsigned int power_controller:1;
-	unsigned int fan_sensor:1;
-	unsigned int thermal_sensor:1;
-	unsigned int voltage_sensor:1;
-	unsigned int reserved1:2;
-
-	unsigned int serial_port:1;
-	unsigned int nvram:1;
-	unsigned int rtc:1;
-	unsigned int jtag:1;
-	unsigned int tod_battery:1;
-	unsigned int reserved2:1;
-	unsigned int heartbeat:1;
-	unsigned int surveillance:1;
-
-	unsigned int pcn_connection:1;	/* power control network */
-	unsigned int pcn_node:1;
-	unsigned int reserved3:2;
-	unsigned int pcn_access:1;
-	unsigned int reserved:3;
-
-	unsigned int sensor_token:32;	/* zero if undef */
-	unsigned int sensor_index:32;	/* zero if undef */
-};
-
-
-static char *severity_names[] = {
-	"NO ERROR", "EVENT", "WARNING", "ERROR_SYNC", "ERROR", "FATAL", "(6)", "(7)"
-};
-static char *rtas_disposition_names[] = {
-	"FULLY RECOVERED", "LIMITED RECOVERY", "NOT RECOVERED", "(4)"
-};
-static char *entity_names[] = { /* for initiator & targets */
-	"UNKNOWN", "CPU", "PCI", "ISA", "MEMORY", "POWER MANAGEMENT", "HOT PLUG", "(7)", "(8)",
-	"(9)", "(10)", "(11)", "(12)", "(13)", "(14)", "(15)"
-};
-static char *error_type[] = {	/* Not all types covered here so need to bounds check */
-	"UNKNOWN", "RETRY", "TCE_ERR", "INTERN_DEV_FAIL",
-	"TIMEOUT", "DATA_PARITY", "ADDR_PARITY", "CACHE_PARITY",
-	"ADDR_INVALID", "ECC_UNCORR", "ECC_CORR",
-};
-
-static char *rtas_error_type(int type)
-{
-	if (type < 11)
-		return error_type[type];
-	if (type == 64)
-		return "SENSOR";
-	if (type >=96 && type <= 159)
-		return "POWER";
-	return error_type[0];
-}
-
-static void printk_cpu_failure(int version, struct exthdr *exthdr, char *data)
-{
-	struct cpuhdr cpuhdr;
-
-	memcpy(&cpuhdr, data, sizeof(cpuhdr));
-
-	if (cpuhdr.internal) printk(RTAS_ERR "Internal error (not cache)\n");
-	if (cpuhdr.intcache) printk(RTAS_ERR "Internal cache\n");
-	if (cpuhdr.extcache_parity) printk(RTAS_ERR "External cache parity (or multi-bit)\n");
-	if (cpuhdr.extcache_ecc) printk(RTAS_ERR "External cache ECC\n");
-	if (cpuhdr.sysbus_timeout) printk(RTAS_ERR "System bus timeout\n");
-	if (cpuhdr.io_timeout) printk(RTAS_ERR "I/O timeout\n");
-	if (cpuhdr.sysbus_parity) printk(RTAS_ERR "System bus parity\n");
-	if (cpuhdr.sysbus_protocol) printk(RTAS_ERR "System bus protocol/transfer\n");
-	printk(RTAS_ERR "CPU id: %d\n", cpuhdr.cpuid);
-	printk(RTAS_ERR "Failing element: 0x%04x\n", cpuhdr.element);
-	if (!exthdr->addr_invalid)
-		printk(RTAS_ERR "Failing address: %08x%08x\n", cpuhdr.failing_address_hi, cpuhdr.failing_address_lo);
-	if (version >= 4 && cpuhdr.try_reboot)
-		printk(RTAS_ERR "A reboot of the system may correct the problem\n");
-}
-
-static void printk_mem_failure(int version, struct exthdr *exthdr, char *data)
-{
-	struct memhdr memhdr;
-
-	memcpy(&memhdr, data, sizeof(memhdr));
-	if (memhdr.uncorrectable) printk(RTAS_ERR "Uncorrectable Memory error\n");
-	if (memhdr.ECC) printk(RTAS_ERR "ECC Correctable error\n");
-	if (memhdr.threshold_exceeded) printk(RTAS_ERR "Correctable threshold exceeded\n");
-	if (memhdr.control_internal) printk(RTAS_ERR "Memory Controller internal error\n");
-	if (memhdr.bad_address) printk(RTAS_ERR "Memory Address error\n");
-	if (memhdr.bad_data) printk(RTAS_ERR "Memory Data error\n");
-	if (memhdr.bus) printk(RTAS_ERR "Memory bus/switch internal error\n");
-	if (memhdr.timeout) printk(RTAS_ERR "Memory timeout\n");
-	if (memhdr.sysbus_parity) printk(RTAS_ERR "System bus parity\n");
-	if (memhdr.sysbus_timeout) printk(RTAS_ERR "System bus timeout\n");
-	if (memhdr.sysbus_protocol) printk(RTAS_ERR "System bus protocol/transfer\n");
-	if (memhdr.hostbridge_timeout) printk(RTAS_ERR "I/O Host Bridge timeout\n");
-	if (memhdr.hostbridge_parity) printk(RTAS_ERR "I/O Host Bridge parity\n");
-	if (memhdr.support) printk(RTAS_ERR "System support function error\n");
-	if (memhdr.sysbus_internal) printk(RTAS_ERR "System bus internal hardware/switch error\n");
-	printk(RTAS_ERR "Memory Controller that detected failure: %d\n", memhdr.mem_controller_detected);
-	printk(RTAS_ERR "Memory Controller that faulted: %d\n", memhdr.mem_controller_faulted);
-	if (!exthdr->addr_invalid)
-		printk(RTAS_ERR "Failing address: 0x%016x%016x\n", memhdr.failing_address_hi, memhdr.failing_address_lo);
-	printk(RTAS_ERR "ECC syndrome bits: 0x%04x\n", memhdr.ecc_syndrome);
-	printk(RTAS_ERR "Memory Card: %d\n", memhdr.memory_card);
-	printk(RTAS_ERR "Failing element: 0x%04x\n", memhdr.element);
-	printk(RTAS_ERR "Sub element bits: 0x%08x\n", memhdr.sub_elements);
-}
-
-static void printk_io_failure(int version, struct exthdr *exthdr, char *data)
-{
-	struct iohdr iohdr;
-
-	memcpy(&iohdr, data, sizeof(iohdr));
-	if (iohdr.bus_addr_parity) printk(RTAS_ERR "I/O bus address parity\n");
-	if (iohdr.bus_data_parity) printk(RTAS_ERR "I/O bus data parity\n");
-	if (iohdr.bus_timeout) printk(RTAS_ERR "I/O bus timeout, access or other\n");
-	if (iohdr.bridge_internal) printk(RTAS_ERR "I/O bus bridge/device internal\n");
-	if (iohdr.non_pci) printk(RTAS_ERR "Signaling IOA is a PCI to non-PCI bridge (e.g. ISA)\n");
-	if (iohdr.mezzanine_addr_parity) printk(RTAS_ERR "Mezzanine/System bus address parity\n");
-	if (iohdr.mezzanine_data_parity) printk(RTAS_ERR "Mezzanine/System bus data parity\n");
-	if (iohdr.mezzanine_timeout) printk(RTAS_ERR "Mezzanine/System bus timeout, transfer or protocol\n");
-	if (iohdr.bridge_via_sysbus) printk(RTAS_ERR "Bridge is connected to system bus\n");
-	if (iohdr.bridge_via_mezzanine) printk(RTAS_ERR "Bridge is connected to memory controller via mezzanine bus\n");
-	if (iohdr.bridge_via_expbus) printk(RTAS_ERR "Bridge is connected to I/O expansion bus\n");
-	if (iohdr.detected_by_expbus) printk(RTAS_ERR "Error on system bus detected by I/O expansion bus controller\n");
-	if (iohdr.expbus_data_parity) printk(RTAS_ERR "I/O expansion bus data error\n");
-	if (iohdr.expbus_timeout) printk(RTAS_ERR "I/O expansion bus timeout, access or other\n");
-	if (iohdr.expbus_connection_failure) printk(RTAS_ERR "I/O expansion bus connection failure\n");
-	if (iohdr.expbus_not_operating) printk(RTAS_ERR "I/O expansion unit not in an operating state (powered off, off-line)\n");
-
-	printk(RTAS_ERR "IOA Signaling the error: %d:%d.%d vendor:%04x device:%04x rev:%02x slot:%d\n",
-	       iohdr.pci_sig_busno, iohdr.pci_sig_devfn >> 3, iohdr.pci_sig_devfn & 0x7,
-	       iohdr.pci_sig_vendorid, iohdr.pci_sig_deviceid, iohdr.pci_sig_revisionid, iohdr.pci_sig_slot);
-	printk(RTAS_ERR "IOA Sending during the error: %d:%d.%d vendor:%04x device:%04x rev:%02x slot:%d\n",
-	       iohdr.pci_send_busno, iohdr.pci_send_devfn >> 3, iohdr.pci_send_devfn & 0x7,
-	       iohdr.pci_send_vendorid, iohdr.pci_send_deviceid, iohdr.pci_send_revisionid, iohdr.pci_send_slot);
-
-}
-
-static void printk_post_failure(int version, struct exthdr *exthdr, char *data)
-{
-	struct posthdr posthdr;
-
-	memcpy(&posthdr, data, sizeof(posthdr));
-
-	if (posthdr.devname[0]) printk(RTAS_ERR "Failing Device: %s\n", posthdr.devname);
-	if (posthdr.firmware) printk(RTAS_ERR "Firmware Error\n");
-	if (posthdr.config) printk(RTAS_ERR "Configuration Error\n");
-	if (posthdr.cpu) printk(RTAS_ERR "CPU POST Error\n");
-	if (posthdr.memory) printk(RTAS_ERR "Memory POST Error\n");
-	if (posthdr.io) printk(RTAS_ERR "I/O Subsystem POST Error\n");
-	if (posthdr.keyboard) printk(RTAS_ERR "Keyboard POST Error\n");
-	if (posthdr.mouse) printk(RTAS_ERR "Mouse POST Error\n");
-	if (posthdr.display) printk(RTAS_ERR "Display POST Error\n");
-
-	if (posthdr.ipl_floppy) printk(RTAS_ERR "Floppy IPL Error\n");
-	if (posthdr.ipl_controller) printk(RTAS_ERR "Drive Controller Error during IPL\n");
-	if (posthdr.ipl_cdrom) printk(RTAS_ERR "CDROM IPL Error\n");
-	if (posthdr.ipl_disk) printk(RTAS_ERR "Disk IPL Error\n");
-	if (posthdr.ipl_net) printk(RTAS_ERR "Network IPL Error\n");
-	if (posthdr.ipl_other) printk(RTAS_ERR "Other (tape,flash) IPL Error\n");
-	if (posthdr.firmware_selftest) printk(RTAS_ERR "Self-test error in firmware extended diagnostics\n");
-	printk(RTAS_ERR "POST Code: %d\n", posthdr.post_code);
-	printk(RTAS_ERR "Firmware Revision Code: %d\n", posthdr.firmware_rev);
-}
-
-static void printk_epow_warning(int version, struct exthdr *exthdr, char *data)
-{
-	struct epowhdr epowhdr;
-
-	memcpy(&epowhdr, data, sizeof(epowhdr));
-	printk(RTAS_ERR "EPOW Sensor Value:  0x%08x\n", epowhdr.epow_sensor_value); 
-	if (epowhdr.sensor) {
-		printk(RTAS_ERR "EPOW detected by a sensor\n");
-		printk(RTAS_ERR "Sensor Token:  0x%08x\n", epowhdr.sensor_token); 
-		printk(RTAS_ERR "Sensor Index:  0x%08x\n", epowhdr.sensor_index); 
-		printk(RTAS_ERR "Sensor Value:  0x%08x\n", epowhdr.sensor_value); 
-		printk(RTAS_ERR "Sensor Status: 0x%08x\n", epowhdr.sensor_status);
-	}
-	if (epowhdr.power_fault) printk(RTAS_ERR "EPOW caused by a power fault\n");
-	if (epowhdr.fan) printk(RTAS_ERR "EPOW caused by fan failure\n");
-	if (epowhdr.temp) printk(RTAS_ERR "EPOW caused by over-temperature condition\n");
-	if (epowhdr.redundancy) printk(RTAS_ERR "EPOW warning due to loss of redundancy\n");
-	if (epowhdr.CUoD) printk(RTAS_ERR "EPOW warning due to CUoD Entitlement Exceeded\n");
-
-	if (epowhdr.general) printk(RTAS_ERR "EPOW general power fault\n");
-	if (epowhdr.power_loss) printk(RTAS_ERR "EPOW power fault due to loss of power source\n");
-	if (epowhdr.power_supply) printk(RTAS_ERR "EPOW power fault due to internal power supply failure\n");
-	if (epowhdr.power_switch) printk(RTAS_ERR "EPOW power fault due to activation of power switch\n");
-}
-
-static void printk_pm_event(int version, struct exthdr *exthdr, char *data)
-{
-	struct pm_eventhdr pm_eventhdr;
-
-	memcpy(&pm_eventhdr, data, sizeof(pm_eventhdr));
-	printk(RTAS_ERR "Event id: 0x%08x\n", pm_eventhdr.event_id);
-}
-
-static void printk_sp_log_msg(int version, struct exthdr *exthdr, char *data)
-{
-	struct sphdr sphdr;
-	u32 eyecatcher;
-
-	memcpy(&sphdr, data, sizeof(sphdr));
-
-	eyecatcher = sphdr.ibm;
-	if (strcmp((char *)&eyecatcher, "IBM") != 0)
-		printk(RTAS_ERR "This log entry may be corrupt (IBM signature malformed)\n");
-	if (sphdr.timeout) printk(RTAS_ERR "Timeout on communication response from service processor\n");
-	if (sphdr.i2c_bus) printk(RTAS_ERR "I2C general bus error\n");
-	if (sphdr.i2c_secondary_bus) printk(RTAS_ERR "I2C secondary bus error\n");
-	if (sphdr.sp_memory) printk(RTAS_ERR "Internal service processor memory error\n");
-	if (sphdr.sp_registers) printk(RTAS_ERR "Service processor error accessing special registers\n");
-	if (sphdr.sp_communication) printk(RTAS_ERR "Service processor reports unknown communcation error\n");
-	if (sphdr.sp_firmware) printk(RTAS_ERR "Internal service processor firmware error\n");
-	if (sphdr.sp_hardware) printk(RTAS_ERR "Other internal service processor hardware error\n");
-	if (sphdr.vpd_eeprom) printk(RTAS_ERR "Service processor error accessing VPD EEPROM\n");
-	if (sphdr.op_panel) printk(RTAS_ERR "Service processor error accessing Operator Panel\n");
-	if (sphdr.power_controller) printk(RTAS_ERR "Service processor error accessing Power Controller\n");
-	if (sphdr.fan_sensor) printk(RTAS_ERR "Service processor error accessing Fan Sensor\n");
-	if (sphdr.thermal_sensor) printk(RTAS_ERR "Service processor error accessing Thermal Sensor\n");
-	if (sphdr.voltage_sensor) printk(RTAS_ERR "Service processor error accessing Voltage Sensor\n");
-	if (sphdr.serial_port) printk(RTAS_ERR "Service processor error accessing serial port\n");
-	if (sphdr.nvram) printk(RTAS_ERR "Service processor detected NVRAM error\n");
-	if (sphdr.rtc) printk(RTAS_ERR "Service processor error accessing real time clock\n");
-	if (sphdr.jtag) printk(RTAS_ERR "Service processor error accessing JTAG/COP\n");
-	if (sphdr.tod_battery) printk(RTAS_ERR "Service processor or RTAS detects loss of voltage from TOD battery\n");
-	if (sphdr.heartbeat) printk(RTAS_ERR "Loss of heartbeat from Service processor\n");
-	if (sphdr.surveillance) printk(RTAS_ERR "Service processor detected a surveillance timeout\n");
-	if (sphdr.pcn_connection) printk(RTAS_ERR "Power Control Network general connection failure\n");
-	if (sphdr.pcn_node) printk(RTAS_ERR "Power Control Network node failure\n");
-	if (sphdr.pcn_access) printk(RTAS_ERR "Service processor error accessing Power Control Network\n");
-
-	if (sphdr.sensor_token) printk(RTAS_ERR "Sensor Token 0x%08x (%d)\n", sphdr.sensor_token, sphdr.sensor_token);
-	if (sphdr.sensor_index) printk(RTAS_ERR "Sensor Index 0x%08x (%d)\n", sphdr.sensor_index, sphdr.sensor_index);
-}
-
-
-static void printk_ext_raw_data(char *data)
-{
-	int i;
-	printk(RTAS_ERR "raw ext data: ");
-	for (i = 0; i < 40; i++) {
-		printk("%02x", data[i]);
-	}
-	printk("\n");
-}
-
-static void printk_ext_log_data(int version, char *buf)
-{
-	char *data = buf+12;
-	struct exthdr exthdr;
-	memcpy(&exthdr, buf, sizeof(exthdr));	/* copy for alignment */
-	if (!exthdr.valid) {
-		if (exthdr.bigendian && exthdr.power_pc)
-			printk(RTAS_ERR "extended log data is not valid\n");
-		else
-			printk(RTAS_ERR "extended log data can not be decoded\n");
-		return;
-	}
-
-	/* Dump useful stuff in the exthdr */
-	printk(RTAS_ERR "Status:%s%s%s%s%s\n",
-	       exthdr.unrecoverable ? " unrecoverable" : "",
-	       exthdr.recoverable ? " recoverable" : "",
-	       exthdr.unrecoverable_bypassed ? " bypassed" : "",
-	       exthdr.predictive ? " predictive" : "",
-	       exthdr.newlog ? " new" : "");
-	printk(RTAS_ERR "Date/Time: %08x %08x\n", exthdr.bcddate, exthdr.bcdtime);
-	switch (exthdr.format_type) {
-	    case EXTLOG_FMT_CPU:
-		printk(RTAS_ERR "CPU Failure\n");
-		printk_cpu_failure(version, &exthdr, data);
-		break;
-	    case EXTLOG_FMT_MEMORY:
-		printk(RTAS_ERR "Memory Failure\n");
-		printk_mem_failure(version, &exthdr, data);
-		break;
-	    case EXTLOG_FMT_IO:
-		printk(RTAS_ERR "I/O Failure\n");
-		printk_io_failure(version, &exthdr, data);
-		break;
-	    case EXTLOG_FMT_POST:
-		printk(RTAS_ERR "POST Failure\n");
-		printk_post_failure(version, &exthdr, data);
-		break;
-	    case EXTLOG_FMT_ENV:
-		printk(RTAS_ERR "Environment and Power Warning\n");
-		printk_epow_warning(version, &exthdr, data);
-		break;
-	    case EXTLOG_FMT_POW:
-		printk(RTAS_ERR "Power Management Event\n");
-		printk_pm_event(version, &exthdr, data);
-		break;
-	    case EXTLOG_FMT_IBMDIAG:
-		printk(RTAS_ERR "IBM Diagnostic Log\n");
-		printk_ext_raw_data(data);
-		break;
-	    case EXTLOG_FMT_IBMSP:
-		printk(RTAS_ERR "IBM Service Processor Log\n");
-		printk_sp_log_msg(version, &exthdr, data);
-		break;
-	    default:
-		printk(RTAS_ERR "Unknown ext format type %d\n", exthdr.format_type);
-		printk_ext_raw_data(data);
-		break;
-	}
-}
-
-#define MAX_LOG_DEBUG 10
-#define MAX_LOG_DEBUG_LEN 900
-/* Print log debug data.  This appears after the location code.
- * We limit the number of debug logs in case the data is somehow corrupt.
- */
-static void printk_log_debug(char *buf)
-{
-	unsigned char *p = (unsigned char *)_ALIGN((unsigned long)buf, 4);
-	int len, n, logged;
-
-	logged = 0;
-	while ((logged < MAX_LOG_DEBUG) && (len = ((p[0] << 8) | p[1])) >= 4) {
-		if (len > MAX_LOG_DEBUG_LEN)
-			len = MAX_LOG_DEBUG_LEN;	/* bound it */
-		printk("RTAS: Log Debug: %c%c ", p[2], p[3]);
-		for (n=4; n < len; n++)
-			printk("%02x", p[n]);
-		printk("\n");
-		p = (unsigned char *)_ALIGN((unsigned long)p+len, 4);
-		logged++;
-		if (len == MAX_LOG_DEBUG_LEN)
-			return;	/* no point continuing */
-	}
-	if (logged == 0)
-		printk("RTAS: no log debug data present\n");
-}
-
-
-/* Yeah, the output here is ugly, but we want a CE to be
- * able to grep RTAS /var/log/messages and see all the info
- * collected together with obvious begin/end.
- */
-static void printk_log_rtas(char *buf)
-{
-	struct rtas_error_log *err = (struct rtas_error_log *)buf;
-
-	printk(RTAS_ERR "-------- event-scan begin --------\n");
-	if (strcmp(buf+8+40, "IBM") == 0) {
-		/* Location code follows */
-		char *loc = buf+8+40+4;
-		int len = strlen(loc);
-		if (len < 64) {	/* Sanity check */
-			printk(RTAS_ERR "Location Code: %s\n", loc);
-			printk_log_debug(loc+len+1);
-		}
-	}
-
-	printk(RTAS_ERR "%s: (%s) type: %s\n",
-	       severity_names[err->severity],
-	       rtas_disposition_names[err->disposition],
-	       rtas_error_type(err->type));
-	printk(RTAS_ERR "initiator: %s  target: %s\n",
-	       entity_names[err->initiator], entity_names[err->target]);
-	if (err->extended_log_length)
-		printk_ext_log_data(err->version, buf+8);
-	printk(RTAS_ERR "-------- event-scan end ----------\n");
-}
-
-
-static void log_rtas(char *buf)
-{
-	unsigned long offset;
-
-	DEBUG("logging rtas event\n");
-
-	/* Temporary -- perhaps we can do this when nobody has the log open? */
-	printk_log_rtas(buf);
-
-	spin_lock(&rtas_log_lock);
-
-	offset = rtas_error_log_max *
-			((rtas_log_start+rtas_log_size) & LOG_NUMBER_MASK);
-
-	memcpy(&rtas_log_buf[offset], buf, rtas_error_log_max);
-
-	if (rtas_log_size < LOG_NUMBER)
-		rtas_log_size += 1;
-	else
-		rtas_log_start += 1;
-
-	spin_unlock(&rtas_log_lock);
-	wake_up_interruptible(&rtas_log_wait);
-}
-
-static int enable_surveillance(void)
+static int enable_surveillance(int timeout)
 {
 	int error;
 
 	error = rtas_call(rtas_token("set-indicator"), 3, 1, NULL, SURVEILLANCE_TOKEN,
-			0, SURVEILLANCE_TIMEOUT);
+			0, timeout);
 
 	if (error) {
 		printk(KERN_ERR "rtasd: could not enable surveillance\n");
 		return -1;
 	}
 
-	rtas_event_scan_rate = SURVEILLANCE_SCANRATE;
-
 	return 0;
 }
 
@@ -754,6 +326,9 @@
 		rtas_error_log_max = RTAS_ERROR_LOG_MAX;
 	}
 
+	/* Make room for the sequence number */
+	rtas_error_log_buffer_max = rtas_error_log_max + sizeof(int);
+
 	return 0;
 }
 
@@ -761,20 +336,25 @@
 
 static int rtasd(void *unused)
 {
+	unsigned int err_type;
+	unsigned long s;
 	int cpu = 0;
 	int error;
 	int first_pass = 1;
 	int event_scan = rtas_token("event-scan");
+	int rc;
 
 	if (event_scan == RTAS_UNKNOWN_SERVICE || get_eventscan_parms() == -1)
 		goto error;
 
-	rtas_log_buf = vmalloc(rtas_error_log_max*LOG_NUMBER);
+	rtas_log_buf = vmalloc(rtas_error_log_buffer_max*LOG_NUMBER);
 	if (!rtas_log_buf) {
 		printk(KERN_ERR "rtasd: no memory\n");
 		goto error;
 	}
 
+	no_more_logging = 0;
+
 	DEBUG("will sleep for %d jiffies\n", (HZ*60/rtas_event_scan_rate) / 2);
 
 	daemonize();
@@ -789,11 +369,23 @@
 	current->cpus_allowed = 1UL << cpu_logical_map(cpu);
 	schedule();
 
+	/* See if we have any error stored in NVRAM */
+	memset(logdata, 0, rtas_error_log_max);
+
+	rc = read_error_log_nvram(logdata, rtas_error_log_max, &err_type);
+	if (!rc) {
+		if (err_type != ERR_FLAG_ALREADY_LOGGED) {
+			pSeries_log_error(logdata, err_type | ERR_FLAG_BOOT, 0);
+		}
+	}
+
 	while(1) {
+
+
 		do {
 			memset(logdata, 0, rtas_error_log_max);
 			error = rtas_call(event_scan, 4, 1, NULL,
-					EVENT_SCAN_ALL_EVENTS, 0,
+					RTAS_EVENT_SCAN_ALL_EVENTS, 0,
 					__pa(logdata), rtas_error_log_max);
 			if (error == -1) {
 				printk(KERN_ERR "event-scan failed\n");
@@ -801,7 +393,7 @@
 			}
 
 			if (error == 0)
-				log_rtas(logdata);
+				pSeries_log_error(logdata, ERR_TYPE_RTAS_LOG, 0);
 
 		} while(error == 0);
 
@@ -810,9 +402,9 @@
 		cpu++;
 		if (cpu >= smp_num_cpus) {
 
-			if (first_pass && surveillance_requested) {
+			if (first_pass && (surveillance_timeout != -1)) {
 				DEBUG("enabling surveillance\n");
-				if (enable_surveillance())
+				if (enable_surveillance(surveillance_timeout))
 					goto error_vfree;
 				DEBUG("surveillance enabled\n");
 			}
@@ -824,8 +416,8 @@
 		current->cpus_allowed = 1UL << cpu_logical_map(cpu);
 
 		/* Check all cpus for pending events before sleeping*/
-                set_current_state(TASK_INTERRUPTIBLE);
-                schedule_timeout(first_pass ? HZ : (HZ*60/rtas_event_scan_rate) / 2);
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(first_pass ? HZ : (HZ*60/rtas_event_scan_rate) / 2);
 	}
 
 error_vfree:
@@ -846,10 +438,10 @@
 		if (!proc_ppc64_root) {
 			spin_unlock(&proc_ppc64_lock);
 			return -EINVAL;
-		}		
+		}
 	}
 	spin_unlock(&proc_ppc64_lock);
-	
+
 	if (rtas_proc_dir == NULL) {
 		rtas_proc_dir = proc_mkdir("rtas", proc_ppc64_root);
 	}
@@ -867,7 +459,7 @@
 		}
 	}
 
-	if (kernel_thread(rtasd, 0, CLONE_FS) < 0) { 
+	if (kernel_thread(rtasd, 0, CLONE_FS) < 0) {
 		printk(KERN_ERR "Failed to start RTAS daemon\n");
 		ret = -EINVAL;
 	}
@@ -881,8 +473,8 @@
 	int i;
 
 	if (get_option(&str,&i)) {
-		if (i == 1)
-			surveillance_requested = 1;
+		if (i >= 0 && i <= 255)
+			surveillance_timeout = i;
 	}
 
 	return 1;
diff -urN linux-2.4.25-pre4/arch/ppc64/kernel/setup.c linux-2.4.25-pre5/arch/ppc64/kernel/setup.c
--- linux-2.4.25-pre4/arch/ppc64/kernel/setup.c	2004-01-15 12:10:14.000000000 -0800
+++ linux-2.4.25-pre5/arch/ppc64/kernel/setup.c	2004-01-15 12:10:22.000000000 -0800
@@ -598,20 +598,35 @@
 	udbg_puts("   "); udbg_puthex(srr1); udbg_puts("\n");
 }
 
-int set_spread_lpevents( char * str )
+void do_spread_lpevents(unsigned long n)
 {
-	/* The parameter is the number of processors to share in processing lp events */
-	unsigned long i;
-	unsigned long val = simple_strtoul( str, NULL, 0 );
-	if ( ( val > 0 ) && ( val <= MAX_PACAS ) ) {
-		for ( i=1; i<val; ++i )
-			paca[i].lpQueuePtr = paca[0].lpQueuePtr;
-		printk("lpevent processing spread over %ld processors\n", val);
-	}
+	unsigned long i,m;
+
+	if (n < MAX_PACAS)
+		m = n;
 	else
+		m = MAX_PACAS;
+
+	for (i=1; i<m; ++i)
+		paca[i].lpQueuePtr = paca[0].lpQueuePtr;
+
+	printk("lpevent processing spread over %ld processors\n", n);
+}
+
+/*
+ * The parameter is the number of processors to share in
+ * processing lp events
+ */
+int set_spread_lpevents(char * str)
+{
+	unsigned long val = simple_strtoul( str, NULL, 0 );
+	if ((val > 0) && (val <= MAX_PACAS)) {
+		do_spread_lpevents(val);
+	} else
 		printk("invalid spreaqd_lpevents %ld\n", val);
+
 	return 1;
-}	
+}
 
 /* This should only be called on processor 0 during calibrate decr */
 void setup_default_decr(void)
diff -urN linux-2.4.25-pre4/arch/ppc64/kernel/traps.c linux-2.4.25-pre5/arch/ppc64/kernel/traps.c
--- linux-2.4.25-pre4/arch/ppc64/kernel/traps.c	2004-01-15 12:10:14.000000000 -0800
+++ linux-2.4.25-pre5/arch/ppc64/kernel/traps.c	2004-01-15 12:10:22.000000000 -0800
@@ -211,6 +211,8 @@
 		nonfatal = 1;
 	}
 
+	log_error((char *)errp, ERR_TYPE_RTAS_LOG, !nonfatal);
+
 	return nonfatal;
 }
 
@@ -250,6 +252,8 @@
 		status = rtas_call(rtas_token("check-exception"), 6, 1, NULL,
 				   0x200, (uint)srr1, RTAS_INTERNAL_ERROR, 0,
 				   __pa(mce_data_buf), RTAS_ERROR_LOG_MAX);
+		if (status == 0)
+			log_error((char *)mce_data_buf, ERR_TYPE_RTAS_LOG, 1);
 	}
 
 #if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
diff -urN linux-2.4.25-pre4/drivers/char/Config.in linux-2.4.25-pre5/drivers/char/Config.in
--- linux-2.4.25-pre4/drivers/char/Config.in	2004-01-15 12:10:14.000000000 -0800
+++ linux-2.4.25-pre5/drivers/char/Config.in	2004-01-15 12:10:22.000000000 -0800
@@ -323,7 +323,7 @@
 if [ "$CONFIG_SGI_IP27" = "y" ]; then
    bool 'SGI M48T35 RTC support' CONFIG_SGI_IP27_RTC
 fi
-if [ "$CONFIG_TOSHIBA_RBTX4927" = "y" -o "$CONFIG_TOSHIBA_JMR3927" ]; then
+if [ "$CONFIG_TOSHIBA_RBTX4927" = "y" -o "$CONFIG_TOSHIBA_JMR3927" = "y" ]; then
    tristate 'Dallas DS1742 RTC support' CONFIG_DS1742
 fi
 
diff -urN linux-2.4.25-pre4/drivers/char/agp/agp.h linux-2.4.25-pre5/drivers/char/agp/agp.h
--- linux-2.4.25-pre4/drivers/char/agp/agp.h	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.25-pre5/drivers/char/agp/agp.h	2004-01-15 12:10:22.000000000 -0800
@@ -319,6 +319,9 @@
 #ifndef PCI_DEVICE_ID_ATI_RS250
 #define PCI_DEVICE_ID_ATI_RS250		0xcab3
 #endif
+#ifndef PCI_DEVICE_ID_ATI_RS200_B
+#define PCI_DEVICE_ID_ATI_RS200_B	0xcbb3
+#endif
 #ifndef PCI_DEVICE_ID_ATI_RS300_100
 #define PCI_DEVICE_ID_ATI_RS300_100	0x5830
 #endif
diff -urN linux-2.4.25-pre4/drivers/char/agp/agpgart_be.c linux-2.4.25-pre5/drivers/char/agp/agpgart_be.c
--- linux-2.4.25-pre4/drivers/char/agp/agpgart_be.c	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.25-pre5/drivers/char/agp/agpgart_be.c	2004-01-15 12:10:22.000000000 -0800
@@ -5738,6 +5738,7 @@
 
 	if ((agp_bridge.dev->device == PCI_DEVICE_ID_ATI_RS100) ||
 	    (agp_bridge.dev->device == PCI_DEVICE_ID_ATI_RS200) ||
+	    (agp_bridge.dev->device == PCI_DEVICE_ID_ATI_RS200_B) ||
 	    (agp_bridge.dev->device == PCI_DEVICE_ID_ATI_RS250)) {
 		pci_read_config_dword(agp_bridge.dev, ATI_RS100_APSIZE, &temp);
 		temp = (((temp & ~(0x0000000e)) | current_size->size_value)
@@ -5791,6 +5792,7 @@
 
 	if ((agp_bridge.dev->device == PCI_DEVICE_ID_ATI_RS100) ||
 	    (agp_bridge.dev->device == PCI_DEVICE_ID_ATI_RS200) ||
+	    (agp_bridge.dev->device == PCI_DEVICE_ID_ATI_RS200_B) ||
 	    (agp_bridge.dev->device == PCI_DEVICE_ID_ATI_RS250)) {
 		pci_read_config_dword(agp_bridge.dev, ATI_RS100_APSIZE, &temp);
 	} else {
@@ -5823,6 +5825,7 @@
 
 	if ((agp_bridge.dev->device == PCI_DEVICE_ID_ATI_RS100) ||
 	    (agp_bridge.dev->device == PCI_DEVICE_ID_ATI_RS200) ||
+	    (agp_bridge.dev->device == PCI_DEVICE_ID_ATI_RS200_B) ||
 	    (agp_bridge.dev->device == PCI_DEVICE_ID_ATI_RS250)) {
         	pci_write_config_dword(agp_bridge.dev, ATI_RS100_IG_AGPMODE, 0x20000);
 	} else {
@@ -5860,6 +5863,7 @@
 	/* Write back the previous size and disable gart translation */
 	if ((agp_bridge.dev->device == PCI_DEVICE_ID_ATI_RS100) ||
 	    (agp_bridge.dev->device == PCI_DEVICE_ID_ATI_RS200) ||
+	    (agp_bridge.dev->device == PCI_DEVICE_ID_ATI_RS200_B) ||
 	    (agp_bridge.dev->device == PCI_DEVICE_ID_ATI_RS250)) {
 		pci_read_config_dword(agp_bridge.dev, ATI_RS100_APSIZE, &temp);
 		temp = ((temp & ~(0x0000000f)) | previous_size->size_value);
@@ -6428,6 +6432,12 @@
 	  "ATI",
 	  "IGP330/340/345/350/M",
 	  ati_generic_setup },
+	{ PCI_DEVICE_ID_ATI_RS200_B,
+	  PCI_VENDOR_ID_ATI,
+	  ATI_RS200,
+	  "ATI",
+	  "IGP330/340/345/350/M",
+	  ati_generic_setup },
 	{ PCI_DEVICE_ID_ATI_RS250,
 	  PCI_VENDOR_ID_ATI,
 	  ATI_RS250,
diff -urN linux-2.4.25-pre4/drivers/char/drm/r128_state.c linux-2.4.25-pre5/drivers/char/drm/r128_state.c
--- linux-2.4.25-pre4/drivers/char/drm/r128_state.c	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.25-pre5/drivers/char/drm/r128_state.c	2004-01-15 12:10:22.000000000 -0800
@@ -23,8 +23,20 @@
  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * RED HAT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * THIS SOFTWARE IS NOT INTENDED FOR USE IN SAFETY CRITICAL SYSTEMS
+ *
  * Authors:
  *    Gareth Hughes <gareth@valinux.com>
+ *
+ * Memory allocation size checks added 14/01/2003, Alan Cox <alan@redhat.com>
  */
 
 #include "r128.h"
@@ -901,6 +913,9 @@
 	DRM_DEBUG( "%s\n", __FUNCTION__ );
 
 	count = depth->n;
+	
+	if( count > 4096 )
+		return -EMSGSIZE;
 	if ( copy_from_user( &x, depth->x, sizeof(x) ) ) {
 		return -EFAULT;
 	}
@@ -994,6 +1009,9 @@
 	DRM_DEBUG( "%s\n", __FUNCTION__ );
 
 	count = depth->n;
+	
+	if( count > 4096 )
+		return -EMSGSIZE;
 
 	x = kmalloc( count * sizeof(*x), GFP_KERNEL );
 	if ( x == NULL ) {
@@ -1109,6 +1127,9 @@
 	DRM_DEBUG( "%s\n", __FUNCTION__ );
 
 	count = depth->n;
+	
+	if ( count > 4096 )
+		return -EMSGSIZE;
 	if ( copy_from_user( &x, depth->x, sizeof(x) ) ) {
 		return -EFAULT;
 	}
diff -urN linux-2.4.25-pre4/drivers/i2c/Config.in linux-2.4.25-pre5/drivers/i2c/Config.in
--- linux-2.4.25-pre4/drivers/i2c/Config.in	2004-01-15 12:10:14.000000000 -0800
+++ linux-2.4.25-pre5/drivers/i2c/Config.in	2004-01-15 12:10:22.000000000 -0800
@@ -7,7 +7,6 @@
 tristate 'I2C support' CONFIG_I2C
 
 if [ "$CONFIG_I2C" != "n" ]; then
-
    dep_tristate 'I2C bit-banging interfaces'  CONFIG_I2C_ALGOBIT $CONFIG_I2C
    if [ "$CONFIG_I2C_ALGOBIT" != "n" ]; then
       dep_tristate '  Philips style parallel port adapter' CONFIG_I2C_PHILIPSPAR $CONFIG_I2C_ALGOBIT $CONFIG_PARPORT
@@ -36,7 +35,7 @@
    if [ "$CONFIG_8xx" = "y" ]; then
       dep_tristate 'MPC8xx CPM I2C interface' CONFIG_I2C_ALGO8XX $CONFIG_I2C
       if [ "$CONFIG_RPXLITE" = "y" -o "$CONFIG_RPXCLASSIC" = "y" ]; then
-         dep_tristate '  Embedded Planet RPX Lite/Classic suppoort' CONFIG_I2C_RPXLITE $CONFIG_I2C_ALGO8XX
+         dep_tristate '  Embedded Planet RPX Lite/Classic support' CONFIG_I2C_RPXLITE $CONFIG_I2C_ALGO8XX
       fi
    fi
    if [ "$CONFIG_405" = "y" ]; then
@@ -55,14 +54,14 @@
       dep_tristate '  MAX1617 Temperature Sensor' CONFIG_I2C_MAX1617 $CONFIG_I2C_ALGO_SIBYTE
    fi
 
-  if [ "$CONFIG_SGI_IP22" = "y" ]; then
-     dep_tristate 'I2C SGI interfaces' CONFIG_I2C_ALGO_SGI $CONFIG_I2C
-  fi
+   if [ "$CONFIG_SGI_IP22" = "y" ]; then
+      dep_tristate 'I2C SGI interfaces' CONFIG_I2C_ALGO_SGI $CONFIG_I2C
+   fi
  
 # This is needed for automatic patch generation: sensors code starts here
 # This is needed for automatic patch generation: sensors code ends here
 
    dep_tristate 'I2C device interface' CONFIG_I2C_CHARDEV $CONFIG_I2C
-   dep_tristate 'I2C /proc interface (required for hardware sensors)' CONFIG_I2C_PROC $CONFIG_I2C
+   dep_tristate 'I2C /proc interface (required for hardware sensors)' CONFIG_I2C_PROC $CONFIG_I2C $CONFIG_SYSCTL
 fi
 endmenu
diff -urN linux-2.4.25-pre4/drivers/i2c/i2c-core.c linux-2.4.25-pre5/drivers/i2c/i2c-core.c
--- linux-2.4.25-pre4/drivers/i2c/i2c-core.c	2004-01-15 12:10:14.000000000 -0800
+++ linux-2.4.25-pre5/drivers/i2c/i2c-core.c	2004-01-15 12:10:22.000000000 -0800
@@ -1062,8 +1062,8 @@
 {
 	union i2c_smbus_data data;
 	int i;
-	if (length > 32)
-		length = 32;
+	if (length > I2C_SMBUS_BLOCK_MAX)
+		length = I2C_SMBUS_BLOCK_MAX;
 	for (i = 1; i <= length; i++)
 		data.block[i] = values[i-1];
 	data.block[0] = length;
@@ -1077,8 +1077,8 @@
 {
 	union i2c_smbus_data data;
 	int i;
-	if (length > 32)
-		length = 32;
+	if (length > I2C_SMBUS_I2C_BLOCK_MAX)
+		length = I2C_SMBUS_I2C_BLOCK_MAX;
 	for (i = 1; i <= length; i++)
 		data.block[i] = values[i-1];
 	data.block[0] = length;
@@ -1152,10 +1152,10 @@
 			return -1;
 		} else {
 			msg[0].len = data->block[0] + 2;
-			if (msg[0].len > 34) {
+			if (msg[0].len > I2C_SMBUS_BLOCK_MAX + 2) {
 				printk(KERN_ERR "i2c-core.o: smbus_access called with "
 				       "invalid block write size (%d)\n",
-				       msg[0].len);
+				       data->block[0]);
 				return -1;
 			}
 			for (i = 1; i <= msg[0].len; i++)
diff -urN linux-2.4.25-pre4/drivers/ide/Config.in linux-2.4.25-pre5/drivers/ide/Config.in
--- linux-2.4.25-pre4/drivers/ide/Config.in	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.25-pre5/drivers/ide/Config.in	2004-01-15 12:10:22.000000000 -0800
@@ -116,6 +116,9 @@
       if [ "$CONFIG_ATARI" = "y" ]; then
 	 dep_bool '  Falcon IDE interface support' CONFIG_BLK_DEV_FALCON_IDE $CONFIG_ATARI
       fi
+      if [ "$CONFIG_CPCI405" = "y" ]; then
+	 dep_bool '  CPCI-405 IDE interface support' CONFIG_BLK_DEV_CPCI405_IDE $CONFIG_CPCI405
+      fi
       if [ "$CONFIG_MAC" = "y" ]; then
 	 dep_bool '  Macintosh Quadra/Powerbook IDE interface support' CONFIG_BLK_DEV_MAC_IDE $CONFIG_MAC
       fi
diff -urN linux-2.4.25-pre4/drivers/ide/ide-proc.c linux-2.4.25-pre5/drivers/ide/ide-proc.c
--- linux-2.4.25-pre4/drivers/ide/ide-proc.c	2003-08-25 04:44:41.000000000 -0700
+++ linux-2.4.25-pre5/drivers/ide/ide-proc.c	2004-01-15 12:10:22.000000000 -0800
@@ -794,7 +794,6 @@
 
 	for (d = 0; d < MAX_DRIVES; d++) {
 		ide_drive_t *drive = &hwif->drives[d];
-		ide_driver_t *driver = drive->driver;
 
 		if (!drive->present)
 			continue;
@@ -802,13 +801,8 @@
 			continue;
 
 		drive->proc = proc_mkdir(drive->name, parent);
-		if (drive->proc) {
+		if (drive->proc)
 			ide_add_proc_entries(drive->proc, generic_drive_entries, drive);
-			if (driver) {
-				ide_add_proc_entries(drive->proc, generic_subdriver_entries, drive);
-				ide_add_proc_entries(drive->proc, driver->proc, drive);
-			}
-		}
 		sprintf(name,"ide%d/%s", (drive->name[2]-'a')/2, drive->name);
 		ent = proc_symlink(drive->name, proc_ide_root, name);
 		if (!ent) return;
diff -urN linux-2.4.25-pre4/drivers/ide/ide.c linux-2.4.25-pre5/drivers/ide/ide.c
--- linux-2.4.25-pre4/drivers/ide/ide.c	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.25-pre5/drivers/ide/ide.c	2004-01-15 12:10:22.000000000 -0800
@@ -2548,6 +2548,12 @@
 		macide_init();
 	}
 #endif /* CONFIG_BLK_DEV_MAC_IDE */
+#ifdef CONFIG_BLK_DEV_CPCI405_IDE
+	{
+		extern void cpci405ide_init(void);
+		cpci405ide_init();
+	}
+#endif /* CONFIG_BLK_DEV_CPCI405_IDE */
 #ifdef CONFIG_BLK_DEV_Q40IDE
 	{
 		extern void q40ide_init(void);
@@ -2850,8 +2856,10 @@
 	drive->revalidate = 1;
 	drive->suspend_reset = 0;
 #ifdef CONFIG_PROC_FS
-	ide_add_proc_entries(drive->proc, generic_subdriver_entries, drive);
-	ide_add_proc_entries(drive->proc, driver->proc, drive);
+	if (drive->driver != &idedefault_driver) {
+		ide_add_proc_entries(drive->proc, generic_subdriver_entries, drive);
+		ide_add_proc_entries(drive->proc, driver->proc, drive);
+	}
 #endif
 	return 0;
 }
diff -urN linux-2.4.25-pre4/drivers/ide/ppc/Makefile linux-2.4.25-pre5/drivers/ide/ppc/Makefile
--- linux-2.4.25-pre4/drivers/ide/ppc/Makefile	2003-06-13 07:51:34.000000000 -0700
+++ linux-2.4.25-pre5/drivers/ide/ppc/Makefile	2004-01-15 12:10:22.000000000 -0800
@@ -4,6 +4,7 @@
 obj-y		:=
 obj-m		:=
 
+obj-$(CONFIG_BLK_DEV_CPCI405_IDE)	+= cpci405ide.o
 obj-$(CONFIG_BLK_DEV_MPC8xx_IDE)	+= mpc8xx.o
 obj-$(CONFIG_BLK_DEV_IDE_PMAC)		+= pmac.o
 obj-$(CONFIG_BLK_DEV_IDE_SWARM)		+= swarm.o
diff -urN linux-2.4.25-pre4/drivers/ide/ppc/cpci405ide.c linux-2.4.25-pre5/drivers/ide/ppc/cpci405ide.c
--- linux-2.4.25-pre4/drivers/ide/ppc/cpci405ide.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.25-pre5/drivers/ide/ppc/cpci405ide.c	2004-01-15 12:10:22.000000000 -0800
@@ -0,0 +1,72 @@
+/*
+ *  linux/drivers/ide/ppc/cpci405ide.c -- CPCI405 IDE Driver
+ *
+ *  Copyright (C) 2001-2003 Stefan Roese, stefan.roese@esd-electronics.de
+ *
+ *  This driver was written based on information obtained from the MacOS IDE
+ *  driver binary by Mikael Forselius
+ *
+ *  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/types.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/blkdev.h>
+#include <linux/hdreg.h>
+#include <linux/delay.h>
+#include <linux/ide.h>
+#include <linux/init.h>
+
+
+/*
+ *  Base of the IDE interface
+ */
+
+#define CPCI405_HD_BASE	0xf0100000
+
+/*
+ *  Offsets from the above base (scaling 4)
+ */
+
+#define CPCI405_HD_DATA	        0x00
+#define CPCI405_HD_ERROR	0x01		/* see err-bits */
+#define CPCI405_HD_NSECTOR	0x02		/* nr of sectors to read/write */
+#define CPCI405_HD_SECTOR	0x03		/* starting sector */
+#define CPCI405_HD_LCYL	        0x04		/* starting cylinder */
+#define CPCI405_HD_HCYL	        0x05		/* high byte of starting cyl */
+#define CPCI405_HD_SELECT	0x06		/* 101dhhhh , d=drive, hhhh=head */
+#define CPCI405_HD_STATUS	0x07		/* see status-bits */
+#define CPCI405_HD_CONTROL	0x0e		/* control/altstatus */
+
+#define CPCI405_IRQ_IDE         0x1f
+
+static int cpci405ide_offsets[IDE_NR_PORTS] __initdata = {
+	CPCI405_HD_DATA, CPCI405_HD_ERROR, CPCI405_HD_NSECTOR, CPCI405_HD_SECTOR,
+	CPCI405_HD_LCYL, CPCI405_HD_HCYL, CPCI405_HD_SELECT, CPCI405_HD_STATUS,
+	CPCI405_HD_CONTROL
+};
+
+static void *cpci405_ide_base_mapped;
+
+
+/*
+ *  Probe for a CPCI405 IDE interface
+ */
+
+void __init cpci405ide_init(void)
+{
+	hw_regs_t hw;
+	int index = -1;
+
+	cpci405_ide_base_mapped =
+		ioremap((unsigned long) CPCI405_HD_BASE, 0x200) - _IO_BASE;
+        ide_setup_ports(&hw, (ide_ioreg_t)cpci405_ide_base_mapped,
+                        cpci405ide_offsets, 0, 0, NULL, CPCI405_IRQ_IDE);
+        index = ide_register_hw(&hw, NULL);
+        if (index != -1)
+		printk("ide%d: CPCI405 IDE interface\n", index);
+
+}
diff -urN linux-2.4.25-pre4/drivers/ieee1394/nodemgr.c linux-2.4.25-pre5/drivers/ieee1394/nodemgr.c
--- linux-2.4.25-pre4/drivers/ieee1394/nodemgr.c	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.25-pre5/drivers/ieee1394/nodemgr.c	2004-01-15 12:10:22.000000000 -0800
@@ -1028,12 +1028,11 @@
 		ne->nodeid = nodeid;
 	}
 
+	ne->generation = generation;
+
 	if (ne->busopt.generation != ((busoptions >> 4) & 0xf))
 		nodemgr_process_config_rom (ne, busoptions);
 
-	/* Since that's done, we can declare this record current */
-	ne->generation = generation;
-
 	list_for_each (lh, &ne->unit_directories) {
 		ud = list_entry (lh, struct unit_directory, node_list);
 		if (ud->driver && ud->driver->update != NULL)
diff -urN linux-2.4.25-pre4/drivers/media/video/Makefile linux-2.4.25-pre5/drivers/media/video/Makefile
--- linux-2.4.25-pre4/drivers/media/video/Makefile	2004-01-15 12:10:14.000000000 -0800
+++ linux-2.4.25-pre5/drivers/media/video/Makefile	2004-01-15 12:10:22.000000000 -0800
@@ -40,7 +40,7 @@
 
 obj-$(CONFIG_VIDEO_ZR36120) += zoran.o i2c-old.o
 obj-$(CONFIG_I2C_PARPORT) += i2c-parport.o i2c-old.o
-obj-$(CONFIG_VIDEO_SAA5249) += saa5249.o i2c-old.o
+obj-$(CONFIG_VIDEO_SAA5249) += saa5249.o
 obj-$(CONFIG_VIDEO_CQCAM) += c-qcam.o
 obj-$(CONFIG_VIDEO_BWQCAM) += bw-qcam.o
 obj-$(CONFIG_VIDEO_W9966) += w9966.o
@@ -48,11 +48,10 @@
 obj-$(CONFIG_VIDEO_ZORAN_BUZ) += saa7111.o saa7185.o
 obj-$(CONFIG_VIDEO_ZORAN_DC10) += saa7110.o adv7175.o
 obj-$(CONFIG_VIDEO_ZORAN_LML33) += bt819.o bt856.o
-obj-$(CONFIG_VIDEO_LML33) += bt856.o bt819.o
 obj-$(CONFIG_VIDEO_PMS) += pms.o
 obj-$(CONFIG_VIDEO_PLANB) += planb.o
 obj-$(CONFIG_VIDEO_VINO) += saa7191.o indycam.o vino.o
-obj-$(CONFIG_VIDEO_STRADIS) += stradis.o
+obj-$(CONFIG_VIDEO_STRADIS) += stradis.o i2c-old.o
 obj-$(CONFIG_VIDEO_CPIA) += cpia.o
 obj-$(CONFIG_VIDEO_CPIA_PP) += cpia_pp.o
 obj-$(CONFIG_VIDEO_CPIA_USB) += cpia_usb.o
@@ -81,8 +80,8 @@
 
 fastdep:
 
-zoran.o: zr36120.o zr36120_i2c.o zr36120_mem.o
-	$(LD) $(LD_RFLAG) -r -o $@ zr36120.o zr36120_i2c.o zr36120_mem.o
+zoran.o: $(zoran-objs)
+	$(LD) $(LD_RFLAG) -r -o $@ $(zoran-objs)
 
 bttv.o: $(bttv-objs)
 	$(LD) $(LD_RFLAG) -r -o $@ $(bttv-objs)
diff -urN linux-2.4.25-pre4/drivers/media/video/i2c-old.c linux-2.4.25-pre5/drivers/media/video/i2c-old.c
--- linux-2.4.25-pre4/drivers/media/video/i2c-old.c	2001-09-30 12:26:06.000000000 -0700
+++ linux-2.4.25-pre5/drivers/media/video/i2c-old.c	2004-01-15 12:10:22.000000000 -0800
@@ -36,28 +36,11 @@
 static struct i2c_driver *drivers[I2C_DRIVER_MAX];
 static int bus_count = 0, driver_count = 0;
 
-#ifdef CONFIG_VIDEO_BUZ
-extern int saa7111_init(void);
-extern int saa7185_init(void);
-#endif
-#ifdef CONFIG_VIDEO_LML33
-extern int bt819_init(void);
-extern int bt856_init(void);
-#endif
-
 int i2c_init(void)
 {
 	printk(KERN_INFO "i2c: initialized%s\n",
 		scan ? " (i2c bus scan enabled)" : "");
-	/* anything to do here ? */
-#ifdef CONFIG_VIDEO_BUZ
-	saa7111_init();
-	saa7185_init();
-#endif
-#ifdef CONFIG_VIDEO_LML33
-	bt819_init();
-	bt856_init();
-#endif
+
 	return 0;
 }
 
diff -urN linux-2.4.25-pre4/drivers/media/video/saa7146.h linux-2.4.25-pre5/drivers/media/video/saa7146.h
--- linux-2.4.25-pre4/drivers/media/video/saa7146.h	2000-12-11 13:15:51.000000000 -0800
+++ linux-2.4.25-pre5/drivers/media/video/saa7146.h	2004-01-15 12:10:22.000000000 -0800
@@ -25,7 +25,7 @@
 #include <linux/types.h>
 #include <linux/wait.h>
 
-#include <linux/i2c.h>
+#include <linux/i2c-old.h>
 #include <linux/videodev.h>
 
 #ifndef O_NONCAP  
diff -urN linux-2.4.25-pre4/drivers/net/wan/Config.in linux-2.4.25-pre5/drivers/net/wan/Config.in
--- linux-2.4.25-pre4/drivers/net/wan/Config.in	2004-01-15 12:10:15.000000000 -0800
+++ linux-2.4.25-pre5/drivers/net/wan/Config.in	2004-01-15 12:10:23.000000000 -0800
@@ -23,7 +23,7 @@
 # COMX drivers
 #
 
-   tristate '  MultiGate (COMX) synchronous serial boards support' CONFIG_COMX
+   bool '  MultiGate (COMX) synchronous serial boards support' CONFIG_COMX
    if [ "$CONFIG_COMX" != "n" ]; then
       dep_tristate '    Support for COMX/CMX/HiCOMX boards' CONFIG_COMX_HW_COMX $CONFIG_COMX
       dep_tristate '    Support for LoCOMX board' CONFIG_COMX_HW_LOCOMX $CONFIG_COMX
diff -urN linux-2.4.25-pre4/drivers/scsi/cpqfcTSstructs.h linux-2.4.25-pre5/drivers/scsi/cpqfcTSstructs.h
--- linux-2.4.25-pre4/drivers/scsi/cpqfcTSstructs.h	2003-06-13 07:51:36.000000000 -0700
+++ linux-2.4.25-pre5/drivers/scsi/cpqfcTSstructs.h	2004-01-15 12:10:23.000000000 -0800
@@ -219,7 +219,6 @@
 #define ELS_PRLI_ACC		0x22		// {FCP-SCSI} Process Login Accept
 #define ELS_RJT			0x1000000
 #define SCSI_REPORT_LUNS	0x0A0
-#define REPORT_LUNS		0xA0		// SCSI-3 command op-code
 #define FCP_TARGET_RESET	0x200
 
 #define ELS_LILP_FRAME		0x00000711	// 1st payload word of LILP frame
diff -urN linux-2.4.25-pre4/drivers/scsi/ips.c linux-2.4.25-pre5/drivers/scsi/ips.c
--- linux-2.4.25-pre4/drivers/scsi/ips.c	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.25-pre5/drivers/scsi/ips.c	2004-01-15 12:10:23.000000000 -0800
@@ -131,6 +131,8 @@
 /* 5.30.00  - use __devexit_p()                                              */
 /* 6.00.00  - Add 6x Adapters and Battery Flash                              */
 /* 6.10.00  - Remove 1G Addressing Limitations                               */
+/* 6.11.xx  - Get VersionInfo buffer off the stack !              DDTS 60401 */
+/* 6.11.xx  - Make Logical Drive Info structure safe for DMA      DDTS 60639 */
 /*****************************************************************************/
 
 /*
@@ -196,11 +198,11 @@
 /*
  * DRIVER_VER
  */
-#define IPS_VERSION_HIGH        "6.10"
-#define IPS_VERSION_LOW         ".24 "
+#define IPS_VERSION_HIGH        "6.11"
+#define IPS_VERSION_LOW         ".07 "
 
-#if !defined(__i386__) && !defined(__ia64__)
-#error "This driver has only been tested on the x86/ia64 platforms"
+#if !defined(__i386__) && !defined(__ia64__) && !defined(__x86_64__)
+#warning "This driver has only been tested on the x86/ia64/x86_64 platforms"
 #endif
 
 #if LINUX_VERSION_CODE <= LinuxVersionCode(2,5,0)
@@ -245,6 +247,7 @@
 static int ips_ioctlsize = IPS_IOCTL_SIZE;	/* Size of the ioctl buffer        */
 static int ips_cd_boot;		/* Booting from Manager CD         */
 static char *ips_FlashData = NULL;	/* CD Boot - Flash Data Buffer      */
+static dma_addr_t ips_flashbusaddr;
 static long ips_FlashDataInUse;	/* CD Boot - Flash Data In Use Flag */
 static uint32_t MaxLiteCmds = 32;	/* Max Active Cmds for a Lite Adapter */
 static Scsi_Host_Template ips_driver_template = IPS;
@@ -468,8 +471,7 @@
 static int ips_host_info(ips_ha_t *, char *, off_t, int);
 static void copy_mem_info(IPS_INFOSTR *, char *, int);
 static int copy_info(IPS_INFOSTR *, char *, ...);
-static int ips_get_version_info(ips_ha_t * ha, IPS_VERSION_DATA * Buffer,
-				int intr);
+static int ips_get_version_info(ips_ha_t * ha, dma_addr_t, int intr);
 static void ips_version_check(ips_ha_t * ha, int intr);
 static int ips_abort_init(ips_ha_t * ha, int index);
 static int ips_init_phase2(int index);
@@ -559,17 +561,6 @@
 		ips_setup(ips);
 #endif
 
-	/* If Booting from the Manager CD, Allocate a large Flash        */
-	/* Buffer ( so we won't need to allocate one for each adapter ). */
-	if (ips_cd_boot) {
-		ips_FlashData = (char *) __get_free_pages(IPS_INIT_GFP, 7);
-		if (ips_FlashData == NULL) {
-			/* The validity of this pointer is checked in ips_make_passthru() before it is used */
-			printk(KERN_WARNING
-			       "ERROR: Can't Allocate Large Buffer for Flashing\n");
-		}
-	}
-
 	SHT->proc_info = ips_proc_info;
 	SHT->proc_name = "ips";
 
@@ -1578,21 +1569,20 @@
 ips_alloc_passthru_buffer(ips_ha_t * ha, int length)
 {
 	void *bigger_buf;
-	int count;
-	int order;
+	dma_addr_t dma_busaddr;
 
-	if (ha->ioctl_data && length <= (PAGE_SIZE << ha->ioctl_order))
+	if (ha->ioctl_data && length <= ha->ioctl_len)
 		return 0;
 	/* there is no buffer or it's not big enough, allocate a new one */
-	for (count = PAGE_SIZE, order = 0;
-	     count < length; order++, count <<= 1) ;
-	bigger_buf = (void *) __get_free_pages(IPS_ATOMIC_GFP, order);
+	bigger_buf = pci_alloc_consistent(ha->pcidev, length, &dma_busaddr);
 	if (bigger_buf) {
 		/* free the old memory */
-		free_pages((unsigned long) ha->ioctl_data, ha->ioctl_order);
+		pci_free_consistent(ha->pcidev, ha->ioctl_len, ha->ioctl_data,
+				    ha->ioctl_busaddr);
 		/* use the new memory */
 		ha->ioctl_data = (char *) bigger_buf;
-		ha->ioctl_order = order;
+		ha->ioctl_len = length;
+		ha->ioctl_busaddr = dma_busaddr;
 	} else {
 		return -1;
 	}
@@ -1708,7 +1698,7 @@
 static int
 ips_flash_copperhead(ips_ha_t * ha, ips_passthru_t * pt, ips_scb_t * scb)
 {
-	int datasize, count;
+	int datasize;
 
 	/* Trombone is the only copperhead that can do packet flash, but only
 	 * for firmware. No one said it had to make sence. */
@@ -1728,24 +1718,28 @@
 		pt->BasicStatus = 0;
 		return ips_flash_bios(ha, pt, scb);
 	} else if (pt->CoppCP.cmd.flashfw.packet_num == 0) {
-		if (ips_FlashData && !test_and_set_bit(0, &ips_FlashDataInUse)) {
+		if (ips_FlashData && !test_and_set_bit(0, &ips_FlashDataInUse)){
 			ha->flash_data = ips_FlashData;
-			ha->flash_order = 7;
+			ha->flash_busaddr = ips_flashbusaddr;
+			ha->flash_len = PAGE_SIZE << 7;
 			ha->flash_datasize = 0;
 		} else if (!ha->flash_data) {
 			datasize = pt->CoppCP.cmd.flashfw.total_packets *
 			    pt->CoppCP.cmd.flashfw.count;
-			for (count = PAGE_SIZE, ha->flash_order = 0;
-			     count < datasize; ha->flash_order++, count <<= 1) ;
-			ha->flash_data =
-			    (char *) __get_free_pages(IPS_ATOMIC_GFP,
-						      ha->flash_order);
+			ha->flash_data = pci_alloc_consistent(ha->pcidev,
+					                      datasize,
+							      &ha->flash_busaddr);
+			if (!ha->flash_data){
+				printk(KERN_WARNING "Unable to allocate a flash buffer\n");
+				return IPS_FAILURE;
+			}
 			ha->flash_datasize = 0;
+			ha->flash_len = datasize;
 		} else
 			return IPS_FAILURE;
 	} else {
 		if (pt->CoppCP.cmd.flashfw.count + ha->flash_datasize >
-		    (PAGE_SIZE << ha->flash_order)) {
+		    ha->flash_len) {
 			ips_free_flash_copperhead(ha);
 			printk(KERN_WARNING "failed size sanity check\n");
 			return IPS_FAILURE;
@@ -1928,7 +1922,8 @@
 	if (ha->flash_data == ips_FlashData)
 		test_and_clear_bit(0, &ips_FlashDataInUse);
 	else if (ha->flash_data)
-		free_pages((unsigned long) ha->flash_data, ha->flash_order);
+		pci_free_consistent(ha->pcidev, ha->flash_len, ha->flash_data,
+				    ha->flash_busaddr);
 	ha->flash_data = NULL;
 }
 
@@ -1981,12 +1976,7 @@
 
 	if (pt->CmdBSize) {
 		scb->data_len = pt->CmdBSize;
-		scb->data_busaddr = pci_map_single(ha->pcidev,
-						   ha->ioctl_data +
-						   sizeof (ips_passthru_t),
-						   pt->CmdBSize,
-						   IPS_DMA_DIR(scb));
-		scb->flags |= IPS_SCB_MAP_SINGLE;
+		scb->data_busaddr = ha->ioctl_busaddr + sizeof (ips_passthru_t);
 	} else {
 		scb->data_busaddr = 0L;
 	}
@@ -2410,9 +2400,7 @@
 	} else {
 		/* Morpheus Family - Send Command to the card */
 
-		buffer = kmalloc(0x1000, IPS_ATOMIC_GFP);
-		if (!buffer)
-			return;
+		buffer = ha->ioctl_data;
 
 		memset(buffer, 0, 0x1000);
 
@@ -2431,11 +2419,7 @@
 		scb->cmd.flashfw.total_packets = 1;
 		scb->cmd.flashfw.packet_num = 0;
 		scb->data_len = 0x1000;
-		scb->data_busaddr =
-		    pci_map_single(ha->pcidev, buffer, scb->data_len,
-				   IPS_DMA_DIR(scb));
-		scb->cmd.flashfw.buffer_addr = scb->data_busaddr;
-		scb->flags |= IPS_SCB_MAP_SINGLE;
+		scb->cmd.flashfw.buffer_addr = ha->ioctl_busaddr;
 
 		/* issue the command */
 		if (
@@ -2443,7 +2427,6 @@
 		     IPS_FAILURE) || (ret == IPS_SUCCESS_IMM)
 		    || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) {
 			/* Error occurred */
-			kfree(buffer);
 
 			return;
 		}
@@ -2453,11 +2436,8 @@
 			minor = buffer[0x1fe + 0xC0];	/* Offset 0x1fe after the header (0xc0) */
 			subminor = buffer[0x1fd + 0xC0];	/* Offset 0x1fd after the header (0xc0) */
 		} else {
-			kfree(buffer);
 			return;
 		}
-
-		kfree(buffer);
 	}
 
 	ha->bios_version[0] = hexDigits[(major & 0xF0) >> 4];
@@ -2806,6 +2786,11 @@
 		scb->dcdb.cmd_attribute =
 		    ips_command_direction[scb->scsi_cmd->cmnd[0]];
 
+        /* Allow a WRITE BUFFER Command to Have no Data */
+        /* This is Used by Tape Flash Utilites          */
+        if ((scb->scsi_cmd->cmnd[0] == WRITE_BUFFER) && (scb->data_len == 0)) 
+            scb->dcdb.cmd_attribute = 0;                  
+
 		if (!(scb->dcdb.cmd_attribute & 0x3))
 			scb->dcdb.transfer_length = 0;
 
@@ -3786,23 +3771,14 @@
 					scb->scsi_cmd->result = DID_OK << 16;
 				}
 			} else {
-				scb->cmd.logical_info.op_code =
-				    IPS_CMD_GET_LD_INFO;
-				scb->cmd.logical_info.command_id =
-				    IPS_COMMAND_ID(ha, scb);
+				scb->cmd.logical_info.op_code = IPS_CMD_GET_LD_INFO;
+				scb->cmd.logical_info.command_id = IPS_COMMAND_ID(ha, scb);
 				scb->cmd.logical_info.reserved = 0;
 				scb->cmd.logical_info.reserved2 = 0;
-				scb->data_len =
-				    sizeof (ha->adapt->logical_drive_info);
-				scb->data_busaddr =
-				    pci_map_single(ha->pcidev,
-						   &ha->adapt->
-						   logical_drive_info,
-						   scb->data_len,
-						   IPS_DMA_DIR(scb));
-				scb->flags |= IPS_SCB_MAP_SINGLE;
-				scb->cmd.logical_info.buffer_addr =
-				    scb->data_busaddr;
+				scb->data_len = sizeof (IPS_LD_INFO);
+				scb->data_busaddr = ha->logical_drive_info_dma_addr;
+				scb->flags = 0;
+				scb->cmd.logical_info.buffer_addr = scb->data_busaddr;
 				ret = IPS_SUCCESS;
 			}
 
@@ -3930,28 +3906,19 @@
 			scb->cmd.basic_io.segment_4G = 0;
 			scb->cmd.basic_io.enhanced_sg = 0;
 			scb->data_len = sizeof (*ha->enq);
-			scb->data_busaddr = pci_map_single(ha->pcidev, ha->enq,
-							   scb->data_len,
-							   IPS_DMA_DIR(scb));
-			scb->cmd.basic_io.sg_addr = scb->data_busaddr;
-			scb->flags |= IPS_SCB_MAP_SINGLE;
+			scb->cmd.basic_io.sg_addr = ha->enq_busaddr;
 			ret = IPS_SUCCESS;
 			break;
 
 		case READ_CAPACITY:
 			scb->cmd.logical_info.op_code = IPS_CMD_GET_LD_INFO;
-			scb->cmd.logical_info.command_id =
-			    IPS_COMMAND_ID(ha, scb);
+			scb->cmd.logical_info.command_id = IPS_COMMAND_ID(ha, scb);
 			scb->cmd.logical_info.reserved = 0;
 			scb->cmd.logical_info.reserved2 = 0;
 			scb->cmd.logical_info.reserved3 = 0;
-			scb->data_len = sizeof (ha->adapt->logical_drive_info);
-			scb->data_busaddr = pci_map_single(ha->pcidev,
-							   &ha->adapt->
-							   logical_drive_info,
-							   scb->data_len,
-							   IPS_DMA_DIR(scb));
-			scb->flags |= IPS_SCB_MAP_SINGLE;
+			scb->data_len = sizeof (IPS_LD_INFO);
+            scb->data_busaddr = ha->logical_drive_info_dma_addr;
+			scb->flags = 0;
 			scb->cmd.logical_info.buffer_addr = scb->data_busaddr;
 			ret = IPS_SUCCESS;
 			break;
@@ -4275,19 +4242,17 @@
 		return (0);
 
 	if ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1) {
-		memset(&ha->adapt->logical_drive_info, 0,
-		       sizeof (ha->adapt->logical_drive_info));
-
-		return (0);
+		memset(ha->logical_drive_info, 0, sizeof (IPS_LD_INFO));
+        return (0);
 	}
 
-	if (ha->adapt->logical_drive_info.drive_info[scb->target_id].state !=
+	if (ha->logical_drive_info->drive_info[scb->target_id].state !=
 	    IPS_LD_OFFLINE
-	    && ha->adapt->logical_drive_info.drive_info[scb->target_id].state !=
+	    && ha->logical_drive_info->drive_info[scb->target_id].state !=
 	    IPS_LD_FREE
-	    && ha->adapt->logical_drive_info.drive_info[scb->target_id].state !=
+	    && ha->logical_drive_info->drive_info[scb->target_id].state !=
 	    IPS_LD_CRS
-	    && ha->adapt->logical_drive_info.drive_info[scb->target_id].state !=
+	    && ha->logical_drive_info->drive_info[scb->target_id].state !=
 	    IPS_LD_SYS) return (1);
 	else
 		return (0);
@@ -4349,7 +4314,7 @@
 
 	cap.lba =
 	    cpu_to_be32(le32_to_cpu
-			(ha->adapt->logical_drive_info.
+			(ha->logical_drive_info->
 			 drive_info[scb->target_id].sector_count) - 1);
 	cap.len = cpu_to_be32((uint32_t) IPS_BLKSIZE);
 
@@ -4488,7 +4453,8 @@
 
 	if (ha) {
 		if (ha->enq) {
-			kfree(ha->enq);
+			pci_free_consistent(ha->pcidev, sizeof(IPS_ENQ),
+					    ha->enq, ha->enq_busaddr);
 			ha->enq = NULL;
 		}
 
@@ -4503,6 +4469,14 @@
 					    sizeof (IPS_IO_CMD), ha->adapt,
 					    ha->adapt->hw_status_start);
 			ha->adapt = NULL;
+		}  	
+        	
+        if (ha->logical_drive_info) {
+			pci_free_consistent(ha->pcidev,
+					    sizeof (IPS_LD_INFO),
+                        ha->logical_drive_info,
+					    ha->logical_drive_info_dma_addr);
+			ha->logical_drive_info = NULL;
 		}
 
 		if (ha->nvram) {
@@ -4516,11 +4490,11 @@
 		}
 
 		if (ha->ioctl_data) {
-			free_pages((unsigned long) ha->ioctl_data,
-				   ha->ioctl_order);
+			pci_free_consistent(ha->pcidev, ha->ioctl_len,
+					    ha->ioctl_data, ha->ioctl_busaddr);
 			ha->ioctl_data = NULL;
 			ha->ioctl_datasize = 0;
-			ha->ioctl_order = 0;
+			ha->ioctl_len = 0;
 		}
 		ips_deallocatescbs(ha, ha->max_cmds);
 
@@ -4694,6 +4668,7 @@
 	}
 
 	ha->scb_freelist = scb->q_next;
+    scb->flags = 0;
 	scb->q_next = NULL;
 
 	ips_init_scb(ha, scb);
@@ -5861,10 +5836,7 @@
 	scb->cmd.basic_io.sector_count = 0;
 	scb->cmd.basic_io.log_drv = 0;
 	scb->data_len = sizeof (*ha->enq);
-	scb->data_busaddr = pci_map_single(ha->pcidev, ha->enq, scb->data_len,
-					   IPS_DMA_DIR(scb));
-	scb->cmd.basic_io.sg_addr = scb->data_busaddr;
-	scb->flags |= IPS_SCB_MAP_SINGLE;
+	scb->cmd.basic_io.sg_addr = ha->enq_busaddr;
 
 	/* send command */
 	if (
@@ -5907,10 +5879,7 @@
 	scb->cmd.basic_io.sector_count = 0;
 	scb->cmd.basic_io.log_drv = 0;
 	scb->data_len = sizeof (*ha->subsys);
-	scb->data_busaddr = pci_map_single(ha->pcidev, ha->subsys,
-					   scb->data_len, IPS_DMA_DIR(scb));
-	scb->cmd.basic_io.sg_addr = scb->data_busaddr;
-	scb->flags |= IPS_SCB_MAP_SINGLE;
+	scb->cmd.basic_io.sg_addr = ha->ioctl_busaddr;
 
 	/* send command */
 	if (
@@ -5919,6 +5888,7 @@
 	    || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1))
 		return (0);
 
+	memcpy(ha->subsys, ha->ioctl_data, sizeof(*ha->subsys));
 	return (1);
 }
 
@@ -5954,10 +5924,7 @@
 	scb->cmd.basic_io.op_code = IPS_CMD_READ_CONF;
 	scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
 	scb->data_len = sizeof (*ha->conf);
-	scb->data_busaddr = pci_map_single(ha->pcidev, ha->conf,
-					   scb->data_len, IPS_DMA_DIR(scb));
-	scb->cmd.basic_io.sg_addr = scb->data_busaddr;
-	scb->flags |= IPS_SCB_MAP_SINGLE;
+	scb->cmd.basic_io.sg_addr = ha->ioctl_busaddr;
 
 	/* send command */
 	if (
@@ -5977,7 +5944,8 @@
 
 		return (0);
 	}
-
+	
+	memcpy(ha->conf, ha->ioctl_data, sizeof(*ha->conf));
 	return (1);
 }
 
@@ -6012,11 +5980,10 @@
 	scb->cmd.nvram.reserved = 0;
 	scb->cmd.nvram.reserved2 = 0;
 	scb->data_len = sizeof (*ha->nvram);
-	scb->data_busaddr = pci_map_single(ha->pcidev, ha->nvram,
-					   scb->data_len, IPS_DMA_DIR(scb));
-	scb->cmd.nvram.buffer_addr = scb->data_busaddr;
-	scb->flags |= IPS_SCB_MAP_SINGLE;
-
+	scb->cmd.nvram.buffer_addr = ha->ioctl_busaddr;
+	if (write)
+		memcpy(ha->ioctl_data, ha->nvram, sizeof(*ha->nvram));
+	
 	/* issue the command */
 	if (
 	    ((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) ==
@@ -6027,7 +5994,8 @@
 
 		return (0);
 	}
-
+	if (!write)
+		memcpy(ha->nvram, ha->ioctl_data, sizeof(*ha->nvram));
 	return (1);
 }
 
@@ -6155,7 +6123,7 @@
 	scb->cmd.ffdc.op_code = IPS_CMD_FFDC;
 	scb->cmd.ffdc.command_id = IPS_COMMAND_ID(ha, scb);
 	scb->cmd.ffdc.reset_count = 0;
-	scb->cmd.ffdc.reset_type = 0x80;
+	scb->cmd.ffdc.reset_type = 0;
 
 	/* convert time to what the card wants */
 	ips_fix_ffdc_time(ha, scb, ha->last_ffdc);
@@ -6750,16 +6718,18 @@
 static void
 ips_version_check(ips_ha_t * ha, int intr)
 {
-	IPS_VERSION_DATA VersionInfo;
+	IPS_VERSION_DATA *VersionInfo;
 	uint8_t FirmwareVersion[IPS_COMPAT_ID_LENGTH + 1];
 	uint8_t BiosVersion[IPS_COMPAT_ID_LENGTH + 1];
 	int MatchError;
-	int rc;
+	int  rc;
 	char BiosString[10];
 	char FirmwareString[10];
 
 	METHOD_TRACE("ips_version_check", 1);
 
+    VersionInfo = ( IPS_VERSION_DATA * ) ha->ioctl_data;
+
 	memset(FirmwareVersion, 0, IPS_COMPAT_ID_LENGTH + 1);
 	memset(BiosVersion, 0, IPS_COMPAT_ID_LENGTH + 1);
 
@@ -6769,10 +6739,11 @@
 
 	rc = IPS_FAILURE;
 	if (ha->subsys->param[4] & IPS_GET_VERSION_SUPPORT) {	/* If Versioning is Supported */
+        memset( VersionInfo, 0, sizeof (IPS_VERSION_DATA));
 		/* Get the Version Info with a Get Version Command */
-		rc = ips_get_version_info(ha, &VersionInfo, intr);
+		rc = ips_get_version_info(ha, ha->ioctl_busaddr, intr);
 		if (rc == IPS_SUCCESS)
-			memcpy(FirmwareVersion, VersionInfo.compatibilityId,
+			memcpy(FirmwareVersion, VersionInfo->compatibilityId,
 			       IPS_COMPAT_ID_LENGTH);
 	}
 
@@ -6835,14 +6806,13 @@
 /*     0 if Successful, else non-zero                                        */
 /*---------------------------------------------------------------------------*/
 static int
-ips_get_version_info(ips_ha_t * ha, IPS_VERSION_DATA * Buffer, int intr)
+ips_get_version_info(ips_ha_t * ha, dma_addr_t Buffer, int intr)
 {
 	ips_scb_t *scb;
 	int rc;
 
 	METHOD_TRACE("ips_get_version_info", 1);
 
-	memset(Buffer, 0, sizeof (IPS_VERSION_DATA));
 	scb = &ha->scbs[ha->max_cmds - 1];
 
 	ips_init_scb(ha, scb);
@@ -6854,11 +6824,10 @@
 	scb->cmd.version_info.reserved = 0;
 	scb->cmd.version_info.count = sizeof (IPS_VERSION_DATA);
 	scb->cmd.version_info.reserved2 = 0;
-	scb->data_len = sizeof (*Buffer);
-	scb->data_busaddr = pci_map_single(ha->pcidev, Buffer,
-					   scb->data_len, IPS_DMA_DIR(scb));
-	scb->cmd.version_info.buffer_addr = scb->data_busaddr;
-	scb->flags |= IPS_SCB_MAP_SINGLE;
+	scb->data_len = sizeof (IPS_VERSION_DATA);
+    scb->data_busaddr = Buffer;
+	scb->cmd.version_info.buffer_addr = Buffer;
+	scb->flags = 0;
 
 	/* issue command */
 	rc = ips_send_wait(ha, scb, ips_cmd_timeout, intr);
@@ -7176,7 +7145,6 @@
 	uint16_t subdevice_id;
 	int j;
 	int index;
-	uint32_t count;
 	dma_addr_t dma_address;
 	char *ioremap_ptr;
 	char *mem_ptr;
@@ -7292,17 +7260,21 @@
 	 * are guaranteed to be < 4G.
 	 */
 	if (IPS_ENABLE_DMA64 && IPS_HAS_ENH_SGLIST(ha) &&
-	    !pci_set_dma_mask(ha->pcidev, (u64) 0xffffffffffffffff)) {
+	    !pci_set_dma_mask(ha->pcidev, 0xffffffffffffffffULL)) {
 		(ha)->flags |= IPS_HA_ENH_SG;
 	} else {
-		if (pci_set_dma_mask(ha->pcidev, (u64) 0xffffffff) != 0) {
+		if (pci_set_dma_mask(ha->pcidev, 0xffffffffULL) != 0) {
 			printk(KERN_WARNING "Unable to set DMA Mask\n");
 			return ips_abort_init(ha, index);
 		}
 	}
-
-	ha->enq = kmalloc(sizeof (IPS_ENQ), IPS_INIT_GFP);
-
+	if(ips_cd_boot && !ips_FlashData){
+		ips_FlashData = pci_alloc_consistent(pci_dev, PAGE_SIZE << 7,
+						     &ips_flashbusaddr);
+	}
+	
+	ha->enq = pci_alloc_consistent(pci_dev, sizeof (IPS_ENQ),
+				       &ha->enq_busaddr);
 	if (!ha->enq) {
 		printk(KERN_WARNING
 		       "Unable to allocate host inquiry structure\n");
@@ -7318,15 +7290,24 @@
 	}
 	ha->adapt->hw_status_start = dma_address;
 	ha->dummy = (void *) (ha->adapt + 1);
-
-	ha->conf = kmalloc(sizeof (IPS_CONF), IPS_INIT_GFP);
+    
+	ha->logical_drive_info = pci_alloc_consistent(pci_dev, sizeof (IPS_LD_INFO),
+                                                  &dma_address);
+	if (!ha->logical_drive_info) {
+		printk(KERN_WARNING
+		       "Unable to allocate host logical drive info structure\n");
+		return ips_abort_init(ha, index);
+	}
+	ha->logical_drive_info_dma_addr = dma_address;
+    
+	ha->conf = kmalloc(sizeof (IPS_CONF), GFP_KERNEL);
 
 	if (!ha->conf) {
 		printk(KERN_WARNING "Unable to allocate host conf structure\n");
 		return ips_abort_init(ha, index);
 	}
 
-	ha->nvram = kmalloc(sizeof (IPS_NVRAM_P5), IPS_INIT_GFP);
+	ha->nvram = kmalloc(sizeof (IPS_NVRAM_P5), GFP_KERNEL);
 
 	if (!ha->nvram) {
 		printk(KERN_WARNING
@@ -7334,7 +7315,7 @@
 		return ips_abort_init(ha, index);
 	}
 
-	ha->subsys = kmalloc(sizeof (IPS_SUBSYS), IPS_INIT_GFP);
+	ha->subsys = kmalloc(sizeof (IPS_SUBSYS), GFP_KERNEL);
 
 	if (!ha->subsys) {
 		printk(KERN_WARNING
@@ -7342,18 +7323,18 @@
 		return ips_abort_init(ha, index);
 	}
 
-	for (count = PAGE_SIZE, ha->ioctl_order = 0;
-	     count < ips_ioctlsize; ha->ioctl_order++, count <<= 1) ;
-
-	ha->ioctl_data =
-	    (char *) __get_free_pages(IPS_INIT_GFP, ha->ioctl_order);
-	ha->ioctl_datasize = count;
+	/* the ioctl buffer is now used during adapter initialization, so its
+	 * successful allocation is now required */
+	if (ips_ioctlsize < PAGE_SIZE)
+		ips_ioctlsize = PAGE_SIZE;
+	
+	ha->ioctl_data = pci_alloc_consistent(pci_dev, ips_ioctlsize,
+					      &ha->ioctl_busaddr);
+	ha->ioctl_len = ips_ioctlsize;
 
 	if (!ha->ioctl_data) {
 		printk(KERN_WARNING "Unable to allocate IOCTL data\n");
-		ha->ioctl_data = NULL;
-		ha->ioctl_order = 0;
-		ha->ioctl_datasize = 0;
+		return ips_abort_init(ha, index);
 	}
 
 	/*
diff -urN linux-2.4.25-pre4/drivers/scsi/ips.h linux-2.4.25-pre5/drivers/scsi/ips.h
--- linux-2.4.25-pre4/drivers/scsi/ips.h	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.25-pre5/drivers/scsi/ips.h	2004-01-15 12:10:23.000000000 -0800
@@ -111,22 +111,13 @@
       #define min(x,y) ((x) < (y) ? x : y)
    #endif
 
+   #define pci_dma_hi32(a)         ((a >> 16) >> 16)
    #define pci_dma_lo32(a)         (a & 0xffffffff)
 
    #if (BITS_PER_LONG > 32) || (defined CONFIG_HIGHMEM64G && defined IPS_HIGHIO)
       #define IPS_ENABLE_DMA64        (1)
-      #define pci_dma_hi32(a)         (a >> 32)
    #else
       #define IPS_ENABLE_DMA64        (0)
-      #define pci_dma_hi32(a)         (0)
-   #endif
-
-   #if defined(__ia64__)
-      #define IPS_ATOMIC_GFP	(GFP_DMA | GFP_ATOMIC)
-      #define IPS_INIT_GFP	GFP_DMA
-   #else
-      #define IPS_ATOMIC_GFP    GFP_ATOMIC
-      #define IPS_INIT_GFP	GFP_KERNEL
    #endif
 
    /*
@@ -734,7 +725,6 @@
    volatile PIPS_STATUS p_status_tail;
    volatile uint32_t    hw_status_start;
    volatile uint32_t    hw_status_tail;
-   IPS_LD_INFO          logical_drive_info;
 } IPS_ADAPTER, *PIPS_ADAPTER;
 
 typedef struct {
@@ -1092,6 +1082,8 @@
    ips_scb_queue_t    scb_activelist;     /* Active SCB list            */
    IPS_IO_CMD        *dummy;              /* dummy command              */
    IPS_ADAPTER       *adapt;              /* Adapter status area        */
+   IPS_LD_INFO       *logical_drive_info; /* Logical Drive Info         */
+   dma_addr_t         logical_drive_info_dma_addr; /* Logical Drive Info DMA Address */
    IPS_ENQ           *enq;                /* Adapter Enquiry data       */
    IPS_CONF          *conf;               /* Adapter config data        */
    IPS_NVRAM_P5      *nvram;              /* NVRAM page 5 data          */
@@ -1109,7 +1101,8 @@
    uint16_t           device_id;          /* PCI device ID              */
    uint8_t            slot_num;           /* PCI Slot Number            */
    uint16_t           subdevice_id;       /* Subsystem device ID        */
-   uint8_t            ioctl_order;        /* Number of pages in ioctl   */
+   int                ioctl_len;          /* size of ioctl buffer       */
+   dma_addr_t         ioctl_busaddr;      /* dma address of ioctl buffer*/
    uint8_t            bios_version[8];    /* BIOS Revision              */
    uint32_t           mem_addr;           /* Memory mapped address      */
    uint32_t           io_len;             /* Size of IO Address         */
@@ -1119,8 +1112,10 @@
    ips_hw_func_t      func;               /* hw function pointers       */
    struct pci_dev    *pcidev;             /* PCI device handle          */
    char              *flash_data;         /* Save Area for flash data   */
-   u8                 flash_order;        /* Save Area for flash size order */
+   int                flash_len;          /* length of flash buffer     */
    u32                flash_datasize;     /* Save Area for flash data size */
+   dma_addr_t         flash_busaddr;      /* dma address of flash buffer*/
+   dma_addr_t         enq_busaddr;        /* dma address of enq struct  */
    uint8_t            requires_esl;       /* Requires an EraseStripeLock */
 } ips_ha_t;
 
@@ -1136,8 +1131,8 @@
    uint8_t           bus;
    uint8_t           lun;
    uint8_t           cdb[12];
-   uint32_t          scb_busaddr;
-   uint32_t          data_busaddr;
+   uint32_t          scb_busaddr;      
+   uint32_t          old_data_busaddr;         // Obsolete field left in to not break utilities
    uint32_t          timeout;
    uint8_t           basic_status;
    uint8_t           extended_status;
@@ -1153,6 +1148,7 @@
    ips_scb_callback  callback;
    uint32_t          sg_busaddr;
    int               sg_count;
+   dma_addr_t        data_busaddr;
 } ips_scb_t;
 
 typedef struct ips_scb_pt {
@@ -1208,13 +1204,13 @@
 
 #define IPS_VER_MAJOR 6
 #define IPS_VER_MAJOR_STRING "6"
-#define IPS_VER_MINOR 10
-#define IPS_VER_MINOR_STRING "10"
-#define IPS_VER_BUILD 24
-#define IPS_VER_BUILD_STRING "24"
-#define IPS_VER_STRING "6.10.24"
-#define IPS_RELEASE_ID 0x00010000
-#define IPS_BUILD_IDENT 1250
+#define IPS_VER_MINOR 11
+#define IPS_VER_MINOR_STRING "11"
+#define IPS_VER_BUILD 07
+#define IPS_VER_BUILD_STRING "07"
+#define IPS_VER_STRING "6.11.07"
+#define IPS_RELEASE_ID 0x00010001
+#define IPS_BUILD_IDENT 2224
 #define IPS_LEGALCOPYRIGHT_STRING "(C) Copyright IBM Corp. 1994, 2003. All Rights Reserved."
 #define IPS_ADAPTECCOPYRIGHT_STRING "(c) Copyright Adaptec, Inc. 2002 to present. All Rights Reserved."
 #define IPS_NT_LEGALCOPYRIGHT_STRING "(C) Copyright IBM Corp. 1994, 2003."
@@ -1224,11 +1220,11 @@
 #define IPS_VER_SERVERAID2 "2.88.13"
 #define IPS_VER_NAVAJO "2.88.13"
 #define IPS_VER_SERVERAID3 "6.10.24"
-#define IPS_VER_SERVERAID4H "6.10.24"
-#define IPS_VER_SERVERAID4MLx "6.10.24"
-#define IPS_VER_SARASOTA "6.10.24"
-#define IPS_VER_MARCO "6.10.24"
-#define IPS_VER_SEBRING "6.10.24"
+#define IPS_VER_SERVERAID4H "6.11.07"
+#define IPS_VER_SERVERAID4MLx "6.11.07"
+#define IPS_VER_SARASOTA "6.11.07"
+#define IPS_VER_MARCO "6.11.07"
+#define IPS_VER_SEBRING "6.11.07"
 
 /* Compatability IDs for various adapters */
 #define IPS_COMPAT_UNKNOWN ""
diff -urN linux-2.4.25-pre4/drivers/sound/ymfpci.c linux-2.4.25-pre5/drivers/sound/ymfpci.c
--- linux-2.4.25-pre4/drivers/sound/ymfpci.c	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.25-pre5/drivers/sound/ymfpci.c	2004-01-15 12:10:23.000000000 -0800
@@ -152,22 +152,19 @@
 	writel(val, codec->reg_area_virt + offset);
 }
 
-static int ymfpci_codec_ready(ymfpci_t *codec, int secondary, int sched)
+static int ymfpci_codec_ready(ymfpci_t *unit, int secondary)
 {
-	signed long end_time;
+	enum { READY_STEP = 10 };
 	u32 reg = secondary ? YDSXGR_SECSTATUSADR : YDSXGR_PRISTATUSADR;
+	int i;
 
-	end_time = jiffies + 3 * (HZ / 4);
-	do {
-		if ((ymfpci_readw(codec, reg) & 0x8000) == 0)
+	for (i = 0; i < ((3*1000)/4) / READY_STEP; i++) {
+		if ((ymfpci_readw(unit, reg) & 0x8000) == 0)
 			return 0;
-		if (sched) {
-			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout(1);
-		}
-	} while (end_time - (signed long)jiffies >= 0);
+		mdelay(READY_STEP);
+	}
 	printk(KERN_ERR "ymfpci_codec_ready: codec %i is not ready [0x%x]\n",
-	    secondary, ymfpci_readw(codec, reg));
+	    secondary, ymfpci_readw(unit, reg));
 	return -EBUSY;
 }
 
@@ -178,38 +175,35 @@
 
 	spin_lock(&codec->ac97_lock);
 	/* XXX Do make use of dev->id */
-	ymfpci_codec_ready(codec, 0, 0);
+	ymfpci_codec_ready(codec, 0);
 	cmd = ((YDSXG_AC97WRITECMD | reg) << 16) | val;
 	ymfpci_writel(codec, YDSXGR_AC97CMDDATA, cmd);
 	spin_unlock(&codec->ac97_lock);
 }
 
-static u16 _ymfpci_codec_read(ymfpci_t *unit, u8 reg)
+static u16 ymfpci_codec_read(struct ac97_codec *dev, u8 reg)
 {
+	ymfpci_t *unit = dev->private_data;
+	u16 ret;
 	int i;
 
-	if (ymfpci_codec_ready(unit, 0, 0))
-		return ~0;
+	spin_lock(&unit->ac97_lock);
+	if (ymfpci_codec_ready(unit, 0))
+		goto out_err;
 	ymfpci_writew(unit, YDSXGR_AC97CMDADR, YDSXG_AC97READCMD | reg);
-	if (ymfpci_codec_ready(unit, 0, 0))
-		return ~0;
+	if (ymfpci_codec_ready(unit, 0))
+		goto out_err;
 	if (unit->pci->device == PCI_DEVICE_ID_YAMAHA_744 && unit->rev < 2) {
 		for (i = 0; i < 600; i++)
 			ymfpci_readw(unit, YDSXGR_PRISTATUSDATA);
 	}
-	return ymfpci_readw(unit, YDSXGR_PRISTATUSDATA);
-}
-
-static u16 ymfpci_codec_read(struct ac97_codec *dev, u8 reg)
-{
-	ymfpci_t *unit = dev->private_data;
-	u16 ret;
-	
-	spin_lock(&unit->ac97_lock);
-	ret = _ymfpci_codec_read(unit, reg);
+	ret = ymfpci_readw(unit, YDSXGR_PRISTATUSDATA);
 	spin_unlock(&unit->ac97_lock);
-	
 	return ret;
+
+ out_err:
+	spin_unlock(&unit->ac97_lock);
+	return ~0;
 }
 
 /*
@@ -2123,7 +2117,7 @@
 	int i;
 
 	ymfpci_aclink_reset(unit->pci);
-	ymfpci_codec_ready(unit, 0, 1);		/* prints diag if not ready. */
+	ymfpci_codec_ready(unit, 0);		/* prints diag if not ready. */
 
 #ifdef CONFIG_SOUND_YMFPCI_LEGACY
 	/* XXX At this time the legacy registers are probably deprogrammed. */
@@ -2549,7 +2543,7 @@
 	    (char *)ent->driver_data, base, pcidev->irq);
 
 	ymfpci_aclink_reset(pcidev);
-	if (ymfpci_codec_ready(codec, 0, 1) < 0)
+	if (ymfpci_codec_ready(codec, 0) < 0)
 		goto out_unmap;
 
 #ifdef CONFIG_SOUND_YMFPCI_LEGACY
@@ -2625,6 +2619,7 @@
  out_release_region:
 	release_mem_region(pci_resource_start(pcidev, 0), 0x8000);
  out_free:
+	kfree(codec);
 	return -ENODEV;
 }
 
@@ -2652,6 +2647,7 @@
 		unload_uart401(&codec->mpu_data);
 	}
 #endif /* CONFIG_SOUND_YMFPCI_LEGACY */
+	kfree(codec);
 }
 
 MODULE_AUTHOR("Jaroslav Kysela");
diff -urN linux-2.4.25-pre4/drivers/usb/storage/usb.c linux-2.4.25-pre5/drivers/usb/storage/usb.c
--- linux-2.4.25-pre4/drivers/usb/storage/usb.c	2003-08-25 04:44:42.000000000 -0700
+++ linux-2.4.25-pre5/drivers/usb/storage/usb.c	2004-01-15 12:10:23.000000000 -0800
@@ -332,6 +332,8 @@
 
 	/* set our name for identification purposes */
 	sprintf(current->comm, "usb-storage-%d", us->host_number);
+	
+	current->flags |= PF_MEMALLOC;
 
 	unlock_kernel();
 
diff -urN linux-2.4.25-pre4/drivers/usb/vicam.c linux-2.4.25-pre5/drivers/usb/vicam.c
--- linux-2.4.25-pre4/drivers/usb/vicam.c	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.25-pre5/drivers/usb/vicam.c	2004-01-15 12:10:23.000000000 -0800
@@ -601,12 +601,19 @@
 	case VIDIOCSWIN:
 		{
 
-			struct video_window *vw = (struct video_window *) arg;
-			DBG("VIDIOCSWIN %d x %d\n", vw->width, vw->height);
+			struct video_window vw;
 
-			if ( vw->width != 320 || vw->height != 240 )
+			if (copy_from_user(&vw, arg, sizeof(vw)))
+			{
 				retval = -EFAULT;
+				break;
+			}
+
+			DBG("VIDIOCSWIN %d x %d\n", vw->width, vw->height);
 			
+			if ( vw.width != 320 || vw.height != 240 )
+				retval = -EFAULT;
+
 			break;
 		}
 
diff -urN linux-2.4.25-pre4/drivers/usb/w9968cf.c linux-2.4.25-pre5/drivers/usb/w9968cf.c
--- linux-2.4.25-pre4/drivers/usb/w9968cf.c	2004-01-15 12:10:15.000000000 -0800
+++ linux-2.4.25-pre5/drivers/usb/w9968cf.c	2004-01-15 12:10:23.000000000 -0800
@@ -3548,10 +3548,13 @@
 
 	case VIDIOCSYNC: /* wait until the capture of a frame is finished */
 	{
-		unsigned int f_num = *((unsigned int *) arg);
+		unsigned int f_num;
 		struct w9968cf_frame_t* fr;
 		int err = 0;
 
+		if (copy_from_user(&f_num, arg, sizeof(f_num)))
+			return -EFAULT;
+
 		if (f_num >= cam->nbuffers) {
 			DBG(4, "Invalid frame number (%d). "
 			       "VIDIOCMCAPTURE failed.", f_num)
@@ -3616,7 +3619,8 @@
 	{
 		struct video_buffer* buffer = (struct video_buffer*)arg;
 
-		memset(buffer, 0, sizeof(struct video_buffer));
+		if (clear_user(buffer, sizeof(struct video_buffer)))
+			return -EFAULT;
 
 		DBG(5, "VIDIOCGFBUF successfully called.")
 		return 0;
diff -urN linux-2.4.25-pre4/drivers/video/sis/300vtbl.h linux-2.4.25-pre5/drivers/video/sis/300vtbl.h
--- linux-2.4.25-pre4/drivers/video/sis/300vtbl.h	2003-11-28 10:26:21.000000000 -0800
+++ linux-2.4.25-pre5/drivers/video/sis/300vtbl.h	2004-01-15 12:10:23.000000000 -0800
@@ -2,35 +2,54 @@
 /*
  * Register settings for SiS 300 series
  *
- * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
+ * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
  *
- * If distributed as part of the linux kernel, the contents of this file
- * is entirely covered by the GPL.
+ * If distributed as part of the Linux kernel, the following license terms
+ * apply:
  *
- * Otherwise, the following terms apply:
+ * * This program is free software; you can redistribute it and/or modify
+ * * it under the terms of the GNU General Public License as published by
+ * * the Free Software Foundation; either version 2 of the named License,
+ * * or any later version.
+ * *
+ * * This program is distributed in the hope that it will be useful,
+ * * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * * GNU General Public License for more details.
+ * *
+ * * You should have received a copy of the GNU General Public License
+ * * along with this program; if not, write to the Free Software
+ * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
  *
- * 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.
+ * Otherwise, the following license terms apply:
  *
- * 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.
+ * * Redistribution and use in source and binary forms, with or without
+ * * modification, are permitted provided that the following conditions
+ * * are met:
+ * * 1) Redistributions of source code must retain the above copyright
+ * *    notice, this list of conditions and the following disclaimer.
+ * * 2) Redistributions in binary form must reproduce the above copyright
+ * *    notice, this list of conditions and the following disclaimer in the
+ * *    documentation and/or other materials provided with the distribution.
+ * * 3) All advertising materials mentioning features or use of this software
+ * *    must display the following acknowledgement: "This product includes
+ * *    software developed by Thomas Winischhofer, Vienna, Austria."
+ * * 4) The name of the author may not be used to endorse or promote products
+ * *    derived from this software without specific prior written permission.
+ * *
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
  *
- * Based on code by Silicon Intergrated Systems
- *
  */
 
 typedef struct _SiS300_StStruct
@@ -43,215 +62,218 @@
 	UCHAR VB_StTVFlickerIndex;
 	UCHAR VB_StTVEdgeIndex;
 	UCHAR VB_StTVYFilterIndex;
+	UCHAR St_PDC;
 } SiS300_StStruct;
 
 static const SiS300_StStruct  SiS300_SModeIDTable[] =
 {
-	{0x01,0x9208,0x01,0x00,0x00,0x00,0x00,0x00},
-	{0x01,0x1210,0x14,0x01,0x01,0x00,0x00,0x00},
-	{0x01,0x1010,0x17,0x02,0x02,0x00,0x00,0x00},
-	{0x03,0x8208,0x03,0x00,0x00,0x00,0x00,0x00},
-	{0x03,0x0210,0x16,0x01,0x01,0x00,0x00,0x00},
-	{0x03,0x0010,0x18,0x02,0x02,0x00,0x00,0x00},
-	{0x05,0x9209,0x05,0x00,0x00,0x00,0x00,0x00},
-	{0x06,0x8209,0x06,0x00,0x00,0x00,0x00,0x00},
-	{0x07,0x0000,0x07,0x03,0x03,0x00,0x00,0x00},
-	{0x07,0x0000,0x19,0x02,0x02,0x00,0x00,0x00},
-	{0x0d,0x920a,0x0d,0x00,0x00,0x00,0x00,0x00},
-	{0x0e,0x820a,0x0e,0x00,0x00,0x00,0x00,0x00},
-	{0x0f,0x0202,0x11,0x01,0x01,0x00,0x00,0x00},
-	{0x10,0x0212,0x12,0x01,0x01,0x00,0x00,0x00},
-	{0x11,0x0212,0x1a,0x04,0x04,0x00,0x00,0x00},
-	{0x12,0x0212,0x1b,0x04,0x04,0x00,0x00,0x00},
-	{0x13,0x021b,0x1c,0x00,0x00,0x00,0x00,0x00},
-	{0x12,0x0010,0x18,0x02,0x02,0x00,0x00,0x00},
-	{0x12,0x0210,0x18,0x01,0x01,0x00,0x00,0x00},
-	{0xff,     0,   0,   0,   0,   0,   0,   0}
+	{0x01,0x9208,0x01,0x00,0x00,0x00,0x00,0x00, 0},
+	{0x01,0x1210,0x14,0x01,0x01,0x00,0x00,0x00, 0},
+	{0x01,0x1010,0x17,0x02,0x02,0x00,0x00,0x00, 0},
+	{0x03,0x8208,0x03,0x00,0x00,0x00,0x00,0x00, 0},
+	{0x03,0x0210,0x16,0x01,0x01,0x00,0x00,0x00, 0},
+	{0x03,0x0010,0x18,0x02,0x02,0x00,0x00,0x00, 0},
+	{0x05,0x9209,0x05,0x00,0x00,0x00,0x00,0x00, 0},
+	{0x06,0x8209,0x06,0x00,0x00,0x00,0x00,0x00, 0},
+	{0x07,0x0000,0x07,0x03,0x03,0x00,0x00,0x00, 0},
+	{0x07,0x0000,0x19,0x02,0x02,0x00,0x00,0x00, 0},
+	{0x0d,0x920a,0x0d,0x00,0x00,0x00,0x00,0x00, 0},
+	{0x0e,0x820a,0x0e,0x00,0x00,0x00,0x00,0x00, 0},
+	{0x0f,0x0202,0x11,0x01,0x01,0x00,0x00,0x00, 0},
+	{0x10,0x0212,0x12,0x01,0x01,0x00,0x00,0x00, 0},
+	{0x11,0x0212,0x1a,0x04,0x04,0x00,0x00,0x00, 0},
+	{0x12,0x0212,0x1b,0x04,0x04,0x00,0x00,0x00, 0},
+	{0x13,0x021b,0x1c,0x00,0x00,0x00,0x00,0x00, 0},
+	{0x12,0x0010,0x18,0x02,0x02,0x00,0x00,0x00, 0},
+	{0x12,0x0210,0x18,0x01,0x01,0x00,0x00,0x00, 0},
+	{0xff,     0,   0,   0,   0,   0,   0,   0, 0}
 };
 
 typedef struct _SiS300_ExtStruct
 {
 	UCHAR  Ext_ModeID;
 	USHORT Ext_ModeFlag;
-	USHORT Ext_ModeInfo;
+	UCHAR  Ext_ModeOffset;
 	USHORT Ext_VESAID;
 	UCHAR  Ext_RESINFO;
 	UCHAR  VB_ExtTVFlickerIndex;
 	UCHAR  VB_ExtTVEdgeIndex;
 	UCHAR  VB_ExtTVYFilterIndex;
+	UCHAR  VB_ExtTVYFilterIndexROM661;
 	UCHAR  REFindex;
 } SiS300_ExtStruct;
 
 static const SiS300_ExtStruct  SiS300_EModeIDTable[] =
 {
-	{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}
+	{0x6a,0x2212,0x04,0x0102,SIS_RI_800x600,  0x00,0x00,0x00,0x00,0x00},  /* 800x600x? */
+	{0x2e,0x0a1b,0x03,0x0101,SIS_RI_640x480,  0x00,0x00,0x00,0x00,0x08},
+	{0x2f,0x021b,0x03,0x0100,SIS_RI_640x400,  0x00,0x00,0x00,0x00,0x10},  /* 640x400x8 */
+	{0x30,0x2a1b,0x04,0x0103,SIS_RI_800x600,  0x00,0x00,0x00,0x00,0x00},
+	{0x31,0x0a1b,0x0a,0x0000,SIS_RI_720x480,  0x00,0x00,0x00,0x00,0x11},  /* 720x480x8 */
+	{0x32,0x2a1b,0x0a,0x0000,SIS_RI_720x576,  0x00,0x00,0x00,0x00,0x12},  /* 720x576x8 */
+	{0x33,0x0a1d,0x0a,0x0000,SIS_RI_720x480,  0x00,0x00,0x00,0x00,0x11},  /* 720x480x16 */
+	{0x34,0x2a1d,0x0a,0x0000,SIS_RI_720x576,  0x00,0x00,0x00,0x00,0x12},  /* 720x576x16 */
+	{0x35,0x0a1f,0x0a,0x0000,SIS_RI_720x480,  0x00,0x00,0x00,0x00,0x11},  /* 720x480x32 */
+	{0x36,0x2a1f,0x0a,0x0000,SIS_RI_720x576,  0x00,0x00,0x00,0x00,0x12},  /* 720x576x32 */
+	{0x37,0x0212,0x05,0x0104,SIS_RI_1024x768, 0x00,0x00,0x00,0x00,0x13},  /* 1024x768x? */
+	{0x38,0x0a1b,0x05,0x0105,SIS_RI_1024x768, 0x00,0x00,0x00,0x00,0x13},  /* 1024x768x8 */
+	{0x3a,0x0e3b,0x06,0x0107,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a},  /* 1280x1024x8 */
+	{0x3c,0x063b,0x07,0x0130,SIS_RI_1600x1200,0x00,0x00,0x00,0x00,0x1e},
+	{0x3d,0x067d,0x07,0x0131,SIS_RI_1600x1200,0x00,0x00,0x00,0x00,0x1e},
+	{0x40,0x921c,0x00,0x010d,SIS_RI_320x200,  0x00,0x00,0x00,0x00,0x23},  /* 320x200x15 */
+	{0x41,0x921d,0x00,0x010e,SIS_RI_320x200,  0x00,0x00,0x00,0x00,0x23},  /* 320x200x16 */
+	{0x43,0x0a1c,0x03,0x0110,SIS_RI_640x480,  0x00,0x00,0x00,0x00,0x08},
+	{0x44,0x0a1d,0x03,0x0111,SIS_RI_640x480,  0x00,0x00,0x00,0x00,0x08},
+	{0x46,0x2a1c,0x04,0x0113,SIS_RI_800x600,  0x00,0x00,0x00,0x00,0x00},  /* 800x600x15 */
+	{0x47,0x2a1d,0x04,0x0114,SIS_RI_800x600,  0x00,0x00,0x00,0x00,0x00},  /* 800x600x16 */
+	{0x49,0x0a3c,0x05,0x0116,SIS_RI_1024x768, 0x00,0x00,0x00,0x00,0x13},
+	{0x4a,0x0a3d,0x05,0x0117,SIS_RI_1024x768, 0x00,0x00,0x00,0x00,0x13},
+	{0x4c,0x0e7c,0x06,0x0119,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a},
+	{0x4d,0x0e7d,0x06,0x011a,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a},
+	{0x50,0x921b,0x00,0x0132,SIS_RI_320x240,  0x00,0x00,0x00,0x00,0x24},  /* 320x240x8  */
+	{0x51,0xb21b,0x01,0x0133,SIS_RI_400x300,  0x00,0x00,0x00,0x00,0x25},  /* 400x300x8  */
+	{0x52,0x921b,0x02,0x0134,SIS_RI_512x384,  0x00,0x00,0x00,0x00,0x26},  /* 512x384x8  */
+	{0x56,0x921d,0x00,0x0135,SIS_RI_320x240,  0x00,0x00,0x00,0x00,0x24},  /* 320x240x16 */
+	{0x57,0xb21d,0x01,0x0136,SIS_RI_400x300,  0x00,0x00,0x00,0x00,0x25},  /* 400x300x16 */
+	{0x58,0x921d,0x02,0x0137,SIS_RI_512x384,  0x00,0x00,0x00,0x00,0x26},  /* 512x384x16 */
+	{0x59,0x921b,0x00,0x0138,SIS_RI_320x200,  0x00,0x00,0x00,0x00,0x23},  /* 320x200x8  */
+	{0x5c,0x921f,0x02,0x0000,SIS_RI_512x384,  0x00,0x00,0x00,0x00,0x26},  /* 512x384x32 */
+	{0x5d,0x021d,0x03,0x0139,SIS_RI_640x400,  0x00,0x00,0x00,0x00,0x10},  /* 640x400x16 */
+ 	{0x5e,0x021f,0x03,0x0000,SIS_RI_640x400,  0x00,0x00,0x00,0x00,0x10},  /* 640x400x32 */
+	{0x62,0x0a3f,0x03,0x013a,SIS_RI_640x480,  0x00,0x00,0x00,0x00,0x08},
+	{0x63,0x2a3f,0x04,0x013b,SIS_RI_800x600,  0x00,0x00,0x00,0x00,0x00},  /* 800x600x32 */
+	{0x64,0x0a7f,0x05,0x013c,SIS_RI_1024x768, 0x00,0x00,0x00,0x00,0x13},
+	{0x65,0x0eff,0x06,0x013d,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a},
+	{0x66,0x06ff,0x07,0x013e,SIS_RI_1600x1200,0x00,0x00,0x00,0x00,0x1e},
+	{0x68,0x067b,0x08,0x013f,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x27},
+	{0x69,0x06fd,0x08,0x0140,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x27},
+	{0x6b,0x07ff,0x08,0x0000,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x27},
+	{0x6c,0x067b,0x09,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x00,0x28},  /* 2048x1536x8 - not in BIOS! */
+	{0x6d,0x06fd,0x09,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x00,0x28},  /* 2048x1536x16 - not in BIOS! */
+	{0x70,0x2a1b,0x04,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x00,0x2d},  /* 800x480x8 */
+	{0x71,0x0a1b,0x05,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x30},  /* 1024x576x8 */
+	{0x74,0x0a1d,0x05,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x30},  /* 1024x576x16 */
+	{0x75,0x0e3d,0x06,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x33},  /* 1280x720x16 */
+	{0x76,0x2a1f,0x04,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x00,0x2d},  /* 800x480x32 */
+	{0x77,0x0a3f,0x05,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x30},  /* 1024x576x32 */
+	{0x78,0x0eff,0x06,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x33},  /* 1280x720x32 */
+	{0x79,0x0e3b,0x06,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x33},  /* 1280x720x8 */
+	{0x7a,0x2a1d,0x04,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x00,0x2d},  /* 800x480x16 */
+	{0x7c,0x0a3b,0x06,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x00,0x29},  /* 1280x960x8 */
+	{0x7d,0x0a7d,0x06,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x00,0x29},  /* 1280x960x16 */
+	{0x7e,0x0aff,0x06,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x00,0x29},  /* 1280x960x32 */
+	{0x20,0x0a1b,0x05,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x00,0x2b},  /* 1024x600 */
+	{0x21,0x0a3d,0x05,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x00,0x2b},
+	{0x22,0x0a7f,0x05,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x00,0x2b},
+	{0x23,0x0a1b,0x0c,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x00,0x2c},  /* 1152x768 */
+	{0x24,0x0a3d,0x0c,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x00,0x2c},
+	{0x25,0x0a7f,0x0c,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x00,0x2c},
+	{0x29,0x0e1b,0x0c,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x36},  /* 1152x864 */
+	{0x2a,0x0e3d,0x0c,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x36},
+	{0x2b,0x0e7f,0x0c,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x36},
+	{0x39,0x2a1b,0x0d,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x00,0x38},  /* 848x480 */
+	{0x3b,0x2a3d,0x0d,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x00,0x38},
+	{0x3e,0x2a7f,0x0d,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x00,0x38},
+	{0x3f,0x2a1b,0x0d,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x00,0x3a},  /* 856x480 */
+	{0x42,0x2a3d,0x0d,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x00,0x3a},
+	{0x45,0x2a7f,0x0d,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x00,0x3a},
+	{0x48,0x223b,0x0e,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x3c},  /* 1360x768 */
+	{0x4b,0x227d,0x0e,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x3c},
+	{0x4e,0x22ff,0x0e,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x3c},
+	{0x4f,0x921f,0x00,0x0000,SIS_RI_320x200,  0x00,0x00,0x00,0x00,0x23},  /* 320x200x32 */
+	{0x53,0x921f,0x00,0x0000,SIS_RI_320x240,  0x00,0x00,0x00,0x00,0x24},  /* 320x240x32 */
+	{0x54,0xb21f,0x01,0x0000,SIS_RI_400x300,  0x00,0x00,0x00,0x00,0x25},  /* 400x300x32 */
+	{0x55,0x2e3b,0x06,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x3d},  /* 1280x768   */
+	{0x5a,0x2e7d,0x06,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x3d},
+	{0x5b,0x2eff,0x06,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x3d},
+	{0x5f,0x2a1b,0x0f,0x0000,SIS_RI_768x576,  0x00,0x00,0x00,0x00,0x3e},  /* 768x576x8 */
+	{0x60,0x2a1d,0x0f,0x0000,SIS_RI_768x576,  0x00,0x00,0x00,0x00,0x3e},  /* 768x576x16 */
+	{0x61,0x2a1f,0x0f,0x0000,SIS_RI_768x576,  0x00,0x00,0x00,0x00,0x3e},  /* 768x576x32 */
+	{0x67,0x2e3b,0x0e,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x00,0x3f},  /* 1360x1024x8 (BARCO) */
+	{0x6f,0x2e7d,0x0e,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x00,0x3f},  /* 1360x1024x16 (BARCO) */
+	{0x72,0x2eff,0x0e,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x00,0x3f},  /* 1360x1024x32 (BARCO) */
+	{0xff,0x0000,0x00,0xffff,0,               0x00,0x00,0x00,0x00,0x00}
 };
 
 typedef struct _SiS300_Ext2Struct
 {
 	USHORT Ext_InfoFlag;
-	UCHAR Ext_CRT1CRTC;  /* TW: Index in SiS300_CRT1Table */
-	UCHAR Ext_CRTVCLK;   /* TW: Index in VCLK array */
-	UCHAR Ext_CRT2CRTC;  /* TW: Index in LCD Paneltype arrays (&3f) */
+	UCHAR  Ext_CRT1CRTC;  /* Index in SiS300_CRT1Table */
+	UCHAR  Ext_CRTVCLK;   /* Index in VCLK array */
+	UCHAR  Ext_CRT2CRTC;  /* Index in LCD Paneltype arrays (&3f) */
 	UCHAR  ModeID;
 	USHORT XRes;
 	USHORT YRes;
+	UCHAR  Ext_PDC;
 } 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}, /* 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}
+{ 
+	{0x085f,0x0d,0x03,0x05,0x6a, 800, 600, 0}, /* 00 */
+	{0x0467,0x0e,0x44,0x05,0x6a, 800, 600, 0}, /* 01 */
+	{0x0067,0x0f,0x07,0x48,0x6a, 800, 600, 0}, /* 02 - CRT1CRTC was 0x4f */
+	{0x0067,0x10,0x06,0x8b,0x6a, 800, 600, 0}, /* 03 */
+	{0x0147,0x11,0x08,0x00,0x6a, 800, 600, 0}, /* 04 */
+	{0x0147,0x12,0x0c,0x00,0x6a, 800, 600, 0}, /* 05 */
+	{0x0047,0x11,0x4e,0x00,0x6a, 800, 600, 0}, /* 06 - CRT1CRTC was 0x51 */
+	{0x0047,0x11,0x13,0x00,0x6a, 800, 600, 0}, /* 07 */
+	{0xc85f,0x05,0x00,0x04,0x2e, 640, 480, 0}, /* 08 */
+	{0xc067,0x06,0x02,0x04,0x2e, 640, 480, 0}, /* 09 */
+	{0xc067,0x07,0x02,0x47,0x2e, 640, 480, 0}, /* 0a */
+	{0xc067,0x08,0x03,0x8a,0x2e, 640, 480, 0}, /* 0b */
+	{0xc047,0x09,0x05,0x00,0x2e, 640, 480, 0}, /* 0c */
+	{0xc047,0x0a,0x08,0x00,0x2e, 640, 480, 0}, /* 0d */
+	{0xc047,0x0b,0x0a,0x00,0x2e, 640, 480, 0}, /* 0e */
+	{0xc047,0x0c,0x10,0x00,0x2e, 640, 480, 0}, /* 0f */
+	{0x487f,0x04,0x00,0x00,0x2f, 640, 400, 0}, /* 10 */
+	{0xc04f,0x31,0x01,0x06,0x31, 720, 480, 0}, /* 11 */
+	{0x004f,0x32,0x03,0x06,0x32, 720, 576, 0}, /* 12 */
+	{0x0187,0x15,0x05,0x00,0x37,1024, 768, 0}, /* 13 */
+        {0xc877,0x16,0x09,0x06,0x37,1024, 768, 0}, /* 14 */
+	{0xc067,0x17,0x0b,0x49,0x37,1024, 768, 0}, /* 15 - CRT1CRTC was 0x97 */
+	{0x0267,0x18,0x0d,0x00,0x37,1024, 768, 0}, /* 16 */
+	{0x0047,0x19,0x11,0x8c,0x37,1024, 768, 0}, /* 17 - CRT1CRTC was 0x59 */
+	{0x0047,0x1a,0x52,0x00,0x37,1024, 768, 0}, /* 18 */
+	{0x0007,0x1b,0x16,0x00,0x37,1024, 768, 0}, /* 19 - CRT1CRTC was 0x5b */
+	{0x0387,0x1c,0x4d,0x00,0x3a,1280,1024, 0}, /* 1a - CRT1CRTC was 0x5c */
+	{0x0077,0x1d,0x14,0x07,0x3a,1280,1024, 0}, /* 1b */
+	{0x0047,0x1e,0x17,0x00,0x3a,1280,1024, 0}, /* 1c */
+	{0x0007,0x1f,0x98,0x00,0x3a,1280,1024, 0}, /* 1d */
+	{0x0007,0x20,0x59,0x00,0x3c,1600,1200, 0}, /* 1e - CRT1CRTC was 0x60 */
+	{0x0007,0x21,0x5a,0x00,0x3c,1600,1200, 0}, /* 1f */
+	{0x0007,0x22,0x1b,0x00,0x3c,1600,1200, 0}, /* 20 */
+	{0x0007,0x23,0x1d,0x00,0x3c,1600,1200, 0}, /* 21 - CRT1CRTC was 0x63 */
+	{0x0007,0x24,0x1e,0x00,0x3c,1600,1200, 0}, /* 22 */
+	{0x407f,0x00,0x00,0x00,0x40, 320, 200, 0}, /* 23 */
+	{0xc07f,0x01,0x00,0x04,0x50, 320, 240, 0}, /* 24 */
+	{0x0077,0x02,0x04,0x05,0x51, 400, 300, 0}, /* 25 */
+	{0xc877,0x03,0x09,0x06,0x52, 512, 384, 0}, /* 26 */  /* was c077 */
+	{0x8207,0x25,0x1f,0x00,0x68,1920,1440, 0}, /* 27 */
+	{0x0007,0x26,0x20,0x00,0x6c,2048,1536, 0}, /* 28 */
+	{0x0067,0x27,0x14,0x08,0x6e,1280, 960, 0}, /* 29 - TW: 1280x960-60 */
+	{0x0027,0x45,0x3c,0x08,0x6e,1280, 960, 0}, /* 2a - TW: 1280x960-85 */
+	{0xc077,0x33,0x09,0x06,0x20,1024, 600, 0}, /* 2b */
+	{0xc077,0x34,0x0b,0x06,0x23,1152, 768, 0}, /* 2c */	/* VCLK 0x09 */
+	{0x0057,0x35,0x27,0x08,0x70, 800, 480, 0}, /* 2d */
+	{0x0047,0x36,0x37,0x08,0x70, 800, 480, 0}, /* 2e */
+	{0x0047,0x37,0x08,0x08,0x70, 800, 480, 0}, /* 2f */
+	{0x0057,0x38,0x09,0x09,0x71,1024, 576, 0}, /* 30 */
+	{0x0047,0x39,0x38,0x09,0x71,1024, 576, 0}, /* 31 */
+	{0x0047,0x3a,0x11,0x09,0x71,1024, 576, 0}, /* 32 */
+	{0x0057,0x3b,0x39,0x0a,0x75,1280, 720, 0}, /* 33 */
+	{0x0047,0x3c,0x3a,0x0a,0x75,1280, 720, 0}, /* 34 */
+	{0x0007,0x3d,0x3b,0x0a,0x75,1280, 720, 0}, /* 35 */
+	{0x0047,0x3e,0x34,0x06,0x29,1152, 864, 0}, /* 36 1152x864-75Hz */
+	{0x0047,0x44,0x3a,0x06,0x29,1152, 864, 0}, /* 37 1152x864-85Hz */
+	{0x00c7,0x3f,0x28,0x00,0x39, 848, 480, 0}, /* 38 848x480-38Hzi */
+	{0xc067,0x40,0x3d,0x0b,0x39, 848, 480, 0}, /* 39 848x480-60Hz  */
+	{0x00c7,0x41,0x28,0x00,0x3f, 856, 480, 0}, /* 3a 856x480-38Hzi */
+	{0xc047,0x42,0x28,0x00,0x3f, 856, 480, 0}, /* 3b 856x480-60Hz  */
+	{0x0067,0x43,0x3e,0x0c,0x48,1360, 768, 0}, /* 3c 1360x768-60Hz */
+	{0x0077,0x46,0x3f,0x08,0x55,1280, 768, 0}, /* 3d 1280x768-60Hz */
+	{0x004f,0x47,0x03,0x06,0x5f, 768, 576, 0}, /* 3e 768x576 */
+	{0x0027,0x48,0x13,0x08,0x67,1360,1024, 0}, /* 3f 1360x1024-59Hz (BARCO1366 only) */
+	{0xffff,   0,   0,   0,   0,   0,   0, 0}
 };
 
 typedef struct _SiS_VBModeIDTableStruct
@@ -291,6 +313,10 @@
 	{0x30,0x00,0x00,0x01,0x07,0x00,0x08,0x0a},
 	{0x31,0x00,0x00,0x01,0x06,0x00,0x00,0x00},
 	{0x32,0x00,0x00,0x01,0x06,0x00,0x00,0x00},
+	{0x33,0x00,0x00,0x01,0x06,0x00,0x00,0x00},
+	{0x34,0x00,0x00,0x01,0x06,0x00,0x00,0x00},
+	{0x35,0x00,0x00,0x01,0x06,0x00,0x00,0x00},
+	{0x36,0x00,0x00,0x01,0x06,0x00,0x00,0x00},
 	{0x37,0x00,0x00,0x01,0x00,0x00,0x0a,0x0c},
 	{0x38,0x00,0x00,0x01,0x00,0x00,0x0a,0x0c},
 	{0x3a,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
@@ -304,21 +330,28 @@
 	{0x4a,0x00,0x00,0x01,0x00,0x00,0x0a,0x0c},
 	{0x4c,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
 	{0x4d,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
+	{0x4f,0x00,0x00,0x01,0x04,0x00,0x05,0x05},
 	{0x50,0x00,0x00,0x01,0x04,0x00,0x05,0x07},
 	{0x51,0x00,0x00,0x01,0x07,0x00,0x07,0x09},
 	{0x52,0x00,0x00,0x01,0x00,0x00,0x09,0x0b},
+	{0x53,0x00,0x00,0x01,0x04,0x00,0x05,0x07},
+	{0x54,0x00,0x00,0x01,0x07,0x00,0x07,0x09},
 	{0x56,0x00,0x00,0x01,0x04,0x00,0x05,0x07},
 	{0x57,0x00,0x00,0x01,0x07,0x00,0x07,0x09},
 	{0x58,0x00,0x00,0x01,0x00,0x00,0x09,0x0b},
 	{0x59,0x00,0x00,0x01,0x04,0x00,0x05,0x05},
-	{0x5d,0x00,0x00,0x01,0x07,0x00,0x06,0x06},
+	{0x5c,0x00,0x00,0x01,0x00,0x00,0x09,0x0b},
+	{0x5d,0x00,0x00,0x01,0x05,0x00,0x06,0x06},
+	{0x5e,0x00,0x00,0x01,0x05,0x00,0x06,0x06},
+	{0x5f,0x00,0x00,0x01,0x06,0x00,0x00,0x00},
+	{0x60,0x00,0x00,0x01,0x06,0x00,0x00,0x00},
+	{0x61,0x00,0x00,0x01,0x06,0x00,0x00,0x00},
 	{0x62,0x00,0x00,0x01,0x05,0x00,0x06,0x08},
 	{0x63,0x00,0x00,0x01,0x07,0x00,0x08,0x0a},
 	{0x64,0x00,0x00,0x01,0x00,0x00,0x0a,0x0c},
 	{0x65,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
-	{0x6e,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
-	{0x6f,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
-	{0x7b,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
+	{0x6c,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
+	{0x6d,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
 	{0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
 };
 
@@ -622,26 +655,6 @@
 	{ 0x37,0x61,0x80,100}
 };
 
-#ifdef LINUXBIOS
-typedef struct _SiS300_ECLKDataStruct
-{
-	UCHAR SR2E,SR2F,SR30;
-	USHORT CLOCK;
-} SiS300_ECLKDataStruct;
-
-static const SiS300_ECLKDataStruct  SiS300_ECLKData[] =
-{
-	{ 0x54,0x43,0x80,100},
-	{ 0x53,0x43,0x80,100},
-	{ 0x55,0x43,0x80,100},
-	{ 0x52,0x43,0x80,100},
-	{ 0x3f,0x42,0x80,100},
-	{ 0x54,0x43,0x80,100},
-	{ 0x54,0x43,0x80,100},
-	{ 0x54,0x43,0x80,100}
-};
-#endif
-
 typedef struct _SiS300_VCLKDataStruct
 {
 	UCHAR SR2B,SR2C;
@@ -722,62 +735,9 @@
 	{ 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}   
-};
-
-#if 0 /* TW: This table is in all BIOSes, but not used */
-static const SiS300_VCLKDataStruct  SiS300_VBVCLKData[] =
-{
-	{ 0x1b,0xe1, 25},
-	{ 0x4e,0xe4, 28},
-	{ 0x57,0xe4, 31},
-	{ 0xc3,0xc8, 36},
-	{ 0x42,0x47, 40},
-	{ 0x5d,0xc4, 44},
-	{ 0x52,0x47, 49},
-	{ 0x53,0x47, 50},
-	{ 0x6d,0x66, 56},
-	{ 0x5a,0x64, 65},
-	{ 0x46,0x44, 67},
-	{ 0x29,0x61, 75},
-	{ 0x6d,0x46, 75},
-	{ 0x41,0x43, 78},
-	{ 0x31,0x42, 79},
-	{ 0x46,0x25, 84},
-	{ 0x78,0x29, 86}, /* 0x10 */
-	{ 0x62,0x44, 94},
-	{ 0x2b,0x22,104},
-	{ 0x49,0x24,105},
-	{ 0x43,0x42,108},
-	{ 0x3c,0x23,109},
-	{ 0xe0,0x46,132},
-	{ 0x70,0x25,135},
-	{ 0x41,0x22,157},
-	{ 0x43,0x22,162},
-	{ 0x30,0x21,175},
-	{ 0xc1,0x24,189},
-	{ 0xde,0x26,194},
-	{ 0x70,0x07,202},
-	{ 0x3f,0x03,229},
-	{ 0x30,0x02,234},  /* 0x1f */
-	{ 0x24,0x01,265},  /* 0x20 */
-	{ 0x52,0x2a, 54},
-	{ 0x52,0x6a, 27},
-	{ 0x62,0x24, 70},
-	{ 0x62,0x64, 70},
-	{ 0xa8,0x4c, 30},
-	{ 0x20,0x26, 33},
-	{ 0x31,0xc2, 39},
-	{ 0x2e,0x48, 25},  /* 0x28 */
-	{ 0x24,0x46, 25},  /* 0x29 */
-	{ 0x26,0x64, 28},
-	{ 0x37,0x64, 40},
-	{ 0xa1,0x42,108},
-	{ 0x37,0x61,100},
-	{ 0x78,0x27,108},
+	{ 0xe2,0x46,135}, /* 0x45 */  /* 1280x1024-75, better clock for VGA2 */
 	{ 0xff,0x00,  0}
 };
-#endif
 
 static const UCHAR  SiS300_ScreenOffset[] =
 {
@@ -790,7 +750,7 @@
 static UCHAR SiS300_SR07 = 0x10;
 #endif
 
-static const UCHAR  SiS300_SR15[8][4] =
+static const DRAM4Type SiS300_SR15[8] =
 {
 	{0x01,0x09,0xa3,0x00},
 	{0x43,0x43,0x43,0x00},
@@ -824,7 +784,7 @@
 static const USHORT SiS300_VideoSenseData2 = 0x0174;
 static const USHORT SiS300_YCSenseData2 = 0x016b;
 
-static const UCHAR SiS300_CR40[5][4];
+static const DRAM4Type SiS300_CR40[5];
 
 static UCHAR SiS300_CR49[2];
 #endif
@@ -854,6 +814,7 @@
 	{{0x05,0x60}}
 };
 
+#if 0
 static const SiS300_PanelDelayTblStruct  SiS300_PanelDelayTblLVDS[] =
 {
 	{{0x05,0xaa}},
@@ -873,6 +834,11 @@
 	{{0x05,0x14}},  /* Some BIOSes: 05, 40 */
 	{{0x05,0x60}}
 };
+#endif
+
+/**************************************************************/
+/* SIS VIDEO BRIDGE ----------------------------------------- */
+/**************************************************************/
 
 typedef struct _SiS300_LCDDataStruct
 {
@@ -983,6 +949,87 @@
 	{    1,   1,1688,1066,1688,1066}
 };
 
+typedef struct _SiS300_Part2PortTblStruct
+{
+ 	UCHAR CR[12];
+} SiS300_Part2PortTblStruct;
+
+static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1024x768_1[] =
+{ /* VESA Timing */
+ {{0x21,0x12,0xbf,0xe4,0xc0,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}},
+ {{0x2c,0x12,0x9a,0xae,0x88,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}},
+ {{0x21,0x12,0xbf,0xe4,0xc0,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}},
+ {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}},
+ {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}}
+};
+
+static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1280x1024_1[] =
+{	/* TW: Temporary data, invalid */
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+};
+
+static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1400x1050_1[] =
+{	/* TW: Temporary data, invalid */
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+};
+
+static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1600x1200_1[] =
+{	/* TW: Temporary data, invalid */
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+};
+
+static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1024x768_2[] =
+{  /* Non-VESA */
+ {{0x28,0x12,0xa3,0xd0,0xaa,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
+ {{0x2c,0x12,0x9a,0xae,0x88,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
+ {{0x28,0x12,0xa3,0xd0,0xaa,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
+ {{0x2c,0x12,0x9a,0xae,0x88,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
+ {{0x28,0x13,0xe7,0x0b,0xe8,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
+ {{0x38,0x18,0x16,0x00,0x00,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
+ {{0x36,0x13,0x13,0x25,0xff,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}}
+};
+
+static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1280x1024_2[] =
+{
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+};
+
+static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1400x1050_2[] =
+{
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+};
+
+static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1600x1200_2[] =
+{	/* TW: Temporary data, invalid */
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+};
+
+static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1024x768_3[] =
+{	/* TW: Temporary data, invalid */
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+};
+
+static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1280x1024_3[] =
+{	/* TW: Temporary data, invalid */
+  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+};
+
+static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1400x1050_3[] =
+{	/* TW: Temporary data, invalid */
+  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+};
+
+static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1600x1200_3[] =
+{	/* TW: Temporary data, invalid */
+  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+};
+
+/**************************************************************/
+/* LVDS/Chrontel -------------------------------------------- */
+/**************************************************************/
+
 typedef struct _SiS300_LVDSDataStruct
 {
 	USHORT VGAHT;
@@ -1526,83 +1573,7 @@
 	{   0, 805}
 };
 
-
-typedef struct _SiS300_Part2PortTblStruct
-{
- 	UCHAR CR[12];
-} SiS300_Part2PortTblStruct;
-
-static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1024x768_1[] =
-{ /* VESA Timing */
- {{0x21,0x12,0xbf,0xe4,0xc0,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}},
- {{0x2c,0x12,0x9a,0xae,0x88,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}},
- {{0x21,0x12,0xbf,0xe4,0xc0,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
- {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}},
- {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}},
- {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}}
-};
-
-static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1280x1024_1[] =
-{	/* TW: Temporary data, invalid */
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
-};
-
-static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1400x1050_1[] =
-{	/* TW: Temporary data, invalid */
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
-};
-
-static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1600x1200_1[] =
-{	/* TW: Temporary data, invalid */
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
-};
-
-static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1024x768_2[] =
-{  /* Non-VESA */
- {{0x28,0x12,0xa3,0xd0,0xaa,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
- {{0x2c,0x12,0x9a,0xae,0x88,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
- {{0x28,0x12,0xa3,0xd0,0xaa,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
- {{0x2c,0x12,0x9a,0xae,0x88,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
- {{0x28,0x13,0xe7,0x0b,0xe8,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
- {{0x38,0x18,0x16,0x00,0x00,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
- {{0x36,0x13,0x13,0x25,0xff,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}}
-};
-
-static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1280x1024_2[] =
-{
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
-};
-
-static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1400x1050_2[] =
-{
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
-};
-
-static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1600x1200_2[] =
-{	/* TW: Temporary data, invalid */
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
-};
-
-static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1024x768_3[] =
-{	/* TW: Temporary data, invalid */
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
-};
-
-static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1280x1024_3[] =
-{	/* TW: Temporary data, invalid */
-  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
-};
-
-static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1400x1050_3[] =
-{	/* TW: Temporary data, invalid */
-  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
-};
-
-static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1600x1200_3[] =
-{	/* TW: Temporary data, invalid */
-  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
-};
+/* CRT1 CRTC for slave modes */
 
 typedef struct _SiS300_LVDSCRT1DataStruct
 {
diff -urN linux-2.4.25-pre4/drivers/video/sis/310vtbl.h linux-2.4.25-pre5/drivers/video/sis/310vtbl.h
--- linux-2.4.25-pre4/drivers/video/sis/310vtbl.h	2003-11-28 10:26:21.000000000 -0800
+++ linux-2.4.25-pre5/drivers/video/sis/310vtbl.h	2004-01-15 12:10:23.000000000 -0800
@@ -2,35 +2,54 @@
 /*
  * Register settings for SiS 315/330 series
  *
- * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
+ * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
  *
- * If distributed as part of the linux kernel, the contents of this file
- * is entirely covered by the GPL.
+ * If distributed as part of the Linux kernel, the following license terms
+ * apply:
  *
- * Otherwise, the following terms apply:
+ * * This program is free software; you can redistribute it and/or modify
+ * * it under the terms of the GNU General Public License as published by
+ * * the Free Software Foundation; either version 2 of the named License,
+ * * or any later version.
+ * *
+ * * This program is distributed in the hope that it will be useful,
+ * * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * * GNU General Public License for more details.
+ * *
+ * * You should have received a copy of the GNU General Public License
+ * * along with this program; if not, write to the Free Software
+ * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
  *
- * 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.
+ * Otherwise, the following license terms apply:
  *
- * 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.
+ * * Redistribution and use in source and binary forms, with or without
+ * * modification, are permitted provided that the following conditions
+ * * are met:
+ * * 1) Redistributions of source code must retain the above copyright
+ * *    notice, this list of conditions and the following disclaimer.
+ * * 2) Redistributions in binary form must reproduce the above copyright
+ * *    notice, this list of conditions and the following disclaimer in the
+ * *    documentation and/or other materials provided with the distribution.
+ * * 3) All advertising materials mentioning features or use of this software
+ * *    must display the following acknowledgement: "This product includes
+ * *    software developed by Thomas Winischhofer, Vienna, Austria."
+ * * 4) The name of the author may not be used to endorse or promote products
+ * *    derived from this software without specific prior written permission.
+ * *
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
  *
- * Based on code by Silicon Intergrated Systems
- *
  */
 
 typedef struct _SiS310_StStruct
@@ -43,223 +62,226 @@
 	UCHAR VB_StTVFlickerIndex;
 	UCHAR VB_StTVEdgeIndex;
 	UCHAR VB_StTVYFilterIndex;
+	UCHAR St_PDC;
 } SiS310_StStruct;
 
 static const SiS310_StStruct SiS310_SModeIDTable[]=
 {
-	{0x01,0x9208,0x01,0x00,0x00,0x00,0x01,0x00},
-	{0x01,0x1210,0x14,0x01,0x01,0x00,0x01,0x00},
-	{0x01,0x1010,0x17,0x02,0x02,0x00,0x01,0x01},
-	{0x03,0x8208,0x03,0x00,0x00,0x00,0x01,0x02},
-	{0x03,0x0210,0x16,0x01,0x01,0x00,0x01,0x02},
-	{0x03,0x0010,0x18,0x02,0x02,0x00,0x01,0x03},
-	{0x05,0x9209,0x05,0x00,0x00,0x00,0x00,0x04},
-	{0x06,0x8209,0x06,0x00,0x00,0x00,0x00,0x05},
-	{0x07,0x0000,0x07,0x03,0x03,0x00,0x01,0x03},
-	{0x07,0x0000,0x19,0x02,0x02,0x00,0x01,0x03},
-	{0x0d,0x920a,0x0d,0x00,0x00,0x00,0x00,0x04},
-	{0x0e,0x820a,0x0e,0x00,0x00,0x00,0x00,0x05},
-	{0x0f,0x0202,0x11,0x01,0x01,0x00,0x00,0x05},
-	{0x10,0x0212,0x12,0x01,0x01,0x00,0x00,0x05},
-	{0x11,0x0212,0x1a,0x04,0x04,0x00,0x00,0x05},
-	{0x12,0x0212,0x1b,0x04,0x04,0x00,0x00,0x05},
-	{0x13,0x021b,0x1c,0x00,0x00,0x00,0x00,0x04},
-	{0x12,0x0010,0x18,0x02,0x02,0x00,0x00,0x05},
-	{0x12,0x0210,0x18,0x01,0x01,0x00,0x00,0x05},
-	{0xff,0x0000,0x00,0x00,0x00,0x00,0x00,0x00}
+	{0x01,0x9208,0x01,0x00,0x00,0x00,0x01,0x00, 0x40},
+	{0x01,0x1210,0x14,0x01,0x01,0x00,0x01,0x00, 0x40},
+	{0x01,0x1010,0x17,0x02,0x02,0x00,0x01,0x01, 0x40},
+	{0x03,0x8208,0x03,0x00,0x00,0x00,0x01,0x02, 0x40},
+	{0x03,0x0210,0x16,0x01,0x01,0x00,0x01,0x02, 0x40},
+	{0x03,0x0010,0x18,0x02,0x02,0x00,0x01,0x03, 0x40},
+	{0x05,0x9209,0x05,0x00,0x00,0x00,0x00,0x04, 0x40},
+	{0x06,0x8209,0x06,0x00,0x00,0x00,0x00,0x05, 0x40},
+	{0x07,0x0000,0x07,0x03,0x03,0x00,0x01,0x03, 0x40},
+	{0x07,0x0000,0x19,0x02,0x02,0x00,0x01,0x03, 0x40},
+	{0x0d,0x920a,0x0d,0x00,0x00,0x00,0x00,0x04, 0x40},
+	{0x0e,0x820a,0x0e,0x00,0x00,0x00,0x00,0x05, 0x40},
+	{0x0f,0x0202,0x11,0x01,0x01,0x00,0x00,0x05, 0x40},
+	{0x10,0x0212,0x12,0x01,0x01,0x00,0x00,0x05, 0x40},
+	{0x11,0x0212,0x1a,0x04,0x04,0x00,0x00,0x05, 0x40},
+	{0x12,0x0212,0x1b,0x04,0x04,0x00,0x00,0x05, 0x40},
+	{0x13,0x021b,0x1c,0x00,0x00,0x00,0x00,0x04, 0x40},
+	{0x12,0x0010,0x18,0x02,0x02,0x00,0x00,0x05, 0x40},
+	{0x12,0x0210,0x18,0x01,0x01,0x00,0x00,0x05, 0x40},
+	{0xff,0x0000,0x00,0x00,0x00,0x00,0x00,0x00, 0x40}
 };
 
 typedef struct _SiS310_ExtStruct
 {
-	UCHAR Ext_ModeID;
+	UCHAR  Ext_ModeID;
 	USHORT Ext_ModeFlag;
-	USHORT Ext_ModeInfo;
+	UCHAR  Ext_ModeOffset;
 	USHORT Ext_VESAID;
-	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  VB_ExtTVYFilterIndexROM661;
+	UCHAR  REFindex;
 } SiS310_ExtStruct;
 
 static const SiS310_ExtStruct  SiS310_EModeIDTable[]=
 {
-	{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}
+	{0x6a,0x2212,0x04,0x0102,SIS_RI_800x600,  0x00,0x00,0x07,0x06,0x00}, /* 800x600x? */
+	{0x2e,0x0a1b,0x03,0x0101,SIS_RI_640x480,  0x00,0x00,0x05,0x05,0x08}, /* 640x480x8 */
+        {0x2f,0x0a1b,0x03,0x0100,SIS_RI_640x400,  0x00,0x00,0x05,0x05,0x10}, /* 640x400x8 */
+	{0x30,0x2a1b,0x04,0x0103,SIS_RI_800x600,  0x00,0x00,0x07,0x06,0x00}, /* 800x600x8 */
+        {0x31,0x0a1b,0x0a,0x0000,SIS_RI_720x480,  0x00,0x00,0x06,0x06,0x11}, /* 720x480x8 */
+	{0x32,0x0a1b,0x0a,0x0000,SIS_RI_720x576,  0x00,0x00,0x06,0x06,0x12}, /* 720x576x8 */
+	{0x33,0x0a1d,0x0a,0x0000,SIS_RI_720x480,  0x00,0x00,0x06,0x06,0x11}, /* 720x480x16 */
+	{0x34,0x2a1d,0x0a,0x0000,SIS_RI_720x576,  0x00,0x00,0x06,0x06,0x12}, /* 720x576x16 */
+	{0x35,0x0a1f,0x0a,0x0000,SIS_RI_720x480,  0x00,0x00,0x06,0x06,0x11}, /* 720x480x32 */
+	{0x36,0x2a1f,0x0a,0x0000,SIS_RI_720x576,  0x00,0x00,0x06,0x06,0x12}, /* 720x576x32 */
+	{0x37,0x0212,0x05,0x0104,SIS_RI_1024x768, 0x00,0x00,0x08,0x07,0x13}, /* 1024x768x? */
+	{0x38,0x0a1b,0x05,0x0105,SIS_RI_1024x768, 0x00,0x00,0x08,0x07,0x13}, /* 1024x768x8 */
+	{0x3a,0x0e3b,0x06,0x0107,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a}, /* 1280x1024x8 */
+	{0x3c,0x0e3b,0x07,0x0130,SIS_RI_1600x1200,0x00,0x00,0x00,0x00,0x1e}, /* 1600x1200x8 */
+	{0x3d,0x0e7d,0x07,0x0131,SIS_RI_1600x1200,0x00,0x00,0x00,0x00,0x1e}, /* 1600x1200x16 */
+	{0x40,0x9a1c,0x00,0x010d,SIS_RI_320x200,  0x00,0x00,0x04,0x04,0x25}, /* 320x200x15 */
+	{0x41,0x9a1d,0x00,0x010e,SIS_RI_320x200,  0x00,0x00,0x04,0x04,0x25}, /* 320x200x16 */
+	{0x43,0x0a1c,0x03,0x0110,SIS_RI_640x480,  0x00,0x00,0x05,0x05,0x08},
+	{0x44,0x0a1d,0x03,0x0111,SIS_RI_640x480,  0x00,0x00,0x05,0x05,0x08}, /* 640x480x16 */
+	{0x46,0x2a1c,0x04,0x0113,SIS_RI_800x600,  0x00,0x00,0x07,0x06,0x00},
+	{0x47,0x2a1d,0x04,0x0114,SIS_RI_800x600,  0x00,0x00,0x07,0x06,0x00}, /* 800x600x16 */
+	{0x49,0x0a3c,0x05,0x0116,SIS_RI_1024x768, 0x00,0x00,0x00,0x07,0x13},
+	{0x4a,0x0a3d,0x05,0x0117,SIS_RI_1024x768, 0x00,0x00,0x08,0x07,0x13}, /* 1024x768x16 */
+	{0x4c,0x0e7c,0x06,0x0119,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a},
+	{0x4d,0x0e7d,0x06,0x011a,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a}, /* 1280x1024x16 */
+	{0x50,0x9a1b,0x00,0x0132,SIS_RI_320x240,  0x00,0x00,0x04,0x04,0x26}, /* 320x240x8  */
+	{0x51,0xba1b,0x01,0x0133,SIS_RI_400x300,  0x00,0x00,0x07,0x07,0x27}, /* 400x300x8  */
+  	{0x52,0xba1b,0x02,0x0134,SIS_RI_512x384,  0x00,0x00,0x00,0x00,0x28}, /* 512x384x8  */
+	{0x56,0x9a1d,0x00,0x0135,SIS_RI_320x240,  0x00,0x00,0x04,0x04,0x26}, /* 320x240x16 */
+	{0x57,0xba1d,0x01,0x0136,SIS_RI_400x300,  0x00,0x00,0x07,0x07,0x27}, /* 400x300x16 */
+ 	{0x58,0xba1d,0x02,0x0137,SIS_RI_512x384,  0x00,0x00,0x00,0x00,0x28}, /* 512x384x16 */
+	{0x59,0x9a1b,0x00,0x0138,SIS_RI_320x200,  0x00,0x00,0x04,0x04,0x25}, /* 320x200x8  */
+	{0x5a,0x021b,0x00,0x0138,SIS_RI_320x240,  0x00,0x00,0x00,0x00,0x3f}, /* 320x240x8  fstn */
+	{0x5b,0x0a1d,0x00,0x0135,SIS_RI_320x240,  0x00,0x00,0x00,0x00,0x3f}, /* 320x240x16 fstn */
+	{0x5c,0xba1f,0x02,0x0000,SIS_RI_512x384,  0x00,0x00,0x00,0x00,0x28}, /* 512x384x32 */
+	{0x5d,0x0a1d,0x03,0x0139,SIS_RI_640x400,  0x00,0x00,0x05,0x07,0x10},
+	{0x5e,0x0a1f,0x03,0x0000,SIS_RI_640x400,  0x00,0x00,0x05,0x07,0x10}, /* 640x400x32 */
+	{0x62,0x0a3f,0x03,0x013a,SIS_RI_640x480,  0x00,0x00,0x05,0x05,0x08}, /* 640x480x32 */
+	{0x63,0x2a3f,0x04,0x013b,SIS_RI_800x600,  0x00,0x00,0x07,0x06,0x00}, /* 800x600x32 */
+	{0x64,0x0a7f,0x05,0x013c,SIS_RI_1024x768, 0x00,0x00,0x08,0x07,0x13}, /* 1024x768x32 */
+	{0x65,0x0eff,0x06,0x013d,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a}, /* 1280x1024x32 */
+	{0x66,0x0eff,0x07,0x013e,SIS_RI_1600x1200,0x00,0x00,0x00,0x00,0x1e}, /* 1600x1200x32 */
+	{0x68,0x067b,0x08,0x013f,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x29}, /* 1920x1440x8 */
+	{0x69,0x06fd,0x08,0x0140,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x29}, /* 1920x1440x16 */
+	{0x6b,0x07ff,0x08,0x0141,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x29}, /* 1920x1440x32 */
+	{0x6c,0x067b,0x09,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x00,0x2f}, /* 2048x1536x8 */
+	{0x6d,0x06fd,0x09,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x00,0x2f}, /* 2048x1536x16 */
+	{0x6e,0x07ff,0x09,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x00,0x2f}, /* 2048x1536x32 */
+	{0x70,0x2a1b,0x04,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x07,0x34}, /* 800x480x8 */
+	{0x71,0x0a1b,0x05,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x37}, /* 1024x576x8 */
+	{0x74,0x0a1d,0x05,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x37}, /* 1024x576x16 */
+	{0x75,0x0a3d,0x06,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x3a}, /* 1280x720x16 */
+	{0x76,0x2a1f,0x04,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x07,0x34}, /* 800x480x32 */
+	{0x77,0x0a1f,0x05,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x37}, /* 1024x576x32 */
+	{0x78,0x0a3f,0x06,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x3a}, /* 1280x720x32 */
+	{0x79,0x0a3b,0x06,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x3a}, /* 1280x720x8 */
+	{0x7a,0x2a1d,0x04,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x07,0x34}, /* 800x480x16 */
+	{0x7c,0x0e3b,0x06,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x00,0x3d}, /* 1280x960x8 */
+	{0x7d,0x0e7d,0x06,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x00,0x3d}, /* 1280x960x16 */
+	{0x7e,0x0eff,0x06,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x00,0x3d}, /* 1280x960x32 */
+	{0x23,0x0e3b,0x06,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x40}, /* 1280x768x8 */
+	{0x24,0x0e7d,0x06,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x40}, /* 1280x768x16 */
+	{0x25,0x0eff,0x06,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x40}, /* 1280x768x32 */
+	{0x26,0x0e3b,0x0c,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x00,0x41}, /* 1400x1050x8 */
+	{0x27,0x0e7d,0x0c,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x00,0x41}, /* 1400x1050x16 */
+	{0x28,0x0eff,0x0c,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x00,0x41}, /* 1400x1050x32*/
+	{0x29,0x0e1b,0x0d,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x43}, /* 1152x864 */
+	{0x2a,0x0e3d,0x0d,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x43},
+	{0x2b,0x0e7f,0x0d,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x43},
+	{0x39,0x2a1b,0x0b,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x00,0x45}, /* 848x480 */
+	{0x3b,0x2a3d,0x0b,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x00,0x45},
+	{0x3e,0x2a7f,0x0b,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x00,0x45},
+	{0x3f,0x2a1b,0x0b,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x00,0x47}, /* 856x480 */
+	{0x42,0x2a3d,0x0b,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x00,0x47},
+	{0x45,0x2a7f,0x0b,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x00,0x47},
+	{0x48,0x2a1b,0x0e,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x49}, /* 1360x768 */
+	{0x4b,0x2a3d,0x0e,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x49},
+	{0x4e,0x2a7f,0x0e,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x49},
+	{0x4f,0x9a1f,0x00,0x0000,SIS_RI_320x200,  0x00,0x00,0x04,0x04,0x25}, /* 320x200x32 */
+	{0x53,0x9a1f,0x00,0x0000,SIS_RI_320x240,  0x00,0x00,0x04,0x04,0x26}, /* 320x240x32 */
+	{0x54,0xba1f,0x01,0x0000,SIS_RI_400x300,  0x00,0x00,0x07,0x07,0x27}, /* 400x300x32 */
+	{0x5f,0x2a1b,0x0f,0x0000,SIS_RI_768x576,  0x00,0x00,0x06,0x06,0x4a}, /* 768x576x8 */
+	{0x60,0x2a1d,0x0f,0x0000,SIS_RI_768x576,  0x00,0x00,0x06,0x06,0x4a}, /* 768x576x16 */
+	{0x61,0x2a1f,0x0f,0x0000,SIS_RI_768x576,  0x00,0x00,0x06,0x06,0x4a}, /* 768x576x32 */
+	{0xff,0x0000,0x00,0x0000,0,               0x00,0x00,0x00,0x00,0x00}
 };
 
 typedef struct _SiS310_Ext2Struct
 {
 	USHORT Ext_InfoFlag;
-	UCHAR Ext_CRT1CRTC;
-	UCHAR Ext_CRTVCLK;
-	UCHAR Ext_CRT2CRTC;
+	UCHAR  Ext_CRT1CRTC;
+	UCHAR  Ext_CRTVCLK;
+	UCHAR  Ext_CRT2CRTC;
 	UCHAR  ModeID;
 	USHORT XRes;
 	USHORT YRes;
+	UCHAR  Ext_PDC;
 } SiS310_Ext2Struct;
 
 static const SiS310_Ext2Struct SiS310_RefIndex[]=
 {
-	{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}
+	{0x085f,0x0d,0x03,0x05,0x6a, 800, 600, 0x40}, /* 0x0 */
+	{0x0067,0x0e,0x04,0x05,0x6a, 800, 600, 0x40}, /* 0x1 */
+	{0x0067,0x0f,0x08,0x48,0x6a, 800, 600, 0x40}, /* 0x2 */
+	{0x0067,0x10,0x07,0x8b,0x6a, 800, 600, 0x40}, /* 0x3 */
+	{0x0047,0x11,0x0a,0x00,0x6a, 800, 600, 0x40}, /* 0x4 */
+	{0x0047,0x12,0x0d,0x00,0x6a, 800, 600, 0x40}, /* 0x5 */
+	{0x0047,0x13,0x13,0x00,0x6a, 800, 600, 0x20}, /* 0x6 */
+	{0x0107,0x14,0x1c,0x00,0x6a, 800, 600, 0x20}, /* 0x7 */
+	{0xc85f,0x05,0x00,0x04,0x2e, 640, 480, 0x40}, /* 0x8 */
+	{0xc067,0x06,0x02,0x04,0x2e, 640, 480, 0x40}, /* 0x9 */
+	{0xc067,0x07,0x02,0x47,0x2e, 640, 480, 0x40}, /* 0xa */
+	{0xc067,0x08,0x03,0x8a,0x2e, 640, 480, 0x40}, /* 0xb */
+	{0xc047,0x09,0x05,0x00,0x2e, 640, 480, 0x40}, /* 0xc */
+	{0xc047,0x0a,0x09,0x00,0x2e, 640, 480, 0x40}, /* 0xd */
+	{0xc047,0x0b,0x0e,0x00,0x2e, 640, 480, 0x40}, /* 0xe */
+	{0xc047,0x0c,0x15,0x00,0x2e, 640, 480, 0x40}, /* 0xf */
+	{0x487f,0x04,0x00,0x00,0x2f, 640, 400, 0x30}, /* 0x10 */
+	{0xc04f,0x3c,0x01,0x06,0x31, 720, 480, 0x30}, /* 0x11 */
+	{0x004f,0x3d,0x03,0x06,0x32, 720, 576, 0x30}, /* 0x12 */
+	{0x0087,0x15,0x06,0x00,0x37,1024, 768, 0x30}, /* 0x13 */
+	{0xc877,0x16,0x0b,0x06,0x37,1024, 768, 0x20}, /* 0x14 */
+	{0xc067,0x17,0x0f,0x49,0x37,1024, 768, 0x20}, /* 0x15 */
+	{0x0067,0x18,0x11,0x00,0x37,1024, 768, 0x20}, /* 0x16 */
+	{0x0047,0x19,0x16,0x8c,0x37,1024, 768, 0x20}, /* 0x17 */
+	{0x0107,0x1a,0x1b,0x00,0x37,1024, 768, 0x10}, /* 0x18 */
+	{0x0107,0x1b,0x1f,0x00,0x37,1024, 768, 0x10}, /* 0x19 */
+	{0x0087,0x1c,0x11,0x00,0x3a,1280,1024, 0x30}, /* 0x1a */
+	{0x0137,0x1d,0x19,0x07,0x3a,1280,1024, 0x00}, /* 0x1b */
+	{0x0107,0x1e,0x1e,0x00,0x3a,1280,1024, 0x00}, /* 0x1c */
+	{0x0207,0x1f,0x20,0x00,0x3a,1280,1024, 0x00}, /* 0x1d */
+	{0x0227,0x20,0x21,0x09,0x3c,1600,1200, 0x00}, /* 0x1e */
+	{0x0407,0x21,0x22,0x00,0x3c,1600,1200, 0x00}, /* 0x1f */
+	{0x0407,0x22,0x23,0x00,0x3c,1600,1200, 0x00}, /* 0x20 */
+	{0x0407,0x23,0x25,0x00,0x3c,1600,1200, 0x00}, /* 0x21 */
+	{0x0007,0x24,0x26,0x00,0x3c,1600,1200, 0x00}, /* 0x22 */
+	{0x0007,0x25,0x2c,0x00,0x3c,1600,1200, 0x00}, /* 0x23 */
+	{0x0007,0x26,0x34,0x00,0x3c,1600,1200, 0x00}, /* 0x24 */
+	{0x407f,0x00,0x00,0x00,0x40, 320, 200, 0x30}, /* 0x25 */
+	{0xc07f,0x01,0x00,0x04,0x50, 320, 240, 0x30}, /* 0x26 */
+	{0x007f,0x02,0x04,0x05,0x51, 400, 300, 0x30}, /* 0x27 */
+	{0xc077,0x03,0x0b,0x06,0x52, 512, 384, 0x30}, /* 0x28 */
+	{0x8007,0x27,0x27,0x00,0x68,1920,1440, 0x00}, /* 0x29 */
+	{0x4007,0x28,0x29,0x00,0x68,1920,1440, 0x00}, /* 0x2a */
+	{0x4007,0x29,0x2e,0x00,0x68,1920,1440, 0x00}, /* 0x2b */
+	{0x4007,0x2a,0x30,0x00,0x68,1920,1440, 0x00}, /* 0x2c */
+	{0x4007,0x2b,0x35,0x00,0x68,1920,1440, 0x00}, /* 0x2d */
+	{0x4005,0x2c,0x39,0x00,0x68,1920,1440, 0x00}, /* 0x2e */
+	{0x4007,0x2d,0x2b,0x00,0x6c,2048,1536, 0x00}, /* 0x2f */
+	{0x4007,0x2e,0x31,0x00,0x6c,2048,1536, 0x00}, /* 0x30 */
+	{0x4007,0x2f,0x33,0x00,0x6c,2048,1536, 0x00}, /* 0x31 */
+	{0x4007,0x30,0x37,0x00,0x6c,2048,1536, 0x00}, /* 0x32 */
+	{0x4005,0x31,0x38,0x00,0x6c,2048,1536, 0x00}, /* 0x33 */
+	{0x0057,0x32,0x40,0x08,0x70, 800, 480, 0x30}, /* 0x34 */
+	{0x0047,0x33,0x07,0x08,0x70, 800, 480, 0x30}, /* 0x35 */
+	{0x0047,0x34,0x0a,0x08,0x70, 800, 480, 0x30}, /* 0x36 */
+	{0x0057,0x35,0x0b,0x09,0x71,1024, 576, 0x30}, /* 0x37 */
+	{0x0047,0x36,0x11,0x09,0x71,1024, 576, 0x30}, /* 0x38 */
+	{0x0047,0x37,0x16,0x09,0x71,1024, 576, 0x30}, /* 0x39 */
+	{0x0117,0x38,0x19,0x0a,0x75,1280, 720, 0x30}, /* 0x3a */
+	{0x0107,0x39,0x1e,0x0a,0x75,1280, 720, 0x30}, /* 0x3b */
+	{0x0207,0x3a,0x20,0x0a,0x75,1280, 720, 0x30}, /* 0x3c */
+	{0x0127,0x3b,0x19,0x08,0x7c,1280, 960, 0x30}, /* 0x3d */
+	{0x0227,0x4c,0x59,0x08,0x7c,1280, 960, 0x20}, /* 0x3e */
+	{0xc07f,0x4e,0x00,0x06,0x5a, 320, 240, 0x30}, /* 0x3f */    /* FSTN 320x240 */
+        {0x0077,0x42,0x5b,0x08,0x23,1280, 768, 0x30}, /* 0x40 */    /* TW: 0x5b was 0x12 */
+	{0x0127,0x43,0x4d,0x08,0x26,1400,1050, 0x30}, /* 0x41 */
+	{0x0207,0x4b,0x5a,0x08,0x26,1400,1050, 0x30}, /* 0x42 Non-BIOS, new */
+	{0x0107,0x44,0x19,0x00,0x29,1152, 864, 0x30}, /* 0x43 Non-BIOS, new */
+	{0x0107,0x4a,0x1e,0x00,0x29,1152, 864, 0x30}, /* 0x44 Non-BIOS, new */
+	{0x0087,0x45,0x57,0x00,0x39, 848, 480, 0x30}, /* 0x45 848x480-38Hzi - Non-BIOS, new */
+	{0xc067,0x46,0x55,0x0b,0x39, 848, 480, 0x30}, /* 0x46 848x480-60Hz  - Non-BIOS, new */
+	{0x0087,0x47,0x57,0x00,0x3f, 856, 480, 0x30}, /* 0x47 856x480-38Hzi - Non-BIOS, new */
+	{0xc047,0x48,0x57,0x00,0x3f, 856, 480, 0x30}, /* 0x48 856x480-60Hz  - Non-BIOS, new */
+	{0x0067,0x49,0x58,0x0c,0x48,1360, 768, 0x30}, /* 0x49 1360x768-60Hz - Non-BIOS, new */
+	{0x004f,0x4d,0x03,0x06,0x5f, 768, 576, 0x30}, /* 0x4a 768x576 */
+	{0xffff,0x00,0x00,0x00,0x00,   0,   0, 0}
 };
 
 typedef struct _SiS310_CRT1TableStruct
@@ -488,31 +510,31 @@
  {{0xe6,0xae,0xae,0x8a,0xbd,0x90,0x3d,0x10,
    0x1a,0x8d,0x19,0x19,0x3e,0x2f,0x00,0x03,
    0x00}},  /* 0x43 */
- {{0xc3,0x8f,0x8f,0x87,0x9b,0x0b,0x82,0xef, /* TW: New, 1152x864-75, not in any BIOS */
+ {{0xc3,0x8f,0x8f,0x87,0x9b,0x0b,0x82,0xef, /* New, 1152x864-75, not in BIOS */
    0x60,0x83,0x5f,0x5f,0x83,0x10,0x00,0x07,
    0x01}},  /* 0x44 */
- {{0x86,0x69,0x69,0x8A,0x74,0x06,0x8C,0x15, /* TW: New, 848x480-38i, not in BIOS */
+ {{0x86,0x69,0x69,0x8A,0x74,0x06,0x8C,0x15, /* New, 848x480-38i, not in BIOS */
    0x4F,0x83,0xEF,0xEF,0x8D,0x30,0x00,0x02,
    0x00}},  /* 0x45 */
- {{0x83,0x69,0x69,0x87,0x6f,0x1d,0x03,0x3E, /* TW: New, 848x480-60, not in BIOS */
+ {{0x83,0x69,0x69,0x87,0x6f,0x1d,0x03,0x3E, /* New, 848x480-60, not in BIOS */
    0xE5,0x8d,0xDF,0xe4,0x04,0x00,0x00,0x06,
    0x00}},  /* 0x46 */
- {{0x86,0x6A,0x6A,0x8A,0x74,0x06,0x8C,0x15, /* TW: New, 856x480-38i, not in BIOS */
+ {{0x86,0x6A,0x6A,0x8A,0x74,0x06,0x8C,0x15, /* New, 856x480-38i, not in BIOS */
    0x4F,0x83,0xEF,0xEF,0x8D,0x30,0x00,0x02,
    0x00}},  /* 0x47 */
- {{0x81,0x6A,0x6A,0x85,0x70,0x00,0x0F,0x3E, /* TW: New, 856x480-60, not in BIOS */
+ {{0x81,0x6A,0x6A,0x85,0x70,0x00,0x0F,0x3E, /* New, 856x480-60, not in BIOS */
    0xEB,0x8E,0xDF,0xDF,0x10,0x00,0x00,0x02,
    0x00}},  /* 0x48 */
- {{0xdd,0xa9,0xa9,0x81,0xb4,0x97,0x26,0xfd, /* TW: New, 1360x768-60, not in BIOS */
+ {{0xdd,0xa9,0xa9,0x81,0xb4,0x97,0x26,0xfd, /* New, 1360x768-60, not in BIOS */
    0x01,0x8d,0xff,0x00,0x27,0x10,0x00,0x03,
    0x01}},  /* 0x49 */
- {{0xd9,0x8f,0x8f,0x9d,0xba,0x0a,0x8a,0xff, /* TW: New, 1152x864-84, not in any BIOS   */
+ {{0xd9,0x8f,0x8f,0x9d,0xba,0x0a,0x8a,0xff, /* New, 1152x864-84, not in any BIOS   */
    0x60,0x8b,0x5f,0x5f,0x8b,0x10,0x00,0x03,
    0x01}},  /* 0x4a */
- {{0xea,0xae,0xae,0x8e,0xba,0x82,0x40,0x10, /* TW: New, 1400x1050-75, not in any BIOS  */
+ {{0xea,0xae,0xae,0x8e,0xba,0x82,0x40,0x10, /* New, 1400x1050-75, not in any BIOS  */
    0x1b,0x87,0x19,0x1a,0x41,0x0f,0x00,0x03,
-   0x00}},  /* 0x4b */ 
- {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0xf1,0xff, /* TW: New, 1280x960-85, not in any BIOS */
+   0x00}},  /* 0x4b */
+ {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0xf1,0xff, /* New, 1280x960-85, not in any BIOS */
    0xc0,0x83,0xbf,0xbf,0xf2,0x10,0x00,0x07,
    0x01}},  /* 0x4c */
  {{0x7b,0x5f,0x63,0x9f,0x6a,0x93,0x6f,0xf0, /* 768x576 */
@@ -529,7 +551,6 @@
 	USHORT CLOCK;
 } SiS310_MCLKDataStruct;
 
-#ifdef LINUXBIOS
 static const SiS310_MCLKDataStruct SiS310_MCLKData_0_315[] =
 {
 	{ 0x3b,0x22,0x01,143},
@@ -553,7 +574,6 @@
 	{ 0x37,0x22,0x82,133},
 	{ 0x37,0x22,0x82,133}
 };
-#endif
 
 static const SiS310_MCLKDataStruct SiS310_MCLKData_0_330[] =
 {
@@ -567,19 +587,17 @@
 	{ 0x79,0x06,0x01,250}
 };
 
-#ifdef LINUXBIOS
 static const SiS310_MCLKDataStruct SiS310_MCLKData_0_660[] =  /* TODO */
 {
-	{ 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}
+	{ 0x5c,0x23,0x82,166},
+	{ 0x5c,0x23,0x82,166},
+	{ 0x37,0x21,0x82,200},
+	{ 0x37,0x22,0x82,133},
+	{ 0x29,0x21,0x82,150},
+	{ 0x5c,0x23,0x82,166},
+	{ 0x65,0x23,0x82,183},
+	{ 0x37,0x21,0x82,200}
 };
-#endif
 
 static const SiS310_MCLKDataStruct SiS310_MCLKData_1[] =
 {
@@ -593,22 +611,6 @@
 	{ 0x37,0x22,0x82,133}
 };
 
-#ifdef LINUXBIOS
-typedef struct _SiS310_ECLKDataStruct
-{
- 	UCHAR SR2E,SR2F,SR30;
- 	USHORT CLOCK;
-} SiS310_ECLKDataStruct;
-
-static const SiS310_ECLKDataStruct SiS310_ECLKData[]=
-{
-	{ 0x5c,0x23,0x01,166},
-	{ 0x5c,0x23,0x01,166},
-	{ 0x5c,0x23,0x01,166},
-	{ 0x5c,0x23,0x01,166}
-};
-#endif
-
 typedef struct _SiS310_VCLKDataStruct
 {
 	UCHAR SR2B,SR2C;
@@ -642,7 +644,7 @@
 	{ 0x62,0x44, 94}, /* 0x16 */
 	{ 0x2b,0x41,104}, /* 0x17 */
 	{ 0x3a,0x23,105}, /* 0x18 */
-	{ 0x70,0x44,108}, /* 0x19 */  /* 1400x1050 LCD */
+	{ 0x70,0x44,108}, /* 0x19 */ 
 	{ 0x3c,0x23,109}, /* 0x1a */
 	{ 0x5e,0x43,113}, /* 0x1b */
 	{ 0xbc,0x44,116}, /* 0x1c */
@@ -708,7 +710,7 @@
 	{ 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 */
-   	{ 0x70,0x29, 81}  /* 0x5b */  /* 1280x768 LCD */
+   	{ 0x70,0x29, 81}  /* 0x5b - added for 1280x768 LCD */
 };
 
 typedef struct _SiS310_VBVCLKDataStruct
@@ -749,10 +751,16 @@
 	{ 0x5e,0x43,113}, /* 0x1b */
 	{ 0xbc,0x44,116}, /* 0x1c */
 	{ 0xe0,0x46,132}, /* 0x1d */
+#if 0
 	{ 0xd4,0x28,135}, /* 0x1e */
 	{ 0xea,0x2a,139}, /* 0x1f */
 	{ 0x41,0x22,157}, /* 0x20 */
 	{ 0x70,0x24,162}, /* 0x21 */
+#endif
+	{ 0xe2,0x46,135}, /* 0x1e */  /* 1280x1024-75, better clock for VGA2 */
+	{ 0xe5,0x46,139}, /* 0x1f */  /* 1024x768-120, better clock for VGA2 */
+	{ 0x15,0x01,157}, /* 0x20 */  /* 1280x1024-85, better clock for VGA2 */
+	{ 0x70,0x09,162}, /* 0x21 */  /* 1600x1200-60, better clock for VGA2 */
 	{ 0x30,0x21,175}, /* 0x22 */
 	{ 0x4e,0x22,189}, /* 0x23 */
 	{ 0xde,0x26,194}, /* 0x24 */
@@ -808,19 +816,19 @@
 	{ 0x6a,0xc6, 37}, /* 0x56 */  /* 848x480-75 - TEMP, UNUSED */
 	{ 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 */
+	{ 0x52,0x07,149}, /* 0x59 */  /* 1280x960-85  */
+	{ 0x56,0x07,156}, /* 0x5a */  /* 1400x1050-75 */
    	{ 0x70,0x29, 81}  /* 0x5b */  /* 1280x768 LCD */
 };
 
-static const UCHAR SiS310_ScreenOffset[] = 
+static const UCHAR SiS310_ScreenOffset[] =
 {
         0x14,0x19,0x20,0x28,0x32,0x40,0x50,0x64,
 	0x78,0x80,0x2d,0x35,0x57,0x48,0x55,0x30,
 	0xff
 };
 
-static const UCHAR SiS310_SR15[8][4]={
+static const DRAM4Type SiS310_SR15[8] = {
 	{0x00,0x04,0x60,0x60},
 	{0x0f,0x0f,0x0f,0x0f},
 	{0xba,0xba,0xba,0xba},
@@ -835,7 +843,7 @@
 
 static UCHAR SiS310_SR07 = 0x18;
 
-static const UCHAR SiS310_CR40[5][4]={
+static const DRAM4Type SiS310_CR40[5] = {
 	{0x77,0x77,0x33,0x33},
 	{0x77,0x77,0x33,0x33},
 	{0x00,0x00,0x00,0x00},
@@ -865,6 +873,55 @@
 static const USHORT SiS310_YCSenseData2    = 0x016b;
 #endif
 
+typedef struct _SiS310_PanelDelayTblStruct
+{
+ 	UCHAR timer[2];
+} SiS310_PanelDelayTblStruct;
+
+static const SiS310_PanelDelayTblStruct SiS310_PanelDelayTbl[]=
+{
+        {{0x10,0x40}},
+	{{0x10,0x40}},
+	{{0x10,0x40}},
+	{{0x10,0x40}},
+	{{0x10,0x40}},
+	{{0x10,0x40}},
+	{{0x10,0x40}},
+	{{0x10,0x40}},
+	{{0x10,0x40}},
+	{{0x10,0x40}},
+	{{0x10,0x40}},
+	{{0x10,0x40}},
+	{{0x10,0x40}},
+	{{0x10,0x40}},
+	{{0x10,0x40}},
+	{{0x10,0x40}}
+};
+
+static const SiS310_PanelDelayTblStruct SiS310_PanelDelayTblLVDS[]=
+{
+	{{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}},
+	{{0x28,0xc8}}
+};
+
+/**************************************************************/
+/* SIS VIDEO BRIDGE ----------------------------------------- */
+/**************************************************************/
+
 typedef struct _SiS310_LCDDataStruct
 {
 	USHORT RVBHCMAX;
@@ -977,1390 +1034,1374 @@
 	{    1,   1,1688,1066,1688,1066}
 };
 
-
-typedef struct _SiS310_PanelDelayTblStruct
+typedef struct _SiS310_Part2PortTblStruct
 {
- 	UCHAR timer[2];
-} SiS310_PanelDelayTblStruct;
+ 	UCHAR CR[12];
+} SiS310_Part2PortTblStruct;
 
-static const SiS310_PanelDelayTblStruct SiS310_PanelDelayTbl[]=
+static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1024x768_1[] =
 {
-        {{0x10,0x40}},
-	{{0x10,0x40}},
-	{{0x10,0x40}},
-	{{0x10,0x40}},
-	{{0x10,0x40}},
-	{{0x10,0x40}},
-	{{0x10,0x40}},
-	{{0x10,0x40}},
-	{{0x10,0x40}},
-	{{0x10,0x40}},
-	{{0x10,0x40}},
-	{{0x10,0x40}},
-	{{0x10,0x40}},
-	{{0x10,0x40}},
-	{{0x10,0x40}},
-	{{0x10,0x40}}
+ {{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 SiS310_PanelDelayTblStruct SiS310_PanelDelayTblLVDS[]=
+static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1024x768_2[] =
 {
-	{{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}},
-	{{0x28,0xc8}}
+ {{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}},  /* 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}}
 };
 
-typedef struct _SiS310_LVDSDataStruct
+static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1024x768_3[] =
 {
-	USHORT VGAHT;
-	USHORT VGAVT;
-	USHORT LCDHT;
-	USHORT LCDVT;
-} SiS310_LVDSDataStruct;
+#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_LVDSDataStruct  SiS310_CHTVUPALData[]=
-{
-	{1008, 625,1008, 625},
-	{1008, 625,1008, 625},
-	{1008, 625,1008, 625},
-	{1008, 625,1008, 625},
-	{ 840, 625, 840, 625},
-	{ 960, 750, 960, 750},
-	{1400,1000,1400,1000}
+static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1280x1024_1[] =
+{ /* Acer; 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_LVDSDataStruct  SiS310_CHTVOPALData[]= 
-{
-	{1008, 625,1008, 625},
-	{1008, 625,1008, 625},
-	{1008, 625,1008, 625},
-	{1008, 625,1008, 625},
-	{ 840, 625, 840, 625},
-	{ 944, 625, 944, 625},
-        {1400, 875,1400, 875}
+static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1280x1024_2[] =
+{ /* Acer */
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
 };
 
-static const SiS310_LVDSDataStruct  SiS310_CHTVUPALMData[]=  
-{
-	{ 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}
+/*   1     2    4    5    6   1c   1d   1f   20   21   23   25   */
+static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1280x1024_3[] =
+{ /* Acer */
+ {{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_LVDSDataStruct  SiS310_CHTVOPALMData[]=  
+static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1400x1050_1[] =
 {
-	{ 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}
+ {{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_LVDSDataStruct  SiS310_CHTVUPALNData[]=  
+static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1400x1050_2[] =
 {
-	{1008, 625,1008, 625},
-	{1008, 625,1008, 625},
-	{1008, 625,1008, 625},
-	{1008, 625,1008, 625},
-	{ 840, 625, 840, 625},
-	{ 960, 750, 960, 750},
-	{1400,1000,1400,1000}
+ {{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 SiS310_LVDSDataStruct  SiS310_CHTVOPALNData[]= 
+static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1400x1050_3[] =
 {
-	{1008, 625,1008, 625},
-	{1008, 625,1008, 625},
-	{1008, 625,1008, 625},
-	{1008, 625,1008, 625},
-	{ 840, 625, 840, 625},
-	{ 944, 625, 944, 625},
-        {1400, 875,1400, 875}
-};
-
-static const SiS310_LVDSDataStruct  SiS310_CHTVSOPALData[]=   /* TW: (super overscan - no effect on 7019) */
-{
-	{1008, 625,1008, 625},
-	{1008, 625,1008, 625},
-	{1008, 625,1008, 625},
-	{1008, 625,1008, 625},
-	{ 840, 625, 840, 625},
-	{ 944, 625, 944, 625},
-        {1400, 875,1400, 875}       	
+ {{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}}
 };
 
-typedef struct _SiS310_LVDSDesStruct
-{
-	USHORT LCDHDES;
-	USHORT LCDVDES;
-} SiS310_LVDSDesStruct;
-
-static const SiS310_LVDSDesStruct  SiS310_PanelType00_1[]=  /* 800x600 */
+static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1600x1200_1[] =
 {
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0}
+ {{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_LVDSDesStruct  SiS310_PanelType01_1[]=  /* 1024x768 */
+static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1600x1200_2[] =
 {
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 805},
-	{ 0, 0},
-	{ 0, 0}
+ {{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_LVDSDesStruct  SiS310_PanelType02_1[]=  /* 1280x1024 */
+static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1600x1200_3[] =
 {
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 1065},
-	{ 0, 0},
-	{ 0, 0}
+ {{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}}
 };
 
+/* CRT1 CRTC for LCDA */
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType03_1[]= 
+typedef struct _SiS310_LCDACRT1DataStruct
 {
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0}
-};
+ 	UCHAR CR[17];
+}SiS310_LCDACRT1DataStruct;
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType04_1[]=  
+static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11024x768_1[]=
 {
-	{1343, 798},
-	{1343, 794},
-	{1343, 798},
-	{1343, 794},
-	{1343,   0},
-	{1343,   0},
-	{ 0, 805},
-	{ 0, 794},
-	{ 0,   0}
+ {{0x73,0x4f,0x4f,0x97,0x59,0x84,0xb4,0x1f,
+   0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x05,
+   0x00}},
+ {{0x73,0x4f,0x4f,0x97,0x59,0x84,0x82,0x1f,
+   0x60,0x87,0x5d,0x5d,0x83,0x10,0x00,0x05,
+   0x00}},
+ {{0x73,0x4f,0x4f,0x97,0x59,0x84,0xb4,0x1f,
+   0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x05,
+   0x00}},
+ {{0x73,0x4f,0x4f,0x97,0x59,0x84,0x82,0x1f,
+   0x60,0x87,0x5d,0x5d,0x83,0x10,0x00,0x05,
+   0x00}},
+ {{0x73,0x4f,0x4f,0x97,0x59,0x84,0x04,0x3e,
+   0xE2,0x89,0xdf,0xdf,0x05,0x00,0x00,0x05,
+   0x00}},
+ {{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}}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType05_1[]= 
+static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11024x768_1_H[]=
 {
-	{1343, 798},
-	{1343, 794},
-	{1343, 798},
-	{1343, 794},
-	{1343,   0},
-	{1343,   0},
-	{ 0, 805},
-	{ 0, 794},
-	{ 0,   0}
+ {{0x4b,0x27,0x27,0x8f,0x31,0x1c,0xb4,0x1f,
+   0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x05,
+   0x00}},
+ {{0x4b,0x27,0x27,0x8f,0x31,0x1c,0x82,0x1f,
+   0x60,0x87,0x5D,0x5D,0x83,0x10,0x00,0x05,
+   0x00}},
+ {{0x4b,0x27,0x27,0x8f,0x31,0x1c,0xb4,0x1f,
+   0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x05,
+   0x00}},
+ {{0x4b,0x27,0x27,0x8f,0x31,0x1c,0x82,0x1f,
+   0x60,0x87,0x5D,0x5D,0x83,0x10,0x00,0x05,
+   0x00}},
+ {{0x4b,0x27,0x27,0x8f,0x31,0x1c,0x04,0x3e,
+   0xE2,0x89,0xDf,0xDf,0x05,0x00,0x00,0x05,
+   0x00}},
+ {{0x55,0x31,0x31,0x99,0x3b,0x06,0x7c,0xf0,
+   0x5A,0x81,0x57,0x57,0x7D,0x00,0x00,0x01,
+   0x01}},
+ {{0x63,0x3F,0x3F,0x87,0x49,0x94,0x24,0xF5,
+   0x02,0x89,0xFF,0xFF,0x25,0x10,0x00,0x01,
+   0x01}}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType06_1[]=  
+static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11024x768_2[]=
 {
-	{1343, 798},
-	{1343, 794},
-	{1343, 798},
-	{1343, 794},
-	{1343,   0},
-	{1343,   0},
-	{ 0, 805},
-	{ 0, 794},
-	{ 0,   0}
+ {{0xa3,0x4f,0x4f,0x0f,0x6e,0x1f,0x24,0xbb,
+   0x4a,0x81,0x8f,0xdb,0xda,0x20,0x00,0x06,
+   0x00}},
+ {{0xa3,0x4f,0x4f,0x0f,0x6e,0x1f,0x24,0xbb,
+   0x31,0x88,0x5d,0xc2,0xc1,0x20,0x00,0x06,
+   0x00}},
+ {{0xa3,0x4f,0x4f,0x0f,0x6e,0x1f,0x24,0xbb,
+   0x4a,0x81,0x8f,0xdb,0xda,0x20,0x00,0x06,
+   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}}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType07_1[]= 
+static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11024x768_2_H[]=
 {
-	{1343, 798},
-	{1343, 794},
-	{1343, 798},
-	{1343, 794},
-	{1343,   0},
-	{1343,   0},
-	{ 0, 805},
-	{ 0, 794},
-	{ 0,   0}
+ {{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 }}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType08_1[]=   /* 1400x1050 */
-{
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0}
+static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11280x1024_1[]=
+{ /* Acer */
+ {{0x7e,0x4f,0x4f,0x82,0x58,0x04,0xb8,0x1f,
+   0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x06,
+   0x00}},
+ {{0x7e,0x4f,0x4f,0x82,0x58,0x04,0x86,0x1f,
+   0x5e,0x82,0x5d,0x5d,0x87,0x10,0x00,0x06,
+   0x00}},
+ {{0x7e,0x4f,0x4f,0x82,0x58,0x04,0xb8,0x1f,
+   0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x06,
+   0x00}},
+ {{0x7e,0x4f,0x4f,0x82,0x58,0x04,0x86,0x1f,
+   0x5e,0x82,0x5d,0x5d,0x87,0x10,0x00,0x06,
+   0x00}},
+ {{0x7e,0x4f,0x4f,0x82,0x58,0x04,0x08,0x3e,
+   0xe0,0x84,0xdf,0xdf,0x09,0x00,0x00,0x06,
+   0x00}},
+ {{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}},
+ {{0xce,0x9f,0x9f,0x92,0xa8,0x14,0x28,0x5a,
+   0x00,0x84,0xff,0xff,0x29,0x01,0x00,0x07,
+   0x01}}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType09_1[]=   /* 1280x768 */
-{
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0}
+static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11280x1024_1_H[]=
+{  /* Acer */
+ {{0x56,0x27,0x27,0x9a,0x31,0x1c,0xb8,0x1f,
+   0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x05,
+   0x00}},
+ {{0x56,0x27,0x27,0x9a,0x31,0x1c,0x86,0x1f,
+   0x5e,0x82,0x5d,0x5d,0x87,0x10,0x00,0x05,
+   0x00}},
+ {{0x56,0x27,0x27,0x9a,0x31,0x1c,0xb8,0x1f,
+   0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x05,
+   0x00}},
+ {{0x56,0x27,0x27,0x9a,0x31,0x1c,0x86,0x1f,
+   0x5e,0x82,0x5d,0x5d,0x87,0x10,0x00,0x05,
+   0x01}},
+ {{0x56,0x27,0x27,0x9a,0x31,0x1c,0x08,0x3e,
+   0xe0,0x84,0xdf,0xdf,0x09,0x00,0x00,0x05,
+   0x00}},
+ {{0x60,0x31,0x31,0x84,0x3a,0x86,0x80,0xf0,
+   0x58,0x8c,0x57,0x57,0x81,0x20,0x00,0x01,
+   0x01}},
+ {{0x6e,0x3f,0x3f,0x92,0x48,0x94,0x28,0xf5,
+   0x00,0x84,0xff,0xff,0x29,0x10,0x00,0x01,
+   0x01}}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType0a_1[]=  /* 1600x1200 */
-{
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0},
-	{ 0, 0}
+static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11280x1024_2[]=
+{  /* Illegal data in BIOS (Acer, Compaq) */
+ {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x06,
+   0x00}},
+ {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x06,
+   0x00}},
+ {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x06,
+   0x00}},
+ {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x06,
+   0x00}},
+ {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x72,0x88,0xdf,0xdf,0x25,0x30,0x00,0x06,
+   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}}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType0b_1[]=  /* 640x480_2 */
+static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11280x1024_2_H[]=
+{  /* Illegal data in BIOS (Acer, Compaq) */
+ {{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[]=
 {
-	{ 0, 524},
-	{ 0, 524},
-	{ 0, 524},
-	{ 0, 524},
-	{ 0, 524},
-	{ 0, 524},
-	{ 8, 524},
-	{ 0, 524}
+ {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0x9e,0x1f,
+   0x93,0x86,0x8f,0x8f,0x9f,0x30,0x00,0x05,
+   0x00}},
+ {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0x6c,0x1f,
+   0x60,0x84,0x5d,0x5d,0x6d,0x10,0x00,0x05,
+   0x00}},
+ {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0x9e,0x1f,
+   0x93,0x86,0x8f,0x8f,0x9f,0x30,0x00,0x05,
+   0x00}},
+ {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0x6c,0x1f,
+   0x60,0x84,0x5d,0x5d,0x6d,0x10,0x00,0x05,
+   0x00}},
+ {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0xee,0x1f,
+   0xe2,0x86,0xdf,0xdf,0xef,0x10,0x00,0x05,
+   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,
+   0x01}},
+ {{0xce,0xae,0xae,0x92,0xb3,0x01,0x28,0x10,
+   0x1a,0x80,0x19,0x19,0x29,0x0f,0x00,0x03,
+   0x00}}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType0c_1[]=  /* 640x480_3 */
+static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11400x1050_1_H[]=
 {
-	{ 0, 524},
-	{ 0, 524},
-	{ 0, 524},
-	{ 0, 524},
-	{ 0, 524},
-	{ 0, 524},
-	{ 8, 524},
-	{ 0, 524}
+  {{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_LVDSDesStruct  SiS310_PanelType0d_1[]=
+static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11400x1050_2[]=
 {
-	{1343, 798},
-	{1343, 794},
-	{1343, 798},
-	{1343, 794},
-	{1343,   0},
-	{1343,   0},
-	{ 0, 805},
-	{ 0, 794},
-	{ 0,   0}
+ {{0xce,0x4f,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
+   0xdb,0x8f,0x8f,0x8f,0x29,0x21,0x00,0x03,
+   0x00}},
+ {{0xce,0x4f,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
+   0xc2,0x86,0x5d,0x5d,0x29,0x01,0x00,0x03,
+   0x01}},
+ {{0xce,0x4f,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
+   0xdb,0x8f,0x8f,0x8f,0x29,0x21,0x00,0x03,
+   0x00}},
+ {{0xce,0x4f,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
+   0xc2,0x86,0x5d,0x5d,0x29,0x01,0x00,0x03,
+   0x00}},
+ {{0xce,0x4f,0x4f,0x92,0x8c,0x1a,0x28,0x9e,
+   0x03,0x87,0xdf,0xdf,0x29,0x01,0x00,0x03,
+   0x00}},
+ {{0xce,0x63,0x63,0x92,0x96,0x04,0x28,0xd4,
+   0x3f,0x83,0x57,0x57,0x29,0x01,0x00,0x07,
+   0x01}},
+ {{0xce,0x7f,0x7f,0x92,0xa4,0x12,0x28,0xd4,
+   0x93,0x87,0xff,0xff,0x29,0x21,0x00,0x07,
+   0x01}},
+ {{0xce,0x9f,0x9f,0x92,0xb4,0x02,0x28,0x5a,
+   0x13,0x87,0xff,0xff,0x29,0x29,0x00,0x03,
+   0x01}},
+ {{0xce,0xae,0xae,0x92,0xbc,0x0a,0x28,0x10,
+   0x20,0x84,0x19,0x19,0x29,0x0f,0x00,0x03,
+   0x00}}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType0e_1[]=  
+static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11400x1050_2_H[]=
 {
-	{1343, 798},
-	{1343, 794},
-	{1343, 798},
-	{1343, 794},
-	{1343,   0},
-	{1343,   0},
-	{ 0, 805},
-	{ 0, 794},
-	{ 0,   0}
+ {{0xa6,0x27,0x27,0x8a,0x64,0x92,0x28,0x9a,
+   0xdb,0x8f,0x8f,0x8f,0x29,0x21,0x00,0x06,
+   0x00}},
+ {{0xa6,0x27,0x27,0x8a,0x64,0x92,0x28,0x9a,
+   0xc2,0x86,0x5d,0x5d,0x29,0x01,0x00,0x06,
+   0x00}},
+ {{0xa6,0x27,0x27,0x8a,0x64,0x92,0x28,0x9a,
+   0xdb,0x8f,0x8f,0x8f,0x29,0x21,0x00,0x06,
+   0x00}},
+ {{0xa6,0x27,0x27,0x8a,0x64,0x92,0x28,0x9a,
+   0xc2,0x86,0x5d,0x5d,0x29,0x01,0x00,0x06,
+   0x00}},
+ {{0xa6,0x27,0x27,0x8a,0x64,0x92,0x28,0x9e,
+   0x03,0x87,0xdf,0xdf,0x29,0x01,0x00,0x06,
+   0x00}},
+ {{0x9c,0x31,0x31,0x80,0x64,0x92,0x28,0xd4,
+   0x3f,0x83,0x57,0x57,0x29,0x01,0x00,0x06,
+   0x01}},
+ {{0x8e,0x3f,0x3f,0x92,0x64,0x12,0x28,0xd4,
+   0x93,0x87,0xff,0xff,0x29,0x21,0x00,0x06,
+   0x01}},
+ {{0x7e,0x4f,0x4f,0x82,0x64,0x12,0x28,0x5a,
+   0x13,0x87,0xff,0xff,0x29,0x29,0x00,0x06,
+   0x01}},
+ {{0x76,0x56,0x56,0x9a,0x64,0x92,0x28,0x10,
+   0x20,0x84,0x19,0x19,0x29,0x0f,0x00,0x05,
+   0x00}}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType0f_1[]=  
+static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11600x1200_1[]=
 {
-	{1343, 798},
-	{1343, 794},
-	{1343, 798},
-	{1343, 794},
-	{1343,   0},
-	{1343,   0},
-	{ 0, 805},
-	{ 0, 794},
-	{ 0,   0}
+ {{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}},
+ {{0x83,0x4F,0x4F,0x87,0x51,0x09,0x8E,0x1F,
+   0x5E,0x82,0x5D,0x5D,0x8F,0x10,0x00,0x06,
+   0x00}},
+ {{0x83,0x4F,0x4F,0x87,0x51,0x09,0x10,0x3E,
+   0xE0,0x84,0xDF,0xDF,0x11,0x00,0x00,0x06,
+   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}},
+ {{0xFB,0xC7,0xC7,0x9F,0xC9,0x81,0xE0,0x10,
+   0xB0,0x84,0xAF,0xAF,0xE1,0x2F,0x00,0x07,
+   0x00}}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType00_2[]=  
+static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11600x1200_1_H[]=
 {
-	{980, 528},
-	{980, 503},
-	{980, 528},
-	{980, 503},
-	{980, 568},
-	{ 0, 628},
-	{ 0,   0},
-	{ 0,   0},
-	{ 0,   0}
+ {{0x69,0x27,0x27,0x8D,0x30,0x88,0xC0,0x1F,
+   0x90,0x84,0x8F,0x8F,0xC1,0x30,0x00,0x01,
+   0x00}},
+ {{0x69,0x27,0x27,0x8D,0x30,0x88,0x8E,0x1F,
+   0x5E,0x82,0x5D,0x5D,0x87,0x10,0x00,0x01,
+   0x00}},
+ {{0x69,0x27,0x27,0x8D,0x30,0x88,0xC0,0x1F,
+   0x90,0x84,0x8F,0x8F,0xC1,0x30,0x00,0x01,
+   0x00}},
+ {{0x69,0x27,0x27,0x8D,0x30,0x88,0x8E,0x1F,
+   0x5E,0x82,0x5D,0x5D,0x87,0x10,0x00,0x01,
+   0x00}},
+ {{0x69,0x27,0x27,0x8D,0x30,0x88,0x10,0x3E,
+   0xE0,0x84,0xDF,0xDF,0x11,0x00,0x00,0x01,
+   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}}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType01_2[]= 
+static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11600x1200_2[]=
 {
-	{1152, 622},
-	{1152, 597},
-	{1152, 622},
-	{1152, 597},
-	{1152, 662},
-	{1232, 722},
-	{ 0, 806},
-	{ 0,   0},
-	{ 0,   0}
+ {{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_LVDSDesStruct  SiS310_PanelType02_2[]= 
+static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11600x1200_2_H[]=
 {
-	{1368, 754},
-	{1368, 729},
-	{1368, 754},
-	{1368, 729},
-	{1368, 794},
-	{1448, 854},
-	{1560, 938},
-	{   0,1066},
-	{ 0,   0},
-	{ 0,   0},
-	{ 0,   0}
+ {{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_LVDSDesStruct  SiS310_PanelType03_2[]=  
+
+/**************************************************************/
+/* LVDS, CHRONTEL ------------------------------------------- */
+/**************************************************************/
+
+typedef struct _SiS310_LVDSDataStruct
 {
-	{ 0,   0},
-	{ 0,   0},
-	{ 0,   0},
-	{ 0,   0},
-	{ 0,   0},
-	{ 0,   0},
-	{ 0,   0}
+	USHORT VGAHT;
+	USHORT VGAVT;
+	USHORT LCDHT;
+	USHORT LCDVT;
+} SiS310_LVDSDataStruct;
+
+static const SiS310_LVDSDataStruct  SiS310_CHTVUPALData[]=
+{
+	{1008, 625,1008, 625},
+	{1008, 625,1008, 625},
+	{1008, 625,1008, 625},
+	{1008, 625,1008, 625},
+	{ 840, 625, 840, 625},
+	{ 960, 750, 960, 750},
+	{1400,1000,1400,1000}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType04_2[]=  
+static const SiS310_LVDSDataStruct  SiS310_CHTVOPALData[]= 
 {
-	{ 0,   0},
-	{ 0,   0},
-	{ 0,   0},
-	{ 0,   0},
-	{ 0,   0},
-	{ 0,   0},
-	{ 0,   0},
-	{ 0,   0},
-	{ 0,   0}
+	{1008, 625,1008, 625},
+	{1008, 625,1008, 625},
+	{1008, 625,1008, 625},
+	{1008, 625,1008, 625},
+	{ 840, 625, 840, 625},
+	{ 944, 625, 944, 625},
+        {1400, 875,1400, 875}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType05_2[]=  
+static const SiS310_LVDSDataStruct  SiS310_CHTVUPALMData[]=  
 {
-	{1152, 622},
-	{1152, 597},
-	{1152, 622},
-	{1152, 597},
-	{1152, 662},
-	{1232, 722},
-	{ 0, 805},
-	{ 0, 794},
-	{ 0,   0}
+	{ 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 SiS310_LVDSDesStruct  SiS310_PanelType06_2[]=  
+static const SiS310_LVDSDataStruct  SiS310_CHTVOPALMData[]=
 {
-	{1152, 622},
-	{1152, 597},
-	{1152, 622},
-	{1152, 597},
-	{1152, 662},
-	{1232, 722},
-	{ 0, 805},
-	{ 0, 794},
-	{ 0,   0}
+	{ 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 SiS310_LVDSDataStruct  SiS310_CHTVUPALNData[]=  
+{
+	{1008, 625,1008, 625},
+	{1008, 625,1008, 625},
+	{1008, 625,1008, 625},
+	{1008, 625,1008, 625},
+	{ 840, 625, 840, 625},
+	{ 960, 750, 960, 750},
+	{1400,1000,1400,1000}
+};
+
+static const SiS310_LVDSDataStruct  SiS310_CHTVOPALNData[]= 
+{
+	{1008, 625,1008, 625},
+	{1008, 625,1008, 625},
+	{1008, 625,1008, 625},
+	{1008, 625,1008, 625},
+	{ 840, 625, 840, 625},
+	{ 944, 625, 944, 625},
+        {1400, 875,1400, 875}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType07_2[]=  
+static const SiS310_LVDSDataStruct  SiS310_CHTVSOPALData[]=   /* TW: (super overscan - no effect on 7019) */
 {
-	{1152, 622},
-	{1152, 597},
-	{1152, 622},
-	{1152, 597},
-	{1152, 662},
-	{1232, 722},
-	{ 0, 805},
-	{ 0, 794},
-	{ 0,   0}
+	{1008, 625,1008, 625},
+	{1008, 625,1008, 625},
+	{1008, 625,1008, 625},
+	{1008, 625,1008, 625},
+	{ 840, 625, 840, 625},
+	{ 944, 625, 944, 625},
+        {1400, 875,1400, 875}       	
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType08_2[]=  /* 1400x1050 */
+typedef struct _SiS310_LVDSDesStruct
 {
-	{1308, 741},
-	{1308, 716},
-	{1308, 741},
-	{1308, 716},
-	{1308, 781},
-	{1388, 841},
-	{1500, 925},
-	{1628,1053},
-	{   0,1065},
-	{   0,   0},
-	{   0,   0}
-#if 0
-	{976, 527},
-	{976, 502},
-	{976, 527},
-	{976, 502},
-	{976, 567},
-	{ 0, 627},
-	{ 0, 627},
-	{ 0,   0},
-	{ 0,   0}
-#endif	
+	USHORT LCDHDES;
+	USHORT LCDVDES;
+} SiS310_LVDSDesStruct;
+
+static const SiS310_LVDSDesStruct  SiS310_PanelType00_1[]=  /* 800x600 */
+{
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType09_2[]= /* 1280x768 */
+static const SiS310_LVDSDesStruct  SiS310_PanelType01_1[]=  /* 1024x768 */
 {
-	{1083, 622},
-	{1083, 597},
-	{1083, 622},
-	{1083, 597},
-	{1083, 662},
-	{1163, 722},
-	{1286, 805},
-	{   0, 794},
-	{   0,   0}
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 805},
+	{ 0, 0},
+	{ 0, 0}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType0a_2[]=  /* 1600x1200 */
+static const SiS310_LVDSDesStruct  SiS310_PanelType02_1[]=  /* 1280x1024 */
 {
-	{1568, 850},
-	{1568, 825},
-	{1568, 850},
-	{1568, 825},
-	{1568, 890},
-	{1648, 950},
-	{1760,1034},
-	{1888,1162},
-	{1948,1175},
-	{   0,   0}
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 1065},
+	{ 0, 0},
+	{ 0, 0}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType0b_2[]=  /* 640x480_2 */
+
+static const SiS310_LVDSDesStruct  SiS310_PanelType03_1[]= 
 {
-	{1152, 622},
-	{1152, 597},
-	{1152, 622},
-	{1152, 597},
-	{1152, 662},
-	{1232, 722},
-	{ 0, 805},
-	{ 0, 794},
-	{ 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_PanelType0c_2[]=  /* 640x480_3 */
+static const SiS310_LVDSDesStruct  SiS310_PanelType04_1[]=  
 {
-	{1152, 622},
-	{1152, 597},
-	{1152, 622},
-	{1152, 597},
-	{1152, 662},
-	{1232, 722},
+	{1343, 798},
+	{1343, 794},
+	{1343, 798},
+	{1343, 794},
+	{1343,   0},
+	{1343,   0},
 	{ 0, 805},
 	{ 0, 794},
 	{ 0,   0}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType0d_2[]=  
+static const SiS310_LVDSDesStruct  SiS310_PanelType05_1[]= 
 {
-	{1152, 622},
-	{1152, 597},
-	{1152, 622},
-	{1152, 597},
-	{1152, 662},
-	{1232, 722},
+	{1343, 798},
+	{1343, 794},
+	{1343, 798},
+	{1343, 794},
+	{1343,   0},
+	{1343,   0},
 	{ 0, 805},
 	{ 0, 794},
 	{ 0,   0}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType0e_2[]= 
+static const SiS310_LVDSDesStruct  SiS310_PanelType06_1[]=  
 {
-	{1152, 622},
-	{1152, 597},
-	{1152, 622},
-	{1152, 597},
-	{1152, 662},
-	{1232, 722},
+	{1343, 798},
+	{1343, 794},
+	{1343, 798},
+	{1343, 794},
+	{1343,   0},
+	{1343,   0},
 	{ 0, 805},
 	{ 0, 794},
 	{ 0,   0}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType0f_2[] = 
+static const SiS310_LVDSDesStruct  SiS310_PanelType07_1[]= 
 {
-	{1152, 622},
-	{1152, 597},
-	{1152, 622},
-	{1152, 597},
-	{1152, 662},
-	{1232, 722},
+	{1343, 798},
+	{1343, 794},
+	{1343, 798},
+	{1343, 794},
+	{1343,   0},
+	{1343,   0},
 	{ 0, 805},
 	{ 0, 794},
 	{ 0,   0}
 };
 
-typedef struct _SiS310_Part2PortTblStruct
-{
- 	UCHAR CR[12];
-} SiS310_Part2PortTblStruct;
-
-static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1024x768_1[] =
+static const SiS310_LVDSDesStruct  SiS310_PanelType08_1[]=   /* 1400x1050 */
 {
- {{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 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}}
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0}
 };
 
-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_LVDSDesStruct  SiS310_PanelType09_1[]=   /* 1280x768 */
+{
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0}
 };
 
-static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1600x1200_1[] =
+static const SiS310_LVDSDesStruct  SiS310_PanelType0a_1[]=  /* 1600x1200 */
 {
- {{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}}
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0}
 };
 
-static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1024x768_2[] =
+static const SiS310_LVDSDesStruct  SiS310_PanelType0b_1[]=  /* 640x480_2 */
 {
- {{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}},  /* 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}}
+	{ 0, 524},
+	{ 0, 524},
+	{ 0, 524},
+	{ 0, 524},
+	{ 0, 524},
+	{ 0, 524},
+	{ 8, 524},
+	{ 0, 524}
 };
 
-static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1280x1024_2[] =
+static const SiS310_LVDSDesStruct  SiS310_PanelType0c_1[]=  /* 640x480_3 */
 {
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+	{ 0, 524},
+	{ 0, 524},
+	{ 0, 524},
+	{ 0, 524},
+	{ 0, 524},
+	{ 0, 524},
+	{ 8, 524},
+	{ 0, 524}
 };
 
-static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1400x1050_2[] =
+static const SiS310_LVDSDesStruct  SiS310_PanelType0d_1[]=
 {
- {{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}}
+	{1343, 798},
+	{1343, 794},
+	{1343, 798},
+	{1343, 794},
+	{1343,   0},
+	{1343,   0},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1600x1200_2[] =
+static const SiS310_LVDSDesStruct  SiS310_PanelType0e_1[]=  
 {
- {{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}}
+	{1343, 798},
+	{1343, 794},
+	{1343, 798},
+	{1343, 794},
+	{1343,   0},
+	{1343,   0},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-
-static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1024x768_3[] =
+static const SiS310_LVDSDesStruct  SiS310_PanelType0f_1[]=  
 {
-#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
+	{1343, 798},
+	{1343, 794},
+	{1343, 798},
+	{1343, 794},
+	{1343,   0},
+	{1343,   0},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-/*   1     2    4    5    6   1c   1d   1f   20   21   23   25   */
-static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1280x1024_3[] =
+static const SiS310_LVDSDesStruct  SiS310_PanelType00_2[]=  
 {
- {{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}}
+	{980, 528},
+	{980, 503},
+	{980, 528},
+	{980, 503},
+	{980, 568},
+	{ 0, 628},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0}
 };
 
-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_LVDSDesStruct  SiS310_PanelType01_2[]= 
+{
+	{1152, 622},
+	{1152, 597},
+	{1152, 622},
+	{1152, 597},
+	{1152, 662},
+	{1232, 722},
+	{ 0, 806},
+	{ 0,   0},
+	{ 0,   0}
 };
 
-static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1600x1200_3[] =
+static const SiS310_LVDSDesStruct  SiS310_PanelType02_2[]= 
 {
- {{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}}
+	{1368, 754},
+	{1368, 729},
+	{1368, 754},
+	{1368, 729},
+	{1368, 794},
+	{1448, 854},
+	{1560, 938},
+	{   0,1066},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0}
 };
 
-typedef struct _SiS310_LCDACRT1DataStruct
+static const SiS310_LVDSDesStruct  SiS310_PanelType03_2[]=  
 {
- 	UCHAR CR[17];
-}SiS310_LCDACRT1DataStruct;
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0}
+};
 
-static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT1800x600_1[] =
+static const SiS310_LVDSDesStruct  SiS310_PanelType04_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}}
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0}
 };
 
-static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11024x768_1[]=
+static const SiS310_LVDSDesStruct  SiS310_PanelType05_2[]=  
 {
- {{0x73,0x4f,0x4f,0x97,0x55,0x86,0xc4,0x1f,
-   0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x05,
-   0x00}},
- {{0x73,0x4f,0x4f,0x97,0x55,0x86,0x97,0x1f,
-   0x60,0x87,0x5d,0x5d,0x83,0x10,0x00,0x05,
-   0x00}},
- {{0x73,0x4f,0x4f,0x97,0x55,0x86,0xc4,0x1f,
-   0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x05,
-   0x00}},
- {{0x73,0x4f,0x4f,0x97,0x55,0x86,0x97,0x1f,
-   0x60,0x87,0x5d,0x5d,0x83,0x10,0x00,0x05,
-   0x00}},
- {{0x73,0x4f,0x4f,0x97,0x55,0x86,0x04,0x3e,
-   0xE2,0x89,0xDf,0xDf,0x05,0x00,0x00,0x05,
-   0x00}},
- {{0x87,0x63,0x63,0x8B,0x69,0x1A,0x7c,0xf0,
-   0x5A,0x8F,0x57,0x57,0x7D,0x20,0x00,0x26,
-   0x01}},
- {{0xA3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,
-   0x02,0x88,0xFf,0xFf,0x25,0x10,0x00,0x02,
-   0x01}}
+	{1152, 622},
+	{1152, 597},
+	{1152, 622},
+	{1152, 597},
+	{1152, 662},
+	{1232, 722},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11280x1024_1[]=
+static const SiS310_LVDSDesStruct  SiS310_PanelType06_2[]=  
 {
- {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0xb8,0x1f,
-   0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x06,
-   0x00}},
- {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0x86,0x1f,
-   0x5e,0x82,0x5d,0x5d,0x87,0x10,0x00,0x06,
-   0x00}},
- {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0xb8,0x1f,
-   0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x06,
-   0x00}},
- {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0x86,0x1f,
-   0x5e,0x82,0x5d,0x5d,0x87,0x10,0x00,0x06,
-   0x00}},
- {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0x08,0x3e,
-   0xe0,0x84,0xdf,0xdf,0x09,0x00,0x00,0x06,
-   0x00}},
- {{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}}
+	{1152, 622},
+	{1152, 597},
+	{1152, 622},
+	{1152, 597},
+	{1152, 662},
+	{1232, 722},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11400x1050_1[]=
+static const SiS310_LVDSDesStruct  SiS310_PanelType07_2[]=  
 {
- {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0x9e,0x1f,
-   0x93,0x86,0x8f,0x8f,0x9f,0x30,0x00,0x05,
-   0x00}},
- {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0x6c,0x1f,
-   0x60,0x84,0x5d,0x5d,0x6d,0x10,0x00,0x05,
-   0x00}},
- {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0x9e,0x1f,
-   0x93,0x86,0x8f,0x8f,0x9f,0x30,0x00,0x05,
-   0x00}},
- {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0x6c,0x1f,
-   0x60,0x84,0x5d,0x5d,0x6d,0x10,0x00,0x05,
-   0x00}},
- {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0xee,0x1f,
-   0xe2,0x86,0xdf,0xdf,0xef,0x10,0x00,0x05,
-   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,
-   0x01}},
- {{0xce,0xae,0xae,0x92,0xb3,0x01,0x28,0x10,
-   0x1a,0x80,0x19,0x19,0x29,0x0f,0x00,0x03,
-   0x00}}
-};
-
-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,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}}
+	{1152, 622},
+	{1152, 597},
+	{1152, 622},
+	{1152, 597},
+	{1152, 662},
+	{1232, 722},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT1800x600_1_H[]=
+static const SiS310_LVDSDesStruct  SiS310_PanelType08_2[]=  /* 1400x1050 */
 {
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}}
+	{1308, 741},
+	{1308, 716},
+	{1308, 741},
+	{1308, 716},
+	{1308, 781},
+	{1388, 841},
+	{1500, 925},
+	{1628,1053},
+	{   0,1065},
+	{   0,   0},
+	{   0,   0}
 };
 
-static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11024x768_1_H[]=
+static const SiS310_LVDSDesStruct  SiS310_PanelType09_2[]= /* 1280x768 */
 {
- {{0x4b,0x27,0x27,0x8f,0x2b,0x03,0xc4,0x1f,
-   0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x44,
-   0x00}},
- {{0x4b,0x27,0x27,0x8f,0x2b,0x03,0x97,0x1f,
-   0x60,0x87,0x5D,0x5D,0x83,0x01,0x00,0x44,
-   0x00}},
- {{0x4b,0x27,0x27,0x8f,0x2b,0x03,0xc4,0x1f,
-   0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x44,
-   0x00}},
- {{0x4b,0x27,0x27,0x8f,0x2b,0x03,0x97,0x1f,
-   0x60,0x87,0x5D,0x5D,0x83,0x01,0x00,0x44,
-   0x00}},
- {{0x4b,0x27,0x27,0x8f,0x32,0x1b,0x04,0x3e,
-   0xE2,0x89,0xDf,0xDf,0x05,0x00,0x00,0x45,
-   0x00}},
- {{0x55,0x31,0x31,0x99,0x46,0x1d,0x7c,0xf0,
-   0x5A,0x8F,0x57,0x57,0x7D,0x20,0x00,0x55,
-   0x01}},
- {{0x63,0x3F,0x3F,0x87,0x4a,0x93,0x24,0xf5,
-   0x02,0x88,0xFf,0xFf,0x25,0x10,0x00,0x01,
-   0x01}}
+	{1083, 622},
+	{1083, 597},
+	{1083, 622},
+	{1083, 597},
+	{1083, 662},
+	{1163, 722},
+	{1286, 805},
+	{   0, 794},
+	{   0,   0}
 };
 
-static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11280x1024_1_H[]=
+static const SiS310_LVDSDesStruct  SiS310_PanelType0a_2[]=  /* 1600x1200 */
 {
- {{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 */
-   0xbc,0x80,0xbb,0xbb,0xe5,0x00,0x00,0x06,
-   0x01}},
- {{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,
-   0xbc,0x80,0xbb,0xbb,0xe5,0x00,0x00,0x06,
-   0x01}},
- {{0x56,0x27,0x27,0x9a,0x30,0x1e,0x08,0x3e,
-   0xe0,0x84,0xdf,0xdf,0x09,0x00,0x00,0x05,
-   0x00}},
- {{0x60,0x31,0x31,0x84,0x3a,0x88,0x80,0xf0,
-   0x58,0x8c,0x57,0x57,0x81,0x20,0x00,0x01,
-   0x01}},
- {{0x6e,0x3f,0x3f,0x92,0x48,0x96,0x28,0xf5,
-   0x00,0x84,0xff,0xff,0x29,0x10,0x00,0x01,
-   0x01}}
+	{1568, 920},
+	{1568, 895},
+	{1568, 920},
+	{1568, 895},
+	{1568, 960},
+	{1648,1020},
+	{1760,1104},
+	{1888,1232},
+	{1948,1245},
+	{   0,   0}
+#if 0
+	{1568, 850},
+	{1568, 825},
+	{1568, 850},
+	{1568, 825},
+	{1568, 890},
+	{1648, 950},
+	{1760,1034},
+	{1888,1162},
+	{1948,1175},
+	{   0,   0}
+#endif
 };
 
-static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11400x1050_1_H[]=
+static const SiS310_LVDSDesStruct  SiS310_PanelType0b_2[]=  /* 640x480_2 */
 {
-  {{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}}
+	{1152, 622},
+	{1152, 597},
+	{1152, 622},
+	{1152, 597},
+	{1152, 662},
+	{1232, 722},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-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_LVDSDesStruct  SiS310_PanelType0c_2[]=  /* 640x480_3 */
+{
+	{1152, 622},
+	{1152, 597},
+	{1152, 622},
+	{1152, 597},
+	{1152, 662},
+	{1232, 722},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT1800x600_2[]=
+static const SiS310_LVDSDesStruct  SiS310_PanelType0d_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}}
+	{1152, 622},
+	{1152, 597},
+	{1152, 622},
+	{1152, 597},
+	{1152, 662},
+	{1232, 722},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11024x768_2[]=
+static const SiS310_LVDSDesStruct  SiS310_PanelType0e_2[]= 
 {
- {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x06,
-   0x00}},
- {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x06,
-   0x00}},
- {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x06,
-   0x00}},
- {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x06,
-   0x00}},
- {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x72,0x88,0xdf,0xdf,0x25,0x30,0x00,0x06,
-   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}}
+	{1152, 622},
+	{1152, 597},
+	{1152, 622},
+	{1152, 597},
+	{1152, 662},
+	{1232, 722},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11280x1024_2[]=
+static const SiS310_LVDSDesStruct  SiS310_PanelType0f_2[] = 
 {
- {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x06,
-   0x00}},
- {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x06,
-   0x00}},
- {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x06,
-   0x00}},
- {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x06,
-   0x00}},
- {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x72,0x88,0xdf,0xdf,0x25,0x30,0x00,0x06,
-   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}}
+	{1152, 622},
+	{1152, 597},
+	{1152, 622},
+	{1152, 597},
+	{1152, 662},
+	{1232, 722},
+	{ 0, 805},
+	{ 0, 794},
+	{ 0,   0}
 };
 
-static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11400x1050_2[]=
+/* CRT1 CRTC for SlaveModes and LCDA */
+
+typedef struct _SiS310_LVDSCRT1DataStruct
 {
- {{0xce,0x4f,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
-   0xdb,0x8f,0x8f,0x8f,0x29,0x21,0x00,0x03,
-   0x00}},
- {{0xce,0x4f,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
-   0xc2,0x86,0x5d,0x5d,0x29,0x01,0x00,0x03,
-   0x01}},
- {{0xce,0x4f,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
-   0xdb,0x8f,0x8f,0x8f,0x29,0x21,0x00,0x03,
-   0x00}},
- {{0xce,0x4f,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
-   0xc2,0x86,0x5d,0x5d,0x29,0x01,0x00,0x03,
-   0x00}},
- {{0xce,0x4f,0x4f,0x92,0x8c,0x1a,0x28,0x9e,
-   0x03,0x87,0xdf,0xdf,0x29,0x01,0x00,0x03,
-   0x00}},
- {{0xce,0x63,0x63,0x92,0x96,0x04,0x28,0xd4,
-   0x3f,0x83,0x57,0x57,0x29,0x01,0x00,0x07,
-   0x01}},
- {{0xce,0x7f,0x7f,0x92,0xa4,0x12,0x28,0xd4,
-   0x93,0x87,0xff,0xff,0x29,0x21,0x00,0x07,
-   0x01}},
- {{0xce,0x9f,0x9f,0x92,0xb4,0x02,0x28,0x5a,
-   0x13,0x87,0xff,0xff,0x29,0x29,0x00,0x03,
-   0x01}},
- {{0xce,0xae,0xae,0x92,0xbc,0x0a,0x28,0x10,
-   0x20,0x84,0x19,0x19,0x29,0x0f,0x00,0x03,
-   0x00}}
-};
+ 	UCHAR CR[15];
+} SiS310_LVDSCRT1DataStruct;
 
-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_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_1[] =
+{
+ {{0x6b,0x4f,0x8f,0x55,0x85,0xaa,0x1f,
+   0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
+   0x00 }},
+ {{0x6b,0x4f,0x8f,0x55,0x85,0x78,0x1f,
+   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
+   0x00 }},
+ {{0x6b,0x4f,0x8f,0x55,0x85,0xaa,0x1f,
+   0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
+   0x00 }},
+ {{0x6b,0x4f,0x8f,0x55,0x85,0x78,0x1f,
+   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
+   0x00 }},
+ {{0x6b,0x4f,0x8f,0x55,0x85,0xfa,0x1f,
+   0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
+   0x00 }},
+ {{0x7f,0x63,0x83,0x69,0x19,0x72,0xf0,
+   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
+   0x01 }}
 };
 
-static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT1800x600_2_H[]=
+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_1_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}}
+ {{0x43,0x27,0x87,0x2d,0x1d,0xaa,0x1f,
+   0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
+   0x00 }},
+ {{0x43,0x27,0x87,0x2d,0x1d,0x78,0x1f,
+   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
+   0x00 }},
+ {{0x43,0x27,0x87,0x2d,0x1d,0xfa,0x1f,
+   0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
+   0x00 }},
+ {{0x43,0x27,0x87,0x2d,0x1d,0x78,0x1f,
+   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
+   0x00 }},
+ {{0x43,0x27,0x87,0x2d,0x1d,0xfa,0x1f,
+   0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
+   0x00 }},
+ {{0x4d,0x31,0x91,0x37,0x07,0x72,0xf0,
+   0x58,0x8d,0x57,0x73,0x20,0x00,0x01,
+   0x01 }}
 };
 
-static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11024x768_2_H[]=
+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_2[]=
 {
- {{0x4f,0x27,0x27,0x93,0x39,0x01,0x24,0xbb,
-   0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x01,
+ {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
+   0xff,0x84,0x8f,0x73,0x00,0x00,0x06,
    0x00 }},
- {{0x4f,0x27,0x27,0x93,0x39,0x01,0x24,0xbb,
-   0x31,0x87,0x8d,0x5d,0x25,0x30,0x00,0x01,   /* <-- invalid data */
+ {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
+   0xe6,0x8b,0x5d,0x73,0x00,0x00,0x06,
    0x00 }},
- {{0x4f,0x27,0x27,0x93,0x39,0x01,0x24,0xbb,
-   0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x01,
+ {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
+   0xff,0x84,0x8f,0x73,0x00,0x00,0x06,
    0x00 }},
- {{0x4f,0x27,0x27,0x93,0x39,0x01,0x24,0xbb,
-   0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x01,
+ {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
+   0xe6,0x8b,0x5d,0x73,0x00,0x00,0x06,
    0x00 }},
- {{0x4f,0x27,0x27,0x93,0x39,0x01,0x24,0xbb,
-   0x72,0x88,0xdf,0xdf,0x25,0x30,0x00,0x01,
+ {{0x7f,0x4f,0x83,0x62,0x12,0x72,0xba,
+   0x27,0x8c,0xdf,0x73,0x00,0x00,0x06,
    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,
+ {{0x7f,0x63,0x83,0x69,0x19,0x72,0xf0,
+   0x58,0x8d,0x57,0x73,0x20,0x00,0x06,
    0x01 }}
 };
 
-static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11280x1024_2_H[]=
+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_2_H[] =
 {
- {{0x4f,0x27,0x27,0x93,0x39,0x81,0x24,0xbb,
-   0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x01,
+ {{0x57,0x27,0x9b,0x3a,0x0a,0x72,0x3e,
+   0xff,0x84,0x8f,0x73,0x00,0x00,0x01,
    0x00 }},
- {{0x4f,0x27,0x27,0x93,0x39,0x81,0x24,0xbb,
-   0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x01,
+ {{0x57,0x27,0x9b,0x3a,0x0a,0x72,0x3e,
+   0xd6,0x8b,0x5d,0x73,0x00,0x00,0x01,
    0x00 }},
- {{0x4f,0x27,0x27,0x93,0x39,0x81,0x24,0xbb,
-   0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x01,
+ {{0x57,0x27,0x9b,0x3a,0x0a,0x72,0x3e,
+   0xff,0x84,0x8f,0x73,0x00,0x00,0x01,
    0x00 }},
- {{0x4f,0x27,0x27,0x93,0x39,0x81,0x24,0xbb,
-   0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x01,
+ {{0x57,0x27,0x9b,0x3a,0x0a,0x72,0x3e,
+   0xd6,0x8b,0x5d,0x73,0x00,0x00,0x01,
    0x00 }},
- {{0x4f,0x27,0x27,0x93,0x39,0x81,0x24,0xbb,
-   0x72,0x88,0xdf,0xdf,0x25,0x30,0x00,0x01,
+ {{0x57,0x27,0x9b,0x3a,0x0a,0x72,0xba,
+   0x27,0x8c,0xdf,0x73,0x00,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,
+ {{0x4d,0x31,0x91,0x3a,0x0a,0x72,0xf0,
+   0x63,0x88,0x57,0x73,0x00,0x00,0x01,
    0x01 }}
 };
 
-static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11400x1050_2_H[]=
+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_1[] =
 {
- {{0xa6,0x27,0x27,0x8a,0x64,0x92,0x28,0x9a,
-   0xdb,0x8f,0x8f,0x8f,0x29,0x21,0x00,0x06,
+ {{0x73,0x4f,0x97,0x53,0x84,0xb4,0x1f,
+   0x92,0x89,0x8f,0xb5,0x30,0x00,0x05,
    0x00}},
- {{0xa6,0x27,0x27,0x8a,0x64,0x92,0x28,0x9a,
-   0xc2,0x86,0x5d,0x5d,0x29,0x01,0x00,0x06,
+ {{0x73,0x4f,0x97,0x53,0x84,0x82,0x1f,
+   0x60,0x87,0x5d,0x83,0x10,0x00,0x05,
    0x00}},
- {{0xa6,0x27,0x27,0x8a,0x64,0x92,0x28,0x9a,
-   0xdb,0x8f,0x8f,0x8f,0x29,0x21,0x00,0x06,
+ {{0x73,0x4f,0x97,0x53,0x84,0xb4,0x1f,
+   0x92,0x89,0x8f,0xb5,0x30,0x00,0x05,
    0x00}},
- {{0xa6,0x27,0x27,0x8a,0x64,0x92,0x28,0x9a,
-   0xc2,0x86,0x5d,0x5d,0x29,0x01,0x00,0x06,
+ {{0x73,0x4f,0x97,0x53,0x84,0x82,0x1f,
+   0x60,0x87,0x5d,0x83,0x10,0x00,0x05,
    0x00}},
- {{0xa6,0x27,0x27,0x8a,0x64,0x92,0x28,0x9e,
-   0x03,0x87,0xdf,0xdf,0x29,0x01,0x00,0x06,
+ {{0x73,0x4f,0x97,0x53,0x84,0x04,0x3e,
+   0xE2,0x89,0xDf,0x05,0x00,0x00,0x05,
    0x00}},
- {{0x9c,0x31,0x31,0x80,0x64,0x92,0x28,0xd4,
-   0x3f,0x83,0x57,0x57,0x29,0x01,0x00,0x06,
-   0x01}},
- {{0x8e,0x3f,0x3f,0x92,0x64,0x12,0x28,0xd4,
-   0x93,0x87,0xff,0xff,0x29,0x21,0x00,0x06,
-   0x01}},
- {{0x7e,0x4f,0x4f,0x82,0x64,0x12,0x28,0x5a,
-   0x13,0x87,0xff,0xff,0x29,0x29,0x00,0x06,
+ {{0x87,0x63,0x8B,0x67,0x18,0x7c,0xf0,
+   0x5A,0x81,0x57,0x7D,0x00,0x00,0x06,
    0x01}},
- {{0x76,0x56,0x56,0x9a,0x64,0x92,0x28,0x10,
-   0x20,0x84,0x19,0x19,0x29,0x0f,0x00,0x05,
-   0x00}}
+ {{0xA3,0x7f,0x87,0x83,0x94,0x24,0xf5,
+   0x02,0x89,0xFf,0x25,0x10,0x00,0x02,
+   0x01}}
 };
 
-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,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,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_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_1_H[] =
+{
+ {{0x4b,0x27,0x8f,0x2b,0x1c,0xb4,0x1f,
+   0x92,0x89,0x8f,0xb5,0x30,0x00,0x05,
+   0x00 }},
+ {{0x4b,0x27,0x8f,0x2b,0x1c,0x82,0x1f,
+   0x60,0x87,0x5D,0x83,0x01,0x00,0x05,
    0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ {{0x4b,0x27,0x8f,0x2b,0x1c,0xb4,0x1f,
+   0x92,0x89,0x8f,0xb5,0x30,0x00,0x05,
    0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ {{0x4b,0x27,0x8f,0x2b,0x1c,0x82,0x1f,
+   0x60,0x87,0x5D,0x83,0x01,0x00,0x05,
    0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ {{0x4b,0x27,0x8f,0x2b,0x1c,0x04,0x3e,
+   0xE2,0x89,0xDf,0x05,0x00,0x00,0x05,
    0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}}
+ {{0x55,0x31,0x99,0x35,0x06,0x7c,0xf0,
+   0x5A,0x81,0x57,0x7D,0x00,0x00,0x01,
+   0x01}},
+ {{0x63,0x3F,0x87,0x43,0x94,0x24,0xf5,
+   0x02,0x89,0xFf,0x25,0x10,0x00,0x01,
+   0x01 }}
 };
 
-typedef struct _SiS310_LVDSCRT1DataStruct
+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_2[] =
 {
- 	UCHAR CR[15];
-} SiS310_LVDSCRT1DataStruct;
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x57,0x8e,0x8f,0x25,0x30,0x00,0x06,
+   0x00 }},
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x3e,0x85,0x5d,0x25,0x10,0x00,0x06,
+   0x00 }},
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x57,0x8e,0x8f,0x25,0x30,0x00,0x06,
+   0x00 }},
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x3e,0x85,0x5d,0x25,0x10,0x00,0x06,
+   0x01 }},
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x7f,0x86,0xdf,0x25,0x10,0x00,0x06,
+   0x00 }},
+ {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
+   0xbb,0x82,0x57,0x25,0x10,0x00,0x02,
+   0x01 }},
+ {{0xa3,0x7f,0x87,0x83,0x94,0x24,0xf5,
+   0x02,0x89,0xff,0x25,0x10,0x00,0x02,
+   0x01 }}
+};
 
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_1[] =
+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_2_H[] =
 {
- {{0x6b,0x4f,0x8f,0x55,0x85,0xaa,0x1f,
-   0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
+ {{0x7b,0x27,0x9f,0x46,0x97,0x24,0xbb,
+   0x57,0x8e,0x8f,0x25,0x30,0x00,0x01,
    0x00 }},
- {{0x6b,0x4f,0x8f,0x55,0x85,0x78,0x1f,
-   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
+ {{0x7b,0x27,0x9f,0x46,0x97,0x24,0xbb,
+   0x3e,0x85,0x5d,0x25,0x10,0x00,0x01,
    0x00 }},
- {{0x6b,0x4f,0x8f,0x55,0x85,0xaa,0x1f,
-   0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
+ {{0x7b,0x27,0x9f,0x46,0x97,0x24,0xbb,
+   0x57,0x8e,0x8f,0x25,0x30,0x00,0x01,
    0x00 }},
- {{0x6b,0x4f,0x8f,0x55,0x85,0x78,0x1f,
-   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
+ {{0x7b,0x27,0x9f,0x46,0x97,0x24,0xbb,
+   0x3e,0x85,0x5d,0x25,0x10,0x00,0x01,
    0x00 }},
- {{0x6b,0x4f,0x8f,0x55,0x85,0xfa,0x1f,
-   0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
+ {{0x7b,0x27,0x9f,0x46,0x97,0x24,0xbb,
+   0x7f,0x86,0xdf,0x25,0x10,0x00,0x01,
    0x00 }},
- {{0x7f,0x63,0x83,0x69,0x19,0x72,0xf0,
-   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
+ {{0x71,0x31,0x95,0x46,0x97,0x24,0xf1,
+   0xbb,0x82,0x57,0x25,0x10,0x00,0x01,
+   0x01 }},
+ {{0x63,0x3f,0x87,0x46,0x97,0x24,0xf5,
+   0x0f,0x86,0xff,0x25,0x30,0x00,0x01,
    0x01 }}
 };
 
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_1[] =    
-{
- {{0x73,0x4f,0x97,0x53,0x84,0xb4,0x1f,
-   0x92,0x89,0x8f,0xb5,0x30,0x00,0x05,
-   0x00}},
- {{0x73,0x4f,0x97,0x53,0x84,0x82,0x1f,
-   0x60,0x87,0x5d,0x83,0x10,0x00,0x05,
-   0x00}},
- {{0x73,0x4f,0x97,0x53,0x84,0xb4,0x1f,
-   0x92,0x89,0x8f,0xb5,0x30,0x00,0x05,
-   0x00}},
- {{0x73,0x4f,0x97,0x53,0x84,0x82,0x1f,
-   0x60,0x87,0x5d,0x83,0x10,0x00,0x05,
-   0x00}},
- {{0x73,0x4f,0x97,0x53,0x84,0x04,0x3e,
-   0xE2,0x89,0xDf,0x05,0x00,0x00,0x05,
-   0x00}},
- {{0x87,0x63,0x8B,0x67,0x18,0x7c,0xf0,
-   0x5A,0x81,0x57,0x7D,0x00,0x00,0x06,
-   0x01}},
- {{0xA3,0x7f,0x87,0x83,0x94,0x24,0xf5,
-   0x02,0x89,0xFf,0x25,0x10,0x00,0x02,
-   0x01}}
-};
-
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x1024_1[] =   
+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x1024_1[] =
 {
  {{0x7e,0x4f,0x82,0x58,0x04,0xb8,0x1f,
    0x90,0x84,0x8f,0xb9,0x30,0x00,0x06,
@@ -2388,53 +2429,6 @@
    0x01}}
 };
 
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_1_H[] =   
-{
- {{0x43,0x27,0x87,0x2d,0x1d,0xaa,0x1f,
-   0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
-   0x00 }},
- {{0x43,0x27,0x87,0x2d,0x1d,0x78,0x1f,
-   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
-   0x00 }},
- {{0x43,0x27,0x87,0x2d,0x1d,0xfa,0x1f,
-   0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
-   0x00 }},
- {{0x43,0x27,0x87,0x2d,0x1d,0x78,0x1f,
-   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
-   0x00 }},
- {{0x43,0x27,0x87,0x2d,0x1d,0xfa,0x1f,
-   0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
-   0x00 }},
- {{0x4d,0x31,0x91,0x37,0x07,0x72,0xf0,
-   0x58,0x8d,0x57,0x73,0x20,0x00,0x01,
-   0x01 }}
-};
-
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_1_H[] = 
-{
- {{0x4b,0x27,0x8f,0x2b,0x1c,0xb4,0x1f,
-   0x92,0x89,0x8f,0xb5,0x30,0x00,0x05,
-   0x00 }},
- {{0x4b,0x27,0x8f,0x2b,0x1c,0x82,0x1f,
-   0x60,0x87,0x5D,0x83,0x01,0x00,0x05,
-   0x00}},
- {{0x4b,0x27,0x8f,0x2b,0x1c,0xb4,0x1f,
-   0x92,0x89,0x8f,0xb5,0x30,0x00,0x05,
-   0x00}},
- {{0x4b,0x27,0x8f,0x2b,0x1c,0x82,0x1f,
-   0x60,0x87,0x5D,0x83,0x01,0x00,0x05,
-   0x00}},
- {{0x4b,0x27,0x8f,0x2b,0x1c,0x04,0x3e,
-   0xE2,0x89,0xDf,0x05,0x00,0x00,0x05,
-   0x00}},
- {{0x55,0x31,0x99,0x35,0x06,0x7c,0xf0,
-   0x5A,0x81,0x57,0x7D,0x00,0x00,0x01,
-   0x01}},
- {{0x63,0x3F,0x87,0x43,0x94,0x24,0xf5,
-   0x02,0x89,0xFf,0x25,0x10,0x00,0x01,
-   0x01 }}
-};
-
 static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x1024_1_H[] =  
 {
  {{0x56,0x27,0x9a,0x31,0x1c,0xb8,0x1f,
@@ -2460,53 +2454,6 @@
    0x01}}
 };
 
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_2[]=  
-{
- {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
-   0xff,0x84,0x8f,0x73,0x00,0x00,0x06,
-   0x00 }},
- {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
-   0xe6,0x8b,0x5d,0x73,0x00,0x00,0x06,
-   0x00 }},
- {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
-   0xff,0x84,0x8f,0x73,0x00,0x00,0x06,
-   0x00 }},
- {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
-   0xe6,0x8b,0x5d,0x73,0x00,0x00,0x06,
-   0x00 }},
- {{0x7f,0x4f,0x83,0x62,0x12,0x72,0xba,
-   0x27,0x8c,0xdf,0x73,0x00,0x00,0x06,
-   0x00 }},
- {{0x7f,0x63,0x83,0x69,0x19,0x72,0xf0,
-   0x58,0x8d,0x57,0x73,0x20,0x00,0x06,
-   0x01 }}
-};
-
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_2[] = 
-{ 
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x57,0x8e,0x8f,0x25,0x30,0x00,0x06,
-   0x00 }},
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x3e,0x85,0x5d,0x25,0x10,0x00,0x06,
-   0x00 }},
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x57,0x8e,0x8f,0x25,0x30,0x00,0x06,
-   0x00 }},
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x3e,0x85,0x5d,0x25,0x10,0x00,0x06,
-   0x01 }},
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x7f,0x86,0xdf,0x25,0x10,0x00,0x06,
-   0x00 }},
- {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
-   0xbb,0x82,0x57,0x25,0x10,0x00,0x02,
-   0x01 }},
- {{0xa3,0x7f,0x87,0x83,0x94,0x24,0xf5,
-   0x02,0x89,0xff,0x25,0x10,0x00,0x02,
-   0x01 }}
-};
-
 static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x1024_2[] =  
 {
  {{0xce,0x72,0x91,0x81,0x8f,0x28,0x92,
@@ -2535,53 +2482,6 @@
    0x01}}
 };
 
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_2_H[] =  
-{
- {{0x57,0x27,0x9b,0x3a,0x0a,0x72,0x3e,
-   0xff,0x84,0x8f,0x73,0x00,0x00,0x01,
-   0x00 }},
- {{0x57,0x27,0x9b,0x3a,0x0a,0x72,0x3e,
-   0xd6,0x8b,0x5d,0x73,0x00,0x00,0x01,
-   0x00 }},
- {{0x57,0x27,0x9b,0x3a,0x0a,0x72,0x3e,
-   0xff,0x84,0x8f,0x73,0x00,0x00,0x01,
-   0x00 }},
- {{0x57,0x27,0x9b,0x3a,0x0a,0x72,0x3e,
-   0xd6,0x8b,0x5d,0x73,0x00,0x00,0x01,
-   0x00 }},
- {{0x57,0x27,0x9b,0x3a,0x0a,0x72,0xba,
-   0x27,0x8c,0xdf,0x73,0x00,0x00,0x01,
-   0x00 }},
- {{0x4d,0x31,0x91,0x3a,0x0a,0x72,0xf0,
-   0x63,0x88,0x57,0x73,0x00,0x00,0x01,
-   0x01 }}
-};
-
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_2_H[] =  
-{ 
- {{0x7b,0x27,0x9f,0x46,0x97,0x24,0xbb,
-   0x57,0x8e,0x8f,0x25,0x30,0x00,0x01,
-   0x00 }},
- {{0x7b,0x27,0x9f,0x46,0x97,0x24,0xbb,
-   0x3e,0x85,0x5d,0x25,0x10,0x00,0x01,
-   0x00 }},
- {{0x7b,0x27,0x9f,0x46,0x97,0x24,0xbb,
-   0x57,0x8e,0x8f,0x25,0x30,0x00,0x01,
-   0x00 }},
- {{0x7b,0x27,0x9f,0x46,0x97,0x24,0xbb,
-   0x3e,0x85,0x5d,0x25,0x10,0x00,0x01,
-   0x00 }},
- {{0x7b,0x27,0x9f,0x46,0x97,0x24,0xbb,
-   0x7f,0x86,0xdf,0x25,0x10,0x00,0x01,
-   0x00 }},
- {{0x71,0x31,0x95,0x46,0x97,0x24,0xf1,
-   0xbb,0x82,0x57,0x25,0x10,0x00,0x01,
-   0x01 }},
- {{0x63,0x3f,0x87,0x46,0x97,0x24,0xf5,
-   0x0f,0x86,0xff,0x25,0x30,0x00,0x01,
-   0x01 }}
-};
-
 static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x1024_2_H[] = 
 {
  {{0xa6,0x4a,0x89,0x59,0x07,0x28,0x92,
@@ -2849,6 +2749,37 @@
 
 static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11600x1200_1[] =
 {
+ {{0x83,0x4F,0x87,0x5B,0x13,0x06,0x3E,
+   0xB3,0x86,0x8F,0x07,0x20,0x00,0x06,
+   0x00}},
+ {{0x83,0x4F,0x87,0x5B,0x13,0xD4,0x1F,
+   0x81,0x84,0x5D,0xD5,0x10,0x00,0x06,
+   0x00}},
+ {{0x83,0x4F,0x87,0x5B,0x13,0x06,0x3E,
+   0xB3,0x86,0x8F,0x07,0x20,0x00,0x06,
+   0x00}},
+ {{0x83,0x4F,0x87,0x5B,0x13,0xD4,0x1F,
+   0x81,0x84,0x5D,0xD5,0x10,0x00,0x06,
+   0x00}},
+ {{0x83,0x4F,0x87,0x5B,0x13,0x56,0xBA,
+   0x03,0x86,0xDF,0x57,0x00,0x00,0x06,
+   0x00}},
+ {{0x97,0x63,0x9B,0x6F,0x07,0xCE,0xF0,
+   0x7B,0x8E,0x57,0xCF,0x20,0x00,0x02,
+   0x01}},
+ {{0xB3,0x7F,0x97,0x8B,0x83,0x76,0xF5,
+   0x23,0x86,0xFF,0x77,0x10,0x00,0x06,
+   0x01}},
+ {{0xD3,0x9F,0x97,0xAB,0x03,0x76,0x5A,
+   0x23,0x86,0xFF,0x77,0x09,0x00,0x03,
+   0x01}},
+ {{0xE2,0xAE,0x86,0xBA,0x92,0x90,0x10,
+   0x3D,0x80,0x19,0x91,0x0F,0x00,0x03,
+   0x00}},
+ {{0xFB,0xC7,0x9F,0xD3,0x8B,0x26,0x11,
+   0xD3,0x86,0xAF,0x27,0x3F,0x00,0x07,
+   0x00}}
+#if 0
  {{0x83,0x4f,0x87,0x51,0x09,0xc0,0x1f,
    0x90,0x84,0x8f,0xc1,0x30,0x00,0x06,
    0x00}},
@@ -2879,10 +2810,42 @@
  {{0xfb,0xc7,0x9f,0xc9,0x81,0xe0,0x10,
    0xb0,0x84,0xaf,0xe1,0x2f,0x00,0x07,
    0x00}}
+#endif
 };
 
 static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11600x1200_1_H[] =
-{ 
+{
+ {{0x5B,0x27,0x9F,0x33,0x0B,0x06,0x2E,
+   0xB3,0x86,0x8F,0x07,0x20,0x00,0x01,
+   0x00}},
+ {{0x5B,0x27,0x9F,0x29,0x01,0x8E,0x1F,
+   0x81,0x84,0x5D,0xD5,0x10,0x00,0x06,
+   0x00}},
+ {{0x5B,0x27,0x9F,0x33,0x0B,0x06,0x2E,
+   0xB3,0x86,0x8F,0x07,0x20,0x00,0x01,
+   0x00}},
+ {{0x83,0x4F,0x87,0x5B,0x13,0xD4,0x1F,
+   0x81,0x84,0x5D,0xD5,0x10,0x00,0x06,
+   0x00}},
+ {{0x5B,0x27,0x9F,0x33,0x0B,0x56,0xBA,
+   0x03,0x86,0xDF,0x57,0x00,0x00,0x01,
+   0x00}},
+ {{0x65,0x31,0x89,0x3D,0x95,0xCE,0xF0,
+   0x7B,0x8E,0x57,0xCF,0x20,0x00,0x01,
+   0x01}},
+ {{0x73,0x3F,0x97,0x4B,0x83,0x76,0xF5,
+   0x23,0x86,0xFF,0x77,0x10,0x00,0x05,
+   0x01}},
+ {{0xD3,0x9F,0x97,0xAB,0x03,0x76,0x5A,
+   0x23,0x86,0xFF,0x77,0x09,0x00,0x03,
+   0x01}},
+ {{0xE2,0xAE,0x86,0xBA,0x92,0x90,0x10,
+   0x3D,0x80,0x19,0x91,0x0F,0x00,0x03,
+   0x00}},
+ {{0x97,0x63,0x9B,0x6F,0x07,0xE0,0x10,
+   0xB0,0x84,0xAF,0xE1,0x2F,0x00,0x06,
+   0x00}}
+#if 0
  {{0x5b,0x27,0x9f,0x29,0x01,0xc0,0x1f,
    0x90,0x84,0x8f,0xc1,0x30,0x00,0x01,
    0x00}},
@@ -2913,10 +2876,42 @@
  {{0x97,0x63,0x9b,0x65,0x1d,0xe0,0x10,
    0xb0,0x84,0xaf,0xe1,0x2f,0x00,0x06,
    0x00}}
+#endif
 };
 
 static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11600x1200_2[] =
-{    
+{
+ {{0xFB,0x87,0x86,0x97,0x0F,0x26,0x97,
+   0x43,0x86,0xDB,0xDA,0x11,0x00,0x07,
+   0x01}},
+ {{0xFB,0x87,0x86,0x97,0x0F,0x26,0x97,
+   0x2A,0x8D,0xC2,0xC1,0x11,0x00,0x07,
+   0x01}},
+ {{0xFB,0x87,0x86,0x97,0x0F,0x26,0x97,
+   0x43,0x86,0xDB,0xDA,0x11,0x00,0x07,
+   0x01}},
+ {{0xFB,0x87,0x86,0x97,0x0F,0x26,0x97,
+   0x2A,0x8D,0xC2,0xC1,0x11,0x00,0x07,
+   0x01}},
+ {{0xFB,0x87,0x86,0x97,0x0F,0x26,0x9F,
+   0x6B,0x8E,0x03,0x02,0x01,0x00,0x07,
+   0x01}},
+ {{0xFB,0x63,0x9F,0xA1,0x99,0x26,0xD5,
+   0xA7,0x8A,0xBF,0xBE,0x01,0x00,0x07,
+   0x01}},
+ {{0xFB,0x7F,0x9F,0xAF,0x87,0x26,0xDD,
+   0xFB,0x8E,0x13,0x12,0x31,0x00,0x03,
+   0x01}},
+ {{0xFB,0x9F,0x9F,0xBF,0x97,0x26,0x5B,
+   0x7B,0x8E,0xFF,0x27,0x39,0x00,0x03,
+   0x01}},
+ {{0xFB,0xAE,0x9F,0xC6,0x9E,0x26,0x11,
+   0x88,0x8B,0x19,0x27,0x1F,0x00,0x03,
+   0x00}},
+ {{0xFB,0xC7,0x9F,0xD3,0x8B,0x26,0x11,
+   0xD3,0x86,0xAF,0x27,0x3F,0x00,0x07,
+   0x00}}
+#if 0
  {{0xfb,0x88,0x87,0x90,0x08,0xe0,0x96,
    0x20,0x84,0xb9,0xb8,0x01,0x00,0x07,
    0x01}},
@@ -2947,10 +2942,42 @@
  {{0xfb,0xc7,0x9f,0xc9,0x84,0xe0,0x10,
    0xc7,0x8b,0xaf,0xe1,0x0f,0x00,0x07,
    0x00}}
+#endif
 };
 
 static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11600x1200_2_H[] = 
-{    
+{
+ {{0xD3,0x5F,0x9E,0x6F,0x07,0x26,0x97,
+   0x43,0x86,0xDB,0xDA,0x11,0x00,0x02,
+   0x01}},
+ {{0xD3,0x27,0x97,0x6F,0x07,0x26,0x97,
+   0x6B,0x8E,0x83,0x82,0x01,0x00,0x03,
+   0x01}},
+ {{0xD3,0x5F,0x9E,0x6F,0x07,0x26,0x97,
+   0x43,0x86,0xDB,0xDA,0x11,0x00,0x02,
+   0x01}},
+ {{0xD3,0x27,0x97,0x6F,0x07,0x26,0x97,
+   0x07,0x8B,0xA0,0x9F,0x01,0x00,0x02,
+   0x01}},
+ {{0xD3,0x27,0x97,0x6F,0x07,0x26,0x97,
+   0x6B,0x8E,0x83,0x82,0x01,0x00,0x03,
+   0x01}},
+ {{0xC9,0x31,0x8D,0x6F,0x07,0x26,0xD5,
+   0xA7,0x8A,0xBF,0xBE,0x01,0x00,0x03,
+   0x01}},
+ {{0xBB,0x3F,0x9F,0x6F,0x87,0x26,0xDD,
+   0xFB,0x8E,0x13,0x12,0x31,0x00,0x02,
+   0x01}},
+ {{0xAB,0x4F,0x8F,0x68,0x80,0xE0,0x5A,
+   0x6F,0x83,0xFF,0xE1,0x29,0x00,0x02,
+   0x01}},
+ {{0xA3,0x56,0x87,0x67,0x9F,0xE0,0x10,
+   0x7C,0x80,0x19,0xE1,0x0F,0x00,0x06,
+   0x00}},
+ {{0x97,0x63,0x9B,0x68,0x00,0xE0,0x10,
+   0xC7,0x8B,0xAF,0xE1,0x0F,0x00,0x02,
+   0x00}}
+#if 0
  {{0xd3,0x60,0x9f,0x68,0x00,0xe0,0x96,
    0x20,0x84,0xb9,0xb8,0x01,0x00,0x02,
    0x01}},
@@ -2981,132 +3008,109 @@
  {{0x97,0x63,0x9b,0x68,0x00,0xe0,0x10,
    0xc7,0x8b,0xaf,0xe1,0x0f,0x00,0x02,
    0x00}}
+#endif
 };
 
+/* CRT1 CRTC for Chrontel TV slave modes */
 
 static const SiS310_LVDSCRT1DataStruct  SiS310_CHTVCRT1UNTSC[] =  
 { 
-	{{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
-	  0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,
-	  0x00 }},
-	{{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
-	  0xd0,0x82,0x5d,0x57,0x00,0x00,0x01,
-	  0x00 }},
-	{{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
-	  0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,
-	  0x00 }},
-	{{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
-	  0xd0,0x82,0x5d,0x57,0x00,0x00,0x01,
-	  0x00 }},
-	{{0x5d,0x4f,0x81,0x56,0x99,0x56,0xba,
-	  0x0a,0x84,0xdf,0x57,0x00,0x00,0x01,
-	  0x00 }},
-	{{0x80,0x63,0x84,0x6d,0x0f,0xec,0xf0,
-	  0x7a,0x8f,0x57,0xed,0x20,0x00,0x06,
-	  0x01 }},
-	{{0x8c,0x7f,0x90,0x86,0x09,0xaf,0xf5,
-	  0x36,0x88,0xff,0xb0,0x10,0x00,0x02,
-	  0x01}}
+ {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
+   0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,
+   0x00 }},
+ {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
+   0xd0,0x82,0x5d,0x57,0x00,0x00,0x01,
+   0x00 }},
+ {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
+   0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,
+   0x00 }},
+ {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
+   0xd0,0x82,0x5d,0x57,0x00,0x00,0x01,
+   0x00 }},
+ {{0x5d,0x4f,0x81,0x56,0x99,0x56,0xba,
+   0x0a,0x84,0xdf,0x57,0x00,0x00,0x01,
+   0x00 }},
+ {{0x80,0x63,0x84,0x6d,0x0f,0xec,0xf0,
+   0x7a,0x8f,0x57,0xed,0x20,0x00,0x06,
+   0x01 }},
+ {{0x8c,0x7f,0x90,0x86,0x09,0xaf,0xf5,
+   0x36,0x88,0xff,0xb0,0x10,0x00,0x02,
+   0x01}}
 };
 
-static const SiS310_LVDSCRT1DataStruct  SiS310_CHTVCRT1ONTSC[] =   
-{ 
-	{{0x63,0x4f,0x87,0x5a,0x9f,0x0b,0x3e,
-	  0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,
-	  0x00 }},
-	{{0x63,0x4f,0x87,0x5a,0x9f,0x0b,0x3e,
-	  0xb0,0x8d,0x5d,0x0c,0x00,0x00,0x01,
-	  0x00 }},
-	{{0x63,0x4f,0x87,0x5a,0x9f,0x0b,0x3e,
-	  0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,
-	  0x00 }},
-	{{0x63,0x4f,0x87,0x5a,0x9f,0x0b,0x3e,
-	  0xb0,0x8d,0x5d,0x0c,0x00,0x00,0x01,
-	  0x00 }},
-	{{0x5d,0x4f,0x81,0x58,0x9d,0x0b,0x3e,
-	  0xe8,0x84,0xdf,0x0c,0x00,0x00,0x01,
-	  0x00 }},
-	{{0x7d,0x63,0x81,0x68,0x0e,0xba,0xf0,
-	  0x78,0x8a,0x57,0xbb,0x20,0x00,0x06,
-	  0x01 }},
-	{{0x8c,0x7f,0x90,0x82,0x06,0x46,0xf5,
-	  0x15,0x88,0xff,0x47,0x70,0x00,0x02,
-	  0x01 }}
+static const SiS310_LVDSCRT1DataStruct  SiS310_CHTVCRT1ONTSC[] =
+{
+ {{0x63,0x4f,0x87,0x5a,0x9f,0x0b,0x3e,
+   0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,
+   0x00 }},
+ {{0x63,0x4f,0x87,0x5a,0x9f,0x0b,0x3e,
+   0xb0,0x8d,0x5d,0x0c,0x00,0x00,0x01,
+   0x00 }},
+ {{0x63,0x4f,0x87,0x5a,0x9f,0x0b,0x3e,
+   0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,
+   0x00 }},
+ {{0x63,0x4f,0x87,0x5a,0x9f,0x0b,0x3e,
+   0xb0,0x8d,0x5d,0x0c,0x00,0x00,0x01,
+   0x00 }},
+ {{0x5d,0x4f,0x81,0x58,0x9d,0x0b,0x3e,
+   0xe8,0x84,0xdf,0x0c,0x00,0x00,0x01,
+   0x00 }},
+ {{0x7d,0x63,0x81,0x68,0x0e,0xba,0xf0,
+   0x78,0x8a,0x57,0xbb,0x20,0x00,0x06,
+   0x01 }},
+ {{0x8c,0x7f,0x90,0x82,0x06,0x46,0xf5,
+   0x15,0x88,0xff,0x47,0x70,0x00,0x02,
+   0x01 }}
 };
 
 static const SiS310_LVDSCRT1DataStruct  SiS310_CHTVCRT1UPAL[] =    
 { 
-	{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
-	  0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,
-	  0x00 }},
-	{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
-	  0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
-	  0x00 }},
-	{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
-	  0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,
-	  0x00 }},
-	{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
-	  0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
-	  0x00 }},
-	{{0x64,0x4f,0x88,0x5a,0x9f,0x6f,0xba,
-	  0x15,0x83,0xdf,0x70,0x00,0x00,0x01,
-	  0x00 }},
-	{{0x73,0x63,0x97,0x69,0x8b,0xec,0xf0,
-	  0x90,0x8c,0x57,0xed,0x20,0x00,0x05,
-	  0x01 }},
-	{{0xaa,0x7f,0x8e,0x8e,0x96,0xe6,0xf5,
-	  0x50,0x88,0xff,0xe7,0x10,0x00,0x02,
-	  0x01}}
-};
-
-static const SiS310_LVDSCRT1DataStruct  SiS310_CHTVCRT1OPAL[] = 
-{
-	{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
-	  0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
-	  0x00 }},
-	{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
-	  0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
-	  0x00 }},
-	{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
-	  0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
-	  0x00 }},
-	{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
-	  0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
-	  0x00 }},
-	{{0x64,0x4f,0x88,0x58,0x9d,0x6f,0xba,
-	  0x15,0x83,0xdf,0x70,0x00,0x00,0x01,
-	  0x00 }},
-	{{0x71,0x63,0x95,0x69,0x8c,0x6f,0xf0,
-	  0x5a,0x8b,0x57,0x70,0x20,0x00,0x05,
-	  0x01 }},
-	{{0xaa,0x7f,0x8e,0x8f,0x96,0x69,0xf5,
-	  0x28,0x88,0xff,0x6a,0x10,0x00,0x02,
-	  0x01 }}
-};
-
-static const SiS310_LVDSCRT1DataStruct  SiS310_CHTVCRT1SOPAL[] =
-{
-	{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
-	  0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
-	  0x00 }},
-	{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
-	  0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
-	  0x00 }},
-	{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
-	  0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
-	  0x00 }},
-	{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
-	  0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
-	  0x00 }},
-	{{0x64,0x4f,0x88,0x58,0x9d,0x6f,0xba,
-	  0x15,0x83,0xdf,0x70,0x00,0x00,0x01,
-	  0x00 }},
-	{{0x71,0x63,0x95,0x69,0x8c,0x6f,0xf0,
-	  0x5a,0x8b,0x57,0x70,0x20,0x00,0x05,
-	  0x01 }},
-	{{0xaa,0x7f,0x8e,0x8f,0x96,0x69,0xf5,
-	  0x28,0x88,0xff,0x6a,0x10,0x00,0x02,
-	  0x01 }}
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+   0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,
+   0x00 }},
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+   0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
+   0x00 }},
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+   0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,
+   0x00 }},
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+   0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
+   0x00 }},
+ {{0x64,0x4f,0x88,0x5a,0x9f,0x6f,0xba,
+   0x15,0x83,0xdf,0x70,0x00,0x00,0x01,
+   0x00 }},
+ {{0x73,0x63,0x97,0x69,0x8b,0xec,0xf0,
+   0x90,0x8c,0x57,0xed,0x20,0x00,0x05,
+   0x01 }},
+ {{0xaa,0x7f,0x8e,0x8e,0x96,0xe6,0xf5,
+   0x50,0x88,0xff,0xe7,0x10,0x00,0x02,
+   0x01}}
+};
+
+static const SiS310_LVDSCRT1DataStruct  SiS310_CHTVCRT1OPAL[] =
+{
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+   0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
+   0x00 }},
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+   0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
+   0x00 }},
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+   0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
+   0x00 }},
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+   0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
+   0x00 }},
+ {{0x64,0x4f,0x88,0x58,0x9d,0x6f,0xba,
+   0x15,0x83,0xdf,0x70,0x00,0x00,0x01,
+   0x00 }},
+ {{0x71,0x63,0x95,0x69,0x8c,0x6f,0xf0,
+   0x5a,0x8b,0x57,0x70,0x20,0x00,0x05,
+   0x01 }},
+ {{0xaa,0x7f,0x8e,0x8f,0x96,0x69,0xf5,
+   0x28,0x88,0xff,0x6a,0x10,0x00,0x02,
+   0x01 }}
 };
 
 typedef struct _SiS310_CHTVRegDataStruct
@@ -3116,118 +3120,131 @@
 
 static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_UNTSC[] =
 {
-	{{0x4a,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
-	{{0x4a,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
-	{{0x4a,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
-	{{0x4a,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
-	{{0x6a,0x77,0xbb,0x6e,0x84,0x2e,0x02,0x5a,0x04,0x00,0x80,0x20,0x7e,0x80,0x98,0x00}},
-	{{0xcf,0x77,0xb7,0xc8,0x84,0x3b,0x02,0x5a,0x04,0x00,0x80,0x19,0x88,0x30,0x7f,0x00}},
-	{{0xee,0x77,0xbb,0x66,0x87,0x32,0x01,0x5a,0x04,0x00,0x80,0x1b,0xd3,0xf2,0x36,0x00}}
-};
+ {{0x4a,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x4a,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x4a,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x4a,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x6a,0x77,0xbb,0x6e,0x84,0x2e,0x02,0x5a,0x04,0x00,0x80,0x20,0x7e,0x80,0x98,0x00}},
+ {{0xcf,0x77,0xb7,0xc8,0x84,0x3b,0x02,0x5a,0x04,0x00,0x80,0x19,0x88,0x30,0x7f,0x00}},
+ {{0xee,0x77,0xbb,0x66,0x87,0x32,0x01,0x5a,0x04,0x00,0x80,0x1b,0xd3,0xf2,0x36,0x00}}
+}; /* WRONG: 0x02: should be 0xfx, because if CIVEnable is clear, this should be set;
+             0x07: Blacklevel: NTSC/PAL-M: Should be 131 (0x83), and not 0x50/0x5a
+	                       PAL/PAL-N:  110 (0x6e)
+			       NTSC-J:     102 (0x66)
+	     0x0c-0x0f: CIV is not default as in datasheet
+      MISSING: 0x21: Should set D1 to ZERO (for NTSC, PAL-M) or ONE (PAL, NTSC-J)
+      Most of this is wrong in all NTSC and PAL register arrays. But I won't correct
+      it as long as it works. For NTSC-J, the blacklevel is corrected in init301.c;
+      for PAL-M and PAL-N all above is corrected.
+    */
 
 static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_ONTSC[] =
 {
-	{{0x49,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
-	{{0x49,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
-	{{0x49,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
-	{{0x49,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
-	{{0x69,0x77,0xbb,0x6e,0x84,0x1e,0x00,0x5a,0x04,0x00,0x80,0x25,0x1a,0x43,0x04,0x00}},
-	{{0xce,0x77,0xb7,0xb6,0x83,0x2c,0x02,0x5a,0x04,0x00,0x80,0x1c,0x00,0x82,0x97,0x00}},
-	{{0xed,0x77,0xbb,0x66,0x8c,0x21,0x02,0x5a,0x04,0x00,0x80,0x1f,0x9f,0xc1,0x0c,0x00}}
+ {{0x49,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x49,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x49,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x49,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x69,0x77,0xbb,0x6e,0x84,0x1e,0x00,0x5a,0x04,0x00,0x80,0x25,0x1a,0x43,0x04,0x00}},
+ {{0xce,0x77,0xb7,0xb6,0x83,0x2c,0x02,0x5a,0x04,0x00,0x80,0x1c,0x00,0x82,0x97,0x00}},
+ {{0xed,0x77,0xbb,0x66,0x8c,0x21,0x02,0x5a,0x04,0x00,0x80,0x1f,0x9f,0xc1,0x0c,0x00}}
 };
 
 static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_UPAL[] =
 {
-	{{0x41,0x7f,0xb7,0x34,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
-	{{0x41,0x7f,0xb7,0x80,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
-	{{0x41,0x7f,0xb7,0x34,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
-	{{0x41,0x7f,0xb7,0x12,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
-	{{0x61,0x7f,0xb7,0x99,0x84,0x35,0x04,0x5a,0x05,0x00,0x80,0x26,0x2a,0x55,0x5d,0x00}},
-	{{0xc3,0x7f,0xb7,0x7a,0x84,0x40,0x02,0x5a,0x05,0x00,0x80,0x1f,0x84,0x3d,0x28,0x00}},
-	{{0xe5,0x7f,0xb7,0x1d,0xa7,0x3e,0x04,0x5a,0x05,0x00,0x80,0x20,0x3e,0xe4,0x22,0x00}}
+ {{0x41,0x7f,0xb7,0x34,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x41,0x7f,0xb7,0x80,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x41,0x7f,0xb7,0x34,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x41,0x7f,0xb7,0x12,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x61,0x7f,0xb7,0x99,0x84,0x35,0x04,0x5a,0x05,0x00,0x80,0x26,0x2a,0x55,0x5d,0x00}},
+ {{0xc3,0x7f,0xb7,0x7a,0x84,0x40,0x02,0x5a,0x05,0x00,0x80,0x1f,0x84,0x3d,0x28,0x00}},
+ {{0xe5,0x7f,0xb7,0x1d,0xa7,0x3e,0x04,0x5a,0x05,0x00,0x80,0x20,0x3e,0xe4,0x22,0x00}}
 };
 
 static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_OPAL[] =
 {
-	{{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
-	{{0x41,0x7f,0xb7,0x86,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
-	{{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
-	{{0x41,0x7f,0xb7,0x86,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
-	{{0x61,0x7f,0xb7,0x99,0x84,0x35,0x04,0x5a,0x05,0x00,0x80,0x26,0x2a,0x55,0x5d,0x00}},
-	{{0xc1,0x7f,0xb7,0x4d,0x8c,0x1e,0x31,0x5a,0x05,0x00,0x80,0x26,0x78,0x19,0x34,0x00}},
-	{{0xe4,0x7f,0xb7,0x1e,0xaf,0x29,0x37,0x5a,0x05,0x00,0x80,0x25,0x8c,0xb2,0x2a,0x00}}
-};
-
-static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_SOPAL[] =
-{
-	{{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
-	{{0x41,0x7f,0xb7,0x86,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
-	{{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
-	{{0x41,0x7f,0xb7,0x86,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
-	{{0x61,0x7f,0xb7,0x99,0x84,0x35,0x04,0x5a,0x05,0x00,0x80,0x26,0x2a,0x55,0x5d,0x00}},
-	{{0xc1,0x7f,0xb7,0x4d,0x8c,0x1e,0x31,0x5a,0x05,0x00,0x80,0x26,0x78,0x19,0x34,0x00}},
-	{{0xe4,0x7f,0xb7,0x1e,0xaf,0x29,0x37,0x5a,0x05,0x00,0x80,0x25,0x8c,0xb2,0x2a,0x00}}
+ {{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x41,0x7f,0xb7,0x86,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x41,0x7f,0xb7,0x86,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x61,0x7f,0xb7,0x99,0x84,0x35,0x04,0x5a,0x05,0x00,0x80,0x26,0x2a,0x55,0x5d,0x00}},
+ {{0xc1,0x7f,0xb7,0x4d,0x8c,0x1e,0x31,0x5a,0x05,0x00,0x80,0x26,0x78,0x19,0x34,0x00}},
+ {{0xe4,0x7f,0xb7,0x1e,0xaf,0x29,0x37,0x5a,0x05,0x00,0x80,0x25,0x8c,0xb2,0x2a,0x00}}
 };
 
 static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_UPALM[] =
 {
-	{{0x52,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
-	{{0x52,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
-	{{0x52,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
-	{{0x52,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
-	{{0x72,0x77,0xbb,0x6e,0x84,0x2e,0x02,0x5a,0x04,0x00,0x80,0x20,0x76,0xdb,0x6e,0x00}},
-	{{0xd7,0x77,0xb7,0xc8,0x84,0x3b,0x02,0x5a,0x04,0x00,0x80,0x19,0x84,0x0a,0xc7,0x00}},
-	{{0xf6,0x77,0xbb,0x66,0x87,0x32,0x01,0x5a,0x04,0x00,0x80,0x1b,0xdc,0xb0,0x8d,0x00}}
+ {{0x52,0x77,0xbb,0x94,0x84,0x48,0xfe,0x83,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x52,0x77,0xbb,0x94,0x84,0x48,0xfe,0x83,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x52,0x77,0xbb,0x94,0x84,0x48,0xfe,0x83,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x52,0x77,0xbb,0x94,0x84,0x48,0xfe,0x83,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x72,0x77,0xfb,0x6e,0x84,0x2e,0x02,0x83,0x04,0x00,0x80,0x20,0x76,0xdb,0x6e,0x00}},
+ {{0xd7,0x77,0xf7,0xc8,0x84,0x3b,0x02,0x83,0x04,0x00,0x80,0x19,0x84,0x0a,0xc7,0x00}},
+ {{0xf6,0x77,0xfb,0x66,0x87,0x32,0x01,0x83,0x04,0x00,0x80,0x1b,0xdc,0xb0,0x8d,0x00}}
+#if 0 /* Correct blacklevel and CFRB */
+ {{0x72,0x77,0xbb,0x6e,0x84,0x2e,0x02,0x5a,0x04,0x00,0x80,0x20,0x76,0xdb,0x6e,0x00}},
+ {{0xd7,0x77,0xb7,0xc8,0x84,0x3b,0x02,0x5a,0x04,0x00,0x80,0x19,0x84,0x0a,0xc7,0x00}},
+ {{0xf6,0x77,0xbb,0x66,0x87,0x32,0x01,0x5a,0x04,0x00,0x80,0x1b,0xdc,0xb0,0x8d,0x00}}
+#endif
 };
 
 static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_OPALM[] =
 {
-	{{0x51,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
-	{{0x51,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
-	{{0x51,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
-	{{0x51,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
-	{{0x71,0x77,0xbb,0x6e,0x84,0x1e,0x00,0x5a,0x04,0x00,0x80,0x25,0x1a,0x1f,0x59,0x00}},
-	{{0xd6,0x77,0xb7,0xb6,0x83,0x2c,0x02,0x5a,0x04,0x00,0x80,0x1b,0xf8,0x1f,0x82,0x00}},
-	{{0xf5,0x77,0xbb,0x66,0x8c,0x21,0x02,0x5a,0x04,0x00,0x80,0x1f,0x58,0x46,0x9f,0x00}}
+ {{0x51,0x77,0xbb,0x7b,0x84,0x34,0x00,0x83,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x51,0x77,0xbb,0x7b,0x84,0x34,0x00,0x83,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x51,0x77,0xbb,0x7b,0x84,0x34,0x00,0x83,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x51,0x77,0xbb,0x7b,0x84,0x34,0x00,0x83,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x71,0x77,0xfb,0x6e,0x84,0x1e,0x00,0x83,0x04,0x00,0x80,0x25,0x1a,0x1f,0x59,0x00}},
+ {{0xd6,0x77,0xf7,0xb6,0x83,0x2c,0x02,0x83,0x04,0x00,0x80,0x1b,0xf8,0x1f,0x82,0x00}},
+ {{0xf5,0x77,0xfb,0x66,0x8c,0x21,0x02,0x83,0x04,0x00,0x80,0x1f,0x58,0x46,0x9f,0x00}}
+#if 0 /* Correct blacklevel and CFRB */
+ {{0x71,0x77,0xbb,0x6e,0x84,0x1e,0x00,0x5a,0x04,0x00,0x80,0x25,0x1a,0x1f,0x59,0x00}},
+ {{0xd6,0x77,0xb7,0xb6,0x83,0x2c,0x02,0x5a,0x04,0x00,0x80,0x1b,0xf8,0x1f,0x82,0x00}},
+ {{0xf5,0x77,0xbb,0x66,0x8c,0x21,0x02,0x5a,0x04,0x00,0x80,0x1f,0x58,0x46,0x9f,0x00}}
+#endif
 };
 
 static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_UPALN[] =
 {
-	{{0x41,0x7f,0xb7,0x34,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
-	{{0x41,0x7f,0xb7,0x80,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
-	{{0x41,0x7f,0xb7,0x34,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
-	{{0x41,0x7f,0xb7,0x12,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
-	{{0x61,0x7f,0xb7,0x99,0x84,0x35,0x04,0x5a,0x05,0x00,0x80,0x1f,0x0d,0x54,0x5e,0x00}},
-	{{0xc3,0x7f,0xb7,0x7a,0x84,0x40,0x02,0x5a,0x05,0x00,0x80,0x19,0x78,0xef,0x35,0x00}},
-	{{0xe5,0x7f,0xb7,0x1d,0xa7,0x3e,0x04,0x5a,0x05,0x00,0x80,0x1a,0x33,0x3f,0x2f,0x00}}
+ {{0x41,0x7f,0xb7,0x34,0xad,0x50,0x34,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
+ {{0x41,0x7f,0xb7,0x80,0x85,0x50,0x00,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
+ {{0x41,0x7f,0xb7,0x34,0xad,0x50,0x34,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
+ {{0x41,0x7f,0xb7,0x12,0x85,0x50,0x00,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
+ {{0x61,0x7f,0xb7,0x99,0x84,0x35,0x04,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
+ {{0xc3,0x7f,0xb7,0x7a,0x84,0x40,0x02,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
+ {{0xe5,0x7f,0xb7,0x1d,0xa7,0x3e,0x04,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}}
+#if 0 /* Correct blacklevel, CIV and CFRB */
+ {{0x61,0x7f,0xb7,0x99,0x84,0x35,0x04,0x5a,0x05,0x00,0x80,0x1f,0x0d,0x54,0x5e,0x00}},
+ {{0xc3,0x7f,0xb7,0x7a,0x84,0x40,0x02,0x5a,0x05,0x00,0x80,0x19,0x78,0xef,0x35,0x00}},
+ {{0xe5,0x7f,0xb7,0x1d,0xa7,0x3e,0x04,0x5a,0x05,0x00,0x80,0x1a,0x33,0x3f,0x2f,0x00}}
+#endif
 };
 
 static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_OPALN[] =
 {
-	{{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
-	{{0x41,0x7f,0xb7,0x86,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
-	{{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
-	{{0x41,0x7f,0xb7,0x86,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
-	{{0x61,0x7f,0xb7,0x99,0x84,0x35,0x04,0x5a,0x05,0x00,0x80,0x1f,0x0d,0x54,0x5e,0x00}},
-	{{0xc1,0x7f,0xb7,0x4d,0x8c,0x1e,0x31,0x5a,0x05,0x00,0x80,0x1f,0x15,0xc0,0x1e,0x00}},
-	{{0xe4,0x7f,0xb7,0x1e,0xaf,0x29,0x37,0x5a,0x05,0x00,0x80,0x1d,0xf1,0x6c,0xcb,0x00}}
+ {{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
+ {{0x41,0x7f,0xb7,0x86,0x85,0x50,0x00,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
+ {{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
+ {{0x41,0x7f,0xb7,0x86,0x85,0x50,0x00,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
+ {{0x61,0x7f,0xb7,0x99,0x84,0x35,0x04,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
+ {{0xc1,0x7f,0xb7,0x4d,0x8c,0x1e,0x31,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
+ {{0xe4,0x7f,0xb7,0x1e,0xaf,0x29,0x37,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}}
+#if 0 /* Correct blacklevel, CIV and CFRB */
+ {{0x61,0x7f,0xb7,0x99,0x84,0x35,0x04,0x5a,0x05,0x00,0x80,0x1f,0x0d,0x54,0x5e,0x00}},
+ {{0xc1,0x7f,0xb7,0x4d,0x8c,0x1e,0x31,0x5a,0x05,0x00,0x80,0x1f,0x15,0xc0,0x1e,0x00}},
+ {{0xe4,0x7f,0xb7,0x1e,0xaf,0x29,0x37,0x5a,0x05,0x00,0x80,0x1d,0xf1,0x6c,0xcb,0x00}}
+#endif
 };
 
 static const UCHAR SiS310_CHTVVCLKUNTSC[] = {0x41,0x41,0x41,0x41,0x42,0x46,0x53};
-
 static const UCHAR SiS310_CHTVVCLKONTSC[] = {0x48,0x48,0x48,0x48,0x45,0x43,0x51};
 
 static const UCHAR SiS310_CHTVVCLKUPAL[]  = {0x47,0x47,0x47,0x47,0x48,0x4a,0x54};
-
 static const UCHAR SiS310_CHTVVCLKOPAL[]  = {0x47,0x47,0x47,0x47,0x48,0x4f,0x52};
 
-static const UCHAR SiS310_CHTVVCLKSOPAL[] = {0x47,0x47,0x47,0x47,0x48,0x4f,0x52};
-
 static const UCHAR SiS310_CHTVVCLKUPALM[] = {0x41,0x41,0x41,0x41,0x42,0x46,0x53};
-
 static const UCHAR SiS310_CHTVVCLKOPALM[] = {0x48,0x48,0x48,0x48,0x45,0x43,0x51};
 
 static const UCHAR SiS310_CHTVVCLKUPALN[] = {0x47,0x47,0x47,0x47,0x48,0x4a,0x54};
-
 static const UCHAR SiS310_CHTVVCLKOPALN[] = {0x47,0x47,0x47,0x47,0x48,0x4f,0x52};
 
+
diff -urN linux-2.4.25-pre4/drivers/video/sis/init.c linux-2.4.25-pre5/drivers/video/sis/init.c
--- linux-2.4.25-pre4/drivers/video/sis/init.c	2003-11-28 10:26:21.000000000 -0800
+++ linux-2.4.25-pre5/drivers/video/sis/init.c	2004-01-15 12:10:23.000000000 -0800
@@ -1,35 +1,60 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/init.c,v 1.3 2002/24/04 01:16:16 dawes Exp $ */
+/* $XFree86$ */
 /*
- * Mode switching code (CRT1 section) for
- * SiS 300/540/630/730/315/550/650/M650/651/M652/740/330/660/M660/760
+ * Mode initializing code (CRT1 section) for
+ * for SiS 300/305/540/630/730 and
+ *     SiS 315/550/650/M650/651/661FX/M661FX/740/741/M741/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>
- * Formerly based on non-functional code-fragements by SiS, Inc.
+ * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
  *
- * If distributed as part of the linux kernel, the contents of this file
- * is entirely covered by the GPL.
+ * If distributed as part of the Linux kernel, the following license terms
+ * apply:
  *
- * Otherwise, the following terms apply:
+ * * This program is free software; you can redistribute it and/or modify
+ * * it under the terms of the GNU General Public License as published by
+ * * the Free Software Foundation; either version 2 of the named License,
+ * * or any later version.
+ * *
+ * * This program is distributed in the hope that it will be useful,
+ * * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * * GNU General Public License for more details.
+ * *
+ * * You should have received a copy of the GNU General Public License
+ * * along with this program; if not, write to the Free Software
+ * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
  *
- * 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.
+ * Otherwise, the following license terms apply:
  *
- * 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.
+ * * Redistribution and use in source and binary forms, with or without
+ * * modification, are permitted provided that the following conditions
+ * * are met:
+ * * 1) Redistributions of source code must retain the above copyright
+ * *    notice, this list of conditions and the following disclaimer.
+ * * 2) Redistributions in binary form must reproduce the above copyright
+ * *    notice, this list of conditions and the following disclaimer in the
+ * *    documentation and/or other materials provided with the distribution.
+ * * 3) All advertising materials mentioning features or use of this software
+ * *    must display the following acknowledgement: "This product includes
+ * *    software developed by Thomas Winischhofer, Vienna, Austria."
+ * * 4) The name of the author may not be used to endorse or promote products
+ * *    derived from this software without specific prior written permission.
+ * *
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ * Formerly based on non-functional code-fragements for 300 series by SiS, Inc.
+ * Used by permission.
  *
  * TW says: This code looks awful, I know. But please don't do anything about
  * this otherwise debugging will be hell.
@@ -51,109 +76,33 @@
 #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, BOOLEAN includelcdmodes, BOOLEAN isfordvi);
-#ifdef SISDUALHEAD
-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, BOOLEAN IsCustom);
-#endif /* dual head */
-#endif /* linux_xf86 */
-
-#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
-
-#ifndef LINUX_XF86
-static ULONG GetDRAMSize(SiS_Private *SiS_Pr,
-                         PSIS_HW_DEVICE_INFO HwDeviceExtension);
-#endif
-
 #if defined(ALLOC_PRAGMA)
 #pragma alloc_text(PAGE,SiSSetMode)
 #pragma alloc_text(PAGE,SiSInit)
 #endif
 
+/*********************************************/
+/*         POINTER INITIALIZATION            */
+/*********************************************/
+
 static void
-InitCommonPointer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+InitCommonPointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
    SiS_Pr->SiS_StResInfo     = SiS_StResInfo;
    SiS_Pr->SiS_ModeResInfo   = SiS_ModeResInfo;
    SiS_Pr->SiS_StandTable    = SiS_StandTable;
-   if(HwDeviceExtension->jChipType < SIS_315H) {
-      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;
-   } else {
-      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_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_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_SpecialPhaseM = SiS_SpecialPhaseM;
+   SiS_Pr->SiS_SpecialPhaseJ = SiS_SpecialPhaseJ;
 
    SiS_Pr->SiS_NTSCTiming     = SiS_NTSCTiming;
    SiS_Pr->SiS_PALTiming      = SiS_PALTiming;
@@ -172,6 +121,12 @@
 /* SiS_Pr->SiS_St1HiTVData = SiS_St1HiTVData;  */
    SiS_Pr->SiS_St2HiTVData = SiS_St2HiTVData;
    SiS_Pr->SiS_ExtHiTVData = SiS_ExtHiTVData;
+   SiS_Pr->SiS_St525iData  = SiS_StNTSCData;
+   SiS_Pr->SiS_St525pData  = SiS_St525pData;
+   SiS_Pr->SiS_St750pData  = SiS_St750pData;
+   SiS_Pr->SiS_Ext525iData = SiS_ExtNTSCData;
+   SiS_Pr->SiS_Ext525pData = SiS_ExtNTSCData;
+   SiS_Pr->SiS_Ext750pData = SiS_Ext750pData;
 
    SiS_Pr->pSiS_OutputSelect = &SiS_OutputSelect;
    SiS_Pr->pSiS_SoftSetting  = &SiS_SoftSetting;
@@ -221,12 +176,17 @@
    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->SiS_CHTVUNTSCData = SiS_CHTVUNTSCData;
-   SiS_Pr->SiS_CHTVONTSCData = SiS_CHTVONTSCData;
 
    SiS_Pr->LVDS1024x768Des_1  = SiS_PanelType1076_1;
    SiS_Pr->LVDS1280x1024Des_1 = SiS_PanelType1210_1;
@@ -270,23 +230,48 @@
 
 #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, HwDeviceExtension);
+   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_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;
@@ -328,7 +313,10 @@
    SiS_Pr->SiS_NoScaleData1280x1024 = (SiS_LCDDataStruct *)SiS300_NoScaleData1280x1024;
 
    SiS_Pr->SiS_PanelDelayTbl     = (SiS_PanelDelayTblStruct *)SiS300_PanelDelayTbl;
+   SiS_Pr->SiS_PanelDelayTblLVDS = (SiS_PanelDelayTblStruct *)SiS300_PanelDelayTbl;
+#if 0
    SiS_Pr->SiS_PanelDelayTblLVDS = (SiS_PanelDelayTblStruct *)SiS300_PanelDelayTblLVDS;
+#endif
 
    SiS_Pr->SiS_CHTVUPALData  = (SiS_LVDSDataStruct *)SiS300_CHTVUPALData;
    SiS_Pr->SiS_CHTVOPALData  = (SiS_LVDSDataStruct *)SiS300_CHTVOPALData;
@@ -429,7 +417,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 315 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;
@@ -439,14 +427,14 @@
    SiS_Pr->SiS_Panel1024x600  = Panel_1024x600;
    SiS_Pr->SiS_Panel1152x768  = Panel_1152x768;
    SiS_Pr->SiS_Panel1280x768  = Panel_1280x768;
-   SiS_Pr->SiS_Panel1600x1200 = 255;  		/* TW: Something illegal */
-   SiS_Pr->SiS_Panel1400x1050 = 255;  		/* TW: Something illegal */
-   SiS_Pr->SiS_Panel640x480_2 = 255;  		/* TW: Something illegal */
-   SiS_Pr->SiS_Panel640x480_3 = 255;  		/* TW: Something illegal */
-   SiS_Pr->SiS_Panel1152x864  = 255;   		/* 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_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;
 }
@@ -454,32 +442,52 @@
 
 #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, HwDeviceExtension);
+   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_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 */
-#ifdef LINUXBIOS
-   if(HwDeviceExtension->jChipType >= SIS_660) {
-      SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS310_MCLKData_0_660;  /* 660/760 */
-   } else if(HwDeviceExtension->jChipType == SIS_330) {
-#endif
+   if(HwInfo->jChipType >= SIS_661) {
+      SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS310_MCLKData_0_660;  /* 661/741/760 */
+   } else if(HwInfo->jChipType == SIS_330) {
       SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS310_MCLKData_0_330;  /* 330 */
-#ifdef LINUXBIOS
-   } else if(HwDeviceExtension->jChipType > SIS_315PRO) {
+   } 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;
@@ -601,7 +609,7 @@
    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_CHTVCRT1SOPAL         = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1OPAL;
 
    SiS_Pr->SiS_CHTVReg_UNTSC = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_UNTSC;
    SiS_Pr->SiS_CHTVReg_ONTSC = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_ONTSC;
@@ -611,24 +619,20 @@
    SiS_Pr->SiS_CHTVReg_OPALM = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_OPALM;
    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_CHTVReg_SOPAL = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_OPAL;
 
-   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;
@@ -642,7 +646,7 @@
    SiS_Pr->SiS_CHTVVCLKOPALM = SiS310_CHTVVCLKOPALM;
    SiS_Pr->SiS_CHTVVCLKUPALN = SiS310_CHTVVCLKUPALN;
    SiS_Pr->SiS_CHTVVCLKOPALN = SiS310_CHTVVCLKOPALN;   
-   SiS_Pr->SiS_CHTVVCLKSOPAL = SiS310_CHTVVCLKSOPAL;
+   SiS_Pr->SiS_CHTVVCLKSOPAL = SiS310_CHTVVCLKOPAL;
 
    SiS_Pr->SiS_Panel320x480   = Panel_320x480;
    SiS_Pr->SiS_Panel640x480   = Panel_640x480;
@@ -658,50 +662,612 @@
    SiS_Pr->SiS_Panel1024x600  = Panel_1024x600;
    SiS_Pr->SiS_Panel640x480_2 = Panel_640x480_2;
    SiS_Pr->SiS_Panel640x480_3 = Panel_640x480_3;
-   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_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
 
+static void
+SiSInitPtr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+   switch(HwInfo->jChipType) {
 #ifdef SIS315H
-UCHAR
-SiS_Get310DRAMType(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+   case SIS_315H:
+   case SIS_315:
+   case SIS_315PRO:
+   case SIS_550:
+   case SIS_650:
+   case SIS_740:
+   case SIS_330:
+   case SIS_661:
+   case SIS_741:
+   case SIS_660:
+   case SIS_760:
+      InitTo310Pointer(SiS_Pr, HwInfo);
+      break;
+#endif
+#ifdef SIS300
+   case SIS_300:
+   case SIS_540:
+   case SIS_630:
+   case SIS_730:
+      InitTo300Pointer(SiS_Pr, HwInfo);
+      break;
+#endif
+   default:
+      break;
+   }
+}
+
+/*********************************************/
+/*            HELPER: Get ModeID             */
+/*********************************************/
+
+USHORT
+SiS_GetModeID(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth, BOOLEAN FSTN)
 {
-   UCHAR data, temp;
+   USHORT ModeIndex = 0;
 
-   if(*SiS_Pr->pSiS_SoftSetting & SoftDRAMType) {
-     data = *SiS_Pr->pSiS_SoftSetting & 0x03;
-   } else {
-     if(IS_SIS550650740660) {
-        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(data > 1) {
-	      temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5f) & 0x30;
-	      switch(temp) {
-	      case 0x00: data = 1; break;
-	      case 0x10: data = 3; break;
-	      case 0x20: data = 3; break;
-	      case 0x30: data = 2; break;
-	      }
-	   } else {
-	      data = 0;
-	   }
-	}
-     }
+   switch(HDisplay)
+   {
+     case 320:
+     	  if(VDisplay == 200)     ModeIndex = ModeIndex_320x200[Depth];
+	  else if(VDisplay == 240) {
+	     if(FSTN) ModeIndex = ModeIndex_320x240_FSTN[Depth];
+	     else     ModeIndex = ModeIndex_320x240[Depth];
+          }
+          break;
+     case 400:
+          if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
+          break;
+     case 512:
+          if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
+          break;
+     case 640:
+          if(VDisplay == 480)      ModeIndex = ModeIndex_640x480[Depth];
+	  else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth];
+          break;
+     case 720:
+          if(!(VBFlags & CRT1_LCDA)) {
+             if(VDisplay == 480)      ModeIndex = ModeIndex_720x480[Depth];
+             else if(VDisplay == 576) ModeIndex = ModeIndex_720x576[Depth];
+          }
+          break;
+     case 768:
+          if(!(VBFlags & CRT1_LCDA)) {
+             if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
+          }
+	  break;
+     case 800:
+	  if(VDisplay == 600)    ModeIndex = ModeIndex_800x600[Depth];
+	  else if(!(VBFlags & CRT1_LCDA)) {
+	     if(VDisplay == 480) ModeIndex = ModeIndex_800x480[Depth];
+	  }
+          break;
+     case 848:
+          if(!(VBFlags & CRT1_LCDA)) {
+	     if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth];
+	  }
+	  break;
+     case 856:
+          if(!(VBFlags & CRT1_LCDA)) {
+	     if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth];
+	  }
+	  break;
+     case 1024:
+          if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
+	  else if(!(VBFlags & CRT1_LCDA)) {
+	     if(VDisplay == 576)    ModeIndex = ModeIndex_1024x576[Depth];
+	     else if(VGAEngine == SIS_300_VGA) {
+	        if(VDisplay == 600) ModeIndex = ModeIndex_1024x600[Depth];
+             }
+	  }
+          break;
+     case 1152:
+          if(!(VBFlags & CRT1_LCDA)) {
+             if(VDisplay == 864)    ModeIndex = ModeIndex_1152x864[Depth];
+             else if(VGAEngine == SIS_300_VGA) {
+	        if(VDisplay == 768) ModeIndex = ModeIndex_1152x768[Depth];
+             }
+	  }
+	  break;
+     case 1280:
+          if(VDisplay == 1024)        ModeIndex = ModeIndex_1280x1024[Depth];
+	  else if(!(VBFlags & CRT1_LCDA)) {
+             if(VDisplay == 960)      ModeIndex = ModeIndex_1280x960[Depth];
+	     else if(VDisplay == 720) ModeIndex = ModeIndex_1280x720[Depth];
+	     else if(VDisplay == 768) {
+	        if(VGAEngine == SIS_300_VGA) {
+	           ModeIndex = ModeIndex_300_1280x768[Depth];
+	        } else {
+	           ModeIndex = ModeIndex_310_1280x768[Depth];
+	        }
+	     }
+	  }
+          break;
+     case 1360:
+          if(!(VBFlags & CRT1_LCDA)) {
+	     if(VDisplay == 768)     ModeIndex = ModeIndex_1360x768[Depth];
+	     else if(VGAEngine == SIS_300_VGA) {
+	        if(VDisplay == 1024) ModeIndex = ModeIndex_300_1360x1024[Depth];
+             }
+	  }
+          break;
+     case 1400:
+          if(VGAEngine == SIS_315_VGA) {
+	     if(VDisplay == 1050) ModeIndex = ModeIndex_1400x1050[Depth];
+	  }
+          break;
+     case 1600:
+          if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
+          break;
+     case 1920:
+          if(!(VBFlags & CRT1_LCDA)) {
+             if(VDisplay == 1440) ModeIndex = ModeIndex_1920x1440[Depth];
+	  }
+          break;
+     case 2048:
+          if(!(VBFlags & CRT1_LCDA)) {
+             if(VDisplay == 1536) {
+                if(VGAEngine == SIS_300_VGA) {
+	            ModeIndex = ModeIndex_300_2048x1536[Depth];
+  	        } else {
+	            ModeIndex = ModeIndex_310_2048x1536[Depth];
+                }
+	     }
+	  }
+          break;
    }
 
-   return data;
+   return(ModeIndex);
+}
+
+USHORT
+SiS_GetModeID_LCD(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay,
+                  int Depth, BOOLEAN FSTN, USHORT CustomT, int LCDwidth, int LCDheight)
+{
+   USHORT ModeIndex = 0;
+
+   if(VBFlags & (VB_LVDS | VB_30xBDH)) {
+
+      switch(HDisplay)
+      {
+	case 320:
+	     if(CustomT != CUT_PANEL848) {
+     	  	if(VDisplay == 200) ModeIndex = ModeIndex_320x200[Depth];
+	  	else if(VDisplay == 240) {
+		   if(!FSTN) ModeIndex = ModeIndex_320x240[Depth];
+          	   else if(VGAEngine == SIS_315_VGA) {
+                      ModeIndex = ModeIndex_320x240_FSTN[Depth];
+		   }
+		}
+	     }
+             break;
+     	case 400:
+	     if(CustomT != CUT_PANEL848) {
+          	if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
+	     }
+             break;
+	case 512:
+	     if(CustomT != CUT_PANEL848) {
+		if(VDisplay == 384) {
+		   if(LCDwidth != 1024 || LCDheight != 600) {
+		      ModeIndex = ModeIndex_512x384[Depth];
+		   }
+		}
+	     }
+	     break;
+	case 640:
+	     if(VDisplay == 480)            ModeIndex = ModeIndex_640x480[Depth];
+	     else if(VDisplay == 400) {
+	        if(CustomT != CUT_PANEL848) ModeIndex = ModeIndex_640x400[Depth];
+	     }
+	     break;
+	case 800:
+	     if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
+	     break;
+	case 848:
+	     if(CustomT == CUT_PANEL848) {
+	        if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth];
+	     }
+	     break;
+	case 1024:
+	     if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
+	     else if(VGAEngine == SIS_300_VGA) {
+		if((VDisplay == 600) && (LCDheight == 600)) {
+		   ModeIndex = ModeIndex_1024x600[Depth];
+		}
+	     }
+	     break;
+	case 1152:
+	     if(VGAEngine == SIS_300_VGA) {
+	        if((VDisplay == 768) && (LCDheight == 768)) {
+		   ModeIndex = ModeIndex_1152x768[Depth];
+		}
+	     }
+	     break;
+        case 1280:
+	     if(VDisplay == 1024) ModeIndex = ModeIndex_1280x1024[Depth];
+	     else if(VGAEngine == SIS_315_VGA) {
+	        if((VDisplay == 768) && (LCDheight == 768)) {
+		   ModeIndex = ModeIndex_310_1280x768[Depth];
+		}
+	     }
+	     break;
+	case 1360:
+	     if(VGAEngine == SIS_300_VGA) {
+	        if(CustomT == CUT_BARCO1366) {
+		   if(VDisplay == 1024) ModeIndex = ModeIndex_300_1360x1024[Depth];
+		}
+	     }
+	     if(CustomT == CUT_PANEL848) {
+	        if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth];
+	     }
+	     break;
+	case 1400:
+	     if(VGAEngine == SIS_315_VGA) {
+	        if(VDisplay == 1050) ModeIndex = ModeIndex_1400x1050[Depth];
+	     }
+	     break;
+	case 1600:
+	     if(VGAEngine == SIS_315_VGA) {
+	        if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
+	     }
+	     break;
+      }
+
+   } else if(VBFlags & VB_SISBRIDGE) {
+
+      switch(HDisplay)
+      {
+	case 320:
+     	     if(VDisplay == 200)      ModeIndex = ModeIndex_320x200[Depth];
+	     else if(VDisplay == 240) ModeIndex = ModeIndex_320x240[Depth];
+             break;
+     	case 400:
+             if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
+             break;
+	case 512:
+	     if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
+	     break;
+	case 640:
+	     if(VDisplay == 480)      ModeIndex = ModeIndex_640x480[Depth];
+	     else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth];
+	     break;
+	case 800:
+	     if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
+	     break;
+	case 1024:
+	     if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
+	     break;
+	case 1280:
+	     if(VDisplay == 1024) ModeIndex = ModeIndex_1280x1024[Depth];
+	     else if(VDisplay == 768) {
+		if((LCDheight == 768) ||
+		   ((LCDheight == 1024) && (VBFlags & (VB_301|VB_301B|VB_301C|VB_302B)))) {
+		   if(VGAEngine == SIS_300_VGA) {
+		      ModeIndex = ModeIndex_300_1280x768[Depth];
+		   } else {
+		      ModeIndex = ModeIndex_310_1280x768[Depth];
+		   }
+		}
+	     } else if(VDisplay == 960) {
+	        if((LCDheight == 960) ||
+		   ((LCDheight == 1024) && (VBFlags & (VB_301|VB_301B|VB_301C|VB_302B)))) {
+		   ModeIndex = ModeIndex_1280x960[Depth];
+		}
+	     }
+	     break;
+	case 1400:
+	     if(VGAEngine == SIS_315_VGA) {
+	        if(VBFlags & (VB_301B | VB_301C | VB_302B | VB_302LV | VB_302ELV)) {
+		   if(LCDheight != 1200) {
+	              if(VDisplay == 1050) ModeIndex = ModeIndex_1400x1050[Depth];
+		   }
+		}
+	     }
+	     break;
+	case 1600:
+	     if(VBFlags & (VB_301C | VB_302B | VB_302LV | VB_302ELV)) {
+	        if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
+	     }
+	     break;
+      }
+   }
+
+   return ModeIndex;
+}
+
+USHORT
+SiS_GetModeID_TV(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth)
+{
+   USHORT ModeIndex = 0;
+
+   if(VBFlags & VB_CHRONTEL) {
+
+      switch(HDisplay)
+      {
+      	case 512:
+	     if(VGAEngine == SIS_315_VGA) {
+		if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
+	     }
+	     break;
+	case 640:
+	     if(VDisplay == 480)      ModeIndex = ModeIndex_640x480[Depth];
+	     else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth];
+	     break;
+	case 800:
+	     if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
+	     break;
+	case 1024:
+	     if(VGAEngine == SIS_315_VGA) {
+	        if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
+	     }
+	     break;
+      }
+
+   } else if(VBFlags & VB_SISTVBRIDGE) {
+
+      switch(HDisplay)
+      {
+	case 320:
+     	     if(VDisplay == 200)      ModeIndex = ModeIndex_320x200[Depth];
+	     else if(VDisplay == 240) ModeIndex = ModeIndex_320x240[Depth];
+             break;
+        case 400:
+             if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
+             break;
+      	case 512:
+	     if( ((VBFlags & TV_YPBPR) && (VBFlags & (TV_YPBPR525P | TV_YPBPR750P))) ||
+	         (VBFlags & TV_HIVISION) 					     ||
+	         ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL)) ) {
+	        if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
+	     }
+	     break;
+	case 640:
+	     if(VDisplay == 480)      ModeIndex = ModeIndex_640x480[Depth];
+	     else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth];
+	     break;
+	case 720:
+	     if(!(VBFlags & TV_HIVISION)) {
+                if(VDisplay == 480) {
+		   if((VBFlags & TV_YPBPR) || (VBFlags & (TV_NTSC | TV_PALM)))
+                      ModeIndex = ModeIndex_720x480[Depth];
+                } else if(VDisplay == 576) {
+		   if((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL))
+                      ModeIndex = ModeIndex_720x576[Depth];
+                }
+	     }
+             break;
+	case 768:
+	     if(!(VBFlags & TV_HIVISION)) {
+	        if((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL)) {
+          	   if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
+		}
+             }
+	     break;
+	case 800:
+	     if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
+	     else if(VDisplay == 480) {
+	        if(VBFlags & TV_HIVISION) {
+		   ModeIndex = ModeIndex_800x480[Depth];
+		}
+	     }
+	     break;
+	case 1024:
+	     if(VDisplay == 768) {
+		if(VBFlags & (VB_301B|VB_301C|VB_302B|VB_301LV|VB_302LV|VB_302ELV)) {
+		   ModeIndex = ModeIndex_1024x768[Depth];
+		}
+	     } else if(VDisplay == 576) {
+	        if(VBFlags & TV_HIVISION) {
+		   ModeIndex = ModeIndex_1024x576[Depth];
+		}
+	     }
+	     break;
+	case 1280:
+	     if(VBFlags & TV_HIVISION) {
+	        if(VDisplay == 720)       ModeIndex = ModeIndex_1280x720[Depth];
+		else if(VDisplay == 1024) ModeIndex = ModeIndex_1280x1024[Depth];
+	     }
+	     break;
+      }
+   }
+   return ModeIndex;
+}
+
+USHORT
+SiS_GetModeID_VGA2(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth)
+{
+   USHORT ModeIndex = 0;
+
+   if(!(VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) return 0;
+
+   switch(HDisplay)
+   {
+	case 320:
+     	  	if(VDisplay == 200)      ModeIndex = ModeIndex_320x200[Depth];
+	  	else if(VDisplay == 240) ModeIndex = ModeIndex_320x240[Depth];
+          	break;
+     	case 400:
+          	if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
+          	break;
+  	case 512:
+		if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
+		break;
+	case 640:
+		if(VDisplay == 480)      ModeIndex = ModeIndex_640x480[Depth];
+		else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth];
+		break;
+	case 720:
+		if(VDisplay == 480)      ModeIndex = ModeIndex_720x480[Depth];
+		else if(VDisplay == 576) ModeIndex = ModeIndex_720x576[Depth];
+		break;
+	case 768:
+          	if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
+	  	break;
+	case 800:
+		if(VDisplay == 600)      ModeIndex = ModeIndex_800x600[Depth];
+   	        else if(VDisplay == 480) ModeIndex = ModeIndex_800x480[Depth];
+		break;
+	case 848:
+		if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth];
+		break;
+	case 856:
+		if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth];
+		break;
+	case 1024:
+		if(VDisplay == 768)      ModeIndex = ModeIndex_1024x768[Depth];
+		else if(VDisplay == 576) ModeIndex = ModeIndex_1024x576[Depth];
+		break;
+	case 1152:
+	        if(VDisplay == 864)    ModeIndex = ModeIndex_1152x864[Depth];
+		else if(VGAEngine == SIS_300_VGA) {
+		   if(VDisplay == 768) ModeIndex = ModeIndex_1152x768[Depth];
+		}
+		break;
+	case 1280:
+	        if(VDisplay == 768) {
+		   if(VGAEngine == SIS_300_VGA) {
+		      ModeIndex = ModeIndex_300_1280x768[Depth];
+		   } else {
+		      ModeIndex = ModeIndex_310_1280x768[Depth];
+		   }
+		} else if(VDisplay == 1024) ModeIndex = ModeIndex_1280x1024[Depth];
+		else if(VDisplay == 720)    ModeIndex = ModeIndex_1280x720[Depth];
+		else if(VDisplay == 960)    ModeIndex = ModeIndex_1280x960[Depth];
+		break;
+        case 1360:
+	        if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth];
+                break;
+        case 1400:
+		if(VGAEngine == SIS_315_VGA) {
+	           if(VDisplay == 1050) ModeIndex = ModeIndex_1400x1050[Depth];
+		}
+		break;
+	case 1600:
+		if(VGAEngine == SIS_315_VGA) {
+		   if(VBFlags & (VB_301B|VB_301C|VB_302B)) {
+	              if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
+		   }
+		}
+		break;
+   }
+
+   return ModeIndex;
+}
+
+
+/*********************************************/
+/*          HELPER: SetReg, GetReg           */
+/*********************************************/
+
+void
+SiS_SetReg(SISIOADDRESS port, USHORT index, USHORT data)
+{
+   OutPortByte(port,index);
+   OutPortByte(port + 1,data);
+}
+
+void
+SiS_SetRegByte(SISIOADDRESS port, USHORT data)
+{
+   OutPortByte(port,data);
+}
+
+void
+SiS_SetRegShort(SISIOADDRESS port, USHORT data)
+{
+   OutPortWord(port,data);
+}
+
+void
+SiS_SetRegLong(SISIOADDRESS port, ULONG data)
+{
+   OutPortLong(port,data);
+}
+
+UCHAR
+SiS_GetReg(SISIOADDRESS port, USHORT index)
+{
+   OutPortByte(port,index);
+   return(InPortByte(port + 1));
+}
+
+UCHAR
+SiS_GetRegByte(SISIOADDRESS port)
+{
+   return(InPortByte(port));
+}
+
+USHORT
+SiS_GetRegShort(SISIOADDRESS port)
+{
+   return(InPortWord(port));
+}
+
+ULONG
+SiS_GetRegLong(SISIOADDRESS port)
+{
+   return(InPortLong(port));
+}
+
+void
+SiS_SetRegANDOR(SISIOADDRESS Port,USHORT Index,USHORT DataAND,USHORT DataOR)
+{
+  USHORT temp;
+
+  temp = SiS_GetReg(Port,Index);
+  temp = (temp & (DataAND)) | DataOR;
+  SiS_SetReg(Port,Index,temp);
+}
+
+void
+SiS_SetRegAND(SISIOADDRESS Port,USHORT Index,USHORT DataAND)
+{
+  USHORT temp;
+
+  temp = SiS_GetReg(Port,Index);
+  temp &= DataAND;
+  SiS_SetReg(Port,Index,temp);
+}
+
+void
+SiS_SetRegOR(SISIOADDRESS Port,USHORT Index,USHORT DataOR)
+{
+  USHORT temp;
+
+  temp = SiS_GetReg(Port,Index);
+  temp |= DataOR;
+  SiS_SetReg(Port,Index,temp);
+}
+
+/*********************************************/
+/*      HELPER: DisplayOn, DisplayOff        */
+/*********************************************/
+
+void
+SiS_DisplayOn(SiS_Private *SiS_Pr)
+{
+   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x01,0xDF,0x00);
+}
+
+void
+SiS_DisplayOff(SiS_Private *SiS_Pr)
+{
+   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x01,0xDF,0x20);
 }
-#endif
 
-/* ----------------------------------------- */
 
-void SiSRegInit(SiS_Private *SiS_Pr, USHORT BaseAddr)
+/*********************************************/
+/*        HELPER: Init Port Addresses        */
+/*********************************************/
+
+void
+SiSRegInit(SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr)
 {
    SiS_Pr->SiS_P3c4 = BaseAddr + 0x14;
    SiS_Pr->SiS_P3d4 = BaseAddr + 0x24;
@@ -726,10 +1292,62 @@
    SiS_Pr->SiS_VidPlay = BaseAddr + SIS_VIDEO_PLAYBACK;
 }
 
-void
-SiSInitPCIetc(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+/*********************************************/
+/*             HELPER: GetSysFlags           */
+/*********************************************/
+
+static void
+SiS_GetSysFlags(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+   unsigned char cr5f, temp1, temp2;
+
+   /* You should use the macros, not these flags directly */
+
+   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;
+	 }
+      }
+   }
+}
+
+/*********************************************/
+/*         HELPER: Init PCI & Engines        */
+/*********************************************/
+
+static void
+SiSInitPCIetc(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
-   switch(HwDeviceExtension->jChipType) {
+   switch(HwInfo->jChipType) {
    case SIS_300:
    case SIS_540:
    case SIS_630:
@@ -738,7 +1356,7 @@
        *     - RELOCATED VGA IO  (0x20)
        *     - MMIO ENABLE (0x1)
        */
-      SiS_SetReg1(SiS_Pr->SiS_P3c4,0x20,0xa1);
+      SiS_SetReg(SiS_Pr->SiS_P3c4,0x20,0xa1);
       /*  - Enable 2D (0x40)
        *  - Enable 3D (0x02)
        *  - Enable 3D Vertex command fetch (0x10) ?
@@ -752,9 +1370,11 @@
    case SIS_650:
    case SIS_740:
    case SIS_330:
+   case SIS_661:
+   case SIS_741:
    case SIS_660:
    case SIS_760:
-      SiS_SetReg1(SiS_Pr->SiS_P3c4,0x20,0xa1);
+      SiS_SetReg(SiS_Pr->SiS_P3c4,0x20,0xa1);
       /*  - Enable 2D (0x40)
        *  - Enable 3D (0x02)
        *  - Enable 3D vertex command fetch (0x10)
@@ -764,7 +1384,7 @@
       SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0xDA);
       break;
    case SIS_550:
-      SiS_SetReg1(SiS_Pr->SiS_P3c4,0x20,0xa1);
+      SiS_SetReg(SiS_Pr->SiS_P3c4,0x20,0xa1);
       /* No 3D engine ! */
       /*  - Enable 2D (0x40)
        */
@@ -772,38 +1392,33 @@
    }
 }
 
+/*********************************************/
+/*             HELPER: SetLVDSetc            */
+/*********************************************/
+
 void
-SiSSetLVDSetc(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo)
+SiSSetLVDSetc(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
    ULONG   temp;
 
    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;
+   SiS_Pr->SiS_IF_DEF_CONEX = 0;
 
    SiS_Pr->SiS_ChrontelInit = 0;
 
-#if 0
-   if(HwDeviceExtension->jChipType >= SIS_315H) {
-      if((ModeNo == 0x5a) || (ModeNo == 0x5b)) {
-   	 SiS_Pr->SiS_IF_DEF_DSTN = 1;   /* for 550 dstn */
-   	 SiS_Pr->SiS_IF_DEF_FSTN = 1;   /* for fstn */
-      }
-   }
-#endif
-
-   switch(HwDeviceExtension->jChipType) {
+   switch(HwInfo->jChipType) {
 #ifdef SIS300
    case SIS_540:
    case SIS_630:
    case SIS_730:
         /* Check for SiS30x first */
-        temp = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x00);
+        temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
 	if((temp == 1) || (temp == 2)) return;
-      	temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37);
+      	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;
@@ -819,12 +1434,20 @@
    case SIS_650:
    case SIS_740:
    case SIS_330:
+        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;
+   case SIS_661:
+   case SIS_741:
    case SIS_660:
    case SIS_760:
-	temp=SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37);
-      	temp = (temp & 0x0E) >> 1;
+        temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
+      	temp = (temp & 0xe0) >> 5;
       	if((temp >= 2) && (temp <= 3)) SiS_Pr->SiS_IF_DEF_LVDS = 1;
       	if(temp == 3)  SiS_Pr->SiS_IF_DEF_CH70xx = 2;
+	if(temp == 4)  SiS_Pr->SiS_IF_DEF_CONEX = 1;  /* Not yet supported */
         break;
 #endif
    default:
@@ -832,2757 +1455,2793 @@
    }
 }
 
+/*********************************************/
+/*          HELPER: Enable DSTN/FSTN         */
+/*********************************************/
+
 void
-SiSInitPtr(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_SetEnableDstn(SiS_Private *SiS_Pr, int enable)
 {
-   switch(HwDeviceExtension->jChipType) {
-#ifdef SIS315H
-   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, HwDeviceExtension);
-      break;
-#endif
-#ifdef SIS300
-   case SIS_300:
-   case SIS_540:
-   case SIS_630:
-   case SIS_730:
-      InitTo300Pointer(SiS_Pr, HwDeviceExtension);
-      break;
-#endif
-   default:
-      break;
-   }
+   SiS_Pr->SiS_IF_DEF_DSTN = enable ? 1 : 0;
 }
 
 void
-SiSDetermineROMUsage(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, UCHAR *ROMAddr)
+SiS_SetEnableFstn(SiS_Private *SiS_Pr, int enable)
+{
+   SiS_Pr->SiS_IF_DEF_FSTN = enable ? 1 : 0;
+}
+
+/*********************************************/
+/*        HELPER: Determine ROM usage        */
+/*********************************************/
+
+static void
+SiSDetermineROMUsage(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
-   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.
+   UCHAR  *ROMAddr  = HwInfo->pjVirtualRomBase;
+
+   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(HwDeviceExtension->jChipType < SIS_315H) {
+	    SiS_Pr->SiS_UseROM = TRUE;
+	 else
+	    SiS_Pr->SiS_UseROM = FALSE;
+      } else if(HwInfo->jChipType < SIS_315H) {
 #if 0
-        /* 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.
+        /* 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;
+         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;
+	 SiS_Pr->SiS_UseROM = TRUE;
 #endif
-     } else {
-        /* TW: 315/330 series stick to the standard */
-	SiS_Pr->SiS_UseROM = TRUE;
-     }
+      } else {
+         /* 315/330 series stick to the standard */
+	 SiS_Pr->SiS_UseROM = TRUE;
+      }
    } else SiS_Pr->SiS_UseROM = FALSE;
 
 }
 
-/*
- 	=========================================
- 	======== 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: SET SEGMENT REGISTERS      */
+/*********************************************/
+
+static void
+SiS_SetSegRegLower(SiS_Private *SiS_Pr, USHORT value)
 {
-   SISPtr  pSiS = SISPTR(pScrn);
-   UShort  ModeNo=0;
-   
-   SiS_Pr->UseCustomMode = FALSE;
+   USHORT temp;
 
-   if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
+   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);
+}
 
-         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)));
+static void
+SiS_SetSegRegUpper(SiS_Private *SiS_Pr, USHORT value)
+{
+   USHORT temp;
 
-	 return(SiSSetMode(SiS_Pr, HwDeviceExtension, pScrn, ModeNo, TRUE));
+   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);
+}
 
-   }
+static void
+SiS_SetSegmentReg(SiS_Private *SiS_Pr, USHORT value)
+{
+   SiS_SetSegRegLower(SiS_Pr, value);
+   SiS_SetSegRegUpper(SiS_Pr, value);
+}
 
-   ModeNo = SiS_CalcModeIndex(pScrn, mode, pSiS->HaveCustomModes);
-   if(!ModeNo) return FALSE;
+static void
+SiS_ResetSegmentReg(SiS_Private *SiS_Pr)
+{
+   SiS_SetSegmentReg(SiS_Pr, 0);
+}
 
-   xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting standard mode 0x%x\n", ModeNo);
+static void
+SiS_SetSegmentRegOver(SiS_Private *SiS_Pr, USHORT value)
+{
+   USHORT temp = value >> 8;
 
-   return(SiSSetMode(SiS_Pr, HwDeviceExtension, pScrn, ModeNo, TRUE));
+   temp &= 0x07;
+   temp |= (temp << 4);
+   SiS_SetReg(SiS_Pr->SiS_P3c4,0x1d,temp);
+   SiS_SetSegmentReg(SiS_Pr, value);
 }
 
-#ifdef SISDUALHEAD
-/* TW: Set CRT1 mode (used for dual head and MergedFB) */
-BOOLEAN
-SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, ScrnInfoPtr pScrn,
-               DisplayModePtr mode, BOOLEAN IsCustom)
+static void
+SiS_ResetSegmentRegOver(SiS_Private *SiS_Pr)
 {
-   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  ModeNo=0;
-   
-   SiS_Pr->UseCustomMode = FALSE;
-
-   if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
+   SiS_SetSegmentRegOver(SiS_Pr, 0);
+}
 
-         USHORT temptemp = SiS_Pr->CVDisplay;
+static void
+SiS_ResetSegmentRegisters(SiS_Private *SiS_Pr,PSIS_HW_INFO HwInfo)
+{
+   if((IS_SIS65x) || (HwInfo->jChipType >= SIS_661)) {
+      SiS_ResetSegmentReg(SiS_Pr);
+      SiS_ResetSegmentRegOver(SiS_Pr);
+   }
+}
 
-         if(SiS_Pr->CModeFlag & DoubleScanMode)     temptemp >>= 1;
-         else if(SiS_Pr->CInfoFlag & InterlaceMode) temptemp <<= 1;
+/*********************************************/
+/*             HELPER: GetVBType             */
+/*********************************************/
 
-         xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
-	 	"Setting custom mode %dx%d on CRT1\n",
-	 	SiS_Pr->CHDisplay, temptemp);
-	 ModeNo = 0xfe;
+void
+SiS_GetVBType(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+  USHORT flag=0, rev=0, nolcd=0;
 
-   } else {
+  SiS_Pr->SiS_VBType = 0;
 
-         ModeNo = SiS_CalcModeIndex(pScrn, mode, pSiS->HaveCustomModes);
-         if(!ModeNo) return FALSE;
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) return;
 
-         xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
-	 	"Setting standard mode 0x%x on CRT1\n", ModeNo);
-   }
+  flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
 
-   SiSInitPtr(SiS_Pr, HwDeviceExtension);
+  if(flag > 3) return;
 
-   SiSRegInit(SiS_Pr, BaseAddr);
+  rev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01);
 
-   SiS_GetSysFlags(SiS_Pr, 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 | VB_NoLCD);
+	if(rev >= 0xE0) {
+	   flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x39);
+	   if(flag == 0xff)
+	      SiS_Pr->SiS_VBType |= VB_SIS302LV;
+	   else
+	      SiS_Pr->SiS_VBType |= VB_SIS302ELV;
+	} else {
+	   SiS_Pr->SiS_VBType |= VB_SIS301LV;
+	}
+     }
+  }
+}
 
-   SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
+/*********************************************/
+/*            HELPER: GetDRAMSize            */
+/*********************************************/
 
-   SiSInitPCIetc(SiS_Pr, HwDeviceExtension);
+#ifndef LINUX_XF86
+static ULONG
+GetDRAMSize(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+  ULONG   AdapterMemorySize = 0;
+#ifdef SIS315H
+  USHORT  counter;
+#endif
 
-   SiSSetLVDSetc(SiS_Pr, HwDeviceExtension, ModeNo);
+  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;
 
-   SiSDetermineROMUsage(SiS_Pr, HwDeviceExtension, ROMAddr);
+  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;
 
-   /* We don't clear the buffer under X */
-   SiS_Pr->SiS_flag_clearbuffer = 0;
+  case SIS_550:
+  case SIS_650:
+  case SIS_740:
+  	counter = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x3F;
+      	counter++;
+      	AdapterMemorySize = counter * 4;
+      	AdapterMemorySize *= (1024*1024);
+	break;
 
-   /* 1.Openkey */
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86);
+  case SIS_661:
+  case SIS_741:
+  case SIS_660:
+  case SIS_760:
+        counter = (SiS_GetReg(SiS_Pr->SiS_P3c4,0x79) & 0xf0) >> 4;
+	AdapterMemorySize = 1 << counter;
+      	AdapterMemorySize *= (1024*1024);
+        break;
+#endif
 
-   SiS_UnLockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr);
+#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;
+  }
 
-   /* 2.Get ModeID Table  */
-   if(!SiS_Pr->UseCustomMode) {
-      temp = SiS_SearchModeID(SiS_Pr, ROMAddr,&ModeNo,&ModeIdIndex);
-      if(temp == 0)  return(0);
-   } else {
-      ModeIdIndex = 0;
-   }
+  return AdapterMemorySize;
+}
+#endif
 
-   /* TW: Determine VBType (301,301B,301LV,302B,302LV) */
-   SiS_GetVBType(SiS_Pr, BaseAddr,HwDeviceExtension);
+/*********************************************/
+/*           HELPER: Check RAM size          */
+/*********************************************/
 
-   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);
-      }
-   }
+#ifndef LINUX_XF86
+static BOOLEAN
+SiS_CheckMemorySize(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+                    USHORT ModeNo, USHORT ModeIdIndex)
+{
+  USHORT memorysize,modeflag;
+  ULONG  temp;
 
-   /* 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(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(HwDeviceExtension->jChipType >= SIS_315H) {
-      if(SiS_GetReg1(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;
-         }
-      }
+  memorysize = modeflag & MemoryInfoFlag;
+  memorysize >>= MemorySizeShift;		/* Get required memory size */
+  memorysize++;
 
-      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 = GetDRAMSize(SiS_Pr, HwInfo);       	/* Get adapter memory size (in MB) */
+  temp /= (1024*1024);
 
-   /* Set mode on CRT1 */
-   SiS_SetCRT1Group(SiS_Pr, ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex,BaseAddr);
+  if(temp < memorysize) return(FALSE);
+  else return(TRUE);
+}
+#endif
 
-   /* SetPitch: Adapt to virtual size & position */
-   SiS_SetPitchCRT1(SiS_Pr, pScrn, BaseAddr);
+/*********************************************/
+/*           HELPER: Get DRAM type           */
+/*********************************************/
 
-   if(pSiS->DualHeadMode) {
-      pSiSEnt->CRT1ModeNo = ModeNo;
-      pSiSEnt->CRT1DMode = mode;
-   }
+#ifdef SIS315H
+static UCHAR
+SiS_Get310DRAMType(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+   UCHAR data, temp;
 
-   if(SiS_Pr->UseCustomMode) {
-      SiS_Pr->CRT1UsesCustomMode = TRUE;
-      SiS_Pr->CSRClock_CRT1 = SiS_Pr->CSRClock;
-      SiS_Pr->CModeFlag_CRT1 = SiS_Pr->CModeFlag;
+   if(*SiS_Pr->pSiS_SoftSetting & SoftDRAMType) {
+     data = *SiS_Pr->pSiS_SoftSetting & 0x03;
    } else {
-      SiS_Pr->CRT1UsesCustomMode = FALSE;
+     if(HwInfo->jChipType >= SIS_661) {
+        data = SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0x07;
+     } else if(IS_SIS550650740) {
+        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_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0x30;
+	      switch(temp) {
+	      case 0x00: data = 1; break;
+	      case 0x10: data = 3; break;
+	      case 0x20: data = 3; break;
+	      case 0x30: data = 2; break;
+	      }
+	   } else {
+	      data = 0;
+	   }
+	}
+     }
    }
 
-   /* We have to 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;
-	 SiSBIOSSetModeCRT2(SiS_Pr, HwDeviceExtension, pSiSEnt->pScrn_1,
-			    pSiSEnt->CRT2DMode, pSiSEnt->CRT2IsCustom);
-	 SiS_Pr->UseCustomMode = backupcustom;
-      }
-   }
-
-   /* Warning: From here, the custom mode entries in SiS_Pr are
-    * possibly overwritten
-    */
-
-   SiS_HandleCRT1(SiS_Pr);
+   return data;
+}
 
-   SiS_StrangeStuff(SiS_Pr, HwDeviceExtension);
+USHORT
+SiS_GetMCLK(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+  USHORT index;
 
-   SiS_DisplayOn(SiS_Pr);
-   SiS_SetReg3(SiS_Pr->SiS_P3c6,0xFF);
+  index = SiS_Get310DRAMType(SiS_Pr, HwInfo);
+  if(HwInfo->jChipType >= SIS_661) {
+     return(SiS_Pr->SiS_MCLKData_0[index].CLOCK);
+  } else if(index >= 4) {
+     index -= 4;
+     return(SiS_Pr->SiS_MCLKData_1[index].CLOCK);
+  } else {
+     return(SiS_Pr->SiS_MCLKData_0[index].CLOCK);
+  }
+}
+#endif
 
-   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);
-      }
-   }
+/*********************************************/
+/*           HELPER: ClearBuffer             */
+/*********************************************/
 
-   /* Backup/Set ModeNo in BIOS scratch area */
-   SiS_GetSetModeID(pScrn,ModeNo);
+#ifndef LINUX_XF86
+static void
+SiS_ClearBuffer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
+{
+  UCHAR   *VideoMemoryAddress = HwInfo->pjVideoMemoryAddress;
+  ULONG   AdapterMemorySize  = (ULONG)HwInfo->ulVideoMemorySize;
+  USHORT  *pBuffer;
+  int i;
 
-   return TRUE;
+  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
+
+/*********************************************/
+/*           HELPER: SearchModeID            */
+/*********************************************/
 
-/* TW: Set CRT2 mode (used for dual head) */
 BOOLEAN
-SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, ScrnInfoPtr pScrn,
-               DisplayModePtr mode, BOOLEAN IsCustom)
+SiS_SearchModeID(SiS_Private *SiS_Pr, USHORT *ModeNo, USHORT *ModeIdIndex)
 {
-   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;
+   UCHAR VGAINFO = SiS_Pr->SiS_VGAINFO;
 
-   SiS_Pr->UseCustomMode = FALSE;
+   if(*ModeNo <= 0x13) {
 
-   /* Remember: Custom modes for CRT2 are ONLY supported
-    * 		-) on 315/330 series,
-    *           -) on the 301 and 30xB, and
-    *           -) if CRT2 is LCD or VGA
-    */
+      if((*ModeNo) <= 0x05) (*ModeNo) |= 0x01;
 
-   if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
+      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;
+      }
 
-	 ModeNo = 0xfe;
+      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 {
 
-         BOOLEAN havecustommodes = pSiS->HaveCustomModes;
-
-#ifdef SISMERGED
-	 if(pSiS->MergedFB) havecustommodes = pSiS->HaveCustomModes2;
-#endif
-
-         ModeNo = SiS_CalcModeIndex(pScrn, mode, havecustommodes);
-         if(!ModeNo) return FALSE;
+      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;
+}
 
-   /* 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;
+/*********************************************/
+/*            HELPER: GetModePtr             */
+/*********************************************/
 
-      /* 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;
-      }
-   }
+UCHAR
+SiS_GetModePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex)
+{
+   UCHAR index;
 
-   SiSInitPtr(SiS_Pr, HwDeviceExtension);
+   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;
+}
 
-   SiSRegInit(SiS_Pr, BaseAddr);
+/*********************************************/
+/*           HELPER: LowModeTests            */
+/*********************************************/
+
+static BOOLEAN
+SiS_DoLowModeTest(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);
+       }
+    }
+}
 
-   SiS_GetSysFlags(SiS_Pr, HwDeviceExtension);
+static void
+SiS_SetLowModeTest(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_INFO HwInfo)
+{
+    if(SiS_DoLowModeTest(SiS_Pr, ModeNo, HwInfo)) {
+       SiS_Pr->SiS_SetFlag |= LowModeTests;
+    }
+}
 
-   SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
+/*********************************************/
+/*           HELPER: GetColorDepth           */
+/*********************************************/
 
-   SiSInitPCIetc(SiS_Pr, HwDeviceExtension);
+USHORT
+SiS_GetColorDepth(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex)
+{
+  USHORT ColorDepth[6] = { 1, 2, 4, 4, 6, 8};
+  SHORT  index;
+  USHORT modeflag;
 
-   SiSSetLVDSetc(SiS_Pr, HwDeviceExtension, ModeNo);
+  /* 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;
+  }
 
-   SiSDetermineROMUsage(SiS_Pr, HwDeviceExtension, ROMAddr);
+  index = (modeflag & ModeInfoFlag) - ModeEGA;
+  if(index < 0) index = 0;
+  return(ColorDepth[index]);
+}
 
-   /* We don't clear the buffer under X */
-   SiS_Pr->SiS_flag_clearbuffer=0;
+/*********************************************/
+/*             HELPER: GetOffset             */
+/*********************************************/
 
-   if(SiS_Pr->UseCustomMode) {
+USHORT
+SiS_GetOffset(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
+              USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo)
+{
+  USHORT temp,colordepth,infoflag;
 
-      USHORT temptemp = SiS_Pr->CVDisplay;
+  if(SiS_Pr->UseCustomMode) {
+     infoflag = SiS_Pr->CInfoFlag;
+     temp = SiS_Pr->CHDisplay / 16;
+  } else {
+     infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+     temp = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeOffset;
+     temp = SiS_Pr->SiS_ScreenOffset[temp];
+  }
 
-      if(SiS_Pr->CModeFlag & DoubleScanMode)     temptemp >>= 1;
-      else if(SiS_Pr->CInfoFlag & InterlaceMode) temptemp <<= 1;
+  colordepth = SiS_GetColorDepth(SiS_Pr,ModeNo,ModeIdIndex);
 
-      xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
-	  "Setting custom mode %dx%d on CRT2\n",
-	  SiS_Pr->CHDisplay, temptemp);
+  if(infoflag & InterlaceMode) temp <<= 1;
 
-   } else {
+  temp *= colordepth;
 
-      xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
-   	  "Setting standard mode 0x%x on CRT2\n", ModeNo);
+  if( ( ((ModeNo >= 0x26) && (ModeNo <= 0x28)) ||
+        ModeNo == 0x3f ||
+	ModeNo == 0x42 ||
+	ModeNo == 0x45 ) ||
+      (SiS_Pr->UseCustomMode && (SiS_Pr->CHDisplay % 16)) ) {
+     colordepth >>= 1;
+     temp += colordepth;
+  }
 
-   }
+  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, PSIS_HW_INFO HwInfo)
+{
+   UCHAR SRdata;
+   USHORT i;
 
-   /* 2.Get ModeID */
-   if(!SiS_Pr->UseCustomMode) {
-      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  */
 
-   /* 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) {
-         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);
-           }
+      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+         SRdata |= 0x01;
+      }
+      if(HwInfo->jChipType >= SIS_661) {
+         if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
+	    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+               SRdata |= 0x01;          		/* 8 dot clock  */
+            }
+	 }
+      } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+         if(SiS_Pr->SiS_VBType & VB_NoLCD) {
+	    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+               SRdata |= 0x01;          		/* 8 dot clock  */
+            }
 	 }
-	 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);
       }
    }
 
-   /* Get VB information (connectors, connected devices) */
-   if(!SiS_Pr->UseCustomMode) {
-      SiS_GetVBInfo(SiS_Pr, BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,1);
-   } else {
-      /* If this is a custom mode, we don't check the modeflag for CRT2Mode */
-      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_GetReg1(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;
+   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  */
          }
       }
    }
 
-   /* Set mode on CRT2 */
-   switch (HwDeviceExtension->ujVBChipID) {
-     case VB_CHIP_301:
-     case VB_CHIP_301B:
-     case VB_CHIP_301C:
-     case VB_CHIP_301LV:
-     case VB_CHIP_302:
-     case VB_CHIP_302B:
-     case VB_CHIP_302LV:
-        SiS_SetCRT2Group(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_SetCRT2Group(SiS_Pr,BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
-  	}
-        break;
-   }
-
-   SiS_StrangeStuff(SiS_Pr, HwDeviceExtension);
+   SRdata |= 0x20;                			/* screen off  */
 
-   SiS_DisplayOn(SiS_Pr);
-   SiS_SetReg3(SiS_Pr->SiS_P3c6,0xFF);
+   SiS_SetReg(SiS_Pr->SiS_P3c4,0x01,SRdata);
 
-   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);
-	 }
-      }
+   for(i = 2; i <= 4; i++) {
+      SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[i-1];
+      SiS_SetReg(SiS_Pr->SiS_P3c4,i,SRdata);
    }
+}
 
-   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);
-	 }
+/*********************************************/
+/*                  MISC                     */
+/*********************************************/
 
-	 SiS_SetReg1(SiS_Pr->SiS_P3d4,0x38,backupreg);
+static void
+SiS_SetMiscRegs(SiS_Private *SiS_Pr, USHORT StandTableIndex, PSIS_HW_INFO HwInfo)
+{
+   UCHAR Miscdata;
 
-	 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);
+   Miscdata = SiS_Pr->SiS_StandTable[StandTableIndex].MISC;
 
-	 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);
+   if(HwInfo->jChipType < SIS_661) {
+      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+            Miscdata |= 0x0C;
+         }
       }
    }
 
-   /* SetPitch: Adapt to virtual size & position */
-   SiS_SetPitchCRT2(SiS_Pr, pScrn, BaseAddr);
-
-   return TRUE;
+   SiS_SetRegByte(SiS_Pr->SiS_P3c2,Miscdata);
 }
-#endif /* Dualhead */
-#endif /* Linux_XF86 */
 
-#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)
-#endif
+/*********************************************/
+/*                  CRTC                     */
+/*********************************************/
+
+static void
+SiS_SetCRTCRegs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+                USHORT StandTableIndex)
 {
-   ULONG   temp;
-   USHORT  ModeIdIndex,KeepLockReg;
-   UCHAR  *ROMAddr  = HwDeviceExtension->pjVirtualRomBase;
-   USHORT  BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
-   unsigned char backupreg=0, tempr1, tempr2;
+  UCHAR CRTCdata;
+  USHORT i;
 
-#ifndef LINUX_XF86
-   SiS_Pr->UseCustomMode = FALSE;
-   SiS_Pr->CRT1UsesCustomMode = FALSE;
-#endif
-   
-   if(SiS_Pr->UseCustomMode) {
-      ModeNo = 0xfe;
-   }
+  SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);                       /* Unlock CRTC */
 
-   SiSInitPtr(SiS_Pr, HwDeviceExtension);
+  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);
+        }
+     }
+  }
+}
 
-   SiSRegInit(SiS_Pr, BaseAddr);
+/*********************************************/
+/*                   ATT                     */
+/*********************************************/
 
-   SiS_GetSysFlags(SiS_Pr, HwDeviceExtension);
+static void
+SiS_SetATTRegs(SiS_Private *SiS_Pr, USHORT StandTableIndex,
+               PSIS_HW_INFO HwInfo)
+{
+   UCHAR ARdata;
+   USHORT i;
 
-#ifdef LINUX_XF86
-   if(pScrn) SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
-   else
-#endif
-         SiS_Pr->SiS_VGAINFO = 0x11;
-
-#ifdef LINUX_XF86
-#ifdef TWDEBUG
-   xf86DrvMsg(0, X_INFO, "VGAInfo 0x%02x\n", SiS_Pr->SiS_VGAINFO);
-#endif
+   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(HwInfo->jChipType >= SIS_661) {
+	    if(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD)) {
+	       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata=0;
+	    }
+	 } else 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                     */
+/*********************************************/
 
-   SiSInitPCIetc(SiS_Pr, HwDeviceExtension);
-
-   SiSSetLVDSetc(SiS_Pr, HwDeviceExtension, ModeNo);
+static void
+SiS_SetGRCRegs(SiS_Private *SiS_Pr, USHORT StandTableIndex)
+{
+   UCHAR GRdata;
+   USHORT i;
 
-   SiSDetermineROMUsage(SiS_Pr, HwDeviceExtension, ROMAddr);
+   for(i = 0; i <= 0x08; i++) {
+      GRdata = SiS_Pr->SiS_StandTable[StandTableIndex].GRC[i];
+      SiS_SetReg(SiS_Pr->SiS_P3ce,i,GRdata);
+   }
 
-   if(!SiS_Pr->UseCustomMode) {
-      /* TW: Shift the clear-buffer-bit away */
-      ModeNo = ((ModeNo & 0x80) << 8) | (ModeNo & 0x7f);
+   if(SiS_Pr->SiS_ModeType > ModeVGA) {
+      /* 256 color disable */
+      SiS_SetRegAND(SiS_Pr->SiS_P3ce,0x05,0xBF);
    }
+}
 
-#ifdef LINUX_XF86
-   /* We never clear the buffer in X */
-   ModeNo |= 0x8000;
-#endif
+/*********************************************/
+/*          CLEAR EXTENDED REGISTERS         */
+/*********************************************/
 
-   if(ModeNo & 0x8000) {
-     	ModeNo &= 0x7fff;
-     	SiS_Pr->SiS_flag_clearbuffer = 0;
+static void
+SiS_ClearExt1Regs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+  USHORT i;
+
+  for(i = 0x0A; i <= 0x0E; i++) {
+     SiS_SetReg(SiS_Pr->SiS_P3c4,i,0x00);
+  }
+
+  if(HwInfo->jChipType >= SIS_315H) {
+     SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x37,0xFE);
+  }
+}
+
+/*********************************************/
+/*                 RESET VCLK                */
+/*********************************************/
+
+static void
+SiS_ResetCRT1VCLK(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+   if(HwInfo->jChipType >= SIS_315H) {
+      if(HwInfo->jChipType < SIS_661) {
+         if(SiS_Pr->SiS_IF_DEF_LVDS == 0) return;
+      }
    } else {
-     	SiS_Pr->SiS_flag_clearbuffer = 1;
+      if((SiS_Pr->SiS_IF_DEF_LVDS == 0) &&
+         (!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) ) {
+	 return;
+      }
    }
 
-   /* 1.Openkey */
-   KeepLockReg = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x05);
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86);
+   if(HwInfo->jChipType >= SIS_315H) {
+      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x31,0xCF,0x20);
+   } else {
+      SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x20);
+   }
+   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_UnLockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr);
+/*********************************************/
+/*                  SYNC                     */
+/*********************************************/
 
-   if(!SiS_Pr->UseCustomMode) {
+static void
+SiS_SetCRT1Sync(SiS_Private *SiS_Pr, USHORT RefreshRateTableIndex)
+{
+  USHORT sync;
 
-      /* 2.Get ModeID Table  */
-      temp = SiS_SearchModeID(SiS_Pr,ROMAddr,&ModeNo,&ModeIdIndex);
-      if(temp == 0) return(0);
+  if(SiS_Pr->UseCustomMode) {
+     sync = SiS_Pr->CInfoFlag >> 8;
+  } else {
+     sync = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag >> 8;
+  }
 
-   } else {
+  sync &= 0xC0;
+  sync |= 0x2f;
+  SiS_SetRegByte(SiS_Pr->SiS_P3c2,sync);
+}
 
-      ModeIdIndex = 0;
+/*********************************************/
+/*                  CRTC/2                   */
+/*********************************************/
 
-   }
+#ifdef SIS315H
+static void
+SiS_GetLCDACRT1Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+		   USHORT RefreshRateTableIndex, USHORT *ResIndex,
+		   USHORT *DisplayType)
+ {
+  USHORT modeflag = 0;
 
-   /* Determine VBType (301,301B,301LV,302B,302LV) */
-   SiS_GetVBType(SiS_Pr,BaseAddr,HwDeviceExtension);
+  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;
+  }
 
-   /* 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);
+  *ResIndex &= 0x3F;
 
-	 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x02,0x0c);
+  *DisplayType = SiS_Pr->SiS_LCDResInfo;
+  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) *DisplayType += 32;
+  if(modeflag & HalfDCLK)                 *DisplayType += 16;
 
-         backupreg = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
-       } else {
-         backupreg = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x35);
-       }
-   }
-   
-   /* Get VB information (connectors, connected devices) */
-   if(SiS_Pr->UseCustomMode) {
-      SiS_GetVBInfo(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,0);
-   } else {
-      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(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+        *DisplayType = 100;
+	if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) *DisplayType += 2;
+        if(modeflag & HalfDCLK)                 *DisplayType += 1;
+     }
+  } else if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+        *DisplayType = 104;
+	if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) *DisplayType += 2;
+        if(modeflag & HalfDCLK)                 *DisplayType += 1;
+     }
+  }
 
-#ifndef LINUX_XF86
-   /* 3. Check memory size (Kernel framebuffer driver only) */
-   temp = SiS_CheckMemorySize(SiS_Pr,ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex);
-   if(!temp) return(0);
+}
 #endif
 
-   if(HwDeviceExtension->jChipType >= SIS_315H) {
-      if(SiS_GetReg1(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;
-         }
-      }
+static void
+SiS_SetCRT1CRTC(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+                USHORT RefreshRateTableIndex,
+		PSIS_HW_INFO HwInfo)
+{
+  UCHAR  index;
+  USHORT temp,i,j,modeflag;
+#ifdef SIS315H
+  USHORT ResIndex,DisplayType;
+  const SiS_LCDACRT1DataStruct *LCDACRT1Ptr = NULL;
+#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);
-	 }
-      }
-   }
+  SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);		/* unlock cr0-7 */
 
-   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;
-   }
+  if(SiS_Pr->UseCustomMode) {
 
-   /* 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);
-     }
-   }
+     modeflag = SiS_Pr->CModeFlag;
 
-   /* 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_301C:
-     case VB_CHIP_301LV:
-     case VB_CHIP_302:
-     case VB_CHIP_302B:
-     case VB_CHIP_302LV:
-        SiS_SetCRT2Group(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_SetCRT2Group(SiS_Pr,BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
-        break;
+     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]);
      }
-   }
-   
-   SiS_HandleCRT1(SiS_Pr);
 
-   SiS_StrangeStuff(SiS_Pr, HwDeviceExtension);
-   
-   SiS_DisplayOn(SiS_Pr);
-   SiS_SetReg3(SiS_Pr->SiS_P3c6,0xFF);
+     temp = SiS_Pr->CCRT1CRTC[16] & 0xE0;
+     SiS_SetReg(SiS_Pr->SiS_P3c4,0x0E,temp);
 
-   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);
-	 }
-      }
-   }
+     temp = (SiS_Pr->CCRT1CRTC[16] & 0x01) << 5;
+     if(modeflag & DoubleScanMode) temp |= 0x80;
+     SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0xDF,temp);
 
-   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);
-	 }
+  } else {
 
-	 SiS_SetReg1(SiS_Pr->SiS_P3d4,0x38,backupreg);
+     if(ModeNo <= 0x13) {
+        modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+     } else {
+        modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+     }
 
-	 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_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
 
-	 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);
-            }
-	 }
+#ifdef SIS315H
 
-	 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);
-      }
-   }
+        SiS_GetLCDACRT1Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, &ResIndex, &DisplayType);
 
-#ifdef LINUX_XF86
-   if(pScrn) {
-      /* SetPitch: Adapt to virtual size & position */
-      if((ModeNo > 0x13) && (dosetpitch)) {
-         SiS_SetPitch(SiS_Pr, pScrn, BaseAddr);
-      }
+        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;
+        case 100:	  	   LCDACRT1Ptr = Compaq1280x1024_LCDACRT1_1;         break;
+        case 101:		   LCDACRT1Ptr = Compaq1280x1024_LCDACRT1_1_H;       break;
+        case 102:		   LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_2;    break;
+        case 103:		   LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_2_H;  break;
+        case 104:		   LCDACRT1Ptr = Clevo1024x768_LCDACRT1_1;           break;
+        case 105:		   LCDACRT1Ptr = Clevo1024x768_LCDACRT1_1_H;         break;
+        case 106:		   LCDACRT1Ptr = Clevo1024x768_LCDACRT1_2;           break;
+        case 107:		   LCDACRT1Ptr = Clevo1024x768_LCDACRT1_2_H;         break;
+        default:                   LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_1;     break;
+        }
 
-      /* Backup/Set ModeNo in BIOS scratch area */
-      SiS_GetSetModeID(pScrn, ModeNo);
-   }
-#endif
+        for(i=0, j=0; i<=0x07; i++, j++) {
+           SiS_SetReg(SiS_Pr->SiS_P3d4,i,(LCDACRT1Ptr+ResIndex)->CR[j]);
+        }
+        for(i=0x10, j=8; i<=0x12; i++, j++) {
+           SiS_SetReg(SiS_Pr->SiS_P3d4,i,(LCDACRT1Ptr+ResIndex)->CR[j]);
+        }
+        for(i=0x15, j=11; i<=0x16; i++, j++) {
+           SiS_SetReg(SiS_Pr->SiS_P3d4,i,(LCDACRT1Ptr+ResIndex)->CR[j]);
+        }
+        for(i=0x0A, j=13; i<=0x0C; i++, j++) {
+           SiS_SetReg(SiS_Pr->SiS_P3c4,i,(LCDACRT1Ptr+ResIndex)->CR[j]);
+        }
+
+        temp = (LCDACRT1Ptr+ResIndex)->CR[16] & 0xE0;
+        SiS_SetReg(SiS_Pr->SiS_P3c4,0x0E,temp);
+
+        temp = ((LCDACRT1Ptr+ResIndex)->CR[16] & 0x01) << 5;
+        if(modeflag & DoubleScanMode) temp |= 0x80;
+        SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0xDF,temp);
 
-#ifndef LINUX_XF86  /* 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
 
-   return TRUE;
-}
+     } else {
 
-void
-SiS_SetEnableDstn(SiS_Private *SiS_Pr, int enable)
-{
-   SiS_Pr->SiS_IF_DEF_DSTN = enable ? 1 : 0;
+        index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+
+        for(i=0,j=0;i<=07;i++,j++) {
+          SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->SiS_CRT1Table[index].CR[i]);
+        }
+        for(j=0x10;i<=10;i++,j++) {
+          SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->SiS_CRT1Table[index].CR[i]);
+        }
+        for(j=0x15;i<=12;i++,j++) {
+          SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->SiS_CRT1Table[index].CR[i]);
+        }
+        for(j=0x0A;i<=15;i++,j++) {
+          SiS_SetReg(SiS_Pr->SiS_P3c4,j,SiS_Pr->SiS_CRT1Table[index].CR[i]);
+        }
+
+        temp = SiS_Pr->SiS_CRT1Table[index].CR[16] & 0xE0;
+        SiS_SetReg(SiS_Pr->SiS_P3c4,0x0E,temp);
+
+        temp = ((SiS_Pr->SiS_CRT1Table[index].CR[16]) & 0x01) << 5;
+        if(modeflag & DoubleScanMode)  temp |= 0x80;
+        SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0xDF,temp);
+
+     }
+  }
+
+  if(SiS_Pr->SiS_ModeType > ModeVGA) SiS_SetReg(SiS_Pr->SiS_P3d4,0x14,0x4F);
 }
 
-void
-SiS_SetEnableFstn(SiS_Private *SiS_Pr, int enable)
+/*********************************************/
+/*               OFFSET & PITCH              */
+/*********************************************/
+/*  (partly overruled by SetPitch() in XF86) */
+/*********************************************/
+
+static void
+SiS_SetCRT1Offset(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+                  USHORT RefreshRateTableIndex,
+		  PSIS_HW_INFO HwInfo)
 {
-   SiS_Pr->SiS_IF_DEF_FSTN = enable ? 1 : 0;
+   USHORT temp, DisplayUnit, infoflag;
+
+   if(SiS_Pr->UseCustomMode) {
+      infoflag = SiS_Pr->CInfoFlag;
+   } else {
+      infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+   }
+
+   DisplayUnit = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,
+                     	       RefreshRateTableIndex,HwInfo);
+
+   temp = (DisplayUnit >> 8) & 0x0f;
+   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0xF0,temp);
+
+   temp = DisplayUnit & 0xFF;
+   SiS_SetReg(SiS_Pr->SiS_P3d4,0x13,temp);
+
+   if(infoflag & InterlaceMode) DisplayUnit >>= 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, clka, clkb;
 
-#if 0
-  if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x15) & 0x01)) {
-     if((SiS_GetReg1(SiS_Pr->SiS_P3c4,0x15) & 0x0a) ||
-        (SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16) & 0x01)) {
-        SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x63,0x40);
+  if(SiS_Pr->UseCustomMode) {
+     clka = SiS_Pr->CSR2B;
+     clkb = SiS_Pr->CSR2C;
+  } else {
+     index = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
+     if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+        clka = SiS_Pr->SiS_VBVCLKData[index].Part4_A;
+	clkb = SiS_Pr->SiS_VBVCLKData[index].Part4_B;
+     } else {
+        clka = SiS_Pr->SiS_VCLKData[index].SR2B;
+	clkb = SiS_Pr->SiS_VCLKData[index].SR2C;
      }
   }
-#endif
-}
 
-void
-SiS_GetSysFlags(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-   unsigned char cr5f, temp1, temp2;
+  if(HwInfo->jChipType >= SIS_315H) {
+     SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x31,0xCF);
+  } else {
+     SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x00);
+  }
 
-   /* You should use the macros, not these flags directly */
+  SiS_SetReg(SiS_Pr->SiS_P3c4,0x2B,clka);
+  SiS_SetReg(SiS_Pr->SiS_P3c4,0x2C,clkb);
 
-   SiS_Pr->SiS_SysFlags = 0;
-   if(HwDeviceExtension->jChipType == SIS_650) {
-      cr5f = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5f) & 0xf0;
-      SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x5c,0x07);
-      temp1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5c) & 0xf8;
-      SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x5c,0xf8);
-      temp2 = SiS_GetReg1(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_GetReg1(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;
-	 }
-      }
-   }
-}
-
-void
-SiS_StrangeStuff(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-   if((IS_SIS651) || (IS_SISM650)) {
-      SiS_SetReg1(SiS_Pr->SiS_VidCapt, 0x3f, 0x00);   /* Fiddle with capture regs */
-      SiS_SetReg1(SiS_Pr->SiS_VidCapt, 0x00, 0x00);
-      SiS_SetReg1(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 !!! */
-}
-
-void
-SiS_SetCRT1Group(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
-                 USHORT ModeNo,USHORT ModeIdIndex,USHORT BaseAddr)
-{
-  USHORT  StandTableIndex,RefreshRateTableIndex;
-
-  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);
-    }
-  }
-
-  /* 550, 651 */
-  SiS_WhatTheHellIsThis(SiS_Pr,HwDeviceExtension,BaseAddr);
-
-  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_Pr->SiS_SelectCRT2Rate = 0;
-  SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
-
-#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
-
-  if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) {
-     if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-        SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
-     }
-  }
-
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
-	SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
-  }
-
-  RefreshRateTableIndex = SiS_GetRatePtrCRT2(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
-
-  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);
-   BOOLEAN isslavemode = FALSE;
-
-   if( (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) ) ) {
-      isslavemode = TRUE;
-   }
+  USHORT tempax, tempbx;
 
-   /* 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, BaseAddr);
-   }
-   /* 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, 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->scrnPitch2 / 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);
 
-  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 >= 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_GetReg1(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;
-		}
-        }
-  }
+  /* 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  */
+static void
+SiS_SetCRT1FIFO_630(SiS_Private *SiS_Pr, USHORT ModeNo,
+ 		    PSIS_HW_INFO HwInfo,
+                    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
+  };
 
-   } else {
+  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(*ModeIdIndex = 0; ;(*ModeIdIndex)++) {
-         if(SiS_Pr->SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == (*ModeNo)) break;
-         if(SiS_Pr->SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF)      return FALSE;
-      }
+    index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A);
+    index &= 0x07;
+    MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;           /* Get MCLK  */
 
-   }
-   return TRUE;
-}
+    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;
+    }
 
-BOOLEAN
-SiS_SearchVBModeID(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT *ModeNo)
-{
-   USHORT ModeIdIndex;
-   UCHAR VGAINFO = SiS_Pr->SiS_VGAINFO;
+    if(HwInfo->jChipType == SIS_730) {
 
-   if(*ModeNo <= 5) *ModeNo |= 1;
+       do {
+          B = SiS_CalcDelay2(SiS_Pr, FQBQData730[i], HwInfo) * VCLK * colorth;
+	  bl = B / (MCLK * 16);
 
-   for(ModeIdIndex=0; ; ModeIdIndex++) {
-        if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == *ModeNo) break;
-        if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == 0xFF)    return FALSE;
-   }
+          if(B == bl * 16 * MCLK) {
+             bl = bl + 1;
+          } else {
+             bl = bl + 2;
+          }
 
-   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);
-}
+          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);
 
-#ifndef LINUX_XF86
-BOOLEAN
-SiS_CheckMemorySize(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
-                    USHORT ModeNo,USHORT ModeIdIndex)
-{
-  USHORT memorysize,modeflag;
-  ULONG  temp;
+          if(B == bl * 16 * MCLK) {
+             bl = bl + 1;
+          } else {
+             bl = bl + 2;
+          }
 
-  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(bl > 0x13) {
+             if(FQBQData[i+1] == 0xFF) {
+                ThresholdLow = 0x13;
+                break;
+             }
+             i++;
+          } else {
+             ThresholdLow = bl;
+             break;
+          }
+       } while(FQBQData[i] != 0xFF);
+    }
+  }
+  else {
+    if(HwInfo->jChipType == SIS_730) {
+    } else {
+      i = 9;
+    }
+    ThresholdLow = 0x02;
   }
 
-  memorysize = modeflag & MemoryInfoFlag;
-  memorysize >>= MemorySizeShift;			/* Get required memory size */
-  memorysize++;
-
-  temp = GetDRAMSize(SiS_Pr, HwDeviceExtension);       	/* Get adapter memory size */
-  temp /= (1024*1024);   				/* (in MB) */
+  /* Write foreground and background queue */
+  if(HwInfo->jChipType == SIS_730) {
+   
+     data2 = FQBQData730[i];
+     data2 = (data2 & 0xC0) >> 5;
+     data2 <<= 8;
 
-  if(temp < memorysize) return(FALSE);
-  else return(TRUE);
-}
+#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
 
-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;
-}
-
-static void
-SiS_WhatIsThis1a(SiS_Private *SiS_Pr, USHORT somevalue)
-{
-   USHORT temp, tempbl, tempbh;
-
-   tempbl = tempbh = somevalue;
-   temp = SiS_GetReg2(SiS_Pr->SiS_P3cb);
-   temp &= 0xf0;
-   tempbl >>= 4;
-   temp |= tempbl;
-   SiS_SetReg3(SiS_Pr->SiS_P3cb, temp);
-   temp = SiS_GetReg2(SiS_Pr->SiS_P3cd);
-   temp &= 0xf0;
-   tempbh &= 0x0f;
-   temp |= tempbh;
-   SiS_SetReg3(SiS_Pr->SiS_P3cd, temp);
-}
-
-static void
-SiS_WhatIsThis1b(SiS_Private *SiS_Pr, USHORT somevalue)
-{
-   USHORT temp, tempbl, tempbh;
-
-   tempbl = tempbh = somevalue;
-   temp = SiS_GetReg2(SiS_Pr->SiS_P3cb);
-   temp &= 0x0f;
-   tempbl &= 0xf0;
-   temp |= tempbl;
-   SiS_SetReg3(SiS_Pr->SiS_P3cb, temp);
-   temp = SiS_GetReg2(SiS_Pr->SiS_P3cd);
-   temp &= 0x0f;
-   tempbh <<= 4;
-   temp |= tempbh;
-   SiS_SetReg3(SiS_Pr->SiS_P3cd, temp);
-}
-
-static void
-SiS_WhatIsThis2b(SiS_Private *SiS_Pr, USHORT somevalue)
-{
-   SiS_WhatIsThis1a(SiS_Pr, somevalue);
-   SiS_WhatIsThis1b(SiS_Pr, somevalue);
-}
-
-static void
-SiS_WhatIsThis1(SiS_Private *SiS_Pr)
-{
-   SiS_WhatIsThis2b(SiS_Pr, 0);
-}
-
-static void
-SiS_WhatIsThis2a(SiS_Private *SiS_Pr, USHORT somevalue)
-{
-   USHORT temp = somevalue >> 8;
-
-   temp &= 0x07;
-   temp |= (temp << 4);
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1d,temp);
-   SiS_WhatIsThis2b(SiS_Pr, somevalue);
-}
-
-static void
-SiS_WhatIsThis2(SiS_Private *SiS_Pr)
-{
-   SiS_WhatIsThis2a(SiS_Pr, 0);
-}
-
-void
-SiS_WhatTheHellIsThis(SiS_Private *SiS_Pr,PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
-{
-   if(IS_SIS65x) {
-      SiS_WhatIsThis1(SiS_Pr);
-      SiS_WhatIsThis2(SiS_Pr);
-   }
-}
+     /* Write GUI grant timer (PCI config 0xA3) */
+     data2 = FQBQData730[i] << 8;
+     data2 = (data2 & 0x0f00) | ((data2 & 0x3000) >> 8);
+     data2 <<= 20;
 
-void
-SiS_SetSeqRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex)
-{
-   UCHAR SRdata;
-   USHORT i;
+#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
 
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x00,0x03);           	/* Set SR0  */
+  } else {
 
-   SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[0];
+     data2 = FQBQData[i];
+     data2 = (data2 & 0xf0) >> 4;
+     data2 <<= 24;
 
-   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  */
-       }
-     }
-   }
+#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
 
-   SRdata |= 0x20;                			/* screen off  */
+     /* Write GUI grant timer (PCI config 0xA3) */
+     data2 = FQBQData[i];
+     data2 &= 0x0f;
+     data2 <<= 24;
 
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x01,SRdata);
+#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
 
-   for(i = 2; i <= 4; i++) {
-       	SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[i-1];
-     	SiS_SetReg1(SiS_Pr->SiS_P3c4,i,SRdata);
-   }
-}
+  }
 
-void
-SiS_SetMiscRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex)
-{
-   UCHAR Miscdata;
+  /* Write CRT/CPU threshold low, CRT/Engine threshold high */
+  data = ((ThresholdLow & 0x0f) << 4) | 0x0f;
+  SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,data);
 
-   Miscdata = SiS_Pr->SiS_StandTable[StandTableIndex].MISC;
+  data = (ThresholdLow & 0x10) << 1;
+  SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xDF,data);
 
-   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
-        Miscdata |= 0x0C;
-      }
-   }
+  /* What is this? */
+  SiS_SetReg(SiS_Pr->SiS_P3c4,0x3B,0x09);
 
-   SiS_SetReg3(SiS_Pr->SiS_P3c2,Miscdata);
+  /* 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
 
-void
-SiS_SetCRTCRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
-                USHORT StandTableIndex)
+#ifdef SIS315H
+static void
+SiS_SetCRT1FIFO_310(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+                    PSIS_HW_INFO HwInfo)
 {
-  UCHAR CRTCdata;
-  USHORT i;
+  USHORT modeflag;
 
-  SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);                       /* Unlock CRTC */
+  SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x3D,0xFE);  /* disable auto-threshold */
 
-  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(SiS_Pr->UseCustomMode) {
+     modeflag = SiS_Pr->CModeFlag;
+  } else {
+     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
   }
-}
-
-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_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;
+  if(HwInfo->jChipType >= SIS_661) {
+     SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0xAE);
+     SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x09,0xF0);
+     if(ModeNo > 0x13) {
+        if(!(modeflag & HalfDCLK)) {
+	   SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0x34);
+	   if(ModeNo != 0x38) {
+	      SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x3D,0x01);
+	   }
 	}
-      }
-    }
-    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);
+     }
+  } else {
+     if(ModeNo > 0x13) {
+        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_SetGRCRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex)
+/*********************************************/
+/*              MODE REGISTERS               */
+/*********************************************/
+
+static void
+SiS_SetVCLKState(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+                 USHORT ModeNo, USHORT RefreshRateTableIndex,
+                 USHORT ModeIdIndex)
 {
-   UCHAR GRdata;
-   USHORT i;
+  USHORT data, data2=0;
+  USHORT VCLK, index=0;
 
-   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(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;
+     }
+  }
 
-   if(SiS_Pr->SiS_ModeType > ModeVGA) {
-     SiS_SetRegAND(SiS_Pr->SiS_P3ce,0x05,0xBF);			/* 256 color disable */
-   }
-}
+  if(HwInfo->jChipType < SIS_315H) {		/* 300 series */
 
-void
-SiS_ClearExt1Regs(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-  USHORT i;
+     data2 = 0x00;
+     if(VCLK > 150) data2 |= 0x80;
+     SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0x7B,data2);
 
-  for(i = 0x0A; i <= 0x0E; i++) {
-      SiS_SetReg1(SiS_Pr->SiS_P3c4,i,0x00);      /* Clear SR0A-SR0E */
-  }
+     data2 = 0x00;
+     if(VCLK >= 150) data2 |= 0x08;
+     SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xF7,data2);
 
-  /* TW: 330, 650/LVDS/301LV, 740/LVDS */
-  if(HwDeviceExtension->jChipType >= SIS_315H) {
-     SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x37,0xFE);
+  } 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);
+     }
   }
-}
 
-void
-SiS_SetSync(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT RefreshRateTableIndex)
-{
-  USHORT sync;
-  USHORT temp;
+  data2 = 0x03;
+  if((VCLK >= 135) && (VCLK < 160))      data2 = 0x02;
+  else if((VCLK >= 160) && (VCLK < 260)) data2 = 0x01;
+  else if(VCLK >= 260)                   data2 = 0x00;
 
-  if(SiS_Pr->UseCustomMode) {
-     sync = SiS_Pr->CInfoFlag >> 8;
-  } else {
-     sync = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag >> 8;
-  }     
+  if(HwInfo->jChipType == SIS_540) {
+     if((VCLK == 203) || (VCLK < 234)) data2 = 0x02;
+  }
 
-  sync &= 0xC0;
-  temp = 0x2F | sync;
-  SiS_SetReg3(SiS_Pr->SiS_P3c2,temp);           /* Set Misc(3c2) */
+  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 */
+  }
 }
 
-void
-SiS_SetCRT1CRTC(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                USHORT RefreshRateTableIndex,
-		PSIS_HW_DEVICE_INFO HwDeviceExtension)
+static void
+SiS_SetCRT1ModeRegs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+                    USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex)
 {
-  UCHAR  index;
-  USHORT tempah,i,modeflag,j;
+  USHORT data,data2;
+  USHORT infoflag=0,modeflag;
+  USHORT resindex,xres;
 #ifdef SIS315H
-  USHORT temp;
-  USHORT ResIndex,DisplayType;
-  const SiS_LCDACRT1DataStruct *LCDACRT1Ptr = NULL;
+  USHORT data3;
+  ULONG  longdata;
+#if 0
+  resinfo = 0;
+#endif
 #endif
-
-  SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);		/*unlock cr0-7  */
 
   if(SiS_Pr->UseCustomMode) {
      modeflag = SiS_Pr->CModeFlag;
+     infoflag = SiS_Pr->CInfoFlag;
   } else {
-     if(ModeNo <= 0x13) {
-        modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+     if(ModeNo > 0x13) {
+    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+    	infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+#ifdef SIS315H
+#if 0
+	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+#endif
+#endif
      } else {
-        modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
      }
-  }     
-
-  if((SiS_Pr->SiS_IF_DEF_LVDS == 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
-
-#ifdef SIS315H
+  }
 
-     /* LCDA */
+  /* Disable DPMS */
+  SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1F,0x3F);
 
-     temp = SiS_GetLCDACRT1Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
-                       RefreshRateTableIndex,&ResIndex,&DisplayType);
+  if(ModeNo > 0x13) data = infoflag;
+  else data = 0;
 
-     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+ResIndex)->CR[0];
-     SiS_SetReg1(SiS_Pr->SiS_P3d4,0x00,tempah);
-     for(i=0x01,j=1;i<=0x07;i++,j++){
-       tempah = (LCDACRT1Ptr+ResIndex)->CR[j];
-       SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
-     }
-     for(i=0x10,j=8;i<=0x12;i++,j++){
-       tempah = (LCDACRT1Ptr+ResIndex)->CR[j];
-       SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
-     }
-     for(i=0x15,j=11;i<=0x16;i++,j++){
-       tempah =(LCDACRT1Ptr+ResIndex)->CR[j];
-       SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
-     }
-     for(i=0x0A,j=13;i<=0x0C;i++,j++){
-       tempah = (LCDACRT1Ptr+ResIndex)->CR[j];
-       SiS_SetReg1(SiS_Pr->SiS_P3c4,i,tempah);
-     }
-
-     tempah = (LCDACRT1Ptr+ResIndex)->CR[16];
-     tempah &= 0x0E0;
-     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x0E,tempah);
-
-     tempah = (LCDACRT1Ptr+ResIndex)->CR[16];
-     tempah &= 0x01;
-     tempah <<= 5;
-     if(modeflag & DoubleScanMode)  tempah |= 0x080;
-     SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
+  data2 = 0;
+  if(ModeNo > 0x13) {
+     if(SiS_Pr->SiS_ModeType > 0x02) {
+        data2 |= 0x02;
+        data2 |= ((SiS_Pr->SiS_ModeType - ModeVGA) << 2);
+     }
+  }
 
+#ifdef TWDEBUG
+  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,ModeNo,ModeIdIndex);
+     if(ModeNo <= 0x13) {
+      	xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
+     } else {
+      	xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
+     }
+  }
 
-     /* LVDS, 301, 301B, 301LV, 302LV, ... (non-LCDA) */
+  if(HwInfo->jChipType != SIS_300) {
+     data = 0x0000;
+     if(infoflag & InterlaceMode) {
+        if(xres <= 800) data = 0x0020;
+        else if(xres <= 1024) data = 0x0035;
+        else data = 0x0048;
+     }
+     SiS_SetReg(SiS_Pr->SiS_P3d4,0x19,(data & 0x00FF));
+     SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x1a,0xFC,(data >> 8));
+  }
 
-     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]);
+  if(modeflag & HalfDCLK) {
+     SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x01,0x08);
+  }
+
+  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(modeflag & LineCompareOff) {
+        SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xB7,0x08);
+     } else {
+        SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x0F,0xB7);
+     }
+     if(SiS_Pr->SiS_ModeType == ModeEGA) {
+        if(ModeNo > 0x13) {
+  	   SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x0F,0x40);
         }
+     }
+  }
 
-        tempah = SiS_Pr->CCRT1CRTC[16] & 0xE0;
-        SiS_SetReg1(SiS_Pr->SiS_P3c4,0x0E,tempah);
+#ifdef SIS315H
+  /* 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) >> 1;
+	if(!data3) data3++;
+	data2 /= data3;
+	if(data2 >= 0x50) {
+	   data &= 0x0f;
+	   data |= 0x50;
+	}
+     }
+     SiS_SetReg(SiS_Pr->SiS_P3c4,0x17,data);
+  }
 
-        tempah = SiS_Pr->CCRT1CRTC[16];
-        tempah &= 0x01;
-        tempah <<= 5;
-        if(modeflag & DoubleScanMode)  tempah |= 0x80;
-        SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0xDF,tempah);
-     
-     
+  /* 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 {
-     
-        index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;  	/* Get index */
-#if 0   /* Not any longer... */     
-        if(HwDeviceExtension->jChipType < SIS_315H) {
-           index &= 0x3F;
-        }
-#endif
+        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;
+	}
 
-        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);
-        }
+	data3 = SiS_GetColorDepth(SiS_Pr,ModeNo,ModeIdIndex) >> 1;
+	if(!data3) data3++;
 
-        tempah = SiS_Pr->SiS_CRT1Table[index].CR[16];
-        tempah &= 0xE0;
-        SiS_SetReg1(SiS_Pr->SiS_P3c4,0x0E,tempah);
+	data2 *= data3;
 
-        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);
+	longdata = SiS_GetMCLK(SiS_Pr, HwInfo) * 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_SetReg(SiS_Pr->SiS_P3c4,0x17,data);
   }
+#endif
 
-  if(SiS_Pr->SiS_ModeType > ModeVGA) SiS_SetReg1(SiS_Pr->SiS_P3d4,0x14,0x4F);
-}
+  data = 0x60;
+  if(SiS_Pr->SiS_ModeType != ModeText) {
+     data ^= 0x60;
+     if(SiS_Pr->SiS_ModeType != ModeEGA) {
+        data ^= 0xA0;
+     }
+  }
+  SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x21,0x1F,data);
 
-BOOLEAN
-SiS_GetLCDACRT1Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-		   USHORT RefreshRateTableIndex,USHORT *ResIndex,
-		   USHORT *DisplayType)
- {
-  USHORT tempbx=0,modeflag=0;
-  USHORT CRT2CRTC=0;
+  SiS_SetVCLKState(SiS_Pr, HwInfo, ModeNo, RefreshRateTableIndex, ModeIdIndex);
 
-  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
+  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);
+     }
+#if 0   /* What is SR0E[D5:6]? */
+     if(HwInfo->jChipType >= SIS_661) {
+        data = 0;
+        if((ModeNo == 6) || ((ModeNo >= 0x0e) && (ModeNo <= 0x13))) {
+	   data |= 0x20;
+	}
+	if(SiS_Pr->SiS_ModeType != ModeVGA) {
+	   if(SiS_Pr->UseCustomMode) {
+              if((xres >= 640) && (SiS_Pr->CVDisplay >= 480)) {
+	         data |= 0x40;
+	      }
+	      if((xres > 1280) && (SiS_Pr->CVDisplay > 1024)) {
+	         data |= 0x60;
+	      }
+	   }
+	} else if(ModeNo > 0x13) {   /* These are in the CRT1 table, and set by CRT1CRTC */
+	   if(resinfo >= SIS_RI_640x480) {
+	      if(resinfo <= SIS_RI_2048x1536) {
+	         data |= 0x40;
+		 if(resinfo > SIS_RI_1280x1024) {
+		    data |= 0x60;
+		    if(resinfo != SIS_RI_1600x1200) {
+		       data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x0e);
+		       data += 0x60;
+		       SiS_SetReg(SiS_Pr->SiS_P3c4,0x0e);
+		       data = 0;
+		    }
+		 }
+	      }
+	      if(resinfo == SIS_RI_1152x864) {
+		 data = 0x40;
+	      }
+	      if(resinfo == SIS_RI_1400x1050) { /* TW */
+		 data = 0x60;
+	      }
+	   }
+	}
+	SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x0e,data);
+     }
+#endif
   }
+#endif
+}
+
+/*********************************************/
+/*                 LOAD DAC                  */
+/*********************************************/
 
-  tempbx = SiS_Pr->SiS_LCDResInfo;
+#if 0
+static void
+SiS_ClearDAC(SiS_Private *SiS_Pr, ULONG port)
+{
+   int i;
 
-  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 32;
-  if(modeflag & HalfDCLK)                 tempbx += 16;
+   OutPortByte(port, 0);
+   port++;
+   for (i=0; i < (256 * 3); i++) {
+      OutPortByte(port, 0);
+   }
+}
+#endif
 
-  *ResIndex = CRT2CRTC & 0x3F;
-  *DisplayType = tempbx;
+static void
+SiS_WriteDAC(SiS_Private *SiS_Pr, SISIOADDRESS DACData, USHORT shiftflag,
+             USHORT dl, USHORT ah, USHORT al, USHORT dh)
+{
+  USHORT temp,bh,bl;
 
-  return 1;
+  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_SetRegByte(DACData,(USHORT)dh);
+  SiS_SetRegByte(DACData,(USHORT)bh);
+  SiS_SetRegByte(DACData,(USHORT)bl);
 }
 
-/* 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)
+SiS_LoadDAC(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+            USHORT ModeNo, USHORT ModeIdIndex)
 {
-   USHORT temp, DisplayUnit, infoflag;
+   USHORT data,data2;
+   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(SiS_Pr->UseCustomMode) {
-      infoflag = SiS_Pr->CInfoFlag;
+   if(ModeNo <= 0x13) {
+      data = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
    } else {
-      infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+      if(SiS_Pr->UseCustomMode) {
+	 data = SiS_Pr->CModeFlag;
+      } else {
+         data = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+      }
    }
-   
-   DisplayUnit = SiS_GetOffset(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
-                     RefreshRateTableIndex,HwDeviceExtension);		     
 
-   temp = (DisplayUnit >> 8) & 0x0f;
-   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0xF0,temp);
-
-   temp = DisplayUnit & 0xFF;
-   SiS_SetReg1(SiS_Pr->SiS_P3d4,0x13,temp);
-
-   if(infoflag & InterlaceMode) DisplayUnit >>= 1;
+   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;
+      }
+   }
 
-   DisplayUnit <<= 5;
-   temp = (DisplayUnit & 0xff00) >> 8;
-   if (DisplayUnit & 0xff) temp++;
-   temp++;
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x10,temp);
+   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 */
+   }
 }
 
-/* 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)
+/*********************************************/
+/*         SET CRT1 REGISTER GROUP           */
+/*********************************************/
+
+static void
+SiS_SetCRT1Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+                 USHORT ModeNo, USHORT ModeIdIndex)
 {
-   USHORT index;
+  USHORT  StandTableIndex,RefreshRateTableIndex;
 
-   /* 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_Pr->SiS_CRT1Mode = ModeNo;
+  StandTableIndex = SiS_GetModePtr(SiS_Pr, ModeNo, ModeIdIndex);
+  if(SiS_Pr->SiS_SetFlag & LowModeTests) {
+     if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchCRT2)) {
+        SiS_DisableBridge(SiS_Pr, HwInfo);
+     }
+  }
+
+  SiS_ResetSegmentRegisters(SiS_Pr, HwInfo);
+
+  SiS_SetSeqRegs(SiS_Pr, StandTableIndex, HwInfo);
+  SiS_SetMiscRegs(SiS_Pr, StandTableIndex, HwInfo);
+  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);
+
+  SiS_Pr->SiS_SelectCRT2Rate = 0;
+  SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
 
-   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);
-}
+#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
 
-void
-SiS_SetCRT1VCLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                PSIS_HW_DEVICE_INFO HwDeviceExtension,
-		USHORT RefreshRateTableIndex)
-{
-  USHORT  index=0;
+  if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) {
+     if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+        SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
+     }
+  }
 
-  if(!SiS_Pr->UseCustomMode) {
-     index = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
-	                  RefreshRateTableIndex,HwDeviceExtension);
-  }			  
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+     SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
+  }
 
-  if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) ){
+  RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
 
-    	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x31,0xCF);
+  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+     SiS_Pr->SiS_SetFlag &= ~ProgrammingCRT2;
+  }
 
-    	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(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);
+  }
 
-    	if(HwDeviceExtension->jChipType >= SIS_315H) {
-		SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2D,0x01);
-   	} else {
-    		SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2D,0x80);
-    	}
+#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
 
-  } else {
+  SiS_SetCRT1ModeRegs(SiS_Pr, HwInfo, ModeNo, ModeIdIndex, RefreshRateTableIndex);
 
-	if(HwDeviceExtension->jChipType >= SIS_315H) {
-	    SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x31,0xCF);
-	} else {
-	    SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x00);
-	}
+  SiS_LoadDAC(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
 
-	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);
-  	}	   
+#ifndef LINUX_XF86
+  if(SiS_Pr->SiS_flag_clearbuffer) {
+     SiS_ClearBuffer(SiS_Pr,HwInfo,ModeNo);
+  }
+#endif
 
-    	if(HwDeviceExtension->jChipType >= SIS_315H) {
-	    SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2D,0x01);
-	} else {
-      	    SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2D,0x80);
-        }
+  if(!(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchCRT2 | SetCRT2ToLCDA))) {
+     SiS_WaitRetrace1(SiS_Pr);
+     SiS_DisplayOn(SiS_Pr);
   }
 }
 
-#if 0  /* TW: Not used */
-void
-SiS_IsLowResolution(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+/*********************************************/
+/*            HELPER: ENABLE CRT1            */
+/*********************************************/
+
+static void
+SiS_HandleCRT1(SiS_Private *SiS_Pr)
 {
-  USHORT ModeFlag;
+  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
+}
 
-  SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x0F,0x7F);
+/*********************************************/
+/*         HELPER: SET VIDEO REGISTERS       */
+/*********************************************/
 
-  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);
-    }
-  }
+static void
+SiS_StrangeStuff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+   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 !!! */
 }
-#endif
 
-void
-SiS_SetCRT1ModeRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
-                    USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex)
+/*********************************************/
+/*         XFree86: SET SCREEN PITCH         */
+/*********************************************/
+
+#ifdef LINUX_XF86
+static void
+SiS_SetPitchCRT1(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn)
 {
-  USHORT data,data2,data3;
-  USHORT infoflag=0,modeflag;
-  USHORT resindex,xres;
-#ifdef SIS315H
-  ULONG  longdata;
-#endif  
+   SISPtr pSiS = SISPTR(pScrn);
+   UShort HDisplay = pSiS->scrnPitch >> 3;
 
-  if(SiS_Pr->UseCustomMode) {
-     modeflag = SiS_Pr->CModeFlag;
-     infoflag = SiS_Pr->CInfoFlag;
-  } else {
-     if(ModeNo > 0x13) {
-    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-    	infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
-     } else {
-    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-     }
-  }
+   SiS_SetReg(SiS_Pr->SiS_P3d4,0x13,(HDisplay & 0xFF));
+   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0xF0,(HDisplay>>8));
+}
 
-  SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1F,0x3F); 		/* DAC pedestal */
+static void
+SiS_SetPitchCRT2(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn)
+{
+   SISPtr pSiS = SISPTR(pScrn);
+   UShort HDisplay = pSiS->scrnPitch2 >> 3;
 
-  if(ModeNo > 0x13) data = infoflag;
-  else data = 0;
+    /* 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);
 
-  data2 = 0;
-  if(ModeNo > 0x13) {
-     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  
-  if(data & InterlaceMode) data2 |= 0x20;
-  SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x06,0xC0,data2);
+   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(HDisplay & 0xFF));
+   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0xF0,(HDisplay >> 8));
+}
 
-  if(SiS_Pr->UseCustomMode) {
-     xres = SiS_Pr->CHDisplay;
-  } else {
-     resindex = SiS_GetResInfo(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex);
-     if(ModeNo <= 0x13) {
-      	xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
-     } else {
-      	xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
-     }
-  }
+static void
+SiS_SetPitch(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn)
+{
+   SISPtr pSiS = SISPTR(pScrn);
+   BOOLEAN isslavemode = FALSE;
 
-  if(HwDeviceExtension->jChipType != SIS_300) {
-     data = 0x0000;
-     if(infoflag & InterlaceMode) {
-        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);
-     data2 = (data & 0xFF00) >> 8;
-     SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x1a,0xFC,data2);
-  }
+   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;
+   }
 
-  if(modeflag & HalfDCLK) {
-     SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x01,0x08);
-  }
+   /* 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
 
-  if(HwDeviceExtension->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);
-     }
-     /* 651 BIOS does something for mode 0x12 here */
-  }
+/*********************************************/
+/*                 SiSSetMode()              */
+/*********************************************/
 
-  if(HwDeviceExtension->jChipType != SIS_300) {
-     if(SiS_Pr->SiS_ModeType == ModeEGA) {
-        if(ModeNo > 0x13) {
-  	   SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x0F,0x40);
-        }
-     }
-  }
+#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
+{
+   ULONG   temp;
+   USHORT  ModeIdIndex;
+   UCHAR  *ROMAddr  = HwInfo->pjVirtualRomBase;
+   SISIOADDRESS BaseAddr = HwInfo->ulIOAddress;
+   unsigned char backupreg=0, tempr1, tempr2;
+#ifndef LINUX_XF86
+   USHORT  KeepLockReg;
 
-#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);
-  }
+   SiS_Pr->UseCustomMode = FALSE;
+   SiS_Pr->CRT1UsesCustomMode = FALSE;
+#endif
 
-  /* 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;
-	  }
+   if(SiS_Pr->UseCustomMode) {
+      ModeNo = 0xfe;
+   }
 
-	  data3 = SiS_GetColorDepth(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex);
-	  data3 >>= 1;
+   SiSInitPtr(SiS_Pr, HwInfo);
 
-	  data2 *= data3;
+   SiSRegInit(SiS_Pr, BaseAddr);
 
-	  data3 = SiS_GetMCLK(SiS_Pr,ROMAddr, HwDeviceExtension);
-	  longdata = data3 * 1024;
+   SiS_GetSysFlags(SiS_Pr, HwInfo);
 
-	  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);
-  }
+#ifdef LINUX_XF86
+   if(pScrn) SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
+   else
 #endif
+         SiS_Pr->SiS_VGAINFO = 0x11;
 
-  data = 0x60;
-  if(SiS_Pr->SiS_ModeType != ModeText) {
-      data ^= 0x60;
-      if(SiS_Pr->SiS_ModeType != ModeEGA) {
-          data ^= 0xA0;
-      }
-  }
-  SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x21,0x1F,data);
+   SiSInitPCIetc(SiS_Pr, HwInfo);
 
-  SiS_SetVCLKState(SiS_Pr,ROMAddr,HwDeviceExtension,ModeNo,RefreshRateTableIndex,ModeIdIndex);
+   SiSSetLVDSetc(SiS_Pr, HwInfo);
 
-#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);
-    }
-  }
+   SiSDetermineROMUsage(SiS_Pr, HwInfo);
+
+   if(!SiS_Pr->UseCustomMode) {
+      ModeNo = ((ModeNo & 0x80) << 8) | (ModeNo & 0x7f);
+   }
+
+#ifdef LINUX_XF86
+   /* We never clear the buffer in X */
+   ModeNo |= 0x8000;
 #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 & 0x8000) {
+     	ModeNo &= 0x7fff;
+     	SiS_Pr->SiS_flag_clearbuffer = 0;
+   } else {
+     	SiS_Pr->SiS_flag_clearbuffer = 1;
+   }
 
-  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;
-     }	
-  }
+#ifndef LINUX_XF86
+   KeepLockReg = SiS_GetReg(SiS_Pr->SiS_P3c4,0x05);
+#endif
+   SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86);
 
-  if(HwDeviceExtension->jChipType < SIS_315H) {		/* 300 series */
+   SiS_UnLockCRT2(SiS_Pr, HwInfo);
 
-    data2 = 0x00;
-    if(VCLK > 150) data2 |= 0x80;
-    SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0x7B,data2); 	/* DAC speed */
+   if(!SiS_Pr->UseCustomMode) {
+      if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return FALSE;
+   } else {
+      ModeIdIndex = 0;
+   }
 
-    data2 = 0x00;
-    if(VCLK >= 150) data2 |= 0x08;       	/* VCLK > 150 */
-    SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xF7,data2);
+   SiS_GetVBType(SiS_Pr, HwInfo);
 
-  } else { 						/* 315 series */
+   /* Init/restore some VB registers */
 
-    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);
+   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+      if(HwInfo->jChipType >= SIS_315H) {
+         SiS_UnLockCRT2(SiS_Pr,HwInfo);
+	 if(ROMAddr && SiS_Pr->SiS_UseROM) {
+	    if(HwInfo->jChipType < SIS_330) {
+               temp = ROMAddr[VB310Data_1_2_Offset];
+	       temp |= 0x40;
+	       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp);
+            }
+	    if(HwInfo->jChipType > SIS_330) {
+	       temp = ROMAddr[0x7e];
+	       if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x7b) >= 100) temp |= 0x40;
+	       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp);
+	    }
+	 }
+	 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x32,0x10);
 
-    if(VCLK >= 166) {				/* TW: Was 200, is 166 in 650, 315 and 330 BIOSes */
-       SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1f,0xe7);
-    }
-  }
+	 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x00,0x0c);
 
-  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;
+         backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
+      } else {
+         backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
       }
-      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xF8,data2);  	/* DAC speed */
-  }
-}
+   }
 
-void
-SiS_LoadDAC(SiS_Private *SiS_Pr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
-            UCHAR *ROMAddr,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;
-   const USHORT *table = NULL;
+   /* Get VB information (connectors, connected devices) */
+   SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, (SiS_Pr->UseCustomMode) ? 0 : 1);
+   SiS_SetYPbPr(SiS_Pr, HwInfo);
+   SiS_SetTVMode(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
+   SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
+   SiS_SetLowModeTest(SiS_Pr, ModeNo, 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
-   USHORT tempah,tempch,tempcl,tempdh,tempal,tempbx;
+      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(ModeNo <= 0x13) {
-        data = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+         if(IS_SIS650) {
+	    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);
+	 } else if(IS_SIS661741660760) {
+	    SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
+	    SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
+	    SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x3a,0xef);
+	 }
+      }
+   }
+
+   if(SiS_Pr->UseCustomMode) {
+      SiS_Pr->CRT1UsesCustomMode = TRUE;
+      SiS_Pr->CSRClock_CRT1 = SiS_Pr->CSRClock;
+      SiS_Pr->CModeFlag_CRT1 = SiS_Pr->CModeFlag;
    } else {
-        if(SiS_Pr->UseCustomMode) {
-	   data = SiS_Pr->CModeFlag;
-	} else {
-           data = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- 	}	   
+      SiS_Pr->CRT1UsesCustomMode = FALSE;
    }
 
-#if 0
-   if(!(ds:489 & 0x08)) {
-#endif
+   /* Set mode on CRT1 */
+   if( (SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SetCRT2ToLCDA)) ||
+       (!(SiS_Pr->SiS_VBInfo & SwitchCRT2)) ) {
+      SiS_SetCRT1Group(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
+   }
 
-	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;
+   /* Set mode on CRT2 */
+   if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchCRT2 | SetCRT2ToLCDA)) {
+      if( (SiS_Pr->SiS_VBType & VB_SISVB)    ||
+          (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);
+      }
+   }
 
-	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;
-	}
+   SiS_HandleCRT1(SiS_Pr);
 
-	SiS_SetReg3(DACAddr,0x00);
+   SiS_StrangeStuff(SiS_Pr, HwInfo);
 
-	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;
-	   }
-	}
+   SiS_DisplayOn(SiS_Pr);
+   SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF);
 
-	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
+   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 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
-}
+   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+      if(HwInfo->jChipType >= SIS_315H) {
+         if(HwInfo->jChipType < SIS_661) {
+	    if(SiS_IsVAMode(SiS_Pr,HwInfo)) {
+	       SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01);
+	    } else {
+	       SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x35,0xFE);
+	    }
+	 }
 
-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_SetReg(SiS_Pr->SiS_P3d4,0x38,backupreg);
 
-  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);
-}
+	 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);
 
-#ifndef LINUX_XF86
-static ULONG
-GetDRAMSize(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-  ULONG   AdapterMemorySize = 0;
-#ifdef SIS315H
-  USHORT  counter;
-#endif
+	 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);
+            }
+	 }
 
-  switch(HwDeviceExtension->jChipType) {
-#ifdef SIS315H
-  case SIS_315H:
-  case SIS_315:
-  case SIS_315PRO:
-    	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);
-        break;
+	 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);
+      }
+   }
 
-  case SIS_330:
-    	counter = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
-	AdapterMemorySize = 1 << ((counter & 0xF0) >> 4);
-	counter &= 0x0c;
-	if(counter != 0) {
-		AdapterMemorySize <<= 1;
-	}
-	AdapterMemorySize *= (1024*1024);
-	break;
+#ifdef LINUX_XF86
+   if(pScrn) {
+      /* SetPitch: Adapt to virtual size & position */
+      if((ModeNo > 0x13) && (dosetpitch)) {
+         SiS_SetPitch(SiS_Pr, pScrn);
+      }
 
-  case SIS_550:
-  case SIS_650:
-  case SIS_740:
-  case SIS_660:
-  case SIS_760:
-  	counter = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14) & 0x3F;
-      	counter++;
-      	AdapterMemorySize = counter * 4;
-      	AdapterMemorySize *= (1024*1024);
-	break;
+      /* Backup/Set ModeNo in BIOS scratch area */
+      SiS_GetSetModeID(pScrn, ModeNo);
+   }
 #endif
 
-#ifdef SIS300
-  case SIS_300:
-  case SIS_540:
-  case SIS_630:
-  case SIS_730:
-      	AdapterMemorySize = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14) & 0x3F;
-      	AdapterMemorySize++;
-      	AdapterMemorySize *= (1024*1024);
-	break;
+#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
-  default:
-        break;
-  }
 
-  return AdapterMemorySize;
+   return TRUE;
 }
-#endif
 
-#ifndef LINUX_XF86
-void
-SiS_ClearBuffer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo)
+/*********************************************/
+/*          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)
 {
-  PVOID   VideoMemoryAddress = (PVOID)HwDeviceExtension->pjVideoMemoryAddress;
-  ULONG   AdapterMemorySize  = (ULONG)HwDeviceExtension->ulVideoMemorySize;
-  PUSHORT pBuffer;
-  int i;
+   SISPtr  pSiS = SISPTR(pScrn);
+   UShort  ModeNo=0;
+   
+   SiS_Pr->UseCustomMode = FALSE;
 
-  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);
-    }
-  }
-}
-#endif
+   if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
 
-void
-SiS_DisplayOn(SiS_Private *SiS_Pr)
-{
-   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x01,0xDF,0x00);
-}
+         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)));
 
-void
-SiS_DisplayOff(SiS_Private *SiS_Pr)
-{
-   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x01,0xDF,0x20);
-}
+	 return(SiSSetMode(SiS_Pr, HwInfo, pScrn, ModeNo, TRUE));
 
+   }
 
-/* ========================================== */
-/*  SR CRTC GR */
-void
-SiS_SetReg1(USHORT port, USHORT index, USHORT data)
-{
-   OutPortByte(port,index);
-   OutPortByte(port+1,data);
-}
+   ModeNo = SiS_CalcModeIndex(pScrn, mode, pSiS->VBFlags, pSiS->HaveCustomModes);
+   if(!ModeNo) return FALSE;
 
-/* ========================================== */
-/*  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);
-}
+   xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting standard mode 0x%x\n", ModeNo);
 
-void
-SiS_SetReg3(USHORT port, USHORT data)
-{
-   OutPortByte(port,data);
+   return(SiSSetMode(SiS_Pr, HwInfo, pScrn, ModeNo, TRUE));
 }
 
-void
-SiS_SetReg4(USHORT port, ULONG data)
+/*********************************************/
+/*       XFree86: SiSBIOSSetModeCRT2()       */
+/*           for Dual-Head modes             */
+/*********************************************/
+BOOLEAN
+SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
+               DisplayModePtr mode, BOOLEAN IsCustom)
 {
-   OutPortLong(port,data);
-}
+   ULONG   temp;
+   USHORT  ModeIdIndex;
+   UCHAR  *ROMAddr  = HwInfo->pjVirtualRomBase;
+   SISIOADDRESS BaseAddr = HwInfo->ulIOAddress;
+   UShort  ModeNo   = 0;
+   unsigned char tempr1, tempr2, backupreg=0;
+   SISPtr  pSiS     = SISPTR(pScrn);
+#ifdef SISDUALHEAD
+   SISEntPtr pSiSEnt = pSiS->entityPrivate;
+#endif
 
-void
-SiS_SetReg5(USHORT port, USHORT data)
-{
-   OutPortWord(port,data);
-}
+   SiS_Pr->UseCustomMode = FALSE;
 
-UCHAR SiS_GetReg1(USHORT port, USHORT index)
-{
-   UCHAR   data;
+   /* Remember: Custom modes for CRT2 are ONLY supported
+    * 		-) on 315/330 series,
+    *           -) on the 30x/B/C, and
+    *           -) if CRT2 is LCD or VGA
+    */
 
-   OutPortByte(port,index);
-   data = InPortByte(port+1);
+   if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
 
-   return(data);
-}
+	 ModeNo = 0xfe;
 
-UCHAR
-SiS_GetReg2(USHORT port)
-{
-   UCHAR   data;
+   } else {
+
+         BOOLEAN havecustommodes = pSiS->HaveCustomModes;
 
-   data= InPortByte(port);
+#ifdef SISMERGED
+	 if(pSiS->MergedFB) havecustommodes = pSiS->HaveCustomModes2;
+#endif
 
-   return(data);
-}
+         ModeNo = SiS_CalcModeIndex(pScrn, mode, pSiS->VBFlags, havecustommodes);
+         if(!ModeNo) return FALSE;
 
-ULONG
-SiS_GetReg3(USHORT port)
-{
-   ULONG   data;
+   }
 
-   data = InPortLong(port);
+   SiSRegInit(SiS_Pr, BaseAddr);
 
-   return(data);
-}
+   SiSInitPtr(SiS_Pr, HwInfo);
 
-USHORT
-SiS_GetReg4(USHORT port)
-{
-   ULONG   data;
+   SiS_GetSysFlags(SiS_Pr, HwInfo);
 
-   data = InPortWord(port);
+   SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
 
-   return(data);
-}
+   SiSInitPCIetc(SiS_Pr, HwInfo);
 
-void
-SiS_ClearDAC(SiS_Private *SiS_Pr, ULONG port)
-{
-   int i;
+   SiSSetLVDSetc(SiS_Pr, HwInfo);
 
-   OutPortByte(port, 0);
-   port++;
-   for (i=0; i < (256 * 3); i++) {
-      OutPortByte(port, 0);
+   SiSDetermineROMUsage(SiS_Pr, HwInfo);
+
+   /* Save mode info so we can set it from within SetMode for CRT1 */
+#ifdef SISDUALHEAD
+   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->CRT2CR35 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
+      pSiSEnt->CRT2CR38 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
+#if 0
+      /* 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;
+      }
+#endif      
+      pSiSEnt->CRT2ModeSet = TRUE;
    }
+#endif
+
+   /* We don't clear the buffer under X */
+   SiS_Pr->SiS_flag_clearbuffer=0;
 
-}
+   if(SiS_Pr->UseCustomMode) {
 
-#if 0  /* TW: Unused */
-void
-SiS_SetInterlace(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT RefreshRateTableIndex)
-{
-  ULONG Temp;
-  USHORT data,Temp2;
+      USHORT temptemp = SiS_Pr->CVDisplay;
 
-  if (ModeNo<=0x13) return;
+      if(SiS_Pr->CModeFlag & DoubleScanMode)     temptemp >>= 1;
+      else if(SiS_Pr->CInfoFlag & InterlaceMode) temptemp <<= 1;
 
-  Temp = (ULONG)SiS_GetReg1(SiS_Pr->SiS_P3d4,0x01);
-  Temp++;
-  Temp <<= 3;
+      xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+	  "Setting custom mode %dx%d on CRT2\n",
+	  SiS_Pr->CHDisplay, temptemp);
 
-  if(Temp == 1024) data = 0x0035;
-  else if(Temp == 1280) data = 0x0048;
-  else data = 0x0000;
+   } else {
 
-  Temp2 = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
-  Temp2 &= InterlaceMode;
-  if(Temp2 == 0) data=0x0000;
+      xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+   	  "Setting standard mode 0x%x on CRT2\n", ModeNo);
 
-  SiS_SetReg1(SiS_Pr->SiS_P3d4,0x19,data);
+   }
 
-  Temp = (ULONG)SiS_GetReg1(SiS_Pr->SiS_P3d4,0x1A);
-  Temp = (USHORT)(Temp & 0xFC);
-  SiS_SetReg1(SiS_Pr->SiS_P3d4,0x1A,(USHORT)Temp);
+   SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86);
 
-  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
+   SiS_UnLockCRT2(SiS_Pr, HwInfo);
 
-#ifdef SIS315H
-void
-SiS_SetCRT1FIFO_310(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-  USHORT modeflag;
+   if(!SiS_Pr->UseCustomMode) {
+      if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return FALSE;
+   } else {
+      ModeIdIndex = 0;
+   }
 
-  SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x3D,0xFE);  /* disable auto-threshold */
+   SiS_GetVBType(SiS_Pr, HwInfo);
 
-  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);
-  }
-}
-#endif
+   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+      if(HwInfo->jChipType >= SIS_315H) {
+         SiS_UnLockCRT2(SiS_Pr,HwInfo);
+         if(ROMAddr && SiS_Pr->SiS_UseROM) {
+	    if(HwInfo->jChipType < SIS_330) {
+               temp = ROMAddr[VB310Data_1_2_Offset];
+	       temp |= 0x40;
+               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp);
+            }
+	    if(HwInfo->jChipType > SIS_330) {
+	       temp = ROMAddr[0x7e];
+	       if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x7b) >= 100) temp |= 0x40;
+	       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp);
+	    }
+	 }
+	 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x32,0x10);
 
-#ifdef SIS300
-void
-SiS_SetCRT1FIFO_300(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,PSIS_HW_DEVICE_INFO HwDeviceExtension,
-                    USHORT RefreshRateTableIndex)
-{
-  USHORT  ThresholdLow = 0;
-  USHORT  index, VCLK, MCLK, colorth=0;
-  USHORT  tempah, temp;
+	 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x00,0x0c);
 
-  if(ModeNo > 0x13) {
+         backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
+      } else {
+         backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
+      }
+   }
 
-     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  */
-     }
+   /* 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_SetYPbPr(SiS_Pr, HwInfo);
+   SiS_SetTVMode(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
+   SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
+   SiS_SetLowModeTest(SiS_Pr, ModeNo, HwInfo);
 
-     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;
-     }
+   /* Set mode on CRT2 */
+   if( (SiS_Pr->SiS_VBType & VB_SISVB)    ||
+       (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);
+   }
 
-     index = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x3A);
-     index &= 0x07;
-     MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;           /* Get MCLK  */
+   SiS_StrangeStuff(SiS_Pr, HwInfo);
 
-     tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x35);
-     tempah &= 0xc3;
-     SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x16,0x3c,tempah);
+   SiS_DisplayOn(SiS_Pr);
+   SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF);
 
-     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);
+   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);
+	 }
+      }
+   }
 
-  } else ThresholdLow = 2;
+   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+      if(HwInfo->jChipType >= SIS_315H) {
+         if(HwInfo->jChipType < SIS_661) {
+	    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 low, CRT/Engine threshold high */
-  temp = (ThresholdLow << 4) | 0x0f;
-  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x08,temp);
+	 SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,backupreg);
 
-  temp = (ThresholdLow & 0x10) << 1;
-  if(ModeNo > 0x13) temp |= 0x40;
-  SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0f,0x9f,temp);
+	 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);
 
-  /* What is this? */
-  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x3B,0x09);
+	 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);
+      }
+   }
 
-  /* Write CRT/CPU threshold high */
-  temp = ThresholdLow + 3;
-  if(temp > 0x0f) temp = 0x0f;
-  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x09,temp);
+   /* SetPitch: Adapt to virtual size & position */
+   SiS_SetPitchCRT2(SiS_Pr, pScrn);
+
+   return TRUE;
 }
 
-USHORT
-SiS_CalcDelay(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT VCLK, USHORT colordepth, USHORT MCLK)
+/*********************************************/
+/*       XFree86: SiSBIOSSetModeCRT1()       */
+/*           for Dual-Head modes             */
+/*********************************************/
+
+BOOLEAN
+SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
+                   DisplayModePtr mode, BOOLEAN IsCustom)
 {
-  USHORT tempax, tempbx;
+   SISPtr  pSiS = SISPTR(pScrn);
+   SISIOADDRESS BaseAddr = HwInfo->ulIOAddress;
+   USHORT  ModeIdIndex, ModeNo=0;
+   UCHAR backupreg=0;
+#ifdef SISDUALHEAD
+   SISEntPtr pSiSEnt = pSiS->entityPrivate;
+   UCHAR backupcr30, backupcr31, backupcr38, backupcr35, backupp40d=0;
+   BOOLEAN backupcustom;
+#endif
 
-  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);
-}
+   SiS_Pr->UseCustomMode = FALSE;
 
-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 };
+   if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
 
-  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 };
+         USHORT temptemp = SiS_Pr->CVDisplay;
 
-  const UCHAR ThTiming[] = {  1, 2, 2, 3, 0, 1,  1, 2 };
+         if(SiS_Pr->CModeFlag & DoubleScanMode)     temptemp >>= 1;
+         else if(SiS_Pr->CInfoFlag & InterlaceMode) temptemp <<= 1;
 
-  USHORT tempah, tempal, tempcl, tempbx, temp;
-  ULONG  longtemp;
+         xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+	 	"Setting custom mode %dx%d on CRT1\n",
+	 	SiS_Pr->CHDisplay, temptemp);
+	 ModeNo = 0xfe;
 
-  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);
-}
+   } else {
 
-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
-  };
+         ModeNo = SiS_CalcModeIndex(pScrn, mode, pSiS->VBFlags, pSiS->HaveCustomModes);
+         if(!ModeNo) return FALSE;
 
-  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 standard mode 0x%x on CRT1\n", ModeNo);
+   }
 
-    index = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1A);
-    index &= 0x07;
-    MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;           /* Get MCLK  */
+   SiSInitPtr(SiS_Pr, HwInfo);
 
-    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;
-    }
+   SiSRegInit(SiS_Pr, BaseAddr);
 
-    if(HwDeviceExtension->jChipType == SIS_730) {
-    
-       do {
-          B = SiS_CalcDelay2(SiS_Pr, ROMAddr, FQBQData730[i], HwDeviceExtension) * VCLK * colorth;
-	  bl = B / (MCLK * 16);
+   SiS_GetSysFlags(SiS_Pr, HwInfo);
 
-          if(B == bl * 16 * MCLK) {
-             bl = bl + 1;
-          } else {
-             bl = bl + 2;
-          }
+   SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
 
-          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);
+   SiSInitPCIetc(SiS_Pr, HwInfo);
+
+   SiSSetLVDSetc(SiS_Pr, HwInfo);
+
+   SiSDetermineROMUsage(SiS_Pr, HwInfo);
+
+   /* We don't clear the buffer under X */
+   SiS_Pr->SiS_flag_clearbuffer = 0;
 
-          if(B == bl * 16 * MCLK) {
-             bl = bl + 1;
-          } else {
-             bl = bl + 2;
-          }
+   SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86);
 
-          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_UnLockCRT2(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->UseCustomMode) {
+      if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return FALSE;
+   } else {
+      ModeIdIndex = 0;
+   }
 
-#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);
+   /* Determine VBType */
+   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);
+      }
+   }
+
+   /* 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_SetYPbPr(SiS_Pr, HwInfo);
+   SiS_SetTVMode(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
+   SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
+   SiS_SetLowModeTest(SiS_Pr, ModeNo, HwInfo);
+
+   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
 
-     /* 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          
+      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+         if(IS_SIS650) {
+	    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);
+	 } else if(IS_SIS661741660760) {
+	    SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
+	    SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
+	    SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x3a,0xef);
+	 }
+      }
+   }
 
-  } else {
-  
-     data2 = FQBQData[i];
-     data2 = (data2 & 0xf0) >> 4;
-     data2 <<= 24;
+   /* Set mode on CRT1 */
+   SiS_SetCRT1Group(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
+   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+      SiS_SetCRT2Group(SiS_Pr, HwInfo, ModeNo);
+   }
 
-#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);
+   /* SetPitch: Adapt to virtual size & position */
+   SiS_SetPitchCRT1(SiS_Pr, pScrn);
+
+#ifdef SISDUALHEAD
+   if(pSiS->DualHeadMode) {
+      pSiSEnt->CRT1ModeNo = ModeNo;
+      pSiSEnt->CRT1DMode = mode;
+   }
 #endif
 
-     /* Write GUI grant timer (PCI config 0xA3) */
-     data2 = FQBQData[i];
-     data2 &= 0x0f;
-     data2 <<= 24;
+   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;
+   }
 
-#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);
+   /* Reset CRT2 if changing mode on CRT1 */
+#ifdef SISDUALHEAD
+   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);
+	 backupcr35 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
+	 backupcr38 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
+	 if(SiS_Pr->SiS_VBType & VB_SISVB) {
+	    /* Backup LUT-enable */
+	    if(pSiSEnt->CRT2ModeSet) {
+	       backupp40d = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x0d) & 0x08;
+	    }
+	 }
+	 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,0x35,pSiSEnt->CRT2CR35);
+	    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,0x35,backupcr35);
+	 SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,backupcr38);
+	 if(SiS_Pr->SiS_VBType & VB_SISVB) {
+	    SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0d, ~0x08, backupp40d);
+	 }
+	 SiS_Pr->UseCustomMode = backupcustom;
+      }
+   }
 #endif
-     
-  }
 
-  /* Write CRT/CPU threshold low, CRT/Engine threshold high */
-  data = ((ThresholdLow & 0x0f) << 4) | 0x0f;
-  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x08,data);
+   /* Warning: From here, the custom mode entries in SiS_Pr are
+    * possibly overwritten
+    */
 
-  data = (ThresholdLow & 0x10) << 1;
-  SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xDF,data);
+   SiS_HandleCRT1(SiS_Pr);
 
-  /* What is this? */
-  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x3B,0x09);
+   SiS_StrangeStuff(SiS_Pr, HwInfo);
 
-  /* 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_DisplayOn(SiS_Pr);
+   SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF);
 
-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,
-  };
+   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);
+      }
+   }
 
-  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);
+   /* Backup/Set ModeNo in BIOS scratch area */
+   SiS_GetSetModeID(pScrn,ModeNo);
+
+   return TRUE;
 }
-#endif
+#endif /* Linux_XF86 */
+
 
 #ifdef LINUX_XF86
 BOOLEAN
-SiS_GetPanelID(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_GetPanelID(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
   const USHORT PanelTypeTable300[16] = {
       0xc101, 0xc117, 0x0121, 0xc135, 0xc142, 0xc152, 0xc162, 0xc072,
@@ -3596,65 +4255,68 @@
       0xc111, 0xc122, 0xc133, 0xc144, 0xc155, 0xc166, 0xc177, 0xc188,
       0xc199, 0xc0aa, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
   };
-  USHORT tempax,tempbx,tempah,temp;
+  USHORT tempax,tempbx,temp;
 
-  if(HwDeviceExtension->jChipType < SIS_315H) {
+  if(HwInfo->jChipType < SIS_315H) {
 
-    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);
+     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);
 
   } else {
 
-    tempax = tempah = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1a);
-    tempax &= 0x1e;
-    tempax >>= 1;
-    if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-       if(tempax == 0) {
+     if(HwInfo->jChipType >= SIS_661) return 0;
+
+     tempax = 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_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);
-    }
+        }
+        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_VBType & VB_SISVB) {
+        temp = tempbx & 0x04;
+        SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x39,0xfb,temp);
+     }
 
   }
   return 1;
 }
 #endif
 
+
 /* ================ XFREE86 ================= */
 
 /* Helper functions */
@@ -3691,17 +4353,17 @@
    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;
+      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->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;
@@ -3807,21 +4469,26 @@
    }	
    
    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;
+      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
@@ -3856,7 +4523,7 @@
    return 1;
 }
 
-/* TW: Build a list of supported modes */
+/* Build a list of supported modes */
 DisplayModePtr
 SiSBuildBuiltInModeList(ScrnInfoPtr pScrn, BOOLEAN includelcdmodes, BOOLEAN isfordvi)
 {
@@ -3879,15 +4546,15 @@
    /* 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;
 
@@ -3895,9 +4562,6 @@
    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      
 
       /* 0x5a (320x240) is a pure FTSN mode, not DSTN! */
       if((!pSiS->FSTN) &&
@@ -4196,6 +4860,8 @@
 	current->name, (float)current->Clock / 1000,
 	current->HDisplay, current->HSyncStart, current->HSyncEnd, current->HTotal,
 	current->VDisplay, current->VSyncStart, current->VSyncEnd, current->VTotal);
+#else
+        (void)VBS;  (void)HBS;  (void)A;
 #endif
 
       i++;
@@ -4205,8 +4871,10 @@
 
    if(!includelcdmodes) return first;
 
-   xf86DrvMsg(0, X_INFO, "Checking database for vendor %x, product %x\n",
-      pSiS->SiS_Pr->CP_Vendor, pSiS->SiS_Pr->CP_Product);
+   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)) {
@@ -4385,78 +5053,106 @@
    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 * 1000 * 1000;
+       return 65 * 1000;
 #endif
     } else {
 #ifdef SIS315H
-       InitTo310Pointer(SiS_Pr, HwDeviceExtension);
+       InitTo310Pointer(SiS_Pr, HwInfo);
 #else
-       return 65 * 1000 * 1000;
+       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 * 1000 * 1000;
+    	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_DEVICE_INFO HwDeviceExtension,
+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;
-    UCHAR  *ROMAddr  = HwDeviceExtension->pjVirtualRomBase;
-    ULONG  temp = 0;
     unsigned char  sr_data, cr_data, cr_data2;
 
-    if(HwDeviceExtension->jChipType < SIS_315H) {
+    if(HwInfo->jChipType < SIS_315H) {
 #ifdef SIS300
-       InitTo300Pointer(SiS_Pr, HwDeviceExtension);
+       InitTo300Pointer(SiS_Pr, HwInfo);
 #else
        return FALSE;
 #endif
     } else {
 #ifdef SIS315H
-       InitTo310Pointer(SiS_Pr, HwDeviceExtension);
+       InitTo310Pointer(SiS_Pr, HwInfo);
 #else
        return FALSE;
 #endif
     }
 
-    temp = SiS_SearchModeID(SiS_Pr, ROMAddr, &ModeNo, &ModeIdIndex);
-    if(!temp) return FALSE;
+    if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return FALSE;
 
     RefreshRateTableIndex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
     RefreshRateTableIndex += (rateindex - 1);
@@ -4481,7 +5177,7 @@
 }
 
 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,
@@ -4491,29 +5187,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;
@@ -4660,7 +5354,7 @@
     else
        *sync |= FB_SYNC_HOR_HIGH_ACT;
 		
-    *vmode = FB_VMODE_NONINTERLACED;       
+    *vmode = FB_VMODE_NONINTERLACED;
     if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x0080)
        *vmode = FB_VMODE_INTERLACED;
     else {
diff -urN linux-2.4.25-pre4/drivers/video/sis/init.h linux-2.4.25-pre5/drivers/video/sis/init.h
--- linux-2.4.25-pre4/drivers/video/sis/init.h	2003-11-28 10:26:21.000000000 -0800
+++ linux-2.4.25-pre5/drivers/video/sis/init.h	2004-01-15 12:10:23.000000000 -0800
@@ -2,35 +2,54 @@
 /*
  * Data and prototypes for init.c
  *
- * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
+ * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
  *
- * If distributed as part of the linux kernel, the contents of this file
- * is entirely covered by the GPL.
+ * If distributed as part of the Linux kernel, the following license terms
+ * apply:
  *
- * Otherwise, the following terms apply:
+ * * This program is free software; you can redistribute it and/or modify
+ * * it under the terms of the GNU General Public License as published by
+ * * the Free Software Foundation; either version 2 of the named License,
+ * * or any later version.
+ * *
+ * * This program is distributed in the hope that it will be useful,
+ * * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * * GNU General Public License for more details.
+ * *
+ * * You should have received a copy of the GNU General Public License
+ * * along with this program; if not, write to the Free Software
+ * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
  *
- * 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.
+ * Otherwise, the following license terms apply:
  *
- * 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.
+ * * Redistribution and use in source and binary forms, with or without
+ * * modification, are permitted provided that the following conditions
+ * * are met:
+ * * 1) Redistributions of source code must retain the above copyright
+ * *    notice, this list of conditions and the following disclaimer.
+ * * 2) Redistributions in binary form must reproduce the above copyright
+ * *    notice, this list of conditions and the following disclaimer in the
+ * *    documentation and/or other materials provided with the distribution.
+ * * 3) All advertising materials mentioning features or use of this software
+ * *    must display the following acknowledgement: "This product includes
+ * *    software developed by Thomas Winischhofer, Vienna, Austria."
+ * * 4) The name of the author may not be used to endorse or promote products
+ * *    derived from this software without specific prior written permission.
+ * *
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
  *
- * Based on code by Silicon Intergrated Systems
- *
  */
 
 #ifndef _INIT_
@@ -67,6 +86,39 @@
 #endif
 #endif
 
+/* Mode numbers */
+const USHORT  ModeIndex_320x200[]      = {0x59, 0x41, 0x00, 0x4f};
+const USHORT  ModeIndex_320x240[]      = {0x50, 0x56, 0x00, 0x53};
+const USHORT  ModeIndex_320x240_FSTN[] = {0x5a, 0x5b, 0x00, 0x00};  /* FSTN */
+const USHORT  ModeIndex_400x300[]      = {0x51, 0x57, 0x00, 0x54};
+const USHORT  ModeIndex_512x384[]      = {0x52, 0x58, 0x00, 0x5c};
+const USHORT  ModeIndex_640x400[]      = {0x2f, 0x5d, 0x00, 0x5e};
+const USHORT  ModeIndex_640x480[]      = {0x2e, 0x44, 0x00, 0x62};
+const USHORT  ModeIndex_720x480[]      = {0x31, 0x33, 0x00, 0x35};
+const USHORT  ModeIndex_720x576[]      = {0x32, 0x34, 0x00, 0x36};
+const USHORT  ModeIndex_768x576[]      = {0x5f, 0x60, 0x00, 0x61};
+const USHORT  ModeIndex_800x480[]      = {0x70, 0x7a, 0x00, 0x76};
+const USHORT  ModeIndex_800x600[]      = {0x30, 0x47, 0x00, 0x63};
+const USHORT  ModeIndex_848x480[]      = {0x39, 0x3b, 0x00, 0x3e};
+const USHORT  ModeIndex_856x480[]      = {0x3f, 0x42, 0x00, 0x45};
+const USHORT  ModeIndex_1024x768[]     = {0x38, 0x4a, 0x00, 0x64};
+const USHORT  ModeIndex_1024x576[]     = {0x71, 0x74, 0x00, 0x77};
+const USHORT  ModeIndex_1024x600[]     = {0x20, 0x21, 0x00, 0x22};  /* 300 series only */
+const USHORT  ModeIndex_1280x1024[]    = {0x3a, 0x4d, 0x00, 0x65};
+const USHORT  ModeIndex_1280x960[]     = {0x7c, 0x7d, 0x00, 0x7e};
+const USHORT  ModeIndex_1152x768[]     = {0x23, 0x24, 0x00, 0x25};  /* 300 series only */
+const USHORT  ModeIndex_1152x864[]     = {0x29, 0x2a, 0x00, 0x2b};
+const USHORT  ModeIndex_300_1280x768[] = {0x55, 0x5a, 0x00, 0x5b};
+const USHORT  ModeIndex_310_1280x768[] = {0x23, 0x24, 0x00, 0x25};
+const USHORT  ModeIndex_1280x720[]     = {0x79, 0x75, 0x00, 0x78};
+const USHORT  ModeIndex_1360x768[]     = {0x48, 0x4b, 0x00, 0x4e};
+const USHORT  ModeIndex_300_1360x1024[]= {0x67, 0x6f, 0x00, 0x72};  /* 300 series, BARCO only */
+const USHORT  ModeIndex_1400x1050[]    = {0x26, 0x27, 0x00, 0x28};  /* 315 series only */
+const USHORT  ModeIndex_1600x1200[]    = {0x3c, 0x3d, 0x00, 0x66};
+const USHORT  ModeIndex_1920x1440[]    = {0x68, 0x69, 0x00, 0x6b};
+const USHORT  ModeIndex_300_2048x1536[]= {0x6c, 0x6d, 0x00, 0x00};
+const USHORT  ModeIndex_310_2048x1536[]= {0x6c, 0x6d, 0x00, 0x6e};
+
 const USHORT SiS_DRAMType[17][5]={
 	{0x0C,0x0A,0x02,0x40,0x39},
 	{0x0D,0x0A,0x01,0x40,0x48},
@@ -643,6 +695,14 @@
  }
 };
 
+/**************************************************************/
+/* SIS VIDEO BRIDGE ----------------------------------------- */
+/**************************************************************/
+
+static const UCHAR SiS_SoftSetting  = 0x30;   /* RAM setting */
+
+static const UCHAR SiS_OutputSelect = 0x40;
+
 static const UCHAR SiS_NTSCTiming[] = {
 	0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c,
 	0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a,
@@ -742,8 +802,8 @@
 	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_NTSCPhase[]    = {0x21,0xed,0xba,0x08};
+static const UCHAR SiS_PALPhase[]     = {0x2a,0x05,0xe3,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};
@@ -751,6 +811,8 @@
 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 UCHAR SiS_SpecialPhaseM[]= {0x1e,0x83,0x0a,0xe0};
+static const UCHAR SiS_SpecialPhaseJ[]= {0x25,0xd4,0xfd,0x5e};
 
 static const SiS_TVDataStruct  SiS_StPALData[]=
 {
@@ -772,7 +834,8 @@
 /*{  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 */
+ {    1,   1,1170, 821,1270, 520, 686,   0, 686,0xF3,0x00,0x1D,0x20},  /* 1024x768 */
+ {    1,   1,1170, 821,1270, 520, 686,   0, 686,0xF3,0x00,0x1D,0x20}   /* 1024x768 (for NTSC equ) */
 };
 
 static const SiS_TVDataStruct  SiS_StNTSCData[]=
@@ -794,21 +857,11 @@
  {  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
+ {    1,   1,1100, 811,1412, 440,   0, 128,   0,0xee,0x0c,0x22,0x08},    /* 1024x768 (525i) CORRECTED */
+/*{  65,  64,1056, 791,1270, 480, 638,   0,   0,0xEE,0x0C,0x22,0x08} */  /* 1024x768 (525i) */
+ {   65,  64,1056, 791,1270, 480, 455,   0,   0,0x00,0x00,0x00,0x00}     /* 1024x768 (525p) */
 };
 
-
 static const SiS_TVDataStruct  SiS_St2HiTVData[]=
 {
  {    3,   1, 0x348,0x1e3,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
@@ -834,9 +887,35 @@
  {    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_TVDataStruct  SiS_St525pData[]=
+{
+ {    1,   1, 0x6b4,0x20d,0x4f6,0x190,   50,  0, 0x2f8, 0x00,0x00,0x00,0x00},
+ {    1,   1, 0x6b4,0x20d,0x4f6,0x15e,   50,  0, 0x280, 0x00,0x00,0x00,0x00},
+ {    1,   1, 0x6b4,0x20d,0x4f6,0x190,   50,  0, 0x2f8, 0x00,0x00,0x00,0x00},
+ {    1,   1, 0x6b4,0x20d,0x4f6,0x15e,   50,  0, 0x280, 0x00,0x00,0x00,0x00},
+ {    1,   1, 0x6b4,0x20d,0x4f6,0x1e0,    0,  0, 0x2f8, 0x00,0x00,0x00,0x00}
+};
+
+static const SiS_TVDataStruct  SiS_St750pData[]=
+{
+ {    1,   1, 0x672,0x2ee,0x500,0x190,   50,  0, 0x2f8, 0x00,0x00,0x00,0x00},
+ {    1,   1, 0x672,0x2ee,0x500,0x15e,   50,  0, 0x280, 0x00,0x00,0x00,0x00},
+ {    1,   1, 0x672,0x2ee,0x500,0x190,    0,  0, 0x2d0, 0x00,0x00,0x00,0x00},
+ {    1,   1, 0x672,0x2ee,0x500,0x15e,    0,  0, 0x2d0, 0x00,0x00,0x00,0x00},
+ {    1,   1, 0x672,0x2ee,0x500,0x1e0,    0,  0, 0x2f8, 0x00,0x00,0x00,0x00}
+};
+
+static const SiS_TVDataStruct  SiS_Ext750pData[]=
+{
+ {    3,   1, 0x3a7,0x1d6,0x500,0x2a8,   50,  0,     0, 0x00,0x00,0x00,0x00},
+ {   24,   7, 0x3a7,0x1a4,0x500,0x2a8,   50,  0,     0, 0x00,0x00,0x00,0x00},
+ {    3,   1, 0x3a7,0x1d6,0x500,0x2a8,   50,  0,     0, 0x00,0x00,0x00,0x00},
+ {   24,   7, 0x3a7,0x1a4,0x500,0x2a8,   50,  0,     0, 0x00,0x00,0x00,0x00},
+ {   99,  32, 0x320,0x1fe,0x500,0x2d0,   50,  0,     0, 0x00,0x00,0x00,0x00},  /* 640x480   */
+ {    5,   4, 0x5d8,0x29e,0x500,0x2a8,   50,  0,     0, 0x00,0x00,0x00,0x00},  /* 800x600   */
+ {    2,   1, 0x35a,0x1f7,0x4f6,0x1e0,    0,128,     0, 0x00,0x00,0x00,0x00},  /* 720x480   */
+ {   68,  64, 0x55f,0x346,0x500,0x2a8,0x27e,  0,     0, 0x00,0x00,0x00,0x00},  /* 1024x768  */
+};
 
 static const SiS_LCDDataStruct  SiS_LCD1280x960Data[] =
 {
@@ -851,6 +930,11 @@
 	{    1,   1,1800,1000,1800,1000}
 };
 
+/* 1280x768 panel data from Fujitsu 7911 (VL-17WDX8).
+ * Other 1280x768 panels (with clock != 81000, HTxVT != 1688x802)
+ * will be treated as custom panels.
+ */
+
 static const SiS_LCDDataStruct  SiS_StLCD1280x768Data[] =
 {
 	{ 211,  100, 2100,  408, 1688,  802 }, /* These values are *wrong* */
@@ -861,7 +945,7 @@
 	{ 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 */
+	{ 1,      1, 1688,  802, 1688,  802 }  /* That's the only one that is correct */
 };
 
 static const SiS_LCDDataStruct  SiS_ExtLCD1280x768Data[] =
@@ -874,11 +958,11 @@
 	{ 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 */
+	{ 1,      1, 1688,  802, 1688,  802 }  /* That's the only one that is 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},
@@ -986,73 +1070,18 @@
 	{ 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}
-};
+/* *** LCDA *** */
 
-static const SiS_LVDSDataStruct  SiS_LVDS1024x768Data_1[]=
+static const SiS_LVDSDataStruct  SiS_LCDA1024x768Data_1[]=
 {
+	{  960, 438,1344, 806},
+	{  960, 388,1344, 806},
+	{ 1040, 438,1344, 806},
+	{ 1040, 388,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},
@@ -1060,11 +1089,10 @@
 	{ 840, 518,1344, 806},   /* 640x480 */
 	{1050, 638,1344, 806},   /* 800x600 */
 	{1344, 806,1344, 806},   /* 1024x768 */
-	{ 800, 449,1280, 801},
-	{ 800, 525,1280, 813}
+#endif
 };
 
-static const SiS_LVDSDataStruct  SiS_LVDS1024x768Data_2[]=
+static const SiS_LVDSDataStruct  SiS_LCDA1024x768Data_2[]=
 {
 	{1344, 806,1344, 806},
 	{1344, 806,1344, 806},
@@ -1073,77 +1101,48 @@
 	{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 */
+static const SiS_LVDSDataStruct  SiS_LCDA1280x1024Data_1[]=
+{ /* Acer, Compaq */
+	{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}
 };
 
-/* 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},
+static const SiS_LVDSDataStruct  SiS_LCDA1280x1024Data_2[]=
+{ /* Corrected (illegal in Acer, correct in Compaq) */
 	{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},
+	{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_LVDS1400x1050Data_1[]=
-{
+static const SiS_LVDSDataStruct  SiS_LCDA1400x1050Data_1[]=
+{ /* Clevo */
         { 928, 416, 1688,1066},
 	{ 928, 366, 1688,1066},
-	{ 928, 416, 1688,1066},
-	{ 928, 366, 1688,1066},
-	{ 928, 496, 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_LVDS1400x1050Data_2[]=
-{
-        {1688,1066, 1688,1066},
-	{1688,1066, 1688,1066},
+static const SiS_LVDSDataStruct  SiS_LCDA1400x1050Data_2[]=
+{ /* Clevo */
+    	{1688,1066, 1688,1066},
 	{1688,1066, 1688,1066},
 	{1688,1066, 1688,1066},
 	{1688,1066, 1688,1066},
@@ -1151,127 +1150,329 @@
 	{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_LCDA1600x1200Data_1[]=
+{ /* Clevo (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},
+	{2048,1250, 2048,1250}   /* this should be correct */
+#if 0
+	{2160,1250, 2048,1250}   /* ? */
+#endif
 };
 
-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_LCDA1600x1200Data_2[]=
+{ /* Clevo (Temporary data. Seems invalid.) */
+	{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_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}
-};
+/* LVDS SKEW for LCDA */
 
-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_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_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_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_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_LVDSDesStruct SiS_PanelType1210_1[]=
+{  /* 1280x1024 */
+	{ 0 ,    0},
+	{ 0 ,    0},
+	{ 0 ,    0},
+	{ 0 ,    0},
+	{ 0 ,    0},
+	{ 0 ,    0},
+	{ 0 ,    0},
+	{ 0 , 1065},  /* Acer */
+	{ 0 ,    0}
 };
 
-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_LVDSDesStruct SiS_PanelType1210_2[]=
+{  /* 1280x1024; not expanded */
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0}
 };
 
-static const SiS_LVDSDataStruct  SiS_LVDS1152x768Data_2[] =
+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 , 1065}   /* Was 0,0 */
+};
+
+static const SiS_LVDSDesStruct SiS_PanelType1296_2[]=
+{  /* 1400x1050; not 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; not expanded */
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0}
+};
+
+#ifdef SIS315H
+
+/* LCDA CRT1 custom data */
+
+static const SiS_LCDACRT1DataStruct  Compaq1280x1024_LCDACRT1_1[]=
 {
-	{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}
+ {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0xb8,0x1f,
+   0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x06,
+   0x00}},
+ {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0x86,0x1f,
+   0x5e,0x82,0x5d,0x5d,0x87,0x10,0x00,0x06,
+   0x00}},
+ {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0xb8,0x1f,
+   0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x06,
+   0x00}},
+ {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0x86,0x1f,
+   0x5e,0x82,0x5d,0x5d,0x87,0x10,0x00,0x06,
+   0x00}},
+ {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0x08,0x3e,
+   0xe0,0x84,0xdf,0xdf,0x09,0x00,0x00,0x06,
+   0x00}},
+ {{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}}
 };
 
-/* TW: Pass 1:1 data */
-static const SiS_LVDSDataStruct  SiS_LVDSXXXxXXXData_1[]=
+static const SiS_LCDACRT1DataStruct  Compaq1280x1024_LCDACRT1_1_H[]=
 {
-        { 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 ! */
+ {{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,
+   0xbc,0x80,0xbb,0xbb,0xe5,0x00,0x00,0x06,
+   0x01}},
+ {{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,
+   0xbc,0x80,0xbb,0xbb,0xe5,0x00,0x00,0x06,
+   0x01}},
+ {{0x56,0x27,0x27,0x9a,0x30,0x1e,0x08,0x3e,
+   0xe0,0x84,0xdf,0xdf,0x09,0x00,0x00,0x05,
+   0x00}},
+ {{0x60,0x31,0x31,0x84,0x3a,0x88,0x80,0xf0,
+   0x58,0x8c,0x57,0x57,0x81,0x20,0x00,0x01,
+   0x01}},
+ {{0x6e,0x3f,0x3f,0x92,0x48,0x96,0x28,0xf5,
+   0x00,0x84,0xff,0xff,0x29,0x10,0x00,0x01,
+   0x01}}
+};
+
+static const SiS_LCDACRT1DataStruct  Clevo1024x768_LCDACRT1_1[]=
+{
+ {{0x73,0x4f,0x4f,0x97,0x55,0x86,0xc4,0x1f,
+   0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x05,
+   0x00}},
+ {{0x73,0x4f,0x4f,0x97,0x55,0x86,0x97,0x1f,
+   0x60,0x87,0x5d,0x5d,0x83,0x10,0x00,0x05,
+   0x00}},
+ {{0x73,0x4f,0x4f,0x97,0x55,0x86,0xc4,0x1f,
+   0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x05,
+   0x00}},
+ {{0x73,0x4f,0x4f,0x97,0x55,0x86,0x97,0x1f,
+   0x60,0x87,0x5d,0x5d,0x83,0x10,0x00,0x05,
+   0x00}},
+ {{0x73,0x4f,0x4f,0x97,0x55,0x86,0x04,0x3e,
+   0xE2,0x89,0xDf,0xDf,0x05,0x00,0x00,0x05,
+   0x00}},
+ {{0x87,0x63,0x63,0x8B,0x69,0x1A,0x7c,0xf0,
+   0x5A,0x8F,0x57,0x57,0x7D,0x20,0x00,0x26,
+   0x01}},
+ {{0xA3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,
+   0x02,0x88,0xFf,0xFf,0x25,0x10,0x00,0x02,
+   0x01}}
+};
+
+static const SiS_LCDACRT1DataStruct  Clevo1024x768_LCDACRT1_1_H[]=
+{
+ {{0x4b,0x27,0x27,0x8f,0x2b,0x03,0xc4,0x1f,
+   0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x44,
+   0x00}},
+ {{0x4b,0x27,0x27,0x8f,0x2b,0x03,0x97,0x1f,
+   0x60,0x87,0x5D,0x5D,0x83,0x01,0x00,0x44,
+   0x00}},
+ {{0x4b,0x27,0x27,0x8f,0x2b,0x03,0xc4,0x1f,
+   0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x44,
+   0x00}},
+ {{0x4b,0x27,0x27,0x8f,0x2b,0x03,0x97,0x1f,
+   0x60,0x87,0x5D,0x5D,0x83,0x01,0x00,0x44,
+   0x00}},
+ {{0x4b,0x27,0x27,0x8f,0x32,0x1b,0x04,0x3e,
+   0xE2,0x89,0xDf,0xDf,0x05,0x00,0x00,0x45,
+   0x00}},
+ {{0x55,0x31,0x31,0x99,0x46,0x1d,0x7c,0xf0,
+   0x5A,0x8F,0x57,0x57,0x7D,0x20,0x00,0x55,
+   0x01}},
+ {{0x63,0x3F,0x3F,0x87,0x4A,0x93,0x24,0xF5,
+   0x02,0x88,0xFF,0xFF,0x25,0x10,0x00,0x01,
+   0x01}}
+};
+
+static const SiS_LCDACRT1DataStruct  Clevo1024x768_LCDACRT1_2[]=
+{
+ {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x06,
+   0x00}},
+ {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x06,
+   0x00}},
+ {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x06,
+   0x00}},
+ {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x06,
+   0x00}},
+ {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x72,0x88,0xdf,0xdf,0x25,0x30,0x00,0x06,
+   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}}
+};
+
+static const SiS_LCDACRT1DataStruct  Clevo1024x768_LCDACRT1_2_H[]=
+{
+ {{0x7b,0x27,0x27,0x9f,0x46,0x97,0x24,0xbb,
+   0x57,0x8e,0x8f,0x8f,0x25,0x30,0x00,0x01,
+   0x00 }},
+ {{0x7b,0x27,0x27,0x9f,0x46,0x97,0x24,0xbb,
+   0x3e,0x85,0x5d,0x5d,0x25,0x10,0x00,0x01,
+   0x00 }},
+ {{0x7b,0x27,0x27,0x9f,0x46,0x97,0x24,0xbb,
+   0x57,0x8e,0x8f,0x8f,0x25,0x30,0x00,0x01,
+   0x00 }},
+ {{0x7b,0x27,0x27,0x9f,0x46,0x97,0x24,0xbb,
+   0x3e,0x85,0x5d,0x5d,0x25,0x10,0x00,0x01,
+   0x00 }},
+ {{0x7b,0x27,0x27,0x9f,0x46,0x97,0x24,0xbb,
+   0x7f,0x86,0xdf,0xdf,0x25,0x10,0x00,0x01,
+   0x00 }},
+ {{0x71,0x31,0x31,0x95,0x46,0x97,0x24,0xf1,
+   0xbb,0x82,0x57,0x57,0x25,0x10,0x00,0x01,
+   0x01 }},
+ {{0x63,0x3f,0x3f,0x87,0x46,0x97,0x24,0xf5,
+   0x0f,0x86,0xff,0xff,0x25,0x30,0x00,0x01,
+   0x01 }}
+};
+
+#endif  /* 315 */
+
+/**************************************************************/
+/* LVDS ----------------------------------------------------- */
+/**************************************************************/
+
+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_LVDS640x480Data_1[]=
@@ -1298,20 +1499,46 @@
 };
 
 
-static const SiS_LVDSDataStruct  SiS_LVDS1280x960Data_1[]=
+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_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},
+	{ 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_LVDS1280x960Data_2[]=
+static const SiS_LVDSDataStruct  SiS_LVDS1024x768Data_2[]=
 {
 	{1344, 806,1344, 806},
 	{1344, 806,1344, 806},
@@ -1324,57 +1551,112 @@
 	{ 800, 525,1280, 813}
 };
 
-static const SiS_LVDSDataStruct  SiS_LVDS848x480Data_1[]=
+
+static const SiS_LVDSDataStruct  SiS_LVDS1280x1024Data_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 */
+	{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_LVDS848x480Data_2[]=
+static const SiS_LVDSDataStruct  SiS_LVDS1280x1024Data_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 */
+	{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}
 };
 
-/* LCDA */
-
-static const SiS_LVDSDataStruct  SiS_LCDA1400x1050Data_1[]=
-{	/* TW: Might be temporary (invalid) data */
+static const SiS_LVDSDataStruct  SiS_LVDS1400x1050Data_1[]=
+{
         { 928, 416, 1688,1066},
 	{ 928, 366, 1688,1066},
-	{1008, 416, 1688,1066},
-	{1008, 366, 1688,1066},
-	{1200, 530, 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_LCDA1400x1050Data_2[]=
-{	/* TW: Temporary data. Not valid */
+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, 520, 2048,1320},
+	{1088, 470, 2048,1320},
+	{1088, 520, 2048,1320},
+	{1088, 470, 2048,1320},
+	{1088, 600, 2048,1320},
+	{1248, 720, 2048,1320},
+	{1472, 888, 2048,1320},
+	{1728,1144, 2048,1320},
+	{1848,1170, 2048,1320},
+	{2048,1320, 2048,1320}
+#if 0
+        {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}
+#endif
+};
+
+static const SiS_LVDSDataStruct  SiS_LVDS1600x1200Data_2[]=
+{
+        {2048,1320, 2048,1320},
+	{2048,1320, 2048,1320},
+	{2048,1320, 2048,1320},
+	{2048,1320, 2048,1320},
+	{2048,1320, 2048,1320},
+	{2048,1320, 2048,1320},
+	{2048,1320, 2048,1320},
+	{2048,1320, 2048,1320},
+	{2048,1320, 2048,1320},
+	{2048,1320, 2048,1320}
+};
+
+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},
@@ -1386,8 +1668,73 @@
 	{ 800, 525,1280, 813}
 };
 
-static const SiS_LVDSDataStruct  SiS_LCDA1600x1200Data_1[]=
-{	/* TW: Temporary data. Not valid */
+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},
@@ -1399,20 +1746,107 @@
 	{ 800, 525,1280, 813}
 };
 
-static const SiS_LVDSDataStruct  SiS_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}
+/* 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 ! */
+};
+
+/* Custom data for Barco iQ R series */
+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 R series */
+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 */
+};
+
+/* Custom data for Barco iQ G series */
+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 */
+};
+
+/* Custom data for Barco iQ G series */
+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},
+};
+
+/* Custom data for 848x480 parallel panel */
+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 */
+};
+
+/* Custom data for 848x480 parallel panel */
+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 */
 };
 
 static const SiS_LVDSDataStruct  SiS_CHTVUNTSCData[]=
@@ -1437,111 +1871,7 @@
         {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},
-	{ 0 , 0},
-	{ 0 , 0}
-};
-
-static const SiS_LVDSDesStruct SiS_PanelType1076_2[]=
-{  /* 1024x768 */
-	{ 1184, 622 },
-	{ 1184, 597 },
-	{ 1184, 622 },
-	{ 1184, 597 },
-	{ 1152, 622 },
-	{ 1232, 722 },
-	{    0, 0   },
-	{    0, 794 },
-	{    0, 0   }
-};
-
-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 - looks heavily invalid */
-	{ 808 , 740},
-	{ 0   , 715},
-	{ 632 , 740},
-	{ 632 , 715},
-	{ 1307, 780},
-	{ 1387,1157},
-	{ 1499, 924},
-	{ 1627,1052},
-	{ 0 , 0}
-};
-
-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 - BIOS 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}
-};
+/* LVDS Skew */
 
 static const SiS_LVDSDesStruct  SiS_PanelTypeNS_1[]=
 {
@@ -1554,7 +1884,7 @@
 	{ 0,   0},
 	{ 0,   0},
 	{ 0, 806},
-	{ 0, 0 }
+	{ 0,   0}
 };
 
 static const SiS_LVDSDesStruct  SiS_PanelTypeNS_2[] =
@@ -1571,6 +1901,8 @@
 	{ 0 , 0}
 };
 
+/* Chrontel TV Skew */
+
 static const SiS_LVDSDesStruct  SiS_CHTVUNTSCDesData[]=
 {
 	{ 0,   0},
@@ -1615,229 +1947,372 @@
 	{ 0,   0}
 };
 
-static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1320x480_1[] =
+/* CRT1 CRTC data for slave modes */
+
+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_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 }},
+   0x00}},
  {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
    0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
-   0x00 }},
+   0x00}},
  {{0x65,0x4f,0x89,0x54,0x9f,0xc4,0x1f,
    0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
-   0x00 }},
+   0x00}},
  {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
    0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
-   0x00 }},
+   0x00}},
  {{0x65,0x4f,0x89,0x56,0x83,0x04,0x3e,
    0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
-   0x00 }},
+   0x00}},
  {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
    0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
-   0x01 }},
+   0x01}},
  {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e,
    0xe9,0x8b,0xe7,0x04,0x00,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}}
+ {{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}}
+ {{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}}
+ {{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}}
+ {{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}}
+ {{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}}
+ {{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}}
+ {{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}}
+ {{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[] =
@@ -2020,146 +2495,10 @@
    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}}
-};
+/**************************************************************/
+/* COMMON --------------------------------------------------- */
+/**************************************************************/
 
 #define SIS_PL_HSYNCP 0x01
 #define SIS_PL_HSYNCN 0x02
@@ -2176,7 +2515,6 @@
   UCHAR  SyncFlags;
 } SiS_PlasmaModes;
 
-
 typedef struct _SiS_PlasmaTables
 {
    USHORT vendor;
@@ -2283,7 +2621,17 @@
       36000,
        800, 1024, 24,   2,
        600,  625,  1,   2,
-      SIS_PL_HSYNCP | SIS_PL_VSYNCP }
+      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
+   {  "1072x600",		/* 19: Panasonic 1072x600 (sync?) */
+      54100,
+       1072, 1424, 48, 176,
+        600,  628, 16,   1,
+      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
+   {  "848x480",		/* 20: Panasonic 848x480 (sync?) */
+      33070,			/* is 852x480, but we can't use 852 */
+        848, 1068, 20,  40,	/* differs from DDC data, better centered */
+        480,  516,  3,   5,	/* won't work assumingly, because data is % 8 */
+      SIS_PL_HSYNCN | SIS_PL_VSYNCN },
 };
 
 static const SiS_PlasmaTables SiS_PlasmaTable[] = {
@@ -2397,160 +2745,106 @@
      { 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       }
    },
+   { 0x34a9, 1,
+     { 0xa005, 0x0000, 0x0000, 0x0000, 0x0000 },
+     { "TH-42PW*4", "", "", "", "" },
+     "Panasonic TH-42PW5",
+     1,   /* No special modes otherwise; no DVI. */
+     {20|0x40,19|0x40, 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     ,
+       0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
+   },
    { 0x0000 }
 };
 
-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);
-BOOLEAN  SiS_SearchVBModeID(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT *ModeNo);
-void     SiS_IsLowResolution(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
-void     SiS_GetSysFlags(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
-#ifdef SIS315H
-UCHAR    SiS_Get310DRAMType(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
-#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, int enable);
-void     SiS_SetEnableFstn(SiS_Private *SiS_Pr, int enable);
-BOOLEAN  SiS_SearchModeID(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT *ModeNo,USHORT *ModeIdIndex);
-#ifndef LINUX_XF86
-BOOLEAN  SiS_CheckMemorySize(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
-                             USHORT ModeNo,USHORT ModeIdIndex);
-#endif
-UCHAR    SiS_GetModePtr(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex);
-void     SiS_WhatTheHellIsThis(SiS_Private *SiS_Pr,PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr);
-void     SiS_StrangeStuff(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
-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     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);
-
+USHORT  SiS_GetModeID(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth, BOOLEAN FSTN);
+USHORT  SiS_GetModeID_LCD(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth, BOOLEAN FSTN,
+                          USHORT CustomT, int LCDwith, int LCDheight);
+USHORT  SiS_GetModeID_TV(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth);
+USHORT  SiS_GetModeID_VGA2(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth);
+
+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);
+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  	SiS_GetPanelID(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO);
-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 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, BOOLEAN hcm);
+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
-
-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_SetCRT2Group(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
-                                  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 void      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);
-
 #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 *upper_margin, ULONG *lower_margin,
 			 ULONG *hsync_len, ULONG *vsync_len,
 			 ULONG *sync, ULONG *vmode);
-BOOLEAN sisfb_gettotalfrommode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+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_SetYPbPr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
+extern void 	 SiS_SetTVMode(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, 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 linux-2.4.25-pre4/drivers/video/sis/init301.c linux-2.4.25-pre5/drivers/video/sis/init301.c
--- linux-2.4.25-pre4/drivers/video/sis/init301.c	2003-11-28 10:26:21.000000000 -0800
+++ linux-2.4.25-pre5/drivers/video/sis/init301.c	2004-01-15 12:10:23.000000000 -0800
@@ -1,34 +1,60 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/init301.c,v 1.3 2002/22/04 01:16:16 dawes Exp $ */
+/* $XFree86$ */
 /*
- * Mode switching code (CRT2 section)
- * for SiS 300/305/540/630/730/315/550/650/M650/651/740/330/660/M660/760/M760
+ * Mode initializing code (CRT2 section)
+ * for SiS 300/305/540/630/730 and
+ *     SiS 315/550/650/M650/651/661FX/M661xX/740/741/M741/330/660/M660/760/M760
  * (Universal module for Linux kernel framebuffer and XFree86 4.x)
  *
- * Copyright 2002, 2003 by Thomas Winischhofer <thomas@winischhofer.net>
- * Formerly based on non-functional code-fragements for 300 series by SiS, Inc.
+ * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
+ *
+ * If distributed as part of the Linux kernel, the following license terms
+ * apply:
  *
- * If distributed as part of the linux kernel, the contents of this file
- * is entirely covered by the GPL.
+ * * This program is free software; you can redistribute it and/or modify
+ * * it under the terms of the GNU General Public License as published by
+ * * the Free Software Foundation; either version 2 of the named License,
+ * * or any later version.
+ * *
+ * * This program is distributed in the hope that it will be useful,
+ * * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * * GNU General Public License for more details.
+ * *
+ * * You should have received a copy of the GNU General Public License
+ * * along with this program; if not, write to the Free Software
+ * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
  *
- * Otherwise, the following terms apply:
+ * Otherwise, the following license 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.
+ * * Redistribution and use in source and binary forms, with or without
+ * * modification, are permitted provided that the following conditions
+ * * are met:
+ * * 1) Redistributions of source code must retain the above copyright
+ * *    notice, this list of conditions and the following disclaimer.
+ * * 2) Redistributions in binary form must reproduce the above copyright
+ * *    notice, this list of conditions and the following disclaimer in the
+ * *    documentation and/or other materials provided with the distribution.
+ * * 3) All advertising materials mentioning features or use of this software
+ * *    must display the following acknowledgement: "This product includes
+ * *    software developed by Thomas Winischhofer, Vienna, Austria."
+ * * 4) The name of the author may not be used to endorse or promote products
+ * *    derived from this software without specific prior written permission.
+ * *
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * 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>
+ *
+ * Formerly based on non-functional code-fragements for 300 series by SiS, Inc.
+ * Used by permission.
  *
  * TW says: This code looks awful, I know. But please don't do anything about
  * this otherwise debugging will be hell.
@@ -36,14 +62,18 @@
  * 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 1
+#define SET_EMI		/* 302LV/ELV: Set EMI values */
 #endif
 
+#define COMPAL_HACK	/* Needed for Compal 1400x1050 (EMI) */
+#define COMPAQ_HACK	/* Needed for Inventec/Compaq 1280x1024 (EMI) */
+#define ASUS_HACK	/* Needed for Asus A2H 1024x768 (EMI) */
+
 #include "init301.h"
 
 #if 0
@@ -61,2693 +91,3413 @@
 #define SiS_I2CDELAY      1000
 #define SiS_I2CDELAYSHORT  150
 
-BOOLEAN
-SiS_SetCRT2Group(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
-                 PSIS_HW_DEVICE_INFO HwDeviceExtension)
+/*********************************************/
+/*         HELPER: Lock/Unlock CRT2          */
+/*********************************************/
+
+void
+SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
-   USHORT ModeIdIndex;
-   USHORT RefreshRateTableIndex;
+  if(HwInfo->jChipType >= SIS_315H)
+     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
+  else
+     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
+}
 
-   SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
+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);
+}
 
-   if(!SiS_Pr->UseCustomMode) {
-      SiS_SearchModeID(SiS_Pr,ROMAddr,&ModeNo,&ModeIdIndex);
-   } else {
-      ModeIdIndex = 0;
-   }
+/*********************************************/
+/*            HELPER: Enable CRT2            */
+/*********************************************/
 
-   /* Used for shifting CR33 */
-   SiS_Pr->SiS_SelectCRT2Rate = 4;
+void
+SiS_EnableCRT2(SiS_Private *SiS_Pr)
+{
+  SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
+}
 
-   SiS_UnLockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr);
+/*********************************************/
+/*    HELPER: Get Pointer to LCD structure   */
+/*********************************************/
+
+/* For 661 series only */
+#ifdef SIS315H
+#if 0   /* Need to wait until hardware using this really exists */
+static UCHAR *
+GetLCDPtr661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, int tabletype,
+             USHORT ModeNo, USHORT ModeIdIndex, USHORT RRTI)
+{
+  UCHAR *ROMAddr =  HwInfo->pjVirtualRomBase;
+  UCHAR *tableptr = NULL;
+  UCHAR tablelengths[] = { 8, 7, 6, 6, 8, 6, 0, 0, 0 };
+  USHORT modeflag, CRT2Index, tablelength, lcdid, myid, tableptri;
 
-   RefreshRateTableIndex = SiS_GetRatePtrCRT2(SiS_Pr, ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
+  if(ModeNo <= 0x13) {
+     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+     CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+  } else {
+     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+     CRT2Index = SiS_Pr->SiS_RefIndex[RRTI].Ext_CRT2CRTC;
+     /* This is total bullshit: */
+     if(SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO == SIS_RI_720x576) CRT2Index = 10;
+  }
 
-   SiS_SaveCRT2Info(SiS_Pr,ModeNo);
+  if(tabletype <= 1) {
+#if 0	/* Not yet implemented */
+     if(ModeNo <= 0x13) {
+        CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex]. + 5;
+     } else {
+        CRT2Index = SiS_Pr->SiS_RefIndex[RRTI]. + 5;
+     }
+     if(tabletype & 1) CRT2Index >>= 4;
+#endif
+  }
 
-   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);
-   }
+  CRT2Index &= 0x0f;
 
-   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
-      SiS_LockCRT2(SiS_Pr,HwDeviceExtension, BaseAddr);
-      SiS_DisplayOn(SiS_Pr);
-      return(TRUE);
-   }
+  tablelength = tablelengths[tabletype];
+  if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
+     if((tabletype == 5) || (tabletype == 7)) tablelength = 8;
+     if((tabletype == 3) || (tabletype == 8)) tablelength = 8;
+  }
 
-   SiS_GetCRT2Data(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
-                   HwDeviceExtension);
+  if(!tablelength) return NULL;
 
-   /* 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, BaseAddr);
+  tableptri = ROMAddr[0x222] | (ROMAddr[0x223] << 8);
+  tableptri += (tabletype << 1);
+  if(!tableptri) return NULL;
+  tableptr = &ROMAddr[tableptri];
+
+  do {
+     lcdid = tableptr[0];
+     if(lcdid == 0xff) break;
+     myid = SiS_Pr->SiS_LCDResInfo;
+     if((lcdid & 0x80) && (lcdid != 0x80)) {
+        lcdid &= 0x7f;
+	myid = SiS_Pr->SiS_LCDTypeInfo;
+     }
+     if(SiS_Pr->SiS_LCDInfo & LCDPass11) myid &= ~0x1f;
+
+     if(myid == lcdid) {
+	lcdid = tableptr[1] | (tableptr[2] << 8);
+	myid = SiS_Pr->SiS_LCDInfo661;
+	if(modeflag & HalfDCLK) myid |= 0x200;
+	if(ModeNo <= 0x13)      myid |= 0x400;
+	lcdid &= myid;
+	myid = tableptr[3] | (tableptr[4] << 8);
+	if(lcdid == myid) break;
+     }
+     tableptr += 7;
+  } while (1);
+
+  if(lcdid == myid) {
+     lcdid = tableptr[5] | (tableptr[6] << 8);
+     lcdid += (tablelength * CRT2Index);
+     return((UCHAR *)&ROMAddr[lcdid]);
+  }
+
+  return NULL;
+}
+#endif
+
+static UCHAR *
+GetLCDStructPtr661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
+   USHORT lcdres = SiS_Pr->SiS_LCDResInfo;
+   USHORT lcdtype = SiS_Pr->SiS_LCDTypeInfo;
+   USHORT romindex=0;
+   UCHAR  *myptr = NULL;
+   UCHAR  lcdid;
+
+   if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+      romindex = ROMAddr[0x256] | (ROMAddr[0x257] << 8);
+   }
+   if(romindex) {
+      myptr = &ROMAddr[romindex];
    } else {
-        SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
+      myptr = (UCHAR *)SiS_LCDStruct661;
    }
 
-#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
+   while(myptr[0] != 0xff) {
+      lcdid = myptr[0];
+      if((lcdid & 0x80) && (lcdid != 0x80)) {
+         lcdres = lcdtype;
+	 lcdid &= 0x7f;
+      }
+      if(lcdid == lcdres) break;
+      myptr += 26;
+   }
+   if(myptr[0] == 0xff) return NULL;
+
+   return myptr;
+}
 #endif
 
-   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_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
-
-	   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);
+/*********************************************/
+/*           Adjust Rate for CRT2            */
+/*********************************************/
 
-	   /* 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);
-		    }
-                 }
-	      }
-	      SiS_SetCRT2ECLK(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
-		              RefreshRateTableIndex,HwDeviceExtension);
-	   }
-        }
+static BOOLEAN
+SiS_AdjustCRT2Rate(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+                   USHORT RefreshRateTableIndex, USHORT *i,
+		   PSIS_HW_INFO HwInfo)
+{
+  USHORT tempax,tempbx,infoflag;
 
-   } else {
+  tempbx = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].ModeID;
 
-        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);
+  tempax = 0;
+
+  if(SiS_Pr->SiS_VBType & VB_SISVB) {
+
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
+
+      	tempax |= SupportRAMDAC2;
+	if(HwInfo->jChipType >= SIS_315H) {
+	   tempax |= SupportRAMDAC2_135;
+	   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+	      tempax |= SupportRAMDAC2_162;
+	      if(SiS_Pr->SiS_VBType & VB_SIS301C) {
+		 tempax |= SupportRAMDAC2_202;
+	      }
 	   }
 	}
 
-        SiS_SetCRT2ECLK(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
-	                RefreshRateTableIndex,HwDeviceExtension);
+     } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
 
-	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		    
+     	tempax |= SupportLCD;
+	if(HwInfo->jChipType >= SIS_315H) {
+	   if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
+	      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+	         if(tempbx == 0x2e) {  /* 640x480 */
+		    tempax |= Support64048060Hz;
 		 }
 	      }
-	      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-       		 SiS_SetCHTVReg(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
-		               RefreshRateTableIndex);
-	      }
-     	   }
+	   }
 	}
 
-   }
+     } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
 
-#ifdef SIS300
-   if(HwDeviceExtension->jChipType < SIS_315H) {
-      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,ModeIdIndex,
-	       			    RefreshRateTableIndex);
-	       }
-	    } else {
-       	       SiS_OEM300Setting(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,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,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,
-	                      ModeIdIndex,RefreshRateTableIndex);
-	    }
-            if(HwDeviceExtension->jChipType == SIS_730) {
-               SiS_DisplayOn(SiS_Pr);
-	    }
-         }
-      }
-      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-          if(HwDeviceExtension->jChipType != SIS_730) {
-             SiS_DisplayOn(SiS_Pr);
-	  }
-      }
-   }
-#endif
+      	tempax |= SupportHiVision;
 
-#ifdef SIS315H
-   if(HwDeviceExtension->jChipType >= SIS_315H) {
-      if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
-	 SiS_FinalizeLCD(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex, HwDeviceExtension);
-         if(SiS_Pr->SiS_UseOEM) {
-            SiS_OEM310Setting(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
-         }
-         SiS_CRT2AutoThreshold(SiS_Pr,BaseAddr);
-      }
-   }
-#endif
+     } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750|SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
 
-   if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
-      SiS_EnableBridge(SiS_Pr,HwDeviceExtension,BaseAddr);
-   }
+        tempax |= SupportTV;
+	if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+	   tempax |= SupportTV1024;
+	}
 
-   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);
-      }
-   }
+  } else {	/* for LVDS  */
 
-   if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
-      SiS_LockCRT2(SiS_Pr,HwDeviceExtension, BaseAddr);
-   }
+     if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+     	if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+           tempax |= SupportCHTV;
+      	}
+     }
 
-   return 1;
-}
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+     	tempax |= SupportLCD;
+     }
 
-BOOLEAN
-SiS_LowModeStuff(SiS_Private *SiS_Pr, USHORT ModeNo,
-                 PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-    USHORT temp,temp1,temp2;
+  }
 
-    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);
-       }
-    }
+  /* 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;
+  }
+
+  /* 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)++) {
+     if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].ModeID != tempbx) {
+     	return(0);
+     }
+     infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag;
+     if(infoflag & tempax) return(1);
+  }
+  return(1);
 }
 
-/* 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)
+/*********************************************/
+/*              Get rate pointer             */
+/*********************************************/
+
+USHORT
+SiS_GetRatePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+               PSIS_HW_INFO HwInfo)
 {
-  USHORT  temp=0, tempax=0, tempbx=0, tempcx=0;
-  USHORT  pushbx=0, CRT1Index=0;
-#ifdef SIS315H
-  USHORT  tempbl=0;
-#endif
-  USHORT  modeflag, resinfo=0;
+  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 <= 0x13) {
+  /* Do NOT check for UseCustomMode here, will skrew up FIFO */
+  if(ModeNo == 0xfe) return 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;
+  else
+     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) {
-#ifdef SIS315H
-     SiS_SetCRT2Sync(SiS_Pr,BaseAddr,ROMAddr,ModeNo,
-                     RefreshRateTableIndex,HwDeviceExtension);
+  if(ModeNo < 0x14) return(0xFFFF);
 
-     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]. */
 
-     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) >> SiS_Pr->SiS_SelectCRT2Rate) & 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_VBType & VB_SISVB) {
+        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;
+	}
+	if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+	   if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) {
+              temp = LCDRefreshIndex[SiS_Pr->SiS_LCDResInfo];
+              if(index > temp) index = temp;
+	   }
+	}
      } else {
+        if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) index = 0;
+	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+           if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) index = 0;
+        }
+     }
+  }
 
-        SiS_SetCRT2Offset(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
-      		          RefreshRateTableIndex,HwDeviceExtension);
+  RefreshRateTableIndex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
+  ModeNo = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].ModeID;
 
-        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(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++;
+        }
+     }
+  }
 
-        SiS_SetCRT2Sync(SiS_Pr,BaseAddr,ROMAddr,ModeNo,
-                        RefreshRateTableIndex,HwDeviceExtension);
+  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);
 
-	/* 1. Horizontal setup */
+  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++;
+     }
+  }
 
-        if (HwDeviceExtension->jChipType < SIS_315H ) {
+  i--;
 
-#ifdef SIS300   /* ------------- 300 series --------------*/
+  if((SiS_Pr->SiS_SetFlag & ProgrammingCRT2) && (!(SiS_Pr->SiS_VBInfo & DisableCRT2Display))) {
+     backup_i = i;
+     if(!(SiS_AdjustCRT2Rate(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, &i, HwInfo))) {
+	i = backup_i;
+     }
+  }
 
-    		temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF;   			/* BTVGA2HT 0x08,0x09 */
-    		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,temp);                   /* CRT2 Horizontal Total */
+  return(RefreshRateTableIndex + i);
+}
 
-    		temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
-    		SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp);          /* CRT2 Horizontal Total Overflow [7:4] */
+/*********************************************/
+/*            STORE CRT2 INFO in CR34        */
+/*********************************************/
 
-    		temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF;                       /* BTVGA2HDEE 0x0A,0x0C */
-    		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0A,temp);                   /* CRT2 Horizontal Display Enable End */
+static void
+SiS_SaveCRT2Info(SiS_Private *SiS_Pr, USHORT ModeNo)
+{
+  USHORT temp1,temp2;
 
-    		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;
+  /* 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);
+}
 
-    		if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+/*********************************************/
+/*    HELPER: GET SOME DATA FROM BIOS ROM    */
+/*********************************************/
 
-		   if(SiS_Pr->UseCustomMode) {
-		      tempbx = SiS_Pr->CHSyncStart + 12;
-		      tempcx = SiS_Pr->CHSyncEnd + 12;
-		   }
+static BOOLEAN
+SiS_CR36BIOSWord23b(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+  USHORT temp,temp1;
+  UCHAR *ROMAddr;
 
-      		   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((ROMAddr = (UCHAR *)HwInfo->pjVirtualRomBase) && SiS_Pr->SiS_UseROM) {
+     if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
+        temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xff) >> 4);
+        temp1 = (ROMAddr[0x23c] << 8) | ROMAddr[0x23b];
+        if(temp1 & temp) return(1);
+     }
+  }
+  return(0);
+}
 
-    		   if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (resinfo == SIS_RI_1024x768)){
-        	      if(!(SiS_Pr->SiS_VBInfo & SetPALTV)){
-      			 tempbx = 1040;
-      			 tempcx = 1042;
-      		      }
-    		   }
-	        }
+static BOOLEAN
+SiS_CR36BIOSWord23d(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+  USHORT temp,temp1;
+  UCHAR *ROMAddr;
 
-    		temp = tempbx & 0x00FF;
-    		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0B,temp);                   /* CRT2 Horizontal Retrace Start */
-#endif /* SIS300 */
+  if((ROMAddr = (UCHAR *)HwInfo->pjVirtualRomBase) && SiS_Pr->SiS_UseROM) {
+     if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
+        temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xff) >> 4);
+        temp1 = (ROMAddr[0x23e] << 8) | ROMAddr[0x23d];
+        if(temp1 & temp) return(1);
+     }
+  }
+  return(0);
+}
 
- 	} else {
+/*********************************************/
+/*          HELPER: DELAY FUNCTIONS          */
+/*********************************************/
 
-#ifdef SIS315H  /* ------------------- 315/330 series --------------- */
+void
+SiS_DDC2Delay(SiS_Private *SiS_Pr, USHORT delaytime)
+{
+  USHORT i, j;
 
-	        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--;
+  for(i=0; i<delaytime; i++) {
+     j += SiS_GetReg(SiS_Pr->SiS_P3c4,0x05);
+  }
+}
 
-		temp = tempcx & 0xff;
-		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,temp);                  /* CRT2 Horizontal Total */
+static void
+SiS_GenericDelay(SiS_Private *SiS_Pr, USHORT delay)
+{
+  USHORT temp,flag;
 
-		temp = ((tempcx & 0xff00) >> 8) << 4;
-		SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp);         /* CRT2 Horizontal Total Overflow [7:4] */
+  flag = SiS_GetRegByte(0x61) & 0x10;
 
-		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;
+  while(delay) {
+     temp = SiS_GetRegByte(0x61) & 0x10;
+     if(temp == flag) continue;
+     flag = temp;
+     delay--;
+  }
+}
 
-		temp = tempbx & 0xff;
-		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0A,temp);                  /* CRT2 Horizontal Display Enable End */
+#ifdef SIS315H
+static void
+SiS_LongDelay(SiS_Private *SiS_Pr, USHORT delay)
+{
+  while(delay--) {
+     SiS_GenericDelay(SiS_Pr,0x19df);
+  }
+}
+#endif
 
-		pushbx = tempbx;
-		tempcx >>= 1;
-		tempbx += tempcx;
-		tempcx += tempbx;
+static void
+SiS_ShortDelay(SiS_Private *SiS_Pr, USHORT delay)
+{
+  while(delay--) {
+     SiS_GenericDelay(SiS_Pr,0x42);
+  }
+}
 
-		if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+static void
+SiS_PanelDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT DelayTime)
+{
+  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
+  USHORT PanelID, DelayIndex, Delay=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(HwInfo->jChipType < SIS_315H) {
 
-             	   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
-                }
+#ifdef SIS300
 
-		temp = tempbx & 0xff;
-	 	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0B,temp);                 /* CRT2 Horizontal Retrace Start */
-#endif  /* SIS315H */
+      PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
+      if(SiS_Pr->SiS_VBType & VB_SISVB) {
+         if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x10)) PanelID = 0x12;
+      }
+      DelayIndex = PanelID >> 4;
+      if((DelayTime >= 2) && ((PanelID & 0x0f) == 1))  {
+         Delay = 3;
+      } else {
+         if(DelayTime >= 2) DelayTime -= 2;
 
-     	}  /* 315/330 series */
+         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);
 
-  	/* The following is done for all bridge/chip types/series */
+#endif  /* SIS300 */
 
-  	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);                        /* Overflow */
+   } else {
 
-  	temp = tempcx & 0x00FF;
-  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0D,temp);                        /* CRT2 Horizontal Retrace End */
+#ifdef SIS315H
 
-  	/* 2. Vertical setup */
+      if(HwInfo->jChipType >= SIS_330) return;
 
-  	tempcx = SiS_Pr->SiS_VGAVT - 1;
-  	temp = tempcx & 0x00FF;
+      if((SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
+         (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
+	 (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) {			/* 315 series, LVDS; Special */
+
+         if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
+            PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
+	    if(SiS_Pr->SiS_CustomT == CUT_CLEVO1400) {
+	       if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1b) & 0x10)) PanelID = 0x12;
+	    }
+	    if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
+	       DelayIndex = PanelID & 0x0f;
+	    } else {
+	       DelayIndex = PanelID >> 4;
+	    }
+	    if((DelayTime >= 2) && ((PanelID & 0x0f) == 1))  {
+               Delay = 3;
+            } else {
+               if(DelayTime >= 2) DelayTime -= 2;
+               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);
+	 }
 
-        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) {
-	   /* 650/30xLV 1.10.6s */
-	   temp--;
-	}
-  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0E,temp);                        /* CRT2 Vertical Total */
+      } else if(SiS_Pr->SiS_VBType & VB_SISVB) {			/* 315 series, all bridges */
 
-  	tempbx = SiS_Pr->SiS_VGAVDE - 1;
-  	temp = tempbx & 0x00FF;
-  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0F,temp);                        /* CRT2 Vertical Display Enable End */
+	 DelayIndex = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
+         if(!(DelayTime & 0x01)) {
+       	    Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
+         } else {
+       	    Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
+         }
+	 Delay <<= 2;
+	 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
+	    Delay <<= 5;
+	 }
+	 SiS_DDC2Delay(SiS_Pr, Delay);
 
-  	temp = ((tempbx & 0xFF00) << 3) >> 8;
-  	temp |= ((tempcx & 0xFF00) >> 8);
-  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x12,temp);                        /* Overflow (and HWCursor Test Mode) */
+      }
 
-	/* 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 {
-	   /* 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        */
-	}
+#endif /* SIS315H */
 
-  	if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+   }
+}
 
-	   if(SiS_Pr->UseCustomMode) {
-	      tempbx = SiS_Pr->CVSyncStart;
-	      tempcx = (tempcx & 0xFF00) | (SiS_Pr->CVSyncEnd & 0x00FF);
-	   }
+#ifdef SIS315H
+static void
+SiS_PanelDelayLoop(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+                      USHORT DelayTime, USHORT DelayLoop)
+{
+   int i;
+   for(i=0; i<DelayLoop; i++) {
+      SiS_PanelDelay(SiS_Pr, HwInfo, DelayTime);
+   }
+}
+#endif
 
-    	   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_SetReg1(SiS_Pr->SiS_Part1Port,0x10,temp);           /* CRT2 Vertical Retrace Start */
+/*********************************************/
+/*    HELPER: WAIT-FOR-RETRACE FUNCTIONS     */
+/*********************************************/
 
-  	temp = ((tempbx & 0xFF00) >> 8) << 4;
-  	temp |= (tempcx & 0x000F);
-  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x11,temp);           /* CRT2 Vert. Retrace End; Overflow; "Enable CRTC Check" */
+void
+SiS_WaitRetrace1(SiS_Private *SiS_Pr)
+{
+  USHORT watchdog;
 
-  	/* 3. Panel compensation delay */
+  if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
 
-  	if(HwDeviceExtension->jChipType < SIS_315H) {
+  if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80)) return;
 
-#ifdef SIS300  /* ---------- 300 series -------------- */
+  watchdog = 65535;
+  while((SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
+  watchdog = 65535;
+  while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
+}
 
-	   if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
-	        temp = 0x20;
+static void
+SiS_WaitRetrace2(SiS_Private *SiS_Pr, USHORT reg)
+{
+  USHORT watchdog;
 
-		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_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(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;
-		   }
-		}
-	   }
+  watchdog = 65535;
+  while((SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02) && --watchdog);
+  watchdog = 65535;
+  while((!(SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02)) && --watchdog);
+}
 
-    	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x03C,temp);         /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
+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
+  }
+}
 
-#endif  /* SIS300 */
+static void
+SiS_VBWait(SiS_Private *SiS_Pr)
+{
+  USHORT tempal,temp,i,j;
 
-  	} else {
+  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;
+  }
+}
 
-#ifdef SIS315H   /* --------------- 315/330 series ---------------*/
+static void
+SiS_VBLongWait(SiS_Private *SiS_Pr)
+{
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+     SiS_VBWait(SiS_Pr);
+  } else {
+     SiS_WaitRetrace1(SiS_Pr);
+  }
+}
 
-	   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(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;
-		}
-		if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD|SetCRT2ToLCDA)) {
-		   if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-		      if(HwDeviceExtension->pdc) {
-		         temp = HwDeviceExtension->pdc;
-		         tempbl = 0;
-		      }
-		   }
-		}
-	   } 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;
-		   }
-		}
-		
-		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 */
+/*********************************************/
+/*               HELPER: MISC                */
+/*********************************************/
 
-    	   tempax = 0;
-    	   if (modeflag & DoubleScanMode) tempax |= 0x80;
-    	   if (modeflag & HalfDCLK)       tempax |= 0x40;
-    	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax);
+static BOOLEAN
+SiS_Is301B(SiS_Private *SiS_Pr)
+{
+  USHORT flag;
 
-#endif  /* SIS315H */
+  flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01);
+  if(flag >= 0xb0) return TRUE;
+  return FALSE;
+}
 
-  	}
+static BOOLEAN
+SiS_CRT2IsLCD(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+  USHORT flag;
 
-     }  /* Slavemode */
+  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;
+  return FALSE;
+}
 
-     if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+BOOLEAN
+SiS_IsDualEdge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+#ifdef SIS315H
+  USHORT flag;
 
-        /* For 301BDH with LCD, we set up the Panel Link */
-        if( (SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ) {
+  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;
+     }
+  }
+#endif
+  return FALSE;
+}
 
-	    SiS_SetGroup1_LVDS(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
-	                       HwDeviceExtension,RefreshRateTableIndex);
+BOOLEAN
+SiS_IsVAMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+#ifdef SIS315H
+  USHORT flag;
 
-        } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+  if(HwInfo->jChipType >= SIS_315H) {
+     flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
+     if((flag & EnableDualEdge) && (flag & SetToLCDA)) return TRUE;
+  }
+#endif
+  return FALSE;
+}
 
-    	    SiS_SetGroup1_301(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
-	                      HwDeviceExtension,RefreshRateTableIndex);
-        }
+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_Pr->SiS_LCDInfo & LCDDualLink) return TRUE;
+     }
+  }
+#endif
+  return FALSE;
+}
 
-     } else {
+#ifdef SIS315H
+static BOOLEAN
+SiS_WeHaveBacklightCtrl(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+  USHORT flag;
 
-        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);
-	   }
-	
-	}
+  if((HwInfo->jChipType >= SIS_315H) && (HwInfo->jChipType < SIS_661)) {
+     flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79);
+     if(flag & 0x10) return TRUE;
+  }
+  return FALSE;
+}
+#endif
 
-     }
-   } /* LCDA */
+#ifdef SIS315H
+static BOOLEAN
+SiS_IsNotM650orLater(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+  USHORT flag;
+
+  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 if(HwInfo->jChipType >= SIS_661) return FALSE;
+  return TRUE;
 }
+#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 SIS315H
+static BOOLEAN
+SiS_IsYPbPr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
-  USHORT  push1,push2;
-  USHORT  tempax,tempbx,tempcx,temp;
-  USHORT  resinfo,modeflag;
-  unsigned char p1_7, p1_8;
+  USHORT flag;
 
-  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(HwInfo->jChipType >= SIS_315H) {
+     flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
+     if(flag & EnableCHYPbPr) return TRUE;  /* = YPrPb = 0x08 */
   }
+  return FALSE;
+}
+#endif
 
-  /* The following is only done if bridge is in slave mode: */
+#ifdef SIS315H
+static BOOLEAN
+SiS_IsChScart(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+  USHORT flag;
 
-  tempax = 0xFFFF;
-  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV))  tempax = SiS_GetVGAHT2(SiS_Pr);
+  if(HwInfo->jChipType >= SIS_315H) {
+     flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
+     if(flag & EnableCHScart) return TRUE;  /* = Scart = 0x04 */
+  }
+  return FALSE;
+}
+#endif
 
-  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)  modeflag |= Charx8Dot;
+#ifdef SIS315H
+static BOOLEAN
+SiS_IsTVOrYPbPrOrScart(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+  USHORT flag;
 
-  if(modeflag & Charx8Dot) tempcx = 0x08;
-  else                     tempcx = 0x09;
+  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 & EnableCHYPbPr)      return TRUE;  /* = YPrPb = 0x08 */
+     if(flag & EnableCHScart)      return TRUE;  /* = Scart = 0x04 - TW */
+  } else {
+     flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
+     if(flag & SetCRT2ToTV)        return TRUE;
+  }
+  return FALSE;
+}
+#endif
 
-  if(tempax >= SiS_Pr->SiS_VGAHT) tempax = SiS_Pr->SiS_VGAHT;
+#ifdef SIS315H
+static BOOLEAN
+SiS_IsLCDOrLCDA(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+  USHORT flag;
 
-  if(modeflag & HalfDCLK) tempax >>= 1;
+  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 {
+     flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
+     if(flag & SetCRT2ToLCD) return TRUE;
+  }
+  return FALSE;
+}
+#endif
 
-  tempax = (tempax / tempcx) - 5;
-  tempbx = tempax & 0x00FF;
+static BOOLEAN
+SiS_BridgeIsOn(SiS_Private *SiS_Pr)
+{
+  USHORT flag;
 
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x03,0xff);                 /* set MAX HT */
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+     return FALSE;
+  } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
+     flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
+     if((flag == 1) || (flag == 2)) return FALSE;
+  }
+  return TRUE;
+}
 
-  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);
+static BOOLEAN
+SiS_BridgeIsEnabled(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+  USHORT flag;
 
-  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;
+  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 {
+       flag &= 0x50;
+       if((flag == 0x40) || (flag == 0x10)) return FALSE;
      }
   }
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x05,temp);                 /* 0x05 Horizontal Display Start */
+  return TRUE;
+}
 
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x06,0x03);                 /* 0x06 Horizontal Blank end     */
+static BOOLEAN
+SiS_BridgeInSlave(SiS_Private *SiS_Pr)
+{
+  USHORT flag1;
 
-  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;
-        }
-     }
+  flag1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
+  if(flag1 & (SetInSlaveMode >> 8)) return TRUE;
+  return FALSE;
+}
+
+/*********************************************/
+/*       GET VIDEO BRIDGE CONFIG INFO        */
+/*********************************************/
+
+/* 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_ChSW)) 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_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo,
+              USHORT ModeIdIndex,PSIS_HW_INFO HwInfo,
+	      int checkcrt2mode)
+{
+  USHORT tempax,tempbx,temp;
+  USHORT modeflag, resinfo=0;
+
+  if(ModeNo <= 0x13) {
+     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
   } 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;
-              }
-           }
-        }
+     if(SiS_Pr->UseCustomMode) {
+        modeflag = SiS_Pr->CModeFlag;
      } 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_LCDInfo & DontExpandLCD) temp += 28;
-                 }
-              }
-           }
-        }
+   	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
      }
   }
 
-  p1_7 = temp;
-  p1_8 = 0x00;
+  SiS_Pr->SiS_SetFlag = 0;
 
-  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;
+  SiS_Pr->SiS_ModeType = modeflag & ModeInfoFlag;
+
+  tempbx = 0;
+  if(SiS_BridgeIsOn(SiS_Pr) == 0) {
+    	temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
+#if 0
+   	if(HwInfo->jChipType < SIS_661) {
+	   if(SiS_Pr->SiS_YPbPr & YPbPrModeMask) {
+	      temp &= (SetCRT2ToHiVision | SwitchCRT2 | SetSimuScanMode); 	/* 0x83 */
+	      temp |= SetCRT2ToHiVision;   					/* 0x80 */
+   	   }
+	   if(SiS_Pr->SiS_YPbPr & YPbPrSetSVideo) {
+	      temp &= (SetCRT2ToHiVision | SwitchCRT2 | SetSimuScanMode); 	/* 0x83 */
+	      temp |= SetCRT2ToSVIDEO;  					/* 0x08 */
+	   }
+	}
+#endif
+    	tempbx |= temp;
+    	tempax = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) << 8;
+        tempax &= (DriverMode | LoadDACFlag | SetNotSimuMode | SetPALTV);
+    	tempbx |= tempax;
+
+#ifdef SIS315H
+	if(HwInfo->jChipType >= SIS_315H) {
+    	   if(SiS_Pr->SiS_VBType & (VB_SIS301C|VB_SIS302B|VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)) {
+	      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));
+		       }
+		    }
+		 }
+	      }
+	      temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
+       	      if((temp & (EnableDualEdge | SetToLCDA)) == (EnableDualEdge | SetToLCDA)) {
+          	 tempbx |= SetCRT2ToLCDA;
+	      }
+	      if(HwInfo->jChipType >= SIS_661) {
+	         if(SiS_Pr->SiS_VBType & (VB_SIS301C|VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)) {
+	            if(temp & 0x04) {
+		       temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
+		       if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
+		       else             tempbx |= SetCRT2ToYPbPr525750;
+		    }
+	         }
+  	      }
+    	   }
+
+	   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 & EnableCHYPbPr) {
+		    tempbx |= SetCRT2ToCHYPbPr;
+		 }
 	      }
-	   } else {
-	      p1_7 = 0x5b;
-	      p1_8 = 0x03;
 	   }
-	} else if( ((HwDeviceExtension->jChipType >= SIS_315H) &&
-	            ((ModeNo == 0x50) || (ModeNo = 0x56) || (ModeNo = 0x53))) ||
-	           ((HwDeviceExtension->jChipType < SIS_315H) &&
-		    (resinfo == SIS_RI_320x200 || resinfo == SIS_RI_320x240)) ) {
-	   if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
-	      p1_7 = 0x30,
-	      p1_8 = 0x03;
+	}
+
+#endif  /* SIS315H */
+
+    	if(SiS_Pr->SiS_VBType & VB_SISVB) {
+	   temp = SetCRT2ToSVIDEO   |
+	          SetCRT2ToAVIDEO   |
+	          SetCRT2ToSCART    |
+	          SetCRT2ToLCDA     |
+	          SetCRT2ToLCD      |
+	          SetCRT2ToRAMDAC   |
+                  SetCRT2ToHiVision |
+		  SetCRT2ToYPbPr525750;
+    	} else {
+           if(HwInfo->jChipType >= SIS_315H) {
+              if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+        	 temp = SetCRT2ToAVIDEO |
+		        SetCRT2ToSVIDEO |
+		        SetCRT2ToSCART  |
+		        SetCRT2ToLCDA   |
+		        SetCRT2ToLCD    |
+		        SetCRT2ToCHYPbPr;
+      	      } else {
+        	 temp = SetCRT2ToLCDA   |
+		        SetCRT2ToLCD;
+	      }
 	   } else {
-	      p1_7 = 0x2f;
-	      p1_8 = 0x03;
+      	      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+          	 temp = SetCRT2ToTV | SetCRT2ToLCD;
+              } else {
+        	 temp = SetCRT2ToLCD;
+	      }
 	   }
-        }
-     }
-  }
+    	}
+
+    	if(!(tempbx & temp)) {
+      	   tempax = DisableCRT2Display;
+      	   tempbx = 0;
+    	}
 
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
-     if(SiS_Pr->SiS_HiVision & 0x03) {
-	p1_7 = 0xb2;
-	if(SiS_Pr->SiS_HiVision & 0x02) {
-	   p1_7 = 0xab;
+   	if(SiS_Pr->SiS_VBType & VB_SISVB) {
+	   USHORT clearmask = ( DriverMode 	   |
+				DisableCRT2Display |
+				LoadDACFlag 	   |
+				SetNotSimuMode 	   |
+				SetInSlaveMode 	   |
+				SetPALTV 	   |
+				SwitchCRT2	   |
+				SetSimuScanMode );
+      	   if(tempbx & SetCRT2ToLCDA) {
+              tempbx &= (clearmask | SetCRT2ToLCDA);
+      	   }
+	   if(tempbx & SetCRT2ToRAMDAC) {
+              tempbx &= (clearmask | SetCRT2ToRAMDAC);
+      	   }
+	   if(tempbx & SetCRT2ToLCD) {
+              tempbx &= (clearmask | SetCRT2ToLCD);
+      	   }
+	   if(tempbx & SetCRT2ToSCART) {
+              tempbx &= (clearmask | SetCRT2ToSCART);
+      	   }
+	   if(tempbx & SetCRT2ToHiVision) {
+              tempbx &= (clearmask | SetCRT2ToHiVision);
+      	   }
+	   if(tempbx & SetCRT2ToYPbPr525750) {
+	      tempbx &= (clearmask | SetCRT2ToYPbPr525750);
+	   }
+   	} 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;
+	      }
+	   }
 	}
-     }
-  }
 
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,p1_7);			/* 0x07 Horizontal Retrace Start */
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,p1_8);			/* 0x08 Horizontal Retrace End   */
+    	if(tempax & DisableCRT2Display) {
+      	   if(!(tempbx & (SwitchCRT2 | SetSimuScanMode))) {
+              tempbx = SetSimuScanMode | DisableCRT2Display;
+      	   }
+    	}
 
+    	if(!(tempbx & DriverMode)){
+      	   tempbx |= SetSimuScanMode;
+    	}
 
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x03);                	/* 0x18 SR08 (FIFO Threshold?)   */
+	/* LVDS/CHRONTEL (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);
+	   }
+	}
 
-  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x19,0xF0);
+    	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;
+            	    }
+                 }
+              }
+      	   }
+    	}
 
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x09,0xFF);                	/* 0x09 Set Max VT    */
+    	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;
+		       }
+		    } else {
+            	       tempbx |= SetInSlaveMode;
+                    }
+	         }
+              }
+           } else {
+              tempbx |= SetInSlaveMode;
+      	   }
+    	}
 
-  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_SetReg1(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;
+  SiS_Pr->SiS_VBInfo = tempbx;
+
+  if(HwInfo->jChipType == SIS_630) {
+     SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo);
   }
+
+#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
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0E,temp);
+#endif
+}
 
-  if(tempbx & 0x0100)  tempcx |= 0x0002;
+/*********************************************/
+/*           DETERMINE YPbPr MODE            */
+/*********************************************/
 
-  tempax = 0x000B;
-  if(modeflag & DoubleScanMode) tempax |= 0x8000;
+void
+SiS_SetYPbPr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+  /* Note: This variable is only used on 30xLV systems.
+   * CR38 has a different meaning on LVDS/CH7019 systems.
+   * On 661 and later, these bits moved to CR35.
+   */
 
-  if(tempbx & 0x0200)  tempcx |= 0x0040;
+  SiS_Pr->SiS_YPbPr = 0;
+#ifdef SIS315H
+  if((HwInfo->jChipType >= SIS_315H) && (HwInfo->jChipType < SIS_661)) {
+     if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+        if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
+	   SiS_Pr->SiS_YPbPr = ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & 0x38) >> 3);
+	}
+     }
+  }
+#endif /* SIS315H */
+}
 
-  temp = (tempax & 0xFF00) >> 8;
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0B,temp);
+/*********************************************/
+/*           DETERMINE TVMode flag           */
+/*********************************************/
 
-  if(tempbx & 0x0400)  tempcx |= 0x0600;
+void
+SiS_SetTVMode(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, PSIS_HW_INFO HwInfo)
+{
+  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
+  USHORT temp, temp1, resinfo = 0, romindex = 0;
+  UCHAR  OutputSelect = *SiS_Pr->pSiS_OutputSelect;
 
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x11,0x00);                	/* 0x11 Vertical Blank End */
+  SiS_Pr->SiS_TVMode = 0;
 
-  tempax = (SiS_Pr->SiS_VGAVT - tempbx) >> 2;
+  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
+  if(SiS_Pr->UseCustomMode) return;
 
-  if((ModeNo > 0x13) || (HwDeviceExtension->jChipType < SIS_315H)) {
-     if(resinfo != SIS_RI_1280x1024) {
-	tempbx += (tempax << 1);
-     }
-  } else if(HwDeviceExtension->jChipType >= SIS_315H) {
-     if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1400x1050) {
-	tempbx += (tempax << 1);
-     }
+  if(ModeNo > 0x13) {
+     resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
   }
 
-  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(HwDeviceExtension->jChipType >= SIS_315H) {
-	         if(SiS_Pr->SiS_VGAHDE == 800) tempbx += 10;
-	      }
-      	   }
+  if(HwInfo->jChipType < SIS_661) {
+
+     if(SiS_Pr->SiS_VBInfo & SetPALTV) SiS_Pr->SiS_TVMode |= TVSetPAL;
+
+     if(SiS_Pr->SiS_VBType & VB_SISVB) {
+        temp = 0;
+        if((HwInfo->jChipType == SIS_630) ||
+           (HwInfo->jChipType == SIS_730)) {
+           temp = 0x35;
+	   romindex = 0xfe;
+        } else if(HwInfo->jChipType >= SIS_315H) {
+           temp = 0x38;
+	   romindex = 0xf3;
+	   if(HwInfo->jChipType >= SIS_330) romindex = 0x11b;
+        }
+        if(temp) {
+           if(romindex && ROMAddr && SiS_Pr->SiS_UseROM) {
+	      OutputSelect = ROMAddr[romindex];
+	      if(!(OutputSelect & EnablePALMN)) {
+                 SiS_SetRegAND(SiS_Pr->SiS_P3d4,temp,0x3F);
+	      }
+	   }
+	   temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,temp);
+	   if(SiS_Pr->SiS_TVMode & TVSetPAL) {
+              if(temp1 & EnablePALM) {		/* 0x40 */
+                 SiS_Pr->SiS_TVMode |= TVSetPALM;
+	         SiS_Pr->SiS_TVMode &= ~TVSetPAL;
+	      } else if(temp1 & EnablePALN) {	/* 0x80 */
+	         SiS_Pr->SiS_TVMode |= TVSetPALN;
+              }
+	   } else {
+              if(temp1 & EnableNTSCJ) {		/* 0x40 */
+	         SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
+  	      }
+	   }
+        }
+	/* Translate HiVision/YPbPr to our new flags */
+	if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
+	   if(SiS_Pr->SiS_YPbPr == YPbPr750)           SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
+	   else if(SiS_Pr->SiS_YPbPr == YPbPr525)      SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
+	   else	if(SiS_Pr->SiS_YPbPr == YPbPrHiVision) SiS_Pr->SiS_TVMode |= TVSetHiVision;
+	   else					       SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
+	   if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p | TVSetYPbPr525i)) {
+	      SiS_Pr->SiS_VBInfo &= ~SetCRT2ToHiVision;
+	      SiS_Pr->SiS_VBInfo |= SetCRT2ToYPbPr525750;
+	   } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
+	      SiS_Pr->SiS_TVMode |= TVSetPAL;
+	   }
+	}
+     } else if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+        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)) {
+	         SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
+              }
+           } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+      	      temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79);
+      	      if((temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1)) {
+	         SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
+ 	      }
+	   }
+           if(SiS_Pr->SiS_CHSOverScan) {
+              SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
+           }
+        }
+        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+	   temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
+     	   if(SiS_Pr->SiS_TVMode & TVSetPAL) {
+              if(temp & EnablePALM)      SiS_Pr->SiS_TVMode |= TVSetPALM;
+	      else if(temp & EnablePALN) SiS_Pr->SiS_TVMode |= TVSetPALN;
+           } else {
+	      if(temp & EnableNTSCJ) {
+	         SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
+  	      }
+	   }
 	}
      }
-  }
-  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_SetReg1(SiS_Pr->SiS_Part1Port,0x0C,temp);			/* 0x0C Vertical Retrace Start */
-
-  tempbx--;
-  temp = tempbx & 0x00FF;
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x10,temp);
 
-  if(tempbx & 0x0100) tempcx |= 0x0008;
+  } else {  /* 661 and later */
 
-  if(tempbx & 0x0200) {
-     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x0B,0x20);
+     temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
+     if(temp1 & 0x01) {
+        SiS_Pr->SiS_TVMode |= TVSetPAL;
+	if(temp1 & 0x08) {
+	   SiS_Pr->SiS_TVMode |= TVSetPALN;
+	} else if(temp1 & 0x04) {
+	   if(SiS_Pr->SiS_VBType & VB_SISVB) {
+	      SiS_Pr->SiS_TVMode &= ~TVSetPAL;
+	   }
+	   SiS_Pr->SiS_TVMode |= TVSetPALM;
+	}
+     } else {
+        if(temp1 & 0x02) {
+	   SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
+	}
+     }
+     if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+        if(SiS_Pr->SiS_CHOverScan) {
+           if((temp1 & 0x10) || (SiS_Pr->SiS_CHOverScan == 1)) {
+	      SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
+	   }
+	}
+     }
+     if(SiS_Pr->SiS_VBType & VB_SISVB) {
+        if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
+	   temp1 &= 0xe0;
+	   if(temp1 == 0x00)      SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
+	   else if(temp1 == 0x20) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
+	   else if(temp1 == 0x40) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
+	} else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
+	   SiS_Pr->SiS_TVMode |= (TVSetHiVision | TVSetPAL);
+	}
+     }
   }
-  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_VBInfo & SetCRT2ToSCART) SiS_Pr->SiS_TVMode |= TVSetPAL;
 
-  tempbx = push1;
-  temp = tempbx & 0x000F;
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0D,temp);        		/* 0x0D vertical Retrace End */
+  if(SiS_Pr->SiS_VBType & VB_SISVB) {
 
-  if(tempbx & 0x0010) tempcx |= 0x2000;
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
+        SiS_Pr->SiS_TVMode |= TVSetPAL;
+     } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
+        if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525i | TVSetYPbPr525p | TVSetYPbPr750p)) {
+	   SiS_Pr->SiS_TVMode &= ~(TVSetPAL | TVSetNTSCJ | TVSetPALM | TVSetPALN);
+	}
+     }
 
-  temp = tempcx & 0x00FF;
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0A,temp);              	/* 0x0A CR07 */
+     if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+        if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
+           SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
+        }
+     }
 
-  temp = (tempcx & 0xFF00) >> 8;
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x17,temp);              	/* 0x17 SR0A */
+     if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
+        if(!(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr525p | TVSetYPbPr750p))) {
+           if(resinfo == SIS_RI_1024x768) {
+              SiS_Pr->SiS_TVMode |= TVSetNTSC1024;
+	   }
+        }
+     }
 
-  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 */
+     SiS_Pr->SiS_TVMode |= TVRPLLDIV2XO;
+     if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) &&
+        (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+	SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
+     } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
+        SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
+     } else if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
+        if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
+           SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
+        }
+     }
 
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0F,0x00);              	/* 0x0F CR14 */
+  }
 
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x12,0x00);              	/* 0x12 CR17 */
+  SiS_Pr->SiS_VBInfo &= ~SetPALTV;
 
-  if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
-     if(IS_SIS650) {
-        /* 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 */
+#ifdef TWDEBUG
+  xf86DrvMsg(0, X_INFO, "(init301.c: TVMode %x)\n", SiS_Pr->SiS_TVMode);
+#endif 
 
 }
 
+/*********************************************/
+/*               GET LCD INFO                */
+/*********************************************/
+
 void
-SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr,USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
-		   USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension,
-		   USHORT RefreshRateTableIndex)
+SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+		  PSIS_HW_INFO HwInfo)
 {
-  USHORT modeflag, resinfo;
-  USHORT push1, push2, tempax, tempbx, tempcx, temp;
-#ifdef SIS315H
-  USHORT pushcx;
+#ifdef SIS300
+  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
 #endif
-  ULONG  tempeax=0, tempebx, tempecx, tempvcfact=0;
+#ifdef SIS315H
+  UCHAR  *myptr = NULL;
+#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 };
 
-  /* This is not supported on LVDS */
-  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return;
-  if(SiS_Pr->UseCustomMode) return;
+  SiS_Pr->SiS_LCDResInfo = 0;
+  SiS_Pr->SiS_LCDTypeInfo = 0;
+  SiS_Pr->SiS_LCDInfo = 0;
 
-  if(ModeNo <= 0x13) {
-     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-     resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+  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;
+     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;
+     }
   }
 
-  /* Set up Panel Link */
+  if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return;
 
-  /* 1. Horizontal setup */
+  temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
 
-  tempax = SiS_Pr->SiS_LCDHDES;
+  if((HwInfo->jChipType < SIS_315H) || (HwInfo->jChipType >= SIS_661)) {
+     SiS_Pr->SiS_LCDTypeInfo = temp >> 4;
+  } else {
+     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;
 
-  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;
-     }
+  if(SiS_Pr->SiS_VBType & VB_SISVB) {
+     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;
   }
 
-  tempcx = SiS_Pr->SiS_HT;    				  /* Horiz. Total */
+  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;
+  }
 
-  tempbx = SiS_Pr->SiS_HDE;                               /* Horiz. Display End */
+  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;
+     }
+  }
 
-  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
-     SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) {
-     tempbx >>= 1;
+  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;
   }
 
-  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;
-	      }
-	   }
+  temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
+  if(HwInfo->jChipType < SIS_661) {
+     temp &= ~0xe;
+  } else {
+#ifdef SIS315H
+     if(!(temp & 0x10)) {
+        if(temp & 0x08) temp |= LCDPass11;
+     }
+     temp &= ~0xe;
+     if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
+        myptr = GetLCDStructPtr661(SiS_Pr, HwInfo);
+        if(myptr) {
+           if(myptr[2] & 0x01) temp |= LCDDualLink;
         }
      }
+#endif
   }
-  tempcx = (tempcx - tempbx) >> 2;		 /* HT-HDE / 4 */
-
-  push1 = tempax;
+  SiS_Pr->SiS_LCDInfo = temp;
 
-  tempax += tempbx;
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+     if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
+        SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20;   /* neg h/v sync, RGB24 */
+     }
+  }
 
-  if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;
+  if(!(SiS_Pr->UsePanelScaler))        SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
+  else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
 
-  push2 = tempax;
+  if(SiS_Pr->SiS_VBType & VB_SISVB) {
+     if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+        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) {
+	      /* We do not scale to 1280x960 (B/C bridges only) */
+              SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+	   }
+	   if(((HwInfo->jChipType >= SIS_315H) && (ModeNo == 0x23 || ModeNo == 0x24 || ModeNo == 0x25)) ||
+	      ((HwInfo->jChipType < SIS_315H)  && (ModeNo == 0x55 || ModeNo == 0x5a || ModeNo == 0x5b))) {
+	      /* We do not scale to 1280x768 (B/C bridges only) */
+              SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+	   }
+	   if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+	      /* No non-scaling data available for LV bridges */
+	      SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
+	   }
+        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
+           /* 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) {
+	      /* We do not scale to 1280x1024 (all bridges) */
+	      SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+	   }
+	} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
+	   if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
+	      /* No idea about the timing and zoom factors (C bridge only) */
+	      SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+	   }
+	}
+	if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+	   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_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(HwDeviceExtension->jChipType < SIS_315H) {
-		      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-		         tempcx = 0x0017;
-#ifdef TWNEWPANEL
-			 tempcx = 0x0018;
+  if(HwInfo->jChipType >= SIS_315H) {
+#ifdef SIS315H
+     if(HwInfo->jChipType < SIS_661) {
+        if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) {
+           SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
+	   SiS_Pr->SiS_LCDInfo |= LCDPass11;
+	}
+     }
 #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;
+  } else {
+#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 &= (~DontExpandLCD);
+ 	      }
 	   }
         }
+     } else if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+	if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
+           SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
+	}
      }
+#endif
   }
 
-  tempcx += tempax;                              /* lcdhrs  */
-  if(tempcx >= SiS_Pr->SiS_HT) tempcx -= SiS_Pr->SiS_HT;
+  /* Trumpion: Assume non-expanding */
+  if(SiS_Pr->SiS_IF_DEF_TRUMPION != 0) {
+     SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
+  }
 
-  tempax = tempcx >> 3;                          /* BPLHRS */
-  temp = tempax & 0x00FF;
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x14,temp);		 /* Part1_14h; Panel Link Horizontal Retrace Start  */
+  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+     SiS_Pr->SiS_LCDInfo &= (~LCDPass11);
+  }
 
-  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(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;
-			  }
-		       }
-	            }
-	         }
-	      }
-           }
-        }
+#ifdef SIS315H
+  if((HwInfo->jChipType >= SIS_315H) && (HwInfo->jChipType < SIS_661)) {
+     if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
+	/* Enable 302LV/302ELV dual link mode.
+	 * For 661, this is done above.
+	 */
+        if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) &&
+	   (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)) {
+	   /* (Sets this in SenseLCD; new paneltypes) */
+	   SiS_Pr->SiS_LCDInfo |= LCDDualLink;
+	}
+        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_Pr->SiS_LCDInfo |= LCDDualLink;
+	}
      }
   }
+#endif
 
-  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_SetReg1(SiS_Pr->SiS_Part1Port,0x15,temp);    	 /* Part1_15h; Panel Link Horizontal Retrace End/Skew */
+  if(!((HwInfo->jChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
 
-  tempbx = push2;
-  tempcx = push1;                                /* lcdhdes  */
+     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;
+	   }
+	}
+     }
 
-  temp = (tempcx & 0x0007);                      /* BPLHDESKEW  */
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1A,temp);   	 /* Part1_1Ah; Panel Link Vertical Retrace Start (2:0) */
+     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;
+     }
 
-  tempcx >>= 3;                                  /* BPLHDES */
-  temp = (tempcx & 0x00FF);
-#if 0 /* Not 550 FSTN */
-  if(HwDeviceExtension->jChipType >= SIS_315H) {
-     if(ModeNo == 0x5b) temp--; */
   }
-#endif
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x16,temp);    	 /* Part1_16h; Panel Link Horizontal Display Enable Start  */
 
-  if((HwDeviceExtension->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(HwDeviceExtension->jChipType >= SIS_315H) {
-     if(ModeNo == 0x5b) temp--;
+  if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+     if(SiS_Pr->SiS_VBInfo & SetNotSimuMode) {
+     	SiS_Pr->SiS_SetFlag |= LCDVESATiming;
+     }
+  } else {
+     SiS_Pr->SiS_SetFlag |= LCDVESATiming;
   }
+
+  SiS_Pr->SiS_LCDInfo661 = 0;
+  if(SiS_Pr->SiS_SetFlag & LCDVESATiming) SiS_Pr->SiS_LCDInfo661 |= 0x0001;
+  if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) SiS_Pr->SiS_LCDInfo661 |= 0x0002;
+  if(SiS_Pr->SiS_LCDInfo & LCDPass11)     SiS_Pr->SiS_LCDInfo661 |= 0x0008;
+  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) SiS_Pr->SiS_LCDInfo661 |= 0x0010;
+  SiS_Pr->SiS_LCDInfo661 |= (SiS_Pr->SiS_LCDInfo & 0xe0);
+  if(SiS_Pr->SiS_LCDInfo & LCDDualLink)   SiS_Pr->SiS_LCDInfo661 |= 0x0100;
+
+#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
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x17,temp);   	 /* Part1_17h; Panel Link Horizontal Display Enable End  */
+#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
+}
 
-  /* 2. Vertical setup */
+/*********************************************/
+/*                 GET VCLK                  */
+/*********************************************/
 
-  if(HwDeviceExtension->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;
+USHORT
+SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+                USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
+{
+  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
+  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;
+  const UCHAR  *CHTVVCLKPtr = NULL;
+  const USHORT *LCDXlatVCLK1 = NULL;
+  const USHORT *LCDXlatVCLK2 = NULL;
+  const USHORT *LVDSXlatVCLK2 = NULL;
+  const USHORT *LVDSXlatVCLK3 = NULL;
 
+  if(HwInfo->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
+  }
 
-     tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE;           /* VGAVT-VGAVDE  */
-
+  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;
   }
 
-  tempbx = SiS_Pr->SiS_LCDVDES;	   		 	 	/* VGAVDES  */
-  push1 = tempbx;
+  if(SiS_Pr->SiS_VBType & VB_SISVB) {    /* 30x/B/LV */
 
-  tempax = SiS_Pr->SiS_VGAVDE;
+     if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
 
-  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;
+        CRT2Index >>= 6;
+        if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {      /*  LCD */
+
+           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;
+		 }
+	      }
 	   }
-	}
-     } 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;
+        } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {                 /*  TV */
 
-  push2 = tempbx;
+	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
+              if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = HiTVVCLKDIV2;
+     	      else                                  VCLKIndex = HiTVVCLK;
+              if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
+            	 if(modeflag & Charx8Dot) 	    VCLKIndex = HiTVSimuVCLK;
+            	 else 			  	    VCLKIndex = HiTVTextVCLK;
+              }
+           } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) VCLKIndex = YPbPr750pVCLK - TVCLKBASE_315;
+	   else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)   VCLKIndex = TVVCLKDIV2;
+	   else if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO)     VCLKIndex = TVVCLKDIV2;
+           else         		            	  VCLKIndex = TVVCLK;
 
-  tempcx >>= 1;
+	   if(HwInfo->jChipType < SIS_315H) {
+              VCLKIndex += TVCLKBASE_300;
+  	   } else {
+	      VCLKIndex += TVCLKBASE_315;
+	   }
 
-  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(HwDeviceExtension->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 {         					/* 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)) {
+		    if(VCLKIndex == 0x14) VCLKIndex = 0x34;
+		 }
+		 /* Better VGA2 clock for 1280x1024@75 */
+		 if(VCLKIndex == 0x17) VCLKIndex = 0x45;
+	      }
            }
-     	   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;
-	}
+        }
+
+     } 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;
+	      }
+	   }
+        }
      }
-  }
 
-  tempbx += tempcx;			 	/* BPLVRS  */
+  } else {       /*   LVDS  */
 
-  if((HwDeviceExtension->jChipType < SIS_315H) ||
-     (SiS_Pr->SiS_IF_DEF_FSTN) ||
-     (SiS_Pr->SiS_IF_DEF_DSTN)) {
-     tempbx++;
-  }
+     VCLKIndex = CRT2Index;
 
-  if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
+     if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {  /* programming CRT2 */
 
-  temp = tempbx & 0x00FF;
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,temp);       	 /* Part1_18h; Panel Link Vertical Retrace Start  */
+        if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
 
-  tempcx >>= 3;
+	   VCLKIndex &= 0x1f;
+           tempbx = 0;
+	   if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
+           if(SiS_Pr->SiS_TVMode & TVSetPAL) {
+	      tempbx += 2;
+	      if(SiS_Pr->SiS_ModeType > ModeVGA) {
+		 if(SiS_Pr->SiS_CHSOverScan) tempbx = 8;
+	      }
+	      if(SiS_Pr->SiS_TVMode & TVSetPALM) {
+		 tempbx = 4;
+		 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
+	      } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
+		 tempbx = 6;
+		 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) 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];
 
-  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( (HwDeviceExtension->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(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;
-		}
-        }
-     }
-  }
+        } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
 
-  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.  */
+	   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 R series */
+	      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 = ?; */
+	      }
+	   }
 
-  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(HwDeviceExtension->jChipType >= SIS_315H) {
-        if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
-           temp |= 0x80;
+        } 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( (HwDeviceExtension->jChipType == SIS_630) ||
-	    (HwDeviceExtension->jChipType == SIS_730) ) {
-	   if(HwDeviceExtension->jChipRevision >= 0x30) {
-	      temp |= 0x80;
+
+     } 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
 	   }
-	}
+        }
+
      }
+
   }
-  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,0x87,temp);  /* Part1_1Ah; Panel Link Control Signal (7:3); Vertical Retrace Start (2:0) */
+  
+#ifdef TWDEBUG
+  xf86DrvMsg(0, X_INFO, "VCLKIndex %d (0x%x)\n", VCLKIndex, VCLKIndex);
+#endif
 
-  if (HwDeviceExtension->jChipType < SIS_315H) {
+  return(VCLKIndex);
+}
 
-#ifdef SIS300      /* 300 series */
+/*********************************************/
+/*        SET CRT2 MODE TYPE REGISTERS       */
+/*********************************************/
 
-        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  */
+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, tempah2, tempbl2;
+#endif
 
-  	if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
-	   tempebx = 0x003F;
-	}
+  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;
+     }
+  }
+  
+  /* 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 */
 
-  	temp = (USHORT)(tempebx & 0x00FF);
-  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1E,temp);      /* Part1_1Eh; Panel Link Vertical Scaling Factor */
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
 
-#endif /* SIS300 */
+     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40);
+     SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2E,0xF7);
 
   } else {
 
-#ifdef SIS315H  /* 315 series */
+     for(i=0,j=4; i<3; i++,j++) SiS_SetReg(SiS_Pr->SiS_Part1Port,j,0);
 
-        if(HwDeviceExtension->jChipType == SIS_740) {
-           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x03);
-        } else {
-	   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1E,0x23);
-	}
+     tempcl = SiS_Pr->SiS_ModeType;
 
-	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; Panel Link Vertical Scaling Factor */
-    	temp = (USHORT)((tempebx & 0x00FF00) >> 8);
-    	SiS_SetReg1(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_SetReg1(SiS_Pr->SiS_Part1Port,0x35,temp);      /* Part1_35h; Panel Link Vertical Scaling Factor */
+     if(HwInfo->jChipType < SIS_315H) {
 
-#endif /* SIS315H */
+#ifdef SIS300    /* ---- 300 series ---- */
 
-  }
+        /* 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);
+        }
 
-  tempbx = push2;                                  /* BPLVDEE  */
-  tempcx = push1;
+        if(ModeNo > 0x13) {
+           tempcl -= ModeVGA;
+           if((tempcl > 0) || (tempcl == 0)) {      /* tempcl is USHORT -> always true! */
+              tempah = ((0x10 >> tempcl) | 0x80);
+           }
+        } else tempah = 0x80;
 
-  push1 = temp;					   
+        if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)  tempah ^= 0xA0;
 
-  if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-   	if(!SiS_Pr->SiS_IF_DEF_FSTN && !SiS_Pr->SiS_IF_DEF_DSTN) {
-		if(HwDeviceExtension->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++;
-			}
-		}
-	}
-  }
+#endif  /* SIS300 */
 
-  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;
-     }
-  }
+     } else {
 
-  temp = ((tempbx & 0x0700) >> 8) << 3;
-  temp |= ((tempcx & 0x0700) >> 8);
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1D,temp);     	/* Part1_1Dh; Vertical Display Overflow; Control Signal */
+#ifdef SIS315H    /* ------- 315/330 series ------ */
 
-  temp = tempbx & 0x00FF;
-  /* if(SiS_Pr->SiS_IF_DEF_FSTN) temp++;  */
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1C,temp);      	/* Part1_1Ch; Panel Link Vertical Display Enable End  */
+        if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+           if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
+	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x08);
+           }
+        }
 
-  temp = tempcx & 0x00FF;
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1B,temp);      	/* Part1_1Bh; Panel Link Vertical Display Enable Start  */
+        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;
 
-  /* 3. Additional horizontal setup (scaling, etc) */
+        if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50;
 
-  tempecx = SiS_Pr->SiS_VGAHDE;
-  if(HwDeviceExtension->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(HwDeviceExtension->jChipType >= SIS_315H) {
-        if(temp) tempeax++;
-     }
-  }
-  tempecx = tempeax;
+#endif  /* SIS315H */
 
-  if(HwDeviceExtension->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_SetReg1(SiS_Pr->SiS_Part1Port,0x1F,temp);  	 /* Part1_1Fh; 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 {
-     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;
-  }
+     if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
 
-  temp = ((tempbx & 0xFF00) >> 8) << 3;
-  temp |= (USHORT)((tempecx & 0x0700) >> 8);
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x20,temp);  	/* Part1_20h; Overflow register */
+     if(HwInfo->jChipType < SIS_315H) {
+        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
+     } else {
+        if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+           SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
+        } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
+           if(IS_SIS740) {
+	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
+	   } else {
+              SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
+	   }
+        }
+     }
 
-  temp = tempbx & 0x00FF;
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x21,temp);  	/* Part1_21h; Panel Link Vertical Accumulator Register */
+     if(SiS_Pr->SiS_VBType & VB_SISVB) {
 
-  tempecx >>= 16;                               /* BPLHCFACT  */
-  if((HwDeviceExtension->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_SetReg1(SiS_Pr->SiS_Part1Port,0x22,temp);     	/* Part1_22h; Panel Link Horizontal Scaling Factor High */
+        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;
+      	   }
+        }
 
-  temp = (USHORT)(tempecx & 0x00FF);
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x23,temp);         /* Part1_22h; Panel Link Horizontal Scaling Factor Low */
+        if(SiS_Pr->SiS_VBInfo & DisableCRT2Display)  tempah = 0;
 
-  /* 630/301B and 630/LVDS do something for 640x480 panels here */
+        if(HwInfo->jChipType < SIS_315H) {
 
-#ifdef SIS315H
-  if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
-     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);
-     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_SetReg1(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_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);
+      	   tempah = (tempah << 5) & 0xFF;
+      	   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
+      	   tempah = (tempah >> 5) & 0xFF;
 
-     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_SetReg1(SiS_Pr->SiS_Part1Port,0x3B,temp);
-     temp = ((tempax & 0xFF00) >> 8) << 3;
-     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);
+        } else {
 
-     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_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);
+      	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF8,tempah);
 
-     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_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 */
-     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_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,0x19,0x38);
+        }
 
-     if(SiS_Pr->SiS_IF_DEF_FSTN) {
-        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_SetReg1(SiS_Pr->SiS_Part1Port,0x35,0x0c);
-        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x36,0x00);
-        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x37,0x00);
-        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x38,0x80);
-        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x39,0xA0);
-        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3a,0x00);
-        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3b,0xf0);
-        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3c,0x00);
-        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3d,0x10);
-        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3e,0x00);
-        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3f,0x00);
-        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x40,0x10);
-        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x41,0x25);
-        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x42,0x80);
-        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x43,0x14);
-        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x44,0x03);
-        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x45,0x0a);
-     }
-  }
-#endif  /* SIS315H */
+        if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
+      	   tempah |= 0x10;
+        }
 
-}
+        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;
+        }
 
-#ifdef SIS315H
-void
-SiS_CRT2AutoThreshold(SiS_Private *SiS_Pr, USHORT BaseAddr)
-{
-  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40);
-}
-#endif
+        if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+	   if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p))) {
+      	      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+                 tempah |= 0x20;
+	      }
+      	   }
+        }
 
+        SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah);
 
-#ifdef SIS315H
-/* For LVDS / 302B/30xLV - LCDA (this must only be called on 315 series!) */
-void
-SiS_SetGroup1_LCDA(SiS_Private *SiS_Pr, USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                   PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex)
-{
-  USHORT modeflag,resinfo;
-  USHORT push1,push2,tempax,tempbx,tempcx,temp;
-  ULONG tempeax=0,tempebx,tempecx,tempvcfact;
+        tempah = 0;
 
-  /* This is not supported with LCDA */
-  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return;
-  if(SiS_Pr->UseCustomMode) return;
+	if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempah |= 0x40;
 
-  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(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 */
-     }
-  }
+        if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+	   if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) {
+              tempah |= 0x40;
+       	   }
+        }
 
-  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;
-  }
+	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;
+        }
 
-  tempax = SiS_Pr->SiS_LCDHDES;
-  tempbx = SiS_Pr->SiS_HDE;
-  tempcx = SiS_Pr->SiS_HT;
+        SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0C,tempah);
 
-  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;
+     } else {  /* LVDS */
 
-  push2 = tempax;						/* push ax   lcdhdee  */
+        if(HwInfo->jChipType >= SIS_315H) {
 
-  tempcx >>= 2;
+	   /* 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;
+	      }
+	   }
 
-  /* 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_Pr->SiS_VBInfo & SetInSlaveMode)) {
+              tempah |= 0x02;
+    	   }
 
-  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 & SetCRT2ToTV) {
+	      tempah ^= 0x01;
+	   }
 
-  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;
-		 }
-	      }
+	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
+	      tempah = 1;
 	   }
-	}
-     }
-  }
-  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  */
+    	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah);
 
-  tempcx >>= 3;   	                                     	/* BPLHDES */
-  temp = tempcx & 0x00FF;
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x16,temp);                         /* Part1_16h  */
+        } else {
 
-  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  */
+	   tempah = 0;
+	   if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
+              tempah |= 0x02;
+    	   }
+	   tempah <<= 5;
 
-  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 {
-     tempax = SiS_Pr->SiS_VGAVDE;
-  }
+	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display)  tempah = 0;
 
-  tempbx += tempax;
-  tempax = SiS_Pr->SiS_VT;                                    	/* VT  */
-  if(tempbx >= tempax)  tempbx -= tempax;
+	   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
 
-  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_SetReg1(SiS_Pr->SiS_Part1Port,0x18,temp);                             /* Part1_18h  */
+  }  /* LCDA */
 
-  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;
+  if(SiS_Pr->SiS_VBType & VB_SISVB) {
+
+     if(HwInfo->jChipType >= SIS_315H) {
+
+#ifdef SIS315H
+
+        unsigned char bridgerev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01);;
+
+	/* 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);
 	}
-     }
-  }
-  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_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80;
-     }
-  } else {
-     if(IS_SIS650) {
-        /* 650/30xLV 1.10.6s */
-        if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
-           if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80;
-        }
-     } else {
-	if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)  temp |= 0x80;
-     }
-  }
-  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,0x87,temp);            /* Part1_1Ah */
+	/* 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; P4_23=0xe5); the b1 version
+	 * in a 650 box (Jake). What is the criteria?
+	 */
 
-  tempbx = push2;                                      		/* BPLVDEE  */
-  tempcx = push1;                                      		/* NPLVDES */
-  push1 = (USHORT)(tempeax & 0xFFFF);
+	if((IS_SIS740) || (HwInfo->jChipType >= SIS_661)) {
+	   tempah = 0x30;
+	   tempbl = 0xc0;
+	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
+	      tempah = 0x00;
+	      tempbl = 0x00;
+	   }
+	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,tempah);
+	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,tempbl);
+	} 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   */
+	   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
+	} else if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);      /* For 30xLV */
+	   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);
+	} else if((SiS_Pr->SiS_VBType & VB_NoLCD) && (bridgerev == 0xb0)) {
+	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);      /* For 30xB-DH rev b0 (or "DH on 651"?) */
+	   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);
+	} else {
+	   tempah = 0x30; tempah2 = 0xc0;		       /* For 30xB (and 301BDH rev b1) */
+	   tempbl = 0xcf; tempbl2 = 0x3f;
+	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+	      tempah = tempah2 = 0x00;
+	      if(SiS_IsDualEdge(SiS_Pr, HwInfo)) {
+		 tempbl = tempbl2 = 0xff;
+	      }
+	   }
+	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
+	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
+	}
 
-  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--;
-  }
+	if(IS_SIS740) {
+	   tempah = 0x80;
+	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
+	      tempah = 0x00;
+	   }
+	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,0x7f,tempah);
+	} else {
+	   tempah = 0x00;
+           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);
+	}
 
-  temp = (tempbx & 0xFF00) >> 8;
-  temp &= 0x07;
-  temp <<= 3;
-  temp = temp | (((tempcx & 0xFF00) >> 8) & 0x07);
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1D,temp);                          /* Part1_1Dh */
+	/* 661: Sets p4 27 and 34 here, done in SetGroup4 here */
 
-  temp = tempbx & 0x00FF;
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1C,temp);                          /* Part1_1Ch  */
+#endif /* SIS315H */
 
-  temp = tempcx & 0x00FF;
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1B,temp);                          /* Part1_1Bh  */
+     } else if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
 
-  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);
+        SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
 
-  temp = (USHORT)((tempebx & 0x00FF00) >> 8);
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x36,temp);
+        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);
+	}
 
-  temp = (USHORT)((tempebx & 0x00030000) >> 16);
-  if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x35,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  */
+  } else {  /* LVDS */
 
-  tempeax = SiS_Pr->SiS_VGAVDE;
-  tempeax <<= 18;
-  tempeax = tempeax / tempvcfact;
-  tempbx = (USHORT)(tempeax & 0x0FFFF);
+#ifdef SIS315H
+     if(HwInfo->jChipType >= SIS_315H) {
 
-  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempbx--;
+        if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
 
-  if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA)  tempbx = 1;
+           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);
 
-  temp = ((tempbx & 0xFF00) >> 8) << 3;
-  temp = temp | (USHORT)(((tempecx & 0x0000FF00) >> 8) & 0x07);
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x20,temp);                         /* Part1_20h */
+	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
+	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
+	   }
 
-  temp = tempbx & 0x00FF;
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x21,temp);                         /* Part1_21h */
+	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
 
-  tempecx >>= 16;   	                                  	/* BPLHCFACT  */
-  if(modeflag & HalfDCLK) tempecx >>= 1;
-  temp = (USHORT)((tempecx & 0x0000FF00) >> 8);
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x22,temp);                         /* Part1_22h */
+	} else if(HwInfo->jChipType == SIS_550) {
 
-  temp=(USHORT)(tempecx & 0x000000FF);
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x23,temp);
+	   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
+	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
 
-#if 0
-  /* 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
 
-  /* 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);
   }
 
 }
-#endif  /* SIS 315 */
 
-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(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return;
+/*********************************************/
+/*            GET RESOLUTION DATA            */
+/*********************************************/
 
-  offset = SiS_GetOffset(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
-                         HwDeviceExtension);
+USHORT
+SiS_GetResInfo(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex)
+{
+  USHORT resindex;
 
-  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
-     SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) offset >>= 1;
+  if(ModeNo <= 0x13)
+     resindex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+  else
+     resindex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
 
-  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);
+  return(resindex);
 }
 
-USHORT
-SiS_GetOffset(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-              USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+static void
+SiS_GetCRT2ResInfo(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
+                   PSIS_HW_INFO HwInfo)
 {
-  USHORT temp,colordepth;
-  USHORT modeinfo,index,infoflag;
+  USHORT xres,yres,modeflag=0,resindex;
 
   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) & 0xFF;
-     temp = SiS_Pr->SiS_ScreenOffset[index];
+     SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = SiS_Pr->CHDisplay;
+     SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = SiS_Pr->CVDisplay;
+     return;
   }
-  
-  colordepth = SiS_GetColorDepth(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex);
-
-  if(infoflag & InterlaceMode) temp <<= 1;
 
-  temp *= colordepth;
+  resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex);
 
-  if( ( ((ModeNo >= 0x26) && (ModeNo <= 0x28)) ||
-        ModeNo == 0x3f ||
-	ModeNo == 0x42 || 
-	ModeNo == 0x45 ) ||
-      (SiS_Pr->UseCustomMode && (SiS_Pr->CHDisplay % 16)) ) {
-        colordepth >>= 1;
-	temp += colordepth;
+  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;
   }
 
-  return(temp);
-}
+  if((!SiS_Pr->SiS_IF_DEF_DSTN) && (!SiS_Pr->SiS_IF_DEF_FSTN)) {
 
-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_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;
+        }
+     }
 
-  /* 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;
-  }	
+     if(ModeNo > 0x13) {
+  	if(modeflag & HalfDCLK)       xres *= 2;
+  	if(modeflag & DoubleScanMode) yres *= 2;
+     }
+
+  }
 
-  index = (modeflag & ModeInfoFlag) - ModeEGA;
-  if(index < 0) index = 0;
-  return(ColorDepth[index]);
+  if(SiS_Pr->SiS_VBType & VB_SISVB) {
+        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 | SetCRT2ToHiVision)) {
+                   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 | SetCRT2ToHiVision)) {
+	         if(xres == 720) xres = 640;
+	      }
+	      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+		 if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
+		    if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
+        	       if(yres == 1024) yres = 1056;
+      		    }
+		 } else 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 {
+    	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_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
+  SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
 }
 
-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;
+/*********************************************/
+/*           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;
 
-  flag = 0;
-  tempbl = 0xC0;
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+     if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+        if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return FALSE;
+     }
+  } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
+     if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return FALSE;
+  } else
+     return FALSE;
 
-  if(SiS_Pr->UseCustomMode) {
-     infoflag = SiS_Pr->CInfoFlag;
+  if(ModeNo <= 0x13) {
+     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+     CRT2CRTC = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
   } else {
-     infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+     CRT2CRTC = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
   }
 
-  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {					/* LVDS */
+  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_TVMode & TVSetCHOverScan) tempbx++;
+        if(SiS_Pr->SiS_TVMode & TVSetPAL) {
+      	   tempbx += 2;
+	   if(SiS_Pr->SiS_ModeType > ModeVGA) {
+	      if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
+	   }
+	   if(SiS_Pr->SiS_TVMode & TVSetPALM) {
+	      tempbx = 18;  /* PALM uses NTSC data */
+	      if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx++;
+	   } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
+	      tempbx = 20;  /* PALN uses PAL data  */
+	      if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) 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++;
+        } 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++;
+        }
 
-    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;
-
-    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-       if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
-          (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
-	  tempah |= 0xc0;
-       }
-    }
+     }
+     if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
+        tempbx = 12;
+	if(modeflag & HalfDCLK) tempbx++;
+     }
+  }
 
-    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 0
+  if(SiS_Pr->SiS_IF_DEF_FSTN) {
+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel320x480){
+        tempbx = 22;
+     }
+  }
+#endif
 
-  } else {
+  *ResIndex = CRT2CRTC & 0x3F;
+  *DisplayType = tempbx;
+  return TRUE;
+}
 
-     if(HwDeviceExtension->jChipType < SIS_315H) {
+static void
+SiS_GetCRT2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
+	       USHORT RefreshRateTableIndex,USHORT *CRT2Index,USHORT *ResIndex,
+	       PSIS_HW_INFO HwInfo)
+{
+  USHORT tempbx=0,tempal=0;
+  USHORT Flag,resinfo=0;
 
-#ifdef SIS300  /* ---- 300 series --- */
+  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;
+  }
 
-        if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {			/* 630 - 301B(-DH) */
+  if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_IF_DEF_LVDS == 0)) {
 
-            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;
+     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;
 #if 0
-            if (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
-	       	/* BIOS does something here @@@ */
-            }
+	} 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;
+		 if(ModeNo >= 0x13) {
+	            /* see below */
+	            if(resinfo == SIS_RI_1280x960) tempal = 10;
+	         }
+              }
+	   } 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;
+       	   }
+	}
+
+#ifdef SIS315H
+	if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
+	   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+	      tempbx = 50;
+	      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)         tempbx = 51;
+	      else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx = 52;
+	   }
+	}
 #endif
 
- 	    tempah &= 0x3f;
-  	    tempah |= tempbl;
-            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
-
-         } else {							/* 630 - 301 */
-
-            tempah = infoflag >> 8;
-            tempah &= 0xC0;
-            tempah |= 0x20;
-	    if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
-            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
+     } else {						  	/* TV */
 
-         }
+     	if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
+           if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_TVMode &= (~TVSetTVSimuMode);
+           tempbx = 2;
+           if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+              if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) tempbx = 13;
+           }
+	} else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
+	   if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)      tempbx = 7;
+	   else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempbx = 6;
+	   else 					tempbx = 5;
+	   if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)     tempbx += 5;
+       	} else {
+           if(SiS_Pr->SiS_TVMode & TVSetPAL) 		tempbx = 3;
+           else 					tempbx = 4;
+           if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) 	tempbx += 5;
+       	}
 
-#endif /* SIS300 */
+     }
 
-      } else {
+     tempal &= 0x3F;
 
-#ifdef SIS315H  /* ------- 315 series ------ */
+     if(ModeNo > 0x13) {
+        if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) {
+      	   if(tempal == 6) tempal = 7;
+           if((resinfo == SIS_RI_720x480) ||
+	      (resinfo == SIS_RI_720x576) ||
+	      (resinfo == SIS_RI_768x576)) {
+	      tempal = 6;
+	   }
+	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
+              if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
+	         if(resinfo == SIS_RI_1024x768) {
+	            tempal = 8;
+	         }
+	      }
+	   }
+	}
+     }
 
-         if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {	  		/* 315 - 30xLV */
+     *CRT2Index = tempbx;
+     *ResIndex = tempal;
 
-	    if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
-	       tempah = infoflag >> 8;
-	       if(SiS_Pr->SiS_LCDInfo & LCDSync) {
-	          tempah = SiS_Pr->SiS_LCDInfo;
-	       }
-	    } else {
-               tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37);
-	    }
-	    tempah &= 0xC0;
+  } else {   /* LVDS, 301B-DH (if running on LCD) */
 
-            tempah |= 0x20;
-            if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
-            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
-
-         } else {							/* 315 - 301, 301B */
-
-            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;
-	    
-            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
+     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_TVMode & TVSetCHOverScan) tempbx += 1;
+           if(SiS_Pr->SiS_TVMode & TVSetPAL) {
+	      tempbx += 2;
+	      if(SiS_Pr->SiS_ModeType > ModeVGA) {
+		 if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
+	      }
+	      if(SiS_Pr->SiS_TVMode & TVSetPALM) {
+		 tempbx = 90;
+		 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
+	      } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
+		 tempbx = 92;
+		 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
+	      }
+           }
+        }
+     }
 
-	    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);
+     if(Flag) {
 
-         } 
-	 
-#endif  /* SIS315H */
-      }
-   }
-}
+	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;
 
-/* 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(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->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(SiS_Pr->SiS_LCDInfo & LCDPass11) {
+	   tempbx = 7;
+        }
 
-     if(CRT1ModeNo >= 0x13) {
-        index = SiS_Pr->SiS_RefIndex[refreshratetableindex].Ext_CRTVCLK;
-        index &= 0x3F;
-        VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;				/* Get VCLK */
+	if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
+	   tempbx = 84;
+	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx++;
+	}
 
-	colorth = SiS_GetColorDepth(SiS_Pr,ROMAddr,CRT1ModeNo,modeidindex); 	/* Get colordepth */
-        colorth >>= 1;
-        if(!colorth) colorth++;
      }
 
-  } else {
-  
-     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(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++;
+	}
      }
 
+     *CRT2Index = tempbx;
+     *ResIndex = tempal & 0x1F;
   }
+}
 
-  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 SIS315H
+static void
+SiS_GetCRT2PtrA(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
+		USHORT RefreshRateTableIndex,USHORT *CRT2Index,
+		USHORT *ResIndex)
+{
+  USHORT tempbx,tempal;
 
-    data2 = (colorth * VCLK) / MCLK;
+  tempbx = SiS_Pr->SiS_LCDResInfo;
 
-    temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
-    temp = ((temp & 0x00FF) >> 6) << 1;
-    if(temp == 0) temp = 1;
-    temp <<= 2;
-    temp &= 0xff;
+  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;
 
-    data2 = temp - data2;
-    
-    if((28 * 16) % data2) {
-      	data2 = (28 * 16) / data2;
-      	data2++;
-    } else {
-      	data2 = (28 * 16) / data2;
-    }
+  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx += 5;
 
-    if(HwDeviceExtension->jChipType == SIS_300) {
+  if(ModeNo <= 0x13)
+     tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+  else
+     tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
 
-	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;
+  /* No customs required yet (Clevo, Compaq, etc) */
 
-    } else if(HwDeviceExtension->jChipType == SIS_730) {
-       
-#ifndef LINUX_XF86
-       SiS_SetReg4(0xcf8,0x80000050);
-       eax = SiS_GetReg3(0xcfc);
-#else
-       eax = pciReadLong(0x00000000, 0x50);
+  *CRT2Index = tempbx;
+  *ResIndex = tempal & 0x1F;
+}
 #endif
-       tempal = (USHORT)(eax >> 8);
-       tempal &= 0x06;
-       tempal <<= 5;
 
-#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;
+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;
 
-       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 {
+  SiS_Pr->SiS_RVBHCMAX  = 1;
+  SiS_Pr->SiS_RVBHCFACT = 1;
 
-       index = 0;
-       temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
-       if(temp & 0x0080) index += 12;
+  if(ModeNo <= 0x13) {
 
-#ifndef LINUX_XF86
-       SiS_SetReg4(0xcf8,0x800000A0);
-       eax = SiS_GetReg3(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
-       temp = (USHORT)(eax >> 24);
-       if(!(temp&0x01)) index += 24;
+     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+     index = SiS_GetModePtr(SiS_Pr,ModeNo,ModeIdIndex);
 
-#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;
+     tempax = SiS_Pr->SiS_StandTable[index].CRTC[0];
+     tempbx = SiS_Pr->SiS_StandTable[index].CRTC[6];
+     temp1 = SiS_Pr->SiS_StandTable[index].CRTC[7];
 
-       temp = (temp & 0x0F) >> 1;
-       index += temp;
-       
-       data = LatencyFactor[index];
-       data += 15;
-       temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
-       if(!(temp & 0x80)) data += 5;
-    }
-    
-    data += data2;				/* CRT1 Request Period */
-    
-    SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
-    SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
+  } else {
 
-    if(!SiS_Pr->UseCustomMode) {
+     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+     index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
 
-       CRT2ModeNo = ModeNo;
-       SiS_SearchModeID(SiS_Pr,ROMAddr,&CRT2ModeNo,&modeidindex);
+     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];
 
-       refreshratetableindex = SiS_GetRatePtrCRT2(SiS_Pr,ROMAddr,CRT2ModeNo,
-                                                  modeidindex,HwDeviceExtension);
+  }
 
-       index = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,CRT2ModeNo,modeidindex,
-                               refreshratetableindex,HwDeviceExtension);
-       VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;                         	/* Get VCLK  */
+  if(temp1 & 0x01) tempbx |= 0x0100;
+  if(temp1 & 0x20) tempbx |= 0x0200;
+  
+  tempax += 5;
 
-       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);
-	     }
-          }
-       }
+  /* Charx8Dot is no more used (and assumed), so we set it */
+  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+     modeflag |= Charx8Dot;
+  }
 
-    } else {
+  if(modeflag & Charx8Dot) tempax *= 8;
+  else                     tempax *= 9;
 
-       CRT2ModeNo = 0xfe;
-       VCLK = SiS_Pr->CSRClock;							/* Get VCLK */
+  if(modeflag & HalfDCLK)  tempax <<= 1;
 
-    }
+  tempbx++;
 
-    colorth = SiS_GetColorDepth(SiS_Pr,ROMAddr,CRT2ModeNo,modeidindex);   	/* Get colordepth */
-    colorth >>= 1;
-    if(!colorth) colorth++;
+  SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
+  SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = tempbx;
+}
 
-    data = data * VCLK * colorth;
-    if(data % (MCLK << 4)) {
-      	data = data / (MCLK << 4);
-      	data++;
-    } else {
-      	data = data / (MCLK << 4);
-    }
-    
-    if(data <= 6) data = 6;
-    if(data > 0x14) data = 0x14;
+static void
+SiS_GetCRT2DataLVDS(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
+                    USHORT RefreshRateTableIndex,
+		    PSIS_HW_INFO HwInfo)
+{
+   USHORT CRT2Index, ResIndex;
+   const SiS_LVDSDataStruct *LVDSData = NULL;
 
-    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);
+   SiS_GetCRT2ResInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
 
-    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
+   if(SiS_Pr->SiS_VBType & VB_SISVB) {
+      SiS_Pr->SiS_RVBHCMAX  = 1;
+      SiS_Pr->SiS_RVBHCFACT = 1;
+      SiS_Pr->SiS_NewFlickerMode = 0;
+      SiS_Pr->SiS_RVBHRS = 50;
+      SiS_Pr->SiS_RY1COE = 0;
+      SiS_Pr->SiS_RY2COE = 0;
+      SiS_Pr->SiS_RY3COE = 0;
+      SiS_Pr->SiS_RY4COE = 0;
+   }
+
+   if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
 
-/* Set FIFO on 315/330 series */
 #ifdef SIS315H
-void
-SiS_SetCRT2FIFO_310(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,
-                    PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-#if 0   /* This code is obsolete */
-  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;
+      SiS_GetCRT2PtrA(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+                      &CRT2Index,&ResIndex);
 
-  SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;
+      switch (CRT2Index) {
+      	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_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_LCDA1024x768Data_1;    break;
+      }
 #endif
 
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x01,0x3B);
-
-#if 0
-  if(!SiS_Pr->CRT1UsesCustomMode) {
-  
-     CRT1ModeNo = SiS_Pr->SiS_CRT1Mode;                                 /* get CRT1 ModeNo */
-     SiS_SearchModeID(SiS_Pr,ROMAddr,&CRT1ModeNo,&ModeIdIndex);
+   } else {
 
-     SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);   
-     SiS_Pr->SiS_SelectCRT2Rate = 0;
+      /* 301BDH needs LVDS Data */
+      if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
+	 SiS_Pr->SiS_IF_DEF_LVDS = 1;
+      }
 
-     /* Get REFIndex for crt1 refreshrate */
-     RefreshRateTableIndex = SiS_GetRatePtrCRT2(SiS_Pr,ROMAddr,CRT1ModeNo,
-                                                ModeIdIndex,HwDeviceExtension);
-     index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
-     tempax = SiS_Pr->SiS_VCLKData[index].CLOCK;			/* Get VCLK */
+      SiS_GetCRT2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
+                     &CRT2Index, &ResIndex, HwInfo);
 
-     tempbx = SiS_GetColorDepth(SiS_Pr,ROMAddr,CRT1ModeNo,ModeIdIndex); /* Get colordepth */
-     tempbx >>= 1;
-     if(!tempbx) tempbx++;
+      /* 301BDH needs LVDS Data */
+      if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
+         SiS_Pr->SiS_IF_DEF_LVDS = 0;
+      }
 
-  } else {
+      switch (CRT2Index) {
+      	case  0:  LVDSData = SiS_Pr->SiS_LVDS800x600Data_1;    break;
+      	case  1:  LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1;   break;
+      	case  2:  LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_1;  break;
+      	case  3:  LVDSData = SiS_Pr->SiS_LVDS800x600Data_2;    break;
+      	case  4:  LVDSData = SiS_Pr->SiS_LVDS1024x768Data_2;   break;
+      	case  5:  LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_2;  break;
+	case  6:  LVDSData = SiS_Pr->SiS_LVDS640x480Data_1;    break;
+        case  7:  LVDSData = SiS_Pr->SiS_LVDSXXXxXXXData_1;    break;
+	case  8:  LVDSData = SiS_Pr->SiS_LVDS1400x1050Data_1;  break;
+	case  9:  LVDSData = SiS_Pr->SiS_LVDS1400x1050Data_2;  break;
+      	case 10:  LVDSData = SiS_Pr->SiS_CHTVUNTSCData;        break;
+      	case 11:  LVDSData = SiS_Pr->SiS_CHTVONTSCData;        break;
+      	case 12:  LVDSData = SiS_Pr->SiS_CHTVUPALData;         break;
+      	case 13:  LVDSData = SiS_Pr->SiS_CHTVOPALData;         break;
+      	case 14:  LVDSData = SiS_Pr->SiS_LVDS320x480Data_1;    break;
+	case 15:  LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1;   break;
+	case 16:  LVDSData = SiS_Pr->SiS_LVDS1152x768Data_1;   break;
+	case 17:  LVDSData = SiS_Pr->SiS_LVDS1024x600Data_2;   break;
+	case 18:  LVDSData = SiS_Pr->SiS_LVDS1152x768Data_2;   break;
+	case 19:  LVDSData = SiS_Pr->SiS_LVDS1280x768Data_1;   break;
+	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;  /* Super Overscan */
+	default:  LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1;   break;
+      }
+   }
 
-     CRT1ModeNo = 0xfe;
-     tempax = SiS_Pr->CSRClock_CRT1;					/* Get VCLK */
-     tempbx = (SiS_Pr->CModeFlag_CRT1 & 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;
-     }
-  
-  }
-    
-  tempax *= tempbx;
+   SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT;
+   SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT;
+   SiS_Pr->SiS_HT    = (LVDSData+ResIndex)->LCDHT;
+   SiS_Pr->SiS_VT    = (LVDSData+ResIndex)->LCDVT;
 
-  tempbx = SiS_GetMCLK(SiS_Pr,ROMAddr, HwDeviceExtension);     		/* Get MCLK */
+   if(SiS_Pr->SiS_VBType & VB_SISVB) {
 
-  tempax /= tempbx;
+      if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
+         SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
+         SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
+      }
 
-  tempbx = tempax;
+   } else {
 
-  tempax = 16;
+      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;
+		     }
+		  }
+               }
+            }
+         }
+      }
+   }
+}
 
-  tempax -= tempbx;
+static void
+SiS_GetCRT2Data301(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
+                   USHORT RefreshRateTableIndex,
+		   PSIS_HW_INFO HwInfo)
+{
+  USHORT tempax,tempbx,modeflag;
+  USHORT resinfo;
+  USHORT CRT2Index,ResIndex;
+  const SiS_LCDDataStruct *LCDPtr = NULL;
+  const SiS_TVDataStruct  *TVPtr  = NULL;
 
-  tempbx = tempax;    /* tempbx = 16-DRamBus - DCLK*BytePerPixel/MCLK */
+  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;
+     }
+  }
+  
+  SiS_Pr->SiS_NewFlickerMode = 0;
+  SiS_Pr->SiS_RVBHRS = 50;
+  SiS_Pr->SiS_RY1COE = 0;
+  SiS_Pr->SiS_RY2COE = 0;
+  SiS_Pr->SiS_RY3COE = 0;
+  SiS_Pr->SiS_RY4COE = 0;
 
-  tempax = ((52 * 16) / tempbx);
+  SiS_GetCRT2ResInfo(SiS_Pr,ModeNo,ModeIdIndex,HwInfo);
 
-  if ((52*16 % tempbx) != 0) {
-    	tempax++;
-  }
-  tempcx = tempax;
-  tempcx += 40;
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC){
 
-  /* 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 */
-
-  for (temp3 = 0; temp3 < 16; temp3 += 2) {
-    if ((CombCode[temp3] == tempcl) && (CombCode[temp3+1] == tempch)) {
-      temp3 = CRT2ThLow[temp3 >> 1];
-    }
-  }
+     if(SiS_Pr->UseCustomMode) {
 
-  tempcx +=  temp3;                                      /* CRT1 Request Period */
+        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_Pr->SiS_SetFlag |= ProgrammingCRT2;
-  SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
+     } else {
 
-  if(!SiS_Pr->UseCustomMode) {
+        SiS_GetRAMDAC2DATA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
+     }
 
-     CRT2ModeNo = ModeNo;                                                 /* get CRT2 ModeNo */
-     SiS_SearchModeID(SiS_Pr,ROMAddr,&CRT2ModeNo,&ModeIdIndex);
+  } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
 
-     RefreshRateTableIndex = SiS_GetRatePtrCRT2(SiS_Pr,ROMAddr,CRT2ModeNo,
-                                                ModeIdIndex,HwDeviceExtension);
+     SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+                    &CRT2Index,&ResIndex,HwInfo);
 
-     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  */
-     } else {
-        tempax = SiS_Pr->SiS_VBVCLKData[index].CLOCK;
+     switch(CRT2Index) {
+       case  2:  TVPtr = SiS_Pr->SiS_ExtHiTVData;   break;
+       case  3:  TVPtr = SiS_Pr->SiS_ExtPALData;    break;
+       case  4:  TVPtr = SiS_Pr->SiS_ExtNTSCData;   break;
+       case  5:  TVPtr = SiS_Pr->SiS_Ext525iData;   break;
+       case  6:  TVPtr = SiS_Pr->SiS_Ext525pData;   break;
+       case  7:  TVPtr = SiS_Pr->SiS_Ext750pData;   break;
+       case  8:  TVPtr = SiS_Pr->SiS_StPALData;     break;
+       case  9:  TVPtr = SiS_Pr->SiS_StNTSCData;    break;
+       case 10:  TVPtr = SiS_Pr->SiS_St525iData;    break;
+       case 11:  TVPtr = SiS_Pr->SiS_St525pData;    break;
+       case 12:  TVPtr = SiS_Pr->SiS_St750pData;    break;
+       case 14:  TVPtr = SiS_Pr->SiS_St2HiTVData;   break;
+       default:  TVPtr = SiS_Pr->SiS_StPALData;     break;
+     }
+
+     SiS_Pr->SiS_RVBHCMAX  = (TVPtr+ResIndex)->RVBHCMAX;
+     SiS_Pr->SiS_RVBHCFACT = (TVPtr+ResIndex)->RVBHCFACT;
+     SiS_Pr->SiS_VGAHT     = (TVPtr+ResIndex)->VGAHT;
+     SiS_Pr->SiS_VGAVT     = (TVPtr+ResIndex)->VGAVT;
+     SiS_Pr->SiS_HDE       = (TVPtr+ResIndex)->TVHDE;
+     SiS_Pr->SiS_VDE       = (TVPtr+ResIndex)->TVVDE;
+     SiS_Pr->SiS_RVBHRS    = (TVPtr+ResIndex)->RVBHRS;
+     SiS_Pr->SiS_NewFlickerMode = (TVPtr+ResIndex)->FlickerMode;
+     if(modeflag & HalfDCLK) {
+        SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->HALFRVBHRS;
      }
 
-  } else {
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
 
-     CRT2ModeNo = 0xfe;							  /* Get VCLK  */
-     tempax = SiS_Pr->CSRClock;
+        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;
+
+        if(SiS_Pr->SiS_VGAVDE == 350) SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
+
+        SiS_Pr->SiS_HT = ExtHiTVHT;
+        SiS_Pr->SiS_VT = ExtHiTVVT;
+        if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+           if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
+              SiS_Pr->SiS_HT = StHiTVHT;
+              SiS_Pr->SiS_VT = StHiTVVT;
+              if(!(modeflag & Charx8Dot)) {
+                 SiS_Pr->SiS_HT = StHiTextTVHT;
+                 SiS_Pr->SiS_VT = StHiTextTVVT;
+              }
+           }
+        }
 
-  }
+     } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
 
-  tempbx = SiS_GetColorDepth(SiS_Pr,ROMAddr,CRT2ModeNo,ModeIdIndex);   	  /* Get colordepth */
-  tempbx >>= 1;
-  if(!tempbx) tempbx++;
+        if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
+           SiS_Pr->SiS_HT = 1650;
+           SiS_Pr->SiS_VT = 750;
+	} else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
+	   SiS_Pr->SiS_HT = NTSCHT;
+	   SiS_Pr->SiS_VT = NTSCVT;
+        } else {
+           SiS_Pr->SiS_HT = NTSCHT;
+	   if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
+           SiS_Pr->SiS_VT = NTSCVT;
+        }
 
-  tempax *= tempbx;
+     } else {
 
-  tempax *= tempcx;
+        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;
 
-  tempbx = SiS_GetMCLK(SiS_Pr,ROMAddr, HwDeviceExtension);	       /* Get MCLK */
-  tempbx <<= 4;
+        if(modeflag & HalfDCLK) {
+           SiS_Pr->SiS_RY1COE = 0x00;
+           SiS_Pr->SiS_RY2COE = 0xf4;
+           SiS_Pr->SiS_RY3COE = 0x10;
+           SiS_Pr->SiS_RY4COE = 0x38;
+        }
 
-  tempcx = tempax;
-  tempax /= tempbx;
-  if(tempcx % tempbx) tempax++;		/* CRT1 Request period * TCLK * BytePerPixel / (MCLK*16) */
+        if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
+           SiS_Pr->SiS_HT = NTSCHT;
+	   if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
+           SiS_Pr->SiS_VT = NTSCVT;
+        } else {
+           SiS_Pr->SiS_HT = PALHT;
+           SiS_Pr->SiS_VT = PALVT;
+        }
 
-  if (tempax > 0x37)  tempax = 0x37;
+     }
 
-  /* 650/LVDS, 650/301LV, 740, 330 overrule calculated value; 315 does not */
-  if(HwDeviceExtension->jChipType >= SIS_650) {
-  	tempax = 0x04;
-  }
-  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3F,tempax);
-#else
+  } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
 
-  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3F,0x04);
+     if(SiS_Pr->UseCustomMode) {
 
-#endif
-}
+        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;
 
-USHORT
-SiS_GetMCLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-  USHORT index;
+     } else {
 
-  index = SiS_Get310DRAMType(SiS_Pr,ROMAddr,HwDeviceExtension);
-  if(index >= 4) {
-    index -= 4;
-    return(SiS_Pr->SiS_MCLKData_1[index].CLOCK);
-  } else {
-    return(SiS_Pr->SiS_MCLKData_0[index].CLOCK);
-  }
-}
+        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;
+        }
 
-/* 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 BaseAddr)
-{
-  USHORT modeflag;
-  USHORT PanelIndex,ResIndex;
-  const  SiS_LVDSDesStruct *PanelDesPtr = NULL;
-
-  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;
-  }
+        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;
 
-  if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+#ifdef TWDEBUG
+        xf86DrvMsg(0, X_INFO,
+    	    "GetCRT2Data: Index %d ResIndex %d\n", CRT2Index, ResIndex);
+#endif
 
-#ifdef SIS315H  
-     SiS_GetLVDSDesPtrA(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
-                        &PanelIndex,&ResIndex, HwDeviceExtension, BaseAddr);
-			
-     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;
+	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_Panel1400x1050) &&
+	          (HwInfo->jChipType >= SIS_661)) {
+	   tempax = 1400;
+	   tempbx = 1050;
+	   if(SiS_Pr->SiS_VGAVDE == 1024) {
+	      tempax = 1280;
+	      tempbx = 1024;
+	   }
+        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
+           tempax = 1600;
+	   tempbx = 1200;
+	   if((HwInfo->jChipType < SIS_661) || (!(SiS_Pr->SiS_SetFlag & LCDVESATiming))) {
+              if     (SiS_Pr->SiS_VGAVDE == 350)  tempbx = 875;
+              else if(SiS_Pr->SiS_VGAVDE == 400)  tempbx = 1000;
+           }
+        } 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;
+     }
+  }
+}
+
+static void
+SiS_GetCRT2Data(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+                USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
+{
+
+  if(SiS_Pr->SiS_VBType & VB_SISVB) {
+
+     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+
+        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+
+           SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
+
+        } else {
+
+	   if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
+
+	      /* Need LVDS Data for LCD on 301B-DH */
+	      SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
+
+	   } else {
+
+	      SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
+
+           }
+
+        }
+
+     } else {
+
+     	SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
+
+     }
+
+  } else {
+
+     SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
+
+  }
+}
+
+/*********************************************/
+/*            GET LVDS DES DATA              */
+/*********************************************/
+
+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(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_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) tempbx += 2;
+        if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
+        /* 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(HwInfo->jChipType >= SIS_661) {
+        /* As long as we don's use the BIOS tables, we
+	 * need to convert the TypeInfo as for 315 series
+	 */
+        tempbx = SiS_Pr->SiS_LCDResInfo - 1;
+     }
+     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 16;
+     if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
+        tempbx = 32;
+        if(modeflag & HalfDCLK) tempbx++;
+     }
+  }
+
+  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
+static void
+SiS_GetLVDSDesPtrA(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+                   USHORT RefreshRateTableIndex, USHORT *PanelIndex, USHORT *ResIndex,
+		   PSIS_HW_INFO HwInfo)
+{
+  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 - 2;
+
+  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx += 4;
+
+  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) ||
+     (SiS_Pr->SiS_CustomT == CUT_UNIWILL10242)) {
+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+	tempbx = 82;
+	if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
+     }
+  }
+  if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+	tempbx = 84;
+	if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
+     }
+  }
+  if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+	tempbx = 86;
+	if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
+     }
+  }
+
+  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;
+}
+#endif
+
+static void
+SiS_GetLVDSDesData(SiS_Private *SiS_Pr, USHORT ModeNo,USHORT ModeIdIndex,
+                   USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
+{
+  USHORT modeflag;
+  USHORT PanelIndex,ResIndex;
+  const  SiS_LVDSDesStruct *PanelDesPtr = NULL;
+
+  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((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+
+#ifdef SIS315H
+     SiS_GetLVDSDesPtrA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
+                        &PanelIndex, &ResIndex, HwInfo);
+
+     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 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;
+	case 84: PanelDesPtr = (SiS_LVDSDesStruct *)Compaq1280x1024Des_1; break;
+	case 85: PanelDesPtr = (SiS_LVDSDesStruct *)Compaq1280x1024Des_2; break;
+	case 86: PanelDesPtr = (SiS_LVDSDesStruct *)Asus1024x768Des_1;    break;  /*  custom  */
+	case 87: PanelDesPtr = (SiS_LVDSDesStruct *)Asus1024x768Des_2;    break;
 	default: PanelDesPtr = SiS_Pr->LVDS1024x768Des_1;   break;
      }
 #endif
 
   } else {
 
-     SiS_GetLVDSDesPtr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
-                       &PanelIndex,&ResIndex,HwDeviceExtension);
+     SiS_GetLVDSDesPtr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
+                       &PanelIndex, &ResIndex, HwInfo);
 
      switch (PanelIndex)
      {
@@ -2790,7 +3540,7 @@
      	case 52: PanelDesPtr = SiS_Pr->SiS_CHTVUPALDesData;    break;
      	case 53: PanelDesPtr = SiS_Pr->SiS_CHTVOPALDesData;    break;
 	default:
-		 if(HwDeviceExtension->jChipType < SIS_315H)
+		 if(HwInfo->jChipType < SIS_315H)
 		    PanelDesPtr = SiS_Pr->SiS_PanelType0e_1;
 		 else
 		    PanelDesPtr = SiS_Pr->SiS_PanelType01_1;
@@ -2810,12 +3560,11 @@
         }
      } 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(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(HwInfo->jChipType < SIS_315H) {
 	               if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320;
 	            } else {
 	               if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)
@@ -2838,4487 +3587,3696 @@
         }
      }
   }
-
 }
 
-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;
-  }
-
-  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_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++;
-     }
-  }
-  /* 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++;
-        }
-     }
-  }
+/*********************************************/
+/*          SET CRT2 AUTO-THRESHOLD          */
+/*********************************************/
 
-  *PanelIndex = tempbx;
-  *ResIndex = tempal & 0x1F;
+#ifdef SIS315H
+static void
+SiS_CRT2AutoThreshold(SiS_Private *SiS_Pr)
+{
+  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40);
 }
+#endif
 
-#ifdef SIS315H
+/*********************************************/
+/*           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_GetLVDSDesPtrA(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                   USHORT RefreshRateTableIndex,USHORT *PanelIndex,USHORT *ResIndex,
-		   PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
+SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
-  USHORT tempbx=0,tempal;
+#ifdef SIS315H
+  USHORT tempah,pushax=0,modenum;
+#endif
+  USHORT temp=0;
 
-  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(SiS_Pr->SiS_VBType & VB_SISVB) {
 
-  if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
-     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
-        if(SiS_IsDualLink(SiS_Pr, HwDeviceExtension, BaseAddr)) {
-	   tempbx = 80;
-	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
-	}
-     }
-  }
+      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {   /* ===== For 30xB/LV ===== */
 
-  if(ModeNo <= 0x13)
-     tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-  else
-     tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+        if(HwInfo->jChipType < SIS_315H) {
 
-  *PanelIndex = tempbx;
-  *ResIndex = tempal & 0x1F;
-}
-#endif
-
-void
-SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT BaseAddr, USHORT ModeNo, USHORT ModeIdIndex,
-                    PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-  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(SiS_Pr->UseCustomMode) {
-        modeflag = SiS_Pr->CModeFlag;
-     } else {
-    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-     }
-  }
-  
-  /* 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 */
+#ifdef SIS300	   /* 300 series */
 
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+           if(HwInfo->jChipType == SIS_300) {  /* For 300+301LV (A907) */
 
-	/*   1. for LVDS/302B/302LV **LCDA** */
+	      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);
+		 }
+	      }
+	      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_Pr->SiS_VBType & VB_SIS301LV302LV) {
+	         if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ||
+	             (!(SiS_CR36BIOSWord23d(SiS_Pr, HwInfo))) ) {
+	            SiS_PanelDelay(SiS_Pr, HwInfo, 2);
+                    SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
+		 }
+	      }
 
-      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40); /* FUNCTION CONTROL */
-      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2E,0xF7);
+	   } else {
 
-  } else {
+	      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);
+	      }
+	   }
 
-    for(i=0,j=4; i<3; i++,j++) SiS_SetReg1(SiS_Pr->SiS_Part1Port,j,0);
+#endif  /* SIS300 */
 
-    tempcl = SiS_Pr->SiS_ModeType;
+        } else {
 
-    if(HwDeviceExtension->jChipType < SIS_315H) {
+#ifdef SIS315H	   /* 315 series */
 
-#ifdef SIS300    /* ---- 300 series ---- */
+           if(IS_SIS550650740660) {		/* 550, 650, 740, 660 */
 
-      /* For 301BDH: (with LCD via LVDS) */
-      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);
-      }
+	      modenum = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34) & 0x7f;
 
-      if(ModeNo > 0x13) {
-         tempcl -= ModeVGA;
-         if((tempcl > 0) || (tempcl == 0)) {      /* tempcl is USHORT -> always true! */
-            tempah = ((0x10 >> tempcl) | 0x80);
-         }
-      } else tempah = 0x80;
+              if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {			/* LV */
+#ifdef SET_EMI
+	         if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
+		    if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
+	               SiS_SetReg(SiS_Pr->SiS_Part4Port,0x30,0x00);
+		    }
+		 }
+#endif
+		 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(SiS_Pr->SiS_VBInfo & SetInSlaveMode)  tempah ^= 0xA0;
+		 if((SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) &&
+		    (SiS_Pr->SiS_CustomT != CUT_CLEVO1400)) {
+		    SiS_DDC2Delay(SiS_Pr,0xff00);
+		    SiS_DDC2Delay(SiS_Pr,0xe000);
 
-#endif  /* SIS300 */
+	            SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
 
-    } else {
+                    pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
 
-#ifdef SIS315H    /* ------- 315/330 series ------ */
+		    if(IS_SIS740) {
+		       SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
+		    }
 
-      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-         if(SiS_Pr->SiS_VBInfo & CRT2DisplayFlag) {
-	    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x08);
-         }
-      }
+	            SiS_PanelDelay(SiS_Pr, HwInfo, 3);
 
-      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;
+		    if(!(SiS_IsNotM650orLater(SiS_Pr, HwInfo))) {
+	               tempah = 0xef;
+	               if(SiS_IsVAMode(SiS_Pr,HwInfo)) {
+	                  tempah = 0xf7;
+                       }
+	               SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
+	            }
+		 }
 
-      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)  tempah ^= 0x50;
+              } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {			/* B-DH */
 
-#endif  /* SIS315H */
+	         if(!(SiS_IsNotM650orLater(SiS_Pr,HwInfo))) {
+	            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,0xef);
+	         }
 
-    }
+	      }
 
-    if(SiS_Pr->SiS_VBInfo & CRT2DisplayFlag)  tempah = 0;
+	      if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
+	         (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) {
+	         SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,0xef);
+	      }
 
-    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_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(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+              if((SiS_IsVAMode(SiS_Pr,HwInfo)) ||
+	         ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && (modenum <= 0x13))) {
 
-	/*   2. for 301 (301B, 302B 301LV, 302LV non-LCDA) */
+	         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);
+		    }
+		 }
 
-    	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;
-      		}
-    	}
+	      } else {
 
-	if(SiS_Pr->SiS_VBInfo & CRT2DisplayFlag)  tempah = 0;
+	         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(HwDeviceExtension->jChipType < SIS_315H) {
+		 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);
 
-		/* ---- 300 series ---- */
+	      }
 
-      		tempah = (tempah << 5) & 0xFF;
-      		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x01,tempah);
-      		tempah = (tempah >> 5) & 0xFF;
+	      if((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) &&
+	         (SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) &&
+		 (SiS_Pr->SiS_CustomT != CUT_CLEVO1400)) {
 
-    	} else {
+		 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,~0x10);
 
-		/* ---- 315 series ---- */
+	         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);
 
-      		SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF8,tempah);
+		 if(SiS_IsNotM650orLater(SiS_Pr,HwInfo)) {
+	            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
+		 }
 
-    	}
+	         if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
+	            SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
+	            if(!(SiS_CRT2IsLCD(SiS_Pr,HwInfo))) {
+	               if(!(SiS_IsDualEdge(SiS_Pr,HwInfo))) {
+		          SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
+                       }
+                    }
+	         }
 
-    	if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
-      		tempah |= 0x10;
-	}
+	         SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
 
-	if((HwDeviceExtension->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->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
+	            if( (SiS_IsVAMode(SiS_Pr, HwInfo)) ||
+	                (SiS_CRT2IsLCD(SiS_Pr, HwInfo)) ) {
+		       SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 20);
+		    }
+	         }
 
-    	if(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)) {
-      		if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-			if(!(SiS_Pr->SiS_HiVision & 0x03)) {
-          			tempah |= 0x20;
-			}
-      		}
-    	}
+  	      } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
 
-    	SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah);
+	         /* NIL */
 
-    	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 if((SiS_Pr->SiS_VBType & VB_SIS301B302B) ||
+	                (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
+			(SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) {
+
+		 if(!(SiS_IsNotM650orLater(SiS_Pr,HwInfo))) {
+	            tempah = 0xef;
+	            if(SiS_IsDualEdge(SiS_Pr,HwInfo)) {
+		       if(modenum > 0x13) {
+	                  tempah = 0xf7;
+		       }
+                    }
+	            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
+		 }
+		 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);
+	               }
+		    }
 		 }
-     	      } else {
-        	SiS_Pr->SiS_SetFlag |= RPLLDIV2XO;
-        	tempah |= 0x40;
-      	      }
-	   }
-    	}
 
-	/* For 302LV dual-channel */
-	if(HwDeviceExtension->jChipType >= SIS_315H) {
-	   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-	      if(SiS_IsDualLink(SiS_Pr, HwDeviceExtension, BaseAddr))
-	         tempah |= 0x40;
-	   }
-	}
+	      }
 
-	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;
-	}
+	  } else {			/* 315, 330 - all bridge types */
 
-    	SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0C,tempah);
+	     if(SiS_Is301B(SiS_Pr)) {
+	        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(SiS_IsVAMode(SiS_Pr,HwInfo)) {
+	           SiS_DisplayOff(SiS_Pr);
+		   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
+	        }
+	     }
+	     if( (!(SiS_Is301B(SiS_Pr))) ||
+	         (!(SiS_IsVAMode(SiS_Pr,HwInfo))) ) {
 
-    } else {
+ 	 	if( (!(SiS_Is301B(SiS_Pr))) ||
+		    (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ) {
 
-    	/* 3. for LVDS */
+	           SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
+	           SiS_DisplayOff(SiS_Pr);
 
-	if(HwDeviceExtension->jChipType >= SIS_315H) {
+		}
 
-	   /* 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;
-	       }
-	   }
+                SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
 
-	   if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-               tempah |= 0x02;
-    	   }
+                SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
 
-	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-	       tempah ^= 0x01;
-	   }
+	        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);
 
-	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
-	       tempah = 1;
-	   }
+	     }
 
-    	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah);
+	  }    /* 315/330 */
 
-	} else {
+#endif /* SIS315H */
 
-	   /* (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;
+      } else {     /* ============ For 301 ================ */
+
+        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_SetReg1(SiS_Pr->SiS_Part1Port,0x01,tempah);
+        SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);           /* disable VB */
+        SiS_DisplayOff(SiS_Pr);
 
+        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(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_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);
+	    }
+	}
 
-  /* Inserted the entire following section */
+      }
 
-  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+  } else {     /* ============ For LVDS =============*/
 
-      if(HwDeviceExtension->jChipType >= SIS_315H) {
+    if(HwInfo->jChipType < SIS_315H) {
 
-#ifdef SIS315H
+#ifdef SIS300	/* 300 series */
 
-         unsigned char bridgerev = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x01);;
+	if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
+	   SiS_SetCH700x(SiS_Pr,0x090E);
+	}
 
-	 /* 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...?
-	  */
+	if(HwInfo->jChipType == SIS_730) {
+	   if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
+	      SiS_WaitVBRetrace(SiS_Pr,HwInfo);
+	   }
+	   if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
+	      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF7,0x08);
+	      SiS_PanelDelay(SiS_Pr, HwInfo, 3);
+	   }
+	} else {
+	   if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
+	      if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
+  	         if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
+                    SiS_WaitVBRetrace(SiS_Pr,HwInfo);
+		    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);
+                 }
+              }
+	   }
+	}
 
-	 /* 740 variants match for 30xB, 301B-DH, 30xLV */
+	SiS_DisplayOff(SiS_Pr);
 
-         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);   
-	 }
+	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
 
-	 /* 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?
-	  */
+	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(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, HwDeviceExtension, BaseAddr)) {
-		  tempbl = 0xff;
-	       }
-	    }
-	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
-	 }
+	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);
+	}
 
-	 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, HwDeviceExtension, BaseAddr)) {
-		  tempbl = 0xff;
-	       }
-	    }
-	    SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl,tempah);
-	 }
+#endif  /* SIS300 */
 
-	 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);
-	 }
+    } else {
 
-#endif /* SIS315H */
+#ifdef SIS315H	/* 315 series */
 
-      } else if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
 
-         SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
+	   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_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_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);
+	   }
 
-  } else {  /* LVDS */
+	   if(HwInfo->jChipType != SIS_740) {
+	      if( (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
+	          (SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo)) ) {
+	   	 SiS_SetCH701x(SiS_Pr,0x0149);
+  	      } 
+	   }
 
-#ifdef SIS315H
-      if(HwDeviceExtension->jChipType >= SIS_315H) {
+	}
 
-         if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+	if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
+	   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF7,0x08);
+	   SiS_PanelDelay(SiS_Pr, HwInfo, 3);
+	}
 
-            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( (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_VBInfo & DisableCRT2Display) {
-	       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x00);
-	    }
+	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);
+	}
 
-	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,0x30);
+	if(HwInfo->jChipType == SIS_740) {
+	   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
+	}
 
-	 } else if(HwDeviceExtension->jChipType == SIS_550) {
+	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
 
-#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);
+	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);
+	}
 
-	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,0x30);
-	 }
+	if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
+	   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);
+	   }
+	}
 
-      }
-#endif
+	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+	   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,HwInfo);
+
+	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(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
+	   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 */
+
+    }  /* 310 series */
+
+  }  /* LVDS */
 
 }
 
+/*********************************************/
+/*            ENABLE VIDEO BRIDGE            */
+/*********************************************/
+
+/* NEVER use any variables (VBInfo), this will be called
+ * from outside the context of a mode switch!
+ * MUST call getVBType before calling this
+ */
 void
-SiS_GetCRT2Data(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                USHORT RefreshRateTableIndex,
-		PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
+  USHORT temp=0,tempah;
+#ifdef SIS315H
+  USHORT temp1,pushax=0;
+  BOOLEAN delaylong = FALSE;
+#endif
 
-  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
-
-     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
 
-        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+  if(SiS_Pr->SiS_VBType & VB_SISVB) {
 
-           SiS_GetCRT2DataLVDS(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
-	                      HwDeviceExtension);
-        } else {
+    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {   /* ====== For 301B et al  ====== */
 
-	   if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_VBType & VB_NoLCD) ) {
+      if(HwInfo->jChipType < SIS_315H) {
 
-	      /* Need LVDS Data for LCD on 301B-DH */
-	      SiS_GetCRT2DataLVDS(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
-	                          HwDeviceExtension);
-				  
-	   } else {
-	
-	      SiS_GetCRT2Data301(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
-	                         HwDeviceExtension);
-           }
+#ifdef SIS300     /* 300 series */
 
-        }
+         if(HwInfo->jChipType == SIS_300) {
 
-     } else {
+	    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, HwInfo))) {
+	             SiS_PanelDelay(SiS_Pr, HwInfo, 0);
+	          }
+	       }
+	    }
+	    temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;             /* lock mode */
+            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);
+	    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20);        /* enable VB processor */
+	    SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
+	    SiS_DisplayOn(SiS_Pr);
+	    if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
+	       if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+	          if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
+		     if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
+		        SiS_PanelDelay(SiS_Pr, HwInfo, 1);
+                     }
+		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
+	 	  }
+	       }
+	    }
 
-     	SiS_GetCRT2Data301(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
-	                   HwDeviceExtension);
-     }
+	 } else {
 
-  } else {
-  
-     SiS_GetCRT2DataLVDS(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
-                         HwDeviceExtension);
-  }
-}
+	    if((SiS_Pr->SiS_VBType & VB_NoLCD) &&
+	       (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,HwInfo))) {
+	          SiS_PanelDelay(SiS_Pr, HwInfo, 0);
+	       }
+	       SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);   /* Enable CRT2 */
+               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_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,HwInfo);
+                       SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF7,0x00);
+                   }
+	       }
+            } else {
+	       temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;             /* lock mode */
+               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);
+	       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20);        /* enable VB processor */
+	       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
+	       SiS_DisplayOn(SiS_Pr);
+	    }
 
-/* Checked with 650/LVDS 1.10.07 BIOS */
-void
-SiS_GetCRT2DataLVDS(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                    USHORT RefreshRateTableIndex,
-		    PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-   USHORT CRT2Index, ResIndex;
-   const SiS_LVDSDataStruct *LVDSData = NULL;
+         }
+#endif /* SIS300 */
 
-   SiS_GetCRT2ResInfo(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
-   
-   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-      SiS_Pr->SiS_RVBHCMAX  = 1;
-      SiS_Pr->SiS_RVBHCFACT = 1;
-      SiS_Pr->SiS_NewFlickerMode = 0;
-      SiS_Pr->SiS_RVBHRS = 50;
-      SiS_Pr->SiS_RY1COE = 0;
-      SiS_Pr->SiS_RY2COE = 0;
-      SiS_Pr->SiS_RY3COE = 0;
-      SiS_Pr->SiS_RY4COE = 0;
-   }
+      } else {
 
-   if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+#ifdef SIS315H    /* 315 series */
 
-#ifdef SIS315H   
-      SiS_GetCRT2PtrA(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
-                      &CRT2Index,&ResIndex);
+	 if(IS_SIS550650740660) {		/* 550, 650, 740, 660 */
 
-      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  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  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      
+	    UCHAR r30=0, r31=0, r32=0, r33=0, cr36=0;
 
-   } else {
+	    if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
 
-      /* 301BDH needs LVDS Data */
-      if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_VBType & VB_NoLCD) ) {
-	      SiS_Pr->SiS_IF_DEF_LVDS = 1;
-      }
+	       if((SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) &&
+	          (SiS_Pr->SiS_CustomT != CUT_CLEVO1400)) {
+	          SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef);
+#ifdef SET_EMI
+		  if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
+	             SiS_SetReg(SiS_Pr->SiS_Part4Port,0x30,0x00);
+		  }
+#endif
+	       }
 
-      SiS_GetCRT2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
-                     &CRT2Index,&ResIndex,HwDeviceExtension);
+               if(!(SiS_IsNotM650orLater(SiS_Pr,HwInfo))) {
+	          tempah = 0x10;
+		  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);
+		  }
+	       }
 
-      /* 301BDH needs LVDS Data */
-      if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_VBType & VB_NoLCD) ) {
-              SiS_Pr->SiS_IF_DEF_LVDS = 0;
-      }
+	       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);
+	          }
+	       }
 
-      switch (CRT2Index) {
-      	case  0:  LVDSData = SiS_Pr->SiS_LVDS800x600Data_1;    break;
-      	case  1:  LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1;   break;
-      	case  2:  LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_1;  break;
-      	case  3:  LVDSData = SiS_Pr->SiS_LVDS800x600Data_2;    break;
-      	case  4:  LVDSData = SiS_Pr->SiS_LVDS1024x768Data_2;   break;
-      	case  5:  LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_2;  break;
-	case  6:  LVDSData = SiS_Pr->SiS_LVDS640x480Data_1;    break;
-        case  7:  LVDSData = SiS_Pr->SiS_LVDSXXXxXXXData_1;    break;
-	case  8:  LVDSData = SiS_Pr->SiS_LVDS1400x1050Data_1;  break;
-	case  9:  LVDSData = SiS_Pr->SiS_LVDS1400x1050Data_2;  break;
-      	case 10:  LVDSData = SiS_Pr->SiS_CHTVUNTSCData;        break;
-      	case 11:  LVDSData = SiS_Pr->SiS_CHTVONTSCData;        break;
-      	case 12:  LVDSData = SiS_Pr->SiS_CHTVUPALData;         break;
-      	case 13:  LVDSData = SiS_Pr->SiS_CHTVOPALData;         break;
-      	case 14:  LVDSData = SiS_Pr->SiS_LVDS320x480Data_1;    break;
-	case 15:  LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1;   break;
-	case 16:  LVDSData = SiS_Pr->SiS_LVDS1152x768Data_1;   break;
-	case 17:  LVDSData = SiS_Pr->SiS_LVDS1024x600Data_2;   break;
-	case 18:  LVDSData = SiS_Pr->SiS_LVDS1152x768Data_2;   break;
-	case 19:  LVDSData = SiS_Pr->SiS_LVDS1280x768Data_1;   break;
-	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;  /* Super Overscan */
-	default:  LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1;   break;
-     }
-   }
+	       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);
+			if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
+			   SiS_GenericDelay(SiS_Pr, 0x4500);
+			}
+	                SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 2);
+		     } else {
+		        SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
+			SiS_PanelDelay(SiS_Pr, HwInfo, 0);
+		     }
+	          }
+	       }
 
-   SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT;
-   SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT;
-   SiS_Pr->SiS_HT    = (LVDSData+ResIndex)->LCDHT;
-   SiS_Pr->SiS_VT    = (LVDSData+ResIndex)->LCDVT;
+               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_Pr->SiS_IF_DEF_LVDS == 0) {
+	    } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
 
-     if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
-        SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
-        SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
-     }
+	       if(!(SiS_IsNotM650orLater(SiS_Pr,HwInfo))) {
+	          SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x10);
+	       }
 
-  } else {
+  	    } else if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
 
-     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		 
-              }
-           }
-        }
-     }
-  }
-}
+	       if(!(SiS_IsNotM650orLater(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);
+	       }
+	       
+	    }
 
-void
-SiS_GetCRT2Data301(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                   USHORT RefreshRateTableIndex,
-		   PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-  USHORT tempax,tempbx,modeflag;
-  USHORT resinfo;
-  USHORT CRT2Index,ResIndex;
-  const SiS_LCDDataStruct *LCDPtr = NULL;
-  const SiS_TVDataStruct  *TVPtr  = NULL;
-
-  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;
-     }
-  }
-  
-  SiS_Pr->SiS_NewFlickerMode = 0;
-  SiS_Pr->SiS_RVBHRS = 50;
-  SiS_Pr->SiS_RY1COE = 0;
-  SiS_Pr->SiS_RY2COE = 0;
-  SiS_Pr->SiS_RY3COE = 0;
-  SiS_Pr->SiS_RY4COE = 0;
-
-  SiS_GetCRT2ResInfo(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
-
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC){
-
-     if(SiS_Pr->UseCustomMode) {
-
-        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_GetRAMDAC2DATA(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
-                           HwDeviceExtension);
-     }
-
-  } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-
-    SiS_GetCRT2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
-                   &CRT2Index,&ResIndex,HwDeviceExtension);
-
-    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;  /* Just to avoid a crash */
-    }
-
-    SiS_Pr->SiS_RVBHCMAX  = (TVPtr+ResIndex)->RVBHCMAX;
-    SiS_Pr->SiS_RVBHCFACT = (TVPtr+ResIndex)->RVBHCFACT;
-    SiS_Pr->SiS_VGAHT     = (TVPtr+ResIndex)->VGAHT;
-    SiS_Pr->SiS_VGAVT     = (TVPtr+ResIndex)->VGAVT;
-    SiS_Pr->SiS_HDE       = (TVPtr+ResIndex)->TVHDE;
-    SiS_Pr->SiS_VDE       = (TVPtr+ResIndex)->TVVDE;
-    SiS_Pr->SiS_RVBHRS    = (TVPtr+ResIndex)->RVBHRS;
-    SiS_Pr->SiS_NewFlickerMode = (TVPtr+ResIndex)->FlickerMode;
-    if(modeflag & HalfDCLK) {
-	SiS_Pr->SiS_RVBHRS     = (TVPtr+ResIndex)->HALFRVBHRS;
-    }
-
-    if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {  
-    
-       if(SiS_Pr->SiS_HiVision != 3) {
-      	  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:
-       case 1:
-       case 0:
-          SiS_Pr->SiS_HT = 0x6b4;
-          SiS_Pr->SiS_VT = 0x20d;
-	  /* Don't care about TVSimuMode */
-          break;
-       default:
-          if(SiS_Pr->SiS_VGAVDE == 350) SiS_Pr->SiS_SetFlag |= TVSimuMode;
-
-          SiS_Pr->SiS_HT = ExtHiTVHT;
-          SiS_Pr->SiS_VT = ExtHiTVVT;
-          if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-             if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
-                SiS_Pr->SiS_HT = StHiTVHT;
-                SiS_Pr->SiS_VT = StHiTVVT;
-                if(!(modeflag & Charx8Dot)){
-                   SiS_Pr->SiS_HT = StHiTextTVHT;
-                   SiS_Pr->SiS_VT = StHiTextTVVT;
-                }
-             }
-          }
-       }
-
-    } 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 == 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;
-       }
-
-    }
-
-  } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-
-     if(SiS_Pr->UseCustomMode) {
-
-        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);
-
-        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; /* Just to avoid a crash */
-        }
-
-        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
-
-	if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
-           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;
-           }
-	} 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)
-{
-  USHORT resindex;
-
-  if(ModeNo <= 0x13)
-     resindex=SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
-  else
-     resindex=SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-
-  return(resindex);
-}
-
-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->UseCustomMode) {
-     SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = SiS_Pr->CHDisplay;
-     SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = SiS_Pr->CVDisplay;
-     return;
-  }
-
-  resindex = SiS_GetResInfo(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex);
-
-  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;
-  }
-
-  if((!SiS_Pr->SiS_IF_DEF_DSTN) && (!SiS_Pr->SiS_IF_DEF_FSTN)) {
-
-     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(ModeNo > 0x13) {
-  	if(modeflag & HalfDCLK)       xres *= 2;
-  	if(modeflag & DoubleScanMode) yres *= 2;
-     }
+	    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);
+	       }
+	    } else {
+	       SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20);
+	    }
 
-  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(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 & (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 {
-    	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;
-	   }
-	   if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) {
-	      yres = 480;
-	   }
-	}
-  }
-  SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
-  SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
-}
+	    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
 
-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_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);
+	       }
+	    }
 
-  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;
-  }
+	    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);
 
-  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+	    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_VBInfo & SetCRT2ToLCD) {                            /* LCD */
+	    if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
 
-	        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 += 5;
-                        /* GetRevisionID();  */
-			/* BIOS only adds 5 once */
-        		tempbx += 5;
-       		   }
-	        }
+	       if((SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) &&
+	          (SiS_Pr->SiS_CustomT != CUT_CLEVO1400)) {
+	          SiS_PanelDelay(SiS_Pr, HwInfo, 2);
+	       }
+#ifdef COMPAQ_HACK
+	       if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
+	          SiS_PanelDelay(SiS_Pr, HwInfo, 2);
+	       }
+#endif
 
-#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;
-		}
+	       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10);
+
+	       if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
+#ifdef SET_EMI
+	          if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
+	             SiS_SetReg(SiS_Pr->SiS_Part4Port,0x30,0x00);
+		  }
 #endif
+	          SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
+#ifdef SET_EMI
+	          if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
+
+		     cr36 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
+
+		     /*                                              (P4_30|0x40)  */
+		     /* Compal 1400x1050: 0x05, 0x60, 0x00                YES  (1.10.7w;  CR36=69)      */
+		     /* Compal 1400x1050: 0x0d, 0x70, 0x40                YES  (1.10.7x;  CR36=69)      */
+		     /* Acer   1280x1024: 0x12, 0xd0, 0x6b                NO   (1.10.9k;  CR36=73)      */
+		     /* Compaq 1280x1024: 0x0d, 0x70, 0x6b                YES  (1.12.04b; CR36=03)      */
+		     /* Clevo   1024x768: 0x05, 0x60, 0x33                NO   (1.10.8e;  CR36=12, DL!) */
+		     /* Clevo   1024x768: 0x0d, 0x70, 0x40 (if type == 3) YES  (1.10.8y;  CR36=?2)      */
+		     /* Clevo   1024x768: 0x05, 0x60, 0x33 (if type != 3) YES  (1.10.8y;  CR36=?2)      */
+		     /* Asus    1024x768: ?                                ?   (1.10.8o;  CR36=?2)      */
+		     /* Asus    1024x768: 0x08, 0x10, 0x3c (problematic)  YES  (1.10.8q;  CR36=22)      */
+
+		     if(SiS_Pr->HaveEMI) {
+		        r30 = SiS_Pr->EMI_30;
+			r31 = SiS_Pr->EMI_31;
+			r32 = SiS_Pr->EMI_32;
+			r33 = SiS_Pr->EMI_33;
+		     } else {
+		        r30 = 0;
+		     }
 
-     	} 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;
-       		}
-		
-     	}
+		     /* EMI_30 is read at driver start; however, the BIOS sets this
+		      * (if it is used) only if the LCD is in use. In case we caught
+		      * the machine while on TV output, this bit is not set and we
+		      * don't know if it should be set - hence our detection is wrong.
+		      * Work-around this here:
+		      */
+
+		     if((!SiS_Pr->HaveEMI) || (!SiS_Pr->HaveEMILCD)) {
+		        if((cr36 & 0x0f) == 0x02) {			/* 1024x768 */
+		           r30 |= 0x40;
+			   if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
+			      r30 &= ~0x40;
+			   }
+		        } else if((cr36 & 0x0f) == 0x03) {		/* 1280x1024 */
+		           r30 |= 0x40;
+			   if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
+			      r30 &= ~0x40;
+			   }
+		        } else if((cr36 & 0x0f) == 0x09) {		/* 1400x1050 */
+		           r30 |= 0x40;
+		        } else if((cr36 & 0x0f) == 0x0b) {		/* 1600x1200 - unknown */
+		           r30 |= 0x40;
+		        }
+                     }
 
-        tempal &= 0x3F;
+		     if(!SiS_Pr->HaveEMI) {
+		        if((cr36 & 0x0f) == 0x02) {
+			   if((cr36 & 0xf0) == 0x30) {
+			      r31 = 0x0d; r32 = 0x70; r33 = 0x40;
+			   } else {
+			      r31 = 0x05; r32 = 0x60; r33 = 0x33;
+			   }
+		        } else if((cr36 & 0x0f) == 0x03) {
+			   if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
+			      r31 = 0x0d; r32 = 0x70; r33 = 0x6b;
+			   } else {
+			      r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
+			   }
+			} else if((cr36 & 0x0f) == 0x09) {
+			   if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
+			      r31 = 0x0d; r32 = 0x70; r33 = 0x40;  /* BIOS values */
+			   } else {
+			      r31 = 0x05; r32 = 0x60; r33 = 0x00;
+			   }
+			} else {
+			   r31 = 0x05; r32 = 0x60; r33 = 0x00;
+			}
+		     }
 
-      	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;
-	      }
-	   }
-        }
+		     /* BIOS values don't work so well sometimes */
+		     if(!SiS_Pr->OverruleEMI) {
+#ifdef COMPAL_HACK
+		        if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
+		           if((cr36 & 0x0f) == 0x09) {
+			      r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x00;
+			   }
+ 		        }
+#endif
+#ifdef COMPAQ_HACK
+		        if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
+		           if((cr36 & 0x0f) == 0x03) {
+			      r30 = 0x20; r31 = 0x12; r32 = 0xd0; r33 = 0x6b;     /* rev 1 */
+			   }
+			}
+#endif
+#ifdef ASUS_HACK
+		        if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
+		           if((cr36 & 0x0f) == 0x02) {
+			      /* r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x33;  */   /* rev 2 */
+			      /* r30 = 0x20; r31 = 0x05; r32 = 0x60; r33 = 0x33;  */   /* rev 3 */
+			      /* r30 = 0x60; r31 = 0x0d; r32 = 0x70; r33 = 0x40;  */   /* rev 4 */
+			      /* r30 = 0x20; r31 = 0x0d; r32 = 0x70; r33 = 0x40;  */   /* rev 5 */
+			   }
+			}
+#endif
+ 		     }
+		     if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) {
+		        SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20);
+		     }
+		     SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,r31);
+		     SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,r32);
+		     SiS_SetReg(SiS_Pr->SiS_Part4Port,0x33,r33);
+		     if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) {
+		        SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
+		     } else {
+		        SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x00);
+		     }
+		     if( (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
+	                 (SiS_CRT2IsLCD(SiS_Pr, HwInfo)) ) {
+	                if(r30 & 0x40) {
+		           SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 5);
+			   if(delaylong) {
+			      SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 5);
+			      delaylong = FALSE;
+			   }
+			   SiS_WaitVBRetrace(SiS_Pr,HwInfo);
+			   if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
+			      SiS_GenericDelay(SiS_Pr, 0x500);
+			   }
+	                   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40);
+	                }
+		     }
+		  }
+#endif
+	       }
 
-     	*CRT2Index = tempbx;
-     	*ResIndex = tempal;
+	       if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
 
-  } else {   /* LVDS, 301B-DH (if running on LCD) */
+	          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);
+		     if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
+		        SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
+	  	     }
+		  }
 
-    	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(SiS_Pr->SiS_CustomT == CUT_CLEVO1400) {
 
-    	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;
-		   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_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);
+		     }
+		  }
 
-		if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
-		   tempbx = 7;
-        	}
-
-		if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
-		   tempbx = 84;
-		   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx++;
-		}
+	       } 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);
+			if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
+			   SiS_GenericDelay(SiS_Pr, 0x500);
+			}
+		        SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
+	             }
+	          }
 
-#if 0
-	if(SiS_Pr->SiS_IF_DEF_FSTN){
-       	 	if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel320x480){
-         		tempbx = 14;
-         		tempal = 6;
-        	}
-    	}
-#endif	
+	          SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
+	          SiS_DisplayOn(SiS_Pr);
+	          SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xff);
 
-	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(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
+	             SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
+	          }
 
-	}
+	       }
 
-	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;
-  }
-}
+	 } else {			/* 315, 330 */
 
-#ifdef SIS315H
-void
-SiS_GetCRT2PtrA(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-		USHORT RefreshRateTableIndex,USHORT *CRT2Index,
-		USHORT *ResIndex)
-{
-  USHORT tempbx,tempal;
+	    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);
 
-  tempbx = SiS_Pr->SiS_LCDResInfo;
+	       SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                   /* enable CRT2 */
 
-  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;
+	       temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
+               if(!(temp & 0x80))
+                  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
+            }
 
-  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx += 5;
+	    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
 
-  if(ModeNo <= 0x13)
-      	tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-  else
-      	tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+	    if(SiS_Is301B(SiS_Pr)) {
 
-  *CRT2Index = tempbx;
-  *ResIndex = tempal & 0x1F;
-}
-#endif
+	       temp=SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
+               if(!(temp & 0x80))
+                  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
 
-void
-SiS_GetCRT2Part2Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-		    USHORT RefreshRateTableIndex,USHORT *CRT2Index,
-		    USHORT *ResIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension,
-		    USHORT BaseAddr)
-{
-  USHORT tempbx,tempal;
+	       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);
 
-  if(ModeNo <= 0x13)
-      	tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-  else
-      	tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+	       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
 
-  tempbx = SiS_Pr->SiS_LCDResInfo;
+	    } else {
 
-  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)      tempbx += 16;
-  else if(SiS_Pr->SiS_SetFlag & LCDVESATiming) tempbx += 32;
+	       SiS_VBLongWait(SiS_Pr);
+               SiS_DisplayOn(SiS_Pr);
+	       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7F);
+               SiS_VBLongWait(SiS_Pr);
 
-#ifdef SIS315H
-  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;
-     }
-  } else if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
-     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
-        if(SiS_IsDualLink(SiS_Pr, HwDeviceExtension, BaseAddr)) {
-           tempbx = 103;
-           if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)      tempbx = 104;
-  	   else if(SiS_Pr->SiS_SetFlag & LCDVESATiming) tempbx = 105;
-	}
-     }
-  }
-#endif
+	    }
 
-  *CRT2Index = tempbx;
-  *ResIndex = tempal & 0x3F;
-}
+	 }   /* 315, 330 */
 
-USHORT
-SiS_GetRatePtrCRT2(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-                   PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-  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;
+#endif /* SIS315H */
 
-  /* Do NOT check for UseCustomMode here, will skrew up FIFO */
-  if(ModeNo == 0xfe) return 0;
+      }
 
-  if(ModeNo <= 0x13)
-    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-  else
-    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+    } else {	/* ============  For 301 ================ */
 
-  if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
-    	if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-      		if(modeflag & HalfDCLK) return(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);
+	  }
+       }
 
-  if(ModeNo < 0x14) return(0xFFFF);
+       temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;          /* lock mode */
+       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);
 
- /* 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
-  */
-
-  index = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x33);
-  index >>= SiS_Pr->SiS_SelectCRT2Rate;
-  index &= 0x0F;
-  backupindex = index;
+       SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                  /* enable CRT2 */
 
-  if(index > 0) index--;
+       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 */
+	  }
+       }
 
-  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_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20);     /* enable VB processor */
 
-     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;
-      	}
-     }
-  }
+       SiS_VBLongWait(SiS_Pr);
+       SiS_DisplayOn(SiS_Pr);
+       if(HwInfo->jChipType >= SIS_315H) {
+          SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
+       }
+       SiS_VBLongWait(SiS_Pr);
 
-  RefreshRateTableIndex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
-  ModeNo = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].ModeID;
+       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);
+	  }
+       }
 
-  /* 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++;
-        }
-     }
-  }
+    }
 
-  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);
+  } else {   /* =================== For LVDS ================== */
 
-  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++;
-      		}
-    	}
-  }
+    if(HwInfo->jChipType < SIS_315H) {
 
-  i--;
+#ifdef SIS300    /* 300 series */
 
-  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))) {
-		/* 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_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,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);
+       }
 
-  return(RefreshRateTableIndex + i);
-}
+       if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
+          if(!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) {
+	     SiS_WaitVBRetrace(SiS_Pr, HwInfo);
+	     SiS_SetCH700x(SiS_Pr,0x0B0E);
+          }
+       }
 
-/* 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_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);
+             }
+	  }
+       }
 
-  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;
-  }
+#endif  /* SIS300 */
 
-  tempbx = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].ModeID;
+    } else {
 
-  tempax = 0;
+#ifdef SIS315H    /* 315 series */
 
-  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+       if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
+	  if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
+	     SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x11,0xFB);
+	     SiS_PanelDelay(SiS_Pr, HwInfo, 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 == SIS_RI_1600x1200) tempax |= SupportTV1024;
-		      }
-		   }
-		}
-    	} else 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 == 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);
-             			     }
-           			  }
-        		       }
-		            }
-		         }
-		      }
-      		   }
-		} 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_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);
-			}
-		}
-    	} 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(HwDeviceExtension->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(HwDeviceExtension->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 {  /* slavemode */
-		      if(resinfo != SIS_RI_1024x768) {
-			 if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
-			     ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != SIS_RI_512x384) ) ) {
-			    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 != 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 {   /* 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 != 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);
-		   }
-	        }
-        }
+       SiS_EnableCRT2(SiS_Pr);
+       SiS_UnLockCRT2(SiS_Pr,HwInfo);
 
-  } else {	/* for LVDS  */
+       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
 
-    	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 != 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);
-		}
-    	}
-  }
-  
-  /* 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;
-  }
-  /* 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_Pr->SiS_IF_DEF_CH70xx == 2) {
+          temp = SiS_GetCH701x(SiS_Pr,0x66);
+	  temp &= 0x20;
+	  SiS_Chrontel701xBLOff(SiS_Pr);
+       }
 
-void
-SiS_SaveCRT2Info(SiS_Private *SiS_Pr, USHORT ModeNo)
-{
-  USHORT temp1,temp2;
+       if(HwInfo->jChipType != SIS_550) {
+          SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
+       }
 
-  /* 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(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);
+	     }
+	  }
+       }
 
-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;
+       temp1 = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
+       if(!(temp1 & 0x80)) {
+          SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
+       }
 
-  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;
-	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-     }
-  }
+       if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+          if(temp) {
+	     SiS_Chrontel701xBLOn(SiS_Pr, HwInfo);
+	  }
+       }
 
-  SiS_Pr->SiS_SetFlag = 0;
+       if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
+          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);
+	  }
+       }
 
-  SiS_Pr->SiS_ModeType = modeflag & ModeInfoFlag;
+       if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
+          SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
+       }
 
-  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 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 | SwitchToCRT2 | SetSimuScanMode); 	/* 0x83 */
-	      temp |= SetCRT2ToHiVisionTV;   					/* 0x80 */
-	   }
-	   if(SiS_Pr->SiS_HiVision & 0x04) {	/* New from 650/30xLV 1.10.6s */
-	      temp &= (SetCRT2ToHiVisionTV | SwitchToCRT2 | SetSimuScanMode); 	/* 0x83 */
-	      temp |= SetCRT2ToSVIDEO;  					/* 0x08 */
-	   }
-	}
-#endif
-#if 0
-    	if(SiS_Pr->SiS_IF_DEF_FSTN) {   /* fstn must set CR30=0x21 */
-       		temp = (SetCRT2ToLCD | SetSimuScanMode);
-       		SiS_SetReg1(SiS_Pr->SiS_P3d4,0x30,temp);
-    	}
-#endif	
-    	tempbx |= temp;
-    	tempax = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) << 8;
-        tempax &= (LoadDACFlag | DriverMode | SetDispDevSwitch | SetNotSimuMode | SetPALTV);
-    	tempbx |= tempax;
-    	tempbx &= ~(SetCHTVOverScan | SetInSlaveMode | DisableCRT2Display);;
+       if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+       	  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);
+          }
+       }
 
-#ifdef SIS315H
+       if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+       	  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,HwInfo))) {
+	     if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
+		SiS_PanelDelay(SiS_Pr, HwInfo, 1);
+		SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x11,0xF7);
+	     }
+	  }
+       }
 
-	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 */
-		       }
-		    }
-		 }
-#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;
-	      }
-    	   }
+#endif  /* SIS315H */
 
-	   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;
-		}
-	   }
-	}
+    } /* 310 series */
 
-#endif  /* SIS315H */
+  }  /* LVDS */
 
-    	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(!(tempbx & temp)) {
-      		tempax = DisableCRT2Display;
-      		tempbx = 0;
-    	}
+/*********************************************/
+/*         SET PART 1 REGISTER GROUP         */
+/*********************************************/
 
-   	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;
-		}
-	}
+/********** Set CRT2 OFFSET / PITCH **********/
+static void
+SiS_SetCRT2Offset(SiS_Private *SiS_Pr,USHORT ModeNo,
+                  USHORT ModeIdIndex ,USHORT RefreshRateTableIndex,
+	          PSIS_HW_INFO HwInfo)
+{
+  USHORT offset;
+  UCHAR temp;
 
-    	if(tempax & DisableCRT2Display) {
-      		if(!(tempbx & (SwitchToCRT2 | SetSimuScanMode))) {
-        		tempbx = SetSimuScanMode | DisableCRT2Display;
-      		}
-    	}
+  if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return;
 
-    	if(!(tempbx & DriverMode)){
-      		tempbx |= SetSimuScanMode;
-    	}
+  offset = SiS_GetOffset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
+                         HwInfo);
 
-	/* 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 != SIS_RI_1600x1200)
-                              tempbx |= SetSimuScanMode;
-		     } else {
-            		      tempbx |= SetSimuScanMode;
-	             }
-        	}
-      	    } else {
-        	if(!(SiS_BridgeIsEnable(SiS_Pr,BaseAddr,HwDeviceExtension))) {
-          	     if(!(tempbx & DriverMode)) {
-            		  if(SiS_BridgeInSlave(SiS_Pr)) {
-			      tempbx |= SetSimuScanMode;
-            		  }
-                     }
-                }
-      	    }
-    	}
+  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
+     SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) offset >>= 1;
 
-    	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 != SIS_RI_1600x1200) {  /* 650/301 BIOS */
-			          tempbx |= SetInSlaveMode;
-            		          if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
-              		 	     if(tempbx & SetCRT2ToTV) {
-                		         if(!(tempbx & SetNotSimuMode))
-					     SiS_Pr->SiS_SetFlag |= TVSimuMode;
-              			     }
-                                  }
-			     }                      /* 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;
-              			}
-            		    }
-                        }
-	            }
-                }
-            } 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_CHSOverScan) {
-	      tempbx |= SetCHTVOverScan;
-	   }
-	}
-  }
+  temp = (UCHAR)(offset & 0xFF);
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,temp);
+  temp = (UCHAR)(offset >> 8);
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,temp);
+  temp = (UCHAR)(((offset >> 3) & 0xFF) + 1);
+  if(offset % 8) temp++;
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,temp);
+}
 
-  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;
-        	}
-        }
-  }
+/************* Set CRT2 Sync *************/
+static void
+SiS_SetCRT2Sync(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT RefreshRateTableIndex,
+                PSIS_HW_INFO HwInfo)
+{
+  USHORT tempah=0,tempbl,infoflag;
 
-  SiS_Pr->SiS_VBInfo = tempbx;
+  tempbl = 0xC0;
 
-  if(HwDeviceExtension->jChipType == SIS_630) {
-       SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo);
+  if(SiS_Pr->UseCustomMode) {
+     infoflag = SiS_Pr->CInfoFlag;
+  } else {
+     infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
   }
 
-#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_IF_DEF_LVDS == 1) {					/* LVDS */
 
-}
+     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;
 
-/* Setup general purpose IO for Chrontel communication */
-void
-SiS_SetChrontelGPIO(SiS_Private *SiS_Pr, USHORT myvbinfo)
-{
-   unsigned long  acpibase;
-   unsigned short temp;
+     tempah &= 0xC0;
 
-   if(!(SiS_Pr->SiS_ChSW)) return;
+     tempah |= 0x20;
+     if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
+
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+        if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
+           (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
+	   tempah |= 0xc0;
+        }
+     }
 
-#ifndef LINUX_XF86
-   SiS_SetReg4(0xcf8,0x80000874);		   /* get ACPI base */
-   acpibase = SiS_GetReg3(0xcfc);
-#else
-   acpibase = pciReadLong(0x00000800, 0x74);
-#endif
-   acpibase &= 0xFFFF;
-   temp = SiS_GetReg4((USHORT)(acpibase + 0x3c));  /* ACPI register 0x3c: GP Event 1 I/O mode select */
-   temp &= 0xFEFF;
-   SiS_SetReg5((USHORT)(acpibase + 0x3c), temp);
-   temp = SiS_GetReg4((USHORT)(acpibase + 0x3c));
-   temp = SiS_GetReg4((USHORT)(acpibase + 0x3a));  /* ACPI register 0x3a: GP Pin Level (low/high) */
-   temp &= 0xFEFF;
-   if(!(myvbinfo & SetCRT2ToTV)) {
-      temp |= 0x0100;
-   }
-   SiS_SetReg5((USHORT)(acpibase + 0x3a), temp);
-   temp = SiS_GetReg4((USHORT)(acpibase + 0x3a));
-}
+     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,0xe0);
+        }
+     } else {
+        SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
+     }
 
-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 ResIndex,DisplayType,temp=0;
-  const  SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr = NULL;
-#endif
+  } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
 
-  SiS_Pr->SiS_RVBHCMAX  = 1;
-  SiS_Pr->SiS_RVBHCFACT = 1;
+     if(HwInfo->jChipType < SIS_315H) {
 
-  if(ModeNo <= 0x13) {
+#ifdef SIS300  /* ---- 300 series --- */
 
-    	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_Pr->SiS_VBType & VB_SIS301BLV302BLV) {			/* 630 - 301B(-DH) */
 
-  } else {
+	   tempah = infoflag >> 8;
+           if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+	      if(SiS_Pr->SiS_LCDInfo & LCDSync) {
+	         tempah = SiS_Pr->SiS_LCDInfo;
+              }
+           }
+           tempah &= 0xC0;
 
-     if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) ) {
-
-#ifdef SIS315H     
-    	temp = SiS_GetLVDSCRT1Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
-			RefreshRateTableIndex,&ResIndex,&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+ResIndex)->CR[0];
-	tempax |= (LVDSCRT1Ptr+ResIndex)->CR[14] << 8;
-	tempax &= 0x03FF;
-    	tempbx = (LVDSCRT1Ptr+ResIndex)->CR[6];
-    	tempcx = (LVDSCRT1Ptr+ResIndex)->CR[13] << 8;
-    	tempcx &= 0x0100;
-    	tempcx <<= 2;
-    	tempbx |= tempcx;
-	temp1  = (LVDSCRT1Ptr+ResIndex)->CR[7];
-#endif
+           tempah |= 0x20;
+           if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
 
-    } else {
+ 	   tempah &= 0x3f;
+  	   tempah |= tempbl;
+           SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
+
+        } else {							/* 630 - 301 */
+
+           tempah = infoflag >> 8;
+           tempah &= 0xC0;
+           tempah |= 0x20;
+	   if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
+           SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
 
-    	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];
+        }
 
-    }
+#endif /* SIS300 */
 
-  }
+     } else {
 
-  if(temp1 & 0x01) tempbx |= 0x0100;
-  if(temp1 & 0x20) tempbx |= 0x0200;
-  
-  tempax += 5;
+#ifdef SIS315H  /* ------- 315 series ------ */
 
-  /* Charx8Dot is no more used (and assumed), so we set it */
-  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-      modeflag |= Charx8Dot;
-  }
+        if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {	  		/* 315 - 30xLV */
 
-  if(modeflag & Charx8Dot) tempax *= 8;
-  else                     tempax *= 9;
+	   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))) {
+	      tempah = infoflag >> 8;
+	   } else {
+              tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
+	   }
+	   tempah &= 0xC0;
 
-  /* From 650/30xLV 1.10.6s */
-  if(modeflag & HalfDCLK)  tempax <<= 1;
+           tempah |= 0x20;
+           if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
+           SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
 
-  tempbx++;
+        } else {							/* 315 - 301, 301B */
 
-  SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
-  SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = tempbx;
-}
+           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;
 
-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);
-}
+           tempah |= 0x20;
+           if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
 
-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);
-}
+	   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);
 
-void
-SiS_EnableCRT2(SiS_Private *SiS_Pr)
-{
-  SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
+        }
+#endif  /* SIS315H */
+      }
+   }
 }
 
-void
-SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
+/******** Set CRT2 FIFO on 300/630/730 *******/
+#ifdef SIS300
+static void
+SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,USHORT ModeNo,
+                    PSIS_HW_INFO HwInfo)
 {
-#ifdef SIS315H
-  USHORT tempah,pushax=0,modenum;
-#endif
-  USHORT temp=0;
-  UCHAR *ROMAddr = HwDeviceExtension->pjVirtualRomBase;
+  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
+  };
 
-  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+  SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;
 
-      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {   /* ===== For 30xB/LV ===== */
+  if(!SiS_Pr->CRT1UsesCustomMode) {
 
-        if(HwDeviceExtension->jChipType < SIS_315H) {
+     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);
 
-#ifdef SIS300	   /* 300 series */
+     if(CRT1ModeNo >= 0x13) {
+        index = SiS_Pr->SiS_RefIndex[refreshratetableindex].Ext_CRTVCLK;
+        index &= 0x3F;
+        VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;				/* Get VCLK */
 
-           if(HwDeviceExtension->jChipType == SIS_300) {  /* New for 300+301LV */
+	colorth = SiS_GetColorDepth(SiS_Pr,CRT1ModeNo,modeidindex); 	/* Get colordepth */
+        colorth >>= 1;
+        if(!colorth) colorth++;
+     }
 
-	      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 {
 
-	   } else {
+     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(!(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 */
+  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 */
 
-        } else {
+    data2 = (colorth * VCLK) / MCLK;
 
-#ifdef SIS315H	   /* 315 series */
+    temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
+    temp = ((temp & 0x00FF) >> 6) << 1;
+    if(temp == 0) temp = 1;
+    temp <<= 2;
+    temp &= 0xff;
 
-           if(IS_SIS550650740660) {		/* 550, 650, 740, 660 */
+    data2 = temp - data2;
 
-#if 0
-	      if(SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x00) != 1) return;	/* From 1.10.7w */
-#endif
+    if((28 * 16) % data2) {
+      	data2 = (28 * 16) / data2;
+      	data2++;
+    } else {
+      	data2 = (28 * 16) / data2;
+    }
 
-	      modenum = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x34);
+    if(HwInfo->jChipType == SIS_300) {
 
-              if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {			/* LV */
-	      
-	         SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
-		 
-		 if( (modenum <= 0x13) ||
-		     (!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) ||
-		     (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ) {
-	     	      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
-		      if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
-		         SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
-		      }
-	         }
+	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;
 
-		 if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
-		    SiS_DDC2Delay(SiS_Pr,0xff00);
-		    SiS_DDC2Delay(SiS_Pr,0x6000);
-		    SiS_DDC2Delay(SiS_Pr,0x8000);
+    } else if(HwInfo->jChipType == SIS_730) {
 
-	            SiS_SetReg3(SiS_Pr->SiS_P3c6,0x00);
+#ifndef LINUX_XF86
+       SiS_SetRegLong(0xcf8,0x80000050);
+       eax = SiS_GetRegLong(0xcfc);
+#else
+       eax = pciReadLong(0x00000000, 0x50);
+#endif
+       tempal = (USHORT)(eax >> 8);
+       tempal &= 0x06;
+       tempal <<= 5;
 
-                    pushax = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x06);
+#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;
 
-		    if(IS_SIS740) {
-		       SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
-		    }
+       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;
 
-	            SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+       data = LatencyFactor730[tempbx];
+       data += 15;
+       temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
+       if(!(temp & 0x80)) data += 5;
 
-		    if(!(IS_SIS740)) {
-		       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);
-		       }
-	            }
-		 }
+    } else {
 
-              } 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(HwDeviceExtension->jChipType == SIS_650) {
-	            if(!(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-	               SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,0xef);
-	            }
-		    if((!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) ||
-		       (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ) {
-	     	       SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFE,0x00);
-	            }
-		    SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 3);
-		 }
-	      }
+       index = 0;
+       temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
+       if(temp & 0x0080) index += 12;
 
-	      if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
-	         SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,0xef);
-	      }
+#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
+       temp = (USHORT)(eax >> 24);
+       if(!(temp&0x01)) index += 24;
 
-              if((SiS_Pr->SiS_VBType & VB_SIS301B302B) || (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280)) {
-	         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);
-	      }
+#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;
 
-              if((SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
-	         ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && (modenum <= 0x13))) {
+       temp = (temp & 0x0F) >> 1;
+       index += temp;
 
-	         if((SiS_Pr->SiS_VBType & VB_SIS301B302B) || (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280)) {
-		    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);
-		    }
-		 }
+       data = LatencyFactor[index];
+       data += 15;
+       temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
+       if(!(temp & 0x80)) data += 5;
+    }
 
-	      } else {
+    data += data2;				/* CRT1 Request Period */
 
-	         if((SiS_Pr->SiS_VBType & VB_SIS301B302B) || (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280)) {
-		    if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-		       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);
-		 } 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_Pr->SiS_SetFlag |= ProgrammingCRT2;
+    SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
 
-	      }
+    if(!SiS_Pr->UseCustomMode) {
 
-	      if((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && (SiS_Pr->SiS_CustomT != CUT_COMPAQ1280)) {
+       CRT2ModeNo = ModeNo;
+       SiS_SearchModeID(SiS_Pr, &CRT2ModeNo, &modeidindex);
 
-		 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,~0x10);    		/* 1.10.8r, 8m */
+       refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT2ModeNo, modeidindex, HwInfo);
 
-	         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);
+       index = SiS_GetVCLK2Ptr(SiS_Pr,CRT2ModeNo,modeidindex,
+                               refreshratetableindex,HwInfo);
+       VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;                         	/* Get VCLK  */
 
-		 if(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr)) {   /* 1.10.8r, 8m */
-	            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
-		 }								/* 1.10.8r, 8m */
+       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_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-	            SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
-	         }
+    } else {
 
-	         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);
-                       }
-                    }
-	         }
+       CRT2ModeNo = 0xfe;
+       VCLK = SiS_Pr->CSRClock;							/* Get VCLK */
 
-	         SiS_SetReg1(SiS_Pr->SiS_P3c4,0x06,pushax);
+    }
 
-  	      } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
+    colorth = SiS_GetColorDepth(SiS_Pr,CRT2ModeNo,modeidindex);   	/* Get colordepth */
+    colorth >>= 1;
+    if(!colorth) colorth++;
 
-	         if(HwDeviceExtension->jChipType == SIS_650) {
-		    if((SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
-		       (!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)))) {
-		       if((!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) ||
-		          (!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)))) {
-			  SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 2);
-	     	          SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
-			  SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 4);
-	               }
-		    }
-		 }
+    data = data * VCLK * colorth;
+    if(data % (MCLK << 4)) {
+      	data = data / (MCLK << 4);
+      	data++;
+    } else {
+      	data = data / (MCLK << 4);
+    }
 
-	      } else if((SiS_Pr->SiS_VBType & VB_SIS301B302B) || (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280)) {
+    if(data <= 6) data = 6;
+    if(data > 0x14) data = 0x14;
 
-	         if(HwDeviceExtension->jChipType == SIS_650) {
-		    if(!(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-	               tempah = 0xef;
-	               if(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-		          if(modenum > 0x13) {
-	                     tempah = 0xf7;
-			  }
-                       }
-	               SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
-		    }
-		    if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
-		       if((SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
-		          (!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)))) {
-		          if((!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) ||
-		             (!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)))) {
-			     SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 2);
-	     	             SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
-			     SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 4);
-	                  }
-		       }
-		    }
-		 }
+    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 {			/* 315, 330 - all bridge types */
+  } else {  /* If mode <= 0x13, we just restore everything */
 
-	     if(SiS_Is301B(SiS_Pr,BaseAddr)) {
-	        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_DisplayOff(SiS_Pr);
-		   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
-	        }
-	     }
-	     if( (!(SiS_Is301B(SiS_Pr,BaseAddr))) ||
-	         (!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) ) {
+    SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
+    SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
 
- 	 	if( (!(SiS_Is301B(SiS_Pr,BaseAddr))) ||
-		    (!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) ) {
+  }
+}
+#endif
 
-	           SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
-	           SiS_DisplayOff(SiS_Pr);
+/**** Set CRT2 FIFO on 315/330 series ****/
+#ifdef SIS315H
+static void
+SiS_SetCRT2FIFO_310(SiS_Private *SiS_Pr)
+{
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3B);
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3F,0x04);
+}
+#endif
 
-		}
+/*************** 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 push2,tempax,tempbx,tempcx,temp;
+  ULONG tempeax=0,tempebx,tempecx,tempvcfact;
 
-                SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
+  /* This is not supported with LCDA */
+  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return;
+  if(SiS_Pr->UseCustomMode) return;
 
-                SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
+  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 if(SiS_Pr->SiS_VBType & VB_SISVB) {
+        SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);			/* 740/301LV, 301BDH */
+     }
+  } 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 if(SiS_Pr->SiS_VBType & VB_SISVB) {
+        SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2D,0x0f);			/* 650/30xLv 1.10.6s */
+     }
+  }
 
-	        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(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;
+  }
 
-	     }
+  tempax = SiS_Pr->SiS_LCDHDES;
 
-	  }    /* 315/330 */
+  temp = (tempax & 0x0007);                        		/* BPLHDESKEW[2:0]   */
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp);                         /* Part1_1Ah  */
+  temp = (tempax >> 3) & 0x00FF;                               	/* BPLHDESKEW[10:3]  */
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp);                         /* Part1_16h  */
 
-#endif /* SIS315H */
+  tempbx = SiS_Pr->SiS_HDE;
+  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+     tempbx = SiS_Pr->PanelXRes;
+  }
 
-	}
+  tempax += tempbx;	                                    	/* HDE + HSKEW = lcdhdee  */
+  if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;
 
-      } else {     /* ============ For 301 ================ */
+  temp = tempax;
+  if(SiS_Pr->SiS_VBType & VB_SISVB) {
+     if(temp & 0x07) temp += 8;
+  }
+  temp >>= 3;                                        		/* BPLHDEE  */
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp);                        	/* Part1_17h  */
 
-        if(HwDeviceExtension->jChipType < SIS_315H) {
-            if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) {
-	      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF7,0x08);
-	      SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
-	   }
-	}
+  tempcx = (SiS_Pr->SiS_HT - tempbx) >> 2;     	            	/* (HT-HDE) / 4  */
 
-        SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);           /* disable VB */
-        SiS_DisplayOff(SiS_Pr);
+  /* 650/30xLV 1.10.6s, 740/LVDS */
+  if( ((SiS_Pr->SiS_VBType & VB_SISVB) && (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(HwDeviceExtension->jChipType >= SIS_315H) {
-            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
-	}
+  tempcx += tempax;  	                                  	/* lcdhrs  */
+  if(tempcx >= SiS_Pr->SiS_HT) tempcx -= SiS_Pr->SiS_HT;
 
-        SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);                /* disable lock mode */
+  temp = (tempcx >> 3) & 0x00FF;				/* BPLHRS */
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,temp);                 		/* Part1_14h  */
 
-	if(HwDeviceExtension->jChipType >= SIS_315H) {
-            temp = SiS_GetReg1(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);
-	} else {
-            SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);            /* disable CRT2 */
-	    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);
-	    }
+  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;
+		 }
+	      }
+	   }
 	}
+     }
+  }
+  temp &= 0x1F;
+  temp |= ((tempcx & 0x07) << 5);
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,temp);                         /* Part1_15h  */
 
-      }
+  if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
+     tempax = SiS_Pr->PanelYRes;
+  } else {
+     tempax = SiS_Pr->SiS_VGAVDE;
+  }
 
-  } else {     /* ============ For LVDS =============*/
+  tempbx = SiS_Pr->SiS_LCDVDES + tempax;
+  if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
+  push2 = tempbx;
 
-    if(HwDeviceExtension->jChipType < SIS_315H) {
+  tempcx = (SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 2;
 
-#ifdef SIS300	/* 300 series */
+  if( ((SiS_Pr->SiS_VBType & VB_SISVB) && (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;
+     }
+  }
 
-	if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
-	   SiS_SetCH700x(SiS_Pr,0x090E);
-	}
+  tempbx += tempcx;
+  if(SiS_Pr->SiS_VBType & VB_SISVB) {
+     tempbx++;                                                	/* BPLVRS  */
+  }
+  if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
+  temp = tempbx & 0x00FF;
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);                             /* Part1_18h  */
 
-	if(HwDeviceExtension->jChipType == SIS_730) {
-	   if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
-	      SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
-	   }
-	   if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) {
-	      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF7,0x08);
-	      SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
-	   }
-	} else {
-	   if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
+  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 & 0x000F;
+  if(SiS_Pr->SiS_VBType & VB_SISVB) {
+     temp |= 0xC0;
+     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp); 		/* Part1_19h  */
+  } else {
+     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp);
+  }
 
-	      if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
-  
-  	         if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) {
+  temp = ((tempbx >> 8) & 0x07) << 3;
+  if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
+  if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA)   temp |= 0x40;
+  if(SiS_Pr->SiS_VBType & VB_SISVB) {
+     /* Don't check Part1Port,0x00 -> is not being set if LCDA! */
+     /* We check SR06 instead here: */
+     if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
+        if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x10) temp |= 0x80;
+     }
+  } else {
+     if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
+        if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80;
+     }
+  }
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,0x07,temp);            /* Part1_1Ah */
 
-                    SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
+  tempbx = push2;                                      		/* BPLVDEE */
 
-		    if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {
-		        SiS_DisplayOff(SiS_Pr);
-	            }
+  tempcx = SiS_Pr->SiS_LCDVDES;                        		/* NPLVDES */
+  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 = tempcx = SiS_Pr->SiS_VGAVDE;
+     tempbx--;
+  }
 
-	            SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF7,0x08);
-	            SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
-                 }
-              }
-	   }
-	}
+  temp = ((tempbx >> 8) & 0x07) << 3;
+  temp = temp | ((tempcx >> 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  */
 
-	SiS_DisplayOff(SiS_Pr);
+  tempeax = SiS_Pr->SiS_VGAVDE << 18;
+  tempebx = SiS_Pr->SiS_VDE;
+  temp = (USHORT)(tempeax % tempebx);
+  tempeax = tempeax / tempebx;
+  if(temp) tempeax++;
+  tempvcfact = tempeax;
 
-	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
+  temp = (USHORT)(tempeax & 0x00FF);
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,temp);
 
-	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);
+  temp = (USHORT)((tempeax & 0x00FF00) >> 8);
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,temp);
 
-	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);
-	}
+  temp = (USHORT)((tempeax & 0x00030000) >> 16);
+  if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,temp);
 
-#endif  /* SIS300 */
+  if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV)) {
+     temp = (USHORT)(tempeax & 0x00FF);
+     SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3c,temp);
+     temp = (USHORT)((tempeax & 0x00FF00) >> 8);
+     SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3b,temp);
+     temp = (USHORT)(((tempeax & 0x00030000) >> 16) << 6);
+     SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0x3f,temp);
+     temp = 0;
+     if(SiS_Pr->SiS_VDE != SiS_Pr->SiS_VGAVDE) temp |= 0x08;
+     SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x30,0xf3,temp);
+  }
 
-    } else {
+  tempeax = SiS_Pr->SiS_VGAHDE << 16;
+  tempebx = SiS_Pr->SiS_HDE;
+  temp = tempeax % tempebx;
+  tempeax /= tempebx;
+  if(temp) tempeax++;
+  if(tempebx == SiS_Pr->SiS_VGAHDE) tempeax = 0xFFFF;
+  tempecx = tempeax;
+  tempeax = ((SiS_Pr->SiS_VGAHDE << 16) / tempecx) - 1;
+  tempecx = (tempecx << 16) | (tempeax & 0xFFFF);
+  temp = (USHORT)(tempecx & 0x00FF);
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1F,temp);                          /* Part1_1Fh  */
 
-#ifdef SIS315H	/* 315 series */
+  tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
+  tempbx = (USHORT)(tempeax & 0x0FFFF);
 
-	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempbx--;
 
-		if(HwDeviceExtension->jChipType == SIS_740) {
-		   temp = SiS_GetCH701x(SiS_Pr,0x61);
-		   if(temp < 1) {
-		      SiS_SetCH701x(SiS_Pr,0xac76);
-		      SiS_SetCH701x(SiS_Pr,0x0066);
-		   }
+  if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA)  tempbx = 1;
 
-		   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);
-		   }
-		}
+  temp = ((tempbx >> 8) & 0x07) << 3;
+  temp = temp | ((tempecx >> 8) & 0x07);
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x20,temp);                         /* Part1_20h */
 
-		if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-			SiS_Chrontel701xBLOff(SiS_Pr);
-			SiS_Chrontel701xOff(SiS_Pr,HwDeviceExtension);
-		} else if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-			SiS_Chrontel701xBLOff(SiS_Pr);
-			SiS_Chrontel701xOff(SiS_Pr,HwDeviceExtension);
-		}
+  temp = tempbx & 0x00FF;
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x21,temp);                         /* Part1_21h */
 
-		if(HwDeviceExtension->jChipType != SIS_740) {
-		   if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-			SiS_SetCH701x(SiS_Pr,0x0149);
-		   } else if(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwDeviceExtension, BaseAddr))  {
-			SiS_SetCH701x(SiS_Pr,0x0149);
-		   }
-		}
+  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(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
-		SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF7,0x08);
-		SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
-	}
+  if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBInfo & VB_SIS301LV302LV)) {
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x20);
+  }
+}
+#endif  /* SIS 315 */
 
-	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);
-	}
+static USHORT
+SiS_GetVGAHT2(SiS_Private *SiS_Pr)
+{
+  ULONG tempax,tempbx;
 
-	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);
-	}
+  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);
+}
 
-	if(HwDeviceExtension->jChipType == SIS_740) {
-	   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
-	}
+/******* 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;
 
-	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
+  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(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);
-	}
+  /* The following is only done if bridge is in slave mode: */
 
-	if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
-	        if(SiS_CRT2IsLCD(SiS_Pr, BaseAddr,HwDeviceExtension)) {
-		   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
-		   if(HwDeviceExtension->jChipType == SIS_550) {
-		      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xbf);
-		      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xef);
-		   }
-		}
-	} else {
-	   if(HwDeviceExtension->jChipType == SIS_740) {
-	        if(SiS_IsLCDOrLCDA(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-		   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
-		}
-	   } else {
-	        if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-		   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
-	        }
-	   }
-	}
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0xff);                  /* set MAX HT */
 
-	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_Pr->SiS_VBType & VB_SIS301BLV302BLV)  modeflag |= Charx8Dot;
 
-	SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension, BaseAddr);
+  if(modeflag & Charx8Dot) tempcx = 0x08;
+  else                     tempcx = 0x09;
 
-	if(HwDeviceExtension->jChipType == SIS_550) {
-	        SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
-		SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
-	} else 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 0  /* 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! */
-		}
-           }
-       }
-#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);
-			}
-		}
-       }
+  tempax = SiS_Pr->SiS_VGAHDE;                                 	/* 0x04 Horizontal Display End */
+  if(modeflag & HalfDCLK) tempax >>= 1;
+  tempax = ((tempax / tempcx) - 1) & 0xff;
+  tempbx = tempax;
 
-#endif  /* SIS315H */
+  temp = tempax;
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,temp);
 
-    }  /* 310 series */
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+     if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
+        temp += 2;
+     }
+  }
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
+     if(resinfo == SIS_RI_800x600) temp -= 2;
+  }
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x05,temp);                 /* 0x05 Horizontal Display Start */
 
-  }  /* LVDS */
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x06,0x03);                 /* 0x06 Horizontal Blank end     */
 
-}
+  tempax = 0xFFFF;
+  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempax = SiS_GetVGAHT2(SiS_Pr);
+  if(tempax >= SiS_Pr->SiS_VGAHT) tempax = SiS_Pr->SiS_VGAHT;
+  if(modeflag & HalfDCLK)         tempax >>= 1;
+  tempax = (tempax / tempcx) - 5;
+  tempcx = tempax;
 
-void
-SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
-{
-  USHORT temp=0,tempah;
-#ifdef SIS315H
-  USHORT temp1,pushax=0;
-  BOOLEAN delaylong = FALSE;
-#endif
-  UCHAR *ROMAddr = HwDeviceExtension->pjVirtualRomBase;
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
+     temp = tempcx - 1;
+     if(!(modeflag & HalfDCLK)) {
+        temp -= 6;
+        if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
+           temp -= 2;
+           if(ModeNo > 0x13) temp -= 10;
+        }
+     }
+  } else {
+     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) &&
+	      (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1600x1200)) {
+              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_LCDResInfo != SiS_Pr->SiS_Panel1400x1050) {
+                    if(SiS_Pr->SiS_VGAHDE >= 1280) {
+                       if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) temp += 28;
+		    }
+                 }
+              }
+           }
+        }
+     }
+  }
 
-  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+  p1_7 = temp;
+  p1_8 = 0x00;
 
-    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {   /* ====== For 301B et al  ====== */
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+     if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
+        if(ModeNo <= 0x01) {
+	   p1_7 = 0x2a;
+	   if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) p1_8 = 0x61;
+	   else 	      			p1_8 = 0x41;
+	} else if(SiS_Pr->SiS_ModeType == ModeText) {
+	   if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) p1_7 = 0x54;
+	   else 	    			p1_7 = 0x55;
+	   p1_8 = 0x00;
+	} else if(ModeNo <= 0x13) {
+	   if(modeflag & HalfDCLK) {
+	      if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
+		 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_TVMode & TVSetPAL)) {
+	      p1_7 = 0x30,
+	      p1_8 = 0x03;
+	   } else {
+	      p1_7 = 0x2f;
+	      p1_8 = 0x03;
+	   }
+        }
+     }
+  }
 
-      if(HwDeviceExtension->jChipType < SIS_315H) {
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
+     if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p)) {
+        p1_7 = 0x63;
+	if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) p1_7 = 0x55;
+     }
+     if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
+        if(!(modeflag & HalfDCLK)) {
+	   p1_7 = 0xb2;
+	   if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
+	      p1_7 = 0xab;
+	   }
+	}
+     }
+  }
 
-#ifdef SIS300     /* 300 series */
+  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   */
 
-         if(HwDeviceExtension->jChipType == SIS_300) {
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x03);                	/* 0x18 SR08 (FIFO Threshold?)   */
 
-	    if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
-	       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);
-	          }
-	       }
-	    }
-	    temp = SiS_GetReg1(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;
-            }
-            SiS_SetReg1(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)) {
-               SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
-	       SiS_DisplayOn(SiS_Pr);
-	    } else {
-	       SiS_VBLongWait(SiS_Pr);
-	       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_Pr->SiS_VBType & VB_SIS301LV302LV) { 
-		         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xfe,0x01);
-	 	     }
-		  }
-               }
-	    }
+  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x19,0xF0);
 
-	 } else {
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,0xFF);                	/* 0x09 Set Max VT    */
 
-	    if((SiS_Pr->SiS_VBType & VB_NoLCD) &&
-	       (SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) {
-	       /* 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);
-	       }
-	       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_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);
-                       }
-		       SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
-                       SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF7,0x00);
-                   }
-	       }
-            } else {
-	       temp = SiS_GetReg1(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;
-               }
-               SiS_SetReg1(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)) {
-                  SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
-	          SiS_DisplayOn(SiS_Pr);
-	       } else {
-	          SiS_VBLongWait(SiS_Pr);
-	          SiS_DisplayOn(SiS_Pr);
-	          SiS_VBLongWait(SiS_Pr);
-	       }
-	    }
+  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 */
 
-         }
-#endif /* SIS300 */
+  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);
 
-      } else {
+  temp = 0;
+  if(modeflag & DoubleScanMode) temp |= 0x80;
+  if(HwInfo->jChipType >= SIS_661) {
+     if(tempbx & 0x0200)        temp |= 0x20;
+     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x0B,0x5F,temp);
+     if(tempbx & 0x0100)  tempcx |= 0x000a;
+     if(tempbx & 0x0400)  tempcx |= 0x1200;
+  } else {
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,temp);
+     if(tempbx & 0x0100)  tempcx |= 0x0002;
+     if(tempbx & 0x0400)  tempcx |= 0x0600;
+  }
 
-#ifdef SIS315H    /* 315 series */
+  if(tempbx & 0x0200)  tempcx |= 0x0040;
 
-	 if(IS_SIS550650740660) {		/* 550, 650, 740, 660 */
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,0x00);                	/* 0x11 Vertical Blank End */
 
-#if 0
-	    if(SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x00) != 1) return;	/* From 1.10.7w */
-#endif
+  tempax = (SiS_Pr->SiS_VGAVT - tempbx) >> 2;
 
-	    if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+  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_CustomT != CUT_COMPAQ1280) {
-	          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_VBInfo & SetCRT2ToHiVision) {
+     tempbx -= 10;
+  } else {
+     if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
+        if(SiS_Pr->SiS_TVMode & TVSetPAL) {
+           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_TVMode & TVSetPAL) {
+     if(tempbx <= 513)  {
+     	if(tempax >= 513) tempbx = 513;
+     }
+  }
+  temp = tempbx & 0x00FF;
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp);			/* 0x0C Vertical Retrace Start */
 
-	       if(!(IS_SIS740)) {
-                  if(!(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-	             tempah = 0x10;
-		     if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
-		        if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x13) & 0x04) {
-			   if((SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) == 0x0c) {
-			      tempah = 0x08;
-			   } else {
-			      tempah = 0x18;
-			   }
-			}
-			SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x4c,tempah);
-		     } else {
-	                if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-	                   tempah = 0x08;
-                        }
-			SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,tempah);
-		     }
-	          }
-	       }
+  tempbx--;
+  temp = tempbx & 0x00FF;
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,temp);
 
-	       if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
-	          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(tempbx & 0x0100) tempcx |= 0x0008;
 
-	       if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
-	           (SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) ) {
-                  if(!(SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
-		     if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
-		        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(tempbx & 0x0200) {
+     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x0B,0x20);
+  }
+  tempbx++;
 
-               if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
-	          if(!(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {
-                     SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 10);
-		     delaylong = TRUE;
-		  }
-	       }
+  if(tempbx & 0x0100) tempcx |= 0x0004;
+  if(tempbx & 0x0200) tempcx |= 0x0080;
+  if(tempbx & 0x0400) {
+     if(HwInfo->jChipType >= SIS_661)        tempcx |= 0x0800;
+     else if(SiS_Pr->SiS_VBType & VB_SIS301) tempcx |= 0x0800;
+     else                                    tempcx |= 0x0C00;
+  }
 
-	    } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
+  tempbx = push1;
+  temp = tempbx & 0x000F;
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,temp);        		/* 0x0D vertical Retrace End */
 
-	       if(HwDeviceExtension->jChipType == SIS_650) {
-	          if(!(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-	             SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x10);
-	          }
-		  if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
-		      (SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) ) {
-		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
-		     SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 0);
-		  }
-	       }
+  if(tempbx & 0x0010) tempcx |= 0x2000;
 
-  	    } else if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
+  temp = tempcx & 0x00FF;
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp);              	/* 0x0A CR07 */
 
-	       if(HwDeviceExtension->jChipType == SIS_650) {
-		  if(!(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-	             tempah = 0x10;
-		     if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x13) & 0x04) {
-		        tempah = 0x18;
-		        if((SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) == 0x0c) {
-			   tempah = 0x08;
-			}
-		     }
-	             SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,tempah);
-		  }
-	       }
-	       
-	    }
+  temp = (tempcx & 0xFF00) >> 8;
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp);              	/* 0x17 SR0A */
 
-	    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)) {
-		     if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
-		        if(!(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x13) & 0x04)) temp |= 0x20;
-		     } else temp |= 0x20;
-		  }
-               }
-               SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
+  tempax = modeflag;
+  temp = (tempax & 0xFF00) >> 8;
+  temp = (temp >> 1) & 0x09;
+  if(!(SiS_Pr->SiS_VBType & VB_SIS301)) temp |= 0x01;		/* Always 8 dotclock */
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp);              	/* 0x16 SR01 */
 
-	       SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                   /* enable CRT2 */
-	       
-	       if((SiS_Pr->SiS_VBType & VB_SIS301B302B) || (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280)) {
-	          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);
-		  }
-	       } else {
-	          SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
-	       }
-	    }
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,0x00);              	/* 0x0F CR14 */
 
-	    if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-	       SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20);
-	    }
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,0x00);              	/* 0x12 CR17 */
 
-	    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
+  temp = 0x00;
+  if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
+     if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
+	temp = 0x80;
+     }
+  }
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp);                	/* 0x1A SR0E */
+}
 
-	    if((SiS_Pr->SiS_VBType & VB_SIS301B302B) || (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);
-	       }
-	    }
+/*********** 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;
 
-	    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);
+  /* This is not supported on LVDS */
+  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return;
+  if(SiS_Pr->UseCustomMode) return;
 
-	    if((SiS_Pr->SiS_VBType & VB_SIS301B302B) ||
-	       ((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
-	        (!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))))) {
-               SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
-	    }
+  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;
+  }
 
-	    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);
+  /* Set up Panel Link */
 
-	       if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
+  /* 1. Horizontal setup */
 
-		  SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x31,0x08);
-	          SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x32,0x10);
-	          SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x33,0x4d);
-		  if((SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0x0f) != 0x02) {
-		     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x31,0x0d);
-	             SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x32,0x70);
-	             SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x33,0x6b);
-		  }
-		  SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
+  tempax = SiS_Pr->SiS_LCDHDES;
 
-	       } else {
+  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;
+     }
+  }
 
-	          SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x31,0x12);
-	          SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x32,0xd0);
-	          SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x33,0x6b);
-	          if((SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0x0f) == 0x02) {   /* @@@@ really == ? */
-	             SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x31,0x0d);
-	             SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x32,0x70);
-	             SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x33,0x40);
-		     if(((SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0xf0) != 0x03)) {
-		        SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x31,0x05);
-	                SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x32,0x60);
-	                SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x33,0x33);  /* 00 */
-		     }
-	          }
-	          SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
-	          if((SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0x0f) != 0x03) {
-	             SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40);
-	          }
-	       }
+  tempcx = SiS_Pr->SiS_HT;    				  /* Horiz. Total */
 
-	       if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
-	          SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
-	       }
+  tempbx = SiS_Pr->SiS_HDE;                               /* Horiz. Display End */
 
-	       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10);  /* 1.10.8r */
+  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_CustomT == CUT_COMPAQ1280) {
+  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 */
 
-	          if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
-	              ((SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) ) {
-		     SiS_DisplayOn(SiS_Pr);
-		     SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1);
-		     SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
-		     SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
-	             SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40);
-		     if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-		        SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xfe,0x01);
-	  	     }
-		  }
+  push1 = tempax;
 
-	       } else {
+  tempax += tempbx;
 
-	          SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
+  if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;
 
-	          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);
-	             }
-	          }
+  push2 = tempax;
 
-	          SiS_SetReg1(SiS_Pr->SiS_P3c4,0x06,pushax);
-	          SiS_DisplayOn(SiS_Pr);
-	          SiS_SetReg3(SiS_Pr->SiS_P3c6,0xff);
+  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_VBType & VB_SISVB) {
+		         tempcx = 0x0017;  /* A901; sometimes 0x0018; */
+		      } else {
+		         tempcx = 0x0017;
+#ifdef TWNEWPANEL
+			 tempcx = 0x0018;
+#endif
+		      }
+		   } 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;
+	   }
+        }
+     }
+  }
 
-	          if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-	             SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
-	          }
+  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_VBType & VB_NoLCD) {
+  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;
+			  }
+		       }
+	            }
+	         }
+	      }
+           }
+        }
+     }
+  }
 
-	       if(HwDeviceExtension->jChipType == SIS_650) {
-	          if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-		     if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
-		         (SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) ) {
-			SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1);
-		        SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
-		     }
-		  }
-	       }
+  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  */
 
-	 } else {			/* 315, 330 */
+  temp = (tempcx & 0x0007);                      /* BPLHDESKEW  */
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp);   	 /* Part1_1Ah; Panel Link Vertical Retrace Start (2:0) */
 
-	    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);
+  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  */
 
-	       SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                   /* enable CRT2 */
+  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  */
 
-	       temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2E);
-               if(!(temp & 0x80))
-                  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
-            }
+  /* 2. Vertical setup */
 
-	    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
+  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;
 
-	    if(SiS_Is301B(SiS_Pr,BaseAddr)) {
+  } else {
 
-	       temp=SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2E);
-               if(!(temp & 0x80))
-                  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
+     tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE;           /* VGAVT-VGAVDE  */
 
-	       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);
+  }
 
-	       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
+  tempbx = SiS_Pr->SiS_LCDVDES;	   		 	 	/* VGAVDES  */
+  push1 = tempbx;
 
-	    } else {
+  tempax = SiS_Pr->SiS_VGAVDE;
 
-	       SiS_VBLongWait(SiS_Pr);
-               SiS_DisplayOn(SiS_Pr);
-	       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7F);
-               SiS_VBLongWait(SiS_Pr);
+  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;
 
-	 }   /* 315, 330 */
+  push2 = tempbx;
 
-#endif /* SIS315H */
+  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_VBType & VB_SISVB) {
+		         tempcx = 0x0002;   /* A901; sometimes 0x0003; */
+		      } else {
+			 tempcx = 0x0002;
+#ifdef TWNEWPANEL
+			 tempcx = 0x0003;
+#endif
+		      }
+		   } 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;
+	}
+     }
+  }
 
-    } else {	/* ============  For 301 ================ */
+  tempbx += tempcx;			 	/* BPLVRS  */
 
-       if(HwDeviceExtension->jChipType < SIS_315H) {
-            if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
-                SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x11,0xFB);
-	        SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 0);
-	    }
-       }
+  if((HwInfo->jChipType < SIS_315H) ||
+     (SiS_Pr->SiS_IF_DEF_FSTN) ||
+     (SiS_Pr->SiS_IF_DEF_DSTN)) {
+     tempbx++;
+  }
 
-       temp = SiS_GetReg1(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;
-       }
-       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
+  if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
 
-       SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                  /* enable CRT2 */
+  temp = tempbx & 0x00FF;
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);       	 /* Part1_18h; Panel Link Vertical Retrace Start  */
 
-       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 */
-       }
+  tempcx >>= 3;
 
-       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20);     /* enable VB processor */
+  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_VBType & VB_SISVB) {
+		      tempcx = 0x0004;   /* A901; Other BIOS sets 0x0005; */
+		   } else {
+		      tempcx = 0x0004;
+#ifdef TWNEWPANEL
+		      tempcx = 0x0005;
+#endif
+		   }
+		} else {
+		   tempcx = 0x0005;
+		}
+        }
+     }
+  }
 
-       SiS_VBLongWait(SiS_Pr);
-       SiS_DisplayOn(SiS_Pr);
-       if(HwDeviceExtension->jChipType >= SIS_315H) {
-           SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
-       }
-       SiS_VBLongWait(SiS_Pr);
+  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.  */
 
-       if(HwDeviceExtension->jChipType < SIS_315H) {
-            if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
-	        SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 1);
-                SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x11,0xF7);
-	    }
-       }
+  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) {
 
-  } else {   /* =================== For LVDS ================== */
+#ifdef SIS300      /* 300 series */
 
-    if(HwDeviceExtension->jChipType < SIS_315H) {
+        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  */
 
-#ifdef SIS300    /* 300 series */
+  	if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
+	   tempebx = 0x003F;
+	}
 
-      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);
-	 }
-      }
+  	temp = (USHORT)(tempebx & 0x00FF);
+  	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,temp);      /* Part1_1Eh; Panel Link Vertical Scaling Factor */
 
-      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);
-      }
+#endif /* SIS300 */
 
-      if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
-         if(!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) {
-	    SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
-	    SiS_SetCH700x(SiS_Pr,0x0B0E);
-         }
-      }
+  } else {
 
-      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);
-            }
-	 }
-      }
+#ifdef SIS315H  /* 315 series */
 
-#endif  /* SIS300 */
+        if(HwInfo->jChipType == SIS_740) {
+           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x03);
+        } else {
+	   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,0x23);
+	}
 
-    } else {
+	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 */
 
-#ifdef SIS315H    /* 315 series */
+#endif /* SIS315H */
 
-#if 0  /* BIOS code makes no sense */
-       if(SiS_IsVAMode()) {
-          if(SiS_IsLCDOrLCDA()) {
-	  }
-       }
-#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);
-            }
-       }
+  tempbx = push2;                                  /* BPLVDEE  */
+  tempcx = push1;
 
-       SiS_EnableCRT2(SiS_Pr);
-       SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension, BaseAddr);
+  push1 = temp;
 
-       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
+  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_IF_DEF_CH70xx == 2) {
-          temp = SiS_GetCH701x(SiS_Pr,0x66);
-	  temp &= 0x20;
-	  SiS_Chrontel701xBLOff(SiS_Pr);
-       }
+  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;
+     }
+  }
 
-       if(HwDeviceExtension->jChipType != SIS_550) {
-          SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
-       }
+  temp = ((tempbx & 0x0700) >> 8) << 3;
+  temp |= ((tempcx & 0x0700) >> 8);
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1D,temp);     	/* Part1_1Dh; Vertical Display Overflow; Control Signal */
 
-       if(HwDeviceExtension->jChipType == SIS_740) {
-          if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
-             if(SiS_IsLCDOrLCDA(SiS_Pr,HwDeviceExtension,BaseAddr)) {
-	   	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
-	     }
-	  }
-       }
+  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  */
 
-       temp1 = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2E);
-       if(!(temp1 & 0x80))
-           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
+  temp = tempcx & 0x00FF;
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1B,temp);      	/* Part1_1Bh; Panel Link Vertical Display Enable Start  */
 
-       if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
-           if(temp) {
-	       SiS_Chrontel701xBLOn(SiS_Pr, HwDeviceExtension);
-	   }
-       }
+  /* 3. Additional horizontal setup (scaling, etc) */
 
-       if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
-           if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
-	   	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
-		if(HwDeviceExtension->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,HwDeviceExtension, BaseAddr)) {
-           if(HwDeviceExtension->jChipType != SIS_740) {
-              SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
-	   }
-       }
+  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(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-           SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
-       }
+  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 */
 
-       if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+  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;
+  }
 
-       		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);
-        	}
+  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 */
 
-       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, HwDeviceExtension);
-	            		SiS_ChrontelDoSomething4(SiS_Pr,HwDeviceExtension, BaseAddr);
-           		} else if(SiS_IsLCDOrLCDA(SiS_Pr,HwDeviceExtension, BaseAddr))  {
-       				SiS_Chrontel701xBLOn(SiS_Pr, HwDeviceExtension);
-       				SiS_ChrontelDoSomething4(SiS_Pr,HwDeviceExtension, BaseAddr);
-	   		}
-       		}
-       } 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);
-			}
-		}
-       }
+  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 */
 
-#endif  /* SIS315H */
+  temp = (USHORT)(tempecx & 0x00FF);
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp);         /* Part1_22h; Panel Link Horizontal Scaling Factor Low */
 
-    } /* 310 series */
+  /* 630/301B and 630/LVDS do something for 640x480 panels here */
 
-  }  /* LVDS */
+#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);
 
-void
-SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-  USHORT  BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
+     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);
 
-  /* 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);
-    }
-  }
-}
+     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);
 
-void
-SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-  USHORT  BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
+     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);
 
-  /* 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);
-  }
+     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_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);
-          }
-      }
+     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);
+     }
   }
-}
-
-BOOLEAN
-SiS_CR36BIOSWord23b(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-  USHORT temp,temp1;
-  UCHAR *ROMAddr;
+#endif  /* SIS315H */
 
-  if((ROMAddr = (UCHAR *)HwDeviceExtension->pjVirtualRomBase) && SiS_Pr->SiS_UseROM) {
-     if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
-        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);
-     } else return(0);
-  } else {
-     return(0);
-  }
 }
 
-BOOLEAN
-SiS_CR36BIOSWord23d(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+/************** Set Part 1 ***************/
+static void
+SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+              PSIS_HW_INFO HwInfo, USHORT RefreshRateTableIndex)
 {
-  USHORT temp,temp1;
-  UCHAR *ROMAddr;
+  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((ROMAddr = (UCHAR *)HwDeviceExtension->pjVirtualRomBase) && SiS_Pr->SiS_UseROM) {
-     if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
-        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(ModeNo <= 0x13) {
+     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
   } else {
-     return(0);
+     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;
+     }
   }
-}
 
-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);
-   }
-}		     
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
 
-void
-SiS_SetPanelDelay(SiS_Private *SiS_Pr, UCHAR *ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-                  USHORT DelayTime)
-{
-  USHORT PanelID, DelayIndex, Delay;
-#ifdef SIS300
-  USHORT temp;
+#ifdef SIS315H
+     SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex, HwInfo);
+     SiS_SetGroup1_LCDA(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
 #endif
 
-  if(HwDeviceExtension->jChipType < SIS_315H) {
-
-#ifdef SIS300
-
-      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {			/* 300 series, LVDS */
-
-	  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;
-
-              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);
-
-      } else {							/* 300 series, 301(B) */
-
-	  PanelID = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36);
-	  temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x18);
-          if(!(temp & 0x10))  PanelID = 0x12;
-
-          DelayIndex = PanelID >> 4;
-
-	  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);
+  } else {
 
-      }
+     if( (HwInfo->jChipType >= SIS_315H) &&
+         (SiS_Pr->SiS_IF_DEF_LVDS == 1) &&
+	 (SiS_Pr->SiS_VBInfo & SetInSlaveMode) ) {
 
-#endif  /* SIS300 */
+        SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex, HwInfo);
 
-   } else {
+     } else {
 
-      if(HwDeviceExtension->jChipType == SIS_330) return;
+        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
+	}
 
-      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {			/* 315 series, LVDS */
+        SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex, HwInfo);
 
-          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;
+	/* 1. Horizontal setup */
 
-                 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);
-	  }
+        if(HwInfo->jChipType < SIS_315H ) {
 
-      } else {							/* 315 series, 301(B) */
+#ifdef SIS300   /* ------------- 300 series --------------*/
 
-          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);
+    		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] */
 
-#endif /* SIS315H */
+    		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_VBType & VB_SISVB) {
 
-void
-SiS_LongDelay(SiS_Private *SiS_Pr, USHORT delay)
-{
-  while(delay--) {
-    SiS_GenericDelay(SiS_Pr,0x19df);
-  }
-}
+		   if(SiS_Pr->UseCustomMode) {
+		      tempbx = SiS_Pr->CHSyncStart + 12;
+		      tempcx = SiS_Pr->CHSyncEnd + 12;
+		   }
 
-void
-SiS_ShortDelay(SiS_Private *SiS_Pr, USHORT delay)
-{
-  while(delay--) {
-      SiS_GenericDelay(SiS_Pr,0x42);
-  }
-}
+      		   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;
+      		   }
 
-void
-SiS_GenericDelay(SiS_Private *SiS_Pr, USHORT delay)
-{
-  USHORT temp,flag;
+    		   if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (resinfo == SIS_RI_1024x768)){
+        	      if(!(SiS_Pr->SiS_TVMode & TVSetPAL)){
+      			 tempbx = 1040;
+      			 tempcx = 1042;
+      		      }
+    		   }
+	        }
 
-  flag = SiS_GetReg3(0x61) & 0x10;
+    		temp = tempbx & 0x00FF;
+    		SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,temp);                   /* CRT2 Horizontal Retrace Start */
+#endif /* SIS300 */
 
-  while(delay) {
-      temp = SiS_GetReg3(0x61) & 0x10;
-      if(temp == flag) continue;
-      flag = temp;
-      delay--;
-  }
-}
+ 	} else {
 
-BOOLEAN
-SiS_Is301B(SiS_Private *SiS_Pr, USHORT BaseAddr)
-{
-  USHORT flag;
+#ifdef SIS315H  /* ------------------- 315/330 series --------------- */
 
-  flag = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x01);
-  if(flag >= 0x0B0) return(1);
-  else return(0);
-}
+	        tempcx = SiS_Pr->SiS_VGAHT;				       /* BTVGA2HT 0x08,0x09 */
+		if(modeflag & HalfDCLK) {
+		    if(SiS_Pr->SiS_VBType & VB_SISVB) {
+		       tempcx >>= 1;
+		    } else {
+		       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;
+		       }
+		    }
+		}
+		tempcx--;
 
-BOOLEAN
-SiS_CRT2IsLCD(SiS_Private *SiS_Pr, USHORT BaseAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-  USHORT flag;
+		temp = tempcx & 0xff;
+		SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp);                  /* CRT2 Horizontal Total */
 
-  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);
-}
+		temp = ((tempcx & 0xff00) >> 8) << 4;
+		SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp);         /* CRT2 Horizontal Total Overflow [7:4] */
 
-BOOLEAN
-SiS_IsDualEdge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
-{
-#ifdef SIS315H
-  USHORT flag;
+		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;
 
-  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);
-}
+		temp = tempbx & 0xff;
+		SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp);                  /* CRT2 Horizontal Display Enable End */
 
-BOOLEAN
-SiS_IsVAMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
-{
-#ifdef SIS315H
-  USHORT flag;
+		pushbx = tempbx;
+		tempcx >>= 1;
+		tempbx += tempcx;
+		tempcx += tempbx;
 
-  if(HwDeviceExtension->jChipType >= SIS_315H) {
-     flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
-     if((flag & EnableDualEdge) && (flag & SetToLCDA))   return(1);
-     else return(0);
-  } else
-#endif
-     return(0);
-}
+		if(SiS_Pr->SiS_VBType & VB_SISVB) {
 
-BOOLEAN
-SiS_IsDualLink(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
-{
-#ifdef SIS315H
-  if(HwDeviceExtension->jChipType >= SIS_315H) {
-     if((SiS_CRT2IsLCD(SiS_Pr, BaseAddr, HwDeviceExtension)) ||
-        (SiS_IsVAMode(SiS_Pr, HwDeviceExtension, BaseAddr))) {
-        if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) return(1);
-     }
-  }
-#endif
-     return(0);
- }
+		   if(HwInfo->jChipType >= SIS_661) {
+		      if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) ||
+		         (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)) {
+			 if(resinfo == SIS_RI_1280x1024) {
+		            tempcx = 0x30;
+			 } else if(resinfo == SIS_RI_1600x1200) {
+			    tempcx = 0xff;
+			 }
+		      }
+		   }
 
-BOOLEAN
-SiS_WeHaveBacklightCtrl(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
-{
-#ifdef SIS315H
-  USHORT flag;
+		   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(HwDeviceExtension->jChipType >= SIS_315H) {
-     flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x79);
-     if(flag & 0x10)  return(1);
-     else             return(0);
-  } else
-#endif
-     return(0);
- }
+             	   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 0
-BOOLEAN
-SiS_Is315E(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
-{
-#ifdef SIS315H
-  USHORT flag;
+		   if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
+      		      tempbx = 1040;
+      		      tempcx = 1042;
+      	     	   }
 
-  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
+                }
 
-BOOLEAN
-SiS_IsNotM650or651(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
-{
-#ifdef SIS315H
-  USHORT flag;
+		temp = tempbx & 0xff;
+	 	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,temp);                 /* CRT2 Horizontal Retrace Start */
+#endif  /* SIS315H */
 
-  if(HwDeviceExtension->jChipType == SIS_650) {
-     flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5f);
-     flag &= 0xF0;
-     /* Check for revision != A0 only */
-     if((flag == 0xe0) || (flag == 0xc0) ||
-        (flag == 0xb0) || (flag == 0x90)) return 0;
-     else return 1;
-  } else
-#endif
-    return 1;
-}
+     	}  /* 315/330 series */
 
-BOOLEAN
-SiS_IsYPbPr(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
-{
-#ifdef SIS315H
-  USHORT flag;
+  	/* The following is done for all bridge/chip types/series */
 
-  if(HwDeviceExtension->jChipType >= SIS_315H) {
-     flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
-     if(flag & EnableLVDSHiVision)  return(1);  /* = YPrPb = 0x08 */
-     else      	                    return(0);
-  } else
-#endif
-     return(0);
-}
+  	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 */
 
-BOOLEAN
-SiS_IsChScart(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
-{
-#ifdef SIS315H
-  USHORT flag;
+  	temp = tempcx & 0x00FF;
+  	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,temp);                        /* CRT2 Horizontal Retrace End */
 
-  if(HwDeviceExtension->jChipType >= SIS_315H) {
-     flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
-     if(flag & EnableLVDSScart)     return(1);  /* = Scart = 0x04 */
-     else      	                    return(0);
-  } else
-#endif
-     return(0);
-}
+  	/* 2. Vertical setup */
 
-BOOLEAN
-SiS_IsTVOrYPbPrOrScart(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
-{
-  USHORT flag;
+  	tempcx = SiS_Pr->SiS_VGAVT - 1;
+  	temp = tempcx & 0x00FF;
 
-#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);
-}
+	if(HwInfo->jChipType < SIS_661) {
+           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) {
+	      temp--;
+	   }
+	}
+  	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp);                        /* CRT2 Vertical Total */
 
-BOOLEAN
-SiS_IsLCDOrLCDA(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
-{
-  USHORT flag;
+  	tempbx = SiS_Pr->SiS_VGAVDE - 1;
+  	temp = tempbx & 0x00FF;
+  	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,temp);                        /* CRT2 Vertical Display Enable End */
 
-#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);
+  	temp = ((tempbx & 0xFF00) << 3) >> 8;
+  	temp |= ((tempcx & 0xFF00) >> 8);
+  	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,temp);                        /* Overflow (and HWCursor Test Mode) */
 
-}
+	if((HwInfo->jChipType >= SIS_315H) && (HwInfo->jChipType < SIS_661)) {
+           tempbx++;
+   	   tempax = tempbx;
+	   tempcx++;
+	   tempcx -= tempax;
+	   tempcx >>= 2;
+	   tempbx += tempcx;
+	   if(tempcx < 4) tempcx = 4;
+	   tempcx >>= 2;
+	   tempcx += tempbx;
+	   tempcx++;
+	} else {
+  	   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        */
+	}
 
-BOOLEAN
-SiS_BridgeIsOn(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-  USHORT flag;
+  	if(SiS_Pr->SiS_VBType & VB_SISVB) {
 
-  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);
-  }
-}
+	   if(SiS_Pr->UseCustomMode) {
+	      tempbx = SiS_Pr->CVSyncStart;
+	      tempcx = (tempcx & 0xFF00) | (SiS_Pr->CVSyncEnd & 0x00FF);
+	   }
 
-BOOLEAN
-SiS_BridgeIsEnable(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-  USHORT flag;
+    	   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 */
 
-  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 {
-      /* 315 series (650/30xLV 1.10.6s) */
-      flag &= 0x50;
-      if((flag == 0x40) || (flag == 0x10)) return 0;
-      else                                 return 1;
-    }
-  }
-  return 1;
-}
+  	temp = ((tempbx & 0xFF00) >> 8) << 4;
+  	temp |= (tempcx & 0x000F);
+  	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,temp);           /* CRT2 Vert. Retrace End; Overflow; "Enable CRTC Check" */
 
-BOOLEAN
-SiS_BridgeInSlave(SiS_Private *SiS_Pr)
-{
-  USHORT flag1;
+  	/* 3. Panel compensation delay */
 
-  flag1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31);
-  if(flag1 & (SetInSlaveMode >> 8)) return 1;
-  else return 0;
-}
+  	if(HwInfo->jChipType < SIS_315H) {
 
-void
-SiS_SetHiVision(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-#ifdef SIS315H
-  USHORT temp;
-#endif
+#ifdef SIS300  /* ---------- 300 series -------------- */
 
-  /* Note: This variable is only used on 30xLV systems.
-     CR38 has a different meaning on LVDS/CH7019 systems.
-   */
+	   if(SiS_Pr->SiS_VBType & VB_SISVB) {
+	        temp = 0x20;
 
-  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 */
-  }
-}
+		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 & SetCRT2ToHiVision) {
+      		   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 & SetCRT2ToTVNoYPbPrHiVision)
+				temp = ROMAddr[0x221];
+			else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)
+				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(SiS_Pr->PDC) {
+			temp = SiS_Pr->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(SiS_Pr->PDC) {
+		      temp = SiS_Pr->PDC & 0x3c;
+		   }
+		}
+	   }
 
-void
-SiS_GetLCDResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,
-                  USHORT ModeIdIndex, PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-  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 };
+    	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x03C,temp);         /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
 
-  SiS_Pr->SiS_LCDResInfo = 0;
-  SiS_Pr->SiS_LCDTypeInfo = 0;
-  SiS_Pr->SiS_LCDInfo = 0;
+#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 {
 
-#ifdef SIS315H
-  if(HwDeviceExtension->jChipType >= SIS_315H) {
-     if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
-        SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x39,~0x04);
-     }
-  }
-#endif
+#ifdef SIS315H   /* --------------- 315/330 series ---------------*/
+
+   	   if(HwInfo->jChipType < SIS_661) {
 
-  if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)))   return;
+	      if(SiS_Pr->SiS_VBType & VB_SISVB) {
 
-  if(!(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchToCRT2))) return;
+                 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 & SetCRT2ToHiVision) {
+		       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(SiS_Pr->PDC) {
+		          temp = SiS_Pr->PDC;
+		          tempbl = 0;
+		       }
+		    }
+		 }
 
-  temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36);
+	      } else {  /* LVDS */
 
-#if 0
-  /* 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);
-  }
-#endif
+	         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(HwDeviceExtension->jChipType < SIS_315H) {
-  	SiS_Pr->SiS_LCDTypeInfo = temp >> 4;
-  } else {
-        SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1;
-  }
-  temp &= 0x0f;
-  if(HwDeviceExtension->jChipType < SIS_315H) {
-      /* Translate 300 series LCDRes to 315 series for unified usage */
-      temp = SiS300SeriesLCDRes[temp];
-  }
-  SiS_Pr->SiS_LCDResInfo = temp;
+		 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;
+		    }
+		 }
+	      }
 
-#if 0
-  if(SiS_Pr->SiS_IF_DEF_FSTN){
-       	SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_Panel320x480;
-  }
-#endif
+	      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp);	    /* Panel Link Delay Compensation */
 
-  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;
-  }
+	   } /* < 661 */
 
-  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;
-  }
+    	   tempax = 0;
+    	   if (modeflag & DoubleScanMode) tempax |= 0x80;
+    	   if (modeflag & HalfDCLK)       tempax |= 0x40;
+    	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax);
 
-  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;
-     }
-  }
+#endif  /* SIS315H */
 
-  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 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37);
-#if 0
-  if(SiS_Pr->SiS_IF_DEF_FSTN){
-        /* Fake LVDS bridge for FSTN */
-      	temp = 0x04;
-      	SiS_SetReg1(SiS_Pr->SiS_P3d4,0x37,temp);
-  }
-#endif
-  SiS_Pr->SiS_LCDInfo = temp;
+     }  /* Slavemode */
 
-  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 */
-     }
-  }
+     if(SiS_Pr->SiS_VBType & VB_SISVB) {
 
-  if(!(SiS_Pr->UsePanelScaler))        SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
-  else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+        /* For 301BDH with LCD, we set up the Panel Link */
+        if( (SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ) {
 
-  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) {
-	   /* 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;
-	   }
-	}
-     }
-  }
+	    SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex,
+	                       HwInfo, RefreshRateTableIndex);
 
+        } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
 
-  if(HwDeviceExtension->jChipType >= SIS_315H) {
-#ifdef SIS315H
-     if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x01) {
-        SiS_Pr->SiS_LCDInfo &= 0xFFEF;
-	SiS_Pr->SiS_LCDInfo |= LCDPass11;
-     }
-#endif
-  } else {
-#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;
- 	      }
-	   }
+    	    SiS_SetGroup1_301(SiS_Pr, ModeNo, ModeIdIndex,
+	                      HwInfo, RefreshRateTableIndex);
         }
-     } else if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-	if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
-           SiS_Pr->SiS_LCDInfo &= 0xEF;
-	}
-     }
-#endif
-  }
 
-  /* Trumpion: Assume non-expanding */
-  if(SiS_Pr->SiS_IF_DEF_TRUMPION != 0) {
-     SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
-  }
+     } else {
 
-  if(!((HwDeviceExtension->jChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
+        if(HwInfo->jChipType < SIS_315H) {
 
-     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;
-		 }
+	   SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex,
+	                        HwInfo, 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, ModeNo,ModeIdIndex,
+	                              HwInfo,RefreshRateTableIndex);
               }
-           }
-        }
-	if(ModeNo == 0x12) {
-	   if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
-	      SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+	   } else {
+	      SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,
+	                         HwInfo,RefreshRateTableIndex);
 	   }
-	}
-     }
-
-     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 == 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;
-     }
-
-  }
-
-  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
-  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)
-	 */
-        if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
-	   if(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
-
-#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
 
+     }
+  } /* LCDA */
 }
 
-void
-SiS_LongWait(SiS_Private *SiS_Pr)
-{
-  USHORT i;
-
-  i = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1F);
-
-  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;
-    }
-  }
-}
+/*********************************************/
+/*         SET PART 2 REGISTER GROUP         */
+/*********************************************/
 
-void
-SiS_VBLongWait(SiS_Private *SiS_Pr)
+#ifdef SIS315H
+static UCHAR *
+SiS_GetGroup2CLVXPtr(SiS_Private *SiS_Pr, int tabletype, PSIS_HW_INFO HwInfo)
 {
-  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
-    SiS_VBWait(SiS_Pr);
-  } else {
-    SiS_LongWait(SiS_Pr);
-  }
-}
+   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
+   const UCHAR  *tableptr = NULL;
+   USHORT a, b, p = 0;
 
-void
-SiS_VBWait(SiS_Private *SiS_Pr)
-{
-  USHORT tempal,temp,i,j;
+   a = SiS_Pr->SiS_VGAHDE;
+   b = SiS_Pr->SiS_HDE;
+   if(tabletype) {
+      a = SiS_Pr->SiS_VGAVDE;
+      b = SiS_Pr->SiS_VDE;
+   }
 
-  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((ROMAddr = (UCHAR *)HwInfo->pjVirtualRomBase) && SiS_Pr->SiS_UseROM) {
 
-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
-  }
-}
+      if(a < b) {
+         p = ROMAddr[0x278] | (ROMAddr[0x279] << 8);
+      } else if(a == b) {
+         p = ROMAddr[0x27a] | (ROMAddr[0x27b] << 8);
+      } else {
+         if(SiS_Pr->SiS_TVMode & TVSetPAL) {
+	    p = ROMAddr[0x27e] | (ROMAddr[0x27f] << 8);
+	 } else {
+	    p = ROMAddr[0x27c] | (ROMAddr[0x27d] << 8);
+	 }
+	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
+	    if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) 	 p = ROMAddr[0x280] | (ROMAddr[0x281] << 8);
+	    else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) p = ROMAddr[0x282] | (ROMAddr[0x283] << 8);
+	    else 				 	 p = ROMAddr[0x284] | (ROMAddr[0x285] << 8);
+	 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
+	    p = ROMAddr[0x286] | (ROMAddr[0x287] << 8);
+	 }
+	 do {
+	    if((ROMAddr[p] | ROMAddr[p+1] << 8) == a) break;
+	    p += 0x42;
+	 } while((ROMAddr[p] | ROMAddr[p+1] << 8) != 0xffff);
+	 if((ROMAddr[p] | ROMAddr[p+1] << 8) == 0xffff) p -= 0x42;
+      }
+      p += 2;
+      return(&ROMAddr[p]);
 
-void
-SiS_WaitRetrace1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-  USHORT watchdog;
-#ifdef SIS300
-  USHORT i;
-#endif
+   } else {
 
-  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  /* 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
-  }
+      if(a < b) {
+         tableptr = SiS_Part2CLVX_1;
+      } else if(a == b) {
+         tableptr = SiS_Part2CLVX_2;
+      } else {
+         if(SiS_Pr->SiS_TVMode & TVSetPAL) {
+	    tableptr = SiS_Part2CLVX_4;
+	 } else {
+	    tableptr = SiS_Part2CLVX_3;
+	 }
+	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
+	    if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) 	 tableptr = SiS_Part2CLVX_3;
+	    else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tableptr = SiS_Part2CLVX_3;
+	    else 				         tableptr = SiS_Part2CLVX_5;
+	 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
+	    tableptr = SiS_Part2CLVX_6;
+	 }
+	 do {
+	    if((tableptr[p] | tableptr[p+1] << 8) == a) break;
+	    p += 0x42;
+	 } while((tableptr[p] | tableptr[p+1] << 8) != 0xffff);
+	 if((tableptr[p] | tableptr[p+1] << 8) == 0xffff) p -= 0x42;
+      }
+      p += 2;
+      return((UCHAR *)&tableptr[p]);
+   }
 }
 
-void
-SiS_WaitRetraceDDC(SiS_Private *SiS_Pr)
+static void
+SiS_SetGroup2_C_ELV(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+	      	    USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
 {
-  USHORT watchdog;
-
-  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);
+   UCHAR *tableptr;
+   int i, j;
+   UCHAR temp;
+
+   if(!(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV))) return;
+
+   tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 0, HwInfo);
+   for(i = 0x80, j = 0; i <= 0xbf; i++, j++) {
+      SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
+   }
+   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+      tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 1, HwInfo);
+      for(i = 0xc0, j = 0; i <= 0xff; i++, j++) {
+         SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
+      }
+   }
+   temp = 0x10;
+   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp |= 0x04;
+   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xeb,temp);
 }
 
-void
-SiS_WaitRetrace2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+static void
+SiS_GetCRT2Part2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
+		    USHORT RefreshRateTableIndex,USHORT *CRT2Index,
+		    USHORT *ResIndex,PSIS_HW_INFO HwInfo)
 {
-  USHORT watchdog;
-#ifdef SIS300
-  USHORT i;
-#endif
+  USHORT tempbx,tempal;
 
-  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(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;
+
+  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;
+     }
+  } 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;
+	}
      }
-     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_ASUSA2H_2) {
+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+        if(SiS_Pr->SiS_SetFlag & LCDVESATiming) tempbx = 106;
      }
-#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,56) 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
 
 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_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);   /* 48 */
-	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2d,0xe4);
-	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2e,0x73);
-	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,0xda);   /* de */
-	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,0x13);
-	      if((SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38)) & 0x40) {
-	         SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x14);
-	      } else {
-	         SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x15);
-	      }
-	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x1b);
-	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x43,0x72);
-           }
-        } else {
-	   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x21);
-	   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x5a);
+  if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) return;
+  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) return;
+  if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) return;
+
+  if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
+     if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
+        const UCHAR specialtv[] = {
+		0xa7,0x07,0xf2,0x6e,0x17,0x8b,0x73,0x53,
+		0x13,0x40,0x34,0xf4,0x63,0xbb,0xcc,0x7a,
+		0x58,0xe4,0x73,0xda,0x13
+	};
+	int i, j;
+	for(i = 0x1c, j = 0; i <= 0x30; i++, j++) {
+	   SiS_SetReg(SiS_Pr->SiS_Part2Port,i,specialtv[j]);
+	}
+	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,0x72);
+	if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750)) {
+	   if(SiS_Pr->SiS_TVMode & TVSetPALM) {
+	      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);
 	}
      }
+  } else {
+     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x21);
+     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x5a);
   }
 }
 
-/* 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)
+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;
+  USHORT      i, j, tempax, tempbx, tempcx, temp;
+  USHORT      push1, push2, modeflag, crt2crtc;
+  ULONG       longtemp, tempeax;
   const       UCHAR *PhasePoint;
   const       UCHAR *TimingPoint;
-#ifdef SIS315H   
-  const       SiS_Part2PortTblStruct *CRT2Part2Ptr = NULL;
+#ifdef SIS315H
   USHORT      resindex, CRT2Index;
+  const       SiS_Part2PortTblStruct *CRT2Part2Ptr = NULL;
 #endif
-  USHORT      modeflag, resinfo, crt2crtc;
-  ULONG       longtemp, tempeax;
 #ifdef SIS300
   const UCHAR atable[] = {
-                 0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,
-	         0xab,0x87,0xab,0x9e,0xe7,0x02,0x02
+       0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,
+       0xab,0x87,0xab,0x9e,0xe7,0x02,0x02
   };
 #endif  
 
 #ifdef SIS315H   
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
-     /* 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 = 0x01;
-	   if(ModeNo <= 0x13) temp = 0x03;
-	   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x0b,temp);
-	}
-     }
-     SiS_SetTVSpecial(SiS_Pr, ModeNo);
-     return;
-  }
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
 #endif
 
   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 {
      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;
-  tempax = (tempcx & 0x00FF) << 8;
-  tempbx = (tempcx & 0x00FF) | ((tempcx & 0x00FF) << 8);
-  tempbx &= 0x0410;
-  temp = (tempax & 0x0800) >> 8;
-  temp >>= 1;
-  temp |= (((tempbx & 0xFF00) >> 8) << 1);
-  temp |= ((tempbx & 0x00FF) >> 3);
-  temp ^= 0x0C;
-
-  /* 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;
+  temp = 0;
+  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO)) temp |= 0x08;
+  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO)) temp |= 0x04;
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART)     temp |= 0x02;
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)  temp |= 0x01;
+
+  /* Disable SVIDEO and CVBS signal */
+  if((SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) &&
+     (SiS_Pr->SiS_CustomT != CUT_CLEVO1400)) {
+     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 & SetCRT2ToHiVision) {
+
      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
         TimingPoint = SiS_Pr->SiS_HiTVSt2Timing;
-        if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
+        if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
            if(modeflag & Charx8Dot) TimingPoint = SiS_Pr->SiS_HiTVSt1Timing;
-           else TimingPoint = SiS_Pr->SiS_HiTVTextTiming;
+           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 & SetCRT2ToYPbPr525750) {
+
+     if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)      TimingPoint = &SiS_YPbPrTable[2][0];
+     else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) TimingPoint = &SiS_YPbPrTable[1][0];
+     else					  TimingPoint = &SiS_YPbPrTable[0][0];
+
+     PhasePoint = SiS_Pr->SiS_NTSCPhase;
 
   } else {
 
-     if(SiS_Pr->SiS_VBInfo & SetPALTV){
+     if(SiS_Pr->SiS_TVMode & TVSetPAL) {
 
         TimingPoint = SiS_Pr->SiS_PALTiming;
         PhasePoint  = SiS_Pr->SiS_PALPhase;
 
         if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
             ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
-	      (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) {
+	      (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
            PhasePoint = SiS_Pr->SiS_PALPhase2;
         }
 
@@ -7327,161 +7285,122 @@
         temp |= 0x10;
         TimingPoint = SiS_Pr->SiS_NTSCTiming;
         PhasePoint  = SiS_Pr->SiS_NTSCPhase;
+	if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
+	   PhasePoint = SiS_Pr->SiS_PALPhase;
+	}
 
         if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
 	    ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
-	      (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) {
+	      (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
            PhasePoint = SiS_Pr->SiS_NTSCPhase2;
+	   if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
+	      PhasePoint = SiS_Pr->SiS_PALPhase2;
+	   }
         }
 
      }
 
   }
-  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)) {
-     temp = 0x35;
-  }
-  if(HwDeviceExtension->jChipType >= SIS_315H) {
-     temp = 0x38;
+  if(SiS_Pr->SiS_TVMode & TVSetPALM) {
+     PhasePoint = SiS_Pr->SiS_PALMPhase;
+     if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
+	 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+	   (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
+        PhasePoint = SiS_Pr->SiS_PALMPhase2;
+     }
   }
-  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_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;
-	      }
-	   }
-        }
+
+  if(SiS_Pr->SiS_TVMode & TVSetPALN) {
+     PhasePoint = SiS_Pr->SiS_PALNPhase;
+     if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
+	 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+	   (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
+	PhasePoint = SiS_Pr->SiS_PALNPhase2;
      }
   }
 
-#ifdef SIS315H
-  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 == 0x64) || (ModeNo == 0x4a) || (ModeNo == 0x38)) {
-	         PhasePoint = SiS_Pr->SiS_SpecialPhase;
-	      }
-           }
-        }
+  if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
+     PhasePoint = SiS_Pr->SiS_SpecialPhase;
+     if(SiS_Pr->SiS_TVMode & TVSetPALM) {
+        PhasePoint = SiS_Pr->SiS_SpecialPhaseM;
+     } else if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
+        PhasePoint = SiS_Pr->SiS_SpecialPhaseJ;
      }
   }
-#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))
-           SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
-     } else {
+     if(SiS_Pr->SiS_ModeType != ModeText) {
         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);
-
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
-     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 & SetCRT2ToTV)) || (SiS_Pr->SiS_HiVision == 3) ) && (SiS_Pr->SiS_VDE <= tempax) ) ||
-      ( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (SiS_Pr->SiS_HiVision != 3) &&
-        ( (SiS_Pr->SiS_VGAHDE == 1024) || ((SiS_Pr->SiS_VGAHDE != 1024) && (SiS_Pr->SiS_VDE <= tempax)) ) ) ) {
+  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 & SetCRT2ToHiVision) 	tempax = 950;
+  else if(SiS_Pr->SiS_TVMode & TVSetPAL)      	tempax = 520;
+  else 			            		tempax = 440;
+
+  if( ( (!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) && (SiS_Pr->SiS_VDE <= tempax) ) ||
+      ( (SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) &&
+        ((SiS_Pr->SiS_VGAHDE == 1024) || (SiS_Pr->SiS_VDE <= tempax)) ) ) {
 
      tempax -= SiS_Pr->SiS_VDE;
      tempax >>= 2;
-     tempax = (tempax & 0x00FF) | ((tempax & 0x00FF) << 8);
+     tempax &= 0x00ff;
+
+     temp = tempax + (USHORT)TimingPoint[0];
+     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
 
-     temp = (tempax & 0xFF00) >> 8;
-     temp += (USHORT)TimingPoint[0];
-     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,temp);
-
-     temp = (tempax & 0xFF00) >> 8;
-     temp += (USHORT)TimingPoint[1];
-     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,temp);
-
-     if( (SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)) &&
-         (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);
+     temp = tempax + (USHORT)TimingPoint[1];
+     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
+
+     if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) && (SiS_Pr->SiS_VGAHDE >= 1024)) {
+        if(SiS_Pr->SiS_TVMode & TVSetPAL) {
+           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);
-	   } else {
-              SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x0b);
-              SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x11);
-	   }
+           SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x17);
+           SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1d);
         }
      }
 
   }
 
   tempcx = SiS_Pr->SiS_HT;
-
-  /* 650/30xLV 1.10.6s */
-  if(SiS_IsDualLink(SiS_Pr, HwDeviceExtension, BaseAddr)) {
-     tempcx >>= 1;
-  }
-
+  if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempcx >>= 1;
   tempcx--;
-  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-        tempcx--;
-  }
+  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) 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);
 
   tempcx++;
-  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-        tempcx++;
-  }
+  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) tempcx++;
   tempcx >>= 1;
 
   push1 = tempcx;
 
   tempcx += 7;
-  if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) &&
-     (SiS_Pr->SiS_HiVision == 3)) {
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
      tempcx -= 4;
   }
   temp = (tempcx & 0x00FF) << 4;
@@ -7493,15 +7412,14 @@
   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);
 
   tempbx = push2;
 
   tempbx += 8;
-  if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) &&
-     (SiS_Pr->SiS_HiVision == 3)) {
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
      tempbx -= 4;
      tempcx = tempbx;
   }
@@ -7511,14 +7429,13 @@
   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);
 
   tempcx += 8;
-  if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) &&
-     (SiS_Pr->SiS_HiVision == 3)) {
-     tempcx -= 4; 
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
+     tempcx -= 4;
   }
   temp = (tempcx & 0x00FF) << 4;
   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2A,0x0F,temp);
@@ -7532,141 +7449,114 @@
 
   tempcx -= 11;
   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
-     tempax = SiS_GetVGAHT2(SiS_Pr) - 1;
-     tempcx = tempax;
+     tempcx = SiS_GetVGAHT2(SiS_Pr) - 1;
   }
   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(HwInfo->jChipType < SIS_315H) {
      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempbx >>= 1;
   } else {
-     if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (!(SiS_Pr->SiS_HiVision & 0x03))) {
+     if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
+         (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p))) ) {
 	tempbx >>= 1;
-	if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
+	if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
 	   if(ModeNo <= 0x13) {
-	      if(crt2crtc == 1) {
-	         tempbx++;
-              }
+	      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++;
+	} else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+	   if(crt2crtc == 4) {
+              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 & SetCRT2ToHiVision) {
      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
         if((ModeNo == 0x2f) || (ModeNo == 0x5d) || (ModeNo == 0x5e)) temp++;
      }
   }
-  /* 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(HwInfo->jChipType < SIS_661) {
+     /* From 1.10.7w - doesn't make sense */
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+        if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+           if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
+	      if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {   /* SetFlag?? */
+	         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(!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV)) {
-        if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART)) {		/* New from 630/301B (II) BIOS */
-           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) */ ) {
-	tempax |= 0x1000;
-        if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO))  tempax |= 0x2000;
-     }
+  temp = (tempcx >> 8) & 0x0F;
+  temp |= (((tempbx >> 8) << 6) & 0xC0);
+  if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToHiVision | SetCRT2ToYPbPr525750 | SetCRT2ToSCART))) {
+     temp |= 0x10;
+     if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO)) temp |= 0x20;
   }
-  temp = (tempax & 0xFF00) >> 8;
-  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,temp);
+  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,temp);
 
-  /* 650/30xLV 1.10.6s */
-  if(HwDeviceExtension->jChipType > SIS_315H) {
+  if((HwInfo->jChipType > SIS_315H) && (HwInfo->jChipType < SIS_661)) {
      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);
+        if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302LV | VB_SIS302ELV)) {
+           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);
+	   }
         }
      }
   }
-  
-  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]);
-	}
-	for(i=0x39; i<=0x45; i++, j++) {
-	    SiS_SetReg1(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;
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+        if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) {
+           tempbx >>= 1;
+	}
      }
      tempbx -= 3;
+     if(HwInfo->jChipType >= SIS_661) {
+        if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302LV | VB_SIS302ELV)) {  /* Why not 301B/LV? */
+           temp = 0;
+	   if(tempcx & 0x0400) temp |= 0x20;
+	   if(tempbx & 0x0400) temp |= 0x40;
+	   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x10,temp);
+	}
+     }
      tempbx &= 0x03ff;
      temp = ((tempbx & 0xFF00) >> 8) << 5;
      temp |= 0x18;
-     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x46,temp);
+     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x46,temp);
      temp = tempbx & 0x00FF;
-     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x47,temp);
-     if(HwDeviceExtension->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_SetReg1(SiS_Pr->SiS_Part2Port,0x4d,temp);
-        }
-     }
+     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x47,temp);
+
   }
 
-  tempbx &= 0x00FF;
+  tempbx = 0;
   if(!(modeflag & HalfDCLK)) {
      if(SiS_Pr->SiS_VGAHDE >= SiS_Pr->SiS_HDE) {
+        tempax = 0;
         tempbx |= 0x2000;
-        tempax &= 0x00FF;
      }
   }
 
   tempcx = 0x0101;
-/*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)) {
-              tempcx = 0x1920;
-              if(SiS_Pr->SiS_VGAHDE >= 1280) {
-                 tempcx = 0x1420;
-                 tempbx &= 0xDFFF;
-              }
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+     if(SiS_Pr->SiS_VGAHDE >= 1024) {
+        if((!(modeflag & HalfDCLK)) || (HwInfo->jChipType < SIS_315H)) {
+           tempcx = 0x1920;
+           if(SiS_Pr->SiS_VGAHDE >= 1280) {
+              tempcx = 0x1420;
+              tempbx &= ~0x2000;
            }
         }
      }
@@ -7684,23 +7574,23 @@
      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);
+     tempcx = (tempax & 0xFF00) >> (8 + 5);
   }
 
-  temp = (tempax & 0xFF00) >> 8;
-  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x44,temp);
-  temp = (tempbx & 0xFF00) >> 8;
-  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,temp);
+  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,tempax);
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,(tempbx >> 8));
 
   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-     temp = tempcx & 0x00FF;
+
+     temp = tempcx & 0x0007;
      if(tempbx & 0x2000) temp = 0;
-     temp |= 0x18;
+     if((HwInfo->jChipType < SIS_661) || (!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD))) {
+        temp |= 0x18;
+     }
      SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xE0,temp);
 
-     if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+     if(SiS_Pr->SiS_TVMode & TVSetPAL) {
         tempbx = 0x0382;
         tempcx = 0x007e;
      } else {
@@ -7708,78 +7598,54 @@
         tempcx = 0x0061;
      }
      temp = (tempbx & 0x00FF) ;
-     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4B,temp);
+     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4B,temp);
      temp = (tempcx & 0x00FF) ;
-     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4C,temp);
+     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4C,temp);
      temp = (tempcx & 0x0300) >> (8 - 2);
      temp |= ((tempbx >> 8) & 0x03);
-     if(HwDeviceExtension->jChipType < SIS_315H) {
-        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4D,temp);
-     } else {
-        SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4D,0xF0,temp);
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
+        temp |= 0x10;
+	if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)      temp |= 0x20;
+	else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp |= 0x40;
      }
+     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4D,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)) {
-     temp = 0x35;
-  } else if(HwDeviceExtension->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);
-           }
-        }
+     SiS_SetTVSpecial(SiS_Pr, ModeNo);
+
+     if(SiS_Pr->SiS_VBType & VB_SIS301C) {
+        temp = 0;
+        if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
+        SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xf7,temp);
      }
+
   }
 
-  if(HwDeviceExtension->jChipType >= SIS_315H) {
-     if((SiS_Pr->SiS_VBType & VB_SIS301B302B) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
-        if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-           SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x0B,0x00);
-        }
+  if(SiS_Pr->SiS_TVMode & TVSetPALM) {
+     if(!(SiS_Pr->SiS_TVMode & TVSetNTSC1024)) {
+        temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
+        SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp - 1);
      }
+     SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF);
   }
 
-#if 0  /* Old: Why HiVision? */
-  if( (SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) &&
-      (!(SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) ) {
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
      if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x0B,0x00);
+        SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,0x00);
      }
   }
-#endif
 
-  if(HwDeviceExtension->jChipType < SIS_315H) {
-     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-     	SiS_Set300Part2Regs(SiS_Pr, HwDeviceExtension, ModeIdIndex,
-			    RefreshRateTableIndex, BaseAddr, ModeNo);
-	return;
-     }
-  } else {
-     /* !!! The following is a duplicate, done for LCDA as well (see above) */
-     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-        SiS_SetTVSpecial(SiS_Pr, ModeNo);
-        return;
-     }
-  }
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) return;
 
   /* From here: Part2 LCD setup */
 
   tempbx = SiS_Pr->SiS_HDE;
-  if(SiS_IsDualLink(SiS_Pr, HwDeviceExtension, BaseAddr)) tempbx >>= 1;
-  tempbx--;			         	/* RHACTE=HDE-1 */
+  if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
+  tempbx--;			         	/* RHACTE = HDE - 1 */
   temp = tempbx & 0x00FF;
-  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2C,temp);
+  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2C,temp);
   temp = (tempbx & 0xFF00) >> 4;
   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,temp);
 
@@ -7788,7 +7654,7 @@
      if(SiS_Pr->SiS_ModeType == ModeEGA) {
         if(SiS_Pr->SiS_VGAHDE >= 1024) {
            temp = 0x02;
-	   if(HwDeviceExtension->jChipType >= SIS_315H) {
+	   if(HwInfo->jChipType >= SIS_315H) {
               if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
                  temp = 0x01;
 	      }
@@ -7796,89 +7662,185 @@
         }
      }
   }
-  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x0B,temp);
+  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,temp);
 
-  tempbx = SiS_Pr->SiS_VDE;         		/* RTVACTEO = VDE - 1 */
-  /* push1 = tempbx; */
-  tempbx--;
+  tempbx = SiS_Pr->SiS_VDE - 1;
   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; */
-  tempcx--;
-  temp = tempcx & 0x00FF;  			 /* RVTVT = VT - 1 */
-  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x19,temp);
+  tempcx = SiS_Pr->SiS_VT - 1;
+  temp = tempcx & 0x00FF;
+  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) {
-     temp |= 0x10;
-  } else {
-     if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-        /* 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 = ((tempcx & 0xFF00) >> 8) << 5;
+
+  /* Enable dithering; only do this for 32bpp mode */
+  if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
+     if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
         temp |= 0x10;
      }
   }
 
-  /* 630/301 does not do all this */
+  /* Must do special for Compaq1280; Acer1280 OK, Clevo1400 OK, COMPAL1400 OK */
+  /* Compaq1280 panel loses sync if using CR37 sync info. */
   if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
-     if((HwDeviceExtension->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
+     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)) {
-#ifdef SIS315H
 	   if(SiS_Pr->SiS_LCDInfo & LCDSync) {
-	      temp |= (SiS_Pr->SiS_LCDInfo >> 6);
+	      temp |= ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6);
 	   }
-#endif
+	} else if((SiS_Pr->SiS_CustomT == CUT_CLEVO1400) &&
+	          (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)) {
+	   temp |= 0x03;
 	} else {
-	   /* 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 */
+           temp |= (SiS_GetReg(SiS_Pr->SiS_P3d4,0x37) >> 6);
+	   temp |= 0x08;
+	   if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) temp |= 0x04;
 	}
      } else {
         if(SiS_Pr->SiS_LCDInfo & LCDSync) {
-	   temp |= (SiS_Pr->SiS_LCDInfo >> 6);
+	   temp |= ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6);
 	}
      }
   }
-  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1A,temp);
 
-  SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x09,0xF0);
-  SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x0A,0xF0);
+  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1A,temp);
+
+  SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x09,0xF0);
+  SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x0A,0xF0);
+
+  SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB);
+  SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF);
+
+#if 0  /* Use the 315/330 series code for now */
+  if((HwInfo->jChipType >= SIS_661)          &&
+     (SiS_Pr->SiS_VBType & VB_SIS301LV302LV) &&
+     (ROMAddr && SiS_Pr->SiS_UseROM)) {
+
+      /* This is done for the LVDS bridges only, since
+       * the TMDS panels already work correctly with
+       * the old code. Besides, we only do that if
+       * we can get the data from the ROM, I am tired
+       * of carrying a lot of tables around.
+       */
+
+#ifdef SIS315H 							/* ------------ 661/741/760 series --------- */
+      UCHAR *myptr = NULL, myptr1 = NULL;
+
+      myptr = (UCHAR *)GetLCDPtr661(SiS_Pr, HwInfo, 6, ModeNo, ModeIdIndex, RefreshRateTableIndex);
+      myptr1 = (UCHAR *)GetLCDStructPtr661(SiS_Pr, HwInfo);
+
+      tempbx = (myptr[3] | (myptr[4] << 8)) & 0x0fff;
+      tempcx = SiS_Pr->PanelYRes;
+      if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
+         tempcx = SiS_Pr->SiS_VDE;
+      }
+
+      tempcx += tempbx;
+      if(tempcx >= SiS_Pr->SiS_VT) tempcx -= SiS_Pr->SiS_VT;
+
+      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,tempbx);
+      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,tempcx);
+
+      tempcx &= 0x07ff;
+      tempbx &= 0x07ff;
+      temp = (tempcx >> 8) << 3;
+      temp |= (tempbx >> 8);
+      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
+
+      tempbx = (myptr[4] | (myptr[5] << 8)) >> 4;
+      tempcx = myptr1[6];
+      if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempcx = myptr[7];
+
+      tempcx += tempbx;
+      if(tempcx >= SiS_Pr->SiS_VT) tempcx -= SiS_Pr->SiS_VT;
+
+      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,tempbx);
+      temp = tempcx & 0x000f;
+      temp |= ((tempbx & 0x0f00) >> 4);
+      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
+
+      tempax = SiS_Pr->SiS_HT;
+      tempbx = (myptr[0] | (myptr[1] << 8)) & 0x0fff;
+      tempcx = SiS_Pr->PanelXRes;
+      if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempcx = SiS_Pr->SiS_HDE;
+
+      if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
+         tempax >>= 1;
+	 tempbx >>= 1;
+	 tempcx >>= 1;
+      }
+      if(SiS_Pr->SiS_VBType & VB_SIS302LV)                 tempbx++;
+      if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV)) tempbx++;
+
+      tempcx += tempbx;
+      if(tempcx >= tempax) tempcx -= tempax;
+
+      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,tempbx);
+      temp = ((tempbx & 0xff00) >> 8) << 4;
+      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x20,temp);
+      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,tempcx);
+      temp = tempcx >> 8;
+      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x25,temp);
+
+      tempax = SiS_Pr->SiS_HT;
+      tempbx = (myptr[1] | (myptr[2] << 8)) >> 4;
+      tempcx = myptr1[5];
+      if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
+         tempcx = myptr[6];
+      }
+      if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
+         tempax >>= 1;
+	 tempbx >>= 1;
+	 tempcx >>= 1;
+      }
+      if(SiS_Pr->SiS_VBType & VB_SIS302LV) tempbx++;
+
+      tempcx += tempbx;
+      if(tempcx >= tempax) tempcx -= tempax;
+
+      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1c,tempbx);
+      temp = (tempbx & 0x0f00) >> 4;
+      SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1d,0x0f,temp);
+      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,tempcx);
+
+      if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
+         if(SiS_Pr->SiS_VGAVDE == 525) {
+	    temp = 0xc3;
+	    if(SiS_Pr->SiS_ModeType <= ModeVGA) {
+	       temp++;
+	       if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp += 2;
+	    }
+	    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_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
+	 }
+      }
+
+#endif
 
-  SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB);
-  SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF);
+  } else
+#endif
+         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)) ) {
 
-  if((HwDeviceExtension->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 							/* ------------- 315/330 series ------------ */
 
-      /* 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,HwDeviceExtension,BaseAddr);
+      SiS_GetCRT2Part2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
+                          &CRT2Index, &resindex, HwInfo);
 
       switch(CRT2Index) {
         case Panel_1024x768      : CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;  break;  /* "Normal" */
@@ -7899,21 +7861,22 @@
 	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;
+	case 106:		   CRT2Part2Ptr = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_Asus1024x768_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)) {
@@ -7923,25 +7886,24 @@
 	     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);
+	  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);
 	}
      }
 
-     /* !!! 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 */
+	   /* See Sync above, 0x1a */
 	   temp = 1;
 	   if(ModeNo <= 0x13) temp = 3;
-	   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x0b,temp);
+	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0b,temp);
 	}
      }
 #endif
@@ -7949,15 +7911,12 @@
   } 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++;
-
+    tempcx = SiS_Pr->SiS_VT;
     tempbx = SiS_Pr->PanelYRes;
 
     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
@@ -7980,13 +7939,6 @@
        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 */
 
@@ -7995,20 +7947,20 @@
 #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 = 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;
+    if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx -= 10;
 
     /* non-expanding: lcdvrs = tempbx = ((VT + VDE) / 2) - 10 */
 
@@ -8021,7 +7973,7 @@
 #endif
 
     temp = tempbx & 0x00FF;   				/* RTVACTEE = lcdvrs */
-    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,temp);
+    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,temp);
 
     temp = ((tempbx & 0xFF00) >> 8) << 4;
     tempbx += (tempcx + 1);
@@ -8036,36 +7988,34 @@
     xf86DrvMsg(0, X_INFO, "lcdvre[3:0] 0x%x\n", (temp & 0x0f));
 #endif
 
-    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,temp);
+    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
 
     /* Code from 630/301B (I+II) BIOS */
 
+#ifdef SIS300
     if(!SiS_Pr->UseCustomMode) {
-       if( ( ( (HwDeviceExtension->jChipType == SIS_630) ||
-               (HwDeviceExtension->jChipType == SIS_730) ) &&
-             (HwDeviceExtension->jChipRevision > 2) )  &&
+       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_SetReg1(SiS_Pr->SiS_Part2Port,0x04,0xB9);
-             SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x05,0xCC);
-             SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x06,0xA6);
+             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_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);
+                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);
              }
           }
        }
-    }
 
-#ifdef SIS300
-    if(HwDeviceExtension->jChipType < SIS_315H) {
-       if(!SiS_Pr->UseCustomMode) {
+       if(HwInfo->jChipType < SIS_315H) {
           if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
              crt2crtc &= 0x1f;
              tempcx = 0;
@@ -8076,18 +8026,18 @@
              }
              tempcx += crt2crtc;
              if(crt2crtc >= 4) {
-                SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x06,0xff);
+                SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xff);
              }
 
              if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
                 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
                    if(crt2crtc == 4) {
-                      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x28);
+                      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x28);
                    }
                 }
              }
-             SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x18);
-             SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
+             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x18);
+             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
           }
        }
     }
@@ -8105,7 +8055,7 @@
 #endif
 
     temp = tempbx & 0x00FF;    			          /* RHEQPLE = lcdhdee */
-    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x23,temp);
+    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,temp);
     temp = (tempbx & 0xFF00) >> 8;
     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0xF0,temp);
 
@@ -8113,7 +8063,7 @@
     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
        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;
@@ -8138,7 +8088,7 @@
           }
        }
     }
-    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1C,temp);
+    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1C,temp);
     temp = (tempbx & 0x0F00) >> 4;
     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,temp);
 
@@ -8158,7 +8108,7 @@
 #endif
 
     temp = tempbx & 0x00FF;            		          /* RHSYEXP2S = lcdhre */
-    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x21,temp);
+    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,temp);
 
     if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
        if(SiS_Pr->SiS_VGAVDE == 525) {
@@ -8166,86 +8116,35 @@
     	     temp=0xC6;
           else
        	     temp=0xC3;
-          SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,temp);
-          SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,0xB3);
+          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_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,temp);
+          SiS_SetReg(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;
+#ifdef SIS300
+    SiS_Set300Part2Regs(SiS_Pr, HwInfo, ModeIdIndex,
+                        RefreshRateTableIndex, ModeNo);
+#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);
+  } /* HwInfo */
 }
 
-/* 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;
-
-  if(HwDeviceExtension->jChipType != SIS_300) return;
-  if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) return;
-  if(SiS_Pr->UseCustomMode) return;
-
-  if(ModeNo <= 0x13) {
-     crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-  } else {
-     crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-  }
-
-  resindex = crt2crtc & 0x3F;
-  if(SiS_Pr->SiS_SetFlag & LCDVESATiming) CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
-  else                                    CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2;
-
-  /* The BIOS code (1.16.51) is obviously a fragment! */
-  if(ModeNo > 0x13) {
-     CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
-     resindex = 4;
-  }
-
-  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]);
-}
+/*********************************************/
+/*         SET PART 3 REGISTER GROUP         */
+/*********************************************/
 
-void
-SiS_SetGroup3(SiS_Private *SiS_Pr, USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
-              USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+static void
+SiS_SetGroup3(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+              PSIS_HW_INFO HwInfo)
 {
-  USHORT temp;
-  USHORT i;
+  USHORT modeflag, i;
   const UCHAR  *tempdi;
-  USHORT modeflag;
 
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
 
@@ -8260,73 +8159,105 @@
   }
 
 #ifndef SIS_CP
-  SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x00,0x00);
-#endif  
+  SiS_SetReg(SiS_Pr->SiS_Part3Port,0x00,0x00);
+#endif
 
 #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);
-  } 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(SiS_Pr->SiS_TVMode & TVSetPAL) {
+     SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
+     SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
+  } else {
+     SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xF5);
+     SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xB7);
   }
 
-  temp = 0;
-  if((HwDeviceExtension->jChipType == SIS_630)||
-     (HwDeviceExtension->jChipType == SIS_730)) {
-     temp = 0x35;
-  } else if(HwDeviceExtension->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_TVMode & TVSetPALM) {
+     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 = NULL;
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
      tempdi = SiS_Pr->SiS_HiTVGroup3Data;
-     if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
+     if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
         tempdi = SiS_Pr->SiS_HiTVGroup3Simu;
         if(!(modeflag & Charx8Dot)) {
            tempdi = SiS_Pr->SiS_HiTVGroup3Text;
         }
      }
-     if(SiS_Pr->SiS_HiVision & 0x03) {
+  } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
+     if(!(SiS_Pr->SiS_TVMode & TVSetYPbPr525i)) {
         tempdi = SiS_HiTVGroup3_1;
-        if(SiS_Pr->SiS_HiVision & 0x02) tempdi = SiS_HiTVGroup3_2;
+        if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempdi = SiS_HiTVGroup3_2;
      }
+  }
+  if(tempdi) {
      for(i=0; i<=0x3E; i++){
-        SiS_SetReg1(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
+        SiS_SetReg(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
+     }
+     if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV)) {
+	if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
+	   SiS_SetReg(SiS_Pr->SiS_Part3Port,0x28,0x3f);
+	}
      }
   }
 
+  if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToHiVision | SetCRT2ToYPbPr525750))) {
 #ifdef SIS_CP
-  SIS_CP_INIT301_CP2
+     SIS_CP_INIT301_CP2
 #endif
+  }
+}
+
+/*********************************************/
+/*         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) {
+     if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
+        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,reg1);
+        SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
+     }
+  } 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 */
-void
-SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
-              USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
-	      PSIS_HW_DEVICE_INFO HwDeviceExtension)
+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;
@@ -8344,48 +8275,50 @@
      }
   }
 
-  if(HwDeviceExtension->jChipType >= SIS_315H) {
+  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);
         }
      }
   }
 
-  if(SiS_Pr->SiS_VBType & VB_SIS302LV) {
-      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-          SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x10,0x9f);
-      }
+  if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302LV)) {
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+        SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x10,0x9f);
+     }
   }
 
-  if(HwDeviceExtension->jChipType >= SIS_315H) {
+  if(HwInfo->jChipType >= SIS_315H) {
      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
         if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-	   /* 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, HwDeviceExtension, BaseAddr)) {
+	   if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
 	      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);
+#ifdef SET_EMI
+	   if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
+	      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;
@@ -8394,16 +8327,19 @@
   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;
+  if(HwInfo->jChipType >= SIS_661) {
+     if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
+  }
 
   temp = 0xA0;
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
      temp = 0;
      if(tempbx > 800) {
         temp = 0xA0;
@@ -8411,524 +8347,188 @@
            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;
-     }
-  }
-  if(SiS_Pr->SiS_HiVision & 0x03) {
-        temp = 0;
-	if(SiS_Pr->SiS_VGAHDE == 1024) temp = 0x20;
-  }
-
-  if(SiS_IsDualLink(SiS_Pr, HwDeviceExtension, BaseAddr)) temp = 0;
-
-  if(SiS_Pr->SiS_VBType & VB_SIS301) {
-     if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024)
-        temp |= 0x0A;
-  }
-
-  SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0E,0x10,temp);
-
-  tempebx = SiS_Pr->SiS_VDE;
-
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
-     if(!(temp & 0xE0)) tempebx >>=1;
-  }
-
-  tempcx = SiS_Pr->SiS_RVBHRS;
-  temp = tempcx & 0x00FF;
-  SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x18,temp);
-
-  tempeax = SiS_Pr->SiS_VGAVDE;
-  tempcx |= 0x4000;
-  if(tempeax <= tempebx) {
-     tempcx ^= 0x4000;
-  } else {
-     tempeax -= tempebx;
-  }
-
-  templong = (tempeax * 256 * 1024) % tempebx;
-  tempeax = (tempeax * 256 * 1024) / tempebx;
-  tempebx = tempeax;
-  if(templong != 0) tempebx++;
-
-  temp = (USHORT)(tempebx & 0x000000FF);
-  SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1B,temp);
-  temp = (USHORT)((tempebx & 0x0000FF00) >> 8);
-  SiS_SetReg1(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);
-
-  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-
-         SiS_SetReg1(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_IsDualLink(SiS_Pr, HwDeviceExtension, BaseAddr)) 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++;
-            }
-         }
-	 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 == SIS_RI_1024x768) tempax = 0x1f;	/* From 1.10.7w */
-	    }							/* From 1.10.7w */
-	 }							/* From 1.10.7w */
-	 SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1D,tempax & 0x00FF);
-	 temp <<= 4;
-	 temp |= tempbx;
-	 SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1E,temp);
-
-	 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-	    if(IS_SIS550650740660) {
-	       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(SiS_IsDualLink(SiS_Pr, HwDeviceExtension, BaseAddr)) 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);
-	       /* LCD-too-dark-error-source, see FinalizeLCD() */
-	    }
-	 }
-
-	 if(HwDeviceExtension->jChipType >= SIS_315H) {
-	    /* 650/LV BIOS does this for all bridge types - assumingly wrong */
-	    /* 315, 330, 650+301B BIOS don't do this at all */
-            /* This is a duplicate; done for LCDA as well (see above) */
-	    if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-	       if(SiS_IsDualLink(SiS_Pr, HwDeviceExtension, BaseAddr)) {
-		  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) {
-	    /* 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 temp, reg1, reg2;
-
-  if(SiS_Pr->UseCustomMode) {
-     reg1 = SiS_Pr->CSR2B;
-     reg2 = SiS_Pr->CSR2C;
-  } else {
-     vclkindex = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
-                                 HwDeviceExtension);
-     reg1 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
-     reg2 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
-  }
-
-  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0A,reg1);
-     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0B,reg2);
-     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 == 0x64) || (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);
-     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0B,reg2);
-     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0A,reg1);
-  }
-  SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x12,0x00);
-  temp = 0x08;
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) temp |= 0x20;
-  SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,temp);
-}
-
-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};
-  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
-  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;
-  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 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+     if(tempbx <= 800) {
+        temp = 0x80;
+     }
   } else {
-#ifdef SIS300
-		LCDXlatVCLK1 = LCDXlat1VCLK300;
-		LCDXlatVCLK2 = LCDXlat2VCLK300;
-		LVDSXlatVCLK2 = LVDSXlat2VCLK300;
-		LVDSXlatVCLK3 = LVDSXlat3VCLK300;
-#endif
+     temp = 0x80;
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+        temp = 0;
+        if(tempbx > 800) temp = 0x60;
+     }
   }
 
-  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_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
+     temp = 0;
+     if(SiS_Pr->SiS_VGAHDE == 1024) temp = 0x20;
   }
 
-  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {    /* 30x/B/LV */
-
-     if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
+  if(HwInfo->jChipType < SIS_661) {
+     if(SiS_IsDualLink(SiS_Pr, HwInfo)) temp = 0;
+  }
 
-        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 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_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) {
-		      if(HwDeviceExtension->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(HwDeviceExtension->jChipType <= SIS_315PRO) {
-		      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 += TVCLKBASE_300;
-  		} else {
-			VCLKIndex += TVCLKBASE_315;
-		}
-        } 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)) {
-				     /* This is certainly wrong: It replaces clock
-				      * 108 by 47...
-				      */
-				     /* if(VCLKIndex == 0x14) VCLKIndex = 0x2e; */
-				     if(VCLKIndex == 0x14) VCLKIndex = 0x34;
-				}
-			}
-        	}
-        }
+  if(SiS_Pr->SiS_VBType & VB_SIS301) {
+     if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024)
+        temp |= 0x0A;
+  }
 
-    } else {   /* If not programming CRT2 */
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0E,0x10,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;
-		}
-	     }
-        }
-    }
+  tempebx = SiS_Pr->SiS_VDE;
 
-  } else {       /*   LVDS  */
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
+     if(!(temp & 0xE0)) tempebx >>=1;
+  }
 
-    	VCLKIndex = CRT2Index;
+  tempcx = SiS_Pr->SiS_RVBHRS;
+  temp = tempcx & 0x00FF;
+  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x18,temp);
 
-	if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {  /* programming CRT2 */
+  tempeax = SiS_Pr->SiS_VGAVDE;
+  tempcx |= 0x4000;
+  if(tempeax <= tempebx) {
+     tempcx ^= 0x4000;
+  } else {
+     tempeax -= tempebx;
+  }
 
-	   if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
+  templong = (tempeax * 256 * 1024) % tempebx;
+  tempeax = (tempeax * 256 * 1024) / tempebx;
+  tempebx = tempeax;
+  if(templong != 0) tempebx++;
 
-		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];
-
-	   } 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_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    VCLKIndex = LVDSXlatVCLK3[VCLKIndex];
-
-		if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
-		   /* Special Timing: Barco iQ Pro R300/400/... */
-		   VCLKIndex = 0x44;
-		}
+  temp = (USHORT)(tempebx & 0x000000FF);
+  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1B,temp);
+  temp = (USHORT)((tempebx & 0x0000FF00) >> 8);
+  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1A,temp);
 
-		if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
-		   if(HwDeviceExtension->jChipType < SIS_315H) {
-		      VCLKIndex = VCLK34_300;
-		      /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
-		   } else {
-		      VCLKIndex = VCLK34_315;
-		      /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
-		   }
-		}
+  tempbx = (USHORT)(tempebx >> 16);
+  temp = tempbx & 0x00FF;
+  temp <<= 4;
+  temp |= ((tempcx & 0xFF00) >> 8);
+  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x19,temp);
 
-	   } else {
+  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
 
-	        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;
-		     }
-	        }
-	   }
+     SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1C,0x28);
 
-	} else {  /* if not programming CRT2 */
+     tempbx = 0;
+     tempax = SiS_Pr->SiS_VGAHDE;
+     if(modeflag & HalfDCLK) 		tempax >>= 1;
+     if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempax >>= 1;
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+	if(tempax > 800) tempax -= 800;
+     } else {
+        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) & 0x03;
+     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_SetReg(SiS_Pr->SiS_Part4Port,0x1E,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(IS_SIS550650740660) {
+	   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) {
+        if(!(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetHiVision | TVSetYPbPr750p | TVSetYPbPr525p))) {
+	   temp |= 0x01;
+	   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+	      if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
+  	         temp &= 0xFE;
 	      }
 	   }
-
 	}
+     }
+     SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0,temp);
 
-  }
-#ifdef TWDEBUG
-  xf86DrvMsg(0, X_INFO, "VCLKIndex %d (0x%x)\n", VCLKIndex, VCLKIndex);
+     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);
+
+     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 | VB_SIS302ELV)) {
+	   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(VCLKIndex);
+     }
+
+  }  /* 301B */
+
+  SiS_SetCRT2VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
 }
 
+/*********************************************/
+/*         SET PART 5 REGISTER GROUP         */
+/*********************************************/
+
 /* Set 301 Palette address port registers */
-/* 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)
+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_VBInfo & (SetInSlaveMode | LoadDACFlag))){
+     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 tempah,i,modeflag,j;
   USHORT ResIndex,DisplayType;
   const SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr=NULL;
 
@@ -8943,12 +8543,10 @@
      (SiS_Pr->SiS_CustomT == CUT_PANEL848))
      return;
 
-  temp = SiS_GetLVDSCRT1Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
-                            &ResIndex,&DisplayType);
+  if(!(SiS_GetLVDSCRT1Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
+                          &ResIndex, &DisplayType))) return;
 
-  if(temp == 0) return;
-
-  if(HwDeviceExtension->jChipType < SIS_315H) {
+  if(HwInfo->jChipType < SIS_315H) {
      if(SiS_Pr->SiS_SetFlag & SetDOSMode) return;
   }
 
@@ -9005,27 +8603,27 @@
   SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);                        /*unlock cr0-7  */
 
   tempah = (LVDSCRT1Ptr + ResIndex)->CR[0];
-  SiS_SetReg1(SiS_Pr->SiS_P3d4,0x00,tempah);
+  SiS_SetReg(SiS_Pr->SiS_P3d4,0x00,tempah);
 
   for(i=0x02,j=1;i<=0x05;i++,j++){
     tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
-    SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
+    SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
   }
   for(i=0x06,j=5;i<=0x07;i++,j++){
     tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
-    SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
+    SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
   }
   for(i=0x10,j=7;i<=0x11;i++,j++){
     tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
-    SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
+    SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
   }
   for(i=0x15,j=9;i<=0x16;i++,j++){
     tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
-    SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
+    SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
   }
   for(i=0x0A,j=11;i<=0x0C;i++,j++){
     tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
-    SiS_SetReg1(SiS_Pr->SiS_P3c4,i,tempah);
+    SiS_SetReg(SiS_Pr->SiS_P3c4,i,tempah);
   }
 
   tempah = (LVDSCRT1Ptr + ResIndex)->CR[14];
@@ -9045,114 +8643,15 @@
   }
 }
 
-BOOLEAN
-SiS_GetLVDSCRT1Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-		   USHORT RefreshRateTableIndex,USHORT *ResIndex,
-		   USHORT *DisplayType)
- {
-  USHORT tempbx,modeflag=0;
-  USHORT Flag,CRT2CRTC;
-
-  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;
-  }
-
-  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;
-  }
-
-  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++;
-	   }
-        }
-     }
-  }
-  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++;
-        }
-
-     }
-     if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
-        tempbx = 12;
-	if(modeflag & HalfDCLK) tempbx++;
-     }
-  }
-
-#if 0
-  if(SiS_Pr->SiS_IF_DEF_FSTN) {
-     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel320x480){
-        tempbx = 22;
-     }
-  }
-#endif
-
-  *ResIndex = CRT2CRTC & 0x3F;
-  *DisplayType = tempbx;
-  return 1;
-}
+/*********************************************/
+/*              SET CRT2 ECLK                */
+/*********************************************/
 
-void
-SiS_SetCRT2ECLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex,
-           USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+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;
 
@@ -9161,12 +8660,12 @@
         if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK & 0x3f) == 2) {
 	   RefreshRateTableIndex--;
 	}
-	vclkindex = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
-                                    RefreshRateTableIndex,HwDeviceExtension);
+	vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
+                                    RefreshRateTableIndex, HwInfo);
 	SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
   } else {
-        vclkindex = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
-                                    RefreshRateTableIndex,HwDeviceExtension);
+        vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
+                                    RefreshRateTableIndex, HwInfo);
   }
 
   sr2b = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
@@ -9188,42 +8687,24 @@
      }
   }
 
-  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86);
-  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x20);
-  SiS_SetReg1(SiS_Pr->SiS_P3c4,clkbase,sr2b);
-  SiS_SetReg1(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
-  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x10);
-  SiS_SetReg1(SiS_Pr->SiS_P3c4,clkbase,sr2b);
-  SiS_SetReg1(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
-  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x00);
-  SiS_SetReg1(SiS_Pr->SiS_P3c4,clkbase,sr2b);
-  SiS_SetReg1(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
-}
-
-#if 0  /* 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
 
-/* 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;
@@ -9236,18 +8717,18 @@
     	tempcl = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
 
   TVType = 0;
-  if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) TVType += 1;
-  if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+  if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
+  if(SiS_Pr->SiS_TVMode & TVSetPAL) {
   	TVType += 2;
 	if(SiS_Pr->SiS_ModeType > ModeVGA) {
 	   if(SiS_Pr->SiS_CHSOverScan) TVType = 8;
 	}
-	if(SiS_Pr->SiS_CHPALM) {
+	if(SiS_Pr->SiS_TVMode & TVSetPALM) {
 		TVType = 4;
-		if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) TVType += 1;
-	} else if(SiS_Pr->SiS_CHPALN) {
+		if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
+	} else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
 		TVType = 6;
-		if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) TVType += 1;
+		if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
 	}
   }
   switch(TVType) {
@@ -9273,7 +8754,7 @@
      /* We don't support modes >800x600 */
      if (resindex > 5) return;
 
-     if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+     if(SiS_Pr->SiS_TVMode & TVSetPAL) {
     	SiS_SetCH700x(SiS_Pr,0x4304);   /* 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
     	SiS_SetCH700x(SiS_Pr,0x6909);	/* Black level for PAL (105)*/
      } else {
@@ -9318,7 +8799,7 @@
       */
 #ifndef SIS_CP
      SiS_SetCH70xx(SiS_Pr,0x003D);
-#endif     
+#endif
 
      /* Register 0x10 only contains 1 writable bit (S0) for sensing,
             all other bits a read-only. Macrovision?
@@ -9334,12 +8815,12 @@
       */
      SiS_SetCH70xxANDOR(SiS_Pr,0x001C,0xEF);
 
-     if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {		/* ---- NTSC ---- */
-       if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) {
+     if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {		/* ---- NTSC ---- */
+       if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) {
          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 */
+         } 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);
@@ -9372,9 +8853,9 @@
            SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);
          }
        }
-     } else {				/* ---- PAL ---- */
+     } else {						/* ---- PAL ---- */
            /* We don't play around with FSCI in PAL mode */
-         if (resindex == 0x04) {
+         if(resindex == 0x04) {
            SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); 	/* loop filter off */
            SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);      /* ACIV on */
          } else {
@@ -9395,69 +8876,85 @@
      if (resindex > 6) return;
 
      temp = CHTVRegData[resindex].Reg[0];
-     tempbx=((temp & 0x00FF) <<8 ) | 0x00;
+     if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
+        temp |= 0x10;
+     }
+     tempbx=((temp & 0x00FF) << 8) | 0x00;
      SiS_SetCH701x(SiS_Pr,tempbx);
 
      temp = CHTVRegData[resindex].Reg[1];
-     tempbx=((temp & 0x00FF) <<8 ) | 0x01;
+     tempbx=((temp & 0x00FF) << 8) | 0x01;
      SiS_SetCH701x(SiS_Pr,tempbx);
 
      temp = CHTVRegData[resindex].Reg[2];
-     tempbx=((temp & 0x00FF) <<8 ) | 0x02;
+     tempbx=((temp & 0x00FF) << 8) | 0x02;
      SiS_SetCH701x(SiS_Pr,tempbx);
 
      temp = CHTVRegData[resindex].Reg[3];
-     tempbx=((temp & 0x00FF) <<8 ) | 0x04;
+     tempbx=((temp & 0x00FF) << 8) | 0x04;
      SiS_SetCH701x(SiS_Pr,tempbx);
 
      temp = CHTVRegData[resindex].Reg[4];
-     tempbx=((temp & 0x00FF) <<8 ) | 0x03;
+     tempbx=((temp & 0x00FF) << 8) | 0x03;
      SiS_SetCH701x(SiS_Pr,tempbx);
 
      temp = CHTVRegData[resindex].Reg[5];
-     tempbx=((temp & 0x00FF) <<8 ) | 0x05;
+     tempbx=((temp & 0x00FF) << 8) | 0x05;
      SiS_SetCH701x(SiS_Pr,tempbx);
 
      temp = CHTVRegData[resindex].Reg[6];
-     tempbx=((temp & 0x00FF) <<8 ) | 0x06;
+     tempbx=((temp & 0x00FF) << 8) | 0x06;
      SiS_SetCH701x(SiS_Pr,tempbx);
 
      temp = CHTVRegData[resindex].Reg[7];
-     tempbx=((temp & 0x00FF) <<8 ) | 0x07;
+     if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
+	temp = 0x66;
+     }
+     tempbx=((temp & 0x00FF) << 8) | 0x07;
      SiS_SetCH701x(SiS_Pr,tempbx);
 
      temp = CHTVRegData[resindex].Reg[8];
-     tempbx=((temp & 0x00FF) <<8 ) | 0x08;
+     tempbx=((temp & 0x00FF) << 8) | 0x08;
      SiS_SetCH701x(SiS_Pr,tempbx);
 
      temp = CHTVRegData[resindex].Reg[9];
-     tempbx=((temp & 0x00FF) <<8 ) | 0x15;
+     tempbx=((temp & 0x00FF) << 8) | 0x15;
      SiS_SetCH701x(SiS_Pr,tempbx);
 
      temp = CHTVRegData[resindex].Reg[10];
-     tempbx=((temp & 0x00FF) <<8 ) | 0x1f;
+     tempbx=((temp & 0x00FF) << 8) | 0x1f;
      SiS_SetCH701x(SiS_Pr,tempbx);
 
      temp = CHTVRegData[resindex].Reg[11];
-     tempbx=((temp & 0x00FF) <<8 ) | 0x0c;
+     tempbx=((temp & 0x00FF) << 8) | 0x0c;
      SiS_SetCH701x(SiS_Pr,tempbx);
 
      temp = CHTVRegData[resindex].Reg[12];
-     tempbx=((temp & 0x00FF) <<8 ) | 0x0d;
+     tempbx=((temp & 0x00FF) << 8) | 0x0d;
      SiS_SetCH701x(SiS_Pr,tempbx);
 
      temp = CHTVRegData[resindex].Reg[13];
-     tempbx=((temp & 0x00FF) <<8 ) | 0x0e;
+     tempbx=((temp & 0x00FF) << 8) | 0x0e;
      SiS_SetCH701x(SiS_Pr,tempbx);
 
      temp = CHTVRegData[resindex].Reg[14];
-     tempbx=((temp & 0x00FF) <<8 ) | 0x0f;
+     tempbx=((temp & 0x00FF) << 8) | 0x0f;
      SiS_SetCH701x(SiS_Pr,tempbx);
 
      temp = CHTVRegData[resindex].Reg[15];
-     tempbx=((temp & 0x00FF) <<8 ) | 0x10;
+     tempbx=((temp & 0x00FF) << 8) | 0x10;
      SiS_SetCH701x(SiS_Pr,tempbx);
-     
+
+     temp = SiS_GetCH701x(SiS_Pr,0x21) & ~0x02;
+     /* D1 should be set for PAL, PAL-N and NTSC-J,
+        but I won't do that for PAL unless somebody
+	tells me to do so. Since the BIOS uses
+	non-default CIV values and blacklevels,
+	this might be compensated anyway.
+      */
+     if(SiS_Pr->SiS_TVMode & (TVSetPALN | TVSetNTSCJ)) temp |= 0x02;
+     SiS_SetCH701x(SiS_Pr,((temp << 8) | 0x21));
+
 #endif	/* 315 */
 
   }
@@ -9468,16 +8965,14 @@
 
 }
 
-/* Chrontel 701x functions ================================= */
-
 void
-SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
   USHORT temp;
 
   /* Enable Chrontel 7019 LCD panel backlight */
   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
-     if(HwDeviceExtension->jChipType == SIS_740) {
+     if(HwInfo->jChipType == SIS_740) {
         SiS_SetCH701x(SiS_Pr,0x6566);
      } else {
         temp = SiS_GetCH701x(SiS_Pr,0x66);
@@ -9487,23 +8982,63 @@
   }
 }
 
-void
-SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr)
-{
-  USHORT temp;
+void
+SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr)
+{
+  USHORT temp;
+
+  /* Disable Chrontel 7019 LCD panel backlight */
+  if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+     temp = SiS_GetCH701x(SiS_Pr,0x66);
+     temp &= 0xDF;
+     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
+  }
+}
+
+#ifdef SIS315H  /* ----------- 315 series only ---------- */
+
+static void
+SiS_ChrontelPowerSequencing(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+  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 */
 
-  /* Disable Chrontel 7019 LCD panel backlight */
-  if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
-        temp = SiS_GetCH701x(SiS_Pr,0x66);
-        temp &= 0xDF;
-	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
+  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;
   }
-}
 
-#ifdef SIS315H  /* ----------- 315 series only ---------- */
+  for(i=0; i<5; i++) {
+     SiS_SetCH701x(SiS_Pr,(tableptr[i] << 8) | regtable[i]);
+  }
+}
 
-void
-SiS_SetCH701xForLCD(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
+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 };
@@ -9527,7 +9062,7 @@
   USHORT tempbh;
   int i;
 
-  if(HwDeviceExtension->jChipType == SIS_740) {
+  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) {
@@ -9558,11 +9093,11 @@
         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;
      }
   }
 
-  if(HwDeviceExtension->jChipType == SIS_740) {
+  if(HwInfo->jChipType == SIS_740) {
      tempbh = 0x0d;
   } else {
      tempbh = 0x0c;
@@ -9570,16 +9105,16 @@
   for(i = 0; i < tempbh; i++) {
      SiS_SetCH701x(SiS_Pr,(tableptr[i] << 8) | regtable[i]);
   }
-  SiS_ChrontelPowerSequencing(SiS_Pr,HwDeviceExtension);
+  SiS_ChrontelPowerSequencing(SiS_Pr,HwInfo);
   tempbh = SiS_GetCH701x(SiS_Pr,0x1e);
   tempbh |= 0xc0;
   SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x1e);
 
-  if(HwDeviceExtension->jChipType == SIS_740) {
+  if(HwInfo->jChipType == SIS_740) {
      tempbh = SiS_GetCH701x(SiS_Pr,0x1c);
      tempbh &= 0xfb;
      SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x1c);
-     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2d,0x03);
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
      tempbh = SiS_GetCH701x(SiS_Pr,0x64);
      tempbh |= 0x40;
      SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x64);
@@ -9589,72 +9124,53 @@
   }
 }
 
-void
-SiS_ChrontelPowerSequencing(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+static void
+SiS_ChrontelResetVSync(SiS_Private *SiS_Pr)
 {
-  UCHAR regtable[]      = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
-  UCHAR table1024_740[] = { 0x01, 0x02, 0x01, 0x01, 0x01 };
-  UCHAR table1400_740[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 };
-  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 */
+  unsigned char temp, temp1;
 
-  if(HwDeviceExtension->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) ||
-               (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) ||
-	       (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)) {
-        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]);
-  }
+  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) {
-     if(HwDeviceExtension->jChipType == SIS_740) {
+     if(HwInfo->jChipType == SIS_740) {
         temp = SiS_GetCH701x(SiS_Pr,0x1c);
-        temp |= 0x04;
+        temp |= 0x04;	/* Invert XCLK phase */
         SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c);
      }
-     if(SiS_IsYPbPr(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+     if(SiS_IsYPbPr(SiS_Pr, HwInfo)) {
         temp = SiS_GetCH701x(SiS_Pr,0x01);
 	temp &= 0x3f;
 	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;	/* Enable SCART + CVBS */
 	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x01);
      }
-     if(HwDeviceExtension->jChipType == SIS_740) {
-        SiS_ChrontelDoSomething5(SiS_Pr);
-        SiS_SetCH701x(SiS_Pr,0x2049);   			/* Enable TV path */
+     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 */
+        SiS_SetCH701x(SiS_Pr,0x2049);   /* Enable TV path */
         temp = SiS_GetCH701x(SiS_Pr,0x49);
-        if(SiS_IsYPbPr(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+        if(SiS_IsYPbPr(SiS_Pr,HwInfo)) {
            temp = SiS_GetCH701x(SiS_Pr,0x73);
 	   temp |= 0x60;
 	   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x73);
@@ -9671,13 +9187,13 @@
 }
 
 void
-SiS_Chrontel701xOff(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+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(HwDeviceExtension->jChipType == SIS_740) {
+     if(HwInfo->jChipType == SIS_740) {
         SiS_LongDelay(SiS_Pr,1);
 	SiS_GenericDelay(SiS_Pr,0x16ff);
 	SiS_SetCH701x(SiS_Pr,0xac76);
@@ -9692,34 +9208,18 @@
   }
 }
 
-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);
-}
-
-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)
 {
      USHORT temp;
 
-     if(HwDeviceExtension->jChipType == SIS_740) {
-        temp = SiS_GetCH701x(SiS_Pr,0x4a);
+     if(HwInfo->jChipType == SIS_740) {
+
+        temp = SiS_GetCH701x(SiS_Pr,0x4a);  /* Version ID */
         temp &= 0x01;
-        if(!(temp)) {
+        if(!temp) {
 
-           if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+           if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo)) {
 	      temp = SiS_GetCH701x(SiS_Pr,0x49);
 	      SiS_SetCH701x(SiS_Pr,0x3e49);
 	   }
@@ -9728,13 +9228,14 @@
            SiS_LongDelay(SiS_Pr,1);
            SiS_SetCH701x(SiS_Pr,0x1848);
 
-	   if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-	      SiS_ChrontelDoSomething5(SiS_Pr);
+	   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);
@@ -9746,9 +9247,10 @@
 	   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
 	   temp = SiS_GetCH701x(SiS_Pr,0x61);
 	   if(!temp) {
-	      SiS_SetCH701xForLCD(SiS_Pr,HwDeviceExtension,BaseAddr);
+	      SiS_SetCH701xForLCD(SiS_Pr, HwInfo);
 	   }
         }
+
      } else { /* 650 */
         /* Reset Chrontel 7019 datapath */
         SiS_SetCH701x(SiS_Pr,0x1048);
@@ -9758,14 +9260,14 @@
 }
 
 void
-SiS_ChrontelDoSomething4(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
+SiS_ChrontelInitTVVSync(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
      USHORT temp;
 
-     if(HwDeviceExtension->jChipType == SIS_740) {
+     if(HwInfo->jChipType == SIS_740) {
 
-        if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-           SiS_ChrontelDoSomething5(SiS_Pr);
+        if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo)) {
+           SiS_ChrontelResetVSync(SiS_Pr);
         }
 
      } else {
@@ -9786,21 +9288,20 @@
      }
 }
 
-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)
 {
      USHORT temp,temp1;
 
-     if(HwDeviceExtension->jChipType == SIS_740) {
+     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);
-        SiS_SetCH701x(SiS_Pr,0xaf76);
+        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);
 
@@ -9818,7 +9319,7 @@
         temp |= 0x5f;
         SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
         if(ModeNo > 0x13) {
-           if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+           if(SiS_WeHaveBacklightCtrl(SiS_Pr, HwInfo)) {
 	      SiS_GenericDelay(SiS_Pr,0x3ff);
 	   } else {
 	      SiS_GenericDelay(SiS_Pr,0x2ff);
@@ -9838,8 +9339,8 @@
      }
 }
 
-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;
 
@@ -9849,43 +9350,43 @@
 
      do {
        temp = SiS_GetCH701x(SiS_Pr,0x66);
-       temp &= 0x04;
+       temp &= 0x04;  /* PLL stable? -> bail out */
        if(temp == 0x04) break;
-       
-       if(HwDeviceExtension->jChipType == SIS_740) {
+
+       if(HwInfo->jChipType == SIS_740) {
+          /* Power down LVDS output, PLL normal operation */
           SiS_SetCH701x(SiS_Pr,0xac76);
        }
 
-       SiS_SetCH701xForLCD(SiS_Pr,HwDeviceExtension,BaseAddr);
+       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);
-       if(HwDeviceExtension->jChipType == SIS_740) {
-          SiS_SetCH701x(SiS_Pr,0xe078);
+       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;
 
@@ -9893,66 +9394,314 @@
      temp |= 0x80;	/* Set datapath 1 to TV   */
      temp &= 0xbf;	/* Set datapath 2 to LVDS */
      SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x03);
-     
-     if(HwDeviceExtension->jChipType == SIS_740) {
+
+     if(HwInfo->jChipType == SIS_740) {
 
         temp = SiS_GetCH701x(SiS_Pr,0x1c);
-        temp &= 0xfb;
+        temp &= 0xfb;	/* Normal XCLK phase */
         SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c);
 
-        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2d,0x03);
+        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
 
         temp = SiS_GetCH701x(SiS_Pr,0x64);
-        temp |= 0x40;
+        temp |= 0x40;	/* ? Bit not defined */
         SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x64);
 
         temp = SiS_GetCH701x(SiS_Pr,0x03);
-        temp &= 0x3f;
+        temp &= 0x3f;	/* D1 input to both LVDS and TV */
         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(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 */
 
-        SiS_ChrontelResetDB(SiS_Pr,HwDeviceExtension,BaseAddr);
+        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_ChrontelDoSomething2(SiS_Pr,HwDeviceExtension,BaseAddr);
+     }
 
-        temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x34);
-        SiS_ChrontelDoSomething3(SiS_Pr,temp,HwDeviceExtension,BaseAddr);
+}
+#endif  /* 315 series  */
 
-        SiS_SetCH701x(SiS_Pr,0xaf76);
+/*********************************************/
+/*      MAIN: SET CRT2 REGISTER GROUP        */
+/*********************************************/
 
-     }
+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_Pr->SiS_SetFlag & LowModeTests) {
+      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) {
+      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 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_Pr->SiS_SetFlag & LowModeTests) {
+      SiS_SetGroup1(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
+   }
+
+   if(SiS_Pr->SiS_VBType & VB_SISVB) {
+
+        if(SiS_Pr->SiS_SetFlag & LowModeTests) {
+
+	   SiS_SetGroup2(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
+#ifdef SIS315H
+	   SiS_SetGroup2_C_ELV(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
+#endif
+      	   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_Pr->SiS_SetFlag & LowModeTests) {
+     	   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_Pr->SiS_SetFlag & LowModeTests) {
+	 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_Pr->SiS_SetFlag & LowModeTests) {
+	 if(HwInfo->jChipType < SIS_661) {
+	    SiS_FinalizeLCD(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
+            if(SiS_Pr->SiS_UseOEM) {
+               SiS_OEM310Setting(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
+            }
+	 } else {
+	    SiS_OEM661Setting(SiS_Pr, HwInfo, ModeNo, ModeIdIndex, RefreshRateTableIndex);
+	 }
+         SiS_CRT2AutoThreshold(SiS_Pr);
+      }
+   }
+#endif
+
+   if(SiS_Pr->SiS_SetFlag & LowModeTests) {
+      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_Pr->SiS_SetFlag & LowModeTests) {
+      SiS_LockCRT2(SiS_Pr,HwInfo);
+   }
+
+   return TRUE;
 }
 
-#endif  /* 315 series ------------------------------------ */
 
-/* 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);
+}
 
-/* Generic Read/write routines for Chrontel ========================== */
+/*********************************************/
+/*          DDC RELATED FUNCTIONS            */
+/*********************************************/
 
-/* 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;
 }
 
 /* Write to Chrontel 700x */
@@ -9960,59 +9709,22 @@
 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;		   /* 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;  	   /* DAB (Device Address Byte) */
-  }
-
-  for(i=0;i<10;i++) {	/* Do only 10 attempts to write */
-    /* SiS_SetSwitchDDC2(SiS_Pr); */
-    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 |= 0x80;                             /* (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;
+     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 */
   }
 
-  /* For 630ST */
-  if(!(SiS_Pr->SiS_ChrontelInit)) {
+  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;  	/* DAB (Device Address Byte) */
 
-     for(i=0;i<10;i++) {	/* Do only 10 attempts to write */
-       /* SiS_SetSwitchDDC2(SiS_Pr); */
-       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 |= 0x80;                          /* (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;
-    }
+     SiS_SetChReg(SiS_Pr, tempbx, 0x80);
   }
 }
 
@@ -10021,39 +9733,51 @@
 void
 SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempbx)
 {
-  USHORT tempah,temp,i;
-
   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;  		/* DAB (Device Address Byte) */
 
-  for(i=0;i<10;i++) {	/* Do only 10 attempts to write */
-    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;
-    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write RAB */
-    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 */
-    return;
-  }
+  SiS_SetChReg(SiS_Pr, tempbx, 0);
 }
-
-/* 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));
+      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;
 }
 
 /* Read from Chrontel 700x */
@@ -10061,65 +9785,29 @@
 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;		/* 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;		/* DAB */
   }
 
   SiS_Pr->SiS_DDC_ReadAddr = tempbx;
 
-  for(i=0;i<20;i++) {	/* Do only 20 attempts to read */
-    /* SiS_SetSwitchDDC2(SiS_Pr); */
-    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 | 0x80;	/* Write RAB | 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);
-  }
-
-  /* For 630ST */
-  if(!SiS_Pr->SiS_ChrontelInit) {
-     SiS_Pr->SiS_DDC_Index = 0x0a;		/* 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;  	/* DAB (Device Address Byte) */
+  if( ((result = SiS_GetChReg(SiS_Pr,0x80)) == 0xFFFF) &&
+      (!SiS_Pr->SiS_ChrontelInit) ) {
 
-     for(i=0;i<20;i++) {	/* Do only 20 attempts to read */
-       /* SiS_SetSwitchDDC2(SiS_Pr); */
-       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 | 0x80;	/* Write RAB | 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);
-     }
+     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);
 }
 
 /* Read from Chrontel 701x */
@@ -10127,32 +9815,26 @@
 USHORT
 SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempbx)
 {
-  USHORT tempah,temp,i;
-
   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;		/* DAB */
+
   SiS_Pr->SiS_DDC_ReadAddr = tempbx;
 
-   for(i=0;i<20;i++) {	/* Do only 20 attempts to read */
-    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;		/* Write RAB */
-    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 */
-    SiS_SetStop(SiS_Pr);			/* Stop condition */
-    return(tempah);
-   }
-  return 0xFFFF;
+  return(SiS_GetChReg(SiS_Pr,0));
+}
+
+/* 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 */
@@ -10179,7 +9861,7 @@
      SiS_Pr->SiS_DDC_Index = 0x11;
      flag = 0xff;
 
-     cr32 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x32);
+     cr32 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x32);
 
 #if 0
      if(VBFlags & VB_SISBRIDGE) {
@@ -10224,7 +9906,7 @@
      } else {						/* 315/330 series */
 
      	/* here we simplify: 0 = CRT1, 1 = CRT2 (VGA, LCD) */
-	
+
 	if(VBFlags & VB_SISBRIDGE) {
 	   if(myadaptnum == 2) {
 	      myadaptnum = 1;
@@ -10323,6 +10005,9 @@
     SiS_SetSwitchDDC2(SiS_Pr);
     if(SiS_PrepareDDC(SiS_Pr)) {
          SiS_SetStop(SiS_Pr);
+#ifdef TWDEBUG
+         xf86DrvMsg(0, X_INFO, "Probe: Prepare failed\n");
+#endif
          return(0xFFFF);
     }
     mask = 0xf0;
@@ -10336,6 +10021,9 @@
        } else {
            failed = TRUE;
 	   ret = 0xFFFF;
+#ifdef TWDEBUG
+           xf86DrvMsg(0, X_INFO, "Probe: Read 1 failed\n");
+#endif
        }
     }
     if(failed == FALSE) {
@@ -10345,6 +10033,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;
           }
@@ -10427,18 +10118,88 @@
 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((!(VBFlags & VB_VIDEOBRIDGE)) && (adaptnum > 0)) return 0xFFFF;
-   if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, TRUE) == 0xFFFF) return 0xFFFF;
+   if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, FALSE) == 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, 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
+
+static BOOLEAN
+checkedid1(unsigned char *buffer)
+{
+   /* Check header */
+   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))
+      return FALSE;
+
+   /* Check EDID version and revision */
+   if((buffer[0x12] != 1) || (buffer[0x13] > 4)) return FALSE;
+
+   /* Check week of manufacture for sanity */
+   if(buffer[0x10] > 53) return FALSE;
+
+   /* Check year of manufacture for sanity */
+   if(buffer[0x11] > 40) return FALSE;
+
+   return TRUE;
+}
+
+static BOOLEAN
+checkedid2(unsigned char *buffer)
+{
+   USHORT year = buffer[6] | (buffer[7] << 8);
+
+   /* Check EDID version */
+   if((buffer[0] & 0xf0) != 0x20) return FALSE;
+
+   /* Check week of manufacture for sanity */
+   if(buffer[5] > 53) return FALSE;
+
+   /* Check year of manufacture for sanity */
+   if((year != 0) && ((year < 1990) || (year > 2030))) return FALSE;
+
+   return TRUE;
+}
+
 /* Sense the LCD parameters (CR36, CR37) via DDC */
 /* SiS30x(B) only */
 USHORT
@@ -10464,7 +10225,7 @@
    
    /* Probe supported DA's */
    flag = SiS_ProbeDDC(SiS_Pr);
-#ifdef TWDEBUG   
+#ifdef TWDEBUG
    xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO,
    	"CRT2 DDC capabilities 0x%x\n", flag);
 #endif	
@@ -10483,17 +10244,17 @@
    retry = 2;
    do {
       if(SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer)) {
-         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO, 
-	 	"CRT2: DDC read failed (attempt %d), %s\n", 
+         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
+	 	"CRT2: DDC read failed (attempt %d), %s\n",
 		(3-retry), (retry == 1) ? "giving up" : "retrying");
 	 retry--;
 	 if(retry == 0) return 0xFFFF;
       } else break;
    } while(1);
-   
-#ifdef TWDEBUG   
+
+#ifdef TWDEBUG
    for(i=0; i<256; i+=16) {
-       xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO,
+       xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
        	"%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
 	buffer[i],    buffer[i+1], buffer[i+2], buffer[i+3],
 	buffer[i+4],  buffer[i+5], buffer[i+6], buffer[i+7],
@@ -10507,8 +10268,14 @@
    switch(DDCdatatype) {
    case 1:							/* Analyze EDID V1 */
       /* Catch a few clear cases: */
+      if(!(checkedid1(buffer))) {
+         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
+	 	"CRT2: EDID corrupt\n");
+	 return 0;
+      }
+
       if(!(buffer[0x14] & 0x80)) {
-         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED, 
+         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
 	        "CRT2: Attached display expects analog input (0x%02x)\n",
 		buffer[0x14]);
       	 return 0;
@@ -10565,9 +10332,13 @@
 		      paneltype = Panel310_1280x960;
 		   }
 	        } else if(yres == 768) {
-	       	   paneltype = Panel_1280x768;
-		   checkexpand = FALSE;
-		   cr37 |= 0x10;
+		   if( ((buffer[0x36] | (buffer[0x37] << 8)) == 8100) &&
+		       ((buffer[0x39] | ((buffer[0x3a] & 0x0f) << 8)) == (1688 - 1280)) &&
+		       ((buffer[0x3c] | ((buffer[0x3d] & 0x0f) << 8)) == (802 - 768)) ) {
+	       	      paneltype = Panel_1280x768;
+		      checkexpand = FALSE;
+		      cr37 |= 0x10;
+		   }
 	        }
 	        break;
 	    case 1400:
@@ -10597,6 +10368,7 @@
 	       /* What now? There is no digital separate output timing... */
 	       xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
 	       	   "CRT2: Unable to retrieve Sync polarity information\n");
+	       cr37 |= 0xc0;  /* Default */
 	    }
 	 }
 
@@ -10623,6 +10395,7 @@
 	 };
 
 	 paneltype = 0;
+	 SiS_Pr->CP_Supports64048075 = TRUE;
 
 	 /* Find the maximum resolution */
 
@@ -10678,20 +10451,21 @@
 	       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)) ) ||
+	       if((SiS_Pr->CP_HDisplay[i] & 7)						||
+	          (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] > 162500)) ||
+	           ((!(pSiS->VBFlags & VB_301C)) && (SiS_Pr->CP_Clock[i] > 108200)))	||
 		  (buffer[base+17] & 0x80)) {
 
 	          SiS_Pr->CP_DataValid[i] = FALSE;
@@ -10709,6 +10483,11 @@
 		  SiS_Pr->CP_Vendor = buffer[9] | (buffer[8] << 8);
 		  SiS_Pr->CP_Product = buffer[10] | (buffer[11] << 8);
 
+		  /* By default we drive the LCD at 75Hz in 640x480 mode; if
+		   * the panel does not provide this mode, use 60hz
+		   */
+		  if(!(buffer[0x23] & 0x04)) SiS_Pr->CP_Supports64048075 = FALSE;
+
 	          /* We must assume the panel can scale, since we have
 	           * no scaling data
 		   */
@@ -10755,6 +10534,13 @@
    case 3:							/* Analyze EDID V2 */
    case 4:
       index = 0;
+
+      if(!(checkedid2(buffer))) {
+         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
+	 	"CRT2: EDID corrupt\n");
+	 return 0;
+      }
+
       if((buffer[0x41] & 0x0f) == 0x03) {
          index = 0x42 + 3;
          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
@@ -10806,11 +10592,8 @@
 	     } else if(yres == 1024) {
 	     	paneltype = Panel_1280x1024;
 		checkexpand = TRUE;
-	     } else if(yres == 768) {
-	        paneltype = Panel_1280x768;
-		checkexpand = FALSE;
-		cr37 |= 0x10;
 	     }
+	     /* 1280x768 treated as custom here */
 	     break;
 	 case 1400:
 	     if(pSiS->VGAEngine == SIS_315_VGA) {
@@ -10849,7 +10632,7 @@
       if(buffer[0x7e] & 0x20) {			    /* skip Luminance Table (if provided) */
          lumsize = buffer[0x80] & 0x1f;
 	 if(buffer[0x80] & 0x80) lumsize *= 3;
-	 lumsize++;
+	 lumsize++;  /* luminance header byte */
 	 index += lumsize;
       }
       index += (((buffer[0x7e] & 0x1c) >> 2) * 8);   /* skip Frequency Ranges */
@@ -10875,9 +10658,12 @@
 
       /* Now seek the detailed timing descriptions for custom panels */
       if(paneltype == Panel_Custom) {
+
+         SiS_Pr->CP_Supports64048075 = TRUE;
+
          index += (numcodes * 4);
 	 numcodes = buffer[0x7f] & 0x07;
-	 for(i=0; i<numcodes; i++) {
+	 for(i=0; i<numcodes; i++, index += 18) {
 	    xres = buffer[index+2] | ((buffer[index+4] & 0xf0) << 4);
             yres = buffer[index+5] | ((buffer[index+7] & 0xf0) << 4);
 
@@ -10899,20 +10685,21 @@
 
 	    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)) ) ||
+	    if((SiS_Pr->CP_HDisplay[i] & 7)						||
+	       (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] > 162500)) ||
+	        ((!(pSiS->VBFlags & VB_301C)) && (SiS_Pr->CP_Clock[i] > 108200)))	||
 	       (buffer[index + 17] & 0x80)) {
 
 	       SiS_Pr->CP_DataValid[i] = FALSE;
@@ -10968,7 +10755,7 @@
          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 Display section\n",
+	    "   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]);
       }
@@ -10978,11 +10765,10 @@
        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_SetRegANDOR(SiS_Pr->SiS_P3d4,0x37,0xf1,cr37);
        SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x32,0x08);
-#ifdef TWDEBUG       
+#ifdef TWDEBUG
        xf86DrvMsgVerb(pSiS->pScrn->scrnIndex, X_PROBED, 3, 
        	"CRT2: [DDC LCD results: 0x%02x, 0x%02x]\n", paneltype, cr37);
 #endif	
@@ -10999,8 +10785,7 @@
    unsigned char buffer[256];
 
    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->VBFlags, pSiS->VGAEngine, 2, 0, FALSE) == 0xFFFF) return 0;
    
    SiS_Pr->SiS_DDC_SecAddr = 0x00;
@@ -11017,16 +10802,16 @@
       SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;	/* EDID V1 */
       DDCdatatype = 1;
    } else {
-   	xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO, 
+   	xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
 		"Do DDC answer\n");
    	return 0;				/* no DDC support (or no device attached) */
    }
-   
+
    /* Read the entire EDID */
    retry = 2;
    do {
       if(SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer)) {
-         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO, 
+         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
 	 	"CRT2: DDC read failed (attempt %d), %s\n", 
 		(3-retry), (retry == 1) ? "giving up" : "retrying");
 	 retry--;
@@ -11039,10 +10824,15 @@
     */
    switch(DDCdatatype) {
    case 1:
+      if(!(checkedid1(buffer))) {
+          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
+	  	"CRT2: EDID corrupt\n");
+      	  return 0;
+      }
       if(buffer[0x14] & 0x80) {			/* Display uses digital input */
           xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
 	  	"CRT2: Attached display expects digital input\n");
-      	  return 0;  	
+      	  return 0;
       }
       SiS_Pr->CP_Vendor = buffer[9] | (buffer[8] << 8);
       SiS_Pr->CP_Product = buffer[10] | (buffer[11] << 8);
@@ -11050,6 +10840,11 @@
       break;
    case 3:
    case 4:
+      if(!(checkedid2(buffer))) {
+          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
+	  	"CRT2: EDID corrupt\n");
+      	  return 0;
+      }
       if( ((buffer[0x41] & 0x0f) != 0x01) &&  	/* Display does not support analog input */
           ((buffer[0x41] & 0x0f) != 0x02) &&
 	  ((buffer[0x41] & 0xf0) != 0x10) &&
@@ -11071,37 +10866,6 @@
    return(0);
 }
 
-/* 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;
-}
-
-void
-SiS_I2C_Stop(SiS_Private *SiS_Pr)
-{
-   SiS_SetStop(SiS_Pr);
-}
-#endif
-
 #endif
 
 void
@@ -11114,18 +10878,23 @@
   SiS_SetCH70xx(SiS_Pr,tempbl);
 }
 
-/* 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);
 }
 
 /* Set I2C start condition */
@@ -11164,8 +10933,8 @@
 {
   USHORT i,flag,temp;
 
-  flag=0x80;
-  for(i=0;i<8;i++) {
+  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,
@@ -11193,7 +10962,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);
@@ -11211,33 +10980,23 @@
 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);
-  }
-}
-
 /* Check I2C acknowledge */
 /* Returns 0 if ack ok, non-0 if ack not ok */
 USHORT
@@ -11249,7 +11008,7 @@
   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
                   ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data);     /* (SD->high) */
   SiS_SetSCLKHigh(SiS_Pr);				           /* SC->high = clock impulse for ack */
-  tempah = SiS_GetReg1(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);/* Read SD */
+  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);
@@ -11263,11 +11022,12 @@
 #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) {
+  if(HwInfo->jChipType < SIS_330) {
      romptr = ROMAddr[0x128] | (ROMAddr[0x129] << 8);
      if(SiS_Pr->SiS_VBType & VB_SIS301B302B)
         romptr = ROMAddr[0x12a] | (ROMAddr[0x12b] << 8);
@@ -11280,11 +11040,12 @@
 }
 
 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) {
+  if(HwInfo->jChipType < SIS_330) {
      romptr = ROMAddr[0x120] | (ROMAddr[0x121] << 8);
      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
         romptr = ROMAddr[0x122] | (ROMAddr[0x123] << 8);
@@ -11297,11 +11058,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);
@@ -11314,13 +11076,13 @@
 }
 
 static USHORT
-GetLCDPtrIndexBIOS(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
+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,HwDeviceExtension, BaseAddr))) {
-        if((index = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0xf0)) {
+     if(!(SiS_IsNotM650orLater(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;
@@ -11354,45 +11116,80 @@
   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)
 {
   USHORT index;
 
   index = 0;
-  if(SiS_Pr->SiS_VBInfo & SetPALTV) index++;
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) index++;  /* Hivision TV use PAL */
+  if(SiS_Pr->SiS_TVMode & TVSetPAL) index++;
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index++;  /* HiVision uses PAL */
 
   index <<= 1;
 
-  if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (SiS_Pr->SiS_SetFlag & TVSimuMode))
-    index++;
+  if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) &&
+     (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
+     index++;
+  }
 
   return index;
 }
 
+static ULONG
+GetOEMTVPtr661_2(SiS_Private *SiS_Pr)
+{
+   USHORT index = 0, temp = 0;
+
+   if(SiS_Pr->SiS_TVMode & TVSetPAL)   index = 1;
+   if(SiS_Pr->SiS_TVMode & TVSetPALM)  index = 2;
+   if(SiS_Pr->SiS_TVMode & TVSetPALN)  index = 3;
+   if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 6;
+   if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
+      index = 4;
+      if(SiS_Pr->SiS_TVMode & TVSetPALM)  index++;
+      if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 7;
+   }
+
+   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+      if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+         (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
+	 index += 8;
+	 temp++;
+      }
+      temp += 0x0100;
+   }
+   return(ULONG)(index | (temp << 16));
+}
+
+static int
+GetOEMTVPtr661(SiS_Private *SiS_Pr)
+{
+   int index = 0;
+
+   if(SiS_Pr->SiS_TVMode & TVSetPAL)       index = 2;
+   if(SiS_Pr->SiS_TVMode & TVSetHiVision)  index = 4;
+   if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 6;
+   if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 8;
+   if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 10;
+
+   if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) index++;
+
+   return index;
+}
+
 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)
 {
+  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
   USHORT delay=0,index,myindex,temp,romptr=0;
   BOOLEAN dochiptest = TRUE;
 
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {			/* VGA */
+  /* 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 {
@@ -11402,166 +11199,247 @@
 	      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;
 	   }
 	}
-        if(SiS_Pr->SiS_IF_DEF_LVDS == 1)
+        if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
            delay = 0x00;
+	}
      }
 
-  } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {		/* LCD */
+  } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD|SetCRT2ToLCDA)) {  /* ----------	LCD/LCDA */
 
      BOOLEAN gotitfrompci = FALSE;
 
      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return;
 
-     if(HwDeviceExtension->pdc) return;
+     /* Could we detect a PDC for LCD? If yes, use it */
+
+     if(SiS_Pr->PDC) {
+        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((SiS_Pr->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.
+      * delay into the code, at no defined place in the BIOS.
       * We now have to start doing a PCI subsystem check here.
       */
 
-     if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
+     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;
 	}
-     }
-
-     if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) ||
-        (SiS_Pr->SiS_CustomT == CUT_CLEVO10242)) {
+	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_SetReg1(SiS_Pr->SiS_Part1Port,0x2D,delay);
+	   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, HwDeviceExtension, BaseAddr);
+        index = GetLCDPtrIndexBIOS(SiS_Pr, HwInfo);
         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(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
+
+           if(SiS_IsNotM650orLater(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];
+	         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)
+	     if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV))
 	        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);
-	      if(!romptr) return;
-	      delay = ROMAddr[(romptr + index)];
-           } 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_SIS550650740660) {
-	            delay = SiS310_LCDDelayCompensation_650301B[myindex];
-	         } else {
+
+        } 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 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_SIS550650740660) {
+	         delay = SiS310_LCDDelayCompensation_650301B[myindex];
+	      } else {
 #endif
-                    delay = SiS310_LCDDelayCompensation_3xx301B[myindex];
+                 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];
-	         }
 	      }
-           }
+#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(SiS_IsNotM650orLater(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];
+	      if(SiS_Pr->SiS_VBType & VB_SIS302LV)
+	         delay = SiS310_TVDelayCompensation_301B[index];
 #endif		
-	  }
-       } else {
-          switch(SiS_Pr->SiS_CustomT) {
-	  case CUT_COMPAQ1280:
-	     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 {
+
+           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_VBType & VB_SISVB) {
+
+     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 (COMPAL) */
+	   delay &= 0x0f;
+	   delay |= 0xb0;
+        } else if(temp == 6) {
+           delay &= 0x0f;
+	   delay |= 0xc0;
+        } else if(temp > 7) {	/* 1280x1024 BIOS (which one?) */
+	   delay = 0x35;
+        }
+        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
+
+     } else {
+
+        SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
+
      }
-    
-  }
 
-  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+  } else {  /* LVDS */
+
      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
      } else {
@@ -11572,49 +11450,44 @@
            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
         }
      }
-  } else {
-     if(dochiptest && IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
-        temp = (SiS_GetReg1(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);
-     } 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)
 {
-  USHORT index,temp,romptr=0;
+  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
+  USHORT index,temp,temp1,romptr=0;
 
-  temp = GetTVPtrIndex(SiS_Pr);
-  temp >>= 1;  	  /* 0: NTSC, 1: PAL, 2: HiTV */
+  if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p|TVSetYPbPr525p)) return;
 
   if(ModeNo<=0x13)
      index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex;
   else
      index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex;
 
+  temp = GetTVPtrIndex(SiS_Pr);
+  temp >>= 1;  	  /* 0: NTSC, 1: PAL, 2: HiTV */
+  temp1 = temp;
+
   if(ROMAddr && SiS_Pr->SiS_UseROM) {
-     romptr = ROMAddr[0x112] | (ROMAddr[0x113] << 8);
-     if(HwDeviceExtension->jChipType >= SIS_330) {
+     if(HwInfo->jChipType >= SIS_661) {
+	romptr = ROMAddr[0x260] | (ROMAddr[0x261] << 8);
+	temp1 = GetOEMTVPtr661(SiS_Pr);
+        temp1 >>= 1;
+     } else if(HwInfo->jChipType >= SIS_330) {
         romptr = ROMAddr[0x192] | (ROMAddr[0x193] << 8);
+     } else {
+        romptr = ROMAddr[0x112] | (ROMAddr[0x113] << 8);
      }
   }
 
   if(romptr) {
-     temp <<= 1;
-     temp = ROMAddr[romptr + temp + index];
+     temp1 <<= 1;
+     temp = ROMAddr[romptr + temp1 + index];
   } else {
      temp = SiS310_TVAntiFlick1[temp][index];
   }
@@ -11624,13 +11497,15 @@
 }
 
 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)
 {
-  USHORT index,temp,romptr=0;
+  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
+  USHORT index,temp,temp1,romptr=0;
 
   temp = GetTVPtrIndex(SiS_Pr);
   temp >>= 1;              	/* 0: NTSC, 1: PAL, 2: HiTV */
+  temp1 = temp;
 
   if(ModeNo<=0x13)
      index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;
@@ -11638,15 +11513,20 @@
      index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;
 
   if(ROMAddr && SiS_Pr->SiS_UseROM) {
-     romptr = ROMAddr[0x124] | (ROMAddr[0x125] << 8);
-     if(HwDeviceExtension->jChipType >= SIS_330) {
+     if(HwInfo->jChipType >= SIS_661) {
+	romptr = ROMAddr[0x26c] | (ROMAddr[0x26d] << 8);
+	temp1 = GetOEMTVPtr661(SiS_Pr);
+        temp1 >>= 1;
+     } else if(HwInfo->jChipType >= SIS_330) {
         romptr = ROMAddr[0x1a4] | (ROMAddr[0x1a5] << 8);
+     } else {
+        romptr = ROMAddr[0x124] | (ROMAddr[0x125] << 8);
      }
   }
 
   if(romptr) {
-     temp <<= 1;
-     temp = ROMAddr[romptr + temp + index];
+     temp1 <<= 1;
+     temp = ROMAddr[romptr + temp1 + index];
   } else {
      temp = SiS310_TVEdge1[temp][index];
   }
@@ -11655,90 +11535,119 @@
 }
 
 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)
 {
-  USHORT index, temp, i, j;
-  UCHAR  OutputSelect = *SiS_Pr->pSiS_OutputSelect;
-
-  temp = GetTVPtrIndex(SiS_Pr);
-  temp >>= 1;  			/* 0: NTSC, 1: PAL, 2: HiTV */
+  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
+  USHORT index, myindex, oldindex,temp, i, j, flag1 = 0, flag2 = 0, romptr = 0;
+  ULONG  lindex;
 
-  if (ModeNo<=0x13) {
+  if(ModeNo<=0x13) {
     index =  SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
   } else {
     index =  SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
   }
 
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV)  temp = 1;  /* Hivision TV uses PAL */
-
-  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]);
-    }
-    for(i=0x48; i<=0x4A; i++, j++) {
-       SiS_SetReg1(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]);
-    }
-  }
+  oldindex = index;
 
-  if(ROMAddr && SiS_Pr->SiS_UseROM) {
-  	OutputSelect = ROMAddr[0xf3];
-	if(HwDeviceExtension->jChipType >= SIS_330) {
-	    OutputSelect = ROMAddr[0x11b];
+  if((HwInfo->jChipType >= SIS_661) && ROMAddr && SiS_Pr->SiS_UseROM) {
+     if(ModeNo > 0x13) {
+        index =  SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndexROM661;
+     }
+     lindex = GetOEMTVPtr661_2(SiS_Pr);
+     if(lindex & 0x00ff0000) flag1 = 1;
+     if(lindex & 0xff000000) flag2 = 1;
+     lindex &= 0xffff;
+
+     /* NTSC-J: Use PAL filters */
+     if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) lindex = 1;
+
+     romptr = ROMAddr[0x268] | (ROMAddr[0x269] << 8);
+     if(flag1) myindex = index * 7;
+     else      myindex = index << 2;
+
+     if(romptr) {
+        romptr += (lindex << 1);
+        romptr = (ROMAddr[romptr] | (ROMAddr[romptr+1] << 8)) + myindex;
+	if(romptr) {
+           if((!flag1) && (flag2)) {
+	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x35,0x00);
+	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x36,0x00);
+	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x37,0x00);
+	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x38,ROMAddr[romptr++]);
+           } else {
+	      for(i=0x35; i<=0x38; i++) {
+                 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr++]);
+              }
+           }
+           if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+	      for(j=0, i=0x48; i<=0x4a; i++, j++) {
+                 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr++]);
+              }
+           }
+           return;
 	}
+     }
   }
-  if(OutputSelect & EnablePALMN) {
-      if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
-         temp = SiS_GetReg1(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]);
-                 }
-                 for(i=0x48; i<=0x4A; i++, j++) {
-                      SiS_SetReg1(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]);
-                 }
-              }
-         }
-	 /* 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]);
-                 }
-                 for(i=0x48, j=0; i<=0x4A; i++, j++) {
-                      SiS_SetReg1(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]);
-		 }
-             }
-         }
-      }
+
+  index = oldindex;
+
+  temp = GetTVPtrIndex(SiS_Pr);
+  temp >>= 1;  			/* 0: NTSC, 1: PAL, 2: HiTV */
+
+  if(SiS_Pr->SiS_TVMode & TVSetNTSCJ)	     temp = 1;  /* NTSC-J uses PAL */
+  else if(SiS_Pr->SiS_TVMode & TVSetPALM)    temp = 3;  /* PAL-M */
+  else if(SiS_Pr->SiS_TVMode & TVSetPALN)    temp = 4;  /* PAL-N */
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp = 1;  /* HiVision uses PAL */
+
+  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+     for(i=0x35, j=0; i<=0x38; i++, j++) {
+        SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
+     }
+     for(i=0x48; i<=0x4A; i++, j++) {
+        SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
+     }
+  } else {
+     for(i=0x35, j=0; i<=0x38; i++, j++) {
+        SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter1[temp][index][j]);
+     }
   }
 }
 
 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)
 {
-  USHORT index,temp,temp1,i,j,resinfo,romptr=0;
+  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
+  USHORT index,temp,i,j,resinfo,romptr=0;
+  ULONG  lindex;
 
   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
 
-  temp1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);        /* if PALM/N not set */
-  temp1 &= (EnablePALM | EnablePALN);
-  if(temp1) return;
+  /* NTSC-J data not in BIOS, and already set in SetGroup2 */
+  if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) return;
+
+  if(HwInfo->jChipType >= SIS_661) {
+     lindex = GetOEMTVPtr661_2(SiS_Pr) & 0xffff;
+     lindex <<= 2;
+     if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+        romptr = ROMAddr[0x264] | (ROMAddr[0x265] << 8);
+     }
+     if(romptr) {
+	romptr += lindex;
+	for(j=0, i=0x31; i<=0x34; i++, j++) {
+           SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
+        }
+     } else {
+        for(j=0, i=0x31; i<=0x34; i++, j++) {
+           SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS661_TVPhase[lindex + j]);
+        }
+     }
+     return;
+  }
+
+  /* PAL-M, PAL-N not in BIOS, and already set in SetGroup2 */
+  if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) return;
 
   if(ModeNo<=0x13) {
      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
@@ -11752,17 +11661,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))) {
+	if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode))) {
 	   romptr = ROMAddr[0x116] | (ROMAddr[0x117] << 8);
-	   if(HwDeviceExtension->jChipType >= SIS_330) {
+	   if(HwInfo->jChipType >= SIS_330) {
               romptr = ROMAddr[0x196] | (ROMAddr[0x197] << 8);
            }
 	}
@@ -11771,61 +11680,204 @@
   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]);
-        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_TVPhaseIncr1[temp][index][j]);
+        else if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || (SiS_Pr->SiS_TVMode & TVSetTVSimuMode))
+           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) {    /* 650/301LV: (VB_SIS301LV | VB_SIS302LV)) */
-     if((!(SiS_Pr->SiS_VBInfo & SetPALTV)) && (ModeNo > 0x13)) {
-        if(resinfo == SIS_RI_640x480) {
-	      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 == SIS_RI_800x600) {
-	      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);
+  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+     if((!(SiS_Pr->SiS_TVMode & TVSetPAL)) && (ModeNo > 0x13)) {
+        if((resinfo == SIS_RI_640x480) ||
+	   (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_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);
+	      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);
+   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);
+   if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
+       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);
        }
    }
 }
 
+static void
+SetDelayComp661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo,
+                USHORT ModeIdIndex, USHORT RTI)
+{
+   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
+   USHORT delay = 0, romptr = 0, index;
+   UCHAR  *myptr = NULL;
+   UCHAR  temp;
+
+   if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToRAMDAC)))
+      return;
+
+   delay = SiS_Pr->SiS_RefIndex[RTI].Ext_PDC;
+
+   delay &= 0xf0;
+   delay >>= 4;
+   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) delay <<= 12;  /* BIOS: 8, wrong */
+
+   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+      index = GetOEMTVPtr661(SiS_Pr);
+      if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+         romptr = ROMAddr[0x25c] | (ROMAddr[0x25d] << 8);
+         if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+            romptr = ROMAddr[0x25e] | (ROMAddr[0x25f] << 8);
+         }
+      }
+      if(romptr) myptr = &ROMAddr[romptr];
+      if(!myptr) {
+         myptr = (UCHAR *)SiS_TVDelay661_301;
+	 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+	    myptr = (UCHAR *)SiS_TVDelay661_301B;
+	 }
+      }
+      delay = myptr[index];
+      if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) delay >>= 4;  /* Should test dual edge */
+   } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+      if(SiS_Pr->PDC) {
+         delay = SiS_Pr->PDC & 0x0f;
+	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+            delay |= (delay << 12);
+         }
+      } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) {
+         delay = 0x4444;  /* TEST THIS */
+      } else if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
+         myptr = GetLCDStructPtr661(SiS_Pr, HwInfo);
+         if(myptr) delay = myptr[4];
+         else delay = 0x44;
+         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+            delay |= (delay << 8);
+         }
+      }
+   }
+
+   temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2d);
+   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToRAMDAC)) {
+      temp &= 0xf0;
+      temp |= (delay & 0x000f);
+   }
+   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+      temp &= 0x0f;
+      temp |= ((delay & 0xf000) >> 8);
+   }
+   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,temp);
+}
+
+static void
+SetCRT2SyncDither661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo, USHORT RTI)
+{
+   USHORT infoflag;
+   UCHAR temp;
+
+   infoflag = SiS_Pr->SiS_RefIndex[RTI].Ext_InfoFlag;
+   if(ModeNo <= 0x13) {
+      infoflag = SiS_GetRegByte(SiS_Pr->SiS_P3ca+2);
+   }
+   infoflag &= 0xc0;
+   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+      temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
+      if(temp & 0x20) infoflag = temp;
+      if(temp & 0x01) infoflag |= 0x01;
+   }
+   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+      temp = 0x0c;
+      if(infoflag & 0x01) temp ^= 0x14;  /* BIOS: 18, wrong */
+      temp |= (infoflag >> 6);
+      SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xe0,temp);
+   }
+   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+      temp = 0;
+      if(infoflag & 0x01) temp |= 0x80;
+      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0x7f,temp);
+      temp = 0x30;
+      if(infoflag & 0x01) temp = 0x20;
+      infoflag &= 0xc0;
+      temp |= infoflag;
+      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0f,temp);
+   }
+}
+
+static void
+SetPanelParms661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+   UCHAR *myptr;
+
+   if(SiS_Pr->SiS_VBType & (VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV)) {
+      if(SiS_Pr->LVDSHL != -1) {
+         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
+      }
+   }
+
+   myptr = GetLCDStructPtr661(SiS_Pr, HwInfo);
+   if(myptr) {
+      if(SiS_Pr->SiS_VBType & (VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV)) {
+         if(SiS_Pr->LVDSHL == -1) {
+            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xE0,myptr[1] & 0x1f);
+	 } else {
+	    SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xE3,myptr[1] & 0x1c);
+	 }
+      }
+      SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0d,0x3f,myptr[2] & 0xc0);
+   }
+}
+
+void
+SiS_OEM661Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+                  USHORT ModeNo,USHORT ModeIdIndex, USHORT RRTI)
+{
+   if(SiS_Pr->SiS_VBType & VB_SISVB) {
+
+      SetDelayComp661(SiS_Pr,HwInfo,ModeNo,ModeIdIndex,RRTI);
+
+      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+         SetCRT2SyncDither661(SiS_Pr,HwInfo,ModeNo,RRTI);
+         SetPanelParms661(SiS_Pr,HwInfo);
+      }
+
+      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+         SetPhaseIncr(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
+         SetYFilter(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
+         SetAntiFlicker(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
+         if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
+            SetEdgeEnhance(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
+         }
+      }
+   }
+}
+
 /* FinalizeLCD
  * This finalizes some CRT2 registers for the very panel used.
  * If we have a backup if these registers, we use it; otherwise
@@ -11834,8 +11886,8 @@
  * 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;
@@ -11851,18 +11903,24 @@
   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return;
   if(SiS_Pr->UseCustomMode) return;
 
-  if(SiS_Pr->SiS_CustomT == CUT_COMPAQ12802) 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_GetReg1(SiS_Pr->SiS_P3d4, 0x5f) & 0xf0)) {
+     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 {
@@ -11872,7 +11930,8 @@
   }
 
   if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
-     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {  /* Maybe all panels? */
+     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);
 	}
@@ -11882,17 +11941,18 @@
 
   if(SiS_Pr->SiS_CustomT == CUT_CLEVO10242) {
      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
-        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {  /* Maybe all panels? */
+        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_GetReg1(SiS_Pr->SiS_P3d4,0x36) >> 4;
+	      tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
 	      if(tempch == 3) {
-	         SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x02);
-	         SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1b,0x25);
-	         SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1c,0x00);
-	         SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
+	         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;
@@ -11902,128 +11962,122 @@
 
   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);
-     } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {   /* Maybe all panels? */
+#ifdef SET_EMI
+	if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
+	   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_GetReg1(SiS_Pr->SiS_P3d4,0x36);
-     tempch &= 0xf0;
-     tempch >>= 4;
+     tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
-        if(tempch == 0x03) {
-	   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x02);
-	   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1b,0x25);
-	   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1c,0x00);
-	   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
-	}
 	if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
-	   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1f,0x76);
+	   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 == SIS_RI_1024x768)) {
-	          SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x02);  /* 1.10.7u */
+	      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_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;
-			 }
-		     }
-		  }
-	       }
+	         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 == 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);
      }
   }
@@ -12031,25 +12085,24 @@
 
 #endif
 
-
 /*  =================  SiS 300 O.E.M. ================== */
 
 #ifdef SIS300
 
 void
-SetOEMLCDData2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
-              UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, USHORT RefTabIndex)
+SetOEMLCDData2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+               USHORT ModeNo,USHORT ModeIdIndex, USHORT RefTabIndex)
 {
   USHORT crt2crtc=0, modeflag, myindex=0;
   UCHAR  temp;
   int i;
 
   if(ModeNo <= 0x13) {
-        modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-	crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+     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;
+     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+     crt2crtc = SiS_Pr->SiS_RefIndex[RefTabIndex].Ext_CRT2CRTC;
   }
 
   crt2crtc &= 0x3f;
@@ -12061,7 +12114,7 @@
   if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
      if(modeflag & HalfDCLK) myindex = 1;
 
-     if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
+     if(SiS_Pr->SiS_SetFlag & LowModeTests) {
         for(i=0; i<7; i++) {
            if(barco_p1[myindex][crt2crtc][i][0]) {
 	      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,
@@ -12071,46 +12124,19 @@
 	   }
         }
      }
-     temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00);
+     temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
      if(temp & 0x80) {
-        temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x18);
+        temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x18);
         temp++;
-        SiS_SetReg1(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)
-{
-   ULONG temp1;
-#ifndef LINUX_XF86
-   ULONG base;
-#endif
-   USHORT temp2 = 0;
-
-   if((HwDeviceExtension->jChipType==SIS_540)||
-      (HwDeviceExtension->jChipType==SIS_630)||
-      (HwDeviceExtension->jChipType==SIS_730)) {
-#ifndef LINUX_XF86
-     	base = 0x80000008;
-     	OutPortLong(base,0xcf8);
-     	temp1 = InPortLong(0xcfc);
-#else
-	temp1=pciReadLong(0x00000000, 0x08);
-#endif
-     	temp1 &= 0x000000FF;
-     	temp2 = (USHORT)(temp1);
-    	return temp2;
-   }
-   return 0;
-}
-#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,
@@ -12121,9 +12147,9 @@
 	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
   };
 
-  if(HwDeviceExtension->jChipType == SIS_300) {
+  if(HwInfo->jChipType == SIS_300) {
 
-    tempbx = (SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0x0f) - 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;
@@ -12132,13 +12158,13 @@
        if(ROMAddr[0x235] & 0x80) {
           tempbx = SiS_Pr->SiS_LCDTypeInfo;
           if(Flag) {
-	    romptr = ROMAddr[0x255] | (ROMAddr[0x256] << 8);
-	    if(romptr) {
+	     romptr = ROMAddr[0x255] | (ROMAddr[0x256] << 8);
+	     if(romptr) {
 	        tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
-	    } else {
+	     } else {
 	        tempbx = customtable300[SiS_Pr->SiS_LCDTypeInfo];
-	    }
-            if(tempbx == 0xFF) return 0xFFFF;
+	     }
+             if(tempbx == 0xFF) return 0xFFFF;
           }
 	  tempbx <<= 1;
 	  if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
@@ -12148,21 +12174,21 @@
   } else {
 
     if(Flag) {
-      if((ROMAddr) && SiS_Pr->SiS_UseROM) {
-         romptr = ROMAddr[0x255] | (ROMAddr[0x256] << 8);
-	 if(romptr) {
-	    tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
-	 } else {
-	    tempbx = 0xff;
-	 }
-      } else {
-         tempbx = customtable630[SiS_Pr->SiS_LCDTypeInfo];
-      }
-      if(tempbx == 0xFF) return 0xFFFF;
-      tempbx <<= 2;
-      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
-      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
-      return tempbx;
+       if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+          romptr = ROMAddr[0x255] | (ROMAddr[0x256] << 8);
+	  if(romptr) {
+	     tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
+	  } else {
+	     tempbx = 0xff;
+	  }
+       } else {
+          tempbx = customtable630[SiS_Pr->SiS_LCDTypeInfo];
+       }
+       if(tempbx == 0xFF) return 0xFFFF;
+       tempbx <<= 2;
+       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
+       if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
+       return tempbx;
     }
     tempbx = SiS_Pr->SiS_LCDTypeInfo << 2;
     if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
@@ -12172,9 +12198,10 @@
 }
 
 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;
@@ -12192,63 +12219,64 @@
    * 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(SiS_Pr->PDC) return;
 
-  temp = GetOEMLCDPtr(SiS_Pr,HwDeviceExtension, ROMAddr, 0);
+  temp = GetOEMLCDPtr(SiS_Pr,HwInfo, 0);
 
   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);
+	romptr += index;
+	temp = ROMAddr[romptr];
+     } else {
+	if(SiS_Pr->SiS_VBType & VB_SISVB) {
+    	   temp = SiS300_OEMLCDDelay2[temp][index];
+	} else {
+           temp = SiS300_OEMLCDDelay3[temp][index];
+        }
+     }
+  } else {
+     if((ROMAddr) && SiS_Pr->SiS_UseROM && (ROMAddr[0x235] & 0x80)) {
 	if(romptr) {
 	   romptr += (temp * 2);
 	   romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8);
 	   romptr += index;
 	   temp = ROMAddr[romptr];
 	} else {
-	   if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
-    	      temp = SiS300_OEMLCDDelay2[temp][index];
+	   temp = SiS300_OEMLCDDelay5[temp][index];
+	}
+     } else {
+        if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+	   romptr = ROMAddr[0x249] | (ROMAddr[0x24a] << 8);
+	   if(romptr) {
+	      romptr += (temp * 2);
+	      romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8);
+	      romptr += index;
+	      temp = ROMAddr[romptr];
 	   } else {
-              temp = SiS300_OEMLCDDelay3[temp][index];
-           }
+	      temp = SiS300_OEMLCDDelay4[temp][index];
+	   }
+	} else {
+	   temp = SiS300_OEMLCDDelay4[temp][index];
 	}
-  } else {
-      if((ROMAddr) && SiS_Pr->SiS_UseROM && (ROMAddr[0x235] & 0x80)) {
-	  if(romptr) {
-	     romptr += (temp * 2);
-	     romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8);
-	     romptr += index;
-	     temp = ROMAddr[romptr];
-	  } else {
-	     temp = SiS300_OEMLCDDelay5[temp][index];
-	  }
-      } else {
-          if((ROMAddr) && SiS_Pr->SiS_UseROM) {
-	     romptr = ROMAddr[0x249] | (ROMAddr[0x24a] << 8);
-	     if(romptr) {
-	        romptr += (temp * 2);
-	        romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8);
-	        romptr += index;
-	        temp = ROMAddr[romptr];
-	     } else {
-	        temp = SiS300_OEMLCDDelay4[temp][index];
-	     }
-	  } else {
-	     temp = SiS300_OEMLCDDelay4[temp][index];
-	  }
-      }
+     }
   }
   temp &= 0x3c;
   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);  /* index 0A D[6:4] */
 }
 
 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  /* Unfinished; Data table missing */
+  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
   USHORT index,temp;
 
   if((ROMAddr) && SiS_Pr->SiS_UseROM) {
@@ -12257,21 +12285,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
 }
@@ -12283,21 +12311,22 @@
 
   index = 0;
   if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))  index += 4;
-  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+  if(SiS_Pr->SiS_VBType & VB_SISVB) {
      if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART)  index += 2;
-     else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) index += 3;
-     else if(SiS_Pr->SiS_VBInfo & SetPALTV)   index += 1;
+     else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index += 3;
+     else if(SiS_Pr->SiS_TVMode & TVSetPAL)   index += 1;
   } else {
-     if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) index += 2;
-     if(SiS_Pr->SiS_VBInfo & SetPALTV)        index += 1;
+     if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) index += 2;
+     if(SiS_Pr->SiS_TVMode & TVSetPAL)        index += 1;
   }
   return index;
 }
 
 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) {
@@ -12316,7 +12345,7 @@
      romptr += index;
      temp = ROMAddr[romptr];
   } else {
-     if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+     if(SiS_Pr->SiS_VBType & VB_SISVB) {
         temp = SiS300_OEMTVDelay301[temp][index];
      } else {
         temp = SiS300_OEMTVDelayLVDS[temp][index];
@@ -12327,10 +12356,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) {
@@ -12356,12 +12385,15 @@
 }
 
 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;
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) return;
+
+  if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetNTSCJ | TVSetPALM | TVSetPALN)) return;
 
   if((ROMAddr) && SiS_Pr->SiS_UseROM) {
      if(!(ROMAddr[0x238] & 0x01)) return;
@@ -12374,32 +12406,33 @@
   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVPhaseIndex;
 
   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]);
-       }
+     for(i=0x31, j=0; i<=0x34; i++, j++) {
+        SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase2[temp][index][j]);
+     }
   } else {
-       if(romptr) {
-          romptr += (temp * 2);
-	  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]);
-	  }
-       } else {
-          for(i=0x31, j=0; i<=0x34; i++, j++) {
-             SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS300_Phase1[temp][index][j]);
-	  }
-       }
+     if(romptr) {
+        romptr += (temp * 2);
+	romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8);
+	romptr += (index * 4);
+        for(i=0x31, j=0; i<=0x34; i++, j++) {
+	   SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
+	}
+     } else {
+        for(i=0x31, j=0; i<=0x34; i++, 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)
 {
-  USHORT index,temp,temp1,i,j,romptr=0;
+  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
+  USHORT index,temp,i,j,romptr=0;
 
-  if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSCART | SetCRT2ToHiVisionTV)) return;
+  if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSCART | SetCRT2ToHiVision | SetCRT2ToYPbPr525750)) return;
 
   if((ROMAddr) && SiS_Pr->SiS_UseROM) {
      if(!(ROMAddr[0x238] & 0x01)) return;
@@ -12409,66 +12442,84 @@
 
   temp = GetOEMTVPtr(SiS_Pr);
 
+  if(SiS_Pr->SiS_TVMode & TVSetPALM)      temp = 8;
+  else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 9;
+  /* NTSCJ uses NTSC filters */
+
   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(temp1 & (EnablePALM | EnablePALN)) {
-          temp = 8;
-	  if(!(temp1 & EnablePALM)) temp = 9;
-       }
-     }
-  }
   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) {
+      if((romptr) && (!(SiS_Pr->SiS_TVMode & (TVSetPALM|TVSetPALN)))) {
          romptr += (temp * 2);
 	 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,USHORT ModeIdIndex,
-		  USHORT RefTableIndex)
+SiS_OEM300Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+		  USHORT ModeNo, USHORT ModeIdIndex, USHORT RefTableIndex)
 {
   USHORT OEMModeIdIndex=0;
 
   if(!SiS_Pr->UseCustomMode) {
-     OEMModeIdIndex = SiS_SearchVBModeID(SiS_Pr,ROMAddr,&ModeNo);
+     OEMModeIdIndex = SiS_SearchVBModeID(SiS_Pr,&ModeNo);
      if(!(OEMModeIdIndex)) return;
   }
 
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-       SetOEMLCDDelay(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,OEMModeIdIndex);
-       if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-            SetOEMLCDData(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,OEMModeIdIndex);
-       }
+     SetOEMLCDDelay(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
+     if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+        SetOEMLCDData(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
+     }
   }
   if(SiS_Pr->UseCustomMode) return;
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-       SetOEMTVDelay(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,OEMModeIdIndex);
-       if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
-       		SetOEMAntiFlicker(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,OEMModeIdIndex);
-    		SetOEMPhaseIncr(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,OEMModeIdIndex);
-       		SetOEMYFilter(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,OEMModeIdIndex);
-       }
+     SetOEMTVDelay(SiS_Pr, HwInfo, ModeNo,OEMModeIdIndex);
+     if(SiS_Pr->SiS_VBType & VB_SISVB) {
+        SetOEMAntiFlicker(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
+    	SetOEMPhaseIncr(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
+       	SetOEMYFilter(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
+     }
   }
 }
 #endif
diff -urN linux-2.4.25-pre4/drivers/video/sis/init301.h linux-2.4.25-pre5/drivers/video/sis/init301.h
--- linux-2.4.25-pre4/drivers/video/sis/init301.h	2003-11-28 10:26:21.000000000 -0800
+++ linux-2.4.25-pre5/drivers/video/sis/init301.h	2004-01-15 12:10:23.000000000 -0800
@@ -2,35 +2,54 @@
 /*
  * Data and prototypes for init301.c
  *
- * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
+ * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
  *
- * If distributed as part of the linux kernel, the contents of this file
- * is entirely covered by the GPL.
+ * If distributed as part of the Linux kernel, the following license terms
+ * apply:
  *
- * Otherwise, the following terms apply:
+ * * This program is free software; you can redistribute it and/or modify
+ * * it under the terms of the GNU General Public License as published by
+ * * the Free Software Foundation; either version 2 of the named License,
+ * * or any later version.
+ * *
+ * * This program is distributed in the hope that it will be useful,
+ * * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * * GNU General Public License for more details.
+ * *
+ * * You should have received a copy of the GNU General Public License
+ * * along with this program; if not, write to the Free Software
+ * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
  *
- * 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.
+ * Otherwise, the following license terms apply:
  *
- * 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.
+ * * Redistribution and use in source and binary forms, with or without
+ * * modification, are permitted provided that the following conditions
+ * * are met:
+ * * 1) Redistributions of source code must retain the above copyright
+ * *    notice, this list of conditions and the following disclaimer.
+ * * 2) Redistributions in binary form must reproduce the above copyright
+ * *    notice, this list of conditions and the following disclaimer in the
+ * *    documentation and/or other materials provided with the distribution.
+ * * 3) All advertising materials mentioning features or use of this software
+ * *    must display the following acknowledgement: "This product includes
+ * *    software developed by Thomas Winischhofer, Vienna, Austria."
+ * * 4) The name of the author may not be used to endorse or promote products
+ * *    derived from this software without specific prior written permission.
+ * *
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
  *
- * Based on code by Silicon Intergrated Systems 
- *
  */
 
 #ifndef  _INIT301_
@@ -65,36 +84,36 @@
 #endif
 #endif
 
-const UCHAR SiS_HiVisionTable[3][64] = {
+const UCHAR SiS_YPbPrTable[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,
-    0x0c, 0x50, 0x00, 0x97, 0x00, 0xd4, 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, 0x53,
-    0x00, 0x40, 0x44, 0x00, 0xdb, 0x02, 0x3b, 0x00
+    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,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,
-    0x0c, 0x50, 0xb2, 0x2e, 0x16, 0xb5, 0xf4, 0x03,
-    0x7d, 0x11, 0x7d, 0xea, 0x30, 0x36, 0x18, 0x96,
-    0x21, 0x0a, 0x58, 0xee, 0x42, 0x92, 0x0f, 0x40,
-    0x60, 0x80, 0x14, 0x90, 0x8c, 0x60, 0x04, 0xf3,
-    0x00, 0x40, 0x11, 0x00, 0xfc, 0xff, 0x32, 0x00
+    0x1d,0x11,0x06,0x09,0x0b,0x0c,0x0c,0x0c,
+    0x98,0x0a,0x01,0x0d,0x06,0x0d,0x04,0x0a,
+    0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x3f,
+    0x0c,0x50,0xb2,0x9f,0x16,0x59,0x4f,0x13,
+    0xad,0x11,0xad,0x1d,0x40,0x8a,0x3d,0xb8,
+    0x51,0x5e,0x60,0x49,0x7d,0x92,0x0f,0x40,
+    0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x4b,
+    0x43,0x41,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,0x27,
+    0x00,0x40,0x11,0x00,0xfc,0xff,0x32,0x00
   }
 };
 
@@ -120,123 +139,140 @@
     0x18, 0x1d, 0x23, 0x28, 0x4c, 0xaa, 0x01
 };
 
-extern   BOOLEAN  SiS_SearchVBModeID(SiS_Private *SiS_Pr, UCHAR *RomAddr, USHORT *);
+/* 301C / 302ELV (?) extended Part2 TV registers */
+
+static const UCHAR SiS_Part2CLVX_1[] = {
+    0x00,0x00,
+    0x00,0x20,0x00,0x00,0x7F,0x20,0x02,0x7F,0x7D,0x20,0x04,0x7F,0x7D,0x1F,0x06,0x7E,
+    0x7C,0x1D,0x09,0x7E,0x7C,0x1B,0x0B,0x7E,0x7C,0x19,0x0E,0x7D,0x7C,0x17,0x11,0x7C,
+    0x7C,0x14,0x14,0x7C,0x7C,0x11,0x17,0x7C,0x7D,0x0E,0x19,0x7C,0x7E,0x0B,0x1B,0x7C,
+    0x7E,0x09,0x1D,0x7C,0x7F,0x06,0x1F,0x7C,0x7F,0x04,0x20,0x7D,0x00,0x02,0x20,0x7E
+};
+
+static const UCHAR SiS_Part2CLVX_2[] = {
+    0x00,0x00,
+    0x00,0x20,0x00,0x00,0x7F,0x20,0x02,0x7F,0x7D,0x20,0x04,0x7F,0x7D,0x1F,0x06,0x7E,
+    0x7C,0x1D,0x09,0x7E,0x7C,0x1B,0x0B,0x7E,0x7C,0x19,0x0E,0x7D,0x7C,0x17,0x11,0x7C,
+    0x7C,0x14,0x14,0x7C,0x7C,0x11,0x17,0x7C,0x7D,0x0E,0x19,0x7C,0x7E,0x0B,0x1B,0x7C,
+    0x7E,0x09,0x1D,0x7C,0x7F,0x06,0x1F,0x7C,0x7F,0x04,0x20,0x7D,0x00,0x02,0x20,0x7E
+};
+
+static const UCHAR SiS_Part2CLVX_3[] = {  /* NTSC, 525i, 525p */
+    0xE0,0x01,
+    0x04,0x1A,0x04,0x7E,0x03,0x1A,0x06,0x7D,0x01,0x1A,0x08,0x7D,0x00,0x19,0x0A,0x7D,
+    0x7F,0x19,0x0C,0x7C,0x7E,0x18,0x0E,0x7C,0x7E,0x17,0x10,0x7B,0x7D,0x15,0x12,0x7C,
+    0x7D,0x13,0x13,0x7D,0x7C,0x12,0x15,0x7D,0x7C,0x10,0x17,0x7D,0x7C,0x0E,0x18,0x7E,
+    0x7D,0x0C,0x19,0x7E,0x7D,0x0A,0x19,0x00,0x7D,0x08,0x1A,0x01,0x7E,0x06,0x1A,0x02,
+    0x58,0x02,
+    0x07,0x14,0x07,0x7E,0x06,0x14,0x09,0x7D,0x05,0x14,0x0A,0x7D,0x04,0x13,0x0B,0x7E,
+    0x03,0x13,0x0C,0x7E,0x02,0x12,0x0D,0x7F,0x01,0x12,0x0E,0x7F,0x01,0x11,0x0F,0x7F,
+    0x00,0x10,0x10,0x00,0x7F,0x0F,0x11,0x01,0x7F,0x0E,0x12,0x01,0x7E,0x0D,0x12,0x03,
+    0x7E,0x0C,0x13,0x03,0x7E,0x0B,0x13,0x04,0x7E,0x0A,0x14,0x04,0x7D,0x09,0x14,0x06,
+    0x00,0x03,
+    0x09,0x0F,0x09,0x7F,0x08,0x0F,0x09,0x00,0x07,0x0F,0x0A,0x00,0x06,0x0F,0x0A,0x01,
+    0x06,0x0E,0x0B,0x01,0x05,0x0E,0x0B,0x02,0x04,0x0E,0x0C,0x02,0x04,0x0D,0x0C,0x03,
+    0x03,0x0D,0x0D,0x03,0x02,0x0C,0x0D,0x05,0x02,0x0C,0x0E,0x04,0x01,0x0B,0x0E,0x06,
+    0x01,0x0B,0x0E,0x06,0x00,0x0A,0x0F,0x07,0x00,0x0A,0x0F,0x07,0x00,0x09,0x0F,0x08,
+    0xFF,0xFF
+};
+
+static const UCHAR SiS_Part2CLVX_4[] = {   /* PAL */
+    0x58,0x02,
+    0x05,0x19,0x05,0x7D,0x03,0x19,0x06,0x7E,0x02,0x19,0x08,0x7D,0x01,0x18,0x0A,0x7D,
+    0x00,0x18,0x0C,0x7C,0x7F,0x17,0x0E,0x7C,0x7E,0x16,0x0F,0x7D,0x7E,0x14,0x11,0x7D,
+    0x7D,0x13,0x13,0x7D,0x7D,0x11,0x14,0x7E,0x7D,0x0F,0x16,0x7E,0x7D,0x0E,0x17,0x7E,
+    0x7D,0x0C,0x18,0x7F,0x7D,0x0A,0x18,0x01,0x7D,0x08,0x19,0x02,0x7D,0x06,0x19,0x04,
+    0x00,0x03,
+    0x08,0x12,0x08,0x7E,0x07,0x12,0x09,0x7E,0x06,0x12,0x0A,0x7E,0x05,0x11,0x0B,0x7F,
+    0x04,0x11,0x0C,0x7F,0x03,0x11,0x0C,0x00,0x03,0x10,0x0D,0x00,0x02,0x0F,0x0E,0x01,
+    0x01,0x0F,0x0F,0x01,0x01,0x0E,0x0F,0x02,0x00,0x0D,0x10,0x03,0x7F,0x0C,0x11,0x04,
+    0x7F,0x0C,0x11,0x04,0x7F,0x0B,0x11,0x05,0x7E,0x0A,0x12,0x06,0x7E,0x09,0x12,0x07,
+    0x40,0x02,
+    0x04,0x1A,0x04,0x7E,0x02,0x1B,0x05,0x7E,0x01,0x1A,0x07,0x7E,0x00,0x1A,0x09,0x7D,
+    0x7F,0x19,0x0B,0x7D,0x7E,0x18,0x0D,0x7D,0x7D,0x17,0x10,0x7C,0x7D,0x15,0x12,0x7C,
+    0x7C,0x14,0x14,0x7C,0x7C,0x12,0x15,0x7D,0x7C,0x10,0x17,0x7D,0x7C,0x0D,0x18,0x7F,
+    0x7D,0x0B,0x19,0x7F,0x7D,0x09,0x1A,0x00,0x7D,0x07,0x1A,0x02,0x7E,0x05,0x1B,0x02,
+    0xFF,0xFF
+};
+
+static const UCHAR SiS_Part2CLVX_5[] = {   /* 750p */
+    0x00,0x03,
+    0x05,0x19,0x05,0x7D,0x03,0x19,0x06,0x7E,0x02,0x19,0x08,0x7D,0x01,0x18,0x0A,0x7D,
+    0x00,0x18,0x0C,0x7C,0x7F,0x17,0x0E,0x7C,0x7E,0x16,0x0F,0x7D,0x7E,0x14,0x11,0x7D,
+    0x7D,0x13,0x13,0x7D,0x7D,0x11,0x14,0x7E,0x7D,0x0F,0x16,0x7E,0x7D,0x0E,0x17,0x7E,
+    0x7D,0x0C,0x18,0x7F,0x7D,0x0A,0x18,0x01,0x7D,0x08,0x19,0x02,0x7D,0x06,0x19,0x04,
+    0xFF,0xFF
+};
+
+static const UCHAR SiS_Part2CLVX_6[] = {   /* 1080i */
+    0x00,0x04,
+    0x04,0x1A,0x04,0x7E,0x02,0x1B,0x05,0x7E,0x01,0x1A,0x07,0x7E,0x00,0x1A,0x09,0x7D,
+    0x7F,0x19,0x0B,0x7D,0x7E,0x18,0x0D,0x7D,0x7D,0x17,0x10,0x7C,0x7D,0x15,0x12,0x7C,
+    0x7C,0x14,0x14,0x7C,0x7C,0x12,0x15,0x7D,0x7C,0x10,0x17,0x1D,0x7C,0x0D,0x18,0x7F,
+    0x7D,0x0B,0x19,0x7F,0x7D,0x09,0x1A,0x00,0x7D,0x07,0x1A,0x02,0x7E,0x05,0x1B,0x02,
+    0xFF,0xFF,
+};
+
 
-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_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_IsDualLink(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,
-			     PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
-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,
-			    USHORT BaseAddr);
-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_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,
-			    PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
-#endif			    
-void     SiS_SetTPData(SiS_Private *SiS_Pr);
-void     SiS_SetChrontelGPIO(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);
+/* 661 et al LCD data structure */
+static const UCHAR SiS_LCDStruct661[] = {
+    /* 1600x1200 */
+    0x0B,0xEA,0x81,0x10,0x00,0xC0,0x03,0x21,0x5A,0x23,0x5A,0x23,0x02,
+    0x14,0x0A,0x02,0x00,0x30,0x10,0x5A,0x10,0x10,0x0A,0xC0,0x30,0x10,
+    /* 1400x1050 */
+    0x09,0xEA,0x81,0x80,0xA3,0x70,0x03,0x19,0xD2,0x2A,0xF8,0x2F,0x02,
+    0x14,0x0A,0x02,0x00,0x30,0x10,0x5A,0x10,0x10,0x0A,0xC0,0x30,0x10,
+    /* 1280x1024 */
+    0x03,0xEA,0x81,0x40,0xA1,0x70,0x03,0x19,0xD2,0x2A,0xF8,0x2F,0x02,
+    0x14,0x0A,0x02,0x00,0x30,0x10,0x5A,0x10,0x10,0x0A,0xC0,0x30,0x10,
+    /* 1024x768 */
+    0x02,0xEA,0x80,0x00,0x11,0x88,0x06,0x0B,0xF5,0x6C,0x35,0x62,0x02,
+    0x14,0x0A,0x02,0x00,0x30,0x10,0x5A,0x10,0x10,0x0A,0xC0,0x28,0x10,
+    0xFF,
+};
 #endif
-void     SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, USHORT tempax,USHORT tempbh);
+
+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_SetYPbPr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
+void    SiS_SetTVMode(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, 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);
@@ -247,115 +283,6 @@
 USHORT   SiS_WriteDDC2Data(SiS_Private *SiS_Pr, USHORT tempax);
 USHORT   SiS_CheckACK(SiS_Private *SiS_Pr);
 
-#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,USHORT RefreshRateTableIndex);
-#endif
-#ifdef SIS300
-void     SiS_OEM300Setting(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
-                           UCHAR *ROMAddr,USHORT ModeNo, USHORT ModeIdIndex, USHORT RefTabindex);
-void     SetOEMLCDData2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
-			UCHAR *ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,USHORT RefTableIndex);
-#endif
-BOOLEAN  SiS_LowModeStuff(SiS_Private *SiS_Pr, USHORT ModeNo,PSIS_HW_DEVICE_INFO HwDeviceExtension);
-
-void     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_SetCRT2Group(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, PSIS_HW_DEVICE_INFO HwDeviceExtension);
-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, PSIS_HW_DEVICE_INFO HwDeviceExtension);
-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,  PSIS_HW_DEVICE_INFO HwDeviceExtension);
-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
-
-/* DDC functions */
 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);
@@ -372,4 +299,44 @@
 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_OEM661Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+                           USHORT ModeNo,USHORT ModeIdIndex, USHORT RRTI);
+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_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 linux-2.4.25-pre4/drivers/video/sis/initdef.h linux-2.4.25-pre5/drivers/video/sis/initdef.h
--- linux-2.4.25-pre4/drivers/video/sis/initdef.h	2003-11-28 10:26:21.000000000 -0800
+++ linux-2.4.25-pre5/drivers/video/sis/initdef.h	2004-01-15 12:10:23.000000000 -0800
@@ -1,45 +1,76 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/initdef.h,v 1.4 2000/12/02 01:16:17 dawes Exp $ */
+/* $XFree86$ */
 /*
  * Global definitions for init.c and init301.c
  *
- * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
+ * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
  *
- * If distributed as part of the linux kernel, the contents of this file
- * is entirely covered by the GPL.
+ * If distributed as part of the Linux kernel, the following license terms
+ * apply:
  *
- * Otherwise, the following terms apply:
+ * * This program is free software; you can redistribute it and/or modify
+ * * it under the terms of the GNU General Public License as published by
+ * * the Free Software Foundation; either version 2 of the named License,
+ * * or any later version.
+ * *
+ * * This program is distributed in the hope that it will be useful,
+ * * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * * GNU General Public License for more details.
+ * *
+ * * You should have received a copy of the GNU General Public License
+ * * along with this program; if not, write to the Free Software
+ * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
  *
- * 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.
+ * Otherwise, the following license terms apply:
  *
- * 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.
+ * * Redistribution and use in source and binary forms, with or without
+ * * modification, are permitted provided that the following conditions
+ * * are met:
+ * * 1) Redistributions of source code must retain the above copyright
+ * *    notice, this list of conditions and the following disclaimer.
+ * * 2) Redistributions in binary form must reproduce the above copyright
+ * *    notice, this list of conditions and the following disclaimer in the
+ * *    documentation and/or other materials provided with the distribution.
+ * * 3) All advertising materials mentioning features or use of this software
+ * *    must display the following acknowledgement: "This product includes
+ * *    software developed by Thomas Winischhofer, Vienna, Austria."
+ * * 4) The name of the author may not be used to endorse or promote products
+ * *    derived from this software without specific prior written permission.
+ * *
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
  *
- * Based on code by Silicon Intergrated 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)  /* All versions, incl 651, M65x */
+#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_SIS65x               (IS_SIS651 || IS_SISM650)       /* Only special versions of 65x */
+#define IS_SIS661		(HwInfo->jChipType == SIS_661)
+#define IS_SIS741		(HwInfo->jChipType == SIS_741)
+#define IS_SIS660		(HwInfo->jChipType == SIS_660)
+#define IS_SIS760		(HwInfo->jChipType == SIS_760)
+#define IS_SIS661741660760	(IS_SIS661 || IS_SIS741 || IS_SIS660 || IS_SIS760)
+#define IS_SIS650740            ((HwInfo->jChipType >= SIS_650) && (HwInfo->jChipType < SIS_330))
+#define IS_SIS550650740         (IS_SIS550 || IS_SIS650740)
+#define IS_SIS650740660         (IS_SIS650 || IS_SIS740 || IS_SIS661741660760)
+#define IS_SIS550650740660      (IS_SIS550 || IS_SIS650740660)
 
 /* SiS_VBType */
 #define VB_SIS301	      	0x0001
@@ -47,34 +78,41 @@
 #define VB_SIS302B        	0x0004
 #define VB_SIS301LV     	0x0008
 #define VB_SIS302LV     	0x0010
-#define VB_SIS301C              0x0020
-#define VB_SIS30xLV		VB_SIS301LV
-#define VB_SIS30xNEW		VB_SIS302LV
+#define VB_SIS302ELV		0x0020
+#define VB_SIS301C              0x0040
 #define VB_NoLCD        	0x8000
-#define VB_SIS301BLV302BLV      (VB_SIS301B|VB_SIS301C|VB_SIS302B|VB_SIS301LV|VB_SIS302LV)
+#define VB_SIS301BLV302BLV      (VB_SIS301B|VB_SIS301C|VB_SIS302B|VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)
 #define VB_SIS301B302B          (VB_SIS301B|VB_SIS301C|VB_SIS302B)
-#define VB_SIS301LV302LV        (VB_SIS301LV|VB_SIS302LV)
+#define VB_SIS301LV302LV        (VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)
+#define VB_SISVB		(VB_SIS301 | VB_SIS301BLV302BLV)
 
-#define IS_SIS330		(HwDeviceExtension->jChipType == SIS_330)
-#define IS_SIS550		(HwDeviceExtension->jChipType == SIS_550)
-#define IS_SIS650		(HwDeviceExtension->jChipType == SIS_650)
-#define IS_SIS740		(HwDeviceExtension->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		(HwDeviceExtension->jChipType == SIS_660)
-#define IS_SIS760		(HwDeviceExtension->jChipType == SIS_760)
-#define IS_SIS650660            (IS_SIS650 || IS_SIS660)
-#define IS_SIS650740            ((HwDeviceExtension->jChipType >= SIS_650) && (HwDeviceExtension->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)
-
-#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 SetCRT2ToHiVision       0x0080   		/* for SiS bridge */
+#define SetCRT2ToCHYPbPr       	SetCRT2ToHiVision	/* for Chrontel   */
+#define SetNTSCTV               0x0000   /* CR 31 */
+#define SetPALTV                0x0100   		/* Deprecated here, now in TVMode */
+#define SetInSlaveMode          0x0200
+#define SetNotSimuMode          0x0400
+#define SetNotSimuTVMode        SetNotSimuMode
+#define SetDispDevSwitch        0x0800
+#define SetCRT2ToYPbPr525750    0x0800   /* 661 */
+#define LoadDACFlag             0x1000
+#define DisableCRT2Display      0x2000
+#define DriverMode              0x4000
+#define HotKeySwitch            0x8000
+#define SetCRT2ToLCDA           0x8000
+
+/* v-- Needs change in sis_vga.c if changed (GPIO) --v */
+#define SetCRT2ToTV             (SetCRT2ToYPbPr525750|SetCRT2ToHiVision|SetCRT2ToSCART|SetCRT2ToSVIDEO|SetCRT2ToAVIDEO)
+#define SetCRT2ToTVNoYPbPrHiVision (SetCRT2ToSCART | SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)
+#define SetCRT2ToTVNoHiVision  	(SetCRT2ToYPbPr525750 | SetCRT2ToSCART | SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)
 
 /* SiS_ModeType */
 #define ModeText                0x00
@@ -102,79 +140,64 @@
 #define DoubleScanMode          0x8000
 
 /* Infoflag */
-#define SupportAllCRT2          0x0078
 #define SupportTV               0x0008
-#define SupportHiVisionTV       0x0010
-#define SupportLCD              0x0020
-#define SupportRAMDAC2          0x0040
-#define NoSupportTV             0x0070
-#define NoSupportHiVisionTV     0x0060
-#define NoSupportLCD            0x0058
+#define SupportTV1024           0x0800
 #define SupportCHTV 		0x0800
-#define SupportTV1024           0x0800            
+#define Support64048060Hz       0x0800  /* Special for 640x480 LCD */
+#define SupportHiVision         0x0010
+#define SupportYPbPr            0x1000  /* TODO */
+#define SupportLCD              0x0020
+#define SupportRAMDAC2          0x0040	/* All           (<= 100Mhz) */
+#define SupportRAMDAC2_135      0x0100  /* All except DH (<= 135Mhz) */
+#define SupportRAMDAC2_162      0x0200  /* B, C          (<= 162Mhz) */
+#define SupportRAMDAC2_202      0x0400  /* C             (<= 202Mhz) */
 #define InterlaceMode           0x0080
-#define SupportHiVisionTV2      0x1000
 #define SyncPP                  0x0000
 #define SyncPN                  0x4000
 #define SyncNP                  0x8000
 #define SyncNN                  0xc000
-#define ECLKindex0              0x0000
-#define ECLKindex1              0x0100
-#define ECLKindex2              0x0200
-#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
 
 /* 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 ProgrammingCRT2         0x0001
+#define LowModeTests		0x0002
+/* #define TVSimuMode           0x0002 - deprecated */
+/* #define RPLLDIV2XO           0x0004 - deprecated */
+#define LCDVESATiming           0x0008
+#define EnableLVDSDDA           0x0010
+#define SetDispDevSwitchFlag    0x0020
+#define CheckWinDos             0x0040
+#define SetDOSMode              0x0080
+
+/* TVMode flag */
+#define TVSetPAL		0x0001
+#define TVSetNTSCJ		0x0002
+#define TVSetPALM		0x0004
+#define TVSetPALN		0x0008
+#define TVSetCHOverScan		0x0010
+#define TVSetYPbPr525i		0x0020
+#define TVSetYPbPr525p		0x0040
+#define TVSetYPbPr750p		0x0080
+#define TVSetHiVision		0x0100
+#define TVSetTVSimuMode		0x0800
+#define TVRPLLDIV2XO		0x1000
+#define TVSetNTSC1024		0x2000
+
+/* YPbPr flag (>=315, <661; YPbPr not supported yet) */
+#define YPbPr750                0x0001	/* 750p (must be a single bit, checked logially) */
+#define YPbPr525                0x0002	/* 525p (must be a single bit, checked logially) */
+#define YPbPrHiVision           0x0003	/* HiVision */
+#define YPbPrModeMask           (YPbPr750 | YPbPr525 | YPbPrHiVision)
+#define YPbPrSetSVideo     	0x0004	/* (sets SVIDEO flag) */
 
-/* SysFlags */
+/* SysFlags (to identify special versions) */
 #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
-
-#define PanelRGB18Bit           0x0100
-#define PanelRGB24Bit           0x0000
-
-#define TVOverScan              0x10    /* Bit in CR35 (300 series only) */
-#define TVOverScanShift         4
-#define ClearBufferFlag         0x20
+#define SF_IsM661		0x0020
+#define SF_IsM741		0x0040
+#define SF_IsM760		0x0080
 
 /* CR32 (Newer 630, and 315 series)
 
@@ -185,9 +208,32 @@
    [4]   VB connected with CRT2 (secondary VGA)
    [5]   CRT1 monitor is connected
    [6]   VB connected with Hi-Vision TV
-   [7]   VB connected with DVI combo connector
+   [7]   <= 330: VB connected with DVI combo connector
+         >= 661: VB connected to YPbPr
+*/
+
+/* CR35 (300 series only) */
+#define TVOverScan              0x10
+#define TVOverScanShift         4
+
+/* CR35 (661 series only)
 
+   [0]    1 = PAL, 0 = NTSC
+   [1]    1 = NTSC-J (if D0 = 0)
+   [2]    1 = PALM (if D0 = 1)
+   [3]    1 = PALN (if D0 = 1)
+   [4]    1 = Overscan (Chrontel only)
+   [7:5]  (only if D2 in CR38 is set; not supported yet)
+          000  525i
+ 	  001  525p
+	  010  750p
+	  011  HiVision (Should be 1080i, but...)
 
+   These bits are being translated to TVMode flag.
+
+*/
+
+/*
    CR37
 
    [0]   Set 24/18 bit (0/1) RGB to LVDS/TMDS transmitter (set by BIOS)
@@ -198,11 +244,14 @@
 	    011   LVDS + Tumpion Zurac
 	    100   LVDS + Chrontel 7005
 	    110   Chrontel 7005
-	  315 series
+	  315/330 series
 	    001   SiS30x (never seen)
 	    010   LVDS
 	    011   LVDS + Chrontel 7019
+	  660 series [2:1] only:
+	     reserved (now in CR38)
 	  All other combinations reserved
+   [3]    661 only: Pass 1:1 data
    [4]    LVDS: 0: Panel Link expands / 1: Panel Link does not expand
           30x:  0: Bridge scales      / 1: Bridge does not scale = Panel scales (if possible)
    [5]    LCD polarity select
@@ -219,37 +268,55 @@
 /* CR37: LCDInfo */
 #define LCDRGB18Bit           0x0001
 #define LCDNonExpanding       0x0010
+#define LCDSync               0x0020
+#define LCDPass11             0x0100
+#define LCDDualLink	      0x0200
+
 #define DontExpandLCD	      LCDNonExpanding
 #define LCDNonExpandingShift       4
 #define DontExpandLCDShift    LCDNonExpandingShift
-#define LCDSync               0x0020
-#define LCDPass11             0x0100 
 #define LCDSyncBit            0x00e0
 #define LCDSyncShift               6
 
 /* CR38 (315 series) */
-#define EnableDualEdge 		0x01   
-#define SetToLCDA		0x02   /* LCD channel A (302B/LV 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 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 EnableDualEdge 		0x01
+#define SetToLCDA		0x02   /* LCD channel A (301C/302B/30x(E)LV and 650+LVDS only) */
+#define EnableSiSYPbPr          0x04   /* YPbPr on SiS bridge (not used; also on 661) */
+#define EnableCHScart           0x04   /* Scart on Ch7019 (unofficial definition - TW) */
+#define EnableCHYPbPr           0x08   /* YPbPr on Ch7019 (480i HDTV); only on 650/Ch7019 systems */
+#define EnableYPbPr750          0x08   /* Enable 750P YPbPr mode (30xLV/301C only) (not supported) */
+#define EnableYPbPr525          0x10   /* Enable 525P YPbPr mode (30xLV/301C only) (not supported) */
+#define EnableYPbPrHiVision     0x18   /* Enable HiVision (not supported) */
+#define EnableYPbPrsetSVideo    0x20   /* Enable YPbPr and set SVideo */
 #define EnablePALM              0x40   /* 1 = Set PALM */
 #define EnablePALN              0x80   /* 1 = Set PALN */
+#define EnableNTSCJ             EnablePALM  /* Not BIOS */
 
-#define SetSCARTOutput          0x01
-#define BoardTVType             0x02
+/* CR38 (661 and later)
+  D[7:5]  000 No VB
+          001 301 series VB
+	  010 LVDS
+	  011 Chrontel 7019
+	  100 Conexant
+  D2      Enable YPbPr output (see CR35)
+  D[1:0]  LCDA (like before)
+*/
 
 #define EnablePALMN             0x40   /* Romflag: 1 = Allow PALM/PALN */
 
-/* CR39 (650) */
+/* CR39 (650 only) */
 #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; enable dual link */
 
+/* CR39 (661 and later; not yet implemented)
+   D[1:0] YPbPr Aspect Ratio
+          00 4:3 letterbox
+	  01 4:3
+	  10 16:9
+	  11 4:3
+*/
 
-/* CR79 (315 series only)
+/* CR79 (315/330 series only; not 661 and later)
    [3-0] Notify driver
          0001 Mode Switch event (set by BIOS)
 	 0010 Epansion On/Off event
@@ -313,53 +380,44 @@
 #define Panel_Custom		0x0f
 #define Panel_Barco1366         0x10
 #define Panel_848x480		0x11
+#define Panel_1280x800		0x12    /* 661etc: 0x0c */
+#define Panel_1680x1050         0x13    /* 661etc: 0x0d */
 
 /* 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_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_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_1152x864  22  /* Up to this SiS conforming */
+#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
@@ -372,9 +430,6 @@
 #define ExtHiTVHT               2100
 #define ExtHiTVVT               1125
 
-#define VCLKStartFreq           25
-#define SoftDramType            0x80
-
 /* Indices in (VB)VCLKData tables */
 
 #define VCLK28                  0x00   /* Index in VCLKData table (300 and 315) */
@@ -392,6 +447,7 @@
 #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) */
@@ -401,25 +457,14 @@
 #define HiTVVCLK                0x03   /* Index relative to TVCLKBASE */
 #define HiTVSimuVCLK            0x04   /* Index relative to TVCLKBASE */
 #define HiTVTextVCLK            0x05   /* Index relative to TVCLKBASE */
+#define YPbPr750pVCLK		0x0f   /* NOT 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
@@ -436,8 +481,11 @@
 #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
 #define ActiveNonExpanding      0x40
 #define ActiveNonExpandingShift 6
@@ -448,8 +496,6 @@
 #define SoftSettingAddr         0x52
 #define ModeSettingAddr         0x53
 
-#define SelectCRT1Rate          0x4
-        
 #define _PanelType00             0x00
 #define _PanelType01             0x08
 #define _PanelType02             0x10
@@ -468,7 +514,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
diff -urN linux-2.4.25-pre4/drivers/video/sis/oem300.h linux-2.4.25-pre5/drivers/video/sis/oem300.h
--- linux-2.4.25-pre4/drivers/video/sis/oem300.h	2003-11-28 10:26:21.000000000 -0800
+++ linux-2.4.25-pre5/drivers/video/sis/oem300.h	2004-01-15 12:10:23.000000000 -0800
@@ -1,36 +1,55 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/oem300.h.c,v 1.0 2001/11/30 12:12:01 eich Exp $ */
+/* $XFree86$ */
 /*
  * OEM Data for 300 series
  *
- * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
+ * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
  *
- * If distributed as part of the linux kernel, the contents of this file
- * is entirely covered by the GPL.
+ * If distributed as part of the Linux kernel, the following license terms
+ * apply:
  *
- * Otherwise, the following terms apply:
+ * * This program is free software; you can redistribute it and/or modify
+ * * it under the terms of the GNU General Public License as published by
+ * * the Free Software Foundation; either version 2 of the named License,
+ * * or any later version.
+ * *
+ * * This program is distributed in the hope that it will be useful,
+ * * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * * GNU General Public License for more details.
+ * *
+ * * You should have received a copy of the GNU General Public License
+ * * along with this program; if not, write to the Free Software
+ * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
  *
- * 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.
+ * Otherwise, the following license terms apply:
  *
- * 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.
+ * * Redistribution and use in source and binary forms, with or without
+ * * modification, are permitted provided that the following conditions
+ * * are met:
+ * * 1) Redistributions of source code must retain the above copyright
+ * *    notice, this list of conditions and the following disclaimer.
+ * * 2) Redistributions in binary form must reproduce the above copyright
+ * *    notice, this list of conditions and the following disclaimer in the
+ * *    documentation and/or other materials provided with the distribution.
+ * * 3) All advertising materials mentioning features or use of this software
+ * *    must display the following acknowledgement: "This product includes
+ * *    software developed by Thomas Winischhofer, Vienna, Austria."
+ * * 4) The name of the author may not be used to endorse or promote products
+ * *    derived from this software without specific prior written permission.
+ * *
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
  *
- * Based on code by Silicon Intergrated Systems
- *
  */
 
 const UCHAR SiS300_OEMTVDelay301[8][4] =
@@ -277,140 +296,124 @@
 	{0x20,0x20,0x20,0x20}
 };
 
-const UCHAR SiS300_Phase1[8][6][4] =
+const UCHAR SiS300_Phase1[8][5][4] =
 {
     {
 	{0x21,0xed,0x00,0x08},
 	{0x21,0xed,0x8a,0x08},
 	{0x21,0xed,0x8a,0x08},
 	{0x21,0xed,0x8a,0x08},
-	{0x21,0xed,0x8a,0x08},
-	{0xff,0xff,0xff,0xff}
+	{0x21,0xed,0x8a,0x08}
     },
     {
         {0x2a,0x05,0xd3,0x00},
 	{0x2a,0x05,0xd3,0x00},
 	{0x2a,0x05,0xd3,0x00},
 	{0x2a,0x05,0xd3,0x00},
-	{0x2a,0x05,0xd3,0x00},
-	{0xff,0xff,0xff,0xff}
+	{0x2a,0x05,0xd3,0x00}
     },
     {
         {0x2a,0x05,0xd3,0x00},
 	{0x2a,0x05,0xd3,0x00},
 	{0x2a,0x05,0xd3,0x00},
 	{0x2a,0x05,0xd3,0x00},
-	{0x2a,0x05,0xd3,0x00},
-	{0xff,0xff,0xff,0xff}
+	{0x2a,0x05,0xd3,0x00}
     },
     {
         {0x2a,0x05,0xd3,0x00},
 	{0x2a,0x05,0xd3,0x00},
 	{0x2a,0x05,0xd3,0x00},
 	{0x2a,0x05,0xd3,0x00},
-	{0x2a,0x05,0xd3,0x00},
-	{0xff,0xff,0xff,0xff}
+	{0x2a,0x05,0xd3,0x00}
     },
     {
         {0x21,0xed,0x00,0x08},
 	{0x21,0xed,0x8a,0x08},
 	{0x21,0xed,0x8a,0x08},
 	{0x21,0xed,0x8a,0x08},
-	{0x21,0xed,0x8a,0x08},
-	{0xff,0xff,0xff,0xff}
+	{0x21,0xed,0x8a,0x08}
     },
     {
         {0x2a,0x05,0xd3,0x00},
 	{0x2a,0x05,0xd3,0x00},
 	{0x2a,0x05,0xd3,0x00},
 	{0x2a,0x05,0xd3,0x00},
-	{0x2a,0x05,0xd3,0x00},
-	{0xff,0xff,0xff,0xff}
+	{0x2a,0x05,0xd3,0x00}
     },
     {
         {0x2a,0x05,0xd3,0x00},
 	{0x2a,0x05,0xd3,0x00},
 	{0x2a,0x05,0xd3,0x00},
 	{0x2a,0x05,0xd3,0x00},
-	{0x2a,0x05,0xd3,0x00},
-	{0xff,0xff,0xff,0xff}
+	{0x2a,0x05,0xd3,0x00}
     },
     {
         {0x2a,0x05,0xd3,0x00},
 	{0x2a,0x05,0xd3,0x00},
 	{0x2a,0x05,0xd3,0x00},
 	{0x2a,0x05,0xd3,0x00},
-	{0x2a,0x05,0xd3,0x00},
-	{0xff,0xff,0xff,0xff}
+	{0x2a,0x05,0xd3,0x00}
     }
 };
 
 
-const UCHAR SiS300_Phase2[8][6][4] =
+const UCHAR SiS300_Phase2[8][5][4] =
 {
     {
         {0x21,0xed,0x00,0x08},
 	{0x21,0xed,0x8a,0x08},
 	{0x21,0xed,0x8a,0x08},
 	{0x21,0xed,0x8a,0x08},
-	{0x21,0xed,0x8a,0x08},
-	{0xff,0xff,0xff,0xff}
+	{0x21,0xed,0x8a,0x08}
     },
     {
 	{0x2a,0x05,0xd3,0x00},
 	{0x2a,0x05,0xd3,0x00},
 	{0x2a,0x05,0xd3,0x00},
 	{0x2a,0x05,0xd3,0x00},
-	{0x2a,0x05,0xd3,0x00},
-	{0xff,0xff,0xff,0xff}
+	{0x2a,0x05,0xd3,0x00}
     },
     {
         {0x2a,0x05,0xd3,0x00},
 	{0x2a,0x05,0xd3,0x00},
 	{0x2a,0x05,0xd3,0x00},
 	{0x2a,0x05,0xd3,0x00},
-	{0x2a,0x05,0xd3,0x00},
-	{0xff,0xff,0xff,0xff}
+	{0x2a,0x05,0xd3,0x00}
     },
     {
         {0x2a,0x05,0xd3,0x00},
 	{0x2a,0x05,0xd3,0x00},
 	{0x2a,0x05,0xd3,0x00},
 	{0x2a,0x05,0xd3,0x00},
-	{0x2a,0x05,0xd3,0x00},
-	{0xff,0xff,0xff,0xff}
+	{0x2a,0x05,0xd3,0x00}
     },
     {
         {0x21,0xed,0x00,0x08},
 	{0x21,0xed,0x8a,0x08},
 	{0x21,0xed,0x8a,0x08},
 	{0x21,0xed,0x8a,0x08},
-	{0x21,0xed,0x8a,0x08},
-	{0xff,0xff,0xff,0xff}
+	{0x21,0xed,0x8a,0x08}
     },
     {
         {0x2a,0x05,0xd3,0x00},
 	{0x2a,0x05,0xd3,0x00},
 	{0x2a,0x05,0xd3,0x00},
 	{0x2a,0x05,0xd3,0x00},
-	{0x2a,0x05,0xd3,0x00},
-	{0xff,0xff,0xff,0xff}
+	{0x2a,0x05,0xd3,0x00}
     },
     {
         {0x2a,0x05,0xd3,0x00},
 	{0x2a,0x05,0xd3,0x00},
 	{0x2a,0x05,0xd3,0x00},
 	{0x2a,0x05,0xd3,0x00},
-	{0x2a,0x05,0xd3,0x00},
-	{0xff,0xff,0xff,0xff}
+	{0x2a,0x05,0xd3,0x00}
     },
     {
         {0x2a,0x05,0xd3,0x00},
 	{0x2a,0x05,0xd3,0x00},
 	{0x2a,0x05,0xd3,0x00},
 	{0x2a,0x05,0xd3,0x00},
-	{0x2a,0x05,0xd3,0x00},
-	{0xff,0xff,0xff,0xff}
+	{0x2a,0x05,0xd3,0x00}
     }
 };
 
diff -urN linux-2.4.25-pre4/drivers/video/sis/oem310.h linux-2.4.25-pre5/drivers/video/sis/oem310.h
--- linux-2.4.25-pre4/drivers/video/sis/oem310.h	2003-11-28 10:26:21.000000000 -0800
+++ linux-2.4.25-pre5/drivers/video/sis/oem310.h	2004-01-15 12:10:23.000000000 -0800
@@ -1,39 +1,58 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/oem300.h.c,v 1.0 2001/11/30 12:12:01 eich Exp $ */
+/* $XFree86$ */
 /*
  * OEM Data for 315/330 series
  *
- * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
+ * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
  *
- * If distributed as part of the linux kernel, the contents of this file
- * is entirely covered by the GPL.
+ * If distributed as part of the Linux kernel, the following license terms
+ * apply:
  *
- * Otherwise, the following terms apply:
+ * * This program is free software; you can redistribute it and/or modify
+ * * it under the terms of the GNU General Public License as published by
+ * * the Free Software Foundation; either version 2 of the named License,
+ * * or any later version.
+ * *
+ * * This program is distributed in the hope that it will be useful,
+ * * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * * GNU General Public License for more details.
+ * *
+ * * You should have received a copy of the GNU General Public License
+ * * along with this program; if not, write to the Free Software
+ * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
  *
- * 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.
+ * Otherwise, the following license terms apply:
  *
- * 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.
+ * * Redistribution and use in source and binary forms, with or without
+ * * modification, are permitted provided that the following conditions
+ * * are met:
+ * * 1) Redistributions of source code must retain the above copyright
+ * *    notice, this list of conditions and the following disclaimer.
+ * * 2) Redistributions in binary form must reproduce the above copyright
+ * *    notice, this list of conditions and the following disclaimer in the
+ * *    documentation and/or other materials provided with the distribution.
+ * * 3) All advertising materials mentioning features or use of this software
+ * *    must display the following acknowledgement: "This product includes
+ * *    software developed by Thomas Winischhofer, Vienna, Austria."
+ * * 4) The name of the author may not be used to endorse or promote products
+ * *    derived from this software without specific prior written permission.
+ * *
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
  *
- * Based on code by Silicon Intergrated Systems 
- *
  */
 
-const UCHAR SiS310_LCDDelayCompensation_301[] =	    	/* 301 */
+static const UCHAR SiS310_LCDDelayCompensation_301[] =	    		/* 301 */
 {
 		 0x00,0x00,0x00,    /*   800x600 */
 		 0x0b,0x0b,0x0b,    /*  1024x768 */
@@ -53,7 +72,7 @@
 };
 
 /* This is contained in 650+301B BIOSes, but it is wrong - so we don't use it */
-UCHAR SiS310_LCDDelayCompensation_650301B[] =	   	/* 30xB,LV */
+static const UCHAR SiS310_LCDDelayCompensation_650301B[] =	   	/* 30xB,LV */
 {
 		 0x01,0x01,0x01,    /*   800x600 */
 		 0x01,0x01,0x01,    /*  1024x768 */
@@ -73,7 +92,7 @@
 };
 
 /* This data is correct, so we use it instead of the table above */
-UCHAR SiS310_LCDDelayCompensation_3xx301B[] =	   	/* 30xB,LV */
+static const UCHAR SiS310_LCDDelayCompensation_3xx301B[] =	   	/* 30xB,LV */
 {
 		 0x01,0x01,0x01,    /*   800x600 */
 		 0x0C,0x0C,0x0C,    /*  1024x768 */
@@ -92,7 +111,7 @@
 		 0x02,0x02,0x02
 };
 
-const UCHAR SiS310_LCDDelayCompensation_LVDS650[] =   	/* LVDS */
+static const UCHAR SiS310_LCDDelayCompensation_LVDS650[] =   	/* LVDS */
 {
                  0x00,0x00,0x00,    /*   800x600 */
 		 0x00,0x00,0x00,    /*  1024x768 */
@@ -111,7 +130,7 @@
 		 0x00,0x00,0x00
 };
 
-const UCHAR SiS310_LCDDelayCompensation_LVDS740[] =   	/* LVDS */
+static const UCHAR SiS310_LCDDelayCompensation_LVDS740[] =   	/* LVDS */
 {
                  0x03,0x03,0x03,    /*   800x600 */
 		 0x03,0x03,0x03,    /*  1024x768 */
@@ -130,7 +149,7 @@
 		 0x00,0x00,0x00
 };
 
-const UCHAR SiS310_LCDDelayCompensation_651301LV[] =	  /* M650/651 301LV */
+static const UCHAR SiS310_LCDDelayCompensation_651301LV[] =	  /* M650/651 301LV */
 {
                  0x33,0x33,0x33,    /*   800x600 (guessed) - new: PanelType, not PanelRes ! */
 		 0x33,0x33,0x33,    /*  1024x768 */
@@ -149,7 +168,7 @@
 		 0x33,0x33,0x33
 };
 
-const UCHAR SiS310_LCDDelayCompensation_651302LV[] =	   /* M650/651 302LV */
+static const UCHAR SiS310_LCDDelayCompensation_651302LV[] =	   /* M650/651 302LV */
 {
                  0x33,0x33,0x33,    /*   800x600 (guessed) */
 		 0x33,0x33,0x33,    /*  1024x768 */
@@ -168,66 +187,92 @@
 		 0x33,0x33,0x33
 };
 
-const UCHAR SiS310_TVDelayCompensation_301[] = 		/* 301 */
+static const UCHAR SiS310_TVDelayCompensation_301[] = 		/* 301 */
 {
 		 0x02,0x02,    /* NTSC Enhanced, Standard */
                  0x02,0x02,    /* PAL */
 		 0x08,0x0b     /* HiVision */
 };
 
-const UCHAR SiS310_TVDelayCompensation_301B[] =		/* 30xB, 30xLV */
+static const UCHAR SiS310_TVDelayCompensation_301B[] =		/* 30xB, 30xLV */
 {
 		 0x03,0x03,
 		 0x03,0x03,
 		 0x03,0x03
 };
 
-const UCHAR SiS310_TVDelayCompensation_740301B[] =	/* 740 + 30xB (30xLV?) */
+static const UCHAR SiS310_TVDelayCompensation_740301B[] =	/* 740 + 30xB (30xLV?) */
 {
 		 0x05,0x05,
 		 0x05,0x05,
 		 0x05,0x05
 };
 
-const UCHAR SiS310_TVDelayCompensation_LVDS[] =		/* LVDS */
+static const UCHAR SiS310_TVDelayCompensation_LVDS[] =		/* LVDS */
 {
 		 0x0a,0x0a,
 		 0x0a,0x0a,
 		 0x0a,0x0a
 };
 
-const UCHAR SiS310_TVDelayCompensation_651301LV[] =	/* M650, 651, 301LV */
+static const UCHAR SiS310_TVDelayCompensation_651301LV[] =	/* M650, 651, 301LV */
 {
 		 0x33,0x33,
 		 0x33,0x33,
 		 0x33,0x33
 };
 
-const UCHAR SiS310_TVDelayCompensation_651302LV[] =	/* M650, 651, 302LV */
+static const UCHAR SiS310_TVDelayCompensation_651302LV[] =	/* M650, 651, 302LV */
 {
 		 0x33,0x33,
 		 0x33,0x33,
 		 0x33,0x33
 };
 
-const UCHAR SiS310_TVAntiFlick1[3][2] =
+static const UCHAR SiS_TVDelay661_301[] =			/* 661, 301 */
+{
+		 0x44,0x44,
+		 0x44,0x44,
+		 0x00,0x00,
+		 0x44,0x44,
+		 0x44,0x44,
+		 0x44,0x44
+};
+
+static const UCHAR SiS_TVDelay661_301B[] =			/* 661, 301B et al */
+{
+		 0x44,0x44,
+		 0x44,0x44,
+		 0x00,0x00,
+		 0x44,0x44,
+		 0x44,0x44,
+		 0x44,0x44
+};
+
+static const UCHAR SiS310_TVAntiFlick1[6][2] =
 {
             {0x4,0x0},
 	    {0x4,0x8},
+	    {0x0,0x0},
+	    {0x0,0x0},
+	    {0x0,0x0},
 	    {0x0,0x0}
 };
 
-const UCHAR SiS310_TVEdge1[3][2] =
+static const UCHAR SiS310_TVEdge1[6][2] =
 {
             {0x0,0x4},
 	    {0x0,0x4},
+	    {0x0,0x0},
+	    {0x0,0x0},
+	    {0x0,0x0},
 	    {0x0,0x0}
 };
 
-const UCHAR SiS310_TVYFilter1[3][8][4] =
+static const UCHAR SiS310_TVYFilter1[5][8][4] =
 {
  {
-	{0x00,0xf4,0x10,0x38},
+	{0x00,0xf4,0x10,0x38},	/* NTSC */
 	{0x00,0xf4,0x10,0x38},
 	{0xeb,0x04,0x25,0x18},
 	{0xf1,0x04,0x1f,0x18},
@@ -237,7 +282,7 @@
 	{0xeb,0x15,0x25,0xf6}
  },
  {
-	{0x00,0xf4,0x10,0x38},
+	{0x00,0xf4,0x10,0x38},	/* PAL */
 	{0x00,0xf4,0x10,0x38},
 	{0xf1,0xf7,0x1f,0x32},
 	{0xf3,0x00,0x1d,0x20},
@@ -247,7 +292,7 @@
 	{0xfc,0xfb,0x14,0x2a}
  },
  {
-	{0x00,0x00,0x00,0x00},
+	{0x00,0x00,0x00,0x00},	/* HiVision */
 	{0x00,0xf4,0x10,0x38},
 	{0x00,0xf4,0x10,0x38},
 	{0xeb,0x04,0x25,0x18},
@@ -255,13 +300,33 @@
 	{0x00,0xf4,0x10,0x38},
 	{0xeb,0x04,0x25,0x18},
 	{0xee,0x0c,0x22,0x08}
+ },
+ {
+ 	{0x00,0xf4,0x10,0x38},	/* PAL-M */
+	{0x00,0xf4,0x10,0x38},
+	{0xeb,0x04,0x10,0x18},
+	{0xf7,0x06,0x19,0x14},
+	{0x00,0xf4,0x10,0x38},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x15,0x25,0xf6}
+ },
+ {
+ 	{0x00,0xf4,0x10,0x38},	/* PAL-N */
+	{0x00,0xf4,0x10,0x38},
+	{0xeb,0x04,0x10,0x18},
+	{0xf7,0x06,0x19,0x14},
+	{0x00,0xf4,0x10,0x38},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x04,0x25,0x18},
+	{0xeb,0x15,0x25,0xf6}
  }
 };
 
-const UCHAR SiS310_TVYFilter2[3][9][7] =
+static const UCHAR SiS310_TVYFilter2[5][9][7] =
 {
  {
-	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},	/* NTSC */
 	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
 	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
 	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
@@ -272,7 +337,7 @@
 	{0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
  },
  {
-	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},   
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},   /* PAL */
 	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
 	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
 	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
@@ -283,6 +348,7 @@
 	{0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
  },
  {
+	{0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22},	/* HiVision */
 	{0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22},
 	{0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22},
 	{0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22},
@@ -291,53 +357,9 @@
 	{0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22},
 	{0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22},
 	{0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22}
- }
-};
-
-const UCHAR SiS310_PALMFilter[16][4] =
-{
-	{0x00,0xf4,0x10,0x38},
-	{0x00,0xf4,0x10,0x38},
-	{0xeb,0x04,0x10,0x18},
-	{0xf7,0x06,0x19,0x14},
-	{0x00,0xf4,0x10,0x38},
-	{0xeb,0x04,0x25,0x18},
-	{0xeb,0x04,0x25,0x18},
-	{0xeb,0x15,0x25,0xf6},
-	{0xeb,0x04,0x25,0x18},
-	{0xeb,0x04,0x25,0x18},
-	{0xeb,0x04,0x25,0x18},
-	{0xeb,0x04,0x25,0x18},
-	{0xeb,0x04,0x25,0x18},
-	{0xeb,0x04,0x25,0x18},
-	{0xeb,0x04,0x25,0x18},
-	{0xeb,0x04,0x25,0x18}
-};
-
-const UCHAR SiS310_PALNFilter[16][4] =
-{
-	{0x00,0xf4,0x10,0x38},
-	{0x00,0xf4,0x10,0x38},
-	{0xeb,0x04,0x10,0x18},
-	{0xf7,0x06,0x19,0x14},
-	{0x00,0xf4,0x10,0x38},
-	{0xeb,0x04,0x25,0x18},
-	{0xeb,0x04,0x25,0x18},
-	{0xeb,0x15,0x25,0xf6},
-	{0xeb,0x04,0x25,0x18},
-	{0xeb,0x04,0x25,0x18},
-	{0xeb,0x04,0x25,0x18},
-	{0xeb,0x04,0x25,0x18},
-	{0xeb,0x04,0x25,0x18},
-	{0xeb,0x04,0x25,0x18},
-	{0xeb,0x04,0x25,0x18},
-	{0xeb,0x04,0x25,0x18}
-};
-
-
-const UCHAR SiS310_PALMFilter2[9][7] =
-{
-	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+ },
+ {
+ 	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, 	/* PAL-M */
 	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
 	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
 	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
@@ -346,11 +368,9 @@
 	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
 	{0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
 	{0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
-};
-
-const UCHAR SiS310_PALNFilter2[9][7] =
-{
-	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+ },
+ {
+ 	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},	/* PAL-N */
 	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
 	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
 	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
@@ -359,9 +379,10 @@
 	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
 	{0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
 	{0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
+ }
 };
 
-const UCHAR SiS310_TVPhaseIncr1[3][2][4] =
+static const UCHAR SiS310_TVPhaseIncr1[3][2][4] =
 {
  {
 	{0x21,0xed,0xba,0x08},
@@ -377,15 +398,15 @@
  }
 };
 
-const UCHAR SiS310_TVPhaseIncr2[3][2][4] =
+static const UCHAR SiS310_TVPhaseIncr2[3][2][4] =
 {
  {
-	{0x21,0xf0,0x7b,0xd6},   /* 1.10.7w;  1.10.6s: {0x1e,0x8b,0xda,0xa7},   old: {0x21,0xF1,0x37,0x56} */
-	{0x21,0xf0,0x7b,0xd6}    /* 1.10.7w;  1.10.6s: {0x1e,0x8b,0xda,0xa7}    old: {0x21,0xF1,0x37,0x56} */
+	{0x21,0xf0,0x7b,0xd6},
+	{0x21,0xf0,0x7b,0xd6}
  },
  {
-	{0x2a,0x0a,0x41,0xe9},   /* 1.10.7w, 1.10.6s. old: {0x2a,0x09,0x86,0xe9}, */
-	{0x2a,0x0a,0x41,0xe9}    /* 1.10.7w, 1.10.6s. old: {0x2a,0x09,0x86,0xe9}  */
+	{0x2a,0x0a,0x41,0xe9},
+	{0x2a,0x0a,0x41,0xe9}  
  },
  {
 	{0x2a,0x05,0xd3,0x00},
@@ -393,7 +414,31 @@
  }
 };
 
-/* OEM data for Compaq Presario 3045US */
+static const UCHAR SiS661_TVPhase[] = {
+    0x21,0xED,0xBA,0x08,
+    0x2A,0x05,0xE3,0x00,
+    0x21,0xE4,0x2E,0x9B,
+    0x21,0xF4,0x3E,0xBA,
+    0x1E,0x8B,0xA2,0xA7,
+    0x1E,0x83,0x0A,0xE0,
+    0x00,0x00,0x00,0x00,
+    0x00,0x00,0x00,0x00,
+    0x21,0xF0,0x7B,0xD6,
+    0x2A,0x09,0x86,0xE9,
+    0x21,0xE6,0xEF,0xA4,
+    0x21,0xF6,0x94,0x46,
+    0x1E,0x8B,0xA2,0xA7,
+    0x1E,0x83,0x0A,0xE0,
+    0x00,0x00,0x00,0x00,
+    0x00,0x00,0x00,0x00 
+};
+
+/**************************************************************/
+/* CUSTOM TIMING DATA --------------------------------------- */
+/**************************************************************/
+
+/* Inventec / Compaq Presario 3045US, 3017 */
+
 static const SiS_LCDDataStruct  SiS310_ExtCompaq1280x1024Data[] =
 {
 	{  211,  60,1024, 501,1688,1066},
@@ -443,6 +488,34 @@
  {{0x47,0x1C,0x14,0x29,0xFF,0xBE,0x23,0x0A,0x07,0x26,0x8A,0x42}}
 };
 
+/* LCDA CRT2 data is std */
+
+static const SiS_LVDSDesStruct Compaq1280x1024Des_1[] =
+{
+  { 0, 0 },
+  { 0, 0 },
+  { 0, 0 },
+  { 0, 0 },
+  { 0, 0 },
+  { 0, 0 },
+  { 0, 0 },
+  { 0, 0 }
+};
+
+static const SiS_LVDSDesStruct Compaq1280x1024Des_2[] =
+{
+  { 0, 0 },
+  { 0, 0 },
+  { 0, 0 },
+  { 0, 0 },
+  { 0, 0 },
+  { 0, 0 },
+  { 0, 0 },
+  { 0, 0 }
+};
+
+/* Clevo L285/287 (dual-link 1024x768) */
+
 static const SiS_Part2PortTblStruct SiS310_CRT2Part2_Clevo1024x768_1[] =
 {
  {{0x25,0x12,0xC9,0xDC,0xB6,0x59,0x45,0x09,0x07,0xF9,0x09,0x24}},
@@ -458,21 +531,21 @@
 
 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}},
+ {{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}}
+ {{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
 };
 
@@ -489,6 +562,8 @@
  {{0x25,0x13,0xC9,0x25,0xFF,0x59,0x45,0x09,0x07,0xF9,0x09,0x24}}
 };
 
+/* CRT2 data is std */
+
 static const SiS_LVDSDesStruct Clevo1024x768Des_1[] =
 {
   { 0, 0 },
@@ -508,9 +583,70 @@
   { 1184, 597 },
   { 1152, 622 },
   { 1232, 722 },
-  {    0,   0 },
-  {    0, 794 },
   {    0,   0 }
 };
 
+/* Asus A2xxxH _2 */
+
+static const SiS_Part2PortTblStruct SiS310_CRT2Part2_Asus1024x768_3[] =
+{
+ {{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,0x25,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,0x13,0x16,0x25,0xff,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
+ {{0x36,0x13,0x13,0x25,0xff,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
+ {{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 Asus1024x768Des_1[] =
+{
+  { 0, 0 },
+  { 0, 0 },
+  { 0, 0 },
+  { 0, 0 },
+  { 0, 0 },
+  { 0, 0 },
+  { 0, 0 }
+};
+
+static const SiS_LVDSDesStruct Asus1024x768Des_2[] =
+{
+  { 1184, 622 },
+  { 1184, 597 },
+  { 1184, 622 },
+  { 1184, 597 },
+  { 1152, 622 },
+  { 1232, 722 },
+  {    0,   0 }
+};
+
+/* CRT2 data is std */
+
+/* Uniwill N243S9, ECS A928 */
+
+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 linux-2.4.25-pre4/drivers/video/sis/osdef.h linux-2.4.25-pre5/drivers/video/sis/osdef.h
--- linux-2.4.25-pre4/drivers/video/sis/osdef.h	2003-08-25 04:44:43.000000000 -0700
+++ linux-2.4.25-pre5/drivers/video/sis/osdef.h	2004-01-15 12:10:23.000000000 -0800
@@ -1,5 +1,57 @@
-
-/* OS depending defines */
+/* $XFree86$ */
+/*
+ * OS depending defines
+ *
+ * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
+ *
+ * If distributed as part of the Linux kernel, the following license terms
+ * apply:
+ *
+ * * This program is free software; you can redistribute it and/or modify
+ * * it under the terms of the GNU General Public License as published by
+ * * the Free Software Foundation; either version 2 of the named License,
+ * * or any later version.
+ * *
+ * * This program is distributed in the hope that it will be useful,
+ * * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * * GNU General Public License for more details.
+ * *
+ * * You should have received a copy of the GNU General Public License
+ * * along with this program; if not, write to the Free Software
+ * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Otherwise, the following license terms apply:
+ *
+ * * Redistribution and use in source and binary forms, with or without
+ * * modification, are permitted provided that the following conditions
+ * * are met:
+ * * 1) Redistributions of source code must retain the above copyright
+ * *    notice, this list of conditions and the following disclaimer.
+ * * 2) Redistributions in binary form must reproduce the above copyright
+ * *    notice, this list of conditions and the following disclaimer in the
+ * *    documentation and/or other materials provided with the distribution.
+ * * 3) All advertising materials mentioning features or use of this software
+ * *    must display the following acknowledgement: "This product includes
+ * *    software developed by Thomas Winischhofer, Vienna, Austria."
+ * * 4) The name of the author may not be used to endorse or promote products
+ * *    derived from this software without specific prior written permission.
+ * *
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
+ *		Silicon Integrated Systems, Inc. (used by permission)
+ *
+ */
 
 /* The choices are: */
 
diff -urN linux-2.4.25-pre4/drivers/video/sis/sis_accel.c linux-2.4.25-pre5/drivers/video/sis/sis_accel.c
--- linux-2.4.25-pre4/drivers/video/sis/sis_accel.c	2003-11-28 10:26:21.000000000 -0800
+++ linux-2.4.25-pre5/drivers/video/sis/sis_accel.c	2004-01-15 12:10:23.000000000 -0800
@@ -1,14 +1,27 @@
 /*
- * SiS 300/630/730/540/315/550/650/740/330/660 frame buffer driver
- * for Linux kernels 2.4.x and 2.5.x
+ * SiS 300/630/730/540/315/550/65x/74x/330/760 frame buffer driver
+ * for Linux kernels 2.4.x and 2.6.x
  *
  * 2D acceleration part
  *
- * Based on the X driver's sis300_accel.c which is
- *     Copyright Xavier Ducoin <x.ducoin@lectra.com>
- *     Copyright 2002 by Thomas Winischhofer, Vienna, Austria
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the named License,
+ * or any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Based on the XFree86 driver's sis300_accel.c which is
+ *     Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
  * and sis310_accel.c which is
- *     Copyright 2002 by Thomas Winischhofer, Vienna, Austria
+ *     Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
  *
  * Author: Thomas Winischhofer <thomas@winischhofer.net>
  *			(see http://www.winischhofer.net/
@@ -114,8 +127,8 @@
    };
 #endif
 
-/* 300 series */
-
+/* 300 series ----------------------------------------------------- */
+#ifdef CONFIG_FB_SIS_300
 static void
 SiS300Sync(void)
 {
@@ -123,12 +136,6 @@
 }
 
 static void
-SiS310Sync(void)
-{
-	SiS310Idle
-}
-
-static void
 SiS300SetupForScreenToScreenCopy(int xdir, int ydir, int rop,
                                 unsigned int planemask, int trans_color)
 {
@@ -210,8 +217,16 @@
 	SiS300SetupCMDFlag(X_INC | Y_INC | BITBLT)
 	SiS300DoCMD
 }
+#endif
 
-/* 315 series ---------------------------------------------------- */
+/* 315/330 series ------------------------------------------------- */
+
+#ifdef CONFIG_FB_SIS_315
+static void
+SiS310Sync(void)
+{
+	SiS310Idle
+}
 
 static void
 SiS310SetupForScreenToScreenCopy(int xdir, int ydir, int rop,
@@ -306,6 +321,7 @@
 	SiS310SetupCMDFlag(BITBLT)
 	SiS310DoCMD
 }
+#endif
 
 /* --------------------------------------------------------------------- */
 
@@ -322,9 +338,13 @@
 void sisfb_syncaccel(void)
 {
     if(sisvga_engine == SIS_300_VGA) {
+#ifdef CONFIG_FB_SIS_300
     	SiS300Sync();
+#endif
     } else {
+#ifdef CONFIG_FB_SIS_315
     	SiS310Sync();
+#endif
     }
 }
 
@@ -332,14 +352,19 @@
 
 int fbcon_sis_sync(struct fb_info *info)
 {
+   CRITFLAGS
+
    if(!ivideo.accel)
    	return 0;
    
-   CRITFLAGS
    if(sisvga_engine == SIS_300_VGA) {
+#ifdef CONFIG_FB_SIS_300
       SiS300Sync();
+#endif
    } else {
+#ifdef CONFIG_FB_SIS_315
       SiS310Sync();
+#endif
    }
    CRITEND
    return 0;
@@ -360,26 +385,30 @@
    }
    
    switch(info->var.bits_per_pixel) {
-		case 8: col = rect->color;
-			break;
-		case 16: col = ((u32 *)(info->pseudo_palette))[rect->color];
-			 break;
-		case 32: col = ((u32 *)(info->pseudo_palette))[rect->color];
-			 break;
-	}	
+	case 8:  col = rect->color;
+		 break;
+	case 16: col = ((u32 *)(info->pseudo_palette))[rect->color];
+		 break;
+	case 32: col = ((u32 *)(info->pseudo_palette))[rect->color];
+		 break;
+   }
 
    if(sisvga_engine == SIS_300_VGA) {
-	   CRITBEGIN
-	   SiS300SetupForSolidFill(col, myrops[rect->rop], 0);
-	   SiS300SubsequentSolidFillRect(rect->dx, rect->dy, rect->width, rect->height);
-	   CRITEND
-	   SiS300Sync();
+#ifdef CONFIG_FB_SIS_300
+      CRITBEGIN
+      SiS300SetupForSolidFill(col, myrops[rect->rop], 0);
+      SiS300SubsequentSolidFillRect(rect->dx, rect->dy, rect->width, rect->height);
+      CRITEND
+      SiS300Sync();
+#endif
    } else {
-	   CRITBEGIN
-	   SiS310SetupForSolidFill(col, myrops[rect->rop], 0);
-	   SiS310SubsequentSolidFillRect(rect->dx, rect->dy, rect->width, rect->height);
-	   CRITEND
-	   SiS310Sync();
+#ifdef CONFIG_FB_SIS_315
+      CRITBEGIN
+      SiS310SetupForSolidFill(col, myrops[rect->rop], 0);
+      SiS310SubsequentSolidFillRect(rect->dx, rect->dy, rect->width, rect->height);
+      CRITEND
+      SiS310Sync();
+#endif
    }
 
 }
@@ -404,17 +433,21 @@
    else                    ydir = 1;
 
    if(sisvga_engine == SIS_300_VGA) {
+#ifdef CONFIG_FB_SIS_300
       CRITBEGIN
       SiS300SetupForScreenToScreenCopy(xdir, ydir, 3, 0, -1);
       SiS300SubsequentScreenToScreenCopy(area->sx, area->sy, area->dx, area->dy, area->width, area->height);
       CRITEND
       SiS300Sync();
+#endif
    } else {
+#ifdef CONFIG_FB_SIS_315
       CRITBEGIN
       SiS310SetupForScreenToScreenCopy(xdir, ydir, 3, 0, -1);
       SiS310SubsequentScreenToScreenCopy(area->sx, area->sy, area->dx, area->dy, area->width, area->height);
       CRITEND
       SiS310Sync();
+#endif
    }
 }
 
@@ -462,25 +495,28 @@
 	else            ydir = 1;
 
 	if(sisvga_engine == SIS_300_VGA) {
+#ifdef CONFIG_FB_SIS_300
 	   CRITBEGIN
 	   SiS300SetupForScreenToScreenCopy(xdir, ydir, 3, 0, -1);
 	   SiS300SubsequentScreenToScreenCopy(srcx, srcy, dstx, dsty, width, height);
 	   CRITEND
 	   SiS300Sync();
+#endif
 	} else {
+#ifdef CONFIG_FB_SIS_315
 	   CRITBEGIN
 	   SiS310SetupForScreenToScreenCopy(xdir, ydir, 3, 0, -1);
 	   SiS310SubsequentScreenToScreenCopy(srcx, srcy, dstx, dsty, width, height);
 	   CRITEND
 	   SiS310Sync();
-#if 0	   
+#if 0
 	   printk(KERN_INFO "sis_bmove sx %d sy %d dx %d dy %d w %d h %d\n",
 		srcx, srcy, dstx, dsty, width, height);
-#endif		
+#endif
+#endif
 	}
 }
 
-
 static void fbcon_sis_clear(struct vc_data *conp, struct display *p,
 			int srcy, int srcx, int height, int width, int color)
 {
@@ -492,17 +528,21 @@
 	height *= fontheight(p);
 
 	if(sisvga_engine == SIS_300_VGA) {
+#ifdef CONFIG_FB_SIS_300
 	   CRITBEGIN
 	   SiS300SetupForSolidFill(color, 3, 0);
 	   SiS300SubsequentSolidFillRect(srcx, srcy, width, height);
 	   CRITEND
 	   SiS300Sync();
+#endif
 	} else {
+#ifdef CONFIG_FB_SIS_315
 	   CRITBEGIN
 	   SiS310SetupForSolidFill(color, 3, 0);
 	   SiS310SubsequentSolidFillRect(srcx, srcy, width, height);
 	   CRITEND
 	   SiS310Sync();
+#endif
 	}
 }
 
@@ -577,17 +617,21 @@
 	srcy *= fontheight(p);
 
 	if(sisvga_engine == SIS_300_VGA) {
+#ifdef CONFIG_FB_SIS_300
 	   CRITBEGIN
 	   SiS300SetupForSolidFill(0, 0x0a, 0);
 	   SiS300SubsequentSolidFillRect(srcx, srcy, fontwidth(p), fontheight(p));
 	   CRITEND
 	   SiS300Sync();
+#endif
 	} else {
+#ifdef CONFIG_FB_SIS_315
 	   CRITBEGIN
 	   SiS310SetupForSolidFill(0, 0x0a, 0);
 	   SiS310SubsequentSolidFillRect(srcx, srcy, fontwidth(p), fontheight(p));
 	   CRITEND
 	   SiS310Sync();
+#endif
 	}
 }
 
diff -urN linux-2.4.25-pre4/drivers/video/sis/sis_accel.h linux-2.4.25-pre5/drivers/video/sis/sis_accel.h
--- linux-2.4.25-pre4/drivers/video/sis/sis_accel.h	2003-11-28 10:26:21.000000000 -0800
+++ linux-2.4.25-pre5/drivers/video/sis/sis_accel.h	2004-01-15 12:10:23.000000000 -0800
@@ -4,11 +4,24 @@
  *
  * 2D acceleration part
  *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the named License,
+ * or any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
+ *
  * Based on the X driver's sis300_accel.h which is
- *     Copyright Xavier Ducoin <x.ducoin@lectra.com>
- *     Copyright 2002 by Thomas Winischhofer, Vienna, Austria
+ *     Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
  * and sis310_accel.h which is
- *     Copyright 2002 by Thomas Winischhofer, Vienna, Austria
+ *     Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
  *
  * Author:   Thomas Winischhofer <thomas@winischhofer.net>:
  *			(see http://www.winischhofer.net/
diff -urN linux-2.4.25-pre4/drivers/video/sis/sis_main.c linux-2.4.25-pre5/drivers/video/sis/sis_main.c
--- linux-2.4.25-pre4/drivers/video/sis/sis_main.c	2003-11-28 10:26:21.000000000 -0800
+++ linux-2.4.25-pre5/drivers/video/sis/sis_main.c	2004-01-15 12:10:23.000000000 -0800
@@ -1,14 +1,28 @@
 /*
- * SiS 300/630/730/540/315/550/650/651/M650/661FX/M661FX/740/741/330
+ * SiS 300/630/730/540/315/550/650/651/M650/661FX/M661FX/740/741/M741/330/760
  * frame buffer driver for Linux kernels 2.4.x and 2.5.x
  *
- * (C) 1999 Silicon Integrated Systems, Inc.
- * (C) 2001-2003 Thomas Winischhofer, Vienna, Austria.
+ * Copyright (C) 2001-2004 Thomas Winischhofer, Vienna, Austria.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the named License,
+ * or any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
  *
  * Author:   	Thomas Winischhofer <thomas@winischhofer.net>
  *
  * Author of code base:
  *		SiS (www.sis.com.tw)
+ *	 	Copyright (C) 1999 Silicon Integrated Systems, Inc.
  *
  * See http://www.winischhofer.net/ for more information and updates
  *
@@ -73,8 +87,8 @@
 #include "sis.h"
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,69)
-#error "This version of sisfb requires at least 2.5.69"
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
+#error "This version of sisfb requires at least 2.6.0"
 #endif
 #endif
 
@@ -120,7 +134,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;
@@ -162,7 +176,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;
@@ -193,6 +207,12 @@
 		case SIS_740:
 			nbridge_id = PCI_DEVICE_ID_SI_740;
 			break;
+		case SIS_661:
+			nbridge_id = PCI_DEVICE_ID_SI_660;
+			break;
+		case SIS_741:
+			nbridge_id = PCI_DEVICE_ID_SI_741;
+			break;
 		case SIS_660:
 			nbridge_id = PCI_DEVICE_ID_SI_660;
 			break;
@@ -524,16 +544,12 @@
 
 #ifdef CONFIG_FB_SIS_300
    if(sisvga_engine == SIS_300_VGA) {
-       if(!(sisbios_mode[myindex].chipset & MD_SIS300)) {
-           return(-1);
-       }
+      if(!(sisbios_mode[myindex].chipset & MD_SIS300)) return(-1);
    }
 #endif
 #ifdef CONFIG_FB_SIS_315
    if(sisvga_engine == SIS_315_VGA) {
-       if(!(sisbios_mode[myindex].chipset & MD_SIS315)) {
-	   return(-1);
-       }
+      if(!(sisbios_mode[myindex].chipset & MD_SIS315)) return(-1);
    }
 #endif
 
@@ -542,230 +558,71 @@
    switch (vbflags & VB_DISPTYPE_DISP2) {
      case CRT2_LCD:
 	switch (sishw_ext.ulCRT2LCDType) {
-	case LCD_640x480:
-		xres =  640; yres =  480;  break;
-	case LCD_800x600:
-		xres =  800; yres =  600;  break;
-        case LCD_1024x600:
-		xres = 1024; yres =  600;  break;		
-	case LCD_1024x768:
-	 	xres = 1024; yres =  768;  break;
-	case LCD_1152x768:
-		xres = 1152; yres =  768;  break;		
-	case LCD_1280x960:
-	        xres = 1280; yres =  960;  break;		
-	case LCD_1280x768:
-		xres = 1280; yres =  768;  break;
-	case LCD_1280x1024:
-		xres = 1280; yres = 1024;  break;
-	case LCD_1400x1050:
-		xres = 1400; yres = 1050;  break;		
-	case LCD_1600x1200:
-		xres = 1600; yres = 1200;  break;
-	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;
+	case LCD_640x480:  xres =  640; yres =  480;  break;
+	case LCD_800x600:  xres =  800; yres =  600;  break;
+        case LCD_1024x600: xres = 1024; yres =  600;  break;
+	case LCD_1024x768: xres = 1024; yres =  768;  break;
+	case LCD_1152x768: xres = 1152; yres =  768;  break;
+	case LCD_1280x960: xres = 1280; yres =  960;  break;
+	case LCD_1280x768: xres = 1280; yres =  768;  break;
+	case LCD_1280x1024:xres = 1280; yres = 1024;  break;
+	case LCD_1400x1050:xres = 1400; yres = 1050;  break;
+	case LCD_1600x1200:xres = 1600; yres = 1200;  break;
+	case LCD_320x480:  xres =  320; yres =  480;  break; /* FSTN (old) */
+	case LCD_640x480_2:
+	case LCD_640x480_3:xres =  640; yres =  480;  break; /* FSTN (new) */
+	default:           xres =    0; yres =    0;  break;
 	}
 
 	if(SiS_Pr.SiS_CustomT == CUT_BARCO1366) {
-	   	xres = 1360; yres = 1024;
+	   xres = 1360; yres = 1024;
 	}
 
 	if(SiS_Pr.SiS_CustomT == CUT_PANEL848) {
-	   	xres = 848;  yres =  480;
+	   xres = 848;  yres =  480;
 	} else {
-	   if(sisbios_mode[myindex].xres > xres) {
-	        return(-1);
-	   }
-           if(myres > yres) {
-	        return(-1);
-	   }
+	   if(sisbios_mode[myindex].xres > xres) return(-1);
+           if(myres > yres) return(-1);
 	}
 
 	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(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((myres != 400) && (myres != 480))
-		          	return -1;
-			if(SiS_Pr.SiS_CustomT == CUT_PANEL848) {
-			   if(myres == 400)
-			 	return(-1);
-			}
-	       		break;
-	   	case 800:
-		       	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((myres != 600) && (myres != 768))
-		          	return(-1);
-			if((myres == 600) &&
-			   (sishw_ext.ulCRT2LCDType != LCD_1024x600))
-			   	return(-1);
-			break;
-		case 1152:
-			if(myres != 768) return(-1);
-			if(sishw_ext.ulCRT2LCDType != LCD_1152x768) return(-1);
-			break;
-	   	case 1280:
-		   	if((myres != 768) && (myres != 1024))
-		          	return(-1);
-			if((myres == 768) &&
-			   (sishw_ext.ulCRT2LCDType != LCD_1280x768))
-			   	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(myres != 1050) return(-1);
-			if(SiS_Pr.SiS_CustomT == CUT_PANEL848) return(-1);
-			break;
-	   	case 1600:
-		   	if(myres != 1200) return(-1);
-			if(SiS_Pr.SiS_CustomT == CUT_PANEL848) return(-1);
-			break;
-	   	default:
-		        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(myres != 384) return(-1);
-	       		break;
-	   	case 640:
-		       	if((myres != 400) && (myres != 480))
-		          	return(-1);
-	       		break;
-	   	case 800:
-		       	if(myres != 600) return(-1);
-	       		break;
-	   	case 1024:
-		       	if(myres != 768) return(-1);
-			break;
-	   	case 1280:
-		   	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(myres != 1050) return(-1);
-			break;
-	   	case 1600:
-		   	if(myres != 1200) return(-1);
-			break;
-	   	default:
-		        return(-1);
+	   if(sisbios_mode[myindex].xres == 320) {
+	      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_GetModeID_LCD(sisvga_engine, vbflags, sisbios_mode[myindex].xres, sisbios_mode[myindex].yres,
+	                     0, sisfb_fstn, SiS_Pr.SiS_CustomT, xres, yres) < 0x14) {
+	   return(-1);
+	}
 	break;
 
      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:
-		if((myres != 400) && (myres != 480))
-		       	return(-1);
-		break;
-	case 720:
-		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(vbflags & VB_301) return(-1);
-		if(vbflags & VB_CHRONTEL) {
-		    	if(ivideo.chip < SIS_315H) {
-				return(-1);
-		    	}
-		}
-		break;
-	default:
-		return(-1);
+	if(SiS_GetModeID_TV(sisvga_engine, vbflags, sisbios_mode[myindex].xres,
+	                    sisbios_mode[myindex].yres, 0) < 0x14) {
+	   return(-1);
 	}
 	break;
 
      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);
+        if(SiS_GetModeID_VGA2(sisvga_engine, vbflags, sisbios_mode[myindex].xres,
+	                    sisbios_mode[myindex].yres, 0) < 0x14) {
+	   return(-1);
 	}
-	break;	
+	break;
      }
+
      return(myindex);
 }
 
@@ -889,8 +746,9 @@
 	      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);
+		 printk(KERN_INFO "sisfb: Special timing for %s %s forced (\"%s\")\n",
+		 	mycustomttable[i].vendorName, mycustomttable[i].cardName,
+		 	mycustomttable[i].optionName);
 		 break;
 	      }
 	      i++;
@@ -925,22 +783,40 @@
    }
 }
 
-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;
@@ -961,7 +837,7 @@
    else 	   return TRUE;
 }
 
-static BOOLEAN sisfb_CheckVBRetrace(void) 
+static BOOLEAN sisfb_CheckVBRetrace(void)
 {
    if(ivideo.currentvbflags & VB_DISPTYPE_DISP2) {
       if(sisfb_bridgeisslave()) {
@@ -1047,7 +923,7 @@
 
    if(ivideo.currentvbflags & CRT2_LCD) {
 
-      if(ivideo.vbflags & (VB_301LV|VB_302LV)) {
+      if(ivideo.vbflags & (VB_301LV|VB_302LV|VB_302ELV)) {
 	 if(backlight) {
 	    SiS_SiS30xBLOn(&SiS_Pr, &sishw_ext);
 	 } else {
@@ -1125,7 +1001,7 @@
 		      struct fb_info *info)
 {
 	unsigned int htotal = 0, vtotal = 0; 
-	double drate = 0, hrate = 0;
+	unsigned int drate = 0, hrate = 0;
 	int found_mode = 0;
 	int old_mode;
 	u32 pixclock;
@@ -1153,9 +1029,9 @@
 	}
 
 	if(pixclock && htotal && vtotal) {
-	   drate = 1E12 / pixclock;
-	   hrate = drate / htotal;
-	   ivideo.refresh_rate = (unsigned int) (hrate / vtotal * 2 + 0.5);
+	   drate = 1000000000 / pixclock;
+	   hrate = (drate * 1000) / htotal;
+	   ivideo.refresh_rate = (unsigned int) (hrate * 2 / vtotal);
 	} else ivideo.refresh_rate = 60;
 
 #if 0
@@ -1358,14 +1234,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, maxyres;
 
 	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:
@@ -1431,16 +1307,16 @@
 	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;
+	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);
@@ -1502,34 +1378,42 @@
 	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;
 
-	if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
-		VT <<= 1;
+	if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
+	   VT <<= 1;
 	}
-	hrate = (double) ivideo.refresh_rate * (double) VT / 2;
-	drate = hrate * HT;
-	var->pixclock = (u32) (1E12 / drate);
+	hrate = ivideo.refresh_rate * VT / 2;
+	drate = (hrate * HT) / 1000;
+	var->pixclock = (u32) (1000000000 / drate);
 
 	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;
-	    }
+	   maxyres = ivideo.heapstart / (var->xres * (var->bits_per_pixel >> 3));
+	   if(maxyres > 32767) maxyres = 32767;
+	   if(sisfb_max) {
+	      var->yres_virtual = maxyres;
+	   } else {
+	      if(var->yres_virtual > maxyres) {
+	         var->yres_virtual = maxyres;
+	      }
+	   }
+	   if(var->yres_virtual <= var->yres) {
+	      var->yres_virtual = var->yres;
+	   }
 	} else
-	    var->yres_virtual = var->yres;
+	   var->yres_virtual = var->yres;
 
 }
 
@@ -1963,7 +1847,7 @@
 		red >>= 8;
 		green >>= 8;
 		blue >>= 8;
-		((u32 *) (info->pseudo_palette))[regno] = 
+		((u32 *) (info->pseudo_palette))[regno] =
 			(red << 16) | (green << 8) | (blue);
 		break;
 	}
@@ -1986,7 +1870,7 @@
                            struct fb_info *info)
 {
 	unsigned int htotal = 0, vtotal = 0, myrateindex = 0;
-	double drate = 0, hrate = 0;
+	unsigned int drate = 0, hrate = 0, maxyres;
 	int found_mode = 0;
 	int refresh_rate, search_idx;
 	BOOLEAN recalc_clock = FALSE;
@@ -2066,9 +1950,9 @@
 	} else if( (ivideo.current_htotal == htotal) &&		/* x=x & y=y & c=c -> assume depth change */
 	    	   (ivideo.current_vtotal == vtotal) &&
 	    	   (ivideo.current_pixclock == pixclock) ) {
-		drate = 1E12 / pixclock;
-	   	hrate = drate / htotal;
-	   	refresh_rate = (unsigned int) (hrate / vtotal * 2 + 0.5);
+		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) ) {
@@ -2081,9 +1965,9 @@
 		}
 		recalc_clock = TRUE;
 	} else if((pixclock) && (htotal) && (vtotal)) {
-	   	drate = 1E12 / pixclock;
-	   	hrate = drate / htotal;
-	   	refresh_rate = (unsigned int) (hrate / vtotal * 2 + 0.5);
+		drate = 1000000000 / pixclock;
+	   	hrate = (drate * 1000) / htotal;
+	   	refresh_rate = (unsigned int) (hrate * 2 / vtotal);
 	} else if(ivideo.current_refresh_rate) {
 		refresh_rate = ivideo.current_refresh_rate;
 		recalc_clock = TRUE;
@@ -2097,7 +1981,7 @@
 	/* Eventually recalculate timing and clock */
 	if(recalc_clock) {
 	   if(!myrateindex) myrateindex = sisbios_mode[search_idx].rate_idx;
-	   var->pixclock = (u32) (1E12 / sisfb_mode_rate_to_dclock(&SiS_Pr, &sishw_ext,
+	   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,
@@ -2131,25 +2015,31 @@
 		var->xres_virtual = var->xres;
 	
 	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));
+	   maxyres = ivideo.heapstart / (var->xres * (var->bits_per_pixel >> 3));
+	   if(maxyres > 32767) maxyres = 32767;
+	   if(sisfb_max) {
+	      var->yres_virtual = maxyres;
+	   } else {
+	      if(var->yres_virtual > maxyres) {
+	         var->yres_virtual = maxyres;
+	      }
+	   }
 	   if(var->yres_virtual <= var->yres) {
-	    	/* TW: Paranoia check */
-	        var->yres_virtual = var->yres;
+	      var->yres_virtual = var->yres;
 	   }
 	} else {
-	   if(var->yres != var->yres_virtual)
-		var->yres_virtual = var->yres;
+	   if(var->yres != var->yres_virtual) {
+	      var->yres_virtual = var->yres;
+	   }
 	   var->xoffset = 0;
 	   var->yoffset = 0;
 	}
 	
 	/* Truncate offsets to maximum if too high */
-	if (var->xoffset > var->xres_virtual - var->xres)
+	if(var->xoffset > var->xres_virtual - var->xres)
 		var->xoffset = var->xres_virtual - var->xres - 1;
 
-	if (var->yoffset > var->yres_virtual - var->yres)
+	if(var->yoffset > var->yres_virtual - var->yres)
 		var->yoffset = var->yres_virtual - var->yres - 1;
 	
 	/* Set everything else to 0 */
@@ -2353,6 +2243,12 @@
 			x.sisfb_currentvbflags = ivideo.currentvbflags;
 			x.sisfb_scalelcd = SiS_Pr.UsePanelScaler;
 			x.sisfb_specialtiming = SiS_Pr.SiS_CustomT;
+			x.sisfb_haveemi = SiS_Pr.HaveEMI ? 1 : 0;
+			x.sisfb_haveemilcd = SiS_Pr.HaveEMILCD ? 1 : 0;
+			x.sisfb_emi30 = SiS_Pr.EMI_30;
+			x.sisfb_emi31 = SiS_Pr.EMI_31;
+			x.sisfb_emi32 = SiS_Pr.EMI_32;
+			x.sisfb_emi33 = SiS_Pr.EMI_33;
 			if(copy_to_user((void *)arg, &x, sizeof(x)))
 				return -EFAULT;
 	                break;
@@ -2365,6 +2261,25 @@
 				return put_user(0UL, (unsigned long *) arg);
 			break;
 		}
+	   case SISFB_GET_AUTOMAXIMIZE:
+	        {
+			if(sisfb_max)
+				return put_user(1UL, (unsigned long *) arg);
+			else
+				return put_user(0UL, (unsigned long *) arg);
+			break;
+		}
+	   case SISFB_SET_AUTOMAXIMIZE:
+	        {
+			unsigned long newmax;
+
+			if(copy_from_user(&newmax, (unsigned long *)arg, sizeof(newmax)))
+				return -EFAULT;
+
+			if(newmax) sisfb_max = 1;
+			else	   sisfb_max = 0;
+			break;
+		}
 	   default:
 		return -EINVAL;
 	}
@@ -2378,7 +2293,7 @@
 	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	
@@ -2402,9 +2317,9 @@
 	fix->type        = FB_TYPE_PACKED_PIXELS;
 	fix->type_aux    = 0;
 	if(ivideo.video_bpp == 8)
-		fix->visual = FB_VISUAL_PSEUDOCOLOR;
+	   fix->visual = FB_VISUAL_PSEUDOCOLOR;
 	else
-		fix->visual = FB_VISUAL_TRUECOLOR;
+	   fix->visual = FB_VISUAL_TRUECOLOR;
 	fix->xpanstep    = 0;
 
         if(sisfb_ypan) 	 fix->ypanstep = 1;
@@ -2415,7 +2330,7 @@
 	fix->mmio_len    = sisfb_mmio_size;
 	if(sisvga_engine == SIS_300_VGA) 
 	   fix->accel    = FB_ACCEL_SIS_GLAMOUR;
-	else if((ivideo.chip == SIS_330) || (ivideo.chip == SIS_660) || (ivideo.chip == SIS_760))
+	else if((ivideo.chip == SIS_330) || (ivideo.chip == SIS_760))
 	   fix->accel    = FB_ACCEL_SIS_XABRE;
 	else
 	   fix->accel    = FB_ACCEL_SIS_GLAMOUR_2;
@@ -2547,179 +2462,42 @@
 #endif  /* CONFIG_FB_SIS_300 */
 
 
-#ifdef CONFIG_FB_SIS_315    /* for SiS 315/550/650/740/330/660/760 */
+#ifdef CONFIG_FB_SIS_315    /* for SiS 315/550/650/740/330/661/741/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) {
-
-#ifdef LINUXBIOS
-
-#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) ||
-				     (pdev->device == PCI_DEVICE_ID_SI_650) ||
-				     (pdev->device == PCI_DEVICE_ID_SI_740) ||
-				     (pdev->device == PCI_DEVICE_ID_SI_660) ||
-				     (pdev->device == PCI_DEVICE_ID_SI_760))) {
-				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;
-
-				/* Initialize SR14 "by hand" */
-				inSISIDXREG(SISSR, IND_SIS_DRAM_SIZE, reg);
-				reg &= 0xC0;
-				switch (pci_data) {
-				   case BRI_DRAM_SIZE_4MB:
-					reg |= SIS550_DRAM_SIZE_4MB;
-					break;
-				   case BRI_DRAM_SIZE_8MB:
-					reg |= SIS550_DRAM_SIZE_8MB;
-					break;
-				   case BRI_DRAM_SIZE_16MB:
-					reg |= SIS550_DRAM_SIZE_16MB;
-					break;
-				   case BRI_DRAM_SIZE_32MB:
-					reg |= SIS550_DRAM_SIZE_32MB;
-					break;
-				   case BRI_DRAM_SIZE_64MB:
-					reg |= SIS550_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;
-
-#else
+	if(ivideo.chip == SIS_550 ||
+	   ivideo.chip == SIS_650 ||
+	   ivideo.chip == SIS_740) {
 
                 inSISIDXREG(SISSR, IND_SIS_DRAM_SIZE, reg);
-		switch (reg & SIS550_DRAM_SIZE_MASK) {
-		   case SIS550_DRAM_SIZE_4MB:
-			ivideo.video_size = 0x400000;   break;
-		   case SIS550_DRAM_SIZE_8MB:
-			ivideo.video_size = 0x800000;   break;
-		   case SIS550_DRAM_SIZE_16MB:
-			ivideo.video_size = 0x1000000;  break;
-		   case SIS550_DRAM_SIZE_24MB:
-			ivideo.video_size = 0x1800000;  break;
-		   case SIS550_DRAM_SIZE_32MB:
-			ivideo.video_size = 0x2000000;	break;
-		   case SIS550_DRAM_SIZE_64MB:
-			ivideo.video_size = 0x4000000;	break;
-		   case SIS550_DRAM_SIZE_96MB:
-			ivideo.video_size = 0x6000000;	break;
-		   case SIS550_DRAM_SIZE_128MB:
-			ivideo.video_size = 0x8000000;	break;
-		   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.
-			 */
-		        printk(KERN_INFO
-			       "sisfb: Warning: Could not determine memory size, "
-			       "now reading from PCI config\n");
-			pdev_valid = 0;
-
-#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) ) {
+		reg &= 0x3f;
+		reg++;
+		reg <<= 2;
+		ivideo.video_size = reg << 20;
+		return 0;
 
-				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;
-				/* TW: Initialize SR14=IND_SIS_DRAM_SIZE */
-				inSISIDXREG(SISSR, IND_SIS_DRAM_SIZE, reg);
-				reg &= 0xC0;
-				switch (pci_data) {
-				   case BRI_DRAM_SIZE_4MB:
-					reg |= SIS550_DRAM_SIZE_4MB;  break;
-				   case BRI_DRAM_SIZE_8MB:
-					reg |= SIS550_DRAM_SIZE_8MB;  break;
-				   case BRI_DRAM_SIZE_16MB:
-					reg |= SIS550_DRAM_SIZE_16MB; break;
-				   case BRI_DRAM_SIZE_32MB:
-					reg |= SIS550_DRAM_SIZE_32MB; break;
-				   case BRI_DRAM_SIZE_64MB:
-					reg |= SIS550_DRAM_SIZE_64MB; break;
-				   default:
-				   	printk(KERN_INFO "sisfb: Unable to determine memory size, giving up.\n");
-					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");
-				return -1;
-			}
-			return 0;
-		}
-#endif
+	} else if(ivideo.chip == SIS_661 ||
+	          ivideo.chip == SIS_741 ||
+		  ivideo.chip == SIS_660 ||
+		  ivideo.chip == SIS_760) {
+
+		inSISIDXREG(SISCR, 0x79, reg);
+		reg &= 0xf0;
+		reg >>= 4;
+		ivideo.video_size = (1 << reg) << 20;
 		return 0;
 
 	} else {	/* 315, 330 */
 
 	        inSISIDXREG(SISSR, IND_SIS_DRAM_SIZE, reg);
-		switch ((reg & SIS315_DRAM_SIZE_MASK) >> 4) {
-		   case SIS315_DRAM_SIZE_2MB:
-			ivideo.video_size = 0x200000;
-			break;
-		   case SIS315_DRAM_SIZE_4MB:
-			ivideo.video_size = 0x400000;
-			break;
-		   case SIS315_DRAM_SIZE_8MB:
-			ivideo.video_size = 0x800000;
-			break;
-		   case SIS315_DRAM_SIZE_16MB:
-			ivideo.video_size = 0x1000000;
-			break;
-		   case SIS315_DRAM_SIZE_32MB:
-			ivideo.video_size = 0x2000000;
-			break;
-		   case SIS315_DRAM_SIZE_64MB:
-			ivideo.video_size = 0x4000000;
-			break;
-		   case SIS315_DRAM_SIZE_128MB:
-			ivideo.video_size = 0x8000000;
-			break;
-		   default:
-			return -1;
-		}
-		
+		ivideo.video_size = (1 << ((reg & 0xf0) >> 4)) << 20;
+
 		reg &= SIS315_DUAL_CHANNEL_MASK;
 		reg >>= 2;
-		
+
 		if(ivideo.chip == SIS_330) {
 
 		   if(reg) ivideo.video_size <<= 1;
@@ -2757,7 +2535,7 @@
 
 	if(sisvga_engine == SIS_300_VGA) {
 	
-		inSISIDXREG(SISSR, IND_SIS_SCRATCH_REG_17, sr17); 
+		inSISIDXREG(SISSR, IND_SIS_SCRATCH_REG_17, sr17);
 	      
 		if ((sr17 & 0x0F) && (ivideo.chip != SIS_300)) {
 	
@@ -2817,9 +2595,8 @@
 	/* TW: Detect/set TV plug & type */
 	if(sisfb_tvplug != -1)
 	        ivideo.vbflags |= sisfb_tvplug;
-	if (cr32 & SIS_VB_HIVISION) 
-		ivideo.vbflags |= (TV_HIVISION | TV_SVIDEO);
-	else if (cr32 & SIS_VB_SVIDEO)
+
+	if (cr32 & SIS_VB_SVIDEO)
 		ivideo.vbflags |= TV_SVIDEO;
 	else if (cr32 & SIS_VB_COMPOSITE)
 		ivideo.vbflags |= TV_AVIDEO;
@@ -2833,10 +2610,10 @@
 				ivideo.vbflags |= TV_PAL;
 			else
 				ivideo.vbflags |= TV_NTSC;
-		} else if((ivideo.chip <= SIS_315PRO) || (ivideo.chip == SIS_330)) {
+		} else if((ivideo.chip <= SIS_315PRO) || (ivideo.chip >= SIS_330)) {
 
-                	inSISIDXREG(SISCR, 0x38, temp);
-			if(temp & 0x10)
+                	inSISIDXREG(SISSR, 0x38, temp);
+			if(temp & 0x01)
 				ivideo.vbflags |= TV_PAL;
 			else
 				ivideo.vbflags |= TV_NTSC;
@@ -2878,14 +2655,21 @@
 	   case 0x01:
 		ivideo.hasVB = HASVB_301;
 		inSISIDXREG(SISPART4, 0x01, reg);
-		if(reg < 0xb0) { 
+		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);
+			inSISIDXREG(SISPART4,0x23,reg);
+			if(!(reg & 0x02)) {
+			   sishw_ext.Is301BDH = TRUE;
+			   ivideo.vbflags |= VB_30xBDH;
+			   printk(KERN_INFO "%s SiS301B-DH %s\n", stdstr, bridgestr);
+			} else {
+			   printk(KERN_INFO "%s SiS301B %s\n", stdstr, bridgestr);
+			}
 		} else if(reg < 0xd0) {
 		 	ivideo.vbflags |= VB_301C;
 			sishw_ext.ujVBChipID = VB_CHIP_301C;
@@ -2895,9 +2679,16 @@
 			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);
+		        inSISIDXREG(SISPART4,0x39,reg);
+			if(reg == 0xff) {
+			   ivideo.vbflags |= VB_302LV;
+			   sishw_ext.ujVBChipID = VB_CHIP_302LV;
+			   printk(KERN_INFO "%s SiS302LV %s\n", stdstr, bridgestr);
+			} else {
+			   ivideo.vbflags |= VB_302ELV;
+			   sishw_ext.ujVBChipID = VB_CHIP_302ELV;
+			   printk(KERN_INFO "%s SiS302ELV %s\n", stdstr, bridgestr);
+			}
 		}
 		break;
 	   case 0x02:
@@ -2906,7 +2697,14 @@
 		if(reg < 0xd0) {
 			ivideo.vbflags |= VB_302B;
 			sishw_ext.ujVBChipID = VB_CHIP_302B;
-			printk(KERN_INFO "%s SiS302B %s\n", stdstr, bridgestr);
+			inSISIDXREG(SISPART4,0x23,reg);
+		  	if(!(reg & 0x02)) {
+			   sishw_ext.Is301BDH = TRUE;
+			   ivideo.vbflags |= VB_30xBDH;
+			   printk(KERN_INFO "%s SiS302B-DH %s\n", stdstr, bridgestr);
+			} else {
+			   printk(KERN_INFO "%s SiS302B %s\n", stdstr, bridgestr);
+			}
 		} else if(reg < 0xe0) {
 		 	ivideo.vbflags |= VB_301LV;
 			sishw_ext.ujVBChipID = VB_CHIP_301LV;
@@ -2918,16 +2716,7 @@
 		}
 		break;
 	}
-	
-	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;
@@ -2958,7 +2747,7 @@
 				printk(KERN_INFO "%s %s and %s\n", stdstr, lvdsstr, chrstr);
 				break;
 			}
-		} else {
+		} else if(ivideo.chip < SIS_661) {
 			switch (reg) {
 	 	   	   case SIS310_EXTERNAL_CHIP_LVDS:
 				ivideo.hasVB = HASVB_LVDS;
@@ -2982,21 +2771,88 @@
 	} 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;
@@ -3008,12 +2864,12 @@
 SiS_Sense30x(void)
 {
   u8 backupP4_0d,backupP2_00;
-  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;
+  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";
@@ -3027,77 +2883,79 @@
   if(sisvga_engine == SIS_300_VGA) {
 
 	if(ivideo.vbflags & (VB_301B|VB_301C|VB_302B|VB_301LV|VB_302LV)) {
-	   	testvga2_tempbh = 0x01; testvga2_tempbl = 0x90;
-	   	testsvhs_tempbh = 0x01; testsvhs_tempbl = 0x6b;
-	   	testcvbs_tempbh = 0x01; testcvbs_tempbl = 0x74;
+	   	vga2_bh = 0x01; vga2_bl = 0x90;
+	   	svhs_bh = 0x01; svhs_bl = 0x6b;
+	   	cvbs_bh = 0x01; cvbs_bl = 0x74;
 	} else {
-		testvga2_tempbh = 0x00; testvga2_tempbl = 0xd1;
-        	testsvhs_tempbh = 0x00; testsvhs_tempbl = 0xb9;
-		testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xb3;
+		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 = 0x04;	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)) {
-	   	testvga2_tempbh = 0x00; testvga2_tempbl = 0x00;
-	   	testvga2_tempch = 0x00; testvga2_tempcl = 0x00;
+	   	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 {
 
-	if(ivideo.vbflags & (VB_301B|VB_301C|VB_302B)) {
-		testvga2_tempbh = 0x01; testvga2_tempbl = 0x90;
-		testsvhs_tempbh = 0x01; testsvhs_tempbl = 0x6b;
-		testcvbs_tempbh = 0x01; testcvbs_tempbl = 0x74;
+	if(ivideo.vbflags & (VB_301B|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_301C|VB_302ELV)) {
+	      	vga2_bh = 0x01; vga2_bl = 0x90;
+	      	svhs_bh = 0x01; svhs_bl = 0x6b;
+	      	cvbs_bh = 0x01; cvbs_bl = 0x10;
 	} else if(ivideo.vbflags & (VB_301LV|VB_302LV)) {
-	      	testvga2_tempbh = 0x00; testvga2_tempbl = 0x00;
-	      	testsvhs_tempbh = 0x02; testsvhs_tempbl = 0x00;
-	      	testcvbs_tempbh = 0x01; testcvbs_tempbl = 0x00;
+	      	vga2_bh = 0x00; vga2_bl = 0x00;
+	      	svhs_bh = 0x02; svhs_bl = 0x00;
+	      	cvbs_bh = 0x01; cvbs_bl = 0x00;
 	} else {
-		testvga2_tempbh = 0x00; testvga2_tempbl = 0xd1;
-        	testsvhs_tempbh = 0x00; testsvhs_tempbl = 0xb9;
-		testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xb3;
-	}
-	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 = 0xd1;
+        	svhs_bh = 0x00; svhs_bl = 0xb9;
+		cvbs_bh = 0x00; cvbs_bl = 0xb3;
+		inSISIDXREG(SISPART4,0x01,myflag);
+	        if(myflag & 0x04) {
+	           vga2_bh = 0x00; vga2_bl = 0xfd;
+	           svhs_bh = 0x00; svhs_bl = 0xdd;
+	           cvbs_bh = 0x00; cvbs_bl = 0xee;
+	        }
 	}
-	if(ivideo.vbflags & (VB_301LV|VB_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|VB_302ELV)) {
+	   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 = 0x04; 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) {
+    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(testvga2_tempbl, testvga2_tempbh,
-                           testvga2_tempcl, testvga2_tempch))
+             if(SISDoSense(vga2_bl, vga2_bh, vga2_cl, vga2_ch))
 	        result++;
           }
 	  if((result == 0) || (result >= 2)) break;
@@ -3110,12 +2968,15 @@
        }
     }
 
+    if(ivideo.vbflags & (VB_301C|VB_302ELV)) {
+       orSISIDXREG(SISPART4,0x0d,0x04);
+    }
+
     haveresult = 0;
     for(j = 0; j < 10; j++) {
        result = 0;
        for(i = 0; i < 3; i++) {
-          if(SISDoSense(testsvhs_tempbl, testsvhs_tempbh,
-                        testsvhs_tempcl, testsvhs_tempch))
+          if(SISDoSense(svhs_bl, svhs_bh, svhs_cl, svhs_ch))
 	        result++;
        }
        if((result == 0) || (result >= 2)) break;
@@ -3133,8 +2994,7 @@
        	for(j = 0; j < 10; j++) {
            result = 0;
            for(i = 0; i < 3; i++) {
-              if(SISDoSense(testcvbs_tempbl, testcvbs_tempbh,
-	                    testcvbs_tempcl, testcvbs_tempch))
+              if(SISDoSense(cvbs_bl, cvbs_bh, cvbs_cl, cvbs_ch))
 	        result++;
            }
            if((result == 0) || (result >= 2)) break;
@@ -3173,7 +3033,7 @@
        SiS_SetChrontelGPIO(&SiS_Pr, 0x9c);	/* Set general purpose IO for Chrontel communication */
        SiS_DDC2Delay(&SiS_Pr, 1000);
        temp1 = SiS_GetCH700x(&SiS_Pr, 0x25);
-       /* TW: See Chrontel TB31 for explanation */
+       /* See Chrontel TB31 for explanation */
        temp2 = SiS_GetCH700x(&SiS_Pr, 0x0e);
        if(((temp2 & 0x07) == 0x01) || (temp2 & 0x04)) {
 	  SiS_SetCH700x(&SiS_Pr, 0x0b0e);
@@ -3270,7 +3130,7 @@
 	case 0x04:
 	     printk(KERN_INFO "%s SCART output\n", stdstr);
 	     orSISIDXREG(SISCR, 0x32, 0x04);
-	     andSISIDXREG(SISCR, 0x32, ~0x03);		
+	     andSISIDXREG(SISCR, 0x32, ~0x03);
              break;
 	default:
 	     andSISIDXREG(SISCR, 0x32, ~0x07);
@@ -3305,7 +3165,7 @@
 	u32            agp_phys;
 #endif
 #endif
-/* TW: The heap start is either set manually using the "mem" parameter, or
+/*     The heap start is either set manually using the "mem" parameter, or
  *     defaults as follows:
  *     -) If more than 16MB videoRAM available, let our heap start at 12MB.
  *     -) If more than  8MB videoRAM available, let our heap start at  8MB.
@@ -3344,7 +3204,7 @@
 
 #ifdef CONFIG_FB_SIS_315
      if (sisvga_engine == SIS_315_VGA) {
-        /* TW: Now initialize the 310 series' command queue mode.
+        /* Now initialize the 310 series' command queue mode.
 	 * 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
@@ -3814,7 +3674,7 @@
 
 static void sisfb_pre_setmode(void)
 {
-	u8 cr30 = 0, cr31 = 0, cr33 = 0;
+	u8 cr30 = 0, cr31 = 0, cr33 = 0, cr35 = 0;
 	
 	ivideo.currentvbflags &= (VB_VIDEOBRIDGE | VB_DISPTYPE_DISP2);
 
@@ -3830,12 +3690,7 @@
 	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);
-			ivideo.currentvbflags |= (TV_HIVISION | TV_SVIDEO);
-			ivideo.TV_type = TVMODE_HIVISION;
-			ivideo.TV_plug = TVPLUG_SVIDEO;
-		} else if (ivideo.vbflags & TV_SVIDEO) {
+		if (ivideo.vbflags & TV_SVIDEO) {
 			cr30 = (SIS_VB_OUTPUT_SVIDEO | SIS_SIMULTANEOUS_VIEW_ENABLE);
 			ivideo.currentvbflags |= TV_SVIDEO;
 			ivideo.TV_plug = TVPLUG_SVIDEO;
@@ -3853,10 +3708,12 @@
 		if(!(ivideo.vbflags & TV_HIVISION)) {
 	        	if (ivideo.vbflags & TV_PAL) {
 		 		cr31 |= 0x01;
+				cr35 |= 0x01;
 				ivideo.currentvbflags |= TV_PAL;
 				ivideo.TV_type = TVMODE_PAL;
                 	} else {
 		       		cr31 &= ~0x01;
+				cr35 &= ~0x01;
 				ivideo.currentvbflags |= TV_NTSC;
 				ivideo.TV_type = TVMODE_NTSC;
 			}
@@ -3884,6 +3741,11 @@
 		cr31 |= (SIS_DRIVER_MODE | SIS_VB_OUTPUT_DISABLE);
 	}
 
+	if(ivideo.chip >= SIS_661) {
+	   cr31 &= ~0x01;
+	   /* Leave overscan bit alone */
+	   setSISIDXREG(SISCR, 0x35, ~0x10, cr35);
+	}
 	outSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR30, cr30);
 	outSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR31, cr31);
 	outSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR33, cr33);
@@ -3891,7 +3753,10 @@
 #ifdef CONFIG_FB_SIS_315
         if(sisvga_engine == SIS_315_VGA) {
 	   /* Clear LCDA and PAL-N/M bits */
-	   andSISIDXREG(SISCR,0x38,~0xc3);
+	   andSISIDXREG(SISCR,0x38,~0x03);
+	   if(ivideo.chip < SIS_661) {
+	      andSISIDXREG(SISCR,0x38,~0xc0);
+	   }
 	}
 #endif
 
@@ -3910,7 +3775,7 @@
 #ifdef CONFIG_FB_SIS_300
 	BOOLEAN doit = TRUE;
 #endif
-	/* TW: We can't switch off CRT1 if bridge is in slave mode */
+	/* 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) {
@@ -4089,7 +3954,7 @@
 	char *this_opt;
 	
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-	sis_fb_info.fontname[0] = '\0';
+	sisfb_fontname[0] = '\0';
 #endif
 
 	ivideo.refresh_rate = 0;
@@ -4115,7 +3980,8 @@
 			sisfb_inverse = 1;
 			/* fb_invert_cmaps(); */
 		} else if (!strnicmp(this_opt, "font:", 5)) {
-			strcpy(sis_fb_info.fontname, this_opt + 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);
@@ -4147,6 +4013,8 @@
 			sisfb_accel = 0;
 		} else if (!strnicmp(this_opt, "noypan", 6)) {
 		        sisfb_ypan = 0;
+		} else if (!strnicmp(this_opt, "nomax", 5)) {
+		        sisfb_max = 0;
 		} else if (!strnicmp(this_opt, "userom:", 7)) {
 			sisfb_userom = (int)simple_strtoul(this_opt + 7, NULL, 0);
 		} else if (!strnicmp(this_opt, "useoem:", 7)) {
@@ -4195,14 +4063,16 @@
         char *sis_sig_300[4] = {
           "300", "540", "630", "730"
         };
-        char *sis_sig_310[9] = {
-          "315", "315", "315", "5315", "6325", "6325", "Xabre", "6330", "6330"
+        char *sis_sig_310[11] = {
+          "315", "315", "315", "5315", "6325", "6325",
+	  "Xabre", "6330", "6330", "6330", "6330"
         };
 	ushort sis_nums_300[4] = {
 	  SIS_300, SIS_540, SIS_630, SIS_730
 	};
-	unsigned short sis_nums_310[9] = {
-	  SIS_315PRO, SIS_315H, SIS_315, SIS_550, SIS_650, SIS_740, SIS_330, SIS_660, SIS_760
+	unsigned short sis_nums_310[11] = {
+	  SIS_315PRO, SIS_315H, SIS_315, SIS_550, SIS_650, SIS_740,
+	  SIS_330, SIS_661, SIS_741, SIS_660, SIS_760
 	};
 
         for(segstart=0x000c0000; segstart<0x000f0000; segstart+=0x00001000) {
@@ -4239,7 +4109,7 @@
                     }
                 }
 		if(stage != 4) {
-                   for(i = 0;(i < 9) && (stage != 4); i++) {
+                   for(i = 0;(i < 11) && (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;
@@ -4271,9 +4141,7 @@
 	u16 reg16;
 	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);
@@ -4288,7 +4156,7 @@
 	sisfb_registered = 0;
 	sisfb_thismonitor.datavalid = FALSE;
 
-	memset(&sis_fb_info, 0, sizeof(sis_fb_info));
+	memset(&sishw_ext, 0, sizeof(sishw_ext));
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
         memset(&sisfb_lastrates[0], 0, 128);
@@ -4296,7 +4164,7 @@
 	
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	
 	memset(&sis_disp, 0, sizeof(sis_disp));
-#endif	
+#endif
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,74)
 	pci_for_each_dev(pdev) {
@@ -4307,8 +4175,17 @@
 			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				
@@ -4350,7 +4227,7 @@
 			if(reg32 == 0x07301039) {
 				ivideo.chip = SIS_730;
 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
-				strcpy(sis_fb_info.modename, "SIS 730");
+				strcpy(sis_fb_info->modename, "SIS 730");
 #else
 				strcpy(myid, "SIS 730");
 #endif
@@ -4400,7 +4277,7 @@
 			if(reg32 == 0x07401039) {
 				ivideo.chip = SIS_740;
 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
-				strcpy(sis_fb_info.modename, "SIS 740");
+				strcpy(sis_fb_info->modename, "SIS 740");
 #else
 				strcpy(myid, "SIS 740");
 #endif
@@ -4418,16 +4295,36 @@
 		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");
+				strcpy(sis_fb_info->modename, "SIS 760");
 #else
 				strcpy(myid, "SIS 760");
 #endif
+			} else if(reg32 == 0x06601039) {
+				ivideo.chip = SIS_660;
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
+				strcpy(sis_fb_info->modename, "SIS 660");
+#else
+				strcpy(myid, "SIS 660");
+#endif
+			} else if(reg32 == 0x07411039) {
+				ivideo.chip = SIS_741;
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
+				strcpy(sis_fb_info->modename, "SIS 741");
+#else
+				strcpy(myid, "SIS 741");
+#endif
+			} else {
+				ivideo.chip = SIS_661;
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
+				strcpy(sis_fb_info->modename, "SIS 661");
+#else
+				strcpy(myid, "SIS 661");
+#endif
 			}
 			sisvga_engine = SIS_315_VGA;
 			sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
@@ -4436,6 +4333,7 @@
 		}
 #endif
            default:
+	   	kfree(sis_fb_info);
 	        return -ENODEV;
 	}
 	sishw_ext.jChipType = ivideo.chip;
@@ -4447,20 +4345,26 @@
 
 	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;
-	SiSRegInit(&SiS_Pr, (USHORT)sishw_ext.ulIOAddress);
+	SiS_Pr.HaveEMI = FALSE;
+	SiS_Pr.HaveEMILCD = FALSE;
+	SiS_Pr.OverruleEMI = FALSE;
+	SiSRegInit(&SiS_Pr, sishw_ext.ulIOAddress);
 
 #ifdef CONFIG_FB_SIS_300
 	/* TW: Find PCI systems for Chrontel/GPIO communication setup */
@@ -4487,37 +4391,13 @@
 	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);	/* Reset memory clock */
-
-                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 || ivideo.chip == SIS_660 ||
-	    ivideo.chip == SIS_760) {
-	        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:
@@ -4528,6 +4408,8 @@
 		   case SIS_550:
 		   case SIS_650:
 		   case SIS_740:
+		   case SIS_661:
+		   case SIS_741:
 		   case SIS_660:
 		   case SIS_760:
 			sishw_ext.bIntegratedMMEnabled = TRUE;
@@ -4547,7 +4429,6 @@
 		}
 	}
 
-	sishw_ext.pDevice = NULL;
 	if(sisfb_userom) {
 	    sishw_ext.pjVirtualRomBase = sis_find_rom();
 	    if(sishw_ext.pjVirtualRomBase) {
@@ -4563,11 +4444,9 @@
 	    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");
 
         /* Find systems for special custom timing */
 	if(SiS_Pr.SiS_CustomT == CUT_NONE) {
@@ -4598,13 +4477,13 @@
 		  (mycustomttable[i].pcisubsysvendor == ivideo.subsysvendor) &&
 		  (mycustomttable[i].pcisubsyscard == ivideo.subsysdevice) ) {
 		 footprint = TRUE;
-		 if(sishw_ext.UseROM) {
-	            for(j=0; j<5; j++) {
-	               if(mycustomttable[i].biosFootprintAddr[j]) {
+	         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) {
@@ -4612,6 +4491,8 @@
 		    printk(KERN_DEBUG "sisfb: Identified [%s %s], special timing applies\n",
 		        mycustomttable[i].vendorName,
 			mycustomttable[i].cardName);
+		    printk(KERN_DEBUG "sisfb: [specialtiming parameter name: %s]\n",
+		    	mycustomttable[i].optionName);
 	            break;
                  }
 	      }
@@ -4632,6 +4513,7 @@
 	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;
@@ -4640,6 +4522,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;
@@ -4651,29 +4534,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;
 		}
 	}
@@ -4686,32 +4554,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;
@@ -4721,11 +4564,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;
 		}
 	}
@@ -4745,9 +4588,9 @@
 
 	if(sisvga_engine == SIS_300_VGA) sisfb_pdc &= 0x3c;
 	if(sisfb_pdc) {
-	    sishw_ext.pdc = sisfb_pdc;
+	    SiS_Pr.PDC = sisfb_pdc;
 	} else {
-	    sishw_ext.pdc = 0;
+	    SiS_Pr.PDC = 0;
 	}
 
 	if (!request_mem_region(ivideo.video_base, ivideo.video_size, "sisfb FB")) {
@@ -4755,6 +4598,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;
 	}
 
@@ -4763,6 +4607,7 @@
 		release_mem_region(ivideo.video_base, ivideo.video_size);
 		vfree(sishw_ext.pSR);
 		vfree(sishw_ext.pCR);
+		kfree(sis_fb_info);
 		return -ENODEV;
 	}
 
@@ -4791,6 +4636,8 @@
 		sishw_ext.ujVBChipID = VB_CHIP_UNKNOWN;
 		sishw_ext.Is301BDH = FALSE;
 		sishw_ext.usExternalChip = 0;
+
+		sisfb_sense_crt1();
 	
 		sisfb_get_VB_type();
 		
@@ -4834,63 +4681,72 @@
 		}
 		
 		sisfb_detectedpdc = 0;
-#ifndef LINUXBIOS
+
 #ifdef CONFIG_FB_SIS_300
-                /* TW: Save the current PanelDelayCompensation if the LCD is currently used */
+                /* Save the current PanelDelayCompensation if the LCD is currently used */
 		if(sisvga_engine == SIS_300_VGA) {
-	          if(ivideo.vbflags & (VB_LVDS | VB_30xBDH)) {
+	           if(ivideo.vbflags & (VB_LVDS | VB_30xBDH)) {
 		       int tmp;
 		       inSISIDXREG(SISCR,0x30,tmp);
 		       if(tmp & 0x20) {
 		          /* Currently on LCD? If yes, read current pdc */
 		          inSISIDXREG(SISPART1,0x13,sisfb_detectedpdc);
 			  sisfb_detectedpdc &= 0x3c;
-			  if(sishw_ext.pdc == 0) {
+			  if(SiS_Pr.PDC == 0) {
 			     /* Let option override detection */
-			     sishw_ext.pdc = sisfb_detectedpdc;
+			     SiS_Pr.PDC = sisfb_detectedpdc;
 			  }
 			  printk(KERN_INFO
 			         "sisfb: Detected LCD PanelDelayCompensation %d\n",
   			         sisfb_detectedpdc);
 		       }
-		       if((sishw_ext.pdc) && (sishw_ext.pdc != sisfb_detectedpdc)) {
+		       if((SiS_Pr.PDC) && (SiS_Pr.PDC != sisfb_detectedpdc)) {
 		          printk(KERN_INFO
 			         "sisfb: Using LCD PanelDelayCompensation %d\n",
-				 sishw_ext.pdc);
+				 SiS_Pr.PDC);
 		       }
-	          }
+	           }
 		}
 #endif
-#endif
+
 	        sisfb_detectedlcda = 0xff;
-#ifndef LINUXBIOS
+
 #ifdef CONFIG_FB_SIS_315
 
 		if(sisvga_engine == SIS_315_VGA) {
 		   /* Save PDC */
-		   if(ivideo.vbflags & (VB_301LV | VB_302LV)) {
+		   if(ivideo.vbflags & (VB_301LV | VB_302LV | VB_302ELV)) {
 		      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) {
+			 if(SiS_Pr.PDC == 0) {
 			    /* Let option override detection */
-			    sishw_ext.pdc = sisfb_detectedpdc;
+			    SiS_Pr.PDC = sisfb_detectedpdc;
 			 }
 			 printk(KERN_INFO
 			        "sisfb: Detected LCD PanelDelayCompensation %d\n",
   			         sisfb_detectedpdc);
 		      }
-		      if((sishw_ext.pdc) && (sishw_ext.pdc != sisfb_detectedpdc)) {
+		      if((SiS_Pr.PDC) && (SiS_Pr.PDC != sisfb_detectedpdc)) {
 		         printk(KERN_INFO
 			         "sisfb: Using LCD PanelDelayCompensation %d\n",
-				 sishw_ext.pdc);
+				 SiS_Pr.PDC);
+		      }
+		      /* Save EMI */
+		      if(ivideo.vbflags & (VB_302LV | VB_302ELV)) {
+		         inSISIDXREG(SISPART4,0x30,SiS_Pr.EMI_30);
+			 inSISIDXREG(SISPART4,0x31,SiS_Pr.EMI_31);
+			 inSISIDXREG(SISPART4,0x32,SiS_Pr.EMI_32);
+			 inSISIDXREG(SISPART4,0x33,SiS_Pr.EMI_33);
+			 SiS_Pr.HaveEMI = TRUE;
+			 if(tmp & 0x20) SiS_Pr.HaveEMILCD = TRUE;
 		      }
 		   }
 
 		   /* Try to find about LCDA */
-		   if(ivideo.vbflags & (VB_302B | VB_301LV | VB_302LV)) {
+		   if(ivideo.vbflags & (VB_301C | VB_302B | VB_301LV | VB_302LV | VB_302ELV)) {
 		      int tmp;
 		      inSISIDXREG(SISCR,0x34,tmp);
 		      if((tmp <= 0x13) || (tmp == 0xff)) {
@@ -4921,7 +4777,6 @@
 	          }
 		}
 #endif
-#endif
 
 		if (!sisfb_crt1off) {
 		   	sisfb_handle_ddc(&sisfb_thismonitor, 0);
@@ -4991,6 +4846,7 @@
 			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;
 		}
 
@@ -5005,18 +4861,21 @@
 		   sisfb_initaccel();
 		}
 
+		/* Maximize regardless of sisfb_max at startup */
+		default_var.yres_virtual = 32767;
 		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;
+		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);
+		sisfb_set_disp(-1, &default_var, sis_fb_info);
 		
 #else		/* --------- For 2.5: Setup a somewhat sane default var ------------ */
 
@@ -5030,7 +4889,7 @@
 
 		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));
 						
@@ -5040,9 +4899,9 @@
 			 &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_DOUBLE) {
-				default_var.pixclock <<= 1;
-	   		}
+		   if((default_var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
+		      default_var.pixclock <<= 1;
+	   	   }
 	        }
 
 		ivideo.accel = 0;
@@ -5053,26 +4912,26 @@
 		}
 		
 		if(sisfb_ypan) {
-	    		default_var.yres_virtual = 
+		   /* Maximize regardless of sisfb_max at startup */
+	    	   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;
-	    		}
-		}
-
-		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;
-#if 0  		/* Waits for class patch to go in */
-		sis_fb_info.dev = &pdev->dev;
-#endif
-		sisfb_get_fix(&sis_fb_info.fix, -1, &sis_fb_info);
-		sis_fb_info.pseudo_palette = pseudo_palette;
+		   if(default_var.yres_virtual > 32767) default_var.yres_virtual = 32767;
+	    	   if(default_var.yres_virtual <= default_var.yres) {
+	              default_var.yres_virtual = default_var.yres;
+	    	   }
+		}
+
+		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);
@@ -5091,7 +4950,7 @@
 		vc_resize_con(1, 1, 0);
 #endif
 
-		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);
@@ -5099,32 +4958,31 @@
 			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_DEBUG "sisfb: Installed SISFB_GET_INFO ioctl (%x)\n", SISFB_GET_INFO);
+		printk(KERN_DEBUG "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",
-		     sisfb_ypan  ? "ypan" : "redraw");
+		     sisfb_ypan  ? (sisfb_max ? "ypan (auto-max)" : "ypan (no auto-max)") : "redraw");
 
 #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)
+#else
 		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");
+		printk(KERN_INFO "sisfb: (C) 2001-2003 Thomas Winischhofer.\n");
 
-	}	/* TW: if mode = "none" */
+	}	/* if mode = "none" */
 	return 0;
 }
 
@@ -5142,6 +5000,7 @@
 static int          pdc = 0;
 static int          noaccel = -1;
 static int          noypan  = -1;
+static int	    nomax = -1;
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 static int          inverse = 0;
 #endif
@@ -5153,7 +5012,7 @@
 static char	    *specialtiming = NULL;
 static int	    lvdshl = -1;
 
-MODULE_DESCRIPTION("SiS 300/540/630/730/315/550/650/651/661/740/741/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("Thomas Winischhofer <thomas@winischhofer.net>; SiS; Various others");
 
@@ -5209,7 +5068,7 @@
 
 MODULE_PARM(queuemode,   "s");
 MODULE_PARM_DESC(queuemode,
-	"\nSelects the queue mode on 315/550/650/740/330/660. Possible choices are AGP, VRAM,\n"
+	"\nSelects the queue mode on 315/550/65x/74x/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"
@@ -5252,14 +5111,21 @@
 
 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)");
+        "\nIf set to anything other than 0, 2D acceleration will be disabled.\n"
+	  "(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. (default: 0)");
 
+MODULE_PARM(nomax, "i");
+MODULE_PARM_DESC(nomax,
+        "\nIf y-panning is enabled, sisfb will by default use the entire available video\n"
+	  "memory for the virtual screen in order to optimize scrolling performance. If this\n"
+	  "is set to anything other than 0, sisfb will not do this and thereby enable the user\n"
+	  "to positively specify a virtual Y size of the screen using fbset. (default: 0)\n");
+
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	
 MODULE_PARM(inverse, "i");
 MODULE_PARM_DESC(inverse,
@@ -5349,9 +5215,13 @@
 
 	if(noypan == 1)       sisfb_ypan = 0;
 	else if(noypan == 0)  sisfb_ypan = 1;
+
+	if(nomax == 1)        sisfb_max = 0;
+	else if(nomax == 0)   sisfb_max = 1;
 	
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 	if(inverse)           sisfb_inverse = 1;
+	sisfb_fontname[0] = '\0';
 #endif
 
 	if(mem)		      sisfb_mem = mem;
@@ -5362,7 +5232,7 @@
 
 	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;
 	}
@@ -5383,7 +5253,7 @@
 
 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);
 
@@ -5398,7 +5268,12 @@
 
 	/* 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);
diff -urN linux-2.4.25-pre4/drivers/video/sis/sis_main.h linux-2.4.25-pre5/drivers/video/sis/sis_main.h
--- linux-2.4.25-pre4/drivers/video/sis/sis_main.h	2003-11-28 10:26:21.000000000 -0800
+++ linux-2.4.25-pre5/drivers/video/sis/sis_main.h	2004-01-15 12:10:23.000000000 -0800
@@ -1,3 +1,24 @@
+/*
+ * 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
+ *
+ * Copyright (C) 2001-2004 Thomas Winischhofer, Vienna, Austria.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the named License,
+ * or any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
+ */
+
 #ifndef _SISFB_MAIN
 #define _SISFB_MAIN
 
@@ -5,14 +26,13 @@
 
 /* ------------------- 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                 16
+#define VER_LEVEL                 25
 
 #include "sis.h"
 
@@ -29,22 +49,28 @@
 #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_660
+#define PCI_DEVICE_ID_SI_660      0x0661
+#endif
+#ifndef PCI_DEVICE_ID_SI_741
+#define PCI_DEVICE_ID_SI_741      0x0741
+#endif
+#ifndef PCI_DEVICE_ID_SI_660
+#define PCI_DEVICE_ID_SI_660      0x0660
+#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, 661, 740		*/
+#define FB_ACCEL_SIS_GLAMOUR_2  40	/* SiS 315, 65x, 740, 661, 741  */
 #endif
 #ifndef FB_ACCEL_SIS_XABRE
-#define FB_ACCEL_SIS_XABRE      41	/* SiS 330 ("Xabre"), 660, 760 (DOA)	*/
+#define FB_ACCEL_SIS_XABRE      41	/* SiS 330 ("Xabre"), 760 	*/
 #endif
 
 #define MAX_ROM_SCAN              0x10000
@@ -101,7 +127,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
@@ -155,14 +183,6 @@
 #define SIS_DATA_BUS_64           0x01
 #define SIS_DATA_BUS_128          0x02
 
-#define SIS315_DRAM_SIZE_MASK     0xF0  /* 315 SR14 */
-#define SIS315_DRAM_SIZE_2MB      0x01
-#define SIS315_DRAM_SIZE_4MB      0x02
-#define SIS315_DRAM_SIZE_8MB      0x03
-#define SIS315_DRAM_SIZE_16MB     0x04
-#define SIS315_DRAM_SIZE_32MB     0x05
-#define SIS315_DRAM_SIZE_64MB     0x06
-#define SIS315_DRAM_SIZE_128MB    0x07
 #define SIS315_DATA_BUS_MASK      0x02
 #define SIS315_DATA_BUS_64        0x00
 #define SIS315_DATA_BUS_128       0x01
@@ -172,17 +192,6 @@
 #define SIS315_ASYM_DDR		  	0x02
 #define SIS315_DUAL_CHANNEL_1_RANK    	0x3
 
-#define SIS550_DRAM_SIZE_MASK     0x3F  /* 550/650/740 SR14 */
-#define SIS550_DRAM_SIZE_4MB      0x00
-#define SIS550_DRAM_SIZE_8MB      0x01
-#define SIS550_DRAM_SIZE_16MB     0x03
-#define SIS550_DRAM_SIZE_24MB     0x05
-#define SIS550_DRAM_SIZE_32MB     0x07
-#define SIS550_DRAM_SIZE_64MB     0x0F
-#define SIS550_DRAM_SIZE_96MB     0x17
-#define SIS550_DRAM_SIZE_128MB    0x1F
-#define SIS550_DRAM_SIZE_256MB    0x3F
-
 #define SIS_SCRATCH_REG_1A_MASK   0x10
 
 #define SIS_ENABLE_2D             0x40  /* SR1E */
@@ -223,7 +232,7 @@
 #define SIS_VB_TV                 (SIS_VB_COMPOSITE | SIS_VB_SVIDEO | \
                                    SIS_VB_SCART | SIS_VB_HIVISION)
 
-#define SIS_EXTERNAL_CHIP_MASK    	   0x0E  /* CR37 */
+#define SIS_EXTERNAL_CHIP_MASK    	   0x0E  /* CR37 (< SiS 660) */
 #define SIS_EXTERNAL_CHIP_SIS301           0x01  /* in CR37 << 1 ! */
 #define SIS_EXTERNAL_CHIP_LVDS             0x02  /* in CR37 << 1 ! */
 #define SIS_EXTERNAL_CHIP_TRUMPION         0x03  /* in CR37 << 1 ! */
@@ -242,12 +251,33 @@
 #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
 
+/* entries for disp_state - deprecated as of 1.6.02 */
+#define DISPTYPE_CRT1       0x00000008L
+#define DISPTYPE_CRT2       0x00000004L
+#define DISPTYPE_LCD        0x00000002L
+#define DISPTYPE_TV         0x00000001L
+#define DISPTYPE_DISP1      DISPTYPE_CRT1
+#define DISPTYPE_DISP2      (DISPTYPE_CRT2 | DISPTYPE_LCD | DISPTYPE_TV)
+#define DISPMODE_SINGLE	    0x00000020L
+#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
+#define HASVB_TRUMPION  	0x04
+#define HASVB_LVDS_CHRONTEL	0x10
+#define HASVB_302       	0x20
+#define HASVB_303       	0x40
+#define HASVB_CHRONTEL  	0x80
+
 /* Useful macros */
 #define inSISREG(base)          inb(base)
 #define outSISREG(base,val)     outb(val,base)
@@ -287,7 +317,7 @@
 /* ------------------- Global Variables ----------------------------- */
 
 /* Fbcon variables */
-static struct fb_info sis_fb_info;
+static struct fb_info *sis_fb_info;
 
 static struct fb_var_screeninfo default_var = {
 	.xres            = 0,
@@ -366,6 +396,7 @@
 static int sisfb_mem = 0;
 static int sisfb_pdc = 0;
 static int sisfb_ypan = -1;
+static int sisfb_max = -1;
 static int sisfb_nocrt2rate = 0;
 static int sisfb_dstn = 0;
 static int sisfb_fstn = 0;
@@ -392,14 +423,8 @@
 /* For ioctl SISFB_GET_INFO */
 sisfb_info sisfbinfo;
 
-/* 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;
 
 /* SiS private structure */
 SiS_Private  SiS_Pr;
@@ -426,11 +451,9 @@
 	{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/661FX/M661FX/740/741 VGA"},
+	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_650_VGA, "SIS 65x/M65x/740 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
+	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_660_VGA, "SIS 661FX/M661FX/741/760 VGA"},
 	{0, 0, NULL}
 };
 
@@ -766,42 +789,119 @@
     unsigned long SpecialID;
     char *optionName;
 } mycustomttable[] = {
-        { SIS_630, "2.00.07", "09/27/2002-13:38:25",
+	{ SIS_630, "2.00.07", "09/27/2002-13:38:25",
 	  0x3240A8,
-	  { 0x220, 0x227, 0x228, 0x229, 0x22a },
-	  {  0x01,  0xe3,  0x9a,  0x6a,  0x00 },
+	  { 0x220, 0x227, 0x228, 0x229, 0x0ee },
+	  {  0x01,  0xe3,  0x9a,  0x6a,  0xef },
 	  0x1039, 0x6300,
-	  "Barco", "iQ R200L/300/400", CUT_BARCO1366, "BARCO1366"
+	  "Barco", "iQ R200L/300/400", CUT_BARCO1366, "BARCO_1366"
 	},
 	{ SIS_630, "2.00.07", "09/27/2002-13:38:25",
 	  0x323FBD,
-	  { 0x220, 0x227, 0x228, 0x229, 0x22a },
-	  {  0x00,  0x5a,  0x64,  0x41,  0x00 },
+	  { 0x220, 0x227, 0x228, 0x229, 0x0ee },
+	  {  0x00,  0x5a,  0x64,  0x41,  0xef },
 	  0x1039, 0x6300,
-	  "Barco", "iQ G200L/300/400/500", CUT_BARCO1024, "BARCO1024"
+	  "Barco", "iQ G200L/300/400/500", CUT_BARCO1024, "BARCO_1024"
 	},
 	{ SIS_650, "", "",
 	  0,
 	  { 0, 0, 0, 0, 0 },
 	  { 0, 0, 0, 0, 0 },
 	  0x0e11, 0x083c,
-	  "Compaq", "Presario 3017cl/3045US", CUT_COMPAQ12802, "COMPAQ1280"
+	  "Inventec (Compaq)", "3017cl/3045US", CUT_COMPAQ12802, "COMPAQ_1280"
 	},
 	{ SIS_650, "", "",
 	  0,
 	  { 0x00c, 0, 0, 0, 0 },
 	  { 'e'  , 0, 0, 0, 0 },
 	  0x1558, 0x0287,
-	  "Clevo", "L285/L287 (Version 1)", CUT_CLEVO1024, "CLEVO1024"
+	  "Clevo", "L285/L287 (Version 1)", CUT_CLEVO1024, "CLEVO_L28X_1"
 	},
 	{ SIS_650, "", "",
 	  0,
 	  { 0x00c, 0, 0, 0, 0 },
 	  { 'y'  , 0, 0, 0, 0 },
 	  0x1558, 0x0287,
-	  "Clevo", "L285/L287 (Version 2)", CUT_CLEVO10242, "CLEVO10242"
+	  "Clevo", "L285/L287 (Version 2)", CUT_CLEVO10242, "CLEVO_L28X_2"
+	},
+	{ SIS_650, "", "",
+	  0,
+	  { 0, 0, 0, 0, 0 },
+	  { 0, 0, 0, 0, 0 },
+	  0x1558, 0x0400,  /* possibly 401 and 402 as well; not panelsize specific (?) */
+	  "Clevo", "D400S/D410S/D400H/D410H", CUT_CLEVO1400, "CLEVO_D4X0"
+	},
+	{ SIS_650, "", "",
+	  0,	/* Shift LCD in LCD-via-CRT1 mode */
+	  { 0, 0, 0, 0, 0 },
+	  { 0, 0, 0, 0, 0 },
+	  0x1558, 0x2263,
+	  "Clevo", "D22ES/D27ES", CUT_UNIWILL1024, "CLEVO_D2X0ES"
+	},
+	{ SIS_650, "", "",
+	  0,	/* Shift LCD in LCD-via-CRT1 mode */
+	  { 0, 0, 0, 0, 0 },
+	  { 0, 0, 0, 0, 0 },
+	  0x1734, 0x101f,
+	  "Uniwill", "N243S9", CUT_UNIWILL1024, "UNIWILL_N243S9"
+	},
+	{ SIS_650, "", "",
+	  0,	/* Shift LCD in LCD-via-CRT1 mode */
+	  { 0, 0, 0, 0, 0 },
+	  { 0, 0, 0, 0, 0 },
+	  0x1584, 0x5103,
+	  "Uniwill", "N35BS1", CUT_UNIWILL10242, "UNIWILL_N35BS1"
+	},
+	{ SIS_650, "1.09.2c", "",  /* Other versions, too? */
+	  0,	/* Shift LCD in LCD-via-CRT1 mode */
+	  { 0, 0, 0, 0, 0 },
+	  { 0, 0, 0, 0, 0 },
+	  0x1019, 0x0f05,
+	  "ECS", "A928", CUT_UNIWILL1024, "ECS_A928"
+	},
+	{ SIS_740, "1.11.27a", "",
+	  0,
+	  { 0, 0, 0, 0, 0 },
+	  { 0, 0, 0, 0, 0 },
+	  0x1043, 0x1612,
+	  "Asus", "L3000D/L3500D", CUT_ASUSL3000D, "ASUS_L3X00"
+	},
+	{ SIS_650, "1.10.9k", "",
+	  0,
+	  { 0, 0, 0, 0, 0 },
+	  { 0, 0, 0, 0, 0 },
+	  0x1025, 0x0028,
+	  "Acer", "Aspire 1700", CUT_ACER1280, "ACER_ASPIRE1700"
+	},
+	{ SIS_650, "1.10.7w", "",
+	  0,
+	  { 0, 0, 0, 0, 0 },
+	  { 0, 0, 0, 0, 0 },
+	  0x14c0, 0x0012,
+	  "Compal", "??? (V1)", CUT_COMPAL1400_1, "COMPAL_1400_1"
+	},
+	{ SIS_650, "1.10.7x", "",
+	  0,
+	  { 0, 0, 0, 0, 0 },
+	  { 0, 0, 0, 0, 0 },
+	  0x14c0, 0x0012,
+	  "Compal", "??? (V2)", CUT_COMPAL1400_2, "COMPAL_1400_2"
 	},
-	{ 4321, "", "",			/* This is hopefully NEVER autodetected */
+	{ SIS_650, "1.10.8o", "",
+	  0,	/* For EMI (unknown) */
+	  { 0, 0, 0, 0, 0 },
+	  { 0, 0, 0, 0, 0 },
+	  0x1043, 0x1612,
+	  "Asus", "A2H (V1)", CUT_ASUSA2H_1, "ASUS_A2H_1"
+	},
+	{ SIS_650, "1.10.8q", "",
+	  0,	/* For EMI */
+	  { 0, 0, 0, 0, 0 },
+	  { 0, 0, 0, 0, 0 },
+	  0x1043, 0x1612,
+	  "Asus", "A2H (V2)", CUT_ASUSA2H_2, "ASUS_A2H_2"
+	},
+	{ 4321, "", "",			/* never autodetected */
 	  0,
 	  { 0, 0, 0, 0, 0 },
 	  { 0, 0, 0, 0, 0 },
@@ -826,6 +926,8 @@
 	u8 gmask[72];
 	int ngmask;
 } SIS_GLYINFO;
+
+static char sisfb_fontname[40];
 #endif
 
 typedef struct _SIS_OH {
@@ -1077,9 +1179,9 @@
 			    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,
@@ -1117,7 +1219,6 @@
 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);
 void            sis_malloc(struct sis_memreq *req);
@@ -1145,20 +1246,29 @@
 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 USHORT   SiS_GetModeID(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth, BOOLEAN FSTN);
+extern USHORT   SiS_GetModeID_LCD(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth,
+                                  BOOLEAN FSTN, USHORT CustomT, int LCDwith, int LCDheight);
+extern USHORT   SiS_GetModeID_TV(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth);
+extern USHORT   SiS_GetModeID_VGA2(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth);
+
+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 void     SiS_LongWait(SiS_Private *SiS_Pr);
 
-extern BOOLEAN  sisfb_gettotalfrommode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+extern BOOLEAN  sisfb_gettotalfrommode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwDeviceExtension,
 		       unsigned char modeno, int *htotal, int *vtotal, unsigned char rateindex);
 
 /* Chrontel TV functions */
@@ -1171,14 +1281,11 @@
 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 void SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
-extern void SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr);
-extern void SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
-extern void SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
-			      
-/* Sensing routines */
-void            SiS_Sense30x(void);
-int             SISDoSense(int tempbl, int tempbh, int tempcl, int tempch);
-void            SiS_SenseCh(void);			
+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);
+
 			
 #endif
diff -urN linux-2.4.25-pre4/drivers/video/sis/vgatypes.h linux-2.4.25-pre5/drivers/video/sis/vgatypes.h
--- linux-2.4.25-pre4/drivers/video/sis/vgatypes.h	2003-11-28 10:26:21.000000000 -0800
+++ linux-2.4.25-pre5/drivers/video/sis/vgatypes.h	2004-01-15 12:10:23.000000000 -0800
@@ -1,40 +1,62 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/vgatypes.h,v 1.0 2001/06/15 21:23:00 dawes Exp $ */
+/* $XFree86$ */
 /*
  * General type definitions for universal mode switching modules
  *
- * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
+ * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
  *
- * If distributed as part of the linux kernel, the contents of this file
- * is entirely covered by the GPL.
+ * If distributed as part of the Linux kernel, the following license terms
+ * apply:
  *
- * Otherwise, the following terms apply:
+ * * This program is free software; you can redistribute it and/or modify
+ * * it under the terms of the GNU General Public License as published by
+ * * the Free Software Foundation; either version 2 of the named License,
+ * * or any later version.
+ * *
+ * * This program is distributed in the hope that it will be useful,
+ * * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * * GNU General Public License for more details.
+ * *
+ * * You should have received a copy of the GNU General Public License
+ * * along with this program; if not, write to the Free Software
+ * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
  *
- * 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.
+ * Otherwise, the following license terms apply:
  *
- * 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.
+ * * Redistribution and use in source and binary forms, with or without
+ * * modification, are permitted provided that the following conditions
+ * * are met:
+ * * 1) Redistributions of source code must retain the above copyright
+ * *    notice, this list of conditions and the following disclaimer.
+ * * 2) Redistributions in binary form must reproduce the above copyright
+ * *    notice, this list of conditions and the following disclaimer in the
+ * *    documentation and/or other materials provided with the distribution.
+ * * 3) All advertising materials mentioning features or use of this software
+ * *    must display the following acknowledgement: "This product includes
+ * *    software developed by Thomas Winischhofer, Vienna, Austria."
+ * * 4) The name of the author may not be used to endorse or promote products
+ * *    derived from this software without specific prior written permission.
+ * *
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * Authors: 	Thomas Winischhofer <thomas@winischhofer.net>
- *		Silicon Integrated Systems
+ * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
  *
  */
+
 #ifndef _VGATYPES_
 #define _VGATYPES_
 
 #ifdef LINUX_XF86
+#include "xf86Version.h"
 #include "xf86Pci.h"
 #endif
 
@@ -42,10 +64,6 @@
 #include <linux/ioctl.h>
 #endif
 
-#ifndef TC
-#define far
-#endif
-
 #ifndef FALSE
 #define FALSE   0
 #endif
@@ -82,25 +100,6 @@
 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
@@ -109,17 +108,26 @@
 typedef UCHAR bool;
 #endif
 
-#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 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,
@@ -132,6 +140,8 @@
     SIS_650,
     SIS_740,
     SIS_330,
+    SIS_661,
+    SIS_741,
     SIS_660,
     SIS_760,
     MAX_SIS_CHIP
@@ -149,6 +159,7 @@
     VB_CHIP_302B,
     VB_CHIP_302LV,
     VB_CHIP_301C,
+    VB_CHIP_302ELV,
     VB_CHIP_UNKNOWN, /* other video bridge or no video bridge */
     MAX_VB_CHIP
 } SIS_VB_CHIP_TYPE;
@@ -174,6 +185,8 @@
     LCD_640x480_2,     /* FSTN, DSTN */
     LCD_640x480_3,     /* FSTN, DSTN */
     LCD_848x480,
+    LCD_1280x800,
+    LCD_1680x1050,
     LCD_CUSTOM,
     LCD_UNKNOWN
 } SIS_LCD_TYPE;
@@ -187,35 +200,27 @@
 } SIS_DSReg, *PSIS_DSReg;
 #endif
 
-#ifndef SIS_HW_DEVICE_INFO
+#ifndef SIS_HW_INFO
 
-typedef struct _SIS_HW_DEVICE_INFO  SIS_HW_DEVICE_INFO, *PSIS_HW_DEVICE_INFO;
+typedef struct _SIS_HW_INFO  SIS_HW_INFO, *PSIS_HW_INFO;
 
-typedef BOOLEAN (*PSIS_QUERYSPACE)   (PSIS_HW_DEVICE_INFO, ULONG, ULONG, ULONG *);
+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 */
-
-    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 */
+#ifdef LINUX_XF86
+    PCITAG PciTag;		 /* PCI Tag */
+#endif
+
+    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" */
@@ -224,20 +229,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 (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 315 series! */
 
     ULONG  ulCRT2LCDType;        /* defined in the data structure type */
                                  /* "SIS_LCD_TYPE" */
@@ -245,6 +242,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  */
@@ -254,37 +253,25 @@
                                  /* end data :(idx, val) =  (FF, FF) */
                                  /* Note : restore cR registers if  */
                                  /* bSkipDramSizing = TRUE */
+#endif
 
     PSIS_QUERYSPACE  pQueryVGAConfigSpace; /* Get/Set VGA Configuration  */
                                            /* space */
  
     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
 };
 #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 {
@@ -319,80 +306,12 @@
 	int sisfb_scalelcd;
 	unsigned long sisfb_specialtiming;
 
-	char reserved[219]; 		/* for future use */
-};
-#endif
-
-#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
-
-#ifndef PCI_TYPE0_ADDRESSES
-#define PCI_TYPE0_ADDRESSES             6
-#endif
-
-#ifndef PCI_TYPE1_ADDRESSES
-#define PCI_TYPE1_ADDRESSES             2
-#endif
-
-#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
+	unsigned char sisfb_haveemi;
+	unsigned char sisfb_emi30,sisfb_emi31,sisfb_emi32,sisfb_emi33;
+	unsigned char sisfb_haveemilcd;
 
-#ifndef FIELD_OFFSET
-#define FIELD_OFFSET(type, field)    ((LONG)&(((type *)0)->field))
-#endif
-
-#ifndef PCI_COMMON_HDR_LENGTH
-#define PCI_COMMON_HDR_LENGTH (FIELD_OFFSET (PCI_COMMON_CONFIG, DeviceSpecific))
+	char reserved[213]; 		/* for future use */
+};
 #endif
 
 #endif
diff -urN linux-2.4.25-pre4/drivers/video/sis/vstruct.h linux-2.4.25-pre5/drivers/video/sis/vstruct.h
--- linux-2.4.25-pre4/drivers/video/sis/vstruct.h	2003-11-28 10:26:21.000000000 -0800
+++ linux-2.4.25-pre5/drivers/video/sis/vstruct.h	2004-01-15 12:10:23.000000000 -0800
@@ -1,34 +1,54 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/vstruct.h,v 1.0 2001/06/15 21:23:00 dawes Exp $ */
+/* $XFree86$ */
 /*
  * General structure definitions for universal mode switching modules
  *
- * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
+ * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
  *
- * If distributed as part of the linux kernel, the contents of this file
- * is entirely covered by the GPL.
+ * If distributed as part of the Linux kernel, the following license terms
+ * apply:
  *
- * Otherwise, the following terms apply:
+ * * This program is free software; you can redistribute it and/or modify
+ * * it under the terms of the GNU General Public License as published by
+ * * the Free Software Foundation; either version 2 of the named License,
+ * * or any later version.
+ * *
+ * * This program is distributed in the hope that it will be useful,
+ * * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * * GNU General Public License for more details.
+ * *
+ * * You should have received a copy of the GNU General Public License
+ * * along with this program; if not, write to the Free Software
+ * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
  *
- * 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.
+ * Otherwise, the following license terms apply:
  *
- * 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.
+ * * Redistribution and use in source and binary forms, with or without
+ * * modification, are permitted provided that the following conditions
+ * * are met:
+ * * 1) Redistributions of source code must retain the above copyright
+ * *    notice, this list of conditions and the following disclaimer.
+ * * 2) Redistributions in binary form must reproduce the above copyright
+ * *    notice, this list of conditions and the following disclaimer in the
+ * *    documentation and/or other materials provided with the distribution.
+ * * 3) All advertising materials mentioning features or use of this software
+ * *    must display the following acknowledgement: "This product includes
+ * *    software developed by Thomas Winischhofer, Vienna, Austria."
+ * * 4) The name of the author may not be used to endorse or promote products
+ * *    derived from this software without specific prior written permission.
+ * *
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * Authors: 	Thomas Winischhofer <thomas@winischhofer.net>
- *              Silicon Integrated Systems
+ * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
  *
  */
  
@@ -112,6 +132,7 @@
 	UCHAR  VB_StTVFlickerIndex;
 	UCHAR  VB_StTVEdgeIndex;
 	UCHAR  VB_StTVYFilterIndex;
+	UCHAR  St_PDC;
 } SiS_StStruct;
 
 typedef struct _SiS_VBModeStruct
@@ -143,12 +164,13 @@
 {
 	UCHAR  Ext_ModeID;
 	USHORT Ext_ModeFlag;
-	USHORT Ext_ModeInfo;
+	UCHAR  Ext_ModeOffset;
 	USHORT Ext_VESAID;
 	UCHAR  Ext_RESINFO;
 	UCHAR  VB_ExtTVFlickerIndex;
 	UCHAR  VB_ExtTVEdgeIndex;
 	UCHAR  VB_ExtTVYFilterIndex;
+	UCHAR  VB_ExtTVYFilterIndexROM661;
 	UCHAR  REFindex;
 } SiS_ExtStruct;
 
@@ -161,6 +183,7 @@
 	UCHAR  ModeID;
 	USHORT XRes;
 	USHORT YRes;
+	UCHAR  Ext_PDC;
 } SiS_Ext2Struct;
 
 typedef struct _SiS_Part2PortTblStruct
@@ -179,12 +202,6 @@
 	USHORT CLOCK;
 } SiS_MCLKDataStruct;
 
-typedef struct _SiS_ECLKDataStruct
-{
-	UCHAR  SR2E,SR2F,SR30;
-	USHORT CLOCK;
-} SiS_ECLKDataStruct;
-
 typedef struct _SiS_VCLKDataStruct
 {
 	UCHAR  SR2B,SR2C;
@@ -213,48 +230,59 @@
 
 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
+/* Defines for SiS_CustomT */
+/* Never change these for sisfb compatibility */
+#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
+#define CUT_UNIWILL10242  13
+#define CUT_ACER1280      14
+#define CUT_COMPAL1400_1  15
+#define CUT_COMPAL1400_2  16
+#define CUT_ASUSA2H_1     17
+#define CUT_ASUSA2H_2     18
 
 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_P3cb;
-	USHORT SiS_P3cd;
-	USHORT SiS_P3da;
-	USHORT SiS_Part1Port;
-	USHORT SiS_Part2Port;
-	USHORT SiS_Part3Port;
-	USHORT SiS_Part4Port;
-	USHORT SiS_Part5Port;
-	USHORT SiS_VidCapt;
-	USHORT SiS_VidPlay;
+	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_CH70xx;
+	USHORT SiS_IF_DEF_CONEX;
 	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
@@ -268,6 +296,11 @@
 	int    SiS_UseOEM;
 	ULONG  SiS_CustomT;
 	USHORT SiS_Backup70xx;
+	BOOLEAN HaveEMI;
+	BOOLEAN HaveEMILCD;
+	BOOLEAN OverruleEMI;
+	UCHAR  EMI_30,EMI_31,EMI_32,EMI_33;
+	UCHAR  PDC;
 	USHORT SiS_CRT1Mode;
 	USHORT SiS_flag_clearbuffer;
 	int    SiS_RAMType;
@@ -275,12 +308,14 @@
 	UCHAR  SiS_DataBusWidth;
 	USHORT SiS_ModeType;
 	USHORT SiS_VBInfo;
+	USHORT SiS_TVMode;
 	USHORT SiS_LCDResInfo;
 	USHORT SiS_LCDTypeInfo;
 	USHORT SiS_LCDInfo;
+	USHORT SiS_LCDInfo661;
 	USHORT SiS_VBType;
 	USHORT SiS_VBExtInfo;
-	USHORT SiS_HiVision;
+	USHORT SiS_YPbPr;
 	USHORT SiS_SelectCRT2Rate;
 	USHORT SiS_SetFlag;
 	USHORT SiS_RVBHCFACT;
@@ -338,7 +373,6 @@
 	const SiS_CRT1TableStruct   *SiS_CRT1Table;
 	const SiS_MCLKDataStruct    *SiS_MCLKData_0;
 	const SiS_MCLKDataStruct    *SiS_MCLKData_1;
-	const SiS_ECLKDataStruct    *SiS_ECLKData;
 	const SiS_VCLKDataStruct    *SiS_VCLKData;
 	const SiS_VBVCLKDataStruct  *SiS_VBVCLKData;
 	const SiS_StResInfoStruct   *SiS_StResInfo;
@@ -382,6 +416,8 @@
 	const UCHAR *SiS_PALMPhase2;
 	const UCHAR *SiS_PALNPhase2;
 	const UCHAR *SiS_SpecialPhase;
+	const UCHAR *SiS_SpecialPhaseM;
+	const UCHAR *SiS_SpecialPhaseJ;
 	const SiS_LCDDataStruct  *SiS_StLCD1024x768Data;
 	const SiS_LCDDataStruct  *SiS_ExtLCD1024x768Data;
 	const SiS_LCDDataStruct  *SiS_St2LCD1024x768Data;
@@ -407,6 +443,12 @@
 	const SiS_TVDataStruct   *SiS_ExtNTSCData;
 	const SiS_TVDataStruct   *SiS_St2HiTVData;
 	const SiS_TVDataStruct   *SiS_ExtHiTVData;
+	const SiS_TVDataStruct   *SiS_St525iData;
+	const SiS_TVDataStruct   *SiS_St525pData;
+	const SiS_TVDataStruct   *SiS_St750pData;
+	const SiS_TVDataStruct   *SiS_Ext525iData;
+	const SiS_TVDataStruct   *SiS_Ext525pData;
+	const SiS_TVDataStruct   *SiS_Ext750pData;
 	const UCHAR *SiS_NTSCTiming;
 	const UCHAR *SiS_PALTiming;
 	const UCHAR *SiS_HiTVExtTiming;
@@ -439,6 +481,10 @@
 	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;
@@ -555,22 +601,18 @@
 
 	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;
@@ -636,9 +678,6 @@
 	USHORT  CModeFlag_CRT1;
 	USHORT  CInfoFlag;
 
-	BOOLEAN SiS_CHPALM;
-	BOOLEAN SiS_CHPALN;
-
 	int	LVDSHL;
 	
 	BOOLEAN Backup;
@@ -660,6 +699,7 @@
 	BOOLEAN CP_HaveCustomData;
 	int     CP_PreferredX, CP_PreferredY;
 	int	CP_MaxX, CP_MaxY, CP_MaxClock;
+	BOOLEAN CP_Supports64048075;
 	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];
diff -urN linux-2.4.25-pre4/fs/dquot.c linux-2.4.25-pre5/fs/dquot.c
--- linux-2.4.25-pre4/fs/dquot.c	2003-11-28 10:26:21.000000000 -0800
+++ linux-2.4.25-pre5/fs/dquot.c	2004-01-15 12:10:23.000000000 -0800
@@ -396,7 +396,7 @@
 		if (dquot->dq_flags & DQ_LOCKED)
 			wait_on_dquot(dquot);
 		if (dquot_dirty(dquot))
-			sb->dq_op->sync_dquot(dquot);
+			sb->dq_op->write_dquot(dquot);
 		dqput(dquot);
 		goto restart;
 	}
@@ -543,7 +543,7 @@
 		return;
 	}
 	if (dquot_dirty(dquot)) {
-		commit_dqblk(dquot);
+		dquot->dq_sb->dq_op->write_dquot(dquot);
 		goto we_slept;
 	}
 
@@ -1219,7 +1219,7 @@
 	free_space:	dquot_free_space,
 	free_inode:	dquot_free_inode,
 	transfer:	dquot_transfer,
-	sync_dquot:	commit_dqblk
+	write_dquot:	commit_dqblk
 };
 
 /* Function used by filesystems for initializing the dquot_operations structure */
@@ -1331,9 +1331,9 @@
 	error = -EINVAL;
 	if (!fmt->qf_ops->check_quota_file(sb, type))
 		goto out_f;
-	/* We don't want quota on quota files */
+	/* We don't want quota and atime on quota files */
 	dquot_drop(inode);
-	inode->i_flags |= S_NOQUOTA;
+	inode->i_flags |= S_NOQUOTA | S_NOATIME;
 
 	dqopt->ops[type] = fmt->qf_ops;
 	dqopt->info[type].dqi_format = fmt;
diff -urN linux-2.4.25-pre4/fs/ext3/super.c linux-2.4.25-pre5/fs/ext3/super.c
--- linux-2.4.25-pre4/fs/ext3/super.c	2004-01-15 12:10:15.000000000 -0800
+++ linux-2.4.25-pre5/fs/ext3/super.c	2004-01-15 12:10:24.000000000 -0800
@@ -1797,14 +1797,14 @@
 
 #ifdef CONFIG_QUOTA
 
-static int (*old_sync_dquot)(struct dquot *dquot);
+static int (*old_write_dquot)(struct dquot *dquot);
 
 /* Blocks: (2 data blocks) * (3 indirect + 1 descriptor + 1 bitmap) + superblock */
 #define EXT3_OLD_QFMT_BLOCKS 11
 /* Blocks: quota info + (4 pointer blocks + 1 entry block) * (3 indirect + 1 descriptor + 1 bitmap) + superblock */
 #define EXT3_V0_QFMT_BLOCKS 27
 
-static int ext3_sync_dquot(struct dquot *dquot)
+static int ext3_write_dquot(struct dquot *dquot)
 {
 	int nblocks, ret;
 	handle_t *handle;
@@ -1829,7 +1829,7 @@
 		return PTR_ERR(handle);
 	}
 	unlock_kernel();
-	ret = old_sync_dquot(dquot);
+	ret = old_write_dquot(dquot);
 	lock_kernel();
 	ret = ext3_journal_stop(handle, qinode);
 	unlock_kernel();
@@ -1843,8 +1843,8 @@
 {
 #ifdef CONFIG_QUOTA
 	init_dquot_operations(&ext3_qops);
-	old_sync_dquot = ext3_qops.sync_dquot;
-	ext3_qops.sync_dquot = ext3_sync_dquot;
+	old_write_dquot = ext3_qops.write_dquot;
+	ext3_qops.write_dquot = ext3_write_dquot;
 #endif
         return register_filesystem(&ext3_fs_type);
 }
diff -urN linux-2.4.25-pre4/fs/inode.c linux-2.4.25-pre5/fs/inode.c
--- linux-2.4.25-pre4/fs/inode.c	2004-01-15 12:10:15.000000000 -0800
+++ linux-2.4.25-pre5/fs/inode.c	2004-01-15 12:10:24.000000000 -0800
@@ -49,7 +49,8 @@
  * other linked list is the "type" list:
  *  "in_use" - valid inode, i_count > 0, i_nlink > 0
  *  "dirty"  - as "in_use" but also dirty
- *  "unused" - valid inode, i_count = 0
+ *  "unused" - valid inode, i_count = 0, no pages in the pagecache
+ *  "unused_pagecache" - valid inode, i_count = 0, data in the pagecache
  *
  * A "dirty" list is maintained for each super block,
  * allowing for low-overhead inode sync() operations.
@@ -57,6 +58,7 @@
 
 static LIST_HEAD(inode_in_use);
 static LIST_HEAD(inode_unused);
+static LIST_HEAD(inode_unused_pagecache);
 static struct list_head *inode_hashtable;
 static LIST_HEAD(anon_hash_chain); /* for inodes with NULL i_sb */
 
@@ -248,9 +250,10 @@
  * ->read_inode, and we want to be sure that evidence of the deletion is found
  * by ->read_inode.
  *
- * This call might return early if an inode which shares the waitq is woken up.
- * This is most easily handled by the caller which will loop around again
- * looking for the inode.
+ * Unlike the 2.6 version, this call call cannot return early, since inodes
+ * do not share wait queue. Therefore, we don't call remove_wait_queue(); it
+ * would be dangerous to do so since the inode may have already been freed, 
+ * and it's unnecessary, since the inode is definitely going to get freed.
  *
  * This is called with inode_lock held.
  */
@@ -262,7 +265,7 @@
         set_current_state(TASK_UNINTERRUPTIBLE);
         spin_unlock(&inode_lock);
         schedule();
-        remove_wait_queue(&inode->i_wait, &wait);
+
         spin_lock(&inode_lock);
 }
 
@@ -286,6 +289,36 @@
 	inodes_stat.nr_unused--;
 }
 
+static inline void __refile_inode(struct inode *inode)
+{
+	struct list_head *to;
+
+	if (inode->i_state & I_FREEING)
+		return;
+	if (list_empty(&inode->i_hash))
+		return;
+
+	if (inode->i_state & I_DIRTY)
+		to = &inode->i_sb->s_dirty;
+	else if (atomic_read(&inode->i_count))
+		to = &inode_in_use;
+	else if (inode->i_data.nrpages)
+		to = &inode_unused_pagecache;
+	else
+		to = &inode_unused;
+	list_del(&inode->i_list);
+	list_add(&inode->i_list, to);
+}
+
+void refile_inode(struct inode *inode)
+{
+	if (!inode)
+		return;
+	spin_lock(&inode_lock);
+	__refile_inode(inode);
+	spin_unlock(&inode_lock);
+}
+
 static inline void __sync_one(struct inode *inode, int sync)
 {
 	unsigned dirty;
@@ -293,7 +326,7 @@
 	list_del(&inode->i_list);
 	list_add(&inode->i_list, &inode->i_sb->s_locked_inodes);
 
-	if (inode->i_state & I_LOCK)
+	if (inode->i_state & (I_LOCK|I_FREEING))
 		BUG();
 
 	/* Set I_LOCK, reset I_DIRTY */
@@ -312,17 +345,7 @@
 
 	spin_lock(&inode_lock);
 	inode->i_state &= ~I_LOCK;
-	if (!(inode->i_state & I_FREEING)) {
-		struct list_head *to;
-		if (inode->i_state & I_DIRTY)
-			to = &inode->i_sb->s_dirty;
-		else if (atomic_read(&inode->i_count))
-			to = &inode_in_use;
-		else
-			to = &inode_unused;
-		list_del(&inode->i_list);
-		list_add(&inode->i_list, to);
-	}
+	__refile_inode(inode);
 	wake_up(&inode->i_wait);
 }
 
@@ -699,6 +722,7 @@
 	spin_lock(&inode_lock);
 	busy = invalidate_list(&inode_in_use, sb, &throw_away);
 	busy |= invalidate_list(&inode_unused, sb, &throw_away);
+	busy |= invalidate_list(&inode_unused_pagecache, sb, &throw_away);
 	busy |= invalidate_list(&sb->s_dirty, sb, &throw_away);
 	busy |= invalidate_list(&sb->s_locked_inodes, sb, &throw_away);
 	spin_unlock(&inode_lock);
@@ -762,7 +786,7 @@
 {
 	LIST_HEAD(list);
 	struct list_head *entry, *freeable = &list;
-	int count;
+	int count, avg_pages;
 	struct inode * inode;
 
 	spin_lock(&inode_lock);
@@ -785,7 +809,7 @@
 		list_add(tmp, freeable);
 		inode->i_state |= I_FREEING;
 		count++;
-		if (!--goal)
+		if (--goal <= 0)
 			break;
 	}
 	inodes_stat.nr_unused -= count;
@@ -799,8 +823,71 @@
 	 * from here or we're either synchronously dogslow
 	 * or we deadlock with oom.
 	 */
-	if (goal)
+	if (goal > 0)
 		schedule_task(&unused_inodes_flush_task);
+
+#ifdef CONFIG_HIGHMEM
+	/*
+	 * On highmem machines it is possible to have low memory
+	 * filled with inodes that cannot be reclaimed because they
+	 * have page cache pages in highmem attached to them.
+	 * This could deadlock the system if the memory used by
+	 * inodes is significant compared to the amount of freeable
+	 * low memory.  In that case we forcefully remove the page
+	 * cache pages from the inodes we want to reclaim.
+	 *
+	 * Note that this loop doesn't actually reclaim the inodes;
+	 * once the last pagecache pages belonging to the inode is
+	 * gone it will be placed on the inode_unused list and the
+	 * loop above will prune it the next time prune_icache() is
+	 * called.
+	 */
+	if (goal <= 0)
+		return;
+	if (inodes_stat.nr_unused * sizeof(struct inode) * 10 <
+				freeable_lowmem() * PAGE_SIZE)
+		return;
+
+	wakeup_bdflush();
+
+	avg_pages = page_cache_size;
+	avg_pages -= atomic_read(&buffermem_pages) + swapper_space.nrpages;
+	avg_pages = avg_pages / (inodes_stat.nr_inodes + 1);
+	spin_lock(&inode_lock);
+	while (goal-- > 0) {
+		if (list_empty(&inode_unused_pagecache))
+			break;
+		entry = inode_unused_pagecache.prev;
+		list_del(entry);
+		list_add(entry, &inode_unused_pagecache);
+
+		inode = INODE(entry);
+		/* Don't nuke inodes with lots of page cache attached. */
+		if (inode->i_mapping->nrpages > 5 * avg_pages)
+			continue;
+		/* Because of locking we grab the inode and unlock the list .*/
+		if (inode->i_state & I_LOCK)
+			continue;
+		inode->i_state |= I_LOCK;
+		spin_unlock(&inode_lock);
+
+		/*
+		 * If the inode has clean pages only, we can free all its
+		 * pagecache memory; the inode will automagically be refiled
+		 * onto the unused_list.  The wakeup_bdflush above makes
+		 * sure that all inodes become clean eventually.
+		 */
+		if (list_empty(&inode->i_mapping->dirty_pages) &&
+				!inode_has_buffers(inode))
+			invalidate_inode_pages(inode);
+
+		/* Release the inode again. */
+		spin_lock(&inode_lock);
+		inode->i_state &= ~I_LOCK;
+		wake_up(&inode->i_wait);
+	}
+	spin_unlock(&inode_lock);
+#endif /* CONFIG_HIGHMEM */
 }
 
 int shrink_icache_memory(int priority, int gfp_mask)
diff -urN linux-2.4.25-pre4/fs/readdir.c linux-2.4.25-pre5/fs/readdir.c
--- linux-2.4.25-pre4/fs/readdir.c	2004-01-15 12:10:15.000000000 -0800
+++ linux-2.4.25-pre5/fs/readdir.c	2004-01-15 12:10:24.000000000 -0800
@@ -146,6 +146,7 @@
 			}
 			spin_unlock(&dcache_lock);
 	}
+	UPDATE_ATIME(dentry->d_inode);
 	return 0;
 }
 
diff -urN linux-2.4.25-pre4/include/asm-i386/processor.h linux-2.4.25-pre5/include/asm-i386/processor.h
--- linux-2.4.25-pre4/include/asm-i386/processor.h	2003-08-25 04:44:43.000000000 -0700
+++ linux-2.4.25-pre5/include/asm-i386/processor.h	2004-01-15 12:10:24.000000000 -0800
@@ -450,7 +450,7 @@
 #define init_task	(init_task_union.task)
 #define init_stack	(init_task_union.stack)
 
-struct microcode {
+struct microcode_header {
 	unsigned int hdrver;
 	unsigned int rev;
 	unsigned int date;
@@ -458,10 +458,32 @@
 	unsigned int cksum;
 	unsigned int ldrver;
 	unsigned int pf;
-	unsigned int reserved[5];
-	unsigned int bits[500];
+	unsigned int datasize;
+	unsigned int totalsize;
+	unsigned int reserved[3];
+};
+
+struct microcode {
+	struct microcode_header hdr;
+	unsigned int bits[0];
+};
+
+typedef struct microcode microcode_t;
+typedef struct microcode_header microcode_header_t;
+
+/* microcode format is extended from prescott processors */
+struct extended_signature {
+	unsigned int sig;
+	unsigned int pf;
+	unsigned int cksum;
 };
 
+struct extended_sigtable {
+	unsigned int count;
+	unsigned int cksum;
+	unsigned int reserved[3];
+	struct extended_signature sigs[0];
+};
 /* '6' because it used to be for P6 only (but now covers Pentium 4 as well) */
 #define MICROCODE_IOCFREE	_IO('6',0)
 
diff -urN linux-2.4.25-pre4/include/asm-ppc/ibm4xx.h linux-2.4.25-pre5/include/asm-ppc/ibm4xx.h
--- linux-2.4.25-pre4/include/asm-ppc/ibm4xx.h	2003-11-28 10:26:21.000000000 -0800
+++ linux-2.4.25-pre5/include/asm-ppc/ibm4xx.h	2004-01-15 12:10:24.000000000 -0800
@@ -58,6 +58,10 @@
 
 #ifdef CONFIG_40x
 
+#if defined(CONFIG_CPCI405)
+#include <platforms/cpci405.h>
+#endif
+
 #if defined(CONFIG_OAK)
 #include <platforms/oak.h>
 #endif
diff -urN linux-2.4.25-pre4/include/asm-ppc64/machdep.h linux-2.4.25-pre5/include/asm-ppc64/machdep.h
--- linux-2.4.25-pre4/include/asm-ppc64/machdep.h	2004-01-15 12:10:15.000000000 -0800
+++ linux-2.4.25-pre5/include/asm-ppc64/machdep.h	2004-01-15 12:10:24.000000000 -0800
@@ -134,6 +134,9 @@
 	void* (*pci_dev_mem_base)(unsigned char bus, unsigned char devfn);
 	int (*pci_dev_root_bridge)(unsigned char bus, unsigned char devfn);
 
+	/* Interface for platform error logging */
+	void (*log_error)(char *buf, unsigned int err_type, int fatal);
+
 	/* this is for modules, since _machine can be a define -- Cort */
 	int ppc_machine;
 };
@@ -159,6 +162,11 @@
 /* Print a dump progress message. */
 void ppc64_dump_msg(unsigned int src, const char *msg);
 
+static inline void log_error(char *buf, unsigned int err_type, int fatal)
+{
+	if (ppc_md.log_error)
+		ppc_md.log_error(buf, err_type, fatal);
+}
 
 #endif /* _PPC_MACHDEP_H */
 #endif /* __KERNEL__ */
diff -urN linux-2.4.25-pre4/include/asm-ppc64/nvram.h linux-2.4.25-pre5/include/asm-ppc64/nvram.h
--- linux-2.4.25-pre4/include/asm-ppc64/nvram.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.25-pre5/include/asm-ppc64/nvram.h	2004-01-15 12:10:24.000000000 -0800
@@ -11,6 +11,12 @@
 #ifndef _PPC64_NVRAM_H
 #define _PPC64_NVRAM_H
 
+#define NVRW_CNT 0x20
+#define NVRAM_HEADER_LEN 16 /* sizeof(struct nvram_header) */
+#define NVRAM_BLOCK_LEN 16
+#define NVRAM_MAX_REQ (2080/NVRAM_BLOCK_LEN)
+#define NVRAM_MIN_REQ (1056/NVRAM_BLOCK_LEN)
+
 #define NVRAM_AS0  0x74
 #define NVRAM_AS1  0x75
 #define NVRAM_DATA 0x77
@@ -36,4 +42,37 @@
 #define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10)
 #endif
 
+#define NVRAM_SIG_SP	0x02	/* support processor */
+#define NVRAM_SIG_OF	0x50	/* open firmware config */
+#define NVRAM_SIG_FW	0x51	/* general firmware */
+#define NVRAM_SIG_HW	0x52	/* hardware (VPD) */
+#define NVRAM_SIG_SYS	0x70	/* system env vars */
+#define NVRAM_SIG_CFG	0x71	/* config data */
+#define NVRAM_SIG_ELOG	0x72	/* error log */
+#define NVRAM_SIG_VEND	0x7e	/* vendor defined */
+#define NVRAM_SIG_FREE	0x7f	/* Free space */
+#define NVRAM_SIG_OS	0xa0	/* OS defined */
+
+/* If change this size, then change the size of NVRAM_HEADER_LEN */
+struct nvram_header {
+	unsigned char signature;
+	unsigned char checksum;
+	unsigned short length;
+	char name[12];
+};
+
+struct nvram_partition {
+	struct list_head partition;
+	struct nvram_header header;
+	unsigned int index;
+};
+
+
+ssize_t read_nvram(char *buf, size_t count, loff_t *index);
+ssize_t write_nvram(char *buf, size_t count, loff_t *index);
+int write_error_log_nvram(char * buff, int length, unsigned int err_type);
+int read_error_log_nvram(char * buff, int length, unsigned int * err_type);
+int clear_error_log_nvram(void);
+void print_nvram_partitions(char * label);
+
 #endif /* _PPC64_NVRAM_H */
diff -urN linux-2.4.25-pre4/include/asm-ppc64/rtas.h linux-2.4.25-pre5/include/asm-ppc64/rtas.h
--- linux-2.4.25-pre4/include/asm-ppc64/rtas.h	2004-01-15 12:10:15.000000000 -0800
+++ linux-2.4.25-pre5/include/asm-ppc64/rtas.h	2004-01-15 12:10:24.000000000 -0800
@@ -182,8 +182,28 @@
 extern struct proc_dir_entry *rtas_proc_dir;
 extern struct errinjct_token ei_token_list[MAX_ERRINJCT_TOKENS];
 
+extern void pSeries_log_error(char *buf, unsigned int err_type, int fatal);
+
+/* Error types logged.  */
+#define ERR_FLAG_ALREADY_LOGGED	0x0
+#define ERR_FLAG_BOOT		0x1 	/* log was pulled from NVRAM on boot */
+#define ERR_TYPE_RTAS_LOG	0x2	/* from rtas event-scan */
+#define ERR_TYPE_KERNEL_PANIC	0x4	/* from panic() */
+
+/* All the types and not flags */
+#define ERR_TYPE_MASK	(ERR_TYPE_RTAS_LOG | ERR_TYPE_KERNEL_PANIC)
+
+#define RTAS_ERR KERN_ERR "RTAS: "
+
 #define RTAS_ERROR_LOG_MAX 1024
 
+
+/* Event Scan Parameters */
+#define EVENT_SCAN_ALL_EVENTS	0xf0000000
+#define SURVEILLANCE_TOKEN	9000
+#define LOG_NUMBER		64		/* must be a power of two */
+#define LOG_NUMBER_MASK		(LOG_NUMBER-1)
+
 /* Given an RTAS status code of 9900..9905 compute the hinted delay */
 unsigned int rtas_extended_busy_delay_time(int status);
 static inline int rtas_is_extended_busy(int status)
diff -urN linux-2.4.25-pre4/include/linux/fs.h linux-2.4.25-pre5/include/linux/fs.h
--- linux-2.4.25-pre4/include/linux/fs.h	2004-01-15 12:10:15.000000000 -0800
+++ linux-2.4.25-pre5/include/linux/fs.h	2004-01-15 12:10:24.000000000 -0800
@@ -1399,6 +1399,7 @@
 extern void inode_init_once(struct inode *);
 extern void __inode_init_once(struct inode *);
 extern void iput(struct inode *);
+extern void refile_inode(struct inode *inode);
 extern void force_delete(struct inode *);
 extern struct inode * igrab(struct inode *);
 extern struct inode * ilookup(struct super_block *, unsigned long);
diff -urN linux-2.4.25-pre4/include/linux/i2c.h linux-2.4.25-pre5/include/linux/i2c.h
--- linux-2.4.25-pre4/include/linux/i2c.h	2004-01-15 12:10:15.000000000 -0800
+++ linux-2.4.25-pre5/include/linux/i2c.h	2004-01-15 12:10:24.000000000 -0800
@@ -413,10 +413,13 @@
 /* 
  * Data for SMBus Messages 
  */
+#define I2C_SMBUS_BLOCK_MAX	32	/* As specified in SMBus standard */	
+#define I2C_SMBUS_I2C_BLOCK_MAX	32	/* Not specified but we use same structure */
 union i2c_smbus_data {
 	__u8 byte;
 	__u16 word;
-	__u8 block[33]; /* block[0] is used for length */
+	__u8 block[I2C_SMBUS_BLOCK_MAX + 2]; /* block[0] is used for length */
+	                  /* one more for read length in block process call */
 };
 
 /* smbus_access read or write markers */
diff -urN linux-2.4.25-pre4/include/linux/quota.h linux-2.4.25-pre5/include/linux/quota.h
--- linux-2.4.25-pre4/include/linux/quota.h	2003-11-28 10:26:21.000000000 -0800
+++ linux-2.4.25-pre5/include/linux/quota.h	2004-01-15 12:10:24.000000000 -0800
@@ -249,7 +249,7 @@
 	void (*free_space) (struct inode *, qsize_t);
 	void (*free_inode) (const struct inode *, unsigned long);
 	int (*transfer) (struct inode *, struct iattr *);
-	int (*sync_dquot) (struct dquot *);
+	int (*write_dquot) (struct dquot *);
 };
 
 /* Operations handling requests from userspace */
diff -urN linux-2.4.25-pre4/include/linux/sisfb.h linux-2.4.25-pre5/include/linux/sisfb.h
--- linux-2.4.25-pre4/include/linux/sisfb.h	2003-11-28 10:26:21.000000000 -0800
+++ linux-2.4.25-pre5/include/linux/sisfb.h	2004-01-15 12:10:24.000000000 -0800
@@ -1,85 +1,97 @@
+/*
+ * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the named License,
+ * or any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
+ */
+
 #ifndef _LINUX_SISFB
 #define _LINUX_SISFB
 
-#include <linux/spinlock.h>
-
 #include <asm/ioctl.h>
 #include <asm/types.h>
 
-/* TW: vbflags */
+/**********************************************/
+/*                   PUBLIC                   */
+/**********************************************/
+
+/* 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_YPBPR                0x00000080
 #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 VB_CONEXANT		0x00000800
 #define TV_PALM                 0x00001000
 #define TV_PALN                 0x00002000
+#define TV_NTSCJ		0x00001000
+#define VB_302ELV		0x00004000
 #define TV_CHSCART              0x00008000
-#define TV_CHHDTV               0x00010000
+#define TV_CHYPBPR525I          0x00010000
+#define CRT1_VGA		0x00000000
+#define CRT1_LCDA		0x00020000
 #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
-#define DISPTYPE_TV         0x00000001L
-#define DISPTYPE_DISP1      DISPTYPE_CRT1
-#define DISPTYPE_DISP2      (DISPTYPE_CRT2 | DISPTYPE_LCD | DISPTYPE_TV)
-#define DISPMODE_SINGLE	    0x00000020L
-#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
-#define HASVB_TRUMPION  	0x04
-#define HASVB_LVDS_CHRONTEL	0x10
-#define HASVB_302       	0x20
-#define HASVB_303       	0x40
-#define HASVB_CHRONTEL  	0x80
+#define VB_301LV                0x04000000
+#define VB_302LV                0x08000000
+#define VB_301C			0x10000000
+#define VB_SINGLE_MODE          0x20000000   	/* CRT1 or CRT2; determined by DISPTYPE_CRTx */
+#define VB_MIRROR_MODE		0x40000000   	/* CRT1 + CRT2 identical (mirror mode) */
+#define VB_DUALVIEW_MODE	0x80000000   	/* CRT1 + CRT2 independent (dual head mode) */
 
-/* TW: *Never* change the order of the following enum */
+/* Aliases: */
+#define CRT2_ENABLE		(CRT2_LCD | CRT2_TV | CRT2_VGA)
+#define TV_STANDARD             (TV_NTSC | TV_PAL | TV_PALM | TV_PALN | TV_NTSCJ)
+#define TV_INTERFACE            (TV_AVIDEO|TV_SVIDEO|TV_SCART|TV_HIVISION|TV_YPBPR|TV_CHSCART|TV_CHYPBPR525I)
+
+/* Only if TV_YPBPR is set: */
+#define TV_YPBPR525I		TV_NTSC
+#define TV_YPBPR525P		TV_PAL
+#define TV_YPBPR750P		TV_PALM
+#define TV_YPBPRALL 		(TV_YPBPR525I | TV_YPBPR525P | TV_YPBPR750P)
+
+#define VB_SISBRIDGE            (VB_301|VB_301B|VB_301C|VB_302B|VB_301LV|VB_302LV|VB_302ELV)
+#define VB_SISTVBRIDGE          (VB_301|VB_301B|VB_301C|VB_302B|VB_301LV|VB_302LV)
+#define VB_VIDEOBRIDGE		(VB_SISBRIDGE | VB_LVDS | VB_CHRONTEL | VB_CONEXANT)
+
+#define VB_DISPTYPE_DISP2	CRT2_ENABLE
+#define VB_DISPTYPE_CRT2	CRT2_ENABLE
+#define VB_DISPTYPE_DISP1	VB_DISPTYPE_CRT1
+#define VB_DISPMODE_SINGLE	VB_SINGLE_MODE
+#define VB_DISPMODE_MIRROR	VB_MIRROR_MODE
+#define VB_DISPMODE_DUAL	VB_DUALVIEW_MODE
+#define VB_DISPLAY_MODE       	(SINGLE_MODE | MIRROR_MODE | DUALVIEW_MODE)
+
+/* *Never* change the order of the following enum */
 typedef enum _SIS_CHIP_TYPE {
-	SIS_VGALegacy = 0,
+	SIS_VGALegacy = 0,	/* chip_id in sisfb_info */
 	SIS_300,
 	SIS_630,
 	SIS_540,
-	SIS_730, 
+	SIS_730,
 	SIS_315H,
 	SIS_315,
 	SIS_315PRO,
@@ -87,17 +99,73 @@
 	SIS_650,
 	SIS_740,
 	SIS_330,
+	SIS_661,
+	SIS_741,
 	SIS_660,
 	SIS_760,
 	MAX_SIS_CHIP
 } SIS_CHIP_TYPE;
 
-typedef enum _VGA_ENGINE {
-	UNKNOWN_VGA = 0,
-	SIS_300_VGA,
-	SIS_315_VGA,
-} VGA_ENGINE;
+/* Addtional IOCTLs for communication sisfb <> X driver                */
+/* If changing this, vgatypes.h must also be changed (for X driver)    */
+
+/* ioctl for identifying and giving some info (esp. memory heap start) */
+#define SISFB_GET_INFO	  	_IOR('n',0xF8,__u32)
+/* ioctrl to get current vertical retrace status */
+#define SISFB_GET_VBRSTATUS  	_IOR('n',0xF9,__u32)
+/* ioctl to enable/disable panning auto-maximize (like nomax parameter) */
+#define SISFB_GET_AUTOMAXIMIZE 	_IOR('n',0xFA,__u32)
+#define SISFB_SET_AUTOMAXIMIZE 	_IOW('n',0xFA,__u32)
+
+/* TW: Structure argument for SISFB_GET_INFO ioctl  */
+typedef struct _SISFB_INFO sisfb_info, *psisfb_info;
+
+struct _SISFB_INFO {
+	unsigned long sisfb_id;         /* for identifying sisfb */
+#ifndef SISFB_ID
+#define SISFB_ID	  0x53495346    /* Identify myself with 'SISF' */
+#endif
+ 	int    chip_id;			/* PCI ID of detected chip */
+	int    memory;			/* video memory in KB which sisfb manages */
+	int    heapstart;               /* heap start (= sisfb "mem" argument) in KB */
+	unsigned char fbvidmode;	/* current sisfb mode */
+
+	unsigned char sisfb_version;
+	unsigned char sisfb_revision;
+	unsigned char sisfb_patchlevel;
+
+	unsigned char sisfb_caps;	/* Sisfb capabilities */
+
+	int    sisfb_tqlen;		/* turbo queue length (in KB) */
+
+	unsigned int sisfb_pcibus;      /* The card's PCI ID */
+	unsigned int sisfb_pcislot;
+	unsigned int sisfb_pcifunc;
+
+	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;
+
+	unsigned char sisfb_haveemi;
+	unsigned char sisfb_emi30,sisfb_emi31,sisfb_emi32,sisfb_emi33;
+	unsigned char sisfb_haveemilcd;
+
+	char reserved[213]; 		/* for future use */
+};
+
+/* For fb memory manager */
+struct sis_memreq {
+	unsigned long offset;
+	unsigned long size;
+};
 
+/* More or less deprecated stuff follows: */
 typedef enum _TVTYPE {
 	TVMODE_NTSC = 0,
 	TVMODE_PAL,
@@ -113,19 +181,14 @@
 	TVPLUG_TOTAL
 } SIS_TV_PLUG;
 
-struct sis_memreq {
-	unsigned long offset;
-	unsigned long size;
-};
-
 struct mode_info {
 	int    bpp;
 	int    xres;
 	int    yres;
-	int    v_xres;
-	int    v_yres;
-	int    org_x;
-	int    org_y;
+	int    v_xres;		/* deprecated - use var instead */
+	int    v_yres;		/* deprecated - use var instead */
+	int    org_x;		/* deprecated - use var instead */
+	int    org_y;		/* deprecated - use var instead */
 	unsigned int  vrate;
 };
 
@@ -133,7 +196,7 @@
 	struct mode_info minfo;
 	unsigned long iobase;
 	unsigned int  mem_size;
-	unsigned long disp_state;  /* deprecated */  	
+	unsigned long disp_state;  /* deprecated */
 	SIS_CHIP_TYPE chip;
 	unsigned char hasVB;
 	SIS_TV_TYPE TV_type;	   /* deprecated */
@@ -144,6 +207,19 @@
 	char reserved[248];
 };
 
+/**********************************************/
+/*                  PRIVATE                   */
+/**********************************************/
+
+#ifdef __KERNEL__
+#include <linux/spinlock.h>
+
+typedef enum _VGA_ENGINE {
+	UNKNOWN_VGA = 0,
+	SIS_300_VGA,
+	SIS_315_VGA,
+} VGA_ENGINE;
+
 struct video_info {
 	int           chip_id;
 	unsigned int  video_size;
@@ -159,10 +235,10 @@
 	int    video_cmap_len;
 	int    video_width;
 	int    video_height;
-	int    video_vwidth;
-	int    video_vheight;
-	int    org_x;
-	int    org_y;
+	int    video_vwidth;			/* DEPRECATED - use var instead */
+	int    video_vheight;			/* DEPRECATED - use var instead */
+	int    org_x;				/* DEPRECATED - use var instead */
+	int    org_y;				/* DEPRECATED - use var instead */
 	int    video_linelength;
 	unsigned int refresh_rate;
 
@@ -174,11 +250,11 @@
 	SIS_CHIP_TYPE chip;
 	unsigned char revision_id;
 
-        unsigned short DstColor;		/* TW: For 2d acceleration */
+        unsigned short DstColor;		/* For 2d acceleration */
 	unsigned long  SiS310_AccelDepth;
 	unsigned long  CommandReg;
 
-	spinlock_t     lockaccel;
+	spinlock_t     lockaccel;		/* Do not use outside of kernel! */
 
         unsigned int   pcibus;
 	unsigned int   pcislot;
@@ -188,10 +264,10 @@
 
 	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;
@@ -203,54 +279,6 @@
 	char reserved[200];
 };
 
-
-/* TW: Addtional IOCTL for communication sisfb <> X driver                 */
-/*     If changing this, vgatypes.h must also be changed (for X driver)    */
-
-/* TW: ioctl for identifying and giving some info (esp. memory heap start) */
-#define SISFB_GET_INFO	  	_IOR('n',0xF8,sizeof(__u32))
-
-#define SISFB_GET_VBRSTATUS  	_IOR('n',0xF9,sizeof(__u32))
-
-/* TW: Structure argument for SISFB_GET_INFO ioctl  */
-typedef struct _SISFB_INFO sisfb_info, *psisfb_info;
-
-struct _SISFB_INFO {
-	unsigned long sisfb_id;         /* for identifying sisfb */
-#ifndef SISFB_ID
-#define SISFB_ID	  0x53495346    /* Identify myself with 'SISF' */
-#endif
- 	int    chip_id;			/* PCI ID of detected chip */
-	int    memory;			/* video memory in KB which sisfb manages */
-	int    heapstart;               /* heap start (= sisfb "mem" argument) in KB */
-	unsigned char fbvidmode;	/* current sisfb mode */
-	
-	unsigned char sisfb_version;
-	unsigned char sisfb_revision;
-	unsigned char sisfb_patchlevel;
-
-	unsigned char sisfb_caps;	/* Sisfb capabilities */
-
-	int    sisfb_tqlen;		/* turbo queue length (in KB) */
-
-	unsigned int sisfb_pcibus;      /* The card's PCI ID */
-	unsigned int sisfb_pcislot;
-	unsigned int sisfb_pcifunc;
-
-	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[219]; 		/* for future use */
-};
-
-#ifdef __KERNEL__
 extern struct video_info ivideo;
 
 extern void sis_malloc(struct sis_memreq *req);
diff -urN linux-2.4.25-pre4/include/linux/swap.h linux-2.4.25-pre5/include/linux/swap.h
--- linux-2.4.25-pre4/include/linux/swap.h	2003-11-28 10:26:21.000000000 -0800
+++ linux-2.4.25-pre5/include/linux/swap.h	2004-01-15 12:10:24.000000000 -0800
@@ -85,6 +85,7 @@
 
 extern unsigned int nr_free_pages(void);
 extern unsigned int nr_free_buffer_pages(void);
+extern unsigned int freeable_lowmem(void);
 extern int nr_active_pages;
 extern int nr_inactive_pages;
 extern unsigned long page_cache_size;
diff -urN linux-2.4.25-pre4/mm/filemap.c linux-2.4.25-pre5/mm/filemap.c
--- linux-2.4.25-pre4/mm/filemap.c	2004-01-15 12:10:15.000000000 -0800
+++ linux-2.4.25-pre5/mm/filemap.c	2004-01-15 12:10:24.000000000 -0800
@@ -102,6 +102,8 @@
 	page->mapping = NULL;
 	wmb();
 	mapping->nrpages--;
+	if (!mapping->nrpages)
+		refile_inode(mapping->host);
 }
 
 static inline void remove_page_from_hash_queue(struct page * page)
diff -urN linux-2.4.25-pre4/mm/page_alloc.c linux-2.4.25-pre5/mm/page_alloc.c
--- linux-2.4.25-pre4/mm/page_alloc.c	2004-01-15 12:10:15.000000000 -0800
+++ linux-2.4.25-pre5/mm/page_alloc.c	2004-01-15 12:10:24.000000000 -0800
@@ -534,6 +534,23 @@
 
 	return pages;
 }
+
+unsigned int freeable_lowmem(void)
+{
+	unsigned int pages = 0;
+	pg_data_t *pgdat;
+
+	for_each_pgdat(pgdat) {
+		pages += pgdat->node_zones[ZONE_DMA].free_pages;
+		pages += pgdat->node_zones[ZONE_DMA].nr_active_pages;
+		pages += pgdat->node_zones[ZONE_DMA].nr_inactive_pages;
+		pages += pgdat->node_zones[ZONE_NORMAL].free_pages;
+		pages += pgdat->node_zones[ZONE_NORMAL].nr_active_pages;
+		pages += pgdat->node_zones[ZONE_NORMAL].nr_inactive_pages;
+	}
+
+	return pages;
+}
 #endif
 
 #define K(x) ((x) << (PAGE_SHIFT-10))
