From: Thomas Winischhofer <thomas@winischhofer.net>

attached is an update for sisfb, lifting it up to version 1.7.17.

It contains all changes done behind my back by other people (viro,
torvalds, adaplas) in the meantime. Furthermore,

- all remaining sparse warnings were fixed (mainly caused by the ROM code)

- problems with very old and brand new BIOSes from SiS were fixed,

- LCD setup was simplified, allowing more display modes than before,

- UMC/charter bridge type handling was added,

- a code clean-up was performed, the new FB_BLANK-flags were taken over,
VBLANK status info was corrected, etc.

Signed-off-by: Thomas Winischhofer <thomas@winischhofer.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/drivers/video/sis/300vtbl.h  |  185 ++--
 25-akpm/drivers/video/sis/310vtbl.h  |  213 ++++-
 25-akpm/drivers/video/sis/init.c     |  643 +++++++++-------
 25-akpm/drivers/video/sis/init.h     |  533 +++++++-------
 25-akpm/drivers/video/sis/init301.c  | 1330 +++++++++++++++++++++--------------
 25-akpm/drivers/video/sis/init301.h  |  154 +---
 25-akpm/drivers/video/sis/initdef.h  |   26 
 25-akpm/drivers/video/sis/oem300.h   |   36 
 25-akpm/drivers/video/sis/oem310.h   |    2 
 25-akpm/drivers/video/sis/osdef.h    |   25 
 25-akpm/drivers/video/sis/sis.h      |  164 +++-
 25-akpm/drivers/video/sis/sis_main.c |  236 +++---
 25-akpm/drivers/video/sis/sis_main.h |   75 +
 25-akpm/drivers/video/sis/vgatypes.h |   63 -
 25-akpm/drivers/video/sis/vstruct.h  |   19 
 drivers/video/sis/sis_accel.c        |    0 
 drivers/video/sis/sis_accel.h        |    0 
 include/video/sisfb.h                |    0 
 18 files changed, 2112 insertions(+), 1592 deletions(-)

diff -puN drivers/video/sis/300vtbl.h~fbdev-sis-framebuffer-driver-update-1717 drivers/video/sis/300vtbl.h
--- 25/drivers/video/sis/300vtbl.h~fbdev-sis-framebuffer-driver-update-1717	2004-11-28 01:30:58.852563432 -0800
+++ 25-akpm/drivers/video/sis/300vtbl.h	2004-11-28 01:30:58.889557808 -0800
@@ -35,7 +35,7 @@
  * * 3) 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 EXPRESSED OR
+ * * 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,
@@ -80,12 +80,12 @@ static const SiS_ExtStruct  SiS300_EMode
 	{0x2e,0x0a1b,0x0101,SIS_RI_640x480,  0x00,0x00,0x00,0x00,0x08,-1},
 	{0x2f,0x021b,0x0100,SIS_RI_640x400,  0x00,0x00,0x00,0x00,0x10,-1},  /* 640x400x8 */
 	{0x30,0x2a1b,0x0103,SIS_RI_800x600,  0x00,0x00,0x00,0x00,0x00,-1},
-	{0x31,0x0a1b,0x0000,SIS_RI_720x480,  0x00,0x00,0x00,0x00,0x11,-1},  /* 720x480x8 */
-	{0x32,0x2a1b,0x0000,SIS_RI_720x576,  0x00,0x00,0x00,0x00,0x12,-1},  /* 720x576x8 */
-	{0x33,0x0a1d,0x0000,SIS_RI_720x480,  0x00,0x00,0x00,0x00,0x11,-1},  /* 720x480x16 */
-	{0x34,0x2a1d,0x0000,SIS_RI_720x576,  0x00,0x00,0x00,0x00,0x12,-1},  /* 720x576x16 */
-	{0x35,0x0a1f,0x0000,SIS_RI_720x480,  0x00,0x00,0x00,0x00,0x11,-1},  /* 720x480x32 */
-	{0x36,0x2a1f,0x0000,SIS_RI_720x576,  0x00,0x00,0x00,0x00,0x12,-1},  /* 720x576x32 */
+	{0x31,0x4a1b,0x0000,SIS_RI_720x480,  0x00,0x00,0x00,0x00,0x11,-1},  /* 720x480x8 */
+	{0x32,0x6a1b,0x0000,SIS_RI_720x576,  0x00,0x00,0x00,0x00,0x12,-1},  /* 720x576x8 */
+	{0x33,0x4a1d,0x0000,SIS_RI_720x480,  0x00,0x00,0x00,0x00,0x11,-1},  /* 720x480x16 */
+	{0x34,0x6a1d,0x0000,SIS_RI_720x576,  0x00,0x00,0x00,0x00,0x12,-1},  /* 720x576x16 */
+	{0x35,0x4a1f,0x0000,SIS_RI_720x480,  0x00,0x00,0x00,0x00,0x11,-1},  /* 720x480x32 */
+	{0x36,0x6a1f,0x0000,SIS_RI_720x576,  0x00,0x00,0x00,0x00,0x12,-1},  /* 720x576x32 */
 	{0x37,0x0212,0x0104,SIS_RI_1024x768, 0x00,0x00,0x00,0x00,0x13,-1},  /* 1024x768x? */
 	{0x38,0x0a1b,0x0105,SIS_RI_1024x768, 0x00,0x00,0x00,0x00,0x13,-1},  /* 1024x768x8 */
 	{0x3a,0x0e3b,0x0107,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a,-1},  /* 1280x1024x8 */
@@ -121,48 +121,48 @@ static const SiS_ExtStruct  SiS300_EMode
 	{0x6b,0x07ff,0x0000,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x27,-1},
 	{0x6c,0x067b,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x00,0x28,-1},  /* 2048x1536x8 - not in BIOS! */
 	{0x6d,0x06fd,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x00,0x28,-1},  /* 2048x1536x16 - not in BIOS! */
-	{0x70,0x2a1b,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x00,0x2d,-1},  /* 800x480x8 */
-	{0x71,0x0a1b,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x30,-1},  /* 1024x576x8 */
-	{0x74,0x0a1d,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x30,-1},  /* 1024x576x16 */
+	{0x70,0x6a1b,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x00,0x2d,-1},  /* 800x480x8 */
+	{0x71,0x4a1b,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x30,-1},  /* 1024x576x8 */
+	{0x74,0x4a1d,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x30,-1},  /* 1024x576x16 */
 	{0x75,0x0e3d,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x33,-1},  /* 1280x720x16 */
-	{0x76,0x2a1f,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x00,0x2d,-1},  /* 800x480x32 */
-	{0x77,0x0a3f,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x30,-1},  /* 1024x576x32 */
+	{0x76,0x6a1f,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x00,0x2d,-1},  /* 800x480x32 */
+	{0x77,0x4a3f,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x30,-1},  /* 1024x576x32 */
 	{0x78,0x0eff,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x33,-1},  /* 1280x720x32 */
 	{0x79,0x0e3b,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x33,-1},  /* 1280x720x8 */
-	{0x7a,0x2a1d,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x00,0x2d,-1},  /* 800x480x16 */
+	{0x7a,0x6a1d,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x00,0x2d,-1},  /* 800x480x16 */
 	{0x7c,0x0a3b,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x00,0x29,-1},  /* 1280x960x8 */
 	{0x7d,0x0a7d,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x00,0x29,-1},  /* 1280x960x16 */
 	{0x7e,0x0aff,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x00,0x29,-1},  /* 1280x960x32 */
-	{0x20,0x0a1b,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x00,0x2b,-1},  /* 1024x600 */
-	{0x21,0x0a3d,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x00,0x2b,-1},
-	{0x22,0x0a7f,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x00,0x2b,-1},
-	{0x23,0x0a1b,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x00,0x2c,-1},  /* 1152x768 */
-	{0x24,0x0a3d,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x00,0x2c,-1},
-	{0x25,0x0a7f,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x00,0x2c,-1},
-	{0x29,0x0e1b,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x36,-1},  /* 1152x864 */
-	{0x2a,0x0e3d,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x36,-1},
-	{0x2b,0x0e7f,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x36,-1},
-	{0x39,0x2a1b,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x00,0x38,-1},  /* 848x480 */
-	{0x3b,0x2a3d,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x00,0x38,-1},
-	{0x3e,0x2a7f,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x00,0x38,-1},
-	{0x3f,0x2a1b,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x00,0x3a,-1},  /* 856x480 */
-	{0x42,0x2a3d,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x00,0x3a,-1},
-	{0x45,0x2a7f,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x00,0x3a,-1},
-	{0x48,0x223b,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x3c,-1},  /* 1360x768 */
-	{0x4b,0x227d,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x3c,-1},
-	{0x4e,0x22ff,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x3c,-1},
+	{0x20,0x4a1b,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x00,0x2b,-1},  /* 1024x600 */
+	{0x21,0x4a3d,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x00,0x2b,-1},
+	{0x22,0x4a7f,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x00,0x2b,-1},
+	{0x23,0x4a1b,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x00,0x2c,-1},  /* 1152x768 */
+	{0x24,0x4a3d,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x00,0x2c,-1},
+	{0x25,0x4a7f,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x00,0x2c,-1},
+	{0x29,0x4e1b,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x36,-1},  /* 1152x864 */
+	{0x2a,0x4e3d,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x36,-1},
+	{0x2b,0x4e7f,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x36,-1},
+	{0x39,0x6a1b,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x00,0x39,-1},  /* 848x480 */
+	{0x3b,0x6a3d,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x00,0x39,-1},
+	{0x3e,0x6a7f,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x00,0x39,-1},
+	{0x3f,0x6a1b,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x00,0x3b,-1},  /* 856x480 */
+	{0x42,0x6a3d,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x00,0x3b,-1},
+	{0x45,0x6a7f,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x00,0x3b,-1},
+	{0x48,0x6a3b,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x3d,-1},  /* 1360x768 */
+	{0x4b,0x6a7d,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x3d,-1},
+	{0x4e,0x6aff,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x3d,-1},
 	{0x4f,0x921f,0x0000,SIS_RI_320x200,  0x00,0x00,0x00,0x00,0x23,-1},  /* 320x200x32 */
 	{0x53,0x921f,0x0000,SIS_RI_320x240,  0x00,0x00,0x00,0x00,0x24,-1},  /* 320x240x32 */
 	{0x54,0xb21f,0x0000,SIS_RI_400x300,  0x00,0x00,0x00,0x00,0x25,-1},  /* 400x300x32 */
-	{0x55,0x2e3b,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x3d,-1},  /* 1280x768   */
-	{0x5a,0x2e7d,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x3d,-1},
-	{0x5b,0x2eff,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x3d,-1},
-	{0x5f,0x2a1b,0x0000,SIS_RI_768x576,  0x00,0x00,0x00,0x00,0x3e,-1},  /* 768x576x8 */
-	{0x60,0x2a1d,0x0000,SIS_RI_768x576,  0x00,0x00,0x00,0x00,0x3e,-1},  /* 768x576x16 */
-	{0x61,0x2a1f,0x0000,SIS_RI_768x576,  0x00,0x00,0x00,0x00,0x3e,-1},  /* 768x576x32 */
-	{0x67,0x2e3b,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x00,0x3f,-1},  /* 1360x1024x8 (BARCO) */
-	{0x6f,0x2e7d,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x00,0x3f,-1},  /* 1360x1024x16 (BARCO) */
-	{0x72,0x2eff,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x00,0x3f,-1},  /* 1360x1024x32 (BARCO) */
+	{0x55,0x2e3b,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x3e,-1},  /* 1280x768   */
+	{0x5a,0x2e7d,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x3e,-1},
+	{0x5b,0x2eff,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x3e,-1},
+	{0x5f,0x6a1b,0x0000,SIS_RI_768x576,  0x00,0x00,0x00,0x00,0x3f,-1},  /* 768x576x8 */
+	{0x60,0x6a1d,0x0000,SIS_RI_768x576,  0x00,0x00,0x00,0x00,0x3f,-1},  /* 768x576x16 */
+	{0x61,0x6a1f,0x0000,SIS_RI_768x576,  0x00,0x00,0x00,0x00,0x3f,-1},  /* 768x576x32 */
+	{0x67,0x6e3b,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x00,0x40,-1},  /* 1360x1024x8 (BARCO) */
+	{0x6f,0x6e7d,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x00,0x40,-1},  /* 1360x1024x16 (BARCO) */
+	{0x72,0x6eff,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x00,0x40,-1},  /* 1360x1024x32 (BARCO) */
 	{0xff,0x0000,0xffff,0,               0x00,0x00,0x00,0x00,0x00}
 };
 
@@ -170,34 +170,34 @@ static const SiS_Ext2Struct  SiS300_RefI
 {
 	{0x085f,0x0d,0x03,0x05,0x05,0x6a, 800, 600, 0}, /* 00 */
 	{0x0467,0x0e,0x44,0x05,0x05,0x6a, 800, 600, 0}, /* 01 */
-	{0x0067,0x0f,0x07,0x48,0x00,0x6a, 800, 600, 0}, /* 02 - CRT1CRTC was 0x4f */
-	{0x0067,0x10,0x06,0x8b,0x00,0x6a, 800, 600, 0}, /* 03 */
-	{0x0147,0x11,0x08,0x00,0x00,0x6a, 800, 600, 0}, /* 04 */
-	{0x0147,0x12,0x0c,0x00,0x00,0x6a, 800, 600, 0}, /* 05 */
-	{0x0047,0x11,0x4e,0x00,0x00,0x6a, 800, 600, 0}, /* 06 - CRT1CRTC was 0x51 */
-	{0x0047,0x11,0x13,0x00,0x00,0x6a, 800, 600, 0}, /* 07 */
+	{0x0067,0x0f,0x07,0x48,0x05,0x6a, 800, 600, 0}, /* 02 - CRT1CRTC was 0x4f */
+	{0x0067,0x10,0x06,0x8b,0x05,0x6a, 800, 600, 0}, /* 03 */
+	{0x0147,0x11,0x08,0x00,0x05,0x6a, 800, 600, 0}, /* 04 */
+	{0x0147,0x12,0x0c,0x00,0x05,0x6a, 800, 600, 0}, /* 05 */
+	{0x0047,0x11,0x4e,0x00,0x05,0x6a, 800, 600, 0}, /* 06 - CRT1CRTC was 0x51 */
+	{0x0047,0x11,0x13,0x00,0x05,0x6a, 800, 600, 0}, /* 07 */
 	{0xc85f,0x05,0x00,0x04,0x04,0x2e, 640, 480, 0}, /* 08 */
 	{0xc067,0x06,0x02,0x04,0x04,0x2e, 640, 480, 0}, /* 09 */
 	{0xc067,0x07,0x02,0x47,0x04,0x2e, 640, 480, 0}, /* 0a */
 	{0xc067,0x08,0x03,0x8a,0x04,0x2e, 640, 480, 0}, /* 0b */
-	{0xc047,0x09,0x05,0x00,0x00,0x2e, 640, 480, 0}, /* 0c */
-	{0xc047,0x0a,0x08,0x00,0x00,0x2e, 640, 480, 0}, /* 0d */
-	{0xc047,0x0b,0x0a,0x00,0x00,0x2e, 640, 480, 0}, /* 0e */
-	{0xc047,0x0c,0x10,0x00,0x00,0x2e, 640, 480, 0}, /* 0f */
+	{0xc047,0x09,0x05,0x00,0x04,0x2e, 640, 480, 0}, /* 0c */
+	{0xc047,0x0a,0x08,0x00,0x04,0x2e, 640, 480, 0}, /* 0d */
+	{0xc047,0x0b,0x0a,0x00,0x04,0x2e, 640, 480, 0}, /* 0e */
+	{0xc047,0x0c,0x10,0x00,0x04,0x2e, 640, 480, 0}, /* 0f */
 	{0x487f,0x04,0x00,0x00,0x00,0x2f, 640, 400, 0}, /* 10 */
-	{0xc04f,0x31,0x01,0x06,0x00,0x31, 720, 480, 0}, /* 11 */
-	{0x004f,0x32,0x03,0x06,0x00,0x32, 720, 576, 0}, /* 12 */
-	{0x0187,0x15,0x05,0x00,0x00,0x37,1024, 768, 0}, /* 13 */
+	{0xc06f,0x31,0x01,0x06,0x13,0x31, 720, 480, 0}, /* 11 */
+	{0x006f,0x32,0x03,0x06,0x14,0x32, 720, 576, 0}, /* 12 */
+	{0x0187,0x15,0x05,0x00,0x06,0x37,1024, 768, 0}, /* 13 */
         {0xc877,0x16,0x09,0x06,0x06,0x37,1024, 768, 0}, /* 14 */
 	{0xc067,0x17,0x0b,0x49,0x06,0x37,1024, 768, 0}, /* 15 - CRT1CRTC was 0x97 */
 	{0x0267,0x18,0x0d,0x00,0x06,0x37,1024, 768, 0}, /* 16 */
-	{0x0047,0x19,0x11,0x8c,0x00,0x37,1024, 768, 0}, /* 17 - CRT1CRTC was 0x59 */
-	{0x0047,0x1a,0x52,0x00,0x00,0x37,1024, 768, 0}, /* 18 */
-	{0x0007,0x1b,0x16,0x00,0x00,0x37,1024, 768, 0}, /* 19 - CRT1CRTC was 0x5b */
-	{0x0387,0x1c,0x4d,0x00,0x00,0x3a,1280,1024, 0}, /* 1a - CRT1CRTC was 0x5c */
-	{0x0077,0x1d,0x14,0x07,0x00,0x3a,1280,1024, 0}, /* 1b */
-	{0x0047,0x1e,0x17,0x00,0x00,0x3a,1280,1024, 0}, /* 1c */
-	{0x0007,0x1f,0x98,0x00,0x00,0x3a,1280,1024, 0}, /* 1d */
+	{0x0047,0x19,0x11,0x8c,0x06,0x37,1024, 768, 0}, /* 17 - CRT1CRTC was 0x59 */
+	{0x0047,0x1a,0x52,0x00,0x06,0x37,1024, 768, 0}, /* 18 */
+	{0x0007,0x1b,0x16,0x00,0x06,0x37,1024, 768, 0}, /* 19 - CRT1CRTC was 0x5b */
+	{0x0387,0x1c,0x4d,0x00,0x07,0x3a,1280,1024, 0}, /* 1a - CRT1CRTC was 0x5c */
+	{0x0077,0x1d,0x14,0x07,0x07,0x3a,1280,1024, 0}, /* 1b */
+	{0x0047,0x1e,0x17,0x00,0x07,0x3a,1280,1024, 0}, /* 1c */
+	{0x0007,0x1f,0x98,0x00,0x07,0x3a,1280,1024, 0}, /* 1d */
 	{0x0007,0x20,0x59,0x00,0x00,0x3c,1600,1200, 0}, /* 1e - CRT1CRTC was 0x60 */
 	{0x0007,0x21,0x5a,0x00,0x00,0x3c,1600,1200, 0}, /* 1f */
 	{0x0007,0x22,0x1b,0x00,0x00,0x3c,1600,1200, 0}, /* 20 */
@@ -213,25 +213,26 @@ static const SiS_Ext2Struct  SiS300_RefI
 	{0x0027,0x45,0x3c,0x08,0x0a,0x6e,1280, 960, 0}, /* 2a - 1280x960-85 */
 	{0xc077,0x33,0x09,0x06,0x00,0x20,1024, 600, 0}, /* 2b */
 	{0xc077,0x34,0x0b,0x06,0x00,0x23,1152, 768, 0}, /* 2c */	/* VCLK 0x09 */
-	{0x0057,0x35,0x27,0x08,0x00,0x70, 800, 480, 0}, /* 2d */
-	{0x0047,0x36,0x37,0x08,0x00,0x70, 800, 480, 0}, /* 2e */
-	{0x0047,0x37,0x08,0x08,0x00,0x70, 800, 480, 0}, /* 2f */
-	{0x0057,0x38,0x09,0x09,0x00,0x71,1024, 576, 0}, /* 30 */
-	{0x0047,0x39,0x38,0x09,0x00,0x71,1024, 576, 0}, /* 31 */
-	{0x0047,0x3a,0x11,0x09,0x00,0x71,1024, 576, 0}, /* 32 */
-	{0x0057,0x3b,0x39,0x0a,0x00,0x75,1280, 720, 0}, /* 33 */
-	{0x0047,0x3c,0x3a,0x0a,0x00,0x75,1280, 720, 0}, /* 34 */
-	{0x0007,0x3d,0x3b,0x0a,0x00,0x75,1280, 720, 0}, /* 35 */
-	{0x0047,0x3e,0x34,0x06,0x00,0x29,1152, 864, 0}, /* 36 1152x864-75Hz */
-	{0x0047,0x44,0x3a,0x06,0x00,0x29,1152, 864, 0}, /* 37 1152x864-85Hz */
-	{0x00c7,0x3f,0x28,0x00,0x00,0x39, 848, 480, 0}, /* 38 848x480-38Hzi */
-	{0xc067,0x40,0x3d,0x0b,0x0b,0x39, 848, 480, 0}, /* 39 848x480-60Hz  */
-	{0x00c7,0x41,0x28,0x00,0x00,0x3f, 856, 480, 0}, /* 3a 856x480-38Hzi */
-	{0xc047,0x42,0x28,0x00,0x00,0x3f, 856, 480, 0}, /* 3b 856x480-60Hz  */
-	{0x0067,0x43,0x3e,0x0c,0x0b,0x48,1360, 768, 0}, /* 3c 1360x768-60Hz */
-	{0x0077,0x46,0x3f,0x08,0x00,0x55,1280, 768, 0}, /* 3d 1280x768-60Hz */
-	{0x004f,0x47,0x03,0x06,0x00,0x5f, 768, 576, 0}, /* 3e 768x576 */
-	{0x0027,0x48,0x13,0x08,0x08,0x67,1360,1024, 0}, /* 3f 1360x1024-59Hz (BARCO1366 only) */
+	{0x0077,0x35,0x27,0x08,0x18,0x70, 800, 480, 0}, /* 2d */
+	{0x0047,0x36,0x37,0x08,0x18,0x70, 800, 480, 0}, /* 2e */
+	{0x0047,0x37,0x08,0x08,0x18,0x70, 800, 480, 0}, /* 2f */
+	{0x0077,0x38,0x09,0x09,0x19,0x71,1024, 576, 0}, /* 30 */
+	{0x0047,0x39,0x38,0x09,0x19,0x71,1024, 576, 0}, /* 31 */
+	{0x0047,0x3a,0x11,0x09,0x19,0x71,1024, 576, 0}, /* 32 */
+	{0x0077,0x3b,0x39,0x0a,0x0c,0x75,1280, 720, 0}, /* 33 */
+	{0x0047,0x3c,0x3a,0x0a,0x0c,0x75,1280, 720, 0}, /* 34 */
+	{0x0007,0x3d,0x3b,0x0a,0x0c,0x75,1280, 720, 0}, /* 35 */
+	{0x0067,0x49,0x35,0x06,0x1a,0x29,1152, 864, 0}, /* 36 1152x864-60Hz  */
+	{0x0067,0x3e,0x34,0x06,0x1a,0x29,1152, 864, 0}, /* 37 1152x864-75Hz */
+	{0x0047,0x44,0x3a,0x06,0x1a,0x29,1152, 864, 0}, /* 38 1152x864-85Hz */
+	{0x00c7,0x3f,0x28,0x00,0x16,0x39, 848, 480, 0}, /* 39 848x480-38Hzi */
+	{0xc067,0x40,0x3d,0x0b,0x16,0x39, 848, 480, 0}, /* 3a 848x480-60Hz  */
+	{0x00c7,0x41,0x28,0x00,0x17,0x3f, 856, 480, 0}, /* 3b 856x480-38Hzi */
+	{0xc047,0x42,0x28,0x00,0x17,0x3f, 856, 480, 0}, /* 3c 856x480-60Hz  */
+	{0x0067,0x43,0x3e,0x0c,0x1b,0x48,1360, 768, 0}, /* 3d 1360x768-60Hz */
+	{0x0077,0x46,0x3f,0x08,0x08,0x55,1280, 768, 0}, /* 3e 1280x768-60Hz */
+	{0x006f,0x47,0x03,0x06,0x15,0x5f, 768, 576, 0}, /* 3f 768x576 */
+	{0x0027,0x48,0x13,0x08,0x00,0x67,1360,1024, 0}, /* 40 1360x1024-59Hz (BARCO1366 only) */
 	{0xffff,   0,   0,   0,   0,   0,   0,   0, 0}
 };
 
@@ -378,7 +379,7 @@ static const SiS_CRT1TableStruct  SiS300
   0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x01,
   0x00}},
  {{0x65,0x4f,0x4f,0x89,0x57,0x9f,0xfb,0x1f,
-  0xe6,0x8a,0xdf,0xdf,0xfc,0x10,0x00,0x01,    /* TW: Corrected VDE, VBE */
+  0xe6,0x8a,0xdf,0xdf,0xfc,0x10,0x00,0x01,    /* Corrected VDE, VBE */
   0x00}},
  {{0x7b,0x63,0x63,0x9f,0x6a,0x93,0x6f,0xf0,
   0x58,0x8a,0x57,0x57,0x70,0x20,0x00,0x05,
@@ -558,13 +559,16 @@ static const SiS_CRT1TableStruct  SiS300
    0x01}}, /* 0x45 */
  {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x20,0xf5,  /* 1280x768-60 */
    0x03,0x88,0xff,0xff,0x21,0x10,0x00,0x07,
-   0x01}},  /* 0x46 */
+   0x01}}, /* 0x46 */
  {{0x7b,0x5f,0x63,0x9f,0x6a,0x93,0x6f,0xf0,  /* 768x576 */
    0x58,0x8a,0x3f,0x57,0x70,0x20,0x00,0x05,
-   0x01}},  /* 0x47 */
+   0x01}}, /* 0x47 */
  {{0xce,0xa9,0xa9,0x92,0xb1,0x07,0x28,0x52,  /* 1360x1024 (Barco iQ Pro R300) */
    0x02,0x8e,0xff,0x00,0x29,0x0d,0x00,0x03,
-   0x00}}   /* 0x48 */
+   0x00}}, /* 0x48 */
+ {{0xcd,0x8f,0x8f,0x91,0x9b,0x1b,0x7a,0xff,  /* 1152x864-60 */
+   0x64,0x8c,0x5f,0x62,0x7b,0x10,0x00,0x07,
+   0x41}}  /* 0x49 */
 };
 
 static const SiS_MCLKDataStruct  SiS300_MCLKData_630[] =
@@ -646,7 +650,7 @@ static SiS_VCLKDataStruct SiS300_VCLKDat
 	{ 0x52,0x4a, 36}, /* 0x32 */  /* CH/PAL 800x600 5/6 */
 	{ 0x34,0x61, 95}, /* 0x33 */
 	{ 0x78,0x27,108}, /* 0x34 */  /* Replacement for index 0x14 for 630 (?) */
-	{ 0xce,0x25,189}, /* 0x35 */  /* Replacement for index 0x1b for 730 (and 540?) */
+	{ 0x70,0x28, 90}, /* 0x35 */  /* 1152x864@60 */
 	{ 0x45,0x6b, 21}, /* 0x36 */  /* Chrontel SuperOverscan */
 	{ 0x52,0xe2, 49}, /* 0x37 */  /* 16:9 modes  */
 	{ 0x2b,0x61, 78}, /* 0x38 */  /* 16:9 modes  */
@@ -656,20 +660,19 @@ static SiS_VCLKDataStruct SiS300_VCLKDat
 	{ 0x52,0x07,149}, /* 0x3c */  /* 1280x960-85 */
 	{ 0x62,0xc6, 34}, /* 0x3d */  /* 848x480-60  */
 	{ 0x30,0x23, 88}, /* 0x3e */  /* 1360x768-60 */
-#if 0
-	{ 0x3f,0x64, 46}, /* 0x3f */  /* 640x480-100 */
-#endif
         { 0x70,0x29, 81}, /* 0x3f */  /* 1280x768-60 */
-	{ 0x72,0x2a, 76}, /* 0x40 */  /* test for SiS730 */
+	{ 0x72,0x2a, 76}, /* 0x40 */  /* test for SiS730 --- LIMIT for table (&0x3f) */
 	{ 0x15,0x21, 79}, /* 0x41 */  /* test for SiS730 */
 	{ 0xa1,0x42,108}, /* 0x42 */  /* 1280x960 LCD */
 	{ 0x37,0x61,100}, /* 0x43 */  /* 1280x960 LCD */
 	{ 0xe3,0x9a,106}, /* 0x44 */  /* 1360x1024 - special for Barco iQ R300 */
 	{ 0xe2,0x46,135}, /* 0x45 */  /* 1280x1024-75, better clock for VGA2 */
-	{    0,   0,  0}  /* 0x46 custom (will be filled out) */
+	{ 0x70,0x29, 81}, /* 0x46 */  /* unused */
+	{    0,   0,  0}, /* 0x47 custom (will be filled out) */
+	{ 0xce,0x25,189}  /* 0x48 */  /* Replacement for index 0x1b for 730 (and 540?) */
 };
 
-#ifndef LINUX_XF86
+#ifdef LINUX_KERNEL
 static UCHAR SiS300_SR07 = 0x10;
 #endif
 
@@ -685,7 +688,7 @@ static const DRAM4Type SiS300_SR15[8] =
 	{0x00,0x00,0x00,0x00}
 };
 
-#ifndef LINUX_XF86
+#ifdef LINUX_KERNEL
 static UCHAR SiS300_SR1F = 0x00;
 static UCHAR SiS300_SR21 = 0x16;
 static UCHAR SiS300_SR22 = 0xb2;
diff -puN drivers/video/sis/310vtbl.h~fbdev-sis-framebuffer-driver-update-1717 drivers/video/sis/310vtbl.h
--- 25/drivers/video/sis/310vtbl.h~fbdev-sis-framebuffer-driver-update-1717	2004-11-28 01:30:58.854563128 -0800
+++ 25-akpm/drivers/video/sis/310vtbl.h	2004-11-28 01:30:58.893557200 -0800
@@ -35,7 +35,7 @@
  * * 3) 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 EXPRESSED OR
+ * * 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,
@@ -145,33 +145,36 @@ static const SiS_ExtStruct  SiS310_EMode
 	{0x29,0x4e1b,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x43,-1}, /* 1152x864 */
 	{0x2a,0x4e3d,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x43,-1},
 	{0x2b,0x4e7f,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x43,-1},
-	{0x39,0x6a1b,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x00,0x45,-1}, /* 848x480 */
-	{0x3b,0x6a3d,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x00,0x45,-1},
-	{0x3e,0x6a7f,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x00,0x45,-1},
-	{0x3f,0x6a1b,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x00,0x47,-1}, /* 856x480 */
-	{0x42,0x6a3d,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x00,0x47,-1},
-	{0x45,0x6a7f,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x00,0x47,-1},
-	{0x48,0x6a3b,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x49,-1}, /* 1360x768 */
-	{0x4b,0x6a7d,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x49,-1},
-	{0x4e,0x6aff,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x49,-1},
+	{0x39,0x6a1b,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x00,0x46,-1}, /* 848x480 */
+	{0x3b,0x6a3d,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x00,0x46,-1},
+	{0x3e,0x6a7f,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x00,0x46,-1},
+	{0x3f,0x6a1b,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x00,0x48,-1}, /* 856x480 */
+	{0x42,0x6a3d,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x00,0x48,-1},
+	{0x45,0x6a7f,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x00,0x48,-1},
+	{0x48,0x6a3b,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x4a,-1}, /* 1360x768 */
+	{0x4b,0x6a7d,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x4a,-1},
+	{0x4e,0x6aff,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x4a,-1},
 	{0x4f,0x9a1f,0x0000,SIS_RI_320x200,  0x00,0x00,0x04,0x04,0x25, 0}, /* 320x200x32 */
 	{0x53,0x9a1f,0x0000,SIS_RI_320x240,  0x00,0x00,0x04,0x04,0x26, 2}, /* 320x240x32 */
 	{0x54,0xba1f,0x0000,SIS_RI_400x300,  0x00,0x00,0x07,0x07,0x27, 3}, /* 400x300x32 */
-	{0x5f,0x6a1b,0x0000,SIS_RI_768x576,  0x00,0x00,0x06,0x06,0x4a,-1}, /* 768x576 */
-	{0x60,0x6a1d,0x0000,SIS_RI_768x576,  0x00,0x00,0x06,0x06,0x4a,-1},
-	{0x61,0x6a3f,0x0000,SIS_RI_768x576,  0x00,0x00,0x06,0x06,0x4a,-1},
-	{0x14,0x0e3b,0x0000,SIS_RI_1280x800, 0x00,0x00,0x00,0x00,0x4b, 7}, /* 1280x800 */
-	{0x15,0x0e7d,0x0000,SIS_RI_1280x800, 0x00,0x00,0x00,0x00,0x4b, 7},
-	{0x16,0x0eff,0x0000,SIS_RI_1280x800, 0x00,0x00,0x00,0x00,0x4b, 7},
-	{0x17,0x0e3b,0x0000,SIS_RI_1680x1050,0x00,0x00,0x00,0x00,0x4c, 9}, /* 1680x1050 */
-	{0x18,0x0e7d,0x0000,SIS_RI_1680x1050,0x00,0x00,0x00,0x00,0x4c, 9},
-	{0x19,0x0eff,0x0000,SIS_RI_1680x1050,0x00,0x00,0x00,0x00,0x4c, 9},
-	{0x2c,0x267b,0x0000,SIS_RI_1920x1080,0x00,0x00,0x00,0x00,0x4d,-1}, /* 1920x1080(i) */
-	{0x2d,0x26fd,0x0000,SIS_RI_1920x1080,0x00,0x00,0x00,0x00,0x4d,-1},
-	{0x73,0x27ff,0x0000,SIS_RI_1920x1080,0x00,0x00,0x00,0x00,0x4d,-1},
-	{0x1d,0x6a1b,0x0000,SIS_RI_960x540,  0x00,0x00,0x00,0x00,0x4e,-1}, /* 960x540 */
-	{0x1e,0x6a3d,0x0000,SIS_RI_960x540,  0x00,0x00,0x00,0x00,0x4e,-1},
-	{0x1f,0x6a7f,0x0000,SIS_RI_960x540,  0x00,0x00,0x00,0x00,0x4e,-1},
+	{0x5f,0x6a1b,0x0000,SIS_RI_768x576,  0x00,0x00,0x06,0x06,0x4b,-1}, /* 768x576 */
+	{0x60,0x6a1d,0x0000,SIS_RI_768x576,  0x00,0x00,0x06,0x06,0x4b,-1},
+	{0x61,0x6a3f,0x0000,SIS_RI_768x576,  0x00,0x00,0x06,0x06,0x4b,-1},
+	{0x14,0x0e3b,0x0000,SIS_RI_1280x800, 0x00,0x00,0x00,0x00,0x4c, 7}, /* 1280x800 */
+	{0x15,0x0e7d,0x0000,SIS_RI_1280x800, 0x00,0x00,0x00,0x00,0x4c, 7},
+	{0x16,0x0eff,0x0000,SIS_RI_1280x800, 0x00,0x00,0x00,0x00,0x4c, 7},
+	{0x17,0x0e3b,0x0000,SIS_RI_1680x1050,0x00,0x00,0x00,0x00,0x4d, 9}, /* 1680x1050 */
+	{0x18,0x0e7d,0x0000,SIS_RI_1680x1050,0x00,0x00,0x00,0x00,0x4d, 9},
+	{0x19,0x0eff,0x0000,SIS_RI_1680x1050,0x00,0x00,0x00,0x00,0x4d, 9},
+	{0x2c,0x267b,0x0000,SIS_RI_1920x1080,0x00,0x00,0x00,0x00,0x4e,-1}, /* 1920x1080(i) */
+	{0x2d,0x26fd,0x0000,SIS_RI_1920x1080,0x00,0x00,0x00,0x00,0x4e,-1},
+	{0x73,0x27ff,0x0000,SIS_RI_1920x1080,0x00,0x00,0x00,0x00,0x4e,-1},
+	{0x1d,0x6a1b,0x0000,SIS_RI_960x540,  0x00,0x00,0x00,0x00,0x4f,-1}, /* 960x540 */
+	{0x1e,0x6a3d,0x0000,SIS_RI_960x540,  0x00,0x00,0x00,0x00,0x4f,-1},
+	{0x1f,0x6a7f,0x0000,SIS_RI_960x540,  0x00,0x00,0x00,0x00,0x4f,-1},
+	{0x20,0x6a1b,0x0000,SIS_RI_960x600,  0x00,0x00,0x00,0x00,0x50,-1}, /* 960x600 */
+	{0x21,0x6a3d,0x0000,SIS_RI_960x600,  0x00,0x00,0x00,0x00,0x50,-1},
+	{0x22,0x6a7f,0x0000,SIS_RI_960x600,  0x00,0x00,0x00,0x00,0x50,-1},
 	{0xff,0x0000,0x0000,0,               0x00,0x00,0x00,0x00,0x00,-1}
 };
 
@@ -244,21 +247,89 @@ static const SiS_Ext2Struct SiS310_RefIn
         {0x0077,0x42,0x5b,0x08,0x11,0x23,1280, 768, 0x30}, /* 0x40 */    /* 0x5b was 0x12 */
 	{0x0127,0x43,0x4d,0x08,0x0b,0x26,1400,1050, 0x30}, /* 0x41 */
 	{0x0207,0x4b,0x5a,0x08,0x0b,0x26,1400,1050, 0x30}, /* 0x42 1400x1050-75Hz */
-	{0x0127,0x44,0x19,0x00,0x1a,0x29,1152, 864, 0x30}, /* 0x43 1152x864-75Hz  */
-	{0x0127,0x4a,0x1e,0x00,0x1a,0x29,1152, 864, 0x30}, /* 0x44 1152x864-85Hz  */
-	{0x0087,0x45,0x57,0x00,0x16,0x39, 848, 480, 0x30}, /* 0x45 848x480-38Hzi  */
-	{0xc067,0x46,0x55,0x0b,0x16,0x39, 848, 480, 0x30}, /* 0x46 848x480-60Hz   */
-	{0x0087,0x47,0x57,0x00,0x17,0x3f, 856, 480, 0x30}, /* 0x47 856x480-38Hzi  */
-	{0xc067,0x48,0x57,0x00,0x17,0x3f, 856, 480, 0x30}, /* 0x48 856x480-60Hz   */
-	{0x0067,0x49,0x58,0x0c,0x1b,0x48,1360, 768, 0x30}, /* 0x49 1360x768-60Hz  */
-	{0x006f,0x4d,0x03,0x06,0x15,0x5f, 768, 576, 0x30}, /* 0x4a 768x576-56Hz   */
-	{0x0067,0x4f,0x5c,0x08,0x0d,0x14,1280, 800, 0x30}, /* 0x4b 1280x800-60Hz  */
-	{0x0067,0x50,0x5d,0x0c,0x0e,0x17,1680,1050, 0x30}, /* 0x4c 1680x1050-60Hz */
-	{0x0087,0x51,0x69,0x00,0x00,0x2c,1920,1080, 0x30}, /* 0x4d 1920x1080 60Hzi */
-	{0x0067,0x52,0x6a,0x00,0x1c,0x1d, 960, 540, 0x30}, /* 0x4e 960x540 60Hz */
+	{0x0127,0x54,0x6d,0x00,0x1a,0x29,1152, 864, 0x30}, /* 0x43 1152x864-60Hz  */
+	{0x0127,0x44,0x19,0x00,0x1a,0x29,1152, 864, 0x30}, /* 0x44 1152x864-75Hz  */
+	{0x0127,0x4a,0x1e,0x00,0x1a,0x29,1152, 864, 0x30}, /* 0x45 1152x864-85Hz  */
+	{0x0087,0x45,0x57,0x00,0x16,0x39, 848, 480, 0x30}, /* 0x46 848x480-38Hzi  */
+	{0xc067,0x46,0x55,0x0b,0x16,0x39, 848, 480, 0x30}, /* 0x47 848x480-60Hz   */
+	{0x0087,0x47,0x57,0x00,0x17,0x3f, 856, 480, 0x30}, /* 0x48 856x480-38Hzi  */
+	{0xc067,0x48,0x57,0x00,0x17,0x3f, 856, 480, 0x30}, /* 0x49 856x480-60Hz   */
+	{0x0067,0x49,0x58,0x0c,0x1b,0x48,1360, 768, 0x30}, /* 0x4a 1360x768-60Hz  */
+	{0x006f,0x4d,0x03,0x06,0x15,0x5f, 768, 576, 0x30}, /* 0x4b 768x576-56Hz   */
+	{0x0067,0x4f,0x5c,0x08,0x0d,0x14,1280, 800, 0x30}, /* 0x4c 1280x800-60Hz  */
+	{0x0067,0x50,0x5d,0x0c,0x0e,0x17,1680,1050, 0x30}, /* 0x4d 1680x1050-60Hz */
+	{0x0087,0x51,0x69,0x00,0x00,0x2c,1920,1080, 0x30}, /* 0x4e 1920x1080 60Hzi */
+	{0x0067,0x52,0x6a,0x00,0x1c,0x1d, 960, 540, 0x30}, /* 0x4f 960x540 60Hz */
+	{0x0077,0x53,0x6b,0x0b,0x1d,0x20, 960, 600, 0x30}, /* 0x50 960x600 60Hz */
 	{0xffff,0x00,0x00,0x00,0x00,0x00,   0,   0,    0}
 };
 
+#ifdef LINUX_XF86
+static const struct {
+	UCHAR  Ext_ModeID;     /* ModeID in new ROM */
+	UCHAR  Ext_MyModeID;   /* corresponding ModeID in my tables (0 = identical) */
+	USHORT Ext_VESAID;     /* corresponding VESA ID in new ROM */
+} SiS_EModeIDTable661[] = {
+        { 0x6a, 0x00, 0x0102 },
+	{ 0x1d, 0x20, 0x0000 },
+	{ 0x1e, 0x21, 0x0000 },
+	{ 0x1f, 0x22, 0x0000 },
+	{ 0x20, 0x29, 0x0000 },
+	{ 0x21, 0x2a, 0x0000 },
+	{ 0x22, 0x2b, 0x0000 },
+	{ 0x23, 0x00, 0x011c },
+	{ 0x24, 0x00, 0x011d },
+	{ 0x25, 0x00, 0x011e },
+	{ 0x26, 0x00, 0x011f },
+	{ 0x27, 0x00, 0x0120 },
+	{ 0x28, 0x00, 0x0121 },
+	{ 0x2a, 0x14, 0x013d },
+	{ 0x2b, 0x15, 0x013e },
+	{ 0x2c, 0x16, 0x013f },
+	{ 0x2e, 0x00, 0x0101 },
+	{ 0x2f, 0x00, 0x0100 },
+	{ 0x30, 0x00, 0x0103 },
+	{ 0x37, 0x00, 0x0104 },
+	{ 0x38, 0x00, 0x0105 },
+	{ 0x3a, 0x00, 0x0107 },
+	{ 0x3c, 0x00, 0x0125 },
+	{ 0x3d, 0x00, 0x0126 },
+	{ 0x40, 0x00, 0x010d },
+	{ 0x41, 0x00, 0x010e },
+	{ 0x43, 0x00, 0x0110 },
+	{ 0x44, 0x00, 0x0111 },
+	{ 0x46, 0x00, 0x0113 },
+	{ 0x47, 0x00, 0x0114 },
+	{ 0x49, 0x00, 0x0116 },
+	{ 0x4a, 0x00, 0x0117 },
+	{ 0x4c, 0x00, 0x0119 },
+	{ 0x4d, 0x00, 0x011a },
+	{ 0x50, 0x00, 0x0127 },
+	{ 0x51, 0x00, 0x0128 },
+	{ 0x52, 0x00, 0x0129 },
+	{ 0x56, 0x00, 0x012a },
+	{ 0x57, 0x00, 0x012b },
+	{ 0x58, 0x00, 0x012c },
+	{ 0x59, 0x00, 0x012d },
+	{ 0x5a, 0x17, 0x012e },
+	{ 0x5b, 0x18, 0x012f },
+	{ 0x5c, 0x19, 0x0130 },
+	{ 0x5d, 0x00, 0x0131 },
+	{ 0x62, 0x00, 0x0112 },
+	{ 0x63, 0x00, 0x0115 },
+	{ 0x64, 0x00, 0x0118 },
+	{ 0x65, 0x00, 0x011b },
+	{ 0x66, 0x00, 0x0132 },
+	{ 0x75, 0x00, 0x013a },
+	{ 0x78, 0x00, 0x013b },
+	{ 0x79, 0x00, 0x013c },
+	{ 0x7b, 0x7c, 0x0136 },
+	{ 0x7c, 0x7d, 0x0137 },
+	{ 0x7d, 0x7e, 0x0138 },
+	{ 0xff, 0xff, 0xffff }
+};
+#endif
+
 static const SiS_CRT1TableStruct SiS310_CRT1Table[]=
 {
  {{0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
@@ -524,7 +595,13 @@ static const SiS_CRT1TableStruct SiS310_
    0x61}},  /* 0x51 */
  {{0x85,0x77,0x77,0x89,0x7d,0x01,0x31,0xf0, /* 960x540-60 */
    0x1e,0x84,0x1b,0x1c,0x32,0x00,0x00,0x02,
-   0x41}}   /* 0x52 */
+   0x41}},  /* 0x52 */
+ {{0x87,0x77,0x77,0x8b,0x81,0x0b,0x68,0xf0, /* 960x600-60 */
+   0x5a,0x80,0x57,0x57,0x69,0x00,0x00,0x02,
+   0x01}},  /* 0x53 */
+ {{0xcd,0x8f,0x8f,0x91,0x9b,0x1b,0x7a,0xff, /* 1152x864-60 */
+   0x64,0x8c,0x5f,0x62,0x7b,0x10,0x00,0x07,
+   0x41}}   /* 0x54 */
 };
 
 static const SiS_MCLKDataStruct SiS310_MCLKData_0_315[] =
@@ -587,6 +664,30 @@ static const SiS_MCLKDataStruct SiS310_M
 	{ 0x37,0x21,0x82,200}
 };
 
+static const SiS_MCLKDataStruct SiS310_MCLKData_0_761[] =
+{
+	{ 0x37,0x22,0x82,133},  /* Preliminary */
+	{ 0x5c,0x23,0x82,166},
+	{ 0x65,0x23,0x82,183},
+	{ 0x7c,0x08,0x82,200},
+	{ 0x29,0x21,0x82,150},
+	{ 0x5c,0x23,0x82,166},
+	{ 0x65,0x23,0x82,183},
+	{ 0x37,0x21,0x82,200}
+};
+
+static const SiS_MCLKDataStruct SiS310_MCLKData_0_340[] =
+{
+	{ 0x79,0x06,0x01,250},
+	{ 0x7c,0x08,0x01,200},
+	{ 0x7c,0x08,0x80,200},
+	{ 0x79,0x06,0x80,250},
+	{ 0x29,0x01,0x81,300},
+	{ 0x29,0x01,0x81,300},
+	{ 0x29,0x01,0x81,300},
+	{ 0x29,0x01,0x81,300}
+};
+
 static const SiS_MCLKDataStruct SiS310_MCLKData_1[] = /* ECLK */
 {
         { 0x29,0x21,0x82,150},
@@ -599,6 +700,18 @@ static const SiS_MCLKDataStruct SiS310_M
 	{ 0x37,0x22,0x82,133}
 };
 
+static const SiS_MCLKDataStruct SiS310_MCLKData_1_340[] =
+{
+	{ 0x7c,0x08,0x01,200},
+	{ 0x7c,0x08,0x01,200},
+	{ 0x7c,0x08,0x80,200},
+	{ 0x79,0x06,0x80,250},
+	{ 0x29,0x01,0x81,300},
+	{ 0x29,0x01,0x81,300},
+	{ 0x29,0x01,0x81,300},
+	{ 0x29,0x01,0x81,300}
+};
+
 static SiS_VCLKDataStruct SiS310_VCLKData[]=
 {
 	{ 0x1b,0xe1, 25}, /* 0x00 */
@@ -707,7 +820,10 @@ static SiS_VCLKDataStruct SiS310_VCLKDat
 	{ 0x76,0xe7, 27}, /* 0x67 720x480@60 */
 	{ 0x5f,0xc6, 33}, /* 0x68 720/768x576@60 */
 	{ 0x52,0x27, 75}, /* 0x69 1920x1080i 60Hz interlaced */
-	{ 0x7c,0x6b, 38}  /* 0x6a 960x540@60 */
+	{ 0x7c,0x6b, 38}, /* 0x6a 960x540@60 */
+	{ 0xe3,0x56, 41}, /* 0x6b 960x600@60 */
+	{ 0x45,0x25, 83}, /* 0x6c 1280x800 */
+	{ 0x70,0x28, 90}  /* 0x6d 1152x864@60 */
 };
 
 static SiS_VBVCLKDataStruct SiS310_VBVCLKData[]=
@@ -809,22 +925,25 @@ static SiS_VBVCLKDataStruct SiS310_VBVCL
 	{ 0x30,0x23, 88}, /* 0x58 1360x768-62 (is 60Hz!) TEMP, UNUSED */
 	{ 0x52,0x07,149}, /* 0x59 1280x960-85  */
 	{ 0x56,0x07,156}, /* 0x5a 1400x1050-75 */
-   	{ 0x70,0x29, 81}, /* 0x5b 1280x768 LCD */
-	{ 0x45,0x25, 83}, /* 0x5c 1280x800 LCD - (was 0x9c,0x62, 69 - wrong?) */
+   	{ 0x70,0x29, 81}, /* 0x5b 1280x768 LCD (TMDS) */
+	{ 0xce,0x1e, 73}, /* 0x5c 1280x800_2 LCD (SiS LVDS) - (CRT1: 45 25 83) */
 	{ 0xbe,0x44,121}, /* 0x5d 1680x1050 LCD */
 	{ 0x70,0x24,162}, /* 0x5e 1600x1200 LCD */
-	{ 0x52,0x27, 75}, /* 0x5f 1280x720 LCD TMDS + HDTV (correct) */
-	{ 0x63,0x46, 68}, /* 0x60 1280x768_2 */
-	{ 0x31,0x42, 79}, /* 0x61 1280x768_3 - temp */
+	{ 0x52,0x27, 75}, /* 0x5f 1280x720 (TMDS + HDTV) (correct) */
+	{ 0xc8,0x48, 77}, /* 0x60 1280x768_2 (SiS LVDS) */
+	{ 0x31,0x42, 79}, /* 0x61 1280x768_3 (SiS LVDS) - temp */
 	{    0,   0,  0}, /* 0x62 - custom (will be filled out at run-time) */
-	{ 0x5a,0x64, 65}, /* 0x63 1280x720 (LCD LVDS) */
+	{ 0x9c,0x62, 69}, /* 0x63 1280x720 (SiS LVDS) */
 	{ 0x70,0x28, 90}, /* 0x64 1152x864@60 */
 	{ 0x41,0xc4, 32}, /* 0x65 848x480@60 */
 	{ 0x5c,0xc6, 32}, /* 0x66 856x480@60 */
 	{ 0x76,0xe7, 27}, /* 0x67 720x480@60 */
 	{ 0x5f,0xc6, 33}, /* 0x68 720/768x576@60 */
 	{ 0x52,0x27, 75}, /* 0x69 1920x1080i 60Hz interlaced (UNUSED) */
-	{ 0x7c,0x6b, 38}  /* 0x6a 960x540@60 */
+	{ 0x7c,0x6b, 38}, /* 0x6a 960x540@60 */
+	{ 0xe3,0x56, 41}, /* 0x6b 960x600@60 */
+	{ 0x9c,0x62, 69}, /* 0x6c 1280x800 (SiS TMDS) (special) */
+	{ 0x70,0x28, 90}  /* 0x6d 1152x864@60 */
 };
 
 static const DRAM4Type SiS310_SR15[8] = {
@@ -838,7 +957,7 @@ static const DRAM4Type SiS310_SR15[8] = 
 	{0x00,0xa5,0xfb,0xf6}
 };
 
-#ifndef LINUX_XF86
+#ifdef LINUX_KERNEL
 
 static UCHAR SiS310_SR07 = 0x18;
 
diff -puN drivers/video/sis/init301.c~fbdev-sis-framebuffer-driver-update-1717 drivers/video/sis/init301.c
--- 25/drivers/video/sis/init301.c~fbdev-sis-framebuffer-driver-update-1717	2004-11-28 01:30:58.858562520 -0800
+++ 25-akpm/drivers/video/sis/init301.c	2004-11-28 01:30:58.920553096 -0800
@@ -133,17 +133,29 @@ GetLCDStructPtr661(SiS_Private *SiS_Pr, 
 {
    UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
    UCHAR  *myptr = NULL;
-   USHORT romindex = 0;
+   USHORT romindex = 0, reg = 0, idx = 0;
 
-   /* Use the BIOS tables only for LVDS panels; DVI is unreliable
+   /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
     * due to the variaty of panels the BIOS doesn't know about.
+    * Exception: If the BIOS has better knowledge (such as in case
+    * of machines with a 301C and a panel that does not support DDC)
+    * use the BIOS data as well.
     */
 
-   if((SiS_Pr->SiS_ROMNew) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
-      myptr = (UCHAR *)SiS_LCDStruct661;
+   if((SiS_Pr->SiS_ROMNew) &&
+      ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) || (!SiS_Pr->PanelSelfDetected))) {
+
+      if(HwInfo->jChipType < SIS_661) reg = 0x3c;
+      else                            reg = 0x7d;
+
+      idx = (SiS_GetReg(SiS_Pr->SiS_P3d4,reg) & 0x1f) * 26;
+
+      if(idx < (8*26)) {
+         myptr = (UCHAR *)&SiS_LCDStruct661[idx];
+      }
       romindex = SISGETROMW(0x100);
       if(romindex) {
-         romindex += ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x7d) & 0x1f) * 26);
+         romindex += idx;
          myptr = &ROMAddr[romindex];
       }
    }
@@ -156,11 +168,15 @@ GetLCDStructPtr661_2(SiS_Private *SiS_Pr
    UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
    USHORT romptr = 0;
 
-   /* Use the BIOS tables only for LVDS panels; DVI is unreliable
+   /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
     * due to the variaty of panels the BIOS doesn't know about.
+    * Exception: If the BIOS has better knowledge (such as in case
+    * of machines with a 301C and a panel that does not support DDC)
+    * use the BIOS data as well.
     */
 
-   if((SiS_Pr->SiS_ROMNew) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
+   if((SiS_Pr->SiS_ROMNew) &&
+      ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) || (!SiS_Pr->PanelSelfDetected))) {
       romptr = SISGETROMW(0x102);
       romptr += ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) * SiS_Pr->SiS661LCD2TableSize);
    }
@@ -175,12 +191,11 @@ GetLCDStructPtr661_2(SiS_Private *SiS_Pr
 
 static BOOLEAN
 SiS_AdjustCRT2Rate(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
-                   USHORT RefreshRateTableIndex, USHORT *i,
-		   PSIS_HW_INFO HwInfo)
+                   USHORT RRTI, USHORT *i, PSIS_HW_INFO HwInfo)
 {
   USHORT checkmask=0,modeid,infoflag;
 
-  modeid = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].ModeID;
+  modeid = SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID;
 
   if(SiS_Pr->SiS_VBType & VB_SISVB) {
 
@@ -241,8 +256,8 @@ SiS_AdjustCRT2Rate(SiS_Private *SiS_Pr, 
   }
 
   /* Look backwards in table for matching CRT2 mode */
-  for(; SiS_Pr->SiS_RefIndex[RefreshRateTableIndex+(*i)].ModeID == modeid; (*i)--) {
-     infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag;
+  for(; SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID == modeid; (*i)--) {
+     infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
      if(infoflag & checkmask) return TRUE;
      if((*i) == 0) break;
   }
@@ -251,13 +266,11 @@ SiS_AdjustCRT2Rate(SiS_Private *SiS_Pr, 
    * for a matching CRT2 mode if no mode was found yet.
    */
   for((*i) = 0; ; (*i)++) {
-     if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].ModeID != modeid) {
-     	return FALSE;
-     }
-     infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag;
+     if(SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID != modeid) break;
+     infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
      if(infoflag & checkmask) return TRUE;
   }
-  return TRUE;
+  return FALSE;
 }
 
 /*********************************************/
@@ -273,7 +286,7 @@ SiS_GetRatePtr(SiS_Private *SiS_Pr, USHO
 			       0x01, 0x01, 0x01, 0x01,
 			       0x01, 0x01, 0x01, 0x01,
 			       0x00, 0x00, 0x00, 0x00 };
-  USHORT RefreshRateTableIndex,i,backup_i;
+  USHORT RRTI,i,backup_i;
   USHORT modeflag,index,temp,backupindex;
 
   /* Do NOT check for UseCustomMode here, will skrew up FIFO */
@@ -318,23 +331,23 @@ SiS_GetRatePtr(SiS_Private *SiS_Pr, USHO
      }
   }
 
-  RefreshRateTableIndex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
-  ModeNo = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].ModeID;
+  RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
+  ModeNo = SiS_Pr->SiS_RefIndex[RRTI].ModeID;
 
   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++;
+           if(backupindex <= 1) RRTI++;
         }
      }
   }
 
   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(SiS_Pr->SiS_RefIndex[RRTI + i].ModeID != ModeNo) break;
+     temp = SiS_Pr->SiS_RefIndex[RRTI + i].Ext_InfoFlag;
+     temp &= ModeTypeMask;
      if(temp < SiS_Pr->SiS_ModeType) break;
      i++;
      index--;
@@ -342,7 +355,7 @@ SiS_GetRatePtr(SiS_Private *SiS_Pr, USHO
 
   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-      	temp = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + i - 1].Ext_InfoFlag;
+      	temp = SiS_Pr->SiS_RefIndex[RRTI + i - 1].Ext_InfoFlag;
       	if(temp & InterlaceMode) i++;
      }
   }
@@ -351,12 +364,12 @@ SiS_GetRatePtr(SiS_Private *SiS_Pr, USHO
 
   if((SiS_Pr->SiS_SetFlag & ProgrammingCRT2) && (!(SiS_Pr->SiS_VBInfo & DisableCRT2Display))) {
      backup_i = i;
-     if(!(SiS_AdjustCRT2Rate(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, &i, HwInfo))) {
+     if(!(SiS_AdjustCRT2Rate(SiS_Pr, ModeNo, ModeIdIndex, RRTI, &i, HwInfo))) {
 	i = backup_i;
      }
   }
 
-  return(RefreshRateTableIndex + i);
+  return(RRTI + i);
 }
 
 /*********************************************/
@@ -383,12 +396,12 @@ SiS_SaveCRT2Info(SiS_Private *SiS_Pr, US
 static BOOLEAN
 SiS_CR36BIOSWord23b(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
-  UCHAR *ROMAddr = (UCHAR *)HwInfo->pjVirtualRomBase;
+  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
   USHORT temp,temp1;
 
   if(SiS_Pr->SiS_UseROM) {
      if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
-        temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xff) >> 4);
+        temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
         temp1 = SISGETROMW(0x23b);
         if(temp1 & temp) return TRUE;
      }
@@ -399,12 +412,12 @@ SiS_CR36BIOSWord23b(SiS_Private *SiS_Pr,
 static BOOLEAN
 SiS_CR36BIOSWord23d(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
-  UCHAR *ROMAddr = (UCHAR *)HwInfo->pjVirtualRomBase;
+  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
   USHORT temp,temp1;
 
   if(SiS_Pr->SiS_UseROM) {
      if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
-        temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xff) >> 4);
+        temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
         temp1 = SISGETROMW(0x23d);
         if(temp1 & temp) return TRUE;
      }
@@ -478,6 +491,7 @@ SiS_PanelDelay(SiS_Private *SiS_Pr, PSIS
 
       PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
       if(SiS_Pr->SiS_VBType & VB_SISVB) {
+         if(SiS_Pr->SiS_VBType & VB_SIS301) PanelID &= 0xf7;
          if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x10)) PanelID = 0x12;
       }
       DelayIndex = PanelID >> 4;
@@ -507,7 +521,8 @@ SiS_PanelDelay(SiS_Private *SiS_Pr, PSIS
 
       if((HwInfo->jChipType >= SIS_661)    ||
          (HwInfo->jChipType <= SIS_315PRO) ||
-	 (HwInfo->jChipType == SIS_330)) {
+	 (HwInfo->jChipType == SIS_330)    ||
+	 (SiS_Pr->SiS_ROMNew)) {
 
          if(!(DelayTime & 0x01)) {
 	    SiS_DDC2Delay(SiS_Pr, 0x1000);
@@ -920,7 +935,7 @@ SiS_SetChrontelGPIO(SiS_Private *SiS_Pr,
 
    if(!(SiS_Pr->SiS_ChSW)) return;
 
-#ifndef LINUX_XF86
+#ifdef LINUX_KERNEL
    SiS_SetRegLong(0xcf8,0x80000874);		       /* get ACPI base */
    acpibase = SiS_GetRegLong(0xcfc);
 #else
@@ -956,7 +971,7 @@ SiS_GetVBInfo(SiS_Private *SiS_Pr, USHOR
 
   SiS_Pr->SiS_SetFlag = 0;
 
-  SiS_Pr->SiS_ModeType = modeflag & ModeInfoFlag;
+  SiS_Pr->SiS_ModeType = modeflag & ModeTypeMask;
 
   tempbx = 0;
   if(SiS_BridgeIsOn(SiS_Pr)) {
@@ -981,7 +996,7 @@ SiS_GetVBInfo(SiS_Private *SiS_Pr, USHOR
 
 #ifdef SIS315H
 	if(HwInfo->jChipType >= SIS_315H) {
-    	   if(SiS_Pr->SiS_VBType & (VB_SIS301C|VB_SIS302B|VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)) {
+    	   if(SiS_Pr->SiS_VBType & VB_SISLCDA) {
 	      if(ModeNo == 0x03) {
 	         /* Mode 0x03 is never in driver mode */
 		 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf);
@@ -1012,13 +1027,13 @@ SiS_GetVBInfo(SiS_Private *SiS_Pr, USHOR
 	   if(HwInfo->jChipType >= SIS_661) {
 	      tempbx &= ~(SetCRT2ToYPbPr525750 | SetCRT2ToHiVision);
 	      temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
-	      if(SiS_Pr->SiS_VBType & (VB_SIS301C|VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)) {
+	      if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
 	         if(temp & 0x04) {
 		    temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
 		    if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
 		    else             tempbx |= SetCRT2ToYPbPr525750;
 		 }
-	      } else if(SiS_Pr->SiS_VBType & (VB_SIS301 | VB_SIS301B | VB_SIS302B)) {
+	      } else if(SiS_Pr->SiS_VBType & VB_SISHIVISION) {
 	         if(temp & 0x04) {
 		    temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
 		    if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
@@ -1445,7 +1460,7 @@ SiS_GetBIOSLCDResInfo(SiS_Private *SiS_P
    USHORT temp = SiS_Pr->SiS_LCDResInfo;
    /* Translate my LCDResInfo to BIOS value */
    if(temp == Panel_1280x768_2)  temp = Panel_1280x768;
-   if(temp == Panel_1280x768_3)  temp = Panel_1280x768;
+   if(temp == Panel_1280x800_2)  temp = Panel_1280x800;
    return temp;
 }
 
@@ -1501,20 +1516,36 @@ SiS_GetLCDInfoBIOS(SiS_Private *SiS_Pr, 
 #endif
 }
 
+static void
+SiS_CheckScaling(SiS_Private *SiS_Pr, USHORT resinfo, const UCHAR *nonscalingmodes)
+{
+    int i = 0;
+    while(nonscalingmodes[i] != 0xff) {
+        if(nonscalingmodes[i++] == resinfo) {
+	   if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ||
+	      (SiS_Pr->UsePanelScaler == -1)) {
+	      SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+	   }
+	   break;
+	}
+    }
+}
+
 void
 SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 		  PSIS_HW_INFO HwInfo)
 {
 #ifdef SIS300
-  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
+  UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
+  const unsigned char SiS300SeriesLCDRes[] =
+          { 0,  1,  2,  3,  7,  4,  5,  8,
+	    0,  0, 10,  0,  0,  0,  0, 15 };
 #endif
 #ifdef SIS315H
-  UCHAR  *myptr = NULL;
+  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 };
+  USHORT  temp,modeflag,resinfo=0,modexres=0,modeyres=0;
+  BOOLEAN panelcanscale = FALSE;
 
   SiS_Pr->SiS_LCDResInfo  = 0;
   SiS_Pr->SiS_LCDTypeInfo = 0;
@@ -1534,10 +1565,14 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, U
   } else {
      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+     modexres = SiS_Pr->SiS_ModeResInfo[resinfo].HTotal;
+     modeyres = SiS_Pr->SiS_ModeResInfo[resinfo].VTotal;
   }
 
   temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
-  if(!temp) return;
+
+  /* For broken BIOSes: Assume 1024x768 */
+  if(temp == 0) temp = 0x02;
 
   if((HwInfo->jChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
      SiS_Pr->SiS_LCDTypeInfo = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x7c) >> 2;
@@ -1547,24 +1582,31 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, U
      SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1;
   }
   temp &= 0x0f;
+#ifdef SIS300
   if(HwInfo->jChipType < SIS_315H) {
+     /* Very old BIOSes only know 7 sizes (NetVista 2179, 1.01g) */
+     if(SiS_Pr->SiS_VBType & VB_SIS301) {
+        if(temp < 0x0f) temp &= 0x07;
+     }
      /* Translate 300 series LCDRes to 315 series for unified usage */
      temp = SiS300SeriesLCDRes[temp];
   }
+#endif
 
+  /* Translate to our internal types */
   if(HwInfo->jChipType == SIS_550) {
      if(temp == Panel310_640x480_2) temp = Panel_640x480_2;
      if(temp == Panel310_640x480_3) temp = Panel_640x480_3;
   }
 
-  if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {	/* SiS LVDS */
+  if(SiS_Pr->SiS_VBType & VB_SISLVDS) {	/* SiS LVDS */
      if(temp == Panel310_1280x768) {
         temp = Panel_1280x768_2;
-#ifdef SIS315H
-	if((myptr = GetLCDStructPtr661(SiS_Pr, HwInfo))) {
-	   if((myptr[8] | (myptr[9] << 8)) == 798) temp = Panel_1280x768_3;
+     }
+     if(SiS_Pr->SiS_ROMNew) {
+        if(temp == Panel661_1280x800) {
+	   temp = Panel_1280x800_2;
 	}
-#endif
      }
   }
 
@@ -1586,6 +1628,77 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, U
 	SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS;
   }
 
+  temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
+  SiS_Pr->SiS_LCDInfo = temp & ~0x000e;
+  /* Need temp below! */
+
+  /* These can't scale no matter what */
+  switch(SiS_Pr->SiS_LCDResInfo) {
+  case Panel_1280x960:
+      SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
+  }
+
+  panelcanscale = (SiS_Pr->SiS_LCDInfo & DontExpandLCD) ? TRUE : FALSE;
+
+  if(!SiS_Pr->UsePanelScaler)          SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
+  else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+
+  /* Dual link, Pass 1:1 BIOS default, etc. */
+#ifdef SIS315H
+  if(HwInfo->jChipType >= SIS_661) {
+     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+        if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11;
+     }
+     if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
+        if(SiS_Pr->SiS_ROMNew) {
+	   if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
+	} else if((myptr = GetLCDStructPtr661(SiS_Pr, HwInfo))) {
+           if(myptr[2] & 0x01) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
+	}
+     }
+  } else if(HwInfo->jChipType >= SIS_315H) {
+     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+        if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) SiS_Pr->SiS_LCDInfo |= LCDPass11;
+     }
+     if((SiS_Pr->SiS_ROMNew) && (!(SiS_Pr->PanelSelfDetected))) {
+        SiS_Pr->SiS_LCDInfo &= ~(LCDRGB18Bit);
+	temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
+        if(temp & 0x01) SiS_Pr->SiS_LCDInfo |= LCDRGB18Bit;
+	if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
+	   if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
+	}
+     } else if(!(SiS_Pr->SiS_ROMNew)) {
+        if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
+           if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) &&
+	      (SiS_Pr->SiS_LCDResInfo == Panel_1024x768)) {
+	      SiS_Pr->SiS_LCDInfo |= LCDDualLink;
+	   }
+           if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
+	      (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
+              (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
+	      (SiS_Pr->SiS_LCDResInfo == Panel_1680x1050)) {
+	      SiS_Pr->SiS_LCDInfo |= LCDDualLink;
+	   }
+        }
+     }
+  }
+#endif
+
+  /* Pass 1:1 */
+  if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
+     /* Always center screen on LVDS (if scaling is disabled) */
+     SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
+  } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
+     if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
+        /* Always center screen on SiS LVDS (if scaling is disabled) */
+        SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
+     } else {
+        /* By default, pass 1:1 on SiS TMDS (if scaling is supported) */
+        if(panelcanscale)             SiS_Pr->SiS_LCDInfo |= LCDPass11;
+        if(SiS_Pr->CenterScreen == 1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
+     }
+  }
+
   SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
   SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
 
@@ -1654,31 +1767,37 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, U
 			    SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
 			    break;
      case Panel_1280x768:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  768;
-     			    SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   =  802;
-			    SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRS  =  112;
-			    SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
-			    SiS_Pr->PanelVCLKIdx300 = VCLK81_300;
-			    SiS_Pr->PanelVCLKIdx315 = VCLK81_315;
+     			    if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+			       SiS_Pr->PanelHT   = 1408; SiS_Pr->PanelVT   =  806;
+			       SiS_Pr->PanelVCLKIdx300 = VCLK81_300; /* ? */
+			       SiS_Pr->PanelVCLKIdx315 = VCLK81_315; /* ? */
+			    } else {
+     			       SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   =  802;
+			       SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRS  =  112;
+			       SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
+			       SiS_Pr->PanelVCLKIdx300 = VCLK81_300;
+			       SiS_Pr->PanelVCLKIdx315 = VCLK81_315;
+			    }
 			    break;
      case Panel_1280x768_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  768;
-     			    SiS_Pr->PanelHT   = 1408; SiS_Pr->PanelVT   =  806;
-			    SiS_Pr->PanelHRS  =   16; SiS_Pr->PanelHRE  =   64;
+     			    SiS_Pr->PanelHT   = 1660; SiS_Pr->PanelVT   =  806;
+			    SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112;
 			    SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
 			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_2;
 			    SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
 			    break;
-     case Panel_1280x768_3: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  768;
-     			    SiS_Pr->PanelHT   = 1664; SiS_Pr->PanelVT   =  798;
-			    SiS_Pr->PanelHRS   =  64; SiS_Pr->PanelHRE  =  128;
-			    SiS_Pr->PanelVRS   =   3; SiS_Pr->PanelVRE  =    7;
-			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_3;
+     case Panel_1280x800:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  800;
+     			    SiS_Pr->PanelHT   = 1408; SiS_Pr->PanelVT   =  816;
+			    SiS_Pr->PanelHRS   =  21; SiS_Pr->PanelHRE  =   24;
+			    SiS_Pr->PanelVRS   =   4; SiS_Pr->PanelVRE  =    3;
+			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315;
 			    SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
 			    break;
-     case Panel_1280x800:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  800;
-     			    SiS_Pr->PanelHT   = 1656; SiS_Pr->PanelVT   =  841;  /* 1408, 816 */
-			    SiS_Pr->PanelHRS   =  32; SiS_Pr->PanelHRE  =  312;  /*   16,  64 */
-			    SiS_Pr->PanelVRS   =  16; SiS_Pr->PanelVRE  =    8;  /*    4,   3 */
-			    SiS_Pr->PanelVCLKIdx315 = VCLK83_315;
+     case Panel_1280x800_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  800;
+     			    SiS_Pr->PanelHT   = 1552; SiS_Pr->PanelVT   =  812;
+			    SiS_Pr->PanelHRS   =  48; SiS_Pr->PanelHRE  =  112;
+			    SiS_Pr->PanelVRS   =   4; SiS_Pr->PanelVRE  =    3;
+			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315_2;
 			    SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
 			    break;
      case Panel_1280x960:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  960;
@@ -1719,6 +1838,12 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, U
 			    SiS_Pr->PanelVCLKIdx315 = VCLK121_315;
 			    SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
 			    break;
+     case Panel_Barco1366:  SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024;
+     			    SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   = 1066;
+     			    break;
+     case Panel_848x480:    SiS_Pr->PanelXRes =  848; SiS_Pr->PanelYRes =  480;
+     			    SiS_Pr->PanelHT   = 1088; SiS_Pr->PanelVT   =  525;
+     			    break;
      case Panel_Custom:     SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX;
     			    SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY;
 			    SiS_Pr->PanelHT   = SiS_Pr->CHTotal;
@@ -1736,63 +1861,185 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, U
 			       SiS_Pr->PanelHRE -= SiS_Pr->PanelHRS;
 			       SiS_Pr->PanelVRS -= SiS_Pr->PanelYRes;
 			       SiS_Pr->PanelVRE -= SiS_Pr->PanelVRS;
+			       if(SiS_Pr->CP_PrefClock) {
+			          int idx;
+			          SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
+				  SiS_Pr->PanelVCLKIdx300 = VCLK_CUSTOM_300;
+				  if(HwInfo->jChipType < SIS_315H) idx = VCLK_CUSTOM_300;
+				  else				   idx = VCLK_CUSTOM_315;
+      			          SiS_Pr->SiS_VCLKData[idx].CLOCK =
+	 		             SiS_Pr->SiS_VBVCLKData[idx].CLOCK = SiS_Pr->CP_PrefClock;
+      			          SiS_Pr->SiS_VCLKData[idx].SR2B =
+  	 			     SiS_Pr->SiS_VBVCLKData[idx].Part4_A = SiS_Pr->CP_PrefSR2B;
+      			          SiS_Pr->SiS_VCLKData[idx].SR2C =
+	 			     SiS_Pr->SiS_VBVCLKData[idx].Part4_B = SiS_Pr->CP_PrefSR2C;
+			       }
 			    }
 			    break;
-     case Panel_Barco1366:  SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024;
-     			    SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   = 1066;
-     			    break;
-     case Panel_848x480:    SiS_Pr->PanelXRes =  848; SiS_Pr->PanelYRes =  480;
-     			    SiS_Pr->PanelHT   = 1088; SiS_Pr->PanelVT   =  525;
-     			    break;
      default:		    SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  768;
      			    SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  806;
 			    break;
   }
 
-  temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
-  SiS_Pr->SiS_LCDInfo = temp & ~0x000e;
+  /* Special cases */
+  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) ) {
+     SiS_Pr->PanelHRS = 999;
+     SiS_Pr->PanelHRE = 999;
+  }
 
-  if(!(SiS_Pr->UsePanelScaler))        SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
-  else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+  if( (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
+      (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
+      (SiS_Pr->SiS_CustomT == CUT_PANEL848) ) {
+     SiS_Pr->PanelVRS = 999;
+     SiS_Pr->PanelVRE = 999;
+  }
 
-#ifdef SIS315H
-  if(HwInfo->jChipType >= SIS_661) {
-     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
-        if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11;
+  /* DontExpand overrule */
+  if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
+
+     if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (modeflag & NoSupportLCDScale)) {
+	/* No scaling for this mode on any panel (LCD=CRT2)*/
+	SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
      }
-     if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
-        if(SiS_Pr->SiS_ROMNew) {
-	   if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
-	} else if((myptr = GetLCDStructPtr661(SiS_Pr, HwInfo))) {
-           if(myptr[2] & 0x01) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
+
+     switch(SiS_Pr->SiS_LCDResInfo) {
+
+     case Panel_Custom:
+     case Panel_1152x864:
+     case Panel_1280x768:	/* TMDS only */
+        SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+	break;
+
+     case Panel_800x600: {
+        static const UCHAR nonscalingmodes[] = {
+	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, 0xff
+	};
+	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
+	break;
+     }
+     case Panel_1024x768: {
+        static const UCHAR nonscalingmodes[] = {
+	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
+	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
+	   0xff
+	};
+	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
+	break;
+     }
+     case Panel_1280x720: {
+        static const UCHAR nonscalingmodes[] = {
+	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
+	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
+	   0xff
+	};
+	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
+	if(SiS_Pr->PanelHT == 1650) {
+	   SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
 	}
+	break;
      }
-  } else if(HwInfo->jChipType >= SIS_315H) {
-     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
-        if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) SiS_Pr->SiS_LCDInfo |= LCDPass11;
+     case Panel_1280x768_2: {  /* LVDS only */
+        static const UCHAR nonscalingmodes[] = {
+	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
+	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
+	   SIS_RI_1152x768,0xff
+	};
+	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
+	switch(resinfo) {
+	case SIS_RI_1280x720:  if(SiS_Pr->UsePanelScaler == -1) {
+	      			  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+	   		       }
+	   		       break;
+	}
+        break;
      }
-     if((SiS_Pr->SiS_ROMNew) && (!(SiS_Pr->PanelSelfDetected))) {
-        SiS_Pr->SiS_LCDInfo &= ~(LCDRGB18Bit);
-	temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
-        if(temp & 0x01) SiS_Pr->SiS_LCDInfo |= LCDRGB18Bit;
-	if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
-	   if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
+     case Panel_1280x800: {  	/* SiS TMDS special (Averatec 6200 series) */
+        static const UCHAR nonscalingmodes[] = {
+	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
+	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
+	   SIS_RI_1152x768,SIS_RI_1280x720,SIS_RI_1280x768,0xff
+	};
+	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
+        break;
+     }
+     case Panel_1280x800_2:  { 	/* SiS LVDS */
+        static const UCHAR nonscalingmodes[] = {
+	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
+	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
+	   SIS_RI_1152x768,0xff
+	};
+	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
+	switch(resinfo) {
+	case SIS_RI_1280x720:
+	case SIS_RI_1280x768:  if(SiS_Pr->UsePanelScaler == -1) {
+	      			  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+	   		       }
+	   		       break;
 	}
+        break;
+     }
+     case Panel_1280x960: {
+        static const UCHAR nonscalingmodes[] = {
+	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
+	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
+	   SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
+	   0xff
+	};
+	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
+        break;
+     }
+     case Panel_1280x1024: {
+        static const UCHAR nonscalingmodes[] = {
+	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
+	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
+	   SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
+	   SIS_RI_1280x960,0xff
+	};
+	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
+	break;
+     }
+     case Panel_1400x1050: {
+        static const UCHAR nonscalingmodes[] = {
+	     SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
+	     SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
+	     SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x768,SIS_RI_1280x800,SIS_RI_1280x960,
+	     0xff
+	};
+	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
+        switch(resinfo) {
+	case SIS_RI_1280x720:  if(SiS_Pr->UsePanelScaler == -1) {
+	      			  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+	   		       }
+	   		       break;
+	case SIS_RI_1280x1024: SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+	      		       break;
+	}
+	break;
+     }
+     case Panel_1600x1200: {
+        static const UCHAR nonscalingmodes[] = {
+	     SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
+	     SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
+	     SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
+	     SIS_RI_1280x960,SIS_RI_1360x768,SIS_RI_1360x1024,0xff
+	};
+	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
+        break;
+     }
+     case Panel_1680x1050: {
+        static const UCHAR nonscalingmodes[] = {
+	     SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
+	     SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
+	     SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x960,SIS_RI_1360x768,SIS_RI_1360x1024,
+	     0xff
+	};
+	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
+	break;
      }
-  }
-#endif
-
-  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-     /* Always center screen on LVDS (if scaling is disabled) */
-     SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
-  } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
-     if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-        /* Always center screen on SiS LVDS (if scaling is disabled) */
-        SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
-     } else {
-        /* By default, pass 1:1 on SiS TMDS (if scaling is disabled) */
-        SiS_Pr->SiS_LCDInfo |= LCDPass11;
-        if(SiS_Pr->CenterScreen == 1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
      }
   }
 
@@ -1802,78 +2049,6 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, U
      }
   }
 
-  if(SiS_Pr->SiS_VBType & VB_SISVB) {
-     if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
-        if(modeflag & NoSupportLCDScale) {
-	   /* No scaling for this mode on any panel */
-	   SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
-	}
-        switch(SiS_Pr->SiS_LCDResInfo) {
-        case Panel_Custom:
-		/* For non-standard LCD resolution, we let the panel scale */
-           	SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
-		break;
-	case Panel_1280x720:
-	      	if(SiS_Pr->PanelHT == 1650) {
-		   SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
-		}
-	case Panel_1280x768:	/* TMDS only */
-		/* No idea about the timing and zoom factors */
-           	SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
-		break;
-	case Panel_1280x960:
-	 	SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
-		break;
-	case Panel_1280x1024:
-	        if(SiS_Pr->SiS_VBType & VB_SISTMDS) {
-		   if(ModeNo == 0x7c || ModeNo == 0x7d || ModeNo == 0x7e ||
-		      ModeNo == 0x79 || ModeNo == 0x75 || ModeNo == 0x78 ||
-		      ModeNo == 0x14 || ModeNo == 0x15 || ModeNo == 0x16) {
-	      	      /* We do not scale to 1280x720/800/960 (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;
-	           }
-		}
-		break;
-	case Panel_1400x1050:
-	 	if(SiS_Pr->SiS_VBType & VB_SISTMDS) {
-	  	   if(ModeNo == 0x7c || ModeNo == 0x7d || ModeNo == 0x7e ||
-		      ModeNo == 0x79 || ModeNo == 0x75 || ModeNo == 0x78 ||
-		      ModeNo == 0x14 || ModeNo == 0x15 || ModeNo == 0x16 ||
-		      ModeNo == 0x23 || ModeNo == 0x24 || ModeNo == 0x25) {
-	      	      /* Do not scale to 1280x720/768/800/960 (B/C bridges only) */
-                      SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
-	           }
-		}
-		if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-		   if(ModeNo == 0x79 || ModeNo == 0x75 || ModeNo == 0x78) {
-		      if(SiS_Pr->UsePanelScaler == -1) {
-		         /* Do not scale to 1280x720 by default (LVDS bridges) */
-	      	         SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
-		      }
-		   }
-		}
-		if(ModeNo == 0x3a || ModeNo == 0x4d || ModeNo == 0x65) {
-	      	   /* Do not scale to 1280x1024 (all bridges) */
-	      	   SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
-	   	}
-		break;
-	case Panel_1600x1200:
-		if(SiS_Pr->SiS_VBType & VB_SISTMDS) {
-	      	   /* No idea about the timing and zoom factors (C bridge only) */
-	      	   SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
-	   	}
-		break;
-	}
-     }
-  }
-
 #ifdef SIS300
   if(HwInfo->jChipType < SIS_315H) {
      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
@@ -1893,12 +2068,32 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, U
 #endif
 
   /* Special cases */
+
+  if(modexres == SiS_Pr->PanelXRes && modeyres == SiS_Pr->PanelYRes) {
+     SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
+  }
+
   if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
      SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
   }
 
-  if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) {
+  switch(SiS_Pr->SiS_LCDResInfo) {
+  case Panel_640x480:
      SiS_Pr->SiS_LCDInfo |= LCDPass11;
+     break;
+  case Panel_1280x800:
+     /* Don't pass 1:1 by default (TMDS special) */
+     if(SiS_Pr->CenterScreen == -1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
+     break;
+  case Panel_1280x960:
+     SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
+     break;
+  case Panel_Custom:
+     if((!SiS_Pr->CP_PrefClock) ||
+        (modexres > SiS_Pr->PanelXRes) || (modeyres > SiS_Pr->PanelYRes)) {
+        SiS_Pr->SiS_LCDInfo |= LCDPass11;
+     }
+     break;
   }
 
   if(SiS_Pr->UseCustomMode) {
@@ -1910,49 +2105,10 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, U
      SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
   }
 
-  /* Special cases */
-  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) ) {
-     SiS_Pr->PanelHRS = 999;
-     SiS_Pr->PanelHRE = 999;
-  }
-
-  if( (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
-      (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
-      (SiS_Pr->SiS_CustomT == CUT_PANEL848) ) {
-     SiS_Pr->PanelVRS = 999;
-     SiS_Pr->PanelVRE = 999;
-  }
-
-#ifdef SIS315H
-  if((HwInfo->jChipType >= SIS_315H) && (HwInfo->jChipType < SIS_661)) {
-     if(!(SiS_Pr->SiS_ROMNew)) {
-        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 == Panel_1024x768)) {
-	      /* (Sets this in SenseLCD; new paneltypes) */
-	      SiS_Pr->SiS_LCDInfo |= LCDDualLink;
-	   }
-           if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
-	      (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
-              (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
-	      (SiS_Pr->SiS_LCDResInfo == Panel_1680x1050)) {
-	      SiS_Pr->SiS_LCDInfo |= LCDDualLink;
-	   }
-        }
-     }
-  }
-#endif
-
+  /* LVDS DDA */
   if(!((HwInfo->jChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
 
-     if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+     if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
 	if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
 	   if(ModeNo == 0x12) {
 	      if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
@@ -1988,6 +2144,7 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, U
 
   }
 
+  /* VESA timing */
   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
      if(SiS_Pr->SiS_VBInfo & SetNotSimuMode) {
      	SiS_Pr->SiS_SetFlag |= LCDVESATiming;
@@ -2043,19 +2200,15 @@ SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USH
 
            if(HwInfo->jChipType < SIS_315H) {
 	      VCLKIndex = SiS_Pr->PanelVCLKIdx300;
+	      if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
+	         VCLKIndex = VCLKIndexGEN;
+	      }
 	   } else {
 	      VCLKIndex = SiS_Pr->PanelVCLKIdx315;
 	      if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
-	         VCLKIndex = VCLKIndexGEN;
 		 switch(resinfo) {
-		 /* Only those whose IndexGEN doesn't match VBVCLK array: */
-		 case SIS_RI_1280x720: VCLKIndex = VCLK_1280x720;
-		 		       if(SiS_Pr->SiS_LCDResInfo == Panel_1280x720) {
-		                          if(SiS_Pr->PanelHT == 1344) {
-					     VCLKIndex = VCLK_1280x720_2;
-					  }
-				       }
-		 		       break;
+		 /* Only those whose IndexGEN doesn't match VBVCLK array */
+		 case SIS_RI_1280x720: VCLKIndex = VCLK_1280x720; break;
 		 case SIS_RI_720x480:  VCLKIndex = VCLK_720x480;  break;
 		 case SIS_RI_720x576:  VCLKIndex = VCLK_720x576;  break;
 		 case SIS_RI_768x576:  VCLKIndex = VCLK_768x576;  break;
@@ -2065,6 +2218,7 @@ SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USH
 		 case SIS_RI_1024x576: VCLKIndex = VCLK_1024x576; break;
 		 case SIS_RI_1152x864: VCLKIndex = VCLK_1152x864; break;
 		 case SIS_RI_1360x768: VCLKIndex = VCLK_1360x768; break;
+		 default:              VCLKIndex = VCLKIndexGEN;
 		 }
 
 		 if(ModeNo <= 0x13) {
@@ -2121,7 +2275,7 @@ SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USH
            if(ModeNo > 0x13) {
 	      if( (HwInfo->jChipType != SIS_630) &&
 		  (HwInfo->jChipType != SIS_300) ) {
-		 if(VCLKIndex == 0x1b) VCLKIndex = 0x35;
+		 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
 	      }
 	   }
         }
@@ -2207,7 +2361,7 @@ SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USH
            if(ModeNo > 0x13) {
 	      if( (HwInfo->jChipType != SIS_630) &&
 	          (HwInfo->jChipType != SIS_300) ) {
-		 if(VCLKIndex == 0x1b) VCLKIndex = 0x35;
+		 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
 	      }
 #if 0
 	      if(HwInfo->jChipType == SIS_730) {
@@ -2255,10 +2409,6 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr,
      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 */
-
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
 
      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40);
@@ -2372,13 +2522,9 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr,
       	   tempah |= 0x10;
         }
 
-        if((HwInfo->jChipType < SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301)) {
-	   if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
-	      (SiS_Pr->SiS_LCDResInfo == Panel_1280x960)) {
-	      tempah |= 0x80;
-	   }
-        } else {
-	   tempah |= 0x80;
+	tempah |= 0x80;
+        if(SiS_Pr->SiS_VBType & VB_SIS301) {
+	   if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah &= ~0x80;
         }
 
         if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
@@ -2391,7 +2537,10 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr,
 
         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah);
 
-        tempah = 0;
+	tempah = 0x80;
+	if(SiS_Pr->SiS_VBType & VB_SIS301) {
+	   if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah = 0;
+	}
 
 	if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempah |= 0x40;
 
@@ -2401,19 +2550,13 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr,
        	   }
         }
 
-	if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
-	   (SiS_Pr->SiS_LCDResInfo == Panel_1280x960)  ||
-	   ((SiS_Pr->SiS_LCDResInfo == Panel_Custom) &&
-	    (SiS_Pr->CP_MaxX >= 1280) && (SiS_Pr->CP_MaxY >= 960))) {
-	   tempah |= 0x80;
-        }
-
         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0C,tempah);
 
      } else {  /* LVDS */
 
         if(HwInfo->jChipType >= SIS_315H) {
 
+#ifdef SIS315H
 	   /* LVDS can only be slave in 8bpp modes */
 	   tempah = 0x80;
 	   if((modeflag & CRT2Mode) && (SiS_Pr->SiS_ModeType > ModeVGA)) {
@@ -2435,9 +2578,11 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr,
 	   }
 
     	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah);
+#endif
 
         } else {
 
+#ifdef SIS300
 	   tempah = 0;
 	   if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
               tempah |= 0x02;
@@ -2447,6 +2592,7 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr,
 	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display)  tempah = 0;
 
 	   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
+#endif
 
         }
 
@@ -2459,7 +2605,6 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr,
      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
@@ -2538,26 +2683,29 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr,
            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
 	}
 
-#if 0
-	if(SiS_Pr->SiS_VBType & VB_SIS301C) {
-	   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3a,0xc0);
-	}
-#endif
-
 #endif /* SIS315H */
 
      } else if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
 
+#ifdef SIS300
         SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
 
         if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
-           (   (SiS_Pr->SiS_VBType & VB_NoLCD) &&
-	       (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ) ) {
+           ((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);
 	}
+#endif
+
+     }
 
+     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+        SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x0D,0x80);
+        if(SiS_Pr->SiS_VBType & VB_SIS301C) {
+	   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3A,0xC0);
+        }
      }
 
   } else {  /* LVDS */
@@ -2823,19 +2971,18 @@ SiS_GetCRT2Ptr(SiS_Private *SiS_Pr,USHOR
 	if(SiS_Pr->SiS_LCDResInfo == Panel_1680x1050) {
 	   if     (resinfo == SIS_RI_1280x800)  tempal =  9;
 	   else if(resinfo == SIS_RI_1400x1050) tempal = 11;
+	} else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x800) ||
+	          (SiS_Pr->SiS_LCDResInfo == Panel_1280x800_2)) {
+	   if     (resinfo == SIS_RI_1280x768)  tempal =  9;
 	}
 
-  	if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {  /* Pass 1:1 only (center-screen handled outside) */
+  	if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+	   /* Pass 1:1 only (center-screen handled outside) */
+	   /* This is never called for the panel's native resolution */
+	   /* since Pass1:1 will not be set in this case */
 	   tempbx = 100;
 	   if(ModeNo >= 0x13) {
 	      tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
-	      if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes == 1280) &&
-	         (SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].YRes ==  768)) {
-	         /* Special for Fujitsu 7911 (VL-17WDX8), others custom */
-	         if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768)        tempal = 0x08;
-		 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768_2) tempal = 0x0f;
-		 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768_3) tempal = 0x10;
-	      }
 	   }
 	}
 
@@ -2907,6 +3054,7 @@ SiS_GetCRT2Ptr(SiS_Private *SiS_Pr,USHOR
 
      tempbx = 0;
      if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
+
         tempbx = 10;
 	if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
         if(SiS_Pr->SiS_TVMode & TVSetPAL) {
@@ -2922,10 +3070,12 @@ SiS_GetCRT2Ptr(SiS_Private *SiS_Pr,USHOR
 	      if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
 	   }
         }
+
      } else {
+
         switch(SiS_Pr->SiS_LCDResInfo) {
 	case Panel_640x480:   tempbx = 6;  break;
-	case Panel_640x480_2: tempbx = 30; break;
+	case Panel_640x480_2:
 	case Panel_640x480_3: tempbx = 30; break;
 	case Panel_800x600:   tempbx = 0;  break;
 	case Panel_1024x600:  tempbx = 15; break;
@@ -2951,19 +3101,20 @@ SiS_GetCRT2Ptr(SiS_Private *SiS_Pr,USHOR
 
 	if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
 	   tempbx = 82;
-	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx++;
+	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
 	} else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
 	   tempbx = 84;
-	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx++;
+	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
 	}
 
-     }
+	if((SiS_Pr->SiS_CustomT != CUT_BARCO1366) &&
+           (SiS_Pr->SiS_CustomT != CUT_PANEL848)) {
+           if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) &&
+	      (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
+              tempal = 0;
+	   }
+        }
 
-     if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
-        if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) tempal = 7;
-  	if(HwInfo->jChipType < SIS_315H) {
-	   if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) tempal++;
-	}
      }
 
      (*CRT2Index) = tempbx;
@@ -3062,20 +3213,6 @@ SiS_GetCRT2DataLVDS(SiS_Private *SiS_Pr,
 	          ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
 	       } else {
 	          ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
-		  /* Special for our 3 types, others custom (works with default) */
-		  if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes == 1280) &&
-	             (SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].YRes ==  768)) {
-	             if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768)        ResIndex = 0x08;
-		     else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768_2) ResIndex = 0x0f;
-		     else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768_3) ResIndex = 0x10;
-	          }
-		  /* Special for 1280x720 TMDS <> LVDS */
-		  if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes == 1280) &&
-	             (SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].YRes ==  720)) {
-		     if(SiS_Pr->SiS_LCDResInfo == Panel_1280x720) {
-		        if(SiS_Pr->PanelHT == 1344) ResIndex = 0x12;
-		     }
-	          }
 	       }
 	       SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAHT;
                SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAVT;
@@ -3348,12 +3485,12 @@ SiS_GetCRT2Data301(SiS_Private *SiS_Pr,U
 
      if(SiS_Pr->UseCustomMode) {
 
-        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_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 {
 
@@ -3361,10 +3498,10 @@ SiS_GetCRT2Data301(SiS_Private *SiS_Pr,U
 
         if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
 
-           SiS_Pr->SiS_VGAHT     = SiS_Pr->PanelHT;
-           SiS_Pr->SiS_VGAVT     = SiS_Pr->PanelVT;
-           SiS_Pr->SiS_HT        = SiS_Pr->PanelHT;
-           SiS_Pr->SiS_VT        = SiS_Pr->PanelVT;
+           SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
+           SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
+           SiS_Pr->SiS_HT    = SiS_Pr->PanelHT;
+           SiS_Pr->SiS_VT    = SiS_Pr->PanelVT;
 	   gotit = TRUE;
 
 	} else if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) && (romptr) && (ROMAddr) ) {
@@ -3377,6 +3514,15 @@ SiS_GetCRT2Data301(SiS_Private *SiS_Pr,U
            SiS_Pr->SiS_HT        = ROMAddr[romptr+5] | ((ROMAddr[romptr+6] & 0x0f) << 8);
            SiS_Pr->SiS_VT        = ROMAddr[romptr+7] | ((ROMAddr[romptr+6] & 0xf0) << 4);
 	   if(SiS_Pr->SiS_VGAHT) gotit = TRUE;
+	   else {
+	      SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+	      SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
+	      SiS_Pr->SiS_VGAHT   = SiS_Pr->PanelHT;
+              SiS_Pr->SiS_VGAVT   = SiS_Pr->PanelVT;
+              SiS_Pr->SiS_HT      = SiS_Pr->PanelHT;
+              SiS_Pr->SiS_VT      = SiS_Pr->PanelVT;
+	      gotit = TRUE;
+	   }
 #endif
 
 	}
@@ -3393,10 +3539,10 @@ SiS_GetCRT2Data301(SiS_Private *SiS_Pr,U
 	      case Panel_1280x720  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x720Data;      break;
 	      case Panel_1280x768_2    : LCDPtr = SiS_Pr->SiS_ExtLCD1280x768_2Data; break;
               case Panel_1280x768_2+ 32: LCDPtr = SiS_Pr->SiS_StLCD1280x768_2Data;  break;
-	      case Panel_1280x768_3    :
-	      case Panel_1280x768_3+ 32: LCDPtr = SiS_Pr->SiS_LCD1280x768_3Data;    break;
 	      case Panel_1280x800      :
 	      case Panel_1280x800  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x800Data;      break;
+	      case Panel_1280x800_2    :
+	      case Panel_1280x800_2+ 32: LCDPtr = SiS_Pr->SiS_LCD1280x800_2Data;    break;
 	      case Panel_1280x960      :
 	      case Panel_1280x960  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x960Data;      break;
               case Panel_1280x1024     : LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data;  break;
@@ -3777,9 +3923,11 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, P
            }
 
 	   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(HwInfo->jChipType < SIS_340) {
+	         tempah = 0xef;
+	         if(SiS_IsVAMode(SiS_Pr,HwInfo)) tempah = 0xf7;
+	         SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
+	      }
 	   }
 
 	   if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
@@ -3962,7 +4110,9 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, P
 #ifdef SIS315H	/* 315 series */
 
         if(!(SiS_IsNotM650orLater(SiS_Pr,HwInfo))) {
-          SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,~0x18);
+	   if(HwInfo->jChipType < SIS_340) {
+              SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,~0x18);
+	   }
         }
 
 	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
@@ -4185,12 +4335,14 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PS
 	 }
 
          if(!(SiS_IsNotM650orLater(SiS_Pr, HwInfo))) {
-	    tempah = 0x10;
-	    if(SiS_LCDAEnabled(SiS_Pr, HwInfo)) {
-	       if(SiS_TVEnabled(SiS_Pr, HwInfo)) tempah = 0x18;
-	       else 			         tempah = 0x08;
+	    if(HwInfo->jChipType < SIS_340) {
+	       tempah = 0x10;
+	       if(SiS_LCDAEnabled(SiS_Pr, HwInfo)) {
+	          if(SiS_TVEnabled(SiS_Pr, HwInfo)) tempah = 0x18;
+	          else 			            tempah = 0x08;
+	       }
+	       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah);
 	    }
-	    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah);
 	 }
 
 	 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
@@ -4267,6 +4419,7 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PS
 #ifdef SET_EMI
 	       if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
 	          SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
+		  SiS_GenericDelay(SiS_Pr, 0x500);
 	       }
 #endif
 	       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
@@ -4277,13 +4430,13 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PS
 
 		  if(SiS_Pr->SiS_ROMNew) {
 		     UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
-		     USHORT romptr   = GetLCDStructPtr661_2(SiS_Pr, HwInfo);
+		     USHORT romptr = GetLCDStructPtr661_2(SiS_Pr, HwInfo);
 		     if(romptr) {
-		        SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20);
+		        SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
 			SiS_Pr->EMI_30 = 0;
-			SiS_Pr->EMI_31 = ROMAddr[romptr + 14];
-			SiS_Pr->EMI_32 = ROMAddr[romptr + 15];
-			SiS_Pr->EMI_33 = ROMAddr[romptr + 16];
+			SiS_Pr->EMI_31 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 0];
+			SiS_Pr->EMI_32 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 1];
+			SiS_Pr->EMI_33 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 2];
 			if(ROMAddr[romptr + 1] & 0x10) SiS_Pr->EMI_30 = 0x40;
 			/* emidelay = SISGETROMW((romptr + 0x22)); */
 			SiS_Pr->HaveEMI = SiS_Pr->HaveEMILCD = SiS_Pr->OverruleEMI = TRUE;
@@ -4382,7 +4535,8 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PS
  		  }
 
 		  if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) {
-		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20);
+		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
+		     SiS_GenericDelay(SiS_Pr, 0x500);
 		  }
 		  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,r31);
 		  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,r32);
@@ -4404,7 +4558,7 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PS
 			if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
 			   SiS_GenericDelay(SiS_Pr, 0x500);
 			}
-	                SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40);
+	                SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40);   /* Enable */
 	             }
 		  }
 #endif
@@ -4537,7 +4691,9 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PS
 #ifdef SIS315H    /* 315 series */
 
        if(!(SiS_IsNotM650orLater(SiS_Pr,HwInfo))) {
-          SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x18);
+          if(HwInfo->jChipType < SIS_340) {
+             SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x18);
+	  }
        }
 
        if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
@@ -4794,9 +4950,11 @@ SiS_SetCRT2Sync(SiS_Private *SiS_Pr, USH
   	         }
 	      }
 	      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
-	         if(SiS_Pr->SiS_LCDInfo & LCDSync) {
-	            tempah = SiS_Pr->SiS_LCDInfo;
-		    tempbl = (tempah >> 6) & 0x03;
+	         if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
+	            if(SiS_Pr->SiS_LCDInfo & LCDSync) {
+	               tempah = SiS_Pr->SiS_LCDInfo;
+		       tempbl = (tempah >> 6) & 0x03;
+		    }
 	         }
 	      }
 	   }
@@ -4901,7 +5059,7 @@ SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,
 
      CRT1ModeNo = 0xfe;
      VCLK = SiS_Pr->CSRClock_CRT1;					/* Get VCLK */
-     data2 = (SiS_Pr->CModeFlag_CRT1 & ModeInfoFlag) - 2;
+     data2 = (SiS_Pr->CModeFlag_CRT1 & ModeTypeMask) - 2;
      switch(data2) {							/* Get color depth */
         case 0 : colorth = 1; break;
         case 1 : colorth = 1; break;
@@ -4964,7 +5122,7 @@ SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,
 
     } else if(HwInfo->jChipType == SIS_730) {
 
-#ifndef LINUX_XF86
+#ifdef LINUX_KERNEL
        SiS_SetRegLong(0xcf8,0x80000050);
        eax = SiS_GetRegLong(0xcfc);
 #else
@@ -4974,7 +5132,7 @@ SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,
        tempal &= 0x06;
        tempal <<= 5;
 
-#ifndef LINUX_XF86
+#ifdef LINUX_KERNEL
        SiS_SetRegLong(0xcf8,0x800000A0);
        eax = SiS_GetRegLong(0xcfc);
 #else
@@ -5004,7 +5162,7 @@ SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,
        temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
        if(temp & 0x0080) index += 12;
 
-#ifndef LINUX_XF86
+#ifdef LINUX_KERNEL
        SiS_SetRegLong(0xcf8,0x800000A0);
        eax = SiS_GetRegLong(0xcfc);
 #else
@@ -5017,7 +5175,7 @@ SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,
        temp = (USHORT)(eax >> 24);
        if(!(temp&0x01)) index += 24;
 
-#ifndef LINUX_XF86
+#ifdef LINUX_KERNEL
        SiS_SetRegLong(0xcf8,0x80000050);
        eax = SiS_GetRegLong(0xcfc);
 #else
@@ -5512,9 +5670,8 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, 
 #endif
   }
 
-  /* is lvds if really LVDS, or SiS 301B-DH with external LVDS transmitter */
-  if((SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
-     ((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBType & VB_NoLCD))) {
+  /* is lvds if really LVDS, or 301B-DH with external LVDS transmitter */
+  if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
      islvds = TRUE;
   }
 
@@ -7467,7 +7624,7 @@ SiS_SetGroup4_C_ELV(SiS_Private *SiS_Pr,
    if(!(temp & 0x01)) {
       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3a,0xdf);
       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xfc);
-      if(HwInfo->jChipType < SIS_661) {
+      if((HwInfo->jChipType < SIS_661) && (!(SiS_Pr->SiS_ROMNew))) {
          SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xf8);
       }
       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0xfb);
@@ -7475,7 +7632,7 @@ SiS_SetGroup4_C_ELV(SiS_Private *SiS_Pr,
       else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp = 0x0002;
       else if(SiS_Pr->SiS_TVMode & TVSetHiVision)  temp = 0x0400;
       else					   temp = 0x0402;
-      if(HwInfo->jChipType >= SIS_661) {
+      if((HwInfo->jChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
          temp1 = 0;
 	 if(SiS_Pr->SiS_TVMode & TVAspect43) temp1 = 4;
 	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0f,0xfb,temp1);
@@ -7488,6 +7645,9 @@ SiS_SetGroup4_C_ELV(SiS_Private *SiS_Pr,
 	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xf8,(temp & 0xff));
       }
       SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
+      if(ModeNo > 0x13) {
+         SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3b,0xfd);
+      }
 
       if(HwInfo->jChipType >= SIS_661) { 		/* ? */
          if(SiS_Pr->SiS_TVMode & TVAspect43) {
@@ -7580,6 +7740,8 @@ SiS_SetGroup4(SiS_Private *SiS_Pr, USHOR
         if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
 	   if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
 	      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
+	   } else {
+	      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,~0x20);
 	   }
 
 	   if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
@@ -7705,7 +7867,7 @@ SiS_SetGroup4(SiS_Private *SiS_Pr, USHOR
      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1E,temp);
 
      temp = 0x0036; tempbx = 0xD0;
-     if((IS_SIS550650740660) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
+     if((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
 	temp = 0x0026; tempbx = 0xC0; /* See En/DisableBridge() */
      }
      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
@@ -7735,6 +7897,8 @@ SiS_SetGroup4(SiS_Private *SiS_Pr, USHOR
 	if(HwInfo->jChipType >= SIS_315H) {
 	   if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
 	      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
+	   } else {
+	      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,~0x20);
 	   }
 	}
 	if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
@@ -8376,7 +8540,7 @@ SiS_ChrontelResetVSync(SiS_Private *SiS_
   SiS_SetCH701x(SiS_Pr,(temp1 << 8) | 0x49);
 }
 
-void
+static void
 SiS_Chrontel701xOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
   USHORT temp;
@@ -8421,7 +8585,7 @@ SiS_Chrontel701xOn(SiS_Private *SiS_Pr, 
   }
 }
 
-void
+static void
 SiS_Chrontel701xOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
   USHORT temp;
@@ -8494,7 +8658,7 @@ SiS_ChrontelResetDB(SiS_Private *SiS_Pr,
      }
 }
 
-void
+static void
 SiS_ChrontelInitTVVSync(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
      USHORT temp;
@@ -8620,7 +8784,7 @@ SiS_ChrontelDoSomething2(SiS_Private *Si
     SiS_SetCH701x(SiS_Pr,0x0077);  /* MV? */
 }
 
-void
+static void
 SiS_ChrontelDoSomething1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
      USHORT temp;
@@ -8823,16 +8987,9 @@ SiS_SetCRT2Group(SiS_Private *SiS_Pr, PS
 	       (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
 	       SetOEMLCDData2(SiS_Pr, HwInfo, ModeNo, ModeIdIndex,RefreshRateTableIndex);
 	    }
-            if(HwInfo->jChipType == SIS_730) {
-               SiS_DisplayOn(SiS_Pr);
-	    }
+	    SiS_DisplayOn(SiS_Pr);
          }
       }
-      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-          if(HwInfo->jChipType != SIS_730) {
-             SiS_DisplayOn(SiS_Pr);
-	  }
-      }
    }
 #endif
 
@@ -8841,7 +8998,7 @@ SiS_SetCRT2Group(SiS_Private *SiS_Pr, PS
       if(SiS_Pr->SiS_SetFlag & LowModeTests) {
 	 if(HwInfo->jChipType < SIS_661) {
 	    SiS_FinalizeLCD(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
-            SiS_OEM310Setting(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
+            SiS_OEM310Setting(SiS_Pr, HwInfo, ModeNo, ModeIdIndex, RefreshRateTableIndex);
 	 } else {
 	    SiS_OEM661Setting(SiS_Pr, HwInfo, ModeNo, ModeIdIndex, RefreshRateTableIndex);
 	 }
@@ -9008,9 +9165,10 @@ SiS_SetChReg(SiS_Private *SiS_Pr, USHORT
   return FALSE;
 }
 
+#if 0
 #ifdef SIS300
 /* Write Trumpion register */
-void
+static void
 SiS_SetTrumpReg(SiS_Private *SiS_Pr, USHORT tempbx)
 {
   SiS_Pr->SiS_DDC_DeviceAddr = 0xF0;  		/* DAB (Device Address Byte) */
@@ -9021,6 +9179,7 @@ SiS_SetTrumpReg(SiS_Private *SiS_Pr, USH
   SiS_SetChReg(SiS_Pr, tempbx, 0);
 }
 #endif
+#endif
 
 /* Write to Chrontel 700x */
 /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
@@ -9098,9 +9257,10 @@ SiS_GetChReg(SiS_Private *SiS_Pr, USHORT
   return 0xFFFF;
 }
 
+#if 0
 #ifdef SIS300
 /* Read from Trumpion */
-USHORT
+static USHORT
 SiS_GetTrumpReg(SiS_Private *SiS_Pr, USHORT tempbx)
 {
   SiS_Pr->SiS_DDC_DeviceAddr = 0xF0;	/* DAB */
@@ -9112,6 +9272,7 @@ SiS_GetTrumpReg(SiS_Private *SiS_Pr, USH
   return(SiS_GetChReg(SiS_Pr,0));
 }
 #endif
+#endif
 
 /* Read from Chrontel 700x */
 /* Parameter is [Register no (S7-S0)] */
@@ -9172,7 +9333,7 @@ SiS_GetCH70xx(SiS_Private *SiS_Pr, USHOR
 }
 
 /* Our own DDC functions */
-USHORT
+static USHORT
 SiS_InitDDCRegs(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
                 USHORT adaptnum, USHORT DDCdatatype, BOOLEAN checkcr32)
 {
@@ -9286,7 +9447,7 @@ SiS_InitDDCRegs(SiS_Private *SiS_Pr, uns
     return 0;
 }
 
-USHORT
+static USHORT
 SiS_WriteDABDDC(SiS_Private *SiS_Pr)
 {
    if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
@@ -9299,7 +9460,7 @@ SiS_WriteDABDDC(SiS_Private *SiS_Pr)
    return(0);
 }
 
-USHORT
+static USHORT
 SiS_PrepareReadDDC(SiS_Private *SiS_Pr)
 {
    if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
@@ -9309,7 +9470,7 @@ SiS_PrepareReadDDC(SiS_Private *SiS_Pr)
    return(0);
 }
 
-USHORT
+static USHORT
 SiS_PrepareDDC(SiS_Private *SiS_Pr)
 {
    if(SiS_WriteDABDDC(SiS_Pr)) SiS_WriteDABDDC(SiS_Pr);
@@ -9317,7 +9478,7 @@ SiS_PrepareDDC(SiS_Private *SiS_Pr)
    return(0);
 }
 
-void
+static void
 SiS_SendACK(SiS_Private *SiS_Pr, USHORT yesno)
 {
    SiS_SetSCLKLow(SiS_Pr);
@@ -9335,7 +9496,7 @@ SiS_SendACK(SiS_Private *SiS_Pr, USHORT 
    SiS_SetSCLKHigh(SiS_Pr);
 }
 
-USHORT
+static USHORT
 SiS_DoProbeDDC(SiS_Private *SiS_Pr)
 {
     unsigned char mask, value;
@@ -9385,7 +9546,7 @@ SiS_DoProbeDDC(SiS_Private *SiS_Pr)
     return(ret);
 }
 
-USHORT
+static USHORT
 SiS_ProbeDDC(SiS_Private *SiS_Pr)
 {
    USHORT flag;
@@ -9401,7 +9562,7 @@ SiS_ProbeDDC(SiS_Private *SiS_Pr)
    return(flag);
 }
 
-USHORT
+static USHORT
 SiS_ReadDDC(SiS_Private *SiS_Pr, USHORT DDCdatatype, unsigned char *buffer)
 {
    USHORT flag, length, i;
@@ -9444,8 +9605,9 @@ SiS_ReadDDC(SiS_Private *SiS_Pr, USHORT 
    regards chipset and video bridge type.
 
    Arguments:
-       adaptnum: 0=CRT1, 1=LCD, 2=VGA2
-                 CRT2 DDC is only supported on SiS301, 301B, 302B.
+       adaptnum: 0=CRT1(analog), 1=CRT2/LCD(digital), 2=CRT2/VGA2(analog)
+                 CRT2 DDC is only supported on SiS301, 301B, 301C, 302B.
+		 LCDA is CRT1, but DDC is read from CRT2 port.
        DDCdatatype: 0=Probe, 1=EDID, 2=EDID+VDIF, 3=EDID V2 (P&D), 4=EDID V2 (FPDI-2)
        buffer: ptr to 256 data bytes which will be filled with read data.
 
@@ -9487,6 +9649,19 @@ SiS_HandleDDC(SiS_Private *SiS_Pr, unsig
       result = SiS_ProbeDDC(SiS_Pr);
    } else {
       result = SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer);
+      if((!result) && (DDCdatatype == 1)) {
+         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) &&
+	    (buffer[0x12] == 1)) {
+	    if(adaptnum == 1) {
+	       if(!(buffer[0x14] & 0x80)) result = 0xFFFE;
+	    } else {
+	       if(buffer[0x14] & 0x80)    result = 0xFFFE;
+	    }
+	 }
+      }
    }
    SiS_SetReg(SiS_Pr->SiS_P3c4,0x1f,sr1f);
    if(VGAEngine == SIS_300_VGA) {
@@ -9546,9 +9721,12 @@ USHORT
 SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS)
 {
    USHORT DDCdatatype, paneltype, flag, xres=0, yres=0;
-   USHORT index, myindex, lumsize, numcodes;
+   USHORT index, myindex, lumsize, numcodes, panelvendor, panelproduct;
+   int maxx=0, maxy=0, prefx=0, prefy=0;
    unsigned char cr37=0, seekcode;
    BOOLEAN checkexpand = FALSE;
+   BOOLEAN havesync = FALSE;
+   BOOLEAN indb = FALSE;
    int retry, i;
    unsigned char buffer[256];
 
@@ -9557,6 +9735,8 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SIS
    SiS_Pr->CP_MaxX = SiS_Pr->CP_MaxY = SiS_Pr->CP_MaxClock = 0;
    SiS_Pr->CP_PreferredX = SiS_Pr->CP_PreferredY = 0;
    SiS_Pr->CP_PreferredIndex = -1;
+   SiS_Pr->CP_PrefClock = 0;
+   SiS_Pr->PanelSelfDetected = FALSE;
 
    if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) return 0;
    if(pSiS->VBFlags & VB_30xBDH) return 0;
@@ -9612,25 +9792,24 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SIS
       /* Catch a few clear cases: */
       if(!(checkedid1(buffer))) {
          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
-	 	"CRT2: EDID corrupt\n");
+	 	"LCD sense: EDID corrupt\n");
 	 return 0;
       }
 
       if(!(buffer[0x14] & 0x80)) {
          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
-	        "CRT2: Attached display expects analog input (0x%02x)\n",
+	        "LCD sense: Attached display expects analog input (0x%02x)\n",
 		buffer[0x14]);
       	 return 0;
       }
 
       if((buffer[0x18] & 0x18) != 0x08) {
          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
-	 	"CRT2: Attached display is not of RGB but of %s type (0x%02x)\n",
+	 	"LCD sense: Warning: Attached display is not of RGB but of %s type (0x%02x)\n",
 		((buffer[0x18] & 0x18) == 0x00) ? "monochrome/greyscale" :
 		  ( ((buffer[0x18] & 0x18) == 0x10) ? "non-RGB multicolor" :
 		     "undefined"),
 		buffer[0x18]);
-	 return 0;
       }
 
       /* Now analyze the first Detailed Timing Block and see
@@ -9642,13 +9821,23 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SIS
       paneltype = Panel_Custom;
       checkexpand = FALSE;
 
+      panelvendor = buffer[9] | (buffer[8] << 8);
+      panelproduct = buffer[10] | (buffer[11] << 8);
+
+      /* Overrule bogus preferred modes from database */
+      if((indb = SiS_FindPanelFromDB(pSiS, panelvendor, panelproduct, &maxx, &maxy, &prefx, &prefy))) {
+         if(prefx) SiS_Pr->CP_PreferredX = xres = prefx;
+	 if(prefy) SiS_Pr->CP_PreferredY = yres = prefy;
+      }
+
       if(buffer[0x18] & 0x02) {
 
-         xres = buffer[0x38] | ((buffer[0x3a] & 0xf0) << 4);
-         yres = buffer[0x3b] | ((buffer[0x3d] & 0xf0) << 4);
+         USHORT pclk = (buffer[0x36] | (buffer[0x37] << 8));
+	 USHORT phb  = (buffer[0x39] | ((buffer[0x3a] & 0x0f) << 8));
+	 USHORT pvb  = (buffer[0x3c] | ((buffer[0x3d] & 0x0f) << 8));
 
-	 SiS_Pr->CP_PreferredX = xres;
-	 SiS_Pr->CP_PreferredY = yres;
+	 if(!xres) SiS_Pr->CP_PreferredX = xres = buffer[0x38] | ((buffer[0x3a] & 0xf0) << 4);
+         if(!yres) SiS_Pr->CP_PreferredY = yres = buffer[0x3b] | ((buffer[0x3d] & 0xf0) << 4);
 
          switch(xres) {
 #if 0	    /* Treat as custom */
@@ -9676,14 +9865,20 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SIS
 		      paneltype = Panel310_1280x960;
 		   }
 	        } else if(yres == 768) {
-		   if( ((buffer[0x36] | (buffer[0x37] << 8)) == 8100) &&
-		       ((buffer[0x39] | ((buffer[0x3a] & 0x0f) << 8)) == (1688 - 1280)) &&
-		       ((buffer[0x3c] | ((buffer[0x3d] & 0x0f) << 8)) == (802 - 768)) ) {
+		   if( (pclk == 8100) &&
+		       (phb == (1688 - 1280)) &&
+		       (pvb == (802 - 768)) ) {
 	       	      paneltype = Panel_1280x768;
 		      checkexpand = FALSE;
 		      cr37 |= 0x10;
 		   }
-	        }
+	        } else if(yres == 800) {
+		   if( (pclk == 6900) &&
+		       (phb == (1408 - 1280)) &&
+		       (pvb == (816 - 800)) ) {
+	       	      paneltype = Panel_1280x800;
+		   }
+		}
 	        break;
 	    case 1400:
 	        if(pSiS->VGAEngine == SIS_315_VGA) {
@@ -9693,7 +9888,6 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SIS
 	           }
 	        }
       	        break;
-#if 0	    /* Treat this as custom, as we have no valid timing data yet */
 	    case 1600:
 	        if(pSiS->VGAEngine == SIS_315_VGA) {
 		   if(pSiS->VBFlags & VB_301C) {
@@ -9704,41 +9898,61 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SIS
 	           }
 	        }
       	        break;
-#endif
          }
 
-	 if(paneltype != Panel_Custom) {
-	    if((buffer[0x47] & 0x18) == 0x18) {
-	       cr37 |= ((((buffer[0x47] & 0x06) ^ 0x06) << 5) | 0x20);
-	    } else {
-	       /* What now? There is no digital separate output timing... */
-	       xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
-	       	   "CRT2: Unable to retrieve Sync polarity information\n");
-	       cr37 |= 0xc0;  /* Default */
-	    }
+	 /* Save sync: This is used if "Pass 1:1" is off; in this case
+	  * we always use the panel's native mode = this "preferred mode"
+	  * we just have been analysing. Hence, we also need its sync.
+	  */
+	 if((buffer[0x47] & 0x18) == 0x18) {
+	    cr37 |= ((((buffer[0x47] & 0x06) ^ 0x06) << 5) | 0x20);
+	    havesync = TRUE;
+	 } else {
+	    /* What now? There is no digital separate output timing... */
+	    xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
+	       	   "LCD sense: Unable to retrieve Sync polarity information\n");
+	    cr37 |= 0xc0;  /* Default */
 	 }
 
       }
 
+      /* Check against our database; eg. Sanyo Z2 projector reports
+       * 1024x768 as preferred mode, although it supports 1280x720
+       * natively in non-HDCP mode. Treat such wrongly reporting
+       * panels as custom and fixup actual maximum resolutions.
+       */
+      if(paneltype != Panel_Custom) {
+         if(indb) {
+	    paneltype = Panel_Custom;
+	    SiS_Pr->CP_MaxX = maxx;
+	    SiS_Pr->CP_MaxY = maxy;
+	    /* Leave preferred unchanged (MUST contain a valid mode!) */
+	 }
+      }
+
       /* If we still don't know what panel this is, we take it
        * as a custom panel and derive the timing data from the
        * detailed timing blocks
        */
       if(paneltype == Panel_Custom) {
 
-         BOOLEAN havesync = FALSE;
 	 int i, temp, base = 0x36;
 	 unsigned long estpack;
-	 unsigned short estx[] = {
+	 const unsigned short estx[] = {
 	 	720, 720, 640, 640, 640, 640, 800, 800,
 		800, 800, 832,1024,1024,1024,1024,1280,
 		1152
 	 };
-	 unsigned short esty[] = {
+	 const unsigned short esty[] = {
 	 	400, 400, 480, 480, 480, 480, 600, 600,
 		600, 600, 624, 768, 768, 768, 768,1024,
 		870
 	 };
+	 const int estclk[] = {
+	            0,     0, 25100,   0, 31500, 31500, 36100, 40000,
+		50100, 49500,     0,   0, 65100, 75200, 78700,135200,
+		0
+	 };
 
 	 paneltype = 0;
 	 SiS_Pr->CP_Supports64048075 = TRUE;
@@ -9751,9 +9965,15 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SIS
 	     if(estpack & (1 << i)) {
 	        if(estx[16 - i] > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = estx[16 - i];
 		if(esty[16 - i] > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = esty[16 - i];
+		if(estclk[16 - i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = estclk[16 - i];
 	     }
 	 }
 
+	 /* 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;
+
 	 /* 2. From Standard Timings */
 	 for(i=0x26; i < 0x36; i+=2) {
 	    if((buffer[i] != 0x01) && (buffer[i+1] != 0x01)) {
@@ -9797,29 +10017,29 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SIS
 	       SiS_Pr->CP_DataValid[i] = TRUE;
 
 	       /* Sort out invalid timings, interlace and too high clocks */
-	       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])      			||
+	       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)))	||
+	           ((!(pSiS->VBFlags & VB_301C)) &&
+		    ((SiS_Pr->CP_Clock[i] > 108200) || (SiS_Pr->CP_VDisplay[i] > 1024) ||
+		     (SiS_Pr->CP_HDisplay[i] > 1600)))) 				  ||
 		  (buffer[base+17] & 0x80)) {
 
 	          SiS_Pr->CP_DataValid[i] = FALSE;
 
 	       } else {
 
-	          paneltype = Panel_Custom;
-
 		  SiS_Pr->CP_HaveCustomData = TRUE;
 
 		  if(xres > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = xres;
@@ -9828,22 +10048,10 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SIS
 
 		  if((SiS_Pr->CP_PreferredX == xres) && (SiS_Pr->CP_PreferredY == yres)) {
 	             SiS_Pr->CP_PreferredIndex = i;
+		     SiS_MakeClockRegs(pSiS->pScrn, SiS_Pr->CP_Clock[i], &SiS_Pr->CP_PrefSR2B, &SiS_Pr->CP_PrefSR2C);
+		     SiS_Pr->CP_PrefClock = (SiS_Pr->CP_Clock[i] / 1000) + 1;
 	          }
 
-		  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
-		   */
-	          checkexpand = FALSE;
-	          cr37 |= 0x10;
-
 	          /* Extract the sync polarisation information. This only works
 	           * if the Flags indicate a digital separate output.
 	           */
@@ -9851,20 +10059,37 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SIS
 		     SiS_Pr->CP_HSync_P[i] = (buffer[base+17] & 0x02) ? TRUE : FALSE;
 		     SiS_Pr->CP_VSync_P[i] = (buffer[base+17] & 0x04) ? TRUE : FALSE;
 		     SiS_Pr->CP_SyncValid[i] = TRUE;
-		     if(!havesync) {
+		     if((i == SiS_Pr->CP_PreferredIndex) && (!havesync)) {
 	                cr37 |= ((((buffer[base+17] & 0x06) ^ 0x06) << 5) | 0x20);
 			havesync = TRUE;
 	   	     }
 	          } else {
 		     SiS_Pr->CP_SyncValid[i] = FALSE;
 		  }
+
 	       }
-            }
+
+            } else if((!buffer[base]) && (!buffer[base+1]) && (!buffer[base+2]) && (!buffer[base+4])) {
+
+	       /* Maximum pixclock from Monitor Range Limits */
+	       if((buffer[base+3] == 0xfd) && (buffer[base+9] != 0xff)) {
+	          int maxclk = buffer[base+9] * 10;
+		  /* More than 170 is not supported anyway */
+		  if(maxclk <= 170) SiS_Pr->CP_MaxClock = maxclk * 1000;
+	       }
+
+	    }
+
 	 }
-	 if(!havesync) {
-	    xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
-	       	   "CRT2: Unable to retrieve Sync polarity information\n");
-   	 }
+
+	 if(SiS_Pr->CP_MaxX && SiS_Pr->CP_MaxY) {
+	    paneltype = Panel_Custom;
+	    checkexpand = FALSE;
+	    cr37 |= 0x10;
+	    SiS_Pr->CP_Vendor = panelvendor;
+	    SiS_Pr->CP_Product = panelproduct;
+	 }
+
       }
 
       if(paneltype && checkexpand) {
@@ -9887,28 +10112,32 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SIS
 
       if(!(checkedid2(buffer))) {
          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
-	 	"CRT2: EDID corrupt\n");
+	 	"LCD sense: EDID corrupt\n");
 	 return 0;
       }
 
       if((buffer[0x41] & 0x0f) == 0x03) {
          index = 0x42 + 3;
          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
-	 	"CRT2: Display supports TMDS input on primary interface\n");
+	 	"LCD sense: Display supports TMDS input on primary interface\n");
       } else if((buffer[0x41] & 0xf0) == 0x30) {
          index = 0x46 + 3;
          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
-	 	"CRT2: Display supports TMDS input on secondary interface\n");
+	 	"LCD sense: Display supports TMDS input on secondary interface\n");
       } else {
          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
-	 	"CRT2: Display does not support TMDS video interface (0x%02x)\n", 
+	 	"LCD sense: Display does not support TMDS video interface (0x%02x)\n",
 		buffer[0x41]);
 	 return 0;
       }
 
+      SiS_Pr->CP_Vendor = panelvendor = buffer[2] | (buffer[1] << 8);
+      SiS_Pr->CP_Product = panelproduct = buffer[3] | (buffer[4] << 8);
+
       paneltype = Panel_Custom;
-      SiS_Pr->CP_MaxX = xres = buffer[0x76] | (buffer[0x77] << 8);
-      SiS_Pr->CP_MaxY = yres = buffer[0x78] | (buffer[0x79] << 8);
+      SiS_Pr->CP_MaxX = SiS_Pr->CP_PreferredX = xres = buffer[0x76] | (buffer[0x77] << 8);
+      SiS_Pr->CP_MaxY = SiS_Pr->CP_PreferredY = yres = buffer[0x78] | (buffer[0x79] << 8);
+
       switch(xres) {
 #if 0
          case 800:
@@ -9945,7 +10174,6 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SIS
 	        }
 	     }
       	     break;
-#if 0    /* Treat this one as custom since we have no timing data yet */
 	 case 1600:
 	     if(pSiS->VGAEngine == SIS_315_VGA) {
 	        if(pSiS->VBFlags & VB_301C) {
@@ -9956,7 +10184,6 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SIS
 	        }
 	     }
       	     break;
-#endif
       }
 
       /* Determine if RGB18 or RGB24 */
@@ -9979,7 +10206,25 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SIS
 	 lumsize++;  /* luminance header byte */
 	 index += lumsize;
       }
+#if 0 /* "pixel rate" = pixel clock? */
+      if(buffer[0x7e] & 0x1c) {
+         for(i=0; i<((buffer[0x7e] & 0x1c) >> 2); i++) {
+	    if(buffer[index + (i*8) + 6] && (buffer[index + (i*8) + 7] & 0x0f)) {
+	       int clk = (buffer[index + (i*8) + 6] | ((buffer[index + (i*8) + 7] & 0x0f) << 4)) * 1000;
+	       if(clk > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = clk;
+	    }
+	 }
+      }
+#endif
       index += (((buffer[0x7e] & 0x1c) >> 2) * 8);   /* skip Frequency Ranges */
+      if(buffer[0x7e] & 0x03) {
+         for(i=0; i<(buffer[0x7e] & 0x03); i++) {
+	    if((buffer[index + (i*27) + 9]) || (buffer[index + (i*27) + 10])) {
+	       int clk = ((buffer[index + (i*27) + 9]) | ((buffer[index + (i*27) + 9]) << 8)) * 10;
+	       if(clk > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = clk;
+	    }
+	 }
+      }
       index += ((buffer[0x7e] & 0x03) * 27);         /* skip Detailed Range Limits */
       numcodes = (buffer[0x7f] & 0xf8) >> 3;
       if(numcodes) {
@@ -9991,13 +10236,29 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SIS
 	 }
 	 if(buffer[myindex] == seekcode) {
 	    cr37 |= ((((buffer[myindex + 1] & 0x0c) ^ 0x0c) << 4) | 0x20);
+	    havesync = TRUE;
 	 } else {
 	    xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
-	        "CRT2: Unable to retrieve Sync polarity information\n");
+	        "LCD sense: Unable to retrieve Sync polarity information\n");
 	 }
       } else {
          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
-	     "CRT2: Unable to retrieve Sync polarity information\n");
+	     "LCD sense: Unable to retrieve Sync polarity information\n");
+      }
+
+      /* Check against our database; Eg. Sanyo projector reports
+       * 1024x768 in non-HDPC mode, although it supports 1280x720.
+       * Treat such wrongly reporting panels as custom.
+       */
+      if(paneltype != Panel_Custom) {
+         int maxx, maxy, prefx, prefy;
+         if((SiS_FindPanelFromDB(pSiS, panelvendor, panelproduct, &maxx, &maxy, &prefx, &prefy))) {
+	    paneltype = Panel_Custom;
+	    SiS_Pr->CP_MaxX = maxx;
+	    SiS_Pr->CP_MaxY = maxy;
+	    cr37 |= 0x10;
+	    /* Leave preferred unchanged (MUST be a valid mode!) */
+	 }
       }
 
       /* Now seek the detailed timing descriptions for custom panels */
@@ -10043,7 +10304,8 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SIS
 	       (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)))	||
+	        ((!(pSiS->VBFlags & VB_301C)) &&
+		 ((SiS_Pr->CP_Clock[i] > 108200) || (SiS_Pr->CP_VDisplay[i] > 1024))))	||
 	       (buffer[index + 17] & 0x80)) {
 
 	       SiS_Pr->CP_DataValid[i] = FALSE;
@@ -10054,25 +10316,25 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SIS
 
 	       if(SiS_Pr->CP_Clock[i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = SiS_Pr->CP_Clock[i];
 
-	       if((SiS_Pr->CP_MaxX == xres) && (SiS_Pr->CP_MaxY == yres)) {
+	       if((SiS_Pr->CP_PreferredX == xres) && (SiS_Pr->CP_PreferredY == yres)) {
 	          SiS_Pr->CP_PreferredIndex = i;
+		  SiS_MakeClockRegs(pSiS->pScrn, SiS_Pr->CP_Clock[i], &SiS_Pr->CP_PrefSR2B, &SiS_Pr->CP_PrefSR2C);
+		  SiS_Pr->CP_PrefClock = (SiS_Pr->CP_Clock[i] / 1000) + 1;
+		  if(!havesync) {
+	             cr37 |= ((((buffer[index + 17] & 0x06) ^ 0x06) << 5) | 0x20);
+		     havesync = TRUE;
+	   	  }
 	       }
 
 	       SiS_Pr->CP_HSync_P[i] = (buffer[index + 17] & 0x02) ? TRUE : FALSE;
 	       SiS_Pr->CP_VSync_P[i] = (buffer[index + 17] & 0x04) ? TRUE : FALSE;
 	       SiS_Pr->CP_SyncValid[i] = TRUE;
 
-	       SiS_Pr->CP_Vendor = buffer[2] | (buffer[1] << 8);
-	       SiS_Pr->CP_Product = buffer[3] | (buffer[4] << 8);
-
-	       /* We must assume the panel can scale, since we have
-	        * no scaling data
-    	        */
-	       cr37 |= 0x10;
-
 	    }
 	 }
 
+	 cr37 |= 0x10;
+
       }
 
       break;
@@ -10091,7 +10353,7 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SIS
    for(i = 0; i < 7; i++) {
       if(SiS_Pr->CP_DataValid[i]) {
          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
-            "Non-standard LCD timing data no. %d:\n", i);
+            "Non-standard LCD/DVI-D timing data no. %d:\n", i);
          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
 	    "   HDisplay %d HSync %d HSyncEnd %d HTotal %d\n",
 	    SiS_Pr->CP_HDisplay[i], SiS_Pr->CP_HSyncStart[i],
@@ -10119,7 +10381,7 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SIS
        SiS_Pr->PanelSelfDetected = TRUE;
 #ifdef TWDEBUG
        xf86DrvMsgVerb(pSiS->pScrn->scrnIndex, X_PROBED, 3, 
-       	   "CRT2: [DDC LCD results: 0x%02x, 0x%02x]\n", paneltype, cr37);
+       	   "LCD sense: [DDC LCD results: 0x%02x, 0x%02x]\n", paneltype, cr37);
 #endif	
    } else {
        SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x32,~0x08);
@@ -10155,7 +10417,7 @@ SiS_SenseVGA2DDC(SiS_Private *SiS_Pr, SI
       DDCdatatype = 1;
    } else {
    	xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
-		"Do DDC answer\n");
+		"VGA2 sense: Do DDC answer\n");
    	return 0;				/* no DDC support (or no device attached) */
    }
 
@@ -10164,7 +10426,7 @@ SiS_SenseVGA2DDC(SiS_Private *SiS_Pr, SI
    do {
       if(SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer)) {
          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
-	 	"CRT2: DDC read failed (attempt %d), %s\n",
+	 	"VGA2 sense: DDC read failed (attempt %d), %s\n",
 		(3-retry), (retry == 1) ? "giving up" : "retrying");
 	 retry--;
 	 if(retry == 0) return 0xFFFF;
@@ -10177,13 +10439,13 @@ SiS_SenseVGA2DDC(SiS_Private *SiS_Pr, SI
    switch(DDCdatatype) {
    case 1:
       if(!(checkedid1(buffer))) {
-          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
-	  	"CRT2: EDID corrupt\n");
+          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_ERROR,
+	  	"VGA2 sense: 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");
+          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_ERROR,
+	  	"VGA2 sense: Attached display expects digital input\n");
       	  return 0;
       }
       SiS_Pr->CP_Vendor = buffer[9] | (buffer[8] << 8);
@@ -10193,16 +10455,16 @@ SiS_SenseVGA2DDC(SiS_Private *SiS_Pr, SI
    case 3:
    case 4:
       if(!(checkedid2(buffer))) {
-          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
-	  	"CRT2: EDID corrupt\n");
+          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_ERROR,
+	  	"VGA2 sense: EDID corrupt\n");
       	  return 0;
       }
       if( ((buffer[0x41] & 0x0f) != 0x01) &&  	/* Display does not support analog input */
           ((buffer[0x41] & 0x0f) != 0x02) &&
 	  ((buffer[0x41] & 0xf0) != 0x10) &&
 	  ((buffer[0x41] & 0xf0) != 0x20) ) {
-	  xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
-	     	"CRT2: Attached display does not support analog input (0x%02x)\n",
+	  xf86DrvMsg(pSiS->pScrn->scrnIndex, X_ERROR,
+	     	"VGA2 sense: Attached display does not support analog input (0x%02x)\n",
 		buffer[0x41]);
 	  return 0;
       }
@@ -10232,7 +10494,7 @@ SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, 
 
 /* Generic I2C functions for Chrontel & DDC --------- */
 
-void
+static void
 SiS_SetSwitchDDC2(SiS_Private *SiS_Pr)
 {
   SiS_SetSCLKHigh(SiS_Pr);
@@ -10251,7 +10513,7 @@ SiS_ReadDDC1Bit(SiS_Private *SiS_Pr)
 
 /* Set I2C start condition */
 /* This is done by a SD high-to-low transition while SC is high */
-USHORT
+static USHORT
 SiS_SetStart(SiS_Private *SiS_Pr)
 {
   if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;			           /* (SC->low)  */
@@ -10270,7 +10532,7 @@ SiS_SetStart(SiS_Private *SiS_Pr)
 
 /* Set I2C stop condition */
 /* This is done by a SD low-to-high transition while SC is high */
-USHORT
+static USHORT
 SiS_SetStop(SiS_Private *SiS_Pr)
 {
   if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;			           /* (SC->low) */
@@ -10288,7 +10550,7 @@ SiS_SetStop(SiS_Private *SiS_Pr)
 }
 
 /* Write 8 bits of data */
-USHORT
+static USHORT
 SiS_WriteDDC2Data(SiS_Private *SiS_Pr, USHORT tempax)
 {
   USHORT i,flag,temp;
@@ -10314,7 +10576,7 @@ SiS_WriteDDC2Data(SiS_Private *SiS_Pr, U
   return(temp);
 }
 
-USHORT
+static USHORT
 SiS_ReadDDC2Data(SiS_Private *SiS_Pr, USHORT tempax)
 {
   USHORT i,temp,getdata;
@@ -10334,7 +10596,7 @@ SiS_ReadDDC2Data(SiS_Private *SiS_Pr, US
   return(getdata);
 }
 
-USHORT
+static USHORT
 SiS_SetSCLKLow(SiS_Private *SiS_Pr)
 {
   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
@@ -10345,7 +10607,7 @@ SiS_SetSCLKLow(SiS_Private *SiS_Pr)
   return 0;
 }
 
-USHORT
+static USHORT
 SiS_SetSCLKHigh(SiS_Private *SiS_Pr)
 {
   USHORT temp, watchdog=1000;
@@ -10369,7 +10631,7 @@ SiS_SetSCLKHigh(SiS_Private *SiS_Pr)
 
 /* Check I2C acknowledge */
 /* Returns 0 if ack ok, non-0 if ack not ok */
-USHORT
+static USHORT
 SiS_CheckACK(SiS_Private *SiS_Pr)
 {
   USHORT tempah;
@@ -11075,35 +11337,18 @@ SetPhaseIncr(SiS_Private *SiS_Pr, PSIS_H
   }
 }
 
-void
-SiS_OEM310Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
-                  USHORT ModeNo,USHORT ModeIdIndex)
-{
-   SetDelayComp(SiS_Pr,HwInfo,ModeNo);
-
-   if(SiS_Pr->UseCustomMode) return;
-
-   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_SIS301) {
-         SetEdgeEnhance(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
-      }
-   }
-}
-
 static void
 SetDelayComp661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo,
                 USHORT ModeIdIndex, USHORT RTI)
 {
-   USHORT delay = 0, romptr = 0, index;
+   USHORT delay = 0, romptr = 0, index, lcdpdcindex;
    UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
 
    if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToRAMDAC)))
       return;
 
    /* 1. New ROM: VGA2 and LCD/LCDA-Pass1:1 */
+   /* (If a custom mode is used, Pass1:1 is always set; hence we do this:) */
 
    if(SiS_Pr->SiS_ROMNew) {
       if((SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) 			||
@@ -11121,7 +11366,7 @@ SetDelayComp661(SiS_Private *SiS_Pr, PSI
          if((ROMAddr[0x5b] & 0x80) || (SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD))) {
 	    index++;
 	 }
-	 romptr = SISGETROMW(0x104);  /* 0x4ae */
+	 romptr = SISGETROMW(0x104);
          delay = ROMAddr[romptr + index];
          if(SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD)) {
             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
@@ -11147,10 +11392,12 @@ SetDelayComp661(SiS_Private *SiS_Pr, PSI
 
       index = GetOEMTVPtr661(SiS_Pr);
       if(SiS_Pr->SiS_ROMNew) {
-         romptr = SISGETROMW(0x106);  /* 0x4ba */
+         romptr = SISGETROMW(0x106);
+	 if(SiS_Pr->SiS_VBType & VB_UMC) romptr += 12;
          delay = ROMAddr[romptr + index];
       } else {
          delay = 0x04;
+	 if(index > 3) delay = 0;
       }
 
    } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
@@ -11160,22 +11407,41 @@ SetDelayComp661(SiS_Private *SiS_Pr, PSI
       if( (SiS_Pr->SiS_LCDResInfo != Panel_Custom) &&
           ((romptr = GetLCDStructPtr661_2(SiS_Pr, HwInfo))) ) {
 
-	 /* For LV, the BIOS must know about the correct value */
-	 delay = ROMAddr[romptr + 0x0d];		/* LCD  */
-	 delay |= (ROMAddr[romptr + 0x0c] << 8);	/* LCDA */
+	 lcdpdcindex = (SiS_Pr->SiS_VBType & VB_UMC) ? 14 : 12;
+
+	 /* For LVDS (and sometimes TMDS), the BIOS must know about the correct value */
+	 delay = ROMAddr[romptr + lcdpdcindex + 1];	/* LCD  */
+	 delay |= (ROMAddr[romptr + lcdpdcindex] << 8);	/* LCDA */
 
       } else {
 
-         /* TMDS: Set our own, since BIOS has no idea - TODO: Find out about values */
+         /* TMDS: Set our own, since BIOS has no idea */
+	 /* (This is done on >=661 only, since <661 is calling this only for LVDS) */
          if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
-            if((SiS_Pr->PanelXRes <= 1024) && (SiS_Pr->PanelYRes <= 768)) {
-	       delay = 0x0404;
-            } else if((SiS_Pr->PanelXRes <= 1280) && (SiS_Pr->PanelYRes <= 1024)) {
-	       delay = 0x0404;
-            } else if((SiS_Pr->PanelXRes <= 1400) && (SiS_Pr->PanelYRes <= 1050)) {
-	       delay = 0x1004;
-            } else
-	       delay = 0x0000;
+	    switch(SiS_Pr->SiS_LCDResInfo) {
+	    case Panel_1024x768:  delay = 0x0008; break;
+	    case Panel_1280x720:  delay = 0x0004; break;
+	    case Panel_1280x768:
+	    case Panel_1280x768_2:delay = 0x0004; break;
+	    case Panel_1280x800:
+	    case Panel_1280x800_2:delay = 0x0004; break; /* Verified for 1280x800 */
+	    case Panel_1280x1024: delay = 0x1e04; break;
+	    case Panel_1400x1050: delay = 0x0004; break;
+	    case Panel_1600x1200: delay = 0x0400; break;
+	    case Panel_1680x1050: delay = 0x0e04; break;
+	    default:
+               if((SiS_Pr->PanelXRes <= 1024) && (SiS_Pr->PanelYRes <= 768)) {
+	          delay = 0x0008;
+	       } else if((SiS_Pr->PanelXRes == 1280) && (SiS_Pr->PanelYRes == 1024)) {
+	          delay = 0x1e04;
+               } else if((SiS_Pr->PanelXRes <= 1400) && (SiS_Pr->PanelYRes <= 1050)) {
+	          delay = 0x0004;
+	       } else if((SiS_Pr->PanelXRes <= 1600) && (SiS_Pr->PanelYRes <= 1200)) {
+	          delay = 0x0400;
+               } else
+	          delay = 0x0e04;
+	       break;
+	    }
          }
 
 	 /* Override by detected or user-set values */
@@ -11216,31 +11482,30 @@ SetCRT2SyncDither661(SiS_Private *SiS_Pr
       } else {
          infoflag = SiS_Pr->SiS_RefIndex[RTI].Ext_InfoFlag;
       }
-      infoflag &= 0xc0;
 
-      temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
-      if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
-         temp &= 0x3f;
-	 temp |= infoflag;
-      } else {
-         if(temp & 0x20) infoflag = temp;
+      if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
+         infoflag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37); /* No longer check D5 */
       }
-      if(temp & 0x01) infoflag |= 0x01;
+
+      infoflag &= 0xc0;
 
       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-         temp = 0x0c;
-         if(infoflag & 0x01) temp ^= 0x14;  /* BIOS: 18, wrong */
-         temp |= (infoflag >> 6);
+         temp = (infoflag >> 6) | 0x0c;
+         if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
+	    temp ^= 0x04;
+	    if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x10;
+	 }
          SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xe0,temp);
       } else {
-         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;
+         if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) temp = 0x20;
          temp |= infoflag;
          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0f,temp);
+         temp = 0;
+         if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
+	    if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x80;
+	 }
+         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0x7f,temp);
       }
 
    }
@@ -11279,7 +11544,31 @@ SetPanelParms661(SiS_Private *SiS_Pr, PS
    }
 }
 
-void
+static void
+SiS_OEM310Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+                  USHORT ModeNo,USHORT ModeIdIndex,USHORT RRTI)
+{
+   if((SiS_Pr->SiS_ROMNew) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
+      SetDelayComp661(SiS_Pr,HwInfo,ModeNo,ModeIdIndex,RRTI);
+      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+         SetCRT2SyncDither661(SiS_Pr,HwInfo,ModeNo,RRTI);
+         SetPanelParms661(SiS_Pr,HwInfo);
+      }
+   } else {
+      SetDelayComp(SiS_Pr,HwInfo,ModeNo);
+   }
+
+   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_SIS301) {
+         SetEdgeEnhance(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
+      }
+   }
+}
+
+static void
 SiS_OEM661Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
                   USHORT ModeNo,USHORT ModeIdIndex, USHORT RRTI)
 {
@@ -11310,7 +11599,7 @@ SiS_OEM661Setting(SiS_Private *SiS_Pr, P
  * function looks quite different in every BIOS, so you better
  * pray that we have a backup...
  */
-void
+static void
 SiS_FinalizeLCD(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
                 PSIS_HW_INFO HwInfo)
 {
@@ -11318,6 +11607,7 @@ SiS_FinalizeLCD(SiS_Private *SiS_Pr, USH
   USHORT resinfo,modeflag;
 
   if(!(SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) return;
+  if(SiS_Pr->SiS_ROMNew) return;
 
   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
      if(SiS_Pr->LVDSHL != -1) {
@@ -11514,7 +11804,7 @@ SiS_FinalizeLCD(SiS_Private *SiS_Pr, USH
 
 #ifdef SIS300
 
-void
+static void
 SetOEMLCDData2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
                USHORT ModeNo,USHORT ModeIdIndex, USHORT RefTabIndex)
 {
@@ -11574,7 +11864,9 @@ GetOEMLCDPtr(SiS_Private *SiS_Pr, PSIS_H
 
   if(HwInfo->jChipType == SIS_300) {
 
-    tempbx = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0x0f) - 2;
+    tempbx = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0x0f;
+    if(SiS_Pr->SiS_VBType & VB_SIS301) tempbx &= 0x07;
+    tempbx -= 2;
     if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 4;
     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 3;
@@ -11612,7 +11904,9 @@ GetOEMLCDPtr(SiS_Private *SiS_Pr, PSIS_H
     tempbx = SiS_Pr->SiS_LCDTypeInfo << 2;
     if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
+
   }
+
   return tempbx;
 }
 
@@ -11914,7 +12208,7 @@ SiS_SearchVBModeID(SiS_Private *SiS_Pr, 
    return ModeIdIndex;
 }
 
-void
+static void
 SiS_OEM300Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
 		  USHORT ModeNo, USHORT ModeIdIndex, USHORT RefTableIndex)
 {
diff -puN drivers/video/sis/init301.h~fbdev-sis-framebuffer-driver-update-1717 drivers/video/sis/init301.h
--- 25/drivers/video/sis/init301.h~fbdev-sis-framebuffer-driver-update-1717	2004-11-28 01:30:58.859562368 -0800
+++ 25-akpm/drivers/video/sis/init301.h	2004-11-28 01:30:58.924552488 -0800
@@ -35,7 +35,7 @@
  * * 3) 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 EXPRESSED OR
+ * * 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,
@@ -54,20 +54,16 @@
 #define  _INIT301_
 
 #include "osdef.h"
-
 #include "initdef.h"
-#include "vgatypes.h"
-#include "vstruct.h"
 
 #ifdef LINUX_XF86
-#include "xf86.h"
-#include "xf86Pci.h"
-#include "xf86PciInfo.h"
 #include "sis.h"
 #include "sis_regs.h"
 #endif
 
 #ifdef LINUX_KERNEL
+#include "vgatypes.h"
+#include "vstruct.h"
 #ifdef SIS_CP
 #undef SIS_CP
 #endif
@@ -82,7 +78,7 @@
 #endif
 #endif
 
-const UCHAR SiS_YPbPrTable[3][64] = {
+static const UCHAR SiS_YPbPrTable[3][64] = {
   {
     0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c,
     0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a,
@@ -127,7 +123,7 @@ const UCHAR SiS_YPbPrTable[3][64] = {
   }
 };
 
-const UCHAR SiS_HiTVGroup3_1[] = {
+static const UCHAR SiS_HiTVGroup3_1[] = {
     0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x13,
     0xb1, 0x41, 0x62, 0x62, 0xff, 0xf4, 0x45, 0xa6,
     0x25, 0x2f, 0x67, 0xf6, 0xbf, 0xff, 0x8e, 0x20,
@@ -138,7 +134,7 @@ const UCHAR SiS_HiTVGroup3_1[] = {
     0x1a, 0x1f, 0x25, 0x2a, 0x4c, 0xaa, 0x01
 };
 
-const UCHAR SiS_HiTVGroup3_2[] = {
+static const UCHAR SiS_HiTVGroup3_2[] = {
     0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x7a,
     0x54, 0x41, 0xe7, 0xe7, 0xff, 0xf4, 0x45, 0xa6,
     0x25, 0x2f, 0x67, 0xf6, 0xbf, 0xff, 0x8e, 0x20,
@@ -149,7 +145,7 @@ const UCHAR SiS_HiTVGroup3_2[] = {
     0x18, 0x1d, 0x23, 0x28, 0x4c, 0xaa, 0x01
 };
 
-/* 301C / 302ELV extended Part2 TV registers */
+/* 301C / 302ELV extended Part2 TV registers (4 tap scaler) */
 
 static const UCHAR SiS_Part2CLVX_1[] = {
     0x00,0x00,
@@ -224,13 +220,13 @@ static const UCHAR SiS_Part2CLVX_6[] = {
 };
 
 #ifdef SIS315H
-/* 661 et al LCD data structure (0.94.0) */
+/* 661 et al LCD data structure (2.03.00) */
 static const UCHAR SiS_LCDStruct661[] = {
     /* 1024x768 */
 /*  type|CR37|   HDE   |   VDE   |    HT   |    VT   |   hss    | hse   */
     0x02,0xC0,0x00,0x04,0x00,0x03,0x40,0x05,0x26,0x03,0x10,0x00,0x88,
     0x00,0x02,0x00,0x06,0x00,0x41,0x5A,0x64,0x00,0x00,0x00,0x00,0x04,
-    /*  | vss      |   vse  |clck|  clock  |CRT2DataP|CRT2DataP|idx     */
+    /*  | vss     |    vse  |clck|  clock  |CRT2DataP|CRT2DataP|idx     */
     /*					      VESA    non-VESA  noscale */
     /* 1280x1024 */
     0x03,0xC0,0x00,0x05,0x00,0x04,0x98,0x06,0x2A,0x04,0x30,0x00,0x70,
@@ -239,23 +235,20 @@ static const UCHAR SiS_LCDStruct661[] = 
     0x09,0x20,0x78,0x05,0x1A,0x04,0x98,0x06,0x2A,0x04,0x18,0x00,0x38,
     0x00,0x01,0x00,0x03,0x00,0x6C,0xF8,0x2F,0x00,0x00,0x00,0x00,0x09,
     /* 1600x1200 */
-    0x0B,0xC0,0x40,0x06,0xB0,0x04,0x70,0x08,0xE2,0x04,0x40,0x00,0xC0,
-    0x00,0x01,0x00,0x03,0x00,0xA2,0x70,0x24,0x00,0x00,0x00,0x00,0x0B,
-    /* 1280x768 */
-    0x0A,0xC0,0x00,0x05,0x00,0x03,0x80,0x05,0x26,0x03,0x10,0x00,0x40,
-    0x00,0x03,0x00,0x06,0x00,0x44,0x63,0x46,0x00,0x00,0x00,0x00,0x06,
+    0x0B,0xE0,0x40,0x06,0xB0,0x04,0x70,0x08,0xE2,0x04,0x40,0x00,0xC0,
+    0x00,0x01,0x00,0x03,0x00,0xA2,0x70,0x24,0x00,0x00,0x00,0x00,0x0A,
+    /* 1280x768 (_2) */
+    0x0A,0xE0,0x00,0x05,0x00,0x03,0x7C,0x06,0x26,0x03,0x30,0x00,0x70,
+    0x00,0x03,0x00,0x06,0x00,0x4D,0xC8,0x48,0x00,0x00,0x00,0x00,0x06,
     /* 1280x720 */
-    0x0E,0xE0,0x00,0x05,0xD0,0x02,0x80,0x05,0x26,0x03,0x10,0x00,0x02,
+    0x0E,0xE0,0x00,0x05,0xD0,0x02,0x80,0x05,0x26,0x03,0x10,0x00,0x20,
     0x00,0x01,0x00,0x06,0x00,0x45,0x9C,0x62,0x00,0x00,0x00,0x00,0x05,
-    /* 1280x800 */
-    0x0C,0xE0,0x00,0x05,0x20,0x03,0x80,0x05,0x30,0x03,0x10,0x00,0x40,
-    0x00,0x04,0x00,0x03,0x00,0x45,0x9C,0x62,0x00,0x00,0x00,0x00,0x07,
+    /* 1280x800 (_2) */
+    0x0C,0xE0,0x00,0x05,0x20,0x03,0x10,0x06,0x2C,0x03,0x30,0x00,0x70,
+    0x00,0x04,0x00,0x03,0x00,0x49,0xCE,0x1E,0x00,0x00,0x00,0x00,0x09,
     /* 1680x1050 */
     0x0D,0xE0,0x90,0x06,0x1A,0x04,0x6C,0x07,0x2A,0x04,0x1A,0x00,0x4C,
     0x00,0x03,0x00,0x06,0x00,0x79,0xBE,0x44,0x00,0x00,0x00,0x00,0x06,
-    /* 1280x768 (not in 0.93) */
-    0x0A,0xC0,0x00,0x05,0x00,0x03,0x80,0x06,0x1E,0x03,0x40,0x00,0x80,
-    0x00,0x03,0x00,0x07,0x00,0x4F,0x00,0x00,0x00,0x00,0x00,0x00,0x06
 };
 #endif
 
@@ -308,8 +301,8 @@ BOOLEAN	SiS_IsDualEdge(SiS_Private *SiS_
 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);
+              	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);
@@ -330,58 +323,61 @@ void   	SiS_SetCH70xx(SiS_Private *SiS_P
 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);
+static void   	SiS_Chrontel701xOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
+static void   	SiS_Chrontel701xOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
+static void   	SiS_ChrontelInitTVVSync(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
+static 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 */
+
 #ifdef SIS300
-void    SiS_SetTrumpReg(SiS_Private *SiS_Pr, USHORT tempbx);
-USHORT  SiS_GetTrumpReg(SiS_Private *SiS_Pr, USHORT tempbx);
-static  BOOLEAN SiS_SetTrumpionBlock(SiS_Private *SiS_Pr, UCHAR *dataptr);
+#if 0
+static  void    SiS_SetTrumpReg(SiS_Private *SiS_Pr, USHORT tempbx);
+static  USHORT  SiS_GetTrumpReg(SiS_Private *SiS_Pr, USHORT tempbx);
+#endif
+static  BOOLEAN	SiS_SetTrumpionBlock(SiS_Private *SiS_Pr, UCHAR *dataptr);
 #endif
 
-USHORT  SiS_ReadDDC1Bit(SiS_Private *SiS_Pr);
-void    SiS_SetSwitchDDC2(SiS_Private *SiS_Pr);
-USHORT  SiS_SetStart(SiS_Private *SiS_Pr);
-USHORT  SiS_SetStop(SiS_Private *SiS_Pr);
 void    SiS_DDC2Delay(SiS_Private *SiS_Pr, USHORT delaytime);
-USHORT  SiS_SetSCLKLow(SiS_Private *SiS_Pr);
-USHORT  SiS_SetSCLKHigh(SiS_Private *SiS_Pr);
-USHORT  SiS_ReadDDC2Data(SiS_Private *SiS_Pr, USHORT tempax);
-USHORT  SiS_WriteDDC2Data(SiS_Private *SiS_Pr, USHORT tempax);
-USHORT  SiS_CheckACK(SiS_Private *SiS_Pr);
-
-USHORT  SiS_InitDDCRegs(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
-                        USHORT adaptnum, USHORT DDCdatatype, BOOLEAN checkcr32);
-USHORT  SiS_WriteDABDDC(SiS_Private *SiS_Pr);
-USHORT  SiS_PrepareReadDDC(SiS_Private *SiS_Pr);
-USHORT  SiS_PrepareDDC(SiS_Private *SiS_Pr);
-void    SiS_SendACK(SiS_Private *SiS_Pr, USHORT yesno);
-USHORT  SiS_DoProbeDDC(SiS_Private *SiS_Pr);
-USHORT  SiS_ProbeDDC(SiS_Private *SiS_Pr);
-USHORT  SiS_ReadDDC(SiS_Private *SiS_Pr, USHORT DDCdatatype, unsigned char *buffer);
-USHORT  SiS_HandleDDC(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
-		      USHORT adaptnum, USHORT DDCdatatype, unsigned char *buffer);
+USHORT  SiS_ReadDDC1Bit(SiS_Private *SiS_Pr);
+USHORT  SiS_HandleDDC(SiS_Private *SiS_Pr, ULONG VBFlags, int VGAEngine,
+		      USHORT adaptnum, USHORT DDCdatatype, UCHAR *buffer);
 #ifdef LINUX_XF86
 USHORT  SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS);
 USHORT  SiS_SenseVGA2DDC(SiS_Private *SiS_Pr, SISPtr pSiS);
 #endif
 
+static void    	SiS_SetSwitchDDC2(SiS_Private *SiS_Pr);
+static USHORT  	SiS_SetStart(SiS_Private *SiS_Pr);
+static USHORT  	SiS_SetStop(SiS_Private *SiS_Pr);
+static USHORT  	SiS_SetSCLKLow(SiS_Private *SiS_Pr);
+static USHORT  	SiS_SetSCLKHigh(SiS_Private *SiS_Pr);
+static USHORT  	SiS_ReadDDC2Data(SiS_Private *SiS_Pr, USHORT tempax);
+static USHORT  	SiS_WriteDDC2Data(SiS_Private *SiS_Pr, USHORT tempax);
+static USHORT  	SiS_CheckACK(SiS_Private *SiS_Pr);
+static USHORT  	SiS_InitDDCRegs(SiS_Private *SiS_Pr, ULONG VBFlags, int VGAEngine,
+                        USHORT adaptnum, USHORT DDCdatatype, BOOLEAN checkcr32);
+static USHORT  	SiS_WriteDABDDC(SiS_Private *SiS_Pr);
+static USHORT  	SiS_PrepareReadDDC(SiS_Private *SiS_Pr);
+static USHORT  	SiS_PrepareDDC(SiS_Private *SiS_Pr);
+static void    	SiS_SendACK(SiS_Private *SiS_Pr, USHORT yesno);
+static USHORT  	SiS_DoProbeDDC(SiS_Private *SiS_Pr);
+static USHORT  	SiS_ProbeDDC(SiS_Private *SiS_Pr);
+static USHORT  	SiS_ReadDDC(SiS_Private *SiS_Pr, USHORT DDCdatatype, UCHAR *buffer);
+
 #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);
+static void    	SiS_OEM310Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+                        USHORT ModeNo,USHORT ModeIdIndex, USHORT RRTI);
+static void    	SiS_OEM661Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+                        USHORT ModeNo,USHORT ModeIdIndex, USHORT RRTI);
+static 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);
+static void    	SiS_OEM300Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+                        USHORT ModeNo, USHORT ModeIdIndex, USHORT RefTabindex);
+static void    	SetOEMLCDData2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+		        USHORT ModeNo, USHORT ModeIdIndex,USHORT RefTableIndex);
 #endif
 
 extern void     SiS_SetReg(SISIOADDRESS, USHORT, USHORT);
@@ -392,23 +388,23 @@ extern UCHAR    SiS_GetReg(SISIOADDRESS,
 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_SetRegANDOR(SISIOADDRESS, USHORT, USHORT, USHORT);
+extern void     SiS_SetRegOR(SISIOADDRESS, USHORT, USHORT);
+extern void     SiS_SetRegAND(SISIOADDRESS, USHORT, USHORT);
 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);
-
-extern void	SiS_CalcLCDACRT1Timing(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex);
+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);
+extern void	SiS_CalcLCDACRT1Timing(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex);
+#ifdef LINUX_XF86
+extern void     SiS_MakeClockRegs(ScrnInfoPtr pScrn, int clock, UCHAR *p2b, UCHAR *p2c);
+extern int 	SiS_FindPanelFromDB(SISPtr pSiS, USHORT panelvendor, USHORT panelproduct,
+			int *maxx, int *maxy, int *prefx, int *prefy);
+#endif
 
 #endif
diff -puN drivers/video/sis/init.c~fbdev-sis-framebuffer-driver-update-1717 drivers/video/sis/init.c
--- 25/drivers/video/sis/init.c~fbdev-sis-framebuffer-driver-update-1717	2004-11-28 01:30:58.861562064 -0800
+++ 25-akpm/drivers/video/sis/init.c	2004-11-28 01:30:58.934550968 -0800
@@ -38,7 +38,7 @@
  * * 3) 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 EXPRESSED OR
+ * * 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,
@@ -135,8 +135,8 @@ InitCommonPointer(SiS_Private *SiS_Pr, P
    SiS_Pr->SiS_LCD1280x720Data      = SiS_LCD1280x720Data;
    SiS_Pr->SiS_StLCD1280x768_2Data  = SiS_StLCD1280x768_2Data;
    SiS_Pr->SiS_ExtLCD1280x768_2Data = SiS_ExtLCD1280x768_2Data;
-   SiS_Pr->SiS_LCD1280x768_3Data    = SiS_LCD1280x768_3Data;
    SiS_Pr->SiS_LCD1280x800Data      = SiS_LCD1280x800Data;
+   SiS_Pr->SiS_LCD1280x800_2Data    = SiS_LCD1280x800_2Data;
    SiS_Pr->SiS_LCD1280x960Data      = SiS_LCD1280x960Data;
    SiS_Pr->SiS_StLCD1400x1050Data   = SiS_StLCD1400x1050Data;
    SiS_Pr->SiS_ExtLCD1400x1050Data  = SiS_ExtLCD1400x1050Data;
@@ -217,34 +217,6 @@ InitTo300Pointer(SiS_Private *SiS_Pr, PS
 {
    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  = SiS300_SModeIDTable;
    SiS_Pr->SiS_VBModeIDTable = SiS300_VBModeIDTable;
    SiS_Pr->SiS_EModeIDTable  = SiS300_EModeIDTable;
@@ -260,7 +232,7 @@ InitTo300Pointer(SiS_Private *SiS_Pr, PS
 
    SiS_Pr->SiS_SR15  = SiS300_SR15;
 
-#ifndef LINUX_XF86
+#ifdef LINUX_KERNEL
    SiS_Pr->pSiS_SR07 = &SiS300_SR07;
    SiS_Pr->SiS_CR40  = SiS300_CR40;
    SiS_Pr->SiS_CR49  = SiS300_CR49;
@@ -399,39 +371,15 @@ InitTo310Pointer(SiS_Private *SiS_Pr, PS
 {
    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  = SiS310_SModeIDTable;
    SiS_Pr->SiS_EModeIDTable  = SiS310_EModeIDTable;
    SiS_Pr->SiS_RefIndex      = (SiS_Ext2Struct *)SiS310_RefIndex;
    SiS_Pr->SiS_CRT1Table     = SiS310_CRT1Table;
-   if(HwInfo->jChipType >= SIS_760) {
+   if(HwInfo->jChipType >= SIS_340) {
+      SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_340;  /* 340 */
+   } else if(HwInfo->jChipType >= SIS_761) {
+      SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_761;  /* 761 - preliminary */
+   } else if(HwInfo->jChipType >= SIS_760) {
       SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_760;  /* 760 */
    } else if(HwInfo->jChipType >= SIS_661) {
       SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_660;  /* 661/741 */
@@ -442,13 +390,17 @@ InitTo310Pointer(SiS_Private *SiS_Pr, PS
    } else {
       SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_315;  /* 315 */
    }
-   SiS_Pr->SiS_MCLKData_1    = SiS310_MCLKData_1;
+   if(HwInfo->jChipType >= SIS_340) {
+      SiS_Pr->SiS_MCLKData_1    = SiS310_MCLKData_1_340;
+   } else {
+      SiS_Pr->SiS_MCLKData_1    = SiS310_MCLKData_1;
+   }
    SiS_Pr->SiS_VCLKData      = SiS310_VCLKData;
    SiS_Pr->SiS_VBVCLKData    = SiS310_VBVCLKData;
 
    SiS_Pr->SiS_SR15  = SiS310_SR15;
 
-#ifndef LINUX_XF86
+#ifdef LINUX_KERNEL
    SiS_Pr->pSiS_SR07 = &SiS310_SR07;
    SiS_Pr->SiS_CR40  = SiS310_CR40;
    SiS_Pr->SiS_CR49  = SiS310_CR49;
@@ -592,6 +544,8 @@ SiSInitPtr(SiS_Private *SiS_Pr, PSIS_HW_
    case SIS_741:
    case SIS_660:
    case SIS_760:
+   case SIS_761:
+   case SIS_340:
       InitTo310Pointer(SiS_Pr, HwInfo);
       break;
 #endif
@@ -612,6 +566,7 @@ SiSInitPtr(SiS_Private *SiS_Pr, PSIS_HW_
 /*            HELPER: Get ModeID             */
 /*********************************************/
 
+#ifdef LINUX_XF86
 USHORT
 SiS_GetModeID(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay,
               int Depth, BOOLEAN FSTN, int LCDwidth, int LCDheight)
@@ -628,10 +583,14 @@ SiS_GetModeID(int VGAEngine, ULONG VBFla
           }
           break;
      case 400:
-          if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
+          if((!(VBFlags & CRT1_LCDA)) || ((LCDwidth >= 800) && (LCDwidth >= 600))) {
+             if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
+	  }
           break;
      case 512:
-          if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
+          if((!(VBFlags & CRT1_LCDA)) || ((LCDwidth >= 1024) && (LCDwidth >= 768))) {
+             if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
+	  }
           break;
      case 640:
           if(VDisplay == 480)      ModeIndex = ModeIndex_640x480[Depth];
@@ -656,67 +615,58 @@ SiS_GetModeID(int VGAEngine, ULONG VBFla
 	  break;
      case 960:
 	  if(VGAEngine == SIS_315_VGA) {
-	     if(VDisplay == 540) ModeIndex = ModeIndex_960x540[Depth];
+	     if(VDisplay == 540)      ModeIndex = ModeIndex_960x540[Depth];
+	     else if(VDisplay == 600) ModeIndex = ModeIndex_960x600[Depth];
 	  }
 	  break;
      case 1024:
-          if(VDisplay == 768)      ModeIndex = ModeIndex_1024x768[Depth];
-	  else if(VDisplay == 576) ModeIndex = ModeIndex_1024x576[Depth];
-	  else if((!(VBFlags & CRT1_LCDA)) && (VGAEngine == SIS_300_VGA)) {
-	     if(VDisplay == 600) ModeIndex = ModeIndex_1024x600[Depth];
+          if(VDisplay == 576)      ModeIndex = ModeIndex_1024x576[Depth];
+          else if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
+	  else if(VGAEngine == SIS_300_VGA) {
+	     if(VDisplay == 600)   ModeIndex = ModeIndex_1024x600[Depth];
 	  }
           break;
      case 1152:
           if(VDisplay == 864) ModeIndex = ModeIndex_1152x864[Depth];
-          if((!(VBFlags & CRT1_LCDA)) && (VGAEngine == SIS_300_VGA)) {
+          if(VGAEngine == SIS_300_VGA) {
 	     if(VDisplay == 768) ModeIndex = ModeIndex_1152x768[Depth];
 	  }
 	  break;
      case 1280:
-          if(VDisplay == 1024) ModeIndex = ModeIndex_1280x1024[Depth];
-	  else if(VDisplay == 800) {
-	     if(VGAEngine == SIS_315_VGA) {
-	        if((VBFlags & CRT1_LCDA) && (LCDwidth == 1280) && (LCDheight == 800)) {
-	           ModeIndex = ModeIndex_1280x800[Depth];
-	        } else if(!(VBFlags & CRT1_LCDA)) {
-	           ModeIndex = ModeIndex_1280x800[Depth];
-	        }
-	     }
-	  } else if(VDisplay == 720) {
-	     if((VBFlags & CRT1_LCDA) && (LCDwidth == 1280) && (LCDheight == 720)) {
-	        ModeIndex = ModeIndex_1280x720[Depth];
-	     } else if(!(VBFlags & CRT1_LCDA)) {
-	        ModeIndex = ModeIndex_1280x720[Depth];
+          switch(VDisplay) {
+	  case 720:
+	     ModeIndex = ModeIndex_1280x720[Depth];
+	     break;
+	  case 768:
+	     if(VGAEngine == SIS_300_VGA) {
+	        ModeIndex = ModeIndex_300_1280x768[Depth];
+	     } else {
+	        ModeIndex = ModeIndex_310_1280x768[Depth];
 	     }
-	  } else if(!(VBFlags & CRT1_LCDA)) {
-             if(VDisplay == 960) ModeIndex = ModeIndex_1280x960[Depth];
-	     else if(VDisplay == 768) {
-	        if(VGAEngine == SIS_300_VGA) {
-	           ModeIndex = ModeIndex_300_1280x768[Depth];
-	        } else {
-	           ModeIndex = ModeIndex_310_1280x768[Depth];
-	        }
+	     break;
+	  case 800:
+	     if(VGAEngine == SIS_315_VGA) {
+	        ModeIndex = ModeIndex_1280x800[Depth];
 	     }
+	     break;
+	  case 960:
+	     ModeIndex = ModeIndex_1280x960[Depth];
+	     break;
+	  case 1024:
+	     ModeIndex = ModeIndex_1280x1024[Depth];
+	     break;
 	  }
           break;
      case 1360:
           if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth];
-          if(!(VBFlags & CRT1_LCDA)) {
-	     if(VGAEngine == SIS_300_VGA) {
-	        if(VDisplay == 1024) ModeIndex = ModeIndex_300_1360x1024[Depth];
-             }
-	  }
+	  if(VGAEngine == SIS_300_VGA) {
+	     if(VDisplay == 1024) ModeIndex = ModeIndex_300_1360x1024[Depth];
+          }
           break;
      case 1400:
           if(VGAEngine == SIS_315_VGA) {
 	     if(VDisplay == 1050) {
-	        if((VBFlags & CRT1_LCDA) &&
-	           (((LCDwidth == 1400) && (LCDheight == 1050)) ||
-		    ((LCDwidth == 1600) && (LCDheight == 1200)))) {
-	           ModeIndex = ModeIndex_1400x1050[Depth];
-	        } else if(!(VBFlags & CRT1_LCDA)) {
-	           ModeIndex = ModeIndex_1400x1050[Depth];
-	        }
+	        ModeIndex = ModeIndex_1400x1050[Depth];
 	     }
 	  }
           break;
@@ -729,28 +679,25 @@ SiS_GetModeID(int VGAEngine, ULONG VBFla
 	  }
           break;
      case 1920:
-          if(!(VBFlags & CRT1_LCDA)) {
-	     if(VGAEngine == SIS_315_VGA) {
-	        if(VDisplay == 1080) ModeIndex = ModeIndex_1920x1080[Depth];
-	     }
-             if(VDisplay == 1440) ModeIndex = ModeIndex_1920x1440[Depth];
+          if(VDisplay == 1440)    ModeIndex = ModeIndex_1920x1440[Depth];
+	  else if(VGAEngine == SIS_315_VGA) {
+	     if(VDisplay == 1080) ModeIndex = ModeIndex_1920x1080[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];
-                }
-	     }
+          if(VDisplay == 1536) {
+             if(VGAEngine == SIS_300_VGA) {
+	         ModeIndex = ModeIndex_300_2048x1536[Depth];
+  	     } else {
+	         ModeIndex = ModeIndex_310_2048x1536[Depth];
+             }
 	  }
           break;
    }
 
    return(ModeIndex);
 }
+#endif
 
 USHORT
 SiS_GetModeID_LCD(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay,
@@ -783,7 +730,7 @@ SiS_GetModeID_LCD(int VGAEngine, ULONG V
 	case 512:
 	     if(CustomT != CUT_PANEL848) {
 	        if(!((VGAEngine == SIS_300_VGA) && (VBFlags & VB_TRUMPION))) {
-		   if(LCDwidth != 1024 || LCDheight != 600) {
+		   if(LCDwidth >= 1024 && LCDwidth != 1152 && LCDheight >= 768) {
 		      if(VDisplay == 384) {
 		         ModeIndex = ModeIndex_512x384[Depth];
 		      }
@@ -826,9 +773,6 @@ SiS_GetModeID_LCD(int VGAEngine, ULONG V
 	        if((VDisplay == 768) && (LCDheight == 768)) {
 		   ModeIndex = ModeIndex_310_1280x768[Depth];
 		}
-		if((VDisplay == 800) && (LCDheight == 800)) {
-		   ModeIndex = ModeIndex_310_1280x768[Depth];
-		}
 	     }
 	     break;
 	case 1360:
@@ -862,10 +806,14 @@ SiS_GetModeID_LCD(int VGAEngine, ULONG V
 	     else if(VDisplay == 240) ModeIndex = ModeIndex_320x240[Depth];
              break;
      	case 400:
-             if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
+	     if(LCDwidth >= 800 && LCDheight >= 600) {
+                if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
+	     }
              break;
 	case 512:
-	     if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
+	     if(LCDwidth >= 1024 && LCDheight >= 768 && LCDwidth != 1152) {
+	        if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
+	     }
 	     break;
 	case 640:
 	     if(VDisplay == 480)      ModeIndex = ModeIndex_640x480[Depth];
@@ -900,7 +848,8 @@ SiS_GetModeID_LCD(int VGAEngine, ULONG V
 	     break;
 	case 960:
 	     if(VGAEngine == SIS_315_VGA) {
-	        if(VDisplay == 540) ModeIndex = ModeIndex_960x540[Depth];
+	        if(VDisplay == 540)      ModeIndex = ModeIndex_960x540[Depth];
+		else if(VDisplay == 600) ModeIndex = ModeIndex_960x600[Depth];
 	     }
 	     break;
 	case 1024:
@@ -915,32 +864,27 @@ SiS_GetModeID_LCD(int VGAEngine, ULONG V
 	     }
 	     break;
 	case 1280:
-	     if(VDisplay == 1024) ModeIndex = ModeIndex_1280x1024[Depth];
-	     else if(VDisplay == 768) {
-		if((LCDheight == 768) ||  (LCDwidth == 1680) ||
-		   (VBFlags & VB_SISTMDS)) {
-		   if(VGAEngine == SIS_300_VGA) {
-		      ModeIndex = ModeIndex_300_1280x768[Depth];
-		   } else {
-		      ModeIndex = ModeIndex_310_1280x768[Depth];
-		   }
-		}
-	     } else if(VDisplay == 960) {
-	        if((LCDheight == 960) || (VBFlags & VB_SISTMDS)) {
-		   ModeIndex = ModeIndex_1280x960[Depth];
+	     switch(VDisplay) {
+	     case 720:
+	        ModeIndex = ModeIndex_1280x720[Depth];
+	     case 768:
+	        if(VGAEngine == SIS_300_VGA) {
+		   ModeIndex = ModeIndex_300_1280x768[Depth];
+		} else {
+		   ModeIndex = ModeIndex_310_1280x768[Depth];
 		}
-	     } else if(VGAEngine == SIS_315_VGA) {
-	        if(VDisplay == 800) {
-		   if((LCDheight == 800) || (LCDwidth == 1680) ||
-		      (VBFlags & VB_SISTMDS)) {
-		      ModeIndex = ModeIndex_1280x800[Depth];
-		   }
-		} else if(VDisplay == 720) {
-		   if((LCDheight == 720) || (LCDwidth == 1680) || (LCDwidth == 1400) ||
-		      (VBFlags & VB_SISTMDS)) {
-		      ModeIndex = ModeIndex_1280x720[Depth];
-		   }
+		break;
+	     case 800:
+	        if(VGAEngine == SIS_315_VGA) {
+		   ModeIndex = ModeIndex_1280x800[Depth];
 		}
+		break;
+	     case 960:
+	        ModeIndex = ModeIndex_1280x960[Depth];
+		break;
+	     case 1024:
+	        ModeIndex = ModeIndex_1280x1024[Depth];
+		break;
 	     }
 	     break;
 	case 1360:
@@ -950,27 +894,27 @@ SiS_GetModeID_LCD(int VGAEngine, ULONG V
 	     break;
 	case 1400:
 	     if(VGAEngine == SIS_315_VGA) {
-	        if(VBFlags & (VB_301B | VB_301C | VB_302B | VB_302LV | VB_302ELV)) {
-		   if((LCDwidth == 1400) || (LCDwidth == 1600) || (LCDwidth == 1680)) {
-		      ModeIndex = ModeIndex_1400x1050[Depth];
-		   }
+	        if(VBFlags & (VB_301C | VB_302LV | VB_302ELV)) {
+		   if(VDisplay == 1050) ModeIndex = ModeIndex_1400x1050[Depth];
 		}
 	     }
 	     break;
 	case 1600:
 	     if(VGAEngine == SIS_315_VGA) {
-	        if(VBFlags & (VB_301C | VB_302B | VB_302LV | VB_302ELV)) {
+	        if(VBFlags & (VB_301C | VB_302LV | VB_302ELV)) {
 	           if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
 		}
 	     }
 	     break;
+#ifndef VB_FORBID_CRT2LCD_OVER_1600
 	case 1680:
 	     if(VGAEngine == SIS_315_VGA) {
-	        if(VBFlags & (VB_301C | VB_302B | VB_302LV | VB_302ELV)) {
+	        if(VBFlags & (VB_301C | VB_302LV | VB_302ELV)) {
 	           if(VDisplay == 1050) ModeIndex = ModeIndex_1680x1050[Depth];
 		}
 	     }
 	     break;
+#endif
       }
    }
 
@@ -1030,8 +974,7 @@ SiS_GetModeID_TV(int VGAEngine, ULONG VB
 	case 720:
 	     if((!(VBFlags & TV_HIVISION)) && (!((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I)))) {
                 if(VDisplay == 480) {
-		   /* if((VBFlags & TV_YPBPR) || (VBFlags & (TV_NTSC | TV_PALM))) */
-                      ModeIndex = ModeIndex_720x480[Depth];
+                   ModeIndex = ModeIndex_720x480[Depth];
                 } else if(VDisplay == 576) {
 		   if( ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR750P)) ||
 		       ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL)) )
@@ -1055,6 +998,15 @@ SiS_GetModeID_TV(int VGAEngine, ULONG VB
 		}
 	     }
 	     break;
+	case 960:
+	     if(VGAEngine == SIS_315_VGA) {
+	        if(VDisplay == 600) {
+		   if((VBFlags & TV_HIVISION) || ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I))) {
+		      ModeIndex = ModeIndex_960x600[Depth];
+		   }
+		}
+	     }
+	     break;
 	case 1024:
 	     if(VDisplay == 768) {
 		if(VBFlags & (VB_301B|VB_301C|VB_302B|VB_301LV|VB_302LV|VB_302ELV)) {
@@ -1126,7 +1078,8 @@ SiS_GetModeID_VGA2(int VGAEngine, ULONG 
 		break;
 	case 960:
 		if(VGAEngine == SIS_315_VGA) {
-		   if(VDisplay == 540) ModeIndex = ModeIndex_960x540[Depth];
+		   if(VDisplay == 540)      ModeIndex = ModeIndex_960x540[Depth];
+		   else if(VDisplay == 600) ModeIndex = ModeIndex_960x600[Depth];
 		}
 		break;
 	case 1024:
@@ -1407,6 +1360,8 @@ SiSInitPCIetc(SiS_Private *SiS_Pr, PSIS_
    case SIS_741:
    case SIS_660:
    case SIS_760:
+   case SIS_761:
+   case SIS_340:
       SiS_SetReg(SiS_Pr->SiS_P3c4,0x20,0xa1);
       /*  - Enable 2D (0x40)
        *  - Enable 3D (0x02)
@@ -1477,6 +1432,8 @@ SiSSetLVDSetc(SiS_Private *SiS_Pr, PSIS_
    case SIS_741:
    case SIS_660:
    case SIS_760:
+   case SIS_761:
+   case SIS_340:
         temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
       	temp = (temp & 0xe0) >> 5;
       	if((temp >= 2) && (temp <= 3)) 	SiS_Pr->SiS_IF_DEF_LVDS = 1;
@@ -1515,7 +1472,10 @@ SiSDetermineROMLayout661(SiS_Private *Si
    UCHAR  *ROMAddr  = HwInfo->pjVirtualRomBase;
    USHORT romversoffs, romvmaj = 1, romvmin = 0;
 
-   if(HwInfo->jChipType >= SIS_661) {
+   if(HwInfo->jChipType >= SIS_761) {
+      /* I very much assume 761 and 340 will use new layout */
+      return TRUE;
+   } else if(HwInfo->jChipType >= SIS_661) {
       if((ROMAddr[0x1a] == 'N') &&
          (ROMAddr[0x1b] == 'e') &&
          (ROMAddr[0x1c] == 'w') &&
@@ -1569,14 +1529,21 @@ SiSDetermineROMUsage(SiS_Private *SiS_Pr
          /* 315/330 series stick to the standard(s) */
 	 SiS_Pr->SiS_UseROM = TRUE;
 	 if((SiS_Pr->SiS_ROMNew = SiSDetermineROMLayout661(SiS_Pr, HwInfo))) {
+	    SiS_Pr->SiS_EMIOffset = 14;
+	    SiS_Pr->SiS661LCD2TableSize = 36;
 	    /* Find out about LCD data table entry size */
 	    if((romptr = SISGETROMW(0x0102))) {
 	       if(ROMAddr[romptr + (32 * 16)] == 0xff)
 	          SiS_Pr->SiS661LCD2TableSize = 32;
 	       else if(ROMAddr[romptr + (34 * 16)] == 0xff)
 	          SiS_Pr->SiS661LCD2TableSize = 34;
-	       else if(ROMAddr[romptr + (36 * 16)] == 0xff)
-	          SiS_Pr->SiS661LCD2TableSize = 36;  /* 0.94 final */
+	       else if(ROMAddr[romptr + (36 * 16)] == 0xff)	   /* 0.94 */
+	          SiS_Pr->SiS661LCD2TableSize = 36;
+	       else if( (ROMAddr[romptr + (38 * 16)] == 0xff) ||   /* 2.00.00 - 2.02.00 */
+	       	 	(ROMAddr[0x6F] & 0x01) ) {		   /* 2.03.00+ */
+		  SiS_Pr->SiS661LCD2TableSize = 38;
+		  SiS_Pr->SiS_EMIOffset = 16;
+	       }
 	    }
 	 }
       }
@@ -1661,7 +1628,7 @@ SiS_ResetSegmentRegisters(SiS_Private *S
 void
 SiS_GetVBType(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
-  USHORT flag=0, rev=0, nolcd=0;
+  USHORT flag=0, rev=0, nolcd=0, p4_0f, p4_25, p4_27;
 
   SiS_Pr->SiS_VBType = 0;
 
@@ -1697,13 +1664,27 @@ SiS_GetVBType(SiS_Private *SiS_Pr, PSIS_
 	SiS_Pr->SiS_VBType = VB_SIS301LV;
      }
   }
+  if(SiS_Pr->SiS_VBType & (VB_301C | VB_301LV | VB_302LV | VB_302ELV)) {
+     p4_0f = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x0f);
+     p4_25 = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x25);
+     p4_27 = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x27);
+     SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0x7f);
+     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x25,0x08);
+     SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,0xfd);
+     if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x08) {
+        SiS_Pr->SiS_VBType |= VB_UMC;
+     }
+     SiS_SetReg(SiS_Pr->SiS_Part4Port,0x27,p4_27);
+     SiS_SetReg(SiS_Pr->SiS_Part4Port,0x25,p4_25);
+     SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0f,p4_0f);
+  }
 }
 
 /*********************************************/
 /*           HELPER: Check RAM size          */
 /*********************************************/
 
-#ifndef LINUX_XF86
+#ifdef LINUX_KERNEL
 static BOOLEAN
 SiS_CheckMemorySize(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
                     USHORT ModeNo, USHORT ModeIdIndex)
@@ -1743,7 +1724,10 @@ SiS_Get310DRAMType(SiS_Private *SiS_Pr, 
    if((*SiS_Pr->pSiS_SoftSetting) & SoftDRAMType) {
      data = (*SiS_Pr->pSiS_SoftSetting) & 0x03;
    } else {
-     if(HwInfo->jChipType >= SIS_661) {
+     if(HwInfo->jChipType >= SIS_340) {
+        /* TODO */
+	data = 0;
+     } if(HwInfo->jChipType >= SIS_661) {
         data = SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0x07;
 	if(SiS_Pr->SiS_ROMNew) {
 	   data = ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0xc0) >> 6);
@@ -1771,10 +1755,10 @@ SiS_Get310DRAMType(SiS_Private *SiS_Pr, 
    return data;
 }
 
-USHORT
+static USHORT
 SiS_GetMCLK(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
-  UCHAR  *ROMAddr  = HwInfo->pjVirtualRomBase;
+  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
   USHORT index;
 
   index = SiS_Get310DRAMType(SiS_Pr, HwInfo);
@@ -1796,26 +1780,26 @@ SiS_GetMCLK(SiS_Private *SiS_Pr, PSIS_HW
 /*           HELPER: ClearBuffer             */
 /*********************************************/
 
-#ifndef LINUX_XF86
+#ifdef LINUX_KERNEL
 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;
+  UCHAR SISIOMEMTYPE *VideoMemoryAddress = HwInfo->pjVideoMemoryAddress;
+  ULONG  AdapterMemorySize = HwInfo->ulVideoMemorySize;
+  USHORT SISIOMEMTYPE *pBuffer;
   int i;
 
   if(SiS_Pr->SiS_ModeType >= ModeEGA) {
      if(ModeNo > 0x13) {
         SiS_SetMemory(VideoMemoryAddress, AdapterMemorySize, 0);
      } else {
-        pBuffer = (USHORT *)VideoMemoryAddress;
-        for(i=0; i<0x4000; i++) pBuffer[i] = 0x0000;
+        pBuffer = (USHORT SISIOMEMTYPE *)VideoMemoryAddress;
+        for(i=0; i<0x4000; i++) writew(0x0000, &pBuffer[i]);
      }
   } else {
      if(SiS_Pr->SiS_ModeType < ModeCGA) {
-        pBuffer = (USHORT *)VideoMemoryAddress;
-        for(i=0; i<0x4000; i++) pBuffer[i] = 0x0720;
+        pBuffer = (USHORT SISIOMEMTYPE *)VideoMemoryAddress;
+        for(i=0; i<0x4000; i++) writew(0x0720, &pBuffer[i]);
      } else {
         SiS_SetMemory(VideoMemoryAddress, 0x8000, 0);
      }
@@ -1927,25 +1911,26 @@ SiS_SetLowModeTest(SiS_Private *SiS_Pr, 
 static void
 SiS_SetupCR5x(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
-   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,0x61,0xf7);
-	 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
-	 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
-	 if(!SiS_Pr->SiS_ROMNew) {
-	    SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x3a,0xef);
-	 }
-      }
-   }
+    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);
+       }
+    } else if(IS_SIS661741660760) {
+       SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x61,0xf7);
+       SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
+       SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
+       if(!SiS_Pr->SiS_ROMNew) {
+	  SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x3a,0xef);
+       }
+    }
 }
 
 static void
 SiS_HandleCRT1(SiS_Private *SiS_Pr)
 {
+  /* Enable CRT1 gating */
   SiS_SetRegAND(SiS_Pr->SiS_P3d4,SiS_Pr->SiS_MyCR63,0xbf);
 #if 0
   if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x15) & 0x01)) {
@@ -1978,7 +1963,7 @@ SiS_GetColorDepth(SiS_Private *SiS_Pr, U
     	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
   }
 
-  index = (modeflag & ModeInfoFlag) - ModeEGA;
+  index = (modeflag & ModeTypeMask) - ModeEGA;
   if(index < 0) index = 0;
   return(ColorDepth[index]);
 }
@@ -2736,7 +2721,7 @@ SiS_SetCRT1FIFO_630(SiS_Private *SiS_Pr,
      data2 = (data2 & 0xC0) >> 5;
      data2 <<= 8;
 
-#ifndef LINUX_XF86
+#ifdef LINUX_KERNEL
      SiS_SetRegLong(0xcf8,0x80000050);
      eax = SiS_GetRegLong(0xcfc);
      eax &= 0xfffff9ff;
@@ -2758,7 +2743,7 @@ SiS_SetCRT1FIFO_630(SiS_Private *SiS_Pr,
      data2 = (data2 & 0x0f00) | ((data2 & 0x3000) >> 8);
      data2 <<= 20;
 
-#ifndef LINUX_XF86
+#ifdef LINUX_KERNEL
      SiS_SetRegLong(0xcf8,0x800000A0);
      eax = SiS_GetRegLong(0xcfc);
      eax &= 0x00ffffff;
@@ -2777,7 +2762,7 @@ SiS_SetCRT1FIFO_630(SiS_Private *SiS_Pr,
      data2 = (data2 & 0xf0) >> 4;
      data2 <<= 24;
 
-#ifndef LINUX_XF86
+#ifdef LINUX_KERNEL
      SiS_SetRegLong(0xcf8,0x80000050);
      eax = SiS_GetRegLong(0xcfc);
      eax &= 0xf0ffffff;
@@ -2795,7 +2780,7 @@ SiS_SetCRT1FIFO_630(SiS_Private *SiS_Pr,
      data2 &= 0x0f;
      data2 <<= 24;
 
-#ifndef LINUX_XF86
+#ifdef LINUX_KERNEL
      SiS_SetRegLong(0xcf8,0x800000A0);
      eax = SiS_GetRegLong(0xcfc);
      eax &= 0xf0ffffff;
@@ -3079,6 +3064,8 @@ SiS_SetCRT1ModeRegs(SiS_Private *SiS_Pr,
 	}
      }
      SiS_SetReg(SiS_Pr->SiS_P3c4,0x17,data);
+  } else if(HwInfo->jChipType == SIS_340) {
+     /* TODO */
   }
 #endif
 
@@ -3327,7 +3314,7 @@ SiS_SetCRT1Group(SiS_Private *SiS_Pr, PS
 
   SiS_LoadDAC(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
 
-#ifndef LINUX_XF86
+#ifdef LINUX_KERNEL
   if(SiS_Pr->SiS_flag_clearbuffer) {
      SiS_ClearBuffer(SiS_Pr,HwInfo,ModeNo);
   }
@@ -3340,7 +3327,7 @@ SiS_SetCRT1Group(SiS_Private *SiS_Pr, PS
 }
 
 /*********************************************/
-/*         HELPER: RESET VIDEO BRIDGE        */
+/*       HELPER: VIDEO BRIDGE PROG CLK       */
 /*********************************************/
 
 static void
@@ -3349,17 +3336,16 @@ SiS_ResetVB(SiS_Private *SiS_Pr, PSIS_HW
    UCHAR  *ROMAddr  = HwInfo->pjVirtualRomBase;
    USHORT temp;
 
+   /* VB programming clock */
    if(SiS_Pr->SiS_UseROM) {
       if(HwInfo->jChipType < SIS_330) {
          temp = ROMAddr[VB310Data_1_2_Offset] | 0x40;
 	 if(SiS_Pr->SiS_ROMNew) temp = ROMAddr[0x80] | 0x40;
-         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp);
+	 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp);
       } else if(HwInfo->jChipType >= SIS_661) {
-         temp = ROMAddr[0x7e];
-         if(SiS_Pr->SiS_ROMNew) temp = ROMAddr[0x80];
-         if(HwInfo->jChipType >= SIS_660)                  temp |= 0x40;
-         else if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x7b) >= 100) temp |= 0x40;
-         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp);
+         temp = ROMAddr[0x7e] | 0x40;
+         if(SiS_Pr->SiS_ROMNew) temp = ROMAddr[0x80] | 0x40;
+	 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp);
       }
    }
 }
@@ -3453,7 +3439,7 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_
    USHORT  ModeIdIndex;
    SISIOADDRESS BaseAddr = HwInfo->ulIOAddress;
    unsigned char backupreg=0;
-#ifndef LINUX_XF86
+#ifdef LINUX_KERNEL
    USHORT  KeepLockReg;
    ULONG   temp;
 
@@ -3482,13 +3468,13 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_
    SiS_Pr->SiS_flag_clearbuffer = 0;
 
    if(!SiS_Pr->UseCustomMode) {
-#ifndef LINUX_XF86
+#ifdef LINUX_KERNEL
       if(!(ModeNo & 0x80)) SiS_Pr->SiS_flag_clearbuffer = 1;
 #endif
       ModeNo &= 0x7f;
    }
 
-#ifndef LINUX_XF86
+#ifdef LINUX_KERNEL
    KeepLockReg = SiS_GetReg(SiS_Pr->SiS_P3c4,0x05);
 #endif
    SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86);
@@ -3523,7 +3509,7 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_
    SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
    SiS_SetLowModeTest(SiS_Pr, ModeNo, HwInfo);
 
-#ifndef LINUX_XF86
+#ifdef LINUX_KERNEL
    /* 3. Check memory size (Kernel framebuffer driver only) */
    temp = SiS_CheckMemorySize(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
    if(!temp) return(0);
@@ -3612,7 +3598,7 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_
    }
 #endif
 
-#ifndef LINUX_XF86  /* We never lock registers in XF86 */
+#ifdef LINUX_KERNEL  /* 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
@@ -3630,27 +3616,28 @@ BOOLEAN
 SiSBIOSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
                DisplayModePtr mode, BOOLEAN IsCustom)
 {
-   SISPtr  pSiS = SISPTR(pScrn);
-   UShort  ModeNo=0;
+   SISPtr pSiS = SISPTR(pScrn);
+   UShort ModeNo = 0;
 
    SiS_Pr->UseCustomMode = FALSE;
 
    if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
 
-         xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting custom mode %dx%d\n",
+      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)));
 
-	 return(SiSSetMode(SiS_Pr, HwInfo, pScrn, ModeNo, TRUE));
+   } else {
 
-   }
+      /* Don't need vbflags here; checks done earlier */
+      ModeNo = SiS_GetModeNumber(pScrn, mode, 0);
+      if(!ModeNo) return FALSE;
 
-   ModeNo = SiS_CalcModeIndex(pScrn, mode, pSiS->VBFlags, pSiS->HaveCustomModes);
-   if(!ModeNo) return FALSE;
+      xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting standard mode 0x%x\n", ModeNo);
 
-   xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting standard mode 0x%x\n", ModeNo);
+   }
 
    return(SiSSetMode(SiS_Pr, HwInfo, pScrn, ModeNo, TRUE));
 }
@@ -3675,9 +3662,8 @@ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, 
    SiS_Pr->UseCustomMode = FALSE;
 
    /* Remember: Custom modes for CRT2 are ONLY supported
-    * 		-) on 315/330 series,
-    *           -) on the 30x/B/C, and
-    *           -) if CRT2 is LCD or VGA
+    *     -) on the 30x/B/C, and
+    *     -) if CRT2 is LCD or VGA, or CRT1 is LCDA
     */
 
    if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
@@ -3686,13 +3672,7 @@ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, 
 
    } else {
 
-         BOOLEAN havecustommodes = pSiS->HaveCustomModes;
-
-#ifdef SISMERGED
-	 if(pSiS->MergedFB) havecustommodes = pSiS->HaveCustomModes2;
-#endif
-
-         ModeNo = SiS_CalcModeIndex(pScrn, mode, pSiS->VBFlags, havecustommodes);
+         ModeNo = SiS_GetModeNumber(pScrn, mode, 0);
          if(!ModeNo) return FALSE;
 
    }
@@ -3731,7 +3711,7 @@ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, 
    }
 #endif
 
-   /* We don't clear the buffer under X */
+   /* We don't clear the buffer in X */
    SiS_Pr->SiS_flag_clearbuffer=0;
 
    if(SiS_Pr->UseCustomMode) {
@@ -3870,7 +3850,7 @@ SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, 
 
    } else {
 
-         ModeNo = SiS_CalcModeIndex(pScrn, mode, pSiS->VBFlags, pSiS->HaveCustomModes);
+         ModeNo = SiS_GetModeNumber(pScrn, mode, 0);
          if(!ModeNo) return FALSE;
 
          xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
@@ -3889,7 +3869,7 @@ SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, 
    SiSSetLVDSetc(SiS_Pr, HwInfo);
    SiSDetermineROMUsage(SiS_Pr, HwInfo);
 
-   /* We don't clear the buffer under X */
+   /* We don't clear the buffer in X */
    SiS_Pr->SiS_flag_clearbuffer = 0;
 
    SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86);
@@ -4267,18 +4247,12 @@ SiS_CalcLCDACRT1Timing(SiS_Private *SiS_
 #endif
 }
 
-/* ================ XFREE86 ================= */
-
-/* Helper functions */
-
 #ifdef LINUX_XF86
 
-USHORT
-SiS_CheckBuildCustomMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int VBFlags)
+void
+SiS_MakeClockRegs(ScrnInfoPtr pScrn, int clock, UCHAR *p2b, UCHAR *p2c)
 {
-   SISPtr pSiS = SISPTR(pScrn);
-   int    out_n, out_dn, out_div, out_sbit, out_scale;
-   int    depth = pSiS->CurrentLayout.bitsPerPixel;
+   int          out_n, out_dn, out_div, out_sbit, out_scale;
    unsigned int vclk[5];
 
 #define Midx         0
@@ -4287,6 +4261,50 @@ SiS_CheckBuildCustomMode(ScrnInfoPtr pSc
 #define Pidx         3
 #define PSNidx       4
 
+   if(SiS_compute_vclk(clock, &out_n, &out_dn, &out_div, &out_sbit, &out_scale)) {
+      (*p2b) = (out_div == 2) ? 0x80 : 0x00;
+      (*p2b) |= ((out_n - 1) & 0x7f);
+      (*p2c) = (out_dn - 1) & 0x1f;
+      (*p2c) |= (((out_scale - 1) & 3) << 5);
+      (*p2c) |= ((out_sbit & 0x01) << 7);
+#ifdef TWDEBUG
+      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clock %d: n %d dn %d div %d sb %d sc %d\n",
+        	 clock, out_n, out_dn, out_div, out_sbit, out_scale);
+#endif
+   } else {
+      SiSCalcClock(pScrn, clock, 2, vclk);
+      (*p2b) = (vclk[VLDidx] == 2) ? 0x80 : 0x00;
+      (*p2b) |= (vclk[Midx] - 1) & 0x7f;
+      (*p2c) = (vclk[Nidx] - 1) & 0x1f;
+      if(vclk[Pidx] <= 4) {
+         /* postscale 1,2,3,4 */
+         (*p2c) |= ((vclk[Pidx] - 1) & 3) << 5;
+      } else {
+         /* postscale 6,8 */
+         (*p2c) |= (((vclk[Pidx] / 2) - 1) & 3) << 5;
+	 (*p2c) |= 0x80;
+      }
+#ifdef TWDEBUG
+      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clock %d: n %d dn %d div %d sc %d\n",
+        	 clock, vclk[Midx], vclk[Nidx], vclk[VLDidx], vclk[Pidx]);
+#endif
+   }
+}
+
+#endif
+
+/* ================ XFREE86/X.ORG ================= */
+
+/* Helper functions */
+
+#ifdef LINUX_XF86
+
+USHORT
+SiS_CheckBuildCustomMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int VBFlags)
+{
+   SISPtr pSiS = SISPTR(pScrn);
+   int    depth = pSiS->CurrentLayout.bitsPerPixel;
+
    pSiS->SiS_Pr->CModeFlag = 0;
    
    pSiS->SiS_Pr->CDClock = mode->Clock;
@@ -4322,34 +4340,7 @@ SiS_CheckBuildCustomMode(ScrnInfoPtr pSc
    pSiS->SiS_Pr->CVBlankStart = pSiS->SiS_Pr->CVSyncStart - 1;
    pSiS->SiS_Pr->CVBlankEnd = pSiS->SiS_Pr->CVTotal;
 
-   if(SiS_compute_vclk(pSiS->SiS_Pr->CDClock, &out_n, &out_dn, &out_div, &out_sbit, &out_scale)) {
-      pSiS->SiS_Pr->CSR2B = (out_div == 2) ? 0x80 : 0x00;
-      pSiS->SiS_Pr->CSR2B |= ((out_n - 1) & 0x7f);
-      pSiS->SiS_Pr->CSR2C = (out_dn - 1) & 0x1f;
-      pSiS->SiS_Pr->CSR2C |= (((out_scale - 1) & 3) << 5);
-      pSiS->SiS_Pr->CSR2C |= ((out_sbit & 0x01) << 7);
-#ifdef TWDEBUG
-      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clock %d: n %d dn %d div %d sb %d sc %d\n",
-        	pSiS->SiS_Pr->CDClock, out_n, out_dn, out_div, out_sbit, out_scale);
-#endif
-   } else {
-      SiSCalcClock(pScrn, pSiS->SiS_Pr->CDClock, 2, vclk);
-      pSiS->SiS_Pr->CSR2B = (vclk[VLDidx] == 2) ? 0x80 : 0x00;
-      pSiS->SiS_Pr->CSR2B |= (vclk[Midx] - 1) & 0x7f;
-      pSiS->SiS_Pr->CSR2C = (vclk[Nidx] - 1) & 0x1f;
-      if(vclk[Pidx] <= 4) {
-         /* postscale 1,2,3,4 */
-         pSiS->SiS_Pr->CSR2C |= ((vclk[Pidx] - 1) & 3) << 5;
-      } else {
-         /* postscale 6,8 */
-         pSiS->SiS_Pr->CSR2C |= (((vclk[Pidx] / 2) - 1) & 3) << 5;
-	 pSiS->SiS_Pr->CSR2C |= 0x80;
-      }
-#ifdef TWDEBUG
-      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clock %d: n %d dn %d div %d sc %d\n",
-        	pSiS->SiS_Pr->CDClock, vclk[Midx], vclk[Nidx], vclk[VLDidx], vclk[Pidx]);
-#endif
-   }
+   SiS_MakeClockRegs(pScrn, pSiS->SiS_Pr->CDClock, &pSiS->SiS_Pr->CSR2B, &pSiS->SiS_Pr->CSR2C);
 
    pSiS->SiS_Pr->CSRClock = (pSiS->SiS_Pr->CDClock / 1000) + 1;
 
@@ -4407,7 +4398,41 @@ SiS_CheckBuildCustomMode(ScrnInfoPtr pSc
    return 1;
 }
 
-/* Build a list of supported modes */
+int
+SiS_FindPanelFromDB(SISPtr pSiS, USHORT panelvendor, USHORT panelproduct, int *maxx, int *maxy, int *prefx, int *prefy)
+{
+   int i, j;
+   BOOLEAN done = FALSE;
+
+   i = 0;
+   while((!done) && (SiS_PlasmaTable[i].vendor) && panelvendor) {
+      if(SiS_PlasmaTable[i].vendor == panelvendor) {
+         for(j=0; j<SiS_PlasmaTable[i].productnum; j++) {
+	    if(SiS_PlasmaTable[i].product[j] == panelproduct) {
+	       if(SiS_PlasmaTable[i].maxx && SiS_PlasmaTable[i].maxy) {
+	          (*maxx) = (int)SiS_PlasmaTable[i].maxx;
+		  (*maxy) = (int)SiS_PlasmaTable[i].maxy;
+		  (*prefx) = (int)SiS_PlasmaTable[i].prefx;
+		  (*prefy) = (int)SiS_PlasmaTable[i].prefy;
+		  done = TRUE;
+		  xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
+	       	        "Identified %s, correcting max X res %d, max Y res %d\n",
+			 SiS_PlasmaTable[i].plasmaname,
+		         SiS_PlasmaTable[i].maxx, SiS_PlasmaTable[i].maxy);
+	          break;
+	       }
+ 	    }
+	 }
+      }
+      i++;
+   }
+   return (done) ? 1 : 0;
+}
+
+/* Build a list of supported modes:
+ * Built-in modes for which we have all data are M_T_DEFAULT,
+ * modes derived from DDC or database data are M_T_BUILTIN
+ */
 DisplayModePtr
 SiSBuildBuiltInModeList(ScrnInfoPtr pScrn, BOOLEAN includelcdmodes, BOOLEAN isfordvi)
 {
@@ -4717,27 +4742,6 @@ SiSBuildBuiltInModeList(ScrnInfoPtr pScr
 	 current->VTotal >>= 1;
       }
 
-#if 0
-      if((backup = xalloc(sizeof(DisplayModeRec)))) {
-         if(!pSiS->backupmodelist) pSiS->backupmodelist = backup;
-	 else {
-	    pSiS->backupmodelist->next = backup;
-	    backup->prev = pSiS->backupmodelist;
-	 }
-	 backup->next = NULL;
-	 backup->HDisplay = current->HDisplay;
-         backup->HSyncStart = current->HSyncStart;
-         backup->HSyncEnd = current->HSyncEnd;
-         backup->HTotal = current->HTotal;
-         backup->VDisplay = current->VDisplay;
-         backup->VSyncStart = current->VSyncStart;
-         backup->VSyncEnd = current->VSyncEnd;
-         backup->VTotal = current->VTotal;
-	 backup->Flags = current->Flags;
-	 backup->Clock = current->Clock;
-      }
-#endif
-
 #ifdef TWDEBUG
       xf86DrvMsg(pScrn->scrnIndex, X_INFO,
       	"Built-in: %s %.2f %d %d %d %d %d %d %d %d\n",
@@ -4781,10 +4785,18 @@ SiSBuildBuiltInModeList(ScrnInfoPtr pScr
 		     if(!(SiS_PlasmaTable[i].plasmamodes[k] & 0x40)) continue;
 		  }
 
+		  l = SiS_PlasmaTable[i].plasmamodes[k] & 0x3f;
+
+		  if(pSiS->VBFlags & (VB_301|VB_301B|VB_302B|VB_301LV)) {
+		     if(isfordvi) {
+		        if(SiS_PlasmaMode[l].VDisplay > 1024) continue;
+		     }
+		  }
+
 	          if(!(new = xalloc(sizeof(DisplayModeRec)))) return first;
 
                   memset(new, 0, sizeof(DisplayModeRec));
-                  if(!(new->name = xalloc(10))) {
+                  if(!(new->name = xalloc(12))) {
       		     xfree(new);
 		     return first;
                   }
@@ -4798,10 +4810,9 @@ SiSBuildBuiltInModeList(ScrnInfoPtr pScr
 
 		  pSiS->AddedPlasmaModes = TRUE;
 
-		  l = SiS_PlasmaTable[i].plasmamodes[k] & 0x3f;
-
-	          sprintf(current->name, "%dx%d", SiS_PlasmaMode[l].HDisplay,
-                                                  SiS_PlasmaMode[l].VDisplay);
+		  strcpy(current->name, SiS_PlasmaMode[l].name);
+	          /* sprintf(current->name, "%dx%d", SiS_PlasmaMode[l].HDisplay,
+                                                  SiS_PlasmaMode[l].VDisplay); */
 
                   current->status = MODE_OK;
 
@@ -4849,6 +4860,9 @@ SiSBuildBuiltInModeList(ScrnInfoPtr pScr
 	          if(current->VDisplay > pSiS->LCDheight)
 		     pSiS->LCDheight = pSiS->SiS_Pr->CP_MaxY = current->VDisplay;
 
+		  xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+		  	"\tAdding \"%s\" to list of built-in modes\n", current->name);
+
                }
 	       done = TRUE;
 	       break;
@@ -4938,12 +4952,12 @@ SiSBuildBuiltInModeList(ScrnInfoPtr pScr
 
 }
 
-/* Build a list of supported modes */
+/* Translate a mode number into the VESA pendant */
 int
 SiSTranslateToVESA(ScrnInfoPtr pScrn, int modenumber)
 {
-   SISPtr         pSiS = SISPTR(pScrn);
-   int i;
+   SISPtr pSiS = SISPTR(pScrn);
+   int    i = 0;
 
    /* Initialize our pointers */
    if(pSiS->VGAEngine == SIS_300_VGA) {
@@ -4962,15 +4976,48 @@ SiSTranslateToVESA(ScrnInfoPtr pScrn, in
 
    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;
+#ifdef SIS315H
+   if(pSiS->ROM661New) {
+      while(SiS_EModeIDTable661[i].Ext_ModeID != 0xff) {
+         if(SiS_EModeIDTable661[i].Ext_ModeID == modenumber) {
+            return (int)SiS_EModeIDTable661[i].Ext_VESAID;
+         }
+         i++;
       }
-      i++;
+   } else {
+#endif
+      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++;
+      }
+#ifdef SIS315H
    }
+#endif
    return -1;
 }
+
+/* Translate a new BIOS mode number into the driver's pendant */
+int
+SiSTranslateToOldMode(int modenumber)
+{
+#ifdef SIS315H
+   int    i = 0;
+
+   while(SiS_EModeIDTable661[i].Ext_ModeID != 0xff) {
+      if(SiS_EModeIDTable661[i].Ext_ModeID == modenumber) {
+         if(SiS_EModeIDTable661[i].Ext_MyModeID)
+            return (int)SiS_EModeIDTable661[i].Ext_MyModeID;
+	 else
+	    return modenumber;
+      }
+      i++;
+   }
+#endif
+   return modenumber;
+}
+
 #endif  /* Xfree86 */
 
 #ifdef LINUX_KERNEL
diff -puN drivers/video/sis/initdef.h~fbdev-sis-framebuffer-driver-update-1717 drivers/video/sis/initdef.h
--- 25/drivers/video/sis/initdef.h~fbdev-sis-framebuffer-driver-update-1717	2004-11-28 01:30:58.863561760 -0800
+++ 25-akpm/drivers/video/sis/initdef.h	2004-11-28 01:30:58.936550664 -0800
@@ -35,7 +35,7 @@
  * * 3) 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 EXPRESSED OR
+ * * 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,
@@ -80,6 +80,7 @@
 #define VB_SIS302LV     	0x0010
 #define VB_SIS302ELV		0x0020
 #define VB_SIS301C              0x0040
+#define VB_UMC			0x4000
 #define VB_NoLCD        	0x8000
 #define VB_SIS301BLV302BLV      (VB_SIS301B|VB_SIS301C|VB_SIS302B|VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)
 #define VB_SIS301B302B          (VB_SIS301B|VB_SIS301C|VB_SIS302B)
@@ -87,6 +88,9 @@
 #define VB_SISVB		(VB_SIS301 | VB_SIS301BLV302BLV)
 #define VB_SISTMDS		(VB_SIS301 | VB_SIS301B302B)
 #define VB_SISLVDS		VB_SIS301LV302LV
+#define VB_SISLCDA		(VB_SIS302B|VB_SIS301C|VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)
+#define VB_SISYPBPR		(VB_SIS301C|VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)
+#define VB_SISHIVISION		(VB_SIS301|VB_SIS301B|VB_SIS302B)
 
 /* VBInfo */
 #define SetSimuScanMode         0x0001   /* CR 30 */
@@ -126,7 +130,7 @@
 #define Mode24Bpp               0x06
 #define Mode32Bpp               0x07
 
-#define ModeInfoFlag            0x07
+#define ModeTypeMask            0x07
 #define IsTextMode              0x07
 
 #define DACInfoFlag             0x0018
@@ -139,7 +143,7 @@
 #define CRT2Mode                0x0800
 #define HalfDCLK                0x1000
 #define NoSupportSimuTV         0x2000
-#define NoSupportLCDScale	0x4000 /* TMDS: No scaling possible (no matter what panel) */
+#define NoSupportLCDScale	0x4000 /* SiS bridge: No scaling possible (no matter what panel) */
 #define DoubleScanMode          0x8000
 
 /* Infoflag */
@@ -402,17 +406,18 @@
 #define Panel_1400x1050         0x09
 #define Panel_1280x768          0x0a    /* 30xB/C and LVDS only (BIOS: all) */
 #define Panel_1600x1200         0x0b
-#define Panel_1280x800		0x0c    /* 661etc  */
+#define Panel_1280x800		0x0c    /* 661etc (TMDS) */
 #define Panel_1680x1050         0x0d    /* 661etc  */
 #define Panel_1280x720		0x0e    /* 661etc  */
-#define Panel_Custom		0x0f	/* MUST BE 0x0f (for DVI DDC detection */
+#define Panel_Custom		0x0f	/* MUST BE 0x0f (for DVI DDC detection) */
 #define Panel_320x480           0x10    /* SiS 550 fstn - TW: This is fake, can be any */
 #define Panel_Barco1366         0x11
 #define Panel_848x480		0x12
 #define Panel_640x480_2		0x13    /* SiS 550 */
 #define Panel_640x480_3		0x14    /* SiS 550 */
 #define Panel_1280x768_2        0x15	/* 30xLV */
-#define Panel_1280x768_3        0x16    /* 30xLV */
+#define Panel_1280x768_3        0x16    /* (unused) */
+#define Panel_1280x800_2	0x17    /* 30xLV */
 
 /* Index in ModeResInfo table */
 #define SIS_RI_320x200    0
@@ -448,6 +453,7 @@
 #define SIS_RI_1280x800  30
 #define SIS_RI_1920x1080 31
 #define SIS_RI_960x540   32
+#define SIS_RI_960x600   33
 
 /* CR5F */
 #define IsM650                  0x80
@@ -475,7 +481,7 @@
 #define VCLK108_3_300           0x42   /* Index in VCLKData table (300) */
 #define VCLK100_300             0x43   /* Index in VCLKData table (300) */
 #define VCLK34_300              0x3d   /* Index in VCLKData table (300) */
-#define VCLK_CUSTOM_300		0x46
+#define VCLK_CUSTOM_300		0x47
 #define VCLK65_315              0x0b   /* Index in (VB)VCLKData table (315) */
 #define VCLK108_2_315           0x19   /* Index in (VB)VCLKData table (315) */
 #define VCLK81_315		0x5b   /* Index in (VB)VCLKData table (315) */
@@ -484,12 +490,11 @@
 #define VCLK100_315             0x46   /* Index in VBVCLKData table (315) */
 #define VCLK34_315              0x55
 #define VCLK68_315		0x0d
-#define VCLK69_315		0x5c   /* deprecated ! Index in VBVCLKData table (315) */
-#define VCLK83_315		0x5c   /* Index in VBVCLKData table (315) */
+#define VCLK_1280x800_315_2	0x5c   /* Index in VBVCLKData table (315) */
 #define VCLK121_315		0x5d   /* Index in VBVCLKData table (315) */
 #define VCLK_1280x720		0x5f
 #define VCLK_1280x768_2		0x60
-#define VCLK_1280x768_3		0x61
+#define VCLK_1280x768_3		0x61   /* (unused?) */
 #define VCLK_CUSTOM_315		0x62
 #define VCLK_1280x720_2		0x63
 #define VCLK_720x480		0x67
@@ -501,6 +506,7 @@
 #define VCLK_1024x576		0x51
 #define VCLK_1152x864		0x64
 #define VCLK_1360x768		0x58
+#define VCLK_1280x800_315	0x6c
 
 #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) */
diff -puN drivers/video/sis/init.h~fbdev-sis-framebuffer-driver-update-1717 drivers/video/sis/init.h
--- 25/drivers/video/sis/init.h~fbdev-sis-framebuffer-driver-update-1717	2004-11-28 01:30:58.865561456 -0800
+++ 25-akpm/drivers/video/sis/init.h	2004-11-28 01:30:58.945549296 -0800
@@ -35,7 +35,7 @@
  * * 3) 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 EXPRESSED OR
+ * * 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,
@@ -54,21 +54,16 @@
 #define _INIT_
 
 #include "osdef.h"
-
 #include "initdef.h"
-#include "vgatypes.h"
-#include "vstruct.h"
 
 #ifdef LINUX_XF86
-#include "xf86.h"
-#include "xf86Pci.h"
-#include "xf86PciInfo.h"
-#include "xf86_OSproc.h"
 #include "sis.h"
 #include "sis_regs.h"
 #endif
 
 #ifdef LINUX_KERNEL
+#include "vgatypes.h"
+#include "vstruct.h"
 #ifdef SIS_CP
 #undef SIS_CP
 #endif
@@ -85,43 +80,44 @@
 #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_960x540[]      = {0x1d, 0x1e, 0x00, 0x1f};  /* 315 series only */
-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_1280x800[]     = {0x14, 0x15, 0x00, 0x16};
-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_1680x1050[]    = {0x17, 0x18, 0x00, 0x19};  /* 315 series only */
-const USHORT  ModeIndex_1600x1200[]    = {0x3c, 0x3d, 0x00, 0x66};
-const USHORT  ModeIndex_1920x1080[]    = {0x2c, 0x2d, 0x00, 0x73};  /* 315 series only */
-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};
+static const USHORT ModeIndex_320x200[]      = {0x59, 0x41, 0x00, 0x4f};
+static const USHORT ModeIndex_320x240[]      = {0x50, 0x56, 0x00, 0x53};
+static const USHORT ModeIndex_320x240_FSTN[] = {0x5a, 0x5b, 0x00, 0x00};  /* FSTN */
+static const USHORT ModeIndex_400x300[]      = {0x51, 0x57, 0x00, 0x54};
+static const USHORT ModeIndex_512x384[]      = {0x52, 0x58, 0x00, 0x5c};
+static const USHORT ModeIndex_640x400[]      = {0x2f, 0x5d, 0x00, 0x5e};
+static const USHORT ModeIndex_640x480[]      = {0x2e, 0x44, 0x00, 0x62};
+static const USHORT ModeIndex_720x480[]      = {0x31, 0x33, 0x00, 0x35};
+static const USHORT ModeIndex_720x576[]      = {0x32, 0x34, 0x00, 0x36};
+static const USHORT ModeIndex_768x576[]      = {0x5f, 0x60, 0x00, 0x61};
+static const USHORT ModeIndex_800x480[]      = {0x70, 0x7a, 0x00, 0x76};
+static const USHORT ModeIndex_800x600[]      = {0x30, 0x47, 0x00, 0x63};
+static const USHORT ModeIndex_848x480[]      = {0x39, 0x3b, 0x00, 0x3e};
+static const USHORT ModeIndex_856x480[]      = {0x3f, 0x42, 0x00, 0x45};
+static const USHORT ModeIndex_960x540[]      = {0x1d, 0x1e, 0x00, 0x1f};  /* 315 series only */
+static const USHORT ModeIndex_960x600[]      = {0x20, 0x21, 0x00, 0x22};  /* 315 series only */
+static const USHORT ModeIndex_1024x768[]     = {0x38, 0x4a, 0x00, 0x64};
+static const USHORT ModeIndex_1024x576[]     = {0x71, 0x74, 0x00, 0x77};
+static const USHORT ModeIndex_1024x600[]     = {0x20, 0x21, 0x00, 0x22};  /* 300 series only */
+static const USHORT ModeIndex_1280x1024[]    = {0x3a, 0x4d, 0x00, 0x65};
+static const USHORT ModeIndex_1280x960[]     = {0x7c, 0x7d, 0x00, 0x7e};
+static const USHORT ModeIndex_1152x768[]     = {0x23, 0x24, 0x00, 0x25};  /* 300 series only */
+static const USHORT ModeIndex_1152x864[]     = {0x29, 0x2a, 0x00, 0x2b};
+static const USHORT ModeIndex_300_1280x768[] = {0x55, 0x5a, 0x00, 0x5b};
+static const USHORT ModeIndex_310_1280x768[] = {0x23, 0x24, 0x00, 0x25};
+static const USHORT ModeIndex_1280x720[]     = {0x79, 0x75, 0x00, 0x78};
+static const USHORT ModeIndex_1280x800[]     = {0x14, 0x15, 0x00, 0x16};
+static const USHORT ModeIndex_1360x768[]     = {0x48, 0x4b, 0x00, 0x4e};
+static const USHORT ModeIndex_300_1360x1024[]= {0x67, 0x6f, 0x00, 0x72};  /* 300 series, BARCO only */
+static const USHORT ModeIndex_1400x1050[]    = {0x26, 0x27, 0x00, 0x28};  /* 315 series only */
+static const USHORT ModeIndex_1680x1050[]    = {0x17, 0x18, 0x00, 0x19};  /* 315 series only */
+static const USHORT ModeIndex_1600x1200[]    = {0x3c, 0x3d, 0x00, 0x66};
+static const USHORT ModeIndex_1920x1080[]    = {0x2c, 0x2d, 0x00, 0x73};  /* 315 series only */
+static const USHORT ModeIndex_1920x1440[]    = {0x68, 0x69, 0x00, 0x6b};
+static const USHORT ModeIndex_300_2048x1536[]= {0x6c, 0x6d, 0x00, 0x00};
+static const USHORT ModeIndex_310_2048x1536[]= {0x6c, 0x6d, 0x00, 0x6e};
 
-const USHORT SiS_DRAMType[17][5]={
+static const USHORT SiS_DRAMType[17][5]={
 	{0x0C,0x0A,0x02,0x40,0x39},
 	{0x0D,0x0A,0x01,0x40,0x48},
 	{0x0C,0x09,0x02,0x20,0x35},
@@ -141,7 +137,7 @@ const USHORT SiS_DRAMType[17][5]={
 	{0x09,0x08,0x01,0x01,0x00}
 };
 
-const USHORT SiS_SDRDRAM_TYPE[13][5] =
+static const USHORT SiS_SDRDRAM_TYPE[13][5] =
 {
 	{ 2,12, 9,64,0x35},
 	{ 1,13, 9,64,0x44},
@@ -158,7 +154,7 @@ const USHORT SiS_SDRDRAM_TYPE[13][5] =
 	{ 1, 9, 8, 2,0x00}
 };
 
-const USHORT SiS_DDRDRAM_TYPE[4][5] =
+static const USHORT SiS_DDRDRAM_TYPE[4][5] =
 {
 	{ 2,12, 9,64,0x35},
 	{ 2,12, 8,32,0x31},
@@ -166,7 +162,7 @@ const USHORT SiS_DDRDRAM_TYPE[4][5] =
 	{ 2, 9, 8, 4,0x01}
 };
 
-const USHORT SiS_MDA_DAC[] =
+static const USHORT SiS_MDA_DAC[] =
 {
 	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
         0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
@@ -178,7 +174,7 @@ const USHORT SiS_MDA_DAC[] =
         0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F
 };
 
-const USHORT SiS_CGA_DAC[] =
+static const USHORT SiS_CGA_DAC[] =
 {
         0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
         0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
@@ -190,7 +186,7 @@ const USHORT SiS_CGA_DAC[] =
         0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F
 };
 
-const USHORT SiS_EGA_DAC[] =
+static const USHORT SiS_EGA_DAC[] =
 {
         0x00,0x10,0x04,0x14,0x01,0x11,0x05,0x15,
         0x20,0x30,0x24,0x34,0x21,0x31,0x25,0x35,
@@ -202,7 +198,7 @@ const USHORT SiS_EGA_DAC[] =
         0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F
 };
 
-const USHORT SiS_VGA_DAC[] =
+static const USHORT SiS_VGA_DAC[] =
 {
 	0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
 	0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F,
@@ -259,11 +255,12 @@ static const SiS_ModeResInfoStruct SiS_M
 	{ 1680,1050, 8,16},   /* 0x1d */
 	{ 1280, 800, 8,16},   /* 0x1e */
 	{ 1920,1080, 8,16},   /* 0x1f */
-	{  960, 540, 8,16}    /* 0x20 */
+	{  960, 540, 8,16},   /* 0x20 */
+	{  960, 600, 8,16}    /* 0x21 */
 };
 
 #if defined(SIS300) || defined(SIS315H)
-static SiS_StandTableStruct SiS_StandTable[]=
+static const SiS_StandTableStruct SiS_StandTable[]=
 {
 /* 0x00: MD_0_200 */
  {
@@ -907,7 +904,8 @@ static const SiS_TVDataStruct  SiS_ExtHi
  {    5,   4, 0x627,0x464,0x670,0x3c0,0x128,  0, 0, 0x00,0x00,0x00,0x00},  /* 1280x1024 */
  {    4,   1, 0x41a,0x233,0x60c,0x3c0,0x143,128, 0, 0x00,0x00,0x00,0x00},  /* 800x480   */
  {    5,   2, 0x578,0x293,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},  /* 1024x576  */
- {    8,   5, 0x6d6,0x323,0x670,0x3c0,0x128,  0, 0, 0x00,0x00,0x00,0x00}   /* 1280x720  */
+ {    8,   5, 0x6d6,0x323,0x670,0x3c0,0x128,  0, 0, 0x00,0x00,0x00,0x00},  /* 1280x720  */
+ {  137,  32, 0x3d4,0x233,0x663,0x3bf,0x143,  0, 0, 0x00,0x00,0x00,0x00}   /* 960x600  */
 };
 
 static const SiS_TVDataStruct  SiS_St525pData[] =
@@ -930,67 +928,41 @@ static const SiS_TVDataStruct  SiS_St750
 
 static const SiS_TVDataStruct  SiS_Ext750pData[] =
 {
-#if 1
  {  143,  65, 0x35a,0x1bb,0x4f6,0x1b8,0x0ab,  0, 0x0ab, 0x00,0x00,0x00,0x00},
  {   88,  35, 0x35a,0x189,0x4f6,0x1b8,0x0ab,  0, 0x0ab, 0x00,0x00,0x00,0x00},
  {   18,   5, 0x339,0x1ae,0x500,0x2d0,0x05c,  0, 0x05c, 0x00,0x00,0x00,0x00},
  {  143,  70, 0x39c,0x189,0x4f6,0x1b8,0x05c,  0, 0x05c, 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  */
-#if 0
- {    2,   1, 0x35a,0x1f7,0x4f6,0x1e0,    0,128,     0, 0x00,0x00,0x00,0x00},  /* 720x480  */
-#endif
  {   99,  32, 0x320,0x1fe,0x500,0x2d0,   50,  0,     0, 0x00,0x00,0x00,0x00},  /* 720x480 test WORKS */
  {   68,  64, 0x55f,0x346,0x500,0x2a8,0x27e,  0,     0, 0x00,0x00,0x00,0x00},  /* 1024x768 */
  {    5,   2, 0x3a7,0x226,0x500,0x2a8,    0,128,     0, 0x00,0x00,0x00,0x00},  /* 720x576  */
  {   25,  24, 0x5d8,0x2f3,0x460,0x2a8,   50,  0,     0, 0x00,0x00,0x00,0x00}   /* 1280x720 WORKS */
-#endif
-#if 0
- {    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  */
- {   25,  24, 0x5d8,0x2f3,0x460,0x2a8,   50,  0,     0, 0x00,0x00,0x00,0x00}   /* 1280x720  */
-#endif
-#if 0
- {  136,  35, 0x339,0x181,0x460,0x2a8,   50,  0,     0, 0x00,0x00,0x00,0x00},  /* TEST (0.93) BAD */
- {   17,   6, 0x339,0x203,0x460,0x2a8,   50,  0,    50, 0x00,0x00,0x00,0x00},
- {  136,  35, 0x339,0x181,0x460,0x2a8,   50,  0,    50, 0x00,0x00,0x00,0x00},
- {   17,   6, 0x339,0x203,0x460,0x2a8,   50,  0,    50, 0x00,0x00,0x00,0x00},
- {   85,  46, 0x3f4,0x27b,0x460,0x2a8,   50,  0,     0, 0x00,0x00,0x00,0x00},  /* 640x480   */
- {   17,  16, 0x55f,0x323,0x460,0x2a8,0x2b6,  0,     0, 0x00,0x00,0x00,0x00},  /* 800x600   */
- {  136,  35, 0x339,0x181,0x460,0x2a8,   50,  0,     0, 0x00,0x00,0x00,0x00},  /* 720x480   */
- {  187,  74, 0x39d,0x203,0x460,0x2a8,   50,  0,     0, 0x00,0x00,0x00,0x00},  /* 1024x768  */
- {   25,  24, 0x5d8,0x2f3,0x460,0x2a8,   50,  0,    50, 0x00,0x00,0x00,0x00}   /* 1280x720  */
-#endif
 };
 
-static const SiS_LCDDataStruct  SiS_LCD1280x720Data[] =
+static const SiS_LCDDataStruct  SiS_LCD1280x720Data[] =  /* 2.03.00 */
 {
-	{  14,    5,  864,  432, 1344,  806 }, /* 640x400 */
-	{  16,    5,  864,  378, 1344,  806 },
-	{  14,    5,  864,  432, 1344,  806 },
-	{  16,    5,  864,  378, 1344,  806 },
-	{  24,   11,  924,  523, 1344,  806 }, /* 640x480 */
-	{   7,    5, 1152,  664, 1344,  806 }, /* 800x600 */
-	{   0,    0,    0,    0,    0,    0 },
+	{  44,   15,  864,  430, 1408,  806 }, /* 640x400 */
+	{ 128,   35,  792,  385, 1408,  806 },
+	{  44,   15,  864,  430, 1408,  806 },
+	{ 128,   35,  792,  385, 1408,  806 },
+	{  22,    9,  864,  516, 1408,  806 }, /* 640x480 */
+	{   8,    5, 1056,  655, 1408,  806 }, /* 800x600 */
+	{   0,    0,    0,    0,    0,    0 }, /* 1024x768 */
+	{   0,    0,    0,    0,    0,    0 }, /* 1280x1024 */
 	{   0,    0,    0,    0,    0,    0 },
 	{   0,    0,    0,    0,    0,    0 },
-	{   0,    0,    0,    0,    0,    0 },
-	{   1,    1, 1344,  806, 1344,  806 }  /* 1280x720 */
+	{   1,    1, 1408,  806, 1408,  806 }  /* 1280x720 */
 };
 
 /* About 1280x768: For TMDS, Panel_1280x768 will only be set if
  * the panel is a Fujitsu 7911 (VL-17WDX8) (with clock 81, 1688x802)
  * Other TMDS panels of this resolution will be treated as custom.
- * For LVDS, we know two types. Data follows:
+ * For LVDS, we know another type (_2).
+ * (Note: 1280x768_3 is now special for SiS301/NetVista
  */
 
-static const SiS_LCDDataStruct  SiS_StLCD1280x768_2Data[] =
+static const SiS_LCDDataStruct  SiS_StLCD1280x768_2Data[] = /* 2.03.00 */
 {
 	{  64,   21,  858,  434, 1408,  806 }, /* 640x400 */
 	{  32,    9,  858,  372, 1408,  806 },
@@ -1000,22 +972,27 @@ static const SiS_LCDDataStruct  SiS_StLC
 	{  64,   51, 1364,  663, 1408,  806 }, /* 800x600 */
 	{  88,   81, 1296,  806, 1408,  806 }, /* 1024x768 */
 	{   0,    0,    0,    0,    0,    0 },
-	{   1,    1, 1408,  806, 1408,  806 }  /* 1280x768 */
+	{   1,    1, 1408,  806, 1408,  806 }, /* 1280x768 */
+	{   0,    0,    0,    0,    0,    0 },
+	{  16,   15, 1600,  750, 1600,  806 }  /* 1280x720 - from Ext */
 };
 
-static const SiS_LCDDataStruct  SiS_ExtLCD1280x768_2Data[] =
+static const SiS_LCDDataStruct  SiS_ExtLCD1280x768_2Data[] = /* 2.03.00 */
 {
-	{  64,   25, 1056,  422, 1408,  806 }, /*, 664 */
-	{ 128,   39,  884,  396, 1408,  806 }, /*, 640 */
-	{  64,   25, 1056,  422, 1408,  806 }, /*, 664 */
-	{ 128,   39,  884,  396, 1408,  806 }, /*, 640 */
-	{  32,   15, 1056,  513, 1408,  806 }, /*, 664 */
-	{ 176,  125, 1280,  640, 1408,  806 }, /*, 768 */
-	{  88,   81, 1296,  806, 1408,  806 },
+	{  16,    5,  960,  410, 1600,  806 }, /* 640x400 */
+	{  64,   21, 1152,  364, 1600,  806 },
+	{  16,    5,  960,  410, 1600,  806 },
+	{  64,   21, 1152,  364, 1600,  806 },
+	{  32,   13, 1040,  493, 1600,  806 }, /* 640x480 */
+	{  16,    9, 1152,  618, 1600,  806 }, /* 800x600 */
+	{  25,   21, 1344,  796, 1600,  806 }, /* 1024x768 */
+	{   0,    0,    0,    0,    0,    0 },
+	{   1,    1, 1600,  806, 1600,  806 }, /* 1280x768 */
 	{   0,    0,    0,    0,    0,    0 },
-	{   1,    1, 1408,  806, 1408,  806 }
+	{  16,   15, 1600,  750, 1600,  806 }  /* 1280x720 */
 };
 
+#if 0  /* Not used; _3 now reserved for NetVista (SiS301) */
 static const SiS_LCDDataStruct  SiS_LCD1280x768_3Data[] =
 {
 	{  64,   25, 1056,  422, 1664,  798 },			/* 640x400 */
@@ -1026,20 +1003,40 @@ static const SiS_LCDDataStruct  SiS_LCD1
 	{ 176,  125, 1280,  640, 1408,  806 }, /* ,768 */	/* 800x600 */
 	{  64,   61, 1342,  806, 1408,  806 },			/* 1024x768 */
 	{   0,    0,    0,    0,    0,    0 },
-	{   1,    1, 1408,  806, 1408,  806 }			/* 1280x768 */
+	{   1,    1, 1408,  806, 1408,  806 },			/* 1280x768 */
+	{   0,    0,    0,    0,    0,    0 },
+	{  16,   15, 1600,  750, 1600,  806 }  /* 1280x720  from above */
 };
+#endif
 
-static const SiS_LCDDataStruct  SiS_LCD1280x800Data[] =
+static const SiS_LCDDataStruct  SiS_LCD1280x800Data[] = /* 0.93.12a (TMDS) */
 {
-	{ 128,   51, 1122,  412, 1408,  816 }, /* 640x400 */
+	{ 128,   51, 1122,  412, 1408,  816 },  /* 640x400 */
 	{ 128,   49, 1232,  361, 1408,  816 },
 	{ 128,   51, 1122,  412, 1408,  816 },
 	{ 128,   49, 1232,  361, 1408,  816 },
-	{   8,    3,  880,  491, 1408,  816 }, /* 640x480 */
-	{  11,    6, 1024,  612, 1408,  816 }, /* 800x600 */
-	{  22,   21, 1400,  784, 1408,  816 }, /* 1024x768 */
-	{   0,    0,    0,    0,    0,    0 },
-	{   1,    1, 1408,  816, 1408,  816 }  /* 1280x800 */
+	{   8,    3,  880,  491, 1408,  816 },  /* 640x480 */
+	{  11,    6, 1024,  612, 1408,  816 },  /* 800x600 */
+	{  22,   21, 1400,  784, 1408,  816 },  /* 1024x768 */
+	{   0,    0,    0,    0,    0,    0 },  /* 1280x1024 */
+	{   1,    1, 1408,  816, 1408,  816 },  /* 1280x800 */
+	{   0,    0,    0,    0,    0,    0 },  /* 1280x768 (patch index) */
+	{   0,    0,    0,    0,    0,    0 }   /* 1280x720 */
+};
+
+static const SiS_LCDDataStruct  SiS_LCD1280x800_2Data[] = /* 2.03.00 (LVDS) */
+{
+	{  97,   42, 1344,  409, 1552,  812 }, /* 640x400 */
+	{  97,   35, 1280,  358, 1552,  812 },
+	{  97,   42, 1344,  409, 1552,  812 },
+	{  97,   35, 1280,  358, 1552,  812 },
+	{  97,   39, 1040,  488, 1552,  812 }, /* 640x480 */
+	{ 194,  105, 1120,  608, 1552,  812 }, /* 800x600 */
+	{  97,   84, 1400,  780, 1552,  812 }, /* 1024x768 */
+	{   0,    0,    0,    0,    0,    0 }, /* 1280x1024 */
+	{   1,    1, 1552,  812, 1552,  812 }, /* 1280x800 */
+	{  97,   96, 1600,  780, 1552,  812 }, /* 1280x768 - patch index */
+	{  97,   90, 1600,  730, 1552,  812 }  /* 1280x720 */
 };
 
 static const SiS_LCDDataStruct  SiS_LCD1280x960Data[] =
@@ -1097,9 +1094,9 @@ static const SiS_LCDDataStruct  SiS_LCD1
 	{  95,   64, 1750,  784, 1900, 1066 }, /*  6 1024x768 */
 	{  95,   94, 1900, 1055, 1900, 1066 }, /*  7 1280x1024 */
 	{  41,   31, 1900,  806, 1900, 1066 }, /*  8 1280x768 */
-	{  95,   69, 1800,  817, 1900, 1066 }, /*  9 1280x800 patch */
+	{  95,   69, 1800,  817, 1900, 1066 }, /*  9 1280x800 patch index */
 	{  13,    9, 1900,  739, 1900, 1066 }, /* 10 1280x720 */
-	{  95,   94, 1880, 1066, 1900, 1066 }, /* 11 1400x1050 patch */
+	{  95,   94, 1880, 1066, 1900, 1066 }, /* 11 1400x1050 patch index */
 	{   1,    1, 1900, 1066, 1900, 1066 }  /* 12 1680x1050 */
 };
 
@@ -1148,12 +1145,12 @@ static const SiS_LCDDataStruct  SiS_NoSc
 	{ 1, 1,1800,1000,1800,1000 },  /* 0x0a: 1280x960  */
 	{ 1, 1,1688,1066,1688,1066 },  /* 0x0b: 1400x1050 */
 	{ 1, 1,1650, 750,1650, 750 },  /* 0x0c: 1280x720 (TMDS, projector)  */
-	{ 1, 1,1656, 841,1656, 841 },  /* 0x0d: 1280x800 (was: 1408, 816) */
+	{ 1, 1,1552, 812,1552, 812 },  /* 0x0d: 1280x800_2 (LVDS) (was: 1408,816/ 1656,841) */
 	{ 1, 1,1900,1066,1900,1066 },  /* 0x0e: 1680x1050 (LVDS) */
-	{ 1, 1,1408, 806,1408, 806 },  /* 0x0f: 1280x768_2 */
-	{ 1, 1,1664, 798,1664, 798 },  /* 0x10: 1280x768_3 */
-	{ 1, 1,1688, 802,1688, 802 },  /* 0x11: 1280x768: Std, TMDS only */
-	{ 1, 1,1344, 806,1344, 806 },  /* 0x12: 1280x720 (LVDS)  */
+	{ 1, 1,1660, 806,1660, 806 },  /* 0x0f: 1280x768_2 (LVDS) */
+	{ 1, 1,1664, 798,1664, 798 },  /* 0x10: 1280x768_3 (NetVista SiS 301) - TODO */
+	{ 1, 1,1688, 802,1688, 802 },  /* 0x11: 1280x768   (TMDS Fujitsu) */
+	{ 1, 1,1408, 806,1408, 806 },  /* 0x12: 1280x720 (LVDS) */
 	{ 1, 1, 896, 497, 896, 497 },  /* 0x13: 720x480 */
 	{ 1, 1, 912, 597, 912, 597 },  /* 0x14: 720x576 */
 	{ 1, 1, 912, 597, 912, 597 },  /* 0x15: 768x576 */
@@ -1163,10 +1160,11 @@ static const SiS_LCDDataStruct  SiS_NoSc
 	{ 1, 1,1328, 739,1328, 739 },  /* 0x19: 1024x576 */
 	{ 1, 1,1680, 892,1680, 892 },  /* 0x1a: 1152x864 */
 	{ 1, 1,1808, 808,1808, 808 },  /* 0x1b: 1360x768 */
-	{ 1, 1,1104, 563,1104, 563 }   /* 0x1c: 960x540 */
+	{ 1, 1,1104, 563,1104, 563 },  /* 0x1c: 960x540 */
+	{ 1, 1,1120, 618,1120, 618 },  /* 0x1d: 960x600 */
+	{ 1, 1,1408, 816,1408, 816 }   /* 0x1f: 1280x800 (TMDS special) */
 };
 
-
 /**************************************************************/
 /* LVDS ----------------------------------------------------- */
 /**************************************************************/
@@ -1207,7 +1205,6 @@ static const SiS_LVDSDataStruct  SiS_LVD
 	{ 800, 525, 800, 525}    /* pseudo */
 };
 
-
 static const SiS_LVDSDataStruct  SiS_LVDS800x600Data_1[]=
 {
 	{ 848, 433,1060, 629},
@@ -1221,12 +1218,6 @@ static const SiS_LVDSDataStruct  SiS_LVD
 
 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}
 };
 
@@ -1243,13 +1234,7 @@ static const SiS_LVDSDataStruct  SiS_LVD
 
 static const SiS_LVDSDataStruct  SiS_LVDS1024x768Data_2[]=
 {
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
+	{1344, 806,1344, 806}
 };
 
 static const SiS_LVDSDataStruct  SiS_LVDS1280x1024Data_1[]=
@@ -1266,13 +1251,6 @@ static const SiS_LVDSDataStruct  SiS_LVD
 
 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}
 };
 
@@ -1291,15 +1269,7 @@ static const SiS_LVDSDataStruct  SiS_LVD
 
 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},
+        {1688,1066, 1688,1066}
 };
 
 static const SiS_LVDSDataStruct  SiS_LVDS1600x1200Data_1[]=
@@ -1314,32 +1284,11 @@ static const SiS_LVDSDataStruct  SiS_LVD
 	{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}
+        {2048,1320, 2048,1320}
 };
 
 static const SiS_LVDSDataStruct  SiS_LVDS1280x960Data_1[]=
@@ -1357,15 +1306,7 @@ static const SiS_LVDSDataStruct  SiS_LVD
 
 static const SiS_LVDSDataStruct  SiS_LVDS1280x960Data_2[]=
 {
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{ 800, 449,1280, 801},
-	{ 800, 525,1280, 813}
+	{1344, 806,1344, 806}
 };
 
 static const SiS_LVDSDataStruct  SiS_LVDS1280x768Data_1[]=
@@ -1383,14 +1324,6 @@ static const SiS_LVDSDataStruct  SiS_LVD
 
 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}
 };
 
@@ -1407,12 +1340,6 @@ static const SiS_LVDSDataStruct  SiS_LVD
 
 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}
 };
 
@@ -1429,12 +1356,6 @@ static const SiS_LVDSDataStruct  SiS_LVD
 
 static const SiS_LVDSDataStruct  SiS_LVDS1152x768Data_2[] =
 {
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
 	{1344, 806,1344, 806}
 };
 
@@ -1445,12 +1366,11 @@ static const SiS_LVDSDataStruct  SiS_LVD
 	{ 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   */
-	{1688,1066, 1688,1066},  /* 1280x1024  */  /* INSERTED ! */
- 	{1688, 806, 1688, 806},  /* 1280x768   */
-	/* No other panels ! */
+	{ 800, 525,  800, 525},  /*  640x480  */
+	{1056, 628, 1056, 628},  /*  800x600  */
+	{1344, 806, 1344, 806},  /* 1024x768  */
+	{1688,1066, 1688,1066},  /* 1280x1024 */  /* INSERTED */
+ 	{1688, 806, 1688, 806},  /* 1280x768  */
 };
 
 /* Custom data for Barco iQ R series */
@@ -1496,13 +1416,7 @@ static const SiS_LVDSDataStruct  SiS_LVD
 /* 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},
+	{1344, 806,1344, 806}
 };
 
 /* Custom data for 848x480 parallel panel */
@@ -1589,10 +1503,10 @@ static const SiS_LVDSDesStruct  SiS_CHTV
 
 static const SiS_LVDSDesStruct  SiS_CHTVUPALDesData[]=
 {
-	{256,   0},
-	{256,   0},
-	{256,   0},
-	{256,   0},
+	{256,  0},
+	{256,  0},
+	{256,  0},
+	{256,  0},
 	{ 0,   0},
 	{ 0,   0},
 	{ 0,   0}
@@ -1600,10 +1514,10 @@ static const SiS_LVDSDesStruct  SiS_CHTV
 
 static const SiS_LVDSDesStruct  SiS_CHTVOPALDesData[]=
 {
-	{256,   0},
-	{256,   0},
-	{256,   0},
-	{256,   0},
+	{256,  0},
+	{256,  0},
+	{256,  0},
+	{256,  0},
 	{ 0,   0},
 	{ 0,   0},
 	{ 0,   0}
@@ -2105,6 +2019,8 @@ static const SiS_LVDSCRT1DataStruct  SiS
 /* COMMON --------------------------------------------------- */
 /**************************************************************/
 
+#ifdef LINUX_XF86
+
 #define SIS_PL_HSYNCP 0x01
 #define SIS_PL_HSYNCN 0x02
 #define SIS_PL_VSYNCP 0x04
@@ -2127,6 +2043,8 @@ typedef struct _SiS_PlasmaTables
    USHORT product[5];
    const char *DDCnames[5];
    const char *plasmaname;
+   USHORT maxx,maxy;
+   USHORT prefx, prefy;
    UCHAR  modenum;
    UCHAR  plasmamodes[20];  /* | 0x80 = DVI-capable, | 0x40 = analog */
 } SiS_PlasmaTables;
@@ -2237,14 +2155,51 @@ static const SiS_PlasmaModes SiS_PlasmaM
         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 },
+   {  "1280x720",		/* 21: WIDE720(60) (aka "750p") (Panasonic) */
+      74300,
+      1280, 1650,110,  40,
+       720,  750,  5,   5,
+      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
+   {  "1280x768",		/* 22: 1280x768@56.5 (Panasonic) */
+      76200,			/* (According to manual not supported for HDMI; but works) */
+      1280, 1680, 16,  24,
+       768,  802,  2,   5,
+      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
+   {  "1280x720@50",		/* 23: WIDE720(50) (aka "750p") (Panasonic) */
+      74300,			/* Panasonic states 45.0kHz. Not possible. This one works (with some overscan) */
+      1280, 1980,400,  80,
+       720,  750,  1,   2,
+      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
+   {  "720x480",		/* 24: 720x480 (aka "525p" and "480p") (Panasonic) */
+      27000,
+       720,  856, 40,  32,
+       480,  525,  1,   3,
+      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
+   {  "720x576",		/* 25: 720x576 (aka "625p"and "576p") (Panasonic) */
+      27500,
+       720,  864, 16,  64,
+       576,  625,  5,   6,
+      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
+   {  "1280x720@50",		/* 26: WIDE720(50) (aka "750p") (Generic) */
+      74300,
+      1280, 1980,400,  80,
+       720,  750,  5,   5,
+      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
 };
 
+/*
+27.00  720 755 791 858  480 480 484 525
+27.50  720 732 795 864  576 581 587 625
+*/
+
 static const SiS_PlasmaTables SiS_PlasmaTable[] = {
 #if 0  /* Product IDs missing */
    { 0x38a3, 4,
      { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
      { "", "", "", "", "" },
      "NEC PlasmaSync 42VP4/42VP4D/42VP4G/42VP4DG",
+     0, 0,
+     0, 0,
      11,   /* All DVI, except 0, 7, 13 */
      { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 7|0x40, 9|0xc0,10|0xc0,11|0xc0,13|0x40,14|0xc0,
       17|0xc0, 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
@@ -2255,6 +2210,8 @@ static const SiS_PlasmaTables SiS_Plasma
      { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
      { "", "", "", "", "" },
      "NEC PlasmaSync 42PD1/50PD1/50PD2",
+     0, 0,
+     0, 0,
      5,   /* DVI entirely unknown */
      { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 9|0xc0, 0     , 0     , 0     , 0     , 0     ,
        0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
@@ -2263,6 +2220,8 @@ static const SiS_PlasmaTables SiS_Plasma
      { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
      { "", "", "", "", "" },
      "NEC PlasmaSync 42PD3",
+     0, 0,
+     0, 0,
      10,   /* DVI entirely unknown */
      { 0|0x40, 1|0xc0, 2|0xc0, 3|0xc0, 4|0xc0, 5|0xc0, 6|0xc0, 7|0x40, 8|0xc0, 9|0xc0,
        0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
@@ -2271,6 +2230,8 @@ static const SiS_PlasmaTables SiS_Plasma
      { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
      { "", "", "", "", "" },
      "NEC PlasmaSync 42VM3/61XM1",
+     0, 0,
+     0, 0,
      11,  /* DVI entirely unknown */
      { 0|0x40, 1|0xc0, 2|0xc0, 3|0xc0, 4|0xc0, 5|0xc0, 6|0xc0, 8|0xc0, 9|0xc0,11|0xc0,
       17|0xc0, 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
@@ -2279,6 +2240,8 @@ static const SiS_PlasmaTables SiS_Plasma
      { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
      { "", "", "", "", "" },
      "NEC PlasmaSync 42MP1/42MP2",
+     0, 0,
+     0, 0,
      6,   /* DVI entirely unknown */
      { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 9|0xc0,11|0xc0, 0     , 0     , 0     , 0     ,
        0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
@@ -2287,6 +2250,8 @@ static const SiS_PlasmaTables SiS_Plasma
      { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
      { "", "", "", "", "" },
      "NEC PlasmaSync 50MP1",
+     0, 0,
+     0, 0,
      10,   /* DVI entirely unknown */
      { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 7|0x40, 9|0xc0,10|0xc0,11|0xc0,13|0x40,14|0xc0,
        0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
@@ -2296,6 +2261,8 @@ static const SiS_PlasmaTables SiS_Plasma
      { 0xa482, 0xa483, 0x0000, 0x0000, 0x0000 },
      { "PX-42VM", "", "", "", "" },
      "NEC PlasmaSync 42MP3/42MP4/50MP2/61MP1",
+     0, 0,
+     0, 0,
      11,   /* All DVI except 0, 7, 13, 17 */
      { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 7|0x40, 9|0xc0,10|0xc0,11|0xc0,13|0x40,14|0xc0,
       17|0x40, 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
@@ -2305,6 +2272,8 @@ static const SiS_PlasmaTables SiS_Plasma
      { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
      { "", "", "", "", "" },
      "NEC PlasmaSync 3300W",
+     0, 0,
+     0, 0,
      3,
      { 0|0x40, 1|0xc0,18|0xc0, 0     , 0     , 0     , 0     , 0     , 0     , 0     ,
        0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
@@ -2321,6 +2290,8 @@ static const SiS_PlasmaTables SiS_Plasma
      { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
      { "", "", "", "", "" },
      "NEC PlasmaSync 4210W",
+     0, 0,
+     0, 0,
      6,   /* DVI entirely unknown */
      { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 9|0xc0,11|0xc0, 0     , 0     , 0     , 0     ,
        0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
@@ -2329,6 +2300,8 @@ static const SiS_PlasmaTables SiS_Plasma
      { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
      { "", "", "", "", "" },
      "NEC PlasmaSync 5000W",
+     0, 0,
+     0, 0,
      7,   /* DVI entirely unknown */
      { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 7|0x40, 9|0xc0,11|0xc0, 0     , 0     , 0     ,
        0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
@@ -2338,6 +2311,8 @@ static const SiS_PlasmaTables SiS_Plasma
      { 0x000c, 0x000b, 0x0000, 0x0000, 0x0000 },
      { "", "", "", "", "" },
      "Pioneer 503CMX/PDA-5002",
+     0, 0,
+     0, 0,
      6,   /* DVI unknown */
      { 1|0xc0, 2|0xc0, 9|0xc0,11|0xc0,12|0xc0,15|0xc0, 0     , 0     , 0     , 0     ,
        0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
@@ -2346,6 +2321,8 @@ static const SiS_PlasmaTables SiS_Plasma
      { 0xa00e, 0x0000, 0x0000, 0x0000, 0x0000 },
      { "", "", "", "", "" },
      "Panasonic TH-42",
+     0, 0,
+     0, 0,
      5,   /* No DVI output */
      { 1|0x40, 2|0x40, 4|0x40, 9|0x40,15|0x40, 0     , 0     , 0     , 0     , 0     ,
        0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
@@ -2354,15 +2331,50 @@ static const SiS_PlasmaTables SiS_Plasma
      { 0xa005, 0x0000, 0x0000, 0x0000, 0x0000 },
      { "TH-42PW*4", "", "", "", "" },
      "Panasonic TH-42PW5",
+     0, 0,
+     0, 0,
      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       }
    },
+   { 0x4c2e, 1,
+     { 0x9b05, 0x0000, 0x0000, 0x0000, 0x0000 },
+     { "PLV-Z2", "", "", "", "" },
+     "Sanyo PLV-Z2 (non HDCP-mode)", 	/* HDCP mode would be id 9b06, but not needed */
+     1280, 768,				/* as it then advertises correct size */
+     1280, 720,
+     1,   /* 1280x720, no special modes otherwise */
+     {21|0xc0, 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     ,
+       0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
+   },
+   { 0x34a9, 1,
+     { 0xd034, 0x0000, 0x0000, 0x0000, 0x0000 },
+     { "AE500U (DVI-D)", "", "", "", "" },
+     "Panasonic AE500U",
+     1280, 768,
+     1280, 720,
+     1,   /* 1280x720, no special modes otherwise */
+     {21|0xc0, 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     ,
+       0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
+   },
+   { 0x34a9, 1,
+     { 0xd043, 0x0000, 0x0000, 0x0000, 0x0000 },
+     { "AE700U (HDMI)", "", "", "", "" },
+     "Panasonic AE700U",
+     1360, 768,
+     1280, 720,
+     6,   /* 1280x720/60, 1280x720/50, 1280x768@56(digital/analog), 720x480, 720x576 */
+     {21|0xc0,23|0xc0,22|0x80,13|0x40,24|0x80,25|0x80, 0     , 0     , 0     , 0     ,
+       0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
+   },
    { 0x0000 }
 };
+#endif
 
+#ifdef LINUX_XF86
 USHORT  SiS_GetModeID(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay,
 			  int Depth, BOOLEAN FSTN, int LCDwith, int LCDheight);
+#endif
 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);
@@ -2376,9 +2388,9 @@ UCHAR	SiS_GetReg(SISIOADDRESS port, USHO
 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_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);
@@ -2387,14 +2399,14 @@ BOOLEAN SiSDetermineROMLayout661(SiS_Pri
 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);
+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);
-void	SiS_CalcLCDACRT1Timing(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex);
+void	SiS_CalcLCDACRT1Timing(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex);
+
 #ifdef LINUX_XF86
 BOOLEAN	SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,ScrnInfoPtr pScrn,USHORT ModeNo, BOOLEAN dosetpitch);
 BOOLEAN	SiSBIOSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
@@ -2404,51 +2416,56 @@ BOOLEAN	SiSBIOSSetModeCRT2(SiS_Private *
 BOOLEAN	SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
                DisplayModePtr mode, BOOLEAN IsCustom);
 int	SiSTranslateToVESA(ScrnInfoPtr pScrn, int modenumber);
+int	SiSTranslateToOldMode(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);
+int 	SiS_FindPanelFromDB(SISPtr pSiS, USHORT panelvendor, USHORT panelproduct, int *maxx, int *maxy, int *prefx, int *prefy);
+void    SiS_MakeClockRegs(ScrnInfoPtr pScrn, int clock, UCHAR *p2b, UCHAR *p2c);
 #else
 BOOLEAN	SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,USHORT ModeNo);
 #endif
+
 #ifdef LINUX_KERNEL
-int    sisfb_mode_rate_to_dclock(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
-			      unsigned char modeno, unsigned char rateindex);
-int    sisfb_mode_rate_to_ddata(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
-			 unsigned char modeno, unsigned char rateindex,
-			 struct fb_var_screeninfo *var);
+int    	sisfb_mode_rate_to_dclock(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+			      UCHAR modeno, UCHAR rateindex);
+int    	sisfb_mode_rate_to_ddata(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+			UCHAR modeno, UCHAR rateindex,
+			struct fb_var_screeninfo *var);
 BOOLEAN sisfb_gettotalfrommode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
-		       unsigned char modeno, int *htotal, int *vtotal, unsigned char rateindex);
+		       	UCHAR modeno, int *htotal, int *vtotal, UCHAR 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);
+/* init301.c: */
+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
+/* From other sis driver modules: */
 extern int      SiS_compute_vclk(int Clock, int *out_n, int *out_dn, int *out_div,
-	     	 		 int *out_sbit, int *out_scale);
+	     	 	 	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);
+extern UCHAR   	SiS_GetSetBIOSScratch(ScrnInfoPtr pScrn, USHORT offset, UCHAR value);
+extern UCHAR   	SiS_GetSetModeID(ScrnInfoPtr pScrn, UCHAR id);
+extern USHORT 	SiS_GetModeNumber(ScrnInfoPtr pScrn, DisplayModePtr mode, ULONG VBFlags);
 #endif
 
 #endif
diff -puN drivers/video/sis/oem300.h~fbdev-sis-framebuffer-driver-update-1717 drivers/video/sis/oem300.h
--- 25/drivers/video/sis/oem300.h~fbdev-sis-framebuffer-driver-update-1717	2004-11-28 01:30:58.866561304 -0800
+++ 25-akpm/drivers/video/sis/oem300.h	2004-11-28 01:30:58.946549144 -0800
@@ -35,7 +35,7 @@
  * * 3) 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 EXPRESSED OR
+ * * 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,
@@ -50,7 +50,7 @@
  *
  */
 
-const UCHAR SiS300_OEMTVDelay301[8][4] =
+static const UCHAR SiS300_OEMTVDelay301[8][4] =
 {
 	{0x08,0x08,0x08,0x08},
 	{0x08,0x08,0x08,0x08},
@@ -62,7 +62,7 @@ const UCHAR SiS300_OEMTVDelay301[8][4] =
 	{0x20,0x20,0x20,0x20}
 };
 
-const UCHAR SiS300_OEMTVDelayLVDS[8][4] =
+static const UCHAR SiS300_OEMTVDelayLVDS[8][4] =
 {
 	{0x20,0x20,0x20,0x20},
 	{0x20,0x20,0x20,0x20},
@@ -74,7 +74,7 @@ const UCHAR SiS300_OEMTVDelayLVDS[8][4] 
 	{0x20,0x20,0x20,0x20}
 };
 
-const UCHAR SiS300_OEMTVFlicker[8][4] =
+static const UCHAR SiS300_OEMTVFlicker[8][4] =
 {
 	{0x00,0x00,0x00,0x00},
 	{0x00,0x00,0x00,0x00},
@@ -87,7 +87,7 @@ const UCHAR SiS300_OEMTVFlicker[8][4] =
 };
 
 #if 0   /* TW: Not used */
-const UCHAR SiS300_OEMLCDDelay1[12][4]={
+static const UCHAR SiS300_OEMLCDDelay1[12][4]={
 	{0x2c,0x2c,0x2c,0x2c},
 	{0x20,0x20,0x20,0x20},
 	{0x20,0x20,0x20,0x20},
@@ -103,8 +103,8 @@ const UCHAR SiS300_OEMLCDDelay1[12][4]={
 };
 #endif
 
-/* TW: From 630/301B BIOS */
-const UCHAR SiS300_OEMLCDDelay2[64][4] =		 /* for 301/301b/302b/301LV/302LV */
+/* From 630/301B BIOS */
+static const UCHAR SiS300_OEMLCDDelay2[64][4] =		 /* for 301/301b/302b/301LV/302LV */
 {
 	{0x20,0x20,0x20,0x20},
 	{0x20,0x20,0x20,0x20},
@@ -172,8 +172,8 @@ const UCHAR SiS300_OEMLCDDelay2[64][4] =
 	{0x20,0x20,0x20,0x20}
 };
 
-/* TW: From 300/301LV BIOS */
-const UCHAR SiS300_OEMLCDDelay4[12][4] =
+/* From 300/301LV BIOS */
+static const UCHAR SiS300_OEMLCDDelay4[12][4] =
 {
 	{0x2c,0x2c,0x2c,0x2c},
 	{0x20,0x20,0x20,0x20},
@@ -189,8 +189,8 @@ const UCHAR SiS300_OEMLCDDelay4[12][4] =
 	{0x24,0x24,0x24,0x24}
 };
 
-/* TW: From 300/301LV BIOS */
-const UCHAR SiS300_OEMLCDDelay5[32][4] =
+/* From 300/301LV BIOS */
+static const UCHAR SiS300_OEMLCDDelay5[32][4] =
 {
 	{0x20,0x20,0x20,0x20},
 	{0x20,0x20,0x20,0x20},
@@ -226,8 +226,8 @@ const UCHAR SiS300_OEMLCDDelay5[32][4] =
 	{0x20,0x20,0x20,0x20},
 };
 
-/* TW: Added for LVDS */
-const UCHAR SiS300_OEMLCDDelay3[64][4] = {	/* For LVDS */
+/* Added for LVDS */
+static const UCHAR SiS300_OEMLCDDelay3[64][4] = {	/* For LVDS */
 	{0x20,0x20,0x20,0x20},
 	{0x20,0x20,0x20,0x20},
 	{0x20,0x20,0x20,0x20},
@@ -294,7 +294,7 @@ const UCHAR SiS300_OEMLCDDelay3[64][4] =
 	{0x20,0x20,0x20,0x20}
 };
 
-const UCHAR SiS300_Phase1[8][5][4] =
+static const UCHAR SiS300_Phase1[8][5][4] =
 {
     {
 	{0x21,0xed,0x00,0x08},
@@ -355,7 +355,7 @@ const UCHAR SiS300_Phase1[8][5][4] =
 };
 
 
-const UCHAR SiS300_Phase2[8][5][4] =
+static const UCHAR SiS300_Phase2[8][5][4] =
 {
     {
         {0x21,0xed,0x00,0x08},
@@ -415,7 +415,7 @@ const UCHAR SiS300_Phase2[8][5][4] =
     }
 };
 
-const UCHAR SiS300_Filter1[10][16][4] =
+static const UCHAR SiS300_Filter1[10][16][4] =
 {
     {
 	{0x00,0xf4,0x10,0x38},
@@ -599,7 +599,7 @@ const UCHAR SiS300_Filter1[10][16][4] =
     },
 };
 
-const UCHAR SiS300_Filter2[10][9][7] =
+static const UCHAR SiS300_Filter2[10][9][7] =
 {
     {
 	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
@@ -714,7 +714,7 @@ const UCHAR SiS300_Filter2[10][9][7] =
 };
 
 /* Custom data for Barco iQ Pro R300 */
-const UCHAR barco_p1[2][9][7][3] = {
+static const UCHAR barco_p1[2][9][7][3] = {
     {
 	{  { 0x16, 0xcf, 0x00 },
 	   { 0x18, 0x00, 0x00 },
diff -puN drivers/video/sis/oem310.h~fbdev-sis-framebuffer-driver-update-1717 drivers/video/sis/oem310.h
--- 25/drivers/video/sis/oem310.h~fbdev-sis-framebuffer-driver-update-1717	2004-11-28 01:30:58.868561000 -0800
+++ 25-akpm/drivers/video/sis/oem310.h	2004-11-28 01:30:58.947548992 -0800
@@ -35,7 +35,7 @@
  * * 3) 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 EXPRESSED OR
+ * * 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,
diff -puN drivers/video/sis/osdef.h~fbdev-sis-framebuffer-driver-update-1717 drivers/video/sis/osdef.h
--- 25/drivers/video/sis/osdef.h~fbdev-sis-framebuffer-driver-update-1717	2004-11-28 01:30:58.869560848 -0800
+++ 25-akpm/drivers/video/sis/osdef.h	2004-11-28 01:30:58.948548840 -0800
@@ -35,7 +35,7 @@
  * * 3) 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 EXPRESSED OR
+ * * 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,
@@ -51,9 +51,12 @@
  *
  */
 
+#ifndef _SIS_OSDEF_H_
+#define _SIS_OSDEF_H_
+
 /* The choices are: */
-#define LINUX_KERNEL	   /* Kernel framebuffer */
-/* #define LINUX_XF86 */   /* XFree86 */
+#define LINUX_KERNEL	   /* Linux kernel framebuffer */
+/* #define LINUX_XF86 */   /* XFree86/X.org */
 
 #ifdef OutPortByte
 #undef OutPortByte
@@ -109,20 +112,20 @@
 #endif
 
 /**********************************************************************/
-/*  XFree86, X.org                                                    */
+/*  XFree86/X.org                                                    */
 /**********************************************************************/
 
 #ifdef LINUX_XF86
 #define SIS300
 #define SIS315H
 
-#define OutPortByte(p,v) outb((IOADDRESS)(p),(CARD8)(v))
-#define OutPortWord(p,v) outw((IOADDRESS)(p),(CARD16)(v))
-#define OutPortLong(p,v) outl((IOADDRESS)(p),(CARD32)(v))
-#define InPortByte(p)    inb((IOADDRESS)(p))
-#define InPortWord(p)    inw((IOADDRESS)(p))
-#define InPortLong(p)    inl((IOADDRESS)(p))
+#define OutPortByte(p,v) outSISREG((IOADDRESS)(p),(CARD8)(v))
+#define OutPortWord(p,v) outSISREGW((IOADDRESS)(p),(CARD16)(v))
+#define OutPortLong(p,v) outSISREGL((IOADDRESS)(p),(CARD32)(v))
+#define InPortByte(p)    inSISREG((IOADDRESS)(p))
+#define InPortWord(p)    inSISREGW((IOADDRESS)(p))
+#define InPortLong(p)    inSISREGL((IOADDRESS)(p))
 #define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize)
 #endif
 
-
+#endif  /* _OSDEF_H_ */
diff -puN drivers/video/sis/sis_accel.c~fbdev-sis-framebuffer-driver-update-1717 drivers/video/sis/sis_accel.c
diff -puN drivers/video/sis/sis_accel.h~fbdev-sis-framebuffer-driver-update-1717 drivers/video/sis/sis_accel.h
diff -puN drivers/video/sis/sis.h~fbdev-sis-framebuffer-driver-update-1717 drivers/video/sis/sis.h
--- 25/drivers/video/sis/sis.h~fbdev-sis-framebuffer-driver-update-1717	2004-11-28 01:30:58.873560240 -0800
+++ 25-akpm/drivers/video/sis/sis.h	2004-11-28 01:30:58.952548232 -0800
@@ -1,5 +1,5 @@
 /*
- * SiS 300/630/730/540/315/550/650/651/M650/661FX/M661FX/740/741/330/760
+ * SiS 300/630/730/540/315/550/[M]650/651/[M]661[FM]X/740/[M]741[GX]/330/[M]760[GX]
  * frame buffer driver for Linux kernels >=2.4.14 and >=2.6.3
  *
  * Copyright (C) 2001-2004 Thomas Winischhofer, Vienna, Austria.
@@ -37,7 +37,7 @@
 
 #define VER_MAJOR                 1
 #define VER_MINOR                 7
-#define VER_LEVEL                 12
+#define VER_LEVEL                 17
 
 #undef SIS_CONFIG_COMPAT
 
@@ -55,6 +55,16 @@
 #endif
 #endif
 
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)
+#define SIS_IOTYPE1 void __iomem
+#define SIS_IOTYPE2 __iomem
+#define SISINITSTATIC static
+#else
+#define SIS_IOTYPE1 unsigned char
+#define SIS_IOTYPE2
+#define SISINITSTATIC
+#endif
+
 #undef SISFBDEBUG
 
 #ifdef SISFBDEBUG
@@ -180,6 +190,7 @@
 #define SIS_CRT2_WENABLE_315 	  0x2F
 
 #define SIS_PASSWORD              0x86  /* SR05 */
+
 #define SIS_INTERLACED_MODE       0x20  /* SR06 */
 #define SIS_8BPP_COLOR_MODE       0x0
 #define SIS_15BPP_COLOR_MODE      0x1
@@ -238,41 +249,58 @@
 #define HW_DEVICE_EXTENSION	  SIS_HW_INFO
 #define PHW_DEVICE_EXTENSION      PSIS_HW_INFO
 
-/* Useful macros */
+/* I/O port access macros */
 #define inSISREG(base)          inb(base)
+
 #define outSISREG(base,val)     outb(val,base)
-#define orSISREG(base,val)      do { \
-                                  u8 __Temp = inb(base); \
-                                  outSISREG(base, __Temp | (val)); \
-                                } while (0)
-#define andSISREG(base,val)     do { \
-                                  u8 __Temp = inb(base); \
-                                  outSISREG(base, __Temp & (val)); \
-                                } while (0)
-#define inSISIDXREG(base,idx,var)   do { \
-                                      outb(idx,base); var=inb((base)+1); \
-                                    } while (0)
-#define outSISIDXREG(base,idx,val)  do { \
-                                      outb(idx,base); outb((val),(base)+1); \
-                                    } while (0)
-#define orSISIDXREG(base,idx,val)   do { \
-                                      u8 __Temp; \
-                                      outb(idx,base);   \
-                                      __Temp = inb((base)+1)|(val); \
-                                      outSISIDXREG(base,idx,__Temp); \
-                                    } while (0)
-#define andSISIDXREG(base,idx,and)  do { \
-                                      u8 __Temp; \
-                                      outb(idx,base);   \
-                                      __Temp = inb((base)+1)&(and); \
-                                      outSISIDXREG(base,idx,__Temp); \
-                                    } while (0)
-#define setSISIDXREG(base,idx,and,or)   do { \
-                                          u8 __Temp; \
-                                          outb(idx,base);   \
-                                          __Temp = (inb((base)+1)&(and))|(or); \
-                                          outSISIDXREG(base,idx,__Temp); \
-                                        } while (0)
+
+#define orSISREG(base,val)      			\
+		    do { 				\
+                      u8 __Temp = inSISREG(base); 	\
+                      outSISREG(base, __Temp | (val)); 	\
+                    } while (0)
+
+#define andSISREG(base,val)     			\
+		    do { 				\
+                      u8 __Temp = inSISREG(base); 	\
+                      outSISREG(base, __Temp & (val)); 	\
+                    } while (0)
+
+#define inSISIDXREG(base,idx,var)   		\
+		    do { 			\
+                      outSISREG(base, idx); 	\
+		      var = inSISREG((base)+1);	\
+                    } while (0)
+
+#define outSISIDXREG(base,idx,val)  		\
+		    do { 			\
+                      outSISREG(base, idx); 	\
+		      outSISREG((base)+1, val); \
+                    } while (0)
+
+#define orSISIDXREG(base,idx,val)   				\
+		    do { 					\
+                      u8 __Temp; 				\
+                      outSISREG(base, idx);   			\
+                      __Temp = inSISREG((base)+1) | (val); 	\
+		      outSISREG((base)+1, __Temp);		\
+                    } while (0)
+
+#define andSISIDXREG(base,idx,and)  				\
+		    do { 					\
+                      u8 __Temp; 				\
+                      outSISREG(base, idx);   			\
+                      __Temp = inSISREG((base)+1) & (and); 	\
+		      outSISREG((base)+1, __Temp);		\
+                    } while (0)
+
+#define setSISIDXREG(base,idx,and,or)   		   		\
+		    do { 				   		\
+                      u8 __Temp; 		   			\
+                      outSISREG(base, idx);   		   		\
+                      __Temp = (inSISREG((base)+1) & (and)) | (or); 	\
+		      outSISREG((base)+1, __Temp);			\
+                    } while (0)
 
 /* MMIO access macros */
 #define MMIO_IN8(base, offset)  readb((base+offset))
@@ -293,10 +321,52 @@
 #define MMIO_QUEUE_WRITEPORT    Q_WRITE_PTR
 #define MMIO_QUEUE_READPORT     Q_READ_PTR
 
+#ifndef FB_BLANK_UNBLANK
+#define FB_BLANK_UNBLANK 	0
+#endif
+#ifndef FB_BLANK_NORMAL
+#define FB_BLANK_NORMAL  	1
+#endif
+#ifndef FB_BLANK_VSYNC_SUSPEND
+#define FB_BLANK_VSYNC_SUSPEND 	2
+#endif
+#ifndef FB_BLANK_HSYNC_SUSPEND
+#define FB_BLANK_HSYNC_SUSPEND 	3
+#endif
+#ifndef FB_BLANK_POWERDOWN
+#define FB_BLANK_POWERDOWN 	4
+#endif
+
+enum _SIS_LCD_TYPE {
+    LCD_INVALID = 0,
+    LCD_800x600,
+    LCD_1024x768,
+    LCD_1280x1024,
+    LCD_1280x960,
+    LCD_640x480,
+    LCD_1600x1200,
+    LCD_1920x1440,
+    LCD_2048x1536,
+    LCD_320x480,       /* FSTN */
+    LCD_1400x1050,
+    LCD_1152x864,
+    LCD_1152x768,
+    LCD_1280x768,
+    LCD_1024x600,
+    LCD_640x480_2,     /* DSTN */
+    LCD_640x480_3,     /* DSTN */
+    LCD_848x480,
+    LCD_1280x800,
+    LCD_1680x1050,
+    LCD_1280x720,
+    LCD_CUSTOM,
+    LCD_UNKNOWN
+};
+
 enum _SIS_CMDTYPE {
-	MMIO_CMD = 0,
-	AGP_CMD_QUEUE,
-	VM_CMD_QUEUE,
+    MMIO_CMD = 0,
+    AGP_CMD_QUEUE,
+    VM_CMD_QUEUE,
 };
 typedef unsigned int SIS_CMDTYPE;
 
@@ -360,10 +430,10 @@ struct sis_video_info {
 	unsigned long 	mmio_base;
 	unsigned long 	vga_base;
 
-	void __iomem *	video_vbase;
-	void __iomem *	mmio_vbase;
-	void __iomem * 	bios_vbase;
-	void *		bios_abase;
+	SIS_IOTYPE1  	*video_vbase;
+	SIS_IOTYPE1 	*mmio_vbase;
+
+	unsigned char   *bios_abase;
 
 	int 		mtrr;
 
@@ -391,9 +461,9 @@ struct sis_video_info {
 	int		sisfb_inverse;
 #endif
 
-	u32 		heapstart;        /* offset  */
-	void __iomem * 	sisfb_heap_start; /* address */
-	void __iomem * 	sisfb_heap_end;   /* address */
+	u32 		heapstart;        	/* offset  */
+	SIS_IOTYPE1  	*sisfb_heap_start; 	/* address */
+	SIS_IOTYPE1  	*sisfb_heap_end;   	/* address */
 	u32 	      	sisfb_heap_size;
 	int		havenoheap;
 #if 0
@@ -434,6 +504,7 @@ struct sis_video_info {
 
 	int		lcdxres, lcdyres;
 	int		lcddefmodeidx, tvdefmodeidx, defmodeidx;
+	u32  		CRT2LCDType;        	/* defined in "SIS_LCD_TYPE" */
 
 	int    		current_bpp;
 	int    		current_width;
@@ -455,6 +526,7 @@ struct sis_video_info {
 
 	int  		newrom;
 	int  		registered;
+	int		warncount;
 #ifdef SIS_CONFIG_COMPAT
 	int		ioctl32registered;
 	int		ioctl32vblankregistered;
@@ -469,7 +541,7 @@ struct sis_video_info {
 	u8 		detectedpdca;
 	u8 		detectedlcda;
 
-	void __iomem * 	hwcursor_vbase;
+	SIS_IOTYPE1 	*hwcursor_vbase;
 
 	int 		chronteltype;
 	int    		tvxpos, tvypos;
diff -puN drivers/video/sis/sis_main.c~fbdev-sis-framebuffer-driver-update-1717 drivers/video/sis/sis_main.c
--- 25/drivers/video/sis/sis_main.c~fbdev-sis-framebuffer-driver-update-1717	2004-11-28 01:30:58.875559936 -0800
+++ 25-akpm/drivers/video/sis/sis_main.c	2004-11-28 01:30:58.971545344 -0800
@@ -754,8 +754,8 @@ sisfbcheckvretracecrt2(struct sis_video_
    }
 
    inSISIDXREG(SISPART1, reg, temp);
-   if(temp & 0x02) return FALSE;
-   else 	   return TRUE;
+   if(temp & 0x02) return TRUE;
+   else 	   return FALSE;
 }
 
 static BOOLEAN
@@ -794,9 +794,9 @@ sisfb_setupvbblankflags(struct sis_video
       inSISIDXREG(SISPART1,(idx+1),reg2); /* 31 */
       inSISIDXREG(SISPART1,(idx+2),reg3); /* 32 */
       inSISIDXREG(SISPART1,(idx+3),reg4); /* 33 */
-      if(!(reg1 & 0x01)) ret |= FB_VBLANK_VBLANKING;
-      if(!(reg1 & 0x02)) ret |= FB_VBLANK_VSYNCING;
-      if(!(reg4 & 0x80)) ret |= FB_VBLANK_HBLANKING;
+      if(reg1 & 0x01) ret |= FB_VBLANK_VBLANKING;
+      if(reg1 & 0x02) ret |= FB_VBLANK_VSYNCING;
+      if(reg4 & 0x80) ret |= FB_VBLANK_HBLANKING;
       (*vcount) = reg3 | ((reg4 & 0x70) << 4);
       (*hcount) = reg2 | ((reg4 & 0x0f) << 8);
    } else if(sisfballowretracecrt1(ivideo)) {
@@ -824,7 +824,7 @@ sisfb_myblank(struct sis_video_info *ivi
    BOOLEAN backlight = TRUE;
 
    switch(blank) {
-   case 0:	/* on */
+   case FB_BLANK_UNBLANK:	/* on */
       sr01  = 0x00;
       sr11  = 0x00;
       sr1f  = 0x00;
@@ -833,7 +833,7 @@ sisfb_myblank(struct sis_video_info *ivi
       p1_13 = 0x00;
       backlight = TRUE;
       break;
-   case 1:	/* blank */
+   case FB_BLANK_NORMAL:	/* blank */
       sr01  = 0x20;
       sr11  = 0x00;
       sr1f  = 0x00;
@@ -842,7 +842,7 @@ sisfb_myblank(struct sis_video_info *ivi
       p1_13 = 0x00;
       backlight = TRUE;
       break;
-   case 2:	/* no vsync */
+   case FB_BLANK_VSYNC_SUSPEND:	/* no vsync */
       sr01  = 0x20;
       sr11  = 0x08;
       sr1f  = 0x80;
@@ -851,7 +851,7 @@ sisfb_myblank(struct sis_video_info *ivi
       p1_13 = 0x80;
       backlight = FALSE;
       break;
-   case 3:	/* no hsync */
+   case FB_BLANK_HSYNC_SUSPEND:	/* no hsync */
       sr01  = 0x20;
       sr11  = 0x08;
       sr1f  = 0x40;
@@ -860,7 +860,7 @@ sisfb_myblank(struct sis_video_info *ivi
       p1_13 = 0x40;
       backlight = FALSE;
       break;
-   case 4:	/* off */
+   case FB_BLANK_POWERDOWN:	/* off */
       sr01  = 0x20;
       sr11  = 0x08;
       sr1f  = 0xc0;
@@ -1566,10 +1566,10 @@ sisfb_do_install_cmap(int con, struct fb
         if(con != ivideo->currcon) return;
 
         if(fb_display[con].cmap.len) {
-		fb_set_cmap(&fb_display[con].cmap, sisfb_setcolreg, info);
+		fb_set_cmap(&fb_display[con].cmap, 1, sisfb_setcolreg, info);
         } else {
 		int size = sisfb_get_cmap_len(&fb_display[con].var);
-		fb_set_cmap(fb_default_cmap(size), sisfb_setcolreg, info);
+		fb_set_cmap(fb_default_cmap(size), 1, sisfb_setcolreg, info);
 	}
 }
 
@@ -1812,11 +1812,10 @@ sisfb_set_par(struct fb_info *info)
         if((err = sisfb_do_set_var(&info->var, 1, info))) {
 		return err;
 	}
-
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
 	sisfb_get_fix(&info->fix, info->currcon, info);
 #else
-	sisfb_get_fix(&info->fix, -1, info);
+      	sisfb_get_fix(&info->fix, -1, info);
 #endif
 	return 0;
 }
@@ -2054,24 +2053,26 @@ sisfb_ioctl(struct inode *inode, struct 
 #endif
 	    struct fb_info *info)
 {
-	struct sis_video_info 	*ivideo = (struct sis_video_info *)info->par;
+	struct sis_video_info	*ivideo = (struct sis_video_info *)info->par;
 	struct sis_memreq 	sismemreq;
 	struct fb_vblank  	sisvbblank;
 	sisfb_info        	x;
 	u32			gpu32 = 0;
-	static int 		count = 0;
-	u32 __user		*argp = (u32 __user *) arg;
+#ifndef __user
+#define __user
+#endif
+	u32 __user 		*argp = (u32 __user *)arg;
 
 	switch (cmd) {
 	   case FBIO_ALLOC:
 		if(!capable(CAP_SYS_RAWIO)) {
 			return -EPERM;
 		}
-		if(copy_from_user(&sismemreq, argp, sizeof(sismemreq))) {
+		if(copy_from_user(&sismemreq, (void __user *)arg, sizeof(sismemreq))) {
 		   	return -EFAULT;
 		}
-        	sis_malloc(&sismemreq);
-		if(copy_to_user(argp, &sismemreq, sizeof(sismemreq))) {
+		sis_malloc(&sismemreq);
+		if(copy_to_user((void __user *)arg, &sismemreq, sizeof(sismemreq))) {
 			sis_free((u32)sismemreq.offset);
 		    	return -EFAULT;
 		}
@@ -2090,7 +2091,7 @@ sisfb_ioctl(struct inode *inode, struct 
 	   case FBIOGET_VBLANK:
 		sisvbblank.count = 0;
 		sisvbblank.flags = sisfb_setupvbblankflags(ivideo, &sisvbblank.vcount, &sisvbblank.hcount);
-		if(copy_to_user(argp, &sisvbblank, sizeof(sisvbblank))) {
+		if(copy_to_user((void __user *)arg, &sisvbblank, sizeof(sisvbblank))) {
 			return -EFAULT;
 		}
 		break;
@@ -2099,7 +2100,7 @@ sisfb_ioctl(struct inode *inode, struct 
 	        return put_user(sizeof(sisfb_info), argp);
 
 	   case SISFB_GET_INFO_OLD:
-	        if(++count < 50) {
+	        if(ivideo->warncount++ < 50) {
 	           printk(KERN_INFO "sisfb: Deprecated ioctl call received - update your application!\n");
 		}
 	   case SISFB_GET_INFO:  /* For communication with X driver */
@@ -2136,13 +2137,13 @@ sisfb_ioctl(struct inode *inode, struct 
 		x.sisfb_tvxpos = (u16)(ivideo->tvxpos + 32);
 		x.sisfb_tvypos = (u16)(ivideo->tvypos + 32);
 
-		if(copy_to_user(argp, &x, sizeof(x))) {
+		if(copy_to_user((void __user *)arg, &x, sizeof(x))) {
 			return -EFAULT;
 		}
 	        break;
 
 	   case SISFB_GET_VBRSTATUS_OLD:
-	   	if(++count < 50) {
+	   	if(ivideo->warncount++ < 50) {
 	           printk(KERN_INFO "sisfb: Deprecated ioctl call received - update your application!\n");
 		}
 	   case SISFB_GET_VBRSTATUS:
@@ -2153,15 +2154,15 @@ sisfb_ioctl(struct inode *inode, struct 
 		}
 
 	   case SISFB_GET_AUTOMAXIMIZE_OLD:
-	   	if(++count < 50) {
+	   	if(ivideo->warncount++ < 50) {
 	           printk(KERN_INFO "sisfb: Deprecated ioctl call received - update your application!\n");
 		}
 	   case SISFB_GET_AUTOMAXIMIZE:
-	        if(ivideo->sisfb_max) return put_user((u32)1, argp);
-		else 	              return put_user((u32)0, argp);
+	        if(ivideo->sisfb_max)	return put_user((u32)1, argp);
+		else			return put_user((u32)0, argp);
 
 	   case SISFB_SET_AUTOMAXIMIZE_OLD:
-	   	if(++count < 50) {
+	   	if(ivideo->warncount++ < 50) {
 		   printk(KERN_INFO "sisfb: Deprecated ioctl call received - update your application!\n");
 		}
 	   case SISFB_SET_AUTOMAXIMIZE:
@@ -2180,7 +2181,8 @@ sisfb_ioctl(struct inode *inode, struct 
 		break;
 
 	   case SISFB_GET_TVPOSOFFSET:
-	        return put_user((u32)(((ivideo->tvxpos+32)<<16)|((ivideo->tvypos+32)&0xffff)), argp);
+	        return put_user((u32)(((ivideo->tvxpos+32)<<16)|((ivideo->tvypos+32)&0xffff)),
+				argp);
 
 	   case SISFB_SET_LOCK:
 		if(copy_from_user(&gpu32, argp, sizeof(gpu32))) {
@@ -2628,29 +2630,29 @@ static BOOLEAN __devinit sisfb_test_DDC1
 static void __devinit sisfb_sense_crt1(struct sis_video_info *ivideo)
 {
     BOOLEAN mustwait = FALSE;
-    u8  SR1F, CR17;
+    u8  sr1F, cr17;
 #ifdef CONFIG_FB_SIS_315
-    u8  CR63=0;
+    u8  cr63=0;
 #endif
     u16 temp = 0xffff;
     int i;
 
-    inSISIDXREG(SISSR,0x1F,SR1F);
+    inSISIDXREG(SISSR,0x1F,sr1F);
     orSISIDXREG(SISSR,0x1F,0x04);
     andSISIDXREG(SISSR,0x1F,0x3F);
-    if(SR1F & 0xc0) mustwait = TRUE;
+    if(sr1F & 0xc0) mustwait = TRUE;
 
 #ifdef CONFIG_FB_SIS_315
     if(ivideo->sisvga_engine == SIS_315_VGA) {
-       inSISIDXREG(SISCR,ivideo->SiS_Pr.SiS_MyCR63,CR63);
-       CR63 &= 0x40;
+       inSISIDXREG(SISCR,ivideo->SiS_Pr.SiS_MyCR63,cr63);
+       cr63 &= 0x40;
        andSISIDXREG(SISCR,ivideo->SiS_Pr.SiS_MyCR63,0xBF);
     }
 #endif
 
-    inSISIDXREG(SISCR,0x17,CR17);
-    CR17 &= 0x80;
-    if(!CR17) {
+    inSISIDXREG(SISCR,0x17,cr17);
+    cr17 &= 0x80;
+    if(!cr17) {
        orSISIDXREG(SISCR,0x17,0x80);
        mustwait = TRUE;
        outSISIDXREG(SISSR, 0x00, 0x01);
@@ -2695,13 +2697,13 @@ static void __devinit sisfb_sense_crt1(s
 
 #ifdef CONFIG_FB_SIS_315
     if(ivideo->sisvga_engine == SIS_315_VGA) {
-       setSISIDXREG(SISCR,ivideo->SiS_Pr.SiS_MyCR63,0xBF,CR63);
+       setSISIDXREG(SISCR,ivideo->SiS_Pr.SiS_MyCR63,0xBF,cr63);
     }
 #endif
 
-    setSISIDXREG(SISCR,0x17,0x7F,CR17);
+    setSISIDXREG(SISCR,0x17,0x7F,cr17);
 
-    outSISIDXREG(SISSR,0x1F,SR1F);
+    outSISIDXREG(SISSR,0x1F,sr1F);
 }
 
 /* Determine and detect attached devices on SiS30x */
@@ -3840,7 +3842,7 @@ sisfb_post_setmode(struct sis_video_info
 }
 
 #ifndef MODULE
-int __init sisfb_setup(char *options)
+SISINITSTATIC int __init sisfb_setup(char *options)
 {
 	char *this_opt;
 	
@@ -3955,19 +3957,22 @@ int __init sisfb_setup(char *options)
 }
 #endif
 
-static void __iomem * __devinit sis_find_rom(struct pci_dev *pdev)
+static UCHAR * __devinit sis_find_rom(struct pci_dev *pdev)
 {
 	struct sis_video_info *ivideo = pci_get_drvdata(pdev);
+	USHORT pciid;
+	int    romptr;
+	UCHAR  *myrombase;
+	u32    temp;
+	SIS_IOTYPE1 *rom_base, *rom;
+
+	if(!(myrombase = vmalloc(65536))) return NULL;
 
 #if defined(__i386__) || defined(__x86_64__)
-        u32  segstart;
-	void __iomem *rom_base, *rom;
-        int  romptr;
-	unsigned short pciid;
 
-        for(segstart=0x000c0000; segstart<0x000f0000; segstart+=0x00001000) {
+        for(temp = 0x000c0000; temp < 0x000f0000; temp += 0x00001000) {
 
-            rom_base = ioremap(segstart, 0x10000);
+            rom_base = ioremap(temp, 0x10000);
 	    if(!rom_base) continue;
 
 	    if((readb(rom_base) != 0x55) || (readb(rom_base + 1) != 0xaa)) {
@@ -3996,17 +4001,18 @@ static void __iomem * __devinit sis_find
 	    }
 
 	    pciid = readb(rom + 6) | (readb(rom + 7) << 8);
-	    if(pciid == ivideo->chip_id) return rom_base;
+	    if(pciid == ivideo->chip_id) {
+	       memcpy_fromio(myrombase, rom_base, 65536);
+	       iounmap(rom_base);
+	       return myrombase;
+	    }
 
 	    iounmap(rom_base);
         }
+
 #else
-	void __iomem *rom_base, *rom, *myrombase = NULL;
-        int  romptr;
-	unsigned short pciid;
-	u32 backup;
 
-	pci_read_config_dword(pdev, PCI_ROM_ADDRESS, &backup);
+	pci_read_config_dword(pdev, PCI_ROM_ADDRESS, &temp);
 	pci_write_config_dword(pdev, PCI_ROM_ADDRESS,
 			(ivideo->video_base & PCI_ROM_ADDRESS_MASK) | PCI_ROM_ADDRESS_ENABLE);
 
@@ -4022,9 +4028,10 @@ static void __iomem * __devinit sis_find
 		    if(pciid == 0x1039) {
 		       pciid = readb(rom + 6) | (readb(rom + 7) << 8);
 		       if(pciid == ivideo->chip_id) {
-		          if((myrombase = vmalloc(65536))) {
-			     memcpy_fromio(myrombase, rom_base, 65536);
-			  }
+			  memcpy_fromio(myrombase, rom_base, 65536);
+			  iounmap(rom_base);
+			  pci_write_config_dword(pdev, PCI_ROM_ADDRESS, temp);
+			  return myrombase;
 		       }
 		    }
 		 }
@@ -4032,15 +4039,17 @@ static void __iomem * __devinit sis_find
 	   }
 	   iounmap(rom_base);
 	}
-        pci_write_config_dword(pdev, PCI_ROM_ADDRESS, backup);
-	if(myrombase) return myrombase;
+        pci_write_config_dword(pdev, PCI_ROM_ADDRESS, temp);
+
 #endif
+
+       	vfree(myrombase);
         return NULL;
 }
 
 #ifdef CONFIG_FB_SIS_300
 static int __devinit
-sisfb_chkbuswidth300(struct pci_dev *pdev, void __iomem *FBAddress)
+sisfb_chkbuswidth300(struct pci_dev *pdev, SIS_IOTYPE1 *FBAddress)
 {
 	struct sis_video_info *ivideo = pci_get_drvdata(pdev);
 	int i, j;
@@ -4083,8 +4092,9 @@ static void __devinit
 sisfb_setramsize300(struct pci_dev *pdev)
 {
 	struct  sis_video_info *ivideo = pci_get_drvdata(pdev);
-	void __iomem *FBAddr = ivideo->sishw_ext.pjVideoMemoryAddress, *Addr;
-	USHORT 	SR13, SR14=0, buswidth, Done, data, TotalCapacity, PhysicalAdrOtherPage=0;
+  	SIS_IOTYPE1 *FBAddr = ivideo->video_vbase;
+	SIS_IOTYPE1 *Addr;
+	USHORT 	sr13, sr14=0, buswidth, Done, data, TotalCapacity, PhysicalAdrOtherPage=0;
 	int     PseudoRankCapacity, PseudoTotalCapacity, PseudoAdrPinCount;
    	int     RankCapacity, AdrPinCount, BankNumHigh, BankNumMid, MB2Bank;
    	int     PageCapacity, PhysicalAdrHigh, PhysicalAdrHalfPage, i, j, k;
@@ -4141,12 +4151,12 @@ sisfb_setramsize300(struct pci_dev *pdev
                           andSISIDXREG(SISSR,0x15,0xFB); /* Test */
                           orSISIDXREG(SISSR,0x15,0x04);  /* Test */
                           TotalCapacity = SiS_DRAMType[k][3] * buswidth;
-                          SR13 = SiS_DRAMType[k][4];
-                          if(buswidth == 4) SR14 = (TotalCapacity - 1) | 0x80;
-                          if(buswidth == 2) SR14 = (TotalCapacity - 1) | 0x40;
-                          if(buswidth == 1) SR14 = (TotalCapacity - 1) | 0x00;
-                          outSISIDXREG(SISSR,0x13,SR13);
-                          outSISIDXREG(SISSR,0x14,SR14);
+                          sr13 = SiS_DRAMType[k][4];
+                          if(buswidth == 4) sr14 = (TotalCapacity - 1) | 0x80;
+                          if(buswidth == 2) sr14 = (TotalCapacity - 1) | 0x40;
+                          if(buswidth == 1) sr14 = (TotalCapacity - 1) | 0x00;
+                          outSISIDXREG(SISSR,0x13,sr13);
+                          outSISIDXREG(SISSR,0x14,sr14);
                           Addr = FBAddr + BankNumHigh * 64 * 1024 + PhysicalAdrHigh;
                           /* *((USHORT *)(Addr)) = (USHORT)PhysicalAdrHigh; */
 			  writew(((USHORT)PhysicalAdrHigh), Addr);
@@ -4307,10 +4317,10 @@ static void __devinit sisfb_post_sis300(
 	} else {
 #endif
 	   /* Need to map max FB size for finding out about RAM size */
-	   ivideo->sishw_ext.pjVideoMemoryAddress = ioremap(ivideo->video_base, 0x4000000);
-	   if(ivideo->sishw_ext.pjVideoMemoryAddress) {
+	   ivideo->video_vbase = ioremap(ivideo->video_base, 0x4000000);
+	   if(ivideo->video_vbase) {
 	      sisfb_setramsize300(pdev);
-	      iounmap(ivideo->sishw_ext.pjVideoMemoryAddress);
+	      iounmap(ivideo->video_vbase);
 	   } else {
 	      printk(KERN_DEBUG "sisfb: Failed to map memory for size detection, assuming 8MB\n");
 	      outSISIDXREG(SISSR,0x13,0x28);  /* ? */
@@ -4696,8 +4706,8 @@ static void __devinit sisfb_post_sis3153
 	andSIDIDXREG(SISSR,0x13,0x00);
 
 	/* Need to map max FB size for finding out about RAM size */
-	ivideo->sishw_ext.pjVideoMemoryAddress = ioremap(ivideo->video_base, 0x4000000);
-	if(ivideo->sishw_ext.pjVideoMemoryAddress) {
+	ivideo->video_vbase = ioremap(ivideo->video_base, 0x4000000);
+	if(ivideo->video_vbase) {
 	   /* Find out about bus width */
 	   if(memtype <= 1) {
 	      outSISIDXREG(SISSR,0x14,0x02);
@@ -4715,7 +4725,7 @@ static void __devinit sisfb_post_sis3153
 	   /* Find out about size */
 
 
-	   iounmap(ivideo->sishw_ext.pjVideoMemoryAddress);
+	   iounmap(ivideo->video_vbase);
 	} else {
 	   printk(KERN_DEBUG "sisfb: Failed to map memory for size detection, assuming 8MB\n");
 	   outSISIDXREG(SISSR,0x14,0x??);  /* 8MB, 64bit default */
@@ -4765,11 +4775,12 @@ int __devinit sisfb_probe(struct pci_dev
 	} else {
 	   struct sis_video_info *countvideo = card_list;
 	   ivideo->cardnumber = 1;
-	   while ((countvideo = countvideo->next) != NULL) ivideo->cardnumber++;
+	   while((countvideo = countvideo->next) != NULL) ivideo->cardnumber++;
 	}
 
 	strncpy(ivideo->myid, chipinfo->chip_name, 30);
 
+	ivideo->warncount = 0;
 	ivideo->chip_id = pdev->device;
 	pci_read_config_byte(pdev, PCI_REVISION_ID, &ivideo->revision_id);
 	ivideo->sishw_ext.jChipRevision = ivideo->revision_id;
@@ -4955,18 +4966,16 @@ int __devinit sisfb_probe(struct pci_dev
 	}
 
 	/* Find out about current video mode */
+	ivideo->modeprechange = 0x03;
 	inSISIDXREG(SISCR,0x34,reg);
 	if(reg & 0x7f) {
 		ivideo->modeprechange = reg & 0x7f;
-	} else {
-		ivideo->modeprechange = 0x03;
+	} else if(sisvga_enabled) {
 #if defined(__i386__) || defined(__x86_64__)
-		{
-			unsigned char __iomem *tt = ioremap(0, 0x1000);
-			if(tt) {
-			   	ivideo->modeprechange = tt[0x449];
-			   	iounmap(tt);
-			}
+		unsigned char SIS_IOTYPE2 *tt = ioremap(0, 0x1000);
+		if(tt) {
+		   	ivideo->modeprechange = readb(tt + 0x449);
+		   	iounmap(tt);
 		}
 #endif
 	}
@@ -4997,18 +5006,11 @@ int __devinit sisfb_probe(struct pci_dev
 #endif
 
 	ivideo->bios_abase = NULL;
-	ivideo->bios_vbase = NULL;
 	if(ivideo->sisfb_userom) {
 	    ivideo->sishw_ext.pjVirtualRomBase = sis_find_rom(pdev);
-#if defined(__i386__) || defined(__x86_64__)
-	    ivideo->bios_vbase = ivideo->sishw_ext.pjVirtualRomBase;	/* mapped */
-#else
-	    ivideo->bios_abase = ivideo->sishw_ext.pjVirtualRomBase;	/* allocated */
-#endif
+	    ivideo->bios_abase = ivideo->sishw_ext.pjVirtualRomBase;
 	    if(ivideo->sishw_ext.pjVirtualRomBase) {
-		printk(KERN_INFO "sisfb: Video ROM found and %s to 0x%p\n",
-			ivideo->bios_vbase ? "mapped" : "copied",
-		        ivideo->sishw_ext.pjVirtualRomBase);
+		printk(KERN_INFO "sisfb: Video ROM found and copied\n");
 		ivideo->sishw_ext.UseROM = TRUE;
 	    } else {
 	        ivideo->sishw_ext.UseROM = FALSE;
@@ -5135,7 +5137,6 @@ int __devinit sisfb_probe(struct pci_dev
 		printk(KERN_ERR "sisfb: Fatal error: Unable to reserve frame buffer memory\n");
 		printk(KERN_ERR "sisfb: Is there another framebuffer driver active?\n");
 		if(ivideo->bios_abase) vfree(ivideo->bios_abase);
-		if(ivideo->bios_vbase) iounmap(ivideo->bios_vbase);
 		pci_set_drvdata(pdev, NULL);
 		kfree(sis_fb_info);
 		return -ENODEV;
@@ -5145,7 +5146,6 @@ int __devinit sisfb_probe(struct pci_dev
 		printk(KERN_ERR "sisfb: Fatal error: Unable to reserve MMIO region\n");
 		release_mem_region(ivideo->video_base, ivideo->video_size);
 		if(ivideo->bios_abase) vfree(ivideo->bios_abase);
-		if(ivideo->bios_vbase) iounmap(ivideo->bios_vbase);
 		pci_set_drvdata(pdev, NULL);
 		kfree(sis_fb_info);
 		return -ENODEV;
@@ -5158,7 +5158,6 @@ int __devinit sisfb_probe(struct pci_dev
 	   	release_mem_region(ivideo->video_base, ivideo->video_size);
 	   	release_mem_region(ivideo->mmio_base, ivideo->mmio_size);
 		if(ivideo->bios_abase) vfree(ivideo->bios_abase);
-		if(ivideo->bios_vbase) iounmap(ivideo->bios_vbase);
 		pci_set_drvdata(pdev, NULL);
 	   	kfree(sis_fb_info);
 	   	return -ENODEV;
@@ -5171,17 +5170,16 @@ int __devinit sisfb_probe(struct pci_dev
 	   	release_mem_region(ivideo->video_base, ivideo->video_size);
 	   	release_mem_region(ivideo->mmio_base, ivideo->mmio_size);
 		if(ivideo->bios_abase) vfree(ivideo->bios_abase);
-		if(ivideo->bios_vbase) iounmap(ivideo->bios_vbase);
 		pci_set_drvdata(pdev, NULL);
 	   	kfree(sis_fb_info);
 	   	return -ENODEV;
 	}
 
-	printk(KERN_INFO "sisfb: Framebuffer at 0x%lx, mapped to 0x%p, size %ldk\n",
-	       	ivideo->video_base, ivideo->video_vbase, ivideo->video_size / 1024);
+	printk(KERN_INFO "sisfb: Framebuffer at 0x%lx, mapped to 0x%lx, size %ldk\n",
+	       	ivideo->video_base, (ULONG)ivideo->video_vbase, ivideo->video_size / 1024);
 
-	printk(KERN_INFO "sisfb: MMIO at 0x%lx, mapped to 0x%p, size %ldk\n",
-	       	ivideo->mmio_base, ivideo->mmio_vbase, ivideo->mmio_size / 1024);
+	printk(KERN_INFO "sisfb: MMIO at 0x%lx, mapped to 0x%lx, size %ldk\n",
+	       	ivideo->mmio_base, (ULONG)ivideo->mmio_vbase, ivideo->mmio_size / 1024);
 
 	if((ivideo->havenoheap = sisfb_heap_init(ivideo))) {
 		printk(KERN_WARNING "sisfb: Failed to initialize offscreen memory heap\n");
@@ -5239,24 +5237,27 @@ int __devinit sisfb_probe(struct pci_dev
 		   inSISIDXREG(SISCR, 0x36, reg);
 		   reg &= 0x0f;
 		   if(ivideo->sisvga_engine == SIS_300_VGA) {
-		      ivideo->sishw_ext.ulCRT2LCDType = sis300paneltype[reg];
+		      ivideo->CRT2LCDType = sis300paneltype[reg];
 		   } else if(ivideo->chip >= SIS_661) {
-		      ivideo->sishw_ext.ulCRT2LCDType = sis661paneltype[reg];
+		      ivideo->CRT2LCDType = sis661paneltype[reg];
 		   } else {
-		      ivideo->sishw_ext.ulCRT2LCDType = sis310paneltype[reg];
+		      ivideo->CRT2LCDType = sis310paneltype[reg];
 		      if((ivideo->chip == SIS_550) && (sisfb_fstn)) {
-		         if((ivideo->sishw_ext.ulCRT2LCDType != LCD_640x480_2) &&
-			    (ivideo->sishw_ext.ulCRT2LCDType != LCD_640x480_3)) {
-		      	    ivideo->sishw_ext.ulCRT2LCDType = LCD_320x480;
+		         if((ivideo->CRT2LCDType != LCD_640x480_2) &&
+			    (ivideo->CRT2LCDType != LCD_640x480_3)) {
+		      	    ivideo->CRT2LCDType = LCD_320x480;
 			 }
 		      }
 		   }
-		   if(ivideo->sishw_ext.ulCRT2LCDType == LCD_UNKNOWN) {
-		      ivideo->sishw_ext.ulCRT2LCDType = LCD_1024x768;
-		      printk(KERN_DEBUG "sisfb: Illegal panel ID (%02x), assuming 1024x768\n", reg);
+		   if(ivideo->CRT2LCDType == LCD_UNKNOWN) {
+		      /* For broken BIOSes: Assume 1024x768, RGB18 */
+		      ivideo->CRT2LCDType = LCD_1024x768;
+		      setSISIDXREG(SISCR,0x36,0xf0,0x02);
+		      setSISIDXREG(SISCR,0x37,0xee,0x01);
+		      printk(KERN_DEBUG "sisfb: Invalid panel ID (%02x), assuming 1024x768, RGB18\n", reg);
 		   }
 		   for(i = 0; i < SIS_LCD_NUMBER; i++) {
-		      if(ivideo->sishw_ext.ulCRT2LCDType == sis_lcd_data[i].lcdtype) {
+		      if(ivideo->CRT2LCDType == sis_lcd_data[i].lcdtype) {
 		         ivideo->lcdxres = sis_lcd_data[i].xres;
 			 ivideo->lcdyres = sis_lcd_data[i].yres;
 			 ivideo->lcddefmodeidx = sis_lcd_data[i].default_mode_idx;
@@ -5459,7 +5460,6 @@ int __devinit sisfb_probe(struct pci_dev
 			release_mem_region(ivideo->video_base, ivideo->video_size);
 			release_mem_region(ivideo->mmio_base, ivideo->mmio_size);
 			if(ivideo->bios_abase) vfree(ivideo->bios_abase);
-			if(ivideo->bios_vbase) iounmap(ivideo->bios_vbase);
 			pci_set_drvdata(pdev, NULL);
 			kfree(sis_fb_info);
 			return -EINVAL;
@@ -5583,7 +5583,6 @@ int __devinit sisfb_probe(struct pci_dev
 			release_mem_region(ivideo->video_base, ivideo->video_size);
 			release_mem_region(ivideo->mmio_base, ivideo->mmio_size);
 			if(ivideo->bios_abase) vfree(ivideo->bios_abase);
-			if(ivideo->bios_vbase) iounmap(ivideo->bios_vbase);
 			pci_set_drvdata(pdev, NULL);
 			kfree(sis_fb_info);
 			return -EINVAL;
@@ -5675,8 +5674,7 @@ static void __devexit sisfb_remove(struc
 	/* Unmap */
 	iounmap(ivideo->video_vbase);
 	iounmap(ivideo->mmio_vbase);
-	if(ivideo->bios_vbase) iounmap(ivideo->bios_vbase);
-	if(ivideo->bios_abase)    vfree(ivideo->bios_abase);
+	if(ivideo->bios_abase) vfree(ivideo->bios_abase);
 
 	/* Release mem regions */
 	release_mem_region(ivideo->video_base, ivideo->video_size);
@@ -5720,15 +5718,15 @@ static struct pci_driver sisfb_driver = 
 	.remove 	= __devexit_p(sisfb_remove)
 };
 
-int __init sisfb_init(void)
+SISINITSTATIC int __init sisfb_init(void)
 {
 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)
 #ifndef MODULE
-	char *option = NULL;
+	char *options = NULL;
 
-	if (fb_get_options("sisfb", &option))
+	if(fb_get_options("sisfb", &options))
 		return -ENODEV;
-	sisfb_setup(option);
+	sisfb_setup(options);
 #endif
 #endif
 	return(pci_module_init(&sisfb_driver));
diff -puN drivers/video/sis/sis_main.h~fbdev-sis-framebuffer-driver-update-1717 drivers/video/sis/sis_main.h
--- 25/drivers/video/sis/sis_main.h~fbdev-sis-framebuffer-driver-update-1717	2004-11-28 01:30:58.877559632 -0800
+++ 25-akpm/drivers/video/sis/sis_main.h	2004-11-28 01:30:58.974544888 -0800
@@ -153,7 +153,7 @@ static struct sis_video_info *card_list 
    now (hoping that nobody is crazy enough to run two
    SiS cards at the same time).
  */
-SIS_HEAP       	sisfb_heap;
+static SIS_HEAP       	sisfb_heap;
 
 #define MD_SIS300 1
 #define MD_SIS315 2
@@ -234,78 +234,82 @@ static const struct _sisbios_mode {
 	{"960x540x16",   {0x1e,0x1e}, 0x0000, 0x0000,  960,  540, 16, 1, 120, 33,           MD_SIS315},
 	{"960x540x24",   {0x1f,0x1f}, 0x0000, 0x0000,  960,  540, 32, 1, 120, 33,           MD_SIS315},
 	{"960x540x32",   {0x1f,0x1f}, 0x0000, 0x0000,  960,  540, 32, 1, 120, 33,           MD_SIS315},
+	{"960x600x8",    {0x20,0x20}, 0x0000, 0x0000,  960,  600,  8, 1, 120, 37,           MD_SIS315},
+/*60*/	{"960x600x16",   {0x21,0x21}, 0x0000, 0x0000,  960,  600, 16, 1, 120, 37,           MD_SIS315},
+	{"960x600x24",   {0x22,0x22}, 0x0000, 0x0000,  960,  600, 32, 1, 120, 37,           MD_SIS315},
+	{"960x600x32",   {0x22,0x22}, 0x0000, 0x0000,  960,  600, 32, 1, 120, 37,           MD_SIS315},
 	{"1024x576x8",   {0x71,0x71}, 0x0000, 0x0000, 1024,  576,  8, 1, 128, 36, MD_SIS300|MD_SIS315},
-/*60*/	{"1024x576x16",  {0x74,0x74}, 0x0000, 0x0000, 1024,  576, 16, 1, 128, 36, MD_SIS300|MD_SIS315},
+	{"1024x576x16",  {0x74,0x74}, 0x0000, 0x0000, 1024,  576, 16, 1, 128, 36, MD_SIS300|MD_SIS315},
 	{"1024x576x24",  {0x77,0x77}, 0x0000, 0x0000, 1024,  576, 32, 1, 128, 36, MD_SIS300|MD_SIS315},
 	{"1024x576x32",  {0x77,0x77}, 0x0000, 0x0000, 1024,  576, 32, 1, 128, 36, MD_SIS300|MD_SIS315},
 	{"1024x600x8",   {0x20,0x20}, 0x0000, 0x0000, 1024,  600,  8, 1, 128, 37, MD_SIS300          },
 	{"1024x600x16",  {0x21,0x21}, 0x0000, 0x0000, 1024,  600, 16, 1, 128, 37, MD_SIS300          },
 	{"1024x600x24",  {0x22,0x22}, 0x0000, 0x0000, 1024,  600, 32, 1, 128, 37, MD_SIS300          },
-	{"1024x600x32",  {0x22,0x22}, 0x0000, 0x0000, 1024,  600, 32, 1, 128, 37, MD_SIS300          },
+/*70*/	{"1024x600x32",  {0x22,0x22}, 0x0000, 0x0000, 1024,  600, 32, 1, 128, 37, MD_SIS300          },
 	{"1024x768x8",   {0x38,0x38}, 0x0105, 0x0105, 1024,  768,  8, 2, 128, 48, MD_SIS300|MD_SIS315},
 	{"1024x768x16",  {0x4a,0x4a}, 0x0117, 0x0117, 1024,  768, 16, 2, 128, 48, MD_SIS300|MD_SIS315},
 	{"1024x768x24",  {0x64,0x64}, 0x013c, 0x0118, 1024,  768, 32, 2, 128, 48, MD_SIS300|MD_SIS315},
-/*70*/	{"1024x768x32",  {0x64,0x64}, 0x013c, 0x0118, 1024,  768, 32, 2, 128, 48, MD_SIS300|MD_SIS315},
+	{"1024x768x32",  {0x64,0x64}, 0x013c, 0x0118, 1024,  768, 32, 2, 128, 48, MD_SIS300|MD_SIS315},
 	{"1152x768x8",   {0x23,0x23}, 0x0000, 0x0000, 1152,  768,  8, 1, 144, 48, MD_SIS300          },
 	{"1152x768x16",  {0x24,0x24}, 0x0000, 0x0000, 1152,  768, 16, 1, 144, 48, MD_SIS300          },
 	{"1152x768x24",  {0x25,0x25}, 0x0000, 0x0000, 1152,  768, 32, 1, 144, 48, MD_SIS300          },
 	{"1152x768x32",  {0x25,0x25}, 0x0000, 0x0000, 1152,  768, 32, 1, 144, 48, MD_SIS300          },
 	{"1152x864x8",   {0x29,0x29}, 0x0000, 0x0000, 1152,  864,  8, 1, 144, 54, MD_SIS300|MD_SIS315},
-	{"1152x864x16",  {0x2a,0x2a}, 0x0000, 0x0000, 1152,  864, 16, 1, 144, 54, MD_SIS300|MD_SIS315},
+/*80*/	{"1152x864x16",  {0x2a,0x2a}, 0x0000, 0x0000, 1152,  864, 16, 1, 144, 54, MD_SIS300|MD_SIS315},
 	{"1152x864x24",  {0x2b,0x2b}, 0x0000, 0x0000, 1152,  864, 32, 1, 144, 54, MD_SIS300|MD_SIS315},
 	{"1152x864x32",  {0x2b,0x2b}, 0x0000, 0x0000, 1152,  864, 32, 1, 144, 54, MD_SIS300|MD_SIS315},
 	{"1280x720x8",   {0x79,0x79}, 0x0000, 0x0000, 1280,  720,  8, 1, 160, 45, MD_SIS300|MD_SIS315},
-/*80*/	{"1280x720x16",  {0x75,0x75}, 0x0000, 0x0000, 1280,  720, 16, 1, 160, 45, MD_SIS300|MD_SIS315},
+	{"1280x720x16",  {0x75,0x75}, 0x0000, 0x0000, 1280,  720, 16, 1, 160, 45, MD_SIS300|MD_SIS315},
 	{"1280x720x24",  {0x78,0x78}, 0x0000, 0x0000, 1280,  720, 32, 1, 160, 45, MD_SIS300|MD_SIS315},
 	{"1280x720x32",  {0x78,0x78}, 0x0000, 0x0000, 1280,  720, 32, 1, 160, 45, MD_SIS300|MD_SIS315},
 	{"1280x768x8",   {0x55,0x23}, 0x0000, 0x0000, 1280,  768,  8, 1, 160, 48, MD_SIS300|MD_SIS315},
 	{"1280x768x16",  {0x5a,0x24}, 0x0000, 0x0000, 1280,  768, 16, 1, 160, 48, MD_SIS300|MD_SIS315},
 	{"1280x768x24",  {0x5b,0x25}, 0x0000, 0x0000, 1280,  768, 32, 1, 160, 48, MD_SIS300|MD_SIS315},
-	{"1280x768x32",  {0x5b,0x25}, 0x0000, 0x0000, 1280,  768, 32, 1, 160, 48, MD_SIS300|MD_SIS315},
+/*90*/	{"1280x768x32",  {0x5b,0x25}, 0x0000, 0x0000, 1280,  768, 32, 1, 160, 48, MD_SIS300|MD_SIS315},
 	{"1280x800x8",   {0x14,0x14}, 0x0000, 0x0000, 1280,  800,  8, 1, 160, 50,           MD_SIS315},
 	{"1280x800x16",  {0x15,0x15}, 0x0000, 0x0000, 1280,  800, 16, 1, 160, 50,           MD_SIS315},
 	{"1280x800x24",  {0x16,0x16}, 0x0000, 0x0000, 1280,  800, 32, 1, 160, 50,           MD_SIS315},
-/*90*/	{"1280x800x32",  {0x16,0x16}, 0x0000, 0x0000, 1280,  800, 32, 1, 160, 50,           MD_SIS315},
+	{"1280x800x32",  {0x16,0x16}, 0x0000, 0x0000, 1280,  800, 32, 1, 160, 50,           MD_SIS315},
 	{"1280x960x8",   {0x7c,0x7c}, 0x0000, 0x0000, 1280,  960,  8, 1, 160, 60, MD_SIS300|MD_SIS315},
 	{"1280x960x16",  {0x7d,0x7d}, 0x0000, 0x0000, 1280,  960, 16, 1, 160, 60, MD_SIS300|MD_SIS315},
 	{"1280x960x24",  {0x7e,0x7e}, 0x0000, 0x0000, 1280,  960, 32, 1, 160, 60, MD_SIS300|MD_SIS315},
 	{"1280x960x32",  {0x7e,0x7e}, 0x0000, 0x0000, 1280,  960, 32, 1, 160, 60, MD_SIS300|MD_SIS315},
 	{"1280x1024x8",  {0x3a,0x3a}, 0x0107, 0x0107, 1280, 1024,  8, 2, 160, 64, MD_SIS300|MD_SIS315},
-	{"1280x1024x16", {0x4d,0x4d}, 0x011a, 0x011a, 1280, 1024, 16, 2, 160, 64, MD_SIS300|MD_SIS315},
+/*100*/	{"1280x1024x16", {0x4d,0x4d}, 0x011a, 0x011a, 1280, 1024, 16, 2, 160, 64, MD_SIS300|MD_SIS315},
 	{"1280x1024x24", {0x65,0x65}, 0x013d, 0x011b, 1280, 1024, 32, 2, 160, 64, MD_SIS300|MD_SIS315},
 	{"1280x1024x32", {0x65,0x65}, 0x013d, 0x011b, 1280, 1024, 32, 2, 160, 64, MD_SIS300|MD_SIS315},
 	{"1360x768x8",   {0x48,0x48}, 0x0000, 0x0000, 1360,  768,  8, 1, 170, 48, MD_SIS300|MD_SIS315},
-/*100*/	{"1360x768x16",  {0x4b,0x4b}, 0x0000, 0x0000, 1360,  768, 16, 1, 170, 48, MD_SIS300|MD_SIS315},
+	{"1360x768x16",  {0x4b,0x4b}, 0x0000, 0x0000, 1360,  768, 16, 1, 170, 48, MD_SIS300|MD_SIS315},
 	{"1360x768x24",  {0x4e,0x4e}, 0x0000, 0x0000, 1360,  768, 32, 1, 170, 48, MD_SIS300|MD_SIS315},
 	{"1360x768x32",  {0x4e,0x4e}, 0x0000, 0x0000, 1360,  768, 32, 1, 170, 48, MD_SIS300|MD_SIS315},
 	{"1360x1024x8",  {0x67,0x67}, 0x0000, 0x0000, 1360, 1024,  8, 1, 170, 64, MD_SIS300          },
 	{"1360x1024x16", {0x6f,0x6f}, 0x0000, 0x0000, 1360, 1024, 16, 1, 170, 64, MD_SIS300          },
 	{"1360x1024x24", {0x72,0x72}, 0x0000, 0x0000, 1360, 1024, 32, 1, 170, 64, MD_SIS300          },
-	{"1360x1024x32", {0x72,0x72}, 0x0000, 0x0000, 1360, 1024, 32, 1, 170, 64, MD_SIS300          },
+/*110*/	{"1360x1024x32", {0x72,0x72}, 0x0000, 0x0000, 1360, 1024, 32, 1, 170, 64, MD_SIS300          },
 	{"1400x1050x8",  {0x26,0x26}, 0x0000, 0x0000, 1400, 1050,  8, 1, 175, 65,           MD_SIS315},
 	{"1400x1050x16", {0x27,0x27}, 0x0000, 0x0000, 1400, 1050, 16, 1, 175, 65,           MD_SIS315},
 	{"1400x1050x24", {0x28,0x28}, 0x0000, 0x0000, 1400, 1050, 32, 1, 175, 65,           MD_SIS315},
-/*110*/	{"1400x1050x32", {0x28,0x28}, 0x0000, 0x0000, 1400, 1050, 32, 1, 175, 65,           MD_SIS315},
+	{"1400x1050x32", {0x28,0x28}, 0x0000, 0x0000, 1400, 1050, 32, 1, 175, 65,           MD_SIS315},
 	{"1600x1200x8",  {0x3c,0x3c}, 0x0130, 0x011c, 1600, 1200,  8, 1, 200, 75, MD_SIS300|MD_SIS315},
 	{"1600x1200x16", {0x3d,0x3d}, 0x0131, 0x011e, 1600, 1200, 16, 1, 200, 75, MD_SIS300|MD_SIS315},
 	{"1600x1200x24", {0x66,0x66}, 0x013e, 0x011f, 1600, 1200, 32, 1, 200, 75, MD_SIS300|MD_SIS315},
 	{"1600x1200x32", {0x66,0x66}, 0x013e, 0x011f, 1600, 1200, 32, 1, 200, 75, MD_SIS300|MD_SIS315},
 	{"1680x1050x8",  {0x17,0x17}, 0x0000, 0x0000, 1680, 1050,  8, 1, 210, 65,           MD_SIS315},
-	{"1680x1050x16", {0x18,0x18}, 0x0000, 0x0000, 1680, 1050, 16, 1, 210, 65,           MD_SIS315},
+/*120*/	{"1680x1050x16", {0x18,0x18}, 0x0000, 0x0000, 1680, 1050, 16, 1, 210, 65,           MD_SIS315},
 	{"1680x1050x24", {0x19,0x19}, 0x0000, 0x0000, 1680, 1050, 32, 1, 210, 65,           MD_SIS315},
 	{"1680x1050x32", {0x19,0x19}, 0x0000, 0x0000, 1680, 1050, 32, 1, 210, 65,           MD_SIS315},
 	{"1920x1080x8",  {0x2c,0x2c}, 0x0000, 0x0000, 1920, 1080,  8, 1, 240, 67,           MD_SIS315},
-/*120*/	{"1920x1080x16", {0x2d,0x2d}, 0x0000, 0x0000, 1920, 1080, 16, 1, 240, 67,           MD_SIS315},
+	{"1920x1080x16", {0x2d,0x2d}, 0x0000, 0x0000, 1920, 1080, 16, 1, 240, 67,           MD_SIS315},
 	{"1920x1080x24", {0x73,0x73}, 0x0000, 0x0000, 1920, 1080, 32, 1, 240, 67,           MD_SIS315},
 	{"1920x1080x32", {0x73,0x73}, 0x0000, 0x0000, 1920, 1080, 32, 1, 240, 67,           MD_SIS315},
 	{"1920x1440x8",  {0x68,0x68}, 0x013f, 0x0000, 1920, 1440,  8, 1, 240, 75, MD_SIS300|MD_SIS315},
 	{"1920x1440x16", {0x69,0x69}, 0x0140, 0x0000, 1920, 1440, 16, 1, 240, 75, MD_SIS300|MD_SIS315},
 	{"1920x1440x24", {0x6b,0x6b}, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, MD_SIS300|MD_SIS315},
-	{"1920x1440x32", {0x6b,0x6b}, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, MD_SIS300|MD_SIS315},
+/*130*/	{"1920x1440x32", {0x6b,0x6b}, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, MD_SIS300|MD_SIS315},
 	{"2048x1536x8",  {0x6c,0x6c}, 0x0000, 0x0000, 2048, 1536,  8, 1, 256, 96,           MD_SIS315},
 	{"2048x1536x16", {0x6d,0x6d}, 0x0000, 0x0000, 2048, 1536, 16, 1, 256, 96,           MD_SIS315},
 	{"2048x1536x24", {0x6e,0x6e}, 0x0000, 0x0000, 2048, 1536, 32, 1, 256, 96,           MD_SIS315},
-/*130*/	{"2048x1536x32", {0x6e,0x6e}, 0x0000, 0x0000, 2048, 1536, 32, 1, 256, 96,           MD_SIS315},
+	{"2048x1536x32", {0x6e,0x6e}, 0x0000, 0x0000, 2048, 1536, 32, 1, 256, 96,           MD_SIS315},
 	{"\0", {0x00,0x00}, 0, 0, 0, 0, 0, 0, 0}
 };
 
@@ -318,37 +322,37 @@ static const struct _sis_lcd_data {
 } sis_lcd_data[] = {
 	{ LCD_640x480,    640,  480,  23 },
 	{ LCD_800x600,    800,  600,  43 },
-	{ LCD_1024x600,  1024,  600,  63 },
-	{ LCD_1024x768,  1024,  768,  67 },
-	{ LCD_1152x768,  1152,  768,  71 },
-	{ LCD_1152x864,  1152,  864,  75 },
-	{ LCD_1280x720,  1280,  720,  79 },
-	{ LCD_1280x768,  1280,  768,  83 },
-	{ LCD_1280x800,  1280,  800,  87 },
-	{ LCD_1280x960,  1280,  960,  91 },
-	{ LCD_1280x1024, 1280, 1024,  95 },
-	{ LCD_1400x1050, 1400, 1050, 107 },
-	{ LCD_1680x1050, 1680, 1050, 115 },
-	{ LCD_1600x1200, 1600, 1200, 111 },
+	{ LCD_1024x600,  1024,  600,  67 },
+	{ LCD_1024x768,  1024,  768,  71 },
+	{ LCD_1152x768,  1152,  768,  75 },
+	{ LCD_1152x864,  1152,  864,  79 },
+	{ LCD_1280x720,  1280,  720,  83 },
+	{ LCD_1280x768,  1280,  768,  87 },
+	{ LCD_1280x800,  1280,  800,  91 },
+	{ LCD_1280x960,  1280,  960,  95 },
+	{ LCD_1280x1024, 1280, 1024,  99 },
+	{ LCD_1400x1050, 1400, 1050, 111 },
+	{ LCD_1680x1050, 1680, 1050, 119 },
+	{ LCD_1600x1200, 1600, 1200, 115 },
 	{ LCD_640x480_2,  640,  480,  23 },
 	{ LCD_640x480_3,  640,  480,  23 },
 	{ LCD_320x480,    320,  480,   9 },
 };
 
 /* CR36 evaluation */
-const USHORT sis300paneltype[] =
+static const USHORT sis300paneltype[] =
     { LCD_UNKNOWN,   LCD_800x600,   LCD_1024x768,  LCD_1280x1024,
       LCD_1280x960,  LCD_640x480,   LCD_1024x600,  LCD_1152x768,
       LCD_UNKNOWN,   LCD_UNKNOWN,   LCD_UNKNOWN,   LCD_UNKNOWN,
       LCD_UNKNOWN,   LCD_UNKNOWN,   LCD_UNKNOWN,   LCD_UNKNOWN };
 
-const USHORT sis310paneltype[] =
+static const USHORT sis310paneltype[] =
     { LCD_UNKNOWN,   LCD_800x600,   LCD_1024x768,  LCD_1280x1024,
       LCD_640x480,   LCD_1024x600,  LCD_1152x864,  LCD_1280x960,
       LCD_1152x768,  LCD_1400x1050, LCD_1280x768,  LCD_1600x1200,
       LCD_640x480_2, LCD_640x480_3, LCD_UNKNOWN,   LCD_UNKNOWN };
 
-const USHORT sis661paneltype[] =
+static const USHORT sis661paneltype[] =
     { LCD_UNKNOWN,   LCD_800x600,   LCD_1024x768,  LCD_1280x1024,
       LCD_640x480,   LCD_1024x600,  LCD_1152x864,  LCD_1280x960,
       LCD_1152x768,  LCD_1400x1050, LCD_1280x768,  LCD_1600x1200,
@@ -426,13 +430,14 @@ static const struct _sis_vrate {
 	{1,  848,  480,  39,  TRUE}, {2,  848,  480,  60,  TRUE},
 	{1,  856,  480,  39,  TRUE}, {2,  856,  480,  60,  TRUE},
 	{1,  960,  540,  60,  TRUE},
+	{1,  960,  600,  60,  TRUE},
 	{1, 1024,  576,  60,  TRUE}, {2, 1024,  576,  75,  TRUE}, {3, 1024,  576,  85,  TRUE},
 	{1, 1024,  600,  60,  TRUE},
 	{1, 1024,  768,  43,  TRUE}, {2, 1024,  768,  60,  TRUE}, {3, 1024,  768,  70, FALSE},
 	{4, 1024,  768,  75, FALSE}, {5, 1024,  768,  85,  TRUE}, {6, 1024,  768, 100,  TRUE},
 	{7, 1024,  768, 120,  TRUE},
 	{1, 1152,  768,  60,  TRUE},
-	{1, 1152,  864,  75,  TRUE}, {2, 1152,  864,  84,  TRUE},
+	{1, 1152,  864,  60,  TRUE}, {1, 1152,  864,  75,  TRUE}, {2, 1152,  864,  84,  TRUE},
 	{1, 1280,  720,  60,  TRUE}, {2, 1280,  720,  75,  TRUE}, {3, 1280,  720,  85,  TRUE},
 	{1, 1280,  768,  60,  TRUE},
 	{1, 1280,  800,  60,  TRUE},
@@ -800,11 +805,11 @@ static const struct _sis_TV_filter {
 
 /* Interface used by the world */
 #ifndef MODULE
-int             sisfb_setup(char *options);
+SISINITSTATIC int sisfb_setup(char *options);
 #endif
 
 /* Interface to the low level console driver */
-int             sisfb_init(void);
+SISINITSTATIC int sisfb_init(void);
 
 
 /* fbdev routines */
@@ -880,7 +885,6 @@ static int      sisfb_do_set_var(struct 
 		      	struct fb_info *info);
 static void     sisfb_pre_setmode(struct sis_video_info *ivideo);
 static void     sisfb_post_setmode(struct sis_video_info *ivideo);
-static void __iomem *sis_find_rom(struct pci_dev *pdev);
 static BOOLEAN  sisfb_CheckVBRetrace(struct sis_video_info *ivideo);
 static BOOLEAN  sisfbcheckvretracecrt2(struct sis_video_info *ivideo);
 static BOOLEAN  sisfbcheckvretracecrt1(struct sis_video_info *ivideo);
@@ -908,7 +912,6 @@ static void     SiS_Sense30x(struct sis_
 static void     SiS_SenseCh(struct sis_video_info *ivideo);
 
 /* Routines from init.c/init301.c */
-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);
diff -puN drivers/video/sis/vgatypes.h~fbdev-sis-framebuffer-driver-update-1717 drivers/video/sis/vgatypes.h
--- 25/drivers/video/sis/vgatypes.h~fbdev-sis-framebuffer-driver-update-1717	2004-11-28 01:30:58.878559480 -0800
+++ 25-akpm/drivers/video/sis/vgatypes.h	2004-11-28 01:30:58.976544584 -0800
@@ -35,7 +35,7 @@
  * * 3) 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 EXPRESSED OR
+ * * 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,
@@ -53,13 +53,9 @@
 #ifndef _VGATYPES_
 #define _VGATYPES_
 
-#ifdef LINUX_XF86
-#include "xf86Version.h"
-#include "xf86Pci.h"
-#endif
-
 #ifdef LINUX_KERNEL  /* We don't want the X driver to depend on kernel source */
 #include <linux/ioctl.h>
+#include <linux/version.h>
 #endif
 
 #ifndef FALSE
@@ -99,15 +95,18 @@ typedef unsigned long ULONG;
 #endif
 
 #ifndef BOOLEAN
-typedef UCHAR BOOLEAN;
+typedef unsigned char BOOLEAN;
 #endif
 
-#ifndef bool
-typedef UCHAR bool;
-#endif
+#define SISIOMEMTYPE
 
 #ifdef LINUX_KERNEL
 typedef unsigned long SISIOADDRESS;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)
+#include <linux/types.h>  /* Need __iomem */
+#undef SISIOMEMTYPE
+#define SISIOMEMTYPE __iomem
+#endif
 #endif
 
 #ifdef LINUX_XF86
@@ -143,55 +142,26 @@ enum _SIS_CHIP_TYPE {
     MAX_SIS_CHIP
 };
 
-#ifdef LINUX_KERNEL
-enum _SIS_LCD_TYPE {
-    LCD_INVALID = 0,
-    LCD_800x600,
-    LCD_1024x768,
-    LCD_1280x1024,
-    LCD_1280x960,
-    LCD_640x480,
-    LCD_1600x1200,
-    LCD_1920x1440,
-    LCD_2048x1536,
-    LCD_320x480,       /* FSTN */
-    LCD_1400x1050,
-    LCD_1152x864,
-    LCD_1152x768,
-    LCD_1280x768,
-    LCD_1024x600,
-    LCD_640x480_2,     /* DSTN */
-    LCD_640x480_3,     /* DSTN */
-    LCD_848x480,
-    LCD_1280x800,
-    LCD_1680x1050,
-    LCD_1280x720,
-    LCD_CUSTOM,
-    LCD_UNKNOWN
-};
-typedef unsigned int SIS_LCD_TYPE;
-#endif
-
 #ifndef SIS_HW_INFO
-
 typedef struct _SIS_HW_INFO  SIS_HW_INFO, *PSIS_HW_INFO;
 
-typedef BOOLEAN (*PSIS_QUERYSPACE)   (PSIS_HW_INFO, ULONG, ULONG, ULONG *);
-
 struct _SIS_HW_INFO
 {
 #ifdef LINUX_XF86
     PCITAG PciTag;		 /* PCI Tag */
 #endif
 
-    UCHAR  *pjVirtualRomBase;    /* ROM image */
+    UCHAR *pjVirtualRomBase;	 /* ROM image */
 
     BOOLEAN UseROM;		 /* Use the ROM image if provided */
 
-    UCHAR  *pjVideoMemoryAddress;/* base virtual memory address */
+#ifdef LINUX_KERNEL
+    UCHAR SISIOMEMTYPE *pjVideoMemoryAddress;
+    				 /* base virtual memory address */
                                  /* of Linear VGA memory */
 
     ULONG  ulVideoMemorySize;    /* size, in bytes, of the memory on the board */
+#endif
 
     SISIOADDRESS ulIOAddress;    /* base I/O address of VGA ports (0x3B0; relocated) */
 
@@ -201,11 +171,6 @@ struct _SIS_HW_INFO
     UCHAR  jChipRevision;        /* Used to Identify SiS Graphics Chip Revision */
 
     BOOLEAN bIntegratedMMEnabled;/* supporting integration MM enable */
-
-#ifdef LINUX_KERNEL
-    ULONG  ulCRT2LCDType;        /* defined in the data structure type */
-                                 /* "SIS_LCD_TYPE" */
-#endif
 };
 #endif
 
diff -puN drivers/video/sis/vstruct.h~fbdev-sis-framebuffer-driver-update-1717 drivers/video/sis/vstruct.h
--- 25/drivers/video/sis/vstruct.h~fbdev-sis-framebuffer-driver-update-1717	2004-11-28 01:30:58.880559176 -0800
+++ 25-akpm/drivers/video/sis/vstruct.h	2004-11-28 01:30:58.977544432 -0800
@@ -35,7 +35,7 @@
  * * 3) 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 EXPRESSED OR
+ * * 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,
@@ -50,12 +50,6 @@
  *
  */
 
-#ifdef _INIT_
-#define EXTERN
-#else
-#define EXTERN extern
-#endif /* _INIT_ */
-
 #ifndef _VSTRUCT_
 #define _VSTRUCT_
 
@@ -286,7 +280,7 @@ typedef struct _SiS_Private
 	USHORT SiS_IF_DEF_FSTN;
 	USHORT SiS_SysFlags;
 	UCHAR  SiS_VGAINFO;
-#ifndef LINUX_KERNEL
+#ifdef LINUX_XF86
         USHORT SiS_CP1, SiS_CP2, SiS_CP3, SiS_CP4;
 #endif
 	BOOLEAN SiS_UseROM;
@@ -304,6 +298,7 @@ typedef struct _SiS_Private
 	BOOLEAN HaveEMILCD;
 	BOOLEAN OverruleEMI;
 	UCHAR  EMI_30,EMI_31,EMI_32,EMI_33;
+	USHORT SiS_EMIOffset;
 	SHORT  PDC, PDCA;
 	UCHAR  SiS_MyCR63;
 	USHORT SiS_CRT1Mode;
@@ -358,7 +353,7 @@ typedef struct _SiS_Private
 	USHORT SiS_PanelMin301;
 
 	const SiS_StStruct          *SiS_SModeIDTable;
-	SiS_StandTableStruct        *SiS_StandTable;
+	const SiS_StandTableStruct  *SiS_StandTable;
 	const SiS_ExtStruct         *SiS_EModeIDTable;
 	const SiS_Ext2Struct        *SiS_RefIndex;
 	const SiS_VBModeStruct      *SiS_VBModeIDTable;
@@ -374,7 +369,7 @@ typedef struct _SiS_Private
 	const UCHAR                 *pSiS_SoftSetting;
 
 	const DRAM4Type *SiS_SR15; /* pointer : point to array */
-#ifndef LINUX_XF86
+#ifdef LINUX_KERNEL
 	UCHAR *pSiS_SR07;
 	const DRAM4Type *SiS_CR40; /* pointer : point to array */
 	UCHAR *SiS_CR49;
@@ -420,8 +415,8 @@ typedef struct _SiS_Private
 	const SiS_LCDDataStruct  *SiS_LCD1280x720Data;
 	const SiS_LCDDataStruct  *SiS_StLCD1280x768_2Data;
 	const SiS_LCDDataStruct  *SiS_ExtLCD1280x768_2Data;
-	const SiS_LCDDataStruct  *SiS_LCD1280x768_3Data;
 	const SiS_LCDDataStruct  *SiS_LCD1280x800Data;
+	const SiS_LCDDataStruct  *SiS_LCD1280x800_2Data;
 	const SiS_LCDDataStruct  *SiS_LCD1280x960Data;
 	const SiS_LCDDataStruct  *SiS_ExtLCD1280x1024Data;
 	const SiS_LCDDataStruct  *SiS_St2LCD1280x1024Data;
@@ -663,6 +658,8 @@ typedef struct _SiS_Private
 	BOOLEAN CP_HaveCustomData;
 	int     CP_PreferredX, CP_PreferredY, CP_PreferredIndex;
 	int	CP_MaxX, CP_MaxY, CP_MaxClock;
+	UCHAR   CP_PrefSR2B, CP_PrefSR2C;
+	USHORT  CP_PrefClock;
 	BOOLEAN CP_Supports64048075;
 	int     CP_HDisplay[7], CP_VDisplay[7];	/* For Custom LCD panel dimensions */
     	int     CP_HTotal[7], CP_VTotal[7];
diff -puN include/video/sisfb.h~fbdev-sis-framebuffer-driver-update-1717 include/video/sisfb.h
_