[PATCH] sisfb update
authorThomas Winischhofer <thomas@winischhofer.net>
Fri, 9 Sep 2005 20:04:45 +0000 (13:04 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Fri, 9 Sep 2005 20:58:01 +0000 (13:58 -0700)
This lifts sisfb from version 1.7.17 to version 1.8.9. Changes include:

- Added support for XGI V3XT, V5, V8, Z7 chipsets, including POSTing of
  all of these chipsets.

- Added support for latest SiS chipsets (761).

- Added support for SiS76x memory "hybrid" mode.

- Added support for new LCD resolutions (eg 1280x854, 856x480).

- Fixed support for 320x240 STN panels (for embedded devices).

- Fixed many HDTV modes (525p, 750p, 1080i).

- Fixed PCI config register reading/writing to use proper kernel
  functions for this purpose.

- Fixed PCI ROM handling to use the kernel's proper functions.

- Removed lots of "typedef"s.

- Removed lots of code which was for X.org/XFree86 only.

- Fixed coding style in many places.

- Removed lots of 2.4 cruft.

- Reduced stack size by unifying two previously separate structs into
  one.

- Added new hooks for memory allocation (for DRM).  Now the driver can
  truly handle multiple cards, including memory management.

- Fixed numerous minor bugs.

Signed-off-by: Thomas Winischhofer <thomas@winischhofer.net>
Cc: "Antonino A. Daplas" <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
22 files changed:
drivers/video/Kconfig
drivers/video/sis/300vtbl.h
drivers/video/sis/310vtbl.h
drivers/video/sis/Makefile
drivers/video/sis/init.c
drivers/video/sis/init.h
drivers/video/sis/init301.c
drivers/video/sis/init301.h
drivers/video/sis/initdef.h
drivers/video/sis/initextlfb.c [new file with mode: 0644]
drivers/video/sis/oem300.h
drivers/video/sis/oem310.h
drivers/video/sis/osdef.h
drivers/video/sis/sis.h
drivers/video/sis/sis_accel.c
drivers/video/sis/sis_accel.h
drivers/video/sis/sis_main.c
drivers/video/sis/sis_main.h
drivers/video/sis/vgatypes.h
drivers/video/sis/vstruct.h
include/linux/fb.h
include/video/sisfb.h

index 544c717..e906b54 100644 (file)
@@ -1079,15 +1079,16 @@ config FB_SAVAGE_ACCEL
           choose N here.
 
 config FB_SIS
-       tristate "SiS acceleration"
+       tristate "SiS/XGI display support"
        depends on FB && PCI
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
        select FB_SOFT_CURSOR
        help
-         This is the frame buffer device driver for the SiS 300, 315 and
-         330 series VGA chipsets. Specs available at <http://www.sis.com>
+         This is the frame buffer device driver for the SiS 300, 315, 330
+         and 340 series as well as XGI V3XT, V5, V8, Z7 graphics chipsets.
+         Specs available at <http://www.sis.com> and <http://www.xgitech.com>.
 
          To compile this driver as a module, choose M here; the module
          will be called sisfb.
@@ -1099,11 +1100,12 @@ config FB_SIS_300
          Say Y here to support use of the SiS 300/305, 540, 630 and 730.
 
 config FB_SIS_315
-       bool "SiS 315/330 series support"
+       bool "SiS 315/330/340 series and XGI support"
        depends on FB_SIS
        help
-         Say Y here to support use of the SiS 315 and 330 series
-         (315/H/PRO, 55x, 650, 651, 740, 330, 661, 741, 760).
+         Say Y here to support use of the SiS 315, 330 and 340 series
+         (315/H/PRO, 55x, 650, 651, 740, 330, 661, 741, 760, 761) as well
+         as XGI V3XT, V5, V8 and Z7.
 
 config FB_NEOMAGIC
        tristate "NeoMagic display support"
index b6d5c71..e4b4a26 100644 (file)
@@ -3,7 +3,7 @@
 /*
  * Register settings for SiS 300 series
  *
- * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
  *
  * If distributed as part of the Linux kernel, the following license terms
  * apply:
  *
  */
 
-static const SiS_StStruct  SiS300_SModeIDTable[] =
-{
-       {0x01,0x9208,0x01,0x00,0x00,0x00,0x00,0x00, 0},
-       {0x01,0x1210,0x14,0x01,0x01,0x00,0x00,0x00, 0},
-       {0x01,0x1010,0x17,0x02,0x02,0x00,0x00,0x00, 0},
-       {0x03,0x8208,0x03,0x00,0x00,0x00,0x00,0x00, 0},
-       {0x03,0x0210,0x16,0x01,0x01,0x00,0x00,0x00, 0},
-       {0x03,0x0010,0x18,0x02,0x02,0x00,0x00,0x00, 0},
-       {0x05,0x9209,0x05,0x00,0x00,0x00,0x00,0x00, 0},
-       {0x06,0x8209,0x06,0x00,0x00,0x00,0x00,0x00, 0},
-       {0x07,0x0000,0x07,0x03,0x03,0x00,0x00,0x00, 0},
-       {0x07,0x0000,0x19,0x02,0x02,0x00,0x00,0x00, 0},
-       {0x0d,0x920a,0x0d,0x00,0x00,0x00,0x00,0x00, 0},
-       {0x0e,0x820a,0x0e,0x00,0x00,0x00,0x00,0x00, 0},
-       {0x0f,0x0202,0x11,0x01,0x01,0x00,0x00,0x00, 0},
-       {0x10,0x0212,0x12,0x01,0x01,0x00,0x00,0x00, 0},
-       {0x11,0x0212,0x1a,0x04,0x04,0x00,0x00,0x00, 0},
-       {0x12,0x0212,0x1b,0x04,0x04,0x00,0x00,0x00, 0},
-       {0x13,0x021b,0x1c,0x00,0x00,0x00,0x00,0x00, 0},
-       {0x12,0x0010,0x18,0x02,0x02,0x00,0x00,0x00, 0},
-       {0x12,0x0210,0x18,0x01,0x01,0x00,0x00,0x00, 0},
-       {0xff,     0,   0,   0,   0,   0,   0,   0, 0}
-};
-
-static const SiS_ExtStruct  SiS300_EModeIDTable[] =
+static const struct SiS_Ext SiS300_EModeIDTable[] =
 {
        {0x6a,0x2212,0x0102,SIS_RI_800x600,  0x00,0x00,0x00,0x00,0x00,-1},  /* 800x600x? */
        {0x2e,0x0a1b,0x0101,SIS_RI_640x480,  0x00,0x00,0x00,0x00,0x08,-1},
@@ -110,7 +86,7 @@ static const SiS_ExtStruct  SiS300_EModeIDTable[] =
        {0x59,0x921b,0x0138,SIS_RI_320x200,  0x00,0x00,0x00,0x00,0x23,-1},  /* 320x200x8  */
        {0x5c,0x921f,0x0000,SIS_RI_512x384,  0x00,0x00,0x00,0x00,0x26,-1},  /* 512x384x32 */
        {0x5d,0x021d,0x0139,SIS_RI_640x400,  0x00,0x00,0x00,0x00,0x10,-1},  /* 640x400x16 */
-       {0x5e,0x021f,0x0000,SIS_RI_640x400,  0x00,0x00,0x00,0x00,0x10,-1},  /* 640x400x32 */
+       {0x5e,0x021f,0x0000,SIS_RI_640x400,  0x00,0x00,0x00,0x00,0x10,-1},  /* 640x400x32 */
        {0x62,0x0a3f,0x013a,SIS_RI_640x480,  0x00,0x00,0x00,0x00,0x08,-1},
        {0x63,0x2a3f,0x013b,SIS_RI_800x600,  0x00,0x00,0x00,0x00,0x00,-1},  /* 800x600x32 */
        {0x64,0x0a7f,0x013c,SIS_RI_1024x768, 0x00,0x00,0x00,0x00,0x13,-1},
@@ -119,8 +95,8 @@ static const SiS_ExtStruct  SiS300_EModeIDTable[] =
        {0x68,0x067b,0x013f,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x27,-1},
        {0x69,0x06fd,0x0140,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x27,-1},
        {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! */
+       {0x6c,0x067b,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x00,0x28,-1},  /* 2048x1536x8 */
+       {0x6d,0x06fd,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x00,0x28,-1},  /* 2048x1536x16 */
        {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 */
@@ -166,77 +142,77 @@ static const SiS_ExtStruct  SiS300_EModeIDTable[] =
        {0xff,0x0000,0xffff,0,               0x00,0x00,0x00,0x00,0x00}
 };
 
-static const SiS_Ext2Struct  SiS300_RefIndex[] =
-{
-       {0x085f,0x0d,0x03,0x05,0x05,0x6a, 800, 600, 0}, /* 00 */
-       {0x0467,0x0e,0x44,0x05,0x05,0x6a, 800, 600, 0}, /* 01 */
-       {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,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 */
-       {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,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 */
-       {0x0007,0x23,0x1d,0x00,0x00,0x3c,1600,1200, 0}, /* 21 - CRT1CRTC was 0x63 */
-       {0x0007,0x24,0x1e,0x00,0x00,0x3c,1600,1200, 0}, /* 22 */
-       {0x407f,0x00,0x00,0x00,0x00,0x40, 320, 200, 0}, /* 23 */
-       {0xc07f,0x01,0x00,0x04,0x04,0x50, 320, 240, 0}, /* 24 */
-       {0x0077,0x02,0x04,0x05,0x05,0x51, 400, 300, 0}, /* 25 */
-       {0xc877,0x03,0x09,0x06,0x06,0x52, 512, 384, 0}, /* 26 */  /* was c077 */
-       {0x8207,0x25,0x1f,0x00,0x00,0x68,1920,1440, 0}, /* 27 */
-       {0x0007,0x26,0x20,0x00,0x00,0x6c,2048,1536, 0}, /* 28 */
-       {0x0067,0x27,0x14,0x08,0x0a,0x6e,1280, 960, 0}, /* 29 - 1280x960-60 */
-       {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 */
-       {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}
-};
-
-static const SiS_VBModeStruct SiS300_VBModeIDTable[] =
+static const struct SiS_Ext2 SiS300_RefIndex[] =
+{
+       {0x085f,0x0d,0x03,0x05,0x05,0x6a, 800, 600, 0, 0x00, 0x00}, /* 00 */
+       {0x0467,0x0e,0x04,0x05,0x05,0x6a, 800, 600, 0, 0x00, 0x00}, /* 01 */
+       {0x0067,0x0f,0x07,0x48,0x05,0x6a, 800, 600, 0, 0x00, 0x00}, /* 02 - CRT1CRTC was 0x4f */
+       {0x0067,0x10,0x06,0x8b,0x05,0x6a, 800, 600, 0, 0x00, 0x00}, /* 03 */
+       {0x0147,0x11,0x08,0x00,0x05,0x6a, 800, 600, 0, 0x00, 0x00}, /* 04 */
+       {0x0147,0x12,0x0c,0x00,0x05,0x6a, 800, 600, 0, 0x00, 0x00}, /* 05 */
+       {0x0047,0x11,0x0e,0x00,0x05,0x6a, 800, 600, 0, 0x00, 0x00}, /* 06 - CRT1CRTC was 0x51 */
+       {0x0047,0x11,0x13,0x00,0x05,0x6a, 800, 600, 0, 0x00, 0x00}, /* 07 */
+       {0xc85f,0x05,0x00,0x04,0x04,0x2e, 640, 480, 0, 0x00, 0x00}, /* 08 */
+       {0xc067,0x06,0x02,0x04,0x04,0x2e, 640, 480, 0, 0x00, 0x00}, /* 09 */
+       {0xc067,0x07,0x02,0x47,0x04,0x2e, 640, 480, 0, 0x00, 0x00}, /* 0a */
+       {0xc067,0x08,0x03,0x8a,0x04,0x2e, 640, 480, 0, 0x00, 0x00}, /* 0b */
+       {0xc047,0x09,0x05,0x00,0x04,0x2e, 640, 480, 0, 0x00, 0x00}, /* 0c */
+       {0xc047,0x0a,0x08,0x00,0x04,0x2e, 640, 480, 0, 0x00, 0x00}, /* 0d */
+       {0xc047,0x0b,0x0a,0x00,0x04,0x2e, 640, 480, 0, 0x00, 0x00}, /* 0e */
+       {0xc047,0x0c,0x10,0x00,0x04,0x2e, 640, 480, 0, 0x00, 0x00}, /* 0f */
+       {0x487f,0x04,0x00,0x00,0x00,0x2f, 640, 400, 0, 0x4a, 0x49}, /* 10 */
+       {0xc06f,0x31,0x01,0x06,0x13,0x31, 720, 480, 0, 0x00, 0x00}, /* 11 */
+       {0x006f,0x32,0x4a,0x06,0x14,0x32, 720, 576, 0, 0x00, 0x00}, /* 12 */ /* 4a was 03 */
+       {0x0187,0x15,0x05,0x00,0x06,0x37,1024, 768, 0, 0x00, 0x00}, /* 13 */
+       {0xc877,0x16,0x09,0x06,0x06,0x37,1024, 768, 0, 0x00, 0x00}, /* 14 */
+       {0xc067,0x17,0x0b,0x49,0x06,0x37,1024, 768, 0, 0x00, 0x00}, /* 15 - CRT1CRTC was 0x97 */
+       {0x0267,0x18,0x0d,0x00,0x06,0x37,1024, 768, 0, 0x00, 0x00}, /* 16 */
+       {0x0047,0x19,0x11,0x8c,0x06,0x37,1024, 768, 0, 0x00, 0x00}, /* 17 - CRT1CRTC was 0x59 */
+       {0x0047,0x1a,0x12,0x00,0x06,0x37,1024, 768, 0, 0x00, 0x00}, /* 18 */
+       {0x0007,0x1b,0x16,0x00,0x06,0x37,1024, 768, 0, 0x00, 0x00}, /* 19 - CRT1CRTC was 0x5b */
+       {0x0387,0x1c,0x0d,0x00,0x07,0x3a,1280,1024, 0, 0x00, 0x00}, /* 1a - CRT1CRTC was 0x5c */
+       {0x0077,0x1d,0x14,0x07,0x07,0x3a,1280,1024, 0, 0x00, 0x00}, /* 1b */
+       {0x0047,0x1e,0x17,0x00,0x07,0x3a,1280,1024, 0, 0x00, 0x00}, /* 1c */
+       {0x0007,0x1f,0x18,0x00,0x07,0x3a,1280,1024, 0, 0x00, 0x00}, /* 1d */
+       {0x0007,0x20,0x19,0x00,0x00,0x3c,1600,1200, 0, 0x00, 0x00}, /* 1e - CRT1CRTC was 0x60 */
+       {0x0007,0x21,0x1a,0x00,0x00,0x3c,1600,1200, 0, 0x00, 0x00}, /* 1f */
+       {0x0007,0x22,0x1b,0x00,0x00,0x3c,1600,1200, 0, 0x00, 0x00}, /* 20 */
+       {0x0007,0x23,0x1d,0x00,0x00,0x3c,1600,1200, 0, 0x00, 0x00}, /* 21 - CRT1CRTC was 0x63 */
+       {0x0007,0x24,0x1e,0x00,0x00,0x3c,1600,1200, 0, 0x00, 0x00}, /* 22 */
+       {0x407f,0x00,0x00,0x00,0x00,0x40, 320, 200, 0, 0x4b, 0x4b}, /* 23 */
+       {0xc07f,0x01,0x00,0x04,0x04,0x50, 320, 240, 0, 0x00, 0x00}, /* 24 */
+       {0x0077,0x02,0x04,0x05,0x05,0x51, 400, 300, 0, 0x00, 0x00}, /* 25 */
+       {0xc877,0x03,0x09,0x06,0x06,0x52, 512, 384, 0, 0x00, 0x00}, /* 26 */  /* was c077 */
+       {0x8207,0x25,0x1f,0x00,0x00,0x68,1920,1440, 0, 0x00, 0x00}, /* 27 */
+       {0x0007,0x26,0x20,0x00,0x00,0x6c,2048,1536, 0, 0x00, 0x00}, /* 28 */
+       {0x0067,0x27,0x14,0x08,0x0a,0x6e,1280, 960, 0, 0x00, 0x00}, /* 29 - 1280x960-60 */
+       {0x0027,0x45,0x3c,0x08,0x0a,0x6e,1280, 960, 0, 0x00, 0x00}, /* 2a - 1280x960-85 */
+       {0xc077,0x33,0x09,0x06,0x00,0x20,1024, 600, 0, 0x00, 0x00}, /* 2b */
+       {0xc077,0x34,0x0b,0x06,0x00,0x23,1152, 768, 0, 0x00, 0x00}, /* 2c */    /* VCLK 0x09 */
+       {0x0077,0x35,0x27,0x08,0x18,0x70, 800, 480, 0, 0x00, 0x00}, /* 2d */
+       {0x0047,0x36,0x37,0x08,0x18,0x70, 800, 480, 0, 0x00, 0x00}, /* 2e */
+       {0x0047,0x37,0x08,0x08,0x18,0x70, 800, 480, 0, 0x00, 0x00}, /* 2f */
+       {0x0077,0x38,0x09,0x09,0x19,0x71,1024, 576, 0, 0x00, 0x00}, /* 30 */
+       {0x0047,0x39,0x38,0x09,0x19,0x71,1024, 576, 0, 0x00, 0x00}, /* 31 */
+       {0x0047,0x3a,0x11,0x09,0x19,0x71,1024, 576, 0, 0x00, 0x00}, /* 32 */
+       {0x0077,0x3b,0x39,0x0a,0x0c,0x75,1280, 720, 0, 0x00, 0x00}, /* 33 */
+       {0x0047,0x3c,0x3a,0x0a,0x0c,0x75,1280, 720, 0, 0x00, 0x00}, /* 34 */
+       {0x0007,0x3d,0x3b,0x0a,0x0c,0x75,1280, 720, 0, 0x00, 0x00}, /* 35 */
+       {0x0067,0x49,0x35,0x06,0x1a,0x29,1152, 864, 0, 0x00, 0x00}, /* 36 1152x864-60Hz  */
+       {0x0067,0x3e,0x34,0x06,0x1a,0x29,1152, 864, 0, 0x00, 0x00}, /* 37 1152x864-75Hz */
+       {0x0047,0x44,0x3a,0x06,0x1a,0x29,1152, 864, 0, 0x00, 0x00}, /* 38 1152x864-85Hz */
+       {0x00c7,0x3f,0x28,0x00,0x16,0x39, 848, 480, 0, 0x00, 0x00}, /* 39 848x480-38Hzi */
+       {0xc067,0x40,0x3d,0x0b,0x16,0x39, 848, 480, 0, 0x00, 0x00}, /* 3a 848x480-60Hz  */
+       {0x00c7,0x41,0x28,0x00,0x17,0x3f, 856, 480, 0, 0x00, 0x00}, /* 3b 856x480-38Hzi */
+       {0xc067,0x42,0x28,0x0c,0x17,0x3f, 856, 480, 0, 0x00, 0x00}, /* 3c 856x480-60Hz  */
+       {0x0067,0x43,0x3e,0x0d,0x1b,0x48,1360, 768, 0, 0x00, 0x00}, /* 3d 1360x768-60Hz */
+       {0x0077,0x46,0x3f,0x08,0x08,0x55,1280, 768, 0, 0x00, 0x00}, /* 3e 1280x768-60Hz */
+       {0x006f,0x47,0x4c,0x06,0x15,0x5f, 768, 576, 0, 0x00, 0x00}, /* 3f 768x576 */
+       {0x0027,0x48,0x13,0x08,0x00,0x67,1360,1024, 0, 0x00, 0x00}, /* 40 1360x1024-59Hz (BARCO1366 only) */
+       {0xffff,   0,   0,   0,   0,   0,   0,   0, 0, 0x00, 0x00}
+};
+
+static const struct SiS_VBMode SiS300_VBModeIDTable[] =
 {
        {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01},
@@ -303,53 +279,26 @@ static const SiS_VBModeStruct SiS300_VBModeIDTable[] =
        {0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
 };
 
-static const SiS_CRT1TableStruct  SiS300_CRT1Table[] =
+static const struct SiS_CRT1Table SiS300_CRT1Table[] =
 {
-#if 1
  {{0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,    /* 0x00 - 320x200 */
   0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x00,     /* HRE [4],[15] is invalid - but correcting it does not work */
   0x00}},
-#endif
-#if 0
- {{0x2d,0x27,0x27,0x91,0x2c,0x92,0xbf,0x1f,    /* 0x00 - corrected 320x200-72 - does not work */
-  0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x04,
-  0x00}},
-#endif
  {{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e,    /* 0x01 */
   0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00,     /* HRE [4],[15] is invalid - but correcting it does not work */
   0x00}},
-#if 0
- {{0x2d,0x27,0x27,0x91,0x2c,0x92,0x0b,0x3e,    /* 0x01 - corrected 320x240-60 - does not work */
-  0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x04,
-  0x00}},
-#endif
  {{0x3d,0x31,0x31,0x81,0x37,0x1f,0x72,0xf0,    /* 0x02 */
   0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x05,
   0x01}},
-#if 0
- {{0x3d,0x31,0x31,0x81,0x37,0x1f,0x72,0xf0,    /* 0x02 - corrected 400x300-60 */
-  0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x05,
-  0x01}},
-#endif
  {{0x4f,0x3f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
   0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x01,
   0x01}},
  {{0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
   0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x05,
   0x00}},
-#if 0  
- {{0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,    /* 0x05 */
-  0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05,
-  0x00}},
-#endif
  {{0x5f,0x4f,0x4f,0x83,0x55,0x81,0x0b,0x3e,    /* 0x05 - corrected 640x480-60 */
   0xe9,0x8b,0xdf,0xe8,0x0c,0x00,0x00,0x05,
   0x00}},
-#if 0
- {{0x63,0x4f,0x50,0x86,0x56,0x9b,0x06,0x3e,    /* 0x06 */
-  0xe8,0x8b,0xdf,0xe7,0xff,0x10,0x00,0x01,
-  0x00}},
-#endif  
  {{0x63,0x4f,0x4f,0x87,0x56,0x9b,0x06,0x3e,    /* 0x06 - corrected 640x480-72 */
   0xe8,0x8a,0xdf,0xe7,0x07,0x00,0x00,0x01,
   0x00}},
@@ -359,19 +308,9 @@ static const SiS_CRT1TableStruct  SiS300_CRT1Table[] =
  {{0x63,0x4f,0x4f,0x87,0x5a,0x81,0xfb,0x1f,
   0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x05,
   0x00}},
-#if 0  
- {{0x66,0x4f,0x4f,0x86,0x56,0x9e,0x03,0x3e,    /* 0x09 */
-  0xe4,0x87,0xdf,0xdf,0x04,0x00,0x00,0x01,
-  0x00}},
-#endif
  {{0x67,0x4f,0x4f,0x8b,0x57,0x83,0x10,0x3e,    /* 0x09 - corrected 640x480-100 */
   0xe7,0x8d,0xdf,0xe6,0x11,0x00,0x00,0x05,
   0x00}},
-#if 0  
- {{0x6c,0x4f,0x4f,0x83,0x59,0x9e,0x00,0x3e,    /* 0x0a */
-  0xe5,0x8d,0xdf,0xdf,0x01,0x00,0x00,0x01,
-  0x00}},
-#endif    
  {{0x67,0x4f,0x4f,0x8b,0x57,0x83,0x10,0x3e,    /* 0x0a - corrected 640x480-120 */
   0xe7,0x8d,0xdf,0xe6,0x11,0x00,0x00,0x05,
   0x00}},
@@ -459,11 +398,6 @@ static const SiS_CRT1TableStruct  SiS300_CRT1Table[] =
  {{0x55,0xff,0xff,0x99,0x0d,0x0c,0x3e,0xba,
   0x00,0x84,0xff,0xff,0x3f,0x0f,0x41,0x05,
   0x00}},
-#if 0  
- {{0xdc,0x9f,0x9f,0x00,0xab,0x19,0xe6,0xef,  /* 0x27: 1280x960-70 - invalid! */
-  0xc0,0xc3,0xbf,0xbf,0xe7,0x10,0x00,0x07,
-  0x01}},
-#endif  
  {{0xdc,0x9f,0x9f,0x80,0xaf,0x9d,0xe6,0xff,  /* 0x27: 1280x960-60 - correct */
   0xc0,0x83,0xbf,0xbf,0xe7,0x10,0x00,0x07,
   0x01}},
@@ -497,9 +431,9 @@ static const SiS_CRT1TableStruct  SiS300_CRT1Table[] =
  {{0x6b,0x59,0x59,0x8f,0x5e,0x8c,0x0b,0x3e,
   0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05,
   0x00}},
- {{0x7b,0x59,0x63,0x9f,0x6a,0x93,0x6f,0xf0,  /* 0x32 */
-  0x58,0x8a,0x3f,0x57,0x70,0x20,0x00,0x05,
-  0x01}},
+ {{0x6d,0x59,0x59,0x91,0x60,0x89,0x53,0xf0,  /* 0x32: 720x576, corrected to 60Hz */
+  0x41,0x84,0x3f,0x3f,0x54,0x00,0x00,0x05,
+  0x41}},
  {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x1e,0xf1,  /* 0x33 - 1024x600 */
   0xae,0x85,0x57,0x57,0x1f,0x30,0x00,0x02,
   0x01}},
@@ -560,18 +494,24 @@ static const SiS_CRT1TableStruct  SiS300_CRT1Table[] =
  {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x20,0xf5,  /* 1280x768-60 */
    0x03,0x88,0xff,0xff,0x21,0x10,0x00,0x07,
    0x01}}, /* 0x46 */
- {{0x7b,0x5f,0x63,0x9f,0x6a,0x93,0x6f,0xf0,  /* 768x576 */
-   0x58,0x8a,0x3f,0x57,0x70,0x20,0x00,0x05,
-   0x01}}, /* 0x47 */
+ {{0x75,0x5f,0x5f,0x99,0x66,0x90,0x53,0xf0,  /* 768x576, corrected to 60Hz */
+   0x41,0x84,0x3f,0x3f,0x54,0x00,0x00,0x05,
+   0x41}}, /* 0x47 */
  {{0xce,0xa9,0xa9,0x92,0xb1,0x07,0x28,0x52,  /* 1360x1024 (Barco iQ Pro R300) */
    0x02,0x8e,0xff,0x00,0x29,0x0d,0x00,0x03,
    0x00}}, /* 0x48 */
  {{0xcd,0x8f,0x8f,0x91,0x9b,0x1b,0x7a,0xff,  /* 1152x864-60 */
    0x64,0x8c,0x5f,0x62,0x7b,0x10,0x00,0x07,
-   0x41}}  /* 0x49 */
+   0x41}}, /* 0x49 */
+ {{0x5c,0x4f,0x4f,0x80,0x57,0x80,0xa3,0x1f, /* fake 640x400@60Hz (for LCD and TV, not actually used) */
+   0x98,0x8c,0x8f,0x96,0xa4,0x30,0x00,0x05,
+   0x40}}, /* 0x4a */
+ {{0x2c,0x27,0x27,0x90,0x2d,0x92,0xa4,0x1f, /* fake 320x200@60Hz (for LCD and TV, not actually used) */
+   0x98,0x8c,0x8f,0x96,0xa5,0x30,0x00,0x04,
+   0x00}}  /* 0x4b */
 };
 
-static const SiS_MCLKDataStruct  SiS300_MCLKData_630[] =
+static const struct SiS_MCLKData SiS300_MCLKData_630[] =
 {
        { 0x5a,0x64,0x80, 66},
        { 0xb3,0x45,0x80, 83},
@@ -583,7 +523,7 @@ static const SiS_MCLKDataStruct  SiS300_MCLKData_630[] =
        { 0x37,0x61,0x80,100}
 };
 
-static const SiS_MCLKDataStruct  SiS300_MCLKData_300[] =
+static const struct SiS_MCLKData SiS300_MCLKData_300[] =
 {
        { 0x68,0x43,0x80,125},
        { 0x68,0x43,0x80,125},
@@ -595,7 +535,7 @@ static const SiS_MCLKDataStruct  SiS300_MCLKData_300[] =
        { 0x37,0x61,0x80,100}
 };
 
-static SiS_VCLKDataStruct SiS300_VCLKData[] =
+static struct SiS_VCLKData SiS300_VCLKData[] =
 {
        { 0x1b,0xe1, 25}, /* 0x00 */
        { 0x4e,0xe4, 28}, /* 0x01 */
@@ -669,53 +609,26 @@ static SiS_VCLKDataStruct SiS300_VCLKData[] =
        { 0xe2,0x46,135}, /* 0x45 */  /* 1280x1024-75, better clock for VGA2 */
        { 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?) */
+       { 0xce,0x25,189}, /* 0x48 */  /* Replacement for index 0x1b for 730 (and 540?) */
+       { 0x15,0xe1, 20}, /* 0x49 */  /* 640x400@60 (fake, not actually used) */
+       { 0x5f,0xc6, 33}, /* 0x4a */  /* 720x576@60 */
+       { 0x37,0x5a, 10}, /* 0x4b */  /* 320x200@60 (fake, not actually used) */
+       { 0x2b,0xc2, 35}  /* 0x4c */  /* 768@576@60 */
 };
 
-#ifdef LINUX_KERNEL
-static UCHAR SiS300_SR07 = 0x10;
-#endif
-
-static const DRAM4Type SiS300_SR15[8] =
+static const unsigned char SiS300_SR15[4 * 8] =
 {
-       {0x01,0x09,0xa3,0x00},
-       {0x43,0x43,0x43,0x00},
-       {0x1e,0x1e,0x1e,0x00},
-       {0x2a,0x2a,0x2a,0x00},
-       {0x06,0x06,0x06,0x00},
-       {0x00,0x00,0x00,0x00},
-       {0x00,0x00,0x00,0x00},
-       {0x00,0x00,0x00,0x00}
+       0x01,0x09,0xa3,0x00,
+       0x43,0x43,0x43,0x00,
+       0x1e,0x1e,0x1e,0x00,
+       0x2a,0x2a,0x2a,0x00,
+       0x06,0x06,0x06,0x00,
+       0x00,0x00,0x00,0x00,
+       0x00,0x00,0x00,0x00,
+       0x00,0x00,0x00,0x00
 };
 
-#ifdef LINUX_KERNEL
-static UCHAR SiS300_SR1F = 0x00;
-static UCHAR SiS300_SR21 = 0x16;
-static UCHAR SiS300_SR22 = 0xb2;
-static UCHAR SiS300_SR23 = 0xf6;
-static UCHAR SiS300_SR24 = 0x0d;
-static UCHAR SiS300_SR25[] = {0x0,0x0};
-static UCHAR SiS300_SR31 = 0x00;
-static UCHAR SiS300_SR32 = 0x11;
-static UCHAR SiS300_SR33 = 0x00;
-static UCHAR SiS300_CRT2Data_1_2 = 0x40;
-static UCHAR SiS300_CRT2Data_4_D = 0x00;
-static UCHAR SiS300_CRT2Data_4_E = 0x00;
-static UCHAR SiS300_CRT2Data_4_10 = 0x80;
-
-static const USHORT SiS300_RGBSenseData = 0xd1;
-static const USHORT SiS300_VideoSenseData = 0xb3;
-static const USHORT SiS300_YCSenseData = 0xb9;
-static const USHORT SiS300_RGBSenseData2 = 0x0190;
-static const USHORT SiS300_VideoSenseData2 = 0x0174;
-static const USHORT SiS300_YCSenseData2 = 0x016b;
-
-static const DRAM4Type SiS300_CR40[5];
-
-static UCHAR SiS300_CR49[2];
-#endif
-
-static const SiS_PanelDelayTblStruct  SiS300_PanelDelayTbl[] =
+static const struct SiS_PanelDelayTbl SiS300_PanelDelayTbl[] =
 {
        {{0x05,0xaa}},
        {{0x05,0x14}},
@@ -735,33 +648,11 @@ static const SiS_PanelDelayTblStruct  SiS300_PanelDelayTbl[] =
        {{0x05,0x60}}
 };
 
-#if 0
-static const SiS_PanelDelayTblStruct  SiS300_PanelDelayTblLVDS[] =
-{
-       {{0x05,0xaa}},
-       {{0x05,0x14}},
-       {{0x05,0x36}},
-       {{0x05,0x14}},
-       {{0x05,0x14}},
-       {{0x05,0x14}},
-       {{0x05,0x90}},
-       {{0x05,0x90}},
-       {{0x05,0x14}},
-       {{0x05,0x14}},
-       {{0x05,0x14}},
-       {{0x05,0x14}},  /* 2.07a (JVC): 14,96 */
-       {{0x05,0x28}},  /* 2.04.5c: 20, 80 - Clevo (2.04.2c): 05, 28 */
-       {{0x05,0x14}},
-       {{0x05,0x14}},  /* Some BIOSes: 05, 40 */
-       {{0x05,0x60}}
-};
-#endif
-
 /**************************************************************/
 /* SIS VIDEO BRIDGE ----------------------------------------- */
 /**************************************************************/
 
-static const SiS_LCDDataStruct  SiS300_St2LCD1024x768Data[] =
+static const struct SiS_LCDData SiS300_St2LCD1024x768Data[] =
 {
        {   62,  25, 800, 546,1344, 806},
        {   32,  15, 930, 546,1344, 806},
@@ -772,7 +663,7 @@ static const SiS_LCDDataStruct  SiS300_St2LCD1024x768Data[] =
        {    1,   1,1344, 806,1344, 806}
 };
 
-static const SiS_LCDDataStruct  SiS300_ExtLCD1024x768Data[] =
+static const struct SiS_LCDData SiS300_ExtLCD1024x768Data[] =
 {
        {   12,   5, 896, 512,1344, 806},
        {   12,   5, 896, 510,1344, 806},
@@ -789,7 +680,7 @@ static const SiS_LCDDataStruct  SiS300_ExtLCD1024x768Data[] =
        {    1,   1,1344, 806,1344, 806}
 };
 
-static const SiS_LCDDataStruct  SiS300_St2LCD1280x1024Data[] =
+static const struct SiS_LCDData SiS300_St2LCD1280x1024Data[] =
 {
        {   22,   5, 800, 510,1650,1088},
        {   22,   5, 800, 510,1650,1088},
@@ -801,7 +692,7 @@ static const SiS_LCDDataStruct  SiS300_St2LCD1280x1024Data[] =
        {    1,   1,1688,1066,1688,1066}
 };
 
-static const SiS_LCDDataStruct  SiS300_ExtLCD1280x1024Data[] =
+static const struct SiS_LCDData SiS300_ExtLCD1280x1024Data[] =
 {
        {  211,  60,1024, 501,1688,1066},
        {  211,  60,1024, 508,1688,1066},
@@ -813,53 +704,116 @@ static const SiS_LCDDataStruct  SiS300_ExtLCD1280x1024Data[] =
        {    1,   1,1688,1066,1688,1066}
 };
 
-static const SiS_Part2PortTblStruct SiS300_CRT2Part2_1024x768_1[] =
+static const struct SiS_Part2PortTbl SiS300_CRT2Part2_1024x768_1[] =
 { /* VESA Timing */
-  {{0x21,0x12,0xbf,0xe4,0xc0,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}},
-  {{0x2c,0x12,0x9a,0xae,0x88,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}},
-  {{0x21,0x12,0xbf,0xe4,0xc0,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}},
-  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
-  {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}},
-  {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}},
-  {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}}
+       {{0x21,0x12,0xbf,0xe4,0xc0,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}},
+       {{0x2c,0x12,0x9a,0xae,0x88,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}},
+       {{0x21,0x12,0xbf,0xe4,0xc0,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}},
+       {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+       {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}},
+       {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}},
+       {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}}
 };
 
-static const SiS_Part2PortTblStruct SiS300_CRT2Part2_1024x768_2[] =
+static const struct SiS_Part2PortTbl SiS300_CRT2Part2_1024x768_2[] =
 {  /* Non-VESA */
- {{0x28,0x12,0xa3,0xd0,0xaa,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
- {{0x2c,0x12,0x9a,0xae,0x88,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
- {{0x28,0x12,0xa3,0xd0,0xaa,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
- {{0x2c,0x12,0x9a,0xae,0x88,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
- {{0x28,0x13,0xe7,0x0b,0xe8,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
- {{0x38,0x18,0x16,0x00,0x00,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
- {{0x36,0x13,0x13,0x25,0xff,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}}
-};
-
-static const SiS_Part2PortTblStruct SiS300_CRT2Part2_1024x768_3[] =
-{
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
-};
-
-static const SiS_Part2PortTblStruct SiS300_CRT2Part2_1280x1024_1[] =
-{
-  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
-};
-
-static const SiS_Part2PortTblStruct SiS300_CRT2Part2_1280x1024_2[] =
-{
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+       {{0x28,0x12,0xa3,0xd0,0xaa,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
+       {{0x2c,0x12,0x9a,0xae,0x88,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
+       {{0x28,0x12,0xa3,0xd0,0xaa,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
+       {{0x2c,0x12,0x9a,0xae,0x88,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
+       {{0x28,0x13,0xe7,0x0b,0xe8,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
+       {{0x38,0x18,0x16,0x00,0x00,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
+       {{0x36,0x13,0x13,0x25,0xff,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}}
 };
 
-static const SiS_Part2PortTblStruct SiS300_CRT2Part2_1280x1024_3[] =
+static const struct SiS_Part2PortTbl SiS300_CRT2Part2_1024x768_3[] =
 {
-  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+       {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
 };
 
 /**************************************************************/
 /* LVDS/Chrontel -------------------------------------------- */
 /**************************************************************/
 
-static const SiS_LVDSDataStruct  SiS300_CHTVUPALData[] =
+/* Custom data for Barco iQ R series */
+static const struct SiS_LVDSData SiS300_LVDSBARCO1366Data_1[]=
+{
+       { 832, 438,1331, 806},
+       { 832, 388,1331, 806},
+       { 832, 438,1331, 806},
+       { 832, 388,1331, 806},
+       { 832, 518,1331, 806},
+       {1050, 638,1344, 806},
+       {1344, 806,1344, 806},
+       {1688,1066,1688,1066},
+       {1688,1066,1688,1066}   /* 1360x1024 */
+};
+
+/* Custom data for Barco iQ R series */
+static const struct SiS_LVDSData SiS300_LVDSBARCO1366Data_2[]=
+{
+       {1344, 806,1344, 806},
+       {1344, 806,1344, 806},
+       {1344, 806,1344, 806},
+       {1344, 806,1344, 806},
+       {1344, 806,1344, 806},
+       {1344, 806,1344, 806},
+       {1344, 806,1344, 806},
+       {1688,1066,1688,1066},
+       {1688,1066,1688,1066}   /* 1360x1024 */
+};
+
+/* Custom data for Barco iQ G series */
+static const struct SiS_LVDSData SiS300_LVDSBARCO1024Data_1[]=
+{
+       { 832, 438,1331, 806},
+       { 832, 409,1331, 806},
+       { 832, 438,1331, 806},
+       { 832, 409,1331, 806},
+       { 832, 518,1331, 806},   /* 640x480 */
+       {1050, 638,1344, 806},   /* 800x600 */
+       {1344, 806,1344, 806},   /* 1024x768 */
+};
+
+/* Custom data for 848x480 and 856x480 parallel LVDS panels */
+static const struct SiS_LVDSData SiS300_LVDS848x480Data_1[]=
+{
+       {   0,   0,   0,   0},
+       {   0,   0,   0,   0},
+       {   0,   0,   0,   0},
+       {   0,   0,   0,   0},
+       {1088, 525,1088, 525},  /* 640x480 TODO */
+       {1088, 525,1088, 525},  /* 800x600 TODO */
+       {1088, 525,1088, 525},  /* 1024x768 TODO */
+       {   0,   0,   0,   0},
+       {   0,   0,   0,   0},
+       {   0,   0,   0,   0},
+       {   0,   0,   0,   0},
+       {1088, 525,1088, 525},  /* 848x480 */
+       {1088, 525,1088, 525},  /* 856x480 */
+       {1088, 525,1088, 525}   /* 1360x768 TODO */
+};
+
+/* Custom data for 848x480 parallel panel */
+static const struct SiS_LVDSData SiS300_LVDS848x480Data_2[]=
+{
+       {   0,   0,   0,   0},
+       {   0,   0,   0,   0},
+       {   0,   0,   0,   0},
+       {   0,   0,   0,   0},
+       {1088, 525,1088, 525},  /*  640x480 */
+       {1088, 525,1088, 525},  /*  800x600 */
+       {1088, 525,1088, 525},  /* 1024x768 */
+       {   0,   0,   0,   0},
+       {   0,   0,   0,   0},
+       {   0,   0,   0,   0},
+       {   0,   0,   0,   0},
+       {1088, 525,1088, 525},  /* 848x480 */
+       {1088, 525,1088, 525},  /* 856x480 */
+       {1088, 525,1088, 525}   /* 1360x768 TODO */
+};
+
+static const struct SiS_LVDSData SiS300_CHTVUPALData[] =
 {
        {1008, 625,1008, 625},
        {1008, 625,1008, 625},
@@ -869,7 +823,7 @@ static const SiS_LVDSDataStruct  SiS300_CHTVUPALData[] =
        { 936, 836, 936, 836}
 };
 
-static const SiS_LVDSDataStruct  SiS300_CHTVOPALData[] =
+static const struct SiS_LVDSData SiS300_CHTVOPALData[] =
 {
        {1008, 625,1008, 625},
        {1008, 625,1008, 625},
@@ -879,7 +833,7 @@ static const SiS_LVDSDataStruct  SiS300_CHTVOPALData[] =
        { 960, 750, 960, 750}
 };
 
-static const SiS_LVDSDataStruct  SiS300_CHTVSOPALData[] =
+static const struct SiS_LVDSData SiS300_CHTVSOPALData[] =
 {
        {1008, 625,1008, 625},
        {1008, 625,1008, 625},
@@ -889,486 +843,8 @@ static const SiS_LVDSDataStruct  SiS300_CHTVSOPALData[] =
        { 944, 625, 944, 625}
 };
 
-
-static const SiS_LVDSDesStruct  SiS300_PanelType00_1[] =
-{
-       { 1059, 626 },   /* 2.08 */
-       { 1059, 624 },
-       { 1059, 626 },
-       { 1059, 624 },
-       { 1059, 624 },
-       {    0, 627 },
-       {    0, 627 },
-       {    0,   0 },
-       {    0,   0 }
-#if 0
-       {0, 626},
-       {0, 624},
-       {0, 626},
-       {0, 624},
-       {0, 624},
-       {0, 627},
-       {0, 627},
-       {0,   0},
-       {0,   0}
-#endif
-};
-
-static const SiS_LVDSDesStruct  SiS300_PanelType01_1[] =
-{
-       {   0,   0 },  /* 2.08 */
-       {   0,   0 },
-       {   0,   0 },
-       {   0,   0 },
-       {   0,   0 },
-       {   0,   0 },
-       {   0,   0 },
-       {   0,   0 },
-       {   0,   0 }
-#if 0
-       {1343, 798},
-       {1343, 794},
-       {1343, 798},
-       {1343, 794},
-       {1343,   0},
-       {1343,   0},
-       {   0, 805},
-       {   0, 794},
-       {   0,   0}
-#endif
-};
-
-static const SiS_LVDSDesStruct  SiS300_PanelType02_1[] =
-{
-       { 1059, 626 },  /* 2.08 */
-       { 1059, 624 },
-       { 1059, 626 },
-       { 1059, 624 },
-       { 1059, 624 },
-       {    0, 627 },
-       {    0, 627 },
-       {    0,   0 },
-       {    0,   0 }
-#if 0
-       {0, 626},
-       {0, 624},
-       {0, 626},
-       {0, 624},
-       {0, 624},
-       {0, 627},
-       {0, 627},
-       {0,   0},
-       {0,   0}
-#endif
-};
-
-static const SiS_LVDSDesStruct  SiS300_PanelType03_1[] =
-{
-       {   8, 436},
-       {   8, 440},
-       {   8, 436},
-       {   8, 440},
-       {   8, 512},
-       {1343, 798},
-       {1343, 794},
-       {1343, 798},
-       {1343, 794}
-};
-
-static const SiS_LVDSDesStruct  SiS300_PanelType04_1[] =       /* 1280x1024 */
-{
-       {1343, 798},
-       {1343, 794},
-       {1343, 798},
-       {1343, 794},
-       {1343,   0},
-       {1343,   0},
-       {   0, 805},
-       {   0, 794},
-       {   0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS300_PanelType05_1[] =
-{
-       {1343, 798},
-       {1343, 794},
-       {1343, 798},
-       {1343, 794},
-       {1343,   0},
-       {1343,   0},
-       {   0, 805},
-       {   0, 794},
-       {   0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS300_PanelType06_1[] =       /* Clevo Trumpion 1024x768 */
-{
-       {1343, 798},
-       {1343, 794},
-       {1343, 798},
-       {1343, 794},
-       {1343,   0},
-       {1343,   0},
-       {   0, 805},
-       {   0, 794},
-       {   0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS300_PanelType07_1[] =
-{
-       {1343, 798},
-       {1343, 794},
-       {1343, 798},
-       {1343, 794},
-       {1343,   0},
-       {1343,   0},
-       {   0, 805},
-       {   0, 794},
-       {   0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS300_PanelType08_1[] =
-{
-       {1059, 626},
-       {1059, 624},
-       {1059, 626},
-       {1059, 624},
-       {1059, 624},
-       {   0, 627},
-       {   0, 627},
-       {   0,   0},
-       {   0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS300_PanelType09_1[] =
-{
-       {1343, 798},
-       {1343, 794},
-       {1343, 798},
-       {1343, 794},
-       {1343,   0},
-       {1343,   0},
-       {   0, 805},
-       {   0, 794},
-       {   0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS300_PanelType0a_1[] =
-{
-       {1059, 626},
-       {1059, 624},
-       {1059, 626},
-       {1059, 624},
-       {1059, 624},
-       {   0, 627},
-       {   0, 627},
-       {   0,   0},
-       {   0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS300_PanelType0b_1[] =
-{
-       {1343,   0},
-       {1343,   0},
-       {1343,   0},
-       {1343,   0},
-       {1343,   0},
-       {1343,   0},
-       {   0, 799},
-       {   0,   0},
-       {   0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS300_PanelType0c_1[] =
-{
-       {1343, 798},
-       {1343, 794},
-       {1343, 798},
-       {1343, 794},
-       {1343,   0},
-       {1343,   0},
-       {   0, 805},
-       {   0, 794},
-       {   0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS300_PanelType0d_1[] =
-{
-       {1343, 798},
-       {1343, 794},
-       {1343, 798},
-       {1343, 794},
-       {1343,   0},
-       {1343,   0},
-       {   0, 805},
-       {   0, 794},
-       {   0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS300_PanelType0e_1[] =
-{
-       {1343, 798},
-       {1343, 794},
-       {1343, 798},
-       {1343, 794},
-       {1343,   0},    /* 640x480 */
-       {1343,   0},    /* 800x600 */
-       {   0, 805},    /* 1024x768 */
-       {   0, 794},    /* 1280x1024 */
-       {   0,   0}     /* 1280x960 - not applicable */
-};
-
-static const SiS_LVDSDesStruct  SiS300_PanelType0f_1[] =
-{
-       {1343, 798},
-       {1343, 794},
-       {1343, 798},
-       {1343, 794},
-       {1343,   0},
-       {1343,   0},
-       {   0, 805},
-       {   0, 794},
-       {   0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS300_PanelType00_2[] =
-{
-       {976, 527},
-       {976, 502},
-       {976, 527},
-       {976, 502},
-       {976, 567},
-       {  0, 627},
-       {  0, 627},
-       {  0,   0},
-       {  0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS300_PanelType01_2[] =
-{
-       {1152, 622},
-       {1152, 597},
-       {1152, 622},
-       {1152, 597},
-       {1152, 662},
-       {1232, 722},
-       {   0, 805},
-       {   0, 794},
-       {   0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS300_PanelType02_2[] =
-{
-       {976, 527},
-       {976, 502},
-       {976, 527},
-       {976, 502},
-       {976, 567},
-       {  0, 627},
-       {  0, 627},
-       {  0,   0},
-       {  0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS300_PanelType03_2[] =
-{
-       {1152, 622},
-       {1152, 597},
-       {1152, 622},
-       {1152, 597},
-       {1152, 662},
-       {1232, 722},
-       {   0, 805},
-       {1152, 622},
-       {1152, 597}
-};
-
-static const SiS_LVDSDesStruct  SiS300_PanelType04_2[] =
-{
-       {1152, 622},
-       {1152, 597},
-       {1152, 622},
-       {1152, 597},
-       {1152, 662},
-       {1232, 722},
-       {   0, 805},
-       {   0, 794},
-       {   0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS300_PanelType05_2[] =
-{
-       {1152, 622},
-       {1152, 597},
-       {1152, 622},
-       {1152, 597},
-       {1152, 662},
-       {1232, 722},
-       {   0, 805},
-       {   0, 794},
-       {   0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS300_PanelType06_2[] =
-{
-       {1152, 622},
-       {1152, 597},
-       {1152, 622},
-       {1152, 597},
-       {1152, 662},
-       {1232, 722},
-       {   0, 805},
-       {   0, 794},
-       {   0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS300_PanelType07_2[] =
-{
-       {1152, 622},
-       {1152, 597},
-       {1152, 622},
-       {1152, 597},
-       {1152, 662},
-       {1232, 722},
-       {   0, 805},
-       {   0, 794},
-       {   0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS300_PanelType08_2[] =
-{
-       {976, 527},
-       {976, 502},
-       {976, 527},
-       {976, 502},
-       {976, 567},
-       {  0, 627},
-       {  0, 627},
-       {  0,   0},
-       {  0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS300_PanelType09_2[] =
-{
-       {1152, 622},
-       {1152, 597},
-       {1152, 622},
-       {1152, 597},
-       {1152, 662},
-       {1232, 722},
-       {   0, 805},
-       {   0, 794},
-       {   0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS300_PanelType0a_2[] =
-{
-       {976, 527},
-       {976, 502},
-       {976, 527},
-       {976, 502},
-       {976, 567},
-       {  0, 627},
-       {  0, 627},
-       {  0,   0},
-       {  0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS300_PanelType0b_2[] =
-{
-       { 1152, 700},
-       { 1152, 675},
-       { 1152, 700},
-       { 1152, 675},
-       { 1152, 740},
-       { 1232, 799},
-       {    0, 799},
-       {    0,   0},
-       {    0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS300_PanelType0c_2[] =
-{
-       {1152, 622},
-       {1152, 597},
-       {1152, 622},
-       {1152, 597},
-       {1152, 662},
-       {1232, 722},
-       {   0, 805},
-       {   0, 794},
-       {   0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS300_PanelType0d_2[] =
-{
-       {1152, 622},
-       {1152, 597},
-       {1152, 622},
-       {1152, 597},
-       {1152, 662},
-       {1232, 722},
-       {   0, 805},
-       {   0, 794},
-       {   0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS300_PanelType0e_2[] =
-{
-       {1152, 622},
-       {1152, 597},
-       {1152, 622},
-       {1152, 597},
-       {1152, 662},
-       {1232, 722},
-       {   0, 805},
-       {   0, 794},
-       {   0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS300_PanelType0f_2[] =
-{
-       {1152, 622},
-       {1152, 597},
-       {1152, 622},
-       {1152, 597},
-       {1152, 662},
-       {1232, 722},
-       {   0, 805},
-       {   0, 794},
-       {   0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS300_PanelTypeNS_1[]=
-{
-       { 0,   0},
-       { 0,   0},
-       { 0,   0},
-       { 0,   0},
-       { 0,   0},
-       { 0,   0},
-       { 0, 805},
-       { 0,   0},
-       { 0,   0},
-       { 0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS300_PanelTypeNS_2[] =
-{
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0}
-};
-
-/* Custom data for Barco iQ R200/300/400 (BIOS 2.00.07) */
-static const SiS_LVDSDesStruct  SiS300_PanelType04_1a[] =      /* 1280x1024 (1366x1024) */
+/* Custom des data for Barco iQ R200/300/400 (BIOS 2.00.07) */
+static const struct SiS_LVDSDes SiS300_PanelType04_1a[] =      /* 1280x1024 (1366x1024) */
 {
        {1330, 798},  /* 320x200 */
        {1330, 794},
@@ -1381,7 +857,7 @@ static const SiS_LVDSDesStruct  SiS300_PanelType04_1a[] =  /* 1280x1024 (1366x102
        {   0,   0}   /* 1360x1024          */
 };
 
-static const SiS_LVDSDesStruct  SiS300_PanelType04_2a[] =
+static const struct SiS_LVDSDes SiS300_PanelType04_2a[] =
 {
        {1152, 622},
        {1152, 597},
@@ -1394,8 +870,8 @@ static const SiS_LVDSDesStruct  SiS300_PanelType04_2a[] =
        {   0,   0}
 };
 
-/* Custom data for Barco iQ G200/300/400 (BIOS 2.00.07) */
-static const SiS_LVDSDesStruct  SiS300_PanelType04_1b[] =      /* 1024x768 */
+/* Custom des data for Barco iQ G200/300/400 (BIOS 2.00.07) */
+static const struct SiS_LVDSDes SiS300_PanelType04_1b[] =      /* 1024x768 */
 {
        {1330, 798},  /* 320x200 */
        {1330, 794},
@@ -1406,7 +882,7 @@ static const SiS_LVDSDesStruct  SiS300_PanelType04_1b[] =  /* 1024x768 */
        {   0, 805}   /* 1024x768 / 512x384 */
 };
 
-static const SiS_LVDSDesStruct  SiS300_PanelType04_2b[] =
+static const struct SiS_LVDSDes SiS300_PanelType04_2b[] =
 {
        {1152, 622},
        {1152, 597},
@@ -1419,376 +895,7 @@ static const SiS_LVDSDesStruct  SiS300_PanelType04_2b[] =
 
 /* CRT1 CRTC for slave modes */
 
-static const SiS_LVDSCRT1DataStruct  SiS300_LVDSCRT1800x600_1[] =
-{
-       {{0x65,0x4f,0x89,0x56,0x83,0xaf,0x1f,
-         0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
-         0x00 }},
-       {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
-         0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
-         0x00 }},
-       {{0x65,0x4f,0x89,0x56,0x83,0xaf,0x1f,
-         0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
-         0x00 }},
-       {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
-         0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
-         0x00 }},
-       {{0x65,0x4f,0x89,0x56,0x83,0x04,0x3e,
-         0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
-         0x00 }},
-       {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
-         0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
-         0x01 }}
-};
-
-static const SiS_LVDSCRT1DataStruct  SiS300_LVDSCRT1800x600_1_H[] =
-{
-       {{0x30,0x27,0x94,0x2c,0x92,0xaf,0x1f,
-         0x90,0x85,0x8f,0xab,0x30,0x00,0x04,
-         0x00 }},
-       {{0x30,0x27,0x94,0x2c,0x92,0x83,0x1f,
-         0x5e,0x83,0x5d,0x79,0x10,0x00,0x04,
-         0x00 }},
-       {{0x30,0x27,0x94,0x2c,0x92,0xaf,0x1f,
-         0x90,0x85,0x8f,0xab,0x30,0x00,0x04,
-         0x00 }},
-       {{0x30,0x27,0x94,0x2c,0x92,0x83,0x1f,
-         0x5e,0x83,0x5d,0x79,0x10,0x00,0x04,
-         0x00 }},
-       {{0x30,0x27,0x94,0x2c,0x92,0x04,0x3e,
-         0xe0,0x85,0xdf,0xfb,0x10,0x00,0x04,
-         0x00 }},
-       {{0x3d,0x31,0x81,0x37,0x1f,0x72,0xf0,
-         0x58,0x8c,0x57,0x73,0x20,0x00,0x05,
-         0x01 }}
-};
-
-static const SiS_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_1[] =
-{
-       {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
-         0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
-         0x00}},
-       {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
-         0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
-         0x00}},
-       {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
-         0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
-         0x00}},
-       {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
-         0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
-         0x00}},
-       {{0x64,0x4f,0x88,0x54,0x9f,0x04,0x3e,
-         0xe2,0x89,0xdf,0x05,0x00,0x00,0x01,
-         0x00}},
-       {{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0,
-         0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26,
-         0x01}},
-       {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
-         0x02,0x88,0xff,0x25,0x10,0x00,0x02,
-         0x01}}
-};
-
-static const SiS_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_1_H[] =
-{
-       {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
-         0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
-         0x00 }},
-       {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
-         0x60,0x87,0x5D,0x83,0x10,0x00,0x44,
-         0x00}},
-       {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
-         0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
-         0x00}},
-       {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
-         0x60,0x87,0x5D,0x83,0x10,0x00,0x44,
-         0x00}},
-       {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
-         0xE2,0x89,0xdf,0x05,0x00,0x00,0x44,
-         0x00}},
-       {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
-         0x5A,0x8F,0x57,0x7D,0x20,0x00,0x55,
-         0x01}},
-       {{0x4f,0x3F,0x93,0x45,0x0D,0x24,0xf5,
-         0x02,0x88,0xff,0x25,0x10,0x00,0x01,
-         0x01 }}
-
-#if 0
-       {{0x37,0x27,0x9B,0x2b,0x94,0xc4,0x1f,
-         0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
-         0x00 }},
-       {{0x37,0x27,0x9B,0x2b,0x94,0x97,0x1f,
-         0x60,0x87,0x5D,0x83,0x01,0x00,0x44,
-         0x00}},
-       {{0x37,0x27,0x9B,0x2b,0x94,0xc4,0x1f,
-         0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
-         0x00}},
-       {{0x37,0x27,0x9B,0x2b,0x94,0x97,0x1f,
-         0x60,0x87,0x5D,0x83,0x01,0x00,0x44,
-         0x00}},
-       {{0x37,0x27,0x9B,0x2b,0x94,0x04,0x3e,
-         0xE2,0x89,0xDf,0x05,0x00,0x00,0x44,
-         0x00}},
-       {{0x41,0x31,0x85,0x35,0x1d,0x7c,0xf0,
-         0x5A,0x8F,0x57,0x7D,0x20,0x00,0x55,
-         0x01}},
-       {{0x4f,0x3F,0x93,0x45,0x0D,0x24,0xf5,
-         0x02,0x88,0xFf,0x25,0x10,0x00,0x01,
-         0x01 }}
-#endif
-};
-
-static const SiS_LVDSCRT1DataStruct  SiS300_LVDSCRT11280x1024_1[] =
-{
-       {{0x63,0x4f,0x87,0x54,0x9f,0xb4,0x1f,
-         0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
-         0x00 }},
-       {{0x63,0x4f,0x87,0x54,0x9f,0x82,0x1f,
-         0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
-         0x00 }},
-       {{0x63,0x4f,0x87,0x54,0x9f,0xb4,0x1f,
-         0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
-         0x00 }},
-       {{0x63,0x4f,0x87,0x54,0x9f,0x82,0x1f,
-         0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
-         0x00 }},
-       {{0x63,0x4f,0x87,0x54,0x9f,0x04,0x3e,
-         0xe2,0x89,0xdf,0x05,0x00,0x00,0x01,
-         0x00 }},
-       {{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0,
-         0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26,
-         0x01 }},
-       {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
-         0x02,0x88,0xff,0x25,0x10,0x00,0x02,
-         0x01 }}
-};
-
-static const SiS_LVDSCRT1DataStruct  SiS300_LVDSCRT11280x1024_1_H[] =
-{
-       {{0x2f,0x27,0x93,0x2b,0x90,0xb4,0x1f,
-         0x92,0x89,0x8f,0xb5,0x30,0x00,0x04,
-         0x00 }},
-       {{0x2f,0x27,0x93,0x2b,0x90,0x82,0x1f,
-         0x60,0x87,0x5d,0x83,0x10,0x00,0x04,
-         0x00 }},
-       {{0x2f,0x27,0x93,0x2b,0x90,0xb4,0x1f,
-         0x92,0x89,0x8f,0xb5,0x30,0x00,0x04,
-         0x00 }},
-       {{0x2f,0x27,0x93,0x2b,0x90,0x82,0x1f,
-         0x60,0x87,0x5d,0x83,0x10,0x00,0x04,
-         0x00 }},
-       {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
-         0xe2,0x89,0xdf,0x05,0x00,0x00,0x04,
-         0x00 }},
-       {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
-         0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
-         0x01 }},
-       {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
-         0x02,0x88,0xff,0x25,0x10,0x00,0x01,
-         0x01 }}
-};
-
-static const SiS_LVDSCRT1DataStruct  SiS300_LVDSCRT1800x600_2[] =
-{
-       {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
-         0xf4,0x88,0x8f,0x73,0x20,0x00,0x06,
-         0x00 }},
-       {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
-         0xdb,0x8f,0x5d,0x73,0x20,0x00,0x06,
-         0x00 }},
-       {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
-         0xf4,0x88,0x8f,0x73,0x20,0x00,0x06,
-         0x00 }},
-       {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
-         0xdb,0x8f,0x5d,0x73,0x20,0x00,0x06,
-         0x00 }},
-       {{0x7f,0x4f,0x83,0x62,0x12,0x72,0xba,
-         0x1c,0x80,0xdf,0x73,0x00,0x00,0x06,
-         0x00 }},
-       {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
-         0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
-         0x01 }}
-};
-
-static const SiS_LVDSCRT1DataStruct  SiS300_LVDSCRT1800x600_2_H[] =
-{
-       {{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
-         0xf4,0x88,0x8f,0x73,0x20,0x00,0x05,
-         0x00 }},
-       {{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
-         0xdb,0x8f,0x5d,0x73,0x20,0x00,0x05,
-         0x00 }},
-       {{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
-         0xf4,0x88,0x8f,0x73,0x20,0x00,0x05,
-         0x00 }},
-       {{0x3d,0x27,0x81,0x3a,0x1a,0x72,0x3e,
-         0xdb,0x8f,0x5d,0x73,0x20,0x00,0x05,
-         0x00 }},
-       {{0x3d,0x27,0x81,0x32,0x1a,0x72,0xba,
-         0x1c,0x80,0xdf,0x73,0x00,0x00,0x05,
-         0x00 }},
-       {{0x3d,0x31,0x81,0x37,0x1f,0x72,0xf0,
-         0x58,0x8c,0x57,0x73,0x20,0x00,0x05,
-         0x01 }}
-};
-
-static const SiS_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_2[] =
-{
-       {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-         0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
-         0x00 }},
-       {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-         0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
-         0x00 }},
-       {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-         0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
-         0x00 }},
-       {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-         0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
-         0x00 }},
-       {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-         0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
-         0x00 }},
-       {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
-         0xae,0x84,0x57,0x25,0x30,0x00,0x02,
-         0x01 }},
-       {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
-         0x02,0x88,0xff,0x25,0x10,0x00,0x02,
-         0x01 }}
-};
-
-static const SiS_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_2_H[] =
-{
-       {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-         0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
-         0x00 }},
-       {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-         0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
-         0x00 }},
-       {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-         0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
-         0x00 }},
-       {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-         0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
-         0x00 }},
-       {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-         0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
-         0x00 }},
-       {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
-         0xae,0x84,0x57,0x25,0x30,0x00,0x01,
-         0x01 }},
-       {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
-         0x02,0x88,0xff,0x25,0x10,0x00,0x01,
-         0x01 }}
-};
-
-static const SiS_LVDSCRT1DataStruct  SiS300_LVDSCRT11280x1024_2[] =
-{
-       {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-         0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
-         0x00 }},
-       {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-         0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
-         0x00 }},
-       {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-         0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
-         0x00 }},
-       {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-         0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
-         0x00 }},
-       {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-         0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
-         0x00 }},
-       {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
-         0xae,0x84,0x57,0x25,0x30,0x00,0x02,
-         0x01 }},
-       {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
-         0x02,0x88,0xff,0x25,0x10,0x00,0x02,
-         0x01 }}
-};
-
-static const SiS_LVDSCRT1DataStruct  SiS300_LVDSCRT11280x1024_2_H[] =
-{
-       {{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
-         0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
-         0x00 }},
-       {{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
-         0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
-         0x00 }},
-       {{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
-         0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
-         0x00 }},
-       {{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
-         0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
-         0x00 }},
-       {{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
-         0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
-         0x00 }},
-       {{0x4f,0x31,0x93,0x3e,0x86,0x24,0xf1,
-         0xae,0x84,0x57,0x25,0x30,0x00,0x01,
-         0x01 }},
-       {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
-         0x02,0x88,0xff,0x25,0x10,0x00,0x01,
-         0x01}}
-};
-
-static const SiS_LVDSCRT1DataStruct  SiS300_LVDSCRT1XXXxXXX_1[] =
-{
- {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
-   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
-   0x00}},
- {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
-   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
-   0x00}},
- {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
-   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
-   0x00}},
- {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
-   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
-   0x00}},
- {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
-   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x05,
-   0x00}},
- {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
-   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
-   0x01}},
- {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
-   0x02,0x88,0xff,0x25,0x10,0x00,0x02,
-   0x01}},
- {{0xce,0x9f,0x92,0xa8,0x14,0x28,0x5a,
-   0x00,0x84,0xff,0x29,0x09,0x00,0x07,
-   0x01}},
- {{0xce,0x9f,0x92,0xa9,0x17,0x24,0xf5,
-   0x02,0x88,0xff,0x25,0x10,0x00,0x07,
-   0x01}}
-};
-
-static const SiS_LVDSCRT1DataStruct  SiS300_LVDSCRT1XXXxXXX_1_H[] =
-{
- {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
-   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
-   0x00}},
- {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
-   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
-   0x00}},
- {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
-   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
-   0x00}},
- {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
-   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
-   0x00}},
- {{0x38,0x27,0x9c,0x2c,0x80,0x0b,0x3e,
-   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
-   0x00}},
- {{0x4d,0x31,0x91,0x3b,0x03,0x72,0xf0,
-   0x58,0x8c,0x57,0x73,0x20,0x00,0x01,
-   0x01}},
- {{0x63,0x3f,0x87,0x4a,0x92,0x24,0xf5,
-   0x02,0x88,0xff,0x25,0x10,0x00,0x01,
-   0x01}}
-};
-
-
-static const SiS_LVDSCRT1DataStruct  SiS300_CHTVCRT1UNTSC[] =
+static const struct SiS_LVDSCRT1Data SiS300_CHTVCRT1UNTSC[] =
 {
        {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
          0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,
@@ -1810,7 +917,7 @@ static const SiS_LVDSCRT1DataStruct  SiS300_CHTVCRT1UNTSC[] =
          0x01 }}
 };
 
-static const SiS_LVDSCRT1DataStruct  SiS300_CHTVCRT1ONTSC[] =
+static const struct SiS_LVDSCRT1Data SiS300_CHTVCRT1ONTSC[] =
 {
        {{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
          0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,
@@ -1832,7 +939,7 @@ static const SiS_LVDSCRT1DataStruct  SiS300_CHTVCRT1ONTSC[] =
          0x01 }}
 };
 
-static const SiS_LVDSCRT1DataStruct  SiS300_CHTVCRT1UPAL[] =
+static const struct SiS_LVDSCRT1Data SiS300_CHTVCRT1UPAL[] =
 {
        {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
          0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,
@@ -1854,7 +961,7 @@ static const SiS_LVDSCRT1DataStruct  SiS300_CHTVCRT1UPAL[] =
          0x01 }}
 };
 
-static const SiS_LVDSCRT1DataStruct  SiS300_CHTVCRT1OPAL[] =
+static const struct SiS_LVDSCRT1Data SiS300_CHTVCRT1OPAL[] =
 {
        {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
          0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
@@ -1876,7 +983,7 @@ static const SiS_LVDSCRT1DataStruct  SiS300_CHTVCRT1OPAL[] =
          0x01 }}
 };
 
-static const SiS_LVDSCRT1DataStruct  SiS300_CHTVCRT1SOPAL[] =
+static const struct SiS_LVDSCRT1Data SiS300_CHTVCRT1SOPAL[] =
 {
        {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
          0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
@@ -1898,7 +1005,7 @@ static const SiS_LVDSCRT1DataStruct  SiS300_CHTVCRT1SOPAL[] =
          0x01 }}
 };
 
-static const SiS_CHTVRegDataStruct SiS300_CHTVReg_UNTSC[] =
+static const struct SiS_CHTVRegData SiS300_CHTVReg_UNTSC[] =
 {
        {{0x4a,0x94,0x00,0x48,0xfe,0,0,0,0,0,0,0,0,0,0,0}},
        {{0x4a,0x94,0x00,0x48,0xfe,0,0,0,0,0,0,0,0,0,0,0}},
@@ -1908,7 +1015,7 @@ static const SiS_CHTVRegDataStruct SiS300_CHTVReg_UNTSC[] =
        {{0x8d,0xc4,0x00,0x3b,0xfb,0,0,0,0,0,0,0,0,0,0,0}}  /* Mode 24: 800x600 NTSC 7/10 */
 };
 
-static const SiS_CHTVRegDataStruct SiS300_CHTVReg_ONTSC[] =
+static const struct SiS_CHTVRegData SiS300_CHTVReg_ONTSC[] =
 {
        {{0x49,0x94,0x00,0x34,0xfe,0,0,0,0,0,0,0,0,0,0,0}},
        {{0x49,0x94,0x00,0x34,0xfe,0,0,0,0,0,0,0,0,0,0,0}},
@@ -1918,7 +1025,7 @@ static const SiS_CHTVRegDataStruct SiS300_CHTVReg_ONTSC[] =
        {{0x8c,0xb4,0x00,0x32,0xf9,0,0,0,0,0,0,0,0,0,0,0}}  /* Mode 23: 800x600 NTSC 3/4 */
 };
 
-static const SiS_CHTVRegDataStruct SiS300_CHTVReg_UPAL[] =
+static const struct SiS_CHTVRegData SiS300_CHTVReg_UPAL[] =
 {
        {{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}},
        {{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}},
@@ -1929,7 +1036,7 @@ static const SiS_CHTVRegDataStruct SiS300_CHTVReg_UPAL[] =
 
 };
 
-static const SiS_CHTVRegDataStruct SiS300_CHTVReg_OPAL[] =
+static const struct SiS_CHTVRegData SiS300_CHTVReg_OPAL[] =
 {
        {{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 9: 640x400 PAL 1/1 */
        {{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}},
@@ -1940,26 +1047,26 @@ static const SiS_CHTVRegDataStruct SiS300_CHTVReg_OPAL[] =
 
 };
 
-static const SiS_CHTVRegDataStruct SiS300_CHTVReg_SOPAL[] =
+static const struct SiS_CHTVRegData SiS300_CHTVReg_SOPAL[] =
 {
        {{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 9: 640x400 PAL 1/1 */
        {{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}},
        {{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}},
        {{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}},
-       {{0x60,0x30,0x00,0x10,0x00,0,0,0,0,0,0,0,0,0,0,0}}, /* TW: Mode 13: 640x480 PAL 5/4 */
-       {{0x81,0x50,0x00,0x1b,0x00,0,0,0,0,0,0,0,0,0,0,0}}  /* TW: Mode 19: 800x600 PAL 1/1 */
+       {{0x60,0x30,0x00,0x10,0x00,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 13: 640x480 PAL 5/4 */
+       {{0x81,0x50,0x00,0x1b,0x00,0,0,0,0,0,0,0,0,0,0,0}}  /* Mode 19: 800x600 PAL 1/1 */
 };
 
-static const UCHAR SiS300_CHTVVCLKUNTSC[]  = {0x29,0x29,0x29,0x29,0x2a,0x2e};
+static const unsigned char SiS300_CHTVVCLKUNTSC[]  = { 0x29,0x29,0x29,0x29,0x2a,0x2e };
 
-static const UCHAR SiS300_CHTVVCLKONTSC[]  = {0x2c,0x2c,0x2c,0x2c,0x2d,0x2b};
+static const unsigned char SiS300_CHTVVCLKONTSC[]  = { 0x2c,0x2c,0x2c,0x2c,0x2d,0x2b };
 
-static const UCHAR SiS300_CHTVVCLKSONTSC[] = {0x2c,0x2c,0x2c,0x2c,0x2d,0x2b};
+static const unsigned char SiS300_CHTVVCLKSONTSC[] = { 0x2c,0x2c,0x2c,0x2c,0x2d,0x2b };
 
-static const UCHAR SiS300_CHTVVCLKUPAL[]   = {0x2f,0x2f,0x2f,0x2f,0x2f,0x31};
+static const unsigned char SiS300_CHTVVCLKUPAL[]   = { 0x2f,0x2f,0x2f,0x2f,0x2f,0x31 };
 
-static const UCHAR SiS300_CHTVVCLKOPAL[]   = {0x2f,0x2f,0x2f,0x2f,0x30,0x32};
+static const unsigned char SiS300_CHTVVCLKOPAL[]   = { 0x2f,0x2f,0x2f,0x2f,0x30,0x32 };
 
-static const UCHAR SiS300_CHTVVCLKSOPAL[]  = {0x2f,0x2f,0x2f,0x2f,0x36,0x29};
+static const unsigned char SiS300_CHTVVCLKSOPAL[]  = { 0x2f,0x2f,0x2f,0x2f,0x36,0x29 };
 
 
index 2c71d04..54fcbbf 100644 (file)
@@ -1,9 +1,9 @@
 /* $XFree86$ */
 /* $XdotOrg$ */
 /*
- * Register settings for SiS 315/330 series
+ * Register settings for SiS 315/330/340 series
  *
- * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
  *
  * If distributed as part of the Linux kernel, the following license terms
  * apply:
  *
  */
 
-static const SiS_StStruct SiS310_SModeIDTable[]=
-{
-       {0x01,0x9208,0x01,0x00,0x00,0x00,0x01,0x00, 0x40},
-       {0x01,0x1210,0x14,0x01,0x01,0x00,0x01,0x00, 0x40},
-       {0x01,0x1010,0x17,0x02,0x02,0x00,0x01,0x01, 0x40},
-       {0x03,0x8208,0x03,0x00,0x00,0x00,0x01,0x02, 0x40},
-       {0x03,0x0210,0x16,0x01,0x01,0x00,0x01,0x02, 0x40},
-       {0x03,0x0010,0x18,0x02,0x02,0x00,0x01,0x03, 0x40},
-       {0x05,0x9209,0x05,0x00,0x00,0x00,0x00,0x04, 0x40},
-       {0x06,0x8209,0x06,0x00,0x00,0x00,0x00,0x05, 0x40},
-       {0x07,0x0000,0x07,0x03,0x03,0x00,0x01,0x03, 0x40},
-       {0x07,0x0000,0x19,0x02,0x02,0x00,0x01,0x03, 0x40},
-       {0x0d,0x920a,0x0d,0x00,0x00,0x00,0x00,0x04, 0x40},
-       {0x0e,0x820a,0x0e,0x00,0x00,0x00,0x00,0x05, 0x40},
-       {0x0f,0x0202,0x11,0x01,0x01,0x00,0x00,0x05, 0x40},
-       {0x10,0x0212,0x12,0x01,0x01,0x00,0x00,0x05, 0x40},
-       {0x11,0x0212,0x1a,0x04,0x04,0x00,0x00,0x05, 0x40},
-       {0x12,0x0212,0x1b,0x04,0x04,0x00,0x00,0x05, 0x40},
-       {0x13,0x021b,0x1c,0x00,0x00,0x00,0x00,0x04, 0x40},
-       {0x12,0x0010,0x18,0x02,0x02,0x00,0x00,0x05, 0x40},
-       {0x12,0x0210,0x18,0x01,0x01,0x00,0x00,0x05, 0x40},
-       {0xff,0x0000,0x00,0x00,0x00,0x00,0x00,0x00, 0x40}
-};
-
-static const SiS_ExtStruct  SiS310_EModeIDTable[]=
+static const struct SiS_Ext SiS310_EModeIDTable[] =
 {
        {0x6a,0x2212,0x0102,SIS_RI_800x600,  0x00,0x00,0x07,0x06,0x00, 3}, /* 800x600x? */
        {0x2e,0x0a1b,0x0101,SIS_RI_640x480,  0x00,0x00,0x05,0x05,0x08, 2}, /* 640x480x8 */
-        {0x2f,0x0a1b,0x0100,SIS_RI_640x400,  0x00,0x00,0x05,0x05,0x10, 0}, /* 640x400x8 */
+       {0x2f,0x0a1b,0x0100,SIS_RI_640x400,  0x00,0x00,0x05,0x05,0x10, 0}, /* 640x400x8 */
        {0x30,0x2a1b,0x0103,SIS_RI_800x600,  0x00,0x00,0x07,0x06,0x00, 3}, /* 800x600x8 */
-        {0x31,0x4a1b,0x0000,SIS_RI_720x480,  0x00,0x00,0x06,0x06,0x11,-1}, /* 720x480x8 */
+       {0x31,0x4a1b,0x0000,SIS_RI_720x480,  0x00,0x00,0x06,0x06,0x11,-1}, /* 720x480x8 */
        {0x32,0x4a1b,0x0000,SIS_RI_720x576,  0x00,0x00,0x06,0x06,0x12,-1}, /* 720x576x8 */
        {0x33,0x4a1d,0x0000,SIS_RI_720x480,  0x00,0x00,0x06,0x06,0x11,-1}, /* 720x480x16 */
        {0x34,0x6a1d,0x0000,SIS_RI_720x576,  0x00,0x00,0x06,0x06,0x12,-1}, /* 720x576x16 */
@@ -103,10 +79,10 @@ static const SiS_ExtStruct  SiS310_EModeIDTable[]=
        {0x4d,0x0e7d,0x011a,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a, 8}, /* 1280x1024x16 */
        {0x50,0x9a1b,0x0132,SIS_RI_320x240,  0x00,0x00,0x04,0x04,0x26, 2}, /* 320x240x8  */
        {0x51,0xba1b,0x0133,SIS_RI_400x300,  0x00,0x00,0x07,0x07,0x27, 3}, /* 400x300x8  */
-       {0x52,0xba1b,0x0134,SIS_RI_512x384,  0x00,0x00,0x00,0x00,0x28, 4}, /* 512x384x8  */
+       {0x52,0xba1b,0x0134,SIS_RI_512x384,  0x00,0x00,0x00,0x00,0x28, 4}, /* 512x384x8  */
        {0x56,0x9a1d,0x0135,SIS_RI_320x240,  0x00,0x00,0x04,0x04,0x26, 2}, /* 320x240x16 */
        {0x57,0xba1d,0x0136,SIS_RI_400x300,  0x00,0x00,0x07,0x07,0x27, 3}, /* 400x300x16 */
-       {0x58,0xba1d,0x0137,SIS_RI_512x384,  0x00,0x00,0x00,0x00,0x28, 4}, /* 512x384x16 */
+       {0x58,0xba1d,0x0137,SIS_RI_512x384,  0x00,0x00,0x00,0x00,0x28, 4}, /* 512x384x16 */
        {0x59,0x9a1b,0x0138,SIS_RI_320x200,  0x00,0x00,0x04,0x04,0x25, 0}, /* 320x200x8  */
        {0x5a,0x021b,0x0138,SIS_RI_320x240,  0x00,0x00,0x00,0x00,0x3f, 2}, /* 320x240x8  fstn */
        {0x5b,0x0a1d,0x0135,SIS_RI_320x240,  0x00,0x00,0x00,0x00,0x3f, 2}, /* 320x240x16 fstn */
@@ -139,406 +115,335 @@ static const SiS_ExtStruct  SiS310_EModeIDTable[]=
        {0x23,0x0e3b,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x40, 6}, /* 1280x768x8 */
        {0x24,0x0e7d,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x40, 6}, /* 1280x768x16 */
        {0x25,0x0eff,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x40, 6}, /* 1280x768x32 */
-       {0x26,0x0e3b,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x00,0x41, 9}, /* 1400x1050x8 */
-       {0x27,0x0e7d,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x00,0x41, 9}, /* 1400x1050x16 */
-       {0x28,0x0eff,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x00,0x41, 9}, /* 1400x1050x32*/
-       {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,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},
+       {0x26,0x0e3b,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x00,0x43, 9}, /* 1400x1050x8 */
+       {0x27,0x0e7d,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x00,0x43, 9}, /* 1400x1050x16 */
+       {0x28,0x0eff,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x00,0x43, 9}, /* 1400x1050x32*/
+       {0x29,0x4e1b,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x45,-1}, /* 1152x864 */
+       {0x2a,0x4e3d,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x45,-1},
+       {0x2b,0x4e7f,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x45,-1},
+       {0x39,0x6a1b,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x00,0x48,-1}, /* 848x480 */
+       {0x3b,0x6a3d,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x00,0x48,-1},
+       {0x3e,0x6a7f,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x00,0x48,-1},
+       {0x3f,0x6a1b,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x00,0x4a,-1}, /* 856x480 */
+       {0x42,0x6a3d,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x00,0x4a,-1},
+       {0x45,0x6a7f,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x00,0x4a,-1},
+       {0x48,0x6a3b,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x4c,-1}, /* 1360x768 */
+       {0x4b,0x6a7d,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x4c,-1},
+       {0x4e,0x6aff,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x4c,-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,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},
+       {0x5f,0x6a1b,0x0000,SIS_RI_768x576,  0x00,0x00,0x06,0x06,0x4d,-1}, /* 768x576 */
+       {0x60,0x6a1d,0x0000,SIS_RI_768x576,  0x00,0x00,0x06,0x06,0x4d,-1},
+       {0x61,0x6a3f,0x0000,SIS_RI_768x576,  0x00,0x00,0x06,0x06,0x4d,-1},
+       {0x14,0x0e3b,0x0000,SIS_RI_1280x800, 0x00,0x00,0x00,0x00,0x4e, 7}, /* 1280x800 */
+       {0x15,0x0e7d,0x0000,SIS_RI_1280x800, 0x00,0x00,0x00,0x00,0x4e, 7},
+       {0x16,0x0eff,0x0000,SIS_RI_1280x800, 0x00,0x00,0x00,0x00,0x4e, 7},
+       {0x17,0x0e3b,0x0000,SIS_RI_1680x1050,0x00,0x00,0x00,0x00,0x51, 9}, /* 1680x1050 */
+       {0x18,0x0e7d,0x0000,SIS_RI_1680x1050,0x00,0x00,0x00,0x00,0x51, 9},
+       {0x19,0x0eff,0x0000,SIS_RI_1680x1050,0x00,0x00,0x00,0x00,0x51, 9},
+       {0x2c,0x267b,0x0000,SIS_RI_1920x1080,0x00,0x00,0x00,0x00,0x52,-1}, /* 1920x1080(i) */
+       {0x2d,0x26fd,0x0000,SIS_RI_1920x1080,0x00,0x00,0x00,0x00,0x52,-1},
+       {0x73,0x27ff,0x0000,SIS_RI_1920x1080,0x00,0x00,0x00,0x00,0x52,-1},
+       {0x1d,0x6a1b,0x0000,SIS_RI_960x540,  0x00,0x00,0x00,0x00,0x53,-1}, /* 960x540 */
+       {0x1e,0x6a3d,0x0000,SIS_RI_960x540,  0x00,0x00,0x00,0x00,0x53,-1},
+       {0x1f,0x6a7f,0x0000,SIS_RI_960x540,  0x00,0x00,0x00,0x00,0x53,-1},
+       {0x20,0x6a1b,0x0000,SIS_RI_960x600,  0x00,0x00,0x00,0x00,0x54,-1}, /* 960x600 */
+       {0x21,0x6a3d,0x0000,SIS_RI_960x600,  0x00,0x00,0x00,0x00,0x54,-1},
+       {0x22,0x6a7f,0x0000,SIS_RI_960x600,  0x00,0x00,0x00,0x00,0x54,-1},
+       {0x1a,0x0e3b,0x0000,SIS_RI_1280x854, 0x00,0x00,0x00,0x00,0x55, 8}, /* 1280x854 */
+       {0x1b,0x0e7d,0x0000,SIS_RI_1280x854, 0x00,0x00,0x00,0x00,0x55, 8},
+       {0x1c,0x0eff,0x0000,SIS_RI_1280x854, 0x00,0x00,0x00,0x00,0x55, 8},
        {0xff,0x0000,0x0000,0,               0x00,0x00,0x00,0x00,0x00,-1}
 };
 
-static const SiS_Ext2Struct SiS310_RefIndex[]=
-{
-       {0x085f,0x0d,0x03,0x05,0x05,0x6a, 800, 600, 0x40}, /* 0x0 */
-       {0x0067,0x0e,0x04,0x05,0x05,0x6a, 800, 600, 0x40}, /* 0x1 */
-       {0x0067,0x0f,0x08,0x48,0x05,0x6a, 800, 600, 0x40}, /* 0x2 */
-       {0x0067,0x10,0x07,0x8b,0x05,0x6a, 800, 600, 0x40}, /* 0x3 */
-       {0x0047,0x11,0x0a,0x00,0x05,0x6a, 800, 600, 0x40}, /* 0x4 */
-       {0x0047,0x12,0x0d,0x00,0x05,0x6a, 800, 600, 0x40}, /* 0x5 */
-       {0x0047,0x13,0x13,0x00,0x05,0x6a, 800, 600, 0x20}, /* 0x6 */
-       {0x0107,0x14,0x1c,0x00,0x05,0x6a, 800, 600, 0x20}, /* 0x7 */
-       {0xc85f,0x05,0x00,0x04,0x04,0x2e, 640, 480, 0x40}, /* 0x8 */
-       {0xc067,0x06,0x02,0x04,0x04,0x2e, 640, 480, 0x40}, /* 0x9 */
-       {0xc067,0x07,0x02,0x47,0x04,0x2e, 640, 480, 0x40}, /* 0xa */
-       {0xc067,0x08,0x03,0x8a,0x04,0x2e, 640, 480, 0x40}, /* 0xb */
-       {0xc047,0x09,0x05,0x00,0x04,0x2e, 640, 480, 0x40}, /* 0xc */
-       {0xc047,0x0a,0x09,0x00,0x04,0x2e, 640, 480, 0x40}, /* 0xd */
-       {0xc047,0x0b,0x0e,0x00,0x04,0x2e, 640, 480, 0x40}, /* 0xe */
-       {0xc047,0x0c,0x15,0x00,0x04,0x2e, 640, 480, 0x40}, /* 0xf */
-       {0x487f,0x04,0x00,0x00,0x00,0x2f, 640, 400, 0x30}, /* 0x10 */
-       {0xc06f,0x3c,0x01,0x06,0x13,0x31, 720, 480, 0x30}, /* 0x11 */
-       {0x006f,0x3d,0x03,0x06,0x14,0x32, 720, 576, 0x30}, /* 0x12 */
-       {0x0087,0x15,0x06,0x00,0x06,0x37,1024, 768, 0x30}, /* 0x13 */
-       {0xc877,0x16,0x0b,0x06,0x06,0x37,1024, 768, 0x20}, /* 0x14 */
-       {0xc067,0x17,0x0f,0x49,0x06,0x37,1024, 768, 0x20}, /* 0x15 */
-       {0x0067,0x18,0x11,0x00,0x06,0x37,1024, 768, 0x20}, /* 0x16 */
-       {0x0047,0x19,0x16,0x8c,0x06,0x37,1024, 768, 0x20}, /* 0x17 */
-       {0x0107,0x1a,0x1b,0x00,0x06,0x37,1024, 768, 0x10}, /* 0x18 */
-       {0x0107,0x1b,0x1f,0x00,0x06,0x37,1024, 768, 0x10}, /* 0x19 */
-       {0x0087,0x1c,0x11,0x00,0x07,0x3a,1280,1024, 0x30}, /* 0x1a */
-       {0x0137,0x1d,0x19,0x07,0x07,0x3a,1280,1024, 0x00}, /* 0x1b */
-       {0x0107,0x1e,0x1e,0x00,0x07,0x3a,1280,1024, 0x00}, /* 0x1c */
-       {0x0207,0x1f,0x20,0x00,0x07,0x3a,1280,1024, 0x00}, /* 0x1d */
-       {0x0227,0x20,0x21,0x09,0x09,0x3c,1600,1200, 0x00}, /* 0x1e */
-       {0x0407,0x21,0x22,0x00,0x09,0x3c,1600,1200, 0x00}, /* 0x1f */
-       {0x0407,0x22,0x23,0x00,0x09,0x3c,1600,1200, 0x00}, /* 0x20 */
-       {0x0407,0x23,0x25,0x00,0x09,0x3c,1600,1200, 0x00}, /* 0x21 */
-       {0x0007,0x24,0x26,0x00,0x09,0x3c,1600,1200, 0x00}, /* 0x22 */
-       {0x0007,0x25,0x2c,0x00,0x09,0x3c,1600,1200, 0x00}, /* 0x23 */
-       {0x0007,0x26,0x34,0x00,0x09,0x3c,1600,1200, 0x00}, /* 0x24 */
-       {0x407f,0x00,0x00,0x00,0x00,0x40, 320, 200, 0x30}, /* 0x25 */
-       {0xc07f,0x01,0x00,0x04,0x04,0x50, 320, 240, 0x30}, /* 0x26 */
-       {0x007f,0x02,0x04,0x05,0x05,0x51, 400, 300, 0x30}, /* 0x27 */
-       {0xc077,0x03,0x0b,0x06,0x06,0x52, 512, 384, 0x30}, /* 0x28 */
-       {0x8007,0x27,0x27,0x00,0x00,0x68,1920,1440, 0x00}, /* 0x29 */
-       {0x4007,0x28,0x29,0x00,0x00,0x68,1920,1440, 0x00}, /* 0x2a */
-       {0x4007,0x29,0x2e,0x00,0x00,0x68,1920,1440, 0x00}, /* 0x2b */
-       {0x4007,0x2a,0x30,0x00,0x00,0x68,1920,1440, 0x00}, /* 0x2c */
-       {0x4007,0x2b,0x35,0x00,0x00,0x68,1920,1440, 0x00}, /* 0x2d */
-       {0x4005,0x2c,0x39,0x00,0x00,0x68,1920,1440, 0x00}, /* 0x2e */
-       {0x4007,0x2d,0x2b,0x00,0x00,0x6c,2048,1536, 0x00}, /* 0x2f */
-       {0x4007,0x2e,0x31,0x00,0x00,0x6c,2048,1536, 0x00}, /* 0x30 */
-       {0x4007,0x2f,0x33,0x00,0x00,0x6c,2048,1536, 0x00}, /* 0x31 */
-       {0x4007,0x30,0x37,0x00,0x00,0x6c,2048,1536, 0x00}, /* 0x32 */
-       {0x4005,0x31,0x38,0x00,0x00,0x6c,2048,1536, 0x00}, /* 0x33 */
-       {0x0077,0x32,0x40,0x08,0x18,0x70, 800, 480, 0x30}, /* 0x34 */
-       {0x0047,0x33,0x07,0x08,0x18,0x70, 800, 480, 0x30}, /* 0x35 */
-       {0x0047,0x34,0x0a,0x08,0x18,0x70, 800, 480, 0x30}, /* 0x36 */
-       {0x0077,0x35,0x0b,0x09,0x19,0x71,1024, 576, 0x30}, /* 0x37 */
-       {0x0047,0x36,0x11,0x09,0x19,0x71,1024, 576, 0x30}, /* 0x38 */
-       {0x0047,0x37,0x16,0x09,0x19,0x71,1024, 576, 0x30}, /* 0x39 */
-       {0x1137,0x38,0x19,0x0a,0x0c,0x75,1280, 720, 0x30}, /* 0x3a */
-       {0x1107,0x39,0x1e,0x0a,0x0c,0x75,1280, 720, 0x30}, /* 0x3b */
-       {0x1307,0x3a,0x20,0x0a,0x0c,0x75,1280, 720, 0x30}, /* 0x3c */
-       {0x0127,0x3b,0x19,0x08,0x0a,0x7c,1280, 960, 0x30}, /* 0x3d */
-       {0x0227,0x4c,0x59,0x08,0x0a,0x7c,1280, 960, 0x20}, /* 0x3e */
-       {0xc07f,0x4e,0x00,0x06,0x04,0x5a, 320, 240, 0x30}, /* 0x3f */    /* FSTN 320x240 */
-        {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,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[]=
+static const struct SiS_Ext2 SiS310_RefIndex[] =
+{
+       {0x085f,0x0d,0x03,0x05,0x05,0x6a, 800, 600, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x0 */
+       {0x0067,0x0e,0x04,0x05,0x05,0x6a, 800, 600, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x1 */
+       {0x0067,0x0f,0x08,0x48,0x05,0x6a, 800, 600, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x2 */
+       {0x0067,0x10,0x07,0x8b,0x05,0x6a, 800, 600, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x3 */
+       {0x0047,0x11,0x0a,0x00,0x05,0x6a, 800, 600, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x4 */
+       {0x0047,0x12,0x0d,0x00,0x05,0x6a, 800, 600, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x5 */
+       {0x0047,0x13,0x13,0x00,0x05,0x6a, 800, 600, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x6 */
+       {0x0107,0x14,0x1c,0x00,0x05,0x6a, 800, 600, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x7 */
+       {0xc85f,0x05,0x00,0x04,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x8 */
+       {0xc067,0x06,0x02,0x04,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x9 */
+       {0xc067,0x07,0x02,0x47,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0xa */
+       {0xc067,0x08,0x03,0x8a,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0xb */
+       {0xc047,0x09,0x05,0x00,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0xc */
+       {0xc047,0x0a,0x09,0x00,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0xd */
+       {0xc047,0x0b,0x0e,0x00,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0xe */
+       {0xc047,0x0c,0x15,0x00,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0xf */
+       {0x487f,0x04,0x00,0x00,0x00,0x2f, 640, 400, 0x30, 0x55, 0x6e, 0x00, 0x00, 0x00, 0x00}, /* 0x10 */
+       {0xc06f,0x3c,0x01,0x06,0x13,0x31, 720, 480, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x11 */
+       {0x006f,0x3d,0x6f,0x06,0x14,0x32, 720, 576, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x12 (6f was 03) */
+       {0x0087,0x15,0x06,0x00,0x06,0x37,1024, 768, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x13 */
+       {0xc877,0x16,0x0b,0x06,0x06,0x37,1024, 768, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x14 */
+       {0xc067,0x17,0x0f,0x49,0x06,0x37,1024, 768, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x15 */
+       {0x0067,0x18,0x11,0x00,0x06,0x37,1024, 768, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x16 */
+       {0x0047,0x19,0x16,0x8c,0x06,0x37,1024, 768, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x17 */
+       {0x0107,0x1a,0x1b,0x00,0x06,0x37,1024, 768, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x18 */
+       {0x0107,0x1b,0x1f,0x00,0x06,0x37,1024, 768, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x19 */
+       {0x0087,0x1c,0x11,0x00,0x07,0x3a,1280,1024, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x1a */
+       {0x0137,0x1d,0x19,0x07,0x07,0x3a,1280,1024, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x1b */
+       {0x0107,0x1e,0x1e,0x00,0x07,0x3a,1280,1024, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x1c */
+       {0x0207,0x1f,0x20,0x00,0x07,0x3a,1280,1024, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x1d */
+       {0x0227,0x20,0x21,0x09,0x09,0x3c,1600,1200, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x1e */
+       {0x0407,0x21,0x22,0x00,0x09,0x3c,1600,1200, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x1f */
+       {0x0407,0x22,0x23,0x00,0x09,0x3c,1600,1200, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x20 */
+       {0x0407,0x23,0x25,0x00,0x09,0x3c,1600,1200, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x21 */
+       {0x0007,0x24,0x26,0x00,0x09,0x3c,1600,1200, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x22 */
+       {0x0007,0x25,0x2c,0x00,0x09,0x3c,1600,1200, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x23 */
+       {0x0007,0x26,0x34,0x00,0x09,0x3c,1600,1200, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x24 */
+       {0x407f,0x00,0x00,0x00,0x00,0x40, 320, 200, 0x30, 0x56, 0x4e, 0x00, 0x00, 0x00, 0x00}, /* 0x25 */
+       {0xc07f,0x01,0x00,0x04,0x04,0x50, 320, 240, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x26 */
+       {0x007f,0x02,0x04,0x05,0x05,0x51, 400, 300, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x27 */
+       {0xc077,0x03,0x0b,0x06,0x06,0x52, 512, 384, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x28 */
+       {0x8007,0x27,0x27,0x00,0x00,0x68,1920,1440, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x29 */
+       {0x4007,0x28,0x29,0x00,0x00,0x68,1920,1440, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x2a */
+       {0x4007,0x29,0x2e,0x00,0x00,0x68,1920,1440, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x2b */
+       {0x4007,0x2a,0x30,0x00,0x00,0x68,1920,1440, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x2c */
+       {0x4007,0x2b,0x35,0x00,0x00,0x68,1920,1440, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x2d */
+       {0x4005,0x2c,0x39,0x00,0x00,0x68,1920,1440, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x2e */
+       {0x4007,0x2d,0x2b,0x00,0x00,0x6c,2048,1536, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x2f */
+       {0x4007,0x2e,0x31,0x00,0x00,0x6c,2048,1536, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x30 */
+       {0x4007,0x2f,0x33,0x00,0x00,0x6c,2048,1536, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x31 */
+       {0x4007,0x30,0x37,0x00,0x00,0x6c,2048,1536, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x32 */
+       {0x4005,0x31,0x38,0x00,0x00,0x6c,2048,1536, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x33 */
+       {0x2077,0x32,0x40,0x08,0x18,0x70, 800, 480, 0x30, 0x00, 0x00, 0x32, 0x40, 0x5e, 0x73}, /* 0x34 */
+       {0x2047,0x33,0x07,0x08,0x18,0x70, 800, 480, 0x30, 0x00, 0x00, 0x33, 0x07, 0xff, 0xff}, /* 0x35 */
+       {0x2047,0x34,0x0a,0x08,0x18,0x70, 800, 480, 0x30, 0x00, 0x00, 0x34, 0x0a, 0xff, 0xff}, /* 0x36 */
+       {0x2077,0x35,0x0b,0x09,0x19,0x71,1024, 576, 0x30, 0x00, 0x00, 0x35, 0x0b, 0x5f, 0x74}, /* 0x37 */
+       {0x2047,0x36,0x11,0x09,0x19,0x71,1024, 576, 0x30, 0x00, 0x00, 0x36, 0x11, 0xff, 0xff}, /* 0x38 */
+       {0x2047,0x37,0x16,0x09,0x19,0x71,1024, 576, 0x30, 0x00, 0x00, 0x37, 0x16, 0xff, 0xff}, /* 0x39 */
+       {0x3137,0x38,0x19,0x0a,0x0c,0x75,1280, 720, 0x30, 0x00, 0x00, 0x38, 0x19, 0x60, 0x75}, /* 0x3a */
+       {0x3107,0x39,0x1e,0x0a,0x0c,0x75,1280, 720, 0x30, 0x00, 0x00, 0x39, 0x1e, 0xff, 0xff}, /* 0x3b */
+       {0x3307,0x3a,0x20,0x0a,0x0c,0x75,1280, 720, 0x30, 0x00, 0x00, 0x3a, 0x20, 0xff, 0xff}, /* 0x3c */
+       {0x0127,0x3b,0x19,0x08,0x0a,0x7c,1280, 960, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x3d */
+       {0x0227,0x4c,0x59,0x08,0x0a,0x7c,1280, 960, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x3e */
+       {0xc07f,0x4e,0x00,0x06,0x04,0x5a, 320, 240, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x3f */    /* FSTN 320x240 */
+       {0x2077,0x42,0x5b,0x08,0x11,0x23,1280, 768, 0x30, 0x00, 0x00, 0x58, 0x19, 0x42, 0x5b}, /* 0x40 */    /* 0x5b was 0x12 */
+       {0x2077,0x42,0x5b,0x08,0x11,0x23,1280, 768, 0x30, 0x00, 0x00, 0x59, 0x1e, 0xff, 0xff}, /* 0x41 */
+       {0x2077,0x42,0x5b,0x08,0x11,0x23,1280, 768, 0x30, 0x00, 0x00, 0x5a, 0x20, 0xff, 0xff}, /* 0x42 */
+       {0x0127,0x43,0x4d,0x08,0x0b,0x26,1400,1050, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x43 */
+       {0x0207,0x4b,0x5a,0x08,0x0b,0x26,1400,1050, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x44 1400x1050-75Hz */
+       {0x0127,0x54,0x6d,0x00,0x1a,0x29,1152, 864, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x45 1152x864-60Hz  */
+       {0x0127,0x44,0x19,0x00,0x1a,0x29,1152, 864, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x46 1152x864-75Hz  */
+       {0x0127,0x4a,0x1e,0x00,0x1a,0x29,1152, 864, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x47 1152x864-85Hz  */
+       {0x0087,0x45,0x57,0x00,0x16,0x39, 848, 480, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x48 848x480-38Hzi  */
+       {0xc067,0x46,0x55,0x0b,0x16,0x39, 848, 480, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x49 848x480-60Hz   */
+       {0x0087,0x47,0x57,0x00,0x17,0x3f, 856, 480, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x4a 856x480-38Hzi  */
+       {0xc067,0x48,0x57,0x00,0x17,0x3f, 856, 480, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x4b 856x480-60Hz   */
+       {0x0067,0x49,0x58,0x0c,0x1b,0x48,1360, 768, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x4c 1360x768-60Hz  */
+       {0x006f,0x4d,0x71,0x06,0x15,0x5f, 768, 576, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x4d 768x576-56Hz   */
+       {0x2067,0x4f,0x5c,0x08,0x0d,0x14,1280, 800, 0x30, 0x00, 0x00, 0x5b, 0x19, 0x4f, 0x5c}, /* 0x4e 1280x800-60Hz  */
+       {0x2067,0x4f,0x5c,0x08,0x0d,0x14,1280, 800, 0x30, 0x00, 0x00, 0x5c, 0x1e, 0xff, 0xff}, /* 0x4f 1280x800-75Hz  */
+       {0x2067,0x4f,0x5c,0x08,0x0d,0x14,1280, 800, 0x30, 0x00, 0x00, 0x5d, 0x20, 0xff, 0xff}, /* 0x50 1280x800-85Hz  */
+       {0x0067,0x50,0x5d,0x0c,0x0e,0x17,1680,1050, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x51 1680x1050-60Hz */
+       {0x0087,0x51,0x69,0x00,0x00,0x2c,1920,1080, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x52 1920x1080 60Hzi */
+       {0x0067,0x52,0x6a,0x00,0x1c,0x1d, 960, 540, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x53 960x540 60Hz */
+       {0x0077,0x53,0x6b,0x0b,0x1d,0x20, 960, 600, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x54 960x600 60Hz */
+       {0x2067,0x61,0x76,0x0d,0x22,0x1a,1280, 854, 0x30, 0x00, 0x00, 0x62, 0x19, 0x61, 0x76}, /* 0x55 1280x854-60Hz  */
+       {0x2067,0x61,0x76,0x0d,0x22,0x1a,1280, 854, 0x30, 0x00, 0x00, 0x63, 0x1e, 0xff, 0xff}, /* 0x56 1280x854-75Hz  */
+       {0x2067,0x61,0x76,0x0d,0x22,0x1a,1280, 854, 0x30, 0x00, 0x00, 0x64, 0x20, 0xff, 0xff}, /* 0x57 1280x854-85Hz  */
+       {0xffff,0x00,0x00,0x00,0x00,0x00,   0,   0,    0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+};
+
+static const struct SiS_CRT1Table SiS310_CRT1Table[] =
 {
  {{0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
    0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x00,
-   0x00}}, /* 0x0 */
+   0x00}},  /* 0x0 */
  {{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e,
    0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00,
-   0x00}}, /* 0x1 */
+   0x00}},  /* 0x1 */
  {{0x3d,0x31,0x31,0x81,0x37,0x1f,0x72,0xf0,
    0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x05,
-   0x01}}, /* 0x2 */
+   0x01}},  /* 0x2 */
  {{0x4f,0x3f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
    0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x01,
-   0x01}}, /* 0x3 */
+   0x01}},  /* 0x3 */
  {{0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
    0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x05,
-   0x00}}, /* 0x4 */
-#if 0
- {{0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,
-   0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05,
-   0x00}}, /* 0x5 */
-#endif
- {{0x5f,0x4f,0x4f,0x83,0x55,0x81,0x0b,0x3e,    /* 0x05 - corrected 640x480-60 */
+   0x00}},  /* 0x4 */
+ {{0x5f,0x4f,0x4f,0x83,0x55,0x81,0x0b,0x3e,    /* corrected 640x480-60 */
    0xe9,0x8b,0xdf,0xe8,0x0c,0x00,0x00,0x05,
-   0x00}},
-#if 0   
- {{0x63,0x4f,0x50,0x86,0x56,0x9b,0x06,0x3e,
-   0xe8,0x8b,0xdf,0xe7,0xff,0x10,0x00,0x01,
-   0x00}}, /* 0x6 */
-#endif
- {{0x63,0x4f,0x4f,0x87,0x56,0x9b,0x06,0x3e,    /* 0x06 - corrected 640x480-72 */
+   0x00}},  /* 0x5 */
+ {{0x63,0x4f,0x4f,0x87,0x56,0x9b,0x06,0x3e,    /* corrected 640x480-72 */
    0xe8,0x8a,0xdf,0xe7,0x07,0x00,0x00,0x01,
-   0x00}},
+   0x00}},  /* 0x6 */
  {{0x64,0x4f,0x4f,0x88,0x55,0x9d,0xf2,0x1f,
    0xe0,0x83,0xdf,0xdf,0xf3,0x10,0x00,0x01,
-   0x00}}, /* 0x7 */
+   0x00}},  /* 0x7 */
  {{0x63,0x4f,0x4f,0x87,0x5a,0x81,0xfb,0x1f,
    0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x05,
-   0x00}}, /* 0x8 */
+   0x00}},  /* 0x8 */
  {{0x65,0x4f,0x4f,0x89,0x58,0x80,0xfb,0x1f,
    0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x05,  /* Corrected VBE */
-   0x61}}, /* 0x9 */
+   0x61}},  /* 0x9 */
  {{0x65,0x4f,0x4f,0x89,0x58,0x80,0x01,0x3e,
    0xe0,0x83,0xdf,0xdf,0x02,0x00,0x00,0x05,
-   0x61}}, /* 0xa */
+   0x61}},  /* 0xa */
  {{0x67,0x4f,0x4f,0x8b,0x58,0x81,0x0d,0x3e,
    0xe0,0x83,0xdf,0xdf,0x0e,0x00,0x00,0x05,  /* Corrected VBE */
-   0x61}}, /* 0xb */
+   0x61}},  /* 0xb */
  {{0x65,0x4f,0x4f,0x89,0x57,0x9f,0xfb,0x1f,
    0xe6,0x8a,0xdf,0xdf,0xfc,0x10,0x00,0x01,  /* Corrected VDE, VBE */
-   0x00}}, /* 0xc */
+   0x00}},  /* 0xc */
  {{0x7b,0x63,0x63,0x9f,0x6a,0x93,0x6f,0xf0,
    0x58,0x8a,0x57,0x57,0x70,0x20,0x00,0x05,
-   0x01}}, /* 0xd */
+   0x01}},  /* 0xd */
  {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xf0,
    0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x06,
-   0x01}}, /* 0xe */
+   0x01}},  /* 0xe */
  {{0x7d,0x63,0x63,0x81,0x6e,0x1d,0x98,0xf0,
    0x7c,0x82,0x57,0x57,0x99,0x00,0x00,0x06,
-   0x01}}, /* 0xf */
+   0x01}},  /* 0xf */
  {{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xf0,
    0x58,0x8b,0x57,0x57,0x70,0x20,0x00,0x06,
-   0x01}}, /* 0x10 */
+   0x01}},  /* 0x10 */
  {{0x7e,0x63,0x63,0x82,0x6b,0x13,0x75,0xf0,
    0x58,0x8b,0x57,0x57,0x76,0x20,0x00,0x06,
-   0x01}}, /* 0x11 */
+   0x01}},  /* 0x11 */
  {{0x81,0x63,0x63,0x85,0x6d,0x18,0x7a,0xf0,
    0x58,0x8b,0x57,0x57,0x7b,0x20,0x00,0x06,
-   0x61}}, /* 0x12 */
+   0x61}},  /* 0x12 */
  {{0x83,0x63,0x63,0x87,0x6e,0x19,0x81,0xf0,
    0x58,0x8b,0x57,0x57,0x82,0x20,0x00,0x06,
-   0x61}}, /* 0x13 */
+   0x61}},  /* 0x13 */
  {{0x85,0x63,0x63,0x89,0x6f,0x1a,0x91,0xf0,
    0x58,0x8b,0x57,0x57,0x92,0x20,0x00,0x06,
-   0x61}}, /* 0x14 */
+   0x61}},  /* 0x14 */
  {{0x99,0x7f,0x7f,0x9d,0x84,0x1a,0x96,0x1f,
    0x7f,0x83,0x7f,0x7f,0x97,0x10,0x00,0x02,
-   0x00}}, /* 0x15 */
+   0x00}},  /* 0x15 */
  {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,
    0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
-   0x01}}, /* 0x16 */
+   0x01}},  /* 0x16 */
  {{0xa1,0x7f,0x7f,0x85,0x86,0x97,0x24,0xf5,
    0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
-   0x01}}, /* 0x17 */
+   0x01}},  /* 0x17 */
  {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf5,
    0x00,0x83,0xff,0xff,0x1f,0x10,0x00,0x02,
-   0x01}}, /* 0x18 */
+   0x01}},  /* 0x18 */
  {{0xa7,0x7f,0x7f,0x8b,0x89,0x95,0x26,0xf5,
    0x00,0x83,0xff,0xff,0x27,0x10,0x00,0x02,
-   0x01}}, /* 0x19 */
+   0x01}},  /* 0x19 */
  {{0xa9,0x7f,0x7f,0x8d,0x8c,0x9a,0x2c,0xf5,
    0x00,0x83,0xff,0xff,0x2d,0x14,0x00,0x02,
-   0x62}}, /* 0x1a */
+   0x62}},  /* 0x1a */
  {{0xab,0x7f,0x7f,0x8f,0x8d,0x9b,0x35,0xf5,
    0x00,0x83,0xff,0xff,0x36,0x14,0x00,0x02,
-   0x62}}, /* 0x1b */
+   0x62}},  /* 0x1b */
  {{0xcf,0x9f,0x9f,0x93,0xb2,0x01,0x14,0xba,
    0x00,0x83,0xff,0xff,0x15,0x00,0x00,0x03,
-   0x00}}, /* 0x1c */
+   0x00}},  /* 0x1c */
  {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0x5a,
    0x00,0x83,0xff,0xff,0x29,0x09,0x00,0x07,
-   0x01}}, /* 0x1d */
+   0x01}},  /* 0x1d */
  {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0x5a,
    0x00,0x83,0xff,0xff,0x29,0x09,0x00,0x07,
-   0x01}}, /* 0x1e */
+   0x01}},  /* 0x1e */
  {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0x5a,
    0x00,0x83,0xff,0xff,0x2f,0x09,0x00,0x07,
-   0x01}}, /* 0x1f */
+   0x01}},  /* 0x1f */
  {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
    0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
-   0x00}}, /* 0x20 */
+   0x00}},  /* 0x20 */
  {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
    0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
-   0x00}}, /* 0x21 @ 4084 */
+   0x00}},  /* 0x21 */
  {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
    0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
-   0x00}}, /* 0x22 */
+   0x00}},  /* 0x22 */
  {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
    0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
-   0x00}}, /* 0x23 */
+   0x00}},  /* 0x23 */
  {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
    0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
-   0x00}}, /* 0x24 */
+   0x00}},  /* 0x24 */
  {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
    0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
-   0x00}}, /* 0x25 */
+   0x00}},  /* 0x25 */
  {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
    0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
-   0x00}}, /* 0x26 */
+   0x00}},  /* 0x26 */
  {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
    0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
-   0x00}}, /* 0x27 */
+   0x00}},  /* 0x27 */
  {{0x43,0xef,0xef,0x87,0x06,0x00,0xd4,0x1f,
    0xa0,0x83,0x9f,0x9f,0xd5,0x1f,0x41,0x05,
-   0x63}}, /* 0x28 */
+   0x63}},  /* 0x28 */
  {{0x45,0xef,0xef,0x89,0x07,0x01,0xd9,0x1f,
    0xa0,0x83,0x9f,0x9f,0xda,0x1f,0x41,0x05,
-   0x63}}, /* 0x29 */
+   0x63}},  /* 0x29 */
  {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
    0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
-   0x00}}, /* 0x2a */
+   0x00}},  /* 0x2a */
  {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
    0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
-   0x00}}, /* 0x2b */
+   0x00}},  /* 0x2b */
  {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
    0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
-   0x00}}, /* 0x2c */
+   0x00}},  /* 0x2c */
  {{0x59,0xff,0xff,0x9d,0x17,0x13,0x33,0xba,
    0x00,0x83,0xff,0xff,0x34,0x0f,0x41,0x05,
-   0x44}}, /* 0x2d */
+   0x44}},  /* 0x2d */
  {{0x5b,0xff,0xff,0x9f,0x18,0x14,0x38,0xba,
    0x00,0x83,0xff,0xff,0x39,0x0f,0x41,0x05,
-   0x44}}, /* 0x2e */
+   0x44}},  /* 0x2e */
  {{0x5b,0xff,0xff,0x9f,0x18,0x14,0x3d,0xba,
    0x00,0x83,0xff,0xff,0x3e,0x0f,0x41,0x05,
-   0x44}}, /* 0x2f */
+   0x44}},  /* 0x2f */
  {{0x5d,0xff,0xff,0x81,0x19,0x95,0x41,0xba,
    0x00,0x84,0xff,0xff,0x42,0x0f,0x41,0x05,
-   0x44}}, /* 0x30 */
+   0x44}},  /* 0x30 */
  {{0x55,0xff,0xff,0x99,0x0d,0x0c,0x3e,0xba,
    0x00,0x84,0xff,0xff,0x3f,0x0f,0x41,0x05,
-   0x00}}, /* 0x31 */
+   0x00}},  /* 0x31 */
  {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xba,
    0x27,0x8b,0xdf,0xdf,0x73,0x00,0x00,0x06,
-   0x01}}, /* 0x32 */
+   0x01}},  /* 0x32 */
  {{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xba,
    0x26,0x89,0xdf,0xdf,0x6f,0x00,0x00,0x06,
-   0x01}}, /* 0x33 */
+   0x01}},  /* 0x33 */
  {{0x7f,0x63,0x63,0x82,0x6b,0x13,0x75,0xba,
    0x29,0x8c,0xdf,0xdf,0x75,0x00,0x00,0x06,
-   0x01}}, /* 0x34 */
+   0x01}},  /* 0x34 */
  {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf1,
    0xaf,0x85,0x3f,0x3f,0x25,0x30,0x00,0x02,
-   0x01}}, /* 0x35 */
+   0x01}},  /* 0x35 */
  {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf1,
    0xad,0x81,0x3f,0x3f,0x1f,0x30,0x00,0x02,
-   0x01}}, /* 0x36 */
+   0x01}},  /* 0x36 */
  {{0xa7,0x7f,0x7f,0x88,0x89,0x95,0x26,0xf1,   /* 95 was 15 - illegal HBE! */
    0xb1,0x85,0x3f,0x3f,0x27,0x30,0x00,0x02,
-   0x01}}, /* 0x37 */
+   0x01}},  /* 0x37 */
  {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0xc4,
    0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07,
-   0x01}}, /* 0x38 */
+   0x01}},  /* 0x38 */
  {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0xd4,
    0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07,
-   0x01}}, /* 0x39 */
+   0x01}},  /* 0x39 */
  {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0xd4,
    0x7d,0x81,0xcf,0xcf,0x2f,0x21,0x00,0x07,
-   0x01}}, /* 0x3a */
-#if 0   
- {{0xdc,0x9f,0x9f,0x00,0xab,0x19,0xe6,0xef,    /* 1280x960 - invalid */
-   0xc0,0xc3,0xbf,0xbf,0xe7,0x10,0x00,0x07,
-   0x01}}, /* 0x3b */
-#endif  
+   0x01}},  /* 0x3a */
  {{0xdc,0x9f,0x9f,0x80,0xaf,0x9d,0xe6,0xff,    /* 1280x960-60 - corrected */
    0xc0,0x83,0xbf,0xbf,0xe7,0x10,0x00,0x07,
-   0x01}}, /* 0x3b */ 
+   0x01}},  /* 0x3b */
  {{0x6b,0x59,0x59,0x8f,0x5e,0x8c,0x0b,0x3e,
    0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05,
-   0x00}}, /* 0x3c */
- {{0x7b,0x59,0x63,0x9f,0x6a,0x93,0x6f,0xf0,
-   0x58,0x8a,0x3f,0x57,0x70,0x20,0x00,0x05,
-   0x01}}, /* 0x3d */
+   0x00}},  /* 0x3c */
+ {{0x6d,0x59,0x59,0x91,0x60,0x89,0x53,0xf0,    /* 720x576, corrected to 60Hz */
+   0x41,0x84,0x3f,0x3f,0x54,0x00,0x00,0x05,
+   0x41}},  /* 0x3d */
  {{0x86,0x6a,0x6a,0x8a,0x74,0x06,0x8c,0x15,
    0x4f,0x83,0xef,0xef,0x8d,0x30,0x00,0x02,
-   0x00}}, /* 0x3e */
+   0x00}},  /* 0x3e */
  {{0x81,0x6a,0x6a,0x85,0x70,0x00,0x0f,0x3e,
    0xeb,0x8e,0xdf,0xdf,0x10,0x00,0x00,0x02,
-   0x00}}, /* 0x3f */
+   0x00}},  /* 0x3f */
  {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x1e,0xf1,
    0xae,0x85,0x57,0x57,0x1f,0x30,0x00,0x02,
    0x01}},  /* 0x40 */
@@ -578,11 +483,11 @@ static const SiS_CRT1TableStruct SiS310_CRT1Table[]=
  {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0xf1,0xff, /* 1280x960-85 */
    0xc0,0x83,0xbf,0xbf,0xf2,0x10,0x00,0x07,
    0x01}},  /* 0x4c */
- {{0x7b,0x5f,0x63,0x9f,0x6a,0x93,0x6f,0xf0, /* 768x576 */
-   0x58,0x8a,0x3f,0x57,0x70,0x20,0x00,0x05,
-   0x01}},  /* 0x4d */
- {{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e, /* FSTN 320x480, TEMP - possibly invalid */
-   0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00,
+ {{0x75,0x5f,0x5f,0x99,0x66,0x90,0x53,0xf0, /* 768x576, corrected to 60Hz */
+   0x41,0x84,0x3f,0x3f,0x54,0x00,0x00,0x05,
+   0x41}},  /* 0x4d */
+ {{0x5f,0x27,0x4f,0x83,0x55,0x81,0x0b,0x3e, /* FSTN 320x240 (working) */
+   0xe9,0x8b,0xdf,0xe8,0x0c,0x00,0x00,0x05,
    0x00}},  /* 0x4e */
  {{0xcd,0x9f,0x9f,0x91,0xab,0x1c,0x3a,0xff, /* 1280x800-60 */
    0x20,0x83,0x1f,0x1f,0x3b,0x10,0x00,0x07,
@@ -601,10 +506,58 @@ static const SiS_CRT1TableStruct SiS310_CRT1Table[]=
    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[] =
+   0x41}},  /* 0x54 */
+ {{0x5c,0x4f,0x4f,0x80,0x57,0x80,0xa3,0x1f, /* fake 640x400@60Hz (for LCD and TV, not actually used) */
+   0x98,0x8c,0x8f,0x96,0xa4,0x30,0x00,0x05,
+   0x40}},  /* 0x55 */
+ {{0x2c,0x27,0x27,0x90,0x2d,0x92,0xa4,0x1f, /* fake 320x200@60Hz (for LCD and TV, not actually used) */
+   0x98,0x8c,0x8f,0x96,0xa5,0x30,0x00,0x04,
+   0x00}},  /* 0x56 */
+ {{0xd7,0xc7,0xc7,0x9b,0xd1,0x15,0xd1,0x10, /* 1600x1200 for LCDA */
+   0xb2,0x86,0xaf,0xb0,0xd2,0x2f,0x00,0x03,
+   0x00}},  /* 0x57 */
+ {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0xdc, /* 1280x768 (1280x1024) 60 Hz */
+   0x92,0x86,0xff,0x91,0x29,0x21,0x00,0x07,
+   0x01}},  /* 0x58 */
+ {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0xdc, /* 1280x768 (1280x1024) 75 Hz */
+   0x92,0x86,0xff,0x91,0x29,0x21,0x00,0x07,
+   0x01}},  /* 0x59 */
+ {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0xdc, /* 1280x768 (1280x1024) 85 Hz */
+   0x95,0x89,0xff,0x94,0x2f,0x21,0x00,0x07,
+   0x01}},  /* 0x5a */
+ {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0xde, /* 1280x800 (1280x1024) 60 Hz */
+   0xa2,0x86,0x1f,0xa1,0x29,0x01,0x00,0x07,
+   0x01}},  /* 0x5b */
+ {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0xde, /* 1280x800 (1280x1024) 75 Hz */
+   0xa2,0x86,0x1f,0xa1,0x29,0x01,0x00,0x07,
+   0x01}},  /* 0x5c */
+ {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0xde, /* 1280x800 (1280x1024) 85 Hz */
+   0xa5,0x89,0x1f,0xa4,0x2f,0x01,0x00,0x07,
+   0x01}},  /* 0x5d */
+ {{0x7f,0x63,0x63,0x83,0x6d,0x1d,0x0b,0x3e, /* 800x480 (wide) 60 Hz */
+   0xe9,0x8b,0xdf,0xe8,0x0c,0x00,0x00,0x06,
+   0x00}},  /* 0x5e */
+ {{0xa0,0x7f,0x7f,0x84,0x85,0x97,0x52,0xf0, /* 1024x576 (wide) 60 Hz */
+   0x41,0x85,0x3f,0x40,0x53,0x00,0x00,0x02,
+   0x01}},  /* 0x5f */
+ {{0xc9,0x9f,0x9f,0x8d,0xb0,0x15,0xec,0xf0, /* 1280x720 (wide) 60 Hz */
+   0xd4,0x89,0xcf,0xd3,0xed,0x20,0x00,0x07,
+   0x01}},  /* 0x60 */
+ {{0xcb,0x9f,0x9f,0x8f,0xa5,0x13,0x5b,0xff, /* 1280x854-60 wide */
+   0x56,0x89,0x55,0x55,0x5c,0x30,0x00,0x07,
+   0x01}},  /* 0x61 */
+ {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0xde, /* 1280x854 (1280x1024) 60 Hz */
+   0xbd,0x81,0x55,0xbc,0x29,0x01,0x00,0x07,
+   0x41}},  /* 0x62 */
+ {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0xde, /* 1280x854 (1280x1024) 75 Hz */
+   0xbd,0x81,0x55,0xbc,0x29,0x01,0x00,0x07,
+   0x41}},  /* 0x63 */
+ {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0xde, /* 1280x854 (1280x1024) 85 Hz */
+   0xc0,0x84,0x55,0xbf,0x2f,0x01,0x00,0x07,
+   0x41}}   /* 0x64 */
+};
+
+static const struct SiS_MCLKData SiS310_MCLKData_0_315[] =
 {
        { 0x3b,0x22,0x01,143},
        { 0x5c,0x23,0x01,166},
@@ -616,7 +569,7 @@ static const SiS_MCLKDataStruct SiS310_MCLKData_0_315[] =
        { 0x5c,0x23,0x01,166}
 };
 
-static const SiS_MCLKDataStruct SiS310_MCLKData_0_650[] =
+static const struct SiS_MCLKData SiS310_MCLKData_0_650[] =
 {
        { 0x5a,0x64,0x82, 66},
        { 0xb3,0x45,0x82, 83},
@@ -628,7 +581,7 @@ static const SiS_MCLKDataStruct SiS310_MCLKData_0_650[] =
        { 0x37,0x22,0x82,133}
 };
 
-static const SiS_MCLKDataStruct SiS310_MCLKData_0_330[] =
+static const struct SiS_MCLKData SiS310_MCLKData_0_330[] =
 {
        { 0x5c,0x23,0x01,166},
        { 0x5c,0x23,0x01,166},
@@ -640,7 +593,7 @@ static const SiS_MCLKDataStruct SiS310_MCLKData_0_330[] =
        { 0x79,0x06,0x01,250}
 };
 
-static const SiS_MCLKDataStruct SiS310_MCLKData_0_660[] =
+static const struct SiS_MCLKData SiS310_MCLKData_0_660[] =
 {
        { 0x5c,0x23,0x82,166},
        { 0x5c,0x23,0x82,166},
@@ -652,7 +605,7 @@ static const SiS_MCLKDataStruct SiS310_MCLKData_0_660[] =
        { 0x37,0x21,0x82,200}
 };
 
-static const SiS_MCLKDataStruct SiS310_MCLKData_0_760[] =
+static const struct SiS_MCLKData SiS310_MCLKData_0_760[] =
 {
        { 0x37,0x22,0x82,133},
        { 0x5c,0x23,0x82,166},
@@ -664,7 +617,7 @@ static const SiS_MCLKDataStruct SiS310_MCLKData_0_760[] =
        { 0x37,0x21,0x82,200}
 };
 
-static const SiS_MCLKDataStruct SiS310_MCLKData_0_761[] =
+static const struct SiS_MCLKData SiS310_MCLKData_0_761[] =
 {
        { 0x37,0x22,0x82,133},  /* Preliminary */
        { 0x5c,0x23,0x82,166},
@@ -676,7 +629,7 @@ static const SiS_MCLKDataStruct SiS310_MCLKData_0_761[] =
        { 0x37,0x21,0x82,200}
 };
 
-static const SiS_MCLKDataStruct SiS310_MCLKData_0_340[] =
+static const struct SiS_MCLKData SiS310_MCLKData_0_340[] =
 {
        { 0x79,0x06,0x01,250},
        { 0x7c,0x08,0x01,200},
@@ -688,9 +641,9 @@ static const SiS_MCLKDataStruct SiS310_MCLKData_0_340[] =
        { 0x29,0x01,0x81,300}
 };
 
-static const SiS_MCLKDataStruct SiS310_MCLKData_1[] = /* ECLK */
+static const struct SiS_MCLKData SiS310_MCLKData_1[] = /* ECLK */
 {
-        { 0x29,0x21,0x82,150},
+       { 0x29,0x21,0x82,150},
        { 0x5c,0x23,0x82,166},
        { 0x65,0x23,0x82,183},
        { 0x37,0x21,0x82,200},
@@ -700,7 +653,7 @@ static const SiS_MCLKDataStruct SiS310_MCLKData_1[] = /* ECLK */
        { 0x37,0x22,0x82,133}
 };
 
-static const SiS_MCLKDataStruct SiS310_MCLKData_1_340[] =
+static const struct SiS_MCLKData SiS310_MCLKData_1_340[] =
 {
        { 0x7c,0x08,0x01,200},
        { 0x7c,0x08,0x01,200},
@@ -712,7 +665,7 @@ static const SiS_MCLKDataStruct SiS310_MCLKData_1_340[] =
        { 0x29,0x01,0x81,300}
 };
 
-static SiS_VCLKDataStruct SiS310_VCLKData[]=
+static struct SiS_VCLKData SiS310_VCLKData[] =
 {
        { 0x1b,0xe1, 25}, /* 0x00 */
        { 0x4e,0xe4, 28}, /* 0x01 */
@@ -805,7 +758,7 @@ static SiS_VCLKDataStruct SiS310_VCLKData[]=
        { 0x30,0x23, 88}, /* 0x58 1360x768-62 (is 60Hz!) */
        { 0x52,0x07,149}, /* 0x59 1280x960-85 */
        { 0x56,0x07,156}, /* 0x5a 1400x1050-75 */
-       { 0x70,0x29, 81}, /* 0x5b 1280x768 LCD */
+       { 0x70,0x29, 81}, /* 0x5b 1280x768 LCD */
        { 0x45,0x25, 83}, /* 0x5c 1280x800  */
        { 0x70,0x0a,147}, /* 0x5d 1680x1050 */
        { 0x70,0x24,162}, /* 0x5e 1600x1200 */
@@ -823,10 +776,19 @@ static SiS_VCLKDataStruct SiS310_VCLKData[]=
        { 0x7c,0x6b, 38}, /* 0x6a 960x540@60 */
        { 0xe3,0x56, 41}, /* 0x6b 960x600@60 */
        { 0x45,0x25, 83}, /* 0x6c 1280x800 */
-       { 0x70,0x28, 90}  /* 0x6d 1152x864@60 */
+       { 0x70,0x28, 90}, /* 0x6d 1152x864@60 */
+       { 0x15,0xe1, 20}, /* 0x6e 640x400@60 (fake, not actually used) */
+       { 0x5f,0xc6, 33}, /* 0x6f 720x576@60 */
+       { 0x37,0x5a, 10}, /* 0x70 320x200@60 (fake, not actually used) */
+       { 0x2b,0xc2, 35}, /* 0x71 768x576@60 */
+       { 0xa8,0x42,131}, /* 0x72 1600x1200@60 for LCDA */
+       { 0x1b,0xc1, 34}, /* 0x73 800x480 60Hz (wide) */
+       { 0x41,0x64, 48}, /* 0x74 1024x576 60Hz (wide) */
+       { 0x52,0x27, 75}, /* 0x75 1280x720 60Hz (wide) */
+       { 0x75,0x13, 84}  /* 0x76 1280x854 60Hz (wide) */
 };
 
-static SiS_VBVCLKDataStruct SiS310_VBVCLKData[]=
+static struct SiS_VBVCLKData SiS310_VBVCLKData[] =
 {
        { 0x1b,0xe1, 25}, /* 0x00 */
        { 0x4e,0xe4, 28}, /* 0x01 */
@@ -858,12 +820,6 @@ static SiS_VBVCLKDataStruct SiS310_VBVCLKData[]=
        { 0x5e,0x43,113}, /* 0x1b */
        { 0xbc,0x44,116}, /* 0x1c */
        { 0xe0,0x46,132}, /* 0x1d */
-#if 0
-       { 0xd4,0x28,135}, /* 0x1e */
-       { 0xea,0x2a,139}, /* 0x1f */
-       { 0x41,0x22,157}, /* 0x20 */
-       { 0x70,0x24,162}, /* 0x21 */
-#endif
        { 0xe2,0x46,135}, /* 0x1e */  /* 1280x1024-75, better clock for VGA2 */
        { 0xe5,0x46,139}, /* 0x1f */  /* 1024x768-120, better clock for VGA2 */
        { 0x15,0x01,157}, /* 0x20 */  /* 1280x1024-85, better clock for VGA2 */
@@ -912,7 +868,7 @@ static SiS_VBVCLKDataStruct SiS310_VBVCLKData[]=
        { 0x34,0x61, 95}, /* 0x4b UNUSED */
        { 0x78,0x27,108}, /* 0x4c UNUSED */
        { 0x66,0x43,123}, /* 0x4d 1400x1050-60 */
-       { 0x41,0x4e, 21}, /* 0x4e UNUSED */
+       { 0x41,0x4e, 21}, /* 0x4e */
        { 0xa1,0x4a, 29}, /* 0x4f UNUSED */
        { 0x19,0x42, 42}, /* 0x50 UNUSED */
        { 0x54,0x46, 58}, /* 0x51 UNUSED */
@@ -925,7 +881,7 @@ static SiS_VBVCLKDataStruct SiS310_VBVCLKData[]=
        { 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 (TMDS) */
+       { 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 */
@@ -943,57 +899,33 @@ static SiS_VBVCLKDataStruct SiS310_VBVCLKData[]=
        { 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 */
+       { 0x70,0x28, 90}, /* 0x6d 1152x864@60 */
+       { 0x15,0xe1, 20}, /* 0x6e 640x400@60 (fake, not actually used) */
+       { 0x5f,0xc6, 33}, /* 0x6f 720x576@60 */
+       { 0x37,0x5a, 10}, /* 0x70 320x200@60 (fake, not actually used) */
+       { 0x2b,0xc2, 35}, /* 0x71 768@576@60 */
+       { 0xa8,0x42,131}, /* 0x72 1600x1200@60 for LCDA */
+       { 0x1b,0xc1, 34}, /* 0x73 800x480 60Hz (wide) */
+       { 0x41,0x64, 48}, /* 0x74 1024x576 60Hz (wide) */
+       { 0x52,0x27, 75}, /* 0x75 1280x720 60Hz (wide) */
+       { 0x75,0x13, 84}  /* 0x76 1280x854 60Hz (SiS LVDS) LCD */
 };
 
-static const DRAM4Type SiS310_SR15[8] = {
-       {0x00,0x04,0x60,0x60},
-       {0x0f,0x0f,0x0f,0x0f},
-       {0xba,0xba,0xba,0xba},
-       {0xa9,0xa9,0xac,0xac},
-       {0xa0,0xa0,0xa0,0xa8},
-       {0x00,0x00,0x02,0x02},
-       {0x30,0x30,0x40,0x40},
-       {0x00,0xa5,0xfb,0xf6}
-};
-
-#ifdef LINUX_KERNEL
-
-static UCHAR SiS310_SR07 = 0x18;
-
-static const DRAM4Type SiS310_CR40[5] = {
-       {0x77,0x77,0x33,0x33},
-       {0x77,0x77,0x33,0x33},
-       {0x00,0x00,0x00,0x00},
-       {0x5b,0x5b,0x03,0x03},
-       {0x00,0x00,0xf0,0xf8}
+static const unsigned char SiS310_SR15[4 * 8] =
+{
+       0x00,0x04,0x60,0x60,
+       0x0f,0x0f,0x0f,0x0f,
+       0xba,0xba,0xba,0xba,
+       0xa9,0xa9,0xac,0xac,
+       0xa0,0xa0,0xa0,0xa8,
+       0x00,0x00,0x02,0x02,
+       0x30,0x30,0x40,0x40,
+       0x00,0xa5,0xfb,0xf6
 };
 
-static UCHAR SiS310_CR49[] = {0xaa,0x88};
-static UCHAR SiS310_SR1F = 0x00;
-static UCHAR SiS310_SR21 = 0xa5;
-static UCHAR SiS310_SR22 = 0xfb;
-static UCHAR SiS310_SR23 = 0xf6;
-static UCHAR SiS310_SR24 = 0x0d;
-static UCHAR SiS310_SR25[] = {0x33,0x3};
-static UCHAR SiS310_SR31 = 0x00;
-static UCHAR SiS310_SR32 = 0x11;
-static UCHAR SiS310_SR33 = 0x00;
-static UCHAR SiS310_CRT2Data_1_2  = 0x00;
-static UCHAR SiS310_CRT2Data_4_D  = 0x00;
-static UCHAR SiS310_CRT2Data_4_E  = 0x00;
-static UCHAR SiS310_CRT2Data_4_10 = 0x80;
-static const USHORT SiS310_RGBSenseData    = 0xd1;
-static const USHORT SiS310_VideoSenseData  = 0xb9;
-static const USHORT SiS310_YCSenseData     = 0xb3;
-static const USHORT SiS310_RGBSenseData2   = 0x0190; 
-static const USHORT SiS310_VideoSenseData2 = 0x0174;
-static const USHORT SiS310_YCSenseData2    = 0x016b;
-#endif
-
-static const SiS_PanelDelayTblStruct SiS310_PanelDelayTbl[]=
+static const struct SiS_PanelDelayTbl SiS310_PanelDelayTbl[] =
 {
-        {{0x10,0x40}},
+       {{0x10,0x40}},
        {{0x10,0x40}},
        {{0x10,0x40}},
        {{0x10,0x40}},
@@ -1011,7 +943,7 @@ static const SiS_PanelDelayTblStruct SiS310_PanelDelayTbl[]=
        {{0x10,0x40}}
 };
 
-static const SiS_PanelDelayTblStruct SiS310_PanelDelayTblLVDS[]=
+static const struct SiS_PanelDelayTbl SiS310_PanelDelayTblLVDS[] =
 {
        {{0x28,0xc8}},
        {{0x28,0xc8}},
@@ -1035,18 +967,18 @@ static const SiS_PanelDelayTblStruct SiS310_PanelDelayTblLVDS[]=
 /* SIS VIDEO BRIDGE ----------------------------------------- */
 /**************************************************************/
 
-static const SiS_LCDDataStruct  SiS310_St2LCD1024x768Data[] =
+static const struct SiS_LCDData SiS310_St2LCD1024x768Data[] =
 {
        {   62,  25, 800, 546,1344, 806},
        {   32,  15, 930, 546,1344, 806},
-        {   62,  25, 800, 546,1344, 806},
+       {   62,  25, 800, 546,1344, 806},
        {  104,  45, 945, 496,1344, 806},
        {   62,  25, 800, 546,1344, 806},
        {   31,  18,1008, 624,1344, 806},
        {    1,   1,1344, 806,1344, 806}
 };
 
-static const SiS_LCDDataStruct  SiS310_ExtLCD1024x768Data[] =
+static const struct SiS_LCDData SiS310_ExtLCD1024x768Data[] =
 {
        {   42,  25,1536, 419,1344, 806},
        {   48,  25,1536, 369,1344, 806},
@@ -1057,7 +989,7 @@ static const SiS_LCDDataStruct  SiS310_ExtLCD1024x768Data[] =
        {    1,   1,1344, 806,1344, 806}
 };
 
-static const SiS_LCDDataStruct  SiS310_St2LCD1280x1024Data[] =
+static const struct SiS_LCDData SiS310_St2LCD1280x1024Data[] =
 {
        {   22,   5, 800, 510,1650,1088},
        {   22,   5, 800, 510,1650,1088},
@@ -1069,7 +1001,7 @@ static const SiS_LCDDataStruct  SiS310_St2LCD1280x1024Data[] =
        {    1,   1,1688,1066,1688,1066}
 };
 
-static const SiS_LCDDataStruct  SiS310_ExtLCD1280x1024Data[] =
+static const struct SiS_LCDData SiS310_ExtLCD1280x1024Data[] =
 {
        {  211,  60,1024, 501,1688,1066},
        {  211,  60,1024, 508,1688,1066},
@@ -1081,45 +1013,22 @@ static const SiS_LCDDataStruct  SiS310_ExtLCD1280x1024Data[] =
        {    1,   1,1688,1066,1688,1066}
 };
 
-static const SiS_Part2PortTblStruct SiS310_CRT2Part2_1024x768_1[] =
+static const struct SiS_Part2PortTbl SiS310_CRT2Part2_1024x768_1[] =
 {
- {{0x25,0x12,0xc9,0xdc,0xb6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x2c,0x12,0x9a,0xae,0x88,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x25,0x12,0xc9,0xdc,0xb6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
- {{0x38,0x13,0x16,0x0c,0xe6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x38,0x18,0x16,0x00,0x00,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}
      {{0x25,0x12,0xc9,0xdc,0xb6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
      {{0x2c,0x12,0x9a,0xae,0x88,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
      {{0x25,0x12,0xc9,0xdc,0xb6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
      {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
      {{0x38,0x13,0x16,0x0c,0xe6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
      {{0x38,0x18,0x16,0x00,0x00,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
      {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}
 };
 
-/* *** LCDA *** */
-
-#if 0
-static const SiS_LVDSDataStruct  SiS_LCDA1600x1200Data_1[]=
-{ /* Clevo, 651+301C */
-       {1200, 450, 2048,1250},
-       {1200, 400, 2048,1250},
-       {1280, 450, 2048,1250},
-       {1280, 400, 2048,1250},
-       {1200, 530, 2048,1250},
-       {1360, 650, 2048,1250},
-       {1584, 818, 2048,1250},
-       {1688,1066, 2048,1250},
-       {1688,1066, 2048,1250},
-#if 0
-       {2048,1250, 2048,1250}   /* this should be correct */
-#endif
-#if 1
-       {2160,1250, 2048,1250}   /* ? */
-#endif
-};
-#endif
-
 /**************************************************************/
 /* LVDS, CHRONTEL ------------------------------------------- */
 /**************************************************************/
 
-static const SiS_LVDSDataStruct  SiS310_CHTVUPALData[]=
+static const struct SiS_LVDSData SiS310_CHTVUPALData[] =
 {
        {1008, 625,1008, 625},
        {1008, 625,1008, 625},
@@ -1130,7 +1039,7 @@ static const SiS_LVDSDataStruct  SiS310_CHTVUPALData[]=
        {1400,1000,1400,1000}
 };
 
-static const SiS_LVDSDataStruct  SiS310_CHTVOPALData[]=
+static const struct SiS_LVDSData SiS310_CHTVOPALData[] =
 {
        {1008, 625,1008, 625},
        {1008, 625,1008, 625},
@@ -1138,10 +1047,10 @@ static const SiS_LVDSDataStruct  SiS310_CHTVOPALData[]=
        {1008, 625,1008, 625},
        { 840, 625, 840, 625},
        { 944, 625, 944, 625},
-        {1400, 875,1400, 875}
+       {1400, 875,1400, 875}
 };
 
-static const SiS_LVDSDataStruct  SiS310_CHTVUPALMData[]=
+static const struct SiS_LVDSData SiS310_CHTVUPALMData[] =
 {
        { 840, 600, 840, 600},
        { 840, 600, 840, 600},
@@ -1149,10 +1058,10 @@ static const SiS_LVDSDataStruct  SiS310_CHTVUPALMData[]=
        { 840, 600, 840, 600},
        { 784, 600, 784, 600},
        {1064, 750,1064, 750},
-        {1160, 945,1160, 945}
+       {1160, 945,1160, 945}
 };
 
-static const SiS_LVDSDataStruct  SiS310_CHTVOPALMData[]=
+static const struct SiS_LVDSData SiS310_CHTVOPALMData[] =
 {
        { 840, 525, 840, 525},
        { 840, 525, 840, 525},
@@ -1160,10 +1069,10 @@ static const SiS_LVDSDataStruct  SiS310_CHTVOPALMData[]=
        { 840, 525, 840, 525},
        { 784, 525, 784, 525},
        {1040, 700,1040, 700},
-        {1160, 840,1160, 840}
+       {1160, 840,1160, 840}
 };
 
-static const SiS_LVDSDataStruct  SiS310_CHTVUPALNData[]=
+static const struct SiS_LVDSData SiS310_CHTVUPALNData[] =
 {
        {1008, 625,1008, 625},
        {1008, 625,1008, 625},
@@ -1174,7 +1083,7 @@ static const SiS_LVDSDataStruct  SiS310_CHTVUPALNData[]=
        {1400,1000,1400,1000}
 };
 
-static const SiS_LVDSDataStruct  SiS310_CHTVOPALNData[]=
+static const struct SiS_LVDSData SiS310_CHTVOPALNData[] =
 {
        {1008, 625,1008, 625},
        {1008, 625,1008, 625},
@@ -1182,10 +1091,10 @@ static const SiS_LVDSDataStruct  SiS310_CHTVOPALNData[]=
        {1008, 625,1008, 625},
        { 840, 625, 840, 625},
        { 944, 625, 944, 625},
-        {1400, 875,1400, 875}
+       {1400, 875,1400, 875}
 };
 
-static const SiS_LVDSDataStruct  SiS310_CHTVSOPALData[]=   /* (super overscan - no effect on 7019) */
+static const struct SiS_LVDSData SiS310_CHTVSOPALData[] =   /* (super overscan - no effect on 7019) */
 {
        {1008, 625,1008, 625},
        {1008, 625,1008, 625},
@@ -1196,1333 +1105,10 @@ static const SiS_LVDSDataStruct  SiS310_CHTVSOPALData[]=   /* (super overscan -
         {1400, 875,1400, 875}
 };
 
-
-static const SiS_LVDSDesStruct  SiS310_PanelType00_1[]=  /* 800x600 */
-{
-       { 0, 0},
-       { 0, 0},
-       { 0, 0},
-       { 0, 0},
-       { 0, 0},
-       { 0, 0},
-       { 0, 0},
-       { 0, 0},
-       { 0, 0}
-};
-
-static const SiS_LVDSDesStruct  SiS310_PanelType01_1[]=  /* 1024x768 */
-{
-       { 0, 0},
-       { 0, 0},
-       { 0, 0},
-       { 0, 0},
-       { 0, 0},
-       { 0, 0},
-       { 0, 805},
-       { 0, 0},
-       { 0, 0}
-};
-
-static const SiS_LVDSDesStruct  SiS310_PanelType02_1[]=  /* 1280x1024 */
-{
-       { 0, 0},
-       { 0, 0},
-       { 0, 0},
-       { 0, 0},
-       { 0, 0},
-       { 0, 0},
-       { 0, 0},
-       { 0, 1065},
-       { 0, 0},
-       { 0, 0}
-};
-
-
-static const SiS_LVDSDesStruct  SiS310_PanelType03_1[]=
-{
-       { 0, 0},
-       { 0, 0},
-       { 0, 0},
-       { 0, 0},
-       { 0, 0},
-       { 0, 0},
-       { 0, 0},
-       { 0, 0},
-       { 0, 0}
-};
-
-static const SiS_LVDSDesStruct  SiS310_PanelType04_1[]=
-{
-       {1343, 798},
-       {1343, 794},
-       {1343, 798},
-       {1343, 794},
-       {1343,   0},
-       {1343,   0},
-       { 0, 805},
-       { 0, 794},
-       { 0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS310_PanelType05_1[]=
-{
-       {1343, 798},
-       {1343, 794},
-       {1343, 798},
-       {1343, 794},
-       {1343,   0},
-       {1343,   0},
-       { 0, 805},
-       { 0, 794},
-       { 0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS310_PanelType06_1[]=
-{
-       {1343, 798},
-       {1343, 794},
-       {1343, 798},
-       {1343, 794},
-       {1343,   0},
-       {1343,   0},
-       { 0, 805},
-       { 0, 794},
-       { 0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS310_PanelType07_1[]=
-{
-       {1343, 798},
-       {1343, 794},
-       {1343, 798},
-       {1343, 794},
-       {1343,   0},
-       {1343,   0},
-       { 0, 805},
-       { 0, 794},
-       { 0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS310_PanelType08_1[]=   /* 1400x1050 */
-{
-       { 0, 0},
-       { 0, 0},
-       { 0, 0},
-       { 0, 0},
-       { 0, 0},
-       { 0, 0},
-       { 0, 0},
-       { 0, 0},
-       { 0, 0},
-       { 0, 0},
-       { 0, 0}
-};
-
-static const SiS_LVDSDesStruct  SiS310_PanelType09_1[]=   /* 1280x768 */
-{
-       { 0, 0},
-       { 0, 0},
-       { 0, 0},
-       { 0, 0},
-       { 0, 0},
-       { 0, 0},
-       { 0, 0},
-       { 0, 0},
-       { 0, 0},
-       { 0, 0},
-       { 0, 0}
-};
-
-static const SiS_LVDSDesStruct  SiS310_PanelType0a_1[]=  /* 1600x1200 */
-{
-       { 0, 0},
-       { 0, 0},
-       { 0, 0},
-       { 0, 0},
-       { 0, 0},
-       { 0, 0},
-       { 0, 0},
-       { 0, 0},
-       { 0, 0},
-       { 0, 0},
-       { 0, 0}
-};
-
-static const SiS_LVDSDesStruct  SiS310_PanelType0b_1[]=  /* 640x480_2 */
-{
-       { 0, 524},
-       { 0, 524},
-       { 0, 524},
-       { 0, 524},
-       { 0, 524},
-       { 0, 524},
-       { 8, 524},
-       { 0, 524}
-};
-
-static const SiS_LVDSDesStruct  SiS310_PanelType0c_1[]=  /* 640x480_3 */
-{
-       { 0, 524},
-       { 0, 524},
-       { 0, 524},
-       { 0, 524},
-       { 0, 524},
-       { 0, 524},
-       { 8, 524},
-       { 0, 524}
-};
-
-static const SiS_LVDSDesStruct  SiS310_PanelType0d_1[]=
-{
-       {1343, 798},
-       {1343, 794},
-       {1343, 798},
-       {1343, 794},
-       {1343,   0},
-       {1343,   0},
-       { 0, 805},
-       { 0, 794},
-       { 0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS310_PanelType0e_1[]=
-{
-       {1343, 798},
-       {1343, 794},
-       {1343, 798},
-       {1343, 794},
-       {1343,   0},
-       {1343,   0},
-       { 0, 805},
-       { 0, 794},
-       { 0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS310_PanelType0f_1[]=
-{
-       {1343, 798},
-       {1343, 794},
-       {1343, 798},
-       {1343, 794},
-       {1343,   0},
-       {1343,   0},
-       { 0, 805},
-       { 0, 794},
-       { 0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS310_PanelType00_2[]=
-{
-       {980, 528},
-       {980, 503},
-       {980, 528},
-       {980, 503},
-       {980, 568},
-       { 0, 628},
-       { 0,   0},
-       { 0,   0},
-       { 0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS310_PanelType01_2[]=
-{
-       {1152, 622},
-       {1152, 597},
-       {1152, 622},
-       {1152, 597},
-       {1152, 662},
-       {1232, 722},
-       { 0, 806},
-       { 0,   0},
-       { 0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS310_PanelType02_2[]=
-{
-       {1368, 754},
-       {1368, 729},
-       {1368, 754},
-       {1368, 729},
-       {1368, 794},
-       {1448, 854},
-       {1560, 938},
-       {   0,1066},
-       { 0,   0},
-       { 0,   0},
-       { 0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS310_PanelType03_2[]=
-{
-       { 0,   0},
-       { 0,   0},
-       { 0,   0},
-       { 0,   0},
-       { 0,   0},
-       { 0,   0},
-       { 0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS310_PanelType04_2[]=
-{
-       { 0,   0},
-       { 0,   0},
-       { 0,   0},
-       { 0,   0},
-       { 0,   0},
-       { 0,   0},
-       { 0,   0},
-       { 0,   0},
-       { 0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS310_PanelType05_2[]=
-{
-       {1152, 622},
-       {1152, 597},
-       {1152, 622},
-       {1152, 597},
-       {1152, 662},
-       {1232, 722},
-       { 0, 805},
-       { 0, 794},
-       { 0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS310_PanelType06_2[]=
-{
-       {1152, 622},
-       {1152, 597},
-       {1152, 622},
-       {1152, 597},
-       {1152, 662},
-       {1232, 722},
-       { 0, 805},
-       { 0, 794},
-       { 0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS310_PanelType07_2[]=
-{
-       {1152, 622},
-       {1152, 597},
-       {1152, 622},
-       {1152, 597},
-       {1152, 662},
-       {1232, 722},
-       { 0, 805},
-       { 0, 794},
-       { 0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS310_PanelType08_2[]=  /* 1400x1050 */
-{
-       {1308, 741},
-       {1308, 716},
-       {1308, 741},
-       {1308, 716},
-       {1308, 781},
-       {1388, 841},
-       {1500, 925},
-       {1628,1053},
-       {   0,1065},
-       {   0,   0},
-       {   0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS310_PanelType09_2[]= /* 1280x768 */
-{
-       {1083, 622},
-       {1083, 597},
-       {1083, 622},
-       {1083, 597},
-       {1083, 662},
-       {1163, 722},
-       {1286, 805},
-       {   0, 794},
-       {   0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS310_PanelType0a_2[]=  /* 1600x1200 */
-{
-       {1568, 920},
-       {1568, 895},
-       {1568, 920},
-       {1568, 895},
-       {1568, 960},
-       {1648,1020},
-       {1760,1104},
-       {1888,1232},
-       {1948,1245},
-       {   0,   0}
-#if 0
-       {1568, 850},
-       {1568, 825},
-       {1568, 850},
-       {1568, 825},
-       {1568, 890},
-       {1648, 950},
-       {1760,1034},
-       {1888,1162},
-       {1948,1175},
-       {   0,   0}
-#endif
-};
-
-static const SiS_LVDSDesStruct  SiS310_PanelType0b_2[]=  /* 640x480_2 */
-{
-       {1152, 622},
-       {1152, 597},
-       {1152, 622},
-       {1152, 597},
-       {1152, 662},
-       {1232, 722},
-       { 0, 805},
-       { 0, 794},
-       { 0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS310_PanelType0c_2[]=  /* 640x480_3 */
-{
-       {1152, 622},
-       {1152, 597},
-       {1152, 622},
-       {1152, 597},
-       {1152, 662},
-       {1232, 722},
-       { 0, 805},
-       { 0, 794},
-       { 0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS310_PanelType0d_2[]=
-{
-       {1152, 622},
-       {1152, 597},
-       {1152, 622},
-       {1152, 597},
-       {1152, 662},
-       {1232, 722},
-       { 0, 805},
-       { 0, 794},
-       { 0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS310_PanelType0e_2[]=
-{
-       {1152, 622},
-       {1152, 597},
-       {1152, 622},
-       {1152, 597},
-       {1152, 662},
-       {1232, 722},
-       { 0, 805},
-       { 0, 794},
-       { 0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS310_PanelType0f_2[] =
-{
-       {1152, 622},
-       {1152, 597},
-       {1152, 622},
-       {1152, 597},
-       {1152, 662},
-       {1232, 722},
-       { 0, 805},
-       { 0, 794},
-       { 0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS310_PanelTypeNS_1[]=
-{
-       { 8,   0},
-       { 8,   0},
-       { 8,   0},
-       { 8,   0},
-       { 8,   0},
-       { 0,   0},
-       { 0,   0},
-       { 0,   0},
-       { 0, 806},
-       { 0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS310_PanelTypeNS_2[] =
-{
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0},
-       { 0 , 0}
-};
-
-/* CRT1 CRTC for SlaveModes and LCDA */
-
-static const SiS_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_1[] =
-{
- {{0x6b,0x4f,0x8f,0x55,0x85,0xaa,0x1f,
-   0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
-   0x00 }},
- {{0x6b,0x4f,0x8f,0x55,0x85,0x78,0x1f,
-   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
-   0x00 }},
- {{0x6b,0x4f,0x8f,0x55,0x85,0xaa,0x1f,
-   0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
-   0x00 }},
- {{0x6b,0x4f,0x8f,0x55,0x85,0x78,0x1f,
-   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
-   0x00 }},
- {{0x6b,0x4f,0x8f,0x55,0x85,0xfa,0x1f,
-   0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
-   0x00 }},
- {{0x7f,0x63,0x83,0x69,0x19,0x72,0xf0,
-   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
-   0x01 }}
-};
-
-static const SiS_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_1_H[] =
-{
- {{0x43,0x27,0x87,0x2d,0x1d,0xaa,0x1f,
-   0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
-   0x00 }},
- {{0x43,0x27,0x87,0x2d,0x1d,0x78,0x1f,
-   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
-   0x00 }},
- {{0x43,0x27,0x87,0x2d,0x1d,0xfa,0x1f,
-   0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
-   0x00 }},
- {{0x43,0x27,0x87,0x2d,0x1d,0x78,0x1f,
-   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
-   0x00 }},
- {{0x43,0x27,0x87,0x2d,0x1d,0xfa,0x1f,
-   0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
-   0x00 }},
- {{0x4d,0x31,0x91,0x37,0x07,0x72,0xf0,
-   0x58,0x8d,0x57,0x73,0x20,0x00,0x01,
-   0x01 }}
-};
-
-static const SiS_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_2[]=
-{
- {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
-   0xff,0x84,0x8f,0x73,0x00,0x00,0x06,
-   0x00 }},
- {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
-   0xe6,0x8b,0x5d,0x73,0x00,0x00,0x06,
-   0x00 }},
- {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
-   0xff,0x84,0x8f,0x73,0x00,0x00,0x06,
-   0x00 }},
- {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
-   0xe6,0x8b,0x5d,0x73,0x00,0x00,0x06,
-   0x00 }},
- {{0x7f,0x4f,0x83,0x62,0x12,0x72,0xba,
-   0x27,0x8c,0xdf,0x73,0x00,0x00,0x06,
-   0x00 }},
- {{0x7f,0x63,0x83,0x69,0x19,0x72,0xf0,
-   0x58,0x8d,0x57,0x73,0x20,0x00,0x06,
-   0x01 }}
-};
-
-static const SiS_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_2_H[] =
-{
- {{0x57,0x27,0x9b,0x3a,0x0a,0x72,0x3e,
-   0xff,0x84,0x8f,0x73,0x00,0x00,0x01,
-   0x00 }},
- {{0x57,0x27,0x9b,0x3a,0x0a,0x72,0x3e,
-   0xd6,0x8b,0x5d,0x73,0x00,0x00,0x01,
-   0x00 }},
- {{0x57,0x27,0x9b,0x3a,0x0a,0x72,0x3e,
-   0xff,0x84,0x8f,0x73,0x00,0x00,0x01,
-   0x00 }},
- {{0x57,0x27,0x9b,0x3a,0x0a,0x72,0x3e,
-   0xd6,0x8b,0x5d,0x73,0x00,0x00,0x01,
-   0x00 }},
- {{0x57,0x27,0x9b,0x3a,0x0a,0x72,0xba,
-   0x27,0x8c,0xdf,0x73,0x00,0x00,0x01,
-   0x00 }},
- {{0x4d,0x31,0x91,0x3a,0x0a,0x72,0xf0,
-   0x63,0x88,0x57,0x73,0x00,0x00,0x01,
-   0x01 }}
-};
-
-static const SiS_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_1[] =
-{
- {{0x73,0x4f,0x97,0x53,0x84,0xb4,0x1f,
-   0x92,0x89,0x8f,0xb5,0x30,0x00,0x05,
-   0x00}},
- {{0x73,0x4f,0x97,0x53,0x84,0x82,0x1f,
-   0x60,0x87,0x5d,0x83,0x10,0x00,0x05,
-   0x00}},
- {{0x73,0x4f,0x97,0x53,0x84,0xb4,0x1f,
-   0x92,0x89,0x8f,0xb5,0x30,0x00,0x05,
-   0x00}},
- {{0x73,0x4f,0x97,0x53,0x84,0x82,0x1f,
-   0x60,0x87,0x5d,0x83,0x10,0x00,0x05,
-   0x00}},
- {{0x73,0x4f,0x97,0x53,0x84,0x04,0x3e,
-   0xE2,0x89,0xDf,0x05,0x00,0x00,0x05,
-   0x00}},
- {{0x87,0x63,0x8B,0x67,0x18,0x7c,0xf0,
-   0x5A,0x81,0x57,0x7D,0x00,0x00,0x06,
-   0x01}},
- {{0xA3,0x7f,0x87,0x83,0x94,0x24,0xf5,
-   0x02,0x89,0xFf,0x25,0x10,0x00,0x02,
-   0x01}}
-};
-
-static const SiS_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_1_H[] =
-{
- {{0x4b,0x27,0x8f,0x2b,0x1c,0xb4,0x1f,
-   0x92,0x89,0x8f,0xb5,0x30,0x00,0x05,
-   0x00 }},
- {{0x4b,0x27,0x8f,0x2b,0x1c,0x82,0x1f,
-   0x60,0x87,0x5D,0x83,0x01,0x00,0x05,
-   0x00}},
- {{0x4b,0x27,0x8f,0x2b,0x1c,0xb4,0x1f,
-   0x92,0x89,0x8f,0xb5,0x30,0x00,0x05,
-   0x00}},
- {{0x4b,0x27,0x8f,0x2b,0x1c,0x82,0x1f,
-   0x60,0x87,0x5D,0x83,0x01,0x00,0x05,
-   0x00}},
- {{0x4b,0x27,0x8f,0x2b,0x1c,0x04,0x3e,
-   0xE2,0x89,0xDf,0x05,0x00,0x00,0x05,
-   0x00}},
- {{0x55,0x31,0x99,0x35,0x06,0x7c,0xf0,
-   0x5A,0x81,0x57,0x7D,0x00,0x00,0x01,
-   0x01}},
- {{0x63,0x3F,0x87,0x43,0x94,0x24,0xf5,
-   0x02,0x89,0xFf,0x25,0x10,0x00,0x01,
-   0x01 }}
-};
-
-static const SiS_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_2[] =
-{
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x57,0x8e,0x8f,0x25,0x30,0x00,0x06,
-   0x00 }},
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x3e,0x85,0x5d,0x25,0x10,0x00,0x06,
-   0x00 }},
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x57,0x8e,0x8f,0x25,0x30,0x00,0x06,
-   0x00 }},
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x3e,0x85,0x5d,0x25,0x10,0x00,0x06,
-   0x01 }},
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x7f,0x86,0xdf,0x25,0x10,0x00,0x06,
-   0x00 }},
- {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
-   0xbb,0x82,0x57,0x25,0x10,0x00,0x02,
-   0x01 }},
- {{0xa3,0x7f,0x87,0x83,0x94,0x24,0xf5,
-   0x02,0x89,0xff,0x25,0x10,0x00,0x02,
-   0x01 }}
-};
-
-static const SiS_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_2_H[] =
-{
- {{0x7b,0x27,0x9f,0x46,0x97,0x24,0xbb,
-   0x57,0x8e,0x8f,0x25,0x30,0x00,0x01,
-   0x00 }},
- {{0x7b,0x27,0x9f,0x46,0x97,0x24,0xbb,
-   0x3e,0x85,0x5d,0x25,0x10,0x00,0x01,
-   0x00 }},
- {{0x7b,0x27,0x9f,0x46,0x97,0x24,0xbb,
-   0x57,0x8e,0x8f,0x25,0x30,0x00,0x01,
-   0x00 }},
- {{0x7b,0x27,0x9f,0x46,0x97,0x24,0xbb,
-   0x3e,0x85,0x5d,0x25,0x10,0x00,0x01,
-   0x00 }},
- {{0x7b,0x27,0x9f,0x46,0x97,0x24,0xbb,
-   0x7f,0x86,0xdf,0x25,0x10,0x00,0x01,
-   0x00 }},
- {{0x71,0x31,0x95,0x46,0x97,0x24,0xf1,
-   0xbb,0x82,0x57,0x25,0x10,0x00,0x01,
-   0x01 }},
- {{0x63,0x3f,0x87,0x46,0x97,0x24,0xf5,
-   0x0f,0x86,0xff,0x25,0x30,0x00,0x01,
-   0x01 }}
-};
-
-static const SiS_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x1024_1[] =
-{
- {{0x7e,0x4f,0x82,0x58,0x04,0xb8,0x1f,
-   0x90,0x84,0x8f,0xb9,0x30,0x00,0x06,
-   0x00}},
- {{0x7e,0x4f,0x82,0x58,0x04,0x86,0x1f,
-   0x5e,0x82,0x5d,0x87,0x10,0x00,0x06,
-   0x00}},
- {{0x7e,0x4f,0x82,0x58,0x04,0xb8,0x1f,
-   0x90,0x84,0x8f,0xb9,0x30,0x00,0x06,
-   0x00}},
- {{0x7e,0x4f,0x82,0x58,0x04,0x86,0x1f,
-   0x5e,0x82,0x5d,0x87,0x10,0x00,0x06,
-   0x00}},
- {{0x7e,0x4f,0x82,0x58,0x04,0x08,0x3e,
-   0xe0,0x84,0xdf,0x09,0x00,0x00,0x06,
-   0x00}},
- {{0x92,0x63,0x96,0x6c,0x18,0x80,0xf0,
-   0x58,0x8c,0x57,0x81,0x20,0x00,0x06,
-   0x01}},
- {{0xae,0x7f,0x92,0x88,0x94,0x28,0xf5,
-   0x00,0x84,0xff,0x29,0x10,0x00,0x02,
-   0x01}},
- {{0xce,0x9f,0x92,0xa8,0x14,0x28,0x5a,
-   0x00,0x84,0xff,0x29,0x09,0x00,0x07,
-   0x01}}
-};
-
-static const SiS_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x1024_1_H[] =
-{
- {{0x56,0x27,0x9a,0x31,0x1c,0xb8,0x1f,
-   0x90,0x84,0x8f,0xb9,0x30,0x00,0x05,
-   0x00}},
- {{0x56,0x27,0x9a,0x31,0x1c,0x86,0x1f,
-   0x5e,0x82,0x5d,0x87,0x10,0x00,0x05,
-   0x00}},
- {{0x56,0x27,0x9a,0x31,0x1c,0xb8,0x1f,
-   0x90,0x84,0x8f,0xb9,0x30,0x00,0x05,
-   0x00}},
- {{0x56,0x27,0x9a,0x31,0x1c,0x86,0x1f,
-   0x5e,0x82,0x5d,0x87,0x10,0x00,0x05,
-   0x01}},
- {{0x56,0x27,0x9a,0x31,0x1c,0x08,0x3e,
-   0xe0,0x84,0xdf,0x09,0x00,0x00,0x05,
-   0x00}},
- {{0x60,0x31,0x84,0x3a,0x86,0x80,0xf0,
-   0x58,0x8c,0x57,0x81,0x20,0x00,0x01,
-   0x01}},
- {{0x6e,0x3f,0x92,0x48,0x94,0x28,0xf5,
-   0x00,0x84,0xff,0x29,0x10,0x00,0x01,
-   0x01}}
-};
-
-static const SiS_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x1024_2[] =
-{
- {{0xce,0x72,0x91,0x81,0x8f,0x28,0x92,
-   0xc8,0x8c,0x5d,0x5c,0x01,0x00,0x02,
-   0x01}},
- {{0xce,0x72,0x91,0x81,0x8f,0x28,0x92,
-   0xaf,0x83,0x44,0x43,0x21,0x00,0x02,
-   0x01}},
- {{0xce,0x72,0x91,0x81,0x8f,0x28,0x92,
-   0xc8,0x8c,0x5d,0x5c,0x01,0x00,0x02,
-   0x01}},
- {{0xce,0x72,0x91,0x81,0x8f,0x28,0x92,
-   0xaf,0x83,0x44,0x43,0x21,0x00,0x02,
-   0x01}},
- {{0xce,0x72,0x91,0x81,0x8f,0x28,0x92,
-   0xf0,0x84,0x85,0x84,0x11,0x00,0x02,
-   0x01}},
- {{0xce,0x63,0x92,0x8b,0x19,0x28,0xd4,
-   0x3f,0x83,0x57,0x29,0x01,0x00,0x03,
-   0x01}},
- {{0xce,0x7f,0x92,0x99,0x07,0x28,0xd4,
-   0x93,0x87,0xff,0x29,0x21,0x00,0x07,
-   0x01}},
- {{0xce,0x9f,0x92,0xa8,0x14,0x28,0x5a,
-   0x00,0x84,0xff,0x29,0x09,0x00,0x07,
-   0x01}}
-};
-
-static const SiS_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x1024_2_H[] =
-{
- {{0xa6,0x4a,0x89,0x59,0x07,0x28,0x92,
-   0xc8,0x8c,0x5d,0x5c,0x01,0x00,0x06,
-   0x01}},
- {{0xa6,0x4a,0x89,0x59,0x07,0x28,0x92,
-   0xaf,0x83,0x44,0x43,0x21,0x00,0x06,
-   0x01}},
- {{0xa6,0x4a,0x89,0x59,0x07,0x28,0x92,
-   0xc8,0x8c,0x5d,0x5c,0x01,0x00,0x06,
-   0x01}},
- {{0xa6,0x4a,0x89,0x59,0x07,0x28,0x92,
-   0xfa,0x83,0x44,0x43,0x31,0x00,0x06,
-   0x01}},
- {{0xa6,0x4a,0x89,0x59,0x07,0x28,0x92,
-   0xf0,0x84,0x85,0x84,0x11,0x00,0x06,
-   0x01}},
- {{0x9c,0x31,0x80,0x59,0x87,0x28,0xd4,
-   0x3f,0x83,0x57,0x29,0x01,0x00,0x06,
-   0x01}},
- {{0x8e,0x3f,0x92,0x59,0x07,0x28,0xd4,
-   0x93,0x87,0xff,0x29,0x21,0x00,0x06,
-   0x01}}
-};
-
-static const SiS_LVDSCRT1DataStruct  SiS310_LVDSCRT11400x1050_1[] =
-{
-  {{0x6f,0x4f,0x93,0x54,0x82,0x9e,0x1f,
-    0x8f,0x81,0x8f,0x9f,0x30,0x00,0x05,
-    0x00}},
-  {{0x6f,0x4f,0x93,0x54,0x82,0x6c,0x1f,
-    0x5e,0x81,0x5d,0x6d,0x10,0x00,0x05,
-    0x00}},
-  {{0x6f,0x4f,0x93,0x54,0x82,0x9e,0x1f,
-    0x90,0x83,0x8f,0x9f,0x30,0x00,0x05,
-    0x00}},
-  {{0x6f,0x4f,0x93,0x54,0x82,0x6c,0x1f,
-    0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
-    0x00}},
-  {{0x6f,0x4f,0x93,0x54,0x82,0xee,0x1f,
-    0xdf,0x82,0xdf,0xef,0x10,0x00,0x05,
-    0x00}},
-  {{0x83,0x63,0x87,0x68,0x16,0x66,0xf0,
-    0x57,0x8e,0x57,0x67,0x20,0x00,0x06,
-    0x01}},
-  {{0x9f,0x7f,0x83,0x84,0x92,0x0e,0xf1,
-    0xff,0x86,0xff,0x0f,0x10,0x00,0x02,
-    0x01,}},
-  {{0xbf,0x9f,0x83,0xa4,0x12,0x0e,0xde,
-    0xff,0x86,0xff,0x0f,0x01,0x00,0x07,
-    0x01}},
-  {{0xce,0xae,0x92,0xb3,0x01,0x28,0x10,
-    0x19,0x80,0x19,0x29,0x0f,0x00,0x03,
-    0x00}}
-#if 0
- {{0x6f,0x4f,0x93,0x54,0x82,0x9e,0x1f,
-   0x93,0x86,0x8f,0x9f,0x30,0x00,0x05,
-   0x00}},
- {{0x6f,0x4f,0x93,0x54,0x82,0x6c,0x1f,
-   0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
-   0x00}},
- {{0x6f,0x4f,0x93,0x54,0x82,0x9e,0x1f,
-   0x93,0x86,0x8f,0x9f,0x30,0x00,0x05,
-   0x00}},
- {{0x6f,0x4f,0x93,0x54,0x82,0x6c,0x1f,
-   0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
-   0x00}},
- {{0x6f,0x4f,0x93,0x54,0x82,0xee,0x1f,
-   0xe2,0x86,0xdf,0xef,0x10,0x00,0x05,
-   0x00}},
- {{0x83,0x63,0x87,0x68,0x16,0x66,0xf0,
-   0x5a,0x8e,0x57,0x67,0x20,0x00,0x06,
-   0x01}},
- {{0x9f,0x7f,0x83,0x84,0x92,0x0e,0xf5,
-   0x02,0x86,0xff,0x0f,0x10,0x00,0x02,
-   0x01}},
- {{0xbf,0x9f,0x83,0xa4,0x12,0x0e,0x5a,
-   0x02,0x86,0xff,0x0f,0x09,0x00,0x07,
-   0x01}},
- {{0xce,0xae,0x92,0xb3,0x01,0x28,0x10,
-   0x1a,0x80,0x19,0x29,0x0f,0x00,0x03,
-   0x00}}
-#endif   
-};
-
-static const SiS_LVDSCRT1DataStruct  SiS310_LVDSCRT11400x1050_1_H[] =
-{
- {{0x47,0x27,0x8b,0x2c,0x1a,0x9e,0x1f,
-   0x8f,0x81,0x8f,0x9f,0x30,0x00,0x05,
-  0x00}},
- {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
-   0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
-   0x00}},
- {{0x47,0x27,0x8b,0x30,0x1e,0x9e,0x1f,
-   0x90,0x83,0x8f,0x9f,0x30,0x00,0x05,
-   0x00}},
- {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
-   0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
-   0x00}},
- {{0x47,0x27,0x8b,0x2c,0x1a,0xee,0x1f,
-   0xdf,0x86,0xdf,0xef,0x10,0x00,0x05,
-   0x00}},
- {{0x51,0x31,0x95,0x36,0x04,0x66,0xf0,
-   0x57,0x8e,0x57,0x67,0x20,0x00,0x01,
-   0x01}},
- {{0x5f,0x3f,0x83,0x44,0x92,0x0e,0xf1,
-   0xff,0x86,0xff,0x0f,0x10,0x00,0x01,
-   0x01}},
- {{0x6f,0x4f,0x93,0x54,0x82,0x0e,0x5a,
-   0x02,0x86,0xff,0x0f,0x09,0x00,0x05,
-   0x01}},
- {{0x76,0x56,0x9a,0x5b,0x89,0x28,0x10,
-   0x1c,0x80,0x19,0x29,0x0b,0x00,0x05,
-   0x00}}
-#if 0
- {{0x47,0x27,0x8b,0x2c,0x1a,0x9e,0x1f,
-   0x93,0x86,0x8f,0x9f,0x30,0x00,0x05,
-   0x00}},
- {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
-   0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
-   0x00}},
- {{0x47,0x27,0x8b,0x30,0x1e,0x9e,0x1f,
-   0x92,0x86,0x8f,0x9f,0x30,0x00,0x05,
-   0x00}},
- {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
-   0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
-   0x00}},
- {{0x47,0x27,0x8b,0x2c,0x1a,0xee,0x1f,
-   0xe2,0x86,0xdf,0xef,0x10,0x00,0x05,
-   0x00}},
- {{0x51,0x31,0x95,0x36,0x04,0x66,0xf0,
-   0x5a,0x8e,0x57,0x67,0x20,0x00,0x01,
-   0x01}},
- {{0x5f,0x3f,0x83,0x44,0x92,0x0e,0xf5,
-   0x02,0x86,0xff,0x0f,0x10,0x00,0x01,
-   0x01}},
- {{0x6f,0x4f,0x93,0x54,0x82,0x0e,0x5a,
-   0x02,0x86,0xff,0x0f,0x09,0x00,0x05,
-   0x01}},
- {{0x76,0x56,0x9a,0x5b,0x89,0x28,0x10,
-   0x1c,0x80,0x19,0x29,0x0b,0x00,0x05,
-   0x00}}
-#endif   
-};
-
-static const SiS_LVDSCRT1DataStruct  SiS310_LVDSCRT11400x1050_2[] =
-{
- {{0xce,0x72,0x91,0x84,0x92,0x28,0x92,
-   0xd7,0x8b,0x5d,0x5c,0x21,0x00,0x02,
-   0x01}},
- {{0xce,0x72,0x91,0x84,0x92,0x28,0x92,
-   0xbe,0x82,0x44,0x43,0x01,0x00,0x02,
-   0x01}},
- {{0xce,0x72,0x91,0x84,0x92,0x28,0x92,
-   0xd7,0x8b,0x5d,0x5c,0x21,0x00,0x02,
-   0x01}},
- {{0xce,0x72,0x91,0x84,0x92,0x28,0x92,
-   0xbe,0x82,0x44,0x43,0x01,0x00,0x02,
-   0x01}},
- {{0xce,0x72,0x91,0x84,0x92,0x28,0x92,
-   0xff,0x83,0x85,0x84,0x11,0x00,0x02,
-   0x01}},
- {{0xce,0x63,0x92,0x8e,0x1c,0x28,0xd4,
-   0x3f,0x83,0x57,0x29,0x01,0x00,0x03,
-   0x01}},
- {{0xce,0x7f,0x92,0x9c,0x0a,0x28,0xd4,
-   0x93,0x87,0xff,0x29,0x21,0x00,0x07,
-   0x01}},
- {{0xce,0x9f,0x92,0xac,0x1a,0x28,0x5a,
-   0x13,0x87,0xff,0x29,0x29,0x00,0x07,
-   0x01}},
- {{0xce,0xae,0x92,0xbc,0x0a,0x28,0x10,
-   0x20,0x84,0x19,0x29,0x0f,0x00,0x03,
-   0x00}}
-#if 0
- {{0xce,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
-   0xdb,0x8f,0x8f,0x29,0x21,0x00,0x03,
-   0x00}},
- {{0xce,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
-   0xc2,0x86,0x5d,0x29,0x01,0x00,0x03,
-   0x01}},
- {{0xce,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
-   0xdb,0x8f,0x8f,0x29,0x21,0x00,0x03,
-   0x00}},
- {{0xce,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
-   0xc2,0x86,0x5d,0x29,0x01,0x00,0x03,
-   0x00}},
- {{0xce,0x4f,0x92,0x8c,0x1a,0x28,0x9e,
-   0x03,0x87,0xdf,0x29,0x01,0x00,0x03,
-   0x00}},
- {{0xce,0x63,0x92,0x96,0x04,0x28,0xd4,
-   0x3f,0x83,0x57,0x29,0x01,0x00,0x07,
-   0x01}},
- {{0xce,0x7f,0x92,0xa4,0x12,0x28,0xd4,
-   0x93,0x87,0xff,0x29,0x21,0x00,0x07,
-   0x01}},
- {{0xce,0x9f,0x92,0xb4,0x02,0x28,0x5a,
-   0x13,0x87,0xff,0x29,0x29,0x00,0x03,
-   0x01}},
- {{0xce,0xae,0x92,0xbc,0x0a,0x28,0x10,
-   0x20,0x84,0x19,0x29,0x0f,0x00,0x03,
-   0x00}}
-#endif   
-};
-
-static const SiS_LVDSCRT1DataStruct  SiS310_LVDSCRT11400x1050_2_H[] =
-{
- {{0xa6,0x4a,0x89,0x5c,0x0a,0x28,0x92,
-   0xd7,0x8b,0x5d,0x5c,0x21,0x00,0x06,
-   0x01}},
- {{0xa6,0x4a,0x89,0x5c,0x0a,0x28,0x92,
-   0xbe,0x82,0x44,0x43,0x01,0x00,0x06,
-   0x01}},
- {{0xa6,0x4a,0x89,0x5c,0x0a,0x28,0x92,
-   0xd7,0x8b,0x5d,0x5c,0x21,0x00,0x06,
-   0x01}},
- {{0xa6,0x4a,0x89,0x5c,0x0a,0x28,0x92,
-   0xbe,0x82,0x44,0x43,0x01,0x00,0x06,
-   0x01}},
- {{0xa6,0x4a,0x89,0x5c,0x0a,0x28,0x92,
-   0xff,0x83,0x85,0x84,0x11,0x00,0x06,
-   0x01}},
- {{0x9c,0x31,0x80,0x5c,0x8a,0x28,0xd4,
-   0x3f,0x83,0x57,0x29,0x01,0x00,0x06,
-   0x01}},
- {{0x8e,0x3f,0x92,0x5c,0x0a,0x28,0xd4,
-   0x93,0x87,0xff,0x29,0x21,0x00,0x06,
-   0x01}},
- {{0x7e,0x4f,0x82,0x5c,0x0a,0x28,0x5a,
-   0x13,0x87,0xff,0x29,0x29,0x00,0x06,
-   0x01}},
- {{0x76,0x56,0x9a,0x64,0x92,0x28,0x10,
-   0x20,0x84,0x19,0x29,0x0f,0x00,0x05,
-   0x00}}
-#if 0
- {{0xa6,0x27,0x8a,0x64,0x92,0x28,0x9a,
-   0xdb,0x8f,0x8f,0x29,0x21,0x00,0x06,
-   0x00}},
- {{0xa6,0x27,0x8a,0x64,0x92,0x28,0x9a,
-   0xc2,0x86,0x5d,0x29,0x01,0x00,0x06,
-   0x00}},
- {{0xa6,0x27,0x8a,0x64,0x92,0x28,0x9a,
-   0xdb,0x8f,0x8f,0x29,0x21,0x00,0x06,
-   0x00}},
- {{0xa6,0x27,0x8a,0x64,0x92,0x28,0x9a,
-   0xc2,0x86,0x5d,0x29,0x01,0x00,0x06,
-   0x00}},
- {{0xa6,0x27,0x8a,0x64,0x92,0x28,0x9e,
-   0x03,0x87,0xdf,0x29,0x01,0x00,0x06,
-   0x00}},
- {{0x9c,0x31,0x80,0x64,0x92,0x28,0xd4,
-   0x3f,0x83,0x57,0x29,0x01,0x00,0x06,
-   0x01}},
- {{0x8e,0x3f,0x92,0x64,0x12,0x28,0xd4,
-   0x93,0x87,0xff,0x29,0x21,0x00,0x06,
-   0x01}},
- {{0x7e,0x4f,0x82,0x64,0x12,0x28,0x5a,
-   0x13,0x87,0xff,0x29,0x29,0x00,0x06,
-   0x01}},
- {{0x76,0x56,0x9a,0x64,0x92,0x28,0x10,
-   0x20,0x84,0x19,0x29,0x0f,0x00,0x05,
-   0x00}}
-#endif   
-};
-
-static const SiS_LVDSCRT1DataStruct  SiS310_LVDSCRT11600x1200_1[] =
-{
- {{0x83,0x4F,0x87,0x5B,0x13,0x06,0x3E,
-   0xB3,0x86,0x8F,0x07,0x20,0x00,0x06,
-   0x00}},
- {{0x83,0x4F,0x87,0x5B,0x13,0xD4,0x1F,
-   0x81,0x84,0x5D,0xD5,0x10,0x00,0x06,
-   0x00}},
- {{0x83,0x4F,0x87,0x5B,0x13,0x06,0x3E,
-   0xB3,0x86,0x8F,0x07,0x20,0x00,0x06,
-   0x00}},
- {{0x83,0x4F,0x87,0x5B,0x13,0xD4,0x1F,
-   0x81,0x84,0x5D,0xD5,0x10,0x00,0x06,
-   0x00}},
- {{0x83,0x4F,0x87,0x5B,0x13,0x56,0xBA,
-   0x03,0x86,0xDF,0x57,0x00,0x00,0x06,
-   0x00}},
- {{0x97,0x63,0x9B,0x6F,0x07,0xCE,0xF0,
-   0x7B,0x8E,0x57,0xCF,0x20,0x00,0x02,
-   0x01}},
- {{0xB3,0x7F,0x97,0x8B,0x83,0x76,0xF5,
-   0x23,0x86,0xFF,0x77,0x10,0x00,0x06,
-   0x01}},
- {{0xD3,0x9F,0x97,0xAB,0x03,0x76,0x5A,
-   0x23,0x86,0xFF,0x77,0x09,0x00,0x03,
-   0x01}},
- {{0xE2,0xAE,0x86,0xBA,0x92,0x90,0x10,
-   0x3D,0x80,0x19,0x91,0x0F,0x00,0x03,
-   0x00}},
- {{0xFB,0xC7,0x9F,0xD3,0x8B,0x26,0x11,
-   0xD3,0x86,0xAF,0x27,0x3F,0x00,0x07,
-   0x00}}
-#if 0
- {{0x83,0x4f,0x87,0x51,0x09,0xc0,0x1f,
-   0x90,0x84,0x8f,0xc1,0x30,0x00,0x06,
-   0x00}},
- {{0x83,0x4f,0x87,0x51,0x09,0x8e,0x1f,
-   0x5e,0x82,0x5d,0x8f,0x10,0x00,0x06,
-   0x00}},
- {{0x83,0x4f,0x87,0x51,0x09,0xc0,0x1f,
-   0x90,0x84,0x8f,0xc1,0x30,0x00,0x06,
-   0x00}},
- {{0x83,0x4f,0x87,0x51,0x09,0x8e,0x1f,
-   0x5e,0x82,0x5d,0x8f,0x10,0x00,0x06,
-   0x00}},
- {{0x83,0x4f,0x87,0x51,0x09,0x10,0x3e,
-   0xe0,0x84,0xdf,0x11,0x00,0x00,0x06,
-   0x00}},
- {{0x97,0x63,0x9b,0x65,0x1d,0x88,0xf0,
-   0x58,0x8c,0x57,0x89,0x20,0x00,0x06,
-   0x01}},
- {{0xb3,0x7f,0x97,0x81,0x99,0x30,0xf5,
-   0x00,0x84,0xff,0x31,0x10,0x00,0x02,
-   0x01}},
- {{0xd3,0x9f,0x97,0xa1,0x19,0x30,0x5a,
-   0x00,0x84,0xff,0x31,0x09,0x00,0x07,
-   0x01}},
- {{0xe2,0xae,0x86,0xb0,0x88,0x4a,0x10,
-   0x1a,0x8e,0x19,0x4b,0x2f,0x00,0x03,
-   0x00}},
- {{0xfb,0xc7,0x9f,0xc9,0x81,0xe0,0x10,
-   0xb0,0x84,0xaf,0xe1,0x2f,0x00,0x07,
-   0x00}}
-#endif
-};
-
-static const SiS_LVDSCRT1DataStruct  SiS310_LVDSCRT11600x1200_1_H[] =
-{
- {{0x5B,0x27,0x9F,0x33,0x0B,0x06,0x2E,
-   0xB3,0x86,0x8F,0x07,0x20,0x00,0x01,
-   0x00}},
- {{0x5B,0x27,0x9F,0x29,0x01,0x8E,0x1F,
-   0x81,0x84,0x5D,0xD5,0x10,0x00,0x06,
-   0x00}},
- {{0x5B,0x27,0x9F,0x33,0x0B,0x06,0x2E,
-   0xB3,0x86,0x8F,0x07,0x20,0x00,0x01,
-   0x00}},
- {{0x83,0x4F,0x87,0x5B,0x13,0xD4,0x1F,
-   0x81,0x84,0x5D,0xD5,0x10,0x00,0x06,
-   0x00}},
- {{0x5B,0x27,0x9F,0x33,0x0B,0x56,0xBA,
-   0x03,0x86,0xDF,0x57,0x00,0x00,0x01,
-   0x00}},
- {{0x65,0x31,0x89,0x3D,0x95,0xCE,0xF0,
-   0x7B,0x8E,0x57,0xCF,0x20,0x00,0x01,
-   0x01}},
- {{0x73,0x3F,0x97,0x4B,0x83,0x76,0xF5,
-   0x23,0x86,0xFF,0x77,0x10,0x00,0x05,
-   0x01}},
- {{0xD3,0x9F,0x97,0xAB,0x03,0x76,0x5A,
-   0x23,0x86,0xFF,0x77,0x09,0x00,0x03,
-   0x01}},
- {{0xE2,0xAE,0x86,0xBA,0x92,0x90,0x10,
-   0x3D,0x80,0x19,0x91,0x0F,0x00,0x03,
-   0x00}},
- {{0x97,0x63,0x9B,0x6F,0x07,0xE0,0x10,
-   0xB0,0x84,0xAF,0xE1,0x2F,0x00,0x06,
-   0x00}}
-#if 0
- {{0x5b,0x27,0x9f,0x29,0x01,0xc0,0x1f,
-   0x90,0x84,0x8f,0xc1,0x30,0x00,0x01,
-   0x00}},
- {{0x5b,0x27,0x9f,0x29,0x01,0x8e,0x1f,
-   0x5e,0x82,0x5d,0x8f,0x10,0x00,0x01,
-   0x00}},
- {{0x5b,0x27,0x9f,0x29,0x01,0xc0,0x1f,
-   0x90,0x84,0x8f,0xc1,0x30,0x00,0x01,
-   0x00}},
- {{0x5b,0x27,0x9f,0x29,0x01,0x8e,0x1f,
-   0x5e,0x82,0x5d,0x8f,0x10,0x00,0x01,
-   0x00}},
- {{0x5b,0x27,0x9f,0x29,0x01,0x10,0x3e,
-   0xe0,0x84,0xdf,0x11,0x00,0x00,0x01,
-   0x00}},
- {{0x65,0x31,0x89,0x33,0x8b,0x88,0xf0,
-   0x58,0x8c,0x57,0x89,0x20,0x00,0x01,
-   0x01}},
- {{0x73,0x3f,0x97,0x41,0x99,0x30,0xf5,
-   0x00,0x84,0xff,0x31,0x10,0x00,0x01,
-   0x01}},
- {{0x83,0x4f,0x87,0x51,0x09,0x30,0x5a,
-   0x00,0x84,0xff,0x31,0x09,0x00,0x06,
-   0x01}},
- {{0x8a,0x56,0x8e,0x58,0x10,0x4a,0x10,
-   0x1a,0x8e,0x19,0x4b,0x2f,0x00,0x06,
-   0x00}},
- {{0x97,0x63,0x9b,0x65,0x1d,0xe0,0x10,
-   0xb0,0x84,0xaf,0xe1,0x2f,0x00,0x06,
-   0x00}}
-#endif
-};
-
-static const SiS_LVDSCRT1DataStruct  SiS310_LVDSCRT11600x1200_2[] =
-{
- {{0xFB,0x87,0x86,0x97,0x0F,0x26,0x97,
-   0x43,0x86,0xDB,0xDA,0x11,0x00,0x07,
-   0x01}},
- {{0xFB,0x87,0x86,0x97,0x0F,0x26,0x97,
-   0x2A,0x8D,0xC2,0xC1,0x11,0x00,0x07,
-   0x01}},
- {{0xFB,0x87,0x86,0x97,0x0F,0x26,0x97,
-   0x43,0x86,0xDB,0xDA,0x11,0x00,0x07,
-   0x01}},
- {{0xFB,0x87,0x86,0x97,0x0F,0x26,0x97,
-   0x2A,0x8D,0xC2,0xC1,0x11,0x00,0x07,
-   0x01}},
- {{0xFB,0x87,0x86,0x97,0x0F,0x26,0x9F,
-   0x6B,0x8E,0x03,0x02,0x01,0x00,0x07,
-   0x01}},
- {{0xFB,0x63,0x9F,0xA1,0x99,0x26,0xD5,
-   0xA7,0x8A,0xBF,0xBE,0x01,0x00,0x07,
-   0x01}},
- {{0xFB,0x7F,0x9F,0xAF,0x87,0x26,0xDD,
-   0xFB,0x8E,0x13,0x12,0x31,0x00,0x03,
-   0x01}},
- {{0xFB,0x9F,0x9F,0xBF,0x97,0x26,0x5B,
-   0x7B,0x8E,0xFF,0x27,0x39,0x00,0x03,
-   0x01}},
- {{0xFB,0xAE,0x9F,0xC6,0x9E,0x26,0x11,
-   0x88,0x8B,0x19,0x27,0x1F,0x00,0x03,
-   0x00}},
- {{0xFB,0xC7,0x9F,0xD3,0x8B,0x26,0x11,
-   0xD3,0x86,0xAF,0x27,0x3F,0x00,0x07,
-   0x00}}
-#if 0
- {{0xfb,0x88,0x87,0x90,0x08,0xe0,0x96,
-   0x20,0x84,0xb9,0xb8,0x01,0x00,0x07,
-   0x01}},
- {{0xfb,0x88,0x87,0x90,0x08,0xe0,0x96,
-   0x07,0x8b,0xa0,0x9f,0x01,0x00,0x07,
-   0x01}},
- {{0xfb,0x88,0x87,0x90,0x08,0xe0,0x96,
-   0x20,0x84,0xb9,0xb8,0x01,0x00,0x07,
-   0x01}},
- {{0xfb,0x88,0x87,0x90,0x08,0xe0,0x96,
-   0x07,0x8b,0xa0,0x9f,0x01,0x00,0x07,
-   0x01}},
- {{0xfb,0x88,0x87,0x90,0x08,0xe0,0x96,
-   0x48,0x8c,0xe1,0xe0,0x11,0x00,0x07,
-   0x01}},
- {{0xfb,0x63,0x9f,0x9a,0x92,0xe0,0xd4,
-   0x9b,0x8f,0x9d,0x9c,0x21,0x00,0x07,
-   0x01}},
- {{0xfb,0x7f,0x9f,0xa8,0x80,0xe0,0xd4,
-   0xef,0x83,0xff,0xe1,0x21,0x00,0x03,
-   0x01}},
- {{0xfb,0x9f,0x9f,0xb8,0x90,0xe0,0x5a,
-   0x6f,0x83,0xff,0xe1,0x29,0x00,0x03,
-   0x01}},
- {{0xfb,0xae,0x9f,0xbf,0x97,0xe0,0x10,
-   0x7c,0x80,0x19,0xe1,0x0f,0x00,0x03,
-   0x00}},
- {{0xfb,0xc7,0x9f,0xc9,0x84,0xe0,0x10,
-   0xc7,0x8b,0xaf,0xe1,0x0f,0x00,0x07,
-   0x00}}
-#endif
-};
-
-static const SiS_LVDSCRT1DataStruct  SiS310_LVDSCRT11600x1200_2_H[] =
-{
- {{0xD3,0x5F,0x9E,0x6F,0x07,0x26,0x97,
-   0x43,0x86,0xDB,0xDA,0x11,0x00,0x02,
-   0x01}},
- {{0xD3,0x27,0x97,0x6F,0x07,0x26,0x97,
-   0x6B,0x8E,0x83,0x82,0x01,0x00,0x03,
-   0x01}},
- {{0xD3,0x5F,0x9E,0x6F,0x07,0x26,0x97,
-   0x43,0x86,0xDB,0xDA,0x11,0x00,0x02,
-   0x01}},
- {{0xD3,0x27,0x97,0x6F,0x07,0x26,0x97,
-   0x07,0x8B,0xA0,0x9F,0x01,0x00,0x02,
-   0x01}},
- {{0xD3,0x27,0x97,0x6F,0x07,0x26,0x97,
-   0x6B,0x8E,0x83,0x82,0x01,0x00,0x03,
-   0x01}},
- {{0xC9,0x31,0x8D,0x6F,0x07,0x26,0xD5,
-   0xA7,0x8A,0xBF,0xBE,0x01,0x00,0x03,
-   0x01}},
- {{0xBB,0x3F,0x9F,0x6F,0x87,0x26,0xDD,
-   0xFB,0x8E,0x13,0x12,0x31,0x00,0x02,
-   0x01}},
- {{0xAB,0x4F,0x8F,0x68,0x80,0xE0,0x5A,
-   0x6F,0x83,0xFF,0xE1,0x29,0x00,0x02,
-   0x01}},
- {{0xA3,0x56,0x87,0x67,0x9F,0xE0,0x10,
-   0x7C,0x80,0x19,0xE1,0x0F,0x00,0x06,
-   0x00}},
- {{0x97,0x63,0x9B,0x68,0x00,0xE0,0x10,
-   0xC7,0x8B,0xAF,0xE1,0x0F,0x00,0x02,
-   0x00}}
-#if 0
- {{0xd3,0x60,0x9f,0x68,0x00,0xe0,0x96,
-   0x20,0x84,0xb9,0xb8,0x01,0x00,0x02,
-   0x01}},
- {{0xd3,0x60,0x9f,0x68,0x00,0xe0,0x96,
-   0x07,0x8b,0xa0,0x9f,0x01,0x00,0x02,
-   0x01}},
- {{0xd3,0x60,0x9f,0x68,0x00,0xe0,0x96,
-   0x20,0x84,0xb9,0xb8,0x01,0x00,0x02,
-   0x01}},
- {{0xd3,0x60,0x9f,0x68,0x00,0xe0,0x96,
-   0x07,0x8b,0xa0,0x9f,0x01,0x00,0x02,
-   0x01}},
- {{0xd3,0x60,0x9f,0x68,0x00,0xe0,0x96,
-   0x48,0x8c,0xe1,0xe0,0x11,0x00,0x02,
-   0x01}},
- {{0xc9,0x31,0x8d,0x68,0x00,0xe0,0xd4,
-   0x9b,0x8f,0x9d,0x9c,0x21,0x00,0x03,
-   0x01}},
- {{0xbb,0x3f,0x9f,0x68,0x80,0xe0,0xd4,
-   0xef,0x83,0xff,0xe1,0x21,0x00,0x02,
-   0x01}},
- {{0xab,0x4f,0x8f,0x68,0x80,0xe0,0x5a,
-   0x6f,0x83,0xff,0xe1,0x29,0x00,0x02,
-   0x01}},
- {{0xa3,0x56,0x87,0x67,0x9f,0xe0,0x10,
-   0x7c,0x80,0x19,0xe1,0x0f,0x00,0x06,
-   0x00}},
- {{0x97,0x63,0x9b,0x68,0x00,0xe0,0x10,
-   0xc7,0x8b,0xaf,0xe1,0x0f,0x00,0x02,
-   0x00}}
-#endif
-};
-
-static const SiS_LVDSCRT1DataStruct  SiS310_LVDSCRT1XXXxXXX_1[] =
-{
- {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
-   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
-   0x00}},
- {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
-   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
-   0x00}},
- {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
-   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
-   0x00}},
- {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
-   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
-   0x00}},
- {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
-   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x05,
-   0x00}},
- {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
-   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
-   0x01}},
- {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
-   0x02,0x88,0xff,0x25,0x10,0x00,0x02,
-   0x01}},
- {{0xce,0x9f,0x92,0xa8,0x14,0x28,0x5a,
-   0x00,0x84,0xff,0x29,0x09,0x00,0x07,
-   0x01}},
- {{0xce,0x9f,0x92,0xa9,0x17,0x24,0xf5,
-   0x02,0x88,0xff,0x25,0x10,0x00,0x07,
-   0x01}}
-};
-
-static const SiS_LVDSCRT1DataStruct  SiS310_LVDSCRT1XXXxXXX_1_H[] =
-{
- {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
-   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
-   0x00}},
- {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
-   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
-   0x00}},
- {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
-   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
-   0x00}},
- {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
-   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
-   0x00}},
- {{0x38,0x27,0x9c,0x2c,0x80,0x0b,0x3e,
-   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
-   0x00}},
- {{0x4d,0x31,0x91,0x3b,0x03,0x72,0xf0,
-   0x58,0x8c,0x57,0x73,0x20,0x00,0x01,
-   0x01}},
- {{0x63,0x3f,0x87,0x4a,0x92,0x24,0xf5,
-   0x02,0x88,0xff,0x25,0x10,0x00,0x01,
-   0x01}}
-};
-
-
 /* CRT1 CRTC for Chrontel TV slave modes */
 
-static const SiS_LVDSCRT1DataStruct  SiS310_CHTVCRT1UNTSC[] =
-{ 
+static const struct SiS_LVDSCRT1Data SiS310_CHTVCRT1UNTSC[] =
+{
  {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
    0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,
    0x00 }},
@@ -2546,7 +1132,7 @@ static const SiS_LVDSCRT1DataStruct  SiS310_CHTVCRT1UNTSC[] =
    0x01}}
 };
 
-static const SiS_LVDSCRT1DataStruct  SiS310_CHTVCRT1ONTSC[] =
+static const struct SiS_LVDSCRT1Data SiS310_CHTVCRT1ONTSC[] =
 {
  {{0x63,0x4f,0x87,0x5a,0x9f,0x0b,0x3e,
    0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,
@@ -2571,8 +1157,8 @@ static const SiS_LVDSCRT1DataStruct  SiS310_CHTVCRT1ONTSC[] =
    0x01 }}
 };
 
-static const SiS_LVDSCRT1DataStruct  SiS310_CHTVCRT1UPAL[] =
-{ 
+static const struct SiS_LVDSCRT1Data SiS310_CHTVCRT1UPAL[] =
+{
  {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
    0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,
    0x00 }},
@@ -2596,7 +1182,7 @@ static const SiS_LVDSCRT1DataStruct  SiS310_CHTVCRT1UPAL[] =
    0x01}}
 };
 
-static const SiS_LVDSCRT1DataStruct  SiS310_CHTVCRT1OPAL[] =
+static const struct SiS_LVDSCRT1Data SiS310_CHTVCRT1OPAL[] =
 {
  {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
    0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
@@ -2621,8 +1207,7 @@ static const SiS_LVDSCRT1DataStruct  SiS310_CHTVCRT1OPAL[] =
    0x01 }}
 };
 
-
-static const SiS_CHTVRegDataStruct SiS310_CHTVReg_UNTSC[] =
+static const struct SiS_CHTVRegData SiS310_CHTVReg_UNTSC[] =
 {
  {{0x4a,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
  {{0x4a,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
@@ -2642,7 +1227,7 @@ static const SiS_CHTVRegDataStruct SiS310_CHTVReg_UNTSC[] =
       for PAL-M and PAL-N all above is corrected.
     */
 
-static const SiS_CHTVRegDataStruct SiS310_CHTVReg_ONTSC[] =
+static const struct SiS_CHTVRegData SiS310_CHTVReg_ONTSC[] =
 {
  {{0x49,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
  {{0x49,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
@@ -2653,7 +1238,7 @@ static const SiS_CHTVRegDataStruct SiS310_CHTVReg_ONTSC[] =
  {{0xed,0x77,0xbb,0x66,0x8c,0x21,0x02,0x5a,0x04,0x00,0x80,0x1f,0x9f,0xc1,0x0c,0x00}}
 };
 
-static const SiS_CHTVRegDataStruct SiS310_CHTVReg_UPAL[] =
+static const struct SiS_CHTVRegData SiS310_CHTVReg_UPAL[] =
 {
  {{0x41,0x7f,0xb7,0x34,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
  {{0x41,0x7f,0xb7,0x80,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
@@ -2664,7 +1249,7 @@ static const SiS_CHTVRegDataStruct SiS310_CHTVReg_UPAL[] =
  {{0xe5,0x7f,0xb7,0x1d,0xa7,0x3e,0x04,0x5a,0x05,0x00,0x80,0x20,0x3e,0xe4,0x22,0x00}}
 };
 
-static const SiS_CHTVRegDataStruct SiS310_CHTVReg_OPAL[] =
+static const struct SiS_CHTVRegData SiS310_CHTVReg_OPAL[] =
 {
  {{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
  {{0x41,0x7f,0xb7,0x86,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
@@ -2675,7 +1260,7 @@ static const SiS_CHTVRegDataStruct SiS310_CHTVReg_OPAL[] =
  {{0xe4,0x7f,0xb7,0x1e,0xaf,0x29,0x37,0x5a,0x05,0x00,0x80,0x25,0x8c,0xb2,0x2a,0x00}}
 };
 
-static const SiS_CHTVRegDataStruct SiS310_CHTVReg_UPALM[] =
+static const struct SiS_CHTVRegData SiS310_CHTVReg_UPALM[] =
 {
  {{0x52,0x77,0xbb,0x94,0x84,0x48,0xfe,0x83,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
  {{0x52,0x77,0xbb,0x94,0x84,0x48,0xfe,0x83,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
@@ -2691,7 +1276,7 @@ static const SiS_CHTVRegDataStruct SiS310_CHTVReg_UPALM[] =
 #endif
 };
 
-static const SiS_CHTVRegDataStruct SiS310_CHTVReg_OPALM[] =
+static const struct SiS_CHTVRegData SiS310_CHTVReg_OPALM[] =
 {
  {{0x51,0x77,0xbb,0x7b,0x84,0x34,0x00,0x83,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
  {{0x51,0x77,0xbb,0x7b,0x84,0x34,0x00,0x83,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
@@ -2707,7 +1292,7 @@ static const SiS_CHTVRegDataStruct SiS310_CHTVReg_OPALM[] =
 #endif
 };
 
-static const SiS_CHTVRegDataStruct SiS310_CHTVReg_UPALN[] =
+static const struct SiS_CHTVRegData SiS310_CHTVReg_UPALN[] =
 {
  {{0x41,0x7f,0xb7,0x34,0xad,0x50,0x34,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
  {{0x41,0x7f,0xb7,0x80,0x85,0x50,0x00,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
@@ -2723,7 +1308,7 @@ static const SiS_CHTVRegDataStruct SiS310_CHTVReg_UPALN[] =
 #endif
 };
 
-static const SiS_CHTVRegDataStruct SiS310_CHTVReg_OPALN[] =
+static const struct SiS_CHTVRegData SiS310_CHTVReg_OPALN[] =
 {
  {{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
  {{0x41,0x7f,0xb7,0x86,0x85,0x50,0x00,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
@@ -2739,16 +1324,16 @@ static const SiS_CHTVRegDataStruct SiS310_CHTVReg_OPALN[] =
 #endif
 };
 
-static const UCHAR SiS310_CHTVVCLKUNTSC[] = {0x41,0x41,0x41,0x41,0x42,0x46,0x53};
-static const UCHAR SiS310_CHTVVCLKONTSC[] = {0x48,0x48,0x48,0x48,0x45,0x43,0x51};
+static const unsigned char SiS310_CHTVVCLKUNTSC[] = { 0x41,0x41,0x41,0x41,0x42,0x46,0x53 };
+static const unsigned char SiS310_CHTVVCLKONTSC[] = { 0x48,0x48,0x48,0x48,0x45,0x43,0x51 };
 
-static const UCHAR SiS310_CHTVVCLKUPAL[]  = {0x47,0x47,0x47,0x47,0x48,0x4a,0x54};
-static const UCHAR SiS310_CHTVVCLKOPAL[]  = {0x47,0x47,0x47,0x47,0x48,0x4f,0x52};
+static const unsigned char SiS310_CHTVVCLKUPAL[]  = { 0x47,0x47,0x47,0x47,0x48,0x4a,0x54 };
+static const unsigned char SiS310_CHTVVCLKOPAL[]  = { 0x47,0x47,0x47,0x47,0x48,0x4f,0x52 };
 
-static const UCHAR SiS310_CHTVVCLKUPALM[] = {0x41,0x41,0x41,0x41,0x42,0x46,0x53};
-static const UCHAR SiS310_CHTVVCLKOPALM[] = {0x48,0x48,0x48,0x48,0x45,0x43,0x51};
+static const unsigned char SiS310_CHTVVCLKUPALM[] = { 0x41,0x41,0x41,0x41,0x42,0x46,0x53 };
+static const unsigned char SiS310_CHTVVCLKOPALM[] = { 0x48,0x48,0x48,0x48,0x45,0x43,0x51 };
 
-static const UCHAR SiS310_CHTVVCLKUPALN[] = {0x47,0x47,0x47,0x47,0x48,0x4a,0x54};
-static const UCHAR SiS310_CHTVVCLKOPALN[] = {0x47,0x47,0x47,0x47,0x48,0x4f,0x52};
+static const unsigned char SiS310_CHTVVCLKUPALN[] = { 0x47,0x47,0x47,0x47,0x48,0x4a,0x54 };
+static const unsigned char SiS310_CHTVVCLKOPALN[] = { 0x47,0x47,0x47,0x47,0x48,0x4f,0x52 };
 
 
index aaed8c2..f7c0046 100644 (file)
@@ -4,4 +4,4 @@
 
 obj-$(CONFIG_FB_SIS) += sisfb.o
 
-sisfb-objs := sis_main.o sis_accel.o init.o init301.o
+sisfb-objs := sis_main.o sis_accel.o init.o init301.o initextlfb.o
index ecfd721..2ab3868 100644 (file)
@@ -2,11 +2,12 @@
 /* $XdotOrg$ */
 /*
  * Mode initializing code (CRT1 section) for
- * for SiS 300/305/540/630/730 and
- *     SiS 315/550/650/M650/651/661FX/M661FX/740/741(GX)/M741/330/660/M660/760/M760
- * (Universal module for Linux kernel framebuffer and XFree86 4.x)
+ * for SiS 300/305/540/630/730,
+ *     SiS 315/550/[M]650/651/[M]661[FGM]X/[M]74x[GX]/330/[M]76x[GX],
+ *     XGI Volari V3XT/V5/V8, Z7
+ * (Universal module for Linux kernel framebuffer and X.org/XFree86 4.x)
  *
- * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
  *
  * If distributed as part of the Linux kernel, the following license terms
  * apply:
  *
  * Formerly based on non-functional code-fragements for 300 series by SiS, Inc.
  * Used by permission.
- *
- * TW says: This code looks awful, I know. But please don't do anything about
- * this otherwise debugging will be hell.
- * The code is extremely fragile as regards the different chipsets, different
- * video bridges and combinations thereof. If anything is changed, extreme
- * care has to be taken that that change doesn't break it for other chipsets,
- * bridges or combinations thereof.
- * All comments in this file are by me, regardless if they are marked TW or not.
- *
  */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include "init.h"
 
 #ifdef SIS300
 
 #if defined(SIS300) || defined(SIS315H)
 static void
-InitCommonPointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+InitCommonPointer(struct SiS_Private *SiS_Pr)
 {
+   SiS_Pr->SiS_SModeIDTable  = SiS_SModeIDTable;
    SiS_Pr->SiS_StResInfo     = SiS_StResInfo;
    SiS_Pr->SiS_ModeResInfo   = SiS_ModeResInfo;
    SiS_Pr->SiS_StandTable    = SiS_StandTable;
 
-   SiS_Pr->SiS_NTSCPhase     = SiS_NTSCPhase;
-   SiS_Pr->SiS_PALPhase      = SiS_PALPhase;
-   SiS_Pr->SiS_NTSCPhase2    = SiS_NTSCPhase2;
-   SiS_Pr->SiS_PALPhase2     = SiS_PALPhase2;
-   SiS_Pr->SiS_PALMPhase     = SiS_PALMPhase;
-   SiS_Pr->SiS_PALNPhase     = SiS_PALNPhase;
-   SiS_Pr->SiS_PALMPhase2    = SiS_PALMPhase2;
-   SiS_Pr->SiS_PALNPhase2    = SiS_PALNPhase2;
-   SiS_Pr->SiS_SpecialPhase  = SiS_SpecialPhase;
-   SiS_Pr->SiS_SpecialPhaseM = SiS_SpecialPhaseM;
-   SiS_Pr->SiS_SpecialPhaseJ = SiS_SpecialPhaseJ;
-
    SiS_Pr->SiS_NTSCTiming     = SiS_NTSCTiming;
    SiS_Pr->SiS_PALTiming      = SiS_PALTiming;
    SiS_Pr->SiS_HiTVSt1Timing  = SiS_HiTVSt1Timing;
@@ -137,6 +122,7 @@ InitCommonPointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
    SiS_Pr->SiS_ExtLCD1280x768_2Data = SiS_ExtLCD1280x768_2Data;
    SiS_Pr->SiS_LCD1280x800Data      = SiS_LCD1280x800Data;
    SiS_Pr->SiS_LCD1280x800_2Data    = SiS_LCD1280x800_2Data;
+   SiS_Pr->SiS_LCD1280x854Data      = SiS_LCD1280x854Data;
    SiS_Pr->SiS_LCD1280x960Data      = SiS_LCD1280x960Data;
    SiS_Pr->SiS_StLCD1400x1050Data   = SiS_StLCD1400x1050Data;
    SiS_Pr->SiS_ExtLCD1400x1050Data  = SiS_ExtLCD1400x1050Data;
@@ -145,67 +131,30 @@ InitCommonPointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
    SiS_Pr->SiS_ExtLCD1600x1200Data  = SiS_ExtLCD1600x1200Data;
    SiS_Pr->SiS_NoScaleData          = SiS_NoScaleData;
 
-   SiS_Pr->SiS_LVDS320x480Data_1   = SiS_LVDS320x480Data_1;
+   SiS_Pr->SiS_LVDS320x240Data_1   = SiS_LVDS320x240Data_1;
+   SiS_Pr->SiS_LVDS320x240Data_2   = SiS_LVDS320x240Data_2;
+   SiS_Pr->SiS_LVDS640x480Data_1   = SiS_LVDS640x480Data_1;
    SiS_Pr->SiS_LVDS800x600Data_1   = SiS_LVDS800x600Data_1;
-   SiS_Pr->SiS_LVDS800x600Data_2   = SiS_LVDS800x600Data_2;
-   SiS_Pr->SiS_LVDS1024x768Data_1  = SiS_LVDS1024x768Data_1;
-   SiS_Pr->SiS_LVDS1024x768Data_2  = SiS_LVDS1024x768Data_2;
-   SiS_Pr->SiS_LVDS1280x1024Data_1 = SiS_LVDS1280x1024Data_1;
-   SiS_Pr->SiS_LVDS1280x1024Data_2 = SiS_LVDS1280x1024Data_2;
-   SiS_Pr->SiS_LVDS1400x1050Data_1 = SiS_LVDS1400x1050Data_1;
-   SiS_Pr->SiS_LVDS1400x1050Data_2 = SiS_LVDS1400x1050Data_2;
-   SiS_Pr->SiS_LVDS1600x1200Data_1 = SiS_LVDS1600x1200Data_1;
-   SiS_Pr->SiS_LVDS1600x1200Data_2 = SiS_LVDS1600x1200Data_2;
-   SiS_Pr->SiS_LVDS1280x768Data_1  = SiS_LVDS1280x768Data_1;
-   SiS_Pr->SiS_LVDS1280x768Data_2  = SiS_LVDS1280x768Data_2;
    SiS_Pr->SiS_LVDS1024x600Data_1  = SiS_LVDS1024x600Data_1;
-   SiS_Pr->SiS_LVDS1024x600Data_2  = SiS_LVDS1024x600Data_2;
-   SiS_Pr->SiS_LVDS1152x768Data_1  = SiS_LVDS1152x768Data_1;
-   SiS_Pr->SiS_LVDS1152x768Data_2  = SiS_LVDS1152x768Data_2;
-   SiS_Pr->SiS_LVDSXXXxXXXData_1   = SiS_LVDSXXXxXXXData_1;
-   SiS_Pr->SiS_LVDS1280x960Data_1  = SiS_LVDS1280x960Data_1;
-   SiS_Pr->SiS_LVDS1280x960Data_2  = SiS_LVDS1280x960Data_2;
-   SiS_Pr->SiS_LVDS640x480Data_1   = SiS_LVDS640x480Data_1;
-   SiS_Pr->SiS_LVDS1280x960Data_1  = SiS_LVDS1280x1024Data_1;
-   SiS_Pr->SiS_LVDS1280x960Data_2  = SiS_LVDS1280x1024Data_2;
-   SiS_Pr->SiS_LVDS640x480Data_1   = SiS_LVDS640x480Data_1;
-   SiS_Pr->SiS_LVDS640x480Data_2   = SiS_LVDS640x480Data_2;
-
-   SiS_Pr->SiS_LVDS848x480Data_1   = SiS_LVDS848x480Data_1;
-   SiS_Pr->SiS_LVDS848x480Data_2   = SiS_LVDS848x480Data_2;
-   SiS_Pr->SiS_LVDSBARCO1024Data_1 = SiS_LVDSBARCO1024Data_1;
-   SiS_Pr->SiS_LVDSBARCO1024Data_2 = SiS_LVDSBARCO1024Data_2;
-   SiS_Pr->SiS_LVDSBARCO1366Data_1 = SiS_LVDSBARCO1366Data_1;
-   SiS_Pr->SiS_LVDSBARCO1366Data_2 = SiS_LVDSBARCO1366Data_2;
+   SiS_Pr->SiS_LVDS1024x768Data_1  = SiS_LVDS1024x768Data_1;
 
-   SiS_Pr->SiS_LVDSCRT11280x768_1    = SiS_LVDSCRT11280x768_1;
+   SiS_Pr->SiS_LVDSCRT1320x240_1     = SiS_LVDSCRT1320x240_1;
+   SiS_Pr->SiS_LVDSCRT1320x240_2     = SiS_LVDSCRT1320x240_2;
+   SiS_Pr->SiS_LVDSCRT1320x240_2_H   = SiS_LVDSCRT1320x240_2_H;
+   SiS_Pr->SiS_LVDSCRT1320x240_3     = SiS_LVDSCRT1320x240_3;
+   SiS_Pr->SiS_LVDSCRT1320x240_3_H   = SiS_LVDSCRT1320x240_3_H;
+   SiS_Pr->SiS_LVDSCRT1640x480_1     = SiS_LVDSCRT1640x480_1;
+   SiS_Pr->SiS_LVDSCRT1640x480_1_H   = SiS_LVDSCRT1640x480_1_H;
+#if 0
    SiS_Pr->SiS_LVDSCRT11024x600_1    = SiS_LVDSCRT11024x600_1;
-   SiS_Pr->SiS_LVDSCRT11152x768_1    = SiS_LVDSCRT11152x768_1;
-   SiS_Pr->SiS_LVDSCRT11280x768_1_H  = SiS_LVDSCRT11280x768_1_H;
    SiS_Pr->SiS_LVDSCRT11024x600_1_H  = SiS_LVDSCRT11024x600_1_H;
-   SiS_Pr->SiS_LVDSCRT11152x768_1_H  = SiS_LVDSCRT11152x768_1_H;
-   SiS_Pr->SiS_LVDSCRT11280x768_2    = SiS_LVDSCRT11280x768_2;
    SiS_Pr->SiS_LVDSCRT11024x600_2    = SiS_LVDSCRT11024x600_2;
-   SiS_Pr->SiS_LVDSCRT11152x768_2    = SiS_LVDSCRT11152x768_2;
-   SiS_Pr->SiS_LVDSCRT11280x768_2_H  = SiS_LVDSCRT11280x768_2_H;
    SiS_Pr->SiS_LVDSCRT11024x600_2_H  = SiS_LVDSCRT11024x600_2_H;
-   SiS_Pr->SiS_LVDSCRT11152x768_2_H  = SiS_LVDSCRT11152x768_2_H;
-   SiS_Pr->SiS_LVDSCRT1320x480_1     = SiS_LVDSCRT1320x480_1;
-   SiS_Pr->SiS_LVDSCRT1640x480_1     = SiS_LVDSCRT1640x480_1;
-   SiS_Pr->SiS_LVDSCRT1640x480_1_H   = SiS_LVDSCRT1640x480_1_H;
-   SiS_Pr->SiS_LVDSCRT1640x480_2     = SiS_LVDSCRT1640x480_2;
-   SiS_Pr->SiS_LVDSCRT1640x480_2_H   = SiS_LVDSCRT1640x480_2_H;
-   SiS_Pr->SiS_LVDSCRT1640x480_3     = SiS_LVDSCRT1640x480_3;
-   SiS_Pr->SiS_LVDSCRT1640x480_3_H   = SiS_LVDSCRT1640x480_3_H;
+#endif
 
    SiS_Pr->SiS_CHTVUNTSCData = SiS_CHTVUNTSCData;
    SiS_Pr->SiS_CHTVONTSCData = SiS_CHTVONTSCData;
 
-   SiS_Pr->SiS_CHTVUNTSCDesData = SiS_CHTVUNTSCDesData;
-   SiS_Pr->SiS_CHTVONTSCDesData = SiS_CHTVONTSCDesData;
-   SiS_Pr->SiS_CHTVUPALDesData  = SiS_CHTVUPALDesData;
-   SiS_Pr->SiS_CHTVOPALDesData  = SiS_CHTVOPALDesData;
-
    SiS_Pr->SiS_PanelMinLVDS   = Panel_800x600;    /* lowest value LVDS/LCDA */
    SiS_Pr->SiS_PanelMin301    = Panel_1024x768;   /* lowest value 301 */
 }
@@ -213,50 +162,24 @@ InitCommonPointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 
 #ifdef SIS300
 static void
-InitTo300Pointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+InitTo300Pointer(struct SiS_Private *SiS_Pr)
 {
-   InitCommonPointer(SiS_Pr, HwInfo);
+   InitCommonPointer(SiS_Pr);
 
-   SiS_Pr->SiS_SModeIDTable  = SiS300_SModeIDTable;
    SiS_Pr->SiS_VBModeIDTable = SiS300_VBModeIDTable;
    SiS_Pr->SiS_EModeIDTable  = SiS300_EModeIDTable;
    SiS_Pr->SiS_RefIndex      = SiS300_RefIndex;
    SiS_Pr->SiS_CRT1Table     = SiS300_CRT1Table;
-   if(HwInfo->jChipType == SIS_300) {
-      SiS_Pr->SiS_MCLKData_0    = SiS300_MCLKData_300; /* 300 */
+   if(SiS_Pr->ChipType == SIS_300) {
+      SiS_Pr->SiS_MCLKData_0 = SiS300_MCLKData_300; /* 300 */
    } else {
-      SiS_Pr->SiS_MCLKData_0    = SiS300_MCLKData_630; /* 630, 730 */
+      SiS_Pr->SiS_MCLKData_0 = SiS300_MCLKData_630; /* 630, 730 */
    }
    SiS_Pr->SiS_VCLKData      = SiS300_VCLKData;
-   SiS_Pr->SiS_VBVCLKData    = (SiS_VBVCLKDataStruct *)SiS300_VCLKData;
+   SiS_Pr->SiS_VBVCLKData    = (struct SiS_VBVCLKData *)SiS300_VCLKData;
 
    SiS_Pr->SiS_SR15  = SiS300_SR15;
 
-#ifdef LINUX_KERNEL
-   SiS_Pr->pSiS_SR07 = &SiS300_SR07;
-   SiS_Pr->SiS_CR40  = SiS300_CR40;
-   SiS_Pr->SiS_CR49  = SiS300_CR49;
-   SiS_Pr->pSiS_SR1F = &SiS300_SR1F;
-   SiS_Pr->pSiS_SR21 = &SiS300_SR21;
-   SiS_Pr->pSiS_SR22 = &SiS300_SR22;
-   SiS_Pr->pSiS_SR23 = &SiS300_SR23;
-   SiS_Pr->pSiS_SR24 = &SiS300_SR24;
-   SiS_Pr->SiS_SR25  = SiS300_SR25;
-   SiS_Pr->pSiS_SR31 = &SiS300_SR31;
-   SiS_Pr->pSiS_SR32 = &SiS300_SR32;
-   SiS_Pr->pSiS_SR33 = &SiS300_SR33;
-   SiS_Pr->pSiS_CRT2Data_1_2  = &SiS300_CRT2Data_1_2;
-   SiS_Pr->pSiS_CRT2Data_4_D  = &SiS300_CRT2Data_4_D;
-   SiS_Pr->pSiS_CRT2Data_4_E  = &SiS300_CRT2Data_4_E;
-   SiS_Pr->pSiS_CRT2Data_4_10 = &SiS300_CRT2Data_4_10;
-   SiS_Pr->pSiS_RGBSenseData    = &SiS300_RGBSenseData;
-   SiS_Pr->pSiS_VideoSenseData  = &SiS300_VideoSenseData;
-   SiS_Pr->pSiS_YCSenseData     = &SiS300_YCSenseData;
-   SiS_Pr->pSiS_RGBSenseData2   = &SiS300_RGBSenseData2;
-   SiS_Pr->pSiS_VideoSenseData2 = &SiS300_VideoSenseData2;
-   SiS_Pr->pSiS_YCSenseData2    = &SiS300_YCSenseData2;
-#endif
-
    SiS_Pr->SiS_PanelDelayTbl     = SiS300_PanelDelayTbl;
    SiS_Pr->SiS_PanelDelayTblLVDS = SiS300_PanelDelayTbl;
 
@@ -266,11 +189,8 @@ InitTo300Pointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
    SiS_Pr->SiS_St2LCD1280x1024Data  = SiS300_St2LCD1280x1024Data;
 
    SiS_Pr->SiS_CRT2Part2_1024x768_1  = SiS300_CRT2Part2_1024x768_1;
-   SiS_Pr->SiS_CRT2Part2_1280x1024_1 = SiS300_CRT2Part2_1280x1024_1;
    SiS_Pr->SiS_CRT2Part2_1024x768_2  = SiS300_CRT2Part2_1024x768_2;
-   SiS_Pr->SiS_CRT2Part2_1280x1024_2 = SiS300_CRT2Part2_1280x1024_2;
    SiS_Pr->SiS_CRT2Part2_1024x768_3  = SiS300_CRT2Part2_1024x768_3;
-   SiS_Pr->SiS_CRT2Part2_1280x1024_3 = SiS300_CRT2Part2_1280x1024_3;
 
    SiS_Pr->SiS_CHTVUPALData  = SiS300_CHTVUPALData;
    SiS_Pr->SiS_CHTVOPALData  = SiS300_CHTVOPALData;
@@ -280,64 +200,16 @@ InitTo300Pointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
    SiS_Pr->SiS_CHTVOPALNData = SiS300_CHTVOPALData;  /* not supported on 300 series */
    SiS_Pr->SiS_CHTVSOPALData = SiS300_CHTVSOPALData;
 
-   SiS_Pr->SiS_PanelType00_1 = SiS300_PanelType00_1;
-   SiS_Pr->SiS_PanelType01_1 = SiS300_PanelType01_1;
-   SiS_Pr->SiS_PanelType02_1 = SiS300_PanelType02_1;
-   SiS_Pr->SiS_PanelType03_1 = SiS300_PanelType03_1;
-   SiS_Pr->SiS_PanelType04_1 = SiS300_PanelType04_1;
-   SiS_Pr->SiS_PanelType05_1 = SiS300_PanelType05_1;
-   SiS_Pr->SiS_PanelType06_1 = SiS300_PanelType06_1;
-   SiS_Pr->SiS_PanelType07_1 = SiS300_PanelType07_1;
-   SiS_Pr->SiS_PanelType08_1 = SiS300_PanelType08_1;
-   SiS_Pr->SiS_PanelType09_1 = SiS300_PanelType09_1;
-   SiS_Pr->SiS_PanelType0a_1 = SiS300_PanelType0a_1;
-   SiS_Pr->SiS_PanelType0b_1 = SiS300_PanelType0b_1;
-   SiS_Pr->SiS_PanelType0c_1 = SiS300_PanelType0c_1;
-   SiS_Pr->SiS_PanelType0d_1 = SiS300_PanelType0d_1;
-   SiS_Pr->SiS_PanelType0e_1 = SiS300_PanelType0e_1;
-   SiS_Pr->SiS_PanelType0f_1 = SiS300_PanelType0f_1;
-   SiS_Pr->SiS_PanelType00_2 = SiS300_PanelType00_2;
-   SiS_Pr->SiS_PanelType01_2 = SiS300_PanelType01_2;
-   SiS_Pr->SiS_PanelType02_2 = SiS300_PanelType02_2;
-   SiS_Pr->SiS_PanelType03_2 = SiS300_PanelType03_2;
-   SiS_Pr->SiS_PanelType04_2 = SiS300_PanelType04_2;
-   SiS_Pr->SiS_PanelType05_2 = SiS300_PanelType05_2;
-   SiS_Pr->SiS_PanelType06_2 = SiS300_PanelType06_2;
-   SiS_Pr->SiS_PanelType07_2 = SiS300_PanelType07_2;
-   SiS_Pr->SiS_PanelType08_2 = SiS300_PanelType08_2;
-   SiS_Pr->SiS_PanelType09_2 = SiS300_PanelType09_2;
-   SiS_Pr->SiS_PanelType0a_2 = SiS300_PanelType0a_2;
-   SiS_Pr->SiS_PanelType0b_2 = SiS300_PanelType0b_2;
-   SiS_Pr->SiS_PanelType0c_2 = SiS300_PanelType0c_2;
-   SiS_Pr->SiS_PanelType0d_2 = SiS300_PanelType0d_2;
-   SiS_Pr->SiS_PanelType0e_2 = SiS300_PanelType0e_2;
-   SiS_Pr->SiS_PanelType0f_2 = SiS300_PanelType0f_2;
-   SiS_Pr->SiS_PanelTypeNS_1 = SiS300_PanelTypeNS_1;
-   SiS_Pr->SiS_PanelTypeNS_2 = SiS300_PanelTypeNS_2;
-
-   if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
-      SiS_Pr->SiS_PanelType04_1 = SiS300_PanelType04_1a;
-      SiS_Pr->SiS_PanelType04_2 = SiS300_PanelType04_2a;
-   }
-   if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
-      SiS_Pr->SiS_PanelType04_1 = SiS300_PanelType04_1b;
-      SiS_Pr->SiS_PanelType04_2 = SiS300_PanelType04_2b;
-   }
-
-   SiS_Pr->SiS_LVDSCRT1800x600_1     = SiS300_LVDSCRT1800x600_1;
-   SiS_Pr->SiS_LVDSCRT1800x600_1_H   = SiS300_LVDSCRT1800x600_1_H;
-   SiS_Pr->SiS_LVDSCRT1800x600_2     = SiS300_LVDSCRT1800x600_2;
-   SiS_Pr->SiS_LVDSCRT1800x600_2_H   = SiS300_LVDSCRT1800x600_2_H;
-   SiS_Pr->SiS_LVDSCRT11024x768_1    = SiS300_LVDSCRT11024x768_1;
-   SiS_Pr->SiS_LVDSCRT11024x768_1_H  = SiS300_LVDSCRT11024x768_1_H;
-   SiS_Pr->SiS_LVDSCRT11024x768_2    = SiS300_LVDSCRT11024x768_2;
-   SiS_Pr->SiS_LVDSCRT11024x768_2_H  = SiS300_LVDSCRT11024x768_2_H;
-   SiS_Pr->SiS_LVDSCRT11280x1024_1   = SiS300_LVDSCRT11280x1024_1;
-   SiS_Pr->SiS_LVDSCRT11280x1024_1_H = SiS300_LVDSCRT11280x1024_1_H;
-   SiS_Pr->SiS_LVDSCRT11280x1024_2   = SiS300_LVDSCRT11280x1024_2;
-   SiS_Pr->SiS_LVDSCRT11280x1024_2_H = SiS300_LVDSCRT11280x1024_2_H;
-   SiS_Pr->SiS_LVDSCRT1XXXxXXX_1     = SiS300_LVDSCRT1XXXxXXX_1;
-   SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H   = SiS300_LVDSCRT1XXXxXXX_1_H;
+   SiS_Pr->SiS_LVDS848x480Data_1   = SiS300_LVDS848x480Data_1;
+   SiS_Pr->SiS_LVDS848x480Data_2   = SiS300_LVDS848x480Data_2;
+   SiS_Pr->SiS_LVDSBARCO1024Data_1 = SiS300_LVDSBARCO1024Data_1;
+   SiS_Pr->SiS_LVDSBARCO1366Data_1 = SiS300_LVDSBARCO1366Data_1;
+   SiS_Pr->SiS_LVDSBARCO1366Data_2 = SiS300_LVDSBARCO1366Data_2;
+
+   SiS_Pr->SiS_PanelType04_1a = SiS300_PanelType04_1a;
+   SiS_Pr->SiS_PanelType04_2a = SiS300_PanelType04_2a;
+   SiS_Pr->SiS_PanelType04_1b = SiS300_PanelType04_1b;
+   SiS_Pr->SiS_PanelType04_2b = SiS300_PanelType04_2b;
 
    SiS_Pr->SiS_CHTVCRT1UNTSC = SiS300_CHTVCRT1UNTSC;
    SiS_Pr->SiS_CHTVCRT1ONTSC = SiS300_CHTVCRT1ONTSC;
@@ -367,64 +239,38 @@ InitTo300Pointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 
 #ifdef SIS315H
 static void
-InitTo310Pointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+InitTo310Pointer(struct SiS_Private *SiS_Pr)
 {
-   InitCommonPointer(SiS_Pr, HwInfo);
+   InitCommonPointer(SiS_Pr);
 
-   SiS_Pr->SiS_SModeIDTable  = SiS310_SModeIDTable;
    SiS_Pr->SiS_EModeIDTable  = SiS310_EModeIDTable;
-   SiS_Pr->SiS_RefIndex      = (SiS_Ext2Struct *)SiS310_RefIndex;
+   SiS_Pr->SiS_RefIndex      = SiS310_RefIndex;
    SiS_Pr->SiS_CRT1Table     = SiS310_CRT1Table;
-   if(HwInfo->jChipType >= SIS_340) {
-      SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_340;  /* 340 */
-   } else if(HwInfo->jChipType >= SIS_761) {
+   if(SiS_Pr->ChipType >= SIS_340) {
+      SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_340;  /* 340 + XGI */
+   } else if(SiS_Pr->ChipType >= SIS_761) {
       SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_761;  /* 761 - preliminary */
-   } else if(HwInfo->jChipType >= SIS_760) {
+   } else if(SiS_Pr->ChipType >= SIS_760) {
       SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_760;  /* 760 */
-   } else if(HwInfo->jChipType >= SIS_661) {
+   } else if(SiS_Pr->ChipType >= SIS_661) {
       SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_660;  /* 661/741 */
-   } else if(HwInfo->jChipType == SIS_330) {
+   } else if(SiS_Pr->ChipType == SIS_330) {
       SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_330;  /* 330 */
-   } else if(HwInfo->jChipType > SIS_315PRO) {
+   } else if(SiS_Pr->ChipType > SIS_315PRO) {
       SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_650;  /* 550, 650, 740 */
    } else {
       SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_315;  /* 315 */
    }
-   if(HwInfo->jChipType >= SIS_340) {
-      SiS_Pr->SiS_MCLKData_1    = SiS310_MCLKData_1_340;
+   if(SiS_Pr->ChipType >= SIS_340) {
+      SiS_Pr->SiS_MCLKData_1 = SiS310_MCLKData_1_340;
    } else {
-      SiS_Pr->SiS_MCLKData_1    = SiS310_MCLKData_1;
+      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;
 
-#ifdef LINUX_KERNEL
-   SiS_Pr->pSiS_SR07 = &SiS310_SR07;
-   SiS_Pr->SiS_CR40  = SiS310_CR40;
-   SiS_Pr->SiS_CR49  = SiS310_CR49;
-   SiS_Pr->pSiS_SR1F = &SiS310_SR1F;
-   SiS_Pr->pSiS_SR21 = &SiS310_SR21;
-   SiS_Pr->pSiS_SR22 = &SiS310_SR22;
-   SiS_Pr->pSiS_SR23 = &SiS310_SR23;
-   SiS_Pr->pSiS_SR24 = &SiS310_SR24;
-   SiS_Pr->SiS_SR25  = SiS310_SR25;
-   SiS_Pr->pSiS_SR31 = &SiS310_SR31;
-   SiS_Pr->pSiS_SR32 = &SiS310_SR32;
-   SiS_Pr->pSiS_SR33 = &SiS310_SR33;
-   SiS_Pr->pSiS_CRT2Data_1_2  = &SiS310_CRT2Data_1_2;
-   SiS_Pr->pSiS_CRT2Data_4_D  = &SiS310_CRT2Data_4_D;
-   SiS_Pr->pSiS_CRT2Data_4_E  = &SiS310_CRT2Data_4_E;
-   SiS_Pr->pSiS_CRT2Data_4_10 = &SiS310_CRT2Data_4_10;
-   SiS_Pr->pSiS_RGBSenseData    = &SiS310_RGBSenseData;
-   SiS_Pr->pSiS_VideoSenseData  = &SiS310_VideoSenseData;
-   SiS_Pr->pSiS_YCSenseData     = &SiS310_YCSenseData;
-   SiS_Pr->pSiS_RGBSenseData2   = &SiS310_RGBSenseData2;
-   SiS_Pr->pSiS_VideoSenseData2 = &SiS310_VideoSenseData2;
-   SiS_Pr->pSiS_YCSenseData2    = &SiS310_YCSenseData2;
-#endif
-
    SiS_Pr->SiS_PanelDelayTbl     = SiS310_PanelDelayTbl;
    SiS_Pr->SiS_PanelDelayTblLVDS = SiS310_PanelDelayTblLVDS;
 
@@ -435,41 +281,6 @@ InitTo310Pointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 
    SiS_Pr->SiS_CRT2Part2_1024x768_1  = SiS310_CRT2Part2_1024x768_1;
 
-   SiS_Pr->SiS_PanelType00_1 = SiS310_PanelType00_1;
-   SiS_Pr->SiS_PanelType01_1 = SiS310_PanelType01_1;
-   SiS_Pr->SiS_PanelType02_1 = SiS310_PanelType02_1;
-   SiS_Pr->SiS_PanelType03_1 = SiS310_PanelType03_1;
-   SiS_Pr->SiS_PanelType04_1 = SiS310_PanelType04_1;
-   SiS_Pr->SiS_PanelType05_1 = SiS310_PanelType05_1;
-   SiS_Pr->SiS_PanelType06_1 = SiS310_PanelType06_1;
-   SiS_Pr->SiS_PanelType07_1 = SiS310_PanelType07_1;
-   SiS_Pr->SiS_PanelType08_1 = SiS310_PanelType08_1;
-   SiS_Pr->SiS_PanelType09_1 = SiS310_PanelType09_1;
-   SiS_Pr->SiS_PanelType0a_1 = SiS310_PanelType0a_1;
-   SiS_Pr->SiS_PanelType0b_1 = SiS310_PanelType0b_1;
-   SiS_Pr->SiS_PanelType0c_1 = SiS310_PanelType0c_1;
-   SiS_Pr->SiS_PanelType0d_1 = SiS310_PanelType0d_1;
-   SiS_Pr->SiS_PanelType0e_1 = SiS310_PanelType0e_1;
-   SiS_Pr->SiS_PanelType0f_1 = SiS310_PanelType0f_1;
-   SiS_Pr->SiS_PanelType00_2 = SiS310_PanelType00_2;
-   SiS_Pr->SiS_PanelType01_2 = SiS310_PanelType01_2;
-   SiS_Pr->SiS_PanelType02_2 = SiS310_PanelType02_2;
-   SiS_Pr->SiS_PanelType03_2 = SiS310_PanelType03_2;
-   SiS_Pr->SiS_PanelType04_2 = SiS310_PanelType04_2;
-   SiS_Pr->SiS_PanelType05_2 = SiS310_PanelType05_2;
-   SiS_Pr->SiS_PanelType06_2 = SiS310_PanelType06_2;
-   SiS_Pr->SiS_PanelType07_2 = SiS310_PanelType07_2;
-   SiS_Pr->SiS_PanelType08_2 = SiS310_PanelType08_2;
-   SiS_Pr->SiS_PanelType09_2 = SiS310_PanelType09_2;
-   SiS_Pr->SiS_PanelType0a_2 = SiS310_PanelType0a_2;
-   SiS_Pr->SiS_PanelType0b_2 = SiS310_PanelType0b_2;
-   SiS_Pr->SiS_PanelType0c_2 = SiS310_PanelType0c_2;
-   SiS_Pr->SiS_PanelType0d_2 = SiS310_PanelType0d_2;
-   SiS_Pr->SiS_PanelType0e_2 = SiS310_PanelType0e_2;
-   SiS_Pr->SiS_PanelType0f_2 = SiS310_PanelType0f_2;
-   SiS_Pr->SiS_PanelTypeNS_1 = SiS310_PanelTypeNS_1;
-   SiS_Pr->SiS_PanelTypeNS_2 = SiS310_PanelTypeNS_2;
-
    SiS_Pr->SiS_CHTVUPALData  = SiS310_CHTVUPALData;
    SiS_Pr->SiS_CHTVOPALData  = SiS310_CHTVOPALData;
    SiS_Pr->SiS_CHTVUPALMData = SiS310_CHTVUPALMData;
@@ -478,33 +289,11 @@ InitTo310Pointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
    SiS_Pr->SiS_CHTVOPALNData = SiS310_CHTVOPALNData;
    SiS_Pr->SiS_CHTVSOPALData = SiS310_CHTVSOPALData;
 
-   SiS_Pr->SiS_LVDSCRT1800x600_1     = SiS310_LVDSCRT1800x600_1;
-   SiS_Pr->SiS_LVDSCRT11024x768_1    = SiS310_LVDSCRT11024x768_1;
-   SiS_Pr->SiS_LVDSCRT11280x1024_1   = SiS310_LVDSCRT11280x1024_1;
-   SiS_Pr->SiS_LVDSCRT11400x1050_1   = SiS310_LVDSCRT11400x1050_1;
-   SiS_Pr->SiS_LVDSCRT11600x1200_1   = SiS310_LVDSCRT11600x1200_1;
-   SiS_Pr->SiS_LVDSCRT1800x600_1_H   = SiS310_LVDSCRT1800x600_1_H;
-   SiS_Pr->SiS_LVDSCRT11024x768_1_H  = SiS310_LVDSCRT11024x768_1_H;
-   SiS_Pr->SiS_LVDSCRT11280x1024_1_H = SiS310_LVDSCRT11280x1024_1_H;
-   SiS_Pr->SiS_LVDSCRT11400x1050_1_H = SiS310_LVDSCRT11400x1050_1_H;
-   SiS_Pr->SiS_LVDSCRT11600x1200_1_H = SiS310_LVDSCRT11600x1200_1_H;
-   SiS_Pr->SiS_LVDSCRT1800x600_2     = SiS310_LVDSCRT1800x600_2;
-   SiS_Pr->SiS_LVDSCRT11024x768_2    = SiS310_LVDSCRT11024x768_2;
-   SiS_Pr->SiS_LVDSCRT11280x1024_2   = SiS310_LVDSCRT11280x1024_2;
-   SiS_Pr->SiS_LVDSCRT11400x1050_2   = SiS310_LVDSCRT11400x1050_2;
-   SiS_Pr->SiS_LVDSCRT11600x1200_2   = SiS310_LVDSCRT11600x1200_2;
-   SiS_Pr->SiS_LVDSCRT1800x600_2_H   = SiS310_LVDSCRT1800x600_2_H;
-   SiS_Pr->SiS_LVDSCRT11024x768_2_H  = SiS310_LVDSCRT11024x768_2_H;
-   SiS_Pr->SiS_LVDSCRT11280x1024_2_H = SiS310_LVDSCRT11280x1024_2_H;
-   SiS_Pr->SiS_LVDSCRT11400x1050_2_H = SiS310_LVDSCRT11400x1050_2_H;
-   SiS_Pr->SiS_LVDSCRT11600x1200_2_H = SiS310_LVDSCRT11600x1200_2_H;
-   SiS_Pr->SiS_LVDSCRT1XXXxXXX_1     = SiS310_LVDSCRT1XXXxXXX_1;
-   SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H   = SiS310_LVDSCRT1XXXxXXX_1_H;
-   SiS_Pr->SiS_CHTVCRT1UNTSC         = SiS310_CHTVCRT1UNTSC;
-   SiS_Pr->SiS_CHTVCRT1ONTSC         = SiS310_CHTVCRT1ONTSC;
-   SiS_Pr->SiS_CHTVCRT1UPAL          = SiS310_CHTVCRT1UPAL;
-   SiS_Pr->SiS_CHTVCRT1OPAL          = SiS310_CHTVCRT1OPAL;
-   SiS_Pr->SiS_CHTVCRT1SOPAL         = SiS310_CHTVCRT1OPAL;
+   SiS_Pr->SiS_CHTVCRT1UNTSC = SiS310_CHTVCRT1UNTSC;
+   SiS_Pr->SiS_CHTVCRT1ONTSC = SiS310_CHTVCRT1ONTSC;
+   SiS_Pr->SiS_CHTVCRT1UPAL  = SiS310_CHTVCRT1UPAL;
+   SiS_Pr->SiS_CHTVCRT1OPAL  = SiS310_CHTVCRT1OPAL;
+   SiS_Pr->SiS_CHTVCRT1SOPAL = SiS310_CHTVCRT1OPAL;
 
    SiS_Pr->SiS_CHTVReg_UNTSC = SiS310_CHTVReg_UNTSC;
    SiS_Pr->SiS_CHTVReg_ONTSC = SiS310_CHTVReg_ONTSC;
@@ -528,208 +317,203 @@ InitTo310Pointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 }
 #endif
 
-static void
-SiSInitPtr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+BOOLEAN
+SiSInitPtr(struct SiS_Private *SiS_Pr)
 {
-   switch(HwInfo->jChipType) {
-#ifdef SIS315H
-   case SIS_315H:
-   case SIS_315:
-   case SIS_315PRO:
-   case SIS_550:
-   case SIS_650:
-   case SIS_740:
-   case SIS_330:
-   case SIS_661:
-   case SIS_741:
-   case SIS_660:
-   case SIS_760:
-   case SIS_761:
-   case SIS_340:
-      InitTo310Pointer(SiS_Pr, HwInfo);
-      break;
-#endif
+   if(SiS_Pr->ChipType < SIS_315H) {
 #ifdef SIS300
-   case SIS_300:
-   case SIS_540:
-   case SIS_630:
-   case SIS_730:
-      InitTo300Pointer(SiS_Pr, HwInfo);
-      break;
+      InitTo300Pointer(SiS_Pr);
+#else
+      return FALSE;
+#endif
+   } else {
+#ifdef SIS315H
+      InitTo310Pointer(SiS_Pr);
+#else
+      return FALSE;
 #endif
-   default:
-      break;
    }
+   return TRUE;
 }
 
 /*********************************************/
 /*            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)
+#ifndef SIS_XORG_XF86
+static
+#endif
+unsigned short
+SiS_GetModeID(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay,
+               int Depth, BOOLEAN FSTN, int LCDwidth, int LCDheight)
 {
-   USHORT ModeIndex = 0;
+   unsigned short ModeIndex = 0;
 
    switch(HDisplay)
    {
-     case 320:
-         if(VDisplay == 200)     ModeIndex = ModeIndex_320x200[Depth];
-         else if(VDisplay == 240) {
-            if(FSTN) ModeIndex = ModeIndex_320x240_FSTN[Depth];
-            else     ModeIndex = ModeIndex_320x240[Depth];
-          }
-          break;
-     case 400:
-          if((!(VBFlags & CRT1_LCDA)) || ((LCDwidth >= 800) && (LCDwidth >= 600))) {
-             if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
-         }
-          break;
-     case 512:
-          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];
-         else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth];
-          break;
-     case 720:
-          if(VDisplay == 480)      ModeIndex = ModeIndex_720x480[Depth];
-          else if(VDisplay == 576) ModeIndex = ModeIndex_720x576[Depth];
-          break;
-     case 768:
-          if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
-         break;
-     case 800:
-         if(VDisplay == 600)      ModeIndex = ModeIndex_800x600[Depth];
-         else if(VDisplay == 480) ModeIndex = ModeIndex_800x480[Depth];
-          break;
-     case 848:
-         if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth];
-         break;
-     case 856:
-         if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth];
-         break;
-     case 960:
-         if(VGAEngine == SIS_315_VGA) {
-            if(VDisplay == 540)      ModeIndex = ModeIndex_960x540[Depth];
-            else if(VDisplay == 600) ModeIndex = ModeIndex_960x600[Depth];
-         }
-         break;
-     case 1024:
-          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(VGAEngine == SIS_300_VGA) {
-            if(VDisplay == 768) ModeIndex = ModeIndex_1152x768[Depth];
-         }
-         break;
-     case 1280:
-          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];
-            }
-            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(VGAEngine == SIS_300_VGA) {
-            if(VDisplay == 1024) ModeIndex = ModeIndex_300_1360x1024[Depth];
-          }
-          break;
-     case 1400:
-          if(VGAEngine == SIS_315_VGA) {
-            if(VDisplay == 1050) {
-               ModeIndex = ModeIndex_1400x1050[Depth];
-            }
-         }
-          break;
-     case 1600:
-          if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
-          break;
-     case 1680:
-          if(VGAEngine == SIS_315_VGA) {
-             if(VDisplay == 1050) ModeIndex = ModeIndex_1680x1050[Depth];
-         }
-          break;
-     case 1920:
-          if(VDisplay == 1440)    ModeIndex = ModeIndex_1920x1440[Depth];
-         else if(VGAEngine == SIS_315_VGA) {
-            if(VDisplay == 1080) ModeIndex = ModeIndex_1920x1080[Depth];
-         }
-          break;
-     case 2048:
-          if(VDisplay == 1536) {
-             if(VGAEngine == SIS_300_VGA) {
-                ModeIndex = ModeIndex_300_2048x1536[Depth];
-            } else {
-                ModeIndex = ModeIndex_310_2048x1536[Depth];
-             }
-         }
-          break;
+       case 320:
+               if(VDisplay == 200) ModeIndex = ModeIndex_320x200[Depth];
+               else if(VDisplay == 240) {
+                       if((VBFlags & CRT2_LCD) && (FSTN))
+                               ModeIndex = ModeIndex_320x240_FSTN[Depth];
+                       else
+                               ModeIndex = ModeIndex_320x240[Depth];
+               }
+               break;
+       case 400:
+               if((!(VBFlags & CRT1_LCDA)) || ((LCDwidth >= 800) && (LCDwidth >= 600))) {
+                       if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
+               }
+               break;
+       case 512:
+               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];
+               else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth];
+               break;
+       case 720:
+               if(VDisplay == 480)      ModeIndex = ModeIndex_720x480[Depth];
+               else if(VDisplay == 576) ModeIndex = ModeIndex_720x576[Depth];
+               break;
+       case 768:
+               if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
+               break;
+       case 800:
+               if(VDisplay == 600)      ModeIndex = ModeIndex_800x600[Depth];
+               else if(VDisplay == 480) ModeIndex = ModeIndex_800x480[Depth];
+               break;
+       case 848:
+               if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth];
+               break;
+       case 856:
+               if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth];
+               break;
+       case 960:
+               if(VGAEngine == SIS_315_VGA) {
+                       if(VDisplay == 540)      ModeIndex = ModeIndex_960x540[Depth];
+                       else if(VDisplay == 600) ModeIndex = ModeIndex_960x600[Depth];
+               }
+               break;
+       case 1024:
+               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(VGAEngine == SIS_300_VGA) {
+                       if(VDisplay == 768) ModeIndex = ModeIndex_1152x768[Depth];
+               }
+               break;
+       case 1280:
+               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];
+                               }
+                               break;
+                       case 800:
+                               if(VGAEngine == SIS_315_VGA) {
+                                       ModeIndex = ModeIndex_1280x800[Depth];
+                               }
+                               break;
+                       case 854:
+                               if(VGAEngine == SIS_315_VGA) {
+                                       ModeIndex = ModeIndex_1280x854[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(VGAEngine == SIS_300_VGA) {
+                       if(VDisplay == 1024) ModeIndex = ModeIndex_300_1360x1024[Depth];
+               }
+               break;
+       case 1400:
+               if(VGAEngine == SIS_315_VGA) {
+                       if(VDisplay == 1050) {
+                               ModeIndex = ModeIndex_1400x1050[Depth];
+                       }
+               }
+               break;
+       case 1600:
+               if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
+               break;
+       case 1680:
+               if(VGAEngine == SIS_315_VGA) {
+                       if(VDisplay == 1050) ModeIndex = ModeIndex_1680x1050[Depth];
+               }
+               break;
+       case 1920:
+               if(VDisplay == 1440) ModeIndex = ModeIndex_1920x1440[Depth];
+               else if(VGAEngine == SIS_315_VGA) {
+                       if(VDisplay == 1080) ModeIndex = ModeIndex_1920x1080[Depth];
+               }
+               break;
+       case 2048:
+               if(VDisplay == 1536) {
+                       if(VGAEngine == SIS_300_VGA) {
+                               ModeIndex = ModeIndex_300_2048x1536[Depth];
+                       } else {
+                               ModeIndex = ModeIndex_310_2048x1536[Depth];
+                       }
+               }
+               break;
    }
 
-   return(ModeIndex);
+   return ModeIndex;
 }
-#endif
 
-USHORT
-SiS_GetModeID_LCD(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay,
-                  int Depth, BOOLEAN FSTN, USHORT CustomT, int LCDwidth, int LCDheight)
+unsigned short
+SiS_GetModeID_LCD(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay,
+               int Depth, BOOLEAN FSTN, unsigned short CustomT, int LCDwidth, int LCDheight,
+               unsigned int VBFlags2)
 {
-   USHORT ModeIndex = 0;
+   unsigned short ModeIndex = 0;
 
-   if(VBFlags & (VB_LVDS | VB_30xBDH)) {
+   if(VBFlags2 & (VB2_LVDS | VB2_30xBDH)) {
 
       switch(HDisplay)
       {
        case 320:
-            if(CustomT != CUT_PANEL848) {
-               if(VDisplay == 200) ModeIndex = ModeIndex_320x200[Depth];
-               else if(VDisplay == 240) {
+            if((CustomT != CUT_PANEL848) && (CustomT != CUT_PANEL856)) {
+               if(VDisplay == 200) {
+                  if(!FSTN) ModeIndex = ModeIndex_320x200[Depth];
+               } else if(VDisplay == 240) {
                   if(!FSTN) ModeIndex = ModeIndex_320x240[Depth];
-                  else if(VGAEngine == SIS_315_VGA) {
-                      ModeIndex = ModeIndex_320x240_FSTN[Depth];
+                  else if(VGAEngine == SIS_315_VGA) {
+                     ModeIndex = ModeIndex_320x240_FSTN[Depth];
                   }
                }
             }
-             break;
-       case 400:
-            if(CustomT != CUT_PANEL848) {
-               if(!((VGAEngine == SIS_300_VGA) && (VBFlags & VB_TRUMPION))) {
-                  if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
+            break;
+       case 400:
+            if((CustomT != CUT_PANEL848) && (CustomT != CUT_PANEL856)) {
+               if(!((VGAEngine == SIS_300_VGA) && (VBFlags2 & VB2_TRUMPION))) {
+                  if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
                }
             }
-             break;
+            break;
        case 512:
-            if(CustomT != CUT_PANEL848) {
-               if(!((VGAEngine == SIS_300_VGA) && (VBFlags & VB_TRUMPION))) {
+            if((CustomT != CUT_PANEL848) && (CustomT != CUT_PANEL856)) {
+               if(!((VGAEngine == SIS_300_VGA) && (VBFlags2 & VB2_TRUMPION))) {
                   if(LCDwidth >= 1024 && LCDwidth != 1152 && LCDheight >= 768) {
                      if(VDisplay == 384) {
                         ModeIndex = ModeIndex_512x384[Depth];
@@ -739,9 +523,10 @@ SiS_GetModeID_LCD(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay,
             }
             break;
        case 640:
-            if(VDisplay == 480)            ModeIndex = ModeIndex_640x480[Depth];
+            if(VDisplay == 480) ModeIndex = ModeIndex_640x480[Depth];
             else if(VDisplay == 400) {
-               if(CustomT != CUT_PANEL848) ModeIndex = ModeIndex_640x400[Depth];
+               if((CustomT != CUT_PANEL848) && (CustomT != CUT_PANEL856))
+                  ModeIndex = ModeIndex_640x400[Depth];
             }
             break;
        case 800:
@@ -752,6 +537,11 @@ SiS_GetModeID_LCD(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay,
                if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth];
             }
             break;
+       case 856:
+            if(CustomT == CUT_PANEL856) {
+               if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth];
+            }
+            break;
        case 1024:
             if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
             else if(VGAEngine == SIS_300_VGA) {
@@ -762,7 +552,7 @@ SiS_GetModeID_LCD(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay,
             break;
        case 1152:
             if(VGAEngine == SIS_300_VGA) {
-               if((VDisplay == 768) && (LCDheight == 768)) {
+               if((VDisplay == 768) && (LCDheight == 768)) {
                   ModeIndex = ModeIndex_1152x768[Depth];
                }
             }
@@ -770,49 +560,49 @@ SiS_GetModeID_LCD(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay,
         case 1280:
             if(VDisplay == 1024) ModeIndex = ModeIndex_1280x1024[Depth];
             else if(VGAEngine == SIS_315_VGA) {
-               if((VDisplay == 768) && (LCDheight == 768)) {
+               if((VDisplay == 768) && (LCDheight == 768)) {
                   ModeIndex = ModeIndex_310_1280x768[Depth];
                }
             }
             break;
        case 1360:
             if(VGAEngine == SIS_300_VGA) {
-               if(CustomT == CUT_BARCO1366) {
+               if(CustomT == CUT_BARCO1366) {
                   if(VDisplay == 1024) ModeIndex = ModeIndex_300_1360x1024[Depth];
                }
             }
             if(CustomT == CUT_PANEL848) {
-               if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth];
+               if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth];
             }
             break;
        case 1400:
             if(VGAEngine == SIS_315_VGA) {
-               if(VDisplay == 1050) ModeIndex = ModeIndex_1400x1050[Depth];
+               if(VDisplay == 1050) ModeIndex = ModeIndex_1400x1050[Depth];
             }
             break;
        case 1600:
             if(VGAEngine == SIS_315_VGA) {
-               if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
+               if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
             }
             break;
       }
 
-   } else if(VBFlags & VB_SISBRIDGE) {
+   } else if(VBFlags2 & VB2_SISBRIDGE) {
 
       switch(HDisplay)
       {
        case 320:
-            if(VDisplay == 200)      ModeIndex = ModeIndex_320x200[Depth];
+            if(VDisplay == 200)      ModeIndex = ModeIndex_320x200[Depth];
             else if(VDisplay == 240) ModeIndex = ModeIndex_320x240[Depth];
-             break;
-       case 400:
+            break;
+       case 400:
             if(LCDwidth >= 800 && LCDheight >= 600) {
-                if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
+               if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
             }
-             break;
+            break;
        case 512:
             if(LCDwidth >= 1024 && LCDheight >= 768 && LCDwidth != 1152) {
-               if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
+               if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
             }
             break;
        case 640:
@@ -821,96 +611,115 @@ SiS_GetModeID_LCD(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay,
             break;
        case 720:
             if(VGAEngine == SIS_315_VGA) {
-               if(VDisplay == 480)      ModeIndex = ModeIndex_720x480[Depth];
+               if(VDisplay == 480)      ModeIndex = ModeIndex_720x480[Depth];
                else if(VDisplay == 576) ModeIndex = ModeIndex_720x576[Depth];
             }
             break;
        case 768:
             if(VGAEngine == SIS_315_VGA) {
-               if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
+               if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
             }
             break;
        case 800:
             if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
             if(VGAEngine == SIS_315_VGA) {
-               if(VDisplay == 480) ModeIndex = ModeIndex_800x480[Depth];
+               if(VDisplay == 480) ModeIndex = ModeIndex_800x480[Depth];
             }
             break;
        case 848:
             if(VGAEngine == SIS_315_VGA) {
-               if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth];
+               if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth];
             }
             break;
        case 856:
             if(VGAEngine == SIS_315_VGA) {
-               if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth];
+               if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth];
             }
             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];
             if(VGAEngine == SIS_315_VGA) {
-               if(VDisplay == 576) ModeIndex = ModeIndex_1024x576[Depth];
+               if(VDisplay == 576) ModeIndex = ModeIndex_1024x576[Depth];
             }
             break;
        case 1152:
             if(VGAEngine == SIS_315_VGA) {
-               if(VDisplay == 864) ModeIndex = ModeIndex_1152x864[Depth];
+               if(VDisplay == 864) ModeIndex = ModeIndex_1152x864[Depth];
             }
             break;
        case 1280:
             switch(VDisplay) {
             case 720:
-               ModeIndex = ModeIndex_1280x720[Depth];
+               ModeIndex = ModeIndex_1280x720[Depth];
             case 768:
-               if(VGAEngine == SIS_300_VGA) {
+               if(VGAEngine == SIS_300_VGA) {
                   ModeIndex = ModeIndex_300_1280x768[Depth];
                } else {
                   ModeIndex = ModeIndex_310_1280x768[Depth];
                }
                break;
             case 800:
-               if(VGAEngine == SIS_315_VGA) {
+               if(VGAEngine == SIS_315_VGA) {
                   ModeIndex = ModeIndex_1280x800[Depth];
                }
                break;
+            case 854:
+               if(VGAEngine == SIS_315_VGA) {
+                  ModeIndex = ModeIndex_1280x854[Depth];
+               }
+               break;
             case 960:
-               ModeIndex = ModeIndex_1280x960[Depth];
+               ModeIndex = ModeIndex_1280x960[Depth];
                break;
             case 1024:
-               ModeIndex = ModeIndex_1280x1024[Depth];
+               ModeIndex = ModeIndex_1280x1024[Depth];
                break;
             }
             break;
        case 1360:
-            if(VGAEngine == SIS_315_VGA) {
-               if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth];
+            if(VGAEngine == SIS_315_VGA) {  /* OVER1280 only? */
+               if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth];
             }
             break;
        case 1400:
             if(VGAEngine == SIS_315_VGA) {
-               if(VBFlags & (VB_301C | VB_302LV | VB_302ELV)) {
+               if(VBFlags2 & VB2_LCDOVER1280BRIDGE) {
                   if(VDisplay == 1050) ModeIndex = ModeIndex_1400x1050[Depth];
                }
             }
             break;
        case 1600:
             if(VGAEngine == SIS_315_VGA) {
-               if(VBFlags & (VB_301C | VB_302LV | VB_302ELV)) {
-                  if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
+               if(VBFlags2 & VB2_LCDOVER1280BRIDGE) {
+                  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_302LV | VB_302ELV)) {
-                  if(VDisplay == 1050) ModeIndex = ModeIndex_1680x1050[Depth];
+               if(VBFlags2 & VB2_LCDOVER1280BRIDGE) {
+                  if(VDisplay == 1050) ModeIndex = ModeIndex_1680x1050[Depth];
+               }
+            }
+            break;
+       case 1920:
+            if(VGAEngine == SIS_315_VGA) {
+               if(VBFlags2 & VB2_LCDOVER1600BRIDGE) {
+                  if(VDisplay == 1440) ModeIndex = ModeIndex_1920x1440[Depth];
+               }
+            }
+            break;
+       case 2048:
+            if(VGAEngine == SIS_315_VGA) {
+               if(VBFlags2 & VB2_LCDOVER1600BRIDGE) {
+                  if(VDisplay == 1536) ModeIndex = ModeIndex_310_2048x1536[Depth];
                }
             }
             break;
@@ -921,16 +730,17 @@ SiS_GetModeID_LCD(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay,
    return ModeIndex;
 }
 
-USHORT
-SiS_GetModeID_TV(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth)
+unsigned short
+SiS_GetModeID_TV(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay, int Depth,
+                       unsigned int VBFlags2)
 {
-   USHORT ModeIndex = 0;
+   unsigned short ModeIndex = 0;
 
-   if(VBFlags & VB_CHRONTEL) {
+   if(VBFlags2 & VB2_CHRONTEL) {
 
       switch(HDisplay)
       {
-       case 512:
+       case 512:
             if(VGAEngine == SIS_315_VGA) {
                if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
             }
@@ -944,27 +754,27 @@ SiS_GetModeID_TV(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int D
             break;
        case 1024:
             if(VGAEngine == SIS_315_VGA) {
-               if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
+               if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
             }
             break;
       }
 
-   } else if(VBFlags & VB_SISTVBRIDGE) {
+   } else if(VBFlags2 & VB2_SISTVBRIDGE) {
 
       switch(HDisplay)
       {
        case 320:
-            if(VDisplay == 200)      ModeIndex = ModeIndex_320x200[Depth];
+            if(VDisplay == 200)      ModeIndex = ModeIndex_320x200[Depth];
             else if(VDisplay == 240) ModeIndex = ModeIndex_320x240[Depth];
-             break;
-        case 400:
-             if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
-             break;
-       case 512:
+            break;
+       case 400:
+            if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
+            break;
+       case 512:
             if( ((VBFlags & TV_YPBPR) && (VBFlags & (TV_YPBPR750P | TV_YPBPR1080I))) ||
-                (VBFlags & TV_HIVISION)                                              ||
-                ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL)) ) {
-               if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
+                (VBFlags & TV_HIVISION)                                              ||
+                ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL)) ) {
+               if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
             }
             break;
        case 640:
@@ -973,34 +783,34 @@ SiS_GetModeID_TV(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int D
             break;
        case 720:
             if((!(VBFlags & TV_HIVISION)) && (!((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I)))) {
-                if(VDisplay == 480) {
-                   ModeIndex = ModeIndex_720x480[Depth];
-                } else if(VDisplay == 576) {
+               if(VDisplay == 480) {
+                  ModeIndex = ModeIndex_720x480[Depth];
+               } else if(VDisplay == 576) {
                   if( ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR750P)) ||
                       ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL)) )
-                      ModeIndex = ModeIndex_720x576[Depth];
-                }
+                     ModeIndex = ModeIndex_720x576[Depth];
+               }
             }
              break;
        case 768:
             if((!(VBFlags & TV_HIVISION)) && (!((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I)))) {
-               if( ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR750P)) ||
+               if( ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR750P)) ||
                    ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL)) ) {
-                  if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
+                  if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
                }
              }
             break;
        case 800:
             if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
             else if(VDisplay == 480) {
-               if((VBFlags & TV_HIVISION) || ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I))) {
+               if(!((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR750P))) {
                   ModeIndex = ModeIndex_800x480[Depth];
                }
             }
             break;
        case 960:
             if(VGAEngine == SIS_315_VGA) {
-               if(VDisplay == 600) {
+               if(VDisplay == 600) {
                   if((VBFlags & TV_HIVISION) || ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I))) {
                      ModeIndex = ModeIndex_960x600[Depth];
                   }
@@ -1009,25 +819,28 @@ SiS_GetModeID_TV(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int D
             break;
        case 1024:
             if(VDisplay == 768) {
-               if(VBFlags & (VB_301B|VB_301C|VB_302B|VB_301LV|VB_302LV|VB_302ELV)) {
+               if(VBFlags2 & VB2_30xBLV) {
                   ModeIndex = ModeIndex_1024x768[Depth];
                }
             } else if(VDisplay == 576) {
-               if((VBFlags & TV_HIVISION) || ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I))) {
+               if( (VBFlags & TV_HIVISION) ||
+                   ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I)) ||
+                   ((VBFlags2 & VB2_30xBLV) &&
+                    ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL))) ) {
                   ModeIndex = ModeIndex_1024x576[Depth];
                }
             }
             break;
        case 1280:
             if(VDisplay == 720) {
-               if((VBFlags & TV_HIVISION) ||
+               if((VBFlags & TV_HIVISION) ||
                   ((VBFlags & TV_YPBPR) && (VBFlags & (TV_YPBPR1080I | TV_YPBPR750P)))) {
-                  ModeIndex = ModeIndex_1280x720[Depth];
+                  ModeIndex = ModeIndex_1280x720[Depth];
                }
             } else if(VDisplay == 1024) {
-               if((VBFlags & TV_HIVISION) ||
+               if((VBFlags & TV_HIVISION) ||
                   ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I))) {
-                  ModeIndex = ModeIndex_1280x1024[Depth];
+                  ModeIndex = ModeIndex_1280x1024[Depth];
                }
             }
             break;
@@ -1036,99 +849,31 @@ SiS_GetModeID_TV(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int D
    return ModeIndex;
 }
 
-USHORT
-SiS_GetModeID_VGA2(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth)
+unsigned short
+SiS_GetModeID_VGA2(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay, int Depth,
+                       unsigned int VBFlags2)
 {
-   USHORT ModeIndex = 0;
+   if(!(VBFlags2 & VB2_SISVGA2BRIDGE)) return 0;
 
-   if(!(VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) return 0;
+   if(HDisplay >= 1920) return 0;
 
    switch(HDisplay)
    {
-       case 320:
-               if(VDisplay == 200)      ModeIndex = ModeIndex_320x200[Depth];
-               else if(VDisplay == 240) ModeIndex = ModeIndex_320x240[Depth];
-               break;
-       case 400:
-               if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
-               break;
-       case 512:
-               if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
-               break;
-       case 640:
-               if(VDisplay == 480)      ModeIndex = ModeIndex_640x480[Depth];
-               else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth];
-               break;
-       case 720:
-               if(VDisplay == 480)      ModeIndex = ModeIndex_720x480[Depth];
-               else if(VDisplay == 576) ModeIndex = ModeIndex_720x576[Depth];
-               break;
-       case 768:
-               if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
-               break;
-       case 800:
-               if(VDisplay == 600)      ModeIndex = ModeIndex_800x600[Depth];
-               else if(VDisplay == 480) ModeIndex = ModeIndex_800x480[Depth];
-               break;
-       case 848:
-               if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth];
-               break;
-       case 856:
-               if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth];
-               break;
-       case 960:
-               if(VGAEngine == SIS_315_VGA) {
-                  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];
-               break;
-       case 1152:
-               if(VDisplay == 864)    ModeIndex = ModeIndex_1152x864[Depth];
-               else if(VGAEngine == SIS_300_VGA) {
-                  if(VDisplay == 768) ModeIndex = ModeIndex_1152x768[Depth];
-               }
-               break;
-       case 1280:
-               if(VDisplay == 768) {
-                  if(VGAEngine == SIS_300_VGA) {
-                     ModeIndex = ModeIndex_300_1280x768[Depth];
-                  } else {
-                     ModeIndex = ModeIndex_310_1280x768[Depth];
-                  }
-               } else if(VDisplay == 1024) ModeIndex = ModeIndex_1280x1024[Depth];
-               else if(VDisplay == 720)    ModeIndex = ModeIndex_1280x720[Depth];
-               else if(VDisplay == 800)    ModeIndex = ModeIndex_1280x800[Depth];
-               else if(VDisplay == 960)    ModeIndex = ModeIndex_1280x960[Depth];
-               break;
-        case 1360:
-               if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth];
-                break;
-        case 1400:
-               if(VGAEngine == SIS_315_VGA) {
-                  if(VDisplay == 1050) ModeIndex = ModeIndex_1400x1050[Depth];
-               }
-               break;
        case 1600:
-               if(VGAEngine == SIS_315_VGA) {
-                  if(VBFlags & (VB_301B|VB_301C|VB_302B)) {
-                     if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
-                  }
+               if(VDisplay == 1200) {
+                       if(VGAEngine != SIS_315_VGA) return 0;
+                       if(!(VBFlags2 & VB2_30xB)) return 0;
                }
                break;
        case 1680:
-               if(VGAEngine == SIS_315_VGA) {
-                  if(VBFlags & (VB_301B|VB_301C|VB_302B)) {
-                     if(VDisplay == 1050) ModeIndex = ModeIndex_1680x1050[Depth];
-                  }
+               if(VDisplay == 1050) {
+                       if(VGAEngine != SIS_315_VGA) return 0;
+                       if(!(VBFlags2 & VB2_30xB)) return 0;
                }
                break;
    }
 
-   return ModeIndex;
+   return SiS_GetModeID(VGAEngine, 0, HDisplay, VDisplay, Depth, FALSE, 0, 0);
 }
 
 
@@ -1137,83 +882,83 @@ SiS_GetModeID_VGA2(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int
 /*********************************************/
 
 void
-SiS_SetReg(SISIOADDRESS port, USHORT index, USHORT data)
+SiS_SetReg(SISIOADDRESS port, unsigned short index, unsigned short data)
 {
-   OutPortByte(port,index);
-   OutPortByte(port + 1,data);
+   OutPortByte(port, index);
+   OutPortByte(port + 1, data);
 }
 
 void
-SiS_SetRegByte(SISIOADDRESS port, USHORT data)
+SiS_SetRegByte(SISIOADDRESS port, unsigned short data)
 {
-   OutPortByte(port,data);
+   OutPortByte(port, data);
 }
 
 void
-SiS_SetRegShort(SISIOADDRESS port, USHORT data)
+SiS_SetRegShort(SISIOADDRESS port, unsigned short data)
 {
-   OutPortWord(port,data);
+   OutPortWord(port, data);
 }
 
 void
-SiS_SetRegLong(SISIOADDRESS port, ULONG data)
+SiS_SetRegLong(SISIOADDRESS port, unsigned int data)
 {
-   OutPortLong(port,data);
+   OutPortLong(port, data);
 }
 
-UCHAR
-SiS_GetReg(SISIOADDRESS port, USHORT index)
+unsigned char
+SiS_GetReg(SISIOADDRESS port, unsigned short index)
 {
-   OutPortByte(port,index);
+   OutPortByte(port, index);
    return(InPortByte(port + 1));
 }
 
-UCHAR
+unsigned char
 SiS_GetRegByte(SISIOADDRESS port)
 {
    return(InPortByte(port));
 }
 
-USHORT
+unsigned short
 SiS_GetRegShort(SISIOADDRESS port)
 {
    return(InPortWord(port));
 }
 
-ULONG
+unsigned int
 SiS_GetRegLong(SISIOADDRESS port)
 {
    return(InPortLong(port));
 }
 
 void
-SiS_SetRegANDOR(SISIOADDRESS Port,USHORT Index,USHORT DataAND,USHORT DataOR)
+SiS_SetRegANDOR(SISIOADDRESS Port, unsigned short Index, unsigned short DataAND, unsigned short DataOR)
 {
-  USHORT temp;
+   unsigned short temp;
 
-  temp = SiS_GetReg(Port,Index);
-  temp = (temp & (DataAND)) | DataOR;
-  SiS_SetReg(Port,Index,temp);
+   temp = SiS_GetReg(Port, Index);
+   temp = (temp & (DataAND)) | DataOR;
+   SiS_SetReg(Port, Index, temp);
 }
 
 void
-SiS_SetRegAND(SISIOADDRESS Port,USHORT Index,USHORT DataAND)
+SiS_SetRegAND(SISIOADDRESS Port, unsigned short Index, unsigned short DataAND)
 {
-  USHORT temp;
+   unsigned short temp;
 
-  temp = SiS_GetReg(Port,Index);
-  temp &= DataAND;
-  SiS_SetReg(Port,Index,temp);
+   temp = SiS_GetReg(Port, Index);
+   temp &= DataAND;
+   SiS_SetReg(Port, Index, temp);
 }
 
 void
-SiS_SetRegOR(SISIOADDRESS Port,USHORT Index,USHORT DataOR)
+SiS_SetRegOR(SISIOADDRESS Port, unsigned short Index, unsigned short DataOR)
 {
-  USHORT temp;
+   unsigned short temp;
 
-  temp = SiS_GetReg(Port,Index);
-  temp |= DataOR;
-  SiS_SetReg(Port,Index,temp);
+   temp = SiS_GetReg(Port, Index);
+   temp |= DataOR;
+   SiS_SetReg(Port, Index, temp);
 }
 
 /*********************************************/
@@ -1221,13 +966,13 @@ SiS_SetRegOR(SISIOADDRESS Port,USHORT Index,USHORT DataOR)
 /*********************************************/
 
 void
-SiS_DisplayOn(SiS_Private *SiS_Pr)
+SiS_DisplayOn(struct SiS_Private *SiS_Pr)
 {
    SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x01,0xDF);
 }
 
 void
-SiS_DisplayOff(SiS_Private *SiS_Pr)
+SiS_DisplayOff(struct SiS_Private *SiS_Pr)
 {
    SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x01,0x20);
 }
@@ -1238,7 +983,7 @@ SiS_DisplayOff(SiS_Private *SiS_Pr)
 /*********************************************/
 
 void
-SiSRegInit(SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr)
+SiSRegInit(struct SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr)
 {
    SiS_Pr->SiS_P3c4 = BaseAddr + 0x14;
    SiS_Pr->SiS_P3d4 = BaseAddr + 0x24;
@@ -1251,16 +996,17 @@ SiSRegInit(SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr)
    SiS_Pr->SiS_P3c8 = BaseAddr + 0x18;
    SiS_Pr->SiS_P3c9 = BaseAddr + 0x19;
    SiS_Pr->SiS_P3cb = BaseAddr + 0x1b;
+   SiS_Pr->SiS_P3cc = BaseAddr + 0x1c;
    SiS_Pr->SiS_P3cd = BaseAddr + 0x1d;
    SiS_Pr->SiS_P3da = BaseAddr + 0x2a;
-   SiS_Pr->SiS_Part1Port = BaseAddr + SIS_CRT2_PORT_04;     /* Digital video interface registers (LCD) */
-   SiS_Pr->SiS_Part2Port = BaseAddr + SIS_CRT2_PORT_10;     /* 301 TV Encoder registers */
-   SiS_Pr->SiS_Part3Port = BaseAddr + SIS_CRT2_PORT_12;     /* 301 Macrovision registers */
-   SiS_Pr->SiS_Part4Port = BaseAddr + SIS_CRT2_PORT_14;     /* 301 VGA2 (and LCD) registers */
-   SiS_Pr->SiS_Part5Port = BaseAddr + SIS_CRT2_PORT_14 + 2; /* 301 palette address port registers */
-   SiS_Pr->SiS_DDC_Port = BaseAddr + 0x14;                  /* DDC Port ( = P3C4, SR11/0A) */
-   SiS_Pr->SiS_VidCapt = BaseAddr + SIS_VIDEO_CAPTURE;
-   SiS_Pr->SiS_VidPlay = BaseAddr + SIS_VIDEO_PLAYBACK;
+   SiS_Pr->SiS_Part1Port = BaseAddr + SIS_CRT2_PORT_04;
+   SiS_Pr->SiS_Part2Port = BaseAddr + SIS_CRT2_PORT_10;
+   SiS_Pr->SiS_Part3Port = BaseAddr + SIS_CRT2_PORT_12;
+   SiS_Pr->SiS_Part4Port = BaseAddr + SIS_CRT2_PORT_14;
+   SiS_Pr->SiS_Part5Port = BaseAddr + SIS_CRT2_PORT_14 + 2;
+   SiS_Pr->SiS_DDC_Port  = BaseAddr + 0x14;
+   SiS_Pr->SiS_VidCapt   = BaseAddr + SIS_VIDEO_CAPTURE;
+   SiS_Pr->SiS_VidPlay   = BaseAddr + SIS_VIDEO_PLAYBACK;
 }
 
 /*********************************************/
@@ -1268,7 +1014,7 @@ SiSRegInit(SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr)
 /*********************************************/
 
 static void
-SiS_GetSysFlags(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_GetSysFlags(struct SiS_Private *SiS_Pr)
 {
    unsigned char cr5f, temp1, temp2;
 
@@ -1276,9 +1022,9 @@ SiS_GetSysFlags(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
    /* (SR11 is used for DDC and in enable/disablebridge) */
    SiS_Pr->SiS_SensibleSR11 = FALSE;
    SiS_Pr->SiS_MyCR63 = 0x63;
-   if(HwInfo->jChipType >= SIS_330) {
+   if(SiS_Pr->ChipType >= SIS_330) {
       SiS_Pr->SiS_MyCR63 = 0x53;
-      if(HwInfo->jChipType >= SIS_661) {
+      if(SiS_Pr->ChipType >= SIS_661) {
          SiS_Pr->SiS_SensibleSR11 = TRUE;
       }
    }
@@ -1286,43 +1032,52 @@ SiS_GetSysFlags(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
    /* You should use the macros, not these flags directly */
 
    SiS_Pr->SiS_SysFlags = 0;
-   if(HwInfo->jChipType == SIS_650) {
+   if(SiS_Pr->ChipType == SIS_650) {
       cr5f = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0;
       SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x5c,0x07);
       temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5c) & 0xf8;
       SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x5c,0xf8);
       temp2 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5c) & 0xf8;
       if((!temp1) || (temp2)) {
-         switch(cr5f) {
+        switch(cr5f) {
            case 0x80:
            case 0x90:
            case 0xc0:
-              SiS_Pr->SiS_SysFlags |= SF_IsM650;  break;
+              SiS_Pr->SiS_SysFlags |= SF_IsM650;
+              break;
            case 0xa0:
            case 0xb0:
            case 0xe0:
-              SiS_Pr->SiS_SysFlags |= SF_Is651;   break;
+              SiS_Pr->SiS_SysFlags |= SF_Is651;
+              break;
         }
       } else {
-         switch(cr5f) {
+        switch(cr5f) {
            case 0x90:
               temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5c) & 0xf8;
               switch(temp1) {
-                 case 0x00: SiS_Pr->SiS_SysFlags |= SF_IsM652; break;
+                 case 0x00: SiS_Pr->SiS_SysFlags |= SF_IsM652; break;
                  case 0x40: SiS_Pr->SiS_SysFlags |= SF_IsM653; break;
                  default:   SiS_Pr->SiS_SysFlags |= SF_IsM650; break;
               }
               break;
            case 0xb0:
-              SiS_Pr->SiS_SysFlags |= SF_Is652;  break;
+              SiS_Pr->SiS_SysFlags |= SF_Is652;
+              break;
            default:
-              SiS_Pr->SiS_SysFlags |= SF_IsM650; break;
+              SiS_Pr->SiS_SysFlags |= SF_IsM650;
+              break;
         }
       }
    }
-   if(HwInfo->jChipType == SIS_760) {
-      temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x78);
-      if(temp1 & 0x30) SiS_Pr->SiS_SysFlags |= SF_760LFB;
+
+   if(SiS_Pr->ChipType >= SIS_760 && SiS_Pr->ChipType <= SIS_761) {
+      if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0x30) {
+         SiS_Pr->SiS_SysFlags |= SF_760LFB;
+      }
+      if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0xf0) {
+         SiS_Pr->SiS_SysFlags |= SF_760UMA;
+      }
    }
 }
 
@@ -1331,18 +1086,20 @@ SiS_GetSysFlags(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 /*********************************************/
 
 static void
-SiSInitPCIetc(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiSInitPCIetc(struct SiS_Private *SiS_Pr)
 {
-   switch(HwInfo->jChipType) {
+   switch(SiS_Pr->ChipType) {
+#ifdef SIS300
    case SIS_300:
    case SIS_540:
    case SIS_630:
    case SIS_730:
       /* Set - PCI LINEAR ADDRESSING ENABLE (0x80)
-       *     - RELOCATED VGA IO  (0x20)
-       *     - MMIO ENABLE (0x1)
+       *     - RELOCATED VGA IO ENABLED (0x20)
+       *     - MMIO ENABLED (0x01)
+       * Leave other bits untouched.
        */
-      SiS_SetReg(SiS_Pr->SiS_P3c4,0x20,0xa1);
+      SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x20,0xa1);
       /*  - Enable 2D (0x40)
        *  - Enable 3D (0x02)
        *  - Enable 3D Vertex command fetch (0x10) ?
@@ -1350,6 +1107,8 @@ SiSInitPCIetc(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
        */
       SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x5A);
       break;
+#endif
+#ifdef SIS315H
    case SIS_315H:
    case SIS_315:
    case SIS_315PRO:
@@ -1362,21 +1121,30 @@ SiSInitPCIetc(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
    case SIS_760:
    case SIS_761:
    case SIS_340:
-      SiS_SetReg(SiS_Pr->SiS_P3c4,0x20,0xa1);
-      /*  - Enable 2D (0x40)
-       *  - Enable 3D (0x02)
+   case XGI_40:
+      /* See above */
+      SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x20,0xa1);
+      /*  - Enable 3D G/L transformation engine (0x80)
+       *  - Enable 2D (0x40)
        *  - Enable 3D vertex command fetch (0x10)
        *  - Enable 3D command parser (0x08)
-       *  - Enable 3D G/L transformation engine (0x80)
+       *  - Enable 3D (0x02)
        */
       SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0xDA);
       break;
+   case XGI_20:
    case SIS_550:
-      SiS_SetReg(SiS_Pr->SiS_P3c4,0x20,0xa1);
+      /* See above */
+      SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x20,0xa1);
       /* No 3D engine ! */
       /*  - Enable 2D (0x40)
+       *  - disable 3D
        */
-      SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x40);
+      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1E,0x60,0x40);
+      break;
+#endif
+   default:
+      break;
    }
 }
 
@@ -1384,38 +1152,40 @@ SiSInitPCIetc(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 /*             HELPER: SetLVDSetc            */
 /*********************************************/
 
-static void
-SiSSetLVDSetc(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+#ifdef SIS_LINUX_KERNEL
+static
+#endif
+void
+SiSSetLVDSetc(struct SiS_Private *SiS_Pr)
 {
-   USHORT temp;
+   unsigned short temp;
 
    SiS_Pr->SiS_IF_DEF_LVDS = 0;
    SiS_Pr->SiS_IF_DEF_TRUMPION = 0;
    SiS_Pr->SiS_IF_DEF_CH70xx = 0;
-   SiS_Pr->SiS_IF_DEF_DSTN = 0;
-   SiS_Pr->SiS_IF_DEF_FSTN = 0;
    SiS_Pr->SiS_IF_DEF_CONEX = 0;
 
    SiS_Pr->SiS_ChrontelInit = 0;
 
+   if(SiS_Pr->ChipType == XGI_20) return;
+
    /* Check for SiS30x first */
    temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
    if((temp == 1) || (temp == 2)) return;
 
-   switch(HwInfo->jChipType) {
+   switch(SiS_Pr->ChipType) {
 #ifdef SIS300
    case SIS_540:
    case SIS_630:
    case SIS_730:
-       temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
-       temp = (temp & 0x0E) >> 1;
-       if((temp >= 2) && (temp <= 5))  SiS_Pr->SiS_IF_DEF_LVDS = 1;
-       if(temp == 3)                   SiS_Pr->SiS_IF_DEF_TRUMPION = 1;
-       if((temp == 4) || (temp == 5)) {
+       temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x37) & 0x0e) >> 1;
+       if((temp >= 2) && (temp <= 5))  SiS_Pr->SiS_IF_DEF_LVDS = 1;
+       if(temp == 3)                   SiS_Pr->SiS_IF_DEF_TRUMPION = 1;
+       if((temp == 4) || (temp == 5)) {
                /* Save power status (and error check) - UNUSED */
                SiS_Pr->SiS_Backup70xx = SiS_GetCH700x(SiS_Pr, 0x0e);
                SiS_Pr->SiS_IF_DEF_CH70xx = 1;
-        }
+       }
        break;
 #endif
 #ifdef SIS315H
@@ -1423,26 +1193,26 @@ SiSSetLVDSetc(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
    case SIS_650:
    case SIS_740:
    case SIS_330:
-        temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
-       temp = (temp & 0x0E) >> 1;
-       if((temp >= 2) && (temp <= 3))  SiS_Pr->SiS_IF_DEF_LVDS = 1;
-       if(temp == 3)                   SiS_Pr->SiS_IF_DEF_CH70xx = 2;
-        break;
+       temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x37) & 0x0e) >> 1;
+       if((temp >= 2) && (temp <= 3))  SiS_Pr->SiS_IF_DEF_LVDS = 1;
+       if(temp == 3)                   SiS_Pr->SiS_IF_DEF_CH70xx = 2;
+       break;
    case SIS_661:
    case SIS_741:
    case SIS_660:
    case SIS_760:
    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;
-       if(temp == 3)                   SiS_Pr->SiS_IF_DEF_CH70xx = 2;
-       if(temp == 4)                   SiS_Pr->SiS_IF_DEF_CONEX = 1;  /* Not yet supported */
-        break;
+   case XGI_20:
+   case XGI_40:
+       temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & 0xe0) >> 5;
+       if((temp >= 2) && (temp <= 3))  SiS_Pr->SiS_IF_DEF_LVDS = 1;
+       if(temp == 3)                   SiS_Pr->SiS_IF_DEF_CH70xx = 2;
+       if(temp == 4)                   SiS_Pr->SiS_IF_DEF_CONEX = 1;  /* Not yet supported */
+       break;
 #endif
    default:
-        break;
+       break;
    }
 }
 
@@ -1451,35 +1221,55 @@ SiSSetLVDSetc(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 /*********************************************/
 
 void
-SiS_SetEnableDstn(SiS_Private *SiS_Pr, int enable)
+SiS_SetEnableDstn(struct SiS_Private *SiS_Pr, int enable)
 {
    SiS_Pr->SiS_IF_DEF_DSTN = enable ? 1 : 0;
 }
 
 void
-SiS_SetEnableFstn(SiS_Private *SiS_Pr, int enable)
+SiS_SetEnableFstn(struct SiS_Private *SiS_Pr, int enable)
 {
    SiS_Pr->SiS_IF_DEF_FSTN = enable ? 1 : 0;
 }
 
 /*********************************************/
+/*            HELPER: Get modeflag           */
+/*********************************************/
+
+unsigned short
+SiS_GetModeFlag(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+               unsigned short ModeIdIndex)
+{
+   if(SiS_Pr->UseCustomMode) {
+      return SiS_Pr->CModeFlag;
+   } else if(ModeNo <= 0x13) {
+      return SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+   } else {
+      return SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+   }
+}
+
+/*********************************************/
 /*        HELPER: Determine ROM usage        */
 /*********************************************/
 
 BOOLEAN
-SiSDetermineROMLayout661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiSDetermineROMLayout661(struct SiS_Private *SiS_Pr)
 {
-   UCHAR  *ROMAddr  = HwInfo->pjVirtualRomBase;
-   USHORT romversoffs, romvmaj = 1, romvmin = 0;
-
-   if(HwInfo->jChipType >= SIS_761) {
-      /* I very much assume 761 and 340 will use new layout */
+   unsigned char  *ROMAddr  = SiS_Pr->VirtualRomBase;
+   unsigned short romversoffs, romvmaj = 1, romvmin = 0;
+
+   if(SiS_Pr->ChipType >= XGI_20) {
+      /* XGI ROMs don't qualify */
+      return FALSE;
+   } else if(SiS_Pr->ChipType >= SIS_761) {
+      /* I very much assume 761, 340 and newer will use new layout */
       return TRUE;
-   } else if(HwInfo->jChipType >= SIS_661) {
+   } else if(SiS_Pr->ChipType >= SIS_661) {
       if((ROMAddr[0x1a] == 'N') &&
-         (ROMAddr[0x1b] == 'e') &&
-         (ROMAddr[0x1c] == 'w') &&
-         (ROMAddr[0x1d] == 'V')) {
+        (ROMAddr[0x1b] == 'e') &&
+        (ROMAddr[0x1c] == 'w') &&
+        (ROMAddr[0x1d] == 'V')) {
         return TRUE;
       }
       romversoffs = ROMAddr[0x16] | (ROMAddr[0x17] << 8);
@@ -1494,9 +1284,9 @@ SiSDetermineROMLayout661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
       }
    } else if(IS_SIS650740) {
       if((ROMAddr[0x1a] == 'N') &&
-         (ROMAddr[0x1b] == 'e') &&
-         (ROMAddr[0x1c] == 'w') &&
-         (ROMAddr[0x1d] == 'V')) {
+        (ROMAddr[0x1b] == 'e') &&
+        (ROMAddr[0x1c] == 'w') &&
+        (ROMAddr[0x1d] == 'V')) {
         return TRUE;
       }
    }
@@ -1504,45 +1294,50 @@ SiSDetermineROMLayout661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 }
 
 static void
-SiSDetermineROMUsage(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiSDetermineROMUsage(struct SiS_Private *SiS_Pr)
 {
-   UCHAR  *ROMAddr  = HwInfo->pjVirtualRomBase;
-   USHORT romptr = 0;
+   unsigned char  *ROMAddr  = SiS_Pr->VirtualRomBase;
+   unsigned short romptr = 0;
 
    SiS_Pr->SiS_UseROM = FALSE;
    SiS_Pr->SiS_ROMNew = FALSE;
+   SiS_Pr->SiS_PWDOffset = 0;
 
-   if((ROMAddr) && (HwInfo->UseROM)) {
-      if(HwInfo->jChipType == SIS_300) {
-         /* 300: We check if the code starts below 0x220 by
+   if(SiS_Pr->ChipType >= XGI_20) return;
+
+   if((ROMAddr) && (SiS_Pr->UseROM)) {
+      if(SiS_Pr->ChipType == SIS_300) {
+        /* 300: We check if the code starts below 0x220 by
          * checking the jmp instruction at the beginning
          * of the BIOS image.
          */
         if((ROMAddr[3] == 0xe9) && ((ROMAddr[5] << 8) | ROMAddr[4]) > 0x21a)
            SiS_Pr->SiS_UseROM = TRUE;
-      } else if(HwInfo->jChipType < SIS_315H) {
+      } else if(SiS_Pr->ChipType < SIS_315H) {
         /* Sony's VAIO BIOS 1.09 follows the standard, so perhaps
          * the others do as well
          */
         SiS_Pr->SiS_UseROM = TRUE;
       } else {
-         /* 315/330 series stick to the standard(s) */
+        /* 315/330 series stick to the standard(s) */
         SiS_Pr->SiS_UseROM = TRUE;
-        if((SiS_Pr->SiS_ROMNew = SiSDetermineROMLayout661(SiS_Pr, HwInfo))) {
+        if((SiS_Pr->SiS_ROMNew = SiSDetermineROMLayout661(SiS_Pr))) {
            SiS_Pr->SiS_EMIOffset = 14;
+           SiS_Pr->SiS_PWDOffset = 17;
            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;
+                 SiS_Pr->SiS661LCD2TableSize = 32;
               else if(ROMAddr[romptr + (34 * 16)] == 0xff)
-                 SiS_Pr->SiS661LCD2TableSize = 34;
-              else if(ROMAddr[romptr + (36 * 16)] == 0xff)        /* 0.94 */
-                 SiS_Pr->SiS661LCD2TableSize = 36;
+                 SiS_Pr->SiS661LCD2TableSize = 34;
+              else if(ROMAddr[romptr + (36 * 16)] == 0xff)        /* 0.94, 2.05.00+ */
+                 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;
+                       (ROMAddr[0x6F] & 0x01) ) {                 /* 2.03.00 - <2.05.00 */
+                 SiS_Pr->SiS661LCD2TableSize = 38;                /* UMC data layout abandoned at 2.05.00 */
                  SiS_Pr->SiS_EMIOffset = 16;
+                 SiS_Pr->SiS_PWDOffset = 19;
               }
            }
         }
@@ -1555,9 +1350,9 @@ SiSDetermineROMUsage(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 /*********************************************/
 
 static void
-SiS_SetSegRegLower(SiS_Private *SiS_Pr, USHORT value)
+SiS_SetSegRegLower(struct SiS_Private *SiS_Pr, unsigned short value)
 {
-   USHORT temp;
+   unsigned short temp;
 
    value &= 0x00ff;
    temp = SiS_GetRegByte(SiS_Pr->SiS_P3cb) & 0xf0;
@@ -1569,9 +1364,9 @@ SiS_SetSegRegLower(SiS_Private *SiS_Pr, USHORT value)
 }
 
 static void
-SiS_SetSegRegUpper(SiS_Private *SiS_Pr, USHORT value)
+SiS_SetSegRegUpper(struct SiS_Private *SiS_Pr, unsigned short value)
 {
-   USHORT temp;
+   unsigned short temp;
 
    value &= 0x00ff;
    temp = SiS_GetRegByte(SiS_Pr->SiS_P3cb) & 0x0f;
@@ -1583,22 +1378,22 @@ SiS_SetSegRegUpper(SiS_Private *SiS_Pr, USHORT value)
 }
 
 static void
-SiS_SetSegmentReg(SiS_Private *SiS_Pr, USHORT value)
+SiS_SetSegmentReg(struct SiS_Private *SiS_Pr, unsigned short value)
 {
    SiS_SetSegRegLower(SiS_Pr, value);
    SiS_SetSegRegUpper(SiS_Pr, value);
 }
 
 static void
-SiS_ResetSegmentReg(SiS_Private *SiS_Pr)
+SiS_ResetSegmentReg(struct SiS_Private *SiS_Pr)
 {
    SiS_SetSegmentReg(SiS_Pr, 0);
 }
 
 static void
-SiS_SetSegmentRegOver(SiS_Private *SiS_Pr, USHORT value)
+SiS_SetSegmentRegOver(struct SiS_Private *SiS_Pr, unsigned short value)
 {
-   USHORT temp = value >> 8;
+   unsigned short temp = value >> 8;
 
    temp &= 0x07;
    temp |= (temp << 4);
@@ -1607,15 +1402,15 @@ SiS_SetSegmentRegOver(SiS_Private *SiS_Pr, USHORT value)
 }
 
 static void
-SiS_ResetSegmentRegOver(SiS_Private *SiS_Pr)
+SiS_ResetSegmentRegOver(struct SiS_Private *SiS_Pr)
 {
    SiS_SetSegmentRegOver(SiS_Pr, 0);
 }
 
 static void
-SiS_ResetSegmentRegisters(SiS_Private *SiS_Pr,PSIS_HW_INFO HwInfo)
+SiS_ResetSegmentRegisters(struct SiS_Private *SiS_Pr)
 {
-   if((IS_SIS65x) || (HwInfo->jChipType >= SIS_661)) {
+   if((IS_SIS65x) || (SiS_Pr->ChipType >= SIS_661)) {
       SiS_ResetSegmentReg(SiS_Pr);
       SiS_ResetSegmentRegOver(SiS_Pr);
    }
@@ -1625,154 +1420,153 @@ SiS_ResetSegmentRegisters(SiS_Private *SiS_Pr,PSIS_HW_INFO HwInfo)
 /*             HELPER: GetVBType             */
 /*********************************************/
 
-static void
-SiS_GetVBType(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+#ifdef SIS_LINUX_KERNEL
+static
+#endif
+void
+SiS_GetVBType(struct SiS_Private *SiS_Pr)
 {
-  USHORT flag=0, rev=0, nolcd=0, p4_0f, p4_25, p4_27;
-
-  SiS_Pr->SiS_VBType = 0;
-
-  if((SiS_Pr->SiS_IF_DEF_LVDS) || (SiS_Pr->SiS_IF_DEF_CONEX))
-     return;
-
-  flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
-
-  if(flag > 3) return;
-
-  rev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01);
-
-  if(flag >= 2) {
-     SiS_Pr->SiS_VBType = VB_SIS302B;
-  } else if(flag == 1) {
-     if(rev >= 0xC0) {
-               SiS_Pr->SiS_VBType = VB_SIS301C;
-     } else if(rev >= 0xB0) {
-               SiS_Pr->SiS_VBType = VB_SIS301B;
-       /* Check if 30xB DH version (no LCD support, use Panel Link instead) */
-       nolcd = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x23);
-        if(!(nolcd & 0x02)) SiS_Pr->SiS_VBType |= VB_NoLCD;
-     } else {
-        SiS_Pr->SiS_VBType = VB_SIS301;
-     }
-  }
-  if(SiS_Pr->SiS_VBType & (VB_SIS301B | VB_SIS301C | VB_SIS302B)) {
-     if(rev >= 0xE0) {
-       flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x39);
-       if(flag == 0xff) SiS_Pr->SiS_VBType = VB_SIS302LV;
-       else             SiS_Pr->SiS_VBType = VB_SIS301C;  /* VB_SIS302ELV; */
-     } else if(rev >= 0xD0) {
-       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);
-  }
-}
+   unsigned short flag = 0, rev = 0, nolcd = 0;
+   unsigned short p4_0f, p4_25, p4_27;
 
-/*********************************************/
-/*           HELPER: Check RAM size          */
-/*********************************************/
+   SiS_Pr->SiS_VBType = 0;
 
-#ifdef LINUX_KERNEL
-static BOOLEAN
-SiS_CheckMemorySize(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
-                    USHORT ModeNo, USHORT ModeIdIndex)
-{
-  USHORT AdapterMemSize = HwInfo->ulVideoMemorySize / (1024*1024);
-  USHORT memorysize,modeflag;
-
-  if(SiS_Pr->UseCustomMode) {
-     modeflag = SiS_Pr->CModeFlag;
-  } else {
-     if(ModeNo <= 0x13) {
-        modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-     } else {
-        modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-     }
-  }
-
-  memorysize = modeflag & MemoryInfoFlag;
-  memorysize >>= MemorySizeShift;              /* Get required memory size */
-  memorysize++;
-
-  if(AdapterMemSize < memorysize) return FALSE;
-  return TRUE;
-}
-#endif
+   if((SiS_Pr->SiS_IF_DEF_LVDS) || (SiS_Pr->SiS_IF_DEF_CONEX))
+      return;
+
+   if(SiS_Pr->ChipType == XGI_20)
+      return;
+
+   flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
+
+   if(flag > 3)
+      return;
+
+   rev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01);
+
+   if(flag >= 2) {
+      SiS_Pr->SiS_VBType = VB_SIS302B;
+   } else if(flag == 1) {
+      if(rev >= 0xC0) {
+        SiS_Pr->SiS_VBType = VB_SIS301C;
+      } else if(rev >= 0xB0) {
+        SiS_Pr->SiS_VBType = VB_SIS301B;
+        /* Check if 30xB DH version (no LCD support, use Panel Link instead) */
+        nolcd = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x23);
+        if(!(nolcd & 0x02)) SiS_Pr->SiS_VBType |= VB_NoLCD;
+      } else {
+        SiS_Pr->SiS_VBType = VB_SIS301;
+      }
+   }
+   if(SiS_Pr->SiS_VBType & (VB_SIS301B | VB_SIS301C | VB_SIS302B)) {
+      if(rev >= 0xE0) {
+        flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x39);
+        if(flag == 0xff) SiS_Pr->SiS_VBType = VB_SIS302LV;
+        else             SiS_Pr->SiS_VBType = VB_SIS301C;  /* VB_SIS302ELV; */
+      } else if(rev >= 0xD0) {
+        SiS_Pr->SiS_VBType = VB_SIS301LV;
+      }
+   }
+   if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV)) {
+      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          */
+/*********************************************/
+
+#ifdef SIS_LINUX_KERNEL
+static BOOLEAN
+SiS_CheckMemorySize(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+               unsigned short ModeIdIndex)
+{
+   unsigned short AdapterMemSize = SiS_Pr->VideoMemorySize / (1024*1024);
+   unsigned short modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
+   unsigned short memorysize = ((modeflag & MemoryInfoFlag) >> MemorySizeShift) + 1;
+
+   if(!AdapterMemSize) return TRUE;
+
+   if(AdapterMemSize < memorysize) return FALSE;
+   return TRUE;
+}
+#endif
 
 /*********************************************/
 /*           HELPER: Get DRAM type           */
 /*********************************************/
 
 #ifdef SIS315H
-static UCHAR
-SiS_Get310DRAMType(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+static unsigned char
+SiS_Get310DRAMType(struct SiS_Private *SiS_Pr)
 {
-   UCHAR data, temp;
+   unsigned char data;
 
    if((*SiS_Pr->pSiS_SoftSetting) & SoftDRAMType) {
-     data = (*SiS_Pr->pSiS_SoftSetting) & 0x03;
+      data = (*SiS_Pr->pSiS_SoftSetting) & 0x03;
    } else {
-     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);
-       }
-     } else if(IS_SIS550650740) {
-        data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x07;
-     } else {  /* 315, 330 */
-        data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3a) & 0x03;
-        if(HwInfo->jChipType == SIS_330) {
-          if(data > 1) {
-             temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0x30;
-             switch(temp) {
-             case 0x00: data = 1; break;
-             case 0x10: data = 3; break;
-             case 0x20: data = 3; break;
-             case 0x30: data = 2; break;
-             }
-          } else {
-             data = 0;
-          }
-       }
-     }
+      if(SiS_Pr->ChipType >= XGI_20) {
+         /* Do I need this? SR17 seems to be zero anyway... */
+        data = 0;
+      } else if(SiS_Pr->ChipType >= SIS_340) {
+        /* TODO */
+        data = 0;
+      } if(SiS_Pr->ChipType >= SIS_661) {
+        if(SiS_Pr->SiS_ROMNew) {
+           data = ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0xc0) >> 6);
+        } else {
+           data = SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0x07;
+        }
+      } else if(IS_SIS550650740) {
+        data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x07;
+      } else { /* 315, 330 */
+        data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3a) & 0x03;
+        if(SiS_Pr->ChipType == SIS_330) {
+           if(data > 1) {
+              switch(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0x30) {
+              case 0x00: data = 1; break;
+              case 0x10: data = 3; break;
+              case 0x20: data = 3; break;
+              case 0x30: data = 2; break;
+              }
+           } else {
+              data = 0;
+           }
+        }
+      }
    }
 
    return data;
 }
 
-static USHORT
-SiS_GetMCLK(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+static unsigned short
+SiS_GetMCLK(struct SiS_Private *SiS_Pr)
 {
-  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
-  USHORT index;
-
-  index = SiS_Get310DRAMType(SiS_Pr, HwInfo);
-  if(HwInfo->jChipType >= SIS_661) {
-     if(SiS_Pr->SiS_ROMNew) {
-        return((USHORT)(SISGETROMW((0x90 + (index * 5) + 3))));
-     }
-     return(SiS_Pr->SiS_MCLKData_0[index].CLOCK);
-  } else if(index >= 4) {
-     index -= 4;
-     return(SiS_Pr->SiS_MCLKData_1[index].CLOCK);
-  } else {
-     return(SiS_Pr->SiS_MCLKData_0[index].CLOCK);
-  }
+   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
+   unsigned short index;
+
+   index = SiS_Get310DRAMType(SiS_Pr);
+   if(SiS_Pr->ChipType >= SIS_661) {
+      if(SiS_Pr->SiS_ROMNew) {
+        return((unsigned short)(SISGETROMW((0x90 + (index * 5) + 3))));
+      }
+      return(SiS_Pr->SiS_MCLKData_0[index].CLOCK);
+   } else if(index >= 4) {
+      return(SiS_Pr->SiS_MCLKData_1[index - 4].CLOCK);
+   } else {
+      return(SiS_Pr->SiS_MCLKData_0[index].CLOCK);
+   }
 }
 #endif
 
@@ -1780,30 +1574,30 @@ SiS_GetMCLK(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 /*           HELPER: ClearBuffer             */
 /*********************************************/
 
-#ifdef LINUX_KERNEL
+#ifdef SIS_LINUX_KERNEL
 static void
-SiS_ClearBuffer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
+SiS_ClearBuffer(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
 {
-  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 SISIOMEMTYPE *)VideoMemoryAddress;
-        for(i=0; i<0x4000; i++) writew(0x0000, &pBuffer[i]);
-     }
-  } else {
-     if(SiS_Pr->SiS_ModeType < ModeCGA) {
-        pBuffer = (USHORT SISIOMEMTYPE *)VideoMemoryAddress;
-        for(i=0; i<0x4000; i++) writew(0x0720, &pBuffer[i]);
-     } else {
-        SiS_SetMemory(VideoMemoryAddress, 0x8000, 0);
-     }
-  }
+   unsigned char  SISIOMEMTYPE *memaddr = SiS_Pr->VideoMemoryAddress;
+   unsigned int   memsize = SiS_Pr->VideoMemorySize;
+   unsigned short SISIOMEMTYPE *pBuffer;
+   int i;
+
+   if(!memaddr || !memsize) return;
+
+   if(SiS_Pr->SiS_ModeType >= ModeEGA) {
+      if(ModeNo > 0x13) {
+        SiS_SetMemory(memaddr, memsize, 0);
+      } else {
+        pBuffer = (unsigned short SISIOMEMTYPE *)memaddr;
+        for(i = 0; i < 0x4000; i++) writew(0x0000, &pBuffer[i]);
+      }
+   } else if(SiS_Pr->SiS_ModeType < ModeCGA) {
+      pBuffer = (unsigned short SISIOMEMTYPE *)memaddr;
+      for(i = 0; i < 0x4000; i++) writew(0x0720, &pBuffer[i]);
+   } else {
+      SiS_SetMemory(memaddr, 0x8000, 0);
+   }
 }
 #endif
 
@@ -1812,35 +1606,36 @@ SiS_ClearBuffer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
 /*********************************************/
 
 BOOLEAN
-SiS_SearchModeID(SiS_Private *SiS_Pr, USHORT *ModeNo, USHORT *ModeIdIndex)
+SiS_SearchModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo,
+               unsigned short *ModeIdIndex)
 {
-   UCHAR VGAINFO = SiS_Pr->SiS_VGAINFO;
+   unsigned char VGAINFO = SiS_Pr->SiS_VGAINFO;
 
-   if(*ModeNo <= 0x13) {
+   if((*ModeNo) <= 0x13) {
 
       if((*ModeNo) <= 0x05) (*ModeNo) |= 0x01;
 
-      for(*ModeIdIndex = 0; ;(*ModeIdIndex)++) {
-         if(SiS_Pr->SiS_SModeIDTable[*ModeIdIndex].St_ModeID == (*ModeNo)) break;
-         if(SiS_Pr->SiS_SModeIDTable[*ModeIdIndex].St_ModeID == 0xFF)   return FALSE;
+      for((*ModeIdIndex) = 0; ;(*ModeIdIndex)++) {
+        if(SiS_Pr->SiS_SModeIDTable[(*ModeIdIndex)].St_ModeID == (*ModeNo)) break;
+        if(SiS_Pr->SiS_SModeIDTable[(*ModeIdIndex)].St_ModeID == 0xFF) return FALSE;
       }
 
-      if(*ModeNo == 0x07) {
-          if(VGAINFO & 0x10) (*ModeIdIndex)++;   /* 400 lines */
-          /* else 350 lines */
+      if((*ModeNo) == 0x07) {
+         if(VGAINFO & 0x10) (*ModeIdIndex)++;   /* 400 lines */
+         /* else 350 lines */
       }
-      if(*ModeNo <= 0x03) {
-         if(!(VGAINFO & 0x80)) (*ModeIdIndex)++;
-         if(VGAINFO & 0x10)    (*ModeIdIndex)++; /* 400 lines  */
-         /* else 350 lines  */
+      if((*ModeNo) <= 0x03) {
+        if(!(VGAINFO & 0x80)) (*ModeIdIndex)++;
+        if(VGAINFO & 0x10)    (*ModeIdIndex)++; /* 400 lines  */
+        /* else 350 lines  */
       }
       /* else 200 lines  */
 
    } else {
 
-      for(*ModeIdIndex = 0; ;(*ModeIdIndex)++) {
-         if(SiS_Pr->SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == (*ModeNo)) break;
-         if(SiS_Pr->SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF)      return FALSE;
+      for((*ModeIdIndex) = 0; ;(*ModeIdIndex)++) {
+        if(SiS_Pr->SiS_EModeIDTable[(*ModeIdIndex)].Ext_ModeID == (*ModeNo)) break;
+        if(SiS_Pr->SiS_EModeIDTable[(*ModeIdIndex)].Ext_ModeID == 0xFF) return FALSE;
       }
 
    }
@@ -1851,10 +1646,10 @@ SiS_SearchModeID(SiS_Private *SiS_Pr, USHORT *ModeNo, USHORT *ModeIdIndex)
 /*            HELPER: GetModePtr             */
 /*********************************************/
 
-UCHAR
-SiS_GetModePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex)
+unsigned short
+SiS_GetModePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
 {
-   UCHAR index;
+   unsigned short index;
 
    if(ModeNo <= 0x13) {
       index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_StTableIndex;
@@ -1866,79 +1661,125 @@ SiS_GetModePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex)
 }
 
 /*********************************************/
+/*         HELPERS: Get some indices         */
+/*********************************************/
+
+unsigned short
+SiS_GetRefCRTVCLK(struct SiS_Private *SiS_Pr, unsigned short Index, int UseWide)
+{
+   if(SiS_Pr->SiS_RefIndex[Index].Ext_InfoFlag & HaveWideTiming) {
+      if(UseWide == 1) {
+         return SiS_Pr->SiS_RefIndex[Index].Ext_CRTVCLK_WIDE;
+      } else {
+         return SiS_Pr->SiS_RefIndex[Index].Ext_CRTVCLK_NORM;
+      }
+   } else {
+      return SiS_Pr->SiS_RefIndex[Index].Ext_CRTVCLK;
+   }
+}
+
+unsigned short
+SiS_GetRefCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short Index, int UseWide)
+{
+   if(SiS_Pr->SiS_RefIndex[Index].Ext_InfoFlag & HaveWideTiming) {
+      if(UseWide == 1) {
+         return SiS_Pr->SiS_RefIndex[Index].Ext_CRT1CRTC_WIDE;
+      } else {
+         return SiS_Pr->SiS_RefIndex[Index].Ext_CRT1CRTC_NORM;
+      }
+   } else {
+      return SiS_Pr->SiS_RefIndex[Index].Ext_CRT1CRTC;
+   }
+}
+
+/*********************************************/
 /*           HELPER: LowModeTests            */
 /*********************************************/
 
 static BOOLEAN
-SiS_DoLowModeTest(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_INFO HwInfo)
+SiS_DoLowModeTest(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
 {
-    USHORT temp,temp1,temp2;
-
-    if((ModeNo != 0x03) && (ModeNo != 0x10) && (ModeNo != 0x12))
-       return(TRUE);
-    temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x11);
-    SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x11,0x80);
-    temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x00);
-    SiS_SetReg(SiS_Pr->SiS_P3d4,0x00,0x55);
-    temp2 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x00);
-    SiS_SetReg(SiS_Pr->SiS_P3d4,0x00,temp1);
-    SiS_SetReg(SiS_Pr->SiS_P3d4,0x11,temp);
-    if((HwInfo->jChipType >= SIS_315H) ||
-       (HwInfo->jChipType == SIS_300)) {
-       if(temp2 == 0x55) return(FALSE);
-       else return(TRUE);
-    } else {
-       if(temp2 != 0x55) return(TRUE);
-       else {
-          SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01);
-          return(FALSE);
-       }
-    }
+   unsigned short temp, temp1, temp2;
+
+   if((ModeNo != 0x03) && (ModeNo != 0x10) && (ModeNo != 0x12))
+      return TRUE;
+   temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x11);
+   SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x11,0x80);
+   temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x00);
+   SiS_SetReg(SiS_Pr->SiS_P3d4,0x00,0x55);
+   temp2 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x00);
+   SiS_SetReg(SiS_Pr->SiS_P3d4,0x00,temp1);
+   SiS_SetReg(SiS_Pr->SiS_P3d4,0x11,temp);
+   if((SiS_Pr->ChipType >= SIS_315H) ||
+      (SiS_Pr->ChipType == SIS_300)) {
+      if(temp2 == 0x55) return FALSE;
+      else return TRUE;
+   } else {
+      if(temp2 != 0x55) return TRUE;
+      else {
+        SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01);
+        return FALSE;
+      }
+   }
 }
 
 static void
-SiS_SetLowModeTest(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_INFO HwInfo)
+SiS_SetLowModeTest(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
 {
-    if(SiS_DoLowModeTest(SiS_Pr, ModeNo, HwInfo)) {
-       SiS_Pr->SiS_SetFlag |= LowModeTests;
-    }
+   if(SiS_DoLowModeTest(SiS_Pr, ModeNo)) {
+      SiS_Pr->SiS_SetFlag |= LowModeTests;
+   }
 }
 
 /*********************************************/
-/*            HELPER: ENABLE CRT1            */
+/*        HELPER: OPEN/CLOSE CRT1 CRTC       */
 /*********************************************/
 
 static void
-SiS_SetupCR5x(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_OpenCRTC(struct SiS_Private *SiS_Pr)
+{
+   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);
+      }
+   }
+}
+
+static void
+SiS_CloseCRTC(struct SiS_Private *SiS_Pr)
 {
-    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);
-       }
-    }
+#if 0 /* This locks some CRTC registers. We don't want that. */
+   unsigned short temp1 = 0, temp2 = 0;
+
+   if(IS_SIS661741660760) {
+      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+         temp1 = 0xa0; temp2 = 0x08;
+      }
+      SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x51,0x1f,temp1);
+      SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x56,0xe7,temp2);
+   }
+#endif
 }
 
 static void
-SiS_HandleCRT1(SiS_Private *SiS_Pr)
+SiS_HandleCRT1(struct SiS_Private *SiS_Pr)
 {
-  /* Enable CRT1 gating */
-  SiS_SetRegAND(SiS_Pr->SiS_P3d4,SiS_Pr->SiS_MyCR63,0xbf);
+   /* 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)) {
-     if((SiS_GetReg(SiS_Pr->SiS_P3c4,0x15) & 0x0a) ||
-        (SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x01)) {
-        SiS_SetRegOR(SiS_Pr->SiS_P3d4,SiS_Pr->SiS_MyCR63,0x40);
-     }
-  }
+   if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x15) & 0x01)) {
+      if((SiS_GetReg(SiS_Pr->SiS_P3c4,0x15) & 0x0a) ||
+         (SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x01)) {
+         SiS_SetRegOR(SiS_Pr->SiS_P3d4,SiS_Pr->SiS_MyCR63,0x40);
+      }
+   }
 #endif
 }
 
@@ -1946,57 +1787,54 @@ SiS_HandleCRT1(SiS_Private *SiS_Pr)
 /*           HELPER: GetColorDepth           */
 /*********************************************/
 
-USHORT
-SiS_GetColorDepth(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex)
+unsigned short
+SiS_GetColorDepth(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+               unsigned short ModeIdIndex)
 {
-  USHORT ColorDepth[6] = { 1, 2, 4, 4, 6, 8};
-  SHORT  index;
-  USHORT modeflag;
-
-  /* Do NOT check UseCustomMode, will skrew up FIFO */
-  if(ModeNo == 0xfe) {
-     modeflag = SiS_Pr->CModeFlag;
-  } else {
-     if(ModeNo <= 0x13)
-       modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-     else
-       modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-  }
-
-  index = (modeflag & ModeTypeMask) - ModeEGA;
-  if(index < 0) index = 0;
-  return(ColorDepth[index]);
+   static const unsigned short ColorDepth[6] = { 1, 2, 4, 4, 6, 8 };
+   unsigned short modeflag;
+   short index;
+
+   /* Do NOT check UseCustomMode, will skrew up FIFO */
+   if(ModeNo == 0xfe) {
+      modeflag = SiS_Pr->CModeFlag;
+   } else if(ModeNo <= 0x13) {
+      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+   } else {
+      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+   }
+
+   index = (modeflag & ModeTypeMask) - ModeEGA;
+   if(index < 0) index = 0;
+   return ColorDepth[index];
 }
 
 /*********************************************/
 /*             HELPER: GetOffset             */
 /*********************************************/
 
-USHORT
-SiS_GetOffset(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
-              USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo)
+unsigned short
+SiS_GetOffset(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+               unsigned short ModeIdIndex, unsigned short RRTI)
 {
-  USHORT xres, temp, colordepth, infoflag;
-
-  if(SiS_Pr->UseCustomMode) {
-     infoflag = SiS_Pr->CInfoFlag;
-     xres = SiS_Pr->CHDisplay;
-  } else {
-     infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
-     xres = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes;
-  }
-
-  colordepth = SiS_GetColorDepth(SiS_Pr,ModeNo,ModeIdIndex);
-
-  temp = xres / 16;
-  if(infoflag & InterlaceMode) temp <<= 1;
-  temp *= colordepth;
-  if(xres % 16) {
-     colordepth >>= 1;
-     temp += colordepth;
-  }
-
-  return(temp);
+   unsigned short xres, temp, colordepth, infoflag;
+
+   if(SiS_Pr->UseCustomMode) {
+      infoflag = SiS_Pr->CInfoFlag;
+      xres = SiS_Pr->CHDisplay;
+   } else {
+      infoflag = SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag;
+      xres = SiS_Pr->SiS_RefIndex[RRTI].XRes;
+   }
+
+   colordepth = SiS_GetColorDepth(SiS_Pr, ModeNo, ModeIdIndex);
+
+   temp = xres / 16;
+   if(infoflag & InterlaceMode) temp <<= 1;
+   temp *= colordepth;
+   if(xres % 16) temp += (colordepth >> 1);
+
+   return temp;
 }
 
 /*********************************************/
@@ -2004,55 +1842,29 @@ SiS_GetOffset(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
 /*********************************************/
 
 static void
-SiS_SetSeqRegs(SiS_Private *SiS_Pr, USHORT StandTableIndex, PSIS_HW_INFO HwInfo)
+SiS_SetSeqRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex)
 {
-   UCHAR SRdata;
-   USHORT i;
+   unsigned char SRdata;
+   int i;
 
-   SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x03);             /* Set SR0  */
+   SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x03);
 
-   SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[0];
+   /* or "display off"  */
+   SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[0] | 0x20;
 
-   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
-         SRdata |= 0x01;
-      }
-      if(HwInfo->jChipType >= SIS_661) {
-         if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
-           if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-               SRdata |= 0x01;                         /* 8 dot clock  */
-            }
-        }
-      } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-         if(SiS_Pr->SiS_VBType & VB_NoLCD) {
-           if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-               SRdata |= 0x01;                         /* 8 dot clock  */
-            }
-        }
-      }
-   }
+   /* determine whether to force x8 dotclock */
+   if((SiS_Pr->SiS_VBType & VB_SISVB) || (SiS_Pr->SiS_IF_DEF_LVDS)) {
 
-   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
-         if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-            if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-               SRdata |= 0x01;                         /* 8 dot clock  */
-            }
-         }
-      }
-      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-         if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-            SRdata |= 0x01;                            /* 8 dot clock  */
-         }
-      }
-   }
+      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
+         if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)    SRdata |= 0x01;
+      } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) SRdata |= 0x01;
 
-   SRdata |= 0x20;                                     /* screen off  */
+   }
 
    SiS_SetReg(SiS_Pr->SiS_P3c4,0x01,SRdata);
 
    for(i = 2; i <= 4; i++) {
-      SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[i-1];
+      SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[i - 1];
       SiS_SetReg(SiS_Pr->SiS_P3c4,i,SRdata);
    }
 }
@@ -2062,17 +1874,17 @@ SiS_SetSeqRegs(SiS_Private *SiS_Pr, USHORT StandTableIndex, PSIS_HW_INFO HwInfo)
 /*********************************************/
 
 static void
-SiS_SetMiscRegs(SiS_Private *SiS_Pr, USHORT StandTableIndex, PSIS_HW_INFO HwInfo)
+SiS_SetMiscRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex)
 {
-   UCHAR Miscdata;
+   unsigned char Miscdata;
 
    Miscdata = SiS_Pr->SiS_StandTable[StandTableIndex].MISC;
 
-   if(HwInfo->jChipType < SIS_661) {
-      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
-            Miscdata |= 0x0C;
-         }
+   if(SiS_Pr->ChipType < SIS_661) {
+      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
+        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+          Miscdata |= 0x0C;
+        }
       }
    }
 
@@ -2084,33 +1896,34 @@ SiS_SetMiscRegs(SiS_Private *SiS_Pr, USHORT StandTableIndex, PSIS_HW_INFO HwInfo
 /*********************************************/
 
 static void
-SiS_SetCRTCRegs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
-                USHORT StandTableIndex)
+SiS_SetCRTCRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex)
 {
-  UCHAR CRTCdata;
-  USHORT i;
-
-  SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);                       /* Unlock CRTC */
-
-  for(i = 0; i <= 0x18; i++) {
-     CRTCdata = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[i];
-     SiS_SetReg(SiS_Pr->SiS_P3d4,i,CRTCdata);                     /* Set CRTC(3d4) */
-  }
-  if(HwInfo->jChipType >= SIS_661) {
-     SiS_SetupCR5x(SiS_Pr, HwInfo);
-     for(i = 0x13; i <= 0x14; i++) {
-        CRTCdata = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[i];
-        SiS_SetReg(SiS_Pr->SiS_P3d4,i,CRTCdata);
-     }
-  } else if( ( (HwInfo->jChipType == SIS_630) ||
-               (HwInfo->jChipType == SIS_730) )  &&
-             (HwInfo->jChipRevision >= 0x30) ) {                  /* for 630S0 */
-     if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-        if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
-           SiS_SetReg(SiS_Pr->SiS_P3d4,0x18,0xFE);
-        }
-     }
-  }
+   unsigned char  CRTCdata;
+   unsigned short i;
+
+   /* Unlock CRTC */
+   SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
+
+   for(i = 0; i <= 0x18; i++) {
+      CRTCdata = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[i];
+      SiS_SetReg(SiS_Pr->SiS_P3d4,i,CRTCdata);
+   }
+
+   if(SiS_Pr->ChipType >= SIS_661) {
+      SiS_OpenCRTC(SiS_Pr);
+      for(i = 0x13; i <= 0x14; i++) {
+        CRTCdata = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[i];
+        SiS_SetReg(SiS_Pr->SiS_P3d4,i,CRTCdata);
+      }
+   } else if( ( (SiS_Pr->ChipType == SIS_630) ||
+               (SiS_Pr->ChipType == SIS_730) )  &&
+             (SiS_Pr->ChipRevision >= 0x30) ) {
+      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+        if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
+           SiS_SetReg(SiS_Pr->SiS_P3d4,0x18,0xFE);
+        }
+      }
+   }
 }
 
 /*********************************************/
@@ -2118,64 +1931,58 @@ SiS_SetCRTCRegs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
 /*********************************************/
 
 static void
-SiS_SetATTRegs(SiS_Private *SiS_Pr, USHORT StandTableIndex,
-               PSIS_HW_INFO HwInfo)
+SiS_SetATTRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex)
 {
-   UCHAR ARdata;
-   USHORT i;
+   unsigned char  ARdata;
+   unsigned short i;
 
    for(i = 0; i <= 0x13; i++) {
       ARdata = SiS_Pr->SiS_StandTable[StandTableIndex].ATTR[i];
-#if 0
-      if((i <= 0x0f) || (i == 0x11)) {
-         if(ds:489 & 0x08) {
-           continue;
-         }
-      }
-#endif
+
       if(i == 0x13) {
-         /* Pixel shift. If screen on LCD or TV is shifted left or right,
-          * this might be the cause.
-          */
-         if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-            if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)  ARdata=0;
-         }
-         if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-            if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
-               if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-                  if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata=0;
-               }
-            }
-         }
-        if(HwInfo->jChipType >= SIS_661) {
+        /* Pixel shift. If screen on LCD or TV is shifted left or right,
+         * this might be the cause.
+         */
+        if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
+           if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) ARdata = 0;
+        }
+        if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+           if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+              if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+                 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata = 0;
+              }
+           }
+        }
+        if(SiS_Pr->ChipType >= SIS_661) {
            if(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD)) {
-              if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata=0;
+              if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata = 0;
            }
         } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-            if(HwInfo->jChipType >= SIS_315H) {
+           if(SiS_Pr->ChipType >= SIS_315H) {
               if(IS_SIS550650740660) {
-                 /* 315, 330 don't do this */
-                 if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
-                    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata=0;
-                 } else {
-                    ARdata = 0;
-                 }
+                 /* 315, 330 don't do this */
+                 if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
+                    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata = 0;
+                 } else {
+                    ARdata = 0;
+                 }
               }
            } else {
-               if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)  ARdata=0;
+              if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata = 0;
            }
-         }
+        }
       }
-      SiS_GetRegByte(SiS_Pr->SiS_P3da);                         /* reset 3da  */
-      SiS_SetRegByte(SiS_Pr->SiS_P3c0,i);                       /* set index  */
-      SiS_SetRegByte(SiS_Pr->SiS_P3c0,ARdata);                  /* set data   */
+      SiS_GetRegByte(SiS_Pr->SiS_P3da);                /* reset 3da  */
+      SiS_SetRegByte(SiS_Pr->SiS_P3c0,i);      /* set index  */
+      SiS_SetRegByte(SiS_Pr->SiS_P3c0,ARdata); /* set data   */
    }
-   SiS_GetRegByte(SiS_Pr->SiS_P3da);                            /* reset 3da  */
-   SiS_SetRegByte(SiS_Pr->SiS_P3c0,0x14);                       /* set index  */
-   SiS_SetRegByte(SiS_Pr->SiS_P3c0,0x00);                       /* set data   */
+
+   SiS_GetRegByte(SiS_Pr->SiS_P3da);           /* reset 3da  */
+   SiS_SetRegByte(SiS_Pr->SiS_P3c0,0x14);      /* set index  */
+   SiS_SetRegByte(SiS_Pr->SiS_P3c0,0x00);      /* set data   */
 
    SiS_GetRegByte(SiS_Pr->SiS_P3da);
-   SiS_SetRegByte(SiS_Pr->SiS_P3c0,0x20);                      /* Enable Attribute  */
+   SiS_SetRegByte(SiS_Pr->SiS_P3c0,0x20);      /* Enable Attribute  */
    SiS_GetRegByte(SiS_Pr->SiS_P3da);
 }
 
@@ -2184,10 +1991,10 @@ SiS_SetATTRegs(SiS_Private *SiS_Pr, USHORT StandTableIndex,
 /*********************************************/
 
 static void
-SiS_SetGRCRegs(SiS_Private *SiS_Pr, USHORT StandTableIndex)
+SiS_SetGRCRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex)
 {
-   UCHAR GRdata;
-   USHORT i;
+   unsigned char  GRdata;
+   unsigned short i;
 
    for(i = 0; i <= 0x08; i++) {
       GRdata = SiS_Pr->SiS_StandTable[StandTableIndex].GRC[i];
@@ -2205,22 +2012,22 @@ SiS_SetGRCRegs(SiS_Private *SiS_Pr, USHORT StandTableIndex)
 /*********************************************/
 
 static void
-SiS_ClearExt1Regs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
+SiS_ClearExt1Regs(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
 {
-  USHORT i;
+   unsigned short i;
 
-  for(i = 0x0A; i <= 0x0E; i++) {
-     SiS_SetReg(SiS_Pr->SiS_P3c4,i,0x00);
-  }
+   for(i = 0x0A; i <= 0x0E; i++) {
+      SiS_SetReg(SiS_Pr->SiS_P3c4,i,0x00);
+   }
 
-  if(HwInfo->jChipType >= SIS_315H) {
-     SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x37,0xFE);
-     if(ModeNo <= 0x13) {
-        if(ModeNo == 0x06 || ModeNo >= 0x0e) {
-          SiS_SetReg(SiS_Pr->SiS_P3c4,0x0e,0x20);
-       }
-     }
-  }
+   if(SiS_Pr->ChipType >= SIS_315H) {
+      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x37,0xFE);
+      if(ModeNo <= 0x13) {
+        if(ModeNo == 0x06 || ModeNo >= 0x0e) {
+           SiS_SetReg(SiS_Pr->SiS_P3c4,0x0e,0x20);
+        }
+      }
+   }
 }
 
 /*********************************************/
@@ -2228,32 +2035,24 @@ SiS_ClearExt1Regs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
 /*********************************************/
 
 static void
-SiS_ResetCRT1VCLK(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_ResetCRT1VCLK(struct SiS_Private *SiS_Pr)
 {
-   if(HwInfo->jChipType >= SIS_315H) {
-      if(HwInfo->jChipType < SIS_661) {
-         if(SiS_Pr->SiS_IF_DEF_LVDS == 0) return;
+   if(SiS_Pr->ChipType >= SIS_315H) {
+      if(SiS_Pr->ChipType < SIS_661) {
+        if(SiS_Pr->SiS_IF_DEF_LVDS == 0) return;
       }
    } else {
       if((SiS_Pr->SiS_IF_DEF_LVDS == 0) &&
-         (!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) ) {
+        (!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) ) {
         return;
       }
    }
 
-   if(HwInfo->jChipType >= SIS_315H) {
-      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x31,0xCF,0x20);
-   } else {
-      SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x20);
-   }
+   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x31,0xcf,0x20);
    SiS_SetReg(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VCLKData[1].SR2B);
    SiS_SetReg(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VCLKData[1].SR2C);
    SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x80);
-   if(HwInfo->jChipType >= SIS_315H) {
-      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x31,0xcf,0x10);
-   } else {
-      SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x10);
-   }
+   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x31,0xcf,0x10);
    SiS_SetReg(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VCLKData[0].SR2B);
    SiS_SetReg(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VCLKData[0].SR2C);
    SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x80);
@@ -2264,19 +2063,19 @@ SiS_ResetCRT1VCLK(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 /*********************************************/
 
 static void
-SiS_SetCRT1Sync(SiS_Private *SiS_Pr, USHORT RefreshRateTableIndex)
+SiS_SetCRT1Sync(struct SiS_Private *SiS_Pr, unsigned short RRTI)
 {
-  USHORT sync;
+   unsigned short sync;
 
-  if(SiS_Pr->UseCustomMode) {
-     sync = SiS_Pr->CInfoFlag >> 8;
-  } else {
-     sync = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag >> 8;
-  }
+   if(SiS_Pr->UseCustomMode) {
+      sync = SiS_Pr->CInfoFlag >> 8;
+   } else {
+      sync = SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag >> 8;
+   }
 
-  sync &= 0xC0;
-  sync |= 0x2f;
-  SiS_SetRegByte(SiS_Pr->SiS_P3c2,sync);
+   sync &= 0xC0;
+   sync |= 0x2f;
+   SiS_SetRegByte(SiS_Pr->SiS_P3c2,sync);
 }
 
 /*********************************************/
@@ -2284,72 +2083,67 @@ SiS_SetCRT1Sync(SiS_Private *SiS_Pr, USHORT RefreshRateTableIndex)
 /*********************************************/
 
 static void
-SiS_SetCRT1CRTC(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
-                USHORT RefreshRateTableIndex,
-               PSIS_HW_INFO HwInfo)
+SiS_SetCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+               unsigned short ModeIdIndex, unsigned short RRTI)
 {
-  UCHAR  index;
-  USHORT temp,i,j,modeflag;
-
-  SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);           /* unlock cr0-7 */
-
-  if(SiS_Pr->UseCustomMode) {
-
-     modeflag = SiS_Pr->CModeFlag;
-
-     for(i=0,j=0;i<=7;i++,j++) {
-        SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
-     }
-     for(j=0x10;i<=10;i++,j++) {
-        SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
-     }
-     for(j=0x15;i<=12;i++,j++) {
-        SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
-     }
-     for(j=0x0A;i<=15;i++,j++) {
-        SiS_SetReg(SiS_Pr->SiS_P3c4,j,SiS_Pr->CCRT1CRTC[i]);
-     }
-
-     temp = SiS_Pr->CCRT1CRTC[16] & 0xE0;
-     SiS_SetReg(SiS_Pr->SiS_P3c4,0x0E,temp);
-
-     temp = (SiS_Pr->CCRT1CRTC[16] & 0x01) << 5;
-     if(modeflag & DoubleScanMode) temp |= 0x80;
-     SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0x5F,temp);
-
-  } else {
-
-     if(ModeNo <= 0x13) {
-        modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-     } else {
-        modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-     }
-
-     index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
-
-     for(i=0,j=0;i<=7;i++,j++) {
-        SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->SiS_CRT1Table[index].CR[i]);
-     }
-     for(j=0x10;i<=10;i++,j++) {
-        SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->SiS_CRT1Table[index].CR[i]);
-     }
-     for(j=0x15;i<=12;i++,j++) {
-        SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->SiS_CRT1Table[index].CR[i]);
-     }
-     for(j=0x0A;i<=15;i++,j++) {
-        SiS_SetReg(SiS_Pr->SiS_P3c4,j,SiS_Pr->SiS_CRT1Table[index].CR[i]);
-     }
-
-     temp = SiS_Pr->SiS_CRT1Table[index].CR[16] & 0xE0;
-     SiS_SetReg(SiS_Pr->SiS_P3c4,0x0E,temp);
-
-     temp = ((SiS_Pr->SiS_CRT1Table[index].CR[16]) & 0x01) << 5;
-     if(modeflag & DoubleScanMode)  temp |= 0x80;
-     SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0x5F,temp);
-
-  }
-
-  if(SiS_Pr->SiS_ModeType > ModeVGA) SiS_SetReg(SiS_Pr->SiS_P3d4,0x14,0x4F);
+   unsigned short temp, i, j, modeflag;
+   unsigned char  *crt1data = NULL;
+
+   modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
+
+   if(SiS_Pr->UseCustomMode) {
+
+      crt1data = &SiS_Pr->CCRT1CRTC[0];
+
+   } else {
+
+      temp = SiS_GetRefCRT1CRTC(SiS_Pr, RRTI, SiS_Pr->SiS_UseWide);
+
+      /* Alternate for 1600x1200 LCDA */
+      if((temp == 0x20) && (SiS_Pr->Alternate1600x1200)) temp = 0x57;
+
+      crt1data = (unsigned char *)&SiS_Pr->SiS_CRT1Table[temp].CR[0];
+
+   }
+
+   /* unlock cr0-7 */
+   SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
+
+   for(i = 0, j = 0; i <= 7; i++, j++) {
+      SiS_SetReg(SiS_Pr->SiS_P3d4,j,crt1data[i]);
+   }
+   for(j = 0x10; i <= 10; i++, j++) {
+      SiS_SetReg(SiS_Pr->SiS_P3d4,j,crt1data[i]);
+   }
+   for(j = 0x15; i <= 12; i++, j++) {
+      SiS_SetReg(SiS_Pr->SiS_P3d4,j,crt1data[i]);
+   }
+   for(j = 0x0A; i <= 15; i++, j++) {
+      SiS_SetReg(SiS_Pr->SiS_P3c4,j,crt1data[i]);
+   }
+
+   SiS_SetReg(SiS_Pr->SiS_P3c4,0x0E,crt1data[16] & 0xE0);
+
+   temp = (crt1data[16] & 0x01) << 5;
+   if(modeflag & DoubleScanMode) temp |= 0x80;
+   SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0x5F,temp);
+
+   if(SiS_Pr->SiS_ModeType > ModeVGA) {
+      SiS_SetReg(SiS_Pr->SiS_P3d4,0x14,0x4F);
+   }
+
+#ifdef SIS315H
+   if(SiS_Pr->ChipType == XGI_20) {
+      SiS_SetReg(SiS_Pr->SiS_P3d4,0x04,crt1data[4] - 1);
+      if(!(temp = crt1data[5] & 0x1f)) {
+         SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x0c,0xfb);
+      }
+      SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x05,0xe0,((temp - 1) & 0x1f));
+      temp = (crt1data[16] >> 5) + 3;
+      if(temp > 7) temp -= 7;
+      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0e,0x1f,(temp << 5));
+   }
+#endif
 }
 
 /*********************************************/
@@ -2359,33 +2153,32 @@ SiS_SetCRT1CRTC(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 /*********************************************/
 
 static void
-SiS_SetCRT1Offset(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
-                  USHORT RefreshRateTableIndex,
-                 PSIS_HW_INFO HwInfo)
+SiS_SetCRT1Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+               unsigned short ModeIdIndex, unsigned short RRTI)
 {
-   USHORT temp, DisplayUnit, infoflag;
+   unsigned short temp, DisplayUnit, infoflag;
 
    if(SiS_Pr->UseCustomMode) {
       infoflag = SiS_Pr->CInfoFlag;
    } else {
-      infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+      infoflag = SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag;
    }
 
-   DisplayUnit = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,
-                              RefreshRateTableIndex,HwInfo);
+   DisplayUnit = SiS_GetOffset(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
 
    temp = (DisplayUnit >> 8) & 0x0f;
    SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0xF0,temp);
 
-   temp = DisplayUnit & 0xFF;
-   SiS_SetReg(SiS_Pr->SiS_P3d4,0x13,temp);
+   SiS_SetReg(SiS_Pr->SiS_P3d4,0x13,DisplayUnit & 0xFF);
 
    if(infoflag & InterlaceMode) DisplayUnit >>= 1;
 
    DisplayUnit <<= 5;
-   temp = (DisplayUnit & 0xff00) >> 8;
+   temp = (DisplayUnit >> 8) + 1;
    if(DisplayUnit & 0xff) temp++;
-   temp++;
+   if(SiS_Pr->ChipType == XGI_20) {
+      if(ModeNo == 0x4a || ModeNo == 0x49) temp--;
+   }
    SiS_SetReg(SiS_Pr->SiS_P3c4,0x10,temp);
 }
 
@@ -2394,39 +2187,49 @@ SiS_SetCRT1Offset(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 /*********************************************/
 
 static void
-SiS_SetCRT1VCLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
-                PSIS_HW_INFO HwInfo, USHORT RefreshRateTableIndex)
+SiS_SetCRT1VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+               unsigned short ModeIdIndex, unsigned short RRTI)
 {
-  USHORT  index=0, clka, clkb;
-
-  if(SiS_Pr->UseCustomMode) {
-     clka = SiS_Pr->CSR2B;
-     clkb = SiS_Pr->CSR2C;
-  } else {
-     index = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
-     if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
-        clka = SiS_Pr->SiS_VBVCLKData[index].Part4_A;
-       clkb = SiS_Pr->SiS_VBVCLKData[index].Part4_B;
-     } else {
-        clka = SiS_Pr->SiS_VCLKData[index].SR2B;
-       clkb = SiS_Pr->SiS_VCLKData[index].SR2C;
-     }
-  }
-
-  if(HwInfo->jChipType >= SIS_315H) {
-     SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x31,0xCF);
-  } else {
-     SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x00);
-  }
-
-  SiS_SetReg(SiS_Pr->SiS_P3c4,0x2B,clka);
-  SiS_SetReg(SiS_Pr->SiS_P3c4,0x2C,clkb);
-
-  if(HwInfo->jChipType >= SIS_315H) {
-     SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x01);
-  } else {
-     SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x80);
-  }
+   unsigned short index = 0, clka, clkb;
+
+   if(SiS_Pr->UseCustomMode) {
+      clka = SiS_Pr->CSR2B;
+      clkb = SiS_Pr->CSR2C;
+   } else {
+      index = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
+      if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) &&
+        (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+        /* Alternate for 1600x1200 LCDA */
+        if((index == 0x21) && (SiS_Pr->Alternate1600x1200)) index = 0x72;
+        clka = SiS_Pr->SiS_VBVCLKData[index].Part4_A;
+        clkb = SiS_Pr->SiS_VBVCLKData[index].Part4_B;
+      } else {
+        clka = SiS_Pr->SiS_VCLKData[index].SR2B;
+        clkb = SiS_Pr->SiS_VCLKData[index].SR2C;
+      }
+   }
+
+   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x31,0xCF);
+
+   SiS_SetReg(SiS_Pr->SiS_P3c4,0x2b,clka);
+   SiS_SetReg(SiS_Pr->SiS_P3c4,0x2c,clkb);
+
+   if(SiS_Pr->ChipType >= SIS_315H) {
+#ifdef SIS315H
+      SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x01);
+      if(SiS_Pr->ChipType == XGI_20) {
+         unsigned short mf = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
+        if(mf & HalfDCLK) {
+           SiS_SetReg(SiS_Pr->SiS_P3c4,0x2b,SiS_GetReg(SiS_Pr->SiS_P3c4,0x2b));
+           clkb = SiS_GetReg(SiS_Pr->SiS_P3c4,0x2c);
+           clkb = (((clkb & 0x1f) << 1) + 1) | (clkb & 0xe0);
+           SiS_SetReg(SiS_Pr->SiS_P3c4,0x2c,clkb);
+        }
+      }
+#endif
+   } else {
+      SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x80);
+   }
 }
 
 /*********************************************/
@@ -2434,802 +2237,730 @@ SiS_SetCRT1VCLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 /*********************************************/
 
 #ifdef SIS300
-static USHORT
-SiS_DoCalcDelay(SiS_Private *SiS_Pr, USHORT MCLK, USHORT VCLK, USHORT colordepth, USHORT key)
+void
+SiS_GetFIFOThresholdIndex300(struct SiS_Private *SiS_Pr, unsigned short *idx1,
+               unsigned short *idx2)
 {
-  const UCHAR ThLowA[]   = { 61, 3,52, 5,68, 7,100,11,
-                             43, 3,42, 5,54, 7, 78,11,
-                             34, 3,37, 5,47, 7, 67,11 };
-
-  const UCHAR ThLowB[]   = { 81, 4,72, 6,88, 8,120,12,
-                             55, 4,54, 6,66, 8, 90,12,
-                             42, 4,45, 6,55, 8, 75,12 };
-
-  const UCHAR ThTiming[] = {  1, 2, 2, 3, 0, 1,  1, 2 };
-
-  USHORT tempah, tempal, tempcl, tempbx, temp;
-  ULONG  longtemp;
-
-  tempah = SiS_GetReg(SiS_Pr->SiS_P3c4,0x18);
-  tempah &= 0x62;
-  tempah >>= 1;
-  tempal = tempah;
-  tempah >>= 3;
-  tempal |= tempah;
-  tempal &= 0x07;
-  tempcl = ThTiming[tempal];
-  tempbx = SiS_GetReg(SiS_Pr->SiS_P3c4,0x16);
-  tempbx >>= 6;
-  tempah = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
-  tempah >>= 4;
-  tempah &= 0x0c;
-  tempbx |= tempah;
-  tempbx <<= 1;
-  if(key == 0) {
-     tempal = ThLowA[tempbx + 1];
-     tempal *= tempcl;
-     tempal += ThLowA[tempbx];
-  } else {
-     tempal = ThLowB[tempbx + 1];
-     tempal *= tempcl;
-     tempal += ThLowB[tempbx];
-  }
-  longtemp = tempal * VCLK * colordepth;
-  temp = longtemp % (MCLK * 16);
-  longtemp /= (MCLK * 16);
-  if(temp) longtemp++;
-  return((USHORT)longtemp);
+   unsigned short temp1, temp2;
+   static const unsigned char ThTiming[8] = {
+               1, 2, 2, 3, 0, 1, 1, 2
+   };
+
+   temp1 = temp2 = (SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x62) >> 1;
+   (*idx2) = (unsigned short)(ThTiming[((temp2 >> 3) | temp1) & 0x07]);
+   (*idx1) = (unsigned short)(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) >> 6) & 0x03;
+   (*idx1) |= (unsigned short)(((SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) >> 4) & 0x0c));
+   (*idx1) <<= 1;
 }
 
-static USHORT
-SiS_CalcDelay(SiS_Private *SiS_Pr, USHORT VCLK, USHORT colordepth, USHORT MCLK)
+static unsigned short
+SiS_GetFIFOThresholdA300(unsigned short idx1, unsigned short idx2)
 {
-  USHORT tempax, tempbx;
-
-  tempbx = SiS_DoCalcDelay(SiS_Pr, MCLK, VCLK, colordepth, 0);
-  tempax = SiS_DoCalcDelay(SiS_Pr, MCLK, VCLK, colordepth, 1);
-  if(tempax < 4) tempax = 4;
-  tempax -= 4;
-  if(tempbx < tempax) tempbx = tempax;
-  return(tempbx);
-}
+   static const unsigned char ThLowA[8 * 3] = {
+               61, 3,52, 5,68, 7,100,11,
+               43, 3,42, 5,54, 7, 78,11,
+               34, 3,37, 5,47, 7, 67,11
+   };
 
-static void
-SiS_SetCRT1FIFO_300(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_INFO HwInfo,
-                    USHORT RefreshRateTableIndex)
-{
-  USHORT  ThresholdLow = 0;
-  USHORT  index, VCLK, MCLK, colorth=0;
-  USHORT  tempah, temp;
-
-  if(ModeNo > 0x13) {
-
-     if(SiS_Pr->UseCustomMode) {
-        VCLK = SiS_Pr->CSRClock;
-     } else {
-        index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
-        index &= 0x3F;
-        VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;             /* Get VCLK  */
-     }
-
-     switch (SiS_Pr->SiS_ModeType - ModeEGA) {     /* Get half colordepth */
-        case 0 : colorth = 1; break;
-        case 1 : colorth = 1; break;
-        case 2 : colorth = 2; break;
-        case 3 : colorth = 2; break;
-        case 4 : colorth = 3; break;
-        case 5 : colorth = 4; break;
-     }
-
-     index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A);
-     index &= 0x07;
-     MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;           /* Get MCLK  */
-
-     tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
-     tempah &= 0xc3;
-     SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x16,0x3c,tempah);
-
-     do {
-        ThresholdLow = SiS_CalcDelay(SiS_Pr, VCLK, colorth, MCLK);
-        ThresholdLow++;
-        if(ThresholdLow < 0x13) break;
-        SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x16,0xfc);
-        ThresholdLow = 0x13;
-        tempah = SiS_GetReg(SiS_Pr->SiS_P3c4,0x16);
-        tempah >>= 6;
-        if(!(tempah)) break;
-        tempah--;
-        tempah <<= 6;
-        SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x16,0x3f,tempah);
-     } while(0);
-
-  } else ThresholdLow = 2;
-
-  /* Write CRT/CPU threshold low, CRT/Engine threshold high */
-  temp = (ThresholdLow << 4) | 0x0f;
-  SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,temp);
-
-  temp = (ThresholdLow & 0x10) << 1;
-  if(ModeNo > 0x13) temp |= 0x40;
-  SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0f,0x9f,temp);
-
-  /* What is this? */
-  SiS_SetReg(SiS_Pr->SiS_P3c4,0x3B,0x09);
-
-  /* Write CRT/CPU threshold high */
-  temp = ThresholdLow + 3;
-  if(temp > 0x0f) temp = 0x0f;
-  SiS_SetReg(SiS_Pr->SiS_P3c4,0x09,temp);
+   return (unsigned short)((ThLowA[idx1 + 1] * idx2) + ThLowA[idx1]);
 }
 
-static USHORT
-SiS_CalcDelay2(SiS_Private *SiS_Pr, UCHAR key, PSIS_HW_INFO HwInfo)
+unsigned short
+SiS_GetFIFOThresholdB300(unsigned short idx1, unsigned short idx2)
 {
-  USHORT data,index;
-  const UCHAR  LatencyFactor[] = {
-       97, 88, 86, 79, 77, 00,       /*; 64  bit    BQ=2   */
-        00, 87, 85, 78, 76, 54,       /*; 64  bit    BQ=1   */
-        97, 88, 86, 79, 77, 00,       /*; 128 bit    BQ=2   */
-        00, 79, 77, 70, 68, 48,       /*; 128 bit    BQ=1   */
-        80, 72, 69, 63, 61, 00,       /*; 64  bit    BQ=2   */
-        00, 70, 68, 61, 59, 37,       /*; 64  bit    BQ=1   */
-        86, 77, 75, 68, 66, 00,       /*; 128 bit    BQ=2   */
-        00, 68, 66, 59, 57, 37        /*; 128 bit    BQ=1   */
-  };
-  const UCHAR  LatencyFactor730[] = {
-         69, 63, 61,
-        86, 79, 77,
-       103, 96, 94,
-       120,113,111,
-       137,130,128,    /* --- Table ends with this entry, data below */
-       137,130,128,    /* to avoid using illegal values              */
-       137,130,128,
-       137,130,128,
-       137,130,128,
-       137,130,128,
-       137,130,128,
-       137,130,128,
-       137,130,128,
-       137,130,128,
-       137,130,128,
-       137,130,128,
-  };
-
-  if(HwInfo->jChipType == SIS_730) {
-     index = ((key & 0x0f) * 3) + ((key & 0xC0) >> 6);
-     data = LatencyFactor730[index];
-  } else {
-     index = (key & 0xE0) >> 5;
-     if(key & 0x10) index +=6;
-     if(!(key & 0x01)) index += 24;
-     data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
-     if(data & 0x0080) index += 12;
-     data = LatencyFactor[index];
-  }
-  return(data);
+   static const unsigned char ThLowB[8 * 3] = {
+               81, 4,72, 6,88, 8,120,12,
+               55, 4,54, 6,66, 8, 90,12,
+               42, 4,45, 6,55, 8, 75,12
+   };
+
+   return (unsigned short)((ThLowB[idx1 + 1] * idx2) + ThLowB[idx1]);
 }
 
-static void
-SiS_SetCRT1FIFO_630(SiS_Private *SiS_Pr, USHORT ModeNo,
-                   PSIS_HW_INFO HwInfo,
-                    USHORT RefreshRateTableIndex)
+static unsigned short
+SiS_DoCalcDelay(struct SiS_Private *SiS_Pr, unsigned short MCLK, unsigned short VCLK,
+               unsigned short colordepth, unsigned short key)
 {
-  USHORT  i,index,data,VCLK,MCLK,colorth=0;
-  ULONG   B,eax,bl,data2;
-  USHORT  ThresholdLow=0;
-  UCHAR   FQBQData[]= {
-       0x01,0x21,0x41,0x61,0x81,
-        0x31,0x51,0x71,0x91,0xb1,
-        0x00,0x20,0x40,0x60,0x80,
-        0x30,0x50,0x70,0x90,0xb0,
-       0xFF
-  };
-  UCHAR   FQBQData730[]= {
-        0x34,0x74,0xb4,
-       0x23,0x63,0xa3,
-       0x12,0x52,0x92,
-       0x01,0x41,0x81,
-       0x00,0x40,0x80,
-       0xff
-  };
-
-  i=0;
-  if(ModeNo > 0x13) {
-    if(SiS_Pr->UseCustomMode) {
-       VCLK = SiS_Pr->CSRClock;
-    } else {
-       index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
-       index &= 0x3F;
-       VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;          /* Get VCLK  */
-    }
-
-    index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A);
-    index &= 0x07;
-    MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;           /* Get MCLK  */
-
-    data2 = SiS_Pr->SiS_ModeType - ModeEGA;      /* Get half colordepth */
-    switch (data2) {
-        case 0 : colorth = 1; break;
-        case 1 : colorth = 1; break;
-        case 2 : colorth = 2; break;
-        case 3 : colorth = 2; break;
-        case 4 : colorth = 3; break;
-        case 5 : colorth = 4; break;
-    }
-
-    if(HwInfo->jChipType == SIS_730) {
-
-       do {
-          B = SiS_CalcDelay2(SiS_Pr, FQBQData730[i], HwInfo) * VCLK * colorth;
-         bl = B / (MCLK * 16);
-
-          if(B == bl * 16 * MCLK) {
-             bl = bl + 1;
-          } else {
-             bl = bl + 2;
-          }
-
-          if(bl > 0x13) {
-             if(FQBQData730[i+1] == 0xFF) {
-                ThresholdLow = 0x13;
-                break;
-             }
-             i++;
-          } else {
-             ThresholdLow = bl;
-             break;
-          }
-       } while(FQBQData730[i] != 0xFF);
+   unsigned short idx1, idx2;
+   unsigned int   longtemp = VCLK * colordepth;
 
-    } else {
+   SiS_GetFIFOThresholdIndex300(SiS_Pr, &idx1, &idx2);
 
-       do {
-          B = SiS_CalcDelay2(SiS_Pr, FQBQData[i], HwInfo) * VCLK * colorth;
-          bl = B / (MCLK * 16);
+   if(key == 0) {
+      longtemp *= SiS_GetFIFOThresholdA300(idx1, idx2);
+   } else {
+      longtemp *= SiS_GetFIFOThresholdB300(idx1, idx2);
+   }
+   idx1 = longtemp % (MCLK * 16);
+   longtemp /= (MCLK * 16);
+   if(idx1) longtemp++;
+   return (unsigned short)longtemp;
+}
 
-          if(B == bl * 16 * MCLK) {
-             bl = bl + 1;
-          } else {
-             bl = bl + 2;
-          }
+static unsigned short
+SiS_CalcDelay(struct SiS_Private *SiS_Pr, unsigned short VCLK,
+               unsigned short colordepth, unsigned short MCLK)
+{
+   unsigned short temp1, temp2;
+
+   temp2 = SiS_DoCalcDelay(SiS_Pr, MCLK, VCLK, colordepth, 0);
+   temp1 = SiS_DoCalcDelay(SiS_Pr, MCLK, VCLK, colordepth, 1);
+   if(temp1 < 4) temp1 = 4;
+   temp1 -= 4;
+   if(temp2 < temp1) temp2 = temp1;
+   return temp2;
+}
 
-          if(bl > 0x13) {
-             if(FQBQData[i+1] == 0xFF) {
-                ThresholdLow = 0x13;
-                break;
-             }
-             i++;
-          } else {
-             ThresholdLow = bl;
-             break;
-          }
-       } while(FQBQData[i] != 0xFF);
-    }
-  }
-  else {
-    if(HwInfo->jChipType == SIS_730) {
-    } else {
-      i = 9;
-    }
-    ThresholdLow = 0x02;
-  }
+static void
+SiS_SetCRT1FIFO_300(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+               unsigned short RefreshRateTableIndex)
+{
+   unsigned short ThresholdLow = 0;
+   unsigned short temp, index, VCLK, MCLK, colorth;
+   static const unsigned short colortharray[6] = { 1, 1, 2, 2, 3, 4 };
 
-  /* Write foreground and background queue */
-  if(HwInfo->jChipType == SIS_730) {
-
-     data2 = FQBQData730[i];
-     data2 = (data2 & 0xC0) >> 5;
-     data2 <<= 8;
-
-#ifdef LINUX_KERNEL
-     SiS_SetRegLong(0xcf8,0x80000050);
-     eax = SiS_GetRegLong(0xcfc);
-     eax &= 0xfffff9ff;
-     eax |= data2;
-     SiS_SetRegLong(0xcfc,eax);
-#else
-     /* We use pci functions X offers. We use pcitag 0, because
-      * we want to read/write to the host bridge (which is always
-      * 00:00.0 on 630, 730 and 540), not the VGA device.
-      */
-     eax = pciReadLong(0x00000000, 0x50);
-     eax &= 0xfffff9ff;
-     eax |= data2;
-     pciWriteLong(0x00000000, 0x50, eax);
-#endif
+   if(ModeNo > 0x13) {
 
-     /* Write GUI grant timer (PCI config 0xA3) */
-     data2 = FQBQData730[i] << 8;
-     data2 = (data2 & 0x0f00) | ((data2 & 0x3000) >> 8);
-     data2 <<= 20;
-
-#ifdef LINUX_KERNEL
-     SiS_SetRegLong(0xcf8,0x800000A0);
-     eax = SiS_GetRegLong(0xcfc);
-     eax &= 0x00ffffff;
-     eax |= data2;
-     SiS_SetRegLong(0xcfc,eax);
-#else
-     eax = pciReadLong(0x00000000, 0xA0);
-     eax &= 0x00ffffff;
-     eax |= data2;
-     pciWriteLong(0x00000000, 0xA0, eax);
-#endif
+      /* Get VCLK  */
+      if(SiS_Pr->UseCustomMode) {
+        VCLK = SiS_Pr->CSRClock;
+      } else {
+        index = SiS_GetRefCRTVCLK(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWide);
+        VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
+      }
 
-  } else {
+      /* Get half colordepth */
+      colorth = colortharray[(SiS_Pr->SiS_ModeType - ModeEGA)];
 
-     data2 = FQBQData[i];
-     data2 = (data2 & 0xf0) >> 4;
-     data2 <<= 24;
+      /* Get MCLK  */
+      index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A) & 0x07;
+      MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;
 
-#ifdef LINUX_KERNEL
-     SiS_SetRegLong(0xcf8,0x80000050);
-     eax = SiS_GetRegLong(0xcfc);
-     eax &= 0xf0ffffff;
-     eax |= data2;
-     SiS_SetRegLong(0xcfc,eax);
-#else
-     eax = pciReadLong(0x00000000, 0x50);
-     eax &= 0xf0ffffff;
-     eax |= data2;
-     pciWriteLong(0x00000000, 0x50, eax);
-#endif
+      temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xc3;
+      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x16,0x3c,temp);
 
-     /* Write GUI grant timer (PCI config 0xA3) */
-     data2 = FQBQData[i];
-     data2 &= 0x0f;
-     data2 <<= 24;
-
-#ifdef LINUX_KERNEL
-     SiS_SetRegLong(0xcf8,0x800000A0);
-     eax = SiS_GetRegLong(0xcfc);
-     eax &= 0xf0ffffff;
-     eax |= data2;
-     SiS_SetRegLong(0xcfc,eax);
-#else
-     eax = pciReadLong(0x00000000, 0xA0);
-     eax &= 0xf0ffffff;
-     eax |= data2;
-     pciWriteLong(0x00000000, 0xA0, eax);
-#endif
+      do {
+        ThresholdLow = SiS_CalcDelay(SiS_Pr, VCLK, colorth, MCLK) + 1;
+        if(ThresholdLow < 0x13) break;
+        SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x16,0xfc);
+        ThresholdLow = 0x13;
+        temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) >> 6;
+        if(!temp) break;
+        SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x16,0x3f,((temp - 1) << 6));
+      } while(0);
 
-  }
+   } else ThresholdLow = 2;
 
-  /* Write CRT/CPU threshold low, CRT/Engine threshold high */
-  data = ((ThresholdLow & 0x0f) << 4) | 0x0f;
-  SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,data);
+   /* Write CRT/CPU threshold low, CRT/Engine threshold high */
+   temp = (ThresholdLow << 4) | 0x0f;
+   SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,temp);
 
-  data = (ThresholdLow & 0x10) << 1;
-  SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xDF,data);
+   temp = (ThresholdLow & 0x10) << 1;
+   if(ModeNo > 0x13) temp |= 0x40;
+   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0f,0x9f,temp);
 
-  /* What is this? */
-  SiS_SetReg(SiS_Pr->SiS_P3c4,0x3B,0x09);
+   /* What is this? */
+   SiS_SetReg(SiS_Pr->SiS_P3c4,0x3B,0x09);
 
-  /* Write CRT/CPU threshold high (gap = 3) */
-  data = ThresholdLow + 3;
-  if(data > 0x0f) data = 0x0f;
-  SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x09,0x80,data);
+   /* Write CRT/CPU threshold high */
+   temp = ThresholdLow + 3;
+   if(temp > 0x0f) temp = 0x0f;
+   SiS_SetReg(SiS_Pr->SiS_P3c4,0x09,temp);
 }
-#endif
 
-#ifdef SIS315H
-static void
-SiS_SetCRT1FIFO_310(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
-                    PSIS_HW_INFO HwInfo)
+unsigned short
+SiS_GetLatencyFactor630(struct SiS_Private *SiS_Pr, unsigned short index)
 {
-  USHORT modeflag;
-
-  /* disable auto-threshold */
-  SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x3D,0xFE);
-
-  if(SiS_Pr->UseCustomMode) {
-     modeflag = SiS_Pr->CModeFlag;
-  } else {
-     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-  }
-
-  SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0xAE);
-  SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x09,0xF0);
-  if(ModeNo > 0x13) {
-     if(HwInfo->jChipType >= SIS_661) {
-        if(!(modeflag & HalfDCLK)) {
-          SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0x34);
-          SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x3D,0x01);
-       }
-     } else {
-        if((!(modeflag & DoubleScanMode)) || (!(modeflag & HalfDCLK))) {
-           SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0x34);
-           SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x3D,0x01);
-       }
-     }
-  }
+   static const unsigned char LatencyFactor[] = {
+               97, 88, 86, 79, 77,  0,       /* 64  bit    BQ=2   */
+                0, 87, 85, 78, 76, 54,       /* 64  bit    BQ=1   */
+               97, 88, 86, 79, 77,  0,       /* 128 bit    BQ=2   */
+                0, 79, 77, 70, 68, 48,       /* 128 bit    BQ=1   */
+               80, 72, 69, 63, 61,  0,       /* 64  bit    BQ=2   */
+                0, 70, 68, 61, 59, 37,       /* 64  bit    BQ=1   */
+               86, 77, 75, 68, 66,  0,       /* 128 bit    BQ=2   */
+                0, 68, 66, 59, 57, 37        /* 128 bit    BQ=1   */
+   };
+   static const unsigned char LatencyFactor730[] = {
+                69, 63, 61,
+                86, 79, 77,
+               103, 96, 94,
+               120,113,111,
+               137,130,128
+   };
+
+   if(SiS_Pr->ChipType == SIS_730) {
+      return (unsigned short)LatencyFactor730[index];
+   } else {
+      return (unsigned short)LatencyFactor[index];
+   }
 }
-#endif
 
-/*********************************************/
-/*              MODE REGISTERS               */
-/*********************************************/
+static unsigned short
+SiS_CalcDelay2(struct SiS_Private *SiS_Pr, unsigned char key)
+{
+   unsigned short index;
+
+   if(SiS_Pr->ChipType == SIS_730) {
+      index = ((key & 0x0f) * 3) + ((key & 0xc0) >> 6);
+   } else {
+      index = (key & 0xe0) >> 5;
+      if(key & 0x10)    index +=  6;
+      if(!(key & 0x01)) index += 24;
+      if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80) index += 12;
+   }
+   return SiS_GetLatencyFactor630(SiS_Pr, index);
+}
 
 static void
-SiS_SetVCLKState(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
-                 USHORT ModeNo, USHORT RefreshRateTableIndex,
-                 USHORT ModeIdIndex)
+SiS_SetCRT1FIFO_630(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+                    unsigned short RefreshRateTableIndex)
 {
-  USHORT data=0, VCLK=0, index=0;
+   unsigned short  ThresholdLow = 0;
+   unsigned short  i, data, VCLK, MCLK16, colorth = 0;
+   unsigned int    templ, datal;
+   const unsigned char *queuedata = NULL;
+   static const unsigned char FQBQData[21] = {
+               0x01,0x21,0x41,0x61,0x81,
+               0x31,0x51,0x71,0x91,0xb1,
+               0x00,0x20,0x40,0x60,0x80,
+               0x30,0x50,0x70,0x90,0xb0,
+               0xff
+   };
+   static const unsigned char FQBQData730[16] = {
+               0x34,0x74,0xb4,
+               0x23,0x63,0xa3,
+               0x12,0x52,0x92,
+               0x01,0x41,0x81,
+               0x00,0x40,0x80,
+               0xff
+   };
+   static const unsigned short colortharray[6] = {
+               1, 1, 2, 2, 3, 4
+   };
+
+   i = 0;
 
-  if(ModeNo > 0x13) {
-     if(SiS_Pr->UseCustomMode) {
-        VCLK = SiS_Pr->CSRClock;
-     } else {
-        index = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,
-                             RefreshRateTableIndex,HwInfo);
-        VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
-     }
-  }
+   if(ModeNo > 0x13) {
+
+      /* Get VCLK  */
+      if(SiS_Pr->UseCustomMode) {
+        VCLK = SiS_Pr->CSRClock;
+      } else {
+        data = SiS_GetRefCRTVCLK(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWide);
+        VCLK = SiS_Pr->SiS_VCLKData[data].CLOCK;
+      }
 
-  if(HwInfo->jChipType < SIS_315H) {
+      /* Get MCLK * 16 */
+      data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A) & 0x07;
+      MCLK16 = SiS_Pr->SiS_MCLKData_0[data].CLOCK * 16;
 
-     if(VCLK > 150) data |= 0x80;
-     SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0x7B,data);
+      /* Get half colordepth */
+      colorth = colortharray[(SiS_Pr->SiS_ModeType - ModeEGA)];
 
-     data = 0x00;
-     if(VCLK >= 150) data |= 0x08;
-     SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xF7,data);
+      if(SiS_Pr->ChipType == SIS_730) {
+        queuedata = &FQBQData730[0];
+      } else {
+        queuedata = &FQBQData[0];
+      }
 
-  } else {
+      do {
+        templ = SiS_CalcDelay2(SiS_Pr, queuedata[i]) * VCLK * colorth;
 
-     if(VCLK >= 166) data |= 0x0c;
-     SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xf3,data);
+        datal = templ % MCLK16;
+        templ = (templ / MCLK16) + 1;
+        if(datal) templ++;
 
-     if(VCLK >= 166) {
-        SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1f,0xe7);
-     }
-  }
+        if(templ > 0x13) {
+           if(queuedata[i + 1] == 0xFF) {
+              ThresholdLow = 0x13;
+              break;
+           }
+           i++;
+        } else {
+           ThresholdLow = templ;
+           break;
+        }
+      } while(queuedata[i] != 0xFF);
 
-  /* DAC speed */
-  if(HwInfo->jChipType >= SIS_661) {
+   } else {
 
-     SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xE8,0x10);
+      if(SiS_Pr->ChipType != SIS_730) i = 9;
+      ThresholdLow = 0x02;
 
-  } else {
+   }
 
-     data = 0x03;
-     if((VCLK >= 135) && (VCLK < 160))      data = 0x02;
-     else if((VCLK >= 160) && (VCLK < 260)) data = 0x01;
-     else if(VCLK >= 260)                   data = 0x00;
+   /* Write CRT/CPU threshold low, CRT/Engine threshold high */
+   data = ((ThresholdLow & 0x0f) << 4) | 0x0f;
+   SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,data);
 
-     if(HwInfo->jChipType == SIS_540) {
-        if((VCLK == 203) || (VCLK < 234))   data = 0x02;
-     }
+   data = (ThresholdLow & 0x10) << 1;
+   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xDF,data);
 
-     if(HwInfo->jChipType < SIS_315H) {
-        SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xFC,data);
-     } else {
-        if(HwInfo->jChipType > SIS_315PRO) {
-           if(ModeNo > 0x13) data &= 0xfc;
-        }
-        SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xF8,data);
-     }
+   /* What is this? */
+   SiS_SetReg(SiS_Pr->SiS_P3c4,0x3B,0x09);
 
-  }
-}
+   /* Write CRT/CPU threshold high (gap = 3) */
+   data = ThresholdLow + 3;
+   if(data > 0x0f) data = 0x0f;
+   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x09,0x80,data);
 
-static void
-SiS_SetCRT1ModeRegs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
-                    USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex)
-{
-  USHORT data,infoflag=0,modeflag;
-  USHORT resindex,xres;
-#ifdef SIS315H
-  USHORT data2,data3;
-  ULONG  longdata;
-  UCHAR  *ROMAddr  = HwInfo->pjVirtualRomBase;
+  /* Write foreground and background queue */
+#ifdef SIS_LINUX_KERNEL
+   templ = sisfb_read_nbridge_pci_dword(SiS_Pr, 0x50);
+#else
+   templ = pciReadLong(0x00000000, 0x50);
 #endif
 
-  if(SiS_Pr->UseCustomMode) {
-     modeflag = SiS_Pr->CModeFlag;
-     infoflag = SiS_Pr->CInfoFlag;
-     xres = SiS_Pr->CHDisplay;
-  } else {
-     resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex);
-     if(ModeNo > 0x13) {
-       modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-       infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
-       xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
-     } else {
-       modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-       xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
-     }
-  }
-
-  /* Disable DPMS */
-  SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1F,0x3F);
-
-  data = 0;
-  if(ModeNo > 0x13) {
-     if(SiS_Pr->SiS_ModeType > ModeEGA) {
-        data |= 0x02;
-        data |= ((SiS_Pr->SiS_ModeType - ModeVGA) << 2);
-     }
-     if(infoflag & InterlaceMode) data |= 0x20;
-  }
-  SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x06,0xC0,data);
-
-  if(HwInfo->jChipType != SIS_300) {
-     data = 0;
-     if(infoflag & InterlaceMode) {
-        if(xres <= 800)       data = 0x0020;
-        else if(xres <= 1024) data = 0x0035;
-        else                  data = 0x0048;
-     }
-     SiS_SetReg(SiS_Pr->SiS_P3d4,0x19,(data & 0xFF));
-     SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x1a,0xFC,(data >> 8));
-  }
-
-  if(modeflag & HalfDCLK) {
-     SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x01,0x08);
-  }
-
-  data = 0;
-  if(modeflag & LineCompareOff) data = 0x08;
-  if(HwInfo->jChipType == SIS_300) {
-     SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xF7,data);
-  } else {
-     SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xB7,data);
-     if(SiS_Pr->SiS_ModeType == ModeEGA) {
-        if(ModeNo > 0x13) {
-          SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x0F,0x40);
-        }
-     }
-  }
-
-  if(HwInfo->jChipType >= SIS_661) {
-     SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x31,0xfb);
-  }
+   if(SiS_Pr->ChipType == SIS_730) {
 
-#ifdef SIS315H
-  if(HwInfo->jChipType == SIS_315PRO) {
-
-     data = SiS_Get310DRAMType(SiS_Pr, HwInfo);
-     data = SiS_Pr->SiS_SR15[2][data];
-     if(SiS_Pr->SiS_ModeType == ModeText) {
-        data &= 0xc7;
-     } else {
-        data2 = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,
-                              RefreshRateTableIndex,HwInfo);
-       data2 >>= 1;
-       if(infoflag & InterlaceMode) data2 >>= 1;
-       data3 = SiS_GetColorDepth(SiS_Pr,ModeNo,ModeIdIndex) >> 1;
-       if(!data3) data3++;
-       data2 /= data3;
-       if(data2 >= 0x50) {
-          data &= 0x0f;
-          data |= 0x50;
-       }
-     }
-     SiS_SetReg(SiS_Pr->SiS_P3c4,0x17,data);
-
-  } else if( (HwInfo->jChipType == SIS_330) ||
-             ((HwInfo->jChipType == SIS_760) && (SiS_Pr->SiS_SysFlags & SF_760LFB))) {
-
-     data = SiS_Get310DRAMType(SiS_Pr, HwInfo);
-     if(HwInfo->jChipType == SIS_330) {
-        data = SiS_Pr->SiS_SR15[2][data];
-     } else {
-        if(SiS_Pr->SiS_ROMNew)             data = ROMAddr[0xf6];
-        else if(SiS_Pr->SiS_UseROM) data = ROMAddr[0x100 + data];
-       else                        data = 0xba;
-     }
-     if(SiS_Pr->SiS_ModeType <= ModeEGA) {
-        data &= 0xc7;
-     } else {
-        if(SiS_Pr->UseCustomMode) {
-          data2 = SiS_Pr->CSRClock;
-       } else {
-           data2 = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,
-                                   RefreshRateTableIndex,HwInfo);
-           data2 = SiS_Pr->SiS_VCLKData[data2].CLOCK;
-       }
+      templ &= 0xfffff9ff;
+      templ |= ((queuedata[i] & 0xc0) << 3);
 
-       data3 = SiS_GetColorDepth(SiS_Pr,ModeNo,ModeIdIndex) >> 1;
-       if(data3) data2 *= data3;
-
-       longdata = SiS_GetMCLK(SiS_Pr, HwInfo) * 1024;
-
-       data2 = longdata / data2;
-
-       if(HwInfo->jChipType == SIS_330) {
-          if(SiS_Pr->SiS_ModeType != Mode16Bpp) {
-              if     (data2 >= 0x19c) data = 0xba;
-             else if(data2 >= 0x140) data = 0x7a;
-             else if(data2 >= 0x101) data = 0x3a;
-             else if(data2 >= 0xf5)  data = 0x32;
-             else if(data2 >= 0xe2)  data = 0x2a;
-             else if(data2 >= 0xc4)  data = 0x22;
-             else if(data2 >= 0xac)  data = 0x1a;
-             else if(data2 >= 0x9e)  data = 0x12;
-             else if(data2 >= 0x8e)  data = 0x0a;
-             else                    data = 0x02;
-          } else {
-             if(data2 >= 0x127)      data = 0xba;
-             else                    data = 0x7a;
-          }
-       } else {  /* 760+LFB */
-          if     (data2 >= 0x190) data = 0xba;
-          else if(data2 >= 0xff)  data = 0x7a;
-          else if(data2 >= 0xd3)  data = 0x3a;
-          else if(data2 >= 0xa9)  data = 0x1a;
-          else if(data2 >= 0x93)  data = 0x0a;
-          else                    data = 0x02;
-       }
-     }
-     SiS_SetReg(SiS_Pr->SiS_P3c4,0x17,data);
-  } else if(HwInfo->jChipType == SIS_340) {
-     /* TODO */
-  }
+   } else {
+
+      templ &= 0xf0ffffff;
+      if( (ModeNo <= 0x13) &&
+          (SiS_Pr->ChipType == SIS_630) &&
+         (SiS_Pr->ChipRevision >= 0x30) ) {
+        templ |= 0x0b000000;
+      } else {
+         templ |= ((queuedata[i] & 0xf0) << 20);
+      }
+
+   }
+
+#ifdef SIS_LINUX_KERNEL
+   sisfb_write_nbridge_pci_dword(SiS_Pr, 0x50, templ);
+   templ = sisfb_read_nbridge_pci_dword(SiS_Pr, 0xA0);
+#else
+   pciWriteLong(0x00000000, 0x50, templ);
+   templ = pciReadLong(0x00000000, 0xA0);
 #endif
 
-  data = 0x60;
-  if(SiS_Pr->SiS_ModeType != ModeText) {
-     data ^= 0x60;
-     if(SiS_Pr->SiS_ModeType != ModeEGA) {
-        data ^= 0xA0;
-     }
-  }
-  SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x21,0x1F,data);
+   /* GUI grant timer (PCI config 0xA3) */
+   if(SiS_Pr->ChipType == SIS_730) {
 
-  SiS_SetVCLKState(SiS_Pr, HwInfo, ModeNo, RefreshRateTableIndex, ModeIdIndex);
+      templ &= 0x00ffffff;
+      datal = queuedata[i] << 8;
+      templ |= (((datal & 0x0f00) | ((datal & 0x3000) >> 8)) << 20);
 
-#ifdef SIS315H
-  if(HwInfo->jChipType >= SIS_315H) {
-     if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40) {
-        SiS_SetReg(SiS_Pr->SiS_P3d4,0x52,0x2c);
-     } else {
-        SiS_SetReg(SiS_Pr->SiS_P3d4,0x52,0x6c);
-     }
-  }
+   } else {
+
+      templ &= 0xf0ffffff;
+      templ |= ((queuedata[i] & 0x0f) << 24);
+
+   }
+
+#ifdef SIS_LINUX_KERNEL
+   sisfb_write_nbridge_pci_dword(SiS_Pr, 0xA0, templ);
+#else
+   pciWriteLong(0x00000000, 0xA0, templ);
 #endif
 }
+#endif /* SIS300 */
+
+#ifdef SIS315H
+static void
+SiS_SetCRT1FIFO_310(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
+{
+   unsigned short modeflag;
+
+   /* disable auto-threshold */
+   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x3D,0xFE);
+
+   modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
+
+   SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0xAE);
+   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x09,0xF0);
+   if(ModeNo > 0x13) {
+      if(SiS_Pr->ChipType >= XGI_20) {
+        SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0x34);
+        SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x3D,0x01);
+      } else if(SiS_Pr->ChipType >= SIS_661) {
+        if(!(modeflag & HalfDCLK)) {
+           SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0x34);
+           SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x3D,0x01);
+        }
+      } else {
+        if((!(modeflag & DoubleScanMode)) || (!(modeflag & HalfDCLK))) {
+           SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0x34);
+           SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x3D,0x01);
+        }
+      }
+   }
+}
+#endif
 
 /*********************************************/
-/*                 LOAD DAC                  */
+/*              MODE REGISTERS               */
 /*********************************************/
 
-#if 0
 static void
-SiS_ClearDAC(SiS_Private *SiS_Pr, ULONG port)
+SiS_SetVCLKState(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+               unsigned short RefreshRateTableIndex, unsigned short ModeIdIndex)
+{
+   unsigned short data = 0, VCLK = 0, index = 0;
+
+   if(ModeNo > 0x13) {
+      if(SiS_Pr->UseCustomMode) {
+         VCLK = SiS_Pr->CSRClock;
+      } else {
+         index = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
+         VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
+      }
+   }
+
+   if(SiS_Pr->ChipType < SIS_315H) {
+#ifdef SIS300
+      if(VCLK > 150) data |= 0x80;
+      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0x7B,data);
+
+      data = 0x00;
+      if(VCLK >= 150) data |= 0x08;
+      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xF7,data);
+#endif
+   } else if(SiS_Pr->ChipType < XGI_20) {
+#ifdef SIS315H
+      if(VCLK >= 166) data |= 0x0c;
+      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xf3,data);
+
+      if(VCLK >= 166) {
+         SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1f,0xe7);
+      }
+#endif
+   } else {
+#ifdef SIS315H
+      if(VCLK >= 200) data |= 0x0c;
+      if(SiS_Pr->ChipType == XGI_20) data &= ~0x04;
+      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xf3,data);
+      if(SiS_Pr->ChipType != XGI_20) {
+         data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xe7;
+        if(VCLK < 200) data |= 0x10;
+        SiS_SetReg(SiS_Pr->SiS_P3c4,0x1f,data);
+      }
+#endif
+   }
+
+   /* DAC speed */
+   if(SiS_Pr->ChipType >= SIS_661) {
+
+      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xE8,0x10);
+
+   } else {
+
+      data = 0x03;
+      if(VCLK >= 260)      data = 0x00;
+      else if(VCLK >= 160) data = 0x01;
+      else if(VCLK >= 135) data = 0x02;
+
+      if(SiS_Pr->ChipType == SIS_540) {
+         if((VCLK == 203) || (VCLK < 234)) data = 0x02;
+      }
+
+      if(SiS_Pr->ChipType < SIS_315H) {
+         SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xFC,data);
+      } else {
+         if(SiS_Pr->ChipType > SIS_315PRO) {
+            if(ModeNo > 0x13) data &= 0xfc;
+         }
+         SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xF8,data);
+      }
+
+   }
+}
+
+static void
+SiS_SetCRT1ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+               unsigned short ModeIdIndex, unsigned short RRTI)
+{
+   unsigned short data, infoflag = 0, modeflag, resindex;
+#ifdef SIS315H
+   unsigned char  *ROMAddr  = SiS_Pr->VirtualRomBase;
+   unsigned short data2, data3;
+#endif
+
+   modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
+
+   if(SiS_Pr->UseCustomMode) {
+      infoflag = SiS_Pr->CInfoFlag;
+   } else {
+      resindex = SiS_GetResInfo(SiS_Pr, ModeNo, ModeIdIndex);
+      if(ModeNo > 0x13) {
+        infoflag = SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag;
+      }
+   }
+
+   /* Disable DPMS */
+   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1F,0x3F);
+
+   data = 0;
+   if(ModeNo > 0x13) {
+      if(SiS_Pr->SiS_ModeType > ModeEGA) {
+         data |= 0x02;
+         data |= ((SiS_Pr->SiS_ModeType - ModeVGA) << 2);
+      }
+      if(infoflag & InterlaceMode) data |= 0x20;
+   }
+   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x06,0xC0,data);
+
+   if(SiS_Pr->ChipType != SIS_300) {
+      data = 0;
+      if(infoflag & InterlaceMode) {
+        /* data = (Hsync / 8) - ((Htotal / 8) / 2) + 3 */
+        int hrs = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x04) |
+                   ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x0b) & 0xc0) << 2)) - 3;
+        int hto = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x00) |
+                   ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x0b) & 0x03) << 8)) + 5;
+        data = hrs - (hto >> 1) + 3;
+      }
+      SiS_SetReg(SiS_Pr->SiS_P3d4,0x19,data);
+      SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x1a,0xFC,((data >> 8) & 0x03));
+   }
+
+   if(modeflag & HalfDCLK) {
+      SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x01,0x08);
+   }
+
+   data = 0;
+   if(modeflag & LineCompareOff) data = 0x08;
+   if(SiS_Pr->ChipType == SIS_300) {
+      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xF7,data);
+   } else {
+      if(SiS_Pr->ChipType >= XGI_20) data |= 0x20;
+      if(SiS_Pr->SiS_ModeType == ModeEGA) {
+        if(ModeNo > 0x13) {
+           data |= 0x40;
+        }
+      }
+      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xB7,data);
+   }
+
+#ifdef SIS315H
+   if(SiS_Pr->ChipType >= SIS_315H) {
+      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x31,0xfb);
+   }
+
+   if(SiS_Pr->ChipType == SIS_315PRO) {
+
+      data = SiS_Pr->SiS_SR15[(2 * 4) + SiS_Get310DRAMType(SiS_Pr)];
+      if(SiS_Pr->SiS_ModeType == ModeText) {
+        data &= 0xc7;
+      } else {
+        data2 = SiS_GetOffset(SiS_Pr, ModeNo, ModeIdIndex, RRTI) >> 1;
+        if(infoflag & InterlaceMode) data2 >>= 1;
+        data3 = SiS_GetColorDepth(SiS_Pr, ModeNo, ModeIdIndex) >> 1;
+        if(data3) data2 /= data3;
+        if(data2 >= 0x50) {
+           data &= 0x0f;
+           data |= 0x50;
+        }
+      }
+      SiS_SetReg(SiS_Pr->SiS_P3c4,0x17,data);
+
+   } else if((SiS_Pr->ChipType == SIS_330) || (SiS_Pr->SiS_SysFlags & SF_760LFB)) {
+
+      data = SiS_Get310DRAMType(SiS_Pr);
+      if(SiS_Pr->ChipType == SIS_330) {
+        data = SiS_Pr->SiS_SR15[(2 * 4) + data];
+      } else {
+        if(SiS_Pr->SiS_ROMNew)      data = ROMAddr[0xf6];
+        else if(SiS_Pr->SiS_UseROM) data = ROMAddr[0x100 + data];
+        else                        data = 0xba;
+      }
+      if(SiS_Pr->SiS_ModeType <= ModeEGA) {
+        data &= 0xc7;
+      } else {
+        if(SiS_Pr->UseCustomMode) {
+           data2 = SiS_Pr->CSRClock;
+        } else {
+           data2 = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
+           data2 = SiS_Pr->SiS_VCLKData[data2].CLOCK;
+        }
+
+        data3 = SiS_GetColorDepth(SiS_Pr, ModeNo, ModeIdIndex) >> 1;
+        if(data3) data2 *= data3;
+
+        data2 = ((unsigned int)(SiS_GetMCLK(SiS_Pr) * 1024)) / data2;
+
+        if(SiS_Pr->ChipType == SIS_330) {
+           if(SiS_Pr->SiS_ModeType != Mode16Bpp) {
+              if     (data2 >= 0x19c) data = 0xba;
+              else if(data2 >= 0x140) data = 0x7a;
+              else if(data2 >= 0x101) data = 0x3a;
+              else if(data2 >= 0xf5)  data = 0x32;
+              else if(data2 >= 0xe2)  data = 0x2a;
+              else if(data2 >= 0xc4)  data = 0x22;
+              else if(data2 >= 0xac)  data = 0x1a;
+              else if(data2 >= 0x9e)  data = 0x12;
+              else if(data2 >= 0x8e)  data = 0x0a;
+              else                    data = 0x02;
+           } else {
+              if(data2 >= 0x127)      data = 0xba;
+              else                    data = 0x7a;
+           }
+        } else {  /* 76x+LFB */
+           if     (data2 >= 0x190) data = 0xba;
+           else if(data2 >= 0xff)  data = 0x7a;
+           else if(data2 >= 0xd3)  data = 0x3a;
+           else if(data2 >= 0xa9)  data = 0x1a;
+           else if(data2 >= 0x93)  data = 0x0a;
+           else                    data = 0x02;
+        }
+      }
+      SiS_SetReg(SiS_Pr->SiS_P3c4,0x17,data);
+
+   }
+      /* XGI: Nothing. */
+      /* TODO: Check SiS340 */
+#endif
+
+   data = 0x60;
+   if(SiS_Pr->SiS_ModeType != ModeText) {
+      data ^= 0x60;
+      if(SiS_Pr->SiS_ModeType != ModeEGA) {
+         data ^= 0xA0;
+      }
+   }
+   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x21,0x1F,data);
+
+   SiS_SetVCLKState(SiS_Pr, ModeNo, RRTI, ModeIdIndex);
+
+#ifdef SIS315H
+   if(((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) ||
+       (SiS_Pr->ChipType == XGI_40)) {
+      if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40) {
+         SiS_SetReg(SiS_Pr->SiS_P3d4,0x52,0x2c);
+      } else {
+         SiS_SetReg(SiS_Pr->SiS_P3d4,0x52,0x6c);
+      }
+   } else if(SiS_Pr->ChipType == XGI_20) {
+      if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40) {
+         SiS_SetReg(SiS_Pr->SiS_P3d4,0x52,0x33);
+      } else {
+         SiS_SetReg(SiS_Pr->SiS_P3d4,0x52,0x73);
+      }
+      SiS_SetReg(SiS_Pr->SiS_P3d4,0x51,0x02);
+   }
+#endif
+}
+
+#ifdef SIS315H
+static void
+SiS_SetupDualChip(struct SiS_Private *SiS_Pr)
 {
+#if 0
+   /* TODO: Find out about IOAddress2 */
+   SISIOADDRESS P2_3c2 = SiS_Pr->IOAddress2 + 0x12;
+   SISIOADDRESS P2_3c4 = SiS_Pr->IOAddress2 + 0x14;
+   SISIOADDRESS P2_3ce = SiS_Pr->IOAddress2 + 0x1e;
    int i;
 
-   OutPortByte(port, 0);
-   port++;
-   for (i=0; i < (256 * 3); i++) {
-      OutPortByte(port, 0);
+   if((SiS_Pr->ChipRevision != 0) ||
+      (!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x3a) & 0x04)))
+      return;
+
+   for(i = 0; i <= 4; i++) {                                   /* SR00 - SR04 */
+      SiS_SetReg(P2_3c4,i,SiS_GetReg(SiS_Pr->SiS_P3c4,i));
    }
+   for(i = 0; i <= 8; i++) {                                   /* GR00 - GR08 */
+      SiS_SetReg(P2_3ce,i,SiS_GetReg(SiS_Pr->SiS_P3ce,i));
+   }
+   SiS_SetReg(P2_3c4,0x05,0x86);
+   SiS_SetReg(P2_3c4,0x06,SiS_GetReg(SiS_Pr->SiS_P3c4,0x06));  /* SR06 */
+   SiS_SetReg(P2_3c4,0x21,SiS_GetReg(SiS_Pr->SiS_P3c4,0x21));  /* SR21 */
+   SiS_SetRegByte(P2_3c2,SiS_GetRegByte(SiS_Pr->SiS_P3cc));    /* MISC */
+   SiS_SetReg(P2_3c4,0x05,0x00);
+#endif
 }
 #endif
 
+/*********************************************/
+/*                 LOAD DAC                  */
+/*********************************************/
+
 static void
-SiS_WriteDAC(SiS_Private *SiS_Pr, SISIOADDRESS DACData, USHORT shiftflag,
-             USHORT dl, USHORT ah, USHORT al, USHORT dh)
+SiS_WriteDAC(struct SiS_Private *SiS_Pr, SISIOADDRESS DACData, unsigned short shiftflag,
+             unsigned short dl, unsigned short ah, unsigned short al, unsigned short dh)
 {
-  USHORT temp,bh,bl;
-
-  bh = ah;
-  bl = al;
-  if(dl != 0) {
-     temp = bh;
-     bh = dh;
-     dh = temp;
-     if(dl == 1) {
-        temp = bl;
-        bl = dh;
-        dh = temp;
-     } else {
-        temp = bl;
-        bl = bh;
-        bh = temp;
-     }
-  }
-  if(shiftflag) {
-     dh <<= 2;
-     bh <<= 2;
-     bl <<= 2;
-  }
-  SiS_SetRegByte(DACData,(USHORT)dh);
-  SiS_SetRegByte(DACData,(USHORT)bh);
-  SiS_SetRegByte(DACData,(USHORT)bl);
+   unsigned short d1, d2, d3;
+
+   switch(dl) {
+   case  0: d1 = dh; d2 = ah; d3 = al; break;
+   case  1: d1 = ah; d2 = al; d3 = dh; break;
+   default: d1 = al; d2 = dh; d3 = ah;
+   }
+   SiS_SetRegByte(DACData, (d1 << shiftflag));
+   SiS_SetRegByte(DACData, (d2 << shiftflag));
+   SiS_SetRegByte(DACData, (d3 << shiftflag));
 }
 
 void
-SiS_LoadDAC(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
-            USHORT ModeNo, USHORT ModeIdIndex)
+SiS_LoadDAC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
 {
-   USHORT data,data2;
-   USHORT time,i,j,k,m,n,o;
-   USHORT si,di,bx,dl,al,ah,dh;
-   USHORT shiftflag;
+   unsigned short data, data2, time, i, j, k, m, n, o;
+   unsigned short si, di, bx, sf;
    SISIOADDRESS DACAddr, DACData;
-   const USHORT *table = NULL;
+   const unsigned char *table = NULL;
 
-   if(ModeNo <= 0x13) {
-      data = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-   } else {
-      if(SiS_Pr->UseCustomMode) {
-        data = SiS_Pr->CModeFlag;
-      } else {
-         data = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-      }
-   }
+   data = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex) & DACInfoFlag;
 
-   data &= DACInfoFlag;
-   time = 64;
-   if(data == 0x00) table = SiS_MDA_DAC;
-   if(data == 0x08) table = SiS_CGA_DAC;
-   if(data == 0x10) table = SiS_EGA_DAC;
-   if(data == 0x18) {
+   j = time = 64;
+   if(data == 0x00)      table = SiS_MDA_DAC;
+   else if(data == 0x08) table = SiS_CGA_DAC;
+   else if(data == 0x10) table = SiS_EGA_DAC;
+   else if(data == 0x18) {
+      j = 16;
       time = 256;
       table = SiS_VGA_DAC;
    }
-   if(time == 256) j = 16;
-   else            j = time;
 
    if( ( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&        /* 301B-DH LCD */
          (SiS_Pr->SiS_VBType & VB_NoLCD) )        ||
        (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)       ||   /* LCDA */
        (!(SiS_Pr->SiS_SetFlag & ProgrammingCRT2)) ) {  /* Programming CRT1 */
+      SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF);
       DACAddr = SiS_Pr->SiS_P3c8;
       DACData = SiS_Pr->SiS_P3c9;
-      shiftflag = 0;
-      SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF);
+      sf = 0;
    } else {
-      shiftflag = 1;
       DACAddr = SiS_Pr->SiS_Part5Port;
       DACData = SiS_Pr->SiS_Part5Port + 1;
+      sf = 2;
    }
 
    SiS_SetRegByte(DACAddr,0x00);
 
-   for(i=0; i<j; i++) {
+   for(i = 0; i < j; i++) {
       data = table[i];
-      for(k=0; k<3; k++) {
+      for(k = 0; k < 3; k++) {
        data2 = 0;
-       if(data & 0x01) data2 = 0x2A;
+       if(data & 0x01) data2 += 0x2A;
        if(data & 0x02) data2 += 0x15;
-       if(shiftflag) data2 <<= 2;
-       SiS_SetRegByte(DACData, data2);
+       SiS_SetRegByte(DACData, (data2 << sf));
        data >>= 2;
       }
    }
 
    if(time == 256) {
       for(i = 16; i < 32; i++) {
-        data = table[i];
-        if(shiftflag) data <<= 2;
+        data = table[i] << sf;
         for(k = 0; k < 3; k++) SiS_SetRegByte(DACData, data);
       }
       si = 32;
       for(m = 0; m < 9; m++) {
-         di = si;
-         bx = si + 4;
-         dl = 0;
-         for(n = 0; n < 3; n++) {
-           for(o = 0; o < 5; o++) {
-              dh = table[si];
-              ah = table[di];
-              al = table[bx];
+        di = si;
+        bx = si + 4;
+        for(n = 0; n < 3; n++) {
+           for(o = 0; o < 5; o++) {
+              SiS_WriteDAC(SiS_Pr, DACData, sf, n, table[di], table[bx], table[si]);
               si++;
-              SiS_WriteDAC(SiS_Pr, DACData, shiftflag, dl, ah, al, dh);
            }
            si -= 2;
            for(o = 0; o < 3; o++) {
-              dh = table[bx];
-              ah = table[di];
-              al = table[si];
+              SiS_WriteDAC(SiS_Pr, DACData, sf, n, table[di], table[si], table[bx]);
               si--;
-              SiS_WriteDAC(SiS_Pr, DACData, shiftflag, dl, ah, al, dh);
            }
-           dl++;
         }            /* for n < 3 */
         si += 5;
       }               /* for m < 9 */
@@ -3241,89 +2972,114 @@ SiS_LoadDAC(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
 /*********************************************/
 
 static void
-SiS_SetCRT1Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
-                 USHORT ModeNo, USHORT ModeIdIndex)
+SiS_SetCRT1Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
 {
-  USHORT  StandTableIndex,RefreshRateTableIndex;
-
-  SiS_Pr->SiS_CRT1Mode = ModeNo;
-  StandTableIndex = SiS_GetModePtr(SiS_Pr, ModeNo, ModeIdIndex);
-  if(SiS_Pr->SiS_SetFlag & LowModeTests) {
-     if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchCRT2)) {
-        SiS_DisableBridge(SiS_Pr, HwInfo);
-     }
-  }
-
-  SiS_ResetSegmentRegisters(SiS_Pr, HwInfo);
-
-  SiS_SetSeqRegs(SiS_Pr, StandTableIndex, HwInfo);
-  SiS_SetMiscRegs(SiS_Pr, StandTableIndex, HwInfo);
-  SiS_SetCRTCRegs(SiS_Pr, HwInfo, StandTableIndex);
-  SiS_SetATTRegs(SiS_Pr, StandTableIndex, HwInfo);
-  SiS_SetGRCRegs(SiS_Pr, StandTableIndex);
-  SiS_ClearExt1Regs(SiS_Pr, HwInfo, ModeNo);
-  SiS_ResetCRT1VCLK(SiS_Pr, HwInfo);
-
-  SiS_Pr->SiS_SelectCRT2Rate = 0;
-  SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
-
-#ifdef LINUX_XF86
-  xf86DrvMsgVerb(0, X_PROBED, 4, "(init: VBType=0x%04x, VBInfo=0x%04x)\n",
+   unsigned short StandTableIndex, RefreshRateTableIndex;
+
+   SiS_Pr->SiS_CRT1Mode = ModeNo;
+
+   StandTableIndex = SiS_GetModePtr(SiS_Pr, ModeNo, ModeIdIndex);
+
+   if(SiS_Pr->SiS_SetFlag & LowModeTests) {
+      if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchCRT2)) {
+         SiS_DisableBridge(SiS_Pr);
+      }
+   }
+
+   SiS_ResetSegmentRegisters(SiS_Pr);
+
+   SiS_SetSeqRegs(SiS_Pr, StandTableIndex);
+   SiS_SetMiscRegs(SiS_Pr, StandTableIndex);
+   SiS_SetCRTCRegs(SiS_Pr, StandTableIndex);
+   SiS_SetATTRegs(SiS_Pr, StandTableIndex);
+   SiS_SetGRCRegs(SiS_Pr, StandTableIndex);
+   SiS_ClearExt1Regs(SiS_Pr, ModeNo);
+   SiS_ResetCRT1VCLK(SiS_Pr);
+
+   SiS_Pr->SiS_SelectCRT2Rate = 0;
+   SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
+
+#ifdef SIS_XORG_XF86
+   xf86DrvMsgVerb(0, X_PROBED, 4, "(init: VBType=0x%04x, VBInfo=0x%04x)\n",
                     SiS_Pr->SiS_VBType, SiS_Pr->SiS_VBInfo);
 #endif
 
-  if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) {
-     if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-        SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
-     }
-  }
+   if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) {
+      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+         SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
+      }
+   }
 
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
-     SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
-  }
+   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+      SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
+   }
 
-  RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
+   RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex);
 
-  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
-     SiS_Pr->SiS_SetFlag &= ~ProgrammingCRT2;
-  }
+   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+      SiS_Pr->SiS_SetFlag &= ~ProgrammingCRT2;
+   }
 
-  if(RefreshRateTableIndex != 0xFFFF) {
-     SiS_SetCRT1Sync(SiS_Pr, RefreshRateTableIndex);
-     SiS_SetCRT1CRTC(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
-     SiS_SetCRT1Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
-     SiS_SetCRT1VCLK(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
-  }
+   if(RefreshRateTableIndex != 0xFFFF) {
+      SiS_SetCRT1Sync(SiS_Pr, RefreshRateTableIndex);
+      SiS_SetCRT1CRTC(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
+      SiS_SetCRT1Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
+      SiS_SetCRT1VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
+   }
 
+   switch(SiS_Pr->ChipType) {
 #ifdef SIS300
-  if(HwInfo->jChipType == SIS_300) {
-     SiS_SetCRT1FIFO_300(SiS_Pr, ModeNo,HwInfo,RefreshRateTableIndex);
-  } else if((HwInfo->jChipType == SIS_630) ||
-            (HwInfo->jChipType == SIS_730) ||
-            (HwInfo->jChipType == SIS_540)) {
-     SiS_SetCRT1FIFO_630(SiS_Pr, ModeNo, HwInfo, RefreshRateTableIndex);
-  }
+   case SIS_300:
+      SiS_SetCRT1FIFO_300(SiS_Pr, ModeNo, RefreshRateTableIndex);
+      break;
+   case SIS_540:
+   case SIS_630:
+   case SIS_730:
+      SiS_SetCRT1FIFO_630(SiS_Pr, ModeNo, RefreshRateTableIndex);
+      break;
 #endif
+   default:
 #ifdef SIS315H
-  if(HwInfo->jChipType >= SIS_315H) {
-     SiS_SetCRT1FIFO_310(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
-  }
+      if(SiS_Pr->ChipType == XGI_20) {
+         unsigned char sr2b = 0, sr2c = 0;
+         switch(ModeNo) {
+        case 0x00:
+        case 0x01: sr2b = 0x4e; sr2c = 0xe9; break;
+        case 0x04:
+        case 0x05:
+        case 0x0d: sr2b = 0x1b; sr2c = 0xe3; break;
+        }
+        if(sr2b) {
+            SiS_SetReg(SiS_Pr->SiS_P3c4,0x2b,sr2b);
+           SiS_SetReg(SiS_Pr->SiS_P3c4,0x2c,sr2c);
+           SiS_SetRegByte(SiS_Pr->SiS_P3c2,(SiS_GetRegByte(SiS_Pr->SiS_P3cc) | 0x0c));
+        }
+      }
+      SiS_SetCRT1FIFO_310(SiS_Pr, ModeNo, ModeIdIndex);
 #endif
+      break;
+   }
+
+   SiS_SetCRT1ModeRegs(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
 
-  SiS_SetCRT1ModeRegs(SiS_Pr, HwInfo, ModeNo, ModeIdIndex, RefreshRateTableIndex);
+#ifdef SIS315H
+   if(SiS_Pr->ChipType == XGI_40) {
+      SiS_SetupDualChip(SiS_Pr);
+   }
+#endif
 
-  SiS_LoadDAC(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
+   SiS_LoadDAC(SiS_Pr, ModeNo, ModeIdIndex);
 
-#ifdef LINUX_KERNEL
-  if(SiS_Pr->SiS_flag_clearbuffer) {
-     SiS_ClearBuffer(SiS_Pr,HwInfo,ModeNo);
-  }
+#ifdef SIS_LINUX_KERNEL
+   if(SiS_Pr->SiS_flag_clearbuffer) {
+      SiS_ClearBuffer(SiS_Pr, ModeNo);
+   }
 #endif
 
-  if(!(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchCRT2 | SetCRT2ToLCDA))) {
-     SiS_WaitRetrace1(SiS_Pr);
-     SiS_DisplayOn(SiS_Pr);
-  }
+   if(!(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchCRT2 | SetCRT2ToLCDA))) {
+      SiS_WaitRetrace1(SiS_Pr);
+      SiS_DisplayOn(SiS_Pr);
+   }
 }
 
 /*********************************************/
@@ -3331,33 +3087,62 @@ SiS_SetCRT1Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
 /*********************************************/
 
 static void
-SiS_ResetVB(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_InitVB(struct SiS_Private *SiS_Pr)
+{
+   unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
+
+   SiS_Pr->Init_P4_0E = 0;
+   if(SiS_Pr->SiS_ROMNew) {
+      SiS_Pr->Init_P4_0E = ROMAddr[0x82];
+   } else if(SiS_Pr->ChipType >= XGI_40) {
+      if(SiS_Pr->SiS_XGIROM) {
+         SiS_Pr->Init_P4_0E = ROMAddr[0x80];
+      }
+   }
+}
+
+static void
+SiS_ResetVB(struct SiS_Private *SiS_Pr)
 {
-   UCHAR  *ROMAddr  = HwInfo->pjVirtualRomBase;
-   USHORT temp;
+#ifdef SIS315H
+   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
+   unsigned short temp;
 
    /* VB programming clock */
    if(SiS_Pr->SiS_UseROM) {
-      if(HwInfo->jChipType < SIS_330) {
-         temp = ROMAddr[VB310Data_1_2_Offset] | 0x40;
+      if(SiS_Pr->ChipType < 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);
-      } else if(HwInfo->jChipType >= SIS_661) {
-         temp = ROMAddr[0x7e] | 0x40;
-         if(SiS_Pr->SiS_ROMNew) temp = ROMAddr[0x80] | 0x40;
+      } else if(SiS_Pr->ChipType >= SIS_661 && SiS_Pr->ChipType < XGI_20) {
+        temp = ROMAddr[0x7e] | 0x40;
+        if(SiS_Pr->SiS_ROMNew) temp = ROMAddr[0x80] | 0x40;
         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp);
       }
+   } else if(SiS_Pr->ChipType >= XGI_40) {
+      temp = 0x40;
+      if(SiS_Pr->SiS_XGIROM) temp |= ROMAddr[0x7e];
+      /* Can we do this on any chipset? */
+      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp);
    }
+#endif
 }
 
 /*********************************************/
-/*         HELPER: SET VIDEO REGISTERS       */
+/*    HELPER: SET VIDEO/CAPTURE REGISTERS    */
 /*********************************************/
 
 static void
-SiS_StrangeStuff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_StrangeStuff(struct SiS_Private *SiS_Pr)
 {
-   if((IS_SIS651) || (IS_SISM650)) {
+   /* SiS65x and XGI set up some sort of "lock mode" for text
+    * which locks CRT2 in some way to CRT1 timing. Disable
+    * this here.
+    */
+#ifdef SIS315H
+   if((IS_SIS651) || (IS_SISM650) ||
+      SiS_Pr->ChipType == SIS_340 ||
+      SiS_Pr->ChipType == XGI_40) {
       SiS_SetReg(SiS_Pr->SiS_VidCapt, 0x3f, 0x00);   /* Fiddle with capture regs */
       SiS_SetReg(SiS_Pr->SiS_VidCapt, 0x00, 0x00);
       SiS_SetReg(SiS_Pr->SiS_VidPlay, 0x00, 0x86);   /* (BIOS does NOT unlock) */
@@ -3365,49 +3150,99 @@ SiS_StrangeStuff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
       SiS_SetRegAND(SiS_Pr->SiS_VidPlay, 0x3f, 0xef);
    }
    /* !!! This does not support modes < 0x13 !!! */
+#endif
+}
+
+/*********************************************/
+/*     HELPER: SET AGP TIMING FOR SiS760     */
+/*********************************************/
+
+static void
+SiS_Handle760(struct SiS_Private *SiS_Pr)
+{
+#ifdef SIS315H
+   unsigned int somebase;
+   unsigned char temp1, temp2, temp3;
+
+   if( (SiS_Pr->ChipType != SIS_760)                         ||
+       ((SiS_GetReg(SiS_Pr->SiS_P3d4, 0x5c) & 0xf8) != 0x80) ||
+       (!(SiS_Pr->SiS_SysFlags & SF_760LFB))                 ||
+       (!(SiS_Pr->SiS_SysFlags & SF_760UMA)) )
+      return;
+
+#ifdef SIS_LINUX_KERNEL
+   somebase = sisfb_read_mio_pci_word(SiS_Pr, 0x74);
+#else
+   somebase = pciReadWord(0x00001000, 0x74);
+#endif
+   somebase &= 0xffff;
+
+   if(somebase == 0) return;
+
+   temp3 = SiS_GetRegByte((somebase + 0x85)) & 0xb7;
+
+   if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40) {
+      temp1 = 0x21;
+      temp2 = 0x03;
+      temp3 |= 0x08;
+   } else {
+      temp1 = 0x25;
+      temp2 = 0x0b;
+   }
+
+#ifdef SIS_LINUX_KERNEL
+   sisfb_write_nbridge_pci_byte(SiS_Pr, 0x7e, temp1);
+   sisfb_write_nbridge_pci_byte(SiS_Pr, 0x8d, temp2);
+#else
+   pciWriteByte(0x00000000, 0x7e, temp1);
+   pciWriteByte(0x00000000, 0x8d, temp2);
+#endif
+
+   SiS_SetRegByte((somebase + 0x85), temp3);
+#endif
 }
 
 /*********************************************/
-/*         XFree86: SET SCREEN PITCH         */
+/*      X.org/XFree86: SET SCREEN PITCH      */
 /*********************************************/
 
-#ifdef LINUX_XF86
+#ifdef SIS_XORG_XF86
 static void
-SiS_SetPitchCRT1(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn)
+SiS_SetPitchCRT1(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn)
 {
    SISPtr pSiS = SISPTR(pScrn);
-   UShort HDisplay = pSiS->scrnPitch >> 3;
+   unsigned short HDisplay = pSiS->scrnPitch >> 3;
 
    SiS_SetReg(SiS_Pr->SiS_P3d4,0x13,(HDisplay & 0xFF));
-   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0xF0,(HDisplay>>8));
+   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0xF0,(HDisplay >> 8));
 }
 
 static void
-SiS_SetPitchCRT2(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn)
+SiS_SetPitchCRT2(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn)
 {
    SISPtr pSiS = SISPTR(pScrn);
-   UShort HDisplay = pSiS->scrnPitch2 >> 3;
+   unsigned short HDisplay = pSiS->scrnPitch2 >> 3;
 
     /* Unlock CRT2 */
    if(pSiS->VGAEngine == SIS_315_VGA)
-     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2F, 0x01);
+      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2F, 0x01);
    else
-     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24, 0x01);
+      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24, 0x01);
 
    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(HDisplay & 0xFF));
    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0xF0,(HDisplay >> 8));
 }
 
 static void
-SiS_SetPitch(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn)
+SiS_SetPitch(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn)
 {
    SISPtr pSiS = SISPTR(pScrn);
    BOOLEAN isslavemode = FALSE;
 
-   if( (pSiS->VBFlags & VB_VIDEOBRIDGE) &&
+   if( (pSiS->VBFlags2 & VB2_VIDEOBRIDGE) &&
        ( ((pSiS->VGAEngine == SIS_300_VGA) &&
-          (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0xa0) == 0x20) ||
-         ((pSiS->VGAEngine == SIS_315_VGA) &&
+         (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0xa0) == 0x20) ||
+        ((pSiS->VGAEngine == SIS_315_VGA) &&
          (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x50) == 0x10) ) ) {
       isslavemode = TRUE;
    }
@@ -3427,59 +3262,59 @@ SiS_SetPitch(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn)
 /*                 SiSSetMode()              */
 /*********************************************/
 
-#ifdef LINUX_XF86
+#ifdef SIS_XORG_XF86
 /* We need pScrn for setting the pitch correctly */
 BOOLEAN
-SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,ScrnInfoPtr pScrn,USHORT ModeNo, BOOLEAN dosetpitch)
+SiSSetMode(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, unsigned short ModeNo, BOOLEAN dosetpitch)
 #else
 BOOLEAN
-SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,USHORT ModeNo)
+SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
 #endif
 {
-   USHORT  ModeIdIndex;
-   SISIOADDRESS BaseAddr = HwInfo->ulIOAddress;
-   unsigned char backupreg=0;
-#ifdef LINUX_KERNEL
-   USHORT  KeepLockReg;
-   ULONG   temp;
+   SISIOADDRESS BaseAddr = SiS_Pr->IOAddress;
+   unsigned short RealModeNo, ModeIdIndex;
+   unsigned char  backupreg = 0;
+#ifdef SIS_LINUX_KERNEL
+   unsigned short KeepLockReg;
 
    SiS_Pr->UseCustomMode = FALSE;
    SiS_Pr->CRT1UsesCustomMode = FALSE;
 #endif
 
+   SiS_Pr->SiS_flag_clearbuffer = 0;
+
    if(SiS_Pr->UseCustomMode) {
       ModeNo = 0xfe;
+   } else {
+#ifdef SIS_LINUX_KERNEL
+      if(!(ModeNo & 0x80)) SiS_Pr->SiS_flag_clearbuffer = 1;
+#endif
+      ModeNo &= 0x7f;
    }
 
-   SiSInitPtr(SiS_Pr, HwInfo);
+   /* Don't use FSTN mode for CRT1 */
+   RealModeNo = ModeNo;
+   if(ModeNo == 0x5b) ModeNo = 0x56;
+
+   SiSInitPtr(SiS_Pr);
    SiSRegInit(SiS_Pr, BaseAddr);
-   SiS_GetSysFlags(SiS_Pr, HwInfo);
+   SiS_GetSysFlags(SiS_Pr);
 
-#if defined(LINUX_XF86) && (defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__))
+   SiS_Pr->SiS_VGAINFO = 0x11;
+#if defined(SIS_XORG_XF86) && (defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__) || defined(__amd64__) || defined(__x86_64__))
    if(pScrn) SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
-   else
-#endif
-         SiS_Pr->SiS_VGAINFO = 0x11;
-
-   SiSInitPCIetc(SiS_Pr, HwInfo);
-   SiSSetLVDSetc(SiS_Pr, HwInfo);
-   SiSDetermineROMUsage(SiS_Pr, HwInfo);
-
-   SiS_Pr->SiS_flag_clearbuffer = 0;
-
-   if(!SiS_Pr->UseCustomMode) {
-#ifdef LINUX_KERNEL
-      if(!(ModeNo & 0x80)) SiS_Pr->SiS_flag_clearbuffer = 1;
 #endif
-      ModeNo &= 0x7f;
-   }
 
-#ifdef LINUX_KERNEL
+#ifdef SIS_LINUX_KERNEL
    KeepLockReg = SiS_GetReg(SiS_Pr->SiS_P3c4,0x05);
 #endif
    SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86);
 
-   SiS_UnLockCRT2(SiS_Pr, HwInfo);
+   SiSInitPCIetc(SiS_Pr);
+   SiSSetLVDSetc(SiS_Pr);
+   SiSDetermineROMUsage(SiS_Pr);
+
+   SiS_UnLockCRT2(SiS_Pr);
 
    if(!SiS_Pr->UseCustomMode) {
       if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return FALSE;
@@ -3487,13 +3322,13 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,USHORT ModeNo)
       ModeIdIndex = 0;
    }
 
-   SiS_GetVBType(SiS_Pr, HwInfo);
+   SiS_GetVBType(SiS_Pr);
 
    /* Init/restore some VB registers */
-
-   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-      if(HwInfo->jChipType >= SIS_315H) {
-         SiS_ResetVB(SiS_Pr, HwInfo);
+   SiS_InitVB(SiS_Pr);
+   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
+      if(SiS_Pr->ChipType >= SIS_315H) {
+         SiS_ResetVB(SiS_Pr);
         SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x32,0x10);
         SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x00,0x0c);
          backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
@@ -3503,21 +3338,20 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,USHORT ModeNo)
    }
 
    /* Get VB information (connectors, connected devices) */
-   SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, (SiS_Pr->UseCustomMode) ? 0 : 1);
-   SiS_SetYPbPr(SiS_Pr, HwInfo);
-   SiS_SetTVMode(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
-   SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
-   SiS_SetLowModeTest(SiS_Pr, ModeNo, HwInfo);
-
-#ifdef LINUX_KERNEL
-   /* 3. Check memory size (Kernel framebuffer driver only) */
-   temp = SiS_CheckMemorySize(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
-   if(!temp) return(0);
+   SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, (SiS_Pr->UseCustomMode) ? 0 : 1);
+   SiS_SetYPbPr(SiS_Pr);
+   SiS_SetTVMode(SiS_Pr, ModeNo, ModeIdIndex);
+   SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex);
+   SiS_SetLowModeTest(SiS_Pr, ModeNo);
+
+#ifdef SIS_LINUX_KERNEL
+   /* Check memory size (kernel framebuffer driver only) */
+   if(!SiS_CheckMemorySize(SiS_Pr, ModeNo, ModeIdIndex)) {
+      return FALSE;
+   }
 #endif
 
-   if(HwInfo->jChipType >= SIS_315H) {
-      SiS_SetupCR5x(SiS_Pr, HwInfo);
-   }
+   SiS_OpenCRTC(SiS_Pr);
 
    if(SiS_Pr->UseCustomMode) {
       SiS_Pr->CRT1UsesCustomMode = TRUE;
@@ -3530,38 +3364,41 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,USHORT ModeNo)
    /* Set mode on CRT1 */
    if( (SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SetCRT2ToLCDA)) ||
        (!(SiS_Pr->SiS_VBInfo & SwitchCRT2)) ) {
-      SiS_SetCRT1Group(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
+      SiS_SetCRT1Group(SiS_Pr, ModeNo, ModeIdIndex);
    }
 
    /* Set mode on CRT2 */
    if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchCRT2 | SetCRT2ToLCDA)) {
       if( (SiS_Pr->SiS_VBType & VB_SISVB)    ||
-          (SiS_Pr->SiS_IF_DEF_LVDS     == 1) ||
-          (SiS_Pr->SiS_IF_DEF_CH70xx   != 0) ||
-          (SiS_Pr->SiS_IF_DEF_TRUMPION != 0) ) {
-         SiS_SetCRT2Group(SiS_Pr, HwInfo, ModeNo);
+         (SiS_Pr->SiS_IF_DEF_LVDS     == 1) ||
+         (SiS_Pr->SiS_IF_DEF_CH70xx   != 0) ||
+         (SiS_Pr->SiS_IF_DEF_TRUMPION != 0) ) {
+        SiS_SetCRT2Group(SiS_Pr, RealModeNo);
       }
    }
 
    SiS_HandleCRT1(SiS_Pr);
 
-   SiS_StrangeStuff(SiS_Pr, HwInfo);
+   SiS_StrangeStuff(SiS_Pr);
 
    SiS_DisplayOn(SiS_Pr);
    SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF);
 
-   if(HwInfo->jChipType >= SIS_315H) {
+#ifdef SIS315H
+   if(SiS_Pr->ChipType >= SIS_315H) {
       if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-         if(!(SiS_IsDualEdge(SiS_Pr, HwInfo))) {
+        if(!(SiS_IsDualEdge(SiS_Pr))) {
            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
         }
       }
    }
+#endif
 
-   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-      if(HwInfo->jChipType >= SIS_315H) {
-         if(!SiS_Pr->SiS_ROMNew) {
-           if(SiS_IsVAMode(SiS_Pr,HwInfo)) {
+   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
+      if(SiS_Pr->ChipType >= SIS_315H) {
+#ifdef SIS315H
+        if(!SiS_Pr->SiS_ROMNew) {
+           if(SiS_IsVAMode(SiS_Pr)) {
               SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01);
            } else {
               SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x35,0xFE);
@@ -3574,23 +3411,24 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,USHORT ModeNo)
            if((ModeNo == 0x03) || (ModeNo == 0x10)) {
               SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x51,0x80);
               SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x56,0x08);
-            }
+           }
         }
 
         if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & SetCRT2ToLCD) {
            SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
         }
-      } else if((HwInfo->jChipType == SIS_630) ||
-                (HwInfo->jChipType == SIS_730)) {
-         SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,backupreg);
+#endif
+      } else if((SiS_Pr->ChipType == SIS_630) ||
+               (SiS_Pr->ChipType == SIS_730)) {
+        SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,backupreg);
       }
    }
 
-#ifdef LINUX_XF86
+#ifdef SIS_XORG_XF86
    if(pScrn) {
       /* SetPitch: Adapt to virtual size & position */
       if((ModeNo > 0x13) && (dosetpitch)) {
-         SiS_SetPitch(SiS_Pr, pScrn);
+        SiS_SetPitch(SiS_Pr, pScrn);
       }
 
       /* Backup/Set ModeNo in BIOS scratch area */
@@ -3598,33 +3436,37 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,USHORT ModeNo)
    }
 #endif
 
-#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);
+   SiS_CloseCRTC(SiS_Pr);
+
+   SiS_Handle760(SiS_Pr);
+
+#ifdef SIS_LINUX_KERNEL
+   /* We never lock registers in XF86 */
+   if(KeepLockReg != 0xA1) SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x00);
 #endif
 
    return TRUE;
 }
 
 /*********************************************/
-/*          XFree86: SiSBIOSSetMode()        */
+/*       X.org/XFree86: SiSBIOSSetMode()     */
 /*           for non-Dual-Head mode          */
 /*********************************************/
 
-#ifdef LINUX_XF86
+#ifdef SIS_XORG_XF86
 BOOLEAN
-SiSBIOSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
+SiSBIOSSetMode(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
                DisplayModePtr mode, BOOLEAN IsCustom)
 {
    SISPtr pSiS = SISPTR(pScrn);
-   UShort ModeNo = 0;
+   unsigned short 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",
-               SiS_Pr->CHDisplay,
+               SiS_Pr->CHDisplay,
                (mode->Flags & V_INTERLACE ? SiS_Pr->CVDisplay * 2 :
                   (mode->Flags & V_DBLSCAN ? SiS_Pr->CVDisplay / 2 :
                      SiS_Pr->CVDisplay)));
@@ -3632,32 +3474,33 @@ SiSBIOSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
    } else {
 
       /* Don't need vbflags here; checks done earlier */
-      ModeNo = SiS_GetModeNumber(pScrn, mode, 0);
+      ModeNo = SiS_GetModeNumber(pScrn, mode, pSiS->VBFlags);
       if(!ModeNo) return FALSE;
 
       xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting standard mode 0x%x\n", ModeNo);
 
    }
 
-   return(SiSSetMode(SiS_Pr, HwInfo, pScrn, ModeNo, TRUE));
+   return(SiSSetMode(SiS_Pr, pScrn, ModeNo, TRUE));
 }
 
 /*********************************************/
-/*       XFree86: SiSBIOSSetModeCRT2()       */
+/*    X.org/XFree86: SiSBIOSSetModeCRT2()    */
 /*           for Dual-Head modes             */
 /*********************************************/
+
 BOOLEAN
-SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
+SiSBIOSSetModeCRT2(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
                DisplayModePtr mode, BOOLEAN IsCustom)
 {
-   USHORT  ModeIdIndex;
-   SISIOADDRESS BaseAddr = HwInfo->ulIOAddress;
-   UShort  ModeNo   = 0;
-   unsigned char backupreg=0;
-   SISPtr  pSiS     = SISPTR(pScrn);
+   SISIOADDRESS BaseAddr = SiS_Pr->IOAddress;
+   SISPtr  pSiS = SISPTR(pScrn);
 #ifdef SISDUALHEAD
    SISEntPtr pSiSEnt = pSiS->entityPrivate;
 #endif
+   unsigned short ModeIdIndex;
+   unsigned short ModeNo = 0;
+   unsigned char  backupreg = 0;
 
    SiS_Pr->UseCustomMode = FALSE;
 
@@ -3672,22 +3515,25 @@ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
 
    } else {
 
-         ModeNo = SiS_GetModeNumber(pScrn, mode, 0);
-         if(!ModeNo) return FALSE;
+        ModeNo = SiS_GetModeNumber(pScrn, mode, pSiS->VBFlags);
+        if(!ModeNo) return FALSE;
 
    }
 
    SiSRegInit(SiS_Pr, BaseAddr);
-   SiSInitPtr(SiS_Pr, HwInfo);
-   SiS_GetSysFlags(SiS_Pr, HwInfo);
-#if (defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__))
+   SiSInitPtr(SiS_Pr);
+   SiS_GetSysFlags(SiS_Pr);
+#if defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__) || defined(__amd64__) || defined(__x86_64__)
    SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
 #else
    SiS_Pr->SiS_VGAINFO = 0x11;
 #endif
-   SiSInitPCIetc(SiS_Pr, HwInfo);
-   SiSSetLVDSetc(SiS_Pr, HwInfo);
-   SiSDetermineROMUsage(SiS_Pr, HwInfo);
+
+   SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86);
+
+   SiSInitPCIetc(SiS_Pr);
+   SiSSetLVDSetc(SiS_Pr);
+   SiSDetermineROMUsage(SiS_Pr);
 
    /* Save mode info so we can set it from within SetMode for CRT1 */
 #ifdef SISDUALHEAD
@@ -3700,23 +3546,20 @@ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
       pSiSEnt->CRT2CR35 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
       pSiSEnt->CRT2CR38 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
 #if 0
-      /* We can't set CRT2 mode before CRT1 mode is set */
+      /* We can't set CRT2 mode before CRT1 mode is set - says who...? */
       if(pSiSEnt->CRT1ModeNo == -1) {
-        xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+        xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
                "Setting CRT2 mode delayed until after setting CRT1 mode\n");
-        return TRUE;
+        return TRUE;
       }
 #endif
       pSiSEnt->CRT2ModeSet = TRUE;
    }
 #endif
 
-   /* We don't clear the buffer in X */
-   SiS_Pr->SiS_flag_clearbuffer=0;
-
    if(SiS_Pr->UseCustomMode) {
 
-      USHORT temptemp = SiS_Pr->CVDisplay;
+      unsigned short temptemp = SiS_Pr->CVDisplay;
 
       if(SiS_Pr->CModeFlag & DoubleScanMode)     temptemp >>= 1;
       else if(SiS_Pr->CInfoFlag & InterlaceMode) temptemp <<= 1;
@@ -3728,13 +3571,11 @@ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
    } else {
 
       xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
-         "Setting standard mode 0x%x on CRT2\n", ModeNo);
+         "Setting standard mode 0x%x on CRT2\n", ModeNo);
 
    }
 
-   SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86);
-
-   SiS_UnLockCRT2(SiS_Pr, HwInfo);
+   SiS_UnLockCRT2(SiS_Pr);
 
    if(!SiS_Pr->UseCustomMode) {
       if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return FALSE;
@@ -3742,56 +3583,59 @@ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
       ModeIdIndex = 0;
    }
 
-   SiS_GetVBType(SiS_Pr, HwInfo);
+   SiS_GetVBType(SiS_Pr);
 
-   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-      if(HwInfo->jChipType >= SIS_315H) {
-        SiS_ResetVB(SiS_Pr, HwInfo);
+   SiS_InitVB(SiS_Pr);
+   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
+      if(SiS_Pr->ChipType >= SIS_315H) {
+        SiS_ResetVB(SiS_Pr);
         SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x32,0x10);
         SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x00,0x0c);
-         backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
+        backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
       } else {
-         backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
+        backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
       }
    }
 
    /* Get VB information (connectors, connected devices) */
    if(!SiS_Pr->UseCustomMode) {
-      SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, 1);
+      SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, 1);
    } else {
       /* If this is a custom mode, we don't check the modeflag for CRT2Mode */
-      SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, 0);
+      SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, 0);
    }
-   SiS_SetYPbPr(SiS_Pr, HwInfo);
-   SiS_SetTVMode(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
-   SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
-   SiS_SetLowModeTest(SiS_Pr, ModeNo, HwInfo);
+   SiS_SetYPbPr(SiS_Pr);
+   SiS_SetTVMode(SiS_Pr, ModeNo, ModeIdIndex);
+   SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex);
+   SiS_SetLowModeTest(SiS_Pr, ModeNo);
+
+   SiS_ResetSegmentRegisters(SiS_Pr);
 
    /* Set mode on CRT2 */
    if( (SiS_Pr->SiS_VBType & VB_SISVB)    ||
        (SiS_Pr->SiS_IF_DEF_LVDS     == 1) ||
        (SiS_Pr->SiS_IF_DEF_CH70xx   != 0) ||
        (SiS_Pr->SiS_IF_DEF_TRUMPION != 0) ) {
-      SiS_SetCRT2Group(SiS_Pr, HwInfo, ModeNo);
+      SiS_SetCRT2Group(SiS_Pr, ModeNo);
    }
 
-   SiS_StrangeStuff(SiS_Pr, HwInfo);
+   SiS_StrangeStuff(SiS_Pr);
 
    SiS_DisplayOn(SiS_Pr);
    SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF);
 
-   if(HwInfo->jChipType >= SIS_315H) {
+   if(SiS_Pr->ChipType >= SIS_315H) {
       if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-         if(!(SiS_IsDualEdge(SiS_Pr, HwInfo))) {
+        if(!(SiS_IsDualEdge(SiS_Pr))) {
            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
         }
       }
    }
 
-   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-      if(HwInfo->jChipType >= SIS_315H) {
-         if(!SiS_Pr->SiS_ROMNew) {
-           if(SiS_IsVAMode(SiS_Pr,HwInfo)) {
+   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
+      if(SiS_Pr->ChipType >= SIS_315H) {
+        if(!SiS_Pr->SiS_ROMNew) {
+           if(SiS_IsVAMode(SiS_Pr)) {
               SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01);
            } else {
               SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x35,0xFE);
@@ -3803,8 +3647,8 @@ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
         if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & SetCRT2ToLCD) {
            SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
         }
-      } else if((HwInfo->jChipType == SIS_630) ||
-                (HwInfo->jChipType == SIS_730)) {
+      } else if((SiS_Pr->ChipType == SIS_630) ||
+               (SiS_Pr->ChipType == SIS_730)) {
          SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,backupreg);
       }
    }
@@ -3812,25 +3656,27 @@ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
    /* SetPitch: Adapt to virtual size & position */
    SiS_SetPitchCRT2(SiS_Pr, pScrn);
 
+   SiS_Handle760(SiS_Pr);
+
    return TRUE;
 }
 
 /*********************************************/
-/*       XFree86: SiSBIOSSetModeCRT1()       */
+/*    X.org/XFree86: SiSBIOSSetModeCRT1()    */
 /*           for Dual-Head modes             */
 /*********************************************/
 
 BOOLEAN
-SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
+SiSBIOSSetModeCRT1(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
                    DisplayModePtr mode, BOOLEAN IsCustom)
 {
+   SISIOADDRESS BaseAddr = SiS_Pr->IOAddress;
    SISPtr  pSiS = SISPTR(pScrn);
-   SISIOADDRESS BaseAddr = HwInfo->ulIOAddress;
-   USHORT  ModeIdIndex, ModeNo=0;
-   UCHAR backupreg=0;
+   unsigned short ModeIdIndex, ModeNo = 0;
+   unsigned char  backupreg = 0;
 #ifdef SISDUALHEAD
    SISEntPtr pSiSEnt = pSiS->entityPrivate;
-   UCHAR backupcr30, backupcr31, backupcr38, backupcr35, backupp40d=0;
+   unsigned char  backupcr30, backupcr31, backupcr38, backupcr35, backupp40d=0;
    BOOLEAN backupcustom;
 #endif
 
@@ -3838,43 +3684,41 @@ SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
 
    if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
 
-         USHORT temptemp = SiS_Pr->CVDisplay;
+        unsigned short temptemp = SiS_Pr->CVDisplay;
 
-         if(SiS_Pr->CModeFlag & DoubleScanMode)     temptemp >>= 1;
-         else if(SiS_Pr->CInfoFlag & InterlaceMode) temptemp <<= 1;
+        if(SiS_Pr->CModeFlag & DoubleScanMode)     temptemp >>= 1;
+        else if(SiS_Pr->CInfoFlag & InterlaceMode) temptemp <<= 1;
 
-         xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+        xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
                "Setting custom mode %dx%d on CRT1\n",
                SiS_Pr->CHDisplay, temptemp);
         ModeNo = 0xfe;
 
    } else {
 
-         ModeNo = SiS_GetModeNumber(pScrn, mode, 0);
-         if(!ModeNo) return FALSE;
+        ModeNo = SiS_GetModeNumber(pScrn, mode, 0); /* don't give VBFlags */
+        if(!ModeNo) return FALSE;
 
-         xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+        xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
                "Setting standard mode 0x%x on CRT1\n", ModeNo);
    }
 
-   SiSInitPtr(SiS_Pr, HwInfo);
+   SiSInitPtr(SiS_Pr);
    SiSRegInit(SiS_Pr, BaseAddr);
-   SiS_GetSysFlags(SiS_Pr, HwInfo);
-#if (defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__))
+   SiS_GetSysFlags(SiS_Pr);
+#if defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__) || defined(__amd64__) || defined(__x86_64__)
    SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
 #else
    SiS_Pr->SiS_VGAINFO = 0x11;
 #endif
-   SiSInitPCIetc(SiS_Pr, HwInfo);
-   SiSSetLVDSetc(SiS_Pr, HwInfo);
-   SiSDetermineROMUsage(SiS_Pr, HwInfo);
-
-   /* We don't clear the buffer in X */
-   SiS_Pr->SiS_flag_clearbuffer = 0;
 
    SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86);
 
-   SiS_UnLockCRT2(SiS_Pr, HwInfo);
+   SiSInitPCIetc(SiS_Pr);
+   SiSSetLVDSetc(SiS_Pr);
+   SiSDetermineROMUsage(SiS_Pr);
+
+   SiS_UnLockCRT2(SiS_Pr);
 
    if(!SiS_Pr->UseCustomMode) {
       if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return FALSE;
@@ -3883,10 +3727,11 @@ SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
    }
 
    /* Determine VBType */
-   SiS_GetVBType(SiS_Pr, HwInfo);
+   SiS_GetVBType(SiS_Pr);
 
-   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-      if(HwInfo->jChipType >= SIS_315H) {
+   SiS_InitVB(SiS_Pr);
+   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
+      if(SiS_Pr->ChipType >= SIS_315H) {
          backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
       } else {
          backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
@@ -3895,25 +3740,29 @@ SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
 
    /* Get VB information (connectors, connected devices) */
    /* (We don't care if the current mode is a CRT2 mode) */
-   SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, 0);
-   SiS_SetYPbPr(SiS_Pr, HwInfo);
-   SiS_SetTVMode(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
-   SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
-   SiS_SetLowModeTest(SiS_Pr, ModeNo, HwInfo);
+   SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, 0);
+   SiS_SetYPbPr(SiS_Pr);
+   SiS_SetTVMode(SiS_Pr, ModeNo, ModeIdIndex);
+   SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex);
+   SiS_SetLowModeTest(SiS_Pr, ModeNo);
 
-   if(HwInfo->jChipType >= SIS_315H) {
-      SiS_SetupCR5x(SiS_Pr, HwInfo);
-   }
+   SiS_OpenCRTC(SiS_Pr);
 
    /* Set mode on CRT1 */
-   SiS_SetCRT1Group(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
+   SiS_SetCRT1Group(SiS_Pr, ModeNo, ModeIdIndex);
    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
-      SiS_SetCRT2Group(SiS_Pr, HwInfo, ModeNo);
+      SiS_SetCRT2Group(SiS_Pr, ModeNo);
    }
 
    /* SetPitch: Adapt to virtual size & position */
    SiS_SetPitchCRT1(SiS_Pr, pScrn);
 
+   SiS_HandleCRT1(SiS_Pr);
+
+   SiS_StrangeStuff(SiS_Pr);
+
+   SiS_CloseCRTC(SiS_Pr);
+
 #ifdef SISDUALHEAD
    if(pSiS->DualHeadMode) {
       pSiSEnt->CRT1ModeNo = ModeNo;
@@ -3933,7 +3782,7 @@ SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
 #ifdef SISDUALHEAD
    if(pSiS->DualHeadMode) {
       if(pSiSEnt->CRT2ModeNo != -1) {
-         xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+        xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
                                "(Re-)Setting mode for CRT2\n");
         backupcustom = SiS_Pr->UseCustomMode;
         backupcr30 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
@@ -3952,9 +3801,11 @@ SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
            SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,pSiSEnt->CRT2CR35);
            SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,pSiSEnt->CRT2CR38);
         }
-        SiSBIOSSetModeCRT2(SiS_Pr, HwInfo, pSiSEnt->pScrn_1,
+
+        SiSBIOSSetModeCRT2(SiS_Pr, pSiSEnt->pScrn_1,
                            pSiSEnt->CRT2DMode, pSiSEnt->CRT2IsCustom);
-         SiS_SetReg(SiS_Pr->SiS_P3d4,0x30,backupcr30);
+
+        SiS_SetReg(SiS_Pr->SiS_P3d4,0x30,backupcr30);
         SiS_SetReg(SiS_Pr->SiS_P3d4,0x31,backupcr31);
         SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,backupcr35);
         SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,backupcr38);
@@ -3970,22 +3821,20 @@ SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
     * possibly overwritten
     */
 
-   SiS_HandleCRT1(SiS_Pr);
-
-   SiS_StrangeStuff(SiS_Pr, HwInfo);
-
    SiS_DisplayOn(SiS_Pr);
    SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF);
 
-   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-      if(HwInfo->jChipType >= SIS_315H) {
+   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
+      if(SiS_Pr->ChipType >= SIS_315H) {
         SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,backupreg);
-      } else if((HwInfo->jChipType == SIS_630) ||
-                (HwInfo->jChipType == SIS_730)) {
+      } else if((SiS_Pr->ChipType == SIS_630) ||
+                (SiS_Pr->ChipType == SIS_730)) {
          SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,backupreg);
       }
    }
 
+   SiS_Handle760(SiS_Pr);
+
    /* Backup/Set ModeNo in BIOS scratch area */
    SiS_GetSetModeID(pScrn,ModeNo);
 
@@ -3993,84 +3842,6 @@ SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
 }
 #endif /* Linux_XF86 */
 
-
-#ifdef LINUX_XF86
-BOOLEAN
-SiS_GetPanelID(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
-{
-  const USHORT PanelTypeTable300[16] = {
-      0xc101, 0xc117, 0x0121, 0xc135, 0xc142, 0xc152, 0xc162, 0xc072,
-      0xc181, 0xc192, 0xc1a1, 0xc1b6, 0xc1c2, 0xc0d2, 0xc1e2, 0xc1f2
-  };
-  const USHORT PanelTypeTable31030x[16] = {
-      0xc102, 0xc112, 0x0122, 0xc132, 0xc142, 0xc152, 0xc169, 0xc179,
-      0x0189, 0xc192, 0xc1a2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
-  };
-  const USHORT PanelTypeTable310LVDS[16] = {
-      0xc111, 0xc122, 0xc133, 0xc144, 0xc155, 0xc166, 0xc177, 0xc188,
-      0xc199, 0xc0aa, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
-  };
-  USHORT tempax,tempbx,temp;
-
-  if(HwInfo->jChipType < SIS_315H) {
-
-     tempax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x18);
-     tempbx = tempax & 0x0F;
-     if(!(tempax & 0x10)){
-        if(SiS_Pr->SiS_IF_DEF_LVDS == 1){
-           tempbx = 0;
-           temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x38);
-           if(temp & 0x40) tempbx |= 0x08;
-           if(temp & 0x20) tempbx |= 0x02;
-           if(temp & 0x01) tempbx |= 0x01;
-           temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x39);
-           if(temp & 0x80) tempbx |= 0x04;
-        } else {
-           return 0;
-        }
-     }
-     tempbx = PanelTypeTable300[tempbx];
-     tempbx |= LCDSync;
-     temp = tempbx & 0x00FF;
-     SiS_SetReg(SiS_Pr->SiS_P3d4,0x36,temp);
-     temp = (tempbx & 0xFF00) >> 8;
-     SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x37,~(LCDSyncBit|LCDRGB18Bit),temp);
-
-  } else {
-
-     if(HwInfo->jChipType >= SIS_661) return 0;
-
-     tempax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1a);
-     tempax &= 0x1e;
-     tempax >>= 1;
-     if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-        if(tempax == 0) {
-           /* TODO: Include HUGE detection routine
-                   (Probably not worth bothering)
-           */
-           return 0;
-        }
-        temp = tempax & 0xff;
-        tempax--;
-        tempbx = PanelTypeTable310LVDS[tempax];
-     } else {
-        tempbx = PanelTypeTable31030x[tempax];
-        temp = tempbx & 0xff;
-     }
-     SiS_SetReg(SiS_Pr->SiS_P3d4,0x36,temp);
-     tempbx = (tempbx & 0xff00) >> 8;
-     temp = tempbx & 0xc1;
-     SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x37,~(LCDSyncBit|LCDRGB18Bit),temp);
-     if(SiS_Pr->SiS_VBType & VB_SISVB) {
-        temp = tempbx & 0x04;
-        SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x39,0xfb,temp);
-     }
-
-  }
-  return 1;
-}
-#endif
-
 #ifndef GETBITSTR
 #define BITMASK(h,l)           (((unsigned)(1U << ((h)-(l)+1))-1)<<(l))
 #define GENMASK(mask)          BITMASK(1?mask,0?mask)
@@ -4078,26 +3849,28 @@ SiS_GetPanelID(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 #define GETBITSTR(val,from,to)  ((GETBITS(val,from)) << (0?to))
 #endif
 
-static void
-SiS_CalcCRRegisters(SiS_Private *SiS_Pr, int depth)
+void
+SiS_CalcCRRegisters(struct SiS_Private *SiS_Pr, int depth)
 {
+   int x = 1; /* Fix sync */
+
    SiS_Pr->CCRT1CRTC[0]  =  ((SiS_Pr->CHTotal >> 3) - 5) & 0xff;               /* CR0 */
    SiS_Pr->CCRT1CRTC[1]  =  (SiS_Pr->CHDisplay >> 3) - 1;                      /* CR1 */
    SiS_Pr->CCRT1CRTC[2]  =  (SiS_Pr->CHBlankStart >> 3) - 1;                   /* CR2 */
    SiS_Pr->CCRT1CRTC[3]  =  (((SiS_Pr->CHBlankEnd >> 3) - 1) & 0x1F) | 0x80;   /* CR3 */
    SiS_Pr->CCRT1CRTC[4]  =  (SiS_Pr->CHSyncStart >> 3) + 3;                    /* CR4 */
    SiS_Pr->CCRT1CRTC[5]  =  ((((SiS_Pr->CHBlankEnd >> 3) - 1) & 0x20) << 2) |  /* CR5 */
-                                   (((SiS_Pr->CHSyncEnd >> 3) + 3) & 0x1F);
+                           (((SiS_Pr->CHSyncEnd >> 3) + 3) & 0x1F);
 
-   SiS_Pr->CCRT1CRTC[6]  =  (SiS_Pr->CVTotal - 2) & 0xFF;                      /* CR6 */
-   SiS_Pr->CCRT1CRTC[7]  =  (((SiS_Pr->CVTotal - 2) & 0x100) >> 8)             /* CR7 */
-                         | (((SiS_Pr->CVDisplay - 1) & 0x100) >> 7)
-                         | ((SiS_Pr->CVSyncStart & 0x100) >> 6)
-                         | (((SiS_Pr->CVBlankStart - 1) & 0x100) >> 5)
+   SiS_Pr->CCRT1CRTC[6]  =  (SiS_Pr->CVTotal       - 2) & 0xFF;                        /* CR6 */
+   SiS_Pr->CCRT1CRTC[7]  =  (((SiS_Pr->CVTotal     - 2) & 0x100) >> 8)         /* CR7 */
+                         | (((SiS_Pr->CVDisplay   - 1) & 0x100) >> 7)
+                         | (((SiS_Pr->CVSyncStart - x) & 0x100) >> 6)
+                         | (((SiS_Pr->CVBlankStart- 1) & 0x100) >> 5)
                          | 0x10
-                         | (((SiS_Pr->CVTotal - 2) & 0x200)   >> 4)
-                         | (((SiS_Pr->CVDisplay - 1) & 0x200) >> 3)
-                         | ((SiS_Pr->CVSyncStart & 0x200) >> 2);
+                         | (((SiS_Pr->CVTotal     - 2) & 0x200) >> 4)
+                         | (((SiS_Pr->CVDisplay   - 1) & 0x200) >> 3)
+                         | (((SiS_Pr->CVSyncStart - x) & 0x200) >> 2);
 
    SiS_Pr->CCRT1CRTC[16] = ((((SiS_Pr->CVBlankStart - 1) & 0x200) >> 4) >> 5);         /* CR9 */
 
@@ -4106,55 +3879,44 @@ SiS_CalcCRRegisters(SiS_Private *SiS_Pr, int depth)
       else if(SiS_Pr->CHDisplay >= 640)  SiS_Pr->CCRT1CRTC[16] |= 0x40;
    }
 
-#if 0
-   if (mode->VScan >= 32)
-       regp->CRTC[9] |= 0x1F;
-   else if (mode->VScan > 1)
-       regp->CRTC[9] |= mode->VScan - 1;
-#endif
-
-   SiS_Pr->CCRT1CRTC[8] =  (SiS_Pr->CVSyncStart     ) & 0xFF;                  /* CR10 */
-   SiS_Pr->CCRT1CRTC[9] =  ((SiS_Pr->CVSyncEnd      ) & 0x0F) | 0x80;          /* CR11 */
+   SiS_Pr->CCRT1CRTC[8] =  (SiS_Pr->CVSyncStart  - x) & 0xFF;                  /* CR10 */
+   SiS_Pr->CCRT1CRTC[9] =  ((SiS_Pr->CVSyncEnd   - x) & 0x0F) | 0x80;          /* CR11 */
    SiS_Pr->CCRT1CRTC[10] = (SiS_Pr->CVDisplay    - 1) & 0xFF;                  /* CR12 */
    SiS_Pr->CCRT1CRTC[11] = (SiS_Pr->CVBlankStart - 1) & 0xFF;                  /* CR15 */
    SiS_Pr->CCRT1CRTC[12] = (SiS_Pr->CVBlankEnd   - 1) & 0xFF;                  /* CR16 */
 
    SiS_Pr->CCRT1CRTC[13] =                                                     /* SRA */
-                        GETBITSTR((SiS_Pr->CVTotal     -2), 10:10, 0:0) |
-                        GETBITSTR((SiS_Pr->CVDisplay   -1), 10:10, 1:1) |
-                        GETBITSTR((SiS_Pr->CVBlankStart-1), 10:10, 2:2) |
-                        GETBITSTR((SiS_Pr->CVSyncStart   ), 10:10, 3:3) |
-                        GETBITSTR((SiS_Pr->CVBlankEnd  -1),   8:8, 4:4) |
-                        GETBITSTR((SiS_Pr->CVSyncEnd     ),   4:4, 5:5) ;
+                       GETBITSTR((SiS_Pr->CVTotal     -2), 10:10, 0:0) |
+                       GETBITSTR((SiS_Pr->CVDisplay   -1), 10:10, 1:1) |
+                       GETBITSTR((SiS_Pr->CVBlankStart-1), 10:10, 2:2) |
+                       GETBITSTR((SiS_Pr->CVSyncStart -x), 10:10, 3:3) |
+                       GETBITSTR((SiS_Pr->CVBlankEnd  -1),   8:8, 4:4) |
+                       GETBITSTR((SiS_Pr->CVSyncEnd     ),   4:4, 5:5) ;
 
    SiS_Pr->CCRT1CRTC[14] =                                                     /* SRB */
-                        GETBITSTR((SiS_Pr->CHTotal      >> 3) - 5, 9:8, 1:0) |
-                        GETBITSTR((SiS_Pr->CHDisplay    >> 3) - 1, 9:8, 3:2) |
-                        GETBITSTR((SiS_Pr->CHBlankStart >> 3) - 1, 9:8, 5:4) |
-                        GETBITSTR((SiS_Pr->CHSyncStart  >> 3) + 3, 9:8, 7:6) ;
+                       GETBITSTR((SiS_Pr->CHTotal      >> 3) - 5, 9:8, 1:0) |
+                       GETBITSTR((SiS_Pr->CHDisplay    >> 3) - 1, 9:8, 3:2) |
+                       GETBITSTR((SiS_Pr->CHBlankStart >> 3) - 1, 9:8, 5:4) |
+                       GETBITSTR((SiS_Pr->CHSyncStart  >> 3) + 3, 9:8, 7:6) ;
 
 
    SiS_Pr->CCRT1CRTC[15] =                                                     /* SRC */
-                        GETBITSTR((SiS_Pr->CHBlankEnd >> 3) - 1, 7:6, 1:0) |
-                        GETBITSTR((SiS_Pr->CHSyncEnd  >> 3) + 3, 5:5, 2:2) ;
+                       GETBITSTR((SiS_Pr->CHBlankEnd >> 3) - 1, 7:6, 1:0) |
+                       GETBITSTR((SiS_Pr->CHSyncEnd  >> 3) + 3, 5:5, 2:2) ;
 }
 
 void
-SiS_CalcLCDACRT1Timing(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex)
+SiS_CalcLCDACRT1Timing(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+               unsigned short ModeIdIndex)
 {
-   USHORT modeflag, tempax, tempbx, VGAHDE = SiS_Pr->SiS_VGAHDE;
-   int i,j;
+   unsigned short modeflag, tempax, tempbx = 0, remaining = 0;
+   unsigned short VGAHDE = SiS_Pr->SiS_VGAHDE;
+   int i, j;
 
    /* 1:1 data: use data set by setcrt1crtc() */
    if(SiS_Pr->SiS_LCDInfo & LCDPass11) return;
 
-   if(ModeNo <= 0x13) {
-     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-   } else if(SiS_Pr->UseCustomMode) {
-     modeflag = SiS_Pr->CModeFlag;
-   } else {
-     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-   }
+   modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
 
    if(modeflag & HalfDCLK) VGAHDE >>= 1;
 
@@ -4164,32 +3926,91 @@ SiS_CalcLCDACRT1Timing(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex)
    SiS_Pr->CVDisplay = SiS_Pr->SiS_VGAVDE;
    SiS_Pr->CVBlankStart = SiS_Pr->SiS_VGAVDE;
 
-   tempbx = SiS_Pr->PanelHT - SiS_Pr->PanelXRes;
-   tempax = SiS_Pr->SiS_VGAHDE;  /* not /2 ! */
-   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
-      tempax = SiS_Pr->PanelXRes;
+   if(SiS_Pr->ChipType < SIS_315H) {
+#ifdef SIS300
+      tempbx = SiS_Pr->SiS_VGAHT;
+      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+         tempbx = SiS_Pr->PanelHT;
+      }
+      if(modeflag & HalfDCLK) tempbx >>= 1;
+      remaining = tempbx % 8;
+#endif
+   } else {
+#ifdef SIS315H
+      /* OK for LCDA, LVDS */
+      tempbx = SiS_Pr->PanelHT - SiS_Pr->PanelXRes;
+      tempax = SiS_Pr->SiS_VGAHDE;  /* not /2 ! */
+      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+         tempax = SiS_Pr->PanelXRes;
+      }
+      tempbx += tempax;
+      if(modeflag & HalfDCLK) tempbx -= VGAHDE;
+#endif
    }
-   tempbx += tempax;
-   if(modeflag & HalfDCLK) tempbx -= VGAHDE;
    SiS_Pr->CHTotal = SiS_Pr->CHBlankEnd = tempbx;
 
-   tempax = VGAHDE;
-   tempbx = SiS_Pr->CHTotal;
-   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
-      tempbx = SiS_Pr->PanelXRes;
-      if(modeflag & HalfDCLK) tempbx >>= 1;
-      tempax += ((tempbx - tempax) >> 1);
+   if(SiS_Pr->ChipType < SIS_315H) {
+#ifdef SIS300
+      if(SiS_Pr->SiS_VGAHDE == SiS_Pr->PanelXRes) {
+        SiS_Pr->CHSyncStart = SiS_Pr->SiS_VGAHDE + ((SiS_Pr->PanelHRS + 1) & ~1);
+        SiS_Pr->CHSyncEnd = SiS_Pr->CHSyncStart + SiS_Pr->PanelHRE;
+        if(modeflag & HalfDCLK) {
+           SiS_Pr->CHSyncStart >>= 1;
+           SiS_Pr->CHSyncEnd >>= 1;
+        }
+      } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+        tempax = (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) >> 1;
+        tempbx = (SiS_Pr->PanelHRS + 1) & ~1;
+        if(modeflag & HalfDCLK) {
+           tempax >>= 1;
+           tempbx >>= 1;
+        }
+        SiS_Pr->CHSyncStart = (VGAHDE + tempax + tempbx + 7) & ~7;
+        tempax = SiS_Pr->PanelHRE + 7;
+        if(modeflag & HalfDCLK) tempax >>= 1;
+        SiS_Pr->CHSyncEnd = (SiS_Pr->CHSyncStart + tempax) & ~7;
+      } else {
+        SiS_Pr->CHSyncStart = SiS_Pr->SiS_VGAHDE;
+        if(modeflag & HalfDCLK) {
+           SiS_Pr->CHSyncStart >>= 1;
+           tempax = ((SiS_Pr->CHTotal - SiS_Pr->CHSyncStart) / 3) << 1;
+           SiS_Pr->CHSyncEnd = SiS_Pr->CHSyncStart + tempax;
+        } else {
+           SiS_Pr->CHSyncEnd = (SiS_Pr->CHSyncStart + (SiS_Pr->CHTotal / 10) + 7) & ~7;
+           SiS_Pr->CHSyncStart += 8;
+        }
+      }
+#endif
+   } else {
+#ifdef SIS315H
+      tempax = VGAHDE;
+      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+        tempbx = SiS_Pr->PanelXRes;
+        if(modeflag & HalfDCLK) tempbx >>= 1;
+        tempax += ((tempbx - tempax) >> 1);
+      }
+      tempax += SiS_Pr->PanelHRS;
+      SiS_Pr->CHSyncStart = tempax;
+      tempax += SiS_Pr->PanelHRE;
+      SiS_Pr->CHSyncEnd = tempax;
+#endif
    }
 
-   tempax += SiS_Pr->PanelHRS;
-   SiS_Pr->CHSyncStart = tempax;
-   tempax += SiS_Pr->PanelHRE;
-   SiS_Pr->CHSyncEnd = tempax;
-
    tempbx = SiS_Pr->PanelVT - SiS_Pr->PanelYRes;
    tempax = SiS_Pr->SiS_VGAVDE;
    if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
       tempax = SiS_Pr->PanelYRes;
+   } else if(SiS_Pr->ChipType < SIS_315H) {
+#ifdef SIS300
+      /* Stupid hack for 640x400/320x200 */
+      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
+        if((tempax + tempbx) == 438) tempbx += 16;
+      } else if((SiS_Pr->SiS_LCDResInfo == Panel_800x600) ||
+               (SiS_Pr->SiS_LCDResInfo == Panel_1024x600)) {
+        tempax = 0;
+        tempbx = SiS_Pr->SiS_VGAVT;
+      }
+#endif
    }
    SiS_Pr->CVTotal = SiS_Pr->CVBlankEnd = tempbx + tempax;
 
@@ -4201,22 +4022,28 @@ SiS_CalcLCDACRT1Timing(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex)
    SiS_Pr->CVSyncStart = tempax;
    tempax += SiS_Pr->PanelVRE;
    SiS_Pr->CVSyncEnd = tempax;
+   if(SiS_Pr->ChipType < SIS_315H) {
+      SiS_Pr->CVSyncStart--;
+      SiS_Pr->CVSyncEnd--;
+   }
 
    SiS_CalcCRRegisters(SiS_Pr, 8);
+   SiS_Pr->CCRT1CRTC[15] &= ~0xF8;
+   SiS_Pr->CCRT1CRTC[15] |= (remaining << 4);
    SiS_Pr->CCRT1CRTC[16] &= ~0xE0;
 
    SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
 
-   for(i=0,j=0;i<=7;i++,j++) {
+   for(i = 0, j = 0; i <= 7; i++, j++) {
       SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
    }
-   for(j=0x10;i<=10;i++,j++) {
+   for(j = 0x10; i <= 10; i++, j++) {
       SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
    }
-   for(j=0x15;i<=12;i++,j++) {
+   for(j = 0x15; i <= 12; i++, j++) {
       SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
    }
-   for(j=0x0A;i<=15;i++,j++) {
+   for(j = 0x0A; i <= 15; i++, j++) {
       SiS_SetReg(SiS_Pr->SiS_P3c4,j,SiS_Pr->CCRT1CRTC[i]);
    }
 
@@ -4227,1092 +4054,192 @@ SiS_CalcLCDACRT1Timing(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex)
    if(modeflag & DoubleScanMode) tempax |= 0x80;
    SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0x5F,tempax);
 
+#ifdef SIS_XORG_XF86
 #ifdef TWDEBUG
    xf86DrvMsg(0, X_INFO, "%d %d %d %d  %d %d %d %d  (%d %d %d %d)\n",
-               SiS_Pr->CHDisplay, SiS_Pr->CHSyncStart, SiS_Pr->CHSyncEnd, SiS_Pr->CHTotal,
+       SiS_Pr->CHDisplay, SiS_Pr->CHSyncStart, SiS_Pr->CHSyncEnd, SiS_Pr->CHTotal,
        SiS_Pr->CVDisplay, SiS_Pr->CVSyncStart, SiS_Pr->CVSyncEnd, SiS_Pr->CVTotal,
        SiS_Pr->CHBlankStart, SiS_Pr->CHBlankEnd, SiS_Pr->CVBlankStart, SiS_Pr->CVBlankEnd);
-
    xf86DrvMsg(0, X_INFO, " {{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
-       SiS_Pr->CCRT1CRTC[0], SiS_Pr->CCRT1CRTC[1],
+       SiS_Pr->CCRT1CRTC[0], SiS_Pr->CCRT1CRTC[1],
        SiS_Pr->CCRT1CRTC[2], SiS_Pr->CCRT1CRTC[3],
        SiS_Pr->CCRT1CRTC[4], SiS_Pr->CCRT1CRTC[5],
        SiS_Pr->CCRT1CRTC[6], SiS_Pr->CCRT1CRTC[7]);
    xf86DrvMsg(0, X_INFO, "   0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
-       SiS_Pr->CCRT1CRTC[8], SiS_Pr->CCRT1CRTC[9],
+       SiS_Pr->CCRT1CRTC[8], SiS_Pr->CCRT1CRTC[9],
        SiS_Pr->CCRT1CRTC[10], SiS_Pr->CCRT1CRTC[11],
        SiS_Pr->CCRT1CRTC[12], SiS_Pr->CCRT1CRTC[13],
        SiS_Pr->CCRT1CRTC[14], SiS_Pr->CCRT1CRTC[15]);
    xf86DrvMsg(0, X_INFO, "   0x%02x}},\n", SiS_Pr->CCRT1CRTC[16]);
 #endif
+#endif
 }
 
-#ifdef LINUX_XF86
-
 void
-SiS_MakeClockRegs(ScrnInfoPtr pScrn, int clock, UCHAR *p2b, UCHAR *p2c)
-{
-   int          out_n, out_dn, out_div, out_sbit, out_scale;
-   unsigned int vclk[5];
-
-#define Midx         0
-#define Nidx         1
-#define VLDidx       2
-#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);
+SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata,
+                       int xres, int yres,
+#ifdef SIS_XORG_XF86
+                       DisplayModePtr current
 #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
-   }
-}
-
+#ifdef SIS_LINUX_KERNEL
+                       struct fb_var_screeninfo *var, BOOLEAN writeres
 #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;
-
-   pSiS->SiS_Pr->CHDisplay = mode->HDisplay;
-   pSiS->SiS_Pr->CHSyncStart = mode->HSyncStart;
-   pSiS->SiS_Pr->CHSyncEnd = mode->HSyncEnd;
-   pSiS->SiS_Pr->CHTotal = mode->HTotal;
-
-   pSiS->SiS_Pr->CVDisplay = mode->VDisplay;
-   pSiS->SiS_Pr->CVSyncStart = mode->VSyncStart;
-   pSiS->SiS_Pr->CVSyncEnd = mode->VSyncEnd;
-   pSiS->SiS_Pr->CVTotal = mode->VTotal;
-
-   pSiS->SiS_Pr->CFlags = mode->Flags;
-
-   if(pSiS->SiS_Pr->CFlags & V_INTERLACE) {
-      pSiS->SiS_Pr->CVDisplay >>= 1;
-      pSiS->SiS_Pr->CVSyncStart >>= 1;
-      pSiS->SiS_Pr->CVSyncEnd >>= 1;
-      pSiS->SiS_Pr->CVTotal >>= 1;
-   }
-   if(pSiS->SiS_Pr->CFlags & V_DBLSCAN) {
-      /* pSiS->SiS_Pr->CDClock <<= 1; */
-      pSiS->SiS_Pr->CVDisplay <<= 1;
-      pSiS->SiS_Pr->CVSyncStart <<= 1;
-      pSiS->SiS_Pr->CVSyncEnd <<= 1;
-      pSiS->SiS_Pr->CVTotal <<= 1;
-   }
+   unsigned short HRE, HBE, HRS, HBS, HDE, HT;
+   unsigned short VRE, VBE, VRS, VBS, VDE, VT;
+   unsigned char  sr_data, cr_data, cr_data2;
+   int            A, B, C, D, E, F, temp;
 
-   pSiS->SiS_Pr->CHBlankStart = pSiS->SiS_Pr->CHDisplay;
-   pSiS->SiS_Pr->CHBlankEnd = pSiS->SiS_Pr->CHTotal;
-   pSiS->SiS_Pr->CVBlankStart = pSiS->SiS_Pr->CVSyncStart - 1;
-   pSiS->SiS_Pr->CVBlankEnd = pSiS->SiS_Pr->CVTotal;
+   sr_data = crdata[14];
 
-   SiS_MakeClockRegs(pScrn, pSiS->SiS_Pr->CDClock, &pSiS->SiS_Pr->CSR2B, &pSiS->SiS_Pr->CSR2C);
+   /* Horizontal total */
+   HT =  crdata[0] | ((unsigned short)(sr_data & 0x03) << 8);
+   A = HT + 5;
 
-   pSiS->SiS_Pr->CSRClock = (pSiS->SiS_Pr->CDClock / 1000) + 1;
+   /* Horizontal display enable end */
+   HDE = crdata[1] | ((unsigned short)(sr_data & 0x0C) << 6);
+   E = HDE + 1;
 
-   SiS_CalcCRRegisters(pSiS->SiS_Pr, depth);
+   /* Horizontal retrace (=sync) start */
+   HRS = crdata[4] | ((unsigned short)(sr_data & 0xC0) << 2);
+   F = HRS - E - 3;
 
-   switch(depth) {
-   case 8:  pSiS->SiS_Pr->CModeFlag |= 0x223b; break;
-   case 16: pSiS->SiS_Pr->CModeFlag |= 0x227d; break;
-   case 32: pSiS->SiS_Pr->CModeFlag |= 0x22ff; break;
-   default: return 0;
-   }
+   /* Horizontal blank start */
+   HBS = crdata[2] | ((unsigned short)(sr_data & 0x30) << 4);
 
-   if(pSiS->SiS_Pr->CFlags & V_DBLSCAN)
-      pSiS->SiS_Pr->CModeFlag |= DoubleScanMode;
+   sr_data = crdata[15];
+   cr_data = crdata[5];
 
-   if((pSiS->SiS_Pr->CVDisplay >= 1024)        ||
-      (pSiS->SiS_Pr->CVTotal >= 1024)   ||
-      (pSiS->SiS_Pr->CHDisplay >= 1024))
-      pSiS->SiS_Pr->CModeFlag |= LineCompareOff;
+   /* Horizontal blank end */
+   HBE = (crdata[3] & 0x1f) |
+         ((unsigned short)(cr_data & 0x80) >> 2) |
+         ((unsigned short)(sr_data & 0x03) << 6);
 
-   if(pSiS->SiS_Pr->CFlags & V_CLKDIV2)
-      pSiS->SiS_Pr->CModeFlag |= HalfDCLK;
+   /* Horizontal retrace (=sync) end */
+   HRE = (cr_data & 0x1f) | ((sr_data & 0x04) << 3);
 
-   pSiS->SiS_Pr->CInfoFlag = 0x0007;
+   temp = HBE - ((E - 1) & 255);
+   B = (temp > 0) ? temp : (temp + 256);
 
-   if(pSiS->SiS_Pr->CFlags & V_NHSYNC)
-      pSiS->SiS_Pr->CInfoFlag |= 0x4000;
+   temp = HRE - ((E + F + 3) & 63);
+   C = (temp > 0) ? temp : (temp + 64);
 
-   if(pSiS->SiS_Pr->CFlags & V_NVSYNC)
-      pSiS->SiS_Pr->CInfoFlag |= 0x8000;
+   D = B - F - C;
 
-   if(pSiS->SiS_Pr->CFlags & V_INTERLACE)
-      pSiS->SiS_Pr->CInfoFlag |= InterlaceMode;
-
-   pSiS->SiS_Pr->UseCustomMode = TRUE;
+#ifdef SIS_XORG_XF86
+   current->HDisplay   = (E * 8);
+   current->HSyncStart = (E * 8) + (F * 8);
+   current->HSyncEnd   = (E * 8) + (F * 8) + (C * 8);
+   current->HTotal     = (E * 8) + (F * 8) + (C * 8) + (D * 8);
 #ifdef TWDEBUG
-   xf86DrvMsg(0, X_INFO, "Custom mode %dx%d:\n",
-       pSiS->SiS_Pr->CHDisplay,pSiS->SiS_Pr->CVDisplay);
-   xf86DrvMsg(0, X_INFO, "Modeflag %04x, Infoflag %04x\n",
-       pSiS->SiS_Pr->CModeFlag, pSiS->SiS_Pr->CInfoFlag);
-   xf86DrvMsg(0, X_INFO, " {{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
-       pSiS->SiS_Pr->CCRT1CRTC[0], pSiS->SiS_Pr->CCRT1CRTC[1],
-       pSiS->SiS_Pr->CCRT1CRTC[2], pSiS->SiS_Pr->CCRT1CRTC[3],
-       pSiS->SiS_Pr->CCRT1CRTC[4], pSiS->SiS_Pr->CCRT1CRTC[5],
-       pSiS->SiS_Pr->CCRT1CRTC[6], pSiS->SiS_Pr->CCRT1CRTC[7]);
-   xf86DrvMsg(0, X_INFO, "  0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
-       pSiS->SiS_Pr->CCRT1CRTC[8], pSiS->SiS_Pr->CCRT1CRTC[9],
-       pSiS->SiS_Pr->CCRT1CRTC[10], pSiS->SiS_Pr->CCRT1CRTC[11],
-       pSiS->SiS_Pr->CCRT1CRTC[12], pSiS->SiS_Pr->CCRT1CRTC[13],
-       pSiS->SiS_Pr->CCRT1CRTC[14], pSiS->SiS_Pr->CCRT1CRTC[15]);
-   xf86DrvMsg(0, X_INFO, "  0x%02x}},\n", pSiS->SiS_Pr->CCRT1CRTC[16]);
-   xf86DrvMsg(0, X_INFO, "Clock: 0x%02x, 0x%02x, %d\n",
-       pSiS->SiS_Pr->CSR2B, pSiS->SiS_Pr->CSR2C, pSiS->SiS_Pr->CSRClock);
-#endif
-   return 1;
-}
-
-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)
-{
-   SISPtr         pSiS = SISPTR(pScrn);
-   unsigned short VRE, VBE, VRS, VBS, VDE, VT;
-   unsigned short HRE, HBE, HRS, HBS, HDE, HT;
-   unsigned char  sr_data, cr_data, cr_data2, cr_data3;
-   unsigned char  sr2b, sr2c;
-   float          num, denum, postscalar, divider;
-   int            A, B, C, D, E, F, temp, i, j, k, l, index, vclkindex;
-   DisplayModePtr new = NULL, current = NULL, first = NULL;
-   BOOLEAN        done = FALSE;
-#if 0
-   DisplayModePtr backup = NULL;
-#endif
-
-   pSiS->backupmodelist = NULL;
-   pSiS->AddedPlasmaModes = FALSE;
-
-   /* Initialize our pointers */
-   if(pSiS->VGAEngine == SIS_300_VGA) {
-#ifdef SIS300
-      InitTo300Pointer(pSiS->SiS_Pr, &pSiS->sishw_ext);
+   xf86DrvMsg(0, X_INFO,
+               "H: A %d B %d C %d D %d E %d F %d  HT %d HDE %d HRS %d HBS %d HBE %d HRE %d\n",
+               A, B, C, D, E, F, HT, HDE, HRS, HBS, HBE, HRE);
 #else
-      return NULL;
+   (void)VBS;  (void)HBS;  (void)A;
 #endif
-   } else if(pSiS->VGAEngine == SIS_315_VGA) {
-#ifdef SIS315H
-      InitTo310Pointer(pSiS->SiS_Pr, &pSiS->sishw_ext);
-#else
-      return NULL;
 #endif
-   } else return NULL;
-
-   i = 0;
-   while(pSiS->SiS_Pr->SiS_RefIndex[i].Ext_InfoFlag != 0xFFFF) {
-
-      index = pSiS->SiS_Pr->SiS_RefIndex[i].Ext_CRT1CRTC;
-
-      /* 0x5a (320x240) is a pure FTSN mode, not DSTN! */
-      if((!pSiS->FSTN) &&
-        (pSiS->SiS_Pr->SiS_RefIndex[i].ModeID == 0x5a))  {
-           i++;
-          continue;
-      }
-      if((pSiS->FSTN) &&
-         (pSiS->SiS_Pr->SiS_RefIndex[i].XRes == 320) &&
-        (pSiS->SiS_Pr->SiS_RefIndex[i].YRes == 240) &&
-        (pSiS->SiS_Pr->SiS_RefIndex[i].ModeID != 0x5a)) {
-          i++;
-          continue;
-      }
-
-      if(!(new = xalloc(sizeof(DisplayModeRec)))) return first;
-      memset(new, 0, sizeof(DisplayModeRec));
-      if(!(new->name = xalloc(10))) {
-               xfree(new);
-               return first;
-      }
-      if(!first) first = new;
-      if(current) {
-         current->next = new;
-        new->prev = current;
-      }
-
-      current = new;
-
-      sprintf(current->name, "%dx%d", pSiS->SiS_Pr->SiS_RefIndex[i].XRes,
-                                      pSiS->SiS_Pr->SiS_RefIndex[i].YRes);
-
-      current->status = MODE_OK;
-
-      current->type = M_T_DEFAULT;
-
-      vclkindex = pSiS->SiS_Pr->SiS_RefIndex[i].Ext_CRTVCLK;
-      if(pSiS->VGAEngine == SIS_300_VGA) vclkindex &= 0x3F;
-
-      sr2b = pSiS->SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
-      sr2c = pSiS->SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
-
-      divider = (sr2b & 0x80) ? 2.0 : 1.0;
-      postscalar = (sr2c & 0x80) ?
-              ( (((sr2c >> 5) & 0x03) == 0x02) ? 6.0 : 8.0) : (((sr2c >> 5) & 0x03) + 1.0);
-      num = (sr2b & 0x7f) + 1.0;
-      denum = (sr2c & 0x1f) + 1.0;
-
-#ifdef TWDEBUG
-      xf86DrvMsg(0, X_INFO, "------------\n");
-      xf86DrvMsg(0, X_INFO, "sr2b: %x sr2c %x div %f ps %f num %f denum %f\n",
-         sr2b, sr2c, divider, postscalar, num, denum);
+#ifdef SIS_LINUX_KERNEL
+   if(writeres) var->xres = xres = E * 8;
+   var->left_margin = D * 8;
+   var->right_margin = F * 8;
+   var->hsync_len = C * 8;
 #endif
 
-      current->Clock = (int)(14318 * (divider / postscalar) * (num / denum));
-
-      sr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[14];
-       /* inSISIDXREG(SISSR, 0x0b, sr_data); */
-
-      cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[0];
-       /* inSISIDXREG(SISCR, 0x00, cr_data); */
-
-      /* Horizontal total */
-      HT = (cr_data & 0xff) |
-           ((unsigned short) (sr_data & 0x03) << 8);
-      A = HT + 5;
-
-      cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[1];
-       /* inSISIDXREG(SISCR, 0x01, cr_data); */
-
-      /* Horizontal display enable end */
-      HDE = (cr_data & 0xff) |
-            ((unsigned short) (sr_data & 0x0C) << 6);
-      E = HDE + 1;  /* 0x80 0x64 */
-
-      cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[4];
-       /* inSISIDXREG(SISCR, 0x04, cr_data); */
-
-      /* Horizontal retrace (=sync) start */
-      HRS = (cr_data & 0xff) |
-            ((unsigned short) (sr_data & 0xC0) << 2);
-      F = HRS - E - 3;  /* 0x06 0x06 */
-
-      cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[2];
-       /* inSISIDXREG(SISCR, 0x02, cr_data); */
-
-      /* Horizontal blank start */
-      HBS = (cr_data & 0xff) |
-            ((unsigned short) (sr_data & 0x30) << 4);
-
-      sr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[15];
-       /* inSISIDXREG(SISSR, 0x0c, sr_data); */
-
-      cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[3];
-       /* inSISIDXREG(SISCR, 0x03, cr_data);  */
-
-      cr_data2 = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[5];
-       /* inSISIDXREG(SISCR, 0x05, cr_data2); */
-
-      /* Horizontal blank end */
-      HBE = (cr_data & 0x1f) |
-            ((unsigned short) (cr_data2 & 0x80) >> 2) |
-           ((unsigned short) (sr_data & 0x03) << 6);
-
-      /* Horizontal retrace (=sync) end */
-      HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3);
-
-      temp = HBE - ((E - 1) & 255);
-      B = (temp > 0) ? temp : (temp + 256);
-
-      temp = HRE - ((E + F + 3) & 63);
-      C = (temp > 0) ? temp : (temp + 64); /* 0x0b 0x0b */
-
-      D = B - F - C;
-
-      if((pSiS->SiS_Pr->SiS_RefIndex[i].XRes == 320) &&
-        ((pSiS->SiS_Pr->SiS_RefIndex[i].YRes == 200) ||
-         (pSiS->SiS_Pr->SiS_RefIndex[i].YRes == 240))) {
-
-        /* Terrible hack, but correct CRTC data for
-         * these modes only produces a black screen...
-         * (HRE is 0, leading into a too large C and
-         * a negative D. The CRT controller does not
-         * seem to like correcting HRE to 50
-         */
-        current->HDisplay   = 320;
-         current->HSyncStart = 328;
-         current->HSyncEnd   = 376;
-         current->HTotal     = 400;
-
-      } else {
-
-         current->HDisplay   = (E * 8);
-         current->HSyncStart = (E * 8) + (F * 8);
-         current->HSyncEnd   = (E * 8) + (F * 8) + (C * 8);
-         current->HTotal     = (E * 8) + (F * 8) + (C * 8) + (D * 8);
-
-      }
-
-#ifdef TWDEBUG
-      xf86DrvMsg(0, X_INFO,
-        "H: A %d B %d C %d D %d E %d F %d  HT %d HDE %d HRS %d HBS %d HBE %d HRE %d\n",
-       A, B, C, D, E, F, HT, HDE, HRS, HBS, HBE, HRE);
-#endif
-
-      sr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[13];
-       /* inSISIDXREG(SISSR, 0x0A, sr_data); */
-
-      cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[6];
-        /* inSISIDXREG(SISCR, 0x06, cr_data); */
-
-      cr_data2 = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[7];
-        /* inSISIDXREG(SISCR, 0x07, cr_data2);  */
-
-      /* Vertical total */
-      VT = (cr_data & 0xFF) |
-           ((unsigned short) (cr_data2 & 0x01) << 8) |
-          ((unsigned short)(cr_data2 & 0x20) << 4) |
-          ((unsigned short) (sr_data & 0x01) << 10);
-      A = VT + 2;
-
-      cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[10];
-       /* inSISIDXREG(SISCR, 0x12, cr_data);  */
-
-      /* Vertical display enable end */
-      VDE = (cr_data & 0xff) |
-            ((unsigned short) (cr_data2 & 0x02) << 7) |
-           ((unsigned short) (cr_data2 & 0x40) << 3) |
-           ((unsigned short) (sr_data & 0x02) << 9);
-      E = VDE + 1;
-
-      cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[8];
-       /* inSISIDXREG(SISCR, 0x10, cr_data); */
-
-      /* Vertical retrace (=sync) start */
-      VRS = (cr_data & 0xff) |
-            ((unsigned short) (cr_data2 & 0x04) << 6) |
-           ((unsigned short) (cr_data2 & 0x80) << 2) |
-           ((unsigned short) (sr_data & 0x08) << 7);
-      F = VRS + 1 - E;
-
-      cr_data =  pSiS->SiS_Pr->SiS_CRT1Table[index].CR[11];
-       /* inSISIDXREG(SISCR, 0x15, cr_data);  */
-
-      cr_data3 = (pSiS->SiS_Pr->SiS_CRT1Table[index].CR[16] & 0x01) << 5;
-       /* inSISIDXREG(SISCR, 0x09, cr_data3);  */
-
-      /* Vertical blank start */
-      VBS = (cr_data & 0xff) |
-            ((unsigned short) (cr_data2 & 0x08) << 5) |
-           ((unsigned short) (cr_data3 & 0x20) << 4) |
-           ((unsigned short) (sr_data & 0x04) << 8);
-
-      cr_data =  pSiS->SiS_Pr->SiS_CRT1Table[index].CR[12];
-       /* inSISIDXREG(SISCR, 0x16, cr_data); */
-
-      /* Vertical blank end */
-      VBE = (cr_data & 0xff) |
-            ((unsigned short) (sr_data & 0x10) << 4);
-      temp = VBE - ((E - 1) & 511);
-      B = (temp > 0) ? temp : (temp + 512);
-
-      cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[9];
-       /* inSISIDXREG(SISCR, 0x11, cr_data); */
-
-      /* Vertical retrace (=sync) end */
-      VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1);
-      temp = VRE - ((E + F - 1) & 31);
-      C = (temp > 0) ? temp : (temp + 32);
-
-      D = B - F - C;
-
-      current->VDisplay   = VDE + 1;
-      current->VSyncStart = VRS + 1;
-      current->VSyncEnd   = ((VRS & ~0x1f) | VRE) + 1;
-      if(VRE <= (VRS & 0x1f)) current->VSyncEnd += 32;
-      current->VTotal     = E + D + C + F;
-
+   /* Vertical */
+   sr_data = crdata[13];
+   cr_data = crdata[7];
+
+   /* Vertical total */
+   VT  = crdata[6] |
+        ((unsigned short)(cr_data & 0x01) << 8) |
+        ((unsigned short)(cr_data & 0x20) << 4) |
+        ((unsigned short)(sr_data & 0x01) << 10);
+   A = VT + 2;
+
+   /* Vertical display enable end */
+   VDE = crdata[10] |
+        ((unsigned short)(cr_data & 0x02) << 7) |
+        ((unsigned short)(cr_data & 0x40) << 3) |
+        ((unsigned short)(sr_data & 0x02) << 9);
+   E = VDE + 1;
+
+   /* Vertical retrace (=sync) start */
+   VRS = crdata[8] |
+        ((unsigned short)(cr_data & 0x04) << 6) |
+        ((unsigned short)(cr_data & 0x80) << 2) |
+        ((unsigned short)(sr_data & 0x08) << 7);
+   F = VRS + 1 - E;
+
+   cr_data2 = (crdata[16] & 0x01) << 5;
+
+   /* Vertical blank start */
+   VBS = crdata[11] |
+        ((unsigned short)(cr_data  & 0x08) << 5) |
+        ((unsigned short)(cr_data2 & 0x20) << 4) |
+        ((unsigned short)(sr_data  & 0x04) << 8);
+
+   /* Vertical blank end */
+   VBE = crdata[12] | ((unsigned short)(sr_data & 0x10) << 4);
+   temp = VBE - ((E - 1) & 511);
+   B = (temp > 0) ? temp : (temp + 512);
+
+   /* Vertical retrace (=sync) end */
+   VRE = (crdata[9] & 0x0f) | ((sr_data & 0x20) >> 1);
+   temp = VRE - ((E + F - 1) & 31);
+   C = (temp > 0) ? temp : (temp + 32);
+
+   D = B - F - C;
+
+#ifdef SIS_XORG_XF86
+   current->VDisplay   = VDE + 1;
+   current->VSyncStart = VRS + 1;
+   current->VSyncEnd   = ((VRS & ~0x1f) | VRE) + 1;
+   if(VRE <= (VRS & 0x1f)) current->VSyncEnd += 32;
+   current->VTotal     = E + D + C + F;
 #if 0
-      current->VDisplay   = E;
-      current->VSyncStart = E + D;
-      current->VSyncEnd   = E + D + C;
-      current->VTotal     = E + D + C + F;
+   current->VDisplay   = E;
+   current->VSyncStart = E + D;
+   current->VSyncEnd   = E + D + C;
+   current->VTotal     = E + D + C + F;
 #endif
-
-#ifdef TWDEBUG
-      xf86DrvMsg(0, X_INFO,
-        "V: A %d B %d C %d D %d E %d F %d  VT %d VDE %d VRS %d VBS %d VBE %d VRE %d\n",
-       A, B, C, D, E, F, VT, VDE, VRS, VBS, VBE, VRE);
-#endif
-
-      if(pSiS->SiS_Pr->SiS_RefIndex[i].Ext_InfoFlag & 0x4000)
-          current->Flags |= V_NHSYNC;
-      else
-          current->Flags |= V_PHSYNC;
-
-      if(pSiS->SiS_Pr->SiS_RefIndex[i].Ext_InfoFlag & 0x8000)
-         current->Flags |= V_NVSYNC;
-      else
-          current->Flags |= V_PVSYNC;
-
-      if(pSiS->SiS_Pr->SiS_RefIndex[i].Ext_InfoFlag & 0x0080)
-          current->Flags |= V_INTERLACE;
-
-      j = 0;
-      while(pSiS->SiS_Pr->SiS_EModeIDTable[j].Ext_ModeID != 0xff) {
-          if(pSiS->SiS_Pr->SiS_EModeIDTable[j].Ext_ModeID ==
-                         pSiS->SiS_Pr->SiS_RefIndex[i].ModeID) {
-              if(pSiS->SiS_Pr->SiS_EModeIDTable[j].Ext_ModeFlag & DoubleScanMode) {
-                 current->Flags |= V_DBLSCAN;
-              }
-             break;
-          }
-         j++;
-      }
-
-      if(current->Flags & V_INTERLACE) {
-         current->VDisplay <<= 1;
-        current->VSyncStart <<= 1;
-        current->VSyncEnd <<= 1;
-        current->VTotal <<= 1;
-        current->VTotal |= 1;
-      }
-      if(current->Flags & V_DBLSCAN) {
-         current->Clock >>= 1;
-        current->VDisplay >>= 1;
-        current->VSyncStart >>= 1;
-        current->VSyncEnd >>= 1;
-        current->VTotal >>= 1;
-      }
-
 #ifdef TWDEBUG
-      xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-       "Built-in: %s %.2f %d %d %d %d %d %d %d %d\n",
-       current->name, (float)current->Clock / 1000,
-       current->HDisplay, current->HSyncStart, current->HSyncEnd, current->HTotal,
-       current->VDisplay, current->VSyncStart, current->VSyncEnd, current->VTotal);
-#else
-        (void)VBS;  (void)HBS;  (void)A;
+   xf86DrvMsg(0, X_INFO,
+       "V: A %d B %d C %d D %d E %d F %d  VT %d VDE %d VRS %d VBS %d VBE %d VRE %d\n",
+       A, B, C, D, E, F, VT, VDE, VRS, VBS, VBE, VRE);
 #endif
-
-      i++;
-   }
-
-   /* Add non-standard LCD modes for panel's detailed timings */
-
-   if(!includelcdmodes) return first;
-
-   if(pSiS->SiS_Pr->CP_Vendor) {
-      xf86DrvMsg(0, X_INFO, "Checking database for vendor %x, product %x\n",
-         pSiS->SiS_Pr->CP_Vendor, pSiS->SiS_Pr->CP_Product);
-   }
-
-   i = 0;
-   while((!done) && (SiS_PlasmaTable[i].vendor) && (pSiS->SiS_Pr->CP_Vendor)) {
-
-     if(SiS_PlasmaTable[i].vendor == pSiS->SiS_Pr->CP_Vendor) {
-
-        for(j=0; j<SiS_PlasmaTable[i].productnum; j++) {
-
-           if(SiS_PlasmaTable[i].product[j] == pSiS->SiS_Pr->CP_Product) {
-
-              xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
-                 "Identified %s panel, adding specific modes\n",
-                 SiS_PlasmaTable[i].plasmaname);
-
-              for(k=0; k<SiS_PlasmaTable[i].modenum; k++) {
-
-                 if(isfordvi) {
-                    if(!(SiS_PlasmaTable[i].plasmamodes[k] & 0x80)) continue;
-                 } else {
-                    if(!(SiS_PlasmaTable[i].plasmamodes[k] & 0x40)) continue;
-                 }
-
-                 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(12))) {
-                    xfree(new);
-                    return first;
-                  }
-                  if(!first) first = new;
-                  if(current) {
-                     current->next = new;
-                    new->prev = current;
-                  }
-
-                  current = new;
-
-                 pSiS->AddedPlasmaModes = TRUE;
-
-                 strcpy(current->name, SiS_PlasmaMode[l].name);
-                 /* sprintf(current->name, "%dx%d", SiS_PlasmaMode[l].HDisplay,
-                                                  SiS_PlasmaMode[l].VDisplay); */
-
-                  current->status = MODE_OK;
-
-                  current->type = M_T_BUILTIN;
-
-                 current->Clock = SiS_PlasmaMode[l].clock;
-                 current->SynthClock = current->Clock;
-
-                  current->HDisplay   = SiS_PlasmaMode[l].HDisplay;
-                  current->HSyncStart = current->HDisplay + SiS_PlasmaMode[l].HFrontPorch;
-                  current->HSyncEnd   = current->HSyncStart + SiS_PlasmaMode[l].HSyncWidth;
-                  current->HTotal     = SiS_PlasmaMode[l].HTotal;
-
-                 current->VDisplay   = SiS_PlasmaMode[l].VDisplay;
-                  current->VSyncStart = current->VDisplay + SiS_PlasmaMode[l].VFrontPorch;
-                  current->VSyncEnd   = current->VSyncStart + SiS_PlasmaMode[l].VSyncWidth;
-                  current->VTotal     = SiS_PlasmaMode[l].VTotal;
-
-                  current->CrtcHDisplay = current->HDisplay;
-                  current->CrtcHBlankStart = current->HSyncStart;
-                  current->CrtcHSyncStart = current->HSyncStart;
-                  current->CrtcHSyncEnd = current->HSyncEnd;
-                  current->CrtcHBlankEnd = current->HSyncEnd;
-                  current->CrtcHTotal = current->HTotal;
-
-                  current->CrtcVDisplay = current->VDisplay;
-                  current->CrtcVBlankStart = current->VSyncStart;
-                  current->CrtcVSyncStart = current->VSyncStart;
-                  current->CrtcVSyncEnd = current->VSyncEnd;
-                  current->CrtcVBlankEnd = current->VSyncEnd;
-                  current->CrtcVTotal = current->VTotal;
-
-                  if(SiS_PlasmaMode[l].SyncFlags & SIS_PL_HSYNCP)
-                     current->Flags |= V_PHSYNC;
-                  else
-                     current->Flags |= V_NHSYNC;
-
-                  if(SiS_PlasmaMode[l].SyncFlags & SIS_PL_VSYNCP)
-                     current->Flags |= V_PVSYNC;
-                  else
-                     current->Flags |= V_NVSYNC;
-
-                 if(current->HDisplay > pSiS->LCDwidth)
-                    pSiS->LCDwidth = pSiS->SiS_Pr->CP_MaxX = current->HDisplay;
-                 if(current->VDisplay > pSiS->LCDheight)
-                    pSiS->LCDheight = pSiS->SiS_Pr->CP_MaxY = current->VDisplay;
-
-                 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
-                       "\tAdding \"%s\" to list of built-in modes\n", current->name);
-
-               }
-              done = TRUE;
-              break;
-           }
-       }
-     }
-
-     i++;
-
-   }
-
-   if(pSiS->SiS_Pr->CP_HaveCustomData) {
-
-      for(i=0; i<7; i++) {
-
-         if(pSiS->SiS_Pr->CP_DataValid[i]) {
-
-            if(!(new = xalloc(sizeof(DisplayModeRec)))) return first;
-
-            memset(new, 0, sizeof(DisplayModeRec));
-            if(!(new->name = xalloc(10))) {
-               xfree(new);
-               return first;
-            }
-            if(!first) first = new;
-            if(current) {
-               current->next = new;
-              new->prev = current;
-            }
-
-            current = new;
-
-            sprintf(current->name, "%dx%d", pSiS->SiS_Pr->CP_HDisplay[i],
-                                            pSiS->SiS_Pr->CP_VDisplay[i]);
-
-            current->status = MODE_OK;
-
-            current->type = M_T_BUILTIN;
-
-            current->Clock = pSiS->SiS_Pr->CP_Clock[i];
-            current->SynthClock = current->Clock;
-
-            current->HDisplay   = pSiS->SiS_Pr->CP_HDisplay[i];
-            current->HSyncStart = pSiS->SiS_Pr->CP_HSyncStart[i];
-            current->HSyncEnd   = pSiS->SiS_Pr->CP_HSyncEnd[i];
-            current->HTotal     = pSiS->SiS_Pr->CP_HTotal[i];
-
-            current->VDisplay   = pSiS->SiS_Pr->CP_VDisplay[i];
-            current->VSyncStart = pSiS->SiS_Pr->CP_VSyncStart[i];
-            current->VSyncEnd   = pSiS->SiS_Pr->CP_VSyncEnd[i];
-            current->VTotal     = pSiS->SiS_Pr->CP_VTotal[i];
-
-            current->CrtcHDisplay = current->HDisplay;
-            current->CrtcHBlankStart = pSiS->SiS_Pr->CP_HBlankStart[i];
-            current->CrtcHSyncStart = current->HSyncStart;
-            current->CrtcHSyncEnd = current->HSyncEnd;
-            current->CrtcHBlankEnd = pSiS->SiS_Pr->CP_HBlankEnd[i];
-            current->CrtcHTotal = current->HTotal;
-
-            current->CrtcVDisplay = current->VDisplay;
-            current->CrtcVBlankStart = pSiS->SiS_Pr->CP_VBlankStart[i];
-            current->CrtcVSyncStart = current->VSyncStart;
-            current->CrtcVSyncEnd = current->VSyncEnd;
-            current->CrtcVBlankEnd = pSiS->SiS_Pr->CP_VBlankEnd[i];
-            current->CrtcVTotal = current->VTotal;
-
-           if(pSiS->SiS_Pr->CP_SyncValid[i]) {
-               if(pSiS->SiS_Pr->CP_HSync_P[i])
-                  current->Flags |= V_PHSYNC;
-               else
-                  current->Flags |= V_NHSYNC;
-
-               if(pSiS->SiS_Pr->CP_VSync_P[i])
-                  current->Flags |= V_PVSYNC;
-               else
-                  current->Flags |= V_NVSYNC;
-           } else {
-              /* No sync data? Use positive sync... */
-              current->Flags |= V_PHSYNC;
-              current->Flags |= V_PVSYNC;
-           }
-         }
-      }
-   }
-
-   return first;
-
-}
-
-/* Translate a mode number into the VESA pendant */
-int
-SiSTranslateToVESA(ScrnInfoPtr pScrn, int modenumber)
-{
-   SISPtr pSiS = SISPTR(pScrn);
-   int    i = 0;
-
-   /* Initialize our pointers */
-   if(pSiS->VGAEngine == SIS_300_VGA) {
-#ifdef SIS300
-       InitTo300Pointer(pSiS->SiS_Pr, &pSiS->sishw_ext);
-#else
-       return -1;
 #endif
-   } else if(pSiS->VGAEngine == SIS_315_VGA) {
-#ifdef SIS315H
-               InitTo310Pointer(pSiS->SiS_Pr, &pSiS->sishw_ext);
-#else
-       return -1;
+#ifdef SIS_LINUX_KERNEL
+   if(writeres) var->yres = yres = E;
+   var->upper_margin = D;
+   var->lower_margin = F;
+   var->vsync_len = C;
 #endif
-   } else return -1;
-
-   if(modenumber <= 0x13) return modenumber;
 
-#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++;
-      }
-   } else {
+   if((xres == 320) && ((yres == 200) || (yres == 240))) {
+       /* Terrible hack, but correct CRTC data for
+        * these modes only produces a black screen...
+        * (HRE is 0, leading into a too large C and
+        * a negative D. The CRT controller does not
+        * seem to like correcting HRE to 50)
+        */
+#ifdef SIS_XORG_XF86
+      current->HDisplay   = 320;
+      current->HSyncStart = 328;
+      current->HSyncEnd   = 376;
+      current->HTotal     = 400;
 #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
-   }
+#ifdef SIS_LINUX_KERNEL
+      var->left_margin = (400 - 376);
+      var->right_margin = (328 - 320);
+      var->hsync_len = (376 - 328);
 #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
-int
-sisfb_mode_rate_to_dclock(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
-                         unsigned char modeno, unsigned char rateindex)
-{
-    USHORT ModeNo = modeno;
-    USHORT ModeIdIndex = 0, ClockIndex = 0;
-    USHORT RefreshRateTableIndex = 0;
-    int    Clock;
-
-    if(HwInfo->jChipType < SIS_315H) {
-#ifdef SIS300
-       InitTo300Pointer(SiS_Pr, HwInfo);
-#else
-       return 65 * 1000;
-#endif
-    } else {
-#ifdef SIS315H
-       InitTo310Pointer(SiS_Pr, HwInfo);
-#else
-       return 65 * 1000;
-#endif
-    }
-
-    if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) {;
-       printk(KERN_ERR "Could not find mode %x\n", ModeNo);
-       return 65 * 1000;
-    }
-
-    RefreshRateTableIndex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
-    RefreshRateTableIndex += (rateindex - 1);
-    ClockIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
-    if(HwInfo->jChipType < SIS_315H) {
-       ClockIndex &= 0x3F;
-    }
-    Clock = SiS_Pr->SiS_VCLKData[ClockIndex].CLOCK * 1000;
-    
-    return(Clock);
 }
 
-BOOLEAN
-sisfb_gettotalfrommode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
-                      unsigned char modeno, int *htotal, int *vtotal, unsigned char rateindex)
-{
-    USHORT ModeNo = modeno;
-    USHORT ModeIdIndex = 0, CRT1Index = 0;
-    USHORT RefreshRateTableIndex = 0;
-    unsigned char  sr_data, cr_data, cr_data2;
-
-    if(HwInfo->jChipType < SIS_315H) {
-#ifdef SIS300
-       InitTo300Pointer(SiS_Pr, HwInfo);
-#else
-       return FALSE;
-#endif
-    } else {
-#ifdef SIS315H
-       InitTo310Pointer(SiS_Pr, HwInfo);
-#else
-       return FALSE;
-#endif
-    }
-
-    if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return FALSE;
-
-    RefreshRateTableIndex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
-    RefreshRateTableIndex += (rateindex - 1);
-    CRT1Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
-
-    sr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
-    cr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[0];
-    *htotal = (((cr_data & 0xff) | ((unsigned short) (sr_data & 0x03) << 8)) + 5) * 8;
 
-    sr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
-    cr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[6];
-    cr_data2 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
-    *vtotal = ((cr_data & 0xFF) |
-               ((unsigned short)(cr_data2 & 0x01) <<  8) |
-              ((unsigned short)(cr_data2 & 0x20) <<  4) |
-              ((unsigned short)(sr_data  & 0x01) << 10)) + 2;
 
-    if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & InterlaceMode)
-       *vtotal *= 2;
-
-    return TRUE;
-}
-
-int
-sisfb_mode_rate_to_ddata(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
-                        unsigned char modeno, unsigned char rateindex,
-                        struct fb_var_screeninfo *var)
-{
-    USHORT ModeNo = modeno;
-    USHORT ModeIdIndex = 0, index = 0;
-    USHORT RefreshRateTableIndex = 0;
-    unsigned short VRE, VBE, VRS, VBS, VDE, VT;
-    unsigned short HRE, HBE, HRS, HBS, HDE, HT;
-    unsigned char  sr_data, cr_data, cr_data2, cr_data3;
-    int            A, B, C, D, E, F, temp, j;
-   
-    if(HwInfo->jChipType < SIS_315H) {
-#ifdef SIS300
-       InitTo300Pointer(SiS_Pr, HwInfo);
-#else
-       return 0;
-#endif
-    } else {
-#ifdef SIS315H
-       InitTo310Pointer(SiS_Pr, HwInfo);
-#else
-       return 0;
-#endif
-    }
-
-    if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return 0;
-
-    RefreshRateTableIndex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
-    RefreshRateTableIndex += (rateindex - 1);
-    index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
-
-    sr_data = SiS_Pr->SiS_CRT1Table[index].CR[14];
-
-    cr_data = SiS_Pr->SiS_CRT1Table[index].CR[0];
-
-    /* Horizontal total */
-    HT = (cr_data & 0xff) |
-         ((unsigned short) (sr_data & 0x03) << 8);
-    A = HT + 5;
-
-    cr_data = SiS_Pr->SiS_CRT1Table[index].CR[1];
-       
-    /* Horizontal display enable end */
-    HDE = (cr_data & 0xff) |
-          ((unsigned short) (sr_data & 0x0C) << 6);
-    E = HDE + 1;
-
-    cr_data = SiS_Pr->SiS_CRT1Table[index].CR[4];
-       
-    /* Horizontal retrace (=sync) start */
-    HRS = (cr_data & 0xff) |
-          ((unsigned short) (sr_data & 0xC0) << 2);
-    F = HRS - E - 3;
-
-    cr_data = SiS_Pr->SiS_CRT1Table[index].CR[2];
-       
-    /* Horizontal blank start */
-    HBS = (cr_data & 0xff) |
-          ((unsigned short) (sr_data & 0x30) << 4);
-
-    sr_data = SiS_Pr->SiS_CRT1Table[index].CR[15];
-       
-    cr_data = SiS_Pr->SiS_CRT1Table[index].CR[3];
-
-    cr_data2 = SiS_Pr->SiS_CRT1Table[index].CR[5];
-       
-    /* Horizontal blank end */
-    HBE = (cr_data & 0x1f) |
-          ((unsigned short) (cr_data2 & 0x80) >> 2) |
-         ((unsigned short) (sr_data & 0x03) << 6);
-
-    /* Horizontal retrace (=sync) end */
-    HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3);
-
-    temp = HBE - ((E - 1) & 255);
-    B = (temp > 0) ? temp : (temp + 256);
-
-    temp = HRE - ((E + F + 3) & 63);
-    C = (temp > 0) ? temp : (temp + 64);
-
-    D = B - F - C;
-
-    if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes == 320) &&
-       ((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].YRes == 200) ||
-       (SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].YRes == 240))) {
-
-        /* Terrible hack, but the correct CRTC data for
-         * these modes only produces a black screen...
-         */
-       var->left_margin = (400 - 376);
-       var->right_margin = (328 - 320);
-       var->hsync_len = (376 - 328);
-
-    } else {
-
-       var->left_margin = D * 8;
-       var->right_margin = F * 8;
-       var->hsync_len = C * 8;
-
-    }
-
-    sr_data = SiS_Pr->SiS_CRT1Table[index].CR[13];
-
-    cr_data = SiS_Pr->SiS_CRT1Table[index].CR[6];
-
-    cr_data2 = SiS_Pr->SiS_CRT1Table[index].CR[7];
-
-    /* Vertical total */
-    VT = (cr_data & 0xFF) |
-         ((unsigned short) (cr_data2 & 0x01) << 8) |
-        ((unsigned short)(cr_data2 & 0x20) << 4) |
-        ((unsigned short) (sr_data & 0x01) << 10);
-    A = VT + 2;
-
-    cr_data = SiS_Pr->SiS_CRT1Table[index].CR[10];
-       
-    /* Vertical display enable end */
-    VDE = (cr_data & 0xff) |
-          ((unsigned short) (cr_data2 & 0x02) << 7) |
-         ((unsigned short) (cr_data2 & 0x40) << 3) |
-         ((unsigned short) (sr_data & 0x02) << 9);
-    E = VDE + 1;
-
-    cr_data = SiS_Pr->SiS_CRT1Table[index].CR[8];
-
-    /* Vertical retrace (=sync) start */
-    VRS = (cr_data & 0xff) |
-          ((unsigned short) (cr_data2 & 0x04) << 6) |
-         ((unsigned short) (cr_data2 & 0x80) << 2) |
-         ((unsigned short) (sr_data & 0x08) << 7);
-    F = VRS + 1 - E;
-
-    cr_data =  SiS_Pr->SiS_CRT1Table[index].CR[11];
-
-    cr_data3 = (SiS_Pr->SiS_CRT1Table[index].CR[16] & 0x01) << 5;
-
-    /* Vertical blank start */
-    VBS = (cr_data & 0xff) |
-          ((unsigned short) (cr_data2 & 0x08) << 5) |
-         ((unsigned short) (cr_data3 & 0x20) << 4) |
-         ((unsigned short) (sr_data & 0x04) << 8);
-
-    cr_data =  SiS_Pr->SiS_CRT1Table[index].CR[12];
-
-    /* Vertical blank end */
-    VBE = (cr_data & 0xff) |
-          ((unsigned short) (sr_data & 0x10) << 4);
-    temp = VBE - ((E - 1) & 511);
-    B = (temp > 0) ? temp : (temp + 512);
-
-    cr_data = SiS_Pr->SiS_CRT1Table[index].CR[9];
-
-    /* Vertical retrace (=sync) end */
-    VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1);
-    temp = VRE - ((E + F - 1) & 31);
-    C = (temp > 0) ? temp : (temp + 32);
-
-    D = B - F - C;
-      
-    var->upper_margin = D;
-    var->lower_margin = F;
-    var->vsync_len = C;
-
-    if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x8000)
-       var->sync &= ~FB_SYNC_VERT_HIGH_ACT;
-    else
-       var->sync |= FB_SYNC_VERT_HIGH_ACT;
-
-    if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x4000)       
-       var->sync &= ~FB_SYNC_HOR_HIGH_ACT;
-    else
-       var->sync |= FB_SYNC_HOR_HIGH_ACT;
-               
-    var->vmode = FB_VMODE_NONINTERLACED;
-    if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x0080)
-       var->vmode = FB_VMODE_INTERLACED;
-    else {
-       j = 0;
-       while(SiS_Pr->SiS_EModeIDTable[j].Ext_ModeID != 0xff) {
-          if(SiS_Pr->SiS_EModeIDTable[j].Ext_ModeID ==
-                         SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].ModeID) {
-              if(SiS_Pr->SiS_EModeIDTable[j].Ext_ModeFlag & DoubleScanMode) {
-                 var->vmode = FB_VMODE_DOUBLE;
-              }
-             break;
-          }
-         j++;
-       }
-    }       
-
-    if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
-#if 0  /* Do this? */
-       var->upper_margin <<= 1;
-       var->lower_margin <<= 1;
-       var->vsync_len <<= 1;
-#endif
-    } else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
-       var->upper_margin >>= 1;
-       var->lower_margin >>= 1;
-       var->vsync_len >>= 1;
-    }
-
-    return 1;       
-}                        
-
-#endif
 
index 7e36b7a..634c0a9 100644 (file)
@@ -3,7 +3,7 @@
 /*
  * Data and prototypes for init.c
  *
- * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
  *
  * If distributed as part of the Linux kernel, the following license terms
  * apply:
  *
  */
 
-#ifndef _INIT_
-#define _INIT_
+#ifndef _INIT_H_
+#define _INIT_H_
 
 #include "osdef.h"
 #include "initdef.h"
 
-#ifdef LINUX_XF86
+#ifdef SIS_XORG_XF86
 #include "sis.h"
+#define SIS_NEED_inSISREG
+#define SIS_NEED_inSISREGW
+#define SIS_NEED_inSISREGL
+#define SIS_NEED_outSISREG
+#define SIS_NEED_outSISREGW
+#define SIS_NEED_outSISREGL
 #include "sis_regs.h"
 #endif
 
-#ifdef LINUX_KERNEL
+#ifdef SIS_LINUX_KERNEL
 #include "vgatypes.h"
 #include "vstruct.h"
 #ifdef SIS_CP
 #include <asm/io.h>
 #include <linux/fb.h>
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+#include <video/fbcon.h>
+#endif
+#include "sis.h"
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 #include <linux/sisfb.h>
 #else
 #include <video/sisfb.h>
 #endif
 
 /* Mode numbers */
-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};
-
-static const USHORT SiS_DRAMType[17][5]={
+static const unsigned short ModeIndex_320x200[]      = {0x59, 0x41, 0x00, 0x4f};
+static const unsigned short ModeIndex_320x240[]      = {0x50, 0x56, 0x00, 0x53};
+static const unsigned short ModeIndex_320x240_FSTN[] = {0x5a, 0x5b, 0x00, 0x00};  /* FSTN */
+static const unsigned short ModeIndex_400x300[]      = {0x51, 0x57, 0x00, 0x54};
+static const unsigned short ModeIndex_512x384[]      = {0x52, 0x58, 0x00, 0x5c};
+static const unsigned short ModeIndex_640x400[]      = {0x2f, 0x5d, 0x00, 0x5e};
+static const unsigned short ModeIndex_640x480[]      = {0x2e, 0x44, 0x00, 0x62};
+static const unsigned short ModeIndex_720x480[]      = {0x31, 0x33, 0x00, 0x35};
+static const unsigned short ModeIndex_720x576[]      = {0x32, 0x34, 0x00, 0x36};
+static const unsigned short ModeIndex_768x576[]      = {0x5f, 0x60, 0x00, 0x61};
+static const unsigned short ModeIndex_800x480[]      = {0x70, 0x7a, 0x00, 0x76};
+static const unsigned short ModeIndex_800x600[]      = {0x30, 0x47, 0x00, 0x63};
+static const unsigned short ModeIndex_848x480[]      = {0x39, 0x3b, 0x00, 0x3e};
+static const unsigned short ModeIndex_856x480[]      = {0x3f, 0x42, 0x00, 0x45};
+static const unsigned short ModeIndex_960x540[]      = {0x1d, 0x1e, 0x00, 0x1f};  /* 315 series only */
+static const unsigned short ModeIndex_960x600[]      = {0x20, 0x21, 0x00, 0x22};  /* 315 series only */
+static const unsigned short ModeIndex_1024x768[]     = {0x38, 0x4a, 0x00, 0x64};
+static const unsigned short ModeIndex_1024x576[]     = {0x71, 0x74, 0x00, 0x77};
+static const unsigned short ModeIndex_1024x600[]     = {0x20, 0x21, 0x00, 0x22};  /* 300 series only */
+static const unsigned short ModeIndex_1280x1024[]    = {0x3a, 0x4d, 0x00, 0x65};
+static const unsigned short ModeIndex_1280x960[]     = {0x7c, 0x7d, 0x00, 0x7e};
+static const unsigned short ModeIndex_1152x768[]     = {0x23, 0x24, 0x00, 0x25};  /* 300 series only */
+static const unsigned short ModeIndex_1152x864[]     = {0x29, 0x2a, 0x00, 0x2b};
+static const unsigned short ModeIndex_300_1280x768[] = {0x55, 0x5a, 0x00, 0x5b};
+static const unsigned short ModeIndex_310_1280x768[] = {0x23, 0x24, 0x00, 0x25};
+static const unsigned short ModeIndex_1280x720[]     = {0x79, 0x75, 0x00, 0x78};
+static const unsigned short ModeIndex_1280x800[]     = {0x14, 0x15, 0x00, 0x16};
+static const unsigned short ModeIndex_1280x854[]     = {0x1a, 0x1b, 0x00, 0x1c};
+static const unsigned short ModeIndex_1360x768[]     = {0x48, 0x4b, 0x00, 0x4e};
+static const unsigned short ModeIndex_300_1360x1024[]= {0x67, 0x6f, 0x00, 0x72};  /* 300 series, BARCO only */
+static const unsigned short ModeIndex_1400x1050[]    = {0x26, 0x27, 0x00, 0x28};  /* 315 series only */
+static const unsigned short ModeIndex_1680x1050[]    = {0x17, 0x18, 0x00, 0x19};  /* 315 series only */
+static const unsigned short ModeIndex_1600x1200[]    = {0x3c, 0x3d, 0x00, 0x66};
+static const unsigned short ModeIndex_1920x1080[]    = {0x2c, 0x2d, 0x00, 0x73};  /* 315 series only */
+static const unsigned short ModeIndex_1920x1440[]    = {0x68, 0x69, 0x00, 0x6b};
+static const unsigned short ModeIndex_300_2048x1536[]= {0x6c, 0x6d, 0x00, 0x00};
+static const unsigned short ModeIndex_310_2048x1536[]= {0x6c, 0x6d, 0x00, 0x6e};
+
+static const unsigned short SiS_DRAMType[17][5]={
        {0x0C,0x0A,0x02,0x40,0x39},
        {0x0D,0x0A,0x01,0x40,0x48},
        {0x0C,0x09,0x02,0x20,0x35},
@@ -137,7 +148,7 @@ static const USHORT SiS_DRAMType[17][5]={
        {0x09,0x08,0x01,0x01,0x00}
 };
 
-static const USHORT SiS_SDRDRAM_TYPE[13][5] =
+static const unsigned short SiS_SDRDRAM_TYPE[13][5] =
 {
        { 2,12, 9,64,0x35},
        { 1,13, 9,64,0x44},
@@ -154,7 +165,7 @@ static const USHORT SiS_SDRDRAM_TYPE[13][5] =
        { 1, 9, 8, 2,0x00}
 };
 
-static const USHORT SiS_DDRDRAM_TYPE[4][5] =
+static const unsigned short SiS_DDRDRAM_TYPE[4][5] =
 {
        { 2,12, 9,64,0x35},
        { 2,12, 8,32,0x31},
@@ -162,7 +173,7 @@ static const USHORT SiS_DDRDRAM_TYPE[4][5] =
        { 2, 9, 8, 4,0x01}
 };
 
-static const USHORT SiS_MDA_DAC[] =
+static const unsigned char SiS_MDA_DAC[] =
 {
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
         0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
@@ -174,7 +185,7 @@ static const USHORT SiS_MDA_DAC[] =
         0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F
 };
 
-static const USHORT SiS_CGA_DAC[] =
+static const unsigned char SiS_CGA_DAC[] =
 {
         0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
         0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
@@ -186,7 +197,7 @@ static const USHORT SiS_CGA_DAC[] =
         0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F
 };
 
-static const USHORT SiS_EGA_DAC[] =
+static const unsigned char SiS_EGA_DAC[] =
 {
         0x00,0x10,0x04,0x14,0x01,0x11,0x05,0x15,
         0x20,0x30,0x24,0x34,0x21,0x31,0x25,0x35,
@@ -198,7 +209,7 @@ static const USHORT SiS_EGA_DAC[] =
         0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F
 };
 
-static const USHORT SiS_VGA_DAC[] =
+static const unsigned char SiS_VGA_DAC[] =
 {
        0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
        0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F,
@@ -212,7 +223,31 @@ static const USHORT SiS_VGA_DAC[] =
        0x0B,0x0C,0x0D,0x0F,0x10
 };
 
-static const SiS_StResInfoStruct SiS_StResInfo[]=
+static const struct SiS_St SiS_SModeIDTable[] =
+{
+       {0x01,0x9208,0x01,0x00,0x00,0x00,0x01,0x00,0x40},
+       {0x01,0x1210,0x14,0x01,0x01,0x00,0x01,0x00,0x40},
+       {0x01,0x1010,0x17,0x02,0x02,0x00,0x01,0x01,0x40},
+       {0x03,0x8208,0x03,0x00,0x00,0x00,0x01,0x02,0x40},
+       {0x03,0x0210,0x16,0x01,0x01,0x00,0x01,0x02,0x40},
+       {0x03,0x0010,0x18,0x02,0x02,0x00,0x01,0x03,0x40},
+       {0x05,0x9209,0x05,0x00,0x00,0x00,0x00,0x04,0x40},
+       {0x06,0x8209,0x06,0x00,0x00,0x00,0x00,0x05,0x40},
+       {0x07,0x0000,0x07,0x03,0x03,0x00,0x01,0x03,0x40},
+       {0x07,0x0000,0x19,0x02,0x02,0x00,0x01,0x03,0x40},
+       {0x0d,0x920a,0x0d,0x00,0x00,0x00,0x00,0x04,0x40},
+       {0x0e,0x820a,0x0e,0x00,0x00,0x00,0x00,0x05,0x40},
+       {0x0f,0x0202,0x11,0x01,0x01,0x00,0x00,0x05,0x40},
+       {0x10,0x0212,0x12,0x01,0x01,0x00,0x00,0x05,0x40},
+       {0x11,0x0212,0x1a,0x04,0x04,0x00,0x00,0x05,0x40},
+       {0x12,0x0212,0x1b,0x04,0x04,0x00,0x00,0x05,0x40},
+       {0x13,0x021b,0x1c,0x00,0x00,0x00,0x00,0x04,0x40},
+       {0x12,0x0010,0x18,0x02,0x02,0x00,0x00,0x05,0x40},
+       {0x12,0x0210,0x18,0x01,0x01,0x00,0x00,0x05,0x40},
+       {0xff,0x0000,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
+};
+
+static const struct SiS_StResInfo_S SiS_StResInfo[]=
 {
        { 640,400},
        { 640,350},
@@ -221,7 +256,7 @@ static const SiS_StResInfoStruct SiS_StResInfo[]=
        { 640,480}
 };
 
-static const SiS_ModeResInfoStruct SiS_ModeResInfo[] =
+static const struct SiS_ModeResInfo_S SiS_ModeResInfo[] =
 {
        {  320, 200, 8, 8},   /* 0x00 */
        {  320, 240, 8, 8},   /* 0x01 */
@@ -256,11 +291,12 @@ static const SiS_ModeResInfoStruct SiS_ModeResInfo[] =
        { 1280, 800, 8,16},   /* 0x1e */
        { 1920,1080, 8,16},   /* 0x1f */
        {  960, 540, 8,16},   /* 0x20 */
-       {  960, 600, 8,16}    /* 0x21 */
+       {  960, 600, 8,16},   /* 0x21 */
+       { 1280, 854, 8,16}    /* 0x22 */
 };
 
 #if defined(SIS300) || defined(SIS315H)
-static const SiS_StandTableStruct SiS_StandTable[]=
+static const struct SiS_StandTable_S SiS_StandTable[]=
 {
 /* 0x00: MD_0_200 */
  {
@@ -704,11 +740,11 @@ static const SiS_StandTableStruct SiS_StandTable[]=
 /* SIS VIDEO BRIDGE ----------------------------------------- */
 /**************************************************************/
 
-static const UCHAR SiS_SoftSetting  = 0x30;   /* RAM setting */
+static const unsigned char SiS_SoftSetting  = 0x30;   /* RAM setting */
 
-static const UCHAR SiS_OutputSelect = 0x40;
+static const unsigned char SiS_OutputSelect = 0x40;
 
-static const UCHAR SiS_NTSCTiming[] = {
+static const unsigned char SiS_NTSCTiming[] = {
        0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c,
        0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a,
        0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x1b,
@@ -719,7 +755,7 @@ static const UCHAR SiS_NTSCTiming[] = {
        0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00
 };
 
-static const UCHAR SiS_PALTiming[] = {
+static const unsigned char SiS_PALTiming[] = {
        0x19,0x52,0x35,0x6e,0x04,0x38,0x3d,0x70,
        0x94,0x49,0x01,0x12,0x06,0x3e,0x35,0x6d,
        0x06,0x14,0x3e,0x35,0x6d,0x00,0x45,0x2b,
@@ -730,8 +766,8 @@ static const UCHAR SiS_PALTiming[] = {
        0x00,0x40,0x3e,0x00,0xe1,0x02,0x28,0x00
 };
 
-static const UCHAR SiS_HiTVExtTiming[] = {
-        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
+static const unsigned char SiS_HiTVExtTiming[] = {
+       0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
        0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
        0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
        0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13,
@@ -741,8 +777,8 @@ static const UCHAR SiS_HiTVExtTiming[] = {
        0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00
 };
 
-static const UCHAR SiS_HiTVSt1Timing[] = {
-        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
+static const unsigned char SiS_HiTVSt1Timing[] = {
+       0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
        0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
        0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
        0x65,0x90,0x7b,0xa8,0x03,0xf0,0x87,0x03,
@@ -752,8 +788,8 @@ static const UCHAR SiS_HiTVSt1Timing[] = {
        0xaf,0x5d,0x0e,0x00,0xfc,0xff,0x2d,0x00
 };
 
-static const UCHAR SiS_HiTVSt2Timing[] = {
-        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
+static const unsigned char SiS_HiTVSt2Timing[] = {
+       0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
        0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
        0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
        0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13,
@@ -764,8 +800,8 @@ static const UCHAR SiS_HiTVSt2Timing[] = {
 };
 
 #if 0
-static const UCHAR SiS_HiTVTextTiming[] = {
-        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
+static const unsigned char SiS_HiTVTextTiming[] = {
+       0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
        0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
        0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
        0x65,0x90,0xe7,0xbc,0x03,0x0c,0x97,0x03,
@@ -776,8 +812,8 @@ static const UCHAR SiS_HiTVTextTiming[] = {
 };
 #endif
 
-static const UCHAR SiS_HiTVGroup3Data[] = {
-        0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x5f,
+static const unsigned char SiS_HiTVGroup3Data[] = {
+       0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x5f,
        0x05,0x21,0xb2,0xb2,0x55,0x77,0x2a,0xa6,
        0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
        0x8c,0x6e,0x60,0x2e,0x58,0x48,0x72,0x44,
@@ -787,8 +823,8 @@ static const UCHAR SiS_HiTVGroup3Data[] = {
        0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
 };
 
-static const UCHAR SiS_HiTVGroup3Simu[] = {
-        0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x95,
+static const unsigned char SiS_HiTVGroup3Simu[] = {
+       0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x95,
        0xdb,0x20,0xb8,0xb8,0x55,0x47,0x2a,0xa6,
        0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
        0x8c,0x6e,0x60,0x15,0x26,0xd3,0xe4,0x11,
@@ -799,8 +835,8 @@ static const UCHAR SiS_HiTVGroup3Simu[] = {
 };
 
 #if 0
-static const UCHAR SiS_HiTVGroup3Text[] = {
-        0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0xa7,
+static const unsigned char SiS_HiTVGroup3Text[] = {
+       0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0xa7,
        0xf5,0x20,0xce,0xce,0x55,0x47,0x2a,0xa6,
        0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
        0x8c,0x6e,0x60,0x18,0x2c,0x0c,0x20,0x22,
@@ -811,136 +847,141 @@ static const UCHAR SiS_HiTVGroup3Text[] = {
 };
 #endif
 
-static const UCHAR SiS_NTSCPhase[]    = {0x21,0xed,0xba,0x08};
-static const UCHAR SiS_PALPhase[]     = {0x2a,0x05,0xe3,0x00};
-static const UCHAR SiS_PALMPhase[]    = {0x21,0xE4,0x2E,0x9B};
-static const UCHAR SiS_PALNPhase[]    = {0x21,0xF4,0x3E,0xBA};
-static const UCHAR SiS_NTSCPhase2[]   = {0x21,0xF0,0x7B,0xD6};
-static const UCHAR SiS_PALPhase2[]    = {0x2a,0x09,0x86,0xe9};
-static const UCHAR SiS_PALMPhase2[]   = {0x21,0xE6,0xEF,0xA4};
-static const UCHAR SiS_PALNPhase2[]   = {0x21,0xF6,0x94,0x46};
-static const UCHAR SiS_SpecialPhase[] = {0x1e,0x8c,0x5c,0x7a};
-static const UCHAR SiS_SpecialPhaseM[]= {0x1e,0x83,0x0a,0xe0};
-static const UCHAR SiS_SpecialPhaseJ[]= {0x25,0xd4,0xfd,0x5e};
-
-static const SiS_TVDataStruct  SiS_StPALData[] =
+static const struct SiS_TVData SiS_StPALData[] =
 {
- {    1,   1, 864, 525,1270, 400, 100,   0, 760,0xf4,0xff,0x1c,0x22},
- {    1,   1, 864, 525,1270, 350, 100,   0, 760,0xf4,0xff,0x1c,0x22},
- {    1,   1, 864, 525,1270, 400,   0,   0, 720,0xf1,0x04,0x1f,0x18},
- {    1,   1, 864, 525,1270, 350,   0,   0, 720,0xf4,0x0b,0x1c,0x0a},
- {    1,   1, 864, 525,1270, 480,  50,   0, 760,0xf4,0xff,0x1c,0x22},
- {    1,   1, 864, 525,1270, 600,  50,   0,   0,0xf4,0xff,0x1c,0x22}
+ {    1,   1, 864, 525,1270, 400, 100, 0, 760,    0,0xf4,0xff,0x1c,0x22},
+ {    1,   1, 864, 525,1270, 350, 100, 0, 760,    0,0xf4,0xff,0x1c,0x22},
+ {    1,   1, 864, 525,1270, 400,   0, 0, 720,    0,0xf1,0x04,0x1f,0x18},
+ {    1,   1, 864, 525,1270, 350,   0, 0, 720,    0,0xf4,0x0b,0x1c,0x0a},
+ {    1,   1, 864, 525,1270, 480,  50, 0, 760,    0,0xf4,0xff,0x1c,0x22},
+ {    1,   1, 864, 525,1270, 600,  50, 0,   0,0x300,0xf4,0xff,0x1c,0x22}
 };
 
-static const SiS_TVDataStruct  SiS_ExtPALData[] =
+static const struct SiS_TVData SiS_ExtPALData[] =
 {
- {   27,  10, 848, 448,1270, 530,  50,   0,  50,0xf4,0xff,0x1c,0x22},  /* 640x400, 320x200 */
- {  108,  35, 848, 398,1270, 530,  50,   0,  50,0xf4,0xff,0x1c,0x22},
- {   12,   5, 954, 448,1270, 530,  50,   0,  50,0xf1,0x04,0x1f,0x18},
- {    9,   4, 960, 463,1644, 438,  50,   0,  50,0xf4,0x0b,0x1c,0x0a},
- {    9,   4, 848, 528,1270, 530,   0,   0,  50,0xf5,0xfb,0x1b,0x2a},  /* 640x480, 320x240 */
-/*{  36,  25,1060, 648,1316, 530, 438,   0, 438,0xeb,0x05,0x25,0x16},*//* 800x600, 400x300 */
- {   36,  25,1060, 648,1270, 530, 438,   0, 438,0xeb,0x05,0x25,0x16},  /* 800x600, 400x300 - better */
- {    3,   2,1080, 619,1270, 540, 438,   0, 438,0xf3,0x00,0x1d,0x20},  /* 720x576 */
- {    1,   1,1170, 821,1270, 520, 686,   0, 686,0xF3,0x00,0x1D,0x20},  /* 1024x768 */
- {    1,   1,1170, 821,1270, 520, 686,   0, 686,0xF3,0x00,0x1D,0x20},  /* 1024x768 (for NTSC equ) */
- {    9,   4, 848, 528,1270, 530,   0,   0,  50,0xf5,0xfb,0x1b,0x2a}   /* 720x480 test */
+ {   27,  10, 848, 448,1270, 530,  50, 0,  50,    0,0xf4,0xff,0x1c,0x22},  /* 640x400, 320x200 */
+ {  108,  35, 848, 398,1270, 530,  50, 0,  50,    0,0xf4,0xff,0x1c,0x22},
+ {   12,   5, 954, 448,1270, 530,  50, 0,  50,    0,0xf1,0x04,0x1f,0x18},
+ {    9,   4, 960, 463,1644, 438,  50, 0,  50,    0,0xf4,0x0b,0x1c,0x0a},
+ {    9,   4, 848, 528,1270, 530,   0, 0,  50,    0,0xf5,0xfb,0x1b,0x2a},  /* 640x480, 320x240 */
+ {   36,  25,1060, 648,1270, 530, 438, 0, 438,    0,0xeb,0x05,0x25,0x16},  /* 800x600, 400x300 */
+ {    3,   2,1080, 619,1270, 540, 438, 0, 438,    0,0xf3,0x00,0x1d,0x20},  /* 720x576 */
+ {    1,   1,1170, 821,1270, 520, 686, 0, 686,    0,0xF3,0x00,0x1D,0x20},  /* 1024x768 */
+ {    1,   1,1170, 821,1270, 520, 686, 0, 686,    0,0xF3,0x00,0x1D,0x20},  /* 1024x768 (for NTSC equ) */
+ {    9,   4, 848, 528,1270, 530,   0, 0,  50,    0,0xf5,0xfb,0x1b,0x2a}   /* 720x480 */
 };
 
-static const SiS_TVDataStruct  SiS_StNTSCData[] =
+static const struct SiS_TVData SiS_StNTSCData[] =
 {
- {    1,   1, 858, 525,1270, 400,  50,   0, 760,0xf1,0x04,0x1f,0x18},
- {    1,   1, 858, 525,1270, 350,  50,   0, 640,0xf1,0x04,0x1f,0x18},
- {    1,   1, 858, 525,1270, 400,   0,   0, 720,0xf1,0x04,0x1f,0x18},
- {    1,   1, 858, 525,1270, 350,   0,   0, 720,0xf4,0x0b,0x1c,0x0a},
- {    1,   1, 858, 525,1270, 480,   0,   0, 760,0xf1,0x04,0x1f,0x18}
+ {    1,   1, 858, 525,1270, 400,  50, 0, 760,    0,0xf1,0x04,0x1f,0x18},
+ {    1,   1, 858, 525,1270, 350,  50, 0, 640,    0,0xf1,0x04,0x1f,0x18},
+ {    1,   1, 858, 525,1270, 400,   0, 0, 720,    0,0xf1,0x04,0x1f,0x18},
+ {    1,   1, 858, 525,1270, 350,   0, 0, 720,    0,0xf4,0x0b,0x1c,0x0a},
+ {    1,   1, 858, 525,1270, 480,   0, 0, 760,    0,0xf1,0x04,0x1f,0x18}
 };
 
-static const SiS_TVDataStruct  SiS_ExtNTSCData[] =
+static const struct SiS_TVData SiS_ExtNTSCData[] =
 {
- {  143,  65, 858, 443,1270, 440, 171,   0, 171,0xf1,0x04,0x1f,0x18},    /* 640x400, 320x200 */
- {   88,  35, 858, 393,1270, 440, 171,   0, 171,0xf1,0x04,0x1f,0x18},
- {  143,  70, 924, 443,1270, 440,  92,   0,  92,0xf1,0x04,0x1f,0x18},
- {  143,  70, 924, 393,1270, 440,  92,   0,  92,0xf4,0x0b,0x1c,0x0a},
- {  143,  76, 836, 523,1270, 440, 224,   0,   0,0xf1,0x05,0x1f,0x16},    /* 640x480, 320x240 */
- {  143, 120,1056, 643,1270, 440,   0, 128,   0,0xf4,0x10,0x1c,0x00},    /* 800x600, 400x300  */
-/*{   2,   1, 858, 503,1270, 480,   0, 128,   0,0xee,0x0c,0x22,0x08},*/  /* 720x480  (old, from 650) */
- {  143,  76, 836, 523,1270, 440,   0, 128,   0,0xee,0x0c,0x22,0x08},    /* 720x480 - BETTER (from 300 series) */
-/*{  65,  64,1056, 791,1270, 480, 638,   0,   0,0xEE,0x0C,0x22,0x08} */  /* 1024x768 (525i) */
- {    1,   1,1100, 811,1412, 440,   0, 128,   0,0xee,0x0c,0x22,0x08},    /* 1024x768 (525i) CORRECTED */
- {   65,  64,1056, 791,1270, 480, 455,   0,   0,0x00,0x00,0x00,0x00}     /* 1024x768 (525p) */
+ {  143,  65, 858, 443,1270, 440, 171, 0, 171,    0,0xf1,0x04,0x1f,0x18},    /* 640x400, 320x200 */
+ {   88,  35, 858, 393,1270, 440, 171, 0, 171,    0,0xf1,0x04,0x1f,0x18},
+ {  143,  70, 924, 443,1270, 440,  92, 0,  92,    0,0xf1,0x04,0x1f,0x18},
+ {  143,  70, 924, 393,1270, 440,  92, 0,  92,    0,0xf4,0x0b,0x1c,0x0a},
+ {  143,  76, 836, 523,1270, 440, 224, 0,   0,    0,0xf1,0x05,0x1f,0x16},    /* 640x480, 320x240 */
+ {  143, 120,1056, 643,1270, 440,   0, 1,   0,    0,0xf4,0x10,0x1c,0x00},    /* 800x600, 400x300  */
+ {  143,  76, 836, 523,1270, 440,   0, 1,   0,    0,0xee,0x0c,0x22,0x08},    /* 720x480 - BETTER (from 300 series) */
+ {    1,   1,1100, 811,1412, 440,   0, 1,   0,    0,0xee,0x0c,0x22,0x08},    /* 1024x768 (525i) CORRECTED */
+#if 0  /* flimmert und ist unten abgeschnitten (NTSCHT, NTSC clock) */
+ {   65,  64,1056, 791,1270, 480, 455, 0,   0,    0,0x00,0x00,0x00,0x00}     /* 1024x768 (525p) */
+#endif
+#if 0
+ {    1,   1,1100, 811,1412, 440,   0, 1,   0,    0,0x00,0x00,0x00,0x00}     /* 1024x768 (525p) */
+#endif
+#if 0
+ {    1,   1,1120, 821,1516, 420,   0, 1,   0,    0,0x00,0x00,0x00,0x00}     /* 1024x768 (525p) */
+#endif
+#if 0
+ {    1,   1, 938, 821,1516, 420,   0, 1,   0,    0,0x00,0x00,0x00,0x00}     /* 1024x768 (525p) */
+#endif
+#if 0 /* zoom hin, unten abgeschnitten (NTSC2HT, NTSC1024 clock) */
+ {    1,   1,1072, 791,1270, 480, 455, 0,   0,    0,0x00,0x00,0x00,0x00}     /* 1024x768 (525p) */
+#endif
+#if 1 /* zu weit links (squeezed) (NTSC2HT, NTSC1024 clock) */
+ {    1,   1,1100, 846,1270, 440, 455, 0,   0,    0,0x00,0x00,0x00,0x00}     /* 1024x768 (525p) */
+#endif
+#if 0 /* zu weit links, rechts abgeschnitten (NTSC2HT, NTSC1024 clock) */
+ {    1,   1,1100, 846,1412, 440, 455, 0,   0,    0,0x00,0x00,0x00,0x00}     /* 1024x768 (525p) */
+#endif
 };
 
-static const SiS_TVDataStruct  SiS_StHiTVData[] =  /* Slave + TVSimu */
+static const struct SiS_TVData SiS_StHiTVData[] =  /* Slave + TVSimu */
 {
- {    1,   1, 0x37c,0x233,0x2b2,0x320,    0,  0, 0, 0x00,0x00,0x00,0x00},
- {    1,   1, 0x37c,0x233,0x2b2,0x2bc,    0,  0, 0, 0x00,0x00,0x00,0x00},
- {    1,   1, 0x37c,0x233,0x2b2,0x320,    0,  0, 0, 0x00,0x00,0x00,0x00},
- {    1,   1, 0x37c,0x233,0x2b2,0x2bc,    0,  0, 0, 0x00,0x00,0x00,0x00},
- {    1,   1, 0x37c,0x233,0x2b2,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
- {    8,   5, 0x41a,0x2ab,0x670,0x3c0,0x150,128, 0, 0x00,0x00,0x00,0x00}
+ {    1,   1, 0x37c,0x233,0x2b2,0x320,    0, 0, 0, 0, 0, 0, 0, 0},
+ {    1,   1, 0x37c,0x233,0x2b2,0x2bc,    0, 0, 0, 0, 0, 0, 0, 0},
+ {    1,   1, 0x37c,0x233,0x2b2,0x320,    0, 0, 0, 0, 0, 0, 0, 0},
+ {    1,   1, 0x37c,0x233,0x2b2,0x2bc,    0, 0, 0, 0, 0, 0, 0, 0},
+ {    1,   1, 0x37c,0x233,0x2b2,0x3c0,    0, 0, 0, 0, 0, 0, 0, 0},
+ {    8,   5, 0x41a,0x2ab,0x670,0x3c0,0x150, 1, 0, 0, 0, 0, 0, 0}
 };
 
-static const SiS_TVDataStruct  SiS_St2HiTVData[] = /* Slave */
+static const struct SiS_TVData SiS_St2HiTVData[] = /* Slave */
 {
- {    3,   1, 0x348,0x1e3,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
- {    1,   1, 0x37c,0x233,0x2b2,0x2bc,           0,  0, 0, 0x00,0x00,0x00,0x00},
- {    3,   1, 0x348,0x1e3,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
- {    1,   1, 0x37c,0x233,0x2b2,0x2bc,    0,  0, 0, 0x00,0x00,0x00,0x00},
- {    5,   2, 0x348,0x233,0x670,0x3c0,0x08d,128, 0, 0x00,0x00,0x00,0x00},
- {    8,   5, 0x41a,0x2ab,0x670,0x3c0,0x17c,128, 0, 0x00,0x00,0x00,0x00}
+ {    3,   1, 0x348,0x1e3,0x670,0x3c0,0x032, 0, 0, 0, 0, 0, 0, 0},
+ {    1,   1, 0x37c,0x233,0x2b2,0x2bc,           0, 0, 0, 0, 0, 0, 0, 0},
+ {    3,   1, 0x348,0x1e3,0x670,0x3c0,0x032, 0, 0, 0, 0, 0, 0, 0},
+ {    1,   1, 0x37c,0x233,0x2b2,0x2bc,    0, 0, 0, 0, 0, 0, 0, 0},
+ {    5,   2, 0x348,0x233,0x670,0x3c0,0x08d, 1, 0, 0, 0, 0, 0, 0},
+ {    8,   5, 0x41a,0x2ab,0x670,0x3c0,0x17c, 1, 0, 0, 0, 0, 0, 0}
 };
 
-static const SiS_TVDataStruct  SiS_ExtHiTVData[] =
-{
- {    6,   1, 0x348,0x233,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
- {    3,   1, 0x3c0,0x233,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
- {    6,   1, 0x348,0x233,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
- {    3,   1, 0x3c0,0x233,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
- {    5,   1, 0x348,0x233,0x670,0x3c0,0x166,128, 0, 0x00,0x00,0x00,0x00},  /* 640x480   */
- {   16,   5, 0x41a,0x2ab,0x670,0x3c0,0x143,128, 0, 0x00,0x00,0x00,0x00},  /* 800x600   */
- {   25,  12, 0x4ec,0x353,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},  /* 1024x768  */
- {    5,   4, 0x627,0x464,0x670,0x3c0,0x128,  0, 0, 0x00,0x00,0x00,0x00},  /* 1280x1024 */
- {    4,   1, 0x41a,0x233,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  */
- {  137,  32, 0x3d4,0x233,0x663,0x3bf,0x143,  0, 0, 0x00,0x00,0x00,0x00}   /* 960x600  */
+static const struct SiS_TVData SiS_ExtHiTVData[] =
+{ /* all ok */
+ {    6,   1, 0x348,0x233,0x660,0x3c0,    0, 0, 0, 0, 0, 0, 0, 0},
+ {    3,   1, 0x3c0,0x233,0x660,0x3c0,    0, 0, 0, 0, 0, 0, 0, 0},
+ {    6,   1, 0x348,0x233,0x660,0x3c0,    0, 0, 0, 0, 0, 0, 0, 0},
+ {    3,   1, 0x3c0,0x233,0x660,0x3c0,    0, 0, 0, 0, 0, 0, 0, 0},
+ {    5,   1, 0x348,0x233,0x670,0x3c0,0x166, 1, 0, 0, 0, 0, 0, 0},  /* 640x480   */
+ {   16,   5, 0x41a,0x2ab,0x670,0x3c0,0x143, 1, 0, 0, 0, 0, 0, 0},  /* 800x600   */
+ {   25,  12, 0x4ec,0x353,0x670,0x3c0,0x032, 0, 0, 0, 0, 0, 0, 0},  /* 1024x768  */
+ {    5,   4, 0x627,0x464,0x670,0x3c0,0x128, 0, 0, 0, 0, 0, 0, 0},  /* 1280x1024 */
+ {    4,   1, 0x41a,0x233,0x60c,0x3c0,0x143, 1, 0, 0, 0, 0, 0, 0},  /* 800x480   */
+ {    5,   2, 0x578,0x293,0x670,0x3c0,0x032, 0, 0, 0, 0, 0, 0, 0},  /* 1024x576  */
+ {    8,   5, 0x6d6,0x323,0x670,0x3c0,0x128, 0, 0, 0, 0, 0, 0, 0},  /* 1280x720  */
+ {    8,   3, 0x4ec,0x353,0x670,0x3c0,0x032, 0, 0, 0, 0, 0, 0, 0},  /* 960x600  */
 };
 
-static const SiS_TVDataStruct  SiS_St525pData[] =
+static const struct SiS_TVData SiS_St525pData[] =
 {
- {    1,   1, 0x6b4,0x20d,0x4f6,0x190,   50,  0, 0x2f8, 0x00,0x00,0x00,0x00},
- {    1,   1, 0x6b4,0x20d,0x4f6,0x15e,   50,  0, 0x280, 0x00,0x00,0x00,0x00},
- {    1,   1, 0x6b4,0x20d,0x4f6,0x190,   50,  0, 0x2f8, 0x00,0x00,0x00,0x00},
- {    1,   1, 0x6b4,0x20d,0x4f6,0x15e,   50,  0, 0x280, 0x00,0x00,0x00,0x00},
- {    1,   1, 0x6b4,0x20d,0x4f6,0x1e0,    0,  0, 0x2f8, 0x00,0x00,0x00,0x00}
+ {    1,   1, 0x6b4,0x20d,0x4f6,0x190,   50, 0, 0x2f8, 0, 0, 0, 0, 0},
+ {    1,   1, 0x6b4,0x20d,0x4f6,0x15e,   50, 0, 0x280, 0, 0, 0, 0, 0},
+ {    1,   1, 0x6b4,0x20d,0x4f6,0x190,   50, 0, 0x2f8, 0, 0, 0, 0, 0},
+ {    1,   1, 0x6b4,0x20d,0x4f6,0x15e,   50, 0, 0x280, 0, 0, 0, 0, 0},
+ {    1,   1, 0x6b4,0x20d,0x4f6,0x1e0,    0, 0, 0x2f8, 0, 0, 0, 0, 0}
 };
 
-static const SiS_TVDataStruct  SiS_St750pData[] =
+static const struct SiS_TVData SiS_St750pData[] =
 {
- {    1,   1, 0x672,0x2ee,0x500,0x190,   50,  0, 0x2f8, 0x00,0x00,0x00,0x00},
- {    1,   1, 0x672,0x2ee,0x500,0x15e,   50,  0, 0x280, 0x00,0x00,0x00,0x00},
- {    1,   1, 0x672,0x2ee,0x500,0x190,    0,  0, 0x2d0, 0x00,0x00,0x00,0x00},
- {    1,   1, 0x672,0x2ee,0x500,0x15e,    0,  0, 0x2d0, 0x00,0x00,0x00,0x00},
- {    1,   1, 0x672,0x2ee,0x500,0x1e0,    0,  0, 0x2f8, 0x00,0x00,0x00,0x00}
+ {    1,   1, 0x672,0x2ee,0x500,0x190,   50, 0, 0x2f8, 0, 0, 0, 0, 0},
+ {    1,   1, 0x672,0x2ee,0x500,0x15e,   50, 0, 0x280, 0, 0, 0, 0, 0},
+ {    1,   1, 0x672,0x2ee,0x500,0x190,    0, 0, 0x2d0, 0, 0, 0, 0, 0},
+ {    1,   1, 0x672,0x2ee,0x500,0x15e,    0, 0, 0x2d0, 0, 0, 0, 0, 0},
+ {    1,   1, 0x672,0x2ee,0x500,0x1e0,    0, 0, 0x2f8, 0, 0, 0, 0, 0}
 };
 
-static const SiS_TVDataStruct  SiS_Ext750pData[] =
-{
- {  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  */
- {   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 */
+static const struct SiS_TVData SiS_Ext750pData[] =
+{ /* all ok */
+ {    3,  1,  935, 470, 1130, 680,  50, 0, 0, 0, 0, 0, 0, 0},  /* 320x200/640x400 */
+ {   24,  7,  935, 420, 1130, 680,  50, 0, 0, 0, 0, 0, 0, 0},
+ {    3,  1,  935, 470, 1130, 680,  50, 0, 0, 0, 0, 0, 0, 0},
+ {   24,  7,  935, 420, 1130, 680,  50, 0, 0, 0, 0, 0, 0, 0},
+ {    2,  1, 1100, 590, 1130, 640,  50, 0, 0, 0, 0, 0, 0, 0},  /* 640x480 */
+ {    3,  2, 1210, 690, 1130, 660,  50, 0, 0, 0, 0, 0, 0, 0},  /* 800x600 OK */
+ {    2,  1, 1100, 562, 1130, 640,   0, 1, 0, 0, 0, 0, 0, 0},  /* 720x480 OK */
+ {    1,  1, 1375, 878, 1130, 640, 638, 0, 0, 0, 0, 0, 0, 0},  /* 1024x768 OK */
+ {    5,  3, 1100, 675, 1130, 640,   0, 1, 0, 0, 0, 0, 0, 0},  /* 720/768x576 OK */
+ {   25, 24, 1496, 755, 1120, 680,  50, 0, 0, 0, 0, 0, 0, 0}   /* 1280x720 OK */
 };
 
-static const SiS_LCDDataStruct  SiS_LCD1280x720Data[] =  /* 2.03.00 */
+static const struct SiS_LCDData SiS_LCD1280x720Data[] =  /* 2.03.00 */
 {
        {  44,   15,  864,  430, 1408,  806 }, /* 640x400 */
        { 128,   35,  792,  385, 1408,  806 },
@@ -962,7 +1003,7 @@ static const SiS_LCDDataStruct  SiS_LCD1280x720Data[] =  /* 2.03.00 */
  * (Note: 1280x768_3 is now special for SiS301/NetVista
  */
 
-static const SiS_LCDDataStruct  SiS_StLCD1280x768_2Data[] = /* 2.03.00 */
+static const struct SiS_LCDData SiS_StLCD1280x768_2Data[] = /* 2.03.00 */
 {
        {  64,   21,  858,  434, 1408,  806 }, /* 640x400 */
        {  32,    9,  858,  372, 1408,  806 },
@@ -977,7 +1018,7 @@ static const SiS_LCDDataStruct  SiS_StLCD1280x768_2Data[] = /* 2.03.00 */
        {  16,   15, 1600,  750, 1600,  806 }  /* 1280x720 - from Ext */
 };
 
-static const SiS_LCDDataStruct  SiS_ExtLCD1280x768_2Data[] = /* 2.03.00 */
+static const struct SiS_LCDData SiS_ExtLCD1280x768_2Data[] = /* 2.03.00 */
 {
        {  16,    5,  960,  410, 1600,  806 }, /* 640x400 */
        {  64,   21, 1152,  364, 1600,  806 },
@@ -993,7 +1034,7 @@ static const SiS_LCDDataStruct  SiS_ExtLCD1280x768_2Data[] = /* 2.03.00 */
 };
 
 #if 0  /* Not used; _3 now reserved for NetVista (SiS301) */
-static const SiS_LCDDataStruct  SiS_LCD1280x768_3Data[] =
+static const struct SiS_LCDData SiS_LCD1280x768_3Data[] =
 {
        {  64,   25, 1056,  422, 1664,  798 },                  /* 640x400 */
        { 128,   39,  884,  396, 1408,  806 }, /* ,640 */
@@ -1009,7 +1050,7 @@ static const SiS_LCDDataStruct  SiS_LCD1280x768_3Data[] =
 };
 #endif
 
-static const SiS_LCDDataStruct  SiS_LCD1280x800Data[] = /* 0.93.12a (TMDS) */
+static const struct SiS_LCDData SiS_LCD1280x800Data[] = /* 0.93.12a (TMDS) */
 {
        { 128,   51, 1122,  412, 1408,  816 },  /* 640x400 */
        { 128,   49, 1232,  361, 1408,  816 },
@@ -1024,7 +1065,7 @@ static const SiS_LCDDataStruct  SiS_LCD1280x800Data[] = /* 0.93.12a (TMDS) */
        {   0,    0,    0,    0,    0,    0 }   /* 1280x720 */
 };
 
-static const SiS_LCDDataStruct  SiS_LCD1280x800_2Data[] = /* 2.03.00 (LVDS) */
+static const struct SiS_LCDData SiS_LCD1280x800_2Data[] = /* 2.03.00 (LVDS) */
 {
        {  97,   42, 1344,  409, 1552,  812 }, /* 640x400 */
        {  97,   35, 1280,  358, 1552,  812 },
@@ -1039,7 +1080,42 @@ static const SiS_LCDDataStruct  SiS_LCD1280x800_2Data[] = /* 2.03.00 (LVDS) */
        {  97,   90, 1600,  730, 1552,  812 }  /* 1280x720 */
 };
 
-static const SiS_LCDDataStruct  SiS_LCD1280x960Data[] =
+#if 0
+static const struct SiS_LCDData SiS_LCD1280x800_3Data[] = /* 2.02.05a (LVDS); m250 */
+{
+       { 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 }, /* 1280x1024 */
+       {   1,    1, 1408,  816, 1408,  816 }, /* 1280x800 */
+       {   0,    0,    0,    0,    0,    0 }, /* 1280x768 - patch index */
+       {   0,    0,    0,    0,    0,    0 }  /* 1280x720 */
+};
+#endif
+
+static const struct SiS_LCDData SiS_LCD1280x854Data[] = /* 2.21.00CS (LVDS) */
+{
+       {  56,   15,  936,  410, 1664,  861 },  /* 640x400 */
+       {  64,   25, 1586,  355, 1664,  861 },
+       {  56,   15,  936,  410, 1664,  861 },
+       {  64,   25, 1586,  355, 1664,  861 },
+       {  91,   45, 1464,  485, 1664,  861 },  /* 640x480 */
+       { 182,   75,  976,  605, 1664,  861 },  /* 800x600 */
+       {  91,   66, 1342,  774, 1664,  861 },  /* 1024x768 */
+       {   0,    0,    0,    0,    0,    0 },  /* 1280x1024 */
+       {  26,   25, 1708,  807, 1664,  861 },  /* 1280x800 */
+       {  13,   12, 1708,  774, 1664,  861 },  /* 1280x768 - patch index */
+       {  52,   45, 1708,  725, 1664,  861 },  /* 1280x720 */
+       {   0,    0,    0,    0,    0,    0 },
+       {   0,    0,    0,    0,    0,    0 },
+       {   1,    1, 1664,  861, 1664,  861 }   /* 1280x854 */
+};
+
+static const struct SiS_LCDData SiS_LCD1280x960Data[] =
 {
        {    9,   2,  800,  500, 1800, 1000 },
        {    9,   2,  800,  500, 1800, 1000 },
@@ -1049,10 +1125,15 @@ static const SiS_LCDDataStruct  SiS_LCD1280x960Data[] =
        {   30,  11, 1056,  625, 1800, 1000 },
        {    5,   3, 1350,  800, 1800, 1000 },
        {    1,   1, 1576, 1050, 1576, 1050 },
-       {    1,   1, 1800, 1000, 1800, 1000 }
+       {    1,   1, 1800, 1000, 1800, 1000 },
+       {   0,    0,    0,    0,    0,    0 },
+       {   0,    0,    0,    0,    0,    0 },
+       {   0,    0,    0,    0,    0,    0 },
+       {   0,    0,    0,    0,    0,    0 },
+       {   0,    0,    0,    0,    0,    0 }
 };
 
-static const SiS_LCDDataStruct  SiS_StLCD1400x1050Data[] =
+static const struct SiS_LCDData SiS_StLCD1400x1050Data[] =
 {
        { 211,  100, 2100,  408, 1688, 1066 },
        { 211,   64, 1536,  358, 1688, 1066 },
@@ -1062,10 +1143,15 @@ static const SiS_LCDDataStruct  SiS_StLCD1400x1050Data[] =
        { 211,   72, 1008,  609, 1688, 1066 },
        { 211,  128, 1400,  776, 1688, 1066 },
        { 211,  205, 1680, 1041, 1688, 1066 },
-       {   1,    1, 1688, 1066, 1688, 1066 }
+       {   1,    1, 1688, 1066, 1688, 1066 },
+       {   0,    0,    0,    0,    0,    0 },
+       {   0,    0,    0,    0,    0,    0 },
+       {   0,    0,    0,    0,    0,    0 },
+       {   0,    0,    0,    0,    0,    0 },
+       {   0,    0,    0,    0,    0,    0 }
 };
 
-static const SiS_LCDDataStruct  SiS_ExtLCD1400x1050Data[] =
+static const struct SiS_LCDData SiS_ExtLCD1400x1050Data[] =
 {
 /*     { 211,   60, 1260,  410, 1688, 1066 },    640x400 (6330) */
        { 211,  100, 2100,  408, 1688, 1066 }, /* 640x400 (6325) WORKS */
@@ -1080,10 +1166,13 @@ static const SiS_LCDDataStruct  SiS_ExtLCD1400x1050Data[] =
        { 211,  205, 1680, 1041, 1688, 1066 }, /* 1280x1024 - not used (always unscaled) */
        {   1,    1, 1688, 1066, 1688, 1066 }, /* 1400x1050 */
        {   0,    0,    0,    0,    0,    0 }, /* kludge */
-       { 211,  120, 1400,  730, 1688, 1066 }  /* 1280x720 */
+       { 211,  120, 1400,  730, 1688, 1066 }, /* 1280x720 */
+       {   0,    0,    0,    0,    0,    0 },
+       {   0,    0,    0,    0,    0,    0 },
+       {   0,    0,    0,    0,    0,    0 }
 };
 
-static const SiS_LCDDataStruct  SiS_LCD1680x1050Data[] =
+static const struct SiS_LCDData SiS_LCD1680x1050Data[] =
 {
        {  95,   24, 1260,  410, 1900, 1066 }, /*  0 640x400 */
        {  10,    3, 1710,  362, 1900, 1066 },
@@ -1097,10 +1186,11 @@ static const SiS_LCDDataStruct  SiS_LCD1680x1050Data[] =
        {  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 index */
-       {   1,    1, 1900, 1066, 1900, 1066 }  /* 12 1680x1050 */
+       {   1,    1, 1900, 1066, 1900, 1066 }, /* 12 1680x1050 */
+       {   0,    0,    0,    0,    0,    0 }
 };
 
-static const SiS_LCDDataStruct  SiS_StLCD1600x1200Data[] =
+static const struct SiS_LCDData SiS_StLCD1600x1200Data[] =
 {
        {27,  4, 800, 500, 2160, 1250 },
        {27,  4, 800, 500, 2160, 1250 },
@@ -1111,10 +1201,14 @@ static const SiS_LCDDataStruct  SiS_StLCD1600x1200Data[] =
        { 5,  2,1350, 800, 2160, 1250 },
        {135,88,1600,1100, 2160, 1250 },
        {72, 49,1680,1092, 2160, 1250 },
-       { 1,  1,2160,1250, 2160, 1250 }
+       { 1,  1,2160,1250, 2160, 1250 },
+       { 0,  0,   0,   0,    0,    0 },
+       { 0,  0,   0,   0,    0,    0 },
+       { 0,  0,   0,   0,    0,    0 },
+       { 0,  0,   0,   0,    0,    0 }
 };
 
-static const SiS_LCDDataStruct  SiS_ExtLCD1600x1200Data[] =
+static const struct SiS_LCDData SiS_ExtLCD1600x1200Data[] =
 {
        {72,11, 990, 422, 2160, 1250 }, /* 640x400 (6330) WORKS */
 /*     {27, 4, 800, 500, 2160, 1250 },    640x400 (6235) */
@@ -1127,10 +1221,14 @@ static const SiS_LCDDataStruct  SiS_ExtLCD1600x1200Data[] =
        { 5, 2,1350, 800, 2160, 1250 },
        {27,16,1500,1064, 2160, 1250 }, /* 1280x1024 */
        {72,49,1680,1092, 2160, 1250 }, /* 1400x1050 (6330, was not supported on 6325) */
-       { 1, 1,2160,1250, 2160, 1250 }
+       { 1, 1,2160,1250, 2160, 1250 },
+       { 0, 0,   0,   0,    0,    0 },
+       { 0, 0,   0,   0,    0,    0 },
+       { 0, 0,   0,   0,    0,    0 },
+       { 0, 0,   0,   0,    0,    0 }
 };
 
-static const SiS_LCDDataStruct  SiS_NoScaleData[] =
+static const struct SiS_LCDData SiS_NoScaleData[] =
 {
        { 1, 1, 800, 449, 800, 449 },  /* 0x00: 320x200, 640x400 */
        { 1, 1, 800, 449, 800, 449 },
@@ -1162,14 +1260,18 @@ static const SiS_LCDDataStruct  SiS_NoScaleData[] =
        { 1, 1,1808, 808,1808, 808 },  /* 0x1b: 1360x768 */
        { 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) */
+       { 1, 1,1408, 816,1408, 816 },  /* 0x1f: 1280x800 (TMDS special) */
+       { 1, 1,1760,1235,1760,1235 },  /* 0x20: 1600x1200 for LCDA */
+       { 1, 1,2048,1320,2048,1320 },  /* 0x21: 1600x1200 for non-SiS LVDS */
+       { 1, 1,1664, 861,1664, 861 }   /* 0x22: 1280x854 */
 };
 
 /**************************************************************/
 /* LVDS ----------------------------------------------------- */
 /**************************************************************/
 
-static const SiS_LVDSDataStruct  SiS_LVDS320x480Data_1[]=
+/* FSTN/DSTN 320x240, 2 variants */
+static const struct SiS_LVDSData SiS_LVDS320x240Data_1[]=
 {
        { 848, 433, 400, 525},
        { 848, 389, 400, 525},
@@ -1177,157 +1279,40 @@ static const SiS_LVDSDataStruct  SiS_LVDS320x480Data_1[]=
        { 848, 389, 400, 525},
        { 848, 518, 400, 525},
        {1056, 628, 400, 525},
-       { 400, 525, 400, 525},
-       { 800, 449,1000, 644},
-       { 800, 525,1000, 635}
+       { 400, 525, 400, 525}  /* xSTN */
 };
 
-static const SiS_LVDSDataStruct  SiS_LVDS640x480Data_1[]=
+static const struct SiS_LVDSData SiS_LVDS320x240Data_2[]=
 {
-       { 800, 445, 800, 525},   /* 800, 449, 800, 449 */
+       { 800, 445, 800, 525},
        { 800, 395, 800, 525},
        { 800, 445, 800, 525},
        { 800, 395, 800, 525},
        { 800, 525, 800, 525},
-       { 800, 525, 800, 525},   /* pseudo */
-       { 800, 525, 800, 525}    /* pseudo */
+       {1056, 628,1056, 628},
+       { 480, 525, 480, 525} /* xSTN */
 };
 
-/* FSTN 320x240 */
-static const SiS_LVDSDataStruct  SiS_LVDS640x480Data_2[]=
+static const struct SiS_LVDSData SiS_LVDS640x480Data_1[]=
 {
-       { 800, 445, 800, 525},
+       { 800, 445, 800, 525},   /* 800, 449, 800, 449 */
        { 800, 395, 800, 525},
        { 800, 445, 800, 525},
        { 800, 395, 800, 525},
-       { 800, 525, 800, 525},
-        { 800, 525, 800, 525},   /* pseudo */
-       { 800, 525, 800, 525}    /* pseudo */
+       { 800, 525, 800, 525}
 };
 
-static const SiS_LVDSDataStruct  SiS_LVDS800x600Data_1[]=
+static const struct SiS_LVDSData SiS_LVDS800x600Data_1[]=
 {
        { 848, 433,1060, 629},
        { 848, 389,1060, 629},
        { 848, 433,1060, 629},
        { 848, 389,1060, 629},
        { 848, 518,1060, 629},
-       {1056, 628,1056, 628},
        {1056, 628,1056, 628}
 };
 
-static const SiS_LVDSDataStruct  SiS_LVDS800x600Data_2[]=
-{
-       {1056, 628,1056, 628}
-};
-
-static const SiS_LVDSDataStruct  SiS_LVDS1024x768Data_1[]=
-{
-       { 840, 438,1344, 806},
-       { 840, 409,1344, 806},
-       { 840, 438,1344, 806},
-       { 840, 409,1344, 806},
-       { 840, 518,1344, 806},   /* 640x480 */
-       {1050, 638,1344, 806},   /* 800x600 */
-       {1344, 806,1344, 806},   /* 1024x768 */
-};
-
-static const SiS_LVDSDataStruct  SiS_LVDS1024x768Data_2[]=
-{
-       {1344, 806,1344, 806}
-};
-
-static const SiS_LVDSDataStruct  SiS_LVDS1280x1024Data_1[]=
-{
-       {1048, 442,1688,1066},
-       {1048, 392,1688,1066},
-       {1048, 442,1688,1066},
-       {1048, 392,1688,1066},
-       {1048, 522,1688,1066},
-       {1208, 642,1688,1066},
-       {1432, 810,1688,1066},
-       {1688,1066,1688,1066}
-};
-
-static const SiS_LVDSDataStruct  SiS_LVDS1280x1024Data_2[]=
-{
-       {1688,1066,1688,1066}
-};
-
-static const SiS_LVDSDataStruct  SiS_LVDS1400x1050Data_1[]=
-{
-        { 928, 416, 1688,1066},
-       { 928, 366, 1688,1066},
-       { 928, 416, 1688,1066},
-       { 928, 366, 1688,1066},
-       { 928, 496, 1688,1066},
-       {1088, 616, 1688,1066},
-       {1312, 784, 1688,1066},
-       {1568,1040, 1688,1066},
-       {1688,1066, 1688,1066}
-};
-
-static const SiS_LVDSDataStruct  SiS_LVDS1400x1050Data_2[]=
-{
-        {1688,1066, 1688,1066}
-};
-
-static const SiS_LVDSDataStruct  SiS_LVDS1600x1200Data_1[]=
-{
-       {1088, 520, 2048,1320},
-       {1088, 470, 2048,1320},
-       {1088, 520, 2048,1320},
-       {1088, 470, 2048,1320},
-       {1088, 600, 2048,1320},
-       {1248, 720, 2048,1320},
-       {1472, 888, 2048,1320},
-       {1728,1144, 2048,1320},
-       {1848,1170, 2048,1320},
-       {2048,1320, 2048,1320}
-};
-
-static const SiS_LVDSDataStruct  SiS_LVDS1600x1200Data_2[]=
-{
-        {2048,1320, 2048,1320}
-};
-
-static const SiS_LVDSDataStruct  SiS_LVDS1280x960Data_1[]=
-{
-       { 840, 438,1344, 806},
-       { 840, 409,1344, 806},
-       { 840, 438,1344, 806},
-       { 840, 409,1344, 806},
-       { 840, 518,1344, 806},
-       {1050, 638,1344, 806},
-       {1344, 806,1344, 806},
-       { 800, 449,1280, 801},
-       { 800, 525,1280, 813}
-};
-
-static const SiS_LVDSDataStruct  SiS_LVDS1280x960Data_2[]=
-{
-       {1344, 806,1344, 806}
-};
-
-static const SiS_LVDSDataStruct  SiS_LVDS1280x768Data_1[]=
-{
-       { 768, 438, 1408, 806},
-       { 768, 388, 1408, 806},
-       { 768, 438, 1408, 806},
-       { 768, 388, 1408, 806},
-       { 768, 518, 1408, 806},
-       { 928, 638, 1408, 806},
-       {1152, 806, 1408, 806},
-       {1408, 806, 1408, 806},
-       {1408, 806, 1408, 806}
-};
-
-static const SiS_LVDSDataStruct  SiS_LVDS1280x768Data_2[]=
-{
-       {1408, 806, 1408, 806}
-};
-
-static const SiS_LVDSDataStruct  SiS_LVDS1024x600Data_1[] =
+static const struct SiS_LVDSData SiS_LVDS1024x600Data_1[] =
 {
        { 840, 604,1344, 800},
        { 840, 560,1344, 800},
@@ -1338,124 +1323,18 @@ static const SiS_LVDSDataStruct  SiS_LVDS1024x600Data_1[] =
        {1344, 800,1344, 800}
 };
 
-static const SiS_LVDSDataStruct  SiS_LVDS1024x600Data_2[] =
-{
-       {1344, 800,1344, 800}
-};
-
-static const SiS_LVDSDataStruct  SiS_LVDS1152x768Data_1[] =
+static const struct SiS_LVDSData SiS_LVDS1024x768Data_1[]=
 {
        { 840, 438,1344, 806},
        { 840, 409,1344, 806},
        { 840, 438,1344, 806},
        { 840, 409,1344, 806},
-       { 840, 518,1344, 806},
-       {1050, 638,1344, 806},
-       {1344, 806,1344, 806}
-};
-
-static const SiS_LVDSDataStruct  SiS_LVDS1152x768Data_2[] =
-{
-       {1344, 806,1344, 806}
-};
-
-/* Pass 1:1 data */
-static const SiS_LVDSDataStruct  SiS_LVDSXXXxXXXData_1[]=
-{
-        { 800, 449,  800, 449},
-       { 800, 449,  800, 449},
-       { 900, 449,  900, 449},
-       { 900, 449,  900, 449},
-       { 800, 525,  800, 525},  /*  640x480  */
-       {1056, 628, 1056, 628},  /*  800x600  */
-       {1344, 806, 1344, 806},  /* 1024x768  */
-       {1688,1066, 1688,1066},  /* 1280x1024 */  /* INSERTED */
-       {1688, 806, 1688, 806},  /* 1280x768  */
-};
-
-/* Custom data for Barco iQ R series */
-static const SiS_LVDSDataStruct  SiS_LVDSBARCO1366Data_1[]=
-{
-       { 832, 438,1331, 806},
-       { 832, 388,1331, 806},
-       { 832, 438,1331, 806},
-       { 832, 388,1331, 806},
-       { 832, 518,1331, 806},
-       {1050, 638,1344, 806},
-       {1344, 806,1344, 806},
-       {1688,1066,1688,1066},
-       {1688,1066,1688,1066}   /* 1360x1024 */
-};
-
-/* Custom data for Barco iQ R series */
-static const SiS_LVDSDataStruct  SiS_LVDSBARCO1366Data_2[]=
-{
-       {1344, 806,1344, 806},
-       {1344, 806,1344, 806},
-       {1344, 806,1344, 806},
-       {1344, 806,1344, 806},
-       {1344, 806,1344, 806},
-       {1344, 806,1344, 806},
-       {1344, 806,1344, 806},
-       {1688,1066,1688,1066},
-       {1688,1066,1688,1066}   /* 1360x1024 */
-};
-
-/* Custom data for Barco iQ G series */
-static const SiS_LVDSDataStruct  SiS_LVDSBARCO1024Data_1[]=
-{
-       { 832, 438,1331, 806},
-       { 832, 409,1331, 806},
-       { 832, 438,1331, 806},
-       { 832, 409,1331, 806},
-       { 832, 518,1331, 806},   /* 640x480 */
+       { 840, 518,1344, 806},   /* 640x480 */
        {1050, 638,1344, 806},   /* 800x600 */
        {1344, 806,1344, 806},   /* 1024x768 */
 };
 
-/* Custom data for Barco iQ G series */
-static const SiS_LVDSDataStruct  SiS_LVDSBARCO1024Data_2[]=
-{
-       {1344, 806,1344, 806}
-};
-
-/* Custom data for 848x480 parallel panel */
-static const SiS_LVDSDataStruct  SiS_LVDS848x480Data_1[]=
-{
-       {   0,   0,   0,   0},
-       {   0,   0,   0,   0},
-       {   0,   0,   0,   0},
-       {   0,   0,   0,   0},
-       {1088, 525,1088, 525},  /* 640x480 TODO */
-       {1088, 525,1088, 525},  /* 800x600 TODO */
-       {1088, 525,1088, 525},  /* 1024x768 TODO */
-       {   0,   0,   0,   0},
-       {   0,   0,   0,   0},
-       {   0,   0,   0,   0},
-       {   0,   0,   0,   0},
-       {1088, 525,1088, 525},  /* 848x480 */
-       {1088, 525,1088, 525}   /* 1360x768 TODO */
-};
-
-/* Custom data for 848x480 parallel panel */
-static const SiS_LVDSDataStruct  SiS_LVDS848x480Data_2[]=
-{
-       {   0,   0,   0,   0},
-       {   0,   0,   0,   0},
-       {   0,   0,   0,   0},
-       {   0,   0,   0,   0},
-       {1088, 525,1088, 525},  /*  640x480 */
-       {1088, 525,1088, 525},  /*  800x600 */
-       {1088, 525,1088, 525},  /* 1024x768 */
-       {   0,   0,   0,   0},
-       {   0,   0,   0,   0},
-       {   0,   0,   0,   0},
-       {   0,   0,   0,   0},
-       {1088, 525,1088, 525},  /* 848x480 */
-       {1088, 525,1088, 525}   /* 1360x768 TODO */
-};
-
-static const SiS_LVDSDataStruct  SiS_CHTVUNTSCData[]=
+static const struct SiS_LVDSData SiS_CHTVUNTSCData[]=
 {
        { 840, 600, 840, 600},
        { 840, 600, 840, 600},
@@ -1466,7 +1345,7 @@ static const SiS_LVDSDataStruct  SiS_CHTVUNTSCData[]=
         {1160, 945,1160, 945}
 };
 
-static const SiS_LVDSDataStruct  SiS_CHTVONTSCData[]=
+static const struct SiS_LVDSData SiS_CHTVONTSCData[]=
 {
        { 840, 525, 840, 525},
        { 840, 525, 840, 525},
@@ -1477,55 +1356,9 @@ static const SiS_LVDSDataStruct  SiS_CHTVONTSCData[]=
         {1160, 840,1160, 840}
 };
 
-/* Chrontel TV Skew */
-
-static const SiS_LVDSDesStruct  SiS_CHTVUNTSCDesData[]=
-{
-       { 0,   0},
-       { 0,   0},
-       { 0,   0},
-       { 0,   0},
-       { 0,   0},
-       { 0,   0},
-       { 0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS_CHTVONTSCDesData[]=
-{
-       { 0,   0},
-       { 0,   0},
-       { 0,   0},
-       { 0,   0},
-       { 0,   0},
-       { 0,   0},
-       { 0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS_CHTVUPALDesData[]=
-{
-       {256,  0},
-       {256,  0},
-       {256,  0},
-       {256,  0},
-       { 0,   0},
-       { 0,   0},
-       { 0,   0}
-};
-
-static const SiS_LVDSDesStruct  SiS_CHTVOPALDesData[]=
-{
-       {256,  0},
-       {256,  0},
-       {256,  0},
-       {256,  0},
-       { 0,   0},
-       { 0,   0},
-       { 0,   0}
-};
-
 /* CRT1 CRTC data for slave modes */
 
-static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1320x480_1[] =
+static const struct SiS_LVDSCRT1Data SiS_LVDSCRT1320x240_1[] =
 {
  {{0x65,0x4f,0x89,0x56,0x83,0xaa,0x1f,
    0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
@@ -1550,48 +1383,7 @@ static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1320x480_1[] =
    0x00 }}
 };
 
-static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1640x480_1[] =
-{
- {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
-   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
-   0x00}},
- {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
-   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
-   0x00}},
- {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
-   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
-   0x00}},
- {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
-   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
-   0x00}},
- {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
-   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
-   0x00}},
- {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
-   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
-   0x01}}
-};
-
-static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1640x480_1_H[] =
-{
- {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
-   0x9c,0x8e,0x96,0xb9,0x00,0x00,0x00,
-   0x00}},
- {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
-   0x83,0x85,0x63,0xba,0x00,0x00,0x00,
-   0x00}},
- {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
-   0x9c,0x8e,0x96,0xb9,0x00,0x00,0x00,
-   0x00}},
- {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
-   0x83,0x85,0x63,0xba,0x00,0x00,0x00,
-   0x00}},
- {{0x2d,0x28,0x90,0x2c,0x80,0x0b,0x3e,
-   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
-   0x00}}
-};
-
-static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1640x480_2[] =
+static const struct SiS_LVDSCRT1Data SiS_LVDSCRT1320x240_2[] =
 {
  {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
    0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
@@ -1611,12 +1403,17 @@ static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1640x480_2[] =
  {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
    0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
    0x01}},
+#if 0
  {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e,
    0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
    0x00}}
+#endif
+ {{0x5f,0x4f,0x83,0x55,0x81,0x0b,0x3e,
+   0xe9,0x8b,0xe8,0x0c,0x00,0x00,0x05,
+   0x00}},
 };
 
-static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1640x480_2_H[] =
+static const struct SiS_LVDSCRT1Data SiS_LVDSCRT1320x240_2_H[] =
 {
  {{0x65,0x4f,0x89,0x56,0x83,0xaa,0x1f,
    0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
@@ -1641,7 +1438,7 @@ static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1640x480_2_H[] =
    0x00}}
 };
 
-static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1640x480_3[] =
+static const struct SiS_LVDSCRT1Data SiS_LVDSCRT1320x240_3[] =
 {
  {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
    0xe9,0x8b,0xdf,0x04,0x00,0x00,0x05,
@@ -1666,7 +1463,7 @@ static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1640x480_3[] =
    0x00}}
 };
 
-static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1640x480_3_H[] =
+static const struct SiS_LVDSCRT1Data SiS_LVDSCRT1320x240_3_H[] =
 {
  {{0x65,0x4f,0x89,0x56,0x83,0xaa,0x1f,
    0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
@@ -1691,778 +1488,175 @@ static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1640x480_3_H[] =
    0x00}}
 };
 
-static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11024x600_1[] =
-{
- {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e,
-   0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01,
-   0x00}},
- {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e,
-   0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01,
-   0x00}},
- {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e,
-   0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01,
-   0x00}},
- {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e,
-   0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01,
-   0x00}},
- {{0x64,0x4f,0x88,0x54,0x9f,0xaf,0xba,
-   0x3b,0x82,0xdf,0xb0,0x00,0x00,0x01,
-   0x00}},
- {{0x7e,0x63,0x82,0x68,0x15,0x1e,0xf1,
-   0xae,0x85,0x57,0x1f,0x30,0x00,0x26,
-   0x01}},
- {{0xa3,0x7f,0x87,0x86,0x97,0x1e,0xf1,
-   0xae,0x85,0x57,0x1f,0x30,0x00,0x02,
-   0x01}}
-};
-
-static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11024x600_1_H[] =
-{
- {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
-   0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
-   0x00}},
- {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
-   0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
-   0x00}},
- {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
-   0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
-   0x00}},
- {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
-   0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
-   0x00}},
- {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
-   0xe2,0x89,0xdf,0x05,0x00,0x00,0x44,
-   0x00}},
- {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
-   0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
-   0x01}},
- {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
-   0x02,0x88,0xff,0x25,0x10,0x00,0x01,
-   0x01}}
-};
-
-static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11024x600_2[] =
-{
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
-   0x00}},
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
-   0x00}},
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
-   0x00}},
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
-   0x00}},
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
-   0x00}},
- {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
-   0xae,0x84,0x57,0x25,0x30,0x00,0x02,
-   0x01}},
- {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
-   0x02,0x88,0xff,0x25,0x10,0x00,0x02,
-   0x01}}
-};
-
-static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11024x600_2_H[] =
-{
- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-   0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
-   0x00}},
- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-   0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
-   0x00}},
- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-   0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
-   0x00}},
- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-   0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
-   0x00}},
- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-   0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
-   0x00}},
- {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
-   0xae,0x84,0x57,0x25,0x30,0x00,0x01,
-   0x01}},
- {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
-   0x02,0x88,0xff,0x25,0x10,0x00,0x01,
-   0x01}}
-};
-
-static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11152x768_1[] =
-{
- {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
-   0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
-   0x00}},
- {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
-   0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
-   0x00}},
- {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
-   0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
-   0x00}},
- {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
-   0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
-   0x00}},
- {{0x64,0x4f,0x88,0x54,0x9f,0x04,0x3e,
-   0xe2,0x89,0xdf,0x05,0x00,0x00,0x01,
-   0x00}},
- {{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0,
-   0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26,
-   0x01}},
- {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
-   0x02,0x88,0xff,0x25,0x10,0x00,0x02,
-   0x01}}
-};
-
-static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11152x768_1_H[] =
-{
- {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
-   0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
-   0x00}},
- {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
-   0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
-   0x00}},
- {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
-   0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
-   0x00}},
- {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
-   0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
-   0x00}},
- {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
-   0xe2,0x89,0xdf,0x05,0x00,0x00,0x44,
-   0x00}},
- {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
-   0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
-   0x01}},
- {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
-   0x02,0x88,0xff,0x25,0x10,0x00,0x01,
-   0x01}}
-};
-
-static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11152x768_2[] =
-{
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
-   0x00}},
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
-   0x00}},
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
-   0x00}},
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
-   0x00}},
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
-   0x00}},
- {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
-   0xae,0x84,0x57,0x25,0x30,0x00,0x02,
-   0x01}},
- {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
-   0x02,0x88,0xff,0x25,0x10,0x00,0x02,
-   0x01}}
-};
-
-static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11152x768_2_H[] =
-{
- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-   0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
-   0x00}},
- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-   0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
-   0x00}},
- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-   0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
-   0x00}},
- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-   0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
-   0x00}},
- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-   0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
-   0x00}},
- {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
-   0xae,0x84,0x57,0x25,0x30,0x00,0x01,
-   0x01}},
- {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
-   0x02,0x88,0xff,0x25,0x10,0x00,0x01,
-   0x01}}
-};
-
-static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11280x768_1[] =
-{
- {{0x5b,0x4f,0x9f,0x55,0x19,0xb4,0x1f,
-   0x9c,0x8e,0x8f,0xb5,0x10,0x00,0x01,
-   0x00}},
- {{0x5b,0x4f,0x9f,0x55,0x19,0x82,0x1f,
-   0x6a,0x8c,0x5d,0x83,0x30,0x00,0x01,
-   0x00}},
- {{0x5b,0x4f,0x9f,0x55,0x19,0xb4,0x1f,
-   0x9c,0x8e,0x8f,0xb5,0x10,0x00,0x01,
-   0x00}},
- {{0x5b,0x4f,0x9f,0x55,0x19,0x82,0x1f,
-   0x6a,0x8c,0x5d,0x83,0x30,0x00,0x01,
-   0x00}},
- {{0x5b,0x4f,0x9f,0x55,0x19,0x04,0x3e,
-   0xec,0x8e,0xdf,0x05,0x20,0x00,0x01,
-   0x00}},
- {{0x6f,0x63,0x93,0x69,0x8d,0x7c,0xf0,
-   0x64,0x86,0x57,0x7d,0x20,0x00,0x05,
-   0x01}},
- {{0x8b,0x7f,0x8f,0x85,0x09,0x24,0xf5,
-   0x0c,0x8e,0xff,0x25,0x30,0x00,0x02,
-   0x01}},
- {{0xab,0x9f,0x8f,0xa5,0x89,0x24,0xf5,
-   0x0c,0x8e,0xff,0x25,0x30,0x00,0x06,
-   0x01}},
- {{0xab,0x9f,0x8f,0xa5,0x89,0x24,0xf5,
-   0x0c,0x8e,0xff,0x25,0x30,0x00,0x06,
-   0x01}}
-};
-
-static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11280x768_1_H[] =
+static const struct SiS_LVDSCRT1Data SiS_LVDSCRT1640x480_1[] =
 {
- {{0x47,0x27,0x8b,0x2c,0x1a,0x9e,0x1f,
-   0x93,0x86,0x8f,0x9f,0x30,0x00,0x05,
-   0x00}},
- {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
-   0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
-   0x00}},
- {{0x47,0x27,0x8b,0x30,0x1e,0x9e,0x1f,
-   0x92,0x86,0x8f,0x9f,0x30,0x00,0x05,
-   0x00}},
- {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
-   0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
-   0x00}},
- {{0x47,0x27,0x8b,0x2c,0x1a,0xee,0x1f,
-   0xe2,0x86,0xdf,0xef,0x10,0x00,0x05,
+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
+   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
    0x00}},
- {{0x51,0x31,0x95,0x36,0x04,0x66,0xf0,
-   0x5a,0x8e,0x57,0x67,0x20,0x00,0x01,
-   0x01}},
- {{0x5f,0x3f,0x83,0x44,0x92,0x0e,0xf5,
-   0x02,0x86,0xff,0x0f,0x10,0x00,0x01,
-   0x01}},
- {{0x6f,0x4f,0x93,0x54,0x82,0x0e,0x5a,
-   0x02,0x86,0xff,0x0f,0x09,0x00,0x05,
-   0x01}},
- {{0x6f,0x4f,0x93,0x54,0x82,0x0e,0x5a,
-   0x02,0x86,0xff,0x0f,0x09,0x00,0x05,
-   0x01}}
-};
-
-static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11280x768_2[] =
-{
- {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
-   0x54,0x86,0xdb,0xda,0x00,0x00,0x02,
+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
+   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
    0x00}},
- {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
-   0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x02,
+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
+   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
    0x00}},
- {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
-   0x54,0x86,0xdb,0xda,0x00,0x00,0x02,
+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
+   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
    0x00}},
- {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
-   0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x02,
+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
+   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
    0x00}},
- {{0xab,0x60,0x9f,0x80,0x04,0x24,0xb3,
-   0x7c,0x8e,0x03,0x02,0x10,0x00,0x02,
-   0x01}},
- {{0xab,0x63,0x8f,0x8a,0x8e,0x24,0xf1,
-   0xb6,0x88,0x57,0x25,0x10,0x00,0x02,
-   0x01}},
- {{0xab,0x7f,0x8f,0x98,0x9c,0x24,0xf5,
-   0x0a,0x8c,0xff,0x25,0x30,0x00,0x02,
-   0x01}},
- {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
-   0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
-   0x01}},
- {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
-   0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
+ {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
+   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
    0x01}}
 };
 
-static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11280x768_2_H[] =
+static const struct SiS_LVDSCRT1Data SiS_LVDSCRT1640x480_1_H[] =
 {
- {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
-   0x54,0x86,0xdb,0xda,0x00,0x00,0x01,
+ {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+   0x9c,0x8e,0x96,0xb9,0x00,0x00,0x00,
    0x00}},
- {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
-   0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x01,
+ {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+   0x83,0x85,0x63,0xba,0x00,0x00,0x00,
    0x00}},
- {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
-   0x54,0x86,0xdb,0xda,0x00,0x00,0x01,
+ {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+   0x9c,0x8e,0x96,0xb9,0x00,0x00,0x00,
    0x00}},
- {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
-   0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x01,
+ {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+   0x83,0x85,0x63,0xba,0x00,0x00,0x00,
    0x00}},
- {{0x83,0x38,0x97,0x58,0x9c,0x24,0xb3,
-   0x7c,0x8e,0x03,0x02,0x10,0x00,0x01,
-   0x01}},
- {{0x79,0x31,0x9d,0x58,0x9c,0x24,0xf1,
-   0xb6,0x88,0x57,0x25,0x10,0x00,0x01,
-   0x01}},
- {{0x6b,0x3f,0x8f,0x58,0x9c,0x24,0xf5,
-   0x0a,0x8c,0xff,0x25,0x30,0x00,0x01,
-   0x01}},
- {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
-   0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
-   0x01}},
- {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
-   0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
-   0x01}}
-};
-
-/**************************************************************/
-/* COMMON --------------------------------------------------- */
-/**************************************************************/
-
-#ifdef LINUX_XF86
-
-#define SIS_PL_HSYNCP 0x01
-#define SIS_PL_HSYNCN 0x02
-#define SIS_PL_VSYNCP 0x04
-#define SIS_PL_VSYNCN 0x08
-#define SIS_PL_DVI    0x80
-
-typedef struct _SiS_PlasmaModes
-{
-  const char *name;
-  ULONG  clock;
-  USHORT HDisplay, HTotal, HFrontPorch, HSyncWidth;
-  USHORT VDisplay, VTotal, VFrontPorch, VSyncWidth;
-  UCHAR  SyncFlags;
-} SiS_PlasmaModes;
-
-typedef struct _SiS_PlasmaTables
-{
-   USHORT vendor;
-   UCHAR  productnum;
-   USHORT product[5];
-   const char *DDCnames[5];
-   const char *plasmaname;
-   USHORT maxx,maxy;
-   USHORT prefx, prefy;
-   UCHAR  modenum;
-   UCHAR  plasmamodes[20];  /* | 0x80 = DVI-capable, | 0x40 = analog */
-} SiS_PlasmaTables;
-
-static const SiS_PlasmaModes SiS_PlasmaMode[] = {
-   {  "640x400",               /* 00: IBM 400@70 */
-      25175,
-       640,  800, 17,  64,
-       400,  449, 13,   2,
-      SIS_PL_HSYNCN | SIS_PL_VSYNCN },
-   {  "640x480",               /* 01: VESA 480@72 */
-      31500,
-       640,  832, 24,  40,
-       480,  520,  9,   3,
-      SIS_PL_HSYNCN | SIS_PL_VSYNCN },
-   {  "800x600",               /* 02: VESA 600@72 */
-      50000,
-       800, 1040, 56, 120,
-       600,  666, 37,   6,
-      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
-   {  "864x480",               /* 03: Cereb wide 1 */
-      42526,
-       864, 1134, 22,  86,
-       480,  500,  1,   3,
-      SIS_PL_HSYNCP | SIS_PL_VSYNCN },
-   {  "848x480",               /* 04: VESA wide (NEC1) */
-      33750,
-       848, 1088, 16, 112,
-       480,  517,  6,   8,
-      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
-   {  "1024x576",              /* 05: VESA wide (NEC2) */
-      47250,
-      1024, 1320, 16, 144,
-       576,  596,  2,   4,
-      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
-   {  "1280x720",              /* 06: VESA wide (NEC3) */
-      76500,
-      1280, 1696, 48, 176,
-       720,  750,  4,   8,
-      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
-   {  "1360x765",              /* 07: VESA wide (NEC4) */
-      85500,
-      1360, 1792, 64, 176,
-       765,  795,  4,   8,
-      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
-   {  "1024x600",              /* 08: CEREB wide 2 */
-      51200,
-      1024, 1352, 51, 164,
-       600,  628,  1,   4,
-      SIS_PL_HSYNCN | SIS_PL_VSYNCP },
-   {  "1024x768",              /* 09: VESA 768@75 */
-      78750,
-      1024, 1312,  16, 96,
-       768,  800,   1,  3,
-      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
-   {  "1152x864",              /* 10: VESA 1152x864@75 */
-      108000,
-      1152, 1600, 64, 128,
-       864,  900,  1,   3,
-      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
-   {  "1280x1024",             /* 11: VESA 1024@60 */
-      108000,
-      1280, 1688, 48, 112,
-      1024, 1066,  1,   3,
-      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
-   {  "1280x768",              /* 12: W_XGA */
-      81000,
-      1280, 1688, 48, 112,
-       768,  802,  3,   6,
-      SIS_PL_HSYNCP | SIS_PL_VSYNCN },
-   {  "1280x768",              /* 13: I/O Data W_XGA@56Hz */
-      76064,
-      1280, 1688, 48, 112,
-       768,  802,  2,   3,
-      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
-   {  "1376x768",              /* 14: I/O Wide XGA */
-      87340,
-      1376, 1808, 32, 128,
-       768,  806,  3,   6,
-      SIS_PL_HSYNCN | SIS_PL_VSYNCP },
-   {  "1280x960",              /* 15: VESA 960@60 */
-      108000,
-      1280, 1800, 96, 112,
-       960, 1000,  1,   3,
-      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
-   {  "1400x1050",             /* 16: VESA 1050@60Hz */
-      108000,
-      1400, 1688, 48, 112,
-      1050, 1066,  1,   3,
-      SIS_PL_HSYNCN | SIS_PL_VSYNCN },
-   {  "1360x768",              /* 17: VESA wide (NEC4/2) */
-      85500,
-      1360, 1792, 64, 112,
-       765,  795,  3,   6,
-      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
-   {  "800x600",               /* 18: VESA 600@56 */
-      36000,
-       800, 1024, 24,   2,
-       600,  625,  1,   2,
-      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
-   {  "1072x600",              /* 19: Panasonic 1072x600 (sync?) */
-      54100,
-       1072, 1424, 48, 176,
-        600,  628, 16,   1,
-      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
-   {  "848x480",               /* 20: Panasonic 848x480 (sync?) */
-      33070,                   /* is 852x480, but we can't use 852 */
-        848, 1068, 20,  40,    /* differs from DDC data, better centered */
-        480,  516,  3,   5,    /* won't work assumingly, because data is % 8 */
-      SIS_PL_HSYNCN | SIS_PL_VSYNCN },
-   {  "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 },
+ {{0x2d,0x28,0x90,0x2c,0x80,0x0b,0x3e,
+   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
+   0x00}}
 };
 
-/*
-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       }
-   },
+BOOLEAN                SiSInitPtr(struct SiS_Private *SiS_Pr);
+#ifdef SIS_XORG_XF86
+unsigned short SiS_GetModeID(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay,
+                               int Depth, BOOLEAN FSTN, int LCDwith, int LCDheight);
 #endif
-#if 0  /* Product IDs missing */
-   { 0x38a3, 3,
-     { 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       }
-   },
-   { 0x38a3, 1,
-     { 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       }
-   },
-   { 0x38a3, 2,
-     { 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       }
-   },
-   { 0x38a3, 2,
-     { 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       }
-   },
-   { 0x38a3, 1,
-     { 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       }
-   },
+unsigned short SiS_GetModeID_LCD(int VGAEngine, unsigned int VBFlags, int HDisplay,
+                               int VDisplay, int Depth, BOOLEAN FSTN,
+                               unsigned short CustomT, int LCDwith, int LCDheight,
+                               unsigned int VBFlags2);
+unsigned short SiS_GetModeID_TV(int VGAEngine, unsigned int VBFlags, int HDisplay,
+                               int VDisplay, int Depth, unsigned int VBFlags2);
+unsigned short SiS_GetModeID_VGA2(int VGAEngine, unsigned int VBFlags, int HDisplay,
+                               int VDisplay, int Depth, unsigned int VBFlags2);
+
+void           SiS_SetReg(SISIOADDRESS port, unsigned short index, unsigned short data);
+void           SiS_SetRegByte(SISIOADDRESS port, unsigned short data);
+void           SiS_SetRegShort(SISIOADDRESS port, unsigned short data);
+void           SiS_SetRegLong(SISIOADDRESS port, unsigned int data);
+unsigned char  SiS_GetReg(SISIOADDRESS port, unsigned short index);
+unsigned char  SiS_GetRegByte(SISIOADDRESS port);
+unsigned short SiS_GetRegShort(SISIOADDRESS port);
+unsigned int   SiS_GetRegLong(SISIOADDRESS port);
+void           SiS_SetRegANDOR(SISIOADDRESS Port, unsigned short Index, unsigned short DataAND,
+                               unsigned short DataOR);
+void           SiS_SetRegAND(SISIOADDRESS Port,unsigned short Index, unsigned short DataAND);
+void           SiS_SetRegOR(SISIOADDRESS Port,unsigned short Index, unsigned short DataOR);
+
+void           SiS_DisplayOn(struct SiS_Private *SiS_Pr);
+void           SiS_DisplayOff(struct SiS_Private *SiS_Pr);
+void           SiSRegInit(struct SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr);
+#ifndef SIS_LINUX_KERNEL
+void           SiSSetLVDSetc(struct SiS_Private *SiS_Pr);
 #endif
-   { 0x38a3, 4,
-     { 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       }
-   },
-#if 0  /* Product IDs missing */
-   { 0x38a3, 1,
-     { 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       }
-   },
-   { 0x38a3, 1,
-     { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
-     { "", "", "", "", "" },
-     "NEC PlasmaSync 4200W",
-     4,   /* DVI entirely unknown */
-     { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 0     , 0     , 0     , 0     , 0     , 0     ,
-       0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
-   },
-   { 0x38a3, 1,
-     { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
-     { "", "", "", "", "" },
-     "NEC PlasmaSync 4210W",
-     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       }
-   },
-   { 0x38a3, 1,
-     { 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       }
-   },
-#endif
-   { 0x412f, 2,
-     { 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       }
-   },
-   { 0x34a9, 1,
-     { 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       }
-   },
-   { 0x34a9, 1,
-     { 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 }
-};
+void           SiS_SetEnableDstn(struct SiS_Private *SiS_Pr, int enable);
+void           SiS_SetEnableFstn(struct SiS_Private *SiS_Pr, int enable);
+unsigned short SiS_GetModeFlag(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+                               unsigned short ModeIdIndex);
+BOOLEAN                SiSDetermineROMLayout661(struct SiS_Private *SiS_Pr);
+#ifndef SIS_LINUX_KERNEL
+void           SiS_GetVBType(struct SiS_Private *SiS_Pr);
 #endif
 
-#ifdef LINUX_XF86
-USHORT  SiS_GetModeID(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay,
-                         int Depth, BOOLEAN FSTN, int LCDwith, int LCDheight);
+BOOLEAN                SiS_SearchModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo,
+                               unsigned short *ModeIdIndex);
+unsigned short SiS_GetModePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+                               unsigned short ModeIdIndex);
+unsigned short  SiS_GetRefCRTVCLK(struct SiS_Private *SiS_Pr, unsigned short Index, int UseWide);
+unsigned short  SiS_GetRefCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short Index, int UseWide);
+unsigned short SiS_GetColorDepth(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+                               unsigned short ModeIdIndex);
+unsigned short SiS_GetOffset(struct SiS_Private *SiS_Pr,unsigned short ModeNo,
+                               unsigned short ModeIdIndex, unsigned short RRTI);
+#ifdef SIS300
+void           SiS_GetFIFOThresholdIndex300(struct SiS_Private *SiS_Pr, unsigned short *idx1,
+                               unsigned short *idx2);
+unsigned short SiS_GetFIFOThresholdB300(unsigned short idx1, unsigned short idx2);
+unsigned short SiS_GetLatencyFactor630(struct SiS_Private *SiS_Pr, unsigned short index);
 #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);
-USHORT  SiS_GetModeID_VGA2(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth);
-
-void   SiS_SetReg(SISIOADDRESS port, USHORT index, USHORT data);
-void   SiS_SetRegByte(SISIOADDRESS port, USHORT data);
-void   SiS_SetRegShort(SISIOADDRESS port, USHORT data);
-void   SiS_SetRegLong(SISIOADDRESS port, ULONG data);
-UCHAR  SiS_GetReg(SISIOADDRESS port, USHORT index);
-UCHAR  SiS_GetRegByte(SISIOADDRESS port);
-USHORT SiS_GetRegShort(SISIOADDRESS port);
-ULONG  SiS_GetRegLong(SISIOADDRESS port);
-void   SiS_SetRegANDOR(SISIOADDRESS Port, USHORT Index, USHORT DataAND, USHORT DataOR);
-void   SiS_SetRegAND(SISIOADDRESS Port,USHORT Index, USHORT DataAND);
-void   SiS_SetRegOR(SISIOADDRESS Port,USHORT Index, USHORT DataOR);
-void   SiS_DisplayOn(SiS_Private *SiS_Pr);
-void   SiS_DisplayOff(SiS_Private *SiS_Pr);
-void   SiSRegInit(SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr);
-BOOLEAN SiSDetermineROMLayout661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
-void   SiS_SetEnableDstn(SiS_Private *SiS_Pr, int enable);
-void   SiS_SetEnableFstn(SiS_Private *SiS_Pr, int enable);
-BOOLEAN        SiS_SearchModeID(SiS_Private *SiS_Pr, USHORT *ModeNo, USHORT *ModeIdIndex);
-UCHAR  SiS_GetModePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex);
-USHORT SiS_GetColorDepth(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex);
-USHORT SiS_GetOffset(SiS_Private *SiS_Pr,USHORT ModeNo, USHORT ModeIdIndex,
-              USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo);
-void   SiS_LoadDAC(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo, USHORT ModeIdIndex);
-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,
-               DisplayModePtr mode, BOOLEAN IsCustom);
-BOOLEAN        SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
-               DisplayModePtr mode, BOOLEAN IsCustom);
-BOOLEAN        SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
-               DisplayModePtr mode, BOOLEAN IsCustom);
-int    SiSTranslateToVESA(ScrnInfoPtr pScrn, int modenumber);
-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);
+void           SiS_LoadDAC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex);
+#ifdef SIS_XORG_XF86
+BOOLEAN                SiSSetMode(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, unsigned short ModeNo,
+                               BOOLEAN dosetpitch);
+BOOLEAN                SiSBIOSSetMode(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
+                               DisplayModePtr mode, BOOLEAN IsCustom);
+BOOLEAN                SiSBIOSSetModeCRT2(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
+                               DisplayModePtr mode, BOOLEAN IsCustom);
+BOOLEAN                SiSBIOSSetModeCRT1(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
+                               DisplayModePtr mode, BOOLEAN IsCustom);
+#endif
+#ifdef SIS_LINUX_KERNEL
+BOOLEAN                SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo);
+#endif
+void           SiS_CalcCRRegisters(struct SiS_Private *SiS_Pr, int depth);
+void           SiS_CalcLCDACRT1Timing(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+                               unsigned short ModeIdIndex);
+#ifdef SIS_XORG_XF86
+void           SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata, int xres,
+                               int yres, DisplayModePtr current);
+#endif
+#ifdef SIS_LINUX_KERNEL
+void           SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata, int xres,
+                               int yres, struct fb_var_screeninfo *var, BOOLEAN writeres);
 #endif
 
-#ifdef LINUX_KERNEL
-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,
-                       UCHAR modeno, int *htotal, int *vtotal, UCHAR rateindex);
+/* From init301.c: */
+extern void            SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+                               unsigned short ModeIdIndex, int chkcrt2mode);
+extern void            SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+                               unsigned short ModeIdIndex);
+extern void            SiS_SetYPbPr(struct SiS_Private *SiS_Pr);
+extern void            SiS_SetTVMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+                               unsigned short ModeIdIndex);
+extern void            SiS_UnLockCRT2(struct SiS_Private *SiS_Pr);
+extern void            SiS_DisableBridge(struct SiS_Private *);
+extern BOOLEAN         SiS_SetCRT2Group(struct SiS_Private *, unsigned short);
+extern unsigned short  SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+                               unsigned short ModeIdIndex);
+extern void            SiS_WaitRetrace1(struct SiS_Private *SiS_Pr);
+extern unsigned short  SiS_GetResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+                               unsigned short ModeIdIndex);
+extern unsigned short  SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short tempax);
+extern unsigned short  SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+                               unsigned short ModeIdIndex, unsigned short RRTI);
+extern BOOLEAN         SiS_IsVAMode(struct SiS_Private *);
+extern BOOLEAN         SiS_IsDualEdge(struct SiS_Private *);
+
+#ifdef SIS_XORG_XF86
+/* From other modules: */
+extern unsigned short  SiS_CheckBuildCustomMode(ScrnInfoPtr pScrn, DisplayModePtr mode,
+                               unsigned int VBFlags);
+extern unsigned char   SiS_GetSetBIOSScratch(ScrnInfoPtr pScrn, unsigned short offset,
+                               unsigned char value);
+extern unsigned char   SiS_GetSetModeID(ScrnInfoPtr pScrn, unsigned char id);
+extern unsigned short  SiS_GetModeNumber(ScrnInfoPtr pScrn, DisplayModePtr mode,
+                               unsigned int VBFlags);
 #endif
 
-/* 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_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);
-extern void    SiSCalcClock(ScrnInfoPtr pScrn, int clock, int max_VLD, unsigned int *vclk);
-
-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);
+#ifdef SIS_LINUX_KERNEL
+#ifdef SIS300
+extern unsigned int    sisfb_read_nbridge_pci_dword(struct SiS_Private *SiS_Pr, int reg);
+extern void            sisfb_write_nbridge_pci_dword(struct SiS_Private *SiS_Pr, int reg,
+                               unsigned int val);
+#endif
+#ifdef SIS315H
+extern void            sisfb_write_nbridge_pci_byte(struct SiS_Private *SiS_Pr, int reg,
+                               unsigned char val);
+extern unsigned int    sisfb_read_mio_pci_word(struct SiS_Private *SiS_Pr, int reg);
+#endif
 #endif
 
 #endif
index 274dacd..2d88f90 100644 (file)
@@ -2,11 +2,12 @@
 /* $XdotOrg$ */
 /*
  * Mode initializing code (CRT2 section)
- * for SiS 300/305/540/630/730 and
- *     SiS 315/550/650/M650/651/661FX/M661xX/740/741(GX)/M741/330/660/M660/760/M760
- * (Universal module for Linux kernel framebuffer and XFree86/X.org 4.x)
+ * for SiS 300/305/540/630/730,
+ *     SiS 315/550/[M]650/651/[M]661[FGM]X/[M]74x[GX]/330/[M]76x[GX],
+ *     XGI V3XT/V5/V8, Z7
+ * (Universal module for Linux kernel framebuffer and X.org/XFree86 4.x)
  *
- * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
  *
  * If distributed as part of the Linux kernel, the following license terms
  * apply:
@@ -38,7 +39,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,
  * Formerly based on non-functional code-fragements for 300 series by SiS, Inc.
  * Used by permission.
  *
- * TW says: This code looks awful, I know. But please don't do anything about
- * this otherwise debugging will be hell.
- * The code is extremely fragile as regards the different chipsets, different
- * video bridges and combinations thereof. If anything is changed, extreme
- * care has to be taken that that change doesn't break it for other chipsets,
- * bridges or combinations thereof.
- * All comments in this file are by me, regardless if marked TW or not.
- *
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #if 1
 #define SET_EMI                /* 302LV/ELV: Set EMI values */
 #endif
 
+#if 1
+#define SET_PWD                /* 301/302LV: Set PWD */
+#endif
+
 #define COMPAL_HACK    /* Needed for Compal 1400x1050 (EMI) */
 #define COMPAQ_HACK    /* Needed for Inventec/Compaq 1280x1024 (EMI) */
 #define ASUS_HACK      /* Needed for Asus A2H 1024x768 (EMI) */
 #define SiS_I2CDELAY      1000
 #define SiS_I2CDELAYSHORT  150
 
-static USHORT SiS_GetBIOSLCDResInfo(SiS_Private *SiS_Pr);
-static void SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx);
+static unsigned short  SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr);
+#ifdef SIS_LINUX_KERNEL
+static void            SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);
+#endif
 
 /*********************************************/
 /*         HELPER: Lock/Unlock CRT2          */
 /*********************************************/
 
 void
-SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_UnLockCRT2(struct SiS_Private *SiS_Pr)
 {
-   if(HwInfo->jChipType >= SIS_315H)
+   if(SiS_Pr->ChipType == XGI_20)
+      return;
+   else if(SiS_Pr->ChipType >= SIS_315H)
       SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
    else
       SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
 }
 
-static void
-SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+#ifdef SIS_LINUX_KERNEL
+static
+#endif
+void
+SiS_LockCRT2(struct SiS_Private *SiS_Pr)
 {
-   if(HwInfo->jChipType >= SIS_315H)
+   if(SiS_Pr->ChipType == XGI_20)
+      return;
+   else if(SiS_Pr->ChipType >= SIS_315H)
       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
    else
       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
@@ -115,9 +125,9 @@ SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 /*********************************************/
 
 static void
-SiS_SetRegSR11ANDOR(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT DataAND, USHORT DataOR)
+SiS_SetRegSR11ANDOR(struct SiS_Private *SiS_Pr, unsigned short DataAND, unsigned short DataOR)
 {
-   if(HwInfo->jChipType >= SIS_661) {
+   if(SiS_Pr->ChipType >= SIS_661) {
       DataAND &= 0x0f;
       DataOR  &= 0x0f;
    }
@@ -129,12 +139,12 @@ SiS_SetRegSR11ANDOR(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT DataAND, US
 /*********************************************/
 
 #ifdef SIS315H
-static UCHAR *
-GetLCDStructPtr661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+static unsigned char *
+GetLCDStructPtr661(struct SiS_Private *SiS_Pr)
 {
-   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
-   UCHAR  *myptr = NULL;
-   USHORT romindex = 0, reg = 0, idx = 0;
+   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
+   unsigned char  *myptr = NULL;
+   unsigned short romindex = 0, reg = 0, idx = 0;
 
    /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
     * due to the variaty of panels the BIOS doesn't know about.
@@ -144,15 +154,15 @@ GetLCDStructPtr661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
     */
 
    if((SiS_Pr->SiS_ROMNew) &&
-      ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) || (!SiS_Pr->PanelSelfDetected))) {
+      ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) {
 
-      if(HwInfo->jChipType < SIS_661) reg = 0x3c;
-      else                            reg = 0x7d;
+      if(SiS_Pr->ChipType < 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];
+         myptr = (unsigned char *)&SiS_LCDStruct661[idx];
       }
       romindex = SISGETROMW(0x100);
       if(romindex) {
@@ -163,11 +173,11 @@ GetLCDStructPtr661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
    return myptr;
 }
 
-static USHORT
-GetLCDStructPtr661_2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+static unsigned short
+GetLCDStructPtr661_2(struct SiS_Private *SiS_Pr)
 {
-   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
-   USHORT romptr = 0;
+   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
+   unsigned short romptr = 0;
 
    /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
     * due to the variaty of panels the BIOS doesn't know about.
@@ -177,12 +187,12 @@ GetLCDStructPtr661_2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
     */
 
    if((SiS_Pr->SiS_ROMNew) &&
-      ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) || (!SiS_Pr->PanelSelfDetected))) {
+      ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) {
       romptr = SISGETROMW(0x102);
       romptr += ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) * SiS_Pr->SiS661LCD2TableSize);
    }
 
-   return(romptr);
+   return romptr;
 }
 #endif
 
@@ -191,186 +201,187 @@ GetLCDStructPtr661_2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 /*********************************************/
 
 static BOOLEAN
-SiS_AdjustCRT2Rate(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
-                   USHORT RRTI, USHORT *i, PSIS_HW_INFO HwInfo)
+SiS_AdjustCRT2Rate(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
+               unsigned short RRTI, unsigned short *i)
 {
-  USHORT checkmask=0,modeid,infoflag;
+   unsigned short checkmask=0, modeid, infoflag;
 
-  modeid = SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID;
+   modeid = SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID;
 
-  if(SiS_Pr->SiS_VBType & VB_SISVB) {
+   if(SiS_Pr->SiS_VBType & VB_SISVB) {
 
-     if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
+      if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
 
-       checkmask |= SupportRAMDAC2;
-       if(HwInfo->jChipType >= SIS_315H) {
-          checkmask |= SupportRAMDAC2_135;
-          if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-             checkmask |= SupportRAMDAC2_162;
-             if(SiS_Pr->SiS_VBType & VB_SIS301C) {
-                checkmask |= SupportRAMDAC2_202;
-             }
-          }
-       }
+        checkmask |= SupportRAMDAC2;
+        if(SiS_Pr->ChipType >= SIS_315H) {
+           checkmask |= SupportRAMDAC2_135;
+           if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
+              checkmask |= SupportRAMDAC2_162;
+              if(SiS_Pr->SiS_VBType & VB_SISRAMDAC202) {
+                 checkmask |= SupportRAMDAC2_202;
+              }
+           }
+        }
 
-     } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+      } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
 
-       checkmask |= SupportLCD;
-       if(HwInfo->jChipType >= SIS_315H) {
-          if(SiS_Pr->SiS_VBType & VB_SISVB) {
-             if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
-                if(modeid == 0x2e) checkmask |= Support64048060Hz;
-             }
-          }
-       }
+        checkmask |= SupportLCD;
+        if(SiS_Pr->ChipType >= SIS_315H) {
+           if(SiS_Pr->SiS_VBType & VB_SISVB) {
+              if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
+                 if(modeid == 0x2e) checkmask |= Support64048060Hz;
+              }
+           }
+        }
 
-     } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
+      } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
 
-       checkmask |= SupportHiVision;
+        checkmask |= SupportHiVision;
 
-     } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750|SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
+      } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750|SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
 
-        checkmask |= SupportTV;
-       if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-          checkmask |= SupportTV1024;
-          if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
-             if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
-                checkmask |= SupportYPbPr750p;
-             }
-          }
-       }
+        checkmask |= SupportTV;
+        if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
+           checkmask |= SupportTV1024;
+           if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
+              if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
+                 checkmask |= SupportYPbPr750p;
+              }
+           }
+        }
 
-     }
+      }
 
-  } else {     /* LVDS */
+   } else {    /* LVDS */
 
-     if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
-       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-           checkmask |= SupportCHTV;
-       }
-     }
+      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+        if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+           checkmask |= SupportCHTV;
+        }
+      }
 
-     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-       checkmask |= SupportLCD;
-     }
+      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+        checkmask |= SupportLCD;
+      }
 
-  }
+   }
 
-  /* Look backwards in table for matching CRT2 mode */
-  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;
-  }
+   /* Look backwards in table for matching CRT2 mode */
+   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;
+   }
 
-  /* Look through the whole mode-section of the table from the beginning
-   * for a matching CRT2 mode if no mode was found yet.
-   */
-  for((*i) = 0; ; (*i)++) {
-     if(SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID != modeid) break;
-     infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
-     if(infoflag & checkmask) return TRUE;
-  }
-  return FALSE;
+   /* Look through the whole mode-section of the table from the beginning
+    * for a matching CRT2 mode if no mode was found yet.
+    */
+   for((*i) = 0; ; (*i)++) {
+      if(SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID != modeid) break;
+      infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
+      if(infoflag & checkmask) return TRUE;
+   }
+   return FALSE;
 }
 
 /*********************************************/
 /*              Get rate index               */
 /*********************************************/
 
-USHORT
-SiS_GetRatePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
-               PSIS_HW_INFO HwInfo)
-{
-  SHORT  LCDRefreshIndex[] = { 0x00, 0x00, 0x01, 0x01,
-                               0x01, 0x01, 0x01, 0x01,
-                              0x01, 0x01, 0x01, 0x01,
-                              0x01, 0x01, 0x01, 0x01,
-                              0x00, 0x00, 0x00, 0x00 };
-  USHORT RRTI,i,backup_i;
-  USHORT modeflag,index,temp,backupindex;
+unsigned short
+SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
+{
+   unsigned short RRTI,i,backup_i;
+   unsigned short modeflag,index,temp,backupindex;
+   static const unsigned short LCDRefreshIndex[] = {
+               0x00, 0x00, 0x01, 0x01,
+               0x01, 0x01, 0x01, 0x01,
+               0x01, 0x01, 0x01, 0x01,
+               0x01, 0x01, 0x01, 0x01,
+               0x00, 0x00, 0x00, 0x00
+   };
 
-  /* Do NOT check for UseCustomMode here, will skrew up FIFO */
-  if(ModeNo == 0xfe) return 0;
+   /* Do NOT check for UseCustomMode here, will skrew up FIFO */
+   if(ModeNo == 0xfe) return 0;
 
-  if(ModeNo <= 0x13) {
-     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-  } else {
-     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-  }
+   if(ModeNo <= 0x13) {
+      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+   } else {
+      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+   }
 
-  if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
-     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-       if(modeflag & HalfDCLK) return 0;
-     }
-  }
+   if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+        if(modeflag & HalfDCLK) return 0;
+      }
+   }
 
-  if(ModeNo < 0x14) return 0xFFFF;
+   if(ModeNo < 0x14) return 0xFFFF;
 
-  index = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x33) >> SiS_Pr->SiS_SelectCRT2Rate) & 0x0F;
-  backupindex = index;
+   index = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x33) >> SiS_Pr->SiS_SelectCRT2Rate) & 0x0F;
+   backupindex = index;
 
-  if(index > 0) index--;
+   if(index > 0) index--;
 
-  if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
-     if(SiS_Pr->SiS_VBType & VB_SISVB) {
-        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-          if(SiS_Pr->SiS_VBType & VB_NoLCD)            index = 0;
-          else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index = backupindex = 0;
-       }
-       if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
-          if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) {
-              temp = LCDRefreshIndex[SiS_GetBIOSLCDResInfo(SiS_Pr)];
-              if(index > temp) index = temp;
-          }
-       }
-     } else {
-        if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) index = 0;
-       if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
-           if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) index = 0;
-        }
-     }
-  }
+   if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
+      if(SiS_Pr->SiS_VBType & VB_SISVB) {
+        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+           if(SiS_Pr->SiS_VBType & VB_NoLCD)            index = 0;
+           else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index = backupindex = 0;
+        }
+        if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+           if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) {
+              temp = LCDRefreshIndex[SiS_GetBIOSLCDResInfo(SiS_Pr)];
+              if(index > temp) index = temp;
+           }
+        }
+      } else {
+        if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) index = 0;
+        if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+           if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) index = 0;
+        }
+      }
+   }
 
-  RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
-  ModeNo = SiS_Pr->SiS_RefIndex[RRTI].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) RRTI++;
-        }
-     }
-  }
+   if(SiS_Pr->ChipType >= 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) RRTI++;
+        }
+      }
+   }
 
-  i = 0;
-  do {
-     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--;
-  } while(index != 0xFFFF);
-
-  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
-     if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-       temp = SiS_Pr->SiS_RefIndex[RRTI + i - 1].Ext_InfoFlag;
-       if(temp & InterlaceMode) i++;
-     }
-  }
+   i = 0;
+   do {
+      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--;
+   } while(index != 0xFFFF);
+
+   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
+      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+        temp = SiS_Pr->SiS_RefIndex[RRTI + i - 1].Ext_InfoFlag;
+        if(temp & InterlaceMode) i++;
+      }
+   }
 
-  i--;
+   i--;
 
-  if((SiS_Pr->SiS_SetFlag & ProgrammingCRT2) && (!(SiS_Pr->SiS_VBInfo & DisableCRT2Display))) {
-     backup_i = i;
-     if(!(SiS_AdjustCRT2Rate(SiS_Pr, ModeNo, ModeIdIndex, RRTI, &i, HwInfo))) {
-       i = backup_i;
-     }
-  }
+   if((SiS_Pr->SiS_SetFlag & ProgrammingCRT2) && (!(SiS_Pr->SiS_VBInfo & DisableCRT2Display))) {
+      backup_i = i;
+      if(!(SiS_AdjustCRT2Rate(SiS_Pr, ModeNo, ModeIdIndex, RRTI, &i))) {
+        i = backup_i;
+      }
+   }
 
-  return(RRTI + i);
+   return (RRTI + i);
 }
 
 /*********************************************/
@@ -378,15 +389,15 @@ SiS_GetRatePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 /*********************************************/
 
 static void
-SiS_SaveCRT2Info(SiS_Private *SiS_Pr, USHORT ModeNo)
+SiS_SaveCRT2Info(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
 {
-  USHORT temp1,temp2;
+   unsigned short temp1, temp2;
 
-  /* Store CRT1 ModeNo in CR34 */
-  SiS_SetReg(SiS_Pr->SiS_P3d4,0x34,ModeNo);
-  temp1 = (SiS_Pr->SiS_VBInfo & SetInSlaveMode) >> 8;
-  temp2 = ~(SetInSlaveMode >> 8);
-  SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x31,temp2,temp1);
+   /* Store CRT1 ModeNo in CR34 */
+   SiS_SetReg(SiS_Pr->SiS_P3d4,0x34,ModeNo);
+   temp1 = (SiS_Pr->SiS_VBInfo & SetInSlaveMode) >> 8;
+   temp2 = ~(SetInSlaveMode >> 8);
+   SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x31,temp2,temp1);
 }
 
 /*********************************************/
@@ -395,35 +406,35 @@ SiS_SaveCRT2Info(SiS_Private *SiS_Pr, USHORT ModeNo)
 
 #ifdef SIS300
 static BOOLEAN
-SiS_CR36BIOSWord23b(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_CR36BIOSWord23b(struct SiS_Private *SiS_Pr)
 {
-  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
-  USHORT temp,temp1;
+   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
+   unsigned short temp,temp1;
 
-  if(SiS_Pr->SiS_UseROM) {
-     if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
-        temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
-        temp1 = SISGETROMW(0x23b);
-        if(temp1 & temp) return TRUE;
-     }
-  }
-  return FALSE;
+   if(SiS_Pr->SiS_UseROM) {
+      if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
+        temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
+        temp1 = SISGETROMW(0x23b);
+        if(temp1 & temp) return TRUE;
+      }
+   }
+   return FALSE;
 }
 
 static BOOLEAN
-SiS_CR36BIOSWord23d(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_CR36BIOSWord23d(struct SiS_Private *SiS_Pr)
 {
-  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
-  USHORT temp,temp1;
+   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
+   unsigned short temp,temp1;
 
-  if(SiS_Pr->SiS_UseROM) {
-     if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
-        temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
-        temp1 = SISGETROMW(0x23d);
-        if(temp1 & temp) return TRUE;
-     }
-  }
-  return FALSE;
+   if(SiS_Pr->SiS_UseROM) {
+      if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
+        temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
+        temp1 = SISGETROMW(0x23d);
+        if(temp1 & temp) return TRUE;
+      }
+   }
+   return FALSE;
 }
 #endif
 
@@ -432,85 +443,76 @@ SiS_CR36BIOSWord23d(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 /*********************************************/
 
 void
-SiS_DDC2Delay(SiS_Private *SiS_Pr, USHORT delaytime)
+SiS_DDC2Delay(struct SiS_Private *SiS_Pr, unsigned int delaytime)
 {
-  USHORT i, j;
+   unsigned int i, j;
 
-  for(i=0; i<delaytime; i++) {
-     j += SiS_GetReg(SiS_Pr->SiS_P3c4,0x05);
-  }
+   for(i = 0; i < delaytime; i++) {
+      j += SiS_GetReg(SiS_Pr->SiS_P3c4,0x05);
+   }
 }
 
 #if defined(SIS300) || defined(SIS315H)
 static void
-SiS_GenericDelay(SiS_Private *SiS_Pr, USHORT delay)
+SiS_GenericDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
 {
-  USHORT temp,flag;
-
-  flag = SiS_GetRegByte(0x61) & 0x10;
-
-  while(delay) {
-     temp = SiS_GetRegByte(0x61) & 0x10;
-     if(temp == flag) continue;
-     flag = temp;
-     delay--;
-  }
+   SiS_DDC2Delay(SiS_Pr, delay * 36);
 }
 #endif
 
 #ifdef SIS315H
 static void
-SiS_LongDelay(SiS_Private *SiS_Pr, USHORT delay)
+SiS_LongDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
 {
-  while(delay--) {
-     SiS_GenericDelay(SiS_Pr,0x19df);
-  }
+   while(delay--) {
+      SiS_GenericDelay(SiS_Pr, 6623);
+   }
 }
 #endif
 
 #if defined(SIS300) || defined(SIS315H)
 static void
-SiS_ShortDelay(SiS_Private *SiS_Pr, USHORT delay)
+SiS_ShortDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
 {
-  while(delay--) {
-     SiS_GenericDelay(SiS_Pr,0x42);
-  }
+   while(delay--) {
+      SiS_GenericDelay(SiS_Pr, 66);
+   }
 }
 #endif
 
 static void
-SiS_PanelDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT DelayTime)
+SiS_PanelDelay(struct SiS_Private *SiS_Pr, unsigned short DelayTime)
 {
 #if defined(SIS300) || defined(SIS315H)
-  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
-  USHORT PanelID, DelayIndex, Delay=0;
+   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
+   unsigned short PanelID, DelayIndex, Delay=0;
 #endif
 
-  if(HwInfo->jChipType < SIS_315H) {
+   if(SiS_Pr->ChipType < SIS_315H) {
 
 #ifdef SIS300
 
       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;
+        if(SiS_Pr->SiS_VBType & VB_SIS301) PanelID &= 0xf7;
+        if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x10)) PanelID = 0x12;
       }
       DelayIndex = PanelID >> 4;
       if((DelayTime >= 2) && ((PanelID & 0x0f) == 1))  {
-         Delay = 3;
+        Delay = 3;
       } else {
-         if(DelayTime >= 2) DelayTime -= 2;
-         if(!(DelayTime & 0x01)) {
-                   Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
-         } else {
-                   Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
-         }
+        if(DelayTime >= 2) DelayTime -= 2;
+        if(!(DelayTime & 0x01)) {
+           Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
+        } else {
+           Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
+        }
         if(SiS_Pr->SiS_UseROM) {
-            if(ROMAddr[0x220] & 0x40) {
-               if(!(DelayTime & 0x01)) Delay = (USHORT)ROMAddr[0x225];
-               else                   Delay = (USHORT)ROMAddr[0x226];
-            }
-         }
+           if(ROMAddr[0x220] & 0x40) {
+              if(!(DelayTime & 0x01)) Delay = (unsigned short)ROMAddr[0x225];
+              else                    Delay = (unsigned short)ROMAddr[0x226];
+           }
+        }
       }
       SiS_ShortDelay(SiS_Pr, Delay);
 
@@ -520,23 +522,23 @@ SiS_PanelDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT DelayTime)
 
 #ifdef SIS315H
 
-      if((HwInfo->jChipType >= SIS_661)    ||
-         (HwInfo->jChipType <= SIS_315PRO) ||
-        (HwInfo->jChipType == SIS_330)    ||
+      if((SiS_Pr->ChipType >= SIS_661)    ||
+        (SiS_Pr->ChipType <= SIS_315PRO) ||
+        (SiS_Pr->ChipType == SIS_330)    ||
         (SiS_Pr->SiS_ROMNew)) {
 
-         if(!(DelayTime & 0x01)) {
+        if(!(DelayTime & 0x01)) {
            SiS_DDC2Delay(SiS_Pr, 0x1000);
-         } else {
+        } else {
            SiS_DDC2Delay(SiS_Pr, 0x4000);
-         }
+        }
 
       } else if((SiS_Pr->SiS_IF_DEF_LVDS == 1) /* ||
-         (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
+        (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
         (SiS_Pr->SiS_CustomT == CUT_CLEVO1400) */ ) {                  /* 315 series, LVDS; Special */
 
-         if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
-            PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
+        if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
+           PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
            if(SiS_Pr->SiS_CustomT == CUT_CLEVO1400) {
               if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1b) & 0x10)) PanelID = 0x12;
            }
@@ -546,35 +548,35 @@ SiS_PanelDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT DelayTime)
               DelayIndex = PanelID >> 4;
            }
            if((DelayTime >= 2) && ((PanelID & 0x0f) == 1))  {
-               Delay = 3;
-            } else {
-               if(DelayTime >= 2) DelayTime -= 2;
-               if(!(DelayTime & 0x01)) {
-                         Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[0];
-               } else {
-                         Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[1];
-               }
+              Delay = 3;
+           } else {
+              if(DelayTime >= 2) DelayTime -= 2;
+              if(!(DelayTime & 0x01)) {
+                 Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[0];
+               } else {
+                 Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[1];
+              }
               if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
-                  if(ROMAddr[0x13c] & 0x40) {
-                     if(!(DelayTime & 0x01)) {
-                       Delay = (USHORT)ROMAddr[0x17e];
-                     } else {
-                       Delay = (USHORT)ROMAddr[0x17f];
-                     }
-                  }
-               }
-            }
+                 if(ROMAddr[0x13c] & 0x40) {
+                    if(!(DelayTime & 0x01)) {
+                       Delay = (unsigned short)ROMAddr[0x17e];
+                    } else {
+                       Delay = (unsigned short)ROMAddr[0x17f];
+                    }
+                 }
+              }
+           }
            SiS_ShortDelay(SiS_Pr, Delay);
         }
 
       } else if(SiS_Pr->SiS_VBType & VB_SISVB) {                       /* 315 series, all bridges */
 
         DelayIndex = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
-         if(!(DelayTime & 0x01)) {
-                   Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
-         } else {
-                   Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
-         }
+        if(!(DelayTime & 0x01)) {
+           Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
+        } else {
+           Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
+        }
         Delay <<= 8;
         SiS_DDC2Delay(SiS_Pr, Delay);
 
@@ -587,12 +589,11 @@ SiS_PanelDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT DelayTime)
 
 #ifdef SIS315H
 static void
-SiS_PanelDelayLoop(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
-                      USHORT DelayTime, USHORT DelayLoop)
+SiS_PanelDelayLoop(struct SiS_Private *SiS_Pr, unsigned short DelayTime, unsigned short DelayLoop)
 {
    int i;
-   for(i=0; i<DelayLoop; i++) {
-      SiS_PanelDelay(SiS_Pr, HwInfo, DelayTime);
+   for(i = 0; i < DelayLoop; i++) {
+      SiS_PanelDelay(SiS_Pr, DelayTime);
    }
 }
 #endif
@@ -602,86 +603,86 @@ SiS_PanelDelayLoop(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
 /*********************************************/
 
 void
-SiS_WaitRetrace1(SiS_Private *SiS_Pr)
+SiS_WaitRetrace1(struct SiS_Private *SiS_Pr)
 {
-  USHORT watchdog;
+   unsigned short watchdog;
 
-  if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
-  if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80)) return;
+   if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
+   if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80)) return;
 
-  watchdog = 65535;
-  while((SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
-  watchdog = 65535;
-  while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
+   watchdog = 65535;
+   while((SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
+   watchdog = 65535;
+   while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
 }
 
 #if defined(SIS300) || defined(SIS315H)
 static void
-SiS_WaitRetrace2(SiS_Private *SiS_Pr, USHORT reg)
+SiS_WaitRetrace2(struct SiS_Private *SiS_Pr, unsigned short reg)
 {
-  USHORT watchdog;
+   unsigned short watchdog;
 
-  watchdog = 65535;
-  while((SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02) && --watchdog);
-  watchdog = 65535;
-  while((!(SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02)) && --watchdog);
+   watchdog = 65535;
+   while((SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02) && --watchdog);
+   watchdog = 65535;
+   while((!(SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02)) && --watchdog);
 }
 #endif
 
 static void
-SiS_WaitVBRetrace(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_WaitVBRetrace(struct SiS_Private *SiS_Pr)
 {
-  if(HwInfo->jChipType < SIS_315H) {
+   if(SiS_Pr->ChipType < SIS_315H) {
 #ifdef SIS300
-     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-        if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return;
-     }
-     if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x80)) {
-        SiS_WaitRetrace1(SiS_Pr);
-     } else {
-        SiS_WaitRetrace2(SiS_Pr, 0x25);
-     }
+      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
+        if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return;
+      }
+      if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x80)) {
+        SiS_WaitRetrace1(SiS_Pr);
+      } else {
+        SiS_WaitRetrace2(SiS_Pr, 0x25);
+      }
 #endif
-  } else {
+   } else {
 #ifdef SIS315H
-     if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) {
-        SiS_WaitRetrace1(SiS_Pr);
-     } else {
-        SiS_WaitRetrace2(SiS_Pr, 0x30);
-     }
+      if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) {
+        SiS_WaitRetrace1(SiS_Pr);
+      } else {
+        SiS_WaitRetrace2(SiS_Pr, 0x30);
+      }
 #endif
-  }
+   }
 }
 
 static void
-SiS_VBWait(SiS_Private *SiS_Pr)
+SiS_VBWait(struct SiS_Private *SiS_Pr)
 {
-  USHORT tempal,temp,i,j;
+   unsigned short tempal,temp,i,j;
 
-  temp = 0;
-  for(i=0; i<3; i++) {
-    for(j=0; j<100; j++) {
-       tempal = SiS_GetRegByte(SiS_Pr->SiS_P3da);
-       if(temp & 0x01) {
-          if((tempal & 0x08))  continue;
-          else break;
-       } else {
-          if(!(tempal & 0x08)) continue;
-          else break;
-       }
-    }
-    temp ^= 0x01;
-  }
+   temp = 0;
+   for(i = 0; i < 3; i++) {
+     for(j = 0; j < 100; j++) {
+        tempal = SiS_GetRegByte(SiS_Pr->SiS_P3da);
+        if(temp & 0x01) {
+          if((tempal & 0x08))  continue;
+          else break;
+        } else {
+          if(!(tempal & 0x08)) continue;
+          else break;
+        }
+     }
+     temp ^= 0x01;
+   }
 }
 
 static void
-SiS_VBLongWait(SiS_Private *SiS_Pr)
+SiS_VBLongWait(struct SiS_Private *SiS_Pr)
 {
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-     SiS_VBWait(SiS_Pr);
-  } else {
-     SiS_WaitRetrace1(SiS_Pr);
-  }
+   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+      SiS_VBWait(SiS_Pr);
+   } else {
+      SiS_WaitRetrace1(SiS_Pr);
+   }
 }
 
 /*********************************************/
@@ -690,237 +691,225 @@ SiS_VBLongWait(SiS_Private *SiS_Pr)
 
 #ifdef SIS300
 static BOOLEAN
-SiS_Is301B(SiS_Private *SiS_Pr)
+SiS_Is301B(struct SiS_Private *SiS_Pr)
 {
-  if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01) >= 0xb0) return TRUE;
-  return FALSE;
+   if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01) >= 0xb0) return TRUE;
+   return FALSE;
 }
 #endif
 
 static BOOLEAN
-SiS_CRT2IsLCD(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_CRT2IsLCD(struct SiS_Private *SiS_Pr)
 {
-  USHORT flag;
-
-  if(HwInfo->jChipType == SIS_730) {
-     flag = SiS_GetReg(SiS_Pr->SiS_P3c4,0x13);
-     if(flag & 0x20) return TRUE;
-  }
-  flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
-  if(flag & 0x20) return TRUE;
-  return FALSE;
+   if(SiS_Pr->ChipType == SIS_730) {
+      if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x20) return TRUE;
+   }
+   if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & 0x20) return TRUE;
+   return FALSE;
 }
 
 BOOLEAN
-SiS_IsDualEdge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_IsDualEdge(struct SiS_Private *SiS_Pr)
 {
 #ifdef SIS315H
-  USHORT flag;
-
-  if(HwInfo->jChipType >= SIS_315H) {
-     if((HwInfo->jChipType != SIS_650) || (SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) {
-        flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
-        if(flag & EnableDualEdge) return TRUE;
-     }
-  }
+   if(SiS_Pr->ChipType >= SIS_315H) {
+      if((SiS_Pr->ChipType != SIS_650) || (SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) {
+        if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableDualEdge) return TRUE;
+      }
+   }
 #endif
-  return FALSE;
+   return FALSE;
 }
 
 BOOLEAN
-SiS_IsVAMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_IsVAMode(struct SiS_Private *SiS_Pr)
 {
 #ifdef SIS315H
-  USHORT flag;
+   unsigned short flag;
 
-  if(HwInfo->jChipType >= SIS_315H) {
-     flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
-     if((flag & EnableDualEdge) && (flag & SetToLCDA)) return TRUE;
-  }
+   if(SiS_Pr->ChipType >= SIS_315H) {
+      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
+      if((flag & EnableDualEdge) && (flag & SetToLCDA)) return TRUE;
+   }
 #endif
-  return FALSE;
+   return FALSE;
 }
 
 #ifdef SIS315H
 static BOOLEAN
-SiS_IsVAorLCD(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_IsVAorLCD(struct SiS_Private *SiS_Pr)
 {
-  if(SiS_IsVAMode(SiS_Pr,HwInfo))   return TRUE;
-  if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) return TRUE;
-  return FALSE;
+   if(SiS_IsVAMode(SiS_Pr))  return TRUE;
+   if(SiS_CRT2IsLCD(SiS_Pr)) return TRUE;
+   return FALSE;
 }
 #endif
 
 static BOOLEAN
-SiS_IsDualLink(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_IsDualLink(struct SiS_Private *SiS_Pr)
 {
 #ifdef SIS315H
-  if(HwInfo->jChipType >= SIS_315H) {
-     if((SiS_CRT2IsLCD(SiS_Pr, HwInfo)) ||
-        (SiS_IsVAMode(SiS_Pr, HwInfo))) {
-        if(SiS_Pr->SiS_LCDInfo & LCDDualLink) return TRUE;
-     }
-  }
+   if(SiS_Pr->ChipType >= SIS_315H) {
+      if((SiS_CRT2IsLCD(SiS_Pr)) ||
+         (SiS_IsVAMode(SiS_Pr))) {
+        if(SiS_Pr->SiS_LCDInfo & LCDDualLink) return TRUE;
+      }
+   }
 #endif
-  return FALSE;
+   return FALSE;
 }
 
 #ifdef SIS315H
 static BOOLEAN
-SiS_TVEnabled(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_TVEnabled(struct SiS_Private *SiS_Pr)
 {
-  if((SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) != 0x0c) return TRUE;
-  if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS301LV302LV)) {
-     if(SiS_GetReg(SiS_Pr->SiS_Part2Port,0x4d) & 0x10) return TRUE;
-  }
-  return FALSE;
+   if((SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) != 0x0c) return TRUE;
+   if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
+      if(SiS_GetReg(SiS_Pr->SiS_Part2Port,0x4d) & 0x10) return TRUE;
+   }
+   return FALSE;
 }
 #endif
 
 #ifdef SIS315H
 static BOOLEAN
-SiS_LCDAEnabled(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_LCDAEnabled(struct SiS_Private *SiS_Pr)
 {
-  if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) return TRUE;
-  return FALSE;
+   if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) return TRUE;
+   return FALSE;
 }
 #endif
 
 #ifdef SIS315H
 static BOOLEAN
-SiS_WeHaveBacklightCtrl(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_WeHaveBacklightCtrl(struct SiS_Private *SiS_Pr)
 {
-  if((HwInfo->jChipType >= SIS_315H) && (HwInfo->jChipType < SIS_661)) {
-     if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0x10) return TRUE;
-  }
-  return FALSE;
+   if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
+      if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0x10) return TRUE;
+   }
+   return FALSE;
 }
 #endif
 
 #ifdef SIS315H
 static BOOLEAN
-SiS_IsNotM650orLater(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_IsNotM650orLater(struct SiS_Private *SiS_Pr)
 {
-  USHORT flag;
+   unsigned short flag;
 
-  if(HwInfo->jChipType == SIS_650) {
-     flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f);
-     flag &= 0xF0;
-     /* Check for revision != A0 only */
-     if((flag == 0xe0) || (flag == 0xc0) ||
-        (flag == 0xb0) || (flag == 0x90)) return FALSE;
-  } else if(HwInfo->jChipType >= SIS_661) return FALSE;
-  return TRUE;
+   if(SiS_Pr->ChipType == SIS_650) {
+      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0;
+      /* Check for revision != A0 only */
+      if((flag == 0xe0) || (flag == 0xc0) ||
+         (flag == 0xb0) || (flag == 0x90)) return FALSE;
+   } else if(SiS_Pr->ChipType >= SIS_661) return FALSE;
+   return TRUE;
 }
 #endif
 
 #ifdef SIS315H
 static BOOLEAN
-SiS_IsYPbPr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_IsYPbPr(struct SiS_Private *SiS_Pr)
 {
-  USHORT flag;
-
-  if(HwInfo->jChipType >= SIS_315H) {
-     flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
-     if(flag & EnableCHYPbPr) return TRUE;  /* = YPrPb = 0x08 */
-  }
-  return FALSE;
+   if(SiS_Pr->ChipType >= SIS_315H) {
+      /* YPrPb = 0x08 */
+      if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHYPbPr) return TRUE;
+   }
+   return FALSE;
 }
 #endif
 
 #ifdef SIS315H
 static BOOLEAN
-SiS_IsChScart(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_IsChScart(struct SiS_Private *SiS_Pr)
 {
-  USHORT flag;
-
-  if(HwInfo->jChipType >= SIS_315H) {
-     flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
-     if(flag & EnableCHScart) return TRUE;  /* = Scart = 0x04 */
-  }
-  return FALSE;
+   if(SiS_Pr->ChipType >= SIS_315H) {
+      /* Scart = 0x04 */
+      if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHScart) return TRUE;
+   }
+   return FALSE;
 }
 #endif
 
 #ifdef SIS315H
 static BOOLEAN
-SiS_IsTVOrYPbPrOrScart(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_IsTVOrYPbPrOrScart(struct SiS_Private *SiS_Pr)
 {
-  USHORT flag;
+   unsigned short flag;
 
-  if(HwInfo->jChipType >= SIS_315H) {
-     flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
-     if(flag & SetCRT2ToTV)        return TRUE;
-     flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
-     if(flag & EnableCHYPbPr)      return TRUE;  /* = YPrPb = 0x08 */
-     if(flag & EnableCHScart)      return TRUE;  /* = Scart = 0x04 - TW */
-  } else {
-     flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
-     if(flag & SetCRT2ToTV)        return TRUE;
-  }
-  return FALSE;
+   if(SiS_Pr->ChipType >= SIS_315H) {
+      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
+      if(flag & SetCRT2ToTV)        return TRUE;
+      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
+      if(flag & EnableCHYPbPr)      return TRUE;  /* = YPrPb = 0x08 */
+      if(flag & EnableCHScart)      return TRUE;  /* = Scart = 0x04 - TW */
+   } else {
+      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
+      if(flag & SetCRT2ToTV)        return TRUE;
+   }
+   return FALSE;
 }
 #endif
 
 #ifdef SIS315H
 static BOOLEAN
-SiS_IsLCDOrLCDA(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_IsLCDOrLCDA(struct SiS_Private *SiS_Pr)
 {
-  USHORT flag;
+   unsigned short flag;
 
-  if(HwInfo->jChipType >= SIS_315H) {
-     flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
-     if(flag & SetCRT2ToLCD) return TRUE;
-     flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
-     if(flag & SetToLCDA)    return TRUE;
-  } else {
-     flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
-     if(flag & SetCRT2ToLCD) return TRUE;
-  }
-  return FALSE;
+   if(SiS_Pr->ChipType >= SIS_315H) {
+      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
+      if(flag & SetCRT2ToLCD) return TRUE;
+      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
+      if(flag & SetToLCDA)    return TRUE;
+   } else {
+      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
+      if(flag & SetCRT2ToLCD) return TRUE;
+   }
+   return FALSE;
 }
 #endif
 
 static BOOLEAN
-SiS_BridgeIsOn(SiS_Private *SiS_Pr)
+SiS_HaveBridge(struct SiS_Private *SiS_Pr)
 {
-  USHORT flag;
+   unsigned short flag;
 
-  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-     return TRUE;
-  } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
-     flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
-     if((flag == 1) || (flag == 2)) return TRUE;
-  }
-  return FALSE;
+   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+      return TRUE;
+   } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
+      flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
+      if((flag == 1) || (flag == 2)) return TRUE;
+   }
+   return FALSE;
 }
 
 static BOOLEAN
-SiS_BridgeIsEnabled(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_BridgeIsEnabled(struct SiS_Private *SiS_Pr)
 {
-  USHORT flag;
+   unsigned short flag;
 
-  if(SiS_BridgeIsOn(SiS_Pr)) {
-     flag = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
-     if(HwInfo->jChipType < SIS_315H) {
-       flag &= 0xa0;
-       if((flag == 0x80) || (flag == 0x20)) return TRUE;
-     } else {
-       flag &= 0x50;
-       if((flag == 0x40) || (flag == 0x10)) return TRUE;
-     }
-  }
-  return FALSE;
+   if(SiS_HaveBridge(SiS_Pr)) {
+      flag = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
+      if(SiS_Pr->ChipType < SIS_315H) {
+       flag &= 0xa0;
+       if((flag == 0x80) || (flag == 0x20)) return TRUE;
+      } else {
+       flag &= 0x50;
+       if((flag == 0x40) || (flag == 0x10)) return TRUE;
+      }
+   }
+   return FALSE;
 }
 
 static BOOLEAN
-SiS_BridgeInSlavemode(SiS_Private *SiS_Pr)
+SiS_BridgeInSlavemode(struct SiS_Private *SiS_Pr)
 {
-  USHORT flag1;
+   unsigned short flag1;
 
-  flag1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
-  if(flag1 & (SetInSlaveMode >> 8)) return TRUE;
-  return FALSE;
+   flag1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
+   if(flag1 & (SetInSlaveMode >> 8)) return TRUE;
+   return FALSE;
 }
 
 /*********************************************/
@@ -928,119 +917,97 @@ SiS_BridgeInSlavemode(SiS_Private *SiS_Pr)
 /*********************************************/
 
 /* Setup general purpose IO for Chrontel communication */
+#ifdef SIS300
 void
-SiS_SetChrontelGPIO(SiS_Private *SiS_Pr, USHORT myvbinfo)
+SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo)
 {
-   unsigned long  acpibase;
+   unsigned int   acpibase;
    unsigned short temp;
 
    if(!(SiS_Pr->SiS_ChSW)) return;
 
-#ifdef LINUX_KERNEL
-   SiS_SetRegLong(0xcf8,0x80000874);                  /* get ACPI base */
-   acpibase = SiS_GetRegLong(0xcfc);
+#ifdef SIS_LINUX_KERNEL
+   acpibase = sisfb_read_lpc_pci_dword(SiS_Pr, 0x74);
 #else
    acpibase = pciReadLong(0x00000800, 0x74);
 #endif
    acpibase &= 0xFFFF;
-   temp = SiS_GetRegShort((USHORT)(acpibase + 0x3c));  /* ACPI register 0x3c: GP Event 1 I/O mode select */
+   if(!acpibase) return;
+   temp = SiS_GetRegShort((acpibase + 0x3c));  /* ACPI register 0x3c: GP Event 1 I/O mode select */
    temp &= 0xFEFF;
-   SiS_SetRegShort((USHORT)(acpibase + 0x3c), temp);
-   temp = SiS_GetRegShort((USHORT)(acpibase + 0x3c));
-   temp = SiS_GetRegShort((USHORT)(acpibase + 0x3a));  /* ACPI register 0x3a: GP Pin Level (low/high) */
+   SiS_SetRegShort((acpibase + 0x3c), temp);
+   temp = SiS_GetRegShort((acpibase + 0x3c));
+   temp = SiS_GetRegShort((acpibase + 0x3a));  /* ACPI register 0x3a: GP Pin Level (low/high) */
    temp &= 0xFEFF;
    if(!(myvbinfo & SetCRT2ToTV)) temp |= 0x0100;
-   SiS_SetRegShort((USHORT)(acpibase + 0x3a), temp);
-   temp = SiS_GetRegShort((USHORT)(acpibase + 0x3a));
+   SiS_SetRegShort((acpibase + 0x3a), temp);
+   temp = SiS_GetRegShort((acpibase + 0x3a));
 }
+#endif
 
 void
-SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
-              PSIS_HW_INFO HwInfo, int checkcrt2mode)
+SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+               unsigned short ModeIdIndex, int checkcrt2mode)
 {
-  USHORT tempax,tempbx,temp;
-  USHORT modeflag, resinfo=0;
+   unsigned short tempax, tempbx, temp;
+   unsigned short modeflag, resinfo = 0;
 
-  if(ModeNo <= 0x13) {
-     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-  } else if(SiS_Pr->UseCustomMode) {
-     modeflag = SiS_Pr->CModeFlag;
-  } else {
-     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-     resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-  }
+   SiS_Pr->SiS_SetFlag = 0;
 
-  SiS_Pr->SiS_SetFlag = 0;
+   modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
 
-  SiS_Pr->SiS_ModeType = modeflag & ModeTypeMask;
+   SiS_Pr->SiS_ModeType = modeflag & ModeTypeMask;
 
-  tempbx = 0;
-  if(SiS_BridgeIsOn(SiS_Pr)) {
-       temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
-#if 0
-       if(HwInfo->jChipType < SIS_661) {
-          /* NO - YPbPr not set yet ! */
-          if(SiS_Pr->SiS_YPbPr & <all ypbpr except 525i>) {
-             temp &= (SetCRT2ToHiVision | SwitchCRT2 | SetSimuScanMode);       /* 0x83 */
-             temp |= SetCRT2ToHiVision;                                        /* 0x80 */
-          }
-          if(SiS_Pr->SiS_YPbPr & <ypbpr525i>) {
-             temp &= (SetCRT2ToHiVision | SwitchCRT2 | SetSimuScanMode);       /* 0x83 */
-             temp |= SetCRT2ToSVIDEO;                                          /* 0x08 */
-          }
-       }
-#endif
-       tempbx |= temp;
-       tempax = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) << 8;
-        tempax &= (DriverMode | LoadDACFlag | SetNotSimuMode | SetPALTV);
-       tempbx |= tempax;
+   if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
+      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+   }
+
+   tempbx = 0;
+
+   if(SiS_HaveBridge(SiS_Pr)) {
+
+       temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
+       tempbx |= temp;
+       tempax = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) << 8;
+       tempax &= (DriverMode | LoadDACFlag | SetNotSimuMode | SetPALTV);
+       tempbx |= tempax;
 
 #ifdef SIS315H
-       if(HwInfo->jChipType >= SIS_315H) {
-          if(SiS_Pr->SiS_VBType & VB_SISLCDA) {
+       if(SiS_Pr->ChipType >= SIS_315H) {
+          if(SiS_Pr->SiS_VBType & VB_SISLCDA) {
              if(ModeNo == 0x03) {
-                /* Mode 0x03 is never in driver mode */
+                /* Mode 0x03 is never in driver mode */
                 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf);
              }
              if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8))) {
-                /* Reset LCDA setting if not driver mode */
+                /* Reset LCDA setting if not driver mode */
                 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
              }
              if(IS_SIS650) {
-                if(SiS_Pr->SiS_UseLCDA) {
+                if(SiS_Pr->SiS_UseLCDA) {
                    if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) {
                       if((ModeNo <= 0x13) || (!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) {
-                         SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA));
+                         SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA));
                       }
                    }
                 }
              }
              temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
-                     if((temp & (EnableDualEdge | SetToLCDA)) == (EnableDualEdge | SetToLCDA)) {
-                tempbx |= SetCRT2ToLCDA;
+             if((temp & (EnableDualEdge | SetToLCDA)) == (EnableDualEdge | SetToLCDA)) {
+                tempbx |= SetCRT2ToLCDA;
              }
           }
 
-          if(SiS_Pr->SiS_VBType & (VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)) {
-             tempbx &= ~(SetCRT2ToRAMDAC);
-          }
-
-          if(HwInfo->jChipType >= SIS_661) {
+          if(SiS_Pr->ChipType >= SIS_661) { /* New CR layout */
              tempbx &= ~(SetCRT2ToYPbPr525750 | SetCRT2ToHiVision);
-             temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
-             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_SISHIVISION) {
-                if(temp & 0x04) {
-                   temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
-                   if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
+             if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & 0x04) {
+                temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
+                if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
+                else if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
+                   tempbx |= SetCRT2ToYPbPr525750;
                 }
              }
-          }
+          }
 
           if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
              temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
@@ -1048,7 +1015,7 @@ SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
                 tempbx |= SetCRT2ToLCDA;
              }
              if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
-                if(temp & EnableCHYPbPr) {
+                if(temp & EnableCHYPbPr) {
                    tempbx |= SetCRT2ToCHYPbPr;
                 }
              }
@@ -1057,44 +1024,49 @@ SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 
 #endif  /* SIS315H */
 
-       if(SiS_Pr->SiS_VBType & VB_SISVB) {
+        if(!(SiS_Pr->SiS_VBType & VB_SISVGA2)) {
+          tempbx &= ~(SetCRT2ToRAMDAC);
+       }
+
+       if(SiS_Pr->SiS_VBType & VB_SISVB) {
           temp = SetCRT2ToSVIDEO   |
-                 SetCRT2ToAVIDEO   |
-                 SetCRT2ToSCART    |
-                 SetCRT2ToLCDA     |
-                 SetCRT2ToLCD      |
-                 SetCRT2ToRAMDAC   |
-                  SetCRT2ToHiVision |
+                 SetCRT2ToAVIDEO   |
+                 SetCRT2ToSCART    |
+                 SetCRT2ToLCDA     |
+                 SetCRT2ToLCD      |
+                 SetCRT2ToRAMDAC   |
+                 SetCRT2ToHiVision |
                  SetCRT2ToYPbPr525750;
-       } else {
-           if(HwInfo->jChipType >= SIS_315H) {
-              if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
-                temp = SetCRT2ToAVIDEO |
+       } else {
+          if(SiS_Pr->ChipType >= SIS_315H) {
+             if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+                temp = SetCRT2ToAVIDEO |
                        SetCRT2ToSVIDEO |
                        SetCRT2ToSCART  |
                        SetCRT2ToLCDA   |
                        SetCRT2ToLCD    |
                        SetCRT2ToCHYPbPr;
-             } else {
-                temp = SetCRT2ToLCDA   |
+             } else {
+                temp = SetCRT2ToLCDA   |
                        SetCRT2ToLCD;
              }
           } else {
-             if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
-                temp = SetCRT2ToTV | SetCRT2ToLCD;
-              } else {
-                temp = SetCRT2ToLCD;
+             if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+                temp = SetCRT2ToTV | SetCRT2ToLCD;
+             } else {
+                temp = SetCRT2ToLCD;
              }
           }
-       }
+       }
+
+       if(!(tempbx & temp)) {
+          tempax = DisableCRT2Display;
+          tempbx = 0;
+       }
 
-       if(!(tempbx & temp)) {
-          tempax = DisableCRT2Display;
-          tempbx = 0;
-       }
+       if(SiS_Pr->SiS_VBType & VB_SISVB) {
 
-       if(SiS_Pr->SiS_VBType & VB_SISVB) {
-          USHORT clearmask = ( DriverMode         |
+          unsigned short clearmask = ( DriverMode |
                                DisableCRT2Display |
                                LoadDACFlag        |
                                SetNotSimuMode     |
@@ -1102,106 +1074,104 @@ SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
                                SetPALTV           |
                                SwitchCRT2         |
                                SetSimuScanMode );
-          if(tempbx & SetCRT2ToLCDA)        tempbx &= (clearmask | SetCRT2ToLCDA);
+
+          if(tempbx & SetCRT2ToLCDA)        tempbx &= (clearmask | SetCRT2ToLCDA);
           if(tempbx & SetCRT2ToRAMDAC)      tempbx &= (clearmask | SetCRT2ToRAMDAC);
           if(tempbx & SetCRT2ToLCD)         tempbx &= (clearmask | SetCRT2ToLCD);
           if(tempbx & SetCRT2ToSCART)       tempbx &= (clearmask | SetCRT2ToSCART);
           if(tempbx & SetCRT2ToHiVision)    tempbx &= (clearmask | SetCRT2ToHiVision);
           if(tempbx & SetCRT2ToYPbPr525750) tempbx &= (clearmask | SetCRT2ToYPbPr525750);
-       } else {
-          if(HwInfo->jChipType >= SIS_315H) {
+
+       } else {
+
+          if(SiS_Pr->ChipType >= SIS_315H) {
              if(tempbx & SetCRT2ToLCDA) {
-                tempbx &= (0xFF00|SwitchCRT2|SetSimuScanMode);
+                tempbx &= (0xFF00|SwitchCRT2|SetSimuScanMode);
              }
           }
-          if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
-              if(tempbx & SetCRT2ToTV) {
-                tempbx &= (0xFF00|SetCRT2ToTV|SwitchCRT2|SetSimuScanMode);
+          if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+             if(tempbx & SetCRT2ToTV) {
+                tempbx &= (0xFF00|SetCRT2ToTV|SwitchCRT2|SetSimuScanMode);
              }
-          }
-          if(tempbx & SetCRT2ToLCD) {
-              tempbx &= (0xFF00|SetCRT2ToLCD|SwitchCRT2|SetSimuScanMode);
           }
-          if(HwInfo->jChipType >= SIS_315H) {
+          if(tempbx & SetCRT2ToLCD) {
+             tempbx &= (0xFF00|SetCRT2ToLCD|SwitchCRT2|SetSimuScanMode);
+          }
+          if(SiS_Pr->ChipType >= SIS_315H) {
              if(tempbx & SetCRT2ToLCDA) {
                 tempbx |= SetCRT2ToLCD;
              }
           }
+
        }
 
-       if(tempax & DisableCRT2Display) {
-          if(!(tempbx & (SwitchCRT2 | SetSimuScanMode))) {
-              tempbx = SetSimuScanMode | DisableCRT2Display;
-          }
-       }
+       if(tempax & DisableCRT2Display) {
+          if(!(tempbx & (SwitchCRT2 | SetSimuScanMode))) {
+             tempbx = SetSimuScanMode | DisableCRT2Display;
+          }
+       }
 
-       if(!(tempbx & DriverMode)) tempbx |= SetSimuScanMode;
+       if(!(tempbx & DriverMode)) tempbx |= SetSimuScanMode;
 
        /* LVDS/CHRONTEL (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */
        if(SiS_Pr->SiS_ModeType <= ModeVGA) {
           if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
               ((SiS_Pr->SiS_VBType & VB_NoLCD) && (tempbx & SetCRT2ToLCD)) ) {
-              modeflag &= (~CRT2Mode);
+             modeflag &= (~CRT2Mode);
           }
        }
 
-       if(!(tempbx & SetSimuScanMode)) {
-          if(tempbx & SwitchCRT2) {
-              if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
-                if( (HwInfo->jChipType >= SIS_315H) &&
-                    (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) ) {
-                   if(resinfo != SIS_RI_1600x1200) {
-                       tempbx |= SetSimuScanMode;
-                   }
-                } else {
-                   tempbx |= SetSimuScanMode;
-                }
+       if(!(tempbx & SetSimuScanMode)) {
+          if(tempbx & SwitchCRT2) {
+             if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
+                if(resinfo != SIS_RI_1600x1200) {
+                   tempbx |= SetSimuScanMode;
+                }
               }
-          } else {
-              if(SiS_BridgeIsEnabled(SiS_Pr,HwInfo)) {
-                if(!(tempbx & DriverMode)) {
-                   if(SiS_BridgeInSlavemode(SiS_Pr)) {
+          } else {
+             if(SiS_BridgeIsEnabled(SiS_Pr)) {
+                if(!(tempbx & DriverMode)) {
+                   if(SiS_BridgeInSlavemode(SiS_Pr)) {
                       tempbx |= SetSimuScanMode;
-                   }
-                 }
-              }
-          }
-       }
-
-       if(!(tempbx & DisableCRT2Display)) {
-           if(tempbx & DriverMode) {
-              if(tempbx & SetSimuScanMode) {
-                if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
-                   if( (HwInfo->jChipType >= SIS_315H) &&
-                       (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) ) {
-                      if(resinfo != SIS_RI_1600x1200) {
-                         tempbx |= SetInSlaveMode;
-                      }
-                   } else {
-                      tempbx |= SetInSlaveMode;
-                    }
-                }
-              }
-           } else {
-              tempbx |= SetInSlaveMode;
-          }
-       }
+                   }
+                }
+             }
+          }
+       }
 
-  }
+       if(!(tempbx & DisableCRT2Display)) {
+          if(tempbx & DriverMode) {
+             if(tempbx & SetSimuScanMode) {
+                if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
+                   if(resinfo != SIS_RI_1600x1200) {
+                      tempbx |= SetInSlaveMode;
+                   }
+                }
+             }
+          } else {
+             tempbx |= SetInSlaveMode;
+          }
+       }
 
-  SiS_Pr->SiS_VBInfo = tempbx;
+   }
 
-  if(HwInfo->jChipType == SIS_630) {
-     SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo);
-  }
+   SiS_Pr->SiS_VBInfo = tempbx;
 
-#ifdef TWDEBUG
-#ifdef LINUX_KERNEL
-  printk(KERN_DEBUG "sisfb: (VBInfo= 0x%04x, SetFlag=0x%04x)\n",
+#ifdef SIS300
+   if(SiS_Pr->ChipType == SIS_630) {
+      SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo);
+   }
+#endif
+
+#ifdef SIS_LINUX_KERNEL
+#if 0
+   printk(KERN_DEBUG "sisfb: (init301: VBInfo= 0x%04x, SetFlag=0x%04x)\n",
       SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
 #endif
-#ifdef LINUX_XF86
-  xf86DrvMsgVerb(0, X_PROBED, 3, "(init301: VBInfo=0x%04x, SetFlag=0x%04x)\n",
+#endif
+#ifdef SIS_XORG_XF86
+#ifdef TWDEBUG
+   xf86DrvMsg(0, X_PROBED, "(init301: VBInfo=0x%04x, SetFlag=0x%04x)\n",
       SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
 #endif
 #endif
@@ -1212,41 +1182,41 @@ SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 /*********************************************/
 
 void
-SiS_SetYPbPr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_SetYPbPr(struct SiS_Private *SiS_Pr)
 {
 
-  UCHAR temp;
+   unsigned char temp;
 
-  /* Note: This variable is only used on 30xLV systems.
-   * CR38 has a different meaning on LVDS/CH7019 systems.
-   * On 661 and later, these bits moved to CR35.
-   *
-   * On 301, 301B, only HiVision 1080i is supported.
-   * On 30xLV, 301C, only YPbPr 1080i is supported.
-   */
+   /* Note: This variable is only used on 30xLV systems.
+    * CR38 has a different meaning on LVDS/CH7019 systems.
+    * On 661 and later, these bits moved to CR35.
+    *
+    * On 301, 301B, only HiVision 1080i is supported.
+    * On 30xLV, 301C, only YPbPr 1080i is supported.
+    */
 
-  SiS_Pr->SiS_YPbPr = 0;
-  if(HwInfo->jChipType >= SIS_661) return;
+   SiS_Pr->SiS_YPbPr = 0;
+   if(SiS_Pr->ChipType >= SIS_661) return;
 
-  if(SiS_Pr->SiS_VBType) {
-     if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
-       SiS_Pr->SiS_YPbPr = YPbPrHiVision;
-     }
-  }
+   if(SiS_Pr->SiS_VBType) {
+      if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
+        SiS_Pr->SiS_YPbPr = YPbPrHiVision;
+      }
+   }
 
-  if(HwInfo->jChipType >= SIS_315H) {
-     if(SiS_Pr->SiS_VBType & (VB_SIS301LV302LV | VB_SIS301C)) {
-        temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
-       if(temp & 0x08) {
-          switch((temp >> 4)) {
-          case 0x00: SiS_Pr->SiS_YPbPr = YPbPr525i;     break;
-          case 0x01: SiS_Pr->SiS_YPbPr = YPbPr525p;     break;
-          case 0x02: SiS_Pr->SiS_YPbPr = YPbPr750p;     break;
-          case 0x03: SiS_Pr->SiS_YPbPr = YPbPrHiVision; break;
-          }
-       }
-     }
-  }
+   if(SiS_Pr->ChipType >= SIS_315H) {
+      if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
+        temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
+        if(temp & 0x08) {
+           switch((temp >> 4)) {
+           case 0x00: SiS_Pr->SiS_YPbPr = YPbPr525i;     break;
+           case 0x01: SiS_Pr->SiS_YPbPr = YPbPr525p;     break;
+           case 0x02: SiS_Pr->SiS_YPbPr = YPbPr750p;     break;
+           case 0x03: SiS_Pr->SiS_YPbPr = YPbPrHiVision; break;
+           }
+        }
+      }
+   }
 
 }
 
@@ -1255,199 +1225,204 @@ 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)
+SiS_SetTVMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
 {
-  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
-  USHORT temp, temp1, resinfo = 0, romindex = 0;
-  UCHAR  OutputSelect = *SiS_Pr->pSiS_OutputSelect;
+   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
+   unsigned short temp, temp1, resinfo = 0, romindex = 0;
+   unsigned char  OutputSelect = *SiS_Pr->pSiS_OutputSelect;
 
-  SiS_Pr->SiS_TVMode = 0;
+   SiS_Pr->SiS_TVMode = 0;
 
-  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
-  if(SiS_Pr->UseCustomMode) return;
+   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
+   if(SiS_Pr->UseCustomMode) return;
 
-  if(ModeNo > 0x13) {
-     resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-  }
+   if(ModeNo > 0x13) {
+      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+   }
 
-  if(HwInfo->jChipType < SIS_661) {
+   if(SiS_Pr->ChipType < SIS_661) {
 
-     if(SiS_Pr->SiS_VBInfo & SetPALTV) SiS_Pr->SiS_TVMode |= TVSetPAL;
+      if(SiS_Pr->SiS_VBInfo & SetPALTV) SiS_Pr->SiS_TVMode |= TVSetPAL;
 
-     if(SiS_Pr->SiS_VBType & VB_SISVB) {
-        temp = 0;
-        if((HwInfo->jChipType == SIS_630) ||
-           (HwInfo->jChipType == SIS_730)) {
-           temp = 0x35;
-          romindex = 0xfe;
-        } else if(HwInfo->jChipType >= SIS_315H) {
-           temp = 0x38;
-          romindex = 0xf3;
-          if(HwInfo->jChipType >= SIS_330) romindex = 0x11b;
-        }
-        if(temp) {
-           if(romindex && SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
-             OutputSelect = ROMAddr[romindex];
-             if(!(OutputSelect & EnablePALMN)) {
-                 SiS_SetRegAND(SiS_Pr->SiS_P3d4,temp,0x3F);
-             }
-          }
-          temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,temp);
-          if(SiS_Pr->SiS_TVMode & TVSetPAL) {
-              if(temp1 & EnablePALM) {         /* 0x40 */
-                 SiS_Pr->SiS_TVMode |= TVSetPALM;
-                SiS_Pr->SiS_TVMode &= ~TVSetPAL;
-             } else if(temp1 & EnablePALN) {   /* 0x80 */
-                SiS_Pr->SiS_TVMode |= TVSetPALN;
-              }
-          } else {
-              if(temp1 & EnableNTSCJ) {                /* 0x40 */
-                SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
-             }
-          }
-        }
-       /* Translate HiVision/YPbPr to our new flags */
-       if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
-          if(SiS_Pr->SiS_YPbPr == YPbPr750p)          SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
-          else if(SiS_Pr->SiS_YPbPr == YPbPr525p)     SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
-          else if(SiS_Pr->SiS_YPbPr == YPbPrHiVision) SiS_Pr->SiS_TVMode |= TVSetHiVision;
-          else                                        SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
-          if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p | TVSetYPbPr525i)) {
-             SiS_Pr->SiS_VBInfo &= ~SetCRT2ToHiVision;
-             SiS_Pr->SiS_VBInfo |= SetCRT2ToYPbPr525750;
-          } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
-             SiS_Pr->SiS_TVMode |= TVSetPAL;
-          }
-       }
-     } else if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
-        if(SiS_Pr->SiS_CHOverScan) {
-           if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
-              temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
-              if((temp & TVOverScan) || (SiS_Pr->SiS_CHOverScan == 1)) {
-                SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
-              }
-           } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
-             temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79);
-             if((temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1)) {
-                SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
-             }
-          }
-           if(SiS_Pr->SiS_CHSOverScan) {
-              SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
-           }
-        }
-        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
-          temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
-          if(SiS_Pr->SiS_TVMode & TVSetPAL) {
-              if(temp & EnablePALM)      SiS_Pr->SiS_TVMode |= TVSetPALM;
-             else if(temp & EnablePALN) SiS_Pr->SiS_TVMode |= TVSetPALN;
-           } else {
-             if(temp & EnableNTSCJ) {
-                SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
-             }
-          }
-       }
-     }
+      if(SiS_Pr->SiS_VBType & VB_SISVB) {
+        temp = 0;
+        if((SiS_Pr->ChipType == SIS_630) ||
+           (SiS_Pr->ChipType == SIS_730)) {
+           temp = 0x35;
+           romindex = 0xfe;
+        } else if(SiS_Pr->ChipType >= SIS_315H) {
+           temp = 0x38;
+           if(SiS_Pr->ChipType < XGI_20) {
+              romindex = 0xf3;
+              if(SiS_Pr->ChipType >= SIS_330) romindex = 0x11b;
+           }
+        }
+        if(temp) {
+           if(romindex && SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
+              OutputSelect = ROMAddr[romindex];
+              if(!(OutputSelect & EnablePALMN)) {
+                 SiS_SetRegAND(SiS_Pr->SiS_P3d4,temp,0x3F);
+              }
+           }
+           temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,temp);
+           if(SiS_Pr->SiS_TVMode & TVSetPAL) {
+              if(temp1 & EnablePALM) {         /* 0x40 */
+                 SiS_Pr->SiS_TVMode |= TVSetPALM;
+                 SiS_Pr->SiS_TVMode &= ~TVSetPAL;
+              } else if(temp1 & EnablePALN) {  /* 0x80 */
+                 SiS_Pr->SiS_TVMode |= TVSetPALN;
+              }
+           } else {
+              if(temp1 & EnableNTSCJ) {        /* 0x40 */
+                 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
+              }
+           }
+        }
+        /* Translate HiVision/YPbPr to our new flags */
+        if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
+           if(SiS_Pr->SiS_YPbPr == YPbPr750p)          SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
+           else if(SiS_Pr->SiS_YPbPr == YPbPr525p)     SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
+           else if(SiS_Pr->SiS_YPbPr == YPbPrHiVision) SiS_Pr->SiS_TVMode |= TVSetHiVision;
+           else                                        SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
+           if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p | TVSetYPbPr525i)) {
+              SiS_Pr->SiS_VBInfo &= ~SetCRT2ToHiVision;
+              SiS_Pr->SiS_VBInfo |= SetCRT2ToYPbPr525750;
+           } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
+              SiS_Pr->SiS_TVMode |= TVSetPAL;
+           }
+        }
+      } else if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+        if(SiS_Pr->SiS_CHOverScan) {
+           if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
+              temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
+              if((temp & TVOverScan) || (SiS_Pr->SiS_CHOverScan == 1)) {
+                 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
+              }
+           } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+              temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79);
+              if((temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1)) {
+                 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
+              }
+           }
+           if(SiS_Pr->SiS_CHSOverScan) {
+              SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
+           }
+        }
+        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+           temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
+           if(SiS_Pr->SiS_TVMode & TVSetPAL) {
+              if(temp & EnablePALM)      SiS_Pr->SiS_TVMode |= TVSetPALM;
+              else if(temp & EnablePALN) SiS_Pr->SiS_TVMode |= TVSetPALN;
+           } else {
+              if(temp & EnableNTSCJ) {
+                 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
+              }
+           }
+        }
+      }
 
-  } else {  /* 661 and later */
+   } else {  /* 661 and later */
 
-     temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
-     if(temp1 & 0x01) {
-        SiS_Pr->SiS_TVMode |= TVSetPAL;
-       if(temp1 & 0x08) {
-          SiS_Pr->SiS_TVMode |= TVSetPALN;
-       } else if(temp1 & 0x04) {
-          if(SiS_Pr->SiS_VBType & VB_SISVB) {
-             SiS_Pr->SiS_TVMode &= ~TVSetPAL;
-          }
-          SiS_Pr->SiS_TVMode |= TVSetPALM;
-       }
-     } else {
-        if(temp1 & 0x02) {
-          SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
-       }
-     }
-     if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
-        if(SiS_Pr->SiS_CHOverScan) {
-           if((temp1 & 0x10) || (SiS_Pr->SiS_CHOverScan == 1)) {
-             SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
-          }
-       }
-     }
-     if(SiS_Pr->SiS_VBType & VB_SISVB) {
-        if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
-          temp1 &= 0xe0;
-          if(temp1 == 0x00)      SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
-          else if(temp1 == 0x20) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
-          else if(temp1 == 0x40) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
-       } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
-          SiS_Pr->SiS_TVMode |= (TVSetHiVision | TVSetPAL);
-       }
-       if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750 | SetCRT2ToHiVision)) {
-          if(resinfo == SIS_RI_800x480 || resinfo == SIS_RI_1024x576 || resinfo == SIS_RI_1280x720) {
-             SiS_Pr->SiS_TVMode |= TVAspect169;
-          } else {
-             temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x39);
-             if(temp1 & 0x02) {
-                if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetHiVision)) {
-                   SiS_Pr->SiS_TVMode |= TVAspect169;
-                } else {
-                   SiS_Pr->SiS_TVMode |= TVAspect43LB;
-                }
-             } else {
-                SiS_Pr->SiS_TVMode |= TVAspect43;
-             }
-          }
-       }
-     }
-  }
+      temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
+      if(temp1 & 0x01) {
+        SiS_Pr->SiS_TVMode |= TVSetPAL;
+        if(temp1 & 0x08) {
+           SiS_Pr->SiS_TVMode |= TVSetPALN;
+        } else if(temp1 & 0x04) {
+           if(SiS_Pr->SiS_VBType & VB_SISVB) {
+              SiS_Pr->SiS_TVMode &= ~TVSetPAL;
+           }
+           SiS_Pr->SiS_TVMode |= TVSetPALM;
+        }
+      } else {
+        if(temp1 & 0x02) {
+           SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
+        }
+      }
+      if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+        if(SiS_Pr->SiS_CHOverScan) {
+           if((temp1 & 0x10) || (SiS_Pr->SiS_CHOverScan == 1)) {
+              SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
+           }
+        }
+      }
+      if(SiS_Pr->SiS_VBType & VB_SISVB) {
+        if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
+           temp1 &= 0xe0;
+           if(temp1 == 0x00)      SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
+           else if(temp1 == 0x20) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
+           else if(temp1 == 0x40) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
+        } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
+           SiS_Pr->SiS_TVMode |= (TVSetHiVision | TVSetPAL);
+        }
+        if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750 | SetCRT2ToHiVision)) {
+           if(resinfo == SIS_RI_800x480 || resinfo == SIS_RI_1024x576 || resinfo == SIS_RI_1280x720) {
+              SiS_Pr->SiS_TVMode |= TVAspect169;
+           } else {
+              temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x39);
+              if(temp1 & 0x02) {
+                 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetHiVision)) {
+                    SiS_Pr->SiS_TVMode |= TVAspect169;
+                 } else {
+                    SiS_Pr->SiS_TVMode |= TVAspect43LB;
+                 }
+              } else {
+                 SiS_Pr->SiS_TVMode |= TVAspect43;
+              }
+           }
+        }
+      }
+   }
 
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) SiS_Pr->SiS_TVMode |= TVSetPAL;
+   if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) SiS_Pr->SiS_TVMode |= TVSetPAL;
 
-  if(SiS_Pr->SiS_VBType & VB_SISVB) {
+   if(SiS_Pr->SiS_VBType & VB_SISVB) {
 
-     if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
-        SiS_Pr->SiS_TVMode |= TVSetPAL;
-       SiS_Pr->SiS_TVMode &= ~(TVSetPALM | TVSetPALN | TVSetNTSCJ);
-     } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
-        if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525i | TVSetYPbPr525p | TVSetYPbPr750p)) {
-          SiS_Pr->SiS_TVMode &= ~(TVSetPAL | TVSetNTSCJ | TVSetPALM | TVSetPALN);
-       }
-     }
+      if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
+        SiS_Pr->SiS_TVMode |= TVSetPAL;
+        SiS_Pr->SiS_TVMode &= ~(TVSetPALM | TVSetPALN | TVSetNTSCJ);
+      } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
+        if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525i | TVSetYPbPr525p | TVSetYPbPr750p)) {
+           SiS_Pr->SiS_TVMode &= ~(TVSetPAL | TVSetNTSCJ | TVSetPALM | TVSetPALN);
+        }
+      }
 
-     if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-        if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
-           SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
-        }
-     }
+      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+        if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
+           SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
+        }
+      }
 
-     if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
-        /* BIOS sets TVNTSC1024 without checking 525p here. Wrong? */
-        if(!(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr525p | TVSetYPbPr750p))) {
-           if(resinfo == SIS_RI_1024x768) {
-              SiS_Pr->SiS_TVMode |= TVSetNTSC1024;
-          }
-        }
-     }
+      if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
+        if(resinfo == SIS_RI_1024x768) {
+           if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
+              SiS_Pr->SiS_TVMode |= TVSet525p1024;
+           } else if(!(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p))) {
+              SiS_Pr->SiS_TVMode |= TVSetNTSC1024;
+           }
+        }
+      }
 
-     SiS_Pr->SiS_TVMode |= TVRPLLDIV2XO;
-     if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) &&
-        (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-       SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
-     } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
-        SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
-     } else if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
-        if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
-           SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
-        }
-     }
+      SiS_Pr->SiS_TVMode |= TVRPLLDIV2XO;
+      if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) &&
+        (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+        SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
+      } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
+        SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
+      } else if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) {
+        if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
+           SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
+        }
+      }
 
-  }
+   }
 
-  SiS_Pr->SiS_VBInfo &= ~SetPALTV;
+   SiS_Pr->SiS_VBInfo &= ~SetPALTV;
 
+#ifdef SIS_XORG_XF86
 #ifdef TWDEBUG
-  xf86DrvMsg(0, X_INFO, "(init301: TVMode %x, VBInfo %x)\n", SiS_Pr->SiS_TVMode, SiS_Pr->SiS_VBInfo);
+   xf86DrvMsg(0, X_INFO, "(init301: TVMode %x, VBInfo %x)\n", SiS_Pr->SiS_TVMode, SiS_Pr->SiS_VBInfo);
+#endif
 #endif
 }
 
@@ -1455,41 +1430,46 @@ SiS_SetTVMode(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, PSIS_HW_IN
 /*               GET LCD INFO                */
 /*********************************************/
 
-static USHORT
-SiS_GetBIOSLCDResInfo(SiS_Private *SiS_Pr)
+static unsigned short
+SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr)
 {
-   USHORT temp = SiS_Pr->SiS_LCDResInfo;
+   unsigned short temp = SiS_Pr->SiS_LCDResInfo;
    /* Translate my LCDResInfo to BIOS value */
-   if(temp == Panel_1280x768_2)  temp = Panel_1280x768;
-   if(temp == Panel_1280x800_2)  temp = Panel_1280x800;
+   switch(temp) {
+   case Panel_1280x768_2: temp = Panel_1280x768;    break;
+   case Panel_1280x800_2: temp = Panel_1280x800;    break;
+   case Panel_1280x854:   temp = Panel661_1280x854; break;
+   }
    return temp;
 }
 
 static void
-SiS_GetLCDInfoBIOS(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_GetLCDInfoBIOS(struct SiS_Private *SiS_Pr)
 {
 #ifdef SIS315H
-   UCHAR  *ROMAddr;
-   USHORT temp;
+   unsigned char  *ROMAddr;
+   unsigned short temp;
 
+#ifdef SIS_XORG_XF86
 #ifdef TWDEBUG
    xf86DrvMsg(0, X_INFO, "Paneldata driver: [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n",
-       SiS_Pr->PanelHT, SiS_Pr->PanelVT,
+       SiS_Pr->PanelHT, SiS_Pr->PanelVT,
        SiS_Pr->PanelHRS, SiS_Pr->PanelHRE,
        SiS_Pr->PanelVRS, SiS_Pr->PanelVRE,
        SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK,
        SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A,
        SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B);
 #endif
+#endif
 
-   if((ROMAddr = GetLCDStructPtr661(SiS_Pr, HwInfo))) {
+   if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
       if((temp = SISGETROMW(6)) != SiS_Pr->PanelHT) {
-         SiS_Pr->SiS_NeedRomModeData = TRUE;
+        SiS_Pr->SiS_NeedRomModeData = TRUE;
         SiS_Pr->PanelHT  = temp;
       }
       if((temp = SISGETROMW(8)) != SiS_Pr->PanelVT) {
-         SiS_Pr->SiS_NeedRomModeData = TRUE;
-         SiS_Pr->PanelVT  = temp;
+        SiS_Pr->SiS_NeedRomModeData = TRUE;
+        SiS_Pr->PanelVT  = temp;
       }
       SiS_Pr->PanelHRS = SISGETROMW(10);
       SiS_Pr->PanelHRE = SISGETROMW(12);
@@ -1497,56 +1477,58 @@ SiS_GetLCDInfoBIOS(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
       SiS_Pr->PanelVRE = SISGETROMW(16);
       SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
       SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].CLOCK =
-        SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].CLOCK = (USHORT)((UCHAR)ROMAddr[18]);
+        SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].CLOCK = (unsigned short)((unsigned char)ROMAddr[18]);
       SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2B =
         SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_A = ROMAddr[19];
       SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2C =
         SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_B = ROMAddr[20];
 
+#ifdef SIS_XORG_XF86
 #ifdef TWDEBUG
       xf86DrvMsg(0, X_INFO, "Paneldata BIOS:  [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n",
-       SiS_Pr->PanelHT, SiS_Pr->PanelVT,
+       SiS_Pr->PanelHT, SiS_Pr->PanelVT,
        SiS_Pr->PanelHRS, SiS_Pr->PanelHRE,
        SiS_Pr->PanelVRS, SiS_Pr->PanelVRE,
        SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK,
        SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A,
        SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B);
 #endif
+#endif
 
    }
 #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;
-       }
-    }
+SiS_CheckScaling(struct SiS_Private *SiS_Pr, unsigned short resinfo,
+                       const unsigned char *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)
+SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
 {
+  unsigned short temp,modeflag,resinfo=0,modexres=0,modeyres=0;
+  BOOLEAN panelcanscale = FALSE;
 #ifdef SIS300
-  UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
-  const unsigned char SiS300SeriesLCDRes[] =
+  unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
+  static 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;
+  unsigned char   *myptr = NULL;
 #endif
-  USHORT  temp,modeflag,resinfo=0,modexres=0,modeyres=0;
-  BOOLEAN panelcanscale = FALSE;
 
   SiS_Pr->SiS_LCDResInfo  = 0;
   SiS_Pr->SiS_LCDTypeInfo = 0;
@@ -1557,14 +1539,14 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
   SiS_Pr->PanelVRE        = 999; /* VSync end */
   SiS_Pr->SiS_NeedRomModeData = FALSE;
 
+  /* Alternative 1600x1200@60 timing for 1600x1200 LCDA */
+  SiS_Pr->Alternate1600x1200 = FALSE;
+
   if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return;
 
-  if(ModeNo <= 0x13) {
-     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-  } else if(SiS_Pr->UseCustomMode) {
-     modeflag = SiS_Pr->CModeFlag;
-  } else {
-     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+  modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
+
+  if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
      modexres = SiS_Pr->SiS_ModeResInfo[resinfo].HTotal;
      modeyres = SiS_Pr->SiS_ModeResInfo[resinfo].VTotal;
@@ -1575,16 +1557,16 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
   /* For broken BIOSes: Assume 1024x768 */
   if(temp == 0) temp = 0x02;
 
-  if((HwInfo->jChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
+  if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
      SiS_Pr->SiS_LCDTypeInfo = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x7c) >> 2;
-  } else if((HwInfo->jChipType < SIS_315H) || (HwInfo->jChipType >= SIS_661)) {
+  } else if((SiS_Pr->ChipType < SIS_315H) || (SiS_Pr->ChipType >= SIS_661)) {
      SiS_Pr->SiS_LCDTypeInfo = temp >> 4;
   } else {
      SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1;
   }
   temp &= 0x0f;
 #ifdef SIS300
-  if(HwInfo->jChipType < SIS_315H) {
+  if(SiS_Pr->ChipType < 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;
@@ -1595,17 +1577,22 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 #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;
+#ifdef SIS315H
+  if(SiS_Pr->ChipType == SIS_550) {
+     if     (temp == Panel310_1152x768)  temp = Panel_320x240_2; /* Verified working */
+     else if(temp == Panel310_320x240_2) temp = Panel_320x240_2;
+     else if(temp == Panel310_320x240_3) temp = Panel_320x240_3;
+  } else if(SiS_Pr->ChipType >= SIS_661) {
+     if(temp == Panel661_1280x854)       temp = Panel_1280x854;
   }
+#endif
 
-  if(SiS_Pr->SiS_VBType & VB_SISLVDS) {        /* SiS LVDS */
+  if(SiS_Pr->SiS_VBType & VB_SISLVDS) {                /* SiS LVDS */
      if(temp == Panel310_1280x768) {
         temp = Panel_1280x768_2;
      }
      if(SiS_Pr->SiS_ROMNew) {
-        if(temp == Panel661_1280x800) {
+       if(temp == Panel661_1280x800) {
           temp = Panel_1280x800_2;
        }
      }
@@ -1613,13 +1600,17 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 
   SiS_Pr->SiS_LCDResInfo = temp;
 
+#ifdef SIS300
   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
      if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
-        SiS_Pr->SiS_LCDResInfo = Panel_Barco1366;
+       SiS_Pr->SiS_LCDResInfo = Panel_Barco1366;
      } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
-        SiS_Pr->SiS_LCDResInfo = Panel_848x480;
+       SiS_Pr->SiS_LCDResInfo = Panel_848x480;
+     } else if(SiS_Pr->SiS_CustomT == CUT_PANEL856) {
+       SiS_Pr->SiS_LCDResInfo = Panel_856x480;
      }
   }
+#endif
 
   if(SiS_Pr->SiS_VBType & VB_SISVB) {
      if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)
@@ -1633,10 +1624,16 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
   SiS_Pr->SiS_LCDInfo = temp & ~0x000e;
   /* Need temp below! */
 
-  /* These can't scale no matter what */
+  /* These must/can't scale no matter what */
   switch(SiS_Pr->SiS_LCDResInfo) {
+  case Panel_320x240_1:
+  case Panel_320x240_2:
+  case Panel_320x240_3:
   case Panel_1280x960:
       SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
+      break;
+  case Panel_640x480:
+      SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
   }
 
   panelcanscale = (SiS_Pr->SiS_LCDInfo & DontExpandLCD) ? TRUE : FALSE;
@@ -1646,41 +1643,41 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 
   /* Dual link, Pass 1:1 BIOS default, etc. */
 #ifdef SIS315H
-  if(HwInfo->jChipType >= SIS_661) {
+  if(SiS_Pr->ChipType >= SIS_661) {
      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
-        if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11;
+       if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11;
      }
-     if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
-        if(SiS_Pr->SiS_ROMNew) {
+     if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
+       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((myptr = GetLCDStructPtr661(SiS_Pr))) {
+          if(myptr[2] & 0x01) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
        }
      }
-  } else if(HwInfo->jChipType >= SIS_315H) {
+  } else if(SiS_Pr->ChipType >= SIS_315H) {
      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
-        if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) SiS_Pr->SiS_LCDInfo |= LCDPass11;
+       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);
+       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 & 0x01) SiS_Pr->SiS_LCDInfo |= LCDRGB18Bit;
+       if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
           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) &&
+       if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
+          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) ||
+          if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
              (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
-              (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
+             (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
              (SiS_Pr->SiS_LCDResInfo == Panel_1680x1050)) {
              SiS_Pr->SiS_LCDInfo |= LCDDualLink;
           }
-        }
+       }
      }
   }
 #endif
@@ -1691,12 +1688,12 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
      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;
+       /* 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;
+       /* 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;
      }
   }
 
@@ -1704,19 +1701,15 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
   SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
 
   switch(SiS_Pr->SiS_LCDResInfo) {
-     case Panel_320x480:    SiS_Pr->PanelXRes =  320; SiS_Pr->PanelYRes =  480;
-                           SiS_Pr->PanelHT   =  400; SiS_Pr->PanelVT   =  525;
-                           SiS_Pr->PanelVCLKIdx300 = VCLK28;
-                           SiS_Pr->PanelVCLKIdx315 = VCLK28;
-                           break;
-     case Panel_640x480_2:
-     case Panel_640x480_3:  SiS_Pr->PanelXRes =  640; SiS_Pr->PanelYRes =  480;
-                           SiS_Pr->PanelVRS  =   24; SiS_Pr->PanelVRE  =    3;
+     case Panel_320x240_1:
+     case Panel_320x240_2:
+     case Panel_320x240_3:  SiS_Pr->PanelXRes =  640; SiS_Pr->PanelYRes =  480;
+                           SiS_Pr->PanelVRS  =   24; SiS_Pr->PanelVRE  =    3;
                            SiS_Pr->PanelVCLKIdx300 = VCLK28;
                            SiS_Pr->PanelVCLKIdx315 = VCLK28;
                            break;
      case Panel_640x480:    SiS_Pr->PanelXRes =  640; SiS_Pr->PanelYRes =  480;
-                                                     SiS_Pr->PanelVRE  =    3;
+                                                     SiS_Pr->PanelVRE  =    3;
                            SiS_Pr->PanelVCLKIdx300 = VCLK28;
                            SiS_Pr->PanelVCLKIdx315 = VCLK28;
                            break;
@@ -1728,52 +1721,52 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
                            SiS_Pr->PanelVCLKIdx315 = VCLK40;
                            break;
      case Panel_1024x600:   SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  600;
-                           SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  800;
+                           SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  800;
                            SiS_Pr->PanelHRS  =   24; SiS_Pr->PanelHRE  =  136;
                            SiS_Pr->PanelVRS  =    2 /* 88 */ ; SiS_Pr->PanelVRE  =    6;
-                           SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
+                           SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
                            SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
-                           break;
+                           break;
      case Panel_1024x768:   SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  768;
-                           SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  806;
+                           SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  806;
                            SiS_Pr->PanelHRS  =   24; SiS_Pr->PanelHRE  =  136;
                            SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
-                           if(HwInfo->jChipType < SIS_315H) {
+                           if(SiS_Pr->ChipType < SIS_315H) {
                               SiS_Pr->PanelHRS = 23;
-                                                     SiS_Pr->PanelVRE  =    5;
+                                                     SiS_Pr->PanelVRE  =    5;
                            }
                            SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
                            SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
-                           SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
+                           SiS_GetLCDInfoBIOS(SiS_Pr);
                            break;
      case Panel_1152x768:   SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes =  768;
-                           SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  806;
-                           SiS_Pr->PanelHRS  =   24;
+                           SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  806;
+                           SiS_Pr->PanelHRS  =   24; SiS_Pr->PanelHRE  =  136;
                            SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
-                           if(HwInfo->jChipType < SIS_315H) {
+                           if(SiS_Pr->ChipType < SIS_315H) {
                               SiS_Pr->PanelHRS = 23;
-                                                     SiS_Pr->PanelVRE  =    5;
+                                                     SiS_Pr->PanelVRE  =    5;
                            }
-                           SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
+                           SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
                            SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
-                           break;
+                           break;
      case Panel_1152x864:   SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes =  864;
-                           break;
+                           break;
      case Panel_1280x720:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  720;
-                           SiS_Pr->PanelHT   = 1650; SiS_Pr->PanelVT   =  750;
+                           SiS_Pr->PanelHT   = 1650; SiS_Pr->PanelVT   =  750;
                            SiS_Pr->PanelHRS  =  110; SiS_Pr->PanelHRE  =   40;
                            SiS_Pr->PanelVRS  =    5; SiS_Pr->PanelVRE  =    5;
                            SiS_Pr->PanelVCLKIdx315 = VCLK_1280x720;
                            /* Data above for TMDS (projector); get from BIOS for LVDS */
-                           SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
+                           SiS_GetLCDInfoBIOS(SiS_Pr);
                            break;
      case Panel_1280x768:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  768;
-                           if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+                           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->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;
@@ -1781,77 +1774,100 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
                            }
                            break;
      case Panel_1280x768_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  768;
-                           SiS_Pr->PanelHT   = 1660; SiS_Pr->PanelVT   =  806;
+                           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);
+                           SiS_GetLCDInfoBIOS(SiS_Pr);
                            break;
      case Panel_1280x800:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  800;
-                           SiS_Pr->PanelHT   = 1408; SiS_Pr->PanelVT   =  816;
+                           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);
+                           SiS_GetLCDInfoBIOS(SiS_Pr);
                            break;
      case Panel_1280x800_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  800;
-                           SiS_Pr->PanelHT   = 1552; SiS_Pr->PanelVT   =  812;
+                           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);
+                           SiS_GetLCDInfoBIOS(SiS_Pr);
+                           break;
+     case Panel_1280x854:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  854;
+                           SiS_Pr->PanelHT   = 1664; SiS_Pr->PanelVT   =  861;
+                           SiS_Pr->PanelHRS   =  16; SiS_Pr->PanelHRE  =  112;
+                           SiS_Pr->PanelVRS   =   1; SiS_Pr->PanelVRE  =    3;
+                           SiS_Pr->PanelVCLKIdx315 = VCLK_1280x854;
+                           SiS_GetLCDInfoBIOS(SiS_Pr);
                            break;
      case Panel_1280x960:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  960;
-                           SiS_Pr->PanelHT   = 1800; SiS_Pr->PanelVT   = 1000;
+                           SiS_Pr->PanelHT   = 1800; SiS_Pr->PanelVT   = 1000;
                            SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
                            SiS_Pr->PanelVCLKIdx315 = VCLK108_3_315;
-                           if(resinfo == SIS_RI_1280x1024) {
+                           if(resinfo == SIS_RI_1280x1024) {
                               SiS_Pr->PanelVCLKIdx300 = VCLK100_300;
                               SiS_Pr->PanelVCLKIdx315 = VCLK100_315;
                            }
                            break;
      case Panel_1280x1024:  SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024;
-                           SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   = 1066;
+                           SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   = 1066;
                            SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112;
                            SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    3;
                            SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
                            SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
-                           SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
+                           SiS_GetLCDInfoBIOS(SiS_Pr);
                            break;
      case Panel_1400x1050:  SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050;
-                           SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   = 1066;
-                           SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112; /* HRE OK for LVDS, not for LCDA */
+                           SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   = 1066;
+                           SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112;
                            SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    3;
                            SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
-                           SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
+                           SiS_GetLCDInfoBIOS(SiS_Pr);
                            break;
      case Panel_1600x1200:  SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200;
-                           SiS_Pr->PanelHT   = 2160; SiS_Pr->PanelVT   = 1250;
+                           SiS_Pr->PanelHT   = 2160; SiS_Pr->PanelVT   = 1250;
                            SiS_Pr->PanelHRS  =   64; SiS_Pr->PanelHRE  =  192;
                            SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    3;
                            SiS_Pr->PanelVCLKIdx315 = VCLK162_315;
-                           SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
+                           if(SiS_Pr->SiS_VBType & VB_SISTMDSLCDA) {
+                              if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+                                 SiS_Pr->PanelHT  = 1760; SiS_Pr->PanelVT  = 1235;
+                                 SiS_Pr->PanelHRS =   48; SiS_Pr->PanelHRE =   32;
+                                 SiS_Pr->PanelVRS =    2; SiS_Pr->PanelVRE =    4;
+                                 SiS_Pr->PanelVCLKIdx315 = VCLK130_315;
+                                 SiS_Pr->Alternate1600x1200 = TRUE;
+                              }
+                           } else if(SiS_Pr->SiS_IF_DEF_LVDS) {
+                              SiS_Pr->PanelHT  = 2048; SiS_Pr->PanelVT  = 1320;
+                              SiS_Pr->PanelHRS = SiS_Pr->PanelHRE = 999;
+                              SiS_Pr->PanelVRS = SiS_Pr->PanelVRE = 999;
+                           }
+                           SiS_GetLCDInfoBIOS(SiS_Pr);
                            break;
      case Panel_1680x1050:  SiS_Pr->PanelXRes = 1680; SiS_Pr->PanelYRes = 1050;
-                           SiS_Pr->PanelHT   = 1900; SiS_Pr->PanelVT   = 1066;
+                           SiS_Pr->PanelHT   = 1900; SiS_Pr->PanelVT   = 1066;
                            SiS_Pr->PanelHRS  =   26; SiS_Pr->PanelHRE  =   76;
                            SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
                            SiS_Pr->PanelVCLKIdx315 = VCLK121_315;
-                           SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
+                           SiS_GetLCDInfoBIOS(SiS_Pr);
                            break;
      case Panel_Barco1366:  SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024;
-                           SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   = 1066;
-                           break;
+                           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;
+                           SiS_Pr->PanelHT   = 1088; SiS_Pr->PanelVT   =  525;
+                           break;
+     case Panel_856x480:    SiS_Pr->PanelXRes =  856; 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->PanelYRes = SiS_Pr->CP_MaxY;
                            SiS_Pr->PanelHT   = SiS_Pr->CHTotal;
                            SiS_Pr->PanelVT   = SiS_Pr->CVTotal;
                            if(SiS_Pr->CP_PreferredIndex != -1) {
                               SiS_Pr->PanelXRes = SiS_Pr->CP_HDisplay[SiS_Pr->CP_PreferredIndex];
-                              SiS_Pr->PanelYRes = SiS_Pr->CP_VDisplay[SiS_Pr->CP_PreferredIndex];
+                              SiS_Pr->PanelYRes = SiS_Pr->CP_VDisplay[SiS_Pr->CP_PreferredIndex];
                               SiS_Pr->PanelHT   = SiS_Pr->CP_HTotal[SiS_Pr->CP_PreferredIndex];
                               SiS_Pr->PanelVT   = SiS_Pr->CP_VTotal[SiS_Pr->CP_PreferredIndex];
                               SiS_Pr->PanelHRS  = SiS_Pr->CP_HSyncStart[SiS_Pr->CP_PreferredIndex];
@@ -1863,22 +1879,22 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
                               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;
+                                 int idx;
+                                 SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
                                  SiS_Pr->PanelVCLKIdx300 = VCLK_CUSTOM_300;
-                                 if(HwInfo->jChipType < SIS_315H) idx = VCLK_CUSTOM_300;
+                                 if(SiS_Pr->ChipType < 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;
+                                 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;
      default:              SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  768;
-                           SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  806;
+                           SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  806;
                            break;
   }
 
@@ -1887,14 +1903,16 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
       (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->SiS_CustomT == CUT_PANEL848)  ||
+      (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
      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->SiS_CustomT == CUT_PANEL848)  ||
+      (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
      SiS_Pr->PanelVRS = 999;
      SiS_Pr->PanelVRE = 999;
   }
@@ -1912,18 +1930,18 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
      case Panel_Custom:
      case Panel_1152x864:
      case Panel_1280x768:      /* TMDS only */
-        SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+       SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
        break;
 
      case Panel_800x600: {
-        static const UCHAR nonscalingmodes[] = {
+       static const unsigned char 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[] = {
+       static const unsigned char 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
@@ -1932,7 +1950,7 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
        break;
      }
      case Panel_1280x720: {
-        static const UCHAR nonscalingmodes[] = {
+       static const unsigned char 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
@@ -1944,7 +1962,7 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
        break;
      }
      case Panel_1280x768_2: {  /* LVDS only */
-        static const UCHAR nonscalingmodes[] = {
+       static const unsigned char 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
@@ -1952,23 +1970,23 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
        SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
        switch(resinfo) {
        case SIS_RI_1280x720:  if(SiS_Pr->UsePanelScaler == -1) {
-                                 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
-                              }
-                              break;
+                                 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+                              }
+                              break;
        }
-        break;
+       break;
      }
      case Panel_1280x800: {    /* SiS TMDS special (Averatec 6200 series) */
-        static const UCHAR nonscalingmodes[] = {
+       static const unsigned char 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;
+       break;
      }
      case Panel_1280x800_2:  {         /* SiS LVDS */
-        static const UCHAR nonscalingmodes[] = {
+       static const unsigned char 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
@@ -1977,66 +1995,83 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
        switch(resinfo) {
        case SIS_RI_1280x720:
        case SIS_RI_1280x768:  if(SiS_Pr->UsePanelScaler == -1) {
-                                 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
-                              }
-                              break;
+                                 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+                              }
+                              break;
        }
-        break;
+       break;
      }
-     case Panel_1280x960: {
-        static const UCHAR nonscalingmodes[] = {
+     case Panel_1280x854: {    /* SiS LVDS */
+       static const unsigned char 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_RI_1152x768,0xff
        };
        SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
-        break;
-     }
-     case Panel_1280x1024: {
-        static const UCHAR nonscalingmodes[] = {
+       switch(resinfo) {
+       case SIS_RI_1280x720:
+       case SIS_RI_1280x768:
+       case SIS_RI_1280x800:  if(SiS_Pr->UsePanelScaler == -1) {
+                                 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+                              }
+                              break;
+       }
+       break;
+     }
+     case Panel_1280x960: {
+       static const unsigned char 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_1280x854,0xff
+       };
+       SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
+       break;
+     }
+     case Panel_1280x1024: {
+       static const unsigned char 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_RI_1280x854,SIS_RI_1280x960,0xff
        };
        SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
        break;
      }
      case Panel_1400x1050: {
-        static const UCHAR nonscalingmodes[] = {
+       static const unsigned char 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_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x768,SIS_RI_1280x800,SIS_RI_1280x854,
+            SIS_RI_1280x960,0xff
        };
        SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
-        switch(resinfo) {
+       switch(resinfo) {
        case SIS_RI_1280x720:  if(SiS_Pr->UsePanelScaler == -1) {
-                                 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
-                              }
-                              break;
+                                 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+                              }
+                              break;
        case SIS_RI_1280x1024: SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
-                              break;
+                              break;
        }
        break;
      }
      case Panel_1600x1200: {
-        static const UCHAR nonscalingmodes[] = {
+       static const unsigned char 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_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,SIS_RI_1360x1024,0xff
        };
        SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
-        break;
+       break;
      }
      case Panel_1680x1050: {
-        static const UCHAR nonscalingmodes[] = {
+       static const unsigned char 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_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,
+            SIS_RI_1360x1024,0xff
        };
        SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
        break;
@@ -2044,25 +2079,25 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
      }
   }
 
+#ifdef SIS300
   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-     if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
-        SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20;   /* neg h/v sync, RGB24(D0 = 0) */
+     if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
+       SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20;   /* neg h/v sync, RGB24(D0 = 0) */
      }
   }
 
-#ifdef SIS300
-  if(HwInfo->jChipType < SIS_315H) {
+  if(SiS_Pr->ChipType < SIS_315H) {
      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-        if(SiS_Pr->SiS_UseROM) {
+       if(SiS_Pr->SiS_UseROM) {
           if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
-              if(!(ROMAddr[0x235] & 0x02)) {
-                SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
-             }
+             if(!(ROMAddr[0x235] & 0x02)) {
+                SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
+             }
           }
-        }
-     } else if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+       }
+     } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
        if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
-           SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
+          SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
        }
      }
   }
@@ -2080,7 +2115,7 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 
   switch(SiS_Pr->SiS_LCDResInfo) {
   case Panel_640x480:
-     SiS_Pr->SiS_LCDInfo |= LCDPass11;
+     SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
      break;
   case Panel_1280x800:
      /* Don't pass 1:1 by default (TMDS special) */
@@ -2097,7 +2132,7 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
      break;
   }
 
-  if(SiS_Pr->UseCustomMode) {
+  if((SiS_Pr->UseCustomMode) || (SiS_Pr->SiS_CustomT == CUT_UNKNOWNLCD)) {
      SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
   }
 
@@ -2107,19 +2142,19 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
   }
 
   /* LVDS DDA */
-  if(!((HwInfo->jChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
+  if(!((SiS_Pr->ChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
 
      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) {
-                SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+                SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
              }
           } else if(ModeNo > 0x13) {
              if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
-                if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
-                   if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) {
-                       SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+                if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
+                   if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) {
+                      SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
                    }
                 }
              }
@@ -2128,18 +2163,18 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
      }
 
      if(modeflag & HalfDCLK) {
-        if(SiS_Pr->SiS_IF_DEF_TRUMPION == 1) {
+       if(SiS_Pr->SiS_IF_DEF_TRUMPION == 1) {
           SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
-        } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+       } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
           SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
        } else if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) {
           SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
        } else if(ModeNo > 0x13) {
-           if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
-              if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
-           } else if(SiS_Pr->SiS_LCDResInfo == Panel_800x600) {
-              if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
-           }
+          if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
+             if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+          } else if(SiS_Pr->SiS_LCDResInfo == Panel_800x600) {
+             if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+          }
        }
      }
 
@@ -2148,21 +2183,21 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
   /* VESA timing */
   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
      if(SiS_Pr->SiS_VBInfo & SetNotSimuMode) {
-       SiS_Pr->SiS_SetFlag |= LCDVESATiming;
+       SiS_Pr->SiS_SetFlag |= LCDVESATiming;
      }
   } else {
      SiS_Pr->SiS_SetFlag |= LCDVESATiming;
   }
 
-#ifdef LINUX_KERNEL
-#ifdef TWDEBUG
+#ifdef SIS_LINUX_KERNEL
+#if 0
   printk(KERN_DEBUG "sisfb: (LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n",
        SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo);
 #endif
 #endif
-#ifdef LINUX_XF86
+#ifdef SIS_XORG_XF86
   xf86DrvMsgVerb(0, X_PROBED, 4,
-       "(init301: LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x SetFlag=0x%04x)\n",
+       "(init301: LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x SetFlag=0x%04x)\n",
        SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo, SiS_Pr->SiS_SetFlag);
 #endif
 }
@@ -2171,45 +2206,46 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 /*                 GET VCLK                  */
 /*********************************************/
 
-USHORT
-SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
-                USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
+unsigned short
+SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
+               unsigned short RefreshRateTableIndex)
 {
-  USHORT CRT2Index,VCLKIndex=0,VCLKIndexGEN=0;
-  USHORT modeflag,resinfo,tempbx;
-  const UCHAR *CHTVVCLKPtr = NULL;
+  unsigned short CRT2Index, VCLKIndex = 0, VCLKIndexGEN = 0, VCLKIndexGENCRT = 0;
+  unsigned short modeflag, resinfo, tempbx;
+  const unsigned char *CHTVVCLKPtr = NULL;
 
   if(ModeNo <= 0x13) {
      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
      CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
      VCLKIndexGEN = (SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)) >> 2) & 0x03;
+     VCLKIndexGENCRT = VCLKIndexGEN;
   } else {
      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
      CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
      VCLKIndexGEN = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
-     if(HwInfo->jChipType < SIS_315H) VCLKIndexGEN &= 0x3f;
+     VCLKIndexGENCRT = SiS_GetRefCRTVCLK(SiS_Pr, RefreshRateTableIndex,
+               (SiS_Pr->SiS_SetFlag & ProgrammingCRT2) ? SiS_Pr->SiS_UseWideCRT2 : SiS_Pr->SiS_UseWide);
   }
 
   if(SiS_Pr->SiS_VBType & VB_SISVB) {    /* 30x/B/LV */
 
      if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
 
-        CRT2Index >>= 6;
-        if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {              /*  LCD */
+       CRT2Index >>= 6;
+       if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {       /*  LCD */
 
-           if(HwInfo->jChipType < SIS_315H) {
+          if(SiS_Pr->ChipType < SIS_315H) {
              VCLKIndex = SiS_Pr->PanelVCLKIdx300;
              if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
-                VCLKIndex = VCLKIndexGEN;
+                VCLKIndex = VCLKIndexGEN;
              }
           } else {
              VCLKIndex = SiS_Pr->PanelVCLKIdx315;
              if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
                 switch(resinfo) {
-                /* Only those whose IndexGEN doesn't match VBVCLK array */
-                case SIS_RI_1280x720: VCLKIndex = VCLK_1280x720; break;
+                /* Correct those whose IndexGEN doesn't match VBVCLK array */
                 case SIS_RI_720x480:  VCLKIndex = VCLK_720x480;  break;
                 case SIS_RI_720x576:  VCLKIndex = VCLK_720x576;  break;
                 case SIS_RI_768x576:  VCLKIndex = VCLK_768x576;  break;
@@ -2218,18 +2254,19 @@ SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
                 case SIS_RI_800x480:  VCLKIndex = VCLK_800x480;  break;
                 case SIS_RI_1024x576: VCLKIndex = VCLK_1024x576; break;
                 case SIS_RI_1152x864: VCLKIndex = VCLK_1152x864; break;
+                case SIS_RI_1280x720: VCLKIndex = VCLK_1280x720; break;
                 case SIS_RI_1360x768: VCLKIndex = VCLK_1360x768; break;
                 default:              VCLKIndex = VCLKIndexGEN;
                 }
 
                 if(ModeNo <= 0x13) {
-                   if(HwInfo->jChipType <= SIS_315PRO) {
+                   if(SiS_Pr->ChipType <= SIS_315PRO) {
                       if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
-                   } else {
+                   } else {
                       if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x00;
                    }
                 }
-                if(HwInfo->jChipType <= SIS_315PRO) {
+                if(SiS_Pr->ChipType <= SIS_315PRO) {
                    if(VCLKIndex == 0) VCLKIndex = 0x41;
                    if(VCLKIndex == 1) VCLKIndex = 0x43;
                    if(VCLKIndex == 4) VCLKIndex = 0x44;
@@ -2237,49 +2274,46 @@ SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
              }
           }
 
-        } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {                  /*  TV */
+       } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {                   /*  TV */
 
           if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
-              if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO)            VCLKIndex = HiTVVCLKDIV2;
-             else                                              VCLKIndex = HiTVVCLK;
-              if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
-                if(modeflag & Charx8Dot)                       VCLKIndex = HiTVSimuVCLK;
-                else                                           VCLKIndex = HiTVTextVCLK;
-              }
-           } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)      VCLKIndex = YPbPr750pVCLK;
-          else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)         VCLKIndex = TVVCLKDIV2;
-          else if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO)           VCLKIndex = TVVCLKDIV2;
-           else                                                VCLKIndex = TVVCLK;
-
-          if(HwInfo->jChipType < SIS_315H) VCLKIndex += TVCLKBASE_300;
-          else                             VCLKIndex += TVCLKBASE_315;
-
-        } else {                                                       /* VGA2 */
-
-          VCLKIndex = VCLKIndexGEN;
-          if(HwInfo->jChipType < SIS_315H) {
-              if(ModeNo > 0x13) {
-                if( (HwInfo->jChipType == SIS_630) &&
-                    (HwInfo->jChipRevision >= 0x30)) {
+             if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO)        VCLKIndex = HiTVVCLKDIV2;
+             else                                         VCLKIndex = HiTVVCLK;
+             if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)     VCLKIndex = HiTVSimuVCLK;
+          } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)  VCLKIndex = YPbPr750pVCLK;
+          else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)    VCLKIndex = TVVCLKDIV2;
+          else if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO)      VCLKIndex = TVVCLKDIV2;
+          else                                            VCLKIndex = TVVCLK;
+
+          if(SiS_Pr->ChipType < SIS_315H) VCLKIndex += TVCLKBASE_300;
+          else                            VCLKIndex += TVCLKBASE_315;
+
+       } else {                                                        /* VGA2 */
+
+          VCLKIndex = VCLKIndexGENCRT;
+          if(SiS_Pr->ChipType < SIS_315H) {
+             if(ModeNo > 0x13) {
+                if( (SiS_Pr->ChipType == SIS_630) &&
+                    (SiS_Pr->ChipRevision >= 0x30)) {
                    if(VCLKIndex == 0x14) VCLKIndex = 0x34;
                 }
                 /* Better VGA2 clock for 1280x1024@75 */
                 if(VCLKIndex == 0x17) VCLKIndex = 0x45;
              }
-           }
-        }
+          }
+       }
 
      } else {   /* If not programming CRT2 */
 
-        VCLKIndex = VCLKIndexGEN;
-       if(HwInfo->jChipType < SIS_315H) {
-           if(ModeNo > 0x13) {
-             if( (HwInfo->jChipType != SIS_630) &&
-                 (HwInfo->jChipType != SIS_300) ) {
+       VCLKIndex = VCLKIndexGENCRT;
+       if(SiS_Pr->ChipType < SIS_315H) {
+          if(ModeNo > 0x13) {
+             if( (SiS_Pr->ChipType != SIS_630) &&
+                 (SiS_Pr->ChipType != SIS_300) ) {
                 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
              }
           }
-        }
+       }
      }
 
   } else {       /*   LVDS  */
@@ -2288,12 +2322,12 @@ SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 
      if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
 
-        if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
+       if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
 
           VCLKIndex &= 0x1f;
-           tempbx = 0;
+          tempbx = 0;
           if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
-           if(SiS_Pr->SiS_TVMode & TVSetPAL) {
+          if(SiS_Pr->SiS_TVMode & TVSetPAL) {
              tempbx += 2;
              if(SiS_Pr->SiS_ModeType > ModeVGA) {
                 if(SiS_Pr->SiS_CHSOverScan) tempbx = 8;
@@ -2306,66 +2340,68 @@ SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
                 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
              }
           }
-                  switch(tempbx) {
-             case  0: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUNTSC;  break;
-             case  1: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKONTSC;  break;
-             case  2: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPAL;   break;
-             case  3: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL;   break;
+          switch(tempbx) {
+            case  0: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUNTSC;  break;
+            case  1: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKONTSC;  break;
+            case  2: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPAL;   break;
+            case  3: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL;   break;
             case  4: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALM;  break;
-             case  5: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALM;  break;
-             case  6: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALN;  break;
-             case  7: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALN;  break;
+            case  5: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALM;  break;
+            case  6: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALN;  break;
+            case  7: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALN;  break;
             case  8: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKSOPAL;  break;
             default: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL;   break;
-           }
-           VCLKIndex = CHTVVCLKPtr[VCLKIndex];
+          }
+          VCLKIndex = CHTVVCLKPtr[VCLKIndex];
 
-        } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+       } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
 
-          if(HwInfo->jChipType < SIS_315H) {
+          if(SiS_Pr->ChipType < SIS_315H) {
              VCLKIndex = SiS_Pr->PanelVCLKIdx300;
           } else {
              VCLKIndex = SiS_Pr->PanelVCLKIdx315;
           }
 
+#ifdef SIS300
           /* Special Timing: Barco iQ Pro R series */
           if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) VCLKIndex = 0x44;
 
-          /* Special Timing: 848x480 parallel lvds */
-          if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
-             if(HwInfo->jChipType < SIS_315H) {
+          /* Special Timing: 848x480 and 856x480 parallel lvds panels */
+          if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
+             if(SiS_Pr->ChipType < SIS_315H) {
                 VCLKIndex = VCLK34_300;
-                /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
+                /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
              } else {
                 VCLKIndex = VCLK34_315;
                 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
              }
           }
+#endif
 
-        } else {
+       } else {
 
-          VCLKIndex = VCLKIndexGEN;
-          if(HwInfo->jChipType < SIS_315H) {
-              if(ModeNo > 0x13) {
-                if( (HwInfo->jChipType == SIS_630) &&
-                     (HwInfo->jChipRevision >= 0x30) ) {
+          VCLKIndex = VCLKIndexGENCRT;
+          if(SiS_Pr->ChipType < SIS_315H) {
+             if(ModeNo > 0x13) {
+                if( (SiS_Pr->ChipType == SIS_630) &&
+                    (SiS_Pr->ChipRevision >= 0x30) ) {
                    if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
-                }
-              }
+                }
+             }
           }
-        }
+       }
 
      } else {  /* if not programming CRT2 */
 
-        VCLKIndex = VCLKIndexGEN;
-       if(HwInfo->jChipType < SIS_315H) {
-           if(ModeNo > 0x13) {
-             if( (HwInfo->jChipType != SIS_630) &&
-                 (HwInfo->jChipType != SIS_300) ) {
+       VCLKIndex = VCLKIndexGENCRT;
+       if(SiS_Pr->ChipType < SIS_315H) {
+          if(ModeNo > 0x13) {
+             if( (SiS_Pr->ChipType != SIS_630) &&
+                 (SiS_Pr->ChipType != SIS_300) ) {
                 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
              }
 #if 0
-             if(HwInfo->jChipType == SIS_730) {
+             if(SiS_Pr->ChipType == SIS_730) {
                 if(VCLKIndex == 0x0b) VCLKIndex = 0x40;   /* 1024x768-70 */
                 if(VCLKIndex == 0x0d) VCLKIndex = 0x41;   /* 1024x768-75 */
              }
@@ -2377,11 +2413,13 @@ SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 
   }
 
+#ifdef SIS_XORG_XF86
 #ifdef TWDEBUG
   xf86DrvMsg(0, X_INFO, "VCLKIndex %d (0x%x)\n", VCLKIndex, VCLKIndex);
 #endif
+#endif
 
-  return(VCLKIndex);
+  return VCLKIndex;
 }
 
 /*********************************************/
@@ -2389,26 +2427,19 @@ SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 /*********************************************/
 
 static void
-SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
-                    PSIS_HW_INFO HwInfo)
+SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
 {
-  USHORT i,j,modeflag;
-  USHORT tempcl,tempah=0;
+  unsigned short i, j, modeflag, tempah=0;
+  short tempcl;
 #if defined(SIS300) || defined(SIS315H)
-  USHORT tempbl;
+  unsigned short tempbl;
 #endif
 #ifdef SIS315H
-  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
-  USHORT tempah2, tempbl2;
+  unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
+  unsigned short tempah2, tempbl2;
 #endif
 
-  if(ModeNo <= 0x13) {
-     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-  } else if(SiS_Pr->UseCustomMode) {
-     modeflag = SiS_Pr->CModeFlag;
-  } else {
-     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-  }
+  modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
 
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
 
@@ -2418,18 +2449,18 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
   } else {
 
      for(i=0,j=4; i<3; i++,j++) SiS_SetReg(SiS_Pr->SiS_Part1Port,j,0);
-     if(HwInfo->jChipType >= SIS_315H) {
+     if(SiS_Pr->ChipType >= SIS_315H) {
         SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0x7F);
      }
 
      tempcl = SiS_Pr->SiS_ModeType;
 
-     if(HwInfo->jChipType < SIS_315H) {
+     if(SiS_Pr->ChipType < SIS_315H) {
 
 #ifdef SIS300    /* ---- 300 series ---- */
 
-        /* For 301BDH: (with LCD via LVDS) */
-        if(SiS_Pr->SiS_VBType & VB_NoLCD) {
+       /* For 301BDH: (with LCD via LVDS) */
+       if(SiS_Pr->SiS_VBType & VB_NoLCD) {
           tempbl = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32);
           tempbl &= 0xef;
           tempbl |= 0x02;
@@ -2438,16 +2469,16 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
              tempbl &= 0xfd;
           }
           SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,tempbl);
-        }
+       }
 
-        if(ModeNo > 0x13) {
-           tempcl -= ModeVGA;
-           if((tempcl > 0) || (tempcl == 0)) {      /* tempcl is USHORT -> always true! */
-              tempah = ((0x10 >> tempcl) | 0x80);
-           }
-        } else tempah = 0x80;
+       if(ModeNo > 0x13) {
+          tempcl -= ModeVGA;
+          if(tempcl >= 0) {
+             tempah = ((0x10 >> tempcl) | 0x80);
+          }
+       } else tempah = 0x80;
 
-        if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)  tempah ^= 0xA0;
+       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)  tempah ^= 0xA0;
 
 #endif  /* SIS300 */
 
@@ -2455,22 +2486,16 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 
 #ifdef SIS315H    /* ------- 315/330 series ------ */
 
-        if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-           if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
-             SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x08);
-           }
-        }
-
-        if(ModeNo > 0x13) {
-           tempcl -= ModeVGA;
-           if((tempcl > 0) || (tempcl == 0)) {  /* tempcl is USHORT -> always true! */
-              tempah = (0x08 >> tempcl);
-              if (tempah == 0) tempah = 1;
-              tempah |= 0x40;
-           }
-        } else tempah = 0x40;
+       if(ModeNo > 0x13) {
+          tempcl -= ModeVGA;
+          if(tempcl >= 0) {
+             tempah = (0x08 >> tempcl);
+             if (tempah == 0) tempah = 1;
+             tempah |= 0x40;
+          }
+       } else tempah = 0x40;
 
-        if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50;
+       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50;
 
 #endif  /* SIS315H */
 
@@ -2478,84 +2503,89 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 
      if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
 
-     if(HwInfo->jChipType < SIS_315H) {
-        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
+     if(SiS_Pr->ChipType < SIS_315H) {
+       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
      } else {
-        if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-           SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
-        } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
-           if(IS_SIS740) {
+#ifdef SIS315H
+       if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
+       } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
+          if(IS_SIS740) {
              SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
           } else {
-              SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
+             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
           }
-        }
+       }
+#endif
      }
 
      if(SiS_Pr->SiS_VBType & VB_SISVB) {
 
-        tempah = 0x01;
-        if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-          tempah |= 0x02;
-        }
-        if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
-          tempah ^= 0x05;
-          if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
-              tempah ^= 0x01;
-          }
-        }
+       tempah = 0x01;
+       if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+          tempah |= 0x02;
+       }
+       if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
+          tempah ^= 0x05;
+          if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
+             tempah ^= 0x01;
+          }
+       }
 
-        if(SiS_Pr->SiS_VBInfo & DisableCRT2Display)  tempah = 0;
+       if(SiS_Pr->ChipType < SIS_315H) {
 
-        if(HwInfo->jChipType < SIS_315H) {
+          if(SiS_Pr->SiS_VBInfo & DisableCRT2Display)  tempah = 0;
 
-          tempah = (tempah << 5) & 0xFF;
-          SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
-          tempah = (tempah >> 5) & 0xFF;
+          tempah = (tempah << 5) & 0xFF;
+          SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
+          tempah = (tempah >> 5) & 0xFF;
 
-        } else {
+       } else {
 
-          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF8,tempah);
+          if(SiS_Pr->SiS_VBInfo & DisableCRT2Display)  tempah = 0x08;
+          else if(!(SiS_IsDualEdge(SiS_Pr)))           tempah |= 0x08;
+          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF0,tempah);
+          tempah &= ~0x08;
 
-        }
+       }
 
-        if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
-          tempah |= 0x10;
-        }
+       if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
+          tempah |= 0x10;
+       }
 
        tempah |= 0x80;
-        if(SiS_Pr->SiS_VBType & VB_SIS301) {
+       if(SiS_Pr->SiS_VBType & VB_SIS301) {
           if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah &= ~0x80;
-        }
+       }
 
-        if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
           if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p))) {
-             if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-                 tempah |= 0x20;
+             if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+                tempah |= 0x20;
              }
-          }
-        }
+          }
+       }
 
-        SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah);
+       SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah);
 
        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;
+       if(SiS_IsDualLink(SiS_Pr)) tempah |= 0x40;
 
-        if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
           if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) {
-              tempah |= 0x40;
-                  }
-        }
+             tempah |= 0x40;
+          }
+       }
 
-        SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0C,tempah);
+       SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0C,tempah);
 
      } else {  /* LVDS */
 
-        if(HwInfo->jChipType >= SIS_315H) {
+       if(SiS_Pr->ChipType >= SIS_315H) {
 
 #ifdef SIS315H
           /* LVDS can only be slave in 8bpp modes */
@@ -2566,36 +2596,30 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
              }
           }
 
-          if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-              tempah |= 0x02;
-          }
+          if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))  tempah |= 0x02;
 
-          if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-             tempah ^= 0x01;
-          }
+          if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)        tempah ^= 0x01;
 
-          if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
-             tempah = 1;
-          }
+          if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 1;
 
-          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah);
+          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah);
 #endif
 
-        } else {
+       } else {
 
 #ifdef SIS300
           tempah = 0;
           if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
-              tempah |= 0x02;
-          }
+             tempah |= 0x02;
+          }
           tempah <<= 5;
 
-          if(SiS_Pr->SiS_VBInfo & DisableCRT2Display)  tempah = 0;
+          if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
 
           SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
 #endif
 
-        }
+       }
 
      }
 
@@ -2603,10 +2627,10 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 
   if(SiS_Pr->SiS_VBType & VB_SISVB) {
 
-     if(HwInfo->jChipType >= SIS_315H) {
+     if(SiS_Pr->ChipType >= SIS_315H) {
 
 #ifdef SIS315H
-        unsigned char bridgerev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01);
+       /* unsigned char bridgerev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01); */
 
        /* The following is nearly unpreditable and varies from machine
         * to machine. Especially the 301DH seems to be a real trouble
@@ -2619,25 +2643,28 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 
        /* 740 variants match for 30xB, 301B-DH, 30xLV */
 
-        if(!(IS_SIS740)) {
-           tempah = 0x04;                                                 /* For all bridges */
-           tempbl = 0xfb;
-           if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
-              tempah = 0x00;
-             if(SiS_IsDualEdge(SiS_Pr, HwInfo)) {
+       if(!(IS_SIS740)) {
+          tempah = 0x04;                                                  /* For all bridges */
+          tempbl = 0xfb;
+          if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+             tempah = 0x00;
+             if(SiS_IsDualEdge(SiS_Pr)) {
                 tempbl = 0xff;
              }
-           }
-           SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
+          }
+          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
        }
 
        /* The following two are responsible for eventually wrong colors
         * in TV output. The DH (VB_NoLCD) conditions are unknown; the
         * b0 was found in some 651 machine (Pim; P4_23=0xe5); the b1 version
         * in a 650 box (Jake). What is the criteria?
+        * Addendum: Another combination 651+301B-DH(b1) (Rapo) needs same
+        * treatment like the 651+301B-DH(b0) case. Seems more to be the
+        * chipset than the bridge revision.
         */
 
-       if((IS_SIS740) || (HwInfo->jChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
+       if((IS_SIS740) || (SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
           tempah = 0x30;
           tempbl = 0xc0;
           if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
@@ -2649,20 +2676,30 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
           SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,tempbl);
        } else if(SiS_Pr->SiS_VBType & VB_SIS301) {
           /* Fixes "TV-blue-bug" on 315+301 */
-          SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xcf);     /* For 301   */
+          SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xcf);      /* For 301   */
           SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
-       } else if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-          SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);      /* For 30xLV */
-          SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);
-       } else if((SiS_Pr->SiS_VBType & VB_NoLCD) && (bridgerev == 0xb0)) {
-          SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);      /* For 30xB-DH rev b0 (or "DH on 651"?) */
+       } else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
+          SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);       /* For 30xLV */
           SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);
+       } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {              /* For 301B-DH */
+          tempah = 0x30; tempah2 = 0xc0;
+          tempbl = 0xcf; tempbl2 = 0x3f;
+          if(SiS_Pr->SiS_TVBlue == 0) {
+                tempah = tempah2 = 0x00;
+          } else if(SiS_Pr->SiS_TVBlue == -1) {
+             /* Set on 651/M650, clear on 315/650 */
+             if(!(IS_SIS65x)) /* (bridgerev != 0xb0) */ {
+                tempah = tempah2 = 0x00;
+             }
+          }
+          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
+          SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
        } else {
-          tempah = 0x30; tempah2 = 0xc0;                      /* For 30xB (and 301BDH rev b1) */
+          tempah = 0x30; tempah2 = 0xc0;                      /* For 30xB, 301C */
           tempbl = 0xcf; tempbl2 = 0x3f;
           if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
              tempah = tempah2 = 0x00;
-             if(SiS_IsDualEdge(SiS_Pr, HwInfo)) {
+             if(SiS_IsDualEdge(SiS_Pr)) {
                 tempbl = tempbl2 = 0xff;
              }
           }
@@ -2676,23 +2713,23 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
           SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,0x7f,tempah);
        } else {
           tempah = 0x00;
-           tempbl = 0x7f;
-           if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
-              tempbl = 0xff;
-             if(!(SiS_IsDualEdge(SiS_Pr, HwInfo))) tempah = 0x80;
-           }
-           SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
+          tempbl = 0x7f;
+          if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+             tempbl = 0xff;
+             if(!(SiS_IsDualEdge(SiS_Pr))) tempah = 0x80;
+          }
+          SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
        }
 
 #endif /* SIS315H */
 
-     } else if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+     } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
 
 #ifdef SIS300
-        SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
+       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
 
-        if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
-           ((SiS_Pr->SiS_VBType & VB_NoLCD) &&
+       if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
+          ((SiS_Pr->SiS_VBType & VB_NoLCD) &&
            (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD))) {
           SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x23,0x7F);
        } else {
@@ -2702,9 +2739,9 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 
      }
 
-     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-        SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x0D,0x80);
-        if(SiS_Pr->SiS_VBType & VB_SIS301C) {
+     if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
+       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x0D,0x80);
+       if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
           SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3A,0xC0);
         }
      }
@@ -2712,16 +2749,16 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
   } else {  /* LVDS */
 
 #ifdef SIS315H
-     if(HwInfo->jChipType >= SIS_315H) {
+     if(SiS_Pr->ChipType >= SIS_315H) {
 
-        if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+       if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
 
-           tempah = 0x04;
+          tempah = 0x04;
           tempbl = 0xfb;
-           if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
-              tempah = 0x00;
-             if(SiS_IsDualEdge(SiS_Pr, HwInfo)) tempbl = 0xff;
-           }
+          if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+             tempah = 0x00;
+             if(SiS_IsDualEdge(SiS_Pr)) tempbl = 0xff;
+          }
           SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
 
           if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
@@ -2730,7 +2767,7 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 
           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
 
-       } else if(HwInfo->jChipType == SIS_550) {
+       } else if(SiS_Pr->ChipType == SIS_550) {
 
           SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
@@ -2748,212 +2785,120 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 /*            GET RESOLUTION DATA            */
 /*********************************************/
 
-USHORT
-SiS_GetResInfo(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex)
+unsigned short
+SiS_GetResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
 {
-  if(ModeNo <= 0x13) return((USHORT)SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo);
-  else               return((USHORT)SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO);
+   if(ModeNo <= 0x13)
+      return ((unsigned short)SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo);
+   else
+      return ((unsigned short)SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO);
 }
 
 static void
-SiS_GetCRT2ResInfo(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
-                   PSIS_HW_INFO HwInfo)
+SiS_GetCRT2ResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
 {
-  USHORT xres,yres,modeflag=0,resindex;
+   unsigned short xres, yres, modeflag=0, resindex;
 
-  if(SiS_Pr->UseCustomMode) {
-     xres = SiS_Pr->CHDisplay;
-     if(SiS_Pr->CModeFlag & HalfDCLK) xres *= 2;
-     SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
-     yres = SiS_Pr->CVDisplay;
-     if(SiS_Pr->CModeFlag & DoubleScanMode) yres *= 2;
-     SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
-     return;
-  }
-
-  resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex);
+   if(SiS_Pr->UseCustomMode) {
+      xres = SiS_Pr->CHDisplay;
+      if(SiS_Pr->CModeFlag & HalfDCLK) xres <<= 1;
+      SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
+      /* DoubleScanMode-check done in CheckCalcCustomMode()! */
+      SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = SiS_Pr->CVDisplay;
+      return;
+   }
 
-  if(ModeNo <= 0x13) {
-     xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
-     yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
-  } else {
-     xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
-     yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
-     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-  }
+   resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex);
 
-  if(!SiS_Pr->SiS_IF_DEF_DSTN && !SiS_Pr->SiS_IF_DEF_FSTN) {
+   if(ModeNo <= 0x13) {
+      xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
+      yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
+   } else {
+      xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
+      yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
+      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+   }
 
-     if((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
-        if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
-           if(yres == 350) yres = 400;
-        }
-        if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
-          if(ModeNo == 0x12) yres = 400;
-        }
-     }
+   if(!SiS_Pr->SiS_IF_DEF_DSTN && !SiS_Pr->SiS_IF_DEF_FSTN) {
 
-     if(modeflag & HalfDCLK)       xres *= 2;
-     if(modeflag & DoubleScanMode) yres *= 2;
+      if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
+        if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
+           if(yres == 350) yres = 400;
+        }
+        if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
+           if(ModeNo == 0x12) yres = 400;
+        }
+      }
 
-  }
+      if(modeflag & HalfDCLK)       xres <<= 1;
+      if(modeflag & DoubleScanMode) yres <<= 1;
 
-  if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
+   }
 
-#if 0
-        if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCDA | SetCRT2ToLCD | SetCRT2ToHiVision)) {
-           if(xres == 720) xres = 640;
-       }
-#endif
+   if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
 
-       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-          switch(SiS_Pr->SiS_LCDResInfo) {
+      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+        switch(SiS_Pr->SiS_LCDResInfo) {
           case Panel_1024x768:
              if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
-                 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
-                   if(yres == 350) yres = 357;
-                   if(yres == 400) yres = 420;
-                   if(yres == 480) yres = 525;
-                }
-             }
+                if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
+                   if(yres == 350) yres = 357;
+                   if(yres == 400) yres = 420;
+                   if(yres == 480) yres = 525;
+                }
+             }
              break;
           case Panel_1280x1024:
              if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
                 /* BIOS bug - does this regardless of scaling */
-                if(yres == 400) yres = 405;
+                if(yres == 400) yres = 405;
+             }
+             if(yres == 350) yres = 360;
+             if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
+                if(yres == 360) yres = 375;
              }
-             if(yres == 350) yres = 360;
-             if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
-                 if(yres == 360) yres = 375;
-             }
              break;
           case Panel_1600x1200:
              if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
-                if(yres == 1024) yres = 1056;
-             }
+                if(yres == 1024) yres = 1056;
+             }
              break;
-          }
-       }
+        }
+      }
 
-  } else {
+   } else {
 
-     if(SiS_Pr->SiS_VBType & VB_SISVB) {
-        if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVision)) {
-           if(xres == 720) xres = 640;
-       }
-     } else if(xres == 720) xres = 640;
+      if(SiS_Pr->SiS_VBType & VB_SISVB) {
+        if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVision)) {
+           if(xres == 720) xres = 640;
+        }
+      } else if(xres == 720) xres = 640;
 
-     if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
-       yres = 400;
-        if(HwInfo->jChipType >= SIS_315H) {
-           if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
-        } else {
-           if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
-        }
-        if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN)  yres = 480;
-     }
+      if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
+        yres = 400;
+        if(SiS_Pr->ChipType >= SIS_315H) {
+           if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
+        } else {
+           if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
+        }
+        if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) yres = 480;
+      }
 
-  }
-  SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
-  SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
+   }
+   SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
+   SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
 }
 
 /*********************************************/
 /*           GET CRT2 TIMING DATA            */
 /*********************************************/
 
-static BOOLEAN
-SiS_GetLVDSCRT1Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
-                  USHORT RefreshRateTableIndex, USHORT *ResIndex,
-                  USHORT *DisplayType)
- {
-  USHORT modeflag=0;
-
-  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-     if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
-        if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return FALSE;
-     }
-  } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
-     if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))    return FALSE;
-  } else
-     return FALSE;
-
-  if(ModeNo <= 0x13) {
-     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-     (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-  } else {
-     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-     (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-  }
-
-  (*ResIndex) &= 0x3F;
-
-  if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
-     (*DisplayType) = 18;
-     if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
-     if(SiS_Pr->SiS_TVMode & TVSetPAL) {
-       (*DisplayType) += 2;
-       if(SiS_Pr->SiS_ModeType > ModeVGA) {
-          if(SiS_Pr->SiS_CHSOverScan) (*DisplayType) = 99;
-       }
-       if(SiS_Pr->SiS_TVMode & TVSetPALM) {
-          (*DisplayType) = 18;  /* PALM uses NTSC data */
-          if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
-       } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
-          (*DisplayType) = 20;  /* PALN uses PAL data  */
-          if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
-       }
-     }
-  } else {
-     switch(SiS_Pr->SiS_LCDResInfo) {
-     case Panel_640x480:   (*DisplayType) = 50; break;
-     case Panel_640x480_2: (*DisplayType) = 52; break;
-     case Panel_640x480_3: (*DisplayType) = 54; break;
-     case Panel_800x600:   (*DisplayType) =  0; break;
-     case Panel_1024x600:  (*DisplayType) = 23; break;
-     case Panel_1024x768:  (*DisplayType) =  4; break;
-     case Panel_1152x768:  (*DisplayType) = 27; break;
-     case Panel_1280x768:  (*DisplayType) = 40; break;
-     case Panel_1280x1024: (*DisplayType) =  8; break;
-     case Panel_1400x1050: (*DisplayType) = 14; break;
-     case Panel_1600x1200: (*DisplayType) = 36; break;
-     default: return FALSE;
-     }
-
-     if(modeflag & HalfDCLK) (*DisplayType)++;
-
-     switch(SiS_Pr->SiS_LCDResInfo) {
-     case Panel_640x480:
-     case Panel_640x480_2:
-     case Panel_640x480_3:
-        break;
-     default:
-        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) (*DisplayType) += 2;
-     }
-
-     if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
-        (*DisplayType) = 12;
-       if(modeflag & HalfDCLK) (*DisplayType)++;
-     }
-  }
-
-#if 0
-  if(SiS_Pr->SiS_IF_DEF_FSTN) {
-     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel320x480){
-        (*DisplayType) = 22;
-     }
-  }
-#endif
-
-  return TRUE;
-}
-
 static void
-SiS_GetCRT2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
-              USHORT RefreshRateTableIndex,USHORT *CRT2Index,USHORT *ResIndex,
-              PSIS_HW_INFO HwInfo)
+SiS_GetCRT2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
+              unsigned short RefreshRateTableIndex, unsigned short *CRT2Index,
+              unsigned short *ResIndex)
 {
-  USHORT tempbx=0,tempal=0,resinfo=0;
+  unsigned short tempbx=0, tempal=0, resinfo=0;
 
   if(ModeNo <= 0x13) {
      tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
@@ -2966,18 +2911,20 @@ SiS_GetCRT2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
 
      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {                            /* LCD */
 
-        tempbx = SiS_Pr->SiS_LCDResInfo;
+       tempbx = SiS_Pr->SiS_LCDResInfo;
        if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 32;
 
+       /* patch index */
        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)) {
+                 (SiS_Pr->SiS_LCDResInfo == Panel_1280x800_2) ||
+                 (SiS_Pr->SiS_LCDResInfo == Panel_1280x854)) {
           if     (resinfo == SIS_RI_1280x768)  tempal =  9;
        }
 
-       if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+       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 */
@@ -2991,8 +2938,8 @@ SiS_GetCRT2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
        if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
           if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
              if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
-                tempbx = 200;
-                if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
+                tempbx = 200;
+                if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
              }
           }
        }
@@ -3000,23 +2947,23 @@ SiS_GetCRT2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
 
      } else {                                                  /* TV */
 
-       if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
-           /* if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_TVMode &= (~TVSetTVSimuMode); */
-           tempbx = 2;
-           if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+       if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
+          /* if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_TVMode &= (~TVSetTVSimuMode); */
+          tempbx = 2;
+          if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
              tempbx = 13;
-              if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) tempbx = 14;
-           }
+             if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) tempbx = 14;
+          }
        } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
-          if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)      tempbx = 7;
-          else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempbx = 6;
-          else                                         tempbx = 5;
-          if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)     tempbx += 5;
-               } else {
-           if(SiS_Pr->SiS_TVMode & TVSetPAL)           tempbx = 3;
-           else                                        tempbx = 4;
-           if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)    tempbx += 5;
-               }
+          if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)      tempbx = 7;
+          else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempbx = 6;
+          else                                         tempbx = 5;
+          if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)     tempbx += 5;
+       } else {
+          if(SiS_Pr->SiS_TVMode & TVSetPAL)            tempbx = 3;
+          else                                         tempbx = 4;
+          if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)     tempbx += 5;
+       }
 
      }
 
@@ -3024,26 +2971,34 @@ SiS_GetCRT2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
 
      if(ModeNo > 0x13) {
         if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) {
-          if(tempal == 6) tempal = 7;
-           if((resinfo == SIS_RI_720x480) ||
-             (resinfo == SIS_RI_720x576) ||
-             (resinfo == SIS_RI_768x576)) {
+          switch(resinfo) {
+          case SIS_RI_720x480:
              tempal = 6;
-             if(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetPALN)) {
-                if(resinfo == SIS_RI_720x480) tempal = 9;
+             if(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetPALN))   tempal = 9;
+             break;
+          case SIS_RI_720x576:
+          case SIS_RI_768x576:
+          case SIS_RI_1024x576: /* Not in NTSC or YPBPR mode (except 1080i)! */
+             tempal = 6;
+             if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
+                if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)        tempal = 8;
              }
-          }
-          if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
-              if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
-                if(resinfo == SIS_RI_1024x768) tempal = 8;
+             break;
+          case SIS_RI_800x480:
+             tempal = 4;
+             break;
+          case SIS_RI_512x384:
+          case SIS_RI_1024x768:
+             tempal = 7;
+             if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
+                if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)        tempal = 8;
              }
-             if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
-                if((resinfo == SIS_RI_720x576) ||
-                   (resinfo == SIS_RI_768x576)) {
-                   tempal = 8;
-                }
-                if(resinfo == SIS_RI_1280x720) tempal = 9;
+             break;
+          case SIS_RI_1280x720:
+             if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
+                if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)        tempal = 9;
              }
+             break;
           }
        }
      }
@@ -3056,65 +3011,60 @@ SiS_GetCRT2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
      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) {
-          tempbx += 2;
+       tempbx = 90;
+       if(SiS_Pr->SiS_TVMode & TVSetPAL) {
+          tempbx = 92;
           if(SiS_Pr->SiS_ModeType > ModeVGA) {
              if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
           }
-          if(SiS_Pr->SiS_TVMode & TVSetPALM) {
-             tempbx = 90;
-             if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
-          } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
-             tempbx = 92;
-             if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
-          }
-        }
+          if(SiS_Pr->SiS_TVMode & TVSetPALM)      tempbx = 94;
+          else if(SiS_Pr->SiS_TVMode & TVSetPALN) tempbx = 96;
+       }
+       if(tempbx != 99) {
+          if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx++;
+       }
 
      } else {
 
-        switch(SiS_Pr->SiS_LCDResInfo) {
-       case Panel_640x480:   tempbx = 6;  break;
-       case Panel_640x480_2:
-       case Panel_640x480_3: tempbx = 30; break;
-       case Panel_800x600:   tempbx = 0;  break;
-       case Panel_1024x600:  tempbx = 15; break;
-       case Panel_1024x768:  tempbx = 2;  break;
-       case Panel_1152x768:  tempbx = 17; break;
-       case Panel_1280x768:  tempbx = 18; break;
-       case Panel_1280x1024: tempbx = 4;  break;
-       case Panel_1400x1050: tempbx = 8;  break;
-       case Panel_1600x1200: tempbx = 21; break;
+       switch(SiS_Pr->SiS_LCDResInfo) {
+       case Panel_640x480:   tempbx = 12; break;
+       case Panel_320x240_1: tempbx = 10; break;
+       case Panel_320x240_2:
+       case Panel_320x240_3: tempbx = 14; break;
+       case Panel_800x600:   tempbx = 16; break;
+       case Panel_1024x600:  tempbx = 18; break;
+       case Panel_1152x768:
+       case Panel_1024x768:  tempbx = 20; break;
+       case Panel_1280x768:  tempbx = 22; break;
+       case Panel_1280x1024: tempbx = 24; break;
+       case Panel_1400x1050: tempbx = 26; break;
+       case Panel_1600x1200: tempbx = 28; break;
+#ifdef SIS300
        case Panel_Barco1366: tempbx = 80; break;
+#endif
        }
 
        switch(SiS_Pr->SiS_LCDResInfo) {
+       case Panel_320x240_1:
+       case Panel_320x240_2:
+       case Panel_320x240_3:
        case Panel_640x480:
-       case Panel_640x480_2:
-       case Panel_640x480_3:
           break;
        default:
           if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
        }
 
-       if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempbx = 7;
+       if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempbx = 30;
 
+#ifdef SIS300
        if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
           tempbx = 82;
           if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
-       } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
+       } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
           tempbx = 84;
           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;
-          }
-        }
+#endif
 
      }
 
@@ -3124,12 +3074,11 @@ SiS_GetCRT2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
 }
 
 static void
-SiS_GetRAMDAC2DATA(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
-                   USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo)
+SiS_GetRAMDAC2DATA(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
+               unsigned short RefreshRateTableIndex)
 {
-  USHORT tempax=0,tempbx=0;
-  USHORT temp1=0,modeflag=0,tempcx=0;
-  USHORT index;
+  unsigned short tempax=0, tempbx=0, index, dotclock;
+  unsigned short temp1=0, modeflag=0, tempcx=0;
 
   SiS_Pr->SiS_RVBHCMAX  = 1;
   SiS_Pr->SiS_RVBHCFACT = 1;
@@ -3143,10 +3092,12 @@ SiS_GetRAMDAC2DATA(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
      tempbx = SiS_Pr->SiS_StandTable[index].CRTC[6];
      temp1 = SiS_Pr->SiS_StandTable[index].CRTC[7];
 
+     dotclock = (modeflag & Charx8Dot) ? 8 : 9;
+
   } else {
 
      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-     index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+     index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);
 
      tempax = SiS_Pr->SiS_CRT1Table[index].CR[0];
      tempax |= (SiS_Pr->SiS_CRT1Table[index].CR[14] << 8);
@@ -3158,22 +3109,16 @@ SiS_GetRAMDAC2DATA(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
      tempbx |= tempcx;
      temp1  = SiS_Pr->SiS_CRT1Table[index].CR[7];
 
+     dotclock = 8;
+
   }
 
   if(temp1 & 0x01) tempbx |= 0x0100;
   if(temp1 & 0x20) tempbx |= 0x0200;
 
   tempax += 5;
-
-  /* Charx8Dot is no more used (and assumed), so we set it */
-  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-     modeflag |= Charx8Dot;
-  }
-
-  if(modeflag & Charx8Dot) tempax *= 8;
-  else                     tempax *= 9;
-
-  if(modeflag & HalfDCLK)  tempax <<= 1;
+  tempax *= dotclock;
+  if(modeflag & HalfDCLK) tempax <<= 1;
 
   tempbx++;
 
@@ -3182,13 +3127,56 @@ SiS_GetRAMDAC2DATA(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
 }
 
 static void
-SiS_GetCRT2DataLVDS(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
-                    USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
+SiS_CalcPanelLinkTiming(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+               unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex)
+{
+   unsigned short ResIndex;
+
+   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+      if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
+        if(SiS_Pr->UseCustomMode) {
+           ResIndex = SiS_Pr->CHTotal;
+           if(SiS_Pr->CModeFlag & HalfDCLK) ResIndex <<= 1;
+           SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = ResIndex;
+           SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
+        } else {
+           if(ModeNo < 0x13) {
+              ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+           } else {
+              ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
+           }
+           if(ResIndex == 0x09) {
+              if(SiS_Pr->Alternate1600x1200)        ResIndex = 0x20; /* 1600x1200 LCDA */
+              else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) ResIndex = 0x21; /* 1600x1200 LVDS */
+           }
+           SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAHT;
+           SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAVT;
+           SiS_Pr->SiS_HT    = SiS_Pr->SiS_NoScaleData[ResIndex].LCDHT;
+           SiS_Pr->SiS_VT    = SiS_Pr->SiS_NoScaleData[ResIndex].LCDVT;
+        }
+      } else {
+        SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
+        SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
+      }
+   } else {
+      /* This handles custom modes and custom panels */
+      SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
+      SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
+      SiS_Pr->SiS_HT  = SiS_Pr->PanelHT;
+      SiS_Pr->SiS_VT  = SiS_Pr->PanelVT;
+      SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT - (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE);
+      SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT - (SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE);
+   }
+}
+
+static void
+SiS_GetCRT2DataLVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
+                    unsigned short RefreshRateTableIndex)
 {
-   USHORT CRT2Index, ResIndex;
-   const SiS_LVDSDataStruct *LVDSData = NULL;
+   unsigned short CRT2Index, ResIndex, backup;
+   const struct SiS_LVDSData *LVDSData = NULL;
 
-   SiS_GetCRT2ResInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
+   SiS_GetCRT2ResInfo(SiS_Pr, ModeNo, ModeIdIndex);
 
    if(SiS_Pr->SiS_VBType & VB_SISVB) {
       SiS_Pr->SiS_RVBHCMAX  = 1;
@@ -3199,133 +3187,94 @@ SiS_GetCRT2DataLVDS(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
       SiS_Pr->SiS_RY2COE = 0;
       SiS_Pr->SiS_RY3COE = 0;
       SiS_Pr->SiS_RY4COE = 0;
+      SiS_Pr->SiS_RVBHRS2 = 0;
    }
 
    if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
 
 #ifdef SIS315H
-      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
-         if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
-           if(SiS_Pr->UseCustomMode) {
-              SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->CHTotal;
-              SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
-           } else {
-              if(ModeNo < 0x13) {
-                 ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-              } else {
-                 ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
-              }
-              SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAHT;
-               SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAVT;
-               SiS_Pr->SiS_HT    = SiS_Pr->SiS_NoScaleData[ResIndex].LCDHT;
-               SiS_Pr->SiS_VT    = SiS_Pr->SiS_NoScaleData[ResIndex].LCDVT;
-           }
-        } else {
-           SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
-            SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
-        }
-      } else {
-        /* This handles custom modes and custom panels */
-        SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
-         SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
-         SiS_Pr->SiS_HT  = SiS_Pr->PanelHT;
-         SiS_Pr->SiS_VT  = SiS_Pr->PanelVT;
-        SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT - (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE);
-        SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT - (SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE);
-      }
-
-      SiS_CalcLCDACRT1Timing(SiS_Pr,ModeNo,ModeIdIndex);
-
+      SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
+      SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
 #endif
 
    } else {
 
       /* 301BDH needs LVDS Data */
+      backup = SiS_Pr->SiS_IF_DEF_LVDS;
       if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
         SiS_Pr->SiS_IF_DEF_LVDS = 1;
       }
 
       SiS_GetCRT2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
-                               &CRT2Index, &ResIndex, HwInfo);
+                                           &CRT2Index, &ResIndex);
 
-      /* 301BDH needs LVDS Data */
-      if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
-         SiS_Pr->SiS_IF_DEF_LVDS = 0;
-      }
+      SiS_Pr->SiS_IF_DEF_LVDS = backup;
 
-      switch (CRT2Index) {
-        case  0: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1;    break;
-        case  1: LVDSData = SiS_Pr->SiS_LVDS800x600Data_2;    break;
-        case  2: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1;   break;
-        case  3: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_2;   break;
-        case  4: LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_1;  break;
-        case  5: LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_2;  break;
-        case  6: LVDSData = SiS_Pr->SiS_LVDS640x480Data_1;    break;
-         case  7: LVDSData = SiS_Pr->SiS_LVDSXXXxXXXData_1;    break;
-        case  8: LVDSData = SiS_Pr->SiS_LVDS1400x1050Data_1;  break;
-        case  9: LVDSData = SiS_Pr->SiS_LVDS1400x1050Data_2;  break;
-        case 10: LVDSData = SiS_Pr->SiS_CHTVUNTSCData;        break;
-        case 11: LVDSData = SiS_Pr->SiS_CHTVONTSCData;        break;
-        case 12: LVDSData = SiS_Pr->SiS_CHTVUPALData;         break;
-        case 13: LVDSData = SiS_Pr->SiS_CHTVOPALData;         break;
-        case 14: LVDSData = SiS_Pr->SiS_LVDS320x480Data_1;    break;
-        case 15: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1;   break;
-        case 16: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_2;   break;
-        case 17: LVDSData = SiS_Pr->SiS_LVDS1152x768Data_1;   break;
-        case 18: LVDSData = SiS_Pr->SiS_LVDS1152x768Data_2;   break;
-        case 19: LVDSData = SiS_Pr->SiS_LVDS1280x768Data_1;   break;
-        case 20: LVDSData = SiS_Pr->SiS_LVDS1280x768Data_2;   break;
-        case 21: LVDSData = SiS_Pr->SiS_LVDS1600x1200Data_1;  break;
-        case 22: LVDSData = SiS_Pr->SiS_LVDS1600x1200Data_2;  break;
-        case 30: LVDSData = SiS_Pr->SiS_LVDS640x480Data_2;    break;
+      switch(CRT2Index) {
+        case 10: LVDSData = SiS_Pr->SiS_LVDS320x240Data_1;    break;
+        case 14: LVDSData = SiS_Pr->SiS_LVDS320x240Data_2;    break;
+        case 12: LVDSData = SiS_Pr->SiS_LVDS640x480Data_1;    break;
+        case 16: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1;    break;
+        case 18: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1;   break;
+        case 20: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1;   break;
+#ifdef SIS300
         case 80: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1;  break;
         case 81: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2;  break;
         case 82: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1;  break;
-        case 83: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_2;  break;
         case 84: LVDSData = SiS_Pr->SiS_LVDS848x480Data_1;    break;
         case 85: LVDSData = SiS_Pr->SiS_LVDS848x480Data_2;    break;
-        case 90: LVDSData = SiS_Pr->SiS_CHTVUPALMData;        break;
-        case 91: LVDSData = SiS_Pr->SiS_CHTVOPALMData;        break;
-        case 92: LVDSData = SiS_Pr->SiS_CHTVUPALNData;        break;
-        case 93: LVDSData = SiS_Pr->SiS_CHTVOPALNData;        break;
-        case 99: LVDSData = SiS_Pr->SiS_CHTVSOPALData;        break;  /* Super Overscan */
-        default: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1;   break;
+#endif
+        case 90: LVDSData = SiS_Pr->SiS_CHTVUNTSCData;        break;
+        case 91: LVDSData = SiS_Pr->SiS_CHTVONTSCData;        break;
+        case 92: LVDSData = SiS_Pr->SiS_CHTVUPALData;         break;
+        case 93: LVDSData = SiS_Pr->SiS_CHTVOPALData;         break;
+        case 94: LVDSData = SiS_Pr->SiS_CHTVUPALMData;        break;
+        case 95: LVDSData = SiS_Pr->SiS_CHTVOPALMData;        break;
+        case 96: LVDSData = SiS_Pr->SiS_CHTVUPALNData;        break;
+        case 97: LVDSData = SiS_Pr->SiS_CHTVOPALNData;        break;
+        case 99: LVDSData = SiS_Pr->SiS_CHTVSOPALData;        break;
       }
 
-      SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT;
-      SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT;
-      SiS_Pr->SiS_HT    = (LVDSData+ResIndex)->LCDHT;
-      SiS_Pr->SiS_VT    = (LVDSData+ResIndex)->LCDVT;
-
-      if(!(SiS_Pr->SiS_VBType & VB_SISVB)) {
-         if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
-            if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
-              SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
-               SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
-              if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
-                 if(ResIndex < 0x08) {
-                    SiS_Pr->SiS_HDE = 1280;
-                     SiS_Pr->SiS_VDE = 1024;
-                  }
-               }
-            }
+      if(LVDSData) {
+        SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT;
+        SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT;
+        SiS_Pr->SiS_HT    = (LVDSData+ResIndex)->LCDHT;
+        SiS_Pr->SiS_VT    = (LVDSData+ResIndex)->LCDVT;
+      } else {
+        SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
+      }
+
+      if( (!(SiS_Pr->SiS_VBType & VB_SISVB)) &&
+         (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
+         (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) ) {
+        if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ||
+            (SiS_Pr->SiS_SetFlag & SetDOSMode) ) {
+           SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
+            SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
+#ifdef SIS300
+           if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
+              if(ResIndex < 0x08) {
+                 SiS_Pr->SiS_HDE = 1280;
+                 SiS_Pr->SiS_VDE = 1024;
+              }
+           }
+#endif
          }
       }
    }
 }
 
 static void
-SiS_GetCRT2Data301(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
-                   USHORT RefreshRateTableIndex,
-                  PSIS_HW_INFO HwInfo)
-{
-  UCHAR  *ROMAddr = NULL;
-  USHORT tempax,tempbx,modeflag,romptr=0;
-  USHORT resinfo,CRT2Index,ResIndex;
-  const SiS_LCDDataStruct *LCDPtr = NULL;
-  const SiS_TVDataStruct  *TVPtr  = NULL;
+SiS_GetCRT2Data301(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
+               unsigned short RefreshRateTableIndex)
+{
+  unsigned char  *ROMAddr = NULL;
+  unsigned short tempax, tempbx, modeflag, romptr=0;
+  unsigned short resinfo, CRT2Index, ResIndex;
+  const struct SiS_LCDData *LCDPtr = NULL;
+  const struct SiS_TVData  *TVPtr  = NULL;
 #ifdef SIS315H
-  SHORT  resinfo661;
+  short resinfo661;
 #endif
 
   if(ModeNo <= 0x13) {
@@ -3340,67 +3289,69 @@ SiS_GetCRT2Data301(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
 #ifdef SIS315H
      resinfo661 = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].ROMMODEIDX661;
      if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)   &&
-         (SiS_Pr->SiS_SetFlag & LCDVESATiming) &&
-         (resinfo661 >= 0)                     &&
+        (SiS_Pr->SiS_SetFlag & LCDVESATiming) &&
+        (resinfo661 >= 0)                     &&
         (SiS_Pr->SiS_NeedRomModeData) ) {
-        if((ROMAddr = GetLCDStructPtr661(SiS_Pr, HwInfo))) {
+       if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
           if((romptr = (SISGETROMW(21)))) {
-              romptr += (resinfo661 * 10);
-             ROMAddr = HwInfo->pjVirtualRomBase;
+             romptr += (resinfo661 * 10);
+             ROMAddr = SiS_Pr->VirtualRomBase;
           }
        }
      }
 #endif
   }
-  
+
   SiS_Pr->SiS_NewFlickerMode = 0;
   SiS_Pr->SiS_RVBHRS = 50;
   SiS_Pr->SiS_RY1COE = 0;
   SiS_Pr->SiS_RY2COE = 0;
   SiS_Pr->SiS_RY3COE = 0;
   SiS_Pr->SiS_RY4COE = 0;
+  SiS_Pr->SiS_RVBHRS2 = 0;
 
-  SiS_GetCRT2ResInfo(SiS_Pr,ModeNo,ModeIdIndex,HwInfo);
+  SiS_GetCRT2ResInfo(SiS_Pr,ModeNo,ModeIdIndex);
 
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC){
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
 
      if(SiS_Pr->UseCustomMode) {
 
-        SiS_Pr->SiS_RVBHCMAX  = 1;
-        SiS_Pr->SiS_RVBHCFACT = 1;
-        SiS_Pr->SiS_VGAHT     = SiS_Pr->CHTotal;
-        SiS_Pr->SiS_VGAVT     = SiS_Pr->CVTotal;
-        SiS_Pr->SiS_HT        = SiS_Pr->CHTotal;
-        SiS_Pr->SiS_VT        = SiS_Pr->CVTotal;
+       SiS_Pr->SiS_RVBHCMAX  = 1;
+       SiS_Pr->SiS_RVBHCFACT = 1;
        SiS_Pr->SiS_HDE       = SiS_Pr->SiS_VGAHDE;
-        SiS_Pr->SiS_VDE       = SiS_Pr->SiS_VGAVDE;
+       SiS_Pr->SiS_VDE       = SiS_Pr->SiS_VGAVDE;
+
+       tempax = SiS_Pr->CHTotal;
+       if(modeflag & HalfDCLK) tempax <<= 1;
+       SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
+       SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
 
      } else {
 
-        SiS_GetRAMDAC2DATA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
+       SiS_GetRAMDAC2DATA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
 
      }
 
   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
 
      SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
-                    &CRT2Index,&ResIndex,HwInfo);
+                   &CRT2Index,&ResIndex);
 
      switch(CRT2Index) {
-        case  2: TVPtr = SiS_Pr->SiS_ExtHiTVData;   break;
-        case  3: TVPtr = SiS_Pr->SiS_ExtPALData;    break;
-        case  4: TVPtr = SiS_Pr->SiS_ExtNTSCData;   break;
-        case  5: TVPtr = SiS_Pr->SiS_Ext525iData;   break;
-        case  6: TVPtr = SiS_Pr->SiS_Ext525pData;   break;
-        case  7: TVPtr = SiS_Pr->SiS_Ext750pData;   break;
-        case  8: TVPtr = SiS_Pr->SiS_StPALData;     break;
-        case  9: TVPtr = SiS_Pr->SiS_StNTSCData;    break;
-        case 10: TVPtr = SiS_Pr->SiS_St525iData;    break;
-        case 11: TVPtr = SiS_Pr->SiS_St525pData;    break;
-        case 12: TVPtr = SiS_Pr->SiS_St750pData;    break;
-        case 13: TVPtr = SiS_Pr->SiS_St1HiTVData;   break;
-        case 14: TVPtr = SiS_Pr->SiS_St2HiTVData;   break;
-        default: TVPtr = SiS_Pr->SiS_StPALData;     break;
+       case  2: TVPtr = SiS_Pr->SiS_ExtHiTVData;   break;
+       case  3: TVPtr = SiS_Pr->SiS_ExtPALData;    break;
+       case  4: TVPtr = SiS_Pr->SiS_ExtNTSCData;   break;
+       case  5: TVPtr = SiS_Pr->SiS_Ext525iData;   break;
+       case  6: TVPtr = SiS_Pr->SiS_Ext525pData;   break;
+       case  7: TVPtr = SiS_Pr->SiS_Ext750pData;   break;
+       case  8: TVPtr = SiS_Pr->SiS_StPALData;     break;
+       case  9: TVPtr = SiS_Pr->SiS_StNTSCData;    break;
+       case 10: TVPtr = SiS_Pr->SiS_St525iData;    break;
+       case 11: TVPtr = SiS_Pr->SiS_St525pData;    break;
+       case 12: TVPtr = SiS_Pr->SiS_St750pData;    break;
+       case 13: TVPtr = SiS_Pr->SiS_St1HiTVData;   break;
+       case 14: TVPtr = SiS_Pr->SiS_St2HiTVData;   break;
+       default: TVPtr = SiS_Pr->SiS_StPALData;     break;
      }
 
      SiS_Pr->SiS_RVBHCMAX  = (TVPtr+ResIndex)->RVBHCMAX;
@@ -3409,73 +3360,77 @@ SiS_GetCRT2Data301(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
      SiS_Pr->SiS_VGAVT     = (TVPtr+ResIndex)->VGAVT;
      SiS_Pr->SiS_HDE       = (TVPtr+ResIndex)->TVHDE;
      SiS_Pr->SiS_VDE       = (TVPtr+ResIndex)->TVVDE;
-     SiS_Pr->SiS_RVBHRS    = (TVPtr+ResIndex)->RVBHRS;
-     SiS_Pr->SiS_NewFlickerMode = (TVPtr+ResIndex)->FlickerMode;
+     SiS_Pr->SiS_RVBHRS2   = (TVPtr+ResIndex)->RVBHRS2 & 0x0fff;
      if(modeflag & HalfDCLK) {
-        SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->HALFRVBHRS;
+       SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->HALFRVBHRS;
+       if(SiS_Pr->SiS_RVBHRS2) {
+          SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
+          tempax = ((TVPtr+ResIndex)->RVBHRS2 >> 12) & 0x07;
+          if((TVPtr+ResIndex)->RVBHRS2 & 0x8000) SiS_Pr->SiS_RVBHRS2 -= tempax;
+          else                                   SiS_Pr->SiS_RVBHRS2 += tempax;
+       }
+     } else {
+       SiS_Pr->SiS_RVBHRS    = (TVPtr+ResIndex)->RVBHRS;
      }
+     SiS_Pr->SiS_NewFlickerMode = ((TVPtr+ResIndex)->FlickerMode) << 7;
 
      if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
 
-        if((resinfo == SIS_RI_1024x768)  ||
-           (resinfo == SIS_RI_1280x1024) ||
-           (resinfo == SIS_RI_1280x720)) {
+       if((resinfo == SIS_RI_960x600)   ||
+          (resinfo == SIS_RI_1024x768)  ||
+          (resinfo == SIS_RI_1280x1024) ||
+          (resinfo == SIS_RI_1280x720)) {
           SiS_Pr->SiS_NewFlickerMode = 0x40;
        }
 
-        if(SiS_Pr->SiS_VGAVDE == 350) SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
+       if(SiS_Pr->SiS_VGAVDE == 350) SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
 
-        SiS_Pr->SiS_HT = ExtHiTVHT;
-        SiS_Pr->SiS_VT = ExtHiTVVT;
-        if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-           if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
-              SiS_Pr->SiS_HT = StHiTVHT;
-              SiS_Pr->SiS_VT = StHiTVVT;
-#if 0
-              if(!(modeflag & Charx8Dot)) {
-                 SiS_Pr->SiS_HT = StHiTextTVHT;
-                 SiS_Pr->SiS_VT = StHiTextTVVT;
-              }
-#endif
-           }
-        }
+       SiS_Pr->SiS_HT = ExtHiTVHT;
+       SiS_Pr->SiS_VT = ExtHiTVVT;
+       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+          if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
+             SiS_Pr->SiS_HT = StHiTVHT;
+             SiS_Pr->SiS_VT = StHiTVVT;
+          }
+       }
 
      } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
 
-        if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
-           SiS_Pr->SiS_HT = 1650;
-           SiS_Pr->SiS_VT = 750;
+       if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
+          SiS_Pr->SiS_HT = 1650;
+          SiS_Pr->SiS_VT = 750;
        } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
           SiS_Pr->SiS_HT = NTSCHT;
+          if(SiS_Pr->SiS_TVMode & TVSet525p1024) SiS_Pr->SiS_HT = NTSC2HT;
           SiS_Pr->SiS_VT = NTSCVT;
-        } else {
-           SiS_Pr->SiS_HT = NTSCHT;
+       } else {
+          SiS_Pr->SiS_HT = NTSCHT;
           if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
-           SiS_Pr->SiS_VT = NTSCVT;
-        }
+          SiS_Pr->SiS_VT = NTSCVT;
+       }
 
      } else {
 
-        SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
-        SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
-        SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
-        SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
+       SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
+       SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
+       SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
+       SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
 
-        if(modeflag & HalfDCLK) {
-           SiS_Pr->SiS_RY1COE = 0x00;
-           SiS_Pr->SiS_RY2COE = 0xf4;
-           SiS_Pr->SiS_RY3COE = 0x10;
-           SiS_Pr->SiS_RY4COE = 0x38;
-        }
+       if(modeflag & HalfDCLK) {
+          SiS_Pr->SiS_RY1COE = 0x00;
+          SiS_Pr->SiS_RY2COE = 0xf4;
+          SiS_Pr->SiS_RY3COE = 0x10;
+          SiS_Pr->SiS_RY4COE = 0x38;
+       }
 
-        if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
-           SiS_Pr->SiS_HT = NTSCHT;
+       if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
+          SiS_Pr->SiS_HT = NTSCHT;
           if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
-           SiS_Pr->SiS_VT = NTSCVT;
-        } else {
-           SiS_Pr->SiS_HT = PALHT;
-           SiS_Pr->SiS_VT = PALVT;
-        }
+          SiS_Pr->SiS_VT = NTSCVT;
+       } else {
+          SiS_Pr->SiS_HT = PALHT;
+          SiS_Pr->SiS_VT = PALVT;
+       }
 
      }
 
@@ -3486,42 +3441,53 @@ SiS_GetCRT2Data301(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
 
      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_VDE   = SiS_Pr->SiS_VGAVDE;
+
+       tempax = SiS_Pr->CHTotal;
+       if(modeflag & HalfDCLK) tempax <<= 1;
+       SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
+       SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
 
      } else {
 
-        BOOLEAN gotit = FALSE;
+       BOOLEAN gotit = FALSE;
 
-        if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
+       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) ) {
 
 #ifdef SIS315H
           SiS_Pr->SiS_RVBHCMAX  = ROMAddr[romptr];
-           SiS_Pr->SiS_RVBHCFACT = ROMAddr[romptr+1];
-           SiS_Pr->SiS_VGAHT     = ROMAddr[romptr+2] | ((ROMAddr[romptr+3] & 0x0f) << 8);
-           SiS_Pr->SiS_VGAVT     = ROMAddr[romptr+4] | ((ROMAddr[romptr+3] & 0xf0) << 4);
-           SiS_Pr->SiS_HT        = ROMAddr[romptr+5] | ((ROMAddr[romptr+6] & 0x0f) << 8);
-           SiS_Pr->SiS_VT        = ROMAddr[romptr+7] | ((ROMAddr[romptr+6] & 0xf0) << 4);
+          SiS_Pr->SiS_RVBHCFACT = ROMAddr[romptr+1];
+          SiS_Pr->SiS_VGAHT     = ROMAddr[romptr+2] | ((ROMAddr[romptr+3] & 0x0f) << 8);
+          SiS_Pr->SiS_VGAVT     = (ROMAddr[romptr+4] << 4) | ((ROMAddr[romptr+3] & 0xf0) >> 4);
+          SiS_Pr->SiS_HT        = ROMAddr[romptr+5] | ((ROMAddr[romptr+6] & 0x0f) << 8);
+          SiS_Pr->SiS_VT        = (ROMAddr[romptr+7] << 4) | ((ROMAddr[romptr+6] & 0xf0) >> 4);
+          SiS_Pr->SiS_RVBHRS2   = ROMAddr[romptr+8] | ((ROMAddr[romptr+9] & 0x0f) << 8);
+          if((SiS_Pr->SiS_RVBHRS2) && (modeflag & HalfDCLK)) {
+             SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
+             tempax = (ROMAddr[romptr+9] >> 4) & 0x07;
+             if(ROMAddr[romptr+9] & 0x80) SiS_Pr->SiS_RVBHRS2 -= tempax;
+             else                         SiS_Pr->SiS_RVBHRS2 += tempax;
+          }
           if(SiS_Pr->SiS_VGAHT) gotit = TRUE;
           else {
              SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
              SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
+             SiS_Pr->SiS_RVBHCMAX  = 1;
+             SiS_Pr->SiS_RVBHCFACT = 1;
              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_VGAVT   = SiS_Pr->PanelVT;
+             SiS_Pr->SiS_HT      = SiS_Pr->PanelHT;
+             SiS_Pr->SiS_VT      = SiS_Pr->PanelVT;
+             SiS_Pr->SiS_RVBHRS2 = 0;
              gotit = TRUE;
           }
 #endif
@@ -3530,28 +3496,30 @@ SiS_GetCRT2Data301(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
 
        if(!gotit) {
 
-           SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
-                          &CRT2Index,&ResIndex,HwInfo);
+          SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+                         &CRT2Index,&ResIndex);
 
-           switch(CRT2Index) {
+          switch(CRT2Index) {
              case Panel_1024x768      : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;   break;
              case Panel_1024x768  + 32: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data;   break;
              case Panel_1280x720      :
              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_2+ 32: LCDPtr = SiS_Pr->SiS_StLCD1280x768_2Data;  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_1280x854      :
+             case Panel_1280x854  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x854Data;      break;
              case Panel_1280x960      :
              case Panel_1280x960  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x960Data;      break;
-              case Panel_1280x1024     : LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data;  break;
-              case Panel_1280x1024 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data;  break;
-              case Panel_1400x1050     : LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data;  break;
-              case Panel_1400x1050 + 32: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data;   break;
-              case Panel_1600x1200     : LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data;  break;
-              case Panel_1600x1200 + 32: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data;   break;
+             case Panel_1280x1024     : LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data;  break;
+             case Panel_1280x1024 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data;  break;
+             case Panel_1400x1050     : LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data;  break;
+             case Panel_1400x1050 + 32: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data;   break;
+             case Panel_1600x1200     : LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data;  break;
+             case Panel_1600x1200 + 32: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data;   break;
              case Panel_1680x1050     :
              case Panel_1680x1050 + 32: LCDPtr = SiS_Pr->SiS_LCD1680x1050Data;     break;
              case 100                 : LCDPtr = SiS_Pr->SiS_NoScaleData;          break;
@@ -3559,271 +3527,340 @@ SiS_GetCRT2Data301(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
              case 200                 : LCDPtr = SiS310_ExtCompaq1280x1024Data;    break;
              case 201                 : LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data;  break;
 #endif
-              default                  : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;   break;
-           }
+             default                  : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;   break;
+          }
 
+#ifdef SIS_XORG_XF86
 #ifdef TWDEBUG
-           xf86DrvMsg(0, X_INFO, "GetCRT2Data: Index %d ResIndex %d\n", CRT2Index, ResIndex);
+          xf86DrvMsg(0, X_INFO, "GetCRT2Data: Index %d ResIndex %d\n", CRT2Index, ResIndex);
+#endif
 #endif
 
-           SiS_Pr->SiS_RVBHCMAX  = (LCDPtr+ResIndex)->RVBHCMAX;
-           SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
-           SiS_Pr->SiS_VGAHT     = (LCDPtr+ResIndex)->VGAHT;
-           SiS_Pr->SiS_VGAVT     = (LCDPtr+ResIndex)->VGAVT;
-           SiS_Pr->SiS_HT        = (LCDPtr+ResIndex)->LCDHT;
-           SiS_Pr->SiS_VT        = (LCDPtr+ResIndex)->LCDVT;
+          SiS_Pr->SiS_RVBHCMAX  = (LCDPtr+ResIndex)->RVBHCMAX;
+          SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
+          SiS_Pr->SiS_VGAHT     = (LCDPtr+ResIndex)->VGAHT;
+          SiS_Pr->SiS_VGAVT     = (LCDPtr+ResIndex)->VGAVT;
+          SiS_Pr->SiS_HT        = (LCDPtr+ResIndex)->LCDHT;
+          SiS_Pr->SiS_VT        = (LCDPtr+ResIndex)->LCDVT;
 
         }
 
        tempax = SiS_Pr->PanelXRes;
-        tempbx = SiS_Pr->PanelYRes;
+       tempbx = SiS_Pr->PanelYRes;
 
-       if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
-           if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
-              if(HwInfo->jChipType < SIS_315H) {
-                 if     (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
-                 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
-              }
-           } else {
-              if     (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
-              else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
-              else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
-              else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
-              else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
-              else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
-           }
-       } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960) {
-           if     (SiS_Pr->SiS_VGAVDE == 350)  tempbx = 700;
-           else if(SiS_Pr->SiS_VGAVDE == 400)  tempbx = 800;
-           else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
-       } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
-           if     (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
-           else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
-           else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
-        } else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) {
+       switch(SiS_Pr->SiS_LCDResInfo) {
+       case Panel_1024x768:
+          if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
+             if(SiS_Pr->ChipType < SIS_315H) {
+                if     (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
+                else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
+             }
+          } else {
+             if     (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
+             else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
+             else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
+             else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
+             else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
+             else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
+          }
+          break;
+       case Panel_1280x960:
+          if     (SiS_Pr->SiS_VGAVDE == 350)  tempbx = 700;
+          else if(SiS_Pr->SiS_VGAVDE == 400)  tempbx = 800;
+          else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
+          break;
+       case Panel_1280x1024:
+          if     (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
+          else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
+          else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
+          break;
+       case Panel_1600x1200:
           if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
-              if     (SiS_Pr->SiS_VGAVDE == 350)  tempbx = 875;
-              else if(SiS_Pr->SiS_VGAVDE == 400)  tempbx = 1000;
-           }
-        }
+             if     (SiS_Pr->SiS_VGAVDE == 350)  tempbx = 875;
+             else if(SiS_Pr->SiS_VGAVDE == 400)  tempbx = 1000;
+          }
+          break;
+       }
 
-        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
-           tempax = SiS_Pr->SiS_VGAHDE;
-           tempbx = SiS_Pr->SiS_VGAVDE;
-        }
+       if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+          tempax = SiS_Pr->SiS_VGAHDE;
+          tempbx = SiS_Pr->SiS_VGAVDE;
+       }
 
-        SiS_Pr->SiS_HDE = tempax;
-        SiS_Pr->SiS_VDE = tempbx;
+       SiS_Pr->SiS_HDE = tempax;
+       SiS_Pr->SiS_VDE = tempbx;
      }
   }
 }
 
 static void
-SiS_GetCRT2Data(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
-                USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
+SiS_GetCRT2Data(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
+                unsigned short RefreshRateTableIndex)
 {
 
-  if(SiS_Pr->SiS_VBType & VB_SISVB) {
+   if(SiS_Pr->SiS_VBType & VB_SISVB) {
 
-     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
-        SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
-     } else {
-       if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
-          /* Need LVDS Data for LCD on 301B-DH */
-          SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
-       } else {
-          SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
-        }
-     }
+      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+         SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
+      } else {
+        if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
+           /* Need LVDS Data for LCD on 301B-DH */
+           SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
+        } else {
+           SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
+        }
+      }
 
-  } else {
+   } else {
 
-     SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
+      SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
 
-  }
+   }
 }
 
 /*********************************************/
 /*         GET LVDS DES (SKEW) DATA          */
 /*********************************************/
 
-static void
-SiS_GetLVDSDesPtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
-                  USHORT RefreshRateTableIndex, USHORT *PanelIndex,
-                 USHORT *ResIndex, PSIS_HW_INFO HwInfo)
+static const struct SiS_LVDSDes *
+SiS_GetLVDSDesPtr(struct SiS_Private *SiS_Pr)
 {
-  USHORT modeflag;
+   const struct SiS_LVDSDes *PanelDesPtr = NULL;
 
-  if(ModeNo <= 0x13) {
-     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-     (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-  } else {
-     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-     (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-  }
+#ifdef SIS300
+   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+
+      if(SiS_Pr->ChipType < SIS_315H) {
+        if(SiS_Pr->SiS_LCDTypeInfo == 4) {
+           if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
+              PanelDesPtr = SiS_Pr->SiS_PanelType04_1a;
+              if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+                 PanelDesPtr = SiS_Pr->SiS_PanelType04_2a;
+              }
+            } else if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
+              PanelDesPtr = SiS_Pr->SiS_PanelType04_1b;
+              if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+                 PanelDesPtr = SiS_Pr->SiS_PanelType04_2b;
+              }
+           }
+        }
+      }
+   }
+#endif
+   return PanelDesPtr;
+}
 
-  (*ResIndex) &= 0x1F;
-  (*PanelIndex) = 0;
+static void
+SiS_GetLVDSDesData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
+                   unsigned short RefreshRateTableIndex)
+{
+  unsigned short modeflag, ResIndex;
+  const struct SiS_LVDSDes *PanelDesPtr = NULL;
 
-  if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
-     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-        (*PanelIndex) = 50;
-        if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) (*PanelIndex) += 2;
-        if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*PanelIndex) += 1;
-        /* Nothing special needed for SOverscan    */
-        /* PALM uses NTSC data, PALN uses PAL data */
-     }
-  }
+  SiS_Pr->SiS_LCDHDES = 0;
+  SiS_Pr->SiS_LCDVDES = 0;
 
+  /* Some special cases */
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-     *PanelIndex = SiS_Pr->SiS_LCDTypeInfo;
-     if(HwInfo->jChipType >= SIS_661) {
-        /* As long as we don's use the BIOS tables, we
-        * need to convert the TypeInfo as for 315 series
-        */
-        (*PanelIndex) = SiS_Pr->SiS_LCDResInfo - 1;
-     }
-     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
-        (*PanelIndex) += 16;
-        if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
-           (*PanelIndex) = 32;
-           if(modeflag & HalfDCLK) (*PanelIndex)++;
+
+     /* Trumpion */
+     if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
+       if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
+          if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
+             SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
+          }
        }
+       return;
      }
-  }
 
-  if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
-     if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) {
-        (*ResIndex) = 7;
-        if(HwInfo->jChipType < SIS_315H) {
-           if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) (*ResIndex)++;
-        }
+     /* 640x480 on LVDS */
+     if(SiS_Pr->ChipType < SIS_315H) {
+       if(SiS_Pr->SiS_LCDResInfo == Panel_640x480 && SiS_Pr->SiS_LCDTypeInfo == 3) {
+          SiS_Pr->SiS_LCDHDES = 8;
+          if     (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
+          else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
+          else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
+          return;
+       }
      }
-  }
-}
-
-static void
-SiS_GetLVDSDesData(SiS_Private *SiS_Pr, USHORT ModeNo,USHORT ModeIdIndex,
-                   USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
-{
-  USHORT modeflag;
-  USHORT PanelIndex,ResIndex;
-  const  SiS_LVDSDesStruct *PanelDesPtr = NULL;
 
-  SiS_Pr->SiS_LCDHDES = 0;
-  SiS_Pr->SiS_LCDVDES = 0;
+  } /* LCD */
 
   if( (SiS_Pr->UseCustomMode)                   ||
       (SiS_Pr->SiS_LCDResInfo == Panel_Custom)   ||
       (SiS_Pr->SiS_CustomT == CUT_PANEL848)      ||
-      ((SiS_Pr->SiS_VBType & VB_SISVB) &&
-       (SiS_Pr->SiS_LCDInfo & DontExpandLCD) &&
-       (SiS_Pr->SiS_LCDInfo & LCDPass11)) ) {
+      (SiS_Pr->SiS_CustomT == CUT_PANEL856)      ||
+      (SiS_Pr->SiS_LCDInfo & LCDPass11) ) {
      return;
   }
 
-  if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+  if(ModeNo <= 0x13) ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+  else               ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+
+  if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
 
 #ifdef SIS315H
      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
-        /* non-pass 1:1 only, see above */
-        if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
-           SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
+       /* non-pass 1:1 only, see above */
+       if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
+          SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
+       }
+       if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
+          SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
+       }
+     }
+     if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
+       switch(SiS_Pr->SiS_CustomT) {
+       case CUT_UNIWILL1024:
+       case CUT_UNIWILL10242:
+       case CUT_CLEVO1400:
+          if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
+             SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
+          }
+          break;
+       }
+       switch(SiS_Pr->SiS_LCDResInfo) {
+       case Panel_1280x1024:
+          if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
+             SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
+          }
+          break;
+       case Panel_1280x800:    /* Verified for Averatec 6240 */
+       case Panel_1280x800_2:  /* Verified for Asus A4L */
+       case Panel_1280x854:    /* Not verified yet FIXME */
+          SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
+          break;
+       }
+     }
+#endif
+
+  } else {
+
+     if((SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
+
+       if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
+          if(ResIndex <= 3) SiS_Pr->SiS_LCDHDES = 256;
+       }
+
+     } else if((PanelDesPtr = SiS_GetLVDSDesPtr(SiS_Pr))) {
+
+       SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
+       SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;
+
+     } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+
+       if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
+          SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
        }
        if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
           SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
-       }
-     }
-     if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
-        switch(SiS_Pr->SiS_CustomT) {
-        case CUT_UNIWILL1024:
-        case CUT_UNIWILL10242:
-        case CUT_CLEVO1400:
-          if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
+       } else {
+          if(SiS_Pr->ChipType < SIS_315H) {
              SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
+          } else {
+             switch(SiS_Pr->SiS_LCDResInfo) {
+             case Panel_800x600:
+             case Panel_1024x768:
+             case Panel_1280x1024:
+                SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
+                break;
+             case Panel_1400x1050:
+                SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
+                break;
+             }
           }
-          break;
        }
-       if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
-          if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
-             SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
+
+     } else {
+
+        if(SiS_Pr->ChipType < SIS_315H) {
+#ifdef SIS300
+          switch(SiS_Pr->SiS_LCDResInfo) {
+          case Panel_800x600:
+             if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
+                SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
+             } else {
+                SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT + 3;
+                SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
+                if(SiS_Pr->SiS_VGAVDE == 400) SiS_Pr->SiS_LCDVDES -= 2;
+                else                          SiS_Pr->SiS_LCDVDES -= 4;
+             }
+             break;
+          case Panel_1024x768:
+             if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
+                SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
+             } else {
+                SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
+                if(SiS_Pr->SiS_VGAVDE <= 400) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 8;
+                if(SiS_Pr->SiS_VGAVDE <= 350) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 12;
+             }
+             break;
+          case Panel_1024x600:
+          default:
+             if( (SiS_Pr->SiS_VGAHDE == SiS_Pr->PanelXRes) &&
+                 (SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) ) {
+                SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
+             } else {
+                SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
+             }
+             break;
+          }
+
+          switch(SiS_Pr->SiS_LCDTypeInfo) {
+          case 1:
+             SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
+             break;
+          case 3: /* 640x480 only? */
+             SiS_Pr->SiS_LCDHDES = 8;
+             if     (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
+             else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
+             else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
+             break;
+          }
+#endif
+        } else {
+#ifdef SIS315H
+          switch(SiS_Pr->SiS_LCDResInfo) {
+          case Panel_1024x768:
+          case Panel_1280x1024:
+             if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
+                SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
+             }
+             break;
+          case Panel_320x240_1:
+          case Panel_320x240_2:
+          case Panel_320x240_3:
+             SiS_Pr->SiS_LCDVDES = 524;
+             break;
           }
+#endif
        }
      }
-#endif
-
-  } else {
-
-     SiS_GetLVDSDesPtr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
-                       &PanelIndex, &ResIndex, HwInfo);
-
-     switch(PanelIndex) {
-       case  0: PanelDesPtr = SiS_Pr->SiS_PanelType00_1;    break;   /* ---  */
-       case  1: PanelDesPtr = SiS_Pr->SiS_PanelType01_1;    break;
-       case  2: PanelDesPtr = SiS_Pr->SiS_PanelType02_1;    break;
-       case  3: PanelDesPtr = SiS_Pr->SiS_PanelType03_1;    break;
-       case  4: PanelDesPtr = SiS_Pr->SiS_PanelType04_1;    break;
-       case  5: PanelDesPtr = SiS_Pr->SiS_PanelType05_1;    break;
-       case  6: PanelDesPtr = SiS_Pr->SiS_PanelType06_1;    break;
-       case  7: PanelDesPtr = SiS_Pr->SiS_PanelType07_1;    break;
-       case  8: PanelDesPtr = SiS_Pr->SiS_PanelType08_1;    break;
-       case  9: PanelDesPtr = SiS_Pr->SiS_PanelType09_1;    break;
-       case 10: PanelDesPtr = SiS_Pr->SiS_PanelType0a_1;    break;
-       case 11: PanelDesPtr = SiS_Pr->SiS_PanelType0b_1;    break;
-       case 12: PanelDesPtr = SiS_Pr->SiS_PanelType0c_1;    break;
-       case 13: PanelDesPtr = SiS_Pr->SiS_PanelType0d_1;    break;
-       case 14: PanelDesPtr = SiS_Pr->SiS_PanelType0e_1;    break;
-       case 15: PanelDesPtr = SiS_Pr->SiS_PanelType0f_1;    break;
-       case 16: PanelDesPtr = SiS_Pr->SiS_PanelType00_2;    break;    /* --- */
-       case 17: PanelDesPtr = SiS_Pr->SiS_PanelType01_2;    break;
-       case 18: PanelDesPtr = SiS_Pr->SiS_PanelType02_2;    break;
-       case 19: PanelDesPtr = SiS_Pr->SiS_PanelType03_2;    break;
-       case 20: PanelDesPtr = SiS_Pr->SiS_PanelType04_2;    break;
-       case 21: PanelDesPtr = SiS_Pr->SiS_PanelType05_2;    break;
-       case 22: PanelDesPtr = SiS_Pr->SiS_PanelType06_2;    break;
-       case 23: PanelDesPtr = SiS_Pr->SiS_PanelType07_2;    break;
-       case 24: PanelDesPtr = SiS_Pr->SiS_PanelType08_2;    break;
-       case 25: PanelDesPtr = SiS_Pr->SiS_PanelType09_2;    break;
-       case 26: PanelDesPtr = SiS_Pr->SiS_PanelType0a_2;    break;
-       case 27: PanelDesPtr = SiS_Pr->SiS_PanelType0b_2;    break;
-       case 28: PanelDesPtr = SiS_Pr->SiS_PanelType0c_2;    break;
-       case 29: PanelDesPtr = SiS_Pr->SiS_PanelType0d_2;    break;
-       case 30: PanelDesPtr = SiS_Pr->SiS_PanelType0e_2;    break;
-       case 31: PanelDesPtr = SiS_Pr->SiS_PanelType0f_2;    break;
-       case 32: PanelDesPtr = SiS_Pr->SiS_PanelTypeNS_1;    break;    /* pass 1:1 */
-       case 33: PanelDesPtr = SiS_Pr->SiS_PanelTypeNS_2;    break;
-       case 50: PanelDesPtr = SiS_Pr->SiS_CHTVUNTSCDesData; break;    /* TV */
-       case 51: PanelDesPtr = SiS_Pr->SiS_CHTVONTSCDesData; break;
-       case 52: PanelDesPtr = SiS_Pr->SiS_CHTVUPALDesData;  break;
-       case 53: PanelDesPtr = SiS_Pr->SiS_CHTVOPALDesData;  break;
-       default: return;
-     }
-
-     SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
-     SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;
 
      if((ModeNo <= 0x13) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
-        modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-        if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+       modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+       if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
           if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 632;
-        } else if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) {
-           if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
-              if(SiS_Pr->SiS_LCDResInfo >= Panel_1024x768) {
-                if(HwInfo->jChipType < SIS_315H) {
+       } else if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) {
+          if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
+             if(SiS_Pr->SiS_LCDResInfo >= Panel_1024x768) {
+                if(SiS_Pr->ChipType < SIS_315H) {
                    if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320;
                 } else {
-                   if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)  SiS_Pr->SiS_LCDHDES = 480;
-                    if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 804;
+#ifdef SIS315H
+                   if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)  SiS_Pr->SiS_LCDHDES = 480;
+                   if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 804;
                    if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 704;
-                    if(!(modeflag & HalfDCLK)) {
-                       SiS_Pr->SiS_LCDHDES = 320;
-                      if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 632;
+                   if(!(modeflag & HalfDCLK)) {
+                      SiS_Pr->SiS_LCDHDES = 320;
+                      if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 632;
                       if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 542;
-                    }
-                 }
-              }
-           }
-        }
+                   }
+#endif
+                }
+             }
+          }
+       }
      }
   }
 }
@@ -3832,54 +3869,90 @@ SiS_GetLVDSDesData(SiS_Private *SiS_Pr, USHORT ModeNo,USHORT ModeIdIndex,
 /*           DISABLE VIDEO BRIDGE            */
 /*********************************************/
 
+#ifdef SIS315H
+static int
+SiS_HandlePWD(struct SiS_Private *SiS_Pr)
+{
+   int ret = 0;
+#ifdef SET_PWD
+   unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
+   unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
+   unsigned char  drivermode = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40;
+   unsigned short temp;
+
+   if( (SiS_Pr->SiS_VBType & VB_SISPWD) &&
+       (romptr)                                &&
+       (SiS_Pr->SiS_PWDOffset) ) {
+      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2b,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 0]);
+      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2c,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 1]);
+      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2d,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 2]);
+      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2e,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 3]);
+      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2f,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 4]);
+      temp = 0x00;
+      if((ROMAddr[romptr + 2] & (0x06 << 1)) && !drivermode) {
+         temp = 0x80;
+        ret = 1;
+      }
+      SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x27,0x7f,temp);
+#ifdef SIS_XORG_XF86
+#ifdef TWDEBUG
+      xf86DrvMsg(0, 0, "Setting PWD %x\n", temp);
+#endif
+#endif
+   }
+#endif
+   return ret;
+}
+#endif
+
 /* NEVER use any variables (VBInfo), this will be called
  * from outside the context of modeswitch!
  * MUST call getVBType before calling this
  */
 void
-SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_DisableBridge(struct SiS_Private *SiS_Pr)
 {
 #ifdef SIS315H
-  USHORT tempah,pushax=0,modenum;
+  unsigned short tempah, pushax=0, modenum;
 #endif
-  USHORT temp=0;
+  unsigned short temp=0;
 
   if(SiS_Pr->SiS_VBType & VB_SISVB) {
 
-     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {   /* ===== For 30xB/LV ===== */
+     if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {           /* ===== For 30xB/C/LV ===== */
 
-        if(HwInfo->jChipType < SIS_315H) {
+       if(SiS_Pr->ChipType < SIS_315H) {
 
 #ifdef SIS300     /* 300 series */
 
-          if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
-             if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-                SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
+          if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
+             if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
+                SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
              } else {
-                SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
+                SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
              }
-             SiS_PanelDelay(SiS_Pr, HwInfo, 3);
+             SiS_PanelDelay(SiS_Pr, 3);
           }
           if(SiS_Is301B(SiS_Pr)) {
              SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);
              SiS_ShortDelay(SiS_Pr,1);
-           }
+          }
           SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
           SiS_DisplayOff(SiS_Pr);
           SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
           SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
-          SiS_UnLockCRT2(SiS_Pr,HwInfo);
-          if(!(SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
+          SiS_UnLockCRT2(SiS_Pr);
+          if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) {
              SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
              SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
           }
-          if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ||
-              (!(SiS_CR36BIOSWord23d(SiS_Pr, HwInfo))) ) {
-             SiS_PanelDelay(SiS_Pr, HwInfo, 2);
-             if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-                 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
+          if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
+              (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
+             SiS_PanelDelay(SiS_Pr, 2);
+             if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
+                SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
              } else {
-                SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
+                SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
              }
           }
 
@@ -3889,130 +3962,127 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 
 #ifdef SIS315H    /* 315 series */
 
+          int didpwd = 0;
           BOOLEAN custom1 = ((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
                              (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) ? TRUE : FALSE;
 
           modenum = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34) & 0x7f;
 
-           if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+          if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
 
 #ifdef SET_EMI
-             if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
+             if(SiS_Pr->SiS_VBType & VB_SISEMI) {
                 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
-                   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
+                   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
                 }
              }
 #endif
-             if( (modenum <= 0x13)                  ||
-                 (SiS_IsVAMode(SiS_Pr,HwInfo))      ||
-                 (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ) {
-                SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
-                if(custom1) SiS_PanelDelay(SiS_Pr, HwInfo, 3);
+
+             didpwd = SiS_HandlePWD(SiS_Pr);
+
+             if( (modenum <= 0x13)           ||
+                 (SiS_IsVAMode(SiS_Pr))      ||
+                 (!(SiS_IsDualEdge(SiS_Pr))) ) {
+                if(!didpwd) {
+                   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfe);
+                   if(custom1) SiS_PanelDelay(SiS_Pr, 3);
+                } else {
+                   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfc);
+                }
              }
 
              if(!custom1) {
                 SiS_DDC2Delay(SiS_Pr,0xff00);
                 SiS_DDC2Delay(SiS_Pr,0xe000);
-                SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
-                 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
+                SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
+                pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
                 if(IS_SIS740) {
                    SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
                 }
-                SiS_PanelDelay(SiS_Pr, HwInfo, 3);
+                SiS_PanelDelay(SiS_Pr, 3);
              }
 
-           }
+          }
 
-          if(!(SiS_IsNotM650orLater(SiS_Pr, HwInfo))) {
-             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_IsNotM650orLater(SiS_Pr))) {
+             /* if(SiS_Pr->ChipType < SIS_340) {*/
+                tempah = 0xef;
+                if(SiS_IsVAMode(SiS_Pr)) tempah = 0xf7;
+                SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
+             /*}*/
           }
 
-          if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+          if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
              SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,~0x10);
           }
 
           tempah = 0x3f;
-          if(SiS_IsDualEdge(SiS_Pr,HwInfo)) {
+          if(SiS_IsDualEdge(SiS_Pr)) {
              tempah = 0x7f;
-             if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) tempah = 0xbf;
+             if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0xbf;
           }
           SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
 
-           if((SiS_IsVAMode(SiS_Pr,HwInfo)) ||
-             ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && (modenum <= 0x13))) {
+          if((SiS_IsVAMode(SiS_Pr)) ||
+             ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
 
              SiS_DisplayOff(SiS_Pr);
-             if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-                SiS_PanelDelay(SiS_Pr, HwInfo, 2);
+             if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
+                SiS_PanelDelay(SiS_Pr, 2);
              }
              SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
              SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
 
           }
 
-          if((!(SiS_IsVAMode(SiS_Pr,HwInfo))) ||
-             ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && (modenum <= 0x13))) {
+          if((!(SiS_IsVAMode(SiS_Pr))) ||
+             ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
 
-             if(!(SiS_IsDualEdge(SiS_Pr,HwInfo))) {
+             if(!(SiS_IsDualEdge(SiS_Pr))) {
                 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
                 SiS_DisplayOff(SiS_Pr);
              }
              SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
 
-             if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-                SiS_PanelDelay(SiS_Pr, HwInfo, 2);
+             if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
+                SiS_PanelDelay(SiS_Pr, 2);
              }
 
              SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
              temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
-              SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
+             SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
              SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
              SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
 
           }
 
-          if(SiS_IsNotM650orLater(SiS_Pr,HwInfo)) {
+          if(SiS_IsNotM650orLater(SiS_Pr)) {
              SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
           }
 
-          if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-
-             if(!custom1) {
-
-                if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
-                   if(!(SiS_CRT2IsLCD(SiS_Pr,HwInfo))) {
-                      if(!(SiS_IsDualEdge(SiS_Pr,HwInfo))) {
-                         SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
-                       }
-                    }
-                }
-
-                SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
+          if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
 
-                if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
-                   if(SiS_IsVAorLCD(SiS_Pr, HwInfo)) {
-                      SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 20);
-                   }
-                }
+             if( (!(SiS_IsVAMode(SiS_Pr)))  &&
+                 (!(SiS_CRT2IsLCD(SiS_Pr))) &&
+                 (!(SiS_IsDualEdge(SiS_Pr))) ) {
 
-             } else {
+                if(custom1) SiS_PanelDelay(SiS_Pr, 2);
+                if(!didpwd) {
+                   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
+                }
+                if(custom1) SiS_PanelDelay(SiS_Pr, 4);
+             }
 
-                if((SiS_IsVAMode(SiS_Pr,HwInfo)) ||
-                   (!(SiS_IsDualEdge(SiS_Pr,HwInfo)))) {
-                   if((!(SiS_WeHaveBacklightCtrl(SiS_Pr, HwInfo))) ||
-                      (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo)))) {
-                      SiS_PanelDelay(SiS_Pr, HwInfo, 2);
-                      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
-                      SiS_PanelDelay(SiS_Pr, HwInfo, 4);
+             if(!custom1) {
+                SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
+                if(SiS_Pr->SiS_VBType & VB_SISEMI) {
+                   if(SiS_IsVAorLCD(SiS_Pr)) {
+                      SiS_PanelDelayLoop(SiS_Pr, 3, 20);
                    }
                 }
-
              }
-           }
+
+          }
 
 #endif /* SIS315H */
 
@@ -4020,36 +4090,36 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 
      } else {     /* ============ For 301 ================ */
 
-        if(HwInfo->jChipType < SIS_315H) {
+        if(SiS_Pr->ChipType < SIS_315H) {
 #ifdef SIS300
-           if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
-             SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
-             SiS_PanelDelay(SiS_Pr, HwInfo, 3);
+          if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
+             SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
+             SiS_PanelDelay(SiS_Pr, 3);
           }
 #endif
        }
 
-        SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);           /* disable VB */
-        SiS_DisplayOff(SiS_Pr);
+       SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);           /* disable VB */
+       SiS_DisplayOff(SiS_Pr);
 
-        if(HwInfo->jChipType >= SIS_315H) {
-           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
+       if(SiS_Pr->ChipType >= SIS_315H) {
+          SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
        }
 
-        SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);                /* disable lock mode */
+       SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);                /* disable lock mode */
 
-       if(HwInfo->jChipType >= SIS_315H) {
-            temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
-            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
+       if(SiS_Pr->ChipType >= SIS_315H) {
+           temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
+           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
            SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
            SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
        } else {
 #ifdef SIS300
-            SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);            /* disable CRT2 */
-           if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ||
-               (!(SiS_CR36BIOSWord23d(SiS_Pr,HwInfo))) ) {
-               SiS_PanelDelay(SiS_Pr, HwInfo, 2);
-               SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
+           SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);            /* disable CRT2 */
+           if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
+               (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
+               SiS_PanelDelay(SiS_Pr, 2);
+               SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
            }
 #endif
        }
@@ -4058,34 +4128,34 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 
   } else {     /* ============ For LVDS =============*/
 
-    if(HwInfo->jChipType < SIS_315H) {
+    if(SiS_Pr->ChipType < SIS_315H) {
 
 #ifdef SIS300  /* 300 series */
 
        if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
-          SiS_SetCH700x(SiS_Pr,0x090E);
+          SiS_SetCH700x(SiS_Pr,0x0E,0x09);
        }
 
-       if(HwInfo->jChipType == SIS_730) {
+       if(SiS_Pr->ChipType == SIS_730) {
           if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
-             SiS_WaitVBRetrace(SiS_Pr,HwInfo);
+             SiS_WaitVBRetrace(SiS_Pr);
           }
-          if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
-             SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
-             SiS_PanelDelay(SiS_Pr, HwInfo, 3);
+          if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
+             SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
+             SiS_PanelDelay(SiS_Pr, 3);
           }
        } else {
           if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
              if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
-                if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
-                    SiS_WaitVBRetrace(SiS_Pr,HwInfo);
+                if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
+                   SiS_WaitVBRetrace(SiS_Pr);
                    if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {
                       SiS_DisplayOff(SiS_Pr);
-                   }
-                   SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
-                   SiS_PanelDelay(SiS_Pr, HwInfo, 3);
-                 }
-              }
+                   }
+                   SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
+                   SiS_PanelDelay(SiS_Pr, 3);
+                }
+             }
           }
        }
 
@@ -4094,14 +4164,14 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
        SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
 
        SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
-       SiS_UnLockCRT2(SiS_Pr,HwInfo);
+       SiS_UnLockCRT2(SiS_Pr);
        SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
        SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
 
-       if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ||
-           (!(SiS_CR36BIOSWord23d(SiS_Pr,HwInfo))) ) {
-          SiS_PanelDelay(SiS_Pr, HwInfo, 2);
-          SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
+       if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
+           (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
+          SiS_PanelDelay(SiS_Pr, 2);
+          SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
        }
 
 #endif  /* SIS300 */
@@ -4110,113 +4180,113 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 
 #ifdef SIS315H /* 315 series */
 
-        if(!(SiS_IsNotM650orLater(SiS_Pr,HwInfo))) {
-          if(HwInfo->jChipType < SIS_340) {
-              SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,~0x18);
-          }
-        }
+       if(!(SiS_IsNotM650orLater(SiS_Pr))) {
+          /*if(SiS_Pr->ChipType < SIS_340) { */ /* XGI needs this */
+             SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,~0x18);
+          /* } */
+       }
 
        if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
 
-          if(HwInfo->jChipType == SIS_740) {
+          if(SiS_Pr->ChipType == SIS_740) {
              temp = SiS_GetCH701x(SiS_Pr,0x61);
              if(temp < 1) {
-                SiS_SetCH701x(SiS_Pr,0xac76);
-                SiS_SetCH701x(SiS_Pr,0x0066);
+                SiS_SetCH701x(SiS_Pr,0x76,0xac);
+                SiS_SetCH701x(SiS_Pr,0x66,0x00);
              }
 
-             if( (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
-                 (SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo)) ) {
-                SiS_SetCH701x(SiS_Pr,0x3e49);
+             if( (!(SiS_IsDualEdge(SiS_Pr))) ||
+                 (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
+                SiS_SetCH701x(SiS_Pr,0x49,0x3e);
              }
           }
 
-          if( (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
-              (SiS_IsVAMode(SiS_Pr,HwInfo)) ) {
+          if( (!(SiS_IsDualEdge(SiS_Pr))) ||
+              (SiS_IsVAMode(SiS_Pr)) ) {
              SiS_Chrontel701xBLOff(SiS_Pr);
-             SiS_Chrontel701xOff(SiS_Pr,HwInfo);
+             SiS_Chrontel701xOff(SiS_Pr);
           }
 
-          if(HwInfo->jChipType != SIS_740) {
-             if( (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
-                 (SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo)) ) {
-                SiS_SetCH701x(SiS_Pr,0x0149);
-             }
+          if(SiS_Pr->ChipType != SIS_740) {
+             if( (!(SiS_IsDualEdge(SiS_Pr))) ||
+                 (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
+                SiS_SetCH701x(SiS_Pr,0x49,0x01);
+             }
           }
 
        }
 
        if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
-          SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
-          SiS_PanelDelay(SiS_Pr, HwInfo, 3);
+          SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
+          SiS_PanelDelay(SiS_Pr, 3);
        }
 
        if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
-           (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
-           (!(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo))) ) {
+           (!(SiS_IsDualEdge(SiS_Pr))) ||
+           (!(SiS_IsTVOrYPbPrOrScart(SiS_Pr))) ) {
           SiS_DisplayOff(SiS_Pr);
        }
 
        if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
-           (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
-           (!(SiS_IsVAMode(SiS_Pr,HwInfo))) ) {
+           (!(SiS_IsDualEdge(SiS_Pr))) ||
+           (!(SiS_IsVAMode(SiS_Pr))) ) {
           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
        }
 
-       if(HwInfo->jChipType == SIS_740) {
+       if(SiS_Pr->ChipType == SIS_740) {
           SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
        }
 
        SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
 
        if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
-           (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
-           (!(SiS_IsVAMode(SiS_Pr,HwInfo))) ) {
+           (!(SiS_IsDualEdge(SiS_Pr))) ||
+           (!(SiS_IsVAMode(SiS_Pr))) ) {
           SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
        }
 
        if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
-          if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
+          if(SiS_CRT2IsLCD(SiS_Pr)) {
              SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
-             if(HwInfo->jChipType == SIS_550) {
-                SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xbf);
-                SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xef);
+             if(SiS_Pr->ChipType == SIS_550) {
+                SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xbf);
+                SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xef);
              }
           }
        } else {
-          if(HwInfo->jChipType == SIS_740) {
-             if(SiS_IsLCDOrLCDA(SiS_Pr,HwInfo)) {
-                SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
+          if(SiS_Pr->ChipType == SIS_740) {
+             if(SiS_IsLCDOrLCDA(SiS_Pr)) {
+                SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
              }
-          } else if(SiS_IsVAMode(SiS_Pr,HwInfo)) {
+          } else if(SiS_IsVAMode(SiS_Pr)) {
              SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
           }
        }
 
        if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
-          if(SiS_IsDualEdge(SiS_Pr,HwInfo)) {
+          if(SiS_IsDualEdge(SiS_Pr)) {
              /* SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff); */
           } else {
              SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
           }
        }
 
-       SiS_UnLockCRT2(SiS_Pr,HwInfo);
+       SiS_UnLockCRT2(SiS_Pr);
 
-       if(HwInfo->jChipType == SIS_550) {
+       if(SiS_Pr->ChipType == SIS_550) {
           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); /* DirectDVD PAL?*/
           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); /* VB clock / 4 ? */
        } else if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
-                  (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
-                  (!(SiS_IsVAMode(SiS_Pr,HwInfo))) ) {
+                  (!(SiS_IsDualEdge(SiS_Pr))) ||
+                  (!(SiS_IsVAMode(SiS_Pr))) ) {
           SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
        }
 
         if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
-          if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
-             if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
-                SiS_PanelDelay(SiS_Pr, HwInfo, 2);
-                SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
+          if(SiS_CRT2IsLCD(SiS_Pr)) {
+             if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
+                SiS_PanelDelay(SiS_Pr, 2);
+                SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
              }
           }
         }
@@ -4237,78 +4307,81 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
  * from outside the context of a mode switch!
  * MUST call getVBType before calling this
  */
-static void
-SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+#ifdef SIS_LINUX_KERNEL
+static
+#endif
+void
+SiS_EnableBridge(struct SiS_Private *SiS_Pr)
 {
-  USHORT temp=0,tempah;
+  unsigned short temp=0, tempah;
 #ifdef SIS315H
-  USHORT temp1,pushax=0;
+  unsigned short temp1, pushax=0;
   BOOLEAN delaylong = FALSE;
 #endif
 
   if(SiS_Pr->SiS_VBType & VB_SISVB) {
 
-    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {   /* ====== For 301B et al  ====== */
+    if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {            /* ====== For 301B et al  ====== */
 
-      if(HwInfo->jChipType < SIS_315H) {
+      if(SiS_Pr->ChipType < SIS_315H) {
 
 #ifdef SIS300     /* 300 series */
 
-        if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
-           if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+        if(SiS_CRT2IsLCD(SiS_Pr)) {
+           if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
               SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
            } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
-              SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
+              SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
            }
-           if(SiS_Pr->SiS_VBType & (VB_SIS301LV302LV | VB_NoLCD)) {
-              if(!(SiS_CR36BIOSWord23d(SiS_Pr, HwInfo))) {
-                 SiS_PanelDelay(SiS_Pr, HwInfo, 0);
+           if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_NoLCD)) {
+              if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
+                 SiS_PanelDelay(SiS_Pr, 0);
               }
            }
         }
 
         if((SiS_Pr->SiS_VBType & VB_NoLCD) &&
-           (SiS_CRT2IsLCD(SiS_Pr, HwInfo))) {
+           (SiS_CRT2IsLCD(SiS_Pr))) {
 
            SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                   /* Enable CRT2 */
-            SiS_DisplayOn(SiS_Pr);
-           SiS_UnLockCRT2(SiS_Pr,HwInfo);
+           SiS_DisplayOn(SiS_Pr);
+           SiS_UnLockCRT2(SiS_Pr);
            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
            if(SiS_BridgeInSlavemode(SiS_Pr)) {
-              SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
-           } else {
-              SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
-            }
+              SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
+           } else {
+              SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
+           }
            if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
               if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
-                 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
-                    SiS_PanelDelay(SiS_Pr, HwInfo, 1);
-                  }
-                 SiS_WaitVBRetrace(SiS_Pr,HwInfo);
-                  SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00);
-               }
+                 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
+                    SiS_PanelDelay(SiS_Pr, 1);
+                 }
+                 SiS_WaitVBRetrace(SiS_Pr);
+                 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
+              }
            }
 
         } else {
 
            temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;             /* lock mode */
-            if(SiS_BridgeInSlavemode(SiS_Pr)) {
-               tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
-               if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
-            }
-            SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
+           if(SiS_BridgeInSlavemode(SiS_Pr)) {
+              tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
+              if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
+           }
+           SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
            SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
            SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20);        /* enable VB processor */
            SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
            SiS_DisplayOn(SiS_Pr);
-           if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-              if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
-                 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
-                    if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
-                       SiS_PanelDelay(SiS_Pr, HwInfo, 1);
-                     }
+           if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
+              if(SiS_CRT2IsLCD(SiS_Pr)) {
+                 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
+                    if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
+                       SiS_PanelDelay(SiS_Pr, 1);
+                    }
                     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
-                 }
+                 }
               }
            }
 
@@ -4322,31 +4395,32 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 #ifdef SIS315H    /* 315 series */
 
 #ifdef SET_EMI
-        UCHAR   r30=0, r31=0, r32=0, r33=0, cr36=0;
-        /* USHORT  emidelay=0; */
+        unsigned char   r30=0, r31=0, r32=0, r33=0, cr36=0;
+        int didpwd = 0;
+        /* unsigned short  emidelay=0; */
 #endif
 
-        if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+        if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
            SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef);
 #ifdef SET_EMI
-           if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
+           if(SiS_Pr->SiS_VBType & VB_SISEMI) {
               SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
            }
 #endif
         }
 
-         if(!(SiS_IsNotM650orLater(SiS_Pr, HwInfo))) {
-           if(HwInfo->jChipType < SIS_340) {
+        if(!(SiS_IsNotM650orLater(SiS_Pr))) {
+           /*if(SiS_Pr->ChipType < SIS_340) { */
               tempah = 0x10;
-              if(SiS_LCDAEnabled(SiS_Pr, HwInfo)) {
-                 if(SiS_TVEnabled(SiS_Pr, HwInfo)) tempah = 0x18;
-                 else                              tempah = 0x08;
+              if(SiS_LCDAEnabled(SiS_Pr)) {
+                 if(SiS_TVEnabled(SiS_Pr)) tempah = 0x18;
+                 else                      tempah = 0x08;
               }
               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah);
-           }
+           /*}*/
         }
 
-        if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+        if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
 
            SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
            SiS_DisplayOff(SiS_Pr);
@@ -4355,42 +4429,51 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
               SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
            }
 
-           if(SiS_IsVAorLCD(SiS_Pr, HwInfo)) {
-               if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
-                 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 2);
-                 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
-                 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 2);
-                 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
-                    SiS_GenericDelay(SiS_Pr, 0x4500);
+           didpwd = SiS_HandlePWD(SiS_Pr);
+
+           if(SiS_IsVAorLCD(SiS_Pr)) {
+              if(!didpwd) {
+                 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
+                    SiS_PanelDelayLoop(SiS_Pr, 3, 2);
+                    SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
+                    SiS_PanelDelayLoop(SiS_Pr, 3, 2);
+                    if(SiS_Pr->SiS_VBType & VB_SISEMI) {
+                       SiS_GenericDelay(SiS_Pr, 17664);
+                    }
+                 }
+              } else {
+                 SiS_PanelDelayLoop(SiS_Pr, 3, 2);
+                 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
+                    SiS_GenericDelay(SiS_Pr, 17664);
                  }
               }
            }
 
            if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {
-               SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10);
+              SiS_PanelDelayLoop(SiS_Pr, 3, 10);
               delaylong = TRUE;
            }
 
         }
 
-        if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
+        if(!(SiS_IsVAMode(SiS_Pr))) {
 
-            temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
+           temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
            if(SiS_BridgeInSlavemode(SiS_Pr)) {
-               tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
-               if(!(tempah & SetCRT2ToRAMDAC)) {
-                 if(!(SiS_LCDAEnabled(SiS_Pr, HwInfo))) temp |= 0x20;
+              tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
+              if(!(tempah & SetCRT2ToRAMDAC)) {
+                 if(!(SiS_LCDAEnabled(SiS_Pr))) temp |= 0x20;
               }
-            }
-            SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
+           }
+           SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
 
            SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                   /* enable CRT2 */
 
            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
 
-           if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-              SiS_PanelDelay(SiS_Pr, HwInfo, 2);
+           if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
+              SiS_PanelDelay(SiS_Pr, 2);
            }
 
         } else {
@@ -4402,38 +4485,48 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
         SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
         SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
 
+        if(SiS_Pr->SiS_VBType & VB_SISPOWER) {
+           if( (SiS_LCDAEnabled(SiS_Pr)) ||
+               (SiS_CRT2IsLCD(SiS_Pr)) ) {
+              /* Enable "LVDS PLL power on" (even on 301C) */
+              SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);
+              /* Enable "LVDS Driver Power on" (even on 301C) */
+              SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x7f);
+           }
+        }
+
         tempah = 0xc0;
-        if(SiS_IsDualEdge(SiS_Pr, HwInfo)) {
+        if(SiS_IsDualEdge(SiS_Pr)) {
            tempah = 0x80;
-           if(!(SiS_IsVAMode(SiS_Pr, HwInfo))) tempah = 0x40;
+           if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0x40;
         }
-         SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
+        SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
 
-        if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+        if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
 
-           SiS_PanelDelay(SiS_Pr, HwInfo, 2);
+           SiS_PanelDelay(SiS_Pr, 2);
 
            SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10);
            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
 
            if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
 #ifdef SET_EMI
-              if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
-                 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
-                 SiS_GenericDelay(SiS_Pr, 0x500);
+              if(SiS_Pr->SiS_VBType & VB_SISEMI) {
+                 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
+                 SiS_GenericDelay(SiS_Pr, 2048);
               }
 #endif
               SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
 
-              if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
+              if(SiS_Pr->SiS_VBType & VB_SISEMI) {
 #ifdef SET_EMI
                  cr36 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
 
                  if(SiS_Pr->SiS_ROMNew) {
-                    UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
-                    USHORT romptr = GetLCDStructPtr661_2(SiS_Pr, HwInfo);
+                    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
+                    unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
                     if(romptr) {
-                       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
+                       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
                        SiS_Pr->EMI_30 = 0;
                        SiS_Pr->EMI_31 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 0];
                        SiS_Pr->EMI_32 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 1];
@@ -4511,21 +4604,21 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
                  if(!SiS_Pr->OverruleEMI) {
 #ifdef COMPAL_HACK
                     if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
-                       if((cr36 & 0x0f) == 0x09) {
+                       if((cr36 & 0x0f) == 0x09) {
                           r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x00;
                        }
                     }
 #endif
 #ifdef COMPAQ_HACK
                     if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
-                       if((cr36 & 0x0f) == 0x03) {
+                       if((cr36 & 0x0f) == 0x03) {
                           r30 = 0x20; r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
                        }
                     }
 #endif
 #ifdef ASUS_HACK
                     if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
-                       if((cr36 & 0x0f) == 0x02) {
+                       if((cr36 & 0x0f) == 0x02) {
                           /* r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x33;  */   /* rev 2 */
                           /* r30 = 0x20; r31 = 0x05; r32 = 0x60; r33 = 0x33;  */   /* rev 3 */
                           /* r30 = 0x60; r31 = 0x0d; r32 = 0x70; r33 = 0x40;  */   /* rev 4 */
@@ -4533,11 +4626,11 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
                        }
                     }
 #endif
-                 }
+                 }
 
                  if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) {
                     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
-                    SiS_GenericDelay(SiS_Pr, 0x500);
+                    SiS_GenericDelay(SiS_Pr, 2048);
                  }
                  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,r31);
                  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,r32);
@@ -4547,36 +4640,44 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
                  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
 
 #ifdef SET_EMI
-                 if( (SiS_LCDAEnabled(SiS_Pr, HwInfo)) ||
-                     (SiS_CRT2IsLCD(SiS_Pr, HwInfo)) ) {
-                    if(r30 & 0x40) {
-                       SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 5);
+                 if( (SiS_LCDAEnabled(SiS_Pr)) ||
+                     (SiS_CRT2IsLCD(SiS_Pr)) ) {
+                    if(r30 & 0x40) {
+                       /*SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x2a,0x80);*/
+                       SiS_PanelDelayLoop(SiS_Pr, 3, 5);
                        if(delaylong) {
-                          SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 5);
+                          SiS_PanelDelayLoop(SiS_Pr, 3, 5);
                           delaylong = FALSE;
                        }
-                       SiS_WaitVBRetrace(SiS_Pr,HwInfo);
+                       SiS_WaitVBRetrace(SiS_Pr);
+                       SiS_WaitVBRetrace(SiS_Pr);
                        if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
-                          SiS_GenericDelay(SiS_Pr, 0x500);
+                          SiS_GenericDelay(SiS_Pr, 1280);
                        }
-                       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40);   /* Enable */
-                    }
+                       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40);   /* Enable */
+                       /*SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);*/
+                    }
                  }
 #endif
               }
            }
 
-           if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
-              if(SiS_IsVAorLCD(SiS_Pr, HwInfo)) {
-                 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10);
+           if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
+              if(SiS_IsVAorLCD(SiS_Pr)) {
+                 SiS_PanelDelayLoop(SiS_Pr, 3, 10);
                  if(delaylong) {
-                    SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10);
+                    SiS_PanelDelayLoop(SiS_Pr, 3, 10);
                  }
-                  SiS_WaitVBRetrace(SiS_Pr,HwInfo);
-                 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
-                    SiS_GenericDelay(SiS_Pr, 0x500);
+                 SiS_WaitVBRetrace(SiS_Pr);
+                 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
+                    SiS_GenericDelay(SiS_Pr, 2048);
+                    SiS_WaitVBRetrace(SiS_Pr);
+                 }
+                 if(!didpwd) {
+                    SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
+                 } else {
+                    SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x03);
                  }
-                 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
               }
            }
 
@@ -4586,7 +4687,7 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 
         }
 
-        if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
+        if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
         }
 
@@ -4596,26 +4697,26 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 
     } else {   /* ============  For 301 ================ */
 
-       if(HwInfo->jChipType < SIS_315H) {
-          if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
-             SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
-            SiS_PanelDelay(SiS_Pr, HwInfo, 0);
+       if(SiS_Pr->ChipType < SIS_315H) {
+         if(SiS_CRT2IsLCD(SiS_Pr)) {
+            SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
+            SiS_PanelDelay(SiS_Pr, 0);
          }
        }
 
        temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;          /* lock mode */
        if(SiS_BridgeInSlavemode(SiS_Pr)) {
-          tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
-          if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
+         tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
+         if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
        }
        SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
 
        SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                  /* enable CRT2 */
 
-       if(HwInfo->jChipType >= SIS_315H) {
-          temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
-          if(!(temp & 0x80)) {
-             SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);         /* BVBDOENABLE=1 */
+       if(SiS_Pr->ChipType >= SIS_315H) {
+         temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
+         if(!(temp & 0x80)) {
+            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);         /* BVBDOENABLE=1 */
          }
        }
 
@@ -4623,15 +4724,15 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 
        SiS_VBLongWait(SiS_Pr);
        SiS_DisplayOn(SiS_Pr);
-       if(HwInfo->jChipType >= SIS_315H) {
-          SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
+       if(SiS_Pr->ChipType >= SIS_315H) {
+         SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
        }
        SiS_VBLongWait(SiS_Pr);
 
-       if(HwInfo->jChipType < SIS_315H) {
-          if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
-            SiS_PanelDelay(SiS_Pr, HwInfo, 1);
-             SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00);
+       if(SiS_Pr->ChipType < SIS_315H) {
+         if(SiS_CRT2IsLCD(SiS_Pr)) {
+            SiS_PanelDelay(SiS_Pr, 1);
+            SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
          }
        }
 
@@ -4639,49 +4740,49 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 
   } else {   /* =================== For LVDS ================== */
 
-    if(HwInfo->jChipType < SIS_315H) {
+    if(SiS_Pr->ChipType < SIS_315H) {
 
 #ifdef SIS300    /* 300 series */
 
-       if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
-          if(HwInfo->jChipType == SIS_730) {
-            SiS_PanelDelay(SiS_Pr, HwInfo, 1);
-            SiS_PanelDelay(SiS_Pr, HwInfo, 1);
-            SiS_PanelDelay(SiS_Pr, HwInfo, 1);
+       if(SiS_CRT2IsLCD(SiS_Pr)) {
+         if(SiS_Pr->ChipType == SIS_730) {
+            SiS_PanelDelay(SiS_Pr, 1);
+            SiS_PanelDelay(SiS_Pr, 1);
+            SiS_PanelDelay(SiS_Pr, 1);
          }
-          SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
-         if(!(SiS_CR36BIOSWord23d(SiS_Pr,HwInfo))) {
-            SiS_PanelDelay(SiS_Pr, HwInfo, 0);
+         SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
+         if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
+            SiS_PanelDelay(SiS_Pr, 0);
          }
        }
 
        SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
        SiS_DisplayOn(SiS_Pr);
-       SiS_UnLockCRT2(SiS_Pr,HwInfo);
+       SiS_UnLockCRT2(SiS_Pr);
        SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
        if(SiS_BridgeInSlavemode(SiS_Pr)) {
-         SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
+         SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
        } else {
-         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
+         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
        }
 
        if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
-          if(!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) {
-            SiS_WaitVBRetrace(SiS_Pr, HwInfo);
-            SiS_SetCH700x(SiS_Pr,0x0B0E);
-          }
+         if(!(SiS_CRT2IsLCD(SiS_Pr))) {
+            SiS_WaitVBRetrace(SiS_Pr);
+            SiS_SetCH700x(SiS_Pr,0x0E,0x0B);
+         }
        }
 
-       if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
-          if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
-             if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
-               if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
-                  SiS_PanelDelay(SiS_Pr, HwInfo, 1);
-                  SiS_PanelDelay(SiS_Pr, HwInfo, 1);
-               }
-               SiS_WaitVBRetrace(SiS_Pr, HwInfo);
-                SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00);
-             }
+       if(SiS_CRT2IsLCD(SiS_Pr)) {
+         if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
+            if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
+               if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
+                  SiS_PanelDelay(SiS_Pr, 1);
+                  SiS_PanelDelay(SiS_Pr, 1);
+               }
+               SiS_WaitVBRetrace(SiS_Pr);
+               SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
+            }
          }
        }
 
@@ -4691,94 +4792,94 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 
 #ifdef SIS315H    /* 315 series */
 
-       if(!(SiS_IsNotM650orLater(SiS_Pr,HwInfo))) {
-          if(HwInfo->jChipType < SIS_340) {
-             SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x18);
-         }
+       if(!(SiS_IsNotM650orLater(SiS_Pr))) {
+         /*if(SiS_Pr->ChipType < SIS_340) {*/  /* XGI needs this */
+            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x18);
+         /*}*/
        }
 
        if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
-         if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
-            SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
-            SiS_PanelDelay(SiS_Pr, HwInfo, 0);
-          }
+         if(SiS_CRT2IsLCD(SiS_Pr)) {
+            SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
+            SiS_PanelDelay(SiS_Pr, 0);
+         }
        }
 
        SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
-       SiS_UnLockCRT2(SiS_Pr,HwInfo);
+       SiS_UnLockCRT2(SiS_Pr);
 
        SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
 
        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
-          temp = SiS_GetCH701x(SiS_Pr,0x66);
+         temp = SiS_GetCH701x(SiS_Pr,0x66);
          temp &= 0x20;
          SiS_Chrontel701xBLOff(SiS_Pr);
        }
 
-       if(HwInfo->jChipType != SIS_550) {
-          SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
+       if(SiS_Pr->ChipType != SIS_550) {
+         SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
        }
 
-       if(HwInfo->jChipType == SIS_740) {
-          if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
-             if(SiS_IsLCDOrLCDA(SiS_Pr, HwInfo)) {
-               SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
+       if(SiS_Pr->ChipType == SIS_740) {
+         if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+            if(SiS_IsLCDOrLCDA(SiS_Pr)) {
+               SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
             }
          }
        }
 
        temp1 = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
        if(!(temp1 & 0x80)) {
-          SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
+         SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
        }
 
        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
-          if(temp) {
-            SiS_Chrontel701xBLOn(SiS_Pr, HwInfo);
+         if(temp) {
+            SiS_Chrontel701xBLOn(SiS_Pr);
          }
        }
 
        if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
-          if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
+         if(SiS_CRT2IsLCD(SiS_Pr)) {
             SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
-            if(HwInfo->jChipType == SIS_550) {
+            if(SiS_Pr->ChipType == SIS_550) {
                SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x40);
                SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x10);
             }
          }
-       } else if(SiS_IsVAMode(SiS_Pr,HwInfo)) {
-          if(HwInfo->jChipType != SIS_740) {
-             SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
+       } else if(SiS_IsVAMode(SiS_Pr)) {
+         if(SiS_Pr->ChipType != SIS_740) {
+            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
          }
        }
 
-       if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
-          SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
+       if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
+         SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
        }
 
        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
-                 if(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo)) {
-             SiS_Chrontel701xOn(SiS_Pr,HwInfo);
-          }
-          if( (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
-             (SiS_IsLCDOrLCDA(SiS_Pr,HwInfo)) ) {
-             SiS_ChrontelDoSomething1(SiS_Pr,HwInfo);
-          }
+         if(SiS_IsTVOrYPbPrOrScart(SiS_Pr)) {
+            SiS_Chrontel701xOn(SiS_Pr);
+         }
+         if( (SiS_IsVAMode(SiS_Pr)) ||
+             (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
+            SiS_ChrontelDoSomething1(SiS_Pr);
+         }
        }
 
        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
-                 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
-            if( (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
-                (SiS_IsLCDOrLCDA(SiS_Pr,HwInfo)) ) {
-               SiS_Chrontel701xBLOn(SiS_Pr, HwInfo);
-               SiS_ChrontelInitTVVSync(SiS_Pr,HwInfo);
-             }
-                 }
+         if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
+            if( (SiS_IsVAMode(SiS_Pr)) ||
+                (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
+               SiS_Chrontel701xBLOn(SiS_Pr);
+               SiS_ChrontelInitTVVSync(SiS_Pr);
+            }
+         }
        } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
-                 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
-            if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
-               SiS_PanelDelay(SiS_Pr, HwInfo, 1);
-               SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00);
+         if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
+            if(SiS_CRT2IsLCD(SiS_Pr)) {
+               SiS_PanelDelay(SiS_Pr, 1);
+               SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
             }
          }
        }
@@ -4797,243 +4898,204 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 
 /* Set CRT2 OFFSET / PITCH */
 static void
-SiS_SetCRT2Offset(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
-                 USHORT RRTI, PSIS_HW_INFO HwInfo)
+SiS_SetCRT2Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
+               unsigned short RRTI)
 {
-  USHORT offset;
-  UCHAR temp;
+   unsigned short offset;
+   unsigned char  temp;
 
-  if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return;
+   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return;
 
-  offset = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,RRTI,HwInfo);
+   offset = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,RRTI);
 
-  if((SiS_Pr->SiS_LCDResInfo == Panel_640x480_2) ||
-     (SiS_Pr->SiS_LCDResInfo == Panel_640x480_3)) {
-     offset >>= 1;
-  }
+   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(offset & 0xFF));
+   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,(offset >> 8));
 
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(offset & 0xFF));
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,(offset >> 8));
-  temp = (UCHAR)(((offset >> 3) & 0xFF) + 1);
-  if(offset % 8) temp++;
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,temp);
+   temp = (unsigned char)(((offset >> 3) & 0xFF) + 1);
+   if(offset & 0x07) temp++;
+   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,temp);
 }
 
 /* Set CRT2 sync and PanelLink mode */
 static void
-SiS_SetCRT2Sync(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT RefreshRateTableIndex,
-                PSIS_HW_INFO HwInfo)
+SiS_SetCRT2Sync(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RefreshRateTableIndex)
 {
-  USHORT tempah=0,tempbl,infoflag;
+   unsigned short tempah=0, tempbl, infoflag;
 
-  tempbl = 0xC0;
+   tempbl = 0xC0;
 
-  if(SiS_Pr->UseCustomMode) {
-     infoflag = SiS_Pr->CInfoFlag;
-  } else {
-     infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
-  }
+   if(SiS_Pr->UseCustomMode) {
+      infoflag = SiS_Pr->CInfoFlag;
+   } else {
+      infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+   }
 
-  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {                                   /* LVDS */
+   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {                                  /* LVDS */
 
-     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-        tempah = 0;
-     } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) {
-        tempah = SiS_Pr->SiS_LCDInfo;
-     } else tempah = infoflag >> 8;
-     tempah &= 0xC0;
-     tempah |= 0x20;
-     if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
-     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-        if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
-           (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
-          tempah |= 0xf0;
-        }
-       if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
-            (SiS_Pr->SiS_IF_DEF_DSTN) ||
-            (SiS_Pr->SiS_IF_DEF_TRUMPION) ||
-            (SiS_Pr->SiS_CustomT == CUT_PANEL848) ) {
-           tempah |= 0x30;
-        }
-     }
-     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-        if(HwInfo->jChipType >= SIS_315H) {
-           tempah >>= 3;
-          tempah &= 0x18;
-           SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xE7,tempah);
-          /* Don't care about 12/18/24 bit mode - TV is via VGA, not PL */
-        } else {
-           SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,0xe0);
-        }
-     } else {
-        SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
-     }
+      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+        tempah = 0;
+      } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) {
+        tempah = SiS_Pr->SiS_LCDInfo;
+      } else tempah = infoflag >> 8;
+      tempah &= 0xC0;
+      tempah |= 0x20;
+      if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
+      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+        if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
+           (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
+           tempah |= 0xf0;
+        }
+        if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
+            (SiS_Pr->SiS_IF_DEF_DSTN) ||
+            (SiS_Pr->SiS_IF_DEF_TRUMPION) ||
+            (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
+            (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
+           tempah |= 0x30;
+        }
+        if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
+            (SiS_Pr->SiS_IF_DEF_DSTN) ) {
+           tempah &= ~0xc0;
+        }
+      }
+      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+        if(SiS_Pr->ChipType >= SIS_315H) {
+           tempah >>= 3;
+           tempah &= 0x18;
+           SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xE7,tempah);
+           /* Don't care about 12/18/24 bit mode - TV is via VGA, not PL */
+        } else {
+           SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,0xe0);
+        }
+      } else {
+        SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
+      }
 
-  } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
+   } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
 
-     if(HwInfo->jChipType < SIS_315H) {
+      if(SiS_Pr->ChipType < SIS_315H) {
 
 #ifdef SIS300  /* ---- 300 series --- */
 
-        if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {                  /* 630 - 301B(-DH) */
+        if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {                        /* 630 - 301B(-DH) */
 
-          tempah = infoflag >> 8;
-          tempbl = 0;
-           if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-             if(SiS_Pr->SiS_LCDInfo & LCDSync) {
-                tempah = SiS_Pr->SiS_LCDInfo;
-                tempbl = (tempah >> 6) & 0x03;
-              }
-           }
-           tempah &= 0xC0;
-           tempah |= 0x20;
-           if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
-          tempah |= 0xc0;
-           SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
-          if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
-             SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
-          }
+           tempah = infoflag >> 8;
+           tempbl = 0;
+           if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+              if(SiS_Pr->SiS_LCDInfo & LCDSync) {
+                 tempah = SiS_Pr->SiS_LCDInfo;
+                 tempbl = (tempah >> 6) & 0x03;
+              }
+           }
+           tempah &= 0xC0;
+           tempah |= 0x20;
+           if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
+           tempah |= 0xc0;
+           SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
+           if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
+              SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
+           }
 
-        } else {                                                       /* 630 - 301 */
+        } else {                                                       /* 630 - 301 */
 
-           tempah = infoflag >> 8;
-           tempah &= 0xC0;
-           tempah |= 0x20;
-          if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
-           SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
+           tempah = ((infoflag >> 8) & 0xc0) | 0x20;
+           if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
+           SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
 
-        }
+        }
 
 #endif /* SIS300 */
 
-     } else {
+      } else {
 
 #ifdef SIS315H  /* ------- 315 series ------ */
 
-        if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {                    /* 315 - LVDS */
+        if(SiS_Pr->SiS_VBType & VB_SISLVDS) {                  /* 315 - LVDS */
 
-          tempbl = 0;
-          if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
-             (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
-             tempah = infoflag >> 8;
-             if(SiS_Pr->SiS_LCDInfo & LCDSync) {
-               tempbl = ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6);
-             }
-          } else if((SiS_Pr->SiS_CustomT == CUT_CLEVO1400)  &&
-                    (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)) {
-                     tempah = infoflag >> 8;
-             tempbl = 0x03;
-          } else {
-              tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
-             tempbl = (tempah >> 6) & 0x03;
-             tempbl |= 0x08;
-             if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempbl |= 0x04;
-          }
-          tempah &= 0xC0;
-           tempah |= 0x20;
-           if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
-          if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)   tempah |= 0xc0;
-           SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
-          if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-             if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-                SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
-             }
-          }
+           tempbl = 0;
+           if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
+              (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
+              tempah = infoflag >> 8;
+              if(SiS_Pr->SiS_LCDInfo & LCDSync) {
+                tempbl = ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6);
+              }
+           } else if((SiS_Pr->SiS_CustomT == CUT_CLEVO1400)  &&
+                     (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)) {
+              tempah = infoflag >> 8;
+              tempbl = 0x03;
+           } else {
+              tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
+              tempbl = (tempah >> 6) & 0x03;
+              tempbl |= 0x08;
+              if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempbl |= 0x04;
+           }
+           tempah &= 0xC0;
+           tempah |= 0x20;
+           if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
+           if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)   tempah |= 0xc0;
+           SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
+           if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
+              if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+                 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
+              }
+           }
 
-        } else {                                                       /* 315 - TMDS */
+        } else {                                                       /* 315 - TMDS */
 
-           tempah = tempbl = infoflag >> 8;
-          if(!SiS_Pr->UseCustomMode) {
-             tempbl = 0;
-             if((SiS_Pr->SiS_VBType & VB_SIS301C) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
-                if(ModeNo <= 0x13) {
-                   tempah = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
-                }
-             }
-             if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
-                if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
-                   if(SiS_Pr->SiS_LCDInfo & LCDSync) {
-                      tempah = SiS_Pr->SiS_LCDInfo;
+           tempah = tempbl = infoflag >> 8;
+           if(!SiS_Pr->UseCustomMode) {
+              tempbl = 0;
+              if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
+                 if(ModeNo <= 0x13) {
+                    tempah = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
+                 }
+              }
+              if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+                 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
+                   if(SiS_Pr->SiS_LCDInfo & LCDSync) {
+                      tempah = SiS_Pr->SiS_LCDInfo;
                       tempbl = (tempah >> 6) & 0x03;
                    }
-                }
-             }
-          }
-          tempah &= 0xC0;
-           tempah |= 0x20;
-           if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
-          if(SiS_Pr->SiS_VBType & VB_NoLCD) {
-             /* Imitate BIOS bug */
-             if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)  tempah |= 0xc0;
-          }
-          if((SiS_Pr->SiS_VBType & VB_SIS301C) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
-             tempah >>= 3;
-             tempah &= 0x18;
-             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xe7,tempah);
-          } else {
-              SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
-             if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-                if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-                   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
-                }
-             }
-          }
+                 }
+              }
+           }
+           tempah &= 0xC0;
+           tempah |= 0x20;
+           if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
+           if(SiS_Pr->SiS_VBType & VB_NoLCD) {
+              /* Imitate BIOS bug */
+              if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)  tempah |= 0xc0;
+           }
+           if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
+              tempah >>= 3;
+              tempah &= 0x18;
+              SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xe7,tempah);
+           } else {
+              SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
+              if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
+                 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+                    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
+                 }
+              }
+           }
 
-        }
+         }
 #endif  /* SIS315H */
       }
    }
 }
 
-/* Set CRT2 FIFO on 300/630/730 */
+/* Set CRT2 FIFO on 300/540/630/730 */
 #ifdef SIS300
 static void
-SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,USHORT ModeNo,
-                    PSIS_HW_INFO HwInfo)
-{
-  UCHAR  *ROMAddr  = HwInfo->pjVirtualRomBase;
-  USHORT temp,index;
-  USHORT modeidindex,refreshratetableindex;
-  USHORT VCLK=0,MCLK,colorth=0,data2=0;
-  USHORT tempal, tempah, tempbx, tempcl, tempax;
-  USHORT CRT1ModeNo,CRT2ModeNo;
-  USHORT SelectRate_backup;
-  ULONG  data,eax;
-  const UCHAR  LatencyFactor[] = {
-       97, 88, 86, 79, 77, 00,       /*; 64  bit    BQ=2   */
-        00, 87, 85, 78, 76, 54,       /*; 64  bit    BQ=1   */
-        97, 88, 86, 79, 77, 00,       /*; 128 bit    BQ=2   */
-        00, 79, 77, 70, 68, 48,       /*; 128 bit    BQ=1   */
-        80, 72, 69, 63, 61, 00,       /*; 64  bit    BQ=2   */
-        00, 70, 68, 61, 59, 37,       /*; 64  bit    BQ=1   */
-        86, 77, 75, 68, 66, 00,       /*; 128 bit    BQ=2   */
-        00, 68, 66, 59, 57, 37        /*; 128 bit    BQ=1   */
-  };
-  const UCHAR  LatencyFactor730[] = {
-         69, 63, 61,
-        86, 79, 77,
-       103, 96, 94,
-       120,113,111,
-       137,130,128,    /* <-- last entry, data below */
-       137,130,128,    /* to avoid using illegal values */
-       137,130,128,
-       137,130,128,
-       137,130,128,
-       137,130,128,
-       137,130,128,
-       137,130,128,
-       137,130,128,
-       137,130,128,
-       137,130,128,
-       137,130,128,
-  };
-  const UCHAR ThLowB[]   = {
-       81, 4, 72, 6, 88, 8,120,12,
-        55, 4, 54, 6, 66, 8, 90,12,
-        42, 4, 45, 6, 55, 8, 75,12
-  };
-  const UCHAR ThTiming[] = {
-       1, 2, 2, 3, 0, 1, 1, 2
+SiS_SetCRT2FIFO_300(struct SiS_Private *SiS_Pr,unsigned short ModeNo)
+{
+  unsigned char  *ROMAddr  = SiS_Pr->VirtualRomBase;
+  unsigned short temp, index, modeidindex, refreshratetableindex;
+  unsigned short VCLK = 0, MCLK, colorth = 0, data2 = 0;
+  unsigned short tempbx, tempcl, CRT1ModeNo, CRT2ModeNo, SelectRate_backup;
+  unsigned int   data, pci50, pciA0;
+  static const unsigned char colortharray[] = {
+       1, 1, 2, 2, 3, 4
   };
 
   SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;
@@ -5044,232 +5106,159 @@ SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,USHORT ModeNo,
      SiS_SearchModeID(SiS_Pr, &CRT1ModeNo, &modeidindex);
      SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
      SiS_Pr->SiS_SelectCRT2Rate = 0;
-     refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT1ModeNo, modeidindex, HwInfo);
+     refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT1ModeNo, modeidindex);
 
      if(CRT1ModeNo >= 0x13) {
-        index = SiS_Pr->SiS_RefIndex[refreshratetableindex].Ext_CRTVCLK;
-        index &= 0x3F;
-        VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;                      /* Get VCLK */
+        /* Get VCLK */
+       index = SiS_GetRefCRTVCLK(SiS_Pr, refreshratetableindex, SiS_Pr->SiS_UseWide);
+       VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
 
-       colorth = SiS_GetColorDepth(SiS_Pr,CRT1ModeNo,modeidindex);     /* Get colordepth */
-        colorth >>= 1;
-        if(!colorth) colorth++;
+       /* Get colordepth */
+       colorth = SiS_GetColorDepth(SiS_Pr,CRT1ModeNo,modeidindex) >> 1;
+       if(!colorth) colorth++;
      }
 
   } else {
 
      CRT1ModeNo = 0xfe;
-     VCLK = SiS_Pr->CSRClock_CRT1;                                     /* Get VCLK */
-     data2 = (SiS_Pr->CModeFlag_CRT1 & ModeTypeMask) - 2;
-     switch(data2) {                                                   /* Get color depth */
-        case 0 : colorth = 1; break;
-        case 1 : colorth = 1; break;
-        case 2 : colorth = 2; break;
-        case 3 : colorth = 2; break;
-        case 4 : colorth = 3; break;
-        case 5 : colorth = 4; break;
-        default: colorth = 2;
-     }
+
+     /* Get VCLK */
+     VCLK = SiS_Pr->CSRClock_CRT1;
+
+     /* Get color depth */
+     colorth = colortharray[((SiS_Pr->CModeFlag_CRT1 & ModeTypeMask) - 2)];
 
   }
 
   if(CRT1ModeNo >= 0x13) {
-    if(HwInfo->jChipType == SIS_300) {
-       index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A);
-    } else {
-       index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A);
-    }
-    index &= 0x07;
-    MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;                                /* Get MCLK */
+     /* Get MCLK */
+     if(SiS_Pr->ChipType == SIS_300) {
+        index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A);
+     } else {
+        index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A);
+     }
+     index &= 0x07;
+     MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;
 
-    data2 = (colorth * VCLK) / MCLK;
+     temp = ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) >> 6) & 0x03) << 1;
+     if(!temp) temp++;
+     temp <<= 2;
 
-    temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
-    temp = ((temp & 0x00FF) >> 6) << 1;
-    if(temp == 0) temp = 1;
-    temp <<= 2;
-    temp &= 0xff;
+     data2 = temp - ((colorth * VCLK) / MCLK);
 
-    data2 = temp - data2;
+     temp = (28 * 16) % data2;
+     data2 = (28 * 16) / data2;
+     if(temp) data2++;
 
-    if((28 * 16) % data2) {
-       data2 = (28 * 16) / data2;
-       data2++;
-    } else {
-       data2 = (28 * 16) / data2;
-    }
+     if(SiS_Pr->ChipType == SIS_300) {
 
-    if(HwInfo->jChipType == SIS_300) {
-
-       tempah = SiS_GetReg(SiS_Pr->SiS_P3c4,0x18);
-       tempah &= 0x62;
-       tempah >>= 1;
-       tempal = tempah;
-       tempah >>= 3;
-       tempal |= tempah;
-       tempal &= 0x07;
-       tempcl = ThTiming[tempal];
-       tempbx = SiS_GetReg(SiS_Pr->SiS_P3c4,0x16);
-       tempbx >>= 6;
-       tempah = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
-       tempah >>= 4;
-       tempah &= 0x0c;
-       tempbx |= tempah;
-       tempbx <<= 1;
-       tempal = ThLowB[tempbx + 1];
-       tempal *= tempcl;
-       tempal += ThLowB[tempbx];
-       data = tempal;
-
-    } else if(HwInfo->jChipType == SIS_730) {
-
-#ifdef LINUX_KERNEL
-       SiS_SetRegLong(0xcf8,0x80000050);
-       eax = SiS_GetRegLong(0xcfc);
+       SiS_GetFIFOThresholdIndex300(SiS_Pr, &tempbx, &tempcl);
+       data = SiS_GetFIFOThresholdB300(tempbx, tempcl);
+
+     } else {
+
+#ifdef SIS_LINUX_KERNEL
+       pci50 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0x50);
+       pciA0 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0xa0);
 #else
-       eax = pciReadLong(0x00000000, 0x50);
+       pci50 = pciReadLong(0x00000000, 0x50);
+       pciA0 = pciReadLong(0x00000000, 0xA0);
 #endif
-       tempal = (USHORT)(eax >> 8);
-       tempal &= 0x06;
-       tempal <<= 5;
 
-#ifdef LINUX_KERNEL
-       SiS_SetRegLong(0xcf8,0x800000A0);
-       eax = SiS_GetRegLong(0xcfc);
-#else
-       eax = pciReadLong(0x00000000, 0xA0);
-#endif
-       temp = (USHORT)(eax >> 28);
-       temp &= 0x0F;
-       tempal |= temp;
-
-       tempbx = tempal;   /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */
-       tempbx = 0;        /* -- do it like the BIOS anyway... */
-       tempax = tempbx;
-       tempbx &= 0xc0;
-       tempbx >>= 6;
-       tempax &= 0x0f;
-       tempax *= 3;
-       tempbx += tempax;
-
-       data = LatencyFactor730[tempbx];
-       data += 15;
-       temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
-       if(!(temp & 0x80)) data += 5;
+        if(SiS_Pr->ChipType == SIS_730) {
 
-    } else {
+          index = (unsigned short)(((pciA0 >> 28) & 0x0f) * 3);
+          index += (unsigned short)(((pci50 >> 9)) & 0x03);
 
-       index = 0;
-       temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
-       if(temp & 0x0080) index += 12;
+          /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */
+          index = 0;  /* -- do it like the BIOS anyway... */
 
-#ifdef LINUX_KERNEL
-       SiS_SetRegLong(0xcf8,0x800000A0);
-       eax = SiS_GetRegLong(0xcfc);
-#else
-       /* We use pci functions X offers. We use tag 0, because
-        * we want to read/write to the host bridge (which is always
-        * 00:00.0 on 630, 730 and 540), not the VGA device.
-        */
-       eax = pciReadLong(0x00000000, 0xA0);
-#endif
-       temp = (USHORT)(eax >> 24);
-       if(!(temp&0x01)) index += 24;
-
-#ifdef LINUX_KERNEL
-       SiS_SetRegLong(0xcf8,0x80000050);
-       eax = SiS_GetRegLong(0xcfc);
-#else
-       eax = pciReadLong(0x00000000, 0x50);
-#endif
-       temp=(USHORT)(eax >> 24);
-       if(temp & 0x01) index += 6;
+       } else {
 
-       temp = (temp & 0x0F) >> 1;
-       index += temp;
+          pci50 >>= 24;
+          pciA0 >>= 24;
 
-       data = LatencyFactor[index];
-       data += 15;
-       temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
-       if(!(temp & 0x80)) data += 5;
-    }
+          index = (pci50 >> 1) & 0x07;
+
+          if(pci50 & 0x01)    index += 6;
+          if(!(pciA0 & 0x01)) index += 24;
+
+          if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80) index += 12;
 
-    data += data2;                             /* CRT1 Request Period */
+       }
 
-    SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
-    SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
+       data = SiS_GetLatencyFactor630(SiS_Pr, index) + 15;
+       if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80)) data += 5;
 
-    if(!SiS_Pr->UseCustomMode) {
+     }
 
-       CRT2ModeNo = ModeNo;
-       SiS_SearchModeID(SiS_Pr, &CRT2ModeNo, &modeidindex);
+     data += data2;                                            /* CRT1 Request Period */
 
-       refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT2ModeNo, modeidindex, HwInfo);
+     SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
+     SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
 
-       index = SiS_GetVCLK2Ptr(SiS_Pr,CRT2ModeNo,modeidindex,
-                               refreshratetableindex,HwInfo);
-       VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;                /* Get VCLK  */
+     if(!SiS_Pr->UseCustomMode) {
 
-       if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
-          if(SiS_Pr->SiS_UseROM) {
-            if(ROMAddr[0x220] & 0x01) {
-                VCLK = ROMAddr[0x229] | (ROMAddr[0x22a] << 8);
-            }
-          }
-       }
+       CRT2ModeNo = ModeNo;
+       SiS_SearchModeID(SiS_Pr, &CRT2ModeNo, &modeidindex);
 
-    } else {
+       refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT2ModeNo, modeidindex);
 
-       CRT2ModeNo = 0xfe;
-       VCLK = SiS_Pr->CSRClock;                                        /* Get VCLK */
+       /* Get VCLK  */
+       index = SiS_GetVCLK2Ptr(SiS_Pr, CRT2ModeNo, modeidindex, refreshratetableindex);
+       VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
 
-    }
+       if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
+          if(SiS_Pr->SiS_UseROM) {
+             if(ROMAddr[0x220] & 0x01) {
+                VCLK = ROMAddr[0x229] | (ROMAddr[0x22a] << 8);
+             }
+           }
+        }
+
+     } else {
+
+       /* Get VCLK */
+       CRT2ModeNo = 0xfe;
+       VCLK = SiS_Pr->CSRClock;
+
+     }
 
-    colorth = SiS_GetColorDepth(SiS_Pr,CRT2ModeNo,modeidindex); /* Get colordepth */
-    colorth >>= 1;
-    if(!colorth) colorth++;
+     /* Get colordepth */
+     colorth = SiS_GetColorDepth(SiS_Pr,CRT2ModeNo,modeidindex) >> 1;
+     if(!colorth) colorth++;
 
-    data = data * VCLK * colorth;
-    if(data % (MCLK << 4)) {
-       data = data / (MCLK << 4);
-       data++;
-    } else {
-       data = data / (MCLK << 4);
-    }
+     data = data * VCLK * colorth;
+     temp = data % (MCLK << 4);
+     data = data / (MCLK << 4);
+     if(temp) data++;
 
-    if(data <= 6) data = 6;
-    if(data > 0x14) data = 0x14;
+     if(data < 6) data = 6;
+     else if(data > 0x14) data = 0x14;
 
-    temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x01);
-    if(HwInfo->jChipType == SIS_300) {
-       if(data <= 0x0f) temp = (temp & (~0x1F)) | 0x13;
-       else             temp = (temp & (~0x1F)) | 0x16;
-       if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
-                 temp = (temp & (~0x1F)) | 0x13;
-       }
-    } else {
-       if( ( (HwInfo->jChipType == SIS_630) ||
-             (HwInfo->jChipType == SIS_730) )  &&
-           (HwInfo->jChipRevision >= 0x30) ) /* 630s or 730(s?) */
-      {
-         temp = (temp & (~0x1F)) | 0x1b;
-      } else {
-         temp = (temp & (~0x1F)) | 0x16;
-      }
-    }
-    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0xe0,temp);
+     if(SiS_Pr->ChipType == SIS_300) {
+        temp = 0x16;
+       if((data <= 0x0f) || (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024))
+          temp = 0x13;
+     } else {
+        temp = 0x16;
+       if(( (SiS_Pr->ChipType == SIS_630) ||
+            (SiS_Pr->ChipType == SIS_730) )  &&
+          (SiS_Pr->ChipRevision >= 0x30))
+          temp = 0x1b;
+     }
+     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0xe0,temp);
 
-    if( (HwInfo->jChipType == SIS_630) &&
-        (HwInfo->jChipRevision >= 0x30) ) /* 630s, NOT 730 */
-    {
-       if(data > 0x13) data = 0x13;
-    }
-    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,0xe0,data);
+     if((SiS_Pr->ChipType == SIS_630) &&
+       (SiS_Pr->ChipRevision >= 0x30)) {
+       if(data > 0x13) data = 0x13;
+     }
+     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,0xe0,data);
 
   } else {  /* If mode <= 0x13, we just restore everything */
 
-    SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
-    SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
+     SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
+     SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
 
   }
 }
@@ -5278,10 +5267,10 @@ SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,USHORT ModeNo,
 /* Set CRT2 FIFO on 315/330 series */
 #ifdef SIS315H
 static void
-SiS_SetCRT2FIFO_310(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_SetCRT2FIFO_310(struct SiS_Private *SiS_Pr)
 {
   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3B);
-  if( (HwInfo->jChipType == SIS_760)      &&
+  if( (SiS_Pr->ChipType == SIS_760)      &&
       (SiS_Pr->SiS_SysFlags & SF_760LFB)  &&
       (SiS_Pr->SiS_ModeType == Mode32Bpp) &&
       (SiS_Pr->SiS_VGAHDE >= 1280)       &&
@@ -5299,337 +5288,162 @@ SiS_SetCRT2FIFO_310(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 }
 #endif
 
-static USHORT
-SiS_GetVGAHT2(SiS_Private *SiS_Pr)
+static unsigned short
+SiS_GetVGAHT2(struct SiS_Private *SiS_Pr)
 {
-  ULONG tempax,tempbx;
+  unsigned int tempax,tempbx;
 
   tempbx = (SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) * SiS_Pr->SiS_RVBHCMAX;
   tempax = (SiS_Pr->SiS_VT - SiS_Pr->SiS_VDE) * SiS_Pr->SiS_RVBHCFACT;
   tempax = (tempax * SiS_Pr->SiS_HT) / tempbx;
-  return((USHORT)tempax);
+  return (unsigned short)tempax;
 }
 
 /* Set Part 1 / SiS bridge slave mode */
 static void
-SiS_SetGroup1_301(SiS_Private *SiS_Pr, USHORT ModeNo,USHORT ModeIdIndex,
-                  PSIS_HW_INFO HwInfo,USHORT RefreshRateTableIndex)
-{
-  USHORT  push1,push2;
-  USHORT  tempax,tempbx,tempcx,temp;
-  USHORT  resinfo,modeflag,xres=0;
-  unsigned char p1_7, p1_8;
+SiS_SetGroup1_301(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,
+                  unsigned short RefreshRateTableIndex)
+{
+  unsigned short temp, modeflag, i, j, xres=0, VGAVDE;
+  static const unsigned short CRTranslation[] = {
+       /* CR0   CR1   CR2   CR3   CR4   CR5   CR6   CR7   */
+         0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
+       /* CR8   CR9   SR0A  SR0B  SR0C  SR0D  SR0E  CR0F  */
+         0x00, 0x0b, 0x17, 0x18, 0x19, 0x00, 0x1a, 0x00,
+       /* CR10  CR11  CR12  CR13  CR14  CR15  CR16  CR17  */
+         0x0c, 0x0d, 0x0e, 0x00, 0x0f, 0x10, 0x11, 0x00
+  };
 
   if(ModeNo <= 0x13) {
      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-     resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
   } else if(SiS_Pr->UseCustomMode) {
      modeflag = SiS_Pr->CModeFlag;
-     resinfo = 0;
      xres = SiS_Pr->CHDisplay;
   } else {
      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-     resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
      xres = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes;
   }
 
   /* The following is only done if bridge is in slave mode: */
 
-  if((HwInfo->jChipType >= SIS_661) && (ModeNo > 0x13)) {
-     if(xres >= 1600) {
+  if(SiS_Pr->ChipType >= SIS_315H) {
+     if(xres >= 1600) {  /* BIOS: == 1600 */
         SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x31,0x04);
      }
   }
 
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0xff);                  /* set MAX HT */
+  SiS_Pr->CHTotal = 8224;  /* Max HT, 0x2020, results in 0x3ff in registers */
 
-  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)  modeflag |= Charx8Dot;
-
-  if(modeflag & Charx8Dot) tempcx = 0x08;
-  else                     tempcx = 0x09;
-
-  tempax = SiS_Pr->SiS_VGAHDE;                                         /* 0x04 Horizontal Display End */
-  if(modeflag & HalfDCLK) tempax >>= 1;
-  tempax = ((tempax / tempcx) - 1) & 0xff;
-  tempbx = tempax;
-
-  temp = tempax;
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,temp);
+  SiS_Pr->CHDisplay = SiS_Pr->SiS_VGAHDE;
+  if(modeflag & HalfDCLK) SiS_Pr->CHDisplay >>= 1;
 
+  SiS_Pr->CHBlankStart = SiS_Pr->CHDisplay;
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-     if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
-        temp += 2;
-     }
-  }
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
-     if(resinfo == SIS_RI_800x600) temp -= 2;
-  }
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x05,temp);                 /* 0x05 Horizontal Display Start */
-
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x06,0x03);                 /* 0x06 Horizontal Blank end     */
-
-  tempax = 0xFFFF;
-  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempax = SiS_GetVGAHT2(SiS_Pr);
-  if(tempax >= SiS_Pr->SiS_VGAHT) tempax = SiS_Pr->SiS_VGAHT;
-  if(modeflag & HalfDCLK)         tempax >>= 1;
-  tempax = (tempax / tempcx) - 5;
-  tempcx = tempax;
-
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
-     temp = tempcx - 1;
-     if(!(modeflag & HalfDCLK)) {
-        temp -= 6;
-        if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
-           temp -= 2;
-           if(ModeNo > 0x13) temp -= 10;
-        }
-     }
-  } else {
-     tempcx = (tempcx + tempbx) >> 1;
-     temp = (tempcx & 0x00FF) + 2;
-     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-        temp--;
-        if(!(modeflag & HalfDCLK)) {
-           if((modeflag & Charx8Dot)) {
-              temp += 4;
-              if(SiS_Pr->SiS_VGAHDE >= 800) temp -= 6;
-              if(HwInfo->jChipType >= SIS_315H) {
-                if(SiS_Pr->SiS_VGAHDE == 800) temp += 2;
-              }
-           }
-        }
-     } else {
-        if(!(modeflag & HalfDCLK)) {
-           temp -= 4;
-           if((SiS_Pr->SiS_LCDResInfo != Panel_1280x960) &&
-             (SiS_Pr->SiS_LCDResInfo != Panel_1600x1200)) {
-              if(SiS_Pr->SiS_VGAHDE >= 800) {
-                 temp -= 7;
-                if(HwInfo->jChipType < SIS_315H) {
-                    if(SiS_Pr->SiS_ModeType == ModeEGA) {
-                       if(SiS_Pr->SiS_VGAVDE == 1024) {
-                          temp += 15;
-                          if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024)
-                            temp += 7;
-                       }
-                    }
-                }
-                if(SiS_Pr->SiS_LCDResInfo != Panel_1400x1050) {
-                    if(SiS_Pr->SiS_VGAHDE >= 1280) {
-                       if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) temp += 28;
-                   }
-                 }
-              }
-           }
-        }
-     }
+     SiS_Pr->CHBlankStart += 16;
   }
 
-  p1_7 = temp;
-  p1_8 = 0x00;
-
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-     if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
-        if(ModeNo <= 0x01) {
-          p1_7 = 0x2a;
-          if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) p1_8 = 0x61;
-          else                                 p1_8 = 0x41;
-       } else if(SiS_Pr->SiS_ModeType == ModeText) {
-          if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) p1_7 = 0x54;
-          else                                 p1_7 = 0x55;
-          p1_8 = 0x00;
-       } else if(ModeNo <= 0x13) {
-          if(modeflag & HalfDCLK) {
-             if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
-                p1_7 = 0x30;
-                p1_8 = 0x03;
-             } else {
-                p1_7 = 0x2f;
-                p1_8 = 0x02;
-             }
-          } else {
-             p1_7 = 0x5b;
-             p1_8 = 0x03;
-          }
-       } else if( ((HwInfo->jChipType >= SIS_315H) &&
-                   ((ModeNo == 0x50) || (ModeNo == 0x56) || (ModeNo == 0x53))) ||
-                  ((HwInfo->jChipType < SIS_315H) &&
-                   (resinfo == SIS_RI_320x200 || resinfo == SIS_RI_320x240)) ) {
-          if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
-             p1_7 = 0x30,
-             p1_8 = 0x03;
-          } else {
-             p1_7 = 0x2f;
-             p1_8 = 0x03;
-          }
-        }
-     }
+  SiS_Pr->CHBlankEnd = 32;
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+     if(xres == 1600) SiS_Pr->CHBlankEnd += 80;
   }
 
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
-     if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p)) {
-        p1_7 = 0x63;
-       if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) p1_7 = 0x55;
-     }
-     if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
-        if(!(modeflag & HalfDCLK)) {
-          p1_7 = 0xb2;
-          if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
-             p1_7 = 0xab;
-          }
-       }
-     } else {
-        if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
-          if(modeflag & HalfDCLK) p1_7 = 0x30;
-       }
-     }
+  temp = SiS_Pr->SiS_VGAHT - 96;
+  if(!(modeflag & HalfDCLK)) temp -= 32;
+  if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
+     temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x04);
+     temp |= ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x0b) & 0xc0) << 2);
+     temp -= 3;
+     temp <<= 3;
+  } else {
+     if(SiS_Pr->SiS_RVBHRS2) temp = SiS_Pr->SiS_RVBHRS2;
   }
+  SiS_Pr->CHSyncStart = temp;
 
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,p1_7);                 /* 0x07 Horizontal Retrace Start */
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,p1_8);                 /* 0x08 Horizontal Retrace End   */
-
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x03);                 /* 0x18 SR08 (FIFO Threshold?)   */
+  SiS_Pr->CHSyncEnd = 0xffe8;  /* results in 0x2000 in registers */
 
-  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x19,0xF0);
+  SiS_Pr->CVTotal = 2049;      /* Max VT, 0x0801, results in 0x7ff in registers */
 
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,0xFF);                 /* 0x09 Set Max VT    */
+  VGAVDE = SiS_Pr->SiS_VGAVDE;
+  if     (VGAVDE ==  357) VGAVDE =  350;
+  else if(VGAVDE ==  360) VGAVDE =  350;
+  else if(VGAVDE ==  375) VGAVDE =  350;
+  else if(VGAVDE ==  405) VGAVDE =  400;
+  else if(VGAVDE ==  420) VGAVDE =  400;
+  else if(VGAVDE ==  525) VGAVDE =  480;
+  else if(VGAVDE == 1056) VGAVDE = 1024;
+  SiS_Pr->CVDisplay = VGAVDE;
 
-  tempcx = 0x121;
-  tempbx = SiS_Pr->SiS_VGAVDE;                                 /* 0x0E Vertical Display End */
-  if     (tempbx == 357) tempbx = 350;
-  else if(tempbx == 360) tempbx = 350;
-  else if(tempbx == 375) tempbx = 350;
-  else if(tempbx == 405) tempbx = 400;
-  else if(tempbx == 420) tempbx = 400;
-  else if(tempbx == 525) tempbx = 480;
-  push2 = tempbx;
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
-       if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
-           if     (tempbx == 350) tempbx += 5;
-           else if(tempbx == 480) tempbx += 5;
-       }
-     }
-  }
-  tempbx -= 2;
-  temp = tempbx & 0x00FF;
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,temp);                 /* 0x10 vertical Blank Start */
-
-  tempbx = push2;
-  tempbx--;
-  temp = tempbx & 0x00FF;
-#if 0
-  /* Missing code from 630/301B 2.04.5a and 650/302LV 1.10.6s (calles int 2f) */
-  if(xxx()) {
-      if(temp == 0xdf) temp = 0xda;
-  }
-#endif
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp);
-
-  temp = 0;
-  if(modeflag & DoubleScanMode) temp |= 0x80;
-  if(HwInfo->jChipType >= SIS_661) {
-     if(tempbx & 0x0200)        temp |= 0x20;
-     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x0B,0x5F,temp);
-     if(tempbx & 0x0100)  tempcx |= 0x000a;
-     if(tempbx & 0x0400)  tempcx |= 0x1200;
-  } else {
-     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,temp);
-     if(tempbx & 0x0100)  tempcx |= 0x0002;
-     if(tempbx & 0x0400)  tempcx |= 0x0600;
-  }
+  SiS_Pr->CVBlankStart = SiS_Pr->CVDisplay;
 
-  if(tempbx & 0x0200)  tempcx |= 0x0040;
+  SiS_Pr->CVBlankEnd = 1;
+  if(ModeNo == 0x3c) SiS_Pr->CVBlankEnd = 226;
 
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,0x00);                 /* 0x11 Vertical Blank End */
+  temp = (SiS_Pr->SiS_VGAVT - VGAVDE) >> 1;
+  SiS_Pr->CVSyncStart = VGAVDE + temp;
 
-  tempax = (SiS_Pr->SiS_VGAVT - tempbx) >> 2;
+  temp >>= 3;
+  SiS_Pr->CVSyncEnd = SiS_Pr->CVSyncStart + temp;
 
-  if((ModeNo > 0x13) || (HwInfo->jChipType < SIS_315H)) {
-     if(resinfo != SIS_RI_1280x1024) {
-       tempbx += (tempax << 1);
-     }
-  } else if(HwInfo->jChipType >= SIS_315H) {
-     if(SiS_Pr->SiS_LCDResInfo != Panel_1400x1050) {
-       tempbx += (tempax << 1);
-     }
-  }
+  SiS_CalcCRRegisters(SiS_Pr, 0);
+  SiS_Pr->CCRT1CRTC[16] &= ~0xE0;
 
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
-     tempbx -= 10;
-  } else {
-     if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
-        if(SiS_Pr->SiS_TVMode & TVSetPAL) {
-           tempbx += 40;
-          if(HwInfo->jChipType >= SIS_315H) {
-             if(SiS_Pr->SiS_VGAHDE == 800) tempbx += 10;
-          }
-       }
-     }
+  for(i = 0; i <= 7; i++) {
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[i]);
   }
-  tempax >>= 2;
-  tempax++;
-  tempax += tempbx;
-  push1 = tempax;
-  if(SiS_Pr->SiS_TVMode & TVSetPAL) {
-     if(tempbx <= 513)  {
-       if(tempax >= 513) tempbx = 513;
-     }
+  for(i = 0x10, j = 8; i <= 0x12; i++, j++) {
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
   }
-  temp = tempbx & 0x00FF;
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp);                 /* 0x0C Vertical Retrace Start */
-
-  tempbx--;
-  temp = tempbx & 0x00FF;
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,temp);
-
-  if(tempbx & 0x0100) tempcx |= 0x0008;
-
-  if(tempbx & 0x0200) {
-     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x0B,0x20);
+  for(i = 0x15, j = 11; i <= 0x16; i++, j++) {
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
   }
-  tempbx++;
-
-  if(tempbx & 0x0100) tempcx |= 0x0004;
-  if(tempbx & 0x0200) tempcx |= 0x0080;
-  if(tempbx & 0x0400) {
-     if(HwInfo->jChipType >= SIS_661)        tempcx |= 0x0800;
-     else if(SiS_Pr->SiS_VBType & VB_SIS301) tempcx |= 0x0800;
-     else                                    tempcx |= 0x0C00;
+  for(i = 0x0a, j = 13; i <= 0x0c; i++, j++) {
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
   }
 
-  tempbx = push1;
-  temp = tempbx & 0x000F;
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,temp);                 /* 0x0D vertical Retrace End */
-
-  if(tempbx & 0x0010) tempcx |= 0x2000;
-
-  temp = tempcx & 0x00FF;
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp);                 /* 0x0A CR07 */
+  temp = SiS_Pr->CCRT1CRTC[16] & 0xE0;
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x0E],0x1F,temp);
 
-  temp = (tempcx & 0xFF00) >> 8;
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp);                 /* 0x17 SR0A */
-
-  tempax = modeflag;
-  temp = (tempax & 0xFF00) >> 8;
-  temp = (temp >> 1) & 0x09;
-  if(!(SiS_Pr->SiS_VBType & VB_SIS301)) temp |= 0x01;          /* Always 8 dotclock */
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp);                 /* 0x16 SR01 */
+  temp = (SiS_Pr->CCRT1CRTC[16] & 0x01) << 5;
+  if(modeflag & DoubleScanMode) temp |= 0x80;
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x09],0x5F,temp);
 
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,0x00);                 /* 0x0F CR14 */
+  temp = 0;
+  temp |= (SiS_GetReg(SiS_Pr->SiS_P3c4,0x01) & 0x01);
+  if(modeflag & HalfDCLK) temp |= 0x08;
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp);                 /* SR01: HalfDCLK[3], 8/9 div dotclock[0] */
 
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,0x00);                 /* 0x12 CR17 */
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,0x00);                 /* CR14: (text mode: underline location) */
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,0x00);                 /* CR17: n/a */
 
-  temp = 0x00;
+  temp = 0;
   if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
-     if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
-       temp = 0x80;
-     }
+     temp = (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) << 7;
   }
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp);                 /* 0x1A SR0E */
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp);                 /* SR0E, dither[7] */
 
   temp = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);                 /* ? */
+
+#ifdef SIS_XORG_XF86
+#ifdef TWDEBUG
+   xf86DrvMsg(0, X_INFO, "%d %d %d %d  %d %d %d %d  (%d %d %d %d)\n",
+       SiS_Pr->CHDisplay, SiS_Pr->CHSyncStart, SiS_Pr->CHSyncEnd, SiS_Pr->CHTotal,
+       SiS_Pr->CVDisplay, SiS_Pr->CVSyncStart, SiS_Pr->CVSyncEnd, SiS_Pr->CVTotal,
+       SiS_Pr->CHBlankStart, SiS_Pr->CHBlankEnd, SiS_Pr->CVBlankStart, SiS_Pr->CVBlankEnd);
+
+   xf86DrvMsg(0, X_INFO, " {{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
+       SiS_Pr->CCRT1CRTC[0], SiS_Pr->CCRT1CRTC[1],
+       SiS_Pr->CCRT1CRTC[2], SiS_Pr->CCRT1CRTC[3],
+       SiS_Pr->CCRT1CRTC[4], SiS_Pr->CCRT1CRTC[5],
+       SiS_Pr->CCRT1CRTC[6], SiS_Pr->CCRT1CRTC[7]);
+   xf86DrvMsg(0, X_INFO, "   0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
+       SiS_Pr->CCRT1CRTC[8], SiS_Pr->CCRT1CRTC[9],
+       SiS_Pr->CCRT1CRTC[10], SiS_Pr->CCRT1CRTC[11],
+       SiS_Pr->CCRT1CRTC[12], SiS_Pr->CCRT1CRTC[13],
+       SiS_Pr->CCRT1CRTC[14], SiS_Pr->CCRT1CRTC[15]);
+   xf86DrvMsg(0, X_INFO, "   0x%02x}},\n", SiS_Pr->CCRT1CRTC[16]);
+#endif
+#endif
 }
 
 /* Setup panel link
@@ -5637,18 +5451,18 @@ SiS_SetGroup1_301(SiS_Private *SiS_Pr, USHORT ModeNo,USHORT ModeIdIndex,
  * 300/LVDS+TV, 300/301B-DH, 315/LVDS+TV, 315/LCDA
  */
 static void
-SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
-                   PSIS_HW_INFO HwInfo, USHORT RefreshRateTableIndex)
+SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
+               unsigned short RefreshRateTableIndex)
 {
-  USHORT modeflag,resinfo;
-  USHORT push2,tempax,tempbx,tempcx,temp;
-  ULONG tempeax=0,tempebx,tempecx,tempvcfact=0;
+  unsigned short modeflag, resinfo = 0;
+  unsigned short push2, tempax, tempbx, tempcx, temp;
+  unsigned int   tempeax = 0, tempebx, tempecx, tempvcfact = 0;
   BOOLEAN islvds = FALSE, issis  = FALSE, chkdclkfirst = FALSE;
 #ifdef SIS300
-  USHORT crt2crtc;
+  unsigned short crt2crtc = 0;
 #endif
 #ifdef SIS315H
-  USHORT pushcx;
+  unsigned short pushcx;
 #endif
 
   if(ModeNo <= 0x13) {
@@ -5659,15 +5473,11 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 #endif
   } else if(SiS_Pr->UseCustomMode) {
      modeflag = SiS_Pr->CModeFlag;
-     resinfo = 0;
-#ifdef SIS300
-     crt2crtc = 0;
-#endif
   } else {
      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
 #ifdef SIS300
-     crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+     crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
 #endif
   }
 
@@ -5681,14 +5491,14 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
      issis = TRUE;
   }
 
-  if((HwInfo->jChipType >= SIS_315H) && (islvds) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA))) {
+  if((SiS_Pr->ChipType >= SIS_315H) && (islvds) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA))) {
      if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
         chkdclkfirst = TRUE;
      }
   }
 
 #ifdef SIS315H
-  if((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+  if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
      if(IS_SIS330) {
         SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
      } else if(IS_SIS740) {
@@ -5704,7 +5514,7 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x00);
         } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2D,0x0f);
-          if(SiS_Pr->SiS_VBType & VB_SIS301C) {
+          if(SiS_Pr->SiS_VBType & VB_SIS30xC) {
              if((SiS_Pr->SiS_LCDResInfo == Panel_1024x768) ||
                 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
                 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x20);
@@ -5720,10 +5530,10 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
   tempax = SiS_Pr->SiS_LCDHDES;
   if(islvds) {
      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
-        if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
-           if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) &&
-              (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
-             tempax -= 8;
+       if(!SiS_Pr->SiS_IF_DEF_FSTN && !SiS_Pr->SiS_IF_DEF_DSTN) {
+          if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) &&
+             (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
+             tempax -= 8;
           }
        }
      }
@@ -5736,13 +5546,14 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 
   tempbx = SiS_Pr->SiS_HDE;
   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
-     if((SiS_Pr->SiS_LCDResInfo == Panel_640x480_2) ||
-        (SiS_Pr->SiS_LCDResInfo == Panel_640x480_3)) {
-        tempbx >>= 1;
-     }
      if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
         tempbx = SiS_Pr->PanelXRes;
      }
+     if((SiS_Pr->SiS_LCDResInfo == Panel_320x240_1) ||
+        (SiS_Pr->SiS_LCDResInfo == Panel_320x240_2) ||
+        (SiS_Pr->SiS_LCDResInfo == Panel_320x240_3)) {
+        tempbx >>= 1;
+     }
   }
 
   tempax += tempbx;
@@ -5767,25 +5578,25 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
   temp = (tempcx >> 3) & 0x00FF;
   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
      if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
-        if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
-           switch(ModeNo) {
-           case 0x04:
-           case 0x05:
-           case 0x0d: temp = 0x56; break;
-           case 0x10: temp = 0x60; break;
-           case 0x13: temp = 0x5f; break;
-           case 0x40:
-           case 0x41:
-           case 0x4f:
-           case 0x43:
-           case 0x44:
-           case 0x62:
-           case 0x56:
-           case 0x53:
-           case 0x5d:
-           case 0x5e: temp = 0x54; break;
-           }
-        }
+       if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
+          switch(ModeNo) {
+          case 0x04:
+          case 0x05:
+          case 0x0d: temp = 0x56; break;
+          case 0x10: temp = 0x60; break;
+          case 0x13: temp = 0x5f; break;
+          case 0x40:
+          case 0x41:
+          case 0x4f:
+          case 0x43:
+          case 0x44:
+          case 0x62:
+          case 0x56:
+          case 0x53:
+          case 0x5d:
+          case 0x5e: temp = 0x54; break;
+          }
+       }
      }
   }
   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,temp);                 /* BPLHRS */
@@ -5793,12 +5604,12 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
      temp += 2;
      if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
-        temp += 8;
-        if(SiS_Pr->PanelHRE != 999) {
-           temp = tempcx + SiS_Pr->PanelHRE;
+       temp += 8;
+       if(SiS_Pr->PanelHRE != 999) {
+          temp = tempcx + SiS_Pr->PanelHRE;
           if(temp >= SiS_Pr->SiS_HT) temp -= SiS_Pr->SiS_HT;
           temp >>= 3;
-        }
+       }
      }
   } else {
      temp += 10;
@@ -5806,9 +5617,6 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 
   temp &= 0x1F;
   temp |= ((tempcx & 0x07) << 5);
-#if 0
-  if(SiS_Pr->SiS_IF_DEF_FSTN) temp = 0x20;                     /* WRONG? BIOS loads cl, not ah */
-#endif
   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,temp);                 /* BPLHRE */
 
   /* Vertical */
@@ -5826,9 +5634,9 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
   push2 = tempbx;
 
   tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE;
-  if(HwInfo->jChipType < SIS_315H) {
+  if(SiS_Pr->ChipType < SIS_315H) {
      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
-        if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
+       if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
           tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->PanelYRes;
        }
      }
@@ -5844,19 +5652,19 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
      if(issis) tempbx++;
   } else {
      tempbx += tempcx;
-     if(HwInfo->jChipType < SIS_315H) tempbx++;
+     if(SiS_Pr->ChipType < SIS_315H) tempbx++;
      else if(issis)                   tempbx++;
   }
 
-  if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;       /* BPLVRS  */
+  if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
 
   temp = tempbx & 0x00FF;
   if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
-        if(ModeNo == 0x10) temp = 0xa9;
+       if(ModeNo == 0x10) temp = 0xa9;
      }
   }
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);                 /* BPLVRS */
 
   tempcx >>= 3;
   tempcx++;
@@ -5879,13 +5687,13 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
   } else if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
   if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA)          temp |= 0x40;
   tempbx = 0x87;
-  if((HwInfo->jChipType >= SIS_315H) ||
-     (HwInfo->jChipRevision >= 0x30)) {
+  if((SiS_Pr->ChipType >= SIS_315H) ||
+     (SiS_Pr->ChipRevision >= 0x30)) {
      tempbx = 0x07;
      if((SiS_Pr->SiS_IF_DEF_CH70xx == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
        if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x03)    temp |= 0x80;
      }
-     /* Chrontel 701x operates in 24bit mode (8-8-8, 2x12bit mutliplexed) via VGA2 */
+     /* Chrontel 701x operates in 24bit mode (8-8-8, 2x12bit multiplexed) via VGA2 */
      if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
           if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x10)      temp |= 0x80;
@@ -5896,59 +5704,58 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
   }
   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,tempbx,temp);
 
-  tempbx = push2;                                                      /* BPLVDEE */
+  tempbx = push2;                                              /* BPLVDEE */
 
-  tempcx = SiS_Pr->SiS_LCDVDES;                                        /* BPLVDES */
+  tempcx = SiS_Pr->SiS_LCDVDES;                                        /* BPLVDES */
 
   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
      switch(SiS_Pr->SiS_LCDResInfo) {
      case Panel_640x480:
-        tempbx = SiS_Pr->SiS_VGAVDE - 1;
-        tempcx = SiS_Pr->SiS_VGAVDE;
+       tempbx = SiS_Pr->SiS_VGAVDE - 1;
+       tempcx = SiS_Pr->SiS_VGAVDE;
        break;
      case Panel_800x600:
-        if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-           if(resinfo == SIS_RI_800x600) tempcx++;
-        }
+       if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+          if(resinfo == SIS_RI_800x600) tempcx++;
+       }
        break;
      case Panel_1024x600:
-        if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-           if(resinfo == SIS_RI_1024x600) tempcx++;
-           if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+       if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+          if(resinfo == SIS_RI_1024x600) tempcx++;
+          if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
              if(resinfo == SIS_RI_800x600) tempcx++;
           }
-        }
+       }
        break;
      case Panel_1024x768:
-        if(HwInfo->jChipType < SIS_315H) {
-           if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-              if(resinfo == SIS_RI_1024x768) tempcx++;
+       if(SiS_Pr->ChipType < SIS_315H) {
+          if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+             if(resinfo == SIS_RI_1024x768) tempcx++;
           }
-        }
+       }
        break;
      }
   }
 
   temp = ((tempbx >> 8) & 0x07) << 3;
-  temp = temp | ((tempcx >> 8) & 0x07);
+  temp |= ((tempcx >> 8) & 0x07);
   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1D,temp);
-  /* if(SiS_Pr->SiS_IF_DEF_FSTN) tempbx++;  */
   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1C,tempbx);
   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1B,tempcx);
 
   /* Vertical scaling */
 
-  if(HwInfo->jChipType < SIS_315H) {
+  if(SiS_Pr->ChipType < SIS_315H) {
 
 #ifdef SIS300      /* 300 series */
      tempeax = SiS_Pr->SiS_VGAVDE << 6;
-     temp = (tempeax % (ULONG)SiS_Pr->SiS_VDE);
-     tempeax = tempeax / (ULONG)SiS_Pr->SiS_VDE;
+     temp = (tempeax % (unsigned int)SiS_Pr->SiS_VDE);
+     tempeax = tempeax / (unsigned int)SiS_Pr->SiS_VDE;
      if(temp) tempeax++;
 
      if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) tempeax = 0x3F;
 
-     temp = (USHORT)(tempeax & 0x00FF);
+     temp = (unsigned short)(tempeax & 0x00FF);
      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,temp);              /* BPLVCFACT */
      tempvcfact = temp;
 #endif /* SIS300 */
@@ -5963,20 +5770,20 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
      if(temp) tempeax++;
      tempvcfact = tempeax;
 
-     temp = (USHORT)(tempeax & 0x00FF);
+     temp = (unsigned short)(tempeax & 0x00FF);
      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,temp);
-     temp = (USHORT)((tempeax & 0x00FF00) >> 8);
+     temp = (unsigned short)((tempeax & 0x00FF00) >> 8);
      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,temp);
-     temp = (USHORT)((tempeax & 0x00030000) >> 16);
+     temp = (unsigned short)((tempeax & 0x00030000) >> 16);
      if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,temp);
 
-     if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV)) {
-        temp = (USHORT)(tempeax & 0x00FF);
+     if(SiS_Pr->SiS_VBType & VB_SISPART4SCALER) {
+        temp = (unsigned short)(tempeax & 0x00FF);
         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3c,temp);
-        temp = (USHORT)((tempeax & 0x00FF00) >> 8);
+        temp = (unsigned short)((tempeax & 0x00FF00) >> 8);
         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3b,temp);
-        temp = (USHORT)(((tempeax & 0x00030000) >> 16) << 6);
+        temp = (unsigned short)(((tempeax & 0x00030000) >> 16) << 6);
         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0x3f,temp);
         temp = 0;
         if(SiS_Pr->SiS_VDE != SiS_Pr->SiS_VGAVDE) temp |= 0x08;
@@ -5997,29 +5804,29 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
      tempecx = 0xFFFF;
   } else {
      tempecx = tempebx / SiS_Pr->SiS_HDE;
-     if(HwInfo->jChipType >= SIS_315H) {
+     if(SiS_Pr->ChipType >= SIS_315H) {
         if(tempebx % SiS_Pr->SiS_HDE) tempecx++;
      }
   }
 
-  if(HwInfo->jChipType >= SIS_315H) {
+  if(SiS_Pr->ChipType >= SIS_315H) {
      tempeax = (tempebx / tempecx) - 1;
   } else {
      tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1;
   }
   tempecx = (tempecx << 16) | (tempeax & 0xFFFF);
-  temp = (USHORT)(tempecx & 0x00FF);
+  temp = (unsigned short)(tempecx & 0x00FF);
   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1F,temp);
 
-  if(HwInfo->jChipType >= SIS_315H) {
+  if(SiS_Pr->ChipType >= SIS_315H) {
      tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
-     tempbx = (USHORT)(tempeax & 0xFFFF);
+     tempbx = (unsigned short)(tempeax & 0xFFFF);
   } else {
      tempeax = SiS_Pr->SiS_VGAVDE << 6;
      tempbx = tempvcfact & 0x3f;
      if(tempbx == 0) tempbx = 64;
      tempeax /= tempbx;
-     tempbx = (USHORT)(tempeax & 0xFFFF);
+     tempbx = (unsigned short)(tempeax & 0xFFFF);
   }
   if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tempbx--;
   if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
@@ -6032,24 +5839,24 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x20,temp);
   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x21,tempbx);
 
-  tempecx >>= 16;                                              /* BPLHCFACT  */
+  tempecx >>= 16;                                              /* BPLHCFACT  */
   if(!chkdclkfirst) {
      if(modeflag & HalfDCLK) tempecx >>= 1;
   }
-  temp = (USHORT)((tempecx & 0xFF00) >> 8);
+  temp = (unsigned short)((tempecx & 0xFF00) >> 8);
   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x22,temp);
-  temp = (USHORT)(tempecx & 0x00FF);
+  temp = (unsigned short)(tempecx & 0x00FF);
   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp);
 
 #ifdef SIS315H
-  if(HwInfo->jChipType >= SIS_315H) {
+  if(SiS_Pr->ChipType >= SIS_315H) {
      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
-        if((islvds) || (SiS_Pr->SiS_VBInfo & VB_SIS301LV302LV)) {
+        if((islvds) || (SiS_Pr->SiS_VBInfo & VB_SISLVDS)) {
            SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x20);
        }
      } else {
         if(islvds) {
-           if(HwInfo->jChipType == SIS_740) {
+           if(SiS_Pr->ChipType == SIS_740) {
               SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
            } else {
              SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x23);
@@ -6061,17 +5868,26 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 
 #ifdef SIS300
   if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
-     int i;
-     UCHAR TrumpMode13[4]   = { 0x01, 0x10, 0x2c, 0x00 };
-     UCHAR TrumpMode10_1[4] = { 0x01, 0x10, 0x27, 0x00 };
-     UCHAR TrumpMode10_2[4] = { 0x01, 0x16, 0x10, 0x00 };
+     unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
+     unsigned char *trumpdata;
+     int   i, j = crt2crtc;
+     unsigned char TrumpMode13[4]   = { 0x01, 0x10, 0x2c, 0x00 };
+     unsigned char TrumpMode10_1[4] = { 0x01, 0x10, 0x27, 0x00 };
+     unsigned char TrumpMode10_2[4] = { 0x01, 0x16, 0x10, 0x00 };
+
+     if(SiS_Pr->SiS_UseROM) {
+       trumpdata = &ROMAddr[0x8001 + (j * 80)];
+     } else {
+       if(SiS_Pr->SiS_LCDTypeInfo == 0x0e) j += 7;
+       trumpdata = &SiS300_TrumpionData[j][0];
+     }
 
      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xbf);
      for(i=0; i<5; i++) {
-        SiS_SetTrumpionBlock(SiS_Pr, &SiS300_TrumpionData[crt2crtc][0]);
+       SiS_SetTrumpionBlock(SiS_Pr, trumpdata);
      }
      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
-        if(ModeNo == 0x13) {
+       if(ModeNo == 0x13) {
           for(i=0; i<4; i++) {
              SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode13[0]);
           }
@@ -6095,67 +5911,66 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x29,0x5A);
      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2A,0x4B);
      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x07,0x03);
-     tempax = SiS_Pr->SiS_HDE;                                 /* Blps = lcdhdee(lcdhdes+HDE) + 64 */
-     if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
-        SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1;
+     tempax = SiS_Pr->SiS_HDE;                                 /* Blps = lcdhdee(lcdhdes+HDE) + 64 */
+     if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
+        SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
+        SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
      tempax += 64;
-     temp = tempax & 0x00FF;
-     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,temp);
-     temp = ((tempax & 0xFF00) >> 8) << 3;
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,tempax & 0xff);
+     temp = (tempax >> 8) << 3;
      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp);
-     tempax += 32;                                             /* Blpe=lBlps+32 */
-     temp = tempax & 0x00FF;
-     if(SiS_Pr->SiS_IF_DEF_FSTN) temp = 0;
-     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,temp);
-     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3A,0x00);              /* Bflml=0 */
-     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x007,0x00);
+     tempax += 32;                                             /* Blpe = lBlps+32 */
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,tempax & 0xff);
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3A,0x00);              /* Bflml = 0 */
+     SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x007);
 
      tempax = SiS_Pr->SiS_VDE;
-     if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
-        SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1;
+     if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
+        SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
+        SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
      tempax >>= 1;
-     temp = tempax & 0x00FF;
-     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3B,temp);
-     temp = ((tempax & 0xFF00) >> 8) << 3;
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3B,tempax & 0xff);
+     temp = (tempax >> 8) << 3;
      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);
 
      tempeax = SiS_Pr->SiS_HDE;
-     if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
-        SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempeax >>= 1;
-     tempeax <<= 2;                                            /* BDxFIFOSTOP = (HDE*4)/128 */
-     tempebx = 128;
-     temp = (USHORT)(tempeax % tempebx);
-     tempeax = tempeax / tempebx;
+     if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
+        SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
+        SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempeax >>= 1;
+     tempeax <<= 2;                                            /* BDxFIFOSTOP = (HDE*4)/128 */
+     temp = tempeax & 0x7f;
+     tempeax >>= 7;
      if(temp) tempeax++;
-     temp = (USHORT)(tempeax & 0x003F);
-     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x45,~0x0FF,temp);
-     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3F,0x00);              /* BDxWadrst0 */
+     temp = tempeax & 0x3f;
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,temp);
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3F,0x00);              /* BDxWadrst0 */
      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3E,0x00);
      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3D,0x10);
-     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x040,0x00);
+     SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x040);
 
      tempax = SiS_Pr->SiS_HDE;
-     if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
-        SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1;
-     tempax >>= 4;                                             /* BDxWadroff = HDE*4/8/8 */
+     if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
+        SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
+        SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
+     tempax >>= 4;                                             /* BDxWadroff = HDE*4/8/8 */
      pushcx = tempax;
      temp = tempax & 0x00FF;
      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,temp);
      temp = ((tempax & 0xFF00) >> 8) << 3;
      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x0F8,temp);
 
-     tempax = SiS_Pr->SiS_VDE;                                 /* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
-     if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
-        SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1;
-     tempeax = (tempax * pushcx);
-     tempebx = 0x00100000 + tempeax;
-     temp = (USHORT)tempebx & 0x000000FF;
+     tempax = SiS_Pr->SiS_VDE;                                 /* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
+     if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
+        SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
+        SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
+     tempeax = tempax * pushcx;
+     temp = tempeax & 0xFF;
      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,temp);
-     temp = (USHORT)((tempebx & 0x0000FF00) >> 8);
+     temp = (tempeax & 0xFF00) >> 8;
      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,temp);
-     temp = (USHORT)((tempebx & 0x00FF0000) >> 16);
+     temp = ((tempeax & 0xFF0000) >> 16) | 0x10;
      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,temp);
-     temp = (USHORT)(((tempebx & 0x01000000) >> 24) << 7);
+     temp = ((tempeax & 0x01000000) >> 24) << 7;
      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x080,temp);
 
      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x03);
@@ -6192,20 +6007,20 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 
 /* Set Part 1 */
 static void
-SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
-              PSIS_HW_INFO HwInfo, USHORT RefreshRateTableIndex)
+SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
+               unsigned short RefreshRateTableIndex)
 {
 #if defined(SIS300) || defined(SIS315H)
-  UCHAR   *ROMAddr = HwInfo->pjVirtualRomBase;
+  unsigned char   *ROMAddr = SiS_Pr->VirtualRomBase;
 #endif
-  USHORT  temp=0, tempax=0, tempbx=0, tempcx=0, bridgeadd=0;
-  USHORT  pushbx=0, CRT1Index=0, modeflag, resinfo=0;
+  unsigned short  temp=0, tempax=0, tempbx=0, tempcx=0, bridgeadd=0;
+  unsigned short  pushbx=0, CRT1Index=0, modeflag, resinfo=0;
 #ifdef SIS315H
-  USHORT  tempbl=0;
+  unsigned short  tempbl=0;
 #endif
 
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
-     SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
+     SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
      return;
   }
 
@@ -6214,47 +6029,47 @@ SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
   } else if(SiS_Pr->UseCustomMode) {
      modeflag = SiS_Pr->CModeFlag;
   } else {
-     CRT1Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+     CRT1Index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);
      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
   }
 
-  SiS_SetCRT2Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
+  SiS_SetCRT2Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
 
-  if( ! ((HwInfo->jChipType >= SIS_315H) &&
+  if( ! ((SiS_Pr->ChipType >= SIS_315H) &&
          (SiS_Pr->SiS_IF_DEF_LVDS == 1) &&
          (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
 
-     if(HwInfo->jChipType < SIS_315H ) {
+     if(SiS_Pr->ChipType < SIS_315H ) {
 #ifdef SIS300
-       SiS_SetCRT2FIFO_300(SiS_Pr, ModeNo, HwInfo);
+       SiS_SetCRT2FIFO_300(SiS_Pr, ModeNo);
 #endif
      } else {
 #ifdef SIS315H
-        SiS_SetCRT2FIFO_310(SiS_Pr, HwInfo);
+       SiS_SetCRT2FIFO_310(SiS_Pr);
 #endif
      }
 
      /* 1. Horizontal setup */
 
-     if(HwInfo->jChipType < SIS_315H ) {
+     if(SiS_Pr->ChipType < SIS_315H ) {
 
 #ifdef SIS300   /* ------------- 300 series --------------*/
 
-       temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF;                   /* BTVGA2HT 0x08,0x09 */
-       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp);              /* CRT2 Horizontal Total */
+       temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF;                   /* BTVGA2HT 0x08,0x09 */
+       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp);              /* CRT2 Horizontal Total */
 
-       temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
-       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp);    /* CRT2 Horizontal Total Overflow [7:4] */
+       temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
+       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp);    /* CRT2 Horizontal Total Overflow [7:4] */
 
-       temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF;                 /* BTVGA2HDEE 0x0A,0x0C */
-       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp);              /* CRT2 Horizontal Display Enable End */
+       temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF;                 /* BTVGA2HDEE 0x0A,0x0C */
+       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp);              /* CRT2 Horizontal Display Enable End */
 
        pushbx = SiS_Pr->SiS_VGAHDE + 12;                         /* bx  BTVGA2HRS 0x0B,0x0C */
-       tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2;
-       tempbx = pushbx + tempcx;
-       tempcx <<= 1;
-       tempcx += tempbx;
+       tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2;
+       tempbx = pushbx + tempcx;
+       tempcx <<= 1;
+       tempcx += tempbx;
 
        bridgeadd = 12;
 
@@ -6301,7 +6116,7 @@ SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
        bridgeadd = 16;
 
        if(SiS_Pr->SiS_VBType & VB_SISVB) {
-          if(HwInfo->jChipType >= SIS_661) {
+          if(SiS_Pr->ChipType >= SIS_661) {
              if((SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
                 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
                 if(resinfo == SIS_RI_1280x1024) {
@@ -6319,7 +6134,7 @@ SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 
      if(SiS_Pr->SiS_VBType & VB_SISVB) {
 
-        if(SiS_Pr->UseCustomMode) {
+       if(SiS_Pr->UseCustomMode) {
           tempbx = SiS_Pr->CHSyncStart + bridgeadd;
           tempcx = SiS_Pr->CHSyncEnd + bridgeadd;
           tempax = SiS_Pr->SiS_VGAHT;
@@ -6341,22 +6156,22 @@ SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
              cr5  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
              cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
           }
-           tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3;               /* (VGAHRS-3)*8 */
-           tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3;   /* (VGAHRE-3)*8 */
+          tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3;                /* (VGAHRS-3)*8 */
+          tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3;   /* (VGAHRE-3)*8 */
           tempcx &= 0x00FF;
           tempcx |= (tempbx & 0xFF00);
-           tempbx += bridgeadd;
-           tempcx += bridgeadd;
+          tempbx += bridgeadd;
+          tempcx += bridgeadd;
           tempax = SiS_Pr->SiS_VGAHT;
           if(modeflag & HalfDCLK) tempax >>= 1;
           tempax--;
           if(tempcx > tempax) tempcx = tempax;
-        }
+       }
 
-        if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
-          tempbx = 1040;
-          tempcx = 1044;   /* HWCursor bug! */
-        }
+       if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {
+          tempbx = 1040;
+          tempcx = 1044;   /* HWCursor bug! */
+       }
 
      }
 
@@ -6372,18 +6187,18 @@ SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
      tempcx = SiS_Pr->SiS_VGAVT - 1;
      temp = tempcx & 0x00FF;
 
-     if(HwInfo->jChipType < SIS_661) {
+     if(SiS_Pr->ChipType < SIS_661) {
         if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-          if(HwInfo->jChipType < SIS_315H) {
+          if(SiS_Pr->ChipType < SIS_315H) {
              if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
                 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
                    temp--;
                 }
-              }
+             }
           } else {
-             temp--;
-           }
-        } else if(HwInfo->jChipType >= SIS_315H) {
+             temp--;
+          }
+       } else if(SiS_Pr->ChipType >= SIS_315H) {
           temp--;
        }
      }
@@ -6395,9 +6210,9 @@ SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
      temp = ((tempbx >> 5) & 0x38) | ((tempcx >> 8) & 0x07);
      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,temp);                 /* Overflow */
 
-     if((HwInfo->jChipType >= SIS_315H) && (HwInfo->jChipType < SIS_661)) {
-        tempbx++;
-       tempax = tempbx;
+     if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
+       tempbx++;
+       tempax = tempbx;
        tempcx++;
        tempcx -= tempax;
        tempcx >>= 2;
@@ -6407,8 +6222,8 @@ SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
        tempcx += tempbx;
        tempcx++;
      } else {
-       tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1;                 /*  BTVGA2VRS     0x10,0x11   */
-       tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1;  /*  BTVGA2VRE     0x11        */
+       tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1;                 /*  BTVGA2VRS     0x10,0x11   */
+       tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1;  /*  BTVGA2VRE     0x11        */
      }
 
      if(SiS_Pr->SiS_VBType & VB_SISVB) {
@@ -6416,7 +6231,7 @@ SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
           tempbx = SiS_Pr->CVSyncStart;
           tempcx = SiS_Pr->CVSyncEnd;
        }
-        if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
+       if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
           unsigned char cr8, cr7, cr13;
           if(SiS_Pr->UseCustomMode) {
              cr8    = SiS_Pr->CCRT1CRTC[8];
@@ -6429,11 +6244,11 @@ SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
              cr13   = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
              tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
           }
-          tempbx = cr8;
-          if(cr7  & 0x04) tempbx |= 0x0100;
-          if(cr7  & 0x80) tempbx |= 0x0200;
-          if(cr13 & 0x08) tempbx |= 0x0400;
-               }
+          tempbx = cr8;
+          if(cr7  & 0x04) tempbx |= 0x0100;
+          if(cr7  & 0x80) tempbx |= 0x0200;
+          if(cr13 & 0x08) tempbx |= 0x0400;
+       }
      }
      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,tempbx);               /* CRT2 Vertical Retrace Start */
 
@@ -6442,13 +6257,13 @@ SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 
      /* 3. Panel delay compensation */
 
-     if(HwInfo->jChipType < SIS_315H) {
+     if(SiS_Pr->ChipType < SIS_315H) {
 
 #ifdef SIS300  /* ---------- 300 series -------------- */
 
        if(SiS_Pr->SiS_VBType & VB_SISVB) {
           temp = 0x20;
-          if(HwInfo->jChipType == SIS_300) {
+          if(SiS_Pr->ChipType == SIS_300) {
              temp = 0x10;
              if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)  temp = 0x2c;
              if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
@@ -6460,24 +6275,23 @@ SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
           if(SiS_Pr->SiS_LCDResInfo == Panel_Custom)       temp = 0x2c;
           if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)             temp = 0x08;
           if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
-             if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)       temp = 0x2c;
-             else                                          temp = 0x20;
-          }
+             if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)       temp = 0x2c;
+             else                                          temp = 0x20;
+          }
           if(SiS_Pr->SiS_UseROM) {
              if(ROMAddr[0x220] & 0x80) {
-                if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision)
-                   temp = ROMAddr[0x221];
+                if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision)
+                   temp = ROMAddr[0x221];
                 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)
                    temp = ROMAddr[0x222];
                 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)
                    temp = ROMAddr[0x223];
                 else
                    temp = ROMAddr[0x224];
-                temp &= 0x3c;
              }
           }
           if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-             if(SiS_Pr->PDC != -1)  temp = SiS_Pr->PDC & 0x3c;
+             if(SiS_Pr->PDC != -1)  temp = SiS_Pr->PDC;
           }
 
        } else {
@@ -6487,15 +6301,17 @@ SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
           }
           if(SiS_Pr->SiS_UseROM) {
              if(ROMAddr[0x220] & 0x80) {
-                temp = ROMAddr[0x220] & 0x3c;
+                temp = ROMAddr[0x220];
              }
           }
           if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-             if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC & 0x3c;
+             if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC;
           }
-        }
+       }
 
-       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);   /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
+       temp &= 0x3c;
+
+       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);   /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
 
 #endif  /* SIS300 */
 
@@ -6503,16 +6319,16 @@ SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 
 #ifdef SIS315H   /* --------------- 315/330 series ---------------*/
 
-        if(HwInfo->jChipType < SIS_661) {
+       if(SiS_Pr->ChipType < SIS_661) {
 
           if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
 
-             if(HwInfo->jChipType == SIS_740) temp = 0x03;
-             else                             temp = 0x00;
+             if(SiS_Pr->ChipType == SIS_740) temp = 0x03;
+             else                            temp = 0x00;
 
              if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x0a;
              tempbl = 0xF0;
-             if(HwInfo->jChipType == SIS_650) {
+             if(SiS_Pr->ChipType == SIS_650) {
                 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
                    if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F;
                 }
@@ -6531,10 +6347,10 @@ SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 
        } /* < 661 */
 
-       tempax = 0;
-       if(modeflag & DoubleScanMode) tempax |= 0x80;
-       if(modeflag & HalfDCLK)       tempax |= 0x40;
-       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax);
+       tempax = 0;
+       if(modeflag & DoubleScanMode) tempax |= 0x80;
+       if(modeflag & HalfDCLK)       tempax |= 0x40;
+       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax);
 
 #endif  /* SIS315H */
 
@@ -6544,21 +6360,21 @@ SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 
   if(SiS_Pr->SiS_VBType & VB_SISVB) {
      if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
-        /* For 301BDH with LCD, we set up the Panel Link */
-       SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
+       /* For 301BDH with LCD, we set up the Panel Link */
+       SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
      } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-       SiS_SetGroup1_301(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
+       SiS_SetGroup1_301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
      }
   } else {
-     if(HwInfo->jChipType < SIS_315H) {
-       SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
+     if(SiS_Pr->ChipType < SIS_315H) {
+       SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
      } else {
        if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
-           if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-             SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex, HwInfo,RefreshRateTableIndex);
-           }
+          if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+             SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex);
+          }
        } else {
-          SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex, HwInfo,RefreshRateTableIndex);
+          SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex);
        }
      }
   }
@@ -6569,11 +6385,11 @@ SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 /*********************************************/
 
 #ifdef SIS315H
-static UCHAR *
-SiS_GetGroup2CLVXPtr(SiS_Private *SiS_Pr, int tabletype, PSIS_HW_INFO HwInfo)
+static unsigned char *
+SiS_GetGroup2CLVXPtr(struct SiS_Private *SiS_Pr, int tabletype)
 {
-   const UCHAR  *tableptr = NULL;
-   USHORT       a, b, p = 0;
+   const unsigned char *tableptr = NULL;
+   unsigned short      a, b, p = 0;
 
    a = SiS_Pr->SiS_VGAHDE;
    b = SiS_Pr->SiS_HDE;
@@ -6606,25 +6422,25 @@ SiS_GetGroup2CLVXPtr(SiS_Private *SiS_Pr, int tabletype, PSIS_HW_INFO HwInfo)
       if((tableptr[p] | tableptr[p+1] << 8) == 0xffff) p -= 0x42;
    }
    p += 2;
-   return((UCHAR *)&tableptr[p]);
+   return ((unsigned char *)&tableptr[p]);
 }
 
 static void
-SiS_SetGroup2_C_ELV(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
-                   USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
+SiS_SetGroup2_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
+                   unsigned short RefreshRateTableIndex)
 {
-   UCHAR *tableptr;
+   unsigned char *tableptr;
+   unsigned char temp;
    int i, j;
-   UCHAR temp;
 
-   if(!(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV))) return;
+   if(!(SiS_Pr->SiS_VBType & VB_SISTAP4SCALER)) return;
 
-   tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 0, HwInfo);
+   tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 0);
    for(i = 0x80, j = 0; i <= 0xbf; i++, j++) {
       SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
    }
    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-      tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 1, HwInfo);
+      tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 1);
       for(i = 0xc0, j = 0; i <= 0xff; i++, j++) {
          SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
       }
@@ -6635,12 +6451,12 @@ SiS_SetGroup2_C_ELV(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 }
 
 static BOOLEAN
-SiS_GetCRT2Part2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
-                   USHORT RefreshRateTableIndex,USHORT *CRT2Index,
-                   USHORT *ResIndex,PSIS_HW_INFO HwInfo)
+SiS_GetCRT2Part2Ptr(struct SiS_Private *SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,
+                   unsigned short RefreshRateTableIndex,unsigned short *CRT2Index,
+                   unsigned short *ResIndex)
 {
 
-  if(HwInfo->jChipType < SIS_315H) return FALSE;
+  if(SiS_Pr->ChipType < SIS_315H) return FALSE;
 
   if(ModeNo <= 0x13)
      (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
@@ -6661,82 +6477,79 @@ SiS_GetCRT2Part2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
         if(SiS_Pr->SiS_SetFlag & LCDVESATiming) (*CRT2Index) = 206;
      }
   }
-  return(((*CRT2Index) != 0));
+  return (((*CRT2Index) != 0));
 }
 #endif
 
 #ifdef SIS300
 static void
-SiS_Group2LCDSpecial(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo, USHORT crt2crtc)
+SiS_Group2LCDSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short crt2crtc)
 {
-   USHORT tempcx;
-   const UCHAR atable[] = {
+   unsigned short tempcx;
+   static const unsigned char atable[] = {
        0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,
        0xab,0x87,0xab,0x9e,0xe7,0x02,0x02
    };
 
    if(!SiS_Pr->UseCustomMode) {
-      if( ( ( (HwInfo->jChipType == SIS_630) ||
-              (HwInfo->jChipType == SIS_730) ) &&
-            (HwInfo->jChipRevision > 2) )  &&
-          (SiS_Pr->SiS_LCDResInfo == Panel_1024x768) &&
-          (!(SiS_Pr->SiS_SetFlag & LCDVESATiming))  &&
-          (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
-         if(ModeNo == 0x13) {
-            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xB9);
-            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0xCC);
-            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xA6);
-         } else {
-            if((crt2crtc & 0x3F) == 4) {
-               SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x2B);
-               SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x13);
-               SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xE5);
-               SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0x08);
-               SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xE2);
-            }
-         }
+      if( ( ( (SiS_Pr->ChipType == SIS_630) ||
+             (SiS_Pr->ChipType == SIS_730) ) &&
+           (SiS_Pr->ChipRevision > 2) )  &&
+         (SiS_Pr->SiS_LCDResInfo == Panel_1024x768) &&
+         (!(SiS_Pr->SiS_SetFlag & LCDVESATiming))  &&
+         (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
+        if(ModeNo == 0x13) {
+           SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xB9);
+           SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0xCC);
+           SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xA6);
+        } else if((crt2crtc & 0x3F) == 4) {
+           SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x2B);
+           SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x13);
+           SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xE5);
+           SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0x08);
+           SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xE2);
+        }
       }
 
-      if(HwInfo->jChipType < SIS_315H) {
-         if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
-            crt2crtc &= 0x1f;
-            tempcx = 0;
-            if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
-               if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-                  tempcx += 7;
-               }
-            }
-            tempcx += crt2crtc;
-            if(crt2crtc >= 4) {
-               SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xff);
-            }
+      if(SiS_Pr->ChipType < SIS_315H) {
+        if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
+           crt2crtc &= 0x1f;
+           tempcx = 0;
+           if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
+              if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+                 tempcx += 7;
+              }
+           }
+           tempcx += crt2crtc;
+           if(crt2crtc >= 4) {
+              SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xff);
+           }
 
-            if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
-               if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-                  if(crt2crtc == 4) {
-                     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x28);
-                  }
-               }
-            }
-            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x18);
-            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
-         }
+           if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
+              if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+                 if(crt2crtc == 4) {
+                    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x28);
+                 }
+              }
+           }
+           SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x18);
+           SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
+        }
       }
    }
 }
 
 /* For ECS A907. Highly preliminary. */
 static void
-SiS_Set300Part2Regs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
-                   USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
-                   USHORT ModeNo)
+SiS_Set300Part2Regs(struct SiS_Private *SiS_Pr, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex,
+                   unsigned short ModeNo)
 {
-  USHORT crt2crtc, resindex;
-  int    i,j;
-  const  SiS_Part2PortTblStruct *CRT2Part2Ptr = NULL;
+  const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
+  unsigned short crt2crtc, resindex;
+  int i, j;
 
-  if(HwInfo->jChipType != SIS_300) return;
-  if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) return;
+  if(SiS_Pr->ChipType != SIS_300) return;
+  if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;
   if(SiS_Pr->UseCustomMode) return;
 
   if(ModeNo <= 0x13) {
@@ -6758,13 +6571,13 @@ SiS_Set300Part2Regs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
   for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
-        SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
+     SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
   }
   for(j = 0x1c; j <= 0x1d; i++, j++ ) {
-        SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
+     SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
   }
   for(j = 0x1f; j <= 0x21; i++, j++ ) {
-        SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
+     SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
   }
   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
@@ -6772,15 +6585,15 @@ SiS_Set300Part2Regs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
 #endif
 
 static void
-SiS_SetTVSpecial(SiS_Private *SiS_Pr, USHORT ModeNo)
+SiS_SetTVSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
 {
-  if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) return;
+  if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;
   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) return;
   if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) return;
 
   if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
      if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
-        const UCHAR specialtv[] = {
+        const unsigned char specialtv[] = {
                0xa7,0x07,0xf2,0x6e,0x17,0x8b,0x73,0x53,
                0x13,0x40,0x34,0xf4,0x63,0xbb,0xcc,0x7a,
                0x58,0xe4,0x73,0xda,0x13
@@ -6813,16 +6626,16 @@ SiS_SetTVSpecial(SiS_Private *SiS_Pr, USHORT ModeNo)
 }
 
 static void
-SiS_SetGroup2_Tail(SiS_Private *SiS_Pr, USHORT ModeNo)
+SiS_SetGroup2_Tail(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
 {
-  USHORT temp;
+  unsigned short temp;
 
   if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
      if(SiS_Pr->SiS_VGAVDE == 525) {
        temp = 0xc3;
        if(SiS_Pr->SiS_ModeType <= ModeVGA) {
           temp++;
-          if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp += 2;
+          if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp += 2;
        }
        SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
        SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xb3);
@@ -6830,7 +6643,7 @@ SiS_SetGroup2_Tail(SiS_Private *SiS_Pr, USHORT ModeNo)
        temp = 0x4d;
        if(SiS_Pr->SiS_ModeType <= ModeVGA) {
           temp++;
-          if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp++;
+          if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp++;
        }
        SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
      }
@@ -6838,7 +6651,7 @@ SiS_SetGroup2_Tail(SiS_Private *SiS_Pr, USHORT ModeNo)
 
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
      if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
-       if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
+       if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
           SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x1a,0x03);
           /* Not always for LV, see SetGrp2 */
        }
@@ -6872,17 +6685,17 @@ SiS_SetGroup2_Tail(SiS_Private *SiS_Pr, USHORT ModeNo)
 }
 
 static void
-SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
-             PSIS_HW_INFO HwInfo)
-{
-  USHORT      i, j, tempax, tempbx, tempcx, tempch, tempcl, temp;
-  USHORT      push2, modeflag, crt2crtc, bridgeoffset;
-  ULONG       longtemp;
-  const       UCHAR *PhasePoint;
-  const       UCHAR *TimingPoint;
+SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
+               unsigned short RefreshRateTableIndex)
+{
+  unsigned short i, j, tempax, tempbx, tempcx, tempch, tempcl, temp;
+  unsigned short push2, modeflag, crt2crtc, bridgeoffset;
+  unsigned int   longtemp, PhaseIndex;
+  BOOLEAN        newtvphase;
+  const unsigned char *TimingPoint;
 #ifdef SIS315H
-  USHORT      resindex, CRT2Index;
-  const       SiS_Part2PortTblStruct *CRT2Part2Ptr = NULL;
+  unsigned short resindex, CRT2Index;
+  const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
 
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
 #endif
@@ -6908,9 +6721,16 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
 
   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x00,temp);
 
-  PhasePoint  = SiS_Pr->SiS_PALPhase;
+  PhaseIndex  = 0x01; /* SiS_PALPhase */
   TimingPoint = SiS_Pr->SiS_PALTiming;
 
+  newtvphase = FALSE;
+  if( (SiS_Pr->SiS_VBType & VB_SIS30xBLV) &&
+      ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+       (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
+     newtvphase = TRUE;
+  }
+
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
 
      TimingPoint = SiS_Pr->SiS_HiTVExtTiming;
@@ -6918,82 +6738,54 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
         TimingPoint = SiS_Pr->SiS_HiTVSt2Timing;
         if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
           TimingPoint = SiS_Pr->SiS_HiTVSt1Timing;
-#if 0
-           if(!(modeflag & Charx8Dot))  TimingPoint = SiS_Pr->SiS_HiTVTextTiming;
-#endif
         }
      }
 
   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
 
-     if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)      TimingPoint = &SiS_YPbPrTable[2][0];
-     else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) TimingPoint = &SiS_YPbPrTable[1][0];
-     else                                        TimingPoint = &SiS_YPbPrTable[0][0];
+     i = 0;
+     if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)      i = 2;
+     else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) i = 1;
 
-     PhasePoint = SiS_Pr->SiS_NTSCPhase;
+     TimingPoint = &SiS_YPbPrTable[i][0];
+
+     PhaseIndex = 0x00; /* SiS_NTSCPhase */
 
   } else if(SiS_Pr->SiS_TVMode & TVSetPAL) {
 
-     if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
-         ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
-          (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
-        PhasePoint = SiS_Pr->SiS_PALPhase2;
-     }
+     if(newtvphase) PhaseIndex = 0x09; /* SiS_PALPhase2 */
 
   } else {
 
      TimingPoint = SiS_Pr->SiS_NTSCTiming;
-     PhasePoint  = SiS_Pr->SiS_NTSCPhase;
-     if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
-       PhasePoint = SiS_Pr->SiS_PALPhase;
-     }
-
-     if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
-        ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
-          (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
-        PhasePoint = SiS_Pr->SiS_NTSCPhase2;
-       if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
-          PhasePoint = SiS_Pr->SiS_PALPhase2;
-       }
-     }
-
-  }
+     PhaseIndex  = (SiS_Pr->SiS_TVMode & TVSetNTSCJ) ? 0x01 : 0x00;    /* SiS_PALPhase : SiS_NTSCPhase */
+     if(newtvphase) PhaseIndex += 8;                                   /* SiS_PALPhase2 : SiS_NTSCPhase2 */
 
-  if(SiS_Pr->SiS_TVMode & TVSetPALM) {
-     PhasePoint = SiS_Pr->SiS_PALMPhase;
-     if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
-        ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
-          (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
-        PhasePoint = SiS_Pr->SiS_PALMPhase2;
-     }
   }
 
-  if(SiS_Pr->SiS_TVMode & TVSetPALN) {
-     PhasePoint = SiS_Pr->SiS_PALNPhase;
-     if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
-        ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
-          (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
-       PhasePoint = SiS_Pr->SiS_PALNPhase2;
-     }
+  if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) {
+     PhaseIndex = (SiS_Pr->SiS_TVMode & TVSetPALM) ? 0x02 : 0x03;      /* SiS_PALMPhase : SiS_PALNPhase */
+     if(newtvphase) PhaseIndex += 8;                                   /* SiS_PALMPhase2 : SiS_PALNPhase2 */
   }
 
   if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
-     PhasePoint = SiS_Pr->SiS_SpecialPhase;
      if(SiS_Pr->SiS_TVMode & TVSetPALM) {
-        PhasePoint = SiS_Pr->SiS_SpecialPhaseM;
+        PhaseIndex = 0x05; /* SiS_SpecialPhaseM */
      } else if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
-        PhasePoint = SiS_Pr->SiS_SpecialPhaseJ;
+        PhaseIndex = 0x11; /* SiS_SpecialPhaseJ */
+     } else {
+        PhaseIndex = 0x10; /* SiS_SpecialPhase */
      }
   }
 
-  for(i=0x31, j=0; i<=0x34; i++, j++) {
-     SiS_SetReg(SiS_Pr->SiS_Part2Port,i,PhasePoint[j]);
+  for(i = 0x31, j = 0; i <= 0x34; i++, j++) {
+     SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[(PhaseIndex * 4) + j]);
   }
 
-  for(i=0x01, j=0; i<=0x2D; i++, j++) {
+  for(i = 0x01, j = 0; i <= 0x2D; i++, j++) {
      SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
   }
-  for(i=0x39; i<=0x45; i++, j++) {
+  for(i = 0x39; i <= 0x45; i++, j++) {
      SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
   }
 
@@ -7010,28 +6802,32 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x37,SiS_Pr->SiS_RY3COE);
   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x38,SiS_Pr->SiS_RY4COE);
 
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)   tempax = 950;
-  else if(SiS_Pr->SiS_TVMode & TVSetPAL)       tempax = 520;
-  else                                                 tempax = 440; /* NTSC, YPbPr 525, 750 */
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)   tempax = 950;
+  else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)  tempax = 680;
+  else if(SiS_Pr->SiS_TVMode & TVSetPAL)       tempax = 520;
+  else                                         tempax = 440; /* NTSC, YPbPr 525 */
 
-  if( ( (!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) && (SiS_Pr->SiS_VDE <= tempax) ) ||
+  if( ((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) && (SiS_Pr->SiS_VDE <= tempax)) ||
       ( (SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) &&
         ((SiS_Pr->SiS_VGAHDE == 1024) || (SiS_Pr->SiS_VDE <= tempax)) ) ) {
 
      tempax -= SiS_Pr->SiS_VDE;
-     tempax >>= 2;
+     tempax >>= 1;
+     if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) {
+        tempax >>= 1;
+     }
      tempax &= 0x00ff;
 
-     temp = tempax + (USHORT)TimingPoint[0];
+     temp = tempax + (unsigned short)TimingPoint[0];
      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
 
-     temp = tempax + (USHORT)TimingPoint[1];
+     temp = tempax + (unsigned short)TimingPoint[1];
      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
 
      if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) && (SiS_Pr->SiS_VGAHDE >= 1024)) {
         if(SiS_Pr->SiS_TVMode & TVSetPAL) {
-           SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b);  /* 19 */
-           SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54);  /* 52 */
+           SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b);
+           SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54);
         } else {
            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x17);
            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1d);
@@ -7041,14 +6837,14 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
   }
 
   tempcx = SiS_Pr->SiS_HT;
-  if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempcx >>= 1;
+  if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
   tempcx--;
-  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) tempcx--;
+  if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) tempcx--;
   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1B,tempcx);
   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0xF0,((tempcx >> 8) & 0x0f));
 
   tempcx = SiS_Pr->SiS_HT >> 1;
-  if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempcx >>= 1;
+  if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
   tempcx += 7;
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,((tempcx << 4) & 0xf0));
@@ -7075,7 +6871,7 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2A,0x0F,((tempcx << 4) & 0xf0));
 
   tempcx = SiS_Pr->SiS_HT >> 1;
-  if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempcx >>= 1;
+  if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
   j += 2;
   tempcx -= (TimingPoint[j] | ((TimingPoint[j+1]) << 8));
   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2D,0x0F,((tempcx << 4) & 0xf0));
@@ -7094,7 +6890,7 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
   } else if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
              (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p))) ) {
      tempbx >>= 1;
-     if(HwInfo->jChipType >= SIS_315H) {
+     if(SiS_Pr->ChipType >= SIS_315H) {
         if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
           if((ModeNo <= 0x13) && (crt2crtc == 1)) tempbx++;
        } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
@@ -7123,23 +6919,11 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
   }
   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,temp);
 
-  if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302LV | VB_SIS302ELV)) {
+  if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {
      SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xdf,((tempbx & 0x0400) >> 5));
   }
 
-#if 0
-  /* TEST qqqq */
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
-     for(i=0x01, j=0; i<=0x2D; i++, j++) {
-        SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
-     }
-     for(i=0x39; i<=0x45; i++, j++) {
-        SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
-     }
-  }
-#endif
-
-  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+  if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
      tempbx = SiS_Pr->SiS_VDE;
      if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
          (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) ) {
@@ -7150,7 +6934,7 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x46,temp);
      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x47,tempbx);
 
-     if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302LV | VB_SIS302ELV)) {
+     if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {
        SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xbf,((tempbx & 0x0400) >> 4));
      }
   }
@@ -7165,14 +6949,17 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
 
   tempch = tempcl = 0x01;
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-     if(SiS_Pr->SiS_VGAHDE >= 1024) {
-        if((!(modeflag & HalfDCLK)) || (HwInfo->jChipType < SIS_315H)) {
-           tempch = 0x19;
+     if(SiS_Pr->SiS_VGAHDE >= 960) {
+        if((!(modeflag & HalfDCLK)) || (SiS_Pr->ChipType < SIS_315H)) {
           tempcl = 0x20;
-           if(SiS_Pr->SiS_VGAHDE >= 1280) {
-              tempch = 0x14;
+          if(SiS_Pr->SiS_VGAHDE >= 1280) {
+              tempch = 20;
               tempbx &= ~0x20;
-           }
+           } else if(SiS_Pr->SiS_VGAHDE >= 1024) {
+              tempch = 25;
+           } else {
+             tempch = 25; /* OK */
+          }
         }
      }
   }
@@ -7180,7 +6967,7 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
   if(!(tempbx & 0x20)) {
      if(modeflag & HalfDCLK) tempcl <<= 1;
      longtemp = ((SiS_Pr->SiS_VGAHDE * tempch) / tempcl) << 13;
-     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) longtemp <<= 3;
+     if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) longtemp <<= 3;
      tempax = longtemp / SiS_Pr->SiS_HDE;
      if(longtemp % SiS_Pr->SiS_HDE) tempax++;
      tempbx |= ((tempax >> 8) & 0x1F);
@@ -7190,7 +6977,7 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,tempax);
   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,tempbx);
 
-  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+  if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
 
      tempcx &= 0x07;
      if(tempbx & 0x20) tempcx = 0;
@@ -7219,7 +7006,7 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
 
      SiS_SetTVSpecial(SiS_Pr, ModeNo);
 
-     if(SiS_Pr->SiS_VBType & VB_SIS301C) {
+     if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
         temp = 0;
         if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
         SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xf7,temp);
@@ -7246,7 +7033,7 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
   /* From here: Part2 LCD setup */
 
   tempbx = SiS_Pr->SiS_HDE;
-  if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
+  if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
   tempbx--;                                    /* RHACTE = HDE - 1 */
   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2C,tempbx);
   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,((tempbx >> 4) & 0xf0));
@@ -7256,10 +7043,8 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
      if(SiS_Pr->SiS_ModeType == ModeEGA) {
         if(SiS_Pr->SiS_VGAHDE >= 1024) {
            temp = 0x02;
-          if(HwInfo->jChipType >= SIS_315H) {
-              if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
-                 temp = 0x01;
-             }
+           if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
+              temp = 0x01;
           }
         }
      }
@@ -7289,11 +7074,11 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
 
 #ifdef SIS315H
   if(SiS_GetCRT2Part2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
-                                               &CRT2Index, &resindex, HwInfo)) {
+                                               &CRT2Index, &resindex)) {
       switch(CRT2Index) {
+        case 206: CRT2Part2Ptr = SiS310_CRT2Part2_Asus1024x768_3;    break;
+       default:
         case 200: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;   break;
-       case 206: CRT2Part2Ptr = SiS310_CRT2Part2_Asus1024x768_3;    break;
-       default:  CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_3;   break;
       }
 
       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
@@ -7312,7 +7097,6 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
 
       SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
 
-
   } else {
 #endif
 
@@ -7349,9 +7133,11 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
 
     /* Non-expanding: lcdvdes = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */
 
+#ifdef SIS_XORG_XF86
 #ifdef TWDEBUG
     xf86DrvMsg(0, X_INFO, "lcdvdes 0x%x lcdvdee 0x%x\n", tempcx, tempbx);
 #endif
+#endif
 
     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,tempcx);     /* lcdvdes  */
     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,tempbx);     /* lcdvdee  */
@@ -7401,9 +7187,11 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
        tempbx = SiS_Pr->CVSyncStart;
     }
 
+#ifdef SIS_XORG_XF86
 #ifdef TWDEBUG
     xf86DrvMsg(0, X_INFO, "lcdvrs 0x%x\n", tempbx);
 #endif
+#endif
 
     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,tempbx);         /* lcdvrs */
 
@@ -7416,26 +7204,30 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
        temp |= (SiS_Pr->CVSyncEnd & 0x0f);
     }
 
+#ifdef SIS_XORG_XF86
 #ifdef TWDEBUG
     xf86DrvMsg(0, X_INFO, "lcdvre[3:0] 0x%x\n", (temp & 0x0f));
 #endif
+#endif
 
     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
 
 #ifdef SIS300
-    SiS_Group2LCDSpecial(SiS_Pr, HwInfo, ModeNo, crt2crtc);
+    SiS_Group2LCDSpecial(SiS_Pr, ModeNo, crt2crtc);
 #endif
 
     bridgeoffset = 7;
-    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)          bridgeoffset += 2;
-    if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV)) bridgeoffset++;
-    if(SiS_IsDualLink(SiS_Pr, HwInfo))                  bridgeoffset++;
+    if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)      bridgeoffset += 2;
+    if(SiS_Pr->SiS_VBType & VB_SIS30xCLV)      bridgeoffset += 2; /* OK for Averatec 1280x800 (301C) */
+    if(SiS_IsDualLink(SiS_Pr))                 bridgeoffset++;
+    else if(SiS_Pr->SiS_VBType & VB_SIS302LV)  bridgeoffset++;    /* OK for Asus A4L 1280x800 */
+    /* Higher bridgeoffset shifts to the LEFT */
 
     temp = 0;
     if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
        if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
-          temp = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
-         if(SiS_IsDualLink(SiS_Pr, HwInfo)) temp >>= 1;
+         temp = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
+         if(SiS_IsDualLink(SiS_Pr)) temp >>= 1;
        }
     }
     temp += bridgeoffset;
@@ -7450,15 +7242,17 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
           tempbx = SiS_Pr->PanelXRes - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
        }
     }
-    if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
+    if(SiS_IsDualLink(SiS_Pr)) {
        tempcx >>= 1;
        tempbx >>= 1;
        tempax >>= 1;
     }
 
+#ifdef SIS_XORG_XF86
 #ifdef TWDEBUG
     xf86DrvMsg(0, X_INFO, "lcdhdee 0x%x\n", tempbx);
 #endif
+#endif
 
     tempbx += bridgeoffset;
 
@@ -7480,13 +7274,16 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
 
     if(SiS_Pr->UseCustomMode) {
        tempbx = SiS_Pr->CHSyncStart;
-       if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
+       if(modeflag & HalfDCLK) tempbx <<= 1;
+       if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
        tempbx += bridgeoffset;
     }
 
+#ifdef SIS_XORG_XF86
 #ifdef TWDEBUG
     xf86DrvMsg(0, X_INFO, "lcdhrs 0x%x\n", tempbx);
 #endif
+#endif
 
     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1C,tempbx);         /* lcdhrs */
     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,((tempbx >> 4) & 0xf0));
@@ -7501,20 +7298,23 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
 
     if(SiS_Pr->UseCustomMode) {
        tempbx = SiS_Pr->CHSyncEnd;
-       if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
+       if(modeflag & HalfDCLK) tempbx <<= 1;
+       if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
        tempbx += bridgeoffset;
     }
 
+#ifdef SIS_XORG_XF86
 #ifdef TWDEBUG
     xf86DrvMsg(0, X_INFO, "lcdhre 0x%x\n", tempbx);
 #endif
+#endif
 
     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,tempbx);         /* lcdhre */
 
     SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
 
 #ifdef SIS300
-    SiS_Set300Part2Regs(SiS_Pr, HwInfo, ModeIdIndex, RefreshRateTableIndex, ModeNo);
+    SiS_Set300Part2Regs(SiS_Pr, ModeIdIndex, RefreshRateTableIndex, ModeNo);
 #endif
 #ifdef SIS315H
   } /* CRT2-LCD from table */
@@ -7526,11 +7326,10 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
 /*********************************************/
 
 static void
-SiS_SetGroup3(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
-              PSIS_HW_INFO HwInfo)
+SiS_SetGroup3(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
 {
-  USHORT       i;
-  const UCHAR          *tempdi;
+  unsigned short i;
+  const unsigned char *tempdi;
 
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
 
@@ -7570,7 +7369,7 @@ SiS_SetGroup3(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
      for(i=0; i<=0x3E; i++) {
         SiS_SetReg(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
      }
-     if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV)) {
+     if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
        if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
           SiS_SetReg(SiS_Pr->SiS_Part3Port,0x28,0x3f);
        }
@@ -7587,35 +7386,43 @@ SiS_SetGroup3(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 /*********************************************/
 
 #ifdef SIS315H
+#if 0
 static void
-SiS_ShiftXPos(SiS_Private *SiS_Pr, int shift)
+SiS_ShiftXPos(struct SiS_Private *SiS_Pr, int shift)
 {
-   USHORT temp, temp1, temp2;
+   unsigned short temp, temp1, temp2;
 
    temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x1f);
    temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x20);
-   temp = (USHORT)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
+   temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,temp);
    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0f,((temp >> 4) & 0xf0));
    temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x2b) & 0x0f;
-   temp = (USHORT)((int)(temp) + shift);
+   temp = (unsigned short)((int)(temp) + shift);
    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2b,0xf0,(temp & 0x0f));
    temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
    temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x42);
-   temp = (USHORT)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
+   temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,temp);
    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x42,0x0f,((temp >> 4) & 0xf0));
 }
+#endif
 
 static void
-SiS_SetGroup4_C_ELV(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
-                    USHORT ModeNo, USHORT ModeIdIndex)
+SiS_SetGroup4_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
 {
-   USHORT temp, temp1, resinfo = 0;
+   unsigned short temp, temp1, resinfo = 0;
+   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
 
-   if(!(SiS_Pr->SiS_VBType & VB_SIS301C)) return;
+   if(!(SiS_Pr->SiS_VBType & VB_SIS30xCLV)) return;
    if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToHiVision | SetCRT2ToYPbPr525750))) return;
 
+   if(SiS_Pr->ChipType >= XGI_20) return;
+
+   if((SiS_Pr->ChipType >= SIS_661) && (SiS_Pr->SiS_ROMNew)) {
+      if(!(ROMAddr[0x61] & 0x04)) return;
+   }
+
    if(ModeNo > 0x13) {
       resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
    }
@@ -7625,7 +7432,7 @@ SiS_SetGroup4_C_ELV(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
    if(!(temp & 0x01)) {
       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3a,0xdf);
       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xfc);
-      if((HwInfo->jChipType < SIS_661) && (!(SiS_Pr->SiS_ROMNew))) {
+      if((SiS_Pr->ChipType < SIS_661) && (!(SiS_Pr->SiS_ROMNew))) {
          SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xf8);
       }
       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0xfb);
@@ -7633,24 +7440,29 @@ SiS_SetGroup4_C_ELV(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
       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) || (SiS_Pr->SiS_ROMNew)) {
+      if((SiS_Pr->ChipType >= 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);
         if(SiS_Pr->SiS_TVMode & TVAspect43LB) temp |= 0x01;
         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0x7c,(temp & 0xff));
+        SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
+        if(ModeNo > 0x13) {
+            SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x39,0xfd);
+         }
       } else {
          temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x3b) & 0x03;
         if(temp1 == 0x01) temp |= 0x01;
         if(temp1 == 0x03) temp |= 0x04;  /* ? why not 0x10? */
         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);
+        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 0
+      if(SiS_Pr->ChipType >= SIS_661) {                /* ? */
          if(SiS_Pr->SiS_TVMode & TVAspect43) {
             if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
               if(resinfo == SIS_RI_1024x768) {
@@ -7663,29 +7475,30 @@ SiS_SetGroup4_C_ELV(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
            }
          }
       }
+#endif
+
    }
+
 }
 #endif
 
 static void
-SiS_SetCRT2VCLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
-                 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
+SiS_SetCRT2VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
+                 unsigned short RefreshRateTableIndex)
 {
-  USHORT vclkindex;
-  USHORT temp, reg1, reg2;
+  unsigned short vclkindex, temp, reg1, reg2;
 
   if(SiS_Pr->UseCustomMode) {
      reg1 = SiS_Pr->CSR2B;
      reg2 = SiS_Pr->CSR2C;
   } else {
-     vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
-                                 HwInfo);
+     vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
      reg1 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
      reg2 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
   }
 
-  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-     if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
+  if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
+     if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {
         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x57);
        SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,0x46);
        SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1f,0xf6);
@@ -7698,18 +7511,42 @@ SiS_SetCRT2VCLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
   }
-  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x12,0x00);
-  temp = 0x08;
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) temp |= 0x20;
-  SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,temp);
+  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x12,0x00);
+  temp = 0x08;
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) temp |= 0x20;
+  SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,temp);
+}
+
+static void
+SiS_SetDualLinkEtc(struct SiS_Private *SiS_Pr)
+{
+  if(SiS_Pr->ChipType >= SIS_315H) {
+     if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
+       if((SiS_CRT2IsLCD(SiS_Pr)) ||
+          (SiS_IsVAMode(SiS_Pr))) {
+          if(SiS_Pr->SiS_LCDInfo & LCDDualLink) {
+             SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
+          } else {
+             SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,~0x20);
+          }
+       }
+     }
+  }
+  if(SiS_Pr->SiS_VBType & VB_SISEMI) {
+     SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
+#ifdef SET_EMI
+     SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
+#endif
+     SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
+  }
 }
 
 static void
-SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
-             USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
+SiS_SetGroup4(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
+               unsigned short RefreshRateTableIndex)
 {
-  USHORT tempax,tempcx,tempbx,modeflag,temp,resinfo;
-  ULONG tempebx,tempeax,templong;
+  unsigned short tempax, tempcx, tempbx, modeflag, temp, resinfo;
+  unsigned int   tempebx, tempeax, templong;
 
   if(ModeNo <= 0x13) {
      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
@@ -7722,38 +7559,24 @@ SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
   }
 
-  if(HwInfo->jChipType >= SIS_315H) {
-     if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
-           SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
-        }
+  if(SiS_Pr->ChipType >= SIS_315H) {
+     if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
+       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+          SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
+       }
      }
   }
 
-  if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302LV)) {
+  if(SiS_Pr->SiS_VBType & (VB_SIS30xCLV | VB_SIS302LV)) {
      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-        SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x10,0x9f);
+       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x10,0x9f);
      }
   }
 
-  if(HwInfo->jChipType >= SIS_315H) {
+  if(SiS_Pr->ChipType >= SIS_315H) {
      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
-        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)) {
-             SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
-#ifdef SET_EMI
-             SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
-#endif
-             SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
-          }
-       }
-       return;
+       SiS_SetDualLinkEtc(SiS_Pr);
+       return;
      }
   }
 
@@ -7777,16 +7600,16 @@ SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x15,temp);
 
   tempbx = SiS_Pr->SiS_VGAHDE;
-  if(modeflag & HalfDCLK)            tempbx >>= 1;
-  if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
+  if(modeflag & HalfDCLK)    tempbx >>= 1;
+  if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
 
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
      temp = 0;
      if(tempbx > 800)        temp = 0x60;
   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
      temp = 0;
-     if(tempbx == 1024)      temp = 0xA0;
-     else if(tempbx > 1024)  temp = 0xC0;
+     if(tempbx > 1024)       temp = 0xC0;
+     else if(tempbx >= 960)  temp = 0xA0;
   } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
      temp = 0;
      if(tempbx >= 1280)      temp = 0x40;
@@ -7796,8 +7619,13 @@ SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
      if(tempbx >= 1024)      temp = 0xA0;
   }
 
+  temp |= SiS_Pr->Init_P4_0E;
+
   if(SiS_Pr->SiS_VBType & VB_SIS301) {
-     if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) temp |= 0x0A;
+     if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
+        temp &= 0xf0;
+        temp |= 0x0A;
+     }
   }
 
   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0E,0x10,temp);
@@ -7824,15 +7652,15 @@ SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
   tempeax /= tempebx;
   if(templong) tempeax++;
 
-  temp = (USHORT)(tempeax & 0x000000FF);
+  temp = (unsigned short)(tempeax & 0x000000FF);
   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1B,temp);
-  temp = (USHORT)((tempeax & 0x0000FF00) >> 8);
+  temp = (unsigned short)((tempeax & 0x0000FF00) >> 8);
   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1A,temp);
-  temp = (USHORT)((tempeax >> 12) & 0x70); /* sic! */
+  temp = (unsigned short)((tempeax >> 12) & 0x70); /* sic! */
   temp |= (tempcx & 0x4F);
   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x19,temp);
 
-  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+  if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
 
      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1C,0x28);
 
@@ -7840,23 +7668,26 @@ SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
      tempbx = 0;
      if(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p)) tempbx = 0x08;
      tempax = SiS_Pr->SiS_VGAHDE;
-     if(modeflag & HalfDCLK)            tempax >>= 1;
-     if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempax >>= 1;
+     if(modeflag & HalfDCLK)    tempax >>= 1;
+     if(SiS_IsDualLink(SiS_Pr)) tempax >>= 1;
      if(tempax > 800) {
         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
           tempax -= 800;
-       } else {  /* 651+301C: Only if TVNoHiviNoYPbPr */
+       } else {
           tempbx = 0x08;
-           if(tempax == 1024) tempax *= 25;
-           else                      tempax *= 20;
+          if(tempax == 960)       tempax *= 25; /* Correct */
+           else if(tempax == 1024) tempax *= 25;
+           else                           tempax *= 20;
           temp = tempax % 32;
           tempax /= 32;
           if(temp) tempax++;
           tempax++;
-          if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) ||
-             (SiS_Pr->SiS_TVMode & TVSetYPbPr525i)) {
-             if(resinfo == SIS_RI_1024x768) {
-                /* Otherwise white line at right edge */
+          if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+             if(resinfo == SIS_RI_1024x768 ||
+                resinfo == SIS_RI_1024x576 ||
+                resinfo == SIS_RI_1280x1024 ||
+                resinfo == SIS_RI_1280x720) {
+                /* Otherwise white line or garbage at right edge */
                 tempax = (tempax & 0xff00) | 0x20;
              }
           }
@@ -7868,7 +7699,7 @@ SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1E,temp);
 
      temp = 0x0036; tempbx = 0xD0;
-     if((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
+     if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
        temp = 0x0026; tempbx = 0xC0; /* See En/DisableBridge() */
      }
      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
@@ -7884,36 +7715,24 @@ SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
      SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,tempbx,temp);
 
      tempbx = SiS_Pr->SiS_HT >> 1;
-     if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
+     if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
      tempbx -= 2;
      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x22,tempbx);
      temp = (tempbx >> 5) & 0x38;
      SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp);
 
-     if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+     if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
            SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
           /* LCD-too-dark-error-source, see FinalizeLCD() */
        }
-       if(HwInfo->jChipType >= SIS_315H) {
-          if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
-             SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
-          } else {
-             SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,~0x20);
-          }
-       }
-       if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
-          SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
-#ifdef SET_EMI
-          SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
-#endif
-          SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
-       }
      }
 
+     SiS_SetDualLinkEtc(SiS_Pr);
+
   }  /* 301B */
 
-  SiS_SetCRT2VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
+  SiS_SetCRT2VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
 }
 
 /*********************************************/
@@ -7921,8 +7740,7 @@ SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 /*********************************************/
 
 static void
-SiS_SetGroup5(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
-              PSIS_HW_INFO HwInfo)
+SiS_SetGroup5(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
 {
 
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)  return;
@@ -7930,7 +7748,7 @@ SiS_SetGroup5(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
   if(SiS_Pr->SiS_ModeType == ModeVGA) {
      if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))) {
         SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
-        SiS_LoadDAC(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
+        SiS_LoadDAC(SiS_Pr, ModeNo, ModeIdIndex);
      }
   }
 }
@@ -7939,116 +7757,156 @@ SiS_SetGroup5(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 /*     MODIFY CRT1 GROUP FOR SLAVE MODE      */
 /*********************************************/
 
-static void
-SiS_ModCRT1CRTC(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
-                USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
-{
-  USHORT tempah,i,modeflag,j;
-  USHORT ResIndex,DisplayType;
-  const SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr=NULL;
+static BOOLEAN
+SiS_GetLVDSCRT1Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
+                  unsigned short RefreshRateTableIndex, unsigned short *ResIndex,
+                  unsigned short *DisplayType)
+ {
+  unsigned short modeflag = 0;
+  BOOLEAN checkhd = TRUE;
+
+  /* Pass 1:1 not supported here */
+
+  if(ModeNo <= 0x13) {
+     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+     (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+  } else {
+     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+     (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+  }
+
+  (*ResIndex) &= 0x3F;
+
+  if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
+
+     (*DisplayType) = 80;
+     if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
+       (*DisplayType) = 82;
+       if(SiS_Pr->SiS_ModeType > ModeVGA) {
+          if(SiS_Pr->SiS_CHSOverScan) (*DisplayType) = 84;
+       }
+     }
+     if((*DisplayType) != 84) {
+        if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
+     }
+
+  } else {
+
+     (*DisplayType = 0);
+     switch(SiS_Pr->SiS_LCDResInfo) {
+     case Panel_320x240_1: (*DisplayType) = 50;
+                          checkhd = FALSE;
+                          break;
+     case Panel_320x240_2: (*DisplayType) = 14;
+                          break;
+     case Panel_320x240_3: (*DisplayType) = 18;
+                          break;
+     case Panel_640x480:   (*DisplayType) = 10;
+                          break;
+     case Panel_1024x600:  (*DisplayType) = 26;
+                          break;
+     default: return TRUE;
+     }
+
+     if(checkhd) {
+        if(modeflag & HalfDCLK) (*DisplayType)++;
+     }
+
+     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
+        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) (*DisplayType) += 2;
+     }
+
+  }
+
+  return TRUE;
+}
 
-  if(ModeNo <= 0x13) modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-  else               modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+static void
+SiS_ModCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
+                unsigned short RefreshRateTableIndex)
+{
+  unsigned short tempah, i, modeflag, j, ResIndex, DisplayType;
+  const struct SiS_LVDSCRT1Data *LVDSCRT1Ptr=NULL;
+  static const unsigned short CRIdx[] = {
+       0x00, 0x02, 0x03, 0x04, 0x05, 0x06,
+       0x07, 0x10, 0x11, 0x15, 0x16
+  };
 
   if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
      (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
-     (SiS_Pr->SiS_CustomT == CUT_PANEL848))
+     (SiS_Pr->SiS_CustomT == CUT_PANEL848)  ||
+     (SiS_Pr->SiS_CustomT == CUT_PANEL856) )
      return;
 
+  if(SiS_Pr->SiS_IF_DEF_LVDS) {
+     if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+        if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;
+     }
+  } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
+     if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;
+  } else return;
+
+  if(SiS_Pr->SiS_LCDInfo & LCDPass11) return;
+
+  if(SiS_Pr->ChipType < SIS_315H) {
+     if(SiS_Pr->SiS_SetFlag & SetDOSMode) return;
+  }
+
   if(!(SiS_GetLVDSCRT1Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
                           &ResIndex, &DisplayType))) {
      return;
   }
 
-  if(HwInfo->jChipType < SIS_315H) {
-     if(SiS_Pr->SiS_SetFlag & SetDOSMode) return;
+  switch(DisplayType) {
+    case 50: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_1;           break; /* xSTN */
+    case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2;           break; /* xSTN */
+    case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2_H;         break; /* xSTN */
+    case 18: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3;           break; /* xSTN */
+    case 19: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3_H;         break; /* xSTN */
+    case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1;           break;
+    case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1_H;         break;
+#if 0 /* Works better with calculated numbers */
+    case 26: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1;          break;
+    case 27: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1_H;        break;
+    case 28: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2;          break;
+    case 29: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2_H;        break;
+#endif
+    case 80: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC;               break;
+    case 81: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC;               break;
+    case 82: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL;                break;
+    case 83: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL;                break;
+    case 84: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1SOPAL;               break;
   }
 
-  switch(DisplayType) {
-    case 0 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1;           break;
-    case 1 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1_H;         break;
-    case 2 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2;           break;
-    case 3 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2_H;         break;
-    case 4 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1;          break;
-    case 5 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1_H;        break;
-    case 6 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2;          break;
-    case 7 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2_H;        break;
-    case 8 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1;         break;
-    case 9 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1_H;       break;
-    case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2;         break;
-    case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2_H;       break;
-    case 12: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1;           break;
-    case 13: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H;         break;
-    case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_1;         break;
-    case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_1_H;       break;
-    case 16: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_2;         break;
-    case 17: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_2_H;       break;
-    case 18: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC;               break;
-    case 19: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC;               break;
-    case 20: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL;                break;
-    case 21: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL;                break;
-    case 22: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x480_1;           break; /* FSTN */
-    case 23: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1;          break;
-    case 24: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1_H;        break;
-    case 25: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2;          break;
-    case 26: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2_H;        break;
-    case 27: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_1;          break;
-    case 28: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_1_H;        break;
-    case 29: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_2;          break;
-    case 30: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_2_H;        break;
-    case 36: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_1;         break;
-    case 37: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_1_H;       break;
-    case 38: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_2;         break;
-    case 39: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_2_H;       break;
-    case 40: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_1;          break;
-    case 41: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_1_H;        break;
-    case 42: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_2;          break;
-    case 43: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_2_H;        break;
-    case 50: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1;           break;
-    case 51: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1_H;         break;
-    case 52: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_2;           break;
-    case 53: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_2_H;         break;
-    case 54: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_3;           break;
-    case 55: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_3_H;         break;
-    case 99: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1SOPAL;               break;
-    default: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1;          break;
-  }
-
-  SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
-
-  tempah = (LVDSCRT1Ptr + ResIndex)->CR[0];
-  SiS_SetReg(SiS_Pr->SiS_P3d4,0x00,tempah);
-
-  for(i=0x02,j=1;i<=0x05;i++,j++){
-    tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
-    SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
-  }
-  for(i=0x06,j=5;i<=0x07;i++,j++){
-    tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
-    SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
-  }
-  for(i=0x10,j=7;i<=0x11;i++,j++){
-    tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
-    SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
-  }
-  for(i=0x15,j=9;i<=0x16;i++,j++){
-    tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
-    SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
-  }
-  for(i=0x0A,j=11;i<=0x0C;i++,j++){
-    tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
-    SiS_SetReg(SiS_Pr->SiS_P3c4,i,tempah);
-  }
-
-  tempah = (LVDSCRT1Ptr + ResIndex)->CR[14];
-  tempah &= 0xE0;
-  SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);
-
-  tempah = (LVDSCRT1Ptr + ResIndex)->CR[14];
-  tempah &= 0x01;
-  tempah <<= 5;
-  if(modeflag & DoubleScanMode)  tempah |= 0x080;
-  SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
+  if(LVDSCRT1Ptr) {
+
+     SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
+
+     for(i = 0; i <= 10; i++) {
+        tempah = (LVDSCRT1Ptr + ResIndex)->CR[i];
+        SiS_SetReg(SiS_Pr->SiS_P3d4,CRIdx[i],tempah);
+     }
+
+     for(i = 0x0A, j = 11; i <= 0x0C; i++, j++) {
+        tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
+        SiS_SetReg(SiS_Pr->SiS_P3c4,i,tempah);
+     }
+
+     tempah = (LVDSCRT1Ptr + ResIndex)->CR[14] & 0xE0;
+     SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);
+
+     if(ModeNo <= 0x13) modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+     else               modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+
+     tempah = ((LVDSCRT1Ptr + ResIndex)->CR[14] & 0x01) << 5;
+     if(modeflag & DoubleScanMode) tempah |= 0x80;
+     SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
+
+  } else {
+
+     SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
+
+  }
 }
 
 /*********************************************/
@@ -8056,24 +7914,24 @@ SiS_ModCRT1CRTC(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 /*********************************************/
 
 static void
-SiS_SetCRT2ECLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
-           USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
+SiS_SetCRT2ECLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
+           unsigned short RefreshRateTableIndex)
 {
-  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
-  USHORT clkbase, vclkindex=0;
-  UCHAR  sr2b, sr2c;
+  unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
+  unsigned short clkbase, vclkindex = 0;
+  unsigned char  sr2b, sr2c;
 
-  if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) || (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
-       SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
-        if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK & 0x3f) == 2) {
-          RefreshRateTableIndex--;
-       }
-       vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
-                                    RefreshRateTableIndex, HwInfo);
-       SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
+  if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
+     SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
+     if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK == 2) {
+       RefreshRateTableIndex--;
+     }
+     vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
+                                    RefreshRateTableIndex);
+     SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
   } else {
-        vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
-                                    RefreshRateTableIndex, HwInfo);
+     vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
+                                    RefreshRateTableIndex);
   }
 
   sr2b = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
@@ -8082,7 +7940,7 @@ SiS_SetCRT2ECLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
   if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
      if(SiS_Pr->SiS_UseROM) {
        if(ROMAddr[0x220] & 0x01) {
-           sr2b = ROMAddr[0x227];
+          sr2b = ROMAddr[0x227];
           sr2c = ROMAddr[0x228];
        }
      }
@@ -8091,7 +7949,7 @@ SiS_SetCRT2ECLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
   clkbase = 0x02B;
   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
      if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-       clkbase += 3;
+       clkbase += 3;
      }
   }
 
@@ -8111,368 +7969,331 @@ SiS_SetCRT2ECLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 /*********************************************/
 
 static void
-SiS_SetCHTVReg(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
-               USHORT RefreshRateTableIndex)
+SiS_SetCHTVReg(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
+               unsigned short RefreshRateTableIndex)
 {
-#if defined(SIS300) || defined(SIS315H)
-  USHORT temp, tempbx;
-#endif
-  USHORT tempcl;
-  USHORT TVType, resindex;
-  const SiS_CHTVRegDataStruct *CHTVRegData = NULL;
+   unsigned short TVType, resindex;
+   const struct SiS_CHTVRegData *CHTVRegData = NULL;
 
-  if(ModeNo <= 0x13)
-     tempcl = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-  else
-     tempcl = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+   if(ModeNo <= 0x13)
+      resindex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+   else
+      resindex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
 
-  TVType = 0;
-  if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
-  if(SiS_Pr->SiS_TVMode & TVSetPAL) {
-       TVType += 2;
-       if(SiS_Pr->SiS_ModeType > ModeVGA) {
-          if(SiS_Pr->SiS_CHSOverScan) TVType = 8;
-       }
-       if(SiS_Pr->SiS_TVMode & TVSetPALM) {
-               TVType = 4;
-               if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
-       } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
-               TVType = 6;
-               if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
-       }
-  }
-  switch(TVType) {
-     case  0: CHTVRegData = SiS_Pr->SiS_CHTVReg_UNTSC; break;
-     case  1: CHTVRegData = SiS_Pr->SiS_CHTVReg_ONTSC; break;
-     case  2: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPAL;  break;
-     case  3: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL;  break;
-     case  4: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALM; break;
-     case  5: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALM; break;
-     case  6: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALN; break;
-     case  7: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALN; break;
-     case  8: CHTVRegData = SiS_Pr->SiS_CHTVReg_SOPAL; break;
-     default: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL;  break;
-  }
-  resindex = tempcl & 0x3F;
+   resindex &= 0x3F;
 
-  if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
+   TVType = 0;
+   if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
+   if(SiS_Pr->SiS_TVMode & TVSetPAL) {
+      TVType += 2;
+      if(SiS_Pr->SiS_ModeType > ModeVGA) {
+        if(SiS_Pr->SiS_CHSOverScan) TVType = 8;
+      }
+      if(SiS_Pr->SiS_TVMode & TVSetPALM) {
+        TVType = 4;
+        if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
+      } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
+        TVType = 6;
+        if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
+      }
+   }
+
+   switch(TVType) {
+      case  0: CHTVRegData = SiS_Pr->SiS_CHTVReg_UNTSC; break;
+      case  1: CHTVRegData = SiS_Pr->SiS_CHTVReg_ONTSC; break;
+      case  2: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPAL;  break;
+      case  3: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL;  break;
+      case  4: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALM; break;
+      case  5: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALM; break;
+      case  6: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALN; break;
+      case  7: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALN; break;
+      case  8: CHTVRegData = SiS_Pr->SiS_CHTVReg_SOPAL; break;
+      default: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL;  break;
+   }
+
+
+   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
 
 #ifdef SIS300
 
-     /* Chrontel 7005 - I assume that it does not come with a 315 series chip */
+      /* Chrontel 7005 - I assume that it does not come with a 315 series chip */
 
-     /* We don't support modes >800x600 */
-     if (resindex > 5) return;
+      /* We don't support modes >800x600 */
+      if (resindex > 5) return;
 
-     if(SiS_Pr->SiS_TVMode & TVSetPAL) {
-       SiS_SetCH700x(SiS_Pr,0x4304);   /* 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
-       SiS_SetCH700x(SiS_Pr,0x6909);   /* Black level for PAL (105)*/
-     } else {
-       SiS_SetCH700x(SiS_Pr,0x0304);   /* upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
-       SiS_SetCH700x(SiS_Pr,0x7109);   /* Black level for NTSC (113)*/
-     }
-
-     temp = CHTVRegData[resindex].Reg[0];
-     tempbx=((temp&0x00FF)<<8)|0x00;   /* Mode register */
-     SiS_SetCH700x(SiS_Pr,tempbx);
-     temp = CHTVRegData[resindex].Reg[1];
-     tempbx=((temp&0x00FF)<<8)|0x07;   /* Start active video register */
-     SiS_SetCH700x(SiS_Pr,tempbx);
-     temp = CHTVRegData[resindex].Reg[2];
-     tempbx=((temp&0x00FF)<<8)|0x08;   /* Position overflow register */
-     SiS_SetCH700x(SiS_Pr,tempbx);
-     temp = CHTVRegData[resindex].Reg[3];
-     tempbx=((temp&0x00FF)<<8)|0x0A;   /* Horiz Position register */
-     SiS_SetCH700x(SiS_Pr,tempbx);
-     temp = CHTVRegData[resindex].Reg[4];
-     tempbx=((temp&0x00FF)<<8)|0x0B;   /* Vertical Position register */
-     SiS_SetCH700x(SiS_Pr,tempbx);
-
-     /* Set minimum flicker filter for Luma channel (SR1-0=00),
+      if(SiS_Pr->SiS_TVMode & TVSetPAL) {
+        SiS_SetCH700x(SiS_Pr,0x04,0x43);  /* 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
+        SiS_SetCH700x(SiS_Pr,0x09,0x69);  /* Black level for PAL (105)*/
+      } else {
+        SiS_SetCH700x(SiS_Pr,0x04,0x03);   /* upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
+        SiS_SetCH700x(SiS_Pr,0x09,0x71);   /* Black level for NTSC (113)*/
+      }
+
+      SiS_SetCH700x(SiS_Pr,0x00,CHTVRegData[resindex].Reg[0]); /* Mode register */
+      SiS_SetCH700x(SiS_Pr,0x07,CHTVRegData[resindex].Reg[1]); /* Start active video register */
+      SiS_SetCH700x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[2]); /* Position overflow register */
+      SiS_SetCH700x(SiS_Pr,0x0a,CHTVRegData[resindex].Reg[3]); /* Horiz Position register */
+      SiS_SetCH700x(SiS_Pr,0x0b,CHTVRegData[resindex].Reg[4]); /* Vertical Position register */
+
+      /* Set minimum flicker filter for Luma channel (SR1-0=00),
                 minimum text enhancement (S3-2=10),
                maximum flicker filter for Chroma channel (S5-4=10)
                =00101000=0x28 (When reading, S1-0->S3-2, and S3-2->S1-0!)
-      */
-     SiS_SetCH700x(SiS_Pr,0x2801);
+       */
+      SiS_SetCH700x(SiS_Pr,0x01,0x28);
 
-     /* Set video bandwidth
+      /* Set video bandwidth
             High bandwith Luma composite video filter(S0=1)
             low bandwith Luma S-video filter (S2-1=00)
            disable peak filter in S-video channel (S3=0)
            high bandwidth Chroma Filter (S5-4=11)
            =00110001=0x31
-     */
-     SiS_SetCH700x(SiS_Pr,0xb103);       /* old: 3103 */
+      */
+      SiS_SetCH700x(SiS_Pr,0x03,0xb1);       /* old: 3103 */
 
-     /* Register 0x3D does not exist in non-macrovision register map
+      /* Register 0x3D does not exist in non-macrovision register map
             (Maybe this is a macrovision register?)
-      */
+       */
 #ifndef SIS_CP
-     SiS_SetCH70xx(SiS_Pr,0x003D);
+      SiS_SetCH70xx(SiS_Pr,0x3d,0x00);
 #endif
 
-     /* Register 0x10 only contains 1 writable bit (S0) for sensing,
-            all other bits a read-only. Macrovision?
-      */
-     SiS_SetCH70xxANDOR(SiS_Pr,0x0010,0x1F);
+      /* Register 0x10 only contains 1 writable bit (S0) for sensing,
+             all other bits a read-only. Macrovision?
+       */
+      SiS_SetCH70xxANDOR(SiS_Pr,0x10,0x00,0x1F);
 
-     /* Register 0x11 only contains 3 writable bits (S0-S2) for
-            contrast enhancement (set to 010 -> gain 1 Yout = 17/16*(Yin-30) )
-      */
-     SiS_SetCH70xxANDOR(SiS_Pr,0x0211,0xF8);
+      /* Register 0x11 only contains 3 writable bits (S0-S2) for
+             contrast enhancement (set to 010 -> gain 1 Yout = 17/16*(Yin-30) )
+       */
+      SiS_SetCH70xxANDOR(SiS_Pr,0x11,0x02,0xF8);
 
-     /* Clear DSEN
-      */
-     SiS_SetCH70xxANDOR(SiS_Pr,0x001C,0xEF);
-
-     if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {            /* ---- NTSC ---- */
-       if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) {
-         if(resindex == 0x04) {                        /* 640x480 overscan: Mode 16 */
-          SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF);      /* loop filter off */
-           SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);      /* ACIV on, no need to set FSCI */
-         } else if(resindex == 0x05) {                 /* 800x600 overscan: Mode 23 */
-           SiS_SetCH70xxANDOR(SiS_Pr,0x0118,0xF0);     /* 0x18-0x1f: FSCI 469,762,048 */
-           SiS_SetCH70xxANDOR(SiS_Pr,0x0C19,0xF0);
-           SiS_SetCH70xxANDOR(SiS_Pr,0x001A,0xF0);
-           SiS_SetCH70xxANDOR(SiS_Pr,0x001B,0xF0);
-           SiS_SetCH70xxANDOR(SiS_Pr,0x001C,0xF0);
-           SiS_SetCH70xxANDOR(SiS_Pr,0x001D,0xF0);
-           SiS_SetCH70xxANDOR(SiS_Pr,0x001E,0xF0);
-           SiS_SetCH70xxANDOR(SiS_Pr,0x001F,0xF0);
-           SiS_SetCH70xxANDOR(SiS_Pr,0x0120,0xEF);       /* Loop filter on for mode 23 */
-           SiS_SetCH70xxANDOR(SiS_Pr,0x0021,0xFE);       /* ACIV off, need to set FSCI */
-         }
-       } else {
-         if(resindex == 0x04) {                         /* ----- 640x480 underscan; Mode 17 */
-           SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF);      /* loop filter off */
-           SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);
-         } else if(resindex == 0x05) {                  /* ----- 800x600 underscan: Mode 24 */
+      /* Clear DSEN
+       */
+      SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xEF);
+
+      if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {           /* ---- NTSC ---- */
+         if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) {
+            if(resindex == 0x04) {                     /* 640x480 overscan: Mode 16 */
+              SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);       /* loop filter off */
+               SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);      /* ACIV on, no need to set FSCI */
+            } else if(resindex == 0x05) {              /* 800x600 overscan: Mode 23 */
+               SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0);      /* 0x18-0x1f: FSCI 469,762,048 */
+               SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x0C,0xF0);
+               SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x00,0xF0);
+               SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x00,0xF0);
+               SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xF0);
+               SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x00,0xF0);
+               SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x00,0xF0);
+               SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x00,0xF0);
+               SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x01,0xEF);      /* Loop filter on for mode 23 */
+               SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE);      /* ACIV off, need to set FSCI */
+            }
+         } else {
+            if(resindex == 0x04) {                             /* ----- 640x480 underscan; Mode 17 */
+               SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);      /* loop filter off */
+               SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);
+            } else if(resindex == 0x05) {              /* ----- 800x600 underscan: Mode 24 */
 #if 0
-           SiS_SetCH70xxANDOR(SiS_Pr,0x0118,0xF0);       /* (FSCI was 0x1f1c71c7 - this is for mode 22) */
-           SiS_SetCH70xxANDOR(SiS_Pr,0x0919,0xF0);      /* FSCI for mode 24 is 428,554,851 */
-           SiS_SetCH70xxANDOR(SiS_Pr,0x081A,0xF0);       /* 198b3a63 */
-           SiS_SetCH70xxANDOR(SiS_Pr,0x0b1B,0xF0);
-           SiS_SetCH70xxANDOR(SiS_Pr,0x041C,0xF0);
-           SiS_SetCH70xxANDOR(SiS_Pr,0x011D,0xF0);
-           SiS_SetCH70xxANDOR(SiS_Pr,0x061E,0xF0);
-           SiS_SetCH70xxANDOR(SiS_Pr,0x051F,0xF0);
-           SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF);       /* loop filter off for mode 24 */
-           SiS_SetCH70xxANDOR(SiS_Pr,0x0021,0xFE);      /* ACIV off, need to set FSCI */
-#endif     /* All alternatives wrong (datasheet wrong?), don't use FSCI */
-          SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF);       /* loop filter off */
-           SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);
+               SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0);      /* (FSCI was 0x1f1c71c7 - this is for mode 22) */
+               SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x09,0xF0);      /* FSCI for mode 24 is 428,554,851 */
+               SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x08,0xF0);       /* 198b3a63 */
+               SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x0b,0xF0);
+               SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x04,0xF0);
+               SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x01,0xF0);
+               SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x06,0xF0);
+               SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x05,0xF0);
+               SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);      /* loop filter off for mode 24 */
+               SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE);      * ACIV off, need to set FSCI */
+#endif         /* All alternatives wrong (datasheet wrong?), don't use FSCI */
+              SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);        /* loop filter off */
+               SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);
+            }
          }
-       }
-     } else {                                          /* ---- PAL ---- */
-           /* We don't play around with FSCI in PAL mode */
+      } else {                                         /* ---- PAL ---- */
+         /* We don't play around with FSCI in PAL mode */
          if(resindex == 0x04) {
-           SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF);     /* loop filter off */
-           SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);      /* ACIV on */
+            SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
+            SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE); /* ACIV on */
          } else {
-           SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF);     /* loop filter off */
-           SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);      /* ACIV on */
+            SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
+            SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE); /* ACIV on */
          }
-     }
-     
+      }
+
 #endif  /* 300 */
 
-  } else {
+   } else {
 
-     /* Chrontel 7019 - assumed that it does not come with a 300 series chip */
+      /* Chrontel 7019 - assumed that it does not come with a 300 series chip */
 
 #ifdef SIS315H
 
-     /* We don't support modes >1024x768 */
-     if (resindex > 6) return;
-
-     temp = CHTVRegData[resindex].Reg[0];
-     if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
-        temp |= 0x10;
-     }
-     tempbx=((temp & 0x00FF) << 8) | 0x00;
-     SiS_SetCH701x(SiS_Pr,tempbx);
-
-     temp = CHTVRegData[resindex].Reg[1];
-     tempbx=((temp & 0x00FF) << 8) | 0x01;
-     SiS_SetCH701x(SiS_Pr,tempbx);
-
-     temp = CHTVRegData[resindex].Reg[2];
-     tempbx=((temp & 0x00FF) << 8) | 0x02;
-     SiS_SetCH701x(SiS_Pr,tempbx);
-
-     temp = CHTVRegData[resindex].Reg[3];
-     tempbx=((temp & 0x00FF) << 8) | 0x04;
-     SiS_SetCH701x(SiS_Pr,tempbx);
-
-     temp = CHTVRegData[resindex].Reg[4];
-     tempbx=((temp & 0x00FF) << 8) | 0x03;
-     SiS_SetCH701x(SiS_Pr,tempbx);
-
-     temp = CHTVRegData[resindex].Reg[5];
-     tempbx=((temp & 0x00FF) << 8) | 0x05;
-     SiS_SetCH701x(SiS_Pr,tempbx);
-
-     temp = CHTVRegData[resindex].Reg[6];
-     tempbx=((temp & 0x00FF) << 8) | 0x06;
-     SiS_SetCH701x(SiS_Pr,tempbx);
-
-     temp = CHTVRegData[resindex].Reg[7];
-     if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
-       temp = 0x66;
-     }
-     tempbx=((temp & 0x00FF) << 8) | 0x07;
-     SiS_SetCH701x(SiS_Pr,tempbx);
-
-     temp = CHTVRegData[resindex].Reg[8];
-     tempbx=((temp & 0x00FF) << 8) | 0x08;
-     SiS_SetCH701x(SiS_Pr,tempbx);
-
-     temp = CHTVRegData[resindex].Reg[9];
-     tempbx=((temp & 0x00FF) << 8) | 0x15;
-     SiS_SetCH701x(SiS_Pr,tempbx);
-
-     temp = CHTVRegData[resindex].Reg[10];
-     tempbx=((temp & 0x00FF) << 8) | 0x1f;
-     SiS_SetCH701x(SiS_Pr,tempbx);
-
-     temp = CHTVRegData[resindex].Reg[11];
-     tempbx=((temp & 0x00FF) << 8) | 0x0c;
-     SiS_SetCH701x(SiS_Pr,tempbx);
-
-     temp = CHTVRegData[resindex].Reg[12];
-     tempbx=((temp & 0x00FF) << 8) | 0x0d;
-     SiS_SetCH701x(SiS_Pr,tempbx);
-
-     temp = CHTVRegData[resindex].Reg[13];
-     tempbx=((temp & 0x00FF) << 8) | 0x0e;
-     SiS_SetCH701x(SiS_Pr,tempbx);
-
-     temp = CHTVRegData[resindex].Reg[14];
-     tempbx=((temp & 0x00FF) << 8) | 0x0f;
-     SiS_SetCH701x(SiS_Pr,tempbx);
-
-     temp = CHTVRegData[resindex].Reg[15];
-     tempbx=((temp & 0x00FF) << 8) | 0x10;
-     SiS_SetCH701x(SiS_Pr,tempbx);
-
-     temp = SiS_GetCH701x(SiS_Pr,0x21) & ~0x02;
-     /* D1 should be set for PAL, PAL-N and NTSC-J,
-        but I won't do that for PAL unless somebody
-       tells me to do so. Since the BIOS uses
-       non-default CIV values and blacklevels,
-       this might be compensated anyway.
-      */
-     if(SiS_Pr->SiS_TVMode & (TVSetPALN | TVSetNTSCJ)) temp |= 0x02;
-     SiS_SetCH701x(SiS_Pr,((temp << 8) | 0x21));
+      unsigned short temp;
+
+      /* We don't support modes >1024x768 */
+      if (resindex > 6) return;
+
+      temp = CHTVRegData[resindex].Reg[0];
+      if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp |= 0x10;
+      SiS_SetCH701x(SiS_Pr,0x00,temp);
+
+      SiS_SetCH701x(SiS_Pr,0x01,CHTVRegData[resindex].Reg[1]);
+      SiS_SetCH701x(SiS_Pr,0x02,CHTVRegData[resindex].Reg[2]);
+      SiS_SetCH701x(SiS_Pr,0x04,CHTVRegData[resindex].Reg[3]);
+      SiS_SetCH701x(SiS_Pr,0x03,CHTVRegData[resindex].Reg[4]);
+      SiS_SetCH701x(SiS_Pr,0x05,CHTVRegData[resindex].Reg[5]);
+      SiS_SetCH701x(SiS_Pr,0x06,CHTVRegData[resindex].Reg[6]);
+
+      temp = CHTVRegData[resindex].Reg[7];
+      if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp = 0x66;
+      SiS_SetCH701x(SiS_Pr,0x07,temp);
+
+      SiS_SetCH701x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[8]);
+      SiS_SetCH701x(SiS_Pr,0x15,CHTVRegData[resindex].Reg[9]);
+      SiS_SetCH701x(SiS_Pr,0x1f,CHTVRegData[resindex].Reg[10]);
+      SiS_SetCH701x(SiS_Pr,0x0c,CHTVRegData[resindex].Reg[11]);
+      SiS_SetCH701x(SiS_Pr,0x0d,CHTVRegData[resindex].Reg[12]);
+      SiS_SetCH701x(SiS_Pr,0x0e,CHTVRegData[resindex].Reg[13]);
+      SiS_SetCH701x(SiS_Pr,0x0f,CHTVRegData[resindex].Reg[14]);
+      SiS_SetCH701x(SiS_Pr,0x10,CHTVRegData[resindex].Reg[15]);
+
+      temp = SiS_GetCH701x(SiS_Pr,0x21) & ~0x02;
+      /* D1 should be set for PAL, PAL-N and NTSC-J,
+         but I won't do that for PAL unless somebody
+        tells me to do so. Since the BIOS uses
+        non-default CIV values and blacklevels,
+        this might be compensated anyway.
+       */
+      if(SiS_Pr->SiS_TVMode & (TVSetPALN | TVSetNTSCJ)) temp |= 0x02;
+      SiS_SetCH701x(SiS_Pr,0x21,temp);
 
 #endif /* 315 */
 
-  }
+   }
 
 #ifdef SIS_CP
-  SIS_CP_INIT301_CP3
+   SIS_CP_INIT301_CP3
 #endif
 
 }
 
+#ifdef SIS315H  /* ----------- 315 series only ---------- */
+
 void
-SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_Chrontel701xBLOn(struct SiS_Private *SiS_Pr)
 {
-  USHORT temp;
+   unsigned short temp;
 
-  /* Enable Chrontel 7019 LCD panel backlight */
-  if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
-     if(HwInfo->jChipType == SIS_740) {
-        SiS_SetCH701x(SiS_Pr,0x6566);
-     } else {
-        temp = SiS_GetCH701x(SiS_Pr,0x66);
-        temp |= 0x20;
-       SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
-     }
-  }
+   /* Enable Chrontel 7019 LCD panel backlight */
+   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+      if(SiS_Pr->ChipType == SIS_740) {
+        SiS_SetCH701x(SiS_Pr,0x66,0x65);
+      } else {
+        temp = SiS_GetCH701x(SiS_Pr,0x66);
+        temp |= 0x20;
+        SiS_SetCH701x(SiS_Pr,0x66,temp);
+      }
+   }
 }
 
 void
-SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr)
+SiS_Chrontel701xBLOff(struct SiS_Private *SiS_Pr)
 {
-  USHORT temp;
+   unsigned short temp;
 
-  /* Disable Chrontel 7019 LCD panel backlight */
-  if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
-     temp = SiS_GetCH701x(SiS_Pr,0x66);
-     temp &= 0xDF;
-     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
-  }
+   /* Disable Chrontel 7019 LCD panel backlight */
+   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+      temp = SiS_GetCH701x(SiS_Pr,0x66);
+      temp &= 0xDF;
+      SiS_SetCH701x(SiS_Pr,0x66,temp);
+   }
 }
 
-#ifdef SIS315H  /* ----------- 315 series only ---------- */
-
 static void
-SiS_ChrontelPowerSequencing(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
-{
-  UCHAR regtable[]      = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
-  UCHAR table1024_740[] = { 0x01, 0x02, 0x01, 0x01, 0x01 };
-  UCHAR table1400_740[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 };
-  UCHAR asus1024_740[]  = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
-  UCHAR asus1400_740[]  = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
-  UCHAR table1024_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
-  UCHAR table1400_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
-  UCHAR *tableptr = NULL;
+SiS_ChrontelPowerSequencing(struct SiS_Private *SiS_Pr)
+{
+  static const unsigned char regtable[]      = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
+  static const unsigned char table1024_740[] = { 0x01, 0x02, 0x01, 0x01, 0x01 };
+  static const unsigned char table1400_740[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 };
+  static const unsigned char asus1024_740[]  = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
+  static const unsigned char asus1400_740[]  = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
+  static const unsigned char table1024_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
+  static const unsigned char table1400_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
+  const unsigned char *tableptr = NULL;
   int i;
 
   /* Set up Power up/down timing */
 
-  if(HwInfo->jChipType == SIS_740) {
+  if(SiS_Pr->ChipType == SIS_740) {
      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
-        if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1024_740;
-        else                                     tableptr = table1024_740;
+       if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1024_740;
+       else                                      tableptr = table1024_740;
      } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
-               (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
+              (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
               (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
        if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1400_740;
         else                                     tableptr = table1400_740;
      } else return;
   } else {
      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
-        tableptr = table1024_650;
+       tableptr = table1024_650;
      } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
-               (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
+              (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
               (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
-        tableptr = table1400_650;
+       tableptr = table1400_650;
      } else return;
   }
 
   for(i=0; i<5; i++) {
-     SiS_SetCH701x(SiS_Pr,(tableptr[i] << 8) | regtable[i]);
+     SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]);
   }
 }
 
 static void
-SiS_SetCH701xForLCD(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
-{
-  UCHAR regtable[]      = { 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
-                            0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66 };
-  UCHAR table1024_740[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
-                            0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44 };
-  UCHAR table1280_740[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
-                           0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 };
-  UCHAR table1400_740[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
-                            0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 };
-  UCHAR table1600_740[] = { 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
-                           0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44 };
-  UCHAR table1024_650[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
-                            0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02 };
-  UCHAR table1280_650[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
-                           0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02 };
-  UCHAR table1400_650[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xef,
-                            0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02 };
-  UCHAR table1600_650[] = { 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
-                           0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a };
-  UCHAR *tableptr = NULL;
-  USHORT tempbh;
+SiS_SetCH701xForLCD(struct SiS_Private *SiS_Pr)
+{
+  const unsigned char *tableptr = NULL;
+  unsigned short tempbh;
   int i;
+  static const unsigned char regtable[] = {
+               0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
+               0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66
+  };
+  static const unsigned char table1024_740[] = {
+               0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
+               0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44
+  };
+  static const unsigned char table1280_740[] = {
+               0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
+               0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44
+  };
+  static const unsigned char table1400_740[] = {
+               0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
+               0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44
+  };
+  static const unsigned char table1600_740[] = {
+               0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
+               0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44
+  };
+  static const unsigned char table1024_650[] = {
+               0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
+               0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02
+  };
+  static const unsigned char table1280_650[] = {
+               0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
+               0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02
+  };
+  static const unsigned char table1400_650[] = {
+               0x60, 0x03, 0x11, 0x00, 0x40, 0xef,
+               0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02
+  };
+  static const unsigned char table1600_650[] = {
+               0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
+               0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a
+  };
 
-  if(HwInfo->jChipType == SIS_740) {
+  if(SiS_Pr->ChipType == SIS_740) {
      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)       tableptr = table1024_740;
      else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_740;
      else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_740;
@@ -8499,138 +8320,139 @@ SiS_SetCH701xForLCD(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
      }
   }
 
-  if(HwInfo->jChipType == SIS_740) tempbh = 0x0d;
-  else                            tempbh = 0x0c;
+  if(SiS_Pr->ChipType == SIS_740) tempbh = 0x0d;
+  else                           tempbh = 0x0c;
 
   for(i = 0; i < tempbh; i++) {
-     SiS_SetCH701x(SiS_Pr,(tableptr[i] << 8) | regtable[i]);
+     SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]);
   }
-  SiS_ChrontelPowerSequencing(SiS_Pr,HwInfo);
+  SiS_ChrontelPowerSequencing(SiS_Pr);
   tempbh = SiS_GetCH701x(SiS_Pr,0x1e);
   tempbh |= 0xc0;
-  SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x1e);
+  SiS_SetCH701x(SiS_Pr,0x1e,tempbh);
 
-  if(HwInfo->jChipType == SIS_740) {
+  if(SiS_Pr->ChipType == SIS_740) {
      tempbh = SiS_GetCH701x(SiS_Pr,0x1c);
      tempbh &= 0xfb;
-     SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x1c);
+     SiS_SetCH701x(SiS_Pr,0x1c,tempbh);
      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
      tempbh = SiS_GetCH701x(SiS_Pr,0x64);
      tempbh |= 0x40;
-     SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x64);
+     SiS_SetCH701x(SiS_Pr,0x64,tempbh);
      tempbh = SiS_GetCH701x(SiS_Pr,0x03);
      tempbh &= 0x3f;
-     SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x03);
+     SiS_SetCH701x(SiS_Pr,0x03,tempbh);
   }
 }
 
 static void
-SiS_ChrontelResetVSync(SiS_Private *SiS_Pr)
+SiS_ChrontelResetVSync(struct SiS_Private *SiS_Pr)
 {
   unsigned char temp, temp1;
 
   temp1 = SiS_GetCH701x(SiS_Pr,0x49);
-  SiS_SetCH701x(SiS_Pr,0x3e49);
+  SiS_SetCH701x(SiS_Pr,0x49,0x3e);
   temp = SiS_GetCH701x(SiS_Pr,0x47);
   temp &= 0x7f;        /* Use external VSYNC */
-  SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
-  SiS_LongDelay(SiS_Pr,3);
+  SiS_SetCH701x(SiS_Pr,0x47,temp);
+  SiS_LongDelay(SiS_Pr, 3);
   temp = SiS_GetCH701x(SiS_Pr,0x47);
   temp |= 0x80;        /* Use internal VSYNC */
-  SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
-  SiS_SetCH701x(SiS_Pr,(temp1 << 8) | 0x49);
+  SiS_SetCH701x(SiS_Pr,0x47,temp);
+  SiS_SetCH701x(SiS_Pr,0x49,temp1);
 }
 
 static void
-SiS_Chrontel701xOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_Chrontel701xOn(struct SiS_Private *SiS_Pr)
 {
-  USHORT temp;
+  unsigned short temp;
 
   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
-     if(HwInfo->jChipType == SIS_740) {
+     if(SiS_Pr->ChipType == SIS_740) {
         temp = SiS_GetCH701x(SiS_Pr,0x1c);
         temp |= 0x04;  /* Invert XCLK phase */
-        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c);
+        SiS_SetCH701x(SiS_Pr,0x1c,temp);
      }
-     if(SiS_IsYPbPr(SiS_Pr, HwInfo)) {
+     if(SiS_IsYPbPr(SiS_Pr)) {
         temp = SiS_GetCH701x(SiS_Pr,0x01);
        temp &= 0x3f;
        temp |= 0x80;   /* Enable YPrPb (HDTV) */
-       SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x01);
+       SiS_SetCH701x(SiS_Pr,0x01,temp);
      }
-     if(SiS_IsChScart(SiS_Pr, HwInfo)) {
+     if(SiS_IsChScart(SiS_Pr)) {
         temp = SiS_GetCH701x(SiS_Pr,0x01);
        temp &= 0x3f;
        temp |= 0xc0;   /* Enable SCART + CVBS */
-       SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x01);
+       SiS_SetCH701x(SiS_Pr,0x01,temp);
      }
-     if(HwInfo->jChipType == SIS_740) {
+     if(SiS_Pr->ChipType == SIS_740) {
         SiS_ChrontelResetVSync(SiS_Pr);
-        SiS_SetCH701x(SiS_Pr,0x2049);   /* Enable TV path */
+        SiS_SetCH701x(SiS_Pr,0x49,0x20);   /* Enable TV path */
      } else {
-        SiS_SetCH701x(SiS_Pr,0x2049);   /* Enable TV path */
+        SiS_SetCH701x(SiS_Pr,0x49,0x20);   /* Enable TV path */
         temp = SiS_GetCH701x(SiS_Pr,0x49);
-        if(SiS_IsYPbPr(SiS_Pr,HwInfo)) {
+        if(SiS_IsYPbPr(SiS_Pr)) {
            temp = SiS_GetCH701x(SiS_Pr,0x73);
           temp |= 0x60;
-          SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x73);
+          SiS_SetCH701x(SiS_Pr,0x73,temp);
         }
         temp = SiS_GetCH701x(SiS_Pr,0x47);
         temp &= 0x7f;
-        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
-        SiS_LongDelay(SiS_Pr,2);
+        SiS_SetCH701x(SiS_Pr,0x47,temp);
+        SiS_LongDelay(SiS_Pr, 2);
         temp = SiS_GetCH701x(SiS_Pr,0x47);
         temp |= 0x80;
-        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
+        SiS_SetCH701x(SiS_Pr,0x47,temp);
      }
   }
 }
 
 static void
-SiS_Chrontel701xOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_Chrontel701xOff(struct SiS_Private *SiS_Pr)
 {
-  USHORT temp;
+  unsigned short temp;
 
   /* Complete power down of LVDS */
   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
-     if(HwInfo->jChipType == SIS_740) {
-        SiS_LongDelay(SiS_Pr,1);
-       SiS_GenericDelay(SiS_Pr,0x16ff);
-       SiS_SetCH701x(SiS_Pr,0xac76);
-       SiS_SetCH701x(SiS_Pr,0x0066);
+     if(SiS_Pr->ChipType == SIS_740) {
+        SiS_LongDelay(SiS_Pr, 1);
+       SiS_GenericDelay(SiS_Pr, 5887);
+       SiS_SetCH701x(SiS_Pr,0x76,0xac);
+       SiS_SetCH701x(SiS_Pr,0x66,0x00);
      } else {
-        SiS_LongDelay(SiS_Pr,2);
+        SiS_LongDelay(SiS_Pr, 2);
        temp = SiS_GetCH701x(SiS_Pr,0x76);
        temp &= 0xfc;
-       SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
-       SiS_SetCH701x(SiS_Pr,0x0066);
+       SiS_SetCH701x(SiS_Pr,0x76,temp);
+       SiS_SetCH701x(SiS_Pr,0x66,0x00);
      }
   }
 }
 
 static void
-SiS_ChrontelResetDB(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_ChrontelResetDB(struct SiS_Private *SiS_Pr)
 {
-     USHORT temp;
+     unsigned short temp;
 
-     if(HwInfo->jChipType == SIS_740) {
+     if(SiS_Pr->ChipType == SIS_740) {
 
         temp = SiS_GetCH701x(SiS_Pr,0x4a);  /* Version ID */
         temp &= 0x01;
         if(!temp) {
 
-           if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo)) {
+           if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
              temp = SiS_GetCH701x(SiS_Pr,0x49);
-             SiS_SetCH701x(SiS_Pr,0x3e49);
+             SiS_SetCH701x(SiS_Pr,0x49,0x3e);
           }
+
           /* Reset Chrontel 7019 datapath */
-           SiS_SetCH701x(SiS_Pr,0x1048);
-           SiS_LongDelay(SiS_Pr,1);
-           SiS_SetCH701x(SiS_Pr,0x1848);
+           SiS_SetCH701x(SiS_Pr,0x48,0x10);
+           SiS_LongDelay(SiS_Pr, 1);
+           SiS_SetCH701x(SiS_Pr,0x48,0x18);
 
-          if(SiS_WeHaveBacklightCtrl(SiS_Pr, HwInfo)) {
+          if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
              SiS_ChrontelResetVSync(SiS_Pr);
-             SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x49);
+             SiS_SetCH701x(SiS_Pr,0x49,temp);
           }
 
         } else {
@@ -8638,72 +8460,72 @@ SiS_ChrontelResetDB(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
           /* Clear/set/clear GPIO */
            temp = SiS_GetCH701x(SiS_Pr,0x5c);
           temp &= 0xef;
-          SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
+          SiS_SetCH701x(SiS_Pr,0x5c,temp);
           temp = SiS_GetCH701x(SiS_Pr,0x5c);
           temp |= 0x10;
-          SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
+          SiS_SetCH701x(SiS_Pr,0x5c,temp);
           temp = SiS_GetCH701x(SiS_Pr,0x5c);
           temp &= 0xef;
-          SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
+          SiS_SetCH701x(SiS_Pr,0x5c,temp);
           temp = SiS_GetCH701x(SiS_Pr,0x61);
           if(!temp) {
-             SiS_SetCH701xForLCD(SiS_Pr, HwInfo);
+             SiS_SetCH701xForLCD(SiS_Pr);
           }
         }
 
      } else { /* 650 */
         /* Reset Chrontel 7019 datapath */
-        SiS_SetCH701x(SiS_Pr,0x1048);
-        SiS_LongDelay(SiS_Pr,1);
-        SiS_SetCH701x(SiS_Pr,0x1848);
+        SiS_SetCH701x(SiS_Pr,0x48,0x10);
+        SiS_LongDelay(SiS_Pr, 1);
+        SiS_SetCH701x(SiS_Pr,0x48,0x18);
      }
 }
 
 static void
-SiS_ChrontelInitTVVSync(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_ChrontelInitTVVSync(struct SiS_Private *SiS_Pr)
 {
-     USHORT temp;
+     unsigned short temp;
 
-     if(HwInfo->jChipType == SIS_740) {
+     if(SiS_Pr->ChipType == SIS_740) {
 
-        if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo)) {
+        if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
            SiS_ChrontelResetVSync(SiS_Pr);
         }
 
      } else {
 
-        SiS_SetCH701x(SiS_Pr,0xaf76);  /* Power up LVDS block */
+        SiS_SetCH701x(SiS_Pr,0x76,0xaf);  /* Power up LVDS block */
         temp = SiS_GetCH701x(SiS_Pr,0x49);
         temp &= 1;
         if(temp != 1) {  /* TV block powered? (0 = yes, 1 = no) */
           temp = SiS_GetCH701x(SiS_Pr,0x47);
           temp &= 0x70;
-          SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);  /* enable VSYNC */
-          SiS_LongDelay(SiS_Pr,3);
+          SiS_SetCH701x(SiS_Pr,0x47,temp);  /* enable VSYNC */
+          SiS_LongDelay(SiS_Pr, 3);
           temp = SiS_GetCH701x(SiS_Pr,0x47);
           temp |= 0x80;
-          SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);  /* disable VSYNC */
+          SiS_SetCH701x(SiS_Pr,0x47,temp);  /* disable VSYNC */
         }
 
      }
 }
 
 static void
-SiS_ChrontelDoSomething3(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_INFO HwInfo)
+SiS_ChrontelDoSomething3(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
 {
-     USHORT temp,temp1;
+     unsigned short temp,temp1;
 
-     if(HwInfo->jChipType == SIS_740) {
+     if(SiS_Pr->ChipType == SIS_740) {
 
         temp = SiS_GetCH701x(SiS_Pr,0x61);
         if(temp < 1) {
            temp++;
-          SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61);
+          SiS_SetCH701x(SiS_Pr,0x61,temp);
         }
-        SiS_SetCH701x(SiS_Pr,0x4566);  /* Panel power on */
-        SiS_SetCH701x(SiS_Pr,0xaf76);  /* All power on */
-        SiS_LongDelay(SiS_Pr,1);
-        SiS_GenericDelay(SiS_Pr,0x16ff);
+        SiS_SetCH701x(SiS_Pr,0x66,0x45);  /* Panel power on */
+        SiS_SetCH701x(SiS_Pr,0x76,0xaf);  /* All power on */
+        SiS_LongDelay(SiS_Pr, 1);
+        SiS_GenericDelay(SiS_Pr, 5887);
 
      } else {  /* 650 */
 
@@ -8711,38 +8533,38 @@ SiS_ChrontelDoSomething3(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_INFO HwInfo
         temp = SiS_GetCH701x(SiS_Pr,0x61);
         if(temp < 2) {
            temp++;
-          SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61);
+          SiS_SetCH701x(SiS_Pr,0x61,temp);
           temp1 = 1;
         }
-        SiS_SetCH701x(SiS_Pr,0xac76);
+        SiS_SetCH701x(SiS_Pr,0x76,0xac);
         temp = SiS_GetCH701x(SiS_Pr,0x66);
         temp |= 0x5f;
-        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
+        SiS_SetCH701x(SiS_Pr,0x66,temp);
         if(ModeNo > 0x13) {
-           if(SiS_WeHaveBacklightCtrl(SiS_Pr, HwInfo)) {
-             SiS_GenericDelay(SiS_Pr,0x3ff);
+           if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
+             SiS_GenericDelay(SiS_Pr, 1023);
           } else {
-             SiS_GenericDelay(SiS_Pr,0x2ff);
+             SiS_GenericDelay(SiS_Pr, 767);
           }
         } else {
            if(!temp1)
-             SiS_GenericDelay(SiS_Pr,0x2ff);
+             SiS_GenericDelay(SiS_Pr, 767);
         }
         temp = SiS_GetCH701x(SiS_Pr,0x76);
         temp |= 0x03;
-        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
+        SiS_SetCH701x(SiS_Pr,0x76,temp);
         temp = SiS_GetCH701x(SiS_Pr,0x66);
         temp &= 0x7f;
-        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
-        SiS_LongDelay(SiS_Pr,1);
+        SiS_SetCH701x(SiS_Pr,0x66,temp);
+        SiS_LongDelay(SiS_Pr, 1);
 
      }
 }
 
 static void
-SiS_ChrontelDoSomething2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_ChrontelDoSomething2(struct SiS_Private *SiS_Pr)
 {
-     USHORT temp,tempcl,tempch;
+     unsigned short temp,tempcl,tempch;
 
      SiS_LongDelay(SiS_Pr, 1);
      tempcl = 3;
@@ -8753,87 +8575,87 @@ SiS_ChrontelDoSomething2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
        temp &= 0x04;  /* PLL stable? -> bail out */
        if(temp == 0x04) break;
 
-       if(HwInfo->jChipType == SIS_740) {
+       if(SiS_Pr->ChipType == SIS_740) {
           /* Power down LVDS output, PLL normal operation */
-          SiS_SetCH701x(SiS_Pr,0xac76);
+          SiS_SetCH701x(SiS_Pr,0x76,0xac);
        }
 
-       SiS_SetCH701xForLCD(SiS_Pr,HwInfo);
+       SiS_SetCH701xForLCD(SiS_Pr);
 
        if(tempcl == 0) {
            if(tempch == 3) break;
-          SiS_ChrontelResetDB(SiS_Pr,HwInfo);
+          SiS_ChrontelResetDB(SiS_Pr);
           tempcl = 3;
           tempch++;
        }
        tempcl--;
        temp = SiS_GetCH701x(SiS_Pr,0x76);
        temp &= 0xfb;  /* Reset PLL */
-       SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
-       SiS_LongDelay(SiS_Pr,2);
+       SiS_SetCH701x(SiS_Pr,0x76,temp);
+       SiS_LongDelay(SiS_Pr, 2);
        temp = SiS_GetCH701x(SiS_Pr,0x76);
        temp |= 0x04;  /* PLL normal operation */
-       SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
-       if(HwInfo->jChipType == SIS_740) {
-          SiS_SetCH701x(SiS_Pr,0xe078);        /* PLL loop filter */
+       SiS_SetCH701x(SiS_Pr,0x76,temp);
+       if(SiS_Pr->ChipType == SIS_740) {
+          SiS_SetCH701x(SiS_Pr,0x78,0xe0);     /* PLL loop filter */
        } else {
-          SiS_SetCH701x(SiS_Pr,0x6078);
+          SiS_SetCH701x(SiS_Pr,0x78,0x60);
        }
-       SiS_LongDelay(SiS_Pr,2);
+       SiS_LongDelay(SiS_Pr, 2);
     } while(0);
 
-    SiS_SetCH701x(SiS_Pr,0x0077);  /* MV? */
+    SiS_SetCH701x(SiS_Pr,0x77,0x00);  /* MV? */
 }
 
 static void
-SiS_ChrontelDoSomething1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_ChrontelDoSomething1(struct SiS_Private *SiS_Pr)
 {
-     USHORT temp;
+     unsigned short temp;
 
      temp = SiS_GetCH701x(SiS_Pr,0x03);
      temp |= 0x80;     /* Set datapath 1 to TV   */
      temp &= 0xbf;     /* Set datapath 2 to LVDS */
-     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x03);
+     SiS_SetCH701x(SiS_Pr,0x03,temp);
 
-     if(HwInfo->jChipType == SIS_740) {
+     if(SiS_Pr->ChipType == SIS_740) {
 
         temp = SiS_GetCH701x(SiS_Pr,0x1c);
         temp &= 0xfb;  /* Normal XCLK phase */
-        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c);
+        SiS_SetCH701x(SiS_Pr,0x1c,temp);
 
         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
 
         temp = SiS_GetCH701x(SiS_Pr,0x64);
         temp |= 0x40;  /* ? Bit not defined */
-        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x64);
+        SiS_SetCH701x(SiS_Pr,0x64,temp);
 
         temp = SiS_GetCH701x(SiS_Pr,0x03);
         temp &= 0x3f;  /* D1 input to both LVDS and TV */
-        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x03);
+        SiS_SetCH701x(SiS_Pr,0x03,temp);
 
        if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) {
-          SiS_SetCH701x(SiS_Pr,0x4063); /* LVDS off */
+          SiS_SetCH701x(SiS_Pr,0x63,0x40); /* LVDS off */
           SiS_LongDelay(SiS_Pr, 1);
-          SiS_SetCH701x(SiS_Pr,0x0063); /* LVDS on */
-          SiS_ChrontelResetDB(SiS_Pr, HwInfo);
-          SiS_ChrontelDoSomething2(SiS_Pr, HwInfo);
-          SiS_ChrontelDoSomething3(SiS_Pr, 0, HwInfo);
+          SiS_SetCH701x(SiS_Pr,0x63,0x00); /* LVDS on */
+          SiS_ChrontelResetDB(SiS_Pr);
+          SiS_ChrontelDoSomething2(SiS_Pr);
+          SiS_ChrontelDoSomething3(SiS_Pr, 0);
        } else {
            temp = SiS_GetCH701x(SiS_Pr,0x66);
            if(temp != 0x45) {
-              SiS_ChrontelResetDB(SiS_Pr, HwInfo);
-              SiS_ChrontelDoSomething2(SiS_Pr, HwInfo);
-              SiS_ChrontelDoSomething3(SiS_Pr, 0, HwInfo);
+              SiS_ChrontelResetDB(SiS_Pr);
+              SiS_ChrontelDoSomething2(SiS_Pr);
+              SiS_ChrontelDoSomething3(SiS_Pr, 0);
            }
        }
 
      } else { /* 650 */
 
-        SiS_ChrontelResetDB(SiS_Pr,HwInfo);
-        SiS_ChrontelDoSomething2(SiS_Pr,HwInfo);
+        SiS_ChrontelResetDB(SiS_Pr);
+        SiS_ChrontelDoSomething2(SiS_Pr);
         temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34);
-        SiS_ChrontelDoSomething3(SiS_Pr,temp,HwInfo);
-        SiS_SetCH701x(SiS_Pr,0xaf76);  /* All power on, LVDS normal operation */
+        SiS_ChrontelDoSomething3(SiS_Pr,temp);
+        SiS_SetCH701x(SiS_Pr,0x76,0xaf);  /* All power on, LVDS normal operation */
 
      }
 
@@ -8845,15 +8667,12 @@ SiS_ChrontelDoSomething1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 /*********************************************/
 
 BOOLEAN
-SiS_SetCRT2Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
+SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
 {
 #ifdef SIS300
-   UCHAR  *ROMAddr  = HwInfo->pjVirtualRomBase;
-#endif
-   USHORT ModeIdIndex, RefreshRateTableIndex;
-#if 0
-   USHORT temp;
+   unsigned char  *ROMAddr  = SiS_Pr->VirtualRomBase;
 #endif
+   unsigned short ModeIdIndex, RefreshRateTableIndex;
 
    SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
 
@@ -8866,37 +8685,37 @@ SiS_SetCRT2Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
    /* Used for shifting CR33 */
    SiS_Pr->SiS_SelectCRT2Rate = 4;
 
-   SiS_UnLockCRT2(SiS_Pr, HwInfo);
+   SiS_UnLockCRT2(SiS_Pr);
 
-   RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
+   RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex);
 
    SiS_SaveCRT2Info(SiS_Pr,ModeNo);
 
    if(SiS_Pr->SiS_SetFlag & LowModeTests) {
-      SiS_DisableBridge(SiS_Pr,HwInfo);
-      if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (HwInfo->jChipType == SIS_730)) {
+      SiS_DisableBridge(SiS_Pr);
+      if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->ChipType == SIS_730)) {
          SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,0x80);
       }
-      SiS_SetCRT2ModeRegs(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
+      SiS_SetCRT2ModeRegs(SiS_Pr, ModeNo, ModeIdIndex);
    }
 
    if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
-      SiS_LockCRT2(SiS_Pr, HwInfo);
+      SiS_LockCRT2(SiS_Pr);
       SiS_DisplayOn(SiS_Pr);
       return TRUE;
    }
 
-   SiS_GetCRT2Data(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
+   SiS_GetCRT2Data(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
 
    /* Set up Panel Link for LVDS and LCDA */
    SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
    if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
        ((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ||
-       ((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) ) {
-      SiS_GetLVDSDesData(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
+       ((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS30xBLV)) ) {
+      SiS_GetLVDSDesData(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
    }
 
-#ifdef LINUX_XF86
+#ifdef SIS_XORG_XF86
 #ifdef TWDEBUG
   xf86DrvMsg(0, X_INFO, "(init301: LCDHDES 0x%03x LCDVDES 0x%03x)\n", SiS_Pr->SiS_LCDHDES, SiS_Pr->SiS_LCDVDES);
   xf86DrvMsg(0, X_INFO, "(init301: HDE     0x%03x VDE     0x%03x)\n", SiS_Pr->SiS_HDE, SiS_Pr->SiS_VDE);
@@ -8907,86 +8726,79 @@ SiS_SetCRT2Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
 #endif
 
    if(SiS_Pr->SiS_SetFlag & LowModeTests) {
-      SiS_SetGroup1(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
+      SiS_SetGroup1(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
    }
 
    if(SiS_Pr->SiS_VBType & VB_SISVB) {
 
-        if(SiS_Pr->SiS_SetFlag & LowModeTests) {
+      if(SiS_Pr->SiS_SetFlag & LowModeTests) {
 
-          SiS_SetGroup2(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
+        SiS_SetGroup2(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
 #ifdef SIS315H
-          SiS_SetGroup2_C_ELV(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
+        SiS_SetGroup2_C_ELV(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
 #endif
-          SiS_SetGroup3(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
-          SiS_SetGroup4(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
+        SiS_SetGroup3(SiS_Pr, ModeNo, ModeIdIndex);
+        SiS_SetGroup4(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
 #ifdef SIS315H
-          SiS_SetGroup4_C_ELV(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
+        SiS_SetGroup4_C_ELV(SiS_Pr, ModeNo, ModeIdIndex);
 #endif
-          SiS_SetGroup5(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
+        SiS_SetGroup5(SiS_Pr, ModeNo, ModeIdIndex);
 
-          SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex, HwInfo);
+        SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex);
 
-          /* For 301BDH (Panel link initialization): */
-          if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
-             if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) {
-                if(!((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10)))) {
-                   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-                      SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,
-                                      RefreshRateTableIndex,HwInfo);
-                   }
-                 }
-             }
-             SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,
-                             RefreshRateTableIndex,HwInfo);
-          }
-        }
+        /* For 301BDH (Panel link initialization): */
+        if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
+
+           if(!((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10)))) {
+              if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+                 SiS_ModCRT1CRTC(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
+              }
+            }
+           SiS_SetCRT2ECLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
+        }
+      }
 
    } else {
 
-        SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex, HwInfo);
+      SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex);
 
-        if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
-          SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwInfo);
-       }
+      SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
 
-        SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwInfo);
+      SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
 
-       if(SiS_Pr->SiS_SetFlag & LowModeTests) {
-          if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
-             if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
-                if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+      if(SiS_Pr->SiS_SetFlag & LowModeTests) {
+        if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+           if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+              if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
 #ifdef SIS315H
-                   SiS_SetCH701xForLCD(SiS_Pr,HwInfo);
+                 SiS_SetCH701xForLCD(SiS_Pr);
 #endif
-                }
-             }
-             if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-                        SiS_SetCHTVReg(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
-             }
-          }
-       }
+              }
+           }
+           if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+              SiS_SetCHTVReg(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
+           }
+        }
+      }
 
    }
 
 #ifdef SIS300
-   if(HwInfo->jChipType < SIS_315H) {
+   if(SiS_Pr->ChipType < SIS_315H) {
       if(SiS_Pr->SiS_SetFlag & LowModeTests) {
         if(SiS_Pr->SiS_UseOEM) {
            if((SiS_Pr->SiS_UseROM) && (SiS_Pr->SiS_UseOEM == -1)) {
               if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
-                 SiS_OEM300Setting(SiS_Pr,HwInfo,ModeNo,ModeIdIndex,
-                                   RefreshRateTableIndex);
+                 SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
               }
            } else {
-                      SiS_OEM300Setting(SiS_Pr,HwInfo,ModeNo,ModeIdIndex,
-                                RefreshRateTableIndex);
+              SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
            }
         }
         if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-            if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
+           if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
               (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
-              SetOEMLCDData2(SiS_Pr, HwInfo, ModeNo, ModeIdIndex,RefreshRateTableIndex);
+              SetOEMLCDData2(SiS_Pr, ModeNo, ModeIdIndex,RefreshRateTableIndex);
            }
            SiS_DisplayOn(SiS_Pr);
          }
@@ -8995,21 +8807,21 @@ SiS_SetCRT2Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
 #endif
 
 #ifdef SIS315H
-   if(HwInfo->jChipType >= SIS_315H) {
+   if(SiS_Pr->ChipType >= SIS_315H) {
       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, RefreshRateTableIndex);
+        if(SiS_Pr->ChipType < SIS_661) {
+           SiS_FinalizeLCD(SiS_Pr, ModeNo, ModeIdIndex);
+           SiS_OEM310Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
         } else {
-           SiS_OEM661Setting(SiS_Pr, HwInfo, ModeNo, ModeIdIndex, RefreshRateTableIndex);
+           SiS_OEM661Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
         }
-         SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40);
+        SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40);
       }
    }
 #endif
 
    if(SiS_Pr->SiS_SetFlag & LowModeTests) {
-      SiS_EnableBridge(SiS_Pr, HwInfo);
+      SiS_EnableBridge(SiS_Pr);
    }
 
    SiS_DisplayOn(SiS_Pr);
@@ -9017,15 +8829,15 @@ SiS_SetCRT2Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
    if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
         /* Disable LCD panel when using TV */
-        SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFF,0x0C);
+        SiS_SetRegSR11ANDOR(SiS_Pr,0xFF,0x0C);
       } else {
         /* Disable TV when using LCD */
-        SiS_SetCH70xxANDOR(SiS_Pr,0x010E,0xF8);
+        SiS_SetCH70xxANDOR(SiS_Pr,0x0e,0x01,0xf8);
       }
    }
 
    if(SiS_Pr->SiS_SetFlag & LowModeTests) {
-      SiS_LockCRT2(SiS_Pr,HwInfo);
+      SiS_LockCRT2(SiS_Pr);
    }
 
    return TRUE;
@@ -9037,13 +8849,13 @@ SiS_SetCRT2Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
 /*********************************************/
 
 void
-SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_SiS30xBLOn(struct SiS_Private *SiS_Pr)
 {
   /* Switch on LCD backlight on SiS30xLV */
   SiS_DDC2Delay(SiS_Pr,0xff00);
   if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
-     SiS_WaitVBRetrace(SiS_Pr,HwInfo);
+     SiS_WaitVBRetrace(SiS_Pr);
   }
   if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x01)) {
      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
@@ -9051,12 +8863,11 @@ SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 }
 
 void
-SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_SiS30xBLOff(struct SiS_Private *SiS_Pr)
 {
   /* Switch off LCD backlight on SiS30xLV */
   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
-  SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
-  SiS_DDC2Delay(SiS_Pr,0xe000);
+  SiS_DDC2Delay(SiS_Pr,0xff00);
 }
 
 /*********************************************/
@@ -9064,7 +8875,7 @@ SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 /*********************************************/
 
 static void
-SiS_SetupDDCN(SiS_Private *SiS_Pr)
+SiS_SetupDDCN(struct SiS_Private *SiS_Pr)
 {
   SiS_Pr->SiS_DDC_NData = ~SiS_Pr->SiS_DDC_Data;
   SiS_Pr->SiS_DDC_NClk  = ~SiS_Pr->SiS_DDC_Clk;
@@ -9075,12 +8886,12 @@ SiS_SetupDDCN(SiS_Private *SiS_Pr)
 }
 
 #ifdef SIS300
-static UCHAR *
-SiS_SetTrumpBlockLoop(SiS_Private *SiS_Pr, UCHAR *dataptr)
+static unsigned char *
+SiS_SetTrumpBlockLoop(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
 {
   int i, j, num;
-  USHORT tempah,temp;
-  UCHAR *mydataptr;
+  unsigned short tempah,temp;
+  unsigned char *mydataptr;
 
   for(i=0; i<20; i++) {                                /* Do 20 attempts to write */
      mydataptr = dataptr;
@@ -9088,7 +8899,7 @@ SiS_SetTrumpBlockLoop(SiS_Private *SiS_Pr, UCHAR *dataptr)
      if(!num) return mydataptr;
      if(i) {
         SiS_SetStop(SiS_Pr);
-       SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT*2);
+       SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 2);
      }
      if(SiS_SetStart(SiS_Pr)) continue;                /* Set start condition */
      tempah = SiS_Pr->SiS_DDC_DeviceAddr;
@@ -9110,12 +8921,12 @@ SiS_SetTrumpBlockLoop(SiS_Private *SiS_Pr, UCHAR *dataptr)
 }
 
 static BOOLEAN
-SiS_SetTrumpionBlock(SiS_Private *SiS_Pr, UCHAR *dataptr)
+SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
 {
   SiS_Pr->SiS_DDC_DeviceAddr = 0xF0;           /* DAB (Device Address Byte) */
   SiS_Pr->SiS_DDC_Index = 0x11;                        /* Bit 0 = SC;  Bit 1 = SD */
-  SiS_Pr->SiS_DDC_Data  = 0x02;                /* Bitmask in IndexReg for Data */
-  SiS_Pr->SiS_DDC_Clk   = 0x01;                /* Bitmask in IndexReg for Clk */
+  SiS_Pr->SiS_DDC_Data  = 0x02;                        /* Bitmask in IndexReg for Data */
+  SiS_Pr->SiS_DDC_Clk   = 0x01;                        /* Bitmask in IndexReg for Clk */
   SiS_SetupDDCN(SiS_Pr);
 
   SiS_SetSwitchDDC2(SiS_Pr);
@@ -9124,9 +8935,11 @@ SiS_SetTrumpionBlock(SiS_Private *SiS_Pr, UCHAR *dataptr)
      dataptr = SiS_SetTrumpBlockLoop(SiS_Pr, dataptr);
      if(!dataptr) return FALSE;
   }
+#ifdef SIS_XORG_XF86
 #ifdef TWDEBUG
   xf86DrvMsg(0, X_INFO, "Trumpion block success\n");
 #endif
+#endif
   return TRUE;
 }
 #endif
@@ -9139,155 +8952,121 @@ SiS_SetTrumpionBlock(SiS_Private *SiS_Pr, UCHAR *dataptr)
  */
 
 static BOOLEAN
-SiS_SetChReg(SiS_Private *SiS_Pr, USHORT tempbx, USHORT myor)
+SiS_SetChReg(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val, unsigned short myor)
 {
-  USHORT tempah,temp,i;
+  unsigned short temp, i;
 
   for(i=0; i<20; i++) {                                /* Do 20 attempts to write */
      if(i) {
-        SiS_SetStop(SiS_Pr);
-       SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
-     }
-     if(SiS_SetStart(SiS_Pr)) continue;                /* Set start condition */
-     tempah = SiS_Pr->SiS_DDC_DeviceAddr;
-     temp = SiS_WriteDDC2Data(SiS_Pr,tempah);  /* Write DAB (S0=0=write) */
-     if(temp) continue;                                /*    (ERROR: no ack) */
-     tempah = tempbx & 0x00FF;                 /* Write RAB */
-     tempah |= myor;                            /* (700x: set bit 7, see datasheet) */
-     temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
-     if(temp) continue;                                /*    (ERROR: no ack) */
-     tempah = (tempbx & 0xFF00) >> 8;
-     temp = SiS_WriteDDC2Data(SiS_Pr,tempah);  /* Write data */
-     if(temp) continue;                                /*    (ERROR: no ack) */
-     if(SiS_SetStop(SiS_Pr)) continue;         /* Set stop condition */
+       SiS_SetStop(SiS_Pr);
+       SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4);
+     }
+     if(SiS_SetStart(SiS_Pr)) continue;                                        /* Set start condition */
+     temp = SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr);     /* Write DAB (S0=0=write) */
+     if(temp) continue;                                                        /*    (ERROR: no ack) */
+     temp = SiS_WriteDDC2Data(SiS_Pr, (reg | myor));                   /* Write RAB (700x: set bit 7, see datasheet) */
+     if(temp) continue;                                                        /*    (ERROR: no ack) */
+     temp = SiS_WriteDDC2Data(SiS_Pr, val);                            /* Write data */
+     if(temp) continue;                                                        /*    (ERROR: no ack) */
+     if(SiS_SetStop(SiS_Pr)) continue;                                 /* Set stop condition */
      SiS_Pr->SiS_ChrontelInit = 1;
      return TRUE;
   }
   return FALSE;
 }
 
-#if 0
-#ifdef SIS300
-/* Write Trumpion register */
-static void
-SiS_SetTrumpReg(SiS_Private *SiS_Pr, USHORT tempbx)
-{
-  SiS_Pr->SiS_DDC_DeviceAddr = 0xF0;           /* DAB (Device Address Byte) */
-  SiS_Pr->SiS_DDC_Index = 0x11;                        /* Bit 0 = SC;  Bit 1 = SD */
-  SiS_Pr->SiS_DDC_Data  = 0x02;                /* Bitmask in IndexReg for Data */
-  SiS_Pr->SiS_DDC_Clk   = 0x01;                /* Bitmask in IndexReg for Clk */
-  SiS_SetupDDCN(SiS_Pr);
-  SiS_SetChReg(SiS_Pr, tempbx, 0);
-}
-#endif
-#endif
-
 /* Write to Chrontel 700x */
-/* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
 void
-SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempbx)
+SiS_SetCH700x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
 {
   SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;           /* DAB (Device Address Byte) */
 
+  SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
+
   if(!(SiS_Pr->SiS_ChrontelInit)) {
      SiS_Pr->SiS_DDC_Index = 0x11;             /* Bit 0 = SC;  Bit 1 = SD */
-     SiS_Pr->SiS_DDC_Data  = 0x02;              /* Bitmask in IndexReg for Data */
-     SiS_Pr->SiS_DDC_Clk   = 0x01;              /* Bitmask in IndexReg for Clk */
+     SiS_Pr->SiS_DDC_Data  = 0x02;             /* Bitmask in IndexReg for Data */
+     SiS_Pr->SiS_DDC_Clk   = 0x01;             /* Bitmask in IndexReg for Clk */
      SiS_SetupDDCN(SiS_Pr);
   }
 
-  if( (!(SiS_SetChReg(SiS_Pr, tempbx, 0x80))) &&
+  if( (!(SiS_SetChReg(SiS_Pr, reg, val, 0x80))) &&
       (!(SiS_Pr->SiS_ChrontelInit)) ) {
-     SiS_Pr->SiS_DDC_Index = 0x0a;             /* Bit 7 = SC;  Bit 6 = SD */
-     SiS_Pr->SiS_DDC_Data  = 0x80;              /* Bitmask in IndexReg for Data */
-     SiS_Pr->SiS_DDC_Clk   = 0x40;              /* Bitmask in IndexReg for Clk */
+     SiS_Pr->SiS_DDC_Index = 0x0a;
+     SiS_Pr->SiS_DDC_Data  = 0x80;
+     SiS_Pr->SiS_DDC_Clk   = 0x40;
      SiS_SetupDDCN(SiS_Pr);
 
-     SiS_SetChReg(SiS_Pr, tempbx, 0x80);
+     SiS_SetChReg(SiS_Pr, reg, val, 0x80);
   }
 }
 
 /* Write to Chrontel 701x */
 /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
 void
-SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempbx)
+SiS_SetCH701x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
 {
   SiS_Pr->SiS_DDC_Index = 0x11;                        /* Bit 0 = SC;  Bit 1 = SD */
-  SiS_Pr->SiS_DDC_Data  = 0x08;                 /* Bitmask in IndexReg for Data */
-  SiS_Pr->SiS_DDC_Clk   = 0x04;                 /* Bitmask in IndexReg for Clk */
+  SiS_Pr->SiS_DDC_Data  = 0x08;                        /* Bitmask in IndexReg for Data */
+  SiS_Pr->SiS_DDC_Clk   = 0x04;                        /* Bitmask in IndexReg for Clk */
   SiS_SetupDDCN(SiS_Pr);
-  SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;           /* DAB (Device Address Byte) */
-  SiS_SetChReg(SiS_Pr, tempbx, 0);
+  SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;           /* DAB (Device Address Byte) */
+  SiS_SetChReg(SiS_Pr, reg, val, 0);
 }
 
-static void
-SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
+#ifdef SIS_LINUX_KERNEL
+static
+#endif
+void
+SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
 {
   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
-     SiS_SetCH700x(SiS_Pr,tempbx);
+     SiS_SetCH700x(SiS_Pr, reg, val);
   else
-     SiS_SetCH701x(SiS_Pr,tempbx);
+     SiS_SetCH701x(SiS_Pr, reg, val);
 }
 
-static USHORT
-SiS_GetChReg(SiS_Private *SiS_Pr, USHORT myor)
+static unsigned short
+SiS_GetChReg(struct SiS_Private *SiS_Pr, unsigned short myor)
 {
-  USHORT tempah,temp,i;
+  unsigned short tempah, temp, i;
 
   for(i=0; i<20; i++) {                                /* Do 20 attempts to read */
      if(i) {
-        SiS_SetStop(SiS_Pr);
-       SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
-     }
-     if(SiS_SetStart(SiS_Pr)) continue;                /* Set start condition */
-     tempah = SiS_Pr->SiS_DDC_DeviceAddr;
-     temp = SiS_WriteDDC2Data(SiS_Pr,tempah);  /* Write DAB (S0=0=write) */
-     if(temp) continue;                                /*        (ERROR: no ack) */
-     tempah = SiS_Pr->SiS_DDC_ReadAddr | myor; /* Write RAB (700x: | 0x80) */
-     temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
-     if(temp) continue;                                /*        (ERROR: no ack) */
-     if (SiS_SetStart(SiS_Pr)) continue;       /* Re-start */
-     tempah = SiS_Pr->SiS_DDC_DeviceAddr | 0x01;/* DAB | 0x01 = Read */
-     temp = SiS_WriteDDC2Data(SiS_Pr,tempah);  /* DAB (S0=1=read) */
-     if(temp) continue;                                /*        (ERROR: no ack) */
-     tempah = SiS_ReadDDC2Data(SiS_Pr,tempah); /* Read byte */
-     if(SiS_SetStop(SiS_Pr)) continue;         /* Stop condition */
+       SiS_SetStop(SiS_Pr);
+       SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4);
+     }
+     if(SiS_SetStart(SiS_Pr)) continue;                                        /* Set start condition */
+     temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr);      /* Write DAB (S0=0=write) */
+     if(temp) continue;                                                        /*        (ERROR: no ack) */
+     temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_ReadAddr | myor); /* Write RAB (700x: | 0x80) */
+     if(temp) continue;                                                        /*        (ERROR: no ack) */
+     if (SiS_SetStart(SiS_Pr)) continue;                               /* Re-start */
+     temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr | 0x01);/* DAB (S0=1=read) */
+     if(temp) continue;                                                        /*        (ERROR: no ack) */
+     tempah = SiS_ReadDDC2Data(SiS_Pr);                                        /* Read byte */
+     if(SiS_SetStop(SiS_Pr)) continue;                                 /* Stop condition */
      SiS_Pr->SiS_ChrontelInit = 1;
-     return(tempah);
+     return tempah;
   }
   return 0xFFFF;
 }
 
-#if 0
-#ifdef SIS300
-/* Read from Trumpion */
-static USHORT
-SiS_GetTrumpReg(SiS_Private *SiS_Pr, USHORT tempbx)
-{
-  SiS_Pr->SiS_DDC_DeviceAddr = 0xF0;   /* DAB */
-  SiS_Pr->SiS_DDC_Index = 0x11;                /* Bit 0 = SC;  Bit 1 = SD */
-  SiS_Pr->SiS_DDC_Data  = 0x02;         /* Bitmask in IndexReg for Data */
-  SiS_Pr->SiS_DDC_Clk   = 0x01;         /* Bitmask in IndexReg for Clk */
-  SiS_SetupDDCN(SiS_Pr);
-  SiS_Pr->SiS_DDC_ReadAddr = tempbx;
-  return(SiS_GetChReg(SiS_Pr,0));
-}
-#endif
-#endif
-
 /* Read from Chrontel 700x */
 /* Parameter is [Register no (S7-S0)] */
-USHORT
-SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempbx)
+unsigned short
+SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short tempbx)
 {
-  USHORT result;
+  unsigned short result;
 
   SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;           /* DAB */
 
+  SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
+
   if(!(SiS_Pr->SiS_ChrontelInit)) {
      SiS_Pr->SiS_DDC_Index = 0x11;             /* Bit 0 = SC;  Bit 1 = SD */
-     SiS_Pr->SiS_DDC_Data  = 0x02;              /* Bitmask in IndexReg for Data */
-     SiS_Pr->SiS_DDC_Clk   = 0x01;              /* Bitmask in IndexReg for Clk */
+     SiS_Pr->SiS_DDC_Data  = 0x02;             /* Bitmask in IndexReg for Data */
+     SiS_Pr->SiS_DDC_Clk   = 0x01;             /* Bitmask in IndexReg for Clk */
      SiS_SetupDDCN(SiS_Pr);
   }
 
@@ -9303,52 +9082,69 @@ SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempbx)
 
      result = SiS_GetChReg(SiS_Pr,0x80);
   }
-  return(result);
+  return result;
 }
 
 /* Read from Chrontel 701x */
 /* Parameter is [Register no (S7-S0)] */
-USHORT
-SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempbx)
+unsigned short
+SiS_GetCH701x(struct SiS_Private *SiS_Pr, unsigned short tempbx)
 {
   SiS_Pr->SiS_DDC_Index = 0x11;                        /* Bit 0 = SC;  Bit 1 = SD */
-  SiS_Pr->SiS_DDC_Data  = 0x08;                 /* Bitmask in IndexReg for Data */
-  SiS_Pr->SiS_DDC_Clk   = 0x04;                 /* Bitmask in IndexReg for Clk */
+  SiS_Pr->SiS_DDC_Data  = 0x08;                        /* Bitmask in IndexReg for Data */
+  SiS_Pr->SiS_DDC_Clk   = 0x04;                        /* Bitmask in IndexReg for Clk */
   SiS_SetupDDCN(SiS_Pr);
   SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;           /* DAB */
 
   SiS_Pr->SiS_DDC_ReadAddr = tempbx;
 
-  return(SiS_GetChReg(SiS_Pr,0));
+  return SiS_GetChReg(SiS_Pr,0);
 }
 
 /* Read from Chrontel 70xx */
 /* Parameter is [Register no (S7-S0)] */
-static USHORT
-SiS_GetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
+#ifdef SIS_LINUX_KERNEL
+static
+#endif
+unsigned short
+SiS_GetCH70xx(struct SiS_Private *SiS_Pr, unsigned short tempbx)
 {
   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
-     return(SiS_GetCH700x(SiS_Pr, tempbx));
+     return SiS_GetCH700x(SiS_Pr, tempbx);
   else
-     return(SiS_GetCH701x(SiS_Pr, tempbx));
+     return SiS_GetCH701x(SiS_Pr, tempbx);
+}
+
+void
+SiS_SetCH70xxANDOR(struct SiS_Private *SiS_Pr, unsigned short reg,
+               unsigned char myor, unsigned short myand)
+{
+  unsigned short tempbl;
+
+  tempbl = (SiS_GetCH70xx(SiS_Pr, (reg & 0xFF)) & myand) | myor;
+  SiS_SetCH70xx(SiS_Pr, reg, tempbl);
 }
 
 /* Our own DDC functions */
-static USHORT
-SiS_InitDDCRegs(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
-                USHORT adaptnum, USHORT DDCdatatype, BOOLEAN checkcr32)
+#ifndef SIS_XORG_XF86
+static
+#endif
+unsigned short
+SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
+                unsigned short adaptnum, unsigned short DDCdatatype, BOOLEAN checkcr32,
+               unsigned int VBFlags2)
 {
      unsigned char ddcdtype[] = { 0xa0, 0xa0, 0xa0, 0xa2, 0xa6 };
      unsigned char flag, cr32;
-     USHORT        temp = 0, myadaptnum = adaptnum;
+     unsigned short        temp = 0, myadaptnum = adaptnum;
 
      if(adaptnum != 0) {
-        if(!(VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) return 0xFFFF;
-       if((VBFlags & VB_30xBDH) && (adaptnum == 1)) return 0xFFFF;
-     } 
-     
+       if(!(VBFlags2 & VB2_SISTMDSBRIDGE)) return 0xFFFF;
+       if((VBFlags2 & VB2_30xBDH) && (adaptnum == 1)) return 0xFFFF;
+     }
+
      /* adapternum for SiS bridges: 0 = CRT1, 1 = LCD, 2 = VGA2 */
-     
+
      SiS_Pr->SiS_ChrontelInit = 0;   /* force re-detection! */
 
      SiS_Pr->SiS_DDC_SecAddr = 0;
@@ -9360,7 +9156,7 @@ SiS_InitDDCRegs(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
      cr32 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x32);
 
 #if 0
-     if(VBFlags & VB_SISBRIDGE) {
+     if(VBFlags2 & VB2_SISBRIDGE) {
        if(myadaptnum == 0) {
           if(!(cr32 & 0x20)) {
              myadaptnum = 2;
@@ -9376,20 +9172,20 @@ SiS_InitDDCRegs(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
 #endif
 
      if(VGAEngine == SIS_300_VGA) {            /* 300 series */
-       
+
         if(myadaptnum != 0) {
           flag = 0;
-          if(VBFlags & VB_SISBRIDGE) {
+          if(VBFlags2 & VB2_SISBRIDGE) {
              SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
               SiS_Pr->SiS_DDC_Index = 0x0f;
           }
         }
 
-       if(!(VBFlags & VB_301)) {
+       if(!(VBFlags2 & VB2_301)) {
           if((cr32 & 0x80) && (checkcr32)) {
               if(myadaptnum >= 1) {
                 if(!(cr32 & 0x08)) {
-                    myadaptnum = 1;
+                    myadaptnum = 1;
                     if(!(cr32 & 0x10)) return 0xFFFF;
                  }
              }
@@ -9401,17 +9197,17 @@ SiS_InitDDCRegs(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
 
      } else {                                          /* 315/330 series */
 
-       /* here we simplify: 0 = CRT1, 1 = CRT2 (VGA, LCD) */
+       /* here we simplify: 0 = CRT1, 1 = CRT2 (VGA, LCD) */
 
-       if(VBFlags & VB_SISBRIDGE) {
+       if(VBFlags2 & VB2_SISBRIDGE) {
           if(myadaptnum == 2) {
              myadaptnum = 1;
-           }
+          }
        }
 
         if(myadaptnum == 1) {
-          flag = 0;
-          if(VBFlags & VB_SISBRIDGE) {
+          flag = 0;
+          if(VBFlags2 & VB2_SISBRIDGE) {
              SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
               SiS_Pr->SiS_DDC_Index = 0x0f;
           }
@@ -9429,93 +9225,96 @@ SiS_InitDDCRegs(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
         temp = myadaptnum;
         if(myadaptnum == 1) {
            temp = 0;
-          if(VBFlags & VB_LVDS) flag = 0xff;
+          if(VBFlags2 & VB2_LVDS) flag = 0xff;
         }
 
        if(flag) temp = 0;
     }
-    
+
     SiS_Pr->SiS_DDC_Data = 0x02 << temp;
     SiS_Pr->SiS_DDC_Clk  = 0x01 << temp;
 
     SiS_SetupDDCN(SiS_Pr);
 
+#ifdef SIS_XORG_XF86
 #ifdef TWDEBUG
     xf86DrvMsg(0, X_INFO, "DDC Port %x Index %x Shift %d\n",
                SiS_Pr->SiS_DDC_Port, SiS_Pr->SiS_DDC_Index, temp);
 #endif
-    
+#endif
     return 0;
 }
 
-static USHORT
-SiS_WriteDABDDC(SiS_Private *SiS_Pr)
+static unsigned short
+SiS_WriteDABDDC(struct SiS_Private *SiS_Pr)
 {
    if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
    if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr)) {
-       return 0xFFFF;
+      return 0xFFFF;
    }
    if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_SecAddr)) {
-       return 0xFFFF;
+      return 0xFFFF;
    }
-   return(0);
+   return 0;
 }
 
-static USHORT
-SiS_PrepareReadDDC(SiS_Private *SiS_Pr)
+static unsigned short
+SiS_PrepareReadDDC(struct SiS_Private *SiS_Pr)
 {
    if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
    if(SiS_WriteDDC2Data(SiS_Pr, (SiS_Pr->SiS_DDC_DeviceAddr | 0x01))) {
-       return 0xFFFF;
+      return 0xFFFF;
    }
-   return(0);
+   return 0;
 }
 
-static USHORT
-SiS_PrepareDDC(SiS_Private *SiS_Pr)
+static unsigned short
+SiS_PrepareDDC(struct SiS_Private *SiS_Pr)
 {
    if(SiS_WriteDABDDC(SiS_Pr)) SiS_WriteDABDDC(SiS_Pr);
-   if(SiS_PrepareReadDDC(SiS_Pr)) return(SiS_PrepareReadDDC(SiS_Pr));
-   return(0);
+   if(SiS_PrepareReadDDC(SiS_Pr)) return (SiS_PrepareReadDDC(SiS_Pr));
+   return 0;
 }
 
 static void
-SiS_SendACK(SiS_Private *SiS_Pr, USHORT yesno)
+SiS_SendACK(struct SiS_Private *SiS_Pr, unsigned short yesno)
 {
    SiS_SetSCLKLow(SiS_Pr);
    if(yesno) {
       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
-                     SiS_Pr->SiS_DDC_Index,
-                      SiS_Pr->SiS_DDC_NData,
+                     SiS_Pr->SiS_DDC_Index,
+                     SiS_Pr->SiS_DDC_NData,
                      SiS_Pr->SiS_DDC_Data);
    } else {
       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
-                     SiS_Pr->SiS_DDC_Index,
-                      SiS_Pr->SiS_DDC_NData,
+                     SiS_Pr->SiS_DDC_Index,
+                     SiS_Pr->SiS_DDC_NData,
                      0);
    }
    SiS_SetSCLKHigh(SiS_Pr);
 }
 
-static USHORT
-SiS_DoProbeDDC(SiS_Private *SiS_Pr)
+static unsigned short
+SiS_DoProbeDDC(struct SiS_Private *SiS_Pr)
 {
     unsigned char mask, value;
-    USHORT  temp, ret=0;
+    unsigned short  temp, ret=0;
     BOOLEAN failed = FALSE;
 
     SiS_SetSwitchDDC2(SiS_Pr);
     if(SiS_PrepareDDC(SiS_Pr)) {
          SiS_SetStop(SiS_Pr);
+#ifdef SIS_XORG_XF86
 #ifdef TWDEBUG
          xf86DrvMsg(0, X_INFO, "Probe: Prepare failed\n");
 #endif
-         return(0xFFFF);
+#endif
+         return 0xFFFF;
     }
     mask = 0xf0;
     value = 0x20;
     if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
-       temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
+       temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
        SiS_SendACK(SiS_Pr, 0);
        if(temp == 0) {
            mask = 0xff;
@@ -9523,34 +9322,41 @@ SiS_DoProbeDDC(SiS_Private *SiS_Pr)
        } else {
            failed = TRUE;
           ret = 0xFFFF;
+#ifdef SIS_XORG_XF86
 #ifdef TWDEBUG
            xf86DrvMsg(0, X_INFO, "Probe: Read 1 failed\n");
 #endif
+#endif
        }
     }
     if(failed == FALSE) {
-       temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
+       temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
        SiS_SendACK(SiS_Pr, 1);
        temp &= mask;
        if(temp == value) ret = 0;
        else {
           ret = 0xFFFF;
+#ifdef SIS_XORG_XF86
 #ifdef TWDEBUG
           xf86DrvMsg(0, X_INFO, "Probe: Read 2 failed\n");
 #endif
+#endif
           if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
              if(temp == 0x30) ret = 0;
           }
        }
     }
     SiS_SetStop(SiS_Pr);
-    return(ret);
+    return ret;
 }
 
-static USHORT
-SiS_ProbeDDC(SiS_Private *SiS_Pr)
+#ifndef SIS_XORG_XF86
+static
+#endif
+unsigned short
+SiS_ProbeDDC(struct SiS_Private *SiS_Pr)
 {
-   USHORT flag;
+   unsigned short flag;
 
    flag = 0x180;
    SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
@@ -9560,16 +9366,19 @@ SiS_ProbeDDC(SiS_Private *SiS_Pr)
    SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;
    if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x10;
    if(!(flag & 0x1a)) flag = 0;
-   return(flag);
+   return flag;
 }
 
-static USHORT
-SiS_ReadDDC(SiS_Private *SiS_Pr, USHORT DDCdatatype, unsigned char *buffer)
+#ifndef SIS_XORG_XF86
+static
+#endif
+unsigned short
+SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype, unsigned char *buffer)
 {
-   USHORT flag, length, i;
+   unsigned short flag, length, i;
    unsigned char chksum,gotcha;
 
-   if(DDCdatatype > 4) return 0xFFFF;  
+   if(DDCdatatype > 4) return 0xFFFF;
 
    flag = 0;
    SiS_SetSwitchDDC2(SiS_Pr);
@@ -9579,21 +9388,21 @@ SiS_ReadDDC(SiS_Private *SiS_Pr, USHORT DDCdatatype, unsigned char *buffer)
       chksum = 0;
       gotcha = 0;
       for(i=0; i<length; i++) {
-         buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
+        buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
         chksum += buffer[i];
         gotcha |= buffer[i];
         SiS_SendACK(SiS_Pr, 0);
       }
-      buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
+      buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
       chksum += buffer[i];
       SiS_SendACK(SiS_Pr, 1);
-      if(gotcha) flag = (USHORT)chksum;
+      if(gotcha) flag = (unsigned short)chksum;
       else flag = 0xFFFF;
    } else {
       flag = 0xFFFF;
    }
    SiS_SetStop(SiS_Pr);
-   return(flag);
+   return flag;
 }
 
 /* Our private DDC functions
@@ -9617,17 +9426,25 @@ SiS_ReadDDC(SiS_Private *SiS_Pr, USHORT DDCdatatype, unsigned char *buffer)
        if DDCdatatype = 0:  Returns supported DDC modes
 
  */
-USHORT
-SiS_HandleDDC(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
-              USHORT adaptnum, USHORT DDCdatatype, unsigned char *buffer)
+unsigned short
+SiS_HandleDDC(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
+              unsigned short adaptnum, unsigned short DDCdatatype, unsigned char *buffer,
+             unsigned int VBFlags2)
 {
-   unsigned char sr1f,cr17=1;
-   USHORT result;
+   unsigned char  sr1f, cr17=1;
+   unsigned short result;
 
-   if(adaptnum > 2) return 0xFFFF;
-   if(DDCdatatype > 4) return 0xFFFF;
-   if((!(VBFlags & VB_VIDEOBRIDGE)) && (adaptnum > 0)) return 0xFFFF;
-   if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, FALSE) == 0xFFFF) return 0xFFFF;
+   if(adaptnum > 2)
+      return 0xFFFF;
+
+   if(DDCdatatype > 4)
+      return 0xFFFF;
+
+   if((!(VBFlags2 & VB2_VIDEOBRIDGE)) && (adaptnum > 0))
+      return 0xFFFF;
+
+   if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, FALSE, VBFlags2) == 0xFFFF)
+      return 0xFFFF;
 
    sr1f = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f);
    SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1f,0x3f,0x04);
@@ -9656,10 +9473,12 @@ SiS_HandleDDC(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
            (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;
+           if(!SiS_Pr->DDCPortMixup) {
+              if(adaptnum == 1) {
+                 if(!(buffer[0x14] & 0x80)) result = 0xFFFE;
+              } else {
+                 if(buffer[0x14] & 0x80)    result = 0xFFFE;
+              }
            }
         }
       }
@@ -9671,832 +9490,10 @@ SiS_HandleDDC(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
    return result;
 }
 
-#ifdef LINUX_XF86
-
-static BOOLEAN
-checkedid1(unsigned char *buffer)
-{
-   /* Check header */
-   if((buffer[0] != 0x00) ||
-      (buffer[1] != 0xff) ||
-      (buffer[2] != 0xff) ||
-      (buffer[3] != 0xff) ||
-      (buffer[4] != 0xff) ||
-      (buffer[5] != 0xff) ||
-      (buffer[6] != 0xff) ||
-      (buffer[7] != 0x00))
-      return FALSE;
-
-   /* Check EDID version and revision */
-   if((buffer[0x12] != 1) || (buffer[0x13] > 4)) return FALSE;
-
-   /* Check week of manufacture for sanity */
-   if(buffer[0x10] > 53) return FALSE;
-
-   /* Check year of manufacture for sanity */
-   if(buffer[0x11] > 40) return FALSE;
-
-   return TRUE;
-}
-
-static BOOLEAN
-checkedid2(unsigned char *buffer)
-{
-   USHORT year = buffer[6] | (buffer[7] << 8);
-
-   /* Check EDID version */
-   if((buffer[0] & 0xf0) != 0x20) return FALSE;
-
-   /* Check week of manufacture for sanity */
-   if(buffer[5] > 53) return FALSE;
-
-   /* Check year of manufacture for sanity */
-   if((year != 0) && ((year < 1990) || (year > 2030))) return FALSE;
-
-   return TRUE;
-}
-
-/* Sense the LCD parameters (CR36, CR37) via DDC */
-/* SiS30x(B) only */
-USHORT
-SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS)
-{
-   USHORT DDCdatatype, paneltype, flag, xres=0, yres=0;
-   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];
-
-   for(i=0; i<7; i++) SiS_Pr->CP_DataValid[i] = FALSE;
-   SiS_Pr->CP_HaveCustomData = FALSE;
-   SiS_Pr->CP_MaxX = SiS_Pr->CP_MaxY = SiS_Pr->CP_MaxClock = 0;
-   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;
-  
-   if(SiS_InitDDCRegs(SiS_Pr, pSiS->VBFlags, pSiS->VGAEngine, 1, 0, FALSE) == 0xFFFF) return 0;
-   
-   SiS_Pr->SiS_DDC_SecAddr = 0x00;
-   
-   /* Probe supported DA's */
-   flag = SiS_ProbeDDC(SiS_Pr);
-#ifdef TWDEBUG
-   xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO,
-       "CRT2 DDC capabilities 0x%x\n", flag);
-#endif 
-   if(flag & 0x10) {
-      SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;       /* EDID V2 (FP) */
-      DDCdatatype = 4;
-   } else if(flag & 0x08) {
-      SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;       /* EDID V2 (P&D-D Monitor) */
-      DDCdatatype = 3;
-   } else if(flag & 0x02) {
-      SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;       /* EDID V1 */
-      DDCdatatype = 1;
-   } else return 0;                            /* no DDC support (or no device attached) */
-   
-   /* Read the entire EDID */
-   retry = 2;
-   do {
-      if(SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer)) {
-         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
-               "CRT2: DDC read failed (attempt %d), %s\n",
-               (3-retry), (retry == 1) ? "giving up" : "retrying");
-        retry--;
-        if(retry == 0) return 0xFFFF;
-      } else break;
-   } while(1);
-
-#ifdef TWDEBUG
-   for(i=0; i<256; i+=16) {
-       xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
-               "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
-       buffer[i],    buffer[i+1], buffer[i+2], buffer[i+3],
-       buffer[i+4],  buffer[i+5], buffer[i+6], buffer[i+7],
-       buffer[i+8],  buffer[i+9], buffer[i+10], buffer[i+11],
-       buffer[i+12], buffer[i+13], buffer[i+14], buffer[i+15]);
-   }
-#endif   
-   
-   /* Analyze EDID and retrieve LCD panel information */
-   paneltype = 0;
-   switch(DDCdatatype) {
-   case 1:                                                     /* Analyze EDID V1 */
-      /* Catch a few clear cases: */
-      if(!(checkedid1(buffer))) {
-         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
-               "LCD sense: EDID corrupt\n");
-        return 0;
-      }
-
-      if(!(buffer[0x14] & 0x80)) {
-         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
-               "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,
-               "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]);
-      }
-
-      /* Now analyze the first Detailed Timing Block and see
-       * if the preferred timing mode is stored there. If so,
-       * check if this is a standard panel for which we already
-       * know the timing.
-       */
-
-      paneltype = Panel_Custom;
-      checkexpand = FALSE;
-
-      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) {
-
-         USHORT pclk = (buffer[0x36] | (buffer[0x37] << 8));
-        USHORT phb  = (buffer[0x39] | ((buffer[0x3a] & 0x0f) << 8));
-        USHORT pvb  = (buffer[0x3c] | ((buffer[0x3d] & 0x0f) << 8));
-
-        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 */
-            case 800:
-               if(yres == 600) {
-                  paneltype = Panel_800x600;
-                  checkexpand = TRUE;
-               }
-               break;
-#endif
-            case 1024:
-               if(yres == 768) {
-                  paneltype = Panel_1024x768;
-                  checkexpand = TRUE;
-               }
-               break;
-           case 1280:
-               if(yres == 1024) {
-                  paneltype = Panel_1280x1024;
-                  checkexpand = TRUE;
-               } else if(yres == 960) {
-                  if(pSiS->VGAEngine == SIS_300_VGA) {
-                     paneltype = Panel300_1280x960;
-                  } else {
-                     paneltype = Panel310_1280x960;
-                  }
-               } else if(yres == 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) {
-                  if(yres == 1050) {
-                     paneltype = Panel310_1400x1050;
-                     checkexpand = TRUE;
-                  }
-               }
-               break;
-           case 1600:
-               if(pSiS->VGAEngine == SIS_315_VGA) {
-                  if(pSiS->VBFlags & VB_301C) {
-                     if(yres == 1200) {
-                        paneltype = Panel310_1600x1200;
-                        checkexpand = TRUE;
-                     }
-                  }
-               }
-               break;
-         }
-
-        /* 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) {
-
-        int i, temp, base = 0x36;
-        unsigned long estpack;
-        const unsigned short estx[] = {
-               720, 720, 640, 640, 640, 640, 800, 800,
-               800, 800, 832,1024,1024,1024,1024,1280,
-               1152
-        };
-        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;
-
-        /* Find the maximum resolution */
-
-        /* 1. From Established timings */
-        estpack = (buffer[0x23] << 9) | (buffer[0x24] << 1) | ((buffer[0x25] >> 7) & 0x01);
-        for(i=16; i>=0; i--) {
-            if(estpack & (1 << i)) {
-               if(estx[16 - i] > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = estx[16 - i];
-               if(esty[16 - i] > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = esty[16 - i];
-               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)) {
-              temp = (buffer[i] + 31) * 8;
-              if(temp > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = temp;
-              switch((buffer[i+1] & 0xc0) >> 6) {
-              case 0x03: temp = temp * 9 / 16; break;
-              case 0x02: temp = temp * 4 / 5;  break;
-              case 0x01: temp = temp * 3 / 4;  break;
-              }
-              if(temp > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = temp;
-           }
-        }
-
-        /* Now extract the Detailed Timings and convert them into modes */
-
-         for(i = 0; i < 4; i++, base += 18) {
-
-           /* Is this a detailed timing block or a monitor descriptor? */
-           if(buffer[base] || buffer[base+1] || buffer[base+2]) {
-
-              xres = buffer[base+2] | ((buffer[base+4] & 0xf0) << 4);
-               yres = buffer[base+5] | ((buffer[base+7] & 0xf0) << 4);
-
-              SiS_Pr->CP_HDisplay[i] = xres;
-              SiS_Pr->CP_HSyncStart[i] = xres + (buffer[base+8] | ((buffer[base+11] & 0xc0) << 2));
-               SiS_Pr->CP_HSyncEnd[i]   = SiS_Pr->CP_HSyncStart[i] + (buffer[base+9] | ((buffer[base+11] & 0x30) << 4));
-              SiS_Pr->CP_HTotal[i] = xres + (buffer[base+3] | ((buffer[base+4] & 0x0f) << 8));
-              SiS_Pr->CP_HBlankStart[i] = xres + 1;
-              SiS_Pr->CP_HBlankEnd[i] = SiS_Pr->CP_HTotal[i];
-
-              SiS_Pr->CP_VDisplay[i] = yres;
-               SiS_Pr->CP_VSyncStart[i] = yres + (((buffer[base+10] & 0xf0) >> 4) | ((buffer[base+11] & 0x0c) << 2));
-               SiS_Pr->CP_VSyncEnd[i] = SiS_Pr->CP_VSyncStart[i] + ((buffer[base+10] & 0x0f) | ((buffer[base+11] & 0x03) << 4));
-              SiS_Pr->CP_VTotal[i] = yres + (buffer[base+6] | ((buffer[base+7] & 0x0f) << 8));
-              SiS_Pr->CP_VBlankStart[i] = yres + 1;
-              SiS_Pr->CP_VBlankEnd[i] = SiS_Pr->CP_VTotal[i];
-
-              SiS_Pr->CP_Clock[i] = (buffer[base] | (buffer[base+1] << 8)) * 10;
-
-              SiS_Pr->CP_DataValid[i] = TRUE;
-
-              /* Sort out invalid timings, interlace and too high clocks */
-              if((SiS_Pr->CP_HDisplay[i] & 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) || (SiS_Pr->CP_VDisplay[i] > 1024) ||
-                    (SiS_Pr->CP_HDisplay[i] > 1600))))                                   ||
-                 (buffer[base+17] & 0x80)) {
-
-                 SiS_Pr->CP_DataValid[i] = FALSE;
-
-              } else {
-
-                 SiS_Pr->CP_HaveCustomData = TRUE;
-
-                 if(xres > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = xres;
-                 if(yres > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = yres;
-                 if(SiS_Pr->CP_Clock[i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = SiS_Pr->CP_Clock[i];
-
-                 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;
-                 }
-
-                 /* Extract the sync polarisation information. This only works
-                  * if the Flags indicate a digital separate output.
-                  */
-                 if((buffer[base+17] & 0x18) == 0x18) {
-                    SiS_Pr->CP_HSync_P[i] = (buffer[base+17] & 0x02) ? TRUE : FALSE;
-                    SiS_Pr->CP_VSync_P[i] = (buffer[base+17] & 0x04) ? TRUE : FALSE;
-                    SiS_Pr->CP_SyncValid[i] = TRUE;
-                    if((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(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) {
-         /* If any of the Established low-res modes is supported, the
-         * panel can scale automatically. For 800x600 panels, we only 
-         * check the even lower ones.
-         */
-        if(paneltype == Panel_800x600) {
-           if(buffer[0x23] & 0xfc) cr37 |= 0x10;
-        } else {
-            if(buffer[0x23])       cr37 |= 0x10;
-        }
-      }
-       
-      break;
-      
-   case 3:                                                     /* Analyze EDID V2 */
-   case 4:
-      index = 0;
-
-      if(!(checkedid2(buffer))) {
-         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
-               "LCD sense: EDID corrupt\n");
-        return 0;
-      }
-
-      if((buffer[0x41] & 0x0f) == 0x03) {
-         index = 0x42 + 3;
-         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
-               "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,
-               "LCD sense: Display supports TMDS input on secondary interface\n");
-      } else {
-         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
-               "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 = 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:
-            if(yres == 600) {
-               paneltype = Panel_800x600;
-               checkexpand = TRUE;
-            }
-            break;
-#endif
-         case 1024:
-            if(yres == 768) {
-               paneltype = Panel_1024x768;
-               checkexpand = TRUE;
-            }
-            break;
-        case 1280:
-            if(yres == 960) {
-               if(pSiS->VGAEngine == SIS_315_VGA) {
-                  paneltype = Panel310_1280x960;
-               } else {
-                  paneltype = Panel300_1280x960;
-               }
-            } else if(yres == 1024) {
-               paneltype = Panel_1280x1024;
-               checkexpand = TRUE;
-            }
-            /* 1280x768 treated as custom here */
-            break;
-        case 1400:
-            if(pSiS->VGAEngine == SIS_315_VGA) {
-               if(yres == 1050) {
-                  paneltype = Panel310_1400x1050;
-                  checkexpand = TRUE;
-               }
-            }
-            break;
-        case 1600:
-            if(pSiS->VGAEngine == SIS_315_VGA) {
-               if(pSiS->VBFlags & VB_301C) {
-                  if(yres == 1200) {
-                     paneltype = Panel310_1600x1200;
-                     checkexpand = TRUE;
-                  }
-               }
-            }
-            break;
-      }
-
-      /* Determine if RGB18 or RGB24 */
-      if(index) {
-         if((buffer[index] == 0x20) || (buffer[index] == 0x34)) {
-           cr37 |= 0x01;
-        }
-      }
-
-      if(checkexpand) {
-         /* TODO - for now, we let the panel scale */
-        cr37 |= 0x10;
-      }
-
-      /* Now seek 4-Byte Timing codes and extract sync pol info */
-      index = 0x80;
-      if(buffer[0x7e] & 0x20) {                            /* skip Luminance Table (if provided) */
-         lumsize = buffer[0x80] & 0x1f;
-        if(buffer[0x80] & 0x80) lumsize *= 3;
-        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) {
-         myindex = index;
-        seekcode = (xres - 256) / 16;
-        for(i=0; i<numcodes; i++) {
-           if(buffer[myindex] == seekcode) break;
-           myindex += 4;
-        }
-        if(buffer[myindex] == seekcode) {
-           cr37 |= ((((buffer[myindex + 1] & 0x0c) ^ 0x0c) << 4) | 0x20);
-           havesync = TRUE;
-        } else {
-           xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
-               "LCD sense: Unable to retrieve Sync polarity information\n");
-        }
-      } else {
-         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
-            "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 */
-      if(paneltype == Panel_Custom) {
-
-         SiS_Pr->CP_Supports64048075 = TRUE;
-
-         index += (numcodes * 4);
-        numcodes = buffer[0x7f] & 0x07;
-        for(i=0; i<numcodes; i++, index += 18) {
-           xres = buffer[index+2] | ((buffer[index+4] & 0xf0) << 4);
-            yres = buffer[index+5] | ((buffer[index+7] & 0xf0) << 4);
-
-           SiS_Pr->CP_HDisplay[i] = xres;
-           SiS_Pr->CP_HSyncStart[i] = xres + (buffer[index+8] | ((buffer[index+11] & 0xc0) << 2));
-            SiS_Pr->CP_HSyncEnd[i] = SiS_Pr->CP_HSyncStart[i] + (buffer[index+9] | ((buffer[index+11] & 0x30) << 4));
-           SiS_Pr->CP_HTotal[i] = xres + (buffer[index+3] | ((buffer[index+4] & 0x0f) << 8));
-           SiS_Pr->CP_HBlankStart[i] = xres + 1;
-           SiS_Pr->CP_HBlankEnd[i] = SiS_Pr->CP_HTotal[i];
-
-           SiS_Pr->CP_VDisplay[i] = yres;
-            SiS_Pr->CP_VSyncStart[i] = yres + (((buffer[index+10] & 0xf0) >> 4) | ((buffer[index+11] & 0x0c) << 2));
-            SiS_Pr->CP_VSyncEnd[i] = SiS_Pr->CP_VSyncStart[i] + ((buffer[index+10] & 0x0f) | ((buffer[index+11] & 0x03) << 4));
-           SiS_Pr->CP_VTotal[i] = yres + (buffer[index+6] | ((buffer[index+7] & 0x0f) << 8));
-           SiS_Pr->CP_VBlankStart[i] = yres + 1;
-           SiS_Pr->CP_VBlankEnd[i] = SiS_Pr->CP_VTotal[i];
-
-           SiS_Pr->CP_Clock[i] = (buffer[index] | (buffer[index+1] << 8)) * 10;
-
-           SiS_Pr->CP_DataValid[i] = TRUE;
-
-           if((SiS_Pr->CP_HDisplay[i] & 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) || (SiS_Pr->CP_VDisplay[i] > 1024))))  ||
-              (buffer[index + 17] & 0x80)) {
-
-              SiS_Pr->CP_DataValid[i] = FALSE;
-
-           } else {
-
-              SiS_Pr->CP_HaveCustomData = TRUE;
-
-              if(SiS_Pr->CP_Clock[i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = SiS_Pr->CP_Clock[i];
-
-              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;
-
-           }
-        }
-
-        cr37 |= 0x10;
-
-      }
-
-      break;
-
-   }
-
-   /* 1280x960 panels are always RGB24, unable to scale and use
-    * high active sync polarity
-    */
-   if(pSiS->VGAEngine == SIS_315_VGA) {
-      if(paneltype == Panel310_1280x960) cr37 &= 0x0e;
-   } else {
-      if(paneltype == Panel300_1280x960) cr37 &= 0x0e;
-   }
-
-   for(i = 0; i < 7; i++) {
-      if(SiS_Pr->CP_DataValid[i]) {
-         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
-            "Non-standard LCD/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],
-           SiS_Pr->CP_HSyncEnd[i], SiS_Pr->CP_HTotal[i]);
-         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
-            "   VDisplay %d VSync %d VSyncEnd %d VTotal %d\n",
-            SiS_Pr->CP_VDisplay[i], SiS_Pr->CP_VSyncStart[i],
-           SiS_Pr->CP_VSyncEnd[i], SiS_Pr->CP_VTotal[i]);
-         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
-           "   Pixel clock: %3.3fMhz\n", (float)SiS_Pr->CP_Clock[i] / 1000);
-        xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO,
-           "   To use this, add \"%dx%d\" to the list of Modes in the Screen section\n",
-           SiS_Pr->CP_HDisplay[i],
-           SiS_Pr->CP_VDisplay[i]);
-      }
-   }
-
-   if(paneltype) {
-       if(!SiS_Pr->CP_PreferredX) SiS_Pr->CP_PreferredX = SiS_Pr->CP_MaxX;
-       if(!SiS_Pr->CP_PreferredY) SiS_Pr->CP_PreferredY = SiS_Pr->CP_MaxY;
-       SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x32,0x08);
-       SiS_SetReg(SiS_Pr->SiS_P3d4,0x36,paneltype);
-       cr37 &= 0xf1;
-       SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x37,0x0c,cr37);
-       SiS_Pr->PanelSelfDetected = TRUE;
-#ifdef TWDEBUG
-       xf86DrvMsgVerb(pSiS->pScrn->scrnIndex, X_PROBED, 3, 
-                  "LCD sense: [DDC LCD results: 0x%02x, 0x%02x]\n", paneltype, cr37);
-#endif 
-   } else {
-       SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x32,~0x08);
-       SiS_SetReg(SiS_Pr->SiS_P3d4,0x36,0x00);
-   }
-   return 0;
-}
-   
-USHORT
-SiS_SenseVGA2DDC(SiS_Private *SiS_Pr, SISPtr pSiS)
-{
-   USHORT DDCdatatype,flag;
-   BOOLEAN foundcrt = FALSE;
-   int retry;
-   unsigned char buffer[256];
-
-   if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) return 0;
-
-   if(SiS_InitDDCRegs(SiS_Pr, pSiS->VBFlags, pSiS->VGAEngine, 2, 0, FALSE) == 0xFFFF) return 0;
-   
-   SiS_Pr->SiS_DDC_SecAddr = 0x00;
-   
-   /* Probe supported DA's */
-   flag = SiS_ProbeDDC(SiS_Pr);
-   if(flag & 0x10) {
-      SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;       /* EDID V2 (FP) */
-      DDCdatatype = 4;
-   } else if(flag & 0x08) {
-      SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;       /* EDID V2 (P&D-D Monitor) */
-      DDCdatatype = 3;
-   } else if(flag & 0x02) {
-      SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;       /* EDID V1 */
-      DDCdatatype = 1;
-   } else {
-       xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
-               "VGA2 sense: Do DDC answer\n");
-       return 0;                               /* no DDC support (or no device attached) */
-   }
-
-   /* Read the entire EDID */
-   retry = 2;
-   do {
-      if(SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer)) {
-         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
-               "VGA2 sense: DDC read failed (attempt %d), %s\n",
-               (3-retry), (retry == 1) ? "giving up" : "retrying");
-        retry--;
-        if(retry == 0) return 0xFFFF;
-      } else break;
-   } while(1);
-
-   /* Analyze EDID. We don't have many chances to
-    * distinguish a flat panel from a CRT...
-    */
-   switch(DDCdatatype) {
-   case 1:
-      if(!(checkedid1(buffer))) {
-          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_ERROR,
-               "VGA2 sense: Attached display expects digital input\n");
-         return 0;
-      }
-      SiS_Pr->CP_Vendor = buffer[9] | (buffer[8] << 8);
-      SiS_Pr->CP_Product = buffer[10] | (buffer[11] << 8);
-      foundcrt = TRUE;
-      break;
-   case 3:
-   case 4:
-      if(!(checkedid2(buffer))) {
-          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_ERROR,
-               "VGA2 sense: Attached display does not support analog input (0x%02x)\n",
-               buffer[0x41]);
-         return 0;
-      }
-      SiS_Pr->CP_Vendor = buffer[2] | (buffer[1] << 8);
-      SiS_Pr->CP_Product = buffer[3] | (buffer[4] << 8);
-      foundcrt = TRUE;
-      break;
-   }
-
-   if(foundcrt) {
-      SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x32,0x10);
-   }
-   return(0);
-}
-
-#endif
-
-void
-SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, USHORT tempax,USHORT tempbh)
-{
-  USHORT tempbl;
-
-  tempbl = SiS_GetCH70xx(SiS_Pr,(tempax & 0x00FF));
-  tempbl = (((tempbl & tempbh) << 8) | tempax);
-  SiS_SetCH70xx(SiS_Pr,tempbl);
-}
-
 /* Generic I2C functions for Chrontel & DDC --------- */
 
 static void
-SiS_SetSwitchDDC2(SiS_Private *SiS_Pr)
+SiS_SetSwitchDDC2(struct SiS_Private *SiS_Pr)
 {
   SiS_SetSCLKHigh(SiS_Pr);
   SiS_WaitRetrace1(SiS_Pr);
@@ -10505,125 +9502,127 @@ SiS_SetSwitchDDC2(SiS_Private *SiS_Pr)
   SiS_WaitRetrace1(SiS_Pr);
 }
 
-USHORT
-SiS_ReadDDC1Bit(SiS_Private *SiS_Pr)
+unsigned short
+SiS_ReadDDC1Bit(struct SiS_Private *SiS_Pr)
 {
    SiS_WaitRetrace1(SiS_Pr);
-   return((SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x02) >> 1);
+   return ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x02) >> 1);
 }
 
 /* Set I2C start condition */
 /* This is done by a SD high-to-low transition while SC is high */
-static USHORT
-SiS_SetStart(SiS_Private *SiS_Pr)
+static unsigned short
+SiS_SetStart(struct SiS_Private *SiS_Pr)
 {
-  if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;                               /* (SC->low)  */
+  if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;                    /* (SC->low)  */
   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
-                 SiS_Pr->SiS_DDC_Index,
-                  SiS_Pr->SiS_DDC_NData,
-                 SiS_Pr->SiS_DDC_Data);                                   /* SD->high */
-  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;                              /* SC->high */
+                 SiS_Pr->SiS_DDC_Index,
+                 SiS_Pr->SiS_DDC_NData,
+                 SiS_Pr->SiS_DDC_Data);                        /* SD->high */
+  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;                   /* SC->high */
   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
-                 SiS_Pr->SiS_DDC_Index,
-                  SiS_Pr->SiS_DDC_NData,
-                 0x00);                                                   /* SD->low = start condition */
-  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;                              /* (SC->low) */
+                 SiS_Pr->SiS_DDC_Index,
+                 SiS_Pr->SiS_DDC_NData,
+                 0x00);                                        /* SD->low = start condition */
+  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;                   /* (SC->low) */
   return 0;
 }
 
 /* Set I2C stop condition */
 /* This is done by a SD low-to-high transition while SC is high */
-static USHORT
-SiS_SetStop(SiS_Private *SiS_Pr)
+static unsigned short
+SiS_SetStop(struct SiS_Private *SiS_Pr)
 {
-  if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;                               /* (SC->low) */
+  if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;                    /* (SC->low) */
   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
-                 SiS_Pr->SiS_DDC_Index,
-                  SiS_Pr->SiS_DDC_NData,
-                 0x00);                                                   /* SD->low   */
-  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;                              /* SC->high  */
+                 SiS_Pr->SiS_DDC_Index,
+                 SiS_Pr->SiS_DDC_NData,
+                 0x00);                                        /* SD->low   */
+  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;                   /* SC->high  */
   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
-                 SiS_Pr->SiS_DDC_Index,
-                  SiS_Pr->SiS_DDC_NData,
-                 SiS_Pr->SiS_DDC_Data);                                   /* SD->high = stop condition */
-  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;                              /* (SC->high) */
+                 SiS_Pr->SiS_DDC_Index,
+                 SiS_Pr->SiS_DDC_NData,
+                 SiS_Pr->SiS_DDC_Data);                        /* SD->high = stop condition */
+  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;                   /* (SC->high) */
   return 0;
 }
 
 /* Write 8 bits of data */
-static USHORT
-SiS_WriteDDC2Data(SiS_Private *SiS_Pr, USHORT tempax)
+static unsigned short
+SiS_WriteDDC2Data(struct SiS_Private *SiS_Pr, unsigned short tempax)
 {
-  USHORT i,flag,temp;
+  unsigned short i,flag,temp;
 
   flag = 0x80;
-  for(i=0; i<8; i++) {
-    SiS_SetSCLKLow(SiS_Pr);                                                  /* SC->low */
+  for(i = 0; i < 8; i++) {
+    SiS_SetSCLKLow(SiS_Pr);                                    /* SC->low */
     if(tempax & flag) {
       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
-                     SiS_Pr->SiS_DDC_Index,
-                      SiS_Pr->SiS_DDC_NData,
-                     SiS_Pr->SiS_DDC_Data);                                  /* Write bit (1) to SD */
+                     SiS_Pr->SiS_DDC_Index,
+                     SiS_Pr->SiS_DDC_NData,
+                     SiS_Pr->SiS_DDC_Data);                    /* Write bit (1) to SD */
     } else {
       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
-                     SiS_Pr->SiS_DDC_Index,
-                      SiS_Pr->SiS_DDC_NData,
-                     0x00);                                                  /* Write bit (0) to SD */
+                     SiS_Pr->SiS_DDC_Index,
+                     SiS_Pr->SiS_DDC_NData,
+                     0x00);                                    /* Write bit (0) to SD */
     }
-    SiS_SetSCLKHigh(SiS_Pr);                                                 /* SC->high */
+    SiS_SetSCLKHigh(SiS_Pr);                                   /* SC->high */
     flag >>= 1;
   }
-  temp = SiS_CheckACK(SiS_Pr);                                               /* Check acknowledge */
-  return(temp);
+  temp = SiS_CheckACK(SiS_Pr);                                 /* Check acknowledge */
+  return temp;
 }
 
-static USHORT
-SiS_ReadDDC2Data(SiS_Private *SiS_Pr, USHORT tempax)
+static unsigned short
+SiS_ReadDDC2Data(struct SiS_Private *SiS_Pr)
 {
-  USHORT i,temp,getdata;
+  unsigned short i, temp, getdata;
 
-  getdata=0;
-  for(i=0; i<8; i++) {
+  getdata = 0;
+  for(i = 0; i < 8; i++) {
     getdata <<= 1;
     SiS_SetSCLKLow(SiS_Pr);
     SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
-                   SiS_Pr->SiS_DDC_Index,
-                    SiS_Pr->SiS_DDC_NData,
+                   SiS_Pr->SiS_DDC_Index,
+                   SiS_Pr->SiS_DDC_NData,
                    SiS_Pr->SiS_DDC_Data);
     SiS_SetSCLKHigh(SiS_Pr);
     temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
     if(temp & SiS_Pr->SiS_DDC_Data) getdata |= 0x01;
   }
-  return(getdata);
+  return getdata;
 }
 
-static USHORT
-SiS_SetSCLKLow(SiS_Private *SiS_Pr)
+static unsigned short
+SiS_SetSCLKLow(struct SiS_Private *SiS_Pr)
 {
   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
-                 SiS_Pr->SiS_DDC_Index,
-                  SiS_Pr->SiS_DDC_NClk,
-                 0x00);                                        /* SetSCLKLow()  */
+                 SiS_Pr->SiS_DDC_Index,
+                 SiS_Pr->SiS_DDC_NClk,
+                 0x00);                                        /* SetSCLKLow()  */
   SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
   return 0;
 }
 
-static USHORT
-SiS_SetSCLKHigh(SiS_Private *SiS_Pr)
+static unsigned short
+SiS_SetSCLKHigh(struct SiS_Private *SiS_Pr)
 {
-  USHORT temp, watchdog=1000;
+  unsigned short temp, watchdog=1000;
 
   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
-                 SiS_Pr->SiS_DDC_Index,
-                  SiS_Pr->SiS_DDC_NClk,
+                 SiS_Pr->SiS_DDC_Index,
+                 SiS_Pr->SiS_DDC_NClk,
                  SiS_Pr->SiS_DDC_Clk);                         /* SetSCLKHigh()  */
   do {
     temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
   } while((!(temp & SiS_Pr->SiS_DDC_Clk)) && --watchdog);
   if (!watchdog) {
+#ifdef SIS_XORG_XF86
 #ifdef TWDEBUG
         xf86DrvMsg(0, X_INFO, "SetClkHigh failed\n");
 #endif
+#endif
        return 0xFFFF;
   }
   SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
@@ -10632,21 +9631,21 @@ SiS_SetSCLKHigh(SiS_Private *SiS_Pr)
 
 /* Check I2C acknowledge */
 /* Returns 0 if ack ok, non-0 if ack not ok */
-static USHORT
-SiS_CheckACK(SiS_Private *SiS_Pr)
+static unsigned short
+SiS_CheckACK(struct SiS_Private *SiS_Pr)
 {
-  USHORT tempah;
+  unsigned short tempah;
 
   SiS_SetSCLKLow(SiS_Pr);                                         /* (SC->low) */
   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
-                 SiS_Pr->SiS_DDC_Index,
-                  SiS_Pr->SiS_DDC_NData,
-                 SiS_Pr->SiS_DDC_Data);                           /* (SD->high) */
+                 SiS_Pr->SiS_DDC_Index,
+                 SiS_Pr->SiS_DDC_NData,
+                 SiS_Pr->SiS_DDC_Data);                           /* (SD->high) */
   SiS_SetSCLKHigh(SiS_Pr);                                        /* SC->high = clock impulse for ack */
   tempah = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); /* Read SD */
   SiS_SetSCLKLow(SiS_Pr);                                         /* SC->low = end of clock impulse */
-  if(tempah & SiS_Pr->SiS_DDC_Data) return(1);                    /* Ack OK if bit = 0 */
-  else return(0);
+  if(tempah & SiS_Pr->SiS_DDC_Data) return 1;                     /* Ack OK if bit = 0 */
+  return 0;
 }
 
 /* End of I2C functions ----------------------- */
@@ -10656,67 +9655,67 @@ SiS_CheckACK(SiS_Private *SiS_Pr)
 
 #ifdef SIS315H
 
-static USHORT
-GetRAMDACromptr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+static unsigned short
+GetRAMDACromptr(struct SiS_Private *SiS_Pr)
 {
-  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
-  USHORT romptr;
+  unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
+  unsigned short romptr;
 
-  if(HwInfo->jChipType < SIS_330) {
+  if(SiS_Pr->ChipType < SIS_330) {
      romptr = SISGETROMW(0x128);
-     if(SiS_Pr->SiS_VBType & VB_SIS301B302B)
+     if(SiS_Pr->SiS_VBType & VB_SIS30xB)
         romptr = SISGETROMW(0x12a);
   } else {
      romptr = SISGETROMW(0x1a8);
-     if(SiS_Pr->SiS_VBType & VB_SIS301B302B)
+     if(SiS_Pr->SiS_VBType & VB_SIS30xB)
         romptr = SISGETROMW(0x1aa);
   }
-  return(romptr);
+  return romptr;
 }
 
-static USHORT
-GetLCDromptr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+static unsigned short
+GetLCDromptr(struct SiS_Private *SiS_Pr)
 {
-  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
-  USHORT romptr;
+  unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
+  unsigned short romptr;
 
-  if(HwInfo->jChipType < SIS_330) {
+  if(SiS_Pr->ChipType < SIS_330) {
      romptr = SISGETROMW(0x120);
-     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
+     if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
         romptr = SISGETROMW(0x122);
   } else {
      romptr = SISGETROMW(0x1a0);
-     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
+     if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
         romptr = SISGETROMW(0x1a2);
   }
-  return(romptr);
+  return romptr;
 }
 
-static USHORT
-GetTVromptr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+static unsigned short
+GetTVromptr(struct SiS_Private *SiS_Pr)
 {
-  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
-  USHORT romptr;
+  unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
+  unsigned short romptr;
 
-  if(HwInfo->jChipType < SIS_330) {
+  if(SiS_Pr->ChipType < SIS_330) {
      romptr = SISGETROMW(0x114);
-     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
+     if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
         romptr = SISGETROMW(0x11a);
   } else {
      romptr = SISGETROMW(0x194);
-     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
+     if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
         romptr = SISGETROMW(0x19a);
   }
-  return(romptr);
+  return romptr;
 }
 
-static USHORT
-GetLCDPtrIndexBIOS(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+static unsigned short
+GetLCDPtrIndexBIOS(struct SiS_Private *SiS_Pr)
 {
-  USHORT index;
+  unsigned short index;
 
-  if((IS_SIS650) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
-     if(!(SiS_IsNotM650orLater(SiS_Pr, HwInfo))) {
+  if((IS_SIS650) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
+     if(!(SiS_IsNotM650orLater(SiS_Pr))) {
         if((index = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0)) {
           index >>= 4;
           index *= 3;
@@ -10729,7 +9728,12 @@ GetLCDPtrIndexBIOS(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 
   index = SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F;
   if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)      index -= 5;
-  else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 6;
+  if(SiS_Pr->SiS_VBType & VB_SIS301C) {  /* 1.15.20 and later (not VB specific) */
+     if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 5;
+     if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768) index -= 5;
+  } else {
+     if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 6;
+  }
   index--;
   index *= 3;
   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
@@ -10737,10 +9741,10 @@ GetLCDPtrIndexBIOS(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
   return index;
 }
 
-static USHORT
-GetLCDPtrIndex(SiS_Private *SiS_Pr)
+static unsigned short
+GetLCDPtrIndex(struct SiS_Private *SiS_Pr)
 {
-  USHORT index;
+  unsigned short index;
 
   index = ((SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F) - 1) * 3;
   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)         index += 2;
@@ -10748,10 +9752,10 @@ GetLCDPtrIndex(SiS_Private *SiS_Pr)
   return index;
 }
 
-static USHORT
-GetTVPtrIndex(SiS_Private *SiS_Pr)
+static unsigned short
+GetTVPtrIndex(struct SiS_Private *SiS_Pr)
 {
-  USHORT index;
+  unsigned short index;
 
   index = 0;
   if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
@@ -10769,10 +9773,10 @@ GetTVPtrIndex(SiS_Private *SiS_Pr)
   return index;
 }
 
-static ULONG
-GetOEMTVPtr661_2_GEN(SiS_Private *SiS_Pr, int addme)
+static unsigned int
+GetOEMTVPtr661_2_GEN(struct SiS_Private *SiS_Pr, int addme)
 {
-   USHORT index = 0, temp = 0;
+   unsigned short index = 0, temp = 0;
 
    if(SiS_Pr->SiS_TVMode & TVSetPAL)   index = 1;
    if(SiS_Pr->SiS_TVMode & TVSetPALM)  index = 2;
@@ -10784,7 +9788,7 @@ GetOEMTVPtr661_2_GEN(SiS_Private *SiS_Pr, int addme)
       if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 7;
    }
 
-   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
       if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
          (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
         index += addme;
@@ -10792,25 +9796,25 @@ GetOEMTVPtr661_2_GEN(SiS_Private *SiS_Pr, int addme)
       }
       temp += 0x0100;
    }
-   return(ULONG)(index | (temp << 16));
+   return (unsigned int)(index | (temp << 16));
 }
 
-static ULONG
-GetOEMTVPtr661_2_OLD(SiS_Private *SiS_Pr)
+static unsigned int
+GetOEMTVPtr661_2_OLD(struct SiS_Private *SiS_Pr)
 {
-   return(GetOEMTVPtr661_2_GEN(SiS_Pr, 8));
+   return (GetOEMTVPtr661_2_GEN(SiS_Pr, 8));
 }
 
 #if 0
-static ULONG
-GetOEMTVPtr661_2_NEW(SiS_Private *SiS_Pr)
+static unsigned int
+GetOEMTVPtr661_2_NEW(struct SiS_Private *SiS_Pr)
 {
-   return(GetOEMTVPtr661_2_GEN(SiS_Pr, 6));
+   return (GetOEMTVPtr661_2_GEN(SiS_Pr, 6));
 }
 #endif
 
 static int
-GetOEMTVPtr661(SiS_Private *SiS_Pr)
+GetOEMTVPtr661(struct SiS_Private *SiS_Pr)
 {
    int index = 0;
 
@@ -10833,10 +9837,10 @@ GetOEMTVPtr661(SiS_Private *SiS_Pr)
 }
 
 static void
-SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
+SetDelayComp(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
 {
-  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
-  USHORT delay=0,index,myindex,temp,romptr=0;
+  unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
+  unsigned short delay=0,index,myindex,temp,romptr=0;
   BOOLEAN dochiptest = TRUE;
 
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
@@ -10848,19 +9852,19 @@ SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
   /* Find delay (from ROM, internal tables, PCI subsystem) */
 
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {                   /* ------------ VGA */
-     
+
      if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
-        romptr = GetRAMDACromptr(SiS_Pr, HwInfo);
+        romptr = GetRAMDACromptr(SiS_Pr);
      }
      if(romptr) delay = ROMAddr[romptr];
      else {
         delay = 0x04;
-        if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
+        if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
           if(IS_SIS650) {
              delay = 0x0a;
           } else if(IS_SIS740) {
              delay = 0x00;
-          } else if(HwInfo->jChipType < SIS_330) {
+          } else if(SiS_Pr->ChipType < SIS_330) {
              delay = 0x0c;
           } else {
              delay = 0x0c;
@@ -10901,8 +9905,12 @@ SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
           SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,delay);
        } else {
           delay = 0x0c;
-          if(SiS_Pr->SiS_VBType & VB_SIS301C) delay = 0x03;
-          else if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+          if(SiS_Pr->SiS_VBType & VB_SIS301C) {
+             delay = 0x03;
+             if((SiS_Pr->PanelXRes > 1280) && (SiS_Pr->PanelYRes > 1024)) {
+                delay = 0x00;
+             }
+          } else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
              if(IS_SIS740) delay = 0x01;
              else          delay = 0x03;
           }
@@ -10947,12 +9955,12 @@ SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
 
      if(!gotitfrompci) {
 
-        index = GetLCDPtrIndexBIOS(SiS_Pr, HwInfo);
+        index = GetLCDPtrIndexBIOS(SiS_Pr);
         myindex = GetLCDPtrIndex(SiS_Pr);
 
-        if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
+        if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
 
-           if(SiS_IsNotM650orLater(SiS_Pr, HwInfo)) {
+           if(SiS_IsNotM650orLater(SiS_Pr)) {
 
               if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
                 /* Always use the second pointer on 650; some BIOSes */
@@ -10978,11 +9986,12 @@ SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
                  (!(SiS_Pr->SiS_ROMNew))                     &&
                  (SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) &&
                  (SiS_Pr->SiS_LCDResInfo != Panel_1280x768)  &&
-                 (SiS_Pr->SiS_LCDResInfo != Panel_1280x960)) {
+                 (SiS_Pr->SiS_LCDResInfo != Panel_1280x960)  &&
+                 (SiS_Pr->SiS_LCDResInfo != Panel_1600x1200)  &&
+                 ((romptr = GetLCDromptr(SiS_Pr)))) {
 
           /* Data for 1280x1024 wrong in 301B BIOS */
-           romptr = GetLCDromptr(SiS_Pr, HwInfo);
-          if(!romptr) return;
+          /* Data for 1600x1200 wrong in 301C BIOS */
           delay = ROMAddr[(romptr + index)];
 
         } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
@@ -10993,14 +10002,15 @@ SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
        } else {
 
            delay = SiS310_LCDDelayCompensation_301[myindex];
-          if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+          if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
              if(IS_SIS740) delay = 0x01;
-             else if(HwInfo->jChipType <= SIS_315PRO) delay = SiS310_LCDDelayCompensation_3xx301LV[myindex];
+             else if(SiS_Pr->ChipType <= SIS_315PRO) delay = SiS310_LCDDelayCompensation_3xx301LV[myindex];
              else          delay = SiS310_LCDDelayCompensation_650301LV[myindex];
           } else if(SiS_Pr->SiS_VBType & VB_SIS301C) {
              if(IS_SIS740) delay = 0x01;  /* ? */
              else          delay = 0x03;
-          } else if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
+             if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) delay = 0x00; /* experience */
+          } else if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
              if(IS_SIS740) delay = 0x01;
              else          delay = SiS310_LCDDelayCompensation_3xx301B[myindex];
           }
@@ -11013,14 +10023,14 @@ SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
        SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,((delay << 4) & 0xf0));
        dochiptest = FALSE;
      }
-     
+
   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {                        /* ------------ TV */
 
      index = GetTVPtrIndex(SiS_Pr);
-     
-     if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
 
-        if(SiS_IsNotM650orLater(SiS_Pr,HwInfo)) {
+     if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
+
+        if(SiS_IsNotM650orLater(SiS_Pr)) {
 
            if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
              /* Always use the second pointer on 650; some BIOSes */
@@ -11062,7 +10072,7 @@ SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
 
      } else if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
 
-        romptr = GetTVromptr(SiS_Pr, HwInfo);
+        romptr = GetTVromptr(SiS_Pr);
        if(!romptr) return;
        delay = ROMAddr[romptr + index];
 
@@ -11073,7 +10083,7 @@ SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
      } else {
 
        delay = SiS310_TVDelayCompensation_301[index];
-        if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+        if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
           if(IS_SIS740) {
              delay = SiS310_TVDelayCompensation_740301B[index];
              /* LV: use 301 data? BIOS bug? */
@@ -11085,18 +10095,18 @@ SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
 
      }
 
-     if(SiS_LCDAEnabled(SiS_Pr, HwInfo)) {
+     if(SiS_LCDAEnabled(SiS_Pr)) {
        delay &= 0x0f;
        dochiptest = FALSE;
      }
-    
+
   } else return;
 
   /* Write delay */
 
   if(SiS_Pr->SiS_VBType & VB_SISVB) {
 
-     if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && dochiptest) {
+     if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS) && dochiptest) {
 
         temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0) >> 4;
         if(temp == 8) {                /* 1400x1050 BIOS (COMPAL) */
@@ -11134,11 +10144,10 @@ SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
 }
 
 static void
-SetAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
-               USHORT ModeNo,USHORT ModeIdIndex)
+SetAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
 {
-  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
-  USHORT index,temp,temp1,romptr=0;
+  unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
+  unsigned short index,temp,temp1,romptr=0;
 
   if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p|TVSetYPbPr525p)) return;
 
@@ -11152,14 +10161,14 @@ SetAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
   temp1 = temp;
 
   if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
-     if(HwInfo->jChipType >= SIS_661) {
+     if(SiS_Pr->ChipType >= SIS_661) {
         temp1 = GetOEMTVPtr661(SiS_Pr);
         temp1 >>= 1;
         romptr = SISGETROMW(0x260);
-        if(HwInfo->jChipType >= SIS_760) {
+        if(SiS_Pr->ChipType >= SIS_760) {
           romptr = SISGETROMW(0x360);
        }
-     } else if(HwInfo->jChipType >= SIS_330) {
+     } else if(SiS_Pr->ChipType >= SIS_330) {
         romptr = SISGETROMW(0x192);
      } else {
         romptr = SISGETROMW(0x112);
@@ -11178,11 +10187,10 @@ SetAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
 }
 
 static void
-SetEdgeEnhance(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
-               USHORT ModeNo,USHORT ModeIdIndex)
+SetEdgeEnhance(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
 {
-  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
-  USHORT index,temp,temp1,romptr=0;
+  unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
+  unsigned short index,temp,temp1,romptr=0;
 
   temp = temp1 = GetTVPtrIndex(SiS_Pr) >> 1;   /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
 
@@ -11192,14 +10200,14 @@ SetEdgeEnhance(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
      index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;
 
   if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
-     if(HwInfo->jChipType >= SIS_661) {
+     if(SiS_Pr->ChipType >= SIS_661) {
         romptr = SISGETROMW(0x26c);
-        if(HwInfo->jChipType >= SIS_760) {
+        if(SiS_Pr->ChipType >= SIS_760) {
           romptr = SISGETROMW(0x36c);
        }
        temp1 = GetOEMTVPtr661(SiS_Pr);
         temp1 >>= 1;
-     } else if(HwInfo->jChipType >= SIS_330) {
+     } else if(SiS_Pr->ChipType >= SIS_330) {
         romptr = SISGETROMW(0x1a4);
      } else {
         romptr = SISGETROMW(0x124);
@@ -11217,10 +10225,9 @@ SetEdgeEnhance(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
 }
 
 static void
-SetYFilter(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
-           USHORT ModeNo,USHORT ModeIdIndex)
+SetYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
 {
-  USHORT index, temp, i, j;
+  unsigned short index, temp, i, j;
 
   if(ModeNo <= 0x13) {
      index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
@@ -11235,7 +10242,7 @@ SetYFilter(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
   else if(SiS_Pr->SiS_TVMode & TVSetPALN)    temp = 4;  /* PAL-N */
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp = 1;  /* HiVision uses PAL */
 
-  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+  if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
      for(i=0x35, j=0; i<=0x38; i++, j++) {
         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
      }
@@ -11250,23 +10257,22 @@ SetYFilter(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
 }
 
 static void
-SetPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
-             USHORT ModeNo,USHORT ModeIdIndex)
+SetPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
 {
-  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
-  USHORT index,temp,i,j,resinfo,romptr=0;
-  ULONG  lindex;
+  unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
+  unsigned short index,temp,i,j,resinfo,romptr=0;
+  unsigned int  lindex;
 
   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
 
   /* NTSC-J data not in BIOS, and already set in SetGroup2 */
   if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) return;
 
-  if((HwInfo->jChipType >= SIS_661) || SiS_Pr->SiS_ROMNew) {
+  if((SiS_Pr->ChipType >= SIS_661) || SiS_Pr->SiS_ROMNew) {
      lindex = GetOEMTVPtr661_2_OLD(SiS_Pr) & 0xffff;
      lindex <<= 2;
      for(j=0, i=0x31; i<=0x34; i++, j++) {
-        SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS661_TVPhase[lindex + j]);
+        SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[lindex + j]);
      }
      return;
   }
@@ -11286,17 +10292,17 @@ SetPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
    */
   if(SiS_Pr->SiS_UseROM) {
      romptr = SISGETROMW(0x116);
-     if(HwInfo->jChipType >= SIS_330) {
+     if(SiS_Pr->ChipType >= SIS_330) {
         romptr = SISGETROMW(0x196);
      }
-     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+     if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
         romptr = SISGETROMW(0x11c);
-       if(HwInfo->jChipType >= SIS_330) {
+       if(SiS_Pr->ChipType >= SIS_330) {
           romptr = SISGETROMW(0x19c);
        }
        if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode))) {
           romptr = SISGETROMW(0x116);
-          if(HwInfo->jChipType >= SIS_330) {
+          if(SiS_Pr->ChipType >= SIS_330) {
               romptr = SISGETROMW(0x196);
            }
        }
@@ -11311,7 +10317,7 @@ SetPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
      index = temp % 2;
      temp >>= 1;          /* 0:NTSC, 1:PAL, 2:HiTV */
      for(j=0, i=0x31; i<=0x34; i++, j++) {
-        if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV))
+        if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV))
           SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
         else if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || (SiS_Pr->SiS_TVMode & TVSetTVSimuMode))
            SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr2[temp][index][j]);
@@ -11320,7 +10326,7 @@ SetPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
      }
   }
 
-  if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision))) {
+  if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision))) {
      if((!(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetYPbPr525p | TVSetYPbPr750p))) && (ModeNo > 0x13)) {
         if((resinfo == SIS_RI_640x480) ||
           (resinfo == SIS_RI_800x600)) {
@@ -11339,11 +10345,11 @@ SetPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
 }
 
 static void
-SetDelayComp661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo,
-                USHORT ModeIdIndex, USHORT RTI)
+SetDelayComp661(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+                unsigned short ModeIdIndex, unsigned short RTI)
 {
-   USHORT delay = 0, romptr = 0, index, lcdpdcindex;
-   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
+   unsigned short delay = 0, romptr = 0, index, lcdpdcindex;
+   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
 
    if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToRAMDAC)))
       return;
@@ -11359,7 +10365,7 @@ SetDelayComp661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo,
          if(SiS_Pr->UseCustomMode) {
            index = SiS_Pr->CSRClock;
          } else if(ModeNo > 0x13) {
-            index = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RTI,HwInfo);
+            index = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RTI);
             index = SiS_Pr->SiS_VCLKData[index].CLOCK;
          }
         if(index < 25) index = 25;
@@ -11387,7 +10393,36 @@ SetDelayComp661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo,
    else                      delay = (SiS_Pr->SiS_RefIndex[RTI].Ext_PDC >> 4);
    delay |= (delay << 8);
 
-   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+   if(SiS_Pr->ChipType >= XGI_20) {
+
+      delay = 0x0606;
+      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+
+        delay = 0x0404;
+         if(SiS_Pr->SiS_XGIROM) {
+            index = GetTVPtrIndex(SiS_Pr);
+            if((romptr = SISGETROMW(0x35e))) {
+               delay = (ROMAddr[romptr + index] & 0x0f) << 1;
+               delay |= (delay << 8);
+            }
+        }
+
+        if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
+           if(SiS_Pr->ChipType == XGI_40 && SiS_Pr->ChipRevision == 0x02) {
+              delay -= 0x0404;
+           }
+        }
+      }
+
+   } else if(SiS_Pr->ChipType >= SIS_340) {
+
+      delay = 0x0606;
+      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+         delay = 0x0404;
+      }
+      /* TODO (eventually) */
+
+   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
 
       /* 3. TV */
 
@@ -11406,7 +10441,7 @@ SetDelayComp661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo,
       /* 4. LCD, LCDA (for new ROM only LV and non-Pass 1:1) */
 
       if( (SiS_Pr->SiS_LCDResInfo != Panel_Custom) &&
-          ((romptr = GetLCDStructPtr661_2(SiS_Pr, HwInfo))) ) {
+          ((romptr = GetLCDStructPtr661_2(SiS_Pr))) ) {
 
         lcdpdcindex = (SiS_Pr->SiS_VBType & VB_UMC) ? 14 : 12;
 
@@ -11426,6 +10461,7 @@ SetDelayComp661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo,
            case Panel_1280x768_2:delay = 0x0004; break;
            case Panel_1280x800:
            case Panel_1280x800_2:delay = 0x0004; break; /* Verified for 1280x800 */
+           case Panel_1280x854:  delay = 0x0004; break; /* FIXME */
            case Panel_1280x1024: delay = 0x1e04; break;
            case Panel_1400x1050: delay = 0x0004; break;
            case Panel_1600x1200: delay = 0x0400; break;
@@ -11469,10 +10505,10 @@ SetDelayComp661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo,
 }
 
 static void
-SetCRT2SyncDither661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo, USHORT RTI)
+SetCRT2SyncDither661(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RTI)
 {
-   USHORT infoflag;
-   UCHAR temp;
+   unsigned short infoflag;
+   unsigned char  temp;
 
    if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
 
@@ -11513,12 +10549,16 @@ SetCRT2SyncDither661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo, US
 }
 
 static void
-SetPanelParms661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SetPanelParms661(struct SiS_Private *SiS_Pr)
 {
-   UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
-   USHORT romptr, temp1, temp2;
+   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
+   unsigned short romptr, temp1, temp2;
+
+   if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_SIS30xC)) {
+      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x24,0x0f);
+   }
 
-   if(SiS_Pr->SiS_VBType & (VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV)) {
+   if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
       if(SiS_Pr->LVDSHL != -1) {
          SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
       }
@@ -11526,8 +10566,8 @@ SetPanelParms661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 
    if(SiS_Pr->SiS_ROMNew) {
 
-      if((romptr = GetLCDStructPtr661_2(SiS_Pr, HwInfo))) {
-         if(SiS_Pr->SiS_VBType & (VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV)) {
+      if((romptr = GetLCDStructPtr661_2(SiS_Pr))) {
+         if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
             temp1 = (ROMAddr[romptr] & 0x03) | 0x0c;
            temp2 = 0xfc;
            if(SiS_Pr->LVDSHL != -1) {
@@ -11546,48 +10586,47 @@ SetPanelParms661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 }
 
 static void
-SiS_OEM310Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
-                  USHORT ModeNo,USHORT ModeIdIndex,USHORT RRTI)
+SiS_OEM310Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RRTI)
 {
    if((SiS_Pr->SiS_ROMNew) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
-      SetDelayComp661(SiS_Pr,HwInfo,ModeNo,ModeIdIndex,RRTI);
+      SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
       if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
-         SetCRT2SyncDither661(SiS_Pr,HwInfo,ModeNo,RRTI);
-         SetPanelParms661(SiS_Pr,HwInfo);
+         SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI);
+         SetPanelParms661(SiS_Pr);
       }
    } else {
-      SetDelayComp(SiS_Pr,HwInfo,ModeNo);
+      SetDelayComp(SiS_Pr,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);
+      SetAntiFlicker(SiS_Pr,ModeNo,ModeIdIndex);
+      SetPhaseIncr(SiS_Pr,ModeNo,ModeIdIndex);
+      SetYFilter(SiS_Pr,ModeNo,ModeIdIndex);
       if(SiS_Pr->SiS_VBType & VB_SIS301) {
-         SetEdgeEnhance(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
+         SetEdgeEnhance(SiS_Pr,ModeNo,ModeIdIndex);
       }
    }
 }
 
 static void
-SiS_OEM661Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
-                  USHORT ModeNo,USHORT ModeIdIndex, USHORT RRTI)
+SiS_OEM661Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+                       unsigned short ModeIdIndex, unsigned short RRTI)
 {
    if(SiS_Pr->SiS_VBType & VB_SISVB) {
 
-      SetDelayComp661(SiS_Pr,HwInfo,ModeNo,ModeIdIndex,RRTI);
+      SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
 
       if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
-         SetCRT2SyncDither661(SiS_Pr,HwInfo,ModeNo,RRTI);
-         SetPanelParms661(SiS_Pr,HwInfo);
+         SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI);
+         SetPanelParms661(SiS_Pr);
       }
 
       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-         SetPhaseIncr(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
-         SetYFilter(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
-         SetAntiFlicker(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
+         SetPhaseIncr(SiS_Pr, ModeNo, ModeIdIndex);
+         SetYFilter(SiS_Pr, ModeNo, ModeIdIndex);
+         SetAntiFlicker(SiS_Pr, ModeNo, ModeIdIndex);
          if(SiS_Pr->SiS_VBType & VB_SIS301) {
-            SetEdgeEnhance(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
+            SetEdgeEnhance(SiS_Pr, ModeNo, ModeIdIndex);
          }
       }
    }
@@ -11601,13 +10640,12 @@ SiS_OEM661Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
  * pray that we have a backup...
  */
 static void
-SiS_FinalizeLCD(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
-                PSIS_HW_INFO HwInfo)
+SiS_FinalizeLCD(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
 {
-  USHORT tempcl,tempch,tempbl,tempbh,tempbx,tempax,temp;
-  USHORT resinfo,modeflag;
+  unsigned short tempcl,tempch,tempbl,tempbh,tempbx,tempax,temp;
+  unsigned short resinfo,modeflag;
 
-  if(!(SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) return;
+  if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) return;
   if(SiS_Pr->SiS_ROMNew) return;
 
   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
@@ -11678,7 +10716,7 @@ SiS_FinalizeLCD(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 
   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
-       if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
+       if(SiS_Pr->SiS_VBType & VB_SISEMI) {
           SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
 #ifdef SET_EMI
           SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
@@ -11806,11 +10844,11 @@ SiS_FinalizeLCD(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 #ifdef SIS300
 
 static void
-SetOEMLCDData2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
-               USHORT ModeNo,USHORT ModeIdIndex, USHORT RefTabIndex)
+SetOEMLCDData2(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,
+               unsigned short RefTabIndex)
 {
-  USHORT crt2crtc=0, modeflag, myindex=0;
-  UCHAR  temp;
+  unsigned short crt2crtc=0, modeflag, myindex=0;
+  unsigned char  temp;
   int i;
 
   if(ModeNo <= 0x13) {
@@ -11849,21 +10887,21 @@ SetOEMLCDData2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
   }
 }
 
-static USHORT
-GetOEMLCDPtr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, int Flag)
+static unsigned short
+GetOEMLCDPtr(struct SiS_Private *SiS_Pr, int Flag)
 {
-  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
-  USHORT tempbx=0,romptr=0;
-  UCHAR customtable300[] = {
-       0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+  unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
+  unsigned short tempbx=0,romptr=0;
+  static const unsigned char customtable300[] = {
+       0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
        0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
   };
-  UCHAR customtable630[] = {
-       0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+  static const unsigned char customtable630[] = {
+       0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
        0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
   };
 
-  if(HwInfo->jChipType == SIS_300) {
+  if(SiS_Pr->ChipType == SIS_300) {
 
     tempbx = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0x0f;
     if(SiS_Pr->SiS_VBType & VB_SIS301) tempbx &= 0x07;
@@ -11912,11 +10950,10 @@ GetOEMLCDPtr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, int Flag)
 }
 
 static void
-SetOEMLCDDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
-               USHORT ModeNo,USHORT ModeIdIndex)
+SetOEMLCDDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
 {
-  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
-  USHORT index,temp,romptr=0;
+  unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
+  unsigned short index,temp,romptr=0;
 
   if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
 
@@ -11927,22 +10964,22 @@ SetOEMLCDDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
   }
 
   /* The Panel Compensation Delay should be set according to tables
-   * here. Unfortunately, various BIOS versions don't case about
+   * here. Unfortunately, various BIOS versions don't care about
    * a uniform way using eg. ROM byte 0x220, but use different
    * hard coded delays (0x04, 0x20, 0x18) in SetGroup1().
-   * Thus we don't set this if the user select a custom pdc or if
+   * Thus we don't set this if the user selected a custom pdc or if
    * we otherwise detected a valid pdc.
    */
   if(SiS_Pr->PDC != -1) return;
 
-  temp = GetOEMLCDPtr(SiS_Pr,HwInfo, 0);
+  temp = GetOEMLCDPtr(SiS_Pr, 0);
 
   if(SiS_Pr->UseCustomMode)
      index = 0;
   else
      index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
 
-  if(HwInfo->jChipType != SIS_300) {
+  if(SiS_Pr->ChipType != SIS_300) {
      if(romptr) {
        romptr += (temp * 2);
        romptr = SISGETROMW(romptr);
@@ -11986,12 +11023,11 @@ SetOEMLCDDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
 }
 
 static void
-SetOEMLCDData(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
-              USHORT ModeNo,USHORT ModeIdIndex)
+SetOEMLCDData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
 {
 #if 0  /* Unfinished; Data table missing */
-  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
-  USHORT index,temp;
+  unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
+  unsigned short index,temp;
 
   if((SiS_Pr->SiS_UseROM) {
      if(!(ROMAddr[0x237] & 0x01)) return;
@@ -11999,8 +11035,8 @@ SetOEMLCDData(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
      /* No rom pointer in BIOS header! */
   }
 
-  temp = GetOEMLCDPtr(SiS_Pr,HwInfo, 1);
-  if(temp = 0xFFFF) return;
+  temp = GetOEMLCDPtr(SiS_Pr, 1);
+  if(temp == 0xFFFF) return;
 
   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDHIndex;
   for(i=0x14, j=0; i<=0x17; i++, j++) {
@@ -12018,10 +11054,10 @@ SetOEMLCDData(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
 #endif
 }
 
-static USHORT
-GetOEMTVPtr(SiS_Private *SiS_Pr)
+static unsigned short
+GetOEMTVPtr(struct SiS_Private *SiS_Pr)
 {
-  USHORT index;
+  unsigned short index;
 
   index = 0;
   if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))  index += 4;
@@ -12037,11 +11073,10 @@ GetOEMTVPtr(SiS_Private *SiS_Pr)
 }
 
 static void
-SetOEMTVDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
-              USHORT ModeNo,USHORT ModeIdIndex)
+SetOEMTVDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
 {
-  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
-  USHORT index,temp,romptr=0;
+  unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
+  unsigned short index,temp,romptr=0;
 
   if(SiS_Pr->SiS_UseROM) {
      if(!(ROMAddr[0x238] & 0x01)) return;
@@ -12070,11 +11105,10 @@ SetOEMTVDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
 }
 
 static void
-SetOEMAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
-                  USHORT ModeNo, USHORT ModeIdIndex)
+SetOEMAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
 {
-  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
-  USHORT index,temp,romptr=0;
+  unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
+  unsigned short index,temp,romptr=0;
 
   if(SiS_Pr->SiS_UseROM) {
      if(!(ROMAddr[0x238] & 0x01)) return;
@@ -12099,11 +11133,10 @@ SetOEMAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
 }
 
 static void
-SetOEMPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
-                USHORT ModeNo,USHORT ModeIdIndex)
+SetOEMPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
 {
-  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
-  USHORT index,i,j,temp,romptr=0;
+  unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
+  unsigned short index,i,j,temp,romptr=0;
 
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) return;
 
@@ -12119,7 +11152,7 @@ SetOEMPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
 
   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVPhaseIndex;
 
-  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+  if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
      for(i=0x31, j=0; i<=0x34; i++, j++) {
         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase2[temp][index][j]);
      }
@@ -12140,11 +11173,10 @@ SetOEMPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
 }
 
 static void
-SetOEMYFilter(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
-              USHORT ModeNo,USHORT ModeIdIndex)
+SetOEMYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
 {
-  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
-  USHORT index,temp,i,j,romptr=0;
+  unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
+  unsigned short index,temp,i,j,romptr=0;
 
   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSCART | SetCRT2ToHiVision | SetCRT2ToYPbPr525750)) return;
 
@@ -12162,7 +11194,7 @@ SetOEMYFilter(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
 
   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVYFilterIndex;
 
-  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+  if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
       for(i=0x35, j=0; i<=0x38; i++, j++) {
                SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
       }
@@ -12185,11 +11217,11 @@ SetOEMYFilter(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
   }
 }
 
-static USHORT
-SiS_SearchVBModeID(SiS_Private *SiS_Pr, USHORT *ModeNo)
+static unsigned short
+SiS_SearchVBModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo)
 {
-   USHORT ModeIdIndex;
-   UCHAR VGAINFO = SiS_Pr->SiS_VGAINFO;
+   unsigned short ModeIdIndex;
+   unsigned char  VGAINFO = SiS_Pr->SiS_VGAINFO;
 
    if(*ModeNo <= 5) *ModeNo |= 1;
 
@@ -12210,10 +11242,10 @@ SiS_SearchVBModeID(SiS_Private *SiS_Pr, USHORT *ModeNo)
 }
 
 static void
-SiS_OEM300Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
-                 USHORT ModeNo, USHORT ModeIdIndex, USHORT RefTableIndex)
+SiS_OEM300Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
+                 unsigned short RefTableIndex)
 {
-  USHORT OEMModeIdIndex=0;
+  unsigned short OEMModeIdIndex = 0;
 
   if(!SiS_Pr->UseCustomMode) {
      OEMModeIdIndex = SiS_SearchVBModeID(SiS_Pr,&ModeNo);
@@ -12221,18 +11253,18 @@ SiS_OEM300Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
   }
 
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-     SetOEMLCDDelay(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
+     SetOEMLCDDelay(SiS_Pr, ModeNo, OEMModeIdIndex);
      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-        SetOEMLCDData(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
+        SetOEMLCDData(SiS_Pr, ModeNo, OEMModeIdIndex);
      }
   }
   if(SiS_Pr->UseCustomMode) return;
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-     SetOEMTVDelay(SiS_Pr, HwInfo, ModeNo,OEMModeIdIndex);
+     SetOEMTVDelay(SiS_Pr, ModeNo,OEMModeIdIndex);
      if(SiS_Pr->SiS_VBType & VB_SISVB) {
-        SetOEMAntiFlicker(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
-       SetOEMPhaseIncr(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
-               SetOEMYFilter(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
+        SetOEMAntiFlicker(SiS_Pr, ModeNo, OEMModeIdIndex);
+       SetOEMPhaseIncr(SiS_Pr, ModeNo, OEMModeIdIndex);
+               SetOEMYFilter(SiS_Pr, ModeNo, OEMModeIdIndex);
      }
   }
 }
index f84eb54..f475b21 100644 (file)
@@ -3,7 +3,7 @@
 /*
  * Data and prototypes for init301.c
  *
- * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
  *
  * If distributed as part of the Linux kernel, the following license terms
  * apply:
  *
  */
 
-#ifndef  _INIT301_
-#define  _INIT301_
+#ifndef  _INIT301_H_
+#define  _INIT301_H_
 
 #include "osdef.h"
 #include "initdef.h"
 
-#ifdef LINUX_XF86
+#ifdef SIS_XORG_XF86
 #include "sis.h"
 #include "sis_regs.h"
 #endif
 
-#ifdef LINUX_KERNEL
+#ifdef SIS_LINUX_KERNEL
 #include "vgatypes.h"
 #include "vstruct.h"
 #ifdef SIS_CP
 #endif
 #include <linux/config.h>
 #include <linux/version.h>
-#include <asm/io.h>
 #include <linux/types.h>
+#include <asm/io.h>
+#include <linux/fb.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+#include <video/fbcon.h>
+#endif
+#include "sis.h"
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 #include <linux/sisfb.h>
 #else
@@ -78,7 +83,7 @@
 #endif
 #endif
 
-static const UCHAR SiS_YPbPrTable[3][64] = {
+static const unsigned char SiS_YPbPrTable[3][64] = {
   {
     0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c,
     0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a,
@@ -90,17 +95,17 @@ static const UCHAR SiS_YPbPrTable[3][64] = {
     0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00
   },
   {
-    0x1d,0x11,0x06,0x09,0x0b,0x0c,0x0c,0x0c,
+    0x33,0x06,0x06,0x09,0x0b,0x0c,0x0c,0x0c,
     0x98,0x0a,0x01,0x0d,0x06,0x0d,0x04,0x0a,
     0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x3f,
-    0x0c,0x50,0xb2,0x9f,0x16,0x59,0x4c /*0x4f*/,0x13,
+    0x0c,0x50,0xb2,0x9f,0x16,0x59,0x4f,0x13,
     0xad,0x11,0xad,0x1d,0x40,0x8a,0x3d,0xb8,
-    0x51,0x5e,0x60,0x57 /*0x49*/,0x7b /*0x7d*/,0x92,0x0f,0x40,
-    0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x4b,
+    0x51,0x5e,0x60,0x49,0x7d,0x92,0x0f,0x40,
+    0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x4e,
     0x43,0x41,0x11,0x00,0xfc,0xff,0x32,0x00
   },
   {
-#if 1
+#if 0 /* OK, but sticks to left edge */
     0x13,0x1d,0xe8,0x09,0x09,0xed,0x0c,0x0c,
     0x98,0x0a,0x01,0x0c,0x06,0x0d,0x04,0x0a,
     0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x3f,
@@ -110,20 +115,42 @@ static const UCHAR SiS_YPbPrTable[3][64] = {
     0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x27,
     0x00,0x40,0x11,0x00,0xfc,0xff,0x32,0x00
 #endif
-#if 0
-    0x2a,0x14,0xe8,0x09,0x09,0xed,0x0c,0x0c,  /* TEST (0.93) - BAD */
+#if 1 /* Perfect */
+    0x23,0x2d,0xe8,0x09,0x09,0xed,0x0c,0x0c,
     0x98,0x0a,0x01,0x0c,0x06,0x0d,0x04,0x0a,
     0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x3f,
-    0xed,0x50,0x70,0x9e,0x16,0x57,0x6c,0x13,
-    0x27,0x0b,0x27,0xfb,0x30,0x27,0x15,0xb0,
-    0x3b,0xdb,0x61,0x24,0x78,0x92,0x0f,0xff,
-    0xff,0xff,0xff,0xff,0xff,0xff,0x14,0x6f,
-    0x00,0x52,0xbb,0x00,0xd5,0xf7,0xa2,0x00
+    0xed,0x50,0x70,0x9f,0x16,0x59,0x60,0x13,
+    0x27,0x0b,0x27,0xfc,0x30,0x27,0x1c,0xb0,
+    0x4b,0x4b,0x6f,0x2f,0x63,0x92,0x0f,0x40,
+    0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x73,
+    0x00,0x40,0x11,0x00,0xfc,0xff,0x32,0x00
 #endif
   }
 };
 
-static const UCHAR SiS_HiTVGroup3_1[] = {
+static const unsigned char SiS_TVPhase[] =
+{
+       0x21,0xED,0xBA,0x08,    /* 0x00 SiS_NTSCPhase */
+       0x2A,0x05,0xE3,0x00,    /* 0x01 SiS_PALPhase */
+       0x21,0xE4,0x2E,0x9B,    /* 0x02 SiS_PALMPhase */
+       0x21,0xF4,0x3E,0xBA,    /* 0x03 SiS_PALNPhase */
+       0x1E,0x8B,0xA2,0xA7,
+       0x1E,0x83,0x0A,0xE0,    /* 0x05 SiS_SpecialPhaseM */
+       0x00,0x00,0x00,0x00,
+       0x00,0x00,0x00,0x00,
+       0x21,0xF0,0x7B,0xD6,    /* 0x08 SiS_NTSCPhase2 */
+       0x2A,0x09,0x86,0xE9,    /* 0x09 SiS_PALPhase2 */
+       0x21,0xE6,0xEF,0xA4,    /* 0x0a SiS_PALMPhase2 */
+       0x21,0xF6,0x94,0x46,    /* 0x0b SiS_PALNPhase2 */
+       0x1E,0x8B,0xA2,0xA7,
+       0x1E,0x83,0x0A,0xE0,    /* 0x0d SiS_SpecialPhaseM */
+       0x00,0x00,0x00,0x00,
+       0x00,0x00,0x00,0x00,
+       0x1e,0x8c,0x5c,0x7a,    /* 0x10 SiS_SpecialPhase */
+       0x25,0xd4,0xfd,0x5e     /* 0x11 SiS_SpecialPhaseJ */
+};
+
+static const unsigned char 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,
@@ -134,7 +161,7 @@ static const UCHAR SiS_HiTVGroup3_1[] = {
     0x1a, 0x1f, 0x25, 0x2a, 0x4c, 0xaa, 0x01
 };
 
-static const UCHAR SiS_HiTVGroup3_2[] = {
+static const unsigned char 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,
@@ -147,7 +174,7 @@ static const UCHAR SiS_HiTVGroup3_2[] = {
 
 /* 301C / 302ELV extended Part2 TV registers (4 tap scaler) */
 
-static const UCHAR SiS_Part2CLVX_1[] = {
+static const unsigned char SiS_Part2CLVX_1[] = {
     0x00,0x00,
     0x00,0x20,0x00,0x00,0x7F,0x20,0x02,0x7F,0x7D,0x20,0x04,0x7F,0x7D,0x1F,0x06,0x7E,
     0x7C,0x1D,0x09,0x7E,0x7C,0x1B,0x0B,0x7E,0x7C,0x19,0x0E,0x7D,0x7C,0x17,0x11,0x7C,
@@ -155,7 +182,7 @@ static const UCHAR SiS_Part2CLVX_1[] = {
     0x7E,0x09,0x1D,0x7C,0x7F,0x06,0x1F,0x7C,0x7F,0x04,0x20,0x7D,0x00,0x02,0x20,0x7E
 };
 
-static const UCHAR SiS_Part2CLVX_2[] = {
+static const unsigned char SiS_Part2CLVX_2[] = {
     0x00,0x00,
     0x00,0x20,0x00,0x00,0x7F,0x20,0x02,0x7F,0x7D,0x20,0x04,0x7F,0x7D,0x1F,0x06,0x7E,
     0x7C,0x1D,0x09,0x7E,0x7C,0x1B,0x0B,0x7E,0x7C,0x19,0x0E,0x7D,0x7C,0x17,0x11,0x7C,
@@ -163,7 +190,7 @@ static const UCHAR SiS_Part2CLVX_2[] = {
     0x7E,0x09,0x1D,0x7C,0x7F,0x06,0x1F,0x7C,0x7F,0x04,0x20,0x7D,0x00,0x02,0x20,0x7E
 };
 
-static const UCHAR SiS_Part2CLVX_3[] = {  /* NTSC, 525i, 525p */
+static const unsigned char SiS_Part2CLVX_3[] = {  /* NTSC, 525i, 525p */
     0xE0,0x01,
     0x04,0x1A,0x04,0x7E,0x03,0x1A,0x06,0x7D,0x01,0x1A,0x08,0x7D,0x00,0x19,0x0A,0x7D,
     0x7F,0x19,0x0C,0x7C,0x7E,0x18,0x0E,0x7C,0x7E,0x17,0x10,0x7B,0x7D,0x15,0x12,0x7C,
@@ -182,7 +209,7 @@ static const UCHAR SiS_Part2CLVX_3[] = {  /* NTSC, 525i, 525p */
     0xFF,0xFF
 };
 
-static const UCHAR SiS_Part2CLVX_4[] = {   /* PAL */
+static const unsigned char SiS_Part2CLVX_4[] = {   /* PAL */
     0x58,0x02,
     0x05,0x19,0x05,0x7D,0x03,0x19,0x06,0x7E,0x02,0x19,0x08,0x7D,0x01,0x18,0x0A,0x7D,
     0x00,0x18,0x0C,0x7C,0x7F,0x17,0x0E,0x7C,0x7E,0x16,0x0F,0x7D,0x7E,0x14,0x11,0x7D,
@@ -201,7 +228,7 @@ static const UCHAR SiS_Part2CLVX_4[] = {   /* PAL */
     0xFF,0xFF
 };
 
-static const UCHAR SiS_Part2CLVX_5[] = {   /* 750p */
+static const unsigned char SiS_Part2CLVX_5[] = {   /* 750p */
     0x00,0x03,
     0x05,0x19,0x05,0x7D,0x03,0x19,0x06,0x7E,0x02,0x19,0x08,0x7D,0x01,0x18,0x0A,0x7D,
     0x00,0x18,0x0C,0x7C,0x7F,0x17,0x0E,0x7C,0x7E,0x16,0x0F,0x7D,0x7E,0x14,0x11,0x7D,
@@ -210,7 +237,7 @@ static const UCHAR SiS_Part2CLVX_5[] = {   /* 750p */
     0xFF,0xFF
 };
 
-static const UCHAR SiS_Part2CLVX_6[] = {   /* 1080i */
+static const unsigned char SiS_Part2CLVX_6[] = {   /* 1080i */
     0x00,0x04,
     0x04,0x1A,0x04,0x7E,0x02,0x1B,0x05,0x7E,0x01,0x1A,0x07,0x7E,0x00,0x1A,0x09,0x7D,
     0x7F,0x19,0x0B,0x7D,0x7E,0x18,0x0D,0x7D,0x7D,0x17,0x10,0x7C,0x7D,0x15,0x12,0x7C,
@@ -221,7 +248,7 @@ static const UCHAR SiS_Part2CLVX_6[] = {   /* 1080i */
 
 #ifdef SIS315H
 /* 661 et al LCD data structure (2.03.00) */
-static const UCHAR SiS_LCDStruct661[] = {
+static const unsigned char SiS_LCDStruct661[] = {
     /* 1024x768 */
 /*  type|CR37|   HDE   |   VDE   |    HT   |    VT   |   hss    | hse   */
     0x02,0xC0,0x00,0x04,0x00,0x03,0x40,0x05,0x26,0x03,0x10,0x00,0x88,
@@ -249,11 +276,20 @@ static const UCHAR SiS_LCDStruct661[] = {
     /* 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,
+    /* 1280x800_3 */
+    0x0C,0xE0,0x00,0x05,0x20,0x03,0xAA,0x05,0x2E,0x03,0x30,0x00,0x50,
+    0x00,0x04,0x00,0x03,0x00,0x47,0xA9,0x10,0x00,0x00,0x00,0x00,0x07,
+    /* 800x600 */
+    0x01,0xC0,0x20,0x03,0x58,0x02,0x20,0x04,0x74,0x02,0x2A,0x00,0x80,
+    0x00,0x06,0x00,0x04,0x00,0x28,0x63,0x4B,0x00,0x00,0x00,0x00,0x00,
+    /* 1280x854 */
+    0x08,0xE0,0x00,0x05,0x56,0x03,0x80,0x06,0x5d,0x03,0x10,0x00,0x70,
+    0x00,0x01,0x00,0x03,0x00,0x54,0x75,0x13,0x00,0x00,0x00,0x00,0x08
 };
 #endif
 
 #ifdef SIS300
-static UCHAR SiS300_TrumpionData[7][80] = {
+static unsigned char SiS300_TrumpionData[14][80] = {
   { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
     0x20,0x03,0x0B,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x10,0x00,0x00,0x04,0x23,
     0x00,0x00,0x03,0x28,0x03,0x10,0x05,0x08,0x40,0x10,0x00,0x10,0x04,0x23,0x00,0x23,
@@ -288,119 +324,182 @@ static UCHAR SiS300_TrumpionData[7][80] = {
     0x40,0x05,0x13,0x00,0x00,0x03,0x26,0x03,0x88,0x0C,0x30,0x90,0x00,0x00,0x04,0x23,
     0x00,0x01,0x03,0x24,0x03,0x28,0x06,0x08,0x40,0x90,0x00,0x90,0x04,0x23,0x00,0x23,
     0x03,0x11,0x60,0x40,0x05,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x08,0x01,0x00,0x08,0x01,
-    0x00,0x08,0x01,0x01,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5B,0x01,0xBE,0x01,0x00 }
+    0x00,0x08,0x01,0x01,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5B,0x01,0xBE,0x01,0x00 },
+  /* variant 2 */
+  { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
+    0x20,0x03,0x15,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x18,0x00,0x00,0x04,0x23,
+    0x00,0x01,0x03,0x44,0x03,0x28,0x06,0x08,0x40,0x18,0x00,0x18,0x04,0x23,0x00,0x23,
+    0x03,0x11,0x60,0xA6,0x01,0xFF,0x03,0xFF,0x19,0x01,0x00,0x05,0x13,0x04,0x04,0x05,
+    0x04,0x0C,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
+  { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
+    0x20,0x03,0x15,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x18,0x00,0x00,0x04,0x23,
+    0x00,0x01,0x03,0x44,0x03,0x28,0x06,0x08,0x40,0x18,0x00,0x18,0x04,0x23,0x00,0x23,
+    0x03,0x11,0x60,0xA6,0x01,0xFF,0x03,0xFF,0x19,0x01,0x00,0x05,0x13,0x04,0x04,0x05,
+    0x04,0x0C,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
+  { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x8A,0x00,0xD8,0x02,
+    0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,
+    0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,
+    0x03,0x11,0x60,0xDA,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,
+    0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
+  { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x72,0x00,0xD8,0x02,
+    0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,
+    0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,
+    0x03,0x11,0x60,0xDA,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,
+    0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
+  { 0x02,0x0A,0x02,0x00,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
+    0x20,0x03,0x16,0x00,0xE0,0x01,0x0D,0x02,0x60,0x0C,0x30,0x98,0x00,0x00,0x04,0x23,
+    0x00,0x01,0x03,0x45,0x03,0x48,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x23,0x00,0x23,
+    0x03,0x11,0x60,0xF4,0x01,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x05,0x01,0x00,0x05,0x05,
+    0x04,0x0C,0x08,0x05,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEA,0x58,0x01,0xBE,0x01,0x00 },
+  { 0x02,0x0A,0x02,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0xBF,0x00,0x20,0x03,
+    0x20,0x04,0x0D,0x00,0x58,0x02,0x71,0x02,0x80,0x0C,0x30,0x9A,0x00,0xFA,0x03,0x1D,
+    0x00,0x01,0x03,0x22,0x03,0x28,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x1D,0x00,0x1D,
+    0x03,0x11,0x60,0x39,0x03,0x40,0x05,0xF4,0x18,0x07,0x02,0x06,0x04,0x01,0x06,0x0B,
+    0x02,0x0A,0x20,0x19,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEA,0x58,0x01,0xBE,0x01,0x00 },
+  { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0xEF,0x00,0x00,0x04,
+    0x40,0x05,0x13,0x00,0x00,0x03,0x26,0x03,0x88,0x0C,0x30,0x90,0x00,0x00,0x04,0x23,
+    0x00,0x01,0x03,0x24,0x03,0x28,0x06,0x08,0x40,0x90,0x00,0x90,0x04,0x23,0x00,0x23,
+    0x03,0x11,0x60,0x40,0x05,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x08,0x01,0x00,0x08,0x01,
+    0x00,0x08,0x01,0x01,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEA,0x58,0x01,0xBE,0x01,0x00 }
 };
 #endif
 
-void   SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
-void   SiS_EnableCRT2(SiS_Private *SiS_Pr);
-USHORT SiS_GetRatePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, PSIS_HW_INFO HwInfo);
-void   SiS_WaitRetrace1(SiS_Private *SiS_Pr);
-BOOLEAN        SiS_IsDualEdge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
-BOOLEAN        SiS_IsVAMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
-void   SiS_SetChrontelGPIO(SiS_Private *SiS_Pr, USHORT myvbinfo);
-void   SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo,
-               USHORT ModeIdIndex, PSIS_HW_INFO HwInfo,
-               int checkcrt2mode);
-void   SiS_SetYPbPr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
-void    SiS_SetTVMode(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, PSIS_HW_INFO HwInfo);
-void   SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, PSIS_HW_INFO HwInfo);
-USHORT SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
-                USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo);
-USHORT SiS_GetResInfo(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex);
-void   SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
-BOOLEAN        SiS_SetCRT2Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo);
-void   SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
-void   SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
+void           SiS_UnLockCRT2(struct SiS_Private *SiS_Pr);
+#ifndef SIS_LINUX_KERNEL
+void           SiS_LockCRT2(struct SiS_Private *SiS_Pr);
+#endif
+void           SiS_EnableCRT2(struct SiS_Private *SiS_Pr);
+unsigned short SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex);
+void           SiS_WaitRetrace1(struct SiS_Private *SiS_Pr);
+BOOLEAN                SiS_IsDualEdge(struct SiS_Private *SiS_Pr);
+BOOLEAN                SiS_IsVAMode(struct SiS_Private *SiS_Pr);
+void           SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+                       unsigned short ModeIdIndex, int checkcrt2mode);
+void           SiS_SetYPbPr(struct SiS_Private *SiS_Pr);
+void           SiS_SetTVMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+                       unsigned short ModeIdIndex);
+void           SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+               unsigned short ModeIdIndex);
+unsigned short SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
+                       unsigned short RefreshRateTableIndex);
+unsigned short SiS_GetResInfo(struct SiS_Private *SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex);
+void           SiS_DisableBridge(struct SiS_Private *SiS_Pr);
+#ifndef SIS_LINUX_KERNEL
+void           SiS_EnableBridge(struct SiS_Private *SiS_Pr);
+#endif
+BOOLEAN                SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo);
+void           SiS_SiS30xBLOn(struct SiS_Private *SiS_Pr);
+void           SiS_SiS30xBLOff(struct SiS_Private *SiS_Pr);
 
-void           SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempax);
-USHORT         SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempax);
-void           SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempax);
-USHORT         SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempax);
-void           SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, USHORT tempax,USHORT tempbh);
+void           SiS_SetCH700x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);
+unsigned short SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short tempax);
+void           SiS_SetCH701x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);
+unsigned short SiS_GetCH701x(struct SiS_Private *SiS_Pr, unsigned short tempax);
+#ifndef SIS_LINUX_KERNEL
+void           SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);
+unsigned short SiS_GetCH70xx(struct SiS_Private *SiS_Pr, unsigned short tempax);
+#endif
+void           SiS_SetCH70xxANDOR(struct SiS_Private *SiS_Pr, unsigned short reg,
+                       unsigned char orval,unsigned short andval);
 #ifdef SIS315H
-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);
+static void    SiS_Chrontel701xOn(struct SiS_Private *SiS_Pr);
+static void    SiS_Chrontel701xOff(struct SiS_Private *SiS_Pr);
+static void    SiS_ChrontelInitTVVSync(struct SiS_Private *SiS_Pr);
+static void    SiS_ChrontelDoSomething1(struct SiS_Private *SiS_Pr);
+void           SiS_Chrontel701xBLOn(struct SiS_Private *SiS_Pr);
+void           SiS_Chrontel701xBLOff(struct SiS_Private *SiS_Pr);
 #endif /* 315 */
 
 #ifdef SIS300
-#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);
+static  BOOLEAN        SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr);
+void           SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo);
 #endif
 
-void    SiS_DDC2Delay(SiS_Private *SiS_Pr, USHORT delaytime);
-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
+void           SiS_DDC2Delay(struct SiS_Private *SiS_Pr, unsigned int delaytime);
+unsigned short SiS_ReadDDC1Bit(struct SiS_Private *SiS_Pr);
+unsigned short SiS_HandleDDC(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
+                       unsigned short adaptnum, unsigned short DDCdatatype,
+                       unsigned char *buffer, unsigned int VBFlags2);
 
-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 SIS_XORG_XF86
+unsigned short         SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags,
+                               int VGAEngine, unsigned short adaptnum, unsigned short DDCdatatype,
+                               BOOLEAN checkcr32, unsigned int VBFlags2);
+unsigned short         SiS_ProbeDDC(struct SiS_Private *SiS_Pr);
+unsigned short         SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype,
+                               unsigned char *buffer);
+#else
+static unsigned short  SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags,
+                               int VGAEngine, unsigned short adaptnum, unsigned short DDCdatatype,
+                               BOOLEAN checkcr32, unsigned int VBFlags2);
+static unsigned short  SiS_ProbeDDC(struct SiS_Private *SiS_Pr);
+static unsigned short  SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype,
+                               unsigned char *buffer);
+#endif
+static void            SiS_SetSwitchDDC2(struct SiS_Private *SiS_Pr);
+static unsigned short  SiS_SetStart(struct SiS_Private *SiS_Pr);
+static unsigned short  SiS_SetStop(struct SiS_Private *SiS_Pr);
+static unsigned short  SiS_SetSCLKLow(struct SiS_Private *SiS_Pr);
+static unsigned short  SiS_SetSCLKHigh(struct SiS_Private *SiS_Pr);
+static unsigned short  SiS_ReadDDC2Data(struct SiS_Private *SiS_Pr);
+static unsigned short  SiS_WriteDDC2Data(struct SiS_Private *SiS_Pr, unsigned short tempax);
+static unsigned short  SiS_CheckACK(struct SiS_Private *SiS_Pr);
+static unsigned short  SiS_WriteDABDDC(struct SiS_Private *SiS_Pr);
+static unsigned short  SiS_PrepareReadDDC(struct SiS_Private *SiS_Pr);
+static unsigned short  SiS_PrepareDDC(struct SiS_Private *SiS_Pr);
+static void            SiS_SendACK(struct SiS_Private *SiS_Pr, unsigned short yesno);
+static unsigned short  SiS_DoProbeDDC(struct SiS_Private *SiS_Pr);
 
+#ifdef SIS300
+static void            SiS_OEM300Setting(struct SiS_Private *SiS_Pr,
+                               unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefTabindex);
+static void            SetOEMLCDData2(struct SiS_Private *SiS_Pr,
+                               unsigned short ModeNo, unsigned short ModeIdIndex,unsigned short RefTableIndex);
+#endif
 #ifdef SIS315H
-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);
+static void            SiS_OEM310Setting(struct SiS_Private *SiS_Pr,
+                               unsigned short ModeNo,unsigned short ModeIdIndex, unsigned short RRTI);
+static void            SiS_OEM661Setting(struct SiS_Private *SiS_Pr,
+                               unsigned short ModeNo,unsigned short ModeIdIndex, unsigned short RRTI);
+static void            SiS_FinalizeLCD(struct SiS_Private *, unsigned short, unsigned short);
 #endif
+
+extern void            SiS_SetReg(SISIOADDRESS, unsigned short, unsigned short);
+extern void            SiS_SetRegByte(SISIOADDRESS, unsigned short);
+extern void            SiS_SetRegShort(SISIOADDRESS, unsigned short);
+extern void            SiS_SetRegLong(SISIOADDRESS, unsigned int);
+extern unsigned char   SiS_GetReg(SISIOADDRESS, unsigned short);
+extern unsigned char   SiS_GetRegByte(SISIOADDRESS);
+extern unsigned short  SiS_GetRegShort(SISIOADDRESS);
+extern unsigned int    SiS_GetRegLong(SISIOADDRESS);
+extern void            SiS_SetRegANDOR(SISIOADDRESS, unsigned short, unsigned short, unsigned short);
+extern void            SiS_SetRegOR(SISIOADDRESS, unsigned short, unsigned short);
+extern void            SiS_SetRegAND(SISIOADDRESS, unsigned short, unsigned short);
+extern void            SiS_DisplayOff(struct SiS_Private *SiS_Pr);
+extern void            SiS_DisplayOn(struct SiS_Private *SiS_Pr);
+extern BOOLEAN         SiS_SearchModeID(struct SiS_Private *, unsigned short *, unsigned short *);
+extern unsigned short  SiS_GetModeFlag(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+                               unsigned short ModeIdIndex);
+extern unsigned short  SiS_GetModePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex);
+extern unsigned short  SiS_GetColorDepth(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex);
+extern unsigned short  SiS_GetOffset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
+                               unsigned short RefreshRateTableIndex);
+extern void            SiS_LoadDAC(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+                               unsigned short ModeIdIndex);
+extern void            SiS_CalcLCDACRT1Timing(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+                               unsigned short ModeIdIndex);
+extern void            SiS_CalcCRRegisters(struct SiS_Private *SiS_Pr, int depth);
+extern unsigned short  SiS_GetRefCRTVCLK(struct SiS_Private *SiS_Pr, unsigned short Index, int UseWide);
+extern unsigned short  SiS_GetRefCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short Index, int UseWide);
 #ifdef SIS300
-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);
+extern void            SiS_GetFIFOThresholdIndex300(struct SiS_Private *SiS_Pr, unsigned short *tempbx,
+                               unsigned short *tempcl);
+extern unsigned short  SiS_GetFIFOThresholdB300(unsigned short tempbx, unsigned short tempcl);
+extern unsigned short  SiS_GetLatencyFactor630(struct SiS_Private *SiS_Pr, unsigned short index);
+#ifdef SIS_LINUX_KERNEL
+extern unsigned int    sisfb_read_nbridge_pci_dword(struct SiS_Private *SiS_Pr, int reg);
+extern unsigned int    sisfb_read_lpc_pci_dword(struct SiS_Private *SiS_Pr, int reg);
 #endif
-
-extern void     SiS_SetReg(SISIOADDRESS, USHORT, USHORT);
-extern void     SiS_SetRegByte(SISIOADDRESS, USHORT);
-extern void     SiS_SetRegShort(SISIOADDRESS, USHORT);
-extern void     SiS_SetRegLong(SISIOADDRESS, ULONG);
-extern UCHAR    SiS_GetReg(SISIOADDRESS, USHORT);
-extern UCHAR    SiS_GetRegByte(SISIOADDRESS);
-extern USHORT   SiS_GetRegShort(SISIOADDRESS);
-extern ULONG    SiS_GetRegLong(SISIOADDRESS);
-extern void     SiS_SetRegANDOR(SISIOADDRESS, 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);
-#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
index 55a82d6..264b55a 100644 (file)
@@ -3,7 +3,7 @@
 /*
  * Global definitions for init.c and init301.c
  *
- * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
  *
  * If distributed as part of the Linux kernel, the following license terms
  * apply:
 #ifndef _INITDEF_
 #define _INITDEF_
 
-#define IS_SIS330              (HwInfo->jChipType == SIS_330)
-#define IS_SIS550              (HwInfo->jChipType == SIS_550)
-#define IS_SIS650              (HwInfo->jChipType == SIS_650)  /* All versions, incl 651, M65x */
-#define IS_SIS740              (HwInfo->jChipType == SIS_740)
+#define IS_SIS330              (SiS_Pr->ChipType == SIS_330)
+#define IS_SIS550              (SiS_Pr->ChipType == SIS_550)
+#define IS_SIS650              (SiS_Pr->ChipType == SIS_650)  /* All versions, incl 651, M65x */
+#define IS_SIS740              (SiS_Pr->ChipType == SIS_740)
 #define IS_SIS651              (SiS_Pr->SiS_SysFlags & (SF_Is651 | SF_Is652))
 #define IS_SISM650             (SiS_Pr->SiS_SysFlags & (SF_IsM650 | SF_IsM652 | SF_IsM653))
 #define IS_SIS65x               (IS_SIS651 || IS_SISM650)       /* Only special versions of 65x */
-#define IS_SIS661              (HwInfo->jChipType == SIS_661)
-#define IS_SIS741              (HwInfo->jChipType == SIS_741)
-#define IS_SIS660              (HwInfo->jChipType == SIS_660)
-#define IS_SIS760              (HwInfo->jChipType == SIS_760)
-#define IS_SIS661741660760     (IS_SIS661 || IS_SIS741 || IS_SIS660 || IS_SIS760)
-#define IS_SIS650740            ((HwInfo->jChipType >= SIS_650) && (HwInfo->jChipType < SIS_330))
+#define IS_SIS661              (SiS_Pr->ChipType == SIS_661)
+#define IS_SIS741              (SiS_Pr->ChipType == SIS_741)
+#define IS_SIS660              (SiS_Pr->ChipType == SIS_660)
+#define IS_SIS760              (SiS_Pr->ChipType == SIS_760)
+#define IS_SIS761              (SiS_Pr->ChipType == SIS_761)
+#define IS_SIS661741660760     (IS_SIS661 || IS_SIS741 || IS_SIS660 || IS_SIS760 || IS_SIS761)
+#define IS_SIS650740            ((SiS_Pr->ChipType >= SIS_650) && (SiS_Pr->ChipType < SIS_330))
 #define IS_SIS550650740         (IS_SIS550 || IS_SIS650740)
 #define IS_SIS650740660         (IS_SIS650 || IS_SIS740 || IS_SIS661741660760)
 #define IS_SIS550650740660      (IS_SIS550 || IS_SIS650740660)
 #define SISGETROMW(x)          (ROMAddr[(x)] | (ROMAddr[(x)+1] << 8))
 
 /* SiS_VBType */
-#define VB_SIS301              0x0001
-#define VB_SIS301B             0x0002
-#define VB_SIS302B             0x0004
-#define VB_SIS301LV            0x0008
-#define VB_SIS302LV            0x0010
+#define VB_SIS301              0x0001
+#define VB_SIS301B             0x0002
+#define VB_SIS302B             0x0004
+#define VB_SIS301LV            0x0008
+#define VB_SIS302LV            0x0010
 #define VB_SIS302ELV           0x0020
-#define VB_SIS301C              0x0040
+#define VB_SIS301C             0x0040
+#define VB_SIS307T             0x0080
+#define VB_SIS307LV            0x0100
 #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)
-#define VB_SIS301LV302LV        (VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)
-#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)
+#define VB_SIS30xB             (VB_SIS301B | VB_SIS301C | VB_SIS302B | VB_SIS307T)
+#define VB_SIS30xC             (VB_SIS301C | VB_SIS307T)
+#define VB_SISTMDS             (VB_SIS301 | VB_SIS301B | VB_SIS301C | VB_SIS302B | VB_SIS307T)
+#define VB_SISLVDS             (VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV | VB_SIS307LV)
+#define VB_SIS30xBLV           (VB_SIS30xB | VB_SISLVDS)
+#define VB_SIS30xCLV           (VB_SIS30xC | VB_SIS302ELV | VB_SIS307LV)
+#define VB_SISVB               (VB_SIS301 | VB_SIS30xBLV)
+#define VB_SISLCDA             (VB_SIS302B | VB_SIS301C  | VB_SIS307T  | VB_SISLVDS)
+#define VB_SISTMDSLCDA         (VB_SIS301C | VB_SIS307T)
+#define VB_SISPART4SCALER      (VB_SIS301C | VB_SIS307T | VB_SIS302ELV | VB_SIS307LV)
+#define VB_SISHIVISION         (VB_SIS301 | VB_SIS301B | VB_SIS302B)
+#define VB_SISYPBPR            (VB_SIS301C | VB_SIS307T  | VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV | VB_SIS307LV)
+#define VB_SISTAP4SCALER       (VB_SIS301C | VB_SIS307T | VB_SIS302ELV | VB_SIS307LV)
+#define VB_SISPART4OVERFLOW    (VB_SIS301C | VB_SIS307T | VB_SIS302LV | VB_SIS302ELV | VB_SIS307LV)
+#define VB_SISPWD              (VB_SIS301C | VB_SIS307T | VB_SISLVDS)
+#define VB_SISEMI              (VB_SIS302LV | VB_SIS302ELV | VB_SIS307LV)
+#define VB_SISPOWER            (VB_SIS301C | VB_SIS307T | VB_SIS302LV | VB_SIS302ELV | VB_SIS307LV)
+#define VB_SISDUALLINK         (VB_SIS302LV | VB_SIS302ELV | VB_SIS307T | VB_SIS307LV)
+#define VB_SISVGA2             VB_SISTMDS
+#define VB_SISRAMDAC202                (VB_SIS301C | VB_SIS307T)
 
 /* VBInfo */
 #define SetSimuScanMode         0x0001   /* CR 30 */
 #define SupportRAMDAC2_202      0x0400  /* C             (<= 202Mhz) */
 #define InterlaceMode           0x0080
 #define SyncPP                  0x0000
+#define HaveWideTiming         0x2000  /* Have specific wide- and non-wide timing */
 #define SyncPN                  0x4000
 #define SyncNP                  0x8000
 #define SyncNN                  0xc000
 #define TVSetTVSimuMode                0x0200 /* new 0x200, prev. 0x800 */
 #define TVRPLLDIV2XO           0x0400 /* prev 0x1000 */
 #define TVSetNTSC1024          0x0800 /* new 0x100, prev. 0x2000 */
+#define TVSet525p1024          0x1000 /* TW */
 #define TVAspect43             0x2000
 #define TVAspect169            0x4000
 #define TVAspect43LB           0x8000
 #define SF_IsM661              0x0020
 #define SF_IsM741              0x0040
 #define SF_IsM760              0x0080
-#define SF_760LFB              0x8000  /* 760: We have LFB */
+#define SF_760UMA              0x4000  /* 76x: We have UMA */
+#define SF_760LFB              0x8000  /* 76x: We have LFB */
 
 /* CR32 (Newer 630, and 315 series)
 
 #define TVOverScanShift         4
 
 /* CR35 (661 series only)
-
    [0]    1 = PAL, 0 = NTSC
    [1]    1 = NTSC-J (if D0 = 0)
    [2]    1 = PALM (if D0 = 1)
    [3]    1 = PALN (if D0 = 1)
    [4]    1 = Overscan (Chrontel only)
    [7:5]  (only if D2 in CR38 is set)
-          000  525i
-         001  525p
+         000  525i
+         001  525p
          010  750p
          011  1080i (or HiVision on 301, 301B)
-
-   These bits are being translated to TVMode flag.
-
 */
 
-/*
-   CR37
-
+/* CR37
    [0]   Set 24/18 bit (0/1) RGB to LVDS/TMDS transmitter (set by BIOS)
    [3:1] External chip
          300 series:
            010   LVDS
            011   LVDS + Chrontel 7019
          660 series [2:1] only:
-            reserved (now in CR38)
+            reserved (chip type now in CR38)
          All other combinations reserved
    [3]    661 only: Pass 1:1 data
    [4]    LVDS: 0: Panel Link expands / 1: Panel Link does not expand
 #define Enable302LV_DualLink    0x04   /* 302LV only; enable dual link */
 
 /* CR39 (661 and later)
+   D[7]   LVDS (SiS or third party)
    D[1:0] YPbPr Aspect Ratio
           00 4:3 letterbox
          01 4:3
         0101 Set Contrast event
         0110 Set Mute event
         0111 Set Volume Up/Down event
-   [4]   Enable Backlight Control by BIOS/driver 
+   [4]   Enable Backlight Control by BIOS/driver
          (set by driver; set means that the BIOS should
         not touch the backlight registers because eg.
         the driver already switched off the backlight)
    [7]   TV UnderScan/OverScan (set by BIOS)
 */
 
+/* CR7C - 661 and later
+   [7]   DualEdge enabled (or: to be enabled)
+   [6]   CRT2 = TV/LCD/VGA enabled (or: to be enabled)
+   [5]   Init done (set at end of SiS_Init)
+   {4]   LVDS LCD capabilities
+   [3]   LVDS LCD capabilities
+   [2]   LVDS LCD capabilities (PWD)
+   [1]   LVDS LCD capabilities (PWD)
+   [0]   LVDS=1, TMDS=0 (SiS or third party)
+*/
+
+/* CR7E - 661 and later
+   VBType:
+   [7] LVDS (third party)
+   [3] 301C
+   [2] 302LV
+   [1] 301LV
+   [0] 301B
+*/
+
 /* LCDResInfo */
 #define Panel300_800x600        0x01   /* CR36 */
 #define Panel300_1024x768       0x02
 #define Panel300_1024x600       0x06
 #define Panel300_1152x768       0x07
 #define Panel300_1280x768       0x0a
-#define Panel300_320x480        0x0e   /* fstn - This is fake, can be any */
 #define Panel300_Custom                0x0f
 #define Panel300_Barco1366      0x10
 
 #define Panel310_1400x1050      0x09
 #define Panel310_1280x768       0x0a
 #define Panel310_1600x1200      0x0b
-#define Panel310_640x480_2      0x0c
-#define Panel310_640x480_3      0x0d
-#define Panel310_320x480        0x0e    /* fstn - TW: This is fake, can be any */
+#define Panel310_320x240_2      0x0c    /* xSTN */
+#define Panel310_320x240_3      0x0d    /* xSTN */
+#define Panel310_320x240_1      0x0e    /* xSTN - This is fake, can be any */
 #define Panel310_Custom                0x0f
 
 #define Panel661_800x600        0x01
 #define Panel661_1024x600       0x05
 #define Panel661_1152x864       0x06
 #define Panel661_1280x960       0x07
-#define Panel661_1152x768       0x08
+#define Panel661_1280x854       0x08
 #define Panel661_1400x1050      0x09
 #define Panel661_1280x768       0x0a
 #define Panel661_1600x1200      0x0b
 #define Panel_1680x1050         0x0d    /* 661etc  */
 #define Panel_1280x720         0x0e    /* 661etc  */
 #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_320x240_1         0x10    /* SiS 550 xSTN */
 #define Panel_Barco1366         0x11
 #define Panel_848x480          0x12
-#define Panel_640x480_2                0x13    /* SiS 550 */
-#define Panel_640x480_3                0x14    /* SiS 550 */
+#define Panel_320x240_2                0x13    /* SiS 550 xSTN */
+#define Panel_320x240_3                0x14    /* SiS 550 xSTN */
 #define Panel_1280x768_2        0x15   /* 30xLV */
 #define Panel_1280x768_3        0x16    /* (unused) */
 #define Panel_1280x800_2       0x17    /* 30xLV */
+#define Panel_856x480          0x18
+#define Panel_1280x854         0x19    /* 661etc */
 
 /* Index in ModeResInfo table */
 #define SIS_RI_320x200    0
 #define SIS_RI_1920x1080 31
 #define SIS_RI_960x540   32
 #define SIS_RI_960x600   33
+#define SIS_RI_1280x854  34
 
 /* CR5F */
 #define IsM650                  0x80
 #define VCLK100_300             0x43   /* Index in VCLKData table (300) */
 #define VCLK34_300              0x3d   /* Index in VCLKData table (300) */
 #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) */
-#define VCLK162_315             0x5e   /* Index in (VB)VCLKData table (315) */
-#define VCLK108_3_315           0x45   /* Index in VBVCLKData table (315) */
-#define VCLK100_315             0x46   /* Index in VBVCLKData table (315) */
+
+#define VCLK65_315              0x0b   /* Indices in (VB)VCLKData table (315) */
+#define VCLK108_2_315           0x19
+#define VCLK81_315             0x5b
+#define VCLK162_315             0x5e
+#define VCLK108_3_315           0x45
+#define VCLK100_315             0x46
 #define VCLK34_315              0x55
 #define VCLK68_315             0x0d
-#define VCLK_1280x800_315_2    0x5c   /* Index in VBVCLKData table (315) */
-#define VCLK121_315            0x5d   /* Index in VBVCLKData table (315) */
+#define VCLK_1280x800_315_2    0x5c
+#define VCLK121_315            0x5d
+#define VCLK130_315            0x72
 #define VCLK_1280x720          0x5f
 #define VCLK_1280x768_2                0x60
 #define VCLK_1280x768_3                0x61   /* (unused?) */
 #define VCLK_1152x864          0x64
 #define VCLK_1360x768          0x58
 #define VCLK_1280x800_315      0x6c
+#define VCLK_1280x854          0x76
 
 #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 --git a/drivers/video/sis/initextlfb.c b/drivers/video/sis/initextlfb.c
new file mode 100644 (file)
index 0000000..cc856d9
--- /dev/null
@@ -0,0 +1,238 @@
+/*
+ * SiS 300/540/630[S]/730[S]
+ * SiS 315[E|PRO]/550/[M]65x/[M]66x[F|M|G]X/[M]74x[GX]/330/[M]76x[GX]
+ * XGI V3XT/V5/V8, Z7
+ * frame buffer driver for Linux kernels >= 2.4.14 and >=2.6.3
+ *
+ * Linux kernel specific extensions to init.c/init301.c
+ *
+ * Copyright (C) 2001-2005 Thomas Winischhofer, Vienna, Austria.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the named License,
+ * or any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Author:     Thomas Winischhofer <thomas@winischhofer.net>
+ */
+
+#include "osdef.h"
+#include "initdef.h"
+#include "vgatypes.h"
+#include "vstruct.h"
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/fb.h>
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+int            sisfb_mode_rate_to_dclock(struct SiS_Private *SiS_Pr,
+                       unsigned char modeno, unsigned char rateindex);
+int            sisfb_mode_rate_to_ddata(struct SiS_Private *SiS_Pr, unsigned char modeno,
+                       unsigned char rateindex, struct fb_var_screeninfo *var);
+#endif
+BOOLEAN                sisfb_gettotalfrommode(struct SiS_Private *SiS_Pr, unsigned char modeno,
+                       int *htotal, int *vtotal, unsigned char rateindex);
+
+extern BOOLEAN SiSInitPtr(struct SiS_Private *SiS_Pr);
+extern BOOLEAN SiS_SearchModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo,
+                       unsigned short *ModeIdIndex);
+extern void    SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata,
+                       int xres, int yres, struct fb_var_screeninfo *var, BOOLEAN writeres);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+int
+sisfb_mode_rate_to_dclock(struct SiS_Private *SiS_Pr, unsigned char modeno,
+                       unsigned char rateindex)
+{
+    unsigned short ModeNo = modeno;
+    unsigned short ModeIdIndex = 0, ClockIndex = 0;
+    unsigned short RRTI = 0;
+    int Clock;
+
+    if(!SiSInitPtr(SiS_Pr)) return 65000;
+
+    if(rateindex > 0) rateindex--;
+
+#ifdef SIS315H
+    switch(ModeNo) {
+    case 0x5a: ModeNo = 0x50; break;
+    case 0x5b: ModeNo = 0x56;
+    }
+#endif
+
+    if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) {;
+       printk(KERN_ERR "Could not find mode %x\n", ModeNo);
+       return 65000;
+    }
+
+    RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
+
+    if(SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag & HaveWideTiming) {
+       if(SiS_Pr->SiS_UseWide == 1) {
+         /* Wide screen: Ignore rateindex */
+         ClockIndex = SiS_Pr->SiS_RefIndex[RRTI].Ext_CRTVCLK_WIDE;
+       } else {
+         RRTI += rateindex;
+         ClockIndex = SiS_Pr->SiS_RefIndex[RRTI].Ext_CRTVCLK_NORM;
+       }
+    } else {
+       RRTI += rateindex;
+       ClockIndex = SiS_Pr->SiS_RefIndex[RRTI].Ext_CRTVCLK;
+    }
+
+    Clock = SiS_Pr->SiS_VCLKData[ClockIndex].CLOCK * 1000;
+
+    return Clock;
+}
+
+int
+sisfb_mode_rate_to_ddata(struct SiS_Private *SiS_Pr, unsigned char modeno,
+                       unsigned char rateindex, struct fb_var_screeninfo *var)
+{
+    unsigned short ModeNo = modeno;
+    unsigned short ModeIdIndex = 0, index = 0, RRTI = 0;
+    int            j;
+
+    if(!SiSInitPtr(SiS_Pr)) return 0;
+
+    if(rateindex > 0) rateindex--;
+
+#ifdef SIS315H
+    switch(ModeNo) {
+       case 0x5a: ModeNo = 0x50; break;
+       case 0x5b: ModeNo = 0x56;
+    }
+#endif
+
+    if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return 0;
+
+    RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
+    if(SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag & HaveWideTiming) {
+       if(SiS_Pr->SiS_UseWide == 1) {
+         /* Wide screen: Ignore rateindex */
+         index = SiS_Pr->SiS_RefIndex[RRTI].Ext_CRT1CRTC_WIDE;
+       } else {
+         RRTI += rateindex;
+         index = SiS_Pr->SiS_RefIndex[RRTI].Ext_CRT1CRTC_NORM;
+       }
+    } else {
+       RRTI += rateindex;
+       index = SiS_Pr->SiS_RefIndex[RRTI].Ext_CRT1CRTC;
+    }
+
+    SiS_Generic_ConvertCRData(SiS_Pr,
+                       (unsigned char *)&SiS_Pr->SiS_CRT1Table[index].CR[0],
+                       SiS_Pr->SiS_RefIndex[RRTI].XRes,
+                       SiS_Pr->SiS_RefIndex[RRTI].YRes,
+                       var, FALSE);
+
+    if(SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag & 0x8000)
+       var->sync &= ~FB_SYNC_VERT_HIGH_ACT;
+    else
+       var->sync |= FB_SYNC_VERT_HIGH_ACT;
+
+    if(SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag & 0x4000)
+       var->sync &= ~FB_SYNC_HOR_HIGH_ACT;
+    else
+       var->sync |= FB_SYNC_HOR_HIGH_ACT;
+
+    var->vmode = FB_VMODE_NONINTERLACED;
+    if(SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag & 0x0080)
+       var->vmode = FB_VMODE_INTERLACED;
+    else {
+       j = 0;
+       while(SiS_Pr->SiS_EModeIDTable[j].Ext_ModeID != 0xff) {
+         if(SiS_Pr->SiS_EModeIDTable[j].Ext_ModeID ==
+                         SiS_Pr->SiS_RefIndex[RRTI].ModeID) {
+             if(SiS_Pr->SiS_EModeIDTable[j].Ext_ModeFlag & DoubleScanMode) {
+                 var->vmode = FB_VMODE_DOUBLE;
+             }
+             break;
+         }
+         j++;
+       }
+    }
+
+    if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
+#if 0  /* Do this? */
+       var->upper_margin <<= 1;
+       var->lower_margin <<= 1;
+       var->vsync_len <<= 1;
+#endif
+    } else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
+       var->upper_margin >>= 1;
+       var->lower_margin >>= 1;
+       var->vsync_len >>= 1;
+    }
+
+    return 1;
+}
+#endif /* Linux >= 2.5 */
+
+BOOLEAN
+sisfb_gettotalfrommode(struct SiS_Private *SiS_Pr, unsigned char modeno, int *htotal,
+                       int *vtotal, unsigned char rateindex)
+{
+    unsigned short ModeNo = modeno;
+    unsigned short ModeIdIndex = 0, CRT1Index = 0;
+    unsigned short RRTI = 0;
+    unsigned char  sr_data, cr_data, cr_data2;
+
+    if(!SiSInitPtr(SiS_Pr)) return FALSE;
+
+    if(rateindex > 0) rateindex--;
+
+#ifdef SIS315H
+    switch(ModeNo) {
+       case 0x5a: ModeNo = 0x50; break;
+       case 0x5b: ModeNo = 0x56;
+    }
+#endif
+
+    if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return FALSE;
+
+    RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
+    if(SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag & HaveWideTiming) {
+       if(SiS_Pr->SiS_UseWide == 1) {
+         /* Wide screen: Ignore rateindex */
+         CRT1Index = SiS_Pr->SiS_RefIndex[RRTI].Ext_CRT1CRTC_WIDE;
+       } else {
+         RRTI += rateindex;
+         CRT1Index = SiS_Pr->SiS_RefIndex[RRTI].Ext_CRT1CRTC_NORM;
+       }
+    } else {
+       RRTI += rateindex;
+       CRT1Index = SiS_Pr->SiS_RefIndex[RRTI].Ext_CRT1CRTC;
+    }
+
+    sr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
+    cr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[0];
+    *htotal = (((cr_data & 0xff) | ((unsigned short) (sr_data & 0x03) << 8)) + 5) * 8;
+
+    sr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
+    cr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[6];
+    cr_data2 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
+    *vtotal = ((cr_data & 0xFF) |
+              ((unsigned short)(cr_data2 & 0x01) <<  8) |
+              ((unsigned short)(cr_data2 & 0x20) <<  4) |
+              ((unsigned short)(sr_data  & 0x01) << 10)) + 2;
+
+    if(SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag & InterlaceMode)
+       *vtotal *= 2;
+
+    return TRUE;
+}
+
+
+
index b1358b7..b73f268 100644 (file)
@@ -3,7 +3,7 @@
 /*
  * OEM Data for 300 series
  *
- * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
  *
  * If distributed as part of the Linux kernel, the following license terms
  * apply:
@@ -50,7 +50,7 @@
  *
  */
 
-static const UCHAR SiS300_OEMTVDelay301[8][4] =
+static const unsigned char SiS300_OEMTVDelay301[8][4] =
 {
        {0x08,0x08,0x08,0x08},
        {0x08,0x08,0x08,0x08},
@@ -62,7 +62,7 @@ static const UCHAR SiS300_OEMTVDelay301[8][4] =
        {0x20,0x20,0x20,0x20}
 };
 
-static const UCHAR SiS300_OEMTVDelayLVDS[8][4] =
+static const unsigned char SiS300_OEMTVDelayLVDS[8][4] =
 {
        {0x20,0x20,0x20,0x20},
        {0x20,0x20,0x20,0x20},
@@ -74,7 +74,7 @@ static const UCHAR SiS300_OEMTVDelayLVDS[8][4] =
        {0x20,0x20,0x20,0x20}
 };
 
-static const UCHAR SiS300_OEMTVFlicker[8][4] =
+static const unsigned char SiS300_OEMTVFlicker[8][4] =
 {
        {0x00,0x00,0x00,0x00},
        {0x00,0x00,0x00,0x00},
@@ -86,25 +86,7 @@ static const UCHAR SiS300_OEMTVFlicker[8][4] =
        {0x00,0x00,0x00,0x00}
 };
 
-#if 0   /* TW: Not used */
-static const UCHAR SiS300_OEMLCDDelay1[12][4]={
-       {0x2c,0x2c,0x2c,0x2c},
-       {0x20,0x20,0x20,0x20},
-       {0x20,0x20,0x20,0x20},
-       {0x2c,0x2c,0x2c,0x2c},
-       {0x2c,0x2c,0x2c,0x2c},
-       {0x20,0x20,0x20,0x20},
-       {0x20,0x20,0x20,0x20},
-       {0x24,0x24,0x24,0x24},
-       {0x24,0x24,0x24,0x24},
-       {0x20,0x20,0x20,0x20},
-       {0x20,0x20,0x20,0x20},
-       {0x24,0x24,0x24,0x24}
-};
-#endif
-
-/* From 630/301B BIOS */
-static const UCHAR SiS300_OEMLCDDelay2[64][4] =                 /* for 301/301b/302b/301LV/302LV */
+static const unsigned char SiS300_OEMLCDDelay2[64][4] =                 /* for 301/301b/302b/301LV/302LV */
 {
        {0x20,0x20,0x20,0x20},
        {0x20,0x20,0x20,0x20},
@@ -172,8 +154,7 @@ static const UCHAR SiS300_OEMLCDDelay2[64][4] =              /* for 301/301b/302b/301LV/302
        {0x20,0x20,0x20,0x20}
 };
 
-/* From 300/301LV BIOS */
-static const UCHAR SiS300_OEMLCDDelay4[12][4] =
+static const unsigned char SiS300_OEMLCDDelay4[12][4] =
 {
        {0x2c,0x2c,0x2c,0x2c},
        {0x20,0x20,0x20,0x20},
@@ -189,8 +170,7 @@ static const UCHAR SiS300_OEMLCDDelay4[12][4] =
        {0x24,0x24,0x24,0x24}
 };
 
-/* From 300/301LV BIOS */
-static const UCHAR SiS300_OEMLCDDelay5[32][4] =
+static const unsigned char SiS300_OEMLCDDelay5[32][4] =
 {
        {0x20,0x20,0x20,0x20},
        {0x20,0x20,0x20,0x20},
@@ -226,8 +206,8 @@ static const UCHAR SiS300_OEMLCDDelay5[32][4] =
        {0x20,0x20,0x20,0x20},
 };
 
-/* Added for LVDS */
-static const UCHAR SiS300_OEMLCDDelay3[64][4] = {      /* For LVDS */
+static const unsigned char SiS300_OEMLCDDelay3[64][4] =                /* For LVDS */
+{
        {0x20,0x20,0x20,0x20},
        {0x20,0x20,0x20,0x20},
        {0x20,0x20,0x20,0x20},
@@ -294,7 +274,7 @@ static const UCHAR SiS300_OEMLCDDelay3[64][4] = {   /* For LVDS */
        {0x20,0x20,0x20,0x20}
 };
 
-static const UCHAR SiS300_Phase1[8][5][4] =
+static const unsigned char SiS300_Phase1[8][5][4] =
 {
     {
        {0x21,0xed,0x00,0x08},
@@ -354,11 +334,10 @@ static const UCHAR SiS300_Phase1[8][5][4] =
     }
 };
 
-
-static const UCHAR SiS300_Phase2[8][5][4] =
+static const unsigned char SiS300_Phase2[8][5][4] =
 {
     {
-        {0x21,0xed,0x00,0x08},
+       {0x21,0xed,0x00,0x08},
        {0x21,0xed,0x8a,0x08},
        {0x21,0xed,0x8a,0x08},
        {0x21,0xed,0x8a,0x08},
@@ -372,42 +351,42 @@ static const UCHAR SiS300_Phase2[8][5][4] =
        {0x2a,0x05,0xd3,0x00}
     },
     {
-        {0x2a,0x05,0xd3,0x00},
+       {0x2a,0x05,0xd3,0x00},
        {0x2a,0x05,0xd3,0x00},
        {0x2a,0x05,0xd3,0x00},
        {0x2a,0x05,0xd3,0x00},
        {0x2a,0x05,0xd3,0x00}
     },
     {
-        {0x2a,0x05,0xd3,0x00},
+       {0x2a,0x05,0xd3,0x00},
        {0x2a,0x05,0xd3,0x00},
        {0x2a,0x05,0xd3,0x00},
        {0x2a,0x05,0xd3,0x00},
        {0x2a,0x05,0xd3,0x00}
     },
     {
-        {0x21,0xed,0x00,0x08},
+       {0x21,0xed,0x00,0x08},
        {0x21,0xed,0x8a,0x08},
        {0x21,0xed,0x8a,0x08},
        {0x21,0xed,0x8a,0x08},
        {0x21,0xed,0x8a,0x08}
     },
     {
-        {0x2a,0x05,0xd3,0x00},
+       {0x2a,0x05,0xd3,0x00},
        {0x2a,0x05,0xd3,0x00},
        {0x2a,0x05,0xd3,0x00},
        {0x2a,0x05,0xd3,0x00},
        {0x2a,0x05,0xd3,0x00}
     },
     {
-        {0x2a,0x05,0xd3,0x00},
+       {0x2a,0x05,0xd3,0x00},
        {0x2a,0x05,0xd3,0x00},
        {0x2a,0x05,0xd3,0x00},
        {0x2a,0x05,0xd3,0x00},
        {0x2a,0x05,0xd3,0x00}
     },
     {
-        {0x2a,0x05,0xd3,0x00},
+       {0x2a,0x05,0xd3,0x00},
        {0x2a,0x05,0xd3,0x00},
        {0x2a,0x05,0xd3,0x00},
        {0x2a,0x05,0xd3,0x00},
@@ -415,7 +394,7 @@ static const UCHAR SiS300_Phase2[8][5][4] =
     }
 };
 
-static const UCHAR SiS300_Filter1[10][16][4] =
+static const unsigned char SiS300_Filter1[10][16][4] =
 {
     {
        {0x00,0xf4,0x10,0x38},
@@ -599,7 +578,7 @@ static const UCHAR SiS300_Filter1[10][16][4] =
     },
 };
 
-static const UCHAR SiS300_Filter2[10][9][7] =
+static const unsigned char SiS300_Filter2[10][9][7] =
 {
     {
        {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
@@ -714,142 +693,144 @@ static const UCHAR SiS300_Filter2[10][9][7] =
 };
 
 /* Custom data for Barco iQ Pro R300 */
-static const UCHAR barco_p1[2][9][7][3] = {
-    {
-       {  { 0x16, 0xcf, 0x00 },
-          { 0x18, 0x00, 0x00 },
-          { 0x1a, 0xe7, 0x00 },
-          { 0x1b, 0x26, 0x00 },
-          { 0x1c, 0xff, 0x00 },
-          { 0x1d, 0x1c, 0x00 },
-          { 0x1e, 0x19, 0x00 }
-       },
-       {
-          { 0x16, 0xcf, 0x00 },
-          { 0x18, 0x00, 0x00 },
-          { 0x1a, 0xe7, 0x00 },
-          { 0x1b, 0x1e, 0x00 },
-          { 0x1c, 0xff, 0x00 },
-          { 0x1d, 0x1c, 0x00 },
-          { 0x1e, 0x16, 0x00 }
-       },
-       {
-          { 0x16, 0xcf, 0x00 },
-          { 0x1a, 0xe7, 0x00 },
-          { 0x1b, 0x26, 0x00 },
-          { 0x1c, 0xff, 0x00 },
-          { 0x1d, 0x1c, 0x00 },
-          { 0x1e, 0x19, 0x00 },
-          {    0,    0,    0 }
-       },
-       {
-          {    0,    0,    0 }
-       },
-       {
-          { 0x16, 0xcf, 0x00 },
-          { 0x1a, 0xe7, 0x00 },
-          { 0x1b, 0x26, 0x00 },
-          { 0x1c, 0xff, 0x00 },
-          { 0x1d, 0x1c, 0x00 },
-          { 0x1e, 0x1e, 0x00 },
-          {    0,    0,    0 }
-       },
-       {
-          { 0x16, 0xd1, 0x00 },
-          { 0x18, 0x00, 0x00 },
-          { 0x1a, 0xe7, 0x00 },
-          { 0x1b, 0x11, 0x00 },
-          { 0x1c, 0xff, 0x00 },
-          { 0x1d, 0x1c, 0x00 },
-          { 0x1e, 0x26, 0x00 }
-       },
-       {
-          { 0x16, 0xd1, 0x00 },
-          { 0x1a, 0xe7, 0x00 },
-          { 0x1b, 0x26, 0x00 },
-          { 0x1c, 0xff, 0x00 },
-          { 0x1d, 0x1c, 0x00 },
-          { 0x1e, 0x30, 0x00 },
-          {    0,    0,    0 }
-       },
-       {
-          { 0x16, 0x00, 0x00 },
-          { 0x17, 0xa0, 0x00 },
-          { 0x1a, 0xa0, 0x00 },
-          { 0x1b, 0x2a, 0x00 },
-          { 0x1c, 0xff, 0x00 },
-          { 0x1d, 0x1c, 0x00 },
-          {    0,    0,    0 }
-       },
-       {
-          { 0x16, 0x00, 0x00 },
-          { 0x17, 0xaa, 0x00 },
-          { 0x1a, 0xa0, 0x00 },
-          { 0x1b, 0x2a, 0x00 },
-          { 0x1c, 0xff, 0x00 },
-          { 0x1d, 0x1c, 0x00 },
-          {    0,    0,    0 }
-       }
-    },
-    {
-       {
-          { 0x16, 0xcf, 0x00 },
-          { 0x18, 0x00, 0x00 },
-          { 0x1a, 0xe7, 0x00 },
-          { 0x1b, 0x26, 0x00 },
-          { 0x1c, 0xff, 0x00 },
-          { 0x1d, 0x1c, 0x00 },
-          { 0x1e, 0x19, 0x00 }
-       },
-       {
-          {    0,    0,    0 }
-       },
-       {
-          { 0x16, 0xcf, 0x00 },
-          { 0x18, 0x00, 0x00 },
-          { 0x1a, 0xe7, 0x00 },
-          { 0x1b, 0x26, 0x00 },
-          { 0x1c, 0xff, 0x00 },
-          { 0x1d, 0x1c, 0x00 },
-          { 0x1e, 0x19, 0x00 },
-       },
-       {
-          {    0,    0,    0 }
-       },
-       {
-          { 0x16, 0xcf, 0x00 },
-          { 0x18, 0x00, 0x00 },
-          { 0x1a, 0xe7, 0x00 },
-          { 0x1b, 0x26, 0x00 },
-          { 0x1c, 0xff, 0x00 },
-          { 0x1d, 0x1c, 0x00 },
-          { 0x1e, 0x1e, 0x00 }
-       },
-       {
-          { 0x16, 0xd1, 0x00 },
-          { 0x18, 0x00, 0x00 },
-          { 0x1a, 0xe6, 0x00 },
-          { 0x1b, 0x11, 0x00 },
-          { 0x1c, 0xff, 0x00 },
-          { 0x1d, 0x1c, 0x00 },
-          { 0x1e, 0x26, 0x00 }
-       },
-       {
-          { 0x18, 0x00, 0x00 },
-          { 0x1a, 0xe0, 0x00 },
-          { 0x1b, 0x26, 0x00 },
-          { 0x1c, 0xff, 0x00 },
-          { 0x1d, 0x1c, 0x00 },
-          { 0x1e, 0x30, 0x00 },
-          {    0,    0,    0 }
-       },
-       {
-          {    0,    0,    0 }
-       },
-       {
-          {    0,    0,    0 }
-       }
-    }
+static const unsigned char barco_p1[2][9][7][3] =
+{
+  {
+     {
+       { 0x16, 0xcf, 0x00 },
+       { 0x18, 0x00, 0x00 },
+       { 0x1a, 0xe7, 0x00 },
+       { 0x1b, 0x26, 0x00 },
+       { 0x1c, 0xff, 0x00 },
+       { 0x1d, 0x1c, 0x00 },
+       { 0x1e, 0x19, 0x00 }
+     },
+     {
+       { 0x16, 0xcf, 0x00 },
+       { 0x18, 0x00, 0x00 },
+       { 0x1a, 0xe7, 0x00 },
+       { 0x1b, 0x1e, 0x00 },
+       { 0x1c, 0xff, 0x00 },
+       { 0x1d, 0x1c, 0x00 },
+       { 0x1e, 0x16, 0x00 }
+     },
+     {
+       { 0x16, 0xcf, 0x00 },
+       { 0x1a, 0xe7, 0x00 },
+       { 0x1b, 0x26, 0x00 },
+       { 0x1c, 0xff, 0x00 },
+       { 0x1d, 0x1c, 0x00 },
+       { 0x1e, 0x19, 0x00 },
+       {    0,    0,    0 }
+     },
+     {
+       {    0,    0,    0 }
+     },
+     {
+       { 0x16, 0xcf, 0x00 },
+       { 0x1a, 0xe7, 0x00 },
+       { 0x1b, 0x26, 0x00 },
+       { 0x1c, 0xff, 0x00 },
+       { 0x1d, 0x1c, 0x00 },
+       { 0x1e, 0x1e, 0x00 },
+       {    0,    0,    0 }
+     },
+     {
+       { 0x16, 0xd1, 0x00 },
+       { 0x18, 0x00, 0x00 },
+       { 0x1a, 0xe7, 0x00 },
+       { 0x1b, 0x11, 0x00 },
+       { 0x1c, 0xff, 0x00 },
+       { 0x1d, 0x1c, 0x00 },
+       { 0x1e, 0x26, 0x00 }
+     },
+     {
+       { 0x16, 0xd1, 0x00 },
+       { 0x1a, 0xe7, 0x00 },
+       { 0x1b, 0x26, 0x00 },
+       { 0x1c, 0xff, 0x00 },
+       { 0x1d, 0x1c, 0x00 },
+       { 0x1e, 0x30, 0x00 },
+       {    0,    0,    0 }
+     },
+     {
+       { 0x16, 0x00, 0x00 },
+       { 0x17, 0xa0, 0x00 },
+       { 0x1a, 0xa0, 0x00 },
+       { 0x1b, 0x2a, 0x00 },
+       { 0x1c, 0xff, 0x00 },
+       { 0x1d, 0x1c, 0x00 },
+       {    0,    0,    0 }
+     },
+     {
+       { 0x16, 0x00, 0x00 },
+       { 0x17, 0xaa, 0x00 },
+       { 0x1a, 0xa0, 0x00 },
+       { 0x1b, 0x2a, 0x00 },
+       { 0x1c, 0xff, 0x00 },
+       { 0x1d, 0x1c, 0x00 },
+       {    0,    0,    0 }
+     }
+  },
+  {
+     {
+       { 0x16, 0xcf, 0x00 },
+       { 0x18, 0x00, 0x00 },
+       { 0x1a, 0xe7, 0x00 },
+       { 0x1b, 0x26, 0x00 },
+       { 0x1c, 0xff, 0x00 },
+       { 0x1d, 0x1c, 0x00 },
+       { 0x1e, 0x19, 0x00 }
+     },
+     {
+       {    0,    0,    0 }
+     },
+     {
+       { 0x16, 0xcf, 0x00 },
+       { 0x18, 0x00, 0x00 },
+       { 0x1a, 0xe7, 0x00 },
+       { 0x1b, 0x26, 0x00 },
+       { 0x1c, 0xff, 0x00 },
+       { 0x1d, 0x1c, 0x00 },
+       { 0x1e, 0x19, 0x00 },
+     },
+     {
+       {    0,    0,    0 }
+     },
+     {
+       { 0x16, 0xcf, 0x00 },
+       { 0x18, 0x00, 0x00 },
+       { 0x1a, 0xe7, 0x00 },
+       { 0x1b, 0x26, 0x00 },
+       { 0x1c, 0xff, 0x00 },
+       { 0x1d, 0x1c, 0x00 },
+       { 0x1e, 0x1e, 0x00 }
+     },
+     {
+       { 0x16, 0xd1, 0x00 },
+       { 0x18, 0x00, 0x00 },
+       { 0x1a, 0xe6, 0x00 },
+       { 0x1b, 0x11, 0x00 },
+       { 0x1c, 0xff, 0x00 },
+       { 0x1d, 0x1c, 0x00 },
+       { 0x1e, 0x26, 0x00 }
+     },
+     {
+       { 0x18, 0x00, 0x00 },
+       { 0x1a, 0xe0, 0x00 },
+       { 0x1b, 0x26, 0x00 },
+       { 0x1c, 0xff, 0x00 },
+       { 0x1d, 0x1c, 0x00 },
+       { 0x1e, 0x30, 0x00 },
+       {    0,    0,    0 }
+     },
+     {
+       {    0,    0,    0 }
+     },
+     {
+       {    0,    0,    0 }
+     }
+  }
 };
 
 
index 2b7db91..8fce56e 100644 (file)
@@ -1,9 +1,9 @@
 /* $XFree86$ */
 /* $XdotOrg$ */
 /*
- * OEM Data for 315/330 series
+ * OEM Data for 315/330/340 series
  *
- * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
  *
  * If distributed as part of the Linux kernel, the following license terms
  * apply:
  *
  */
 
-static const UCHAR SiS310_LCDDelayCompensation_301[] =                 /* 301 */
+static const unsigned char SiS310_LCDDelayCompensation_301[] =                 /* 301 */
 {
-                0x00,0x00,0x00,    /*   800x600 */
-                0x0b,0x0b,0x0b,    /*  1024x768 */
-                0x08,0x08,0x08,    /* 1280x1024 */
-                0x00,0x00,0x00,    /*   640x480 (unknown) */
-                0x00,0x00,0x00,    /*  1024x600 (unknown) */
-                0x00,0x00,0x00,    /*  1152x864 (unknown) */
-                0x08,0x08,0x08,    /*  1280x960 (guessed) */
-                0x00,0x00,0x00,    /*  1152x768 (unknown) */
-                0x08,0x08,0x08,    /* 1400x1050 */
-                0x08,0x08,0x08,    /*  1280x768  (guessed) */
-                0x00,0x00,0x00,    /* 1600x1200 */
-                0x00,0x00,0x00,    /*   320x480 (unknown) */
-                0x00,0x00,0x00,
-                0x00,0x00,0x00,
-                0x00,0x00,0x00
+       0x00,0x00,0x00,    /*   800x600 */
+       0x0b,0x0b,0x0b,    /*  1024x768 */
+       0x08,0x08,0x08,    /* 1280x1024 */
+       0x00,0x00,0x00,    /*   640x480 (unknown) */
+       0x00,0x00,0x00,    /*  1024x600 (unknown) */
+       0x00,0x00,0x00,    /*  1152x864 (unknown) */
+       0x08,0x08,0x08,    /*  1280x960 (guessed) */
+       0x00,0x00,0x00,    /*  1152x768 (unknown) */
+       0x08,0x08,0x08,    /* 1400x1050 */
+       0x08,0x08,0x08,    /*  1280x768  (guessed) */
+       0x00,0x00,0x00,    /* 1600x1200 */
+       0x00,0x00,0x00,    /*   320x480 (unknown) */
+       0x00,0x00,0x00,
+       0x00,0x00,0x00,
+       0x00,0x00,0x00
 };
 
 /* This is contained in 650+301B BIOSes, but it is wrong - so we don't use it */
-static const UCHAR SiS310_LCDDelayCompensation_650301LV[] =            /* 650 + 30xLV */
+static const unsigned char SiS310_LCDDelayCompensation_650301LV[] =            /* 650 + 30xLV */
 {
-                0x01,0x01,0x01,    /*   800x600 */
-                0x01,0x01,0x01,    /*  1024x768 */
-                0x01,0x01,0x01,    /* 1280x1024 */
-                 0x01,0x01,0x01,    /*   640x480 (unknown) */
-                0x01,0x01,0x01,    /*  1024x600 (unknown) */
-                0x01,0x01,0x01,    /*  1152x864 (unknown) */
-                0x01,0x01,0x01,    /*  1280x960 (guessed) */
-                0x01,0x01,0x01,    /*  1152x768 (unknown) */
-                0x01,0x01,0x01,    /* 1400x1050 */
-                0x01,0x01,0x01,    /*  1280x768  (guessed) */
-                0x01,0x01,0x01,    /* 1600x1200 */
-                0x02,0x02,0x02,
-                0x02,0x02,0x02,
-                0x02,0x02,0x02,
-                0x02,0x02,0x02
+       0x01,0x01,0x01,    /*   800x600 */
+       0x01,0x01,0x01,    /*  1024x768 */
+       0x01,0x01,0x01,    /* 1280x1024 */
+       0x01,0x01,0x01,    /*   640x480 (unknown) */
+       0x01,0x01,0x01,    /*  1024x600 (unknown) */
+       0x01,0x01,0x01,    /*  1152x864 (unknown) */
+       0x01,0x01,0x01,    /*  1280x960 (guessed) */
+       0x01,0x01,0x01,    /*  1152x768 (unknown) */
+       0x01,0x01,0x01,    /* 1400x1050 */
+       0x01,0x01,0x01,    /*  1280x768  (guessed) */
+       0x01,0x01,0x01,    /* 1600x1200 */
+       0x02,0x02,0x02,
+       0x02,0x02,0x02,
+       0x02,0x02,0x02,
+       0x02,0x02,0x02
 };
 
-static const UCHAR SiS310_LCDDelayCompensation_651301LV[] =            /* M650/651 301LV */
+static const unsigned char SiS310_LCDDelayCompensation_651301LV[] =            /* M650/651 301LV */
 {
-                 0x33,0x33,0x33,    /*   800x600 (guessed) - new: PanelType, not PanelRes ! */
-                0x33,0x33,0x33,    /*  1024x768 */
-                0x33,0x33,0x33,    /* 1280x1024 */
-                0x33,0x33,0x33,    /*   640x480 (unknown) */
-                0x33,0x33,0x33,    /*  1024x600 (unknown) */
-                0x33,0x33,0x33,    /*  1152x864 (unknown) */
-                0x33,0x33,0x33,    /*  1280x960 (guessed) */
-                0x33,0x33,0x33,    /*  1152x768 (unknown) */
-                0x33,0x33,0x33,    /* 1400x1050 */
-                0x33,0x33,0x33,    /*  1280x768  (guessed) */
-                0x33,0x33,0x33,    /* 1600x1200 */
-                0x33,0x33,0x33,
-                0x33,0x33,0x33,
-                0x33,0x33,0x33,
-                0x33,0x33,0x33
+       0x33,0x33,0x33,    /*   800x600 (guessed) - new: PanelType, not PanelRes ! */
+       0x33,0x33,0x33,    /*  1024x768 */
+       0x33,0x33,0x33,    /* 1280x1024 */
+       0x33,0x33,0x33,    /*   640x480 (unknown) */
+       0x33,0x33,0x33,    /*  1024x600 (unknown) */
+       0x33,0x33,0x33,    /*  1152x864 (unknown) */
+       0x33,0x33,0x33,    /*  1280x960 (guessed) */
+       0x33,0x33,0x33,    /*  1152x768 (unknown) */
+       0x33,0x33,0x33,    /* 1400x1050 */
+       0x33,0x33,0x33,    /*  1280x768  (guessed) */
+       0x33,0x33,0x33,    /* 1600x1200 */
+       0x33,0x33,0x33,
+       0x33,0x33,0x33,
+       0x33,0x33,0x33,
+       0x33,0x33,0x33
 };
 
-static const UCHAR SiS310_LCDDelayCompensation_651302LV[] =            /* M650/651 302LV */
+static const unsigned char SiS310_LCDDelayCompensation_651302LV[] =            /* M650/651 302LV */
 {
-                 0x33,0x33,0x33,    /*   800x600 (guessed) */
-                0x33,0x33,0x33,    /*  1024x768 */
-                0x33,0x33,0x33,    /* 1280x1024 */
-                0x33,0x33,0x33,    /*   640x480 (unknown) */
-                0x33,0x33,0x33,    /*  1024x600 (unknown) */
-                0x33,0x33,0x33,    /*  1152x864 (unknown) */
-                0x33,0x33,0x33,    /*  1280x960 (guessed) */
-                0x33,0x33,0x33,    /*  1152x768 (unknown) */
-                0x33,0x33,0x33,    /* 1400x1050 */
-                0x33,0x33,0x33,    /*  1280x768  (guessed) */
-                0x33,0x33,0x33,    /* 1600x1200 */
-                0x33,0x33,0x33,
-                0x33,0x33,0x33,
-                0x33,0x33,0x33,
-                0x33,0x33,0x33
+       0x33,0x33,0x33,    /*   800x600 (guessed) */
+       0x33,0x33,0x33,    /*  1024x768 */
+       0x33,0x33,0x33,    /* 1280x1024 */
+       0x33,0x33,0x33,    /*   640x480 (unknown) */
+       0x33,0x33,0x33,    /*  1024x600 (unknown) */
+       0x33,0x33,0x33,    /*  1152x864 (unknown) */
+       0x33,0x33,0x33,    /*  1280x960 (guessed) */
+       0x33,0x33,0x33,    /*  1152x768 (unknown) */
+       0x33,0x33,0x33,    /* 1400x1050 */
+       0x33,0x33,0x33,    /*  1280x768  (guessed) */
+       0x33,0x33,0x33,    /* 1600x1200 */
+       0x33,0x33,0x33,
+       0x33,0x33,0x33,
+       0x33,0x33,0x33,
+       0x33,0x33,0x33
 };
 
-static const UCHAR SiS310_LCDDelayCompensation_3xx301B[] =             /* 30xB */
+static const unsigned char SiS310_LCDDelayCompensation_3xx301B[] =             /* 30xB */
 {
-                0x01,0x01,0x01,    /*   800x600 */
-                0x0C,0x0C,0x0C,    /*  1024x768 */
-                0x0C,0x0C,0x0C,    /* 1280x1024 */
-                 0x08,0x08,0x08,    /*   640x480 */
-                0x0C,0x0C,0x0C,    /*  1024x600 (guessed) */
-                0x0C,0x0C,0x0C,    /*  1152x864 (guessed) */
-                0x0C,0x0C,0x0C,    /*  1280x960 (guessed) */
-                0x0C,0x0C,0x0C,    /*  1152x768 (guessed) */
-                0x0C,0x0C,0x0C,    /* 1400x1050 (guessed) */
-                0x0C,0x0C,0x0C,    /*  1280x768 (guessed) */
-                0x0C,0x0C,0x0C,    /* 1600x1200 (guessed) */
-                0x02,0x02,0x02,
-                0x02,0x02,0x02,
-                0x02,0x02,0x02,
-                0x02,0x02,0x02
+       0x01,0x01,0x01,    /*   800x600 */
+       0x0C,0x0C,0x0C,    /*  1024x768 */
+       0x0C,0x0C,0x0C,    /* 1280x1024 */
+       0x08,0x08,0x08,    /*   640x480 */
+       0x0C,0x0C,0x0C,    /*  1024x600 (guessed) */
+       0x0C,0x0C,0x0C,    /*  1152x864 (guessed) */
+       0x0C,0x0C,0x0C,    /*  1280x960 (guessed) */
+       0x0C,0x0C,0x0C,    /*  1152x768 (guessed) */
+       0x0C,0x0C,0x0C,    /* 1400x1050 (guessed) */
+       0x0C,0x0C,0x0C,    /*  1280x768 (guessed) */
+       0x0C,0x0C,0x0C,    /* 1600x1200 (guessed) */
+       0x02,0x02,0x02,
+       0x02,0x02,0x02,
+       0x02,0x02,0x02,
+       0x02,0x02,0x02
 };
 
-static const UCHAR SiS310_LCDDelayCompensation_3xx301LV[] =            /* 315+30xLV */
+static const unsigned char SiS310_LCDDelayCompensation_3xx301LV[] =            /* 315+30xLV */
 {
-                0x01,0x01,0x01,    /*   800x600 */
-                0x04,0x04,0x04,    /*  1024x768 (A531/BIOS 1.14.05f: 4 - works with 6 */
-                0x0C,0x0C,0x0C,    /* 1280x1024 */
-                 0x08,0x08,0x08,    /*   640x480 */
-                0x0C,0x0C,0x0C,    /*  1024x600 (guessed) */
-                0x0C,0x0C,0x0C,    /*  1152x864 (guessed) */
-                0x0C,0x0C,0x0C,    /*  1280x960 (guessed) */
-                0x0C,0x0C,0x0C,    /*  1152x768 (guessed) */
-                0x0C,0x0C,0x0C,    /* 1400x1050 (guessed) */
-                0x0C,0x0C,0x0C,    /*  1280x768 (guessed) */
-                0x0C,0x0C,0x0C,    /* 1600x1200 (guessed) */
-                0x02,0x02,0x02,
-                0x02,0x02,0x02,
-                0x02,0x02,0x02,
-                0x02,0x02,0x02
+       0x01,0x01,0x01,    /*   800x600 */
+       0x04,0x04,0x04,    /*  1024x768 (A531/BIOS 1.14.05f: 4 - works with 6 */
+       0x0C,0x0C,0x0C,    /* 1280x1024 */
+       0x08,0x08,0x08,    /*   640x480 */
+       0x0C,0x0C,0x0C,    /*  1024x600 (guessed) */
+       0x0C,0x0C,0x0C,    /*  1152x864 (guessed) */
+       0x0C,0x0C,0x0C,    /*  1280x960 (guessed) */
+       0x0C,0x0C,0x0C,    /*  1152x768 (guessed) */
+       0x0C,0x0C,0x0C,    /* 1400x1050 (guessed) */
+       0x0C,0x0C,0x0C,    /*  1280x768 (guessed) */
+       0x0C,0x0C,0x0C,    /* 1600x1200 (guessed) */
+       0x02,0x02,0x02,
+       0x02,0x02,0x02,
+       0x02,0x02,0x02,
+       0x02,0x02,0x02
 };
 
-static const UCHAR SiS310_TVDelayCompensation_301[] =          /* 301 */
+static const unsigned char SiS310_TVDelayCompensation_301[] =          /* 301 */
 {
-                0x02,0x02,    /* NTSC Enhanced, Standard */
-                 0x02,0x02,    /* PAL */
-                0x08,0x0b     /* HiVision */
+       0x02,0x02,    /* NTSC Enhanced, Standard */
+       0x02,0x02,    /* PAL */
+       0x08,0x0b     /* HiVision */
 };
 
-static const UCHAR SiS310_TVDelayCompensation_301B[] =         /* 30xB, 30xLV */
+static const unsigned char SiS310_TVDelayCompensation_301B[] =         /* 30xB, 30xLV */
 {
-                0x03,0x03,
-                0x03,0x03,
-                0x03,0x03
+       0x03,0x03,
+       0x03,0x03,
+       0x03,0x03
 };
 
-static const UCHAR SiS310_TVDelayCompensation_740301B[] =      /* 740 + 30xB (30xLV?) */
+static const unsigned char SiS310_TVDelayCompensation_740301B[] =      /* 740 + 30xB (30xLV?) */
 {
-                0x05,0x05,
-                0x05,0x05,
-                0x05,0x05
+       0x05,0x05,
+       0x05,0x05,
+       0x05,0x05
 };
 
-static const UCHAR SiS310_TVDelayCompensation_651301LV[] =     /* M650, 651, 301LV */
+static const unsigned char SiS310_TVDelayCompensation_651301LV[] =     /* M650, 651, 301LV */
 {
-                0x33,0x33,
-                0x33,0x33,
-                0x33,0x33
+       0x33,0x33,
+       0x33,0x33,
+       0x33,0x33
 };
 
-static const UCHAR SiS310_TVDelayCompensation_651302LV[] =     /* M650, 651, 302LV */
+static const unsigned char SiS310_TVDelayCompensation_651302LV[] =     /* M650, 651, 302LV */
 {
-                0x33,0x33,
-                0x33,0x33,
-                0x33,0x33
+       0x33,0x33,
+       0x33,0x33,
+       0x33,0x33
 };
 
-static const UCHAR SiS_TVDelay661_301[] =                      /* 661, 301 */
+static const unsigned char SiS_TVDelay661_301[] =                      /* 661, 301 */
 {
-                0x44,0x44,
-                0x44,0x44,
-                0x00,0x00,
-                0x44,0x44,
-                0x44,0x44,
-                0x44,0x44
+       0x44,0x44,
+       0x44,0x44,
+       0x00,0x00,
+       0x44,0x44,
+       0x44,0x44,
+       0x44,0x44
 };
 
-static const UCHAR SiS_TVDelay661_301B[] =                     /* 661, 301B et al */
+static const unsigned char SiS_TVDelay661_301B[] =                     /* 661, 301B et al */
 {
-                0x44,0x44,
-                0x44,0x44,
-                0x00,0x00,
-                0x44,0x44,
-                0x44,0x44,
-                0x44,0x44
+       0x44,0x44,
+       0x44,0x44,
+       0x00,0x00,
+       0x44,0x44,
+       0x44,0x44,
+       0x44,0x44
 };
 
-static const UCHAR SiS310_TVDelayCompensation_LVDS[] =         /* LVDS */
+static const unsigned char SiS310_TVDelayCompensation_LVDS[] =         /* LVDS */
 {
-                0x0a,0x0a,
-                0x0a,0x0a,
-                0x0a,0x0a
+       0x0a,0x0a,
+       0x0a,0x0a,
+       0x0a,0x0a
 };
 
-static const UCHAR SiS310_TVAntiFlick1[6][2] =
+static const unsigned char SiS310_TVAntiFlick1[6][2] =
 {
-            {0x4,0x0},
-           {0x4,0x8},
-           {0x0,0x0},
-           {0x0,0x0},
-           {0x0,0x0},
-           {0x0,0x0}
+       {0x4,0x0},
+       {0x4,0x8},
+       {0x0,0x0},
+       {0x0,0x0},
+       {0x0,0x0},
+       {0x0,0x0}
 };
 
-static const UCHAR SiS310_TVEdge1[6][2] =
+static const unsigned char SiS310_TVEdge1[6][2] =
 {
-            {0x0,0x4},
-           {0x0,0x4},
-           {0x0,0x0},
-           {0x0,0x0},
-           {0x0,0x0},
-           {0x0,0x0}
+       {0x0,0x4},
+       {0x0,0x4},
+       {0x0,0x0},
+       {0x0,0x0},
+       {0x0,0x0},
+       {0x0,0x0}
 };
 
-static const UCHAR SiS310_TVYFilter1[5][8][4] =
+static const unsigned char SiS310_TVYFilter1[5][8][4] =
 {
- {
  {
        {0x00,0xf4,0x10,0x38},  /* NTSC */
        {0x00,0xf4,0x10,0x38},
        {0xeb,0x04,0x25,0x18},
@@ -258,8 +258,8 @@ static const UCHAR SiS310_TVYFilter1[5][8][4] =
        {0xeb,0x04,0x25,0x18},
        {0xee,0x0c,0x22,0x08},
        {0xeb,0x15,0x25,0xf6}
- },
- {
  },
  {
        {0x00,0xf4,0x10,0x38},  /* PAL */
        {0x00,0xf4,0x10,0x38},
        {0xf1,0xf7,0x1f,0x32},
@@ -268,8 +268,8 @@ static const UCHAR SiS310_TVYFilter1[5][8][4] =
        {0xf1,0xf7,0x1f,0x32},
        {0xf3,0x00,0x1d,0x20},
        {0xfc,0xfb,0x14,0x2a}
- },
- {
  },
  {
        {0x00,0x00,0x00,0x00},  /* HiVision */
        {0x00,0xf4,0x10,0x38},
        {0x00,0xf4,0x10,0x38},
@@ -278,9 +278,9 @@ static const UCHAR SiS310_TVYFilter1[5][8][4] =
        {0x00,0xf4,0x10,0x38},
        {0xeb,0x04,0x25,0x18},
        {0xee,0x0c,0x22,0x08}
- },
- {
-       {0x00,0xf4,0x10,0x38},  /* PAL-M */
  },
  {
+       {0x00,0xf4,0x10,0x38},  /* PAL-M */
        {0x00,0xf4,0x10,0x38},
        {0xeb,0x04,0x10,0x18},
        {0xf7,0x06,0x19,0x14},
@@ -288,9 +288,9 @@ static const UCHAR SiS310_TVYFilter1[5][8][4] =
        {0xeb,0x04,0x25,0x18},
        {0xeb,0x04,0x25,0x18},
        {0xeb,0x15,0x25,0xf6}
- },
- {
-       {0x00,0xf4,0x10,0x38},  /* PAL-N */
  },
  {
+       {0x00,0xf4,0x10,0x38},  /* PAL-N */
        {0x00,0xf4,0x10,0x38},
        {0xeb,0x04,0x10,0x18},
        {0xf7,0x06,0x19,0x14},
@@ -298,12 +298,12 @@ static const UCHAR SiS310_TVYFilter1[5][8][4] =
        {0xeb,0x04,0x25,0x18},
        {0xeb,0x04,0x25,0x18},
        {0xeb,0x15,0x25,0xf6}
- }
  }
 };
 
-static const UCHAR SiS310_TVYFilter2[5][9][7] =
+static const unsigned char SiS310_TVYFilter2[5][9][7] =
 {
- {
  {
        {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},   /* NTSC */
        {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
        {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
@@ -313,8 +313,8 @@ static const UCHAR SiS310_TVYFilter2[5][9][7] =
        {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
        {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
        {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
- },
- {
  },
  {
        {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},   /* PAL */
        {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
        {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
@@ -324,8 +324,8 @@ static const UCHAR SiS310_TVYFilter2[5][9][7] =
        {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
        {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
        {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
- },
- {
  },
  {
        {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22},   /* HiVision */
        {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22},
        {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22},
@@ -335,9 +335,9 @@ static const UCHAR SiS310_TVYFilter2[5][9][7] =
        {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22},
        {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22},
        {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22}
- },
- {
-       {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},   /* PAL-M */
  },
  {
+       {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},   /* PAL-M */
        {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
        {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
        {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
@@ -346,9 +346,9 @@ static const UCHAR SiS310_TVYFilter2[5][9][7] =
        {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
        {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
        {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
- },
- {
-       {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},   /* PAL-N */
  },
  {
+       {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},   /* PAL-N */
        {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
        {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
        {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
@@ -357,58 +357,39 @@ static const UCHAR SiS310_TVYFilter2[5][9][7] =
        {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
        {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
        {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
- }
  }
 };
 
-static const UCHAR SiS310_TVPhaseIncr1[3][2][4] =
+static const unsigned char SiS310_TVPhaseIncr1[3][2][4] =
 {
- {
  {
        {0x21,0xed,0xba,0x08},
        {0x21,0xed,0xba,0x08}
- },
- {
  },
  {
        {0x2a,0x05,0xe3,0x00},
        {0x2a,0x05,0xe3,0x00}
- },
- {
  },
  {
        {0x2a,0x05,0xd3,0x00},
        {0x2a,0x05,0xd3,0x00}
- }
  }
 };
 
-static const UCHAR SiS310_TVPhaseIncr2[3][2][4] =
+static const unsigned char SiS310_TVPhaseIncr2[3][2][4] =
 {
- {
  {
        {0x21,0xf0,0x7b,0xd6},
        {0x21,0xf0,0x7b,0xd6}
- },
- {
  },
  {
        {0x2a,0x0a,0x41,0xe9},
        {0x2a,0x0a,0x41,0xe9}
- },
- {
  },
  {
        {0x2a,0x05,0xd3,0x00},
        {0x2a,0x05,0xd3,0x00}
- }
-};
-
-static const UCHAR SiS661_TVPhase[] = {
-    0x21,0xED,0xBA,0x08,
-    0x2A,0x05,0xE3,0x00,
-    0x21,0xE4,0x2E,0x9B,
-    0x21,0xF4,0x3E,0xBA,
-    0x1E,0x8B,0xA2,0xA7,
-    0x1E,0x83,0x0A,0xE0,
-    0x00,0x00,0x00,0x00,
-    0x00,0x00,0x00,0x00,
-    0x21,0xF0,0x7B,0xD6,
-    0x2A,0x09,0x86,0xE9,
-    0x21,0xE6,0xEF,0xA4,
-    0x21,0xF6,0x94,0x46,
-    0x1E,0x8B,0xA2,0xA7,
-    0x1E,0x83,0x0A,0xE0,
-    0x00,0x00,0x00,0x00,
-    0x00,0x00,0x00,0x00
+   }
 };
 
 /**************************************************************/
@@ -417,7 +398,7 @@ static const UCHAR SiS661_TVPhase[] = {
 
 /* Inventec / Compaq Presario 3045US, 3017 */
 
-static const SiS_LCDDataStruct  SiS310_ExtCompaq1280x1024Data[] =
+static const struct SiS_LCDData SiS310_ExtCompaq1280x1024Data[] =
 {
        {  211,  60,1024, 501,1688,1066},
        {  211,  60,1024, 508,1688,1066},
@@ -431,17 +412,17 @@ static const SiS_LCDDataStruct  SiS310_ExtCompaq1280x1024Data[] =
 
 /* Asus A2xxxH _2 */
 
-static const SiS_Part2PortTblStruct SiS310_CRT2Part2_Asus1024x768_3[] =
+static const struct SiS_Part2PortTbl SiS310_CRT2Part2_Asus1024x768_3[] =
 {
- {{0x25,0x13,0xc9,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x2c,0x13,0x9a,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x25,0x13,0xc9,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
- {{0x38,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x38,0x13,0x16,0x25,0xff,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
- {{0x36,0x13,0x13,0x25,0xff,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
- {{0x25,0x13,0xc9,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}
      {{0x25,0x13,0xc9,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
      {{0x2c,0x13,0x9a,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
      {{0x25,0x13,0xc9,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
      {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
      {{0x38,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
      {{0x38,0x13,0x16,0x25,0xff,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
      {{0x36,0x13,0x13,0x25,0xff,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
      {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
      {{0x25,0x13,0xc9,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}
 };
 
 
index 15939b0..841ca31 100644 (file)
@@ -3,7 +3,7 @@
 /*
  * OS depending defines
  *
- * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
  *
  * If distributed as part of the Linux kernel, the following license terms
  * apply:
 #define _SIS_OSDEF_H_
 
 /* The choices are: */
-#define LINUX_KERNEL      /* Linux kernel framebuffer */
-/* #define LINUX_XF86 */   /* XFree86/X.org */
+#define SIS_LINUX_KERNEL               /* Linux kernel framebuffer */
+#undef  SIS_XORG_XF86                  /* XFree86/X.org */
+
+#undef SIS_LINUX_KERNEL_24
+#undef SIS_LINUX_KERNEL_26
 
 #ifdef OutPortByte
 #undef OutPortByte
@@ -86,8 +89,9 @@
 /*  LINUX KERNEL                                                      */
 /**********************************************************************/
 
-#ifdef LINUX_KERNEL
+#ifdef SIS_LINUX_KERNEL
 #include <linux/config.h>
+#include <linux/version.h>
 
 #ifdef CONFIG_FB_SIS_300
 #define SIS300
 #define SIS315H
 #endif
 
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+#define SIS_LINUX_KERNEL_26
+#else
+#define SIS_LINUX_KERNEL_24
+#endif
+
 #if !defined(SIS300) && !defined(SIS315H)
 #warning Neither CONFIG_FB_SIS_300 nor CONFIG_FB_SIS_315 is set
 #warning sisfb will not work!
 #define InPortWord(p)    inw((SISIOADDRESS)(p))
 #define InPortLong(p)    inl((SISIOADDRESS)(p))
 #define SiS_SetMemory(MemoryAddress,MemorySize,value) memset_io(MemoryAddress, value, MemorySize)
-#endif
+
+#endif /* LINUX_KERNEL */
 
 /**********************************************************************/
 /*  XFree86/X.org                                                    */
 /**********************************************************************/
 
-#ifdef LINUX_XF86
+#ifdef SIS_XORG_XF86
+
 #define SIS300
 #define SIS315H
 
 #define InPortWord(p)    inSISREGW((IOADDRESS)(p))
 #define InPortLong(p)    inSISREGL((IOADDRESS)(p))
 #define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize)
-#endif
+
+#endif /* XF86 */
 
 #endif  /* _OSDEF_H_ */
index d0103c1..0b6e625 100644 (file)
@@ -1,8 +1,10 @@
 /*
- * SiS 300/630/730/540/315/550/[M]650/651/[M]661[FM]X/740/[M]741[GX]/330/[M]760[GX]
+ * SiS 300/540/630[S]/730[S],
+ * SiS 315[E|PRO]/550/[M]65x/[M]661[F|M]X/740/[M]741[GX]/330/[M]76x[GX],
+ * XGI V3XT/V5/V8, Z7
  * frame buffer driver for Linux kernels >=2.4.14 and >=2.6.3
  *
- * Copyright (C) 2001-2004 Thomas Winischhofer, Vienna, Austria.
+ * Copyright (C) 2001-2005 Thomas Winischhofer, Vienna, Austria.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -19,8 +21,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
  */
 
-#ifndef _SIS_H
-#define _SIS_H
+#ifndef _SIS_H_
+#define _SIS_H_
 
 #include <linux/config.h>
 #include <linux/version.h>
 #include "vgatypes.h"
 #include "vstruct.h"
 
-#define VER_MAJOR                 1
-#define VER_MINOR                 7
-#define VER_LEVEL                 17
-
-#undef SIS_CONFIG_COMPAT
+#define VER_MAJOR              1
+#define VER_MINOR              8
+#define VER_LEVEL              9
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 #include <linux/spinlock.h>
+#define SIS_PCI_GET_CLASS(a, b) pci_get_class(a, b)
+#define SIS_PCI_GET_DEVICE(a,b,c) pci_get_device(a,b,c)
+#define SIS_PCI_GET_SLOT(a,b) pci_get_slot(a,b)
+#define SIS_PCI_PUT_DEVICE(a) pci_dev_put(a)
 #ifdef CONFIG_COMPAT
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,10)
 #include <linux/ioctl32.h>
-#define SIS_CONFIG_COMPAT
-#endif
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,19)
-#ifdef __x86_64__
-/* Shouldn't we check for CONFIG_IA32_EMULATION here? */
+#define SIS_OLD_CONFIG_COMPAT
+#else
+#include <linux/smp_lock.h>
+#define SIS_NEW_CONFIG_COMPAT
+#endif
+#endif /* CONFIG_COMPAT */
+#else  /* 2.4 */
+#define SIS_PCI_GET_CLASS(a, b) pci_find_class(a, b)
+#define SIS_PCI_GET_DEVICE(a,b,c) pci_find_device(a,b,c)
+#define SIS_PCI_GET_SLOT(a,b) pci_find_slot(a,b)
+#define SIS_PCI_PUT_DEVICE(a)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,19)
+#ifdef __x86_64__      /* Shouldn't we check for CONFIG_IA32_EMULATION here? */
 #include <asm/ioctl32.h>
-#define SIS_CONFIG_COMPAT
+#define SIS_OLD_CONFIG_COMPAT
 #endif
 #endif
-
+#endif /* 2.4 */
 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)
 #define SIS_IOTYPE1 void __iomem
 #define SIS_IOTYPE2 __iomem
 
 /* To be included in pci_ids.h */
 #ifndef PCI_DEVICE_ID_SI_650_VGA
-#define PCI_DEVICE_ID_SI_650_VGA  0x6325
+#define PCI_DEVICE_ID_SI_650_VGA       0x6325
 #endif
 #ifndef PCI_DEVICE_ID_SI_650
-#define PCI_DEVICE_ID_SI_650      0x0650
+#define PCI_DEVICE_ID_SI_650           0x0650
 #endif
 #ifndef PCI_DEVICE_ID_SI_651
-#define PCI_DEVICE_ID_SI_651      0x0651
+#define PCI_DEVICE_ID_SI_651           0x0651
 #endif
 #ifndef PCI_DEVICE_ID_SI_740
-#define PCI_DEVICE_ID_SI_740      0x0740
+#define PCI_DEVICE_ID_SI_740           0x0740
 #endif
 #ifndef PCI_DEVICE_ID_SI_330
-#define PCI_DEVICE_ID_SI_330      0x0330
+#define PCI_DEVICE_ID_SI_330           0x0330
 #endif
 #ifndef PCI_DEVICE_ID_SI_660_VGA
-#define PCI_DEVICE_ID_SI_660_VGA  0x6330
+#define PCI_DEVICE_ID_SI_660_VGA       0x6330
 #endif
 #ifndef PCI_DEVICE_ID_SI_661
-#define PCI_DEVICE_ID_SI_661      0x0661
+#define PCI_DEVICE_ID_SI_661           0x0661
 #endif
 #ifndef PCI_DEVICE_ID_SI_741
-#define PCI_DEVICE_ID_SI_741      0x0741
+#define PCI_DEVICE_ID_SI_741           0x0741
 #endif
 #ifndef PCI_DEVICE_ID_SI_660
-#define PCI_DEVICE_ID_SI_660      0x0660
+#define PCI_DEVICE_ID_SI_660           0x0660
 #endif
 #ifndef PCI_DEVICE_ID_SI_760
-#define PCI_DEVICE_ID_SI_760      0x0760
+#define PCI_DEVICE_ID_SI_760           0x0760
+#endif
+#ifndef PCI_DEVICE_ID_SI_761
+#define PCI_DEVICE_ID_SI_761           0x0761
+#endif
+
+#ifndef PCI_VENDOR_ID_XGI
+#define PCI_VENDOR_ID_XGI              0x18ca
+#endif
+
+#ifndef PCI_DEVICE_ID_XGI_20
+#define PCI_DEVICE_ID_XGI_20           0x0020
+#endif
+
+#ifndef PCI_DEVICE_ID_XGI_40
+#define PCI_DEVICE_ID_XGI_40           0x0040
 #endif
 
 /* To be included in fb.h */
 #ifndef FB_ACCEL_SIS_GLAMOUR_2
-#define FB_ACCEL_SIS_GLAMOUR_2   40    /* SiS 315, 65x, 740, 661, 741  */
+#define FB_ACCEL_SIS_GLAMOUR_2 40      /* SiS 315, 65x, 740, 661, 741  */
 #endif
 #ifndef FB_ACCEL_SIS_XABRE
-#define FB_ACCEL_SIS_XABRE        41   /* SiS 330 ("Xabre"), 760       */
+#define FB_ACCEL_SIS_XABRE     41      /* SiS 330 ("Xabre"), 76x       */
+#endif
+#ifndef FB_ACCEL_XGI_VOLARI_V
+#define FB_ACCEL_XGI_VOLARI_V  47      /* XGI Volari Vx (V3XT, V5, V8) */
+#endif
+#ifndef FB_ACCEL_XGI_VOLARI_Z
+#define FB_ACCEL_XGI_VOLARI_Z  48      /* XGI Volari Z7                */
 #endif
-
-#define MAX_ROM_SCAN              0x10000
 
 /* ivideo->caps */
-#define HW_CURSOR_CAP             0x80
-#define TURBO_QUEUE_CAP           0x40
-#define AGP_CMD_QUEUE_CAP         0x20
-#define VM_CMD_QUEUE_CAP          0x10
-#define MMIO_CMD_QUEUE_CAP        0x08
+#define HW_CURSOR_CAP          0x80
+#define TURBO_QUEUE_CAP                0x40
+#define AGP_CMD_QUEUE_CAP      0x20
+#define VM_CMD_QUEUE_CAP       0x10
+#define MMIO_CMD_QUEUE_CAP     0x08
 
 /* For 300 series */
-#define TURBO_QUEUE_AREA_SIZE     0x80000 /* 512K */
-#define HW_CURSOR_AREA_SIZE_300   0x1000  /* 4K */
+#define TURBO_QUEUE_AREA_SIZE  (512 * 1024)    /* 512K */
+#define HW_CURSOR_AREA_SIZE_300        4096            /* 4K */
 
 /* For 315/Xabre series */
-#define COMMAND_QUEUE_AREA_SIZE   0x80000 /* 512K */
-#define COMMAND_QUEUE_THRESHOLD   0x1F
-#define HW_CURSOR_AREA_SIZE_315   0x4000  /* 16K */
-
-#define SIS_OH_ALLOC_SIZE         4000
-#define SENTINEL                  0x7fffffff
-
-#define SEQ_ADR                   0x14
-#define SEQ_DATA                  0x15
-#define DAC_ADR                   0x18
-#define DAC_DATA                  0x19
-#define CRTC_ADR                  0x24
-#define CRTC_DATA                 0x25
-#define DAC2_ADR                  (0x16-0x30)
-#define DAC2_DATA                 (0x17-0x30)
-#define VB_PART1_ADR              (0x04-0x30)
-#define VB_PART1_DATA             (0x05-0x30)
-#define VB_PART2_ADR              (0x10-0x30)
-#define VB_PART2_DATA             (0x11-0x30)
-#define VB_PART3_ADR              (0x12-0x30)
-#define VB_PART3_DATA             (0x13-0x30)
-#define VB_PART4_ADR              (0x14-0x30)
-#define VB_PART4_DATA             (0x15-0x30)
-
-#define SISSR                    ivideo->SiS_Pr.SiS_P3c4
-#define SISCR                     ivideo->SiS_Pr.SiS_P3d4
-#define SISDACA                   ivideo->SiS_Pr.SiS_P3c8
-#define SISDACD                   ivideo->SiS_Pr.SiS_P3c9
-#define SISPART1                  ivideo->SiS_Pr.SiS_Part1Port
-#define SISPART2                  ivideo->SiS_Pr.SiS_Part2Port
-#define SISPART3                  ivideo->SiS_Pr.SiS_Part3Port
-#define SISPART4                  ivideo->SiS_Pr.SiS_Part4Port
-#define SISPART5                  ivideo->SiS_Pr.SiS_Part5Port
-#define SISDAC2A                  SISPART5
-#define SISDAC2D                  (SISPART5 + 1)
-#define SISMISCR                  (ivideo->SiS_Pr.RelIO + 0x1c)
-#define SISMISCW                  ivideo->SiS_Pr.SiS_P3c2
-#define SISINPSTAT               (ivideo->SiS_Pr.RelIO + 0x2a)
-#define SISPEL                   ivideo->SiS_Pr.SiS_P3c6
-
-#define IND_SIS_PASSWORD          0x05  /* SRs */
-#define IND_SIS_COLOR_MODE        0x06
-#define IND_SIS_RAMDAC_CONTROL    0x07
-#define IND_SIS_DRAM_SIZE         0x14
-#define IND_SIS_MODULE_ENABLE     0x1E
-#define IND_SIS_PCI_ADDRESS_SET   0x20
-#define IND_SIS_TURBOQUEUE_ADR    0x26
-#define IND_SIS_TURBOQUEUE_SET    0x27
-#define IND_SIS_POWER_ON_TRAP     0x38
-#define IND_SIS_POWER_ON_TRAP2    0x39
-#define IND_SIS_CMDQUEUE_SET      0x26
-#define IND_SIS_CMDQUEUE_THRESHOLD  0x27
-
-#define IND_SIS_AGP_IO_PAD        0x48
-
-#define SIS_CRT2_WENABLE_300     0x24  /* Part1 */
-#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
-#define SIS_16BPP_COLOR_MODE      0x2
-#define SIS_32BPP_COLOR_MODE      0x4
-
-#define SIS_ENABLE_2D             0x40  /* SR1E */
-
-#define SIS_MEM_MAP_IO_ENABLE     0x01  /* SR20 */
-#define SIS_PCI_ADDR_ENABLE       0x80
-
-#define SIS_AGP_CMDQUEUE_ENABLE   0x80  /* 315/330 series SR26 */
-#define SIS_VRAM_CMDQUEUE_ENABLE  0x40
-#define SIS_MMIO_CMD_ENABLE       0x20
-#define SIS_CMD_QUEUE_SIZE_512k   0x00
-#define SIS_CMD_QUEUE_SIZE_1M     0x04
-#define SIS_CMD_QUEUE_SIZE_2M     0x08
-#define SIS_CMD_QUEUE_SIZE_4M     0x0C
-#define SIS_CMD_QUEUE_RESET       0x01
-#define SIS_CMD_AUTO_CORR        0x02
-
-#define SIS_SIMULTANEOUS_VIEW_ENABLE  0x01  /* CR30 */
-#define SIS_MODE_SELECT_CRT2      0x02
-#define SIS_VB_OUTPUT_COMPOSITE   0x04
-#define SIS_VB_OUTPUT_SVIDEO      0x08
-#define SIS_VB_OUTPUT_SCART       0x10
-#define SIS_VB_OUTPUT_LCD         0x20
-#define SIS_VB_OUTPUT_CRT2        0x40
-#define SIS_VB_OUTPUT_HIVISION    0x80
-
-#define SIS_VB_OUTPUT_DISABLE     0x20  /* CR31 */
-#define SIS_DRIVER_MODE           0x40
-
-#define SIS_VB_COMPOSITE          0x01  /* CR32 */
-#define SIS_VB_SVIDEO             0x02
-#define SIS_VB_SCART              0x04
-#define SIS_VB_LCD                0x08
-#define SIS_VB_CRT2               0x10
-#define SIS_CRT1                  0x20
-#define SIS_VB_HIVISION           0x40
-#define SIS_VB_YPBPR              0x80
-#define SIS_VB_TV                 (SIS_VB_COMPOSITE | SIS_VB_SVIDEO | \
-                                   SIS_VB_SCART | SIS_VB_HIVISION | SIS_VB_YPBPR)
-
-#define SIS_EXTERNAL_CHIP_MASK            0x0E  /* CR37 (< SiS 660) */
-#define SIS_EXTERNAL_CHIP_SIS301           0x01  /* in CR37 << 1 ! */
-#define SIS_EXTERNAL_CHIP_LVDS             0x02
-#define SIS_EXTERNAL_CHIP_TRUMPION         0x03
-#define SIS_EXTERNAL_CHIP_LVDS_CHRONTEL    0x04
-#define SIS_EXTERNAL_CHIP_CHRONTEL         0x05
-#define SIS310_EXTERNAL_CHIP_LVDS          0x02
-#define SIS310_EXTERNAL_CHIP_LVDS_CHRONTEL 0x03
-
-#define SIS_AGP_2X                0x20  /* CR48 */
-
-#define HW_DEVICE_EXTENSION      SIS_HW_INFO
-#define PHW_DEVICE_EXTENSION      PSIS_HW_INFO
+#define COMMAND_QUEUE_AREA_SIZE        (512 * 1024)    /* 512K */
+#define COMMAND_QUEUE_AREA_SIZE_Z7 (128 * 1024)        /* 128k for XGI Z7 */
+#define HW_CURSOR_AREA_SIZE_315        16384           /* 16K */
+#define COMMAND_QUEUE_THRESHOLD        0x1F
+
+#define SIS_OH_ALLOC_SIZE      4000
+#define SENTINEL               0x7fffffff
+
+#define SEQ_ADR                        0x14
+#define SEQ_DATA               0x15
+#define DAC_ADR                        0x18
+#define DAC_DATA               0x19
+#define CRTC_ADR               0x24
+#define CRTC_DATA              0x25
+#define DAC2_ADR               (0x16-0x30)
+#define DAC2_DATA              (0x17-0x30)
+#define VB_PART1_ADR           (0x04-0x30)
+#define VB_PART1_DATA          (0x05-0x30)
+#define VB_PART2_ADR           (0x10-0x30)
+#define VB_PART2_DATA          (0x11-0x30)
+#define VB_PART3_ADR           (0x12-0x30)
+#define VB_PART3_DATA          (0x13-0x30)
+#define VB_PART4_ADR           (0x14-0x30)
+#define VB_PART4_DATA          (0x15-0x30)
+
+#define SISSR                  ivideo->SiS_Pr.SiS_P3c4
+#define SISCR                  ivideo->SiS_Pr.SiS_P3d4
+#define SISDACA                        ivideo->SiS_Pr.SiS_P3c8
+#define SISDACD                        ivideo->SiS_Pr.SiS_P3c9
+#define SISPART1               ivideo->SiS_Pr.SiS_Part1Port
+#define SISPART2               ivideo->SiS_Pr.SiS_Part2Port
+#define SISPART3               ivideo->SiS_Pr.SiS_Part3Port
+#define SISPART4               ivideo->SiS_Pr.SiS_Part4Port
+#define SISPART5               ivideo->SiS_Pr.SiS_Part5Port
+#define SISDAC2A               SISPART5
+#define SISDAC2D               (SISPART5 + 1)
+#define SISMISCR               (ivideo->SiS_Pr.RelIO + 0x1c)
+#define SISMISCW               ivideo->SiS_Pr.SiS_P3c2
+#define SISINPSTAT             (ivideo->SiS_Pr.RelIO + 0x2a)
+#define SISPEL                 ivideo->SiS_Pr.SiS_P3c6
+#define SISVGAENABLE           (ivideo->SiS_Pr.RelIO + 0x13)
+#define SISVID                 (ivideo->SiS_Pr.RelIO + 0x02 - 0x30)
+#define SISCAP                 (ivideo->SiS_Pr.RelIO + 0x00 - 0x30)
+
+#define IND_SIS_PASSWORD               0x05  /* SRs */
+#define IND_SIS_COLOR_MODE             0x06
+#define IND_SIS_RAMDAC_CONTROL         0x07
+#define IND_SIS_DRAM_SIZE              0x14
+#define IND_SIS_MODULE_ENABLE          0x1E
+#define IND_SIS_PCI_ADDRESS_SET                0x20
+#define IND_SIS_TURBOQUEUE_ADR         0x26
+#define IND_SIS_TURBOQUEUE_SET         0x27
+#define IND_SIS_POWER_ON_TRAP          0x38
+#define IND_SIS_POWER_ON_TRAP2         0x39
+#define IND_SIS_CMDQUEUE_SET           0x26
+#define IND_SIS_CMDQUEUE_THRESHOLD     0x27
+
+#define IND_SIS_AGP_IO_PAD     0x48
+
+#define SIS_CRT2_WENABLE_300   0x24  /* Part1 */
+#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
+#define SIS_16BPP_COLOR_MODE   0x2
+#define SIS_32BPP_COLOR_MODE   0x4
+
+#define SIS_ENABLE_2D          0x40  /* SR1E */
+
+#define SIS_MEM_MAP_IO_ENABLE  0x01  /* SR20 */
+#define SIS_PCI_ADDR_ENABLE    0x80
+
+#define SIS_AGP_CMDQUEUE_ENABLE                0x80  /* 315/330/340 series SR26 */
+#define SIS_VRAM_CMDQUEUE_ENABLE       0x40
+#define SIS_MMIO_CMD_ENABLE            0x20
+#define SIS_CMD_QUEUE_SIZE_512k                0x00
+#define SIS_CMD_QUEUE_SIZE_1M          0x04
+#define SIS_CMD_QUEUE_SIZE_2M          0x08
+#define SIS_CMD_QUEUE_SIZE_4M          0x0C
+#define SIS_CMD_QUEUE_RESET            0x01
+#define SIS_CMD_AUTO_CORR              0x02
+
+#define SIS_CMD_QUEUE_SIZE_Z7_64k      0x00 /* XGI Z7 */
+#define SIS_CMD_QUEUE_SIZE_Z7_128k     0x04
+
+#define SIS_SIMULTANEOUS_VIEW_ENABLE   0x01  /* CR30 */
+#define SIS_MODE_SELECT_CRT2           0x02
+#define SIS_VB_OUTPUT_COMPOSITE                0x04
+#define SIS_VB_OUTPUT_SVIDEO           0x08
+#define SIS_VB_OUTPUT_SCART            0x10
+#define SIS_VB_OUTPUT_LCD              0x20
+#define SIS_VB_OUTPUT_CRT2             0x40
+#define SIS_VB_OUTPUT_HIVISION         0x80
+
+#define SIS_VB_OUTPUT_DISABLE  0x20  /* CR31 */
+#define SIS_DRIVER_MODE                0x40
+
+#define SIS_VB_COMPOSITE       0x01  /* CR32 */
+#define SIS_VB_SVIDEO          0x02
+#define SIS_VB_SCART           0x04
+#define SIS_VB_LCD             0x08
+#define SIS_VB_CRT2            0x10
+#define SIS_CRT1               0x20
+#define SIS_VB_HIVISION                0x40
+#define SIS_VB_YPBPR           0x80
+#define SIS_VB_TV              (SIS_VB_COMPOSITE | SIS_VB_SVIDEO | \
+                               SIS_VB_SCART | SIS_VB_HIVISION | SIS_VB_YPBPR)
+
+#define SIS_EXTERNAL_CHIP_MASK                 0x0E  /* CR37 (< SiS 660) */
+#define SIS_EXTERNAL_CHIP_SIS301               0x01  /* in CR37 << 1 ! */
+#define SIS_EXTERNAL_CHIP_LVDS                 0x02
+#define SIS_EXTERNAL_CHIP_TRUMPION             0x03
+#define SIS_EXTERNAL_CHIP_LVDS_CHRONTEL                0x04
+#define SIS_EXTERNAL_CHIP_CHRONTEL             0x05
+#define SIS310_EXTERNAL_CHIP_LVDS              0x02
+#define SIS310_EXTERNAL_CHIP_LVDS_CHRONTEL     0x03
+
+#define SIS_AGP_2X             0x20  /* CR48 */
+
+/* vbflags, private entries (others in sisfb.h) */
+#define VB_CONEXANT            0x00000800      /* 661 series only */
+#define VB_TRUMPION            VB_CONEXANT     /* 300 series only */
+#define VB_302ELV              0x00004000
+#define VB_301                 0x00100000      /* Video bridge type */
+#define VB_301B                        0x00200000
+#define VB_302B                        0x00400000
+#define VB_30xBDH              0x00800000      /* 30xB DH version (w/o LCD support) */
+#define VB_LVDS                        0x01000000
+#define VB_CHRONTEL            0x02000000
+#define VB_301LV               0x04000000
+#define VB_302LV               0x08000000
+#define VB_301C                        0x10000000
+
+#define VB_SISBRIDGE           (VB_301|VB_301B|VB_301C|VB_302B|VB_301LV|VB_302LV|VB_302ELV)
+#define VB_VIDEOBRIDGE         (VB_SISBRIDGE | VB_LVDS | VB_CHRONTEL | VB_CONEXANT)
+
+/* vbflags2 (static stuff only!) */
+#define VB2_SISUMC             0x00000001
+#define VB2_301                        0x00000002      /* Video bridge type */
+#define VB2_301B               0x00000004
+#define VB2_301C               0x00000008
+#define VB2_307T               0x00000010
+#define VB2_302B               0x00000800
+#define VB2_301LV              0x00001000
+#define VB2_302LV              0x00002000
+#define VB2_302ELV             0x00004000
+#define VB2_307LV              0x00008000
+#define VB2_30xBDH             0x08000000      /* 30xB DH version (w/o LCD support) */
+#define VB2_CONEXANT           0x10000000
+#define VB2_TRUMPION           0x20000000
+#define VB2_LVDS               0x40000000
+#define VB2_CHRONTEL           0x80000000
+
+#define VB2_SISLVDSBRIDGE      (VB2_301LV | VB2_302LV | VB2_302ELV | VB2_307LV)
+#define VB2_SISTMDSBRIDGE      (VB2_301   | VB2_301B  | VB2_301C   | VB2_302B | VB2_307T)
+#define VB2_SISBRIDGE          (VB2_SISLVDSBRIDGE | VB2_SISTMDSBRIDGE)
+
+#define VB2_SISTMDSLCDABRIDGE  (VB2_301C | VB2_307T)
+#define VB2_SISLCDABRIDGE      (VB2_SISTMDSLCDABRIDGE | VB2_301LV | VB2_302LV | VB2_302ELV | VB2_307LV)
+
+#define VB2_SISHIVISIONBRIDGE  (VB2_301  | VB2_301B | VB2_302B)
+#define VB2_SISYPBPRBRIDGE     (VB2_301C | VB2_307T | VB2_SISLVDSBRIDGE)
+#define VB2_SISYPBPRARBRIDGE   (VB2_301C | VB2_307T | VB2_307LV)
+#define VB2_SISTAP4SCALER      (VB2_301C | VB2_307T | VB2_302ELV | VB2_307LV)
+#define VB2_SISTVBRIDGE                (VB2_SISHIVISIONBRIDGE | VB2_SISYPBPRBRIDGE)
+
+#define VB2_SISVGA2BRIDGE      (VB2_301 | VB2_301B | VB2_301C | VB2_302B | VB2_307T)
+
+#define VB2_VIDEOBRIDGE                (VB2_SISBRIDGE | VB2_LVDS | VB2_CHRONTEL | VB2_CONEXANT)
+
+#define VB2_30xB               (VB2_301B  | VB2_301C   | VB2_302B  | VB2_307T)
+#define VB2_30xBLV             (VB2_30xB  | VB2_SISLVDSBRIDGE)
+#define VB2_30xC               (VB2_301C  | VB2_307T)
+#define VB2_30xCLV             (VB2_301C  | VB2_307T   | VB2_302ELV| VB2_307LV)
+#define VB2_SISEMIBRIDGE       (VB2_302LV | VB2_302ELV | VB2_307LV)
+#define VB2_LCD162MHZBRIDGE    (VB2_301C  | VB2_307T)
+#define VB2_LCDOVER1280BRIDGE  (VB2_301C  | VB2_307T   | VB2_302LV | VB2_302ELV | VB2_307LV)
+#define VB2_LCDOVER1600BRIDGE  (VB2_307T  | VB2_307LV)
+#define VB2_RAMDAC202MHZBRIDGE (VB2_301C  | VB2_307T)
 
 /* I/O port access macros */
-#define inSISREG(base)          inb(base)
+#define inSISREG(base)         inb(base)
 
-#define outSISREG(base,val)     outb(val,base)
+#define outSISREG(base,val)    outb(val,base)
 
 #define orSISREG(base,val)                             \
-                   do {                                \
-                      u8 __Temp = inSISREG(base);      \
-                      outSISREG(base, __Temp | (val));         \
-                    } while (0)
+               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)
+               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))
 #define MMIO_QUEUE_READPORT     Q_READ_PTR
 
 #ifndef FB_BLANK_UNBLANK
-#define FB_BLANK_UNBLANK       0
+#define FB_BLANK_UNBLANK       0
 #endif
 #ifndef FB_BLANK_NORMAL
-#define FB_BLANK_NORMAL        1
+#define FB_BLANK_NORMAL                1
 #endif
 #ifndef FB_BLANK_VSYNC_SUSPEND
-#define FB_BLANK_VSYNC_SUSPEND         2
+#define FB_BLANK_VSYNC_SUSPEND 2
 #endif
 #ifndef FB_BLANK_HSYNC_SUSPEND
-#define FB_BLANK_HSYNC_SUSPEND         3
+#define FB_BLANK_HSYNC_SUSPEND 3
 #endif
 #ifndef FB_BLANK_POWERDOWN
-#define FB_BLANK_POWERDOWN     4
+#define FB_BLANK_POWERDOWN     4
 #endif
 
 enum _SIS_LCD_TYPE {
@@ -347,18 +444,19 @@ enum _SIS_LCD_TYPE {
     LCD_1600x1200,
     LCD_1920x1440,
     LCD_2048x1536,
-    LCD_320x480,       /* FSTN */
+    LCD_320x240,       /* FSTN */
     LCD_1400x1050,
     LCD_1152x864,
     LCD_1152x768,
     LCD_1280x768,
     LCD_1024x600,
-    LCD_640x480_2,     /* DSTN */
-    LCD_640x480_3,     /* DSTN */
+    LCD_320x240_2,     /* DSTN */
+    LCD_320x240_3,     /* DSTN */
     LCD_848x480,
     LCD_1280x800,
     LCD_1680x1050,
     LCD_1280x720,
+    LCD_1280x854,
     LCD_CUSTOM,
     LCD_UNKNOWN
 };
@@ -368,31 +466,50 @@ enum _SIS_CMDTYPE {
     AGP_CMD_QUEUE,
     VM_CMD_QUEUE,
 };
-typedef unsigned int SIS_CMDTYPE;
+
+struct SIS_OH {
+       struct SIS_OH *poh_next;
+       struct SIS_OH *poh_prev;
+       u32            offset;
+       u32            size;
+};
+
+struct SIS_OHALLOC {
+       struct SIS_OHALLOC *poha_next;
+       struct SIS_OH aoh[1];
+};
+
+struct SIS_HEAP {
+       struct SIS_OH   oh_free;
+       struct SIS_OH   oh_used;
+       struct SIS_OH   *poh_freelist;
+       struct SIS_OHALLOC *poha_chain;
+       u32             max_freesize;
+       struct sis_video_info *vinfo;
+};
 
 /* Our "par" */
 struct sis_video_info {
        int             cardnumber;
        struct fb_info  *memyselfandi;
 
-       SIS_HW_INFO     sishw_ext;
-       SiS_Private     SiS_Pr;
+       struct SiS_Private SiS_Pr;
 
-       sisfb_info      sisfbinfo;      /* For ioctl SISFB_GET_INFO */
+       struct sisfb_info sisfbinfo;    /* For ioctl SISFB_GET_INFO */
 
        struct fb_var_screeninfo default_var;
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
        struct fb_fix_screeninfo sisfb_fix;
-       u32             pseudo_palette[17];
+       u32             pseudo_palette[17];
 #endif
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-       struct display           sis_disp;
+       struct display           sis_disp;
        struct display_switch    sisfb_sw;
        struct {
                u16 red, green, blue, pad;
-       }               sis_palette[256];
+       }               sis_palette[256];
        union {
 #ifdef FBCON_HAS_CFB16
                u16 cfb16[16];
@@ -400,10 +517,10 @@ struct sis_video_info {
 #ifdef FBCON_HAS_CFB32
                u32 cfb32[16];
 #endif
-       }               sis_fbcon_cmap;
+       }               sis_fbcon_cmap;
 #endif
 
-        struct sisfb_monitor {
+       struct sisfb_monitor {
                u16 hmin;
                u16 hmax;
                u16 vmin;
@@ -411,163 +528,166 @@ struct sis_video_info {
                u32 dclockmax;
                u8  feature;
                BOOLEAN datavalid;
-       }               sisfb_thismonitor;
+       }               sisfb_thismonitor;
 
-       int             chip_id;
+       unsigned short  chip_id;        /* PCI ID of chip */
+       unsigned short  chip_vendor;    /* PCI ID of vendor */
        char            myid[40];
 
        struct pci_dev  *nbridge;
+       struct pci_dev  *lpcdev;
 
        int             mni;    /* Mode number index */
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-       int             currcon;
+       int             currcon;
 #endif
 
        unsigned long   video_size;
-       unsigned long   video_base;
+       unsigned long   video_base;
        unsigned long   mmio_size;
-       unsigned long   mmio_base;
-       unsigned long   vga_base;
+       unsigned long   mmio_base;
+       unsigned long   vga_base;
+
+       unsigned long   video_offset;
 
-       SIS_IOTYPE1     *video_vbase;
-       SIS_IOTYPE1     *mmio_vbase;
+       unsigned long   UMAsize, LFBsize;
 
-       unsigned char   *bios_abase;
+       SIS_IOTYPE1     *video_vbase;
+       SIS_IOTYPE1     *mmio_vbase;
 
-       int             mtrr;
+       unsigned char   *bios_abase;
+
+       int             mtrr;
 
        u32             sisfb_mem;
 
-       u32             sisfb_parm_mem;
-       int             sisfb_accel;
-       int             sisfb_ypan;
-       int             sisfb_max;
-       int             sisfb_userom;
-       int             sisfb_useoem;
+       u32             sisfb_parm_mem;
+       int             sisfb_accel;
+       int             sisfb_ypan;
+       int             sisfb_max;
+       int             sisfb_userom;
+       int             sisfb_useoem;
        int             sisfb_mode_idx;
        int             sisfb_parm_rate;
        int             sisfb_crt1off;
        int             sisfb_forcecrt1;
        int             sisfb_crt2type;
        int             sisfb_crt2flags;
-       int             sisfb_dstn;
-       int             sisfb_fstn;
+       int             sisfb_dstn;
+       int             sisfb_fstn;
        int             sisfb_tvplug;
        int             sisfb_tvstd;
-       int             sisfb_filter;
        int             sisfb_nocrt2rate;
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
        int             sisfb_inverse;
 #endif
 
-       u32             heapstart;              /* offset  */
-       SIS_IOTYPE1     *sisfb_heap_start;      /* address */
-       SIS_IOTYPE1     *sisfb_heap_end;        /* address */
-       u32             sisfb_heap_size;
+       u32             heapstart;              /* offset  */
+       SIS_IOTYPE1     *sisfb_heap_start;      /* address */
+       SIS_IOTYPE1     *sisfb_heap_end;        /* address */
+       u32             sisfb_heap_size;
        int             havenoheap;
-#if 0
-       SIS_HEAP        sisfb_heap;
-#endif
 
+       struct SIS_HEAP sisfb_heap;             /* This card's vram heap */
 
-       int             video_bpp;
-       int             video_cmap_len;
-       int             video_width;
-       int             video_height;
-       unsigned int    refresh_rate;
+       int             video_bpp;
+       int             video_cmap_len;
+       int             video_width;
+       int             video_height;
+       unsigned int    refresh_rate;
 
-       unsigned int    chip;
-       u8              revision_id;
+       unsigned int    chip;
+       u8              revision_id;
+       int             sisvga_enabled;         /* PCI device was enabled */
 
-       int             video_linelength;       /* real pitch */
+       int             video_linelength;       /* real pitch */
        int             scrnpitchCRT1;          /* pitch regarding interlace */
 
-        u16            DstColor;               /* For 2d acceleration */
-       u32             SiS310_AccelDepth;
-       u32             CommandReg;
-       int             cmdqueuelength;
+       u16             DstColor;               /* For 2d acceleration */
+       u32             SiS310_AccelDepth;
+       u32             CommandReg;
+       int             cmdqueuelength;         /* Current (for accel) */
+       u32             cmdQueueSize;           /* Total size in KB */
 
-       spinlock_t      lockaccel;              /* Do not use outside of kernel! */
+       spinlock_t      lockaccel;              /* Do not use outside of kernel! */
 
-        unsigned int           pcibus;
-       unsigned int    pcislot;
-       unsigned int    pcifunc;
+       unsigned int    pcibus;
+       unsigned int    pcislot;
+       unsigned int    pcifunc;
 
-       int             accel;
+       int             accel;
+       int             engineok;
 
-       u16             subsysvendor;
-       u16             subsysdevice;
+       u16             subsysvendor;
+       u16             subsysdevice;
 
-       u32             vbflags;                /* Replacing deprecated stuff from above */
-       u32             currentvbflags;
+       u32             vbflags;                /* Replacing deprecated stuff from above */
+       u32             currentvbflags;
+       u32             vbflags2;
 
        int             lcdxres, lcdyres;
        int             lcddefmodeidx, tvdefmodeidx, defmodeidx;
-       u32             CRT2LCDType;            /* defined in "SIS_LCD_TYPE" */
-
-       int             current_bpp;
-       int             current_width;
-       int             current_height;
-       int             current_htotal;
-       int             current_vtotal;
+       u32             CRT2LCDType;            /* defined in "SIS_LCD_TYPE" */
+       u32             curFSTN, curDSTN;
+
+       int             current_bpp;
+       int             current_width;
+       int             current_height;
+       int             current_htotal;
+       int             current_vtotal;
        int             current_linelength;
-       __u32           current_pixclock;
-       int             current_refresh_rate;
+       __u32           current_pixclock;
+       int             current_refresh_rate;
+
+       unsigned int    current_base;
 
-       u8              mode_no;
-       u8              rate_idx;
-       int             modechanged;
-       unsigned char   modeprechange;
+       u8              mode_no;
+       u8              rate_idx;
+       int             modechanged;
+       unsigned char   modeprechange;
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-       u8              sisfb_lastrates[128];
+       u8              sisfb_lastrates[128];
 #endif
 
-       int             newrom;
-       int             registered;
+       int             newrom;
+       int             haveXGIROM;
+       int             registered;
        int             warncount;
+#ifdef SIS_OLD_CONFIG_COMPAT
+       int             ioctl32registered;
+#endif
 
-       int             sisvga_engine;
-       int             hwcursor_size;
-       int             CRT2_write_enable;
-       u8              caps;
+       int             sisvga_engine;
+       int             hwcursor_size;
+       int             CRT2_write_enable;
+       u8              caps;
 
-       u8              detectedpdc;
-       u8              detectedpdca;
-       u8              detectedlcda;
+       u8              detectedpdc;
+       u8              detectedpdca;
+       u8              detectedlcda;
 
-       SIS_IOTYPE1     *hwcursor_vbase;
+       SIS_IOTYPE1     *hwcursor_vbase;
 
-       int             chronteltype;
-       int             tvxpos, tvypos;
-       u8              p2_1f,p2_20,p2_2b,p2_42,p2_43,p2_01,p2_02;
+       int             chronteltype;
+       int             tvxpos, tvypos;
+       u8              p2_1f,p2_20,p2_2b,p2_42,p2_43,p2_01,p2_02;
        int             tvx, tvy;
 
-       u8              sisfblocked;
+       u8              sisfblocked;
+
+       struct sisfb_info sisfb_infoblock;
+
+       struct sisfb_cmd sisfb_command;
+
+       u32             sisfb_id;
+
+       u8              sisfb_can_post;
+       u8              sisfb_card_posted;
+       u8              sisfb_was_boot_device;
 
        struct sis_video_info *next;
 };
 
-typedef struct _SIS_OH {
-       struct _SIS_OH *poh_next;
-       struct _SIS_OH *poh_prev;
-       u32            offset;
-       u32            size;
-} SIS_OH;
-
-typedef struct _SIS_OHALLOC {
-       struct _SIS_OHALLOC *poha_next;
-       SIS_OH aoh[1];
-} SIS_OHALLOC;
-
-typedef struct _SIS_HEAP {
-       SIS_OH      oh_free;
-       SIS_OH      oh_used;
-       SIS_OH      *poh_freelist;
-       SIS_OHALLOC *poha_chain;
-       u32         max_freesize;
-       struct sis_video_info *vinfo;
-} SIS_HEAP;
-
 #endif
index 30e90a5..bab933e 100644 (file)
@@ -1,6 +1,8 @@
 /*
- * SiS 300/630/730/540/315/550/65x/74x/330/760 frame buffer driver
- * for Linux kernels 2.4.x and 2.6.x
+ * SiS 300/540/630[S]/730[S],
+ * SiS 315[E|PRO]/550/[M]650/651/[M]661[F|M]X/740/[M]741[GX]/330/[M]760[GX],
+ * XGI V3XT/V5/V8, Z7
+ * frame buffer driver for Linux kernels >= 2.4.14 and >=2.6.3
  *
  * 2D acceleration part
  *
@@ -19,7 +21,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
  *
  * Based on the XFree86/X.org driver which is
- *     Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
+ *     Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
  *
  * Author: Thomas Winischhofer <thomas@winischhofer.net>
  *                     (see http://www.winischhofer.net/
 #include <linux/version.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/errno.h>
 #include <linux/fb.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 #include <linux/console.h>
-#include <linux/selection.h>
+#endif
 #include <linux/ioport.h>
-#include <linux/capability.h>
-#include <linux/fs.h>
 #include <linux/types.h>
 
 #include <asm/io.h>
@@ -188,7 +188,7 @@ SiS300SubsequentSolidFillRect(struct sis_video_info *ivideo, int x, int y, int w
 }
 #endif
 
-/* 315/330 series ------------------------------------------------- */
+/* 315/330/340 series ---------------------------------------------- */
 
 #ifdef CONFIG_FB_SIS_315
 static void
@@ -202,7 +202,7 @@ SiS310SetupForScreenToScreenCopy(struct sis_video_info *ivideo, int rop, int tra
 {
        SiS310SetupDSTColorDepth(ivideo->DstColor);
        SiS310SetupSRCPitch(ivideo->video_linelength)
-       SiS310SetupDSTRect(ivideo->video_linelength, 0xffff)
+       SiS310SetupDSTRect(ivideo->video_linelength, 0x0fff)
        if(trans_color != -1) {
                SiS310SetupROP(0x0A)
                SiS310SetupSRCTrans(trans_color)
@@ -213,7 +213,7 @@ SiS310SetupForScreenToScreenCopy(struct sis_video_info *ivideo, int rop, int tra
                /* SiSSetupCMDFlag(BITBLT | SRCVIDEO) */
        }
        SiS310SetupCMDFlag(ivideo->SiS310_AccelDepth)
-       /* The 315 series is smart enough to know the direction */
+       /* The chip is smart enough to know the direction */
 }
 
 static void
@@ -223,35 +223,38 @@ SiS310SubsequentScreenToScreenCopy(struct sis_video_info *ivideo, int src_x, int
        u32 srcbase = 0, dstbase = 0;
        int mymin = min(src_y, dst_y);
        int mymax = max(src_y, dst_y);
-       
+
        /* Although the chip knows the direction to use
-        * if the source and destination areas overlap, 
+        * if the source and destination areas overlap,
         * that logic fails if we fiddle with the bitmap
         * addresses. Therefore, we check if the source
-        * and destination blitting areas overlap and 
-        * adapt the bitmap addresses synchronously 
+        * and destination blitting areas overlap and
+        * adapt the bitmap addresses synchronously
         * if the coordinates exceed the valid range.
-        * The the areas do not overlap, we do our 
+        * The the areas do not overlap, we do our
         * normal check.
         */
-       if((mymax - mymin) < height) { 
-          if((src_y >= 2048) || (dst_y >= 2048)) {           
-             srcbase = ivideo->video_linelength * mymin;
-             dstbase = ivideo->video_linelength * mymin;
-             src_y -= mymin;
-             dst_y -= mymin;
-          }
+       if((mymax - mymin) < height) {
+               if((src_y >= 2048) || (dst_y >= 2048)) {
+                       srcbase = ivideo->video_linelength * mymin;
+                       dstbase = ivideo->video_linelength * mymin;
+                       src_y -= mymin;
+                       dst_y -= mymin;
+               }
        } else {
-          if(src_y >= 2048) {
-             srcbase = ivideo->video_linelength * src_y;
-             src_y = 0;
-          }
-          if(dst_y >= 2048) {
-             dstbase = ivideo->video_linelength * dst_y;
-             dst_y = 0;
-          }
+               if(src_y >= 2048) {
+                       srcbase = ivideo->video_linelength * src_y;
+                       src_y = 0;
+               }
+               if(dst_y >= 2048) {
+                       dstbase = ivideo->video_linelength * dst_y;
+                       dst_y = 0;
+               }
        }
 
+       srcbase += ivideo->video_offset;
+       dstbase += ivideo->video_offset;
+
        SiS310SetupSRCBase(srcbase);
        SiS310SetupDSTBase(dstbase);
        SiS310SetupRect(width, height)
@@ -264,7 +267,7 @@ static void
 SiS310SetupForSolidFill(struct sis_video_info *ivideo, u32 color, int rop)
 {
        SiS310SetupPATFG(color)
-       SiS310SetupDSTRect(ivideo->video_linelength, 0xffff)
+       SiS310SetupDSTRect(ivideo->video_linelength, 0x0fff)
        SiS310SetupDSTColorDepth(ivideo->DstColor);
        SiS310SetupROP(sisPatALUConv[rop])
        SiS310SetupCMDFlag(PATFG | ivideo->SiS310_AccelDepth)
@@ -279,6 +282,7 @@ SiS310SubsequentSolidFillRect(struct sis_video_info *ivideo, int x, int y, int w
                dstbase = ivideo->video_linelength * y;
                y = 0;
        }
+       dstbase += ivideo->video_offset;
        SiS310SetupDSTBase(dstbase)
        SiS310SetupDSTXY(x,y)
        SiS310SetupRect(w,h)
@@ -294,384 +298,153 @@ SiS310SubsequentSolidFillRect(struct sis_video_info *ivideo, int x, int y, int w
 int sisfb_initaccel(struct sis_video_info *ivideo)
 {
 #ifdef SISFB_USE_SPINLOCKS
-    spin_lock_init(&ivideo->lockaccel);
+       spin_lock_init(&ivideo->lockaccel);
 #endif
-    return(0);
+       return 0;
 }
 
 void sisfb_syncaccel(struct sis_video_info *ivideo)
 {
-    if(ivideo->sisvga_engine == SIS_300_VGA) {
+       if(ivideo->sisvga_engine == SIS_300_VGA) {
 #ifdef CONFIG_FB_SIS_300
-       SiS300Sync(ivideo);
+               SiS300Sync(ivideo);
 #endif
-    } else {
+       } else {
 #ifdef CONFIG_FB_SIS_315
-       SiS310Sync(ivideo);
+               SiS310Sync(ivideo);
 #endif
-    }
+       }
 }
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)  /* --------------- 2.5 --------------- */
 
 int fbcon_sis_sync(struct fb_info *info)
 {
-   struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
-   CRITFLAGS
+       struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
+       CRITFLAGS
 
-   if(!ivideo->accel)
-       return 0;
+       if((!ivideo->accel) || (!ivideo->engineok))
+               return 0;
 
-   if(ivideo->sisvga_engine == SIS_300_VGA) {
-#ifdef CONFIG_FB_SIS_300
-      SiS300Sync(ivideo);
-#endif
-   } else {
-#ifdef CONFIG_FB_SIS_315
-      SiS310Sync(ivideo);
-#endif
-   }
-   CRITEND
-   return 0;
+       CRITBEGIN
+       sisfb_syncaccel(ivideo);
+       CRITEND
+
+       return 0;
 }
 
 void fbcon_sis_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
 {
-   struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
-   u32 col = 0;
-   u32 vxres = info->var.xres_virtual;
-   u32 vyres = info->var.yres_virtual;
-   int width, height;
-   CRITFLAGS
-
-   if(info->state != FBINFO_STATE_RUNNING) {
-       return;
-   }
-
-   if(!ivideo->accel) {
-       cfb_fillrect(info, rect);
-       return;
-   }
-   
-   if(!rect->width || !rect->height || rect->dx >= vxres || rect->dy >= vyres) {
-       return;
-   }
-
-   /* Clipping */
-   width = ((rect->dx + rect->width) > vxres) ? (vxres - rect->dx) : rect->width;
-   height = ((rect->dy + rect->height) > vyres) ? (vyres - rect->dy) : rect->height;
-
-   switch(info->var.bits_per_pixel) {
+       struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
+       u32 col = 0;
+       u32 vxres = info->var.xres_virtual;
+       u32 vyres = info->var.yres_virtual;
+       int width, height;
+       CRITFLAGS
+
+       if(info->state != FBINFO_STATE_RUNNING)
+               return;
+
+       if((!ivideo->accel) || (!ivideo->engineok)) {
+               cfb_fillrect(info, rect);
+               return;
+       }
+
+       if(!rect->width || !rect->height || rect->dx >= vxres || rect->dy >= vyres)
+               return;
+
+       /* Clipping */
+       width = ((rect->dx + rect->width) > vxres) ? (vxres - rect->dx) : rect->width;
+       height = ((rect->dy + rect->height) > vyres) ? (vyres - rect->dy) : rect->height;
+
+       switch(info->var.bits_per_pixel) {
        case 8:  col = rect->color;
                 break;
        case 16:
        case 32: col = ((u32 *)(info->pseudo_palette))[rect->color];
                 break;
-   }
+       }
 
-   if(ivideo->sisvga_engine == SIS_300_VGA) {
+       if(ivideo->sisvga_engine == SIS_300_VGA) {
 #ifdef CONFIG_FB_SIS_300
-      CRITBEGIN
-      SiS300SetupForSolidFill(ivideo, col, myrops[rect->rop]);
-      SiS300SubsequentSolidFillRect(ivideo, rect->dx, rect->dy, width, height);
-      CRITEND
-      SiS300Sync(ivideo);
+               CRITBEGIN
+               SiS300SetupForSolidFill(ivideo, col, myrops[rect->rop]);
+               SiS300SubsequentSolidFillRect(ivideo, rect->dx, rect->dy, width, height);
+               CRITEND
 #endif
-   } else {
+       } else {
 #ifdef CONFIG_FB_SIS_315
-      CRITBEGIN
-      SiS310SetupForSolidFill(ivideo, col, myrops[rect->rop]);
-      SiS310SubsequentSolidFillRect(ivideo, rect->dx, rect->dy, width, height);
-      CRITEND
-      SiS310Sync(ivideo);
+               CRITBEGIN
+               SiS310SetupForSolidFill(ivideo, col, myrops[rect->rop]);
+               SiS310SubsequentSolidFillRect(ivideo, rect->dx, rect->dy, width, height);
+               CRITEND
 #endif
-   }
+       }
 
+       sisfb_syncaccel(ivideo);
 }
 
 void fbcon_sis_copyarea(struct fb_info *info, const struct fb_copyarea *area)
 {
-   struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
-   u32 vxres = info->var.xres_virtual;
-   u32 vyres = info->var.yres_virtual;
-   int width = area->width;
-   int height = area->height;
-   CRITFLAGS
-
-   if(info->state != FBINFO_STATE_RUNNING) {
-       return;
-   }
-
-   if(!ivideo->accel) {
-       cfb_copyarea(info, area);
-       return;
-   }
-
-   if(!width || !height ||
-      area->sx >= vxres || area->sy >= vyres ||
-      area->dx >= vxres || area->dy >= vyres) {
-       return;
-   }
-
-   /* Clipping */
-   if((area->sx + width) > vxres) width = vxres - area->sx;
-   if((area->dx + width) > vxres) width = vxres - area->dx;
-   if((area->sy + height) > vyres) height = vyres - area->sy;
-   if((area->dy + height) > vyres) height = vyres - area->dy;
-
-   if(ivideo->sisvga_engine == SIS_300_VGA) {
-#ifdef CONFIG_FB_SIS_300
-      int xdir, ydir;
-
-      if(area->sx < area->dx) xdir = 0;
-      else                    xdir = 1;
-      if(area->sy < area->dy) ydir = 0;
-      else                    ydir = 1;
-
-      CRITBEGIN
-      SiS300SetupForScreenToScreenCopy(ivideo, xdir, ydir, 3, -1);
-      SiS300SubsequentScreenToScreenCopy(ivideo, area->sx, area->sy, area->dx, area->dy,
-                                        width, height);
-      CRITEND
-      SiS300Sync(ivideo);
-#endif
-   } else {
-#ifdef CONFIG_FB_SIS_315
-      CRITBEGIN
-      SiS310SetupForScreenToScreenCopy(ivideo, 3, -1);
-      SiS310SubsequentScreenToScreenCopy(ivideo, area->sx, area->sy, area->dx, area->dy,
-                                        width, height);
-      CRITEND
-      SiS310Sync(ivideo);
-#endif
-   }
-}
-
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)  /* -------------- 2.4 --------------- */
-
-void fbcon_sis_bmove(struct display *p, int srcy, int srcx,
-                           int dsty, int dstx, int height, int width)
-{
-       struct sis_video_info *ivideo = (struct sis_video_info *)p->fb_info->par;
-
+       struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
+       u32 vxres = info->var.xres_virtual;
+       u32 vyres = info->var.yres_virtual;
+       int width = area->width;
+       int height = area->height;
        CRITFLAGS
 
-       if(!ivideo->accel) {
-           switch(ivideo->video_bpp) {
-           case 8:
-#ifdef FBCON_HAS_CFB8
-              fbcon_cfb8_bmove(p, srcy, srcx, dsty, dstx, height, width);
-#endif
-              break;
-           case 16:
-#ifdef FBCON_HAS_CFB16
-              fbcon_cfb16_bmove(p, srcy, srcx, dsty, dstx, height, width);
-#endif
-              break;
-           case 32:
-#ifdef FBCON_HAS_CFB32
-              fbcon_cfb32_bmove(p, srcy, srcx, dsty, dstx, height, width);
-#endif
-              break;
-            }
-           return;
-       }
-
-       srcx *= fontwidth(p);
-       srcy *= fontheight(p);
-       dstx *= fontwidth(p);
-       dsty *= fontheight(p);
-       width *= fontwidth(p);
-       height *= fontheight(p);
+       if(info->state != FBINFO_STATE_RUNNING)
+               return;
 
-       if(ivideo->sisvga_engine == SIS_300_VGA) {
-#ifdef CONFIG_FB_SIS_300
-          int xdir, ydir;
-
-          if(srcx < dstx) xdir = 0;
-          else            xdir = 1;
-          if(srcy < dsty) ydir = 0;
-          else            ydir = 1;
-
-          CRITBEGIN
-          SiS300SetupForScreenToScreenCopy(ivideo, xdir, ydir, 3, -1);
-          SiS300SubsequentScreenToScreenCopy(ivideo, srcx, srcy, dstx, dsty, width, height);
-          CRITEND
-          SiS300Sync(ivideo);
-#endif
-       } else {
-#ifdef CONFIG_FB_SIS_315
-          CRITBEGIN
-          SiS310SetupForScreenToScreenCopy(ivideo, 3, -1);
-          SiS310SubsequentScreenToScreenCopy(ivideo, srcx, srcy, dstx, dsty, width, height);
-          CRITEND
-          SiS310Sync(ivideo);
-#endif
+       if((!ivideo->accel) || (!ivideo->engineok)) {
+               cfb_copyarea(info, area);
+               return;
        }
-}
 
-static void fbcon_sis_clear(struct vc_data *conp, struct display *p,
-                       int srcy, int srcx, int height, int width, int color)
-{
-        struct sis_video_info *ivideo = (struct sis_video_info *)p->fb_info->par;
-       CRITFLAGS
+       if(!width || !height ||
+          area->sx >= vxres || area->sy >= vyres ||
+          area->dx >= vxres || area->dy >= vyres)
+               return;
 
-       srcx *= fontwidth(p);
-       srcy *= fontheight(p);
-       width *= fontwidth(p);
-       height *= fontheight(p);
+       /* Clipping */
+       if((area->sx + width) > vxres) width = vxres - area->sx;
+       if((area->dx + width) > vxres) width = vxres - area->dx;
+       if((area->sy + height) > vyres) height = vyres - area->sy;
+       if((area->dy + height) > vyres) height = vyres - area->dy;
 
        if(ivideo->sisvga_engine == SIS_300_VGA) {
 #ifdef CONFIG_FB_SIS_300
-          CRITBEGIN
-          SiS300SetupForSolidFill(ivideo, color, 3);
-          SiS300SubsequentSolidFillRect(ivideo, srcx, srcy, width, height);
-          CRITEND
-          SiS300Sync(ivideo);
+               int xdir, ydir;
+
+               if(area->sx < area->dx) xdir = 0;
+               else                    xdir = 1;
+               if(area->sy < area->dy) ydir = 0;
+               else                    ydir = 1;
+
+               CRITBEGIN
+               SiS300SetupForScreenToScreenCopy(ivideo, xdir, ydir, 3, -1);
+               SiS300SubsequentScreenToScreenCopy(ivideo, area->sx, area->sy,
+                                       area->dx, area->dy, width, height);
+               CRITEND
 #endif
        } else {
 #ifdef CONFIG_FB_SIS_315
-          CRITBEGIN
-          SiS310SetupForSolidFill(ivideo, color, 3);
-          SiS310SubsequentSolidFillRect(ivideo, srcx, srcy, width, height);
-          CRITEND
-          SiS310Sync(ivideo);
-#endif
-       }
-}
-
-void fbcon_sis_clear8(struct vc_data *conp, struct display *p,
-                       int srcy, int srcx, int height, int width)
-{
-       struct sis_video_info *ivideo = (struct sis_video_info *)p->fb_info->par;
-       u32 bgx;
-
-       if(!ivideo->accel) {
-#ifdef FBCON_HAS_CFB8
-           fbcon_cfb8_clear(conp, p, srcy, srcx, height, width);
+               CRITBEGIN
+               SiS310SetupForScreenToScreenCopy(ivideo, 3, -1);
+               SiS310SubsequentScreenToScreenCopy(ivideo, area->sx, area->sy,
+                                       area->dx, area->dy, width, height);
+               CRITEND
 #endif
-           return;
        }
 
-       bgx = attr_bgcol_ec(p, conp);
-       fbcon_sis_clear(conp, p, srcy, srcx, height, width, bgx);
+       sisfb_syncaccel(ivideo);
 }
 
-void fbcon_sis_clear16(struct vc_data *conp, struct display *p,
-                       int srcy, int srcx, int height, int width)
-{
-        struct sis_video_info *ivideo = (struct sis_video_info *)p->fb_info->par;
-       u32 bgx;
-
-       if(!ivideo->accel) {
-#ifdef FBCON_HAS_CFB16
-           fbcon_cfb16_clear(conp, p, srcy, srcx, height, width);
 #endif
-           return;
-       }
-
-       bgx = ((u_int16_t*)p->dispsw_data)[attr_bgcol_ec(p, conp)];
-       fbcon_sis_clear(conp, p, srcy, srcx, height, width, bgx);
-}
 
-void fbcon_sis_clear32(struct vc_data *conp, struct display *p,
-                       int srcy, int srcx, int height, int width)
-{
-       struct sis_video_info *ivideo = (struct sis_video_info *)p->fb_info->par;
-       u32 bgx;
-
-       if(!ivideo->accel) {
-#ifdef FBCON_HAS_CFB32
-           fbcon_cfb32_clear(conp, p, srcy, srcx, height, width);
-#endif
-           return;
-       }
-
-       bgx = ((u_int32_t*)p->dispsw_data)[attr_bgcol_ec(p, conp)];
-       fbcon_sis_clear(conp, p, srcy, srcx, height, width, bgx);
-}
-
-void fbcon_sis_revc(struct display *p, int srcx, int srcy)
-{
-       struct sis_video_info *ivideo = (struct sis_video_info *)p->fb_info->par;
-       CRITFLAGS
-
-       if(!ivideo->accel) {
-           switch(ivideo->video_bpp) {
-           case 16:
-#ifdef FBCON_HAS_CFB16
-              fbcon_cfb16_revc(p, srcx, srcy);
-#endif
-              break;
-           case 32:
-#ifdef FBCON_HAS_CFB32
-              fbcon_cfb32_revc(p, srcx, srcy);
-#endif
-              break;
-            }
-           return;
-       }
-
-       srcx *= fontwidth(p);
-       srcy *= fontheight(p);
-
-       if(ivideo->sisvga_engine == SIS_300_VGA) {
-#ifdef CONFIG_FB_SIS_300
-          CRITBEGIN
-          SiS300SetupForSolidFill(ivideo, 0, 0x0a);
-          SiS300SubsequentSolidFillRect(ivideo, srcx, srcy, fontwidth(p), fontheight(p));
-          CRITEND
-          SiS300Sync(ivideo);
-#endif
-       } else {
-#ifdef CONFIG_FB_SIS_315
-          CRITBEGIN
-          SiS310SetupForSolidFill(ivideo, 0, 0x0a);
-          SiS310SubsequentSolidFillRect(ivideo, srcx, srcy, fontwidth(p), fontheight(p));
-          CRITEND
-          SiS310Sync(ivideo);
-#endif
-       }
-}
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)  /* -------------- 2.4 --------------- */
 
-#ifdef FBCON_HAS_CFB8
-struct display_switch fbcon_sis8 = {
-       .setup          = fbcon_cfb8_setup,
-       .bmove          = fbcon_sis_bmove,
-       .clear          = fbcon_sis_clear8,
-       .putc           = fbcon_cfb8_putc,
-       .putcs          = fbcon_cfb8_putcs,
-       .revc           = fbcon_cfb8_revc,
-       .clear_margins  = fbcon_cfb8_clear_margins,
-       .fontwidthmask  = FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
-};
-#endif
-#ifdef FBCON_HAS_CFB16
-struct display_switch fbcon_sis16 = {
-       .setup          = fbcon_cfb16_setup,
-       .bmove          = fbcon_sis_bmove,
-       .clear          = fbcon_sis_clear16,
-       .putc           = fbcon_cfb16_putc,
-       .putcs          = fbcon_cfb16_putcs,
-       .revc           = fbcon_sis_revc,
-       .clear_margins  = fbcon_cfb16_clear_margins,
-       .fontwidthmask  = FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
-};
-#endif
-#ifdef FBCON_HAS_CFB32
-struct display_switch fbcon_sis32 = {
-       .setup          = fbcon_cfb32_setup,
-       .bmove          = fbcon_sis_bmove,
-       .clear          = fbcon_sis_clear32,
-       .putc           = fbcon_cfb32_putc,
-       .putcs          = fbcon_cfb32_putcs,
-       .revc           = fbcon_sis_revc,
-       .clear_margins  = fbcon_cfb32_clear_margins,
-       .fontwidthmask  = FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
-};
-#endif
+#include "sisfb_accel_2_4.h"
 
 #endif /* KERNEL VERSION */
 
index bb28f33..046e2c4 100644 (file)
@@ -1,6 +1,8 @@
 /*
- * SiS 300/630/730/540/315/550/650/740 frame buffer driver
- * for Linux kernels 2.4.x and 2.5.x
+ * SiS 300/540/630[S]/730[S],
+ * SiS 315[E|PRO]/550/[M]650/651/[M]661[F|M]X/740/[M]741[GX]/330/[M]760[GX],
+ * XGI V3XT/V5/V8, Z7
+ * frame buffer driver for Linux kernels >= 2.4.14 and >=2.6.3
  *
  * 2D acceleration part
  *
   { \
        while( (MMIO_IN16(ivideo->mmio_vbase, Q_STATUS+2) & 0x8000) != 0x8000){}; \
        while( (MMIO_IN16(ivideo->mmio_vbase, Q_STATUS+2) & 0x8000) != 0x8000){}; \
+       while( (MMIO_IN16(ivideo->mmio_vbase, Q_STATUS+2) & 0x8000) != 0x8000){}; \
+       while( (MMIO_IN16(ivideo->mmio_vbase, Q_STATUS+2) & 0x8000) != 0x8000){}; \
        CmdQueLen = 0; \
   }
 
@@ -402,6 +406,7 @@ void fbcon_sis_clear32(struct vc_data *conp, struct display *p, int srcy,
                        int srcx, int height, int width);
 #endif
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,34)
+int  fbcon_sis_sync(struct fb_info *info);
 void fbcon_sis_fillrect(struct fb_info *info, const struct fb_fillrect *rect);
 void fbcon_sis_copyarea(struct fb_info *info, const struct fb_copyarea *area);
 #endif
index 6982660..42c54b6 100644 (file)
@@ -1,9 +1,10 @@
 /*
- * SiS 300/305/540/630(S)/730(S)
- * SiS 315(H/PRO)/55x/(M)65x/(M)661(F/M)X/740/741(GX)/330/(M)760
+ * SiS 300/540/630[S]/730[S],
+ * SiS 315[E|PRO]/550/[M]65x/[M]66x[F|M|G]X/[M]74x[GX]/330/[M]76x[GX],
+ * XGI V3XT/V5/V8, Z7
  * frame buffer driver for Linux kernels >= 2.4.14 and >=2.6.3
  *
- * Copyright (C) 2001-2004 Thomas Winischhofer, Vienna, Austria.
+ * Copyright (C) 2001-2005 Thomas Winischhofer, Vienna, Austria.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
  *
- * Author:     Thomas Winischhofer <thomas@winischhofer.net>
+ * Author:     Thomas Winischhofer <thomas@winischhofer.net>
  *
  * Author of (practically wiped) code base:
  *             SiS (www.sis.com)
- *             Copyright (C) 1999 Silicon Integrated Systems, Inc.
+ *             Copyright (C) 1999 Silicon Integrated Systems, Inc.
  *
  * See http://www.winischhofer.net/ for more information and updates
  *
 #include <linux/mm.h>
 #include <linux/tty.h>
 #include <linux/slab.h>
-#include <linux/delay.h>
 #include <linux/fb.h>
-#include <linux/console.h>
 #include <linux/selection.h>
-#include <linux/smp_lock.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/vmalloc.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 #include <linux/vt_kern.h>
+#endif
 #include <linux/capability.h>
 #include <linux/fs.h>
 #include <linux/types.h>
@@ -94,71 +94,75 @@ extern struct display_switch fbcon_sis32;
 #endif
 #endif
 
+static void sisfb_handle_command(struct sis_video_info *ivideo,
+                                struct sisfb_cmd *sisfb_command);
+
 /* ------------------ Internal helper routines ----------------- */
 
 static void __init
 sisfb_setdefaultparms(void)
 {
-       sisfb_off               = 0;
-       sisfb_parm_mem          = 0;
-       sisfb_accel             = -1;
-       sisfb_ypan              = -1;
-       sisfb_max               = -1;
-       sisfb_userom            = -1;
-        sisfb_useoem           = -1;
+       sisfb_off               = 0;
+       sisfb_parm_mem          = 0;
+       sisfb_accel             = -1;
+       sisfb_ypan              = -1;
+       sisfb_max               = -1;
+       sisfb_userom            = -1;
+       sisfb_useoem            = -1;
 #ifdef MODULE
        /* Module: "None" for 2.4, default mode for 2.5+ */
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-       sisfb_mode_idx          = -1;
+       sisfb_mode_idx          = -1;
 #else
-       sisfb_mode_idx          = MODE_INDEX_NONE;
+       sisfb_mode_idx          = MODE_INDEX_NONE;
 #endif
 #else
        /* Static: Default mode */
-       sisfb_mode_idx          = -1;
-#endif
-       sisfb_parm_rate         = -1;
-       sisfb_crt1off           = 0;
-       sisfb_forcecrt1         = -1;
-       sisfb_crt2type          = -1;
-       sisfb_crt2flags         = 0;
-       sisfb_pdc               = 0xff;
-       sisfb_pdca              = 0xff;
-       sisfb_scalelcd          = -1;
+       sisfb_mode_idx          = -1;
+#endif
+       sisfb_parm_rate         = -1;
+       sisfb_crt1off           = 0;
+       sisfb_forcecrt1         = -1;
+       sisfb_crt2type          = -1;
+       sisfb_crt2flags         = 0;
+       sisfb_pdc               = 0xff;
+       sisfb_pdca              = 0xff;
+       sisfb_scalelcd          = -1;
        sisfb_specialtiming     = CUT_NONE;
-       sisfb_lvdshl            = -1;
-       sisfb_dstn              = 0;
-       sisfb_fstn              = 0;
-       sisfb_tvplug            = -1;
-       sisfb_tvstd             = -1;
-       sisfb_tvxposoffset      = 0;
-       sisfb_tvyposoffset      = 0;
-       sisfb_filter            = -1;
-       sisfb_nocrt2rate        = 0;
+       sisfb_lvdshl            = -1;
+       sisfb_dstn              = 0;
+       sisfb_fstn              = 0;
+       sisfb_tvplug            = -1;
+       sisfb_tvstd             = -1;
+       sisfb_tvxposoffset      = 0;
+       sisfb_tvyposoffset      = 0;
+       sisfb_nocrt2rate        = 0;
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-       sisfb_inverse           = 0;
-       sisfb_fontname[0]       = 0;
+       sisfb_inverse           = 0;
+       sisfb_fontname[0]       = 0;
 #endif
 #if !defined(__i386__) && !defined(__x86_64__)
-       sisfb_resetcard         = 0;
-       sisfb_videoram          = 0;
+       sisfb_resetcard         = 0;
+       sisfb_videoram          = 0;
 #endif
 }
 
+/* ------------- Parameter parsing -------------- */
+
 static void __devinit
 sisfb_search_vesamode(unsigned int vesamode, BOOLEAN quiet)
 {
        int i = 0, j = 0;
 
-       /* BEWARE: We don't know the hardware specs yet and there is no ivideo */
+       /* We don't know the hardware specs yet and there is no ivideo */
 
        if(vesamode == 0) {
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
                sisfb_mode_idx = MODE_INDEX_NONE;
 #else
-               if(!quiet) {
-                  printk(KERN_ERR "sisfb: Invalid mode. Using default.\n");
-               }
+               if(!quiet)
+                       printk(KERN_ERR "sisfb: Invalid mode. Using default.\n");
+
                sisfb_mode_idx = DEFAULT_MODE;
 #endif
                return;
@@ -169,95 +173,102 @@ sisfb_search_vesamode(unsigned int vesamode, BOOLEAN quiet)
        while(sisbios_mode[i++].mode_no[0] != 0) {
                if( (sisbios_mode[i-1].vesa_mode_no_1 == vesamode) ||
                    (sisbios_mode[i-1].vesa_mode_no_2 == vesamode) ) {
-                   if(sisfb_fstn) {
-                      if(sisbios_mode[i-1].mode_no[1] == 0x50 ||
-                         sisbios_mode[i-1].mode_no[1] == 0x56 ||
-                         sisbios_mode[i-1].mode_no[1] == 0x53) continue;
-                   } else {
-                      if(sisbios_mode[i-1].mode_no[1] == 0x5a ||
-                         sisbios_mode[i-1].mode_no[1] == 0x5b) continue;
-                   }
-                   sisfb_mode_idx = i - 1;
-                   j = 1;
-                   break;
+                       if(sisfb_fstn) {
+                               if(sisbios_mode[i-1].mode_no[1] == 0x50 ||
+                                  sisbios_mode[i-1].mode_no[1] == 0x56 ||
+                                  sisbios_mode[i-1].mode_no[1] == 0x53)
+                                       continue;
+                       } else {
+                               if(sisbios_mode[i-1].mode_no[1] == 0x5a ||
+                                  sisbios_mode[i-1].mode_no[1] == 0x5b)
+                                       continue;
+                       }
+                       sisfb_mode_idx = i - 1;
+                       j = 1;
+                       break;
                }
        }
-       if((!j) && !quiet) printk(KERN_ERR "sisfb: Invalid VESA mode 0x%x'\n", vesamode);
+       if((!j) && !quiet)
+               printk(KERN_ERR "sisfb: Invalid VESA mode 0x%x'\n", vesamode);
 }
 
-static void
+static void __devinit
 sisfb_search_mode(char *name, BOOLEAN quiet)
 {
-       int i = 0;
        unsigned int j = 0, xres = 0, yres = 0, depth = 0, rate = 0;
+       int i = 0;
        char strbuf[16], strbuf1[20];
        char *nameptr = name;
 
-       /* BEWARE: We don't know the hardware specs yet and there is no ivideo */
+       /* We don't know the hardware specs yet and there is no ivideo */
 
        if(name == NULL) {
-          if(!quiet) {
-             printk(KERN_ERR "sisfb: Internal error, using default mode.\n");
-          }
-          sisfb_mode_idx = DEFAULT_MODE;
-          return;
+               if(!quiet)
+                       printk(KERN_ERR "sisfb: Internal error, using default mode.\n");
+
+               sisfb_mode_idx = DEFAULT_MODE;
+               return;
        }
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-        if(!strnicmp(name, sisbios_mode[MODE_INDEX_NONE].name, strlen(name))) {
-          if(!quiet) {
-             printk(KERN_ERR "sisfb: Mode 'none' not supported anymore. Using default.\n");
-          }
-          sisfb_mode_idx = DEFAULT_MODE;
-          return;
+       if(!strnicmp(name, sisbios_mode[MODE_INDEX_NONE].name, strlen(name))) {
+               if(!quiet)
+                       printk(KERN_ERR "sisfb: Mode 'none' not supported anymore. Using default.\n");
+
+               sisfb_mode_idx = DEFAULT_MODE;
+               return;
        }
 #endif
        if(strlen(name) <= 19) {
-          strcpy(strbuf1, name);
-          for(i=0; i<strlen(strbuf1); i++) {
-             if(strbuf1[i] < '0' || strbuf1[i] > '9') strbuf1[i] = ' ';
-          }
+               strcpy(strbuf1, name);
+               for(i = 0; i < strlen(strbuf1); i++) {
+                       if(strbuf1[i] < '0' || strbuf1[i] > '9') strbuf1[i] = ' ';
+               }
 
-          /* This does some fuzzy mode naming detection */
-          if(sscanf(strbuf1, "%u %u %u %u", &xres, &yres, &depth, &rate) == 4) {
-             if((rate <= 32) || (depth > 32)) {
-                j = rate; rate = depth; depth = j;
-             }
-             sprintf(strbuf, "%ux%ux%u", xres, yres, depth);
-             nameptr = strbuf;
-             sisfb_parm_rate = rate;
-          } else if(sscanf(strbuf1, "%u %u %u", &xres, &yres, &depth) == 3) {
-             sprintf(strbuf, "%ux%ux%u", xres, yres, depth);
-             nameptr = strbuf;
-          } else {
-             xres = 0;
-             if((sscanf(strbuf1, "%u %u", &xres, &yres) == 2) && (xres != 0)) {
-                sprintf(strbuf, "%ux%ux8", xres, yres);
-                nameptr = strbuf;
-             } else {
-                sisfb_search_vesamode(simple_strtoul(name, NULL, 0), quiet);
-                return;
-             }
-          }
+               /* This does some fuzzy mode naming detection */
+               if(sscanf(strbuf1, "%u %u %u %u", &xres, &yres, &depth, &rate) == 4) {
+                       if((rate <= 32) || (depth > 32)) {
+                               j = rate; rate = depth; depth = j;
+                       }
+                       sprintf(strbuf, "%ux%ux%u", xres, yres, depth);
+                       nameptr = strbuf;
+                       sisfb_parm_rate = rate;
+               } else if(sscanf(strbuf1, "%u %u %u", &xres, &yres, &depth) == 3) {
+                       sprintf(strbuf, "%ux%ux%u", xres, yres, depth);
+                       nameptr = strbuf;
+               } else {
+                       xres = 0;
+                       if((sscanf(strbuf1, "%u %u", &xres, &yres) == 2) && (xres != 0)) {
+                               sprintf(strbuf, "%ux%ux8", xres, yres);
+                               nameptr = strbuf;
+                       } else {
+                               sisfb_search_vesamode(simple_strtoul(name, NULL, 0), quiet);
+                               return;
+                       }
+               }
        }
 
        i = 0; j = 0;
        while(sisbios_mode[i].mode_no[0] != 0) {
                if(!strnicmp(nameptr, sisbios_mode[i++].name, strlen(nameptr))) {
-                       if(sisfb_fstn) {
-                               if(sisbios_mode[i-1].mode_no[1] == 0x50 ||
-                                  sisbios_mode[i-1].mode_no[1] == 0x56 ||
-                                  sisbios_mode[i-1].mode_no[1] == 0x53) continue;
-                       } else {
-                               if(sisbios_mode[i-1].mode_no[1] == 0x5a ||
-                                  sisbios_mode[i-1].mode_no[1] == 0x5b) continue;
-                       }
-                       sisfb_mode_idx = i - 1;
-                       j = 1;
-                       break;
-               }
-       }
-       if((!j) && !quiet) printk(KERN_ERR "sisfb: Invalid mode '%s'\n", nameptr);
+                       if(sisfb_fstn) {
+                               if(sisbios_mode[i-1].mode_no[1] == 0x50 ||
+                                  sisbios_mode[i-1].mode_no[1] == 0x56 ||
+                                  sisbios_mode[i-1].mode_no[1] == 0x53)
+                                       continue;
+                       } else {
+                               if(sisbios_mode[i-1].mode_no[1] == 0x5a ||
+                                  sisbios_mode[i-1].mode_no[1] == 0x5b)
+                                       continue;
+                       }
+                       sisfb_mode_idx = i - 1;
+                       j = 1;
+                       break;
+               }
+       }
+
+       if((!j) && !quiet)
+               printk(KERN_ERR "sisfb: Invalid mode '%s'\n", nameptr);
 }
 
 #ifndef MODULE
@@ -265,7 +276,7 @@ static void __devinit
 sisfb_get_vga_mode_from_kernel(void)
 {
 #if (defined(__i386__) || defined(__x86_64__)) && defined(CONFIG_VIDEO_SELECT)
-       char mymode[32];
+       char mymode[32];
        int  mydepth = screen_info.lfb_depth;
 
        if(screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB) return;
@@ -274,15 +285,17 @@ sisfb_get_vga_mode_from_kernel(void)
            (screen_info.lfb_height >= 200) && (screen_info.lfb_height <= 1536) &&
            (mydepth >= 8) && (mydepth <= 32) ) {
 
-           if(mydepth == 24) mydepth = 32;
+               if(mydepth == 24) mydepth = 32;
 
-           sprintf(mymode, "%ux%ux%u", screen_info.lfb_width,
-                                       screen_info.lfb_height,
+               sprintf(mymode, "%ux%ux%u", screen_info.lfb_width,
+                                       screen_info.lfb_height,
                                        mydepth);
 
-           printk(KERN_DEBUG "sisfb: Using vga mode %s pre-set by kernel as default\n", mymode);
+               printk(KERN_DEBUG
+                       "sisfb: Using vga mode %s pre-set by kernel as default\n",
+                       mymode);
 
-           sisfb_search_mode(mymode, TRUE);
+               sisfb_search_mode(mymode, TRUE);
        }
 #endif
        return;
@@ -294,26 +307,25 @@ sisfb_search_crt2type(const char *name)
 {
        int i = 0;
 
-       /* BEWARE: We don't know the hardware specs yet and there is no ivideo */
+       /* We don't know the hardware specs yet and there is no ivideo */
 
        if(name == NULL) return;
 
        while(sis_crt2type[i].type_no != -1) {
-               if(!strnicmp(name, sis_crt2type[i].name, strlen(sis_crt2type[i].name))) {
-                       sisfb_crt2type = sis_crt2type[i].type_no;
-                       sisfb_tvplug = sis_crt2type[i].tvplug_no;
-                       sisfb_crt2flags = sis_crt2type[i].flags;
-                       break;
-               }
-               i++;
+               if(!strnicmp(name, sis_crt2type[i].name, strlen(sis_crt2type[i].name))) {
+                       sisfb_crt2type = sis_crt2type[i].type_no;
+                       sisfb_tvplug = sis_crt2type[i].tvplug_no;
+                       sisfb_crt2flags = sis_crt2type[i].flags;
+                       break;
+               }
+               i++;
        }
 
        sisfb_dstn = (sisfb_crt2flags & FL_550_DSTN) ? 1 : 0;
        sisfb_fstn = (sisfb_crt2flags & FL_550_FSTN) ? 1 : 0;
 
-       if(sisfb_crt2type < 0) {
+       if(sisfb_crt2type < 0)
                printk(KERN_ERR "sisfb: Invalid CRT2 type: %s\n", name);
-       }
 }
 
 static void __init
@@ -321,16 +333,17 @@ sisfb_search_tvstd(const char *name)
 {
        int i = 0;
 
-       /* BEWARE: We don't know the hardware specs yet and there is no ivideo */
+       /* We don't know the hardware specs yet and there is no ivideo */
 
-       if(name == NULL) return;
+       if(name == NULL)
+               return;
 
        while(sis_tvtype[i].type_no != -1) {
-               if(!strnicmp(name, sis_tvtype[i].name, strlen(sis_tvtype[i].name))) {
-                       sisfb_tvstd = sis_tvtype[i].type_no;
-                       break;
-               }
-               i++;
+               if(!strnicmp(name, sis_tvtype[i].name, strlen(sis_tvtype[i].name))) {
+                       sisfb_tvstd = sis_tvtype[i].type_no;
+                       break;
+               }
+               i++;
        }
 }
 
@@ -340,38 +353,101 @@ sisfb_search_specialtiming(const char *name)
        int i = 0;
        BOOLEAN found = FALSE;
 
-       /* BEWARE: We don't know the hardware specs yet and there is no ivideo */
+       /* We don't know the hardware specs yet and there is no ivideo */
 
-       if(name == NULL) return;
+       if(name == NULL)
+               return;
 
        if(!strnicmp(name, "none", 4)) {
-               sisfb_specialtiming = CUT_FORCENONE;
+               sisfb_specialtiming = CUT_FORCENONE;
                printk(KERN_DEBUG "sisfb: Special timing disabled\n");
        } else {
-          while(mycustomttable[i].chipID != 0) {
-             if(!strnicmp(name,mycustomttable[i].optionName, strlen(mycustomttable[i].optionName))) {
-                sisfb_specialtiming = mycustomttable[i].SpecialID;
-                found = TRUE;
-                printk(KERN_INFO "sisfb: Special timing for %s %s forced (\"%s\")\n",
-                       mycustomttable[i].vendorName, mycustomttable[i].cardName,
-                       mycustomttable[i].optionName);
-                break;
-             }
-             i++;
-          }
-          if(!found) {
-             printk(KERN_WARNING "sisfb: Invalid SpecialTiming parameter, valid are:");
-             printk(KERN_WARNING "\t\"none\" (to disable special timings)\n");
-             i = 0;
-             while(mycustomttable[i].chipID != 0) {
-                printk(KERN_WARNING "\t\"%s\" (for %s %s)\n",
-                    mycustomttable[i].optionName,
-                    mycustomttable[i].vendorName,
-                    mycustomttable[i].cardName);
-                i++;
-             }
-           }
-       }
+               while(mycustomttable[i].chipID != 0) {
+                       if(!strnicmp(name,mycustomttable[i].optionName,
+                          strlen(mycustomttable[i].optionName))) {
+                               sisfb_specialtiming = mycustomttable[i].SpecialID;
+                               found = TRUE;
+                               printk(KERN_INFO "sisfb: Special timing for %s %s forced (\"%s\")\n",
+                                       mycustomttable[i].vendorName,
+                                       mycustomttable[i].cardName,
+                                       mycustomttable[i].optionName);
+                               break;
+                       }
+                       i++;
+               }
+               if(!found) {
+                       printk(KERN_WARNING "sisfb: Invalid SpecialTiming parameter, valid are:");
+                       printk(KERN_WARNING "\t\"none\" (to disable special timings)\n");
+                       i = 0;
+                       while(mycustomttable[i].chipID != 0) {
+                               printk(KERN_WARNING "\t\"%s\" (for %s %s)\n",
+                                       mycustomttable[i].optionName,
+                                       mycustomttable[i].vendorName,
+                                       mycustomttable[i].cardName);
+                               i++;
+                       }
+               }
+       }
+}
+
+/* ----------- Various detection routines ----------- */
+
+static void __devinit
+sisfb_detect_custom_timing(struct sis_video_info *ivideo)
+{
+       unsigned char *biosver = NULL;
+       unsigned char *biosdate = NULL;
+       BOOLEAN footprint;
+       u32 chksum = 0;
+       int i, j;
+
+       if(ivideo->SiS_Pr.UseROM) {
+               biosver = ivideo->SiS_Pr.VirtualRomBase + 0x06;
+               biosdate = ivideo->SiS_Pr.VirtualRomBase + 0x2c;
+               for(i = 0; i < 32768; i++)
+                       chksum += ivideo->SiS_Pr.VirtualRomBase[i];
+       }
+
+       i = 0;
+       do {
+               if( (mycustomttable[i].chipID == ivideo->chip)                  &&
+                   ((!strlen(mycustomttable[i].biosversion)) ||
+                    (ivideo->SiS_Pr.UseROM &&
+                     (!strncmp(mycustomttable[i].biosversion, biosver,
+                               strlen(mycustomttable[i].biosversion)))))       &&
+                   ((!strlen(mycustomttable[i].biosdate)) ||
+                    (ivideo->SiS_Pr.UseROM &&
+                     (!strncmp(mycustomttable[i].biosdate, biosdate,
+                               strlen(mycustomttable[i].biosdate)))))          &&
+                   ((!mycustomttable[i].bioschksum) ||
+                    (ivideo->SiS_Pr.UseROM &&
+                     (mycustomttable[i].bioschksum == chksum)))                &&
+                   (mycustomttable[i].pcisubsysvendor == ivideo->subsysvendor) &&
+                   (mycustomttable[i].pcisubsyscard == ivideo->subsysdevice) ) {
+                       footprint = TRUE;
+                       for(j = 0; j < 5; j++) {
+                               if(mycustomttable[i].biosFootprintAddr[j]) {
+                                       if(ivideo->SiS_Pr.UseROM) {
+                                               if(ivideo->SiS_Pr.VirtualRomBase[mycustomttable[i].biosFootprintAddr[j]] !=
+                                                       mycustomttable[i].biosFootprintData[j]) {
+                                                       footprint = FALSE;
+                                               }
+                                       } else
+                                               footprint = FALSE;
+                               }
+                       }
+                       if(footprint) {
+                               ivideo->SiS_Pr.SiS_CustomT = mycustomttable[i].SpecialID;
+                               printk(KERN_DEBUG "sisfb: Identified [%s %s], special timing applies\n",
+                                       mycustomttable[i].vendorName,
+                               mycustomttable[i].cardName);
+                               printk(KERN_DEBUG "sisfb: [specialtiming parameter name: %s]\n",
+                                       mycustomttable[i].optionName);
+                               break;
+                       }
+               }
+               i++;
+       } while(mycustomttable[i].chipID);
 }
 
 static BOOLEAN __devinit
@@ -384,22 +460,23 @@ sisfb_interpret_edid(struct sisfb_monitor *monitor, u8 *buffer)
           buffer[2] != 0xff || buffer[3] != 0xff ||
           buffer[4] != 0xff || buffer[5] != 0xff ||
           buffer[6] != 0xff || buffer[7] != 0x00) {
-          printk(KERN_DEBUG "sisfb: Bad EDID header\n");
-          return FALSE;
+               printk(KERN_DEBUG "sisfb: Bad EDID header\n");
+               return FALSE;
        }
 
        if(buffer[0x12] != 0x01) {
-          printk(KERN_INFO "sisfb: EDID version %d not supported\n",
-               buffer[0x12]);
-          return FALSE;
+               printk(KERN_INFO "sisfb: EDID version %d not supported\n",
+                       buffer[0x12]);
+               return FALSE;
        }
 
        monitor->feature = buffer[0x18];
 
        if(!buffer[0x14] & 0x80) {
-          if(!(buffer[0x14] & 0x08)) {
-             printk(KERN_INFO "sisfb: WARNING: Monitor does not support separate syncs\n");
-          }
+               if(!(buffer[0x14] & 0x08)) {
+                       printk(KERN_INFO
+                               "sisfb: WARNING: Monitor does not support separate syncs\n");
+               }
        }
 
        if(buffer[0x13] >= 0x01) {
@@ -409,7 +486,7 @@ sisfb_interpret_edid(struct sisfb_monitor *monitor, u8 *buffer)
            j = 0x36;
            for(i=0; i<4; i++) {
               if(buffer[j]     == 0x00 && buffer[j + 1] == 0x00 &&
-                 buffer[j + 2] == 0x00 && buffer[j + 3] == 0xfd &&
+                 buffer[j + 2] == 0x00 && buffer[j + 3] == 0xfd &&
                  buffer[j + 4] == 0x00) {
                  monitor->hmin = buffer[j + 7];
                  monitor->hmax = buffer[j + 8];
@@ -435,7 +512,7 @@ sisfb_interpret_edid(struct sisfb_monitor *monitor, u8 *buffer)
           emodes = buffer[0x23] | (buffer[0x24] << 8) | (buffer[0x25] << 16);
           for(i = 0; i < 13; i++) {
              if(emodes & sisfb_ddcsmodes[i].mask) {
-                if(monitor->hmin > sisfb_ddcsmodes[i].h) monitor->hmin = sisfb_ddcsmodes[i].h;
+                if(monitor->hmin > sisfb_ddcsmodes[i].h) monitor->hmin = sisfb_ddcsmodes[i].h;
                 if(monitor->hmax < sisfb_ddcsmodes[i].h) monitor->hmax = sisfb_ddcsmodes[i].h + 1;
                 if(monitor->vmin > sisfb_ddcsmodes[i].v) monitor->vmin = sisfb_ddcsmodes[i].v;
                 if(monitor->vmax < sisfb_ddcsmodes[i].v) monitor->vmax = sisfb_ddcsmodes[i].v;
@@ -446,80 +523,81 @@ sisfb_interpret_edid(struct sisfb_monitor *monitor, u8 *buffer)
           for(i = 0; i < 8; i++) {
              xres = (buffer[index] + 31) * 8;
              switch(buffer[index + 1] & 0xc0) {
-                case 0xc0: yres = (xres * 9) / 16; break;
-                case 0x80: yres = (xres * 4) /  5; break;
-                case 0x40: yres = (xres * 3) /  4; break;
-                default:   yres = xres;            break;
+                case 0xc0: yres = (xres * 9) / 16; break;
+                case 0x80: yres = (xres * 4) /  5; break;
+                case 0x40: yres = (xres * 3) /  4; break;
+                default:   yres = xres;            break;
              }
              refresh = (buffer[index + 1] & 0x3f) + 60;
              if((xres >= 640) && (yres >= 480)) {
-                 for(j = 0; j < 8; j++) {
-                   if((xres == sisfb_ddcfmodes[j].x) &&
-                      (yres == sisfb_ddcfmodes[j].y) &&
+                for(j = 0; j < 8; j++) {
+                   if((xres == sisfb_ddcfmodes[j].x) &&
+                      (yres == sisfb_ddcfmodes[j].y) &&
                       (refresh == sisfb_ddcfmodes[j].v)) {
                      if(monitor->hmin > sisfb_ddcfmodes[j].h) monitor->hmin = sisfb_ddcfmodes[j].h;
                      if(monitor->hmax < sisfb_ddcfmodes[j].h) monitor->hmax = sisfb_ddcfmodes[j].h + 1;
                      if(monitor->vmin > sisfb_ddcsmodes[j].v) monitor->vmin = sisfb_ddcsmodes[j].v;
                      if(monitor->vmax < sisfb_ddcsmodes[j].v) monitor->vmax = sisfb_ddcsmodes[j].v;
-                     if(monitor->dclockmax < sisfb_ddcsmodes[j].d) monitor->dclockmax = sisfb_ddcsmodes[i].d;
-                   }
-                }
+                     if(monitor->dclockmax < sisfb_ddcsmodes[j].d) monitor->dclockmax = sisfb_ddcsmodes[j].d;
+                   }
+                }
              }
              index += 2;
-           }
+          }
           if((monitor->hmin <= monitor->hmax) && (monitor->vmin <= monitor->vmax)) {
              monitor->datavalid = TRUE;
           }
        }
 
-       return(monitor->datavalid);
+       return monitor->datavalid;
 }
 
 static void __devinit
 sisfb_handle_ddc(struct sis_video_info *ivideo, struct sisfb_monitor *monitor, int crtno)
 {
-       USHORT  temp, i, realcrtno = crtno;
-       u8      buffer[256];
+       unsigned short temp, i, realcrtno = crtno;
+       unsigned char  buffer[256];
 
        monitor->datavalid = FALSE;
 
        if(crtno) {
-                  if(ivideo->vbflags & CRT2_LCD)      realcrtno = 1;
-          else if(ivideo->vbflags & CRT2_VGA) realcrtno = 2;
-          else return;
-       }
+          if(ivideo->vbflags & CRT2_LCD)      realcrtno = 1;
+          else if(ivideo->vbflags & CRT2_VGA) realcrtno = 2;
+          else return;
+       }
 
-       if((ivideo->sisfb_crt1off) && (!crtno)) return;
+       if((ivideo->sisfb_crt1off) && (!crtno))
+               return;
 
-       temp = SiS_HandleDDC(&ivideo->SiS_Pr, ivideo->vbflags, ivideo->sisvga_engine,
-                               realcrtno, 0, &buffer[0]);
-       if((!temp) || (temp == 0xffff)) {
-          printk(KERN_INFO "sisfb: CRT%d DDC probing failed\n", crtno + 1);
+       temp = SiS_HandleDDC(&ivideo->SiS_Pr, ivideo->vbflags, ivideo->sisvga_engine,
+                               realcrtno, 0, &buffer[0], ivideo->vbflags2);
+       if((!temp) || (temp == 0xffff)) {
+          printk(KERN_INFO "sisfb: CRT%d DDC probing failed\n", crtno + 1);
           return;
-       } else {
-          printk(KERN_INFO "sisfb: CRT%d DDC supported\n", crtno + 1);
-          printk(KERN_INFO "sisfb: CRT%d DDC level: %s%s%s%s\n",
-               crtno + 1,
-               (temp & 0x1a) ? "" : "[none of the supported]",
-               (temp & 0x02) ? "2 " : "",
-               (temp & 0x08) ? "D&P" : "",
-               (temp & 0x10) ? "FPDI-2" : "");
-          if(temp & 0x02) {
+       } else {
+          printk(KERN_INFO "sisfb: CRT%d DDC supported\n", crtno + 1);
+          printk(KERN_INFO "sisfb: CRT%d DDC level: %s%s%s%s\n",
+               crtno + 1,
+               (temp & 0x1a) ? "" : "[none of the supported]",
+               (temp & 0x02) ? "2 " : "",
+               (temp & 0x08) ? "D&P" : "",
+               (temp & 0x10) ? "FPDI-2" : "");
+          if(temp & 0x02) {
              i = 3;  /* Number of retrys */
              do {
-                temp = SiS_HandleDDC(&ivideo->SiS_Pr, ivideo->vbflags, ivideo->sisvga_engine,
-                                    realcrtno, 1, &buffer[0]);
+                temp = SiS_HandleDDC(&ivideo->SiS_Pr, ivideo->vbflags, ivideo->sisvga_engine,
+                                    realcrtno, 1, &buffer[0], ivideo->vbflags2);
              } while((temp) && i--);
-              if(!temp) {
-                if(sisfb_interpret_edid(monitor, &buffer[0])) {
+             if(!temp) {
+                if(sisfb_interpret_edid(monitor, &buffer[0])) {
                    printk(KERN_INFO "sisfb: Monitor range H %d-%dKHz, V %d-%dHz, Max. dotclock %dMHz\n",
-                       monitor->hmin, monitor->hmax, monitor->vmin, monitor->vmax,
+                       monitor->hmin, monitor->hmax, monitor->vmin, monitor->vmax,
                        monitor->dclockmax / 1000);
                 } else {
-                   printk(KERN_INFO "sisfb: CRT%d DDC EDID corrupt\n", crtno + 1);
-                }
+                   printk(KERN_INFO "sisfb: CRT%d DDC EDID corrupt\n", crtno + 1);
+                }
              } else {
-                printk(KERN_INFO "sisfb: CRT%d DDC reading failed\n", crtno + 1);
+                printk(KERN_INFO "sisfb: CRT%d DDC reading failed\n", crtno + 1);
              }
           } else {
              printk(KERN_INFO "sisfb: VESA D&P and FPDI-2 not supported yet\n");
@@ -527,6 +605,8 @@ sisfb_handle_ddc(struct sis_video_info *ivideo, struct sisfb_monitor *monitor, i
        }
 }
 
+/* -------------- Mode validation --------------- */
+
 static BOOLEAN
 sisfb_verify_rate(struct sis_video_info *ivideo, struct sisfb_monitor *monitor,
                int mode_idx, int rate_idx, int rate)
@@ -534,42 +614,49 @@ sisfb_verify_rate(struct sis_video_info *ivideo, struct sisfb_monitor *monitor,
        int htotal, vtotal;
        unsigned int dclock, hsync;
 
-       if(!monitor->datavalid) return TRUE;
+       if(!monitor->datavalid)
+               return TRUE;
 
-       if(mode_idx < 0) return FALSE;
+       if(mode_idx < 0)
+               return FALSE;
 
        /* Skip for 320x200, 320x240, 640x400 */
-       switch(sisbios_mode[mode_idx].mode_no[ivideo->mni]) {
-       case 0x59:
-       case 0x41:
-       case 0x4f:
-       case 0x50:
-       case 0x56:
-       case 0x53:
-       case 0x2f:
-       case 0x5d:
-       case 0x5e:
-               return TRUE;
+       switch(sisbios_mode[mode_idx].mode_no[ivideo->mni]) {
+       case 0x59:
+       case 0x41:
+       case 0x4f:
+       case 0x50:
+       case 0x56:
+       case 0x53:
+       case 0x2f:
+       case 0x5d:
+       case 0x5e:
+               return TRUE;
 #ifdef CONFIG_FB_SIS_315
        case 0x5a:
        case 0x5b:
                if(ivideo->sisvga_engine == SIS_315_VGA) return TRUE;
 #endif
-       }
+       }
 
-       if(rate < (monitor->vmin - 1)) return FALSE;
-       if(rate > (monitor->vmax + 1)) return FALSE;
+       if(rate < (monitor->vmin - 1))
+               return FALSE;
+       if(rate > (monitor->vmax + 1))
+               return FALSE;
 
-       if(sisfb_gettotalfrommode(&ivideo->SiS_Pr, &ivideo->sishw_ext,
+       if(sisfb_gettotalfrommode(&ivideo->SiS_Pr,
                                  sisbios_mode[mode_idx].mode_no[ivideo->mni],
-                                 &htotal, &vtotal, rate_idx)) {
+                                 &htotal, &vtotal, rate_idx)) {
                dclock = (htotal * vtotal * rate) / 1000;
-               if(dclock > (monitor->dclockmax + 1000)) return FALSE;
+               if(dclock > (monitor->dclockmax + 1000))
+                       return FALSE;
                hsync = dclock / htotal;
-               if(hsync < (monitor->hmin - 1)) return FALSE;
-               if(hsync > (monitor->hmax + 1)) return FALSE;
+               if(hsync < (monitor->hmin - 1))
+                       return FALSE;
+               if(hsync > (monitor->hmax + 1))
+                       return FALSE;
         } else {
-               return FALSE;
+               return FALSE;
        }
        return TRUE;
 }
@@ -577,82 +664,79 @@ sisfb_verify_rate(struct sis_video_info *ivideo, struct sisfb_monitor *monitor,
 static int
 sisfb_validate_mode(struct sis_video_info *ivideo, int myindex, u32 vbflags)
 {
-   u16 xres=0, yres, myres;
+       u16 xres=0, yres, myres;
 
 #ifdef CONFIG_FB_SIS_300
-   if(ivideo->sisvga_engine == SIS_300_VGA) {
-      if(!(sisbios_mode[myindex].chipset & MD_SIS300)) return(-1);
-   }
+       if(ivideo->sisvga_engine == SIS_300_VGA) {
+               if(!(sisbios_mode[myindex].chipset & MD_SIS300))
+                       return -1 ;
+       }
 #endif
 #ifdef CONFIG_FB_SIS_315
-   if(ivideo->sisvga_engine == SIS_315_VGA) {
-      if(!(sisbios_mode[myindex].chipset & MD_SIS315)) return(-1);
-   }
+       if(ivideo->sisvga_engine == SIS_315_VGA) {
+               if(!(sisbios_mode[myindex].chipset & MD_SIS315))
+                       return -1;
+       }
 #endif
 
-   myres = sisbios_mode[myindex].yres;
+       myres = sisbios_mode[myindex].yres;
 
-   switch(vbflags & VB_DISPTYPE_DISP2) {
+       switch(vbflags & VB_DISPTYPE_DISP2) {
 
-     case CRT2_LCD:
+       case CRT2_LCD:
+               xres = ivideo->lcdxres; yres = ivideo->lcdyres;
 
-        xres = ivideo->lcdxres; yres = ivideo->lcdyres;
-
-       if(ivideo->SiS_Pr.SiS_CustomT != CUT_PANEL848) {
-               if(sisbios_mode[myindex].xres > xres) return(-1);
-               if(myres > yres) return(-1);
-       }
+               if((ivideo->SiS_Pr.SiS_CustomT != CUT_PANEL848) &&
+                  (ivideo->SiS_Pr.SiS_CustomT != CUT_PANEL856)) {
+                       if(sisbios_mode[myindex].xres > xres)
+                               return -1;
+                       if(myres > yres)
+                               return -1;
+               }
 
-       if(vbflags & (VB_LVDS | VB_30xBDH)) {
-          if(sisbios_mode[myindex].xres == 320) {
-             if((myres == 240) || (myres == 480)) {
-                if(!ivideo->sisfb_fstn) {
-                   if(sisbios_mode[myindex].mode_no[1] == 0x5a ||
-                      sisbios_mode[myindex].mode_no[1] == 0x5b)
-                      return(-1);
-                } else {
-                   if(sisbios_mode[myindex].mode_no[1] == 0x50 ||
-                      sisbios_mode[myindex].mode_no[1] == 0x56 ||
-                      sisbios_mode[myindex].mode_no[1] == 0x53)
-                      return(-1);
-                }
-             }
-          }
-       }
+               if(ivideo->sisfb_fstn) {
+                       if(sisbios_mode[myindex].xres == 320) {
+                               if(myres == 240) {
+                                       switch(sisbios_mode[myindex].mode_no[1]) {
+                                               case 0x50: myindex = MODE_FSTN_8;  break;
+                                               case 0x56: myindex = MODE_FSTN_16; break;
+                                               case 0x53: return -1;
+                                       }
+                               }
+                       }
+               }
 
-       if(SiS_GetModeID_LCD(ivideo->sisvga_engine, vbflags, sisbios_mode[myindex].xres,
-                            sisbios_mode[myindex].yres, 0, ivideo->sisfb_fstn,
-                            ivideo->SiS_Pr.SiS_CustomT, xres, yres) < 0x14) {
-               return(-1);
-       }
-       break;
+               if(SiS_GetModeID_LCD(ivideo->sisvga_engine, vbflags, sisbios_mode[myindex].xres,
+                               sisbios_mode[myindex].yres, 0, ivideo->sisfb_fstn,
+                               ivideo->SiS_Pr.SiS_CustomT, xres, yres, ivideo->vbflags2) < 0x14) {
+                       return -1;
+               }
+               break;
 
-     case CRT2_TV:
-       if(SiS_GetModeID_TV(ivideo->sisvga_engine, vbflags, sisbios_mode[myindex].xres,
-                           sisbios_mode[myindex].yres, 0) < 0x14) {
-               return(-1);
-       }
-       break;
+       case CRT2_TV:
+               if(SiS_GetModeID_TV(ivideo->sisvga_engine, vbflags, sisbios_mode[myindex].xres,
+                               sisbios_mode[myindex].yres, 0, ivideo->vbflags2) < 0x14) {
+                       return -1;
+               }
+               break;
 
-     case CRT2_VGA:
-        if(SiS_GetModeID_VGA2(ivideo->sisvga_engine, vbflags, sisbios_mode[myindex].xres,
-                             sisbios_mode[myindex].yres, 0) < 0x14) {
-               return(-1);
+       case CRT2_VGA:
+               if(SiS_GetModeID_VGA2(ivideo->sisvga_engine, vbflags, sisbios_mode[myindex].xres,
+                               sisbios_mode[myindex].yres, 0, ivideo->vbflags2) < 0x14) {
+                       return -1;
+               }
+               break;
        }
-       break;
-     }
 
-     return(myindex);
+       return myindex;
 }
 
 static u8
 sisfb_search_refresh_rate(struct sis_video_info *ivideo, unsigned int rate, int mode_idx)
 {
-       u16 xres, yres;
        int i = 0;
-
-       xres = sisbios_mode[mode_idx].xres;
-       yres = sisbios_mode[mode_idx].yres;
+       u16 xres = sisbios_mode[mode_idx].xres;
+       u16 yres = sisbios_mode[mode_idx].yres;
 
        ivideo->rate_idx = 0;
        while((sisfb_vrate[i].idx != 0) && (sisfb_vrate[i].xres <= xres)) {
@@ -672,14 +756,14 @@ sisfb_search_refresh_rate(struct sis_video_info *ivideo, unsigned int rate, int
                                                rate, sisfb_vrate[i-1].refresh);
                                        ivideo->rate_idx = sisfb_vrate[i-1].idx;
                                        ivideo->refresh_rate = sisfb_vrate[i-1].refresh;
-                               } 
+                               }
                                break;
                        } else if((rate - sisfb_vrate[i].refresh) <= 2) {
                                DPRINTK("sisfb: Adjusting rate from %d down to %d\n",
                                                rate, sisfb_vrate[i].refresh);
-                               ivideo->rate_idx = sisfb_vrate[i].idx;
-                               break;
-                       }
+                               ivideo->rate_idx = sisfb_vrate[i].idx;
+                               break;
+                       }
                }
                i++;
        }
@@ -695,252 +779,321 @@ sisfb_search_refresh_rate(struct sis_video_info *ivideo, unsigned int rate, int
 static BOOLEAN
 sisfb_bridgeisslave(struct sis_video_info *ivideo)
 {
-   unsigned char P1_00;
+       unsigned char P1_00;
 
-   if(!(ivideo->vbflags & VB_VIDEOBRIDGE)) return FALSE;
+       if(!(ivideo->vbflags2 & VB2_VIDEOBRIDGE))
+               return FALSE;
 
-   inSISIDXREG(SISPART1,0x00,P1_00);
-   if( ((ivideo->sisvga_engine == SIS_300_VGA) && (P1_00 & 0xa0) == 0x20) ||
-       ((ivideo->sisvga_engine == SIS_315_VGA) && (P1_00 & 0x50) == 0x10) ) {
-          return TRUE;
-   } else {
-           return FALSE;
-   }
+       inSISIDXREG(SISPART1,0x00,P1_00);
+       if( ((ivideo->sisvga_engine == SIS_300_VGA) && (P1_00 & 0xa0) == 0x20) ||
+           ((ivideo->sisvga_engine == SIS_315_VGA) && (P1_00 & 0x50) == 0x10) ) {
+               return TRUE;
+       } else {
+               return FALSE;
+       }
 }
 
 static BOOLEAN
 sisfballowretracecrt1(struct sis_video_info *ivideo)
 {
-   u8 temp;
+       u8 temp;
 
-   inSISIDXREG(SISCR,0x17,temp);
-   if(!(temp & 0x80)) return FALSE;
+       inSISIDXREG(SISCR,0x17,temp);
+       if(!(temp & 0x80))
+               return FALSE;
 
-   inSISIDXREG(SISSR,0x1f,temp);
-   if(temp & 0xc0) return FALSE;
+       inSISIDXREG(SISSR,0x1f,temp);
+       if(temp & 0xc0)
+               return FALSE;
 
-   return TRUE;
+       return TRUE;
 }
 
 static BOOLEAN
 sisfbcheckvretracecrt1(struct sis_video_info *ivideo)
 {
-   if(!sisfballowretracecrt1(ivideo)) return FALSE;
+       if(!sisfballowretracecrt1(ivideo))
+               return FALSE;
 
-   if(inSISREG(SISINPSTAT) & 0x08) return TRUE;
-   else                           return FALSE;
+       if(inSISREG(SISINPSTAT) & 0x08)
+               return TRUE;
+       else
+               return FALSE;
 }
 
 static void
 sisfbwaitretracecrt1(struct sis_video_info *ivideo)
 {
-   int watchdog;
+       int watchdog;
 
-   if(!sisfballowretracecrt1(ivideo)) return;
+       if(!sisfballowretracecrt1(ivideo))
+               return;
 
-   watchdog = 65536;
-   while((!(inSISREG(SISINPSTAT) & 0x08)) && --watchdog);
-   watchdog = 65536;
-   while((inSISREG(SISINPSTAT) & 0x08) && --watchdog);
+       watchdog = 65536;
+       while((!(inSISREG(SISINPSTAT) & 0x08)) && --watchdog);
+       watchdog = 65536;
+       while((inSISREG(SISINPSTAT) & 0x08) && --watchdog);
 }
 
 static BOOLEAN
 sisfbcheckvretracecrt2(struct sis_video_info *ivideo)
 {
-   unsigned char temp, reg;
+       unsigned char temp, reg;
 
-   switch(ivideo->sisvga_engine) {
-   case SIS_300_VGA: reg = 0x25; break;
-   case SIS_315_VGA: reg = 0x30; break;
-   default:          return FALSE;
-   }
+       switch(ivideo->sisvga_engine) {
+       case SIS_300_VGA: reg = 0x25; break;
+       case SIS_315_VGA: reg = 0x30; break;
+       default:          return FALSE;
+       }
 
-   inSISIDXREG(SISPART1, reg, temp);
-   if(temp & 0x02) return TRUE;
-   else           return FALSE;
+       inSISIDXREG(SISPART1, reg, temp);
+       if(temp & 0x02)
+               return TRUE;
+       else
+               return FALSE;
 }
 
 static BOOLEAN
 sisfb_CheckVBRetrace(struct sis_video_info *ivideo)
 {
-   if(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {
-      if(sisfb_bridgeisslave(ivideo)) {
-         return(sisfbcheckvretracecrt1(ivideo));
-      } else {
-         return(sisfbcheckvretracecrt2(ivideo));
-      }
-   } 
-   return(sisfbcheckvretracecrt1(ivideo));
+       if(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {
+               if(!sisfb_bridgeisslave(ivideo)) {
+                       return sisfbcheckvretracecrt2(ivideo);
+               }
+       }
+       return sisfbcheckvretracecrt1(ivideo);
 }
 
 static u32
 sisfb_setupvbblankflags(struct sis_video_info *ivideo, u32 *vcount, u32 *hcount)
 {
-   u8 idx, reg1, reg2, reg3, reg4;
-   u32 ret = 0;
-
-   (*vcount) = (*hcount) = 0;
-
-   if((ivideo->currentvbflags & VB_DISPTYPE_DISP2) && (!(sisfb_bridgeisslave(ivideo)))) {
-      ret |= (FB_VBLANK_HAVE_VSYNC  |
-             FB_VBLANK_HAVE_HBLANK |
-              FB_VBLANK_HAVE_VBLANK |
-             FB_VBLANK_HAVE_VCOUNT |
-             FB_VBLANK_HAVE_HCOUNT);
-      switch(ivideo->sisvga_engine) {
-         case SIS_300_VGA: idx = 0x25; break;
-        default:
-         case SIS_315_VGA: idx = 0x30; break;
-      }
-      inSISIDXREG(SISPART1,(idx+0),reg1); /* 30 */
-      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;
-      (*vcount) = reg3 | ((reg4 & 0x70) << 4);
-      (*hcount) = reg2 | ((reg4 & 0x0f) << 8);
-   } else if(sisfballowretracecrt1(ivideo)) {
-      ret |= (FB_VBLANK_HAVE_VSYNC  |
-              FB_VBLANK_HAVE_VBLANK |
-             FB_VBLANK_HAVE_VCOUNT |
-             FB_VBLANK_HAVE_HCOUNT);
-      reg1 = inSISREG(SISINPSTAT);
-      if(reg1 & 0x08) ret |= FB_VBLANK_VSYNCING;
-      if(reg1 & 0x01) ret |= FB_VBLANK_VBLANKING;
-      inSISIDXREG(SISCR,0x20,reg1);
-      inSISIDXREG(SISCR,0x1b,reg1);
-      inSISIDXREG(SISCR,0x1c,reg2);
-      inSISIDXREG(SISCR,0x1d,reg3);
-      (*vcount) = reg2 | ((reg3 & 0x07) << 8);
-      (*hcount) = (reg1 | ((reg3 & 0x10) << 4)) << 3;
-   }
-   return ret;
+       u8 idx, reg1, reg2, reg3, reg4;
+       u32 ret = 0;
+
+       (*vcount) = (*hcount) = 0;
+
+       if((ivideo->currentvbflags & VB_DISPTYPE_DISP2) && (!(sisfb_bridgeisslave(ivideo)))) {
+
+               ret |= (FB_VBLANK_HAVE_VSYNC  |
+                       FB_VBLANK_HAVE_HBLANK |
+                       FB_VBLANK_HAVE_VBLANK |
+                       FB_VBLANK_HAVE_VCOUNT |
+                       FB_VBLANK_HAVE_HCOUNT);
+               switch(ivideo->sisvga_engine) {
+                       case SIS_300_VGA: idx = 0x25; break;
+                       default:
+                       case SIS_315_VGA: idx = 0x30; break;
+               }
+               inSISIDXREG(SISPART1,(idx+0),reg1); /* 30 */
+               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;
+               (*vcount) = reg3 | ((reg4 & 0x70) << 4);
+               (*hcount) = reg2 | ((reg4 & 0x0f) << 8);
+
+       } else if(sisfballowretracecrt1(ivideo)) {
+
+               ret |= (FB_VBLANK_HAVE_VSYNC  |
+                       FB_VBLANK_HAVE_VBLANK |
+                       FB_VBLANK_HAVE_VCOUNT |
+                       FB_VBLANK_HAVE_HCOUNT);
+               reg1 = inSISREG(SISINPSTAT);
+               if(reg1 & 0x08) ret |= FB_VBLANK_VSYNCING;
+               if(reg1 & 0x01) ret |= FB_VBLANK_VBLANKING;
+               inSISIDXREG(SISCR,0x20,reg1);
+               inSISIDXREG(SISCR,0x1b,reg1);
+               inSISIDXREG(SISCR,0x1c,reg2);
+               inSISIDXREG(SISCR,0x1d,reg3);
+               (*vcount) = reg2 | ((reg3 & 0x07) << 8);
+               (*hcount) = (reg1 | ((reg3 & 0x10) << 4)) << 3;
+       }
+
+       return ret;
 }
 
 static int
 sisfb_myblank(struct sis_video_info *ivideo, int blank)
 {
-   u8 sr01, sr11, sr1f, cr63=0, p2_0, p1_13;
-   BOOLEAN backlight = TRUE;
-
-   switch(blank) {
-   case FB_BLANK_UNBLANK:      /* on */
-      sr01  = 0x00;
-      sr11  = 0x00;
-      sr1f  = 0x00;
-      cr63  = 0x00;
-      p2_0  = 0x20;
-      p1_13 = 0x00;
-      backlight = TRUE;
-      break;
-   case FB_BLANK_NORMAL:       /* blank */
-      sr01  = 0x20;
-      sr11  = 0x00;
-      sr1f  = 0x00;
-      cr63  = 0x00;
-      p2_0  = 0x20;
-      p1_13 = 0x00;
-      backlight = TRUE;
-      break;
-   case FB_BLANK_VSYNC_SUSPEND:        /* no vsync */
-      sr01  = 0x20;
-      sr11  = 0x08;
-      sr1f  = 0x80;
-      cr63  = 0x40;
-      p2_0  = 0x40;
-      p1_13 = 0x80;
-      backlight = FALSE;
-      break;
-   case FB_BLANK_HSYNC_SUSPEND:        /* no hsync */
-      sr01  = 0x20;
-      sr11  = 0x08;
-      sr1f  = 0x40;
-      cr63  = 0x40;
-      p2_0  = 0x80;
-      p1_13 = 0x40;
-      backlight = FALSE;
-      break;
-   case FB_BLANK_POWERDOWN:    /* off */
-      sr01  = 0x20;
-      sr11  = 0x08;
-      sr1f  = 0xc0;
-      cr63  = 0x40;
-      p2_0  = 0xc0;
-      p1_13 = 0xc0;
-      backlight = FALSE;
-      break;
-   default:
-      return 1;
-   }
-
-   if(ivideo->currentvbflags & VB_DISPTYPE_CRT1) {
-
-      if( (!ivideo->sisfb_thismonitor.datavalid) ||
-          ((ivideo->sisfb_thismonitor.datavalid) &&
-           (ivideo->sisfb_thismonitor.feature & 0xe0))) {
-
-        if(ivideo->sisvga_engine == SIS_315_VGA) {
-           setSISIDXREG(SISCR, ivideo->SiS_Pr.SiS_MyCR63, 0xbf, cr63);
-        }
-
-        if(!(sisfb_bridgeisslave(ivideo))) {
-           setSISIDXREG(SISSR, 0x01, ~0x20, sr01);
-           setSISIDXREG(SISSR, 0x1f, 0x3f, sr1f);
-        }
-      }
-
-   }
-
-   if(ivideo->currentvbflags & CRT2_LCD) {
-
-      if(ivideo->vbflags & (VB_301LV|VB_302LV|VB_302ELV)) {
-        if(backlight) {
-           SiS_SiS30xBLOn(&ivideo->SiS_Pr, &ivideo->sishw_ext);
-        } else {
-           SiS_SiS30xBLOff(&ivideo->SiS_Pr, &ivideo->sishw_ext);
-        }
-      } else if(ivideo->sisvga_engine == SIS_315_VGA) {
-        if(ivideo->vbflags & VB_CHRONTEL) {
-           if(backlight) {
-              SiS_Chrontel701xBLOn(&ivideo->SiS_Pr,&ivideo->sishw_ext);
-           } else {
-              SiS_Chrontel701xBLOff(&ivideo->SiS_Pr);
-           }
-        }
-      }
-
-      if(((ivideo->sisvga_engine == SIS_300_VGA) &&
-          (ivideo->vbflags & (VB_301|VB_30xBDH|VB_LVDS))) ||
-         ((ivideo->sisvga_engine == SIS_315_VGA) &&
-          ((ivideo->vbflags & (VB_LVDS | VB_CHRONTEL)) == VB_LVDS))) {
-          setSISIDXREG(SISSR, 0x11, ~0x0c, sr11);
-      }
-
-      if(ivideo->sisvga_engine == SIS_300_VGA) {
-         if((ivideo->vbflags & (VB_301B|VB_301C|VB_302B)) &&
-            (!(ivideo->vbflags & VB_30xBDH))) {
-           setSISIDXREG(SISPART1, 0x13, 0x3f, p1_13);
-        }
-      } else if(ivideo->sisvga_engine == SIS_315_VGA) {
-         if((ivideo->vbflags & (VB_301B|VB_301C|VB_302B)) &&
-            (!(ivideo->vbflags & VB_30xBDH))) {
-           setSISIDXREG(SISPART2, 0x00, 0x1f, p2_0);
-        }
-      }
-
-   } else if(ivideo->currentvbflags & CRT2_VGA) {
-
-      if(ivideo->vbflags & (VB_301B|VB_301C|VB_302B)) {
-         setSISIDXREG(SISPART2, 0x00, 0x1f, p2_0);
-      }
-
-   }
-
-   return(0);
+       u8 sr01, sr11, sr1f, cr63=0, p2_0, p1_13;
+       BOOLEAN backlight = TRUE;
+
+       switch(blank) {
+               case FB_BLANK_UNBLANK:  /* on */
+                       sr01  = 0x00;
+                       sr11  = 0x00;
+                       sr1f  = 0x00;
+                       cr63  = 0x00;
+                       p2_0  = 0x20;
+                       p1_13 = 0x00;
+                       backlight = TRUE;
+                       break;
+               case FB_BLANK_NORMAL:   /* blank */
+                       sr01  = 0x20;
+                       sr11  = 0x00;
+                       sr1f  = 0x00;
+                       cr63  = 0x00;
+                       p2_0  = 0x20;
+                       p1_13 = 0x00;
+                       backlight = TRUE;
+                       break;
+               case FB_BLANK_VSYNC_SUSPEND:    /* no vsync */
+                       sr01  = 0x20;
+                       sr11  = 0x08;
+                       sr1f  = 0x80;
+                       cr63  = 0x40;
+                       p2_0  = 0x40;
+                       p1_13 = 0x80;
+                       backlight = FALSE;
+                       break;
+               case FB_BLANK_HSYNC_SUSPEND:    /* no hsync */
+                       sr01  = 0x20;
+                       sr11  = 0x08;
+                       sr1f  = 0x40;
+                       cr63  = 0x40;
+                       p2_0  = 0x80;
+                       p1_13 = 0x40;
+                       backlight = FALSE;
+                       break;
+               case FB_BLANK_POWERDOWN:        /* off */
+                       sr01  = 0x20;
+                       sr11  = 0x08;
+                       sr1f  = 0xc0;
+                       cr63  = 0x40;
+                       p2_0  = 0xc0;
+                       p1_13 = 0xc0;
+                       backlight = FALSE;
+                       break;
+               default:
+                       return 1;
+       }
+
+       if(ivideo->currentvbflags & VB_DISPTYPE_CRT1) {
+
+               if( (!ivideo->sisfb_thismonitor.datavalid) ||
+                   ((ivideo->sisfb_thismonitor.datavalid) &&
+                    (ivideo->sisfb_thismonitor.feature & 0xe0))) {
+
+                       if(ivideo->sisvga_engine == SIS_315_VGA) {
+                               setSISIDXREG(SISCR, ivideo->SiS_Pr.SiS_MyCR63, 0xbf, cr63);
+                       }
+
+                       if(!(sisfb_bridgeisslave(ivideo))) {
+                               setSISIDXREG(SISSR, 0x01, ~0x20, sr01);
+                               setSISIDXREG(SISSR, 0x1f, 0x3f, sr1f);
+                       }
+               }
+
+       }
+
+       if(ivideo->currentvbflags & CRT2_LCD) {
+
+               if(ivideo->vbflags2 & VB2_SISLVDSBRIDGE) {
+                       if(backlight) {
+                               SiS_SiS30xBLOn(&ivideo->SiS_Pr);
+                       } else {
+                               SiS_SiS30xBLOff(&ivideo->SiS_Pr);
+                       }
+               } else if(ivideo->sisvga_engine == SIS_315_VGA) {
+#ifdef CONFIG_FB_SIS_315
+                       if(ivideo->vbflags2 & VB2_CHRONTEL) {
+                               if(backlight) {
+                                       SiS_Chrontel701xBLOn(&ivideo->SiS_Pr);
+                               } else {
+                                       SiS_Chrontel701xBLOff(&ivideo->SiS_Pr);
+                               }
+                       }
+#endif
+               }
+
+               if(((ivideo->sisvga_engine == SIS_300_VGA) &&
+                   (ivideo->vbflags2 & (VB2_301|VB2_30xBDH|VB2_LVDS))) ||
+                  ((ivideo->sisvga_engine == SIS_315_VGA) &&
+                   ((ivideo->vbflags2 & (VB2_LVDS | VB2_CHRONTEL)) == VB2_LVDS))) {
+                       setSISIDXREG(SISSR, 0x11, ~0x0c, sr11);
+               }
+
+               if(ivideo->sisvga_engine == SIS_300_VGA) {
+                       if((ivideo->vbflags2 & VB2_30xB) &&
+                          (!(ivideo->vbflags2 & VB2_30xBDH))) {
+                               setSISIDXREG(SISPART1, 0x13, 0x3f, p1_13);
+                       }
+               } else if(ivideo->sisvga_engine == SIS_315_VGA) {
+                       if((ivideo->vbflags2 & VB2_30xB) &&
+                          (!(ivideo->vbflags2 & VB2_30xBDH))) {
+                               setSISIDXREG(SISPART2, 0x00, 0x1f, p2_0);
+                       }
+               }
+
+       } else if(ivideo->currentvbflags & CRT2_VGA) {
+
+               if(ivideo->vbflags2 & VB2_30xB) {
+                       setSISIDXREG(SISPART2, 0x00, 0x1f, p2_0);
+               }
+
+       }
+
+       return 0;
+}
+
+/* ------------- Callbacks from init.c/init301.c  -------------- */
+
+#ifdef CONFIG_FB_SIS_300
+unsigned int
+sisfb_read_nbridge_pci_dword(struct SiS_Private *SiS_Pr, int reg)
+{
+   struct sis_video_info *ivideo = (struct sis_video_info *)SiS_Pr->ivideo;
+   u32 val = 0;
+
+   pci_read_config_dword(ivideo->nbridge, reg, &val);
+   return (unsigned int)val;
+}
+
+void
+sisfb_write_nbridge_pci_dword(struct SiS_Private *SiS_Pr, int reg, unsigned int val)
+{
+   struct sis_video_info *ivideo = (struct sis_video_info *)SiS_Pr->ivideo;
+
+   pci_write_config_dword(ivideo->nbridge, reg, (u32)val);
+}
+
+unsigned int
+sisfb_read_lpc_pci_dword(struct SiS_Private *SiS_Pr, int reg)
+{
+   struct sis_video_info *ivideo = (struct sis_video_info *)SiS_Pr->ivideo;
+   u32 val = 0;
+
+   if(!ivideo->lpcdev) return 0;
+
+   pci_read_config_dword(ivideo->lpcdev, reg, &val);
+   return (unsigned int)val;
+}
+#endif
+
+#ifdef CONFIG_FB_SIS_315
+void
+sisfb_write_nbridge_pci_byte(struct SiS_Private *SiS_Pr, int reg, unsigned char val)
+{
+   struct sis_video_info *ivideo = (struct sis_video_info *)SiS_Pr->ivideo;
+
+   pci_write_config_byte(ivideo->nbridge, reg, (u8)val);
 }
 
+unsigned int
+sisfb_read_mio_pci_word(struct SiS_Private *SiS_Pr, int reg)
+{
+   struct sis_video_info *ivideo = (struct sis_video_info *)SiS_Pr->ivideo;
+   u16 val = 0;
+
+   if(!ivideo->lpcdev) return 0;
+
+   pci_read_config_word(ivideo->lpcdev, reg, &val);
+   return (unsigned int)val;
+}
+#endif
+
 /* ----------- FBDev related routines for all series ----------- */
 
 static int
@@ -952,7 +1105,7 @@ sisfb_get_cmap_len(const struct fb_var_screeninfo *var)
 static void
 sisfb_set_vparms(struct sis_video_info *ivideo)
 {
-       switch(ivideo->video_bpp) {
+       switch(ivideo->video_bpp) {
        case 8:
                ivideo->DstColor = 0x0000;
                ivideo->SiS310_AccelDepth = 0x00000000;
@@ -972,14 +1125,13 @@ sisfb_set_vparms(struct sis_video_info *ivideo)
                ivideo->video_cmap_len = 16;
                printk(KERN_ERR "sisfb: Unsupported depth %d", ivideo->video_bpp);
                ivideo->accel = 0;
-               break;
-       }
+       }
 }
 
 static int
 sisfb_calc_maxyres(struct sis_video_info *ivideo, struct fb_var_screeninfo *var)
 {
-       int maxyres = ivideo->heapstart / (var->xres_virtual * (var->bits_per_pixel >> 3));
+       int maxyres = ivideo->sisfb_mem / (var->xres_virtual * (var->bits_per_pixel >> 3));
 
        if(maxyres > 32767) maxyres = 32767;
 
@@ -996,30 +1148,29 @@ sisfb_calc_pitch(struct sis_video_info *ivideo, struct fb_var_screeninfo *var)
                        ivideo->scrnpitchCRT1 <<= 1;
                }
        }
-
 }
 
 static void
 sisfb_set_pitch(struct sis_video_info *ivideo)
 {
-       BOOLEAN isslavemode = FALSE;
+       BOOLEAN isslavemode = FALSE;
        unsigned short HDisplay1 = ivideo->scrnpitchCRT1 >> 3;
        unsigned short HDisplay2 = ivideo->video_linelength >> 3;
 
-       if(sisfb_bridgeisslave(ivideo)) isslavemode = TRUE;
+       if(sisfb_bridgeisslave(ivideo)) isslavemode = TRUE;
 
-       /* We need to set pitch for CRT1 if bridge is in slave mode, too */
-       if((ivideo->currentvbflags & VB_DISPTYPE_DISP1) || (isslavemode)) {
-               outSISIDXREG(SISCR,0x13,(HDisplay1 & 0xFF));
-               setSISIDXREG(SISSR,0x0E,0xF0,(HDisplay1 >> 8));
+       /* We need to set pitch for CRT1 if bridge is in slave mode, too */
+       if((ivideo->currentvbflags & VB_DISPTYPE_DISP1) || (isslavemode)) {
+               outSISIDXREG(SISCR,0x13,(HDisplay1 & 0xFF));
+               setSISIDXREG(SISSR,0x0E,0xF0,(HDisplay1 >> 8));
        }
 
-       /* We must not set the pitch for CRT2 if bridge is in slave mode */
-       if((ivideo->currentvbflags & VB_DISPTYPE_DISP2) && (!isslavemode)) {
+       /* We must not set the pitch for CRT2 if bridge is in slave mode */
+       if((ivideo->currentvbflags & VB_DISPTYPE_DISP2) && (!isslavemode)) {
                orSISIDXREG(SISPART1,ivideo->CRT2_write_enable,0x01);
-               outSISIDXREG(SISPART1,0x07,(HDisplay2 & 0xFF));
-               setSISIDXREG(SISPART1,0x09,0xF0,(HDisplay2 >> 8));
-       }
+               outSISIDXREG(SISPART1,0x07,(HDisplay2 & 0xFF));
+               setSISIDXREG(SISPART1,0x09,0xF0,(HDisplay2 >> 8));
+       }
 }
 
 static void
@@ -1056,12 +1207,41 @@ sisfb_bpp_to_var(struct sis_video_info *ivideo, struct fb_var_screeninfo *var)
 }
 
 static int
+sisfb_set_mode(struct sis_video_info *ivideo, int clrscrn)
+{
+       unsigned short modeno = ivideo->mode_no;
+
+       /* >=2.6.12's fbcon clears the screen anyway */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12)
+       if(!clrscrn) modeno |= 0x80;
+#else
+       modeno |= 0x80;
+#endif
+
+       outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
+
+       sisfb_pre_setmode(ivideo);
+
+       if(SiSSetMode(&ivideo->SiS_Pr, modeno) == 0) {
+               printk(KERN_ERR "sisfb: Setting mode[0x%x] failed\n", ivideo->mode_no);
+               return -EINVAL;
+       }
+
+       outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
+
+       sisfb_post_setmode(ivideo);
+
+       return 0;
+}
+
+
+static int
 sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive, struct fb_info *info)
 {
        struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
        unsigned int htotal = 0, vtotal = 0;
        unsigned int drate = 0, hrate = 0;
-       int found_mode = 0;
+       int found_mode = 0, ret;
        int old_mode;
        u32 pixclock;
 
@@ -1088,11 +1268,11 @@ sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive, struct fb_info *in
        }
 
        if(pixclock && htotal && vtotal) {
-               drate = 1000000000 / pixclock;
-               hrate = (drate * 1000) / htotal;
-               ivideo->refresh_rate = (unsigned int) (hrate * 2 / vtotal);
+               drate = 1000000000 / pixclock;
+               hrate = (drate * 1000) / htotal;
+               ivideo->refresh_rate = (unsigned int) (hrate * 2 / vtotal);
        } else {
-               ivideo->refresh_rate = 60;
+               ivideo->refresh_rate = 60;
        }
 
        old_mode = ivideo->sisfb_mode_idx;
@@ -1113,6 +1293,7 @@ sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive, struct fb_info *in
        if(found_mode) {
                ivideo->sisfb_mode_idx = sisfb_validate_mode(ivideo,
                                ivideo->sisfb_mode_idx, ivideo->currentvbflags);
+               ivideo->mode_no = sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni];
        } else {
                ivideo->sisfb_mode_idx = -1;
        }
@@ -1131,10 +1312,10 @@ sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive, struct fb_info *in
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
        if(ivideo->sisfb_thismonitor.datavalid) {
-          if(!sisfb_verify_rate(ivideo, &ivideo->sisfb_thismonitor, ivideo->sisfb_mode_idx,
+               if(!sisfb_verify_rate(ivideo, &ivideo->sisfb_thismonitor, ivideo->sisfb_mode_idx,
                                 ivideo->rate_idx, ivideo->refresh_rate)) {
-             printk(KERN_INFO "sisfb: WARNING: Refresh rate exceeds monitor specs!\n");
-          }
+                       printk(KERN_INFO "sisfb: WARNING: Refresh rate exceeds monitor specs!\n");
+               }
        }
 #endif
 
@@ -1143,24 +1324,9 @@ sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive, struct fb_info *in
 #else
        if(isactive) {
 #endif
-               sisfb_pre_setmode(ivideo);
-
-               if(SiSSetMode(&ivideo->SiS_Pr, &ivideo->sishw_ext, ivideo->mode_no) == 0) {
-                       printk(KERN_ERR "sisfb: Setting mode[0x%x] failed\n", ivideo->mode_no);
-                       return -EINVAL;
-               }
-
-               outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
-
-               sisfb_post_setmode(ivideo);
-
-               ivideo->video_bpp    = sisbios_mode[ivideo->sisfb_mode_idx].bpp;
-               ivideo->video_width  = sisbios_mode[ivideo->sisfb_mode_idx].xres;
-               ivideo->video_height = sisbios_mode[ivideo->sisfb_mode_idx].yres;
-
-               sisfb_calc_pitch(ivideo, var);
-               sisfb_set_pitch(ivideo);
-
+               /* If acceleration to be used? Need to know
+                * before pre/post_set_mode()
+                */
                ivideo->accel = 0;
 #if defined(FBINFO_HWACCEL_DISABLED) && defined(FBINFO_HWACCEL_XPAN)
 #ifdef STUPID_ACCELF_TEXT_SHIT
@@ -1175,6 +1341,17 @@ sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive, struct fb_info *in
                if(var->accel_flags & FB_ACCELF_TEXT) ivideo->accel = -1;
 #endif
 
+               if((ret = sisfb_set_mode(ivideo, 1))) {
+                       return ret;
+               }
+
+               ivideo->video_bpp    = sisbios_mode[ivideo->sisfb_mode_idx].bpp;
+               ivideo->video_width  = sisbios_mode[ivideo->sisfb_mode_idx].xres;
+               ivideo->video_height = sisbios_mode[ivideo->sisfb_mode_idx].yres;
+
+               sisfb_calc_pitch(ivideo, var);
+               sisfb_set_pitch(ivideo);
+
                sisfb_set_vparms(ivideo);
 
                ivideo->current_width = ivideo->video_width;
@@ -1186,823 +1363,342 @@ sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive, struct fb_info *in
                ivideo->current_pixclock = var->pixclock;
                ivideo->current_refresh_rate = ivideo->refresh_rate;
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-                ivideo->sisfb_lastrates[ivideo->mode_no] = ivideo->refresh_rate;
+               ivideo->sisfb_lastrates[ivideo->mode_no] = ivideo->refresh_rate;
 #endif
        }
 
        return 0;
 }
 
-static int
-sisfb_pan_var(struct sis_video_info *ivideo, struct fb_var_screeninfo *var)
+static void
+sisfb_set_base_CRT1(struct sis_video_info *ivideo, unsigned int base)
 {
-       unsigned int base;
-
-       if(var->xoffset > (var->xres_virtual - var->xres)) {
-               return -EINVAL;
-       }
-       if(var->yoffset > (var->yres_virtual - var->yres)) {
-               return -EINVAL;
-       }
-
-       base = (var->yoffset * var->xres_virtual) + var->xoffset;
-
-        /* calculate base bpp dep. */
-        switch(var->bits_per_pixel) {
-       case 32:
-               break;
-        case 16:
-               base >>= 1;
-               break;
-       case 8:
-        default:
-               base >>= 2;
-               break;
-        }
-       
        outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
 
-        outSISIDXREG(SISCR, 0x0D, base & 0xFF);
+       outSISIDXREG(SISCR, 0x0D, base & 0xFF);
        outSISIDXREG(SISCR, 0x0C, (base >> 8) & 0xFF);
        outSISIDXREG(SISSR, 0x0D, (base >> 16) & 0xFF);
        if(ivideo->sisvga_engine == SIS_315_VGA) {
                setSISIDXREG(SISSR, 0x37, 0xFE, (base >> 24) & 0x01);
        }
-        if(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {
+}
+
+static void
+sisfb_set_base_CRT2(struct sis_video_info *ivideo, unsigned int base)
+{
+       if(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {
                orSISIDXREG(SISPART1, ivideo->CRT2_write_enable, 0x01);
-               outSISIDXREG(SISPART1, 0x06, (base & 0xFF));
-               outSISIDXREG(SISPART1, 0x05, ((base >> 8) & 0xFF));
-               outSISIDXREG(SISPART1, 0x04, ((base >> 16) & 0xFF));
+               outSISIDXREG(SISPART1, 0x06, (base & 0xFF));
+               outSISIDXREG(SISPART1, 0x05, ((base >> 8) & 0xFF));
+               outSISIDXREG(SISPART1, 0x04, ((base >> 16) & 0xFF));
                if(ivideo->sisvga_engine == SIS_315_VGA) {
                        setSISIDXREG(SISPART1, 0x02, 0x7F, ((base >> 24) & 0x01) << 7);
                }
-        }
-       return 0;
+       }
 }
 
-/* ------------ FBDev related routines for 2.4 series ----------- */
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-
-static void
-sisfb_crtc_to_var(struct sis_video_info *ivideo, struct fb_var_screeninfo *var)
+static int
+sisfb_pan_var(struct sis_video_info *ivideo, struct fb_var_screeninfo *var)
 {
-       u16 VRE, VBE, VRS, VBS, VDE, VT;
-       u16 HRE, HBE, HRS, HBS, HDE, HT;
-       u8  sr_data, cr_data, cr_data2, cr_data3, mr_data;
-       int A, B, C, D, E, F, temp;
-       unsigned int hrate, drate, maxyres;
-
-       inSISIDXREG(SISSR, IND_SIS_COLOR_MODE, sr_data);
+       if(var->xoffset > (var->xres_virtual - var->xres)) {
+               return -EINVAL;
+       }
+       if(var->yoffset > (var->yres_virtual - var->yres)) {
+               return -EINVAL;
+       }
 
-       if(sr_data & SIS_INTERLACED_MODE)
-          var->vmode = FB_VMODE_INTERLACED;
-       else
-          var->vmode = FB_VMODE_NONINTERLACED;
+       ivideo->current_base = (var->yoffset * var->xres_virtual) + var->xoffset;
 
-       switch((sr_data & 0x1C) >> 2) {
-       case SIS_8BPP_COLOR_MODE:
-               var->bits_per_pixel = 8;
+       /* calculate base bpp dep. */
+       switch(var->bits_per_pixel) {
+       case 32:
                break;
-       case SIS_16BPP_COLOR_MODE:
-               var->bits_per_pixel = 16;
+       case 16:
+               ivideo->current_base >>= 1;
                break;
-       case SIS_32BPP_COLOR_MODE:
-               var->bits_per_pixel = 32;
+       case 8:
+       default:
+               ivideo->current_base >>= 2;
                break;
        }
 
-       sisfb_bpp_to_var(ivideo, var);
-       
-       inSISIDXREG(SISSR, 0x0A, sr_data);
-        inSISIDXREG(SISCR, 0x06, cr_data);
-        inSISIDXREG(SISCR, 0x07, cr_data2);
-
-       VT = (cr_data & 0xFF) |
-            ((u16) (cr_data2 & 0x01) << 8) |
-            ((u16) (cr_data2 & 0x20) << 4) |
-            ((u16) (sr_data  & 0x01) << 10);
-       A = VT + 2;
-
-       inSISIDXREG(SISCR, 0x12, cr_data);
-
-       VDE = (cr_data & 0xff) |
-             ((u16) (cr_data2 & 0x02) << 7) |
-             ((u16) (cr_data2 & 0x40) << 3) |
-             ((u16) (sr_data  & 0x02) << 9);
-       E = VDE + 1;
-
-       inSISIDXREG(SISCR, 0x10, cr_data);
-
-       VRS = (cr_data & 0xff) |
-             ((u16) (cr_data2 & 0x04) << 6) |
-             ((u16) (cr_data2 & 0x80) << 2) |
-             ((u16) (sr_data  & 0x08) << 7);
-       F = VRS + 1 - E;
-
-       inSISIDXREG(SISCR, 0x15, cr_data);
-       inSISIDXREG(SISCR, 0x09, cr_data3);
-
-       if(cr_data3 & 0x80) var->vmode = FB_VMODE_DOUBLE;
-
-       VBS = (cr_data & 0xff) |
-             ((u16) (cr_data2 & 0x08) << 5) |
-             ((u16) (cr_data3 & 0x20) << 4) |
-             ((u16) (sr_data & 0x04) << 8);
-
-       inSISIDXREG(SISCR, 0x16, cr_data);
-
-       VBE = (cr_data & 0xff) | ((u16) (sr_data & 0x10) << 4);
-       temp = VBE - ((E - 1) & 511);
-       B = (temp > 0) ? temp : (temp + 512);
-
-       inSISIDXREG(SISCR, 0x11, cr_data);
-
-       VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1);
-       temp = VRE - ((E + F - 1) & 31);
-       C = (temp > 0) ? temp : (temp + 32);
-
-       D = B - F - C;
-
-        var->yres = E;
-       var->upper_margin = D;
-       var->lower_margin = F;
-       var->vsync_len = C;
-
-       if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
-          var->yres <<= 1;
-          var->upper_margin <<= 1;
-          var->lower_margin <<= 1;
-          var->vsync_len <<= 1;
-       } else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
-          var->yres >>= 1;
-          var->upper_margin >>= 1;
-          var->lower_margin >>= 1;
-          var->vsync_len >>= 1;
-       }
-
-       inSISIDXREG(SISSR, 0x0b, sr_data);
-       inSISIDXREG(SISCR, 0x00, cr_data);
-
-       HT = (cr_data & 0xff) | ((u16) (sr_data & 0x03) << 8);
-       A = HT + 5;
-
-       inSISIDXREG(SISCR, 0x01, cr_data);
-
-       HDE = (cr_data & 0xff) | ((u16) (sr_data & 0x0C) << 6);
-       E = HDE + 1;
-
-       inSISIDXREG(SISCR, 0x04, cr_data);
-
-       HRS = (cr_data & 0xff) | ((u16) (sr_data & 0xC0) << 2);
-       F = HRS - E - 3;
-
-       inSISIDXREG(SISCR, 0x02, cr_data);
+       ivideo->current_base += (ivideo->video_offset >> 2);
 
-       HBS = (cr_data & 0xff) | ((u16) (sr_data & 0x30) << 4);
+       sisfb_set_base_CRT1(ivideo, ivideo->current_base);
+       sisfb_set_base_CRT2(ivideo, ivideo->current_base);
 
-       inSISIDXREG(SISSR, 0x0c, sr_data);
-       inSISIDXREG(SISCR, 0x03, cr_data);
-       inSISIDXREG(SISCR, 0x05, cr_data2);
-
-       HBE = (cr_data & 0x1f) |
-             ((u16) (cr_data2 & 0x80) >> 2) |
-             ((u16) (sr_data  & 0x03) << 6);
-       HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3);
-
-       temp = HBE - ((E - 1) & 255);
-       B = (temp > 0) ? temp : (temp + 256);
-
-       temp = HRE - ((E + F + 3) & 63);
-       C = (temp > 0) ? temp : (temp + 64);
-
-       D = B - F - C;
-
-       var->xres = E * 8;
-       if(var->xres_virtual < var->xres) {
-               var->xres_virtual = var->xres;
-       }
-
-       if((var->xres == 320) &&
-          (var->yres == 200 || var->yres == 240)) {
-               /* Terrible hack, but the correct CRTC data for
-                * these modes only produces a black screen...
-                */
-                       var->left_margin = (400 - 376);
-                       var->right_margin = (328 - 320);
-                       var->hsync_len = (376 - 328);
-       } else {
-               var->left_margin = D * 8;
-               var->right_margin = F * 8;
-               var->hsync_len = C * 8;
-       }
-       var->activate = FB_ACTIVATE_NOW;
+       return 0;
+}
 
-       var->sync = 0;
+/* ------------ FBDev related routines for 2.4 series ----------- */
 
-       mr_data = inSISREG(SISMISCR);
-       if(mr_data & 0x80)
-          var->sync &= ~FB_SYNC_VERT_HIGH_ACT;
-       else
-          var->sync |= FB_SYNC_VERT_HIGH_ACT;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 
-       if(mr_data & 0x40)
-          var->sync &= ~FB_SYNC_HOR_HIGH_ACT;
-       else
-          var->sync |= FB_SYNC_HOR_HIGH_ACT;
+#include "sisfb_fbdev_2_4.h"
 
-       VT += 2;
-       VT <<= 1;
-       HT = (HT + 5) * 8;
+#endif
 
-       if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
-          VT <<= 1;
-       }
-       hrate = ivideo->refresh_rate * VT / 2;
-       drate = (hrate * HT) / 1000;
-       var->pixclock = (u32) (1000000000 / drate);
+/* ------------ FBDev related routines for 2.6 series ----------- */
 
-       if(ivideo->sisfb_ypan) {
-          maxyres = sisfb_calc_maxyres(ivideo, var);
-          if(ivideo->sisfb_max) {
-             var->yres_virtual = maxyres;
-          } else {
-             if(var->yres_virtual > maxyres) {
-                var->yres_virtual = maxyres;
-             }
-          }
-          if(var->yres_virtual <= var->yres) {
-             var->yres_virtual = var->yres;
-          }
-       } else {
-          var->yres_virtual = var->yres;
-       }
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 
+static int
+sisfb_open(struct fb_info *info, int user)
+{
+       return 0;
 }
 
 static int
-sis_getcolreg(unsigned regno, unsigned *red, unsigned *green, unsigned *blue,
-                        unsigned *transp, struct fb_info *info)
+sisfb_release(struct fb_info *info, int user)
 {
-       struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
-
-       if(regno >= ivideo->video_cmap_len) return 1;
-
-       *red   = ivideo->sis_palette[regno].red;
-       *green = ivideo->sis_palette[regno].green;
-       *blue  = ivideo->sis_palette[regno].blue;
-       *transp = 0;
-
        return 0;
 }
 
 static int
 sisfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
-                           unsigned transp, struct fb_info *info)
+               unsigned transp, struct fb_info *info)
 {
        struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
 
-       if(regno >= ivideo->video_cmap_len) return 1;
-
-       ivideo->sis_palette[regno].red   = red;
-       ivideo->sis_palette[regno].green = green;
-       ivideo->sis_palette[regno].blue  = blue;
+       if(regno >= sisfb_get_cmap_len(&info->var))
+               return 1;
 
-       switch(ivideo->video_bpp) {
-#ifdef FBCON_HAS_CFB8
+       switch(info->var.bits_per_pixel) {
        case 8:
-               outSISREG(SISDACA, regno);
+               outSISREG(SISDACA, regno);
                outSISREG(SISDACD, (red >> 10));
                outSISREG(SISDACD, (green >> 10));
                outSISREG(SISDACD, (blue >> 10));
                if(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {
-                       outSISREG(SISDAC2A, regno);
+                       outSISREG(SISDAC2A, regno);
                        outSISREG(SISDAC2D, (red >> 8));
                        outSISREG(SISDAC2D, (green >> 8));
                        outSISREG(SISDAC2D, (blue >> 8));
                }
                break;
-#endif
-#ifdef FBCON_HAS_CFB16
        case 16:
-               ivideo->sis_fbcon_cmap.cfb16[regno] =
-                   ((red & 0xf800)) | ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11);
+               ((u32 *)(info->pseudo_palette))[regno] =
+                               (red & 0xf800)          |
+                               ((green & 0xfc00) >> 5) |
+                               ((blue & 0xf800) >> 11);
                break;
-#endif
-#ifdef FBCON_HAS_CFB32
        case 32:
-               red   >>= 8;
+               red >>= 8;
                green >>= 8;
-               blue  >>= 8;
-               ivideo->sis_fbcon_cmap.cfb32[regno] = (red << 16) | (green << 8) | (blue);
+               blue >>= 8;
+               ((u32 *)(info->pseudo_palette))[regno] =
+                               (red << 16) | (green << 8) | (blue);
                break;
-#endif
        }
-
        return 0;
 }
 
-static void
-sisfb_set_disp(int con, struct fb_var_screeninfo *var, struct fb_info *info)
-{
-       struct sis_video_info    *ivideo = (struct sis_video_info *)info->par;
-       struct display           *display;
-       struct display_switch    *sw;
-       struct fb_fix_screeninfo fix;
-       long   flags;
-
-       display = (con >= 0) ? &fb_display[con] : &ivideo->sis_disp;
-
-       sisfb_get_fix(&fix, con, info);
-
-       display->var = *var;
-       display->screen_base = (char *)ivideo->video_vbase;
-       display->visual = fix.visual;
-       display->type = fix.type;
-       display->type_aux = fix.type_aux;
-       display->ypanstep = fix.ypanstep;
-       display->ywrapstep = fix.ywrapstep;
-       display->line_length = fix.line_length;
-       display->can_soft_blank = 1;
-       display->inverse = ivideo->sisfb_inverse;
-       display->next_line = fix.line_length;
-
-       save_flags(flags);
-
-       switch(ivideo->video_bpp) {
-#ifdef FBCON_HAS_CFB8
-       case 8: sw = ivideo->accel ? &fbcon_sis8 : &fbcon_cfb8;
-               break;
-#endif
-#ifdef FBCON_HAS_CFB16
-       case 16:sw = ivideo->accel ? &fbcon_sis16 : &fbcon_cfb16;
-               display->dispsw_data = &ivideo->sis_fbcon_cmap.cfb16;
-               break;
-#endif
-#ifdef FBCON_HAS_CFB32
-       case 32:sw = ivideo->accel ? &fbcon_sis32 : &fbcon_cfb32;
-               display->dispsw_data = &ivideo->sis_fbcon_cmap.cfb32;
-               break;
-#endif
-       default:sw = &fbcon_dummy;
-               break;
-       }
-       memcpy(&ivideo->sisfb_sw, sw, sizeof(*sw));
-       display->dispsw = &ivideo->sisfb_sw;
-
-       restore_flags(flags);
-
-        if(ivideo->sisfb_ypan) {
-           /* display->scrollmode = 0;  */
-       } else {
-           display->scrollmode = SCROLL_YREDRAW;
-           ivideo->sisfb_sw.bmove = fbcon_redraw_bmove;
-       }
-}
-
-static void
-sisfb_do_install_cmap(int con, struct fb_info *info)
-{
-       struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
-
-        if(con != ivideo->currcon) return;
-
-        if(fb_display[con].cmap.len) {
-               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), 1, sisfb_setcolreg, info);
-       }
-}
-
 static int
-sisfb_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
+sisfb_set_par(struct fb_info *info)
 {
-       struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
-
-       if(con == -1) {
-               memcpy(var, &ivideo->default_var, sizeof(struct fb_var_screeninfo));
-       } else {
-               *var = fb_display[con].var;
-       }
+       int err;
 
-       if(ivideo->sisfb_fstn) {
-               if(var->xres == 320 && var->yres == 480) var->yres = 240;
-        }
+       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);
+#endif
        return 0;
 }
 
 static int
-sisfb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
+sisfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 {
        struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
-       int err;
+       unsigned int htotal = 0, vtotal = 0, myrateindex = 0;
+       unsigned int drate = 0, hrate = 0, maxyres;
+       int found_mode = 0;
+       int refresh_rate, search_idx, tidx;
+       BOOLEAN recalc_clock = FALSE;
+       u32 pixclock;
 
-       fb_display[con].var.activate = FB_ACTIVATE_NOW;
+       htotal = var->left_margin + var->xres + var->right_margin + var->hsync_len;
 
-        if(sisfb_do_set_var(var, con == ivideo->currcon, info)) {
-               sisfb_crtc_to_var(ivideo, var);
-               return -EINVAL;
-       }
+       vtotal = var->upper_margin + var->lower_margin + var->vsync_len;
 
-       sisfb_crtc_to_var(ivideo, var);
+       pixclock = var->pixclock;
 
-       sisfb_set_disp(con, var, info);
+       if((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) {
+               vtotal += var->yres;
+               vtotal <<= 1;
+       } else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
+               vtotal += var->yres;
+               vtotal <<= 2;
+       } else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
+               vtotal += var->yres;
+               vtotal <<= 1;
+       } else
+               vtotal += var->yres;
 
-       if(info->changevar) {
-               (*info->changevar)(con);
+       if(!(htotal) || !(vtotal)) {
+               SISFAIL("sisfb: no valid timing data");
        }
 
-       if((err = fb_alloc_cmap(&fb_display[con].cmap, 0, 0))) {
-               return err;
+       search_idx = 0;
+       while( (sisbios_mode[search_idx].mode_no[0] != 0) &&
+              (sisbios_mode[search_idx].xres <= var->xres) ) {
+               if( (sisbios_mode[search_idx].xres == var->xres) &&
+                   (sisbios_mode[search_idx].yres == var->yres) &&
+                   (sisbios_mode[search_idx].bpp == var->bits_per_pixel)) {
+                       if((tidx = sisfb_validate_mode(ivideo, search_idx,
+                                               ivideo->currentvbflags)) > 0) {
+                               found_mode = 1;
+                               search_idx = tidx;
+                               break;
+                       }
+               }
+               search_idx++;
        }
 
-       sisfb_do_install_cmap(con, info);
+       if(!found_mode) {
+               search_idx = 0;
+               while(sisbios_mode[search_idx].mode_no[0] != 0) {
+                  if( (var->xres <= sisbios_mode[search_idx].xres) &&
+                      (var->yres <= sisbios_mode[search_idx].yres) &&
+                      (var->bits_per_pixel == sisbios_mode[search_idx].bpp) ) {
+                       if((tidx = sisfb_validate_mode(ivideo,search_idx,
+                                               ivideo->currentvbflags)) > 0) {
+                               found_mode = 1;
+                               search_idx = tidx;
+                               break;
+                       }
+                  }
+                  search_idx++;
+               }
+               if(found_mode) {
+                       printk(KERN_DEBUG
+                               "sisfb: Adapted from %dx%dx%d to %dx%dx%d\n",
+                               var->xres, var->yres, var->bits_per_pixel,
+                               sisbios_mode[search_idx].xres,
+                               sisbios_mode[search_idx].yres,
+                               var->bits_per_pixel);
+                       var->xres = sisbios_mode[search_idx].xres;
+                       var->yres = sisbios_mode[search_idx].yres;
+               } else {
+                       printk(KERN_ERR
+                               "sisfb: Failed to find supported mode near %dx%dx%d\n",
+                               var->xres, var->yres, var->bits_per_pixel);
+                       return -EINVAL;
+               }
+       }
 
-#if 0  /* Why was this called here? */
-       unsigned int cols, rows;
-       cols = sisbios_mode[ivideo->sisfb_mode_idx].cols;
-       rows = sisbios_mode[ivideo->sisfb_mode_idx].rows;
-       vc_resize_con(rows, cols, fb_display[con].conp->vc_num);
-#endif
-       return 0;
-}
+       if( ((ivideo->vbflags2 & VB2_LVDS) ||
+            ((ivideo->vbflags2 & VB2_30xBDH) && (ivideo->currentvbflags & CRT2_LCD))) &&
+           (var->bits_per_pixel == 8) ) {
+               /* Slave modes on LVDS and 301B-DH */
+               refresh_rate = 60;
+               recalc_clock = TRUE;
+       } else if( (ivideo->current_htotal == htotal) &&
+                  (ivideo->current_vtotal == vtotal) &&
+                  (ivideo->current_pixclock == pixclock) ) {
+               /* x=x & y=y & c=c -> assume depth change */
+               drate = 1000000000 / pixclock;
+               hrate = (drate * 1000) / htotal;
+               refresh_rate = (unsigned int) (hrate * 2 / vtotal);
+       } else if( ( (ivideo->current_htotal != htotal) ||
+                    (ivideo->current_vtotal != vtotal) ) &&
+                  (ivideo->current_pixclock == var->pixclock) ) {
+               /* x!=x | y!=y & c=c -> invalid pixclock */
+               if(ivideo->sisfb_lastrates[sisbios_mode[search_idx].mode_no[ivideo->mni]]) {
+                       refresh_rate =
+                               ivideo->sisfb_lastrates[sisbios_mode[search_idx].mode_no[ivideo->mni]];
+               } else if(ivideo->sisfb_parm_rate != -1) {
+                       /* Sic, sisfb_parm_rate - want to know originally desired rate here */
+                       refresh_rate = ivideo->sisfb_parm_rate;
+               } else {
+                       refresh_rate = 60;
+               }
+               recalc_clock = TRUE;
+       } else if((pixclock) && (htotal) && (vtotal)) {
+               drate = 1000000000 / pixclock;
+               hrate = (drate * 1000) / htotal;
+               refresh_rate = (unsigned int) (hrate * 2 / vtotal);
+       } else if(ivideo->current_refresh_rate) {
+               refresh_rate = ivideo->current_refresh_rate;
+               recalc_clock = TRUE;
+       } else {
+               refresh_rate = 60;
+               recalc_clock = TRUE;
+       }
 
-static int
-sisfb_get_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info)
-{
-       struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
-       struct display *display;
+       myrateindex = sisfb_search_refresh_rate(ivideo, refresh_rate, search_idx);
 
-       display = (con >= 0) ? &fb_display[con] : &ivideo->sis_disp;
+       /* Eventually recalculate timing and clock */
+       if(recalc_clock) {
+               if(!myrateindex) myrateindex = sisbios_mode[search_idx].rate_idx;
+               var->pixclock = (u32) (1000000000 / sisfb_mode_rate_to_dclock(&ivideo->SiS_Pr,
+                                               sisbios_mode[search_idx].mode_no[ivideo->mni],
+                                               myrateindex));
+               sisfb_mode_rate_to_ddata(&ivideo->SiS_Pr,
+                                       sisbios_mode[search_idx].mode_no[ivideo->mni],
+                                       myrateindex, var);
+               if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
+                       var->pixclock <<= 1;
+               }
+       }
 
-        if(con == ivideo->currcon) {
+       if(ivideo->sisfb_thismonitor.datavalid) {
+               if(!sisfb_verify_rate(ivideo, &ivideo->sisfb_thismonitor, search_idx,
+                               myrateindex, refresh_rate)) {
+                       printk(KERN_INFO
+                               "sisfb: WARNING: Refresh rate exceeds monitor specs!\n");
+               }
+       }
 
-               return fb_get_cmap(cmap, kspc, sis_getcolreg, info);
+       /* Adapt RGB settings */
+       sisfb_bpp_to_var(ivideo, var);
 
-       } else if(display->cmap.len) {
-
-               fb_copy_cmap(&display->cmap, cmap, kspc ? 0 : 2);
-
-       } else {
-
-               int size = sisfb_get_cmap_len(&display->var);
-               fb_copy_cmap(fb_default_cmap(size), cmap, kspc ? 0 : 2);
-
-       }
-
-       return 0;
-}
-
-static int
-sisfb_set_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info)
-{
-       struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
-       struct display *display;
-       int err, size;
-
-       display = (con >= 0) ? &fb_display[con] : &ivideo->sis_disp;
-
-       size = sisfb_get_cmap_len(&display->var);
-       if(display->cmap.len != size) {
-               err = fb_alloc_cmap(&display->cmap, size, 0);
-               if(err) return err;
-       }
-        
-       if(con == ivideo->currcon) {
-               return fb_set_cmap(cmap, kspc, sisfb_setcolreg, info);
-       } else {
-               fb_copy_cmap(cmap, &display->cmap, kspc ? 0 : 1);
-       }
-
-       return 0;
-}
-
-static int
-sisfb_pan_display(struct fb_var_screeninfo *var, int con, struct fb_info* info)
-{
-       struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
-       int err;
-
-       if(var->vmode & FB_VMODE_YWRAP) return -EINVAL;
-
-       if((var->xoffset+fb_display[con].var.xres > fb_display[con].var.xres_virtual) ||
-          (var->yoffset+fb_display[con].var.yres > fb_display[con].var.yres_virtual)) {
-               return -EINVAL;
-       }
-
-        if(con == ivideo->currcon) {
-               if((err = sisfb_pan_var(ivideo, var)) < 0) return err;
-       }
-
-       fb_display[con].var.xoffset = var->xoffset;
-       fb_display[con].var.yoffset = var->yoffset;
-
-       return 0;
-}
-
-static int
-sisfb_update_var(int con, struct fb_info *info)
-{
-       struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
-
-        return(sisfb_pan_var(ivideo, &fb_display[con].var));
-}
-
-static int
-sisfb_switch(int con, struct fb_info *info)
-{
-       struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
-       int cols, rows;
-
-        if(fb_display[ivideo->currcon].cmap.len) {
-               fb_get_cmap(&fb_display[ivideo->currcon].cmap, 1, sis_getcolreg, info);
-       }
-
-       fb_display[con].var.activate = FB_ACTIVATE_NOW;
-
-       if(!memcmp(&fb_display[con].var, &fb_display[ivideo->currcon].var,
-                                       sizeof(struct fb_var_screeninfo))) {
-               ivideo->currcon = con;
-               return 1;
-       }
-
-       ivideo->currcon = con;
-
-       sisfb_do_set_var(&fb_display[con].var, 1, info);
-
-       sisfb_set_disp(con, &fb_display[con].var, info);
-
-       sisfb_do_install_cmap(con, info);
-
-       cols = sisbios_mode[ivideo->sisfb_mode_idx].cols;
-       rows = sisbios_mode[ivideo->sisfb_mode_idx].rows;
-       vc_resize_con(rows, cols, fb_display[con].conp->vc_num);
-
-       sisfb_update_var(con, info);
-
-       return 1;
-}
-
-static void
-sisfb_blank(int blank, struct fb_info *info)
-{
-       struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
-
-       sisfb_myblank(ivideo, blank);
-}
-#endif
-
-/* ------------ FBDev related routines for 2.6 series ----------- */
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-
-static int
-sisfb_open(struct fb_info *info, int user)
-{
-       return 0;
-}
-
-static int
-sisfb_release(struct fb_info *info, int user)
-{
-       return 0;
-}
-
-static int
-sisfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
-               unsigned transp, struct fb_info *info)
-{
-       struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
-
-       if(regno >= sisfb_get_cmap_len(&info->var)) return 1;
-
-       switch(info->var.bits_per_pixel) {
-       case 8:
-               outSISREG(SISDACA, regno);
-               outSISREG(SISDACD, (red >> 10));
-               outSISREG(SISDACD, (green >> 10));
-               outSISREG(SISDACD, (blue >> 10));
-               if(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {
-                       outSISREG(SISDAC2A, regno);
-                       outSISREG(SISDAC2D, (red >> 8));
-                       outSISREG(SISDAC2D, (green >> 8));
-                       outSISREG(SISDAC2D, (blue >> 8));
-               }
-               break;
-       case 16:
-               ((u32 *)(info->pseudo_palette))[regno] =
-                   ((red & 0xf800)) | ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11);
-               break;
-       case 32:
-               red >>= 8;
-               green >>= 8;
-               blue >>= 8;
-               ((u32 *)(info->pseudo_palette))[regno] =
-                               (red << 16) | (green << 8) | (blue);
-               break;
-       }
-       return 0;
-}
-
-static int
-sisfb_set_par(struct fb_info *info)
-{
-       int err;
-
-        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);
-#endif
-       return 0;
-}
-
-static int
-sisfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
-{
-       struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
-       unsigned int htotal = 0, vtotal = 0, myrateindex = 0;
-       unsigned int drate = 0, hrate = 0, maxyres;
-       int found_mode = 0;
-       int refresh_rate, search_idx;
-       BOOLEAN recalc_clock = FALSE;
-       u32 pixclock;
-
-       htotal = var->left_margin + var->xres + var->right_margin + var->hsync_len;
-
-       vtotal = var->upper_margin + var->lower_margin + var->vsync_len;
-
-       pixclock = var->pixclock;
-
-       if((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) {
-               vtotal += var->yres;
-               vtotal <<= 1;
-       } else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
-               vtotal += var->yres;
-               vtotal <<= 2;
-       } else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
-               vtotal += var->yres;
-               vtotal <<= 1;
-       } else  vtotal += var->yres;
-
-       if(!(htotal) || !(vtotal)) {
-               SISFAIL("sisfb: no valid timing data");
-       }
-
-       search_idx = 0;
-       while( (sisbios_mode[search_idx].mode_no[0] != 0) &&
-              (sisbios_mode[search_idx].xres <= var->xres) ) {
-               if( (sisbios_mode[search_idx].xres == var->xres) &&
-                   (sisbios_mode[search_idx].yres == var->yres) &&
-                   (sisbios_mode[search_idx].bpp == var->bits_per_pixel)) {
-                       if(sisfb_validate_mode(ivideo, search_idx, ivideo->currentvbflags) > 0) {
-                          found_mode = 1;
-                          break;
-                       }
-               }
-               search_idx++;
-       }
-
-       if(!found_mode) {
-                search_idx = 0;
-               while(sisbios_mode[search_idx].mode_no[0] != 0) {
-                  if( (var->xres <= sisbios_mode[search_idx].xres) &&
-                      (var->yres <= sisbios_mode[search_idx].yres) &&
-                      (var->bits_per_pixel == sisbios_mode[search_idx].bpp) ) {
-                         if(sisfb_validate_mode(ivideo,search_idx, ivideo->currentvbflags) > 0) {
-                            found_mode = 1;
-                            break;
-                         }
-                  }
-                  search_idx++;
-               }
-               if(found_mode) {
-                       printk(KERN_DEBUG "sisfb: Adapted from %dx%dx%d to %dx%dx%d\n",
-                               var->xres, var->yres, var->bits_per_pixel,
-                               sisbios_mode[search_idx].xres,
-                               sisbios_mode[search_idx].yres,
-                               var->bits_per_pixel);
-                       var->xres = sisbios_mode[search_idx].xres;
-                       var->yres = sisbios_mode[search_idx].yres;
+       /* Sanity check for offsets */
+       if(var->xoffset < 0) var->xoffset = 0;
+       if(var->yoffset < 0) var->yoffset = 0;
 
+       if(var->xres > var->xres_virtual)
+               var->xres_virtual = var->xres;
 
+       if(ivideo->sisfb_ypan) {
+               maxyres = sisfb_calc_maxyres(ivideo, var);
+               if(ivideo->sisfb_max) {
+                       var->yres_virtual = maxyres;
                } else {
-                       printk(KERN_ERR "sisfb: Failed to find supported mode near %dx%dx%d\n",
-                               var->xres, var->yres, var->bits_per_pixel);
-                       return -EINVAL;
+                       if(var->yres_virtual > maxyres) {
+                               var->yres_virtual = maxyres;
+                       }
                }
-       }
-
-       if( ((ivideo->vbflags & VB_LVDS) ||                     /* Slave modes on LVDS and 301B-DH */
-            ((ivideo->vbflags & VB_30xBDH) && (ivideo->currentvbflags & CRT2_LCD))) &&
-           (var->bits_per_pixel == 8) ) {
-               refresh_rate = 60;
-               recalc_clock = TRUE;
-       } else if( (ivideo->current_htotal == htotal) &&        /* x=x & y=y & c=c -> assume depth change */
-                  (ivideo->current_vtotal == vtotal) &&
-                  (ivideo->current_pixclock == pixclock) ) {
-               drate = 1000000000 / pixclock;
-               hrate = (drate * 1000) / htotal;
-               refresh_rate = (unsigned int) (hrate * 2 / vtotal);
-       } else if( ( (ivideo->current_htotal != htotal) ||      /* x!=x | y!=y & c=c -> invalid pixclock */
-                    (ivideo->current_vtotal != vtotal) ) &&
-                  (ivideo->current_pixclock == var->pixclock) ) {
-               if(ivideo->sisfb_lastrates[sisbios_mode[search_idx].mode_no[ivideo->mni]]) {
-                       refresh_rate = ivideo->sisfb_lastrates[sisbios_mode[search_idx].mode_no[ivideo->mni]];
-               } else if(ivideo->sisfb_parm_rate != -1) {
-                       /* Sic, sisfb_parm_rate - want to know originally desired rate here */
-                       refresh_rate = ivideo->sisfb_parm_rate;
-               } else {
-                       refresh_rate = 60;
+               if(var->yres_virtual <= var->yres) {
+                       var->yres_virtual = var->yres;
                }
-               recalc_clock = TRUE;
-       } else if((pixclock) && (htotal) && (vtotal)) {
-               drate = 1000000000 / pixclock;
-               hrate = (drate * 1000) / htotal;
-               refresh_rate = (unsigned int) (hrate * 2 / vtotal);
-       } else if(ivideo->current_refresh_rate) {
-               refresh_rate = ivideo->current_refresh_rate;
-               recalc_clock = TRUE;
        } else {
-               refresh_rate = 60;
-               recalc_clock = TRUE;
-       }
-
-       myrateindex = sisfb_search_refresh_rate(ivideo, refresh_rate, search_idx);
-
-       /* Eventually recalculate timing and clock */
-       if(recalc_clock) {
-          if(!myrateindex) myrateindex = sisbios_mode[search_idx].rate_idx;
-          var->pixclock = (u32) (1000000000 / sisfb_mode_rate_to_dclock(&ivideo->SiS_Pr,
-                                               &ivideo->sishw_ext,
-                                               sisbios_mode[search_idx].mode_no[ivideo->mni],
-                                               myrateindex));
-          sisfb_mode_rate_to_ddata(&ivideo->SiS_Pr, &ivideo->sishw_ext,
-                                   sisbios_mode[search_idx].mode_no[ivideo->mni], myrateindex, var);
-          if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
-             var->pixclock <<= 1;
-          }
-       }
-
-       if(ivideo->sisfb_thismonitor.datavalid) {
-          if(!sisfb_verify_rate(ivideo, &ivideo->sisfb_thismonitor, search_idx,
-                                myrateindex, refresh_rate)) {
-             printk(KERN_INFO "sisfb: WARNING: Refresh rate exceeds monitor specs!\n");
-          }
-       }
-
-       /* Adapt RGB settings */
-       sisfb_bpp_to_var(ivideo, var);
-       
-       /* Sanity check for offsets */
-       if(var->xoffset < 0) var->xoffset = 0;
-       if(var->yoffset < 0) var->yoffset = 0;
-
-       if(var->xres > var->xres_virtual) {
-          var->xres_virtual = var->xres;
+               if(var->yres != var->yres_virtual) {
+                       var->yres_virtual = var->yres;
+               }
+               var->xoffset = 0;
+               var->yoffset = 0;
        }
 
-       if(ivideo->sisfb_ypan) {
-          maxyres = sisfb_calc_maxyres(ivideo, var);
-          if(ivideo->sisfb_max) {
-             var->yres_virtual = maxyres;
-          } else {
-             if(var->yres_virtual > maxyres) {
-                var->yres_virtual = maxyres;
-             }
-          }
-          if(var->yres_virtual <= var->yres) {
-             var->yres_virtual = var->yres;
-          }
-       } else {
-          if(var->yres != var->yres_virtual) {
-             var->yres_virtual = var->yres;
-          }
-          var->xoffset = 0;
-          var->yoffset = 0;
-       }
-       
        /* Truncate offsets to maximum if too high */
        if(var->xoffset > var->xres_virtual - var->xres) {
-          var->xoffset = var->xres_virtual - var->xres - 1;
+               var->xoffset = var->xres_virtual - var->xres - 1;
        }
 
        if(var->yoffset > var->yres_virtual - var->yres) {
-          var->yoffset = var->yres_virtual - var->yres - 1;
+               var->yoffset = var->yres_virtual - var->yres - 1;
        }
-       
+
        /* Set everything else to 0 */
-       var->red.msb_right = 
-       var->green.msb_right =
-       var->blue.msb_right =
-       var->transp.offset =
-       var->transp.length =
-       var->transp.msb_right = 0;
+       var->red.msb_right =
+               var->green.msb_right =
+               var->blue.msb_right =
+               var->transp.offset =
+               var->transp.length =
+               var->transp.msb_right = 0;
 
        return 0;
 }
@@ -2013,21 +1709,21 @@ sisfb_pan_display(struct fb_var_screeninfo *var, struct fb_info* info)
        struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
        int err;
 
-       if(var->xoffset > (var->xres_virtual - var->xres)) {
+       if(var->xoffset > (var->xres_virtual - var->xres))
                return -EINVAL;
-       }
-       if(var->yoffset > (var->yres_virtual - var->yres)) {
+
+       if(var->yoffset > (var->yres_virtual - var->yres))
                return -EINVAL;
-       }
 
-       if(var->vmode & FB_VMODE_YWRAP) return -EINVAL;
+       if(var->vmode & FB_VMODE_YWRAP)
+               return -EINVAL;
 
        if(var->xoffset + info->var.xres > info->var.xres_virtual ||
-          var->yoffset + info->var.yres > info->var.yres_virtual) {
+          var->yoffset + info->var.yres > info->var.yres_virtual)
                return -EINVAL;
-       }
 
-       if((err = sisfb_pan_var(ivideo, var)) < 0) return err;
+       if((err = sisfb_pan_var(ivideo, var)) < 0)
+               return err;
 
        info->var.xoffset = var->xoffset;
        info->var.yoffset = var->yoffset;
@@ -2040,7 +1736,7 @@ sisfb_blank(int blank, struct fb_info *info)
 {
        struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
 
-       return(sisfb_myblank(ivideo, blank));
+       return sisfb_myblank(ivideo, blank);
 }
 
 #endif
@@ -2056,153 +1752,184 @@ sisfb_ioctl(struct inode *inode, struct file *file,
            struct fb_info *info)
 {
        struct sis_video_info   *ivideo = (struct sis_video_info *)info->par;
-       struct sis_memreq       sismemreq;
-       struct fb_vblank        sisvbblank;
-       sisfb_info              x;
+       struct sis_memreq       sismemreq;
+       struct fb_vblank        sisvbblank;
        u32                     gpu32 = 0;
 #ifndef __user
 #define __user
 #endif
        u32 __user              *argp = (u32 __user *)arg;
 
-       switch (cmd) {
+       switch(cmd) {
           case FBIO_ALLOC:
-               if(!capable(CAP_SYS_RAWIO)) {
+               if(!capable(CAP_SYS_RAWIO))
                        return -EPERM;
-               }
-               if(copy_from_user(&sismemreq, (void __user *)arg, sizeof(sismemreq))) {
-                       return -EFAULT;
-               }
+
+               if(copy_from_user(&sismemreq, (void __user *)arg, sizeof(sismemreq)))
+                       return -EFAULT;
+
                sis_malloc(&sismemreq);
+
                if(copy_to_user((void __user *)arg, &sismemreq, sizeof(sismemreq))) {
                        sis_free((u32)sismemreq.offset);
-                       return -EFAULT;
+                       return -EFAULT;
                }
                break;
 
           case FBIO_FREE:
-               if(!capable(CAP_SYS_RAWIO)) {
+               if(!capable(CAP_SYS_RAWIO))
                        return -EPERM;
-               }
-               if(get_user(gpu32, argp)) {
+
+               if(get_user(gpu32, argp))
                        return -EFAULT;
-               }
+
                sis_free(gpu32);
                break;
 
           case FBIOGET_VBLANK:
                sisvbblank.count = 0;
                sisvbblank.flags = sisfb_setupvbblankflags(ivideo, &sisvbblank.vcount, &sisvbblank.hcount);
-               if(copy_to_user((void __user *)arg, &sisvbblank, sizeof(sisvbblank))) {
+
+               if(copy_to_user((void __user *)arg, &sisvbblank, sizeof(sisvbblank)))
                        return -EFAULT;
-               }
+
                break;
 
           case SISFB_GET_INFO_SIZE:
-               return put_user(sizeof(sisfb_info), argp);
+               return put_user(sizeof(struct sisfb_info), argp);
 
           case SISFB_GET_INFO_OLD:
-               if(ivideo->warncount++ < 50) {
-                  printk(KERN_INFO "sisfb: Deprecated ioctl call received - update your application!\n");
-               }
+               if(ivideo->warncount++ < 10)
+                       printk(KERN_INFO
+                               "sisfb: Deprecated ioctl call received - update your application!\n");
           case SISFB_GET_INFO:  /* For communication with X driver */
-               x.sisfb_id         = SISFB_ID;
-               x.sisfb_version    = VER_MAJOR;
-               x.sisfb_revision   = VER_MINOR;
-               x.sisfb_patchlevel = VER_LEVEL;
-               x.chip_id = ivideo->chip_id;
-               x.memory = ivideo->video_size / 1024;
-               x.heapstart = ivideo->heapstart / 1024;
+               ivideo->sisfb_infoblock.sisfb_id         = SISFB_ID;
+               ivideo->sisfb_infoblock.sisfb_version    = VER_MAJOR;
+               ivideo->sisfb_infoblock.sisfb_revision   = VER_MINOR;
+               ivideo->sisfb_infoblock.sisfb_patchlevel = VER_LEVEL;
+               ivideo->sisfb_infoblock.chip_id = ivideo->chip_id;
+               ivideo->sisfb_infoblock.sisfb_pci_vendor = ivideo->chip_vendor;
+               ivideo->sisfb_infoblock.memory = ivideo->video_size / 1024;
+               ivideo->sisfb_infoblock.heapstart = ivideo->heapstart / 1024;
                if(ivideo->modechanged) {
-                  x.fbvidmode = ivideo->mode_no;
+                       ivideo->sisfb_infoblock.fbvidmode = ivideo->mode_no;
                } else {
-                  x.fbvidmode = ivideo->modeprechange;
-               }
-               x.sisfb_caps = ivideo->caps;
-               x.sisfb_tqlen = 512; /* yet fixed */
-               x.sisfb_pcibus = ivideo->pcibus;
-               x.sisfb_pcislot = ivideo->pcislot;
-               x.sisfb_pcifunc = ivideo->pcifunc;
-               x.sisfb_lcdpdc = ivideo->detectedpdc;
-               x.sisfb_lcdpdca = ivideo->detectedpdca;
-               x.sisfb_lcda = ivideo->detectedlcda;
-               x.sisfb_vbflags = ivideo->vbflags;
-               x.sisfb_currentvbflags = ivideo->currentvbflags;
-               x.sisfb_scalelcd = ivideo->SiS_Pr.UsePanelScaler;
-               x.sisfb_specialtiming = ivideo->SiS_Pr.SiS_CustomT;
-               x.sisfb_haveemi = ivideo->SiS_Pr.HaveEMI ? 1 : 0;
-               x.sisfb_haveemilcd = ivideo->SiS_Pr.HaveEMILCD ? 1 : 0;
-               x.sisfb_emi30 = ivideo->SiS_Pr.EMI_30;
-               x.sisfb_emi31 = ivideo->SiS_Pr.EMI_31;
-               x.sisfb_emi32 = ivideo->SiS_Pr.EMI_32;
-               x.sisfb_emi33 = ivideo->SiS_Pr.EMI_33;
-               x.sisfb_tvxpos = (u16)(ivideo->tvxpos + 32);
-               x.sisfb_tvypos = (u16)(ivideo->tvypos + 32);
-
-               if(copy_to_user((void __user *)arg, &x, sizeof(x))) {
-                       return -EFAULT;
+                       ivideo->sisfb_infoblock.fbvidmode = ivideo->modeprechange;
                }
+               ivideo->sisfb_infoblock.sisfb_caps = ivideo->caps;
+               ivideo->sisfb_infoblock.sisfb_tqlen = ivideo->cmdQueueSize / 1024;
+               ivideo->sisfb_infoblock.sisfb_pcibus = ivideo->pcibus;
+               ivideo->sisfb_infoblock.sisfb_pcislot = ivideo->pcislot;
+               ivideo->sisfb_infoblock.sisfb_pcifunc = ivideo->pcifunc;
+               ivideo->sisfb_infoblock.sisfb_lcdpdc = ivideo->detectedpdc;
+               ivideo->sisfb_infoblock.sisfb_lcdpdca = ivideo->detectedpdca;
+               ivideo->sisfb_infoblock.sisfb_lcda = ivideo->detectedlcda;
+               ivideo->sisfb_infoblock.sisfb_vbflags = ivideo->vbflags;
+               ivideo->sisfb_infoblock.sisfb_currentvbflags = ivideo->currentvbflags;
+               ivideo->sisfb_infoblock.sisfb_scalelcd = ivideo->SiS_Pr.UsePanelScaler;
+               ivideo->sisfb_infoblock.sisfb_specialtiming = ivideo->SiS_Pr.SiS_CustomT;
+               ivideo->sisfb_infoblock.sisfb_haveemi = ivideo->SiS_Pr.HaveEMI ? 1 : 0;
+               ivideo->sisfb_infoblock.sisfb_haveemilcd = ivideo->SiS_Pr.HaveEMILCD ? 1 : 0;
+               ivideo->sisfb_infoblock.sisfb_emi30 = ivideo->SiS_Pr.EMI_30;
+               ivideo->sisfb_infoblock.sisfb_emi31 = ivideo->SiS_Pr.EMI_31;
+               ivideo->sisfb_infoblock.sisfb_emi32 = ivideo->SiS_Pr.EMI_32;
+               ivideo->sisfb_infoblock.sisfb_emi33 = ivideo->SiS_Pr.EMI_33;
+               ivideo->sisfb_infoblock.sisfb_tvxpos = (u16)(ivideo->tvxpos + 32);
+               ivideo->sisfb_infoblock.sisfb_tvypos = (u16)(ivideo->tvypos + 32);
+               ivideo->sisfb_infoblock.sisfb_heapsize = ivideo->sisfb_heap_size / 1024;
+               ivideo->sisfb_infoblock.sisfb_videooffset = ivideo->video_offset;
+               ivideo->sisfb_infoblock.sisfb_curfstn = ivideo->curFSTN;
+               ivideo->sisfb_infoblock.sisfb_curdstn = ivideo->curDSTN;
+               ivideo->sisfb_infoblock.sisfb_vbflags2 = ivideo->vbflags2;
+               ivideo->sisfb_infoblock.sisfb_can_post = ivideo->sisfb_can_post ? 1 : 0;
+               ivideo->sisfb_infoblock.sisfb_card_posted = ivideo->sisfb_card_posted ? 1 : 0;
+               ivideo->sisfb_infoblock.sisfb_was_boot_device = ivideo->sisfb_was_boot_device ? 1 : 0;
+
+               if(copy_to_user((void __user *)arg, &ivideo->sisfb_infoblock,
+                                               sizeof(ivideo->sisfb_infoblock)))
+                       return -EFAULT;
+
                break;
 
           case SISFB_GET_VBRSTATUS_OLD:
-               if(ivideo->warncount++ < 50) {
-                  printk(KERN_INFO "sisfb: Deprecated ioctl call received - update your application!\n");
-               }
+               if(ivideo->warncount++ < 10)
+                       printk(KERN_INFO
+                               "sisfb: Deprecated ioctl call received - update your application!\n");
           case SISFB_GET_VBRSTATUS:
-               if(sisfb_CheckVBRetrace(ivideo)) {
+               if(sisfb_CheckVBRetrace(ivideo))
                        return put_user((u32)1, argp);
-               } else {
+               else
                        return put_user((u32)0, argp);
-               }
 
           case SISFB_GET_AUTOMAXIMIZE_OLD:
-               if(ivideo->warncount++ < 50) {
-                  printk(KERN_INFO "sisfb: Deprecated ioctl call received - update your application!\n");
-               }
+               if(ivideo->warncount++ < 10)
+                       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(ivideo->warncount++ < 50) {
-                  printk(KERN_INFO "sisfb: Deprecated ioctl call received - update your application!\n");
-               }
+               if(ivideo->warncount++ < 10)
+                       printk(KERN_INFO
+                               "sisfb: Deprecated ioctl call received - update your application!\n");
           case SISFB_SET_AUTOMAXIMIZE:
-               if(copy_from_user(&gpu32, argp, sizeof(gpu32))) {
+               if(get_user(gpu32, argp))
                        return -EFAULT;
-               }
+
                ivideo->sisfb_max = (gpu32) ? 1 : 0;
                break;
 
           case SISFB_SET_TVPOSOFFSET:
-               if(copy_from_user(&gpu32, argp, sizeof(gpu32))) {
+               if(get_user(gpu32, argp))
                        return -EFAULT;
-               }
+
                sisfb_set_TVxposoffset(ivideo, ((int)(gpu32 >> 16)) - 32);
                sisfb_set_TVyposoffset(ivideo, ((int)(gpu32 & 0xffff)) - 32);
                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_COMMAND:
+               if(copy_from_user(&ivideo->sisfb_command, (void __user *)arg,
+                                                       sizeof(struct sisfb_cmd)))
+                       return -EFAULT;
+
+               sisfb_handle_command(ivideo, &ivideo->sisfb_command);
+
+               if(copy_to_user((void __user *)arg, &ivideo->sisfb_command,
+                                                       sizeof(struct sisfb_cmd)))
+                       return -EFAULT;
+
+               break;
 
           case SISFB_SET_LOCK:
-               if(copy_from_user(&gpu32, argp, sizeof(gpu32))) {
+               if(get_user(gpu32, argp))
                        return -EFAULT;
-               }
+
                ivideo->sisfblocked = (gpu32) ? 1 : 0;
                break;
 
           default:
+#ifdef SIS_NEW_CONFIG_COMPAT
                return -ENOIOCTLCMD;
+#else
+               return -EINVAL;
+#endif
        }
        return 0;
 }
 
-#ifdef CONFIG_COMPAT
-static long sisfb_compat_ioctl(struct file *f, unsigned cmd, unsigned long arg, struct fb_info *info)
+#ifdef SIS_NEW_CONFIG_COMPAT
+static long
+sisfb_compat_ioctl(struct file *f, unsigned int cmd, unsigned long arg, struct fb_info *info)
 {
        int ret;
+
        lock_kernel();
        ret = sisfb_ioctl(NULL, f, cmd, arg, info);
        unlock_kernel();
@@ -2219,7 +1946,7 @@ sisfb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info)
 
        strcpy(fix->id, ivideo->myid);
 
-       fix->smem_start  = ivideo->video_base;
+       fix->smem_start  = ivideo->video_base + ivideo->video_offset;
        fix->smem_len    = ivideo->sisfb_mem;
        fix->type        = FB_TYPE_PACKED_PIXELS;
        fix->type_aux    = 0;
@@ -2231,11 +1958,17 @@ sisfb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info)
        fix->mmio_start  = ivideo->mmio_base;
        fix->mmio_len    = ivideo->mmio_size;
        if(ivideo->sisvga_engine == SIS_300_VGA) {
-          fix->accel    = FB_ACCEL_SIS_GLAMOUR;
-       } else if((ivideo->chip == SIS_330) || (ivideo->chip == SIS_760)) {
-          fix->accel    = FB_ACCEL_SIS_XABRE;
+               fix->accel = FB_ACCEL_SIS_GLAMOUR;
+       } else if((ivideo->chip == SIS_330) ||
+                 (ivideo->chip == SIS_760) ||
+                 (ivideo->chip == SIS_761)) {
+               fix->accel = FB_ACCEL_SIS_XABRE;
+       } else if(ivideo->chip == XGI_20) {
+               fix->accel = FB_ACCEL_XGI_VOLARI_Z;
+       } else if(ivideo->chip >= XGI_40) {
+               fix->accel = FB_ACCEL_XGI_VOLARI_V;
        } else {
-          fix->accel    = FB_ACCEL_SIS_GLAMOUR_2;
+               fix->accel = FB_ACCEL_SIS_GLAMOUR_2;
        }
 
        return 0;
@@ -2251,40 +1984,41 @@ static struct fb_ops sisfb_ops = {
        .fb_set_var     = sisfb_set_var,
        .fb_get_cmap    = sisfb_get_cmap,
        .fb_set_cmap    = sisfb_set_cmap,
-        .fb_pan_display = sisfb_pan_display,
+       .fb_pan_display = sisfb_pan_display,
        .fb_ioctl       = sisfb_ioctl
 };
 #endif
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 static struct fb_ops sisfb_ops = {
-       .owner          = THIS_MODULE,
-       .fb_open        = sisfb_open,
-       .fb_release     = sisfb_release,
-       .fb_check_var   = sisfb_check_var,
-       .fb_set_par     = sisfb_set_par,
-       .fb_setcolreg   = sisfb_setcolreg,
-        .fb_pan_display = sisfb_pan_display,
-        .fb_blank       = sisfb_blank,
-       .fb_fillrect    = fbcon_sis_fillrect,
-       .fb_copyarea    = fbcon_sis_copyarea,
-       .fb_imageblit   = cfb_imageblit,
-       .fb_cursor      = soft_cursor,
-       .fb_sync        = fbcon_sis_sync,
-       .fb_ioctl       = sisfb_ioctl,
-#ifdef CONFIG_COMPAT
-       .fb_compat_ioctl = sisfb_compat_ioctl,
+       .owner          = THIS_MODULE,
+       .fb_open        = sisfb_open,
+       .fb_release     = sisfb_release,
+       .fb_check_var   = sisfb_check_var,
+       .fb_set_par     = sisfb_set_par,
+       .fb_setcolreg   = sisfb_setcolreg,
+       .fb_pan_display = sisfb_pan_display,
+       .fb_blank       = sisfb_blank,
+       .fb_fillrect    = fbcon_sis_fillrect,
+       .fb_copyarea    = fbcon_sis_copyarea,
+       .fb_imageblit   = cfb_imageblit,
+       .fb_cursor      = soft_cursor,
+       .fb_sync        = fbcon_sis_sync,
+#ifdef SIS_NEW_CONFIG_COMPAT
+       .fb_compat_ioctl= sisfb_compat_ioctl,
 #endif
+       .fb_ioctl       = sisfb_ioctl
 };
 #endif
 
 /* ---------------- Chip generation dependent routines ---------------- */
 
-static struct pci_dev * sisfb_get_northbridge(int basechipid)
+static struct pci_dev * __devinit
+sisfb_get_northbridge(int basechipid)
 {
        struct pci_dev *pdev = NULL;
        int nbridgenum, nbridgeidx, i;
-       const unsigned short nbridgeids[] = {
+       static const unsigned short nbridgeids[] = {
                PCI_DEVICE_ID_SI_540,   /* for SiS 540 VGA */
                PCI_DEVICE_ID_SI_630,   /* for SiS 630/730 VGA */
                PCI_DEVICE_ID_SI_730,
@@ -2292,13 +2026,14 @@ static struct pci_dev * sisfb_get_northbridge(int basechipid)
                PCI_DEVICE_ID_SI_650,   /* for SiS 650/651/740 VGA */
                PCI_DEVICE_ID_SI_651,
                PCI_DEVICE_ID_SI_740,
-               PCI_DEVICE_ID_SI_661,   /* for SiS 661/741/660/760 VGA */
+               PCI_DEVICE_ID_SI_661,   /* for SiS 661/741/660/760/761 VGA */
                PCI_DEVICE_ID_SI_741,
                PCI_DEVICE_ID_SI_660,
-               PCI_DEVICE_ID_SI_760
+               PCI_DEVICE_ID_SI_760,
+               PCI_DEVICE_ID_SI_761
        };
 
-       switch(basechipid) {
+       switch(basechipid) {
 #ifdef CONFIG_FB_SIS_300
        case SIS_540:   nbridgeidx = 0; nbridgenum = 1; break;
        case SIS_630:   nbridgeidx = 1; nbridgenum = 2; break;
@@ -2306,35 +2041,40 @@ static struct pci_dev * sisfb_get_northbridge(int basechipid)
 #ifdef CONFIG_FB_SIS_315
        case SIS_550:   nbridgeidx = 3; nbridgenum = 1; break;
        case SIS_650:   nbridgeidx = 4; nbridgenum = 3; break;
-       case SIS_660:   nbridgeidx = 7; nbridgenum = 4; break;
+       case SIS_660:   nbridgeidx = 7; nbridgenum = 5; break;
 #endif
        default:        return NULL;
        }
        for(i = 0; i < nbridgenum; i++) {
-               if((pdev = pci_find_device(PCI_VENDOR_ID_SI, nbridgeids[nbridgeidx+i], NULL))) break;
+               if((pdev = SIS_PCI_GET_DEVICE(PCI_VENDOR_ID_SI,
+                               nbridgeids[nbridgeidx+i], NULL)))
+                       break;
        }
        return pdev;
 }
 
-static int __devinit sisfb_get_dram_size(struct sis_video_info *ivideo)
+static int __devinit
+sisfb_get_dram_size(struct sis_video_info *ivideo)
 {
 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
        u8 reg;
 #endif
 
        ivideo->video_size = 0;
+       ivideo->UMAsize = ivideo->LFBsize = 0;
 
        switch(ivideo->chip) {
 #ifdef CONFIG_FB_SIS_300
        case SIS_300:
-               inSISIDXREG(SISSR, 0x14, reg);
+               inSISIDXREG(SISSR, 0x14, reg);
                ivideo->video_size = ((reg & 0x3F) + 1) << 20;
                break;
        case SIS_540:
        case SIS_630:
        case SIS_730:
-               if(!ivideo->nbridge) return -1;
-               pci_read_config_byte(ivideo->nbridge, 0x63, &reg);
+               if(!ivideo->nbridge)
+                       return -1;
+               pci_read_config_byte(ivideo->nbridge, 0x63, &reg);
                ivideo->video_size = 1 << (((reg & 0x70) >> 4) + 21);
                break;
 #endif
@@ -2342,45 +2082,68 @@ static int __devinit sisfb_get_dram_size(struct sis_video_info *ivideo)
        case SIS_315H:
        case SIS_315PRO:
        case SIS_315:
-               inSISIDXREG(SISSR, 0x14, reg);
+               inSISIDXREG(SISSR, 0x14, reg);
                ivideo->video_size = (1 << ((reg & 0xf0) >> 4)) << 20;
                switch((reg >> 2) & 0x03) {
                case 0x01:
                case 0x03:
-                  ivideo->video_size <<= 1;
-                  break;
+                       ivideo->video_size <<= 1;
+                       break;
                case 0x02:
-                  ivideo->video_size += (ivideo->video_size/2);
+                       ivideo->video_size += (ivideo->video_size/2);
                }
-               break;
+               break;
        case SIS_330:
-               inSISIDXREG(SISSR, 0x14, reg);
+               inSISIDXREG(SISSR, 0x14, reg);
                ivideo->video_size = (1 << ((reg & 0xf0) >> 4)) << 20;
                if(reg & 0x0c) ivideo->video_size <<= 1;
-               break;
+               break;
        case SIS_550:
        case SIS_650:
        case SIS_740:
-               inSISIDXREG(SISSR, 0x14, reg);
+               inSISIDXREG(SISSR, 0x14, reg);
                ivideo->video_size = (((reg & 0x3f) + 1) << 2) << 20;
                break;
        case SIS_661:
        case SIS_741:
-               inSISIDXREG(SISCR, 0x79, reg);
+               inSISIDXREG(SISCR, 0x79, reg);
                ivideo->video_size = (1 << ((reg & 0xf0) >> 4)) << 20;
-               break;
+               break;
        case SIS_660:
        case SIS_760:
+       case SIS_761:
                inSISIDXREG(SISCR, 0x79, reg);
                reg = (reg & 0xf0) >> 4;
-               if(reg) ivideo->video_size = (1 << reg) << 20;
+               if(reg) {
+                       ivideo->video_size = (1 << reg) << 20;
+                       ivideo->UMAsize = ivideo->video_size;
+               }
                inSISIDXREG(SISCR, 0x78, reg);
                reg &= 0x30;
                if(reg) {
-                  if(reg == 0x10) ivideo->video_size += (32 << 20);
-                  else            ivideo->video_size += (64 << 20);
+                       if(reg == 0x10) {
+                               ivideo->LFBsize = (32 << 20);
+                       } else {
+                               ivideo->LFBsize = (64 << 20);
+                       }
+                       ivideo->video_size += ivideo->LFBsize;
+               }
+               break;
+       case SIS_340:
+       case XGI_20:
+       case XGI_40:
+               inSISIDXREG(SISSR, 0x14, reg);
+               ivideo->video_size = (1 << ((reg & 0xf0) >> 4)) << 20;
+               if(ivideo->chip != XGI_20) {
+                       reg = (reg & 0x0c) >> 2;
+                       if(ivideo->revision_id == 2) {
+                               if(reg & 0x01) reg = 0x02;
+                               else           reg = 0x00;
+                       }
+                       if(reg == 0x02)         ivideo->video_size <<= 1;
+                       else if(reg == 0x03)    ivideo->video_size <<= 2;
                }
-               break;
+               break;
 #endif
        default:
                return -1;
@@ -2390,17 +2153,24 @@ static int __devinit sisfb_get_dram_size(struct sis_video_info *ivideo)
 
 /* -------------- video bridge device detection --------------- */
 
-static void __devinit sisfb_detect_VB_connect(struct sis_video_info *ivideo)
+static void __devinit
+sisfb_detect_VB_connect(struct sis_video_info *ivideo)
 {
        u8 cr32, temp;
 
+       /* No CRT2 on XGI Z7 */
+       if(ivideo->chip == XGI_20) {
+               ivideo->sisfb_crt1off = 0;
+               return;
+       }
+
 #ifdef CONFIG_FB_SIS_300
        if(ivideo->sisvga_engine == SIS_300_VGA) {
                inSISIDXREG(SISSR, 0x17, temp);
                if((temp & 0x0F) && (ivideo->chip != SIS_300)) {
                        /* PAL/NTSC is stored on SR16 on such machines */
                        if(!(ivideo->vbflags & (TV_PAL | TV_NTSC | TV_PALM | TV_PALN))) {
-                               inSISIDXREG(SISSR, 0x16, temp);
+                               inSISIDXREG(SISSR, 0x16, temp);
                                if(temp & 0x20)
                                        ivideo->vbflags |= TV_PAL;
                                else
@@ -2435,28 +2205,29 @@ static void __devinit sisfb_detect_VB_connect(struct sis_video_info *ivideo)
 
        if(ivideo->sisfb_tvplug != -1) {
           if( (ivideo->sisvga_engine != SIS_315_VGA) ||
-              (!(ivideo->vbflags & (VB_301C|VB_301LV|VB_302LV))) ) {
+              (!(ivideo->vbflags2 & VB2_SISYPBPRBRIDGE)) ) {
              if(ivideo->sisfb_tvplug & TV_YPBPR) {
-                ivideo->sisfb_tvplug = -1;
+                ivideo->sisfb_tvplug = -1;
                 printk(KERN_ERR "sisfb: YPbPr not supported\n");
              }
           }
        }
        if(ivideo->sisfb_tvplug != -1) {
           if( (ivideo->sisvga_engine != SIS_315_VGA) ||
-              (!(ivideo->vbflags & (VB_301|VB_301B|VB_302B))) ) {
+              (!(ivideo->vbflags2 & VB2_SISHIVISIONBRIDGE)) ) {
              if(ivideo->sisfb_tvplug & TV_HIVISION) {
-                ivideo->sisfb_tvplug = -1;
+                ivideo->sisfb_tvplug = -1;
                 printk(KERN_ERR "sisfb: HiVision not supported\n");
              }
           }
        }
        if(ivideo->sisfb_tvstd != -1) {
-          if( (!(ivideo->vbflags & VB_SISBRIDGE)) &&
-              (!((ivideo->sisvga_engine == SIS_315_VGA) && (ivideo->vbflags & VB_CHRONTEL))) ) {
+          if( (!(ivideo->vbflags2 & VB2_SISBRIDGE)) &&
+              (!((ivideo->sisvga_engine == SIS_315_VGA) &&
+                       (ivideo->vbflags2 & VB2_CHRONTEL))) ) {
              if(ivideo->sisfb_tvstd & (TV_PALN | TV_PALN | TV_NTSCJ)) {
-                ivideo->sisfb_tvstd = -1;
-                printk(KERN_ERR "sisfb: PALM/PALN/NTSCJ not supported\n");
+                ivideo->sisfb_tvstd = -1;
+                printk(KERN_ERR "sisfb: PALM/PALN/NTSCJ not supported\n");
              }
           }
        }
@@ -2468,7 +2239,7 @@ static void __devinit sisfb_detect_VB_connect(struct sis_video_info *ivideo)
                if(cr32 & SIS_VB_YPBPR)          ivideo->vbflags |= (TV_YPBPR|TV_YPBPR525I); /* default: 480i */
                else if(cr32 & SIS_VB_HIVISION)  ivideo->vbflags |= TV_HIVISION;
                else if(cr32 & SIS_VB_SCART)     ivideo->vbflags |= TV_SCART;
-               else {
+               else {
                        if(cr32 & SIS_VB_SVIDEO)    ivideo->vbflags |= TV_SVIDEO;
                        if(cr32 & SIS_VB_COMPOSITE) ivideo->vbflags |= TV_AVIDEO;
                }
@@ -2485,165 +2256,44 @@ static void __devinit sisfb_detect_VB_connect(struct sis_video_info *ivideo)
            }
            if(!(ivideo->vbflags & (TV_PAL | TV_NTSC | TV_PALM | TV_PALN | TV_NTSCJ))) {
                if(ivideo->sisvga_engine == SIS_300_VGA) {
-                       inSISIDXREG(SISSR, 0x38, temp);
+                       inSISIDXREG(SISSR, 0x38, temp);
                        if(temp & 0x01) ivideo->vbflags |= TV_PAL;
                        else            ivideo->vbflags |= TV_NTSC;
                } else if((ivideo->chip <= SIS_315PRO) || (ivideo->chip >= SIS_330)) {
-                       inSISIDXREG(SISSR, 0x38, temp);
+                       inSISIDXREG(SISSR, 0x38, temp);
                        if(temp & 0x01) ivideo->vbflags |= TV_PAL;
                        else            ivideo->vbflags |= TV_NTSC;
-               } else {
-                       inSISIDXREG(SISCR, 0x79, temp);
+               } else {
+                       inSISIDXREG(SISCR, 0x79, temp);
                        if(temp & 0x20) ivideo->vbflags |= TV_PAL;
                        else            ivideo->vbflags |= TV_NTSC;
-               }
+               }
            }
        }
 
        /* Copy forceCRT1 option to CRT1off if option is given */
-       if(ivideo->sisfb_forcecrt1 != -1) {
-          ivideo->sisfb_crt1off = (ivideo->sisfb_forcecrt1) ? 0 : 1;
-       }
-}
-
-static void __devinit sisfb_get_VB_type(struct sis_video_info *ivideo)
-{
-       char stdstr[]    = "sisfb: Detected";
-       char bridgestr[] = "video bridge";
-       u8 vb_chipid;
-       u8 reg;
-
-       inSISIDXREG(SISPART4, 0x00, vb_chipid);
-       switch(vb_chipid) {
-       case 0x01:
-               inSISIDXREG(SISPART4, 0x01, reg);
-               if(reg < 0xb0) {
-                       ivideo->vbflags |= VB_301;
-                       printk(KERN_INFO "%s SiS301 %s\n", stdstr, bridgestr);
-               } else if(reg < 0xc0) {
-                       ivideo->vbflags |= VB_301B;
-                       inSISIDXREG(SISPART4,0x23,reg);
-                       if(!(reg & 0x02)) {
-                          ivideo->vbflags |= VB_30xBDH;
-                          printk(KERN_INFO "%s SiS301B-DH %s\n", stdstr, bridgestr);
-                       } else {
-                          printk(KERN_INFO "%s SiS301B %s\n", stdstr, bridgestr);
-                       }
-               } else if(reg < 0xd0) {
-                       ivideo->vbflags |= VB_301C;
-                       printk(KERN_INFO "%s SiS301C %s\n", stdstr, bridgestr);
-               } else if(reg < 0xe0) {
-                       ivideo->vbflags |= VB_301LV;
-                       printk(KERN_INFO "%s SiS301LV %s\n", stdstr, bridgestr);
-               } else if(reg <= 0xe1) {
-                       inSISIDXREG(SISPART4,0x39,reg);
-                       if(reg == 0xff) {
-                          ivideo->vbflags |= VB_302LV;
-                          printk(KERN_INFO "%s SiS302LV %s\n", stdstr, bridgestr);
-                       } else {
-                          ivideo->vbflags |= VB_301C;
-                          printk(KERN_INFO "%s SiS301C(P4) %s\n", stdstr, bridgestr);
-#if 0
-                          ivideo->vbflags |= VB_302ELV;
-                          printk(KERN_INFO "%s SiS302ELV %s\n", stdstr, bridgestr);
-#endif
-                       }
-               }
-               break;
-       case 0x02:
-               ivideo->vbflags |= VB_302B;
-               printk(KERN_INFO "%s SiS302B %s\n", stdstr, bridgestr);
-               break;
-       }
-
-       if((!(ivideo->vbflags & VB_VIDEOBRIDGE)) && (ivideo->chip != SIS_300)) {
-               inSISIDXREG(SISCR, 0x37, reg);
-               reg &= SIS_EXTERNAL_CHIP_MASK;
-               reg >>= 1;
-               if(ivideo->sisvga_engine == SIS_300_VGA) {
-#ifdef CONFIG_FB_SIS_300
-                       switch(reg) {
-                          case SIS_EXTERNAL_CHIP_LVDS:
-                               ivideo->vbflags |= VB_LVDS;
-                               break;
-                          case SIS_EXTERNAL_CHIP_TRUMPION:
-                               ivideo->vbflags |= VB_TRUMPION;
-                               break;
-                          case SIS_EXTERNAL_CHIP_CHRONTEL:
-                               ivideo->vbflags |= VB_CHRONTEL;
-                               break;
-                          case SIS_EXTERNAL_CHIP_LVDS_CHRONTEL:
-                               ivideo->vbflags |= (VB_LVDS | VB_CHRONTEL);
-                               break;
-                       }
-                       if(ivideo->vbflags & VB_CHRONTEL) ivideo->chronteltype = 1;
-#endif
-               } else if(ivideo->chip < SIS_661) {
-#ifdef CONFIG_FB_SIS_315
-                       switch (reg) {
-                          case SIS310_EXTERNAL_CHIP_LVDS:
-                               ivideo->vbflags |= VB_LVDS;
-                               break;
-                          case SIS310_EXTERNAL_CHIP_LVDS_CHRONTEL:
-                               ivideo->vbflags |= (VB_LVDS | VB_CHRONTEL);
-                               break;
-                       }
-                       if(ivideo->vbflags & VB_CHRONTEL) ivideo->chronteltype = 2;
-#endif
-               } else if(ivideo->chip >= SIS_661) {
-#ifdef CONFIG_FB_SIS_315
-                       inSISIDXREG(SISCR, 0x38, reg);
-                       reg >>= 5;
-                       switch(reg) {
-                          case 0x02:
-                               ivideo->vbflags |= VB_LVDS;
-                               break;
-                          case 0x03:
-                               ivideo->vbflags |= (VB_LVDS | VB_CHRONTEL);
-                               break;
-                          case 0x04:
-                               ivideo->vbflags |= (VB_LVDS | VB_CONEXANT);
-                               break;
-                       }
-                       if(ivideo->vbflags & VB_CHRONTEL) ivideo->chronteltype = 2;
-#endif
-               }
-               if(ivideo->vbflags & VB_LVDS) {
-                  printk(KERN_INFO "%s LVDS transmitter\n", stdstr);
-               }
-               if(ivideo->vbflags & VB_TRUMPION) {
-                  printk(KERN_INFO "%s Trumpion Zurac LCD scaler\n", stdstr);
-               }
-               if(ivideo->vbflags & VB_CHRONTEL) {
-                  printk(KERN_INFO "%s Chrontel TV encoder\n", stdstr);
-               }
-               if(ivideo->vbflags & VB_CONEXANT) {
-                  printk(KERN_INFO "%s Conexant external device\n", stdstr);
-               }
-       }
-
-       if(ivideo->vbflags & VB_SISBRIDGE) {
-               SiS_Sense30x(ivideo);
-       } else if(ivideo->vbflags & VB_CHRONTEL) {
-               SiS_SenseCh(ivideo);
+       if(ivideo->sisfb_forcecrt1 != -1) {
+          ivideo->sisfb_crt1off = (ivideo->sisfb_forcecrt1) ? 0 : 1;
        }
 }
 
 /* ------------------ Sensing routines ------------------ */
 
-static BOOLEAN __devinit sisfb_test_DDC1(struct sis_video_info *ivideo)
+static BOOLEAN __devinit
+sisfb_test_DDC1(struct sis_video_info *ivideo)
 {
     unsigned short old;
     int count = 48;
 
     old = SiS_ReadDDC1Bit(&ivideo->SiS_Pr);
     do {
-               if(old != SiS_ReadDDC1Bit(&ivideo->SiS_Pr)) break;
+       if(old != SiS_ReadDDC1Bit(&ivideo->SiS_Pr)) break;
     } while(count--);
     return (count == -1) ? FALSE : TRUE;
 }
 
-static void __devinit sisfb_sense_crt1(struct sis_video_info *ivideo)
+static void __devinit
+sisfb_sense_crt1(struct sis_video_info *ivideo)
 {
     BOOLEAN mustwait = FALSE;
     u8  sr1F, cr17;
@@ -2699,7 +2349,8 @@ static void __devinit sisfb_sense_crt1(struct sis_video_info *ivideo)
     if(temp == 0xffff) {
        i = 3;
        do {
-          temp = SiS_HandleDDC(&ivideo->SiS_Pr, ivideo->vbflags, ivideo->sisvga_engine, 0, 0, NULL);
+         temp = SiS_HandleDDC(&ivideo->SiS_Pr, ivideo->vbflags,
+               ivideo->sisvga_engine, 0, 0, NULL, ivideo->vbflags2);
        } while(((temp == 0) || (temp == 0xffff)) && i--);
 
        if((temp == 0) || (temp == 0xffff)) {
@@ -2723,7 +2374,96 @@ static void __devinit sisfb_sense_crt1(struct sis_video_info *ivideo)
 }
 
 /* Determine and detect attached devices on SiS30x */
-static int __devinit SISDoSense(struct sis_video_info *ivideo, u16 type, u16 test)
+static void __devinit
+SiS_SenseLCD(struct sis_video_info *ivideo)
+{
+       unsigned char buffer[256];
+       unsigned short temp, realcrtno, i;
+       u8 reg, cr37 = 0, paneltype = 0;
+       u16 xres, yres;
+
+       ivideo->SiS_Pr.PanelSelfDetected = FALSE;
+
+       /* LCD detection only for TMDS bridges */
+       if(!(ivideo->vbflags2 & VB2_SISTMDSBRIDGE))
+               return;
+       if(ivideo->vbflags2 & VB2_30xBDH)
+               return;
+
+       /* If LCD already set up by BIOS, skip it */
+       inSISIDXREG(SISCR, 0x32, reg);
+       if(reg & 0x08)
+               return;
+
+       realcrtno = 1;
+       if(ivideo->SiS_Pr.DDCPortMixup)
+               realcrtno = 0;
+
+       /* Check DDC capabilities */
+       temp = SiS_HandleDDC(&ivideo->SiS_Pr, ivideo->vbflags, ivideo->sisvga_engine,
+                               realcrtno, 0, &buffer[0], ivideo->vbflags2);
+
+       if((!temp) || (temp == 0xffff) || (!(temp & 0x02)))
+               return;
+
+       /* Read DDC data */
+       i = 3;  /* Number of retrys */
+       do {
+               temp = SiS_HandleDDC(&ivideo->SiS_Pr, ivideo->vbflags,
+                               ivideo->sisvga_engine, realcrtno, 1,
+                               &buffer[0], ivideo->vbflags2);
+       } while((temp) && i--);
+
+       if(temp)
+               return;
+
+       /* No digital device */
+       if(!(buffer[0x14] & 0x80))
+               return;
+
+       /* First detailed timing preferred timing? */
+       if(!(buffer[0x18] & 0x02))
+               return;
+
+       xres = buffer[0x38] | ((buffer[0x3a] & 0xf0) << 4);
+       yres = buffer[0x3b] | ((buffer[0x3d] & 0xf0) << 4);
+
+       switch(xres) {
+               case 1024:
+                       if(yres == 768)
+                               paneltype = 0x02;
+                       break;
+               case 1280:
+                       if(yres == 1024)
+                               paneltype = 0x03;
+                       break;
+               case 1600:
+                       if((yres == 1200) && (ivideo->vbflags2 & VB2_30xC))
+                               paneltype = 0x0b;
+                       break;
+       }
+
+       if(!paneltype)
+               return;
+
+       if(buffer[0x23])
+               cr37 |= 0x10;
+
+       if((buffer[0x47] & 0x18) == 0x18)
+               cr37 |= ((((buffer[0x47] & 0x06) ^ 0x06) << 5) | 0x20);
+       else
+               cr37 |= 0xc0;
+
+       outSISIDXREG(SISCR, 0x36, paneltype);
+       cr37 &= 0xf1;
+       setSISIDXREG(SISCR, 0x37, 0x0c, cr37);
+       orSISIDXREG(SISCR, 0x32, 0x08);
+
+       ivideo->SiS_Pr.PanelSelfDetected = TRUE;
+}
+
+static int __devinit
+SISDoSense(struct sis_video_info *ivideo, u16 type, u16 test)
 {
     int temp, mytest, result, i, j;
 
@@ -2749,10 +2489,11 @@ static int __devinit SISDoSense(struct sis_video_info *ivideo, u16 type, u16 tes
        }
        if((result == 0) || (result >= 2)) break;
     }
-    return(result);
+    return result;
 }
 
-static void __devinit SiS_Sense30x(struct sis_video_info *ivideo)
+static void __devinit
+SiS_Sense30x(struct sis_video_info *ivideo)
 {
     u8  backupP4_0d,backupP2_00,backupP2_4d,backupSR_1e,biosflag=0;
     u16 svhs=0, svhs_c=0;
@@ -2762,36 +2503,51 @@ static void __devinit SiS_Sense30x(struct sis_video_info *ivideo)
     char stdstr[] = "sisfb: Detected";
     char tvstr[]  = "TV connected to";
 
-    if(ivideo->vbflags & VB_301) {
+    if(ivideo->vbflags2 & VB2_301) {
        svhs = 0x00b9; cvbs = 0x00b3; vga2 = 0x00d1;
        inSISIDXREG(SISPART4,0x01,myflag);
        if(myflag & 0x04) {
          svhs = 0x00dd; cvbs = 0x00ee; vga2 = 0x00fd;
        }
-    } else if(ivideo->vbflags & (VB_301B | VB_302B)) {
+    } else if(ivideo->vbflags2 & (VB2_301B | VB2_302B)) {
        svhs = 0x016b; cvbs = 0x0174; vga2 = 0x0190;
-    } else if(ivideo->vbflags & (VB_301LV | VB_302LV)) {
+    } else if(ivideo->vbflags2 & (VB2_301LV | VB2_302LV)) {
        svhs = 0x0200; cvbs = 0x0100;
-    } else if(ivideo->vbflags & (VB_301C | VB_302ELV)) {
+    } else if(ivideo->vbflags2 & (VB2_301C | VB2_302ELV | VB2_307T | VB2_307LV)) {
        svhs = 0x016b; cvbs = 0x0110; vga2 = 0x0190;
-    } else return;
+    } else
+       return;
 
     vga2_c = 0x0e08; svhs_c = 0x0404; cvbs_c = 0x0804;
-    if(ivideo->vbflags & (VB_301LV|VB_302LV|VB_302ELV)) {
+    if(ivideo->vbflags & (VB2_301LV|VB2_302LV|VB2_302ELV|VB2_307LV)) {
        svhs_c = 0x0408; cvbs_c = 0x0808;
     }
+
     biosflag = 2;
+    if(ivideo->haveXGIROM) {
+       biosflag = ivideo->bios_abase[0x58] & 0x03;
+    } else if(ivideo->newrom) {
+       if(ivideo->bios_abase[0x5d] & 0x04) biosflag |= 0x01;
+    } else if(ivideo->sisvga_engine == SIS_300_VGA) {
+       if(ivideo->bios_abase) {
+          biosflag = ivideo->bios_abase[0xfe] & 0x03;
+       }
+    }
 
     if(ivideo->chip == SIS_300) {
        inSISIDXREG(SISSR,0x3b,myflag);
        if(!(myflag & 0x01)) vga2 = vga2_c = 0;
     }
 
+    if(!(ivideo->vbflags2 & VB2_SISVGA2BRIDGE)) {
+       vga2 = vga2_c = 0;
+    }
+
     inSISIDXREG(SISSR,0x1e,backupSR_1e);
     orSISIDXREG(SISSR,0x1e,0x20);
 
     inSISIDXREG(SISPART4,0x0d,backupP4_0d);
-    if(ivideo->vbflags & VB_301C) {
+    if(ivideo->vbflags2 & VB2_30xC) {
        setSISIDXREG(SISPART4,0x0d,~0x07,0x01);
     } else {
        orSISIDXREG(SISPART4,0x0d,0x04);
@@ -2802,11 +2558,11 @@ static void __devinit SiS_Sense30x(struct sis_video_info *ivideo)
     outSISIDXREG(SISPART2,0x00,((backupP2_00 | 0x1c) & 0xfc));
 
     inSISIDXREG(SISPART2,0x4d,backupP2_4d);
-    if(ivideo->vbflags & (VB_301C|VB_301LV|VB_302LV|VB_302ELV)) {
+    if(ivideo->vbflags2 & VB2_SISYPBPRBRIDGE) {
        outSISIDXREG(SISPART2,0x4d,(backupP2_4d & ~0x10));
     }
 
-    if(!(ivideo->vbflags & VB_301C)) {
+    if(!(ivideo->vbflags2 & VB2_30xCLV)) {
        SISDoSense(ivideo, 0, 0);
     }
 
@@ -2826,12 +2582,11 @@ static void __devinit SiS_Sense30x(struct sis_video_info *ivideo)
 
     andSISIDXREG(SISCR, 0x32, 0x3f);
 
-    if(ivideo->vbflags & VB_301C) {
+    if(ivideo->vbflags2 & VB2_30xCLV) {
        orSISIDXREG(SISPART4,0x0d,0x04);
     }
 
-    if((ivideo->sisvga_engine == SIS_315_VGA) &&
-       (ivideo->vbflags & (VB_301C|VB_301LV|VB_302LV|VB_302ELV))) {
+    if((ivideo->sisvga_engine == SIS_315_VGA) && (ivideo->vbflags2 & VB2_SISYPBPRBRIDGE)) {
        outSISIDXREG(SISPART2,0x4d,(backupP2_4d | 0x10));
        SiS_DDC2Delay(&ivideo->SiS_Pr, 0x2000);
        if((result = SISDoSense(ivideo, svhs, 0x0604))) {
@@ -2864,7 +2619,7 @@ static void __devinit SiS_Sense30x(struct sis_video_info *ivideo)
     outSISIDXREG(SISPART4,0x0d,backupP4_0d);
     outSISIDXREG(SISSR,0x1e,backupSR_1e);
 
-    if(ivideo->vbflags & VB_301C) {
+    if(ivideo->vbflags2 & VB2_30xCLV) {
        inSISIDXREG(SISPART2,0x00,biosflag);
        if(biosflag & 0x20) {
           for(myflag = 2; myflag > 0; myflag--) {
@@ -2878,7 +2633,8 @@ static void __devinit SiS_Sense30x(struct sis_video_info *ivideo)
 }
 
 /* Determine and detect attached TV's on Chrontel */
-static void __devinit SiS_SenseCh(struct sis_video_info *ivideo)
+static void __devinit
+SiS_SenseCh(struct sis_video_info *ivideo)
 {
 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
     u8 temp1, temp2;
@@ -2899,7 +2655,7 @@ static void __devinit SiS_SenseCh(struct sis_video_info *ivideo)
        /* See Chrontel TB31 for explanation */
        temp2 = SiS_GetCH700x(&ivideo->SiS_Pr, 0x0e);
        if(((temp2 & 0x07) == 0x01) || (temp2 & 0x04)) {
-         SiS_SetCH700x(&ivideo->SiS_Pr, 0x0b0e);
+         SiS_SetCH700x(&ivideo->SiS_Pr, 0x0e, 0x0b);
          SiS_DDC2Delay(&ivideo->SiS_Pr, 300);
        }
        temp2 = SiS_GetCH700x(&ivideo->SiS_Pr, 0x25);
@@ -2909,15 +2665,15 @@ static void __devinit SiS_SenseCh(struct sis_video_info *ivideo)
           /* Read power status */
           temp1 = SiS_GetCH700x(&ivideo->SiS_Pr, 0x0e);
           if((temp1 & 0x03) != 0x03) {
-               /* Power all outputs */
-               SiS_SetCH700x(&ivideo->SiS_Pr, 0x0B0E);
+               /* Power all outputs */
+               SiS_SetCH700x(&ivideo->SiS_Pr, 0x0e,0x0b);
                SiS_DDC2Delay(&ivideo->SiS_Pr, 300);
           }
           /* Sense connected TV devices */
           for(i = 0; i < 3; i++) {
-              SiS_SetCH700x(&ivideo->SiS_Pr, 0x0110);
+              SiS_SetCH700x(&ivideo->SiS_Pr, 0x10, 0x01);
               SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96);
-              SiS_SetCH700x(&ivideo->SiS_Pr, 0x0010);
+              SiS_SetCH700x(&ivideo->SiS_Pr, 0x10, 0x00);
               SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96);
               temp1 = SiS_GetCH700x(&ivideo->SiS_Pr, 0x10);
               if(!(temp1 & 0x08))       test[i] = 0x02;
@@ -2930,7 +2686,7 @@ static void __devinit SiS_SenseCh(struct sis_video_info *ivideo)
           else if(test[0] == test[2]) temp1 = test[0];
           else if(test[1] == test[2]) temp1 = test[1];
           else {
-               printk(KERN_INFO
+               printk(KERN_INFO
                        "sisfb: TV detection unreliable - test results varied\n");
                temp1 = test[2];
           }
@@ -2945,11 +2701,11 @@ static void __devinit SiS_SenseCh(struct sis_video_info *ivideo)
                orSISIDXREG(SISCR, 0x32, 0x01);
                andSISIDXREG(SISCR, 0x32, ~0x06);
           } else {
-               SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, 0x010E,0xF8);
+               SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, 0x0e, 0x01, 0xF8);
                andSISIDXREG(SISCR, 0x32, ~0x07);
           }
        } else if(temp1 == 0) {
-         SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, 0x010E,0xF8);
+         SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, 0x0e, 0x01, 0xF8);
          andSISIDXREG(SISCR, 0x32, ~0x07);
        }
        /* Set general purpose IO for Chrontel communication */
@@ -2960,19 +2716,19 @@ static void __devinit SiS_SenseCh(struct sis_video_info *ivideo)
 
 #ifdef CONFIG_FB_SIS_315
        ivideo->SiS_Pr.SiS_IF_DEF_CH70xx = 2;           /* Chrontel 7019 */
-        temp1 = SiS_GetCH701x(&ivideo->SiS_Pr, 0x49);
-       SiS_SetCH701x(&ivideo->SiS_Pr, 0x2049);
+       temp1 = SiS_GetCH701x(&ivideo->SiS_Pr, 0x49);
+       SiS_SetCH701x(&ivideo->SiS_Pr, 0x49, 0x20);
        SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96);
        temp2 = SiS_GetCH701x(&ivideo->SiS_Pr, 0x20);
        temp2 |= 0x01;
-       SiS_SetCH701x(&ivideo->SiS_Pr, (temp2 << 8) | 0x20);
+       SiS_SetCH701x(&ivideo->SiS_Pr, 0x20, temp2);
        SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96);
        temp2 ^= 0x01;
-       SiS_SetCH701x(&ivideo->SiS_Pr, (temp2 << 8) | 0x20);
+       SiS_SetCH701x(&ivideo->SiS_Pr, 0x20, temp2);
        SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96);
        temp2 = SiS_GetCH701x(&ivideo->SiS_Pr, 0x20);
-       SiS_SetCH701x(&ivideo->SiS_Pr, (temp1 << 8) | 0x49);
-        temp1 = 0;
+       SiS_SetCH701x(&ivideo->SiS_Pr, 0x49, temp1);
+       temp1 = 0;
        if(temp2 & 0x02) temp1 |= 0x01;
        if(temp2 & 0x10) temp1 |= 0x01;
        if(temp2 & 0x04) temp1 |= 0x02;
@@ -2983,18 +2739,18 @@ static void __devinit SiS_SenseCh(struct sis_video_info *ivideo)
             ivideo->vbflags |= TV_AVIDEO;
             orSISIDXREG(SISCR, 0x32, 0x01);
             andSISIDXREG(SISCR, 0x32, ~0x06);
-             break;
+            break;
        case 0x02:
             printk(KERN_INFO "%s SVIDEO output\n", stdstr);
             ivideo->vbflags |= TV_SVIDEO;
             orSISIDXREG(SISCR, 0x32, 0x02);
             andSISIDXREG(SISCR, 0x32, ~0x05);
-             break;
+            break;
        case 0x04:
             printk(KERN_INFO "%s SCART output\n", stdstr);
             orSISIDXREG(SISCR, 0x32, 0x04);
             andSISIDXREG(SISCR, 0x32, ~0x03);
-             break;
+            break;
        default:
             andSISIDXREG(SISCR, 0x32, ~0x07);
        }
@@ -3002,165 +2758,589 @@ static void __devinit SiS_SenseCh(struct sis_video_info *ivideo)
     }
 }
 
-/* ------------------------ Heap routines -------------------------- */
-
-static u32 __devinit
-sisfb_getheapstart(struct sis_video_info *ivideo)
+static void __devinit
+sisfb_get_VB_type(struct sis_video_info *ivideo)
 {
-       u32 ret = ivideo->sisfb_parm_mem * 1024;
-       u32 max = ivideo->video_size - ivideo->hwcursor_size;
-       u32 def;
+       char stdstr[]    = "sisfb: Detected";
+       char bridgestr[] = "video bridge";
+       u8 vb_chipid;
+       u8 reg;
 
-       /* Calculate heap start = end of memory for console
-        *
-        * CCCCCCCCDDDDDDDDDDDDDDDDDDDDDDDDDDDDHHHHQQQQQQQQQQ
-        * C = console, D = heap, H = HWCursor, Q = cmd-queue
-        *
-        * Basically given by "mem" parameter
-        *
-        * maximum = videosize - cmd_queue - hwcursor
-        *           (results in a heap of size 0)
-        * default = SiS 300: depends on videosize
-        *           SiS 315/330: 32k below max
-        */
+       /* No CRT2 on XGI Z7 */
+       if(ivideo->chip == XGI_20)
+               return;
 
-       if(ivideo->sisvga_engine == SIS_300_VGA) {
-          max -= TURBO_QUEUE_AREA_SIZE;
-          if(ivideo->video_size > 0x1000000) {
-             def = 0xc00000;
-          } else if(ivideo->video_size > 0x800000) {
-             def = 0x800000;
-          } else {
-             def = 0x400000;
-          }
-       } else {
-          max -= COMMAND_QUEUE_AREA_SIZE;
-          def = max - 0x8000;
+       inSISIDXREG(SISPART4, 0x00, vb_chipid);
+       switch(vb_chipid) {
+       case 0x01:
+               inSISIDXREG(SISPART4, 0x01, reg);
+               if(reg < 0xb0) {
+                       ivideo->vbflags |= VB_301;      /* Deprecated */
+                       ivideo->vbflags2 |= VB2_301;
+                       printk(KERN_INFO "%s SiS301 %s\n", stdstr, bridgestr);
+               } else if(reg < 0xc0) {
+                       ivideo->vbflags |= VB_301B;     /* Deprecated */
+                       ivideo->vbflags2 |= VB2_301B;
+                       inSISIDXREG(SISPART4,0x23,reg);
+                       if(!(reg & 0x02)) {
+                          ivideo->vbflags |= VB_30xBDH;        /* Deprecated */
+                          ivideo->vbflags2 |= VB2_30xBDH;
+                          printk(KERN_INFO "%s SiS301B-DH %s\n", stdstr, bridgestr);
+                       } else {
+                          printk(KERN_INFO "%s SiS301B %s\n", stdstr, bridgestr);
+                       }
+               } else if(reg < 0xd0) {
+                       ivideo->vbflags |= VB_301C;     /* Deprecated */
+                       ivideo->vbflags2 |= VB2_301C;
+                       printk(KERN_INFO "%s SiS301C %s\n", stdstr, bridgestr);
+               } else if(reg < 0xe0) {
+                       ivideo->vbflags |= VB_301LV;    /* Deprecated */
+                       ivideo->vbflags2 |= VB2_301LV;
+                       printk(KERN_INFO "%s SiS301LV %s\n", stdstr, bridgestr);
+               } else if(reg <= 0xe1) {
+                       inSISIDXREG(SISPART4,0x39,reg);
+                       if(reg == 0xff) {
+                          ivideo->vbflags |= VB_302LV; /* Deprecated */
+                          ivideo->vbflags2 |= VB2_302LV;
+                          printk(KERN_INFO "%s SiS302LV %s\n", stdstr, bridgestr);
+                       } else {
+                          ivideo->vbflags |= VB_301C;  /* Deprecated */
+                          ivideo->vbflags2 |= VB2_301C;
+                          printk(KERN_INFO "%s SiS301C(P4) %s\n", stdstr, bridgestr);
+#if 0
+                          ivideo->vbflags |= VB_302ELV;        /* Deprecated */
+                          ivideo->vbflags2 |= VB2_302ELV;
+                          printk(KERN_INFO "%s SiS302ELV %s\n", stdstr, bridgestr);
+#endif
+                       }
+               }
+               break;
+       case 0x02:
+               ivideo->vbflags |= VB_302B;     /* Deprecated */
+               ivideo->vbflags2 |= VB2_302B;
+               printk(KERN_INFO "%s SiS302B %s\n", stdstr, bridgestr);
+               break;
        }
 
-        if((!ret) || (ret > max) || (ivideo->cardnumber != 0)) {
-          ret = def;
-        }
-
-       return ret;
-}
-
-static int __devinit
-sisfb_heap_init(struct sis_video_info *ivideo)
+       if((!(ivideo->vbflags2 & VB2_VIDEOBRIDGE)) && (ivideo->chip != SIS_300)) {
+               inSISIDXREG(SISCR, 0x37, reg);
+               reg &= SIS_EXTERNAL_CHIP_MASK;
+               reg >>= 1;
+               if(ivideo->sisvga_engine == SIS_300_VGA) {
+#ifdef CONFIG_FB_SIS_300
+                       switch(reg) {
+                          case SIS_EXTERNAL_CHIP_LVDS:
+                               ivideo->vbflags |= VB_LVDS;     /* Deprecated */
+                               ivideo->vbflags2 |= VB2_LVDS;
+                               break;
+                          case SIS_EXTERNAL_CHIP_TRUMPION:
+                               ivideo->vbflags |= (VB_LVDS | VB_TRUMPION);     /* Deprecated */
+                               ivideo->vbflags2 |= (VB2_LVDS | VB2_TRUMPION);
+                               break;
+                          case SIS_EXTERNAL_CHIP_CHRONTEL:
+                               ivideo->vbflags |= VB_CHRONTEL; /* Deprecated */
+                               ivideo->vbflags2 |= VB2_CHRONTEL;
+                               break;
+                          case SIS_EXTERNAL_CHIP_LVDS_CHRONTEL:
+                               ivideo->vbflags |= (VB_LVDS | VB_CHRONTEL);     /* Deprecated */
+                               ivideo->vbflags2 |= (VB2_LVDS | VB2_CHRONTEL);
+                               break;
+                       }
+                       if(ivideo->vbflags2 & VB2_CHRONTEL) ivideo->chronteltype = 1;
+#endif
+               } else if(ivideo->chip < SIS_661) {
+#ifdef CONFIG_FB_SIS_315
+                       switch (reg) {
+                          case SIS310_EXTERNAL_CHIP_LVDS:
+                               ivideo->vbflags |= VB_LVDS;     /* Deprecated */
+                               ivideo->vbflags2 |= VB2_LVDS;
+                               break;
+                          case SIS310_EXTERNAL_CHIP_LVDS_CHRONTEL:
+                               ivideo->vbflags |= (VB_LVDS | VB_CHRONTEL);     /* Deprecated */
+                               ivideo->vbflags2 |= (VB2_LVDS | VB2_CHRONTEL);
+                               break;
+                       }
+                       if(ivideo->vbflags2 & VB2_CHRONTEL) ivideo->chronteltype = 2;
+#endif
+               } else if(ivideo->chip >= SIS_661) {
+#ifdef CONFIG_FB_SIS_315
+                       inSISIDXREG(SISCR, 0x38, reg);
+                       reg >>= 5;
+                       switch(reg) {
+                          case 0x02:
+                               ivideo->vbflags |= VB_LVDS;     /* Deprecated */
+                               ivideo->vbflags2 |= VB2_LVDS;
+                               break;
+                          case 0x03:
+                               ivideo->vbflags |= (VB_LVDS | VB_CHRONTEL);     /* Deprecated */
+                               ivideo->vbflags2 |= (VB2_LVDS | VB2_CHRONTEL);
+                               break;
+                          case 0x04:
+                               ivideo->vbflags |= (VB_LVDS | VB_CONEXANT);     /* Deprecated */
+                               ivideo->vbflags2 |= (VB2_LVDS | VB2_CONEXANT);
+                               break;
+                       }
+                       if(ivideo->vbflags2 & VB2_CHRONTEL) ivideo->chronteltype = 2;
+#endif
+               }
+               if(ivideo->vbflags2 & VB2_LVDS) {
+                  printk(KERN_INFO "%s LVDS transmitter\n", stdstr);
+               }
+               if((ivideo->sisvga_engine == SIS_300_VGA) && (ivideo->vbflags2 & VB2_TRUMPION)) {
+                  printk(KERN_INFO "%s Trumpion Zurac LCD scaler\n", stdstr);
+               }
+               if(ivideo->vbflags2 & VB2_CHRONTEL) {
+                  printk(KERN_INFO "%s Chrontel TV encoder\n", stdstr);
+               }
+               if((ivideo->chip >= SIS_661) && (ivideo->vbflags2 & VB2_CONEXANT)) {
+                  printk(KERN_INFO "%s Conexant external device\n", stdstr);
+               }
+       }
+
+       if(ivideo->vbflags2 & VB2_SISBRIDGE) {
+               SiS_SenseLCD(ivideo);
+               SiS_Sense30x(ivideo);
+       } else if(ivideo->vbflags2 & VB2_CHRONTEL) {
+               SiS_SenseCh(ivideo);
+       }
+}
+
+/* ---------- Engine initialization routines ------------ */
+
+static void
+sisfb_engine_init(struct sis_video_info *ivideo)
 {
-     SIS_OH *poh;
 
-     ivideo->heapstart = ivideo->sisfb_mem = sisfb_getheapstart(ivideo);
+       /* Initialize command queue (we use MMIO only) */
 
-     ivideo->sisfb_heap_start = ivideo->video_vbase + ivideo->heapstart;
-     ivideo->sisfb_heap_end   = ivideo->video_vbase + ivideo->video_size;
+       /* BEFORE THIS IS CALLED, THE ENGINES *MUST* BE SYNC'ED */
 
-     /* Initialize command queue (We use MMIO only) */
+       ivideo->caps &= ~(TURBO_QUEUE_CAP    |
+                         MMIO_CMD_QUEUE_CAP |
+                         VM_CMD_QUEUE_CAP   |
+                         AGP_CMD_QUEUE_CAP);
+
+#ifdef CONFIG_FB_SIS_300
+       if(ivideo->sisvga_engine == SIS_300_VGA) {
+               u32 tqueue_pos;
+               u8 tq_state;
+
+               tqueue_pos = (ivideo->video_size - ivideo->cmdQueueSize) / (64 * 1024);
+
+               inSISIDXREG(SISSR, IND_SIS_TURBOQUEUE_SET, tq_state);
+               tq_state |= 0xf0;
+               tq_state &= 0xfc;
+               tq_state |= (u8)(tqueue_pos >> 8);
+               outSISIDXREG(SISSR, IND_SIS_TURBOQUEUE_SET, tq_state);
+
+               outSISIDXREG(SISSR, IND_SIS_TURBOQUEUE_ADR, (u8)(tqueue_pos & 0xff));
+
+               ivideo->caps |= TURBO_QUEUE_CAP;
+       }
+#endif
 
 #ifdef CONFIG_FB_SIS_315
-     if(ivideo->sisvga_engine == SIS_315_VGA) {
-        u32 tempq = 0;
-       u8  temp = 0;
+       if(ivideo->sisvga_engine == SIS_315_VGA) {
+               u32 tempq = 0, templ;
+               u8  temp;
+
+               if(ivideo->chip == XGI_20) {
+                       switch(ivideo->cmdQueueSize) {
+                       case (64 * 1024):
+                               temp = SIS_CMD_QUEUE_SIZE_Z7_64k;
+                               break;
+                       case (128 * 1024):
+                       default:
+                               temp = SIS_CMD_QUEUE_SIZE_Z7_128k;
+                       }
+               } else {
+                       switch(ivideo->cmdQueueSize) {
+                       case (4 * 1024 * 1024):
+                               temp = SIS_CMD_QUEUE_SIZE_4M;
+                               break;
+                       case (2 * 1024 * 1024):
+                               temp = SIS_CMD_QUEUE_SIZE_2M;
+                               break;
+                       case (1 * 1024 * 1024):
+                               temp = SIS_CMD_QUEUE_SIZE_1M;
+                               break;
+                       default:
+                       case (512 * 1024):
+                               temp = SIS_CMD_QUEUE_SIZE_512k;
+                       }
+               }
+
+               outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD);
+               outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_SET, SIS_CMD_QUEUE_RESET);
+
+               if((ivideo->chip >= XGI_40) && ivideo->modechanged) {
+                       /* Must disable dual pipe on XGI_40. Can't do
+                        * this in MMIO mode, because it requires
+                        * setting/clearing a bit in the MMIO fire trigger
+                        * register.
+                        */
+                       if(!((templ = MMIO_IN32(ivideo->mmio_vbase, 0x8240)) & (1 << 10))) {
+
+                               MMIO_OUT32(ivideo->mmio_vbase, Q_WRITE_PTR, 0);
+
+                               outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_SET, (temp | SIS_VRAM_CMDQUEUE_ENABLE));
+
+                               tempq = MMIO_IN32(ivideo->mmio_vbase, Q_READ_PTR);
+                               MMIO_OUT32(ivideo->mmio_vbase, Q_WRITE_PTR, tempq);
 
-        ivideo->sisfb_heap_end -= COMMAND_QUEUE_AREA_SIZE;
+                               tempq = (u32)(ivideo->video_size - ivideo->cmdQueueSize);
+                               MMIO_OUT32(ivideo->mmio_vbase, Q_BASE_ADDR, tempq);
 
-       outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD);
-       outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_SET, SIS_CMD_QUEUE_RESET);
+                               writel(0x16800000 + 0x8240, ivideo->video_vbase + tempq);
+                               writel(templ | (1 << 10), ivideo->video_vbase + tempq + 4);
+                               writel(0x168F0000, ivideo->video_vbase + tempq + 8);
+                               writel(0x168F0000, ivideo->video_vbase + tempq + 12);
+
+                               MMIO_OUT32(ivideo->mmio_vbase, Q_WRITE_PTR, (tempq + 16));
+
+                               sisfb_syncaccel(ivideo);
+
+                               outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_SET, SIS_CMD_QUEUE_RESET);
+
+                       }
+               }
+
+               tempq = MMIO_IN32(ivideo->mmio_vbase, MMIO_QUEUE_READPORT);
+               MMIO_OUT32(ivideo->mmio_vbase, MMIO_QUEUE_WRITEPORT, tempq);
+
+               temp |= (SIS_MMIO_CMD_ENABLE | SIS_CMD_AUTO_CORR);
+               outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_SET, temp);
+
+               tempq = (u32)(ivideo->video_size - ivideo->cmdQueueSize);
+               MMIO_OUT32(ivideo->mmio_vbase, MMIO_QUEUE_PHYBASE, tempq);
+
+               ivideo->caps |= MMIO_CMD_QUEUE_CAP;
+       }
+#endif
+
+       ivideo->engineok = 1;
+}
+
+static void __devinit
+sisfb_detect_lcd_type(struct sis_video_info *ivideo)
+{
+       u8 reg;
+       int i;
 
-       tempq = MMIO_IN32(ivideo->mmio_vbase, MMIO_QUEUE_READPORT);
-       MMIO_OUT32(ivideo->mmio_vbase, MMIO_QUEUE_WRITEPORT, tempq);
+       inSISIDXREG(SISCR, 0x36, reg);
+       reg &= 0x0f;
+       if(ivideo->sisvga_engine == SIS_300_VGA) {
+               ivideo->CRT2LCDType = sis300paneltype[reg];
+       } else if(ivideo->chip >= SIS_661) {
+               ivideo->CRT2LCDType = sis661paneltype[reg];
+       } else {
+               ivideo->CRT2LCDType = sis310paneltype[reg];
+               if((ivideo->chip == SIS_550) && (sisfb_fstn)) {
+                       if((ivideo->CRT2LCDType != LCD_320x240_2) &&
+                          (ivideo->CRT2LCDType != LCD_320x240_3)) {
+                               ivideo->CRT2LCDType = LCD_320x240;
+                       }
+               }
+       }
 
-       temp = SIS_CMD_QUEUE_SIZE_512k;
-       temp |= (SIS_MMIO_CMD_ENABLE | SIS_CMD_AUTO_CORR);
-       outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_SET, temp);
+       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);
+       }
 
-       tempq = (u32)(ivideo->video_size - COMMAND_QUEUE_AREA_SIZE);
-       MMIO_OUT32(ivideo->mmio_vbase, MMIO_QUEUE_PHYBASE, tempq);
+       for(i = 0; i < SIS_LCD_NUMBER; i++) {
+               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;
+                       break;
+               }
+       }
 
-       ivideo->caps |= MMIO_CMD_QUEUE_CAP;
-     }
+#ifdef CONFIG_FB_SIS_300
+       if(ivideo->SiS_Pr.SiS_CustomT == CUT_BARCO1366) {
+               ivideo->lcdxres = 1360; ivideo->lcdyres = 1024;
+               ivideo->lcddefmodeidx = DEFAULT_MODE_1360;
+       } else if(ivideo->SiS_Pr.SiS_CustomT == CUT_PANEL848) {
+               ivideo->lcdxres =  848; ivideo->lcdyres =  480;
+               ivideo->lcddefmodeidx = DEFAULT_MODE_848;
+       } else if(ivideo->SiS_Pr.SiS_CustomT == CUT_PANEL856) {
+               ivideo->lcdxres =  856; ivideo->lcdyres =  480;
+               ivideo->lcddefmodeidx = DEFAULT_MODE_856;
+       }
 #endif
 
+       printk(KERN_DEBUG "sisfb: Detected %dx%d flat panel\n",
+                       ivideo->lcdxres, ivideo->lcdyres);
+}
+
+static void __devinit
+sisfb_save_pdc_emi(struct sis_video_info *ivideo)
+{
 #ifdef CONFIG_FB_SIS_300
-     if(ivideo->sisvga_engine == SIS_300_VGA) {
-       unsigned long tqueue_pos;
-       u8 tq_state;
+       /* Save the current PanelDelayCompensation if the LCD is currently used */
+       if(ivideo->sisvga_engine == SIS_300_VGA) {
+               if(ivideo->vbflags2 & (VB2_LVDS | VB2_30xBDH)) {
+                       int tmp;
+                       inSISIDXREG(SISCR,0x30,tmp);
+                       if(tmp & 0x20) {
+                               /* Currently on LCD? If yes, read current pdc */
+                               inSISIDXREG(SISPART1,0x13,ivideo->detectedpdc);
+                               ivideo->detectedpdc &= 0x3c;
+                               if(ivideo->SiS_Pr.PDC == -1) {
+                                       /* Let option override detection */
+                                       ivideo->SiS_Pr.PDC = ivideo->detectedpdc;
+                               }
+                               printk(KERN_INFO "sisfb: Detected LCD PDC 0x%02x\n",
+                                       ivideo->detectedpdc);
+                       }
+                       if((ivideo->SiS_Pr.PDC != -1) &&
+                          (ivideo->SiS_Pr.PDC != ivideo->detectedpdc)) {
+                               printk(KERN_INFO "sisfb: Using LCD PDC 0x%02x\n",
+                                       ivideo->SiS_Pr.PDC);
+                       }
+               }
+       }
+#endif
+
+#ifdef CONFIG_FB_SIS_315
+       if(ivideo->sisvga_engine == SIS_315_VGA) {
 
-       ivideo->sisfb_heap_end -= TURBO_QUEUE_AREA_SIZE;
+               /* Try to find about LCDA */
+               if(ivideo->vbflags2 & VB2_SISLCDABRIDGE) {
+                       int tmp;
+                       inSISIDXREG(SISPART1,0x13,tmp);
+                       if(tmp & 0x04) {
+                               ivideo->SiS_Pr.SiS_UseLCDA = TRUE;
+                               ivideo->detectedlcda = 0x03;
+                       }
+               }
 
-       tqueue_pos = (ivideo->video_size - TURBO_QUEUE_AREA_SIZE) / (64 * 1024);
+               /* Save PDC */
+               if(ivideo->vbflags2 & VB2_SISLVDSBRIDGE) {
+                       int tmp;
+                       inSISIDXREG(SISCR,0x30,tmp);
+                       if((tmp & 0x20) || (ivideo->detectedlcda != 0xff)) {
+                               /* Currently on LCD? If yes, read current pdc */
+                               u8 pdc;
+                               inSISIDXREG(SISPART1,0x2D,pdc);
+                               ivideo->detectedpdc  = (pdc & 0x0f) << 1;
+                               ivideo->detectedpdca = (pdc & 0xf0) >> 3;
+                               inSISIDXREG(SISPART1,0x35,pdc);
+                               ivideo->detectedpdc |= ((pdc >> 7) & 0x01);
+                               inSISIDXREG(SISPART1,0x20,pdc);
+                               ivideo->detectedpdca |= ((pdc >> 6) & 0x01);
+                               if(ivideo->newrom) {
+                                       /* New ROM invalidates other PDC resp. */
+                                       if(ivideo->detectedlcda != 0xff) {
+                                               ivideo->detectedpdc = 0xff;
+                                       } else {
+                                               ivideo->detectedpdca = 0xff;
+                                       }
+                               }
+                               if(ivideo->SiS_Pr.PDC == -1) {
+                                       if(ivideo->detectedpdc != 0xff) {
+                                               ivideo->SiS_Pr.PDC = ivideo->detectedpdc;
+                                       }
+                               }
+                               if(ivideo->SiS_Pr.PDCA == -1) {
+                                       if(ivideo->detectedpdca != 0xff) {
+                                               ivideo->SiS_Pr.PDCA = ivideo->detectedpdca;
+                                       }
+                               }
+                               if(ivideo->detectedpdc != 0xff) {
+                                       printk(KERN_INFO
+                                               "sisfb: Detected LCD PDC 0x%02x (for LCD=CRT2)\n",
+                                               ivideo->detectedpdc);
+                               }
+                               if(ivideo->detectedpdca != 0xff) {
+                                       printk(KERN_INFO
+                                               "sisfb: Detected LCD PDC1 0x%02x (for LCD=CRT1)\n",
+                                               ivideo->detectedpdca);
+                               }
+                       }
 
-       inSISIDXREG(SISSR, IND_SIS_TURBOQUEUE_SET, tq_state);
-       tq_state |= 0xf0;
-       tq_state &= 0xfc;
-       tq_state |= (u8)(tqueue_pos >> 8);
-       outSISIDXREG(SISSR, IND_SIS_TURBOQUEUE_SET, tq_state);
+                       /* Save EMI */
+                       if(ivideo->vbflags2 & VB2_SISEMIBRIDGE) {
+                               inSISIDXREG(SISPART4,0x30,ivideo->SiS_Pr.EMI_30);
+                               inSISIDXREG(SISPART4,0x31,ivideo->SiS_Pr.EMI_31);
+                               inSISIDXREG(SISPART4,0x32,ivideo->SiS_Pr.EMI_32);
+                               inSISIDXREG(SISPART4,0x33,ivideo->SiS_Pr.EMI_33);
+                               ivideo->SiS_Pr.HaveEMI = TRUE;
+                               if((tmp & 0x20) || (ivideo->detectedlcda != 0xff)) {
+                                       ivideo->SiS_Pr.HaveEMILCD = TRUE;
+                               }
+                       }
+               }
 
-       outSISIDXREG(SISSR, IND_SIS_TURBOQUEUE_ADR, (u8)(tqueue_pos & 0xff));
+               /* Let user override detected PDCs (all bridges) */
+               if(ivideo->vbflags2 & VB2_30xBLV) {
+                       if((ivideo->SiS_Pr.PDC != -1) &&
+                          (ivideo->SiS_Pr.PDC != ivideo->detectedpdc)) {
+                               printk(KERN_INFO "sisfb: Using LCD PDC 0x%02x (for LCD=CRT2)\n",
+                                       ivideo->SiS_Pr.PDC);
+                       }
+                       if((ivideo->SiS_Pr.PDCA != -1) &&
+                          (ivideo->SiS_Pr.PDCA != ivideo->detectedpdca)) {
+                               printk(KERN_INFO "sisfb: Using LCD PDC1 0x%02x (for LCD=CRT1)\n",
+                                ivideo->SiS_Pr.PDCA);
+                       }
+               }
 
-       ivideo->caps |= TURBO_QUEUE_CAP;
-     }
+       }
 #endif
+}
+
+/* -------------------- Memory manager routines ---------------------- */
+
+static u32 __devinit
+sisfb_getheapstart(struct sis_video_info *ivideo)
+{
+       u32 ret = ivideo->sisfb_parm_mem * 1024;
+       u32 maxoffs = ivideo->video_size - ivideo->hwcursor_size - ivideo->cmdQueueSize;
+       u32 def;
+
+       /* Calculate heap start = end of memory for console
+        *
+        * CCCCCCCCDDDDDDDDDDDDDDDDDDDDDDDDDDDDHHHHQQQQQQQQQQ
+        * C = console, D = heap, H = HWCursor, Q = cmd-queue
+        *
+        * On 76x in UMA+LFB mode, the layout is as follows:
+        * DDDDDDDDDDDCCCCCCCCCCCCCCCCCCCCCCCCHHHHQQQQQQQQQQQ
+        * where the heap is the entire UMA area, eventually
+        * into the LFB area if the given mem parameter is
+        * higher than the size of the UMA memory.
+        *
+        * Basically given by "mem" parameter
+        *
+        * maximum = videosize - cmd_queue - hwcursor
+        *           (results in a heap of size 0)
+        * default = SiS 300: depends on videosize
+        *           SiS 315/330/340/XGI: 32k below max
+        */
+
+       if(ivideo->sisvga_engine == SIS_300_VGA) {
+               if(ivideo->video_size > 0x1000000) {
+                       def = 0xc00000;
+               } else if(ivideo->video_size > 0x800000) {
+                       def = 0x800000;
+               } else {
+                       def = 0x400000;
+               }
+       } else if(ivideo->UMAsize && ivideo->LFBsize) {
+               ret = def = 0;
+       } else {
+               def = maxoffs - 0x8000;
+       }
+
+       /* Use default for secondary card for now (FIXME) */
+       if((!ret) || (ret > maxoffs) || (ivideo->cardnumber != 0))
+               ret = def;
+
+       return ret;
+}
+
+static u32 __devinit
+sisfb_getheapsize(struct sis_video_info *ivideo)
+{
+       u32 max = ivideo->video_size - ivideo->hwcursor_size - ivideo->cmdQueueSize;
+       u32 ret = 0;
+
+       if(ivideo->UMAsize && ivideo->LFBsize) {
+               if( (!ivideo->sisfb_parm_mem)                   ||
+                   ((ivideo->sisfb_parm_mem * 1024) > max)     ||
+                   ((max - (ivideo->sisfb_parm_mem * 1024)) < ivideo->UMAsize) ) {
+                       ret = ivideo->UMAsize;
+                       max -= ivideo->UMAsize;
+               } else {
+                       ret = max - (ivideo->sisfb_parm_mem * 1024);
+                       max = ivideo->sisfb_parm_mem * 1024;
+               }
+               ivideo->video_offset = ret;
+               ivideo->sisfb_mem = max;
+       } else {
+               ret = max - ivideo->heapstart;
+               ivideo->sisfb_mem = ivideo->heapstart;
+       }
 
-     /* Reserve memory for the HWCursor */
-     ivideo->sisfb_heap_end -= ivideo->hwcursor_size;
-     ivideo->hwcursor_vbase = ivideo->sisfb_heap_end;
-     ivideo->caps |= HW_CURSOR_CAP;
+       return ret;
+}
 
-     ivideo->sisfb_heap_size = ivideo->sisfb_heap_end - ivideo->sisfb_heap_start;
+static int __devinit
+sisfb_heap_init(struct sis_video_info *ivideo)
+{
+       struct SIS_OH *poh;
 
-     if(ivideo->cardnumber == 0) {
+       ivideo->video_offset = 0;
+       if(ivideo->sisfb_parm_mem) {
+               if( (ivideo->sisfb_parm_mem < (2 * 1024 * 1024)) ||
+                   (ivideo->sisfb_parm_mem > ivideo->video_size) ) {
+                       ivideo->sisfb_parm_mem = 0;
+               }
+       }
 
-       printk(KERN_INFO "sisfb: Memory heap starting at %dK, size %dK\n",
-               (int)(ivideo->heapstart / 1024), (int)(ivideo->sisfb_heap_size / 1024));
+       ivideo->heapstart = sisfb_getheapstart(ivideo);
+       ivideo->sisfb_heap_size = sisfb_getheapsize(ivideo);
 
-       sisfb_heap.vinfo = ivideo;
+       ivideo->sisfb_heap_start = ivideo->video_vbase + ivideo->heapstart;
+       ivideo->sisfb_heap_end   = ivideo->sisfb_heap_start + ivideo->sisfb_heap_size;
 
-       sisfb_heap.poha_chain = NULL;
-       sisfb_heap.poh_freelist = NULL;
+       printk(KERN_INFO "sisfb: Memory heap starting at %dK, size %dK\n",
+               (int)(ivideo->heapstart / 1024), (int)(ivideo->sisfb_heap_size / 1024));
 
-       poh = sisfb_poh_new_node();
-       if(poh == NULL) return 1;
+       ivideo->sisfb_heap.vinfo = ivideo;
 
-       poh->poh_next = &sisfb_heap.oh_free;
-       poh->poh_prev = &sisfb_heap.oh_free;
-       poh->size = ivideo->sisfb_heap_size;
-       poh->offset = ivideo->heapstart;
+       ivideo->sisfb_heap.poha_chain = NULL;
+       ivideo->sisfb_heap.poh_freelist = NULL;
 
-       sisfb_heap.oh_free.poh_next = poh;
-       sisfb_heap.oh_free.poh_prev = poh;
-       sisfb_heap.oh_free.size = 0;
-       sisfb_heap.max_freesize = poh->size;
+       poh = sisfb_poh_new_node(&ivideo->sisfb_heap);
+       if(poh == NULL)
+               return 1;
 
-       sisfb_heap.oh_used.poh_next = &sisfb_heap.oh_used;
-       sisfb_heap.oh_used.poh_prev = &sisfb_heap.oh_used;
-       sisfb_heap.oh_used.size = SENTINEL;
+       poh->poh_next = &ivideo->sisfb_heap.oh_free;
+       poh->poh_prev = &ivideo->sisfb_heap.oh_free;
+       poh->size = ivideo->sisfb_heap_size;
+       poh->offset = ivideo->heapstart;
 
-     } else {
+       ivideo->sisfb_heap.oh_free.poh_next = poh;
+       ivideo->sisfb_heap.oh_free.poh_prev = poh;
+       ivideo->sisfb_heap.oh_free.size = 0;
+       ivideo->sisfb_heap.max_freesize = poh->size;
 
-        printk(KERN_INFO "Skipped heap initialization for secondary cards\n");
+       ivideo->sisfb_heap.oh_used.poh_next = &ivideo->sisfb_heap.oh_used;
+       ivideo->sisfb_heap.oh_used.poh_prev = &ivideo->sisfb_heap.oh_used;
+       ivideo->sisfb_heap.oh_used.size = SENTINEL;
 
-     }
+       if(ivideo->cardnumber == 0) {
+               /* For the first card, make this heap the "global" one
+                * for old DRM (which could handle only one card)
+                */
+               sisfb_heap = &ivideo->sisfb_heap;
+       }
 
-     return 0;
+       return 0;
 }
 
-static SIS_OH *
-sisfb_poh_new_node(void)
+static struct SIS_OH *
+sisfb_poh_new_node(struct SIS_HEAP *memheap)
 {
-       int           i;
-       unsigned long cOhs;
-       SIS_OHALLOC   *poha;
-       SIS_OH        *poh;
+       struct SIS_OHALLOC      *poha;
+       struct SIS_OH           *poh;
+       unsigned long           cOhs;
+       int                     i;
 
-       if(sisfb_heap.poh_freelist == NULL) {
+       if(memheap->poh_freelist == NULL) {
                poha = kmalloc(SIS_OH_ALLOC_SIZE, GFP_KERNEL);
-               if(!poha) return NULL;
+               if(!poha)
+                       return NULL;
 
-               poha->poha_next = sisfb_heap.poha_chain;
-               sisfb_heap.poha_chain = poha;
+               poha->poha_next = memheap->poha_chain;
+               memheap->poha_chain = poha;
 
-               cOhs = (SIS_OH_ALLOC_SIZE - sizeof(SIS_OHALLOC)) / sizeof(SIS_OH) + 1;
+               cOhs = (SIS_OH_ALLOC_SIZE - sizeof(struct SIS_OHALLOC)) / sizeof(struct SIS_OH) + 1;
 
                poh = &poha->aoh[0];
                for(i = cOhs - 1; i != 0; i--) {
@@ -3169,32 +3349,32 @@ sisfb_poh_new_node(void)
                }
 
                poh->poh_next = NULL;
-               sisfb_heap.poh_freelist = &poha->aoh[0];
+               memheap->poh_freelist = &poha->aoh[0];
        }
 
-       poh = sisfb_heap.poh_freelist;
-       sisfb_heap.poh_freelist = poh->poh_next;
+       poh = memheap->poh_freelist;
+       memheap->poh_freelist = poh->poh_next;
 
-       return (poh);
+       return poh;
 }
 
-static SIS_OH *
-sisfb_poh_allocate(u32 size)
+static struct SIS_OH *
+sisfb_poh_allocate(struct SIS_HEAP *memheap, u32 size)
 {
-       SIS_OH *pohThis;
-       SIS_OH *pohRoot;
-       int     bAllocated = 0;
+       struct SIS_OH   *pohThis;
+       struct SIS_OH   *pohRoot;
+       int             bAllocated = 0;
 
-       if(size > sisfb_heap.max_freesize) {
+       if(size > memheap->max_freesize) {
                DPRINTK("sisfb: Can't allocate %dk video memory\n",
                        (unsigned int) size / 1024);
-               return (NULL);
+               return NULL;
        }
 
-       pohThis = sisfb_heap.oh_free.poh_next;
+       pohThis = memheap->oh_free.poh_next;
 
-       while(pohThis != &sisfb_heap.oh_free) {
-               if (size <= pohThis->size) {
+       while(pohThis != &memheap->oh_free) {
+               if(size <= pohThis->size) {
                        bAllocated = 1;
                        break;
                }
@@ -3204,18 +3384,16 @@ sisfb_poh_allocate(u32 size)
        if(!bAllocated) {
                DPRINTK("sisfb: Can't allocate %dk video memory\n",
                        (unsigned int) size / 1024);
-               return (NULL);
+               return NULL;
        }
 
        if(size == pohThis->size) {
                pohRoot = pohThis;
                sisfb_delete_node(pohThis);
        } else {
-               pohRoot = sisfb_poh_new_node();
-
-               if(pohRoot == NULL) {
-                       return (NULL);
-               }
+               pohRoot = sisfb_poh_new_node(memheap);
+               if(pohRoot == NULL)
+                       return NULL;
 
                pohRoot->offset = pohThis->offset;
                pohRoot->size = size;
@@ -3224,33 +3402,25 @@ sisfb_poh_allocate(u32 size)
                pohThis->size -= size;
        }
 
-       sisfb_heap.max_freesize -= size;
+       memheap->max_freesize -= size;
 
-       pohThis = &sisfb_heap.oh_used;
+       pohThis = &memheap->oh_used;
        sisfb_insert_node(pohThis, pohRoot);
 
-       return (pohRoot);
+       return pohRoot;
 }
 
 static void
-sisfb_delete_node(SIS_OH *poh)
+sisfb_delete_node(struct SIS_OH *poh)
 {
-       SIS_OH *poh_prev;
-       SIS_OH *poh_next;
-
-       poh_prev = poh->poh_prev;
-       poh_next = poh->poh_next;
-
-       poh_prev->poh_next = poh_next;
-       poh_next->poh_prev = poh_prev;
+       poh->poh_prev->poh_next = poh->poh_next;
+       poh->poh_next->poh_prev = poh->poh_prev;
 }
 
 static void
-sisfb_insert_node(SIS_OH *pohList, SIS_OH *poh)
+sisfb_insert_node(struct SIS_OH *pohList, struct SIS_OH *poh)
 {
-       SIS_OH *pohTemp;
-
-       pohTemp = pohList->poh_next;
+       struct SIS_OH *pohTemp = pohList->poh_next;
 
        pohList->poh_next = poh;
        pohTemp->poh_prev = poh;
@@ -3259,20 +3429,20 @@ sisfb_insert_node(SIS_OH *pohList, SIS_OH *poh)
        poh->poh_next = pohTemp;
 }
 
-static SIS_OH *
-sisfb_poh_free(u32 base)
+static struct SIS_OH *
+sisfb_poh_free(struct SIS_HEAP *memheap, u32 base)
 {
-       SIS_OH *pohThis;
-       SIS_OH *poh_freed;
-       SIS_OH *poh_prev;
-       SIS_OH *poh_next;
-       u32     ulUpper;
-       u32     ulLower;
-       int     foundNode = 0;
+       struct SIS_OH *pohThis;
+       struct SIS_OH *poh_freed;
+       struct SIS_OH *poh_prev;
+       struct SIS_OH *poh_next;
+       u32    ulUpper;
+       u32    ulLower;
+       int    foundNode = 0;
 
-       poh_freed = sisfb_heap.oh_used.poh_next;
+       poh_freed = memheap->oh_used.poh_next;
 
-       while(poh_freed != &sisfb_heap.oh_used) {
+       while(poh_freed != &memheap->oh_used) {
                if(poh_freed->offset == base) {
                        foundNode = 1;
                        break;
@@ -3281,17 +3451,18 @@ sisfb_poh_free(u32 base)
                poh_freed = poh_freed->poh_next;
        }
 
-       if(!foundNode) return(NULL);
+       if(!foundNode)
+               return NULL;
 
-       sisfb_heap.max_freesize += poh_freed->size;
+       memheap->max_freesize += poh_freed->size;
 
        poh_prev = poh_next = NULL;
        ulUpper = poh_freed->offset + poh_freed->size;
        ulLower = poh_freed->offset;
 
-       pohThis = sisfb_heap.oh_free.poh_next;
+       pohThis = memheap->oh_free.poh_next;
 
-       while(pohThis != &sisfb_heap.oh_free) {
+       while(pohThis != &memheap->oh_free) {
                if(pohThis->offset == ulUpper) {
                        poh_next = pohThis;
                } else if((pohThis->offset + pohThis->size) == ulLower) {
@@ -3305,70 +3476,88 @@ sisfb_poh_free(u32 base)
        if(poh_prev && poh_next) {
                poh_prev->size += (poh_freed->size + poh_next->size);
                sisfb_delete_node(poh_next);
-               sisfb_free_node(poh_freed);
-               sisfb_free_node(poh_next);
-               return(poh_prev);
+               sisfb_free_node(memheap, poh_freed);
+               sisfb_free_node(memheap, poh_next);
+               return poh_prev;
        }
 
        if(poh_prev) {
                poh_prev->size += poh_freed->size;
-               sisfb_free_node(poh_freed);
-               return(poh_prev);
+               sisfb_free_node(memheap, poh_freed);
+               return poh_prev;
        }
 
        if(poh_next) {
                poh_next->size += poh_freed->size;
                poh_next->offset = poh_freed->offset;
-               sisfb_free_node(poh_freed);
-               return(poh_next);
+               sisfb_free_node(memheap, poh_freed);
+               return poh_next;
        }
 
-       sisfb_insert_node(&sisfb_heap.oh_free, poh_freed);
+       sisfb_insert_node(&memheap->oh_free, poh_freed);
 
-       return(poh_freed);
+       return poh_freed;
 }
 
 static void
-sisfb_free_node(SIS_OH *poh)
+sisfb_free_node(struct SIS_HEAP *memheap, struct SIS_OH *poh)
 {
-       if(poh == NULL) return;
+       if(poh == NULL)
+               return;
 
-       poh->poh_next = sisfb_heap.poh_freelist;
-       sisfb_heap.poh_freelist = poh;
+       poh->poh_next = memheap->poh_freelist;
+       memheap->poh_freelist = poh;
 }
 
-void
-sis_malloc(struct sis_memreq *req)
+static void
+sis_int_malloc(struct sis_video_info *ivideo, struct sis_memreq *req)
 {
-       struct sis_video_info *ivideo = sisfb_heap.vinfo;
-       SIS_OH *poh = NULL;
+       struct SIS_OH *poh = NULL;
 
-       if((ivideo) && (!ivideo->havenoheap)) {
-          poh = sisfb_poh_allocate((u32)req->size);
-       }
+       if((ivideo) && (ivideo->sisfb_id == SISFB_ID) && (!ivideo->havenoheap))
+               poh = sisfb_poh_allocate(&ivideo->sisfb_heap, (u32)req->size);
 
        if(poh == NULL) {
-          req->offset = req->size = 0;
-          DPRINTK("sisfb: Video RAM allocation failed\n");
+               req->offset = req->size = 0;
+               DPRINTK("sisfb: Video RAM allocation failed\n");
        } else {
-          req->offset = poh->offset;
-          req->size = poh->size;
-          DPRINTK("sisfb: Video RAM allocation succeeded: 0x%lx\n",
-                   (poh->offset + ivideo->video_vbase));
+               req->offset = poh->offset;
+               req->size = poh->size;
+               DPRINTK("sisfb: Video RAM allocation succeeded: 0x%lx\n",
+                       (poh->offset + ivideo->video_vbase));
        }
 }
 
-/* sis_free: u32 because "base" is offset inside video ram, can never be >4GB */
+void
+sis_malloc(struct sis_memreq *req)
+{
+       struct sis_video_info *ivideo = sisfb_heap->vinfo;
+
+       if(&ivideo->sisfb_heap == sisfb_heap)
+               sis_int_malloc(ivideo, req);
+       else
+               req->offset = req->size = 0;
+}
 
 void
-sis_free(u32 base)
+sis_malloc_new(struct pci_dev *pdev, struct sis_memreq *req)
+{
+       struct sis_video_info *ivideo = pci_get_drvdata(pdev);
+
+       sis_int_malloc(ivideo, req);
+}
+
+/* sis_free: u32 because "base" is offset inside video ram, can never be >4GB */
+
+static void
+sis_int_free(struct sis_video_info *ivideo, u32 base)
 {
-       struct sis_video_info *ivideo = sisfb_heap.vinfo;
-       SIS_OH *poh;
+       struct SIS_OH *poh;
 
-       if((!ivideo) || (ivideo->havenoheap)) return;
+       if((!ivideo) || (ivideo->sisfb_id != SISFB_ID) || (ivideo->havenoheap))
+               return;
 
-       poh = sisfb_poh_free((u32)base);
+       poh = sisfb_poh_free(&ivideo->sisfb_heap, base);
 
        if(poh == NULL) {
                DPRINTK("sisfb: sisfb_poh_free() failed at base 0x%x\n",
@@ -3376,9 +3565,63 @@ sis_free(u32 base)
        }
 }
 
+void
+sis_free(u32 base)
+{
+       struct sis_video_info *ivideo = sisfb_heap->vinfo;
+
+       sis_int_free(ivideo, base);
+}
+
+void
+sis_free_new(struct pci_dev *pdev, u32 base)
+{
+       struct sis_video_info *ivideo = pci_get_drvdata(pdev);
+
+       sis_int_free(ivideo, base);
+}
+
 /* --------------------- SetMode routines ------------------------- */
 
 static void
+sisfb_check_engine_and_sync(struct sis_video_info *ivideo)
+{
+       u8 cr30, cr31;
+
+       /* Check if MMIO and engines are enabled,
+        * and sync in case they are. Can't use
+        * ivideo->accel here, as this might have
+        * been changed before this is called.
+        */
+       inSISIDXREG(SISSR, IND_SIS_PCI_ADDRESS_SET, cr30);
+       inSISIDXREG(SISSR, IND_SIS_MODULE_ENABLE, cr31);
+       /* MMIO and 2D/3D engine enabled? */
+       if((cr30 & SIS_MEM_MAP_IO_ENABLE) && (cr31 & 0x42)) {
+#ifdef CONFIG_FB_SIS_300
+               if(ivideo->sisvga_engine == SIS_300_VGA) {
+                       /* Don't care about TurboQueue. It's
+                        * enough to know that the engines
+                        * are enabled
+                        */
+                       sisfb_syncaccel(ivideo);
+               }
+#endif
+#ifdef CONFIG_FB_SIS_315
+               if(ivideo->sisvga_engine == SIS_315_VGA) {
+                       /* Check that any queue mode is
+                        * enabled, and that the queue
+                        * is not in the state of "reset"
+                        */
+                       inSISIDXREG(SISSR, 0x26, cr30);
+                       if((cr30 & 0xe0) && (!(cr30 & 0x01))) {
+                               sisfb_syncaccel(ivideo);
+                       }
+               }
+#endif
+       }
+}
+
+static void
 sisfb_pre_setmode(struct sis_video_info *ivideo)
 {
        u8 cr30 = 0, cr31 = 0, cr33 = 0, cr35 = 0, cr38 = 0;
@@ -3386,6 +3629,8 @@ sisfb_pre_setmode(struct sis_video_info *ivideo)
 
        ivideo->currentvbflags &= (VB_VIDEOBRIDGE | VB_DISPTYPE_DISP2);
 
+       outSISIDXREG(SISSR, 0x05, 0x86);
+
        inSISIDXREG(SISCR, 0x31, cr31);
        cr31 &= ~0x60;
        cr31 |= 0x04;
@@ -3413,41 +3658,43 @@ sisfb_pre_setmode(struct sis_video_info *ivideo)
 
        SiS_SetEnableDstn(&ivideo->SiS_Pr, FALSE);
        SiS_SetEnableFstn(&ivideo->SiS_Pr, FALSE);
+       ivideo->curFSTN = ivideo->curDSTN = 0;
 
        switch(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {
 
           case CRT2_TV:
              cr38 &= ~0xc0;   /* Clear PAL-M / PAL-N bits */
-             if((ivideo->vbflags & TV_YPBPR) && (ivideo->vbflags & (VB_301C|VB_301LV|VB_302LV))) {
+             if((ivideo->vbflags & TV_YPBPR) && (ivideo->vbflags2 & VB2_SISYPBPRBRIDGE)) {
 #ifdef CONFIG_FB_SIS_315
-                if(ivideo->chip >= SIS_661) {
-                   cr38 |= 0x04;
-                   if(ivideo->vbflags & TV_YPBPR525P)       cr35 |= 0x20;
+                if(ivideo->chip >= SIS_661) {
+                   cr38 |= 0x04;
+                   if(ivideo->vbflags & TV_YPBPR525P)       cr35 |= 0x20;
                    else if(ivideo->vbflags & TV_YPBPR750P)  cr35 |= 0x40;
                    else if(ivideo->vbflags & TV_YPBPR1080I) cr35 |= 0x60;
                    cr30 |= SIS_SIMULTANEOUS_VIEW_ENABLE;
                    cr35 &= ~0x01;
                    ivideo->currentvbflags |= (TV_YPBPR | (ivideo->vbflags & TV_YPBPRALL));
-                } else if(ivideo->sisvga_engine == SIS_315_VGA) {
-                   cr30 |= (0x80 | SIS_SIMULTANEOUS_VIEW_ENABLE);
+                } else if(ivideo->sisvga_engine == SIS_315_VGA) {
+                   cr30 |= (0x80 | SIS_SIMULTANEOUS_VIEW_ENABLE);
                    cr38 |= 0x08;
-                   if(ivideo->vbflags & TV_YPBPR525P)       cr38 |= 0x10;
+                   if(ivideo->vbflags & TV_YPBPR525P)       cr38 |= 0x10;
                    else if(ivideo->vbflags & TV_YPBPR750P)  cr38 |= 0x20;
                    else if(ivideo->vbflags & TV_YPBPR1080I) cr38 |= 0x30;
                    cr31 &= ~0x01;
                    ivideo->currentvbflags |= (TV_YPBPR | (ivideo->vbflags & TV_YPBPRALL));
-                }
-#endif
-             } else if((ivideo->vbflags & TV_HIVISION) && (ivideo->vbflags & (VB_301|VB_301B|VB_302B))) {
-                if(ivideo->chip >= SIS_661) {
-                   cr38 |= 0x04;
-                   cr35 |= 0x60;
-                } else {
-                   cr30 |= 0x80;
-                }
+                }
+#endif
+             } else if((ivideo->vbflags & TV_HIVISION) &&
+                               (ivideo->vbflags2 & VB2_SISHIVISIONBRIDGE)) {
+                if(ivideo->chip >= SIS_661) {
+                   cr38 |= 0x04;
+                   cr35 |= 0x60;
+                } else {
+                   cr30 |= 0x80;
+                }
                 cr30 |= SIS_SIMULTANEOUS_VIEW_ENABLE;
-                cr31 |= 0x01;
-                cr35 |= 0x01;
+                cr31 |= 0x01;
+                cr35 |= 0x01;
                 ivideo->currentvbflags |= TV_HIVISION;
              } else if(ivideo->vbflags & TV_SCART) {
                 cr30 = (SIS_VB_OUTPUT_SCART | SIS_SIMULTANEOUS_VIEW_ENABLE);
@@ -3466,8 +3713,8 @@ sisfb_pre_setmode(struct sis_video_info *ivideo)
              }
              cr31 |= SIS_DRIVER_MODE;
 
-             if(ivideo->vbflags & (TV_AVIDEO|TV_SVIDEO)) {
-                if(ivideo->vbflags & TV_PAL) {
+             if(ivideo->vbflags & (TV_AVIDEO | TV_SVIDEO)) {
+                if(ivideo->vbflags & TV_PAL) {
                    cr31 |= 0x01; cr35 |= 0x01;
                    ivideo->currentvbflags |= TV_PAL;
                    if(ivideo->vbflags & TV_PALM) {
@@ -3476,14 +3723,14 @@ sisfb_pre_setmode(struct sis_video_info *ivideo)
                    } else if(ivideo->vbflags & TV_PALN) {
                       cr38 |= 0x80; cr35 |= 0x08;
                       ivideo->currentvbflags |= TV_PALN;
-                   }
-                 } else {
+                   }
+                } else {
                    cr31 &= ~0x01; cr35 &= ~0x01;
                    ivideo->currentvbflags |= TV_NTSC;
                    if(ivideo->vbflags & TV_NTSCJ) {
                       cr38 |= 0x40; cr35 |= 0x02;
                       ivideo->currentvbflags |= TV_NTSCJ;
-                   }
+                   }
                 }
              }
              break;
@@ -3493,6 +3740,8 @@ sisfb_pre_setmode(struct sis_video_info *ivideo)
              cr31 |= SIS_DRIVER_MODE;
              SiS_SetEnableDstn(&ivideo->SiS_Pr, ivideo->sisfb_dstn);
              SiS_SetEnableFstn(&ivideo->SiS_Pr, ivideo->sisfb_fstn);
+             ivideo->curFSTN = ivideo->sisfb_fstn;
+             ivideo->curDSTN = ivideo->sisfb_dstn;
              break;
 
           case CRT2_VGA:
@@ -3525,9 +3774,9 @@ sisfb_pre_setmode(struct sis_video_info *ivideo)
        }
        outSISIDXREG(SISCR, 0x31, cr31);
 
-       if(ivideo->accel) sisfb_syncaccel(ivideo);
-
        ivideo->SiS_Pr.SiS_UseOEM = ivideo->sisfb_useoem;
+
+       sisfb_check_engine_and_sync(ivideo);
 }
 
 /* Fix SR11 for 661 and later */
@@ -3535,125 +3784,129 @@ sisfb_pre_setmode(struct sis_video_info *ivideo)
 static void
 sisfb_fixup_SR11(struct sis_video_info *ivideo)
 {
-    u8  tmpreg;
-
-    if(ivideo->chip >= SIS_661) {
-       inSISIDXREG(SISSR,0x11,tmpreg);
-       if(tmpreg & 0x20) {
-          inSISIDXREG(SISSR,0x3e,tmpreg);
-         tmpreg = (tmpreg + 1) & 0xff;
-         outSISIDXREG(SISSR,0x3e,tmpreg);
-         inSISIDXREG(SISSR,0x11,tmpreg);
-       }
-       if(tmpreg & 0xf0) {
-          andSISIDXREG(SISSR,0x11,0x0f);
-       }
-    }
+       u8  tmpreg;
+
+       if(ivideo->chip >= SIS_661) {
+               inSISIDXREG(SISSR,0x11,tmpreg);
+               if(tmpreg & 0x20) {
+                       inSISIDXREG(SISSR,0x3e,tmpreg);
+                       tmpreg = (tmpreg + 1) & 0xff;
+                       outSISIDXREG(SISSR,0x3e,tmpreg);
+                       inSISIDXREG(SISSR,0x11,tmpreg);
+               }
+               if(tmpreg & 0xf0) {
+                       andSISIDXREG(SISSR,0x11,0x0f);
+               }
+       }
 }
 #endif
 
-static void sisfb_set_TVxposoffset(struct sis_video_info *ivideo, int val)
+static void
+sisfb_set_TVxposoffset(struct sis_video_info *ivideo, int val)
 {
-   if(val > 32) val = 32;
-   if(val < -32) val = -32;
-   ivideo->tvxpos = val;
+       if(val > 32) val = 32;
+       if(val < -32) val = -32;
+       ivideo->tvxpos = val;
 
-   if(ivideo->sisfblocked) return;
-   if(!ivideo->modechanged) return;
+       if(ivideo->sisfblocked) return;
+       if(!ivideo->modechanged) return;
 
-   if(ivideo->currentvbflags & CRT2_TV) {
+       if(ivideo->currentvbflags & CRT2_TV) {
 
-      if(ivideo->vbflags & VB_CHRONTEL) {
+               if(ivideo->vbflags2 & VB2_CHRONTEL) {
 
-        int x = ivideo->tvx;
+                       int x = ivideo->tvx;
 
-        switch(ivideo->chronteltype) {
-        case 1:
-            x += val;
-            if(x < 0) x = 0;
-            outSISIDXREG(SISSR,0x05,0x86);
-            SiS_SetCH700x(&ivideo->SiS_Pr, (((x & 0xff) << 8) | 0x0a));
-            SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, (((x & 0x0100) << 1) | 0x08),0xFD);
-            break;
-        case 2:
-            /* Not supported by hardware */
-            break;
-        }
-
-      } else if(ivideo->vbflags & VB_SISBRIDGE) {
-
-        u8 p2_1f,p2_20,p2_2b,p2_42,p2_43;
-        unsigned short temp;
-
-        p2_1f = ivideo->p2_1f;
-        p2_20 = ivideo->p2_20;
-        p2_2b = ivideo->p2_2b;
-        p2_42 = ivideo->p2_42;
-        p2_43 = ivideo->p2_43;
-
-        temp = p2_1f | ((p2_20 & 0xf0) << 4);
-        temp += (val * 2);
-        p2_1f = temp & 0xff;
-        p2_20 = (temp & 0xf00) >> 4;
-        p2_2b = ((p2_2b & 0x0f) + (val * 2)) & 0x0f;
-        temp = p2_43 | ((p2_42 & 0xf0) << 4);
-        temp += (val * 2);
-        p2_43 = temp & 0xff;
-        p2_42 = (temp & 0xf00) >> 4;
-        outSISIDXREG(SISPART2,0x1f,p2_1f);
-        setSISIDXREG(SISPART2,0x20,0x0F,p2_20);
-        setSISIDXREG(SISPART2,0x2b,0xF0,p2_2b);
-        setSISIDXREG(SISPART2,0x42,0x0F,p2_42);
-        outSISIDXREG(SISPART2,0x43,p2_43);
-      }
-   }
+                       switch(ivideo->chronteltype) {
+                       case 1:
+                               x += val;
+                               if(x < 0) x = 0;
+                               outSISIDXREG(SISSR,0x05,0x86);
+                               SiS_SetCH700x(&ivideo->SiS_Pr, 0x0a, (x & 0xff));
+                               SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, 0x08, ((x & 0x0100) >> 7), 0xFD);
+                               break;
+                       case 2:
+                               /* Not supported by hardware */
+                               break;
+                       }
+
+               } else if(ivideo->vbflags2 & VB2_SISBRIDGE) {
+
+                       u8 p2_1f,p2_20,p2_2b,p2_42,p2_43;
+                       unsigned short temp;
+
+                       p2_1f = ivideo->p2_1f;
+                       p2_20 = ivideo->p2_20;
+                       p2_2b = ivideo->p2_2b;
+                       p2_42 = ivideo->p2_42;
+                       p2_43 = ivideo->p2_43;
+
+                       temp = p2_1f | ((p2_20 & 0xf0) << 4);
+                       temp += (val * 2);
+                       p2_1f = temp & 0xff;
+                       p2_20 = (temp & 0xf00) >> 4;
+                       p2_2b = ((p2_2b & 0x0f) + (val * 2)) & 0x0f;
+                       temp = p2_43 | ((p2_42 & 0xf0) << 4);
+                       temp += (val * 2);
+                       p2_43 = temp & 0xff;
+                       p2_42 = (temp & 0xf00) >> 4;
+                       outSISIDXREG(SISPART2,0x1f,p2_1f);
+                       setSISIDXREG(SISPART2,0x20,0x0F,p2_20);
+                       setSISIDXREG(SISPART2,0x2b,0xF0,p2_2b);
+                       setSISIDXREG(SISPART2,0x42,0x0F,p2_42);
+                       outSISIDXREG(SISPART2,0x43,p2_43);
+               }
+       }
 }
 
-static void sisfb_set_TVyposoffset(struct sis_video_info *ivideo, int val)
+static void
+sisfb_set_TVyposoffset(struct sis_video_info *ivideo, int val)
 {
-   if(val > 32) val = 32;
-   if(val < -32) val = -32;
-   ivideo->tvypos = val;
-
-   if(ivideo->sisfblocked) return;
-   if(!ivideo->modechanged) return;
-
-   if(ivideo->currentvbflags & CRT2_TV) {
-
-      if(ivideo->vbflags & VB_CHRONTEL) {
-
-        int y = ivideo->tvy;
-
-        switch(ivideo->chronteltype) {
-        case 1:
-           y -= val;
-           if(y < 0) y = 0;
-           outSISIDXREG(SISSR,0x05,0x86);
-           SiS_SetCH700x(&ivideo->SiS_Pr, (((y & 0xff) << 8) | 0x0b));
-           SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, ((y & 0x0100) | 0x08),0xFE);
-           break;
-        case 2:
-           /* Not supported by hardware */
-           break;
-        }
-
-      } else if(ivideo->vbflags & VB_SISBRIDGE) {
-
-        char p2_01, p2_02;
-        val /= 2;
-        p2_01 = ivideo->p2_01;
-        p2_02 = ivideo->p2_02;
-
-        p2_01 += val;
-        p2_02 += val;
-        while((p2_01 <= 0) || (p2_02 <= 0)) {
-           p2_01 += 2;
-           p2_02 += 2;
-        }
-        outSISIDXREG(SISPART2,0x01,p2_01);
-        outSISIDXREG(SISPART2,0x02,p2_02);
-      }
-   }
+       if(val > 32) val = 32;
+       if(val < -32) val = -32;
+       ivideo->tvypos = val;
+
+       if(ivideo->sisfblocked) return;
+       if(!ivideo->modechanged) return;
+
+       if(ivideo->currentvbflags & CRT2_TV) {
+
+               if(ivideo->vbflags2 & VB2_CHRONTEL) {
+
+                       int y = ivideo->tvy;
+
+                       switch(ivideo->chronteltype) {
+                       case 1:
+                               y -= val;
+                               if(y < 0) y = 0;
+                               outSISIDXREG(SISSR,0x05,0x86);
+                               SiS_SetCH700x(&ivideo->SiS_Pr, 0x0b, (y & 0xff));
+                               SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, 0x08, ((y & 0x0100) >> 8), 0xFE);
+                               break;
+                       case 2:
+                               /* Not supported by hardware */
+                               break;
+                       }
+
+               } else if(ivideo->vbflags2 & VB2_SISBRIDGE) {
+
+                       char p2_01, p2_02;
+                       val /= 2;
+                       p2_01 = ivideo->p2_01;
+                       p2_02 = ivideo->p2_02;
+
+                       p2_01 += val;
+                       p2_02 += val;
+                       if(!(ivideo->currentvbflags & (TV_HIVISION | TV_YPBPR))) {
+                               while((p2_01 <= 0) || (p2_02 <= 0)) {
+                                       p2_01 += 2;
+                                       p2_02 += 2;
+                               }
+                       }
+                       outSISIDXREG(SISPART2,0x01,p2_01);
+                       outSISIDXREG(SISPART2,0x02,p2_02);
+               }
+       }
 }
 
 static void
@@ -3668,207 +3921,172 @@ sisfb_post_setmode(struct sis_video_info *ivideo)
        u8 reg1;
 #endif
 
-       outSISIDXREG(SISSR,0x05,0x86);
+       outSISIDXREG(SISSR, 0x05, 0x86);
 
 #ifdef CONFIG_FB_SIS_315
        sisfb_fixup_SR11(ivideo);
 #endif
 
        /* Now we actually HAVE changed the display mode */
-        ivideo->modechanged = 1;
+       ivideo->modechanged = 1;
 
        /* We can't switch off CRT1 if bridge is in slave mode */
-       if(ivideo->vbflags & VB_VIDEOBRIDGE) {
+       if(ivideo->vbflags2 & VB2_VIDEOBRIDGE) {
                if(sisfb_bridgeisslave(ivideo)) doit = FALSE;
-       } else ivideo->sisfb_crt1off = 0;
+       } else
+               ivideo->sisfb_crt1off = 0;
 
 #ifdef CONFIG_FB_SIS_300
        if(ivideo->sisvga_engine == SIS_300_VGA) {
-          if((ivideo->sisfb_crt1off) && (doit)) {
-               crt1isoff = TRUE;
-               reg = 0x00;
-          } else {
-               crt1isoff = FALSE;
-               reg = 0x80;
-          }
-          setSISIDXREG(SISCR, 0x17, 0x7f, reg);
+               if((ivideo->sisfb_crt1off) && (doit)) {
+                       crt1isoff = TRUE;
+                       reg = 0x00;
+               } else {
+                       crt1isoff = FALSE;
+                       reg = 0x80;
+               }
+               setSISIDXREG(SISCR, 0x17, 0x7f, reg);
        }
 #endif
 #ifdef CONFIG_FB_SIS_315
        if(ivideo->sisvga_engine == SIS_315_VGA) {
-          if((ivideo->sisfb_crt1off) && (doit)) {
-               crt1isoff = TRUE;
-               reg  = 0x40;
-               reg1 = 0xc0;
-          } else {
-               crt1isoff = FALSE;
-               reg  = 0x00;
-               reg1 = 0x00;
-
-          }
-          setSISIDXREG(SISCR, ivideo->SiS_Pr.SiS_MyCR63, ~0x40, reg);
-          setSISIDXREG(SISSR, 0x1f, ~0xc0, reg1);
+               if((ivideo->sisfb_crt1off) && (doit)) {
+                       crt1isoff = TRUE;
+                       reg  = 0x40;
+                       reg1 = 0xc0;
+               } else {
+                       crt1isoff = FALSE;
+                       reg  = 0x00;
+                       reg1 = 0x00;
+               }
+               setSISIDXREG(SISCR, ivideo->SiS_Pr.SiS_MyCR63, ~0x40, reg);
+               setSISIDXREG(SISSR, 0x1f, ~0xc0, reg1);
        }
 #endif
 
        if(crt1isoff) {
-          ivideo->currentvbflags &= ~VB_DISPTYPE_CRT1;
-          ivideo->currentvbflags |= VB_SINGLE_MODE;
+               ivideo->currentvbflags &= ~VB_DISPTYPE_CRT1;
+               ivideo->currentvbflags |= VB_SINGLE_MODE;
        } else {
-          ivideo->currentvbflags |= VB_DISPTYPE_CRT1;
-          if(ivideo->currentvbflags & VB_DISPTYPE_CRT2) {
-               ivideo->currentvbflags |= VB_MIRROR_MODE;
-          } else {
-               ivideo->currentvbflags |= VB_SINGLE_MODE;
-          }
+               ivideo->currentvbflags |= VB_DISPTYPE_CRT1;
+               if(ivideo->currentvbflags & VB_DISPTYPE_CRT2) {
+                       ivideo->currentvbflags |= VB_MIRROR_MODE;
+               } else {
+                       ivideo->currentvbflags |= VB_SINGLE_MODE;
+               }
        }
 
-        andSISIDXREG(SISSR, IND_SIS_RAMDAC_CONTROL, ~0x04);
+       andSISIDXREG(SISSR, IND_SIS_RAMDAC_CONTROL, ~0x04);
 
        if(ivideo->currentvbflags & CRT2_TV) {
-          if(ivideo->vbflags & VB_SISBRIDGE) {
-             inSISIDXREG(SISPART2,0x1f,ivideo->p2_1f);
-             inSISIDXREG(SISPART2,0x20,ivideo->p2_20);
-             inSISIDXREG(SISPART2,0x2b,ivideo->p2_2b);
-             inSISIDXREG(SISPART2,0x42,ivideo->p2_42);
-             inSISIDXREG(SISPART2,0x43,ivideo->p2_43);
-             inSISIDXREG(SISPART2,0x01,ivideo->p2_01);
-             inSISIDXREG(SISPART2,0x02,ivideo->p2_02);
-          } else if(ivideo->vbflags & VB_CHRONTEL) {
-             if(ivideo->chronteltype == 1) {
-                ivideo->tvx = SiS_GetCH700x(&ivideo->SiS_Pr, 0x0a);
-                ivideo->tvx |= (((SiS_GetCH700x(&ivideo->SiS_Pr, 0x08) & 0x02) >> 1) << 8);
-                ivideo->tvy = SiS_GetCH700x(&ivideo->SiS_Pr, 0x0b);
-                ivideo->tvy |= ((SiS_GetCH700x(&ivideo->SiS_Pr, 0x08) & 0x01) << 8);
-             }
-          }
+               if(ivideo->vbflags2 & VB2_SISBRIDGE) {
+                       inSISIDXREG(SISPART2,0x1f,ivideo->p2_1f);
+                       inSISIDXREG(SISPART2,0x20,ivideo->p2_20);
+                       inSISIDXREG(SISPART2,0x2b,ivideo->p2_2b);
+                       inSISIDXREG(SISPART2,0x42,ivideo->p2_42);
+                       inSISIDXREG(SISPART2,0x43,ivideo->p2_43);
+                       inSISIDXREG(SISPART2,0x01,ivideo->p2_01);
+                       inSISIDXREG(SISPART2,0x02,ivideo->p2_02);
+               } else if(ivideo->vbflags2 & VB2_CHRONTEL) {
+                       if(ivideo->chronteltype == 1) {
+                               ivideo->tvx = SiS_GetCH700x(&ivideo->SiS_Pr, 0x0a);
+                               ivideo->tvx |= (((SiS_GetCH700x(&ivideo->SiS_Pr, 0x08) & 0x02) >> 1) << 8);
+                               ivideo->tvy = SiS_GetCH700x(&ivideo->SiS_Pr, 0x0b);
+                               ivideo->tvy |= ((SiS_GetCH700x(&ivideo->SiS_Pr, 0x08) & 0x01) << 8);
+                       }
+               }
        }
 
        if(ivideo->tvxpos) {
-          sisfb_set_TVxposoffset(ivideo, ivideo->tvxpos);
+               sisfb_set_TVxposoffset(ivideo, ivideo->tvxpos);
        }
        if(ivideo->tvypos) {
-          sisfb_set_TVyposoffset(ivideo, ivideo->tvypos);
+               sisfb_set_TVyposoffset(ivideo, ivideo->tvypos);
        }
 
-       if((ivideo->currentvbflags & CRT2_TV) && (ivideo->vbflags & VB_301)) {  /* Set filter for SiS301 */
+       /* Eventually sync engines */
+       sisfb_check_engine_and_sync(ivideo);
 
-               unsigned char filter_tb = 0;
+       /* (Re-)Initialize chip engines */
+       if(ivideo->accel) {
+               sisfb_engine_init(ivideo);
+       } else {
+               ivideo->engineok = 0;
+       }
+}
 
-               switch (ivideo->video_width) {
-                  case 320:
-                       filter_tb = (ivideo->vbflags & TV_NTSC) ? 4 : 12;
-                       break;
-                  case 640:
-                       filter_tb = (ivideo->vbflags & TV_NTSC) ? 5 : 13;
-                       break;
-                  case 720:
-                       filter_tb = (ivideo->vbflags & TV_NTSC) ? 6 : 14;
-                       break;
-                  case 400:
-                  case 800:
-                       filter_tb = (ivideo->vbflags & TV_NTSC) ? 7 : 15;
-                       break;
-                  default:
-                       ivideo->sisfb_filter = -1;
-                       break;
-               }
+static int
+sisfb_reset_mode(struct sis_video_info *ivideo)
+{
+       if(sisfb_set_mode(ivideo, 0))
+               return 1;
 
-               orSISIDXREG(SISPART1, ivideo->CRT2_write_enable, 0x01);
+       sisfb_set_pitch(ivideo);
+       sisfb_set_base_CRT1(ivideo, ivideo->current_base);
+       sisfb_set_base_CRT2(ivideo, ivideo->current_base);
 
-               if(ivideo->vbflags & TV_NTSC) {
-
-                       andSISIDXREG(SISPART2, 0x3a, 0x1f);
-
-                       if (ivideo->vbflags & TV_SVIDEO) {
-
-                               andSISIDXREG(SISPART2, 0x30, 0xdf);
-
-                       } else if (ivideo->vbflags & TV_AVIDEO) {
-
-                               orSISIDXREG(SISPART2, 0x30, 0x20);
-
-                               switch (ivideo->video_width) {
-                               case 640:
-                                       outSISIDXREG(SISPART2, 0x35, 0xEB);
-                                       outSISIDXREG(SISPART2, 0x36, 0x04);
-                                       outSISIDXREG(SISPART2, 0x37, 0x25);
-                                       outSISIDXREG(SISPART2, 0x38, 0x18);
-                                       break;
-                               case 720:
-                                       outSISIDXREG(SISPART2, 0x35, 0xEE);
-                                       outSISIDXREG(SISPART2, 0x36, 0x0C);
-                                       outSISIDXREG(SISPART2, 0x37, 0x22);
-                                       outSISIDXREG(SISPART2, 0x38, 0x08);
-                                       break;
-                               case 400:
-                               case 800:
-                                       outSISIDXREG(SISPART2, 0x35, 0xEB);
-                                       outSISIDXREG(SISPART2, 0x36, 0x15);
-                                       outSISIDXREG(SISPART2, 0x37, 0x25);
-                                       outSISIDXREG(SISPART2, 0x38, 0xF6);
-                                       break;
-                               }
-                       }
+       return 0;
+}
+
+static void
+sisfb_handle_command(struct sis_video_info *ivideo, struct sisfb_cmd *sisfb_command)
+{
+       int mycrt1off;
 
-               } else if(ivideo->vbflags & TV_PAL) {
-
-                       andSISIDXREG(SISPART2, 0x3A, 0x1F);
-
-                       if (ivideo->vbflags & TV_SVIDEO) {
-
-                               andSISIDXREG(SISPART2, 0x30, 0xDF);
-
-                       } else if (ivideo->vbflags & TV_AVIDEO) {
-
-                               orSISIDXREG(SISPART2, 0x30, 0x20);
-
-                               switch (ivideo->video_width) {
-                               case 640:
-                                       outSISIDXREG(SISPART2, 0x35, 0xF1);
-                                       outSISIDXREG(SISPART2, 0x36, 0xF7);
-                                       outSISIDXREG(SISPART2, 0x37, 0x1F);
-                                       outSISIDXREG(SISPART2, 0x38, 0x32);
-                                       break;
-                               case 720:
-                                       outSISIDXREG(SISPART2, 0x35, 0xF3);
-                                       outSISIDXREG(SISPART2, 0x36, 0x00);
-                                       outSISIDXREG(SISPART2, 0x37, 0x1D);
-                                       outSISIDXREG(SISPART2, 0x38, 0x20);
-                                       break;
-                               case 400:
-                               case 800:
-                                       outSISIDXREG(SISPART2, 0x35, 0xFC);
-                                       outSISIDXREG(SISPART2, 0x36, 0xFB);
-                                       outSISIDXREG(SISPART2, 0x37, 0x14);
-                                       outSISIDXREG(SISPART2, 0x38, 0x2A);
-                                       break;
+       switch(sisfb_command->sisfb_cmd) {
+       case SISFB_CMD_GETVBFLAGS:
+               if(!ivideo->modechanged) {
+                       sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_EARLY;
+               } else {
+                       sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_OK;
+                       sisfb_command->sisfb_result[1] = ivideo->currentvbflags;
+                       sisfb_command->sisfb_result[2] = ivideo->vbflags2;
+               }
+               break;
+       case SISFB_CMD_SWITCHCRT1:
+               /* arg[0]: 0 = off, 1 = on, 99 = query */
+               if(!ivideo->modechanged) {
+                       sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_EARLY;
+               } else if(sisfb_command->sisfb_arg[0] == 99) {
+                       /* Query */
+                       sisfb_command->sisfb_result[1] = ivideo->sisfb_crt1off ? 0 : 1;
+                       sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_OK;
+               } else if(ivideo->sisfblocked) {
+                       sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_LOCKED;
+               } else if((!(ivideo->currentvbflags & CRT2_ENABLE)) &&
+                                       (sisfb_command->sisfb_arg[0] == 0)) {
+                       sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_NOCRT2;
+               } else {
+                       sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_OK;
+                       mycrt1off = sisfb_command->sisfb_arg[0] ? 0 : 1;
+                       if( ((ivideo->currentvbflags & VB_DISPTYPE_CRT1) && mycrt1off) ||
+                           ((!(ivideo->currentvbflags & VB_DISPTYPE_CRT1)) && !mycrt1off) ) {
+                               ivideo->sisfb_crt1off = mycrt1off;
+                               if(sisfb_reset_mode(ivideo)) {
+                                       sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_OTHER;
                                }
                        }
+                       sisfb_command->sisfb_result[1] = ivideo->sisfb_crt1off ? 0 : 1;
                }
-
-               if((ivideo->sisfb_filter >= 0) && (ivideo->sisfb_filter <= 7)) {
-                  outSISIDXREG(SISPART2,0x35,(sis_TV_filter[filter_tb].filter[ivideo->sisfb_filter][0]));
-                  outSISIDXREG(SISPART2,0x36,(sis_TV_filter[filter_tb].filter[ivideo->sisfb_filter][1]));
-                  outSISIDXREG(SISPART2,0x37,(sis_TV_filter[filter_tb].filter[ivideo->sisfb_filter][2]));
-                  outSISIDXREG(SISPART2,0x38,(sis_TV_filter[filter_tb].filter[ivideo->sisfb_filter][3]));
-               }
-         
+               break;
+       /* more to come */
+       default:
+               sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_UNKNOWN;
+               printk(KERN_ERR "sisfb: Unknown command 0x%x\n",
+                       sisfb_command->sisfb_cmd);
        }
 }
 
 #ifndef MODULE
-SISINITSTATIC int __init sisfb_setup(char *options)
+SISINITSTATIC int __init
+sisfb_setup(char *options)
 {
        char *this_opt;
-       
-       sisfb_setdefaultparms();
 
-        printk(KERN_DEBUG "sisfb: Options %s\n", options);
+       sisfb_setdefaultparms();
 
-       if(!options || !(*options)) {
+       if(!options || !(*options))
                return 0;
-       }
 
        while((this_opt = strsep(&options, ",")) != NULL) {
 
@@ -3880,9 +4098,9 @@ SISINITSTATIC int __init sisfb_setup(char *options)
                        /* Need to check crt2 type first for fstn/dstn */
                        sisfb_search_crt2type(this_opt + 14);
                } else if(!strnicmp(this_opt, "tvmode:",7)) {
-                       sisfb_search_tvstd(this_opt + 7);
-                } else if(!strnicmp(this_opt, "tvstandard:",11)) {
                        sisfb_search_tvstd(this_opt + 7);
+               } else if(!strnicmp(this_opt, "tvstandard:",11)) {
+                       sisfb_search_tvstd(this_opt + 11);
                } else if(!strnicmp(this_opt, "mode:", 5)) {
                        sisfb_search_mode(this_opt + 5, FALSE);
                } else if(!strnicmp(this_opt, "vesa:", 5)) {
@@ -3892,74 +4110,72 @@ SISINITSTATIC int __init sisfb_setup(char *options)
                        sisfb_inverse = 1;
                        /* fb_invert_cmaps(); */
                } else if(!strnicmp(this_opt, "font:", 5)) {
-                       if(strlen(this_opt + 5) < 40) {
+                       if(strlen(this_opt + 5) < 40) {
                           strncpy(sisfb_fontname, this_opt + 5, sizeof(sisfb_fontname) - 1);
                           sisfb_fontname[sizeof(sisfb_fontname) - 1] = '\0';
                        }
 #endif
                } else if(!strnicmp(this_opt, "rate:", 5)) {
                        sisfb_parm_rate = simple_strtoul(this_opt + 5, NULL, 0);
-               } else if(!strnicmp(this_opt, "filter:", 7)) {
-                       sisfb_filter = (int)simple_strtoul(this_opt + 7, NULL, 0);
                } else if(!strnicmp(this_opt, "forcecrt1:", 10)) {
                        sisfb_forcecrt1 = (int)simple_strtoul(this_opt + 10, NULL, 0);
-                } else if(!strnicmp(this_opt, "mem:",4)) {
-                       sisfb_parm_mem = simple_strtoul(this_opt + 4, NULL, 0);
+               } else if(!strnicmp(this_opt, "mem:",4)) {
+                       sisfb_parm_mem = simple_strtoul(this_opt + 4, NULL, 0);
                } else if(!strnicmp(this_opt, "pdc:", 4)) {
-                       sisfb_pdc = simple_strtoul(this_opt + 4, NULL, 0);
+                       sisfb_pdc = simple_strtoul(this_opt + 4, NULL, 0);
                } else if(!strnicmp(this_opt, "pdc1:", 5)) {
-                       sisfb_pdca = simple_strtoul(this_opt + 5, NULL, 0);
+                       sisfb_pdca = simple_strtoul(this_opt + 5, NULL, 0);
                } else if(!strnicmp(this_opt, "noaccel", 7)) {
                        sisfb_accel = 0;
                } else if(!strnicmp(this_opt, "accel", 5)) {
                        sisfb_accel = -1;
                } else if(!strnicmp(this_opt, "noypan", 6)) {
-                       sisfb_ypan = 0;
+                       sisfb_ypan = 0;
                } else if(!strnicmp(this_opt, "ypan", 4)) {
-                       sisfb_ypan = -1;
+                       sisfb_ypan = -1;
                } else if(!strnicmp(this_opt, "nomax", 5)) {
-                       sisfb_max = 0;
+                       sisfb_max = 0;
                } else if(!strnicmp(this_opt, "max", 3)) {
-                       sisfb_max = -1;
+                       sisfb_max = -1;
                } else if(!strnicmp(this_opt, "userom:", 7)) {
                        sisfb_userom = (int)simple_strtoul(this_opt + 7, NULL, 0);
                } else if(!strnicmp(this_opt, "useoem:", 7)) {
                        sisfb_useoem = (int)simple_strtoul(this_opt + 7, NULL, 0);
                } else if(!strnicmp(this_opt, "nocrt2rate", 10)) {
                        sisfb_nocrt2rate = 1;
-               } else if(!strnicmp(this_opt, "scalelcd:", 9)) {
-                       unsigned long temp = 2;
-                       temp = simple_strtoul(this_opt + 9, NULL, 0);
-                       if((temp == 0) || (temp == 1)) {
+               } else if(!strnicmp(this_opt, "scalelcd:", 9)) {
+                       unsigned long temp = 2;
+                       temp = simple_strtoul(this_opt + 9, NULL, 0);
+                       if((temp == 0) || (temp == 1)) {
                           sisfb_scalelcd = temp ^ 1;
-                       }
+                       }
                } else if(!strnicmp(this_opt, "tvxposoffset:", 13)) {
-                       int temp = 0;
-                       temp = (int)simple_strtol(this_opt + 13, NULL, 0);
-                       if((temp >= -32) && (temp <= 32)) {
+                       int temp = 0;
+                       temp = (int)simple_strtol(this_opt + 13, NULL, 0);
+                       if((temp >= -32) && (temp <= 32)) {
                           sisfb_tvxposoffset = temp;
-                       }
+                       }
                } else if(!strnicmp(this_opt, "tvyposoffset:", 13)) {
-                       int temp = 0;
-                       temp = (int)simple_strtol(this_opt + 13, NULL, 0);
-                       if((temp >= -32) && (temp <= 32)) {
+                       int temp = 0;
+                       temp = (int)simple_strtol(this_opt + 13, NULL, 0);
+                       if((temp >= -32) && (temp <= 32)) {
                           sisfb_tvyposoffset = temp;
-                       }
+                       }
                } else if(!strnicmp(this_opt, "specialtiming:", 14)) {
                        sisfb_search_specialtiming(this_opt + 14);
                } else if(!strnicmp(this_opt, "lvdshl:", 7)) {
-                       int temp = 4;
-                       temp = simple_strtoul(this_opt + 7, NULL, 0);
-                       if((temp >= 0) && (temp <= 3)) {
+                       int temp = 4;
+                       temp = simple_strtoul(this_opt + 7, NULL, 0);
+                       if((temp >= 0) && (temp <= 3)) {
                           sisfb_lvdshl = temp;
-                       }
+                       }
                } else if(this_opt[0] >= '0' && this_opt[0] <= '9') {
                        sisfb_search_mode(this_opt, TRUE);
 #if !defined(__i386__) && !defined(__x86_64__)
-               } else if(!strnicmp(this_opt, "resetcard", 9)) {
-                       sisfb_resetcard = 1;
+               } else if(!strnicmp(this_opt, "resetcard", 9)) {
+                       sisfb_resetcard = 1;
                } else if(!strnicmp(this_opt, "videoram:", 9)) {
-                       sisfb_videoram = simple_strtoul(this_opt + 9, NULL, 0);
+                       sisfb_videoram = simple_strtoul(this_opt + 9, NULL, 0);
 #endif
                } else {
                        printk(KERN_INFO "sisfb: Invalid option %s\n", this_opt);
@@ -3967,819 +4183,1706 @@ SISINITSTATIC int __init sisfb_setup(char *options)
 
        }
 
+       return 0;
+}
+#endif
+
+static int __devinit
+sisfb_check_rom(SIS_IOTYPE1 *rom_base, struct sis_video_info *ivideo)
+{
+       SIS_IOTYPE1 *rom;
+       int romptr;
+
+       if((readb(rom_base) != 0x55) || (readb(rom_base + 1) != 0xaa))
+               return 0;
+
+       romptr = (readb(rom_base + 0x18) | (readb(rom_base + 0x19) << 8));
+       if(romptr > (0x10000 - 8))
+               return 0;
+
+       rom = rom_base + romptr;
+
+       if((readb(rom)     != 'P') || (readb(rom + 1) != 'C') ||
+          (readb(rom + 2) != 'I') || (readb(rom + 3) != 'R'))
+               return 0;
+
+       if((readb(rom + 4) | (readb(rom + 5) << 8)) != ivideo->chip_vendor)
+               return 0;
+
+       if((readb(rom + 6) | (readb(rom + 7) << 8)) != ivideo->chip_id)
+               return 0;
+
+       return 1;
+}
+
+static unsigned char * __devinit
+sisfb_find_rom(struct pci_dev *pdev)
+{
+       struct sis_video_info *ivideo = pci_get_drvdata(pdev);
+       SIS_IOTYPE1 *rom_base;
+       unsigned char *myrombase = NULL;
+       u32 temp;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11)
+       size_t romsize;
+
+       /* First, try the official pci ROM functions (except
+        * on integrated chipsets which have no ROM).
+        */
+
+       if(!ivideo->nbridge) {
+
+               if((rom_base = pci_map_rom(pdev, &romsize))) {
+
+                       if(sisfb_check_rom(rom_base, ivideo)) {
+
+                               if((myrombase = vmalloc(65536))) {
+
+                                       /* Work around bug in pci/rom.c: Folks forgot to check
+                                        * whether the size retrieved from the BIOS image eventually
+                                        * is larger than the mapped size
+                                        */
+                                       if(pci_resource_len(pdev, PCI_ROM_RESOURCE) < romsize)
+                                               romsize = pci_resource_len(pdev, PCI_ROM_RESOURCE);
+
+                                       memcpy_fromio(myrombase, rom_base,
+                                                       (romsize > 65536) ? 65536 : romsize);
+                               }
+                       }
+                       pci_unmap_rom(pdev, rom_base);
+               }
+       }
+
+       if(myrombase) return myrombase;
+#endif
+
+       /* Otherwise do it the conventional way. */
+
+#if defined(__i386__) || defined(__x86_64__)
+
+       for(temp = 0x000c0000; temp < 0x000f0000; temp += 0x00001000) {
+
+               rom_base = ioremap(temp, 65536);
+               if(!rom_base)
+                       continue;
+
+               if(!sisfb_check_rom(rom_base, ivideo)) {
+                       iounmap(rom_base);
+                       continue;
+               }
+
+               if((myrombase = vmalloc(65536)))
+                       memcpy_fromio(myrombase, rom_base, 65536);
+
+               iounmap(rom_base);
+               break;
+
+        }
+
+#else
+
+       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);
+
+       rom_base = ioremap(ivideo->video_base, 65536);
+       if(rom_base) {
+               if(sisfb_check_rom(rom_base, ivideo)) {
+                       if((myrombase = vmalloc(65536)))
+                               memcpy_fromio(myrombase, rom_base, 65536);
+               }
+               iounmap(rom_base);
+       }
+
+       pci_write_config_dword(pdev, PCI_ROM_ADDRESS, temp);
+
+#endif
+
+       return myrombase;
+}
+
+static void __devinit
+sisfb_post_map_vram(struct sis_video_info *ivideo, unsigned int *mapsize,
+                       unsigned int min)
+{
+       ivideo->video_vbase = ioremap(ivideo->video_base, (*mapsize));
+
+       if(!ivideo->video_vbase) {
+               printk(KERN_ERR
+                       "sisfb: Unable to map maximum video RAM for size detection\n");
+               (*mapsize) >>= 1;
+               while((!(ivideo->video_vbase = ioremap(ivideo->video_base, (*mapsize))))) {
+                       (*mapsize) >>= 1;
+                       if((*mapsize) < (min << 20))
+                               break;
+               }
+               if(ivideo->video_vbase) {
+                       printk(KERN_ERR
+                               "sisfb: Video RAM size detection limited to %dMB\n",
+                               (int)((*mapsize) >> 20));
+               }
+       }
+}
+
+#ifdef CONFIG_FB_SIS_300
+static int __devinit
+sisfb_post_300_buswidth(struct sis_video_info *ivideo)
+{
+       SIS_IOTYPE1 *FBAddress = ivideo->video_vbase;
+       unsigned short temp;
+       unsigned char reg;
+       int i, j;
+
+       andSISIDXREG(SISSR, 0x15, 0xFB);
+       orSISIDXREG(SISSR, 0x15, 0x04);
+       outSISIDXREG(SISSR, 0x13, 0x00);
+       outSISIDXREG(SISSR, 0x14, 0xBF);
+
+       for(i = 0; i < 2; i++) {
+               temp = 0x1234;
+               for(j = 0; j < 4; j++) {
+                       writew(temp, FBAddress);
+                       if(readw(FBAddress) == temp)
+                               break;
+                       orSISIDXREG(SISSR, 0x3c, 0x01);
+                       inSISIDXREG(SISSR, 0x05, reg);
+                       inSISIDXREG(SISSR, 0x05, reg);
+                       andSISIDXREG(SISSR, 0x3c, 0xfe);
+                       inSISIDXREG(SISSR, 0x05, reg);
+                       inSISIDXREG(SISSR, 0x05, reg);
+                       temp++;
+               }
+       }
+
+       writel(0x01234567L, FBAddress);
+       writel(0x456789ABL, (FBAddress + 4));
+       writel(0x89ABCDEFL, (FBAddress + 8));
+       writel(0xCDEF0123L, (FBAddress + 12));
+
+       inSISIDXREG(SISSR, 0x3b, reg);
+       if(reg & 0x01) {
+               if(readl((FBAddress + 12)) == 0xCDEF0123L)
+                       return 4;       /* Channel A 128bit */
+       }
+
+       if(readl((FBAddress + 4)) == 0x456789ABL)
+               return 2;               /* Channel B 64bit */
+
+       return 1;                       /* 32bit */
+}
+
+static int __devinit
+sisfb_post_300_rwtest(struct sis_video_info *ivideo, int iteration, int buswidth,
+                       int PseudoRankCapacity, int PseudoAdrPinCount,
+                       unsigned int mapsize)
+{
+       SIS_IOTYPE1 *FBAddr = ivideo->video_vbase;
+       unsigned short sr14;
+       unsigned int k, RankCapacity, PageCapacity, BankNumHigh, BankNumMid;
+       unsigned int PhysicalAdrOtherPage, PhysicalAdrHigh, PhysicalAdrHalfPage;
+       static const unsigned short SiS_DRAMType[17][5] = {
+               {0x0C,0x0A,0x02,0x40,0x39},
+               {0x0D,0x0A,0x01,0x40,0x48},
+               {0x0C,0x09,0x02,0x20,0x35},
+               {0x0D,0x09,0x01,0x20,0x44},
+               {0x0C,0x08,0x02,0x10,0x31},
+               {0x0D,0x08,0x01,0x10,0x40},
+               {0x0C,0x0A,0x01,0x20,0x34},
+               {0x0C,0x09,0x01,0x08,0x32},
+               {0x0B,0x08,0x02,0x08,0x21},
+               {0x0C,0x08,0x01,0x08,0x30},
+               {0x0A,0x08,0x02,0x04,0x11},
+               {0x0B,0x0A,0x01,0x10,0x28},
+               {0x09,0x08,0x02,0x02,0x01},
+               {0x0B,0x09,0x01,0x08,0x24},
+               {0x0B,0x08,0x01,0x04,0x20},
+               {0x0A,0x08,0x01,0x02,0x10},
+               {0x09,0x08,0x01,0x01,0x00}
+       };
+
+        for(k = 0; k <= 16; k++) {
+
+               RankCapacity = buswidth * SiS_DRAMType[k][3];
+
+               if(RankCapacity != PseudoRankCapacity)
+                       continue;
+
+               if((SiS_DRAMType[k][2] + SiS_DRAMType[k][0]) > PseudoAdrPinCount)
+                       continue;
+
+               BankNumHigh = RankCapacity * 16 * iteration - 1;
+               if(iteration == 3) {             /* Rank No */
+                       BankNumMid  = RankCapacity * 16 - 1;
+               } else {
+                       BankNumMid  = RankCapacity * 16 * iteration / 2 - 1;
+               }
+
+               PageCapacity = (1 << SiS_DRAMType[k][1]) * buswidth * 4;
+               PhysicalAdrHigh = BankNumHigh;
+               PhysicalAdrHalfPage = (PageCapacity / 2 + PhysicalAdrHigh) % PageCapacity;
+               PhysicalAdrOtherPage = PageCapacity * SiS_DRAMType[k][2] + PhysicalAdrHigh;
+
+               andSISIDXREG(SISSR, 0x15, 0xFB); /* Test */
+               orSISIDXREG(SISSR, 0x15, 0x04);  /* Test */
+               sr14 = (SiS_DRAMType[k][3] * buswidth) - 1;
+               if(buswidth == 4)      sr14 |= 0x80;
+               else if(buswidth == 2) sr14 |= 0x40;
+               outSISIDXREG(SISSR, 0x13, SiS_DRAMType[k][4]);
+               outSISIDXREG(SISSR, 0x14, sr14);
+
+               BankNumHigh <<= 16;
+               BankNumMid <<= 16;
+
+               if((BankNumHigh + PhysicalAdrHigh      >= mapsize) ||
+                  (BankNumMid  + PhysicalAdrHigh      >= mapsize) ||
+                  (BankNumHigh + PhysicalAdrHalfPage  >= mapsize) ||
+                  (BankNumHigh + PhysicalAdrOtherPage >= mapsize))
+                       continue;
+
+               /* Write data */
+               writew(((unsigned short)PhysicalAdrHigh),
+                               (FBAddr + BankNumHigh + PhysicalAdrHigh));
+               writew(((unsigned short)BankNumMid),
+                               (FBAddr + BankNumMid  + PhysicalAdrHigh));
+               writew(((unsigned short)PhysicalAdrHalfPage),
+                               (FBAddr + BankNumHigh + PhysicalAdrHalfPage));
+               writew(((unsigned short)PhysicalAdrOtherPage),
+                               (FBAddr + BankNumHigh + PhysicalAdrOtherPage));
+
+               /* Read data */
+               if(readw(FBAddr + BankNumHigh + PhysicalAdrHigh) == PhysicalAdrHigh)
+                       return 1;
+       }
+
+       return 0;
+}
+
+static void __devinit
+sisfb_post_300_ramsize(struct pci_dev *pdev, unsigned int mapsize)
+{
+       struct  sis_video_info *ivideo = pci_get_drvdata(pdev);
+       int     i, j, buswidth;
+       int     PseudoRankCapacity, PseudoAdrPinCount;
+
+       buswidth = sisfb_post_300_buswidth(ivideo);
+
+       for(i = 6; i >= 0; i--) {
+               PseudoRankCapacity = 1 << i;
+               for(j = 4; j >= 1; j--) {
+                       PseudoAdrPinCount = 15 - j;
+                       if((PseudoRankCapacity * j) <= 64) {
+                               if(sisfb_post_300_rwtest(ivideo,
+                                               j,
+                                               buswidth,
+                                               PseudoRankCapacity,
+                                               PseudoAdrPinCount,
+                                               mapsize))
+                                       return;
+                       }
+               }
+       }
+}
+
+static void __devinit
+sisfb_post_sis300(struct pci_dev *pdev)
+{
+       struct sis_video_info *ivideo = pci_get_drvdata(pdev);
+       unsigned char *bios = ivideo->SiS_Pr.VirtualRomBase;
+       u8  reg, v1, v2, v3, v4, v5, v6, v7, v8;
+       u16 index, rindex, memtype = 0;
+       unsigned int mapsize;
+
+       if(!ivideo->SiS_Pr.UseROM)
+               bios = NULL;
+
+       outSISIDXREG(SISSR, 0x05, 0x86);
+
+       if(bios) {
+               if(bios[0x52] & 0x80) {
+                       memtype = bios[0x52];
+               } else {
+                       inSISIDXREG(SISSR, 0x3a, memtype);
+               }
+               memtype &= 0x07;
+       }
+
+       v3 = 0x80; v6 = 0x80;
+       if(ivideo->revision_id <= 0x13) {
+               v1 = 0x44; v2 = 0x42;
+               v4 = 0x44; v5 = 0x42;
+       } else {
+               v1 = 0x68; v2 = 0x43; /* Assume 125Mhz MCLK */
+               v4 = 0x68; v5 = 0x43; /* Assume 125Mhz ECLK */
+               if(bios) {
+                       index = memtype * 5;
+                       rindex = index + 0x54;
+                       v1 = bios[rindex++];
+                       v2 = bios[rindex++];
+                       v3 = bios[rindex++];
+                       rindex = index + 0x7c;
+                       v4 = bios[rindex++];
+                       v5 = bios[rindex++];
+                       v6 = bios[rindex++];
+               }
+       }
+       outSISIDXREG(SISSR, 0x28, v1);
+       outSISIDXREG(SISSR, 0x29, v2);
+       outSISIDXREG(SISSR, 0x2a, v3);
+       outSISIDXREG(SISSR, 0x2e, v4);
+       outSISIDXREG(SISSR, 0x2f, v5);
+       outSISIDXREG(SISSR, 0x30, v6);
+
+       v1 = 0x10;
+       if(bios)
+               v1 = bios[0xa4];
+       outSISIDXREG(SISSR, 0x07, v1);       /* DAC speed */
+
+       outSISIDXREG(SISSR, 0x11, 0x0f);     /* DDC, power save */
+
+       v1 = 0x01; v2 = 0x43; v3 = 0x1e; v4 = 0x2a;
+       v5 = 0x06; v6 = 0x00; v7 = 0x00; v8 = 0x00;
+       if(bios) {
+               memtype += 0xa5;
+               v1 = bios[memtype];
+               v2 = bios[memtype + 8];
+               v3 = bios[memtype + 16];
+               v4 = bios[memtype + 24];
+               v5 = bios[memtype + 32];
+               v6 = bios[memtype + 40];
+               v7 = bios[memtype + 48];
+               v8 = bios[memtype + 56];
+       }
+       if(ivideo->revision_id >= 0x80)
+               v3 &= 0xfd;
+       outSISIDXREG(SISSR, 0x15, v1);       /* Ram type (assuming 0, BIOS 0xa5 step 8) */
+       outSISIDXREG(SISSR, 0x16, v2);
+       outSISIDXREG(SISSR, 0x17, v3);
+       outSISIDXREG(SISSR, 0x18, v4);
+       outSISIDXREG(SISSR, 0x19, v5);
+       outSISIDXREG(SISSR, 0x1a, v6);
+       outSISIDXREG(SISSR, 0x1b, v7);
+       outSISIDXREG(SISSR, 0x1c, v8);     /* ---- */
+       andSISIDXREG(SISSR, 0x15 ,0xfb);
+       orSISIDXREG(SISSR, 0x15, 0x04);
+       if(bios) {
+               if(bios[0x53] & 0x02) {
+                       orSISIDXREG(SISSR, 0x19, 0x20);
+               }
+       }
+       v1 = 0x04;                         /* DAC pedestal (BIOS 0xe5) */
+       if(ivideo->revision_id >= 0x80)
+               v1 |= 0x01;
+       outSISIDXREG(SISSR, 0x1f, v1);
+       outSISIDXREG(SISSR, 0x20, 0xa4);     /* linear & relocated io & disable a0000 */
+       v1 = 0xf6; v2 = 0x0d; v3 = 0x00;
+       if(bios) {
+               v1 = bios[0xe8];
+               v2 = bios[0xe9];
+               v3 = bios[0xea];
+       }
+       outSISIDXREG(SISSR, 0x23, v1);
+       outSISIDXREG(SISSR, 0x24, v2);
+       outSISIDXREG(SISSR, 0x25, v3);
+       outSISIDXREG(SISSR, 0x21, 0x84);
+       outSISIDXREG(SISSR, 0x22, 0x00);
+       outSISIDXREG(SISCR, 0x37, 0x00);
+       orSISIDXREG(SISPART1, 0x24, 0x01);   /* unlock crt2 */
+       outSISIDXREG(SISPART1, 0x00, 0x00);
+       v1 = 0x40; v2 = 0x11;
+       if(bios) {
+               v1 = bios[0xec];
+               v2 = bios[0xeb];
+       }
+       outSISIDXREG(SISPART1, 0x02, v1);
+
+       if(ivideo->revision_id >= 0x80)
+               v2 &= ~0x01;
+
+       inSISIDXREG(SISPART4, 0x00, reg);
+       if((reg == 1) || (reg == 2)) {
+               outSISIDXREG(SISCR, 0x37, 0x02);
+               outSISIDXREG(SISPART2, 0x00, 0x1c);
+               v4 = 0x00; v5 = 0x00; v6 = 0x10;
+               if(ivideo->SiS_Pr.UseROM) {
+                       v4 = bios[0xf5];
+                       v5 = bios[0xf6];
+                       v6 = bios[0xf7];
+               }
+               outSISIDXREG(SISPART4, 0x0d, v4);
+               outSISIDXREG(SISPART4, 0x0e, v5);
+               outSISIDXREG(SISPART4, 0x10, v6);
+               outSISIDXREG(SISPART4, 0x0f, 0x3f);
+               inSISIDXREG(SISPART4, 0x01, reg);
+               if(reg >= 0xb0) {
+                       inSISIDXREG(SISPART4, 0x23, reg);
+                       reg &= 0x20;
+                       reg <<= 1;
+                       outSISIDXREG(SISPART4, 0x23, reg);
+               }
+       } else {
+               v2 &= ~0x10;
+       }
+       outSISIDXREG(SISSR, 0x32, v2);
+
+       andSISIDXREG(SISPART1, 0x24, 0xfe);  /* Lock CRT2 */
+
+       inSISIDXREG(SISSR, 0x16, reg);
+       reg &= 0xc3;
+       outSISIDXREG(SISCR, 0x35, reg);
+       outSISIDXREG(SISCR, 0x83, 0x00);
+#if !defined(__i386__) && !defined(__x86_64__)
+       if(sisfb_videoram) {
+               outSISIDXREG(SISSR, 0x13, 0x28);  /* ? */
+               reg = ((sisfb_videoram >> 10) - 1) | 0x40;
+               outSISIDXREG(SISSR, 0x14, reg);
+       } else {
+#endif
+               /* Need to map max FB size for finding out about RAM size */
+               mapsize = 64 << 20;
+               sisfb_post_map_vram(ivideo, &mapsize, 4);
+
+               if(ivideo->video_vbase) {
+                       sisfb_post_300_ramsize(pdev, mapsize);
+                       iounmap(ivideo->video_vbase);
+               } else {
+                       printk(KERN_DEBUG
+                               "sisfb: Failed to map memory for size detection, assuming 8MB\n");
+                       outSISIDXREG(SISSR, 0x13, 0x28);  /* ? */
+                       outSISIDXREG(SISSR, 0x14, 0x47);  /* 8MB, 64bit default */
+               }
+#if !defined(__i386__) && !defined(__x86_64__)
+       }
+#endif
+       if(bios) {
+               v1 = bios[0xe6];
+               v2 = bios[0xe7];
+       } else {
+               inSISIDXREG(SISSR, 0x3a, reg);
+               if((reg & 0x30) == 0x30) {
+                       v1 = 0x04; /* PCI */
+                       v2 = 0x92;
+               } else {
+                       v1 = 0x14; /* AGP */
+                       v2 = 0xb2;
+               }
+       }
+       outSISIDXREG(SISSR, 0x21, v1);
+       outSISIDXREG(SISSR, 0x22, v2);
+
+       /* Sense CRT1 */
+       sisfb_sense_crt1(ivideo);
+
+       /* Set default mode, don't clear screen */
+       ivideo->SiS_Pr.SiS_UseOEM = FALSE;
+       SiS_SetEnableDstn(&ivideo->SiS_Pr, FALSE);
+       SiS_SetEnableFstn(&ivideo->SiS_Pr, FALSE);
+       ivideo->curFSTN = ivideo->curDSTN = 0;
+       ivideo->SiS_Pr.VideoMemorySize = 8 << 20;
+       SiSSetMode(&ivideo->SiS_Pr, 0x2e | 0x80);
+
+       outSISIDXREG(SISSR, 0x05, 0x86);
+
+       /* Display off */
+       orSISIDXREG(SISSR, 0x01, 0x20);
+
+       /* Save mode number in CR34 */
+       outSISIDXREG(SISCR, 0x34, 0x2e);
+
+       /* Let everyone know what the current mode is */
+       ivideo->modeprechange = 0x2e;
+}
+#endif
+
+#ifdef CONFIG_FB_SIS_315
+#if 0
+static void __devinit
+sisfb_post_sis315330(struct pci_dev *pdev)
+{
+       /* TODO */
+}
+#endif
+
+static void __devinit
+sisfb_post_xgi_delay(struct sis_video_info *ivideo, int delay)
+{
+       unsigned int i;
+       u8 reg;
+
+       for(i = 0; i <= (delay * 10 * 36); i++) {
+               inSISIDXREG(SISSR, 0x05, reg);
+               reg++;
+       }
+}
+
+static int __devinit
+sisfb_find_host_bridge(struct sis_video_info *ivideo, struct pci_dev *mypdev,
+                               unsigned short pcivendor)
+{
+       struct pci_dev *pdev = NULL;
+       unsigned short temp;
+       int ret = 0;
+
+       while((pdev = SIS_PCI_GET_CLASS(PCI_CLASS_BRIDGE_HOST, pdev))) {
+               temp = pdev->vendor;
+               SIS_PCI_PUT_DEVICE(pdev);
+               if(temp == pcivendor) {
+                       ret = 1;
+                       break;
+               }
+       }
+
+       return ret;
+}
+
+static int __devinit
+sisfb_post_xgi_rwtest(struct sis_video_info *ivideo, int starta,
+                       unsigned int enda, unsigned int mapsize)
+{
+       unsigned int pos;
+       int i;
+
+       writel(0, ivideo->video_vbase);
+
+       for(i = starta; i <= enda; i++) {
+               pos = 1 << i;
+               if(pos < mapsize)
+                       writel(pos, ivideo->video_vbase + pos);
+       }
+
+       sisfb_post_xgi_delay(ivideo, 150);
+
+       if(readl(ivideo->video_vbase) != 0)
+               return 0;
+
+       for(i = starta; i <= enda; i++) {
+               pos = 1 << i;
+               if(pos < mapsize) {
+                       if(readl(ivideo->video_vbase + pos) != pos)
+                               return 0;
+               } else
+                       return 0;
+       }
+
+       return 1;
+}
+
+static void __devinit
+sisfb_post_xgi_ramsize(struct sis_video_info *ivideo)
+{
+       unsigned int buswidth, ranksize, channelab, mapsize;
+       int i, j, k, l;
+       u8 reg, sr14;
+       static const u8 dramsr13[12 * 5] = {
+               0x02, 0x0e, 0x0b, 0x80, 0x5d,
+               0x02, 0x0e, 0x0a, 0x40, 0x59,
+               0x02, 0x0d, 0x0b, 0x40, 0x4d,
+               0x02, 0x0e, 0x09, 0x20, 0x55,
+               0x02, 0x0d, 0x0a, 0x20, 0x49,
+               0x02, 0x0c, 0x0b, 0x20, 0x3d,
+               0x02, 0x0e, 0x08, 0x10, 0x51,
+               0x02, 0x0d, 0x09, 0x10, 0x45,
+               0x02, 0x0c, 0x0a, 0x10, 0x39,
+               0x02, 0x0d, 0x08, 0x08, 0x41,
+               0x02, 0x0c, 0x09, 0x08, 0x35,
+               0x02, 0x0c, 0x08, 0x04, 0x31
+       };
+       static const u8 dramsr13_4[4 * 5] = {
+               0x02, 0x0d, 0x09, 0x40, 0x45,
+               0x02, 0x0c, 0x09, 0x20, 0x35,
+               0x02, 0x0c, 0x08, 0x10, 0x31,
+               0x02, 0x0b, 0x08, 0x08, 0x21
+       };
+
+       /* Enable linear mode, disable 0xa0000 address decoding */
+       /* We disable a0000 address decoding, because
+        * - if running on x86, if the card is disabled, it means
+        *   that another card is in the system. We don't want
+        *   to interphere with that primary card's textmode.
+        * - if running on non-x86, there usually is no VGA window
+        *   at a0000.
+        */
+       orSISIDXREG(SISSR, 0x20, (0x80 | 0x04));
+
+       /* Need to map max FB size for finding out about RAM size */
+       mapsize = 256 << 20;
+       sisfb_post_map_vram(ivideo, &mapsize, 32);
+
+       if(!ivideo->video_vbase) {
+               printk(KERN_ERR "sisfb: Unable to detect RAM size. Setting default.\n");
+               outSISIDXREG(SISSR, 0x13, 0x35);
+               outSISIDXREG(SISSR, 0x14, 0x41);
+               /* TODO */
+               return;
+       }
+
+       /* Non-interleaving */
+       outSISIDXREG(SISSR, 0x15, 0x00);
+       /* No tiling */
+       outSISIDXREG(SISSR, 0x1c, 0x00);
+
+       if(ivideo->chip == XGI_20) {
+
+               channelab = 1;
+               inSISIDXREG(SISCR, 0x97, reg);
+               if(!(reg & 0x01)) {     /* Single 32/16 */
+                       buswidth = 32;
+                       outSISIDXREG(SISSR, 0x13, 0xb1);
+                       outSISIDXREG(SISSR, 0x14, 0x52);
+                       sisfb_post_xgi_delay(ivideo, 1);
+                       sr14 = 0x02;
+                       if(sisfb_post_xgi_rwtest(ivideo, 23, 24, mapsize))
+                               goto bail_out;
+
+                       outSISIDXREG(SISSR, 0x13, 0x31);
+                       outSISIDXREG(SISSR, 0x14, 0x42);
+                       sisfb_post_xgi_delay(ivideo, 1);
+                       if(sisfb_post_xgi_rwtest(ivideo, 23, 23, mapsize))
+                               goto bail_out;
+
+                       buswidth = 16;
+                       outSISIDXREG(SISSR, 0x13, 0xb1);
+                       outSISIDXREG(SISSR, 0x14, 0x41);
+                       sisfb_post_xgi_delay(ivideo, 1);
+                       sr14 = 0x01;
+                       if(sisfb_post_xgi_rwtest(ivideo, 22, 23, mapsize))
+                               goto bail_out;
+                       else
+                               outSISIDXREG(SISSR, 0x13, 0x31);
+               } else {                /* Dual 16/8 */
+                       buswidth = 16;
+                       outSISIDXREG(SISSR, 0x13, 0xb1);
+                       outSISIDXREG(SISSR, 0x14, 0x41);
+                       sisfb_post_xgi_delay(ivideo, 1);
+                       sr14 = 0x01;
+                       if(sisfb_post_xgi_rwtest(ivideo, 22, 23, mapsize))
+                               goto bail_out;
+
+                       outSISIDXREG(SISSR, 0x13, 0x31);
+                       outSISIDXREG(SISSR, 0x14, 0x31);
+                       sisfb_post_xgi_delay(ivideo, 1);
+                       if(sisfb_post_xgi_rwtest(ivideo, 22, 22, mapsize))
+                               goto bail_out;
+
+                       buswidth = 8;
+                       outSISIDXREG(SISSR, 0x13, 0xb1);
+                       outSISIDXREG(SISSR, 0x14, 0x30);
+                       sisfb_post_xgi_delay(ivideo, 1);
+                       sr14 = 0x00;
+                       if(sisfb_post_xgi_rwtest(ivideo, 21, 22, mapsize))
+                               goto bail_out;
+                       else
+                               outSISIDXREG(SISSR, 0x13, 0x31);
+               }
+
+       } else {        /* XGI_40 */
+
+               inSISIDXREG(SISCR, 0x97, reg);
+               if(!(reg & 0x10)) {
+                       inSISIDXREG(SISSR, 0x39, reg);
+                       reg >>= 1;
+               }
+
+               if(reg & 0x01) {        /* DDRII */
+                       buswidth = 32;
+                       if(ivideo->revision_id == 2) {
+                               channelab = 2;
+                               outSISIDXREG(SISSR, 0x13, 0xa1);
+                               outSISIDXREG(SISSR, 0x14, 0x44);
+                               sr14 = 0x04;
+                               sisfb_post_xgi_delay(ivideo, 1);
+                               if(sisfb_post_xgi_rwtest(ivideo, 23, 24, mapsize))
+                                       goto bail_out;
+
+                               outSISIDXREG(SISSR, 0x13, 0x21);
+                               outSISIDXREG(SISSR, 0x14, 0x34);
+                               if(sisfb_post_xgi_rwtest(ivideo, 22, 23, mapsize))
+                                       goto bail_out;
+
+                               channelab = 1;
+                               outSISIDXREG(SISSR, 0x13, 0xa1);
+                               outSISIDXREG(SISSR, 0x14, 0x40);
+                               sr14 = 0x00;
+                               if(sisfb_post_xgi_rwtest(ivideo, 22, 23, mapsize))
+                                       goto bail_out;
+
+                               outSISIDXREG(SISSR, 0x13, 0x21);
+                               outSISIDXREG(SISSR, 0x14, 0x30);
+                       } else {
+                               channelab = 3;
+                               outSISIDXREG(SISSR, 0x13, 0xa1);
+                               outSISIDXREG(SISSR, 0x14, 0x4c);
+                               sr14 = 0x0c;
+                               sisfb_post_xgi_delay(ivideo, 1);
+                               if(sisfb_post_xgi_rwtest(ivideo, 23, 25, mapsize))
+                                       goto bail_out;
+
+                               channelab = 2;
+                               outSISIDXREG(SISSR, 0x14, 0x48);
+                               sisfb_post_xgi_delay(ivideo, 1);
+                               sr14 = 0x08;
+                               if(sisfb_post_xgi_rwtest(ivideo, 23, 24, mapsize))
+                                       goto bail_out;
+
+                               outSISIDXREG(SISSR, 0x13, 0x21);
+                               outSISIDXREG(SISSR, 0x14, 0x3c);
+                               sr14 = 0x0c;
+
+                               if(sisfb_post_xgi_rwtest(ivideo, 23, 24, mapsize)) {
+                                       channelab = 3;
+                               } else {
+                                       channelab = 2;
+                                       outSISIDXREG(SISSR, 0x14, 0x38);
+                                       sr14 = 0x08;
+                               }
+                       }
+                       sisfb_post_xgi_delay(ivideo, 1);
+
+               } else {        /* DDR */
+
+                       buswidth = 64;
+                       if(ivideo->revision_id == 2) {
+                               channelab = 1;
+                               outSISIDXREG(SISSR, 0x13, 0xa1);
+                               outSISIDXREG(SISSR, 0x14, 0x52);
+                               sisfb_post_xgi_delay(ivideo, 1);
+                               sr14 = 0x02;
+                               if(sisfb_post_xgi_rwtest(ivideo, 23, 24, mapsize))
+                                       goto bail_out;
+
+                               outSISIDXREG(SISSR, 0x13, 0x21);
+                               outSISIDXREG(SISSR, 0x14, 0x42);
+                       } else {
+                               channelab = 2;
+                               outSISIDXREG(SISSR, 0x13, 0xa1);
+                               outSISIDXREG(SISSR, 0x14, 0x5a);
+                               sisfb_post_xgi_delay(ivideo, 1);
+                               sr14 = 0x0a;
+                               if(sisfb_post_xgi_rwtest(ivideo, 24, 25, mapsize))
+                                       goto bail_out;
+
+                               outSISIDXREG(SISSR, 0x13, 0x21);
+                               outSISIDXREG(SISSR, 0x14, 0x4a);
+                       }
+                       sisfb_post_xgi_delay(ivideo, 1);
+
+               }
+       }
+
+bail_out:
+       setSISIDXREG(SISSR, 0x14, 0xf0, sr14);
+       sisfb_post_xgi_delay(ivideo, 1);
+
+       j = (ivideo->chip == XGI_20) ? 5 : 9;
+       k = (ivideo->chip == XGI_20) ? 12 : 4;
+
+       for(i = 0; i < k; i++) {
+
+               reg = (ivideo->chip == XGI_20) ?
+                               dramsr13[(i * 5) + 4] : dramsr13_4[(i * 5) + 4];
+               setSISIDXREG(SISSR, 0x13, 0x80, reg);
+               sisfb_post_xgi_delay(ivideo, 50);
+
+               ranksize = (ivideo->chip == XGI_20) ?
+                               dramsr13[(i * 5) + 3] : dramsr13_4[(i * 5) + 3];
+
+               inSISIDXREG(SISSR, 0x13, reg);
+               if(reg & 0x80) ranksize <<= 1;
+
+               if(ivideo->chip == XGI_20) {
+                       if(buswidth == 16)      ranksize <<= 1;
+                       else if(buswidth == 32) ranksize <<= 2;
+               } else {
+                       if(buswidth == 64)      ranksize <<= 1;
+               }
+
+               reg = 0;
+               l = channelab;
+               if(l == 3) l = 4;
+               if((ranksize * l) <= 256) {
+                       while((ranksize >>= 1)) reg += 0x10;
+               }
+
+               if(!reg) continue;
+
+               setSISIDXREG(SISSR, 0x14, 0x0f, (reg & 0xf0));
+               sisfb_post_xgi_delay(ivideo, 1);
+
+               if(sisfb_post_xgi_rwtest(ivideo, j, ((reg >> 4) + channelab - 2 + 20), mapsize))
+                       break;
+       }
+
+       iounmap(ivideo->video_vbase);
+}
 
+static void __devinit
+sisfb_post_xgi_setclocks(struct sis_video_info *ivideo, u8 regb)
+{
+       u8 v1, v2, v3;
+       int index;
+       static const u8 cs90[8 * 3] = {
+               0x16, 0x01, 0x01,
+               0x3e, 0x03, 0x01,
+               0x7c, 0x08, 0x01,
+               0x79, 0x06, 0x01,
+               0x29, 0x01, 0x81,
+               0x5c, 0x23, 0x01,
+               0x5c, 0x23, 0x01,
+               0x5c, 0x23, 0x01
+       };
+       static const u8 csb8[8 * 3] = {
+               0x5c, 0x23, 0x01,
+               0x29, 0x01, 0x01,
+               0x7c, 0x08, 0x01,
+               0x79, 0x06, 0x01,
+               0x29, 0x01, 0x81,
+               0x5c, 0x23, 0x01,
+               0x5c, 0x23, 0x01,
+               0x5c, 0x23, 0x01
+       };
 
-       return 0;
+       regb = 0;  /* ! */
+
+       index = regb * 3;
+       v1 = cs90[index]; v2 = cs90[index + 1]; v3 = cs90[index + 2];
+       if(ivideo->haveXGIROM) {
+               v1 = ivideo->bios_abase[0x90 + index];
+               v2 = ivideo->bios_abase[0x90 + index + 1];
+               v3 = ivideo->bios_abase[0x90 + index + 2];
+       }
+       outSISIDXREG(SISSR, 0x28, v1);
+       outSISIDXREG(SISSR, 0x29, v2);
+       outSISIDXREG(SISSR, 0x2a, v3);
+       sisfb_post_xgi_delay(ivideo, 0x43);
+       sisfb_post_xgi_delay(ivideo, 0x43);
+       sisfb_post_xgi_delay(ivideo, 0x43);
+       index = regb * 3;
+       v1 = csb8[index]; v2 = csb8[index + 1]; v3 = csb8[index + 2];
+       if(ivideo->haveXGIROM) {
+               v1 = ivideo->bios_abase[0xb8 + index];
+               v2 = ivideo->bios_abase[0xb8 + index + 1];
+               v3 = ivideo->bios_abase[0xb8 + index + 2];
+       }
+       outSISIDXREG(SISSR, 0x2e, v1);
+       outSISIDXREG(SISSR, 0x2f, v2);
+       outSISIDXREG(SISSR, 0x30, v3);
+       sisfb_post_xgi_delay(ivideo, 0x43);
+       sisfb_post_xgi_delay(ivideo, 0x43);
+       sisfb_post_xgi_delay(ivideo, 0x43);
 }
-#endif
 
-static UCHAR * __devinit sis_find_rom(struct pci_dev *pdev)
+static int __devinit
+sisfb_post_xgi(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;
+       unsigned char *bios = ivideo->bios_abase;
+       struct pci_dev *mypdev = NULL;
+       const u8 *ptr, *ptr2;
+       u8 v1, v2, v3, v4, v5, reg, ramtype;
+       u32 rega, regb, regd;
+       int i, j, k, index;
+       static const u8 cs78[3] = { 0xf6, 0x0d, 0x00 };
+       static const u8 cs76[2] = { 0xa3, 0xfb };
+       static const u8 cs7b[3] = { 0xc0, 0x11, 0x00 };
+       static const u8 cs158[8] = {
+               0x88, 0xaa, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00
+       };
+       static const u8 cs160[8] = {
+               0x44, 0x77, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00
+       };
+       static const u8 cs168[8] = {
+               0x48, 0x78, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00
+       };
+       static const u8 cs128[3 * 8] = {
+               0x90, 0x28, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00,
+               0x77, 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00,
+               0x77, 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00
+       };
+       static const u8 cs148[2 * 8] = {
+               0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00,
+               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+       };
+       static const u8 cs31a[8 * 4] = {
+               0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+               0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00,
+               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+       };
+       static const u8 cs33a[8 * 4] = {
+               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+       };
+       static const u8 cs45a[8 * 2] = {
+               0x00, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0x00, 0x00,
+               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+       };
+       static const u8 cs170[7 * 8] = {
+               0x54, 0x32, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00,
+               0x54, 0x43, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00,
+               0x0a, 0x05, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+               0x44, 0x34, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00,
+               0x10, 0x0a, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00,
+               0x11, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
+               0x05, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00
+       };
+       static const u8 cs1a8[3 * 8] = {
+               0xf0, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
+               0x05, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+       };
+       static const u8 cs100[2 * 8] = {
+               0xc4, 0x04, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00,
+               0xc4, 0x04, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00
+       };
 
-       if(!(myrombase = vmalloc(65536))) return NULL;
+       /* VGA enable */
+       reg = inSISREG(SISVGAENABLE) | 0x01;
+       outSISREG(SISVGAENABLE, reg);
 
-#if defined(__i386__) || defined(__x86_64__)
+       /* Misc */
+       reg = inSISREG(SISMISCR) | 0x01;
+       outSISREG(SISMISCW, reg);
 
-        for(temp = 0x000c0000; temp < 0x000f0000; temp += 0x00001000) {
+       /* Unlock SR */
+       outSISIDXREG(SISSR, 0x05, 0x86);
+       inSISIDXREG(SISSR, 0x05, reg);
+       if(reg != 0xa1)
+               return 0;
 
-            rom_base = ioremap(temp, 0x10000);
-           if(!rom_base) continue;
+       /* Clear some regs */
+       for(i = 0; i < 0x22; i++) {
+               if(0x06 + i == 0x20) continue;
+               outSISIDXREG(SISSR, 0x06 + i, 0x00);
+       }
+       for(i = 0; i < 0x0b; i++) {
+               outSISIDXREG(SISSR, 0x31 + i, 0x00);
+       }
+       for(i = 0; i < 0x10; i++) {
+               outSISIDXREG(SISCR, 0x30 + i, 0x00);
+       }
 
-           if((readb(rom_base) != 0x55) || (readb(rom_base + 1) != 0xaa)) {
-              iounmap(rom_base);
-               continue;
-           }
+       ptr = cs78;
+       if(ivideo->haveXGIROM) {
+               ptr = (const u8 *)&bios[0x78];
+       }
+       for(i = 0; i < 3; i++) {
+               outSISIDXREG(SISSR, 0x23 + i, ptr[i]);
+       }
 
-           romptr = (unsigned short)(readb(rom_base + 0x18) | (readb(rom_base + 0x19) << 8));
-           if(romptr > (0x10000 - 8)) {
-              iounmap(rom_base);
-              continue;
-           }
+       ptr = cs76;
+       if(ivideo->haveXGIROM) {
+               ptr = (const u8 *)&bios[0x76];
+       }
+       for(i = 0; i < 2; i++) {
+               outSISIDXREG(SISSR, 0x21 + i, ptr[i]);
+       }
 
-           rom = rom_base + romptr;
+       v1 = 0x18; v2 = 0x00;
+       if(ivideo->haveXGIROM) {
+               v1 = bios[0x74];
+               v2 = bios[0x75];
+       }
+       outSISIDXREG(SISSR, 0x07, v1);
+       outSISIDXREG(SISSR, 0x11, 0x0f);
+       outSISIDXREG(SISSR, 0x1f, v2);
+       /* PCI linear mode, RelIO enabled, A0000 decoding disabled */
+       outSISIDXREG(SISSR, 0x20, 0x80 | 0x20 | 0x04);
+       outSISIDXREG(SISSR, 0x27, 0x74);
 
-           if((readb(rom)     != 'P') || (readb(rom + 1) != 'C') ||
-              (readb(rom + 2) != 'I') || (readb(rom + 3) != 'R')) {
-              iounmap(rom_base);
-              continue;
-           }
+       ptr = cs7b;
+       if(ivideo->haveXGIROM) {
+               ptr = (const u8 *)&bios[0x7b];
+       }
+       for(i = 0; i < 3; i++) {
+               outSISIDXREG(SISSR, 0x31 + i, ptr[i]);
+       }
 
-           pciid = readb(rom + 4) | (readb(rom + 5) << 8);
-           if(pciid != 0x1039) {
-              iounmap(rom_base);
-              continue;
-           }
+       if(ivideo->chip == XGI_40) {
+               if(ivideo->revision_id == 2) {
+                       setSISIDXREG(SISSR, 0x3b, 0x3f, 0xc0);
+               }
+               outSISIDXREG(SISCR, 0x7d, 0xfe);
+               outSISIDXREG(SISCR, 0x7e, 0x0f);
+       }
+       if(ivideo->revision_id == 0) {  /* 40 *and* 20? */
+               andSISIDXREG(SISCR, 0x58, 0xd7);
+               inSISIDXREG(SISCR, 0xcb, reg);
+               if(reg & 0x20) {
+                       setSISIDXREG(SISCR, 0x58, 0xd7, (reg & 0x10) ? 0x08 : 0x20); /* =0x28 Z7 ? */
+               }
+       }
 
-           pciid = readb(rom + 6) | (readb(rom + 7) << 8);
-           if(pciid == ivideo->chip_id) {
-              memcpy_fromio(myrombase, rom_base, 65536);
-              iounmap(rom_base);
-              return myrombase;
-           }
+       reg = (ivideo->chip == XGI_40) ? 0x20 : 0x00;
+       setSISIDXREG(SISCR, 0x38, 0x1f, reg);
 
-           iounmap(rom_base);
-        }
+       if(ivideo->chip == XGI_20) {
+               outSISIDXREG(SISSR, 0x36, 0x70);
+       } else {
+               outSISIDXREG(SISVID, 0x00, 0x86);
+               outSISIDXREG(SISVID, 0x32, 0x00);
+               outSISIDXREG(SISVID, 0x30, 0x00);
+               outSISIDXREG(SISVID, 0x32, 0x01);
+               outSISIDXREG(SISVID, 0x30, 0x00);
+               andSISIDXREG(SISVID, 0x2f, 0xdf);
+               andSISIDXREG(SISCAP, 0x00, 0x3f);
+
+               outSISIDXREG(SISPART1, 0x2f, 0x01);
+               outSISIDXREG(SISPART1, 0x00, 0x00);
+               outSISIDXREG(SISPART1, 0x02, bios[0x7e]);
+               outSISIDXREG(SISPART1, 0x2e, 0x08);
+               andSISIDXREG(SISPART1, 0x35, 0x7f);
+               andSISIDXREG(SISPART1, 0x50, 0xfe);
+
+               inSISIDXREG(SISPART4, 0x00, reg);
+               if(reg == 1 || reg == 2) {
+                       outSISIDXREG(SISPART2, 0x00, 0x1c);
+                       outSISIDXREG(SISPART4, 0x0d, bios[0x7f]);
+                       outSISIDXREG(SISPART4, 0x0e, bios[0x80]);
+                       outSISIDXREG(SISPART4, 0x10, bios[0x81]);
+                       andSISIDXREG(SISPART4, 0x0f, 0x3f);
+
+                       inSISIDXREG(SISPART4, 0x01, reg);
+                       if((reg & 0xf0) >= 0xb0) {
+                               inSISIDXREG(SISPART4, 0x23, reg);
+                               if(reg & 0x20) reg |= 0x40;
+                               outSISIDXREG(SISPART4, 0x23, reg);
+                               reg = (reg & 0x20) ? 0x02 : 0x00;
+                               setSISIDXREG(SISPART1, 0x1e, 0xfd, reg);
+                       }
+               }
 
-#else
+               v1 = bios[0x77];
+
+               inSISIDXREG(SISSR, 0x3b, reg);
+               if(reg & 0x02) {
+                       inSISIDXREG(SISSR, 0x3a, reg);
+                       v2 = (reg & 0x30) >> 3;
+                       if(!(v2 & 0x04)) v2 ^= 0x02;
+                       inSISIDXREG(SISSR, 0x39, reg);
+                       if(reg & 0x80) v2 |= 0x80;
+                       v2 |= 0x01;
+
+                       if((mypdev = SIS_PCI_GET_DEVICE(PCI_VENDOR_ID_SI, 0x0730, NULL))) {
+                               SIS_PCI_PUT_DEVICE(mypdev);
+                               if(((v2 & 0x06) == 2) || ((v2 & 0x06) == 4))
+                                       v2 &= 0xf9;
+                               v2 |= 0x08;
+                               v1 &= 0xfe;
+                       } else {
+                               mypdev = SIS_PCI_GET_DEVICE(PCI_VENDOR_ID_SI, 0x0735, NULL);
+                               if(!mypdev)
+                                       mypdev = SIS_PCI_GET_DEVICE(PCI_VENDOR_ID_SI, 0x0645, NULL);
+                               if(!mypdev)
+                                       mypdev = SIS_PCI_GET_DEVICE(PCI_VENDOR_ID_SI, 0x0650, NULL);
+                               if(mypdev) {
+                                       pci_read_config_dword(mypdev, 0x94, &regd);
+                                       regd &= 0xfffffeff;
+                                       pci_write_config_dword(mypdev, 0x94, regd);
+                                       v1 &= 0xfe;
+                                       SIS_PCI_PUT_DEVICE(mypdev);
+                               } else if(sisfb_find_host_bridge(ivideo, pdev, PCI_VENDOR_ID_SI)) {
+                                       v1 &= 0xfe;
+                               } else if(sisfb_find_host_bridge(ivideo, pdev, 0x1106) ||
+                                         sisfb_find_host_bridge(ivideo, pdev, 0x1022) ||
+                                         sisfb_find_host_bridge(ivideo, pdev, 0x700e) ||
+                                         sisfb_find_host_bridge(ivideo, pdev, 0x10de)) {
+                                       if((v2 & 0x06) == 4)
+                                               v2 ^= 0x06;
+                                       v2 |= 0x08;
+                               }
+                       }
+                       setSISIDXREG(SISCR, 0x5f, 0xf0, v2);
+               }
+               outSISIDXREG(SISSR, 0x22, v1);
+
+               if(ivideo->revision_id == 2) {
+                       inSISIDXREG(SISSR, 0x3b, v1);
+                       inSISIDXREG(SISSR, 0x3a, v2);
+                       regd = bios[0x90 + 3] | (bios[0x90 + 4] << 8);
+                       if( (!(v1 & 0x02)) && (v2 & 0x30) && (regd < 0xcf) )
+                               setSISIDXREG(SISCR, 0x5f, 0xf1, 0x01);
+
+                       if((mypdev = SIS_PCI_GET_DEVICE(0x10de, 0x01e0, NULL))) {
+                               /* TODO: set CR5f &0xf1 | 0x01 for version 6570
+                                * of nforce 2 ROM
+                                */
+                               if(0)
+                                       setSISIDXREG(SISCR, 0x5f, 0xf1, 0x01);
+                               SIS_PCI_PUT_DEVICE(mypdev);
+                       }
+               }
 
-       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);
+               v1 = 0x30;
+               inSISIDXREG(SISSR, 0x3b, reg);
+               inSISIDXREG(SISCR, 0x5f, v2);
+               if((!(reg & 0x02)) && (v2 & 0x0e))
+                       v1 |= 0x08;
+               outSISIDXREG(SISSR, 0x27, v1);
 
-       rom_base = ioremap(ivideo->video_base, 65536);
-       if(rom_base) {
-          if((readb(rom_base) == 0x55) && (readb(rom_base + 1) == 0xaa)) {
-             romptr = (u16)(readb(rom_base + 0x18) | (readb(rom_base + 0x19) << 8));
-             if(romptr <= (0x10000 - 8)) {
-                rom = rom_base + romptr;
-                if((readb(rom)     == 'P') && (readb(rom + 1) == 'C') &&
-                   (readb(rom + 2) == 'I') && (readb(rom + 3) == 'R')) {
-                   pciid = readb(rom + 4) | (readb(rom + 5) << 8);
-                   if(pciid == 0x1039) {
-                      pciid = readb(rom + 6) | (readb(rom + 7) << 8);
-                      if(pciid == ivideo->chip_id) {
-                         memcpy_fromio(myrombase, rom_base, 65536);
-                         iounmap(rom_base);
-                         pci_write_config_dword(pdev, PCI_ROM_ADDRESS, temp);
-                         return myrombase;
-                      }
-                   }
-                }
-             }
-          }
-          iounmap(rom_base);
+               if(bios[0x64] & 0x01) {
+                       setSISIDXREG(SISCR, 0x5f, 0xf0, bios[0x64]);
+               }
+
+               v1 = bios[0x4f7];
+               pci_read_config_dword(pdev, 0x50, &regd);
+               regd = (regd >> 20) & 0x0f;
+               if(regd == 1) {
+                       v1 &= 0xfc;
+                       orSISIDXREG(SISCR, 0x5f, 0x08);
+               }
+               outSISIDXREG(SISCR, 0x48, v1);
+
+               setSISIDXREG(SISCR, 0x47, 0x04, bios[0x4f6] & 0xfb);
+               setSISIDXREG(SISCR, 0x49, 0xf0, bios[0x4f8] & 0x0f);
+               setSISIDXREG(SISCR, 0x4a, 0x60, bios[0x4f9] & 0x9f);
+               setSISIDXREG(SISCR, 0x4b, 0x08, bios[0x4fa] & 0xf7);
+               setSISIDXREG(SISCR, 0x4c, 0x80, bios[0x4fb] & 0x7f);
+               outSISIDXREG(SISCR, 0x70, bios[0x4fc]);
+               setSISIDXREG(SISCR, 0x71, 0xf0, bios[0x4fd] & 0x0f);
+               outSISIDXREG(SISCR, 0x74, 0xd0);
+               setSISIDXREG(SISCR, 0x74, 0xcf, bios[0x4fe] & 0x30);
+               setSISIDXREG(SISCR, 0x75, 0xe0, bios[0x4ff] & 0x1f);
+               setSISIDXREG(SISCR, 0x76, 0xe0, bios[0x500] & 0x1f);
+               v1 = bios[0x501];
+               if((mypdev = SIS_PCI_GET_DEVICE(0x8086, 0x2530, NULL))) {
+                       v1 = 0xf0;
+                       SIS_PCI_PUT_DEVICE(mypdev);
+               }
+               outSISIDXREG(SISCR, 0x77, v1);
        }
-        pci_write_config_dword(pdev, PCI_ROM_ADDRESS, temp);
 
-#endif
+       /* RAM type */
 
-               vfree(myrombase);
-        return NULL;
-}
+       regb = 0;       /* ! */
 
-#ifdef CONFIG_FB_SIS_300
-static int __devinit
-sisfb_chkbuswidth300(struct pci_dev *pdev, SIS_IOTYPE1 *FBAddress)
-{
-       struct sis_video_info *ivideo = pci_get_drvdata(pdev);
-       int i, j;
-       USHORT temp;
-       UCHAR reg;
-
-       andSISIDXREG(SISSR,0x15,0xFB);
-       orSISIDXREG(SISSR,0x15,0x04);
-       outSISIDXREG(SISSR,0x13,0x00);
-       outSISIDXREG(SISSR,0x14,0xBF);
-
-       for(i=0; i<2; i++) {
-          temp = 0x1234;
-          for(j=0; j<4; j++) {
-             writew(temp, FBAddress);
-             if(readw(FBAddress) == temp) break;
-             orSISIDXREG(SISSR,0x3c,0x01);
-             inSISIDXREG(SISSR,0x05,reg);
-             inSISIDXREG(SISSR,0x05,reg);
-             andSISIDXREG(SISSR,0x3c,0xfe);
-             inSISIDXREG(SISSR,0x05,reg);
-             inSISIDXREG(SISSR,0x05,reg);
-             temp++;
-          }
+       v1 = 0xff;
+       if(ivideo->haveXGIROM) {
+               v1 = bios[0x140 + regb];
        }
+       outSISIDXREG(SISCR, 0x6d, v1);
 
-       writel(0x01234567L, FBAddress);
-       writel(0x456789ABL, (FBAddress+4));
-       writel(0x89ABCDEFL, (FBAddress+8));
-       writel(0xCDEF0123L, (FBAddress+12));
-       inSISIDXREG(SISSR,0x3b,reg);
-       if(reg & 0x01) {
-          if(readl((FBAddress+12)) == 0xCDEF0123L) return(4);  /* Channel A 128bit */
+       ptr = cs128;
+       if(ivideo->haveXGIROM) {
+               ptr = (const u8 *)&bios[0x128];
        }
-       if(readl((FBAddress+4)) == 0x456789ABL)     return(2);  /* Channel B 64bit */
-       return(1);                                              /* 32bit */
-}
-
-static void __devinit
-sisfb_setramsize300(struct pci_dev *pdev)
-{
-       struct  sis_video_info *ivideo = pci_get_drvdata(pdev);
-       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;
-       const   USHORT SiS_DRAMType[17][5] = {
-                       {0x0C,0x0A,0x02,0x40,0x39},
-                       {0x0D,0x0A,0x01,0x40,0x48},
-                       {0x0C,0x09,0x02,0x20,0x35},
-                       {0x0D,0x09,0x01,0x20,0x44},
-                       {0x0C,0x08,0x02,0x10,0x31},
-                       {0x0D,0x08,0x01,0x10,0x40},
-                       {0x0C,0x0A,0x01,0x20,0x34},
-                       {0x0C,0x09,0x01,0x08,0x32},
-                       {0x0B,0x08,0x02,0x08,0x21},
-                       {0x0C,0x08,0x01,0x08,0x30},
-                       {0x0A,0x08,0x02,0x04,0x11},
-                       {0x0B,0x0A,0x01,0x10,0x28},
-                       {0x09,0x08,0x02,0x02,0x01},
-                       {0x0B,0x09,0x01,0x08,0x24},
-                       {0x0B,0x08,0x01,0x04,0x20},
-                       {0x0A,0x08,0x01,0x02,0x10},
-                       {0x09,0x08,0x01,0x01,0x00}
-               };
-
-        buswidth = sisfb_chkbuswidth300(pdev, FBAddr);
-
-       MB2Bank = 16;
-       Done = 0;
-       for(i = 6; i >= 0; i--) {
-          if(Done) break;
-          PseudoRankCapacity = 1 << i;
-          for(j = 4; j >= 1; j--) {
-              if(Done) break;
-              PseudoTotalCapacity = PseudoRankCapacity * j;
-              PseudoAdrPinCount = 15 - j;
-              if(PseudoTotalCapacity <= 64) {
-                 for(k = 0; k <= 16; k++) {
-                    if(Done) break;
-                    RankCapacity = buswidth * SiS_DRAMType[k][3];
-                    AdrPinCount = SiS_DRAMType[k][2] + SiS_DRAMType[k][0];
-                    if(RankCapacity == PseudoRankCapacity)
-                       if(AdrPinCount <= PseudoAdrPinCount) {
-                          if(j == 3) {             /* Rank No */
-                             BankNumHigh = RankCapacity * MB2Bank * 3 - 1;
-                             BankNumMid  = RankCapacity * MB2Bank * 1 - 1;
-                          } else {
-                             BankNumHigh = RankCapacity * MB2Bank * j - 1;
-                             BankNumMid  = RankCapacity * MB2Bank * j / 2 - 1;
-                          }
-                          PageCapacity = (1 << SiS_DRAMType[k][1]) * buswidth * 4;
-                          PhysicalAdrHigh = BankNumHigh;
-                          PhysicalAdrHalfPage = (PageCapacity / 2 + PhysicalAdrHigh) % PageCapacity;
-                          PhysicalAdrOtherPage = PageCapacity * SiS_DRAMType[k][2] + PhysicalAdrHigh;
-                          /* Write data */
-                          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);
-                          Addr = FBAddr + BankNumHigh * 64 * 1024 + PhysicalAdrHigh;
-                          /* *((USHORT *)(Addr)) = (USHORT)PhysicalAdrHigh; */
-                         writew(((USHORT)PhysicalAdrHigh), Addr);
-                          Addr = FBAddr + BankNumMid * 64 * 1024 + PhysicalAdrHigh;
-                          /* *((USHORT *)(Addr)) = (USHORT)BankNumMid; */
-                         writew(((USHORT)BankNumMid), Addr);
-                          Addr = FBAddr + BankNumHigh * 64 * 1024 + PhysicalAdrHalfPage;
-                          /* *((USHORT *)(Addr)) = (USHORT)PhysicalAdrHalfPage; */
-                         writew(((USHORT)PhysicalAdrHalfPage), Addr);
-                          Addr = FBAddr + BankNumHigh * 64 * 1024 + PhysicalAdrOtherPage;
-                          /* *((USHORT *)(Addr)) = PhysicalAdrOtherPage; */
-                         writew(((USHORT)PhysicalAdrOtherPage), Addr);
-                          /* Read data */
-                          Addr = FBAddr + BankNumHigh * 64 * 1024 + PhysicalAdrHigh;
-                          data = readw(Addr); /* *((USHORT *)(Addr)); */
-                          if(data == PhysicalAdrHigh) Done = 1;
-                       }  /* if */
-                 }  /* for k */
-              }  /* if */
-          }  /* for j */
-       }  /* for i */
-}
-
-static void __devinit sisfb_post_sis300(struct pci_dev *pdev)
-{
-       struct sis_video_info *ivideo = pci_get_drvdata(pdev);
-       u8  reg, v1, v2, v3, v4, v5, v6, v7, v8;
-       u16 index, rindex, memtype = 0;
-
-       outSISIDXREG(SISSR,0x05,0x86);
-
-       if(ivideo->sishw_ext.UseROM) {
-          if(ivideo->sishw_ext.pjVirtualRomBase[0x52] & 0x80) {
-             memtype = ivideo->sishw_ext.pjVirtualRomBase[0x52];
-          } else {
-             inSISIDXREG(SISSR,0x3a,memtype);
-          }
-          memtype &= 0x07;
+       for(i = 0, j = 0; i < 3; i++, j += 8) {
+               outSISIDXREG(SISCR, 0x68 + i, ptr[j + regb]);
        }
 
-       if(ivideo->revision_id <= 0x13) {
-          v1 = 0x44; v2 = 0x42; v3 = 0x80;
-          v4 = 0x44; v5 = 0x42; v6 = 0x80;
-       } else {
-          v1 = 0x68; v2 = 0x43; v3 = 0x80;  /* Assume 125Mhz MCLK */
-          v4 = 0x68; v5 = 0x43; v6 = 0x80;  /* Assume 125Mhz ECLK */
-          if(ivideo->sishw_ext.UseROM) {
-             index = memtype * 5;
-             rindex = index + 0x54;
-             v1 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
-             v2 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
-             v3 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
-             rindex = index + 0x7c;
-             v4 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
-             v5 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
-             v6 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
-          }
+       ptr  = cs31a;
+       ptr2 = cs33a;
+       if(ivideo->haveXGIROM) {
+               index = (ivideo->chip == XGI_20) ? 0x31a : 0x3a6;
+               ptr  = (const u8 *)&bios[index];
+               ptr2 = (const u8 *)&bios[index + 0x20];
        }
-       outSISIDXREG(SISSR,0x28,v1);
-       outSISIDXREG(SISSR,0x29,v2);
-       outSISIDXREG(SISSR,0x2a,v3);
-       outSISIDXREG(SISSR,0x2e,v4);
-       outSISIDXREG(SISSR,0x2f,v5);
-       outSISIDXREG(SISSR,0x30,v6);
-       v1 = 0x10;
-       if(ivideo->sishw_ext.UseROM) v1 = ivideo->sishw_ext.pjVirtualRomBase[0xa4];
-       outSISIDXREG(SISSR,0x07,v1);       /* DAC speed */
-       outSISIDXREG(SISSR,0x11,0x0f);     /* DDC, power save */
-       v1 = 0x01; v2 = 0x43; v3 = 0x1e; v4 = 0x2a;
-       v5 = 0x06; v6 = 0x00; v7 = 0x00; v8 = 0x00;
-       if(ivideo->sishw_ext.UseROM) {
-          memtype += 0xa5;
-          v1 = ivideo->sishw_ext.pjVirtualRomBase[memtype];
-          v2 = ivideo->sishw_ext.pjVirtualRomBase[memtype + 8];
-          v3 = ivideo->sishw_ext.pjVirtualRomBase[memtype + 16];
-          v4 = ivideo->sishw_ext.pjVirtualRomBase[memtype + 24];
-          v5 = ivideo->sishw_ext.pjVirtualRomBase[memtype + 32];
-          v6 = ivideo->sishw_ext.pjVirtualRomBase[memtype + 40];
-          v7 = ivideo->sishw_ext.pjVirtualRomBase[memtype + 48];
-          v8 = ivideo->sishw_ext.pjVirtualRomBase[memtype + 56];
-       }
-       if(ivideo->revision_id >= 0x80) v3 &= 0xfd;
-       outSISIDXREG(SISSR,0x15,v1);       /* Ram type (assuming 0, BIOS 0xa5 step 8) */
-       outSISIDXREG(SISSR,0x16,v2);
-       outSISIDXREG(SISSR,0x17,v3);
-       outSISIDXREG(SISSR,0x18,v4);
-       outSISIDXREG(SISSR,0x19,v5);
-       outSISIDXREG(SISSR,0x1a,v6);
-       outSISIDXREG(SISSR,0x1b,v7);
-       outSISIDXREG(SISSR,0x1c,v8);       /* ---- */
-       andSISIDXREG(SISSR,0x15,0xfb);
-       orSISIDXREG(SISSR,0x15,0x04);
-       if(ivideo->sishw_ext.UseROM) {
-          if(ivideo->sishw_ext.pjVirtualRomBase[0x53] & 0x02) {
-             orSISIDXREG(SISSR,0x19,0x20);
-          }
+       for(i = 0; i < 2; i++) {
+               if(i == 0) {
+                       regd = le32_to_cpu(((u32 *)ptr)[regb]);
+                       rega = 0x6b;
+               } else {
+                       regd = le32_to_cpu(((u32 *)ptr2)[regb]);
+                       rega = 0x6e;
+               }
+               reg = 0x00;
+               for(j = 0; j < 16; j++) {
+                       reg &= 0xf3;
+                       if(regd & 0x01) reg |= 0x04;
+                       if(regd & 0x02) reg |= 0x08;
+                       regd >>= 2;
+                       outSISIDXREG(SISCR, rega, reg);
+                       inSISIDXREG(SISCR, rega, reg);
+                       inSISIDXREG(SISCR, rega, reg);
+                       reg += 0x10;
+               }
        }
-       v1 = 0x04;                         /* DAC pedestal (BIOS 0xe5) */
-       if(ivideo->revision_id >= 0x80) v1 |= 0x01;
-       outSISIDXREG(SISSR,0x1f,v1);
-       outSISIDXREG(SISSR,0x20,0xa0);     /* linear & relocated io */
-       v1 = 0xf6; v2 = 0x0d; v3 = 0x00;
-       if(ivideo->sishw_ext.UseROM) {
-          v1 = ivideo->sishw_ext.pjVirtualRomBase[0xe8];
-          v2 = ivideo->sishw_ext.pjVirtualRomBase[0xe9];
-          v3 = ivideo->sishw_ext.pjVirtualRomBase[0xea];
-       }
-       outSISIDXREG(SISSR,0x23,v1);
-       outSISIDXREG(SISSR,0x24,v2);
-       outSISIDXREG(SISSR,0x25,v3);
-       outSISIDXREG(SISSR,0x21,0x84);
-       outSISIDXREG(SISSR,0x22,0x00);
-       outSISIDXREG(SISCR,0x37,0x00);
-       orSISIDXREG(SISPART1,0x24,0x01);   /* unlock crt2 */
-       outSISIDXREG(SISPART1,0x00,0x00);
-       v1 = 0x40; v2 = 0x11;
-       if(ivideo->sishw_ext.UseROM) {
-          v1 = ivideo->sishw_ext.pjVirtualRomBase[0xec];
-          v2 = ivideo->sishw_ext.pjVirtualRomBase[0xeb];
+
+       andSISIDXREG(SISCR, 0x6e, 0xfc);
+
+       ptr  = NULL;
+       if(ivideo->haveXGIROM) {
+               index = (ivideo->chip == XGI_20) ? 0x35a : 0x3e6;
+               ptr  = (const u8 *)&bios[index];
        }
-       outSISIDXREG(SISPART1,0x02,v1);
-       if(ivideo->revision_id >= 0x80) v2 &= ~0x01;
-       inSISIDXREG(SISPART4,0x00,reg);
-       if((reg == 1) || (reg == 2)) {
-          outSISIDXREG(SISCR,0x37,0x02);
-          outSISIDXREG(SISPART2,0x00,0x1c);
-          v4 = 0x00; v5 = 0x00; v6 = 0x10;
-          if(ivideo->sishw_ext.UseROM) {
-             v4 = ivideo->sishw_ext.pjVirtualRomBase[0xf5];
-             v5 = ivideo->sishw_ext.pjVirtualRomBase[0xf6];
-             v6 = ivideo->sishw_ext.pjVirtualRomBase[0xf7];
-          }
-          outSISIDXREG(SISPART4,0x0d,v4);
-          outSISIDXREG(SISPART4,0x0e,v5);
-          outSISIDXREG(SISPART4,0x10,v6);
-          outSISIDXREG(SISPART4,0x0f,0x3f);
-          inSISIDXREG(SISPART4,0x01,reg);
-          if(reg >= 0xb0) {
-             inSISIDXREG(SISPART4,0x23,reg);
-             reg &= 0x20;
-             reg <<= 1;
-             outSISIDXREG(SISPART4,0x23,reg);
-          }
-       } else {
-          v2 &= ~0x10;
+       for(i = 0; i < 4; i++) {
+               setSISIDXREG(SISCR, 0x6e, 0xfc, i);
+               reg = 0x00;
+               for(j = 0; j < 2; j++) {
+                       regd = 0;
+                       if(ptr) {
+                               regd = le32_to_cpu(((u32 *)ptr)[regb * 8]);
+                               ptr += 4;
+                       }
+                       /* reg = 0x00; */
+                       for(k = 0; k < 16; k++) {
+                               reg &= 0xfc;
+                               if(regd & 0x01) reg |= 0x01;
+                               if(regd & 0x02) reg |= 0x02;
+                               regd >>= 2;
+                               outSISIDXREG(SISCR, 0x6f, reg);
+                               inSISIDXREG(SISCR, 0x6f, reg);
+                               inSISIDXREG(SISCR, 0x6f, reg);
+                               reg += 0x08;
+                       }
+               }
        }
-       outSISIDXREG(SISSR,0x32,v2);
-       andSISIDXREG(SISPART1,0x24,0xfe);  /* Lock CRT2 */
-       inSISIDXREG(SISSR,0x16,reg);
-       reg &= 0xc3;
-       outSISIDXREG(SISCR,0x35,reg);
-       outSISIDXREG(SISCR,0x83,0x00);
-#if !defined(__i386__) && !defined(__x86_64__)
-       if(sisfb_videoram) {
-          outSISIDXREG(SISSR,0x13,0x28);  /* ? */
-          reg = ((sisfb_videoram >> 10) - 1) | 0x40;
-          outSISIDXREG(SISSR,0x14,reg);
-       } else {
-#endif
-          /* Need to map max FB size for finding out about RAM size */
-          ivideo->video_vbase = ioremap(ivideo->video_base, 0x4000000);
-          if(ivideo->video_vbase) {
-             sisfb_setramsize300(pdev);
-             iounmap(ivideo->video_vbase);
-          } else {
-             printk(KERN_DEBUG "sisfb: Failed to map memory for size detection, assuming 8MB\n");
-             outSISIDXREG(SISSR,0x13,0x28);  /* ? */
-             outSISIDXREG(SISSR,0x14,0x47);  /* 8MB, 64bit default */
-          }
-#if !defined(__i386__) && !defined(__x86_64__)
+
+       ptr  = cs148;
+       if(ivideo->haveXGIROM) {
+               ptr  = (const u8 *)&bios[0x148];
        }
-#endif
-       if(ivideo->sishw_ext.UseROM) {
-          v1 = ivideo->sishw_ext.pjVirtualRomBase[0xe6];
-          v2 = ivideo->sishw_ext.pjVirtualRomBase[0xe7];
-       } else {
-          inSISIDXREG(SISSR,0x3a,reg);
-          if((reg & 0x30) == 0x30) {
-             v1 = 0x04; /* PCI */
-             v2 = 0x92;
-          } else {
-             v1 = 0x14; /* AGP */
-             v2 = 0xb2;
-          }
+       for(i = 0, j = 0; i < 2; i++, j += 8) {
+               outSISIDXREG(SISCR, 0x80 + i, ptr[j + regb]);
        }
-       outSISIDXREG(SISSR,0x21,v1);
-       outSISIDXREG(SISSR,0x22,v2);
-}
-#endif
-
-#ifdef CONFIG_FB_SIS_315
-static void __devinit sisfb_post_sis315330(struct pci_dev *pdev)
-{
-#ifdef YET_TO_BE_DONE
-       struct sis_video_info *ivideo = pci_get_drvdata(pdev);
-       u8  reg, v1, v2, v3, v4, v5, v6, v7, v8;
-       u16 index, rindex, memtype = 0;
-       u32 reg1_32, reg2_32, reg3_32;
-       int i;
 
-       /* Unlock */
-       /* outSISIDXREG(0x3c4,0x05,0x86); */
-       outSISIDXREG(SISSR,0x05,0x86);
+       andSISIDXREG(SISCR, 0x89, 0x8f);
 
-       /* Enable relocated i/o ports */
-       /* setSISIDXREG(0x3c4,0x20,~0x10,0x20); */
-       setSISIDXREG(SISSR,0x20,~0x10,0x20);
+       ptr  = cs45a;
+       if(ivideo->haveXGIROM) {
+               index = (ivideo->chip == XGI_20) ? 0x45a : 0x4e6;
+               ptr  = (const u8 *)&bios[index];
+       }
+       regd = le16_to_cpu(((const u16 *)ptr)[regb]);
+       reg = 0x80;
+       for(i = 0; i < 5; i++) {
+               reg &= 0xfc;
+               if(regd & 0x01) reg |= 0x01;
+               if(regd & 0x02) reg |= 0x02;
+               regd >>= 2;
+               outSISIDXREG(SISCR, 0x89, reg);
+               inSISIDXREG(SISCR, 0x89, reg);
+               inSISIDXREG(SISCR, 0x89, reg);
+               reg += 0x10;
+       }
 
-       /* Clear regs */
-       for(i = 0; i < 0x22; i++) {
-          outSISIDXREG(SISSR,(0x06 + i),0x00);
+       v1 = 0xb5; v2 = 0x20; v3 = 0xf0; v4 = 0x13;
+       if(ivideo->haveXGIROM) {
+               v1 = bios[0x118 + regb];
+               v2 = bios[0xf8 + regb];
+               v3 = bios[0x120 + regb];
+               v4 = bios[0x1ca];
        }
-       v1 = 0x0d;
-       if( is 330) v1 = 0x0b;
-       for(i = 0; i < v1; i++) {
-          outSISIDXREG(SISSR,(0x31 + i),0x00);
+       outSISIDXREG(SISCR, 0x45, v1 & 0x0f);
+       outSISIDXREG(SISCR, 0x99, (v1 >> 4) & 0x07);
+       orSISIDXREG(SISCR, 0x40, v1 & 0x80);
+       outSISIDXREG(SISCR, 0x41, v2);
+
+       ptr  = cs170;
+       if(ivideo->haveXGIROM) {
+               ptr  = (const u8 *)&bios[0x170];
        }
-       for(i = 0; i < 0x10; i++) {
-          outSISIDXREG(SISCR,(0x30 + i),0x00);
-       }
-
-       /* Reset clocks */
-       reg = inSISREG(SISMISCR);
-       outSISIDXREG(SISSR,0x28,0x81);
-       outSISIDXREG(SISSR,0x2A,0x00);
-       outSISIDXREG(SISSR,0x29,0xE1);
-       outSISREG(SISMISCW,(reg | 0x0c));
-       outSISIDXREG(SISSR,0x2B,0x81);
-       outSISIDXREG(SISSR,0x2D,0x00);
-       outSISIDXREG(SISSR,0x2C,0xE1);
-       outSISIDXREG(SISSR,0x2E,0x81);
-       outSISIDXREG(SISSR,0x30,0x00);
-       outSISIDXREG(SISSR,0x2F,0xE1);
-       SiS_DDC2Delay(....);
-       outSISREG(SISMISCW,reg);
-
-       /* Get memory type */
-       if(ivideo->sishw_ext.UseROM) {
-          if(ivideo->sishw_ext.pjVirtualRomBase[0x52] & 0x80)) {
-             memtype = ivideo->sishw_ext.pjVirtualRomBase[0x52];
-          } else {
-             inSISIDXREG(SISSR,0x3a,memtype);
-          }
-          memtype &= 0x03;
-          if( is 330 ) {
-             if(memtype <= 1) memtype = 0;
-             else {
-                inSISIDXREG(SISCR,0x5F,reg);
-                reg &= 0x30;
-                switch(reg) {
-                case 0x00: memtype = 1; break;
-                case 0x10: memtype = 3; break;
-                case 0x20: memtype = 3; break;
-                default:   memtype = 2;
-                }
-             }
-          }
+       for(i = 0, j = 0; i < 7; i++, j += 8) {
+               outSISIDXREG(SISCR, 0x90 + i, ptr[j + regb]);
        }
 
-       /* Set clocks */
-       v1 = 0x3b; v2 = 0x22; v3 = 0x01;  /* Assume 143Mhz MCLK */
-       v4 = 0x5c; v5 = 0x23; v6 = 0x01;  /* Assume 166Mhz ECLK */
-       if(ivideo->sishw_ext.UseROM) {
-          index = memtype * 5;
-          rindex = index + 0x54;
-          v1 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
-          v2 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
-          v3 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
-          rindex = index + 0x68;
-          v4 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
-          v5 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
-          v6 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
-       }
-       outSISIDXREG(SISSR,0x28,v1);
-       outSISIDXREG(SISSR,0x29,v2);
-       outSISIDXREG(SISSR,0x2a,v3);
-       if( is 330 ) {
-          inSISIDXREG(SISSR,0x3a,reg);
-          reg &= 0x03;
-          if(reg >= 2) {
-             ...
-          }
+       outSISIDXREG(SISCR, 0x59, v3);
+
+       ptr  = cs1a8;
+       if(ivideo->haveXGIROM) {
+               ptr  = (const u8 *)&bios[0x1a8];
+       }
+       for(i = 0, j = 0; i < 3; i++, j += 8) {
+               outSISIDXREG(SISCR, 0xc3 + i, ptr[j + regb]);
        }
-       outSISIDXREG(SISSR,0x2e,v4);
-       outSISIDXREG(SISSR,0x2f,v5);
-       outSISIDXREG(SISSR,0x30,v6);
-
-       /* End of comp with 330 */
-
-       v1 = 0x18;
-       if(ivideo->sishw_ext.UseROM) v1 = ivideo->sishw_ext.pjVirtualRomBase[0x7c];
-       outSISIDXREG(SISSR,0x07,v1);
-       outSISIDXREG(SISSR,0x11,0x0f);
-
-       v1 = 0x00; v2 = 0x0f; v3 = 0xba; v4 = 0xa9;
-       v5 = 0xa0; v6 = 0x00; v7 = 0x30;
-       if(ivideo->sishw_ext.UseROM) {
-          index = memtype + 0x7d;
-          v1 = ivideo->sishw_ext.pjVirtualRomBase[index];
-          v2 = ivideo->sishw_ext.pjVirtualRomBase[index + 4];
-          v3 = ivideo->sishw_ext.pjVirtualRomBase[index + 8];
-          v4 = ivideo->sishw_ext.pjVirtualRomBase[index + 12];
-          v5 = ivideo->sishw_ext.pjVirtualRomBase[index + 16];
-          v6 = ivideo->sishw_ext.pjVirtualRomBase[index + 20];
-          v7 = ivideo->sishw_ext.pjVirtualRomBase[index + 24];
-       }
-       outSISIDXREG(SISSR,0x15,v1);       /* Ram type (assuming 0, BIOS 0x7d step 4) */
-       outSISIDXREG(SISSR,0x16,v2);
-       outSISIDXREG(SISSR,0x17,v3);
-       outSISIDXREG(SISSR,0x18,v4);
-       outSISIDXREG(SISSR,0x19,v5);
-       outSISIDXREG(SISSR,0x1a,v6);
-       outSISIDXREG(SISSR,0x1b,v7);
-       outSISIDXREG(SISSR,0x1c,v8);       /* ---- */
-
-       v1 = 0x77; v2 = 0x77; v3 = 0x00; v4 = 0x5b; v5 = 0x00;
-       if(ivideo->sishw_ext.UseROM) {
-          index = memtype + 0xa2;
-          v1 = ivideo->sishw_ext.pjVirtualRomBase[index];
-          v2 = ivideo->sishw_ext.pjVirtualRomBase[index + 4];
-          v3 = ivideo->sishw_ext.pjVirtualRomBase[index + 8];
-          v4 = ivideo->sishw_ext.pjVirtualRomBase[index + 12];
-          v5 = ivideo->sishw_ext.pjVirtualRomBase[index + 16];
-       }
-       outSISIDXREG(SISCR,0x40,v1);
-       outSISIDXREG(SISCR,0x41,v2);
-       outSISIDXREG(SISCR,0x42,v3);
-       outSISIDXREG(SISCR,0x43,v4);
-       outSISIDXREG(SISCR,0x44,v5);
-
-       if( is 330 ) {
-
-          v1 = 0x;
-          if(ivideo->sishw_ext.UseROM) {
-             v1 = ivideo->sishw_ext.pjVirtualRomBase[0xBA];
-          }
-          outSISIDXREG(SISCR,0x59,v1);
-
-          v1 = 0x; v2 = 0x; v3 = 0x; v4 = 0x;
-          v5 = 0x; v6 = 0x; v7 = 0x; v8 = 0x;
-          if(ivideo->sishw_ext.UseROM) {
-             index = memtype + 0xbe;
-             v1 = ivideo->sishw_ext.pjVirtualRomBase[index];
-             v2 = ivideo->sishw_ext.pjVirtualRomBase[index + 4];
-             v3 = ivideo->sishw_ext.pjVirtualRomBase[index + 8];
-             v4 = ivideo->sishw_ext.pjVirtualRomBase[index + 12];
-             v5 = ivideo->sishw_ext.pjVirtualRomBase[index + 16];
-             v6 = ivideo->sishw_ext.pjVirtualRomBase[index + 20];
-             v7 = ivideo->sishw_ext.pjVirtualRomBase[index + 24];
-             v8 = ivideo->sishw_ext.pjVirtualRomBase[index + 28];
-          }
-          outSISIDXREG(SISCR,0x68,v1);
-          outSISIDXREG(SISCR,0x69,v2);
-          outSISIDXREG(SISCR,0x6a,v3);
-          outSISIDXREG(SISCR,0x6b,v4);
-          outSISIDXREG(SISCR,0x6c,v5);
-          outSISIDXREG(SISCR,0x6d,v6);
-          outSISIDXREG(SISCR,0x6e,v7);
-          outSISIDXREG(SISCR,0x6f,v8);
-
-          v1 = 0x20;
-          inSISIDXREG(SISSR,0x3b,reg);
-
-          if(!(reg & 0x04)) {
-             inSISIDXREG(SISCR,0x5F,reg);
-             reg &= 0x30;
-             if(reg) v1 = 0x23;
-          }
-          outSISIDXREG(SISCR,0x48,v1);
-          outSISIDXREG(SISCR,0x4c,0x20);
-
-          xx= xxx();
-          if(xx >= 1) {
-             v1 = 0x;
-             if(ivideo->sishw_ext.UseROM) {
-                v1 = ivideo->sishw_ext.pjVirtualRomBase[0xBA];
-             }
-             outSISIDXREG(SISCR,0x59,v1);
-          }
 
+       ptr  = cs100;
+       if(ivideo->haveXGIROM) {
+               ptr  = (const u8 *)&bios[0x100];
+       }
+       for(i = 0, j = 0; i < 2; i++, j += 8) {
+               outSISIDXREG(SISCR, 0x8a + i, ptr[j + regb]);
+       }
 
+       outSISIDXREG(SISCR, 0xcf, v4);
 
-       } else {
+       outSISIDXREG(SISCR, 0x83, 0x09);
+       outSISIDXREG(SISCR, 0x87, 0x00);
 
-          outSISIDXREG(SISCR,0x48,0x23);
+       if(ivideo->chip == XGI_40) {
+               if( (ivideo->revision_id == 1) ||
+                   (ivideo->revision_id == 2) ) {
+                       outSISIDXREG(SISCR, 0x8c, 0x87);
+               }
+       }
 
-          andSISIDXREG(SISSR,0x16,0x0f);
-          if(memtype <= 1) {
-             orSISIDXREG(SISSR,0x16,0x80);
-          } else {
-             v1 = 0x0f;
-             if(ivideo->sishw_ext.UseROM) {
-                v1 = ivideo->sishw_ext.pjVirtualRomBase[0x81 + memtype];
-             }
-             if(!(v1 & 0x10)) v2 = 0xc0;
-             else             v2 = 0xd0;
-             orSISIDXREG(SISSR,0x16,v2);
-             andSISIDXREG(SISSR,0x16,0x0f);
-             if(!(v1 & 0x10)) v2 = 0x80;
-             else             v2 = 0xA0;
-             orSISIDXREG(SISSR,0x16,v2);
-          }
-
-          if(memtype >= 2) {
-             const u8 sr3cseq1[] = { 0xc0,0xe0,0xf0,0xe0,0xf0,0xa0,0xb0,0xa0,0xb0,0x90,0xd0 };
-             const u8 sr3cseq2[] = { 0xc0,0xa0,0xb0,0xa0,0xb0,0xe0,0xf0,0xa0,0xb0,0x90,0xd0 };
-             for(i = 0; i < 11; i++) {
-                outSISIDXREG(SISSR,0x3c,sr3cseq1[i]);
-             }
-             outSISIDXREG(SISSR,0x3d,0x00);
-             outSISIDXREG(SISSR,0x3d,0x04);
-             SiS_DDC2Delay(0x200);
-             v1 = inSISIDXREG(SISCR,0xEC);
-             v2 = inSISIDXREG(SISCR,0xED);
-             reg1_32 = (v2 << 8) | v1;
-             outSISIDXREG(SISSR,0x3D,0x00);
-             for(i = 0; i < 11; i++) {
-                outSISIDXREG(SISSR,0x3c,sr3cseq2[i]);
-             }
-             outSISIDXREG(SISSR,0x3d,0x00);
-             outSISIDXREG(SISSR,0x3d,0x04);
-             SiS_DDC2Delay(0x200);
-             v1 = inSISIDXREG(SISCR,0xEC);
-             v2 = inSISIDXREG(SISCR,0xED);
-             reg2_32 = (v2 << 8) | v1;
-             outSISIDXREG(SISSR,0x3D,0x00);
-             reg3_32 = reg2_32 << 1;
-             reg2_32 >>= 1;
-             reg3_32 += reg2_32;
-             v1 = 0x40;
-             if(reg3_32 > reg1_32) v1 = 0x10;
-                outSISIDXREG(SISCR,0x59,v1);
-          }
+       outSISIDXREG(SISSR, 0x17, 0x00);
+       outSISIDXREG(SISSR, 0x1a, 0x87);
 
+       if(ivideo->chip == XGI_20) {
+               outSISIDXREG(SISSR, 0x15, 0x00);
+               outSISIDXREG(SISSR, 0x1c, 0x00);
        }
 
-       v1 = 0x00;
-       if(ivideo->sishw_ext.UseROM) {
-          v1 = ivideo->sishw_ext.pjVirtualRomBase[0x99];
+       ramtype = 0x00; v1 = 0x10;
+       if(ivideo->haveXGIROM) {
+               ramtype = bios[0x62];
+               v1 = bios[0x1d2];
+       }
+       if(!(ramtype & 0x80)) {
+               if(ivideo->chip == XGI_20) {
+                       outSISIDXREG(SISCR, 0x97, v1);
+                       inSISIDXREG(SISCR, 0x97, reg);
+                       if(reg & 0x10) {
+                               ramtype = (reg & 0x01) << 1;
+                       }
+               } else {
+                       inSISIDXREG(SISSR, 0x39, reg);
+                       ramtype = reg & 0x02;
+                       if(!(ramtype)) {
+                               inSISIDXREG(SISSR, 0x3a, reg);
+                               ramtype = (reg >> 1) & 0x01;
+                       }
+               }
        }
-       outSISIDXREG(SISSR,0x1f,v1);
+       ramtype &= 0x07;
+
+       regb = 0;       /* ! */
+
+       switch(ramtype) {
+       case 0:
+               sisfb_post_xgi_setclocks(ivideo, regb);
+               if((ivideo->chip == XGI_20) ||
+                  (ivideo->revision_id == 1)   ||
+                  (ivideo->revision_id == 2)) {
+                       v1 = cs158[regb]; v2 = cs160[regb]; v3 = cs168[regb];
+                       if(ivideo->haveXGIROM) {
+                               v1 = bios[regb + 0x158];
+                               v2 = bios[regb + 0x160];
+                               v3 = bios[regb + 0x168];
+                       }
+                       outSISIDXREG(SISCR, 0x82, v1);
+                       outSISIDXREG(SISCR, 0x85, v2);
+                       outSISIDXREG(SISCR, 0x86, v3);
+               } else {
+                       outSISIDXREG(SISCR, 0x82, 0x88);
+                       outSISIDXREG(SISCR, 0x86, 0x00);
+                       inSISIDXREG(SISCR, 0x86, reg);
+                       outSISIDXREG(SISCR, 0x86, 0x88);
+                       inSISIDXREG(SISCR, 0x86, reg);
+                       outSISIDXREG(SISCR, 0x86, bios[regb + 0x168]);
+                       outSISIDXREG(SISCR, 0x82, 0x77);
+                       outSISIDXREG(SISCR, 0x85, 0x00);
+                       inSISIDXREG(SISCR, 0x85, reg);
+                       outSISIDXREG(SISCR, 0x85, 0x88);
+                       inSISIDXREG(SISCR, 0x85, reg);
+                       outSISIDXREG(SISCR, 0x85, bios[regb + 0x160]);
+                       outSISIDXREG(SISCR, 0x82, bios[regb + 0x158]);
+               }
+               if(ivideo->chip == XGI_40) {
+                       outSISIDXREG(SISCR, 0x97, 0x00);
+               }
+               outSISIDXREG(SISCR, 0x98, 0x01);
+               outSISIDXREG(SISCR, 0x9a, 0x02);
 
-       outSISIDXREG(SISSR,0x20,0x20);
+               outSISIDXREG(SISSR, 0x18, 0x01);
+               if((ivideo->chip == XGI_20) ||
+                  (ivideo->revision_id == 2)) {
+                       outSISIDXREG(SISSR, 0x19, 0x40);
+               } else {
+                       outSISIDXREG(SISSR, 0x19, 0x20);
+               }
+               outSISIDXREG(SISSR, 0x16, 0x00);
+               outSISIDXREG(SISSR, 0x16, 0x80);
+               if((ivideo->chip == XGI_20) || (bios[0x1cb] != 0x0c)) {
+                       sisfb_post_xgi_delay(ivideo, 0x43);
+                       sisfb_post_xgi_delay(ivideo, 0x43);
+                       sisfb_post_xgi_delay(ivideo, 0x43);
+                       outSISIDXREG(SISSR, 0x18, 0x00);
+                       if((ivideo->chip == XGI_20) ||
+                          (ivideo->revision_id == 2)) {
+                               outSISIDXREG(SISSR, 0x19, 0x40);
+                       } else {
+                               outSISIDXREG(SISSR, 0x19, 0x20);
+                       }
+               } else if((ivideo->chip == XGI_40) && (bios[0x1cb] == 0x0c)) {
+                       /* outSISIDXREG(SISSR, 0x16, 0x0c); */ /* ? */
+               }
+               outSISIDXREG(SISSR, 0x16, 0x00);
+               outSISIDXREG(SISSR, 0x16, 0x80);
+               sisfb_post_xgi_delay(ivideo, 4);
+               v1 = 0x31; v2 = 0x03; v3 = 0x83; v4 = 0x03; v5 = 0x83;
+               if(ivideo->haveXGIROM) {
+                       v1 = bios[0xf0];
+                       index = (ivideo->chip == XGI_20) ? 0x4b2 : 0x53e;
+                       v2 = bios[index];
+                       v3 = bios[index + 1];
+                       v4 = bios[index + 2];
+                       v5 = bios[index + 3];
+               }
+               outSISIDXREG(SISSR, 0x18, v1);
+               outSISIDXREG(SISSR, 0x19, ((ivideo->chip == XGI_20) ? 0x02 : 0x01));
+               outSISIDXREG(SISSR, 0x16, v2);
+               outSISIDXREG(SISSR, 0x16, v3);
+               sisfb_post_xgi_delay(ivideo, 0x43);
+               outSISIDXREG(SISSR, 0x1b, 0x03);
+               sisfb_post_xgi_delay(ivideo, 0x22);
+               outSISIDXREG(SISSR, 0x18, v1);
+               outSISIDXREG(SISSR, 0x19, 0x00);
+               outSISIDXREG(SISSR, 0x16, v4);
+               outSISIDXREG(SISSR, 0x16, v5);
+               outSISIDXREG(SISSR, 0x1b, 0x00);
+               break;
+       case 1:
+               outSISIDXREG(SISCR, 0x82, 0x77);
+               outSISIDXREG(SISCR, 0x86, 0x00);
+               inSISIDXREG(SISCR, 0x86, reg);
+               outSISIDXREG(SISCR, 0x86, 0x88);
+               inSISIDXREG(SISCR, 0x86, reg);
+               v1 = cs168[regb]; v2 = cs160[regb]; v3 = cs158[regb];
+               if(ivideo->haveXGIROM) {
+                       v1 = bios[regb + 0x168];
+                       v2 = bios[regb + 0x160];
+                       v3 = bios[regb + 0x158];
+               }
+               outSISIDXREG(SISCR, 0x86, v1);
+               outSISIDXREG(SISCR, 0x82, 0x77);
+               outSISIDXREG(SISCR, 0x85, 0x00);
+               inSISIDXREG(SISCR, 0x85, reg);
+               outSISIDXREG(SISCR, 0x85, 0x88);
+               inSISIDXREG(SISCR, 0x85, reg);
+               outSISIDXREG(SISCR, 0x85, v2);
+               outSISIDXREG(SISCR, 0x82, v3);
+               outSISIDXREG(SISCR, 0x98, 0x01);
+               outSISIDXREG(SISCR, 0x9a, 0x02);
+
+               outSISIDXREG(SISSR, 0x28, 0x64);
+               outSISIDXREG(SISSR, 0x29, 0x63);
+               sisfb_post_xgi_delay(ivideo, 15);
+               outSISIDXREG(SISSR, 0x18, 0x00);
+               outSISIDXREG(SISSR, 0x19, 0x20);
+               outSISIDXREG(SISSR, 0x16, 0x00);
+               outSISIDXREG(SISSR, 0x16, 0x80);
+               outSISIDXREG(SISSR, 0x18, 0xc5);
+               outSISIDXREG(SISSR, 0x19, 0x23);
+               outSISIDXREG(SISSR, 0x16, 0x00);
+               outSISIDXREG(SISSR, 0x16, 0x80);
+               sisfb_post_xgi_delay(ivideo, 1);
+               outSISIDXREG(SISCR, 0x97,0x11);
+               sisfb_post_xgi_setclocks(ivideo, regb);
+               sisfb_post_xgi_delay(ivideo, 0x46);
+               outSISIDXREG(SISSR, 0x18, 0xc5);
+               outSISIDXREG(SISSR, 0x19, 0x23);
+               outSISIDXREG(SISSR, 0x16, 0x00);
+               outSISIDXREG(SISSR, 0x16, 0x80);
+               sisfb_post_xgi_delay(ivideo, 1);
+               outSISIDXREG(SISSR, 0x1b, 0x04);
+               sisfb_post_xgi_delay(ivideo, 1);
+               outSISIDXREG(SISSR, 0x1b, 0x00);
+               sisfb_post_xgi_delay(ivideo, 1);
+               v1 = 0x31;
+               if(ivideo->haveXGIROM) {
+                       v1 = bios[0xf0];
+               }
+               outSISIDXREG(SISSR, 0x18, v1);
+               outSISIDXREG(SISSR, 0x19, 0x06);
+               outSISIDXREG(SISSR, 0x16, 0x04);
+               outSISIDXREG(SISSR, 0x16, 0x84);
+               sisfb_post_xgi_delay(ivideo, 1);
+               break;
+       default:
+               sisfb_post_xgi_setclocks(ivideo, regb);
+               if((ivideo->chip == XGI_40) &&
+                  ((ivideo->revision_id == 1) ||
+                   (ivideo->revision_id == 2))) {
+                       outSISIDXREG(SISCR, 0x82, bios[regb + 0x158]);
+                       outSISIDXREG(SISCR, 0x85, bios[regb + 0x160]);
+                       outSISIDXREG(SISCR, 0x86, bios[regb + 0x168]);
+               } else {
+                       outSISIDXREG(SISCR, 0x82, 0x88);
+                       outSISIDXREG(SISCR, 0x86, 0x00);
+                       inSISIDXREG(SISCR, 0x86, reg);
+                       outSISIDXREG(SISCR, 0x86, 0x88);
+                       outSISIDXREG(SISCR, 0x82, 0x77);
+                       outSISIDXREG(SISCR, 0x85, 0x00);
+                       inSISIDXREG(SISCR, 0x85, reg);
+                       outSISIDXREG(SISCR, 0x85, 0x88);
+                       inSISIDXREG(SISCR, 0x85, reg);
+                       v1 = cs160[regb]; v2 = cs158[regb];
+                       if(ivideo->haveXGIROM) {
+                               v1 = bios[regb + 0x160];
+                               v2 = bios[regb + 0x158];
+                       }
+                       outSISIDXREG(SISCR, 0x85, v1);
+                       outSISIDXREG(SISCR, 0x82, v2);
+               }
+               if(ivideo->chip == XGI_40) {
+                       outSISIDXREG(SISCR, 0x97, 0x11);
+               }
+               if((ivideo->chip == XGI_40) && (ivideo->revision_id == 2)) {
+                       outSISIDXREG(SISCR, 0x98, 0x01);
+               } else {
+                       outSISIDXREG(SISCR, 0x98, 0x03);
+               }
+               outSISIDXREG(SISCR, 0x9a, 0x02);
 
-       v1 = 0xf6; v2 = 0x0d; v3 = 0x33;
-       if(ivideo->sishw_ext.UseROM) {
-          v1 = ivideo->sishw_ext.pjVirtualRomBase[0x9c];
-          v2 = ivideo->sishw_ext.pjVirtualRomBase[0x9d];
-          v3 = ivideo->sishw_ext.pjVirtualRomBase[0x9e];
+               if(ivideo->chip == XGI_40) {
+                       outSISIDXREG(SISSR, 0x18, 0x01);
+               } else {
+                       outSISIDXREG(SISSR, 0x18, 0x00);
+               }
+               outSISIDXREG(SISSR, 0x19, 0x40);
+               outSISIDXREG(SISSR, 0x16, 0x00);
+               outSISIDXREG(SISSR, 0x16, 0x80);
+               if((ivideo->chip == XGI_40) && (bios[0x1cb] != 0x0c)) {
+                       sisfb_post_xgi_delay(ivideo, 0x43);
+                       sisfb_post_xgi_delay(ivideo, 0x43);
+                       sisfb_post_xgi_delay(ivideo, 0x43);
+                       outSISIDXREG(SISSR, 0x18, 0x00);
+                       outSISIDXREG(SISSR, 0x19, 0x40);
+                       outSISIDXREG(SISSR, 0x16, 0x00);
+                       outSISIDXREG(SISSR, 0x16, 0x80);
+               }
+               sisfb_post_xgi_delay(ivideo, 4);
+               v1 = 0x31;
+               if(ivideo->haveXGIROM) {
+                       v1 = bios[0xf0];
+               }
+               outSISIDXREG(SISSR, 0x18, v1);
+               outSISIDXREG(SISSR, 0x19, 0x01);
+               if(ivideo->chip == XGI_40) {
+                       outSISIDXREG(SISSR, 0x16, bios[0x53e]);
+                       outSISIDXREG(SISSR, 0x16, bios[0x53f]);
+               } else {
+                       outSISIDXREG(SISSR, 0x16, 0x05);
+                       outSISIDXREG(SISSR, 0x16, 0x85);
+               }
+               sisfb_post_xgi_delay(ivideo, 0x43);
+               if(ivideo->chip == XGI_40) {
+                       outSISIDXREG(SISSR, 0x1b, 0x01);
+               } else {
+                       outSISIDXREG(SISSR, 0x1b, 0x03);
+               }
+               sisfb_post_xgi_delay(ivideo, 0x22);
+               outSISIDXREG(SISSR, 0x18, v1);
+               outSISIDXREG(SISSR, 0x19, 0x00);
+               if(ivideo->chip == XGI_40) {
+                       outSISIDXREG(SISSR, 0x16, bios[0x540]);
+                       outSISIDXREG(SISSR, 0x16, bios[0x541]);
+               } else {
+                       outSISIDXREG(SISSR, 0x16, 0x05);
+                       outSISIDXREG(SISSR, 0x16, 0x85);
+               }
+               outSISIDXREG(SISSR, 0x1b, 0x00);
        }
-       outSISIDXREG(SISSR,0x23,v1);
-       outSISIDXREG(SISSR,0x24,v2);
-       outSISIDXREG(SISSR,0x25,v3);
 
-       outSISIDXREG(SISSR,0x21,0x84);
-       outSISIDXREG(SISSR,0x22,0x00);
-       outSISIDXREG(SISSR,0x27,0x1f);
-
-       v1 = 0x00; v2 = 0x00;
-       if(ivideo->sishw_ext.UseROM) {
-          v1 = ivideo->sishw_ext.pjVirtualRomBase[0x9F];
-          v2 = ivideo->sishw_ext.pjVirtualRomBase[0xA1];
-       }
-       outSISIDXREG(SISSR,0x31,v1);
-       outSISIDXREG(SISSR,0x33,v2);
-
-       v1 = 0x11;
-       if(ivideo->sishw_ext.UseROM) {
-          v1 = ivideo->sishw_ext.pjVirtualRomBase[0xA0];
-       }
-       v2 = inSISIDXREG(SISPART4,0x00);
-       if((v2 != 1) && (v2 != 2)) v1 &= 0xef;
-       outSISIDXREG(SISSR,0x32,v1);
-
-       /* AGP */
-       pci_read_config_long(pdev, 0x50, &reg1_32);
-       reg1_32 >>= 20;
-       reg1_32 &= 0x0f;
-       if(reg1_32 == 1) {
-          v1 = 0xAA; v2 = 0x33;
-          if(ivideo->sishw_ext.UseROM) {
-             v1 = ivideo->sishw_ext.pjVirtualRomBase[0xF7];
-             v2 = ivideo->sishw_ext.pjVirtualRomBase[0x9E];
-          }
-       } else {
-          v1 = 0x88; v2 = 0x03;
-          if(ivideo->sishw_ext.UseROM) {
-             v1 = ivideo->sishw_ext.pjVirtualRomBase[0xF8];
-             v2 = ivideo->sishw_ext.pjVirtualRomBase[0xF6];
-          }
+       regb = 0;       /* ! */
+       v1 = 0x03;
+       if(ivideo->haveXGIROM) {
+               v1 = bios[0x110 + regb];
        }
-       outSISIDXREG(SISCR,0x49,v1);
-       outSISIDXREG(SISSR,0x25,v2);
+       outSISIDXREG(SISSR, 0x1b, v1);
 
-       v1 = inSISIDXREG(SISPART4,0x00);
-       if((v1 == 1) || (v1 == 2)) {
-          orSISIDXREG(SISPART1,0x2F,0x01);  /* Unlock CRT2 */
-          outSISIDXREG(SISPART1,0x00,0x00);
-          v1 = 0x00;
-          if(ivideo->sishw_ext.UseROM) {
-             v1 = ivideo->sishw_ext.pjVirtualRomBase[0xb6];
-          }
-          outSISIDXREG(SISPART1,0x02,v1);
-          outSISIDXREG(SISPART1,0x2E,0x08);
-          outSISIDXREG(SISPART2,0x00,0x1c);
-          v1 = 0x40; v2 = 0x00; v3 = 0x80;
-          if(ivideo->sishw_ext.UseROM) {
-             v1 = ivideo->sishw_ext.pjVirtualRomBase[0xb7];
-             v2 = ivideo->sishw_ext.pjVirtualRomBase[0xb8];
-             v3 = ivideo->sishw_ext.pjVirtualRomBase[0xbb];
-          }
-          outSISIDXREG(SISPART4,0x0d,v1);
-          outSISIDXREG(SISPART4,0x0e,v2);
-          outSISIDXREG(SISPART4,0x10,v3);
-          outSISIDXREG(SISPART4,0x0F,0x3F);
-
-          inSISIDXREG(SISPART4,0x01,reg);
-          if(reg >= 0xb0) {
-             inSISIDXREG(SISPART4,0x23,reg);
-             reg &= 0x20;
-             reg <<= 1;
-             outSISIDXREG(SISPART4,0x23,reg);
-          }
+       /* RAM size */
+       v1 = 0x00; v2 = 0x00;
+       if(ivideo->haveXGIROM) {
+               v1 = bios[0x62];
+               v2 = bios[0x63];
        }
-       outSISIDXREG(SISCR,0x37,0x02); /* Why? */
-
-       outSISIDXREG(SISCR,0x83,0x00);
-       outSISIDXREG(SISCR,0x90,0x00);
-       andSISIDXREG(SISSR,0x5B,0xDF);
-       outSISIDXREG(SISVID,0x00,0x86);
-       outSISIDXREG(SISVID,0x32,0x00);
-       outSISIDXREG(SISVID,0x30,0x00);
-       outSISIDXREG(SISVID,0x32,0x01);
-       outSISIDXREG(SISVID,0x30,0x00);
-       orSISIDXREG(SISCR,0x63,0x80);
-       /* End of Init1 */
-
-       /* Set Mode 0x2e */
-
-       /* Ramsize */
-       orSISIDXREG(SISSR,0x16,0x0f);
-       orSISIDXREG(SISSR,0x18,0xA9);
-       orSISIDXREG(SISSR,0x19,0xA0);
-       orSISIDXREG(SISSR,0x1B,0x30);
-       andSISIDXREG(SISSR,0x17,0xF8);
-       orSISIDXREG(SISSR,0x19,0x03);
-       andSIDIDXREG(SISSR,0x13,0x00);
+       regb = 0;       /* ! */
+       regd = 1 << regb;
+       if((v1 & 0x40) && (v2 & regd) && ivideo->haveXGIROM) {
 
-       /* Need to map max FB size for finding out about RAM size */
-       ivideo->video_vbase = ioremap(ivideo->video_base, 0x4000000);
-       if(ivideo->video_vbase) {
-          /* Find out about bus width */
-          if(memtype <= 1) {
-             outSISIDXREG(SISSR,0x14,0x02);
-             andSISIDXREG(SISSR,0x16,0x0F);
-             orSISIDXREG(SISSR,0x16,0x80);
+               outSISIDXREG(SISSR, 0x13, bios[regb + 0xe0]);
+               outSISIDXREG(SISSR, 0x14, bios[regb + 0xe0 + 8]);
 
-             ...
+       } else {
 
-          } else {
+               /* Set default mode, don't clear screen */
+               ivideo->SiS_Pr.SiS_UseOEM = FALSE;
+               SiS_SetEnableDstn(&ivideo->SiS_Pr, FALSE);
+               SiS_SetEnableFstn(&ivideo->SiS_Pr, FALSE);
+               ivideo->curFSTN = ivideo->curDSTN = 0;
+               ivideo->SiS_Pr.VideoMemorySize = 8 << 20;
+               SiSSetMode(&ivideo->SiS_Pr, 0x2e | 0x80);
 
-             ...
+               outSISIDXREG(SISSR, 0x05, 0x86);
 
-          }
+               /* Disable read-cache */
+               andSISIDXREG(SISSR, 0x21, 0xdf);
+               sisfb_post_xgi_ramsize(ivideo);
+               /* Enable read-cache */
+               orSISIDXREG(SISSR, 0x21, 0x20);
 
-          /* Find out about size */
+       }
 
+#if 0
+       printk(KERN_DEBUG "-----------------\n");
+       for(i = 0; i < 0xff; i++) {
+               inSISIDXREG(SISCR, i, reg);
+               printk(KERN_DEBUG "CR%02x(%x) = 0x%02x\n", i, SISCR, reg);
+       }
+       for(i = 0; i < 0x40; i++) {
+               inSISIDXREG(SISSR, i, reg);
+               printk(KERN_DEBUG "SR%02x(%x) = 0x%02x\n", i, SISSR, reg);
+       }
+       printk(KERN_DEBUG "-----------------\n");
+#endif
 
-          iounmap(ivideo->video_vbase);
+       /* Sense CRT1 */
+       if(ivideo->chip == XGI_20) {
+               orSISIDXREG(SISCR, 0x32, 0x20);
        } else {
-          printk(KERN_DEBUG "sisfb: Failed to map memory for size detection, assuming 8MB\n");
-          outSISIDXREG(SISSR,0x14,0x??);  /* 8MB, 64bit default */
+               inSISIDXREG(SISPART4, 0x00, reg);
+               if((reg == 1) || (reg == 2)) {
+                       sisfb_sense_crt1(ivideo);
+               } else {
+                       orSISIDXREG(SISCR, 0x32, 0x20);
+               }
        }
 
-       /* AGP (Missing: Checks for VIA and AMD hosts) */
-       v1 = 0xA5; v2 = 0xFB;
-       if(ivideo->sishw_ext.UseROM) {
-          v1 = ivideo->sishw_ext.pjVirtualRomBase[0x9A];
-          v2 = ivideo->sishw_ext.pjVirtualRomBase[0x9B];
+       /* Set default mode, don't clear screen */
+       ivideo->SiS_Pr.SiS_UseOEM = FALSE;
+       SiS_SetEnableDstn(&ivideo->SiS_Pr, FALSE);
+       SiS_SetEnableFstn(&ivideo->SiS_Pr, FALSE);
+       ivideo->curFSTN = ivideo->curDSTN = 0;
+       SiSSetMode(&ivideo->SiS_Pr, 0x2e | 0x80);
+
+       outSISIDXREG(SISSR, 0x05, 0x86);
+
+       /* Display off */
+       orSISIDXREG(SISSR, 0x01, 0x20);
+
+       /* Save mode number in CR34 */
+       outSISIDXREG(SISCR, 0x34, 0x2e);
+
+       /* Let everyone know what the current mode is */
+       ivideo->modeprechange = 0x2e;
+
+       if(ivideo->chip == XGI_40) {
+               inSISIDXREG(SISCR, 0xca, reg);
+               inSISIDXREG(SISCR, 0xcc, v1);
+               if((reg & 0x10) && (!(v1 & 0x04))) {
+                       printk(KERN_ERR
+                               "sisfb: Please connect power to the card.\n");
+                       return 0;
+               }
        }
-       outSISIDXREG(SISSR,0x21,v1);
-       outSISIDXREG(SISSR,0x22,v2);
 
-#endif
-       return;
+       return 1;
 }
 #endif
 
-
-static int __devinit sisfb_probe(struct pci_dev *pdev,
-                                const struct pci_device_id *ent)
+static int __devinit
+sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
-       struct sisfb_chip_info  *chipinfo = &sisfb_chip_info[ent->driver_data];
-       struct sis_video_info   *ivideo = NULL;
-       struct fb_info          *sis_fb_info = NULL;
+       struct sisfb_chip_info  *chipinfo = &sisfb_chip_info[ent->driver_data];
+       struct sis_video_info   *ivideo = NULL;
+       struct fb_info          *sis_fb_info = NULL;
        u16 reg16;
        u8  reg;
-       int sisvga_enabled = 0, i;
+       int i, ret;
 
-       if(sisfb_off) return -ENXIO;
+       if(sisfb_off)
+               return -ENXIO;
 
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,3))
        sis_fb_info = framebuffer_alloc(sizeof(*ivideo), &pdev->dev);
-       if(!sis_fb_info) return -ENOMEM;
+       if(!sis_fb_info)
+               return -ENOMEM;
 #else
        sis_fb_info = kmalloc(sizeof(*sis_fb_info) + sizeof(*ivideo), GFP_KERNEL);
-       if(!sis_fb_info) return -ENOMEM;
+       if(!sis_fb_info)
+               return -ENOMEM;
        memset(sis_fb_info, 0, sizeof(*sis_fb_info) + sizeof(*ivideo));
        sis_fb_info->par = ((char *)sis_fb_info + sizeof(*sis_fb_info));
 #endif
@@ -4787,27 +5890,34 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
        ivideo = (struct sis_video_info *)sis_fb_info->par;
        ivideo->memyselfandi = sis_fb_info;
 
+       ivideo->sisfb_id = SISFB_ID;
+
        if(card_list == NULL) {
-          ivideo->cardnumber = 0;
+               ivideo->cardnumber = 0;
        } else {
-          struct sis_video_info *countvideo = card_list;
-          ivideo->cardnumber = 1;
-          while((countvideo = countvideo->next) != NULL) ivideo->cardnumber++;
+               struct sis_video_info *countvideo = card_list;
+               ivideo->cardnumber = 1;
+               while((countvideo = countvideo->next) != 0)
+                       ivideo->cardnumber++;
        }
 
        strncpy(ivideo->myid, chipinfo->chip_name, 30);
 
        ivideo->warncount = 0;
        ivideo->chip_id = pdev->device;
+       ivideo->chip_vendor = pdev->vendor;
        pci_read_config_byte(pdev, PCI_REVISION_ID, &ivideo->revision_id);
-       ivideo->sishw_ext.jChipRevision = ivideo->revision_id;
+       ivideo->SiS_Pr.ChipRevision = ivideo->revision_id;
        pci_read_config_word(pdev, PCI_COMMAND, &reg16);
-       sisvga_enabled = reg16 & 0x01;
+       ivideo->sisvga_enabled = reg16 & 0x01;
        ivideo->pcibus = pdev->bus->number;
        ivideo->pcislot = PCI_SLOT(pdev->devfn);
        ivideo->pcifunc = PCI_FUNC(pdev->devfn);
        ivideo->subsysvendor = pdev->subsystem_vendor;
        ivideo->subsysdevice = pdev->subsystem_device;
+#ifdef SIS_OLD_CONFIG_COMPAT
+       ivideo->ioctl32registered = 0;
+#endif
 
 #ifndef MODULE
        if(sisfb_mode_idx == -1) {
@@ -4827,6 +5937,24 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
 
        ivideo->sisfb_thismonitor.datavalid = FALSE;
 
+       ivideo->current_base = 0;
+
+       ivideo->engineok = 0;
+
+       ivideo->sisfb_was_boot_device = 0;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12))
+       if(pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW) {
+               if(ivideo->sisvga_enabled)
+                       ivideo->sisfb_was_boot_device = 1;
+               else {
+                       printk(KERN_DEBUG "sisfb: PCI device is disabled, "
+                               "but marked as boot video device ???\n");
+                       printk(KERN_DEBUG "sisfb: I will not accept this "
+                               "as the primary VGA device\n");
+               }
+       }
+#endif
+
        ivideo->sisfb_parm_mem = sisfb_parm_mem;
        ivideo->sisfb_accel = sisfb_accel;
        ivideo->sisfb_ypan = sisfb_ypan;
@@ -4846,7 +5974,6 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
        ivideo->sisfb_tvstd = sisfb_tvstd;
        ivideo->tvxpos = sisfb_tvxposoffset;
        ivideo->tvypos = sisfb_tvyposoffset;
-       ivideo->sisfb_filter = sisfb_filter;
        ivideo->sisfb_nocrt2rate = sisfb_nocrt2rate;
 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
        ivideo->sisfb_inverse = sisfb_inverse;
@@ -4854,7 +5981,7 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
 
        ivideo->refresh_rate = 0;
        if(ivideo->sisfb_parm_rate != -1) {
-          ivideo->refresh_rate = ivideo->sisfb_parm_rate;
+               ivideo->refresh_rate = ivideo->sisfb_parm_rate;
        }
 
        ivideo->SiS_Pr.UsePanelScaler = sisfb_scalelcd;
@@ -4863,8 +5990,8 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
        ivideo->SiS_Pr.LVDSHL = sisfb_lvdshl;
 
        ivideo->SiS_Pr.SiS_Backup70xx = 0xff;
-        ivideo->SiS_Pr.SiS_CHOverScan = -1;
-        ivideo->SiS_Pr.SiS_ChSW = FALSE;
+       ivideo->SiS_Pr.SiS_CHOverScan = -1;
+       ivideo->SiS_Pr.SiS_ChSW = FALSE;
        ivideo->SiS_Pr.SiS_UseLCDA = FALSE;
        ivideo->SiS_Pr.HaveEMI = FALSE;
        ivideo->SiS_Pr.HaveEMILCD = FALSE;
@@ -4873,12 +6000,13 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
        ivideo->SiS_Pr.SiS_MyCR63 = 0x63;
        ivideo->SiS_Pr.PDC  = -1;
        ivideo->SiS_Pr.PDCA = -1;
+       ivideo->SiS_Pr.DDCPortMixup = FALSE;
 #ifdef CONFIG_FB_SIS_315
        if(ivideo->chip >= SIS_330) {
-          ivideo->SiS_Pr.SiS_MyCR63 = 0x53;
-          if(ivideo->chip >= SIS_661) {
-             ivideo->SiS_Pr.SiS_SensibleSR11 = TRUE;
-          }
+               ivideo->SiS_Pr.SiS_MyCR63 = 0x53;
+               if(ivideo->chip >= SIS_661) {
+                       ivideo->SiS_Pr.SiS_SensibleSR11 = TRUE;
+               }
        }
 #endif
 
@@ -4891,9 +6019,9 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
                switch(ivideo->nbridge->device) {
 #ifdef CONFIG_FB_SIS_300
                case PCI_DEVICE_ID_SI_730:
-                       ivideo->chip = SIS_730;
+                       ivideo->chip = SIS_730;
                        strcpy(ivideo->myid, "SiS 730");
-                       break;
+                       break;
 #endif
 #ifdef CONFIG_FB_SIS_315
                case PCI_DEVICE_ID_SI_651:
@@ -4901,22 +6029,28 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
                        strcpy(ivideo->myid, "SiS 651");
                        break;
                case PCI_DEVICE_ID_SI_740:
-                       ivideo->chip = SIS_740;
+                       ivideo->chip = SIS_740;
                        strcpy(ivideo->myid, "SiS 740");
                        break;
                case PCI_DEVICE_ID_SI_661:
-                       ivideo->chip = SIS_661;
+                       ivideo->chip = SIS_661;
                        strcpy(ivideo->myid, "SiS 661");
                        break;
                case PCI_DEVICE_ID_SI_741:
-                       ivideo->chip = SIS_741;
+                       ivideo->chip = SIS_741;
                        strcpy(ivideo->myid, "SiS 741");
                        break;
                case PCI_DEVICE_ID_SI_760:
-                       ivideo->chip = SIS_760;
+                       ivideo->chip = SIS_760;
                        strcpy(ivideo->myid, "SiS 760");
                        break;
+               case PCI_DEVICE_ID_SI_761:
+                       ivideo->chip = SIS_761;
+                       strcpy(ivideo->myid, "SiS 761");
+                       break;
 #endif
+               default:
+                       break;
                }
        }
 
@@ -4924,71 +6058,83 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
        strcpy(sis_fb_info->modename, ivideo->myid);
 #endif
 
-       ivideo->sishw_ext.jChipType = ivideo->chip;
+       ivideo->SiS_Pr.ChipType = ivideo->chip;
+
+       ivideo->SiS_Pr.ivideo = (void *)ivideo;
 
 #ifdef CONFIG_FB_SIS_315
-       if((ivideo->sishw_ext.jChipType == SIS_315PRO) ||
-          (ivideo->sishw_ext.jChipType == SIS_315)) {
-               ivideo->sishw_ext.jChipType = SIS_315H;
+       if((ivideo->SiS_Pr.ChipType == SIS_315PRO) ||
+          (ivideo->SiS_Pr.ChipType == SIS_315)) {
+               ivideo->SiS_Pr.ChipType = SIS_315H;
        }
 #endif
 
+       if(!ivideo->sisvga_enabled) {
+               if(pci_enable_device(pdev)) {
+                       if(ivideo->nbridge) SIS_PCI_PUT_DEVICE(ivideo->nbridge);
+                       pci_set_drvdata(pdev, NULL);
+                       kfree(sis_fb_info);
+                       return -EIO;
+               }
+       }
+
        ivideo->video_base = pci_resource_start(pdev, 0);
        ivideo->mmio_base  = pci_resource_start(pdev, 1);
        ivideo->mmio_size  = pci_resource_len(pdev, 1);
-       ivideo->SiS_Pr.RelIO = pci_resource_start(pdev, 2) + 0x30;
-       ivideo->sishw_ext.ulIOAddress = ivideo->vga_base = ivideo->SiS_Pr.RelIO;
-
-       if(!sisvga_enabled) {
-               if(pci_enable_device(pdev)) {
-                       pci_set_drvdata(pdev, NULL);
-                       kfree(sis_fb_info);
-                       return -EIO;
-               }
-       }
+       ivideo->SiS_Pr.RelIO = pci_resource_start(pdev, 2) + 0x30;
+       ivideo->SiS_Pr.IOAddress = ivideo->vga_base = ivideo->SiS_Pr.RelIO;
 
-       SiSRegInit(&ivideo->SiS_Pr, ivideo->sishw_ext.ulIOAddress);
+       SiSRegInit(&ivideo->SiS_Pr, ivideo->SiS_Pr.IOAddress);
 
 #ifdef CONFIG_FB_SIS_300
        /* Find PCI systems for Chrontel/GPIO communication setup */
        if(ivideo->chip == SIS_630) {
-          i=0;
-           do {
-             if(mychswtable[i].subsysVendor == ivideo->subsysvendor &&
-                mychswtable[i].subsysCard   == ivideo->subsysdevice) {
-                ivideo->SiS_Pr.SiS_ChSW = TRUE;
-                printk(KERN_DEBUG "sisfb: Identified [%s %s] requiring Chrontel/GPIO setup\n",
-                       mychswtable[i].vendorName, mychswtable[i].cardName);
-                break;
-              }
-              i++;
-           } while(mychswtable[i].subsysVendor != 0);
+               i = 0;
+               do {
+                       if(mychswtable[i].subsysVendor == ivideo->subsysvendor &&
+                          mychswtable[i].subsysCard   == ivideo->subsysdevice) {
+                               ivideo->SiS_Pr.SiS_ChSW = TRUE;
+                               printk(KERN_DEBUG "sisfb: Identified [%s %s] "
+                                       "requiring Chrontel/GPIO setup\n",
+                                       mychswtable[i].vendorName,
+                                       mychswtable[i].cardName);
+                               ivideo->lpcdev = SIS_PCI_GET_DEVICE(PCI_VENDOR_ID_SI, 0x0008, NULL);
+                               break;
+                       }
+                       i++;
+               } while(mychswtable[i].subsysVendor != 0);
+       }
+#endif
+
+#ifdef CONFIG_FB_SIS_315
+       if((ivideo->chip == SIS_760) && (ivideo->nbridge)) {
+               ivideo->lpcdev = SIS_PCI_GET_SLOT(ivideo->nbridge->bus, (2 << 3));
        }
 #endif
 
-        outSISIDXREG(SISSR, 0x05, 0x86);
+       outSISIDXREG(SISSR, 0x05, 0x86);
 
-       if( (!sisvga_enabled)
+       if( (!ivideo->sisvga_enabled)
 #if !defined(__i386__) && !defined(__x86_64__)
-                             || (sisfb_resetcard)
+                             || (sisfb_resetcard)
 #endif
-                                                  ) {
-               for(i = 0x30; i <= 0x3f; i++) {
-                       outSISIDXREG(SISCR,i,0x00);
-               }
+                                                  ) {
+               for(i = 0x30; i <= 0x3f; i++) {
+                       outSISIDXREG(SISCR, i, 0x00);
+               }
        }
 
        /* Find out about current video mode */
        ivideo->modeprechange = 0x03;
-       inSISIDXREG(SISCR,0x34,reg);
+       inSISIDXREG(SISCR, 0x34, reg);
        if(reg & 0x7f) {
                ivideo->modeprechange = reg & 0x7f;
-       } else if(sisvga_enabled) {
+       } else if(ivideo->sisvga_enabled) {
 #if defined(__i386__) || defined(__x86_64__)
-               unsigned char SIS_IOTYPE2 *tt = ioremap(0, 0x1000);
+               unsigned char SIS_IOTYPE2 *tt = ioremap(0x400, 0x100);
                if(tt) {
-                       ivideo->modeprechange = readb(tt + 0x449);
-                       iounmap(tt);
+                       ivideo->modeprechange = readb(tt + 0x49);
+                       iounmap(tt);
                }
 #endif
        }
@@ -4996,219 +6142,221 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 #ifdef MODULE
        if((reg & 0x80) && (reg != 0xff)) {
-          if((sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni]) != 0xFF) {
-             printk(KERN_INFO "sisfb: Cannot initialize display mode, X server is active\n");
-             pci_set_drvdata(pdev, NULL);
-             kfree(sis_fb_info);
-             return -EBUSY;
-          }
+               if((sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni])
+                                                                       != 0xFF) {
+                       printk(KERN_INFO "sisfb: Cannot initialize display mode, "
+                                        "X server is active\n");
+                       ret = -EBUSY;
+                       goto error_4;
+               }
        }
-#endif 
 #endif
-
-       ivideo->sishw_ext.bIntegratedMMEnabled = TRUE;
-#ifdef CONFIG_FB_SIS_300
-       if(ivideo->sisvga_engine == SIS_300_VGA) {
-          if(ivideo->chip != SIS_300) {
-             inSISIDXREG(SISSR, 0x1a, reg);
-             if(!(reg & 0x10)) {
-                ivideo->sishw_ext.bIntegratedMMEnabled = FALSE;
-             }
-          }
-       }
 #endif
 
+       /* Search and copy ROM image */
        ivideo->bios_abase = NULL;
+       ivideo->SiS_Pr.VirtualRomBase = NULL;
+       ivideo->SiS_Pr.UseROM = FALSE;
+       ivideo->haveXGIROM = ivideo->SiS_Pr.SiS_XGIROM = FALSE;
        if(ivideo->sisfb_userom) {
-           ivideo->sishw_ext.pjVirtualRomBase = sis_find_rom(pdev);
-           ivideo->bios_abase = ivideo->sishw_ext.pjVirtualRomBase;
-           if(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;
-               printk(KERN_INFO "sisfb: Video ROM not found\n");
-           }
+               ivideo->SiS_Pr.VirtualRomBase = sisfb_find_rom(pdev);
+               ivideo->bios_abase = ivideo->SiS_Pr.VirtualRomBase;
+               ivideo->SiS_Pr.UseROM = (ivideo->SiS_Pr.VirtualRomBase) ? TRUE : FALSE;
+               printk(KERN_INFO "sisfb: Video ROM %sfound\n",
+                       ivideo->SiS_Pr.UseROM ? "" : "not ");
+               if((ivideo->SiS_Pr.UseROM) && (ivideo->chip >= XGI_20)) {
+                  ivideo->SiS_Pr.UseROM = FALSE;
+                  ivideo->haveXGIROM = ivideo->SiS_Pr.SiS_XGIROM = TRUE;
+                  if( (ivideo->revision_id == 2) &&
+                      (!(ivideo->bios_abase[0x1d1] & 0x01)) ) {
+                       ivideo->SiS_Pr.DDCPortMixup = TRUE;
+                  }
+               }
        } else {
-           ivideo->sishw_ext.pjVirtualRomBase = NULL;
-           ivideo->sishw_ext.UseROM = FALSE;
-           printk(KERN_INFO "sisfb: Video ROM usage disabled\n");
+               printk(KERN_INFO "sisfb: Video ROM usage disabled\n");
        }
 
-        /* Find systems for special custom timing */
+       /* Find systems for special custom timing */
        if(ivideo->SiS_Pr.SiS_CustomT == CUT_NONE) {
-          int j;
-          unsigned char *biosver = NULL;
-           unsigned char *biosdate = NULL;
-          BOOLEAN footprint;
-          u32 chksum = 0;
-
-          if(ivideo->sishw_ext.UseROM) {
-             biosver = ivideo->sishw_ext.pjVirtualRomBase + 0x06;
-             biosdate = ivideo->sishw_ext.pjVirtualRomBase + 0x2c;
-              for(i=0; i<32768; i++) chksum += ivideo->sishw_ext.pjVirtualRomBase[i];
-          }
-
-          i=0;
-           do {
-             if( (mycustomttable[i].chipID == ivideo->chip) &&
-                 ((!strlen(mycustomttable[i].biosversion)) ||
-                  (ivideo->sishw_ext.UseROM &&
-                  (!strncmp(mycustomttable[i].biosversion, biosver, strlen(mycustomttable[i].biosversion))))) &&
-                 ((!strlen(mycustomttable[i].biosdate)) ||
-                  (ivideo->sishw_ext.UseROM &&
-                  (!strncmp(mycustomttable[i].biosdate, biosdate, strlen(mycustomttable[i].biosdate))))) &&
-                 ((!mycustomttable[i].bioschksum) ||
-                  (ivideo->sishw_ext.UseROM &&
-                  (mycustomttable[i].bioschksum == chksum)))   &&
-                 (mycustomttable[i].pcisubsysvendor == ivideo->subsysvendor) &&
-                 (mycustomttable[i].pcisubsyscard == ivideo->subsysdevice) ) {
-                footprint = TRUE;
-                for(j = 0; j < 5; j++) {
-                   if(mycustomttable[i].biosFootprintAddr[j]) {
-                      if(ivideo->sishw_ext.UseROM) {
-                         if(ivideo->sishw_ext.pjVirtualRomBase[mycustomttable[i].biosFootprintAddr[j]] !=
-                               mycustomttable[i].biosFootprintData[j]) {
-                            footprint = FALSE;
-                         }
-                      } else footprint = FALSE;
-                   }
-                }
-                if(footprint) {
-                   ivideo->SiS_Pr.SiS_CustomT = mycustomttable[i].SpecialID;
-                   printk(KERN_DEBUG "sisfb: Identified [%s %s], special timing applies\n",
-                       mycustomttable[i].vendorName,
-                       mycustomttable[i].cardName);
-                   printk(KERN_DEBUG "sisfb: [specialtiming parameter name: %s]\n",
-                       mycustomttable[i].optionName);
-                   break;
-                 }
-             }
-              i++;
-           } while(mycustomttable[i].chipID);
+               sisfb_detect_custom_timing(ivideo);
        }
 
-#ifdef CONFIG_FB_SIS_300
-       if(ivideo->sisvga_engine == SIS_300_VGA) {
-               if( (!sisvga_enabled)
+       /* POST card in case this has not been done by the BIOS */
+       if( (!ivideo->sisvga_enabled)
 #if !defined(__i386__) && !defined(__x86_64__)
-                                     || (sisfb_resetcard)
+                            || (sisfb_resetcard)
 #endif
-                                                          ) {
+                                                ) {
+#ifdef CONFIG_FB_SIS_300
+               if(ivideo->sisvga_engine == SIS_300_VGA) {
                        if(ivideo->chip == SIS_300) {
                                sisfb_post_sis300(pdev);
+                               ivideo->sisfb_can_post = 1;
                        }
                }
-       }
 #endif
 
 #ifdef CONFIG_FB_SIS_315
-       if(ivideo->sisvga_engine == SIS_315_VGA) {
-               if( (!sisvga_enabled)
-#if !defined(__i386__) && !defined(__x86_64__)
-                                    || (sisfb_resetcard)
-#endif
-                                                         ) {
-                       if((ivideo->chip == SIS_315H)   ||
+               if(ivideo->sisvga_engine == SIS_315_VGA) {
+                       int result = 1;
+               /*      if((ivideo->chip == SIS_315H)   ||
                           (ivideo->chip == SIS_315)    ||
                           (ivideo->chip == SIS_315PRO) ||
                           (ivideo->chip == SIS_330)) {
                                sisfb_post_sis315330(pdev);
+                       } else */ if(ivideo->chip == XGI_20) {
+                               result = sisfb_post_xgi(pdev);
+                               ivideo->sisfb_can_post = 1;
+                       } else if((ivideo->chip == XGI_40) && ivideo->haveXGIROM) {
+                               result = sisfb_post_xgi(pdev);
+                               ivideo->sisfb_can_post = 1;
+                       } else {
+                               printk(KERN_INFO "sisfb: Card is not "
+                                       "POSTed and sisfb can't do this either.\n");
+                       }
+                       if(!result) {
+                               printk(KERN_ERR "sisfb: Failed to POST card\n");
+                               ret = -ENODEV;
+                               goto error_3;
                        }
                }
-       }
 #endif
+       }
 
+       ivideo->sisfb_card_posted = 1;
+
+       /* Find out about RAM size */
        if(sisfb_get_dram_size(ivideo)) {
-               printk(KERN_INFO "sisfb: Fatal error: Unable to determine RAM size.\n");
-               if(ivideo->bios_abase) vfree(ivideo->bios_abase);
-               pci_set_drvdata(pdev, NULL);
-               kfree(sis_fb_info);
-               return -ENODEV;
+               printk(KERN_INFO "sisfb: Fatal error: Unable to determine VRAM size.\n");
+               ret = -ENODEV;
+               goto error_3;
        }
 
+
+       /* Enable PCI addressing and MMIO */
        if((ivideo->sisfb_mode_idx < 0) ||
           ((sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni]) != 0xFF)) {
-               /* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE  */
-               orSISIDXREG(SISSR, IND_SIS_PCI_ADDRESS_SET, (SIS_PCI_ADDR_ENABLE | SIS_MEM_MAP_IO_ENABLE));
-                /* Enable 2D accelerator engine */
-               orSISIDXREG(SISSR, IND_SIS_MODULE_ENABLE, SIS_ENABLE_2D);
+               /* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE  */
+               orSISIDXREG(SISSR, IND_SIS_PCI_ADDRESS_SET, (SIS_PCI_ADDR_ENABLE | SIS_MEM_MAP_IO_ENABLE));
+               /* Enable 2D accelerator engine */
+               orSISIDXREG(SISSR, IND_SIS_MODULE_ENABLE, SIS_ENABLE_2D);
        }
 
        if(sisfb_pdc != 0xff) {
-          if(ivideo->sisvga_engine == SIS_300_VGA) sisfb_pdc &= 0x3c;
-          else                                     sisfb_pdc &= 0x1f;
-          ivideo->SiS_Pr.PDC = sisfb_pdc;
+               if(ivideo->sisvga_engine == SIS_300_VGA)
+                       sisfb_pdc &= 0x3c;
+               else
+                       sisfb_pdc &= 0x1f;
+               ivideo->SiS_Pr.PDC = sisfb_pdc;
        }
 #ifdef CONFIG_FB_SIS_315
        if(ivideo->sisvga_engine == SIS_315_VGA) {
-          if(sisfb_pdca != 0xff) ivideo->SiS_Pr.PDCA = sisfb_pdca & 0x1f;
+               if(sisfb_pdca != 0xff)
+                       ivideo->SiS_Pr.PDCA = sisfb_pdca & 0x1f;
        }
 #endif
 
        if(!request_mem_region(ivideo->video_base, ivideo->video_size, "sisfb FB")) {
-               printk(KERN_ERR "sisfb: Fatal error: Unable to reserve frame buffer memory\n");
+               printk(KERN_ERR "sisfb: Fatal error: Unable to reserve %dMB framebuffer memory\n",
+                               (int)(ivideo->video_size >> 20));
                printk(KERN_ERR "sisfb: Is there another framebuffer driver active?\n");
-               if(ivideo->bios_abase) vfree(ivideo->bios_abase);
-               pci_set_drvdata(pdev, NULL);
-               kfree(sis_fb_info);
-               return -ENODEV;
+               ret = -ENODEV;
+               goto error_3;
        }
 
        if(!request_mem_region(ivideo->mmio_base, ivideo->mmio_size, "sisfb MMIO")) {
                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);
-               pci_set_drvdata(pdev, NULL);
-               kfree(sis_fb_info);
-               return -ENODEV;
+               ret = -ENODEV;
+               goto error_2;
        }
 
        ivideo->video_vbase = ioremap(ivideo->video_base, ivideo->video_size);
-       ivideo->sishw_ext.pjVideoMemoryAddress = ivideo->video_vbase;
+       ivideo->SiS_Pr.VideoMemoryAddress = ivideo->video_vbase;
        if(!ivideo->video_vbase) {
-               printk(KERN_ERR "sisfb: Fatal error: Unable to map frame buffer memory\n");
-               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);
-               pci_set_drvdata(pdev, NULL);
-               kfree(sis_fb_info);
-               return -ENODEV;
+               printk(KERN_ERR "sisfb: Fatal error: Unable to map framebuffer memory\n");
+               ret = -ENODEV;
+               goto error_1;
        }
 
        ivideo->mmio_vbase = ioremap(ivideo->mmio_base, ivideo->mmio_size);
        if(!ivideo->mmio_vbase) {
-               printk(KERN_ERR "sisfb: Fatal error: Unable to map MMIO region\n");
-               iounmap(ivideo->video_vbase);
-               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);
+               printk(KERN_ERR "sisfb: Fatal error: Unable to map MMIO region\n");
+               ret = -ENODEV;
+error_0:       iounmap(ivideo->video_vbase);
+error_1:       release_mem_region(ivideo->video_base, ivideo->video_size);
+error_2:       release_mem_region(ivideo->mmio_base, ivideo->mmio_size);
+error_3:       vfree(ivideo->bios_abase);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+error_4:
+#endif
+               if(ivideo->lpcdev)
+                       SIS_PCI_PUT_DEVICE(ivideo->lpcdev);
+               if(ivideo->nbridge)
+                       SIS_PCI_PUT_DEVICE(ivideo->nbridge);
                pci_set_drvdata(pdev, NULL);
-               kfree(sis_fb_info);
-               return -ENODEV;
+               if(!ivideo->sisvga_enabled)
+                       pci_disable_device(pdev);
+               kfree(sis_fb_info);
+               return ret;
        }
 
-       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: Video RAM at 0x%lx, mapped to 0x%lx, size %ldk\n",
+               ivideo->video_base, (unsigned long)ivideo->video_vbase, ivideo->video_size / 1024);
+
+       if(ivideo->video_offset) {
+               printk(KERN_INFO "sisfb: Viewport offset %ldk\n",
+                       ivideo->video_offset / 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);
+               ivideo->mmio_base, (unsigned long)ivideo->mmio_vbase, ivideo->mmio_size / 1024);
+
+
+       /* Determine the size of the command queue */
+       if(ivideo->sisvga_engine == SIS_300_VGA) {
+               ivideo->cmdQueueSize = TURBO_QUEUE_AREA_SIZE;
+       } else {
+               if(ivideo->chip == XGI_20) {
+                       ivideo->cmdQueueSize = COMMAND_QUEUE_AREA_SIZE_Z7;
+               } else {
+                       ivideo->cmdQueueSize = COMMAND_QUEUE_AREA_SIZE;
+               }
+       }
 
+       /* Engines are no longer initialized here; this is
+        * now done after the first mode-switch (if the
+        * submitted var has its acceleration flags set).
+        */
+
+       /* Calculate the base of the (unused) hw cursor */
+       ivideo->hwcursor_vbase = ivideo->video_vbase
+                                + ivideo->video_size
+                                - ivideo->cmdQueueSize
+                                - ivideo->hwcursor_size;
+       ivideo->caps |= HW_CURSOR_CAP;
+
+       /* Initialize offscreen memory manager */
        if((ivideo->havenoheap = sisfb_heap_init(ivideo))) {
                printk(KERN_WARNING "sisfb: Failed to initialize offscreen memory heap\n");
        }
 
        /* Used for clearing the screen only, therefore respect our mem limit */
-       ivideo->sishw_ext.ulVideoMemorySize = ivideo->sisfb_mem;
+       ivideo->SiS_Pr.VideoMemoryAddress += ivideo->video_offset;
+       ivideo->SiS_Pr.VideoMemorySize = ivideo->sisfb_mem;
 
-       ivideo->mtrr = 0;
+       ivideo->mtrr = -1;
 
        ivideo->vbflags = 0;
        ivideo->lcddefmodeidx = DEFAULT_LCDMODE;
        ivideo->tvdefmodeidx  = DEFAULT_TVMODE;
        ivideo->defmodeidx    = DEFAULT_MODE;
 
-       ivideo->newrom = SiSDetermineROMLayout661(&ivideo->SiS_Pr, &ivideo->sishw_ext);
+       ivideo->newrom = 0;
+       if(ivideo->chip < XGI_20) {
+               if(ivideo->bios_abase) {
+                       ivideo->newrom = SiSDetermineROMLayout661(&ivideo->SiS_Pr);
+               }
+       }
 
        if((ivideo->sisfb_mode_idx < 0) ||
           ((sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni]) != 0xFF)) {
@@ -5217,192 +6365,57 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
 
                sisfb_get_VB_type(ivideo);
 
-               if(ivideo->vbflags & VB_VIDEOBRIDGE) {
+               if(ivideo->vbflags2 & VB2_VIDEOBRIDGE) {
                        sisfb_detect_VB_connect(ivideo);
                }
 
                ivideo->currentvbflags = ivideo->vbflags & (VB_VIDEOBRIDGE | TV_STANDARD);
 
-               if(ivideo->vbflags & VB_VIDEOBRIDGE) {
-                  if(ivideo->sisfb_crt2type != -1) {
-                     if((ivideo->sisfb_crt2type == CRT2_LCD) && (ivideo->vbflags & CRT2_LCD)) {
-                        ivideo->currentvbflags |= CRT2_LCD;
-                     } else if(ivideo->sisfb_crt2type != CRT2_LCD) {
-                        ivideo->currentvbflags |= ivideo->sisfb_crt2type;
-                     }
-                  } else {
-                     /* Chrontel 700x TV detection often unreliable, therefore use a
-                      * different default order on such machines
-                      */
-                     if((ivideo->sisvga_engine == SIS_300_VGA) && (ivideo->vbflags & VB_CHRONTEL)) {
-                        if(ivideo->vbflags & CRT2_LCD)      ivideo->currentvbflags |= CRT2_LCD;
-                        else if(ivideo->vbflags & CRT2_TV)  ivideo->currentvbflags |= CRT2_TV;
-                        else if(ivideo->vbflags & CRT2_VGA) ivideo->currentvbflags |= CRT2_VGA;
-                     } else {
-                        if(ivideo->vbflags & CRT2_TV)       ivideo->currentvbflags |= CRT2_TV;
-                        else if(ivideo->vbflags & CRT2_LCD) ivideo->currentvbflags |= CRT2_LCD;
-                        else if(ivideo->vbflags & CRT2_VGA) ivideo->currentvbflags |= CRT2_VGA;
-                     }
-                  }
+               /* Decide on which CRT2 device to use */
+               if(ivideo->vbflags2 & VB2_VIDEOBRIDGE) {
+                       if(ivideo->sisfb_crt2type != -1) {
+                               if((ivideo->sisfb_crt2type == CRT2_LCD) &&
+                                  (ivideo->vbflags & CRT2_LCD)) {
+                                       ivideo->currentvbflags |= CRT2_LCD;
+                               } else if(ivideo->sisfb_crt2type != CRT2_LCD) {
+                                       ivideo->currentvbflags |= ivideo->sisfb_crt2type;
+                               }
+                       } else {
+                               /* Chrontel 700x TV detection often unreliable, therefore
+                                * use a different default order on such machines
+                                */
+                               if((ivideo->sisvga_engine == SIS_300_VGA) &&
+                                  (ivideo->vbflags2 & VB2_CHRONTEL)) {
+                                       if(ivideo->vbflags & CRT2_LCD)
+                                               ivideo->currentvbflags |= CRT2_LCD;
+                                       else if(ivideo->vbflags & CRT2_TV)
+                                               ivideo->currentvbflags |= CRT2_TV;
+                                       else if(ivideo->vbflags & CRT2_VGA)
+                                               ivideo->currentvbflags |= CRT2_VGA;
+                               } else {
+                                       if(ivideo->vbflags & CRT2_TV)
+                                               ivideo->currentvbflags |= CRT2_TV;
+                                       else if(ivideo->vbflags & CRT2_LCD)
+                                               ivideo->currentvbflags |= CRT2_LCD;
+                                       else if(ivideo->vbflags & CRT2_VGA)
+                                               ivideo->currentvbflags |= CRT2_VGA;
+                               }
+                       }
                }
 
                if(ivideo->vbflags & CRT2_LCD) {
-                  inSISIDXREG(SISCR, 0x36, reg);
-                  reg &= 0x0f;
-                  if(ivideo->sisvga_engine == SIS_300_VGA) {
-                     ivideo->CRT2LCDType = sis300paneltype[reg];
-                  } else if(ivideo->chip >= SIS_661) {
-                     ivideo->CRT2LCDType = sis661paneltype[reg];
-                  } else {
-                     ivideo->CRT2LCDType = sis310paneltype[reg];
-                     if((ivideo->chip == SIS_550) && (sisfb_fstn)) {
-                        if((ivideo->CRT2LCDType != LCD_640x480_2) &&
-                           (ivideo->CRT2LCDType != LCD_640x480_3)) {
-                           ivideo->CRT2LCDType = LCD_320x480;
-                        }
-                     }
-                  }
-                  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->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;
-                        break;
-                     }
-                  }
-                  if(ivideo->SiS_Pr.SiS_CustomT == CUT_BARCO1366) {
-                       ivideo->lcdxres = 1360; ivideo->lcdyres = 1024; ivideo->lcddefmodeidx = 99;
-                  } else if(ivideo->SiS_Pr.SiS_CustomT == CUT_PANEL848) {
-                       ivideo->lcdxres =  848; ivideo->lcdyres =  480; ivideo->lcddefmodeidx = 47;
-                  }
-                  printk(KERN_DEBUG "sisfb: Detected %dx%d flat panel\n",
-                               ivideo->lcdxres, ivideo->lcdyres);
-               }
-
-#ifdef CONFIG_FB_SIS_300
-                /* Save the current PanelDelayCompensation if the LCD is currently used */
-               if(ivideo->sisvga_engine == SIS_300_VGA) {
-                  if(ivideo->vbflags & (VB_LVDS | VB_30xBDH)) {
-                      int tmp;
-                      inSISIDXREG(SISCR,0x30,tmp);
-                      if(tmp & 0x20) {
-                         /* Currently on LCD? If yes, read current pdc */
-                         inSISIDXREG(SISPART1,0x13,ivideo->detectedpdc);
-                         ivideo->detectedpdc &= 0x3c;
-                         if(ivideo->SiS_Pr.PDC == -1) {
-                            /* Let option override detection */
-                            ivideo->SiS_Pr.PDC = ivideo->detectedpdc;
-                         }
-                         printk(KERN_INFO "sisfb: Detected LCD PDC 0x%02x\n",
-                                ivideo->detectedpdc);
-                      }
-                      if((ivideo->SiS_Pr.PDC != -1) && (ivideo->SiS_Pr.PDC != ivideo->detectedpdc)) {
-                         printk(KERN_INFO "sisfb: Using LCD PDC 0x%02x\n",
-                                ivideo->SiS_Pr.PDC);
-                      }
-                  }
+                       sisfb_detect_lcd_type(ivideo);
                }
-#endif
-
-#ifdef CONFIG_FB_SIS_315
-               if(ivideo->sisvga_engine == SIS_315_VGA) {
-
-                  /* Try to find about LCDA */
-                  if(ivideo->vbflags & (VB_301C | VB_302B | VB_301LV | VB_302LV | VB_302ELV)) {
-                     int tmp;
-                     inSISIDXREG(SISPART1,0x13,tmp);
-                     if(tmp & 0x04) {
-                        ivideo->SiS_Pr.SiS_UseLCDA = TRUE;
-                        ivideo->detectedlcda = 0x03;
-                     }
-                  }
-
-                  /* Save PDC */
-                  if(ivideo->vbflags & (VB_301LV | VB_302LV | VB_302ELV)) {
-                     int tmp;
-                     inSISIDXREG(SISCR,0x30,tmp);
-                     if((tmp & 0x20) || (ivideo->detectedlcda != 0xff)) {
-                        /* Currently on LCD? If yes, read current pdc */
-                        u8 pdc;
-                        inSISIDXREG(SISPART1,0x2D,pdc);
-                        ivideo->detectedpdc  = (pdc & 0x0f) << 1;
-                        ivideo->detectedpdca = (pdc & 0xf0) >> 3;
-                        inSISIDXREG(SISPART1,0x35,pdc);
-                        ivideo->detectedpdc |= ((pdc >> 7) & 0x01);
-                        inSISIDXREG(SISPART1,0x20,pdc);
-                        ivideo->detectedpdca |= ((pdc >> 6) & 0x01);
-                        if(ivideo->newrom) {
-                           /* New ROM invalidates other PDC resp. */
-                           if(ivideo->detectedlcda != 0xff) {
-                              ivideo->detectedpdc = 0xff;
-                           } else {
-                              ivideo->detectedpdca = 0xff;
-                           }
-                        }
-                        if(ivideo->SiS_Pr.PDC == -1) {
-                           if(ivideo->detectedpdc != 0xff) {
-                              ivideo->SiS_Pr.PDC = ivideo->detectedpdc;
-                           }
-                        }
-                        if(ivideo->SiS_Pr.PDCA == -1) {
-                           if(ivideo->detectedpdca != 0xff) {
-                              ivideo->SiS_Pr.PDCA = ivideo->detectedpdca;
-                           }
-                        }
-                        if(ivideo->detectedpdc != 0xff) {
-                           printk(KERN_INFO
-                                "sisfb: Detected LCD PDC 0x%02x (for LCD=CRT2)\n",
-                                 ivideo->detectedpdc);
-                        }
-                        if(ivideo->detectedpdca != 0xff) {
-                           printk(KERN_INFO
-                                "sisfb: Detected LCD PDC1 0x%02x (for LCD=CRT1)\n",
-                                 ivideo->detectedpdca);
-                        }
-                     }
-
-                     /* Save EMI */
-                     if(ivideo->vbflags & (VB_302LV | VB_302ELV)) {
-                        inSISIDXREG(SISPART4,0x30,ivideo->SiS_Pr.EMI_30);
-                        inSISIDXREG(SISPART4,0x31,ivideo->SiS_Pr.EMI_31);
-                        inSISIDXREG(SISPART4,0x32,ivideo->SiS_Pr.EMI_32);
-                        inSISIDXREG(SISPART4,0x33,ivideo->SiS_Pr.EMI_33);
-                        ivideo->SiS_Pr.HaveEMI = TRUE;
-                        if((tmp & 0x20) || (ivideo->detectedlcda != 0xff)) {
-                               ivideo->SiS_Pr.HaveEMILCD = TRUE;
-                        }
-                     }
-                  }
 
-                  /* Let user override detected PDCs (all bridges) */
-                  if(ivideo->vbflags & (VB_301B | VB_301C | VB_301LV | VB_302LV | VB_302ELV)) {
-                     if((ivideo->SiS_Pr.PDC != -1) && (ivideo->SiS_Pr.PDC != ivideo->detectedpdc)) {
-                        printk(KERN_INFO "sisfb: Using LCD PDC 0x%02x (for LCD=CRT2)\n",
-                                ivideo->SiS_Pr.PDC);
-                     }
-                     if((ivideo->SiS_Pr.PDCA != -1) && (ivideo->SiS_Pr.PDCA != ivideo->detectedpdca)) {
-                        printk(KERN_INFO "sisfb: Using LCD PDC1 0x%02x (for LCD=CRT1)\n",
-                                ivideo->SiS_Pr.PDCA);
-                     }
-                  }
-
-               }
-#endif
+               sisfb_save_pdc_emi(ivideo);
 
                if(!ivideo->sisfb_crt1off) {
-                       sisfb_handle_ddc(ivideo, &ivideo->sisfb_thismonitor, 0);
+                       sisfb_handle_ddc(ivideo, &ivideo->sisfb_thismonitor, 0);
                } else {
-                       if((ivideo->vbflags & (VB_301|VB_301B|VB_301C|VB_302B)) &&
-                          (ivideo->vbflags & (CRT2_VGA | CRT2_LCD))) {
-                               sisfb_handle_ddc(ivideo, &ivideo->sisfb_thismonitor, 1);
-                       }
+                       if((ivideo->vbflags2 & VB2_SISTMDSBRIDGE) &&
+                          (ivideo->vbflags & (CRT2_VGA | CRT2_LCD))) {
+                               sisfb_handle_ddc(ivideo, &ivideo->sisfb_thismonitor, 1);
+                       }
                }
 
                if(ivideo->sisfb_mode_idx >= 0) {
@@ -5434,7 +6447,8 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
                ivideo->mode_no = sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni];
 
                if(ivideo->refresh_rate != 0) {
-                       sisfb_search_refresh_rate(ivideo, ivideo->refresh_rate, ivideo->sisfb_mode_idx);
+                       sisfb_search_refresh_rate(ivideo, ivideo->refresh_rate,
+                                               ivideo->sisfb_mode_idx);
                }
 
                if(ivideo->rate_idx == 0) {
@@ -5443,9 +6457,12 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
                }
 
                if(ivideo->sisfb_thismonitor.datavalid) {
-                       if(!sisfb_verify_rate(ivideo, &ivideo->sisfb_thismonitor, ivideo->sisfb_mode_idx,
-                                             ivideo->rate_idx, ivideo->refresh_rate)) {
-                               printk(KERN_INFO "sisfb: WARNING: Refresh rate exceeds monitor specs!\n");
+                       if(!sisfb_verify_rate(ivideo, &ivideo->sisfb_thismonitor,
+                                               ivideo->sisfb_mode_idx,
+                                               ivideo->rate_idx,
+                                               ivideo->refresh_rate)) {
+                               printk(KERN_INFO "sisfb: WARNING: Refresh rate "
+                                                       "exceeds monitor specs!\n");
                        }
                }
 
@@ -5454,28 +6471,34 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
                ivideo->video_height = sisbios_mode[ivideo->sisfb_mode_idx].yres;
 
                sisfb_set_vparms(ivideo);
-               
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) 
 
-               /* ---------------- For 2.4: Now switch the mode ------------------ */          
-               
-               printk(KERN_INFO "sisfb: Mode is %dx%dx%d (%dHz)\n",
-                       ivideo->video_width, ivideo->video_height, ivideo->video_bpp,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+
+               /* ---------------- For 2.4: Now switch the mode ------------------ */
+
+               printk(KERN_INFO "sisfb: Setting mode %dx%dx%d (%dHz)\n",
+                       ivideo->video_width, ivideo->video_height, ivideo->video_bpp,
                        ivideo->refresh_rate);
 
+               /* Determine whether or not acceleration is to be
+                * used. Need to know before pre/post_set_mode()
+                */
+               ivideo->accel = 0;
+               ivideo->default_var.accel_flags &= ~FB_ACCELF_TEXT;
+               if(ivideo->sisfb_accel) {
+                       ivideo->accel = -1;
+                       ivideo->default_var.accel_flags |= FB_ACCELF_TEXT;
+               }
+
+               /* Now switch the mode */
                sisfb_pre_setmode(ivideo);
 
-               if(SiSSetMode(&ivideo->SiS_Pr, &ivideo->sishw_ext, ivideo->mode_no) == 0) {
+               if(SiSSetMode(&ivideo->SiS_Pr, ivideo->mode_no) == 0) {
                        printk(KERN_ERR "sisfb: Fatal error: Setting mode[0x%x] failed\n",
                                                                        ivideo->mode_no);
-                       iounmap(ivideo->video_vbase);
+                       ret = -EINVAL;
                        iounmap(ivideo->mmio_vbase);
-                       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);
-                       pci_set_drvdata(pdev, NULL);
-                       kfree(sis_fb_info);
-                       return -EINVAL;
+                       goto error_0;
                }
 
                outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
@@ -5488,18 +6511,17 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
                /* Force reset of x virtual in crtc_to_var */
                ivideo->default_var.xres_virtual = 0;
 
+               /* Copy mode timing to var */
                sisfb_crtc_to_var(ivideo, &ivideo->default_var);
 
+               /* Find out about screen pitch */
                sisfb_calc_pitch(ivideo, &ivideo->default_var);
                sisfb_set_pitch(ivideo);
 
-               ivideo->accel = 0;
-               if(ivideo->sisfb_accel) {
-                  ivideo->accel = -1;
-                  ivideo->default_var.accel_flags |= FB_ACCELF_TEXT;
-               }
+               /* Init the accelerator (does nothing currently) */
                sisfb_initaccel(ivideo);
-               
+
+               /* Init some fbinfo entries */
                sis_fb_info->node  = -1;
                sis_fb_info->flags = FBINFO_FLAG_DEFAULT;
                sis_fb_info->fbops = &sisfb_ops;
@@ -5515,41 +6537,42 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
 #else          /* --------- For 2.6: Setup a somewhat sane default var ------------ */
 
                printk(KERN_INFO "sisfb: Default mode is %dx%dx%d (%dHz)\n",
-                       ivideo->video_width, ivideo->video_height, ivideo->video_bpp,
+                       ivideo->video_width, ivideo->video_height, ivideo->video_bpp,
                        ivideo->refresh_rate);
 
+               /* Set up the default var according to chosen default display mode */
                ivideo->default_var.xres = ivideo->default_var.xres_virtual = ivideo->video_width;
                ivideo->default_var.yres = ivideo->default_var.yres_virtual = ivideo->video_height;
                ivideo->default_var.bits_per_pixel = ivideo->video_bpp;
 
                sisfb_bpp_to_var(ivideo, &ivideo->default_var);
-               
+
                ivideo->default_var.pixclock = (u32) (1000000000 /
-                               sisfb_mode_rate_to_dclock(&ivideo->SiS_Pr, &ivideo->sishw_ext,
-                                               ivideo->mode_no, ivideo->rate_idx));
-                                               
-               if(sisfb_mode_rate_to_ddata(&ivideo->SiS_Pr, &ivideo->sishw_ext,
-                               ivideo->mode_no, ivideo->rate_idx, &ivideo->default_var)) {
-                  if((ivideo->default_var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
-                     ivideo->default_var.pixclock <<= 1;
-                  }
-               }
+                       sisfb_mode_rate_to_dclock(&ivideo->SiS_Pr, ivideo->mode_no, ivideo->rate_idx));
+
+               if(sisfb_mode_rate_to_ddata(&ivideo->SiS_Pr, ivideo->mode_no,
+                                               ivideo->rate_idx, &ivideo->default_var)) {
+                       if((ivideo->default_var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
+                               ivideo->default_var.pixclock <<= 1;
+                       }
+               }
 
                if(ivideo->sisfb_ypan) {
-                  /* Maximize regardless of sisfb_max at startup */
-                  ivideo->default_var.yres_virtual = sisfb_calc_maxyres(ivideo, &ivideo->default_var);
-                  if(ivideo->default_var.yres_virtual < ivideo->default_var.yres) {
-                     ivideo->default_var.yres_virtual = ivideo->default_var.yres;
-                  }
+                       /* Maximize regardless of sisfb_max at startup */
+                       ivideo->default_var.yres_virtual =
+                               sisfb_calc_maxyres(ivideo, &ivideo->default_var);
+                       if(ivideo->default_var.yres_virtual < ivideo->default_var.yres) {
+                               ivideo->default_var.yres_virtual = ivideo->default_var.yres;
+                       }
                }
 
                sisfb_calc_pitch(ivideo, &ivideo->default_var);
 
                ivideo->accel = 0;
                if(ivideo->sisfb_accel) {
-                  ivideo->accel = -1;
+                       ivideo->accel = -1;
 #ifdef STUPID_ACCELF_TEXT_SHIT
-                  ivideo->default_var.accel_flags |= FB_ACCELF_TEXT;
+                       ivideo->default_var.accel_flags |= FB_ACCELF_TEXT;
 #endif
                }
                sisfb_initaccel(ivideo);
@@ -5566,21 +6589,21 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
 #endif
                sis_fb_info->var = ivideo->default_var;
                sis_fb_info->fix = ivideo->sisfb_fix;
-               sis_fb_info->screen_base = ivideo->video_vbase;
+               sis_fb_info->screen_base = ivideo->video_vbase + ivideo->video_offset;
                sis_fb_info->fbops = &sisfb_ops;
 
                sisfb_get_fix(&sis_fb_info->fix, -1, sis_fb_info);
                sis_fb_info->pseudo_palette = ivideo->pseudo_palette;
-               
+
                fb_alloc_cmap(&sis_fb_info->cmap, 256 , 0);
 #endif         /* 2.6 */
 
-               printk(KERN_DEBUG "sisfb: Initial vbflags 0x%lx\n", (unsigned long)ivideo->vbflags);
+               printk(KERN_DEBUG "sisfb: Initial vbflags 0x%x\n", (int)ivideo->vbflags);
 
 #ifdef CONFIG_MTRR
                ivideo->mtrr = mtrr_add(ivideo->video_base, ivideo->video_size,
                                        MTRR_TYPE_WRCOMB, 1);
-               if(!ivideo->mtrr) {
+               if(ivideo->mtrr < 0) {
                        printk(KERN_DEBUG "sisfb: Failed to add MTRRs\n");
                }
 #endif
@@ -5591,14 +6614,9 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
 
                if(register_framebuffer(sis_fb_info) < 0) {
                        printk(KERN_ERR "sisfb: Fatal error: Failed to register framebuffer\n");
-                       iounmap(ivideo->video_vbase);
+                       ret = -EINVAL;
                        iounmap(ivideo->mmio_vbase);
-                       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);
-                       pci_set_drvdata(pdev, NULL);
-                       kfree(sis_fb_info);
-                       return -EINVAL;
+                       goto error_0;
                }
 
                ivideo->registered = 1;
@@ -5607,21 +6625,47 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
                ivideo->next = card_list;
                card_list = ivideo;
 
+#ifdef SIS_OLD_CONFIG_COMPAT
+               {
+               int ret;
+               /* Our ioctls are all "32/64bit compatible" */
+               ret =  register_ioctl32_conversion(FBIO_ALLOC,             NULL);
+               ret |= register_ioctl32_conversion(FBIO_FREE,              NULL);
+               ret |= register_ioctl32_conversion(FBIOGET_VBLANK,         NULL);
+               ret |= register_ioctl32_conversion(SISFB_GET_INFO_SIZE,    NULL);
+               ret |= register_ioctl32_conversion(SISFB_GET_INFO,         NULL);
+               ret |= register_ioctl32_conversion(SISFB_GET_TVPOSOFFSET,  NULL);
+               ret |= register_ioctl32_conversion(SISFB_SET_TVPOSOFFSET,  NULL);
+               ret |= register_ioctl32_conversion(SISFB_SET_LOCK,         NULL);
+               ret |= register_ioctl32_conversion(SISFB_GET_VBRSTATUS,    NULL);
+               ret |= register_ioctl32_conversion(SISFB_GET_AUTOMAXIMIZE, NULL);
+               ret |= register_ioctl32_conversion(SISFB_SET_AUTOMAXIMIZE, NULL);
+               ret |= register_ioctl32_conversion(SISFB_COMMAND,          NULL);
+               if(ret)
+                       printk(KERN_ERR
+                               "sisfb: Error registering ioctl32 translations\n");
+               else
+                       ivideo->ioctl32registered = 1;
+               }
+#endif
+
                printk(KERN_INFO "sisfb: 2D acceleration is %s, y-panning %s\n",
-                    ivideo->sisfb_accel ? "enabled" : "disabled",
-                    ivideo->sisfb_ypan  ?
-                       (ivideo->sisfb_max ? "enabled (auto-max)" : "enabled (no auto-max)") : "disabled");
+                       ivideo->sisfb_accel ? "enabled" : "disabled",
+                       ivideo->sisfb_ypan  ?
+                               (ivideo->sisfb_max ? "enabled (auto-max)" :
+                                               "enabled (no auto-max)") :
+                                                                       "disabled");
 
 
-               printk(KERN_INFO "fb%d: %s frame buffer device, Version %d.%d.%d\n",
+               printk(KERN_INFO "fb%d: %s frame buffer device version %d.%d.%d\n",
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-                       GET_FB_IDX(sis_fb_info->node),
+                       GET_FB_IDX(sis_fb_info->node),
 #else
-                       sis_fb_info->node,
+                       sis_fb_info->node,
 #endif
                        ivideo->myid, VER_MAJOR, VER_MINOR, VER_LEVEL);
 
-               printk(KERN_INFO "sisfb: (C) 2001-2004 Thomas Winischhofer.\n");
+               printk(KERN_INFO "sisfb: Copyright (C) 2001-2005 Thomas Winischhofer\n");
 
        }       /* if mode = "none" */
 
@@ -5634,26 +6678,62 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
 
 static void __devexit sisfb_remove(struct pci_dev *pdev)
 {
-       struct sis_video_info *ivideo = pci_get_drvdata(pdev);
-       struct fb_info        *sis_fb_info = ivideo->memyselfandi;
-       int                   registered = ivideo->registered;
+       struct sis_video_info   *ivideo = pci_get_drvdata(pdev);
+       struct fb_info          *sis_fb_info = ivideo->memyselfandi;
+       int                     registered = ivideo->registered;
+       int                     modechanged = ivideo->modechanged;
+
+#ifdef SIS_OLD_CONFIG_COMPAT
+       if(ivideo->ioctl32registered) {
+               int ret;
+               ret =  unregister_ioctl32_conversion(FBIO_ALLOC);
+               ret |= unregister_ioctl32_conversion(FBIO_FREE);
+               ret |= unregister_ioctl32_conversion(FBIOGET_VBLANK);
+               ret |= unregister_ioctl32_conversion(SISFB_GET_INFO_SIZE);
+               ret |= unregister_ioctl32_conversion(SISFB_GET_INFO);
+               ret |= unregister_ioctl32_conversion(SISFB_GET_TVPOSOFFSET);
+               ret |= unregister_ioctl32_conversion(SISFB_SET_TVPOSOFFSET);
+               ret |= unregister_ioctl32_conversion(SISFB_SET_LOCK);
+               ret |= unregister_ioctl32_conversion(SISFB_GET_VBRSTATUS);
+               ret |= unregister_ioctl32_conversion(SISFB_GET_AUTOMAXIMIZE);
+               ret |= unregister_ioctl32_conversion(SISFB_SET_AUTOMAXIMIZE);
+               ret |= unregister_ioctl32_conversion(SISFB_COMMAND);
+               if(ret)
+                       printk(KERN_ERR
+                            "sisfb: Error unregistering ioctl32 translations\n");
+       }
+#endif
 
        /* Unmap */
-       iounmap(ivideo->video_vbase);
        iounmap(ivideo->mmio_vbase);
-       vfree(ivideo->bios_abase);
+       iounmap(ivideo->video_vbase);
 
        /* Release mem regions */
        release_mem_region(ivideo->video_base, ivideo->video_size);
        release_mem_region(ivideo->mmio_base, ivideo->mmio_size);
 
+       vfree(ivideo->bios_abase);
+
+       if(ivideo->lpcdev)
+               SIS_PCI_PUT_DEVICE(ivideo->lpcdev);
+
+       if(ivideo->nbridge)
+               SIS_PCI_PUT_DEVICE(ivideo->nbridge);
+
 #ifdef CONFIG_MTRR
        /* Release MTRR region */
-       if(ivideo->mtrr) {
+       if(ivideo->mtrr >= 0)
                mtrr_del(ivideo->mtrr, ivideo->video_base, ivideo->video_size);
-       }
 #endif
 
+       pci_set_drvdata(pdev, NULL);
+
+       /* If device was disabled when starting, disable
+        * it when quitting.
+        */
+       if(!ivideo->sisvga_enabled)
+               pci_disable_device(pdev);
+
        /* Unregister the framebuffer */
        if(ivideo->registered) {
                unregister_framebuffer(sis_fb_info);
@@ -5664,7 +6744,7 @@ static void __devexit sisfb_remove(struct pci_dev *pdev)
 #endif
        }
 
-       pci_set_drvdata(pdev, NULL);
+       /* OK, our ivideo is gone for good from here. */
 
        /* TODO: Restore the initial mode
         * This sounds easy but is as good as impossible
@@ -5673,15 +6753,15 @@ static void __devexit sisfb_remove(struct pci_dev *pdev)
         * from machine to machine. Depends on the type
         * of integration between chipset and bridge.
         */
-       if(registered) {
-          printk(KERN_INFO "sisfb: Restoring of text mode not supported yet\n");
-       }
+       if(registered && modechanged)
+               printk(KERN_INFO
+                       "sisfb: Restoring of text mode not supported yet\n");
 };
 
 static struct pci_driver sisfb_driver = {
        .name           = "sisfb",
        .id_table       = sisfb_pci_table,
-       .probe          = sisfb_probe,
+       .probe          = sisfb_probe,
        .remove         = __devexit_p(sisfb_remove)
 };
 
@@ -5693,10 +6773,11 @@ SISINITSTATIC int __init sisfb_init(void)
 
        if(fb_get_options("sisfb", &options))
                return -ENODEV;
+
        sisfb_setup(options);
 #endif
 #endif
-       return(pci_register_driver(&sisfb_driver));
+       return pci_register_driver(&sisfb_driver);
 }
 
 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)
@@ -5711,36 +6792,129 @@ module_init(sisfb_init);
 
 #ifdef MODULE
 
-static char         *mode = NULL;
-static int          vesa = -1;
-static unsigned int rate = 0;
-static unsigned int crt1off = 1;
-static unsigned int mem = 0;
-static char         *forcecrt2type = NULL;
-static int          forcecrt1 = -1;
-static int          pdc = -1;
-static int          pdc1 = -1;
-static int          noaccel = -1;
-static int          noypan  = -1;
-static int         nomax = -1;
+static char            *mode = NULL;
+static int             vesa = -1;
+static unsigned int    rate = 0;
+static unsigned int    crt1off = 1;
+static unsigned int    mem = 0;
+static char            *forcecrt2type = NULL;
+static int             forcecrt1 = -1;
+static int             pdc = -1;
+static int             pdc1 = -1;
+static int             noaccel = -1;
+static int             noypan  = -1;
+static int             nomax = -1;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+static int             inverse = 0;
+#endif
+static int             userom = -1;
+static int             useoem = -1;
+static char            *tvstandard = NULL;
+static int             nocrt2rate = 0;
+static int             scalelcd = -1;
+static char            *specialtiming = NULL;
+static int             lvdshl = -1;
+static int             tvxposoffset = 0, tvyposoffset = 0;
+#if !defined(__i386__) && !defined(__x86_64__)
+static int             resetcard = 0;
+static int             videoram = 0;
+#endif
+
+static int __init sisfb_init_module(void)
+{
+       sisfb_setdefaultparms();
+
+       if(rate)
+               sisfb_parm_rate = rate;
+
+       if((scalelcd == 0) || (scalelcd == 1))
+               sisfb_scalelcd = scalelcd ^ 1;
+
+       /* Need to check crt2 type first for fstn/dstn */
+
+       if(forcecrt2type)
+               sisfb_search_crt2type(forcecrt2type);
+
+       if(tvstandard)
+               sisfb_search_tvstd(tvstandard);
+
+       if(mode)
+               sisfb_search_mode(mode, FALSE);
+       else if(vesa != -1)
+               sisfb_search_vesamode(vesa, FALSE);
+
+       sisfb_crt1off = (crt1off == 0) ? 1 : 0;
+
+       sisfb_forcecrt1 = forcecrt1;
+       if(forcecrt1 == 1)
+               sisfb_crt1off = 0;
+       else if(forcecrt1 == 0)
+               sisfb_crt1off = 1;
+
+       if(noaccel == 1)
+               sisfb_accel = 0;
+       else if(noaccel == 0)
+               sisfb_accel = 1;
+
+       if(noypan == 1)
+               sisfb_ypan = 0;
+       else if(noypan == 0)
+               sisfb_ypan = 1;
+
+       if(nomax == 1)
+               sisfb_max = 0;
+       else if(nomax == 0)
+               sisfb_max = 1;
+
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-static int          inverse = 0;
-#endif
-static int          userom = -1;
-static int          useoem = -1;
-static char         *tvstandard = NULL;
-static int         nocrt2rate = 0;
-static int          scalelcd = -1;
-static char        *specialtiming = NULL;
-static int         lvdshl = -1;
-static int         tvxposoffset = 0, tvyposoffset = 0;
-static int         filter = -1;
+       if(inverse) sisfb_inverse = 1;
+#endif
+
+       if(mem)
+               sisfb_parm_mem = mem;
+
+       if(userom != -1)
+               sisfb_userom = userom;
+
+       if(useoem != -1)
+               sisfb_useoem = useoem;
+
+        if(pdc != -1)
+               sisfb_pdc  = (pdc  & 0x7f);
+
+       if(pdc1 != -1)
+               sisfb_pdca = (pdc1 & 0x1f);
+
+       sisfb_nocrt2rate = nocrt2rate;
+
+       if(specialtiming)
+               sisfb_search_specialtiming(specialtiming);
+
+       if((lvdshl >= 0) && (lvdshl <= 3))
+               sisfb_lvdshl = lvdshl;
+
+       sisfb_tvxposoffset = tvxposoffset;
+       sisfb_tvyposoffset = tvyposoffset;
+
 #if !defined(__i386__) && !defined(__x86_64__)
-static int         resetcard = 0;
-static int         videoram = 0;
+       sisfb_resetcard = (resetcard) ? 1 : 0;
+       if(videoram)
+               sisfb_videoram = videoram;
 #endif
 
-MODULE_DESCRIPTION("SiS 300/540/630/730/315/550/65x/661/74x/330/760 framebuffer device driver");
+       return sisfb_init();
+}
+
+static void __exit sisfb_remove_module(void)
+{
+       pci_unregister_driver(&sisfb_driver);
+       printk(KERN_DEBUG "sisfb: Module unloaded\n");
+}
+
+module_init(sisfb_init_module);
+module_exit(sisfb_remove_module);
+
+MODULE_DESCRIPTION("SiS 300/540/630/730/315/55x/65x/661/74x/330/76x/34x, XGI V3XT/V5/V8/Z7 framebuffer device driver");
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Thomas Winischhofer <thomas@winischhofer.net>, Others");
 
@@ -5764,7 +6938,6 @@ MODULE_PARM(lvdshl, "i");
 MODULE_PARM(tvstandard, "s");
 MODULE_PARM(tvxposoffset, "i");
 MODULE_PARM(tvyposoffset, "i");
-MODULE_PARM(filter, "i");
 MODULE_PARM(nocrt2rate, "i");
 MODULE_PARM(inverse, "i");
 #if !defined(__i386__) && !defined(__x86_64__)
@@ -5793,7 +6966,6 @@ module_param(lvdshl, int, 0);
 module_param(tvstandard, charp, 0);
 module_param(tvxposoffset, int, 0);
 module_param(tvyposoffset, int, 0);
-module_param(filter, int, 0);
 module_param(nocrt2rate, int, 0);
 #if !defined(__i386__) && !defined(__x86_64__)
 module_param(resetcard, int, 0);
@@ -5801,25 +6973,35 @@ module_param(videoram, int, 0);
 #endif
 #endif
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 MODULE_PARM_DESC(mem,
        "\nDetermines the beginning of the video memory heap in KB. This heap is used\n"
          "for video RAM management for eg. DRM/DRI. On 300 series, the default depends\n"
          "on the amount of video RAM available. If 8MB of video RAM or less is available,\n"
          "the heap starts at 4096KB, if between 8 and 16MB are available at 8192KB,\n"
-         "otherwise at 12288KB. On 315 and Xabre series, the heap size is 32KB by default.\n"
+         "otherwise at 12288KB. On 315/330/340 series, the heap size is 32KB by default.\n"
          "The value is to be specified without 'KB' and must match the MaxXFBMem setting\n"
          "for XFree86 4.x/X.org 6.7 and later.\n");
+#else
+MODULE_PARM_DESC(mem,
+       "\nDetermines the beginning of the video memory heap in KB. This heap is used\n"
+         "for video RAM management for eg. DRM/DRI. On 300 series, the default depends\n"
+         "on the amount of video RAM available. If 8MB of video RAM or less is available,\n"
+         "the heap starts at 4096KB, if between 8 and 16MB are available at 8192KB,\n"
+         "otherwise at 12288KB. On 315/330/340 series, the heap size is 32KB by default.\n"
+         "The value is to be specified without 'KB'.\n");
+#endif
 
 MODULE_PARM_DESC(noaccel,
-        "\nIf set to anything other than 0, 2D acceleration will be disabled.\n"
+       "\nIf set to anything other than 0, 2D acceleration will be disabled.\n"
          "(default: 0)\n");
 
 MODULE_PARM_DESC(noypan,
-        "\nIf set to anything other than 0, y-panning will be disabled and scrolling\n"
-         "will be performed by redrawing the screen. (default: 0)\n");
+       "\nIf set to anything other than 0, y-panning will be disabled and scrolling\n"
+         "will be performed by redrawing the screen. (default: 0)\n");
 
 MODULE_PARM_DESC(nomax,
-        "\nIf y-panning is enabled, sisfb will by default use the entire available video\n"
+       "\nIf y-panning is enabled, sisfb will by default use the entire available video\n"
          "memory for the virtual screen in order to optimize scrolling performance. If\n"
          "this is set to anything other than 0, sisfb will not do this and thereby \n"
          "enable the user to positively specify a virtual Y size of the screen using\n"
@@ -5827,30 +7009,30 @@ MODULE_PARM_DESC(nomax,
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 MODULE_PARM_DESC(mode,
-        "\nSelects the desired display mode in the format [X]x[Y]x[Depth], eg.\n"
-          "1024x768x16. Other formats supported include XxY-Depth and\n"
-         "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
+       "\nSelects the desired display mode in the format [X]x[Y]x[Depth], eg.\n"
+         "1024x768x16. Other formats supported include XxY-Depth and\n"
+         "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
          "number, it will be interpreted as a VESA mode number. (default: none if\n"
          "sisfb is a module; this leaves the console untouched and the driver will\n"
          "only do the video memory management for eg. DRM/DRI; 800x600x8 if sisfb\n"
          "is in the kernel)\n");
 MODULE_PARM_DESC(vesa,
-        "\nSelects the desired display mode by VESA defined mode number, eg. 0x117\n"
-          "(default: 0x0000 if sisfb is a module; this leaves the console untouched\n"
+       "\nSelects the desired display mode by VESA defined mode number, eg. 0x117\n"
+         "(default: 0x0000 if sisfb is a module; this leaves the console untouched\n"
          "and the driver will only do the video memory management for eg. DRM/DRI;\n"
          "0x0103 if sisfb is in the kernel)\n");
 #endif
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 MODULE_PARM_DESC(mode,
-       "\nSelects the desired default display mode in the format XxYxDepth,\n"
-         "eg. 1024x768x16. Other formats supported include XxY-Depth and\n"
+       "\nSelects the desired default display mode in the format XxYxDepth,\n"
+        "eg. 1024x768x16. Other formats supported include XxY-Depth and\n"
         "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
         "number, it will be interpreted as a VESA mode number. (default: 800x600x8)\n");
 
 MODULE_PARM_DESC(vesa,
-       "\nSelects the desired default display mode by VESA defined mode number, eg.\n"
-         "0x117 (default: 0x0103)\n");
+       "\nSelects the desired default display mode by VESA defined mode number, eg.\n"
+        "0x117 (default: 0x0103)\n");
 #endif
 
 MODULE_PARM_DESC(rate,
@@ -5880,16 +7062,16 @@ MODULE_PARM_DESC(scalelcd,
          "themselves. Default: 1 on LVDS panels, 0 on TMDS panels\n");
 
 MODULE_PARM_DESC(pdc,
-        "\nThis is for manually selecting the LCD panel delay compensation. The driver\n"
+       "\nThis is for manually selecting the LCD panel delay compensation. The driver\n"
          "should detect this correctly in most cases; however, sometimes this is not\n"
          "possible. If you see 'small waves' on the LCD, try setting this to 4, 32 or 24\n"
-         "on a 300 series chipset; 6 on a 315 series chipset. If the problem persists,\n"
-         "try other values (on 300 series: between 4 and 60 in steps of 4; on 315 series:\n"
-         "any value from 0 to 31). (default: autodetected, if LCD is active during start)\n");
+         "on a 300 series chipset; 6 on other chipsets. If the problem persists, try\n"
+         "other values (on 300 series: between 4 and 60 in steps of 4; otherwise: any\n"
+         "value from 0 to 31). (default: autodetected, if LCD is active during start)\n");
 
 #ifdef CONFIG_FB_SIS_315
 MODULE_PARM_DESC(pdc1,
-        "\nThis is same as pdc, but for LCD-via CRT1. Hence, this is for the 315/330\n"
+       "\nThis is same as pdc, but for LCD-via CRT1. Hence, this is for the 315/330/340\n"
          "series only. (default: autodetected if LCD is in LCD-via-CRT1 mode during\n"
          "startup) - Note: currently, this has no effect because LCD-via-CRT1 is not\n"
          "implemented yet.\n");
@@ -5913,17 +7095,13 @@ MODULE_PARM_DESC(tvyposoffset,
        "\nRelocate TV output vertically. Possible parameters: -32 through 32.\n"
          "Default: 0\n");
 
-MODULE_PARM_DESC(filter,
-       "\nSelects TV flicker filter type (only for systems with a SiS301 video bridge).\n"
-         "(Possible values 0-7, default: [no filter])\n");
-
 MODULE_PARM_DESC(nocrt2rate,
        "\nSetting this to 1 will force the driver to use the default refresh rate for\n"
          "CRT2 if CRT2 type is VGA. (default: 0, use same rate as CRT1)\n");
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 MODULE_PARM_DESC(inverse,
-        "\nSetting this to anything but 0 should invert the display colors, but this\n"
+       "\nSetting this to anything but 0 should invert the display colors, but this\n"
          "does not seem to work. (default: 0)\n");
 #endif
 
@@ -5931,98 +7109,23 @@ MODULE_PARM_DESC(inverse,
 #ifdef CONFIG_FB_SIS_300
 MODULE_PARM_DESC(resetcard,
        "\nSet this to 1 in order to reset (POST) the card on non-x86 machines where\n"
-         "the BIOS did not POST the card (only supported for SiS 300/305 currently).\n"
-         "Default: 0\n");
+         "the BIOS did not POST the card (only supported for SiS 300/305 and XGI cards\n"
+         "currently). Default: 0\n");
 
 MODULE_PARM_DESC(videoram,
        "\nSet this to the amount of video RAM (in kilobyte) the card has. Required on\n"
          "some non-x86 architectures where the memory auto detection fails. Only\n"
-         "relevant if resetcard is set, too. Default: [auto-detect]\n");
-#endif
-#endif
-
-static int __devinit sisfb_init_module(void)
-{
-       sisfb_setdefaultparms();
-
-       if(rate) sisfb_parm_rate = rate;
-
-       if((scalelcd == 0) || (scalelcd == 1)) {
-          sisfb_scalelcd = scalelcd ^ 1;
-       }
-
-       /* Need to check crt2 type first for fstn/dstn */
-
-       if(forcecrt2type)
-               sisfb_search_crt2type(forcecrt2type);
-
-       if(tvstandard)
-               sisfb_search_tvstd(tvstandard);
-
-       if(mode)
-               sisfb_search_mode(mode, FALSE);
-       else if(vesa != -1)
-               sisfb_search_vesamode(vesa, FALSE);
-
-       sisfb_crt1off = (crt1off == 0) ? 1 : 0;
-
-       sisfb_forcecrt1 = forcecrt1;
-       if(forcecrt1 == 1)      sisfb_crt1off = 0;
-       else if(forcecrt1 == 0) sisfb_crt1off = 1;
-
-       if(noaccel == 1)      sisfb_accel = 0;
-       else if(noaccel == 0) sisfb_accel = 1;
-
-       if(noypan == 1)       sisfb_ypan = 0;
-       else if(noypan == 0)  sisfb_ypan = 1;
-
-       if(nomax == 1)        sisfb_max = 0;
-       else if(nomax == 0)   sisfb_max = 1;
-       
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-       if(inverse)           sisfb_inverse = 1;
+         "relevant if resetcard is set, too. SiS300/305 only. Default: [auto-detect]\n");
 #endif
-
-       if(mem)               sisfb_parm_mem = mem;
-
-       if(userom != -1)      sisfb_userom = userom;
-       if(useoem != -1)      sisfb_useoem = useoem;
-
-        if(pdc != -1)  sisfb_pdc  = (pdc  & 0x7f);
-       if(pdc1 != -1) sisfb_pdca = (pdc1 & 0x1f);
-
-       sisfb_nocrt2rate = nocrt2rate;
-
-       if(specialtiming)
-               sisfb_search_specialtiming(specialtiming);
-
-       if((lvdshl >= 0) && (lvdshl <= 3))  sisfb_lvdshl = lvdshl;
-
-       if(filter != -1) sisfb_filter = filter;
-
-       sisfb_tvxposoffset = tvxposoffset;
-       sisfb_tvyposoffset = tvyposoffset;
-
-#if !defined(__i386__) && !defined(__x86_64__)
-       sisfb_resetcard = (resetcard) ? 1 : 0;
-       if(videoram)    sisfb_videoram = videoram;
 #endif
 
-        return(sisfb_init());
-}
-
-static void __exit sisfb_remove_module(void)
-{
-       pci_unregister_driver(&sisfb_driver);
-       printk(KERN_DEBUG "sisfb: Module unloaded\n");
-}
-
-module_init(sisfb_init_module);
-module_exit(sisfb_remove_module);
-
 #endif            /*  /MODULE  */
 
+/* _GPL only for new symbols. */
 EXPORT_SYMBOL(sis_malloc);
 EXPORT_SYMBOL(sis_free);
+EXPORT_SYMBOL_GPL(sis_malloc_new);
+EXPORT_SYMBOL_GPL(sis_free_new);
+
 
 
index a6678a7..445bcbb 100644 (file)
@@ -1,9 +1,10 @@
 /*
- * SiS 300/305/540/630(S)/730(S)
- * SiS 315(H/PRO)/55x/(M)65x/(M)661(F/M)X/740/741(GX)/330/(M)760
+ * SiS 300/305/540/630(S)/730(S),
+ * SiS 315[E|PRO]/550/[M]65x/[M]66x[F|M|G]X/[M]74x[GX]/330/[M]76x[GX],
+ * XGI V3XT/V5/V8, Z7
  * frame buffer driver for Linux kernels >=2.4.14 and >=2.6.3
  *
- * Copyright (C) 2001-2004 Thomas Winischhofer, Vienna, Austria.
+ * Copyright (C) 2001-2005 Thomas Winischhofer, Vienna, Austria.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
 #ifndef _SISFB_MAIN
 #define _SISFB_MAIN
 
-#include <linux/spinlock.h>
-
 #include "vstruct.h"
 #include "sis.h"
 
-#define MODE_INDEX_NONE           0  /* index for mode=none */
-
 /* Fbcon stuff */
 static struct fb_var_screeninfo my_default_var = {
        .xres            = 0,
@@ -60,6 +57,8 @@ static struct fb_var_screeninfo my_default_var = {
        .vmode           = FB_VMODE_NONINTERLACED,
 };
 
+#define MODE_INDEX_NONE           0  /* index for mode=none */
+
 /* Boot-time parameters */
 static int sisfb_off = 0;
 static int sisfb_parm_mem = 0;
@@ -93,7 +92,6 @@ static int sisfb_tvplug = -1;         /* Tv plug type (for overriding autodetection) */
 static int sisfb_tvstd  = -1;
 static int sisfb_tvxposoffset = 0;
 static int sisfb_tvyposoffset = 0;
-static int sisfb_filter = -1;
 static int sisfb_nocrt2rate = 0;
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 static int  sisfb_inverse = 0;
@@ -106,12 +104,12 @@ static int sisfb_videoram = 0;
 
 /* List of supported chips */
 static struct sisfb_chip_info {
-        int            chip;
-       int             vgaengine;
+       int             chip;
+       int             vgaengine;
        int             mni;
-       int             hwcursor_size;
+       int             hwcursor_size;
        int             CRT2_write_enable;
-       const char      *chip_name;
+       const char      *chip_name;
 } sisfb_chip_info[] __devinitdata = {
        { SIS_300,    SIS_300_VGA, 0, HW_CURSOR_AREA_SIZE_300 * 2, SIS_CRT2_WENABLE_300, "SiS 300/305" },
        { SIS_540,    SIS_300_VGA, 0, HW_CURSOR_AREA_SIZE_300 * 2, SIS_CRT2_WENABLE_300, "SiS 540" },
@@ -123,6 +121,8 @@ static struct sisfb_chip_info {
        { SIS_650,    SIS_315_VGA, 1, HW_CURSOR_AREA_SIZE_315 * 4, SIS_CRT2_WENABLE_315, "SiS 650" },
        { SIS_330,    SIS_315_VGA, 1, HW_CURSOR_AREA_SIZE_315 * 4, SIS_CRT2_WENABLE_315, "SiS 330" },
        { SIS_660,    SIS_315_VGA, 1, HW_CURSOR_AREA_SIZE_315 * 4, SIS_CRT2_WENABLE_315, "SiS 660" },
+       { XGI_20,     SIS_315_VGA, 1, HW_CURSOR_AREA_SIZE_315 * 4, SIS_CRT2_WENABLE_315, "XGI Z7" },
+       { XGI_40,     SIS_315_VGA, 1, HW_CURSOR_AREA_SIZE_315 * 4, SIS_CRT2_WENABLE_315, "XGI V3XT/V5/V8" },
 };
 
 static struct pci_device_id __devinitdata sisfb_pci_table[] = {
@@ -139,6 +139,8 @@ static struct pci_device_id __devinitdata sisfb_pci_table[] = {
        { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_650_VGA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 7},
        { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_330,     PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8},
        { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_660_VGA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 9},
+       { PCI_VENDOR_ID_XGI,PCI_DEVICE_ID_XGI_20,     PCI_ANY_ID, PCI_ANY_ID, 0, 0,10},
+       { PCI_VENDOR_ID_XGI,PCI_DEVICE_ID_XGI_40,     PCI_ANY_ID, PCI_ANY_ID, 0, 0,11},
 #endif
        { 0 }
 };
@@ -147,13 +149,12 @@ MODULE_DEVICE_TABLE(pci, sisfb_pci_table);
 
 static struct sis_video_info *card_list = NULL;
 
-/* TODO: This is not handled card-wise because the DRM
-   does not refer to a unique fb when calling sis_alloc
-   or sis_free. Therefore, this is handled globally for
-   now (hoping that nobody is crazy enough to run two
-   SiS cards at the same time).
+/* The memory heap is now handled card-wise, by using
+   sis_malloc_new/sis_free_new. However, the DRM does
+   not do this yet. Until it does, we keep a "global"
+   heap which is actually the first card's one.
  */
-static SIS_HEAP        sisfb_heap;
+static struct SIS_HEAP *sisfb_heap;
 
 #define MD_SIS300 1
 #define MD_SIS315 2
@@ -181,8 +182,10 @@ static const struct _sisbios_mode {
        {"320x240x16",   {0x56,0x56}, 0x0135, 0x0000,  320,  240, 16, 1,  40, 15, MD_SIS300|MD_SIS315},
        {"320x240x24",   {0x53,0x53}, 0x0000, 0x0000,  320,  240, 32, 1,  40, 15, MD_SIS300|MD_SIS315},
        {"320x240x32",   {0x53,0x53}, 0x0000, 0x0000,  320,  240, 32, 1,  40, 15, MD_SIS300|MD_SIS315},
-       {"320x240x8",    {0x5a,0x5a}, 0x0132, 0x0000,  320,  480,  8, 1,  40, 30,           MD_SIS315},  /* FSTN */
-/*10*/ {"320x240x16",   {0x5b,0x5b}, 0x0135, 0x0000,  320,  480, 16, 1,  40, 30,           MD_SIS315},  /* FSTN */
+#define MODE_FSTN_8    9
+#define MODE_FSTN_16   10
+       {"320x240x8",    {0x5a,0x5a}, 0x0132, 0x0000,  320,  240,  8, 1,  40, 15,           MD_SIS315},  /* FSTN */
+/*10*/ {"320x240x16",   {0x5b,0x5b}, 0x0135, 0x0000,  320,  240, 16, 1,  40, 15,           MD_SIS315},  /* FSTN */
        {"400x300x8",    {0x51,0x51}, 0x0133, 0x0000,  400,  300,  8, 1,  50, 18, MD_SIS300|MD_SIS315},
        {"400x300x16",   {0x57,0x57}, 0x0136, 0x0000,  400,  300, 16, 1,  50, 18, MD_SIS300|MD_SIS315},
        {"400x300x24",   {0x54,0x54}, 0x0000, 0x0000,  400,  300, 32, 1,  50, 18, MD_SIS300|MD_SIS315},
@@ -215,18 +218,20 @@ static const struct _sisbios_mode {
 /*40*/ {"800x480x16",   {0x7a,0x7a}, 0x0000, 0x0000,  800,  480, 16, 1, 100, 30, MD_SIS300|MD_SIS315},
        {"800x480x24",   {0x76,0x76}, 0x0000, 0x0000,  800,  480, 32, 1, 100, 30, MD_SIS300|MD_SIS315},
        {"800x480x32",   {0x76,0x76}, 0x0000, 0x0000,  800,  480, 32, 1, 100, 30, MD_SIS300|MD_SIS315},
-#define DEFAULT_MODE              43 /* index for 800x600x8 */
-#define DEFAULT_LCDMODE           43 /* index for 800x600x8 */
-#define DEFAULT_TVMODE            43 /* index for 800x600x8 */
+#define DEFAULT_MODE           43 /* index for 800x600x8 */
+#define DEFAULT_LCDMODE                43 /* index for 800x600x8 */
+#define DEFAULT_TVMODE         43 /* index for 800x600x8 */
        {"800x600x8",    {0x30,0x30}, 0x0103, 0x0103,  800,  600,  8, 2, 100, 37, MD_SIS300|MD_SIS315},
        {"800x600x16",   {0x47,0x47}, 0x0114, 0x0114,  800,  600, 16, 2, 100, 37, MD_SIS300|MD_SIS315},
        {"800x600x24",   {0x63,0x63}, 0x013b, 0x0115,  800,  600, 32, 2, 100, 37, MD_SIS300|MD_SIS315},
        {"800x600x32",   {0x63,0x63}, 0x013b, 0x0115,  800,  600, 32, 2, 100, 37, MD_SIS300|MD_SIS315},
        {"848x480x8",    {0x39,0x39}, 0x0000, 0x0000,  848,  480,  8, 2, 106, 30, MD_SIS300|MD_SIS315},
+#define DEFAULT_MODE_848       48
        {"848x480x16",   {0x3b,0x3b}, 0x0000, 0x0000,  848,  480, 16, 2, 106, 30, MD_SIS300|MD_SIS315},
        {"848x480x24",   {0x3e,0x3e}, 0x0000, 0x0000,  848,  480, 32, 2, 106, 30, MD_SIS300|MD_SIS315},
 /*50*/ {"848x480x32",   {0x3e,0x3e}, 0x0000, 0x0000,  848,  480, 32, 2, 106, 30, MD_SIS300|MD_SIS315},
        {"856x480x8",    {0x3f,0x3f}, 0x0000, 0x0000,  856,  480,  8, 2, 107, 30, MD_SIS300|MD_SIS315},
+#define DEFAULT_MODE_856       52
        {"856x480x16",   {0x42,0x42}, 0x0000, 0x0000,  856,  480, 16, 2, 107, 30, MD_SIS300|MD_SIS315},
        {"856x480x24",   {0x45,0x45}, 0x0000, 0x0000,  856,  480, 32, 2, 107, 30, MD_SIS300|MD_SIS315},
        {"856x480x32",   {0x45,0x45}, 0x0000, 0x0000,  856,  480, 32, 2, 107, 30, MD_SIS300|MD_SIS315},
@@ -270,42 +275,47 @@ static const struct _sisbios_mode {
        {"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},
        {"1280x800x32",  {0x16,0x16}, 0x0000, 0x0000, 1280,  800, 32, 1, 160, 50,           MD_SIS315},
+       {"1280x854x8",   {0x14,0x14}, 0x0000, 0x0000, 1280,  854,  8, 1, 160, 53,           MD_SIS315},
+       {"1280x854x16",  {0x15,0x15}, 0x0000, 0x0000, 1280,  854, 16, 1, 160, 53,           MD_SIS315},
+       {"1280x854x24",  {0x16,0x16}, 0x0000, 0x0000, 1280,  854, 32, 1, 160, 53,           MD_SIS315},
+       {"1280x854x32",  {0x16,0x16}, 0x0000, 0x0000, 1280,  854, 32, 1, 160, 53,           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},
+/*100*/        {"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},
-/*100*/        {"1280x1024x16", {0x4d,0x4d}, 0x011a, 0x011a, 1280, 1024, 16, 2, 160, 64, MD_SIS300|MD_SIS315},
+       {"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},
        {"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},
+/*110*/        {"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          },
+#define DEFAULT_MODE_1360      112
        {"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          },
-/*110*/        {"1360x1024x32", {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          },
        {"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},
        {"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},
+/*120*/        {"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},
-/*120*/        {"1680x1050x16", {0x18,0x18}, 0x0000, 0x0000, 1680, 1050, 16, 1, 210, 65,           MD_SIS315},
+       {"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},
        {"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},
+/*130*/        {"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},
-/*130*/        {"1920x1440x32", {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},
        {"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},
@@ -313,13 +323,13 @@ static const struct _sisbios_mode {
        {"\0", {0x00,0x00}, 0, 0, 0, 0, 0, 0, 0}
 };
 
-#define SIS_LCD_NUMBER 17
-static const struct _sis_lcd_data {
+#define SIS_LCD_NUMBER 18
+static struct _sis_lcd_data {
        u32 lcdtype;
        u16 xres;
        u16 yres;
        u8  default_mode_idx;
-} sis_lcd_data[] = {
+} sis_lcd_data[] __devinitdata = {
        { LCD_640x480,    640,  480,  23 },
        { LCD_800x600,    800,  600,  43 },
        { LCD_1024x600,  1024,  600,  67 },
@@ -329,34 +339,38 @@ static const struct _sis_lcd_data {
        { 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 },
+       { LCD_1280x854,  1280,  854,  95 },
+       { LCD_1280x960,  1280,  960,  99 },
+       { LCD_1280x1024, 1280, 1024, 103 },
+       { LCD_1400x1050, 1400, 1050, 115 },
+       { LCD_1680x1050, 1680, 1050, 123 },
+       { LCD_1600x1200, 1600, 1200, 119 },
+       { LCD_320x240_2,  320,  240,   9 },
+       { LCD_320x240_3,  320,  240,   9 },
+       { LCD_320x240,    320,  240,   9 },
 };
 
 /* CR36 evaluation */
-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 };
-
-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 };
-
-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,
-      LCD_1280x800,  LCD_1680x1050, LCD_1280x720,  LCD_UNKNOWN };
+static unsigned short sis300paneltype[] __devinitdata = {
+       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
+};
+
+static unsigned short sis310paneltype[] __devinitdata = {
+       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_320x240_2, LCD_320x240_3, LCD_UNKNOWN,   LCD_UNKNOWN
+};
+
+static unsigned short sis661paneltype[] __devinitdata = {
+       LCD_UNKNOWN,   LCD_800x600,   LCD_1024x768,  LCD_1280x1024,
+       LCD_640x480,   LCD_1024x600,  LCD_1152x864,  LCD_1280x960,
+       LCD_1280x854,  LCD_1400x1050, LCD_1280x768,  LCD_1600x1200,
+       LCD_1280x800,  LCD_1680x1050, LCD_1280x720,  LCD_UNKNOWN
+};
 
 #define FL_550_DSTN 0x01
 #define FL_550_FSTN 0x02
@@ -413,7 +427,6 @@ static const struct _sis_vrate {
 } sisfb_vrate[] = {
        {1,  320,  200,  70,  TRUE},
        {1,  320,  240,  60,  TRUE},
-       {1,  320,  480,  60,  TRUE},
        {1,  400,  300,  60,  TRUE},
        {1,  512,  384,  60,  TRUE},
        {1,  640,  400,  72,  TRUE},
@@ -437,10 +450,11 @@ static const struct _sis_vrate {
        {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,  60,  TRUE}, {1, 1152,  864,  75,  TRUE}, {2, 1152,  864,  84,  TRUE},
+       {1, 1152,  864,  60,  TRUE}, {2, 1152,  864,  75,  TRUE}, {3, 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},
+       {1, 1280,  854,  60,  TRUE},
        {1, 1280,  960,  60,  TRUE}, {2, 1280,  960,  85,  TRUE},
        {1, 1280, 1024,  43,  TRUE}, {2, 1280, 1024,  60,  TRUE}, {3, 1280, 1024,  75,  TRUE},
        {4, 1280, 1024,  85,  TRUE},
@@ -459,12 +473,12 @@ static const struct _sis_vrate {
        {0,    0,    0,   0, FALSE}
 };
 
-static const struct _sisfbddcsmodes {
+static struct _sisfbddcsmodes {
        u32 mask;
        u16 h;
        u16 v;
        u32 d;
-} sisfb_ddcsmodes[] = {
+} sisfb_ddcsmodes[] __devinitdata = {
        { 0x10000, 67, 75, 108000},
        { 0x08000, 48, 72,  50000},
        { 0x04000, 46, 75,  49500},
@@ -480,49 +494,49 @@ static const struct _sisfbddcsmodes {
        { 0x00001, 38, 60,  40000}
 };
 
-static const struct _sisfbddcfmodes {
+static struct _sisfbddcfmodes {
        u16 x;
        u16 y;
        u16 v;
        u16 h;
        u32 d;
-} sisfb_ddcfmodes[] = {
-       { 1280, 1024, 85, 92, 157500},
-       { 1600, 1200, 60, 75, 162000},
-       { 1600, 1200, 65, 82, 175500},
-       { 1600, 1200, 70, 88, 189000},
-       { 1600, 1200, 75, 94, 202500},
-       { 1600, 1200, 85, 107,229500},
-       { 1920, 1440, 60, 90, 234000},
-       { 1920, 1440, 75, 113,297000}
+} sisfb_ddcfmodes[] __devinitdata = {
+       { 1280, 1024, 85, 92, 157500},
+       { 1600, 1200, 60, 75, 162000},
+       { 1600, 1200, 65, 82, 175500},
+       { 1600, 1200, 70, 88, 189000},
+       { 1600, 1200, 75, 94, 202500},
+       { 1600, 1200, 85, 107,229500},
+       { 1920, 1440, 60, 90, 234000},
+       { 1920, 1440, 75, 113,297000}
 };
 
 #ifdef CONFIG_FB_SIS_300
 static struct _chswtable {
-    u16  subsysVendor;
-    u16  subsysCard;
-    char *vendorName;
-    char *cardName;
+       u16  subsysVendor;
+       u16  subsysCard;
+       char *vendorName;
+       char *cardName;
 } mychswtable[] __devinitdata = {
-        { 0x1631, 0x1002, "Mitachi", "0x1002" },
+       { 0x1631, 0x1002, "Mitachi", "0x1002" },
        { 0x1071, 0x7521, "Mitac"  , "7521P"  },
        { 0,      0,      ""       , ""       }
 };
 #endif
 
 static struct _customttable {
-    u16   chipID;
-    char  *biosversion;
-    char  *biosdate;
-    u32   bioschksum;
-    u16   biosFootprintAddr[5];
-    u8    biosFootprintData[5];
-    u16   pcisubsysvendor;
-    u16   pcisubsyscard;
-    char  *vendorName;
-    char  *cardName;
-    u32   SpecialID;
-    char  *optionName;
+       u16   chipID;
+       char  *biosversion;
+       char  *biosdate;
+       u32   bioschksum;
+       u16   biosFootprintAddr[5];
+       u8    biosFootprintData[5];
+       u16   pcisubsysvendor;
+       u16   pcisubsyscard;
+       char  *vendorName;
+       char  *cardName;
+       u32   SpecialID;
+       char  *optionName;
 } mycustomttable[] __devinitdata = {
        { SIS_630, "2.00.07", "09/27/2002-13:38:25",
          0x3240A8,
@@ -643,6 +657,13 @@ static struct _customttable {
          0, 0,
          "Generic", "LVDS/Parallel 848x480", CUT_PANEL848, "PANEL848x480"
        },
+       { 4322, "", "",                 /* never autodetected */
+         0,
+         { 0, 0, 0, 0, 0 },
+         { 0, 0, 0, 0, 0 },
+         0, 0,
+         "Generic", "LVDS/Parallel 856x480", CUT_PANEL856, "PANEL856x480"
+       },
        { 0, "", "",
          0,
          { 0, 0, 0, 0 },
@@ -652,155 +673,6 @@ static struct _customttable {
        }
 };
 
-static const struct _sis_TV_filter {
-       u8 filter[9][4];
-} sis_TV_filter[] = {
-       { {{0x00,0x00,0x00,0x40},  /* NTSCFilter_0 */
-          {0x00,0xE0,0x10,0x60},
-          {0x00,0xEE,0x10,0x44},
-          {0x00,0xF4,0x10,0x38},
-          {0xF8,0xF4,0x18,0x38},
-          {0xFC,0xFB,0x14,0x2A},
-          {0x00,0x00,0x10,0x20},
-          {0x00,0x04,0x10,0x18}, 
-          {0xFF,0xFF,0xFF,0xFF} }},
-       { {{0x00,0x00,0x00,0x40},  /* NTSCFilter_1 */
-          {0x00,0xE0,0x10,0x60},
-          {0x00,0xEE,0x10,0x44},
-          {0x00,0xF4,0x10,0x38},
-          {0xF8,0xF4,0x18,0x38},
-          {0xFC,0xFB,0x14,0x2A},
-          {0x00,0x00,0x10,0x20},
-          {0x00,0x04,0x10,0x18},
-          {0xFF,0xFF,0xFF,0xFF} }},
-       { {{0x00,0x00,0x00,0x40},  /* NTSCFilter_2 */
-          {0xF5,0xEE,0x1B,0x44},
-          {0xF8,0xF4,0x18,0x38},
-          {0xEB,0x04,0x25,0x18},
-          {0xF1,0x05,0x1F,0x16},
-          {0xF6,0x06,0x1A,0x14},
-          {0xFA,0x06,0x16,0x14},
-          {0x00,0x04,0x10,0x18}, 
-          {0xFF,0xFF,0xFF,0xFF} }},
-       { {{0x00,0x00,0x00,0x40},  /* NTSCFilter_3 */
-          {0xF1,0x04,0x1F,0x18},
-          {0xEE,0x0D,0x22,0x06},
-          {0xF7,0x06,0x19,0x14},
-          {0xF4,0x0B,0x1C,0x0A},
-          {0xFA,0x07,0x16,0x12},
-          {0xF9,0x0A,0x17,0x0C},
-          {0x00,0x07,0x10,0x12}, 
-          {0xFF,0xFF,0xFF,0xFF} }},
-       { {{0x00,0x00,0x00,0x40},  /* NTSCFilter_4 - 320 */
-          {0x00,0xE0,0x10,0x60},
-          {0x00,0xEE,0x10,0x44},
-          {0x00,0xF4,0x10,0x38},
-          {0xF8,0xF4,0x18,0x38},
-          {0xFC,0xFB,0x14,0x2A},
-          {0x00,0x00,0x10,0x20},
-          {0x00,0x04,0x10,0x18}, 
-          {0xFF,0xFF,0xFF,0xFF} }},
-       { {{0x00,0x00,0x00,0x40},  /* NTSCFilter_5 - 640 */
-          {0xF5,0xEE,0x1B,0x44},
-          {0xF8,0xF4,0x18,0x38},
-          {0xEB,0x04,0x25,0x18},
-          {0xF1,0x05,0x1F,0x16},
-          {0xF6,0x06,0x1A,0x14},
-          {0xFA,0x06,0x16,0x14},
-          {0x00,0x04,0x10,0x18}, 
-          {0xFF,0xFF,0xFF,0xFF} }},
-       { {{0x00,0x00,0x00,0x40},  /* NTSCFilter_6 - 720 */
-          {0xEB,0x04,0x25,0x18},
-          {0xE7,0x0E,0x29,0x04},
-          {0xEE,0x0C,0x22,0x08},
-          {0xF6,0x0B,0x1A,0x0A},
-          {0xF9,0x0A,0x17,0x0C},
-          {0xFC,0x0A,0x14,0x0C},
-          {0x00,0x08,0x10,0x10}, 
-          {0xFF,0xFF,0xFF,0xFF} }},
-       { {{0x00,0x00,0x00,0x40},  /* NTSCFilter_7 - 800 */
-          {0xEC,0x02,0x24,0x1C},
-          {0xF2,0x04,0x1E,0x18},
-          {0xEB,0x15,0x25,0xF6},
-          {0xF4,0x10,0x1C,0x00},
-          {0xF8,0x0F,0x18,0x02},
-          {0x00,0x04,0x10,0x18},
-          {0x01,0x06,0x0F,0x14}, 
-          {0xFF,0xFF,0xFF,0xFF} }},
-       { {{0x00,0x00,0x00,0x40},  /* PALFilter_0 */
-          {0x00,0xE0,0x10,0x60},
-          {0x00,0xEE,0x10,0x44},
-          {0x00,0xF4,0x10,0x38},
-          {0xF8,0xF4,0x18,0x38},
-          {0xFC,0xFB,0x14,0x2A},
-          {0x00,0x00,0x10,0x20},
-          {0x00,0x04,0x10,0x18}, 
-          {0xFF,0xFF,0xFF,0xFF} }},
-       { {{0x00,0x00,0x00,0x40},  /* PALFilter_1 */
-          {0x00,0xE0,0x10,0x60},
-          {0x00,0xEE,0x10,0x44},
-          {0x00,0xF4,0x10,0x38},
-          {0xF8,0xF4,0x18,0x38},
-          {0xFC,0xFB,0x14,0x2A},
-          {0x00,0x00,0x10,0x20},
-          {0x00,0x04,0x10,0x18}, 
-          {0xFF,0xFF,0xFF,0xFF} }},
-       { {{0x00,0x00,0x00,0x40},  /* PALFilter_2 */
-          {0xF5,0xEE,0x1B,0x44},
-          {0xF8,0xF4,0x18,0x38},
-          {0xF1,0xF7,0x01,0x32},
-          {0xF5,0xFB,0x1B,0x2A},
-          {0xF9,0xFF,0x17,0x22},
-          {0xFB,0x01,0x15,0x1E},
-          {0x00,0x04,0x10,0x18}, 
-          {0xFF,0xFF,0xFF,0xFF} }},
-       { {{0x00,0x00,0x00,0x40},  /* PALFilter_3 */
-          {0xF5,0xFB,0x1B,0x2A},
-          {0xEE,0xFE,0x22,0x24},
-          {0xF3,0x00,0x1D,0x20},
-          {0xF9,0x03,0x17,0x1A},
-          {0xFB,0x02,0x14,0x1E},
-          {0xFB,0x04,0x15,0x18},
-          {0x00,0x06,0x10,0x14}, 
-          {0xFF,0xFF,0xFF,0xFF} }},
-       { {{0x00,0x00,0x00,0x40},  /* PALFilter_4 - 320 */
-          {0x00,0xE0,0x10,0x60},
-          {0x00,0xEE,0x10,0x44},
-          {0x00,0xF4,0x10,0x38},
-          {0xF8,0xF4,0x18,0x38},
-          {0xFC,0xFB,0x14,0x2A},
-          {0x00,0x00,0x10,0x20},
-          {0x00,0x04,0x10,0x18}, 
-          {0xFF,0xFF,0xFF,0xFF} }},
-       { {{0x00,0x00,0x00,0x40},  /* PALFilter_5 - 640 */
-          {0xF5,0xEE,0x1B,0x44},
-          {0xF8,0xF4,0x18,0x38},
-          {0xF1,0xF7,0x1F,0x32},
-          {0xF5,0xFB,0x1B,0x2A},
-          {0xF9,0xFF,0x17,0x22},
-          {0xFB,0x01,0x15,0x1E},
-          {0x00,0x04,0x10,0x18}, 
-          {0xFF,0xFF,0xFF,0xFF} }},
-       { {{0x00,0x00,0x00,0x40},  /* PALFilter_6 - 720 */
-          {0xF5,0xEE,0x1B,0x2A},
-          {0xEE,0xFE,0x22,0x24},
-          {0xF3,0x00,0x1D,0x20},
-          {0xF9,0x03,0x17,0x1A},
-          {0xFB,0x02,0x14,0x1E},
-          {0xFB,0x04,0x15,0x18},
-          {0x00,0x06,0x10,0x14}, 
-          {0xFF,0xFF,0xFF,0xFF} }},
-       { {{0x00,0x00,0x00,0x40},  /* PALFilter_7 - 800 */
-          {0xF5,0xEE,0x1B,0x44},
-          {0xF8,0xF4,0x18,0x38},
-          {0xFC,0xFB,0x14,0x2A},
-          {0xEB,0x05,0x25,0x16},
-          {0xF1,0x05,0x1F,0x16},
-          {0xFA,0x07,0x16,0x12},
-          {0x00,0x07,0x10,0x12}, 
-          {0xFF,0xFF,0xFF,0xFF} }}
-};
-
 /* ---------------------- Prototypes ------------------------- */
 
 /* Interface used by the world */
@@ -811,145 +683,159 @@ SISINITSTATIC int sisfb_setup(char *options);
 /* Interface to the low level console driver */
 SISINITSTATIC int sisfb_init(void);
 
-
 /* fbdev routines */
-static int      sisfb_get_fix(struct fb_fix_screeninfo *fix, int con,
-                             struct fb_info *info);
+static int     sisfb_get_fix(struct fb_fix_screeninfo *fix, int con,
+                               struct fb_info *info);
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-static int      sisfb_get_fix(struct fb_fix_screeninfo *fix, 
-                             int con,
-                             struct fb_info *info);
-static int      sisfb_get_var(struct fb_var_screeninfo *var, 
-                             int con,
-                             struct fb_info *info);
-static int      sisfb_set_var(struct fb_var_screeninfo *var, 
-                             int con,
-                             struct fb_info *info);
-static void     sisfb_crtc_to_var(struct sis_video_info *ivideo,
-                                 struct fb_var_screeninfo *var);
-static int      sisfb_get_cmap(struct fb_cmap *cmap, 
-                              int kspc, 
-                              int con,
-                              struct fb_info *info);
-static int      sisfb_set_cmap(struct fb_cmap *cmap, 
-                              int kspc, 
-                              int con,
-                              struct fb_info *info);                   
-static int      sisfb_update_var(int con, 
-                                struct fb_info *info);
-static int      sisfb_switch(int con, 
+static int     sisfb_get_fix(struct fb_fix_screeninfo *fix,
+                               int con,
+                               struct fb_info *info);
+static int     sisfb_get_var(struct fb_var_screeninfo *var,
+                               int con,
+                               struct fb_info *info);
+static int     sisfb_set_var(struct fb_var_screeninfo *var,
+                               int con,
+                               struct fb_info *info);
+static void    sisfb_crtc_to_var(struct sis_video_info *ivideo,
+                               struct fb_var_screeninfo *var);
+static int     sisfb_get_cmap(struct fb_cmap *cmap,
+                               int kspc,
+                               int con,
+                               struct fb_info *info);
+static int     sisfb_set_cmap(struct fb_cmap *cmap,
+                               int kspc,
+                               int con,
+                               struct fb_info *info);
+static int     sisfb_update_var(int con,
+                               struct fb_info *info);
+static int     sisfb_switch(int con,
                             struct fb_info *info);
-static void     sisfb_blank(int blank, 
-                           struct fb_info *info);
-static void     sisfb_set_disp(int con, 
-                              struct fb_var_screeninfo *var, 
-                               struct fb_info *info);
-static int      sis_getcolreg(unsigned regno, unsigned *red, unsigned *green,
-                             unsigned *blue, unsigned *transp,
-                             struct fb_info *fb_info);
-static void     sisfb_do_install_cmap(int con, 
-                                      struct fb_info *info);
-static int      sisfb_ioctl(struct inode *inode, struct file *file,
-                           unsigned int cmd, unsigned long arg, int con,
-                           struct fb_info *info);                    
-#endif                 
+static void    sisfb_blank(int blank,
+                               struct fb_info *info);
+static void    sisfb_set_disp(int con,
+                               struct fb_var_screeninfo *var,
+                               struct fb_info *info);
+static int     sis_getcolreg(unsigned regno, unsigned *red, unsigned *green,
+                               unsigned *blue, unsigned *transp,
+                               struct fb_info *fb_info);
+static void    sisfb_do_install_cmap(int con,
+                               struct fb_info *info);
+static int     sisfb_ioctl(struct inode *inode, struct file *file,
+                               unsigned int cmd, unsigned long arg, int con,
+                               struct fb_info *info);
+#endif
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-static int      sisfb_ioctl(struct inode *inode, struct file *file,
-                           unsigned int cmd, unsigned long arg,
-                           struct fb_info *info);
-static int      sisfb_set_par(struct fb_info *info);
-static int      sisfb_blank(int blank, 
-                            struct fb_info *info);                     
-extern void     fbcon_sis_fillrect(struct fb_info *info, 
-                                   const struct fb_fillrect *rect);
-extern void     fbcon_sis_copyarea(struct fb_info *info, 
-                                   const struct fb_copyarea *area);
-extern int      fbcon_sis_sync(struct fb_info *info);
+static int     sisfb_ioctl(struct inode *inode, struct file *file,
+                               unsigned int cmd, unsigned long arg,
+                               struct fb_info *info);
+static int     sisfb_set_par(struct fb_info *info);
+static int     sisfb_blank(int blank,
+                               struct fb_info *info);
+extern void    fbcon_sis_fillrect(struct fb_info *info,
+                               const struct fb_fillrect *rect);
+extern void    fbcon_sis_copyarea(struct fb_info *info,
+                               const struct fb_copyarea *area);
+extern int     fbcon_sis_sync(struct fb_info *info);
 #endif
-                       
+
 /* Internal 2D accelerator functions */
-extern int      sisfb_initaccel(struct sis_video_info *ivideo);
-extern void     sisfb_syncaccel(struct sis_video_info *ivideo);
+extern int     sisfb_initaccel(struct sis_video_info *ivideo);
+extern void    sisfb_syncaccel(struct sis_video_info *ivideo);
 
 /* Internal general routines */
-static void     sisfb_search_mode(char *name, BOOLEAN quiet);
-static int      sisfb_validate_mode(struct sis_video_info *ivideo, int modeindex, u32 vbflags);
-static u8       sisfb_search_refresh_rate(struct sis_video_info *ivideo, unsigned int rate,
-                       int index);
-static int      sisfb_setcolreg(unsigned regno, unsigned red, unsigned green,
-                       unsigned blue, unsigned transp,
-                       struct fb_info *fb_info);
-static int      sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
-                       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 BOOLEAN  sisfb_CheckVBRetrace(struct sis_video_info *ivideo);
-static BOOLEAN  sisfbcheckvretracecrt2(struct sis_video_info *ivideo);
-static BOOLEAN  sisfbcheckvretracecrt1(struct sis_video_info *ivideo);
-static BOOLEAN  sisfb_bridgeisslave(struct sis_video_info *ivideo);
-static void     sisfb_detect_VB_connect(struct sis_video_info *ivideo);
-static void     sisfb_get_VB_type(struct sis_video_info *ivideo);
-static void     sisfb_set_TVxposoffset(struct sis_video_info *ivideo, int val);
-static void     sisfb_set_TVyposoffset(struct sis_video_info *ivideo, int val);
+static void    sisfb_search_mode(char *name, BOOLEAN quiet);
+static int     sisfb_validate_mode(struct sis_video_info *ivideo, int modeindex, u32 vbflags);
+static u8      sisfb_search_refresh_rate(struct sis_video_info *ivideo, unsigned int rate,
+                               int index);
+static int     sisfb_setcolreg(unsigned regno, unsigned red, unsigned green,
+                               unsigned blue, unsigned transp,
+                               struct fb_info *fb_info);
+static int     sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
+                               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 BOOLEAN sisfb_CheckVBRetrace(struct sis_video_info *ivideo);
+static BOOLEAN sisfbcheckvretracecrt2(struct sis_video_info *ivideo);
+static BOOLEAN sisfbcheckvretracecrt1(struct sis_video_info *ivideo);
+static BOOLEAN sisfb_bridgeisslave(struct sis_video_info *ivideo);
+static void    sisfb_detect_VB_connect(struct sis_video_info *ivideo);
+static void    sisfb_get_VB_type(struct sis_video_info *ivideo);
+static void    sisfb_set_TVxposoffset(struct sis_video_info *ivideo, int val);
+static void    sisfb_set_TVyposoffset(struct sis_video_info *ivideo, int val);
+#ifdef CONFIG_FB_SIS_300
+unsigned int   sisfb_read_nbridge_pci_dword(struct SiS_Private *SiS_Pr, int reg);
+void           sisfb_write_nbridge_pci_dword(struct SiS_Private *SiS_Pr, int reg, unsigned int val);
+unsigned int   sisfb_read_lpc_pci_dword(struct SiS_Private *SiS_Pr, int reg);
+#endif
+#ifdef CONFIG_FB_SIS_315
+void           sisfb_write_nbridge_pci_byte(struct SiS_Private *SiS_Pr, int reg, unsigned char val);
+unsigned int   sisfb_read_mio_pci_word(struct SiS_Private *SiS_Pr, int reg);
+#endif
 
 /* SiS-specific exported functions */
-void            sis_malloc(struct sis_memreq *req);
-void            sis_free(u32 base);
+void                   sis_malloc(struct sis_memreq *req);
+void                   sis_malloc_new(struct pci_dev *pdev, struct sis_memreq *req);
+void                   sis_free(u32 base);
+void                   sis_free_new(struct pci_dev *pdev, u32 base);
 
 /* Internal heap routines */
-static int      sisfb_heap_init(struct sis_video_info *ivideo);
-static SIS_OH   *sisfb_poh_new_node(void);
-static SIS_OH   *sisfb_poh_allocate(u32 size);
-static void     sisfb_delete_node(SIS_OH *poh);
-static void     sisfb_insert_node(SIS_OH *pohList, SIS_OH *poh);
-static SIS_OH   *sisfb_poh_free(u32 base);
-static void     sisfb_free_node(SIS_OH *poh);
-
-/* Sensing routines */
-static void     SiS_Sense30x(struct sis_video_info *ivideo);
-static void     SiS_SenseCh(struct sis_video_info *ivideo);
+static int             sisfb_heap_init(struct sis_video_info *ivideo);
+static struct SIS_OH * sisfb_poh_new_node(struct SIS_HEAP *memheap);
+static struct SIS_OH * sisfb_poh_allocate(struct SIS_HEAP *memheap, u32 size);
+static void            sisfb_delete_node(struct SIS_OH *poh);
+static void            sisfb_insert_node(struct SIS_OH *pohList, struct SIS_OH *poh);
+static struct SIS_OH * sisfb_poh_free(struct SIS_HEAP *memheap, u32 base);
+static void            sisfb_free_node(struct SIS_HEAP *memheap, struct SIS_OH *poh);
 
 /* Routines from init.c/init301.c */
-extern USHORT   SiS_GetModeID_LCD(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth,
-                                  BOOLEAN FSTN, USHORT CustomT, int LCDwith, int LCDheight);
-extern USHORT   SiS_GetModeID_TV(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth);
-extern USHORT   SiS_GetModeID_VGA2(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth);
-
-extern void    SiSRegInit(SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr);
-extern BOOLEAN  SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwDeviceInfo, USHORT ModeNo);
-extern void     SiS_SetEnableDstn(SiS_Private *SiS_Pr, int enable);
-extern void     SiS_SetEnableFstn(SiS_Private *SiS_Pr, int enable);
-
-extern BOOLEAN  SiSDetermineROMLayout661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
-
-extern BOOLEAN  sisfb_gettotalfrommode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwDeviceExtension,
-                      unsigned char modeno, int *htotal, int *vtotal, unsigned char rateindex);
+extern unsigned short  SiS_GetModeID_LCD(int VGAEngine, unsigned int VBFlags, int HDisplay,
+                               int VDisplay, int Depth, BOOLEAN FSTN, unsigned short CustomT,
+                               int LCDwith, int LCDheight, unsigned int VBFlags2);
+extern unsigned short  SiS_GetModeID_TV(int VGAEngine, unsigned int VBFlags, int HDisplay,
+                               int VDisplay, int Depth, unsigned int VBFlags2);
+extern unsigned short  SiS_GetModeID_VGA2(int VGAEngine, unsigned int VBFlags, int HDisplay,
+                               int VDisplay, int Depth, unsigned int VBFlags2);
+extern void            SiSRegInit(struct SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr);
+extern BOOLEAN         SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo);
+extern void            SiS_SetEnableDstn(struct SiS_Private *SiS_Pr, int enable);
+extern void            SiS_SetEnableFstn(struct SiS_Private *SiS_Pr, int enable);
+
+extern BOOLEAN         SiSDetermineROMLayout661(struct SiS_Private *SiS_Pr);
+
+extern BOOLEAN         sisfb_gettotalfrommode(struct SiS_Private *SiS_Pr, unsigned char modeno,
+                               int *htotal, int *vtotal, unsigned char rateindex);
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-extern int     sisfb_mode_rate_to_dclock(SiS_Private *SiS_Pr,
-                       PSIS_HW_INFO HwDeviceExtension,
-                       unsigned char modeno, unsigned char rateindex);
-extern int      sisfb_mode_rate_to_ddata(SiS_Private *SiS_Pr, PSIS_HW_INFO HwDeviceExtension,
-                       unsigned char modeno, unsigned char rateindex,
-                       struct fb_var_screeninfo *var);
+extern int             sisfb_mode_rate_to_dclock(struct SiS_Private *SiS_Pr,
+                               unsigned char modeno, unsigned char rateindex);
+extern int             sisfb_mode_rate_to_ddata(struct SiS_Private *SiS_Pr, unsigned char modeno,
+                               unsigned char rateindex, struct fb_var_screeninfo *var);
+#endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+extern void            SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata, int xres,
+                               int yres, struct fb_var_screeninfo *var, BOOLEAN writeres);
 #endif
 
 /* Chrontel TV, DDC and DPMS functions */
-extern USHORT  SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempbx);
-extern void    SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempbx);
-extern USHORT  SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempbx);
-extern void    SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempbx);
-extern void     SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, USHORT tempax,USHORT tempbh);
-extern void     SiS_DDC2Delay(SiS_Private *SiS_Pr, USHORT delaytime);
-extern void     SiS_SetChrontelGPIO(SiS_Private *SiS_Pr, USHORT myvbinfo);
-extern USHORT   SiS_HandleDDC(SiS_Private *SiS_Pr, ULONG VBFlags, int VGAEngine,
-                             USHORT adaptnum, USHORT DDCdatatype, unsigned char *buffer);
-extern USHORT   SiS_ReadDDC1Bit(SiS_Private *SiS_Pr);
-extern void    SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwDeviceInfo);
-extern void    SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr);
-extern void    SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwDeviceInfo);
-extern void    SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwDeviceInfo);
+extern unsigned short  SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short reg);
+extern void            SiS_SetCH700x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);
+extern unsigned short  SiS_GetCH701x(struct SiS_Private *SiS_Pr, unsigned short reg);
+extern void            SiS_SetCH701x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);
+extern void            SiS_SetCH70xxANDOR(struct SiS_Private *SiS_Pr, unsigned short reg,
+                               unsigned char myor, unsigned char myand);
+extern void            SiS_DDC2Delay(struct SiS_Private *SiS_Pr, unsigned int delaytime);
+extern void            SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo);
+extern unsigned short  SiS_HandleDDC(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
+                               unsigned short adaptnum, unsigned short DDCdatatype, unsigned char *buffer,
+                               unsigned int VBFlags2);
+extern unsigned short  SiS_ReadDDC1Bit(struct SiS_Private *SiS_Pr);
+#ifdef CONFIG_FB_SIS_315
+extern void            SiS_Chrontel701xBLOn(struct SiS_Private *SiS_Pr);
+extern void            SiS_Chrontel701xBLOff(struct SiS_Private *SiS_Pr);
+#endif
+extern void            SiS_SiS30xBLOn(struct SiS_Private *SiS_Pr);
+extern void            SiS_SiS30xBLOff(struct SiS_Private *SiS_Pr);
 #endif
 
 
index 507bba1..831b9f4 100644 (file)
@@ -3,7 +3,7 @@
 /*
  * General type definitions for universal mode switching modules
  *
- * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
  *
  * If distributed as part of the Linux kernel, the following license terms
  * apply:
  *
  */
 
-#ifndef _VGATYPES_
-#define _VGATYPES_
+#ifndef _VGATYPES_H_
+#define _VGATYPES_H_
 
-#ifdef LINUX_KERNEL  /* We don't want the X driver to depend on kernel source */
-#include <linux/ioctl.h>
+#ifdef SIS_LINUX_KERNEL
 #include <linux/version.h>
 #endif
 
 #define TRUE    1
 #endif
 
-#ifndef NULL
-#define NULL    0
-#endif
-
-#ifndef CHAR
-typedef char CHAR;
-#endif
-
-#ifndef SHORT
-typedef short SHORT;
-#endif
-
-#ifndef LONG
-typedef long  LONG;
-#endif
-
-#ifndef UCHAR
-typedef unsigned char UCHAR;
-#endif
-
-#ifndef USHORT
-typedef unsigned short USHORT;
-#endif
-
-#ifndef ULONG
-typedef unsigned long ULONG;
-#endif
-
 #ifndef BOOLEAN
-typedef unsigned char BOOLEAN;
+typedef unsigned int BOOLEAN;
 #endif
 
 #define SISIOMEMTYPE
 
-#ifdef LINUX_KERNEL
+#ifdef SIS_LINUX_KERNEL
 typedef unsigned long SISIOADDRESS;
 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)
 #include <linux/types.h>  /* Need __iomem */
@@ -109,7 +80,7 @@ typedef unsigned long SISIOADDRESS;
 #endif
 #endif
 
-#ifdef LINUX_XF86
+#ifdef SIS_XORG_XF86
 #if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,0,0,0)
 typedef unsigned long IOADDRESS;
 typedef unsigned long SISIOADDRESS;
@@ -118,7 +89,7 @@ typedef IOADDRESS SISIOADDRESS;
 #endif
 #endif
 
-enum _SIS_CHIP_TYPE {
+typedef enum _SIS_CHIP_TYPE {
     SIS_VGALegacy = 0,
     SIS_530,
     SIS_OLD,
@@ -128,115 +99,27 @@ enum _SIS_CHIP_TYPE {
     SIS_540,
     SIS_315H,   /* SiS 310 */
     SIS_315,
-    SIS_315PRO,
+    SIS_315PRO, /* SiS 325 */
     SIS_550,
     SIS_650,
     SIS_740,
     SIS_330,
     SIS_661,
     SIS_741,
-    SIS_660,
+    SIS_670,
+    SIS_660 = 35,
     SIS_760,
     SIS_761,
-    SIS_340,
+    SIS_762,
+    SIS_770,
+    SIS_340 = 55,
+    SIS_341,
+    SIS_342,
+    XGI_20  = 75,
+    XGI_40,
     MAX_SIS_CHIP
-};
-
-#ifndef SIS_HW_INFO
-typedef struct _SIS_HW_INFO  SIS_HW_INFO, *PSIS_HW_INFO;
-
-struct _SIS_HW_INFO
-{
-#ifdef LINUX_XF86
-    PCITAG PciTag;              /* PCI Tag */
-#endif
-
-    UCHAR *pjVirtualRomBase;    /* ROM image */
-
-    BOOLEAN UseROM;             /* Use the ROM image if provided */
-
-#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) */
-
-    UCHAR  jChipType;            /* Used to Identify SiS Graphics Chip */
-                                 /* defined in the enum "SIS_CHIP_TYPE" (above or sisfb.h) */
+} SIS_CHIP_TYPE;
 
-    UCHAR  jChipRevision;        /* Used to Identify SiS Graphics Chip Revision */
-
-    BOOLEAN bIntegratedMMEnabled;/* supporting integration MM enable */
-};
-#endif
-
-/* Addtional IOCTLs for communication sisfb <> X driver        */
-/* If changing this, sisfb.h must also be changed (for sisfb) */
-
-#ifdef LINUX_XF86  /* We don't want the X driver to depend on the kernel source */
-
-/* ioctl for identifying and giving some info (esp. memory heap start) */
-#define SISFB_GET_INFO_SIZE    0x8004f300
-#define SISFB_GET_INFO         0x8000f301  /* Must be patched with result from ..._SIZE at D[29:16] */
-/* deprecated ioctl number (for older versions of sisfb) */
-#define SISFB_GET_INFO_OLD     0x80046ef8
-
-/* ioctls for tv parameters (position) */
-#define SISFB_SET_TVPOSOFFSET   0x4004f304
-
-/* lock sisfb from register access */
-#define SISFB_SET_LOCK         0x4004f306
-
-/* Structure argument for SISFB_GET_INFO ioctl  */
-typedef struct _SISFB_INFO sisfb_info, *psisfb_info;
-
-struct _SISFB_INFO {
-       CARD32  sisfb_id;               /* for identifying sisfb */
-#ifndef SISFB_ID
-#define SISFB_ID         0x53495346    /* Identify myself with 'SISF' */
-#endif
-       CARD32  chip_id;                /* PCI ID of detected chip */
-       CARD32  memory;                 /* video memory in KB which sisfb manages */
-       CARD32  heapstart;              /* heap start (= sisfb "mem" argument) in KB */
-       CARD8   fbvidmode;              /* current sisfb mode */
-
-       CARD8   sisfb_version;
-       CARD8   sisfb_revision;
-       CARD8   sisfb_patchlevel;
-
-       CARD8   sisfb_caps;             /* sisfb's capabilities */
-
-       CARD32  sisfb_tqlen;            /* turbo queue length (in KB) */
-
-       CARD32  sisfb_pcibus;           /* The card's PCI ID */
-       CARD32  sisfb_pcislot;
-       CARD32  sisfb_pcifunc;
-
-       CARD8   sisfb_lcdpdc;
-
-       CARD8   sisfb_lcda;
-
-       CARD32  sisfb_vbflags;
-       CARD32  sisfb_currentvbflags;
-
-       CARD32  sisfb_scalelcd;
-       CARD32  sisfb_specialtiming;
-
-       CARD8   sisfb_haveemi;
-       CARD8   sisfb_emi30,sisfb_emi31,sisfb_emi32,sisfb_emi33;
-       CARD8   sisfb_haveemilcd;
-
-       CARD8   sisfb_lcdpdca;
-
-       CARD16  sisfb_tvxpos, sisfb_tvypos;     /* Warning: Values + 32 ! */
-
-       CARD8 reserved[208];                    /* for future use */
-};
-#endif
 
 #endif
 
index d4d55c9..9ae3292 100644 (file)
@@ -3,7 +3,7 @@
 /*
  * General structure definitions for universal mode switching modules
  *
- * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
  *
  * If distributed as part of the Linux kernel, the following license terms
  * apply:
  *
  */
 
-#ifndef _VSTRUCT_
-#define _VSTRUCT_
-
-typedef struct _SiS_PanelDelayTblStruct
-{
-       UCHAR timer[2];
-} SiS_PanelDelayTblStruct;
-
-typedef struct _SiS_LCDDataStruct
-{
-       USHORT RVBHCMAX;
-       USHORT RVBHCFACT;
-       USHORT VGAHT;
-       USHORT VGAVT;
-       USHORT LCDHT;
-       USHORT LCDVT;
-} SiS_LCDDataStruct;
-
-typedef struct _SiS_TVDataStruct
-{
-       USHORT RVBHCMAX;
-       USHORT RVBHCFACT;
-       USHORT VGAHT;
-       USHORT VGAVT;
-       USHORT TVHDE;
-       USHORT TVVDE;
-       USHORT RVBHRS;
-       UCHAR  FlickerMode;
-       USHORT HALFRVBHRS;
-       UCHAR  RY1COE;
-       UCHAR  RY2COE;
-       UCHAR  RY3COE;
-       UCHAR  RY4COE;
-} SiS_TVDataStruct;
-
-typedef struct _SiS_LVDSDataStruct
-{
-       USHORT VGAHT;
-       USHORT VGAVT;
-       USHORT LCDHT;
-       USHORT LCDVT;
-} SiS_LVDSDataStruct;
-
-typedef struct _SiS_LVDSDesStruct
-{
-       USHORT LCDHDES;
-       USHORT LCDVDES;
-} SiS_LVDSDesStruct;
-
-typedef struct _SiS_LVDSCRT1DataStruct
-{
-       UCHAR  CR[15];
-} SiS_LVDSCRT1DataStruct;
-
-typedef struct _SiS_LCDACRT1DataStruct
-{
-       UCHAR  CR[17];
-} SiS_LCDACRT1DataStruct;
-
-typedef struct _SiS_CHTVRegDataStruct
-{
-       UCHAR  Reg[16];
-} SiS_CHTVRegDataStruct;
-
-typedef struct _SiS_StStruct
-{
-       UCHAR  St_ModeID;
-       USHORT St_ModeFlag;
-       UCHAR  St_StTableIndex;
-       UCHAR  St_CRT2CRTC;
-       UCHAR  St_ResInfo;
-       UCHAR  VB_StTVFlickerIndex;
-       UCHAR  VB_StTVEdgeIndex;
-       UCHAR  VB_StTVYFilterIndex;
-       UCHAR  St_PDC;
-} SiS_StStruct;
-
-typedef struct _SiS_VBModeStruct
-{
-       UCHAR  ModeID;
-       UCHAR  VB_TVDelayIndex;
-       UCHAR  VB_TVFlickerIndex;
-       UCHAR  VB_TVPhaseIndex;
-       UCHAR  VB_TVYFilterIndex;
-       UCHAR  VB_LCDDelayIndex;
-       UCHAR  _VB_LCDHIndex;
-       UCHAR  _VB_LCDVIndex;
-} SiS_VBModeStruct;
-
-typedef struct _SiS_StandTableStruct
-{
-       UCHAR  CRT_COLS;
-       UCHAR  ROWS;
-       UCHAR  CHAR_HEIGHT;
-       USHORT CRT_LEN;
-       UCHAR  SR[4];
-       UCHAR  MISC;
-       UCHAR  CRTC[0x19];
-       UCHAR  ATTR[0x14];
-       UCHAR  GRC[9];
-} SiS_StandTableStruct;
-
-typedef struct _SiS_ExtStruct
-{
-       UCHAR  Ext_ModeID;
-       USHORT Ext_ModeFlag;
-       USHORT Ext_VESAID;
-       UCHAR  Ext_RESINFO;
-       UCHAR  VB_ExtTVFlickerIndex;
-       UCHAR  VB_ExtTVEdgeIndex;
-       UCHAR  VB_ExtTVYFilterIndex;
-       UCHAR  VB_ExtTVYFilterIndexROM661;
-       UCHAR  REFindex;
-       CHAR   ROMMODEIDX661;
-} SiS_ExtStruct;
-
-typedef struct _SiS_Ext2Struct
-{
-       USHORT Ext_InfoFlag;
-       UCHAR  Ext_CRT1CRTC;
-       UCHAR  Ext_CRTVCLK;
-       UCHAR  Ext_CRT2CRTC;
-       UCHAR  Ext_CRT2CRTC_NS;
-       UCHAR  ModeID;
-       USHORT XRes;
-       USHORT YRes;
-       UCHAR  Ext_PDC;
-} SiS_Ext2Struct;
-
-typedef struct _SiS_Part2PortTblStruct
-{
-       UCHAR  CR[12];
-} SiS_Part2PortTblStruct;
-
-typedef struct _SiS_CRT1TableStruct
-{
-       UCHAR  CR[17];
-} SiS_CRT1TableStruct;
-
-typedef struct _SiS_MCLKDataStruct
-{
-       UCHAR  SR28,SR29,SR2A;
-       USHORT CLOCK;
-} SiS_MCLKDataStruct;
-
-typedef struct _SiS_VCLKDataStruct
-{
-       UCHAR  SR2B,SR2C;
-       USHORT CLOCK;
-} SiS_VCLKDataStruct;
-
-typedef struct _SiS_VBVCLKDataStruct
-{
-       UCHAR  Part4_A,Part4_B;
-       USHORT CLOCK;
-} SiS_VBVCLKDataStruct;
-
-typedef struct _SiS_StResInfoStruct
-{
-       USHORT HTotal;
-       USHORT VTotal;
-} SiS_StResInfoStruct;
-
-typedef struct _SiS_ModeResInfoStruct
-{
-       USHORT HTotal;
-       USHORT VTotal;
-       UCHAR  XChar;
-       UCHAR  YChar;
-} SiS_ModeResInfoStruct;
-
-
-
-typedef UCHAR DRAM4Type[4];
+#ifndef _VSTRUCT_H_
+#define _VSTRUCT_H_
+
+struct SiS_PanelDelayTbl {
+       unsigned char timer[2];
+};
+
+struct SiS_LCDData {
+       unsigned short RVBHCMAX;
+       unsigned short RVBHCFACT;
+       unsigned short VGAHT;
+       unsigned short VGAVT;
+       unsigned short LCDHT;
+       unsigned short LCDVT;
+};
+
+struct SiS_TVData {
+       unsigned short RVBHCMAX;
+       unsigned short RVBHCFACT;
+       unsigned short VGAHT;
+       unsigned short VGAVT;
+       unsigned short TVHDE;
+       unsigned short TVVDE;
+       unsigned short RVBHRS;
+       unsigned char  FlickerMode;
+       unsigned short HALFRVBHRS;
+       unsigned short RVBHRS2;
+       unsigned char  RY1COE;
+       unsigned char  RY2COE;
+       unsigned char  RY3COE;
+       unsigned char  RY4COE;
+};
+
+struct SiS_LVDSData {
+       unsigned short VGAHT;
+       unsigned short VGAVT;
+       unsigned short LCDHT;
+       unsigned short LCDVT;
+};
+
+struct SiS_LVDSDes {
+       unsigned short LCDHDES;
+       unsigned short LCDVDES;
+};
+
+struct SiS_LVDSCRT1Data {
+       unsigned char  CR[15];
+};
+
+struct SiS_CHTVRegData {
+       unsigned char  Reg[16];
+};
+
+struct SiS_St {
+       unsigned char  St_ModeID;
+       unsigned short St_ModeFlag;
+       unsigned char  St_StTableIndex;
+       unsigned char  St_CRT2CRTC;
+       unsigned char  St_ResInfo;
+       unsigned char  VB_StTVFlickerIndex;
+       unsigned char  VB_StTVEdgeIndex;
+       unsigned char  VB_StTVYFilterIndex;
+       unsigned char  St_PDC;
+};
+
+struct SiS_VBMode {
+       unsigned char  ModeID;
+       unsigned char  VB_TVDelayIndex;
+       unsigned char  VB_TVFlickerIndex;
+       unsigned char  VB_TVPhaseIndex;
+       unsigned char  VB_TVYFilterIndex;
+       unsigned char  VB_LCDDelayIndex;
+       unsigned char  _VB_LCDHIndex;
+       unsigned char  _VB_LCDVIndex;
+};
+
+struct SiS_StandTable_S {
+       unsigned char  CRT_COLS;
+       unsigned char  ROWS;
+       unsigned char  CHAR_HEIGHT;
+       unsigned short CRT_LEN;
+       unsigned char  SR[4];
+       unsigned char  MISC;
+       unsigned char  CRTC[0x19];
+       unsigned char  ATTR[0x14];
+       unsigned char  GRC[9];
+};
+
+struct SiS_Ext {
+       unsigned char  Ext_ModeID;
+       unsigned short Ext_ModeFlag;
+       unsigned short Ext_VESAID;
+       unsigned char  Ext_RESINFO;
+       unsigned char  VB_ExtTVFlickerIndex;
+       unsigned char  VB_ExtTVEdgeIndex;
+       unsigned char  VB_ExtTVYFilterIndex;
+       unsigned char  VB_ExtTVYFilterIndexROM661;
+       unsigned char  REFindex;
+       char           ROMMODEIDX661;
+};
+
+struct SiS_Ext2 {
+       unsigned short Ext_InfoFlag;
+       unsigned char  Ext_CRT1CRTC;
+       unsigned char  Ext_CRTVCLK;
+       unsigned char  Ext_CRT2CRTC;
+       unsigned char  Ext_CRT2CRTC_NS;
+       unsigned char  ModeID;
+       unsigned short XRes;
+       unsigned short YRes;
+       unsigned char  Ext_PDC;
+       unsigned char  Ext_FakeCRT2CRTC;
+       unsigned char  Ext_FakeCRT2Clk;
+       unsigned char  Ext_CRT1CRTC_NORM;
+       unsigned char  Ext_CRTVCLK_NORM;
+       unsigned char  Ext_CRT1CRTC_WIDE;
+       unsigned char  Ext_CRTVCLK_WIDE;
+};
+
+struct SiS_Part2PortTbl {
+       unsigned char  CR[12];
+};
+
+struct SiS_CRT1Table {
+       unsigned char  CR[17];
+};
+
+struct SiS_MCLKData {
+       unsigned char  SR28,SR29,SR2A;
+       unsigned short CLOCK;
+};
+
+struct SiS_VCLKData {
+       unsigned char  SR2B,SR2C;
+       unsigned short CLOCK;
+};
+
+struct SiS_VBVCLKData {
+       unsigned char  Part4_A,Part4_B;
+       unsigned short CLOCK;
+};
+
+struct SiS_StResInfo_S {
+       unsigned short HTotal;
+       unsigned short VTotal;
+};
+
+struct SiS_ModeResInfo_S {
+       unsigned short HTotal;
+       unsigned short VTotal;
+       unsigned char  XChar;
+       unsigned char  YChar;
+};
 
 /* Defines for SiS_CustomT */
 /* Never change these for sisfb compatibility */
-#define CUT_NONE          0
-#define CUT_FORCENONE     1
-#define CUT_BARCO1366     2
-#define CUT_BARCO1024     3
-#define CUT_COMPAQ1280    4
-#define CUT_COMPAQ12802   5
-#define CUT_PANEL848      6
-#define CUT_CLEVO1024     7
-#define CUT_CLEVO10242    8
-#define CUT_CLEVO1400     9
-#define CUT_CLEVO14002    10
-#define CUT_UNIWILL1024   11
-#define CUT_ASUSL3000D    12
-#define CUT_UNIWILL10242  13
-#define CUT_ACER1280      14
-#define CUT_COMPAL1400_1  15
-#define CUT_COMPAL1400_2  16
-#define CUT_ASUSA2H_1     17
-#define CUT_ASUSA2H_2     18
-
-typedef struct _SiS_Private
+#define CUT_NONE                0
+#define CUT_FORCENONE           1
+#define CUT_BARCO1366           2
+#define CUT_BARCO1024           3
+#define CUT_COMPAQ1280          4
+#define CUT_COMPAQ12802                 5
+#define CUT_PANEL848            6
+#define CUT_CLEVO1024           7
+#define CUT_CLEVO10242          8
+#define CUT_CLEVO1400           9
+#define CUT_CLEVO14002         10
+#define CUT_UNIWILL1024                11
+#define CUT_ASUSL3000D         12
+#define CUT_UNIWILL10242       13
+#define CUT_ACER1280           14
+#define CUT_COMPAL1400_1       15
+#define CUT_COMPAL1400_2       16
+#define CUT_ASUSA2H_1          17
+#define CUT_ASUSA2H_2          18
+#define CUT_UNKNOWNLCD         19
+#define CUT_AOP8060            20
+#define CUT_PANEL856           21
+
+struct SiS_Private
 {
-#ifdef LINUX_KERNEL
-        SISIOADDRESS RelIO;
+       unsigned char                   ChipType;
+       unsigned char                   ChipRevision;
+#ifdef SIS_XORG_XF86
+       PCITAG                          PciTag;
 #endif
-       SISIOADDRESS SiS_P3c4;
-       SISIOADDRESS SiS_P3d4;
-       SISIOADDRESS SiS_P3c0;
-       SISIOADDRESS SiS_P3ce;
-       SISIOADDRESS SiS_P3c2;
-       SISIOADDRESS SiS_P3ca;
-       SISIOADDRESS SiS_P3c6;
-       SISIOADDRESS SiS_P3c7;
-       SISIOADDRESS SiS_P3c8;
-       SISIOADDRESS SiS_P3c9;
-       SISIOADDRESS SiS_P3cb;
-       SISIOADDRESS SiS_P3cd;
-       SISIOADDRESS SiS_P3da;
-       SISIOADDRESS SiS_Part1Port;
-       SISIOADDRESS SiS_Part2Port;
-       SISIOADDRESS SiS_Part3Port;
-       SISIOADDRESS SiS_Part4Port;
-       SISIOADDRESS SiS_Part5Port;
-       SISIOADDRESS SiS_VidCapt;
-       SISIOADDRESS SiS_VidPlay;
-       USHORT SiS_IF_DEF_LVDS;
-       USHORT SiS_IF_DEF_CH70xx;
-       USHORT SiS_IF_DEF_CONEX;
-       USHORT SiS_IF_DEF_TRUMPION;
-       USHORT SiS_IF_DEF_DSTN;
-       USHORT SiS_IF_DEF_FSTN;
-       USHORT SiS_SysFlags;
-       UCHAR  SiS_VGAINFO;
-#ifdef LINUX_XF86
-        USHORT SiS_CP1, SiS_CP2, SiS_CP3, SiS_CP4;
+#ifdef SIS_LINUX_KERNEL
+       void                            *ivideo;
 #endif
-       BOOLEAN SiS_UseROM;
-       BOOLEAN SiS_ROMNew;
-       BOOLEAN SiS_NeedRomModeData;
-       BOOLEAN PanelSelfDetected;
-       int     SiS_CHOverScan;
-       BOOLEAN SiS_CHSOverScan;
-       BOOLEAN SiS_ChSW;
-       BOOLEAN SiS_UseLCDA;
-       int     SiS_UseOEM;
-       ULONG   SiS_CustomT;
-       USHORT  SiS_Backup70xx;
-       BOOLEAN HaveEMI;
-       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;
-       USHORT SiS_flag_clearbuffer;
-       int    SiS_RAMType;
-       UCHAR  SiS_ChannelAB;
-       UCHAR  SiS_DataBusWidth;
-       USHORT SiS_ModeType;
-       USHORT SiS_VBInfo;
-       USHORT SiS_TVMode;
-       USHORT SiS_LCDResInfo;
-       USHORT SiS_LCDTypeInfo;
-       USHORT SiS_LCDInfo;
-       USHORT SiS_LCDInfo661;
-       USHORT SiS_VBType;
-       USHORT SiS_VBExtInfo;
-       USHORT SiS_YPbPr;
-       USHORT SiS_SelectCRT2Rate;
-       USHORT SiS_SetFlag;
-       USHORT SiS_RVBHCFACT;
-       USHORT SiS_RVBHCMAX;
-       USHORT SiS_RVBHRS;
-       USHORT SiS_VGAVT;
-       USHORT SiS_VGAHT;
-       USHORT SiS_VT;
-       USHORT SiS_HT;
-       USHORT SiS_VGAVDE;
-       USHORT SiS_VGAHDE;
-       USHORT SiS_VDE;
-       USHORT SiS_HDE;
-       USHORT SiS_NewFlickerMode;
-       USHORT SiS_RY1COE;
-       USHORT SiS_RY2COE;
-       USHORT SiS_RY3COE;
-       USHORT SiS_RY4COE;
-       USHORT SiS_LCDHDES;
-       USHORT SiS_LCDVDES;
-       USHORT SiS_DDC_Port;
-       USHORT SiS_DDC_Index;
-       USHORT SiS_DDC_Data;
-       USHORT SiS_DDC_NData;
-       USHORT SiS_DDC_Clk;
-       USHORT SiS_DDC_NClk;
-       USHORT SiS_DDC_DeviceAddr;
-       USHORT SiS_DDC_ReadAddr;
-       USHORT SiS_DDC_SecAddr;
-       USHORT SiS_ChrontelInit;
-       BOOLEAN SiS_SensibleSR11;
-       USHORT SiS661LCD2TableSize;
-
-       USHORT SiS_PanelMinLVDS;
-       USHORT SiS_PanelMin301;
-
-       const SiS_StStruct          *SiS_SModeIDTable;
-       const SiS_StandTableStruct  *SiS_StandTable;
-       const SiS_ExtStruct         *SiS_EModeIDTable;
-       const SiS_Ext2Struct        *SiS_RefIndex;
-       const SiS_VBModeStruct      *SiS_VBModeIDTable;
-       const SiS_CRT1TableStruct   *SiS_CRT1Table;
-       const SiS_MCLKDataStruct    *SiS_MCLKData_0;
-       const SiS_MCLKDataStruct    *SiS_MCLKData_1;
-       SiS_VCLKDataStruct          *SiS_VCLKData;
-       SiS_VBVCLKDataStruct        *SiS_VBVCLKData;
-       const SiS_StResInfoStruct   *SiS_StResInfo;
-       const SiS_ModeResInfoStruct *SiS_ModeResInfo;
-
-       const UCHAR                 *pSiS_OutputSelect;
-       const UCHAR                 *pSiS_SoftSetting;
-
-       const DRAM4Type *SiS_SR15; /* pointer : point to array */
-#ifdef LINUX_KERNEL
-       UCHAR *pSiS_SR07;
-       const DRAM4Type *SiS_CR40; /* pointer : point to array */
-       UCHAR *SiS_CR49;
-       UCHAR *SiS_SR25;
-       UCHAR *pSiS_SR1F;
-       UCHAR *pSiS_SR21;
-       UCHAR *pSiS_SR22;
-       UCHAR *pSiS_SR23;
-       UCHAR *pSiS_SR24;
-       UCHAR *pSiS_SR31;
-       UCHAR *pSiS_SR32;
-       UCHAR *pSiS_SR33;
-       UCHAR *pSiS_CRT2Data_1_2;
-       UCHAR *pSiS_CRT2Data_4_D;
-       UCHAR *pSiS_CRT2Data_4_E;
-       UCHAR *pSiS_CRT2Data_4_10;
-       const USHORT *pSiS_RGBSenseData;
-       const USHORT *pSiS_VideoSenseData;
-       const USHORT *pSiS_YCSenseData;
-       const USHORT *pSiS_RGBSenseData2;
-       const USHORT *pSiS_VideoSenseData2;
-       const USHORT *pSiS_YCSenseData2;
+       unsigned char                   *VirtualRomBase;
+       BOOLEAN                         UseROM;
+#ifdef SIS_LINUX_KERNEL
+       unsigned char SISIOMEMTYPE      *VideoMemoryAddress;
+       unsigned int                    VideoMemorySize;
 #endif
+       SISIOADDRESS                    IOAddress;
+       SISIOADDRESS                    IOAddress2;  /* For dual chip XGI volari */
 
-       const SiS_PanelDelayTblStruct *SiS_PanelDelayTbl;
-       const SiS_PanelDelayTblStruct *SiS_PanelDelayTblLVDS;
+#ifdef SIS_LINUX_KERNEL
+       SISIOADDRESS                    RelIO;
+#endif
+       SISIOADDRESS                    SiS_P3c4;
+       SISIOADDRESS                    SiS_P3d4;
+       SISIOADDRESS                    SiS_P3c0;
+       SISIOADDRESS                    SiS_P3ce;
+       SISIOADDRESS                    SiS_P3c2;
+       SISIOADDRESS                    SiS_P3ca;
+       SISIOADDRESS                    SiS_P3c6;
+       SISIOADDRESS                    SiS_P3c7;
+       SISIOADDRESS                    SiS_P3c8;
+       SISIOADDRESS                    SiS_P3c9;
+       SISIOADDRESS                    SiS_P3cb;
+       SISIOADDRESS                    SiS_P3cc;
+       SISIOADDRESS                    SiS_P3cd;
+       SISIOADDRESS                    SiS_P3da;
+       SISIOADDRESS                    SiS_Part1Port;
+       SISIOADDRESS                    SiS_Part2Port;
+       SISIOADDRESS                    SiS_Part3Port;
+       SISIOADDRESS                    SiS_Part4Port;
+       SISIOADDRESS                    SiS_Part5Port;
+       SISIOADDRESS                    SiS_VidCapt;
+       SISIOADDRESS                    SiS_VidPlay;
+       unsigned short                  SiS_IF_DEF_LVDS;
+       unsigned short                  SiS_IF_DEF_CH70xx;
+       unsigned short                  SiS_IF_DEF_CONEX;
+       unsigned short                  SiS_IF_DEF_TRUMPION;
+       unsigned short                  SiS_IF_DEF_DSTN;
+       unsigned short                  SiS_IF_DEF_FSTN;
+       unsigned short                  SiS_SysFlags;
+       unsigned char                   SiS_VGAINFO;
+#ifdef SIS_XORG_XF86
+       unsigned short                  SiS_CP1, SiS_CP2, SiS_CP3, SiS_CP4;
+#endif
+       BOOLEAN                         SiS_UseROM;
+       BOOLEAN                         SiS_ROMNew;
+       BOOLEAN                         SiS_XGIROM;
+       BOOLEAN                         SiS_NeedRomModeData;
+       BOOLEAN                         PanelSelfDetected;
+       BOOLEAN                         DDCPortMixup;
+       int                             SiS_CHOverScan;
+       BOOLEAN                         SiS_CHSOverScan;
+       BOOLEAN                         SiS_ChSW;
+       BOOLEAN                         SiS_UseLCDA;
+       int                             SiS_UseOEM;
+       unsigned int                    SiS_CustomT;
+       int                             SiS_UseWide, SiS_UseWideCRT2;
+       int                             SiS_TVBlue;
+       unsigned short                  SiS_Backup70xx;
+       BOOLEAN                         HaveEMI;
+       BOOLEAN                         HaveEMILCD;
+       BOOLEAN                         OverruleEMI;
+       unsigned char                   EMI_30,EMI_31,EMI_32,EMI_33;
+       unsigned short                  SiS_EMIOffset;
+       unsigned short                  SiS_PWDOffset;
+       short                           PDC, PDCA;
+       unsigned char                   SiS_MyCR63;
+       unsigned short                  SiS_CRT1Mode;
+       unsigned short                  SiS_flag_clearbuffer;
+       int                             SiS_RAMType;
+       unsigned char                   SiS_ChannelAB;
+       unsigned char                   SiS_DataBusWidth;
+       unsigned short                  SiS_ModeType;
+       unsigned short                  SiS_VBInfo;
+       unsigned short                  SiS_TVMode;
+       unsigned short                  SiS_LCDResInfo;
+       unsigned short                  SiS_LCDTypeInfo;
+       unsigned short                  SiS_LCDInfo;
+       unsigned short                  SiS_LCDInfo661;
+       unsigned short                  SiS_VBType;
+       unsigned short                  SiS_VBExtInfo;
+       unsigned short                  SiS_YPbPr;
+       unsigned short                  SiS_SelectCRT2Rate;
+       unsigned short                  SiS_SetFlag;
+       unsigned short                  SiS_RVBHCFACT;
+       unsigned short                  SiS_RVBHCMAX;
+       unsigned short                  SiS_RVBHRS;
+       unsigned short                  SiS_RVBHRS2;
+       unsigned short                  SiS_VGAVT;
+       unsigned short                  SiS_VGAHT;
+       unsigned short                  SiS_VT;
+       unsigned short                  SiS_HT;
+       unsigned short                  SiS_VGAVDE;
+       unsigned short                  SiS_VGAHDE;
+       unsigned short                  SiS_VDE;
+       unsigned short                  SiS_HDE;
+       unsigned short                  SiS_NewFlickerMode;
+       unsigned short                  SiS_RY1COE;
+       unsigned short                  SiS_RY2COE;
+       unsigned short                  SiS_RY3COE;
+       unsigned short                  SiS_RY4COE;
+       unsigned short                  SiS_LCDHDES;
+       unsigned short                  SiS_LCDVDES;
+       unsigned short                  SiS_DDC_Port;
+       unsigned short                  SiS_DDC_Index;
+       unsigned short                  SiS_DDC_Data;
+       unsigned short                  SiS_DDC_NData;
+       unsigned short                  SiS_DDC_Clk;
+       unsigned short                  SiS_DDC_NClk;
+       unsigned short                  SiS_DDC_DeviceAddr;
+       unsigned short                  SiS_DDC_ReadAddr;
+       unsigned short                  SiS_DDC_SecAddr;
+       unsigned short                  SiS_ChrontelInit;
+       BOOLEAN                         SiS_SensibleSR11;
+       unsigned short                  SiS661LCD2TableSize;
+
+       unsigned short                  SiS_PanelMinLVDS;
+       unsigned short                  SiS_PanelMin301;
+
+       const struct SiS_St             *SiS_SModeIDTable;
+       const struct SiS_StandTable_S   *SiS_StandTable;
+       const struct SiS_Ext            *SiS_EModeIDTable;
+       const struct SiS_Ext2           *SiS_RefIndex;
+       const struct SiS_VBMode         *SiS_VBModeIDTable;
+       const struct SiS_CRT1Table      *SiS_CRT1Table;
+       const struct SiS_MCLKData       *SiS_MCLKData_0;
+       const struct SiS_MCLKData       *SiS_MCLKData_1;
+       struct SiS_VCLKData             *SiS_VCLKData;
+       struct SiS_VBVCLKData           *SiS_VBVCLKData;
+       const struct SiS_StResInfo_S    *SiS_StResInfo;
+       const struct SiS_ModeResInfo_S  *SiS_ModeResInfo;
+
+       const unsigned char             *pSiS_OutputSelect;
+       const unsigned char             *pSiS_SoftSetting;
+
+       const unsigned char             *SiS_SR15;
+
+       const struct SiS_PanelDelayTbl  *SiS_PanelDelayTbl;
+       const struct SiS_PanelDelayTbl  *SiS_PanelDelayTblLVDS;
 
        /* SiS bridge */
 
-       const UCHAR *SiS_NTSCPhase;
-       const UCHAR *SiS_PALPhase;
-       const UCHAR *SiS_NTSCPhase2;
-       const UCHAR *SiS_PALPhase2;
-       const UCHAR *SiS_PALMPhase;
-       const UCHAR *SiS_PALNPhase;
-       const UCHAR *SiS_PALMPhase2;
-       const UCHAR *SiS_PALNPhase2;
-       const UCHAR *SiS_SpecialPhase;
-       const UCHAR *SiS_SpecialPhaseM;
-       const UCHAR *SiS_SpecialPhaseJ;
-       const SiS_LCDDataStruct  *SiS_ExtLCD1024x768Data;
-       const SiS_LCDDataStruct  *SiS_St2LCD1024x768Data;
-       const SiS_LCDDataStruct  *SiS_LCD1280x720Data;
-       const SiS_LCDDataStruct  *SiS_StLCD1280x768_2Data;
-       const SiS_LCDDataStruct  *SiS_ExtLCD1280x768_2Data;
-       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;
-       const SiS_LCDDataStruct  *SiS_StLCD1400x1050Data;
-       const SiS_LCDDataStruct  *SiS_ExtLCD1400x1050Data;
-       const SiS_LCDDataStruct  *SiS_StLCD1600x1200Data;
-       const SiS_LCDDataStruct  *SiS_ExtLCD1600x1200Data;
-       const SiS_LCDDataStruct  *SiS_LCD1680x1050Data;
-       const SiS_LCDDataStruct  *SiS_NoScaleData;
-       const SiS_TVDataStruct   *SiS_StPALData;
-       const SiS_TVDataStruct   *SiS_ExtPALData;
-       const SiS_TVDataStruct   *SiS_StNTSCData;
-       const SiS_TVDataStruct   *SiS_ExtNTSCData;
-       const SiS_TVDataStruct   *SiS_St1HiTVData;
-       const SiS_TVDataStruct   *SiS_St2HiTVData;
-       const SiS_TVDataStruct   *SiS_ExtHiTVData;
-       const SiS_TVDataStruct   *SiS_St525iData;
-       const SiS_TVDataStruct   *SiS_St525pData;
-       const SiS_TVDataStruct   *SiS_St750pData;
-       const SiS_TVDataStruct   *SiS_Ext525iData;
-       const SiS_TVDataStruct   *SiS_Ext525pData;
-       const SiS_TVDataStruct   *SiS_Ext750pData;
-       const UCHAR *SiS_NTSCTiming;
-       const UCHAR *SiS_PALTiming;
-       const UCHAR *SiS_HiTVExtTiming;
-       const UCHAR *SiS_HiTVSt1Timing;
-       const UCHAR *SiS_HiTVSt2Timing;
-       const UCHAR *SiS_HiTVGroup3Data;
-       const UCHAR *SiS_HiTVGroup3Simu;
+       const struct SiS_LCDData        *SiS_ExtLCD1024x768Data;
+       const struct SiS_LCDData        *SiS_St2LCD1024x768Data;
+       const struct SiS_LCDData        *SiS_LCD1280x720Data;
+       const struct SiS_LCDData        *SiS_StLCD1280x768_2Data;
+       const struct SiS_LCDData        *SiS_ExtLCD1280x768_2Data;
+       const struct SiS_LCDData        *SiS_LCD1280x800Data;
+       const struct SiS_LCDData        *SiS_LCD1280x800_2Data;
+       const struct SiS_LCDData        *SiS_LCD1280x854Data;
+       const struct SiS_LCDData        *SiS_LCD1280x960Data;
+       const struct SiS_LCDData        *SiS_ExtLCD1280x1024Data;
+       const struct SiS_LCDData        *SiS_St2LCD1280x1024Data;
+       const struct SiS_LCDData        *SiS_StLCD1400x1050Data;
+       const struct SiS_LCDData        *SiS_ExtLCD1400x1050Data;
+       const struct SiS_LCDData        *SiS_StLCD1600x1200Data;
+       const struct SiS_LCDData        *SiS_ExtLCD1600x1200Data;
+       const struct SiS_LCDData        *SiS_LCD1680x1050Data;
+       const struct SiS_LCDData        *SiS_NoScaleData;
+       const struct SiS_TVData         *SiS_StPALData;
+       const struct SiS_TVData         *SiS_ExtPALData;
+       const struct SiS_TVData         *SiS_StNTSCData;
+       const struct SiS_TVData         *SiS_ExtNTSCData;
+       const struct SiS_TVData         *SiS_St1HiTVData;
+       const struct SiS_TVData         *SiS_St2HiTVData;
+       const struct SiS_TVData         *SiS_ExtHiTVData;
+       const struct SiS_TVData         *SiS_St525iData;
+       const struct SiS_TVData         *SiS_St525pData;
+       const struct SiS_TVData         *SiS_St750pData;
+       const struct SiS_TVData         *SiS_Ext525iData;
+       const struct SiS_TVData         *SiS_Ext525pData;
+       const struct SiS_TVData         *SiS_Ext750pData;
+       const unsigned char             *SiS_NTSCTiming;
+       const unsigned char             *SiS_PALTiming;
+       const unsigned char             *SiS_HiTVExtTiming;
+       const unsigned char             *SiS_HiTVSt1Timing;
+       const unsigned char             *SiS_HiTVSt2Timing;
+       const unsigned char             *SiS_HiTVGroup3Data;
+       const unsigned char             *SiS_HiTVGroup3Simu;
 #if 0
-       const UCHAR *SiS_HiTVTextTiming;
-       const UCHAR *SiS_HiTVGroup3Text;
+       const unsigned char             *SiS_HiTVTextTiming;
+       const unsigned char             *SiS_HiTVGroup3Text;
 #endif
 
-       const SiS_Part2PortTblStruct *SiS_CRT2Part2_1024x768_1;
-       const SiS_Part2PortTblStruct *SiS_CRT2Part2_1280x1024_1;
-       const SiS_Part2PortTblStruct *SiS_CRT2Part2_1024x768_2;
-       const SiS_Part2PortTblStruct *SiS_CRT2Part2_1280x1024_2;
-       const SiS_Part2PortTblStruct *SiS_CRT2Part2_1024x768_3;
-       const SiS_Part2PortTblStruct *SiS_CRT2Part2_1280x1024_3;
+       const struct SiS_Part2PortTbl   *SiS_CRT2Part2_1024x768_1;
+       const struct SiS_Part2PortTbl   *SiS_CRT2Part2_1024x768_2;
+       const struct SiS_Part2PortTbl   *SiS_CRT2Part2_1024x768_3;
 
        /* LVDS, Chrontel */
 
-       const SiS_LVDSDataStruct  *SiS_LVDS800x600Data_1;
-       const SiS_LVDSDataStruct  *SiS_LVDS800x600Data_2;
-       const SiS_LVDSDataStruct  *SiS_LVDS1024x768Data_1;
-       const SiS_LVDSDataStruct  *SiS_LVDS1024x768Data_2;
-       const SiS_LVDSDataStruct  *SiS_LVDS1280x1024Data_1;
-       const SiS_LVDSDataStruct  *SiS_LVDS1280x1024Data_2;
-       const SiS_LVDSDataStruct  *SiS_LVDS1280x960Data_1;
-       const SiS_LVDSDataStruct  *SiS_LVDS1280x960Data_2;
-       const SiS_LVDSDataStruct  *SiS_LVDS1400x1050Data_1;
-       const SiS_LVDSDataStruct  *SiS_LVDS1400x1050Data_2;
-       const SiS_LVDSDataStruct  *SiS_LVDS1600x1200Data_1;
-       const SiS_LVDSDataStruct  *SiS_LVDS1600x1200Data_2;
-       const SiS_LVDSDataStruct  *SiS_LVDS1280x768Data_1;
-       const SiS_LVDSDataStruct  *SiS_LVDS1280x768Data_2;
-       const SiS_LVDSDataStruct  *SiS_LVDS1024x600Data_1;
-       const SiS_LVDSDataStruct  *SiS_LVDS1024x600Data_2;
-       const SiS_LVDSDataStruct  *SiS_LVDS1152x768Data_1;
-       const SiS_LVDSDataStruct  *SiS_LVDS1152x768Data_2;
-       const SiS_LVDSDataStruct  *SiS_LVDS640x480Data_1;
-       const SiS_LVDSDataStruct  *SiS_LVDS640x480Data_2;
-       const SiS_LVDSDataStruct  *SiS_LVDS320x480Data_1;
-       const SiS_LVDSDataStruct  *SiS_LVDSXXXxXXXData_1;
-       const SiS_LVDSDataStruct  *SiS_LVDSBARCO1366Data_1;
-       const SiS_LVDSDataStruct  *SiS_LVDSBARCO1366Data_2;
-       const SiS_LVDSDataStruct  *SiS_LVDSBARCO1024Data_1;
-       const SiS_LVDSDataStruct  *SiS_LVDSBARCO1024Data_2;
-       const SiS_LVDSDataStruct  *SiS_LVDS848x480Data_1;
-       const SiS_LVDSDataStruct  *SiS_LVDS848x480Data_2;
-       const SiS_LVDSDataStruct  *SiS_CHTVUNTSCData;
-       const SiS_LVDSDataStruct  *SiS_CHTVONTSCData;
-       const SiS_LVDSDataStruct  *SiS_CHTVUPALData;
-       const SiS_LVDSDataStruct  *SiS_CHTVOPALData;
-       const SiS_LVDSDataStruct  *SiS_CHTVUPALMData;
-       const SiS_LVDSDataStruct  *SiS_CHTVOPALMData;
-       const SiS_LVDSDataStruct  *SiS_CHTVUPALNData;
-       const SiS_LVDSDataStruct  *SiS_CHTVOPALNData;
-       const SiS_LVDSDataStruct  *SiS_CHTVSOPALData;
-
-       const SiS_LVDSDesStruct  *SiS_PanelType00_1;
-       const SiS_LVDSDesStruct  *SiS_PanelType01_1;
-       const SiS_LVDSDesStruct  *SiS_PanelType02_1;
-       const SiS_LVDSDesStruct  *SiS_PanelType03_1;
-       const SiS_LVDSDesStruct  *SiS_PanelType04_1;
-       const SiS_LVDSDesStruct  *SiS_PanelType05_1;
-       const SiS_LVDSDesStruct  *SiS_PanelType06_1;
-       const SiS_LVDSDesStruct  *SiS_PanelType07_1;
-       const SiS_LVDSDesStruct  *SiS_PanelType08_1;
-       const SiS_LVDSDesStruct  *SiS_PanelType09_1;
-       const SiS_LVDSDesStruct  *SiS_PanelType0a_1;
-       const SiS_LVDSDesStruct  *SiS_PanelType0b_1;
-       const SiS_LVDSDesStruct  *SiS_PanelType0c_1;
-       const SiS_LVDSDesStruct  *SiS_PanelType0d_1;
-       const SiS_LVDSDesStruct  *SiS_PanelType0e_1;
-       const SiS_LVDSDesStruct  *SiS_PanelType0f_1;
-       const SiS_LVDSDesStruct  *SiS_PanelTypeNS_1;
-       const SiS_LVDSDesStruct  *SiS_PanelType00_2;
-       const SiS_LVDSDesStruct  *SiS_PanelType01_2;
-       const SiS_LVDSDesStruct  *SiS_PanelType02_2;
-       const SiS_LVDSDesStruct  *SiS_PanelType03_2;
-       const SiS_LVDSDesStruct  *SiS_PanelType04_2;
-       const SiS_LVDSDesStruct  *SiS_PanelType05_2;
-       const SiS_LVDSDesStruct  *SiS_PanelType06_2;
-       const SiS_LVDSDesStruct  *SiS_PanelType07_2;
-       const SiS_LVDSDesStruct  *SiS_PanelType08_2;
-       const SiS_LVDSDesStruct  *SiS_PanelType09_2;
-       const SiS_LVDSDesStruct  *SiS_PanelType0a_2;
-       const SiS_LVDSDesStruct  *SiS_PanelType0b_2;
-       const SiS_LVDSDesStruct  *SiS_PanelType0c_2;
-       const SiS_LVDSDesStruct  *SiS_PanelType0d_2;
-       const SiS_LVDSDesStruct  *SiS_PanelType0e_2;
-       const SiS_LVDSDesStruct  *SiS_PanelType0f_2;
-       const SiS_LVDSDesStruct  *SiS_PanelTypeNS_2;
-       const SiS_LVDSDesStruct  *SiS_CHTVUNTSCDesData;
-       const SiS_LVDSDesStruct  *SiS_CHTVONTSCDesData;
-       const SiS_LVDSDesStruct  *SiS_CHTVUPALDesData;
-       const SiS_LVDSDesStruct  *SiS_CHTVOPALDesData;
-
-       const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1800x600_1;
-       const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11024x768_1;
-       const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11280x1024_1;
-       const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11400x1050_1;
-       const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11280x768_1;
-       const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11024x600_1;
-       const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11152x768_1;
-       const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11600x1200_1;
-       const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1800x600_1_H;
-       const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11024x768_1_H;
-       const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11280x1024_1_H;
-       const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11400x1050_1_H;
-       const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11280x768_1_H;
-       const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11024x600_1_H;
-       const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11152x768_1_H;
-       const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11600x1200_1_H;
-       const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1800x600_2;
-       const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11024x768_2;
-       const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11280x1024_2;
-       const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11400x1050_2;
-       const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11280x768_2;
-       const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11024x600_2;
-       const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11152x768_2;
-       const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11600x1200_2;
-       const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1800x600_2_H;
-       const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11024x768_2_H;
-       const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11280x1024_2_H;
-       const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11400x1050_2_H;
-       const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11280x768_2_H;
-       const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11024x600_2_H;
-       const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11152x768_2_H;
-       const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11600x1200_2_H;
-       const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1XXXxXXX_1;
-       const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1XXXxXXX_1_H;
-       const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1640x480_1;
-       const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1640x480_1_H;
-       const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1640x480_2;
-       const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1640x480_2_H;
-       const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1640x480_3;
-       const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1640x480_3_H;
-       const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1320x480_1;
-       const SiS_LVDSCRT1DataStruct  *SiS_CHTVCRT1UNTSC;
-       const SiS_LVDSCRT1DataStruct  *SiS_CHTVCRT1ONTSC;
-       const SiS_LVDSCRT1DataStruct  *SiS_CHTVCRT1UPAL;
-       const SiS_LVDSCRT1DataStruct  *SiS_CHTVCRT1OPAL;
-       const SiS_LVDSCRT1DataStruct  *SiS_CHTVCRT1SOPAL;
-
-       const SiS_CHTVRegDataStruct *SiS_CHTVReg_UNTSC;
-       const SiS_CHTVRegDataStruct *SiS_CHTVReg_ONTSC;
-       const SiS_CHTVRegDataStruct *SiS_CHTVReg_UPAL;
-       const SiS_CHTVRegDataStruct *SiS_CHTVReg_OPAL;
-       const SiS_CHTVRegDataStruct *SiS_CHTVReg_UPALM;
-       const SiS_CHTVRegDataStruct *SiS_CHTVReg_OPALM;
-       const SiS_CHTVRegDataStruct *SiS_CHTVReg_UPALN;
-       const SiS_CHTVRegDataStruct *SiS_CHTVReg_OPALN;
-       const SiS_CHTVRegDataStruct *SiS_CHTVReg_SOPAL;
-
-       const UCHAR *SiS_CHTVVCLKUNTSC;
-       const UCHAR *SiS_CHTVVCLKONTSC;
-       const UCHAR *SiS_CHTVVCLKUPAL;
-       const UCHAR *SiS_CHTVVCLKOPAL;
-       const UCHAR *SiS_CHTVVCLKUPALM;
-       const UCHAR *SiS_CHTVVCLKOPALM;
-       const UCHAR *SiS_CHTVVCLKUPALN;
-       const UCHAR *SiS_CHTVVCLKOPALN;
-       const UCHAR *SiS_CHTVVCLKSOPAL;
-
-       USHORT  PanelXRes, PanelHT;
-       USHORT  PanelYRes, PanelVT;
-       USHORT  PanelHRS,  PanelHRE;
-       USHORT  PanelVRS,  PanelVRE;
-       USHORT  PanelVCLKIdx300;
-       USHORT  PanelVCLKIdx315;
-
-       BOOLEAN UseCustomMode;
-       BOOLEAN CRT1UsesCustomMode;
-       USHORT  CHDisplay;
-       USHORT  CHSyncStart;
-       USHORT  CHSyncEnd;
-       USHORT  CHTotal;
-       USHORT  CHBlankStart;
-       USHORT  CHBlankEnd;
-       USHORT  CVDisplay;
-       USHORT  CVSyncStart;
-       USHORT  CVSyncEnd;
-       USHORT  CVTotal;
-       USHORT  CVBlankStart;
-       USHORT  CVBlankEnd;
-       ULONG   CDClock;
-       ULONG   CFlags;   
-       UCHAR   CCRT1CRTC[17];
-       UCHAR   CSR2B;
-       UCHAR   CSR2C;
-       USHORT  CSRClock;
-       USHORT  CSRClock_CRT1;
-       USHORT  CModeFlag;
-       USHORT  CModeFlag_CRT1;
-       USHORT  CInfoFlag;
-
-       int     LVDSHL;
-       
-       BOOLEAN Backup;
-       UCHAR Backup_Mode;
-       UCHAR Backup_14;
-       UCHAR Backup_15;
-       UCHAR Backup_16;
-       UCHAR Backup_17;
-       UCHAR Backup_18;
-       UCHAR Backup_19;
-       UCHAR Backup_1a;
-       UCHAR Backup_1b;
-       UCHAR Backup_1c;
-       UCHAR Backup_1d;
-       
-       int     UsePanelScaler;
-       int     CenterScreen;
-
-       USHORT  CP_Vendor, CP_Product;
-       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];
-       int     CP_HSyncStart[7], CP_VSyncStart[7];
-       int     CP_HSyncEnd[7], CP_VSyncEnd[7];
-       int     CP_HBlankStart[7], CP_VBlankStart[7];
-       int     CP_HBlankEnd[7], CP_VBlankEnd[7];
-       int     CP_Clock[7];
-       BOOLEAN CP_DataValid[7];
-       BOOLEAN CP_HSync_P[7], CP_VSync_P[7], CP_SyncValid[7];
-} SiS_Private;
+       const struct SiS_LVDSData       *SiS_LVDS320x240Data_1;
+       const struct SiS_LVDSData       *SiS_LVDS320x240Data_2;
+       const struct SiS_LVDSData       *SiS_LVDS640x480Data_1;
+       const struct SiS_LVDSData       *SiS_LVDS800x600Data_1;
+       const struct SiS_LVDSData       *SiS_LVDS1024x600Data_1;
+       const struct SiS_LVDSData       *SiS_LVDS1024x768Data_1;
+       const struct SiS_LVDSData       *SiS_LVDSBARCO1366Data_1;
+       const struct SiS_LVDSData       *SiS_LVDSBARCO1366Data_2;
+       const struct SiS_LVDSData       *SiS_LVDSBARCO1024Data_1;
+       const struct SiS_LVDSData       *SiS_LVDS848x480Data_1;
+       const struct SiS_LVDSData       *SiS_LVDS848x480Data_2;
+       const struct SiS_LVDSData       *SiS_CHTVUNTSCData;
+       const struct SiS_LVDSData       *SiS_CHTVONTSCData;
+       const struct SiS_LVDSData       *SiS_CHTVUPALData;
+       const struct SiS_LVDSData       *SiS_CHTVOPALData;
+       const struct SiS_LVDSData       *SiS_CHTVUPALMData;
+       const struct SiS_LVDSData       *SiS_CHTVOPALMData;
+       const struct SiS_LVDSData       *SiS_CHTVUPALNData;
+       const struct SiS_LVDSData       *SiS_CHTVOPALNData;
+       const struct SiS_LVDSData       *SiS_CHTVSOPALData;
+
+       const struct SiS_LVDSDes        *SiS_PanelType04_1a;
+       const struct SiS_LVDSDes        *SiS_PanelType04_2a;
+       const struct SiS_LVDSDes        *SiS_PanelType04_1b;
+       const struct SiS_LVDSDes        *SiS_PanelType04_2b;
+
+       const struct SiS_LVDSCRT1Data   *SiS_LVDSCRT1320x240_1;
+       const struct SiS_LVDSCRT1Data   *SiS_LVDSCRT1320x240_2;
+       const struct SiS_LVDSCRT1Data   *SiS_LVDSCRT1320x240_2_H;
+       const struct SiS_LVDSCRT1Data   *SiS_LVDSCRT1320x240_3;
+       const struct SiS_LVDSCRT1Data   *SiS_LVDSCRT1320x240_3_H;
+       const struct SiS_LVDSCRT1Data   *SiS_LVDSCRT1640x480_1;
+       const struct SiS_LVDSCRT1Data   *SiS_LVDSCRT1640x480_1_H;
+       const struct SiS_LVDSCRT1Data   *SiS_CHTVCRT1UNTSC;
+       const struct SiS_LVDSCRT1Data   *SiS_CHTVCRT1ONTSC;
+       const struct SiS_LVDSCRT1Data   *SiS_CHTVCRT1UPAL;
+       const struct SiS_LVDSCRT1Data   *SiS_CHTVCRT1OPAL;
+       const struct SiS_LVDSCRT1Data   *SiS_CHTVCRT1SOPAL;
+
+       const struct SiS_CHTVRegData    *SiS_CHTVReg_UNTSC;
+       const struct SiS_CHTVRegData    *SiS_CHTVReg_ONTSC;
+       const struct SiS_CHTVRegData    *SiS_CHTVReg_UPAL;
+       const struct SiS_CHTVRegData    *SiS_CHTVReg_OPAL;
+       const struct SiS_CHTVRegData    *SiS_CHTVReg_UPALM;
+       const struct SiS_CHTVRegData    *SiS_CHTVReg_OPALM;
+       const struct SiS_CHTVRegData    *SiS_CHTVReg_UPALN;
+       const struct SiS_CHTVRegData    *SiS_CHTVReg_OPALN;
+       const struct SiS_CHTVRegData    *SiS_CHTVReg_SOPAL;
+
+       const unsigned char             *SiS_CHTVVCLKUNTSC;
+       const unsigned char             *SiS_CHTVVCLKONTSC;
+       const unsigned char             *SiS_CHTVVCLKUPAL;
+       const unsigned char             *SiS_CHTVVCLKOPAL;
+       const unsigned char             *SiS_CHTVVCLKUPALM;
+       const unsigned char             *SiS_CHTVVCLKOPALM;
+       const unsigned char             *SiS_CHTVVCLKUPALN;
+       const unsigned char             *SiS_CHTVVCLKOPALN;
+       const unsigned char             *SiS_CHTVVCLKSOPAL;
+
+       unsigned short                  PanelXRes, PanelHT;
+       unsigned short                  PanelYRes, PanelVT;
+       unsigned short                  PanelHRS,  PanelHRE;
+       unsigned short                  PanelVRS,  PanelVRE;
+       unsigned short                  PanelVCLKIdx300;
+       unsigned short                  PanelVCLKIdx315;
+       BOOLEAN                         Alternate1600x1200;
+
+       BOOLEAN                         UseCustomMode;
+       BOOLEAN                         CRT1UsesCustomMode;
+       unsigned short                  CHDisplay;
+       unsigned short                  CHSyncStart;
+       unsigned short                  CHSyncEnd;
+       unsigned short                  CHTotal;
+       unsigned short                  CHBlankStart;
+       unsigned short                  CHBlankEnd;
+       unsigned short                  CVDisplay;
+       unsigned short                  CVSyncStart;
+       unsigned short                  CVSyncEnd;
+       unsigned short                  CVTotal;
+       unsigned short                  CVBlankStart;
+       unsigned short                  CVBlankEnd;
+       unsigned int                    CDClock;
+       unsigned int                    CFlags;
+       unsigned char                   CCRT1CRTC[17];
+       unsigned char                   CSR2B;
+       unsigned char                   CSR2C;
+       unsigned short                  CSRClock;
+       unsigned short                  CSRClock_CRT1;
+       unsigned short                  CModeFlag;
+       unsigned short                  CModeFlag_CRT1;
+       unsigned short                  CInfoFlag;
+
+       int                             LVDSHL;
+
+       BOOLEAN                         Backup;
+       unsigned char                   Backup_Mode;
+       unsigned char                   Backup_14;
+       unsigned char                   Backup_15;
+       unsigned char                   Backup_16;
+       unsigned char                   Backup_17;
+       unsigned char                   Backup_18;
+       unsigned char                   Backup_19;
+       unsigned char                   Backup_1a;
+       unsigned char                   Backup_1b;
+       unsigned char                   Backup_1c;
+       unsigned char                   Backup_1d;
+
+       unsigned char                   Init_P4_0E;
+
+       int                             UsePanelScaler;
+       int                             CenterScreen;
+
+       unsigned short                  CP_Vendor, CP_Product;
+       BOOLEAN                         CP_HaveCustomData;
+       int                             CP_PreferredX, CP_PreferredY, CP_PreferredIndex;
+       int                             CP_MaxX, CP_MaxY, CP_MaxClock;
+       unsigned char                   CP_PrefSR2B, CP_PrefSR2C;
+       unsigned short                  CP_PrefClock;
+       BOOLEAN                         CP_Supports64048075;
+       int                             CP_HDisplay[7], CP_VDisplay[7]; /* For Custom LCD panel dimensions */
+       int                             CP_HTotal[7], CP_VTotal[7];
+       int                             CP_HSyncStart[7], CP_VSyncStart[7];
+       int                             CP_HSyncEnd[7], CP_VSyncEnd[7];
+       int                             CP_HBlankStart[7], CP_VBlankStart[7];
+       int                             CP_HBlankEnd[7], CP_VBlankEnd[7];
+       int                             CP_Clock[7];
+       BOOLEAN                         CP_DataValid[7];
+       BOOLEAN                         CP_HSync_P[7], CP_VSync_P[7], CP_SyncValid[7];
+};
 
 #endif
 
index c71a716..34814a0 100644 (file)
 #define FB_ACCEL_NV_20          44      /* nVidia Arch 20               */
 #define FB_ACCEL_NV_30          45      /* nVidia Arch 30               */
 #define FB_ACCEL_NV_40          46      /* nVidia Arch 40               */
+#define FB_ACCEL_XGI_VOLARI_V  47      /* XGI Volari V3XT, V5, V8      */
+#define FB_ACCEL_XGI_VOLARI_Z  48      /* XGI Volari Z7                */
 #define FB_ACCEL_NEOMAGIC_NM2070 90    /* NeoMagic NM2070              */
 #define FB_ACCEL_NEOMAGIC_NM2090 91    /* NeoMagic NM2090              */
 #define FB_ACCEL_NEOMAGIC_NM2093 92    /* NeoMagic NM2093              */
index 136bf79..e402eb5 100644 (file)
@@ -1,5 +1,7 @@
 /*
- * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria.
+ * sisfb.h - definitions for the SiS framebuffer driver
+ *
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -16,8 +18,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
  */
 
-#ifndef _LINUX_SISFB
-#define _LINUX_SISFB
+#ifndef _LINUX_SISFB_H_
+#define _LINUX_SISFB_H_
 
 #include <asm/ioctl.h>
 #include <asm/types.h>
 /*                   PUBLIC                   */
 /**********************************************/
 
-/* vbflags */
-#define CRT2_DEFAULT            0x00000001
-#define CRT2_LCD                0x00000002  /* TW: Never change the order of the CRT2_XXX entries */
-#define CRT2_TV                 0x00000004  /*     (see SISCycleCRT2Type())                       */
-#define CRT2_VGA                0x00000008
-#define TV_NTSC                 0x00000010
-#define TV_PAL                  0x00000020
-#define TV_HIVISION             0x00000040
-#define TV_YPBPR                0x00000080
-#define TV_AVIDEO               0x00000100
-#define TV_SVIDEO               0x00000200
-#define TV_SCART                0x00000400
-#define VB_CONEXANT            0x00000800      /* 661 series only */
-#define VB_TRUMPION            VB_CONEXANT     /* 300 series only */
-#define TV_PALM                 0x00001000
-#define TV_PALN                 0x00002000
+/* vbflags, public (others in sis.h) */
+#define CRT2_DEFAULT           0x00000001
+#define CRT2_LCD               0x00000002
+#define CRT2_TV                        0x00000004
+#define CRT2_VGA               0x00000008
+#define TV_NTSC                        0x00000010
+#define TV_PAL                 0x00000020
+#define TV_HIVISION            0x00000040
+#define TV_YPBPR               0x00000080
+#define TV_AVIDEO              0x00000100
+#define TV_SVIDEO              0x00000200
+#define TV_SCART               0x00000400
+#define TV_PALM                        0x00001000
+#define TV_PALN                        0x00002000
 #define TV_NTSCJ               0x00001000
-#define VB_302ELV              0x00004000
-#define TV_CHSCART              0x00008000
-#define TV_CHYPBPR525I          0x00010000
+#define TV_CHSCART             0x00008000
+#define TV_CHYPBPR525I         0x00010000
 #define CRT1_VGA               0x00000000
 #define CRT1_LCDA              0x00020000
 #define VGA2_CONNECTED          0x00040000
-#define VB_DISPTYPE_CRT1       0x00080000      /* CRT1 connected and used */
-#define VB_301                  0x00100000     /* Video bridge type */
-#define VB_301B                 0x00200000
-#define VB_302B                 0x00400000
-#define VB_30xBDH              0x00800000      /* 30xB DH version (w/o LCD support) */
-#define VB_LVDS                 0x01000000
-#define VB_CHRONTEL             0x02000000
-#define VB_301LV                0x04000000
-#define VB_302LV                0x08000000
-#define VB_301C                        0x10000000
-#define VB_SINGLE_MODE          0x20000000     /* CRT1 or CRT2; determined by DISPTYPE_CRTx */
-#define VB_MIRROR_MODE         0x40000000      /* CRT1 + CRT2 identical (mirror mode) */
-#define VB_DUALVIEW_MODE       0x80000000      /* CRT1 + CRT2 independent (dual head mode) */
+#define VB_DISPTYPE_CRT1       0x00080000      /* CRT1 connected and used */
+#define VB_SINGLE_MODE         0x20000000      /* CRT1 or CRT2; determined by DISPTYPE_CRTx */
+#define VB_MIRROR_MODE         0x40000000      /* CRT1 + CRT2 identical (mirror mode) */
+#define VB_DUALVIEW_MODE       0x80000000      /* CRT1 + CRT2 independent (dual head mode) */
 
 /* Aliases: */
 #define CRT2_ENABLE            (CRT2_LCD | CRT2_TV | CRT2_VGA)
-#define TV_STANDARD             (TV_NTSC | TV_PAL | TV_PALM | TV_PALN | TV_NTSCJ)
-#define TV_INTERFACE            (TV_AVIDEO|TV_SVIDEO|TV_SCART|TV_HIVISION|TV_YPBPR|TV_CHSCART|TV_CHYPBPR525I)
+#define TV_STANDARD            (TV_NTSC | TV_PAL | TV_PALM | TV_PALN | TV_NTSCJ)
+#define TV_INTERFACE           (TV_AVIDEO|TV_SVIDEO|TV_SCART|TV_HIVISION|TV_YPBPR|TV_CHSCART|TV_CHYPBPR525I)
 
 /* Only if TV_YPBPR is set: */
 #define TV_YPBPR525I           TV_NTSC
 #define TV_YPBPR1080I          TV_PALN
 #define TV_YPBPRALL            (TV_YPBPR525I | TV_YPBPR525P | TV_YPBPR750P | TV_YPBPR1080I)
 
-#define VB_SISBRIDGE            (VB_301|VB_301B|VB_301C|VB_302B|VB_301LV|VB_302LV|VB_302ELV)
-#define VB_SISTVBRIDGE          (VB_301|VB_301B|VB_301C|VB_302B|VB_301LV|VB_302LV)
-#define VB_VIDEOBRIDGE         (VB_SISBRIDGE | VB_LVDS | VB_CHRONTEL | VB_CONEXANT)
-
 #define VB_DISPTYPE_DISP2      CRT2_ENABLE
 #define VB_DISPTYPE_CRT2       CRT2_ENABLE
 #define VB_DISPTYPE_DISP1      VB_DISPTYPE_CRT1
 #define VB_DISPMODE_SINGLE     VB_SINGLE_MODE
 #define VB_DISPMODE_MIRROR     VB_MIRROR_MODE
 #define VB_DISPMODE_DUAL       VB_DUALVIEW_MODE
-#define VB_DISPLAY_MODE        (SINGLE_MODE | MIRROR_MODE | DUALVIEW_MODE)
+#define VB_DISPLAY_MODE                (SINGLE_MODE | MIRROR_MODE | DUALVIEW_MODE)
 
 /* Structure argument for SISFB_GET_INFO ioctl  */
-typedef struct _SISFB_INFO sisfb_info, *psisfb_info;
-
-struct _SISFB_INFO {
-       __u32   sisfb_id;               /* for identifying sisfb */
+struct sisfb_info {
+       __u32   sisfb_id;               /* for identifying sisfb */
 #ifndef SISFB_ID
 #define SISFB_ID         0x53495346    /* Identify myself with 'SISF' */
 #endif
-       __u32   chip_id;                /* PCI-ID of detected chip */
-       __u32   memory;                 /* video memory in KB which sisfb manages */
-       __u32   heapstart;              /* heap start (= sisfb "mem" argument) in KB */
+       __u32   chip_id;                /* PCI-ID of detected chip */
+       __u32   memory;                 /* total video memory in KB */
+       __u32   heapstart;              /* heap start offset in KB */
        __u8    fbvidmode;              /* current sisfb mode */
 
-       __u8    sisfb_version;
-       __u8    sisfb_revision;
-       __u8    sisfb_patchlevel;
+       __u8    sisfb_version;
+       __u8    sisfb_revision;
+       __u8    sisfb_patchlevel;
 
-       __u8    sisfb_caps;             /* sisfb capabilities */
+       __u8    sisfb_caps;             /* sisfb capabilities */
 
        __u32   sisfb_tqlen;            /* turbo queue length (in KB) */
 
-       __u32   sisfb_pcibus;           /* The card's PCI ID */
-       __u32   sisfb_pcislot;
-       __u32   sisfb_pcifunc;
+       __u32   sisfb_pcibus;           /* The card's PCI ID */
+       __u32   sisfb_pcislot;
+       __u32   sisfb_pcifunc;
+
+       __u8    sisfb_lcdpdc;           /* PanelDelayCompensation */
+
+       __u8    sisfb_lcda;             /* Detected status of LCDA for low res/text modes */
+
+       __u32   sisfb_vbflags;
+       __u32   sisfb_currentvbflags;
+
+       __u32   sisfb_scalelcd;
+       __u32   sisfb_specialtiming;
+
+       __u8    sisfb_haveemi;
+       __u8    sisfb_emi30,sisfb_emi31,sisfb_emi32,sisfb_emi33;
+       __u8    sisfb_haveemilcd;
 
-       __u8    sisfb_lcdpdc;           /* PanelDelayCompensation */
+       __u8    sisfb_lcdpdca;          /* PanelDelayCompensation for LCD-via-CRT1 */
 
-       __u8    sisfb_lcda;             /* Detected status of LCDA for low res/text modes */
+       __u16   sisfb_tvxpos, sisfb_tvypos;     /* Warning: Values + 32 ! */
 
-       __u32   sisfb_vbflags;
-       __u32   sisfb_currentvbflags;
+       __u32   sisfb_heapsize;         /* heap size (in KB) */
+       __u32   sisfb_videooffset;      /* Offset of viewport in video memory (in bytes) */
 
-       __u32   sisfb_scalelcd;
-       __u32   sisfb_specialtiming;
+       __u32   sisfb_curfstn;          /* currently running FSTN/DSTN mode */
+       __u32   sisfb_curdstn;
 
-       __u8    sisfb_haveemi;
-       __u8    sisfb_emi30,sisfb_emi31,sisfb_emi32,sisfb_emi33;
-       __u8    sisfb_haveemilcd;
+       __u16   sisfb_pci_vendor;       /* PCI vendor (SiS or XGI) */
 
-       __u8    sisfb_lcdpdca;          /* PanelDelayCompensation for LCD-via-CRT1 */
+       __u32   sisfb_vbflags2;         /* ivideo->vbflags2 */
 
-       __u16   sisfb_tvxpos, sisfb_tvypos;  /* Warning: Values + 32 ! */
+       __u8    sisfb_can_post;         /* sisfb can POST this card */
+       __u8    sisfb_card_posted;      /* card is POSTED */
+       __u8    sisfb_was_boot_device;  /* This card was the boot video device (ie is primary) */
 
-       __u8    reserved[208];          /* for future use */
+       __u8    reserved[183];          /* for future use */
+};
+
+#define SISFB_CMD_GETVBFLAGS   0x55AA0001      /* no arg; result[1] = vbflags */
+#define SISFB_CMD_SWITCHCRT1   0x55AA0010      /* arg[0]: 99 = query, 0 = off, 1 = on */
+/* more to come */
+
+#define SISFB_CMD_ERR_OK       0x80000000      /* command succeeded */
+#define SISFB_CMD_ERR_LOCKED   0x80000001      /* sisfb is locked */
+#define SISFB_CMD_ERR_EARLY    0x80000002      /* request before sisfb took over gfx system */
+#define SISFB_CMD_ERR_NOVB     0x80000003      /* No video bridge */
+#define SISFB_CMD_ERR_NOCRT2   0x80000004      /* can't change CRT1 status, CRT2 disabled */
+/* more to come */
+#define SISFB_CMD_ERR_UNKNOWN   0x8000ffff     /* Unknown command */
+#define SISFB_CMD_ERR_OTHER    0x80010000      /* Other error */
+
+/* Argument for SISFB_CMD ioctl */
+struct sisfb_cmd {
+       __u32  sisfb_cmd;
+       __u32  sisfb_arg[16];
+       __u32  sisfb_result[4];
 };
 
 /* Addtional IOCTLs for communication sisfb <> X driver                */
 /* If changing this, vgatypes.h must also be changed (for X driver)    */
 
 /* ioctl for identifying and giving some info (esp. memory heap start) */
-#define SISFB_GET_INFO_SIZE    _IOR(0xF3,0x00,__u32)
-#define SISFB_GET_INFO         _IOR(0xF3,0x01,struct _SISFB_INFO)
+#define SISFB_GET_INFO_SIZE    _IOR(0xF3,0x00,__u32)
+#define SISFB_GET_INFO         _IOR(0xF3,0x01,struct sisfb_info)
 
 /* ioctrl to get current vertical retrace status */
-#define SISFB_GET_VBRSTATUS    _IOR(0xF3,0x02,__u32)
+#define SISFB_GET_VBRSTATUS    _IOR(0xF3,0x02,__u32)
 
 /* ioctl to enable/disable panning auto-maximize (like nomax parameter) */
-#define SISFB_GET_AUTOMAXIMIZE         _IOR(0xF3,0x03,__u32)
-#define SISFB_SET_AUTOMAXIMIZE         _IOW(0xF3,0x03,__u32)
+#define SISFB_GET_AUTOMAXIMIZE _IOR(0xF3,0x03,__u32)
+#define SISFB_SET_AUTOMAXIMIZE _IOW(0xF3,0x03,__u32)
 
 /* ioctls to relocate TV output (x=D[31:16], y=D[15:0], + 32)*/
-#define SISFB_GET_TVPOSOFFSET   _IOR(0xF3,0x04,__u32)
-#define SISFB_SET_TVPOSOFFSET   _IOW(0xF3,0x04,__u32)
+#define SISFB_GET_TVPOSOFFSET  _IOR(0xF3,0x04,__u32)
+#define SISFB_SET_TVPOSOFFSET  _IOW(0xF3,0x04,__u32)
+
+/* ioctl for internal sisfb commands (sisfbctrl) */
+#define SISFB_COMMAND          _IOWR(0xF3,0x05,struct sisfb_cmd)
 
 /* ioctl for locking sisfb (no register access during lock) */
 /* As of now, only used to avoid register access during
  * the ioctls listed above.
  */
-#define SISFB_SET_LOCK         _IOW(0xF3,0x06,__u32)
-
-/* more to come soon */
+#define SISFB_SET_LOCK         _IOW(0xF3,0x06,__u32)
 
 /* ioctls 0xF3 up to 0x3F reserved for sisfb */
 
@@ -165,7 +184,7 @@ struct _SISFB_INFO {
 /* The following are deprecated and should not be used anymore: */
 /****************************************************************/
 /* ioctl for identifying and giving some info (esp. memory heap start) */
-#define SISFB_GET_INFO_OLD        _IOR('n',0xF8,__u32)
+#define SISFB_GET_INFO_OLD        _IOR('n',0xF8,__u32)
 /* ioctrl to get current vertical retrace status */
 #define SISFB_GET_VBRSTATUS_OLD           _IOR('n',0xF9,__u32)
 /* ioctl to enable/disable panning auto-maximize (like nomax parameter) */
@@ -177,8 +196,8 @@ struct _SISFB_INFO {
 
 /* For fb memory manager (FBIO_ALLOC, FBIO_FREE) */
 struct sis_memreq {
-       __u32   offset;
-       __u32   size;
+       __u32   offset;
+       __u32   size;
 };
 
 /**********************************************/
@@ -187,12 +206,19 @@ struct sis_memreq {
 /**********************************************/
 
 #ifdef __KERNEL__
+
+#include <linux/pci.h>
+
 #define        UNKNOWN_VGA  0
 #define        SIS_300_VGA  1
 #define        SIS_315_VGA  2
 
+#define SISFB_HAVE_MALLOC_NEW
 extern void sis_malloc(struct sis_memreq *req);
+extern void sis_malloc_new(struct pci_dev *pdev, struct sis_memreq *req);
+
 extern void sis_free(u32 base);
+extern void sis_free_new(struct pci_dev *pdev, u32 base);
 #endif
 
 #endif