summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaleb Keithley <kaleb@freedesktop.org>2003-11-14 16:48:55 +0000
committerKaleb Keithley <kaleb@freedesktop.org>2003-11-14 16:48:55 +0000
commitd1473b7bcf205215781d461eb62f8dba0fb78931 (patch)
tree3e20c3e5811215076b10a98c5f1dfe7553d44e94
parent727bfe5d006d0e5c0167c2472af9d8ba69c9e109 (diff)
Initial revision
-rw-r--r--man/sis.man413
-rw-r--r--src/300vtbl.h3314
-rw-r--r--src/310vtbl.h4673
-rw-r--r--src/init.c5968
-rw-r--r--src/init.h316
-rw-r--r--src/init301.c10798
-rw-r--r--src/init301.h285
-rw-r--r--src/initdef.h434
-rw-r--r--src/oem300.h1005
-rw-r--r--src/oem310.h377
-rw-r--r--src/osdef.h169
-rw-r--r--src/sis.h710
-rw-r--r--src/sis300_accel.c1397
-rw-r--r--src/sis300_accel.h297
-rw-r--r--src/sis310_accel.c894
-rw-r--r--src/sis310_accel.h341
-rw-r--r--src/sis6326_video.c1662
-rw-r--r--src/sis_accel.c651
-rw-r--r--src/sis_accel.h237
-rw-r--r--src/sis_cursor.c1106
-rw-r--r--src/sis_cursor.h427
-rw-r--r--src/sis_dac.c2148
-rw-r--r--src/sis_dac.h53
-rw-r--r--src/sis_dga.c412
-rw-r--r--src/sis_dri.c616
-rw-r--r--src/sis_dri.h69
-rw-r--r--src/sis_driver.c7648
-rw-r--r--src/sis_driver.h512
-rw-r--r--src/sis_opt.c774
-rw-r--r--src/sis_regs.h587
-rw-r--r--src/sis_setup.c528
-rw-r--r--src/sis_shadow.c250
-rw-r--r--src/sis_vb.c353
-rw-r--r--src/sis_vga.c1535
-rw-r--r--src/sis_video.c2454
-rw-r--r--src/vgatypes.h368
-rw-r--r--src/vstruct.h571
37 files changed, 54352 insertions, 0 deletions
diff --git a/man/sis.man b/man/sis.man
new file mode 100644
index 0000000..7663044
--- /dev/null
+++ b/man/sis.man
@@ -0,0 +1,413 @@
+.\" $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis.man,v 1.10 2003/01/29 15:42:16 eich Exp $
+.\" shorthand for double quote that works everywhere.
+.ds q \N'34'
+.TH SIS __drivermansuffix__ __vendorversion__
+.SH NAME
+sis \- SiS video driver
+.SH SYNOPSIS
+.nf
+.B "Section \*qDevice\*q"
+.BI " Identifier \*q" devname \*q
+.B " Driver \*qsis\*q"
+\ \ ...
+.B EndSection
+.fi
+.SH DESCRIPTION
+.B sis
+is an XFree86 driver for SiS video chips. The driver is accelerated, and
+provides support for 8, 16 and 24 colordepths. XVideo, Render and other
+extensions are supported as well.
+.SH SUPPORTED HARDWARE
+The
+.B sis
+driver supports PCI and AGP video cards based on the following chipsets:
+.PP
+.B SiS5597/5598
+.B SiS530/620
+.B SiS6326/AGP/DVD
+.B SiS300/305
+.B SiS540
+.B SiS630/730
+.B SiS315/H/PRO
+.B SiS550
+.B SiS650/651/650M/740
+.B SiS330 (Xabre)
+.PP
+In the following text, the following terms are used:
+.PP
+.B old series
+for SiS5597/5598, 530/620 and 6326/AGP/DVD
+.PP
+.B 300 series
+for SiS300/305, 540 and 630/730
+.PP
+.B 310/325/330 series
+for SiS315/H/PRO, 550 and 650/651/650M/740, 330
+.SH CONFIGURATION DETAILS
+Please refer to XF86Config(__filemansuffix__) for general configuration
+details. This section only covers configuration details specific to this
+driver. Please note that support for the SiS330 is new and there may be
+some problems.
+.PP
+.I "1. For all supported chipsets"
+.PP
+The following driver
+.B Options
+are supported on all chipsets:
+.TP
+.BI "Option \*qNoAccel\*q \*q" boolean \*q
+Disable or enable 2D acceleration. Please note: On chipsets with XVideo
+support, this also disables XVideo. Default: acceleration is enabled.
+.TP
+.BI "Option \*qHWCursor\*q \*q" boolean \*q
+Enable or disable the HW cursor. Default: HWCursor is on.
+.TP
+.BI "Option \*qSWCursor\*q \*q" boolean \*q
+The opposite of HWCursor. Default: SWCursor is off.
+.TP
+.BI "Option \*qRotate\*q \*qCW\*q"
+Rotate the display clockwise. This mode is unaccelerated, and uses
+the Shadow Frame Buffer layer.
+Default: no rotation.
+.TP
+.BI "Option \*qRotate\*q \*qCCW\*q"
+Rotate the display counterclockwise. This mode is unaccelerated, and
+uses the Shadow Frame Buffer layer.
+Default: no rotation.
+.TP
+.BI "Option \*qShadowFB\*q \*q" boolean \*q
+Enable or disable use of the shadow framebuffer layer.
+Default: Shadow framebuffer is off.
+.PP
+.I "2. Old series specific information"
+.PP
+The driver will auto-detect the amount of video memory present for all
+these chips, but in the 6326 case, it will limit the memory size to 4MB.
+This is because the 6326's 2D engine can only address 4MB. The remaining
+memory seems to be intended for 3D texture data, since only the 3D
+engine can address RAM above 4MB. However, you can override this forced
+limitation using the
+.B \*qVideoRAM\*q
+option in the device section if your board has more than
+4MB and you need to use it. However, 2D acceleration, Xvideo and the
+HWCursor will be disabled in this case.
+.PP
+The driver will also auto-detect the maximum dotclock and DAC speed.
+If you have problems getting high resolutions because of dot clock
+limitations, try using the
+.B \*qDacSpeed\*q
+option, also in the device section. However, this is not recommended
+for the 6326. For this chipset, the driver has two built-in modes for
+high resolutions which you should use instead. These are named
+.B \*qSIS1280x1024-75\*q
+and
+.B \*qSIS1600x1200-60\*q
+and they will be added to the list of default modes. To use these modes,
+just place them in your Screen section. Example:
+.PP
+.BI "Modes \*qSIS1600x1200-60\*q \*qSIS1280x1024x75\*q \*q1024x768\*q ...
+.PP
+1280x1024 is only available at 8, 15 and 16bpp. 1600x1200 is available
+at 8bpp only.
+.PP
+TV support for the 6326
+.PP
+TV output is supported on the 6326. The driver will auto detect a
+TV connected, and in this case add the following modes to the list
+of default modes: "PAL800x600", "PAL800x600U", "PAL720x540",
+"PAL640x480", "NTSC640x480", "NTSC640x480U" and "NTSC640x400".
+Use these modes like the hi-res modes described above.
+.PP
+The following driver
+.B Options
+are supported on the old series:
+.TP
+.BI "Option \*qTurboQueue\*q \*q" boolean \*q
+Enable or disable TurboQueue mode. Default: off for SIS530/620, on for
+the others
+.TP
+.BI "Option \*qFastVram\*q \*q" boolean \*q
+Enable or disable FastVram mode. Enabling this sets the video RAM timing
+to only one cycle per read operation instead of two cycles. Disabling
+this will set 2 cycles for read and write operations. Leaving this
+option out uses the default.
+Default: off for read, on for write.
+.TP
+.BI "Option \*qNoHostBus\*q \*q" boolean \*q
+(SiS5597/5598 only). Disable CPU-to-VGA host bus support. This
+speeds up CPU to video RAM transfers. Default: Host bus is enabled.
+.TP
+.BI "Option \*qNoXVideo\*q \*q" boolean \*q
+Disable XV (XVideo) extension support. Default: XVideo is on.
+.TP
+.BI "Option \*qTVStandard\*q \*q" string \*q
+(6326 only) Possible parameters are
+.B PAL
+or
+.B NTSC.
+The default is set by a jumper on the card.
+.TP
+.BI "Option \*qTVXPosOffset\*q \*q" integer \*q
+(6326 only) This option allows horizontal relocation the TV output.
+The range is from -16 to 16.
+.TP
+.BI "Option \*qTVYPosOffset\*q \*q" integer \*q
+(6326 only) This option allows vertical relocation the TV output.
+The range is from -16 to 16.
+.TP
+.BI "Option \*qSIS6326TVEnableYFilter\*q \*q" boolean \*q
+(6326 only) This option allows enabling/disabling the Y filter for
+TV output.
+.TP
+.BI "Option \*qSIS6326TVAntiFlicker\*q \*q" string \*q
+(6326 only) This option allow enabling/disabling the anti flicker
+facility for TV output. Possible parameters are
+.B OFF, LOW, MED, HIGH
+or
+.B ADAPTIVE.
+By experience,
+.B ADAPTIVE
+yields the best results.
+.PP
+.I "2. 300 and 310/325/330 series specific information"
+.PP
+The 300 and 310/325/330 series very often come with a video bridge for
+controlling LCD and TV output. Hereinafter, the term
+.B CRT1
+refers to the VGA output of the chip, and
+.B CRT2
+refers to either LCD, TV or secondary VGA. Due to timing reasons,
+only one CRT2 output can be active at the same time. But this
+limitation does not apply to using CRT1 and CRT2 at the same time
+which makes it possible to run the driver in dual head mode.
+.PP
+The driver supports the following video bridges:
+.PP
+.B SiS301
+.B SiS301B
+.B SiS301LV
+.B SiS302B
+.B SiS302LV
+.PP
+Instead of a video bridge, some machines have a
+.B LVDS
+transmitter to control LCD panels, and a
+.B "Chrontel 7005"
+or
+.B "7019"
+for TV output. All these are supported as well.
+.PP
+About TV output
+.PP
+On the SiS301 and the Chrontel 7005, only resolutions up to 800x600
+are supported. On all others, resolutions up to 1024x768 are supported.
+.PP
+About XVideo support
+.PP
+XVideo is supported on all chipsets of both families. However, there
+are some differences in hardware features which cause limitations.
+The 300 series as well as the SiS550, 650M, 651 and 330 support two video
+overlays. The SiS315/H/PRO and 650/740 support only one such overlay.
+On chips with two overlays, one overlay is used for CRT1, the other
+for CRT2. On the other chipsets, the option
+.B \*qXvOnCRT2\*q
+can be used to select the desired output channel.
+.PP
+About dual-head support
+.PP
+Dual head mode has some limitations as regards color depth and
+resolution. Due to memory bandwidth limits, CRT1 might have a
+reduced refresh rate if running on higher resolutions than
+1280x1024.
+.PP
+Colordepth 8 is not supported when running in dual head mode.
+.PP
+The following driver
+.B Options
+are supported on the 300 and 310/325 series:
+.TP
+.BI "Option \*qNoXVideo\*q \*q" boolean \*q
+Disable XV (XVideo) extension support.
+Default: XVideo is on.
+.TP
+.BI "Option \*qXvOnCRT2\*q \*q" boolean \*q
+On chipsets with only one video overlay, this option can
+used to bind the overlay to CRT1 ( if a monitor is detected
+and if this option is either unset or set to
+.B false
+) or CRT2 ( if a CRT2 device is detected or forced, and if this
+option is set to
+.B true
+). If either only CRT1 or CRT2 is detected, the driver decides
+automatically.
+Default: overlay is used on CRT1
+.TP
+.BI "Option \*qForceCRT1\*q \*q" boolean \*q
+The BIOS detects VGA monitors connected to CRT1 at boot time
+and the X driver by default relies on the information passed
+by the BIOS. However, some old monitors are not detected
+correctly. If this is the case, or if you connected the VGA
+monitor after you booted the machine, you may set this
+option to
+.B true
+in order to make the X driver ignore the
+information from the BIOS and initialize CRT1 anyway.
+If this option is set to
+.B false
+, the driver will switch
+off CRT1 and thus save memory bandwidth.
+Default: auto detect CRT1
+.TP
+.BI "Option \*qForceCRT2Type\*q \*q" string \*q
+Force display type to one of:
+.B NONE
+,
+.B TV
+,
+.B SVIDEO
+,
+.B COMPOSITE
+,
+.B SCART,
+,
+.B LCD
+,
+.B VGA
+;
+.B NONE
+will disable CRT2. The SVIDEO, COMPOSITE and SCART parameters
+can be used to force the driver to use a specific TV output
+connector (if present).
+Default: auto detect.
+.TP
+.BI "Option \*qPanelDelayCompensation\*q \*q" integer \*q
+This option is only for machines with a 300 series chipset
+and either a SiS301B video bridge or a LVDS transmitter.
+Different LCD panels require different delay compensation
+values. In most cases, the driver can autodetect this value.
+However, due to bad BIOS design this might fail in rare
+cases. If your LCD shows small horizontal waves, set the
+parameter of this option first to
+.B 4
+,
+.B 32
+or
+.B 24
+and if the problem persists, try using other values between
+4 and 60 in steps of 4.
+.TP
+.BI "Option \*qUseROMData\*q \*q" boolean \*q
+The driver reads some data from the BIOS ROM, especially
+LCD dependent information. If the folks at SiS some day
+decide to change the location of this data inside the
+BIOS image, the display might not be initialized correctly.
+In order to prevent this, set this option's parameter to
+.B false.
+Default: ROM data is used
+.TP
+.BI "Option \*qTVStandard\*q \*q" string \*q
+Force the TV standard to either
+.B PAL
+or
+.B NTSC.
+On some machines with 630, 730 or 650/740,
+.B PALM
+and
+.B PALN
+are supported as well. Default: BIOS setting.
+.TP
+.BI "Option \*qTVXPosOffset\*q \*q" integer \*q
+This option allows horizontal relocation the TV output.
+The range is from -32 to 32. Not supported on the Chrontel
+7019 yet.
+.TP
+.BI "Option \*qTVYPosOffset\*q \*q" integer \*q
+This option allows vertical relocation the TV output.
+The range is from -32 to 32. Not supported on the Chrontel
+7019 yet.
+.TP
+.BI "Option \*qCHTVOverscan\*q \*q" boolean \*q
+On machines with a Chrontel TV encoder, this can be used to
+force the TV mode to overscan or underscan.
+.B True
+means overscan,
+.B false
+means underscan.
+Default: BIOS setting.
+.TP
+.BI "Option \*qCHTVSuperOverscan\*q \*q" boolean \*q
+On machines with a Chrontel 7005 TV encoder, this option
+enables a super-overscan mode. This is only supported if
+the TV standard is PAL. Super overscan will produce an
+image on the TV which is larger than the viewable area.
+.PP
+.I "3. 300 series specific information"
+.PP
+DRI is supported on the 300 series only. DRI requires
+the kernel's SiS framebuffer driver (
+.B sisfb
+) and some other modules
+which come with either the kernel or XFree86.
+.PP
+Sisfb takes care of memory management for texture
+data. In order to prevent the X driver and sisfb from
+overwriting each others video memory, sisfb reserves
+an amount of video memory for the X driver. This amount
+can either be selected using sisfb's mem parameter, or
+auto-selected depending on the amount of total video RAM
+available. However, the X driver needs to know about the
+amount of RAM sisfb reserved. For this purpose, the
+.TP
+.BI "Option \*qMaxXFBMem\*q \*q" integer \*q
+.PP
+exists.
+.PP
+At the moment (2002), the SiS DRI driver is not
+maintained, lacks support for memory swapping and
+has a few bugs. If you intend to use DRI, I recommend
+setting the total video memory in the BIOS to 64MB
+in order to at least overcome the lack of memory
+swap functions.
+.PP
+Sisfb can be used for memory management only, or as
+a complete framebuffer driver. If you start sisfb
+with a valid mode (ie you gain a graphical console),
+the X driver can communicate with sisfb and doesn't
+require setting the
+.B \*qMaxXFBMem\*q
+option at all. The X driver will receive enough information
+from sisfb in this case.
+.PP
+However, if you use sisfb for memory management only, ie
+you started sisfb with mode=none and still have a text
+mode console, there is no communication between sisfb
+and the X driver. In this case, you need to set
+.B \*qMaxXFBMem\*q
+to the same value as you gave sisfb with its mem
+parameter. If you didn't specify any mem parameter,
+sisfb will reserve
+.TP
+12288KB if more than 16MB of total video RAM is available,
+.TP
+8192KB if between 12 and 16MB of video RAM is available,
+.TP
+4096KB in all other cases.
+.PP
+Then you need to specify any of these amounts as the
+parameter for the
+.B \*qMaxXFBMem\*q
+option. The value is to be given without 'KB'.
+.SH "KNOWN BUGS"
+For some reason, PAL TV output on the SiS301LV bridge is
+only black and white. NTSC is OK, though.
+.PP
+LCD panels with a resolution of 1280x1024 do not work
+correctly.
+.SH "SEE ALSO"
+XFree86(1), XF86Config(__filemansuffix__), xf86config(1), Xserver(1), X(__miscmansuffix__)
+.PP
+.B "http://www.winischhofer.net"
+for more information and updates
+.SH AUTHORS
+Authors include: Alan Hourihane, Mike Chapman, Juanjo Santamarta, Mitani
+Hiroshi, David Thomas, Sung-Ching Lin, Ademar Reis, Thomas Winischhofer
diff --git a/src/300vtbl.h b/src/300vtbl.h
new file mode 100644
index 0000000..a6989da
--- /dev/null
+++ b/src/300vtbl.h
@@ -0,0 +1,3314 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/300vtbl.h,v 1.6 2003/02/10 01:14:16 tsi Exp $ */
+
+
+/* Register settings for SiS 300 series */
+
+
+typedef struct _SiS300_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;
+} SiS300_StStruct;
+
+static const SiS300_StStruct SiS300_SModeIDTable[] =
+{
+ {0x01,0x9208,0x01,0x00,0x00,0x00,0x00,0x00},
+ {0x01,0x1210,0x14,0x01,0x01,0x00,0x00,0x00},
+ {0x01,0x1010,0x17,0x02,0x02,0x00,0x00,0x00},
+ {0x03,0x8208,0x03,0x00,0x00,0x00,0x00,0x00},
+ {0x03,0x0210,0x16,0x01,0x01,0x00,0x00,0x00},
+ {0x03,0x0010,0x18,0x02,0x02,0x00,0x00,0x00},
+ {0x05,0x9209,0x05,0x00,0x00,0x00,0x00,0x00},
+ {0x06,0x8209,0x06,0x00,0x00,0x00,0x00,0x00},
+ {0x07,0x0000,0x07,0x03,0x03,0x00,0x00,0x00},
+ {0x07,0x0000,0x19,0x02,0x02,0x00,0x00,0x00},
+ {0x0d,0x920a,0x0d,0x00,0x00,0x00,0x00,0x00},
+ {0x0e,0x820a,0x0e,0x00,0x00,0x00,0x00,0x00},
+ {0x0f,0x0202,0x11,0x01,0x01,0x00,0x00,0x00},
+ {0x10,0x0212,0x12,0x01,0x01,0x00,0x00,0x00},
+ {0x11,0x0212,0x1a,0x04,0x04,0x00,0x00,0x00},
+ {0x12,0x0212,0x1b,0x04,0x04,0x00,0x00,0x00},
+ {0x13,0x021b,0x1c,0x00,0x00,0x00,0x00,0x00},
+ {0x12,0x0010,0x18,0x02,0x02,0x00,0x00,0x00},
+ {0x12,0x0210,0x18,0x01,0x01,0x00,0x00,0x00},
+ {0xff, 0, 0, 0, 0, 0, 0, 0}
+};
+
+typedef struct _SiS300_StandTableStruct
+{
+ UCHAR CRT_COLS;
+ UCHAR ROWS;
+ UCHAR CHAR_HEIGHT;
+ USHORT CRT_LEN;
+ UCHAR SR[4];
+ UCHAR MISC;
+ UCHAR CRTC[0x19];
+ UCHAR ATTR[0x14];
+ UCHAR GRC[9];
+} SiS300_StandTableStruct;
+
+static const SiS300_StandTableStruct SiS300_StandTable[] =
+{
+ {0x28,0x18,0x08,0x0800, /* 0x00 */
+ {0x09,0x03,0x00,0x02},
+ 0x63,
+ {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+ 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
+ 0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
+ 0xff},
+ {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+ 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+ 0x08,0x00,0x0f,0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+ 0xff} },
+ {0x28,0x18,0x08,0x0800, /* 0x01 */
+ {0x09,0x03,0x00,0x02},
+ 0x63,
+ {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+ 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
+ 0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
+ 0xff},
+ {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+ 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+ 0x08,0x00,0x0f,0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+ 0xff} },
+ {0x50,0x18,0x08,0x1000, /* 0x02 */
+ {0x01,0x03,0x00,0x02},
+ 0x63,
+ {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+ 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
+ 0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
+ 0xff},
+ {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+ 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+ 0x08,0x00,0x0f,0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+ 0xff} },
+ {0x50,0x18,0x08,0x1000, /* 0x03 */
+ {0x01,0x03,0x00,0x02},
+ 0x63,
+ {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+ 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
+ 0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
+ 0xff},
+ {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+ 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+ 0x08,0x00,0x0f,0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+ 0xff} },
+ {0x28,0x18,0x08,0x4000, /* 0x04 */
+ {0x09,0x03,0x00,0x02},
+ 0x63,
+ {0x2d,0x27,0x28,0x90,0x2b,0x80,0xbf,0x1f,
+ 0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
+ 0xff},
+ {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
+ 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+ 0x01,0x00,0x03,0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
+ 0xff} },
+ {0x28,0x18,0x08,0x4000, /* 0x05 */
+ {0x09,0x03,0x00,0x02},
+ 0x63,
+ {0x2d,0x27,0x28,0x90,0x2b,0x80,0xbf,0x1f,
+ 0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
+ 0xff},
+ {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
+ 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+ 0x01,0x00,0x03,0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
+ 0xff} },
+ {0x50,0x18,0x08,0x4000, /* 0x06 */
+ {0x01,0x01,0x00,0x06},
+ 0x63,
+ {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,
+ 0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xc2,
+ 0xff},
+ {0x00,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+ 0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+ 0x01,0x00,0x01,0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x00,
+ 0xff} },
+ {0x50,0x18,0x0e,0x1000, /* 0x07 */
+ {0x00,0x03,0x00,0x03},
+ 0xa6,
+ {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+ 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+ 0x83,0x85,0x5d,0x28,0x0d,0x63,0xba,0xa3,
+ 0xff},
+ {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+ 0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+ 0x0e,0x00,0x0f,0x08},
+ {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
+ 0xff} },
+/* MDA_DAC*/
+ {0x00,0x00,0x00,0x0000, /* 0x08 */
+ {0x00,0x00,0x00,0x15},
+ 0x15,
+ {0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+ 0x15,0x15,0x15,0x15,0x15,0x15,0x3f,0x3f,
+ 0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x00,
+ 0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x15,0x15,0x15,
+ 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+ 0x15,0x15,0x15,0x15},
+ {0x15,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
+ 0x3f} },
+/* CGA_DAC*/
+ {0x00,0x10,0x04,0x0114, /* 0x09 */
+ {0x11,0x09,0x15,0x00},
+ 0x10,
+ {0x04,0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,
+ 0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x2a,0x3a,
+ 0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x10,
+ 0x04},
+ {0x14,0x01,0x11,0x09,0x15,0x00,0x10,0x04,
+ 0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,0x2e,
+ 0x3e,0x2b,0x3b,0x2f},
+ {0x3f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
+ 0x3f} },
+/* EGA_DAC*/
+ {0x00,0x10,0x04,0x0114, /* 0x0a */
+ {0x11,0x05,0x15,0x20},
+ 0x30,
+ {0x24,0x34,0x21,0x31,0x25,0x35,0x08,0x18,
+ 0x0c,0x1c,0x09,0x19,0x0d,0x1d,0x28,0x38,
+ 0x2c,0x3c,0x29,0x39,0x2d,0x3d,0x02,0x12,
+ 0x06},
+ {0x16,0x03,0x13,0x07,0x17,0x22,0x32,0x26,
+ 0x36,0x23,0x33,0x27,0x37,0x0a,0x1a,0x0e,
+ 0x1e,0x0b,0x1b,0x0f},
+ {0x1f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
+ 0x3f} },
+/* VGA_DAC*/
+ {0x00,0x10,0x04,0x0114, /* 0x0b */
+ {0x11,0x09,0x15,0x2a},
+ 0x3a,
+ {0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x05,
+ 0x08,0x0b,0x0e,0x11,0x14,0x18,0x1c,0x20,
+ 0x24,0x28,0x2d,0x32,0x38,0x3f,0x00,0x10,
+ 0x1f},
+ {0x2f,0x3f,0x1f,0x27,0x2f,0x37,0x3f,0x2d,
+ 0x31,0x36,0x3a,0x3f,0x00,0x07,0x0e,0x15,
+ 0x1c,0x0e,0x11,0x15},
+ {0x18,0x1c,0x14,0x16,0x18,0x1a,0x1c,0x00,
+ 0x04} },
+ {0x08,0x0c,0x10,0x0a08, /* 0x0c */
+ {0x0c,0x0e,0x10,0x0b},
+ 0x0c,
+ {0x0d,0x0f,0x10,0x10,0x01,0x08,0x00,0x00,
+ 0x00,0x00,0x01,0x00,0x02,0x02,0x01,0x00,
+ 0x04,0x04,0x01,0x00,0x05,0x02,0x05,0x00,
+ 0x06},
+ {0x01,0x06,0x05,0x06,0x00,0x08,0x01,0x08,
+ 0x00,0x07,0x02,0x07,0x06,0x07,0x00,0x00,
+ 0x00,0x00,0x00,0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00} },
+ {0x28,0x18,0x08,0x2000, /* 0x0d */
+ {0x09,0x0f,0x00,0x06},
+ 0x63,
+ {0x2d,0x27,0x28,0x90,0x2b,0x80,0xbf,0x1f,
+ 0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xe3,
+ 0xff},
+ {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+ 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+ 0x01,0x00,0x0f,0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
+ 0xff} },
+ {0x50,0x18,0x08,0x4000, /* 0x0e */
+ {0x01,0x0f,0x00,0x06},
+ 0x63,
+ {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,
+ 0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xe3,
+ 0xff},
+ {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+ 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+ 0x01,0x00,0x0f,0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
+ 0xff} },
+ {0x00,0x00,0x00,0x0000, /* 0x0f */ /* TW: Standtable for VGA modes */
+ {0x01,0x0f,0x00,0x0e},
+ 0x23,
+ {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,
+ 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xea,0x8c,0xdf,0x28,0x40,0xe7,0x04,0xa3,
+ 0xff},
+ {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+ 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
+ 0x01,0x00,0x00,0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
+ 0xff} },
+ {0x4a,0x36,0x00,0x00c0, /* 0x10 */
+ {0x00,0x00,0x00,0x00},
+ 0x00,
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x3a,
+ 0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x1a,0x00,0x57,0x39,0x00,0xc0,
+ 0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00} },
+ {0x50,0x18,0x0e,0x8000, /* 0x11 */
+ {0x01,0x0f,0x00,0x06},
+ 0xa2,
+ {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,
+ 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x83,0x85,0x5d,0x28,0x0f,0x63,0xba,0xe3,
+ 0xff},
+ {0x00,0x08,0x00,0x00,0x18,0x18,0x00,0x00,
+ 0x00,0x08,0x00,0x00,0x00,0x18,0x00,0x00,
+ 0x0b,0x00,0x05,0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x05,
+ 0xff} },
+ {0x50,0x18,0x0e,0x8000, /* 0x12 */
+ {0x01,0x0f,0x00,0x06},
+ 0xa3,
+ {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,
+ 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x83,0x85,0x5d,0x28,0x0f,0x63,0xba,0xe3,
+ 0xff},
+ {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+ 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+ 0x01,0x00,0x0f,0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
+ 0xff} },
+ {0x28,0x18,0x0e,0x0800, /* 0x13 */
+ {0x09,0x03,0x00,0x02},
+ 0xa3,
+ {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+ 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+ 0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
+ 0xff},
+ {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+ 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+ 0x08,0x00,0x0f,0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+ 0xff} },
+ {0x28,0x18,0x0e,0x0800, /* 0x14 */
+ {0x09,0x03,0x00,0x02},
+ 0xa3,
+ {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+ 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+ 0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
+ 0xff},
+ {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+ 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+ 0x08,0x00,0x0f,0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+ 0xff} },
+ {0x50,0x18,0x0e,0x1000, /* 0x15 */
+ {0x01,0x03,0x00,0x02},
+ 0xa3,
+ {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+ 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+ 0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
+ 0xff},
+ {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+ 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+ 0x08,0x00,0x0f,0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+ 0xff} },
+ {0x50,0x18,0x0e,0x1000, /* 0x16 */
+ {0x01,0x03,0x00,0x02},
+ 0xa3,
+ {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+ 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+ 0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
+ 0xff},
+ {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+ 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+ 0x08,0x00,0x0f,0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+ 0xff} },
+ {0x28,0x18,0x10,0x0800, /* 0x17 */
+ {0x08,0x03,0x00,0x02},
+ 0x67,
+ {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+ 0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
+ 0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
+ 0xff},
+ {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+ 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+ 0x0c,0x00,0x0f,0x08},
+ {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+ 0xff} },
+ {0x50,0x18,0x10,0x1000, /* 0x18 */
+ {0x00,0x03,0x00,0x02},
+ 0x67,
+ {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+ 0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
+ 0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
+ 0xff},
+ {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+ 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+ 0x0c,0x00,0x0f,0x08},
+ {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+ 0xff} },
+ {0x50,0x18,0x10,0x1000, /* 0x19 */
+ {0x00,0x03,0x00,0x02},
+ 0x66,
+ {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+ 0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
+ 0x9c,0x8e,0x8f,0x28,0x0f,0x96,0xb9,0xa3,
+ 0xff},
+ {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+ 0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+ 0x0e,0x00,0x0f,0x08},
+ {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
+ 0xff} },
+ {0x50,0x1d,0x10,0xa000, /* 0x1a */
+ {0x01,0x0f,0x00,0x06},
+ 0xe3,
+ {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,
+ 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xea,0x8c,0xdf,0x28,0x00,0xe7,0x04,0xc3,
+ 0xff},
+ {0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
+ 0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
+ 0x01,0x00,0x0f,0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x01,
+ 0xff} },
+ {0x50,0x1d,0x10,0xa000, /* 0x1b */
+ {0x01,0x0f,0x00,0x06},
+ 0xe3,
+ {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,
+ 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xea,0x8c,0xdf,0x28,0x00,0xe7,0x04,0xe3,
+ 0xff},
+ {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+ 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+ 0x01,0x00,0x0f,0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
+ 0xff} },
+ {0x28,0x18,0x08,0x2000, /* 0x1c */
+ {0x01,0x0f,0x00,0x0e},
+ 0x63,
+ {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,
+ 0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x9c,0x8e,0x8f,0x28,0x40,0x96,0xb9,0xa3,
+ 0xff},
+ {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+ 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
+ 0x41,0x00,0x0f,0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
+ 0xff} }
+};
+
+typedef struct _SiS300_ExtStruct
+{
+ UCHAR Ext_ModeID;
+ USHORT Ext_ModeFlag;
+ USHORT Ext_ModeInfo;
+ USHORT Ext_Point;
+ USHORT Ext_VESAID;
+ UCHAR Ext_VESAMEMSize;
+ UCHAR Ext_RESINFO;
+ UCHAR VB_ExtTVFlickerIndex;
+ UCHAR VB_ExtTVEdgeIndex;
+ UCHAR VB_ExtTVYFilterIndex;
+ UCHAR REFindex;
+} SiS300_ExtStruct;
+
+static const SiS300_ExtStruct SiS300_EModeIDTable[] =
+{
+ {0x6a,0x2212,0x47,0x3563,0x0102,0x08,0x07,0x00,0x00,0x00,0x00}, /* 800x600x? */
+ {0x2e,0x0a1b,0x36,0x3539,0x0101,0x08,0x06,0x00,0x00,0x00,0x08},
+ {0x2f,0x021b,0x35,0x3532,0x0100,0x08,0x05,0x00,0x00,0x00,0x10}, /* 640x400x8 */
+ {0x30,0x2a1b,0x47,0x3563,0x0103,0x08,0x07,0x00,0x00,0x00,0x00},
+ {0x31,0x0a1b,0xad,0x3630,0x0000,0x08,0x0c,0x00,0x00,0x00,0x11}, /* 720x480x8 */
+ {0x32,0x2a1b,0xae,0x3637,0x0000,0x08,0x0d,0x00,0x00,0x00,0x12}, /* 720x576x8 */
+ {0x33,0x0a1d,0xad,0x3630,0x0000,0x08,0x0c,0x00,0x00,0x00,0x11}, /* 720x480x16 */
+ {0x34,0x2a1d,0xae,0x3637,0x0000,0x08,0x0d,0x00,0x00,0x00,0x12}, /* 720x576x16 */
+ {0x35,0x0a1f,0xad,0x3630,0x0000,0x08,0x0c,0x00,0x00,0x00,0x11}, /* 720x480x32 */
+ {0x36,0x2a1f,0xae,0x3637,0x0000,0x08,0x0d,0x00,0x00,0x00,0x12}, /* 720x576x32 */
+ {0x37,0x0212,0x58,0x358d,0x0104,0x08,0x08,0x00,0x00,0x00,0x13}, /* 1024x768x? */
+ {0x38,0x0a1b,0x58,0x358d,0x0105,0x08,0x08,0x00,0x00,0x00,0x13}, /* 1024x768x8 */
+ {0x3a,0x0e3b,0x69,0x35be,0x0107,0x08,0x09,0x00,0x00,0x00,0x1a}, /* 1280x1024x8 */
+ {0x3c,0x063b,0x7a,0x35d4,0x0130,0x08,0x0a,0x00,0x00,0x00,0x1e},
+ {0x3d,0x067d,0x7a,0x35d4,0x0131,0x08,0x0a,0x00,0x00,0x00,0x1e},
+ {0x40,0x921c,0x00,0x3516,0x010d,0x08,0x00,0x00,0x00,0x00,0x23},
+ {0x41,0x921d,0x00,0x3516,0x010e,0x08,0x00,0x00,0x00,0x00,0x23},
+ {0x43,0x0a1c,0x36,0x3539,0x0110,0x08,0x06,0x00,0x00,0x00,0x08},
+ {0x44,0x0a1d,0x36,0x3539,0x0111,0x08,0x06,0x00,0x00,0x00,0x08},
+ {0x46,0x2a1c,0x47,0x3563,0x0113,0x08,0x07,0x00,0x00,0x00,0x00}, /* 800x600 */
+ {0x47,0x2a1d,0x47,0x3563,0x0114,0x08,0x07,0x00,0x00,0x00,0x00}, /* 800x600 */
+ {0x49,0x0a3c,0x58,0x358d,0x0116,0x08,0x08,0x00,0x00,0x00,0x13},
+ {0x4a,0x0a3d,0x58,0x358d,0x0117,0x08,0x08,0x00,0x00,0x00,0x13},
+ {0x4c,0x0e7c,0x69,0x35be,0x0119,0x08,0x09,0x00,0x00,0x00,0x1a},
+ {0x4d,0x0e7d,0x69,0x35be,0x011a,0x08,0x09,0x00,0x00,0x00,0x1a},
+ {0x50,0x921b,0x01,0x351d,0x0132,0x08,0x01,0x00,0x00,0x00,0x24},
+ {0x51,0xb21b,0x13,0x3524,0x0133,0x08,0x03,0x00,0x00,0x00,0x25}, /* 400x300 */
+ {0x52,0x921b,0x24,0x352b,0x0134,0x08,0x04,0x00,0x00,0x00,0x26},
+ {0x56,0x921d,0x01,0x351d,0x0135,0x08,0x01,0x00,0x00,0x00,0x24},
+ {0x57,0xb21d,0x13,0x3524,0x0136,0x08,0x03,0x00,0x00,0x00,0x25}, /* 400x300 */
+ {0x58,0x921d,0x24,0x352b,0x0137,0x08,0x04,0x00,0x00,0x00,0x26},
+ {0x59,0x921b,0x00,0x3516,0x0138,0x08,0x00,0x00,0x00,0x00,0x23},
+ {0x5c,0x921f,0x24,0x352b,0x0000,0x08,0x04,0x00,0x00,0x00,0x26}, /* TW: inserted 512x384x32 */
+ {0x5d,0x021d,0x35,0x3532,0x0139,0x08,0x05,0x00,0x00,0x00,0x10}, /* 640x400x16 */
+ {0x5e,0x021f,0x35,0x3532,0x0000,0x08,0x05,0x00,0x00,0x00,0x10}, /* TW: inserted 640x400x32 */
+ {0x62,0x0a3f,0x36,0x3539,0x013a,0x08,0x06,0x00,0x00,0x00,0x08},
+ {0x63,0x2a3f,0x47,0x3563,0x013b,0x08,0x07,0x00,0x00,0x00,0x00}, /* 800x600 */
+ {0x64,0x0a7f,0x58,0x358d,0x013c,0x08,0x08,0x00,0x00,0x00,0x13},
+ {0x65,0x0eff,0x69,0x35be,0x013d,0x08,0x09,0x00,0x00,0x00,0x1a},
+ {0x66,0x06ff,0x7a,0x35d4,0x013e,0x08,0x0a,0x00,0x00,0x00,0x1e},
+ {0x68,0x067b,0x8b,0x35ef,0x013f,0x08,0x0b,0x00,0x00,0x00,0x27},
+ {0x69,0x06fd,0x8b,0x35ef,0x0140,0x08,0x0b,0x00,0x00,0x00,0x27},
+ {0x6b,0x07ff,0x8b,0x35ef,0x0000,0x10,0x0b,0x00,0x00,0x00,0x27},
+ {0x6c,0x067b,0x9c,0x35f6,0x0000,0x08,0x11,0x00,0x00,0x00,0x28}, /* TW: 2048x1536x8 - not in BIOS! */
+ {0x6d,0x06fd,0x9c,0x35f6,0x0000,0x10,0x11,0x00,0x00,0x00,0x28}, /* TW: 2048x1536x16 - not in BIOS! */
+ {0x6e,0x0a3b,0x6f,0x35b2,0x0000,0x08,0x0e,0x00,0x00,0x00,0x29}, /* 1280x960x8 */
+ {0x6f,0x0a7d,0x6f,0x35b2,0x0000,0x08,0x0e,0x00,0x00,0x00,0x29}, /* 1280x960x16 */
+ /* TW: 16:9 modes copied from 310/325 series - not in ANY BIOS */
+ {0x70,0x2a1b,0x40,0x3b52,0x0000,0x08,0x12,0x00,0x00,0x07,0x2d}, /* 800x480x8 */
+ {0x71,0x0a1b,0x51,0x3b63,0x0000,0x08,0x13,0x00,0x00,0x00,0x30}, /* 1024x576x8 */
+ {0x74,0x0a1d,0x51,0x3b63,0x0000,0x08,0x13,0x00,0x00,0x00,0x30}, /* 1024x576x16 */
+ {0x75,0x0e3d,0x62,0x3b74,0x0000,0x08,0x14,0x00,0x00,0x00,0x33}, /* 1280x720x16 */
+ {0x76,0x2a1f,0x40,0x3b52,0x0000,0x08,0x12,0x00,0x00,0x07,0x2d}, /* 800x480x32 */
+ {0x77,0x0a3f,0x51,0x3b63,0x0000,0x08,0x13,0x00,0x00,0x00,0x30}, /* 1024x576x32 */
+ {0x78,0x0eff,0x62,0x3b74,0x0000,0x08,0x14,0x00,0x00,0x00,0x33}, /* 1280x720x32 */
+ {0x79,0x0e3b,0x62,0x3b74,0x0000,0x08,0x14,0x00,0x00,0x00,0x33}, /* 1280x720x8 */
+ {0x7a,0x2a1d,0x40,0x3b52,0x0000,0x08,0x12,0x00,0x00,0x07,0x2d}, /* 800x480x16 */
+ /* TW: End of new 16:9 modes */
+ {0x7b,0x0aff,0x6f,0x35b2,0x0000,0x08,0x0e,0x00,0x00,0x00,0x29}, /* 1280x960x32 */
+ {0x20,0x0a1b,0x54,0x0000,0x0000,0x08,0x0f,0x00,0x00,0x00,0x2b}, /* 1024x600 */
+ {0x21,0x0a3d,0x54,0x0000,0x0000,0x08,0x0f,0x00,0x00,0x00,0x2b},
+ {0x22,0x0a7f,0x54,0x0000,0x0000,0x08,0x0f,0x00,0x00,0x00,0x2b},
+ {0x23,0x0a1b,0xc5,0x0000,0x0000,0x08,0x10,0x00,0x00,0x00,0x2c}, /* 1152x768 */
+ {0x24,0x0a3d,0xc5,0x431d,0x0000,0x08,0x10,0x00,0x00,0x00,0x2c},
+ {0x25,0x0a7f,0xc5,0x431d,0x0000,0x08,0x10,0x00,0x00,0x00,0x2c},
+ {0x29,0x0e1b,0xc5,0x0000,0x0000,0x08,0x15,0x00,0x00,0x00,0x36}, /* TW: NEW 1152x864 - not in BIOS */
+ {0x2a,0x0e3d,0xc5,0x0000,0x0000,0x08,0x15,0x00,0x00,0x00,0x36},
+ {0x2b,0x0e7f,0xc5,0x0000,0x0000,0x08,0x15,0x00,0x00,0x00,0x36},
+ {0x39,0x2a1b,0xd6,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x38}, /* TW: NEW 848x480 - not in BIOS */
+ {0x3b,0x2a3d,0xd6,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x38},
+ {0x3e,0x2a7f,0xd6,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x38},
+ {0x3f,0x2a1b,0xd7,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x3a}, /* TW: NEW 856x480 - not in BIOS */
+ {0x42,0x2a3d,0xd7,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x3a},
+ {0x45,0x2a7f,0xd7,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x3a},
+ {0x48,0x223b,0xe8,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x3c}, /* TW: NEW 1360x768 - not in BIOS */
+ {0x4b,0x227d,0xe8,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x3c},
+ {0x4e,0x22ff,0xe8,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x3c},
+ {0xff,0x0000,0x00,0x0000,0xffff,0x00,0x00,0x00,0x00,0x00,0x00}
+};
+
+typedef struct _SiS300_Ext2Struct
+{
+ USHORT Ext_InfoFlag;
+ UCHAR Ext_CRT1CRTC; /* TW: Index in SiS300_CRT1Table */
+ UCHAR Ext_CRTVCLK; /* TW: Index in VCLK array */
+ UCHAR Ext_CRT2CRTC; /* TW: Index in LCD Paneltype arrays (&3f) */
+ UCHAR ModeID;
+ USHORT XRes;
+ USHORT YRes;
+ USHORT ROM_OFFSET;
+} SiS300_Ext2Struct;
+
+static const SiS300_Ext2Struct SiS300_RefIndex[] =
+{ /* TW: Don't ever insert anything here, table is indexed */
+ {0x085f,0x0d,0x03,0x05,0x6a, 800, 600,0x3563}, /* 00 */
+ {0x0467,0x0e,0x44,0x05,0x6a, 800, 600,0x3568}, /* 01 */
+ {0x0067,0x0f,0x07,0x48,0x6a, 800, 600,0x356d}, /* 02 - CRT1CRTC was 0x4f */
+ {0x0067,0x10,0x06,0x8b,0x6a, 800, 600,0x3572}, /* 03 */
+ {0x0147,0x11,0x08,0x00,0x6a, 800, 600,0x3577}, /* 04 */
+ {0x0147,0x12,0x0c,0x00,0x6a, 800, 600,0x357c}, /* 05 */
+ {0x0047,0x11,0x4e,0x00,0x6a, 800, 600,0x3581}, /* 06 - CRT1CRTC was 0x51 */
+ {0x0047,0x11,0x13,0x00,0x6a, 800, 600,0x3586}, /* 07 */
+ {0xc85f,0x05,0x00,0x04,0x2e, 640, 480,0x3539}, /* 08 */
+ {0xc067,0x06,0x02,0x04,0x2e, 640, 480,0x353e}, /* 09 */
+ {0xc067,0x07,0x02,0x47,0x2e, 640, 480,0x3543}, /* 0a */
+ {0xc067,0x08,0x03,0x8a,0x2e, 640, 480,0x3548}, /* 0b */
+ {0xc047,0x09,0x05,0x00,0x2e, 640, 480,0x354d}, /* 0c */
+ {0xc047,0x0a,0x08,0x00,0x2e, 640, 480,0x3552}, /* 0d */
+ {0xc047,0x0b,0x0a,0x00,0x2e, 640, 480,0x3557}, /* 0e */
+ {0xc047,0x0c,0x10,0x00,0x2e, 640, 480,0x355c}, /* 0f */
+ {0x487f,0x04,0x00,0x00,0x2f, 640, 400,0x3532}, /* 10 */
+ {0xc00f,0x31,0x01,0x06,0x31, 720, 480,0x3630}, /* 11 */
+ {0x000f,0x32,0x03,0x06,0x32, 720, 576,0x3637}, /* 12 */
+ {0x0187,0x15,0x05,0x00,0x37,1024, 768,0x358d}, /* 13 */
+ {0xc877,0x16,0x09,0x06,0x37,1024, 768,0x3592}, /* 14 */
+ {0xc067,0x17,0x0b,0x49,0x37,1024, 768,0x3597}, /* 15 - CRT1CRTC was 0x97 */
+ {0x0267,0x18,0x0d,0x00,0x37,1024, 768,0x359c}, /* 16 */
+ {0x0047,0x19,0x11,0x8c,0x37,1024, 768,0x35a1}, /* 17 - CRT1CRTC was 0x59 */
+ {0x0047,0x1a,0x52,0x00,0x37,1024, 768,0x35a6}, /* 18 */
+ {0x0047,0x1b,0x16,0x00,0x37,1024, 768,0x35ab}, /* 19 - CRT1CRTC was 0x5b */
+ {0x0387,0x1c,0x4d,0x00,0x3a,1280,1024,0x35be}, /* 1a - CRT1CRTC was 0x5c */
+ {0x0077,0x1d,0x14,0x07,0x3a,1280,1024,0x35c3}, /* 1b */
+ {0x0047,0x1e,0x17,0x00,0x3a,1280,1024,0x35c8}, /* 1c */
+ {0x0007,0x1f,0x98,0x00,0x3a,1280,1024,0x35cd}, /* 1d */
+ {0x0007,0x20,0x59,0x00,0x3c,1600,1200,0x35d4}, /* 1e - CRT1CRTC was 0x60 */
+ {0x0007,0x21,0x5a,0x00,0x3c,1600,1200,0x35d9}, /* 1f */
+ {0x0007,0x22,0x1b,0x00,0x3c,1600,1200,0x35de}, /* 20 */
+ {0x0007,0x23,0x1d,0x00,0x3c,1600,1200,0x35e3}, /* 21 - CRT1CRTC was 0x63 */
+ {0x0007,0x24,0x1e,0x00,0x3c,1600,1200,0x35e8}, /* 22 */
+ {0x407f,0x00,0x00,0x00,0x40, 320, 200,0x3516}, /* 23 */
+ {0xc07f,0x01,0x00,0x04,0x50, 320, 240,0x351d}, /* 24 */
+ {0x0077,0x02,0x04,0x05,0x51, 400, 300,0x3524}, /* 25 */
+ {0xc877,0x03,0x09,0x06,0x52, 512, 384,0x352b}, /* 26 */ /* was c077 */
+ {0x8207,0x25,0x1f,0x00,0x68,1920,1440,0x35ef}, /* 27 */
+ {0x0007,0x26,0x20,0x00,0x6c,2048,1536,0x35f6}, /* 28 */
+ {0x0027,0x27,0x14,0x08,0x6e,1280, 960,0x35b7}, /* 29 - TW: 1280x960-60 */
+ {0x0047,0x45,0x3c,0x08,0x6e,1280, 960,0x35b7}, /* 2a - TW: 1280x960-85 */
+ {0xc077,0x33,0x09,0x06,0x20,1024, 600,0x0000}, /* 2b */
+ {0xc077,0x34,0x0b,0x06,0x23,1152, 768,0x0000}, /* 2c */ /* VCLK 0x09 */
+ {0x0057,0x35,0x27,0x08,0x70, 800, 480,0x3b52}, /* 2d - TW: 16:9 modes */
+ {0x0047,0x36,0x37,0x08,0x70, 800, 480,0x3b57}, /* 2e */
+ {0x0047,0x37,0x08,0x08,0x70, 800, 480,0x3b5c}, /* 2f */
+ {0x0057,0x38,0x09,0x09,0x71,1024, 576,0x3b63}, /* 30 */
+ {0x0047,0x39,0x38,0x09,0x71,1024, 576,0x3b68}, /* 31 */
+ {0x0047,0x3a,0x11,0x09,0x71,1024, 576,0x3b6d}, /* 32 */
+ {0x0057,0x3b,0x39,0x0a,0x75,1280, 720,0x3b74}, /* 33 */
+ {0x0047,0x3c,0x3a,0x0a,0x75,1280, 720,0x3b79}, /* 34 */
+ {0x0047,0x3d,0x3b,0x0a,0x75,1280, 720,0x3b7e}, /* 35 - TW: END of 16:9 modes */
+ {0x0047,0x3e,0x34,0x06,0x29,1152, 864,0x0000}, /* 36 TW: 1152x864-75Hz - Non-BIOS, new */
+ {0x0047,0x44,0x3a,0x06,0x29,1152, 864,0x0000}, /* 37 TW: 1152x864-85Hz - Non-BIOS, new */
+ {0x00c7,0x3f,0x28,0x00,0x39, 848, 480,0x0000}, /* 38 TW: 848x480-38Hzi - Non-BIOS, new */
+ {0xc047,0x40,0x3d,0x00,0x39, 848, 480,0x0000}, /* 39 TW: 848x480-60Hz - Non-BIOS, new */
+ {0x00c7,0x41,0x28,0x00,0x3f, 856, 480,0x0000}, /* 3a TW: 856x480-38Hzi - Non-BIOS, new */
+ {0xc047,0x42,0x28,0x00,0x3f, 856, 480,0x0000}, /* 3b TW: 856x480-60Hz - Non-BIOS, new */
+ {0x0047,0x43,0x3e,0x00,0x48,1360, 768,0x0000}, /* 3c TW: 1360x768-60Hz - Non-BIOS, new */
+ {0xffff,0,0,0,0,0,0,0}
+};
+
+/*add for 300 oem util*/
+typedef struct _SiS_VBModeIDTableStruct
+{
+ UCHAR ModeID;
+ UCHAR VB_TVDelayIndex;
+ UCHAR VB_TVFlickerIndex;
+ UCHAR VB_TVPhaseIndex;
+ UCHAR VB_TVYFilterIndex;
+ UCHAR VB_LCDDelayIndex;
+ UCHAR _VB_LCDHIndex;
+ UCHAR _VB_LCDVIndex;
+}SiS_VBModeIDTableStruct;
+
+static const SiS_VBModeIDTableStruct SiS300_VBModeIDTable[] =
+{
+ {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01},
+ {0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x02},
+ {0x03,0x00,0x00,0x00,0x02,0x00,0x02,0x00},
+ {0x03,0x00,0x00,0x00,0x02,0x00,0x02,0x01},
+ {0x03,0x00,0x00,0x00,0x03,0x00,0x03,0x02},
+ {0x05,0x00,0x00,0x01,0x04,0x00,0x00,0x00},
+ {0x06,0x00,0x00,0x01,0x05,0x00,0x02,0x00},
+ {0x07,0x00,0x00,0x00,0x03,0x00,0x03,0x01},
+ {0x07,0x00,0x00,0x00,0x03,0x00,0x03,0x02},
+ {0x0d,0x00,0x00,0x01,0x04,0x00,0x00,0x00},
+ {0x0e,0x00,0x00,0x01,0x05,0x00,0x02,0x00},
+ {0x0f,0x00,0x00,0x01,0x05,0x00,0x02,0x01},
+ {0x10,0x00,0x00,0x01,0x05,0x00,0x02,0x01},
+ {0x11,0x00,0x00,0x01,0x05,0x00,0x02,0x03},
+ {0x12,0x00,0x00,0x01,0x05,0x00,0x02,0x03},
+ {0x13,0x00,0x00,0x01,0x04,0x00,0x04,0x00},
+ {0x6a,0x00,0x00,0x01,0x07,0x00,0x08,0x0a},
+ {0x2e,0x00,0x00,0x01,0x05,0x00,0x06,0x08},
+ {0x2f,0x00,0x00,0x01,0x05,0x00,0x06,0x06},
+ {0x30,0x00,0x00,0x01,0x07,0x00,0x08,0x0a},
+ {0x31,0x00,0x00,0x01,0x06,0x00,0x00,0x00},
+ {0x32,0x00,0x00,0x01,0x06,0x00,0x00,0x00},
+ {0x37,0x00,0x00,0x01,0x00,0x00,0x0a,0x0c},
+ {0x38,0x00,0x00,0x01,0x00,0x00,0x0a,0x0c},
+ {0x3a,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
+ {0x40,0x00,0x00,0x01,0x04,0x00,0x05,0x05},
+ {0x41,0x00,0x00,0x01,0x04,0x00,0x05,0x05},
+ {0x43,0x00,0x00,0x01,0x05,0x00,0x06,0x08},
+ {0x44,0x00,0x00,0x01,0x05,0x00,0x06,0x08},
+ {0x46,0x00,0x00,0x01,0x07,0x00,0x08,0x0a},
+ {0x47,0x00,0x00,0x01,0x07,0x00,0x08,0x0a},
+ {0x49,0x00,0x00,0x01,0x00,0x00,0x0a,0x0c},
+ {0x4a,0x00,0x00,0x01,0x00,0x00,0x0a,0x0c},
+ {0x4c,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
+ {0x4d,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
+ {0x50,0x00,0x00,0x01,0x04,0x00,0x05,0x07},
+ {0x51,0x00,0x00,0x01,0x07,0x00,0x07,0x09},
+ {0x52,0x00,0x00,0x01,0x00,0x00,0x09,0x0b},
+ {0x56,0x00,0x00,0x01,0x04,0x00,0x05,0x07},
+ {0x57,0x00,0x00,0x01,0x07,0x00,0x07,0x09},
+ {0x58,0x00,0x00,0x01,0x00,0x00,0x09,0x0b},
+ {0x59,0x00,0x00,0x01,0x04,0x00,0x05,0x05},
+ {0x5d,0x00,0x00,0x01,0x07,0x00,0x06,0x06},
+ {0x62,0x00,0x00,0x01,0x05,0x00,0x06,0x08},
+ {0x63,0x00,0x00,0x01,0x07,0x00,0x08,0x0a},
+ {0x64,0x00,0x00,0x01,0x00,0x00,0x0a,0x0c},
+ {0x65,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
+ {0x6e,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
+ {0x6f,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
+ {0x7b,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
+ {0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00} /* TW: added! */
+};
+/*end*/
+
+typedef struct _SiS300_CRT1TableStruct
+{
+ UCHAR CR[17];
+} SiS300_CRT1TableStruct;
+
+static const SiS300_CRT1TableStruct SiS300_CRT1Table[] =
+{
+ {{0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f, /* 0x00 */
+ 0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x00,
+ 0x00}},
+ {{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e,
+ 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00,
+ 0x00}},
+ {{0x3d,0x31,0x31,0x81,0x37,0x1f,0x72,0xf0,
+ 0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x05,
+ 0x01}},
+ {{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}},
+ {{0x64,0x4f,0x4f,0x88,0x55,0x9d,0xf2,0x1f,
+ 0xe0,0x83,0xdf,0xdf,0xf3,0x10,0x00,0x01,
+ 0x00}},
+ {{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}},
+ {{0x63,0x4f,0x4f,0x87,0x56,0x9d,0xfb,0x1f,
+ 0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x01,
+ 0x00}},
+ {{0x65,0x4f,0x4f,0x89,0x57,0x9f,0xfb,0x1f,
+ 0xe6,0x8a,0xdf,0xdf,0xfc,0x10,0x00,0x01, /* TW: Corrected VDE, VBE */
+ 0x00}},
+ {{0x7b,0x63,0x63,0x9f,0x6a,0x93,0x6f,0xf0,
+ 0x58,0x8a,0x57,0x57,0x70,0x20,0x00,0x05,
+ 0x01}},
+ {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xf0,
+ 0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x06,
+ 0x01}},
+ {{0x7d,0x63,0x63,0x81,0x6e,0x1d,0x98,0xf0,
+ 0x7c,0x82,0x57,0x57,0x99,0x00,0x00,0x06,
+ 0x01}},
+ {{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xf0,
+ 0x58,0x8b,0x57,0x57,0x70,0x20,0x00,0x06,
+ 0x01}},
+ {{0x7e,0x63,0x63,0x82,0x6b,0x13,0x75,0xf0,
+ 0x58,0x8b,0x57,0x57,0x76,0x20,0x00,0x06,
+ 0x01}},
+ {{0x8c,0x63,0x63,0x87,0x72,0x16,0x7e,0xf0,
+ 0x59,0x8d,0x57,0x57,0x7f,0x00,0x00,0x06,
+ 0x01}},
+ {{0x7e,0x63,0x63,0x82,0x6c,0x14,0x75,0xe0,
+ 0x58,0x0b,0x57,0x57,0x76,0x20,0x00,0x06,
+ 0x01}},
+ {{0x7e,0x63,0x63,0x82,0x6c,0x14,0x75,0xe0, /* 0x14 */
+ 0x58,0x0b,0x57,0x57,0x76,0x20,0x00,0x06,
+ 0x01}},
+ {{0x99,0x7f,0x7f,0x9d,0x84,0x1a,0x96,0x1f,
+ 0x7f,0x83,0x7f,0x7f,0x97,0x10,0x00,0x02,
+ 0x00}},
+ {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,
+ 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
+ 0x01}},
+ {{0xa1,0x7f,0x7f,0x85,0x86,0x97,0x24,0xf5,
+ 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
+ 0x01}},
+ {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf5,
+ 0x00,0x83,0xff,0xff,0x1f,0x10,0x00,0x02,
+ 0x01}},
+ {{0xa7,0x7f,0x7f,0x8b,0x89,0x95,0x26,0xf5,
+ 0x00,0x83,0xff,0xff,0x27,0x10,0x00,0x02,
+ 0x01}},
+ {{0x9f,0x7f,0x7f,0x83,0x83,0x93,0x1e,0xf5, /* 0x1a */
+ 0x00,0x84,0xff,0xff,0x1f,0x10,0x00,0x02,
+ 0x01}},
+ {{0xa2,0x7f,0x7f,0x86,0x84,0x94,0x37,0xf5,
+ 0x0b,0x82,0xff,0xff,0x38,0x10,0x00,0x02,
+ 0x01}},
+ {{0xcf,0x9f,0x9f,0x93,0xb2,0x01,0x14,0xba,
+ 0x00,0x83,0xff,0xff,0x15,0x00,0x00,0x03,
+ 0x00}},
+ {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0x5a,
+ 0x00,0x83,0xff,0xff,0x29,0x09,0x00,0x07,
+ 0x01}},
+ {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0x5a, /* 0x1e */
+ 0x00,0x83,0xff,0xff,0x29,0x09,0x00,0x07,
+ 0x01}},
+ {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0x5a,
+ 0x00,0x83,0xff,0xff,0x2f,0x09,0x00,0x07,
+ 0x01}},
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+ 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+ 0x00}},
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+ 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+ 0x00}},
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+ 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+ 0x00}},
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+ 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+ 0x00}},
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10, /* 36: 1600x1200x85Hz */
+ 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+ 0x00}},
+ {{0x3f,0xef,0xef,0x83,0xfd,0x1a,0xda,0x1f, /* 37: 1920x1440x60Hz */
+ 0xa0,0x84,0x9f,0x9f,0xdb,0x1f,0x01,0x01,
+ 0x00}},
+ {{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}},
+ {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xba, /* 0x28 */
+ 0x27,0x8b,0xdf,0xdf,0x73,0x00,0x00,0x06,
+ 0x01}},
+ {{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xba,
+ 0x26,0x89,0xdf,0xdf,0x6f,0x00,0x00,0x06,
+ 0x01}},
+ {{0x7f,0x63,0x63,0x82,0x6b,0x13,0x75,0xba,
+ 0x29,0x8c,0xdf,0xdf,0x75,0x00,0x00,0x06,
+ 0x01}},
+ {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf1,
+ 0xaf,0x85,0x3f,0x3f,0x25,0x30,0x00,0x02,
+ 0x01}},
+ {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf1,
+ 0xad,0x81,0x3f,0x3f,0x1f,0x30,0x00,0x02,
+ 0x01}},
+ {{0xa7,0x7f,0x7f,0x88,0x89,0x15,0x26,0xf1,
+ 0xb1,0x85,0x3f,0x3f,0x27,0x30,0x00,0x02,
+ 0x01}},
+ {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0xc4,
+ 0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07,
+ 0x01}},
+ {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0xd4,
+ 0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07,
+ 0x01}},
+ {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0xd4,
+ 0x7d,0x81,0xcf,0xcf,0x2f,0x21,0x00,0x07,
+ 0x01}},
+ {{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}},
+ {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x1e,0xf1, /* 0x33 - 1024x600 */
+ 0xae,0x85,0x57,0x57,0x1f,0x30,0x00,0x02,
+ 0x01}},
+#if 0
+ {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5, /* 0x34 - 1152x768 */
+ 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
+ 0x01}},
+#endif
+ {{0xa3,0x8f,0x8f,0x97,0x96,0x97,0x24,0xf5, /* 0x34 - 1152x768 - TW: corrected */
+ 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
+ 0x01}},
+ {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xba, /* 0x35 - NEW 16:9 modes, not in BIOS ------ */
+ 0x27,0x8b,0xdf,0xdf,0x73,0x00,0x00,0x06,
+ 0x01}}, /* 0x35 */
+ {{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xba,
+ 0x26,0x89,0xdf,0xdf,0x6f,0x00,0x00,0x06,
+ 0x01}}, /* 0x36 */
+ {{0x7f,0x63,0x63,0x82,0x6b,0x13,0x75,0xba,
+ 0x29,0x8c,0xdf,0xdf,0x75,0x00,0x00,0x06,
+ 0x01}}, /* 0x37 */
+ {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf1,
+ 0xaf,0x85,0x3f,0x3f,0x25,0x30,0x00,0x02,
+ 0x01}}, /* 0x38 */
+ {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf1,
+ 0xad,0x81,0x3f,0x3f,0x1f,0x30,0x00,0x02,
+ 0x01}}, /* 0x39 */
+ {{0xa7,0x7f,0x7f,0x88,0x89,0x95,0x26,0xf1, /* TW: 95 was 15 - illegal HBE! */
+ 0xb1,0x85,0x3f,0x3f,0x27,0x30,0x00,0x02,
+ 0x01}}, /* 0x3a */
+ {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0xc4,
+ 0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07,
+ 0x01}}, /* 0x3b */
+ {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0xd4,
+ 0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07,
+ 0x01}}, /* 0x3c */
+ {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0xd4,
+ 0x7d,0x81,0xcf,0xcf,0x2f,0x21,0x00,0x07,
+ 0x01}}, /* 0x3d */ /* TW: End of 16:9 modes --------------- */
+ {{0xc3,0x8f,0x8f,0x87,0x9b,0x0b,0x82,0xef, /* TW: New, 1152x864-75 (not in any BIOS) */
+ 0x60,0x83,0x5f,0x5f,0x83,0x10,0x00,0x07,
+ 0x01}}, /* 0x3e */
+ {{0x86,0x69,0x69,0x8A,0x74,0x06,0x8C,0x15, /* TW: New, 848x480-38i, not in BIOS */
+ 0x4F,0x83,0xEF,0xEF,0x8D,0x30,0x00,0x02,
+ 0x00}}, /* 0x3f */
+#if 0
+ {{0x81,0x69,0x69,0x85,0x70,0x00,0x0F,0x3E, /* TW: New, 848x480-60, not in BIOS - incorrect for Philips panel */
+ 0xEB,0x8E,0xDF,0xDF,0x10,0x00,0x00,0x02,
+ 0x00}}, /* 0x40 */
+#endif
+ {{0x83,0x69,0x69,0x87,0x6f,0x1d,0x03,0x3E, /* TW: New, 848x480-60, not in BIOS */
+ 0xE5,0x8d,0xDF,0xe4,0x04,0x00,0x00,0x06,
+ 0x00}}, /* 0x40 */
+ {{0x86,0x6A,0x6A,0x8A,0x74,0x06,0x8C,0x15, /* TW: New, 856x480-38i, not in BIOS */
+ 0x4F,0x83,0xEF,0xEF,0x8D,0x30,0x00,0x02,
+ 0x00}}, /* 0x41 */
+ {{0x81,0x6A,0x6A,0x85,0x70,0x00,0x0F,0x3E, /* TW: New, 856x480-60, not in BIOS */
+ 0xEB,0x8E,0xDF,0xDF,0x10,0x00,0x00,0x02,
+ 0x00}}, /* 0x42 */
+ {{0xdd,0xa9,0xa9,0x81,0xb4,0x97,0x26,0xfd, /* TW: New, 1360x768-60, not in BIOS */
+ 0x01,0x8d,0xff,0x00,0x27,0x10,0x00,0x03,
+ 0x01}}, /* 0x43 */
+ {{0xd9,0x8f,0x8f,0x9d,0xba,0x0a,0x8a,0xff, /* TW: New, 1152x864-84 (not in any BIOS) */
+ 0x60,0x8b,0x5f,0x5f,0x8b,0x10,0x00,0x03,
+ 0x01}}, /* 0x44 */
+ {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0xf1,0xff, /* TW: New, 1280x960-85 (not in any BIOS) */
+ 0xc0,0x83,0xbf,0xbf,0xf2,0x10,0x00,0x07,
+ 0x01}} /* 0x45 */
+};
+
+typedef struct _SiS300_MCLKDataStruct
+{
+ UCHAR SR28,SR29,SR2A;
+ USHORT CLOCK;
+} SiS300_MCLKDataStruct;
+
+static const SiS300_MCLKDataStruct SiS300_MCLKData_630[] = /* 630 */
+{ /* TW: at 0x54 in BIOS */
+ { 0x5a,0x64,0x80, 66},
+ { 0xb3,0x45,0x80, 83},
+ { 0x37,0x61,0x80,100},
+ { 0x37,0x22,0x80,133},
+ { 0x37,0x61,0x80,100},
+ { 0x37,0x61,0x80,100},
+ { 0x37,0x61,0x80,100},
+ { 0x37,0x61,0x80,100}
+};
+
+static const SiS300_MCLKDataStruct SiS300_MCLKData_300[] = /* 300 */
+{ /* TW: at 0x54 in BIOS */
+ { 0x68,0x43,0x80,125},
+ { 0x68,0x43,0x80,125},
+ { 0x68,0x43,0x80,125},
+ { 0x37,0x61,0x80,100},
+ { 0x37,0x61,0x80,100},
+ { 0x37,0x61,0x80,100},
+ { 0x37,0x61,0x80,100},
+ { 0x37,0x61,0x80,100}
+};
+
+typedef struct _SiS300_ECLKDataStruct
+{
+ UCHAR SR2E,SR2F,SR30;
+ USHORT CLOCK;
+} SiS300_ECLKDataStruct;
+
+static const SiS300_ECLKDataStruct SiS300_ECLKData[] =
+{
+ { 0x54,0x43,0x80,100},
+ { 0x53,0x43,0x80,100},
+ { 0x55,0x43,0x80,100},
+ { 0x52,0x43,0x80,100},
+ { 0x3f,0x42,0x80,100},
+ { 0x54,0x43,0x80,100},
+ { 0x54,0x43,0x80,100},
+ { 0x54,0x43,0x80,100}
+};
+
+typedef struct _SiS300_VCLKDataStruct
+{
+ UCHAR SR2B,SR2C;
+ USHORT CLOCK;
+} SiS300_VCLKDataStruct;
+
+static const SiS300_VCLKDataStruct SiS300_VCLKData[] =
+{
+ { 0x1b,0xe1, 25}, /* 0x00 */
+ { 0x4e,0xe4, 28},
+ { 0x57,0xe4, 32}, /* 0x02 */
+ { 0xc3,0xc8, 36},
+ { 0x42,0xc3, 40}, /* 0x04 */
+ { 0x5d,0xc4, 45},
+ { 0x52,0x65, 50}, /* 0x06 */
+ { 0x53,0x65, 50},
+ { 0x6d,0x66, 56}, /* 0x08 */
+ { 0x5a,0x64, 65},
+ { 0x46,0x44, 68}, /* 0x0a */
+ { 0x3e,0x43, 75},
+ { 0x6d,0x46, 76}, /* 0x0c: 800x600 | LVDS_2(CH), MITAC(CH); - 730, A901(301B): 0xb1,0x46, 76 */
+ { 0x41,0x43, 79},
+ { 0x31,0x42, 79}, /* 0x0e */
+ { 0x46,0x25, 85},
+ { 0x78,0x29, 87}, /* 0x10 */
+ { 0x62,0x44, 95},
+ { 0x2b,0x22,105}, /* 0x12 */
+ { 0x49,0x24,106},
+ { 0xc3,0x28,108}, /* 0x14 */
+ { 0x3c,0x23,109},
+ { 0xf7,0x2c,132}, /* 0x16 */
+ { 0xd4,0x28,136},
+ { 0x41,0x05,158}, /* 0x18 */
+ { 0x43,0x05,162},
+ { 0xe1,0x0f,175}, /* 0x1a */
+ { 0xfc,0x12,189}, /* 0x1b */
+ { 0xde,0x26,194}, /* 0x1c */
+ { 0x54,0x05,203},
+ { 0x3f,0x03,230}, /* 0x1e */
+ { 0x30,0x02,234},
+ { 0x24,0x01,266}, /* 0x20 */
+ { 0x52,0x2a, 54}, /* 301 TV */
+ { 0x52,0x6a, 27}, /* 301 TV */
+ { 0x62,0x24, 70}, /* 301 TV */
+ { 0x62,0x64, 70}, /* 301 TV */
+ { 0xa8,0x4c, 30}, /* 301 TV */
+ { 0x20,0x26, 33}, /* 301 TV */
+ { 0x31,0xc2, 39},
+ { 0xbf,0xc8, 35}, /* 0x28 - 856x480 */
+ { 0x60,0x36, 30}, /* 0x29 CH/UNTSC TEXT | LVDS_2(CH) - 730, A901(301B), Mitac(CH): 0xe0, 0xb6, 30 */
+ { 0x40,0x4a, 28},
+ { 0x9f,0x46, 44},
+ { 0x97,0x2c, 26},
+ { 0x44,0xe4, 25},
+ { 0x7e,0x32, 47},
+ { 0x8a,0x24, 31}, /* 0x2f CH/PAL TEXT | LVDS_2(CH), Mitac(CH) - 730, A901(301B): 0x57, 0xe4, 31 */
+ { 0x97,0x2c, 26},
+ { 0xce,0x3c, 39},
+ { 0x52,0x4a, 36}, /* 0x32 CH/PAL 800x600 5/6 */
+ { 0x34,0x61, 95},
+ { 0x78,0x27,108},
+ { 0xce,0x25,189}, /* 0x35 */
+ { 0x45,0x6b, 21}, /* 0x36 */ /* TW: Added from Mitac */
+ { 0x52,0xe2, 49}, /* 0x37 - added for 16:9 modes (not in any BIOS) */
+ { 0x2b,0x61, 78}, /* 0x38 - added for 16:9 modes (not in any BIOS) */
+ { 0x70,0x44,108}, /* 0x39 - added for 16:9 modes (not in any BIOS) */
+ { 0x54,0x42,135}, /* 0x3a - added for 16:9 modes (not in any BIOS) */
+ { 0x41,0x22,157}, /* 0x3b - added for 16:9 modes (not in any BIOS) */
+ { 0x52,0x07,149}, /* 0x3c - added for 1280x960-85 (not in any BIOS)*/
+ { 0x62,0xc6, 34}, /* 0x3d - added for 848x480-60 (not in any BIOS) */
+ { 0x30,0x23, 88}, /* 0x3e - added for 1360x768-60 (not in any BIOS)*/
+ { 0x3f,0x64, 46}, /* 0x3f - added for 640x480-100 (not in any BIOS)*/
+ { 0x72,0x2a, 76}, /* 0x40 - test for SiS730 */
+ { 0x15,0x21, 79}, /* 0x41 - test for SiS730 */
+ { 0xff,0x00, 0}
+};
+
+#if 0 /* TW: This table is in all BIOSes, but not used */
+static const SiS300_VCLKDataStruct SiS300_VBVCLKData[] =
+{
+ { 0x1b,0xe1, 25},
+ { 0x4e,0xe4, 28},
+ { 0x57,0xe4, 31},
+ { 0xc3,0xc8, 36},
+ { 0x42,0x47, 40},
+ { 0x5d,0xc4, 44},
+ { 0x52,0x47, 49},
+ { 0x53,0x47, 50},
+ { 0x6d,0x66, 56},
+ { 0x5a,0x64, 65},
+ { 0x46,0x44, 67},
+ { 0x29,0x61, 75},
+ { 0x6d,0x46, 75},
+ { 0x41,0x43, 78},
+ { 0x31,0x42, 79},
+ { 0x46,0x25, 84},
+ { 0x78,0x29, 86}, /* 0x10 */
+ { 0x62,0x44, 94},
+ { 0x2b,0x22,104},
+ { 0x49,0x24,105},
+ { 0x43,0x42,108},
+ { 0x3c,0x23,109},
+ { 0xe0,0x46,132},
+ { 0x70,0x25,135},
+ { 0x41,0x22,157},
+ { 0x43,0x22,162},
+ { 0x30,0x21,175},
+ { 0xc1,0x24,189},
+ { 0xde,0x26,194},
+ { 0x70,0x07,202},
+ { 0x3f,0x03,229},
+ { 0x30,0x02,234}, /* 0x1f */
+ { 0x24,0x01,265}, /* 0x20 */
+ { 0x52,0x2a, 54},
+ { 0x52,0x6a, 27},
+ { 0x62,0x24, 70},
+ { 0x62,0x64, 70},
+ { 0xa8,0x4c, 30},
+ { 0x20,0x26, 33},
+ { 0x31,0xc2, 39},
+ { 0x2e,0x48, 25}, /* 0x28 */
+ { 0x24,0x46, 25}, /* 0x29 */
+ { 0x26,0x64, 28},
+ { 0x37,0x64, 40},
+ { 0xa1,0x42,108},
+ { 0x37,0x61,100},
+ { 0x78,0x27,108},
+ { 0xff,0x00, 0}
+};
+#endif
+
+static const UCHAR SiS300_ScreenOffset[] =
+{
+ 0x14,0x19,0x20,0x28,0x32,0x40,0x50,
+ 0x64,0x78,0x80,0x2d,0x35,0x48,0x35, /* 0x35 for 848 and 856 */
+ 0x55,0xff /* 0x55 for 1360 */
+};
+
+typedef struct _SiS300_StResInfoStruct
+{
+ USHORT HTotal;
+ USHORT VTotal;
+} SiS300_StResInfoStruct;
+
+static const SiS300_StResInfoStruct SiS300_StResInfo[] =
+{
+ { 640,400},
+ { 640,350},
+ { 720,400},
+ { 720,350},
+ { 640,480}
+};
+
+typedef struct _SiS300_ModeResInfoStruct
+{
+ USHORT HTotal;
+ USHORT VTotal;
+ UCHAR XChar;
+ UCHAR YChar;
+} SiS300_ModeResInfoStruct;
+
+static const SiS300_ModeResInfoStruct SiS300_ModeResInfo[] =
+{
+ { 320, 200, 8, 8}, /* 0x00 */
+ { 320, 240, 8, 8}, /* 0x01 */
+ { 320, 400, 8, 8}, /* 0x02 */
+ { 400, 300, 8, 8}, /* 0x03 */
+ { 512, 384, 8, 8}, /* 0x04 */
+ { 640, 400, 8,16}, /* 0x05 */
+ { 640, 480, 8,16}, /* 0x06 */
+ { 800, 600, 8,16}, /* 0x07 */
+ { 1024, 768, 8,16}, /* 0x08 */
+ { 1280,1024, 8,16}, /* 0x09 */
+ { 1600,1200, 8,16}, /* 0x0a */
+ { 1920,1440, 8,16}, /* 0x0b */
+ { 720, 480, 8,16}, /* 0x0c */
+ { 720, 576, 8,16}, /* 0x0d */
+ { 1280, 960, 8,16}, /* 0x0e */
+ { 1024, 600, 8,16}, /* 0x0f */
+ { 1152, 768, 8,16}, /* 0x10 */
+ { 2048,1536, 8,16}, /* 0x11 - TW: Not in BIOS! */
+ { 800, 480, 8,16}, /* 0x12 - TW: New, not in any BIOS */
+ { 1024, 576, 8,16}, /* 0x13 - TW: New, not in any BIOS */
+ { 1280, 720, 8,16}, /* 0x14 - TW: New, not in any BIOS */
+ { 1152, 864, 8,16}, /* 0x15 - TW: New, not in any BIOS */
+ { 848, 480, 8,16}, /* 0x16 - TW: New, not in any BIOS */
+ { 856, 480, 8,16}, /* 0x17 - TW: New, not in any BIOS */
+ { 1360, 768, 8,16} /* 0x18 - TW: New, not in any BIOS */
+};
+
+static const UCHAR SiS300_OutputSelect = 0x40;
+
+static const UCHAR SiS300_SoftSetting = 0x30;
+
+#ifndef LINUX_XF86
+static UCHAR SiS300_SR07 = 0x10;
+#endif
+
+static const UCHAR SiS300_SR15[8][4] =
+{
+ {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}
+};
+
+#ifndef LINUX_XF86
+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; /*301b*/
+static const USHORT SiS300_VideoSenseData2 = 0x0174;
+static const USHORT SiS300_YCSenseData2 = 0x016b;
+
+static const UCHAR SiS300_CR40[5][4];
+
+static UCHAR SiS300_CR49[2];
+#endif
+
+static const UCHAR SiS300_NTSCPhase[] = {0x21,0xed,0xba,0x08}; /* TW: Was {0x21,0xed,0x8a,0x08}; */
+static const UCHAR SiS300_PALPhase[] = {0x2a,0x05,0xe3,0x00}; /* TW: Was {0x2a,0x05,0xd3,0x00}; */
+static const UCHAR SiS300_PALMPhase[] = {0x21,0xE4,0x2E,0x9B}; /* palmn */
+static const UCHAR SiS300_PALNPhase[] = {0x21,0xF4,0x3E,0xBA};
+static const UCHAR SiS300_NTSCPhase2[] = {0x21,0xF0,0x7B,0xD6}; /* 301b */
+static const UCHAR SiS300_PALPhase2[] = {0x2a,0x09,0x86,0xe9}; /* 301b */
+static const UCHAR SiS300_PALMPhase2[] = {0x21,0xE6,0xEF,0xA4}; /* TW: palm 301b*/
+static const UCHAR SiS300_PALNPhase2[] = {0x21,0xF6,0x94,0x46}; /* TW: paln 301b*/
+
+typedef struct _SiS300_PanelDelayTblStruct
+{
+ UCHAR timer[2];
+} SiS300_PanelDelayTblStruct;
+
+static const SiS300_PanelDelayTblStruct SiS300_PanelDelayTbl[] =
+{
+ {{0x05,0xaa}}, /* TW: From 2.04.5a */
+ {{0x05,0x14}},
+ {{0x05,0x36}},
+ {{0x05,0x14}},
+ {{0x05,0x14}},
+ {{0x05,0x14}},
+ {{0x05,0x90}},
+ {{0x05,0x90}},
+ {{0x05,0x14}},
+ {{0x05,0x14}},
+ {{0x05,0x14}},
+ {{0x05,0x14}},
+ {{0x20,0x80}},
+ {{0x05,0x14}},
+ {{0x05,0x40}},
+ {{0x05,0x60}}
+};
+
+static const SiS300_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}}
+};
+
+typedef struct _SiS300_LCDDataStruct
+{
+ USHORT RVBHCMAX;
+ USHORT RVBHCFACT;
+ USHORT VGAHT;
+ USHORT VGAVT;
+ USHORT LCDHT;
+ USHORT LCDVT;
+} SiS300_LCDDataStruct;
+
+static const SiS300_LCDDataStruct SiS300_StLCD1024x768Data[] =
+{
+ { 66, 31, 992, 510,1320, 816},
+ { 66, 31, 992, 510,1320, 816},
+ { 176, 75, 900, 510,1320, 816},
+ { 176, 75, 900, 510,1320, 816},
+ { 66, 31, 992, 510,1320, 816},
+ { 27, 16,1024, 650,1350, 832},
+ { 1, 1,1344, 806,1344, 806}
+};
+
+static const SiS300_LCDDataStruct SiS300_ExtLCD1024x768Data[] =
+{
+ { 12, 5, 896, 512,1344, 806},
+ { 12, 5, 896, 510,1344, 806},
+ { 32, 15,1008, 505,1344, 806},
+ { 32, 15,1008, 514,1344, 806},
+ { 12, 5, 896, 500,1344, 806},
+ { 42, 25,1024, 625,1344, 806},
+ { 1, 1,1344, 806,1344, 806},
+ { 12, 5, 896, 500,1344, 806},
+ { 42, 25,1024, 625,1344, 806},
+ { 1, 1,1344, 806,1344, 806},
+ { 12, 5, 896, 500,1344, 806},
+ { 42, 25,1024, 625,1344, 806},
+ { 1, 1,1344, 806,1344, 806}
+};
+
+static const SiS300_LCDDataStruct SiS300_St2LCD1024x768Data[] =
+{
+ { 62, 25, 800, 546,1344, 806},
+ { 32, 15, 930, 546,1344, 806},
+ { 32, 15, 930, 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 SiS300_LCDDataStruct SiS300_StLCD1280x1024Data[] =
+{
+ { 4, 1, 880, 510,1650,1088},
+ { 4, 1, 880, 510,1650,1088},
+ { 176, 45, 900, 510,1650,1088},
+ { 176, 45, 900, 510,1650,1088},
+ { 4, 1, 880, 510,1650,1088},
+ { 13, 5,1024, 675,1560,1152},
+ { 16, 9,1266, 804,1688,1072},
+ { 1, 1,1688,1066,1688,1066}
+};
+
+static const SiS300_LCDDataStruct SiS300_ExtLCD1280x1024Data[] =
+{
+ { 211, 60,1024, 501,1688,1066},
+ { 211, 60,1024, 508,1688,1066},
+ { 211, 60,1024, 501,1688,1066},
+ { 211, 60,1024, 508,1688,1066},
+ { 211, 60,1024, 500,1688,1066},
+ { 211, 75,1024, 625,1688,1066},
+ { 211, 120,1280, 798,1688,1066},
+ { 1, 1,1688,1066,1688,1066}
+};
+
+static const SiS300_LCDDataStruct SiS300_St2LCD1280x1024Data[] =
+{
+ { 22, 5, 800, 510,1650,1088},
+ { 22, 5, 800, 510,1650,1088},
+ { 176, 45, 900, 510,1650,1088},
+ { 176, 45, 900, 510,1650,1088},
+ { 22, 5, 800, 510,1650,1088},
+ { 13, 5,1024, 675,1560,1152},
+ { 16, 9,1266, 804,1688,1072},
+ { 1, 1,1688,1066,1688,1066}
+};
+
+static const SiS300_LCDDataStruct SiS300_NoScaleData1024x768[] =
+{
+ { 1, 1, 800, 449, 800, 449},
+ { 1, 1, 800, 449, 800, 449},
+ { 1, 1, 900, 449, 900, 449},
+ { 1, 1, 900, 449, 900, 449},
+ { 1, 1, 800, 525, 800, 525},
+ { 1, 1,1056, 628,1056, 628},
+ { 1, 1,1344, 806,1344, 806},
+ { 1, 1,1688,1066,1688,1066}
+};
+
+static const SiS300_LCDDataStruct SiS300_NoScaleData1280x1024[] = /* TW: Fake */
+{
+ { 1, 1, 800, 449, 800, 449},
+ { 1, 1, 800, 449, 800, 449},
+ { 1, 1, 900, 449, 900, 449},
+ { 1, 1, 900, 449, 900, 449},
+ { 1, 1, 800, 525, 800, 525},
+ { 1, 1,1056, 628,1056, 628},
+ { 1, 1,1344, 806,1344, 806},
+ { 1, 1,1688,1066,1688,1066}
+};
+
+static const SiS300_LCDDataStruct SiS300_LCD1280x960Data[] =
+{
+ { 9, 2, 800, 500,1800,1000},
+ { 9, 2, 800, 500,1800,1000},
+ { 4, 1, 900, 500,1800,1000},
+ { 4, 1, 900, 500,1800,1000},
+ { 9, 2, 800, 500,1800,1000},
+ { 30, 11,1056, 625,1800,1000},
+ { 5, 3,1350, 800,1800,1000},
+ { 1, 1,1576,1050,1576,1050},
+ { 1, 1,1800,1000,1800,1000}
+};
+
+static const SiS300_LCDDataStruct SiS300_ExtLCD1400x1050Data[] = /* TW: New */
+{
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0}
+};
+
+static const SiS300_LCDDataStruct SiS300_ExtLCD1600x1200Data[] = /* TW: New */
+{
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0}
+};
+
+static const SiS300_LCDDataStruct SiS300_StLCD1400x1050Data[] = /* TW: New */
+{
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0}
+};
+
+static const SiS300_LCDDataStruct SiS300_StLCD1600x1200Data[] = /* TW: New */
+{
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0}
+};
+
+static const SiS300_LCDDataStruct SiS300_NoScaleData1400x1050[] = /* TW: New */
+{
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0}
+};
+
+static const SiS300_LCDDataStruct SiS300_NoScaleData1600x1200[] = /* TW: New */
+{
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0}
+};
+
+
+typedef struct _SiS300_TVDataStruct
+{
+ USHORT RVBHCMAX;
+ USHORT RVBHCFACT;
+ USHORT VGAHT;
+ USHORT VGAVT;
+ USHORT TVHDE;
+ USHORT TVVDE;
+ USHORT RVBHRS;
+ UCHAR FlickerMode;
+ USHORT HALFRVBHRS;
+ UCHAR RY1COE;
+ UCHAR RY2COE;
+ UCHAR RY3COE;
+ UCHAR RY4COE;
+} SiS300_TVDataStruct;
+
+static const SiS300_TVDataStruct SiS300_StPALData[] =
+{
+ { 1, 1, 864, 525,1270, 400, 100, 0, 760,0xf4,0xff,0x1c,0x22},
+ { 1, 1, 864, 525,1270, 350, 100, 0, 760,0xf4,0xff,0x1c,0x22},
+ { 1, 1, 864, 525,1270, 400, 0, 0, 720,0xf1,0x04,0x1f,0x18},
+ { 1, 1, 864, 525,1270, 350, 0, 0, 720,0xf4,0x0b,0x1c,0x0a},
+ { 1, 1, 864, 525,1270, 480, 50, 0, 760,0xf4,0xff,0x1c,0x22},
+ { 1, 1, 864, 525,1270, 600, 50, 0, 0,0xf4,0xff,0x1c,0x22}
+};
+
+static const SiS300_TVDataStruct SiS300_ExtPALData[] =
+{
+ { 27, 10, 848, 448,1270, 530, 50, 0, 50,0xf4,0xff,0x1c,0x22},
+ { 108, 35, 848, 398,1270, 530, 50, 0, 50,0xf4,0xff,0x1c,0x22},
+ { 12, 5, 954, 448,1270, 530, 50, 0, 50,0xf1,0x04,0x1f,0x18},
+ { 9, 4, 960, 463,1644, 438, 50, 0, 50,0xf4,0x0b,0x1c,0x0a},
+ { 9, 4, 848, 528,1270, 530, 0, 0, 50,0xf5,0xfb,0x1b,0x2a},
+ { 36, 25,1060, 648,1316, 530, 438, 0, 438,0xeb,0x05,0x25,0x16},
+ { 3, 2,1080, 619,1270, 540, 438, 0, 438,0xf3,0x00,0x1d,0x20},
+ { 1, 1,1170, 821,1270, 520, 686, 0, 686,0xF3,0x00,0x1D,0x20}
+
+};
+
+static const SiS300_TVDataStruct SiS300_StNTSCData[] =
+{
+ { 1, 1, 858, 525,1270, 400, 50, 0, 760,0xf1,0x04,0x1f,0x18},
+ { 1, 1, 858, 525,1270, 350, 50, 0, 640,0xf1,0x04,0x1f,0x18},
+ { 1, 1, 858, 525,1270, 400, 0, 0, 720,0xf1,0x04,0x1f,0x18},
+ { 1, 1, 858, 525,1270, 350, 0, 0, 720,0xf4,0x0b,0x1c,0x0a},
+ { 1, 1, 858, 525,1270, 480, 0, 0, 760,0xf1,0x04,0x1f,0x18}
+};
+
+static const SiS300_TVDataStruct SiS300_ExtNTSCData[] =
+{
+ { 143, 65, 858, 443,1270, 440, 171, 0, 171,0xf1,0x04,0x1f,0x18},
+ { 88, 35, 858, 393,1270, 440, 171, 0, 171,0xf1,0x04,0x1f,0x18},
+ { 143, 70, 924, 443,1270, 440, 92, 0, 92,0xf1,0x04,0x1f,0x18},
+ { 143, 70, 924, 393,1270, 440, 92, 0, 92,0xf4,0x0b,0x1c,0x0a},
+ { 143, 76, 836, 523,1270, 440, 224, 0, 0,0xf1,0x05,0x1f,0x16},
+ { 143, 120,1056, 643,1270, 440, 0, 128, 0,0xf4,0x10,0x1c,0x00},
+ { 143, 76, 836, 523,1270, 440, 0, 128, 0,0xee,0x0c,0x22,0x08},
+ { 65, 64,1056, 791,1270, 480, 638, 0, 0,0xf1,0x04,0x1f,0x18}
+};
+
+static const SiS_TVDataStruct SiS300_St1HiTVData[] =
+{
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
+};
+
+static const SiS_TVDataStruct SiS300_St2HiTVData[] =
+{
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
+};
+
+static const SiS_TVDataStruct SiS300_ExtHiTVData[] =
+{
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
+};
+
+static const UCHAR SiS300_NTSCTiming[] =
+{
+ 0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c,
+ 0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a,
+ 0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x1b,
+ 0x0c,0x50,0x00,0x97,0x00,0xda,0x4a,0x17, /* (in 2.06.50) */
+/* 0x0c,0x50,0x00,0x99,0x00,0xec,0x4a,0x17, (in 2.04.5a) */
+ 0x7d,0x05,0x4b,0x00,0x00,0xe2,0x00,0x02, /* (in 2.06.50) */
+/* 0x88,0x00,0x4b,0x00,0x00,0xe2,0x00,0x02, (in 2.04.5a) */
+ 0x03,0x0a,0x65,0x9d,0x08,0x92,0x8f,0x40,
+ 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x50,
+ 0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00
+};
+
+static const UCHAR SiS300_PALTiming[] =
+{
+ 0x19,0x52,0x35,0x6e,0x04,0x38,0x3d,0x70,
+ 0x94,0x49,0x01,0x12,0x06,0x3e,0x35,0x6d,
+ 0x06,0x14,0x3e,0x35,0x6d,0x00,0x45,0x2b,
+ 0x70,0x50,0x00,0x9b,0x00,0xd9,0x5d,0x17, /* (in 2.06.50) */
+/* 0x70,0x50,0x00,0x97,0x00,0xd7,0x5d,0x17, (in 2.04.5a) */
+ 0x7d,0x05,0x45,0x00,0x00,0xe8,0x00,0x02, /* (in 2.06.50) */
+/* 0x88,0x00,0x45,0x00,0x00,0xe8,0x00,0x02, (in 2.04.5a) */
+ 0x0d,0x00,0x68,0xb0,0x0b,0x92,0x8f,0x40,
+ 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x63,
+ 0x00,0x40,0x3e,0x00,0xe1,0x02,0x28,0x00
+};
+
+#ifdef oldHV
+static const UCHAR SiS300_HiTVExtTiming[] = /* TW: New */
+{
+ 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
+ 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
+ 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
+ 0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13,
+ 0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40,
+ 0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40,
+ 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d,
+ 0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00
+};
+
+static const UCHAR SiS300_HiTVSt1Timing[] = /* TW: New */
+{
+ 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
+ 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
+ 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
+ 0x65,0x90,0x7b,0xa8,0x03,0xf0,0x87,0x03,
+ 0x11,0x15,0x11,0xcf,0x10,0x11,0xcf,0x10,
+ 0x35,0x35,0x3b,0x69,0x1d,0x92,0x0f,0x40,
+ 0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x86,
+ 0xaf,0x5d,0x0e,0x00,0xfc,0xff,0x2d,0x00
+};
+
+static const UCHAR SiS300_HiTVSt2Timing[] = /* TW: New */
+{
+ 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
+ 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
+ 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
+ 0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13,
+ 0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40,
+ 0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40,
+ 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d,
+ 0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00
+};
+
+static const UCHAR SiS300_HiTVTextTiming[] = /* TW: New */
+{
+ 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
+ 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
+ 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
+ 0x65,0x90,0xe7,0xbc,0x03,0x0c,0x97,0x03,
+ 0x14,0x78,0x14,0x08,0x20,0x14,0x08,0x20,
+ 0xc8,0xc8,0x3b,0xd2,0x26,0x92,0x0f,0x40,
+ 0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x96,
+ 0x72,0x5c,0x11,0x00,0xfc,0xff,0x32,0x00
+};
+
+static const UCHAR SiS300_HiTVGroup3Data[] = /* TW: New */
+{
+ 0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x5f,
+ 0x05,0x21,0xb2,0xb2,0x55,0x77,0x2a,0xa6,
+ 0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
+ 0x8c,0x6e,0x60,0x2e,0x58,0x48,0x72,0x44,
+ 0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
+ 0x4f,0x7f,0x03,0xa8,0x7d,0x20,0x1a,0xa9,
+ 0x14,0x05,0x03,0x7e,0x64,0x31,0x14,0x75,
+ 0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
+};
+
+static const UCHAR SiS300_HiTVGroup3Simu[] = /* TW: New */
+{
+ 0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x95,
+ 0xdb,0x20,0xb8,0xb8,0x55,0x47,0x2a,0xa6,
+ 0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
+ 0x8c,0x6e,0x60,0x15,0x26,0xd3,0xe4,0x11,
+ 0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
+ 0x67,0x36,0x01,0x47,0x0e,0x10,0xbe,0xb4,
+ 0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75,
+ 0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
+};
+
+static const UCHAR SiS300_HiTVGroup3Text[] = /* TW: New */
+{
+ 0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0xa7,
+ 0xf5,0x20,0xce,0xce,0x55,0x47,0x2a,0xa6,
+ 0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
+ 0x8c,0x6e,0x60,0x18,0x2c,0x0c,0x20,0x22,
+ 0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
+ 0x93,0x3c,0x01,0x50,0x2f,0x10,0xf4,0xca,
+ 0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75,
+ 0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
+};
+#endif
+
+typedef struct _SiS300_LVDSDataStruct
+{
+ USHORT VGAHT;
+ USHORT VGAVT;
+ USHORT LCDHT;
+ USHORT LCDVT;
+} SiS300_LVDSDataStruct;
+
+static const SiS300_LVDSDataStruct SiS300_LVDS320x480Data_1[] =
+{
+ {848, 433,400, 525},
+ {848, 389,400, 525},
+ {848, 433,400, 525},
+ {848, 389,400, 525},
+ {848, 518,400, 525},
+ {1056,628,400, 525},
+ {400, 525,400, 525},
+ {800, 449,1000, 644},
+ {800, 525,1000, 635}
+};
+
+static const SiS300_LVDSDataStruct SiS300_LVDS800x600Data_1[] =
+{
+ {848, 433,1060, 629},
+ {848, 389,1060, 629},
+ {848, 433,1060, 629},
+ {848, 389,1060, 629},
+ {848, 518,1060, 629},
+ {1056, 628,1056, 628},
+ {1056, 628,1056, 628},
+ {800, 449,1000, 644},
+ {800, 525,1000, 635}
+};
+
+static const SiS300_LVDSDataStruct SiS300_LVDS800x600Data_2[] =
+{
+ {1056, 628,1056, 628},
+ {1056, 628,1056, 628},
+ {1056, 628,1056, 628},
+ {1056, 628,1056, 628},
+ {1056, 628,1056, 628},
+ {1056, 628,1056, 628},
+ {1056, 628,1056, 628},
+ {800, 449,1000, 644},
+ {800, 525,1000, 635}
+};
+
+static const SiS300_LVDSDataStruct SiS300_LVDS1024x768Data_1[] =
+{
+ {840, 438,1344, 806},
+ {840, 409,1344, 806},
+ {840, 438,1344, 806},
+ {840, 409,1344, 806},
+ {840, 518,1344, 806},
+ {1050, 638,1344, 806},
+ {1344, 806,1344, 806},
+ {800, 449,1280, 801},
+ {800, 525,1280, 813}
+};
+
+static const SiS300_LVDSDataStruct SiS300_LVDS1024x768Data_2[] =
+{
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {800, 449,1280, 801},
+ {800, 525,1280, 813}
+};
+
+static const SiS300_LVDSDataStruct SiS300_LVDS1280x1024Data_1[] =
+{
+ {840, 438,1344, 806},
+ {840, 409,1344, 806},
+ {840, 438,1344, 806},
+ {840, 409,1344, 806},
+ {840, 518,1344, 806},
+ {1050, 638,1344, 806},
+ {1344, 806,1344, 806},
+ {800, 449,1280, 801},
+ {800, 525,1280, 813}
+};
+
+static const SiS300_LVDSDataStruct SiS300_LVDS1280x1024Data_2[] =
+{
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {800, 449,1280, 801},
+ {800, 525,1280, 813}
+};
+
+static const SiS300_LVDSDataStruct SiS300_LVDS1400x1050Data_1[] = /* TW: New */
+{
+ {928, 416, 1688, 1066},
+ {928, 366, 1688, 1066},
+ {928, 416, 1688, 1066},
+ {928, 366, 1688, 1066},
+ {928, 496, 1688, 1066},
+ {1088, 616, 1688, 1066},
+ {1312, 784, 1688, 1066},
+ {1568, 1040, 1688, 1066},
+ {1688, 1066, 1688, 1066}
+};
+
+static const SiS300_LVDSDataStruct SiS300_LVDS1400x1050Data_2[] = /* TW: New */
+{
+ {1688,1066, 1688,1066},
+ {1688,1066, 1688,1066},
+ {1688,1066, 1688,1066},
+ {1688,1066, 1688,1066},
+ {1688,1066, 1688,1066},
+ {1688,1066, 1688,1066},
+ {1688,1066, 1688,1066},
+ {1688,1066, 1688,1066},
+ {1688,1066, 1688,1066},
+};
+
+static const SiS300_LVDSDataStruct SiS300_LVDS1280x768Data_1[]= /* TW: New - TODO */
+{ /* TW: Temp data, invalid (is identical to 1024x768) */
+ {840, 438,1344, 806},
+ {840, 409,1344, 806},
+ {840, 438,1344, 806},
+ {840, 409,1344, 806},
+ {840, 518,1344, 806},
+ {1050, 638,1344, 806},
+ {1344, 806,1344, 806},
+ {800, 449,1280, 801},
+ {800, 525,1280, 813}
+};
+
+static const SiS300_LVDSDataStruct SiS300_LVDS1280x768Data_2[]= /* TW: New - TODO */
+{ /* TW: Temp data, invalid (is identical to 1024x768) */
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {800, 449,1280, 801},
+ {800, 525,1280, 813}
+};
+
+/* TW: New: */
+static const SiS300_LVDSDataStruct SiS300_LVDS1024x600Data_1[] =
+{
+ {840, 604,1344, 800},
+ {840, 560,1344, 800},
+ {840, 604,1344, 800},
+ {840, 560,1344, 800},
+ {840, 689,1344, 800},
+ {1050, 800,1344, 800},
+ {1344, 800,1344, 800},
+ {800, 449,1280, 789},
+ {800, 525,1280, 785}
+};
+
+/* TW: New: */
+static const SiS300_LVDSDataStruct SiS300_LVDS1024x600Data_2[] =
+{
+ {1344, 800,1344, 800},
+ {1344, 800,1344, 800},
+ {1344, 800,1344, 800},
+ {1344, 800,1344, 800},
+ {1344, 800,1344, 800},
+ {1344, 800,1344, 800},
+ {1344, 800,1344, 800},
+ {800, 449,1280, 801},
+ {800, 525,1280, 813}
+};
+
+/* TW: New: */
+static const SiS300_LVDSDataStruct SiS300_LVDS1152x768Data_1[] =
+{
+ {840, 438,1344, 806},
+ {840, 409,1344, 806},
+ {840, 438,1344, 806},
+ {840, 409,1344, 806},
+ {840, 518,1344, 806},
+ {1050, 638,1344, 806},
+ {1344, 806,1344, 806},
+ {800, 449,1280, 801},
+ {800, 525,1280, 813}
+};
+
+/* TW: New: */
+static const SiS300_LVDSDataStruct SiS300_LVDS1152x768Data_2[] =
+{
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {800, 449,1280, 801},
+ {800, 525,1280, 813}
+};
+
+/* TW: New in 650/LVDS BIOS - 1:1 */
+static const SiS300_LVDSDataStruct SiS300_LVDSXXXxXXXData_1[] = /* TW: New */
+{
+ { 800, 449, 800, 449},
+ { 800, 449, 800, 449},
+ { 900, 449, 900, 449},
+ { 900, 449, 900, 449},
+ { 800, 525, 800, 525},
+ {1056, 628,1056, 628},
+ {1344, 806,1344, 806},
+ {1688, 806,1688, 806}
+};
+
+static const SiS300_LVDSDataStruct SiS300_LVDS640x480Data_1[] =
+{
+ {800, 449, 800, 449},
+ {800, 449, 800, 449},
+ {800, 449, 800, 449},
+ {800, 449, 800, 449},
+ {800, 525, 800, 525},
+ {1056, 628,1056, 628},
+ {1056, 628,1056, 628},
+ {1056, 628,1056, 628},
+ {1056, 628,1056, 628}
+};
+
+static const SiS300_LVDSDataStruct SiS300_LVDS1280x960Data_1[] = /* TW: New */
+{
+ {840, 438,1344, 806},
+ {840, 409,1344, 806},
+ {840, 438,1344, 806},
+ {840, 409,1344, 806},
+ {840, 518,1344, 806},
+ {1050, 638,1344, 806},
+ {1344, 806,1344, 806},
+ {800, 449,1280, 801},
+ {800, 525,1280, 813}
+};
+
+static const SiS300_LVDSDataStruct SiS300_LVDS1280x960Data_2[] = /* TW: New */
+{
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {800, 449,1280, 801},
+ {800, 525,1280, 813}
+};
+
+static const SiS300_LVDSDataStruct SiS300_LCDA1400x1050Data_1[] = /* TW: New */
+{ /* TW: Might be temporary (invalid) data */
+ {928, 416, 1688, 1066},
+ {928, 366, 1688, 1066},
+ {1008, 416, 1688, 1066},
+ {1008, 366, 1688, 1066},
+ {1200, 530, 1688, 1066},
+ {1088, 616, 1688, 1066},
+ {1312, 784, 1688, 1066},
+ {1568, 1040, 1688, 1066},
+ {1688, 1066, 1688, 1066}
+};
+
+static const SiS300_LVDSDataStruct SiS300_LCDA1400x1050Data_2[] = /* TW: New */
+{ /* TW: Temporary data. Not valid */
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {800, 449,1280, 801},
+ {800, 525,1280, 813}
+};
+
+static const SiS300_LVDSDataStruct SiS300_LCDA1600x1200Data_1[] = /* TW: New */
+{ /* TW: Temporary data. Not valid */
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {800, 449,1280, 801},
+ {800, 525,1280, 813}
+};
+
+static const SiS300_LVDSDataStruct SiS300_LCDA1600x1200Data_2[] = /* TW: New */
+{ /* TW: Temporary data. Not valid */
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0}
+};
+
+
+/* TW: New: */
+static const SiS300_LVDSDataStruct SiS300_CHTVUNTSCData[] =
+{
+ {840, 600, 840, 600},
+ {840, 600, 840, 600},
+ {840, 600, 840, 600},
+ {840, 600, 840, 600},
+ {784, 600, 784, 600},
+ {1064, 750,1064, 750}
+};
+
+static const SiS300_LVDSDataStruct SiS300_CHTVONTSCData[] =
+{
+ {840, 525, 840, 525},
+ {840, 525, 840, 525},
+ {840, 525, 840, 525},
+ {840, 525, 840, 525},
+ {784, 525, 784, 525},
+ {1040, 700,1040, 700}
+};
+
+static const SiS300_LVDSDataStruct SiS300_CHTVUPALData[] =
+{
+ {1008, 625,1008, 625},
+ {1008, 625,1008, 625},
+ {1008, 625,1008, 625},
+ {1008, 625,1008, 625},
+ {840, 750, 840, 750},
+ {936, 836, 936, 836}
+};
+
+static const SiS300_LVDSDataStruct SiS300_CHTVOPALData[] =
+{
+ {1008, 625,1008, 625},
+ {1008, 625,1008, 625},
+ {1008, 625,1008, 625},
+ {1008, 625,1008, 625},
+ {840, 625, 840, 625},
+ {960, 750, 960, 750}
+};
+
+static const SiS300_LVDSDataStruct SiS300_CHTVSOPALData[] =
+{
+ {1008, 625,1008, 625},
+ {1008, 625,1008, 625},
+ {1008, 625,1008, 625},
+ {1008, 625,1008, 625},
+ {840, 500, 840, 500},
+ {944, 625, 944, 625}
+};
+
+/* TW: new end */
+
+typedef struct _SiS300_LVDSDesStruct
+{
+ USHORT LCDHDES;
+ USHORT LCDVDES;
+} SiS300_LVDSDesStruct;
+
+static const SiS300_LVDSDesStruct SiS300_PanelType00_1[] =
+{
+ {0, 626},
+ {0, 624},
+ {0, 626},
+ {0, 624},
+ {0, 624},
+ { 0, 627},
+ { 0, 627},
+ { 0, 0},
+ { 0, 0}
+};
+
+static const SiS300_LVDSDesStruct SiS300_PanelType01_1[] =
+{
+ {1343, 798},
+ {1343, 794},
+ {1343, 798},
+ {1343, 794},
+ {1343, 0},
+ {1343, 0},
+ { 0, 805},
+ { 0, 794},
+ { 0, 0}
+};
+
+static const SiS300_LVDSDesStruct SiS300_PanelType02_1[] =
+{
+ {0, 626},
+ {0, 624},
+ {0, 626},
+ {0, 624},
+ {0, 624},
+ { 0, 627},
+ { 0, 627},
+ { 0, 0},
+ { 0, 0}
+};
+
+static const SiS300_LVDSDesStruct SiS300_PanelType03_1[] =
+{
+ { 8, 436},
+ { 8, 440},
+ { 8, 436},
+ { 8, 440},
+ { 8, 512},
+ {1343, 798},
+ {1343, 794},
+ {1343, 798},
+ {1343, 794}
+};
+
+static const SiS300_LVDSDesStruct SiS300_PanelType04_1[] =
+{
+ {1343, 798},
+ {1343, 794},
+ {1343, 798},
+ {1343, 794},
+ {1343, 0},
+ {1343, 0},
+ { 0, 805},
+ { 0, 794},
+ { 0, 0}
+};
+
+static const SiS300_LVDSDesStruct SiS300_PanelType05_1[] =
+{
+ {1343, 798},
+ {1343, 794},
+ {1343, 798},
+ {1343, 794},
+ {1343, 0},
+ {1343, 0},
+ { 0, 805},
+ { 0, 794},
+ { 0, 0}
+};
+
+static const SiS300_LVDSDesStruct SiS300_PanelType06_1[] =
+{
+ {1343, 798},
+ {1343, 794},
+ {1343, 798},
+ {1343, 794},
+ {1343, 0},
+ {1343, 0},
+ { 0, 805},
+ { 0, 794},
+ { 0, 0}
+};
+
+static const SiS300_LVDSDesStruct SiS300_PanelType07_1[] =
+{
+ {1343, 798},
+ {1343, 794},
+ {1343, 798},
+ {1343, 794},
+ {1343, 0},
+ {1343, 0},
+ { 0, 805},
+ { 0, 794},
+ { 0, 0}
+};
+
+static const SiS300_LVDSDesStruct SiS300_PanelType08_1[] =
+{
+ {1059, 626},
+ {1059, 624},
+ {1059, 626},
+ {1059, 624},
+ {1059, 624},
+ { 0, 627},
+ { 0, 627},
+ { 0, 0},
+ { 0, 0}
+};
+
+static const SiS300_LVDSDesStruct SiS300_PanelType09_1[] =
+{
+ {1343, 798},
+ {1343, 794},
+ {1343, 798},
+ {1343, 794},
+ {1343, 0},
+ {1343, 0},
+ { 0, 805},
+ { 0, 794},
+ { 0, 0}
+};
+
+static const SiS300_LVDSDesStruct SiS300_PanelType0a_1[] =
+{
+ {1059, 626},
+ {1059, 624},
+ {1059, 626},
+ {1059, 624},
+ {1059, 624},
+ { 0, 627},
+ { 0, 627},
+ { 0, 0},
+ { 0, 0}
+};
+
+static const SiS300_LVDSDesStruct SiS300_PanelType0b_1[] =
+{
+ {1343, 0},
+ {1343, 0},
+ {1343, 0},
+ {1343, 0},
+ {1343, 0}, /* 640x480 - BIOS 1343, 0 */
+ {1343, 0},
+ { 0, 799},
+ { 0, 0},
+ { 0, 0}
+};
+
+static const SiS300_LVDSDesStruct SiS300_PanelType0c_1[] =
+{
+ {1343, 798},
+ {1343, 794},
+ {1343, 798},
+ {1343, 794},
+ {1343, 0},
+ {1343, 0},
+ { 0, 805},
+ { 0, 794},
+ { 0, 0}
+};
+
+static const SiS300_LVDSDesStruct SiS300_PanelType0d_1[] =
+{
+ {1343, 798},
+ {1343, 794},
+ {1343, 798},
+ {1343, 794},
+ {1343, 0},
+ {1343, 0},
+ { 0, 805},
+ { 0, 794},
+ { 0, 0}
+};
+
+static const SiS300_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 SiS300_LVDSDesStruct SiS300_PanelType0f_1[] =
+{
+ {1343, 798},
+ {1343, 794},
+ {1343, 798},
+ {1343, 794},
+ {1343, 0},
+ {1343, 0},
+ { 0, 805},
+ { 0, 794},
+ { 0, 0}
+};
+
+static const SiS300_LVDSDesStruct SiS300_PanelType00_2[] =
+{
+ {976, 527},
+ {976, 502},
+ {976, 527},
+ {976, 502},
+ {976, 567},
+ { 0, 627},
+ { 0, 627},
+ { 0, 0},
+ { 0, 0}
+};
+
+static const SiS300_LVDSDesStruct SiS300_PanelType01_2[] =
+{
+ {1152, 622},
+ {1152, 597},
+ {1152, 622},
+ {1152, 597},
+ {1152, 662},
+ {1232, 722},
+ { 0, 805},
+ { 0, 794},
+ { 0, 0}
+};
+
+static const SiS300_LVDSDesStruct SiS300_PanelType02_2[] =
+{
+ {976, 527},
+ {976, 502},
+ {976, 527},
+ {976, 502},
+ {976, 567},
+ { 0, 627},
+ { 0, 627},
+ { 0, 0},
+ { 0, 0}
+};
+
+static const SiS300_LVDSDesStruct SiS300_PanelType03_2[] =
+{
+ {1152, 622},
+ {1152, 597},
+ {1152, 622},
+ {1152, 597},
+ {1152, 662},
+ {1232, 722},
+ { 0, 805},
+ {1152, 622},
+ {1152, 597}
+};
+
+static const SiS300_LVDSDesStruct SiS300_PanelType04_2[] =
+{
+ {1152, 622},
+ {1152, 597},
+ {1152, 622},
+ {1152, 597},
+ {1152, 662},
+ {1232, 722},
+ { 0, 805},
+ { 0, 794},
+ { 0, 0}
+};
+
+static const SiS300_LVDSDesStruct SiS300_PanelType05_2[] =
+{
+ {1152, 622},
+ {1152, 597},
+ {1152, 622},
+ {1152, 597},
+ {1152, 662},
+ {1232, 722},
+ { 0, 805},
+ { 0, 794},
+ { 0, 0}
+};
+
+static const SiS300_LVDSDesStruct SiS300_PanelType06_2[] =
+{
+ {1152, 622},
+ {1152, 597},
+ {1152, 622},
+ {1152, 597},
+ {1152, 662},
+ {1232, 722},
+ { 0, 805},
+ { 0, 794},
+ { 0, 0}
+};
+
+static const SiS300_LVDSDesStruct SiS300_PanelType07_2[] =
+{
+ {1152, 622},
+ {1152, 597},
+ {1152, 622},
+ {1152, 597},
+ {1152, 662},
+ {1232, 722},
+ { 0, 805},
+ { 0, 794},
+ { 0, 0}
+};
+
+static const SiS300_LVDSDesStruct SiS300_PanelType08_2[] =
+{
+ {976, 527},
+ {976, 502},
+ {976, 527},
+ {976, 502},
+ {976, 567},
+ { 0, 627},
+ { 0, 627},
+ { 0, 0},
+ { 0, 0}
+};
+
+static const SiS300_LVDSDesStruct SiS300_PanelType09_2[] =
+{
+ {1152, 622},
+ {1152, 597},
+ {1152, 622},
+ {1152, 597},
+ {1152, 662},
+ {1232, 722},
+ { 0, 805},
+ { 0, 794},
+ { 0, 0}
+};
+
+static const SiS300_LVDSDesStruct SiS300_PanelType0a_2[] =
+{
+ {976, 527},
+ {976, 502},
+ {976, 527},
+ {976, 502},
+ {976, 567},
+ { 0, 627},
+ { 0, 627},
+ { 0, 0},
+ { 0, 0}
+};
+
+static const SiS300_LVDSDesStruct SiS300_PanelType0b_2[] =
+{
+ { 1152, 700},
+ { 1152, 675},
+ { 1152, 700},
+ { 1152, 675},
+ { 1152, 740},
+ { 1232, 799},
+ { 0, 799},
+ { 0, 0},
+ { 0, 0}
+};
+
+static const SiS300_LVDSDesStruct SiS300_PanelType0c_2[] =
+{
+ {1152, 622},
+ {1152, 597},
+ {1152, 622},
+ {1152, 597},
+ {1152, 662},
+ {1232, 722},
+ { 0, 805},
+ { 0, 794},
+ { 0, 0}
+};
+
+static const SiS300_LVDSDesStruct SiS300_PanelType0d_2[] =
+{
+ {1152, 622},
+ {1152, 597},
+ {1152, 622},
+ {1152, 597},
+ {1152, 662},
+ {1232, 722},
+ { 0, 805},
+ { 0, 794},
+ { 0, 0}
+};
+
+static const SiS300_LVDSDesStruct SiS300_PanelType0e_2[] =
+{
+ {1152, 622},
+ {1152, 597},
+ {1152, 622},
+ {1152, 597},
+ {1152, 662},
+ {1232, 722},
+ { 0, 805},
+ { 0, 794},
+ { 0, 0}
+};
+
+static const SiS300_LVDSDesStruct SiS300_PanelType0f_2[] =
+{
+ {1152, 622},
+ {1152, 597},
+ {1152, 622},
+ {1152, 597},
+ {1152, 662},
+ {1232, 722},
+ { 0, 805},
+ { 0, 794},
+ { 0, 0}
+};
+
+static const SiS300_LVDSDesStruct SiS300_PanelType1076_1[] = /* TW: New */
+{
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0}
+};
+
+static const SiS300_LVDSDesStruct SiS300_PanelType1076_2[] = /* TW: New */
+{
+ { 1152, 622 },
+ { 1152, 597 },
+ { 1152, 622 },
+ { 1152, 597 },
+ { 1152, 622 },
+ { 1232, 722 },
+ { 0, 0 },
+ { 0, 794 },
+ { 0, 0 }
+};
+
+static const SiS300_LVDSDesStruct SiS300_PanelType1210_1[] = /* TW: New */
+{
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0}
+};
+
+static const SiS300_LVDSDesStruct SiS300_PanelType1210_2[] = /* TW: New */
+{
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0}
+};
+
+static const SiS300_LVDSDesStruct SiS300_PanelType1296_1[] = /* TW: New */
+{
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0}
+};
+
+static const SiS300_LVDSDesStruct SiS300_PanelType1296_2[] = /* TW: New */
+{
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0}
+};
+
+
+/* TW: New */
+static const SiS300_LVDSDesStruct SiS300_CHTVUNTSCDesData[] =
+{
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0}
+};
+
+static const SiS300_LVDSDesStruct SiS300_CHTVONTSCDesData[] =
+{
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0}
+};
+
+static const SiS300_LVDSDesStruct SiS300_CHTVUPALDesData[] =
+{
+ {256, 0},
+ {256, 0},
+ {256, 0},
+ {256, 0},
+ { 0, 0},
+ { 0, 0}
+};
+
+static const SiS300_LVDSDesStruct SiS300_CHTVOPALDesData[] =
+{
+ {256, 0},
+ {256, 0},
+ {256, 0},
+ {256, 0},
+ { 0, 0},
+ { 0, 0}
+};
+/* TW: New end */
+
+/* TW: New for SiS300+301LV */
+typedef struct _SiS300_Part2PortTblStruct
+{
+ UCHAR CR[12];
+} SiS300_Part2PortTblStruct;
+
+static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1024x768_1[] =
+{ /* VESA Timing */
+ {{0x21,0x12,0xbf,0xe4,0xc0,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}},
+ {{0x2c,0x12,0x9a,0xae,0x88,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}},
+ {{0x21,0x12,0xbf,0xe4,0xc0,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}},
+ {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}},
+ {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}}
+};
+
+static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1280x1024_1[] =
+{ /* TW: Temporary data, invalid */
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+};
+
+static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1400x1050_1[] =
+{ /* TW: Temporary data, invalid */
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+};
+
+static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1600x1200_1[] =
+{ /* TW: Temporary data, invalid */
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+};
+
+static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1024x768_2[] =
+{ /* Non-VESA */
+ {{0x28,0x12,0xa3,0xd0,0xaa,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
+ {{0x2c,0x12,0x9a,0xae,0x88,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
+ {{0x28,0x12,0xa3,0xd0,0xaa,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
+ {{0x2c,0x12,0x9a,0xae,0x88,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
+ {{0x28,0x13,0xe7,0x0b,0xe8,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
+ {{0x38,0x18,0x16,0x00,0x00,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
+ {{0x36,0x13,0x13,0x25,0xff,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}}
+};
+
+static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1280x1024_2[] =
+{
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+};
+
+static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1400x1050_2[] =
+{
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+};
+
+static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1600x1200_2[] =
+{ /* TW: Temporary data, invalid */
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+};
+
+static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1024x768_3[] =
+{ /* TW: Temporary data, invalid */
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+};
+
+static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1280x1024_3[] =
+{ /* TW: Temporary data, invalid */
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+};
+
+static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1400x1050_3[] =
+{ /* TW: Temporary data, invalid */
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+};
+
+static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1600x1200_3[] =
+{ /* TW: Temporary data, invalid */
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+};
+
+typedef struct _SiS300_LVDSCRT1DataStruct
+{
+UCHAR CR[15];
+} SiS300_LVDSCRT1DataStruct;
+
+static const SiS300_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 SiS300_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 SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11280x1024_1[] =
+{
+ {{0x63,0x4f,0x87,0x54,0x9f,0xb4,0x1f,
+ 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
+ 0x00 }},
+ {{0x63,0x4f,0x87,0x54,0x9f,0x82,0x1f,
+ 0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
+ 0x00 }},
+ {{0x63,0x4f,0x87,0x54,0x9f,0xb4,0x1f,
+ 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
+ 0x00 }},
+ {{0x63,0x4f,0x87,0x54,0x9f,0x82,0x1f,
+ 0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
+ 0x00 }},
+ {{0x63,0x4f,0x87,0x54,0x9f,0x04,0x3e,
+ 0xe2,0x89,0xdf,0x05,0x00,0x00,0x01,
+ 0x00 }},
+ {{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0,
+ 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26,
+ 0x01 }},
+ {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+ 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+ 0x01 }}
+};
+
+static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT1800x600_1_H[] =
+{
+ {{0x30,0x27,0x94,0x2c,0x92,0xaf,0x1f,
+ 0x90,0x85,0x8f,0xab,0x30,0x00,0x04,
+ 0x00 }},
+ {{0x30,0x27,0x94,0x2c,0x92,0x83,0x1f,
+ 0x5e,0x83,0x5d,0x79,0x10,0x00,0x04,
+ 0x00 }},
+ {{0x30,0x27,0x94,0x2c,0x92,0xaf,0x1f,
+ 0x90,0x85,0x8f,0xab,0x30,0x00,0x04,
+ 0x00 }},
+ {{0x30,0x27,0x94,0x2c,0x92,0x83,0x1f,
+ 0x5e,0x83,0x5d,0x79,0x10,0x00,0x04,
+ 0x00 }},
+ {{0x30,0x27,0x94,0x2c,0x92,0x04,0x3e,
+ 0xe0,0x85,0xdf,0xfb,0x10,0x00,0x04,
+ 0x00 }},
+ {{0x3d,0x31,0x81,0x37,0x1f,0x72,0xf0,
+ 0x58,0x8c,0x57,0x73,0x20,0x00,0x05,
+ 0x01 }}
+};
+
+static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11024x768_1_H[] =
+{
+ {{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 }}
+};
+
+static const SiS300_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 SiS300_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 SiS300_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 SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11280x1024_2[] =
+{
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+ 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+ 0x00 }},
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+ 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+ 0x00 }},
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+ 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+ 0x00 }},
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+ 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+ 0x00 }},
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+ 0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
+ 0x00 }},
+ {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
+ 0xae,0x84,0x57,0x25,0x30,0x00,0x02,
+ 0x01 }},
+ {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+ 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+ 0x01 }}
+};
+
+static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT1800x600_2_H[] =
+{
+ {{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
+ 0xf4,0x88,0x8f,0x73,0x20,0x00,0x05,
+ 0x00 }},
+ {{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
+ 0xdb,0x8f,0x5d,0x73,0x20,0x00,0x05,
+ 0x00 }},
+ {{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
+ 0xf4,0x88,0x8f,0x73,0x20,0x00,0x05,
+ 0x00 }},
+ {{0x3d,0x27,0x81,0x3a,0x1a,0x72,0x3e,
+ 0xdb,0x8f,0x5d,0x73,0x20,0x00,0x05,
+ 0x00 }},
+ {{0x3d,0x27,0x81,0x32,0x1a,0x72,0xba,
+ 0x1c,0x80,0xdf,0x73,0x00,0x00,0x05,
+ 0x00 }},
+ {{0x3d,0x31,0x81,0x37,0x1f,0x72,0xf0,
+ 0x58,0x8c,0x57,0x73,0x20,0x00,0x05,
+ 0x01 }}
+};
+
+static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11024x768_2_H[] =
+{
+ {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+ 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+ 0x00 }},
+ {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+ 0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+ 0x00 }},
+ {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+ 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+ 0x00 }},
+ {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+ 0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+ 0x00 }},
+ {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+ 0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
+ 0x00 }},
+ {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
+ 0xae,0x84,0x57,0x25,0x30,0x00,0x01,
+ 0x01 }},
+ {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+ 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+ 0x01 }}
+};
+
+static const SiS300_LVDSCRT1DataStruct SiS300_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 SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11024x600_1[] =
+{
+ {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e,
+ 0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01,
+ 0x00}},
+ {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e,
+ 0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01,
+ 0x00}},
+ {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e,
+ 0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01,
+ 0x00}},
+ {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e,
+ 0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01,
+ 0x00}},
+ {{0x64,0x4f,0x88,0x54,0x9f,0xaf,0xba,
+ 0x3b,0x82,0xdf,0xb0,0x00,0x00,0x01,
+ 0x00}},
+ {{0x7e,0x63,0x82,0x68,0x15,0x1e,0xf1,
+ 0xae,0x85,0x57,0x1f,0x30,0x00,0x26,
+ 0x01}},
+ {{0xa3,0x7f,0x87,0x86,0x97,0x1e,0xf1,
+ 0xae,0x85,0x57,0x1f,0x30,0x00,0x02,
+ 0x01}}
+};
+
+static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11024x600_1_H[] =
+{
+ {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
+ 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
+ 0x00}},
+ {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
+ 0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
+ 0x00}},
+ {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
+ 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
+ 0x00}},
+ {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
+ 0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
+ 0x00}},
+ {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
+ 0xe2,0x89,0xdf,0x05,0x00,0x00,0x44,
+ 0x00}},
+ {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
+ 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
+ 0x01}},
+ {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+ 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+ 0x01}}
+};
+
+static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11024x600_2[] =
+{
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+ 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+ 0x00}},
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+ 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+ 0x00}},
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+ 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+ 0x00}},
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+ 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+ 0x00}},
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+ 0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
+ 0x00}},
+ {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
+ 0xae,0x84,0x57,0x25,0x30,0x00,0x02,
+ 0x01}},
+ {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+ 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+ 0x01}}
+};
+
+static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11024x600_2_H[] =
+{
+ {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+ 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+ 0x00}},
+ {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+ 0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+ 0x00}},
+ {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+ 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+ 0x00}},
+ {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+ 0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+ 0x00}},
+ {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+ 0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
+ 0x00}},
+ {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
+ 0xae,0x84,0x57,0x25,0x30,0x00,0x01,
+ 0x01}},
+ {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+ 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+ 0x01}}
+};
+
+static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11152x768_1[] =
+{
+ {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
+ 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
+ 0x00}},
+ {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
+ 0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
+ 0x00}},
+ {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
+ 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
+ 0x00}},
+ {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
+ 0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
+ 0x00}},
+ {{0x64,0x4f,0x88,0x54,0x9f,0x04,0x3e,
+ 0xe2,0x89,0xdf,0x05,0x00,0x00,0x01,
+ 0x00}},
+ {{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0,
+ 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26,
+ 0x01}},
+ {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+ 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+ 0x01}}
+};
+
+static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11152x768_1_H[] =
+{
+ {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
+ 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
+ 0x00}},
+ {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
+ 0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
+ 0x00}},
+ {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
+ 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
+ 0x00}},
+ {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
+ 0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
+ 0x00}},
+ {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
+ 0xe2,0x89,0xdf,0x05,0x00,0x00,0x44,
+ 0x00}},
+ {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
+ 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
+ 0x01}},
+ {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+ 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+ 0x01}}
+};
+
+static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11152x768_2[] =
+{
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+ 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+ 0x00}},
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+ 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+ 0x00}},
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+ 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+ 0x00}},
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+ 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+ 0x00}},
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+ 0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
+ 0x00}},
+ {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
+ 0xae,0x84,0x57,0x25,0x30,0x00,0x02,
+ 0x01}},
+ {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+ 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+ 0x01}}
+};
+
+static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11152x768_2_H[] =
+{
+ {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+ 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+ 0x00}},
+ {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+ 0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+ 0x00}},
+ {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+ 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+ 0x00}},
+ {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+ 0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+ 0x00}},
+ {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+ 0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
+ 0x00}},
+ {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
+ 0xae,0x84,0x57,0x25,0x30,0x00,0x01,
+ 0x01}},
+ {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+ 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+ 0x01}}
+};
+
+/* TW: New */
+static const SiS300_LVDSCRT1DataStruct SiS300_CHTVCRT1UNTSC[] =
+{
+ {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
+ 0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,
+ 0x00 }},
+ {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
+ 0xd0,0x82,0x5d,0x57,0x00,0x00,0x01,
+ 0x00 }},
+ {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
+ 0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,
+ 0x00 }},
+ {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
+ 0xd0,0x82,0x5d,0x57,0x00,0x00,0x01,
+ 0x00 }},
+ {{0x5d,0x4f,0x81,0x53,0x9c,0x56,0xba,
+ 0x18,0x84,0xdf,0x57,0x00,0x00,0x01,
+ 0x00 }},
+ {{0x80,0x63,0x84,0x6c,0x17,0xec,0xf0,
+ 0x90,0x8c,0x57,0xed,0x20,0x00,0x06,
+ 0x01 }}
+};
+
+static const SiS300_LVDSCRT1DataStruct SiS300_CHTVCRT1ONTSC[] =
+{
+ {{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
+ 0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,
+ 0x00 }},
+ {{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
+ 0xb0,0x8d,0x5d,0x0c,0x00,0x00,0x01,
+ 0x00 }},
+ {{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
+ 0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,
+ 0x00 }},
+ {{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
+ 0xb0,0x8d,0x5d,0x0c,0x00,0x00,0x01,
+ 0x00 }},
+ {{0x5d,0x4f,0x81,0x56,0x9c,0x0b,0x3e,
+ 0xe8,0x84,0xdf,0x0c,0x00,0x00,0x01,
+ 0x00 }},
+ {{0x7d,0x63,0x81,0x6a,0x16,0xba,0xf0,
+ 0x7f,0x86,0x57,0xbb,0x00,0x00,0x06,
+ 0x01 }}
+};
+
+static const SiS300_LVDSCRT1DataStruct SiS300_CHTVCRT1UPAL[] =
+{
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+ 0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,
+ 0x00 }},
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+ 0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
+ 0x00 }},
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+ 0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,
+ 0x00 }},
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+ 0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
+ 0x00 }},
+ {{0x64,0x4f,0x88,0x55,0x80,0xec,0xba,
+ 0x50,0x84,0xdf,0xed,0x00,0x00,0x05,
+ 0x00 }},
+ {{0x70,0x63,0x94,0x68,0x8d,0x42,0xf1,
+ 0xc8,0x8c,0x57,0xe9,0x20,0x00,0x05,
+ 0x01 }}
+};
+
+static const SiS300_LVDSCRT1DataStruct SiS300_CHTVCRT1OPAL[] =
+{
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+ 0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
+ 0x00 }},
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+ 0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
+ 0x00 }},
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+ 0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
+ 0x00 }},
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+ 0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
+ 0x00 }},
+ {{0x64,0x4f,0x88,0x55,0x80,0x6f,0xba,
+ 0x20,0x83,0xdf,0x70,0x00,0x00,0x05,
+ 0x00 }},
+ {{0x73,0x63,0x97,0x69,0x8e,0xec,0xf0,
+ 0x90,0x8c,0x57,0xed,0x20,0x00,0x05,
+ 0x01 }}
+};
+
+static const SiS300_LVDSCRT1DataStruct SiS300_CHTVCRT1SOPAL[] =
+{
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+ 0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
+ 0x00 }},
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+ 0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
+ 0x00 }},
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+ 0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
+ 0x00 }},
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+ 0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
+ 0x00 }},
+ {{0x64,0x4f,0x88,0x55,0x80,0x6f,0xba, /* TODO */
+ 0x20,0x83,0xdf,0x70,0x00,0x00,0x05,
+ 0x00 }},
+ {{0x73,0x63,0x97,0x69,0x8e,0xec,0xf0, /* TODO */
+ 0x90,0x8c,0x57,0xed,0x20,0x00,0x05,
+ 0x01 }}
+};
+/* TW: New end */
+
+/* TW: New */
+typedef struct _SiS300_CHTVRegDataStruct
+{
+ UCHAR Reg[16];
+} SiS300_CHTVRegDataStruct;
+
+static const SiS300_CHTVRegDataStruct 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}},
+ {{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}},
+ {{0x6a,0x6a,0x00,0x2d,0xfa,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 17: 640x480 NTSC 7/8 */
+ {{0x8d,0xc4,0x00,0x3b,0xfb,0,0,0,0,0,0,0,0,0,0,0}} /* Mode 24: 800x600 NTSC 7/10 */
+};
+
+static const SiS300_CHTVRegDataStruct 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}},
+ {{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}},
+ {{0x69,0x6a,0x00,0x1e,0xfd,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 16: 640x480 NTSC 1/1 */
+ {{0x8c,0xb4,0x00,0x32,0xf9,0,0,0,0,0,0,0,0,0,0,0}} /* Mode 23: 800x600 NTSC 3/4 */
+};
+
+static const SiS300_CHTVRegDataStruct 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}},
+ {{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}},
+ {{0x63,0x94,0x01,0x50,0x30,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 15: 640x480 PAL 5/6 */
+ {{0x84,0x64,0x01,0x4e,0x2f,0,0,0,0,0,0,0,0,0,0,0}} /* Mode 21: 800x600 PAL 3/4 */
+
+};
+
+static const SiS300_CHTVRegDataStruct 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}},
+ {{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}},
+ {{0x61,0x94,0x01,0x36,0x30,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 14: 640x480 PAL 1/1 */
+ {{0x83,0x76,0x01,0x40,0x31,0,0,0,0,0,0,0,0,0,0,0}} /* Mode 20: 800x600 PAL 5/6 */
+
+};
+
+static const SiS300_CHTVRegDataStruct SiS300_CHTVReg_SOPAL[] =
+{
+ {{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 9: 640x400 PAL 5/4 */
+ {{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}},
+ {{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}},
+ {{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}},
+ {{0x60,0x30,0x00,0x10,0x00,0,0,0,0,0,0,0,0,0,0,0}}, /* TW: Mode 13: 640x480 PAL 5/4 */
+ {{0x81,0x50,0x00,0x1b,0x00,0,0,0,0,0,0,0,0,0,0,0}} /* TW: Mode 19: 800x600 PAL 1/1 */
+};
+/* TW: New end */
+
+/* TW: New */
+static const UCHAR SiS300_CHTVVCLKUNTSC[] = {0x29,0x29,0x29,0x29,0x2a,0x2e};
+
+static const UCHAR SiS300_CHTVVCLKONTSC[] = {0x2c,0x2c,0x2c,0x2c,0x2d,0x2b};
+
+static const UCHAR SiS300_CHTVVCLKSONTSC[] = {0x2c,0x2c,0x2c,0x2c,0x2d,0x2b};
+
+static const UCHAR SiS300_CHTVVCLKUPAL[] = {0x2f,0x2f,0x2f,0x2f,0x2f,0x31};
+
+static const UCHAR SiS300_CHTVVCLKOPAL[] = {0x2f,0x2f,0x2f,0x2f,0x30,0x32};
+
+static const UCHAR SiS300_CHTVVCLKSOPAL[] = {0x2f,0x2f,0x2f,0x2f,0x36,0x29};
+/* TW: New end */
+
+
diff --git a/src/310vtbl.h b/src/310vtbl.h
new file mode 100644
index 0000000..5bb9d77
--- /dev/null
+++ b/src/310vtbl.h
@@ -0,0 +1,4673 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/310vtbl.h,v 1.5 2003/02/10 01:14:16 tsi Exp $ */
+
+
+/* Register settings for SiS 310/325 series */
+
+
+typedef struct _SiS310_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;
+} SiS310_StStruct;
+
+static const SiS310_StStruct SiS310_SModeIDTable[]=
+{
+ {0x01,0x9208,0x01,0x00,0x00,0x00,0x01,0x00},
+ {0x01,0x1210,0x14,0x01,0x01,0x00,0x01,0x00},
+ {0x01,0x1010,0x17,0x02,0x02,0x00,0x01,0x01},
+ {0x03,0x8208,0x03,0x00,0x00,0x00,0x01,0x02},
+ {0x03,0x0210,0x16,0x01,0x01,0x00,0x01,0x02},
+ {0x03,0x0010,0x18,0x02,0x02,0x00,0x01,0x03},
+ {0x05,0x9209,0x05,0x00,0x00,0x00,0x00,0x04},
+ {0x06,0x8209,0x06,0x00,0x00,0x00,0x00,0x05},
+ {0x07,0x0000,0x07,0x03,0x03,0x00,0x01,0x03},
+ {0x07,0x0000,0x19,0x02,0x02,0x00,0x01,0x03},
+ {0x0d,0x920a,0x0d,0x00,0x00,0x00,0x00,0x04},
+ {0x0e,0x820a,0x0e,0x00,0x00,0x00,0x00,0x05},
+ {0x0f,0x0202,0x11,0x01,0x01,0x00,0x00,0x05},
+ {0x10,0x0212,0x12,0x01,0x01,0x00,0x00,0x05},
+ {0x11,0x0212,0x1a,0x04,0x04,0x00,0x00,0x05},
+ {0x12,0x0212,0x1b,0x04,0x04,0x00,0x00,0x05},
+ {0x13,0x021b,0x1c,0x00,0x00,0x00,0x00,0x04},
+ {0x12,0x0010,0x18,0x02,0x02,0x00,0x00,0x05},
+ {0x12,0x0210,0x18,0x01,0x01,0x00,0x00,0x05},
+ {0xff,0x0000,0x00,0x00,0x00,0x00,0x00,0x00}
+};
+
+typedef struct _SiS310_StandTableStruct
+{
+ UCHAR CRT_COLS;
+ UCHAR ROWS;
+ UCHAR CHAR_HEIGHT;
+ USHORT CRT_LEN;
+ UCHAR SR[4];
+ UCHAR MISC;
+ UCHAR CRTC[0x19];
+ UCHAR ATTR[0x14];
+ UCHAR GRC[9];
+} SiS310_StandTableStruct;
+
+static const SiS310_StandTableStruct SiS310_StandTable[]=
+{
+/* MD_0_200 */
+ {
+ 0x28,0x18,0x08,0x0800,
+ {0x09,0x03,0x00,0x02},
+ 0x63,
+ {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+ 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
+ 0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
+ 0xff},
+ {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+ 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+ 0x08,0x00,0x0f,0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+ 0xff}
+ },
+/* MD_1_200 */
+ {
+ 0x28,0x18,0x08,0x0800,
+ {0x09,0x03,0x00,0x02},
+ 0x63,
+ {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+ 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
+ 0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
+ 0xff},
+ {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+ 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+ 0x08,0x00,0x0f,0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+ 0xff}
+ },
+/* MD_2_200 */
+ {
+ 0x50,0x18,0x08,0x1000,
+ {0x01,0x03,0x00,0x02},
+ 0x63,
+ {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+ 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
+ 0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
+ 0xff},
+ {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+ 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+ 0x08,0x00,0x0f,0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+ 0xff}
+ },
+/* MD_3_200 */
+ {
+ 0x50,0x18,0x08,0x1000,
+ {0x01,0x03,0x00,0x02},
+ 0x63,
+ {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+ 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
+ 0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
+ 0xff},
+ {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+ 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+ 0x08,0x00,0x0f,0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+ 0xff}
+ },
+/* MD_4 */
+ {
+ 0x28,0x18,0x08,0x4000,
+ {0x09,0x03,0x00,0x02},
+ 0x63,
+ {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
+ 0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
+ 0xff},
+ {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
+ 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+ 0x01,0x00,0x03,0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
+ 0xff}
+ },
+/* MD_5 */
+ {
+ 0x28,0x18,0x08,0x4000,
+ {0x09,0x03,0x00,0x02},
+ 0x63,
+ {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
+ 0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
+ 0xff},
+ {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
+ 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+ 0x01,0x00,0x03,0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
+ 0xff}
+ },
+/* MD_6 */
+ {
+ 0x50,0x18,0x08,0x4000,
+ {0x01,0x01,0x00,0x06},
+ 0x63,
+ {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+ 0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xc2,
+ 0xff},
+ {0x00,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+ 0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+ 0x01,0x00,0x01,0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x00,
+ 0xff}
+ },
+/* MD_7 */
+ {
+ 0x50,0x18,0x0e,0x1000,
+ {0x00,0x03,0x00,0x03},
+ 0xa6,
+ {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+ 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+ 0x83,0x85,0x5d,0x28,0x0d,0x63,0xba,0xa3,
+ 0xff},
+ {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+ 0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+ 0x0e,0x00,0x0f,0x08},
+ {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
+ 0xff}
+ },
+/* MDA_DAC */
+ {
+ 0x00,0x00,0x00,0x0000,
+ {0x00,0x00,0x00,0x15},
+ 0x15,
+ {0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+ 0x15,0x15,0x15,0x15,0x15,0x15,0x3f,0x3f,
+ 0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x00,
+ 0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x15,0x15,0x15,
+ 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+ 0x15,0x15,0x15,0x15},
+ {0x15,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
+ 0x3f}
+ },
+/* CGA_DAC */
+ {
+ 0x00,0x10,0x04,0x0114,
+ {0x11,0x09,0x15,0x00},
+ 0x10,
+ {0x04,0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,
+ 0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x2a,0x3a,
+ 0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x10,
+ 0x04},
+ {0x14,0x01,0x11,0x09,0x15,0x00,0x10,0x04,
+ 0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,0x2e,
+ 0x3e,0x2b,0x3b,0x2f},
+ {0x3f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
+ 0x3f}
+ },
+/* EGA_DAC */
+ {
+ 0x00,0x10,0x04,0x0114,
+ {0x11,0x05,0x15,0x20},
+ 0x30,
+ {0x24,0x34,0x21,0x31,0x25,0x35,0x08,0x18,
+ 0x0c,0x1c,0x09,0x19,0x0d,0x1d,0x28,0x38,
+ 0x2c,0x3c,0x29,0x39,0x2d,0x3d,0x02,0x12,
+ 0x06},
+ {0x16,0x03,0x13,0x07,0x17,0x22,0x32,0x26,
+ 0x36,0x23,0x33,0x27,0x37,0x0a,0x1a,0x0e,
+ 0x1e,0x0b,0x1b,0x0f},
+ {0x1f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
+ 0x3f}
+ },
+/* VGA_DAC */
+ {
+ 0x00,0x10,0x04,0x0114,
+ {0x11,0x09,0x15,0x2a},
+ 0x3a,
+ {0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x05,
+ 0x08,0x0b,0x0e,0x11,0x14,0x18,0x1c,0x20,
+ 0x24,0x28,0x2d,0x32,0x38,0x3f,0x00,0x10,
+ 0x1f},
+ {0x2f,0x3f,0x1f,0x27,0x2f,0x37,0x3f,0x2d,
+ 0x31,0x36,0x3a,0x3f,0x00,0x07,0x0e,0x15,
+ 0x1c,0x0e,0x11,0x15},
+ {0x18,0x1c,0x14,0x16,0x18,0x1a,0x1c,0x00,
+ 0x04}
+ },
+ {
+ 0x08,0x0c,0x10,0x0a08,
+ {0x0c,0x0e,0x10,0x0b},
+ 0x0c,
+ {0x0d,0x0f,0x10,0x10,0x01,0x08,0x00,0x00,
+ 0x00,0x00,0x01,0x00,0x02,0x02,0x01,0x00,
+ 0x04,0x04,0x01,0x00,0x05,0x02,0x05,0x00,
+ 0x06},
+ {0x01,0x06,0x05,0x06,0x00,0x08,0x01,0x08,
+ 0x00,0x07,0x02,0x07,0x06,0x07,0x00,0x00,
+ 0x00,0x00,0x00,0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}
+ },
+/* MD_D */
+ {
+ 0x28,0x18,0x08,0x2000,
+ {0x09,0x0f,0x00,0x06},
+ 0x63,
+ {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
+ 0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xe3,
+ 0xff},
+ {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+ 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+ 0x01,0x00,0x0f,0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
+ 0xff}
+ },
+/* MD_E */
+ {
+ 0x50,0x18,0x08,0x4000,
+ {0x01,0x0f,0x00,0x06},
+ 0x63,
+ {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+ 0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xe3,
+ 0xff},
+ {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+ 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+ 0x01,0x00,0x0f,0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
+ 0xff}
+ },
+/* ExtVGATable */
+ {
+ 0x00,0x00,0x00,0x0000,
+ {0x01,0x0f,0x00,0x0e},
+ 0x23,
+ {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,
+ 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xea,0x8c,0xdf,0x28,0x40,0xe7,0x04,0xa3,
+ 0xff},
+ {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+ 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
+ 0x01,0x00,0x00,0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
+ 0xff}
+ },
+/* ROM_SAVEPTR */
+ {
+ 0x9f,0x3b,0x00,0x00c0,
+ {0x00,0x00,0x00,0x00},
+ 0x00,
+ {0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x3f,
+ 0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x1a,0x00,0xac,0x3e,0x00,0xc0,
+ 0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}
+ },
+/* MD_F */
+ {
+ 0x50,0x18,0x0e,0x8000,
+ {0x01,0x0f,0x00,0x06},
+ 0xa2,
+ {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+ 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x82,0x84,0x5d,0x28,0x0f,0x63,0xba,0xe3,
+ 0xff},
+ {0x00,0x08,0x00,0x00,0x18,0x18,0x00,0x00,
+ 0x00,0x08,0x00,0x00,0x00,0x18,0x00,0x00,
+ 0x0b,0x00,0x05,0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x05,
+ 0xff}
+ },
+/* MD_10 */
+ {
+ 0x50,0x18,0x0e,0x8000,
+ {0x01,0x0f,0x00,0x06},
+ 0xa3,
+ {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+ 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x82,0x84,0x5d,0x28,0x0f,0x63,0xba,0xe3,
+ 0xff},
+ {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+ 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+ 0x01,0x00,0x0f,0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
+ 0xff}
+ },
+/* MD_0_350 */
+ {
+ 0x28,0x18,0x0e,0x0800,
+ {0x09,0x03,0x00,0x02},
+ 0xa3,
+ {0x2d,0x27,0x28,0x90,0x2b,0xb1,0xbf,0x1f,
+ 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+ 0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
+ 0xff},
+ {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+ 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+ 0x08,0x00,0x0f,0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+ 0xff}
+ },
+/* MD_1_350 */
+ {
+ 0x28,0x18,0x0e,0x0800,
+ {0x09,0x03,0x00,0x02},
+ 0xa3,
+ {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+ 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+ 0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
+ 0xff},
+ {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+ 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+ 0x08,0x00,0x0f,0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+ 0xff}
+ },
+/* MD_2_350 */
+ {
+ 0x50,0x18,0x0e,0x1000,
+ {0x01,0x03,0x00,0x02},
+ 0xa3,
+ {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+ 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+ 0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
+ 0xff},
+ {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+ 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+ 0x08,0x00,0x0f,0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+ 0xff}
+ },
+/* MD_3_350 */
+ {
+ 0x50,0x18,0x0e,0x1000,
+ {0x01,0x03,0x00,0x02},
+ 0xa3,
+ {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+ 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+ 0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
+ 0xff},
+ {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+ 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+ 0x08,0x00,0x0f,0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+ 0xff}
+ },
+/* MD_0_1_400 */
+ {
+ 0x28,0x18,0x10,0x0800,
+ {0x08,0x03,0x00,0x02},
+ 0x67,
+ {0x2d,0x27,0x28,0x90,0x2b,0xb1,0xbf,0x1f,
+ 0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
+ 0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
+ 0xff},
+ {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+ 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+ 0x0c,0x00,0x0f,0x08},
+ {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+ 0xff}
+ },
+/* MD_2_3_400 */
+ {
+ 0x50,0x18,0x10,0x1000,
+ {0x00,0x03,0x00,0x02},
+ 0x67,
+ {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+ 0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
+ 0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
+ 0xff},
+ {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+ 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+ 0x0c,0x00,0x0f,0x08},
+ {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+ 0xff}
+ },
+/* MD_7_400 */
+ {
+ 0x50,0x18,0x10,0x1000,
+ {0x00,0x03,0x00,0x02},
+ 0x66,
+ {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+ 0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
+ 0x9c,0x8e,0x8f,0x28,0x0f,0x96,0xb9,0xa3,
+ 0xff},
+ {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+ 0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+ 0x0e,0x00,0x0f,0x08},
+ {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
+ 0xff}
+ },
+/* MD_11 */
+ {
+ 0x50,0x1d,0x10,0xa000,
+ {0x01,0x0f,0x00,0x06},
+ 0xe3,
+ {0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,
+ 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xe9,0x8b,0xdf,0x28,0x00,0xe7,0x04,0xc3,
+ 0xff},
+ {0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
+ 0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
+ 0x01,0x00,0x0f,0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x01,
+ 0xff}
+ },
+/* ExtEGATable */
+ {
+ 0x50,0x1d,0x10,0xa000,
+ {0x01,0x0f,0x00,0x06},
+ 0xe3,
+ {0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,
+ 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xe9,0x8b,0xdf,0x28,0x00,0xe7,0x04,0xe3,
+ 0xff},
+ {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+ 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+ 0x01,0x00,0x0f,0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
+ 0xff}
+ },
+/* MD_13 */
+ {
+ 0x28,0x18,0x08,0x2000,
+ {0x01,0x0f,0x00,0x0e},
+ 0x63,
+ {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+ 0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x9c,0x8e,0x8f,0x28,0x40,0x96,0xb9,0xa3,
+ 0xff},
+ {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+ 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
+ 0x41,0x00,0x0f,0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
+ 0xff}
+ }
+};
+
+typedef struct _SiS310_ExtStruct
+{
+ UCHAR Ext_ModeID;
+ USHORT Ext_ModeFlag;
+ USHORT Ext_ModeInfo;
+ USHORT Ext_Point; /* TW: Address of table entry in (older) BIOS image */
+ USHORT Ext_VESAID;
+ UCHAR Ext_VESAMEMSize;
+ UCHAR Ext_RESINFO;
+ UCHAR VB_ExtTVFlickerIndex;
+ UCHAR VB_ExtTVEdgeIndex;
+ UCHAR VB_ExtTVYFilterIndex;
+ UCHAR REFindex;
+} SiS310_ExtStruct;
+
+/* TW: Checked with 650/LVDS and 650/301LVx 1.10.6s */
+static const SiS310_ExtStruct SiS310_EModeIDTable[]=
+{
+ {0x6a,0x2212,0x0407,0x3a81,0x0102,0x08,0x07,0x00,0x00,0x07,0x00}, /* 800x600x? */
+ {0x2e,0x0a1b,0x0306,0x3a57,0x0101,0x08,0x06,0x00,0x00,0x05,0x08}, /* 640x480x8 */
+/* {0x2e,0x021b,0x0306,0x3a57,0x0101,0x08,0x06,0x00,0x00,0x05,0x08}, */ /* 640x480x8 - 650/LVDS BIOS (no CRt2Mode) */
+ {0x2f,0x0a1b,0x0305,0x3a50,0x0100,0x08,0x05,0x00,0x00,0x05,0x10}, /* 640x400x8 */
+/* {0x2f,0x021b,0x0305,0x3a50,0x0100,0x08,0x05,0x00,0x00,0x05,0x10}, */ /* 640x400x8 - 650/LVDS BIOS (no CRt2Mode) */
+ {0x30,0x2a1b,0x0407,0x3a81,0x0103,0x08,0x07,0x00,0x00,0x07,0x00}, /* 800x600x8 */
+/* {0x30,0x221b,0x0407,0x3a81,0x0103,0x08,0x07,0x00,0x00,0x07,0x00}, */ /* 800x600x8 - 650/LVDS BIOS (no CRt2Mode) */
+/* {0x31,0x0a1b,0x030d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x11}, */ /* 720x480x8 */
+ {0x31,0x0a1b,0x0a0d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x11}, /* 720x480x8 BIOS (301/LVDS) */
+ {0x32,0x0a1b,0x0a0e,0x3b8c,0x0000,0x08,0x0e,0x00,0x00,0x06,0x12}, /* 720x576x8 */
+ {0x33,0x0a1d,0x0a0d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x11}, /* 720x480x16 */
+ {0x34,0x2a1d,0x0a0e,0x3b8c,0x0000,0x08,0x0e,0x00,0x00,0x06,0x12}, /* 720x576x16 */
+ {0x35,0x0a1f,0x0a0d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x11}, /* 720x480x32 */
+ {0x36,0x2a1f,0x0a0e,0x3b8c,0x0000,0x08,0x0e,0x00,0x00,0x06,0x12}, /* 720x576x32 */
+ {0x37,0x0212,0x0508,0x3aab,0x0104,0x08,0x08,0x00,0x00,0x08,0x13}, /* 1024x768x? */
+ {0x38,0x0a1b,0x0508,0x3aab,0x0105,0x08,0x08,0x00,0x00,0x08,0x13}, /* 1024x768x8 */
+/* {0x38,0x021b,0x0508,0x3aab,0x0105,0x08,0x08,0x00,0x00,0x00,0x13}, */ /* 1024x768x8 - 650/LVDS BIOS (no CRt2Mode) */
+ {0x3a,0x0e3b,0x0609,0x3adc,0x0107,0x08,0x09,0x00,0x00,0x00,0x1a}, /* 1280x1024x8 */
+/* {0x3a,0x063b,0x0609,0x3adc,0x0107,0x08,0x09,0x00,0x00,0x00,0x1a}, */ /* 1280x1024x8 - 650/LVDS BIOS*/
+ {0x3c,0x0e3b,0x070a,0x3af2,0x0130,0x08,0x0a,0x00,0x00,0x00,0x1e}, /* 1600x1200x8 */
+/* {0x3c,0x063b,0x070a,0x3af2,0x0130,0x08,0x0a,0x00,0x00,0x00,0x1e}, */ /* 1600x1200x8 - 650/LVDS BIOS */
+ {0x3d,0x067d,0x070a,0x3af2,0x0131,0x08,0x0a,0x00,0x00,0x00,0x1e}, /* 1600x1200x16 - 650/301LVx - no CRT2Mode? */
+ {0x40,0x9a1c,0x0000,0x3a34,0x010d,0x08,0x00,0x00,0x00,0x04,0x25},
+ {0x41,0x9a1d,0x0000,0x3a34,0x010e,0x08,0x00,0x00,0x00,0x04,0x25},
+ {0x43,0x0a1c,0x0306,0x3a57,0x0110,0x08,0x06,0x00,0x00,0x05,0x08},
+ {0x44,0x0a1d,0x0306,0x3a57,0x0111,0x08,0x06,0x00,0x00,0x05,0x08}, /* 640x480x16 */
+ {0x46,0x2a1c,0x0407,0x3a81,0x0113,0x08,0x07,0x00,0x00,0x07,0x00},
+ {0x47,0x2a1d,0x0407,0x3a81,0x0114,0x08,0x07,0x00,0x00,0x07,0x00}, /* 800x600x16 */
+ {0x49,0x0a3c,0x0508,0x3aab,0x0116,0x08,0x08,0x00,0x00,0x00,0x13},
+ {0x4a,0x0a3d,0x0508,0x3aab,0x0117,0x08,0x08,0x00,0x00,0x08,0x13}, /* 1024x768x16 */
+ {0x4c,0x0e7c,0x0609,0x3adc,0x0119,0x08,0x09,0x00,0x00,0x00,0x1a},
+ {0x4d,0x0e7d,0x0609,0x3adc,0x011a,0x08,0x09,0x00,0x00,0x00,0x1a}, /* 1280x1024x16 */
+ {0x50,0x9a1b,0x0001,0x3a3b,0x0132,0x08,0x01,0x00,0x00,0x04,0x26},
+/* {0x50,0x921b,0x0001,0x3a3b,0x0132,0x08,0x01,0x00,0x00,0x04,0x26}, */ /* 650/LVDS BIOS */
+ {0x51,0xba1b,0x0103,0x3a42,0x0133,0x08,0x03,0x00,0x00,0x07,0x27},
+/* {0x52,0x9a1b,0x0204,0x3a49,0x0134,0x08,0x04,0x00,0x00,0x00,0x28}, */
+ {0x52,0xba1b,0x0204,0x3a49,0x0134,0x08,0x04,0x00,0x00,0x00,0x28}, /* 650/301 BIOS */
+/* {0x52,0xb21b,0x0204,0x3a49,0x0134,0x08,0x04,0x00,0x00,0x00,0x28}, */ /* 650/LVDS BIOS (no CRT2Mode) */
+ {0x56,0x9a1d,0x0001,0x3a3b,0x0135,0x08,0x01,0x00,0x00,0x04,0x26},
+ {0x57,0xba1d,0x0103,0x3a42,0x0136,0x08,0x03,0x00,0x00,0x07,0x27},
+/* {0x58,0x9a1d,0x0204,0x3a49,0x0137,0x08,0x04,0x00,0x00,0x00,0x28}, */
+ {0x58,0xba1d,0x0204,0x3a49,0x0137,0x08,0x04,0x00,0x00,0x00,0x28}, /* BIOS (301+LVDS) */
+ {0x59,0x9a1b,0x0000,0x3a34,0x0138,0x08,0x00,0x00,0x00,0x04,0x25},
+/* {0x59,0x921b,0x0000,0x3a34,0x0138,0x08,0x00,0x00,0x00,0x04,0x25}, */ /* 650/LVDS BIOS (no CRT2Mode) */
+ {0x5A,0x021b,0x0014,0x3b83,0x0138,0x08,0x01,0x00,0x00,0x04,0x3f}, /* 320x480x8 fstn add new mode*/
+ {0x5B,0x0a1d,0x0014,0x3b83,0x0135,0x08,0x01,0x00,0x00,0x04,0x3f}, /* 320x480x16 fstn add new mode*/
+ {0x5c,0xba1f,0x0204,0x3a49,0x0000,0x08,0x04,0x00,0x00,0x00,0x28}, /* TW: inserted 512x384x32 */
+ {0x5d,0x0a1d,0x0305,0x3a50,0x0139,0x08,0x05,0x00,0x00,0x07,0x10},
+ {0x5e,0x0a1f,0x0305,0x3a50,0x0000,0x08,0x05,0x00,0x00,0x07,0x10}, /* TW: Inserted 640x400x32 */
+ {0x62,0x0a3f,0x0306,0x3a57,0x013a,0x08,0x06,0x00,0x00,0x05,0x08}, /* 640x480x32 */
+ {0x63,0x2a3f,0x0407,0x3a81,0x013b,0x08,0x07,0x00,0x00,0x07,0x00}, /* 800x600x32 */
+ {0x64,0x0a7f,0x0508,0x3aab,0x013c,0x08,0x08,0x00,0x00,0x08,0x13}, /* 1024x768x32 */
+ {0x65,0x0eff,0x0609,0x3adc,0x013d,0x08,0x09,0x00,0x00,0x00,0x1a}, /* 1280x1024x32 */
+ {0x66,0x06ff,0x070a,0x3af2,0x013e,0x08,0x0a,0x00,0x00,0x00,0x1e}, /* 1600x1200x32 */
+ {0x68,0x067b,0x080b,0x3b17,0x013f,0x08,0x0b,0x00,0x00,0x00,0x29}, /* 1920x1440x8 */
+ {0x69,0x06fd,0x080b,0x3b17,0x0140,0x08,0x0b,0x00,0x00,0x00,0x29}, /* 1920x1440x16 */
+ {0x6b,0x07ff,0x080b,0x3b17,0x0141,0x10,0x0b,0x00,0x00,0x00,0x29}, /* 1920x1440x32 */
+ {0x6c,0x067b,0x090c,0x3b37,0x0000,0x08,0x0c,0x00,0x00,0x00,0x2f}, /* 2048x1536x8 */
+ {0x6d,0x06fd,0x090c,0x3b37,0x0000,0x10,0x0c,0x00,0x00,0x00,0x2f}, /* 2048x1536x16 */
+ {0x6e,0x07ff,0x090c,0x3b37,0x0000,0x10,0x0c,0x00,0x00,0x00,0x2f}, /* 2048x1536x32 */
+ {0x70,0x2a1b,0x0410,0x3b52,0x0000,0x08,0x10,0x00,0x00,0x07,0x34}, /* 800x480x8 */
+ {0x71,0x0a1b,0x0511,0x3b63,0x0000,0x08,0x11,0x00,0x00,0x00,0x37}, /* 1024x576x8 */
+ {0x74,0x0a1d,0x0511,0x3b63,0x0000,0x08,0x11,0x00,0x00,0x00,0x37}, /* 1024x576x16 */
+ {0x75,0x0a3d,0x0612,0x3b74,0x0000,0x08,0x12,0x00,0x00,0x00,0x3a}, /* 1280x720x16 */
+ {0x76,0x2a1f,0x0410,0x3b52,0x0000,0x08,0x10,0x00,0x00,0x07,0x34}, /* 800x480x32 */
+ {0x77,0x0a1f,0x0511,0x3b63,0x0000,0x08,0x11,0x00,0x00,0x00,0x37}, /* 1024x576x32 */
+ {0x78,0x0a3f,0x0612,0x3b74,0x0000,0x08,0x12,0x00,0x00,0x00,0x3a}, /* 1280x720x32 */
+ {0x79,0x0a3b,0x0612,0x3b74,0x0000,0x08,0x12,0x00,0x00,0x00,0x3a}, /* 1280x720x8 */
+ {0x7a,0x2a1d,0x0410,0x3b52,0x0000,0x08,0x10,0x00,0x00,0x07,0x34}, /* 800x480x16 */
+ {0x7c,0x0e3b,0x060f,0x3ad0,0x0000,0x08,0x0f,0x00,0x00,0x00,0x3d}, /* 1280x960x8 - TW */
+ {0x7d,0x0e7d,0x060f,0x3ad0,0x0000,0x08,0x0f,0x00,0x00,0x00,0x3d}, /* 1280x960x16 - TW */
+ {0x7e,0x0eff,0x060f,0x3ad0,0x0000,0x08,0x0f,0x00,0x00,0x00,0x3d}, /* 1280x960x32 - TW */
+ /* TW: 650/LVDS BIOS new modes */
+/* {0x23,0x063b,0x0614,0x36f7,0x0000,0x08,0x14,0x00,0x00,0x00,0x40}, */ /* 1280x768x8 - 650/LVDS BIOS */
+ {0x23,0x0e3b,0x0614,0x36f7,0x0000,0x08,0x14,0x00,0x00,0x00,0x40}, /* 1280x768x8 */
+ {0x24,0x0e7d,0x0614,0x36f7,0x0000,0x08,0x14,0x00,0x00,0x00,0x40}, /* 1280x768x16 */
+ {0x25,0x0eff,0x0614,0x36f7,0x0000,0x08,0x14,0x00,0x00,0x00,0x40}, /* 1280x768x32 */
+ {0x26,0x0e3b,0x0c15,0x36fe,0x0000,0x08,0x15,0x00,0x00,0x00,0x41}, /* 1400x1050x8 */
+/* {0x26,0x063b,0x0c15,0x36fe,0x0000,0x08,0x15,0x00,0x00,0x00,0x41}, */ /* 1400x1050x8 - 650/LVDS BIOS */
+ {0x27,0x0e7d,0x0c15,0x36fe,0x0000,0x08,0x15,0x00,0x00,0x00,0x41}, /* 1400x1050x16 */
+ {0x28,0x0eff,0x0c15,0x36fe,0x0000,0x08,0x15,0x00,0x00,0x00,0x41}, /* 1400x1050x32*/
+ {0x29,0x0e1b,0x0d16,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x43}, /* TW: NEW 1152x864 - not in BIOS */
+ {0x2a,0x0e3d,0x0d16,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x43},
+ {0x2b,0x0e7f,0x0d16,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x43},
+ {0x39,0x2a1b,0x0b17,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x45}, /* TW: NEW 848x480 - not in BIOS */
+ {0x3b,0x2a3d,0x0b17,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x45},
+ {0x3e,0x2a7f,0x0b17,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x45},
+ {0x3f,0x2a1b,0x0b13,0x0000,0x0000,0x08,0x13,0x00,0x00,0x00,0x47}, /* TW: NEW 856x480 - not in BIOS */
+ {0x42,0x2a3d,0x0b13,0x0000,0x0000,0x08,0x13,0x00,0x00,0x00,0x47},
+ {0x45,0x2a7f,0x0b13,0x0000,0x0000,0x08,0x13,0x00,0x00,0x00,0x47},
+ {0x48,0x2a1b,0x0e18,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x49}, /* TW: NEW 1360x768 - not in BIOS */
+ {0x4b,0x2a3d,0x0e18,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x49},
+ {0x4e,0x2a7f,0x0e18,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x49},
+ {0xff,0x0000,0x0000,0x0000,0x0000,0x00,0x00,0x00,0x00,0x00,0x00}
+};
+
+typedef struct _SiS310_Ext2Struct
+{
+ USHORT Ext_InfoFlag;
+ UCHAR Ext_CRT1CRTC;
+ UCHAR Ext_CRTVCLK;
+ UCHAR Ext_CRT2CRTC;
+ UCHAR ModeID;
+ USHORT XRes;
+ USHORT YRes;
+ USHORT ROM_OFFSET;
+} SiS310_Ext2Struct;
+
+static const SiS310_Ext2Struct SiS310_RefIndex[]=
+{
+/* {0x005f,0x0d,0x03,0x05,0x6a, 800, 600,0x3a81}, 0x0 - TW: Patch for Chrontel 7019 */
+ {0x085f,0x0d,0x03,0x05,0x6a, 800, 600,0x3a81}, /* 0x0 */
+ {0x0467,0x0e,0x04,0x05,0x6a, 800, 600,0x3a86}, /* 0x1 */
+ {0x0067,0x0f,0x08,0x48,0x6a, 800, 600,0x3a8b}, /* 0x2 */
+ {0x0067,0x10,0x07,0x8b,0x6a, 800, 600,0x3a90}, /* 0x3 */
+ {0x0147,0x11,0x0a,0x00,0x6a, 800, 600,0x3a95}, /* 0x4 */
+ {0x0147,0x12,0x0d,0x00,0x6a, 800, 600,0x3a9a}, /* 0x5 - 4147 TW: Test sync change */
+ {0x0047,0x13,0x13,0x00,0x6a, 800, 600,0x3a9f}, /* 0x6 - 4047 */
+ {0x0047,0x14,0x1c,0x00,0x6a, 800, 600,0x3aa4}, /* 0x7 - 4047 */
+/* {0xc05f,0x05,0x00,0x04,0x2e, 640, 480,0x3a57}, 0x8 - TW: Patch for Chrontel 7019 */
+ {0xc85f,0x05,0x00,0x04,0x2e, 640, 480,0x3a57}, /* 0x8 */
+ {0xc067,0x06,0x02,0x04,0x2e, 640, 480,0x3a5c}, /* 0x9 */
+ {0xc067,0x07,0x02,0x47,0x2e, 640, 480,0x3a61}, /* 0xa */
+ {0xc067,0x08,0x03,0x8a,0x2e, 640, 480,0x3a66}, /* 0xb */
+ {0xc047,0x09,0x05,0x00,0x2e, 640, 480,0x3a6b}, /* 0xc - 4047 */
+ {0xc047,0x0a,0x09,0x00,0x2e, 640, 480,0x3a70}, /* 0xd - 4047 */
+ {0xc047,0x0b,0x0e,0x00,0x2e, 640, 480,0x3a75}, /* 0xe - 4047 */
+ {0xc047,0x0c,0x15,0x00,0x2e, 640, 480,0x3a7a}, /* 0xf */
+ {0x407f,0x04,0x00,0x00,0x2f, 640, 400,0x3a50}, /* 0x10 */
+ {0xc00f,0x3c,0x01,0x06,0x31, 720, 480,0x3b85}, /* 0x11 */
+ {0x000f,0x3d,0x03,0x06,0x32, 720, 576,0x3b8c}, /* 0x12 */
+ {0x0187,0x15,0x06,0x00,0x37,1024, 768,0x3aab}, /* 0x13 */
+ {0xc877,0x16,0x0b,0x06,0x37,1024, 768,0x3ab0}, /* 0x14 301b TV1024x768*/
+ {0xc067,0x17,0x0f,0x49,0x37,1024, 768,0x3ab5}, /* 0x15 */
+ {0x0267,0x18,0x11,0x00,0x37,1024, 768,0x3aba}, /* 0x16 */
+ {0x0047,0x19,0x16,0x8c,0x37,1024, 768,0x3abf}, /* 0x17 */
+ {0x0047,0x1a,0x1b,0x00,0x37,1024, 768,0x3ac4}, /* 0x18 - 4047 */
+ {0x0047,0x1b,0x1f,0x00,0x37,1024, 768,0x3ac9}, /* 0x19 - 4047 */
+ {0x0387,0x1c,0x11,0x00,0x3a,1280,1024,0x3adc}, /* 0x1a */
+ {0x0077,0x1d,0x19,0x07,0x3a,1280,1024,0x3ae1}, /* 0x1b */
+ {0x0047,0x1e,0x1e,0x00,0x3a,1280,1024,0x3ae6}, /* 0x1c */
+ {0x0007,0x1f,0x20,0x00,0x3a,1280,1024,0x3aeb}, /* 0x1d */
+ {0x0007,0x20,0x21,0x00,0x3c,1600,1200,0x3af2}, /* 0x1e */
+ {0x0007,0x21,0x22,0x00,0x3c,1600,1200,0x3af7}, /* 0x1f */
+ {0x0007,0x22,0x23,0x00,0x3c,1600,1200,0x3afc}, /* 0x20 */
+ {0x0007,0x23,0x25,0x00,0x3c,1600,1200,0x3b01}, /* 0x21 */
+ {0x0007,0x24,0x26,0x00,0x3c,1600,1200,0x3b06}, /* 0x22 */
+ {0x0007,0x25,0x2c,0x00,0x3c,1600,1200,0x3b0b}, /* 0x23 */
+ {0x0007,0x26,0x34,0x00,0x3c,1600,1200,0x3b10}, /* 0x24 */
+ {0x407f,0x00,0x00,0x00,0x40, 320, 200,0x3a34}, /* 0x25 */
+ {0xc07f,0x01,0x00,0x04,0x50, 320, 240,0x3a3b}, /* 0x26 */
+ {0x007f,0x02,0x04,0x05,0x51, 400, 300,0x3a42}, /* 0x27 */
+ {0xc077,0x03,0x0b,0x06,0x52, 512, 384,0x3a49}, /* 0x28 */
+ {0x8007,0x27,0x27,0x00,0x68,1920,1440,0x3b17}, /* 0x29 */
+ {0x4007,0x28,0x29,0x00,0x68,1920,1440,0x3b1c}, /* 0x2a */
+ {0x4007,0x29,0x2e,0x00,0x68,1920,1440,0x3b21}, /* 0x2b */
+ {0x4007,0x2a,0x30,0x00,0x68,1920,1440,0x3b26}, /* 0x2c */
+ {0x4007,0x2b,0x35,0x00,0x68,1920,1440,0x3b2b}, /* 0x2d */
+ {0x4005,0x2c,0x39,0x00,0x68,1920,1440,0x3b30}, /* 0x2e */
+ {0x4007,0x2d,0x2b,0x00,0x6c,2048,1536,0x3b37}, /* 0x2f */
+ {0x4007,0x2e,0x31,0x00,0x6c,2048,1536,0x3b3c}, /* 0x30 */
+ {0x4007,0x2f,0x33,0x00,0x6c,2048,1536,0x3b41}, /* 0x31 */
+ {0x4007,0x30,0x37,0x00,0x6c,2048,1536,0x3b46}, /* 0x32 */
+ {0x4005,0x31,0x38,0x00,0x6c,2048,1536,0x3b4b}, /* 0x33 */
+ {0x0057,0x32,0x40,0x08,0x70, 800, 480,0x3b52}, /* 0x34 */
+ {0x0047,0x33,0x07,0x08,0x70, 800, 480,0x3b57}, /* 0x35 */
+ {0x0047,0x34,0x0a,0x08,0x70, 800, 480,0x3b5c}, /* 0x36 */
+ {0x0057,0x35,0x0b,0x09,0x71,1024, 576,0x3b63}, /* 0x37 */
+ {0x0047,0x36,0x11,0x09,0x71,1024, 576,0x3b68}, /* 0x38 */
+ {0x0047,0x37,0x16,0x09,0x71,1024, 576,0x3b6d}, /* 0x39 */
+ {0x0057,0x38,0x19,0x0a,0x75,1280, 720,0x3b74}, /* 0x3a */
+ {0x0047,0x39,0x1e,0x0a,0x75,1280, 720,0x3b79}, /* 0x3b */
+ {0x0047,0x3a,0x20,0x0a,0x75,1280, 720,0x3b7e}, /* 0x3c */
+ {0x0027,0x3b,0x19,0x08,0x7c,1280, 960,0x3ad0}, /* 0x3d */
+ {0x0047,0x4c,0x59,0x08,0x7c,1280, 960,0x3ad0}, /* 0x3e */
+ {0xc07f,0x01,0x00,0x06,0x5a, 320, 480,0x3b83}, /* 0x3f */ /* FSTN mode */
+ {0x0077,0x42,0x12,0x07,0x23,1280, 768,0x0000}, /* 0x40 */ /* TW: 650/LVDS/301LVx new mode */
+ {0x0067,0x43,0x4d,0x08,0x26,1400,1050,0x0000}, /* 0x41 */ /* TW: 650/LVDS/301LVx new mode */
+ {0x0067,0x4b,0x5a,0x08,0x26,1400,1050,0x0000}, /* 0x42 */ /* TW: new, not in any BIOS */
+ {0x0047,0x44,0x19,0x06,0x29,1152, 864,0x0000}, /* 0x43 TW: Non-BIOS, new */
+ {0x0047,0x4a,0x1e,0x06,0x29,1152, 864,0x0000}, /* 0x44 TW: Non-BIOS, new */
+ {0x00c7,0x45,0x57,0x00,0x39, 848, 480,0x0000}, /* 0x45 TW: 848x480-38Hzi - Non-BIOS, new */
+ {0xc047,0x46,0x55,0x00,0x39, 848, 480,0x0000}, /* 0x46 TW: 848x480-60Hz - Non-BIOS, new */
+ {0x00c7,0x47,0x57,0x00,0x3f, 856, 480,0x0000}, /* 0x47 TW: 856x480-38Hzi - Non-BIOS, new */
+ {0xc047,0x48,0x57,0x00,0x3f, 856, 480,0x0000}, /* 0x48 TW: 856x480-60Hz - Non-BIOS, new */
+ {0x0047,0x49,0x58,0x00,0x48,1360, 768,0x0000}, /* 0x49 TW: 1360x768-60Hz - Non-BIOS, new */
+ {0xffff,0x00,0x00,0x00,0x00, 0, 0,0x0000}
+};
+
+typedef struct _SiS310_CRT1TableStruct
+{
+ UCHAR CR[17];
+} SiS310_CRT1TableStruct;
+
+static const SiS310_CRT1TableStruct SiS310_CRT1Table[]=
+{
+ {{0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
+ 0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x00,
+ 0x00}}, /* 0x0 */
+ {{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e,
+ 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00,
+ 0x00}}, /* 0x1 */
+ {{0x3d,0x31,0x31,0x81,0x37,0x1f,0x72,0xf0,
+ 0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x05,
+ 0x01}}, /* 0x2 */
+ {{0x4f,0x3f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+ 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x01,
+ 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 */
+ 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 */
+ 0xe8,0x8a,0xdf,0xe7,0x07,0x00,0x00,0x01,
+ 0x00}},
+ {{0x64,0x4f,0x4f,0x88,0x55,0x9d,0xf2,0x1f,
+ 0xe0,0x83,0xdf,0xdf,0xf3,0x10,0x00,0x01,
+ 0x00}}, /* 0x7 */
+ {{0x63,0x4f,0x4f,0x87,0x5a,0x81,0xfb,0x1f,
+ 0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x05,
+ 0x00}}, /* 0x8 */
+ {{0x65,0x4f,0x4f,0x89,0x58,0x80,0xfb,0x1f,
+ 0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x05, /* TW: Corrected VBE */
+ 0x61}}, /* 0x9 */
+ {{0x65,0x4f,0x4f,0x89,0x58,0x80,0x01,0x3e,
+ 0xe0,0x83,0xdf,0xdf,0x02,0x00,0x00,0x05,
+ 0x61}}, /* 0xa */
+ {{0x67,0x4f,0x4f,0x8b,0x58,0x81,0x0d,0x3e,
+ 0xe0,0x83,0xdf,0xdf,0x0e,0x00,0x00,0x05, /* TW: Corrected VBE */
+ 0x61}}, /* 0xb */
+ {{0x65,0x4f,0x4f,0x89,0x57,0x9f,0xfb,0x1f,
+ 0xe6,0x8a,0xdf,0xdf,0xfc,0x10,0x00,0x01, /* TW: Corrected VDE, VBE */
+ 0x00}}, /* 0xc */
+ {{0x7b,0x63,0x63,0x9f,0x6a,0x93,0x6f,0xf0,
+ 0x58,0x8a,0x57,0x57,0x70,0x20,0x00,0x05,
+ 0x01}}, /* 0xd */
+ {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xf0,
+ 0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x06,
+ 0x01}}, /* 0xe */
+ {{0x7d,0x63,0x63,0x81,0x6e,0x1d,0x98,0xf0,
+ 0x7c,0x82,0x57,0x57,0x99,0x00,0x00,0x06,
+ 0x01}}, /* 0xf */
+ {{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xf0,
+ 0x58,0x8b,0x57,0x57,0x70,0x20,0x00,0x06,
+ 0x01}}, /* 0x10 */
+ {{0x7e,0x63,0x63,0x82,0x6b,0x13,0x75,0xf0,
+ 0x58,0x8b,0x57,0x57,0x76,0x20,0x00,0x06,
+ 0x01}}, /* 0x11 */
+ {{0x81,0x63,0x63,0x85,0x6d,0x18,0x7a,0xf0,
+ 0x58,0x8b,0x57,0x57,0x7b,0x20,0x00,0x06,
+ 0x61}}, /* 0x12 */
+ {{0x83,0x63,0x63,0x87,0x6e,0x19,0x81,0xf0,
+ 0x58,0x8b,0x57,0x57,0x82,0x20,0x00,0x06,
+ 0x61}}, /* 0x13 */
+ {{0x85,0x63,0x63,0x89,0x6f,0x1a,0x91,0xf0,
+ 0x58,0x8b,0x57,0x57,0x92,0x20,0x00,0x06,
+ 0x61}}, /* 0x14 */
+ {{0x99,0x7f,0x7f,0x9d,0x84,0x1a,0x96,0x1f,
+ 0x7f,0x83,0x7f,0x7f,0x97,0x10,0x00,0x02,
+ 0x00}}, /* 0x15 */
+ {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,
+ 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
+ 0x01}}, /* 0x16 */
+ {{0xa1,0x7f,0x7f,0x85,0x86,0x97,0x24,0xf5,
+ 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
+ 0x01}}, /* 0x17 */
+ {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf5,
+ 0x00,0x83,0xff,0xff,0x1f,0x10,0x00,0x02,
+ 0x01}}, /* 0x18 */
+ {{0xa7,0x7f,0x7f,0x8b,0x89,0x95,0x26,0xf5,
+ 0x00,0x83,0xff,0xff,0x27,0x10,0x00,0x02,
+ 0x01}}, /* 0x19 */
+ {{0xa9,0x7f,0x7f,0x8d,0x8c,0x9a,0x2c,0xf5,
+ 0x00,0x83,0xff,0xff,0x2d,0x14,0x00,0x02,
+ 0x62}}, /* 0x1a */
+ {{0xab,0x7f,0x7f,0x8f,0x8d,0x9b,0x35,0xf5,
+ 0x00,0x83,0xff,0xff,0x36,0x14,0x00,0x02,
+ 0x62}}, /* 0x1b */
+ {{0xcf,0x9f,0x9f,0x93,0xb2,0x01,0x14,0xba,
+ 0x00,0x83,0xff,0xff,0x15,0x00,0x00,0x03,
+ 0x00}}, /* 0x1c */
+ {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0x5a,
+ 0x00,0x83,0xff,0xff,0x29,0x09,0x00,0x07,
+ 0x01}}, /* 0x1d */
+ {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0x5a,
+ 0x00,0x83,0xff,0xff,0x29,0x09,0x00,0x07,
+ 0x01}}, /* 0x1e */
+ {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0x5a,
+ 0x00,0x83,0xff,0xff,0x2f,0x09,0x00,0x07,
+ 0x01}}, /* 0x1f */
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+ 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+ 0x00}}, /* 0x20 */
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+ 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+ 0x00}}, /* 0x21 @ 4084 */
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+ 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+ 0x00}}, /* 0x22 */
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+ 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+ 0x00}}, /* 0x23 */
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+ 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+ 0x00}}, /* 0x24 */
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+ 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+ 0x00}}, /* 0x25 */
+ {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
+ 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
+ 0x00}}, /* 0x26 */
+ {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
+ 0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
+ 0x00}}, /* 0x27 */
+ {{0x43,0xef,0xef,0x87,0x06,0x00,0xd4,0x1f,
+ 0xa0,0x83,0x9f,0x9f,0xd5,0x1f,0x41,0x05,
+ 0x63}}, /* 0x28 */
+ {{0x45,0xef,0xef,0x89,0x07,0x01,0xd9,0x1f,
+ 0xa0,0x83,0x9f,0x9f,0xda,0x1f,0x41,0x05,
+ 0x63}}, /* 0x29 */
+ {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
+ 0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
+ 0x00}}, /* 0x2a */
+ {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
+ 0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
+ 0x00}}, /* 0x2b */
+ {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
+ 0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
+ 0x00}}, /* 0x2c */
+ {{0x59,0xff,0xff,0x9d,0x17,0x13,0x33,0xba,
+ 0x00,0x83,0xff,0xff,0x34,0x0f,0x41,0x05,
+ 0x44}}, /* 0x2d */
+ {{0x5b,0xff,0xff,0x9f,0x18,0x14,0x38,0xba,
+ 0x00,0x83,0xff,0xff,0x39,0x0f,0x41,0x05,
+ 0x44}}, /* 0x2e */
+ {{0x5b,0xff,0xff,0x9f,0x18,0x14,0x3d,0xba,
+ 0x00,0x83,0xff,0xff,0x3e,0x0f,0x41,0x05,
+ 0x44}}, /* 0x2f */
+ {{0x5d,0xff,0xff,0x81,0x19,0x95,0x41,0xba,
+ 0x00,0x84,0xff,0xff,0x42,0x0f,0x41,0x05,
+ 0x44}}, /* 0x30 */
+ {{0x55,0xff,0xff,0x99,0x0d,0x0c,0x3e,0xba,
+ 0x00,0x84,0xff,0xff,0x3f,0x0f,0x41,0x05,
+ 0x00}}, /* 0x31 */
+ {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xba,
+ 0x27,0x8b,0xdf,0xdf,0x73,0x00,0x00,0x06,
+ 0x01}}, /* 0x32 */
+ {{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xba,
+ 0x26,0x89,0xdf,0xdf,0x6f,0x00,0x00,0x06,
+ 0x01}}, /* 0x33 */
+ {{0x7f,0x63,0x63,0x82,0x6b,0x13,0x75,0xba,
+ 0x29,0x8c,0xdf,0xdf,0x75,0x00,0x00,0x06,
+ 0x01}}, /* 0x34 */
+ {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf1,
+ 0xaf,0x85,0x3f,0x3f,0x25,0x30,0x00,0x02,
+ 0x01}}, /* 0x35 */
+ {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf1,
+ 0xad,0x81,0x3f,0x3f,0x1f,0x30,0x00,0x02,
+ 0x01}}, /* 0x36 */
+ {{0xa7,0x7f,0x7f,0x88,0x89,0x95,0x26,0xf1, /* TW: 95 was 15 - illegal HBE! */
+ 0xb1,0x85,0x3f,0x3f,0x27,0x30,0x00,0x02,
+ 0x01}}, /* 0x37 */
+ {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0xc4,
+ 0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07,
+ 0x01}}, /* 0x38 */
+ {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0xd4,
+ 0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07,
+ 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
+ {{0xdc,0x9f,0x9f,0x80,0xaf,0x9d,0xe6,0xff, /* 1280x960-60 - corrected */
+ 0xc0,0x83,0xbf,0xbf,0xe7,0x10,0x00,0x07,
+ 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 */
+ {{0x86,0x6a,0x6a,0x8a,0x74,0x06,0x8c,0x15,
+ 0x4f,0x83,0xef,0xef,0x8d,0x30,0x00,0x02,
+ 0x00}}, /* 0x3e */
+ {{0x81,0x6a,0x6a,0x85,0x70,0x00,0x0f,0x3e,
+ 0xeb,0x8e,0xdf,0xdf,0x10,0x00,0x00,0x02,
+ 0x00}}, /* 0x3f */
+ {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x1e,0xf1, /* TW: The following from 650/LVDS BIOS */
+ 0xae,0x85,0x57,0x57,0x1f,0x30,0x00,0x02,
+ 0x01}}, /* 0x40 */
+ {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,
+ 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
+ 0x01}}, /* 0x41 */
+ {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x20,0xf5,
+ 0x03,0x88,0xff,0xff,0x21,0x10,0x00,0x07,
+ 0x01}}, /* 0x42 */
+ {{0xe6,0xae,0xae,0x8a,0xbd,0x90,0x3d,0x10,
+ 0x1a,0x8d,0x19,0x19,0x3e,0x2f,0x00,0x03,
+ 0x00}}, /* 0x43 */
+ {{0xc3,0x8f,0x8f,0x87,0x9b,0x0b,0x82,0xef, /* TW: New, 1152x864-75, not in any BIOS */
+ 0x60,0x83,0x5f,0x5f,0x83,0x10,0x00,0x07,
+ 0x01}}, /* 0x44 */
+ {{0x86,0x69,0x69,0x8A,0x74,0x06,0x8C,0x15, /* TW: New, 848x480-38i, not in BIOS */
+ 0x4F,0x83,0xEF,0xEF,0x8D,0x30,0x00,0x02,
+ 0x00}}, /* 0x45 */
+#if 0
+ {{0x81,0x69,0x69,0x85,0x70,0x00,0x0F,0x3E, /* TW: New, 848x480-60, not in BIOS - incorrect for Philips panel */
+ 0xEB,0x8E,0xDF,0xDF,0x10,0x00,0x00,0x02,
+ 0x00}}, /* 0x46 */
+#endif
+ {{0x83,0x69,0x69,0x87,0x6f,0x1d,0x03,0x3E, /* TW: New, 848x480-60, not in BIOS */
+ 0xE5,0x8d,0xDF,0xe4,0x04,0x00,0x00,0x06,
+ 0x00}}, /* 0x46 */
+ {{0x86,0x6A,0x6A,0x8A,0x74,0x06,0x8C,0x15, /* TW: New, 856x480-38i, not in BIOS */
+ 0x4F,0x83,0xEF,0xEF,0x8D,0x30,0x00,0x02,
+ 0x00}}, /* 0x47 */
+ {{0x81,0x6A,0x6A,0x85,0x70,0x00,0x0F,0x3E, /* TW: New, 856x480-60, not in BIOS */
+ 0xEB,0x8E,0xDF,0xDF,0x10,0x00,0x00,0x02,
+ 0x00}}, /* 0x48 */
+ {{0xdd,0xa9,0xa9,0x81,0xb4,0x97,0x26,0xfd, /* TW: New, 1360x768-60, not in BIOS */
+ 0x01,0x8d,0xff,0x00,0x27,0x10,0x00,0x03,
+ 0x01}}, /* 0x49 */
+ {{0xd9,0x8f,0x8f,0x9d,0xba,0x0a,0x8a,0xff, /* TW: New, 1152x864-84, not in any BIOS */
+ 0x60,0x8b,0x5f,0x5f,0x8b,0x10,0x00,0x03,
+ 0x01}}, /* 0x4a */
+ {{0xea,0xae,0xae,0x8e,0xba,0x82,0x40,0x10, /* TW: New, 1400x1050-75, not in any BIOS */
+ 0x1b,0x87,0x19,0x1a,0x41,0x0f,0x00,0x03,
+ 0x00}}, /* 0x4b */
+ {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0xf1,0xff, /* TW: New, 1280x960-85, not in any BIOS */
+ 0xc0,0x83,0xbf,0xbf,0xf2,0x10,0x00,0x07,
+ 0x01}} /* 0x4c */
+};
+
+
+typedef struct _SiS310_MCLKDataStruct
+{
+ UCHAR SR28,SR29,SR2A;
+ USHORT CLOCK;
+} SiS310_MCLKDataStruct;
+
+static const SiS310_MCLKDataStruct SiS310_MCLKData_0_315[] =
+{
+ { 0x3b,0x22,0x01,143}, /* TW: Was { 0x5c,0x23,0x01,166}, */
+ { 0x5c,0x23,0x01,166},
+ { 0x5c,0x23,0x01,166},
+ { 0x5c,0x23,0x01,166},
+ { 0x5c,0x23,0x01,166},
+ { 0x5c,0x23,0x01,166},
+ { 0x5c,0x23,0x01,166},
+ { 0x5c,0x23,0x01,166}
+};
+
+static const SiS310_MCLKDataStruct SiS310_MCLKData_0_650[] = /* @ 0x54 */
+{
+ { 0x5a,0x64,0x82, 66},
+ { 0xb3,0x45,0x82, 83},
+ { 0x37,0x61,0x82,100},
+ { 0x37,0x22,0x82,133},
+ { 0x37,0x61,0x82,100},
+ { 0x37,0x22,0x82,133},
+ { 0x37,0x22,0x82,133},
+ { 0x37,0x22,0x82,133}
+};
+
+static const SiS310_MCLKDataStruct SiS310_MCLKData_0_330[] = /* @ 0x54 */
+{
+ { 0x5c,0x23,0x01,166},
+ { 0x5c,0x23,0x01,166},
+ { 0x7c,0x08,0x01,200},
+ { 0x79,0x06,0x01,250},
+ { 0x7c,0x08,0x01,200},
+ { 0x7c,0x08,0x01,200},
+ { 0x7c,0x08,0x01,200},
+ { 0x79,0x06,0x01,250}
+};
+
+static const SiS310_MCLKDataStruct SiS310_MCLKData_1[] = /* @ 0x155 */
+{
+ { 0x29,0x21,0x82,150},
+ { 0x5c,0x23,0x82,166},
+ { 0x65,0x23,0x82,183},
+ { 0x37,0x21,0x82,200},
+ { 0x37,0x22,0x82,133},
+ { 0x37,0x22,0x82,133},
+ { 0x37,0x22,0x82,133},
+ { 0x37,0x22,0x82,133}
+};
+
+typedef struct _SiS310_ECLKDataStruct
+{
+ UCHAR SR2E,SR2F,SR30;
+ USHORT CLOCK;
+} SiS310_ECLKDataStruct;
+
+static const SiS310_ECLKDataStruct SiS310_ECLKData[]=
+{
+ { 0x5c,0x23,0x01,166},
+ { 0x5c,0x23,0x01,166},
+ { 0x5c,0x23,0x01,166},
+ { 0x5c,0x23,0x01,166}
+};
+
+typedef struct _SiS310_VCLKDataStruct
+{
+ UCHAR SR2B,SR2C;
+ USHORT CLOCK;
+} SiS310_VCLKDataStruct;
+
+static const SiS310_VCLKDataStruct SiS310_VCLKData[]=
+{
+ { 0x1b,0xe1, 25}, /* 0x0 */ /* 650/LVDS BIOS: @ 0x5647 */
+ { 0x4e,0xe4, 28}, /* 0x1 */
+ { 0x57,0xe4, 31}, /* 0x2 */
+ { 0xc3,0xc8, 36}, /* 0x3 */
+ { 0x42,0xe2, 40}, /* 0x4 */
+ { 0xfe,0xcd, 43}, /* 0x5 */
+ { 0x5d,0xc4, 44}, /* 0x6 */
+ { 0x52,0xe2, 49}, /* 0x7 */
+ { 0x53,0xe2, 50}, /* 0x8 */
+ { 0x74,0x67, 52}, /* 0x9 */
+ { 0x6d,0x66, 56}, /* 0xa */
+ { 0x5a,0x64, 65}, /* 0xb */ /* TW: was 6c c3 - WRONG */
+ { 0x46,0x44, 67}, /* 0xc */
+ { 0xb1,0x46, 68}, /* 0xd */
+ { 0xd3,0x4a, 72}, /* 0xe */
+ { 0x29,0x61, 75}, /* 0xf */
+ { 0x6e,0x46, 76}, /* 0x10 */
+ { 0x2b,0x61, 78}, /* 0x11 */
+ { 0x31,0x42, 79}, /* 0x12 */
+ { 0xab,0x44, 83}, /* 0x13 */
+ { 0x46,0x25, 84}, /* 0x14 */
+ { 0x78,0x29, 86}, /* 0x15 */
+ { 0x62,0x44, 94}, /* 0x16 */
+ { 0x2b,0x41,104}, /* 0x17 */
+ { 0x3a,0x23,105}, /* 0x18 */
+ { 0x70,0x44,108}, /* 0x19 */
+ { 0x3c,0x23,109}, /* 0x1a */
+ { 0x5e,0x43,113}, /* 0x1b */
+ { 0xbc,0x44,116}, /* 0x1c */
+ { 0xe0,0x46,132}, /* 0x1d */
+ { 0x54,0x42,135}, /* 0x1e */
+ { 0xea,0x2a,139}, /* 0x1f */
+ { 0x41,0x22,157}, /* 0x20 */
+ { 0x70,0x24,162}, /* 0x21 */
+ { 0x30,0x21,175}, /* 0x22 */
+ { 0x4e,0x22,189}, /* 0x23 */
+ { 0xde,0x26,194}, /* 0x24 */
+ { 0x62,0x06,202}, /* 0x25 */
+ { 0x3f,0x03,229}, /* 0x26 */
+ { 0xb8,0x06,234}, /* 0x27 */
+ { 0x34,0x02,253}, /* 0x28 */
+ { 0x58,0x04,255}, /* 0x29 */
+ { 0x24,0x01,265}, /* 0x2a */
+ { 0x9b,0x02,267}, /* 0x2b */
+ { 0x70,0x05,270}, /* 0x2c */
+ { 0x25,0x01,272}, /* 0x2d */
+ { 0x9c,0x02,277}, /* 0x2e */
+ { 0x27,0x01,286}, /* 0x2f */
+ { 0x3c,0x02,291}, /* 0x30 */
+ { 0xef,0x0a,292}, /* 0x31 */
+ { 0xf6,0x0a,310}, /* 0x32 */
+ { 0x95,0x01,315}, /* 0x33 */
+ { 0xf0,0x09,324}, /* 0x34 */
+ { 0xfe,0x0a,331}, /* 0x35 */
+ { 0xf3,0x09,332}, /* 0x36 */
+ { 0xea,0x08,340}, /* 0x37 */
+ { 0xe8,0x07,376}, /* 0x38 */
+ { 0xde,0x06,389}, /* 0x39 */
+ { 0x52,0x2a, 54}, /* 0x3a */
+ { 0x52,0x6a, 27}, /* 0x3b */
+ { 0x62,0x24, 70}, /* 0x3c */
+ { 0x62,0x64, 70}, /* 0x3d */
+ { 0xa8,0x4c, 30}, /* 0x3e */
+ { 0x20,0x26, 33}, /* 0x3f */
+ { 0x31,0xc2, 39}, /* 0x40 */
+ /* TW: 650/LVDS BIOS @ 0x574b new: */
+ { 0x60,0x36, 30}, /* 0x41 */ /* Chrontel */
+ { 0x40,0x4a, 28}, /* 0x42 */ /* Chrontel */
+ { 0x9f,0x46, 44}, /* 0x43 */ /* Chrontel */
+ { 0x97,0x2c, 26}, /* 0x44 */
+ { 0x44,0xe4, 25}, /* 0x45 */ /* Chrontel */
+ { 0x7e,0x32, 47}, /* 0x46 */ /* Chrontel */
+ { 0x8a,0x24, 31}, /* 0x47 */ /* Chrontel */
+ { 0x97,0x2c, 26}, /* 0x48 */ /* Chrontel */
+ { 0xce,0x3c, 39}, /* 0x49 */
+ { 0x52,0x4a, 36}, /* 0x4a */ /* Chrontel */
+ { 0x34,0x61, 95}, /* 0x4b */
+ { 0x78,0x27,108}, /* 0x4c - was 102 */ /* TW: Last entry in 650/301 BIOS */
+ { 0x66,0x43,123}, /* 0x4d */ /* Modes 0x26-0x28 (1400x1050) */
+ { 0x41,0x4e, 21}, /* 0x4e */
+ { 0xa1,0x4a, 29}, /* 0x4f */ /* Chrontel */
+ { 0x19,0x42, 42}, /* 0x50 */
+ { 0x54,0x46, 58}, /* 0x51 */ /* Chrontel */
+ { 0x25,0x42, 61}, /* 0x52 */
+ { 0x44,0x44, 66}, /* 0x53 */ /* Chrontel */
+ { 0x3a,0x62, 70}, /* 0x54 */ /* Chrontel */
+ { 0x62,0xc6, 34}, /* 0x55 - added for 848x480-60 (not in any BIOS) */
+ { 0x6a,0xc6, 37}, /* 0x56 - added for 848x480-75 (not in any BIOS) - TEMP */
+ { 0xbf,0xc8, 35}, /* 0x57 - added for 856x480-38i,60 (not in any BIOS) */
+ { 0x30,0x23, 88}, /* 0x58 - added for 1360x768-62 (is 60Hz!) (not in any BIOS) - TEMP */
+ { 0x52,0x07,149}, /* 0x59 - added for 1280x960-85 (Not in any BIOS) */
+ { 0x56,0x07,156} /* 0x5a - added for 1400x1050-75 */
+};
+
+typedef struct _SiS310_VBVCLKDataStruct
+{
+ UCHAR Part4_A,Part4_B;
+ USHORT CLOCK;
+} SiS310_VBVCLKDataStruct;
+
+static const SiS310_VBVCLKDataStruct SiS310_VBVCLKData[]=
+{
+ { 0x1b,0xe1, 25}, /* 0x0 */ /* 650/LVDS BIOS: @ 0x579c */
+ { 0x4e,0xe4, 28}, /* 0x1 */
+ { 0x57,0xe4, 31}, /* 0x2 */
+ { 0xc3,0xc8, 36}, /* 0x3 */
+ { 0x42,0x47, 40}, /* 0x4 */
+ { 0xfe,0xcd, 43}, /* 0x5 */
+ { 0x5d,0xc4, 44}, /* 0x6 */
+ { 0x52,0x47, 49}, /* 0x7 */
+ { 0x53,0x47, 50}, /* 0x8 */
+ { 0x74,0x67, 52}, /* 0x9 */
+ { 0x6d,0x66, 56}, /* 0xa */
+ { 0x35,0x62, 65}, /* 0xb */ /* Was 0x5a,0x64 - 650/LVDS+301 bios: 35,62 */
+ { 0x46,0x44, 67}, /* 0xc */
+ { 0xb1,0x46, 68}, /* 0xd */
+ { 0xd3,0x4a, 72}, /* 0xe */
+ { 0x29,0x61, 75}, /* 0xf */
+ { 0x6d,0x46, 75}, /* 0x10 */
+ { 0x41,0x43, 78}, /* 0x11 */
+ { 0x31,0x42, 79}, /* 0x12 */
+ { 0xab,0x44, 83}, /* 0x13 */
+ { 0x46,0x25, 84}, /* 0x14 */
+ { 0x78,0x29, 86}, /* 0x15 */
+ { 0x62,0x44, 94}, /* 0x16 */
+ { 0x2b,0x22,104}, /* 0x17 */
+ { 0x49,0x24,105}, /* 0x18 */
+ { 0xf8,0x2f,108}, /* 0x19 */
+ { 0x3c,0x23,109}, /* 0x1a */
+ { 0x5e,0x43,113}, /* 0x1b */
+ { 0xbc,0x44,116}, /* 0x1c */
+ { 0xe0,0x46,132}, /* 0x1d */
+ { 0xd4,0x28,135}, /* 0x1e */
+ { 0xea,0x2a,139}, /* 0x1f */
+ { 0x41,0x22,157}, /* 0x20 */
+ { 0x70,0x24,162}, /* 0x21 */
+ { 0x30,0x21,175}, /* 0x22 */
+ { 0x4e,0x22,189}, /* 0x23 */
+ { 0xde,0x26,194}, /* 0x24 */
+ { 0x70,0x07,202}, /* 0x25 */
+ { 0x3f,0x03,229}, /* 0x26 */
+ { 0xb8,0x06,234}, /* 0x27 */
+ { 0x34,0x02,253}, /* 0x28 */
+ { 0x58,0x04,255}, /* 0x29 */
+ { 0x24,0x01,265}, /* 0x2a */
+ { 0x9b,0x02,267}, /* 0x2b */
+ { 0x70,0x05,270}, /* 0x2c */
+ { 0x25,0x01,272}, /* 0x2d */
+ { 0x9c,0x02,277}, /* 0x2e */
+ { 0x27,0x01,286}, /* 0x2f */
+ { 0x3c,0x02,291}, /* 0x30 */
+ { 0xef,0x0a,292}, /* 0x31 */
+ { 0xf6,0x0a,310}, /* 0x32 */
+ { 0x95,0x01,315}, /* 0x33 */
+ { 0xf0,0x09,324}, /* 0x34 */
+ { 0xfe,0x0a,331}, /* 0x35 */
+ { 0xf3,0x09,332}, /* 0x36 */
+ { 0xea,0x08,340}, /* 0x37 */
+ { 0xe8,0x07,376}, /* 0x38 */
+ { 0xde,0x06,389}, /* 0x39 */
+ { 0x52,0x2a, 54}, /* 0x3a */
+ { 0x52,0x6a, 27}, /* 0x3b */
+ { 0x62,0x24, 70}, /* 0x3c */
+ { 0x62,0x64, 70}, /* 0x3d */
+ { 0xa8,0x4c, 30}, /* 0x3e */
+ { 0x20,0x26, 33}, /* 0x3f */
+ { 0x31,0xc2, 39}, /* 0x40 */
+ /* TW: 650/LVDS+301 BIOS (@ 0x58a0 in LVDS) new: */
+ { 0x2e,0x48, 25}, /* 0x41 */
+ { 0x24,0x46, 25}, /* 0x42 */
+ { 0x26,0x64, 28}, /* 0x43 */
+ { 0x37,0x64, 40}, /* 0x44 */
+ { 0xa1,0x42,108}, /* 0x45 */
+ { 0x37,0x61,100}, /* 0x46 */
+ { 0x78,0x27,108} /* 0x47 */
+ /* --- 0x58bc --- */
+};
+
+static const UCHAR SiS310_ScreenOffset[] =
+{
+ 0x14,0x19,0x20,0x28,0x32,0x40,0x50,0x64,
+ 0x78,0x80,0x2d,0x35,0x57,0x48,0x55,
+ 0xff
+}; /* TW: Added 1400x1050, 1152x864, 848/856x480, 1360x768 */
+
+typedef struct _SiS310_StResInfoStruct
+{
+ USHORT HTotal;
+ USHORT VTotal;
+} SiS310_StResInfoStruct;
+
+static const SiS310_StResInfoStruct SiS310_StResInfo[]=
+{
+ { 640,400},
+ { 640,350},
+ { 720,400},
+ { 720,350},
+ { 640,480}
+};
+
+typedef struct _SiS310_ModeResInfoStruct
+{
+ USHORT HTotal;
+ USHORT VTotal;
+ UCHAR XChar;
+ UCHAR YChar;
+} SiS310_ModeResInfoStruct;
+
+static const SiS310_ModeResInfoStruct SiS310_ModeResInfo[] =
+{
+ { 320, 200, 8, 8}, /* 0x00 */
+ { 320, 240, 8, 8}, /* 0x01 */
+ { 320, 400, 8, 8}, /* 0x02 */
+ { 400, 300, 8, 8}, /* 0x03 */
+ { 512, 384, 8, 8}, /* 0x04 */
+ { 640, 400, 8,16}, /* 0x05 */
+ { 640, 480, 8,16}, /* 0x06 */
+ { 800, 600, 8,16}, /* 0x07 */
+ { 1024, 768, 8,16}, /* 0x08 */
+ { 1280,1024, 8,16}, /* 0x09 */
+ { 1600,1200, 8,16}, /* 0x0a */
+ { 1920,1440, 8,16}, /* 0x0b */
+ { 2048,1536, 8,16}, /* 0x0c */
+ { 720, 480, 8,16}, /* 0x0d */
+ { 720, 576, 8,16}, /* 0x0e */
+ { 1280, 960, 8,16}, /* 0x0f */
+ { 800, 480, 8,16}, /* 0x10 */
+ { 1024, 576, 8,16}, /* 0x11 */
+ { 1280, 720, 8,16}, /* 0x12 */
+ { 856, 480, 8,16}, /* 0x13 - TW: New, not in any BIOS */
+ { 1280, 768, 8,16}, /* 0x14 20; TW: New */
+ { 1400,1050, 8,16}, /* 0x15 21; TW: New */
+ { 1152, 864, 8,16}, /* 0x16 - TW: New, not in any BIOS */
+ { 848, 480, 8,16}, /* 0x17 - TW: New, not in any BIOS */
+ { 1360, 768, 8,16} /* 0x18 - TW: New, not in any BIOS */
+};
+
+static const UCHAR SiS310_OutputSelect = 0x40;
+
+static const UCHAR SiS310_SoftSetting = 0x30; /* TW: RAM setting */
+
+static const UCHAR SiS310_SR15[8][4]={
+ {0x00,0x04,0x60,0x60},
+ {0x0f,0x0f,0x0f,0x0f},
+ {0xba,0xba,0xba,0xba},
+ {0xa9,0xa9,0xac,0xac},
+ {0xa0,0xa0,0xa0,0xa8},
+ {0x00,0x00,0x02,0x02},
+ {0x30,0x30,0x40,0x40},
+ {0x00,0xa5,0xfb,0xf6}
+};
+
+#ifndef LINUX_XF86
+
+static UCHAR SiS310_SR07 = 0x18;
+
+static const UCHAR SiS310_CR40[5][4]={
+ {0x77,0x77,0x33,0x33},
+ {0x77,0x77,0x33,0x33},
+ {0x00,0x00,0x00,0x00},
+ {0x5b,0x5b,0x03,0x03},
+ {0x00,0x00,0xf0,0xf8}
+};
+
+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; /*301b*/
+static const USHORT SiS310_VideoSenseData2 = 0x0174;
+static const USHORT SiS310_YCSenseData2 = 0x016b;
+#endif
+
+static const UCHAR SiS310_NTSCPhase[] = {0x21,0xed,0xba,0x08}; /* TW: Was {0x21,0xed,0x8a,0x08}; */
+static const UCHAR SiS310_PALPhase[] = {0x2a,0x05,0xe3,0x00}; /* TW: Was {0x2a,0x05,0xd3,0x00}; */
+static const UCHAR SiS310_PALMPhase[] = {0x21,0xE4,0x2E,0x9B}; /* TW: palm*/
+static const UCHAR SiS310_PALNPhase[] = {0x21,0xF4,0x3E,0xBA}; /* TW: paln*/
+static const UCHAR SiS310_NTSCPhase2[] = {0x21,0xF0,0x7B,0xD6};
+static const UCHAR SiS310_PALPhase2[] = {0x2a,0x09,0x86,0xe9};
+static const UCHAR SiS310_PALMPhase2[] = {0x21,0xE6,0xEF,0xA4}; /* TW: palm 301b*/
+static const UCHAR SiS310_PALNPhase2[] = {0x21,0xF6,0x94,0x46}; /* TW: paln 301b*/
+static const UCHAR SiS310_SpecialPhase[] = {0x1e,0x8c,0x5c,0x7a};
+
+typedef struct _SiS310_LCDDataStruct
+{
+ USHORT RVBHCMAX;
+ USHORT RVBHCFACT;
+ USHORT VGAHT;
+ USHORT VGAVT;
+ USHORT LCDHT;
+ USHORT LCDVT;
+} SiS310_LCDDataStruct;
+
+static const SiS310_LCDDataStruct SiS310_StLCD1024x768Data[]=
+{
+ { 62, 25, 800, 546,1344, 806},
+ { 32, 15, 930, 546,1344, 806},
+ { 32, 15, 930, 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 SiS310_LCDDataStruct SiS310_ExtLCD1024x768Data[] = /* TW: Checked */
+{
+ { 12, 5, 896, 512,1344, 806},
+ { 12, 5, 896, 510,1344, 806},
+ { 32, 15,1008, 505,1344, 806},
+ { 32, 15,1008, 514,1344, 806},
+ { 12, 5, 896, 500,1344, 806},
+ { 42, 25,1024, 625,1344, 806},
+ { 1, 1,1344, 806,1344, 806},
+ { 12, 5, 896, 500,1344, 806},
+ { 42, 25,1024, 625,1344, 806},
+ { 1, 1,1344, 806,1344, 806},
+ { 12, 5, 896, 500,1344, 806},
+ { 42, 25,1024, 625,1344, 806},
+ { 1, 1,1344, 806,1344, 806}
+};
+
+static const SiS310_LCDDataStruct SiS310_St2LCD1024x768Data[] = /* TW: Checked */
+{
+ { 62, 25, 800, 546,1344, 806},
+ { 32, 15, 930, 546,1344, 806},
+/* { 32, 15, 930, 546,1344, 806}, */
+ { 62, 25, 800, 546,1344, 806}, /* TW: Different in 650/301LV BIOS */
+ { 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 SiS310_LCDDataStruct SiS310_StLCD1280x1024Data[] =
+{
+ { 22, 5, 800, 510,1650,1088},
+ { 22, 5, 800, 510,1650,1088},
+ { 176, 45, 900, 510,1650,1088},
+ { 176, 45, 900, 510,1650,1088},
+ { 22, 5, 800, 510,1650,1088},
+ { 13, 5,1024, 675,1560,1152},
+ { 16, 9,1266, 804,1688,1072},
+ { 1, 1,1688,1066,1688,1066}
+};
+
+static const SiS310_LCDDataStruct SiS310_ExtLCD1280x1024Data[] = /* TW: Checked */
+{
+ { 211, 60,1024, 501,1688,1066},
+ { 211, 60,1024, 508,1688,1066},
+ { 211, 60,1024, 501,1688,1066},
+ { 211, 60,1024, 508,1688,1066},
+ { 211, 60,1024, 500,1688,1066},
+ { 211, 75,1024, 625,1688,1066},
+ { 211, 120,1280, 798,1688,1066},
+ { 1, 1,1688,1066,1688,1066}
+};
+
+static const SiS310_LCDDataStruct SiS310_St2LCD1280x1024Data[] =
+{
+ { 22, 5, 800, 510,1650,1088},
+ { 22, 5, 800, 510,1650,1088},
+ { 176, 45, 900, 510,1650,1088},
+ { 176, 45, 900, 510,1650,1088},
+ { 22, 5, 800, 510,1650,1088},
+ { 13, 5,1024, 675,1560,1152},
+ { 16, 9,1266, 804,1688,1072},
+ { 1, 1,1688,1066,1688,1066}
+};
+
+static const SiS310_LCDDataStruct SiS310_NoScaleData1024x768[] = /* TW: Checked */
+{
+ { 1, 1,1344, 806,1344, 806},
+ { 1, 1,1344, 806,1344, 806},
+ { 1, 1,1344, 806,1344, 806},
+ { 1, 1,1344, 806,1344, 806},
+ { 1, 1,1344, 806,1344, 806},
+ { 1, 1,1344, 806,1344, 806},
+ { 1, 1,1344, 806,1344, 806},
+ { 1, 1,1344, 806,1344, 806}
+};
+
+static const SiS310_LCDDataStruct SiS310_NoScaleData1280x1024[] = /* TW: New; Checked */
+{
+ { 1, 1,1688,1066,1688,1066},
+ { 1, 1,1688,1066,1688,1066},
+ { 1, 1,1688,1066,1688,1066},
+ { 1, 1,1688,1066,1688,1066},
+ { 1, 1,1688,1066,1688,1066},
+ { 1, 1,1688,1066,1688,1066},
+ { 1, 1,1688,1066,1688,1066},
+ { 1, 1,1688,1066,1688,1066}
+};
+
+static const SiS310_LCDDataStruct SiS310_LCD1280x960Data[] =
+{
+ { 9, 2, 800, 500,1800,1000},
+ { 9, 2, 800, 500,1800,1000},
+ { 4, 1, 900, 500,1800,1000},
+ { 4, 1, 900, 500,1800,1000},
+ { 9, 2, 800, 500,1800,1000},
+ { 30, 11,1056, 625,1800,1000},
+ { 5, 3,1350, 800,1800,1000},
+ { 1, 1,1576,1050,1576,1050},
+ { 1, 1,1800,1000,1800,1000}
+};
+
+static const SiS310_LCDDataStruct SiS310_StLCD1400x1050Data[] = /* TW: New */
+{ /* TW: New from 1.11.6s */
+ { 211, 100, 2100, 408, 1688, 1066 },
+ { 211, 64, 1536, 358, 1688, 1066 },
+ { 211, 100, 2100, 408, 1688, 1066 },
+ { 211, 64, 1536, 358, 1688, 1066 },
+ { 211, 48, 840, 488, 1688, 1066 },
+ { 211, 72, 1008, 609, 1688, 1066 },
+ { 211, 128, 1400, 776, 1688, 1066 },
+ { 211, 205, 1680, 1041, 1688, 1066 },
+ { 1, 1, 1688, 1066, 1688, 1066 }
+};
+
+static const SiS310_LCDDataStruct SiS310_ExtLCD1400x1050Data[] = /* TW: New */
+{ /* TW: New from 1.11.6s */
+ { 211, 100, 2100, 408, 1688, 1066 },
+ { 211, 64, 1536, 358, 1688, 1066 },
+ { 211, 100, 2100, 408, 1688, 1066 },
+ { 211, 64, 1536, 358, 1688, 1066 },
+ { 211, 48, 840, 488, 1688, 1066 },
+ { 211, 72, 1008, 609, 1688, 1066 },
+ { 211, 128, 1400, 776, 1688, 1066 },
+ { 211, 205, 1680, 1041, 1688, 1066 },
+ { 1, 1, 1688, 1066, 1688, 1066 }
+};
+
+static const SiS310_LCDDataStruct SiS310_NoScaleData1400x1050[] = /* TW: New */
+{ /* TW: To be checked (BIOS uses 1280x1024 data, one line too short) */
+ { 1, 1, 1688, 1066, 1688, 1066 },
+ { 1, 1, 1688, 1066, 1688, 1066 },
+ { 1, 1, 1688, 1066, 1688, 1066 },
+ { 1, 1, 1688, 1066, 1688, 1066 },
+ { 1, 1, 1688, 1066, 1688, 1066 },
+ { 1, 1, 1688, 1066, 1688, 1066 },
+ { 1, 1, 1688, 1066, 1688, 1066 },
+ { 1, 1, 1688, 1066, 1688, 1066 },
+ { 1, 1, 1688, 1066, 1688, 1066 }
+};
+
+static const SiS310_LCDDataStruct SiS310_StLCD1600x1200Data[] = /* TW: New */
+{ /* TODO */
+ { 0, 0, 0, 0, 0, 0}
+};
+
+static const SiS310_LCDDataStruct SiS310_ExtLCD1600x1200Data[] = /* TW: New */
+{ /* TODO */
+ { 0, 0, 0, 0, 0, 0}
+};
+
+static const SiS310_LCDDataStruct SiS310_NoScaleData1600x1200[] = /* TW: New */
+{ /* TODO */
+ { 0, 0, 0, 0, 0, 0}
+};
+
+typedef struct _SiS310_TVDataStruct
+{
+ USHORT RVBHCMAX;
+ USHORT RVBHCFACT;
+ USHORT VGAHT;
+ USHORT VGAVT;
+ USHORT TVHDE;
+ USHORT TVVDE;
+ USHORT RVBHRS;
+ UCHAR FlickerMode;
+ USHORT HALFRVBHRS;
+ UCHAR RY1COE;
+ UCHAR RY2COE;
+ UCHAR RY3COE;
+ UCHAR RY4COE;
+} SiS310_TVDataStruct;
+
+static const SiS310_TVDataStruct SiS310_StPALData[]=
+{
+ { 1, 1, 864, 525,1270, 400, 100, 0, 760,0xf4,0xff,0x1c,0x22},
+ { 1, 1, 864, 525,1270, 350, 100, 0, 760,0xf4,0xff,0x1c,0x22},
+ { 1, 1, 864, 525,1270, 400, 0, 0, 720,0xf1,0x04,0x1f,0x18},
+ { 1, 1, 864, 525,1270, 350, 0, 0, 720,0xf4,0x0b,0x1c,0x0a},
+ { 1, 1, 864, 525,1270, 480, 50, 0, 760,0xf4,0xff,0x1c,0x22},
+ { 1, 1, 864, 525,1270, 600, 50, 0, 0,0xf4,0xff,0x1c,0x22}
+};
+
+static const SiS310_TVDataStruct SiS310_ExtPALData[] = /* TW: Verfied (1.10.7w) */
+{
+ { 27, 10, 848, 448,1270, 530, 50, 0, 50,0xf4,0xff,0x1c,0x22},
+ { 108, 35, 848, 398,1270, 530, 50, 0, 50,0xf4,0xff,0x1c,0x22},
+ { 12, 5, 954, 448,1270, 530, 50, 0, 50,0xf1,0x04,0x1f,0x18},
+ { 9, 4, 960, 463,1644, 438, 50, 0, 50,0xf4,0x0b,0x1c,0x0a},
+ { 9, 4, 848, 528,1270, 530, 0, 0, 50,0xf5,0xfb,0x1b,0x2a}, /* 640x480 */
+ { 36, 25,1060, 648,1316, 530, 438, 0, 438,0xeb,0x05,0x25,0x16}, /* 800x600 */
+ { 3, 2,1080, 619,1270, 540, 438, 0, 438,0xf3,0x00,0x1d,0x20}, /* 720x480/576 */
+ { 1, 1,1170, 821,1270, 520, 686, 0, 686,0xF3,0x00,0x1D,0x20} /* 1024x768 */
+};
+
+static const SiS310_TVDataStruct SiS310_StNTSCData[]=
+{
+ { 1, 1, 858, 525,1270, 400, 50, 0, 760,0xf1,0x04,0x1f,0x18},
+ { 1, 1, 858, 525,1270, 350, 50, 0, 640,0xf1,0x04,0x1f,0x18},
+ { 1, 1, 858, 525,1270, 400, 0, 0, 720,0xf1,0x04,0x1f,0x18},
+ { 1, 1, 858, 525,1270, 350, 0, 0, 720,0xf4,0x0b,0x1c,0x0a},
+ { 1, 1, 858, 525,1270, 480, 0, 0, 760,0xf1,0x04,0x1f,0x18}
+};
+
+static const SiS310_TVDataStruct SiS310_ExtNTSCData[]=
+{
+ { 143, 65, 858, 443,1270, 440, 171, 0, 171,0xf1,0x04,0x1f,0x18},
+ { 88, 35, 858, 393,1270, 440, 171, 0, 171,0xf1,0x04,0x1f,0x18},
+ { 143, 70, 924, 443,1270, 440, 92, 0, 92,0xf1,0x04,0x1f,0x18},
+ { 143, 70, 924, 393,1270, 440, 92, 0, 92,0xf4,0x0b,0x1c,0x0a},
+ { 143, 76, 836, 523,1270, 440, 224, 0, 0,0xf1,0x05,0x1f,0x16}, /* 640x480 */
+ { 143, 120,1056, 643,1270, 440, 0, 128, 0,0xf4,0x10,0x1c,0x00}, /* 800x600 */
+ { 2, 1, 858, 503,1270, 480, 0, 128, 0,0xee,0x0c,0x22,0x08}, /* 720x480/576 */
+ { 65, 64,1056, 791,1270, 480, 638, 0, 0,0xEE,0x0C,0x22,0x08} /* 1024x768 */
+};
+
+/* TW: These tables will need data ! */
+static const SiS310_TVDataStruct SiS310_St1HiTVData[]=
+{
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
+};
+
+static const SiS310_TVDataStruct SiS310_St2HiTVData[]=
+{
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
+};
+
+static const SiS310_TVDataStruct SiS310_ExtHiTVData[]=
+{
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
+};
+
+static const UCHAR SiS310_NTSCTiming[] = { /* TW: New (checked 1.09, 1.10.6s) */
+ 0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c,
+ 0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a,
+ 0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x1b,
+ 0x0c,0x50,0x00,0x97,0x00,0xda,0x4a,0x17,
+ 0x7d,0x05,0x4b,0x00,0x00,0xe2,0x00,0x02,
+ 0x03,0x0a,0x65,0x9d,0x08,0x92,0x8f,0x40,
+ 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x50,
+ 0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00
+};
+
+static const UCHAR SiS310_PALTiming[] = { /* TW: New (checked 1.09, 1.10.6s) */
+ 0x19,0x52,0x35,0x6e,0x04,0x38,0x3d,0x70,
+ 0x94,0x49,0x01,0x12,0x06,0x3e,0x35,0x6d,
+ 0x06,0x14,0x3e,0x35,0x6d,0x00,0x45,0x2b,
+ 0x70,0x50,0x00,0x9b,0x00,0xd9,0x5d,0x17,
+ 0x7d,0x05,0x45,0x00,0x00,0xe8,0x00,0x02,
+ 0x0d,0x00,0x68,0xb0,0x0b,0x92,0x8f,0x40,
+ 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x63,
+ 0x00,0x40,0x3e,0x00,0xe1,0x02,0x28,0x00
+};
+
+#ifdef oldHV
+static const UCHAR SiS310_HiTVExtTiming[] = { /* TW: New */
+ 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
+ 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
+ 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
+ 0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13,
+ 0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40,
+ 0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40,
+ 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d,
+ 0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00
+};
+
+static const UCHAR SiS310_HiTVSt1Timing[] = { /* TW: New */
+ 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
+ 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
+ 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
+ 0x65,0x90,0x7b,0xa8,0x03,0xf0,0x87,0x03,
+ 0x11,0x15,0x11,0xcf,0x10,0x11,0xcf,0x10,
+ 0x35,0x35,0x3b,0x69,0x1d,0x92,0x0f,0x40,
+ 0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x86,
+ 0xaf,0x5d,0x0e,0x00,0xfc,0xff,0x2d,0x00
+};
+
+static const UCHAR SiS310_HiTVSt2Timing[] = { /* TW: New */
+ 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
+ 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
+ 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
+ 0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13,
+ 0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40,
+ 0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40,
+ 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d,
+ 0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00
+};
+
+static const UCHAR SiS310_HiTVTextTiming[] = { /* TW: New */
+ 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
+ 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
+ 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
+ 0x65,0x90,0xe7,0xbc,0x03,0x0c,0x97,0x03,
+ 0x14,0x78,0x14,0x08,0x20,0x14,0x08,0x20,
+ 0xc8,0xc8,0x3b,0xd2,0x26,0x92,0x0f,0x40,
+ 0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x96,
+ 0x72,0x5c,0x11,0x00,0xfc,0xff,0x32,0x00
+};
+
+static const UCHAR SiS310_HiTVGroup3Data[] = { /* TW: New */
+ 0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x5f,
+ 0x05,0x21,0xb2,0xb2,0x55,0x77,0x2a,0xa6,
+ 0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
+ 0x8c,0x6e,0x60,0x2e,0x58,0x48,0x72,0x44,
+ 0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
+ 0x4f,0x7f,0x03,0xa8,0x7d,0x20,0x1a,0xa9,
+ 0x14,0x05,0x03,0x7e,0x64,0x31,0x14,0x75,
+ 0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
+};
+
+static const UCHAR SiS310_HiTVGroup3Simu[] = { /* TW: New */
+ 0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x95,
+ 0xdb,0x20,0xb8,0xb8,0x55,0x47,0x2a,0xa6,
+ 0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
+ 0x8c,0x6e,0x60,0x15,0x26,0xd3,0xe4,0x11,
+ 0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
+ 0x67,0x36,0x01,0x47,0x0e,0x10,0xbe,0xb4,
+ 0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75,
+ 0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
+};
+
+static const UCHAR SiS310_HiTVGroup3Text[] = { /* TW: New */
+ 0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0xa7,
+ 0xf5,0x20,0xce,0xce,0x55,0x47,0x2a,0xa6,
+ 0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
+ 0x8c,0x6e,0x60,0x18,0x2c,0x0c,0x20,0x22,
+ 0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
+ 0x93,0x3c,0x01,0x50,0x2f,0x10,0xf4,0xca,
+ 0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75,
+ 0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
+};
+#endif
+
+typedef struct _SiS310_PanelDelayTblStruct
+{
+ UCHAR timer[2];
+} SiS310_PanelDelayTblStruct;
+
+static const SiS310_PanelDelayTblStruct SiS310_PanelDelayTbl[]= /* TW: New */
+{
+ {{0x10,0x40}}, /* TW: from 650/301LVx 1.10.6s BIOS */
+ {{0x10,0x40}},
+ {{0x10,0x40}},
+ {{0x10,0x40}},
+ {{0x10,0x40}},
+ {{0x10,0x40}},
+ {{0x10,0x40}},
+ {{0x10,0x40}},
+ {{0x10,0x40}},
+ {{0x10,0x40}},
+ {{0x10,0x40}},
+ {{0x10,0x40}},
+ {{0x10,0x40}},
+ {{0x10,0x40}},
+ {{0x10,0x40}},
+ {{0x10,0x40}}
+#if 0
+ {{0x28,0xc8}}, /* TW: from 650/301LV BIOS */
+ {{0x28,0xc8}},
+ {{0x28,0xc8}},
+ {{0x28,0xc8}},
+ {{0x28,0xc8}},
+ {{0x28,0xc8}},
+ {{0x28,0xc8}},
+ {{0x28,0xc8}},
+ {{0x28,0xc8}},
+ {{0x28,0xc8}},
+ {{0x28,0xc8}},
+ {{0x28,0xc8}},
+ {{0x28,0xc8}},
+ {{0x28,0xc8}},
+ {{0x28,0xc8}},
+ {{0x28,0xc8}}
+#endif
+};
+
+static const SiS310_PanelDelayTblStruct SiS310_PanelDelayTblLVDS[]=
+{
+ {{0x28,0xc8}},
+ {{0x28,0xc8}},
+ {{0x28,0xc8}},
+ {{0x28,0xc8}},
+ {{0x28,0xc8}},
+ {{0x28,0xc8}},
+ {{0x28,0xc8}},
+ {{0x28,0xc8}},
+ {{0x28,0xc8}},
+ {{0x28,0xc8}},
+ {{0x28,0xc8}},
+ {{0x28,0xc8}},
+ {{0x28,0xc8}},
+ {{0x28,0xc8}},
+ {{0x28,0xc8}},
+ {{0x28,0xc8}}
+};
+
+typedef struct _SiS310_LVDSDataStruct
+{
+ USHORT VGAHT;
+ USHORT VGAVT;
+ USHORT LCDHT;
+ USHORT LCDVT;
+} SiS310_LVDSDataStruct;
+
+static const SiS310_LVDSDataStruct SiS310_LVDS320x480Data_1[]=
+{
+ {848, 433,400, 525},
+ {848, 389,400, 525},
+ {848, 433,400, 525},
+ {848, 389,400, 525},
+ {848, 518,400, 525},
+ {1056,628,400, 525},
+ {400, 525,400, 525},
+ {800, 449,1000, 644},
+ {800, 525,1000, 635}
+};
+
+static const SiS310_LVDSDataStruct SiS310_LVDS800x600Data_1[]= /* TW: New */
+{
+ {848, 433,1060, 629},
+ {848, 389,1060, 629},
+ {848, 433,1060, 629},
+ {848, 389,1060, 629},
+ {848, 518,1060, 629},
+ {1056, 628,1056, 628},
+ {1056, 628,1056, 628},
+ {800, 449,1000, 644},
+ {800, 525,1000, 635}
+};
+
+static const SiS310_LVDSDataStruct SiS310_LVDS800x600Data_2[]= /* TW: New */
+{
+ {1056, 628,1056, 628},
+ {1056, 628,1056, 628},
+ {1056, 628,1056, 628},
+ {1056, 628,1056, 628},
+ {1056, 628,1056, 628},
+ {1056, 628,1056, 628},
+ {1056, 628,1056, 628},
+ {800, 449,1000, 644},
+ {800, 525,1000, 635}
+};
+
+static const SiS310_LVDSDataStruct SiS310_LVDS1024x768Data_1[]= /* TW: New */
+{
+ {840, 438,1344, 806},
+ {840, 409,1344, 806},
+ {840, 438,1344, 806},
+ {840, 409,1344, 806},
+ {840, 518,1344, 806}, /* 640x480 */
+ {1050, 638,1344, 806}, /* 800x600 */
+ {1344, 806,1344, 806}, /* 1024x768 */
+ {800, 449,1280, 801},
+ {800, 525,1280, 813}
+};
+
+static const SiS310_LVDSDataStruct SiS310_LVDS1024x768Data_2[]= /* TW: New */
+{
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {800, 449,1280, 801},
+ {800, 525,1280, 813}
+};
+
+static const SiS310_LVDSDataStruct SiS310_LVDS1280x1024Data_1[]= /* TW: New - TODO */
+{ /* TW: Temp data, invalid (is identical to 1024x768) */
+ {840, 438,1344, 806},
+ {840, 409,1344, 806},
+ {840, 438,1344, 806},
+ {840, 409,1344, 806},
+ {840, 518,1344, 806},
+ {1050, 638,1344, 806},
+ {1344, 806,1344, 806},
+ {800, 449,1280, 801},
+ {800, 525,1280, 813}
+};
+
+static const SiS310_LVDSDataStruct SiS310_LVDS1280x1024Data_2[]= /* TW: New - TODO */
+{ /* TW: Temp data, invalid (is identical to 1024x768) */
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {800, 449,1280, 801},
+ {800, 525,1280, 813}
+};
+
+static const SiS310_LVDSDataStruct SiS310_LVDS1400x1050Data_1[]= /* TW: New */
+{
+ {928, 416, 1688, 1066},
+ {928, 366, 1688, 1066},
+ {928, 416, 1688, 1066},
+ {928, 366, 1688, 1066},
+ {928, 496, 1688, 1066},
+ {1088, 616, 1688, 1066},
+ {1312, 784, 1688, 1066},
+ {1568, 1040, 1688, 1066},
+ {1688, 1066, 1688, 1066}
+};
+
+static const SiS310_LVDSDataStruct SiS310_LVDS1400x1050Data_2[]= /* TW: New */
+{
+ {1688,1066, 1688,1066},
+ {1688,1066, 1688,1066},
+ {1688,1066, 1688,1066},
+ {1688,1066, 1688,1066},
+ {1688,1066, 1688,1066},
+ {1688,1066, 1688,1066},
+ {1688,1066, 1688,1066},
+ {1688,1066, 1688,1066},
+ {1688,1066, 1688,1066},
+};
+
+static const SiS310_LVDSDataStruct SiS310_LVDS1280x768Data_1[]= /* TW: New - TODO */
+{ /* TW: Temp data, invalid (is identical to 1024x768) */
+ {840, 438,1344, 806},
+ {840, 409,1344, 806},
+ {840, 438,1344, 806},
+ {840, 409,1344, 806},
+ {840, 518,1344, 806},
+ {1050, 638,1344, 806},
+ {1344, 806,1344, 806},
+ {800, 449,1280, 801},
+ {800, 525,1280, 813}
+};
+
+static const SiS310_LVDSDataStruct SiS310_LVDS1280x768Data_2[]= /* TW: New - TODO */
+{ /* TW: Temp data, invalid (is identical to 1024x768) */
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {800, 449,1280, 801},
+ {800, 525,1280, 813}
+};
+
+/* TW: New: - from 300 series */
+static const SiS310_LVDSDataStruct SiS310_LVDS1024x600Data_1[]=
+{
+ {840, 604,1344, 800},
+ {840, 560,1344, 800},
+ {840, 604,1344, 800},
+ {840, 560,1344, 800},
+ {840, 689,1344, 800},
+ {1050, 800,1344, 800},
+ {1344, 800,1344, 800},
+ {800, 449,1280, 801},
+ {800, 525,1280, 813}
+};
+
+/* TW: New: - from 300 series */
+static const SiS310_LVDSDataStruct SiS310_LVDS1024x600Data_2[]=
+{
+ {1344, 800,1344, 800},
+ {1344, 800,1344, 800},
+ {1344, 800,1344, 800},
+ {1344, 800,1344, 800},
+ {1344, 800,1344, 800},
+ {1344, 800,1344, 800},
+ {1344, 800,1344, 800},
+ {800, 449,1280, 801},
+ {800, 525,1280, 813}
+};
+
+/* TW: New: - from 300 series */
+static const SiS310_LVDSDataStruct SiS310_LVDS1152x768Data_1[]=
+{
+ {840, 438,1344, 806},
+ {840, 409,1344, 806},
+ {840, 438,1344, 806},
+ {840, 409,1344, 806},
+ {840, 518,1344, 806},
+ {1050, 638,1344, 806},
+ {1344, 806,1344, 806},
+ {800, 449,1280, 801},
+ {800, 525,1280, 813}
+};
+
+/* TW: New: - from 300 series */
+static const SiS310_LVDSDataStruct SiS310_LVDS1152x768Data_2[]=
+{
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {800, 449,1280, 801},
+ {800, 525,1280, 813}
+};
+
+/* TW: New in 650/LVDS BIOS - pass 1:1 data */
+static const SiS310_LVDSDataStruct SiS310_LVDSXXXxXXXData_1[]= /* TW: New */
+{
+ { 800, 449, 800, 449},
+ { 800, 449, 800, 449},
+ { 900, 449, 900, 449},
+ { 900, 449, 900, 449},
+ { 800, 525, 800, 525},
+ {1056, 628,1056, 628},
+ {1344, 806,1344, 806},
+ {1688, 806,1688, 806}
+};
+
+static const SiS310_LVDSDataStruct SiS310_LVDS640x480Data_1[]= /* TW: New */
+{
+ {800, 449, 800, 449},
+ {800, 449, 800, 449},
+ {800, 449, 800, 449},
+ {800, 449, 800, 449},
+ {800, 525, 800, 525},
+ {1056, 628,1056, 628},
+ {1056, 628,1056, 628},
+ {1056, 628,1056, 628},
+ {1056, 628,1056, 628}
+};
+
+static const SiS310_LVDSDataStruct SiS310_LVDS1280x960Data_1[]= /* TW: New */
+{
+ {840, 438,1344, 806},
+ {840, 409,1344, 806},
+ {840, 438,1344, 806},
+ {840, 409,1344, 806},
+ {840, 518,1344, 806},
+ {1050, 638,1344, 806},
+ {1344, 806,1344, 806},
+ {800, 449,1280, 801},
+ {800, 525,1280, 813}
+};
+
+static const SiS310_LVDSDataStruct SiS310_LVDS1280x960Data_2[]= /* TW: New */
+{
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {800, 449,1280, 801},
+ {800, 525,1280, 813}
+};
+
+static const SiS310_LVDSDataStruct SiS310_LCDA1400x1050Data_1[]= /* TW: New */
+{ /* TW: Might be temporary (invalid) data */
+ {928, 416, 1688, 1066},
+ {928, 366, 1688, 1066},
+ {1008, 416, 1688, 1066},
+ {1008, 366, 1688, 1066},
+ {1200, 530, 1688, 1066},
+ {1088, 616, 1688, 1066},
+ {1312, 784, 1688, 1066},
+ {1568, 1040, 1688, 1066},
+ {1688, 1066, 1688, 1066}
+};
+
+static const SiS310_LVDSDataStruct SiS310_LCDA1400x1050Data_2[]= /* TW: New */
+{ /* TW: Temporary data. Not valid */
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {800, 449,1280, 801},
+ {800, 525,1280, 813}
+};
+
+static const SiS310_LVDSDataStruct SiS310_LCDA1600x1200Data_1[]= /* TW: New */
+{ /* TW: Temporary data. Not valid */
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {800, 449,1280, 801},
+ {800, 525,1280, 813}
+};
+
+static const SiS310_LVDSDataStruct SiS310_LCDA1600x1200Data_2[]= /* TW: New */
+{ /* TW: Temporary data. Not valid */
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0}
+};
+
+static const SiS310_LVDSDataStruct SiS310_CHTVUNTSCData[]= /* TW: New */
+{
+ { 840, 600, 840, 600},
+ { 840, 600, 840, 600},
+ { 840, 600, 840, 600},
+ { 840, 600, 840, 600},
+ { 784, 600, 784, 600},
+ {1064, 750,1064, 750},
+ {1160, 945,1160, 945} /* TW: For Ch7019 1024 */
+};
+
+static const SiS310_LVDSDataStruct SiS310_CHTVONTSCData[]= /* TW: New */
+{
+ { 840, 525, 840, 525},
+ { 840, 525, 840, 525},
+ { 840, 525, 840, 525},
+ { 840, 525, 840, 525},
+ { 784, 525, 784, 525},
+ {1040, 700,1040, 700},
+ {1160, 840,1160, 840} /* TW: For Ch7019 1024 */
+};
+
+static const SiS310_LVDSDataStruct SiS310_CHTVUPALData[]= /* TW: New */
+{
+ {1008, 625,1008, 625},
+ {1008, 625,1008, 625},
+ {1008, 625,1008, 625},
+ {1008, 625,1008, 625},
+ { 840, 625, 840, 625},
+ { 960, 750, 960, 750},
+ {1400,1000,1400,1000} /* TW: For Ch7019 1024 */
+};
+
+static const SiS310_LVDSDataStruct SiS310_CHTVOPALData[]= /* TW: New */
+{
+ {1008, 625,1008, 625},
+ {1008, 625,1008, 625},
+ {1008, 625,1008, 625},
+ {1008, 625,1008, 625},
+ { 840, 625, 840, 625},
+ { 944, 625, 944, 625},
+ {1400, 875,1400, 875} /* TW: For Ch7019 1024 */
+};
+
+static const SiS310_LVDSDataStruct SiS310_CHTVUPALMData[]= /* TW: New */
+{
+ { 840, 600, 840, 600},
+ { 840, 600, 840, 600},
+ { 840, 600, 840, 600},
+ { 840, 600, 840, 600},
+ { 784, 600, 784, 600},
+ {1064, 750,1064, 750},
+ {1160, 945,1160, 945} /* TW: For Ch7019 1024 */
+};
+
+static const SiS310_LVDSDataStruct SiS310_CHTVOPALMData[]= /* TW: New */
+{
+ { 840, 525, 840, 525},
+ { 840, 525, 840, 525},
+ { 840, 525, 840, 525},
+ { 840, 525, 840, 525},
+ { 784, 525, 784, 525},
+ {1040, 700,1040, 700},
+ {1160, 840,1160, 840} /* TW: For Ch7019 1024 */
+};
+
+static const SiS310_LVDSDataStruct SiS310_CHTVUPALNData[]= /* TW: New */
+{
+ {1008, 625,1008, 625},
+ {1008, 625,1008, 625},
+ {1008, 625,1008, 625},
+ {1008, 625,1008, 625},
+ { 840, 625, 840, 625},
+ { 960, 750, 960, 750},
+ {1400,1000,1400,1000} /* TW: For Ch7019 1024 */
+};
+
+static const SiS310_LVDSDataStruct SiS310_CHTVOPALNData[]= /* TW: New */
+{
+ {1008, 625,1008, 625},
+ {1008, 625,1008, 625},
+ {1008, 625,1008, 625},
+ {1008, 625,1008, 625},
+ { 840, 625, 840, 625},
+ { 944, 625, 944, 625},
+ {1400, 875,1400, 875} /* TW: For Ch7019 1024 */
+};
+
+static const SiS310_LVDSDataStruct SiS310_CHTVSOPALData[]= /* TW: New (super overscan - no effect on 7019) */
+{
+ {1008, 625,1008, 625},
+ {1008, 625,1008, 625},
+ {1008, 625,1008, 625},
+ {1008, 625,1008, 625},
+ { 840, 625, 840, 625},
+ { 944, 625, 944, 625},
+ {1400, 875,1400, 875}
+};
+
+typedef struct _SiS310_LVDSDesStruct
+{
+ USHORT LCDHDES;
+ USHORT LCDVDES;
+} SiS310_LVDSDesStruct;
+
+/* TW: PanelType arrays taken from 650/LVDS BIOS 1.10.0 */
+
+static const SiS310_LVDSDesStruct SiS310_PanelType00_1[]= /* TW: New */
+{
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0}
+};
+
+static const SiS310_LVDSDesStruct SiS310_PanelType01_1[]= /* TW: New */
+{
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 805},
+ { 0, 0},
+ { 0, 0}
+};
+
+static const SiS310_LVDSDesStruct SiS310_PanelType02_1[]= /* TW: New */
+{
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 1065},
+ { 0, 0},
+ { 0, 0}
+};
+
+
+static const SiS310_LVDSDesStruct SiS310_PanelType03_1[]= /* TW: New */
+{
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0}
+};
+
+static const SiS310_LVDSDesStruct SiS310_PanelType04_1[]= /* TW: New */
+{
+ {1343, 798},
+ {1343, 794},
+ {1343, 798},
+ {1343, 794},
+ {1343, 0},
+ {1343, 0},
+ { 0, 805},
+ { 0, 794},
+ { 0, 0}
+};
+
+static const SiS310_LVDSDesStruct SiS310_PanelType05_1[]= /* TW: New */
+{
+ {1343, 798},
+ {1343, 794},
+ {1343, 798},
+ {1343, 794},
+ {1343, 0},
+ {1343, 0},
+ { 0, 805},
+ { 0, 794},
+ { 0, 0}
+};
+
+static const SiS310_LVDSDesStruct SiS310_PanelType06_1[]= /* TW: New */
+{
+ {1343, 798},
+ {1343, 794},
+ {1343, 798},
+ {1343, 794},
+ {1343, 0},
+ {1343, 0},
+ { 0, 805},
+ { 0, 794},
+ { 0, 0}
+};
+
+static const SiS310_LVDSDesStruct SiS310_PanelType07_1[]= /* TW: New */
+{
+ {1343, 798},
+ {1343, 794},
+ {1343, 798},
+ {1343, 794},
+ {1343, 0},
+ {1343, 0},
+ { 0, 805},
+ { 0, 794},
+ { 0, 0}
+};
+
+static const SiS310_LVDSDesStruct SiS310_PanelType08_1[]= /* TW: New */
+{
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0}
+};
+
+static const SiS310_LVDSDesStruct SiS310_PanelType09_1[]= /* TW: New - to check (1280x768) */
+{
+ { 0, 448},
+ { 0, 448},
+ { 0, 448},
+ { 0, 448},
+ { 0, 524},
+ { 0, 627},
+ { 0, 805},
+ { 0, 805},
+};
+
+static const SiS310_LVDSDesStruct SiS310_PanelType0a_1[]= /* TW: New */
+{
+ {1059, 626},
+ {1059, 624},
+ {1059, 626},
+ {1059, 624},
+ {1059, 624},
+ { 0, 627},
+ { 0, 627},
+ { 0, 0},
+ { 0, 0}
+};
+
+static const SiS310_LVDSDesStruct SiS310_PanelType0b_1[]= /* TW: New */
+{
+ {1343, 798},
+ {1343, 794},
+ {1343, 798},
+ {1343, 794},
+ {1343, 0},
+ {1343, 0},
+ { 0, 805},
+ { 0, 794},
+ { 0, 0}
+};
+
+static const SiS310_LVDSDesStruct SiS310_PanelType0c_1[]= /* TW: New */
+{
+ {1343, 798},
+ {1343, 794},
+ {1343, 798},
+ {1343, 794},
+ {1343, 0},
+ {1343, 0},
+ { 0, 805},
+ { 0, 794},
+ { 0, 0}
+};
+
+static const SiS310_LVDSDesStruct SiS310_PanelType0d_1[]= /* TW: New */
+{
+ {1343, 798},
+ {1343, 794},
+ {1343, 798},
+ {1343, 794},
+ {1343, 0},
+ {1343, 0},
+ { 0, 805},
+ { 0, 794},
+ { 0, 0}
+};
+
+static const SiS310_LVDSDesStruct SiS310_PanelType0e_1[]= /* TW: New */
+{
+ {1343, 798},
+ {1343, 794},
+ {1343, 798},
+ {1343, 794},
+ {1343, 0},
+ {1343, 0},
+ { 0, 805},
+ { 0, 794},
+ { 0, 0}
+};
+
+static const SiS310_LVDSDesStruct SiS310_PanelType0f_1[]= /* TW: New */
+{
+ {1343, 798},
+ {1343, 794},
+ {1343, 798},
+ {1343, 794},
+ {1343, 0},
+ {1343, 0},
+ { 0, 805},
+ { 0, 794},
+ { 0, 0}
+};
+
+static const SiS310_LVDSDesStruct SiS310_PanelType00_2[]= /* TW: New */
+{
+ {980, 528},
+ {980, 503},
+ {980, 528},
+ {980, 503},
+ {980, 568},
+ { 0, 628},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0}
+};
+
+static const SiS310_LVDSDesStruct SiS310_PanelType01_2[]= /* TW: New */
+{
+ {1152, 622},
+ {1152, 597},
+ {1152, 622},
+ {1152, 597},
+ {1152, 662},
+ {1232, 722},
+ { 0, 806},
+ { 0, 0},
+ { 0, 0}
+};
+
+static const SiS310_LVDSDesStruct SiS310_PanelType02_2[]= /* TW: New */
+{
+ {1368, 754},
+ {1368, 729},
+ {1368, 754},
+ {1368, 729},
+ {1368, 794},
+ {1448, 854},
+ {1560, 938},
+ { 0,1066},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0}
+};
+
+static const SiS310_LVDSDesStruct SiS310_PanelType03_2[]= /* TW: New */
+{
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0}
+};
+
+static const SiS310_LVDSDesStruct SiS310_PanelType04_2[]= /* TW: New */
+{
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0}
+};
+
+static const SiS310_LVDSDesStruct SiS310_PanelType05_2[]= /* TW: New */
+{
+ {1152, 622},
+ {1152, 597},
+ {1152, 622},
+ {1152, 597},
+ {1152, 662},
+ {1232, 722},
+ { 0, 805},
+ { 0, 794},
+ { 0, 0}
+};
+
+static const SiS310_LVDSDesStruct SiS310_PanelType06_2[]= /* TW: New */
+{
+ {1152, 622},
+ {1152, 597},
+ {1152, 622},
+ {1152, 597},
+ {1152, 662},
+ {1232, 722},
+ { 0, 805},
+ { 0, 794},
+ { 0, 0}
+};
+
+static const SiS310_LVDSDesStruct SiS310_PanelType07_2[]= /* TW: New */
+{
+ {1152, 622},
+ {1152, 597},
+ {1152, 622},
+ {1152, 597},
+ {1152, 662},
+ {1232, 722},
+ { 0, 805},
+ { 0, 794},
+ { 0, 0}
+};
+
+static const SiS310_LVDSDesStruct SiS310_PanelType08_2[]= /* TW: New */
+{
+ {976, 527},
+ {976, 502},
+ {976, 527},
+ {976, 502},
+ {976, 567},
+ { 0, 627},
+ { 0, 627},
+ { 0, 0},
+ { 0, 0}
+};
+
+static const SiS310_LVDSDesStruct SiS310_PanelType09_2[]= /* TW: New - to check (1280x768) */
+{
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0}
+};
+
+static const SiS310_LVDSDesStruct SiS310_PanelType0a_2[]= /* TW: New */
+{
+ {976, 527},
+ {976, 502},
+ {976, 527},
+ {976, 502},
+ {976, 567},
+ { 0, 627},
+ { 0, 627},
+ { 0, 0},
+ { 0, 0}
+};
+
+static const SiS310_LVDSDesStruct SiS310_PanelType0b_2[]= /* TW: New */
+{
+ {1152, 622},
+ {1152, 597},
+ {1152, 622},
+ {1152, 597},
+ {1152, 662},
+ {1232, 722},
+ { 0, 805},
+ { 0, 794},
+ { 0, 0}
+};
+
+static const SiS310_LVDSDesStruct SiS310_PanelType0c_2[]= /* TW: New */
+{
+ {1152, 622},
+ {1152, 597},
+ {1152, 622},
+ {1152, 597},
+ {1152, 662},
+ {1232, 722},
+ { 0, 805},
+ { 0, 794},
+ { 0, 0}
+};
+
+static const SiS310_LVDSDesStruct SiS310_PanelType0d_2[]= /* TW: New */
+{
+ {1152, 622},
+ {1152, 597},
+ {1152, 622},
+ {1152, 597},
+ {1152, 662},
+ {1232, 722},
+ { 0, 805},
+ { 0, 794},
+ { 0, 0}
+};
+
+static const SiS310_LVDSDesStruct SiS310_PanelType0e_2[]= /* TW: New */
+{
+ {1152, 622},
+ {1152, 597},
+ {1152, 622},
+ {1152, 597},
+ {1152, 662},
+ {1232, 722},
+ { 0, 805},
+ { 0, 794},
+ { 0, 0}
+};
+
+static const SiS310_LVDSDesStruct SiS310_PanelType0f_2[] = /* TW: New */
+{
+ {1152, 622},
+ {1152, 597},
+ {1152, 622},
+ {1152, 597},
+ {1152, 662},
+ {1232, 722},
+ { 0, 805},
+ { 0, 794},
+ { 0, 0}
+};
+
+static const SiS310_LVDSDesStruct SiS310_PanelType1076_1[]= /* TW: New */
+{ /* 1024x768 - Checked (1.10.6s) */
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0}
+};
+
+static const SiS310_LVDSDesStruct SiS310_PanelType1076_2[]= /* TW: New */
+{ /* 1024x768 - Checked (1.10.6s) */
+ { 1184, 622 },
+ { 1184, 597 },
+ { 1184, 622 },
+ { 1184, 597 },
+ { 1152, 622 },
+ { 1232, 722 },
+ { 0, 0 },
+ { 0, 794 },
+ { 0, 0 }
+};
+
+static const SiS310_LVDSDesStruct SiS310_PanelType1210_1[]= /* TW: New */
+{ /* 1280x1024 - Checked (1.10.6s) */
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0}
+};
+
+static const SiS310_LVDSDesStruct SiS310_PanelType1210_2[]= /* TW: New */
+{ /* 1280x1024 - Checked (1.10.6s) */
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0}
+};
+
+static const SiS310_LVDSDesStruct SiS310_PanelType1296_1[]= /* TW: New */
+{ /* 1400x1050 - Checked (1.10.6s) */
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0}
+};
+
+static const SiS310_LVDSDesStruct SiS310_PanelType1296_2[]= /* TW: New */
+{ /* 1400x1050 - Checked (1.10.6s) - looks heavily invalid */
+ { 808 , 740},
+ { 0 , 715},
+ { 632 , 740},
+ { 632 , 715},
+ { 1307, 780},
+ { 1387,1157},
+ { 1499, 924},
+ { 1627,1052},
+ { 0 , 0}
+};
+
+static const SiS310_LVDSDesStruct SiS310_PanelType1600_1[]= /* TW: New */
+{ /* 1600x1200 - Checked (1.10.6s) */
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0}
+};
+
+static const SiS310_LVDSDesStruct SiS310_PanelType1600_2[]= /* TW: New */
+{ /* 1600x1200 - Checked (1.10.6s) - looks heavily invalid */
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0}
+};
+
+static const SiS310_LVDSDesStruct SiS310_CHTVUNTSCDesData[]=
+{
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0}
+};
+
+static const SiS310_LVDSDesStruct SiS310_CHTVONTSCDesData[]=
+{
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0}
+};
+
+static const SiS310_LVDSDesStruct SiS310_CHTVUPALDesData[]=
+{
+ {256, 0},
+ {256, 0},
+ {256, 0},
+ {256, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0}
+};
+
+static const SiS310_LVDSDesStruct SiS310_CHTVOPALDesData[]=
+{
+ {256, 0},
+ {256, 0},
+ {256, 0},
+ {256, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0}
+};
+
+typedef struct _SiS310_Part2PortTblStruct
+{
+ UCHAR CR[12];
+} SiS310_Part2PortTblStruct;
+
+static const SiS310_Part2PortTblStruct 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}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {{0x25,0x12,0xc9,0xdc,0xb6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}
+};
+
+static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1280x1024_1[] =
+{ /* TW: Temporary data, invalid */
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}
+};
+
+static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1400x1050_1[] =
+{ /* TW: Temporary data, invalid */
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}
+};
+
+static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1600x1200_1[] =
+{ /* TW: Temporary data, invalid */
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}
+};
+
+static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1024x768_2[] =
+{
+ {{0x25,0x12,0x51,0x6e,0x48,0x99,0x35,0x89,0x47,0xc1,0x49,0x33}},
+ {{0x2c,0x12,0x38,0x55,0x2f,0x99,0x35,0x89,0x47,0xc1,0x49,0x33}},
+ {{0x25,0x12,0x51,0x6e,0x48,0x99,0x35,0x89,0x47,0xc1,0x49,0x33}},
+ {{0x2c,0x12,0x38,0x55,0x2f,0xc1,0x35,0xb1,0x47,0xe9,0x71,0x33}},
+ {{0x2d,0x12,0x79,0x96,0x70,0x99,0x35,0x89,0x47,0xc1,0x49,0x33}},
+ {{0x29,0x12,0xb5,0xd2,0xac,0xe9,0x35,0xd9,0x47,0x11,0x99,0x33}},
+ {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+};
+
+static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1280x1024_2[] =
+{
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+};
+
+static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1400x1050_2[] =
+{
+ {{0x2b,0x12,0xd9,0xe5,0xd5,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}},
+ {{0x22,0x12,0xc0,0xcc,0xbc,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}},
+ {{0x2b,0x12,0xd9,0xe5,0xd5,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}},
+ {{0x22,0x12,0xc0,0xcc,0xbc,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}},
+ {{0x33,0x13,0x01,0x0d,0xfd,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}},
+ {{0x3f,0x1b,0x3d,0x49,0x39,0x54,0x23,0xc0,0x27,0x66,0x30,0x42}},
+ {{0x33,0x1b,0x91,0x9d,0x8d,0x8c,0x23,0xf8,0x27,0x9e,0x68,0x42}},
+ {{0x43,0x24,0x11,0x1d,0x0d,0xcc,0x23,0x38,0x37,0xde,0xa8,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}
+};
+
+static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1600x1200_2[] =
+{ /* TW: Temporary data, invalid */
+ {{0x2b,0x12,0xd9,0xe5,0xd5,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}},
+ {{0x22,0x12,0xc0,0xcc,0xbc,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}},
+ {{0x2b,0x12,0xd9,0xe5,0xd5,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}},
+ {{0x22,0x12,0xc0,0xcc,0xbc,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}},
+ {{0x33,0x13,0x01,0x0d,0xfd,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}},
+ {{0x3f,0x1b,0x3d,0x49,0x39,0x54,0x23,0xc0,0x27,0x66,0x30,0x42}},
+ {{0x33,0x1b,0x91,0x9d,0x8d,0x8c,0x23,0xf8,0x27,0x9e,0x68,0x42}},
+ {{0x43,0x24,0x11,0x1d,0x0d,0xcc,0x23,0x38,0x37,0xde,0xa8,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}
+};
+
+
+static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1024x768_3[] =
+{ /* TW: Data from 650/301LVx 1.10.6s */
+ {{0x25,0x13,0xc9,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+ {{0x2c,0x13,0x9a,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+ {{0x25,0x13,0xc9,0x24,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {{0x38,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+ {{0x38,0x18,0x16,0x00,0x00,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+ {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {{0x25,0x13,0xc9,0x25,0xff,0xf9,0x45,0x09,0x07,0xf9,0x09,0x24}}
+#if 0 /* TW: Data from 650/301LV */
+ {{0x25,0x12,0xc9,0xdc,0xb6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+ {{0x2c,0x12,0x9a,0xae,0x88,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+ {{0x25,0x12,0xc9,0xdc,0xb6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {{0x38,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+ {{0x38,0x18,0x16,0x00,0x00,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+ {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+#endif
+};
+
+/* 1 2 4 5 6 1c 1d 1f 20 21 23 25 */
+static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1280x1024_3[] =
+{ /* TW: Temporary data, invalid */
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}
+};
+
+static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1400x1050_3[] =
+{ /* TW: Temporary data, invalid */
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}
+};
+
+static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1600x1200_3[] =
+{ /* TW: Temporary data, invalid */
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}
+};
+
+typedef struct _SiS310_LCDACRT1DataStruct
+{
+ UCHAR CR[17];
+}SiS310_LCDACRT1DataStruct;
+
+static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT1800x600_1[] =
+{
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}}
+};
+
+static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11024x768_1[]=
+{ /* TW: Checked (1.10.6s) */
+ {{0x73,0x4f,0x4f,0x97,0x55,0x86,0xc4,0x1f,
+ 0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x05,
+ 0x00}},
+ {{0x73,0x4f,0x4f,0x97,0x55,0x86,0x97,0x1f,
+ 0x60,0x87,0x5d,0x5d,0x83,0x10,0x00,0x05,
+ 0x00}},
+ {{0x73,0x4f,0x4f,0x97,0x55,0x86,0xc4,0x1f,
+ 0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x05,
+ 0x00}},
+ {{0x73,0x4f,0x4f,0x97,0x55,0x86,0x97,0x1f,
+ 0x60,0x87,0x5d,0x5d,0x83,0x10,0x00,0x05,
+ 0x00}},
+ {{0x73,0x4f,0x4f,0x97,0x55,0x86,0x04,0x3e,
+ 0xE2,0x89,0xDf,0xDf,0x05,0x00,0x00,0x05,
+ 0x00}},
+ {{0x87,0x63,0x63,0x8B,0x69,0x1A,0x7c,0xf0,
+ 0x5A,0x8F,0x57,0x57,0x7D,0x20,0x00,0x26,
+ 0x01}},
+ {{0xA3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,
+ 0x02,0x88,0xFf,0xFf,0x25,0x10,0x00,0x02,
+ 0x01}}
+};
+
+static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11280x1024_1[]=
+{ /* Checked (1.10.6s) */
+ {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0xb8,0x1f,
+ 0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x06,
+ 0x00}},
+ {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0x86,0x1f,
+ 0x5e,0x82,0x5d,0x5d,0x87,0x10,0x00,0x06,
+ 0x00}},
+ {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0xb8,0x1f,
+ 0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x06,
+ 0x00}},
+ {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0x86,0x1f,
+ 0x5e,0x82,0x5d,0x5d,0x87,0x10,0x00,0x06,
+ 0x00}},
+ {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0x08,0x3e,
+ 0xe0,0x84,0xdf,0xdf,0x09,0x00,0x00,0x06,
+ 0x00}},
+ {{0x92,0x63,0x63,0x96,0x6c,0x1a,0x80,0xf0,
+ 0x58,0x8c,0x57,0x57,0x81,0x20,0x00,0x06,
+ 0x01}},
+ {{0xae,0x7f,0x7f,0x92,0x88,0x96,0x28,0xf5,
+ 0x00,0x84,0xff,0xff,0x29,0x10,0x00,0x02,
+ 0x01}},
+ {{0xce,0x9f,0x9f,0x92,0xa8,0x16,0x28,0x5a,
+ 0x00,0x84,0xff,0xff,0x29,0x01,0x00,0x07,
+ 0x01}}
+};
+
+static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11400x1050_1[]=
+{ /* Checked (1.10.6s) */
+ {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0x9e,0x1f,
+ 0x93,0x86,0x8f,0x8f,0x9f,0x30,0x00,0x05,
+ 0x00}},
+ {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0x6c,0x1f,
+ 0x60,0x84,0x5d,0x5d,0x6d,0x10,0x00,0x05,
+ 0x00}},
+ {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0x9e,0x1f,
+ 0x93,0x86,0x8f,0x8f,0x9f,0x30,0x00,0x05,
+ 0x00}},
+ {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0x6c,0x1f,
+ 0x60,0x84,0x5d,0x5d,0x6d,0x10,0x00,0x05,
+ 0x00}},
+ {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0xee,0x1f,
+ 0xe2,0x86,0xdf,0xdf,0xef,0x10,0x00,0x05,
+ 0x00}},
+ {{0x83,0x63,0x63,0x87,0x68,0x16,0x66,0xf0,
+ 0x5a,0x8e,0x57,0x57,0x67,0x20,0x00,0x06,
+ 0x01}},
+ {{0x9f,0x7f,0x7f,0x83,0x84,0x92,0x0e,0xf5,
+ 0x02,0x86,0xff,0xff,0x0f,0x10,0x00,0x02,
+ 0x01}},
+ {{0xbf,0x9f,0x9f,0x83,0xa4,0x12,0x0e,0x5a,
+ 0x02,0x86,0xff,0xff,0x0f,0x09,0x00,0x07,
+ 0x01}},
+ {{0xce,0xae,0xae,0x92,0xb3,0x01,0x28,0x10,
+ 0x1a,0x80,0x19,0x19,0x29,0x0f,0x00,0x03,
+ 0x00}}
+};
+
+static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11600x1200_1[]=
+{ /* MISSING */
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}}
+};
+
+static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT1800x600_1_H[]=
+{
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}}
+};
+
+static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11024x768_1_H[]=
+{ /* TW: Checked (1.10.6s) */
+ {{0x4b,0x27,0x27,0x8f,0x2b,0x03,0xc4,0x1f,
+ 0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x44,
+ 0x00}},
+ {{0x4b,0x27,0x27,0x8f,0x2b,0x03,0x97,0x1f,
+ 0x60,0x87,0x5D,0x5D,0x83,0x01,0x00,0x44,
+ 0x00}},
+ {{0x4b,0x27,0x27,0x8f,0x2b,0x03,0xc4,0x1f,
+ 0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x44,
+ 0x00}},
+ {{0x4b,0x27,0x27,0x8f,0x2b,0x03,0x97,0x1f,
+ 0x60,0x87,0x5D,0x5D,0x83,0x01,0x00,0x44,
+ 0x00}},
+ {{0x4b,0x27,0x27,0x8f,0x32,0x1b,0x04,0x3e,
+ 0xE2,0x89,0xDf,0xDf,0x05,0x00,0x00,0x45,
+ 0x00}},
+ {{0x55,0x31,0x31,0x99,0x46,0x1d,0x7c,0xf0,
+ 0x5A,0x8F,0x57,0x57,0x7D,0x20,0x00,0x55,
+ 0x01}},
+ {{0x63,0x3F,0x3F,0x87,0x4a,0x93,0x24,0xf5,
+ 0x02,0x88,0xFf,0xFf,0x25,0x10,0x00,0x01,
+ 0x01}}
+};
+
+static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11280x1024_1_H[]=
+{ /* Checked (1.10.6s) */
+ {{0x56,0x27,0x27,0x9a,0x30,0x1e,0xb8,0x1f,
+ 0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x05,
+ 0x00}},
+ {{0x3c,0x4f,0x4f,0x82,0x58,0x06,0x86,0xd1, /* <-- Invalid data - one byte missing in BIOS */
+ 0xbc,0x80,0xbb,0xbb,0xe5,0x00,0x00,0x06,
+ 0x01}},
+ {{0x56,0x27,0x27,0x9a,0x30,0x1e,0xb8,0x1f,
+ 0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x05,
+ 0x00}},
+ {{0x3c,0x4f,0x4f,0x82,0x58,0x06,0x86,0xd1,
+ 0xbc,0x80,0xbb,0xbb,0xe5,0x00,0x00,0x06,
+ 0x01}},
+ {{0x56,0x27,0x27,0x9a,0x30,0x1e,0x08,0x3e,
+ 0xe0,0x84,0xdf,0xdf,0x09,0x00,0x00,0x05,
+ 0x00}},
+ {{0x60,0x31,0x31,0x84,0x3a,0x88,0x80,0xf0,
+ 0x58,0x8c,0x57,0x57,0x81,0x20,0x00,0x01,
+ 0x01}},
+ {{0x6e,0x3f,0x3f,0x92,0x48,0x96,0x28,0xf5,
+ 0x00,0x84,0xff,0xff,0x29,0x10,0x00,0x01,
+ 0x01}}
+};
+
+static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11400x1050_1_H[]=
+{ /* Checked (1.10.6s) */
+ {{0x47,0x27,0x27,0x8b,0x2c,0x1a,0x9e,0x1f,
+ 0x93,0x86,0x8f,0x8f,0x9f,0x30,0x00,0x05,
+ 0x00}},
+ {{0x47,0x27,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
+ 0x60,0x84,0x5d,0x5d,0x6d,0x10,0x00,0x05,
+ 0x00}},
+ {{0x47,0x27,0x27,0x8b,0x30,0x1e,0x9e,0x1f,
+ 0x92,0x86,0x8f,0x8f,0x9f,0x30,0x00,0x05,
+ 0x00}},
+ {{0x47,0x27,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
+ 0x60,0x84,0x5d,0x5d,0x6d,0x10,0x00,0x05,
+ 0x00}},
+ {{0x47,0x27,0x27,0x8b,0x2c,0x1a,0xee,0x1f,
+ 0xe2,0x86,0xdf,0xdf,0xef,0x10,0x00,0x05,
+ 0x00}},
+ {{0x51,0x31,0x31,0x95,0x36,0x04,0x66,0xf0,
+ 0x5a,0x8e,0x57,0x57,0x67,0x20,0x00,0x01,
+ 0x01}},
+ {{0x5f,0x3f,0x3f,0x83,0x44,0x92,0x0e,0xf5,
+ 0x02,0x86,0xff,0xff,0x0f,0x10,0x00,0x01,
+ 0x01}},
+ {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0x0e,0x5a,
+ 0x02,0x86,0xff,0xff,0x0f,0x09,0x00,0x05,
+ 0x01}},
+ {{0x76,0x56,0x56,0x9a,0x5b,0x89,0x28,0x10,
+ 0x1c,0x80,0x19,0x19,0x29,0x0b,0x00,0x05,
+ 0x00}}
+};
+
+static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11600x1200_1_H[]=
+{ /* MISSING */
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}}
+};
+
+static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT1800x600_2[]=
+{
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}}
+};
+
+static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11024x768_2[]=
+{ /* Checked (1.10.6s) */
+ {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+ 0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x06,
+ 0x00}},
+ {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+ 0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x06,
+ 0x00}},
+ {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+ 0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x06,
+ 0x00}},
+ {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+ 0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x06,
+ 0x00}},
+ {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+ 0x72,0x88,0xdf,0xdf,0x25,0x30,0x00,0x06,
+ 0x00}},
+ {{0xa3,0x63,0x63,0x87,0x78,0x89,0x24,0xf1,
+ 0xae,0x84,0x57,0x57,0x25,0x30,0x00,0x02,
+ 0x01}},
+ {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,
+ 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
+ 0x01}}
+};
+
+static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11280x1024_2[]=
+{ /* Checked (1.10.6s) */
+ {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+ 0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x06,
+ 0x00}},
+ {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+ 0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x06,
+ 0x00}},
+ {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+ 0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x06,
+ 0x00}},
+ {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+ 0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x06,
+ 0x00}},
+ {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+ 0x72,0x88,0xdf,0xdf,0x25,0x30,0x00,0x06,
+ 0x00}},
+ {{0xa3,0x63,0x63,0x87,0x78,0x89,0x24,0xf1,
+ 0xae,0x84,0x57,0x57,0x25,0x30,0x00,0x02,
+ 0x01}},
+ {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,
+ 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
+ 0x01}}
+};
+
+static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11400x1050_2[]=
+{ /* Checked (1.10.6s) */
+ {{0xce,0x4f,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
+ 0xdb,0x8f,0x8f,0x8f,0x29,0x21,0x00,0x03,
+ 0x00}},
+ {{0xce,0x4f,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
+ 0xc2,0x86,0x5d,0x5d,0x29,0x01,0x00,0x03,
+ 0x01}},
+ {{0xce,0x4f,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
+ 0xdb,0x8f,0x8f,0x8f,0x29,0x21,0x00,0x03,
+ 0x00}},
+ {{0xce,0x4f,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
+ 0xc2,0x86,0x5d,0x5d,0x29,0x01,0x00,0x03,
+ 0x00}},
+ {{0xce,0x4f,0x4f,0x92,0x8c,0x1a,0x28,0x9e,
+ 0x03,0x87,0xdf,0xdf,0x29,0x01,0x00,0x03,
+ 0x00}},
+ {{0xce,0x63,0x63,0x92,0x96,0x04,0x28,0xd4,
+ 0x3f,0x83,0x57,0x57,0x29,0x01,0x00,0x07,
+ 0x01}},
+ {{0xce,0x7f,0x7f,0x92,0xa4,0x12,0x28,0xd4,
+ 0x93,0x87,0xff,0xff,0x29,0x21,0x00,0x07,
+ 0x01}},
+ {{0xce,0x9f,0x9f,0x92,0xb4,0x02,0x28,0x5a,
+ 0x13,0x87,0xff,0xff,0x29,0x29,0x00,0x03,
+ 0x01}},
+ {{0xce,0xae,0xae,0x92,0xbc,0x0a,0x28,0x10,
+ 0x20,0x84,0x19,0x19,0x29,0x0f,0x00,0x03,
+ 0x00}}
+};
+
+static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11600x1200_2[]=
+{ /* MISSING */
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}}
+};
+
+static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT1800x600_2_H[]=
+{
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}}
+};
+
+static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11024x768_2_H[]=
+{ /* Checked (1.10.6s) */
+ {{0x4f,0x27,0x27,0x93,0x39,0x01,0x24,0xbb,
+ 0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x01,
+ 0x00 }},
+ {{0x4f,0x27,0x27,0x93,0x39,0x01,0x24,0xbb,
+ 0x31,0x87,0x8d,0x5d,0x25,0x30,0x00,0x01, /* <-- invalid data */
+ 0x00 }},
+ {{0x4f,0x27,0x27,0x93,0x39,0x01,0x24,0xbb,
+ 0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x01,
+ 0x00 }},
+ {{0x4f,0x27,0x27,0x93,0x39,0x01,0x24,0xbb,
+ 0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x01,
+ 0x00 }},
+ {{0x4f,0x27,0x27,0x93,0x39,0x01,0x24,0xbb,
+ 0x72,0x88,0xdf,0xdf,0x25,0x30,0x00,0x01,
+ 0x00 }},
+ {{0x4f,0x31,0x31,0x93,0x3e,0x06,0x24,0xf1,
+ 0xae,0x84,0x57,0x57,0x25,0x30,0x00,0x01, /* <-- invalid data */
+ 0x01 }},
+ {{0x4f,0x3f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+ 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x01,
+ 0x01 }}
+};
+
+static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11280x1024_2_H[]=
+{ /* Checked (1.10.6s) */
+ {{0x4f,0x27,0x27,0x93,0x39,0x81,0x24,0xbb,
+ 0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x01,
+ 0x00 }},
+ {{0x4f,0x27,0x27,0x93,0x39,0x81,0x24,0xbb,
+ 0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x01,
+ 0x00 }},
+ {{0x4f,0x27,0x27,0x93,0x39,0x81,0x24,0xbb,
+ 0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x01,
+ 0x00 }},
+ {{0x4f,0x27,0x27,0x93,0x39,0x81,0x24,0xbb,
+ 0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x01,
+ 0x00 }},
+ {{0x4f,0x27,0x27,0x93,0x39,0x81,0x24,0xbb,
+ 0x72,0x88,0xdf,0xdf,0x25,0x30,0x00,0x01,
+ 0x00 }},
+ {{0x4f,0x31,0x31,0x93,0x3e,0x86,0x24,0xf1,
+ 0xae,0x84,0x57,0x57,0x25,0x30,0x00,0x01,
+ 0x01 }},
+ {{0x4f,0x3f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+ 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x01,
+ 0x01 }}
+};
+
+static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11400x1050_2_H[]=
+{ /* Checked (1.10.6s) */
+ {{0xa6,0x27,0x27,0x8a,0x64,0x92,0x28,0x9a,
+ 0xdb,0x8f,0x8f,0x8f,0x29,0x21,0x00,0x06,
+ 0x00}},
+ {{0xa6,0x27,0x27,0x8a,0x64,0x92,0x28,0x9a,
+ 0xc2,0x86,0x5d,0x5d,0x29,0x01,0x00,0x06,
+ 0x00}},
+ {{0xa6,0x27,0x27,0x8a,0x64,0x92,0x28,0x9a,
+ 0xdb,0x8f,0x8f,0x8f,0x29,0x21,0x00,0x06,
+ 0x00}},
+ {{0xa6,0x27,0x27,0x8a,0x64,0x92,0x28,0x9a,
+ 0xc2,0x86,0x5d,0x5d,0x29,0x01,0x00,0x06,
+ 0x00}},
+ {{0xa6,0x27,0x27,0x8a,0x64,0x92,0x28,0x9e,
+ 0x03,0x87,0xdf,0xdf,0x29,0x01,0x00,0x06,
+ 0x00}},
+ {{0x9c,0x31,0x31,0x80,0x64,0x92,0x28,0xd4,
+ 0x3f,0x83,0x57,0x57,0x29,0x01,0x00,0x06,
+ 0x01}},
+ {{0x8e,0x3f,0x3f,0x92,0x64,0x12,0x28,0xd4,
+ 0x93,0x87,0xff,0xff,0x29,0x21,0x00,0x06,
+ 0x01}},
+ {{0x7e,0x4f,0x4f,0x82,0x64,0x12,0x28,0x5a,
+ 0x13,0x87,0xff,0xff,0x29,0x29,0x00,0x06,
+ 0x01}},
+ {{0x76,0x56,0x56,0x9a,0x64,0x92,0x28,0x10,
+ 0x20,0x84,0x19,0x19,0x29,0x0f,0x00,0x05,
+ 0x00}}
+};
+
+static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11600x1200_2_H[]=
+{ /* MISSING */
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00}}
+};
+
+typedef struct _SiS310_LVDSCRT1DataStruct
+{
+ UCHAR CR[15];
+} SiS310_LVDSCRT1DataStruct;
+
+static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1320x480_1[] =
+{
+ {{0x65,0x4f,0x89,0x56,0x83,0xaa,0x1f,
+ 0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
+ 0x00 }},
+ {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
+ 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
+ 0x00 }},
+ {{0x65,0x4f,0x89,0x54,0x9f,0xc4,0x1f,
+ 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
+ 0x00 }},
+ {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
+ 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
+ 0x00 }},
+ {{0x65,0x4f,0x89,0x56,0x83,0x04,0x3e,
+ 0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
+ 0x00 }},
+ {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
+ 0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
+ 0x01 }},
+ {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e,
+ 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
+ 0x00 }}
+};
+
+static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_1[] = /* TW: New */
+{
+ {{0x6b,0x4f,0x8f,0x55,0x85,0xaa,0x1f,
+ 0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
+ 0x00 }},
+ {{0x6b,0x4f,0x8f,0x55,0x85,0x78,0x1f,
+ 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
+ 0x00 }},
+ {{0x6b,0x4f,0x8f,0x55,0x85,0xaa,0x1f,
+ 0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
+ 0x00 }},
+ {{0x6b,0x4f,0x8f,0x55,0x85,0x78,0x1f,
+ 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
+ 0x00 }},
+ {{0x6b,0x4f,0x8f,0x55,0x85,0xfa,0x1f,
+ 0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
+ 0x00 }},
+ {{0x7f,0x63,0x83,0x69,0x19,0x72,0xf0,
+ 0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
+ 0x01 }}
+};
+
+static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_1[] = /* TW: New */
+{
+ {{0x73,0x4f,0x97,0x53,0x84,0xb4,0x1f,
+ 0x92,0x89,0x8f,0xb5,0x30,0x00,0x05,
+ 0x00}},
+ {{0x73,0x4f,0x97,0x53,0x84,0x82,0x1f,
+ 0x60,0x87,0x5d,0x83,0x10,0x00,0x05,
+ 0x00}},
+ {{0x73,0x4f,0x97,0x53,0x84,0xb4,0x1f,
+ 0x92,0x89,0x8f,0xb5,0x30,0x00,0x05,
+ 0x00}},
+ {{0x73,0x4f,0x97,0x53,0x84,0x82,0x1f,
+ 0x60,0x87,0x5d,0x83,0x10,0x00,0x05,
+ 0x00}},
+ {{0x73,0x4f,0x97,0x53,0x84,0x04,0x3e,
+ 0xE2,0x89,0xDf,0x05,0x00,0x00,0x05,
+ 0x00}},
+ {{0x87,0x63,0x8B,0x67,0x18,0x7c,0xf0,
+ 0x5A,0x81,0x57,0x7D,0x00,0x00,0x06,
+ 0x01}},
+ {{0xA3,0x7f,0x87,0x83,0x94,0x24,0xf5,
+ 0x02,0x89,0xFf,0x25,0x10,0x00,0x02,
+ 0x01}}
+};
+
+static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11280x1024_1[] = /* TW: New */
+{
+ {{0x7e,0x4f,0x82,0x56,0x04,0xb8,0x1f,
+ 0x90,0x84,0x8f,0xb9,0x30,0x00,0x06,
+ 0x00 }},
+ {{0x7e,0x4f,0x82,0x56,0x04,0x86,0x1f,
+ 0x5e,0x82,0x5d,0x87,0x10,0x00,0x06,
+ 0x00 }},
+ {{0x7e,0x4f,0x82,0x56,0x04,0xb8,0x1f,
+ 0x90,0x84,0x8f,0xb9,0x30,0x00,0x06,
+ 0x00 }},
+ {{0x7e,0x4f,0x82,0x56,0x04,0x86,0x1f,
+ 0x5e,0x82,0x5d,0x87,0x10,0x00,0x06,
+ 0x00 }},
+ {{0x7e,0x4f,0x82,0x56,0x04,0x08,0x3e,
+ 0xe0,0x84,0xdf,0x09,0x00,0x00,0x06,
+ 0x00 }},
+ {{0x92,0x63,0x96,0x6a,0x18,0x80,0xf0,
+ 0x58,0x8c,0x57,0x81,0x20,0x00,0x06,
+ 0x01 }},
+ {{0xae,0x7f,0x92,0x86,0x94,0x28,0xf5,
+ 0x00,0x84,0xff,0x29,0x10,0x00,0x02,
+ 0x01 }},
+ {{0xce,0x9f,0x92,0xa6,0x14,0x28,0x5a,
+ 0x00,0x84,0xff,0x29,0x09,0x00,0x07,
+ 0x01}}
+};
+
+static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_1_H[] = /* TW: New */
+{
+ {{0x43,0x27,0x87,0x2d,0x1d,0xaa,0x1f,
+ 0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
+ 0x00 }},
+ {{0x43,0x27,0x87,0x2d,0x1d,0x78,0x1f,
+ 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
+ 0x00 }},
+ {{0x43,0x27,0x87,0x2d,0x1d,0xfa,0x1f,
+ 0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
+ 0x00 }},
+ {{0x43,0x27,0x87,0x2d,0x1d,0x78,0x1f,
+ 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
+ 0x00 }},
+ {{0x43,0x27,0x87,0x2d,0x1d,0xfa,0x1f,
+ 0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
+ 0x00 }},
+ {{0x4d,0x31,0x91,0x37,0x07,0x72,0xf0,
+ 0x58,0x8d,0x57,0x73,0x20,0x00,0x01,
+ 0x01 }}
+};
+
+static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_1_H[] = /* TW: New */
+{
+ {{0x4b,0x27,0x8f,0x2b,0x1c,0xb4,0x1f,
+ 0x92,0x89,0x8f,0xb5,0x30,0x00,0x05,
+ 0x00 }},
+ {{0x4b,0x27,0x8f,0x2b,0x1c,0x82,0x1f,
+ 0x60,0x87,0x5D,0x83,0x01,0x00,0x05,
+ 0x00}},
+ {{0x4b,0x27,0x8f,0x2b,0x1c,0xb4,0x1f,
+ 0x92,0x89,0x8f,0xb5,0x30,0x00,0x05,
+ 0x00}},
+ {{0x4b,0x27,0x8f,0x2b,0x1c,0x82,0x1f,
+ 0x60,0x87,0x5D,0x83,0x01,0x00,0x05,
+ 0x00}},
+ {{0x4b,0x27,0x8f,0x2b,0x1c,0x04,0x3e,
+ 0xE2,0x89,0xDf,0x05,0x00,0x00,0x05,
+ 0x00}},
+ {{0x55,0x31,0x99,0x35,0x06,0x7c,0xf0,
+ 0x5A,0x81,0x57,0x7D,0x00,0x00,0x01,
+ 0x01}},
+ {{0x63,0x3F,0x87,0x43,0x94,0x24,0xf5,
+ 0x02,0x89,0xFf,0x25,0x10,0x00,0x01,
+ 0x01 }}
+};
+
+static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11280x1024_1_H[] = /* TW: New */
+{
+ {{0x56,0x27,0x9a,0x2e,0x1c,0xb8,0x1f,
+ 0x90,0x84,0x8f,0xb9,0x30,0x00,0x05,
+ 0x00 }},
+ {{0x56,0x27,0x9a,0x2e,0x1c,0x86,0x1f,
+ 0x5e,0x82,0x5d,0x87,0x10,0x00,0x05,
+ 0x00 }},
+ {{0x56,0x27,0x9a,0x2e,0x1c,0xb8,0x1f,
+ 0x90,0x84,0x8f,0xb9,0x30,0x00,0x05,
+ 0x00 }},
+ {{0x56,0x27,0x9a,0x2e,0x1c,0x86,0x1f,
+ 0x5e,0x82,0x5d,0x87,0x10,0x00,0x05,
+ 0x01 }},
+ {{0x56,0x27,0x9a,0x2e,0x1c,0x08,0x3e,
+ 0xe0,0x84,0xdf,0x09,0x00,0x00,0x05,
+ 0x00 }},
+ {{0x60,0x31,0x84,0x38,0x86,0x80,0xf0,
+ 0x58,0x8c,0x57,0x81,0x20,0x00,0x01,
+ 0x01 }},
+ {{0x6e,0x3f,0x92,0x46,0x94,0x28,0xf5,
+ 0x00,0x84,0xff,0x29,0x10,0x00,0x01,
+ 0x01 }}
+};
+
+static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_2[]= /* TW: New */
+{
+ {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
+ 0xff,0x84,0x8f,0x73,0x00,0x00,0x06,
+ 0x00 }},
+ {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
+ 0xe6,0x8b,0x5d,0x73,0x00,0x00,0x06,
+ 0x00 }},
+ {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
+ 0xff,0x84,0x8f,0x73,0x00,0x00,0x06,
+ 0x00 }},
+ {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
+ 0xe6,0x8b,0x5d,0x73,0x00,0x00,0x06,
+ 0x00 }},
+ {{0x7f,0x4f,0x83,0x62,0x12,0x72,0xba,
+ 0x27,0x8c,0xdf,0x73,0x00,0x00,0x06,
+ 0x00 }},
+ {{0x7f,0x63,0x83,0x69,0x19,0x72,0xf0,
+ 0x58,0x8d,0x57,0x73,0x20,0x00,0x06,
+ 0x01 }}
+};
+
+static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_2[] = /* TW: New */
+{
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+ 0x57,0x8e,0x8f,0x25,0x30,0x00,0x06,
+ 0x00 }},
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+ 0x3e,0x85,0x5d,0x25,0x10,0x00,0x06,
+ 0x00 }},
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+ 0x57,0x8e,0x8f,0x25,0x30,0x00,0x06,
+ 0x00 }},
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+ 0x3e,0x85,0x5d,0x25,0x10,0x00,0x06,
+ 0x01 }},
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+ 0x7f,0x86,0xdf,0x25,0x10,0x00,0x06,
+ 0x00 }},
+ {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
+ 0xbb,0x82,0x57,0x25,0x10,0x00,0x02,
+ 0x01 }},
+ {{0xa3,0x7f,0x87,0x83,0x94,0x24,0xf5,
+ 0x02,0x89,0xff,0x25,0x10,0x00,0x02,
+ 0x01 }}
+};
+
+static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11280x1024_2[] = /* TW: New */
+{
+ {{0xce,0x4f,0x92,0x81,0x0f,0x28,0x9a,
+ 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x03,
+ 0x00 }},
+ {{0xce,0x4f,0x92,0x81,0x0f,0x28,0x9a,
+ 0xc2,0x86,0x5d,0x29,0x01,0x00,0x03,
+ 0x00 }},
+ {{0xce,0x4f,0x92,0x81,0x0f,0x28,0x9a,
+ 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x03,
+ 0x00 }},
+ {{0xce,0x4f,0x92,0x81,0x0f,0x28,0x9a,
+ 0xc2,0x86,0x5d,0x29,0x01,0x00,0x03,
+ 0x00 }},
+ {{0xce,0x4f,0x92,0x81,0x0f,0x28,0x9e,
+ 0x03,0x87,0xdf,0x29,0x01,0x00,0x03,
+ 0x00 }},
+ {{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,0xa6,0x14,0x28,0x5a,
+ 0x00,0x84,0xff,0x29,0x09,0x00,0x07,
+ 0x01}}
+};
+
+static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_2_H[] = /* TW: New */
+{
+ {{0x57,0x27,0x9b,0x3a,0x0a,0x72,0x3e,
+ 0xff,0x84,0x8f,0x73,0x00,0x00,0x01,
+ 0x00 }},
+ {{0x57,0x27,0x9b,0x3a,0x0a,0x72,0x3e,
+ 0xd6,0x8b,0x5d,0x73,0x00,0x00,0x01,
+ 0x00 }},
+ {{0x57,0x27,0x9b,0x3a,0x0a,0x72,0x3e,
+ 0xff,0x84,0x8f,0x73,0x00,0x00,0x01,
+ 0x00 }},
+ {{0x57,0x27,0x9b,0x3a,0x0a,0x72,0x3e,
+ 0xd6,0x8b,0x5d,0x73,0x00,0x00,0x01,
+ 0x00 }},
+ {{0x57,0x27,0x9b,0x3a,0x0a,0x72,0xba,
+ 0x27,0x8c,0xdf,0x73,0x00,0x00,0x01,
+ 0x00 }},
+ {{0x4d,0x31,0x91,0x3a,0x0a,0x72,0xf0,
+ 0x63,0x88,0x57,0x73,0x00,0x00,0x01,
+ 0x01 }}
+};
+
+static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_2_H[] = /* TW: New */
+{
+ {{0x7b,0x27,0x9f,0x46,0x97,0x24,0xbb,
+ 0x57,0x8e,0x8f,0x25,0x30,0x00,0x01,
+ 0x00 }},
+ {{0x7b,0x27,0x9f,0x46,0x97,0x24,0xbb,
+ 0x3e,0x85,0x5d,0x25,0x10,0x00,0x01,
+ 0x00 }},
+ {{0x7b,0x27,0x9f,0x46,0x97,0x24,0xbb,
+ 0x57,0x8e,0x8f,0x25,0x30,0x00,0x01,
+ 0x00 }},
+ {{0x7b,0x27,0x9f,0x46,0x97,0x24,0xbb,
+ 0x3e,0x85,0x5d,0x25,0x10,0x00,0x01,
+ 0x00 }},
+ {{0x7b,0x27,0x9f,0x46,0x97,0x24,0xbb,
+ 0x7f,0x86,0xdf,0x25,0x10,0x00,0x01,
+ 0x00 }},
+ {{0x71,0x31,0x95,0x46,0x97,0x24,0xf1,
+ 0xbb,0x82,0x57,0x25,0x10,0x00,0x01,
+ 0x01 }},
+ {{0x63,0x3f,0x87,0x46,0x97,0x24,0xf5,
+ 0x0f,0x86,0xff,0x25,0x30,0x00,0x01,
+ 0x01 }}
+};
+
+static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11280x1024_2_H[] = /* TW: New */
+{
+ {{0xa6,0x27,0x8a,0x59,0x87,0x28,0x9a,
+ 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x06,
+ 0x00 }},
+ {{0xa6,0x27,0x8a,0x59,0x87,0x28,0x9a,
+ 0xc2,0x86,0x5d,0x29,0x01,0x00,0x06,
+ 0x00 }},
+ {{0xa6,0x27,0x8a,0x59,0x87,0x28,0x9a,
+ 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x06,
+ 0x00 }},
+ {{0xa6,0x27,0x8a,0x59,0x87,0x28,0x9a,
+ 0xc2,0x86,0x5d,0x29,0x01,0x00,0x06,
+ 0x00 }},
+ {{0xa6,0x27,0x8a,0x59,0x87,0x28,0x9e,
+ 0x03,0x87,0xdf,0x29,0x01,0x00,0x06,
+ 0x00 }},
+ {{0x9c,0x31,0x80,0x59,0x87,0x28,0xd4,
+ 0x3f,0x83,0x57,0x29,0x01,0x00,0x06,
+ 0x01 }},
+ {{0x8e,0x3f,0x92,0x79,0x07,0x28,0xd4,
+ 0x93,0x87,0xff,0x29,0x21,0x00,0x06,
+ 0x01}}
+};
+
+static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1XXXxXXX_1[] = /* TW: New */
+{
+ {{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,0xa9,0x17,0x24,0xf5,
+ 0x02,0x88,0xff,0x25,0x10,0x00,0x07,
+ 0x01}}
+};
+
+static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1XXXxXXX_1_H[] = /* TW: New */
+{
+ {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
+ 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
+ 0x00}},
+ {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
+ 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
+ 0x00}},
+ {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
+ 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
+ 0x00}},
+ {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
+ 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
+ 0x00}},
+ {{0x38,0x27,0x9c,0x2c,0x80,0x0b,0x3e,
+ 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
+ 0x00}},
+ {{0x4d,0x31,0x91,0x3b,0x03,0x72,0xf0,
+ 0x58,0x8c,0x57,0x73,0x20,0x00,0x01,
+ 0x01}},
+ {{0x63,0x3f,0x87,0x4a,0x92,0x24,0xf5,
+ 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+ 0x01}}
+};
+
+static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11400x1050_1[] = /* TW: New */
+{
+ {{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}}
+};
+
+static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11400x1050_1_H[] = /* TW: New */
+{
+ {{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}}
+};
+
+static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11400x1050_2[] = /* TW: New */
+{
+ {{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}}
+};
+
+static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11400x1050_2_H[] = /* TW: New */
+{
+ {{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}}
+};
+
+static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11280x768_1[] = /* TW: New */
+{ /* TW: Temp data, invalid */
+ {{0x7e,0x4f,0x82,0x56,0x04,0xb8,0x1f,
+ 0x90,0x84,0x8f,0xb9,0x30,0x00,0x06,
+ 0x00 }},
+ {{0x7e,0x4f,0x82,0x56,0x04,0x86,0x1f,
+ 0x5e,0x82,0x5d,0x87,0x10,0x00,0x06,
+ 0x00 }},
+ {{0x7e,0x4f,0x82,0x56,0x04,0xb8,0x1f,
+ 0x90,0x84,0x8f,0xb9,0x30,0x00,0x06,
+ 0x00 }},
+ {{0x7e,0x4f,0x82,0x56,0x04,0x86,0x1f,
+ 0x5e,0x82,0x5d,0x87,0x10,0x00,0x06,
+ 0x00 }},
+ {{0x7e,0x4f,0x82,0x56,0x04,0x08,0x3e,
+ 0xe0,0x84,0xdf,0x09,0x00,0x00,0x06,
+ 0x00 }},
+ {{0x92,0x63,0x96,0x6a,0x18,0x80,0xf0,
+ 0x58,0x8c,0x57,0x81,0x20,0x00,0x06,
+ 0x01 }},
+ {{0xae,0x7f,0x92,0x86,0x94,0x28,0xf5,
+ 0x00,0x84,0xff,0x29,0x10,0x00,0x02,
+ 0x01 }},
+ {{0xce,0x9f,0x92,0xa6,0x14,0x28,0x5a,
+ 0x00,0x84,0xff,0x29,0x09,0x00,0x07,
+ 0x01}}
+};
+
+static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11280x768_1_H[] = /* TW: New */
+{ /* TW: Temp data, invalid */
+ {{0x56,0x27,0x9a,0x2e,0x1c,0xb8,0x1f,
+ 0x90,0x84,0x8f,0xb9,0x30,0x00,0x05,
+ 0x00 }},
+ {{0x56,0x27,0x9a,0x2e,0x1c,0x86,0x1f,
+ 0x5e,0x82,0x5d,0x87,0x10,0x00,0x05,
+ 0x00 }},
+ {{0x56,0x27,0x9a,0x2e,0x1c,0xb8,0x1f,
+ 0x90,0x84,0x8f,0xb9,0x30,0x00,0x05,
+ 0x00 }},
+ {{0x56,0x27,0x9a,0x2e,0x1c,0x86,0x1f,
+ 0x5e,0x82,0x5d,0x87,0x10,0x00,0x05,
+ 0x01 }},
+ {{0x56,0x27,0x9a,0x2e,0x1c,0x08,0x3e,
+ 0xe0,0x84,0xdf,0x09,0x00,0x00,0x05,
+ 0x00 }},
+ {{0x60,0x31,0x84,0x38,0x86,0x80,0xf0,
+ 0x58,0x8c,0x57,0x81,0x20,0x00,0x01,
+ 0x01 }},
+ {{0x6e,0x3f,0x92,0x46,0x94,0x28,0xf5,
+ 0x00,0x84,0xff,0x29,0x10,0x00,0x01,
+ 0x01 }}
+};
+
+static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11280x768_2[] = /* TW: New */
+{ /* TW: Temp data, invalid */
+ {{0xce,0x4f,0x92,0x81,0x0f,0x28,0x9a,
+ 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x03,
+ 0x00 }},
+ {{0xce,0x4f,0x92,0x81,0x0f,0x28,0x9a,
+ 0xc2,0x86,0x5d,0x29,0x01,0x00,0x03,
+ 0x00 }},
+ {{0xce,0x4f,0x92,0x81,0x0f,0x28,0x9a,
+ 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x03,
+ 0x00 }},
+ {{0xce,0x4f,0x92,0x81,0x0f,0x28,0x9a,
+ 0xc2,0x86,0x5d,0x29,0x01,0x00,0x03,
+ 0x00 }},
+ {{0xce,0x4f,0x92,0x81,0x0f,0x28,0x9e,
+ 0x03,0x87,0xdf,0x29,0x01,0x00,0x03,
+ 0x00 }},
+ {{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,0xa6,0x14,0x28,0x5a,
+ 0x00,0x84,0xff,0x29,0x09,0x00,0x07,
+ 0x01}}
+};
+
+static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11280x768_2_H[] = /* TW: New */
+{ /* TW: Temp data, invalid */
+ {{0xa6,0x27,0x8a,0x59,0x87,0x28,0x9a,
+ 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x06,
+ 0x00 }},
+ {{0xa6,0x27,0x8a,0x59,0x87,0x28,0x9a,
+ 0xc2,0x86,0x5d,0x29,0x01,0x00,0x06,
+ 0x00 }},
+ {{0xa6,0x27,0x8a,0x59,0x87,0x28,0x9a,
+ 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x06,
+ 0x00 }},
+ {{0xa6,0x27,0x8a,0x59,0x87,0x28,0x9a,
+ 0xc2,0x86,0x5d,0x29,0x01,0x00,0x06,
+ 0x00 }},
+ {{0xa6,0x27,0x8a,0x59,0x87,0x28,0x9e,
+ 0x03,0x87,0xdf,0x29,0x01,0x00,0x06,
+ 0x00 }},
+ {{0x9c,0x31,0x80,0x59,0x87,0x28,0xd4,
+ 0x3f,0x83,0x57,0x29,0x01,0x00,0x06,
+ 0x01 }},
+ {{0x8e,0x3f,0x92,0x79,0x07,0x28,0xd4,
+ 0x93,0x87,0xff,0x29,0x21,0x00,0x06,
+ 0x01}}
+};
+
+static const SiS310_LVDSCRT1DataStruct SiS310_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 SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x600_1_H[] =
+{
+ {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
+ 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
+ 0x00}},
+ {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
+ 0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
+ 0x00}},
+ {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
+ 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
+ 0x00}},
+ {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
+ 0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
+ 0x00}},
+ {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
+ 0xe2,0x89,0xdf,0x05,0x00,0x00,0x44,
+ 0x00}},
+ {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
+ 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
+ 0x01}},
+ {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+ 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+ 0x01}}
+};
+
+static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x600_2[] =
+{
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+ 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+ 0x00}},
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+ 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+ 0x00}},
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+ 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+ 0x00}},
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+ 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+ 0x00}},
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+ 0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
+ 0x00}},
+ {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
+ 0xae,0x84,0x57,0x25,0x30,0x00,0x02,
+ 0x01}},
+ {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+ 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+ 0x01}}
+};
+
+static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x600_2_H[] =
+{
+ {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+ 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+ 0x00}},
+ {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+ 0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+ 0x00}},
+ {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+ 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+ 0x00}},
+ {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+ 0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+ 0x00}},
+ {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+ 0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
+ 0x00}},
+ {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
+ 0xae,0x84,0x57,0x25,0x30,0x00,0x01,
+ 0x01}},
+ {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+ 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+ 0x01}}
+};
+
+static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11152x768_1[] =
+{
+ {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
+ 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
+ 0x00}},
+ {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
+ 0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
+ 0x00}},
+ {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
+ 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
+ 0x00}},
+ {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
+ 0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
+ 0x00}},
+ {{0x64,0x4f,0x88,0x54,0x9f,0x04,0x3e,
+ 0xe2,0x89,0xdf,0x05,0x00,0x00,0x01,
+ 0x00}},
+ {{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0,
+ 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26,
+ 0x01}},
+ {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+ 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+ 0x01}}
+};
+
+static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11152x768_1_H[] =
+{
+ {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
+ 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
+ 0x00}},
+ {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
+ 0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
+ 0x00}},
+ {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
+ 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
+ 0x00}},
+ {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
+ 0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
+ 0x00}},
+ {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
+ 0xe2,0x89,0xdf,0x05,0x00,0x00,0x44,
+ 0x00}},
+ {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
+ 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
+ 0x01}},
+ {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+ 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+ 0x01}}
+};
+
+static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11152x768_2[] =
+{
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+ 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+ 0x00}},
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+ 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+ 0x00}},
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+ 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+ 0x00}},
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+ 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+ 0x00}},
+ {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+ 0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
+ 0x00}},
+ {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
+ 0xae,0x84,0x57,0x25,0x30,0x00,0x02,
+ 0x01}},
+ {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+ 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+ 0x01}}
+};
+
+static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11152x768_2_H[] =
+{
+ {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+ 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+ 0x00}},
+ {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+ 0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+ 0x00}},
+ {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+ 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+ 0x00}},
+ {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+ 0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+ 0x00}},
+ {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+ 0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
+ 0x00}},
+ {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
+ 0xae,0x84,0x57,0x25,0x30,0x00,0x01,
+ 0x01}},
+ {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+ 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+ 0x01}}
+};
+
+static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11600x1200_1[] =
+{ /* TW: Temporary data - invalid */
+ {{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}}
+};
+
+static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11600x1200_1_H[] =
+{ /* TW: Temporary data - invalid */
+ {{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}}
+};
+
+static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11600x1200_2[] =
+{ /* TW: Temporary data - invalid */
+ {{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}}
+};
+
+static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11600x1200_2_H[] = /* TW: New */
+{ /* TW: Temporary data - invalid */
+ {{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}}
+};
+
+
+static const SiS310_LVDSCRT1DataStruct SiS310_CHTVCRT1UNTSC[] = /* TW: New */
+{
+ {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
+ 0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,
+ 0x00 }},
+ {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
+ 0xd0,0x82,0x5d,0x57,0x00,0x00,0x01,
+ 0x00 }},
+ {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
+ 0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,
+ 0x00 }},
+ {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
+ 0xd0,0x82,0x5d,0x57,0x00,0x00,0x01,
+ 0x00 }},
+ {{0x5d,0x4f,0x81,0x56,0x99,0x56,0xba,
+ 0x0a,0x84,0xdf,0x57,0x00,0x00,0x01,
+ 0x00 }},
+ {{0x80,0x63,0x84,0x6d,0x0f,0xec,0xf0,
+ 0x7a,0x8f,0x57,0xed,0x20,0x00,0x06,
+ 0x01 }},
+ {{0x8c,0x7f,0x90,0x86,0x09,0xaf,0xf5, /* TW: 1024x768 */
+ 0x36,0x88,0xff,0xb0,0x10,0x00,0x02,
+ 0x01}}
+};
+
+static const SiS310_LVDSCRT1DataStruct SiS310_CHTVCRT1ONTSC[] = /* TW: New */
+{
+ {{0x63,0x4f,0x87,0x5a,0x9f,0x0b,0x3e,
+ 0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,
+ 0x00 }},
+ {{0x63,0x4f,0x87,0x5a,0x9f,0x0b,0x3e,
+ 0xb0,0x8d,0x5d,0x0c,0x00,0x00,0x01,
+ 0x00 }},
+ {{0x63,0x4f,0x87,0x5a,0x9f,0x0b,0x3e,
+ 0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,
+ 0x00 }},
+ {{0x63,0x4f,0x87,0x5a,0x9f,0x0b,0x3e,
+ 0xb0,0x8d,0x5d,0x0c,0x00,0x00,0x01,
+ 0x00 }},
+ {{0x5d,0x4f,0x81,0x58,0x9d,0x0b,0x3e,
+ 0xe8,0x84,0xdf,0x0c,0x00,0x00,0x01,
+ 0x00 }},
+ {{0x7d,0x63,0x81,0x68,0x0e,0xba,0xf0,
+ 0x78,0x8a,0x57,0xbb,0x20,0x00,0x06,
+ 0x01 }},
+ {{0x8c,0x7f,0x90,0x82,0x06,0x46,0xf5, /* TW: 1024x768 */
+ 0x15,0x88,0xff,0x47,0x70,0x00,0x02,
+ 0x01 }}
+};
+
+static const SiS310_LVDSCRT1DataStruct SiS310_CHTVCRT1UPAL[] = /* TW: New */
+{
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+ 0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,
+ 0x00 }},
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+ 0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
+ 0x00 }},
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+ 0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,
+ 0x00 }},
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+ 0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
+ 0x00 }},
+ {{0x64,0x4f,0x88,0x5a,0x9f,0x6f,0xba,
+ 0x15,0x83,0xdf,0x70,0x00,0x00,0x01,
+ 0x00 }},
+ {{0x73,0x63,0x97,0x69,0x8b,0xec,0xf0,
+ 0x90,0x8c,0x57,0xed,0x20,0x00,0x05,
+ 0x01 }},
+ {{0xaa,0x7f,0x8e,0x8e,0x96,0xe6,0xf5, /* TW: 1024x768 */
+ 0x50,0x88,0xff,0xe7,0x10,0x00,0x02,
+ 0x01}}
+};
+
+static const SiS310_LVDSCRT1DataStruct SiS310_CHTVCRT1OPAL[] = /* TW: New */
+{
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+ 0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
+ 0x00 }},
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+ 0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
+ 0x00 }},
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+ 0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
+ 0x00 }},
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+ 0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
+ 0x00 }},
+ {{0x64,0x4f,0x88,0x58,0x9d,0x6f,0xba,
+ 0x15,0x83,0xdf,0x70,0x00,0x00,0x01,
+ 0x00 }},
+ {{0x71,0x63,0x95,0x69,0x8c,0x6f,0xf0,
+ 0x5a,0x8b,0x57,0x70,0x20,0x00,0x05,
+ 0x01 }},
+ {{0xaa,0x7f,0x8e,0x8f,0x96,0x69,0xf5, /* TW: 1024x768 */
+ 0x28,0x88,0xff,0x6a,0x10,0x00,0x02,
+ 0x01 }}
+};
+
+static const SiS310_LVDSCRT1DataStruct SiS310_CHTVCRT1SOPAL[] = /* TW: New */
+{
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+ 0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
+ 0x00 }},
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+ 0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
+ 0x00 }},
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+ 0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
+ 0x00 }},
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+ 0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
+ 0x00 }},
+ {{0x64,0x4f,0x88,0x58,0x9d,0x6f,0xba,
+ 0x15,0x83,0xdf,0x70,0x00,0x00,0x01,
+ 0x00 }},
+ {{0x71,0x63,0x95,0x69,0x8c,0x6f,0xf0,
+ 0x5a,0x8b,0x57,0x70,0x20,0x00,0x05,
+ 0x01 }},
+ {{0xaa,0x7f,0x8e,0x8f,0x96,0x69,0xf5, /* TW: 1024x768 */
+ 0x28,0x88,0xff,0x6a,0x10,0x00,0x02,
+ 0x01 }}
+};
+
+/* TW: New data for Chrontel 7019 (From 650/LVDS BIOS 1.10.0) */
+typedef struct _SiS310_CHTVRegDataStruct
+{
+ UCHAR Reg[16];
+} SiS310_CHTVRegDataStruct;
+
+static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_UNTSC[] =
+{
+ {{0x4a,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x4a,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x4a,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x4a,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x6a,0x77,0xbb,0x6e,0x84,0x2e,0x02,0x5a,0x04,0x00,0x80,0x20,0x7e,0x80,0x98,0x00}},
+ {{0xcf,0x77,0xb7,0xc8,0x84,0x3b,0x02,0x5a,0x04,0x00,0x80,0x19,0x88,0x30,0x7f,0x00}},
+ {{0xee,0x77,0xbb,0x66,0x87,0x32,0x01,0x5a,0x04,0x00,0x80,0x1b,0xd3,0xf2,0x36,0x00}}
+};
+
+static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_ONTSC[] =
+{
+ {{0x49,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x49,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x49,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x49,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x69,0x77,0xbb,0x6e,0x84,0x1e,0x00,0x5a,0x04,0x00,0x80,0x25,0x1a,0x43,0x04,0x00}},
+ {{0xce,0x77,0xb7,0xb6,0x83,0x2c,0x02,0x5a,0x04,0x00,0x80,0x1c,0x00,0x82,0x97,0x00}},
+ {{0xed,0x77,0xbb,0x66,0x8c,0x21,0x02,0x5a,0x04,0x00,0x80,0x1f,0x9f,0xc1,0x0c,0x00}}
+};
+
+static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_UPAL[] =
+{
+ {{0x41,0x7f,0xb7,0x34,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x41,0x7f,0xb7,0x80,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x41,0x7f,0xb7,0x34,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x41,0x7f,0xb7,0x12,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x61,0x7f,0xb7,0x99,0x84,0x35,0x04,0x5a,0x05,0x00,0x80,0x26,0x2a,0x55,0x5d,0x00}},
+ {{0xc3,0x7f,0xb7,0x7a,0x84,0x40,0x02,0x5a,0x05,0x00,0x80,0x1f,0x84,0x3d,0x28,0x00}},
+ {{0xe5,0x7f,0xb7,0x1d,0xa7,0x3e,0x04,0x5a,0x05,0x00,0x80,0x20,0x3e,0xe4,0x22,0x00}}
+};
+
+static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_OPAL[] =
+{
+ {{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x41,0x7f,0xb7,0x86,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x41,0x7f,0xb7,0x86,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x61,0x7f,0xb7,0x99,0x84,0x35,0x04,0x5a,0x05,0x00,0x80,0x26,0x2a,0x55,0x5d,0x00}},
+ {{0xc1,0x7f,0xb7,0x4d,0x8c,0x1e,0x31,0x5a,0x05,0x00,0x80,0x26,0x78,0x19,0x34,0x00}},
+ {{0xe4,0x7f,0xb7,0x1e,0xaf,0x29,0x37,0x5a,0x05,0x00,0x80,0x25,0x8c,0xb2,0x2a,0x00}}
+};
+
+static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_SOPAL[] =
+{
+ {{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x41,0x7f,0xb7,0x86,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x41,0x7f,0xb7,0x86,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x61,0x7f,0xb7,0x99,0x84,0x35,0x04,0x5a,0x05,0x00,0x80,0x26,0x2a,0x55,0x5d,0x00}},
+ {{0xc1,0x7f,0xb7,0x4d,0x8c,0x1e,0x31,0x5a,0x05,0x00,0x80,0x26,0x78,0x19,0x34,0x00}},
+ {{0xe4,0x7f,0xb7,0x1e,0xaf,0x29,0x37,0x5a,0x05,0x00,0x80,0x25,0x8c,0xb2,0x2a,0x00}}
+};
+
+static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_UPALM[] =
+{
+ {{0x52,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x52,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x52,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x52,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x72,0x77,0xbb,0x6e,0x84,0x2e,0x02,0x5a,0x04,0x00,0x80,0x20,0x76,0xdb,0x6e,0x00}},
+ {{0xd7,0x77,0xb7,0xc8,0x84,0x3b,0x02,0x5a,0x04,0x00,0x80,0x19,0x84,0x0a,0xc7,0x00}},
+ {{0xf6,0x77,0xbb,0x66,0x87,0x32,0x01,0x5a,0x04,0x00,0x80,0x1b,0xdc,0xb0,0x8d,0x00}}
+};
+
+static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_OPALM[] =
+{
+ {{0x51,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x51,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x51,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x51,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x71,0x77,0xbb,0x6e,0x84,0x1e,0x00,0x5a,0x04,0x00,0x80,0x25,0x1a,0x1f,0x59,0x00}},
+ {{0xd6,0x77,0xb7,0xb6,0x83,0x2c,0x02,0x5a,0x04,0x00,0x80,0x1b,0xf8,0x1f,0x82,0x00}},
+ {{0xf5,0x77,0xbb,0x66,0x8c,0x21,0x02,0x5a,0x04,0x00,0x80,0x1f,0x58,0x46,0x9f,0x00}}
+};
+
+static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_UPALN[] =
+{
+ {{0x41,0x7f,0xb7,0x34,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x41,0x7f,0xb7,0x80,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x41,0x7f,0xb7,0x34,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x41,0x7f,0xb7,0x12,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x61,0x7f,0xb7,0x99,0x84,0x35,0x04,0x5a,0x05,0x00,0x80,0x1f,0x0d,0x54,0x5e,0x00}},
+ {{0xc3,0x7f,0xb7,0x7a,0x84,0x40,0x02,0x5a,0x05,0x00,0x80,0x19,0x78,0xef,0x35,0x00}},
+ {{0xe5,0x7f,0xb7,0x1d,0xa7,0x3e,0x04,0x5a,0x05,0x00,0x80,0x1a,0x33,0x3f,0x2f,0x00}}
+};
+
+static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_OPALN[] =
+{
+ {{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x41,0x7f,0xb7,0x86,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x41,0x7f,0xb7,0x86,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+ {{0x61,0x7f,0xb7,0x99,0x84,0x35,0x04,0x5a,0x05,0x00,0x80,0x1f,0x0d,0x54,0x5e,0x00}},
+ {{0xc1,0x7f,0xb7,0x4d,0x8c,0x1e,0x31,0x5a,0x05,0x00,0x80,0x1f,0x15,0xc0,0x1e,0x00}},
+ {{0xe4,0x7f,0xb7,0x1e,0xaf,0x29,0x37,0x5a,0x05,0x00,0x80,0x1d,0xf1,0x6c,0xcb,0x00}}
+};
+
+static const UCHAR SiS310_CHTVVCLKUNTSC[] = {0x41,0x41,0x41,0x41,0x42,0x46,0x53};
+
+static const UCHAR SiS310_CHTVVCLKONTSC[] = {0x48,0x48,0x48,0x48,0x45,0x43,0x51};
+
+static const UCHAR SiS310_CHTVVCLKUPAL[] = {0x47,0x47,0x47,0x47,0x48,0x4a,0x54};
+
+static const UCHAR SiS310_CHTVVCLKOPAL[] = {0x47,0x47,0x47,0x47,0x48,0x4f,0x52};
+
+static const UCHAR SiS310_CHTVVCLKSOPAL[] = {0x47,0x47,0x47,0x47,0x48,0x4f,0x52};
+
+static const UCHAR SiS310_CHTVVCLKUPALM[] = {0x41,0x41,0x41,0x41,0x42,0x46,0x53};
+
+static const UCHAR SiS310_CHTVVCLKOPALM[] = {0x48,0x48,0x48,0x48,0x45,0x43,0x51};
+
+static const UCHAR SiS310_CHTVVCLKUPALN[] = {0x47,0x47,0x47,0x47,0x48,0x4a,0x54};
+
+static const UCHAR SiS310_CHTVVCLKOPALN[] = {0x47,0x47,0x47,0x47,0x48,0x4f,0x52};
+
+/* TW: New end */
diff --git a/src/init.c b/src/init.c
new file mode 100644
index 0000000..74c302c
--- /dev/null
+++ b/src/init.c
@@ -0,0 +1,5968 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/init.c,v 1.6 2003/02/04 02:44:28 dawes Exp $ */
+/*
+ * Mode switching code (CRT1 section) for SiS 300/540/630/730/315/550/650/740/330
+ * (Universal module for Linux kernel framebuffer and XFree86 4.x)
+ *
+ * Assembler-To-C translation
+ * Copyright 2002 by Thomas Winischhofer <thomas@winischhofer.net>
+ * Minor parts Copyright SiS, Inc.
+ *
+ * Based on BIOS
+ * 1.10.07, 1.10a for SiS650/LVDS+CH7019
+ * 1.11.05 for 650/LVDS (w/o Chrontel)
+ * 1.07.1b, 1.11.6s, 1.11.6w, 1.11.7w, 1.11.8r for SiS650/301(B/LV)
+ * 2.04.50 (I) and 2.04.5c (II) for SiS630/301(B)
+ * 2.06.50 for 630/301B (dual VGA)
+ * 2.02.3b, 2.03.02, 2.04.5c, 2.07a and 2.08.b3 for 630/LVDS/LVDS+CH7005
+ * 2.04.5c, 2.04.6c for 730+LVDS+CH7005
+ * 1.09b for 315/301(B)
+ * 1.16.51 for 300+301LVX (ECS A907)
+ * 1.01.03 for 330 (Xabre 400)
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the copyright holder not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The copyright holder makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * 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.
+ *
+ */
+
+#include "init.h"
+
+#ifdef SIS300
+#include "300vtbl.h"
+#endif
+
+#ifdef SIS315H
+#include "310vtbl.h"
+#endif
+
+#ifdef LINUX_XF86
+BOOLEAN SiSBIOSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+ ScrnInfoPtr pScrn, DisplayModePtr mode, BOOLEAN IsCustom);
+DisplayModePtr SiSBuildBuiltInModeList(ScrnInfoPtr pScrn);
+#ifdef SISDUALHEAD /* TW: For dual head */
+BOOLEAN SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+ ScrnInfoPtr pScrn, DisplayModePtr mode, BOOLEAN IsCustom);
+BOOLEAN SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+ ScrnInfoPtr pScrn, DisplayModePtr mode);
+#endif /* dual head */
+#endif /* linux_xf86 */
+
+#ifdef LINUXBIOS
+BOOLEAN SiSInit(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+#endif
+
+#ifdef LINUX_XF86
+BOOLEAN SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+ ScrnInfoPtr pScrn,USHORT ModeNo, BOOLEAN dosetpitch);
+#else
+BOOLEAN SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+ USHORT ModeNo);
+#endif
+
+#if defined(ALLOC_PRAGMA)
+#pragma alloc_text(PAGE,SiSSetMode)
+#pragma alloc_text(PAGE,SiSInit)
+#endif
+
+static ULONG GetDRAMSize(SiS_Private *SiS_Pr,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension);
+
+static void DelaySeconds(int seconds);
+void SiS_DebugCode(SiS_Private *SiS_Pr, UCHAR code);
+
+#ifdef LINUX_XF86
+/* TW: Mode table for X driver */
+const UShort ModeIndex_320x480[] = {0x5a, 0x5b, 0x00, 0x00}; /* DSTN/FSTN */
+const UShort ModeIndex_512x384[] = {0x52, 0x58, 0x00, 0x5c};
+const UShort ModeIndex_640x400[] = {0x2f, 0x5d, 0x00, 0x5e};
+const UShort ModeIndex_640x480[] = {0x2e, 0x44, 0x00, 0x62};
+const UShort ModeIndex_720x480[] = {0x31, 0x33, 0x00, 0x35};
+const UShort ModeIndex_720x576[] = {0x32, 0x34, 0x00, 0x36};
+const UShort ModeIndex_800x480[] = {0x70, 0x7a, 0x00, 0x76};
+const UShort ModeIndex_800x600[] = {0x30, 0x47, 0x00, 0x63};
+const UShort ModeIndex_848x480[] = {0x39, 0x3b, 0x00, 0x3e};
+const UShort ModeIndex_856x480[] = {0x3f, 0x42, 0x00, 0x45};
+const UShort ModeIndex_1024x768[] = {0x38, 0x4a, 0x00, 0x64};
+const UShort ModeIndex_1024x576[] = {0x71, 0x74, 0x00, 0x77};
+const UShort ModeIndex_1024x600[] = {0x20, 0x21, 0x00, 0x22}; /* 300 series only */
+const UShort ModeIndex_1280x1024[] = {0x3a, 0x4d, 0x00, 0x65};
+const UShort ModeIndex_300_1280x960[] = {0x6e, 0x6f, 0x00, 0x7b};
+const UShort ModeIndex_310_1280x960[] = {0x7c, 0x7d, 0x00, 0x7e};
+const UShort ModeIndex_1152x768[] = {0x23, 0x24, 0x00, 0x25}; /* 300 series only */
+const UShort ModeIndex_1152x864[] = {0x29, 0x2a, 0x00, 0x2b};
+const UShort ModeIndex_1280x768[] = {0x23, 0x24, 0x00, 0x25}; /* 310/325 series only */
+const UShort ModeIndex_1280x720[] = {0x79, 0x75, 0x00, 0x78};
+const UShort ModeIndex_1360x768[] = {0x48, 0x4b, 0x00, 0x4e};
+const UShort ModeIndex_1400x1050[] = {0x26, 0x27, 0x00, 0x28}; /* 310/325 series only */
+const UShort ModeIndex_1600x1200[] = {0x3c, 0x3d, 0x00, 0x66};
+const UShort ModeIndex_1920x1440[] = {0x68, 0x69, 0x00, 0x6b};
+const UShort ModeIndex_300_2048x1536[]= {0x6c, 0x6d, 0x00, 0x00};
+const UShort ModeIndex_310_2048x1536[]= {0x6c, 0x6d, 0x00, 0x6e};
+#endif
+
+static void
+DelaySeconds(int seconds)
+{
+ int i;
+#ifdef WIN2000
+ int j;
+#endif
+
+ for (i=0;i<seconds;i++) {
+#ifdef TC
+ delay(1000);
+#endif
+
+#ifdef WIN2000
+ for (j=0;j<20000;j++)
+ VideoPortStallExecution(50);
+#endif
+
+#ifdef WINCE_HEADER
+#endif
+
+#ifdef LINUX_KERNEL
+#endif
+ }
+}
+
+void
+SiS_DebugCode(SiS_Private *SiS_Pr, UCHAR code)
+{
+ OutPortByte(0x80, code);
+ DelaySeconds(0x3);
+}
+
+#ifdef SIS300
+static void
+InitTo300Pointer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ SiS_Pr->SiS_SModeIDTable = (SiS_StStruct *)SiS300_SModeIDTable;
+ SiS_Pr->SiS_VBModeIDTable = (SiS_VBModeStruct *)SiS300_VBModeIDTable;
+ SiS_Pr->SiS_StandTable = (SiS_StandTableStruct *)SiS300_StandTable;
+ SiS_Pr->SiS_EModeIDTable = (SiS_ExtStruct *)SiS300_EModeIDTable;
+ SiS_Pr->SiS_RefIndex = (SiS_Ext2Struct *)SiS300_RefIndex;
+ SiS_Pr->SiS_CRT1Table = (SiS_CRT1TableStruct *)SiS300_CRT1Table;
+ if(HwDeviceExtension->jChipType == SIS_300) {
+ SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS300_MCLKData_300; /* 300 */
+ } else {
+ SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS300_MCLKData_630; /* 630 */
+ }
+ SiS_Pr->SiS_ECLKData = (SiS_ECLKDataStruct *)SiS300_ECLKData;
+ SiS_Pr->SiS_VCLKData = (SiS_VCLKDataStruct *)SiS300_VCLKData;
+ SiS_Pr->SiS_VBVCLKData = (SiS_VBVCLKDataStruct *)SiS300_VCLKData;
+ SiS_Pr->SiS_ScreenOffset = SiS300_ScreenOffset;
+ SiS_Pr->SiS_StResInfo = (SiS_StResInfoStruct *)SiS300_StResInfo;
+ SiS_Pr->SiS_ModeResInfo = (SiS_ModeResInfoStruct *)SiS300_ModeResInfo;
+
+ SiS_Pr->pSiS_OutputSelect = &SiS300_OutputSelect;
+ SiS_Pr->pSiS_SoftSetting = &SiS300_SoftSetting;
+
+ SiS_Pr->SiS_SR15 = SiS300_SR15;
+
+#ifndef LINUX_XF86
+ 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_NTSCPhase = SiS300_NTSCPhase;
+ SiS_Pr->SiS_PALPhase = SiS300_PALPhase;
+ SiS_Pr->SiS_NTSCPhase2 = SiS300_NTSCPhase2;
+ SiS_Pr->SiS_PALPhase2 = SiS300_PALPhase2;
+ SiS_Pr->SiS_PALMPhase = SiS300_PALMPhase;
+ SiS_Pr->SiS_PALNPhase = SiS300_PALNPhase;
+ SiS_Pr->SiS_PALMPhase2 = SiS300_PALMPhase2;
+ SiS_Pr->SiS_PALNPhase2 = SiS300_PALNPhase2;
+
+ SiS_Pr->SiS_StLCD1024x768Data = (SiS_LCDDataStruct *)SiS300_StLCD1024x768Data;
+ SiS_Pr->SiS_ExtLCD1024x768Data = (SiS_LCDDataStruct *)SiS300_ExtLCD1024x768Data;
+ SiS_Pr->SiS_St2LCD1024x768Data = (SiS_LCDDataStruct *)SiS300_St2LCD1024x768Data;
+ SiS_Pr->SiS_StLCD1280x1024Data = (SiS_LCDDataStruct *)SiS300_StLCD1280x1024Data;
+ SiS_Pr->SiS_ExtLCD1280x1024Data = (SiS_LCDDataStruct *)SiS300_ExtLCD1280x1024Data;
+ SiS_Pr->SiS_St2LCD1280x1024Data = (SiS_LCDDataStruct *)SiS300_St2LCD1280x1024Data;
+ SiS_Pr->SiS_NoScaleData1024x768 = (SiS_LCDDataStruct *)SiS300_NoScaleData1024x768;
+ SiS_Pr->SiS_NoScaleData1280x1024 = (SiS_LCDDataStruct *)SiS300_NoScaleData1280x1024;
+ SiS_Pr->SiS_LCD1280x960Data = (SiS_LCDDataStruct *)SiS300_LCD1280x960Data;
+ SiS_Pr->SiS_ExtLCD1400x1050Data = (SiS_LCDDataStruct *)SiS300_ExtLCD1400x1050Data;
+ SiS_Pr->SiS_ExtLCD1600x1200Data = (SiS_LCDDataStruct *)SiS300_ExtLCD1600x1200Data;
+ SiS_Pr->SiS_StLCD1400x1050Data = (SiS_LCDDataStruct *)SiS300_StLCD1400x1050Data;
+ SiS_Pr->SiS_StLCD1600x1200Data = (SiS_LCDDataStruct *)SiS300_StLCD1600x1200Data;
+ SiS_Pr->SiS_NoScaleData1400x1050 = (SiS_LCDDataStruct *)SiS300_NoScaleData1400x1050;
+ SiS_Pr->SiS_NoScaleData1600x1200 = (SiS_LCDDataStruct *)SiS300_NoScaleData1600x1200;
+
+ SiS_Pr->SiS_StPALData = (SiS_TVDataStruct *)SiS300_StPALData;
+ SiS_Pr->SiS_ExtPALData = (SiS_TVDataStruct *)SiS300_ExtPALData;
+ SiS_Pr->SiS_StNTSCData = (SiS_TVDataStruct *)SiS300_StNTSCData;
+ SiS_Pr->SiS_ExtNTSCData = (SiS_TVDataStruct *)SiS300_ExtNTSCData;
+#ifdef oldHV
+ SiS_Pr->SiS_St1HiTVData = (SiS_TVDataStruct *)SiS300_St1HiTVData;
+ SiS_Pr->SiS_St2HiTVData = (SiS_TVDataStruct *)SiS300_St2HiTVData;
+ SiS_Pr->SiS_ExtHiTVData = (SiS_TVDataStruct *)SiS300_ExtHiTVData;
+#endif
+
+ SiS_Pr->SiS_NTSCTiming = SiS300_NTSCTiming;
+ SiS_Pr->SiS_PALTiming = SiS300_PALTiming;
+#ifdef oldHV
+ SiS_Pr->SiS_HiTVSt1Timing = SiS300_HiTVSt1Timing;
+ SiS_Pr->SiS_HiTVSt2Timing = SiS300_HiTVSt2Timing;
+ SiS_Pr->SiS_HiTVTextTiming = SiS300_HiTVTextTiming;
+ SiS_Pr->SiS_HiTVGroup3Data = SiS300_HiTVGroup3Data;
+ SiS_Pr->SiS_HiTVGroup3Simu = SiS300_HiTVGroup3Simu;
+ SiS_Pr->SiS_HiTVGroup3Text = SiS300_HiTVGroup3Text;
+#endif
+
+ SiS_Pr->SiS_PanelDelayTbl = (SiS_PanelDelayTblStruct *)SiS300_PanelDelayTbl;
+ SiS_Pr->SiS_PanelDelayTblLVDS = (SiS_PanelDelayTblStruct *)SiS300_PanelDelayTblLVDS;
+
+ SiS_Pr->SiS_LVDS800x600Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS800x600Data_1;
+ SiS_Pr->SiS_LVDS800x600Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS800x600Data_2;
+ SiS_Pr->SiS_LVDS1024x768Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS1024x768Data_1;
+ SiS_Pr->SiS_LVDS1024x768Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS1024x768Data_2;
+ SiS_Pr->SiS_LVDS1280x1024Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS1280x1024Data_1;
+ SiS_Pr->SiS_LVDS1280x1024Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS1280x1024Data_2;
+ SiS_Pr->SiS_LVDS1280x960Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS1280x1024Data_1;
+ SiS_Pr->SiS_LVDS1280x960Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS1280x1024Data_2;
+ SiS_Pr->SiS_LVDS1400x1050Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS1400x1050Data_1;
+ SiS_Pr->SiS_LVDS1400x1050Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS1400x1050Data_2;
+ SiS_Pr->SiS_LVDS1280x768Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS1280x768Data_1;
+ SiS_Pr->SiS_LVDS1280x768Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS1280x768Data_2;
+ SiS_Pr->SiS_LVDS1024x600Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS1024x600Data_1;
+ SiS_Pr->SiS_LVDS1024x600Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS1024x600Data_2;
+ SiS_Pr->SiS_LVDS1152x768Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS1152x768Data_1;
+ SiS_Pr->SiS_LVDS1152x768Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS1152x768Data_2;
+ SiS_Pr->SiS_LVDSXXXxXXXData_1 = (SiS_LVDSDataStruct *)SiS300_LVDSXXXxXXXData_1;
+ SiS_Pr->SiS_LVDS320x480Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS320x480Data_1;
+ SiS_Pr->SiS_LVDS640x480Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS640x480Data_1;
+ SiS_Pr->SiS_LCDA1400x1050Data_1 = (SiS_LVDSDataStruct *)SiS300_LCDA1400x1050Data_1;
+ SiS_Pr->SiS_LCDA1400x1050Data_2 = (SiS_LVDSDataStruct *)SiS300_LCDA1400x1050Data_2;
+ SiS_Pr->SiS_LCDA1600x1200Data_1 = (SiS_LVDSDataStruct *)SiS300_LCDA1600x1200Data_1;
+ SiS_Pr->SiS_LCDA1600x1200Data_2 = (SiS_LVDSDataStruct *)SiS300_LCDA1600x1200Data_2;
+ SiS_Pr->SiS_CHTVUNTSCData = (SiS_LVDSDataStruct *)SiS300_CHTVUNTSCData;
+ SiS_Pr->SiS_CHTVONTSCData = (SiS_LVDSDataStruct *)SiS300_CHTVONTSCData;
+ SiS_Pr->SiS_CHTVUPALData = (SiS_LVDSDataStruct *)SiS300_CHTVUPALData;
+ SiS_Pr->SiS_CHTVOPALData = (SiS_LVDSDataStruct *)SiS300_CHTVOPALData;
+ SiS_Pr->SiS_CHTVUPALMData = (SiS_LVDSDataStruct *)SiS300_CHTVUNTSCData; /* not supported on 300 series */
+ SiS_Pr->SiS_CHTVOPALMData = (SiS_LVDSDataStruct *)SiS300_CHTVONTSCData; /* not supported on 300 series */
+ SiS_Pr->SiS_CHTVUPALNData = (SiS_LVDSDataStruct *)SiS300_CHTVUPALData; /* not supported on 300 series */
+ SiS_Pr->SiS_CHTVOPALNData = (SiS_LVDSDataStruct *)SiS300_CHTVOPALData; /* not supported on 300 series */
+ SiS_Pr->SiS_CHTVSOPALData = (SiS_LVDSDataStruct *)SiS300_CHTVSOPALData;
+ SiS_Pr->SiS_PanelType00_1 = (SiS_LVDSDesStruct *)SiS300_PanelType00_1;
+ SiS_Pr->SiS_PanelType01_1 = (SiS_LVDSDesStruct *)SiS300_PanelType01_1;
+ SiS_Pr->SiS_PanelType02_1 = (SiS_LVDSDesStruct *)SiS300_PanelType02_1;
+ SiS_Pr->SiS_PanelType03_1 = (SiS_LVDSDesStruct *)SiS300_PanelType03_1;
+ SiS_Pr->SiS_PanelType04_1 = (SiS_LVDSDesStruct *)SiS300_PanelType04_1;
+ SiS_Pr->SiS_PanelType05_1 = (SiS_LVDSDesStruct *)SiS300_PanelType05_1;
+ SiS_Pr->SiS_PanelType06_1 = (SiS_LVDSDesStruct *)SiS300_PanelType06_1;
+ SiS_Pr->SiS_PanelType07_1 = (SiS_LVDSDesStruct *)SiS300_PanelType07_1;
+ SiS_Pr->SiS_PanelType08_1 = (SiS_LVDSDesStruct *)SiS300_PanelType08_1;
+ SiS_Pr->SiS_PanelType09_1 = (SiS_LVDSDesStruct *)SiS300_PanelType09_1;
+ SiS_Pr->SiS_PanelType0a_1 = (SiS_LVDSDesStruct *)SiS300_PanelType0a_1;
+ SiS_Pr->SiS_PanelType0b_1 = (SiS_LVDSDesStruct *)SiS300_PanelType0b_1;
+ SiS_Pr->SiS_PanelType0c_1 = (SiS_LVDSDesStruct *)SiS300_PanelType0c_1;
+ SiS_Pr->SiS_PanelType0d_1 = (SiS_LVDSDesStruct *)SiS300_PanelType0d_1;
+ SiS_Pr->SiS_PanelType0e_1 = (SiS_LVDSDesStruct *)SiS300_PanelType0e_1;
+ SiS_Pr->SiS_PanelType0f_1 = (SiS_LVDSDesStruct *)SiS300_PanelType0f_1;
+ SiS_Pr->SiS_PanelType00_2 = (SiS_LVDSDesStruct *)SiS300_PanelType00_2;
+ SiS_Pr->SiS_PanelType01_2 = (SiS_LVDSDesStruct *)SiS300_PanelType01_2;
+ SiS_Pr->SiS_PanelType02_2 = (SiS_LVDSDesStruct *)SiS300_PanelType02_2;
+ SiS_Pr->SiS_PanelType03_2 = (SiS_LVDSDesStruct *)SiS300_PanelType03_2;
+ SiS_Pr->SiS_PanelType04_2 = (SiS_LVDSDesStruct *)SiS300_PanelType04_2;
+ SiS_Pr->SiS_PanelType05_2 = (SiS_LVDSDesStruct *)SiS300_PanelType05_2;
+ SiS_Pr->SiS_PanelType06_2 = (SiS_LVDSDesStruct *)SiS300_PanelType06_2;
+ SiS_Pr->SiS_PanelType07_2 = (SiS_LVDSDesStruct *)SiS300_PanelType07_2;
+ SiS_Pr->SiS_PanelType08_2 = (SiS_LVDSDesStruct *)SiS300_PanelType08_2;
+ SiS_Pr->SiS_PanelType09_2 = (SiS_LVDSDesStruct *)SiS300_PanelType09_2;
+ SiS_Pr->SiS_PanelType0a_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0a_2;
+ SiS_Pr->SiS_PanelType0b_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0b_2;
+ SiS_Pr->SiS_PanelType0c_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0c_2;
+ SiS_Pr->SiS_PanelType0d_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0d_2;
+ SiS_Pr->SiS_PanelType0e_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0e_2;
+ SiS_Pr->SiS_PanelType0f_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0f_2;
+ SiS_Pr->SiS_CHTVUNTSCDesData = (SiS_LVDSDesStruct *)SiS300_CHTVUNTSCDesData;
+ SiS_Pr->SiS_CHTVONTSCDesData = (SiS_LVDSDesStruct *)SiS300_CHTVONTSCDesData;
+ SiS_Pr->SiS_CHTVUPALDesData = (SiS_LVDSDesStruct *)SiS300_CHTVUPALDesData;
+ SiS_Pr->SiS_CHTVOPALDesData = (SiS_LVDSDesStruct *)SiS300_CHTVOPALDesData;
+ SiS_Pr->SiS_LVDSCRT1800x600_1 = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT1800x600_1;
+ SiS_Pr->SiS_LVDSCRT11024x768_1 = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x768_1;
+ SiS_Pr->SiS_LVDSCRT11280x1024_1 = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11280x1024_1;
+ SiS_Pr->SiS_LVDSCRT11024x600_1 = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x600_1;
+ SiS_Pr->SiS_LVDSCRT11152x768_1 = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11152x768_1;
+ SiS_Pr->SiS_LVDSCRT1800x600_1_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT1800x600_1_H;
+ SiS_Pr->SiS_LVDSCRT11024x768_1_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x768_1_H;
+ SiS_Pr->SiS_LVDSCRT11280x1024_1_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11280x1024_1_H;
+ SiS_Pr->SiS_LVDSCRT11024x600_1_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x600_1_H;
+ SiS_Pr->SiS_LVDSCRT11152x768_1_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11152x768_1_H;
+ SiS_Pr->SiS_LVDSCRT1800x600_2 = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT1800x600_2;
+ SiS_Pr->SiS_LVDSCRT11024x768_2 = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x768_2;
+ SiS_Pr->SiS_LVDSCRT11280x1024_2 = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11280x1024_2;
+ SiS_Pr->SiS_LVDSCRT11024x600_2 = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x600_2;
+ SiS_Pr->SiS_LVDSCRT11152x768_2 = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11152x768_2;
+ SiS_Pr->SiS_LVDSCRT1800x600_2_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT1800x600_2_H;
+ SiS_Pr->SiS_LVDSCRT11024x768_2_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x768_2_H;
+ SiS_Pr->SiS_LVDSCRT11280x1024_2_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11280x1024_2_H;
+ SiS_Pr->SiS_LVDSCRT11024x600_2_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x600_2_H;
+ SiS_Pr->SiS_LVDSCRT11152x768_2_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11152x768_2_H;
+ SiS_Pr->SiS_CHTVCRT1UNTSC = (SiS_LVDSCRT1DataStruct *)SiS300_CHTVCRT1UNTSC;
+ SiS_Pr->SiS_CHTVCRT1ONTSC = (SiS_LVDSCRT1DataStruct *)SiS300_CHTVCRT1ONTSC;
+ SiS_Pr->SiS_CHTVCRT1UPAL = (SiS_LVDSCRT1DataStruct *)SiS300_CHTVCRT1UPAL;
+ SiS_Pr->SiS_CHTVCRT1OPAL = (SiS_LVDSCRT1DataStruct *)SiS300_CHTVCRT1OPAL;
+ SiS_Pr->SiS_CHTVCRT1SOPAL = (SiS_LVDSCRT1DataStruct *)SiS300_CHTVCRT1SOPAL;
+ SiS_Pr->SiS_CHTVReg_UNTSC = (SiS_CHTVRegDataStruct *)SiS300_CHTVReg_UNTSC;
+ SiS_Pr->SiS_CHTVReg_ONTSC = (SiS_CHTVRegDataStruct *)SiS300_CHTVReg_ONTSC;
+ SiS_Pr->SiS_CHTVReg_UPAL = (SiS_CHTVRegDataStruct *)SiS300_CHTVReg_UPAL;
+ SiS_Pr->SiS_CHTVReg_OPAL = (SiS_CHTVRegDataStruct *)SiS300_CHTVReg_OPAL;
+ SiS_Pr->SiS_CHTVReg_UPALM = (SiS_CHTVRegDataStruct *)SiS300_CHTVReg_UNTSC; /* not supported on 300 series */
+ SiS_Pr->SiS_CHTVReg_OPALM = (SiS_CHTVRegDataStruct *)SiS300_CHTVReg_ONTSC; /* not supported on 300 series */
+ SiS_Pr->SiS_CHTVReg_UPALN = (SiS_CHTVRegDataStruct *)SiS300_CHTVReg_UPAL; /* not supported on 300 series */
+ SiS_Pr->SiS_CHTVReg_OPALN = (SiS_CHTVRegDataStruct *)SiS300_CHTVReg_OPAL; /* not supported on 300 series */
+ SiS_Pr->SiS_CHTVReg_SOPAL = (SiS_CHTVRegDataStruct *)SiS300_CHTVReg_SOPAL;
+ SiS_Pr->SiS_CHTVVCLKUNTSC = SiS300_CHTVVCLKUNTSC;
+ SiS_Pr->SiS_CHTVVCLKONTSC = SiS300_CHTVVCLKONTSC;
+ SiS_Pr->SiS_CHTVVCLKUPAL = SiS300_CHTVVCLKUPAL;
+ SiS_Pr->SiS_CHTVVCLKOPAL = SiS300_CHTVVCLKOPAL;
+ SiS_Pr->SiS_CHTVVCLKUPALM = SiS300_CHTVVCLKUNTSC; /* not supported on 300 series */
+ SiS_Pr->SiS_CHTVVCLKOPALM = SiS300_CHTVVCLKONTSC; /* not supported on 300 series */
+ SiS_Pr->SiS_CHTVVCLKUPALN = SiS300_CHTVVCLKUPAL; /* not supported on 300 series */
+ SiS_Pr->SiS_CHTVVCLKOPALN = SiS300_CHTVVCLKOPAL; /* not supported on 300 series */
+ SiS_Pr->SiS_CHTVVCLKSOPAL = SiS300_CHTVVCLKSOPAL;
+
+ /* TW: New from 300/301LV BIOS */
+ SiS_Pr->SiS_CRT2Part2_1024x768_1 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1024x768_1;
+ SiS_Pr->SiS_CRT2Part2_1280x1024_1 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1280x1024_1;
+ SiS_Pr->SiS_CRT2Part2_1400x1050_1 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1400x1050_1;
+ SiS_Pr->SiS_CRT2Part2_1600x1200_1 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1600x1200_1;
+ SiS_Pr->SiS_CRT2Part2_1024x768_2 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1024x768_2;
+ SiS_Pr->SiS_CRT2Part2_1280x1024_2 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1280x1024_2;
+ SiS_Pr->SiS_CRT2Part2_1400x1050_2 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1400x1050_2;
+ SiS_Pr->SiS_CRT2Part2_1600x1200_2 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1600x1200_2;
+ SiS_Pr->SiS_CRT2Part2_1024x768_3 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1024x768_3;
+ SiS_Pr->SiS_CRT2Part2_1280x1024_3 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1280x1024_3;
+ SiS_Pr->SiS_CRT2Part2_1400x1050_3 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1400x1050_3;
+ SiS_Pr->SiS_CRT2Part2_1600x1200_3 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1600x1200_3;
+
+ /* TW: LCDResInfo will on 300 series be translated to 310/325 series definitions */
+ SiS_Pr->SiS_Panel320x480 = Panel_320x480;
+ SiS_Pr->SiS_Panel640x480 = Panel_640x480;
+ SiS_Pr->SiS_Panel800x600 = Panel_800x600;
+ SiS_Pr->SiS_Panel1024x768 = Panel_1024x768;
+ SiS_Pr->SiS_Panel1280x1024 = Panel_1280x1024;
+ SiS_Pr->SiS_Panel1280x960 = Panel_1280x960;
+ SiS_Pr->SiS_Panel1024x600 = Panel_1024x600;
+ SiS_Pr->SiS_Panel1152x768 = Panel_1152x768;
+ SiS_Pr->SiS_Panel1600x1200 = 16; /* TW: Something illegal */
+ SiS_Pr->SiS_Panel1400x1050 = 16; /* TW: Something illegal */
+ SiS_Pr->SiS_Panel1152x864 = 16; /* TW: Something illegal */
+ SiS_Pr->SiS_Panel1280x768 = 16; /* TW: Something illegal */
+ SiS_Pr->SiS_PanelMax = Panel_320x480; /* TW: highest value */
+ SiS_Pr->SiS_PanelMinLVDS = Panel_800x600; /* TW: Lowest value LVDS */
+ SiS_Pr->SiS_PanelMin301 = Panel_1024x768; /* TW: lowest value 301 */
+}
+#endif
+
+#ifdef SIS315H
+static void
+InitTo310Pointer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ SiS_Pr->SiS_SModeIDTable = (SiS_StStruct *)SiS310_SModeIDTable;
+ SiS_Pr->SiS_StandTable = (SiS_StandTableStruct *)SiS310_StandTable;
+ SiS_Pr->SiS_EModeIDTable = (SiS_ExtStruct *)SiS310_EModeIDTable;
+ SiS_Pr->SiS_RefIndex = (SiS_Ext2Struct *)SiS310_RefIndex;
+ SiS_Pr->SiS_CRT1Table = (SiS_CRT1TableStruct *)SiS310_CRT1Table;
+ /* TW: MCLK is different */
+ if(HwDeviceExtension->jChipType == SIS_330) {
+ SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS310_MCLKData_0_330; /* 330 */
+ } else if(HwDeviceExtension->jChipType > SIS_315PRO) {
+ SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS310_MCLKData_0_650; /* 550, 650 */
+ } else {
+ SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS310_MCLKData_0_315; /* 315 */
+ }
+ SiS_Pr->SiS_MCLKData_1 = (SiS_MCLKDataStruct *)SiS310_MCLKData_1;
+ SiS_Pr->SiS_ECLKData = (SiS_ECLKDataStruct *)SiS310_ECLKData;
+ SiS_Pr->SiS_VCLKData = (SiS_VCLKDataStruct *)SiS310_VCLKData;
+ SiS_Pr->SiS_VBVCLKData = (SiS_VBVCLKDataStruct *)SiS310_VBVCLKData;
+ SiS_Pr->SiS_ScreenOffset = SiS310_ScreenOffset;
+ SiS_Pr->SiS_StResInfo = (SiS_StResInfoStruct *)SiS310_StResInfo;
+ SiS_Pr->SiS_ModeResInfo = (SiS_ModeResInfoStruct *)SiS310_ModeResInfo;
+
+ SiS_Pr->pSiS_OutputSelect = &SiS310_OutputSelect;
+ SiS_Pr->pSiS_SoftSetting = &SiS310_SoftSetting;
+
+ SiS_Pr->SiS_SR15 = SiS310_SR15;
+
+#ifndef LINUX_XF86
+ 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_NTSCPhase = SiS310_NTSCPhase;
+ SiS_Pr->SiS_PALPhase = SiS310_PALPhase;
+ SiS_Pr->SiS_NTSCPhase2 = SiS310_NTSCPhase2;
+ SiS_Pr->SiS_PALPhase2 = SiS310_PALPhase2;
+ SiS_Pr->SiS_PALMPhase = SiS310_PALMPhase;
+ SiS_Pr->SiS_PALNPhase = SiS310_PALNPhase;
+ SiS_Pr->SiS_PALMPhase2 = SiS310_PALMPhase2;
+ SiS_Pr->SiS_PALNPhase2 = SiS310_PALNPhase2;
+ SiS_Pr->SiS_SpecialPhase = SiS310_SpecialPhase;
+
+ SiS_Pr->SiS_StLCD1024x768Data = (SiS_LCDDataStruct *)SiS310_StLCD1024x768Data;
+ SiS_Pr->SiS_ExtLCD1024x768Data = (SiS_LCDDataStruct *)SiS310_ExtLCD1024x768Data;
+ SiS_Pr->SiS_St2LCD1024x768Data = (SiS_LCDDataStruct *)SiS310_St2LCD1024x768Data;
+ SiS_Pr->SiS_StLCD1280x1024Data = (SiS_LCDDataStruct *)SiS310_StLCD1280x1024Data;
+ SiS_Pr->SiS_ExtLCD1280x1024Data = (SiS_LCDDataStruct *)SiS310_ExtLCD1280x1024Data;
+ SiS_Pr->SiS_St2LCD1280x1024Data = (SiS_LCDDataStruct *)SiS310_St2LCD1280x1024Data;
+ SiS_Pr->SiS_NoScaleData1024x768 = (SiS_LCDDataStruct *)SiS310_NoScaleData1024x768;
+ SiS_Pr->SiS_NoScaleData1280x1024 = (SiS_LCDDataStruct *)SiS310_NoScaleData1280x1024;
+ SiS_Pr->SiS_LCD1280x960Data = (SiS_LCDDataStruct *)SiS310_LCD1280x960Data;
+ SiS_Pr->SiS_ExtLCD1400x1050Data = (SiS_LCDDataStruct *)SiS310_ExtLCD1400x1050Data;
+ SiS_Pr->SiS_ExtLCD1600x1200Data = (SiS_LCDDataStruct *)SiS310_ExtLCD1600x1200Data;
+ SiS_Pr->SiS_StLCD1400x1050Data = (SiS_LCDDataStruct *)SiS310_StLCD1400x1050Data;
+ SiS_Pr->SiS_StLCD1600x1200Data = (SiS_LCDDataStruct *)SiS310_StLCD1600x1200Data;
+ SiS_Pr->SiS_NoScaleData1400x1050 = (SiS_LCDDataStruct *)SiS310_NoScaleData1400x1050;
+ SiS_Pr->SiS_NoScaleData1600x1200 = (SiS_LCDDataStruct *)SiS310_NoScaleData1600x1200;
+
+ SiS_Pr->SiS_StPALData = (SiS_TVDataStruct *)SiS310_StPALData;
+ SiS_Pr->SiS_ExtPALData = (SiS_TVDataStruct *)SiS310_ExtPALData;
+ SiS_Pr->SiS_StNTSCData = (SiS_TVDataStruct *)SiS310_StNTSCData;
+ SiS_Pr->SiS_ExtNTSCData = (SiS_TVDataStruct *)SiS310_ExtNTSCData;
+#ifdef oldHV
+ SiS_Pr->SiS_St1HiTVData = (SiS_TVDataStruct *)SiS310_St1HiTVData;
+ SiS_Pr->SiS_St2HiTVData = (SiS_TVDataStruct *)SiS310_St2HiTVData;
+ SiS_Pr->SiS_ExtHiTVData = (SiS_TVDataStruct *)SiS310_ExtHiTVData;
+#endif
+
+ SiS_Pr->SiS_NTSCTiming = SiS310_NTSCTiming;
+ SiS_Pr->SiS_PALTiming = SiS310_PALTiming;
+#ifdef oldHV
+ SiS_Pr->SiS_HiTVSt1Timing = SiS310_HiTVSt1Timing;
+ SiS_Pr->SiS_HiTVSt2Timing = SiS310_HiTVSt2Timing;
+ SiS_Pr->SiS_HiTVTextTiming = SiS310_HiTVTextTiming;
+ SiS_Pr->SiS_HiTVExtTiming = SiS310_HiTVExtTiming;
+ SiS_Pr->SiS_HiTVGroup3Data = SiS310_HiTVGroup3Data;
+ SiS_Pr->SiS_HiTVGroup3Simu = SiS310_HiTVGroup3Simu;
+ SiS_Pr->SiS_HiTVGroup3Text = SiS310_HiTVGroup3Text;
+#endif
+
+ SiS_Pr->SiS_PanelDelayTbl = (SiS_PanelDelayTblStruct *)SiS310_PanelDelayTbl;
+ SiS_Pr->SiS_PanelDelayTblLVDS = (SiS_PanelDelayTblStruct *)SiS310_PanelDelayTblLVDS;
+
+ SiS_Pr->SiS_LVDS800x600Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS800x600Data_1;
+ SiS_Pr->SiS_LVDS800x600Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS800x600Data_2;
+ SiS_Pr->SiS_LVDS1024x768Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS1024x768Data_1;
+ SiS_Pr->SiS_LVDS1024x768Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS1024x768Data_2;
+ SiS_Pr->SiS_LVDS1280x1024Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS1280x1024Data_1;
+ SiS_Pr->SiS_LVDS1280x1024Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS1280x1024Data_2;
+ SiS_Pr->SiS_LVDS1280x960Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS1280x960Data_1;
+ SiS_Pr->SiS_LVDS1280x960Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS1280x960Data_2;
+ SiS_Pr->SiS_LVDS1400x1050Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS1400x1050Data_1;
+ SiS_Pr->SiS_LVDS1400x1050Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS1400x1050Data_2;
+ SiS_Pr->SiS_LVDS1280x768Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS1280x768Data_1;
+ SiS_Pr->SiS_LVDS1280x768Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS1280x768Data_2;
+ SiS_Pr->SiS_LVDS1024x600Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS1024x600Data_1;
+ SiS_Pr->SiS_LVDS1024x600Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS1024x600Data_2;
+ SiS_Pr->SiS_LVDS1152x768Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS1152x768Data_1;
+ SiS_Pr->SiS_LVDS1152x768Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS1152x768Data_2;
+ SiS_Pr->SiS_LVDSXXXxXXXData_1 = (SiS_LVDSDataStruct *)SiS310_LVDSXXXxXXXData_1;
+ SiS_Pr->SiS_LVDS320x480Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS320x480Data_1;
+ SiS_Pr->SiS_LVDS640x480Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS640x480Data_1;
+ SiS_Pr->SiS_LCDA1400x1050Data_1 = (SiS_LVDSDataStruct *)SiS310_LCDA1400x1050Data_1;
+ SiS_Pr->SiS_LCDA1400x1050Data_2 = (SiS_LVDSDataStruct *)SiS310_LCDA1400x1050Data_2;
+ SiS_Pr->SiS_LCDA1600x1200Data_1 = (SiS_LVDSDataStruct *)SiS310_LCDA1600x1200Data_1;
+ SiS_Pr->SiS_LCDA1600x1200Data_2 = (SiS_LVDSDataStruct *)SiS310_LCDA1600x1200Data_2;
+ SiS_Pr->SiS_CHTVUNTSCData = (SiS_LVDSDataStruct *)SiS310_CHTVUNTSCData;
+ SiS_Pr->SiS_CHTVONTSCData = (SiS_LVDSDataStruct *)SiS310_CHTVONTSCData;
+ SiS_Pr->SiS_CHTVUPALData = (SiS_LVDSDataStruct *)SiS310_CHTVUPALData;
+ SiS_Pr->SiS_CHTVOPALData = (SiS_LVDSDataStruct *)SiS310_CHTVOPALData;
+ SiS_Pr->SiS_CHTVUPALMData = (SiS_LVDSDataStruct *)SiS310_CHTVUPALMData;
+ SiS_Pr->SiS_CHTVOPALMData = (SiS_LVDSDataStruct *)SiS310_CHTVOPALMData;
+ SiS_Pr->SiS_CHTVUPALNData = (SiS_LVDSDataStruct *)SiS310_CHTVUPALNData;
+ SiS_Pr->SiS_CHTVOPALNData = (SiS_LVDSDataStruct *)SiS310_CHTVOPALNData;
+ SiS_Pr->SiS_CHTVSOPALData = (SiS_LVDSDataStruct *)SiS310_CHTVSOPALData;
+ SiS_Pr->SiS_PanelType00_1 = (SiS_LVDSDesStruct *)SiS310_PanelType00_1;
+ SiS_Pr->SiS_PanelType01_1 = (SiS_LVDSDesStruct *)SiS310_PanelType01_1;
+ SiS_Pr->SiS_PanelType02_1 = (SiS_LVDSDesStruct *)SiS310_PanelType02_1;
+ SiS_Pr->SiS_PanelType03_1 = (SiS_LVDSDesStruct *)SiS310_PanelType03_1;
+ SiS_Pr->SiS_PanelType04_1 = (SiS_LVDSDesStruct *)SiS310_PanelType04_1;
+ SiS_Pr->SiS_PanelType05_1 = (SiS_LVDSDesStruct *)SiS310_PanelType05_1;
+ SiS_Pr->SiS_PanelType06_1 = (SiS_LVDSDesStruct *)SiS310_PanelType06_1;
+ SiS_Pr->SiS_PanelType07_1 = (SiS_LVDSDesStruct *)SiS310_PanelType07_1;
+ SiS_Pr->SiS_PanelType08_1 = (SiS_LVDSDesStruct *)SiS310_PanelType08_1;
+ SiS_Pr->SiS_PanelType09_1 = (SiS_LVDSDesStruct *)SiS310_PanelType09_1;
+ SiS_Pr->SiS_PanelType0a_1 = (SiS_LVDSDesStruct *)SiS310_PanelType0a_1;
+ SiS_Pr->SiS_PanelType0b_1 = (SiS_LVDSDesStruct *)SiS310_PanelType0b_1;
+ SiS_Pr->SiS_PanelType0c_1 = (SiS_LVDSDesStruct *)SiS310_PanelType0c_1;
+ SiS_Pr->SiS_PanelType0d_1 = (SiS_LVDSDesStruct *)SiS310_PanelType0d_1;
+ SiS_Pr->SiS_PanelType0e_1 = (SiS_LVDSDesStruct *)SiS310_PanelType0e_1;
+ SiS_Pr->SiS_PanelType0f_1 = (SiS_LVDSDesStruct *)SiS310_PanelType0f_1;
+ SiS_Pr->SiS_PanelType00_2 = (SiS_LVDSDesStruct *)SiS310_PanelType00_2;
+ SiS_Pr->SiS_PanelType01_2 = (SiS_LVDSDesStruct *)SiS310_PanelType01_2;
+ SiS_Pr->SiS_PanelType02_2 = (SiS_LVDSDesStruct *)SiS310_PanelType02_2;
+ SiS_Pr->SiS_PanelType03_2 = (SiS_LVDSDesStruct *)SiS310_PanelType03_2;
+ SiS_Pr->SiS_PanelType04_2 = (SiS_LVDSDesStruct *)SiS310_PanelType04_2;
+ SiS_Pr->SiS_PanelType05_2 = (SiS_LVDSDesStruct *)SiS310_PanelType05_2;
+ SiS_Pr->SiS_PanelType06_2 = (SiS_LVDSDesStruct *)SiS310_PanelType06_2;
+ SiS_Pr->SiS_PanelType07_2 = (SiS_LVDSDesStruct *)SiS310_PanelType07_2;
+ SiS_Pr->SiS_PanelType08_2 = (SiS_LVDSDesStruct *)SiS310_PanelType08_2;
+ SiS_Pr->SiS_PanelType09_2 = (SiS_LVDSDesStruct *)SiS310_PanelType09_2;
+ SiS_Pr->SiS_PanelType0a_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0a_2;
+ SiS_Pr->SiS_PanelType0b_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0b_2;
+ SiS_Pr->SiS_PanelType0c_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0c_2;
+ SiS_Pr->SiS_PanelType0d_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0d_2;
+ SiS_Pr->SiS_PanelType0e_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0e_2;
+ SiS_Pr->SiS_PanelType0f_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0f_2;
+
+ SiS_Pr->LVDS1024x768Des_1 = (SiS_LVDSDesStruct *)SiS310_PanelType1076_1;
+ SiS_Pr->LVDS1280x1024Des_1 = (SiS_LVDSDesStruct *)SiS310_PanelType1210_1;
+ SiS_Pr->LVDS1400x1050Des_1 = (SiS_LVDSDesStruct *)SiS310_PanelType1296_1 ;
+ SiS_Pr->LVDS1600x1200Des_1 = (SiS_LVDSDesStruct *)SiS310_PanelType1600_1 ;
+ SiS_Pr->LVDS1024x768Des_2 = (SiS_LVDSDesStruct *)SiS310_PanelType1076_2;
+ SiS_Pr->LVDS1280x1024Des_2 = (SiS_LVDSDesStruct *)SiS310_PanelType1210_2;
+ SiS_Pr->LVDS1400x1050Des_2 = (SiS_LVDSDesStruct *)SiS310_PanelType1296_2;
+ SiS_Pr->LVDS1600x1200Des_2 = (SiS_LVDSDesStruct *)SiS310_PanelType1600_2 ;
+
+ /* TW: New from 650/301LV BIOS */
+ SiS_Pr->SiS_CRT2Part2_1024x768_1 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1024x768_1;
+ SiS_Pr->SiS_CRT2Part2_1280x1024_1 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1280x1024_1;
+ SiS_Pr->SiS_CRT2Part2_1400x1050_1 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1400x1050_1;
+ SiS_Pr->SiS_CRT2Part2_1600x1200_1 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1600x1200_1;
+ SiS_Pr->SiS_CRT2Part2_1024x768_2 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1024x768_2;
+ SiS_Pr->SiS_CRT2Part2_1280x1024_2 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1280x1024_2;
+ SiS_Pr->SiS_CRT2Part2_1400x1050_2 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1400x1050_2;
+ SiS_Pr->SiS_CRT2Part2_1600x1200_2 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1600x1200_2;
+ SiS_Pr->SiS_CRT2Part2_1024x768_3 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1024x768_3;
+ SiS_Pr->SiS_CRT2Part2_1280x1024_3 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1280x1024_3;
+ SiS_Pr->SiS_CRT2Part2_1400x1050_3 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1400x1050_3;
+ SiS_Pr->SiS_CRT2Part2_1600x1200_3 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1600x1200_3;
+
+ SiS_Pr->SiS_CHTVUNTSCDesData = (SiS_LVDSDesStruct *)SiS310_CHTVUNTSCDesData;
+ SiS_Pr->SiS_CHTVONTSCDesData = (SiS_LVDSDesStruct *)SiS310_CHTVONTSCDesData;
+ SiS_Pr->SiS_CHTVUPALDesData = (SiS_LVDSDesStruct *)SiS310_CHTVUPALDesData;
+ SiS_Pr->SiS_CHTVOPALDesData = (SiS_LVDSDesStruct *)SiS310_CHTVOPALDesData;
+
+ SiS_Pr->SiS_LVDSCRT1800x600_1 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1800x600_1;
+ SiS_Pr->SiS_LVDSCRT11024x768_1 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x768_1;
+ SiS_Pr->SiS_LVDSCRT11280x1024_1 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x1024_1;
+ SiS_Pr->SiS_LVDSCRT11400x1050_1 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11400x1050_1;
+ SiS_Pr->SiS_LVDSCRT11280x768_1 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x768_1;
+ SiS_Pr->SiS_LVDSCRT11024x600_1 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x600_1;
+ SiS_Pr->SiS_LVDSCRT11152x768_1 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11152x768_1;
+ SiS_Pr->SiS_LVDSCRT11600x1200_1 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11600x1200_1;
+ SiS_Pr->SiS_LVDSCRT1800x600_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1800x600_1_H;
+ SiS_Pr->SiS_LVDSCRT11024x768_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x768_1_H;
+ SiS_Pr->SiS_LVDSCRT11280x1024_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x1024_1_H;
+ SiS_Pr->SiS_LVDSCRT11400x1050_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11400x1050_1_H;
+ SiS_Pr->SiS_LVDSCRT11280x768_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x768_1_H;
+ SiS_Pr->SiS_LVDSCRT11024x600_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x600_1_H;
+ SiS_Pr->SiS_LVDSCRT11152x768_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11152x768_1_H;
+ SiS_Pr->SiS_LVDSCRT11600x1200_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11600x1200_1_H;
+ SiS_Pr->SiS_LVDSCRT1800x600_2 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1800x600_2;
+ SiS_Pr->SiS_LVDSCRT11024x768_2 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x768_2;
+ SiS_Pr->SiS_LVDSCRT11280x1024_2 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x1024_2;
+ SiS_Pr->SiS_LVDSCRT11400x1050_2 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11400x1050_2;
+ SiS_Pr->SiS_LVDSCRT11280x768_2 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x768_2;
+ SiS_Pr->SiS_LVDSCRT11024x600_2 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x600_2;
+ SiS_Pr->SiS_LVDSCRT11152x768_2 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11152x768_2;
+ SiS_Pr->SiS_LVDSCRT11600x1200_2 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11600x1200_2;
+ SiS_Pr->SiS_LVDSCRT1800x600_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1800x600_2_H;
+ SiS_Pr->SiS_LVDSCRT11024x768_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x768_2_H;
+ SiS_Pr->SiS_LVDSCRT11280x1024_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x1024_2_H;
+ SiS_Pr->SiS_LVDSCRT11400x1050_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11400x1050_2_H;
+ SiS_Pr->SiS_LVDSCRT11280x768_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x768_2_H;
+ SiS_Pr->SiS_LVDSCRT11024x600_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x600_2_H;
+ SiS_Pr->SiS_LVDSCRT11152x768_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11152x768_2_H;
+ SiS_Pr->SiS_LVDSCRT11600x1200_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11600x1200_2_H;
+ SiS_Pr->SiS_LVDSCRT1XXXxXXX_1 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1XXXxXXX_1;
+ SiS_Pr->SiS_LVDSCRT1320x480_1 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1320x480_1;
+ SiS_Pr->SiS_CHTVCRT1UNTSC = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1UNTSC;
+ SiS_Pr->SiS_CHTVCRT1ONTSC = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1ONTSC;
+ SiS_Pr->SiS_CHTVCRT1UPAL = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1UPAL;
+ SiS_Pr->SiS_CHTVCRT1OPAL = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1OPAL;
+ SiS_Pr->SiS_CHTVCRT1SOPAL = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1SOPAL;
+ SiS_Pr->SiS_CHTVReg_UNTSC = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_UNTSC;
+ SiS_Pr->SiS_CHTVReg_ONTSC = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_ONTSC;
+ SiS_Pr->SiS_CHTVReg_UPAL = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_UPAL;
+ SiS_Pr->SiS_CHTVReg_OPAL = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_OPAL;
+ SiS_Pr->SiS_CHTVReg_UPALM = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_UPALM;
+ SiS_Pr->SiS_CHTVReg_OPALM = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_OPALM;
+ SiS_Pr->SiS_CHTVReg_UPALN = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_UPALN;
+ SiS_Pr->SiS_CHTVReg_OPALN = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_OPALN;
+ SiS_Pr->SiS_CHTVReg_SOPAL = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_SOPAL;
+ SiS_Pr->SiS_LCDACRT1800x600_1 = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT1800x600_1;
+ SiS_Pr->SiS_LCDACRT11024x768_1 = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11024x768_1;
+ SiS_Pr->SiS_LCDACRT11280x1024_1 = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11280x1024_1;
+ SiS_Pr->SiS_LCDACRT11400x1050_1 = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11400x1050_1;
+ SiS_Pr->SiS_LCDACRT11600x1200_1 = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11600x1200_1;
+ SiS_Pr->SiS_LCDACRT1800x600_1_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT1800x600_1_H;
+ SiS_Pr->SiS_LCDACRT11024x768_1_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11024x768_1_H;
+ SiS_Pr->SiS_LCDACRT11280x1024_1_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11280x1024_1_H;
+ SiS_Pr->SiS_LCDACRT11400x1050_1_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11400x1050_1_H;
+ SiS_Pr->SiS_LCDACRT11600x1200_1_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11600x1200_1_H;
+ SiS_Pr->SiS_LCDACRT1800x600_2 = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT1800x600_2;
+ SiS_Pr->SiS_LCDACRT11024x768_2 = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11024x768_2;
+ SiS_Pr->SiS_LCDACRT11280x1024_2 = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11280x1024_2;
+ SiS_Pr->SiS_LCDACRT11400x1050_2 = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11400x1050_2;
+ SiS_Pr->SiS_LCDACRT11600x1200_2 = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11600x1200_2;
+ SiS_Pr->SiS_LCDACRT1800x600_2_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT1800x600_2_H;
+ SiS_Pr->SiS_LCDACRT11024x768_2_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11024x768_2_H;
+ SiS_Pr->SiS_LCDACRT11280x1024_2_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11280x1024_2_H;
+ SiS_Pr->SiS_LCDACRT11400x1050_2_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11400x1050_2_H;
+ SiS_Pr->SiS_LCDACRT11600x1200_2_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11600x1200_2_H;
+ SiS_Pr->SiS_CHTVVCLKUNTSC = SiS310_CHTVVCLKUNTSC;
+ SiS_Pr->SiS_CHTVVCLKONTSC = SiS310_CHTVVCLKONTSC;
+ SiS_Pr->SiS_CHTVVCLKUPAL = SiS310_CHTVVCLKUPAL;
+ SiS_Pr->SiS_CHTVVCLKOPAL = SiS310_CHTVVCLKOPAL;
+ SiS_Pr->SiS_CHTVVCLKUPALM = SiS310_CHTVVCLKUPALM;
+ SiS_Pr->SiS_CHTVVCLKOPALM = SiS310_CHTVVCLKOPALM;
+ SiS_Pr->SiS_CHTVVCLKUPALN = SiS310_CHTVVCLKUPALN;
+ SiS_Pr->SiS_CHTVVCLKOPALN = SiS310_CHTVVCLKOPALN;
+ SiS_Pr->SiS_CHTVVCLKSOPAL = SiS310_CHTVVCLKSOPAL;
+
+ SiS_Pr->SiS_Panel320x480 = Panel_320x480;
+ SiS_Pr->SiS_Panel640x480 = Panel_640x480;
+ SiS_Pr->SiS_Panel800x600 = Panel_800x600;
+ SiS_Pr->SiS_Panel1024x768 = Panel_1024x768;
+ SiS_Pr->SiS_Panel1280x1024 = Panel_1280x1024;
+ SiS_Pr->SiS_Panel1280x960 = Panel_1280x960;
+ SiS_Pr->SiS_Panel1600x1200 = Panel_1600x1200;
+ SiS_Pr->SiS_Panel1400x1050 = Panel_1400x1050;
+ SiS_Pr->SiS_Panel1152x768 = Panel_1152x768;
+ SiS_Pr->SiS_Panel1152x864 = Panel_1152x864;
+ SiS_Pr->SiS_Panel1280x768 = Panel_1280x768;
+ SiS_Pr->SiS_Panel1024x600 = Panel_1024x600;
+ SiS_Pr->SiS_PanelMax = Panel_320x480; /* TW: highest value */
+ SiS_Pr->SiS_PanelMinLVDS = Panel_800x600; /* TW: lowest value LVDS/LCDA */
+ SiS_Pr->SiS_PanelMin301 = Panel_1024x768; /* TW: lowest value 301 */
+}
+#endif
+
+#ifdef LINUXBIOS
+/* -------------- SiSInit -----------------*/
+/* TW: I degraded this for LINUXBIOS only, because we
+ * don't need this otherwise. Under normal
+ * circumstances, the video BIOS has initialized
+ * the adapter for us. BTW, this code is incomplete
+ * and very possibly not functioning on newer chipsets.
+ */
+BOOLEAN
+SiSInit(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ UCHAR *ROMAddr = HwDeviceExtension->pjVirtualRomBase;
+ ULONG FBAddr = (ULONG)HwDeviceExtension->pjVideoMemoryAddress;
+ USHORT BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
+ UCHAR i, temp=0;
+ UCHAR SR11;
+#ifdef LINUX_KERNEL
+ UCHAR temp1;
+ ULONG base;
+#endif
+ UCHAR SR13=0, SR14=0, SR16=0
+ UCHAR SR17=0, SR19=0, SR1A=0;
+#ifdef SIS300
+ UCHAR SR18=0, SR12=0;
+#endif
+#ifdef SIS315H
+ UCHAR CR37=0, CR38=0, CR79=0,
+ UCHAR CR7A=0, CR7B=0, CR7C=0;
+ UCHAR SR1B=0, SR15=0;
+ PSIS_DSReg pSR;
+ ULONG Temp;
+#endif
+ UCHAR VBIOSVersion[5];
+
+ if(FBAddr==0) return (FALSE);
+ if(BaseAddr==0) return (FALSE);
+
+ SiS_SetReg3((USHORT)(BaseAddr+0x12), 0x67); /* Misc */
+
+#ifdef SIS315H
+ if(HwDeviceExtension->jChipType > SIS_315PRO) {
+ if(!HwDeviceExtension->bIntegratedMMEnabled)
+ return (FALSE);
+ }
+#endif
+
+ SiS_MemoryCopy(VBIOSVersion,HwDeviceExtension->szVBIOSVer,4);
+ VBIOSVersion[4]= 0x00;
+
+ SiSDetermineROMUsage(SiS_Pr, HwDeviceExtension, ROMAddr);
+
+ /* TW: Init pointers */
+#ifdef SIS315H
+ if((HwDeviceExtension->jChipType == SIS_315H) ||
+ (HwDeviceExtension->jChipType == SIS_315) ||
+ (HwDeviceExtension->jChipType == SIS_315PRO) ||
+ (HwDeviceExtension->jChipType == SIS_550) ||
+ (HwDeviceExtension->jChipType == SIS_650) ||
+ (HwDeviceExtension->jChipType == SIS_740) ||
+ (HwDeviceExtension->jChipType == SIS_330))
+ InitTo310Pointer(SiS_Pr, HwDeviceExtension);
+#endif
+
+#ifdef SIS300
+ if((HwDeviceExtension->jChipType == SIS_540) ||
+ (HwDeviceExtension->jChipType == SIS_630) ||
+ (HwDeviceExtension->jChipType == SIS_730) ||
+ (HwDeviceExtension->jChipType == SIS_300))
+ InitTo300Pointer(SiS_Pr, HwDeviceExtension);
+#endif
+
+ /* TW: Set SiS Register definitions */
+ SiSRegInit(SiS_Pr, BaseAddr);
+
+ /* TW: Determine LVDS/CH70xx/TRUMPION */
+ SiS_Set_LVDS_TRUMPION(SiS_Pr, HwDeviceExtension);
+
+ /* TW: Unlock registers */
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86);
+
+#ifdef LINUX_KERNEL
+
+#ifdef SIS300 /* Set SR14 */
+ if((HwDeviceExtension->jChipType==SIS_540) ||
+ (HwDeviceExtension->jChipType==SIS_630) ||
+ (HwDeviceExtension->jChipType==SIS_730)) {
+ base=0x80000060;
+ OutPortLong(base,0xcf8);
+ temp1 = InPortLong(0xcfc);
+ temp1 >>= (16+8+4);
+ temp1 &= 0x07;
+ temp1++;
+ temp1 = 1 << temp1;
+ SR14 = temp1 - 1;
+ base = 0x80000064;
+ OutPortLong(base,0xcf8);
+ temp1 = InPortLong(0xcfc);
+ temp1 &= 0x00000020;
+ if(temp1) SR14 |= 0x80;
+ else SR14 |= 0x40;
+ }
+#endif
+
+#ifdef SIS315H /* Set SR14 */
+ if(HwDeviceExtension->jChipType == SIS_550) {
+ base = 0x80000060;
+ OutPortLong(base,0xcf8);
+ temp1 = InPortLong(0xcfc);
+ temp1 >>= (16+8+4);
+ temp1 &= 0x07;
+ temp1++;
+ temp1 = 1 << temp1;
+ SR14 = temp1 - 1;
+ base = 0x80000064;
+ OutPortLong(base,0xcf8);
+ temp1 = InPortLong(0xcfc);
+ temp1 &= 0x00000020;
+ if(temp1) SR14 |= 0x80;
+ else SR14 |= 0x40;
+ }
+
+ if((HwDeviceExtension->jChipType == SIS_740) || /* Set SR14 */
+ (HwDeviceExtension->jChipType == SIS_650)) {
+ base = 0x80000064;
+ OutPortLong(base,0xcf8);
+ temp1=InPortLong(0xcfc);
+ temp1 >>= 4;
+ temp1 &= 0x07;
+ if(temp1 > 2) {
+ temp = temp1;
+ switch(temp) {
+ case 3: temp1 = 0x07; break;
+ case 4: temp1 = 0x0F; break;
+ case 5: temp1 = 0x1F; break;
+ case 6: temp1 = 0x05; break;
+ case 7: temp1 = 0x17; break;
+ case 8: break;
+ case 9: break;
+ }
+ }
+ SR14 = temp1;
+ base = 0x8000007C;
+ OutPortLong(base,0xcf8);
+ temp1 = InPortLong(0xcfc);
+ temp1 &= 0x00000020;
+ if(temp1) SR14 |= 0x80;
+ }
+#endif
+
+#endif /* Linux kernel */
+
+#ifdef SIS300
+ if((HwDeviceExtension->jChipType == SIS_540)||
+ (HwDeviceExtension->jChipType == SIS_630)||
+ (HwDeviceExtension->jChipType == SIS_730)) {
+ SR12 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x12);
+ SR13 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13);
+ SR14 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
+ SR16 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16);
+ SR17 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17);
+ SR18 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x18);
+ SR19 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x19);
+ SR1A = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1A);
+ } else if(HwDeviceExtension->jChipType == SIS_300){
+ SR13 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13);
+ SR14 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
+ }
+#endif
+#ifdef SIS315H
+ if((HwDeviceExtension->jChipType == SIS_550) ||
+ (HwDeviceExtension->jChipType == SIS_740) ||
+ (HwDeviceExtension->jChipType == SIS_650)) {
+ SR19 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x19);
+ SR19 = (SR19)||0x01; /* TW: ??? || ??? */
+ if(SR19==0x00) {
+ SR13 = 0x22;
+ SR14 = 0x00;
+ SR15 = 0x01;
+ SR16 = 0x00;
+ SR17 = 0x00;
+ SR1A = 0x00;
+ SR1B = 0x00;
+ CR37 = 0x00;
+ CR38 = 0x00;
+ CR79 = 0x00;
+ CR7A = 0x00;
+ CR7B = 0x00;
+ CR7C = 0x00;
+ } else {
+ SR13 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13);
+ SR14 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
+ SR15 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x15);
+ SR16 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16);
+ SR17 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17);
+ SR1A = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1A);
+ SR1B = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1B);
+ CR37 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37); /* TW: Was 0x02 - why? */
+ CR38 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
+ CR79 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3d4,0x79);
+ CR7A = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3d4,0x7A);
+ CR7B = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3d4,0x7B);
+ CR7C = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3d4,0x7C);
+ }
+ }
+#endif
+
+ /* Reset extended registers */
+
+ for(i=0x06; i< 0x20; i++) SiS_SetReg1(SiS_Pr->SiS_P3c4,i,0);
+ for(i=0x21; i<=0x27; i++) SiS_SetReg1(SiS_Pr->SiS_P3c4,i,0);
+ for(i=0x31; i<=0x3D; i++) SiS_SetReg1(SiS_Pr->SiS_P3c4,i,0);
+
+#ifdef SIS300
+ if((HwDeviceExtension->jChipType == SIS_540) ||
+ (HwDeviceExtension->jChipType == SIS_630) ||
+ (HwDeviceExtension->jChipType == SIS_730) ||
+ (HwDeviceExtension->jChipType == SIS_300)) {
+ for(i=0x38; i<=0x3F; i++) SiS_SetReg1(SiS_Pr->SiS_P3d4,i,0);
+ }
+#endif
+
+#ifdef SIS315H
+ if((HwDeviceExtension->jChipType == SIS_315H) ||
+ (HwDeviceExtension->jChipType == SIS_315) ||
+ (HwDeviceExtension->jChipType == SIS_315PRO) ||
+ (HwDeviceExtension->jChipType == SIS_550) ||
+ (HwDeviceExtension->jChipType == SIS_650) ||
+ (HwDeviceExtension->jChipType == SIS_740) ||
+ (HwDeviceExtension->jChipType == SIS_330)) {
+ for(i=0x12; i<=0x1B; i++) SiS_SetReg1(SiS_Pr->SiS_P3c4,i,0);
+ for(i=0x79; i<=0x7C; i++) SiS_SetReg1(SiS_Pr->SiS_P3d4,i,0);
+ }
+#endif
+
+ /* Restore Extended Registers */
+
+#ifdef SIS300
+ if((HwDeviceExtension->jChipType == SIS_540) ||
+ (HwDeviceExtension->jChipType == SIS_630) ||
+ (HwDeviceExtension->jChipType == SIS_730)) {
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x12,SR12);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,SR13);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,SR14);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,SR16);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x17,SR17);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x18,SR18);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x19,SR19);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1A,SR1A);
+ }
+#endif
+
+#ifdef SIS315H
+ if((HwDeviceExtension->jChipType == SIS_550) ||
+ (HwDeviceExtension->jChipType == SIS_740) ||
+ (HwDeviceExtension->jChipType == SIS_650)) {
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,SR13);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,SR14);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x15,SR15);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,SR16);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x17,SR17);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x19,SR19);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1A,SR1A);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1B,SR1B);
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x37,CR37);
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x38,CR38);
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x79,CR79);
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x7A,CR7A);
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x7B,CR7B);
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x7C,CR7C);
+ }
+#endif
+
+#ifdef SIS300
+ if((HwDeviceExtension->jChipType==SIS_540) ||
+ (HwDeviceExtension->jChipType==SIS_630) ||
+ (HwDeviceExtension->jChipType==SIS_730)) {
+ temp = (UCHAR)SR1A & 0x03;
+ } else if(HwDeviceExtension->jChipType == SIS_300) {
+ /* TW: Nothing */
+ }
+#endif
+#ifdef SIS315H
+ if((HwDeviceExtension->jChipType == SIS_315H) ||
+ (HwDeviceExtension->jChipType == SIS_315) ||
+ (HwDeviceExtension->jChipType == SIS_315PRO) ||
+ (HwDeviceExtension->jChipType == SIS_330) ) {
+ if((*SiS_Pr->pSiS_SoftSetting & SoftDRAMType) == 0) {
+ temp = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x3A) & 0x03;
+ }
+ }
+ if((HwDeviceExtension->jChipType == SIS_550) ||
+ (HwDeviceExtension->jChipType == SIS_740) ||
+ (HwDeviceExtension->jChipType == SIS_650)) {
+ if((*SiS_Pr->pSiS_SoftSetting & SoftDRAMType) == 0) {
+ temp = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x07;
+ }
+ }
+#endif
+
+ SiS_Pr->SiS_RAMType = temp;
+ SiS_SetMemoryClock(SiS_Pr, ROMAddr, HwDeviceExtension);
+
+ /* Set default register contents */
+
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x07,*SiS_Pr->pSiS_SR07); /* DAC speed */
+
+ if((HwDeviceExtension->jChipType != SIS_540) &&
+ (HwDeviceExtension->jChipType != SIS_630) &&
+ (HwDeviceExtension->jChipType != SIS_730)){
+ for(i=0x15;i<0x1C;i++) {
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,i,SiS_Pr->SiS_SR15[i-0x15][SiS_Pr->SiS_RAMType]);
+ }
+ }
+
+#ifdef SIS315H
+ if((HwDeviceExtension->jChipType == SIS_315H) ||
+ (HwDeviceExtension->jChipType == SIS_315) ||
+ (HwDeviceExtension->jChipType == SIS_315PRO) ||
+ (HwDeviceExtension->jChipType == SIS_330)) {
+ for(i=0x40;i<=0x44;i++) {
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,i,SiS_Pr->SiS_CR40[i-0x40][SiS_Pr->SiS_RAMType]);
+ }
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x48,0x23);
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x49,SiS_Pr->SiS_CR49[0]);
+ /* SiS_SetReg1(SiS_Pr->SiS_P3c4,0x25,SiS_Pr->SiS_SR25[0]); */
+ }
+#endif
+
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1F,*SiS_Pr->pSiS_SR1F); /* DAC pedestal */
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x20,0xA0);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x23,*SiS_Pr->pSiS_SR23);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x24,*SiS_Pr->pSiS_SR24);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x25,SiS_Pr->SiS_SR25[0]);
+
+#ifdef SIS300
+ if(HwDeviceExtension->jChipType == SIS_300) {
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x21,0x84);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x22,0x00);
+ }
+#endif
+
+ SR11 = 0x0F;
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x11,SR11); /* Power Management & DDC port */
+
+ SiS_UnLockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,0x00);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x02,*SiS_Pr->pSiS_CRT2Data_1_2);
+
+#ifdef SIS315H
+ if((HwDeviceExtension->jChipType == SIS_315H) ||
+ (HwDeviceExtension->jChipType == SIS_315) ||
+ (HwDeviceExtension->jChipType == SIS_315PRO) ||
+ (HwDeviceExtension->jChipType == SIS_550) ||
+ (HwDeviceExtension->jChipType == SIS_650) ||
+ (HwDeviceExtension->jChipType == SIS_740) ||
+ (HwDeviceExtension->jChipType == SIS_330))
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2E,0x08); /* use VB */
+#endif
+
+ temp = *SiS_Pr->pSiS_SR32;
+ if(SiS_BridgeIsOn(SiS_Pr, BaseAddr)) {
+ temp &= 0xEF;
+ }
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
+
+#ifdef SIS315H
+ if((HwDeviceExtension->jChipType == SIS_315H) ||
+ (HwDeviceExtension->jChipType == SIS_315) ||
+ (HwDeviceExtension->jChipType == SIS_315PRO) ||
+ (HwDeviceExtension->jChipType == SIS_330)) {
+ HwDeviceExtension->pQueryVGAConfigSpace(HwDeviceExtension,0x50,0,&Temp);
+ Temp >>= 20;
+ Temp &= 0xF;
+ if (Temp != 1) {
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x25,SiS_Pr->SiS_SR25[1]);
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x49,SiS_Pr->SiS_CR49[1]);
+ }
+
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x27,0x1F);
+
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,*SiS_Pr->pSiS_SR31);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,*SiS_Pr->pSiS_SR32);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x33,*SiS_Pr->pSiS_SR33);
+ }
+#endif
+
+ if (SiS_BridgeIsOn(SiS_Pr, BaseAddr) == 0) {
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x00,0x1C);
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0D,*SiS_Pr->pSiS_CRT2Data_4_D);
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0E,*SiS_Pr->pSiS_CRT2Data_4_E);
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x10,*SiS_Pr->pSiS_CRT2Data_4_10);
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0F,0x3F);
+ }
+ SiS_LockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr);
+ }
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x83,0x00);
+
+#ifdef SIS315H
+ if((HwDeviceExtension->jChipType == SIS_315H) ||
+ (HwDeviceExtension->jChipType == SIS_315) ||
+ (HwDeviceExtension->jChipType == SIS_315PRO) ||
+ (HwDeviceExtension->jChipType == SIS_330)) {
+ if(HwDeviceExtension->bSkipDramSizing==TRUE) {
+ SiS_SetDRAMModeRegister(SiS_Pr, ROMAddr,HwDeviceExtension);
+ pSR = HwDeviceExtension->pSR;
+ if(pSR != NULL) {
+ while(pSR->jIdx != 0xFF) {
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,pSR->jIdx,pSR->jVal);
+ pSR++;
+ }
+ }
+ } else SiS_SetDRAMSize_310(SiS_Pr, HwDeviceExtension);
+ }
+#endif
+
+#ifdef SIS315H
+ if(HwDeviceExtension->jChipType == SIS_550) {
+ /* SetDRAMConfig begin */
+/* SiS_SetReg1(SiS_Pr->SiS_P3c4,0x12,SR12);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,SR13);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,SR14);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,SR16);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x17,SR17);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x18,SR18);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x19,SR19);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1A,SR1A); */
+ /* SetDRAMConfig end */
+ }
+#endif
+
+#ifdef SIS300
+ if(HwDeviceExtension->jChipType == SIS_300) {
+ if (HwDeviceExtension->bSkipDramSizing == TRUE) {
+/* SiS_SetDRAMModeRegister(ROMAddr,HwDeviceExtension);
+ temp = (HwDeviceExtension->pSR)->jVal;
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,temp);
+ temp = (HwDeviceExtension->pSR)->jVal;
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,temp); */
+ } else {
+#ifdef TC
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,SR13);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,SR14);
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x15,0xFF,0x04);
+#else
+ SiS_SetDRAMSize_300(SiS_Pr, HwDeviceExtension);
+ SiS_SetDRAMSize_300(SiS_Pr, HwDeviceExtension);
+#endif
+ }
+ }
+ if((HwDeviceExtension->jChipType==SIS_540)||
+ (HwDeviceExtension->jChipType==SIS_630)||
+ (HwDeviceExtension->jChipType==SIS_730)) {
+#if 0
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x12,SR12);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,SR13);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,SR14);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,SR16);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x17,SR17);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x18,SR18);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x19,SR19);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1A,SR1A);
+#endif
+ }
+/* SetDRAMSize end */
+#endif /* SIS300 */
+
+ /* Set default Ext2Regs */
+#if 0
+ AGP=1;
+ temp=(UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x3A);
+ temp &= 0x30;
+ if(temp == 0x30) AGP=0;
+ if(AGP == 0) *SiS_Pr->pSiS_SR21 &= 0xEF;
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x21,*SiS_Pr->pSiS_SR21);
+ if(AGP == 1) *SiS_Pr->pSiS_SR22 &= 0x20;
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x22,*SiS_Pr->pSiS_SR22);
+#endif
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x21,*SiS_Pr->pSiS_SR21);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x22,*SiS_Pr->pSiS_SR22);
+
+#if 0
+ SiS_SetReg3(SiS_Pr->SiS_P3c6,0xff);
+ SiS_ClearDAC(SiS_Pr, SiS_Pr->SiS_P3c8);
+#endif
+
+#ifdef LINUXBIOS /* TW: This is not needed for our purposes */
+ SiS_DetectMonitor(SiS_Pr, HwDeviceExtension,BaseAddr); /* Sense CRT1 */
+ SiS_GetSenseStatus(SiS_Pr, HwDeviceExtension,ROMAddr); /* Sense CRT2 */
+#endif
+
+ return(TRUE);
+}
+
+void
+SiS_Set_LVDS_TRUMPION(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ USHORT temp = 0;
+
+#ifdef SiS300
+ if((HwDeviceExtension->jChipType == SIS_540) ||
+ (HwDeviceExtension->jChipType == SIS_630) ||
+ (HwDeviceExtension->jChipType == SIS_730)) {
+ /* TW: Read POWER_ON_TRAP and copy to CR37 */
+ temp = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1A);
+ temp = (temp & 0xE0) >> 4;
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x37,0xF1,temp);
+ }
+#endif
+#ifdef SIS315H
+ if((HwDeviceExtension->jChipType == SIS_650) ||
+ (HwDeviceExtension->jChipType == SIS_740) ||
+ (HwDeviceExtension->jChipType == SIS_330)) {
+#if 0 /* TW: This is not required */
+ /* TW: Read POWER_ON_TRAP and copy to CR37 */
+ temp = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1A);
+ temp = (temp & 0xE0) >> 4;
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x37,0xF1,temp);
+#endif
+ }
+#endif
+
+ SiSSetLVDSetc(SiS_Pr, HwDeviceExtension, 0);
+}
+
+/* =============== SiS 300 dram sizing begin =============== */
+#ifdef SIS300
+void
+SiS_SetDRAMSize_300(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ ULONG FBAddr = (ULONG)HwDeviceExtension->pjVideoMemoryAddress;
+ USHORT SR13, SR14=0, buswidth, Done;
+ SHORT i, j, k;
+ USHORT data, TotalCapacity, PhysicalAdrOtherPage=0;
+ ULONG Addr;
+ UCHAR temp;
+ int PseudoRankCapacity, PseudoTotalCapacity, PseudoAdrPinCount;
+ int RankCapacity, AdrPinCount, BankNumHigh, BankNumMid, MB2Bank;
+ int PageCapacity, PhysicalAdrHigh, PhysicalAdrHalfPage;
+
+ SiSSetMode(SiS_Pr, HwDeviceExtension, 0x2e);
+
+ SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x01,0x20); /* Turn OFF Display */
+
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,0x00);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,0xBF);
+
+ buswidth = SiS_ChkBUSWidth_300(SiS_Pr, FBAddr);
+
+ MB2Bank = 16;
+ Done = 0;
+ for(i=6; i>=0; i--) {
+ if(Done == 1) break;
+ PseudoRankCapacity = 1 << i;
+ for(j=4; j>=1; j--) {
+ if(Done == 1) break;
+ PseudoTotalCapacity = PseudoRankCapacity * j;
+ PseudoAdrPinCount = 15 - j;
+ if(PseudoTotalCapacity <= 64) {
+ for(k=0; k<=16; k++) {
+ if(Done == 1) break;
+ RankCapacity = buswidth * SiS_DRAMType[k][3];
+ AdrPinCount = SiS_DRAMType[k][2] + SiS_DRAMType[k][0];
+ if(RankCapacity == PseudoRankCapacity)
+ if(AdrPinCount <= PseudoAdrPinCount) {
+ if(j == 3) { /* Rank No */
+ BankNumHigh = RankCapacity * MB2Bank * 3 - 1;
+ BankNumMid = RankCapacity * MB2Bank * 1 - 1;
+ } else {
+ BankNumHigh = RankCapacity * MB2Bank * j - 1;
+ BankNumMid = RankCapacity * MB2Bank * j / 2 - 1;
+ }
+ PageCapacity = (1 << SiS_DRAMType[k][1]) * buswidth * 4;
+ PhysicalAdrHigh = BankNumHigh;
+ PhysicalAdrHalfPage = (PageCapacity / 2 + PhysicalAdrHigh) % PageCapacity;
+ PhysicalAdrOtherPage = PageCapacity * SiS_DRAMType[k][2] + PhysicalAdrHigh;
+ /* Write data */
+ /*Test*/
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x15,0xFB);
+ SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x15,0x04);
+ /*/Test*/
+ TotalCapacity = SiS_DRAMType[k][3] * buswidth;
+ SR13 = SiS_DRAMType[k][4];
+ if(buswidth == 4) SR14 = (TotalCapacity - 1) | 0x80;
+ if(buswidth == 2) SR14 = (TotalCapacity - 1) | 0x40;
+ if(buswidth == 1) SR14 = (TotalCapacity - 1) | 0x00;
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,SR13);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,SR14);
+
+ Addr = FBAddr + (BankNumHigh) * 64 * 1024 + PhysicalAdrHigh;
+ *((USHORT *)(Addr)) = (USHORT)PhysicalAdrHigh;
+ Addr = FBAddr + (BankNumMid) * 64 * 1024 + PhysicalAdrHigh;
+ *((USHORT *)(Addr)) = (USHORT)BankNumMid;
+ Addr = FBAddr + (BankNumHigh) * 64 * 1024 + PhysicalAdrHalfPage;
+ *((USHORT *)(Addr)) = (USHORT)PhysicalAdrHalfPage;
+ Addr = FBAddr + (BankNumHigh) * 64 * 1024 + PhysicalAdrOtherPage;
+ *((USHORT *)(Addr)) = PhysicalAdrOtherPage;
+
+ /* Read data */
+ Addr = FBAddr + (BankNumHigh) * 64 * 1024 + PhysicalAdrHigh;
+ data = *((USHORT *)(Addr));
+ if(data == PhysicalAdrHigh) Done = 1;
+ } /* if struct */
+ } /* for loop (k) */
+ } /* if struct */
+ } /* for loop (j) */
+ } /* for loop (i) */
+}
+
+USHORT
+SiS_ChkBUSWidth_300(SiS_Private *SiS_Pr, ULONG FBAddress)
+{
+ PULONG pVideoMemory;
+
+ pVideoMemory = (PULONG)FBAddress;
+
+ pVideoMemory[0] = 0x01234567L;
+ pVideoMemory[1] = 0x456789ABL;
+ pVideoMemory[2] = 0x89ABCDEFL;
+ pVideoMemory[3] = 0xCDEF0123L;
+ if (pVideoMemory[3]==0xCDEF0123L) { /* Channel A 128bit */
+ return(4);
+ }
+ if (pVideoMemory[1]==0x456789ABL) { /* Channel B 64bit */
+ return(2);
+ }
+ return(1);
+}
+#endif
+/* =============== SiS 300 dram sizing end =============== */
+
+/* ============ SiS 310/325 dram sizing begin ============== */
+#ifdef SIS315H
+
+/* TW: Moved Get310DRAMType further down */
+
+void
+SiS_Delay15us(SiS_Private *SiS_Pr, ULONG ulMicrsoSec)
+{
+}
+
+void
+SiS_SDR_MRS(SiS_Private *SiS_Pr, )
+{
+ USHORT data;
+
+ data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16);
+ data &= 0x3F; /* SR16 D7=0, D6=0 */
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,data); /* enable mode register set(MRS) low */
+ SiS_Delay15us(SiS_Pr, 0x100);
+ data |= 0x80; /* SR16 D7=1, D6=0 */
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,data); /* enable mode register set(MRS) high */
+ SiS_Delay15us(SiS_Pr, 0x100);
+}
+
+void
+SiS_DDR_MRS(SiS_Private *SiS_Pr)
+{
+ USHORT data;
+
+ /* SR16 <- 1F,DF,2F,AF */
+
+ /* enable DLL of DDR SD/SGRAM , SR16 D4=1 */
+ data=SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16);
+ data &= 0x0F;
+ data |= 0x10;
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,data);
+
+ if (!(SiS_Pr->SiS_SR15[1][SiS_Pr->SiS_RAMType] & 0x10))
+ data &= 0x0F;
+
+ /* SR16 D7=1,D6=1 */
+ data |= 0xC0;
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,data);
+
+ /* SR16 D7=1,D6=0,D5=1,D4=0 */
+ data &= 0x0F;
+ data |= 0x20;
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,data);
+ if (!(SiS_Pr->SiS_SR15[1][SiS_Pr->SiS_RAMType] & 0x10))
+ data &= 0x0F;
+
+ /* SR16 D7=1 */
+ data |= 0x80;
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,data);
+}
+
+void
+SiS_SetDRAMModeRegister(SiS_Private *SiS_Pr, UCHAR *ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ if (SiS_Get310DRAMType(ROMAddr,HwDeviceExtension) < 2)
+ SiS_SDR_MRS(SiS_Pr);
+ else
+ /* SR16 <- 0F,CF,0F,8F */
+ SiS_DDR_MRS(SiS_Pr);
+}
+
+void
+SiS_DisableRefresh(SiS_Private *SiS_Pr)
+{
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x17,0xF8);
+ SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x19,0x03);
+}
+
+void
+SiS_EnableRefresh(SiS_Private *SiS_Pr, UCHAR *ROMAddr)
+{
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x17,SiS_Pr->SiS_SR15[2][SiS_Pr->SiS_RAMType]);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x19,SiS_Pr->SiS_SR15[4][SiS_Pr->SiS_RAMType]);
+}
+
+void
+SiS_DisableChannelInterleaving(SiS_Private *SiS_Pr, int index,
+ USHORT SiS_DDRDRAM_TYPE[][5])
+{
+ USHORT data;
+
+ data=SiS_GetReg1(SiS_Pr->SiS_P3c4,0x15);
+ data &= 0x1F;
+ switch (SiS_DDRDRAM_TYPE[index][3])
+ {
+ case 64: data |= 0; break;
+ case 32: data |= 0x20; break;
+ case 16: data |= 0x40; break;
+ case 4: data |= 0x60; break;
+ }
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x15,data);
+}
+
+void
+SiS_SetDRAMSizingType(SiS_Private *SiS_Pr, int index, USHORT DRAMTYPE_TABLE[][5])
+{
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,DRAMTYPE_TABLE[index][4]);
+ /* should delay 50 ns */
+}
+
+void
+SiS_CheckBusWidth_310(SiS_Private *SiS_Pr, UCHAR *ROMAddress,ULONG FBAddress,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ USHORT data, temp;
+ PULONG volatile pVideoMemory;
+
+ pVideoMemory = (PULONG)FBAddress;
+
+ if(HwDeviceExtension->jChipType == SIS_330) temp = 1;
+ else temp = 2;
+
+ if(SiS_Get310DRAMType(ROMAddress,HwDeviceExtension) < temp) {
+
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,0x00);
+ if(HwDeviceExtension->jChipType != SIS_330) {
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,0x12);
+ } else {
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,0x02);
+ }
+ /* should delay */
+ SiS_SDR_MRS(SiS_Pr);
+
+ SiS_Pr->SiS_ChannelAB = 0;
+ SiS_Pr->SiS_DataBusWidth = 128;
+ pVideoMemory[0] = 0x01234567L;
+ pVideoMemory[1] = 0x456789ABL;
+ pVideoMemory[2] = 0x89ABCDEFL;
+ pVideoMemory[3] = 0xCDEF0123L;
+ pVideoMemory[4] = 0x55555555L;
+ pVideoMemory[5] = 0x55555555L;
+ pVideoMemory[6] = 0xFFFFFFFFL;
+ pVideoMemory[7] = 0xFFFFFFFFL;
+ if((pVideoMemory[3] != 0xCDEF0123L) || (pVideoMemory[2] != 0x89ABCDEFL)) {
+ /* Channel A 64Bit */
+ SiS_Pr->SiS_DataBusWidth = 64;
+ SiS_Pr->SiS_ChannelAB = 0;
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x14, 0xFD);
+ }
+ if((pVideoMemory[1] != 0x456789ABL) || (pVideoMemory[0] != 0x01234567L)) {
+ /* Channel B 64Bit */
+ SiS_Pr->SiS_DataBusWidth = 64;
+ SiS_Pr->SiS_ChannelAB = 1;
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x14,0xfd,0x01);
+ }
+ return;
+
+ } else {
+
+ /* DDR Dual channel */
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,0x00);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,0x02); /* Channel A, 64bit */
+ /* should delay */
+ SiS_DDR_MRS(SiS_Pr);
+
+ SiS_Pr->SiS_ChannelAB = 0;
+ SiS_Pr->SiS_DataBusWidth = 64;
+ pVideoMemory[0] = 0x01234567L;
+ pVideoMemory[1] = 0x456789ABL;
+ pVideoMemory[2] = 0x89ABCDEFL;
+ pVideoMemory[3] = 0xCDEF0123L;
+ pVideoMemory[4] = 0x55555555L;
+ pVideoMemory[5] = 0x55555555L;
+ pVideoMemory[6] = 0xAAAAAAAAL;
+ pVideoMemory[7] = 0xAAAAAAAAL;
+
+ if (pVideoMemory[1] == 0x456789ABL) {
+ if (pVideoMemory[0] == 0x01234567L) {
+ /* Channel A 64bit */
+ return;
+ }
+ } else {
+ if (pVideoMemory[0] == 0x01234567L) {
+ /* Channel A 32bit */
+ SiS_Pr->SiS_DataBusWidth = 32;
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,0x00);
+ return;
+ }
+ }
+
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,0x03); /* Channel B, 64bit */
+ SiS_DDR_MRS(SiS_Pr);
+
+ SiS_Pr->SiS_ChannelAB = 1;
+ SiS_Pr->SiS_DataBusWidth = 64;
+ pVideoMemory[0] = 0x01234567L;
+ pVideoMemory[1] = 0x456789ABL;
+ pVideoMemory[2] = 0x89ABCDEFL;
+ pVideoMemory[3] = 0xCDEF0123L;
+ pVideoMemory[4] = 0x55555555L;
+ pVideoMemory[5] = 0x55555555L;
+ pVideoMemory[6] = 0xAAAAAAAAL;
+ pVideoMemory[7] = 0xAAAAAAAAL;
+ if(pVideoMemory[1] == 0x456789ABL) {
+ /* Channel B 64 */
+ if(pVideoMemory[0] == 0x01234567L) {
+ /* Channel B 64bit */
+ return;
+ } else {
+ /* error */
+ }
+ } else {
+ if(pVideoMemory[0] == 0x01234567L) {
+ /* Channel B 32 */
+ SiS_Pr->SiS_DataBusWidth = 32;
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,0x01);
+ } else {
+ /* error */
+ }
+ }
+ }
+}
+
+int
+SiS_SetRank(SiS_Private *SiS_Pr, int index,UCHAR RankNo,USHORT DRAMTYPE_TABLE[][5])
+{
+ USHORT data;
+ int RankSize;
+
+ if ((RankNo==2)&&(DRAMTYPE_TABLE[index][0]==2))
+ return 0;
+
+ RankSize = DRAMTYPE_TABLE[index][3]/2 * SiS_Pr->SiS_DataBusWidth / 32;
+
+ if (RankNo * RankSize <= 128) {
+ data = 0;
+ while((RankSize >>= 1) > 0) {
+ data += 0x10;
+ }
+ data |= (RankNo - 1) << 2;
+ data |= (SiS_Pr->SiS_DataBusWidth / 64) & 2;
+ data |= SiS_Pr->SiS_ChannelAB;
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,data);
+ /* should delay */
+ SiS_SDR_MRS(SiS_Pr);
+ return 1;
+ } else
+ return 0;
+}
+
+int
+SiS_SetDDRChannel(SiS_Private *SiS_Pr, int index,UCHAR ChannelNo,
+ USHORT DRAMTYPE_TABLE[][5])
+{
+ USHORT data;
+ int RankSize;
+
+ RankSize = DRAMTYPE_TABLE[index][3]/2 * SiS_Pr->SiS_DataBusWidth / 32;
+ /* RankSize = DRAMTYPE_TABLE[index][3]; */
+ if (ChannelNo * RankSize <= 128) {
+ data = 0;
+ while((RankSize >>= 1) > 0) {
+ data += 0x10;
+ }
+ if(ChannelNo == 2) data |= 0x0C;
+ data |= (SiS_Pr->SiS_DataBusWidth / 32) & 2;
+ data |= SiS_Pr->SiS_ChannelAB;
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,data);
+ /* should delay */
+ SiS_DDR_MRS(SiS_Pr);
+ return 1;
+ } else
+ return 0;
+}
+
+int
+SiS_CheckColumn(SiS_Private *SiS_Pr, int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress)
+{
+ int i;
+ ULONG Increment,Position;
+
+ /*Increment = 1<<(DRAMTYPE_TABLE[index][2] + SiS_Pr->SiS_DataBusWidth / 64 + 1); */
+ Increment = 1 << (10 + SiS_Pr->SiS_DataBusWidth / 64);
+
+ for (i=0,Position=0;i<2;i++) {
+ *((PULONG)(FBAddress + Position)) = Position;
+ Position += Increment;
+ }
+
+ for (i=0,Position=0;i<2;i++) {
+/* if (FBAddress[Position]!=Position) */
+ if((*(PULONG)(FBAddress + Position)) != Position)
+ return 0;
+ Position += Increment;
+ }
+ return 1;
+}
+
+int
+SiS_CheckBanks(SiS_Private *SiS_Pr, int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress)
+{
+ int i;
+ ULONG Increment,Position;
+ Increment = 1 << (DRAMTYPE_TABLE[index][2] + SiS_Pr->SiS_DataBusWidth / 64 + 2);
+
+ for (i=0,Position=0;i<4;i++) {
+/* FBAddress[Position]=Position; */
+ *((PULONG)(FBAddress + Position)) = Position;
+ Position += Increment;
+ }
+
+ for (i=0,Position=0;i<4;i++) {
+/* if (FBAddress[Position]!=Position) */
+ if((*(PULONG)(FBAddress + Position)) != Position)
+ return 0;
+ Position += Increment;
+ }
+ return 1;
+}
+
+int
+SiS_CheckRank(SiS_Private *SiS_Pr, int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress)
+{
+ int i;
+ ULONG Increment,Position;
+ Increment = 1<<(DRAMTYPE_TABLE[index][2] + DRAMTYPE_TABLE[index][1] +
+ DRAMTYPE_TABLE[index][0] + SiS_Pr->SiS_DataBusWidth / 64 + RankNo);
+
+ for (i=0,Position=0;i<2;i++) {
+/* FBAddress[Position]=Position; */
+ *((PULONG)(FBAddress+Position))=Position;
+ /* *((PULONG)(FBAddress))=Position; */
+ Position += Increment;
+ }
+
+ for (i=0,Position=0;i<2;i++) {
+/* if (FBAddress[Position]!=Position) */
+ if ( (*(PULONG) (FBAddress + Position)) !=Position)
+ /*if ( (*(PULONG) (FBAddress )) !=Position) */
+ return 0;
+ Position += Increment;
+ }
+ return 1;
+}
+
+int
+SiS_CheckDDRRank(SiS_Private *SiS_Pr, int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress)
+{
+ ULONG Increment,Position;
+ USHORT data;
+
+ Increment = 1<<(DRAMTYPE_TABLE[index][2] + DRAMTYPE_TABLE[index][1] +
+ DRAMTYPE_TABLE[index][0] + SiS_Pr->SiS_DataBusWidth / 64 + RankNo);
+
+ Increment += Increment/2;
+
+ Position =0;
+ *((PULONG)(FBAddress+Position + 0)) = 0x01234567;
+ *((PULONG)(FBAddress+Position + 1)) = 0x456789AB;
+ *((PULONG)(FBAddress+Position + 2)) = 0x55555555;
+ *((PULONG)(FBAddress+Position + 3)) = 0x55555555;
+ *((PULONG)(FBAddress+Position + 4)) = 0xAAAAAAAA;
+ *((PULONG)(FBAddress+Position + 5)) = 0xAAAAAAAA;
+
+ if ( (*(PULONG) (FBAddress + 1)) == 0x456789AB)
+ return 1;
+
+ if ( (*(PULONG) (FBAddress + 0)) == 0x01234567)
+ return 0;
+
+ data=SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
+ data &= 0xF3;
+ data |= 0x08;
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,data);
+ data=SiS_GetReg1(SiS_Pr->SiS_P3c4,0x15);
+ data += 0x20;
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x15,data);
+
+ return 1;
+}
+
+int
+SiS_CheckRanks(SiS_Private *SiS_Pr, int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress)
+{
+ int r;
+
+ for (r=RankNo;r>=1;r--) {
+ if (!SiS_CheckRank(SiS_Pr, r, index, DRAMTYPE_TABLE, FBAddress))
+ return 0;
+ }
+ if (!SiS_CheckBanks(SiS_Pr, index, DRAMTYPE_TABLE, FBAddress))
+ return 0;
+
+ if (!SiS_CheckColumn(SiS_Pr, index, DRAMTYPE_TABLE, FBAddress))
+ return 0;
+
+ return 1;
+}
+
+int
+SiS_CheckDDRRanks(SiS_Private *SiS_Pr, int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],
+ ULONG FBAddress)
+{
+ int r;
+
+ for (r=RankNo;r>=1;r--) {
+ if (!SiS_CheckDDRRank(SiS_Pr, r,index,DRAMTYPE_TABLE,FBAddress))
+ return 0;
+ }
+ if (!SiS_CheckBanks(SiS_Pr, index,DRAMTYPE_TABLE,FBAddress))
+ return 0;
+
+ if (!SiS_CheckColumn(SiS_Pr, index,DRAMTYPE_TABLE,FBAddress))
+ return 0;
+
+ return 1;
+}
+
+int
+SiS_SDRSizing(SiS_Private *SiS_Pr, ULONG FBAddress)
+{
+ int i;
+ UCHAR j;
+
+ for (i=0;i<13;i++) {
+ SiS_SetDRAMSizingType(SiS_Pr, i, SiS_SDRDRAM_TYPE);
+ for (j=2;j>0;j--) {
+ if (!SiS_SetRank(SiS_Pr, i,(UCHAR) j, SiS_SDRDRAM_TYPE))
+ continue;
+ else {
+ if (SiS_CheckRanks(SiS_Pr, j,i,SiS_SDRDRAM_TYPE, FBAddress))
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+int
+SiS_DDRSizing(SiS_Private *SiS_Pr, ULONG FBAddress)
+{
+
+ int i;
+ UCHAR j;
+
+ for (i=0; i<4; i++){
+ SiS_SetDRAMSizingType(SiS_Pr, i, SiS_DDRDRAM_TYPE);
+ SiS_DisableChannelInterleaving(SiS_Pr, i, SiS_DDRDRAM_TYPE);
+ for (j=2; j>0; j--) {
+ SiS_SetDDRChannel(SiS_Pr, i, j, SiS_DDRDRAM_TYPE);
+ if (!SiS_SetRank(SiS_Pr, i, (UCHAR) j, SiS_DDRDRAM_TYPE))
+ continue;
+ else {
+ if (SiS_CheckDDRRanks(SiS_Pr, j, i, SiS_DDRDRAM_TYPE, FBAddress))
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+/*
+ check if read cache pointer is correct
+*/
+void
+SiS_VerifyMclk(SiS_Private *SiS_Pr, ULONG FBAddr)
+{
+ PUCHAR pVideoMemory = (PUCHAR) FBAddr;
+ UCHAR i, j;
+ USHORT Temp,SR21;
+
+ pVideoMemory[0] = 0xaa; /* alan */
+ pVideoMemory[16] = 0x55; /* note: PCI read cache is off */
+
+ if((pVideoMemory[0] != 0xaa) || (pVideoMemory[16] != 0x55)) {
+ for (i=0,j=16; i<2; i++,j+=16) {
+ SR21 = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x21);
+ Temp = SR21 & 0xFB; /* disable PCI post write buffer empty gating */
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x21,Temp);
+
+ Temp = SiS_GetReg1(SiS_Pr->SiS_P3c4, 0x3C);
+ Temp |= 0x01; /* MCLK reset */
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x3C,Temp);
+ Temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x3C);
+ Temp &= 0xFE; /* MCLK normal operation */
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x3C,Temp);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x21,SR21);
+
+ pVideoMemory[16+j] = j;
+ if(pVideoMemory[16+j] == j) {
+ pVideoMemory[j] = j;
+ break;
+ }
+ }
+ }
+}
+
+/* TW: Is this a 315E? */
+int
+Is315E(SiS_Private *SiS_Pr)
+{
+ USHORT data;
+
+ data = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5F);
+ if(data & 0x10) return 1;
+ else return 0;
+}
+
+/* TW: For 315 only */
+void
+SiS_SetDRAMSize_310(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ UCHAR *ROMAddr = HwDeviceExtension->pjVirtualRomBase;
+ ULONG FBAddr = (ULONG)HwDeviceExtension->pjVideoMemoryAddress;
+ USHORT data;
+
+#ifdef SIS301 /* TW: SIS301 ??? */
+ /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x30,0x40); */
+#endif
+#ifdef SIS302 /* TW: SIS302 ??? */
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x30,0x4D); /* alan,should change value */
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x31,0xc0); /* alan,should change value */
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x34,0x3F); /* alan,should change value */
+#endif
+
+ SiSSetMode(SiS_Pr, HwDeviceExtension, 0x2e);
+
+ data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x21);
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x21,0xDF); /* disable read cache */
+
+ SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x01,0x20); /* Turn OFF Display */
+
+ SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x16,0x0F); /* assume lowest speed DRAM */
+
+ SiS_SetDRAMModeRegister(SiS_Pr, ROMAddr, HwDeviceExtension);
+ SiS_DisableRefresh(SiS_Pr);
+ SiS_CheckBusWidth_310(SiS_Pr, ROMAddr, FBAddr, HwDeviceExtension);
+
+ SiS_VerifyMclk(SiS_Pr, FBAddr);
+
+ if(HwDeviceExtension->jChipType == SIS_330) temp = 1;
+ else temp = 2;
+
+ if(SiS_Get310DRAMType(SiS_Pr, ROMAddr, HwDeviceExtension) < temp)
+ SiS_SDRSizing(SiS_Pr, FBAddr);
+ else
+ SiS_DDRSizing(SiS_Pr, FBAddr);
+
+ if(HwDeviceExtension->jChipType != SIS_330) {
+ if(Is315E(SiS_Pr)) {
+ data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
+ if((data & 0x0C) == 0x0C) { /* dual channel */
+ if((data & 0xF0) > 0x40)
+ data = (data & 0x0F) | 0x40;
+ } else { /* single channel */
+ if((data & 0xF0) > 0x50)
+ data = (data & 0x0F) | 0x50;
+ }
+ }
+ }
+
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,SiS_Pr->SiS_SR15[1][SiS_Pr->SiS_RAMType]); /* restore SR16 */
+
+ SiS_EnableRefresh(SiS_Pr, ROMAddr);
+ SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x21,0x20); /* enable read cache */
+}
+#endif
+
+void
+SiS_SetMemoryClock(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x28,SiS_Pr->SiS_MCLKData_0[SiS_Pr->SiS_RAMType].SR28);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x29,SiS_Pr->SiS_MCLKData_0[SiS_Pr->SiS_RAMType].SR29);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2A,SiS_Pr->SiS_MCLKData_0[SiS_Pr->SiS_RAMType].SR2A);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2E,SiS_Pr->SiS_ECLKData[SiS_Pr->SiS_RAMType].SR2E);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2F,SiS_Pr->SiS_ECLKData[SiS_Pr->SiS_RAMType].SR2F);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x30,SiS_Pr->SiS_ECLKData[SiS_Pr->SiS_RAMType].SR30);
+
+#ifdef SIS315H
+ if (Is315E(SiS_Pr)) {
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x28,0x3B); /* 143 */
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x29,0x22);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2E,0x3B); /* 143 */
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2F,0x22);
+ }
+#endif
+}
+
+#endif /* ifdef LINUXBIOS */
+
+#ifdef SIS315H
+UCHAR
+SiS_Get310DRAMType(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ UCHAR data, temp;
+
+ if(*SiS_Pr->pSiS_SoftSetting & SoftDRAMType) {
+ data = *SiS_Pr->pSiS_SoftSetting & 0x03;
+ } else {
+ if((HwDeviceExtension->jChipType > SIS_315PRO) &&
+ (HwDeviceExtension->jChipType < SIS_330)) {
+ data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x07;
+ } else { /* TW: 315, 330 */
+ data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x3a) & 0x03;
+ if(HwDeviceExtension->jChipType == SIS_330) {
+ if(data > 1) {
+ temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5f) & 0x30;
+ switch(temp) {
+ case 0x00: data = 1; break;
+ case 0x10: data = 3; break;
+ case 0x20: data = 3; break;
+ case 0x30: data = 2; break;
+ }
+ } else {
+ data = 0;
+ }
+ }
+ }
+ }
+
+ return data;
+}
+#endif
+
+/* SiSInit END */
+
+/* ----------------------------------------- */
+
+void SiSRegInit(SiS_Private *SiS_Pr, USHORT BaseAddr)
+{
+ SiS_Pr->SiS_P3c4 = BaseAddr + 0x14;
+ SiS_Pr->SiS_P3d4 = BaseAddr + 0x24;
+ SiS_Pr->SiS_P3c0 = BaseAddr + 0x10;
+ SiS_Pr->SiS_P3ce = BaseAddr + 0x1e;
+ SiS_Pr->SiS_P3c2 = BaseAddr + 0x12;
+ SiS_Pr->SiS_P3ca = BaseAddr + 0x1a;
+ SiS_Pr->SiS_P3c6 = BaseAddr + 0x16;
+ SiS_Pr->SiS_P3c7 = BaseAddr + 0x17;
+ SiS_Pr->SiS_P3c8 = BaseAddr + 0x18;
+ SiS_Pr->SiS_P3c9 = BaseAddr + 0x19;
+ SiS_Pr->SiS_P3da = BaseAddr + 0x2A;
+ SiS_Pr->SiS_Part1Port = BaseAddr + SIS_CRT2_PORT_04; /* Digital video interface registers (LCD) */
+ SiS_Pr->SiS_Part2Port = BaseAddr + SIS_CRT2_PORT_10; /* 301 TV Encoder registers */
+ SiS_Pr->SiS_Part3Port = BaseAddr + SIS_CRT2_PORT_12; /* 301 Macrovision registers */
+ SiS_Pr->SiS_Part4Port = BaseAddr + SIS_CRT2_PORT_14; /* 301 VGA2 (and LCD) registers */
+ SiS_Pr->SiS_Part5Port = BaseAddr + SIS_CRT2_PORT_14+2; /* 301 palette address port registers */
+ SiS_Pr->SiS_DDC_Port = BaseAddr + 0x14; /* DDC Port ( = P3C4, SR11/0A) */
+}
+
+void
+SiSInitPCIetc(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+/* #ifdef LINUX_XF86 */
+ if ((HwDeviceExtension->jChipType == SIS_540)||
+ (HwDeviceExtension->jChipType == SIS_630)||
+ (HwDeviceExtension->jChipType == SIS_730)||
+ (HwDeviceExtension->jChipType == SIS_300)) {
+ /* TW: Set - PCI LINEAR ADDRESSING ENABLE (0x80)
+ - PCI IO ENABLE (0x20)
+ - MMIO ENABLE (0x1)
+ */
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x20,0xa1);
+ /* TW: Enable 2D (0x42) & 3D accelerator (0x18) */
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1E,0xFF,0x5A);
+ }
+ if((HwDeviceExtension->jChipType == SIS_315H)||
+ (HwDeviceExtension->jChipType == SIS_315) ||
+ (HwDeviceExtension->jChipType == SIS_315PRO)||
+ (HwDeviceExtension->jChipType == SIS_550) ||
+ (HwDeviceExtension->jChipType == SIS_650) ||
+ (HwDeviceExtension->jChipType == SIS_740) ||
+ (HwDeviceExtension->jChipType == SIS_330)) {
+ /* TW: This seems to be done the same way on these chipsets */
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x20,0xa1);
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1E,0xFF,0x5A);
+ }
+/* #endif */
+}
+
+void
+SiSSetLVDSetc(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo)
+{
+ ULONG temp;
+
+ SiS_Pr->SiS_IF_DEF_LVDS = 0;
+ SiS_Pr->SiS_IF_DEF_TRUMPION = 0;
+ SiS_Pr->SiS_IF_DEF_CH70xx = 0;
+ SiS_Pr->SiS_IF_DEF_HiVision = 0;
+ SiS_Pr->SiS_IF_DEF_DSTN = 0;
+ SiS_Pr->SiS_IF_DEF_FSTN = 0;
+
+ SiS_Pr->SiS_ChrontelInit = 0;
+
+ if((ModeNo == 0x5a) || (ModeNo == 0x5b)) {
+ SiS_Pr->SiS_IF_DEF_DSTN = 1; /* for 550 dstn */
+ SiS_Pr->SiS_IF_DEF_FSTN = 1; /* for fstn */
+ }
+
+#ifdef SIS300
+ if((HwDeviceExtension->jChipType == SIS_540) ||
+ (HwDeviceExtension->jChipType == SIS_630) ||
+ (HwDeviceExtension->jChipType == SIS_730))
+ {
+ /* TW: Check for SiS30x first */
+ temp = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x00);
+ if((temp == 1) || (temp == 2)) return;
+ temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37);
+ temp = (temp & 0x0E) >> 1;
+ if((temp >= 2) && (temp <= 5)) SiS_Pr->SiS_IF_DEF_LVDS = 1;
+ if(temp == 3) SiS_Pr->SiS_IF_DEF_TRUMPION = 1;
+ if((temp == 4) || (temp == 5)) {
+ /* TW: Save power status (and error check) - UNUSED */
+ SiS_Pr->SiS_Backup70xx = SiS_GetCH700x(SiS_Pr, 0x0e);
+ SiS_Pr->SiS_IF_DEF_CH70xx = 1;
+ }
+ }
+#endif
+#ifdef SIS315H
+ if((HwDeviceExtension->jChipType == SIS_550) ||
+ (HwDeviceExtension->jChipType == SIS_650) ||
+ (HwDeviceExtension->jChipType == SIS_740) ||
+ (HwDeviceExtension->jChipType == SIS_330))
+ {
+ /* TW: CR37 is different on 310/325 series */
+ if(SiS_Pr->SiS_IF_DEF_FSTN) /* fstn: set CR37=0x04 */
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x37,0x04); /* (fake LVDS bridge) */
+
+ temp=SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37);
+ temp = (temp & 0x0E) >> 1;
+ if((temp >= 2) && (temp <= 3)) SiS_Pr->SiS_IF_DEF_LVDS = 1;
+ if(temp == 3) {
+ SiS_Pr->SiS_IF_DEF_CH70xx = 2;
+ }
+
+ /* HiVision (HDTV) is done differently now. */
+ /* SiS_Pr->SiS_IF_DEF_HiVision = 1; */
+ }
+#endif
+}
+
+void
+SiSInitPtr(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+#ifdef SIS315H
+ if((HwDeviceExtension->jChipType == SIS_315H) ||
+ (HwDeviceExtension->jChipType == SIS_315) ||
+ (HwDeviceExtension->jChipType == SIS_315PRO) ||
+ (HwDeviceExtension->jChipType == SIS_550) ||
+ (HwDeviceExtension->jChipType == SIS_650) ||
+ (HwDeviceExtension->jChipType == SIS_740) ||
+ (HwDeviceExtension->jChipType == SIS_330))
+ InitTo310Pointer(SiS_Pr, HwDeviceExtension);
+#endif
+
+#ifdef SIS300
+ if ((HwDeviceExtension->jChipType == SIS_540) ||
+ (HwDeviceExtension->jChipType == SIS_630) ||
+ (HwDeviceExtension->jChipType == SIS_730) ||
+ (HwDeviceExtension->jChipType == SIS_300))
+ InitTo300Pointer(SiS_Pr, HwDeviceExtension);
+#endif
+}
+
+void
+SiSDetermineROMUsage(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, UCHAR *ROMAddr)
+{
+ if((ROMAddr) && (HwDeviceExtension->UseROM)) {
+ if((ROMAddr[0x00] != 0x55) || (ROMAddr[0x01] != 0xAA)) {
+ SiS_Pr->SiS_UseROM = FALSE;
+ } else if(HwDeviceExtension->jChipType == SIS_300) {
+ /* TW: 300: We check if the code starts below 0x220 by
+ * checking the jmp instruction at the beginning
+ * of the BIOS image.
+ */
+ if((ROMAddr[3] == 0xe9) &&
+ ((ROMAddr[5] << 8) | ROMAddr[4]) > 0x21a)
+ SiS_Pr->SiS_UseROM = TRUE;
+ else SiS_Pr->SiS_UseROM = FALSE;
+ } else if(HwDeviceExtension->jChipType < SIS_315H) {
+ /* TW: Rest of 300 series: We don't use the ROM image if
+ * the BIOS version < 2.0.0 as such old BIOSes don't
+ * have the needed data at the expected locations.
+ */
+ if(ROMAddr[0x06] < '2') SiS_Pr->SiS_UseROM = FALSE;
+ else SiS_Pr->SiS_UseROM = TRUE;
+ } else {
+ /* TW: 310/325/330 series stick to the standard */
+ SiS_Pr->SiS_UseROM = TRUE;
+ }
+ } else SiS_Pr->SiS_UseROM = FALSE;
+
+}
+
+/*
+ =========================================
+ ======== SiS SetMode Functions ==========
+ =========================================
+*/
+#ifdef LINUX_XF86
+/* TW: This is used for non-Dual-Head mode from X */
+BOOLEAN
+SiSBIOSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, ScrnInfoPtr pScrn,
+ DisplayModePtr mode, BOOLEAN IsCustom)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ UShort ModeNo=0;
+
+ SiS_Pr->UseCustomMode = FALSE;
+
+ if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting custom mode %dx%d\n",
+ SiS_Pr->CHDisplay, SiS_Pr->CVDisplay);
+
+ return(SiSSetMode(SiS_Pr, HwDeviceExtension, pScrn, ModeNo, TRUE));
+
+ }
+
+ ModeNo = SiS_CalcModeIndex(pScrn, mode);
+ if(!ModeNo) return FALSE;
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting mode 0x%x\n", ModeNo);
+
+ return(SiSSetMode(SiS_Pr, HwDeviceExtension, pScrn, ModeNo, TRUE));
+}
+
+#ifdef SISDUALHEAD
+/* TW: Set CRT1 mode (used for dual head) */
+BOOLEAN
+SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, ScrnInfoPtr pScrn,
+ DisplayModePtr mode, BOOLEAN IsCustom)
+{
+ ULONG temp;
+ USHORT ModeIdIndex;
+ UCHAR *ROMAddr = HwDeviceExtension->pjVirtualRomBase;
+ USHORT BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
+ SISPtr pSiS = SISPTR(pScrn);
+ SISEntPtr pSiSEnt = pSiS->entityPrivate;
+ unsigned char backupreg=0;
+ BOOLEAN backupcustom;
+
+ UShort ModeNo=0;
+
+ SiS_Pr->UseCustomMode = FALSE;
+
+ if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+ "Setting custom mode %dx%d in CRT1\n",
+ SiS_Pr->CHDisplay, SiS_Pr->CVDisplay);
+ ModeNo = 0xfe;
+
+ } else {
+
+ ModeNo = SiS_CalcModeIndex(pScrn, mode);
+ if(!ModeNo) return FALSE;
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+ "Setting mode 0x%x on CRT1\n", ModeNo);
+ }
+
+ SiSInitPtr(SiS_Pr, HwDeviceExtension);
+
+ SiSRegInit(SiS_Pr, BaseAddr);
+
+ SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
+
+ SiSInitPCIetc(SiS_Pr, HwDeviceExtension);
+
+ SiSSetLVDSetc(SiS_Pr, HwDeviceExtension, ModeNo);
+
+ SiSDetermineROMUsage(SiS_Pr, HwDeviceExtension, ROMAddr);
+
+ /* TW: We don't clear the buffer under X */
+ SiS_Pr->SiS_flag_clearbuffer = 0;
+
+ /* 1.Openkey */
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86);
+
+ SiS_UnLockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr);
+
+ if(!SiS_Pr->UseCustomMode) {
+ /* 2.Get ModeID Table */
+ temp = SiS_SearchModeID(SiS_Pr, ROMAddr,&ModeNo,&ModeIdIndex);
+ if(temp == 0) return(0);
+ } else {
+ ModeIdIndex = 0;
+ }
+
+ /* TW: Determine VBType (301,301B,301LV,302B,302LV) */
+ SiS_GetVBType(SiS_Pr, BaseAddr,HwDeviceExtension);
+
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ backupreg = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
+ } else {
+ backupreg = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x35);
+ }
+ }
+
+ SiS_SetHiVision(SiS_Pr, BaseAddr,HwDeviceExtension);
+
+ /* TW: Get VB information (connectors, connected devices) */
+ /* (We don't care if the current mode is a CRT2 mode) */
+ SiS_GetVBInfo(SiS_Pr, BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,0);
+ SiS_GetLCDResInfo(SiS_Pr, ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
+
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x08) {
+ /* TW: I am not sure the flag's name is correct */
+ if(ModeNo != 0x10) SiS_Pr->SiS_SetFlag |= CRT2IsVGA;
+ }
+
+ /* TW: New from 650/LV 1.10.6x */
+ if(IS_SIS650740) {
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
+ SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
+ }
+ }
+ }
+
+ /* TW: Set mode on CRT1 */
+ SiS_SetCRT1Group(SiS_Pr, ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex,BaseAddr);
+
+ pSiSEnt->CRT1ModeNo = ModeNo;
+ pSiSEnt->CRT1DMode = mode;
+
+ /* TW: SetPitch: Adapt to virtual size & position */
+ SiS_SetPitchCRT1(SiS_Pr, pScrn, BaseAddr);
+
+ /* We have to reset CRT2 if changing mode on CRT1 */
+ if(pSiSEnt->CRT2ModeNo != -1) {
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+ "(Re-)Setting mode 0x%x on CRT2\n",
+ pSiSEnt->CRT2ModeNo);
+ backupcustom = SiS_Pr->UseCustomMode;
+ if(SiS_Pr->UseCustomMode) {
+ SiS_Pr->CRT1UsesCustomMode = TRUE;
+ } else {
+ SiS_Pr->CRT1UsesCustomMode = FALSE;
+ }
+ SiSBIOSSetModeCRT2(SiS_Pr, HwDeviceExtension, pSiSEnt->pScrn_1,
+ pSiSEnt->CRT2DMode);
+ SiS_Pr->UseCustomMode = backupcustom;
+ SiS_Pr->CRT1UsesCustomMode = FALSE;
+ }
+
+ if(IS_SIS650740) { /* TW: *** For 650 only! *** */
+ SiS_HandleCRT1(SiS_Pr);
+ }
+
+ SiS_DisplayOn(SiS_Pr);
+ SiS_SetReg3(SiS_Pr->SiS_P3c6,0xFF);
+
+ /* TW: New from 650/LV 1.10.6x and 1.10.7w, 630/301B 2.06.50 */
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x38,backupreg);
+ } else if((HwDeviceExtension->jChipType == SIS_630) ||
+ (HwDeviceExtension->jChipType == SIS_730)) {
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x35,backupreg);
+ }
+ }
+
+ /* Backup/Set ModeNo in BIOS scratch area */
+ SiS_GetSetModeID(pScrn,ModeNo);
+
+ return TRUE;
+}
+
+/* TW: Set CRT2 mode (used for dual head) */
+BOOLEAN
+SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, ScrnInfoPtr pScrn,
+ DisplayModePtr mode)
+{
+ ULONG temp;
+ USHORT ModeIdIndex;
+ UCHAR *ROMAddr = HwDeviceExtension->pjVirtualRomBase;
+ USHORT BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
+ UShort ModeNo = 0;
+ SISPtr pSiS = SISPTR(pScrn);
+ SISEntPtr pSiSEnt = pSiS->entityPrivate;
+ unsigned char tempr1, tempr2, backupreg=0;
+
+ SiS_Pr->UseCustomMode = FALSE;
+
+ ModeNo = SiS_CalcModeIndex(pScrn, mode);
+ if(!ModeNo) return FALSE;
+
+ SiSInitPtr(SiS_Pr, HwDeviceExtension);
+
+ SiSRegInit(SiS_Pr, BaseAddr);
+
+ SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
+
+ SiSInitPCIetc(SiS_Pr, HwDeviceExtension);
+
+ SiSSetLVDSetc(SiS_Pr, HwDeviceExtension, ModeNo);
+
+ SiSDetermineROMUsage(SiS_Pr, HwDeviceExtension, ROMAddr);
+
+ /* TW: We don't clear the buffer under X */
+ SiS_Pr->SiS_flag_clearbuffer=0;
+
+ /* TW: Save ModeNo so we can set it from within SetMode for CRT1 */
+ pSiSEnt->CRT2ModeNo = ModeNo;
+ pSiSEnt->CRT2DMode = mode;
+
+ /* TW: We can't set CRT2 mode before CRT1 mode is set */
+ if(pSiSEnt->CRT1ModeNo == -1) {
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+ "Setting CRT2 mode delayed until after setting CRT1 mode\n");
+ return TRUE;
+ }
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+ "Setting mode 0x%x on CRT2\n", ModeNo);
+
+ /* 1.Openkey */
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86);
+
+ SiS_UnLockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr);
+
+ /* 2.Get ModeID */
+ temp = SiS_SearchModeID(SiS_Pr, ROMAddr,&ModeNo,&ModeIdIndex);
+ if(temp == 0) return(0);
+
+ /* TW: Determine VBType (301,301B,301LV,302B,302LV) */
+ SiS_GetVBType(SiS_Pr, BaseAddr,HwDeviceExtension);
+
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension,BaseAddr);
+ if(HwDeviceExtension->jChipType < SIS_330) {
+ if(ROMAddr && SiS_Pr->SiS_UseROM) {
+ temp = ROMAddr[VB310Data_1_2_Offset];
+ temp |= 0x40;
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x02,temp);
+ }
+ }
+ SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x32,0x10);
+
+ SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x02,0x0c);
+
+ backupreg = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
+ } else {
+ backupreg = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x35);
+ }
+ }
+
+ /* TW: Get VB information (connectors, connected devices) */
+ SiS_SetHiVision(SiS_Pr, BaseAddr,HwDeviceExtension);
+ SiS_GetVBInfo(SiS_Pr, BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,1);
+ SiS_GetLCDResInfo(SiS_Pr, ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
+
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x08) {
+ /* TW: I am not sure the flag's name is correct */
+ if(ModeNo != 0x10) SiS_Pr->SiS_SetFlag |= CRT2IsVGA;
+ }
+ }
+
+ /* Set mode on CRT2 */
+ switch (HwDeviceExtension->ujVBChipID) {
+ case VB_CHIP_301:
+ case VB_CHIP_301B:
+ case VB_CHIP_301LV:
+ case VB_CHIP_301LVX:
+ case VB_CHIP_302:
+ case VB_CHIP_302B:
+ case VB_CHIP_302LV:
+ case VB_CHIP_302LVX:
+ SiS_SetCRT2Group301(SiS_Pr, BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
+ break;
+ case VB_CHIP_303:
+ break;
+ case VB_CHIP_UNKNOWN:
+ if (SiS_Pr->SiS_IF_DEF_LVDS == 1 ||
+ SiS_Pr->SiS_IF_DEF_CH70xx != 0 ||
+ SiS_Pr->SiS_IF_DEF_TRUMPION != 0) {
+ SiS_SetCRT2Group301(SiS_Pr,BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
+ }
+ break;
+ }
+
+ SiS_DisplayOn(SiS_Pr);
+ SiS_SetReg3(SiS_Pr->SiS_P3c6,0xFF);
+
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+ if(!(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr))) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
+ }
+ }
+ }
+
+ /* TW: New from 650/LV 1.10.6x and 1.10.7w, 630 2.06.50 */
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+ SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01);
+ } else {
+ SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x35,0xFE);
+ }
+
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x38,backupreg);
+
+ tempr1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
+ tempr2 = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x00);
+ if(tempr1 & SetCRT2ToAVIDEO) tempr2 &= 0xF7;
+ if(tempr1 & SetCRT2ToSVIDEO) tempr2 &= 0xFB;
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x00,tempr2);
+
+ if(tempr1 & SetCRT2ToLCD) {
+ SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
+ }
+ } else if((HwDeviceExtension->jChipType == SIS_630) ||
+ (HwDeviceExtension->jChipType == SIS_730)) {
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x35,backupreg);
+ }
+ }
+
+ /* TW: SetPitch: Adapt to virtual size & position */
+ SiS_SetPitchCRT2(SiS_Pr, pScrn, BaseAddr);
+
+ return TRUE;
+}
+#endif /* Dualhead */
+#endif /* Linux_XF86 */
+
+#ifdef LINUX_XF86
+/* TW: We need pScrn for setting the pitch correctly */
+BOOLEAN
+SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,ScrnInfoPtr pScrn,USHORT ModeNo, BOOLEAN dosetpitch)
+#else
+BOOLEAN
+SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo)
+#endif
+{
+ ULONG temp;
+ USHORT ModeIdIndex,KeepLockReg;
+ UCHAR *ROMAddr = HwDeviceExtension->pjVirtualRomBase;
+ USHORT BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
+ unsigned char backupreg=0, tempr1, tempr2;
+
+#ifndef LINUX_XF86
+ SiS_Pr->UseCustomMode = FALSE;
+ SiS_Pr->CRT1UsesCustomMode = FALSE;
+#endif
+
+ if(SiS_Pr->UseCustomMode) {
+ ModeNo = 0xfe;
+ }
+
+ SiSInitPtr(SiS_Pr, HwDeviceExtension);
+
+ SiSRegInit(SiS_Pr, BaseAddr);
+
+#ifdef LINUX_XF86
+ if(pScrn) SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
+ else
+#endif
+ SiS_Pr->SiS_VGAINFO = 0x11;
+
+ SiSInitPCIetc(SiS_Pr, HwDeviceExtension);
+
+ SiSSetLVDSetc(SiS_Pr, HwDeviceExtension, ModeNo);
+
+ SiSDetermineROMUsage(SiS_Pr, HwDeviceExtension, ROMAddr);
+
+ if(!SiS_Pr->UseCustomMode) {
+ /* TW: Shift the clear-buffer-bit away */
+ ModeNo = ((ModeNo & 0x80) << 8) | (ModeNo & 0x7f);
+ }
+
+#ifdef LINUX_XF86
+ /* TW: We never clear the buffer in X */
+ ModeNo |= 0x8000;
+#endif
+
+ if(ModeNo & 0x8000) {
+ ModeNo &= 0x7fff;
+ SiS_Pr->SiS_flag_clearbuffer = 0;
+ } else {
+ SiS_Pr->SiS_flag_clearbuffer = 1;
+ }
+
+ /* 1.Openkey */
+ KeepLockReg = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x05);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86);
+
+ SiS_UnLockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr);
+
+ if(!SiS_Pr->UseCustomMode) {
+
+ /* 2.Get ModeID Table */
+ temp = SiS_SearchModeID(SiS_Pr,ROMAddr,&ModeNo,&ModeIdIndex);
+ if(temp == 0) return(0);
+
+ } else {
+
+ ModeIdIndex = 0;
+
+ }
+
+ /* TW: Determine VBType (301,301B,301LV,302B,302LV) */
+ SiS_GetVBType(SiS_Pr,BaseAddr,HwDeviceExtension);
+
+ /* TW: Init/restore some VB registers */
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension,BaseAddr);
+ if(HwDeviceExtension->jChipType < SIS_330) {
+ if(ROMAddr && SiS_Pr->SiS_UseROM) {
+ temp = ROMAddr[VB310Data_1_2_Offset];
+ temp |= 0x40;
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x02,temp);
+ }
+ }
+ SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x32,0x10);
+
+ SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x02,0x0c);
+
+ backupreg = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
+ } else {
+ backupreg = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x35);
+ }
+ }
+
+ /* TW: Get VB information (connectors, connected devices) */
+ SiS_SetHiVision(SiS_Pr,BaseAddr,HwDeviceExtension);
+ SiS_GetVBInfo(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,1);
+ SiS_GetLCDResInfo(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
+
+ /* 3. Check memory size */
+ temp = SiS_CheckMemorySize(SiS_Pr,ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex);
+ if(!temp) return(0);
+
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x08) {
+ /* TW: I am not sure the flag's name is correct */
+ if(ModeNo != 0x10) SiS_Pr->SiS_SetFlag |= CRT2IsVGA;
+ }
+
+ /* TW: New from 650/LV 1.10.6x */
+ if(IS_SIS650740) {
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
+ SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
+ }
+ }
+ }
+
+ /* TW: Set mode on CRT1 */
+ if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SetCRT2ToLCDA)) {
+ SiS_SetCRT1Group(SiS_Pr,ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex,BaseAddr);
+ } else {
+ if(!(SiS_Pr->SiS_VBInfo & SwitchToCRT2)) {
+ SiS_SetCRT1Group(SiS_Pr,ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex,BaseAddr);
+ }
+ }
+
+ /* TW: Set mode on CRT2 */
+ if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchToCRT2 | SetCRT2ToLCDA)) {
+ switch (HwDeviceExtension->ujVBChipID) {
+ case VB_CHIP_301:
+ case VB_CHIP_301B:
+ case VB_CHIP_301LV:
+ case VB_CHIP_301LVX:
+ case VB_CHIP_302:
+ case VB_CHIP_302B:
+ case VB_CHIP_302LV:
+ case VB_CHIP_302LVX:
+ SiS_SetCRT2Group301(SiS_Pr,BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
+ break;
+ case VB_CHIP_303:
+ break;
+ case VB_CHIP_UNKNOWN:
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1 ||
+ SiS_Pr->SiS_IF_DEF_CH70xx != 0 ||
+ SiS_Pr->SiS_IF_DEF_TRUMPION != 0)
+ SiS_SetCRT2Group301(SiS_Pr,BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
+ break;
+ }
+ }
+
+ if(IS_SIS650740) { /* TW: For 650 only! */
+ SiS_HandleCRT1(SiS_Pr);
+ }
+
+ SiS_DisplayOn(SiS_Pr);
+ SiS_SetReg3(SiS_Pr->SiS_P3c6,0xFF);
+
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+#if 0
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+ SiS_Handle301B_1400x1050(SiS_Pr, ModeNo);
+ }
+ }
+#endif
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+ if(!(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr))) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
+ }
+ }
+ }
+
+ /* TW: New from 650/LV 1.10.6x and 1.10.7w */
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+ SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01);
+ } else {
+ SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x35,0xFE);
+ }
+
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x38,backupreg);
+
+ tempr1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
+ tempr2 = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x00);
+ if(tempr1 & SetCRT2ToAVIDEO) tempr2 &= 0xF7;
+ if(tempr1 & SetCRT2ToSVIDEO) tempr2 &= 0xFB;
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x00,tempr2);
+
+ if((IS_SIS650740) && (SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30) & 0xfc)) {
+ if((ModeNo == 0x03) || (ModeNo == 0x10)) {
+ SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x51,0x80);
+ SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x56,0x08);
+ }
+ }
+
+ if(tempr1 & SetCRT2ToLCD) {
+/* if(ModeNo <= 0x13) { - not in 1.10.8r */
+ SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
+/* } */
+ }
+ } else if((HwDeviceExtension->jChipType == SIS_630) ||
+ (HwDeviceExtension->jChipType == SIS_730)) {
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x35,backupreg);
+ }
+ }
+
+#ifdef LINUX_XF86
+ if(pScrn) {
+ /* TW: SetPitch: Adapt to virtual size & position */
+ if((ModeNo > 0x13) && (dosetpitch)) {
+ SiS_SetPitch(SiS_Pr, pScrn, BaseAddr);
+ }
+
+ /* Backup/Set ModeNo in BIOS scratch area */
+ SiS_GetSetModeID(pScrn, ModeNo);
+ }
+#endif
+
+#ifndef LINUX_XF86 /* TW: We never lock registers in XF86 */
+ if(KeepLockReg == 0xA1) SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86);
+ else SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x00);
+#endif
+
+ return TRUE;
+}
+
+void
+SiS_SetEnableDstn(SiS_Private *SiS_Pr) /* TW: Called from sis_main.c */
+{
+ /* For 550 dstn */
+ SiS_Pr->SiS_IF_DEF_DSTN = 1;
+}
+
+void
+SiS_HandleCRT1(SiS_Private *SiS_Pr)
+{
+ /* TW: Do this on 650 only! */
+
+ /* TW: No, we don't do this at all. There is a new
+ * CRT1-is-connected-at-boot-time logic in the 650, which
+ * confuses our own. So just clear the bit and skip the rest.
+ */
+
+ SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x63,0xbf);
+
+#if 0
+ if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x15) & 0x01))
+ SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x63,0x40);
+ }
+#endif
+}
+
+#if 0
+void
+SiS_Handle301B_1400x1050(SiS_Private *SiS_Pr, USHORT ModeNo)
+{
+ if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30) & SetCRT2ToLCD) {
+ if(ModeNo <= 0x13) {
+ if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & (SetNotSimuMode >> 8)) {
+ SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xFC);
+ }
+ }
+ }
+}
+#endif
+
+void
+SiS_SetCRT1Group(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+ USHORT ModeNo,USHORT ModeIdIndex,USHORT BaseAddr)
+{
+ USHORT StandTableIndex,RefreshRateTableIndex;
+
+ SiS_Pr->SiS_CRT1Mode = ModeNo;
+ StandTableIndex = SiS_GetModePtr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex);
+ if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
+ if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchToCRT2)) {
+ SiS_DisableBridge(SiS_Pr,HwDeviceExtension,BaseAddr);
+ }
+ }
+
+ SiS_SetSeqRegs(SiS_Pr,ROMAddr,StandTableIndex);
+ SiS_SetMiscRegs(SiS_Pr,ROMAddr,StandTableIndex);
+ SiS_SetCRTCRegs(SiS_Pr,ROMAddr,HwDeviceExtension,StandTableIndex);
+ SiS_SetATTRegs(SiS_Pr,ROMAddr,StandTableIndex,HwDeviceExtension);
+ SiS_SetGRCRegs(SiS_Pr,ROMAddr,StandTableIndex);
+ SiS_ClearExt1Regs(SiS_Pr,HwDeviceExtension);
+ SiS_ResetCRT1VCLK(SiS_Pr,ROMAddr,HwDeviceExtension);
+
+ SiS_Pr->SiS_SelectCRT2Rate = 0;
+ SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
+
+#ifdef LINUX_XF86
+ xf86DrvMsgVerb(0, X_PROBED, 3, "(init: VBType=0x%04x, VBInfo=0x%04x)\n",
+ SiS_Pr->SiS_VBType, SiS_Pr->SiS_VBInfo);
+#endif
+
+ if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) {
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+ SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
+ }
+ }
+
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+ SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
+ }
+
+ RefreshRateTableIndex = SiS_GetRatePtrCRT2(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
+
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+ SiS_Pr->SiS_SetFlag &= ~ProgrammingCRT2;
+ }
+
+ if(RefreshRateTableIndex != 0xFFFF) {
+ SiS_SetSync(SiS_Pr,ROMAddr,RefreshRateTableIndex);
+ SiS_SetCRT1CRTC(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwDeviceExtension);
+ SiS_SetCRT1Offset(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwDeviceExtension);
+ SiS_SetCRT1VCLK(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,RefreshRateTableIndex);
+ }
+
+#ifdef SIS300
+ if(HwDeviceExtension->jChipType == SIS_300) {
+ SiS_SetCRT1FIFO_300(SiS_Pr,ROMAddr,ModeNo,HwDeviceExtension,RefreshRateTableIndex);
+ }
+ if((HwDeviceExtension->jChipType == SIS_630) ||
+ (HwDeviceExtension->jChipType == SIS_730) ||
+ (HwDeviceExtension->jChipType == SIS_540)) {
+ SiS_SetCRT1FIFO_630(SiS_Pr,ROMAddr,ModeNo,HwDeviceExtension,RefreshRateTableIndex);
+ }
+#endif
+#ifdef SIS315H
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ SiS_SetCRT1FIFO_310(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
+ }
+#endif
+
+ SiS_SetCRT1ModeRegs(SiS_Pr,ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex,RefreshRateTableIndex);
+
+ SiS_LoadDAC(SiS_Pr,HwDeviceExtension,ROMAddr,ModeNo,ModeIdIndex);
+
+#ifndef LINUX_XF86
+ if(SiS_Pr->SiS_flag_clearbuffer) {
+ SiS_ClearBuffer(SiS_Pr,HwDeviceExtension,ModeNo);
+ }
+#endif
+
+ if(!(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchToCRT2 | SetCRT2ToLCDA))) {
+ SiS_LongWait(SiS_Pr);
+ SiS_DisplayOn(SiS_Pr);
+ }
+}
+
+#ifdef LINUX_XF86
+void
+SiS_SetPitch(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, UShort BaseAddr)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+
+ /* TW: We need to set pitch for CRT1 if bridge is in SlaveMode, too */
+ if( (pSiS->VBFlags & DISPTYPE_DISP1) ||
+ ( (pSiS->VBFlags & VB_VIDEOBRIDGE) &&
+ ( ((pSiS->VGAEngine == SIS_300_VGA) && (SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0xa0) == 0x20) ||
+ ((pSiS->VGAEngine == SIS_315_VGA) && (SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x50) == 0x10) ) ) ) {
+ SiS_SetPitchCRT1(SiS_Pr, pScrn, BaseAddr);
+ }
+ if (pSiS->VBFlags & DISPTYPE_DISP2) {
+ SiS_SetPitchCRT2(SiS_Pr, pScrn, BaseAddr);
+ }
+}
+
+void
+SiS_SetPitchCRT1(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, UShort BaseAddr)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ ULong HDisplay,temp;
+
+ HDisplay = pSiS->scrnPitch / 8;
+ SiS_SetReg1(SiS_Pr->SiS_P3d4, 0x13, (HDisplay & 0xFF));
+ temp = (SiS_GetReg1(SiS_Pr->SiS_P3c4, 0x0E) & 0xF0) | (HDisplay>>8);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4, 0x0E, temp);
+}
+
+void
+SiS_SetPitchCRT2(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, UShort BaseAddr)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ ULong HDisplay,temp;
+
+ HDisplay = pSiS->scrnPitch / 8;
+
+ /* Unlock CRT2 */
+ if (pSiS->VGAEngine == SIS_315_VGA)
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2F, 0x01);
+ else
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24, 0x01);
+
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07, (HDisplay & 0xFF));
+ temp = (SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x09) & 0xF0) | ((HDisplay >> 8) & 0xFF);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x09, temp);
+}
+#endif
+
+/* TW: Checked against 650/301 and 630/301B BIOS */
+/* TW: Re-written for 650/301LVx 1.10.6s BIOS */
+void
+SiS_GetVBType(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ USHORT flag=0, rev=0, nolcd=0;
+
+ SiS_Pr->SiS_VBType = 0;
+
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) return;
+
+ flag = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x00);
+
+ /* TW: Illegal values not welcome... */
+ if(flag > 10) return;
+
+ rev = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x01);
+
+ if (flag >= 2) {
+ SiS_Pr->SiS_VBType = VB_SIS302B;
+ } else if (flag == 1) {
+ SiS_Pr->SiS_VBType = VB_SIS301;
+ if(rev >= 0xB0) {
+ SiS_Pr->SiS_VBType = VB_SIS301B;
+ if((HwDeviceExtension->jChipType >= SIS_315H) ||
+ (HwDeviceExtension->jChipType == SIS_300)) {
+ /* 650/301LV and 300/301LV use this, 630/301B does not */
+ nolcd = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x23);
+ if(!(nolcd & 0x02))
+ SiS_Pr->SiS_VBType |= VB_NoLCD;
+ }
+ }
+ }
+ if(SiS_Pr->SiS_VBType & (VB_SIS301B | VB_SIS302B)) {
+ if(rev >= 0xD0) {
+ SiS_Pr->SiS_VBType &= ~(VB_SIS301B | VB_SIS302B);
+ SiS_Pr->SiS_VBType |= VB_SIS30xLV;
+ SiS_Pr->SiS_VBType &= ~(VB_NoLCD);
+ if(rev >= 0xE0) {
+ SiS_Pr->SiS_VBType &= ~(VB_SIS30xLV);
+ SiS_Pr->SiS_VBType |= VB_SIS30xNEW;
+ }
+ }
+ }
+}
+
+/* TW: Checked against 650/301LVx 1.10.6s */
+BOOLEAN
+SiS_SearchModeID(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT *ModeNo,USHORT *ModeIdIndex)
+{
+ UCHAR VGAINFO = SiS_Pr->SiS_VGAINFO;
+
+ if(*ModeNo <= 0x13) {
+
+ if((*ModeNo) <= 5) (*ModeNo) |= 1;
+
+ 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 <= 3) {
+ if(!(VGAINFO & 0x80)) (*ModeIdIndex)++;
+ if(VGAINFO & 0x10) (*ModeIdIndex)++; /* 400 lines */
+ /* else 350 lines */
+ }
+ /* else 200 lines */
+
+ } else {
+
+ for(*ModeIdIndex=0;;(*ModeIdIndex)++) {
+ if(SiS_Pr->SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == (*ModeNo)) break;
+ if(SiS_Pr->SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF) return FALSE;
+ }
+
+ }
+ return TRUE;
+}
+
+/* For SiS 300 oem util: Search VBModeID */
+BOOLEAN
+SiS_SearchVBModeID(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT *ModeNo)
+{
+ USHORT ModeIdIndex;
+ UCHAR VGAINFO = SiS_Pr->SiS_VGAINFO;
+
+ if(*ModeNo <= 5) *ModeNo |= 1;
+
+ for(ModeIdIndex=0; ; ModeIdIndex++) {
+ if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == *ModeNo) break;
+ if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == 0xFF) return FALSE;
+ }
+
+ if(*ModeNo != 0x07) {
+ if(*ModeNo > 0x03) return ((BOOLEAN)ModeIdIndex);
+ if(VGAINFO & 0x80) return ((BOOLEAN)ModeIdIndex);
+ ModeIdIndex++;
+ }
+ if(VGAINFO & 0x10) ModeIdIndex++; /* 400 lines */
+ /* else 350 lines */
+ return ((BOOLEAN)ModeIdIndex);
+}
+
+/* TW: Checked against 630/301B, 315 1.09 and 650/301LVx 1.10.6s BIOS */
+BOOLEAN
+SiS_CheckMemorySize(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+ USHORT ModeNo,USHORT ModeIdIndex)
+{
+ USHORT memorysize,modeflag;
+ ULONG temp;
+
+ if(SiS_Pr->UseCustomMode) {
+ modeflag = SiS_Pr->CModeFlag;
+ } else {
+ if(ModeNo <= 0x13) {
+ modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+ } else {
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ }
+ }
+
+ memorysize = modeflag & MemoryInfoFlag;
+ memorysize >>= MemorySizeShift; /* Get required memory size */
+ memorysize++;
+
+ temp = GetDRAMSize(SiS_Pr, HwDeviceExtension); /* Get adapter memory size */
+ temp /= (1024*1024); /* (in MB) */
+
+ if(temp < memorysize) return(FALSE);
+ else return(TRUE);
+}
+
+UCHAR
+SiS_GetModePtr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+{
+ UCHAR index;
+
+ if(ModeNo <= 0x13) {
+ index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_StTableIndex;
+ } else {
+ if(SiS_Pr->SiS_ModeType <= 0x02) index = 0x1B; /* 02 -> ModeEGA */
+ else index = 0x0F;
+ }
+ return index;
+}
+
+/* TW: Checked against 300, 330, 650/LVDS (1.10.07, 1.10a) and 650/301LV BIOS */
+void
+SiS_SetSeqRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex)
+{
+ UCHAR SRdata;
+ USHORT i;
+
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x00,0x03); /* Set SR0 */
+
+ SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[0];
+
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+ SRdata |= 0x01;
+ }
+ }
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+ if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+ SRdata |= 0x01; /* 8 dot clock */
+ }
+ }
+ }
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+ SRdata |= 0x01; /* 8 dot clock */
+ }
+ }
+ }
+
+ SRdata |= 0x20; /* screen off */
+
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x01,SRdata);
+
+ for(i = 2; i <= 4; i++) {
+ SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[i-1];
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,i,SRdata);
+ }
+}
+
+/* Checked against 300, 650/301LVx 1.10.6s and 650/LVDS 1.10.07 BIOS */
+void
+SiS_SetMiscRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex)
+{
+ UCHAR Miscdata;
+
+ Miscdata = SiS_Pr->SiS_StandTable[StandTableIndex].MISC;
+
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+ Miscdata |= 0x0C;
+ }
+ }
+
+ SiS_SetReg3(SiS_Pr->SiS_P3c2,Miscdata);
+}
+
+/* Checked against 300, 330, 650/LVDS (1.10.07) and 650/301LVx (1.10.6s) BIOS (630 code still there!) */
+void
+SiS_SetCRTCRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+ USHORT 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_SetReg1(SiS_Pr->SiS_P3d4,i,CRTCdata); /* Set CRTC(3d4) */
+ }
+ if( ( (HwDeviceExtension->jChipType == SIS_630) ||
+ (HwDeviceExtension->jChipType == SIS_730) ) &&
+ (HwDeviceExtension->jChipRevision >= 0x30) ) { /* for 630S0 */
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+ if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x18,0xFE);
+ }
+ }
+ }
+}
+
+/* TW: Checked against 300, 650/LVDS (1.10.07), 650/301LVx (1.10.6s) and 630/301B BIOS */
+void
+SiS_SetATTRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ UCHAR ARdata;
+ USHORT i;
+
+ for(i = 0; i <= 0x13; i++) {
+ ARdata = SiS_Pr->SiS_StandTable[StandTableIndex].ATTR[i];
+#if 0
+ if((i <= 0x0f) || (i == 0x11)) {
+ if(ds:489 & 0x08) {
+ continue;
+ }
+ }
+#endif
+ if(i == 0x13) {
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) ARdata=0;
+ }
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+ if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata=0;
+ }
+ }
+ }
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ /* TW: From 650/LVDS 1.10.07, 1.10a; 650/301LVx 1.10.6s; not in 330 BIOS */
+ ARdata = 0;
+ } else {
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+ ARdata=0;
+ }
+ }
+ }
+ }
+ SiS_GetReg2(SiS_Pr->SiS_P3da); /* reset 3da */
+ SiS_SetReg3(SiS_Pr->SiS_P3c0,i); /* set index */
+ SiS_SetReg3(SiS_Pr->SiS_P3c0,ARdata); /* set data */
+ }
+ SiS_GetReg2(SiS_Pr->SiS_P3da); /* reset 3da */
+ SiS_SetReg3(SiS_Pr->SiS_P3c0,0x14); /* set index */
+ SiS_SetReg3(SiS_Pr->SiS_P3c0,0x00); /* set data */
+
+ SiS_GetReg2(SiS_Pr->SiS_P3da);
+ SiS_SetReg3(SiS_Pr->SiS_P3c0,0x20); /* Enable Attribute */
+ SiS_GetReg2(SiS_Pr->SiS_P3da);
+}
+
+/* TW: Checked against 300, 330, 650/LVDS (1.10.07, 1.10a) and 650/301LV BIOS */
+void
+SiS_SetGRCRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex)
+{
+ UCHAR GRdata;
+ USHORT i;
+
+ for(i = 0; i <= 0x08; i++) {
+ GRdata = SiS_Pr->SiS_StandTable[StandTableIndex].GRC[i];
+ SiS_SetReg1(SiS_Pr->SiS_P3ce,i,GRdata); /* Set GR(3ce) */
+ }
+
+ if(SiS_Pr->SiS_ModeType > ModeVGA) {
+ SiS_SetRegAND(SiS_Pr->SiS_P3ce,0x05,0xBF); /* 256 color disable */
+ }
+}
+
+/* TW: Checked against 650/LVDS (1.10.07, 1.10a), 650/301LVx (1.10.6s) and 630/301B BIOS */
+void
+SiS_ClearExt1Regs(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ USHORT i;
+
+ for(i = 0x0A; i <= 0x0E; i++) {
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,i,0x00); /* Clear SR0A-SR0E */
+ }
+
+ /* TW: New from 330, 650/LVDS/301LV BIOSes: */
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x37,0xFE);
+ }
+}
+
+/* TW: Checked against 300, 330, 650/LVDS (1.10.07) and 650/301LV BIOS */
+void
+SiS_SetSync(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT RefreshRateTableIndex)
+{
+ USHORT sync;
+ USHORT temp;
+
+ if(SiS_Pr->UseCustomMode) {
+ sync = SiS_Pr->CInfoFlag >> 8;
+ } else {
+ sync = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag >> 8;
+ }
+
+ sync &= 0xC0;
+ temp = 0x2F | sync;
+ SiS_SetReg3(SiS_Pr->SiS_P3c2,temp); /* Set Misc(3c2) */
+}
+
+/* TW: Checked against 300, 330, 650/LVDS (1.10.07) and 650/301LVx (1.10.6s) BIOS */
+void
+SiS_SetCRT1CRTC(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ UCHAR index;
+ USHORT tempah,i,modeflag,j;
+#ifdef SIS315H
+ USHORT temp;
+ USHORT ResInfo,DisplayType;
+ const SiS_LCDACRT1DataStruct *LCDACRT1Ptr = NULL;
+#endif
+
+ SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f); /*unlock cr0-7 */
+
+ if(SiS_Pr->UseCustomMode) {
+ modeflag = SiS_Pr->CModeFlag;
+ } else {
+ if(ModeNo <= 0x13) {
+ modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+ } else {
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ }
+ }
+
+ if((SiS_Pr->SiS_IF_DEF_LVDS == 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+
+#ifdef SIS315H
+
+ /* LCDA */
+
+ temp = SiS_GetLCDACRT1Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
+ RefreshRateTableIndex,&ResInfo,&DisplayType);
+
+ switch(DisplayType) {
+ case Panel_800x600 : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT1800x600_1; break;
+ case Panel_1024x768 : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_1; break;
+ case Panel_1280x1024 : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_1; break;
+ case Panel_1400x1050 : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11400x1050_1; break;
+ case Panel_1600x1200 : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11600x1200_1; break;
+ case Panel_800x600 + 16 : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT1800x600_1_H; break;
+ case Panel_1024x768 + 16 : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_1_H; break;
+ case Panel_1280x1024 + 16: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_1_H; break;
+ case Panel_1400x1050 + 16: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11400x1050_1_H; break;
+ case Panel_1600x1200 + 16: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11600x1200_1_H; break;
+ case Panel_800x600 + 32 : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT1800x600_2; break;
+ case Panel_1024x768 + 32 : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_2; break;
+ case Panel_1280x1024 + 32: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_2; break;
+ case Panel_1400x1050 + 32: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11400x1050_2; break;
+ case Panel_1600x1200 + 32: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11600x1200_2; break;
+ case Panel_800x600 + 48 : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT1800x600_2_H; break;
+ case Panel_1024x768 + 48 : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_2_H; break;
+ case Panel_1280x1024 + 48: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_2_H; break;
+ case Panel_1400x1050 + 48: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11400x1050_2_H; break;
+ case Panel_1600x1200 + 48: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11600x1200_2_H; break;
+ default: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_1; break;
+ }
+
+ tempah = (LCDACRT1Ptr+ResInfo)->CR[0];
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x00,tempah);
+ for(i=0x01,j=1;i<=0x07;i++,j++){
+ tempah = (LCDACRT1Ptr+ResInfo)->CR[j];
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
+ }
+ for(i=0x10,j=8;i<=0x12;i++,j++){
+ tempah = (LCDACRT1Ptr+ResInfo)->CR[j];
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
+ }
+ for(i=0x15,j=11;i<=0x16;i++,j++){
+ tempah =(LCDACRT1Ptr+ResInfo)->CR[j];
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
+ }
+ for(i=0x0A,j=13;i<=0x0C;i++,j++){
+ tempah = (LCDACRT1Ptr+ResInfo)->CR[j];
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,i,tempah);
+ }
+
+ tempah = (LCDACRT1Ptr+ResInfo)->CR[16];
+ tempah &= 0x0E0;
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x0E,tempah);
+
+ tempah = (LCDACRT1Ptr+ResInfo)->CR[16];
+ tempah &= 0x01;
+ tempah <<= 5;
+ if(modeflag & DoubleScanMode) tempah |= 0x080;
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
+
+#endif
+
+ } else {
+
+ /* LVDS, 301, 301B, 301LV, 302LV, ... (non-LCDA) */
+
+ if(SiS_Pr->UseCustomMode) {
+
+ for(i=0,j=0;i<=07;i++,j++) {
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
+ }
+ for(j=0x10;i<=10;i++,j++) {
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
+ }
+ for(j=0x15;i<=12;i++,j++) {
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
+ }
+ for(j=0x0A;i<=15;i++,j++) {
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,j,SiS_Pr->CCRT1CRTC[i]);
+ }
+
+ tempah = SiS_Pr->CCRT1CRTC[16] & 0xE0;
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x0E,tempah);
+
+ tempah = SiS_Pr->CCRT1CRTC[16];
+ tempah &= 0x01;
+ tempah <<= 5;
+ if(modeflag & DoubleScanMode) tempah |= 0x80;
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0xDF,tempah);
+
+
+ } else {
+
+ index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; /* Get index */
+#if 0 /* Not any longer... */
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+ index &= 0x3F;
+ }
+#endif
+
+ for(i=0,j=0;i<=07;i++,j++) {
+ tempah=SiS_Pr->SiS_CRT1Table[index].CR[i];
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,j,tempah);
+ }
+ for(j=0x10;i<=10;i++,j++) {
+ tempah=SiS_Pr->SiS_CRT1Table[index].CR[i];
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,j,tempah);
+ }
+ for(j=0x15;i<=12;i++,j++) {
+ tempah=SiS_Pr->SiS_CRT1Table[index].CR[i];
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,j,tempah);
+ }
+ for(j=0x0A;i<=15;i++,j++) {
+ tempah=SiS_Pr->SiS_CRT1Table[index].CR[i];
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,j,tempah);
+ }
+
+ tempah = SiS_Pr->SiS_CRT1Table[index].CR[16];
+ tempah &= 0xE0;
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x0E,tempah);
+
+ tempah = SiS_Pr->SiS_CRT1Table[index].CR[16];
+ tempah &= 0x01;
+ tempah <<= 5;
+ if(modeflag & DoubleScanMode) tempah |= 0x80;
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0xDF,tempah);
+
+ }
+ }
+
+ if(SiS_Pr->SiS_ModeType > ModeVGA) SiS_SetReg1(SiS_Pr->SiS_P3d4,0x14,0x4F);
+}
+
+BOOLEAN
+SiS_GetLCDACRT1Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,USHORT *ResInfo,
+ USHORT *DisplayType)
+ {
+ USHORT tempbx=0,modeflag=0;
+ USHORT CRT2CRTC=0;
+
+ if(ModeNo <= 0x13) {
+ modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+ CRT2CRTC = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+ } else {
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ CRT2CRTC = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+ }
+
+ tempbx = SiS_Pr->SiS_LCDResInfo;
+
+ if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) tempbx += 32;
+ if(modeflag & HalfDCLK) tempbx += 16;
+
+ *ResInfo = CRT2CRTC & 0x3F;
+ *DisplayType = tempbx;
+
+ return 1;
+}
+
+/* TW: Set offset and pitch - partly overruled by SetPitch() in XF86 */
+/* TW: Checked against 330, 650/LVDS (1.10.07), 650/301LV and 315 BIOS */
+void
+SiS_SetCRT1Offset(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ USHORT temp, DisplayUnit, infoflag;
+
+ if(SiS_Pr->UseCustomMode) {
+ infoflag = SiS_Pr->CInfoFlag;
+ } else {
+ infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+ }
+
+ DisplayUnit = SiS_GetOffset(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
+ RefreshRateTableIndex,HwDeviceExtension);
+
+ temp = (DisplayUnit >> 8) & 0x0f;
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0xF0,temp);
+
+ temp = DisplayUnit & 0xFF;
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x13,temp);
+
+ if(infoflag & InterlaceMode) DisplayUnit >>= 1;
+
+ DisplayUnit <<= 5;
+ temp = (DisplayUnit & 0xff00) >> 8;
+ if (DisplayUnit & 0xff) temp++;
+ temp++;
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x10,temp);
+}
+
+/* TW: New from 650/LVDS 1.10.07, 630/301B and 630/LVDS BIOS */
+void
+SiS_ResetCRT1VCLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ USHORT index;
+
+ /* TW: We only need to do this if Panel Link is to be
+ * initialized, thus on 630/LVDS/301B, and 650/LVDS
+ */
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ if (SiS_Pr->SiS_IF_DEF_LVDS == 0) return;
+ } else {
+ if( (SiS_Pr->SiS_IF_DEF_LVDS == 0) &&
+ (!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) ) {
+ return;
+ }
+ }
+
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x31,0xCF,0x20);
+ } else {
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x20);
+ }
+ index = 1;
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VCLKData[index].SR2B);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VCLKData[index].SR2C);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2D,0x80);
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x31,0xcf,0x10);
+ } else {
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x10);
+ }
+ index = 0;
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VCLKData[index].SR2B);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VCLKData[index].SR2C);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2D,0x80);
+}
+
+/* TW: Checked against 300, 330, 650/LVDS, 650/301LVx, 315, 630/301B, 630/LVDS BIOS */
+void
+SiS_SetCRT1VCLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension,
+ USHORT RefreshRateTableIndex)
+{
+ USHORT index=0;
+
+ if(!SiS_Pr->UseCustomMode) {
+ index = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
+ RefreshRateTableIndex,HwDeviceExtension);
+ }
+
+ if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
+ && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) ){
+
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x31,0xCF);
+
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VBVCLKData[index].Part4_A);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VBVCLKData[index].Part4_B);
+
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2D,0x01);
+ } else {
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2D,0x80);
+ }
+
+ } else {
+
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x31,0xCF);
+ } else {
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x00);
+ }
+
+ if(SiS_Pr->UseCustomMode) {
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->CSR2B);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->CSR2C);
+ } else {
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VCLKData[index].SR2B);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VCLKData[index].SR2C);
+ }
+
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2D,0x01);
+ } else {
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2D,0x80);
+ }
+ }
+}
+
+#if 0 /* TW: Not used */
+void
+SiS_IsLowResolution(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+{
+ USHORT ModeFlag;
+
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x0F,0x7F);
+
+ if(ModeNo > 0x13) {
+ ModeFlag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ if ((ModeFlag & HalfDCLK) && (ModeFlag & DoubleScanMode)) {
+ SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x0F,0x80);
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x01,0xF7);
+ }
+ }
+}
+#endif
+
+/* TW: Checked against 300, 630/LVDS, 650/LVDS, 315 and 330 BIOS */
+void
+SiS_SetCRT1ModeRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+ USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex)
+{
+ USHORT data,data2,data3;
+ USHORT infoflag=0,modeflag;
+ USHORT resindex,xres;
+
+ if(SiS_Pr->UseCustomMode) {
+ modeflag = SiS_Pr->CModeFlag;
+ infoflag = SiS_Pr->CInfoFlag;
+ } else {
+ if(ModeNo > 0x13) {
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+ } else {
+ modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+ }
+ }
+
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1F,0x3F); /* DAC pedestal */
+
+ if(ModeNo > 0x13) data = infoflag;
+ else data = 0;
+
+ data2 = 0;
+ if(ModeNo > 0x13) {
+ if(SiS_Pr->SiS_ModeType > 0x02) {
+ data2 |= 0x02;
+ data3 = (SiS_Pr->SiS_ModeType - ModeVGA) << 2;
+ data2 |= data3;
+ }
+ }
+#ifdef TWDEBUG
+ xf86DrvMsg(0, X_INFO, "Debug: Mode infoflag = %x, Chiptype %d\n",
+ data, HwDeviceExtension->jChipType);
+#endif
+ if(data & InterlaceMode) data2 |= 0x20;
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x06,0xC0,data2);
+
+ if(SiS_Pr->UseCustomMode) {
+ xres = SiS_Pr->CHDisplay;
+ } else {
+ resindex = SiS_GetResInfo(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex);
+ if(ModeNo <= 0x13) {
+ xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
+ } else {
+ xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
+ }
+ }
+
+ if(HwDeviceExtension->jChipType != SIS_300) {
+ data = 0x0000;
+ if(infoflag & InterlaceMode) {
+ if(xres == 1024) data = 0x0035;
+ else data = 0x0048;
+ }
+ data2 = data & 0x00FF;
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x19,data2);
+ data2 = (data & 0xFF00) >> 8;
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x1a,0xFC,data2);
+ }
+
+ if(modeflag & HalfDCLK) {
+ SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x01,0x08);
+ }
+
+ if(HwDeviceExtension->jChipType == SIS_300) {
+ if(modeflag & LineCompareOff) {
+ SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x0F,0x08);
+ } else {
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x0F,0xF7);
+ }
+ } else if(HwDeviceExtension->jChipType < SIS_315H) {
+ if(modeflag & LineCompareOff) {
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xB7,0x08);
+ } else {
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x0F,0xB7);
+ }
+ /* 630 BIOS does something for mode 0x12 here */
+ } else {
+ if(modeflag & LineCompareOff) {
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xB7,0x08);
+ } else {
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x0F,0xB7);
+ }
+ }
+
+ if(HwDeviceExtension->jChipType != SIS_300) {
+ if(SiS_Pr->SiS_ModeType == ModeEGA) {
+ if(ModeNo > 0x13) {
+ SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x0F,0x40);
+ }
+ }
+ }
+
+#ifdef SIS315H
+ /* TW: 315 BIOS sets SR17 at this point */
+ if(HwDeviceExtension->jChipType == SIS_315PRO) {
+ data = SiS_Get310DRAMType(SiS_Pr,ROMAddr,HwDeviceExtension);
+ data = SiS_Pr->SiS_SR15[2][data];
+ if(SiS_Pr->SiS_ModeType == ModeText) {
+ data &= 0xc7;
+ } else {
+ data2 = SiS_GetOffset(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
+ RefreshRateTableIndex,HwDeviceExtension);
+ data2 >>= 1;
+ if(infoflag & InterlaceMode) data2 >>= 1;
+ data3 = SiS_GetColorDepth(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex);
+ data3 >>= 1;
+ if(data3 == 0) data3++;
+ data2 /= data3;
+ if(data2 >= 0x50) {
+ data &= 0x0f;
+ data |= 0x50;
+ }
+ }
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x17,data);
+ }
+
+ /* TW: 330 BIOS sets SR17 at this point */
+ if(HwDeviceExtension->jChipType == SIS_330) {
+ data = SiS_Get310DRAMType(SiS_Pr,ROMAddr,HwDeviceExtension);
+ data = SiS_Pr->SiS_SR15[2][data];
+ if(SiS_Pr->SiS_ModeType <= ModeEGA) {
+ data &= 0xc7;
+ } else {
+ if(SiS_Pr->UseCustomMode) {
+ data2 = SiS_Pr->CSRClock;
+ } else {
+ data2 = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
+ RefreshRateTableIndex,HwDeviceExtension);
+ data2 = SiS_Pr->SiS_VCLKData[data2].CLOCK;
+ }
+
+ data3 = SiS_GetColorDepth(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex);
+ data3 >>= 1;
+
+ data2 *= data3;
+
+ data3 = SiS_GetMCLK(SiS_Pr,ROMAddr, HwDeviceExtension);
+ data3 *= 1024;
+
+ data2 = data3 / data2;
+
+ if(SiS_Pr->SiS_ModeType != Mode16Bpp) {
+ if(data2 >= 0x19c) data = 0xba;
+ else if(data2 >= 0x140) data = 0x7a;
+ else if(data2 >= 0x101) data = 0x3a;
+ else if(data2 >= 0xf5) data = 0x32;
+ else if(data2 >= 0xe2) data = 0x2a;
+ else if(data2 >= 0xc4) data = 0x22;
+ else if(data2 >= 0xac) data = 0x1a;
+ else if(data2 >= 0x9e) data = 0x12;
+ else if(data2 >= 0x8e) data = 0x0a;
+ else data = 0x02;
+ } else {
+ if(data2 >= 0x127) data = 0xba;
+ else data = 0x7a;
+ }
+ }
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x17,data);
+ }
+#endif
+
+ data = 0x60;
+ if(SiS_Pr->SiS_ModeType != ModeText) {
+ data ^= 0x60;
+ if(SiS_Pr->SiS_ModeType != ModeEGA) {
+ data ^= 0xA0;
+ }
+ }
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x21,0x1F,data);
+
+ SiS_SetVCLKState(SiS_Pr,ROMAddr,HwDeviceExtension,ModeNo,RefreshRateTableIndex,ModeIdIndex);
+
+#ifdef SIS315H
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x40) {
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x52,0x2c);
+ } else {
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x52,0x6c);
+ }
+ }
+#endif
+}
+
+/* TW: Checked against 300, 315, 330, 650/LVDS, 650/301LVx, 630/301B and 630/LVDS BIOS */
+void
+SiS_SetVCLKState(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+ USHORT ModeNo,USHORT RefreshRateTableIndex,
+ USHORT ModeIdIndex)
+{
+ USHORT data, data2=0;
+ USHORT VCLK, index=0;
+
+ if (ModeNo <= 0x13) VCLK = 0;
+ else {
+ if(SiS_Pr->UseCustomMode) {
+ VCLK = SiS_Pr->CSRClock;
+ } else {
+ index = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
+ RefreshRateTableIndex,HwDeviceExtension);
+ VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
+ }
+ }
+
+ if(HwDeviceExtension->jChipType < SIS_315H) { /* 300 series */
+
+ data2 = 0x00;
+ if(VCLK > 150) data2 |= 0x80;
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0x7B,data2); /* DAC speed */
+
+ data2 = 0x00;
+ if(VCLK >= 150) data2 |= 0x08; /* VCLK > 150 */
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xF7,data2);
+
+ } else { /* 310/325 series */
+
+ data = 0;
+ if(VCLK >= 166) data |= 0x0c; /* TW: Was 200; is 166 in 650, 315 and 330 BIOSes */
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xf3,data);
+
+ if(VCLK >= 166) { /* TW: Was 200, is 166 in 650, 315 and 330 BIOSes */
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1f,0xe7);
+ }
+#if 0 /* Not done in 315 and 650/301LV/LVDS BIOSes: */
+ data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1F); /* DAC pedestal */
+ data &= 0xE7;
+ if(VCLK<200) data |= 0x10;
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1F,data); /* DAC pedestal */
+#endif
+ }
+
+ data2 = 0x03;
+ if((VCLK >= 135) && (VCLK < 160)) data2 = 0x02;
+ if((VCLK >= 160) && (VCLK < 260)) data2 = 0x01;
+ if(VCLK >= 260) data2 = 0x00;
+
+ if(HwDeviceExtension->jChipType == SIS_540) {
+ if((VCLK == 203) || (VCLK < 234)) data2 = 0x02;
+ }
+
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xFC,data2); /* DAC speed */
+ } else {
+ if(HwDeviceExtension->jChipType > SIS_315PRO) {
+ /* TW: This "if" is done in 330 and 650/LVDS/301LV BIOSes; Not in 315 BIOS */
+ if(ModeNo > 0x13) data2 &= 0xfc;
+ }
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xF8,data2); /* DAC speed */
+ }
+}
+
+/* TW: Checked against 650/301LVx 1.10.6s, 315, 630/301B BIOS */
+void
+SiS_LoadDAC(SiS_Private *SiS_Pr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+ UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+{
+ USHORT data,data2;
+ USHORT time,i,j,k;
+ USHORT m,n,o;
+ USHORT si,di,bx,dl;
+ USHORT al,ah,dh;
+ USHORT DACAddr, DACData, shiftflag;
+ const USHORT *table = NULL;
+#if 0
+ USHORT tempah,tempch,tempcl,tempdh,tempal,tempbx;
+#endif
+
+ 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;
+ }
+ }
+
+#if 0
+ if(!(ds:489 & 0x08)) {
+#endif
+
+ data &= DACInfoFlag;
+ time = 64;
+ if(data == 0x00) table = SiS_MDA_DAC;
+ if(data == 0x08) table = SiS_CGA_DAC;
+ if(data == 0x10) table = SiS_EGA_DAC;
+ if(data == 0x18) {
+ time = 256;
+ table = SiS_VGA_DAC;
+ }
+ if(time == 256) j = 16;
+ else j = time;
+
+ if( ( (HwDeviceExtension->jChipType == SIS_630) && /* 630/301B LCD */
+ (SiS_Pr->SiS_VBType & (VB_SIS301B | VB_SIS302B)) &&
+ (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ) ||
+ (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) || /* LCDA */
+ (!(SiS_Pr->SiS_SetFlag & ProgrammingCRT2)) ) { /* Programming CRT1 */
+ DACAddr = SiS_Pr->SiS_P3c8;
+ DACData = SiS_Pr->SiS_P3c9;
+ shiftflag = 0;
+ SiS_SetReg3(SiS_Pr->SiS_P3c6,0xFF);
+ } else {
+ shiftflag = 1;
+ DACAddr = SiS_Pr->SiS_Part5Port;
+ DACData = SiS_Pr->SiS_Part5Port + 1;
+ }
+
+ SiS_SetReg3(DACAddr,0x00);
+
+ for(i=0; i<j; i++) {
+ data = table[i];
+ for(k=0; k<3; k++) {
+ data2 = 0;
+ if(data & 0x01) data2 = 0x2A;
+ if(data & 0x02) data2 += 0x15;
+ if(shiftflag) data2 <<= 2;
+ SiS_SetReg3(DACData,data2);
+ data >>= 2;
+ }
+ }
+
+ if(time == 256) {
+ for(i = 16; i < 32; i++) {
+ data = table[i];
+ if(shiftflag) data <<= 2;
+ for(k=0; k<3; k++) SiS_SetReg3(DACData,data);
+ }
+ si = 32;
+ for(m = 0; m < 9; m++) {
+ di = si;
+ bx = si + 4;
+ dl = 0;
+ for(n = 0; n < 3; n++) {
+ for(o = 0; o < 5; o++) {
+ dh = table[si];
+ ah = table[di];
+ al = table[bx];
+ si++;
+ SiS_WriteDAC(SiS_Pr,DACData,shiftflag,dl,ah,al,dh);
+ }
+ si -= 2;
+ for(o = 0; o < 3; o++) {
+ dh = table[bx];
+ ah = table[di];
+ al = table[si];
+ si--;
+ SiS_WriteDAC(SiS_Pr,DACData,shiftflag,dl,ah,al,dh);
+ }
+ dl++;
+ } /* for n < 3 */
+ si += 5;
+ } /* for m < 9 */
+ }
+#if 0
+ } /* ds:489 & 0x08 */
+#endif
+
+#if 0
+ if((!(ds:489 & 0x08)) && (ds:489 & 0x06)) {
+ tempbx = 0;
+ for(i=0; i< 256; i++) {
+ SiS_SetReg3(SiS_Pr->SiS_P3c8-1,tempbx); /* 7f87 */
+ tempah = SiS_GetReg3(SiS_Pr->SiS_P3c8+1); /* 7f83 */
+ tempch = SiS_GetReg3(SiS_Pr->SiS_P3c8+1);
+ tempcl = SiS_GetReg3(SiS_Pr->SiS_P3c8+1);
+ tempdh = tempah;
+ tempal = 0x4d * tempdh; /* 7fb8 */
+ tempbx += tempal;
+ tempal = 0x97 * tempch;
+ tempbx += tempal;
+ tempal = 0x1c * tempcl;
+ tempbx += tempal;
+ if((tempbx & 0x00ff) > 0x80) tempbx += 0x100;
+ tempdh = (tempbx & 0x00ff) >> 8;
+ tempch = tempdh;
+ tempcl = tempdh;
+ SiS_SetReg3(SiS_Pr->SiS_P3c8,(tempbx & 0xff)); /* 7f7c */
+ SiS_SetReg3(SiS_Pr->SiS_P3c8+1,tempdh); /* 7f92 */
+ SiS_SetReg3(SiS_Pr->SiS_P3c8+1,tempch);
+ SiS_SetReg3(SiS_Pr->SiS_P3c8+1,tempcl);
+ }
+ }
+#endif
+}
+
+void
+SiS_WriteDAC(SiS_Private *SiS_Pr, USHORT DACData, USHORT shiftflag,
+ USHORT dl, USHORT ah, USHORT al, USHORT dh)
+{
+ USHORT temp;
+ USHORT 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_SetReg3(DACData,(USHORT)dh);
+ SiS_SetReg3(DACData,(USHORT)bh);
+ SiS_SetReg3(DACData,(USHORT)bl);
+}
+
+static ULONG
+GetDRAMSize(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ ULONG AdapterMemorySize = 0;
+#ifdef SIS315H
+ USHORT counter;
+#endif
+
+#ifdef SIS315H
+ if ((HwDeviceExtension->jChipType == SIS_315H) ||
+ (HwDeviceExtension->jChipType == SIS_315) ||
+ (HwDeviceExtension->jChipType == SIS_315PRO)) {
+
+ counter = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
+ AdapterMemorySize = 1 << ((counter & 0xF0) >> 4);
+ counter >>= 2;
+ counter &= 0x03;
+ if(counter == 0x02) {
+ AdapterMemorySize += (AdapterMemorySize / 2); /* DDR asymetric */
+ } else if(counter != 0) {
+ AdapterMemorySize <<= 1; /* SINGLE_CHANNEL_2_RANK or DUAL_CHANNEL_1_RANK */
+ }
+ AdapterMemorySize *= (1024*1024);
+
+ } else if(HwDeviceExtension->jChipType == SIS_330) {
+
+ counter = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
+ AdapterMemorySize = 1 << ((counter & 0xF0) >> 4);
+ counter &= 0x0c;
+ if(counter != 0) {
+ AdapterMemorySize <<= 1;
+ }
+ AdapterMemorySize *= (1024*1024);
+
+ } else if((HwDeviceExtension->jChipType == SIS_550) ||
+ (HwDeviceExtension->jChipType == SIS_740) ||
+ (HwDeviceExtension->jChipType == SIS_650)) {
+
+ counter = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14) & 0x3F;
+ counter++;
+ AdapterMemorySize = counter * 4;
+ AdapterMemorySize *= (1024*1024);
+ }
+#endif
+
+#ifdef SIS300
+ if ((HwDeviceExtension->jChipType==SIS_300) ||
+ (HwDeviceExtension->jChipType==SIS_540) ||
+ (HwDeviceExtension->jChipType==SIS_630) ||
+ (HwDeviceExtension->jChipType==SIS_730)) {
+
+ AdapterMemorySize = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14) & 0x3F;
+ AdapterMemorySize++;
+ AdapterMemorySize *= (1024*1024);
+
+ }
+#endif
+
+ return AdapterMemorySize;
+}
+
+#ifndef LINUX_XF86
+void
+SiS_ClearBuffer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo)
+{
+ PVOID VideoMemoryAddress = (PVOID)HwDeviceExtension->pjVideoMemoryAddress;
+ ULONG AdapterMemorySize = (ULONG)HwDeviceExtension->ulVideoMemorySize;
+ PUSHORT pBuffer;
+ int i;
+
+ if (SiS_Pr->SiS_ModeType>=ModeEGA) {
+ if(ModeNo > 0x13) {
+ AdapterMemorySize = GetDRAMSize(SiS_Pr, HwDeviceExtension);
+ SiS_SetMemory(VideoMemoryAddress,AdapterMemorySize,0);
+ } else {
+ pBuffer = VideoMemoryAddress;
+ for(i=0; i<0x4000; i++)
+ pBuffer[i] = 0x0000;
+ }
+ } else {
+ pBuffer = VideoMemoryAddress;
+ if (SiS_Pr->SiS_ModeType < ModeCGA) {
+ for(i=0; i<0x4000; i++)
+ pBuffer[i] = 0x0720;
+ } else {
+ SiS_SetMemory(VideoMemoryAddress,0x8000,0);
+ }
+ }
+}
+#endif
+
+void
+SiS_DisplayOn(SiS_Private *SiS_Pr)
+{
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x01,0xDF,0x00);
+}
+
+void
+SiS_DisplayOff(SiS_Private *SiS_Pr)
+{
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x01,0xDF,0x20);
+}
+
+
+/* ========================================== */
+/* SR CRTC GR */
+void
+SiS_SetReg1(USHORT port, USHORT index, USHORT data)
+{
+ OutPortByte(port,index);
+ OutPortByte(port+1,data);
+}
+
+/* ========================================== */
+/* AR(3C0) */
+void
+SiS_SetReg2(SiS_Private *SiS_Pr, USHORT port, USHORT index, USHORT data)
+{
+ InPortByte(port+0x3da-0x3c0);
+ OutPortByte(SiS_Pr->SiS_P3c0,index);
+ OutPortByte(SiS_Pr->SiS_P3c0,data);
+ OutPortByte(SiS_Pr->SiS_P3c0,0x20);
+}
+
+void
+SiS_SetReg3(USHORT port, USHORT data)
+{
+ OutPortByte(port,data);
+}
+
+void
+SiS_SetReg4(USHORT port, ULONG data)
+{
+ OutPortLong(port,data);
+}
+
+void
+SiS_SetReg5(USHORT port, USHORT data)
+{
+ OutPortWord(port,data);
+}
+
+UCHAR SiS_GetReg1(USHORT port, USHORT index)
+{
+ UCHAR data;
+
+ OutPortByte(port,index);
+ data = InPortByte(port+1);
+
+ return(data);
+}
+
+UCHAR
+SiS_GetReg2(USHORT port)
+{
+ UCHAR data;
+
+ data= InPortByte(port);
+
+ return(data);
+}
+
+ULONG
+SiS_GetReg3(USHORT port)
+{
+ ULONG data;
+
+ data = InPortLong(port);
+
+ return(data);
+}
+
+USHORT
+SiS_GetReg4(USHORT port)
+{
+ ULONG data;
+
+ data = InPortWord(port);
+
+ return(data);
+}
+
+void
+SiS_ClearDAC(SiS_Private *SiS_Pr, ULONG port)
+{
+ int i;
+
+ OutPortByte(port, 0);
+ port++;
+ for (i=0; i < (256 * 3); i++) {
+ OutPortByte(port, 0);
+ }
+
+}
+
+#if 0 /* TW: Unused */
+void
+SiS_SetInterlace(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT RefreshRateTableIndex)
+{
+ ULONG Temp;
+ USHORT data,Temp2;
+
+ if (ModeNo<=0x13) return;
+
+ Temp = (ULONG)SiS_GetReg1(SiS_Pr->SiS_P3d4,0x01);
+ Temp++;
+ Temp <<= 3;
+
+ if(Temp == 1024) data = 0x0035;
+ else if(Temp == 1280) data = 0x0048;
+ else data = 0x0000;
+
+ Temp2 = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+ Temp2 &= InterlaceMode;
+ if(Temp2 == 0) data=0x0000;
+
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x19,data);
+
+ Temp = (ULONG)SiS_GetReg1(SiS_Pr->SiS_P3d4,0x1A);
+ Temp = (USHORT)(Temp & 0xFC);
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x1A,(USHORT)Temp);
+
+ Temp = (ULONG)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x0f);
+ Temp2 = (USHORT)Temp & 0xBF;
+ if(ModeNo==0x37) Temp2 |= 0x40;
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x1A,(USHORT)Temp2);
+}
+#endif
+
+/* TW: Checked against 330, 650/LVDS (1.10.07), 650/301LVx (1.10.6s) and 315 BIOS */
+#ifdef SIS315H
+void
+SiS_SetCRT1FIFO_310(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ USHORT modeflag;
+
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x3D,0xFE); /* disable auto-threshold */
+
+ if(ModeNo > 0x13) {
+ if(SiS_Pr->UseCustomMode) {
+ modeflag = SiS_Pr->CModeFlag;
+ } else {
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ }
+ if( (!(modeflag & DoubleScanMode)) || (!(modeflag & HalfDCLK))) {
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x08,0x34);
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x09,0xF0);
+ SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x3D,0x01);
+ } else {
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x08,0xAE);
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x09,0xF0);
+ }
+ } else {
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x08,0xAE);
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x09,0xF0);
+ }
+}
+#endif
+
+#ifdef SIS300
+void
+SiS_SetCRT1FIFO_300(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+ USHORT RefreshRateTableIndex)
+{
+ USHORT ThresholdLow = 0;
+ USHORT index, VCLK, MCLK, colorth=0;
+ USHORT tempah, temp;
+
+ 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_GetReg1(SiS_Pr->SiS_P3c4,0x3A);
+ index &= 0x07;
+ MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK; /* Get MCLK */
+
+ tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x35);
+ tempah &= 0xc3;
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x16,0x3c,tempah);
+
+ do {
+ ThresholdLow = SiS_CalcDelay(SiS_Pr, ROMAddr, VCLK, colorth, MCLK);
+ ThresholdLow++;
+ if(ThresholdLow < 0x13) break;
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x16,0xfc);
+ ThresholdLow = 0x13;
+ tempah = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16);
+ tempah >>= 6;
+ if(!(tempah)) break;
+ tempah--;
+ tempah <<= 6;
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x16,0x3f,tempah);
+ } while(0);
+
+ } else ThresholdLow = 2;
+
+ /* Write CRT/CPU threshold low, CRT/Engine threshold high */
+ temp = (ThresholdLow << 4) | 0x0f;
+ SiS_SetReg1(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_SetReg1(SiS_Pr->SiS_P3c4,0x3B,0x09);
+
+ /* Write CRT/CPU threshold high */
+ temp = ThresholdLow + 3;
+ if(temp > 0x0f) temp = 0x0f;
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x09,temp);
+}
+
+USHORT
+SiS_CalcDelay(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT VCLK, USHORT colordepth, USHORT MCLK)
+{
+ 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);
+}
+
+USHORT
+SiS_DoCalcDelay(SiS_Private *SiS_Pr, USHORT MCLK, USHORT VCLK, USHORT colordepth, USHORT key)
+{
+ const UCHAR ThLowA[] = { 61, 3,52, 5,68, 7,100,11,
+ 43, 3,42, 5,54, 7, 78,11,
+ 34, 3,37, 5,47, 7, 67,11 };
+
+ 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_GetReg1(SiS_Pr->SiS_P3c4,0x18);
+ tempah &= 0x62;
+ tempah >>= 1;
+ tempal = tempah;
+ tempah >>= 3;
+ tempal |= tempah;
+ tempal &= 0x07;
+ tempcl = ThTiming[tempal];
+ tempbx = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16);
+ tempbx >>= 6;
+ tempah = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
+ tempah >>= 4;
+ tempah &= 0x0c;
+ tempbx |= tempah;
+ tempbx <<= 1;
+ if(key == 0) {
+ tempal = ThLowA[tempbx + 1];
+ tempal *= tempcl;
+ tempal += ThLowA[tempbx];
+ } else {
+ tempal = ThLowB[tempbx + 1];
+ tempal *= tempcl;
+ tempal += ThLowB[tempbx];
+ }
+ longtemp = tempal * VCLK * colordepth;
+ temp = longtemp % (MCLK * 16);
+ longtemp /= (MCLK * 16);
+ if(temp) longtemp++;
+ return((USHORT)longtemp);
+}
+
+#if 0 /* TW: Old fragment, unused */
+USHORT
+SiS_CalcDelay(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT key)
+{
+ USHORT data,data2,temp0,temp1;
+ UCHAR ThLowA[]= {61,3,52,5,68,7,100,11,
+ 43,3,42,5,54,7, 78,11,
+ 34,3,37,5,47,7, 67,11};
+
+ UCHAR ThLowB[]= {81,4,72,6,88,8,120,12,
+ 55,4,54,6,66,8, 90,12,
+ 42,4,45,6,55,8, 75,12};
+
+ UCHAR ThTiming[]= {1,2,2,3,0,1,1,2};
+
+ data=SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16);
+ data=data>>6;
+ data2=SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
+ data2=(data2>>4)&0x0C;
+ data=data|data2;
+ data=data<1;
+ if(key==0) {
+ temp0=(USHORT)ThLowA[data];
+ temp1=(USHORT)ThLowA[data+1];
+ } else {
+ temp0=(USHORT)ThLowB[data];
+ temp1=(USHORT)ThLowB[data+1];
+ }
+
+ data2=0;
+ data=SiS_GetReg1(SiS_Pr->SiS_P3c4,0x18);
+ if(data&0x02) data2=data2|0x01;
+ if(data&0x20) data2=data2|0x02;
+ if(data&0x40) data2=data2|0x04;
+
+ data=temp1*ThTiming[data2]+temp0;
+ return(data);
+}
+#endif
+
+void
+SiS_SetCRT1FIFO_630(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension,
+ USHORT RefreshRateTableIndex)
+{
+ USHORT i,index,data,VCLK,MCLK,colorth=0;
+ ULONG B,eax,bl,data2;
+ USHORT ThresholdLow=0;
+ UCHAR FQBQData[]= {
+ 0x01,0x21,0x41,0x61,0x81,
+ 0x31,0x51,0x71,0x91,0xb1,
+ 0x00,0x20,0x40,0x60,0x80,
+ 0x30,0x50,0x70,0x90,0xb0,
+ 0xFF
+ };
+ UCHAR FQBQData730[]= {
+ 0x34,0x74,0xb4,
+ 0x23,0x63,0xa3,
+ 0x12,0x52,0x92,
+ 0x01,0x41,0x81,
+ 0x00,0x40,0x80,
+ 0xff
+ };
+
+ 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_GetReg1(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(HwDeviceExtension->jChipType == SIS_730) {
+
+ do {
+ B = SiS_CalcDelay2(SiS_Pr, ROMAddr, FQBQData730[i], HwDeviceExtension) * VCLK * colorth;
+ bl = B / (MCLK * 16);
+
+ if(B == bl * 16 * MCLK) {
+ bl = bl + 1;
+ } else {
+ bl = bl + 2;
+ }
+
+ if(bl > 0x13) {
+ if(FQBQData730[i+1] == 0xFF) {
+ ThresholdLow = 0x13;
+ break;
+ }
+ i++;
+ } else {
+ ThresholdLow = bl;
+ break;
+ }
+ } while(FQBQData730[i] != 0xFF);
+
+ } else {
+
+ do {
+ B = SiS_CalcDelay2(SiS_Pr, ROMAddr, FQBQData[i], HwDeviceExtension) * VCLK * colorth;
+ bl = B / (MCLK * 16);
+
+ if(B == bl * 16 * MCLK) {
+ bl = bl + 1;
+ } else {
+ bl = bl + 2;
+ }
+
+ if(bl > 0x13) {
+ if(FQBQData[i+1] == 0xFF) {
+ ThresholdLow = 0x13;
+ break;
+ }
+ i++;
+ } else {
+ ThresholdLow = bl;
+ break;
+ }
+ } while(FQBQData[i] != 0xFF);
+ }
+ }
+ else {
+ if(HwDeviceExtension->jChipType == SIS_730) {
+ } else {
+ i = 9;
+ }
+ ThresholdLow = 0x02;
+ }
+
+ /* Write foreground and background queue */
+ if(HwDeviceExtension->jChipType == SIS_730) {
+
+ data2 = FQBQData730[i];
+ data2 = (data2 & 0xC0) >> 5;
+ data2 <<= 8;
+
+#ifndef LINUX_XF86
+ SiS_SetReg4(0xcf8,0x80000050);
+ eax = SiS_GetReg3(0xcfc);
+ eax &= 0xfffff9ff;
+ eax |= data2;
+ SiS_SetReg4(0xcfc,eax);
+#else
+ /* We use pci functions X offers. We use pcitag 0, because
+ * we want to read/write to the host bridge (which is always
+ * 00:00.0 on 630, 730 and 540), not the VGA device.
+ */
+ eax = pciReadLong(0x00000000, 0x50);
+ eax &= 0xfffff9ff;
+ eax |= data2;
+ pciWriteLong(0x00000000, 0x50, eax);
+#endif
+
+ /* Write GUI grant timer (PCI config 0xA3) */
+ data2 = FQBQData730[i] << 8;
+ data2 = (data2 & 0x0f00) | ((data2 & 0x3000) >> 8);
+ data2 <<= 20;
+
+#ifndef LINUX_XF86
+ SiS_SetReg4(0xcf8,0x800000A0);
+ eax = SiS_GetReg3(0xcfc);
+ eax &= 0x00ffffff;
+ eax |= data2;
+ SiS_SetReg4(0xcfc,eax);
+#else
+ eax = pciReadLong(0x00000000, 0xA0);
+ eax &= 0x00ffffff;
+ eax |= data2;
+ pciWriteLong(0x00000000, 0xA0, eax);
+#endif
+
+ } else {
+
+ data2 = FQBQData[i];
+ data2 = (data2 & 0xf0) >> 4;
+ data2 <<= 24;
+
+#ifndef LINUX_XF86
+ SiS_SetReg4(0xcf8,0x80000050);
+ eax = SiS_GetReg3(0xcfc);
+ eax &= 0xf0ffffff;
+ eax |= data2;
+ SiS_SetReg4(0xcfc,eax);
+#else
+ eax = pciReadLong(0x00000000, 0x50);
+ eax &= 0xf0ffffff;
+ eax |= data2;
+ pciWriteLong(0x00000000, 0x50, eax);
+#endif
+
+ /* Write GUI grant timer (PCI config 0xA3) */
+ data2 = FQBQData[i];
+ data2 &= 0x0f;
+ data2 <<= 24;
+
+#ifndef LINUX_XF86
+ SiS_SetReg4(0xcf8,0x800000A0);
+ eax = SiS_GetReg3(0xcfc);
+ eax &= 0xf0ffffff;
+ eax |= data2;
+ SiS_SetReg4(0xcfc,eax);
+#else
+ eax = pciReadLong(0x00000000, 0xA0);
+ eax &= 0xf0ffffff;
+ eax |= data2;
+ pciWriteLong(0x00000000, 0xA0, eax);
+#endif
+
+ }
+
+ /* Write CRT/CPU threshold low, CRT/Engine threshold high */
+ data = ((ThresholdLow & 0x0f) << 4) | 0x0f;
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x08,data);
+
+ data = (ThresholdLow & 0x10) << 1;
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xDF,data);
+
+ /* What is this? */
+ SiS_SetReg1(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);
+}
+
+USHORT
+SiS_CalcDelay2(SiS_Private *SiS_Pr, UCHAR *ROMAddr,UCHAR key, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ USHORT data,index;
+ const UCHAR LatencyFactor[] = {
+ 97, 88, 86, 79, 77, 00, /*; 64 bit BQ=2 */
+ 00, 87, 85, 78, 76, 54, /*; 64 bit BQ=1 */
+ 97, 88, 86, 79, 77, 00, /*; 128 bit BQ=2 */
+ 00, 79, 77, 70, 68, 48, /*; 128 bit BQ=1 */
+ 80, 72, 69, 63, 61, 00, /*; 64 bit BQ=2 */
+ 00, 70, 68, 61, 59, 37, /*; 64 bit BQ=1 */
+ 86, 77, 75, 68, 66, 00, /*; 128 bit BQ=2 */
+ 00, 68, 66, 59, 57, 37 /*; 128 bit BQ=1 */
+ };
+ const UCHAR LatencyFactor730[] = {
+ 69, 63, 61,
+ 86, 79, 77,
+ 103, 96, 94,
+ 120,113,111,
+ 137,130,128, /* --- Table ends with this entry, data below */
+ 137,130,128, /* to avoid using illegal values */
+ 137,130,128,
+ 137,130,128,
+ 137,130,128,
+ 137,130,128,
+ 137,130,128,
+ 137,130,128,
+ 137,130,128,
+ 137,130,128,
+ 137,130,128,
+ 137,130,128,
+ };
+
+ if(HwDeviceExtension->jChipType == SIS_730) {
+ index = ((key & 0x0f) * 3) + ((key & 0xC0) >> 6);
+ data = LatencyFactor730[index];
+ } else {
+ index = (key & 0xE0) >> 5;
+ if(key & 0x10) index +=6;
+ if(!(key & 0x01)) index += 24;
+ data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
+ if(data & 0x0080) index += 12;
+ data = LatencyFactor[index];
+ }
+ return(data);
+}
+#endif
+
+/* =============== Autodetection ================ */
+/* I N C O M P L E T E */
+
+BOOLEAN
+SiS_GetPanelID(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ 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, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+ };
+ const USHORT PanelTypeTable310LVDS[16] = {
+ 0xc111, 0xc122, 0xc133, 0xc144, 0xc155, 0xc166, 0xc177, 0xc188,
+ 0xc199, 0xc0aa, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+ };
+ USHORT tempax,tempbx,tempah,temp;
+
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+
+ tempax = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x18);
+ tempbx = tempax & 0x0F;
+ if(!(tempax & 0x10)){
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1){
+ tempbx = 0;
+ temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x38);
+ if(temp & 0x40) tempbx |= 0x08;
+ if(temp & 0x20) tempbx |= 0x02;
+ if(temp & 0x01) tempbx |= 0x01;
+ temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x39);
+ if(temp & 0x80) tempbx |= 0x04;
+ } else {
+ return 0;
+ }
+ }
+ tempbx = PanelTypeTable300[tempbx];
+ tempbx |= LCDSync;
+ temp = tempbx & 0x00FF;
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x36,temp);
+ temp = (tempbx & 0xFF00) >> 8;
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x37,~(LCDSyncBit|LCDRGB18Bit),temp);
+
+ } else {
+
+ tempax = tempah = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1a);
+ tempax &= 0x1e;
+ tempax >>= 1;
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+ if(tempax == 0) {
+ /* TODO: Include HUGE detection routine
+ (Probably not worth bothering)
+ */
+ return 0;
+ }
+ temp = tempax & 0xff;
+ tempax--;
+ tempbx = PanelTypeTable310LVDS[tempax];
+ } else {
+ tempbx = PanelTypeTable31030x[tempax];
+ temp = tempbx & 0xff;
+ }
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x36,temp);
+ tempbx = (tempbx & 0xff00) >> 8;
+ temp = tempbx & 0xc1;
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x37,~(LCDSyncBit|LCDRGB18Bit),temp);
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+ temp = tempbx & 0x04;
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x39,0xfb,temp);
+ }
+
+ }
+ return 1;
+}
+
+
+#ifdef LINUXBIOS
+
+void
+SiS_DetectMonitor(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
+{
+ UCHAR DAC_TEST_PARMS[] = {0x0F,0x0F,0x0F};
+ UCHAR DAC_CLR_PARMS[] = {0x00,0x00,0x00};
+ USHORT SR1F;
+
+ SR1F = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1F); /* backup DAC pedestal */
+ SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1F,0x04);
+
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+ if(!(SiS_BridgeIsOn(SiS_Pr, BaseAddr))) {
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x30,0x41);
+ }
+ }
+
+ SiSSetMode(SiS_Pr,HwDeviceExtension,0x2E);
+ if(HwDeviceExtension->jChipType >= SIS_650) {
+ /* TW: On 650 only - enable CRT1 */
+ SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x63,0xbf);
+ }
+ SiS_SetReg3(SiS_Pr->SiS_P3c6,0xff);
+ SiS_ClearDAC(SiS_Pr, SiS_Pr->SiS_P3c8);
+ SiS_LongWait(SiS_Pr);
+ SiS_LongWait(SiS_Pr);
+ SiS_LongWait(SiS_Pr);
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x32,0xDF,0x00);
+ if(SiS_TestMonitorType(SiS_Pr, DAC_TEST_PARMS[0],DAC_TEST_PARMS[1],DAC_TEST_PARMS[2])) {
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x32,0xDF,0x20);
+ } else if(SiS_TestMonitorType(SiS_Pr, DAC_TEST_PARMS[0],DAC_TEST_PARMS[1],DAC_TEST_PARMS[2])) {
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x32,0xDF,0x20);
+ }
+ SiS_TestMonitorType(SiS_Pr, DAC_CLR_PARMS[0],DAC_CLR_PARMS[1],DAC_CLR_PARMS[2]);
+
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1F,SR1F);
+}
+
+USHORT
+SiS_TestMonitorType(SiS_Private *SiS_Pr, UCHAR R_DAC,UCHAR G_DAC,UCHAR B_DAC)
+{
+ USHORT temp,tempbx;
+
+ tempbx = R_DAC * 0x4d + G_DAC * 0x97 + B_DAC * 0x1c;
+ if((tempbx & 0x00ff) > 0x80) tempbx += 0x100;
+ tempbx = (tempbx & 0xFF00) >> 8;
+ R_DAC = (UCHAR) tempbx;
+ G_DAC = (UCHAR) tempbx;
+ B_DAC = (UCHAR) tempbx;
+
+ SiS_SetReg3(SiS_Pr->SiS_P3c8,0x00);
+ SiS_SetReg3(SiS_Pr->SiS_P3c9,R_DAC);
+ SiS_SetReg3(SiS_Pr->SiS_P3c9,G_DAC);
+ SiS_SetReg3(SiS_Pr->SiS_P3c9,B_DAC);
+ SiS_LongWait(SiS_Pr);
+ temp=SiS_GetReg2(SiS_Pr->SiS_P3c2);
+ if(temp & 0x10) return(1);
+ else return(0);
+}
+
+void
+SiS_GetSenseStatus(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,UCHAR *ROMAddr)
+{
+ USHORT tempax=0,tempbx,tempcx,temp;
+ USHORT P2reg0=0,SenseModeNo=0,OutputSelect=*SiS_Pr->pSiS_OutputSelect;
+ USHORT ModeIdIndex,i;
+ USHORT BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
+
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1){
+ SiS_GetPanelID(SiS_Pr);
+ temp=LCDSense;
+ temp=temp|SiS_SenseCHTV(SiS_Pr);
+ tempbx=~(LCDSense|AVIDEOSense|SVIDEOSense);
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x32,tempbx,temp);
+ } else { /* for 301 */
+ if(SiS_Pr->SiS_IF_DEF_HiVision==1) { /* for HiVision */
+ tempax=SiS_GetReg1(SiS_Pr->SiS_P3c4,0x38);
+ temp=tempax&0x01;
+ tempax=SiS_GetReg1(SiS_Pr->SiS_P3c4,0x3A);
+ temp=temp|(tempax&0x02);
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x32,0xA0,temp);
+ } else {
+ if(SiS_BridgeIsOn(SiS_Pr, BaseAddr)==0) { /* TW: Inserted "==0" */
+ P2reg0 = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x00);
+ if(!(SiS_BridgeIsEnable(SiS_Pr, BaseAddr,HwDeviceExtension))) {
+ SenseModeNo=0x2e;
+ temp = SiS_SearchModeID(SiS_Pr, ROMAddr,&SenseModeNo,&ModeIdIndex);
+ SiS_Pr->SiS_SetFlag = 0x00;
+ SiS_Pr->SiS_ModeType = ModeVGA;
+ SiS_Pr->SiS_VBInfo = SetCRT2ToRAMDAC |LoadDACFlag |SetInSlaveMode;
+ SiS_SetCRT2Group301(SiS_Pr, BaseAddr,ROMAddr,SenseModeNo,HwDeviceExtension);
+ for(i=0;i<20;i++) {
+ SiS_LongWait(SiS_Pr);
+ }
+ }
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x00,0x1c);
+ tempax=0;
+ tempbx=*SiS_Pr->pSiS_RGBSenseData;
+ if(SiS_Is301B(SiS_Pr, BaseAddr)){
+ tempbx=*SiS_Pr->pSiS_RGBSenseData2;
+ }
+ tempcx=0x0E08;
+ if(SiS_Sense(SiS_Pr, tempbx,tempcx)){
+ if(SiS_Sense(SiS_Pr, tempbx,tempcx)){
+ tempax=tempax|Monitor2Sense;
+ }
+ }
+ tempbx=*SiS_Pr->pSiS_YCSenseData;
+ if(SiS_Is301B(SiS_Pr, BaseAddr)){
+ tempbx=*SiS_Pr->pSiS_YCSenseData2;
+ }
+ tempcx=0x0604;
+ if(SiS_Sense(SiS_Pr, tempbx,tempcx)){
+ if(SiS_Sense(SiS_Pr,tempbx,tempcx)){
+ tempax=tempax|SVIDEOSense;
+ }
+ }
+
+ if(ROMAddr && SiS_Pr->SiS_UseROM) {
+#ifdef SIS300
+ if((HwDeviceExtension->jChipType==SIS_630)||
+ (HwDeviceExtension->jChipType==SIS_730)) {
+ OutputSelect = ROMAddr[0xfe];
+ }
+#endif
+#ifdef SIS315H
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ OutputSelect = ROMAddr[0xf3];
+ if(HwDeviceExtension->jChipType == SIS_330) {
+ OutputSelect = ROMAddr[0x11b];
+ }
+ }
+#endif
+ }
+ if(OutputSelect & BoardTVType){
+ tempbx = *SiS_Pr->pSiS_VideoSenseData;
+ if(SiS_Is301B(SiS_Pr, BaseAddr)){
+ tempbx = *SiS_Pr->pSiS_VideoSenseData2;
+ }
+ tempcx = 0x0804;
+ if(SiS_Sense(SiS_Pr, tempbx,tempcx)){
+ if(SiS_Sense(SiS_Pr, tempbx,tempcx)){
+ tempax |= AVIDEOSense;
+ }
+ }
+ } else {
+ if(!(tempax & SVIDEOSense)){
+ tempbx = *SiS_Pr->pSiS_VideoSenseData;
+ if(SiS_Is301B(SiS_Pr, BaseAddr)){
+ tempbx = *SiS_Pr->pSiS_VideoSenseData2;
+ }
+ tempcx = 0x0804;
+ if(SiS_Sense(SiS_Pr,tempbx,tempcx)){
+ if(SiS_Sense(SiS_Pr, tempbx,tempcx)){
+ tempax |= AVIDEOSense;
+ }
+ }
+ }
+ }
+ }
+
+ if(SiS_SenseLCD(SiS_Pr, HwDeviceExtension)){
+ tempax |= LCDSense;
+ }
+
+ tempbx=0;
+ tempcx=0;
+ SiS_Sense(SiS_Pr, tempbx,tempcx);
+
+ if(SiS_Pr->SiS_VBType & (VB_SIS30xLV|VB_SIS30xNEW)) {
+ tempax &= 0x00ef; /* 301lv to disable CRT2*/
+ }
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x32,~0xDF,tempax);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x00,P2reg0);
+ if(!(P2reg0 & 0x20)) {
+ SiS_Pr->SiS_VBInfo = DisableCRT2Display;
+ SiS_SetCRT2Group301(SiS_Pr,BaseAddr,ROMAddr,SenseModeNo,HwDeviceExtension);
+ }
+ }
+ }
+}
+
+BOOLEAN
+SiS_Sense(SiS_Private *SiS_Pr, USHORT tempbx,USHORT tempcx)
+{
+ USHORT temp,i,tempch;
+
+ temp = tempbx & 0xFF;
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x11,temp);
+ temp = (tempbx & 0xFF00) >> 8;
+ temp |= (tempcx & 0x00FF);
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,~0x1F,temp);
+
+ for(i=0; i<10; i++) SiS_LongWait(SiS_Pr);
+
+ tempch = (tempcx & 0x7F00) >> 8;
+ temp = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x03);
+ temp ^= 0x0E;
+ temp &= tempch;
+ if(temp>0) return 1;
+ else return 0;
+}
+
+USHORT
+SiS_SenseLCD(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ USHORT temp;
+
+ temp=SiS_GetPanelID(SiS_Pr);
+ if(!temp) temp=SiS_GetLCDDDCInfo(SiS_Pr, HwDeviceExtension);
+ return(temp);
+}
+
+BOOLEAN
+SiS_GetLCDDDCInfo(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ USHORT temp;
+ /*add lcd sense*/
+ if(HwDeviceExtension->ulCRT2LCDType==LCD_UNKNOWN)
+ return 0;
+ else{
+ temp=(USHORT)HwDeviceExtension->ulCRT2LCDType;
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x36,temp);
+ return 1;
+ }
+}
+
+USHORT
+SiS_SenseCHTV(SiS_Private *SiS_Pr)
+{
+ USHORT temp,push0e,status;
+
+ status=0;
+ push0e = SiS_GetCH700x(SiS_Pr, 0x0e);
+ push0e = (push0e << 8) | 0x0e;
+ SiS_SetCH700x(SiS_Pr, 0x0b0e);
+ SiS_SetCH700x(SiS_Pr, 0x0110);
+ SiS_SetCH700x(SiS_Pr, 0x0010);
+ temp = SiS_GetCH700x(SiS_Pr, 0x10);
+ if(temp & 0x08) status |= SVIDEOSense;
+ if(temp & 0x02) status |= AVIDEOSense;
+ SiS_SetCH700x(SiS_Pr, push0e);
+ return(status);
+}
+#endif /* LINUXBIOS */
+
+/* ================ for TC only ================= */
+
+#ifdef TC
+
+int
+INT1AReturnCode(union REGS regs)
+{
+ if (regs.x.cflag)
+ {
+ /*printf("Error to find pci device!\n"); */
+ return 1;
+ }
+
+ switch(regs.h.ah)
+ {
+ case 0: return 0;
+ break;
+ case 0x81: printf("Function not support\n");
+ break;
+ case 0x83: printf("bad vendor id\n");
+ break;
+ case 0x86: printf("device not found\n");
+ break;
+ case 0x87: printf("bad register number\n");
+ break;
+ case 0x88: printf("set failed\n");
+ break;
+ case 0x89: printf("buffer too small");
+ break;
+ }
+ return 1;
+}
+
+unsigned
+FindPCIIOBase(unsigned index,unsigned deviceid)
+{
+ union REGS regs;
+
+ regs.h.ah = 0xb1; /*PCI_FUNCTION_ID */
+ regs.h.al = 0x02; /*FIND_PCI_DEVICE */
+ regs.x.cx = deviceid;
+ regs.x.dx = 0x1039;
+ regs.x.si = index; /* find n-th device */
+
+ int86(0x1A, &regs, &regs);
+
+ if (INT1AReturnCode(regs)!=0)
+ return 0;
+
+ /* regs.h.bh *//* bus number */
+ /* regs.h.bl *//* device number */
+ regs.h.ah = 0xb1; /*PCI_FUNCTION_ID */
+ regs.h.al = 0x09; /*READ_CONFIG_WORD */
+ regs.x.cx = deviceid;
+ regs.x.dx = 0x1039;
+ regs.x.di = 0x18; /* register number */
+ int86(0x1A, &regs, &regs);
+
+ if (INT1AReturnCode(regs)!=0)
+ return 0;
+ return regs.x.cx;
+}
+
+
+void
+main(int argc, char *argv[])
+{
+ SIS_HW_DEVICE_INFO HwDeviceExtension;
+ USHORT temp;
+ USHORT ModeNo;
+
+ /*HwDeviceExtension.pjVirtualRomBase =(PUCHAR) MK_FP(0xC000,0); */
+ /*HwDeviceExtension.pjVideoMemoryAddress = (PUCHAR)MK_FP(0xA000,0);*/
+
+#ifdef SIS300
+ HwDeviceExtension.ulIOAddress = (FindPCIIOBase(0,0x6300)&0xFF80) + 0x30;
+ HwDeviceExtension.jChipType = SIS_630;
+#endif
+
+#ifdef SIS315H
+// HwDeviceExtension.ulIOAddress = (FindPCIIOBase(0,0x5315)&0xFF80) + 0x30;
+// HwDeviceExtension.jChipType = SIS_550;
+ HwDeviceExtension.ulIOAddress = (FindPCIIOBase(0,0x325)&0xFF80) + 0x30;
+ HwDeviceExtension.jChipType = SIS_315H;
+#endif
+
+ HwDeviceExtension.ujVBChipID = VB_CHIP_301;
+ strcpy(HwDeviceExtension.szVBIOSVer,"0.84");
+ HwDeviceExtension.bSkipDramSizing = FALSE;
+ HwDeviceExtension.ulVideoMemorySize = 0;
+ if(argc==2) {
+ ModeNo=atoi(argv[1]);
+ }
+ else {
+ ModeNo=0x2e;
+ /*ModeNo=0x37; */ /* 1024x768x 4bpp */
+ /*ModeNo=0x38; *//* 1024x768x 8bpp */
+ /*ModeNo=0x4A; *//* 1024x768x 16bpp */
+ /*ModeNo=0x47;*/ /* 800x600x 16bpp */
+ }
+ /* SiSInit(SiS_Pr, &HwDeviceExtension);*/
+ SiSSetMode(SiS_Pr, &HwDeviceExtension, ModeNo);
+}
+#endif /* TC END */
+
+/* ================ LINUX XFREE86 ====================== */
+
+/* Helper functions */
+
+#ifdef LINUX_XF86
+USHORT
+SiS_CalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ UShort i = (pSiS->CurrentLayout.bitsPerPixel+7)/8 - 1;
+ UShort ModeIndex = 0;
+
+ if((pSiS->HaveCustomModes) && (!(mode->type & M_T_DEFAULT)))
+ return 0xfe;
+
+ switch(mode->HDisplay)
+ {
+ case 320:
+ if(mode->VDisplay == 480) {
+ ModeIndex = ModeIndex_320x480[i];
+ }
+ break;
+ case 512:
+ if(mode->VDisplay == 384) {
+ ModeIndex = ModeIndex_512x384[i];
+ }
+ break;
+ case 640:
+ if(mode->VDisplay == 480) {
+ ModeIndex = ModeIndex_640x480[i];
+ } else if(mode->VDisplay == 400) {
+ ModeIndex = ModeIndex_640x400[i];
+ }
+ break;
+ case 720:
+ if(mode->VDisplay == 480) {
+ ModeIndex = ModeIndex_720x480[i];
+ } else if(mode->VDisplay == 576) {
+ ModeIndex = ModeIndex_720x576[i];
+ }
+ break;
+ case 800:
+ if(mode->VDisplay == 600) {
+ ModeIndex = ModeIndex_800x600[i];
+ } else if(mode->VDisplay == 480) {
+ ModeIndex = ModeIndex_800x480[i];
+ }
+ break;
+ case 848:
+ if(mode->VDisplay == 480) {
+ ModeIndex = ModeIndex_848x480[i];
+ }
+ break;
+ case 856:
+ if(mode->VDisplay == 480) {
+ ModeIndex = ModeIndex_856x480[i];
+ }
+ break;
+ case 1024:
+ if(mode->VDisplay == 768) {
+ ModeIndex = ModeIndex_1024x768[i];
+ } else if(mode->VDisplay == 576) {
+ ModeIndex = ModeIndex_1024x576[i];
+ } else if(pSiS->VGAEngine == SIS_300_VGA) {
+ if(mode->VDisplay == 600) {
+ ModeIndex = ModeIndex_1024x600[i];
+ }
+ }
+ break;
+ case 1152:
+ if(mode->VDisplay == 864) {
+ ModeIndex = ModeIndex_1152x864[i];
+ } else if(pSiS->VGAEngine == SIS_300_VGA) {
+ if(mode->VDisplay == 768) {
+ ModeIndex = ModeIndex_1152x768[i];
+ }
+ }
+ break;
+ case 1280:
+ if(mode->VDisplay == 960) {
+ if(pSiS->VGAEngine == SIS_300_VGA) {
+ ModeIndex = ModeIndex_300_1280x960[i];
+ } else {
+ ModeIndex = ModeIndex_310_1280x960[i];
+ }
+ } else if (mode->VDisplay == 1024) {
+ ModeIndex = ModeIndex_1280x1024[i];
+ } else if (mode->VDisplay == 720) {
+ ModeIndex = ModeIndex_1280x720[i];
+ } else if(pSiS->VGAEngine == SIS_315_VGA) {
+ if (mode->VDisplay == 768) {
+ ModeIndex = ModeIndex_1280x768[i];
+ }
+ }
+ break;
+ case 1360:
+ if(mode->VDisplay == 768) {
+ ModeIndex = ModeIndex_1360x768[i];
+ }
+ break;
+ case 1400:
+ if(pSiS->VGAEngine == SIS_315_VGA) {
+ if(mode->VDisplay == 1050) {
+ ModeIndex = ModeIndex_1400x1050[i];
+ }
+ }
+ break;
+ case 1600:
+ if(mode->VDisplay == 1200) {
+ ModeIndex = ModeIndex_1600x1200[i];
+ }
+ break;
+ case 1920:
+ if(mode->VDisplay == 1440) {
+ ModeIndex = ModeIndex_1920x1440[i];
+ }
+ break;
+ case 2048:
+ if(mode->VDisplay == 1536) {
+ if(pSiS->VGAEngine == SIS_300_VGA) {
+ ModeIndex = ModeIndex_300_2048x1536[i];
+ } else {
+ ModeIndex = ModeIndex_310_2048x1536[i];
+ }
+ }
+ break;
+ }
+
+ return(ModeIndex);
+}
+
+USHORT
+SiS_CheckCalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode, int VBFlags)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ UShort i = (pSiS->CurrentLayout.bitsPerPixel+7)/8 - 1;
+ UShort ModeIndex = 0;
+
+ if(VBFlags & CRT2_LCD) {
+
+ if( (mode->HDisplay <= pSiS->LCDwidth) &&
+ (mode->VDisplay <= pSiS->LCDheight) ) {
+
+ if(VBFlags & VB_LVDS) { /* LCD on LVDS */
+
+ switch(mode->HDisplay)
+ {
+ case 512:
+ if(mode->VDisplay == 384) {
+ if(pSiS->LCDwidth != 1024 || pSiS->LCDheight != 600) { /* not supported on 1024x600 panels */
+ ModeIndex = ModeIndex_512x384[i];
+ }
+ }
+ break;
+ case 640:
+ if(mode->VDisplay == 480) {
+ ModeIndex = ModeIndex_640x480[i];
+ } else if(mode->VDisplay == 400) {
+ ModeIndex = ModeIndex_640x400[i];
+ }
+ break;
+ case 800:
+ if(mode->VDisplay == 600) {
+ ModeIndex = ModeIndex_800x600[i];
+ }
+ break;
+ case 1024:
+ if(mode->VDisplay == 768) {
+ ModeIndex = ModeIndex_1024x768[i];
+ } else if(pSiS->VGAEngine == SIS_300_VGA) {
+ if(mode->VDisplay == 600) {
+ if(pSiS->LCDheight == 600) { /* This mode only supported on 1024x600 panels */
+ ModeIndex = ModeIndex_1024x600[i];
+ }
+ }
+ }
+ break;
+ case 1152:
+ if(pSiS->VGAEngine == SIS_300_VGA) {
+ if(mode->VDisplay == 768) {
+ ModeIndex = ModeIndex_1152x768[i];
+ }
+ }
+ break;
+ case 1280:
+ if(mode->VDisplay == 1024) {
+ ModeIndex = ModeIndex_1280x1024[i];
+ } else if(pSiS->VGAEngine == SIS_315_VGA) {
+ if(mode->VDisplay == 768) {
+ ModeIndex = ModeIndex_1280x768[i];
+ }
+ }
+ break;
+ case 1400:
+ if(mode->VDisplay == 1050) {
+ if(pSiS->VGAEngine == SIS_315_VGA) {
+ ModeIndex = ModeIndex_1400x1050[i];
+ }
+ }
+ break;
+ }
+
+ } else { /* LCD on 301(B) */
+
+ switch(mode->HDisplay)
+ {
+ case 512:
+ if(mode->VDisplay == 384) {
+ ModeIndex = ModeIndex_512x384[i];
+ }
+ break;
+ case 640:
+ if(mode->VDisplay == 480) {
+ ModeIndex = ModeIndex_640x480[i];
+ } else if(mode->VDisplay == 400) {
+ ModeIndex = ModeIndex_640x400[i];
+ }
+ break;
+ case 800:
+ if(mode->VDisplay == 600) {
+ ModeIndex = ModeIndex_800x600[i];
+ }
+ break;
+ case 1024:
+ if(mode->VDisplay == 768) {
+ ModeIndex = ModeIndex_1024x768[i];
+ }
+ break;
+ case 1280:
+ if(mode->VDisplay == 960) {
+ if(pSiS->VGAEngine == SIS_300_VGA) {
+ ModeIndex = ModeIndex_300_1280x960[i];
+ } else {
+ ModeIndex = ModeIndex_310_1280x960[i];
+ }
+ } else if (mode->VDisplay == 1024) {
+ ModeIndex = ModeIndex_1280x1024[i];
+ }
+ break;
+ case 1400:
+ if(mode->VDisplay == 1050) {
+ if(pSiS->VGAEngine == SIS_315_VGA) {
+ ModeIndex = ModeIndex_1400x1050[i];
+ }
+ }
+ break;
+ case 1600:
+ if(mode->VDisplay == 1200) {
+ ModeIndex = ModeIndex_1600x1200[i];
+ }
+ break;
+ }
+
+ }
+
+ }
+
+ } else if(VBFlags & CRT2_TV) {
+
+ if(VBFlags & VB_CHRONTEL) { /* TV on Chrontel */
+
+ switch(mode->HDisplay)
+ {
+ case 512:
+ if(pSiS->VGAEngine == SIS_315_VGA) {
+ if(mode->VDisplay == 384) {
+ ModeIndex = ModeIndex_512x384[i];
+ }
+ }
+ break;
+ case 640:
+ if(mode->VDisplay == 480) {
+ ModeIndex = ModeIndex_640x480[i];
+ } else if(mode->VDisplay == 400) {
+ ModeIndex = ModeIndex_640x400[i];
+ }
+ break;
+ case 800:
+ if(mode->VDisplay == 600) {
+ ModeIndex = ModeIndex_800x600[i];
+ }
+ break;
+ case 1024:
+ if(mode->VDisplay == 768) {
+ if(pSiS->VGAEngine == SIS_315_VGA) {
+ ModeIndex = ModeIndex_1024x768[i];
+ }
+ }
+ break;
+ }
+
+ } else { /* TV on 301(B/LV) */
+
+ switch(mode->HDisplay)
+ {
+ case 512:
+ if(mode->VDisplay == 384) {
+ ModeIndex = ModeIndex_512x384[i];
+ }
+ break;
+ case 640:
+ if(mode->VDisplay == 480) {
+ ModeIndex = ModeIndex_640x480[i];
+ }
+ break;
+ case 720:
+ if(mode->VDisplay == 480) {
+ ModeIndex = ModeIndex_720x480[i];
+ } else if(mode->VDisplay == 576) {
+ ModeIndex = ModeIndex_720x576[i];
+ }
+ break;
+ case 800:
+ if(mode->VDisplay == 600) {
+ ModeIndex = ModeIndex_800x600[i];
+ }
+ break;
+ case 1024: /* Not supported with depth 32 */
+ if((mode->VDisplay == 768) && (i != 3) ) {
+ if(VBFlags & (VB_301B|VB_302B|VB_30xLV|VB_30xLVX)) {
+ ModeIndex = ModeIndex_1024x768[i];
+ }
+ }
+ break;
+ }
+
+ }
+
+ } else if(VBFlags & CRT2_VGA) { /* CRT2 is VGA2 */
+
+ switch(mode->HDisplay)
+ {
+ case 640:
+ if(mode->VDisplay == 480) {
+ ModeIndex = ModeIndex_640x480[i];
+ } else if(mode->VDisplay == 400) {
+ ModeIndex = ModeIndex_640x400[i];
+ }
+ break;
+ case 800:
+ if(mode->VDisplay == 600) {
+ ModeIndex = ModeIndex_800x600[i];
+ } else if(mode->VDisplay == 480) {
+ ModeIndex = ModeIndex_800x480[i];
+ }
+ break;
+ case 848:
+ if(mode->VDisplay == 480) {
+ ModeIndex = ModeIndex_848x480[i];
+ }
+ break;
+ case 856:
+ if(mode->VDisplay == 480) {
+ ModeIndex = ModeIndex_856x480[i];
+ }
+ break;
+ case 1024:
+ if(mode->VDisplay == 768) {
+ ModeIndex = ModeIndex_1024x768[i];
+ } else if(mode->VDisplay == 576) {
+ ModeIndex = ModeIndex_1024x576[i];
+ }
+ break;
+ case 1152:
+ if(mode->VDisplay == 864) {
+ ModeIndex = ModeIndex_1152x864[i];
+ } else if(pSiS->VGAEngine == SIS_300_VGA) {
+ if(mode->VDisplay == 768) {
+ ModeIndex = ModeIndex_1152x768[i];
+ }
+ }
+ break;
+ case 1280:
+ if (mode->VDisplay == 1024) {
+ ModeIndex = ModeIndex_1280x1024[i];
+ } else if (mode->VDisplay == 720) {
+ ModeIndex = ModeIndex_1280x720[i];
+ } else if(pSiS->VGAEngine == SIS_315_VGA) {
+ if (mode->VDisplay == 768) {
+ ModeIndex = ModeIndex_1280x768[i];
+ }
+ }
+ break;
+ }
+
+ } else { /* CRT1 only, no CRT2 */
+
+ ModeIndex = SiS_CalcModeIndex(pScrn, mode);
+
+ }
+
+ return(ModeIndex);
+}
+
+USHORT
+SiS_CheckBuildCustomMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int VBFlags)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int out_n, out_dn, out_div, out_sbit, out_scale;
+ int depth = pSiS->CurrentLayout.bitsPerPixel;
+
+#ifdef SISDUALHEAD
+ if( ((!pSiS->DualHeadMode) && (VBFlags & DISPTYPE_DISP2)) ||
+ ((pSiS->DualHeadMode) && (!pSiS->SecondHead)) ) return 0;
+#else
+ if(VBFlags & DISPTYPE_DISP2) return 0;
+#endif
+
+ pSiS->SiS_Pr->CDClock = mode->Clock;
+
+ pSiS->SiS_Pr->CHDisplay = mode->HDisplay;
+ pSiS->SiS_Pr->CHSyncStart = mode->HSyncStart;
+ pSiS->SiS_Pr->CHSyncEnd = mode->HSyncEnd;
+ pSiS->SiS_Pr->CHTotal = mode->HTotal;
+ pSiS->SiS_Pr->CHBlankStart = pSiS->SiS_Pr->CHDisplay;
+ pSiS->SiS_Pr->CHBlankEnd = pSiS->SiS_Pr->CHTotal;
+
+ pSiS->SiS_Pr->CVDisplay = mode->VDisplay;
+ pSiS->SiS_Pr->CVSyncStart = mode->VSyncStart;
+ pSiS->SiS_Pr->CVSyncEnd = mode->VSyncEnd;
+ pSiS->SiS_Pr->CVTotal = mode->VTotal;
+ pSiS->SiS_Pr->CVBlankStart = pSiS->SiS_Pr->CVSyncStart - 1;
+ pSiS->SiS_Pr->CVBlankEnd = pSiS->SiS_Pr->CVTotal;
+
+ pSiS->SiS_Pr->CFlags = mode->Flags;
+
+ SiS_compute_vclk(pSiS->SiS_Pr->CDClock, &out_n, &out_dn, &out_div, &out_sbit, &out_scale);
+
+#ifdef TWDEBUG
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clock %d: n %d dn %d div %d sb %d sc %d\n",
+ pSiS->SiS_Pr->CDClock, out_n, out_dn, out_div, out_sbit, out_scale);
+#endif
+
+ pSiS->SiS_Pr->CSR2B = (out_div == 2) ? 0x80 : 0x00;
+ pSiS->SiS_Pr->CSR2B |= ((out_n - 1) & 0x7f);
+ pSiS->SiS_Pr->CSR2C = (out_dn - 1) & 0x1f;
+ pSiS->SiS_Pr->CSR2C |= (((out_scale - 1) & 3) << 5);
+ pSiS->SiS_Pr->CSR2C |= ((out_sbit & 0x01) << 7);
+ pSiS->SiS_Pr->CSRClock = (pSiS->SiS_Pr->CDClock / 1000) + 1;
+
+ pSiS->SiS_Pr->CCRT1CRTC[0] = ((pSiS->SiS_Pr->CHTotal >> 3) - 5) & 0xff;
+ pSiS->SiS_Pr->CCRT1CRTC[1] = (pSiS->SiS_Pr->CHDisplay >> 3) - 1;
+ pSiS->SiS_Pr->CCRT1CRTC[2] = (pSiS->SiS_Pr->CHBlankStart >> 3) - 1;
+ pSiS->SiS_Pr->CCRT1CRTC[3] = (((pSiS->SiS_Pr->CHBlankEnd >> 3) - 1) & 0x1F) | 0x80;
+ pSiS->SiS_Pr->CCRT1CRTC[4] = (pSiS->SiS_Pr->CHSyncStart >> 3) + 3;
+ pSiS->SiS_Pr->CCRT1CRTC[5] = ((((pSiS->SiS_Pr->CHBlankEnd >> 3) - 1) & 0x20) << 2) |
+ (((pSiS->SiS_Pr->CHSyncEnd >> 3) + 3) & 0x1F);
+
+ pSiS->SiS_Pr->CCRT1CRTC[6] = (pSiS->SiS_Pr->CVTotal - 2) & 0xFF;
+ pSiS->SiS_Pr->CCRT1CRTC[7] = (((pSiS->SiS_Pr->CVTotal - 2) & 0x100) >> 8)
+ | (((pSiS->SiS_Pr->CVDisplay - 1) & 0x100) >> 7)
+ | ((pSiS->SiS_Pr->CVSyncStart & 0x100) >> 6)
+ | (((pSiS->SiS_Pr->CVBlankStart - 1) & 0x100) >> 5)
+ | 0x10
+ | (((pSiS->SiS_Pr->CVTotal - 2) & 0x200) >> 4)
+ | (((pSiS->SiS_Pr->CVDisplay - 1) & 0x200) >> 3)
+ | ((pSiS->SiS_Pr->CVSyncStart & 0x200) >> 2);
+
+ pSiS->SiS_Pr->CCRT1CRTC[16] = ((((pSiS->SiS_Pr->CVBlankStart - 1) & 0x200) >> 4) >> 5); /* cr9 */
+
+#if 0
+ if (mode->VScan >= 32)
+ regp->CRTC[9] |= 0x1F;
+ else if (mode->VScan > 1)
+ regp->CRTC[9] |= mode->VScan - 1;
+#endif
+
+ pSiS->SiS_Pr->CCRT1CRTC[8] = (pSiS->SiS_Pr->CVSyncStart - 1) & 0xFF; /* cr10 */
+ pSiS->SiS_Pr->CCRT1CRTC[9] = ((pSiS->SiS_Pr->CVSyncEnd - 1) & 0x0F) | 0x80; /* cr11 */
+ pSiS->SiS_Pr->CCRT1CRTC[10] = (pSiS->SiS_Pr->CVDisplay - 1) & 0xFF; /* cr12 */
+ pSiS->SiS_Pr->CCRT1CRTC[11] = (pSiS->SiS_Pr->CVBlankStart - 1) & 0xFF; /* cr15 */
+ pSiS->SiS_Pr->CCRT1CRTC[12] = (pSiS->SiS_Pr->CVBlankEnd - 1) & 0xFF; /* cr16 */
+
+ pSiS->SiS_Pr->CCRT1CRTC[13] =
+ GETBITSTR((pSiS->SiS_Pr->CVTotal -2), 10:10, 0:0) |
+ GETBITSTR((pSiS->SiS_Pr->CVDisplay -1), 10:10, 1:1) |
+ GETBITSTR((pSiS->SiS_Pr->CVBlankStart-1), 10:10, 2:2) |
+ GETBITSTR((pSiS->SiS_Pr->CVSyncStart ), 10:10, 3:3) |
+ GETBITSTR((pSiS->SiS_Pr->CVBlankEnd -1), 8:8, 4:4) |
+ GETBITSTR((pSiS->SiS_Pr->CVSyncEnd -1), 4:4, 5:5) ;
+
+ pSiS->SiS_Pr->CCRT1CRTC[14] =
+ GETBITSTR((pSiS->SiS_Pr->CHTotal >> 3) - 5, 9:8, 1:0) |
+ GETBITSTR((pSiS->SiS_Pr->CHDisplay >> 3) - 1, 9:8, 3:2) |
+ GETBITSTR((pSiS->SiS_Pr->CHBlankStart >> 3) - 1, 9:8, 5:4) |
+ GETBITSTR((pSiS->SiS_Pr->CHSyncStart >> 3) + 3, 9:8, 7:6) ;
+
+
+ pSiS->SiS_Pr->CCRT1CRTC[15] =
+ GETBITSTR((pSiS->SiS_Pr->CHBlankEnd >> 3) - 1, 7:6, 1:0) |
+ GETBITSTR((pSiS->SiS_Pr->CHSyncEnd >> 3) + 3, 5:5, 2:2) ;
+
+ 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;
+ }
+
+ if(pSiS->SiS_Pr->CFlags & V_DBLSCAN)
+ pSiS->SiS_Pr->CModeFlag |= DoubleScanMode;
+ if((pSiS->SiS_Pr->CVDisplay >= 1024) ||
+ (pSiS->SiS_Pr->CVTotal >= 1024) ||
+ (pSiS->SiS_Pr->CHDisplay >= 1024))
+ pSiS->SiS_Pr->CModeFlag |= LineCompareOff;
+ if(pSiS->SiS_Pr->CFlags & V_CLKDIV2)
+ pSiS->SiS_Pr->CModeFlag |= HalfDCLK;
+
+ pSiS->SiS_Pr->CInfoFlag = 0x0007;
+ if(pSiS->SiS_Pr->CFlags & V_NHSYNC)
+ pSiS->SiS_Pr->CInfoFlag |= 0x4000;
+ if(pSiS->SiS_Pr->CFlags & V_NVSYNC)
+ pSiS->SiS_Pr->CInfoFlag |= 0x8000;
+ if(pSiS->SiS_Pr->CFlags & V_INTERLACE)
+ pSiS->SiS_Pr->CInfoFlag |= InterlaceMode;
+
+ pSiS->SiS_Pr->UseCustomMode = TRUE;
+#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;
+}
+
+/* TW: Build a list of supported modes */
+DisplayModePtr
+SiSBuildBuiltInModeList(ScrnInfoPtr pScrn)
+{
+ 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, index, vclkindex;
+ DisplayModePtr new = NULL, current = NULL, first = NULL, backup = NULL;
+
+ pSiS->backupmodelist = NULL;
+
+ /* Initialize our pointers */
+ if(pSiS->VGAEngine == SIS_300_VGA) {
+#ifdef SIS300
+ InitTo300Pointer(pSiS->SiS_Pr, &pSiS->sishw_ext);
+#else
+ return NULL;
+#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;
+#if 0 /* Not any longer */
+ if(pSiS->VGAEngine == SIS_300_VGA) index &= 0x3F;
+#endif
+
+ if(((pSiS->SiS_Pr->SiS_RefIndex[i].XRes < 512) && (!pSiS->DSTN)) ||
+ ((pSiS->DSTN) &&
+ (pSiS->SiS_Pr->SiS_RefIndex[i].XRes < 512) &&
+ (pSiS->SiS_Pr->SiS_RefIndex[i].XRes != 320) &&
+ (pSiS->SiS_Pr->SiS_RefIndex[i].YRes != 480))) {
+ 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);
+#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;
+
+ 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;
+
+ 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);
+
+ D = B - F - C;
+
+ current->HDisplay = (E * 8);
+ current->HSyncStart = (E * 8) + (F * 8);
+ current->HSyncEnd = (E * 8) + (F * 8) + (C * 8);
+ current->HTotal = (E * 8) + (F * 8) + (C * 8) + (D * 8);
+
+#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;
+
+#if 0
+ 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;
+ }
+
+ if((backup = xalloc(sizeof(DisplayModeRec)))) {
+ if(!pSiS->backupmodelist) pSiS->backupmodelist = backup;
+ else {
+ pSiS->backupmodelist->next = backup;
+ backup->prev = pSiS->backupmodelist;
+ }
+ backup->next = NULL;
+ backup->HDisplay = current->HDisplay;
+ backup->HSyncStart = current->HSyncStart;
+ backup->HSyncEnd = current->HSyncEnd;
+ backup->HTotal = current->HTotal;
+ backup->VDisplay = current->VDisplay;
+ backup->VSyncStart = current->VSyncStart;
+ backup->VSyncEnd = current->VSyncEnd;
+ backup->VTotal = current->VTotal;
+ backup->Flags = current->Flags;
+ backup->Clock = current->Clock;
+ }
+
+#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);
+#endif
+
+ i++;
+ }
+
+ return first;
+
+}
+
+#define MODEID_OFF 0x449
+
+unsigned char
+SiS_GetSetModeID(ScrnInfoPtr pScrn, unsigned char id)
+{
+ return(SiS_GetSetBIOSScratch(pScrn, MODEID_OFF, id));
+}
+
+unsigned char
+SiS_GetSetBIOSScratch(ScrnInfoPtr pScrn, USHORT offset, unsigned char value)
+{
+ unsigned char ret;
+ unsigned char *base;
+
+ base = xf86MapVidMem(pScrn->scrnIndex, VIDMEM_MMIO, 0, 0x2000);
+ if(!base) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "(init.c: Could not map BIOS scratch area)\n");
+ return 0;
+ }
+
+ ret = *(base + offset);
+
+ /* value != 0xff means: set register */
+ if (value != 0xff)
+ *(base + offset) = value;
+
+ xf86UnMapVidMem(pScrn->scrnIndex, base, 0x2000);
+
+ return ret;
+}
+
+#endif
+
+
+
diff --git a/src/init.h b/src/init.h
new file mode 100644
index 0000000..8663509
--- /dev/null
+++ b/src/init.h
@@ -0,0 +1,316 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/init.h,v 1.5 2003/02/10 01:14:16 tsi Exp $ */
+
+#ifndef _INIT_
+#define _INIT_
+
+#include "osdef.h"
+#include "initdef.h"
+#include "vgatypes.h"
+#include "vstruct.h"
+
+#ifdef TC
+#include <stdio.h>
+#include <string.h>
+#include <conio.h>
+#include <dos.h>
+#include <stdlib.h>
+#endif
+
+#ifdef LINUX_XF86
+#include "xf86.h"
+#include "xf86Pci.h"
+#include "xf86PciInfo.h"
+#include "xf86_OSproc.h"
+#include "sis.h"
+#include "sis_regs.h"
+#endif
+
+#ifdef LINUX_KERNEL
+#include <linux/types.h>
+#include <asm/io.h>
+#include <linux/sisfb.h>
+#endif
+
+#ifdef WIN2000
+#include <stdio.h>
+#include <string.h>
+#include <miniport.h>
+#include "dderror.h"
+#include "devioctl.h"
+#include "miniport.h"
+#include "ntddvdeo.h"
+#include "video.h"
+#include "sisv.h"
+#include "tools.h"
+#endif
+
+const USHORT SiS_DRAMType[17][5]={
+ {0x0C,0x0A,0x02,0x40,0x39},
+ {0x0D,0x0A,0x01,0x40,0x48},
+ {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}
+};
+
+const USHORT SiS_SDRDRAM_TYPE[13][5] =
+{
+ { 2,12, 9,64,0x35},
+ { 1,13, 9,64,0x44},
+ { 2,12, 8,32,0x31},
+ { 2,11, 9,32,0x25},
+ { 1,12, 9,32,0x34},
+ { 1,13, 8,32,0x40},
+ { 2,11, 8,16,0x21},
+ { 1,12, 8,16,0x30},
+ { 1,11, 9,16,0x24},
+ { 1,11, 8, 8,0x20},
+ { 2, 9, 8, 4,0x01},
+ { 1,10, 8, 4,0x10},
+ { 1, 9, 8, 2,0x00}
+};
+
+const USHORT SiS_DDRDRAM_TYPE[4][5] =
+{
+ { 2,12, 9,64,0x35},
+ { 2,12, 8,32,0x31},
+ { 2,11, 8,16,0x21},
+ { 2, 9, 8, 4,0x01}
+};
+
+const USHORT SiS_MDA_DAC[] =
+{
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+ 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+ 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+ 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+ 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F
+};
+
+const USHORT SiS_CGA_DAC[] =
+{
+ 0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
+ 0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
+ 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F,
+ 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F,
+ 0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
+ 0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
+ 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F,
+ 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F
+};
+
+const USHORT SiS_EGA_DAC[] =
+{
+ 0x00,0x10,0x04,0x14,0x01,0x11,0x05,0x15,
+ 0x20,0x30,0x24,0x34,0x21,0x31,0x25,0x35,
+ 0x08,0x18,0x0C,0x1C,0x09,0x19,0x0D,0x1D,
+ 0x28,0x38,0x2C,0x3C,0x29,0x39,0x2D,0x3D,
+ 0x02,0x12,0x06,0x16,0x03,0x13,0x07,0x17,
+ 0x22,0x32,0x26,0x36,0x23,0x33,0x27,0x37,
+ 0x0A,0x1A,0x0E,0x1E,0x0B,0x1B,0x0F,0x1F,
+ 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F
+};
+
+const USHORT SiS_VGA_DAC[] =
+{
+ 0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
+ 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F,
+ 0x00,0x05,0x08,0x0B,0x0E,0x11,0x14,0x18,
+ 0x1C,0x20,0x24,0x28,0x2D,0x32,0x38,0x3F,
+ 0x00,0x10,0x1F,0x2F,0x3F,0x1F,0x27,0x2F,
+ 0x37,0x3F,0x2D,0x31,0x36,0x3A,0x3F,0x00,
+ 0x07,0x0E,0x15,0x1C,0x0E,0x11,0x15,0x18,
+ 0x1C,0x14,0x16,0x18,0x1A,0x1C,0x00,0x04,
+ 0x08,0x0C,0x10,0x08,0x0A,0x0C,0x0E,0x10,
+ 0x0B,0x0C,0x0D,0x0F,0x10
+};
+
+void SiS_SetReg1(USHORT, USHORT, USHORT);
+void SiS_SetReg2(SiS_Private *, USHORT, USHORT, USHORT);
+void SiS_SetReg3(USHORT, USHORT);
+void SiS_SetReg4(USHORT, ULONG);
+void SiS_SetReg5(USHORT, USHORT);
+UCHAR SiS_GetReg1(USHORT, USHORT);
+UCHAR SiS_GetReg2(USHORT);
+ULONG SiS_GetReg3(USHORT);
+USHORT SiS_GetReg4(USHORT);
+void SiS_ClearDAC(SiS_Private *SiS_Pr, ULONG);
+void SiS_SetMemoryClock(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void SiS_SetDRAMModeRegister(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+BOOLEAN SiS_SearchVBModeID(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT *ModeNo);
+void SiS_IsLowResolution(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
+
+#ifdef SIS300
+void SiS_SetDRAMSize_300(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+USHORT SiS_ChkBUSWidth_300(SiS_Private *SiS_Pr, ULONG FBAddress);
+#endif
+
+#ifdef SIS315H
+UCHAR SiS_Get310DRAMType(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void SiS_DDR_MRS(SiS_Private *SiS_Pr);
+void SiS_SDR_MRS(SiS_Private *SiS_Pr);
+void SiS_DisableRefresh(SiS_Private *SiS_Pr);
+void SiS_EnableRefresh(SiS_Private *SiS_Pr, UCHAR *ROMAddr);
+void SiS_SetDRAMSize_310(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO);
+void SiS_DisableChannelInterleaving(SiS_Private *SiS_Pr, int index,USHORT SiS_DDRDRAM_TYPE[][5]);
+void SiS_SetDRAMSizingType(SiS_Private *SiS_Pr, int index,USHORT DRAMTYPE_TABLE[][5]);
+void SiS_CheckBusWidth_310(SiS_Private *SiS_Pr, UCHAR *ROMAddress,ULONG FBAddress,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension);
+int SiS_SetRank(SiS_Private *SiS_Pr, int index,UCHAR RankNo,USHORT DRAMTYPE_TABLE[][5]);
+int SiS_SetDDRChannel(SiS_Private *SiS_Pr, int index,UCHAR ChannelNo,
+ USHORT DRAMTYPE_TABLE[][5]);
+int SiS_CheckColumn(SiS_Private *SiS_Pr, int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress);
+int SiS_CheckBanks(SiS_Private *SiS_Pr, int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress);
+int SiS_CheckRank(SiS_Private *SiS_Pr, int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress);
+int SiS_CheckDDRRank(SiS_Private *SiS_Pr, int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress);
+int SiS_CheckRanks(SiS_Private *SiS_Pr, int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress);
+int SiS_CheckDDRRanks(SiS_Private *SiS_Pr, int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress);
+int SiS_SDRSizing(SiS_Private *SiS_Pr, ULONG FBAddress);
+int SiS_DDRSizing(SiS_Private *SiS_Pr, ULONG FBAddress);
+int Is315E(SiS_Private *SiS_Pr);
+void SiS_VerifyMclk(SiS_Private *SiS_Pr, ULONG FBAddr);
+#endif
+
+void SiS_HandleCRT1(SiS_Private *SiS_Pr);
+void SiS_Handle301B_1400x1050(SiS_Private *SiS_Pr, USHORT ModeNo);
+void SiS_SetEnableDstn(SiS_Private *SiS_Pr);
+void SiS_Delay15us(SiS_Private *SiS_Pr);
+BOOLEAN SiS_SearchModeID(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT *ModeNo,USHORT *ModeIdIndex);
+BOOLEAN SiS_CheckMemorySize(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+ USHORT ModeNo,USHORT ModeIdIndex);
+UCHAR SiS_GetModePtr(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex);
+void SiS_SetSeqRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex);
+void SiS_SetMiscRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex);
+void SiS_SetCRTCRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+ USHORT StandTableIndex);
+void SiS_SetATTRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void SiS_SetGRCRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex);
+void SiS_ClearExt1Regs(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void SiS_SetSync(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT RefreshRateTableIndex);
+void SiS_SetCRT1CRTC(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension);
+BOOLEAN SiS_GetLCDACRT1Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,USHORT *ResInfo,USHORT *DisplayType);
+void SiS_ResetCRT1VCLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void SiS_SetCRT1VCLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO,
+ USHORT RefreshRateTableIndex);
+void SiS_SetVCLKState(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO, USHORT ModeNo,
+ USHORT RefreshRateTableIndex, USHORT ModeIdIndex);
+void SiS_LoadDAC(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
+void SiS_WriteDAC(SiS_Private *SiS_Pr, USHORT, USHORT, USHORT, USHORT, USHORT, USHORT);
+void SiS_DisplayOn(SiS_Private *SiS_Pr);
+void SiS_DisplayOff(SiS_Private *SiS_Pr);
+void SiS_SetCRT1ModeRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO,USHORT ModeNo,
+ USHORT ModeIdIndex,USHORT RefreshRateTableIndex);
+void SiS_GetVBType(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO);
+USHORT SiS_ChkBUSWidth(SiS_Private *SiS_Pr, UCHAR *ROMAddr);
+USHORT SiS_GetModeIDLength(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT);
+USHORT SiS_GetRefindexLength(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT);
+void SiS_SetInterlace(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT RefreshRateTableIndex);
+void SiS_Set_LVDS_TRUMPION(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void SiS_SetCRT1Offset(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT,USHORT,USHORT,PSIS_HW_DEVICE_INFO);
+#ifdef SIS315H
+void SiS_SetCRT1FIFO_310(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT,USHORT,PSIS_HW_DEVICE_INFO);
+#endif
+#ifdef SIS300
+void SiS_SetCRT1FIFO_300(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,PSIS_HW_DEVICE_INFO,
+ USHORT RefreshRateTableIndex);
+void SiS_SetCRT1FIFO_630(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,PSIS_HW_DEVICE_INFO,
+ USHORT RefreshRateTableIndex);
+USHORT SiS_CalcDelay(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT VCLK,
+ USHORT colordepth, USHORT MCLK);
+USHORT SiS_DoCalcDelay(SiS_Private *SiS_Pr, USHORT MCLK, USHORT VCLK, USHORT colordepth, USHORT key);
+USHORT SiS_CalcDelay2(SiS_Private *SiS_Pr, UCHAR *ROMAddr, UCHAR,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+#endif
+void SiS_ClearBuffer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO,USHORT ModeNo);
+void SiS_SetCRT1Group(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+ USHORT ModeNo,USHORT ModeIdIndex,USHORT BaseAddr);
+void SiS_DetectMonitor(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr);
+void SiS_GetSenseStatus(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,UCHAR *ROMAddr);
+USHORT SiS_TestMonitorType(SiS_Private *SiS_Pr, UCHAR R_DAC,UCHAR G_DAC,UCHAR B_DAC);
+USHORT SiS_SenseCHTV(SiS_Private *SiS_Pr);
+BOOLEAN SiS_Sense(SiS_Private *SiS_Pr, USHORT tempbx,USHORT tempcx);
+BOOLEAN SiS_GetPanelID(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO);
+BOOLEAN SiS_GetLCDDDCInfo(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO);
+USHORT SiS_SenseLCD(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO);
+void SiSRegInit(SiS_Private *SiS_Pr, USHORT BaseAddr);
+void SiSInitPtr(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void SiSSetLVDSetc(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo);
+void SiSInitPCIetc(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void SiSDetermineROMUsage(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, UCHAR *ROMAddr);
+
+#ifdef LINUX_XF86
+USHORT SiS_CalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode);
+USHORT SiS_CheckCalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode, int VBFlags);
+USHORT SiS_CheckBuildCustomMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int VBFlags);
+void SiS_SetPitch(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, UShort BaseAddr);
+void SiS_SetPitchCRT1(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, UShort BaseAddr);
+void SiS_SetPitchCRT2(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, UShort BaseAddr);
+unsigned char SiS_GetSetModeID(ScrnInfoPtr pScrn, unsigned char id);
+unsigned char SiS_GetSetBIOSScratch(ScrnInfoPtr pScrn, USHORT offset, unsigned char value);
+extern int SiS_compute_vclk(int Clock, int *out_n, int *out_dn, int *out_div,
+ int *out_sbit, int *out_scale);
+#endif
+
+extern USHORT SiS_GetOffset(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+extern USHORT SiS_GetColorDepth(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
+extern void SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+extern BOOLEAN SiS_SetCRT2Group301(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension);
+extern void SiS_PresetScratchregister(SiS_Private *SiS_Pr, USHORT SiS_P3d4,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension);
+extern void SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr);
+extern void SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr);
+extern BOOLEAN SiS_BridgeIsOn(SiS_Private *SiS_Pr, USHORT BaseAddr);
+extern BOOLEAN SiS_BridgeIsEnable(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO );
+extern void SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+ USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension, int chkcrt2mode);
+extern BOOLEAN SiS_GetLCDResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,
+ USHORT ModeIdIndex, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+extern void SiS_SetHiVision(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+extern USHORT SiS_GetRatePtrCRT2(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension);
+extern void SiS_WhatIsThis(SiS_Private *SiS_Pr, USHORT myvbinfo);
+extern void SiS_LongWait(SiS_Private *SiS_Pr);
+extern void SiS_SetRegOR(USHORT Port,USHORT Index,USHORT DataOR);
+extern void SiS_SetRegAND(USHORT Port,USHORT Index,USHORT DataAND);
+extern void SiS_SetRegANDOR(USHORT Port,USHORT Index,USHORT DataAND,USHORT DataOR);
+extern USHORT SiS_GetResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
+extern void SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempax);
+extern USHORT SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempax);
+extern void SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempax);
+extern USHORT SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempax);
+extern void SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempax);
+extern USHORT SiS_GetCH70xx(SiS_Private *SiS_Pr, USHORT tempax);
+extern BOOLEAN SiS_GetLVDSCRT1Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,
+ USHORT *ResInfo,USHORT *DisplayType);
+extern USHORT SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension);
+extern BOOLEAN SiS_Is301B(SiS_Private *SiS_Pr, USHORT BaseAddr);
+extern BOOLEAN SiS_IsM650(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+extern BOOLEAN SiS_LowModeStuff(SiS_Private *SiS_Pr, USHORT ModeNo,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+extern BOOLEAN SiS_IsVAMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+extern BOOLEAN SiS_IsDualEdge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+extern USHORT SiS_GetMCLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+
+#endif
+
diff --git a/src/init301.c b/src/init301.c
new file mode 100644
index 0000000..0c2b635
--- /dev/null
+++ b/src/init301.c
@@ -0,0 +1,10798 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/init301.c,v 1.10 2003/02/04 02:44:28 dawes Exp $ */
+/*
+ * Mode switching code (CRT2 section) for SiS 300/540/630/730/315/550/650/740/330
+ * (Universal module for Linux kernel framebuffer, XFree86 4.x)
+ *
+ * Assembler-To-C translation
+ * Copyright 2002, 2003 by Thomas Winischhofer <thomas@winischhofer.net>
+ * Minor parts Copyright SiS, Inc.
+ *
+ * Based on BIOS
+ * 1.10.07, 1.10a for SiS650/LVDS+CH7019
+ * 1.11.05 for 650/LVDS (w/o Chrontel)
+ * 1.07.1b, 1.10.6s, 1.11.6w, 1.11.7w, 1.11.8r for SiS650/301(B/LV), 650/301LVx
+ * 2.04.50 (I) and 2.04.5c (II) for SiS630/301(B)
+ * 2.02.3b, 2.03.02, 2.04.2c, 2.04.5c, 2.07a and 2.08.b3 for 630/LVDS/LVDS+CH7005
+ * 2.04.5c, 2.04.6c for 730+LVDS+CH7005
+ * 1.09b for 315/301(B)
+ * 1.16.51 for 300+301LVX (ECS A907)
+ * 1.01.03 for 330 (Xabre 400)
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the copyright holder not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The copyright holder makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * 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.
+ *
+ */
+
+#include "init301.h"
+
+#if 0
+#define TWNEWPANEL
+#endif
+
+#if 1 /* TW: Emulate 650/301LVx BIOS 1.10.6s (should be set) */
+#define SIS650301NEW
+#endif
+
+#ifdef SIS300
+#include "oem300.h"
+#endif
+
+#ifdef SIS315H
+#include "oem310.h"
+#endif
+
+#define SiS_I2CDELAY 1000
+#define SiS_I2CDELAYSHORT 333
+
+BOOLEAN
+SiS_SetCRT2Group301(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ USHORT ModeIdIndex;
+ USHORT RefreshRateTableIndex;
+
+ SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
+
+ if(!SiS_Pr->UseCustomMode) {
+ SiS_SearchModeID(SiS_Pr,ROMAddr,&ModeNo,&ModeIdIndex);
+ } else {
+ ModeIdIndex = 0;
+ }
+
+ /* TW: Used for shifting CR33 */
+ SiS_Pr->SiS_SelectCRT2Rate = 4;
+
+ SiS_UnLockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr);
+
+ RefreshRateTableIndex = SiS_GetRatePtrCRT2(SiS_Pr, ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
+
+ SiS_SaveCRT2Info(SiS_Pr,ModeNo);
+
+ if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
+ SiS_DisableBridge(SiS_Pr,HwDeviceExtension,BaseAddr);
+ if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (HwDeviceExtension->jChipType == SIS_730)) {
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,0x80);
+ }
+ SiS_SetCRT2ModeRegs(SiS_Pr,BaseAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
+ }
+
+ if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
+ SiS_LockCRT2(SiS_Pr,HwDeviceExtension, BaseAddr);
+ SiS_DisplayOn(SiS_Pr);
+ return(TRUE);
+ }
+
+ if(SiS_Pr->UseCustomMode) return(FALSE);
+
+ SiS_GetCRT2Data(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+ HwDeviceExtension);
+
+ /* LVDS, 650/301LV(LCDA) and 630/301B BIOS set up Panel Link */
+ /* 300+LV does not */
+ if((SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
+ ((HwDeviceExtension->jChipType != SIS_300) && (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV))) {
+ SiS_GetLVDSDesData(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+ HwDeviceExtension);
+ } else {
+ SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
+ }
+
+#ifdef LINUX_XF86
+#ifdef TWDEBUG
+ xf86DrvMsg(0, X_INFO, "(init301: LCDHDES 0x%03x LCDVDES 0x%03x)\n", SiS_Pr->SiS_LCDHDES, SiS_Pr->SiS_LCDVDES);
+ xf86DrvMsg(0, X_INFO, "(init301: HDE 0x%03x VDE 0x%03x)\n", SiS_Pr->SiS_HDE, SiS_Pr->SiS_VDE);
+ xf86DrvMsg(0, X_INFO, "(init301: VGAHDE 0x%03x VGAVDE 0x%03x)\n", SiS_Pr->SiS_VGAHDE, SiS_Pr->SiS_VGAVDE);
+ xf86DrvMsg(0, X_INFO, "(init301: HT 0x%03x VT 0x%03x)\n", SiS_Pr->SiS_HT, SiS_Pr->SiS_VT);
+ xf86DrvMsg(0, X_INFO, "(init301: VGAHT 0x%03x VGAVT 0x%03x)\n", SiS_Pr->SiS_VGAHT, SiS_Pr->SiS_VGAVT);
+#endif
+#endif
+
+ if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
+ SiS_SetGroup1(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
+ HwDeviceExtension,RefreshRateTableIndex);
+ }
+
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+
+ if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
+
+ SiS_SetGroup2(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
+ RefreshRateTableIndex,HwDeviceExtension);
+ SiS_SetGroup3(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
+ HwDeviceExtension);
+ SiS_SetGroup4(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
+ RefreshRateTableIndex,HwDeviceExtension);
+ SiS_SetGroup5(SiS_Pr,HwDeviceExtension, BaseAddr,ROMAddr,
+ ModeNo,ModeIdIndex);
+
+ /* TW: 630/301B BIOS does all this: */
+ if((HwDeviceExtension->jChipType < SIS_315H) &&
+ (HwDeviceExtension->jChipType != SIS_300)) {
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+ if(!((SiS_Pr->SiS_SetFlag & CRT2IsVGA) && ((ModeNo == 0x03) || (ModeNo = 0x10)))) {
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+ SiS_ModCRT1CRTC(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
+ RefreshRateTableIndex,HwDeviceExtension);
+ }
+ }
+ }
+ SiS_SetCRT2ECLK(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
+ RefreshRateTableIndex,HwDeviceExtension);
+ }
+ }
+
+ }
+
+ } else {
+
+ if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+ if (SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
+ SiS_ModCRT1CRTC(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
+ RefreshRateTableIndex,HwDeviceExtension);
+ }
+ }
+ if(SiS_Pr->SiS_IF_DEF_FSTN == 0) {
+ SiS_SetCRT2ECLK(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
+ RefreshRateTableIndex,HwDeviceExtension);
+ }
+ if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
+ if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+ /* TW: Inserted from 650/LVDS BIOS */
+ if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+ SiS_SetCH701xForLCD(SiS_Pr,HwDeviceExtension,BaseAddr);
+ }
+ }
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ /* TW: Set Chrontel registers only if CRT2 is TV */
+ SiS_SetCHTVReg(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
+ RefreshRateTableIndex);
+ }
+ }
+ }
+
+ }
+
+#ifdef SIS300
+ if ( (HwDeviceExtension->jChipType == SIS_540) ||
+ (HwDeviceExtension->jChipType == SIS_630) ||
+ (HwDeviceExtension->jChipType == SIS_730) ||
+ (HwDeviceExtension->jChipType == SIS_300) )
+ {
+ if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
+ if(SiS_Pr->SiS_UseOEM) {
+ if((SiS_Pr->SiS_UseROM) && ROMAddr && (SiS_Pr->SiS_UseOEM == -1)) {
+ if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
+ SiS_OEM300Setting(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo);
+ }
+ } else {
+ SiS_OEM300Setting(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo);
+ }
+ }
+ }
+ }
+#endif
+
+#ifdef SIS315H
+ if ( (HwDeviceExtension->jChipType == SIS_315H) ||
+ (HwDeviceExtension->jChipType == SIS_315) ||
+ (HwDeviceExtension->jChipType == SIS_315PRO)||
+ (HwDeviceExtension->jChipType == SIS_550) ||
+ (HwDeviceExtension->jChipType == SIS_740) ||
+ (HwDeviceExtension->jChipType == SIS_650) ||
+ (HwDeviceExtension->jChipType == SIS_330) )
+ {
+ if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
+#ifdef SIS650301NEW
+ SiS_FinalizeLCD(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex, HwDeviceExtension);
+#else
+ SiS_OEMLCD(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+#endif
+ if(SiS_Pr->SiS_UseOEM) {
+ SiS_OEM310Setting(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+ }
+ SiS_CRT2AutoThreshold(SiS_Pr,BaseAddr);
+ }
+ }
+#endif
+
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+ if(HwDeviceExtension->jChipType != SIS_730) {
+ SiS_DisplayOn(SiS_Pr);
+ }
+ }
+ }
+
+ if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+ if(HwDeviceExtension->jChipType == SIS_730) {
+ SiS_DisplayOn(SiS_Pr);
+ }
+ }
+ SiS_EnableBridge(SiS_Pr,HwDeviceExtension,BaseAddr);
+ }
+
+ SiS_DisplayOn(SiS_Pr);
+
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ /* TW: Disable LCD panel when using TV */
+ SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x11,0x0C);
+ } else {
+ /* TW: Disable TV when using LCD */
+ SiS_SetCH70xxANDOR(SiS_Pr,0x010E,0xF8);
+ }
+ }
+
+ if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
+ SiS_LockCRT2(SiS_Pr,HwDeviceExtension, BaseAddr);
+ }
+
+ return 1;
+}
+
+/* TW: Checked with 330, 650/LVDS (1.10.07) and 630+301B/LVDS BIOS */
+BOOLEAN
+SiS_LowModeStuff(SiS_Private *SiS_Pr, USHORT ModeNo,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ USHORT temp,temp1,temp2;
+
+ if((ModeNo != 0x03) && (ModeNo != 0x10) && (ModeNo != 0x12))
+ return(1);
+ temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x11);
+ SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x11,0x80);
+ temp1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x00);
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x00,0x55);
+ temp2 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x00);
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x00,temp1);
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x11,temp);
+ if((HwDeviceExtension->jChipType >= SIS_315H) ||
+ (HwDeviceExtension->jChipType == SIS_300)) {
+ if(temp2 == 0x55) return(0);
+ else return(1);
+ } else {
+ if(temp2 != 0x55) return(1);
+ else {
+ SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01);
+ return(0);
+ }
+ }
+}
+
+/* TW: Set Part1 registers */
+/* TW: Checked with 650/LVDS (1.10.07), 650/301LV (II) and 630/301B (II) BIOS */
+/* TW: Pass 2: Checked with 650/301LVx 1.10.6s, 630/301B 2.04.5a */
+void
+SiS_SetGroup1(SiS_Private *SiS_Pr,USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+ USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+ USHORT RefreshRateTableIndex)
+{
+ USHORT temp=0, tempax=0, tempbx=0, tempcx=0;
+ USHORT pushbx=0, CRT1Index=0;
+#ifdef SIS315H
+ USHORT pushcx=0, tempbl=0;
+#endif
+ USHORT modeflag, resinfo=0;
+
+ if(ModeNo<=0x13) {
+ modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+ } else {
+ CRT1Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+ resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ }
+
+ /* TW: LCDA exists with LVDS as well */
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+
+ SiS_SetCRT2Sync(SiS_Pr,BaseAddr,ROMAddr,ModeNo,
+ RefreshRateTableIndex,HwDeviceExtension);
+
+ SiS_SetGroup1_LCDA(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
+ HwDeviceExtension,RefreshRateTableIndex);
+
+ } else {
+
+ if( (HwDeviceExtension->jChipType >= SIS_315H) &&
+ (SiS_Pr->SiS_IF_DEF_LVDS == 1) &&
+ (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+
+ SiS_SetCRT2Sync(SiS_Pr,BaseAddr,ROMAddr,ModeNo,
+ RefreshRateTableIndex,HwDeviceExtension);
+
+ } else {
+
+ SiS_SetCRT2Offset(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
+ RefreshRateTableIndex,HwDeviceExtension);
+
+ if (HwDeviceExtension->jChipType < SIS_315H ) {
+#ifdef SIS300
+ SiS_SetCRT2FIFO_300(SiS_Pr,ROMAddr,ModeNo,HwDeviceExtension);
+#endif
+ } else {
+#ifdef SIS315H
+ SiS_SetCRT2FIFO_310(SiS_Pr,ROMAddr,ModeNo,HwDeviceExtension);
+#endif
+ }
+
+ SiS_SetCRT2Sync(SiS_Pr,BaseAddr,ROMAddr,ModeNo,
+ RefreshRateTableIndex,HwDeviceExtension);
+
+ /* 1. Horizontal setup */
+
+ if (HwDeviceExtension->jChipType < SIS_315H ) {
+
+#ifdef SIS300 /* ------------- 300 series --------------*/
+
+ temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,temp); /* TW: CRT2 Horizontal Total */
+
+ temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp); /* TW: CRT2 Horizontal Total Overflow [7:4] */
+
+ temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0A,temp); /* TW: CRT2 Horizontal Display Enable End */
+
+ pushbx = SiS_Pr->SiS_VGAHDE + 12; /* bx BTVGA@HRS 0x0B,0x0C */
+ tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2;
+ tempbx = pushbx + tempcx;
+ tempcx <<= 1;
+ tempcx += tempbx;
+
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC){
+ /* CRT1Index &= 0x3F; - Not any longer */
+ tempbx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
+ tempbx |= ((SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14] & 0xC0) << 2);
+ tempbx = (tempbx - 1) << 3;
+ tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
+ tempcx &= 0x1F;
+ temp = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
+ temp = (temp & 0x04) << (6-2);
+ tempcx = ((tempcx | temp) - 1) << 3;
+ }
+
+ if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (resinfo == 0x08)){
+ if(!(SiS_Pr->SiS_VBInfo & SetPALTV)){
+ tempbx = 1040;
+ tempcx = 1042;
+ }
+ }
+ }
+
+ temp = tempbx & 0x00FF;
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0B,temp); /* TW: CRT2 Horizontal Retrace Start */
+#endif /* SIS300 */
+
+ } else {
+
+#ifdef SIS315H /* ----------------- 310/325 series ------------- */
+
+ tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HT 0x08,0x09 */
+ pushcx = tempcx;
+ if(modeflag & HalfDCLK) {
+ if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->SiS_IF_DEF_CH70xx == 0)) {
+ tempax = SiS_Pr->SiS_VGAHDE >> 1;
+ tempcx = SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE + tempax;
+ if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) {
+ tempcx = SiS_Pr->SiS_HT - tempax;
+ }
+ } else {
+ tempcx >>= 1;
+ }
+ }
+ tempcx--;
+
+ temp = tempcx & 0xff;
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,temp); /* TW: CRT2 Horizontal Total */
+
+ temp = ((tempcx & 0xff00) >> 8) << 4;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp); /* TW: CRT2 Horizontal Total Overflow [7:4] */
+
+ tempcx = pushcx; /* BTVGA2HDEE 0x0A,0x0C */
+ tempbx = SiS_Pr->SiS_VGAHDE;
+ tempcx -= tempbx;
+ tempcx >>= 2;
+ if(modeflag & HalfDCLK) {
+ tempbx >>= 1;
+ tempcx >>= 1;
+ }
+ tempbx += 16;
+
+ temp = tempbx & 0xff;
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0A,temp); /* TW: CRT2 Horizontal Display Enable End */
+
+ pushbx = tempbx;
+ tempcx >>= 1;
+ tempbx += tempcx;
+ tempcx += tempbx;
+
+ if(SiS_Pr->SiS_IF_DEF_LVDS==0) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
+ tempbx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
+ tempbx |= ((SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14] & 0xC0) << 2);
+ tempbx = (tempbx - 3) << 3; /*(VGAHRS-3)*8 */
+ tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
+ tempcx &= 0x1F;
+ temp = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
+ temp = (temp & 0x04) << (5-2); /* VGAHRE D[5] */
+ tempcx = ((tempcx | temp) - 3) << 3; /* (VGAHRE-3)*8 */
+ tempcx &= 0x00FF;
+ tempcx |= (tempbx & 0xFF00);
+ tempbx += 16;
+ tempcx += 16;
+ tempax = SiS_Pr->SiS_VGAHT;
+ if (modeflag & HalfDCLK) tempax >>= 1;
+ tempax--;
+ if (tempcx > tempax) tempcx = tempax;
+ }
+ if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (resinfo == 0x08)){
+ if(!(SiS_Pr->SiS_VBInfo & SetPALTV)){
+ tempbx = 1040;
+ tempcx = 1042;
+ }
+ }
+ /* TW: Makes no sense, but is in 650/301LVx 1.10.6s */
+ if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (resinfo == 0x08)){
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV)) {
+ if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+ tempbx = 1040;
+ tempcx = 1042;
+ }
+ }
+ }
+ }
+
+ temp = tempbx & 0xff;
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0B,temp); /* TW: CRT2 Horizontal Retrace Start */
+#endif /* SIS315H */
+
+ } /* 310 series */
+
+ /* TW: The following is done for all bridge/chip types/series */
+
+ tempax = tempbx & 0xFF00;
+ tempbx = pushbx;
+ tempbx = (tempbx & 0x00FF) | ((tempbx & 0xFF00) << 4);
+ tempax |= (tempbx & 0xFF00);
+ temp = (tempax & 0xFF00) >> 8;
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0C,temp); /* TW: Overflow */
+
+ temp = tempcx & 0x00FF;
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0D,temp); /* TW: CRT2 Horizontal Retrace End */
+
+ /* 2. Vertical setup */
+
+ tempcx = SiS_Pr->SiS_VGAVT - 1;
+ temp = tempcx & 0x00FF;
+
+ /* TW: Matches 650/301LV, 650/LVDS, 630/LVDS(CLEVO), 630/LVDS(no-Ch7005) */
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+ if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+ if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO|SetCRT2ToAVIDEO)) {
+ temp--;
+ }
+ }
+ } else {
+ temp--;
+ }
+ } else if(HwDeviceExtension->jChipType >= SIS_315H) {
+ /* TW: Inserted from 650/301LVx 1.10.6s */
+ temp--;
+ }
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0E,temp); /* TW: CRT2 Vertical Total */
+
+ tempbx = SiS_Pr->SiS_VGAVDE - 1;
+ temp = tempbx & 0x00FF;
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0F,temp); /* TW: CRT2 Vertical Display Enable End */
+
+ temp = ((tempbx & 0xFF00) << 3) >> 8;
+ temp |= ((tempcx & 0xFF00) >> 8);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x12,temp); /* TW: Overflow (and HWCursor Test Mode) */
+
+ /* TW: For 650/LVDS (1.10.07), 650/301LVx (1.10.6s) */
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ tempbx++;
+ tempax = tempbx;
+ tempcx++;
+ tempcx -= tempax;
+ tempcx >>= 2;
+ tempbx += tempcx;
+ if(tempcx < 4) tempcx = 4;
+ tempcx >>= 2;
+ tempcx += tempbx;
+ tempcx++;
+ } else {
+ /* TW: For 300/630/LVDS/301B: */
+ tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1; /* BTVGA2VRS 0x10,0x11 */
+ tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1; /* BTVGA2VRE 0x11 */
+ }
+
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC){
+ tempbx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8];
+ temp = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
+ if(temp & 0x04) tempbx |= 0x0100;
+ if(temp & 0x80) tempbx |= 0x0200;
+ temp = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
+ if(temp & 0x08) tempbx |= 0x0400;
+ temp = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
+ tempcx = (tempcx & 0xFF00) | (temp & 0x00FF);
+ }
+ }
+ temp = tempbx & 0x00FF;
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x10,temp); /* TW: CRT2 Vertical Retrace Start */
+
+ temp = ((tempbx & 0xFF00) >> 8) << 4;
+ temp |= (tempcx & 0x000F);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x11,temp); /* TW: CRT2 Vert. Retrace End; Overflow; "Enable CRTC Check" */
+
+ /* 3. Panel compensation delay */
+
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+
+#ifdef SIS300 /* ---------- 300 series -------------- */
+
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+ temp = 0x20;
+
+ if(HwDeviceExtension->jChipType == SIS_300) {
+ temp = 0x10;
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) temp = 0x2c;
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) temp = 0x20;
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) temp = 0x24;
+ }
+ if(SiS_Pr->SiS_VBType & VB_SIS301) {
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) temp = 0x20;
+ }
+#if 0 /* TW: Not in 630/301B BIOS */
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) temp = 0x24;
+#endif
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x08;
+#ifdef oldHV
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) temp = 0x2c;
+ else temp = 0x20;
+ }
+#endif
+ if((ROMAddr) && (SiS_Pr->SiS_UseROM) && (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
+ if(ROMAddr[0x220] & 0x80) {
+ if(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV-SetCRT2ToHiVisionTV))
+ temp = ROMAddr[0x221];
+ else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV)
+ temp = ROMAddr[0x222];
+ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)
+ temp = ROMAddr[0x223];
+ else
+ temp = ROMAddr[0x224];
+ temp &= 0x3c;
+ }
+ }
+ if(HwDeviceExtension->pdc) {
+ temp = HwDeviceExtension->pdc & 0x3c;
+ }
+ } else {
+ temp = 0x20;
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) temp = 0x04;
+ }
+ if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+ if(ROMAddr[0x220] & 0x80) {
+ temp = ROMAddr[0x220] & 0x3c;
+ }
+ }
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ if(HwDeviceExtension->pdc) {
+ temp = HwDeviceExtension->pdc & 0x3c;
+ }
+ }
+ }
+
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x03C,temp); /* TW: Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
+
+#endif /* SIS300 */
+
+ } else {
+
+#ifdef SIS315H /* ----------- 310/325 series ---------------*/
+
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+ temp = 0x10;
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) temp = 0x2c;
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) temp = 0x20;
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) temp = 0x24;
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x08;
+ tempbl = 0xF0;
+ } else {
+ temp = 0x00;
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x0a;
+ tempbl = 0xF0;
+ if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F;
+ }
+ }
+#if 0 /* TW: Not done in 650/301LVx 1.10.6s */
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+ temp >>= 2;
+ }
+#endif
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp); /* TW: Panel Link Delay Compensation */
+
+ tempax = 0;
+ if (modeflag & DoubleScanMode) tempax |= 0x80;
+ if (modeflag & HalfDCLK) tempax |= 0x40;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax);
+
+#endif /* SIS315H */
+
+ }
+
+ } /* Slavemode */
+
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+
+ /* TW: 630/301B BIOS sets up Panel Link, too! (300/301LV and 650/LV do not) */
+ if( (HwDeviceExtension->jChipType < SIS_315H) &&
+ (HwDeviceExtension->jChipType != SIS_300) &&
+ (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
+ (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ) {
+
+ SiS_SetGroup1_LVDS(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
+ HwDeviceExtension,RefreshRateTableIndex);
+
+ } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+
+ SiS_SetGroup1_301(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
+ HwDeviceExtension,RefreshRateTableIndex);
+ }
+
+ } else {
+
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+ SiS_SetGroup1_LVDS(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
+ HwDeviceExtension,RefreshRateTableIndex);
+ } else {
+ /* TW: For 650/LVDS */
+ if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+ if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+ SiS_SetGroup1_LVDS(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
+ HwDeviceExtension,RefreshRateTableIndex);
+ }
+ } else {
+ SiS_SetGroup1_LVDS(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
+ HwDeviceExtension,RefreshRateTableIndex);
+ }
+ }
+
+ }
+ } /* LCDA */
+}
+
+/* TW: Checked against 650/301LV and 630/301B (II) BIOS */
+/* TW: Pass 2: Checked with 650/301LVx (1.10.6s) and 630/301B (2.04.5a) */
+void
+SiS_SetGroup1_301(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex)
+{
+ USHORT push1,push2;
+ USHORT tempax,tempbx,tempcx,temp;
+ USHORT resinfo,modeflag;
+
+ if(ModeNo<=0x13) {
+ modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+ resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+ } else {
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ }
+
+ /* TW: The following is only done if bridge is in slave mode: */
+
+ tempax = 0xFFFF;
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempax = SiS_GetVGAHT2(SiS_Pr);
+
+ /* TW: 630/301B, 300/301LV do not check this flag, assume it is set */
+ /* 650/LV and 650/301LVx BIOS do not check this either; so we set it... */
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ modeflag |= Charx8Dot;
+ }
+
+ if(modeflag & Charx8Dot) tempcx = 0x08;
+ else tempcx = 0x09;
+
+ if(tempax >= SiS_Pr->SiS_VGAHT) tempax = SiS_Pr->SiS_VGAHT;
+
+ if(modeflag & HalfDCLK) tempax >>= 1;
+
+ tempax = (tempax / tempcx) - 5;
+ tempbx = tempax & 0xFF;
+
+ temp = 0xFF; /* set MAX HT */
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x03,temp);
+
+ tempax = SiS_Pr->SiS_VGAHDE; /* 0x04 Horizontal Display End */
+ if(modeflag & HalfDCLK) tempax >>= 1;
+ tempax = (tempax / tempcx) - 1;
+ tempbx |= ((tempax & 0x00FF) << 8);
+ temp = tempax & 0xFF;
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x04,temp);
+
+ temp = (tempbx & 0xFF00) >> 8;
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
+ temp += 2;
+ }
+#ifdef oldHV
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
+ if(resinfo == 7) temp -= 2;
+ }
+#endif
+ }
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x05,temp); /* 0x05 Horizontal Display Start */
+
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x06,0x03); /* 0x06 Horizontal Blank end */
+
+#ifdef oldHV
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
+ temp = (tempbx & 0x00FF) - 1;
+ if(!(modeflag & HalfDCLK)) {
+ temp -= 6;
+ if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
+ temp -= 2;
+ if(ModeNo > 0x13) temp -= 10;
+ }
+ }
+ } else {
+#endif
+ tempcx = tempbx & 0x00FF;
+ tempbx = (tempbx & 0xFF00) >> 8;
+ tempcx = (tempcx + tempbx) >> 1;
+ temp = (tempcx & 0x00FF) + 2;
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV){
+ temp--;
+ if(!(modeflag & HalfDCLK)){
+ if((modeflag & Charx8Dot)){
+ temp += 4;
+ if(SiS_Pr->SiS_VGAHDE >= 800) temp -= 6;
+ /* TW: Inserted from 650/301 BIOS, 630/301B/301 don't do this */
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ if(SiS_Pr->SiS_VGAHDE == 800) temp += 2;
+ }
+ }
+ }
+ } else {
+ if(!(modeflag & HalfDCLK)) {
+ temp -= 4;
+ if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x960) {
+ if(SiS_Pr->SiS_VGAHDE >= 800){
+ temp -= 7;
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+ /* 650/301LV(x) does not do this, 630/301B, 300/301LV do */
+ if(SiS_Pr->SiS_ModeType == ModeEGA){
+ if(SiS_Pr->SiS_VGAVDE == 1024){
+ temp += 15;
+ if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024) temp += 7;
+ }
+ }
+ }
+ if(SiS_Pr->SiS_VGAHDE >= 1280){
+ if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x960) {
+ if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) temp += 28;
+ }
+ }
+ }
+ }
+ }
+ }
+#ifdef oldHV
+ }
+#endif
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,temp); /* 0x07 Horizontal Retrace Start */
+
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x00); /* 0x08 Horizontal Retrace End */
+
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
+ if(ModeNo <= 1) {
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x2a);
+ if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x61);
+ } else {
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x41);
+ }
+ } else if(SiS_Pr->SiS_ModeType == ModeText) {
+ if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x54);
+ } else {
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x55);
+ }
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x00);
+ } else if(ModeNo <= 0x13) {
+ if(modeflag & HalfDCLK) {
+ if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x30);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x03);
+ } else {
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x2f);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x02);
+ }
+ } else {
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x5b);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x03);
+ }
+ } else if( ((HwDeviceExtension->jChipType >= SIS_315H) && (ModeNo == 0x50)) ||
+ ((HwDeviceExtension->jChipType < SIS_315H) && (resinfo == 0 || resinfo == 1)) ) {
+ if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x30);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x03);
+ } else {
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x2f);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x03);
+ }
+ }
+
+ }
+ }
+
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x03); /* 0x18 SR08 */
+
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x19,0xF0);
+
+ tempbx = SiS_Pr->SiS_VGAVT;
+ push1 = tempbx;
+
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x09,0xFF); /* 0x09 Set Max VT */
+
+ tempcx = 0x121;
+ tempbx = SiS_Pr->SiS_VGAVDE; /* 0x0E Vertical Display End */
+ if(tempbx == 357) tempbx = 350;
+ if(tempbx == 360) tempbx = 350;
+ if(tempbx == 375) tempbx = 350;
+ if(tempbx == 405) tempbx = 400;
+ if(tempbx == 420) tempbx = 400;
+ if(tempbx == 525) tempbx = 480;
+ push2 = tempbx;
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+ if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
+ if(tempbx == 350) tempbx += 5;
+ if(tempbx == 480) tempbx += 5;
+ }
+ }
+ }
+ tempbx--;
+ temp = tempbx & 0x00FF;
+ tempbx--;
+ temp = tempbx & 0x00FF;
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x10,temp); /* 0x10 vertical Blank Start */
+
+ tempbx = push2;
+ tempbx--;
+ temp = tempbx & 0x00FF;
+#if 0
+ /* TW: Missing code from 630/301B 2.04.5a and 650/301LVx 1.10.6s (calles int 2f) */
+ if(xxx()) {
+ if(temp == 0xdf) temp = 0xda;
+ }
+#endif
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0E,temp);
+
+ if(tempbx & 0x0100) {
+ tempcx |= 0x0002;
+ if(SiS_Pr->SiS_VBType & VB_SIS301) tempcx |= 0x000a;
+ }
+
+ tempax = 0x000B;
+ if(modeflag & DoubleScanMode) tempax |= 0x8000;
+
+ if(tempbx & 0x0200) {
+ tempcx |= 0x0040;
+ if(SiS_Pr->SiS_VBType & VB_SIS301) tempax |= 0x2000;
+ }
+
+ if(SiS_Pr->SiS_VBType & VB_SIS301) {
+ if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+ if(SiS_Pr->SiS_VGAVDE == 480) {
+ tempax = (tempax & 0x00ff) | 0x2000;
+ if(modeflag & DoubleScanMode) tempax |= 0x8000;
+ }
+ }
+ }
+
+ temp = (tempax & 0xFF00) >> 8;
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0B,temp);
+
+ if(tempbx & 0x0400) tempcx |= 0x0600;
+
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x11,0x00); /* 0x11 Vertical Blank End */
+
+ tempax = push1;
+ tempax -= tempbx;
+ tempax >>= 2;
+ push1 = tempax;
+
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ /* TW: Inserted from 650/301LVx 1.10.6s */
+ if(ModeNo > 0x13) {
+ if(resinfo != 0x09) {
+ tempax <<= 1;
+ tempbx += tempax;
+ }
+ } else {
+ if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1400x1050) {
+ tempax <<= 1;
+ tempbx += tempax;
+ }
+ }
+ } else if((resinfo != 0x09) || (SiS_Pr->SiS_VBType & VB_SIS301)) {
+ tempax <<= 1;
+ tempbx += tempax;
+ }
+#ifdef oldHV
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
+ tempbx -= 10;
+ } else {
+#endif
+ if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
+ if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+ if(!(SiS_Pr->SiS_HiVision & 0x03)) {
+ tempbx += 40;
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ if(SiS_Pr->SiS_VGAHDE == 800) tempbx += 10;
+ }
+ }
+ }
+ }
+#ifdef oldHV
+ }
+#endif
+ tempax = push1;
+ tempax >>= 2;
+ tempax++;
+ tempax += tempbx;
+ push1 = tempax;
+ if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+ if(tempbx <= 513) {
+ if(tempax >= 513) tempbx = 513;
+ }
+ }
+ temp = tempbx & 0x00FF;
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0C,temp); /* 0x0C Vertical Retrace Start */
+
+ if(!(SiS_Pr->SiS_VBType & VB_SIS301)) {
+ tempbx--;
+ temp = tempbx & 0x00FF;
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x10,temp);
+
+ if(tempbx & 0x0100) tempcx |= 0x0008;
+
+ if(tempbx & 0x0200) {
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x0B,0x20);
+ }
+
+ tempbx++;
+ }
+ if(tempbx & 0x0100) tempcx |= 0x0004;
+ if(tempbx & 0x0200) tempcx |= 0x0080;
+ if(tempbx & 0x0400) {
+ if(SiS_Pr->SiS_VBType & VB_SIS301) tempcx |= 0x0800;
+ else tempcx |= 0x0C00;
+ }
+
+ tempbx = push1;
+ temp = tempbx & 0x00FF;
+ temp &= 0x0F;
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0D,temp); /* 0x0D vertical Retrace End */
+
+ if(tempbx & 0x0010) tempcx |= 0x2000;
+
+ temp = tempcx & 0x00FF;
+ if(SiS_Pr->SiS_VBType & VB_SIS301) {
+ if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+ if(SiS_Pr->SiS_VGAVDE == 480) temp = 0xa3;
+ }
+ }
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0A,temp); /* 0x0A CR07 */
+
+ temp = (tempcx & 0xFF00) >> 8;
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x17,temp); /* 0x17 SR0A */
+
+ tempax = modeflag;
+ temp = (tempax & 0xFF00) >> 8;
+ temp = (temp >> 1) & 0x09;
+ /* TW: Inserted from 630/301B and 650/301(LV/LVX) BIOS; not in 630/301 BIOS */
+ if(!(SiS_Pr->SiS_VBType & VB_SIS301)) {
+ temp |= 0x01;
+ }
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x16,temp); /* 0x16 SR01 */
+
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0F,0x00); /* 0x0F CR14 */
+
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x12,0x00); /* 0x12 CR17 */
+
+ if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ /* TW: Inserted from 650/301LVx 1.10.6s */
+ if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
+ temp = 0x80;
+ }
+ } else temp = 0x80;
+ } else temp = 0x00;
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1A,temp); /* 0x1A SR0E */
+
+ return;
+}
+
+/* TW: Checked against 650/LVDS 1.10.07, 630/301B (I,II) and 630/LVDS BIOS */
+void
+SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr,USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+ USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+ USHORT RefreshRateTableIndex)
+{
+ USHORT modeflag, resinfo;
+ USHORT push1, push2, tempax, tempbx, tempcx, temp;
+#ifdef SIS315H
+ USHORT pushcx;
+#endif
+ ULONG tempeax=0, tempebx, tempecx, tempvcfact=0;
+
+ if(ModeNo<=0x13) {
+ modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+ resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+ } else {
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ }
+
+ /* TW: Set up Panel Link */
+
+ /* 1. Horizontal setup */
+
+ tempax = SiS_Pr->SiS_LCDHDES;
+
+ if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
+ tempax -= 8;
+ }
+
+ tempcx = SiS_Pr->SiS_HT; /* Horiz. Total */
+
+ tempbx = SiS_Pr->SiS_HDE; /* Horiz. Display End */
+
+ if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) {
+ if(!SiS_Pr->SiS_IF_DEF_DSTN) {
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) tempbx = 800;
+ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempbx = 1024;
+ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) tempbx = 1024; /* TW: not done in BIOS */
+ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) tempbx = 1152; /* TW: not done in BIOS */
+ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempbx = 1280; /* TW */
+ else if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) tempbx = 1400; /* TW */
+ }
+ }
+ tempcx = (tempcx - tempbx) >> 2; /* HT-HDE / 4 */
+
+ push1 = tempax;
+
+ tempax += tempbx;
+
+ if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;
+
+ push2 = tempax;
+
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ if(!SiS_Pr->SiS_IF_DEF_DSTN){
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) tempcx = 0x0028;
+ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempcx = 0x0030;
+ else if( (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) ||
+ (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) ) {
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+ tempcx = 0x0017;
+#ifdef TWNEWPANEL
+ tempcx = 0x0018;
+#endif
+ } else {
+ tempcx = 0x0017; /* A901; other 301B BIOS 0x0018; */
+ }
+ } else {
+ tempcx = 0x0018;
+ }
+ }
+ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) tempcx = 0x0018;
+ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempcx = 0x0040;
+ else if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) tempcx = 0x0030;
+ }
+ }
+
+ tempcx += tempax; /* lcdhrs */
+ if(tempcx >= SiS_Pr->SiS_HT) tempcx -= SiS_Pr->SiS_HT;
+
+ tempax = tempcx >> 3; /* BPLHRS */
+ temp = tempax & 0x00FF;
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x14,temp); /* Part1_14h; TW: Panel Link Horizontal Retrace Start */
+
+ temp = (tempax & 0x00FF) + 10;
+
+ /* TW: Inserted this entire "if"-section from 650/LVDS BIOS */
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ if(!SiS_Pr->SiS_IF_DEF_DSTN){
+ if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+ temp += 6;
+ if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel800x600) {
+ temp++;
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1024x768) {
+ temp += 7;
+ if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1600x1200) {
+ temp -= 10;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ temp &= 0x1F;
+ temp |= ((tempcx & 0x0007) << 5);
+ if(SiS_Pr->SiS_IF_DEF_FSTN) temp = 0x20;
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x15,temp); /* Part1_15h; TW: Panel Link Horizontal Retrace End/Skew */
+
+ tempbx = push2;
+ tempcx = push1; /* lcdhdes */
+
+ temp = (tempcx & 0x0007); /* BPLHDESKEW */
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1A,temp); /* Part1_1Ah; TW: Panel Link Vertical Retrace Start (2:0) */
+
+ tempcx >>= 3; /* BPLHDES */
+ temp = (tempcx & 0x00FF);
+ if(ModeNo == 0x5b) temp--; /* fix fstn mode=5b */
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x16,temp); /* Part1_16h; TW: Panel Link Horizontal Display Enable Start */
+
+ if(HwDeviceExtension->jChipType < SIS_315H) { /* TW: Not done in LVDS BIOS 1.10.07 */
+ if(tempbx & 0x07) tempbx += 8; /* TW: Done in 630/301B and 630/LVDS BIOSes */
+ }
+ tempbx >>= 3; /* BPLHDEE */
+ temp = tempbx & 0x00FF;
+ if(ModeNo == 0x5b) temp--; /* fix fstn mode=5b */
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x17,temp); /* Part1_17h; TW: Panel Link Horizontal Display Enable End */
+
+ /* 2. Vertical setup */
+
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+
+ /* TW: This entire section from 630/301B and 630/LVDS/LVDS+CH BIOS */
+ tempcx = SiS_Pr->SiS_VGAVT;
+ tempbx = SiS_Pr->SiS_VGAVDE;
+ if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) {
+ if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+ tempbx = 600;
+ if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel800x600) {
+ tempbx = 768;
+ if( (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1024x768) &&
+ (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1152x768) ) {
+ tempbx = 600;
+ }
+ }
+ }
+ }
+ tempcx -= tempbx;
+
+ } else {
+
+ tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE; /* VGAVT-VGAVDE */
+
+ }
+
+ tempbx = SiS_Pr->SiS_LCDVDES; /* VGAVDES */
+ push1 = tempbx;
+
+ tempax = SiS_Pr->SiS_VGAVDE;
+
+ if((SiS_Pr->SiS_IF_DEF_TRUMPION == 0) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))
+ && (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480)) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ if(!SiS_Pr->SiS_IF_DEF_DSTN){
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) tempax = 600;
+ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempax = 768;
+ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) tempax = 600; /* TW */
+ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) tempax = 768; /* TW */
+ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempax = 1024; /* TW */
+ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempax = 1050; /* TW */
+ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempax = 1200; /* TW */
+ else tempax = 600;
+ }
+ }
+ }
+
+ tempbx += tempax;
+ if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
+
+ push2 = tempbx;
+
+ tempcx >>= 1;
+
+ if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480)){
+ if(!SiS_Pr->SiS_IF_DEF_DSTN){
+ if( (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) ||
+ (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) ) { /* TW: @@@ TEST - not in BIOS! */
+ tempcx = 0x0001;
+ } else if( (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) ||
+ (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) ) {
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+ tempcx = 0x0002;
+#ifdef TWNEWPANEL
+ tempcx = 0x0003;
+#endif
+ } else {
+ tempcx = 0x0002; /* TW: A901; other 301B BIOS sets 0x0003; */
+ }
+ } else tempcx = 0x0003;
+ }
+ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) tempcx = 0x0003;
+ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempcx = 0x0001;
+ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempcx = 0x0001;
+ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempcx = 0x0001;
+ else tempcx = 0x0057;
+ }
+ }
+
+ tempbx += tempcx; /* BPLVRS */
+
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+ tempbx++;
+ }
+
+ if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
+
+ temp = tempbx & 0x00FF;
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,temp); /* Part1_18h; TW: Panel Link Vertical Retrace Start */
+
+ tempcx >>= 3;
+
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ if( (HwDeviceExtension->jChipType < SIS_315H) &&
+ (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) ) tempcx = 0x0001;
+ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempcx = 0x0002;
+ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempcx = 0x0002;
+ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) tempcx = 0x0003;
+ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) tempcx = 0x0005;
+ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) tempcx = 0x0005;
+ else if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+ tempcx = 0x0004;
+#ifdef TWNEWPANEL
+ tempcx = 0x0005;
+#endif
+ } else {
+ tempcx = 0x0004; /* A901; Other BIOS sets 0x0005; */
+ }
+ } else {
+ tempcx = 0x0005;
+ }
+ }
+ }
+
+ tempcx = tempcx + tempbx + 1; /* BPLVRE */
+ temp = tempcx & 0x000F;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xf0,temp); /* Part1_19h; TW: Panel Link Vertical Retrace End (3:0); Misc. */
+
+ temp = ((tempbx & 0x0700) >> 8) << 3; /* BPLDESKEW =0 */
+ if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
+ if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) temp |= 0x40;
+ if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) { /* TW: Inserted from 650/LVDS 1.10.07 */
+ temp |= 0x80;
+ }
+ } else {
+ if( (HwDeviceExtension->jChipType == SIS_630) ||
+ (HwDeviceExtension->jChipType == SIS_730) ) {
+ if(HwDeviceExtension->jChipRevision >= 0x30) {
+ temp |= 0x80;
+ }
+ }
+ }
+ }
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,0x87,temp); /* Part1_1Ah; TW: Panel Link Control Signal (7:3); Vertical Retrace Start (2:0) */
+
+ if (HwDeviceExtension->jChipType < SIS_315H) {
+
+#ifdef SIS300 /* 300 series */
+
+ tempeax = SiS_Pr->SiS_VGAVDE << 6;
+ temp = (USHORT)(tempeax % (ULONG)SiS_Pr->SiS_VDE);
+ tempeax = tempeax / (ULONG)SiS_Pr->SiS_VDE;
+ if(temp != 0) tempeax++;
+ tempebx = tempeax; /* BPLVCFACT */
+
+ if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
+ tempebx = 0x003F;
+ }
+
+ temp = (USHORT)(tempebx & 0x00FF);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1E,temp); /* Part1_1Eh; TW: Panel Link Vertical Scaling Factor */
+
+#endif /* SIS300 */
+
+ } else {
+
+#ifdef SIS315H /* 310/325 series */
+
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1E,0x23);
+
+ tempeax = SiS_Pr->SiS_VGAVDE << 18;
+ temp = (USHORT)(tempeax % (ULONG)SiS_Pr->SiS_VDE);
+ tempeax = tempeax / SiS_Pr->SiS_VDE;
+ if(temp != 0) tempeax++;
+ tempebx = tempeax; /* BPLVCFACT */
+ tempvcfact = tempeax;
+ temp = (USHORT)(tempebx & 0x00FF);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x37,temp); /* Part1_37h; TW: Panel Link Vertical Scaling Factor */
+ temp = (USHORT)((tempebx & 0x00FF00) >> 8);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x36,temp); /* Part1_36h; TW: Panel Link Vertical Scaling Factor */
+ temp = (USHORT)((tempebx & 0x00030000) >> 16);
+ if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x35,temp); /* Part1_35h; TW: Panel Link Vertical Scaling Factor */
+
+#endif /* SIS315H */
+
+ }
+
+ tempbx = push2; /* p bx temppush1 BPLVDEE */
+ tempcx = push1;
+
+ push1 = temp; /* TW: For 630/301B and 630/LVDS */
+
+ if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+ if(!SiS_Pr->SiS_IF_DEF_DSTN){
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
+ if(resinfo == 15) tempcx++;
+ if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) {
+ if(resinfo == 7) tempcx++;
+ }
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
+ if(resinfo == 7) tempcx++;
+ if(resinfo == 8) tempcx++; /* TW: Doesnt make sense anyway... */
+ } else if(resinfo == 8) tempcx++;
+ } else {
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
+ if(resinfo == 7) tempcx++;
+ }
+ }
+ }
+ }
+
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
+ tempcx = SiS_Pr->SiS_VGAVDE;
+ tempbx = SiS_Pr->SiS_VGAVDE - 1;
+ }
+
+ temp = ((tempbx & 0x0700) >> 8) << 3;
+ temp |= ((tempcx & 0x0700) >> 8);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1D,temp); /* Part1_1Dh; TW: Vertical Display Overflow; Control Signal */
+
+ temp = tempbx & 0x00FF;
+ if(SiS_Pr->SiS_IF_DEF_FSTN) temp++;
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1C,temp); /* Part1_1Ch; TW: Panel Link Vertical Display Enable End */
+
+ temp = tempcx & 0x00FF;
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1B,temp); /* Part1_1Bh; TW: Panel Link Vertical Display Enable Start */
+
+ /* 3. Additional horizontal setup (scaling, etc) */
+
+ tempecx = SiS_Pr->SiS_VGAHDE;
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ if(modeflag & HalfDCLK)
+ tempecx >>= 1;
+ }
+ tempebx = SiS_Pr->SiS_HDE;
+ if(tempecx == tempebx) tempeax = 0xFFFF;
+ else {
+ tempeax = tempecx;
+ tempeax <<= 16;
+ temp = (USHORT)(tempeax % tempebx);
+ tempeax = tempeax / tempebx;
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ if(temp) tempeax++;
+ }
+ }
+ tempecx = tempeax;
+
+ if (HwDeviceExtension->jChipType >= SIS_315H) {
+ tempeax = SiS_Pr->SiS_VGAHDE;
+ if(modeflag & HalfDCLK)
+ tempeax >>= 1;
+ tempeax <<= 16;
+ tempeax = (tempeax / tempecx) - 1;
+ } else {
+ tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1;
+ }
+ tempecx <<= 16;
+ tempecx |= (tempeax & 0xFFFF);
+ temp = (USHORT)(tempecx & 0x00FF);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1F,temp); /* Part1_1Fh; TW: Panel Link DDA Operational Number in each horiz. line */
+
+ tempbx = SiS_Pr->SiS_VDE;
+ if (HwDeviceExtension->jChipType >= SIS_315H) {
+ tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
+ tempbx = (USHORT)(tempeax & 0x0FFFF);
+ } else {
+ tempax = SiS_Pr->SiS_VGAVDE << 6;
+ tempbx = push1;
+ tempbx &= 0x3f;
+ if(tempbx == 0) tempbx = 64;
+ tempax = tempax / tempbx;
+ tempbx = tempax;
+ }
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempbx--;
+ if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) tempbx = 1;
+
+ temp = ((tempbx & 0xFF00) >> 8) << 3;
+ temp |= (USHORT)((tempecx & 0x0700) >> 8);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x20,temp); /* Part1_20h; TW: Overflow register */
+
+ temp = tempbx & 0x00FF;
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x21,temp); /* Part1_21h; TW: Panel Link Vertical Accumulator Register */
+
+ tempecx >>= 16; /* BPLHCFACT */
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+ if(modeflag & HalfDCLK) tempecx >>= 1;
+ }
+ temp = (USHORT)((tempecx & 0xFF00) >> 8);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x22,temp); /* Part1_22h; TW: Panel Link Horizontal Scaling Factor High */
+
+ temp = (USHORT)(tempecx & 0x00FF);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x23,temp); /* Part1_22h; TW: Panel Link Horizontal Scaling Factor Low */
+
+ /* 630/301B and 630/LVDS do something for 640x480 panels here */
+
+#ifdef SIS315H
+ /* TW: DSTN/FSTN initialisation - hardcoded for 320x480 panel */
+ if(SiS_Pr->SiS_IF_DEF_DSTN) {
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1E,0x01);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x25,0x00);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x26,0x00);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x27,0x00);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x28,0x87);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x29,0x5A);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2A,0x4B);
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x007,0x03);
+ tempbx = SiS_Pr->SiS_HDE + 64; /*Blps = lcdhdee(lcdhdes+HDE) + 64*/
+ temp = tempbx & 0x00FF;
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x38,temp);
+ temp=((tempbx & 0xFF00) >> 8) << 3;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp);
+ tempbx += 32; /*Blpe=lBlps+32*/
+ temp = tempbx & 0x00FF;
+ if(SiS_Pr->SiS_IF_DEF_FSTN) temp=0;
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x39,temp);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3A,0x00); /*Bflml=0*/
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x007,0x00);
+ tempbx = SiS_Pr->SiS_VDE / 2;
+ temp = tempbx & 0x00FF;
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3B,temp);
+ temp = ((tempbx & 0xFF00) >> 8) << 3;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);
+ tempeax = SiS_Pr->SiS_HDE << 2; /* BDxFIFOSTOP = (HDE*4)/128 */
+ tempebx = 128;
+ temp = (USHORT)(tempeax % tempebx);
+ tempeax = tempeax / tempebx;
+ if(temp != 0) tempeax++;
+ temp = (USHORT)(tempeax & 0x003F);
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x45,~0x0FF,temp);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3F,0x00); /* BDxWadrst0 */
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3E,0x00);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3D,0x10);
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x040,0x00);
+ tempax = SiS_Pr->SiS_HDE >> 4; /* BDxWadroff = HDE*4/8/8 */
+ pushcx = tempax;
+ temp = tempax & 0x00FF;
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x43,temp);
+ temp = ((tempax & 0xFF00) >> 8) << 3;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x0F8,temp);
+ tempax = SiS_Pr->SiS_VDE; /*BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
+ tempeax = (tempax * pushcx);
+ tempebx = 0x00100000 + tempeax;
+ temp = (USHORT)tempebx & 0x000000FF;
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x42,temp);
+ temp = (USHORT)((tempebx & 0x0000FF00)>>8);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x41,temp);
+ temp = (USHORT)((tempebx & 0x00FF0000)>>16);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x40,temp);
+ temp = (USHORT)(((tempebx & 0x01000000)>>24) << 7);
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x080,temp);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2F,0x03);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x03,0x50);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x04,0x00);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2F,0x01);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x13,0x00);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86); /* Unlock */
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1e,0x62);
+ if(SiS_Pr->SiS_IF_DEF_FSTN){
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2b,0x1b);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2c,0xe3);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1e,0x62);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2e,0x04);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2f,0x42);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,0x01);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2b,0x02);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2c,0x00);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2d,0x00);
+ }
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0f,0x30);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1e,0x7d);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2e,0xe0);
+ }
+#endif /* SIS315H */
+
+ return;
+
+}
+
+#ifdef SIS315H
+void
+SiS_CRT2AutoThreshold(SiS_Private *SiS_Pr, USHORT BaseAddr)
+{
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40);
+}
+#endif
+
+
+/* TW: For LVDS / 302b/lv - LCDA (this must only be called on 310/325 series!) */
+/* TW: Double-checked against 650/LVDS and 650/301 BIOS */
+void
+SiS_SetGroup1_LCDA(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex)
+{
+ USHORT modeflag,resinfo;
+ USHORT push1,push2,tempax,tempbx,tempcx,temp;
+ ULONG tempeax=0,tempebx,tempecx,tempvcfact;
+
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { /* TW: From 650/LVDS BIOS */
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04); /* TW: From 650/LVDS BIOS */
+ }
+
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { /* TW: From 650/LVDS 1.10.07 */
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x00); /* TW: From 650/LVDS 1.10.07 */
+ } else {
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2D,0x0f); /* TW: From 650/301Lvx 1.10.6s */
+ }
+
+ if(ModeNo<=0x13) {
+ modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+ resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+ } else {
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ }
+
+ tempax = SiS_Pr->SiS_LCDHDES;
+ tempbx = SiS_Pr->SiS_HDE;
+ tempcx = SiS_Pr->SiS_HT;
+
+ if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) {
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempbx = 1024;
+ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempbx = 1400;
+ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempbx = 1600;
+ else tempbx = 1280;
+
+ }
+ tempcx -= tempbx; /* HT-HDE */
+ push1 = tempax;
+ tempax += tempbx; /* lcdhdee */
+ tempbx = SiS_Pr->SiS_HT;
+ if(tempax >= tempbx) tempax -= tempbx;
+
+ push2 = tempax; /* push ax lcdhdee */
+
+ tempcx >>= 2;
+
+ /* TW: Inserted from 650/301LVx 1.10.6s */
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+ if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) tempcx = 0x28;
+ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempcx = 0x30;
+ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempcx = 0x18;
+ else tempcx = 0x30;
+ }
+ }
+
+ tempcx += tempax; /* lcdhrs */
+ if(tempcx >= tempbx) tempcx -= tempbx;
+ /* v ah,cl */
+ tempax = tempcx;
+ tempax >>= 3; /* BPLHRS */
+ temp = tempax & 0x00FF;
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x14,temp); /* Part1_14h */
+
+ temp += 10;
+ temp &= 0x1F;
+ temp |= ((tempcx & 0x07) << 5);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x15,temp); /* Part1_15h */
+
+ tempbx = push2; /* lcdhdee */
+ tempcx = push1; /* lcdhdes */
+ temp = (tempcx & 0x00FF);
+ temp &= 0x07; /* BPLHDESKEW */
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1A,temp); /* Part1_1Ah */
+
+ tempcx >>= 3; /* BPLHDES */
+ temp = tempcx & 0x00FF;
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x16,temp); /* Part1_16h */
+
+ if(tempbx & 0x07) tempbx += 8;
+ tempbx >>= 3; /* BPLHDEE */
+ temp = tempbx & 0x00FF;
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x17,temp); /* Part1_17h */
+
+ tempcx = SiS_Pr->SiS_VGAVT;
+ tempbx = SiS_Pr->SiS_VGAVDE;
+ tempcx -= tempbx; /* GAVT-VGAVDE */
+ tempbx = SiS_Pr->SiS_LCDVDES; /* VGAVDES */
+ push1 = tempbx; /* push bx temppush1 */
+ if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0){
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempax = 768;
+ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempax = 1024;
+ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempax = 1050;
+ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempax = 1200;
+ else tempax = 960;
+#if 0 /* TW: Removed (650/LVDS BIOS) */
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ tempax = SiS_Pr->SiS_VGAVDE;
+ }
+ }
+#endif
+ } else tempax = SiS_Pr->SiS_VGAVDE; /* Trumpion */
+
+ tempbx += tempax;
+ tempax = SiS_Pr->SiS_VT; /* VT */
+ if(tempbx >= tempax) tempbx -= tempax;
+
+ push2 = tempbx; /* push bx temppush2 */
+ tempcx >>= 2; /* TO CHECK - was 1 */
+
+ /* TW: Inserted from 650/301LVx 1.10.6s */
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+ if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) tempcx = 1;
+ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempcx = 3;
+ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) tempcx = 3;
+ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempcx = 1;
+ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempcx = 1;
+ else tempcx = 0x0057;
+ }
+ }
+
+ tempbx += tempcx;
+ tempbx++; /* BPLVRS */
+ if(tempbx >= tempax) tempbx -= tempax;
+ temp = tempbx & 0x00FF;
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,temp); /* Part1_18h */
+
+ tempcx >>= 3;
+ tempcx += tempbx;
+ tempcx++; /* BPLVRE */
+ temp = tempcx & 0x00FF;
+ temp &= 0x0F;
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+ /* TW: Inserted from 650/LVDS BIOS */
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xf0,temp);
+ } else {
+ /* TW: Inserted from 650/301LVx 1.10.6s */
+ temp |= 0xC0;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp); /* Part1_19h */
+ }
+
+ temp = (tempbx & 0xFF00) >> 8;
+ temp &= 0x07;
+ temp <<= 3; /* BPLDESKEW =0 */
+ tempbx = SiS_Pr->SiS_VGAVDE;
+ if(tempbx != SiS_Pr->SiS_VDE) temp |= 0x40;
+ if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) temp |= 0x40;
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+ /* TW: Inserted from 650/LVDS 1.10.07 */
+ if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) temp |= 0x80;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,0x87,temp); /* Part1_1Ah */
+ } else {
+ /* TW: Inserted from 650/301LVx 1.10.6s */
+ if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
+ if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80;
+ }
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,0x87,temp); /* Part1_1Ah */
+ }
+
+ tempbx = push2; /* p bx temppush2 BPLVDEE */
+ tempcx = push1; /* pop cx temppush1 NPLVDES */
+ push1 = (USHORT)(tempeax & 0xFFFF);
+
+ if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
+ if(resinfo == 7) tempcx++;
+ }
+ }
+ /* TW: Inserted from 650/301LVx+LVDS BIOSes */
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
+ tempbx = SiS_Pr->SiS_VGAVDE;
+ tempcx = tempbx;
+ tempbx--;
+ }
+
+ temp = (tempbx & 0xFF00) >> 8;
+ temp &= 0x07;
+ temp <<= 3;
+ temp = temp | (((tempcx & 0xFF00) >> 8) & 0x07);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1D,temp); /* Part1_1Dh */
+
+ temp = tempbx & 0x00FF;
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1C,temp); /* Part1_1Ch */
+
+ temp = tempcx & 0x00FF;
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1B,temp); /* Part1_1Bh */
+
+ tempecx = SiS_Pr->SiS_VGAVT;
+ tempebx = SiS_Pr->SiS_VDE;
+ tempeax = SiS_Pr->SiS_VGAVDE;
+ tempecx -= tempeax; /* VGAVT-VGAVDE */
+ tempeax <<= 18;
+ temp = (USHORT)(tempeax % tempebx);
+ tempeax = tempeax / tempebx;
+ if(temp) tempeax++;
+ tempebx = tempeax; /* BPLVCFACT */
+ tempvcfact = tempeax;
+ temp = (USHORT)(tempebx & 0x00FF);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x37,temp);
+
+ temp = (USHORT)((tempebx & 0x00FF00) >> 8);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x36,temp);
+
+ temp = (USHORT)((tempebx & 0x00030000) >> 16);
+ if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x35,temp);
+
+ tempecx = SiS_Pr->SiS_VGAHDE;
+ tempebx = SiS_Pr->SiS_HDE;
+ tempeax = tempecx;
+ tempeax <<= 16;
+ temp = tempeax % tempebx;
+ tempeax = tempeax / tempebx;
+ if(temp) tempeax++;
+ if(tempebx == tempecx) tempeax = 0xFFFF;
+ tempecx = tempeax;
+ tempeax = SiS_Pr->SiS_VGAHDE;
+ tempeax <<= 16;
+ tempeax = tempeax / tempecx;
+ tempecx <<= 16;
+ tempeax--;
+ tempecx = tempecx | (tempeax & 0xFFFF);
+ temp = (USHORT)(tempecx & 0x00FF);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1F,temp); /* Part1_1Fh */
+
+ tempeax = SiS_Pr->SiS_VGAVDE;
+ tempeax <<= 18;
+ tempeax = tempeax / tempvcfact;
+ tempbx = (USHORT)(tempeax & 0x0FFFF);
+
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempbx--;
+
+ if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) tempbx = 1;
+
+ temp = ((tempbx & 0xFF00) >> 8) << 3;
+ temp = temp | (USHORT)(((tempecx & 0x0000FF00) >> 8) & 0x07);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x20,temp); /* Part1_20h */
+
+ temp = tempbx & 0x00FF;
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x21,temp); /* Part1_21h */
+
+ tempecx >>= 16; /* BPLHCFACT */
+ if(modeflag & HalfDCLK) tempecx >>= 1;
+ temp = (USHORT)((tempecx & 0x0000FF00) >> 8);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x22,temp); /* Part1_22h */
+
+ temp=(USHORT)(tempecx & 0x000000FF);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x23,temp);
+
+#if 0
+ /* TW: Missing code (calles int 2f) (650/301LVx 1.10.6s; 1.10.7w doesn't do this) */
+ if(xxx()) {
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0e,0xda);
+ }
+#endif
+
+ /* TW: Only for 650/LVDS and 30xLV/30xLVX */
+ if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBInfo & (VB_SIS30xLV|VB_SIS30xNEW))){
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1e,0x20);
+ }
+
+ return;
+}
+
+/* TW: Double-checked against 650/LVDS (1.10.07) and 650/301 BIOS */
+void SiS_SetCRT2Offset(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,
+ USHORT ModeIdIndex ,USHORT RefreshRateTableIndex,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ USHORT offset;
+ UCHAR temp;
+
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return;
+
+ offset = SiS_GetOffset(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+ HwDeviceExtension);
+ temp = (UCHAR)(offset & 0xFF);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,temp);
+ temp = (UCHAR)((offset & 0xFF00) >> 8);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x09,temp);
+ temp = (UCHAR)(((offset >> 3) & 0xFF) + 1);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x03,temp);
+}
+
+/* TW: Checked with 650/LVDS and 650/301 BIOS */
+USHORT
+SiS_GetOffset(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ USHORT temp,colordepth;
+ USHORT modeinfo,index,infoflag;
+
+ if(SiS_Pr->UseCustomMode) {
+ infoflag = SiS_Pr->CInfoFlag;
+ temp = SiS_Pr->CHDisplay / 16;
+ } else {
+ infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+ modeinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeInfo;
+
+ if(HwDeviceExtension->jChipType < SIS_315H ) {
+ index = (modeinfo >> 4) & 0xFF;
+ } else {
+ index = (modeinfo >> 8) & 0xFF;
+ }
+
+ temp = SiS_Pr->SiS_ScreenOffset[index];
+ }
+
+ colordepth = SiS_GetColorDepth(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex);
+
+ if(infoflag & InterlaceMode) temp <<= 1;
+
+ temp *= colordepth;
+
+ /* TW: For 1400x1050 and 856x480 */
+ if( ( ((ModeNo >= 0x26) && (ModeNo <= 0x28)) ||
+ ModeNo == 0x3f ||
+ ModeNo == 0x42 ||
+ ModeNo == 0x45 ) ||
+ (SiS_Pr->UseCustomMode && (SiS_Pr->CHDisplay % 16)) ) {
+ colordepth >>= 1;
+ temp += colordepth;
+ }
+
+ return(temp);
+}
+
+/* TW: Checked with 650/LVDS BIOS */
+USHORT
+SiS_GetColorDepth(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+{
+ USHORT ColorDepth[6] = { 1, 2, 4, 4, 6, 8};
+ SHORT index;
+ USHORT modeflag;
+
+ if(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;
+ }
+
+ index = (modeflag & ModeInfoFlag) - ModeEGA;
+ if(index < 0) index = 0;
+ return(ColorDepth[index]);
+}
+
+/* TW: Checked against 630/301/301B/LVDS, 650/301LVx/LVDS */
+void
+SiS_SetCRT2Sync(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+ USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ USHORT tempah=0,tempbl,infoflag,flag;
+
+ flag = 0;
+ tempbl = 0xC0;
+
+ infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { /* LVDS */
+
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ tempah = SiS_Pr->SiS_LCDInfo;
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ tempbl = tempah & 0xc0;
+ }
+ if(SiS_Pr->SiS_LCDInfo & LCDSync) {
+ flag = 1;
+ }
+ }
+ if(flag != 1) tempah = infoflag >> 8;
+ tempah &= 0xC0;
+ tempah |= 0x20;
+ if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
+
+ if (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
+ /* TW: BIOS does something here @@@ */
+ }
+
+ tempah &= 0x3f;
+ tempah |= tempbl;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
+
+ } else {
+
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+
+#ifdef SIS300 /* ---- 300 series --- */
+
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { /* 630 - 301B */
+
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ tempah = SiS_Pr->SiS_LCDInfo;
+ if(SiS_Pr->SiS_LCDInfo & LCDSync) {
+ flag = 1;
+ }
+ }
+ if(flag != 1) tempah = infoflag >> 8;
+ tempah &= 0xC0;
+ tempah |= 0x20;
+
+ if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
+
+ if (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
+ /* TW: BIOS does something here @@@ */
+ }
+
+ tempah &= 0x3f;
+ tempah |= tempbl;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
+
+ } else { /* 630 - 301 */
+
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ tempah = SiS_Pr->SiS_LCDInfo;
+ if(SiS_Pr->SiS_LCDInfo & LCDNonExpandingShift) { /* ! */
+ flag = 1;
+ }
+ }
+ if(flag != 1) tempah = infoflag >> 8;
+ tempah &= 0xC0;
+ tempah |= 0x30;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x3F,tempah);
+
+ }
+
+#endif /* SIS300 */
+
+ } else {
+
+#ifdef SIS315H /* ----- 310/325 series ---- */
+
+ if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { /* 310/325 - 301LV/LVX */
+
+ tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37);
+ tempah &= 0xC0;
+ tempah |= 0x20;
+ if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
+
+ } else { /* 310/325 - 301, 301B */
+
+ tempah = infoflag >> 8;
+ tempah &= 0xC0;
+ tempah |= 0x20;
+
+ if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
+
+ if (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
+ /* TW: BIOS does something here @@@ */
+ }
+
+ tempah &= 0x3f;
+ tempah |= tempbl;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
+
+ }
+#endif /* SIS315H */
+ }
+ }
+}
+
+/* TW: Set CRT2 FIFO on 300/630/730 */
+/* TW: Checked against 630/301B BIOS; BIOS does not set PCI registers */
+#ifdef SIS300
+void
+SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ USHORT temp,index;
+ USHORT modeidindex,refreshratetableindex;
+ USHORT VCLK=0,MCLK,colorth=0,data2=0;
+ USHORT tempal, tempah, tempbx, tempcl, tempax;
+ USHORT CRT1ModeNo,CRT2ModeNo;
+ USHORT SelectRate_backup;
+ ULONG data,eax;
+ const UCHAR LatencyFactor[] = {
+ 97, 88, 86, 79, 77, 00, /*; 64 bit BQ=2 */
+ 00, 87, 85, 78, 76, 54, /*; 64 bit BQ=1 */
+ 97, 88, 86, 79, 77, 00, /*; 128 bit BQ=2 */
+ 00, 79, 77, 70, 68, 48, /*; 128 bit BQ=1 */
+ 80, 72, 69, 63, 61, 00, /*; 64 bit BQ=2 */
+ 00, 70, 68, 61, 59, 37, /*; 64 bit BQ=1 */
+ 86, 77, 75, 68, 66, 00, /*; 128 bit BQ=2 */
+ 00, 68, 66, 59, 57, 37 /*; 128 bit BQ=1 */
+ };
+ const UCHAR LatencyFactor730[] = {
+ 69, 63, 61,
+ 86, 79, 77,
+ 103, 96, 94,
+ 120,113,111,
+ 137,130,128, /* <-- last entry, data below */
+ 137,130,128, /* to avoid using illegal values */
+ 137,130,128,
+ 137,130,128,
+ 137,130,128,
+ 137,130,128,
+ 137,130,128,
+ 137,130,128,
+ 137,130,128,
+ 137,130,128,
+ 137,130,128,
+ 137,130,128,
+ };
+ const UCHAR ThLowB[] = {
+ 81, 4, 72, 6, 88, 8,120,12,
+ 55, 4, 54, 6, 66, 8, 90,12,
+ 42, 4, 45, 6, 55, 8, 75,12
+ };
+ const UCHAR ThTiming[] = {
+ 1, 2, 2, 3, 0, 1, 1, 2
+ };
+
+ SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;
+
+ if(!SiS_Pr->CRT1UsesCustomMode) {
+
+ CRT1ModeNo = SiS_Pr->SiS_CRT1Mode; /* get CRT1 ModeNo */
+ SiS_SearchModeID(SiS_Pr,ROMAddr,&CRT1ModeNo,&modeidindex);
+ SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
+ SiS_Pr->SiS_SelectCRT2Rate = 0;
+ refreshratetableindex = SiS_GetRatePtrCRT2(SiS_Pr,ROMAddr,CRT1ModeNo,
+ modeidindex,HwDeviceExtension);
+
+ if(CRT1ModeNo >= 0x13) {
+ index = SiS_Pr->SiS_RefIndex[refreshratetableindex].Ext_CRTVCLK;
+ index &= 0x3F;
+ VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; /* Get VCLK */
+ data2 = SiS_Pr->SiS_ModeType - 2;
+ }
+
+ } else {
+
+ CRT1ModeNo = 0xfe;
+ VCLK = SiS_Pr->CSRClock; /* Get VCLK */
+ data2 = (SiS_Pr->CModeFlag & ModeInfoFlag) - 2;
+
+ }
+
+ if(CRT1ModeNo >= 0x13) {
+ if(HwDeviceExtension->jChipType == SIS_300) {
+ index = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x3A);
+ } else {
+ index = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1A);
+ }
+ index &= 0x07;
+ MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK; /* Get MCLK */
+
+#ifdef TWDEBUG
+ xf86DrvMsg(0, X_INFO, "FIFO2: CRT1Mode 0x%x VCLK %d MCLK %d modetype-2 = %d\n",
+ CRT1ModeNo, VCLK, MCLK, data2);
+#endif
+
+ switch(data2) { /* Get color depth */
+ case 0 : colorth = 1; break;
+ case 1 : colorth = 1; break;
+ case 2 : colorth = 2; break;
+ case 3 : colorth = 2; break;
+ case 4 : colorth = 3; break;
+ case 5 : colorth = 4; break;
+ default: colorth = 2; break;
+ }
+ data2 = (colorth * VCLK) / MCLK;
+
+ temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
+ temp = ((temp & 0x00FF) >> 6) << 1;
+ if(temp == 0) temp = 1;
+ temp <<= 2;
+ temp &= 0xff;
+
+ data2 = temp - data2;
+
+#ifdef TWDEBUG
+ xf86DrvMsg(0, X_INFO, "FIFO2: data2 (step1) = %d\n",
+ data2);
+#endif
+
+ if((28 * 16) % data2) {
+ data2 = (28 * 16) / data2;
+ data2++;
+ } else {
+ data2 = (28 * 16) / data2;
+ }
+
+#ifdef TWDEBUG
+ xf86DrvMsg(0, X_INFO, "FIFO2: data2 (step2) = %d\n",
+ data2);
+#endif
+
+ if(HwDeviceExtension->jChipType == SIS_300) {
+
+ tempah = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x18);
+ tempah &= 0x62;
+ tempah >>= 1;
+ tempal = tempah;
+ tempah >>= 3;
+ tempal |= tempah;
+ tempal &= 0x07;
+ tempcl = ThTiming[tempal];
+ tempbx = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16);
+ tempbx >>= 6;
+ tempah = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
+ tempah >>= 4;
+ tempah &= 0x0c;
+ tempbx |= tempah;
+ tempbx <<= 1;
+ tempal = ThLowB[tempbx + 1];
+ tempal *= tempcl;
+ tempal += ThLowB[tempbx];
+ data = tempal;
+
+ } else if(HwDeviceExtension->jChipType == SIS_730) {
+
+#ifndef LINUX_XF86
+ SiS_SetReg4(0xcf8,0x80000050);
+ eax = SiS_GetReg3(0xcfc);
+#else
+ eax = pciReadLong(0x00000000, 0x50);
+#endif
+ tempal = (USHORT)(eax >> 8);
+ tempal &= 0x06;
+ tempal <<= 5;
+
+#ifndef LINUX_XF86
+ SiS_SetReg4(0xcf8,0x800000A0);
+ eax = SiS_GetReg3(0xcfc);
+#else
+ eax = pciReadLong(0x00000000, 0xA0);
+#endif
+ temp = (USHORT)(eax >> 28);
+ temp &= 0x0F;
+ tempal |= temp;
+
+#ifdef TWDEBUG
+ xf86DrvMsg(0, X_INFO, "FIFO2: Latencyfactorindex = 0x%x\n", tempal);
+#endif
+
+ tempbx = tempal; /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */
+ tempbx = 0; /* -- do it like the BIOS anyway... */
+ tempax = tempbx;
+ tempbx &= 0xc0;
+ tempbx >>= 6;
+ tempax &= 0x0f;
+ tempax *= 3;
+ tempbx += tempax;
+
+ data = LatencyFactor730[tempbx];
+ data += 15;
+ temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
+ if(!(temp & 0x80)) data += 5;
+
+ } else {
+
+ index = 0;
+ temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
+ if(temp & 0x0080) index += 12;
+
+#ifndef LINUX_XF86
+ SiS_SetReg4(0xcf8,0x800000A0);
+ eax = SiS_GetReg3(0xcfc);
+#else
+ /* TW: We use pci functions X offers. We use tag 0, because
+ * we want to read/write to the host bridge (which is always
+ * 00:00.0 on 630, 730 and 540), not the VGA device.
+ */
+ eax = pciReadLong(0x00000000, 0xA0);
+#endif
+ temp = (USHORT)(eax >> 24);
+ if(!(temp&0x01)) index += 24;
+
+#ifndef LINUX_XF86
+ SiS_SetReg4(0xcf8,0x80000050);
+ eax = SiS_GetReg3(0xcfc);
+#else
+ eax = pciReadLong(0x00000000, 0x50);
+#endif
+ temp=(USHORT)(eax >> 24);
+ if(temp & 0x01) index += 6;
+
+ temp = (temp & 0x0F) >> 1;
+ index += temp;
+
+ data = LatencyFactor[index];
+ data += 15;
+ temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
+ if(!(temp & 0x80)) data += 5;
+ }
+
+#ifdef TWDEBUG
+ xf86DrvMsg(0, X_INFO, "FIFO2: latencyfactor (CRT1) = %d\n", data);
+#endif
+
+ data += data2; /* CRT1 Request Period */
+
+#ifdef TWDEBUG
+ xf86DrvMsg(0, X_INFO, "FIFO2: CRT1 request period = %d\n", data);
+#endif
+
+ CRT2ModeNo = ModeNo;
+ SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
+ SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
+ SiS_SearchModeID(SiS_Pr,ROMAddr,&CRT2ModeNo,&modeidindex);
+
+ refreshratetableindex = SiS_GetRatePtrCRT2(SiS_Pr,ROMAddr,CRT2ModeNo,
+ modeidindex,HwDeviceExtension);
+
+ index = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,CRT2ModeNo,modeidindex,
+ refreshratetableindex,HwDeviceExtension);
+ VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; /* Get VCLK */
+
+ data2 = SiS_Pr->SiS_ModeType - 2;
+ switch(data2) { /* Get color depth */
+ case 0 : colorth = 1; break;
+ case 1 : colorth = 1; break;
+ case 2 : colorth = 2; break;
+ case 3 : colorth = 2; break;
+ case 4 : colorth = 3; break;
+ case 5 : colorth = 4; break;
+ default: colorth = 2; break;
+ }
+
+#ifdef TWDEBUG
+ xf86DrvMsg(0, X_INFO, "FIFO2: CRT2Mode 0x%x VCLK %d MCLK %d modetype-2 = %d, colorth %d\n",
+ CRT2ModeNo, VCLK, MCLK, data2, colorth);
+#endif
+
+ data = data * VCLK * colorth;
+ if(data % (MCLK << 4)) {
+ data = data / (MCLK << 4);
+ data++;
+ } else {
+ data = data / (MCLK << 4);
+ }
+
+#ifdef TWDEBUG
+ xf86DrvMsg(0, X_INFO, "FIFO2: data (unclipped) = 0x%x\n", data);
+#endif
+
+ if(data <= 6) data = 6;
+ if(data > 0x14) data = 0x14;
+
+ temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x01);
+ if(HwDeviceExtension->jChipType == SIS_300) {
+ if(data <= 0x0f) temp = (temp & (~0x1F)) | 0x13;
+ else temp = (temp & (~0x1F)) | 0x16;
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+ temp = (temp & (~0x1F)) | 0x13;
+ }
+ } else {
+ if( ( (HwDeviceExtension->jChipType == SIS_630) ||
+ (HwDeviceExtension->jChipType == SIS_730) ) &&
+ (HwDeviceExtension->jChipRevision >= 0x30) ) /* 630s or 730(s?) */
+ {
+ temp = (temp & (~0x1F)) | 0x1b;
+ } else {
+ temp = (temp & (~0x1F)) | 0x16;
+ }
+ }
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0xe0,temp);
+
+ if( (HwDeviceExtension->jChipType == SIS_630) &&
+ (HwDeviceExtension->jChipRevision >= 0x30) ) /* 630s, NOT 730 */
+ {
+ if(data > 0x13) data = 0x13;
+ }
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,0xe0,data);
+
+ } else { /* If mode <= 0x13, we just restore everything */
+
+ SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
+ SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
+
+ }
+}
+#endif
+
+/* TW: Set FIFO on 310 series */
+#ifdef SIS315H
+void
+SiS_SetCRT2FIFO_310(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+
+ UCHAR CombCode[] = { 1, 1, 1, 4, 3, 1, 3, 4,
+ 4, 1, 4, 4, 5, 1, 5, 4};
+ UCHAR CRT2ThLow[] = { 39, 63, 55, 79, 78,102, 90,114,
+ 55, 87, 84,116,103,135,119,151};
+ USHORT temp3,tempax,tempbx,tempcx;
+ USHORT tempcl, tempch;
+ USHORT index;
+ USHORT CRT1ModeNo,CRT2ModeNo;
+ USHORT ModeIdIndex;
+ USHORT RefreshRateTableIndex;
+ USHORT SelectRate_backup;
+
+ SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;
+
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x01,0x3B);
+
+ if(!SiS_Pr->CRT1UsesCustomMode) {
+
+ CRT1ModeNo = SiS_Pr->SiS_CRT1Mode; /* get CRT1 ModeNo */
+ SiS_SearchModeID(SiS_Pr,ROMAddr,&CRT1ModeNo,&ModeIdIndex);
+
+ SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
+ SiS_Pr->SiS_SelectCRT2Rate = 0;
+
+ /* Get REFIndex for crt1 refreshrate */
+ RefreshRateTableIndex = SiS_GetRatePtrCRT2(SiS_Pr,ROMAddr,CRT1ModeNo,
+ ModeIdIndex,HwDeviceExtension);
+
+ index = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,CRT1ModeNo,ModeIdIndex,
+ RefreshRateTableIndex,HwDeviceExtension);
+ tempax = SiS_Pr->SiS_VCLKData[index].CLOCK; /* Get VCLK */
+
+ tempbx = SiS_GetColorDepth(SiS_Pr,ROMAddr,CRT1ModeNo,ModeIdIndex); /* Get colordepth */
+ tempbx >>= 1;
+ if(!tempbx) tempbx++;
+
+ } else {
+
+ tempax = SiS_Pr->CSRClock; /* Get VCLK */
+ tempbx = (SiS_Pr->CModeFlag & ModeInfoFlag) - 2;
+ switch(tempbx) { /* Get color depth */
+ case 0 : tempbx = 1; break;
+ case 1 : tempbx = 1; break;
+ case 2 : tempbx = 2; break;
+ case 3 : tempbx = 2; break;
+ case 4 : tempbx = 3; break;
+ case 5 : tempbx = 4; break;
+ default: tempbx = 2; break;
+ }
+
+ }
+
+ tempax *= tempbx;
+
+ tempbx = SiS_GetMCLK(SiS_Pr,ROMAddr, HwDeviceExtension); /* Get MCLK */
+
+ tempax /= tempbx;
+
+ tempbx = tempax;
+
+#if 0 /* TW: BIOS code is skrewed */
+ if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14) & 0x02) {
+ tempax = 16;
+ } else {
+ tempax = 8;
+ }
+#endif
+ tempax = 16;
+
+ tempax -= tempbx;
+
+ tempbx = tempax; /* tempbx = 16-DRamBus - DCLK*BytePerPixel/MCLK */
+
+ tempax = ((52 * 16) / tempbx);
+
+ if ((52*16 % tempbx) != 0) {
+ tempax++;
+ }
+ tempcx = tempax;
+ tempcx += 40;
+
+ /* get DRAM latency */
+ tempcl = (SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) >> 3) & 0x7; /* SR17[5:3] DRAM Queue depth */
+ tempch = (SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) >> 6) & 0x3; /* SR17[7:6] DRAM Grant length */
+
+ for (temp3 = 0; temp3 < 16; temp3 += 2) {
+ if ((CombCode[temp3] == tempcl) && (CombCode[temp3+1] == tempch)) {
+ temp3 = CRT2ThLow[temp3 >> 1];
+ }
+ }
+
+ tempcx += temp3; /* CRT1 Request Period */
+
+ CRT2ModeNo = ModeNo; /* get CRT2 ModeNo */
+ SiS_SearchModeID(SiS_Pr,ROMAddr,&CRT2ModeNo,&ModeIdIndex); /* Get ModeID Table */
+
+ SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
+ SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
+
+ RefreshRateTableIndex = SiS_GetRatePtrCRT2(SiS_Pr,ROMAddr,CRT2ModeNo,
+ ModeIdIndex,HwDeviceExtension);
+
+ index = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,CRT2ModeNo,ModeIdIndex,
+ RefreshRateTableIndex,HwDeviceExtension);
+ tempax = SiS_Pr->SiS_VCLKData[index].CLOCK; /* Get VCLK */
+
+ tempbx = SiS_GetColorDepth(SiS_Pr,ROMAddr,CRT2ModeNo,ModeIdIndex); /* Get colordepth */
+ tempbx >>= 1;
+ if(!tempbx) tempbx++;
+
+ tempax *= tempbx;
+
+ tempax *= tempcx;
+
+ tempbx = SiS_GetMCLK(SiS_Pr,ROMAddr, HwDeviceExtension); /* Get MCLK */
+ tempbx <<= 4;
+
+ tempcx = tempax;
+ tempax /= tempbx;
+ if(tempcx % tempbx) tempax++; /* CRT1 Request period * TCLK * BytePerPixel / (MCLK*16) */
+
+ if (tempax > 0x37) tempax = 0x37;
+
+ /* TW: 650/LVDS (1.10.07, 1.10.00), 650/301LV overrule calculated value; 315 does not */
+ if(HwDeviceExtension->jChipType == SIS_650) {
+ tempax = 0x04;
+ }
+
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3F,tempax);
+}
+
+USHORT
+SiS_GetMCLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ USHORT index;
+
+ index = SiS_Get310DRAMType(SiS_Pr,ROMAddr,HwDeviceExtension);
+ if(index >= 4) {
+ index -= 4;
+ return(SiS_Pr->SiS_MCLKData_1[index].CLOCK);
+ } else {
+ return(SiS_Pr->SiS_MCLKData_0[index].CLOCK);
+ }
+}
+#endif
+
+/* TW: Checked against 650/LVDS 1.10.07 BIOS */
+void
+SiS_GetLVDSDesData(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ USHORT modeflag;
+ USHORT PanelIndex,ResIndex;
+ const SiS_LVDSDesStruct *PanelDesPtr = NULL;
+
+ if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) ) {
+
+ SiS_GetLVDSDesPtrA(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+ &PanelIndex,&ResIndex);
+ switch (PanelIndex)
+ {
+ case 0: PanelDesPtr = SiS_Pr->LVDS1024x768Des_1; break; /* --- expanding --- */
+ case 1: PanelDesPtr = SiS_Pr->LVDS1280x1024Des_1; break;
+ case 2: PanelDesPtr = SiS_Pr->LVDS1400x1050Des_1; break;
+ case 3: PanelDesPtr = SiS_Pr->LVDS1600x1200Des_1; break;
+ case 4: PanelDesPtr = SiS_Pr->LVDS1024x768Des_2; break; /* --- non expanding --- */
+ case 5: PanelDesPtr = SiS_Pr->LVDS1280x1024Des_2; break;
+ case 6: PanelDesPtr = SiS_Pr->LVDS1400x1050Des_2; break;
+ case 7: PanelDesPtr = SiS_Pr->LVDS1600x1200Des_2; break;
+ default: PanelDesPtr = SiS_Pr->LVDS1024x768Des_1; break;
+ }
+
+ } else {
+
+ SiS_GetLVDSDesPtr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+ &PanelIndex,&ResIndex,HwDeviceExtension);
+
+ switch (PanelIndex)
+ {
+ case 0: PanelDesPtr = SiS_Pr->SiS_PanelType00_1; break; /* --- expanding --- | */
+ 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; /* --- non-expanding --- */
+ 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_CHTVUNTSCDesData; break;
+ case 33: PanelDesPtr = SiS_Pr->SiS_CHTVONTSCDesData; break;
+ case 34: PanelDesPtr = SiS_Pr->SiS_CHTVUPALDesData; break;
+ case 35: PanelDesPtr = SiS_Pr->SiS_CHTVOPALDesData; break;
+ default:
+ if(HwDeviceExtension->jChipType < SIS_315H)
+ PanelDesPtr = SiS_Pr->SiS_PanelType0e_1;
+ else
+ PanelDesPtr = SiS_Pr->SiS_PanelType01_1;
+ break;
+ }
+ }
+ SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
+ SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;
+
+ if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding){
+ if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+ if(ModeNo <= 0x13) {
+ modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+ if(!(modeflag & HalfDCLK)) {
+ SiS_Pr->SiS_LCDHDES = 632;
+ }
+ }
+ } else {
+ if(!(SiS_Pr->SiS_SetFlag & CRT2IsVGA)) {
+ if((HwDeviceExtension->jChipType < SIS_315H) || (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024)) { /* TW: New from 650/LVDS 1.10.07 */
+ if(SiS_Pr->SiS_LCDResInfo >= SiS_Pr->SiS_Panel1024x768){
+ if(ModeNo <= 0x13) {
+ modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+ if(!(modeflag & HalfDCLK)) {
+ SiS_Pr->SiS_LCDHDES = 320;
+ }
+ } else {
+ /* TW: New from 650/LVDS 1.10.07 */
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)
+ SiS_Pr->SiS_LCDHDES = 480;
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)
+ SiS_Pr->SiS_LCDHDES = 804;
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)
+ SiS_Pr->SiS_LCDHDES = 704;
+ if(!(modeflag & HalfDCLK)) {
+ SiS_Pr->SiS_LCDHDES = 320;
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)
+ SiS_Pr->SiS_LCDHDES = 632;
+ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)
+ SiS_Pr->SiS_LCDHDES = 542;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return;
+}
+
+/* TW: Checked against 630/LVDS (2.04.5c) and 650/LVDS (1.10.07) BIOS */
+void
+SiS_GetLVDSDesPtr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,USHORT *PanelIndex,
+ USHORT *ResIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ USHORT tempbx,tempal,modeflag;
+
+ if(ModeNo<=0x13) {
+ modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+ tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+ } else {
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+ }
+
+ tempbx = 0;
+ if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
+ tempbx = 32;
+ if((SiS_Pr->SiS_VBInfo & SetPALTV) && (!SiS_Pr->SiS_CHPALM)) tempbx += 2;
+ if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
+ /* TW: Nothing special needed for SOverscan */
+ /* PALM uses NTSC data, PALN uses PAL data */
+ }
+ }
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ tempbx = SiS_Pr->SiS_LCDTypeInfo;
+ if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) tempbx += 16;
+ /* TW: Inserted from 650/LVDS (1.10.07) BIOS */
+ if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
+ if(modeflag & HalfDCLK) tempbx += 16;
+ }
+ }
+ /* TW: Inserted from 630/LVDS and 650/LVDS (1.10.07) BIOS */
+ if(SiS_Pr->SiS_SetFlag & CRT2IsVGA) {
+ if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+ tempal = 0x07;
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+ if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x80) tempal++;
+ }
+ }
+ }
+
+ *PanelIndex = tempbx;
+ *ResIndex = tempal & 0x1F;
+}
+
+void
+SiS_GetLVDSDesPtrA(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,USHORT *PanelIndex,
+ USHORT *ResIndex)
+{
+ USHORT tempbx=0,tempal;
+
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+ tempbx = 3;
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
+ tempbx = 4;
+ } else tempbx = SiS_Pr->SiS_LCDResInfo - SiS_Pr->SiS_PanelMinLVDS;
+
+ if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) tempbx += 4;
+
+ if(ModeNo<=0x13)
+ tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+ else
+ tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+
+ *PanelIndex = tempbx;
+ *ResIndex = tempal & 0x1F;
+}
+
+/* TW: Checked against 650/LVDS (1.10.07), 650/301LV, 650/301LVx (!), 630/301 and 630/301B (II) BIOS */
+void
+SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT BaseAddr, USHORT ModeNo, USHORT ModeIdIndex,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ USHORT i,j,modeflag;
+ USHORT tempcl,tempah=0;
+#ifdef SIS300
+ USHORT temp;
+#endif
+#ifdef SIS315H
+ USHORT tempbl;
+#endif
+
+ if(ModeNo<=0x13) {
+ modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+ } else {
+ if(SiS_Pr->UseCustomMode) {
+ modeflag = SiS_Pr->CModeFlag;
+ } else {
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ }
+ }
+
+ /* TW: BIOS does not do this (neither 301 nor LVDS) */
+ /* (But it's harmless; see SetCRT2Offset) */
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x03,0x00); /* fix write part1 index 0 BTDRAM bit Bug */
+
+ /* TW: Removed 301B302B301LV302LV check here to match 650/LVDS BIOS */
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+
+ /* TW: 1. for LVDS/302B/302LV **LCDA** */
+
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40); /* FUNCTION CONTROL */
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2E,0xF7);
+
+ } else {
+
+ for(i=0,j=4; i<3; i++,j++) SiS_SetReg1(SiS_Pr->SiS_Part1Port,j,0);
+
+ tempcl = SiS_Pr->SiS_ModeType;
+
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+
+#ifdef SIS300 /* ---- 300 series ---- */
+
+ /* TW: Inserted entire if-section from 630/301B BIOS */
+ if((HwDeviceExtension->jChipType != SIS_300) &&
+ (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
+ temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32);
+ temp &= 0xef;
+ temp |= 0x02;
+ /* If 0x10 not set when using VGA2, monitor will stay black */
+ if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
+ temp |= 0x10;
+ temp &= 0xfd;
+ }
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
+ }
+
+ if(ModeNo > 0x13) {
+ tempcl -= ModeVGA;
+ if((tempcl > 0) || (tempcl == 0)) { /* TW: tempcl is USHORT -> always true! */
+ tempah = ((0x10 >> tempcl) | 0x80);
+ }
+ } else tempah = 0x80;
+
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0xA0;
+
+#endif /* SIS300 */
+
+ } else {
+
+#ifdef SIS315H /* ---- 310 series ---- */
+
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ if(SiS_Pr->SiS_VBInfo & CRT2DisplayFlag) {
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x08);
+ }
+ }
+
+ if(ModeNo > 0x13) {
+ tempcl -= ModeVGA;
+ if((tempcl > 0) || (tempcl == 0)) { /* TW: tempcl is USHORT -> always true! */
+ tempah = (0x08 >> tempcl);
+ if (tempah == 0) tempah = 1;
+ tempah |= 0x40;
+ }
+ } else tempah = 0x40;
+
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50;
+
+#endif /* SIS315H */
+
+ }
+
+ if(SiS_Pr->SiS_VBInfo & CRT2DisplayFlag) tempah = 0;
+
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,tempah); /* FUNCTION CONTROL */
+ } else {
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah); /* FUNCTION CONTROL */
+ }
+
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+
+ /* TW: 2. for 301 (301B, 302B 301LV, 302LV non-LCDA) */
+
+ tempah = 0x01;
+ if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+ tempah |= 0x02;
+ }
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
+ tempah ^= 0x05;
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
+ tempah ^= 0x01;
+ }
+ }
+
+ if(SiS_Pr->SiS_VBInfo & CRT2DisplayFlag) tempah = 0;
+
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+
+ /* --- 300 series --- */
+
+ tempah = (tempah << 5) & 0xFF;
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x01,tempah);
+ tempah = (tempah >> 5) & 0xFF;
+
+ } else {
+
+ /* --- 310 series --- */
+
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF8,tempah);
+
+ }
+
+ if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
+ tempah |= 0x10;
+ }
+
+ /* TW: Inserted from 630/301 BIOS */
+ if((HwDeviceExtension->jChipType < SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301)) {
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+ tempah |= 0x80;
+ }
+ } else {
+ tempah |= 0x80;
+ }
+
+ if(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)){
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+ tempah |= 0x20;
+ }
+ }
+
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah);
+
+ tempah = 0;
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ SiS_Pr->SiS_SetFlag |= RPLLDIV2XO;
+ tempah |= 0x40;
+ } else {
+ if(!(SiS_Pr->SiS_SetFlag & TVSimuMode)) {
+#ifdef oldHV
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV)) {
+#endif
+ SiS_Pr->SiS_SetFlag |= RPLLDIV2XO;
+ tempah |= 0x40;
+#ifdef oldHV
+ }
+#endif
+ }
+ }
+ } else {
+ SiS_Pr->SiS_SetFlag |= RPLLDIV2XO;
+ tempah |= 0x40;
+ }
+ }
+ /* TW: Inserted from 630/301LVx BIOS 1.10.6s */
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04)
+ tempah |= 0x40;
+ }
+ }
+
+ if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
+ (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960)) {
+ tempah |= 0x80;
+ }
+
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0C,tempah);
+
+ } else {
+
+ /* TW: 3. for LVDS */
+
+ /* TW: Inserted if-statement - Part1Port 0x2e not assigned on 300 series */
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+
+ /* TW: Inserted this entire section (BIOS 650/LVDS); added ModeType check
+ * (LVDS can only be slave in 8bpp modes)
+ */
+ tempah = 0x80;
+ if( (modeflag & CRT2Mode) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
+ if (SiS_Pr->SiS_VBInfo & DriverMode) {
+ tempah |= 0x02;
+ }
+ }
+
+ if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+ tempah |= 0x02;
+ }
+
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ tempah ^= 0x01;
+ }
+
+ if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
+ tempah = 1;
+ }
+
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah);
+
+ } else {
+
+ /* TW: (added ModeType check) */
+ tempah = 0;
+ if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
+ tempah |= 0x02;
+ }
+ tempah <<= 5;
+
+ if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
+
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x01,tempah);
+
+ }
+
+ }
+
+ }
+
+ /* TW: Inserted the entire following section */
+
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+
+#ifdef SIS315H
+ tempah = 0x04; /* For all bridges */
+ tempbl = 0xfb;
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+ tempah = 0x00;
+ if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr))
+ tempbl = 0xff;
+ }
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
+
+ /* TW: This in order to fix "TV-blue-bug" on 315+301 */
+ if(SiS_Pr->SiS_VBType & VB_SIS301) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xCF); /* For 301 */
+ } else {
+ if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xCF,0x30); /* For 301LV */
+ } else {
+ tempah = 0x30; /* For 301B */
+ tempbl = 0xcf;
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+ tempah = 0x00;
+ if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr)) {
+ tempbl = 0xff;
+ }
+ }
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
+ }
+ }
+
+ if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { /* For 301LV */
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,0xc0);
+ } else { /* For 301, 301B */
+ tempah = 0xc0;
+ tempbl = 0x3f;
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+ tempah = 0x00;
+ if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr)) {
+ tempbl = 0xff;
+ }
+ }
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl,tempah);
+ }
+
+ tempah = 0x00; /* For all bridges */
+ tempbl = 0x7f;
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+ tempbl = 0xff;
+ if(!(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr)))
+ tempah |= 0x80;
+ }
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
+
+#endif /* SIS315H */
+
+ } else if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+
+ SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
+
+ if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
+ ( (HwDeviceExtension->jChipType != SIS_300) &&
+ (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ) ) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x23,0x7F);
+ } else {
+ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x23,0x80);
+ }
+
+ }
+
+ } else { /* LVDS */
+
+#ifdef SIS315H
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+
+ if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+
+ tempah = 0x04;
+ tempbl = 0xfb;
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+ tempah = 0x00;
+ if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr))
+ tempbl = 0xff;
+ }
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
+
+ if(SiS_Pr->SiS_VBInfo & DisableCRT2Display)
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x00);
+
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,0x30);
+
+ }
+
+ }
+#endif
+
+ }
+
+}
+
+void
+SiS_GetCRT2Data(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+
+ SiS_GetCRT2DataLVDS(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+ HwDeviceExtension);
+ } else {
+
+ if((HwDeviceExtension->jChipType < SIS_315H) &&
+ (HwDeviceExtension->jChipType != SIS_300) &&
+ (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
+
+ SiS_GetCRT2Data301(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+ HwDeviceExtension);
+
+ /* TW: Need LVDS Data for LCD on 630/301B! */
+ SiS_GetCRT2DataLVDS(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+ HwDeviceExtension);
+
+ } else {
+
+ SiS_GetCRT2Data301(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+ HwDeviceExtension);
+ }
+
+ }
+
+ } else {
+
+ SiS_GetCRT2Data301(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+ HwDeviceExtension);
+ }
+
+ } else {
+
+ SiS_GetCRT2DataLVDS(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+ HwDeviceExtension);
+ }
+}
+
+/* Checked with 650/LVDS 1.10.07 BIOS */
+void
+SiS_GetCRT2DataLVDS(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ USHORT CRT2Index, ResIndex;
+ const SiS_LVDSDataStruct *LVDSData = NULL;
+
+ SiS_GetCRT2ResInfo(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
+
+ if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+
+ 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_GetCRT2PtrA(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+ &CRT2Index,&ResIndex);
+
+ switch (CRT2Index) {
+ case 0: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break;
+ case 1: LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_1; break;
+ case 2: LVDSData = SiS_Pr->SiS_LVDS1280x960Data_1; break;
+ case 3: LVDSData = SiS_Pr->SiS_LCDA1400x1050Data_1; break;
+ case 4: LVDSData = SiS_Pr->SiS_LCDA1600x1200Data_1; break;
+ case 5: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_2; break;
+ case 6: LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_2; break;
+ case 7: LVDSData = SiS_Pr->SiS_LVDS1280x960Data_2; break;
+ case 8: LVDSData = SiS_Pr->SiS_LCDA1400x1050Data_2; break;
+ case 9: LVDSData = SiS_Pr->SiS_LCDA1600x1200Data_2; break;
+ default: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break;
+ }
+
+ } else {
+
+ /* TW: SiS630/301B needs LVDS Data! */
+ if( (HwDeviceExtension->jChipType < SIS_315H) &&
+ (HwDeviceExtension->jChipType != SIS_300) &&
+ (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
+ (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ) {
+ SiS_Pr->SiS_IF_DEF_LVDS = 1;
+ }
+
+ SiS_GetCRT2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+ &CRT2Index,&ResIndex,HwDeviceExtension);
+
+ /* TW: SiS630/301B needs LVDS Data! */
+ if( (HwDeviceExtension->jChipType < SIS_315H) &&
+ (HwDeviceExtension->jChipType != SIS_300) &&
+ (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
+ (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ) {
+ SiS_Pr->SiS_IF_DEF_LVDS = 0;
+ }
+
+ switch (CRT2Index) {
+ case 0: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1; break;
+ case 1: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break;
+ case 2: LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_1; break;
+ case 3: LVDSData = SiS_Pr->SiS_LVDS800x600Data_2; break;
+ case 4: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_2; break;
+ case 5: LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_2; break;
+ case 6: LVDSData = SiS_Pr->SiS_LVDS640x480Data_1; break;
+ case 7: LVDSData = SiS_Pr->SiS_LVDSXXXxXXXData_1; break; /* TW: New */
+ case 8: LVDSData = SiS_Pr->SiS_LVDS1400x1050Data_1; break; /* TW: New */
+ case 9: LVDSData = SiS_Pr->SiS_LVDS1400x1050Data_2; break; /* TW: New */
+ 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; /* TW: New */
+ case 16: LVDSData = SiS_Pr->SiS_LVDS1152x768Data_1; break; /* TW: New */
+ case 17: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_2; break; /* TW: New */
+ case 18: LVDSData = SiS_Pr->SiS_LVDS1152x768Data_2; break; /* TW: New */
+ case 19: LVDSData = SiS_Pr->SiS_LVDS1280x768Data_1; break; /* TW: New */
+ case 20: LVDSData = SiS_Pr->SiS_LVDS1280x768Data_2; break; /* TW: New */
+ case 90: LVDSData = SiS_Pr->SiS_CHTVUPALMData; break;
+ case 91: LVDSData = SiS_Pr->SiS_CHTVOPALMData; break;
+ case 92: LVDSData = SiS_Pr->SiS_CHTVUPALNData; break;
+ case 93: LVDSData = SiS_Pr->SiS_CHTVOPALNData; break;
+ case 99: LVDSData = SiS_Pr->SiS_CHTVSOPALData; break; /* TW: Super Overscan */
+ default: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; 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_IF_DEF_LVDS == 0) && (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
+
+ if(!(SiS_Pr->SiS_LCDInfo & LCDNonExpanding)){
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768){
+ SiS_Pr->SiS_HDE = 1024;
+ SiS_Pr->SiS_VDE = 768;
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024){
+ SiS_Pr->SiS_HDE = 1280;
+ SiS_Pr->SiS_VDE = 1024;
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050){
+ SiS_Pr->SiS_HDE = 1400;
+ SiS_Pr->SiS_VDE = 1050;
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200){
+ SiS_Pr->SiS_HDE = 1600;
+ SiS_Pr->SiS_VDE = 1200;
+ } else {
+ SiS_Pr->SiS_HDE = 1280;
+ SiS_Pr->SiS_VDE = 960;
+ }
+ }
+
+ } else {
+
+ if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
+ if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
+ if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+ if((!(SiS_Pr->SiS_LCDInfo & LCDNonExpanding)) || (SiS_Pr->SiS_SetFlag & CRT2IsVGA)) {
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
+ SiS_Pr->SiS_HDE = 800;
+ SiS_Pr->SiS_VDE = 600;
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+ SiS_Pr->SiS_HDE = 1024;
+ SiS_Pr->SiS_VDE = 768;
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+ SiS_Pr->SiS_HDE = 1280;
+ SiS_Pr->SiS_VDE = 1024;
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
+ SiS_Pr->SiS_HDE = 1024;
+ SiS_Pr->SiS_VDE = 600;
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+ SiS_Pr->SiS_HDE = 1400;
+ SiS_Pr->SiS_VDE = 1050;
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
+ SiS_Pr->SiS_HDE = 1152;
+ SiS_Pr->SiS_VDE = 768;
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x864) {
+ SiS_Pr->SiS_HDE = 1152;
+ SiS_Pr->SiS_VDE = 864;
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
+ SiS_Pr->SiS_HDE = 1280;
+ SiS_Pr->SiS_VDE = 768;
+ } else {
+ SiS_Pr->SiS_HDE = 1600;
+ SiS_Pr->SiS_VDE = 1200;
+ }
+ if(SiS_Pr->SiS_IF_DEF_FSTN) {
+ SiS_Pr->SiS_HDE = 320;
+ SiS_Pr->SiS_VDE = 480;
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+/* TW: Checked against 630/301B BIOS; does not check VDE values for LCD */
+void
+SiS_GetCRT2Data301(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ USHORT tempax,tempbx,modeflag;
+ USHORT resinfo;
+ USHORT CRT2Index,ResIndex;
+ const SiS_LCDDataStruct *LCDPtr = NULL;
+ const SiS_TVDataStruct *TVPtr = NULL;
+
+ if(ModeNo<=0x13) {
+ modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+ resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+ } else {
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ }
+ SiS_Pr->SiS_NewFlickerMode = 0;
+ SiS_Pr->SiS_RVBHRS = 50;
+ SiS_Pr->SiS_RY1COE = 0;
+ SiS_Pr->SiS_RY2COE = 0;
+ SiS_Pr->SiS_RY3COE = 0;
+ SiS_Pr->SiS_RY4COE = 0;
+
+ SiS_GetCRT2ResInfo(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
+
+ /* TW: For VGA2 ("RAMDAC2") */
+
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC){
+ SiS_GetRAMDAC2DATA(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+ HwDeviceExtension);
+ return;
+ }
+
+ /* TW: For TV */
+
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+
+ SiS_GetCRT2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+ &CRT2Index,&ResIndex,HwDeviceExtension);
+
+ switch (CRT2Index) {
+#ifdef oldHV
+ case 2: TVPtr = SiS_Pr->SiS_ExtHiTVData; break;
+ case 7: TVPtr = SiS_Pr->SiS_St1HiTVData; break;
+ case 12: TVPtr = SiS_Pr->SiS_St2HiTVData; break;
+#endif
+ case 3: TVPtr = SiS_Pr->SiS_ExtPALData; break;
+ case 4: TVPtr = SiS_Pr->SiS_ExtNTSCData; break;
+ case 8: TVPtr = SiS_Pr->SiS_StPALData; break;
+ case 9: TVPtr = SiS_Pr->SiS_StNTSCData; break;
+ default: TVPtr = SiS_Pr->SiS_StPALData; break; /* TW: Just to avoid a crash */
+ }
+
+ SiS_Pr->SiS_RVBHCMAX = (TVPtr+ResIndex)->RVBHCMAX;
+ SiS_Pr->SiS_RVBHCFACT = (TVPtr+ResIndex)->RVBHCFACT;
+ SiS_Pr->SiS_VGAHT = (TVPtr+ResIndex)->VGAHT;
+ SiS_Pr->SiS_VGAVT = (TVPtr+ResIndex)->VGAVT;
+ SiS_Pr->SiS_HDE = (TVPtr+ResIndex)->TVHDE;
+ SiS_Pr->SiS_VDE = (TVPtr+ResIndex)->TVVDE;
+ SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->RVBHRS;
+ SiS_Pr->SiS_NewFlickerMode = (TVPtr+ResIndex)->FlickerMode;
+ if(modeflag & HalfDCLK) {
+ SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->HALFRVBHRS;
+ }
+
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) { /* TW: NOT oldHV! */
+
+ if(resinfo == 0x08) SiS_Pr->SiS_NewFlickerMode = 0x40;
+ if(resinfo == 0x09) SiS_Pr->SiS_NewFlickerMode = 0x40;
+ if(resinfo == 0x12) SiS_Pr->SiS_NewFlickerMode = 0x40;
+
+ if(SiS_Pr->SiS_VGAVDE == 350) SiS_Pr->SiS_SetFlag |= TVSimuMode;
+
+ SiS_Pr->SiS_HT = ExtHiTVHT;
+ SiS_Pr->SiS_VT = ExtHiTVVT;
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+ if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
+ SiS_Pr->SiS_HT = StHiTVHT;
+ SiS_Pr->SiS_VT = StHiTVVT;
+ if(!(modeflag & Charx8Dot)){
+ SiS_Pr->SiS_HT = StHiTextTVHT;
+ SiS_Pr->SiS_VT = StHiTextTVVT;
+ }
+ }
+ }
+
+ } else {
+
+ SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
+ SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
+ SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
+ SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
+
+ if(modeflag & HalfDCLK) {
+ SiS_Pr->SiS_RY1COE = 0x00;
+ SiS_Pr->SiS_RY2COE = 0xf4;
+ SiS_Pr->SiS_RY3COE = 0x10;
+ SiS_Pr->SiS_RY4COE = 0x38;
+ }
+
+ if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+ SiS_Pr->SiS_HT = NTSCHT;
+/* if(SiS_Pr->SiS_VBType & (VB_SIS30xLV|VB_SIS30xNEW)) { */ /* TW: ALL newer 650 BIOSes do this, no idea about 301B */
+ if((ModeNo == 0x4a) || (ModeNo == 0x38)) SiS_Pr->SiS_HT = NTSC2HT;
+/* } */
+ SiS_Pr->SiS_VT = NTSCVT;
+ } else {
+ SiS_Pr->SiS_HT = PALHT;
+ SiS_Pr->SiS_VT = PALVT;
+ }
+
+ }
+
+ return;
+ }
+
+ /* TW: For LCD */
+ /* TW: Checked against 650/301LV; CRT2Index different (but does not matter) */
+
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+
+ SiS_GetCRT2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+ &CRT2Index,&ResIndex,HwDeviceExtension);
+
+ switch (CRT2Index) {
+ case 0: LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break; /* VESA Timing */
+ case 1: LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data; break; /* VESA Timing */
+ case 5: LCDPtr = SiS_Pr->SiS_StLCD1024x768Data; break; /* Obviously unused */
+ case 6: LCDPtr = SiS_Pr->SiS_StLCD1280x1024Data; break; /* Obviously unused */
+ case 10: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data; break; /* Non-VESA Timing */
+ case 11: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break; /* Non-VESA Timing */
+ case 13: LCDPtr = SiS_Pr->SiS_NoScaleData1024x768; break; /* Non-expanding */
+ case 14: LCDPtr = SiS_Pr->SiS_NoScaleData1280x1024; break; /* Non-expanding */
+ case 15: LCDPtr = SiS_Pr->SiS_LCD1280x960Data; break; /* 1280x960 */
+ case 20: LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data; break; /* VESA Timing */
+ case 21: LCDPtr = SiS_Pr->SiS_NoScaleData1400x1050; break; /* Non-expanding */
+ case 22: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data; break; /* Non-VESA Timing */
+ case 23: LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data; break; /* VESA Timing */
+ case 24: LCDPtr = SiS_Pr->SiS_NoScaleData1600x1200; break; /* Non-expanding */
+ case 25: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data; break; /* Non-VESA Timing */
+ default: LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break; /* Just to avoid a crash */
+ }
+
+ SiS_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 = 1024;
+ if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
+ if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
+ else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
+ else tempbx = 768;
+ } else {
+ if (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
+ else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
+ else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
+ else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
+ else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
+ else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
+ else tempbx = 768;
+ }
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024){
+ tempax = 1280;
+ if (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
+ else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
+ else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
+ else tempbx = 1024;
+ }
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960){
+ tempax = 1280;
+ if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 700;
+ else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 800;
+ else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
+ else tempbx = 960;
+ }
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050){
+ tempax = 1400;
+ tempbx = 1050;
+ }
+ if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) {
+ tempax = SiS_Pr->SiS_VGAHDE;
+ tempbx = SiS_Pr->SiS_VGAVDE;
+ }
+ SiS_Pr->SiS_HDE = tempax;
+ SiS_Pr->SiS_VDE = tempbx;
+ return;
+ }
+}
+
+USHORT
+SiS_GetResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+{
+ USHORT resindex;
+
+ if(ModeNo<=0x13)
+ resindex=SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+ else
+ resindex=SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+
+ return(resindex);
+}
+
+/* TW: Checked against 650/301LV, 650/LVDS, 630/LVDS, 630/301 and 630/301B BIOS */
+void
+SiS_GetCRT2ResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ USHORT xres,yres,modeflag=0,resindex;
+
+ resindex = SiS_GetResInfo(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex);
+
+ if(ModeNo <= 0x13) {
+ xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
+ yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
+ } else {
+ xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
+ yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ }
+
+ /* TW: Inserted entire if-section from 650/LVDS BIOS 1.10.07: */
+ if((HwDeviceExtension->jChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
+ if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & CRT2IsVGA)) {
+ if(yres == 350) yres = 400;
+ }
+ if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
+ if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x34) == 0x12)
+ yres = 400;
+ }
+ }
+
+ if(ModeNo > 0x13) {
+ if(SiS_Pr->SiS_IF_DEF_FSTN == 1){
+ xres *= 2;
+ yres *= 2;
+ } else {
+ if(modeflag & HalfDCLK) xres *= 2;
+ if(modeflag & DoubleScanMode) yres *= 2;
+ }
+ }
+
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+ /* TW: Inserted from 650/301LV BIOS */
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+ if(xres == 720) xres = 640;
+ } else {
+ if((HwDeviceExtension->jChipType != SIS_300) ||
+ (SiS_Pr->SiS_VBInfo & (SetCRT2ToAVIDEO | SetCRT2ToSVIDEO |
+ SetCRT2ToSCART | SetCRT2ToLCD | SetCRT2ToHiVisionTV))) {
+ if(xres == 720) xres = 640;
+ }
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+ if(yres == 400) yres = 405;
+ if(yres == 350) yres = 360;
+ if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
+ if(yres == 360) yres = 375;
+ }
+ }
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768){
+ if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
+ if(!(SiS_Pr->SiS_LCDInfo & LCDNonExpanding)) {
+ if(yres == 350) yres = 357;
+ if(yres == 400) yres = 420;
+ if(yres == 480) yres = 525;
+ }
+ }
+ }
+ /* TW: Inserted for 630/301B */
+ if( ( (HwDeviceExtension->jChipType < SIS_315H) &&
+ (HwDeviceExtension->jChipType != SIS_300) ) &&
+ (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) ) {
+ if(xres == 720) xres = 640;
+ }
+ }
+ } else {
+ if(xres == 720) xres = 640;
+ /* TW: Inserted from 650/LVDS and 630/LVDS BIOS */
+ if(SiS_Pr->SiS_SetFlag & CRT2IsVGA) {
+ yres = 400;
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
+ } else {
+ if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
+ }
+ }
+ }
+ SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
+ SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
+}
+
+/* TW: Checked against 650/301 and 650/LVDS (1.10.07) BIOS; modified for new panel resolutions */
+/* TW: Done differently in 630/301B BIOS; but same effect; checked against 630/301 */
+void
+SiS_GetCRT2Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,USHORT *CRT2Index,USHORT *ResIndex,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ USHORT tempbx=0,tempal=0;
+ USHORT Flag,resinfo=0;
+
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { /* LCD */
+
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
+ tempbx = 15;
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+ tempbx = 20;
+ if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) tempbx = 21;
+ if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx = 22;
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
+ tempbx = 23;
+ if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) tempbx = 24;
+ if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx = 25;
+ } else if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) {
+ tempbx = 13;
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempbx++;
+ } else {
+ tempbx = SiS_Pr->SiS_LCDResInfo - SiS_Pr->SiS_Panel1024x768;
+ if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
+ tempbx += 5;
+ /* GetRevisionID(); */
+ /* TW: BIOS only adds 5 once */
+ tempbx += 5;
+ }
+ }
+
+ } else { /* TV */
+#ifdef oldHV
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV){
+ if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_SetFlag &= (~TVSimuMode); /* TW: Was "(!TVSimuMode)" - WRONG */
+ tempbx = 2;
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+ if(!(SiS_Pr->SiS_SetFlag & TVSimuMode)) tempbx = 12; /* TW: Was 10! - WRONG */
+ }
+ } else {
+#endif
+ if(SiS_Pr->SiS_VBInfo & SetPALTV) tempbx = 3;
+ else tempbx = 4;
+ if(SiS_Pr->SiS_SetFlag & TVSimuMode) tempbx += 5;
+#ifdef oldHV
+ }
+#endif
+ }
+
+ if(ModeNo <= 0x13) {
+ tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+ } else {
+ tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+ resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ }
+
+ tempal &= 0x3F;
+
+ if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
+ (SiS_Pr->SiS_VBInfo & (SetCRT2ToTV-SetCRT2ToHiVisionTV))) {
+ if(tempal == 0x06) tempal = 0x07;
+ }
+
+ /* TW: Inserted from 300/301LV BIOS */
+ if((HwDeviceExtension->jChipType == SIS_300) &&
+ (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
+ if(ModeNo > 0x13) {
+ if((resinfo == 0x0c) || (resinfo == 0x0d)) /* 720 (index diff. on 310/325!) */
+ tempal = 6;
+ }
+ }
+
+ if(HwDeviceExtension->jChipType != SIS_300) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ if((ModeNo == 0x31) || (ModeNo == 0x32)) tempal = 6;
+ }
+ }
+
+ *CRT2Index = tempbx;
+ *ResIndex = tempal;
+
+ } else { /* LVDS */
+
+ Flag = 1;
+ tempbx = 0;
+ if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
+ Flag = 0;
+ tempbx = 10;
+ if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
+ if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+ tempbx += 2;
+ if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
+ if(SiS_Pr->SiS_CHPALM) {
+ tempbx = 90;
+ if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
+ } else if(SiS_Pr->SiS_CHPALN) {
+ tempbx = 92;
+ if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
+ }
+
+ }
+ }
+ }
+
+ if(Flag == 1) {
+ tempbx = SiS_Pr->SiS_LCDResInfo - SiS_Pr->SiS_PanelMinLVDS;
+ if(SiS_Pr->SiS_LCDResInfo <= SiS_Pr->SiS_Panel1280x1024) {
+ if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) tempbx += 3;
+ } else {
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+ tempbx = 8;
+ if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) tempbx++;
+ }
+ if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
+ tempbx = 7;
+ }
+
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) tempbx = 6;
+
+ /* TW: Inserted from 630/LVDS 2.04.5c BIOS */
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
+ tempbx = 15;
+ if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) tempbx += 2;
+ }
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
+ tempbx = 16;
+ if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) tempbx += 2;
+ }
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
+ tempbx = 18;
+ if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) tempbx++;
+ }
+ }
+ }
+
+ if(ModeNo <= 0x13)
+ tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+ else {
+ tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+ resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ }
+
+ if(SiS_Pr->SiS_IF_DEF_FSTN){
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel320x480){
+ tempbx = 14;
+ tempal = 6;
+ }
+ }
+
+ /* TW: Inserted from 650/LVDS BIOS */
+ if(SiS_Pr->SiS_SetFlag & CRT2IsVGA) {
+ if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) tempal = 7;
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+ /* TW: Inserted from 630/LVDS (2.04.5c) and 630/301B (II) BIOS */
+ if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x80) tempal++;
+ }
+
+ }
+
+ /* TW: Inserted from 630/301B BIOS */
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ if(ModeNo > 0x13) {
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+ if((resinfo == 0x0c) || (resinfo == 0x0d)) /* 720 */
+ tempal = 6;
+ } else {
+ if((resinfo == 0x0d) || (resinfo == 0x0e)) /* 720 */
+ tempal = 6;
+ }
+ }
+ }
+
+ *CRT2Index = tempbx;
+ *ResIndex = tempal & 0x1F;
+ }
+}
+
+void
+SiS_GetCRT2PtrA(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,USHORT *CRT2Index,
+ USHORT *ResIndex)
+{
+ USHORT tempbx,tempal;
+
+ tempbx = SiS_Pr->SiS_LCDResInfo;
+
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
+ tempbx = 4;
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+ tempbx = 3;
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
+ tempbx = 2;
+ } else {
+ tempbx -= SiS_Pr->SiS_Panel1024x768;
+ }
+
+ if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) tempbx += 5;
+
+ if(ModeNo <= 0x13)
+ tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+ else
+ tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+
+ *CRT2Index = tempbx;
+ *ResIndex = tempal & 0x1F;
+}
+
+/* TW: New from 650/301LVx BIOS */
+void
+SiS_GetCRT2Part2Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,USHORT *CRT2Index,
+ USHORT *ResIndex)
+{
+ USHORT tempbx,tempal;
+
+ if(ModeNo <= 0x13)
+ tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+ else
+ tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+
+ tempbx = SiS_Pr->SiS_LCDResInfo;
+
+ if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) tempbx += 16;
+ else if(SiS_Pr->SiS_SetFlag & LCDVESATiming) tempbx += 32;
+
+ *CRT2Index = tempbx;
+ *ResIndex = tempal & 0x3F;
+}
+
+/* TW: Checked against all (incl 650/LVDS (1.10.07), 630/301B, 630/301) BIOSes */
+USHORT
+SiS_GetRatePtrCRT2(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ SHORT LCDRefreshIndex[] = { 0x00, 0x00, 0x03, 0x01,
+ 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01 };
+ USHORT RefreshRateTableIndex,i,backup_i;
+ USHORT modeflag,index,temp,backupindex;
+
+ if(SiS_Pr->UseCustomMode) return 0;
+
+ if(ModeNo <= 0x13)
+ modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+ else
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+
+ if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ if(modeflag & HalfDCLK) return(0);
+ }
+ }
+
+ if(ModeNo < 0x14) return(0xFFFF);
+
+ /* TW: CR33 holds refresh rate index for CRT1 [3:0] and CRT2 [7:4].
+ * On LVDS machines, CRT2 index is always 0 and will be
+ * set to 0 by the following code; this causes the function
+ * to take the first non-interlaced mode in SiS_Ext2Struct
+ */
+
+ index = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x33);
+ index >>= SiS_Pr->SiS_SelectCRT2Rate;
+ index &= 0x0F;
+ backupindex = index;
+
+ if(index > 0) index--;
+
+ if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+ if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) index = 0;
+ } else {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ if((HwDeviceExtension->jChipType < SIS_315H) &&
+ (HwDeviceExtension->jChipType != SIS_300))
+ index = 0;
+ else if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding)
+ index = backupindex = 0;
+ }
+ }
+ }
+
+ if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
+ if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ index = 0;
+ }
+ }
+ if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+ /* TW: This is not done in 630/301B BIOS */
+ temp = LCDRefreshIndex[SiS_Pr->SiS_LCDResInfo];
+ if(index > temp) index = temp;
+ } else {
+ index = 0;
+ }
+ }
+ }
+
+ RefreshRateTableIndex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
+ ModeNo = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].ModeID;
+
+ /* TW: Inserted from 650/LVDS 1.10.07, 650/301LVx 1.10.6s */
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ if(!(SiS_Pr->SiS_VBInfo & DriverMode)) {
+ if( (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x105) ||
+ (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x107) ) {
+ if(backupindex <= 1)
+ RefreshRateTableIndex++;
+ }
+ }
+ }
+
+ i = 0;
+ do {
+ if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + i].ModeID != ModeNo) break;
+ temp = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + i].Ext_InfoFlag;
+ temp &= ModeInfoFlag;
+ if(temp < SiS_Pr->SiS_ModeType) break;
+ i++;
+ index--;
+ } while(index != 0xFFFF);
+
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+ temp = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + i - 1].Ext_InfoFlag;
+ if(temp & InterlaceMode) {
+ i++;
+ }
+ }
+ }
+
+ i--;
+
+ if((SiS_Pr->SiS_SetFlag & ProgrammingCRT2) && (!(SiS_Pr->SiS_VBInfo & DisableCRT2Display))) {
+ backup_i = i;
+ if (!(SiS_AdjustCRT2Rate(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
+ RefreshRateTableIndex,&i,HwDeviceExtension))) {
+ /* TW: This is for avoiding random data to be used; i is
+ * in an undefined state if no matching CRT2 mode is
+ * found.
+ */
+ i = backup_i;
+ }
+ }
+
+ return(RefreshRateTableIndex + i);
+}
+
+/* Checked against all (incl 650/LVDS (1.10.07), 630/301) BIOSes */
+BOOLEAN
+SiS_AdjustCRT2Rate(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,USHORT *i,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ USHORT tempax,tempbx,resinfo;
+ USHORT modeflag,infoflag;
+
+ if (ModeNo <= 0x13)
+ modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+ else
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+
+ resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ tempbx = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].ModeID;
+
+ tempax = 0;
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+ /* TW: For 301, 301B, 302B, 301LV, 302LV */
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
+ tempax |= SupportRAMDAC2;
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ tempax |= SupportTV;
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+ if(resinfo == 0x0a) tempax |= SupportTV1024;
+ }
+ }
+ }
+ }
+ if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+ tempax |= SupportLCD;
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1600x1200) {
+ if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1400x1050) {
+ if((resinfo == 6) && (SiS_Pr->SiS_LCDInfo & LCDNonExpanding)) {
+ tempax |= SupportAllCRT2;
+ (*i) = 0; /* TW: Restore RefreshTableIndex (BIOS 650/301LVx 1.10.6s) */
+ return(1);
+ } else {
+ if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024) {
+ if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x960) {
+ if((resinfo == 6) && (SiS_Pr->SiS_LCDInfo & LCDNonExpanding)) {
+ return(0);
+ } else {
+ if((resinfo >= 9) && (resinfo != 0x14)) {
+ tempax = 0;
+ return(0);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ } else {
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
+ if((resinfo != 0x0f) && ((resinfo == 4) || (resinfo >= 8))) return(0);
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
+ if((resinfo != 0x10) && (resinfo > 8)) return(0);
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
+ if((resinfo != 0x0e) && (resinfo > 8)) return(0);
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+ if(resinfo > 9) return(0);
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+ if(resinfo > 8) return(0);
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
+ if((resinfo == 4) || (resinfo > 7)) return(0);
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
+ if((resinfo == 4) || (resinfo == 3) || (resinfo > 6)) return(0);
+ }
+ }
+ }
+#ifdef oldHV
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) { /* for HiTV */
+ tempax |= SupportHiVisionTV;
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode){
+ if(resinfo == 4) return(0);
+ if(resinfo == 3) {
+ if(SiS_Pr->SiS_SetFlag & TVSimuMode) return(0);
+ }
+ if(resinfo > 7) return(0);
+ }
+ } else {
+#endif
+ if(SiS_Pr->SiS_VBInfo & (SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
+ tempax |= SupportTV;
+ tempax |= SupportTV1024;
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+ if((SiS_Pr->SiS_VBInfo & SetNotSimuMode) && (SiS_Pr->SiS_VBInfo & SetPALTV)) {
+ if(resinfo != 8) {
+ if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
+ ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != 4)) ) {
+ tempax &= ~(SupportTV1024);
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+ if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
+ ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != 7)) ) {
+ if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0);
+ }
+ }
+ } else {
+ if( (resinfo != 3) ||
+ (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+ (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
+ if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+ if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+ if(resinfo == 3) return(0);
+ if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return (0);
+ }
+ }
+ } else return(0);
+ }
+ }
+ }
+ } else {
+ tempax &= ~(SupportTV1024);
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+ if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
+ ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != 7)) ) {
+ if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0);
+ }
+ }
+ } else {
+ if( (resinfo != 3) ||
+ (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+ (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
+ if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+ if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+ if(resinfo == 3) return(0);
+ if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return (0);
+ }
+ }
+ } else return(0);
+ }
+ }
+ } else { /* slavemode */
+ if(resinfo != 8) {
+ if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
+ ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != 4) ) ) {
+ tempax &= ~(SupportTV1024);
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+ if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
+ ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != 7)) ) {
+ if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0);
+ }
+ }
+ } else {
+ if( (resinfo != 3) ||
+ (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+ (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
+ if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+ if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+ if(resinfo == 3) return(0);
+ if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return (0);
+ }
+ }
+ } else return(0);
+ }
+ }
+ }
+ }
+ } else { /* 301 */
+ tempax &= ~(SupportTV1024);
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+ if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
+ ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != 7)) ) {
+ if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0);
+ }
+ }
+ } else {
+ if( (resinfo != 3) ||
+ (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+ (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
+ if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+ if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+ if(resinfo == 3) return(0);
+ if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return (0);
+ }
+ }
+ } else return(0);
+ }
+ }
+ }
+#ifdef oldHV
+ }
+#endif
+ } else { /* TW: for LVDS */
+
+ if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ tempax |= SupportCHTV;
+ }
+ }
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ tempax |= SupportLCD;
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
+ if((resinfo != 0x14) && (resinfo > 0x09)) return(0);
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
+ if((resinfo != 0x0f) && (resinfo > 0x08)) return(0);
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
+ if((resinfo != 0x10) && (resinfo > 0x08)) return(0);
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+ if((resinfo != 0x15) && (resinfo > 0x09)) return(0);
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+ if(resinfo > 0x09) return(0);
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+ if(resinfo > 0x08) return(0);
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600){
+ if(resinfo > 0x07) return(0);
+ if(resinfo == 0x04) return(0);
+ }
+ }
+ }
+ /* TW: Look backwards in table for matching CRT2 mode */
+ for(; SiS_Pr->SiS_RefIndex[RefreshRateTableIndex+(*i)].ModeID == tempbx; (*i)--) {
+ infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag;
+ if(infoflag & tempax) {
+ return(1);
+ }
+ if ((*i) == 0) break;
+ }
+ /* TW: Look through the whole mode-section of the table from the beginning
+ * for a matching CRT2 mode if no mode was found yet.
+ */
+ for((*i) = 0; ; (*i)++) {
+ infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag;
+ if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].ModeID != tempbx) {
+ return(0);
+ }
+ if(infoflag & tempax) {
+ return(1);
+ }
+ }
+ return(1);
+}
+
+/* Checked against 650/LVDS (1.10.07) and 650/301LV BIOS */
+void
+SiS_SaveCRT2Info(SiS_Private *SiS_Pr, USHORT ModeNo)
+{
+ USHORT temp1,temp2;
+
+ /* TW: We store CRT1 ModeNo in CR34 */
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x34,ModeNo);
+ temp1 = (SiS_Pr->SiS_VBInfo & SetInSlaveMode) >> 8;
+ temp2 = ~(SetInSlaveMode >> 8);
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x31,temp2,temp1);
+}
+
+/* TW: Checked against 650+301, 650/LVDS (1.10.07) and 650/301LVx (1.10.6s) BIOS */
+void
+SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+ USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+ int checkcrt2mode)
+{
+ USHORT tempax,tempbx,temp;
+ USHORT modeflag, resinfo=0;
+ UCHAR OutputSelect = *SiS_Pr->pSiS_OutputSelect;
+
+ if(SiS_Pr->UseCustomMode) {
+ modeflag = SiS_Pr->CModeFlag;
+ } else {
+ if (ModeNo <= 0x13)
+ modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+ else {
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ }
+ }
+
+ SiS_Pr->SiS_SetFlag = 0;
+
+ SiS_Pr->SiS_ModeType = modeflag & ModeInfoFlag;
+
+ tempbx = 0;
+ if(SiS_BridgeIsOn(SiS_Pr,BaseAddr,HwDeviceExtension) == 0) { /* TW: "== 0" inserted from 630/301B BIOS */
+ temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
+ /* SiS_HiVision is only used on 310/325+30xB/LV/LVX */
+ if(SiS_Pr->SiS_HiVision & 0x03) { /* TW: New from 650/301LVx 1.10.6s */
+ temp &= (SetCRT2ToHiVisionTV | SwitchToCRT2 | SetSimuScanMode); /* 0x83 */
+ temp |= SetCRT2ToHiVisionTV; /* 0x80 */
+ }
+ if(SiS_Pr->SiS_HiVision & 0x04) { /* TW: New from 650/301LVx 1.10.6s */
+ temp &= (SetCRT2ToHiVisionTV | SwitchToCRT2 | SetSimuScanMode); /* 0x83 */
+ temp |= SetCRT2ToSVIDEO; /* 0x08 */
+ }
+ if(SiS_Pr->SiS_IF_DEF_FSTN) { /* fstn must set CR30=0x21 */
+ temp = (SetCRT2ToLCD | SetSimuScanMode);
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x30,temp);
+ }
+ tempbx |= temp;
+ tempax = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) << 8;
+ tempax &= (LoadDACFlag | DriverMode | SetDispDevSwitch | SetNotSimuMode | SetPALTV);
+ tempbx |= tempax;
+ tempbx &= ~(SetCHTVOverScan | SetInSlaveMode | DisableCRT2Display);;
+
+#ifdef SIS315H
+
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ if(SiS_Pr->SiS_VBType & (VB_SIS302B | VB_SIS30xLV | VB_SIS30xNEW)) {
+#if 0 /* Not in 1.10.8r */
+ if(ModeNo == 3) {
+ SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf);
+ }
+#endif
+#if 0 /* Not in 1.10.8r */
+ if(!(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8))) {
+ SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
+ }
+#endif
+ if((tempbx & SetCRT2ToLCD) && (SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30) & SetCRT2ToLCD)) {
+ if((SiS_GetReg1(SiS_Pr->SiS_P3d4, 0x36) & 0x0f) == SiS_Pr->SiS_Panel1400x1050) {
+ if((ModeNo <= 0x13) || (!(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) {
+ if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) {
+ SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA)); /* 3 */
+ }
+ }
+ } else {
+ if((ModeNo <= 0x13) || (!(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) {
+ if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) {
+ SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA)); /* 3 */
+ }
+ }
+ }
+ }
+ temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
+ if((temp & (EnableDualEdge | SetToLCDA)) == (EnableDualEdge | SetToLCDA)) {
+ tempbx |= SetCRT2ToLCDA;
+ }
+ }
+ /* TW: Inserted from 650/LVDS 1.10.07 BIOS: */
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+ temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
+ if(temp & SetToLCDA)
+ tempbx |= SetCRT2ToLCDA;
+ if(temp & EnableLVDSHiVision)
+ tempbx |= SetCRT2ToHiVisionTV;
+ }
+ }
+
+#endif /* SIS315H */
+
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+ temp = SetCRT2ToLCDA | SetCRT2ToSCART | SetCRT2ToLCD |
+ SetCRT2ToRAMDAC | SetCRT2ToSVIDEO | SetCRT2ToAVIDEO; /* = 0x807C; */
+ if(SiS_Pr->SiS_IF_DEF_HiVision == 1)
+ temp |= SetCRT2ToHiVisionTV; /* = 0x80FC; */
+ } else {
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ if(SiS_Pr->SiS_IF_DEF_CH70xx != 0)
+ temp = SetCRT2ToLCDA | SetCRT2ToSCART |
+ SetCRT2ToLCD | SetCRT2ToHiVisionTV |
+ SetCRT2ToAVIDEO | SetCRT2ToSVIDEO; /* = 0x80bc */
+ else
+ temp = SetCRT2ToLCDA | SetCRT2ToLCD;
+ } else {
+ if(SiS_Pr->SiS_IF_DEF_CH70xx != 0)
+ temp = SetCRT2ToTV | SetCRT2ToLCD;
+ else
+ temp = SetCRT2ToLCD;
+ }
+ }
+
+ if(!(tempbx & temp)) {
+ tempax = DisableCRT2Display;
+ tempbx = 0;
+ }
+
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+ if(tempbx & SetCRT2ToLCDA) {
+ tempbx &= (0xFF00|SwitchToCRT2|SetSimuScanMode);
+ }
+ if(tempbx & SetCRT2ToRAMDAC) {
+ tempbx &= (0xFF00|SetCRT2ToRAMDAC|SwitchToCRT2|SetSimuScanMode);
+ }
+ if((tempbx & SetCRT2ToLCD) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
+ tempbx &= (0xFF00|SetCRT2ToLCD|SwitchToCRT2|SetSimuScanMode);
+ }
+ if(tempbx & SetCRT2ToSCART) {
+ tempbx &= (0xFF00|SetCRT2ToSCART|SwitchToCRT2|SetSimuScanMode);
+ tempbx |= SetPALTV;
+ }
+#if 0 /* TW: Not done in 650/301LVx 1.10.6s BIOS */
+ } else if(tempbx & SetCRT2ToHiVisionTV){
+ tempbx &= (0xFF00|SetCRT2ToHiVisionTV|SwitchToCRT2|SetSimuScanMode);
+ tempbx |= SetPALTV;
+ }
+#endif
+ } else { /* LVDS */
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ if(tempbx & SetCRT2ToLCDA)
+ tempbx &= (0xFF00|SwitchToCRT2|SetSimuScanMode);
+ }
+ if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+ if(tempbx & SetCRT2ToTV)
+ tempbx &= (0xFF00|SetCRT2ToTV|SwitchToCRT2|SetSimuScanMode);
+ }
+ if(tempbx & SetCRT2ToLCD) {
+ tempbx &= (0xFF00|SetCRT2ToLCD|SwitchToCRT2|SetSimuScanMode);
+ }
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ if(tempbx & SetCRT2ToLCDA)
+ tempbx |= SetCRT2ToLCD;
+ }
+ }
+
+ if(tempax & DisableCRT2Display) {
+ if(!(tempbx & (SwitchToCRT2 | SetSimuScanMode))) {
+ tempbx = SetSimuScanMode | DisableCRT2Display;
+ }
+ }
+
+ if(!(tempbx & DriverMode)){
+ tempbx |= SetSimuScanMode;
+ }
+
+ /* TW: LVDS (LCD/TV) and 630+301B (LCD) can only be slave in 8bpp modes */
+ if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->SiS_ModeType <= ModeVGA) ) {
+ modeflag &= (~CRT2Mode);
+ }
+ if( (HwDeviceExtension->jChipType < SIS_315H) &&
+ (HwDeviceExtension->jChipType != SIS_300) &&
+ (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
+ if(SiS_Pr->SiS_ModeType <= ModeVGA) {
+ if(tempbx & SetCRT2ToLCD) {
+ modeflag &= (~CRT2Mode);
+ }
+ }
+ }
+ /* TW end */
+
+ if(!(tempbx & SetSimuScanMode)){
+ if(tempbx & SwitchToCRT2) {
+ if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
+ if( (HwDeviceExtension->jChipType >= SIS_315H) &&
+ (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) ) {
+ if(resinfo != 0x0a)
+ tempbx |= SetSimuScanMode;
+ } else {
+ tempbx |= SetSimuScanMode;
+ }
+ }
+ } else {
+ if(!(SiS_BridgeIsEnable(SiS_Pr,BaseAddr,HwDeviceExtension))) {
+ if(!(tempbx & DriverMode)) {
+ if(SiS_BridgeInSlave(SiS_Pr)) {
+ tempbx |= SetSimuScanMode;
+ }
+ }
+ }
+ }
+ }
+
+ if(!(tempbx & DisableCRT2Display)) {
+ if(tempbx & DriverMode) {
+ if(tempbx & SetSimuScanMode) {
+ if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
+ if( (HwDeviceExtension->jChipType >= SIS_315H) &&
+ (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) ) {
+ if(resinfo != 0x0a) { /* TW: Inserted from 650/301 BIOS */
+ tempbx |= SetInSlaveMode;
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+ if(tempbx & SetCRT2ToTV) {
+ if(!(tempbx & SetNotSimuMode))
+ SiS_Pr->SiS_SetFlag |= TVSimuMode;
+ }
+ }
+ } /* TW: Inserted from 650/301 BIOS */
+ } else {
+ tempbx |= SetInSlaveMode;
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+ if(tempbx & SetCRT2ToTV) {
+ if(!(tempbx & SetNotSimuMode))
+ SiS_Pr->SiS_SetFlag |= TVSimuMode;
+ }
+ }
+ }
+ }
+ }
+ } else {
+ tempbx |= SetInSlaveMode;
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+ if(tempbx & SetCRT2ToTV) {
+ if(!(tempbx & SetNotSimuMode))
+ SiS_Pr->SiS_SetFlag |= TVSimuMode;
+ }
+ }
+ }
+ }
+
+ if(SiS_Pr->SiS_CHOverScan) {
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
+ temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x35);
+ if((temp & TVOverScan) || (SiS_Pr->SiS_CHOverScan == 1) )
+ tempbx |= SetCHTVOverScan;
+ }
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+ temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x79);
+ if( (temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1) )
+ tempbx |= SetCHTVOverScan;
+ }
+ }
+ }
+
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+#ifdef SIS300
+ if((HwDeviceExtension->jChipType==SIS_630) ||
+ (HwDeviceExtension->jChipType==SIS_730)) {
+ if(ROMAddr && SiS_Pr->SiS_UseROM) {
+ OutputSelect = ROMAddr[0xfe];
+ }
+ if(!(OutputSelect & EnablePALMN))
+ SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x35,0x3F);
+ if(tempbx & SetCRT2ToTV) {
+ if(tempbx & SetPALTV) {
+ temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x35);
+ if(temp & EnablePALM) tempbx &= (~SetPALTV);
+ }
+ }
+ }
+#endif
+#ifdef SIS315H
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ if(ROMAddr && SiS_Pr->SiS_UseROM) {
+ OutputSelect = ROMAddr[0xf3];
+ if(HwDeviceExtension->jChipType == SIS_330) {
+ OutputSelect = ROMAddr[0x11b];
+ }
+ }
+ if(!(OutputSelect & EnablePALMN))
+ SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0x3F);
+ if(tempbx & SetCRT2ToTV) {
+ if(tempbx & SetPALTV) {
+ temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
+ if(temp & EnablePALM) tempbx &= (~SetPALTV);
+ }
+ }
+ }
+#endif
+ }
+
+ /* PALM/PALN on Chrontel 7019 */
+ SiS_Pr->SiS_CHPALM = SiS_Pr->SiS_CHPALN = FALSE;
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+ if(tempbx & SetCRT2ToTV) {
+ if(tempbx & SetPALTV) {
+ temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
+ if(temp & EnablePALM) SiS_Pr->SiS_CHPALM = TRUE;
+ else if(temp & EnablePALN) SiS_Pr->SiS_CHPALN = TRUE;
+ }
+ }
+ }
+
+ SiS_Pr->SiS_VBInfo = tempbx;
+
+ if(HwDeviceExtension->jChipType == SIS_630) {
+ SiS_WhatIsThis(SiS_Pr, SiS_Pr->SiS_VBInfo);
+ }
+
+#ifdef TWDEBUG
+#ifdef LINUX_KERNEL
+ printk(KERN_DEBUG "sisfb: (VBInfo= 0x%04x, SetFlag=0x%04x)\n",
+ SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
+#endif
+#ifdef LINUX_XF86
+ xf86DrvMsgVerb(0, X_PROBED, 3, "(init301: VBInfo=0x%04x, SetFlag=0x%04x)\n",
+ SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
+#endif
+#endif
+
+#if 0 /* TW: Incomplete! (But does not seem to be required) */
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+ /* TW: From A901/630+301B BIOS */
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x80)
+ }
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
+ if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x80)
+ if( [si] == 3) ModeIdIndex = 0x3f2b;
+ }
+ }
+ SiS_SetRegAND(SiS_Pr->SiS_P3d4, 0x31, 0xF7);
+ if(ModeNo == 0x13) bp+4 = 0x03;
+ } else {
+ /* From 650/301LVx BIOS: */
+ SiS_SetRegAND(SiS_Pr->SiS_P3d4, 0x31, 0xF7);
+ if(ModeNo == 0x13) bp+4 = 0x03;
+ else bp+4 = ModeNo;
+ }
+#endif
+
+ /* TW: 630/301B and 650/301 (not 301LV!) BIOSes do more here, but this seems for DOS mode */
+
+}
+
+void
+SiS_WhatIsThis(SiS_Private *SiS_Pr, USHORT myvbinfo)
+{
+ unsigned long eax, temp;
+ unsigned short temp1;
+
+ if(!(SiS_Pr->SiS_ChSW)) return;
+
+#ifndef LINUX_XF86
+ SiS_SetReg4(0xcf8,0x80000874);
+ eax = SiS_GetReg3(0xcfc);
+#else
+ eax = pciReadLong(0x00000800, 0x74);
+#endif
+ eax &= 0xFFFF;
+ temp = eax;
+ eax += 0x3c;
+ temp1 = SiS_GetReg4((USHORT)eax);
+ temp1 &= 0xFEFF;
+ SiS_SetReg5((USHORT)eax, temp1);
+ temp1 = SiS_GetReg4((USHORT)eax);
+ eax = temp;
+ eax += 0x3a;
+ temp1 = SiS_GetReg4((USHORT)eax);
+ temp1 &= 0xFEFF;
+ if(!(myvbinfo & SetCRT2ToTV)) {
+ temp1 |= 0x0100;
+ }
+ SiS_SetReg5((USHORT)eax, temp1);
+ temp1 = SiS_GetReg4((USHORT)eax);
+}
+
+void
+SiS_GetRAMDAC2DATA(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ USHORT tempax,tempbx,temp;
+ USHORT temp1,modeflag=0,tempcx;
+ USHORT StandTableIndex,CRT1Index;
+ USHORT ResInfo,DisplayType;
+ const SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr = NULL;
+
+ SiS_Pr->SiS_RVBHCMAX = 1;
+ SiS_Pr->SiS_RVBHCFACT = 1;
+
+ if(ModeNo <= 0x13){
+
+ modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+ StandTableIndex = SiS_GetModePtr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex);
+ tempax = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[0];
+ tempbx = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[6];
+ temp1 = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[7];
+
+ } else {
+
+ if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) ) {
+
+ temp = SiS_GetLVDSCRT1Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
+ RefreshRateTableIndex,&ResInfo,&DisplayType);
+
+ if(temp == 0) return;
+
+ switch(DisplayType) {
+ case 0 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1; break;
+ case 1 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1; break;
+ case 2 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1; break;
+ case 3 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1_H; break;
+ case 4 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1_H; break;
+ case 5 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1_H; break;
+ case 6 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2; break;
+ case 7 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2; break;
+ case 8 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2; break;
+ case 9 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2_H; break;
+ case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2_H; break;
+ case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2_H; break;
+ case 12: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1; break;
+ case 13: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H; break;
+ case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_1; break;
+ case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_1_H; break;
+ case 16: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_2; break;
+ case 17: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_2_H; break;
+ case 18: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC; break;
+ case 19: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC; break;
+ case 20: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL; break;
+ case 21: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL; break;
+ case 22: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x480_1; break;
+ case 23: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1; break;
+ case 24: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1_H; break;
+ case 25: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2; break;
+ case 26: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2_H; break;
+ case 27: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_1; break;
+ case 28: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_1_H; break;
+ case 29: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_2; break;
+ case 30: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_2_H; break;
+ case 36: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_1; break;
+ case 37: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_1_H; break;
+ case 38: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_2; break;
+ case 39: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_2_H; break;
+ case 99: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL; break;
+ default: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1; break;
+ }
+ tempax = (LVDSCRT1Ptr+ResInfo)->CR[0];
+ tempax |= (LVDSCRT1Ptr+ResInfo)->CR[14] << 8;
+ tempax &= 0x03FF;
+ tempbx = (LVDSCRT1Ptr+ResInfo)->CR[6];
+ tempcx = (LVDSCRT1Ptr+ResInfo)->CR[13] << 8;
+ tempcx &= 0x0100;
+ tempcx <<= 2;
+ tempbx |= tempcx;
+ temp1 = (LVDSCRT1Ptr+ResInfo)->CR[7];
+
+ } else {
+
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ CRT1Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+#if 0 /* Not any longer */
+ if(HwDeviceExtension->jChipType < SIS_315H) CRT1Index &= 0x3F;
+#endif
+ tempax = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[0];
+ tempax |= SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14] << 8;
+ tempax &= 0x03FF;
+ tempbx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[6];
+ tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13] << 8;
+ tempcx &= 0x0100;
+ tempcx <<= 2;
+ tempbx |= tempcx;
+ temp1 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
+
+ }
+
+ }
+
+ if(temp1 & 0x01) tempbx |= 0x0100;
+ if(temp1 & 0x20) tempbx |= 0x0200;
+
+ tempax += 5;
+
+ /* Charx8Dot is no more used (and assumed), so we set it */
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ modeflag |= Charx8Dot;
+ }
+
+ if(modeflag & Charx8Dot) tempax *= 8;
+ else tempax *= 9;
+
+ /* TW: From 650/301LVx 1.10.6s */
+ if(modeflag & HalfDCLK) tempax <<= 1;
+
+ SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
+ tempbx++;
+ SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = tempbx;
+}
+
+void
+SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
+{
+ if(HwDeviceExtension->jChipType >= SIS_315H)
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
+ else
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
+}
+
+void
+SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
+{
+ if(HwDeviceExtension->jChipType >= SIS_315H)
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
+ else
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
+}
+
+void
+SiS_EnableCRT2(SiS_Private *SiS_Pr)
+{
+ SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
+}
+
+/* Checked against all BIOSes */
+void
+SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
+{
+#ifdef SIS315H
+ USHORT tempah,pushax=0;
+#endif
+ USHORT temp=0;
+ UCHAR *ROMAddr = HwDeviceExtension->pjVirtualRomBase;
+
+ if (SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { /* ===== TW: For 30xB/LV ===== */
+
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+
+#ifdef SIS300 /* 300 series */
+
+ if(HwDeviceExtension->jChipType == SIS_300) { /* New for 300+301LV */
+
+ if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) {
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFE,0x00);
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+ }
+ if(SiS_Is301B(SiS_Pr,BaseAddr)) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);
+ SiS_ShortDelay(SiS_Pr,1);
+ }
+ SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
+ SiS_DisplayOff(SiS_Pr);
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
+ if( (!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) ||
+ (!(SiS_CR36BIOSWord23d(SiS_Pr,HwDeviceExtension))) ) {
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xFB,0x04);
+ }
+
+ } else {
+
+ if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) {
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF7,0x08);
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+ }
+ if(SiS_Is301B(SiS_Pr,BaseAddr)) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);
+ SiS_ShortDelay(SiS_Pr,1);
+ }
+ SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
+ SiS_DisplayOff(SiS_Pr);
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
+ SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension,BaseAddr);
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
+ if( (!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) ||
+ (!(SiS_CR36BIOSWord23d(SiS_Pr,HwDeviceExtension))) ) {
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xFB,0x04);
+ }
+ }
+
+#endif /* SIS300 */
+
+ } else {
+
+#ifdef SIS315H /* 310/325 series */
+
+ if(IS_SIS650740) { /* 650, 740 */
+
+#if 0
+ if(SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x00) != 1) return; /* From 1.10.7w */
+#endif
+
+ if(SiS_Pr->SiS_VBType & (VB_SIS30xLV|VB_SIS30xNEW)) {
+
+ if(!(SiS_IsM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ tempah = 0xef;
+ if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+ tempah = 0xf7;
+ }
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
+ }
+
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
+
+ if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFE,0x00);
+ } else if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFE,0x00);
+ }
+
+ SiS_SetReg3(SiS_Pr->SiS_P3c6,0x00);
+
+ pushax = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x06);
+
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+
+ }
+
+ if(SiS_Pr->SiS_VBType & (VB_SIS301B|VB_SIS302B)) {
+ tempah = 0x3f;
+ if(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+ tempah = 0x7f;
+ if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ tempah = 0xbf;
+ }
+ }
+ SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
+ }
+
+ if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+
+ if(SiS_Pr->SiS_VBType & (VB_SIS301B|VB_SIS302B)) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
+ SiS_DisplayOff(SiS_Pr);
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
+ } else {
+ SiS_DisplayOff(SiS_Pr);
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
+ }
+
+ } else {
+
+ if(SiS_Pr->SiS_VBType & (VB_SIS301B|VB_SIS302B)) {
+ if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
+ SiS_DisplayOff(SiS_Pr);
+ }
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
+ temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00);
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,temp);
+ } else {
+ SiS_DisplayOff(SiS_Pr);
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
+ temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00);
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,temp);
+ }
+
+ }
+
+ if(SiS_Pr->SiS_VBType & (VB_SIS30xLV|VB_SIS30xNEW)) {
+
+ tempah = 0x3f;
+ if(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+ tempah = 0x7f;
+ if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ tempah = 0xbf;
+ }
+ }
+ SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
+
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
+
+ if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
+ }
+
+ if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ if(!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) {
+ if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFD,0x00);
+ }
+ }
+ }
+
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x06,pushax);
+
+ }
+
+
+ } else { /* 315, 330 */
+
+ if(SiS_Is301B(SiS_Pr,BaseAddr)) {
+ tempah = 0x3f;
+ if(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+ tempah = 0x7f;
+ if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ tempah = 0xbf;
+ }
+ }
+ SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
+ if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+ SiS_DisplayOff(SiS_Pr);
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
+ }
+ }
+ if( (!(SiS_Is301B(SiS_Pr,BaseAddr))) ||
+ (!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) ) {
+
+ if( (!(SiS_Is301B(SiS_Pr,BaseAddr))) ||
+ (!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) ) {
+
+ SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
+ SiS_DisplayOff(SiS_Pr);
+
+ }
+
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
+
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
+
+ temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00);
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,temp);
+
+ }
+
+ } /* 315/330 */
+
+#endif /* SIS315H */
+
+ }
+
+ } else { /* ============ TW: For 301 ================ */
+
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+ if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF0,0x0B);
+ SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 1);
+ }
+ }
+
+ SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF); /* disable VB */
+ SiS_DisplayOff(SiS_Pr);
+
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
+ }
+
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); /* disable lock mode */
+
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00);
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
+ SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,temp);
+ } else {
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); /* disable CRT2 */
+ }
+
+ }
+
+ } else { /* ============ TW: For LVDS =============*/
+
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+
+#ifdef SIS300 /* 300 series */
+
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
+ SiS_SetCH700x(SiS_Pr,0x090E);
+ }
+
+ if(HwDeviceExtension->jChipType == SIS_730) {
+ if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
+ SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
+ }
+ if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) {
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF7,0x08);
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+ }
+ } else {
+ if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
+
+ if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
+
+ if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) {
+
+ SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
+
+ if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {
+ SiS_DisplayOff(SiS_Pr);
+ }
+
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF7,0x08);
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+ }
+ }
+ }
+ }
+
+ SiS_DisplayOff(SiS_Pr);
+
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
+
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
+ SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension,BaseAddr);
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
+
+ if( (!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) ||
+ (!(SiS_CR36BIOSWord23d(SiS_Pr,HwDeviceExtension))) ) {
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xFB,0x04);
+ }
+
+#endif /* SIS300 */
+
+ } else {
+
+#ifdef SIS315H /* 310/325 series */
+
+ if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+ if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ SiS_Chrontel701xBLOff(SiS_Pr);
+ SiS_Chrontel701xOff(SiS_Pr);
+ } else if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+ SiS_Chrontel701xBLOff(SiS_Pr);
+ SiS_Chrontel701xOff(SiS_Pr);
+ }
+
+ if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ SiS_SetCH701x(SiS_Pr,0x0149);
+ } else if(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+ SiS_SetCH701x(SiS_Pr,0x0149);
+ }
+ }
+
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF7,0x08);
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+ }
+
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
+ SiS_DisplayOff(SiS_Pr);
+ } else if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ SiS_DisplayOff(SiS_Pr);
+ } else if(!(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ SiS_DisplayOff(SiS_Pr);
+ }
+
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
+ } else if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
+ } else if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
+ }
+
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
+
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
+ } else if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
+ } else if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
+ }
+
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
+ if(SiS_CRT2IsLCD(SiS_Pr, BaseAddr,HwDeviceExtension)) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
+ }
+ } else if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
+ }
+
+ if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+ if(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff);
+ } else {
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
+ }
+ }
+
+ SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension, BaseAddr);
+
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
+ } else if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
+ } else if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
+ }
+
+#if 0 /* TW: BIOS code makes no sense */
+ if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+ if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+ /* Nothing there! */
+ }
+ }
+ }
+#endif
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
+ if(SiS_CRT2IsLCD(SiS_Pr, BaseAddr,HwDeviceExtension)) {
+ if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xFB,0x04);
+ }
+ }
+ }
+
+#endif /* SIS315H */
+
+ } /* 310 series */
+
+ } /* LVDS */
+
+}
+
+/* TW: Checked against all BIOSes */
+void
+SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
+{
+ USHORT temp=0,tempah;
+#ifdef SIS315H
+ USHORT temp1,pushax=0;
+ BOOLEAN delaylong = FALSE;
+#endif
+ UCHAR *ROMAddr = HwDeviceExtension->pjVirtualRomBase;
+
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { /* TW: ====== For 301B et al ====== */
+
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+
+#ifdef SIS300 /* 300 series */
+
+ if(HwDeviceExtension->jChipType == SIS_300) {
+
+ if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
+ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
+ if(!(SiS_CR36BIOSWord23d(SiS_Pr,HwDeviceExtension))) {
+ SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 0);
+ }
+ }
+ temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
+ if(SiS_BridgeInSlave(SiS_Pr)) {
+ tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
+ if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
+ }
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
+ SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */
+ if(SiS_Is301B(SiS_Pr,BaseAddr)) {
+ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
+ SiS_DisplayOn(SiS_Pr);
+ } else {
+ SiS_VBLongWait(SiS_Pr);
+ SiS_DisplayOn(SiS_Pr);
+ SiS_VBLongWait(SiS_Pr);
+ }
+ if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
+ if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
+ if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
+ if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) {
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1);
+ }
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xfe,0x01);
+ }
+ }
+ }
+
+ } else {
+
+ if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x11,0xFB);
+ if(!(SiS_CR36BIOSWord23d(SiS_Pr,HwDeviceExtension))) {
+ SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 0);
+ }
+ SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* Enable CRT2 */
+/* DoSomeThingPCI_On(SiS_Pr) */
+ SiS_DisplayOn(SiS_Pr);
+ SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension, BaseAddr);
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
+ if(SiS_BridgeInSlave(SiS_Pr)) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
+ } else {
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
+ }
+ if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
+ if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
+ if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) {
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1);
+ }
+ SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF7,0x00);
+ }
+ }
+ } else {
+ temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
+ if(SiS_BridgeInSlave(SiS_Pr)) {
+ tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
+ if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
+ }
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
+ SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */
+ if(SiS_Is301B(SiS_Pr,BaseAddr)) {
+ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
+ SiS_DisplayOn(SiS_Pr);
+ } else {
+ SiS_VBLongWait(SiS_Pr);
+ SiS_DisplayOn(SiS_Pr);
+ SiS_VBLongWait(SiS_Pr);
+ }
+ }
+
+ }
+#endif /* SIS300 */
+
+ } else {
+
+#ifdef SIS315H /* 310/325 series */
+
+ if(IS_SIS650740) { /* 650, 740 */
+
+#if 0
+ if(SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x00) != 1) return; /* From 1.10.7w */
+#endif
+
+ if(SiS_Pr->SiS_VBType & (VB_SIS30xLV|VB_SIS30xNEW)) {
+
+ if(!(SiS_IsM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ tempah = 0x10;
+ if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+ tempah = 0x08;
+ }
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,tempah);
+ }
+
+ SiS_SetReg3(SiS_Pr->SiS_P3c6,0x00);
+
+ SiS_DisplayOff(SiS_Pr);
+
+ pushax = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x06);
+
+ if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
+ (SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) ) {
+ if(!(SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
+ }
+ }
+
+ if(!(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+ delaylong = TRUE;
+ }
+
+ }
+
+ if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
+ if(SiS_BridgeInSlave(SiS_Pr)) {
+ tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
+ if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
+ }
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
+
+ SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
+ if(SiS_Pr->SiS_VBType & (VB_SIS301B|VB_SIS302B)) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
+ temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2e);
+ if(!(temp & 0x80)) {
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
+ }
+ } else {
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
+ }
+ }
+
+ if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20);
+ }
+
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
+
+ if(SiS_Pr->SiS_VBType & (VB_SIS301B|VB_SIS302B)) {
+ temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2e);
+ if(!(temp & 0x80)) {
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
+ }
+ }
+
+ tempah = 0xc0;
+ if(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+ tempah = 0x80;
+ if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ tempah = 0x40;
+ }
+ }
+ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
+
+ if(SiS_Pr->SiS_VBType & (VB_SIS301B|VB_SIS302B)) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
+ }
+
+ if(SiS_Pr->SiS_VBType & (VB_SIS30xLV|VB_SIS30xNEW)) {
+
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
+
+ if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
+ ((SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) ) {
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+ if(delaylong) {
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+ }
+ SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xfe,0x01);
+ }
+ }
+
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x06,pushax);
+ SiS_DisplayOn(SiS_Pr);
+ SiS_SetReg3(SiS_Pr->SiS_P3c6,0xff);
+
+ if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
+ }
+
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
+ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
+ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20);
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x31,0x05);
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x32,0x60);
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x33,0x00);
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
+ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40);
+
+ }
+
+
+ } else { /* 315, 330 */
+
+ if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
+ if(SiS_BridgeInSlave(SiS_Pr)) {
+ tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
+ if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
+ }
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
+
+ SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
+
+ temp=SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2E);
+ if (!(temp & 0x80))
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
+ }
+
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
+
+ if(SiS_Is301B(SiS_Pr,BaseAddr)) {
+
+ temp=SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2E);
+ if (!(temp & 0x80))
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
+
+ tempah = 0xc0;
+ if(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+ tempah = 0x80;
+ if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ tempah = 0x40;
+ }
+ }
+ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
+
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
+
+ } else {
+
+ SiS_VBLongWait(SiS_Pr);
+ SiS_DisplayOn(SiS_Pr);
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7F);
+ SiS_VBLongWait(SiS_Pr);
+
+ }
+
+ } /* 315, 330 */
+
+#endif /* SIS315H */
+
+ }
+
+ } else { /* ============ TW: For 301 ================ */
+
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+ if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF0,0x0B);
+ SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 0);
+ }
+ }
+
+ temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
+ if(SiS_BridgeInSlave(SiS_Pr)) {
+ tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
+ if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
+ }
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
+
+ SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
+
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2E);
+ if(!(temp & 0x80))
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80); /* BVBDOENABLE=1 */
+ }
+
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */
+
+ SiS_VBLongWait(SiS_Pr);
+ SiS_DisplayOn(SiS_Pr);
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
+ }
+ SiS_VBLongWait(SiS_Pr);
+
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+ if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
+ SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 1);
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF0,0x03);
+ }
+ }
+
+ }
+
+ } else { /* =================== TW: For LVDS ================== */
+
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+
+#ifdef SIS300 /* 300 series */
+
+ if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
+ if(HwDeviceExtension->jChipType == SIS_730) {
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1);
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1);
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1);
+ }
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x11,0xFB);
+ if(!(SiS_CR36BIOSWord23d(SiS_Pr,HwDeviceExtension))) {
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 0);
+ }
+ }
+
+ SiS_EnableCRT2(SiS_Pr);
+ SiS_DisplayOn(SiS_Pr);
+ SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension, BaseAddr);
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
+ if(SiS_BridgeInSlave(SiS_Pr)) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
+ } else {
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
+ }
+
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
+ if(!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) {
+ SiS_SetCH700x(SiS_Pr,0x0B0E);
+ }
+ }
+
+ if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
+ if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
+ if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
+ if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) {
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1);
+ SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1);
+ }
+ SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x11,0xF7);
+ }
+ }
+ }
+
+#endif /* SIS300 */
+
+ } else {
+
+#ifdef SIS315H /* 310/325 series */
+
+#if 0 /* BIOS code makes no sense */
+ if(SiS_IsVAMode()) {
+ if(SiS_IsLCDOrLCDA()) {
+ }
+ }
+#endif
+
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
+ if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x11,0xFB);
+ SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 0);
+ }
+ }
+
+ SiS_EnableCRT2(SiS_Pr);
+ SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension, BaseAddr);
+
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
+
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+ temp = SiS_GetCH701x(SiS_Pr,0x66);
+ temp &= 0x20;
+ SiS_Chrontel701xBLOff(SiS_Pr);
+ }
+
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
+
+ temp1 = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2E);
+ if (!(temp1 & 0x80))
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
+
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+ if(temp) {
+ SiS_Chrontel701xBLOn(SiS_Pr);
+ }
+ }
+
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
+ if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
+ }
+ } else if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
+ }
+
+ if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
+ }
+
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+
+ if(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+ SiS_Chrontel701xOn(SiS_Pr,HwDeviceExtension, BaseAddr);
+ }
+
+ if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+ SiS_ChrontelDoSomething1(SiS_Pr,HwDeviceExtension, BaseAddr);
+ } else if(SiS_IsLCDOrLCDA(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+ SiS_ChrontelDoSomething1(SiS_Pr,HwDeviceExtension, BaseAddr);
+ }
+
+ }
+
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+ if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+ SiS_Chrontel701xBLOn(SiS_Pr);
+ SiS_ChrontelDoSomething4(SiS_Pr,HwDeviceExtension, BaseAddr);
+ } else if(SiS_IsLCDOrLCDA(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+/* if(!SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) { */ /* TW: makes no sense */
+ SiS_Chrontel701xBLOn(SiS_Pr);
+ SiS_ChrontelDoSomething4(SiS_Pr,HwDeviceExtension, BaseAddr);
+/* } */
+ }
+ }
+ } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
+ if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
+ SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 1);
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x11,0xF7);
+ }
+ }
+ }
+
+#endif /* SIS315H */
+
+ } /* 310 series */
+
+ } /* LVDS */
+
+}
+
+void
+SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ USHORT BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
+
+ /* TW: Switch on LCD backlight on SiS30xLV */
+ if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
+ (SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) ) {
+ if(!(SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
+ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
+ SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
+ }
+ if(!(SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x26) & 0x01)) {
+ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
+ }
+ }
+}
+
+void
+SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ USHORT BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
+
+ /* TW: Switch off LCD backlight on SiS30xLV */
+ if( (!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) ||
+ (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ) {
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFE,0x00);
+ }
+
+ if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ if(!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) {
+ if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFD,0x00);
+ }
+ }
+ }
+}
+
+BOOLEAN
+SiS_CR36BIOSWord23b(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ USHORT temp,temp1;
+ UCHAR *ROMAddr;
+
+ if((ROMAddr = (UCHAR *)HwDeviceExtension->pjVirtualRomBase) && SiS_Pr->SiS_UseROM) {
+ temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0xff;
+ temp >>= 4;
+ temp = 1 << temp;
+ temp1 = (ROMAddr[0x23c] << 8) | ROMAddr[0x23b];
+ if(temp1 & temp) return(1);
+ else return(0);
+ } else {
+ return(0);
+ }
+}
+
+BOOLEAN
+SiS_CR36BIOSWord23d(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ USHORT temp,temp1;
+ UCHAR *ROMAddr;
+
+ if((ROMAddr = (UCHAR *)HwDeviceExtension->pjVirtualRomBase) && SiS_Pr->SiS_UseROM) {
+ temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0xff;
+ temp >>= 4;
+ temp = 1 << temp;
+ temp1 = (ROMAddr[0x23e] << 8) | ROMAddr[0x23d];
+ if(temp1 & temp) return(1);
+ else return(0);
+ } else {
+ return(0);
+ }
+}
+
+void
+SiS_SetPanelDelay(SiS_Private *SiS_Pr, UCHAR *ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+ USHORT DelayTime)
+{
+ USHORT PanelID, DelayIndex, Delay;
+#ifdef SIS300
+ USHORT temp;
+#endif
+
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+
+#ifdef SIS300
+
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { /* 300 series, LVDS */
+
+ PanelID = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36);
+
+ DelayIndex = PanelID >> 4;
+
+ if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) {
+ Delay = 3;
+ } else {
+ if(DelayTime >= 2) DelayTime -= 2;
+
+ if(!(DelayTime & 0x01)) {
+ Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
+ } else {
+ Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
+ }
+ if((ROMAddr) && (SiS_Pr->SiS_UseROM)) {
+ if(ROMAddr[0x220] & 0x40) {
+ if(!(DelayTime & 0x01)) {
+ Delay = (USHORT)ROMAddr[0x225];
+ } else {
+ Delay = (USHORT)ROMAddr[0x226];
+ }
+ }
+ }
+ }
+ SiS_ShortDelay(SiS_Pr,Delay);
+
+ } else { /* 300 series, 301(B) */
+
+ PanelID = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36);
+ temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x18);
+ if(!(temp & 0x10)) PanelID = 0x12;
+
+ DelayIndex = PanelID >> 4;
+
+ if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) {
+ Delay = 3;
+ } else {
+ if(DelayTime >= 2) DelayTime -= 2;
+
+ if(!(DelayTime & 0x01)) {
+ Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
+ } else {
+ Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
+ }
+ if((ROMAddr) && (SiS_Pr->SiS_UseROM)) {
+ if(ROMAddr[0x220] & 0x40) {
+ if(!(DelayTime & 0x01)) {
+ Delay = (USHORT)ROMAddr[0x225];
+ } else {
+ Delay = (USHORT)ROMAddr[0x226];
+ }
+ }
+ }
+ }
+ SiS_ShortDelay(SiS_Pr,Delay);
+
+ }
+
+#endif /* SIS300 */
+
+ } else {
+
+ if(HwDeviceExtension->jChipType == SIS_330) return;
+
+#ifdef SIS315H
+
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { /* 310/325 series, LVDS */
+
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
+ PanelID = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36);
+ DelayIndex = PanelID >> 4;
+ if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) {
+ Delay = 3;
+ } else {
+ if(DelayTime >= 2) DelayTime -= 2;
+
+ if(!(DelayTime & 0x01)) {
+ Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[0];
+ } else {
+ Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[1];
+ }
+ if((ROMAddr) && (SiS_Pr->SiS_UseROM)) {
+ if(ROMAddr[0x13c] & 0x40) {
+ if(!(DelayTime & 0x01)) {
+ Delay = (USHORT)ROMAddr[0x17e];
+ } else {
+ Delay = (USHORT)ROMAddr[0x17f];
+ }
+ }
+ }
+ }
+ SiS_ShortDelay(SiS_Pr,Delay);
+ }
+
+ } else { /* 310/325 series, 301(B) */
+
+ PanelID = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36);
+ DelayIndex = PanelID >> 4;
+ if(!(DelayTime & 0x01)) {
+ Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
+ } else {
+ Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
+ }
+ SiS_DDC2Delay(SiS_Pr, Delay * 4);
+
+ }
+
+#endif /* SIS315H */
+
+ }
+
+}
+
+void
+SiS_LongDelay(SiS_Private *SiS_Pr, USHORT delay)
+{
+ while(delay--) {
+ SiS_GenericDelay(SiS_Pr,0x19df);
+ }
+}
+
+void
+SiS_ShortDelay(SiS_Private *SiS_Pr, USHORT delay)
+{
+ while(delay--) {
+ SiS_GenericDelay(SiS_Pr,0x42);
+ }
+}
+
+void
+SiS_GenericDelay(SiS_Private *SiS_Pr, USHORT delay)
+{
+ USHORT temp,flag;
+
+ flag = SiS_GetReg3(0x61) & 0x10;
+
+ while(delay) {
+ temp = SiS_GetReg3(0x61) & 0x10;
+ if(temp == flag) continue;
+ flag = temp;
+ delay--;
+ }
+}
+
+BOOLEAN
+SiS_Is301B(SiS_Private *SiS_Pr, USHORT BaseAddr)
+{
+ USHORT flag;
+
+ flag = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x01);
+ if(flag >= 0x0B0) return(1);
+ else return(0);
+}
+
+BOOLEAN
+SiS_CRT2IsLCD(SiS_Private *SiS_Pr, USHORT BaseAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ USHORT flag;
+
+ if(HwDeviceExtension->jChipType == SIS_730) {
+ flag = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13);
+ if(flag & 0x20) return(1);
+ }
+ flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
+ if(flag & 0x20) return(1);
+ else return(0);
+}
+
+BOOLEAN
+SiS_IsDualEdge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
+{
+#ifdef SIS315H
+ USHORT flag;
+
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ if((HwDeviceExtension->jChipType != SIS_650) || (SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) {
+ flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
+ if(flag & EnableDualEdge) return(1);
+ else return(0);
+ } else return(0);
+ } else
+#endif
+ return(0);
+}
+
+BOOLEAN
+SiS_IsVAMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
+{
+#ifdef SIS315H
+ USHORT flag;
+
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
+ if((flag & EnableDualEdge) && (flag & SetToLCDA)) return(1);
+#if 0 /* Not done in 650/301LVx 1.10.6s, but in 650/301LV */
+ else if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ if(flag) return(1);
+ else return(0);
+ }
+#endif
+ else
+ return(0);
+ } else
+#endif
+ return(0);
+ }
+
+BOOLEAN
+SiS_WeHaveBacklightCtrl(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
+{
+#ifdef SIS315H
+ USHORT flag;
+
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x79);
+ if(flag & 0x10) return(1);
+ else return(0);
+ } else
+#endif
+ return(0);
+ }
+
+#if 0
+BOOLEAN
+SiS_Is315E(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
+{
+#ifdef SIS315H
+ USHORT flag;
+
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5f);
+ if(flag & 0x10) return(1);
+ else return(0);
+ } else
+#endif
+ return(0);
+}
+#endif
+
+BOOLEAN
+SiS_IsM650or651(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
+{
+#ifdef SIS315H
+ USHORT flag;
+
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5f);
+ flag &= 0xF0;
+ if((flag == 0xb0) || (flag == 0x90)) return 0;
+ else return 1;
+ } else
+#endif
+ return 1;
+}
+
+BOOLEAN
+SiS_IsYPbPr(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
+{
+#ifdef SIS315H
+ USHORT flag;
+
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
+ if(flag & EnableLVDSHiVision) return(1); /* = YPrPb = 0x08 */
+ else return(0);
+ } else
+#endif
+ return(0);
+}
+
+BOOLEAN
+SiS_IsChScart(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
+{
+#ifdef SIS315H
+ USHORT flag;
+
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
+ if(flag & EnableLVDSScart) return(1); /* = Scart = 0x04 */
+ else return(0);
+ } else
+#endif
+ return(0);
+}
+
+BOOLEAN
+SiS_IsTVOrYPbPrOrScart(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
+{
+ USHORT flag;
+
+#ifdef SIS315H
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
+ if(flag & SetCRT2ToTV) return(1);
+ flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
+ if(flag & EnableLVDSHiVision) return(1); /* = YPrPb = 0x08 */
+ if(flag & EnableLVDSScart) return(1); /* = Scart = 0x04- TW inserted */
+ else return(0);
+ } else
+#endif
+ {
+ flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
+ if(flag & SetCRT2ToTV) return(1);
+ }
+ return(0);
+}
+
+BOOLEAN
+SiS_IsLCDOrLCDA(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
+{
+ USHORT flag;
+
+#ifdef SIS315H
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
+ if(flag & SetCRT2ToLCD) return(1);
+ flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
+ if(flag & SetToLCDA) return(1);
+ else return(0);
+ } else
+#endif
+ {
+ flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
+ if(flag & SetCRT2ToLCD) return(1);
+ }
+ return(0);
+
+}
+
+BOOLEAN
+SiS_IsDisableCRT2(SiS_Private *SiS_Pr, USHORT BaseAddr)
+{
+ USHORT flag;
+
+ flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
+ if(flag & 0x20) return(0);
+ else return(1);
+}
+
+BOOLEAN
+SiS_BridgeIsOn(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ USHORT flag;
+
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+ return(0);
+ } else {
+ flag = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x00);
+ if((flag == 1) || (flag == 2)) return(0);
+ else return(1);
+ }
+}
+
+BOOLEAN
+SiS_BridgeIsEnable(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ USHORT flag;
+
+ if(!(SiS_BridgeIsOn(SiS_Pr,BaseAddr,HwDeviceExtension))) {
+ flag = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00);
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+ /* 300 series (630/301B 2.04.5a) */
+ flag &= 0xa0;
+ if((flag == 0x80) || (flag == 0x20)) return 0;
+ else return 1;
+ } else {
+ /* 310/325 series (650/301LVx 1.10.6s) */
+ flag &= 0x50;
+ if((flag == 0x40) || (flag == 0x10)) return 0;
+ else return 1;
+ }
+ }
+ return 1;
+}
+
+BOOLEAN
+SiS_BridgeInSlave(SiS_Private *SiS_Pr)
+{
+ USHORT flag1;
+
+ flag1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31);
+ if(flag1 & (SetInSlaveMode >> 8)) return 1;
+ else return 0;
+}
+
+/* TW: New from 650/301LV(x) 1.10.6s BIOS */
+void
+SiS_SetHiVision(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+#ifdef SIS315H
+ USHORT temp;
+#endif
+
+ /* Note: This variable is only used on 30x/B/LV systems.
+ CR38 has a different meaning on LVDS/CH7019 systems.
+ */
+
+ SiS_Pr->SiS_HiVision = 0;
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+#ifdef SIS315H
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ /* TW: New from 650/301LVx BIOS 1.10.6s */
+ temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
+ if(temp & 0x04) {
+ temp &= 0x30;
+ switch(temp) {
+ case 0x00: SiS_Pr->SiS_HiVision = 4; break;
+ case 0x10: SiS_Pr->SiS_HiVision = 1; break;
+ case 0x20: SiS_Pr->SiS_HiVision = 2; break;
+ default: SiS_Pr->SiS_HiVision = 3; break;
+ }
+ }
+ }
+#endif /* SIS315H */
+ }
+}
+
+/* TW: Checked against 630/LVDS 2.08, 650/LVDS and 650/301LV BIOS */
+BOOLEAN
+SiS_GetLCDResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,
+ USHORT ModeIdIndex, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ USHORT temp,modeflag,resinfo=0;
+ const unsigned char SiS300SeriesLCDRes[] =
+ { 0, 1, 2, 3, 7, 4, 5, 8,
+ 0, 0, 0, 0, 0, 0, 0, 0 };
+
+ SiS_Pr->SiS_LCDResInfo = 0;
+ SiS_Pr->SiS_LCDTypeInfo = 0;
+ SiS_Pr->SiS_LCDInfo = 0;
+
+ if(SiS_Pr->UseCustomMode) {
+ modeflag = SiS_Pr->CModeFlag;
+ } else {
+ if(ModeNo <= 0x13) {
+ modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+ } else {
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ }
+ }
+
+ if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return 0;
+
+ if(!(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchToCRT2))) return 0;
+
+ temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36);
+
+ /* FSTN: Fake CR36 (TypeInfo 2, ResInfo SiS_Panel320x480) */
+ if(SiS_Pr->SiS_IF_DEF_FSTN) {
+ temp = 0x20 | SiS_Pr->SiS_Panel320x480;
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x36,temp);
+ }
+
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+ SiS_Pr->SiS_LCDTypeInfo = temp >> 4;
+ } else {
+ SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1;
+ }
+ temp &= 0x0f;
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+ /* TW: Translate 300 series LCDRes to 310/325 series for unified usage */
+ temp = SiS300SeriesLCDRes[temp];
+ }
+ SiS_Pr->SiS_LCDResInfo = temp;
+
+ if(SiS_Pr->SiS_IF_DEF_FSTN){
+ SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_Panel320x480;
+ }
+
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+ if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)
+ SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMin301;
+ } else {
+ if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMinLVDS)
+ SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS;
+ }
+
+ if(SiS_Pr->SiS_LCDResInfo > SiS_Pr->SiS_PanelMax)
+ SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_Panel1024x768;
+
+ temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37);
+ if(SiS_Pr->SiS_IF_DEF_FSTN){
+ /* TW: Fake LVDS bridge for FSTN */
+ temp = 0x04;
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x37,temp);
+ }
+ SiS_Pr->SiS_LCDInfo = temp;
+
+ /* TW: Inserted entire 315-block from 650/LVDS/301+LVx BIOSes */
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+#ifdef SIS315H
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+ if(ModeNo == 0x3a || ModeNo == 0x4d || ModeNo == 0x65) {
+ SiS_Pr->SiS_LCDInfo |= LCDNonExpanding;
+ }
+ }
+ }
+ }
+ if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x01) {
+ SiS_Pr->SiS_LCDInfo &= 0xFFEF;
+ SiS_Pr->SiS_LCDInfo |= LCDPass11;
+ }
+#endif
+ } else {
+#ifdef SIS300
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+ if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+ if(!(ROMAddr[0x235] & 0x02)) {
+ SiS_Pr->SiS_LCDInfo &= 0xEF;
+ }
+ }
+ } else {
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ if((SiS_Pr->SiS_SetFlag & CRT2IsVGA) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
+ SiS_Pr->SiS_LCDInfo &= 0xEF;
+ }
+ }
+ }
+#endif
+ }
+
+#ifdef LINUX_KERNEL
+ 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
+#ifdef LINUX_XF86
+ xf86DrvMsgVerb(0, X_PROBED, 3,
+ "(init301: LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n",
+ SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo);
+#endif
+
+ /* TW: With Trumpion, always Expanding */
+ if(SiS_Pr->SiS_IF_DEF_TRUMPION != 0){
+ SiS_Pr->SiS_LCDInfo &= (~LCDNonExpanding);
+ }
+
+ if(!((HwDeviceExtension->jChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & CRT2IsVGA))) {
+
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
+ if(ModeNo > 0x13) {
+ if(!(SiS_Pr->SiS_LCDInfo & LCDNonExpanding)) {
+ if((resinfo == 7) || (resinfo == 3)) {
+ SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+ }
+ }
+ }
+ }
+ if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
+ SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+ }
+ }
+
+ if(modeflag & HalfDCLK) {
+ if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
+ if(!(SiS_Pr->SiS_LCDInfo & LCDNonExpanding)) {
+ if(!(((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (HwDeviceExtension->jChipType < SIS_315H)) &&
+ (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480))) {
+ if(ModeNo > 0x13) {
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+ if(resinfo == 4) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA; /* 512x384 */
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
+ if(resinfo == 3) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA; /* 400x300 */
+ }
+ }
+ } else SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+ } else SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+ } else SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+ }
+
+ }
+
+ /* TW: wdr: if (VBInfo & LCD) && (VBInfo & (SetSimuScanMode | SwitchToCRT2)) { */
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+ if(SiS_Pr->SiS_VBInfo & SetNotSimuMode) {
+ SiS_Pr->SiS_SetFlag |= LCDVESATiming;
+ }
+ } else {
+ SiS_Pr->SiS_SetFlag |= LCDVESATiming;
+ }
+
+#ifdef SIS315H
+ /* TW: Inserted from 650/301LVx BIOS 1.10.6s */
+ if(HwDeviceExtension->jChipType > SIS_315H) {
+ if(SiS_Pr->SiS_VBType & VB_SIS30xNEW) {
+ temp = 0x00;
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) temp = 0x04;
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) temp = 0x04;
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) temp = 0x04;
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x39,temp);
+ } else if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x39,0x00);
+ }
+ }
+#endif
+
+ return 1;
+}
+
+void
+SiS_PresetScratchregister(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ return;
+ /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x30,0x21); */
+ /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x31,0x41); */
+ /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x32,0x28); */
+ /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x33,0x22); */
+ /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x35,0x43); */
+ /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x36,0x01); */
+ /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x37,0x00); */
+}
+
+void
+SiS_LongWait(SiS_Private *SiS_Pr)
+{
+ USHORT i;
+
+ i = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1F);
+
+ if(!(i & 0xC0)) {
+ for(i=0; i<0xFFFF; i++) {
+ if(!(SiS_GetReg2(SiS_Pr->SiS_P3da) & 0x08))
+ break;
+ }
+ for(i=0; i<0xFFFF; i++) {
+ if((SiS_GetReg2(SiS_Pr->SiS_P3da) & 0x08))
+ break;
+ }
+ }
+}
+
+void
+SiS_VBLongWait(SiS_Private *SiS_Pr)
+{
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
+ SiS_VBWait(SiS_Pr);
+ } else {
+ SiS_LongWait(SiS_Pr);
+ }
+ return;
+}
+
+void
+SiS_VBWait(SiS_Private *SiS_Pr)
+{
+ USHORT tempal,temp,i,j;
+
+ temp = 0;
+ for(i=0; i<3; i++) {
+ for(j=0; j<100; j++) {
+ tempal = SiS_GetReg2(SiS_Pr->SiS_P3da);
+ if(temp & 0x01) {
+ if((tempal & 0x08)) continue;
+ if(!(tempal & 0x08)) break;
+ } else {
+ if(!(tempal & 0x08)) continue;
+ if((tempal & 0x08)) break;
+ }
+ }
+ temp ^= 0x01;
+ }
+}
+
+void
+SiS_WaitVBRetrace(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+#ifdef SIS300
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ if(!(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return;
+ }
+ if(!(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x80)) {
+ SiS_WaitRetrace1(SiS_Pr,HwDeviceExtension);
+ } else {
+ SiS_WaitRetrace2(SiS_Pr,HwDeviceExtension);
+ }
+#endif
+ } else {
+#ifdef SIS315H
+ if(!(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) {
+ SiS_WaitRetrace1(SiS_Pr,HwDeviceExtension);
+ } else {
+ SiS_WaitRetrace2(SiS_Pr,HwDeviceExtension);
+ }
+#endif
+ }
+}
+
+void
+SiS_WaitRetrace1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ USHORT watchdog;
+#ifdef SIS300
+ USHORT i;
+#endif
+
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+#ifdef SIS315H
+ if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
+ watchdog = 65535;
+ while( (SiS_GetReg2(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
+ watchdog = 65535;
+ while( (!(SiS_GetReg2(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
+#endif
+ } else {
+#ifdef SIS300
+#if 0 /* TW: Not done in A901 BIOS */
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
+ }
+#endif
+ for(i=0; i<10; i++) {
+ watchdog = 65535;
+ while( (SiS_GetReg2(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
+ if(watchdog) break;
+ }
+ for(i=0; i<10; i++) {
+ watchdog = 65535;
+ while( (!(SiS_GetReg2(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
+ if(watchdog) break;
+ }
+#endif
+ }
+}
+
+void
+SiS_WaitRetraceDDC(SiS_Private *SiS_Pr)
+{
+ USHORT watchdog;
+
+ if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
+ watchdog = 65535;
+ while( (SiS_GetReg2(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
+ watchdog = 65535;
+ while( (!(SiS_GetReg2(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
+}
+
+void
+SiS_WaitRetrace2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ USHORT watchdog;
+#ifdef SIS300
+ USHORT i;
+#endif
+
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+#ifdef SIS315H
+ watchdog = 65535;
+ while( (SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x30) & 0x02) && --watchdog);
+ watchdog = 65535;
+ while( (!(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x30) & 0x02)) && --watchdog);
+#endif
+ } else {
+#ifdef SIS300
+ for(i=0; i<10; i++) {
+ watchdog = 65535;
+ while( (SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x25) & 0x02) && --watchdog);
+ if(watchdog) break;
+ }
+ for(i=0; i<10; i++) {
+ watchdog = 65535;
+ while( (!(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x25) & 0x02)) && --watchdog);
+ if(watchdog) break;
+ }
+#endif
+ }
+}
+
+/* =========== Set and Get register routines ========== */
+
+void
+SiS_SetRegANDOR(USHORT Port,USHORT Index,USHORT DataAND,USHORT DataOR)
+{
+ USHORT temp;
+
+ temp = SiS_GetReg1(Port,Index);
+ temp = (temp & (DataAND)) | DataOR;
+ SiS_SetReg1(Port,Index,temp);
+}
+
+void
+SiS_SetRegAND(USHORT Port,USHORT Index,USHORT DataAND)
+{
+ USHORT temp;
+
+ temp = SiS_GetReg1(Port,Index);
+ temp &= DataAND;
+ SiS_SetReg1(Port,Index,temp);
+}
+
+void SiS_SetRegOR(USHORT Port,USHORT Index,USHORT DataOR)
+{
+ USHORT temp;
+
+ temp = SiS_GetReg1(Port,Index);
+ temp |= DataOR;
+ SiS_SetReg1(Port,Index,temp);
+}
+
+/* ========================================================= */
+
+/* TW: Set 301 TV Encoder (and some LCD relevant) registers */
+void
+SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr, USHORT ModeNo,
+ USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ USHORT i, j, tempax, tempbx, tempcx, temp, temp1;
+ USHORT push1, push2;
+ const UCHAR *PhasePoint;
+ const UCHAR *TimingPoint;
+ const SiS_Part2PortTblStruct *CRT2Part2Ptr = NULL;
+ USHORT modeflag, resinfo, crt2crtc, resindex, CRT2Index;
+ ULONG longtemp, tempeax, tempebx, temp2, tempecx;
+ const UCHAR atable[] = {
+ 0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,
+ 0xab,0x87,0xab,0x9e,0xe7,0x02,0x02
+ };
+
+ /* TW: Inserted from 650/301LV BIOS */
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+ /* TW: Inserted from 650/301LVx 1.10.6s: (Is at end of SetGroup2!) */
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xfc,0x03);
+ temp = 1;
+ if(ModeNo <= 0x13) temp = 3;
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x0b,temp);
+ }
+ }
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+ if((ModeNo == 0x4a) || (ModeNo == 0x38)) {
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1c,0xa7);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1d,0x07);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1e,0xf2);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1f,0x6e);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x20,0x17);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x21,0x8b);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x22,0x73);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x23,0x53);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x24,0x13);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x25,0x40);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x26,0x34);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x27,0xf4);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x28,0x63);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x29,0xbb);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2a,0xcc);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2b,0x7a);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2c,0x58);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2d,0xe4);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2e,0x73);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,0xda);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,0x13);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x43,0x72);
+ }
+ }
+ }
+ }
+ return;
+ }
+
+ if(ModeNo<=0x13) {
+ modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
+ resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+ crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+ } else {
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
+ resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+ }
+
+ tempcx = SiS_Pr->SiS_VBInfo;
+ tempax = (tempcx & 0x00FF) << 8;
+ tempbx = (tempcx & 0x00FF) | ((tempcx & 0x00FF) << 8);
+ tempbx &= 0x0410;
+ temp = (tempax & 0x0800) >> 8;
+ temp >>= 1;
+ temp |= (((tempbx & 0xFF00) >> 8) << 1);
+ temp |= ((tempbx & 0x00FF) >> 3);
+ temp ^= 0x0C;
+
+ /* TW: From 1.10.7w (no vb check there) */
+ if(SiS_Pr->SiS_VBType & (VB_SIS30xLV | VB_SIS30xNEW)) {
+ temp |= 0x0c;
+ }
+
+ PhasePoint = SiS_Pr->SiS_PALPhase;
+ TimingPoint = SiS_Pr->SiS_PALTiming;
+#ifdef oldHV
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) { /* PALPhase */
+ temp ^= 0x01;
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+ TimingPoint = SiS_Pr->SiS_HiTVSt2Timing;
+ if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
+ if(modeflag & Charx8Dot) TimingPoint = SiS_Pr->SiS_HiTVSt1Timing;
+ else TimingPoint = SiS_Pr->SiS_HiTVTextTiming;
+ }
+ } else TimingPoint = SiS_Pr->SiS_HiTVExtTiming;
+ } else {
+#endif
+ if(SiS_Pr->SiS_VBInfo & SetPALTV){
+
+ TimingPoint = SiS_Pr->SiS_PALTiming;
+ PhasePoint = SiS_Pr->SiS_PALPhase;
+
+ if( (SiS_Pr->SiS_VBType & (VB_SIS301B | VB_SIS302B)) &&
+ ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+ (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) {
+ PhasePoint = SiS_Pr->SiS_PALPhase2;
+ }
+
+ } else {
+
+ temp |= 0x10;
+ TimingPoint = SiS_Pr->SiS_NTSCTiming;
+ PhasePoint = SiS_Pr->SiS_NTSCPhase;
+
+ if( (SiS_Pr->SiS_VBType & (VB_SIS301B | VB_SIS302B)) &&
+ ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+ (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) {
+ PhasePoint = SiS_Pr->SiS_NTSCPhase2;
+ }
+
+ }
+#ifdef oldHV
+ }
+#endif
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x00,temp);
+
+ temp = 0;
+ if((HwDeviceExtension->jChipType == SIS_630)||
+ (HwDeviceExtension->jChipType == SIS_730)) {
+ temp = 0x35;
+ }
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ temp = 0x38;
+ }
+ if(temp) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
+ temp1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,temp);
+ if(temp1 & EnablePALM) { /* 0x40 */
+ PhasePoint = SiS_Pr->SiS_PALMPhase;
+ if( (SiS_Pr->SiS_VBType & (VB_SIS301B | VB_SIS302B)) &&
+ ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+ (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) {
+ PhasePoint = SiS_Pr->SiS_PALMPhase2;
+ }
+ }
+ if(temp1 & EnablePALN) { /* 0x80 */
+ PhasePoint = SiS_Pr->SiS_PALNPhase;
+ if( (SiS_Pr->SiS_VBType & (VB_SIS301B | VB_SIS302B)) &&
+ ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+ (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) {
+ PhasePoint = SiS_Pr->SiS_PALNPhase2;
+ }
+ }
+ }
+ }
+ }
+
+#ifdef SIS315H
+ /* TW: Inserted from 650/301LV BIOS */
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { /* 650/301LV : 301LV | 302LV */
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+ if((ModeNo == 0x4a) || (ModeNo == 0x38)) {
+ PhasePoint = SiS_Pr->SiS_SpecialPhase;
+ }
+ }
+ }
+ }
+ }
+#endif
+
+ for(i=0x31, j=0; i<=0x34; i++, j++){
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,PhasePoint[j]);
+ }
+
+ for(i=0x01, j=0; i<=0x2D; i++, j++){
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
+ }
+ for(i=0x39; i<=0x45; i++, j++){
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
+ }
+
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ if(!(SiS_Pr->SiS_ModeType & 0x07))
+ SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
+ } else {
+ SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
+ }
+ }
+
+ SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x0A,SiS_Pr->SiS_NewFlickerMode);
+
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x35,SiS_Pr->SiS_RY1COE);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x36,SiS_Pr->SiS_RY2COE);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x37,SiS_Pr->SiS_RY3COE);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x38,SiS_Pr->SiS_RY4COE);
+
+#ifdef oldHV
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) tempax = 950;
+ else {
+#endif
+ if(SiS_Pr->SiS_VBInfo & SetPALTV) tempax = 520;
+ else tempax = 440;
+#ifdef oldHV
+ }
+#endif
+
+ if( ( ( (!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_HiVision == 3) ) && (SiS_Pr->SiS_VDE <= tempax) ) ||
+ ( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (SiS_Pr->SiS_HiVision != 3) &&
+ ( (SiS_Pr->SiS_VGAHDE == 1024) || ((SiS_Pr->SiS_VGAHDE != 1024) && (SiS_Pr->SiS_VDE <= tempax)) ) ) ) {
+
+ tempax -= SiS_Pr->SiS_VDE;
+ tempax >>= 2;
+ tempax = (tempax & 0x00FF) | ((tempax & 0x00FF) << 8);
+
+ temp = (tempax & 0xFF00) >> 8;
+ temp += (USHORT)TimingPoint[0];
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,temp);
+
+ temp = (tempax & 0xFF00) >> 8;
+ temp += (USHORT)TimingPoint[1];
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,temp);
+
+ if( (SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)) &&
+ (SiS_Pr->SiS_HiVision != 3) &&
+ (SiS_Pr->SiS_VGAHDE >= 1024) ) {
+ if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x19);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x52);
+ } else {
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x17);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x1d);
+ } else {
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x0b);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x11);
+ }
+ }
+ }
+
+ }
+
+ tempcx = SiS_Pr->SiS_HT;
+
+ /* TW: Inserted from 650/301LVx 1.10.6s */
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) {
+ tempcx >>= 1;
+ }
+ }
+
+ tempcx--;
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ tempcx--;
+ }
+ temp = tempcx & 0x00FF;
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1B,temp);
+ temp = (tempcx & 0xFF00) >> 8;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0xF0,temp);
+
+ tempcx++;
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ tempcx++;
+ }
+ tempcx >>= 1;
+
+ push1 = tempcx;
+
+ tempcx += 7;
+#ifdef oldHV
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) tempcx -= 4;
+#endif
+ temp = (tempcx & 0x00FF) << 4;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,temp);
+
+ tempbx = TimingPoint[j] | ((TimingPoint[j+1]) << 8);
+ tempbx += tempcx;
+
+ push2 = tempbx;
+
+ temp = tempbx & 0x00FF;
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x24,temp);
+ temp = ((tempbx & 0xFF00) >> 8) << 4;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0F,temp);
+
+ tempbx = push2;
+
+ tempbx += 8;
+#ifdef oldHV
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
+ tempbx -= 4;
+ tempcx = tempbx;
+ }
+#endif
+ temp = (tempbx & 0x00FF) << 4;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x29,0x0F,temp);
+
+ j += 2;
+ tempcx += ((TimingPoint[j] | ((TimingPoint[j+1]) << 8)));
+ temp = tempcx & 0x00FF;
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x27,temp);
+ temp = ((tempcx & 0xFF00) >> 8) << 4;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x28,0x0F,temp);
+
+ tempcx += 8;
+#ifdef oldHV
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) tempcx -= 4;
+#endif
+ temp = (tempcx & 0x00FF) << 4;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2A,0x0F,temp);
+
+ tempcx = push1;
+
+ j += 2;
+ tempcx -= (TimingPoint[j] | ((TimingPoint[j+1]) << 8));
+ temp = (tempcx & 0x00FF) << 4;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2D,0x0F,temp);
+
+ tempcx -= 11;
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
+ tempax = SiS_GetVGAHT2(SiS_Pr) - 1;
+ tempcx = tempax;
+ }
+ temp = tempcx & 0x00FF;
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2E,temp);
+
+ tempbx = SiS_Pr->SiS_VDE;
+ if(SiS_Pr->SiS_VGAVDE == 360) tempbx = 746;
+ if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 746;
+ if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 853;
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempbx >>= 1;
+ } else {
+ if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (!(SiS_Pr->SiS_HiVision & 0x03))) {
+ tempbx >>= 1;
+ if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
+ if(ModeNo <= 0x13) {
+ if(crt2crtc == 1) {
+ tempbx++;
+ }
+ }
+ } else {
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+ if(crt2crtc == 4) /* TW: BIOS calls GetRatePtrCRT2 here - does not make sense */
+ if(SiS_Pr->SiS_ModeType <= 3) tempbx++;
+ }
+ }
+ }
+ }
+ tempbx -= 2;
+ temp = tempbx & 0x00FF;
+#ifdef oldHV
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+ if(ModeNo == 0x2f) temp++;
+ }
+ }
+#endif
+ /* TW: From 1.10.7w - doesn't make sense */
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+ if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+ if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) { /* SetFlag?? */
+ if(ModeNo == 0x03) temp++;
+ }
+ }
+ }
+ }
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2F,temp);
+
+ tempax = (tempcx & 0xFF00) | (tempax & 0x00FF);
+ tempbx = ((tempbx & 0xFF00) << 6) | (tempbx & 0x00FF);
+ tempax |= (tempbx & 0xFF00);
+#ifdef oldHV
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV)) {
+#endif
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART)) { /* TW: New from 630/301B (II) BIOS */
+ tempax |= 0x1000;
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO)) tempax |= 0x2000;
+ }
+ } else {
+ tempax |= 0x1000;
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO)) tempax |= 0x2000;
+ }
+#ifdef oldHV
+ }
+#endif
+ temp = (tempax & 0xFF00) >> 8;
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,temp);
+
+ /* TW: Inserted from 650/301LVx 1.10.6s */
+ if(HwDeviceExtension->jChipType > SIS_315H) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ if( (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) ||
+ (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) ) {
+ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x10,0x60);
+ }
+ }
+ }
+
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { /* tv gatingno */
+ tempbx = SiS_Pr->SiS_VDE;
+ if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (!(SiS_Pr->SiS_HiVision & 0x03))) {
+ tempbx >>= 1;
+ }
+ tempbx -= 3;
+ tempbx &= 0x03ff;
+ temp = ((tempbx & 0xFF00) >> 8) << 5;
+ temp |= 0x18;
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x46,temp);
+ temp = tempbx & 0x00FF;
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x47,temp);
+ if(HwDeviceExtension->jChipType >= SIS_315H) { /* TW: Inserted from 650/301LVx 1.10.6s */
+ tempax = 0;
+ if(SiS_Pr->SiS_HiVision & 0x07) {
+ if(SiS_Pr->SiS_HiVision & 0x04) tempax = 0x1000;
+ else if(SiS_Pr->SiS_HiVision & 0x01) tempax = 0x3000;
+ else tempax = 0x5000;
+ }
+ temp = (tempax & 0xFF00) >> 8;
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4d,temp);
+ }
+ }
+
+ tempbx &= 0x00FF;
+ if(!(modeflag & HalfDCLK)) {
+ tempcx = SiS_Pr->SiS_VGAHDE;
+ if(tempcx >= SiS_Pr->SiS_HDE) {
+ tempbx |= 0x2000;
+ tempax &= 0x00FF;
+ }
+ }
+
+ tempcx = 0x0101;
+/*if(SiS_Pr->SiS_VBInfo & (SetPALTV | SetCRT2ToTV)) { */ /*301b- TW: BIOS BUG? */
+ if(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)) {
+ if(!(SiS_Pr->SiS_HiVision & 0x03)) {
+ if(SiS_Pr->SiS_VGAHDE >= 1024) {
+ if((!(modeflag & HalfDCLK)) ||
+ (HwDeviceExtension->jChipType < SIS_315H)) { /* TW: This check not in 630/301B */
+ tempcx = 0x1920;
+ if(SiS_Pr->SiS_VGAHDE >= 1280) {
+ tempcx = 0x1420;
+ tempbx &= 0xDFFF;
+ }
+ }
+ }
+ }
+ }
+
+ if(!(tempbx & 0x2000)){
+ if(modeflag & HalfDCLK) {
+ tempcx = (tempcx & 0xFF00) | (((tempcx & 0x00FF) << 1) & 0xff);
+ }
+ push1 = tempbx;
+ tempeax = SiS_Pr->SiS_VGAHDE;
+ tempebx = (tempcx & 0xFF00) >> 8;
+ longtemp = tempeax * tempebx;
+ tempecx = tempcx & 0x00FF;
+ longtemp /= tempecx;
+ longtemp <<= 0x0d;
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ longtemp <<= 3;
+ }
+ tempecx = SiS_Pr->SiS_HDE;
+ temp2 = longtemp % tempecx;
+ tempeax = longtemp / tempecx;
+ if(temp2 != 0) tempeax++;
+ tempax = (USHORT)tempeax;
+ tempbx = push1;
+ tempcx = (tempcx & 0xff00) | (((tempax & 0xFF00) >> 8) >> 5);
+ tempbx |= (tempax & 0x1F00);
+ tempax = ((tempax & 0x00FF) << 8) | (tempax & 0x00FF);
+ }
+
+ temp = (tempax & 0xFF00) >> 8;
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x44,temp);
+ temp = (tempbx & 0xFF00) >> 8;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,temp);
+
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ temp = tempcx & 0x00FF;
+ if(tempbx & 0x2000) temp = 0;
+ temp |= 0x18;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xE0,temp);
+ if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+ tempbx = 0x0382; /* TW: BIOS; Was 0x0364; */
+ tempcx = 0x007e; /* TW: BIOS; Was 0x009c; */
+ } else {
+ tempbx = 0x0369; /* TW: BIOS; Was 0x0346; */
+ tempcx = 0x0061; /* TW: BIOS; Was 0x0078; */
+ }
+ temp = (tempbx & 0x00FF) ;
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4B,temp);
+ temp = (tempcx & 0x00FF) ;
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4C,temp);
+ tempbx &= 0x03FF;
+ temp = (tempcx & 0xFF00) >> 8;
+ temp = (temp & 0x0003) << 2;
+ temp |= (tempbx >> 8);
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4D,temp);
+ } else {
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4D,0xF0,temp);
+ }
+
+ temp = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x43);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x43,(USHORT)(temp - 3));
+ }
+
+ temp = 0;
+ if((HwDeviceExtension->jChipType == SIS_630) ||
+ (HwDeviceExtension->jChipType == SIS_730)) {
+ temp = 0x35;
+ } else if(HwDeviceExtension->jChipType >= SIS_315H) {
+ temp = 0x38;
+ }
+ if(temp) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
+ if(SiS_GetReg1(SiS_Pr->SiS_P3d4,temp) & EnablePALM) { /* 0x40 */
+ SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF);
+ temp = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x01);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,temp - 1);
+ }
+ }
+ }
+ }
+
+
+#ifdef oldHV
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
+ if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x0B,0x00);
+ }
+ }
+#endif
+
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ SiS_Set300Part2Regs(SiS_Pr, HwDeviceExtension, ModeIdIndex,
+ RefreshRateTableIndex, BaseAddr, ModeNo);
+ return;
+ }
+ } else {
+ /* TW: !!! The following is a duplicate, done for LCDA as well (see above) */
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { /* 650/301LV: (VB_SIS301LV | VB_SIS302LV)) */
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+ if((ModeNo == 0x4a) || (ModeNo == 0x38)) {
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1c,0xa7);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1d,0x07);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1e,0xf2);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1f,0x6e);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x20,0x17);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x21,0x8b);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x22,0x73);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x23,0x53);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x24,0x13);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x25,0x40);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x26,0x34);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x27,0xf4);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x28,0x63);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x29,0xbb);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2a,0xcc);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2b,0x7a);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2c,0x58);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2d,0xe4);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2e,0x73);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,0xda);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,0x13);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x43,0x72);
+ }
+ }
+ }
+ }
+ return;
+ }
+ }
+
+ /* TW: From here: Part2 LCD setup */
+
+ tempbx = SiS_Pr->SiS_HDE;
+ /* TW: Inserted from 650/301LVx 1.10.6s */
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) tempbx >>= 1;
+ }
+ tempbx--; /* RHACTE=HDE-1 */
+ temp = tempbx & 0x00FF;
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2C,temp);
+ temp = (tempbx & 0xFF00) >> 8;
+ temp <<= 4;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,temp);
+
+ temp = 0x01;
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+ if(SiS_Pr->SiS_ModeType == ModeEGA) {
+ if(SiS_Pr->SiS_VGAHDE >= 1024) {
+ temp = 0x02;
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
+ temp = 0x01;
+ }
+ }
+ }
+ }
+ }
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x0B,temp);
+
+ tempbx = SiS_Pr->SiS_VDE; /* RTVACTEO=(VDE-1)&0xFF */
+ push1 = tempbx;
+
+ tempbx--;
+ temp = tempbx & 0x00FF;
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x03,temp);
+ temp = ((tempbx & 0xFF00) >> 8) & 0x07;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0C,0xF8,temp);
+
+ tempcx = SiS_Pr->SiS_VT;
+ push2 = tempcx;
+
+ tempcx--;
+ temp = tempcx & 0x00FF; /* RVTVT=VT-1 */
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x19,temp);
+
+ temp = (tempcx & 0xFF00) >> 8;
+ temp <<= 5;
+ if((HwDeviceExtension->jChipType == SIS_300) && (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
+ if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) temp |= 0x10;
+ } else if(HwDeviceExtension->jChipType < SIS_315H) {
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp |= 0x10;
+ else {
+ if(SiS_Pr->SiS_LCDInfo & LCDSync) /* TW: 630/301 BIOS checks this */
+ temp |= 0x10;
+ }
+ } else {
+ if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+ /* TW: Inserted from 630/301LVx 1.10.6s */
+ if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
+ if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
+ temp |= 0x10;
+ }
+ }
+ } else {
+ temp |= 0x10;
+ }
+ }
+
+ /* 630/301 does not do all this */
+ if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
+ if((HwDeviceExtension->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
+ /* TW: Inserted from 650/301LVx 1.10.6s */
+ temp |= (SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37) >> 6);
+ temp |= 0x08; /* From 1.10.7w */
+ if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) temp |= 0x04; /* From 1.10.7w */
+ } else {
+ tempbx = (tempbx & 0xFF00) | (SiS_Pr->SiS_LCDInfo & 0x0FF);
+ if(tempbx & LCDSync) {
+ tempbx &= (0xFF00 | LCDSyncBit);
+ tempbx = (tempbx & 0xFF00) | ((tempbx & 0x00FF) >> LCDSyncShift);
+ temp |= (tempbx & 0x00FF);
+ }
+ }
+ }
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1A,temp);
+
+ SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x09,0xF0);
+ SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x0A,0xF0);
+
+ SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB);
+ SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF);
+
+ /* 1280x960, 1280x1024 and 1600x1200 data invalid/missing in tables, use old calculation */
+ if((HwDeviceExtension->jChipType >= SIS_315H) &&
+ (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
+ (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024) &&
+ (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1600x1200) &&
+ (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x960)) {
+ /* ------------- 310 series ------------ */
+
+ /* TW: Inserted this entire section from 650/301LV(x) BIOS */
+
+ SiS_GetCRT2Part2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+ &CRT2Index,&resindex);
+
+ switch(CRT2Index) {
+ case Panel_1024x768 : CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1; break; /* "Normal" */
+ case Panel_1280x1024 : CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1280x1024_1; break;
+ case Panel_1400x1050 : CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1400x1050_1; break;
+ case Panel_1600x1200 : CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1600x1200_1; break;
+ case Panel_1024x768 + 16 : CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2; break; /* Non-Expanding */
+ case Panel_1280x1024 + 16: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1280x1024_2; break;
+ case Panel_1400x1050 + 16: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1400x1050_2; break;
+ case Panel_1600x1200 + 16: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1600x1200_2; break;
+ case Panel_1024x768 + 32 : CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_3; break; /* VESA Timing */
+ case Panel_1280x1024 + 32: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1280x1024_3; break;
+ case Panel_1400x1050 + 32: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1400x1050_3; break;
+ case Panel_1600x1200 + 32: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1600x1200_3; break;
+ default: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_3; break;
+ }
+
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
+ for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
+ }
+ for(j = 0x1c; j <= 0x1d; i++, j++ ) {
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
+ }
+ for(j = 0x1f; j <= 0x21; i++, j++ ) {
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
+ }
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
+
+ if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
+ if(SiS_Pr->SiS_VGAVDE == 0x20d) {
+ temp = 0xc3;
+ if(SiS_Pr->SiS_ModeType <= ModeVGA) {
+ temp++;
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp += 2;
+ }
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,temp);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,0xb3);
+ }
+ if(SiS_Pr->SiS_VGAVDE == 0x1a4) {
+ temp = 0x4d;
+ if(SiS_Pr->SiS_ModeType <= ModeVGA) {
+ temp++;
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp++;
+ }
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,temp);
+ }
+ }
+
+ /* TW: Inserted from 650/301LVx 1.10.6s: */
+ /* !!! This is a duplicate, done for LCDA as well - see above */
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xfc,0x03); /* Not done in 1.10.7w */
+ temp = 1;
+ if(ModeNo <= 0x13) temp = 3;
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x0b,temp);
+ }
+ }
+
+ } else { /* ------------- 300 series (and other LCD resolutions) ----------- */
+
+ tempcx++;
+ tempbx = 768;
+ if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1024x768) {
+ tempbx = 1024;
+ if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024) {
+ tempbx = 1200;
+ if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1600x1200) {
+ if(tempbx != SiS_Pr->SiS_VDE) {
+ tempbx = 960;
+ }
+ }
+ }
+ }
+ if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) {
+ tempbx = SiS_Pr->SiS_VDE - 1;
+ tempcx--;
+ }
+ tempax = 1;
+ if(!(SiS_Pr->SiS_LCDInfo & LCDNonExpanding)) {
+ if(tempbx != SiS_Pr->SiS_VDE){
+ tempax = tempbx;
+ if(tempax < SiS_Pr->SiS_VDE) {
+ tempax = 0;
+ tempcx = 0;
+ } else {
+ tempax -= SiS_Pr->SiS_VDE;
+ }
+ tempax >>= 1;
+ }
+ tempcx -= tempax; /* lcdvdes */
+ tempbx -= tempax; /* lcdvdee */
+ } else {
+ tempax >>= 1;
+ tempcx -= tempax; /* lcdvdes */
+ tempbx -= tempax; /* lcdvdee */
+ }
+
+ temp = tempcx & 0x00FF; /* RVEQ1EQ=lcdvdes */
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x05,temp);
+ temp = tempbx & 0x00FF; /* RVEQ2EQ=lcdvdee */
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x06,temp);
+
+ temp = ((tempbx & 0xFF00) >> 8 ) << 3;
+ temp |= ((tempcx & 0xFF00) >> 8);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,temp);
+
+ tempbx = push2;
+ tempax = push1;
+ tempcx = tempbx;
+ tempcx -= tempax;
+ tempcx >>= 4;
+ tempbx += tempax;
+ tempbx >>= 1;
+ if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) tempbx -= 10;
+
+ temp = tempbx & 0x00FF; /* RTVACTEE=lcdvrs */
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,temp);
+
+ temp = ((tempbx & 0xFF00) >> 8) << 4;
+ tempbx += (tempcx + 1);
+ temp |= (tempbx & 0x000F);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,temp);
+
+ /* TW: Code from 630/301B (I+II) BIOS */
+
+ if( ( ( (HwDeviceExtension->jChipType == SIS_630) ||
+ (HwDeviceExtension->jChipType == SIS_730) ) &&
+ (HwDeviceExtension->jChipRevision > 2) ) &&
+ (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) &&
+ (!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) &&
+ (!(SiS_Pr->SiS_LCDInfo & LCDNonExpanding)) ) {
+ if(ModeNo == 0x13) {
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,0xB9);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x05,0xCC);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x06,0xA6);
+ } else {
+ if((crt2crtc & 0x3F) == 4) {
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x2B);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x13);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,0xE5);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x05,0x08);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x06,0xE2);
+ }
+ }
+ }
+
+ /* TW: Inserted missing code from 630/301B BIOS: (II: 3258) */
+
+ if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
+ crt2crtc &= 0x1f;
+ tempcx = 0;
+ if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
+ if (SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+ tempcx += 7;
+ }
+ }
+ tempcx += crt2crtc;
+ if (crt2crtc >= 4) {
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x06,0xff);
+ }
+
+ if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+ if(crt2crtc == 4) {
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x28);
+ }
+ }
+ }
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x18);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
+ }
+
+ tempcx = (SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE) >> 2; /* (HT-HDE)>>2 */
+ tempbx = SiS_Pr->SiS_HDE + 7; /* lcdhdee */
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ tempbx += 2;
+ }
+ push1 = tempbx;
+ temp = tempbx & 0x00FF; /* RHEQPLE=lcdhdee */
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x23,temp);
+ temp = (tempbx & 0xFF00) >> 8;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0xF0,temp);
+
+ temp = 7;
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ temp += 2;
+ }
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1F,temp); /* RHBLKE=lcdhdes */
+
+ SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x20,0x0F);
+
+ tempbx += tempcx;
+ push2 = tempbx;
+ temp = tempbx & 0xFF; /* RHBURSTS=lcdhrs */
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+ if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) {
+ if(SiS_Pr->SiS_HDE == 1280) temp = 0x47;
+ }
+ }
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1C,temp);
+ temp = ((tempbx & 0xFF00) >> 8) << 4;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,temp);
+
+ tempbx = push2;
+ tempcx <<= 1;
+ tempbx += tempcx;
+ temp = tempbx & 0x00FF; /* RHSYEXP2S=lcdhre */
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x21,temp);
+
+ if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
+ if(SiS_Pr->SiS_VGAVDE == 525) {
+ if(SiS_Pr->SiS_ModeType <= ModeVGA)
+ temp=0xC6;
+ else
+ temp=0xC3;
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,temp);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,0xB3);
+ } else if(SiS_Pr->SiS_VGAVDE == 420) {
+ if(SiS_Pr->SiS_ModeType <= ModeVGA)
+ temp=0x4F;
+ else
+ temp=0x4D; /* 650: 4e */
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,temp);
+ }
+ }
+ SiS_Set300Part2Regs(SiS_Pr, HwDeviceExtension, ModeIdIndex,
+ RefreshRateTableIndex, BaseAddr, ModeNo);
+
+ } /* HwDeviceExtension */
+}
+
+USHORT
+SiS_GetVGAHT2(SiS_Private *SiS_Pr)
+{
+ ULONG tempax,tempbx;
+
+ tempbx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) * SiS_Pr->SiS_RVBHCMAX) & 0xFFFF;
+ tempax = (SiS_Pr->SiS_VT - SiS_Pr->SiS_VDE) * SiS_Pr->SiS_RVBHCFACT;
+ tempax = (tempax * SiS_Pr->SiS_HT) / tempbx;
+ return((USHORT) tempax);
+}
+
+/* TW: New from 300/301LV BIOS 1.16.51. Seems highly preliminary. */
+void
+SiS_Set300Part2Regs(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+ USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
+ USHORT BaseAddr, USHORT ModeNo)
+{
+ USHORT crt2crtc, resindex;
+ int i,j;
+ const SiS_Part2PortTblStruct *CRT2Part2Ptr = NULL;
+
+ if(HwDeviceExtension->jChipType != SIS_300) return;
+ if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) return;
+
+ if(ModeNo<=0x13) {
+ crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+ } else {
+ crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+ }
+
+ resindex = crt2crtc & 0x3F;
+ if(SiS_Pr->SiS_SetFlag & LCDVESATiming) CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
+ else CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2;
+
+ /* TW: The BIOS code (1.16.51) is obviously a fragment! */
+ if(ModeNo > 0x13) {
+ CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
+ resindex = 4;
+ }
+
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
+ for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
+ }
+ for(j = 0x1c; j <= 0x1d; i++, j++ ) {
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
+ }
+ for(j = 0x1f; j <= 0x21; i++, j++ ) {
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
+ }
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
+}
+
+/* TW: Set 301 Macrovision(tm) registers */
+/* TW: Double-Checked against 650/301LV, 650/301LVx and 630/301B BIOS */
+void
+SiS_SetGroup3(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+ USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ USHORT temp;
+#ifdef oldHV
+ USHORT i;
+ const UCHAR *tempdi;
+#endif
+ USHORT modeflag;
+
+ /* TW: Inserted from 650/301LVx 1.10.6s, 1.10.7w */
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
+
+ if(ModeNo<=0x13)
+ modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+ else
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+
+ SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x00,0x00);
+
+ if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+ SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xFA);
+ SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xC8);
+ } else {
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xF5);
+ SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xB7);
+ } else {
+ SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xF6);
+ SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xBf);
+ }
+ }
+
+ temp = 0;
+ if((HwDeviceExtension->jChipType == SIS_630)||
+ (HwDeviceExtension->jChipType == SIS_730)) {
+ temp = 0x35;
+ } else if(HwDeviceExtension->jChipType >= SIS_315H) {
+ temp = 0x38;
+ }
+ if(temp) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
+ if(SiS_GetReg1(SiS_Pr->SiS_P3d4,temp) & EnablePALM){ /* 0x40 */
+ SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xFA);
+ SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xC8);
+ SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x3D,0xA8);
+ }
+ }
+ }
+ }
+
+#ifdef oldHV
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
+ tempdi = SiS_Pr->SiS_HiTVGroup3Data;
+ if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
+ tempdi = SiS_Pr->SiS_HiTVGroup3Simu;
+ if(!(modeflag & Charx8Dot)) {
+ tempdi = SiS_Pr->SiS_HiTVGroup3Text;
+ }
+ }
+ for(i=0; i<=0x3E; i++){
+ SiS_SetReg1(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
+ }
+ }
+#endif
+
+ return;
+}
+
+/* TW: Set 301 VGA2 registers */
+/* TW: Double-Checked against 650/301LV(x) and 630/301B BIOS */
+void
+SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+ USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ USHORT tempax,tempcx,tempbx,modeflag,temp,temp2,resinfo;
+ ULONG tempebx,tempeax,templong;
+
+
+ if(ModeNo<=0x13) {
+ modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+ resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+ } else {
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ }
+
+ /* TW: From 650/301LVx 1.10.6s BIOS */
+ if(SiS_Pr->SiS_VBType & (VB_SIS30xLV | VB_SIS30xNEW)) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x24,0x0e);
+ }
+ }
+
+ if(SiS_Pr->SiS_VBType & VB_SIS30xNEW) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x10,0x9f);
+ }
+ }
+
+ /* TW: From 650/301LV BIOS (any, incl. 1.10.6s, 1.10.7w) */
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+ /* TW: This is a duplicate; done at the end, too */
+ if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) {
+ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
+ }
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x2a,0x00);
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
+ return;
+ }
+
+ temp = SiS_Pr->SiS_RVBHCFACT;
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x13,temp);
+
+ tempbx = SiS_Pr->SiS_RVBHCMAX;
+ temp = tempbx & 0x00FF;
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x14,temp);
+
+ temp2 = (((tempbx & 0xFF00) >> 8) << 7) & 0x00ff;
+
+ tempcx = SiS_Pr->SiS_VGAHT - 1;
+ temp = tempcx & 0x00FF;
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x16,temp);
+
+ temp = (((tempcx & 0xFF00) >> 8) << 3) & 0x00ff;
+ temp2 |= temp;
+
+ tempcx = SiS_Pr->SiS_VGAVT - 1;
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempcx -= 5;
+
+ temp = tempcx & 0x00FF;
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x17,temp);
+
+ temp = temp2 | ((tempcx & 0xFF00) >> 8);
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x15,temp);
+
+ tempcx = SiS_Pr->SiS_VBInfo;
+ tempbx = SiS_Pr->SiS_VGAHDE;
+ if(modeflag & HalfDCLK) tempbx >>= 1;
+
+ /* TW: New for 650/301LV and 630/301B */
+ temp = 0xA0;
+#ifdef oldHV
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
+ temp = 0;
+ if(tempbx > 800) {
+ temp = 0xA0;
+ if(tempbx != 1024) {
+ temp = 0xC0;
+ if(tempbx != 1280) temp = 0;
+ }
+ }
+ } else
+#endif
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ if(tempbx <= 800) {
+ temp = 0x80;
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD){
+ temp = 0;
+ if(tempbx > 800) temp = 0x60;
+ }
+ }
+ } else {
+ temp = 0x80;
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD){
+ temp = 0;
+ if(tempbx > 800) temp = 0x60;
+ }
+ }
+ if(SiS_Pr->SiS_HiVision & 0x03) {
+ temp = 0;
+ if(SiS_Pr->SiS_VGAHDE == 1024) temp = 0x20;
+ }
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) temp = 0;
+ }
+
+ if(SiS_Pr->SiS_VBType & VB_SIS301) {
+ if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024)
+ temp |= 0x0A;
+ }
+
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0E,0x10,temp);
+
+ tempebx = SiS_Pr->SiS_VDE;
+
+#ifdef oldHV
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
+ if(!(temp & 0xE0)) tempebx >>=1;
+ }
+#endif
+
+ tempcx = SiS_Pr->SiS_RVBHRS;
+ temp = tempcx & 0x00FF;
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x18,temp);
+
+ tempeax = SiS_Pr->SiS_VGAVDE;
+ tempcx |= 0x4000;
+ if(tempeax <= tempebx){
+ tempcx ^= 0x4000;
+ } else {
+ tempeax -= tempebx;
+ }
+
+ templong = (tempeax * 256 * 1024) % tempebx;
+ tempeax = (tempeax * 256 * 1024) / tempebx;
+ tempebx = tempeax;
+ if(templong != 0) tempebx++;
+
+ temp = (USHORT)(tempebx & 0x000000FF);
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1B,temp);
+ temp = (USHORT)((tempebx & 0x0000FF00) >> 8);
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1A,temp);
+
+ tempbx = (USHORT)(tempebx >> 16);
+ temp = tempbx & 0x00FF;
+ temp <<= 4;
+ temp |= ((tempcx & 0xFF00) >> 8);
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x19,temp);
+
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1C,0x28);
+ tempbx = 0;
+ tempax = SiS_Pr->SiS_VGAHDE;
+ if(modeflag & HalfDCLK) tempax >>= 1;
+ if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) || (SiS_Pr->SiS_HiVision & 0x03)) {
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) tempax >>= 1;
+ else if(tempax > 800) tempax -= 800;
+ } else {
+ if(tempax > 800) tempax -= 800;
+ }
+ }
+
+/* if((SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetPALTV)) && (!(SiS_Pr->SiS_HiVision & 0x03))) { */
+ if((SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)) && (!(SiS_Pr->SiS_HiVision & 0x03))) {
+ if(tempax > 800) {
+ tempbx = 8;
+ if(tempax == 1024)
+ tempax *= 25;
+ else
+ tempax *= 20;
+
+ temp = tempax % 32;
+ tempax /= 32;
+ tempax--;
+ if (temp!=0) tempax++;
+ }
+ }
+ tempax--;
+ temp = (tempax & 0xFF00) >> 8;
+ temp &= 0x03;
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* From 1.10.7w */
+ if(ModeNo > 0x13) { /* From 1.10.7w */
+ if(resinfo == 8) tempax = 0x1f; /* From 1.10.7w */
+ } /* From 1.10.7w */
+ } /* From 1.10.7w */
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1D,tempax & 0x00FF);
+ temp <<= 4;
+ temp |= tempbx;
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1E,temp);
+
+ if(HwDeviceExtension->jChipType > SIS_315H) {
+ temp = 0x0026; /* From 1.10.7w; 1.10.6s: 0x0036 */
+ } else {
+ temp = 0x0036;
+ }
+ if((SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)) &&
+ (!(SiS_Pr->SiS_HiVision & 0x03))) {
+ temp |= 0x01;
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+ if(!(SiS_Pr->SiS_SetFlag & TVSimuMode))
+ temp &= 0xFE;
+ }
+ }
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0,temp);
+
+ tempbx = SiS_Pr->SiS_HT;
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) tempbx >>= 1;
+ }
+ tempbx >>= 1;
+ tempbx -= 2;
+ temp = ((tempbx & 0x0700) >> 8) << 3;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp);
+ temp = tempbx & 0x00FF;
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x22,temp);
+ if( (SiS_Pr->SiS_VBType & (VB_SIS30xLV | VB_SIS30xNEW)) &&
+ (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ) {
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x24,0x0e);
+ }
+
+ /* TW: 650 BIOS does this for all bridge types - assumingly wrong */
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ /* TW: This is a duplicate; done for LCDA as well (see above) */
+ if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) {
+ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
+ }
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x2a,0x00);
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
+ } else if(HwDeviceExtension->jChipType == SIS_300) {
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x2a,0x00);
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
+ }
+
+ } /* 301B */
+
+ SiS_SetCRT2VCLK(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
+ RefreshRateTableIndex,HwDeviceExtension);
+}
+
+/* TW: Double-Checked against 650/301LV(x) and 630/301B BIOS */
+void
+SiS_SetCRT2VCLK(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ USHORT vclkindex;
+ USHORT tempah;
+
+ vclkindex = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+ HwDeviceExtension);
+
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ tempah = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0A,tempah);
+ tempah = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0B,tempah);
+ /* TW: New from 650/301LV, LVx BIOS (300/301LV does not do this) */
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { /* 650/301LV: (VB_SIS301LV | VB_SIS302LV)) */
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+ if((ModeNo == 0x4a) || (ModeNo == 0x38)) {
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0a,0x57);
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0b,0x46);
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1f,0xf6);
+ }
+ }
+ }
+ }
+ }
+ } else { /* 650/301LVx does not do this anymore, jumps to SetRegs above - BUG? */
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0A,0x01);
+ tempah = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0B,tempah);
+ tempah = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0A,tempah);
+ }
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x12,0x00);
+ tempah = 0x08;
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
+ tempah |= 0x20;
+ }
+ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,tempah);
+}
+
+/* TW: Double-checked against 650/LVDS (1.10.07), 630/301B/LVDS/LVDS+CH, 650/301LVx (1.10.6s) BIOS */
+USHORT
+SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ USHORT tempbx;
+#ifdef SIS300
+ const USHORT LCDXlat1VCLK300[4] = {VCLK65, VCLK65, VCLK65, VCLK65};
+ const USHORT LCDXlat2VCLK300[4] = {VCLK108_2,VCLK108_2,VCLK108_2,VCLK108_2};
+ const USHORT LVDSXlat2VCLK300[4]= {VCLK65, VCLK65, VCLK65, VCLK65};
+ const USHORT LVDSXlat3VCLK300[4]= {VCLK65, VCLK65, VCLK65, VCLK65};
+#endif
+#ifdef SIS315H
+ const USHORT LCDXlat1VCLK310[4] = {VCLK65+2, VCLK65+2, VCLK65+2, VCLK65+2};
+ const USHORT LCDXlat2VCLK310[4] = {VCLK108_2+5,VCLK108_2+5,VCLK108_2+5,VCLK108_2+5};
+ const USHORT LVDSXlat2VCLK310[4]= {VCLK65+2, VCLK65+2, VCLK65+2, VCLK65+2};
+ const USHORT LVDSXlat3VCLK310[4]= {VCLK108_2+5,VCLK108_2+5,VCLK108_2+5,VCLK108_2+5};
+ /* {VCLK65+2, VCLK65+2, VCLK65+2, VCLK65+2}; - 650/LVDS 1.10.07 */
+#endif
+ const USHORT LCDXlat0VCLK[4] = {VCLK40, VCLK40, VCLK40, VCLK40};
+ const USHORT LVDSXlat1VCLK[4] = {VCLK40, VCLK40, VCLK40, VCLK40};
+ USHORT CRT2Index,VCLKIndex=0;
+ USHORT modeflag,resinfo;
+ const UCHAR *CHTVVCLKPtr=NULL;
+ const USHORT *LCDXlatVCLK1 = NULL;
+ const USHORT *LCDXlatVCLK2 = NULL;
+ const USHORT *LVDSXlatVCLK2 = NULL;
+ const USHORT *LVDSXlatVCLK3 = NULL;
+
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+#ifdef SIS315H
+ LCDXlatVCLK1 = LCDXlat1VCLK310;
+ LCDXlatVCLK2 = LCDXlat2VCLK310;
+ LVDSXlatVCLK2 = LVDSXlat2VCLK310;
+ LVDSXlatVCLK3 = LVDSXlat3VCLK310;
+#endif
+ } else {
+#ifdef SIS300
+ LCDXlatVCLK1 = LCDXlat1VCLK300;
+ LCDXlatVCLK2 = LCDXlat2VCLK300;
+ LVDSXlatVCLK2 = LVDSXlat2VCLK300;
+ LVDSXlatVCLK3 = LVDSXlat3VCLK300;
+#endif
+ }
+
+ if(ModeNo <= 0x13) {
+ modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+ resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+ CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+ } else {
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+ }
+
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) { /* 301 */
+
+ if (SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
+
+ CRT2Index >>= 6;
+ if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)){ /* LCD */
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+ /* TW: Inserted from 630/301B BIOS */
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)
+ VCLKIndex = LCDXlat0VCLK[CRT2Index];
+ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)
+ VCLKIndex = LCDXlatVCLK1[CRT2Index];
+ else
+ VCLKIndex = LCDXlatVCLK2[CRT2Index];
+ } else {
+ /* TW: 330, 650/301LV BIOS does not check expanding, 315 does */
+ if( (HwDeviceExtension->jChipType > SIS_315PRO) ||
+ (!(SiS_Pr->SiS_LCDInfo & LCDNonExpanding)) ) {
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+ VCLKIndex = 0x19;
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+ VCLKIndex = 0x19;
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
+ VCLKIndex = 0x21;
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+ VCLKIndex = LCDXlatVCLK1[CRT2Index];
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
+ VCLKIndex = 0x45; /* TW: TODO: This is certainly wrong */
+ if(resinfo == 0x09) VCLKIndex++;
+ } else {
+ VCLKIndex = LCDXlatVCLK2[CRT2Index];
+ }
+ } else {
+ VCLKIndex = (UCHAR)SiS_GetReg2((USHORT)(SiS_Pr->SiS_P3ca+0x02)); /* Port 3cch */
+ VCLKIndex = ((VCLKIndex >> 2) & 0x03);
+ if(ModeNo > 0x13) {
+ VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+ }
+ if(ModeNo <= 0x13) { /* TW: Inserted from 315 BIOS */
+ if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
+ }
+ if(VCLKIndex == 0) VCLKIndex = 0x41;
+ if(VCLKIndex == 1) VCLKIndex = 0x43;
+ if(VCLKIndex == 4) VCLKIndex = 0x44;
+ }
+ }
+ } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* TV */
+ if((SiS_Pr->SiS_IF_DEF_HiVision == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV)) {
+ if(SiS_Pr->SiS_SetFlag & RPLLDIV2XO) VCLKIndex = HiTVVCLKDIV2;
+ else VCLKIndex = HiTVVCLK;
+ if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
+ if(modeflag & Charx8Dot) VCLKIndex = HiTVSimuVCLK;
+ else VCLKIndex = HiTVTextVCLK;
+ }
+ } else {
+ if(SiS_Pr->SiS_SetFlag & RPLLDIV2XO) VCLKIndex = TVVCLKDIV2;
+ else VCLKIndex = TVVCLK;
+ }
+ if(HwDeviceExtension->jChipType >= SIS_315H) {
+ VCLKIndex += 25;
+ }
+ } else { /* RAMDAC2 */
+ VCLKIndex = (UCHAR)SiS_GetReg2((USHORT)(SiS_Pr->SiS_P3ca+0x02));
+ VCLKIndex = ((VCLKIndex >> 2) & 0x03);
+ if(ModeNo > 0x13) {
+ VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+ VCLKIndex &= 0x3f;
+ if( (HwDeviceExtension->jChipType == SIS_630) &&
+ (HwDeviceExtension->jChipRevision >= 0x30)) {
+ if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
+ }
+ }
+ }
+ }
+
+ } else { /* If not programming CRT2 */
+
+ VCLKIndex = (UCHAR)SiS_GetReg2((USHORT)(SiS_Pr->SiS_P3ca+0x02));
+ VCLKIndex = ((VCLKIndex >> 2) & 0x03);
+ if(ModeNo > 0x13) {
+ VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+ VCLKIndex &= 0x3f;
+ if( (HwDeviceExtension->jChipType != SIS_630) &&
+ (HwDeviceExtension->jChipType != SIS_300) ) {
+ if(VCLKIndex == 0x1b) VCLKIndex = 0x35;
+ }
+ }
+ }
+ }
+
+ } else { /* LVDS */
+
+ VCLKIndex = CRT2Index;
+
+ if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) { /* programming CRT2 */
+
+ if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
+
+ VCLKIndex &= 0x1f;
+ tempbx = 0;
+ if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
+ if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+ tempbx += 2;
+ if(SiS_Pr->SiS_CHSOverScan) tempbx = 8;
+ if(SiS_Pr->SiS_CHPALM) {
+ tempbx = 4;
+ if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
+ } else if(SiS_Pr->SiS_CHPALN) {
+ tempbx = 6;
+ if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
+ }
+ }
+ switch(tempbx) {
+ case 0: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUNTSC; break;
+ case 1: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKONTSC; break;
+ case 2: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPAL; break;
+ case 3: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break;
+ case 4: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALM; break;
+ case 5: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALM; break;
+ case 6: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALN; break;
+ case 7: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALN; break;
+ case 8: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKSOPAL; break;
+ default: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break;
+ }
+ VCLKIndex = CHTVVCLKPtr[VCLKIndex];
+
+ } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+
+ VCLKIndex >>= 6;
+ if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) ||
+ (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel320x480))
+ VCLKIndex = LVDSXlat1VCLK[VCLKIndex];
+ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)
+ VCLKIndex = LVDSXlatVCLK2[VCLKIndex];
+ else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)
+ VCLKIndex = LVDSXlatVCLK2[VCLKIndex];
+ else VCLKIndex = LVDSXlatVCLK3[VCLKIndex];
+
+ } else {
+
+ VCLKIndex = (UCHAR)SiS_GetReg2((USHORT)(SiS_Pr->SiS_P3ca+0x02));
+ VCLKIndex = ((VCLKIndex >> 2) & 0x03);
+ if(ModeNo > 0x13) {
+ VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+ VCLKIndex &= 0x3F;
+ }
+ if( (HwDeviceExtension->jChipType == SIS_630) &&
+ (HwDeviceExtension->jChipRevision >= 0x30) ) {
+ if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
+ }
+ }
+ }
+
+ } else { /* if not programming CRT2 */
+
+ VCLKIndex = (UCHAR)SiS_GetReg2((USHORT)(SiS_Pr->SiS_P3ca+0x02));
+ VCLKIndex = ((VCLKIndex >> 2) & 0x03);
+ if(ModeNo > 0x13) {
+ VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+ VCLKIndex &= 0x3F;
+ if( (HwDeviceExtension->jChipType != SIS_630) &&
+ (HwDeviceExtension->jChipType != SIS_300) ) {
+ if(VCLKIndex == 0x1b) VCLKIndex = 0x35;
+ }
+#if 0
+ if(HwDeviceExtension->jChipType == SIS_730) {
+ if(VCLKIndex == 0x0b) VCLKIndex = 0x40; /* 1024x768-70 */
+ if(VCLKIndex == 0x0d) VCLKIndex = 0x41; /* 1024x768-75 */
+ }
+#endif
+ }
+ }
+
+ }
+
+ }
+#ifdef TWDEBUG
+ xf86DrvMsg(0, X_INFO, "VCLKIndex %d (0x%x)\n", VCLKIndex, VCLKIndex);
+#endif
+ return (VCLKIndex);
+}
+
+/* TW: Set 301 Palette address port registers */
+/* TW: Checked against 650/301LV BIOS */
+void
+SiS_SetGroup5(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr,
+ UCHAR *ROMAddr, USHORT ModeNo, USHORT ModeIdIndex)
+{
+
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
+
+ if(SiS_Pr->SiS_ModeType == ModeVGA){
+ if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))){
+ SiS_EnableCRT2(SiS_Pr);
+ SiS_LoadDAC(SiS_Pr,HwDeviceExtension,ROMAddr,ModeNo,ModeIdIndex);
+ }
+ }
+ return;
+}
+
+/* TW: Checked against 650/LVDS and 630/301B BIOS */
+void
+SiS_ModCRT1CRTC(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ USHORT temp,tempah,i,modeflag,j;
+ USHORT ResInfo,DisplayType;
+ const SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr=NULL;
+
+ if(ModeNo <= 0x13) {
+ modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+ } else {
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ }
+
+ temp = SiS_GetLVDSCRT1Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+ &ResInfo,&DisplayType);
+
+ if(temp == 0) return;
+
+ /* TW: Inserted from 630/LVDS BIOS */
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+ if(SiS_Pr->SiS_SetFlag & CRT2IsVGA) return;
+ }
+
+ switch(DisplayType) {
+ case 0 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1; break;
+ case 1 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1; break;
+ case 2 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1; break;
+ case 3 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1_H; break;
+ case 4 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1_H; break;
+ case 5 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1_H; break;
+ case 6 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2; break;
+ case 7 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2; break;
+ case 8 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2; break;
+ case 9 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2_H; break;
+ case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2_H; break;
+ case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2_H; break;
+ case 12: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1; break;
+ case 13: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H; break;
+ case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_1; break;
+ case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_1_H; break;
+ case 16: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_2; break;
+ case 17: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_2_H; break;
+ case 18: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC; break;
+ case 19: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC; break;
+ case 20: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL; break;
+ case 21: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL; break;
+ case 22: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x480_1; break; /* 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 99: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1SOPAL; break;
+ default: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1; break;
+ }
+
+ SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f); /*unlock cr0-7 */
+
+ tempah = (LVDSCRT1Ptr+ResInfo)->CR[0];
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x00,tempah);
+
+ for(i=0x02,j=1;i<=0x05;i++,j++){
+ tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
+ }
+ for(i=0x06,j=5;i<=0x07;i++,j++){
+ tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
+ }
+ for(i=0x10,j=7;i<=0x11;i++,j++){
+ tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
+ }
+ for(i=0x15,j=9;i<=0x16;i++,j++){
+ tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
+ }
+ for(i=0x0A,j=11;i<=0x0C;i++,j++){
+ tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,i,tempah);
+ }
+
+ tempah = (LVDSCRT1Ptr+ResInfo)->CR[14];
+ tempah &= 0xE0;
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah); /* TW: Modfied (650/LVDS); Was SetReg(tempah) */
+
+ tempah = (LVDSCRT1Ptr+ResInfo)->CR[14];
+ tempah &= 0x01;
+ tempah <<= 5;
+ if(modeflag & DoubleScanMode){
+ tempah |= 0x080;
+ }
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
+
+ /* TW: Inserted from 650/LVDS BIOS */
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ if(modeflag & HalfDCLK)
+ SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
+ }
+
+ return;
+}
+
+#if 0 /* TW: Unused */
+/*301b*/
+void
+SiS_CHACRT1CRTC(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex)
+{
+ USHORT temp,tempah,i,modeflag,j;
+ USHORT ResInfo,DisplayType;
+ SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr=NULL;
+
+ if(ModeNo<=0x13) {
+ modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
+ } else {
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
+ }
+
+ temp=SiS_GetLVDSCRT1Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+ &ResInfo,&DisplayType);
+ if(temp==0){
+ return;
+ }
+
+ switch(DisplayType) {
+ case 0 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1; break;
+ case 1 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1; break;
+ case 2 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1; break;
+ case 3 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1_H; break;
+ case 4 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1_H; break;
+ case 5 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1_H; break;
+ case 6 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2; break;
+ case 7 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2; break;
+ case 8 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2; break;
+ case 9 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2_H; break;
+ case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2_H; break;
+ case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2_H; break;
+ case 12: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1; break;
+ case 13: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H; break;
+ case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_1; break;
+ case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_1_H; break;
+ case 16: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_2; break;
+ case 17: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_2_H; break;
+ case 18: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC; break;
+ case 19: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC; break;
+ case 20: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL; break;
+ case 21: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL; break;
+ case 22: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x480_1; break; /* FSTN */
+ case 99: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL; break;
+ }
+
+ tempah=(UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3d4,0x11); /*unlock cr0-7 */
+ tempah=tempah&0x7F;
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x11,tempah);
+ tempah = (LVDSCRT1Ptr+ResInfo)->CR[0];
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x0,tempah);
+ for(i=0x02,j=1;i<=0x05;i++,j++){
+ tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
+ }
+ for(i=0x06,j=5;i<=0x07;i++,j++){
+ tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
+ }
+ for(i=0x10,j=7;i<=0x11;i++,j++){
+ tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
+ }
+ for(i=0x15,j=9;i<=0x16;i++,j++){
+ tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
+ }
+
+ for(i=0x0A,j=11;i<=0x0C;i++,j++){
+ tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,i,tempah);
+ }
+
+ tempah = (LVDSCRT1Ptr+ResInfo)->CR[14];
+ tempah=tempah&0x0E0;
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x0E,tempah);
+
+ tempah = (LVDSCRT1Ptr+ResInfo)->CR[14];
+ tempah=tempah&0x01;
+ tempah=tempah<<5;
+ if(modeflag&DoubleScanMode){
+ tempah=tempah|0x080;
+ }
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
+ return;
+}
+#endif
+
+/* TW: Checked against 650/LVDS BIOS: modified for new panel resolutions */
+BOOLEAN
+SiS_GetLVDSCRT1Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,USHORT *ResInfo,
+ USHORT *DisplayType)
+ {
+ USHORT tempbx,modeflag=0;
+ USHORT Flag,CRT2CRTC;
+
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+ /* TW: Inserted from 650/LVDS BIOS */
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+ if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return 0;
+ }
+ }
+
+ if(ModeNo <= 0x13) {
+ modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+ CRT2CRTC = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+ } else {
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ CRT2CRTC = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+ }
+
+ Flag = 1;
+ tempbx = 0;
+ if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
+ Flag = 0;
+ tempbx = 18;
+ if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx++;
+ if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+ tempbx += 2;
+ if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
+ if(SiS_Pr->SiS_CHPALM) {
+ tempbx = 18; /* PALM uses NTSC data */
+ if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx++;
+ } else if(SiS_Pr->SiS_CHPALN) {
+ tempbx = 20; /* PALN uses PAL data */
+ if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx++;
+ }
+ }
+ }
+ }
+ if(Flag) {
+ tempbx = SiS_Pr->SiS_LCDResInfo;
+ tempbx -= SiS_Pr->SiS_PanelMinLVDS;
+ if(SiS_Pr->SiS_LCDResInfo <= SiS_Pr->SiS_Panel1280x1024) {
+ if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) tempbx += 6;
+ if(modeflag & HalfDCLK) tempbx += 3;
+ } else {
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+ tempbx = 14;
+ if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) tempbx += 2;
+ if(modeflag & HalfDCLK) tempbx++;
+ } else if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
+ tempbx = 12;
+ if(modeflag & HalfDCLK) tempbx++;
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
+ tempbx = 23;
+ if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) tempbx += 2;
+ if(modeflag & HalfDCLK) tempbx++;
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
+ tempbx = 27;
+ if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) tempbx += 2;
+ if(modeflag & HalfDCLK) tempbx++;
+ } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
+ tempbx = 36;
+ if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) tempbx += 2;
+ if(modeflag & HalfDCLK) tempbx++;
+ }
+ }
+ }
+ if(SiS_Pr->SiS_IF_DEF_FSTN){
+ if(SiS_Pr->SiS_LCDResInfo==SiS_Pr->SiS_Panel320x480){
+ tempbx=22;
+ }
+ }
+ *ResInfo = CRT2CRTC & 0x3F;
+ *DisplayType = tempbx;
+ return 1;
+}
+
+/* TW: Checked against 650/LVDS (1.10a, 1.10.07), 630/301B (I/II) and 630/LVDS BIOS */
+void
+SiS_SetCRT2ECLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ USHORT tempah,tempal,pushax;
+ USHORT vclkindex=0;
+
+ if(HwDeviceExtension->jChipType < SIS_315H) {
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) return;
+ }
+ }
+
+ if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) || (SiS_Pr->SiS_IF_DEF_TRUMPION == 1)) {
+ SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
+ tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+ tempal &= 0x3F;
+ if(tempal == 2) RefreshRateTableIndex--;
+ vclkindex = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
+ RefreshRateTableIndex,HwDeviceExtension);
+ SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
+ } else {
+ vclkindex = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
+ RefreshRateTableIndex,HwDeviceExtension);
+ }
+
+ tempal = 0x02B;
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+ if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+ tempal += 3;
+ }
+ }
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86);
+ pushax = tempal;
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x20);
+ tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
+ tempal++;
+ tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x10);
+ tempal = pushax;
+ tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
+ tempal++;
+ tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x00);
+ tempal = pushax;
+ tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
+ tempal++;
+ tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
+ SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
+ return;
+}
+
+#if 0 /* TW: Not used */
+void
+SiS_SetDefCRT2ExtRegs(SiS_Private *SiS_Pr, USHORT BaseAddr)
+{
+ USHORT temp;
+
+ if(SiS_Pr->SiS_IF_DEF_LVDS==0) {
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x02,0x40);
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x10,0x80);
+ temp=(UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16);
+ temp &= 0xC3;
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x35,temp);
+ } else {
+ SiS_SetReg1(SiS_Pr->SiS_P3d4,0x32,0x02);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x02,0x00);
+ }
+}
+#endif
+
+/* TW: Start of Chrontel 70xx functions ---------------------- */
+
+/* Set-up the Chrontel Registers */
+void
+SiS_SetCHTVReg(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex)
+{
+ USHORT temp, tempbx, tempcl;
+ USHORT TVType, resindex;
+ const SiS_CHTVRegDataStruct *CHTVRegData = NULL;
+
+ if(ModeNo <= 0x13)
+ tempcl = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+ else
+ tempcl = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+
+ TVType = 0;
+ if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) TVType += 1;
+ if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+ TVType += 2;
+ if(SiS_Pr->SiS_CHSOverScan) TVType = 8;
+ if(SiS_Pr->SiS_CHPALM) {
+ TVType = 4;
+ if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) TVType += 1;
+ } else if(SiS_Pr->SiS_CHPALN) {
+ TVType = 6;
+ if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) 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;
+
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
+
+ /* Chrontel 7005 */
+
+ /* TW: We don't support modes >800x600 */
+ if (resindex > 5) return;
+
+ if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+ SiS_SetCH700x(SiS_Pr,0x4304); /* TW: 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
+ SiS_SetCH700x(SiS_Pr,0x6909); /* TW: Black level for PAL (105)*/
+ } else {
+ SiS_SetCH700x(SiS_Pr,0x0304); /* TW: upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
+ SiS_SetCH700x(SiS_Pr,0x7109); /* TW: Black level for NTSC (113)*/
+ }
+
+ temp = CHTVRegData[resindex].Reg[0];
+ tempbx=((temp&0x00FF)<<8)|0x00; /* TW: Mode register */
+ SiS_SetCH700x(SiS_Pr,tempbx);
+ temp = CHTVRegData[resindex].Reg[1];
+ tempbx=((temp&0x00FF)<<8)|0x07; /* TW: Start active video register */
+ SiS_SetCH700x(SiS_Pr,tempbx);
+ temp = CHTVRegData[resindex].Reg[2];
+ tempbx=((temp&0x00FF)<<8)|0x08; /* TW: Position overflow register */
+ SiS_SetCH700x(SiS_Pr,tempbx);
+ temp = CHTVRegData[resindex].Reg[3];
+ tempbx=((temp&0x00FF)<<8)|0x0A; /* TW: Horiz Position register */
+ SiS_SetCH700x(SiS_Pr,tempbx);
+ temp = CHTVRegData[resindex].Reg[4];
+ tempbx=((temp&0x00FF)<<8)|0x0B; /* TW: Vertical Position register */
+ SiS_SetCH700x(SiS_Pr,tempbx);
+
+ /* TW: Set minimum flicker filter for Luma channel (SR1-0=00),
+ minimum text enhancement (S3-2=10),
+ maximum flicker filter for Chroma channel (S5-4=10)
+ =00101000=0x28 (When reading, S1-0->S3-2, and S3-2->S1-0!)
+ */
+ SiS_SetCH700x(SiS_Pr,0x2801);
+
+ /* TW: Set video bandwidth
+ 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 */
+
+ /* TW: Register 0x3D does not exist in non-macrovision register map
+ (Maybe this is a macrovision register?)
+ */
+ /* SiS_SetCH70xx(SiS_Pr,0x003D); */
+
+ /* TW: Register 0x10 only contains 1 writable bit (S0) for sensing,
+ all other bits a read-only. Macrovision?
+ */
+ SiS_SetCH70xxANDOR(SiS_Pr,0x0010,0x1F);
+
+ /* TW: Register 0x11 only contains 3 writable bits (S0-S2) for
+ contrast enhancement (set to 010 -> gain 1 Yout = 17/16*(Yin-30) )
+ */
+ SiS_SetCH70xxANDOR(SiS_Pr,0x0211,0xF8);
+
+ /* TW: Clear DSEN
+ */
+ SiS_SetCH70xxANDOR(SiS_Pr,0x001C,0xEF);
+
+ if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) { /* ---- NTSC ---- */
+ if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) {
+ 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 */
+ SiS_SetCH70xxANDOR(SiS_Pr,0x0118,0xF0); /* (FSCI was 0x1f1c71c7 - this is for mode 22) */
+ SiS_SetCH70xxANDOR(SiS_Pr,0x0919,0xF0); /* FSCI for mode 24 is 428,554,851 */
+ SiS_SetCH70xxANDOR(SiS_Pr,0x081A,0xF0);
+ SiS_SetCH70xxANDOR(SiS_Pr,0x0b1B,0xF0);
+ SiS_SetCH70xxANDOR(SiS_Pr,0x031C,0xF0);
+ SiS_SetCH70xxANDOR(SiS_Pr,0x0a1D,0xF0);
+ SiS_SetCH70xxANDOR(SiS_Pr,0x061E,0xF0);
+ SiS_SetCH70xxANDOR(SiS_Pr,0x031F,0xF0);
+ SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off for mode 24 */
+ SiS_SetCH70xxANDOR(SiS_Pr,0x0021,0xFE); /* ACIV off, need to set FSCI */
+ }
+ }
+ }
+ } else { /* ---- PAL ---- */
+ /* TW: 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 */
+ } else {
+ SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off */
+ SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE); /* ACIV on */
+ }
+ }
+
+ } else {
+
+ /* Chrontel 7019 */
+
+ /* TW: We don't support modes >1024x768 */
+ if (resindex > 6) return;
+
+ temp = CHTVRegData[resindex].Reg[0];
+ 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];
+ 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);
+
+ }
+}
+
+/* TW: Chrontel 701x functions ================================= */
+
+void
+SiS_SetCH701xForLCD(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
+{
+ UCHAR regtable[] = { 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
+ 0x72, 0x73, 0x74, 0x76, 0x78, 0x7d };
+ UCHAR table1024[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
+ 0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02 };
+ UCHAR table1400[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xef,
+ 0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02 };
+ UCHAR *tableptr = NULL;
+ USHORT tempbh;
+ int i;
+
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+ tableptr = table1400;
+ } else {
+ tableptr = table1024;
+ }
+ tempbh = SiS_GetCH701x(SiS_Pr,0x74);
+ if((tempbh == 0xf6) || (tempbh == 0xc7)) {
+ tempbh = SiS_GetCH701x(SiS_Pr,0x73);
+ if(tempbh == 0xc8) {
+ if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1400x1050) return;
+ } else if(tempbh == 0xdb) {
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) return;
+ }
+ }
+ for(i=0; i<0x0c; i++) {
+ SiS_SetCH701x(SiS_Pr,(tableptr[i] << 8) | regtable[i]);
+ }
+ SiS_ChrontelPowerSequencing(SiS_Pr);
+ tempbh = SiS_GetCH701x(SiS_Pr,0x1e);
+ tempbh |= 0xc0;
+ SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x1e);
+}
+
+void
+SiS_ChrontelPowerSequencing(SiS_Private *SiS_Pr)
+{
+ UCHAR regtable[] = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
+ UCHAR table1024[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
+ UCHAR table1400[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
+ UCHAR *tableptr = NULL;
+ int i;
+
+ /* Set up Power up/down timing */
+
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+ tableptr = table1400;
+ } else {
+ tableptr = table1024;
+ }
+
+ for(i=0; i<5; i++) {
+ SiS_SetCH701x(SiS_Pr,(tableptr[i] << 8) | regtable[i]);
+ }
+}
+
+void
+SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr)
+{
+ USHORT temp;
+
+ /* TW: Enable Chrontel 7019 LCD panel backlight */
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+ temp = SiS_GetCH701x(SiS_Pr,0x66);
+ temp |= 0x20;
+ SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
+ }
+}
+
+void
+SiS_Chrontel701xOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
+{
+ USHORT temp;
+
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+ if(SiS_IsYPbPr(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+ temp = SiS_GetCH701x(SiS_Pr,0x01);
+ temp &= 0x3f;
+ temp |= 0x80; /* TW: Enable YPrPb (HDTV) */
+ SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x01);
+ }
+ if(SiS_IsChScart(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+ temp = SiS_GetCH701x(SiS_Pr,0x01);
+ temp &= 0x3f;
+ temp |= 0xc0; /* TW: Enable SCART + CVBS */
+ SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x01);
+ }
+ SiS_SetCH701x(SiS_Pr,0x2049); /* TW: Enable TV path */
+ temp = SiS_GetCH701x(SiS_Pr,0x49);
+ if(SiS_IsYPbPr(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+ temp = SiS_GetCH701x(SiS_Pr,0x73);
+ temp |= 0x60;
+ SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x73);
+ }
+ temp = SiS_GetCH701x(SiS_Pr,0x47);
+ temp &= 0x7f;
+ SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
+ SiS_LongDelay(SiS_Pr,2);
+ temp = SiS_GetCH701x(SiS_Pr,0x47);
+ temp |= 0x80;
+ SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
+ }
+}
+
+void
+SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr)
+{
+ USHORT temp;
+
+ /* TW: 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);
+ }
+}
+
+void
+SiS_Chrontel701xOff(SiS_Private *SiS_Pr)
+{
+ USHORT temp;
+
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+ SiS_LongDelay(SiS_Pr,2);
+ /* TW: Complete power down of LVDS */
+ temp = SiS_GetCH701x(SiS_Pr,0x76);
+ temp &= 0xfc;
+ SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
+ SiS_SetCH701x(SiS_Pr,0x0066);
+ }
+}
+
+void
+SiS_ChrontelResetDB(SiS_Private *SiS_Pr)
+{
+ /* TW: Reset Chrontel 7019 datapath */
+ SiS_SetCH701x(SiS_Pr,0x1048);
+ SiS_LongDelay(SiS_Pr,1);
+ SiS_SetCH701x(SiS_Pr,0x1848);
+}
+
+void
+SiS_ChrontelDoSomething4(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
+{
+ USHORT temp;
+
+ SiS_SetCH701x(SiS_Pr,0xaf76); /* Power up LVDS block */
+ temp = SiS_GetCH701x(SiS_Pr,0x49);
+ temp &= 1;
+ if(temp != 1) { /* TV block powered? (0 = yes, 1 = no) */
+ temp = SiS_GetCH701x(SiS_Pr,0x47);
+ temp &= 0x70;
+ SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47); /* enable VSYNC */
+ SiS_LongDelay(SiS_Pr,3);
+ temp = SiS_GetCH701x(SiS_Pr,0x47);
+ temp |= 0x80;
+ SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47); /* disable VSYNC */
+ }
+}
+
+void
+SiS_ChrontelDoSomething3(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+ USHORT BaseAddr)
+{
+ USHORT temp,temp1;
+
+ temp1 = 0;
+ temp = SiS_GetCH701x(SiS_Pr,0x61);
+ if(temp < 2) {
+ temp++;
+ SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61);
+ temp1 = 1;
+ }
+ SiS_SetCH701x(SiS_Pr,0xac76);
+ temp = SiS_GetCH701x(SiS_Pr,0x66);
+ temp |= 0x5f;
+ SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
+ if(ModeNo > 0x13) {
+ if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+ SiS_GenericDelay(SiS_Pr,0x3ff);
+ } else {
+ SiS_GenericDelay(SiS_Pr,0x2ff);
+ }
+ } else {
+ if(!temp1)
+ SiS_GenericDelay(SiS_Pr,0x2ff);
+ }
+ temp = SiS_GetCH701x(SiS_Pr,0x76);
+ temp |= 0x03;
+ SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
+ temp = SiS_GetCH701x(SiS_Pr,0x66);
+ temp &= 0x7f;
+ SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
+ SiS_LongDelay(SiS_Pr,1);
+}
+
+void
+SiS_ChrontelDoSomething2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
+{
+ USHORT temp,tempcl,tempch;
+
+ SiS_LongDelay(SiS_Pr, 1);
+ tempcl = 3;
+ tempch = 0;
+
+ do {
+ temp = SiS_GetCH701x(SiS_Pr,0x66);
+ temp &= 0x04;
+ if(temp == 0x04) break;
+
+ SiS_SetCH701xForLCD(SiS_Pr,HwDeviceExtension,BaseAddr);
+
+ if(tempcl == 0) {
+ if(tempch == 3) break;
+ SiS_ChrontelResetDB(SiS_Pr);
+ tempcl = 3;
+ tempch++;
+ }
+ tempcl--;
+ temp = SiS_GetCH701x(SiS_Pr,0x76);
+ temp &= 0xfb;
+ SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
+ SiS_LongDelay(SiS_Pr,2);
+ temp = SiS_GetCH701x(SiS_Pr,0x76);
+ temp |= 0x04;
+ SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
+ SiS_SetCH701x(SiS_Pr,0x6078);
+ SiS_LongDelay(SiS_Pr,2);
+ } while(0);
+
+ SiS_SetCH701x(SiS_Pr,0x0077);
+}
+
+void
+SiS_ChrontelDoSomething1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+ USHORT BaseAddr)
+{
+ USHORT 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_ChrontelResetDB(SiS_Pr);
+
+ SiS_ChrontelDoSomething2(SiS_Pr,HwDeviceExtension,BaseAddr);
+
+ temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x34);
+ SiS_ChrontelDoSomething3(SiS_Pr,temp,HwDeviceExtension,BaseAddr);
+
+ SiS_SetCH701x(SiS_Pr,0xaf76);
+}
+
+/* TW: End of Chrontel 701x functions ==================================== */
+
+/* TW: Generic Read/write routines for Chrontel ========================== */
+
+/* TW: The Chrontel is connected to the 630/730 via
+ * the 630/730's DDC/I2C port.
+ *
+ * On 630(S)T chipset, the index changed from 0x11 to 0x0a,
+ * possibly for working around the DDC problems
+ */
+
+void
+SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
+{
+ if (SiS_Pr->SiS_IF_DEF_CH70xx == 1)
+ SiS_SetCH700x(SiS_Pr,tempbx);
+ else
+ SiS_SetCH701x(SiS_Pr,tempbx);
+}
+
+/* TW: Write to Chrontel 700x */
+/* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
+void
+SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempbx)
+{
+ USHORT tempah,temp,i;
+
+ if(!(SiS_Pr->SiS_ChrontelInit)) {
+ SiS_Pr->SiS_DDC_Index = 0x11; /* TW: Bit 0 = SC; Bit 1 = SD */
+ SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
+ SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
+ SiS_Pr->SiS_DDC_DataShift = 0x00;
+ SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* TW: DAB (Device Address Byte) */
+ }
+
+ for(i=0;i<10;i++) { /* TW: Do only 10 attempts to write */
+ /* SiS_SetSwitchDDC2(SiS_Pr); */
+ if(SiS_SetStart(SiS_Pr)) continue; /* TW: Set start condition */
+ tempah = SiS_Pr->SiS_DDC_DeviceAddr;
+ temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* TW: Write DAB (S0=0=write) */
+ if(temp) continue; /* TW: (ERROR: no ack) */
+ tempah = tempbx & 0x00FF; /* TW: Write RAB */
+ tempah |= 0x80; /* TW: (set bit 7, see datasheet) */
+ temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
+ if(temp) continue; /* TW: (ERROR: no ack) */
+ tempah = (tempbx & 0xFF00) >> 8;
+ temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* TW: Write data */
+ if(temp) continue; /* TW: (ERROR: no ack) */
+ if(SiS_SetStop(SiS_Pr)) continue; /* TW: Set stop condition */
+ SiS_Pr->SiS_ChrontelInit = 1;
+ return;
+ }
+
+ /* TW: For 630ST */
+ if(!(SiS_Pr->SiS_ChrontelInit)) {
+ SiS_Pr->SiS_DDC_Index = 0x0a; /* TW: Bit 7 = SC; Bit 6 = SD */
+ SiS_Pr->SiS_DDC_Data = 0x80; /* Bitmask in IndexReg for Data */
+ SiS_Pr->SiS_DDC_Clk = 0x40; /* Bitmask in IndexReg for Clk */
+ SiS_Pr->SiS_DDC_DataShift = 0x00;
+ SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* TW: DAB (Device Address Byte) */
+
+ for(i=0;i<10;i++) { /* TW: Do only 10 attempts to write */
+ /* SiS_SetSwitchDDC2(SiS_Pr); */
+ if (SiS_SetStart(SiS_Pr)) continue; /* TW: Set start condition */
+ tempah = SiS_Pr->SiS_DDC_DeviceAddr;
+ temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* TW: Write DAB (S0=0=write) */
+ if(temp) continue; /* TW: (ERROR: no ack) */
+ tempah = tempbx & 0x00FF; /* TW: Write RAB */
+ tempah |= 0x80; /* TW: (set bit 7, see datasheet) */
+ temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
+ if(temp) continue; /* TW: (ERROR: no ack) */
+ tempah = (tempbx & 0xFF00) >> 8;
+ temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* TW: Write data */
+ if(temp) continue; /* TW: (ERROR: no ack) */
+ if(SiS_SetStop(SiS_Pr)) continue; /* TW: Set stop condition */
+ SiS_Pr->SiS_ChrontelInit = 1;
+ return;
+ }
+ }
+}
+
+/* TW: Write to Chrontel 701x */
+/* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
+void
+SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempbx)
+{
+ USHORT tempah,temp,i;
+
+ SiS_Pr->SiS_DDC_Index = 0x11; /* TW: Bit 0 = SC; Bit 1 = SD */
+ SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */
+ SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */
+ SiS_Pr->SiS_DDC_DataShift = 0x00;
+ SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* TW: DAB (Device Address Byte) */
+
+ for(i=0;i<10;i++) { /* TW: Do only 10 attempts to write */
+ if (SiS_SetStart(SiS_Pr)) continue; /* TW: Set start condition */
+ tempah = SiS_Pr->SiS_DDC_DeviceAddr;
+ temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* TW: Write DAB (S0=0=write) */
+ if(temp) continue; /* TW: (ERROR: no ack) */
+ tempah = tempbx & 0x00FF;
+ temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* TW: Write RAB */
+ if(temp) continue; /* TW: (ERROR: no ack) */
+ tempah = (tempbx & 0xFF00) >> 8;
+ temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* TW: Write data */
+ if(temp) continue; /* TW: (ERROR: no ack) */
+ if(SiS_SetStop(SiS_Pr)) continue; /* TW: Set stop condition */
+ return;
+ }
+}
+
+/* TW: Read from Chrontel 70xx */
+/* Parameter is [Register no (S7-S0)] */
+USHORT
+SiS_GetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
+{
+ if (SiS_Pr->SiS_IF_DEF_CH70xx == 1)
+ return(SiS_GetCH700x(SiS_Pr,tempbx));
+ else
+ return(SiS_GetCH701x(SiS_Pr,tempbx));
+}
+
+/* TW: Read from Chrontel 700x */
+/* Parameter is [Register no (S7-S0)] */
+USHORT
+SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempbx)
+{
+ USHORT tempah,temp,i;
+
+ if(!(SiS_Pr->SiS_ChrontelInit)) {
+ SiS_Pr->SiS_DDC_Index = 0x11; /* TW: Bit 0 = SC; Bit 1 = SD */
+ SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
+ SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
+ SiS_Pr->SiS_DDC_DataShift = 0x00;
+ SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* TW: DAB */
+ }
+
+ SiS_Pr->SiS_DDC_ReadAddr = tempbx;
+
+ for(i=0;i<20;i++) { /* TW: Do only 20 attempts to read */
+ /* SiS_SetSwitchDDC2(SiS_Pr); */
+ if(SiS_SetStart(SiS_Pr)) continue; /* TW: Set start condition */
+ tempah = SiS_Pr->SiS_DDC_DeviceAddr;
+ temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* TW: Write DAB (S0=0=write) */
+ if(temp) continue; /* TW: (ERROR: no ack) */
+ tempah = SiS_Pr->SiS_DDC_ReadAddr | 0x80; /* TW: Write RAB | 0x80 */
+ temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
+ if(temp) continue; /* TW: (ERROR: no ack) */
+ if (SiS_SetStart(SiS_Pr)) continue; /* TW: Re-start */
+ tempah = SiS_Pr->SiS_DDC_DeviceAddr | 0x01; /* DAB | 0x01 = Read */
+ temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* TW: DAB (S0=1=read) */
+ if(temp) continue; /* TW: (ERROR: no ack) */
+ tempah = SiS_ReadDDC2Data(SiS_Pr,tempah); /* TW: Read byte */
+ if (SiS_SetStop(SiS_Pr)) continue; /* TW: Stop condition */
+ SiS_Pr->SiS_ChrontelInit = 1;
+ return(tempah);
+ }
+
+ /* TW: For 630ST */
+ if(!SiS_Pr->SiS_ChrontelInit) {
+ SiS_Pr->SiS_DDC_Index = 0x0a; /* TW: Bit 0 = SC; Bit 1 = SD */
+ SiS_Pr->SiS_DDC_Data = 0x80; /* Bitmask in IndexReg for Data */
+ SiS_Pr->SiS_DDC_Clk = 0x40; /* Bitmask in IndexReg for Clk */
+ SiS_Pr->SiS_DDC_DataShift = 0x00;
+ SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* TW: DAB (Device Address Byte) */
+
+ for(i=0;i<20;i++) { /* TW: Do only 20 attempts to read */
+ /* SiS_SetSwitchDDC2(SiS_Pr); */
+ if(SiS_SetStart(SiS_Pr)) continue; /* TW: Set start condition */
+ tempah = SiS_Pr->SiS_DDC_DeviceAddr;
+ temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* TW: Write DAB (S0=0=write) */
+ if(temp) continue; /* TW: (ERROR: no ack) */
+ tempah = SiS_Pr->SiS_DDC_ReadAddr | 0x80; /* TW: Write RAB | 0x80 */
+ temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
+ if(temp) continue; /* TW: (ERROR: no ack) */
+ if (SiS_SetStart(SiS_Pr)) continue; /* TW: Re-start */
+ tempah = SiS_Pr->SiS_DDC_DeviceAddr | 0x01; /* DAB | 0x01 = Read */
+ temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* TW: DAB (S0=1=read) */
+ if(temp) continue; /* TW: (ERROR: no ack) */
+ tempah = SiS_ReadDDC2Data(SiS_Pr,tempah); /* TW: Read byte */
+ if (SiS_SetStop(SiS_Pr)) continue; /* TW: Stop condition */
+ SiS_Pr->SiS_ChrontelInit = 1;
+ return(tempah);
+ }
+ }
+ return(0xFFFF);
+}
+
+/* TW: Read from Chrontel 701x */
+/* Parameter is [Register no (S7-S0)] */
+USHORT
+SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempbx)
+{
+ USHORT tempah,temp,i;
+
+ SiS_Pr->SiS_DDC_Index = 0x11; /* TW: Bit 0 = SC; Bit 1 = SD */
+ SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */
+ SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */
+ SiS_Pr->SiS_DDC_DataShift = 0x00;
+ SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* TW: DAB */
+ SiS_Pr->SiS_DDC_ReadAddr = tempbx;
+
+ for(i=0;i<20;i++) { /* TW: Do only 20 attempts to read */
+ if(SiS_SetStart(SiS_Pr)) continue; /* TW: Set start condition */
+ tempah = SiS_Pr->SiS_DDC_DeviceAddr;
+ temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* TW: Write DAB (S0=0=write) */
+ if(temp) continue; /* TW: (ERROR: no ack) */
+ tempah = SiS_Pr->SiS_DDC_ReadAddr; /* TW: Write RAB */
+ temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
+ if(temp) continue; /* TW: (ERROR: no ack) */
+ if (SiS_SetStart(SiS_Pr)) continue; /* TW: Re-start */
+ tempah = SiS_Pr->SiS_DDC_DeviceAddr | 0x01; /* DAB | 0x01 = Read */
+ temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* TW: DAB (S0=1=read) */
+ if(temp) continue; /* TW: (ERROR: no ack) */
+ tempah = SiS_ReadDDC2Data(SiS_Pr,tempah); /* TW: Read byte */
+ SiS_SetStop(SiS_Pr); /* TW: Stop condition */
+ return(tempah);
+ }
+ return 0xFFFF;
+}
+
+#ifdef LINUX_XF86
+/* TW: Our own DDC functions */
+USHORT
+SiS_InitDDCRegs(SiS_Private *SiS_Pr, SISPtr pSiS, USHORT adaptnum, USHORT DDCdatatype)
+{
+ unsigned char ddcdtype[] = { 0xa0, 0xa0, 0xa0, 0xa2, 0xa6};
+ unsigned char flag, cr32;
+ USHORT temp = 0, myadaptnum = adaptnum;
+
+ SiS_Pr->SiS_ChrontelInit = 0; /* force re-detection! */
+
+ SiS_Pr->SiS_DDC_SecAddr = 0;
+ SiS_Pr->SiS_DDC_DeviceAddr = ddcdtype[DDCdatatype];
+ SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_P3c4;
+ SiS_Pr->SiS_DDC_Index = 0x11;
+ flag = 0xff;
+
+ cr32 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x32);
+
+ if(pSiS->VGAEngine == SIS_300_VGA) { /* 300 series */
+
+ if(pSiS->VBFlags & VB_SISBRIDGE) {
+ if(myadaptnum == 0) {
+ if(!(cr32 & 0x20)) {
+ myadaptnum = 2;
+ if(!(cr32 & 0x10)) {
+ myadaptnum = 1;
+ if(!(cr32 & 0x08)) {
+ myadaptnum = 0;
+ }
+ }
+ }
+ }
+ }
+
+ if(myadaptnum != 0) {
+ flag = 0;
+ if(pSiS->VBFlags & VB_SISBRIDGE) {
+ SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
+ SiS_Pr->SiS_DDC_Index = 0x0f;
+ }
+ }
+
+ if(cr32 & 0x80) {
+ if(myadaptnum >= 1) {
+ if(!(cr32 & 0x08)) {
+ myadaptnum = 1;
+ if(!(cr32 & 0x10)) return 0xFFFF;
+ }
+ }
+ }
+
+ temp = 4 - (myadaptnum * 2);
+ if(flag) temp = 0;
+
+ SiS_Pr->SiS_DDC_Data = 0x02 << temp;
+ SiS_Pr->SiS_DDC_Clk = 0x01 << temp;
+
+ } else { /* 310/325 series */
+
+ if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) myadaptnum = 0;
+
+ if(pSiS->VBFlags & VB_SISBRIDGE) {
+ if(myadaptnum == 0) {
+ if(!(cr32 & 0x20)) {
+ myadaptnum = 2;
+ if(!(cr32 & 0x10)) {
+ myadaptnum = 1;
+ if(!(cr32 & 0x08)) {
+ myadaptnum = 0;
+ }
+ }
+ }
+ }
+ if(myadaptnum == 2) {
+ myadaptnum = 1;
+ }
+ }
+
+ if(myadaptnum == 1) {
+ flag = 0;
+ if(pSiS->VBFlags & VB_SISBRIDGE) {
+ SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
+ SiS_Pr->SiS_DDC_Index = 0x0f;
+ }
+ }
+
+ if(cr32 & 0x80) {
+ if(myadaptnum >= 1) {
+ if(!(cr32 & 0x08)) {
+ myadaptnum = 1;
+ if(!(cr32 & 0x10)) return 0xFFFF;
+ }
+ }
+ }
+
+ temp = myadaptnum;
+ if(myadaptnum == 1) {
+ temp = 0;
+ if(pSiS->VBFlags & VB_LVDS) flag = 0xff;
+ }
+
+ if(flag) temp = 0;
+
+ SiS_Pr->SiS_DDC_Data = 0x02 << temp;
+ SiS_Pr->SiS_DDC_Clk = 0x01 << temp;
+
+ }
+ return 0;
+}
+
+USHORT
+SiS_WriteDABDDC(SiS_Private *SiS_Pr)
+{
+ SiS_SetStart(SiS_Pr);
+ if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr)) return 0xFFFF;
+ if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_SecAddr)) return 0xFFFF;
+ return(0);
+}
+
+USHORT
+SiS_PrepareReadDDC(SiS_Private *SiS_Pr)
+{
+ SiS_SetStart(SiS_Pr);
+ if(SiS_WriteDDC2Data(SiS_Pr, (SiS_Pr->SiS_DDC_DeviceAddr | 0x01))) return 0xFFFF;
+ return(0);
+}
+
+USHORT
+SiS_PrepareDDC(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);
+}
+
+void
+SiS_SendACK(SiS_Private *SiS_Pr, USHORT yesno)
+{
+ SiS_SetSCLKLow(SiS_Pr);
+ if(yesno) {
+ SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, SiS_Pr->SiS_DDC_Index,
+ ~SiS_Pr->SiS_DDC_Data, SiS_Pr->SiS_DDC_Data);
+ } else {
+ SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, SiS_Pr->SiS_DDC_Index,
+ ~SiS_Pr->SiS_DDC_Data, 0);
+ }
+ SiS_SetSCLKHigh(SiS_Pr);
+}
+
+USHORT
+SiS_DoProbeDDC(SiS_Private *SiS_Pr)
+{
+ unsigned char mask, value;
+ USHORT temp, ret;
+
+ SiS_SetSwitchDDC2(SiS_Pr);
+ if(SiS_PrepareDDC(SiS_Pr)) {
+ SiS_SetStop(SiS_Pr);
+ return(0xFFFF);
+ }
+ mask = 0xf0;
+ value = 0x20;
+ if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
+ temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
+ SiS_SendACK(SiS_Pr, 0);
+ if(temp == 0) {
+ mask = 0xff;
+ value = 0xff;
+ }
+ }
+ temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
+ SiS_SendACK(SiS_Pr, 1);
+ temp &= mask;
+ if(temp == value) ret = 0;
+ else {
+ ret = 0xFFFF;
+ if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
+ if(value == 0x30) ret = 0;
+ }
+ }
+ SiS_SetStop(SiS_Pr);
+ return(ret);
+}
+
+USHORT
+SiS_ProbeDDC(SiS_Private *SiS_Pr)
+{
+ USHORT flag;
+
+ flag = 0x180;
+ SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
+ if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x02;
+ SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;
+ if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x08;
+ SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;
+ if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x10;
+ if(!(flag & 0x1a)) flag = 0;
+ return(flag);
+}
+
+USHORT
+SiS_ReadDDC(SiS_Private *SiS_Pr, SISPtr pSiS, USHORT DDCdatatype, unsigned char *buffer)
+{
+ USHORT flag, length, i;
+ unsigned char chksum,gotcha;
+
+ if(DDCdatatype > 3) return 0xFFFF; /* incomplete! */
+
+ flag = 0;
+ SiS_SetSwitchDDC2(SiS_Pr);
+ if(!(SiS_PrepareDDC(SiS_Pr))) {
+ length = 127;
+ if(DDCdatatype != 1) length = 255;
+ chksum = 0;
+ gotcha = 0;
+ for(i=0; i<length; i++) {
+ buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
+ chksum += buffer[i];
+ gotcha |= buffer[i];
+ SiS_SendACK(SiS_Pr, 0);
+ }
+ buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
+ chksum += buffer[i];
+ SiS_SendACK(SiS_Pr, 1);
+ if(gotcha) flag = (USHORT)chksum;
+ else flag = 0xFFFF;
+ } else {
+ flag = 0xFFFF;
+ }
+ SiS_SetStop(SiS_Pr);
+ return(flag);
+}
+
+USHORT
+SiS_ReadLCDDDC(SiS_Private *SiS_Pr, USHORT length, unsigned char *buffer)
+{
+ USHORT i=0, flag=0;
+
+ length--;
+
+ SiS_SetSwitchDDC2(SiS_Pr);
+ if(!(SiS_PrepareDDC(SiS_Pr))) {
+ for(i=0; i<length; i++) {
+ buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
+ SiS_SendACK(SiS_Pr, 0);
+ }
+ buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
+ SiS_SendACK(SiS_Pr, 1);
+ } else flag = 0xFFFF;
+
+ SiS_SetStop(SiS_Pr);
+ return(0);
+}
+
+/* TW: Our private DDC function
+
+ It complies somewhat with the corresponding VESA function
+ in arguments and return values.
+
+ Since this is probably called before the mode is changed,
+ we use our pre-detected pSiS-values instead of SiS_Pr as
+ regards chipset and video bridge type.
+
+ Arguments:
+ adaptnum: 0=CRT1, 1=CRT2
+ CRT2 DDC is not supported in some cases.
+ DDCdatatype: 0=Probe, 1=EDID, 2=VDIF(not supported), 3=?, 4=?(not supported)
+ buffer: ptr to 256 data bytes which will be filled with read data.
+
+ Returns 0xFFFF if error, otherwise
+ if DDCdatatype > 0: Returns 0 if reading OK (included a correct checksum)
+ if DDCdatatype = 0: Returns supported DDC modes
+
+ */
+USHORT
+SiS_HandleDDC(SiS_Private *SiS_Pr, SISPtr pSiS, USHORT adaptnum,
+ USHORT DDCdatatype, unsigned char *buffer)
+{
+ if(DDCdatatype == 2) return 0xFFFF;
+ if(adaptnum > 2) return 0xFFFF;
+ if(pSiS->VGAEngine == SIS_300_VGA) {
+ if((adaptnum != 0) && (DDCdatatype != 0)) return 0xFFFF;
+ }
+ if((!(pSiS->VBFlags & VB_VIDEOBRIDGE)) && (adaptnum > 0)) return 0xFFFF;
+ if(SiS_InitDDCRegs(SiS_Pr, pSiS, adaptnum, DDCdatatype) == 0xFFFF) return 0xFFFF;
+ if(DDCdatatype == 0) {
+ return(SiS_ProbeDDC(SiS_Pr));
+ } else {
+ if(DDCdatatype > 4) return 0xFFFF;
+ return(SiS_ReadDDC(SiS_Pr, pSiS, DDCdatatype, buffer));
+ }
+}
+
+#if 0 /* for future use */
+
+USHORT
+SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS, unsigned char *buffer)
+{
+ USHORT flag, temp;
+ unsigned char buffer[8];
+ unsigned char cr36=0, cr37=0;
+ unsigned chat tempal, tempah, tempbl, tempbh;
+ USHORT tempax, tempbx tempcx, push1, push2, push3;
+ unsigned char addresstable[] = { 0x00, 0x22, 0x30, 0x40 };
+
+ if(SiS_InitDDCRegs(SiS_Pr, pSiS, 1, 0) == 0xFFFF) return 0xFFFF;
+ flag = SiS_ProbeDDC(SiS_Pr);
+
+ if(flag & 0x02) {
+ SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
+ SiS_Pr->SiS_DDC_SecAddr = 0x3a;
+ } else if(flag & 0x08) {
+ SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;
+ SiS_Pr->SiS_DDC_SecAddr = 0x76;
+ } else if(flag & 0x10) {
+ SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;
+ SiS_Pr->SiS_DDC_SecAddr = 0x76;
+ } else return 0xFFFF;
+
+ SiS_ReadLCDDDC(SiS_Pr, 4, buffer);
+ tempbl = buffer[0];
+ tempbh = buffer[1];
+ if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
+ tempah = 0x02;
+ tempbl &= 0xf0;
+ if(tempbl != 0x40) {
+ tempah = 0x03;
+ if(tempbl == 0x50) {
+ if(!tempbh) {
+ tempbh = buffer[3] & 0xf0;
+ if(tempbh == 0x30) {
+ SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
+ SiS_Pr->SiS_DDC_SecAddr = 0x23;
+ SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
+ tempbl = buffer[0];
+ tempbh = buffer[1];
+ if(tempbl) cr37 |= 0x10;
+ tempah = 0x0a;
+ }
+ if(tempbh == 0x40) {
+ SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
+ SiS_Pr->SiS_DDC_SecAddr = 0x23;
+ SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
+ tempbl = buffer[0];
+ tempbh = buffer[1];
+ if(tempbl) cr37 |= 0x10;
+ tempah = 0x03;
+ }
+ tempbh = 0x00;
+ }
+ }
+ if(tempbh == 0x00) goto cr36ready;
+ tempah = 0x07;
+ if(tempbh == 0xc0) goto cr36ready;
+ }
+ SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
+ SiS_Pr->SiS_DDC_SecAddr = 0x18;
+ SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
+ tempbl = buffer[0];
+ tempbh = buffer[1];
+ if(tempbl & 0x02) goto cr36ready;
+ SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
+ SiS_Pr->SiS_DDC_SecAddr = 0x23;
+ SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
+ tempbl = buffer[0];
+ tempbh = buffer[1];
+ tempah = 0x03;
+ if(!tempbh & 0x01)) tempah = 0x02;
+ if(!tempbl) cr37 |= 0x10;
+
+ } else {
+
+ tempah = 0x02;
+ tempbx = tempbl | (tempbh << 8);
+ if(tempbx != 1024) tempah = 0x03;
+
+ }
+
+cr36ready:
+ cr36 = tempah;
+
+ if((SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
+
+ SiS_Pr->SiS_DDC_SecAddr = 0x47;
+ SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
+ tempah = buffer[0];
+ tempah &= 0x06;
+ tempah ^= 0x06;
+ tempah <<= 5;
+ tempah |= 0x20;
+ cr37 &= 0x1f;
+ cr37 |= tempah;
+ if((cr36 & 0x07) == 0x07) cr37 &= 0x0e;
+
+ } else {
+
+ push1 = tempah;
+ SiS_Pr->SiS_DDC_SecAddr = 0x45;
+ SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
+ tempah = 0x01;
+ if((buffer[0] != 0x20) && (buffer[0] != 0x34)) {
+ tempah = 0x00;
+ }
+ cr37 &= 0xfe;
+ cr37 |= tempah;
+
+ SiS_Pr->SiS_DDC_SecAddr = 0x7e;
+ SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
+ tempax = (USHORT)(buffer[0] | (buffer[1] << 8));
+ push2 = tempax;
+ tempax &= 0x0003;
+ tempax *= 0x1b;
+ push3 = tempax;
+ tempax = (USHORT)buffer[0];
+ tempax &= 0x001c;
+ tempax >>= 2;
+ tempax *= 8;
+ tempbx = push3;
+ tempbx += tempax;
+ if(buffer[0] & 0x20) {
+ SiS_Pr->SiS_DDC_SecAddr = 0x80;
+ SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
+ tempax = buffer[0] | (buffer[1] << 8);
+ tempax &= 0x1f;
+ if(buffer[0] & 0x70) tempax <<= 1;
+ tempax++;
+ tempbx += tempax;
+ }
+ tempcx = push2;
+ tempax = push1 << 8;
+ tempbx = (tempbx & 0xff00) | (((tempbx & 0x00ff) + 0x80) & 0x00ff);
+ if(tempcx & 0xf800) {
+ tempal = addresstable[((tempax & 0xff00) >> 8)];
+ tempcx &= 0xf8ff;
+ tempcx >>= 11;
+ for(i=0; i<tempcx; i++) {
+ SiS_Pr->SiS_DDC_SecAddr = (tempbx & 0x00ff);
+ SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
+ tempbx += 0x04;
+ if(buffer[0] == tempal) break;
+ }
+ tempah = buffer[1];
+ tempah &= 0x0c;
+ tempah ^= 0x0c;
+ tempah <<= 4;
+ tempah |= 0x20;
+ cr37 &= 0x1f;
+ cr37 |= tempah;
+ if((cr36 & 0x07) == 0x07) cr37 &= 0x0e;
+ }
+ }
+ xf86DrvMsg(0, X_INFO, "DDC: cr36 = 0x%02x, cr37 = 0x%02x\n", cr36, cr37);
+
+}
+
+#endif
+
+/* TW: Generic I2C functions (compliant to i2c library) */
+
+#if 0
+USHORT
+SiS_I2C_GetByte(SiS_Private *SiS_Pr)
+{
+ return(SiS_ReadDDC2Data(SiS_Pr,0));
+}
+
+Bool
+SiS_I2C_PutByte(SiS_Private *SiS_Pr, USHORT data)
+{
+ if(SiS_WriteDDC2Data(SiS_Pr,data)) return FALSE;
+ return TRUE;
+}
+
+Bool
+SiS_I2C_Address(SiS_Private *SiS_Pr, USHORT addr)
+{
+ if(SiS_SetStart(SiS_Pr)) return FALSE;
+ if(SiS_WriteDDC2Data(SiS_Pr,addr)) return FALSE;
+ return TRUE;
+}
+
+void
+SiS_I2C_Stop(SiS_Private *SiS_Pr)
+{
+ SiS_SetStop(SiS_Pr);
+}
+#endif
+
+#endif
+
+void
+SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, USHORT tempax,USHORT tempbh)
+{
+ USHORT tempal,tempah,tempbl;
+
+ tempal = tempax & 0x00FF;
+ tempah =(tempax >> 8) & 0x00FF;
+ tempbl = SiS_GetCH70xx(SiS_Pr,tempal);
+ tempbl = (((tempbl & tempbh) | tempah) << 8 | tempal);
+ SiS_SetCH70xx(SiS_Pr,tempbl);
+}
+
+/* TW: Generic I2C functions for Chrontel --------- */
+
+void
+SiS_SetSwitchDDC2(SiS_Private *SiS_Pr)
+{
+ SiS_SetSCLKHigh(SiS_Pr);
+ /* SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAY); */
+ SiS_WaitRetraceDDC(SiS_Pr);
+
+ SiS_SetSCLKLow(SiS_Pr);
+ /* SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAY); */
+ SiS_WaitRetraceDDC(SiS_Pr);
+}
+
+/* TW: Set I2C start condition */
+/* TW: This is done by a SD high-to-low transition while SC is high */
+USHORT
+SiS_SetStart(SiS_Private *SiS_Pr)
+{
+ if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* TW: (SC->low) */
+ SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
+ ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data); /* TW: SD->high */
+ if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* TW: SC->high */
+ SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
+ ~SiS_Pr->SiS_DDC_Data,0x00); /* TW: SD->low = start condition */
+ if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* TW: (SC->low) */
+ return 0;
+}
+
+/* TW: Set I2C stop condition */
+/* TW: This is done by a SD low-to-high transition while SC is high */
+USHORT
+SiS_SetStop(SiS_Private *SiS_Pr)
+{
+ if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* TW: (SC->low) */
+ SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
+ ~SiS_Pr->SiS_DDC_Data,0x00); /* TW: SD->low */
+ if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* TW: SC->high */
+ SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
+ ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data); /* TW: SD->high = stop condition */
+ if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* TW: (SC->high) */
+ return 0;
+}
+
+/* TW: Write 8 bits of data */
+USHORT
+SiS_WriteDDC2Data(SiS_Private *SiS_Pr, USHORT tempax)
+{
+ USHORT i,flag,temp;
+
+ flag=0x80;
+ for(i=0;i<8;i++) {
+ SiS_SetSCLKLow(SiS_Pr); /* TW: SC->low */
+ if(tempax & flag) {
+ SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
+ ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data); /* TW: Write bit (1) to SD */
+ } else {
+ SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
+ ~SiS_Pr->SiS_DDC_Data,0x00); /* TW: Write bit (0) to SD */
+ }
+ SiS_SetSCLKHigh(SiS_Pr); /* TW: SC->high */
+ flag >>= 1;
+ }
+ temp = SiS_CheckACK(SiS_Pr); /* TW: Check acknowledge */
+ return(temp);
+}
+
+USHORT
+SiS_ReadDDC2Data(SiS_Private *SiS_Pr, USHORT tempax)
+{
+ USHORT i,temp,getdata;
+
+ 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_Data,SiS_Pr->SiS_DDC_Data);
+ SiS_SetSCLKHigh(SiS_Pr);
+ temp = SiS_GetReg1(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
+ if(temp & SiS_Pr->SiS_DDC_Data) getdata |= 0x01;
+ }
+ return(getdata);
+}
+
+USHORT
+SiS_SetSCLKLow(SiS_Private *SiS_Pr)
+{
+ USHORT temp, watchdog=50000;
+
+ SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
+ ~SiS_Pr->SiS_DDC_Clk,0x00); /* SetSCLKLow() */
+ do {
+ temp = SiS_GetReg1(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
+ } while((temp & SiS_Pr->SiS_DDC_Clk) && --watchdog);
+ if (!watchdog) return 0xFFFF;
+ SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
+ return 0;
+}
+
+USHORT
+SiS_SetSCLKHigh(SiS_Private *SiS_Pr)
+{
+ USHORT temp,watchdog=50000;
+
+ SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
+ ~SiS_Pr->SiS_DDC_Clk,SiS_Pr->SiS_DDC_Clk); /* SetSCLKHigh() */
+ do {
+ temp = SiS_GetReg1(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
+ } while((!(temp & SiS_Pr->SiS_DDC_Clk)) && --watchdog);
+ if (!watchdog) return 0xFFFF;
+ SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
+ return 0;
+}
+
+void
+SiS_DDC2Delay(SiS_Private *SiS_Pr, USHORT delaytime)
+{
+ USHORT i;
+
+ for(i=0; i<delaytime; i++) {
+ SiS_GetReg1(SiS_Pr->SiS_P3c4,0x05);
+ }
+}
+
+/* TW: Check I2C acknowledge */
+/* Returns 0 if ack ok, non-0 if ack not ok */
+USHORT
+SiS_CheckACK(SiS_Private *SiS_Pr)
+{
+ USHORT tempah;
+
+ SiS_SetSCLKLow(SiS_Pr); /* TW: (SC->low) */
+ SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
+ ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data); /* TW: (SD->high) */
+ SiS_SetSCLKHigh(SiS_Pr); /* TW: SC->high = clock impulse for ack */
+ tempah = SiS_GetReg1(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);/* TW: Read SD */
+ SiS_SetSCLKLow(SiS_Pr); /* TW: SC->low = end of clock impulse */
+ if(tempah & SiS_Pr->SiS_DDC_Data) return(1); /* TW: Ack OK if bit = 0 */
+ else return(0);
+}
+
+/* TW: End of I2C functions ----------------------- */
+
+
+/* =============== SiS 310/325 O.E.M. ================= */
+
+#ifdef SIS315H
+
+static USHORT
+GetLCDPtrIndex(SiS_Private *SiS_Pr)
+{
+ USHORT index;
+
+ index = SiS_Pr->SiS_LCDResInfo & 0x0F;
+ index--;
+ index *= 3;
+ if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) index += 2;
+ else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
+
+ return index;
+}
+
+/*
+---------------------------------------------------------
+ GetTVPtrIndex()
+ return 0 : NTSC Enhanced/Standard
+ 1 : NTSC Standard TVSimuMode
+ 2 : PAL Enhanced/Standard
+ 3 : PAL Standard TVSimuMode
+ 4 : HiVision Enhanced/Standard
+ 5 : HiVision Standard TVSimuMode
+---------------------------------------------------------
+*/
+static USHORT
+GetTVPtrIndex(SiS_Private *SiS_Pr)
+{
+ USHORT index;
+
+ index = 0;
+ if(SiS_Pr->SiS_VBInfo & SetPALTV) index++;
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) index++; /* Hivision TV use PAL */
+
+ index <<= 1;
+
+ if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (SiS_Pr->SiS_SetFlag & TVSimuMode))
+ index++;
+
+ return index;
+}
+
+/* TW: Checked against 650/LVDS (1.10.07) and 650/301LVx (1.10.6s) BIOS (including data) */
+static void
+SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+ UCHAR *ROMAddr, USHORT ModeNo)
+{
+ USHORT delay,index,temp,romptr=0;
+
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
+ if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+ if(HwDeviceExtension->jChipType != SIS_330) {
+ romptr = ROMAddr[0x128] | (ROMAddr[0x129] << 8); /* 301, LVDS */
+ if(SiS_Pr->SiS_VBType & (VB_SIS301B | VB_SIS302B))
+ romptr = ROMAddr[0x12a] | (ROMAddr[0x12b] << 8);
+ } else {
+ romptr = ROMAddr[0x1a8] | (ROMAddr[0x1a9] << 8); /* 301, LVDS */
+ if(SiS_Pr->SiS_VBType & (VB_SIS301B | VB_SIS302B))
+ romptr = ROMAddr[0x1aa] | (ROMAddr[0x1ab] << 8);
+ }
+ }
+ if(romptr) delay = ROMAddr[romptr];
+ else {
+ delay = SiS310_CRT2DelayCompensation1;
+ if(SiS_Pr->SiS_VBType & (VB_SIS301B | VB_SIS302B))
+ delay = SiS310_CRT2DelayCompensation2;
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1)
+ delay = SiS310_CRT2DelayCompensation3;
+ }
+ } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ index = GetLCDPtrIndex(SiS_Pr);
+ delay = SiS310_LCDDelayCompensation1[index];
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
+ delay = SiS310_LCDDelayCompensation2[index];
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1)
+ delay = SiS310_LCDDelayCompensation3[index];
+ if((IS_SIS650740) && (SiS_Pr->SiS_IF_DEF_LVDS == 0)) {
+ if(SiS_IsM650or651(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+ delay = SiS310_LCDDelayCompensation4[index]; /* 652c */
+ if(SiS_Pr->SiS_VBType & VB_SIS30xNEW)
+ delay = SiS310_LCDDelayCompensation5[index]; /* 6541 */
+ } else {
+ delay = SiS310_LCDDelayCompensation6[index]; /* 6550 */
+ if(SiS_Pr->SiS_VBType & VB_SIS30xNEW)
+ delay = SiS310_LCDDelayCompensation7[index]; /* 655f */
+ }
+ }
+ } else {
+ index = GetTVPtrIndex(SiS_Pr);
+ if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+ if(HwDeviceExtension->jChipType != SIS_330) {
+ romptr = ROMAddr[0x114] | (ROMAddr[0x115] << 8);
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
+ romptr = ROMAddr[0x11a] | (ROMAddr[0x11b] << 8);
+ } else {
+ romptr = ROMAddr[0x194] | (ROMAddr[0x195] << 8);
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
+ romptr = ROMAddr[0x19a] | (ROMAddr[0x19b] << 8);
+ }
+ }
+ if(romptr) delay = ROMAddr[romptr + index];
+ else {
+ delay = SiS310_TVDelayCompensation1[index];
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
+ delay = SiS310_TVDelayCompensation2[index];
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1)
+ delay = SiS310_TVDelayCompensation3[index];
+ }
+ if((IS_SIS650740) && (SiS_Pr->SiS_IF_DEF_LVDS == 0)) {
+ romptr = 0;
+ if(SiS_IsM650or651(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+ if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+ romptr = ROMAddr[0x114] | (ROMAddr[0x115] << 8);
+ if(SiS_Pr->SiS_VBType & VB_SIS30xNEW)
+ romptr = ROMAddr[0x11a] | (ROMAddr[0x11b] << 8);
+ }
+ if(romptr) delay = ROMAddr[romptr + index];
+ else {
+ delay = SiS310_TVDelayCompensation4[index]; /* 656e @ 0x114 */
+ if(SiS_Pr->SiS_VBType & VB_SIS30xNEW)
+ delay = SiS310_TVDelayCompensation5[index]; /* 6574 @ 0x11a */
+ }
+ } else {
+ delay = SiS310_TVDelayCompensation6[index]; /* 657a */
+ if(SiS_Pr->SiS_VBType & VB_SIS30xNEW)
+ delay = SiS310_TVDelayCompensation7[index]; /* 6580 */
+ }
+ }
+ }
+
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
+ } else {
+ if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+ delay <<= 4;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,delay);
+ } else {
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
+ }
+ }
+ } else {
+ if((IS_SIS650740) && (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
+ temp = (SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0xf0) >> 4;
+ if(temp == 8) {
+ delay &= 0x0f;
+ delay |= 0xb0;
+ } else if(temp == 6) {
+ delay &= 0x0f;
+ delay |= 0xc0;
+ }
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2D,delay); /* index 2D D[3:0] */
+ } else {
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
+ }
+ }
+}
+
+/* TW: Checked against 650/301LVx 1.10.6s BIOS (including data) */
+static void
+SetAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+ UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+{
+ USHORT index,temp,romptr=0;
+
+ temp = GetTVPtrIndex(SiS_Pr);
+ temp >>= 1; /* 0: NTSC, 1: PAL, 2: HiTV */
+
+ if(ModeNo<=0x13)
+ index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex;
+ else
+ index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex;
+
+ if(ROMAddr && SiS_Pr->SiS_UseROM) {
+ romptr = ROMAddr[0x112] | (ROMAddr[0x113] << 8);
+ if(HwDeviceExtension->jChipType == SIS_330) {
+ romptr = ROMAddr[0x192] | (ROMAddr[0x193] << 8);
+ }
+ }
+
+ if(romptr) {
+ temp <<= 1;
+ temp = ROMAddr[romptr + temp + index];
+ } else {
+ temp = SiS310_TVAntiFlick1[temp][index];
+ }
+ temp <<= 4;
+
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8f,temp); /* index 0A D[6:4] */
+}
+
+/* TW: Checked against 650/301LVx 1.10.6s BIOS (including data) */
+static void
+SetEdgeEnhance(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+ UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+{
+ USHORT index,temp,romptr=0;
+
+ temp = GetTVPtrIndex(SiS_Pr);
+ temp >>= 1; /* 0: NTSC, 1: PAL, 2: HiTV */
+
+ if(ModeNo<=0x13)
+ index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;
+ else
+ index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;
+
+ if(ROMAddr && SiS_Pr->SiS_UseROM) {
+ romptr = ROMAddr[0x124] | (ROMAddr[0x125] << 8);
+ if(HwDeviceExtension->jChipType == SIS_330) {
+ romptr = ROMAddr[0x1a4] | (ROMAddr[0x1a5] << 8);
+ }
+ }
+
+ if(romptr) {
+ temp <<= 1;
+ temp = ROMAddr[romptr + temp + index];
+ } else {
+ temp = SiS310_TVEdge1[temp][index];
+ }
+ temp <<= 5;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x3A,0x1F,temp); /* index 0A D[7:5] */
+}
+
+/* TW: Checked against 650/301LVx 1.10.6s BIOS (incl data) */
+static void
+SetYFilter(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+ UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+{
+ USHORT index, temp, i, j;
+ UCHAR OutputSelect = *SiS_Pr->pSiS_OutputSelect;
+
+ temp = GetTVPtrIndex(SiS_Pr);
+ temp >>= 1; /* 0: NTSC, 1: PAL, 2: HiTV */
+
+ if (ModeNo<=0x13) {
+ index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
+ } else {
+ index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
+ }
+
+ if(SiS_Pr->SiS_VBInfo&SetCRT2ToHiVisionTV) temp = 1; /* Hivision TV uses PAL */
+
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ for(i=0x35, j=0; i<=0x38; i++, j++) {
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
+ }
+ for(i=0x48; i<=0x4A; i++, j++) {
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
+ }
+ } else {
+ for(i=0x35, j=0; i<=0x38; i++, j++){
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter1[temp][index][j]);
+ }
+ }
+
+ if(ROMAddr && SiS_Pr->SiS_UseROM) {
+ OutputSelect = ROMAddr[0xf3];
+ if(HwDeviceExtension->jChipType == SIS_330) {
+ OutputSelect = ROMAddr[0x11b];
+ }
+ }
+ if(OutputSelect & EnablePALMN) {
+ if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
+ temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
+ temp &= (EnablePALM | EnablePALN);
+ if(temp == EnablePALM) {
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ for(i=0x35, j=0; i<=0x38; i++, j++) {
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_PALMFilter2[index][j]);
+ }
+ for(i=0x48; i<=0x4A; i++, j++) {
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_PALMFilter2[index][j]);
+ }
+ } else {
+ for(i=0x35, j=0; i<=0x38; i++, j++) {
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_PALMFilter[index][j]);
+ }
+ }
+ }
+ if(temp == EnablePALN) {
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ for(i=0x35, j=0; i<=0x38; i++, j++) {
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_PALNFilter2[index][j]);
+ }
+ for(i=0x48, j=0; i<=0x4A; i++, j++) {
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_PALNFilter2[index][j]);
+ }
+ } else {
+ for(i=0x35, j=0; i<=0x38; i++, j++) {
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_PALNFilter[index][j]);
+ }
+ }
+ }
+ }
+ }
+}
+
+/* TW: Checked against 650/301LVx 1.10.6s BIOS (including data) */
+static void
+SetPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+ UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+{
+ USHORT index,temp,temp1,i,j,resinfo,romptr=0;
+
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
+
+ temp1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38); /* if PALM/N not set */
+ temp1 &= (EnablePALM | EnablePALN);
+ if(temp1) return;
+
+ if (ModeNo<=0x13) {
+ resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+ } else {
+ resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ }
+
+ temp = GetTVPtrIndex(SiS_Pr);
+ /* 0: NTSC Graphics, 1: NTSC Text, 2: PAL Graphics,
+ * 3: PAL Text, 4: HiTV Graphics 5: HiTV Text
+ */
+ if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+ romptr = ROMAddr[0x116] | (ROMAddr[0x117] << 8);
+ if(HwDeviceExtension->jChipType == SIS_330) {
+ romptr = ROMAddr[0x196] | (ROMAddr[0x197] << 8);
+ }
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ romptr = ROMAddr[0x11c] | (ROMAddr[0x11d] << 8);
+ if(HwDeviceExtension->jChipType == SIS_330) {
+ romptr = ROMAddr[0x19c] | (ROMAddr[0x19d] << 8);
+ }
+ if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (!(SiS_Pr->SiS_SetFlag & TVSimuMode))) {
+ romptr = ROMAddr[0x116] | (ROMAddr[0x117] << 8);
+ if(HwDeviceExtension->jChipType == SIS_330) {
+ romptr = ROMAddr[0x196] | (ROMAddr[0x197] << 8);
+ }
+ }
+ }
+ }
+ if(romptr) {
+ romptr += (temp << 2);
+ for(j=0, i=0x31; i<=0x34; i++, j++) {
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
+ }
+ } else {
+ index = temp % 2;
+ temp >>= 1; /* 0:NTSC, 1:PAL, 2:HiTV */
+ for(j=0, i=0x31; i<=0x34; i++, j++) {
+ if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV))
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
+ else if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || (SiS_Pr->SiS_SetFlag & TVSimuMode))
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr2[temp][index][j]);
+ else
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
+ }
+ }
+
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { /* TW: 650/301LV: (VB_SIS301LV | VB_SIS302LV)) */
+ if((!(SiS_Pr->SiS_VBInfo & SetPALTV)) && (ModeNo > 0x13)) {
+ if(resinfo == 6) {
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x31,0x21);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x32,0xf0);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x33,0xf5);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x34,0x7f);
+ } else if (resinfo == 7) {
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x31,0x21);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x32,0xf0);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x33,0xf5);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x34,0x7f);
+ } else if (resinfo == 8) {
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x31,0x1e);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x32,0x8b);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x33,0xfb);
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x34,0x7b);
+ }
+ }
+ }
+}
+
+void
+SiS_OEM310Setting(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+ UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+{
+ SetDelayComp(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo);
+ /* TW: The TV functions are not for LVDS */
+ if( (SiS_Pr->SiS_IF_DEF_LVDS == 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
+ SetAntiFlicker(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+ SetPhaseIncr(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+ SetYFilter(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+ if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
+ SetEdgeEnhance(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+ }
+ }
+}
+
+/* TW: New from 650/301LVx 1.10.6s, 1.10.7w - clashes with OEMLCD() */
+void
+SiS_FinalizeLCD(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+ USHORT ModeIdIndex, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ USHORT tempcl,tempch,tempbl,tempbh,tempbx,tempax,temp;
+ USHORT resinfo,modeflag;
+
+ if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) return;
+
+ if(ModeNo <= 0x13) {
+ resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+ modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+ } else {
+ resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ }
+
+ if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x2a,0x00);
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
+ SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
+ }
+ tempch = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36);
+ tempch &= 0xf0;
+ tempch >>= 4;
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1f,0x76);
+ }
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) { /* From 1.10.8w */
+ if(!(SiS_Pr->SiS_LCDInfo & LCDNonExpanding)) {
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x14,0x90);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x01);
+ if((ModeNo > 0x13) && (resinfo == 8)) {
+ tempbx = 806; /* 0x326 */
+ tempbx--;
+ temp = tempbx & 0xff;
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1b,temp);
+ temp = (tempbx >> 8) & 0x03;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1d,0xf8,temp);
+ }
+ } else {
+ if(ModeNo <= 0x13) {
+ if(ModeNo <= 1) {
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x70);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x19,0xff);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1b,0x48);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1d,0x12);
+ }
+ if(!(modeflag & HalfDCLK)) {
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x14,0x20);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x15,0x1a);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x16,0x28);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x17,0x00);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x4c);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x19,0xdc);
+ if(ModeNo == 0x12) {
+ switch(tempch) {
+ case 0:
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x95);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x19,0xdc);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1a,0x10);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1b,0x95);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1c,0x48);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1d,0x12);
+ break;
+ case 2:
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x95);
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1b,0x48);
+ break;
+ case 3:
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1b,0x95);
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ } else {
+ tempcl = tempbh = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x01);
+ tempcl &= 0x0f;
+ tempbh &= 0x70;
+ tempbh >>= 4;
+ tempbl = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x04);
+ tempbx = (tempbh << 8) | tempbl;
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+ if((resinfo == 8) || (!(SiS_Pr->SiS_LCDInfo & LCDNonExpanding))) {
+ if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
+ tempbx = 770;
+ } else {
+ if(tempbx > 770) tempbx = 770;
+ if(SiS_Pr->SiS_VGAVDE < 600) {
+ tempax = 768 - SiS_Pr->SiS_VGAVDE;
+ tempax >>= 4; /* From 1.10.7w; 1.10.6s: 3; */
+ if(SiS_Pr->SiS_VGAVDE <= 480) tempax >>= 4; /* From 1.10.7w; 1.10.6s: < 480; >>=1; */
+ tempbx -= tempax;
+ }
+ }
+ } else return;
+ }
+#if 0
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+ }
+#endif
+ temp = tempbx & 0xff;
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,temp);
+ temp = (tempbx & 0xff00) >> 8;
+ temp <<= 4;
+ temp |= tempcl;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,temp);
+ }
+ }
+}
+
+/* TW: New and checked from 650/301LV BIOS */
+/* This might clash with newer "FinalizeLCD()" function */
+void
+SiS_OEMLCD(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+ UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+{
+ USHORT tempbx,tempah,tempbl,tempbh,tempcl;
+
+ if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) return;
+
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+ SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension,BaseAddr);
+ tempbh = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x1a);
+ tempbh &= 0x38;
+ tempbh >>= 3;
+ tempbl = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x18);
+ tempbx = (tempbh << 8) | tempbl;
+ if(SiS_Pr->SiS_LCDTypeInfo == 1) tempbx -= 0x12;
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,tempbx & 0x00ff);
+ tempah = (tempbx & 0xff00) >> 8;
+ tempah &= 0x07;
+ tempah <<= 3;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0xc7,tempah);
+ tempah = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x19);
+ tempah &= 0x0f;
+ if(SiS_Pr->SiS_LCDTypeInfo == 1) tempah -= 2;
+ tempah &= 0x0f;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,tempah);
+ tempah = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x14);
+ if(SiS_Pr->SiS_LCDTypeInfo == 1) tempah++;
+ tempah -= 8;
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x14,tempah);
+ } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ tempcl = tempbh = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x01);
+ tempbh &= 0x70;
+ tempbh >>= 4;
+ tempbl = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x04);
+ tempbx = (tempbh << 8) | tempbl;
+ if(SiS_Pr->SiS_LCDTypeInfo == 1) {
+ tempbx -= 0x1e;
+ tempcl &= 0x0f;
+ tempcl -= 4;
+ tempcl &= 0x0f;
+ }
+ tempbl = tempbx & 0x00ff;
+ tempbh = (tempbx >> 8) & 0x00ff;
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,tempbl);
+ tempbh <<= 4;
+ tempbh |= tempcl;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,tempbh);
+ }
+}
+#endif
+
+
+/* ================= SiS 300 O.E.M. ================== */
+
+#ifdef SIS300
+
+#if 0 /* Not used */
+static USHORT
+GetRevisionID(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+ ULONG temp1;
+#ifndef LINUX_XF86
+ ULONG base;
+#endif
+ USHORT temp2 = 0;
+
+ if((HwDeviceExtension->jChipType==SIS_540)||
+ (HwDeviceExtension->jChipType==SIS_630)||
+ (HwDeviceExtension->jChipType==SIS_730)) {
+#ifndef LINUX_XF86
+ base = 0x80000008;
+ OutPortLong(base,0xcf8);
+ temp1 = InPortLong(0xcfc);
+#else
+ temp1=pciReadLong(0x00000000, 0x08);
+#endif
+ temp1 &= 0x000000FF;
+ temp2 = (USHORT)(temp1);
+ return temp2;
+ }
+ return 0;
+}
+#endif
+
+/* TW: Checked against 630/301B BIOS (incl data) */
+static USHORT
+GetOEMLCDPtr(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, UCHAR *ROMAddr, int Flag)
+{
+ USHORT tempbx=0,romptr=0;
+ UCHAR 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,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
+ };
+
+ if(HwDeviceExtension->jChipType == SIS_300) {
+
+ tempbx = SiS_Pr->SiS_LCDResInfo - 2;
+ if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 4;
+ if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+ if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) tempbx += 3;
+ }
+ if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+ if(ROMAddr[0x235] & 0x80) {
+ tempbx = SiS_Pr->SiS_LCDTypeInfo;
+ if(Flag) {
+ romptr = ROMAddr[0x255] | (ROMAddr[0x256] << 8);
+ if(romptr) {
+ tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
+ } else {
+ tempbx = customtable300[SiS_Pr->SiS_LCDTypeInfo];
+ }
+ if(tempbx == 0xFF) return 0xFFFF;
+ }
+ tempbx <<= 1;
+ if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
+ }
+ }
+
+ } else {
+
+ if(Flag) {
+ if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+ romptr = ROMAddr[0x255] | (ROMAddr[0x256] << 8);
+ if(romptr) {
+ tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
+ } else {
+ tempbx = 0xff;
+ }
+ } else {
+ tempbx = customtable630[SiS_Pr->SiS_LCDTypeInfo];
+ }
+ if(tempbx == 0xFF) return 0xFFFF;
+ tempbx <<= 2;
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
+ if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) tempbx++;
+ return tempbx;
+ }
+ tempbx = SiS_Pr->SiS_LCDTypeInfo << 2;
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
+ if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) tempbx++;
+ }
+ return tempbx;
+}
+
+/* TW: Checked against 630/301B and 630/LVDS BIOS (incl data) */
+static void
+SetOEMLCDDelay(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+ UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+{
+ USHORT index,temp,romptr=0;
+
+ if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+ if(!(ROMAddr[0x237] & 0x01)) return;
+ if(!(ROMAddr[0x237] & 0x02)) return;
+ romptr = ROMAddr[0x24b] | (ROMAddr[0x24c] << 8);
+ }
+
+ /* TW: The Panel Compensation Delay should be set according to tables
+ * here. Unfortunately, various BIOS versions don't case about
+ * a uniform way using eg. ROM byte 0x220, but use different
+ * hard coded delays (0x04, 0x20, 0x18) in SetGroup1().
+ * Thus we don't set this if the user select a custom pdc or if
+ * we otherwise detected a valid pdc.
+ */
+ if(HwDeviceExtension->pdc) return;
+
+ temp = GetOEMLCDPtr(SiS_Pr,HwDeviceExtension, ROMAddr, 0);
+
+ index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
+
+ if(HwDeviceExtension->jChipType != SIS_300) {
+ if(romptr) {
+ romptr += (temp * 2);
+ romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8);
+ romptr += index;
+ temp = ROMAddr[romptr];
+ } else {
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+ temp = SiS300_OEMLCDDelay2[temp][index];
+ } else {
+ temp = SiS300_OEMLCDDelay3[temp][index];
+ }
+ }
+ } else {
+ if((ROMAddr) && SiS_Pr->SiS_UseROM && (ROMAddr[0x235] & 0x80)) {
+ if(romptr) {
+ romptr += (temp * 2);
+ romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8);
+ romptr += index;
+ temp = ROMAddr[romptr];
+ } else {
+ temp = SiS300_OEMLCDDelay5[temp][index];
+ }
+ } else {
+ if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+ romptr = ROMAddr[0x249] | (ROMAddr[0x24a] << 8);
+ if(romptr) {
+ romptr += (temp * 2);
+ romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8);
+ romptr += index;
+ temp = ROMAddr[romptr];
+ } else {
+ temp = SiS300_OEMLCDDelay4[temp][index];
+ }
+ } else {
+ temp = SiS300_OEMLCDDelay4[temp][index];
+ }
+ }
+ }
+ temp &= 0x3c;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* index 0A D[6:4] */
+}
+
+static void
+SetOEMLCDData(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+ UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+{
+#if 0 /* TW: Unfinished; VData table missing */
+ USHORT index,temp;
+
+ if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+ if(!(ROMAddr[0x237] & 0x01)) return;
+ if(!(ROMAddr[0x237] & 0x04)) return;
+ /* No rom pointer in BIOS header! */
+ }
+
+ temp = GetOEMLCDPtr(SiS_Pr,HwDeviceExtension, ROMAddr, 1);
+ if(temp = 0xFFFF) return;
+
+ index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDHIndex;
+ for(i=0x14, j=0; i<=0x17; i++, j++) {
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,i,SiS300_LCDHData[temp][index][j]);
+ }
+ SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1a, 0xf8, (SiS300_LCDHData[temp][index][j] & 0x07));
+
+ index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDVIndex;
+ SiS_SetReg1(SiS_SiS_Part1Port,0x18, SiS300_LCDVData[temp][index][0]);
+ SiS_SetRegANDOR(SiS_SiS_Part1Port,0x19, 0xF0, SiS300_LCDVData[temp][index][1]);
+ SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1A, 0xC7, (SiS300_LCDVData[temp][index][2] & 0x38));
+ for(i=0x1b, j=3; i<=0x1d; i++, j++) {
+ SiS_SetReg1(SiS_Pr->SiS_Part1Port,i,SiS300_LCDVData[temp][index][j]);
+ }
+#endif
+}
+
+/* TW: Checked against 630/301B 2.04.50 and 630/LVDS BIOS */
+static USHORT
+GetOEMTVPtr(SiS_Private *SiS_Pr)
+{
+ USHORT index;
+
+ index = 0;
+ if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) index += 4;
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) index += 2;
+ else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) index += 3;
+ else if(SiS_Pr->SiS_VBInfo & SetPALTV) index += 1;
+ } else {
+ if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) index += 2;
+ if(SiS_Pr->SiS_VBInfo & SetPALTV) index += 1;
+ }
+ return index;
+}
+
+/* TW: Checked against 630/301B 2.04.50 and 630/LVDS BIOS (incl data) */
+static void
+SetOEMTVDelay(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+ UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+{
+ USHORT index,temp,romptr=0;
+
+ if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+ if(!(ROMAddr[0x238] & 0x01)) return;
+ if(!(ROMAddr[0x238] & 0x02)) return;
+ romptr = ROMAddr[0x241] | (ROMAddr[0x242] << 8);
+ }
+
+ temp = GetOEMTVPtr(SiS_Pr);
+
+ index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVDelayIndex;
+
+ if(romptr) {
+ romptr += (temp * 2);
+ romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8);
+ romptr += index;
+ temp = ROMAddr[romptr];
+ } else {
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+ temp = SiS300_OEMTVDelay301[temp][index];
+ } else {
+ temp = SiS300_OEMTVDelayLVDS[temp][index];
+ }
+ }
+ temp &= 0x3c;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* index 0A D[6:4] */
+}
+
+/* TW: Checked against 630/301B 2.04.50 BIOS (incl data) */
+static void
+SetOEMAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+ USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+ USHORT ModeIdIndex)
+{
+ USHORT index,temp,romptr=0;
+
+ if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+ if(!(ROMAddr[0x238] & 0x01)) return;
+ if(!(ROMAddr[0x238] & 0x04)) return;
+ romptr = ROMAddr[0x243] | (ROMAddr[0x244] << 8);
+ }
+
+ temp = GetOEMTVPtr(SiS_Pr);
+
+ index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVFlickerIndex;
+
+ if(romptr) {
+ romptr += (temp * 2);
+ romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8);
+ romptr += index;
+ temp = ROMAddr[romptr];
+ } else {
+ temp = SiS300_OEMTVFlicker[temp][index];
+ }
+ temp &= 0x70;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8F,temp); /* index 0A D[6:4] */
+}
+
+/* TW: Checked against 630/301B 2.04.50 BIOS (incl data) */
+static void
+SetOEMPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+ UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+{
+ USHORT index,i,j,temp,romptr=0;
+
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) return;
+
+ if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+ if(!(ROMAddr[0x238] & 0x01)) return;
+ if(!(ROMAddr[0x238] & 0x08)) return;
+ romptr = ROMAddr[0x245] | (ROMAddr[0x246] << 8);
+ }
+
+ temp = GetOEMTVPtr(SiS_Pr);
+
+ index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVPhaseIndex;
+
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ for(i=0x31, j=0; i<=0x34; i++, j++) {
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS300_Phase2[temp][index][j]);
+ }
+ } else {
+ if(romptr) {
+ romptr += (temp * 2);
+ romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8);
+ romptr += (index * 4);
+ for(i=0x31, j=0; i<=0x34; i++, j++) {
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
+ }
+ } else {
+ for(i=0x31, j=0; i<=0x34; i++, j++) {
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS300_Phase1[temp][index][j]);
+ }
+ }
+ }
+}
+
+/* TW: Checked against 630/301B 2.04.50 BIOS (incl data) */
+static void
+SetOEMYFilter(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+ UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+{
+ USHORT index,temp,temp1,i,j,romptr=0;
+
+ if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSCART | SetCRT2ToHiVisionTV)) return;
+
+ if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+ if(!(ROMAddr[0x238] & 0x01)) return;
+ if(!(ROMAddr[0x238] & 0x10)) return;
+ romptr = ROMAddr[0x247] | (ROMAddr[0x248] << 8);
+ }
+
+ temp = GetOEMTVPtr(SiS_Pr);
+
+ index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVYFilterIndex;
+
+ if(HwDeviceExtension->jChipType > SIS_300) {
+ if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
+ temp1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x35);
+ if(temp1 & (EnablePALM | EnablePALN)) {
+ temp = 8;
+ if(!(temp1 & EnablePALM)) temp = 9;
+ }
+ }
+ }
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ for(i=0x35, j=0; i<=0x38; i++, j++) {
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
+ }
+ for(i=0x48; i<=0x4A; i++, j++) {
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
+ }
+ } else {
+ if(romptr) {
+ romptr += (temp * 2);
+ romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8);
+ romptr += (index * 4);
+ for(i=0x35, j=0; i<=0x38; i++, j++) {
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
+ }
+ } else {
+ for(i=0x35, j=0; i<=0x38; i++, j++) {
+ SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS300_Filter1[temp][index][j]);
+ }
+ }
+ }
+}
+
+void
+SiS_OEM300Setting(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+ USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo)
+{
+ USHORT ModeIdIndex;
+
+ ModeIdIndex = SiS_SearchVBModeID(SiS_Pr,ROMAddr,&ModeNo);
+ if(!(ModeIdIndex)) return;
+
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ SetOEMLCDDelay(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+ SetOEMLCDData(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+ }
+ }
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ SetOEMTVDelay(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+ SetOEMAntiFlicker(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+ SetOEMPhaseIncr(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+ SetOEMYFilter(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+ }
+ }
+}
+#endif
+
+
diff --git a/src/init301.h b/src/init301.h
new file mode 100644
index 0000000..2cbb39d
--- /dev/null
+++ b/src/init301.h
@@ -0,0 +1,285 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/init301.h,v 1.9 2003/02/04 02:44:28 dawes Exp $ */
+#ifndef _INIT301_
+#define _INIT301_
+
+#include "osdef.h"
+#include "initdef.h"
+#include "vgatypes.h"
+#include "vstruct.h"
+
+#ifdef TC
+#include <stdio.h>
+#include <string.h>
+#include <conio.h>
+#include <dos.h>
+#include <stdlib.h>
+#endif
+
+#ifdef LINUX_XF86
+#include "xf86.h"
+#include "xf86Pci.h"
+#include "xf86PciInfo.h"
+#include "sis.h"
+#include "sis_regs.h"
+#endif
+
+#ifdef LINUX_KERNEL
+#include <asm/io.h>
+#include <linux/types.h>
+#include <linux/sisfb.h>
+#endif
+
+#ifdef WIN2000
+#include <stdio.h>
+#include <string.h>
+#include <miniport.h>
+#include "dderror.h"
+#include "devioctl.h"
+#include "miniport.h"
+#include "ntddvdeo.h"
+#include "video.h"
+#include "sisv.h"
+#endif
+
+#if 0
+extern const USHORT SiS_MDA_DAC[];
+extern const USHORT SiS_CGA_DAC[];
+extern const USHORT SiS_EGA_DAC[];
+extern const USHORT SiS_VGA_DAC[];
+#endif
+
+extern BOOLEAN SiS_SearchVBModeID(SiS_Private *SiS_Pr, UCHAR *RomAddr, USHORT *);
+
+BOOLEAN SiS_Is301B(SiS_Private *SiS_Pr, USHORT BaseAddr);
+BOOLEAN SiS_IsM650or651(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+BOOLEAN SiS_IsDisableCRT2(SiS_Private *SiS_Pr, USHORT BaseAddr);
+BOOLEAN SiS_IsVAMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+BOOLEAN SiS_IsDualEdge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+BOOLEAN SiS_CRT2IsLCD(SiS_Private *SiS_Pr, USHORT BaseAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void SiS_SetDefCRT2ExtRegs(SiS_Private *SiS_Pr, USHORT BaseAddr);
+USHORT SiS_GetRatePtrCRT2(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension);
+BOOLEAN SiS_AdjustCRT2Rate(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT MODEIdIndex,
+ USHORT RefreshRateTableIndex,USHORT *i,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void SiS_SaveCRT2Info(SiS_Private *SiS_Pr, USHORT ModeNo);
+void SiS_GetCRT2Data(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void SiS_GetCRT2DataLVDS(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void SiS_GetCRT2PtrA(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,USHORT *CRT2Index,USHORT *ResIndex);
+void SiS_GetCRT2Part2Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,USHORT *CRT2Index, USHORT *ResIndex);
+void SiS_GetCRT2Data301(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+USHORT SiS_GetResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
+void SiS_GetCRT2ResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void SiS_GetRAMDAC2DATA(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void SiS_GetCRT2Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,USHORT *CRT2Index,USHORT *ResIndex,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT BaseAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ PSIS_HW_DEVICE_INFO );
+void SiS_SetHiVision(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void SiS_GetLVDSDesData(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void SiS_SetCRT2Offset(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+USHORT SiS_GetOffset(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+USHORT SiS_GetColorDepth(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
+USHORT SiS_GetMCLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+USHORT SiS_CalcDelayVB(SiS_Private *SiS_Pr);
+USHORT SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void SiS_SetCRT2Sync(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+ USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void SiS_SetRegANDOR(USHORT Port,USHORT Index,USHORT DataAND,USHORT DataOR);
+void SiS_SetRegOR(USHORT Port,USHORT Index,USHORT DataOR);
+void SiS_SetRegAND(USHORT Port,USHORT Index,USHORT DataAND);
+USHORT SiS_GetVGAHT2(SiS_Private *SiS_Pr);
+void SiS_Set300Part2Regs(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+ USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
+ USHORT BaseAddr, USHORT ModeNo);
+void SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void SiS_SetGroup3(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void SiS_SetGroup5(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+ USHORT ModeIdIndex);
+void SiS_FinalizeLCD(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void SiS_SetCRT2VCLK(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void SiS_EnableCRT2(SiS_Private *SiS_Pr);
+void SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension, int checkcrt2mode);
+BOOLEAN SiS_BridgeIsOn(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO);
+BOOLEAN SiS_BridgeIsEnable(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO);
+BOOLEAN SiS_BridgeInSlave(SiS_Private *SiS_Pr);
+void SiS_PresetScratchregister(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void SiS_SetTVSystem(SiS_Private *SiS_Pr);
+void SiS_LongWait(SiS_Private *SiS_Pr);
+USHORT SiS_GetQueueConfig(SiS_Private *SiS_Pr);
+void SiS_VBLongWait(SiS_Private *SiS_Pr);
+USHORT SiS_GetVCLKLen(SiS_Private *SiS_Pr, UCHAR *ROMAddr);
+void SiS_WaitVBRetrace(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void SiS_WaitRetrace1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void SiS_WaitRetrace2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void SiS_WaitRetraceDDC(SiS_Private *SiS_Pr);
+void SiS_SetCRT2ECLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void SiS_GetLVDSDesPtr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,USHORT *PanelIndex,USHORT *ResIndex,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void SiS_GetLVDSDesPtrA(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,USHORT *PanelIndex,USHORT *ResIndex);
+void SiS_SetTPData(SiS_Private *SiS_Pr);
+void SiS_WhatIsThis(SiS_Private *SiS_Pr, USHORT myvbinfo);
+void SiS_ModCRT1CRTC(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void SiS_SetCHTVReg(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex);
+void SiS_GetCHTVRegPtr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex);
+void SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempax);
+USHORT SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempax);
+void SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempax);
+USHORT SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempax);
+void SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempax);
+USHORT SiS_GetCH70xx(SiS_Private *SiS_Pr, USHORT tempax);
+#ifdef LINUX_XF86
+USHORT SiS_I2C_GetByte(SiS_Private *SiS_Pr);
+Bool SiS_I2C_PutByte(SiS_Private *SiS_Pr, USHORT data);
+Bool SiS_I2C_Address(SiS_Private *SiS_Pr, USHORT addr);
+void SiS_I2C_Stop(SiS_Private *SiS_Pr);
+#endif
+void SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, USHORT tempax,USHORT tempbh);
+void SiS_SetSwitchDDC2(SiS_Private *SiS_Pr);
+USHORT SiS_SetStart(SiS_Private *SiS_Pr);
+USHORT SiS_SetStop(SiS_Private *SiS_Pr);
+void SiS_DDC2Delay(SiS_Private *SiS_Pr, USHORT delaytime);
+USHORT SiS_SetSCLKLow(SiS_Private *SiS_Pr);
+USHORT SiS_SetSCLKHigh(SiS_Private *SiS_Pr);
+USHORT SiS_ReadDDC2Data(SiS_Private *SiS_Pr, USHORT tempax);
+USHORT SiS_WriteDDC2Data(SiS_Private *SiS_Pr, USHORT tempax);
+USHORT SiS_CheckACK(SiS_Private *SiS_Pr);
+USHORT SiS_ReadLCDDDC(SiS_Private *SiS_Pr, USHORT length, unsigned char *buffer);
+#ifdef SIS315H
+void SiS_OEM310Setting(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+ UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
+void SiS_OEMLCD(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+ UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
+#endif
+#ifdef SIS300
+void SiS_OEM300Setting(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+ UCHAR *ROMAddr,USHORT ModeNo);
+#endif
+BOOLEAN SiS_LowModeStuff(SiS_Private *SiS_Pr, USHORT ModeNo,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+
+BOOLEAN SiS_GetLCDResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo, USHORT ModeIdIndex,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension);
+/* void SiS_CHACRT1CRTC(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex); */
+
+BOOLEAN SiS_SetCRT2Group301(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex);
+void SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex);
+void SiS_SetGroup1_LCDA(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex);
+void SiS_SetGroup1_301(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex);
+#ifdef SIS300
+void SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension);
+#endif
+#ifdef SIS315H
+void SiS_SetCRT2FIFO_310(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,
+ PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void SiS_CRT2AutoThreshold(SiS_Private *SiS_Pr, USHORT BaseAddr);
+#endif
+BOOLEAN SiS_GetLCDDDCInfo(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO,USHORT BaseAddr);
+void SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO,USHORT BaseAddr);
+void SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO,USHORT BaseAddr);
+void SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO,USHORT BaseAddr);
+void SiS_SetPanelDelay(SiS_Private *SiS_Pr, UCHAR* ROMAddr,PSIS_HW_DEVICE_INFO,USHORT DelayTime);
+void SiS_ShortDelay(SiS_Private *SiS_Pr, USHORT delay);
+void SiS_LongDelay(SiS_Private *SiS_Pr, USHORT delay);
+void SiS_GenericDelay(SiS_Private *SiS_Pr, USHORT delay);
+void SiS_VBWait(SiS_Private *SiS_Pr);
+
+void SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+
+/* TW: New functions (with mostly temporary names) */
+void SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr);
+void SiS_Chrontel701xOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+ USHORT BaseAddr);
+void SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr);
+void SiS_Chrontel701xOff(SiS_Private *SiS_Pr);
+void SiS_ChrontelResetDB(SiS_Private *SiS_Pr);
+void SiS_ChrontelDoSomething4(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+void SiS_ChrontelDoSomething3(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+void SiS_ChrontelDoSomething2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+void SiS_ChrontelDoSomething1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+BOOLEAN SiS_WeHaveBacklightCtrl(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+#if 0
+BOOLEAN SiS_IsSomethingCR5F(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+#endif
+BOOLEAN SiS_IsYPbPr(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+BOOLEAN SiS_IsChScart(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+BOOLEAN SiS_IsTVOrYPbPrOrScart(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+BOOLEAN SiS_IsLCDOrLCDA(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+void SiS_SetCH701xForLCD(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+void SiS_ChrontelPowerSequencing(SiS_Private *SiS_Pr);
+BOOLEAN SiS_CR36BIOSWord23b(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+BOOLEAN SiS_CR36BIOSWord23d(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+BOOLEAN SiS_IsSR13_CR30(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+/* TW end */
+
+extern void SiS_SetReg1(USHORT, USHORT, USHORT);
+extern void SiS_SetReg3(USHORT, USHORT);
+extern UCHAR SiS_GetReg1(USHORT, USHORT);
+extern UCHAR SiS_GetReg2(USHORT);
+extern BOOLEAN SiS_SearchModeID(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT *ModeNo,USHORT *ModeIdIndex);
+extern BOOLEAN SiS_GetRatePtr(SiS_Private *SiS_Pr, ULONG, USHORT);
+extern void SiS_SetReg4(USHORT, ULONG);
+extern ULONG SiS_GetReg3(USHORT);
+extern void SiS_SetReg5(USHORT, USHORT);
+extern USHORT SiS_GetReg4(USHORT);
+extern void SiS_DisplayOff(SiS_Private *SiS_Pr);
+extern void SiS_DisplayOn(SiS_Private *SiS_Pr);
+extern UCHAR SiS_GetModePtr(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex);
+extern BOOLEAN SiS_GetLCDACRT1Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,USHORT *ResInfo,USHORT *DisplayType);
+extern BOOLEAN SiS_GetLVDSCRT1Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,USHORT *ResInfo,USHORT *DisplayType);
+extern void SiS_LoadDAC(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO, UCHAR *ROMAddr,USHORT ModeNo,
+ USHORT ModeIdIndex);
+#ifdef SIS315H
+extern UCHAR SiS_Get310DRAMType(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+#endif
+
+#ifdef LINUX_XF86
+/* DDC functions */
+USHORT SiS_InitDDCRegs(SiS_Private *SiS_Pr, SISPtr pSiS, USHORT adaptnum, USHORT DDCdatatype);
+USHORT SiS_WriteDABDDC(SiS_Private *SiS_Pr);
+USHORT SiS_PrepareReadDDC(SiS_Private *SiS_Pr);
+USHORT SiS_PrepareDDC(SiS_Private *SiS_Pr);
+void SiS_SendACK(SiS_Private *SiS_Pr, USHORT yesno);
+USHORT SiS_DoProbeDDC(SiS_Private *SiS_Pr);
+USHORT SiS_ProbeDDC(SiS_Private *SiS_Pr);
+USHORT SiS_ReadDDC(SiS_Private *SiS_Pr, SISPtr pSiS, USHORT DDCdatatype, unsigned char *buffer);
+USHORT SiS_HandleDDC(SiS_Private *SiS_Pr, SISPtr pSiS, USHORT adaptnum,
+ USHORT DDCdatatype, unsigned char *buffer);
+#endif
+
+#endif
diff --git a/src/initdef.h b/src/initdef.h
new file mode 100644
index 0000000..a2d796b
--- /dev/null
+++ b/src/initdef.h
@@ -0,0 +1,434 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/initdef.h,v 1.9 2003/02/04 02:44:28 dawes Exp $ */
+
+
+#ifndef _INITDEF_
+#define _INITDEF_
+
+#define SiS300 0x0300
+#define SiS540 0x5300
+#define SiS630 0x6300
+#define SiS730 0x6300
+
+/* SiS_VBType */
+#define VB_SIS301 0x0001
+#define VB_SIS301B 0x0002
+#define VB_SIS302B 0x0004
+#define VB_SIS30xLV 0x0008
+#define VB_SIS30xNEW 0x0010
+#define VB_NoLCD 0x8000
+#define VB_SIS301BLV302BLV (VB_SIS301B|VB_SIS302B|VB_SIS30xLV|VB_SIS30xNEW)
+#define VB_SIS301B302B (VB_SIS301B|VB_SIS302B)
+#define VB_SIS301LV302LV (VB_SIS30xLV|VB_SIS30xNEW)
+
+#define IS_SIS650740 ((HwDeviceExtension->jChipType >= SIS_650) && (HwDeviceExtension->jChipType < SIS_330))
+
+#define CRT1Len 17
+#define LVDSCRT1Len 15
+#define CHTVRegDataLen 5
+
+/* SiS_ModeType */
+#define ModeText 0x00
+#define ModeCGA 0x01
+#define ModeEGA 0x02
+#define ModeVGA 0x03
+#define Mode15Bpp 0x04
+#define Mode16Bpp 0x05
+#define Mode24Bpp 0x06
+#define Mode32Bpp 0x07
+
+#define ModeInfoFlag 0x07
+#define IsTextMode 0x07
+
+#define DACInfoFlag 0x0018
+#define MemoryInfoFlag 0x01E0
+#define MemorySizeShift 5
+
+/* modeflag */
+#define Charx8Dot 0x0200
+#define LineCompareOff 0x0400
+#define CRT2Mode 0x0800
+#define HalfDCLK 0x1000
+#define NoSupportSimuTV 0x2000
+#define DoubleScanMode 0x8000
+
+/* Infoflag */
+#define SupportAllCRT2 0x0078
+#define SupportTV 0x0008
+#define SupportHiVisionTV 0x0010
+#define SupportLCD 0x0020
+#define SupportRAMDAC2 0x0040
+#define NoSupportTV 0x0070
+#define NoSupportHiVisionTV 0x0060
+#define NoSupportLCD 0x0058
+#define SupportCHTV 0x0800
+#define SupportTV1024 0x0800
+#define InterlaceMode 0x0080
+#define SyncPP 0x0000
+#define SyncPN 0x4000
+#define SyncNP 0x8000
+#define SyncNN 0xc000
+#define ECLKindex0 0x0000
+#define ECLKindex1 0x0100
+#define ECLKindex2 0x0200
+#define ECLKindex3 0x0300
+#define ECLKindex4 0x0400
+
+/* VBInfo */
+#define SetSimuScanMode 0x0001 /* CR 30 */
+#define SwitchToCRT2 0x0002
+#define SetCRT2ToAVIDEO 0x0004
+#define SetCRT2ToSVIDEO 0x0008
+#define SetCRT2ToSCART 0x0010
+#define SetCRT2ToLCD 0x0020
+#define SetCRT2ToRAMDAC 0x0040
+#define SetCRT2ToHiVisionTV 0x0080
+#define SetCRT2ToTV 0x009C /* alias */
+#define SetNTSCTV 0x0000 /* CR 31 */
+#define SetPALTV 0x0100
+#define SetInSlaveMode 0x0200
+#define SetNotSimuMode 0x0400
+#define SetNotSimuTVMode 0x0400
+#define SetDispDevSwitch 0x0800
+#define LoadDACFlag 0x1000
+#define SetCHTVOverScan 0x1000 /* TW: Re-defined (from 0x8000) */
+#define DisableCRT2Display 0x2000
+#define CRT2DisplayFlag 0x2000
+#define DriverMode 0x4000
+#define HotKeySwitch 0x8000 /* TW: ? */
+#define SetCRT2ToLCDA 0x8000
+
+#define PanelRGB18Bit 0x0100
+#define PanelRGB24Bit 0x0000
+
+#define TVOverScan 0x10 /* Bit in CR35 (300 series only) */
+#define TVOverScanShift 4
+#define ClearBufferFlag 0x20
+
+/* CR32 (Newer 630, and 310/325 series)
+
+ [0] VB connected with CVBS
+ [1] VB connected with SVHS
+ [2] VB connected with SCART
+ [3] VB connected with LCD
+ [4] VB connected with CRT2 (secondary VGA)
+ [5] CRT1 monitor is connected
+ [6] VB connected with Hi-Vision TV
+ [7] VB connected with DVI combo connector
+
+
+ CR37
+
+ [0] Set 24/18 bit (0/1) RGB to LVDS/TMDS transmitter (set by BIOS)
+ [3:1] External chip
+ 300 series:
+ 001 SiS301 (never seen)
+ 010 LVDS
+ 011 LVDS + Tumpion Zurac
+ 100 LVDS + Chrontel 7005
+ 110 Chrontel 7005
+ 310/325 series
+ 001 SiS30x (never seen)
+ 010 LVDS
+ 011 LVDS + Chrontel 7019
+ All other combinations reserved
+ [4] LVDS: Expanding(0)/Non-expanding(1) LCD display
+ 30x: SiS30x(0)/LCD monitor(1) scaling display
+ [5] LCD polarity select
+ 0: VESA DMT Standard
+ 1: EDID 2.x defined
+ [6] LCD horizontal polarity select
+ 0: High active
+ 1: Low active
+ [7] LCD vertical polarity select
+ 0: High active
+ 1: Low active
+*/
+
+/* CR38 (310/325 series) */
+#define EnableDualEdge 0x01
+#define SetToLCDA 0x02 /* LCD channel A (302B/LV and 650+LVDS only) */
+#define EnableSiSHiVision 0x04 /* HiVision (HDTV) on SiS bridge */
+#define EnableLVDSScart 0x04 /* Scart on Ch7019 (unofficial definition - TW) */
+#define EnableLVDSHiVision 0x08 /* YPbPr color format (480i HDTV); only on 650/Ch7019 systems */
+#define SiSHiVision1 0x10 /* See SetHiVision() */
+#define SiSHiVision2 0x20
+#define EnablePALM 0x40 /* 1 = Set PALM */
+#define EnablePALN 0x80 /* 1 = Set PALN */
+
+#define SetSCARTOutput 0x01
+#define BoardTVType 0x02
+
+#define EnablePALMN 0x40 /* Romflag: 1 = Allow PALM/PALN */
+
+/* CR39 (650) */
+#define LCDPass1_1 0x01 /* LVDS only; set by driver to pass 1:1 data to LVDS output */
+#define SomeThingTV_LVNEW 0x04 /* 30xNEW only; set by mode switching function */
+
+
+/* CR79 (310/325 series only)
+ [3-0] Notify driver
+ 0001 Mode Switch event (set by BIOS)
+ 0010 Epansion On/Off event
+ 0011 TV UnderScan/OverScan event
+ 0100 Set Brightness event
+ 0101 Set Contrast event
+ 0110 Set Mute event
+ 0111 Set Volume Up/Down event
+ [4] Enable Backlight Control by BIOS/driver (set by driver)
+ [5] PAL/NTSC (set by BIOS)
+ [6] Expansion On/Off (set by BIOS; copied to CR32[4])
+ [7] TV UnderScan/OverScan (set by BIOS)
+*/
+
+/* SetFlag */
+#define ProgrammingCRT2 0x01
+#define TVSimuMode 0x02
+#define RPLLDIV2XO 0x04
+#define LCDVESATiming 0x08
+#define EnableLVDSDDA 0x10
+#define SetDispDevSwitchFlag 0x20
+#define CheckWinDos 0x40
+#define SetJDOSMode 0x80
+#define CRT2IsVGA 0x80 /* TW: Not sure about this name... */
+
+/* LCDResInfo */
+#define Panel300_800x600 0x01 /* CR36 */
+#define Panel300_1024x768 0x02
+#define Panel300_1280x1024 0x03
+#define Panel300_1280x960 0x04
+#define Panel300_640x480 0x05
+#define Panel300_1024x600 0x06
+#define Panel300_1152x768 0x07
+#define Panel300_320x480 0x08 /* fstn - TW: This is fake, can be any */
+
+#define Panel310_800x600 0x01
+#define Panel310_1024x768 0x02
+#define Panel310_1280x1024 0x03
+#define Panel310_640x480 0x04
+#define Panel310_1024x600 0x05
+#define Panel310_1152x864 0x06
+#define Panel310_1280x960 0x07
+#define Panel310_1152x768 0x08 /* LVDS only */
+#define Panel310_1400x1050 0x09
+#define Panel310_1280x768 0x0a /* LVDS only */
+#define Panel310_1600x1200 0x0b
+#define Panel310_320x480 0x0c /* fstn - TW: This is fake, can be any */
+
+#define Panel_800x600 0x01 /* Unified values */
+#define Panel_1024x768 0x02
+#define Panel_1280x1024 0x03
+#define Panel_640x480 0x04
+#define Panel_1024x600 0x05
+#define Panel_1152x864 0x06
+#define Panel_1280x960 0x07
+#define Panel_1152x768 0x08 /* LVDS only */
+#define Panel_1400x1050 0x09
+#define Panel_1280x768 0x0a /* LVDS only */
+#define Panel_1600x1200 0x0b
+#define Panel_320x480 0x0c /* fstn - TW: This is fake, can be any */
+
+#define ExtChipType 0x0e
+#define ExtChip301 0x02
+#define ExtChipLVDS 0x04
+#define ExtChipTrumpion 0x06
+#define ExtChipCH7005 0x08
+#define ExtChipMitacTV 0x0a /* TW: Incorrect, 0x0a = Chrontel 7005 only */
+
+#define IsM650 0x80 /* TW: CR5F */
+
+/* LCDInfo */
+#define LCDRGB18Bit 0x01
+#define LCDNonExpanding 0x10
+#define LCDNonExpandingShift 4
+#define LCDSync 0x20
+#define LCDPass11 0x100
+#define LCDSyncBit 0xe0
+#define LCDSyncShift 6
+
+#define LCDDataLen 8
+#define HiTVDataLen 12
+#define TVDataLen 16
+#define SetPALTV 0x0100
+#define HalfDCLK 0x1000 /* modeflag */
+#define NTSCHT 1716
+#define NTSC2HT 1920
+#define NTSCVT 525
+#define PALHT 1728
+#define PALVT 625
+#define StHiTVHT 892
+#define StHiTVVT 1126
+#define StHiTextTVHT 1000
+#define StHiTextTVVT 1126
+#define ExtHiTVHT 2100
+#define ExtHiTVVT 1125
+
+#define VCLKStartFreq 25
+#define SoftDramType 0x80
+
+#define VCLK40 0x04 /* Index in VCLKData array */
+#define VCLK65 0x09 /* Index in VCLKData array */
+#define VCLK108_2 0x14 /* Index in VCLKData array */
+#define TVVCLKDIV2 0x21 /* Indices in (VB)VCLKData arrays */
+#define TVVCLK 0x22
+#define HiTVVCLKDIV2 0x23
+#define HiTVVCLK 0x24
+#define HiTVSimuVCLK 0x25
+#define HiTVTextVCLK 0x26
+
+#define LoadDACFlag 0x1000
+#define AfterLockCRT2 0x4000
+#define SetCRT2ToAVIDEO 0x0004
+#define SetCRT2ToSCART 0x0010
+#define Ext2StructSize 5
+
+#define SetSCARTOutput 0x01
+#define AVIDEOSense 0x01
+#define SVIDEOSense 0x02
+#define SCARTSense 0x04
+#define LCDSense 0x08
+#define Monitor1Sense 0x20
+#define Monitor2Sense 0x10
+#define HiTVSense 0x40
+#define BoardTVType 0x02
+#define HotPlugFunction 0x08
+#define StStructSize 0x06
+
+#define SIS_CRT2_PORT_04 0x04 - 0x30
+#define SIS_CRT2_PORT_10 0x10 - 0x30
+#define SIS_CRT2_PORT_12 0x12 - 0x30
+#define SIS_CRT2_PORT_14 0x14 - 0x30
+
+#define ADR_CRT2PtrData 0x20E
+#define offset_Zurac 0x210 /* TW: Trumpion Zurac data pointer */
+#define ADR_LVDSDesPtrData 0x212
+#define ADR_LVDSCRT1DataPtr 0x214
+#define ADR_CHTVVCLKPtr 0x216
+#define ADR_CHTVRegDataPtr 0x218
+
+#define LVDSDataLen 6
+#define EnableLVDSDDA 0x10
+#define LVDSDesDataLen 3
+#define ActiveNonExpanding 0x40
+#define ActiveNonExpandingShift 6
+#define ActivePAL 0x20
+#define ActivePALShift 5
+#define ModeSwitchStatus 0x0F
+#define SoftTVType 0x40
+#define SoftSettingAddr 0x52
+#define ModeSettingAddr 0x53
+
+#define SelectCRT1Rate 0x4
+
+#define _PanelType00 0x00
+#define _PanelType01 0x08
+#define _PanelType02 0x10
+#define _PanelType03 0x18
+#define _PanelType04 0x20
+#define _PanelType05 0x28
+#define _PanelType06 0x30
+#define _PanelType07 0x38
+#define _PanelType08 0x40
+#define _PanelType09 0x48
+#define _PanelType0A 0x50
+#define _PanelType0B 0x58
+#define _PanelType0C 0x60
+#define _PanelType0D 0x68
+#define _PanelType0E 0x70
+#define _PanelType0F 0x78
+
+#define PRIMARY_VGA 0 /* 1: SiS is primary vga 0:SiS is secondary vga */
+#define BIOSIDCodeAddr 0x235 /* TW: Offsets to ptrs in BIOS image */
+#define OEMUtilIDCodeAddr 0x237
+#define VBModeIDTableAddr 0x239
+#define OEMTVPtrAddr 0x241
+#define PhaseTableAddr 0x243
+#define NTSCFilterTableAddr 0x245
+#define PALFilterTableAddr 0x247
+#define OEMLCDPtr_1Addr 0x249
+#define OEMLCDPtr_2Addr 0x24B
+#define LCDHPosTable_1Addr 0x24D
+#define LCDHPosTable_2Addr 0x24F
+#define LCDVPosTable_1Addr 0x251
+#define LCDVPosTable_2Addr 0x253
+#define OEMLCDPIDTableAddr 0x255
+
+#define VBModeStructSize 5
+#define PhaseTableSize 4
+#define FilterTableSize 4
+#define LCDHPosTableSize 7
+#define LCDVPosTableSize 5
+#define OEMLVDSPIDTableSize 4
+#define LVDSHPosTableSize 4
+#define LVDSVPosTableSize 6
+
+#define VB_ModeID 0
+#define VB_TVTableIndex 1
+#define VB_LCDTableIndex 2
+#define VB_LCDHIndex 3
+#define VB_LCDVIndex 4
+
+#define OEMLCDEnable 0x0001
+#define OEMLCDDelayEnable 0x0002
+#define OEMLCDPOSEnable 0x0004
+#define OEMTVEnable 0x0100
+#define OEMTVDelayEnable 0x0200
+#define OEMTVFlickerEnable 0x0400
+#define OEMTVPhaseEnable 0x0800
+#define OEMTVFilterEnable 0x1000
+
+#define OEMLCDPanelIDSupport 0x0080
+
+/*
+ =============================================================
+ for 310/325 series
+ =============================================================
+*/
+#define SoftDRAMType 0x80
+#define SoftSetting_OFFSET 0x52
+#define SR07_OFFSET 0x7C
+#define SR15_OFFSET 0x7D
+#define SR16_OFFSET 0x81
+#define SR17_OFFSET 0x85
+#define SR19_OFFSET 0x8D
+#define SR1F_OFFSET 0x99
+#define SR21_OFFSET 0x9A
+#define SR22_OFFSET 0x9B
+#define SR23_OFFSET 0x9C
+#define SR24_OFFSET 0x9D
+#define SR25_OFFSET 0x9E
+#define SR31_OFFSET 0x9F
+#define SR32_OFFSET 0xA0
+#define SR33_OFFSET 0xA1
+
+#define CR40_OFFSET 0xA2
+#define SR25_1_OFFSET 0xF6
+#define CR49_OFFSET 0xF7
+
+#define VB310Data_1_2_Offset 0xB6
+#define VB310Data_4_D_Offset 0xB7
+#define VB310Data_4_E_Offset 0xB8
+#define VB310Data_4_10_Offset 0xBB
+
+#define RGBSenseDataOffset 0xBD
+#define YCSenseDataOffset 0xBF
+#define VideoSenseDataOffset 0xC1
+#define OutputSelectOffset 0xF3
+
+#define ECLK_MCLK_DISTANCE 0x14
+#define VBIOSTablePointerStart 0x100
+#define StandTablePtrOffset VBIOSTablePointerStart+0x02
+#define EModeIDTablePtrOffset VBIOSTablePointerStart+0x04
+#define CRT1TablePtrOffset VBIOSTablePointerStart+0x06
+#define ScreenOffsetPtrOffset VBIOSTablePointerStart+0x08
+#define VCLKDataPtrOffset VBIOSTablePointerStart+0x0A
+#define MCLKDataPtrOffset VBIOSTablePointerStart+0x0E
+#define CRT2PtrDataPtrOffset VBIOSTablePointerStart+0x10
+#define TVAntiFlickPtrOffset VBIOSTablePointerStart+0x12
+#define TVDelayPtr1Offset VBIOSTablePointerStart+0x14
+#define TVPhaseIncrPtr1Offset VBIOSTablePointerStart+0x16
+#define TVYFilterPtr1Offset VBIOSTablePointerStart+0x18
+#define LCDDelayPtr1Offset VBIOSTablePointerStart+0x20
+#define TVEdgePtr1Offset VBIOSTablePointerStart+0x24
+#define CRT2Delay1Offset VBIOSTablePointerStart+0x28
+
+#endif
diff --git a/src/oem300.h b/src/oem300.h
new file mode 100644
index 0000000..8f7e524
--- /dev/null
+++ b/src/oem300.h
@@ -0,0 +1,1005 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/oem300.h,v 1.3 2003/02/10 01:14:16 tsi Exp $ */
+
+/* OEM Data for 300 series */
+
+const UCHAR SiS300_OEMTVDelay301[8][4] =
+{
+ {0x08,0x08,0x08,0x08},
+ {0x08,0x08,0x08,0x08},
+ {0x08,0x08,0x08,0x08},
+ {0x2c,0x2c,0x2c,0x2c},
+ {0x08,0x08,0x08,0x08},
+ {0x08,0x08,0x08,0x08},
+ {0x08,0x08,0x08,0x08},
+ {0x20,0x20,0x20,0x20}
+};
+
+const UCHAR SiS300_OEMTVDelayLVDS[8][4] =
+{
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20}
+};
+
+const UCHAR SiS300_OEMTVFlicker[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}
+};
+
+#if 0 /* TW: Not used */
+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
+
+/* TW: From 630/301B BIOS */
+const UCHAR SiS300_OEMLCDDelay2[64][4] = /* for 301/301b/302b/301LV/302LV */
+{
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20}
+};
+
+/* TW: From 300/301LV BIOS */
+const UCHAR SiS300_OEMLCDDelay4[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}
+};
+
+/* TW: From 300/301LV BIOS */
+const UCHAR SiS300_OEMLCDDelay5[32][4] =
+{
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+};
+
+/* TW: Added for LVDS */
+const UCHAR SiS300_OEMLCDDelay3[64][4] = { /* For LVDS */
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20},
+ {0x20,0x20,0x20,0x20}
+};
+
+const UCHAR SiS300_Phase1[8][6][4] =
+{
+ {
+ {0x21,0xed,0x00,0x08},
+ {0x21,0xed,0x8a,0x08},
+ {0x21,0xed,0x8a,0x08},
+ {0x21,0xed,0x8a,0x08},
+ {0x21,0xed,0x8a,0x08},
+ {0xff,0xff,0xff,0xff}
+ },
+ {
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
+ {0xff,0xff,0xff,0xff}
+ },
+ {
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
+ {0xff,0xff,0xff,0xff}
+ },
+ {
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
+ {0xff,0xff,0xff,0xff}
+ },
+ {
+ {0x21,0xed,0x00,0x08},
+ {0x21,0xed,0x8a,0x08},
+ {0x21,0xed,0x8a,0x08},
+ {0x21,0xed,0x8a,0x08},
+ {0x21,0xed,0x8a,0x08},
+ {0xff,0xff,0xff,0xff}
+ },
+ {
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
+ {0xff,0xff,0xff,0xff}
+ },
+ {
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
+ {0xff,0xff,0xff,0xff}
+ },
+ {
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
+ {0xff,0xff,0xff,0xff}
+ }
+};
+
+
+const UCHAR SiS300_Phase2[8][6][4] =
+{
+ {
+ {0x21,0xed,0x00,0x08},
+ {0x21,0xed,0x8a,0x08},
+ {0x21,0xed,0x8a,0x08},
+ {0x21,0xed,0x8a,0x08},
+ {0x21,0xed,0x8a,0x08},
+ {0xff,0xff,0xff,0xff}
+ },
+ {
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
+ {0xff,0xff,0xff,0xff}
+ },
+ {
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
+ {0xff,0xff,0xff,0xff}
+ },
+ {
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
+ {0xff,0xff,0xff,0xff}
+ },
+ {
+ {0x21,0xed,0x00,0x08},
+ {0x21,0xed,0x8a,0x08},
+ {0x21,0xed,0x8a,0x08},
+ {0x21,0xed,0x8a,0x08},
+ {0x21,0xed,0x8a,0x08},
+ {0xff,0xff,0xff,0xff}
+ },
+ {
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
+ {0xff,0xff,0xff,0xff}
+ },
+ {
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
+ {0xff,0xff,0xff,0xff}
+ },
+ {
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
+ {0xff,0xff,0xff,0xff}
+ }
+};
+
+const UCHAR SiS300_Filter1[10][16][4] =
+{
+ {
+ {0x00,0xf4,0x10,0x38},
+ {0x00,0xf4,0x10,0x38},
+ {0xeb,0x04,0x10,0x18},
+ {0xf7,0x06,0x19,0x14},
+ {0x00,0xf4,0x10,0x38},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x15,0x25,0xf6},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x04,0x25,0x18}
+ },
+ {
+ {0x00,0xf4,0x10,0x38},
+ {0x00,0xf4,0x10,0x38},
+ {0xf1,0xf7,0x10,0x32},
+ {0xf3,0x00,0x1d,0x20},
+ {0x00,0xf4,0x10,0x38},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xfc,0xfb,0x14,0x2a},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf1,0xf7,0x1f,0x32}
+ },
+ {
+ {0x00,0xf4,0x10,0x38},
+ {0x00,0xf4,0x10,0x38},
+ {0xf1,0xf7,0x10,0x32},
+ {0xf3,0x00,0x1d,0x20},
+ {0x00,0xf4,0x10,0x38},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xfc,0xfb,0x14,0x2a},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf1,0xf7,0x1f,0x32}
+ },
+ {
+ {0x00,0xf4,0x10,0x38},
+ {0x00,0xf4,0x10,0x38},
+ {0xf1,0xf7,0x10,0x32},
+ {0xf3,0x00,0x1d,0x20},
+ {0x00,0xf4,0x10,0x38},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xfc,0xfb,0x14,0x2a},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf1,0xf7,0x1f,0x32}
+ },
+ {
+ {0x00,0xf4,0x10,0x38},
+ {0x00,0xf4,0x10,0x38},
+ {0xeb,0x04,0x10,0x18},
+ {0xf7,0x06,0x19,0x14},
+ {0x00,0xf4,0x10,0x38},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x15,0x25,0xf6},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x04,0x25,0x18}
+ },
+ {
+ {0x00,0xf4,0x10,0x38},
+ {0x00,0xf4,0x10,0x38},
+ {0xf1,0xf7,0x10,0x32},
+ {0xf3,0x00,0x1d,0x20},
+ {0x00,0xf4,0x10,0x38},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xfc,0xfb,0x14,0x2a},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf1,0xf7,0x1f,0x32}
+ },
+ {
+ {0x00,0xf4,0x10,0x38},
+ {0x00,0xf4,0x10,0x38},
+ {0xf1,0xf7,0x10,0x32},
+ {0xf3,0x00,0x1d,0x20},
+ {0x00,0xf4,0x10,0x38},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xfc,0xfb,0x14,0x2a},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf1,0xf7,0x1f,0x32}
+ },
+ {
+ {0x00,0xf4,0x10,0x38},
+ {0x00,0xf4,0x10,0x38},
+ {0xf1,0xf7,0x10,0x32},
+ {0xf3,0x00,0x1d,0x20},
+ {0x00,0xf4,0x10,0x38},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xfc,0xfb,0x14,0x2a},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf1,0xf7,0x1f,0x32}
+ },
+ {
+ {0x00,0xf4,0x10,0x38},
+ {0x00,0xf4,0x10,0x38},
+ {0xeb,0x04,0x10,0x18},
+ {0xf7,0x06,0x19,0x14},
+ {0x00,0xf4,0x10,0x38},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x15,0x25,0xf6},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x04,0x25,0x18}
+ },
+ {
+ {0x00,0xf4,0x10,0x38},
+ {0x00,0xf4,0x10,0x38},
+ {0xeb,0x04,0x10,0x18},
+ {0xf7,0x06,0x19,0x14},
+ {0x00,0xf4,0x10,0x38},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x15,0x25,0xf6},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x04,0x25,0x18}
+ },
+};
+
+const UCHAR SiS300_Filter2[10][9][7] =
+{
+ {
+ {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+ {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+ {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+ {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+ {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+ {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+ {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},
+ {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+ {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+ {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+ {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+ {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+ {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},
+ {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+ {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+ {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+ {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+ {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+ {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},
+ {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+ {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+ {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+ {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+ {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+ {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},
+ {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+ {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+ {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+ {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+ {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+ {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},
+ {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+ {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+ {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+ {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+ {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+ {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},
+ {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+ {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+ {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+ {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+ {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+ {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},
+ {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+ {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+ {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+ {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+ {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+ {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},
+ {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+ {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+ {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+ {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+ {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+ {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},
+ {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+ {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+ {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+ {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+ {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+ {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+ {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
+ {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
+ }
+};
+
+const UCHAR SiS300_LCDHData[24][11][5] = {
+ {
+ {0x67,0x91,0x84,0x5e,0x00},
+ {0x67,0x91,0x84,0x5e,0x00},
+ {0x67,0x91,0x84,0x5e,0x00},
+ {0x67,0x91,0x84,0x5e,0x00},
+ {0x67,0x91,0x84,0x5e,0x00},
+ {0x67,0x91,0x84,0x5e,0x00},
+ {0x67,0x91,0x84,0x5e,0x00},
+ {0x65,0xef,0x83,0x5c,0x00},
+ {0x65,0xef,0x83,0x5c,0x00},
+ {0x8a,0x14,0x00,0x80,0x00},
+ {0x8a,0x14,0x00,0x80,0x00}
+ },
+ {
+ {0x4e,0x18,0x90,0x38,0x00},
+ {0x4e,0x18,0x90,0x38,0x00},
+ {0x8e,0x18,0x28,0x78,0x00},
+ {0x8e,0x18,0x28,0x78,0x00},
+ {0x8e,0x18,0x28,0x78,0x00},
+ {0x4e,0x18,0x90,0x38,0x00},
+ {0x4e,0x18,0x90,0x38,0x00},
+ {0x67,0x11,0x9a,0x56,0x00},
+ {0x67,0x11,0x9a,0x56,0x00},
+ {0x8a,0x14,0x00,0x80,0x00},
+ {0x8a,0x14,0x00,0x80,0x00}
+ },
+ {
+ {0x67,0x91,0x84,0x5e,0x00},
+ {0x67,0x91,0x84,0x5e,0x00},
+ {0x67,0x91,0x84,0x5e,0x00},
+ {0x67,0x91,0x84,0x5e,0x00},
+ {0x67,0x91,0x84,0x5e,0x00},
+ {0x67,0x91,0x84,0x5e,0x00},
+ {0x67,0x91,0x84,0x5e,0x00},
+ {0x65,0xef,0x83,0x5c,0x00},
+ {0x65,0xef,0x83,0x5c,0x00},
+ {0x8a,0x14,0x00,0x80,0x00},
+ {0x8a,0x14,0x00,0x80,0x00}
+ },
+ {
+ {0x4e,0x18,0x90,0x38,0x00},
+ {0x4e,0x18,0x90,0x38,0x00},
+ {0x8e,0x18,0x28,0x78,0x00},
+ {0x8e,0x18,0x28,0x78,0x00},
+ {0x8e,0x18,0x28,0x78,0x00},
+ {0x4e,0x18,0x90,0x38,0x00},
+ {0x4e,0x18,0x90,0x38,0x00},
+ {0x67,0x11,0x9a,0x56,0x00},
+ {0x67,0x11,0x9a,0x56,0x00},
+ {0x8a,0x14,0x00,0x80,0x00},
+ {0x8a,0x14,0x00,0x80,0x00}
+ },
+ {
+ {0x67,0x91,0x84,0x5e,0x00},
+ {0x67,0x91,0x84,0x5e,0x00},
+ {0x67,0x91,0x84,0x5e,0x00},
+ {0x67,0x91,0x84,0x5e,0x00},
+ {0x67,0x91,0x84,0x5e,0x00},
+ {0x67,0x91,0x84,0x5e,0x00},
+ {0x67,0x91,0x84,0x5e,0x00},
+ {0x65,0xef,0x83,0x5c,0x00},
+ {0x65,0xef,0x83,0x5c,0x00},
+ {0x8a,0x14,0x00,0x80,0x00},
+ {0x8a,0x14,0x00,0x80,0x00}
+ },
+ {
+ {0x4E,0x18,0x90,0x38,0x00},
+ {0x4E,0x18,0x90,0x38,0x00},
+ {0x8E,0x18,0x28,0x78,0x00},
+ {0x8E,0x18,0x28,0x78,0x00},
+ {0x8E,0x18,0x28,0x78,0x00},
+ {0x4E,0x18,0x90,0x38,0x00},
+ {0x4E,0x18,0x90,0x38,0x00},
+ {0x67,0x11,0x9A,0x56,0x00},
+ {0x67,0x11,0x9A,0x56,0x00},
+ {0x8A,0x14,0x00,0x80,0x00},
+ {0x8A,0x14,0x00,0x80,0x00}
+ },
+ {
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x65,0xEF,0x83,0x5C,0x00},
+ {0x65,0xEF,0x83,0x5C,0x00},
+ {0x8A,0x14,0x00,0x80,0x00},
+ {0x8A,0x14,0x00,0x80,0x00}
+ },
+ {
+ {0x4E,0x18,0x90,0x38,0x00},
+ {0x4E,0x18,0x90,0x38,0x00},
+ {0x8E,0x18,0x28,0x78,0x00},
+ {0x8E,0x18,0x28,0x78,0x00},
+ {0x8E,0x18,0x28,0x78,0x00},
+ {0x4E,0x18,0x90,0x38,0x00},
+ {0x4E,0x18,0x90,0x38,0x00},
+ {0x67,0x11,0x9A,0x56,0x00},
+ {0x67,0x11,0x9A,0x56,0x00},
+ {0x8A,0x14,0x00,0x80,0x00},
+ {0x8A,0x14,0x00,0x80,0x00}
+ },
+ {
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x65,0xEF,0x83,0x5C,0x00},
+ {0x65,0xEF,0x83,0x5C,0x00},
+ {0x8A,0x14,0x00,0x80,0x00},
+ {0x8A,0x14,0x00,0x80,0x00}
+ },
+ {
+ {0x4E,0x18,0x90,0x38,0x00},
+ {0x4E,0x18,0x90,0x38,0x00},
+ {0x8E,0x18,0x28,0x78,0x00},
+ {0x8E,0x18,0x28,0x78,0x00},
+ {0x8E,0x18,0x28,0x78,0x00},
+ {0x4E,0x18,0x90,0x38,0x00},
+ {0x4E,0x18,0x90,0x38,0x00},
+ {0x67,0x11,0x9A,0x56,0x00},
+ {0x67,0x11,0x9A,0x56,0x00},
+ {0x8A,0x14,0x00,0x80,0x00},
+ {0x8A,0x14,0x00,0x80,0x00}
+ },
+ {
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x65,0xEF,0x83,0x5C,0x00},
+ {0x65,0xEF,0x83,0x5C,0x00},
+ {0x8A,0x14,0x00,0x80,0x00},
+ {0x8A,0x14,0x00,0x80,0x00}
+ },
+ {
+ {0x4E,0x18,0x90,0x38,0x00},
+ {0x4E,0x18,0x90,0x38,0x00},
+ {0x8E,0x18,0x28,0x78,0x00},
+ {0x8E,0x18,0x28,0x78,0x00},
+ {0x8E,0x18,0x28,0x78,0x00},
+ {0x4E,0x18,0x90,0x38,0x00},
+ {0x4E,0x18,0x90,0x38,0x00},
+ {0x67,0x11,0x9A,0x56,0x00},
+ {0x67,0x11,0x9A,0x56,0x00},
+ {0x8A,0x14,0x00,0x80,0x00},
+ {0x8A,0x14,0x00,0x80,0x00}
+ },
+ {
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x65,0xEF,0x83,0x5C,0x00},
+ {0x65,0xEF,0x83,0x5C,0x00},
+ {0x8A,0x14,0x00,0x80,0x00},
+ {0x8A,0x14,0x00,0x80,0x00}
+ },
+ {
+ {0x4E,0x18,0x90,0x38,0x00},
+ {0x4E,0x18,0x90,0x38,0x00},
+ {0x8E,0x18,0x28,0x78,0x00},
+ {0x8E,0x18,0x28,0x78,0x00},
+ {0x8E,0x18,0x28,0x78,0x00},
+ {0x4E,0x18,0x90,0x38,0x00},
+ {0x4E,0x18,0x90,0x38,0x00},
+ {0x67,0x11,0x9A,0x56,0x00},
+ {0x67,0x11,0x9A,0x56,0x00},
+ {0x8A,0x14,0x00,0x80,0x00},
+ {0x8A,0x14,0x00,0x80,0x00}
+ },
+ {
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x65,0xEF,0x83,0x5C,0x00},
+ {0x65,0xEF,0x83,0x5C,0x00},
+ {0x8A,0x14,0x00,0x80,0x00},
+ {0x8A,0x14,0x00,0x80,0x00}
+ },
+ {
+ {0x4E,0x18,0x90,0x38,0x00},
+ {0x4E,0x18,0x90,0x38,0x00},
+ {0x8E,0x18,0x28,0x78,0x00},
+ {0x8E,0x18,0x28,0x78,0x00},
+ {0x8E,0x18,0x28,0x78,0x00},
+ {0x4E,0x18,0x90,0x38,0x00},
+ {0x4E,0x18,0x90,0x38,0x00},
+ {0x67,0x11,0x9A,0x56,0x00},
+ {0x67,0x11,0x9A,0x56,0x00},
+ {0x8A,0x14,0x00,0x80,0x00},
+ {0x8A,0x14,0x00,0x80,0x00}
+ },
+ {
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x65,0xEF,0x83,0x5C,0x00},
+ {0x65,0xEF,0x83,0x5C,0x00},
+ {0x8A,0x14,0x00,0x80,0x00},
+ {0x8A,0x14,0x00,0x80,0x00}
+ },
+ {
+ {0x4E,0x18,0x90,0x38,0x00},
+ {0x4E,0x18,0x90,0x38,0x00},
+ {0x8E,0x18,0x28,0x78,0x00},
+ {0x8E,0x18,0x28,0x78,0x00},
+ {0x8E,0x18,0x28,0x78,0x00},
+ {0x4E,0x18,0x90,0x38,0x00},
+ {0x4E,0x18,0x90,0x38,0x00},
+ {0x67,0x11,0x9A,0x56,0x00},
+ {0x67,0x11,0x9A,0x56,0x00},
+ {0x8A,0x14,0x00,0x80,0x00},
+ {0x8A,0x14,0x00,0x80,0x00}
+ },
+ {
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x65,0xEF,0x83,0x5C,0x00},
+ {0x65,0xEF,0x83,0x5C,0x00},
+ {0x8A,0x14,0x00,0x80,0x00},
+ {0x8A,0x14,0x00,0x80,0x00}
+ },
+ {
+ {0x4E,0x18,0x90,0x38,0x00},
+ {0x4E,0x18,0x90,0x38,0x00},
+ {0x8E,0x18,0x28,0x78,0x00},
+ {0x8E,0x18,0x28,0x78,0x00},
+ {0x8E,0x18,0x28,0x78,0x00},
+ {0x4E,0x18,0x90,0x38,0x00},
+ {0x4E,0x18,0x90,0x38,0x00},
+ {0x67,0x11,0x9A,0x56,0x00},
+ {0x67,0x11,0x9A,0x56,0x00},
+ {0x8A,0x14,0x00,0x80,0x00},
+ {0x8A,0x14,0x00,0x80,0x00}
+ },
+ {
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x65,0xEF,0x83,0x5C,0x00},
+ {0x65,0xEF,0x83,0x5C,0x00},
+ {0x8A,0x14,0x00,0x80,0x00},
+ {0x8A,0x14,0x00,0x80,0x00}
+ },
+ {
+ {0x4E,0x18,0x90,0x38,0x00},
+ {0x4E,0x18,0x90,0x38,0x00},
+ {0x8E,0x18,0x28,0x78,0x00},
+ {0x8E,0x18,0x28,0x78,0x00},
+ {0x8E,0x18,0x28,0x78,0x00},
+ {0x4E,0x18,0x90,0x38,0x00},
+ {0x4E,0x18,0x90,0x38,0x00},
+ {0x67,0x11,0x9A,0x56,0x00},
+ {0x67,0x11,0x9A,0x56,0x00},
+ {0x8A,0x14,0x00,0x80,0x00},
+ {0x8A,0x14,0x00,0x80,0x00}
+ },
+ {
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x67,0x91,0x84,0x5E,0x00},
+ {0x65,0xEF,0x83,0x5C,0x00},
+ {0x65,0xEF,0x83,0x5C,0x00},
+ {0x8A,0x14,0x00,0x80,0x00},
+ {0x8A,0x14,0x00,0x80,0x00}
+ },
+ {
+ {0x4E,0x18,0x90,0x38,0x00},
+ {0x4E,0x18,0x90,0x38,0x00},
+ {0x8E,0x18,0x28,0x78,0x00},
+ {0x8E,0x18,0x28,0x78,0x00},
+ {0x8E,0x18,0x28,0x78,0x00},
+ {0x4E,0x18,0x90,0x38,0x00},
+ {0x4E,0x18,0x90,0x38,0x00},
+ {0x67,0x11,0x9A,0x56,0x00},
+ {0x67,0x11,0x9A,0x56,0x00},
+ {0x8A,0x14,0x00,0x80,0x00},
+ {0x8A,0x14,0x00,0x80,0x00}
+ }
+};
+
+#if 0
+const UCHAR SiS300_LCDVData[24][11][6] = {
+ {
+ {
+ },
+};
+#endif
diff --git a/src/oem310.h b/src/oem310.h
new file mode 100644
index 0000000..c4415aa
--- /dev/null
+++ b/src/oem310.h
@@ -0,0 +1,377 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/oem310.h,v 1.4 2003/02/10 01:14:16 tsi Exp $ */
+
+/* OEM Data for 310/325 series */
+
+const UCHAR SiS310_CRT2DelayCompensation1 = 0x04; /* 301 */
+
+const UCHAR SiS310_CRT2DelayCompensation2 = 0x00; /* 301B */
+
+const UCHAR SiS310_CRT2DelayCompensation3 = 0x00; /* LVDS */
+
+const UCHAR SiS310_LCDDelayCompensation1[] = /* 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
+};
+
+UCHAR SiS310_LCDDelayCompensation2[] = /* 30xB,LV,LVX */
+{
+ 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
+};
+
+const UCHAR SiS310_LCDDelayCompensation3[] = /* LVDS */
+{
+ 0x00,0x00,0x00, /* 800x600 */
+ 0x00,0x00,0x00, /* 1024x768 */
+ 0x00,0x00,0x00, /* 1280x1024 */
+ 0x00,0x00,0x00, /* 640x480 (unknown) */
+ 0x00,0x00,0x00, /* 1024x600 (unknown) */
+ 0x00,0x00,0x00, /* 1152x864 (unknown) */
+ 0x00,0x00,0x00, /* 1280x960 (guessed) */
+ 0x00,0x00,0x00, /* 1152x768 (unknown) */
+ 0x00,0x00,0x00, /* 1400x1050 */
+ 0x00,0x00,0x00, /* 1280x768 (guessed) */
+ 0x00,0x00,0x00, /* 1600x1200 */
+ 0x00,0x00,0x00,
+ 0x00,0x00,0x00,
+ 0x00,0x00,0x00,
+ 0x00,0x00,0x00
+};
+
+const UCHAR SiS310_LCDDelayCompensation4[] = /* 650 */
+{
+ 0x01,0x01,0x01, /* 800x600 (guessed)*/
+ 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 */
+ 0x01,0x01,0x01,
+ 0x01,0x01,0x01,
+ 0x01,0x01,0x01,
+ 0x01,0x01,0x01
+};
+
+const UCHAR SiS310_LCDDelayCompensation5[] = /* 650 LVX */
+{
+ 0x01,0x01,0x01, /* 800x600 (guessed) */
+ 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 */
+ 0x01,0x01,0x01,
+ 0x01,0x01,0x01,
+ 0x01,0x01,0x01,
+ 0x01,0x01,0x01
+};
+
+const UCHAR SiS310_LCDDelayCompensation6[] = /* M650/651 */
+{
+ 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
+};
+
+const UCHAR SiS310_LCDDelayCompensation7[] = /* M650/651 301LVX */
+{
+ 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
+};
+
+const UCHAR SiS310_TVDelayCompensation1[] = /* 301 */
+{
+ 0x02,0x02, /* NTSC Enhanced, Standard */
+ 0x02,0x02, /* PAL */
+ 0x08,0x0b /* HiVision */
+};
+
+const UCHAR SiS310_TVDelayCompensation2[] = /* 301B;LV */
+{
+ 0x03,0x03,
+ 0x03,0x03,
+ 0x03,0x03
+};
+
+const UCHAR SiS310_TVDelayCompensation3[] = /* LVDS */
+{
+ 0x0a,0x0a,
+ 0x0a,0x0a,
+ 0x0a,0x0a
+};
+
+const UCHAR SiS310_TVDelayCompensation4[] = /* 650 */
+{
+ 0x03,0x03,
+ 0x03,0x03,
+ 0x03,0x03
+};
+
+const UCHAR SiS310_TVDelayCompensation5[] = /* 650 LVX */
+{
+ 0x03,0x03,
+ 0x03,0x03,
+ 0x03,0x03
+};
+
+const UCHAR SiS310_TVDelayCompensation6[] = /* M650, 651 */
+{
+ 0x33,0x33,
+ 0x33,0x33,
+ 0x33,0x33
+};
+
+const UCHAR SiS310_TVDelayCompensation7[] = /* M650, 651, LVX */
+{
+ 0x33,0x33,
+ 0x33,0x33,
+ 0x33,0x33
+};
+
+const UCHAR SiS310_TVAntiFlick1[3][2] =
+{
+ {0x4,0x0},
+ {0x4,0x8},
+ {0x0,0x0}
+};
+
+const UCHAR SiS310_TVEdge1[3][2] =
+{
+ {0x0,0x4},
+ {0x0,0x4},
+ {0x0,0x0}
+};
+
+const UCHAR SiS310_TVYFilter1[3][8][4] =
+{
+ {
+ {0x00,0xf4,0x10,0x38},
+ {0x00,0xf4,0x10,0x38},
+ {0xeb,0x04,0x25,0x18},
+ {0xf1,0x04,0x1f,0x18},
+ {0x00,0xf4,0x10,0x38},
+ {0xeb,0x04,0x25,0x18},
+ {0xee,0x0c,0x22,0x08},
+ {0xeb,0x15,0x25,0xf6}
+ },
+ {
+ {0x00,0xf4,0x10,0x38},
+ {0x00,0xf4,0x10,0x38},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf3,0x00,0x1d,0x20},
+ {0x00,0xf4,0x10,0x38},
+ {0xf1,0xf7,0x1f,0x32},
+ {0xf3,0x00,0x1d,0x20},
+ {0xfc,0xfb,0x14,0x2a}
+ },
+ {
+ {0x00,0x00,0x00,0x00},
+ {0x00,0xf4,0x10,0x38},
+ {0x00,0xf4,0x10,0x38},
+ {0xeb,0x04,0x25,0x18},
+ {0xf7,0x06,0x19,0x14},
+ {0x00,0xf4,0x10,0x38},
+ {0xeb,0x04,0x25,0x18},
+ {0xee,0x0c,0x22,0x08}
+ }
+};
+
+const UCHAR SiS310_TVYFilter2[3][9][7] =
+{
+ {
+ {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+ {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+ {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+ {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+ {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+ {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+ {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},
+ {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+ {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+ {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+ {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+ {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+ {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},
+ {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22},
+ {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22},
+ {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22},
+ {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22},
+ {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22},
+ {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22},
+ {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22}
+ }
+};
+
+const UCHAR SiS310_PALMFilter[16][4] =
+{
+ {0x00,0xf4,0x10,0x38},
+ {0x00,0xf4,0x10,0x38},
+ {0xeb,0x04,0x10,0x18},
+ {0xf7,0x06,0x19,0x14},
+ {0x00,0xf4,0x10,0x38},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x15,0x25,0xf6},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x04,0x25,0x18}
+};
+
+const UCHAR SiS310_PALNFilter[16][4] =
+{
+ {0x00,0xf4,0x10,0x38},
+ {0x00,0xf4,0x10,0x38},
+ {0xeb,0x04,0x10,0x18},
+ {0xf7,0x06,0x19,0x14},
+ {0x00,0xf4,0x10,0x38},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x15,0x25,0xf6},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x04,0x25,0x18},
+ {0xeb,0x04,0x25,0x18}
+};
+
+
+const UCHAR SiS310_PALMFilter2[9][7] =
+{
+ {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+ {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+ {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+ {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+ {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+ {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+ {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+ {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
+ {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
+};
+
+const UCHAR SiS310_PALNFilter2[9][7] =
+{
+ {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+ {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+ {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+ {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+ {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+ {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+ {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
+ {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
+ {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
+};
+
+const UCHAR SiS310_TVPhaseIncr1[3][2][4] =
+{
+ {
+ {0x21,0xed,0xba,0x08},
+ {0x21,0xed,0xba,0x08}
+ },
+ {
+ {0x2a,0x05,0xe3,0x00},
+ {0x2a,0x05,0xe3,0x00}
+ },
+ {
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00}
+ }
+};
+
+const UCHAR SiS310_TVPhaseIncr2[3][2][4] =
+{
+ {
+ {0x21,0xf0,0x7b,0xd6}, /* 1.10.7w; 1.10.6s: {0x1e,0x8b,0xda,0xa7}, old: {0x21,0xF1,0x37,0x56} */
+ {0x21,0xf0,0x7b,0xd6} /* 1.10.7w; 1.10.6s: {0x1e,0x8b,0xda,0xa7} old: {0x21,0xF1,0x37,0x56} */
+ },
+ {
+ {0x2a,0x0a,0x41,0xe9}, /* 1.10.7w, 1.10.6s. old: {0x2a,0x09,0x86,0xe9}, */
+ {0x2a,0x0a,0x41,0xe9} /* 1.10.7w, 1.10.6s. old: {0x2a,0x09,0x86,0xe9} */
+ },
+ {
+ {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00}
+ }
+};
+
+
+
diff --git a/src/osdef.h b/src/osdef.h
new file mode 100644
index 0000000..039d968
--- /dev/null
+++ b/src/osdef.h
@@ -0,0 +1,169 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/osdef.h,v 1.2 2003/02/10 01:14:16 tsi Exp $ */
+
+/* OS depending defines */
+
+/* The choices are: */
+/* #define WINCE_HEADER */ /* Incomplete! */
+/* #define WIN2000 */ /* Incomplete! */
+/* #define TC */ /* Incomplete! */
+/* #define LINUX_KERNEL */ /* Kernel framebuffer */
+#define LINUX_XF86 /* XFree86 */
+
+/**********************************************************************/
+#ifdef LINUX_KERNEL /* ----------------------------*/
+
+#include <linux/config.h>
+#ifdef CONFIG_FB_SIS_300
+#define SIS300
+#endif
+
+#ifdef CONFIG_FB_SIS_315
+#define SIS315H
+#endif
+
+#else /* if not LINUX_KERNEL --------------------- */
+/* #define SIS300*/
+#define SIS315H
+
+#endif /* if LINUX_KERNEL ------------------------ */
+
+#ifdef LINUX_XF86 /* Linux Xfree86 ---------------- */
+
+#define SIS300
+/* #define SIS315H */ /* TW: done above */
+#endif
+
+/**********************************************************************/
+#ifdef TC
+#endif
+#ifdef WIN2000
+#endif
+#ifdef WINCE_HEADER
+#endif
+#ifdef LINUX_XF86
+#endif
+#ifdef LINUX_KERNEL
+#endif
+/**********************************************************************/
+#ifdef TC
+#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize);
+#endif
+#ifdef WIN2000
+#define SiS_SetMemory(MemoryAddress,MemorySize,value) MemFill((PVOID) MemoryAddress,(ULONG) MemorySize,(UCHAR) value);
+#endif
+#ifdef WINCE_HEADER
+#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize);
+#endif
+#ifdef LINUX_XF86
+#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize)
+#endif
+#ifdef LINUX_KERNEL
+#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize)
+#endif
+/**********************************************************************/
+
+/**********************************************************************/
+
+#ifdef TC
+#define SiS_MemoryCopy(Destination,Soruce,Length) memmove(Destination, Soruce, Length);
+#endif
+#ifdef WIN2000
+#define SiS_MemoryCopy(Destination,Soruce,Length) /*VideoPortMoveMemory((PUCHAR)Destination , Soruce,length);*/
+#endif
+#ifdef WINCE_HEADER
+#define SiS_MemoryCopy(Destination,Soruce,Length) memmove(Destination, Soruce, Length);
+#endif
+#ifdef LINUX_XF86
+#define SiS_MemoryCopy(Destination,Soruce,Length) memcpy(Destination,Soruce,Length)
+#endif
+#ifdef LINUX_KERNEL
+#define SiS_MemoryCopy(Destination,Soruce,Length) memcpy(Destination,Soruce,Length)
+#endif
+
+/**********************************************************************/
+
+#ifdef OutPortByte
+#undef OutPortByte
+#endif /* OutPortByte */
+
+#ifdef OutPortWord
+#undef OutPortWord
+#endif /* OutPortWord */
+
+#ifdef OutPortLong
+#undef OutPortLong
+#endif /* OutPortLong */
+
+#ifdef InPortByte
+#undef InPortByte
+#endif /* InPortByte */
+
+#ifdef InPortWord
+#undef InPortWord
+#endif /* InPortWord */
+
+#ifdef InPortLong
+#undef InPortLong
+#endif /* InPortLong */
+
+/**********************************************************************/
+/* TC */
+/**********************************************************************/
+
+#ifdef TC
+#define OutPortByte(p,v) outp((unsigned short)(p),(unsigned char)(v))
+#define OutPortWord(p,v) outp((unsigned short)(p),(unsigned short)(v))
+#define OutPortLong(p,v) outp((unsigned short)(p),(unsigned long)(v))
+#define InPortByte(p) inp((unsigned short)(p))
+#define InPortWord(p) inp((unsigned short)(p))
+#define InPortLong(p) ((inp((unsigned short)(p+2))<<16) | inp((unsigned short)(p)))
+#endif
+
+/**********************************************************************/
+/* LINUX XF86 */
+/**********************************************************************/
+
+#ifdef LINUX_XF86
+#define OutPortByte(p,v) outb((CARD16)(p),(CARD8)(v))
+#define OutPortWord(p,v) outw((CARD16)(p),(CARD16)(v))
+#define OutPortLong(p,v) outl((CARD16)(p),(CARD32)(v))
+#define InPortByte(p) inb((CARD16)(p))
+#define InPortWord(p) inw((CARD16)(p))
+#define InPortLong(p) inl((CARD16)(p))
+#endif
+
+#ifdef LINUX_KERNEL
+#define OutPortByte(p,v) outb((u8)(v),(u16)(p))
+#define OutPortWord(p,v) outw((u16)(v),(u16)(p))
+#define OutPortLong(p,v) outl((u32)(v),(u16)(p))
+#define InPortByte(p) inb((u16)(p))
+#define InPortWord(p) inw((u16)(p))
+#define InPortLong(p) inl((u16)(p))
+#endif
+
+/**********************************************************************/
+/* WIN 2000 */
+/**********************************************************************/
+
+#ifdef WIN2000
+#define OutPortByte(p,v) VideoPortWritePortUchar ((PUCHAR) (p), (UCHAR) (v))
+#define OutPortWord(p,v) VideoPortWritePortUshort((PUSHORT) (p), (USHORT) (v))
+#define OutPortLong(p,v) VideoPortWritePortUlong ((PULONG) (p), (ULONG) (v))
+#define InPortByte(p) VideoPortReadPortUchar ((PUCHAR) (p))
+#define InPortWord(p) VideoPortReadPortUshort ((PUSHORT) (p))
+#define InPortLong(p) VideoPortReadPortUlong ((PULONG) (p))
+#endif
+
+
+/**********************************************************************/
+/* WIN CE */
+/**********************************************************************/
+
+#ifdef WINCE_HEADER
+#define OutPortByte(p,v) WRITE_PORT_UCHAR ((PUCHAR) (p), (UCHAR) (v))
+#define OutPortWord(p,v) WRITE_PORT_USHORT((PUSHORT) (p), (USHORT) (v))
+#define OutPortLong(p,v) WRITE_PORT_ULONG ((PULONG) (p), (ULONG) (v))
+#define InPortByte(p) READ_PORT_UCHAR ((PUCHAR) (p))
+#define InPortWord(p) READ_PORT_USHORT ((PUSHORT) (p))
+#define InPortLong(p) READ_PORT_ULONG ((PULONG) (p))
+#endif
diff --git a/src/sis.h b/src/sis.h
new file mode 100644
index 0000000..7278674
--- /dev/null
+++ b/src/sis.h
@@ -0,0 +1,710 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis.h,v 1.29 2003/01/29 15:42:16 eich Exp $ */
+/*
+ * Copyright 1998,1999 by Alan Hourihane, Wigan, England.
+ * Parts Copyright 2001, 2002 by Thomas Winischhofer, Vienna, Austria
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the copyright holder not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The copyright holder makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, alanh@fairlite.demon.co.uk
+ * Mike Chapman <mike@paranoia.com>,
+ * Juanjo Santamarta <santamarta@ctv.es>,
+ * Mitani Hiroshi <hmitani@drl.mei.co.jp>
+ * David Thomas <davtom@dream.org.uk>.
+ *
+ * Thomas Winischhofer <thomas@winischhofer.net>:
+ * - 310/325 series (315/550/650/651/740/M650) support
+ * - (possibly incomplete) Xabre (SiS330) support
+ * - new mode switching code for 300, 310/325 and 330 series
+ * - many fixes for 300/540/630/730 chipsets,
+ * - many fixes for 5597/5598, 6326 and 530/620 chipsets,
+ * - VESA mode switching (deprecated),
+ * - extended CRT2/video bridge handling support,
+ * - dual head support on 300, 310/325 and 330 series
+ * - 650/LVDS (up to 1400x1050), 650/Chrontel 701x support
+ * - 30xB/30xLV/30xLVX video bridge support (300, 310/325, 330 series)
+ * - Xv support for 5597/5598, 6326, 530/620 and 310/325 series
+ * - video overlay enhancements for 300 series
+ * - TV and hi-res support for the 6326
+ * - Color hardware cursor support for 300/310/325/330 series
+ * - etc.
+ */
+
+
+#ifndef _SIS_H
+#define _SIS_H_
+
+/* Always unlock the registers (should be set!) */
+#define UNLOCK_ALWAYS
+
+#if 0
+#define TWDEBUG /* for debugging */
+#endif
+
+#include "xf86Pci.h"
+#include "xf86Cursor.h"
+#include "xf86_ansic.h"
+#include "xf86xv.h"
+#include "compiler.h"
+#include "xaa.h"
+#include "vgaHW.h"
+#include "vbe.h"
+#include "osdef.h"
+#include "vgatypes.h"
+#include "vstruct.h"
+
+#ifdef XF86DRI
+#include "xf86drm.h"
+#include "sarea.h"
+#define _XF86DRI_SERVER_
+#include "xf86dri.h"
+#include "dri.h"
+#include "GL/glxint.h"
+#include "sis_dri.h"
+#endif
+
+#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,0,0,0)
+typedef unsigned long IOADDRESS;
+#endif
+
+#if 1
+#define SISDUALHEAD /* TW: Include Dual Head code */
+#endif
+
+#if 1
+#define USE6326VIDEO /* TW: Include 6326/530/620 Xv code */
+#endif
+
+#if 1 /* TW: Include code for 330 - highly preliminary */
+#define INCL_SIS330
+#endif
+
+#if 1 /* TW: Include code for cycling CRT2 type via keyboard */
+#define CYCLECRT2 /* (not functional yet) */
+#endif
+
+#if 1
+#define SISGAMMA /* TW: Include code for gamma correction */
+#endif
+
+#if 1 /* TW: Include code for color hardware cursors */
+#define SIS_ARGB_CURSOR
+#endif
+
+/* TW: new for SiS315/550/650/740/330 - these should be moved elsewhere! */
+#ifndef PCI_CHIP_SIS315H
+#define PCI_CHIP_SIS315H 0x0310
+#endif
+#ifndef PCI_CHIP_SIS315
+#define PCI_CHIP_SIS315 0x0315
+#endif
+#ifndef PCI_CHIP_SIS315PRO
+#define PCI_CHIP_SIS315PRO 0x0325
+#endif
+#ifndef PCI_CHIP_SIS550
+#define PCI_CHIP_SIS550 0x5315 /* This is 550_VGA */
+#endif
+#ifndef PCI_CHIP_SIS650
+#define PCI_CHIP_SIS650 0x6325 /* This is 650_VGA and 740_VGA */
+#endif
+#ifndef PCI_CHIP_SIS330
+#define PCI_CHIP_SIS330 0x0330
+#endif
+
+#define SIS_NAME "SIS"
+#define SIS_DRIVER_NAME "sis"
+#define SIS_MAJOR_VERSION 0
+#define SIS_MINOR_VERSION 6
+#define SIS_PATCHLEVEL 0
+#define SIS_CURRENT_VERSION ((SIS_MAJOR_VERSION << 16) | \
+ (SIS_MINOR_VERSION << 8) | SIS_PATCHLEVEL )
+
+/* pSiS->Flags (old series only) */
+#define SYNCDRAM 0x00000001
+#define RAMFLAG 0x00000002
+#define ESS137xPRESENT 0x00000004
+#define SECRETFLAG 0x00000008
+#define A6326REVAB 0x00000010
+#define MMIOMODE 0x00010000
+#define LFBQMODE 0x00020000
+#define AGPQMODE 0x00040000
+#define UMA 0x80000000
+
+#define BIOS_BASE 0xC0000
+#define BIOS_SIZE 0x10000
+
+/* TW: New mode switching code */
+#define SR_BUFFER_SIZE 5
+#define CR_BUFFER_SIZE 5
+
+/* TW: VBFlags */
+#define CRT2_DEFAULT 0x00000001
+#define CRT2_LCD 0x00000002 /* TW: Never change the order of the CRT2_XXX entries */
+#define CRT2_TV 0x00000004 /* (see SISCycleCRT2Type()) */
+#define CRT2_VGA 0x00000008
+#define CRT2_ENABLE (CRT2_LCD | CRT2_TV | CRT2_VGA)
+#define DISPTYPE_DISP2 CRT2_ENABLE
+#define TV_NTSC 0x00000010
+#define TV_PAL 0x00000020
+#define TV_HIVISION 0x00000040
+#define TV_TYPE (TV_NTSC | TV_PAL | TV_HIVISION)
+#define TV_AVIDEO 0x00000100
+#define TV_SVIDEO 0x00000200
+#define TV_SCART 0x00000400
+#define TV_INTERFACE (TV_AVIDEO | TV_SVIDEO | TV_SCART | TV_CHSCART | TV_CHHDTV)
+#define TV_PALM 0x00001000
+#define TV_PALN 0x00002000
+#define TV_CHSCART 0x00008000
+#define TV_CHHDTV 0x00010000
+#define VGA2_CONNECTED 0x00040000
+#define DISPTYPE_CRT1 0x00080000 /* TW: CRT1 connected and used */
+#define DISPTYPE_DISP1 DISPTYPE_CRT1
+#define VB_301 0x00100000 /* Video bridge type */
+#define VB_301B 0x00200000
+#define VB_302B 0x00400000
+#define VB_303 0x00800000
+#define VB_LVDS 0x01000000
+#define VB_CHRONTEL 0x02000000
+#define VB_30xLV 0x04000000
+#define VB_30xLVX 0x08000000
+#define VB_TRUMPION 0x10000000
+#define VB_VIDEOBRIDGE (VB_301|VB_301B|VB_302B|VB_303|VB_30xLV|VB_30xLVX| \
+ VB_LVDS|VB_CHRONTEL|VB_TRUMPION) /* TW */
+#define VB_SISBRIDGE (VB_301|VB_301B|VB_302B|VB_303|VB_30xLV|VB_30xLVX)
+#define SINGLE_MODE 0x20000000 /* TW: CRT1 or CRT2; determined by DISPTYPE_CRTx */
+#define VB_DISPMODE_SINGLE SINGLE_MODE /* TW: alias */
+#define MIRROR_MODE 0x40000000 /* TW: CRT1 + CRT2 identical (mirror mode) */
+#define VB_DISPMODE_MIRROR MIRROR_MODE /* TW: alias */
+#define DUALVIEW_MODE 0x80000000 /* TW: CRT1 + CRT2 independent (dual head mode) */
+#define VB_DISPMODE_DUAL DUALVIEW_MODE /* TW: alias */
+#define DISPLAY_MODE (SINGLE_MODE | MIRROR_MODE | DUALVIEW_MODE) /* TW */
+
+/* TW: pSiS->VBLCDFlags */
+#define VB_LCD_320x480 0x00000001 /* TW: DSTN/FSTN for 550 */
+#define VB_LCD_640x480 0x00000002
+#define VB_LCD_800x600 0x00000004
+#define VB_LCD_1024x768 0x00000008
+#define VB_LCD_1280x1024 0x00000010
+#define VB_LCD_1280x960 0x00000020
+#define VB_LCD_1600x1200 0x00000040
+#define VB_LCD_2048x1536 0x00000080
+#define VB_LCD_1400x1050 0x00000100
+#define VB_LCD_1152x864 0x00000200
+#define VB_LCD_1152x768 0x00000400
+#define VB_LCD_1280x768 0x00000800
+#define VB_LCD_1024x600 0x00001000
+
+/* TW: More or less useful macros (although we often use pSiS->VGAEngine instead) */
+#define SIS_IS_300_CHIPSET (pSiS->Chipset == PCI_CHIP_SIS300) || \
+ (pSiS->Chipset == PCI_CHIP_SIS630) || \
+ (pSiS->Chipset == PCI_CHIP_SIS540) || \
+ (pSiS->Chipset == PCI_CHIP_SIS730)
+
+/* This preliminaryly also contains SIS330 */
+#define SIS_IS_315_CHIPSET (pSiS->Chipset == PCI_CHIP_SIS315) || \
+ (pSiS->Chipset == PCI_CHIP_SIS315H) || \
+ (pSiS->Chipset == PCI_CHIP_SIS315PRO) || \
+ (pSiS->Chipset == PCI_CHIP_SIS550) || \
+ (pSiS->Chipset == PCI_CHIP_SIS650) || \
+ (pSiS->Chipset == PCI_CHIP_SIS330)
+
+/* SiS6326Flags */
+#define SIS6326_HASTV 0x00000001
+#define SIS6326_TVSVIDEO 0x00000002
+#define SIS6326_TVCVBS 0x00000004
+#define SIS6326_TVPAL 0x00000008
+#define SIS6326_TVDETECTED 0x00000010
+#define SIS6326_TVON 0x80000000
+
+#define HW_DEVICE_EXTENSION SIS_HW_DEVICE_INFO
+
+#ifdef DEBUG
+#define PDEBUG(p) p
+#else
+#define PDEBUG(p)
+#endif
+
+typedef unsigned long ULong;
+typedef unsigned short UShort;
+typedef unsigned char UChar;
+
+/* TW: VGA engine types */
+#define UNKNOWN_VGA 0
+#define SIS_530_VGA 1
+#define SIS_OLD_VGA 2
+#define SIS_300_VGA 3
+#define SIS_315_VGA 4
+
+/* TW: oldChipset */
+#define OC_UNKNOWN 0
+#define OC_SIS6205A 3
+#define OC_SIS6205B 4
+#define OC_SIS82204 5
+#define OC_SIS6205C 6
+#define OC_SIS6225 7
+#define OC_SIS5597 8
+#define OC_SIS6326 9
+#define OC_SIS530A 11
+#define OC_SIS530B 12
+
+/* TW: Chrontel type */
+#define CHRONTEL_700x 0
+#define CHRONTEL_701x 1
+
+/* Flags650 */
+#define SiS650_LARGEOVERLAY 0x00000001
+
+/* TW: For backup of register contents */
+typedef struct {
+ unsigned char sisRegs3C4[0x50];
+ unsigned char sisRegs3D4[0x90];
+ unsigned char sisRegs3C2;
+ unsigned char VBPart1[0x50];
+ unsigned char VBPart2[0x50];
+ unsigned char VBPart3[0x50];
+ unsigned char VBPart4[0x50];
+ unsigned short ch70xx[64];
+ unsigned long sisMMIO85C0; /* TW: Queue location for 310/325 series */
+ unsigned char sis6326tv[0x46];
+ unsigned long sisRegsPCI50, sisRegsPCIA0;
+} SISRegRec, *SISRegPtr;
+
+typedef struct _sisModeInfoPtr {
+ int width;
+ int height;
+ int bpp;
+ int n;
+ struct _sisModeInfoPtr *next;
+} sisModeInfoRec, *sisModeInfoPtr;
+
+/* TW: SISFBLayout is mainly there because of DGA. It holds the
+ current layout parameters needed for acceleration and other
+ stuff. When switching mode using DGA, these are set up
+ accordingly and not necessarily match pScrn's. Therefore,
+ driver modules should read these values instead of pScrn's.
+ */
+typedef struct {
+ int bitsPerPixel; /* TW: Copy from pScrn->bitsPerPixel */
+ int depth; /* TW: Copy from pScrn->depth */
+ int displayWidth; /* TW: Copy from pScrn->displayWidth */
+ DisplayModePtr mode; /* TW: Copy from pScrn->currentMode */
+} SISFBLayout;
+
+/* TW: Dual head private entity structure */
+#ifdef SISDUALHEAD
+typedef struct {
+ ScrnInfoPtr pScrn_1;
+ ScrnInfoPtr pScrn_2;
+ unsigned char * BIOS;
+ SiS_Private * SiS_Pr; /* TW: For new mode switching code */
+ int CRT1ModeNo; /* Current display mode for CRT1 */
+ DisplayModePtr CRT1DMode; /* Current display mode for CRT1 */
+ int CRT2ModeNo; /* Current display mode for CRT2 */
+ DisplayModePtr CRT2DMode; /* Current display mode for CRT2 */
+ int refCount;
+ int lastInstance; /* number of entities */
+ Bool DisableDual; /* Emergency flag */
+ Bool ErrorAfterFirst; /* Emergency flag: Error after first init -> Abort second */
+ Bool HWCursor; /* Backup master settings for use on slave */
+ Bool TurboQueue;
+ int ForceCRT2Type;
+ int OptTVStand;
+ int OptTVOver;
+ int OptTVSOver;
+ int OptROMUsage;
+ int PDC;
+ Bool NoAccel;
+ Bool NoXvideo;
+ int forceCRT1;
+ int DSTN;
+ Bool XvOnCRT2;
+ int maxUsedClock; /* Max used pixelclock on master head */
+ unsigned long masterFbAddress; /* Framebuffer addresses and sizes */
+ unsigned long masterFbSize;
+ unsigned long slaveFbAddress;
+ unsigned long slaveFbSize;
+ unsigned char * FbBase; /* VRAM linear address */
+ unsigned char * IOBase; /* MMIO linear address */
+ unsigned short MapCountIOBase; /* map/unmap queue counter */
+ unsigned short MapCountFbBase; /* map/unmap queue counter */
+ Bool forceUnmapIOBase; /* ignore counter and unmap */
+ Bool forceUnmapFbBase; /* ignore counter and unmap */
+#ifdef __alpha__
+ unsigned char * IOBaseDense; /* MMIO for Alpha platform */
+ unsigned short MapCountIOBaseDense;
+ Bool forceUnmapIOBaseDense; /* ignore counter and unmap */
+#endif
+ int chtvlumabandwidthcvbs; /* TW: TV settings for Chrontel TV encoder */
+ int chtvlumabandwidthsvideo;
+ int chtvlumaflickerfilter;
+ int chtvchromabandwidth;
+ int chtvchromaflickerfilter;
+ int chtvcvbscolor;
+ int chtvtextenhance;
+ int chtvcontrast;
+ int sistvedgeenhance; /* TW: TV settings for SiS bridge */
+ int sistvantiflicker;
+ int sistvsaturation;
+ int tvxpos;
+ int tvypos;
+ int ForceTVType;
+ int chtvtype;
+ int NonDefaultPAL;
+ unsigned short tvx, tvy;
+ unsigned char p2_01, p2_02, p2_2d;
+ unsigned short cursorBufferNum;
+ BOOLEAN restorebyset;
+} SISEntRec, *SISEntPtr;
+#endif
+
+#define SISPTR(p) ((SISPtr)((p)->driverPrivate))
+#define XAAPTR(p) ((XAAInfoRecPtr)(SISPTR(p)->AccelInfoPtr))
+
+typedef struct {
+ ScrnInfoPtr pScrn; /* -------------- DON'T INSERT ANYTHING HERE --------------- */
+ pciVideoPtr PciInfo; /* -------- OTHERWISE sis_dri.so MUST BE RECOMPILED -------- */
+ PCITAG PciTag;
+ EntityInfoPtr pEnt;
+ int Chipset;
+ int ChipRev;
+ int VGAEngine; /* TW: see above */
+ int hasTwoOverlays; /* TW: Chipset supports two video overlays? */
+ HW_DEVICE_EXTENSION sishw_ext; /* TW: For new mode switching code */
+ SiS_Private * SiS_Pr; /* TW: For new mode switching code */
+ int DSTN; /* TW: For 550 FSTN/DSTN; set by option, no detection */
+ unsigned long FbAddress; /* VRAM physical address (in DHM: for each Fb!) */
+ unsigned long realFbAddress; /* For DHM/PCI mem mapping: store global FBAddress */
+ unsigned char * FbBase; /* VRAM virtual linear address */
+ CARD32 IOAddress; /* MMIO physical address */
+ unsigned char * IOBase; /* MMIO linear address */
+ IOADDRESS IODBase; /* Base of PIO memory area */
+#ifdef __alpha__
+ unsigned char * IOBaseDense; /* MMIO for Alpha platform */
+#endif
+ CARD16 RelIO; /* Relocated IO Ports baseaddress */
+ unsigned char * BIOS;
+ int MemClock;
+ int BusWidth;
+ int MinClock;
+ int MaxClock;
+ int Flags; /* HW config flags */
+ long FbMapSize; /* Used for Mem Mapping - DON'T CHANGE THIS */
+ long availMem; /* Really available Fb mem (minus TQ, HWCursor) */
+ unsigned long maxxfbmem; /* limit fb memory X is to use to this (KB) */
+ unsigned long sisfbMem; /* heapstart of sisfb (if running) */
+#ifdef SISDUALHEAD
+ unsigned long dhmOffset; /* Offset to memory for each head (0 or ..) */
+#endif
+ DGAModePtr DGAModes;
+ int numDGAModes;
+ Bool DGAactive;
+ int DGAViewportStatus;
+ int OldMode; /* TW: Back old modeNo (if available) */
+ Bool NoAccel;
+ Bool NoXvideo;
+ Bool XvOnCRT2; /* TW: see sis_opt.c */
+ Bool HWCursor;
+ Bool UsePCIRetry;
+ Bool TurboQueue;
+ int VESA;
+ int ForceCRT2Type;
+ int OptTVStand;
+ int OptTVOver;
+ int OptROMUsage;
+ int UseCHOverScan;
+ Bool ValidWidth;
+ Bool FastVram; /* TW: now unused */
+ int forceCRT1;
+ Bool CRT1changed;
+ unsigned char oldCR17;
+ unsigned char oldCR32;
+ unsigned char newCR32;
+ int VBFlags; /* TW: Video bridge configuration */
+ int VBFlags_backup; /* TW: Backup for SlaveMode-modes */
+ int VBLCDFlags; /* TW: Moved LCD panel size bits here */
+ int ChrontelType; /* TW: CHRONTEL_700x or CHRONTEL_701x */
+ int PDC; /* TW: PanelDelayCompensation */
+ short scrnOffset; /* TW: Screen pitch (data) */
+ short scrnPitch; /* TW: Screen pitch (display; regarding interlace) */
+ short DstColor;
+ int xcurrent; /* for temp use in accel */
+ int ycurrent; /* for temp use in accel */
+ long SiS310_AccelDepth; /* used in accel for 310/325 series */
+ int Xdirection; /* for temp use in accel */
+ int Ydirection; /* for temp use in accel */
+ int sisPatternReg[4];
+ int ROPReg;
+ int CommandReg;
+ int MaxCMDQueueLen;
+ int CurCMDQueueLen;
+ int MinCMDQueueLen;
+ CARD16 CursorSize; /* TW: Size of HWCursor area (bytes) */
+ CARD32 cursorOffset; /* TW: see sis_driver.c and sis_cursor.c */
+ int DstX;
+ int DstY;
+ unsigned char * XAAScanlineColorExpandBuffers[2];
+ CARD32 AccelFlags;
+ Bool ClipEnabled;
+ Bool DoColorExpand;
+ SISRegRec SavedReg;
+ SISRegRec ModeReg;
+ xf86CursorInfoPtr CursorInfoPtr;
+ XAAInfoRecPtr AccelInfoPtr;
+ CloseScreenProcPtr CloseScreen;
+ unsigned int (*ddc1Read)(ScrnInfoPtr);
+ Bool (*ModeInit)(ScrnInfoPtr pScrn, DisplayModePtr mode);
+ void (*SiSSave)(ScrnInfoPtr pScrn, SISRegPtr sisreg);
+ void (*SiSSave2)(ScrnInfoPtr pScrn, SISRegPtr sisreg);
+ void (*SiSSave3)(ScrnInfoPtr pScrn, SISRegPtr sisreg);
+ void (*SiSSaveLVDSChrontel)(ScrnInfoPtr pScrn, SISRegPtr sisreg);
+ void (*SiSRestore)(ScrnInfoPtr pScrn, SISRegPtr sisreg);
+ void (*SiSRestore2)(ScrnInfoPtr pScrn, SISRegPtr sisreg);
+ void (*SiSRestore3)(ScrnInfoPtr pScrn, SISRegPtr sisreg);
+ void (*SiSRestoreLVDSChrontel)(ScrnInfoPtr pScrn, SISRegPtr sisreg);
+ void (*SetThreshold)(ScrnInfoPtr pScrn, DisplayModePtr mode,
+ unsigned short *Low, unsigned short *High);
+ void (*LoadCRT2Palette)(ScrnInfoPtr pScrn, int numColors,
+ int *indicies, LOCO *colors, VisualPtr pVisual);
+
+ int cmdQueueLen; /* TW: Current cmdQueueLength (for 2D and 3D) */
+ int *cmdQueueLenPtr;
+ unsigned long agpHandle;
+ CARD32 agpAddr;
+ unsigned char *agpBase;
+ unsigned int agpSize;
+ CARD32 agpCmdBufAddr;
+ unsigned char *agpCmdBufBase;
+ unsigned int agpCmdBufSize;
+ unsigned int agpCmdBufFree;
+ Bool irqEnabled;
+ int irq;
+
+ int ColorExpandRingHead;
+ int ColorExpandRingTail;
+ int PerColorExpandBufferSize;
+ int ColorExpandBufferNumber;
+ int ColorExpandBufferCountMask;
+ unsigned char *ColorExpandBufferAddr[32];
+ int ColorExpandBufferScreenOffset[32];
+ int ImageWriteBufferSize;
+ unsigned char *ImageWriteBufferAddr;
+
+ int Rotate;
+ void (*PointerMoved)(int index, int x, int y);
+
+ /* ShadowFB support */
+ Bool ShadowFB;
+ unsigned char *ShadowPtr;
+ int ShadowPitch;
+
+#ifdef XF86DRI
+ Bool directRenderingEnabled;
+ DRIInfoPtr pDRIInfo;
+ int drmSubFD;
+ int numVisualConfigs;
+ __GLXvisualConfig* pVisualConfigs;
+ SISConfigPrivPtr pVisualConfigsPriv;
+ SISRegRec DRContextRegs;
+#endif
+
+ XF86VideoAdaptorPtr adaptor;
+ ScreenBlockHandlerProcPtr BlockHandler;
+ void (*VideoTimerCallback)(ScrnInfoPtr, Time);
+
+ OptionInfoPtr Options;
+ unsigned char LCDon;
+#ifdef SISDUALHEAD
+ Bool BlankCRT1, BlankCRT2;
+#endif
+ Bool Blank;
+ unsigned char BIOSModeSave;
+ int CRT1off; /* TW: 1=CRT1 off, 0=CRT1 on */
+ CARD16 LCDheight; /* TW: Vertical resolution of LCD panel */
+ CARD16 LCDwidth; /* TW: Horizontal resolution of LCD panel */
+ vbeInfoPtr pVbe; /* TW: For VESA mode switching */
+ CARD16 vesamajor;
+ CARD16 vesaminor;
+ VbeInfoBlock *vbeInfo;
+ int UseVESA;
+ sisModeInfoPtr SISVESAModeList;
+ xf86MonPtr monitor;
+ CARD16 maxBytesPerScanline;
+ CARD32 *pal, *savedPal;
+ int mapPhys, mapOff, mapSize;
+ int statePage, stateSize, stateMode;
+ CARD8 *fonts;
+ CARD8 *state, *pstate;
+ void *base, *VGAbase;
+#ifdef SISDUALHEAD
+ BOOL DualHeadMode; /* TW: TRUE if we use dual head mode */
+ BOOL SecondHead; /* TW: TRUE is this is the second head */
+ SISEntPtr entityPrivate; /* TW: Ptr to private entity (see above) */
+ BOOL SiSXinerama; /* TW: Do we use Xinerama mode? */
+#endif
+ SISFBLayout CurrentLayout; /* TW: Current framebuffer layout */
+ Bool (*i2cInit)(ScrnInfoPtr);/* I2C stuff */
+ I2CBusPtr I2C;
+ USHORT SiS_DDC2_Index;
+ USHORT SiS_DDC2_Data;
+ USHORT SiS_DDC2_Clk;
+ BOOL Primary; /* TW: Display adapter is primary */
+ xf86Int10InfoPtr pInt; /* TW: Our int10 */
+ int oldChipset; /* TW: Type of old chipset */
+ CARD32 RealVideoRam; /* TW: 6326 can only address 4MB, but TQ can be above */
+ CARD32 CmdQueLenMask; /* TW: Mask of queue length in MMIO register */
+ CARD32 CmdQueLenFix; /* TW: Fix value to subtract from QueLen (530/620) */
+ CARD32 CmdQueMaxLen; /* TW: (6326/5597/5598) Amount of cmds the queue can hold */
+ CARD32 TurboQueueLen; /* TW: For future use */
+ CARD32 detectedCRT2Devices; /* TW: detected CRT2 devices before mask-out */
+ Bool NoHostBus; /* TW: Enable/disable 5597/5598 host bus */
+ Bool noInternalModes; /* TW: Use our own default modes? */
+ char * sbiosn; /* TW: For debug */
+ int OptUseOEM; /* TW: Use internal OEM data? */
+ int chtvlumabandwidthcvbs; /* TW: TV settings for Chrontel TV encoder */
+ int chtvlumabandwidthsvideo;
+ int chtvlumaflickerfilter;
+ int chtvchromabandwidth;
+ int chtvchromaflickerfilter;
+ int chtvcvbscolor;
+ int chtvtextenhance;
+ int chtvcontrast;
+ int sistvedgeenhance; /* TW: TV settings for SiS bridges */
+ int sistvantiflicker;
+ int sistvsaturation;
+ int OptTVSOver; /* TW: Chrontel 7005: Superoverscan */
+ int tvxpos;
+ int tvypos;
+ int SiS6326Flags; /* TW: SiS6326 TV settings */
+ int sis6326antiflicker;
+ int sis6326enableyfilter;
+ int sis6326yfilterstrong;
+ BOOL donttrustpdc; /* TW: Don't trust the detected PDC */
+ unsigned char sisfbpdc;
+ int NoYV12; /* TW: Disable Xv YV12 support (old series) */
+ unsigned char postVBCR32;
+ int newFastVram; /* TW: Replaces FastVram */
+ int ForceTVType;
+ int NonDefaultPAL;
+ unsigned long lockcalls; /* TW: Count unlock calls for debug */
+ unsigned short tvx, tvy; /* TW: Backup TV position registers */
+ unsigned char p2_01, p2_02, p2_2d; /* TW: Backup TV position registers */
+ unsigned short tvx1, tvx2, tvx3, tvy1; /* TW: Backup TV position registers */
+ BOOLEAN ForceCursorOff;
+ BOOLEAN HaveCustomModes;
+ BOOLEAN IsCustom;
+ DisplayModePtr backupmodelist;
+ int chtvtype;
+ Atom xvBrightness, xvContrast, xvColorKey, xvHue, xvSaturation;
+ Atom xvAutopaintColorKey, xvSetDefaults;
+ unsigned long Flags650;
+ BOOLEAN UseHWARGBCursor;
+ int OptUseColorCursor;
+ int OptUseColorCursorBlend;
+ CARD32 OptColorCursorBlendThreshold;
+ unsigned short cursorBufferNum;
+ BOOLEAN restorebyset;
+} SISRec, *SISPtr;
+
+typedef struct _ModeInfoData {
+ int mode;
+ VbeModeInfoBlock *data;
+ VbeCRTCInfoBlock *block;
+} ModeInfoData;
+
+typedef struct _myhddctiming {
+ int whichone;
+ unsigned char mask;
+ float rate;
+} myhddctiming;
+
+typedef struct _myvddctiming {
+ int whichone;
+ unsigned char mask;
+ int rate;
+} myvddctiming;
+
+typedef struct _myddcstdmodes {
+ int hsize;
+ int vsize;
+ int refresh;
+ float hsync;
+} myddcstdmodes;
+
+typedef struct _pdctable {
+ int subsysVendor;
+ int subsysCard;
+ int pdc;
+ char *vendorName;
+ char *cardName;
+} pdctable;
+
+typedef struct _chswtable {
+ int subsysVendor;
+ int subsysCard;
+ char *vendorName;
+ char *cardName;
+} chswtable;
+
+extern void sisSaveUnlockExtRegisterLock(SISPtr pSiS, unsigned char *reg1, unsigned char *reg2);
+extern void sisRestoreExtRegisterLock(SISPtr pSiS, unsigned char reg1, unsigned char reg2);
+extern void SiSOptions(ScrnInfoPtr pScrn);
+extern const OptionInfoRec * SISAvailableOptions(int chipid, int busid);
+extern void SiSSetup(ScrnInfoPtr pScrn);
+extern void SISVGAPreInit(ScrnInfoPtr pScrn);
+extern Bool SiSAccelInit(ScreenPtr pScreen);
+extern Bool SiS300AccelInit(ScreenPtr pScreen);
+extern Bool SiS310AccelInit(ScreenPtr pScreen);
+extern Bool SiS530AccelInit(ScreenPtr pScreen);
+extern Bool SiSHWCursorInit(ScreenPtr pScreen);
+extern Bool SISDGAInit(ScreenPtr pScreen);
+extern void SISInitVideo(ScreenPtr pScreen);
+extern void SIS6326InitVideo(ScreenPtr pScreen);
+
+extern void SiS_SetCHTVlumabandwidthcvbs(ScrnInfoPtr pScrn, int val);
+extern void SiS_SetCHTVlumabandwidthsvideo(ScrnInfoPtr pScrn, int val);
+extern void SiS_SetCHTVlumaflickerfilter(ScrnInfoPtr pScrn, int val);
+extern void SiS_SetCHTVchromabandwidth(ScrnInfoPtr pScrn, int val);
+extern void SiS_SetCHTVchromaflickerfilter(ScrnInfoPtr pScrn, int val);
+extern void SiS_SetCHTVcvbscolor(ScrnInfoPtr pScrn, int val);
+extern void SiS_SetCHTVtextenhance(ScrnInfoPtr pScrn, int val);
+extern void SiS_SetCHTVcontrast(ScrnInfoPtr pScrn, int val);
+extern void SiS_SetSISTVedgeenhance(ScrnInfoPtr pScrn, int val);
+extern void SiS_SetSISTVantiflicker(ScrnInfoPtr pScrn, int val);
+extern void SiS_SetSISTVsaturation(ScrnInfoPtr pScrn, int val);
+extern void SiS_SetSIS6326TVantiflicker(ScrnInfoPtr pScrn, int val);
+extern void SiS_SetSIS6326TVenableyfilter(ScrnInfoPtr pScrn, int val);
+extern void SiS_SetSIS6326TVyfilterstrong(ScrnInfoPtr pScrn, int val);
+extern void SiS_SetTVxposoffset(ScrnInfoPtr pScrn, int val);
+extern void SiS_SetTVyposoffset(ScrnInfoPtr pScrn, int val);
+extern int SiS_GetCHTVlumabandwidthcvbs(ScrnInfoPtr pScrn);
+extern int SiS_GetCHTVlumabandwidthsvideo(ScrnInfoPtr pScrn);
+extern int SiS_GetCHTVlumaflickerfilter(ScrnInfoPtr pScrn);
+extern int SiS_GetCHTVchromabandwidth(ScrnInfoPtr pScrn);
+extern int SiS_GetCHTVchromaflickerfilter(ScrnInfoPtr pScrn);
+extern int SiS_GetCHTVcvbscolor(ScrnInfoPtr pScrn);
+extern int SiS_GetCHTVtextenhance(ScrnInfoPtr pScrn);
+extern int SiS_GetCHTVcontrast(ScrnInfoPtr pScrn);
+extern int SiS_GetSISTVedgeenhance(ScrnInfoPtr pScrn);
+extern int SiS_GetSISTVantiflicker(ScrnInfoPtr pScrn);
+extern int SiS_GetSISTVsaturation(ScrnInfoPtr pScrn);
+extern int SiS_GetSIS6326TVantiflicker(ScrnInfoPtr pScrn);
+extern int SiS_GetSIS6326TVenableyfilter(ScrnInfoPtr pScrn);
+extern int SiS_GetSIS6326TVyfilterstrong(ScrnInfoPtr pScrn);
+extern int SiS_GetTVxposoffset(ScrnInfoPtr pScrn);
+extern int SiS_GetTVyposoffset(ScrnInfoPtr pScrn);
+#endif
diff --git a/src/sis300_accel.c b/src/sis300_accel.c
new file mode 100644
index 0000000..8db9d49
--- /dev/null
+++ b/src/sis300_accel.c
@@ -0,0 +1,1397 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis300_accel.c,v 1.14 2003/01/29 15:42:16 eich Exp $ */
+/*
+ * 2D Acceleration for SiS300, SiS540, SiS630, SiS730, SiS530, SiS620
+ *
+ * Copyright Xavier Ducoin <x.ducoin@lectra.com>
+ * Copyright 2002 by Thomas Winischhofer, Vienna, Austria
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the copyright holders not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors:
+ *
+ * Xavier Ducoin <x.ducoin@lectra.com>
+ * Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ */
+#if 0
+#define DEBUG
+#endif
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+#include "compiler.h"
+#include "xaa.h"
+
+#include "sis.h"
+#include "sis300_accel.h"
+
+#ifdef SISDUALHEAD
+/* TW: This is the offset to the memory for each head */
+#define HEADOFFSET (pSiS->dhmOffset)
+#endif
+
+#undef STSCE /* TW: Use/Don't use ScreenToScreenColorExpand - does not work */
+
+#undef TRAP /* TW: Use/Don't use Trapezoid Fills - does not work - XAA provides
+ * illegal trapezoid data (left and right edges cross each other
+ * sometimes) which causes drawing errors. Further, I have not found
+ * out how to draw polygones with a height greater than 127...
+ */
+
+static void SiSInitializeAccelerator(ScrnInfoPtr pScrn);
+static void SiSSync(ScrnInfoPtr pScrn);
+static void SiSSetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int xdir, int ydir, int rop,
+ unsigned int planemask, int trans_color);
+static void SiSSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int x1, int y1, int x2, int y2,
+ int width, int height);
+static void SiSSetupForSolidFill(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask);
+static void SiSSubsequentSolidFillRect(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h);
+#ifdef TRAP
+static void SiSSubsequentSolidFillTrap(ScrnInfoPtr pScrn, int y, int h,
+ int left, int dxL, int dyL, int eL,
+ int right, int dxR, int dyR, int eR);
+#endif
+static void SiSSetupForSolidLine(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask);
+static void SiSSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, int x1,
+ int y1, int x2, int y2, int flags);
+static void SiSSubsequentSolidHorzVertLine(ScrnInfoPtr pScrn,
+ int x, int y, int len, int dir);
+static void SiSSetupForDashedLine(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop, unsigned int planemask,
+ int length, unsigned char *pattern);
+static void SiSSubsequentDashedTwoPointLine(ScrnInfoPtr pScrn,
+ int x1, int y1, int x2, int y2,
+ int flags, int phase);
+static void SiSSetupForMonoPatternFill(ScrnInfoPtr pScrn,
+ int patx, int paty, int fg, int bg,
+ int rop, unsigned int planemask);
+static void SiSSubsequentMonoPatternFill(ScrnInfoPtr pScrn,
+ int patx, int paty,
+ int x, int y, int w, int h);
+#ifdef TRAP
+static void SiSSubsequentMonoPatternFillTrap(ScrnInfoPtr pScrn,
+ int patx, int paty,
+ int y, int h,
+ int left, int dxL, int dyL, int eL,
+ int right, int dxR, int dyR, int eR );
+#endif
+#if 0
+static void SiSSetupForColorPatternFill(ScrnInfoPtr pScrn,
+ int patx, int paty, int rop,
+ unsigned int planemask,
+ int trans_color);
+static void SiSSubsequentColorPatternFill(ScrnInfoPtr pScrn,
+ int patx, int paty,
+ int x, int y, int w, int h);
+#endif
+#if 0
+static void SiSSetupForCPUToScreenColorExpand(ScrnInfoPtr pScrn,
+ int fg, int bg,
+ int rop, unsigned int planemask);
+static void SiSSubsequentCPUToScreenColorExpand(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft);
+#endif
+#ifdef STSCE
+static void SiSSetupForScreenToScreenColorExpand(ScrnInfoPtr pScrn,
+ int fg, int bg,
+ int rop, unsigned int planemask);
+static void SiSSubsequentScreenToScreenColorExpand(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int srcx, int srcy, int skipleft);
+#endif
+static void SiSSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask);
+static void SiSSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int skipleft);
+static void SiSSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno);
+
+#ifdef SISDUALHEAD
+static void SiSRestoreAccelState(ScrnInfoPtr pScrn);
+#endif
+
+static void
+SiSInitializeAccelerator(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+
+ pSiS->DoColorExpand = FALSE;
+}
+
+Bool
+SiS300AccelInit(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr infoPtr;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ SISPtr pSiS = SISPTR(pScrn);
+ int topFB;
+ int reservedFbSize;
+ int UsableFbSize;
+ unsigned char *AvailBufBase;
+ BoxRec Avail;
+ int i;
+
+ pSiS->AccelInfoPtr = infoPtr = XAACreateInfoRec();
+ if (!infoPtr) return FALSE;
+
+ SiSInitializeAccelerator(pScrn);
+
+ infoPtr->Flags = LINEAR_FRAMEBUFFER |
+ OFFSCREEN_PIXMAPS |
+ PIXMAP_CACHE;
+
+ /* sync */
+ infoPtr->Sync = SiSSync;
+
+ /* Acceleration only supported at 8, 16 and 32 bpp */
+ if((pScrn->bitsPerPixel != 8) && (pScrn->bitsPerPixel != 16) &&
+ (pScrn->bitsPerPixel != 32))
+ return FALSE;
+
+ /* screen to screen copy - TW: We now support transparent copies */
+ infoPtr->SetupForScreenToScreenCopy = SiSSetupForScreenToScreenCopy;
+ infoPtr->SubsequentScreenToScreenCopy = SiSSubsequentScreenToScreenCopy;
+ infoPtr->ScreenToScreenCopyFlags = NO_PLANEMASK |
+ TRANSPARENCY_GXCOPY_ONLY;
+
+ /* solid fills */
+ infoPtr->SetupForSolidFill = SiSSetupForSolidFill;
+ infoPtr->SubsequentSolidFillRect = SiSSubsequentSolidFillRect;
+#ifdef TRAP
+ infoPtr->SubsequentSolidFillTrap = SiSSubsequentSolidFillTrap;
+#endif
+ infoPtr->SolidFillFlags = NO_PLANEMASK;
+
+ /* solid line */
+ infoPtr->SetupForSolidLine = SiSSetupForSolidLine;
+ infoPtr->SubsequentSolidTwoPointLine = SiSSubsequentSolidTwoPointLine;
+ infoPtr->SubsequentSolidHorVertLine = SiSSubsequentSolidHorzVertLine;
+ infoPtr->SolidLineFlags = NO_PLANEMASK;
+
+ /* dashed line */
+ infoPtr->SetupForDashedLine = SiSSetupForDashedLine;
+ infoPtr->SubsequentDashedTwoPointLine = SiSSubsequentDashedTwoPointLine;
+ infoPtr->DashPatternMaxLength = 64;
+ infoPtr->DashedLineFlags = NO_PLANEMASK |
+ LINE_PATTERN_MSBFIRST_LSBJUSTIFIED;
+
+ /* 8x8 mono pattern fill */
+ infoPtr->SetupForMono8x8PatternFill = SiSSetupForMonoPatternFill;
+ infoPtr->SubsequentMono8x8PatternFillRect = SiSSubsequentMonoPatternFill;
+#ifdef TRAP
+ infoPtr->SubsequentMono8x8PatternFillTrap = SiSSubsequentMonoPatternFillTrap;
+#endif
+ infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK |
+ HARDWARE_PATTERN_SCREEN_ORIGIN |
+ HARDWARE_PATTERN_PROGRAMMED_BITS |
+ NO_TRANSPARENCY |
+ BIT_ORDER_IN_BYTE_MSBFIRST ;
+
+#ifdef STSCE
+ /* Screen To Screen Color Expand */
+ /* TW: The hardware does support this the way we need it */
+ infoPtr->SetupForScreenToScreenColorExpandFill =
+ SiSSetupForScreenToScreenColorExpand;
+ infoPtr->SubsequentScreenToScreenColorExpandFill =
+ SiSSubsequentScreenToScreenColorExpand;
+ infoPtr->ScreenToScreenColorExpandFillFlags = NO_PLANEMASK |
+ BIT_ORDER_IN_BYTE_MSBFIRST ;
+#endif
+
+#if 0
+ /* CPU To Screen Color Expand --- implement another instead of this one! */
+ infoPtr->SetupForCPUToScreenColorExpandFill =
+ SiSSetupForCPUToScreenColorExpand;
+ infoPtr->SubsequentCPUToScreenColorExpandFill =
+ SiSSubsequentCPUToScreenColorExpand;
+ infoPtr->ColorExpandRange = PATREGSIZE;
+ infoPtr->ColorExpandBase = pSiS->IOBase+PBR(0);
+ infoPtr->CPUToScreenColorExpandFillFlags = NO_PLANEMASK |
+ BIT_ORDER_IN_BYTE_MSBFIRST |
+ NO_TRANSPARENCY |
+ SYNC_AFTER_COLOR_EXPAND |
+ HARDWARE_PATTERN_SCREEN_ORIGIN |
+ HARDWARE_PATTERN_PROGRAMMED_BITS ;
+#endif
+
+ /* per-scanline color expansion (using indirect method) */
+ if(pSiS->VGAEngine == SIS_530_VGA) {
+ pSiS->ColorExpandBufferNumber = 4;
+ pSiS->ColorExpandBufferCountMask = 0x03;
+ } else {
+ pSiS->ColorExpandBufferNumber = 16;
+ pSiS->ColorExpandBufferCountMask = 0x0F;
+ }
+ pSiS->PerColorExpandBufferSize = ((pScrn->virtualX + 31)/32) * 4;
+ infoPtr->NumScanlineColorExpandBuffers = pSiS->ColorExpandBufferNumber;
+ infoPtr->ScanlineColorExpandBuffers = (unsigned char **)&pSiS->ColorExpandBufferAddr[0];
+
+ infoPtr->SetupForScanlineCPUToScreenColorExpandFill =
+ SiSSetupForScanlineCPUToScreenColorExpandFill;
+ infoPtr->SubsequentScanlineCPUToScreenColorExpandFill =
+ SiSSubsequentScanlineCPUToScreenColorExpandFill;
+ infoPtr->SubsequentColorExpandScanline =
+ SiSSubsequentColorExpandScanline;
+ infoPtr->ScanlineCPUToScreenColorExpandFillFlags =
+ NO_PLANEMASK |
+ CPU_TRANSFER_PAD_DWORD |
+ SCANLINE_PAD_DWORD |
+ BIT_ORDER_IN_BYTE_MSBFIRST |
+ LEFT_EDGE_CLIPPING;
+
+#ifdef SISDUALHEAD
+ if (pSiS->DualHeadMode) {
+ infoPtr->RestoreAccelState = SiSRestoreAccelState;
+ }
+#endif
+
+ /* init Frame Buffer Manager */
+ topFB = pSiS->maxxfbmem;
+
+ reservedFbSize = pSiS->ColorExpandBufferNumber * pSiS->PerColorExpandBufferSize;
+
+ UsableFbSize = topFB - reservedFbSize;
+
+ /* Layout: (Sizes do not reflect correct proportions)
+ * |--------------++++++++++++++++++++^************==========~~~~~~~~~~~~|
+ * UsableFbSize ColorExpandBuffers | DRI-Heap | HWCursor TurboQueue 300/310/325 series
+ * |--------------++++++++++++++++++++| ====================~~~~~~~~~~~~|
+ * UsableFbSize ColorExpandBuffers | TurboQueue HWCursor 530/620
+ * topFB
+ */
+
+ AvailBufBase = pSiS->FbBase + UsableFbSize;
+ for (i = 0; i < pSiS->ColorExpandBufferNumber; i++) {
+ pSiS->ColorExpandBufferAddr[i] = AvailBufBase +
+ i * pSiS->PerColorExpandBufferSize;
+ pSiS->ColorExpandBufferScreenOffset[i] = UsableFbSize +
+ i * pSiS->PerColorExpandBufferSize;
+ }
+ Avail.x1 = 0;
+ Avail.y1 = 0;
+ Avail.x2 = pScrn->displayWidth;
+ Avail.y2 = (UsableFbSize / (pScrn->displayWidth * pScrn->bitsPerPixel/8)) - 1;
+
+ if(Avail.y2 < 0) Avail.y2 = 32767;
+
+ if(Avail.y2 < pScrn->currentMode->VDisplay) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Not enough video RAM for accelerator. At least "
+ "%dKB needed, %dKB available\n",
+ ((((pScrn->displayWidth * pScrn->bitsPerPixel/8) /* TW: +8 for make it sure */
+ * pScrn->currentMode->VDisplay) + reservedFbSize) / 1024) + 8,
+ pSiS->maxxfbmem/1024);
+ pSiS->NoAccel = TRUE;
+ pSiS->NoXvideo = TRUE;
+ XAADestroyInfoRec(pSiS->AccelInfoPtr);
+ pSiS->AccelInfoPtr = NULL;
+ return FALSE;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Frame Buffer From (%d,%d) To (%d,%d)\n",
+ Avail.x1, Avail.y1, Avail.x2, Avail.y2);
+
+ xf86InitFBManager(pScreen, &Avail);
+
+ return(XAAInit(pScreen, infoPtr));
+}
+
+
+static void
+SiSSync(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+
+ PDEBUG(ErrorF("SiSSync()\n"));
+
+ pSiS->DoColorExpand = FALSE;
+ SiSIdle
+}
+
+#ifdef SISDUALHEAD
+static void
+SiSRestoreAccelState(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+
+ /* TW: We don't need to do anything special here; forcing the
+ * other head to re-read the CmdQueLen is not necessary:
+ * After the Sync in RestoreAccelState(), the real queue
+ * length is always larger than (or at least equal to)
+ * the amount stored in CmdQueueLen of the other head,
+ * so the only thing that might happen is one unnecessary
+ * Sync on the other head. I think we can live with that.
+ */
+ pSiS->DoColorExpand = FALSE;
+ SiSIdle
+}
+#endif
+
+static const int sisALUConv[] =
+{
+ 0x00, /* dest = 0; 0, GXclear, 0 */
+ 0x88, /* dest &= src; DSa, GXand, 0x1 */
+ 0x44, /* dest = src & ~dest; SDna, GXandReverse, 0x2 */
+ 0xCC, /* dest = src; S, GXcopy, 0x3 */
+ 0x22, /* dest &= ~src; DSna, GXandInverted, 0x4 */
+ 0xAA, /* dest = dest; D, GXnoop, 0x5 */
+ 0x66, /* dest = ^src; DSx, GXxor, 0x6 */
+ 0xEE, /* dest |= src; DSo, GXor, 0x7 */
+ 0x11, /* dest = ~src & ~dest; DSon, GXnor, 0x8 */
+ 0x99, /* dest ^= ~src ; DSxn, GXequiv, 0x9 */
+ 0x55, /* dest = ~dest; Dn, GXInvert, 0xA */
+ 0xDD, /* dest = src|~dest ; SDno, GXorReverse, 0xB */
+ 0x33, /* dest = ~src; Sn, GXcopyInverted, 0xC */
+ 0xBB, /* dest |= ~src; DSno, GXorInverted, 0xD */
+ 0x77, /* dest = ~src|~dest; DSan, GXnand, 0xE */
+ 0xFF, /* dest = 0xFF; 1, GXset, 0xF */
+};
+/* same ROP but with Pattern as Source */
+static const int sisPatALUConv[] =
+{
+ 0x00, /* dest = 0; 0, GXclear, 0 */
+ 0xA0, /* dest &= src; DPa, GXand, 0x1 */
+ 0x50, /* dest = src & ~dest; PDna, GXandReverse, 0x2 */
+ 0xF0, /* dest = src; P, GXcopy, 0x3 */
+ 0x0A, /* dest &= ~src; DPna, GXandInverted, 0x4 */
+ 0xAA, /* dest = dest; D, GXnoop, 0x5 */
+ 0x5A, /* dest = ^src; DPx, GXxor, 0x6 */
+ 0xFA, /* dest |= src; DPo, GXor, 0x7 */
+ 0x05, /* dest = ~src & ~dest; DPon, GXnor, 0x8 */
+ 0xA5, /* dest ^= ~src ; DPxn, GXequiv, 0x9 */
+ 0x55, /* dest = ~dest; Dn, GXInvert, 0xA */
+ 0xF5, /* dest = src|~dest ; PDno, GXorReverse, 0xB */
+ 0x0F, /* dest = ~src; Pn, GXcopyInverted, 0xC */
+ 0xAF, /* dest |= ~src; DPno, GXorInverted, 0xD */
+ 0x5F, /* dest = ~src|~dest; DPan, GXnand, 0xE */
+ 0xFF, /* dest = 0xFF; 1, GXset, 0xF */
+};
+
+static void SiSSetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int xdir, int ydir, int rop,
+ unsigned int planemask, int trans_color)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+
+ PDEBUG(ErrorF("Setup ScreenCopy(%d, %d, 0x%x, 0x%x, 0x%x)\n",
+ xdir, ydir, rop, planemask, trans_color));
+
+ SiSSetupDSTColorDepth(pSiS->DstColor);
+ SiSSetupSRCPitch(pSiS->scrnOffset)
+ SiSSetupDSTRect(pSiS->scrnOffset, -1)
+
+ if(trans_color != -1) {
+ SiSSetupROP(0x0A)
+ SiSSetupSRCTrans(trans_color)
+ SiSSetupCMDFlag(TRANSPARENT_BITBLT)
+ } else {
+ SiSSetupROP(sisALUConv[rop])
+ }
+ if(xdir > 0) {
+ SiSSetupCMDFlag(X_INC)
+ }
+ if(ydir > 0) {
+ SiSSetupCMDFlag(Y_INC)
+ }
+}
+
+static void SiSSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int src_x, int src_y, int dst_x, int dst_y,
+ int width, int height)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ long srcbase, dstbase;
+
+ PDEBUG(ErrorF("Subsequent ScreenCopy(%d,%d, %d,%d, %d,%d)\n",
+ src_x, src_y, dst_x, dst_y, width, height));
+
+ srcbase = dstbase = 0;
+ if(src_y >= 2048) {
+ srcbase = pSiS->scrnOffset * src_y;
+ src_y = 0;
+ }
+ if( (dst_y >= pScrn->virtualY) || (dst_y >= 2048) ) {
+ dstbase = pSiS->scrnOffset * dst_y;
+ dst_y = 0;
+ }
+#ifdef SISDUALHEAD
+ if(pSiS->VGAEngine != SIS_530_VGA) {
+ srcbase += HEADOFFSET;
+ dstbase += HEADOFFSET;
+ }
+#endif
+ SiSSetupSRCBase(srcbase);
+ SiSSetupDSTBase(dstbase);
+
+ if(!(pSiS->CommandReg & X_INC)) {
+ src_x += width-1;
+ dst_x += width-1;
+ }
+ if(!(pSiS->CommandReg & Y_INC)) {
+ src_y += height-1;
+ dst_y += height-1;
+ }
+ SiSSetupRect(width, height)
+ SiSSetupSRCXY(src_x, src_y)
+ SiSSetupDSTXY(dst_x, dst_y)
+
+ SiSDoCMD
+}
+
+static void
+SiSSetupForSolidFill(ScrnInfoPtr pScrn,
+ int color, int rop, unsigned int planemask)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+
+ PDEBUG(ErrorF("Setup SolidFill(0x%x, 0x%x, 0x%x)\n",
+ color, rop, planemask));
+
+ SiSSetupPATFG(color)
+ SiSSetupDSTRect(pSiS->scrnOffset, -1)
+ SiSSetupDSTColorDepth(pSiS->DstColor);
+ SiSSetupROP(sisPatALUConv[rop])
+ /* SiSSetupCMDFlag(PATFG) - is zero */
+}
+
+static void
+SiSSubsequentSolidFillRect(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ long dstbase;
+
+ PDEBUG(ErrorF("Subsequent SolidFillRect(%d, %d, %d, %d)\n",
+ x, y, w, h));
+ dstbase = 0;
+
+ if (y >= 2048) {
+ dstbase = pSiS->scrnOffset * y;
+ y = 0;
+ }
+#ifdef SISDUALHEAD
+ if(pSiS->VGAEngine != SIS_530_VGA) {
+ dstbase += HEADOFFSET;
+ }
+#endif
+ SiSSetupDSTBase(dstbase)
+ SiSSetupDSTXY(x,y)
+ SiSSetupRect(w,h)
+ /* Clear commandReg because Setup can be used for Rect and Trap */
+ pSiS->CommandReg &= ~(T_XISMAJORL | T_XISMAJORR |
+ T_L_X_INC | T_L_Y_INC |
+ T_R_X_INC | T_R_Y_INC |
+ TRAPAZOID_FILL);
+ SiSSetupCMDFlag(X_INC | Y_INC | BITBLT)
+
+ SiSDoCMD
+}
+
+/* TW: Trapezoid */
+/* This would work better if XAA would provide us with valid trapezoids.
+ * In fact, with small trapezoids the left and the right edge often cross
+ * each other or result in a line length of 0 which causes drawing errors
+ * (filling over whole scanline).
+ * Furthermore, I have not found out how to draw trapezoids with a height
+ * greater than 127.
+ */
+#ifdef TRAP
+static void
+SiSSubsequentSolidFillTrap(ScrnInfoPtr pScrn, int y, int h,
+ int left, int dxL, int dyL, int eL,
+ int right, int dxR, int dyR, int eR )
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ long dstbase;
+#if 0
+ float kL, kR;
+#endif
+
+ dstbase = 0;
+ if (y >= 2048) {
+ dstbase=pSiS->scrnOffset*y;
+ y = 0;
+ }
+#ifdef SISDUALHEAD
+ if(pSiS->VGAEngine != SIS_530_VGA) {
+ dstbase += HEADOFFSET;
+ }
+#endif
+ SiSSetupDSTBase(dstbase)
+ /* SiSSetupRect(w,h) */
+
+#if 1
+ SiSSetupPATFG(0xff0000) /* FOR TESTING */
+#endif
+
+ /* Clear CommandReg because SetUp can be used for Rect and Trap */
+ pSiS->CommandReg &= ~(T_L_X_INC | T_L_Y_INC |
+ T_R_X_INC | T_R_Y_INC |
+ T_XISMAJORL | T_XISMAJORR |
+ BITBLT);
+
+ xf86DrvMsg(0, X_INFO, "Trap (%d %d %d %d) dxL %d dyL %d eL %d dxR %d dyR %d eR %d\n",
+ left, right, y, h, dxL, dyL, eL, dxR, dyR, eR);
+
+ /* Unfortunately, we must check if the right and the left edge
+ * cross each other... INCOMPLETE (line equation wrong)
+ */
+#if 0
+ if (dxL == 0) kL = 0;
+ else kL = (float)dyL / (float)dxL;
+ if (dxR == 0) kR = 0;
+ else kR = (float)dyR / (float)dxR;
+ xf86DrvMsg(0, X_INFO, "kL %f kR %f!\n", kL, kR);
+ if ( (kR != kL) &&
+ (!(kR == 0 && kL == 0)) &&
+ (!(kR < 0 && kL > 0)) ) {
+ xf86DrvMsg(0, X_INFO, "Inside if (%f - %d)\n", ( kL * ( ( ((float)right - (float)left) / (kL - kR) ) - left) + y), h+y);
+ if ( ( ( kL * ( ( ((float)right - (float)left) / (kL - kR) ) - (float)left) + (float)y) < (h + y) ) ) {
+ xf86DrvMsg(0, X_INFO, "Cross detected!\n");
+ }
+ }
+#endif
+
+ /* Determine egde angles */
+ if (dxL < 0) { dxL = -dxL; }
+ else { SiSSetupCMDFlag(T_L_X_INC) }
+ if (dxR < 0) { dxR = -dxR; }
+ else { SiSSetupCMDFlag(T_R_X_INC) }
+
+ /* (Y direction always positive - do this anyway) */
+ if (dyL < 0) { dyL = -dyL; }
+ else { SiSSetupCMDFlag(T_L_Y_INC) }
+ if (dyR < 0) { dyR = -dyR; }
+ else { SiSSetupCMDFlag(T_R_Y_INC) }
+
+ /* Determine major axis */
+ if (dxL >= dyL) { /* X is major axis */
+ SiSSetupCMDFlag(T_XISMAJORL)
+ }
+ if (dxR >= dyR) { /* X is major axis */
+ SiSSetupCMDFlag(T_XISMAJORR)
+ }
+
+ /* Set up deltas */
+ SiSSetupdL(dxL, dyL)
+ SiSSetupdR(dxR, dyR)
+
+#if 0 /* Could it be that this crappy engine can only draw trapezoids up to 127 pixels high? */
+ h &= 0x7F;
+ if (h == 0) h = 10;
+#endif
+
+ /* Set up y, h, left, right */
+ SiSSetupYH(y,h)
+ SiSSetupLR(left,right)
+
+ /* Set up initial error term */
+ SiSSetupEL(eL)
+ SiSSetupER(eR)
+
+ SiSSetupCMDFlag(TRAPAZOID_FILL);
+
+ SiSDoCMD
+}
+#endif
+
+static void
+SiSSetupForSolidLine(ScrnInfoPtr pScrn,
+ int color, int rop, unsigned int planemask)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+
+ PDEBUG(ErrorF("Setup SolidLine(0x%x, 0x%x, 0x%x)\n",
+ color, rop, planemask));
+
+ SiSSetupLineCount(1)
+ SiSSetupPATFG(color)
+ SiSSetupDSTRect(pSiS->scrnOffset, -1)
+ SiSSetupDSTColorDepth(pSiS->DstColor);
+ SiSSetupROP(sisPatALUConv[rop])
+ SiSSetupCMDFlag(PATFG | LINE)
+}
+
+static void
+SiSSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn,
+ int x1, int y1, int x2, int y2, int flags)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ long dstbase,miny,maxy;
+
+ PDEBUG(ErrorF("Subsequent SolidLine(%d, %d, %d, %d, 0x%x)\n",
+ x1, y1, x2, y2, flags));
+
+ dstbase = 0;
+ miny = (y1 > y2) ? y2 : y1;
+ maxy = (y1 > y2) ? y1 : y2;
+ if(maxy >= 2048) {
+ dstbase = pSiS->scrnOffset * miny;
+ y1 -= miny;
+ y2 -= miny;
+ }
+#ifdef SISDUALHEAD
+ if(pSiS->VGAEngine != SIS_530_VGA) {
+ dstbase += HEADOFFSET;
+ }
+#endif
+ SiSSetupDSTBase(dstbase)
+
+ SiSSetupX0Y0(x1,y1)
+ SiSSetupX1Y1(x2,y2)
+ if (flags & OMIT_LAST) {
+ SiSSetupCMDFlag(NO_LAST_PIXEL)
+ } else {
+ pSiS->CommandReg &= ~(NO_LAST_PIXEL);
+ }
+
+ SiSDoCMD
+}
+
+static void
+SiSSubsequentSolidHorzVertLine(ScrnInfoPtr pScrn,
+ int x, int y, int len, int dir)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ long dstbase;
+
+ PDEBUG(ErrorF("Subsequent SolidHorzVertLine(%d, %d, %d, %d)\n",
+ x, y, len, dir));
+ len--; /* starting point is included! */
+
+ dstbase = 0;
+ if((y >= 2048) || ((y + len) >= 2048)) {
+ dstbase = pSiS->scrnOffset * y;
+ y = 0;
+ }
+#ifdef SISDUALHEAD
+ if(pSiS->VGAEngine != SIS_530_VGA) {
+ dstbase += HEADOFFSET;
+ }
+#endif
+ SiSSetupDSTBase(dstbase)
+
+ SiSSetupX0Y0(x,y)
+ if (dir == DEGREES_0) {
+ SiSSetupX1Y1(x + len, y);
+ } else {
+ SiSSetupX1Y1(x, y + len);
+ }
+
+ SiSDoCMD
+}
+
+static void
+SiSSetupForDashedLine(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop, unsigned int planemask,
+ int length, unsigned char *pattern)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+
+ PDEBUG(ErrorF("Setup DashedLine(0x%x, 0x%x, 0x%x, 0x%x, %d, 0x%x:%x)\n",
+ fg, bg, rop, planemask, length, *(pattern+4), *pattern));
+
+ SiSSetupLineCount(1)
+ SiSSetupDSTRect(pSiS->scrnOffset, -1)
+ SiSSetupDSTColorDepth(pSiS->DstColor);
+ SiSSetupStyleLow(*pattern)
+ SiSSetupStyleHigh(*(pattern+4))
+ SiSSetupStylePeriod(length-1); /* TW: This was missing!!! */
+ SiSSetupROP(sisPatALUConv[rop])
+ SiSSetupPATFG(fg)
+ SiSSetupCMDFlag(LINE | LINE_STYLE) /* TW: This was missing!!! */
+ if(bg != -1) {
+ SiSSetupPATBG(bg)
+ } else {
+ SiSSetupCMDFlag(TRANSPARENT); /* TW: This was missing!!! */
+ }
+}
+
+static void
+SiSSubsequentDashedTwoPointLine(ScrnInfoPtr pScrn,
+ int x1, int y1, int x2, int y2,
+ int flags, int phase)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ long dstbase,miny,maxy;
+
+ PDEBUG(ErrorF("Subsequent DashedLine(%d,%d, %d,%d, 0x%x,0x%x)\n",
+ x1, y1, x2, y2, flags, phase));
+
+ dstbase = 0;
+ miny = (y1 > y2) ? y2 : y1;
+ maxy = (y1 > y2) ? y1 : y2;
+ if(maxy >= 2048) {
+ dstbase = pSiS->scrnOffset * miny;
+ y1 -= miny;
+ y2 -= miny;
+ }
+#ifdef SISDUALHEAD
+ if(pSiS->VGAEngine != SIS_530_VGA) {
+ dstbase += HEADOFFSET;
+ }
+#endif
+ SiSSetupDSTBase(dstbase)
+
+ SiSSetupX0Y0(x1,y1)
+ SiSSetupX1Y1(x2,y2)
+ if(flags & OMIT_LAST) {
+ SiSSetupCMDFlag(NO_LAST_PIXEL)
+ } else {
+ pSiS->CommandReg &= ~(NO_LAST_PIXEL);
+ }
+
+ SiSDoCMD
+}
+
+static void
+SiSSetupForMonoPatternFill(ScrnInfoPtr pScrn,
+ int patx, int paty, int fg, int bg,
+ int rop, unsigned int planemask)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+
+ PDEBUG(ErrorF("Setup MonoPatFill(0x%x,0x%x, 0x%x,0x%x, 0x%x, 0x%x)\n",
+ patx, paty, fg, bg, rop, planemask));
+ SiSSetupDSTRect(pSiS->scrnOffset, -1)
+ SiSSetupDSTColorDepth(pSiS->DstColor);
+ SiSSetupMONOPAT(patx,paty)
+ SiSSetupPATFG(fg)
+ SiSSetupROP(sisPatALUConv[rop])
+ SiSSetupCMDFlag(PATMONO)
+ SiSSetupPATBG(bg)
+}
+
+static void
+SiSSubsequentMonoPatternFill(ScrnInfoPtr pScrn,
+ int patx, int paty,
+ int x, int y, int w, int h)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ long dstbase;
+
+ PDEBUG(ErrorF("Subsequent MonoPatFill(0x%x,0x%x, %d,%d, %d,%d)\n",
+ patx, paty, x, y, w, h));
+ dstbase = 0;
+
+ if (y >= 2048) {
+ dstbase = pSiS->scrnOffset * y;
+ y = 0;
+ }
+#ifdef SISDUALHEAD
+ if(pSiS->VGAEngine != SIS_530_VGA) {
+ dstbase += HEADOFFSET;
+ }
+#endif
+ SiSSetupDSTBase(dstbase)
+ SiSSetupDSTXY(x, y)
+ SiSSetupRect(w, h)
+ /* Clear commandReg because Setup can be used for Rect and Trap */
+ pSiS->CommandReg &= ~(T_XISMAJORL | T_XISMAJORR |
+ T_L_X_INC | T_L_Y_INC |
+ T_R_X_INC | T_R_Y_INC |
+ TRAPAZOID_FILL);
+ SiSSetupCMDFlag(X_INC | Y_INC)
+
+ SiSDoCMD
+}
+
+/* Trapezoid */
+#ifdef TRAP
+static void
+SiSSubsequentMonoPatternFillTrap(ScrnInfoPtr pScrn,
+ int patx, int paty,
+ int y, int h,
+ int left, int dxL, int dyL, int eL,
+ int right, int dxR, int dyR, int eR )
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ long dstbase;
+
+ PDEBUG(ErrorF("Subsequent Mono8x8PatternFillTrap(%d, %d, %d - %d %d/%d %d/%d)\n",
+ y, h, left, right, dxL, dxR, eL, eR));
+
+ dstbase = 0;
+ if (y >= 2048) {
+ dstbase=pSiS->scrnOffset*y;
+ y = 0;
+ }
+#ifdef SISDUALHEAD
+ if(pSiS->VGAEngine != SIS_530_VGA) {
+ dstbase += HEADOFFSET;
+ }
+#endif
+ SiSSetupDSTBase(dstbase)
+
+ /* Clear CommandReg because SetUp can be used for Rect and Trap */
+ pSiS->CommandReg &= ~(T_XISMAJORL | T_XISMAJORR |
+ T_L_X_INC | T_L_Y_INC |
+ T_R_X_INC | T_R_Y_INC |
+ BITBLT);
+
+ if (dxL < 0) { dxL = -dxL; }
+ else { SiSSetupCMDFlag(T_L_X_INC) }
+ if (dxR < 0) { dxR = -dxR; }
+ else { SiSSetupCMDFlag(T_R_X_INC) }
+
+ if (dyL < 0) { dyL = -dyL; }
+ else { SiSSetupCMDFlag(T_L_Y_INC) }
+ if (dyR < 0) { dyR = -dyR; }
+ else { SiSSetupCMDFlag(T_R_Y_INC) }
+
+ /* Determine major axis */
+ if (dxL >= dyL) { /* X is major axis */
+ SiSSetupCMDFlag(T_XISMAJORL)
+ }
+ if (dxR >= dyR) { /* X is major axis */
+ SiSSetupCMDFlag(T_XISMAJORR)
+ }
+
+ SiSSetupYH(y,h)
+ SiSSetupLR(left,right)
+
+ SiSSetupdL(dxL, dyL)
+ SiSSetupdR(dxR, dyR)
+
+ SiSSetupEL(eL)
+ SiSSetupER(eR)
+
+ SiSSetupCMDFlag(TRAPAZOID_FILL);
+
+ SiSDoCMD
+}
+#endif
+
+
+#if 0
+
+/* TW: The following (already commented) functions have NOT been adapted for dual-head mode */
+
+
+/* ------- Color Pattern Fill --- is not useful for XAA -------------- */
+
+static void
+SiSSetupForColorPatternFill(ScrnInfoPtr pScrn,
+ int patx, int paty, int rop,
+ unsigned int planemask,
+ int trans_color)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+
+ PDEBUG(ErrorF("Setup ColorPatFill(0x%x,0x%x, 0x%x,0x%x, 0x%x)\n",
+ patx, paty, rop, planemask, trans_color));
+
+/* SiSSetupDSTRect(pSiS->scrnOffset, pScrn->virtualY)*/
+ SiSSetupDSTRect(pSiS->scrnOffset, -1)
+ SiSSetupDSTColorDepth(pSiS->DstColor);
+ SiSSetupROP(sisPatALUConv[rop])
+ SiSSetupCMDFlag(PATPATREG | X_INC | Y_INC)
+}
+
+static void
+SiSSubsequentColorPatternFill(ScrnInfoPtr pScrn,
+ int patx, int paty,
+ int x, int y, int w, int h)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ long dstbase;
+
+ PDEBUG(ErrorF("Subsequent ColorPatFill(0x%x,0x%x, %d,%d, %d,%d)\n",
+ patx, paty, x, y, w, h));
+
+ dstbase = 0;
+ if (y >= 2048) {
+ dstbase = pSiS->scrnOffset * y;
+ y = 0;
+ }
+ SiSSetupDSTBase(dstbase)
+ SiSSetupDSTXY(x,y)
+ SiSSetupRect(w,h)
+ SiSDoCMD
+}
+
+/* ----- CPU To Screen Color Expand (single task) ------------------------- */
+
+/* This does not work. Assumingly for the same
+ * reason why STSColorExpand does not work either.
+ */
+static void
+SiSSetupForCPUToScreenColorExpand(ScrnInfoPtr pScrn,
+ int fg, int bg,
+ int rop, unsigned int planemask)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+
+ PDEBUG(ErrorF("Setup CPUToScreen ColorExpand(0x%x,0x%x, 0x%x,0x%x)\n",
+ fg, bg, rop, planemask));
+
+/* SiSSetupDSTRect(pSiS->scrnOffset, pScrn->virtualY)*/
+ SiSSetupDSTRect(pSiS->scrnOffset, -1)
+ SiSSetupDSTColorDepth(pSiS->DstColor);
+ SiSSetupSRCXY(0,0)
+ SiSSetupSRCFG(fg)
+ SiSSetupROP(sisPatALUConv[rop])
+ SiSSetupCMDFlag(X_INC | Y_INC | COLOREXP)
+ if (bg == -1) {
+ SiSSetupCMDFlag(TRANSPARENT)
+ }
+ else {
+ SiSSetupSRCBG(bg)
+ }
+}
+
+static void
+SiSSubsequentCPUToScreenColorExpand(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ long dstbase;
+
+ PDEBUG(ErrorF("Subsequent CPUToScreen ColorExpand(%d,%d, %d,%d, %d)\n",
+ x, y, w, h, skipleft));
+
+ dstbase = 0;
+ if (y >= 2048) {
+ dstbase = pSiS->scrnOffset * y;
+ y = 0;
+ }
+ SiSSetupDSTBase(dstbase)
+
+/* SiSSetupSRCPitch(((w+31)&0xFFE0)/8)*/
+ SiSSetupSRCPitch((w+7)/8)
+ SiSSetupDSTXY(x,y)
+ SiSSetupRect(w,h)
+/* SiSDoCMD*/
+ pSiS->DoColorExpand = TRUE;
+}
+#endif
+
+/* ------ Screen To Screen Color Expand ------------------------------- */
+
+/* TW: The hareware does not seem to support this the way we need it */
+
+#ifdef STSCE
+static void
+SiSSetupForScreenToScreenColorExpand(ScrnInfoPtr pScrn,
+ int fg, int bg,
+ int rop, unsigned int planemask)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+
+ PDEBUG(ErrorF("Setup ScreenToScreen ColorExp(0x%x,0x%x, 0x%x)\n",
+ fg, bg, rop));
+
+ SiSSetupDSTColorDepth(pSiS->DstColor)
+ SiSSetupDSTRect(pSiS->scrnOffset, -1)
+ SiSSetupROP(sisALUConv[rop])
+ SiSSetupSRCFG(fg)
+ /* SiSSetupSRCXY(0,0) */
+
+ if(bg == -1) {
+ SiSSetupCMDFlag(TRANSPARENT | ENCOLOREXP | X_INC |
+ Y_INC | SRCVIDEO);
+ } else {
+ SiSSetupSRCBG(bg);
+ SiSSetupCMDFlag(ENCOLOREXP | X_INC | Y_INC |
+ SRCVIDEO);
+ };
+}
+#endif
+
+/* TW. This method blits in a single task; this does not seem to work
+ * because the hardware does not use the source pitch as scanline
+ * offset but only to calculate pattern address from source X and Y.
+ * XAA provides the pattern bitmap with scrnOffset (displayWidth * bpp/8)
+ * offset, but this does not seem to be supported by the hardware.
+ */
+#ifdef STSCE
+
+/* For testing, these are the methods: (use only one at a time!) */
+
+#undef npitch /* Normal: Use srcx/y as srcx/y, use scrnOffset as source pitch
+ * This would work if the hareware used the source pitch for
+ * incrementing the source address after each scanline - but
+ * it doesn't do this! The first line of the area is correctly
+ * color expanded, but since the source pitch is ignored and
+ * the source address not incremented correctly, the following
+ * lines are color expanded with any bit pattern that is left
+ * in the unused space of the source bitmap (which is organized
+ * with the depth of the screen framebuffer hence with a pitch
+ * of scrnOffset).
+ */
+
+#undef pitchdw /* Use source pitch "displayWidth / 8" instead
+ * of scrnOffset (=displayWidth * bpp / 8)
+ * This can't work, because the pitch of the source
+ * bitmap is scrnoffset!
+ */
+
+#define nopitch /* Calculate srcbase with srcx and srcy, set the
+ * pitch to scrnOffset (which IS the correct pitch
+ * for the source bitmap) and set srcx and srcy both
+ * to 0.
+ * This would work if the hareware used the source pitch for
+ * incrementing the source address after each scanline - but
+ * it doesn't do this! Again: The first line of the area is
+ * correctly color expanded, but since the source pitch is
+ * ignored for scanline address incremention, the following
+ * lines are not correctly color expanded.
+ * WHATEVER I write to source pitch is ignored!
+ */
+
+static void
+SiSSubsequentScreenToScreenColorExpand(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int srcx, int srcy, int skipleft)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ long srcbase, dstbase;
+#if 0
+ int _x0, _y0, _x1, _y1;
+#endif
+#ifdef pitchdw
+ int newsrcx, newsrcy;
+
+ /* srcx and srcy are provided based on a scrnOffset pitch ( = displayWidth * bpp / 8 )
+ * We recalulate srcx and srcy based on pitch = displayWidth / 8
+ */
+ newsrcy = ((pSiS->scrnOffset * srcy) + (srcx * ((pScrn->bitsPerPixel+7)/8))) /
+ (pScrn->displayWidth/8);
+ newsrcx = ((pSiS->scrnOffset * srcy) + (srcx * ((pScrn->bitsPerPixel+7)/8))) %
+ (pScrn->displayWidth/8);
+#endif
+ xf86DrvMsg(0, X_INFO, "Sub ScreenToScreen ColorExp(%d,%d, %d,%d, %d,%d, %d)\n",
+ x, y, w, h, srcx, srcy, skipleft);
+
+ srcbase = dstbase = 0;
+
+#ifdef pitchdw
+ if (newsrcy >= 2048) {
+ srcbase = (pScrn->displayWidth / 8) * newsrcy;
+ newsrcy = 0;
+ }
+#endif
+#ifdef nopitch
+ srcbase = (pSiS->scrnOffset * srcy) + (srcx * ((pScrn->bitsPerPixel+7)/8));
+#endif
+#ifdef npitch
+ if (srcy >= 2048) {
+ srcbase = pSiS->scrnOffset * srcy;
+ srcy = 0;
+ }
+#endif
+ if (y >= 2048) {
+ dstbase = pSiS->scrnOffset * y;
+ y = 0;
+ }
+#ifdef SISDUALHEAD
+ if(pSiS->VGAEngine != SIS_530_VGA) {
+ srcbase += HEADOFFSET;
+ dstbase += HEADOFFSET;
+ }
+#endif
+ SiSSetupSRCBase(srcbase)
+ SiSSetupDSTBase(dstbase)
+
+#ifdef pitchdw
+ SiSSetupSRCPitch(pScrn->displayWidth/8)
+#endif
+#ifdef nopitch
+ SiSSetupSRCPitch(pSiS->scrnOffset)
+ /* SiSSetupSRCPitch(100) */ /* For test - has NO effect WHATSOEVER */
+#endif
+#ifdef npitch
+ SiSSetupSRCPitch(pSiS->scrnOffset)
+#endif
+
+ SiSSetupRect(w,h)
+
+#if 0 /* How do I implement the offset? Not this way, that's for sure.. */
+ if (skipleft > 0) {
+ _x0 = x+skipleft;
+ _y0 = y;
+ _x1 = x+w;
+ _y1 = y+h;
+ SiSSetupClipLT(_x0, _y0);
+ SiSSetupClipRB(_x1, _y1);
+ SiSSetupCMDFlag(CLIPENABLE);
+ }
+#endif
+#ifdef pitchdw
+ SiSSetupSRCXY(newsrcx, newsrcy)
+#endif
+#ifdef nopitch
+ SiSSetupSRCXY(0,0)
+#endif
+#ifdef npitch
+ SiSSetupSRCXY(srcx, srcy)
+#endif
+
+ SiSSetupDSTXY(x,y)
+
+ SiSDoCMD
+}
+#endif
+
+/* TW: TEST: Do it scanline-wise because the other way does not seem to
+ * be supported by the hardware. (The source pitch seems to be
+ * displayWidth * (bbp/8) as opposed by the XAA HOWTO, where
+ * it is stated that the pitch would be displayWidth pixels;
+ * besides, the hardware seems to ignore the source pitch
+ * for address increments.)
+ * Apart from this (which can be solved by doing the color
+ * expand scanline-wise), I don't know how to implement the
+ * offset argument. The current method (which uses hardware
+ * clipping) does not work.
+ *
+ * THIS DOES NOT WORK IN THE CURRENT STATE.
+ */
+#if 0
+static void
+SiSSubsequentScreenToScreenColorExpand(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int srcx, int srcy, int offset)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ long srcbase, dstbase;
+ int _x0, _y0, _x1, _y1;
+
+ int newsrcx, newsrcy;
+
+ newsrcy = ((pSiS->scrnOffset * srcy) + (srcx * ((pScrn->bitsPerPixel+7)/8))) /
+ (((((w+7)/8)+3) >> 2) * 4);
+ /* (pScrn->displayWidth/8); */
+ newsrcx = ((pSiS->scrnOffset * srcy) + (srcx * ((pScrn->bitsPerPixel+7)/8))) %
+ (((((w+7)/8)+3) >> 2) * 4);
+ /* (pScrn->displayWidth/8); */
+
+ xf86DrvMsg(0, X_INFO, "Sub STS CE(%d,%d, %d,%d, %d,%d, %d)\n",
+ x, y, w, h, srcx, srcy, skipleft);
+
+ srcbase = dstbase = 0;
+ if (newsrcy >= 2048) {
+ srcbase = (((((w+7)/8)+3) >> 2) * 4) * newsrcy;
+ /* (pScrn->displayWidth/8) * newsrcy; */
+ /* pSiS->scrnOffset * srcy; */
+ newsrcy = 0;
+ }
+ if (y >= 2048) {
+ dstbase = pSiS->scrnOffset * y;
+ y = 0;
+ }
+#ifdef SISDUALHEAD
+ srcbase += HEADOFFSET;
+ dstbase += HEADOFFSET;
+#endif
+ SiSSetupDSTBase(dstbase)
+
+ SiSSetupRect(w, 1)
+
+ SiSSetupSRCXY(newsrcx, newsrcy)
+
+ /* SiSSetupSRCPitch(pScrn->displayWidth/8) */ /* old: (((w+31)&0xFFE0)/8) */
+ SiSSetupSRCPitch(((((w+7)/8)+3) >> 2) * 4)
+#if 1
+ if (offset > 0) {
+ SiSSetupCMDFlag(CLIPENABLE)
+ } else
+ pSiS->CommandReg &= ~CLIPENABLE;
+#endif
+
+ while (h) {
+
+ SiSSetupSRCBase(srcbase)
+#if 1
+ if (offset > 0) {
+ _x0 = x+skipleft;
+ _y0 = y;
+ _x1 = x+w;
+ _y1 = y+h;
+ SiSSetupClipLT(_x0, _y0);
+ SiSSetupClipRB(_x1, _y1);
+ }
+#endif
+ SiSSetupDSTXY(x,y)
+
+ SiSDoCMD
+
+ srcbase += ((((w+7)/8)+3) >> 2) * 4 * 8* ((pScrn->bitsPerPixel+7)/8);
+ /* pSiS->scrnOffset; */
+ y++;
+ h--;
+ }
+}
+#endif
+
+
+/* ----- CPU To Screen Color Expand (scanline-wise) ----------------- */
+
+/* We do it using the indirect method */
+
+static void
+SiSSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop, unsigned int planemask)
+{
+ SISPtr pSiS=SISPTR(pScrn);
+
+ /* TW: Make sure that current CPU-driven BitBlt buffer stage is 0
+ * This is required!!! (Otherwise -> drawing errors)
+ */
+ while((MMIO_IN16(pSiS->IOBase, 0x8242) & 0x1F00) != 0) {} /* WDR: == 0x10 */
+
+#if 0 /* TW: This is obviously not needed */
+ pSiS->ColorExpandRingHead = 0;
+ pSiS->ColorExpandRingTail = pSiS->ColorExpandBufferNumber - 1;
+#endif
+
+ SiSSetupSRCXY(0,0);
+ SiSSetupROP(sisALUConv[rop]);
+ SiSSetupSRCFG(fg);
+ SiSSetupDSTRect(pSiS->scrnOffset, -1);
+ SiSSetupDSTColorDepth(pSiS->DstColor);
+ if(bg == -1) {
+ SiSSetupCMDFlag(TRANSPARENT |
+ ENCOLOREXP |
+ X_INC | Y_INC |
+ SRCCPUBLITBUF);
+ } else {
+ SiSSetupSRCBG(bg);
+ SiSSetupCMDFlag(ENCOLOREXP |
+ X_INC | Y_INC |
+ SRCCPUBLITBUF);
+ }
+}
+
+
+static void
+SiSSubsequentScanlineCPUToScreenColorExpandFill(
+ ScrnInfoPtr pScrn, int x, int y, int w,
+ int h, int skipleft)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int _x0, _y0, _x1, _y1;
+ long dstbase;
+
+ dstbase = 0;
+ if (y >= 2048) {
+ dstbase = pSiS->scrnOffset * y;
+ y = 0;
+ }
+#ifdef SISDUALHEAD
+ if(pSiS->VGAEngine != SIS_530_VGA) {
+ dstbase += HEADOFFSET;
+ }
+#endif
+
+ /* TW: Wait until there is no color expansion command in queue
+ * (This solves the OpenOffice.org window-move bug)
+ * Added Idle-check - bit 23 is set sometimes, although
+ * engine is actually idle!
+ * Update: Bit 23 is not reliable. After heavy 3D engine
+ * action, this bit never gets cleared again. So do
+ * SiSIdle instead.
+ */
+ if((MMIO_IN16(pSiS->IOBase, 0x8242) & 0xe000) != 0xe000) {
+ /* while ((MMIO_IN16(pSiS->IOBase, 0x8242) & 0x0080) != 0) {} */
+ SiSIdle
+ }
+
+ SiSSetupDSTBase(dstbase)
+
+ if (skipleft > 0) {
+ _x0 = x + skipleft;
+ _y0 = y;
+ _x1 = x + w;
+ _y1 = y + h;
+ SiSSetupClipLT(_x0, _y0);
+ SiSSetupClipRB(_x1, _y1);
+ SiSSetupCMDFlag(CLIPENABLE);
+ } else {
+ pSiS->CommandReg &= (~CLIPENABLE);
+ }
+
+ SiSSetupRect(w, 1);
+ SiSSetupSRCPitch(((((w+7)/8)+3) >> 2) * 4);
+ pSiS->xcurrent = x;
+ pSiS->ycurrent = y;
+}
+
+static void
+SiSSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
+{
+ SISPtr pSiS=SISPTR(pScrn);
+#if 0
+ int newhead,bltbufstage,newtail;
+#endif
+ long cbo;
+
+ cbo = pSiS->ColorExpandBufferScreenOffset[bufno];
+#ifdef SISDUALHEAD
+ if(pSiS->VGAEngine != SIS_530_VGA) {
+ cbo += HEADOFFSET;
+ }
+#endif
+
+ /* TW: Wait until there is no color expansion command in queue
+ * (This solves the GTK-big-font bug)
+ * Added Idle-check - bit 23 is set sometimes, although
+ * engine is actually idle!
+ * Update: Bit 23 is not reliable. After heavy 3D engine
+ * action, this bit never gets cleared again. So do
+ * SiSIdle instead.
+ */
+ if((MMIO_IN16(pSiS->IOBase, 0x8242) & 0xe000) != 0xe000) {
+ /* while ((MMIO_IN16(pSiS->IOBase, 0x8242) & 0x0080) != 0) {} */
+ SiSIdle
+ }
+
+ SiSSetupSRCBase(cbo);
+
+ SiSSetupDSTXY(pSiS->xcurrent, pSiS->ycurrent);
+
+ SiSDoCMD
+
+ pSiS->ycurrent++;
+
+ if(pSiS->VGAEngine == SIS_530_VGA) {
+ while(MMIO_IN8(pSiS->IOBase, 0x8242) & 0x80) {}
+ }
+
+#if 0 /* TW: What is this good for? The Head/Tail data is never ever used elsewhere! */
+ pSiS->ColorExpandRingHead = newhead =
+ (bufno + 1) & pSiS->ColorExpandBufferCountMask;
+ while (newhead == pSiS->ColorExpandRingTail) {
+ bltbufstage = (int)((MMIO_IN16(pSiS->IOBase,0x8242) & 0x1F00) >> 8);
+ newtail = newhead - (bltbufstage + 1);
+ pSiS->ColorExpandRingTail = (newtail >= 0) ?
+ newtail : (pSiS->ColorExpandBufferNumber + newtail);
+ }
+#endif
+}
+
diff --git a/src/sis300_accel.h b/src/sis300_accel.h
new file mode 100644
index 0000000..33948d0
--- /dev/null
+++ b/src/sis300_accel.h
@@ -0,0 +1,297 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis300_accel.h,v 1.8 2003/01/29 15:42:16 eich Exp $ */
+/*
+ * 2D acceleration for SiS530/620 and 300 series
+ *
+ * Copyright 1998,1999 by Alan Hourihane, Wigan, England.
+ * Parts Copyright 2002 Thomas Winischhofer, Vienna, Austria
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, alanh@fairlite.demon.co.uk
+ * Mike Chapman <mike@paranoia.com>,
+ * Juanjo Santamarta <santamarta@ctv.es>,
+ * Mitani Hiroshi <hmitani@drl.mei.co.jp>
+ * David Thomas <davtom@dream.org.uk>.
+ * Xavier Ducoin <x.ducoin@lectra.com>
+ * Thomas Winischhofer <thomas@winischhofer.net>
+ */
+
+
+/* Definitions for the SIS engine communication. */
+
+#define PATREGSIZE 384 /* Pattern register size. 384 bytes @ 0x8300 */
+#define BR(x) (0x8200 | (x) << 2)
+#define PBR(x) (0x8300 | (x) << 2)
+
+/* SiS300 engine commands */
+#define BITBLT 0x00000000 /* Blit */
+#define COLOREXP 0x00000001 /* Color expand */
+#define ENCOLOREXP 0x00000002 /* Enhanced color expand */
+#define MULTIPLE_SCANLINE 0x00000003 /* ? */
+#define LINE 0x00000004 /* Draw line */
+#define TRAPAZOID_FILL 0x00000005 /* Fill trapezoid */
+#define TRANSPARENT_BITBLT 0x00000006 /* Transparent Blit */
+
+/* source select */
+#define SRCVIDEO 0x00000000 /* source is video RAM */
+#define SRCSYSTEM 0x00000010 /* source is system memory */
+#define SRCCPUBLITBUF SRCSYSTEM /* source is CPU-driven BitBuffer (for color expand) */
+#define SRCAGP 0x00000020 /* source is AGP memory (?) */
+
+/* Pattern flags */
+#define PATFG 0x00000000 /* foreground color */
+#define PATPATREG 0x00000040 /* pattern in pattern buffer (0x8300) */
+#define PATMONO 0x00000080 /* mono pattern */
+
+/* blitting direction */
+#define X_INC 0x00010000
+#define X_DEC 0x00000000
+#define Y_INC 0x00020000
+#define Y_DEC 0x00000000
+
+/* Clipping flags */
+#define NOCLIP 0x00000000
+#define NOMERGECLIP 0x04000000
+#define CLIPENABLE 0x00040000
+#define CLIPWITHOUTMERGE 0x04040000
+
+/* Transparency */
+#define OPAQUE 0x00000000
+#define TRANSPARENT 0x00100000
+
+/* Trapezoid */
+#define T_XISMAJORL 0x00800000 /* X axis is driving axis (left) */
+#define T_XISMAJORR 0x01000000 /* X axis is driving axis (right) */
+#define T_L_Y_INC Y_INC /* left edge direction Y */
+#define T_L_X_INC X_INC /* left edge direction X */
+#define T_R_Y_INC 0x00400000 /* right edge direction Y */
+#define T_R_X_INC 0x00200000 /* right edge direction X */
+
+/* ? */
+#define DSTAGP 0x02000000
+#define DSTVIDEO 0x02000000
+
+/* Line */
+#define LINE_STYLE 0x00800000
+#define NO_RESET_COUNTER 0x00400000
+#define NO_LAST_PIXEL 0x00200000
+
+
+/* Macros to do useful things with the SIS BitBLT engine */
+
+/* BR(16) (0x8240):
+
+ bit 31 2D engine: 1 is idle,
+ bit 30 3D engine: 1 is idle,
+ bit 29 Command queue: 1 is empty
+
+ bits 28:24: Current CPU driven BitBlt buffer stage bit[4:0]
+
+ bits 15:0: Current command queue length (530/620: 12:0)
+
+*/
+
+/* TW: BR(16)+2 = 0x8242 */
+
+#define CmdQueLen pSiS->cmdQueueLen
+
+#define SiSIdle \
+ { \
+ while( (MMIO_IN16(pSiS->IOBase, BR(16)+2) & 0xE000) != 0xE000){}; \
+ while( (MMIO_IN16(pSiS->IOBase, BR(16)+2) & 0xE000) != 0xE000){}; \
+ while( (MMIO_IN16(pSiS->IOBase, BR(16)+2) & 0xE000) != 0xE000){}; \
+ CmdQueLen = (MMIO_IN16(pSiS->IOBase, 0x8240) & pSiS->CmdQueLenMask) - pSiS->CmdQueLenFix; \
+ }
+/* TW: (do three times, because 2D engine seems quite unsure about whether or not it's idle) */
+
+#define SiSSetupSRCBase(base) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, BR(0), base);\
+ CmdQueLen--;
+
+#define SiSSetupSRCPitch(pitch) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT16(pSiS->IOBase, BR(1), pitch);\
+ CmdQueLen--;
+
+#define SiSSetupSRCXY(x,y) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, BR(2), (x)<<16 | (y) );\
+ CmdQueLen--;
+
+#define SiSSetupDSTBase(base) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, BR(4), base);\
+ CmdQueLen--;
+
+#define SiSSetupDSTXY(x,y) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, BR(3), (x)<<16 | (y) );\
+ CmdQueLen--;
+
+#define SiSSetupDSTRect(x,y) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, BR(5), (y)<<16 | (x) );\
+ CmdQueLen--;
+
+#define SiSSetupDSTColorDepth(bpp) \
+ if(pSiS->VGAEngine != SIS_530_VGA) { \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT16(pSiS->IOBase, BR(1)+2, bpp);\
+ CmdQueLen--; \
+ }
+
+#define SiSSetupRect(w,h) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, BR(6), (h)<<16 | (w) );\
+ CmdQueLen--;
+
+#define SiSSetupPATFG(color) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, BR(7), color);\
+ CmdQueLen--;
+
+#define SiSSetupPATBG(color) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, BR(8), color);\
+ CmdQueLen--;
+
+#define SiSSetupSRCFG(color) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, BR(9), color);\
+ CmdQueLen--;
+
+#define SiSSetupSRCBG(color) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, BR(10), color);\
+ CmdQueLen--;
+
+/* 0x8224 src colorkey high */
+/* 0x8228 src colorkey low */
+/* 0x821c dest colorkey high */
+/* 0x8220 dest colorkey low */
+#define SiSSetupSRCTrans(color) \
+ if (CmdQueLen <= 1) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, 0x8224, color);\
+ MMIO_OUT32(pSiS->IOBase, 0x8228, color);\
+ CmdQueLen -= 2;
+
+#define SiSSetupDSTTrans(color) \
+ if (CmdQueLen <= 1) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, 0x821C, color); \
+ MMIO_OUT32(pSiS->IOBase, 0x8220, color); \
+ CmdQueLen -= 2;
+
+#define SiSSetupMONOPAT(p0,p1) \
+ if (CmdQueLen <= 1) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, BR(11), p0);\
+ MMIO_OUT32(pSiS->IOBase, BR(12), p1);\
+ CmdQueLen -= 2;
+
+#define SiSSetupClipLT(left,top) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, BR(13), ((left) & 0xFFFF) | (top)<<16 );\
+ CmdQueLen--;
+
+#define SiSSetupClipRB(right,bottom) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, BR(14), ((right) & 0xFFFF) | (bottom)<<16 );\
+ CmdQueLen--;
+
+/* General */
+#define SiSSetupROP(rop) \
+ pSiS->CommandReg = (rop) << 8;
+
+#define SiSSetupCMDFlag(flags) \
+ pSiS->CommandReg |= (flags);
+
+#define SiSDoCMD \
+ if (CmdQueLen <= 1) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, BR(15), pSiS->CommandReg); \
+ CmdQueLen--; \
+ if(pSiS->VGAEngine != SIS_530_VGA) { \
+ MMIO_OUT32(pSiS->IOBase, BR(16), 0);\
+ CmdQueLen--; \
+ } else { \
+ unsigned long temp; \
+ temp = MMIO_IN32(pSiS->IOBase, BR(16)); \
+ } \
+
+/* Line */
+#define SiSSetupX0Y0(x,y) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, BR(2), (y)<<16 | (x) );\
+ CmdQueLen--;
+
+#define SiSSetupX1Y1(x,y) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, BR(3), (y)<<16 | (x) );\
+ CmdQueLen--;
+
+#define SiSSetupLineCount(c) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT16(pSiS->IOBase, BR(6), c);\
+ CmdQueLen--;
+
+#define SiSSetupStylePeriod(p) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT16(pSiS->IOBase, BR(6)+2, p);\
+ CmdQueLen--;
+
+#define SiSSetupStyleLow(ls) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, BR(11), ls);\
+ CmdQueLen--;
+
+#define SiSSetupStyleHigh(ls) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, BR(12), ls);\
+ CmdQueLen--;
+
+/* TW: Trapezoid */
+#define SiSSetupYH(y,h) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, 0x8208, (y)<<16 | (h) );\
+ CmdQueLen--;
+
+#define SiSSetupLR(left,right) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, 0x820C, (right)<<16 | (left) );\
+ CmdQueLen--;
+
+#define SiSSetupdL(dxL,dyL) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, 0x8244, (dyL)<<16 | (dxL) );\
+ CmdQueLen--;
+
+#define SiSSetupdR(dxR,dyR) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, 0x8248, (dyR)<<16 | (dxR) );\
+ CmdQueLen--;
+
+#define SiSSetupEL(eL) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, 0x824C, eL);\
+ CmdQueLen--;
+
+#define SiSSetupER(eR) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, 0x8250, eR);\
+ CmdQueLen--;
+
diff --git a/src/sis310_accel.c b/src/sis310_accel.c
new file mode 100644
index 0000000..aeee273
--- /dev/null
+++ b/src/sis310_accel.c
@@ -0,0 +1,894 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis310_accel.c,v 1.2 2003/01/29 15:42:16 eich Exp $ */
+/*
+ * 2D Acceleration for SiS 310/325 series (315, 550, 650, 740, M650, 651)
+ *
+ * Copyright 2002 by Thomas Winischhofer, Vienna, Austria
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Thomas Winischhofer not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Thomas Winischhofer makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THOMAS WINISCHHOFER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THOMAS WINISCHHOFER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Based on sis300_accel.c
+ *
+ * Author: Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+#include "compiler.h"
+#include "xaa.h"
+
+#include "sis.h"
+#include "sis310_accel.h"
+
+#ifdef SISDUALHEAD
+/* TW: This is the offset to the memory for each head */
+#define HEADOFFSET (pSiS->dhmOffset)
+#endif
+
+#undef TRAP /* TW: Use/Don't use Trapezoid Fills - does not work - XAA provides
+ * illegal trapezoid data (left and right edges cross each other
+ * sometimes) which causes drawing errors.
+ */
+
+#define CTSCE /* Use/Don't use CPUToScreenColorExpand. */
+
+/* Accelerator functions */
+static void SiSInitializeAccelerator(ScrnInfoPtr pScrn);
+static void SiSSync(ScrnInfoPtr pScrn);
+static void SiSSetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int xdir, int ydir, int rop,
+ unsigned int planemask, int trans_color);
+static void SiSSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int x1, int y1, int x2, int y2,
+ int width, int height);
+static void SiSSetupForSolidFill(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask);
+static void SiSSubsequentSolidFillRect(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h);
+#ifdef TRAP
+static void SiSSubsequentSolidFillTrap(ScrnInfoPtr pScrn, int y, int h,
+ int left, int dxL, int dyL, int eL,
+ int right, int dxR, int dyR, int eR);
+#endif
+static void SiSSetupForSolidLine(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask);
+static void SiSSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, int x1,
+ int y1, int x2, int y2, int flags);
+static void SiSSubsequentSolidHorzVertLine(ScrnInfoPtr pScrn,
+ int x, int y, int len, int dir);
+static void SiSSetupForDashedLine(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop, unsigned int planemask,
+ int length, unsigned char *pattern);
+static void SiSSubsequentDashedTwoPointLine(ScrnInfoPtr pScrn,
+ int x1, int y1, int x2, int y2,
+ int flags, int phase);
+static void SiSSetupForMonoPatternFill(ScrnInfoPtr pScrn,
+ int patx, int paty, int fg, int bg,
+ int rop, unsigned int planemask);
+static void SiSSubsequentMonoPatternFill(ScrnInfoPtr pScrn,
+ int patx, int paty,
+ int x, int y, int w, int h);
+#ifdef TRAP
+static void SiSSubsequentMonoPatternFillTrap(ScrnInfoPtr pScrn,
+ int patx, int paty,
+ int y, int h,
+ int left, int dxL, int dyL, int eL,
+ int right, int dxR, int dyR, int eR);
+#endif
+#ifdef CTSCE
+static void SiSSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask);
+static void SiSSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int skipleft);
+static void SiSSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno);
+#endif
+
+#ifdef SISDUALHEAD
+static void SiSRestoreAccelState(ScrnInfoPtr pScrn);
+#endif
+
+static void
+SiSInitializeAccelerator(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+
+ pSiS->DoColorExpand = FALSE;
+}
+
+Bool
+SiS310AccelInit(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr infoPtr;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ SISPtr pSiS = SISPTR(pScrn);
+ int topFB;
+ int reservedFbSize;
+ int UsableFbSize;
+ unsigned char *AvailBufBase;
+ BoxRec Avail;
+ int i;
+
+ pSiS->AccelInfoPtr = infoPtr = XAACreateInfoRec();
+ if (!infoPtr)
+ return FALSE;
+
+ SiSInitializeAccelerator(pScrn);
+
+ infoPtr->Flags = LINEAR_FRAMEBUFFER |
+ OFFSCREEN_PIXMAPS |
+ PIXMAP_CACHE;
+
+ /* sync */
+ infoPtr->Sync = SiSSync;
+
+ if ((pScrn->bitsPerPixel != 8) && (pScrn->bitsPerPixel != 16) &&
+ (pScrn->bitsPerPixel != 32))
+ return FALSE;
+
+ /* BitBlt */
+ infoPtr->SetupForScreenToScreenCopy = SiSSetupForScreenToScreenCopy;
+ infoPtr->SubsequentScreenToScreenCopy = SiSSubsequentScreenToScreenCopy;
+ infoPtr->ScreenToScreenCopyFlags = NO_PLANEMASK | TRANSPARENCY_GXCOPY_ONLY;
+ /*| NO_TRANSPARENCY; */
+
+ /* solid fills */
+ infoPtr->SetupForSolidFill = SiSSetupForSolidFill;
+ infoPtr->SubsequentSolidFillRect = SiSSubsequentSolidFillRect;
+#ifdef TRAP
+ infoPtr->SubsequentSolidFillTrap = SiSSubsequentSolidFillTrap;
+#endif
+ infoPtr->SolidFillFlags = NO_PLANEMASK;
+
+ /* solid line */
+ infoPtr->SetupForSolidLine = SiSSetupForSolidLine;
+ infoPtr->SubsequentSolidTwoPointLine = SiSSubsequentSolidTwoPointLine;
+ infoPtr->SubsequentSolidHorVertLine = SiSSubsequentSolidHorzVertLine;
+ infoPtr->SolidLineFlags = NO_PLANEMASK;
+
+ /* dashed line */
+ infoPtr->SetupForDashedLine = SiSSetupForDashedLine;
+ infoPtr->SubsequentDashedTwoPointLine = SiSSubsequentDashedTwoPointLine;
+ infoPtr->DashPatternMaxLength = 64;
+ infoPtr->DashedLineFlags = NO_PLANEMASK |
+ LINE_PATTERN_MSBFIRST_LSBJUSTIFIED;
+
+ /* 8x8 mono pattern fill */
+ infoPtr->SetupForMono8x8PatternFill = SiSSetupForMonoPatternFill;
+ infoPtr->SubsequentMono8x8PatternFillRect = SiSSubsequentMonoPatternFill;
+#ifdef TRAP
+ infoPtr->SubsequentMono8x8PatternFillTrap = SiSSubsequentMonoPatternFillTrap;
+#endif
+ infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK |
+ HARDWARE_PATTERN_SCREEN_ORIGIN |
+ HARDWARE_PATTERN_PROGRAMMED_BITS |
+ NO_TRANSPARENCY |
+ BIT_ORDER_IN_BYTE_MSBFIRST ;
+
+#if 0
+ /* Screen To Screen Color Expand */
+ /* TW: The hardware does not seem to support this the way we need it */
+ infoPtr->SetupForScreenToScreenColorExpandFill =
+ SiSSetupForScreenToScreenColorExpand;
+ infoPtr->SubsequentScreenToScreenColorExpandFill =
+ SiSSubsequentScreenToScreenColorExpand;
+ infoPtr->ScreenToScreenColorExpandFillFlags = NO_PLANEMASK |
+ BIT_ORDER_IN_BYTE_MSBFIRST ;
+#endif
+
+ /* per-scanline color expansion - indirect method */
+ pSiS->ColorExpandBufferNumber = 16;
+ pSiS->ColorExpandBufferCountMask = 0x0F;
+ pSiS->PerColorExpandBufferSize = ((pScrn->virtualX + 31)/32) * 4;
+#ifdef CTSCE
+ infoPtr->NumScanlineColorExpandBuffers = pSiS->ColorExpandBufferNumber;
+ infoPtr->ScanlineColorExpandBuffers = (unsigned char **)&pSiS->ColorExpandBufferAddr[0];
+ infoPtr->SetupForScanlineCPUToScreenColorExpandFill = SiSSetupForScanlineCPUToScreenColorExpandFill;
+ infoPtr->SubsequentScanlineCPUToScreenColorExpandFill = SiSSubsequentScanlineCPUToScreenColorExpandFill;
+ infoPtr->SubsequentColorExpandScanline = SiSSubsequentColorExpandScanline;
+ infoPtr->ScanlineCPUToScreenColorExpandFillFlags =
+ NO_PLANEMASK |
+ CPU_TRANSFER_PAD_DWORD |
+ SCANLINE_PAD_DWORD |
+ BIT_ORDER_IN_BYTE_MSBFIRST |
+ LEFT_EDGE_CLIPPING;
+#endif
+
+#ifdef SISDUALHEAD
+ if (pSiS->DualHeadMode) {
+ infoPtr->RestoreAccelState = SiSRestoreAccelState;
+ }
+#endif
+
+ /* init Frame Buffer Manager */
+
+ topFB = pSiS->maxxfbmem;
+
+ reservedFbSize = (pSiS->ColorExpandBufferNumber
+ * pSiS->PerColorExpandBufferSize);
+ /* TW: New for MaxXFBmem Option */
+ UsableFbSize = topFB - reservedFbSize;
+ /* Layout:
+ * |--------------++++++++++++++++++++^************==========~~~~~~~~~~~~|
+ * UsableFbSize ColorExpandBuffers | DRI-Heap HWCursor CommandQueue
+ * topFB
+ */
+ AvailBufBase = pSiS->FbBase + UsableFbSize;
+ for (i = 0; i < pSiS->ColorExpandBufferNumber; i++) {
+ pSiS->ColorExpandBufferAddr[i] = AvailBufBase +
+ i * pSiS->PerColorExpandBufferSize;
+ pSiS->ColorExpandBufferScreenOffset[i] = UsableFbSize +
+ i * pSiS->PerColorExpandBufferSize;
+ }
+ Avail.x1 = 0;
+ Avail.y1 = 0;
+ Avail.x2 = pScrn->displayWidth;
+ Avail.y2 = UsableFbSize
+ / (pScrn->displayWidth * pScrn->bitsPerPixel/8) - 1;
+ if (Avail.y2 < 0)
+ Avail.y2 = 32767;
+ if (Avail.y2 < pScrn->currentMode->VDisplay) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Not enough video RAM for accelerator. At least "
+ "%dKB needed, %dKB available\n",
+ ((((pScrn->displayWidth * pScrn->bitsPerPixel/8) /* TW: +8 for make it sure */
+ * pScrn->currentMode->VDisplay) + reservedFbSize) / 1024) + 8,
+ pSiS->maxxfbmem/1024);
+ pSiS->NoAccel = TRUE;
+ pSiS->NoXvideo = TRUE;
+ XAADestroyInfoRec(pSiS->AccelInfoPtr);
+ pSiS->AccelInfoPtr = NULL;
+ return FALSE;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Frame Buffer From (%d,%d) To (%d,%d)\n",
+ Avail.x1, Avail.y1, Avail.x2, Avail.y2);
+
+ xf86InitFBManager(pScreen, &Avail);
+
+ return(XAAInit(pScreen, infoPtr));
+}
+
+static void
+SiSSync(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+
+ PDEBUG(ErrorF("SiSSync()\n"));
+
+ pSiS->DoColorExpand = FALSE;
+ SiSIdle
+}
+
+#ifdef SISDUALHEAD
+static void
+SiSRestoreAccelState(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+
+ /* TW: We don't need to do anything special here */
+ pSiS->DoColorExpand = FALSE;
+ SiSIdle
+}
+#endif
+
+static const int sisALUConv[] =
+{
+ 0x00, /* dest = 0; 0, GXclear, 0 */
+ 0x88, /* dest &= src; DSa, GXand, 0x1 */
+ 0x44, /* dest = src & ~dest; SDna, GXandReverse, 0x2 */
+ 0xCC, /* dest = src; S, GXcopy, 0x3 */
+ 0x22, /* dest &= ~src; DSna, GXandInverted, 0x4 */
+ 0xAA, /* dest = dest; D, GXnoop, 0x5 */
+ 0x66, /* dest = ^src; DSx, GXxor, 0x6 */
+ 0xEE, /* dest |= src; DSo, GXor, 0x7 */
+ 0x11, /* dest = ~src & ~dest; DSon, GXnor, 0x8 */
+ 0x99, /* dest ^= ~src ; DSxn, GXequiv, 0x9 */
+ 0x55, /* dest = ~dest; Dn, GXInvert, 0xA */
+ 0xDD, /* dest = src|~dest ; SDno, GXorReverse, 0xB */
+ 0x33, /* dest = ~src; Sn, GXcopyInverted, 0xC */
+ 0xBB, /* dest |= ~src; DSno, GXorInverted, 0xD */
+ 0x77, /* dest = ~src|~dest; DSan, GXnand, 0xE */
+ 0xFF, /* dest = 0xFF; 1, GXset, 0xF */
+};
+/* same ROP but with Pattern as Source */
+static const int sisPatALUConv[] =
+{
+ 0x00, /* dest = 0; 0, GXclear, 0 */
+ 0xA0, /* dest &= src; DPa, GXand, 0x1 */
+ 0x50, /* dest = src & ~dest; PDna, GXandReverse, 0x2 */
+ 0xF0, /* dest = src; P, GXcopy, 0x3 */
+ 0x0A, /* dest &= ~src; DPna, GXandInverted, 0x4 */
+ 0xAA, /* dest = dest; D, GXnoop, 0x5 */
+ 0x5A, /* dest = ^src; DPx, GXxor, 0x6 */
+ 0xFA, /* dest |= src; DPo, GXor, 0x7 */
+ 0x05, /* dest = ~src & ~dest; DPon, GXnor, 0x8 */
+ 0xA5, /* dest ^= ~src ; DPxn, GXequiv, 0x9 */
+ 0x55, /* dest = ~dest; Dn, GXInvert, 0xA */
+ 0xF5, /* dest = src|~dest ; PDno, GXorReverse, 0xB */
+ 0x0F, /* dest = ~src; Pn, GXcopyInverted, 0xC */
+ 0xAF, /* dest |= ~src; DPno, GXorInverted, 0xD */
+ 0x5F, /* dest = ~src|~dest; DPan, GXnand, 0xE */
+ 0xFF, /* dest = 0xFF; 1, GXset, 0xF */
+};
+
+static void SiSSetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int xdir, int ydir, int rop,
+ unsigned int planemask, int trans_color)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+
+ PDEBUG(ErrorF("Setup ScreenCopy(%d, %d, 0x%x, 0x%x, 0x%x)\n",
+ xdir, ydir, rop, planemask, trans_color));
+
+ /* "AGP base" - color depth depending value (see sis_vga.c) */
+ SiSSetupDSTColorDepth(pSiS->DstColor);
+ /* SRC pitch */
+ SiSSetupSRCPitch(pSiS->scrnOffset)
+ /* DST pitch and height (-1 for disabling merge-clipping) */
+ SiSSetupDSTRect(pSiS->scrnOffset, -1)
+ /* Init CommandReg and set ROP */
+ if (trans_color != -1) {
+ SiSSetupROP(0x0A)
+ SiSSetupSRCTrans(trans_color)
+ SiSSetupCMDFlag(TRANSPARENT_BITBLT)
+ } else {
+ SiSSetupROP(sisALUConv[rop])
+ /* Set command - not needed, both 0 */
+ /* SiSSetupCMDFlag(BITBLT | SRCVIDEO) */
+ }
+ /* Set some color depth depending value (see sis_vga.c) */
+ SiSSetupCMDFlag(pSiS->SiS310_AccelDepth)
+
+ /* TW: The 310/325 series is smart enough to know the direction */
+}
+
+static void SiSSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int src_x, int src_y, int dst_x, int dst_y,
+ int width, int height)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ long srcbase, dstbase;
+
+ PDEBUG(ErrorF("Subsequent ScreenCopy(%d,%d, %d,%d, %d,%d)\n",
+ src_x, src_y, dst_x, dst_y, width, height));
+
+ srcbase = dstbase = 0;
+ if (src_y >= 2048) {
+ srcbase = pSiS->scrnOffset * src_y;
+ src_y = 0;
+ }
+ if ((dst_y >= pScrn->virtualY) || (dst_y >= 2048)) {
+ dstbase = pSiS->scrnOffset*dst_y;
+ dst_y = 0;
+ }
+#ifdef SISDUALHEAD
+ srcbase += HEADOFFSET;
+ dstbase += HEADOFFSET;
+#endif
+ SiSSetupSRCBase(srcbase);
+ SiSSetupDSTBase(dstbase);
+ SiSSetupRect(width, height)
+ SiSSetupSRCXY(src_x, src_y)
+ SiSSetupDSTXY(dst_x, dst_y)
+ SiSDoCMD
+}
+
+static void
+SiSSetupForSolidFill(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+
+ PDEBUG(ErrorF("Setup SolidFill(0x%x, 0x%x, 0x%x)\n",
+ color, rop, planemask));
+
+ SiSSetupPATFG(color)
+ SiSSetupDSTRect(pSiS->scrnOffset, -1)
+ SiSSetupDSTColorDepth(pSiS->DstColor);
+ SiSSetupROP(sisPatALUConv[rop])
+ SiSSetupCMDFlag(PATFG | pSiS->SiS310_AccelDepth)
+}
+
+static void
+SiSSubsequentSolidFillRect(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ long dstbase;
+
+ PDEBUG(ErrorF("Subsequent SolidFillRect(%d, %d, %d, %d)\n",
+ x, y, w, h));
+ dstbase = 0;
+ if (y >= 2048) {
+ dstbase=pSiS->scrnOffset*y;
+ y = 0;
+ }
+#ifdef SISDUALHEAD
+ dstbase += HEADOFFSET;
+#endif
+ SiSSetupDSTBase(dstbase)
+ SiSSetupDSTXY(x,y)
+ SiSSetupRect(w,h)
+ pSiS->CommandReg &= ~(T_XISMAJORL | T_XISMAJORR |
+ T_L_X_INC | T_L_Y_INC |
+ T_R_X_INC | T_R_Y_INC |
+ TRAPAZOID_FILL);
+ SiSSetupCMDFlag(BITBLT)
+ SiSDoCMD
+}
+
+/* TW: Trapezoid */
+/* This would work better if XAA would provide us with valid trapezoids.
+ * In fact, with small trapezoids the left and the right edge often cross
+ * each other which causes drawing errors (filling over whole scanline).
+ */
+#ifdef TRAP
+static void
+SiSSubsequentSolidFillTrap(ScrnInfoPtr pScrn, int y, int h,
+ int left, int dxL, int dyL, int eL,
+ int right, int dxR, int dyR, int eR )
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ long dstbase;
+#if 0
+ float kL, kR;
+#endif
+
+ dstbase = 0;
+ if (y >= 2048) {
+ dstbase=pSiS->scrnOffset*y;
+ y = 0;
+ }
+#ifdef SISDUALHEAD
+ dstbase += HEADOFFSET;
+#endif
+ SiSSetupDSTBase(dstbase)
+
+#if 1
+ SiSSetupPATFG(0xff0000) /* FOR TESTING */
+#endif
+
+ /* Clear CommandReg because SetUp can be used for Rect and Trap */
+ pSiS->CommandReg &= ~(T_L_X_INC | T_L_Y_INC |
+ T_R_X_INC | T_R_Y_INC |
+ T_XISMAJORL | T_XISMAJORR |
+ BITBLT);
+
+ xf86DrvMsg(0, X_INFO, "Trap (%d %d %d %d) dxL %d dyL %d eL %d dxR %d dyR %d eR %d\n",
+ left, right, y, h, dxL, dyL, eL, dxR, dyR, eR);
+
+ /* Unfortunately, we must check if the right and the left edge
+ * cross each other... INCOMPLETE (equation wrong)
+ */
+#if 0
+ if (dxL == 0) kL = 0;
+ else kL = (float)dyL / (float)dxL;
+ if (dxR == 0) kR = 0;
+ else kR = (float)dyR / (float)dxR;
+ xf86DrvMsg(0, X_INFO, "kL %f kR %f!\n", kL, kR);
+ if ( (kR != kL) &&
+ (!(kR == 0 && kL == 0)) &&
+ (!(kR < 0 && kL > 0)) ) {
+ xf86DrvMsg(0, X_INFO, "Inside if (%f - %d)\n", ( kL * ( ( ((float)right - (float)left) / (kL - kR) ) - left) + y), h+y);
+ if ( ( ( kL * ( ( ((float)right - (float)left) / (kL - kR) ) - (float)left) + (float)y) < (h + y) ) ) {
+ xf86DrvMsg(0, X_INFO, "Cross detected!\n");
+ }
+ }
+#endif
+
+ /* Determine egde angles */
+ if (dxL < 0) { dxL = -dxL; }
+ else { SiSSetupCMDFlag(T_L_X_INC) }
+ if (dxR < 0) { dxR = -dxR; }
+ else { SiSSetupCMDFlag(T_R_X_INC) }
+
+ /* (Y direction always positive - do this anyway) */
+ if (dyL < 0) { dyL = -dyL; }
+ else { SiSSetupCMDFlag(T_L_Y_INC) }
+ if (dyR < 0) { dyR = -dyR; }
+ else { SiSSetupCMDFlag(T_R_Y_INC) }
+
+ /* Determine major axis */
+ if (dxL >= dyL) { /* X is major axis */
+ SiSSetupCMDFlag(T_XISMAJORL)
+ }
+ if (dxR >= dyR) { /* X is major axis */
+ SiSSetupCMDFlag(T_XISMAJORR)
+ }
+
+ /* Set up deltas */
+ SiSSetupdL(dxL, dyL)
+ SiSSetupdR(dxR, dyR)
+
+ /* Set up y, h, left, right */
+ SiSSetupYH(y,h)
+ SiSSetupLR(left,right)
+
+ /* Set up initial error term */
+ SiSSetupEL(eL)
+ SiSSetupER(eR)
+
+ SiSSetupCMDFlag(TRAPAZOID_FILL);
+
+ SiSDoCMD
+}
+#endif
+
+static void
+SiSSetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned int planemask)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+
+ PDEBUG(ErrorF("Setup SolidLine(0x%x, 0x%x, 0x%x)\n",
+ color, rop, planemask));
+
+ SiSSetupLineCount(1)
+ SiSSetupPATFG(color)
+ SiSSetupDSTRect(pSiS->scrnOffset, -1)
+ SiSSetupDSTColorDepth(pSiS->DstColor);
+ SiSSetupROP(sisPatALUConv[rop])
+ SiSSetupCMDFlag(PATFG | LINE | pSiS->SiS310_AccelDepth)
+}
+
+static void
+SiSSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn,
+ int x1, int y1, int x2, int y2, int flags)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ long dstbase,miny,maxy;
+
+ PDEBUG(ErrorF("Subsequent SolidLine(%d, %d, %d, %d, 0x%x)\n",
+ x1, y1, x2, y2, flags));
+
+ dstbase = 0;
+ miny = (y1 > y2) ? y2 : y1;
+ maxy = (y1 > y2) ? y1 : y2;
+ if (maxy >= 2048) {
+ dstbase = pSiS->scrnOffset*miny;
+ y1 -= miny;
+ y2 -= miny;
+ }
+#ifdef SISDUALHEAD
+ dstbase += HEADOFFSET;
+#endif
+ SiSSetupDSTBase(dstbase)
+
+ SiSSetupX0Y0(x1,y1)
+ SiSSetupX1Y1(x2,y2)
+ if (flags & OMIT_LAST) {
+ SiSSetupCMDFlag(NO_LAST_PIXEL)
+ } else {
+ pSiS->CommandReg &= ~(NO_LAST_PIXEL);
+ }
+ SiSDoCMD
+}
+
+static void
+SiSSubsequentSolidHorzVertLine(ScrnInfoPtr pScrn,
+ int x, int y, int len, int dir)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ long dstbase;
+
+ PDEBUG(ErrorF("Subsequent SolidHorzVertLine(%d, %d, %d, %d)\n",
+ x, y, len, dir));
+
+ len--; /* starting point is included! */
+ dstbase = 0;
+ if ((y >= 2048) || ((y + len) >= 2048)) {
+ dstbase = pSiS->scrnOffset * y;
+ y = 0;
+ }
+#ifdef SISDUALHEAD
+ dstbase += HEADOFFSET;
+#endif
+ SiSSetupDSTBase(dstbase)
+
+ SiSSetupX0Y0(x,y)
+ if (dir == DEGREES_0) {
+ SiSSetupX1Y1(x + len, y);
+ } else {
+ SiSSetupX1Y1(x, y + len);
+ }
+ SiSDoCMD
+}
+
+static void
+SiSSetupForDashedLine(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop, unsigned int planemask,
+ int length, unsigned char *pattern)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+
+ PDEBUG(ErrorF("Setup DashedLine(0x%x, 0x%x, 0x%x, 0x%x, %d, 0x%x:%x)\n",
+ fg, bg, rop, planemask, length, *(pattern+4), *pattern));
+
+ SiSSetupLineCount(1)
+ SiSSetupDSTRect(pSiS->scrnOffset, -1)
+ SiSSetupDSTColorDepth(pSiS->DstColor);
+ SiSSetupStyleLow(*pattern)
+ SiSSetupStyleHigh(*(pattern+4))
+ SiSSetupStylePeriod(length-1); /* TW: This was missing!!! */
+ SiSSetupROP(sisPatALUConv[rop])
+ SiSSetupPATFG(fg)
+ SiSSetupCMDFlag(LINE | LINE_STYLE) /* TW: This was missing!!! */
+ if (bg != -1) {
+ SiSSetupPATBG(bg)
+ } else {
+ SiSSetupCMDFlag(TRANSPARENT) /* TW: This was missing!!! */
+ }
+ SiSSetupCMDFlag(pSiS->SiS310_AccelDepth)
+}
+
+static void
+SiSSubsequentDashedTwoPointLine(ScrnInfoPtr pScrn,
+ int x1, int y1, int x2, int y2,
+ int flags, int phase)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ long dstbase,miny,maxy;
+
+ PDEBUG(ErrorF("Subsequent DashedLine(%d,%d, %d,%d, 0x%x,0x%x)\n",
+ x1, y1, x2, y2, flags, phase));
+
+ dstbase = 0;
+ miny=(y1 > y2) ? y2 : y1;
+ maxy=(y1 > y2) ? y1 : y2;
+ if (maxy >= 2048) {
+ dstbase = pSiS->scrnOffset * miny;
+ y1 -= miny;
+ y2 -= miny;
+ }
+#ifdef SISDUALHEAD
+ dstbase += HEADOFFSET;
+#endif
+ SiSSetupDSTBase(dstbase)
+
+ SiSSetupX0Y0(x1,y1)
+ SiSSetupX1Y1(x2,y2)
+ if (flags & OMIT_LAST) {
+ SiSSetupCMDFlag(NO_LAST_PIXEL)
+ } else {
+ pSiS->CommandReg &= ~(NO_LAST_PIXEL);
+ }
+ SiSDoCMD
+}
+
+static void
+SiSSetupForMonoPatternFill(ScrnInfoPtr pScrn,
+ int patx, int paty, int fg, int bg,
+ int rop, unsigned int planemask)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+
+ PDEBUG(ErrorF("Setup MonoPatFill(0x%x,0x%x, 0x%x,0x%x, 0x%x, 0x%x)\n",
+ patx, paty, fg, bg, rop, planemask));
+ SiSSetupDSTRect(pSiS->scrnOffset, -1)
+ SiSSetupDSTColorDepth(pSiS->DstColor);
+ SiSSetupMONOPAT(patx,paty)
+ SiSSetupPATFG(fg)
+ SiSSetupROP(sisPatALUConv[rop])
+ SiSSetupCMDFlag(PATMONO | pSiS->SiS310_AccelDepth)
+ SiSSetupPATBG(bg)
+}
+
+static void
+SiSSubsequentMonoPatternFill(ScrnInfoPtr pScrn,
+ int patx, int paty,
+ int x, int y, int w, int h)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ long dstbase;
+
+ PDEBUG(ErrorF("Subsequent MonoPatFill(0x%x,0x%x, %d,%d, %d,%d)\n",
+ patx, paty, x, y, w, h));
+ dstbase = 0;
+ if (y >= 2048) {
+ dstbase = pSiS->scrnOffset * y;
+ y = 0;
+ }
+#ifdef SISDUALHEAD
+ dstbase += HEADOFFSET;
+#endif
+ SiSSetupDSTBase(dstbase)
+ SiSSetupDSTXY(x,y)
+ SiSSetupRect(w,h)
+ /* Clear commandReg because Setup can be used for Rect and Trap */
+ pSiS->CommandReg &= ~(T_XISMAJORL | T_XISMAJORR |
+ T_L_X_INC | T_L_Y_INC |
+ T_R_X_INC | T_R_Y_INC |
+ TRAPAZOID_FILL);
+ SiSDoCMD
+}
+
+/* TW: Trapezoid */
+#ifdef TRAP
+static void
+SiSSubsequentMonoPatternFillTrap(ScrnInfoPtr pScrn,
+ int patx, int paty,
+ int y, int h,
+ int left, int dxL, int dyL, int eL,
+ int right, int dxR, int dyR, int eR)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ long dstbase;
+
+ PDEBUG(ErrorF("Subsequent Mono8x8PatternFillTrap(%d, %d, %d - %d %d/%d %d/%d)\n",
+ y, h, left, right, dxL, dxR, eL, eR));
+
+ dstbase = 0;
+ if (y >= 2048) {
+ dstbase=pSiS->scrnOffset*y;
+ y = 0;
+ }
+#ifdef SISDUALHEAD
+ dstbase += HEADOFFSET;
+#endif
+ SiSSetupDSTBase(dstbase)
+
+ /* Clear CommandReg because SetUp can be used for Rect and Trap */
+ pSiS->CommandReg &= ~(T_XISMAJORL | T_XISMAJORR |
+ T_L_X_INC | T_L_Y_INC |
+ T_R_X_INC | T_R_Y_INC |
+ BITBLT);
+
+ if (dxL < 0) { dxL = -dxL; }
+ else { SiSSetupCMDFlag(T_L_X_INC) }
+ if (dxR < 0) { dxR = -dxR; }
+ else { SiSSetupCMDFlag(T_R_X_INC) }
+
+ if (dyL < 0) { dyL = -dyL; }
+ else { SiSSetupCMDFlag(T_L_Y_INC) }
+ if (dyR < 0) { dyR = -dyR; }
+ else { SiSSetupCMDFlag(T_R_Y_INC) }
+
+ /* Determine major axis */
+ if (dxL >= dyL) { /* X is major axis */
+ SiSSetupCMDFlag(T_XISMAJORL)
+ }
+ if (dxR >= dyR) { /* X is major axis */
+ SiSSetupCMDFlag(T_XISMAJORR)
+ }
+
+ SiSSetupYH(y,h)
+ SiSSetupLR(left,right)
+
+ SiSSetupdL(dxL, dyL)
+ SiSSetupdR(dxR, dyR)
+
+ SiSSetupEL(eL)
+ SiSSetupER(eR)
+
+ SiSSetupCMDFlag(TRAPAZOID_FILL);
+
+ SiSDoCMD
+}
+#endif
+
+/* ---- CPUToScreen Color Expand */
+
+#ifdef CTSCE
+/* We use the indirect method */
+static void
+SiSSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop, unsigned int planemask)
+{
+ SISPtr pSiS=SISPTR(pScrn);
+
+ /* TW: FIXME: How do I check the "CPU driven blit stage" on the
+ * 310/325 series?
+ * That's the 300 series method but definitely wrong for
+ * 310/325 series (bit 28 is already used for idle!)
+ */
+ /* while ((MMIO_IN16(pSiS->IOBase, Q_STATUS+2) & 0x1F00) != 0) {} */
+
+ /* TW: Do Idle instead... */
+ SiSIdle
+
+ SiSSetupSRCXY(0,0);
+ SiSSetupROP(sisALUConv[rop]);
+ SiSSetupSRCFG(fg);
+ SiSSetupDSTRect(pSiS->scrnOffset, -1);
+ SiSSetupDSTColorDepth(pSiS->DstColor);
+ if (bg == -1) {
+ SiSSetupCMDFlag(TRANSPARENT | ENCOLOREXP | SRCCPUBLITBUF
+ | pSiS->SiS310_AccelDepth);
+ } else {
+ SiSSetupSRCBG(bg);
+ SiSSetupCMDFlag(ENCOLOREXP | SRCCPUBLITBUF
+ | pSiS->SiS310_AccelDepth);
+ };
+}
+
+static void
+SiSSubsequentScanlineCPUToScreenColorExpandFill(
+ ScrnInfoPtr pScrn, int x, int y, int w,
+ int h, int skipleft)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int _x0, _y0, _x1, _y1;
+ long dstbase;
+
+ dstbase = 0;
+ if (y >= 2048) {
+ dstbase = pSiS->scrnOffset*y;
+ y = 0;
+ }
+#ifdef SISDUALHEAD
+ dstbase += HEADOFFSET;
+#endif
+
+ if((MMIO_IN16(pSiS->IOBase, Q_STATUS+2) & 0x8000) != 0x8000) {
+ SiSIdle;
+ }
+
+ SiSSetupDSTBase(dstbase)
+
+ if (skipleft > 0) {
+ _x0 = x+skipleft;
+ _y0 = y;
+ _x1 = x+w;
+ _y1 = y+h;
+ SiSSetupClipLT(_x0, _y0);
+ SiSSetupClipRB(_x1, _y1);
+ SiSSetupCMDFlag(CLIPENABLE);
+ } else {
+ pSiS->CommandReg &= (~CLIPENABLE);
+ }
+ SiSSetupRect(w, 1);
+ SiSSetupSRCPitch(((((w+7)/8)+3) >> 2) * 4);
+ pSiS->ycurrent = y;
+ pSiS->xcurrent = x;
+}
+
+static void
+SiSSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
+{
+ SISPtr pSiS=SISPTR(pScrn);
+ long cbo;
+
+ cbo = pSiS->ColorExpandBufferScreenOffset[bufno];
+#ifdef SISDUALHEAD
+ cbo += HEADOFFSET;
+#endif
+
+ if((MMIO_IN16(pSiS->IOBase, Q_STATUS+2) & 0x8000) != 0x8000) {
+ SiSIdle;
+ }
+
+ SiSSetupSRCBase(cbo);
+
+ SiSSetupDSTXY(pSiS->xcurrent, pSiS->ycurrent);
+
+ SiSDoCMD
+
+ pSiS->ycurrent++;
+
+ SiSIdle
+}
+#endif
+
+
diff --git a/src/sis310_accel.h b/src/sis310_accel.h
new file mode 100644
index 0000000..9a6b20a
--- /dev/null
+++ b/src/sis310_accel.h
@@ -0,0 +1,341 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis310_accel.h,v 1.2 2003/01/29 15:42:16 eich Exp $ */
+/*
+ * Copyright 2002 by Thomas Winischhofer, Vienna, Austria
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Thomas Winischhofer not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Thomas Winischhofer makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THOMAS WINISCHHOFER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THOMAS WINISCHHOFER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Based on sis300_accel.h
+ *
+ * Author: Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ */
+
+/* Definitions for the SIS engine communication. */
+
+
+/* SiS310 engine commands */
+#define BITBLT 0x00000000 /* Blit */
+#define COLOREXP 0x00000001 /* Color expand */
+#define ENCOLOREXP 0x00000002 /* Enhanced color expand */
+#define MULTIPLE_SCANLINE 0x00000003 /* ? */
+#define LINE 0x00000004 /* Draw line */
+#define TRAPAZOID_FILL 0x00000005 /* Fill trapezoid */
+#define TRANSPARENT_BITBLT 0x00000006 /* Transparent Blit */
+#define ALPHA_BLEND 0x00000007 /* Alpha blend ? */
+#define A3D_FUNCTION 0x00000008 /* 3D command ? */
+#define CLEAR_Z_BUFFER 0x00000009 /* ? */
+#define GRADIENT_FILL 0x0000000A /* Gradient fill */
+#define STRETCH_BITBLT 0x0000000B /* Stretched Blit */
+
+/* Command bits */
+
+/* Source selection */
+#define SRCVIDEO 0x00000000 /* source is video RAM */
+#define SRCSYSTEM 0x00000010 /* source is system memory */
+#define SRCCPUBLITBUF SRCSYSTEM /* source is CPU-driven BitBuffer (for color expand) */
+#define SRCAGP 0x00000020 /* source is AGP memory (?) */
+
+/* Pattern source selection */
+#define PATFG 0x00000000 /* foreground color */
+#define PATPATREG 0x00000040 /* pattern in pattern buffer (0x8300) */
+#define PATMONO 0x00000080 /* mono pattern */
+
+/* Clipping flags */
+#define NOCLIP 0x00000000
+#define NOMERGECLIP 0x04000000
+#define CLIPENABLE 0x00040000
+#define CLIPWITHOUTMERGE 0x04040000
+
+/* Transparency */
+#define OPAQUE 0x00000000
+#define TRANSPARENT 0x00100000
+
+/* ? */
+#define DSTAGP 0x02000000
+#define DSTVIDEO 0x02000000
+
+/* Subfunctions for Color/Enhanced Color Expansion */
+#define COLOR_TO_MONO 0x00100000
+#define AA_TEXT 0x00200000
+
+/* Line */
+#define LINE_STYLE 0x00800000
+#define NO_RESET_COUNTER 0x00400000
+#define NO_LAST_PIXEL 0x00200000
+
+/* Trapezoid */
+#define T_XISMAJORL 0x00800000 /* X axis is driving axis (left) */
+#define T_XISMAJORR 0x08000000 /* X axis is driving axis (right) */
+#define T_L_Y_INC 0x00000020 /* left edge direction Y */
+#define T_L_X_INC 0x00000010 /* left edge direction X */
+#define T_R_Y_INC 0x00400000 /* right edge direction Y */
+#define T_R_X_INC 0x00200000 /* right edge direction X */
+
+/* Some general registers */
+#define SRC_ADDR 0x8200
+#define SRC_PITCH 0x8204
+#define AGP_BASE 0x8206 /* color-depth dependent value */
+#define SRC_Y 0x8208
+#define SRC_X 0x820A
+#define DST_Y 0x820C
+#define DST_X 0x820E
+#define DST_ADDR 0x8210
+#define DST_PITCH 0x8214
+#define DST_HEIGHT 0x8216
+#define RECT_WIDTH 0x8218
+#define RECT_HEIGHT 0x821A
+#define PAT_FGCOLOR 0x821C
+#define PAT_BGCOLOR 0x8220
+#define SRC_FGCOLOR 0x8224
+#define SRC_BGCOLOR 0x8228
+#define MONO_MASK 0x822C
+#define LEFT_CLIP 0x8234
+#define TOP_CLIP 0x8236
+#define RIGHT_CLIP 0x8238
+#define BOTTOM_CLIP 0x823A
+#define COMMAND_READY 0x823C
+#define FIRE_TRIGGER 0x8240
+
+#define PATTERN_REG 0x8300 /* 384 bytes pattern buffer */
+
+/* Line registers */
+#define LINE_X0 SRC_Y
+#define LINE_X1 DST_Y
+#define LINE_Y0 SRC_X
+#define LINE_Y1 DST_X
+#define LINE_COUNT RECT_WIDTH
+#define LINE_STYLE_PERIOD RECT_HEIGHT
+#define LINE_STYLE_0 MONO_MASK
+#define LINE_STYLE_1 0x8230
+#define LINE_XN PATTERN_REG
+#define LINE_YN PATTERN_REG+2
+
+/* Transparent bitblit registers */
+#define TRANS_DST_KEY_HIGH PAT_FGCOLOR
+#define TRANS_DST_KEY_LOW PAT_BGCOLOR
+#define TRANS_SRC_KEY_HIGH SRC_FGCOLOR
+#define TRANS_SRC_KEY_LOW SRC_BGCOLOR
+
+/* Trapezoid registers */
+#define TRAP_YH SRC_Y /* 0x8208 */
+#define TRAP_LR DST_Y /* 0x820C */
+#define TRAP_DL 0x8244
+#define TRAP_DR 0x8248
+#define TRAP_EL 0x824C
+#define TRAP_ER 0x8250
+
+/* Queue */
+#define Q_BASE_ADDR 0x85C0 /* Base address of software queue (?) */
+#define Q_WRITE_PTR 0x85C4 /* Current write pointer (?) */
+#define Q_READ_PTR 0x85C8 /* Current read pointer (?) */
+#define Q_STATUS 0x85CC /* queue status */
+
+/* Macros to do useful things with the SIS 310 BitBLT engine */
+
+/* Q_STATUS:
+ bit 31 = 1: All engines idle and all queues empty
+ bit 30 = 1: Hardware Queue (=HW CQ, 2D queue, 3D queue) empty
+ bit 29 = 1: 2D engine is idle
+ bit 28 = 1: 3D engine is idle
+ bit 27 = 1: HW command queue empty
+ bit 26 = 1: 2D queue empty
+ bit 25 = 1: 3D queue empty
+ bit 24 = 1: SW command queue empty
+ bits 23:16: 2D counter 3
+ bits 15:8: 2D counter 2
+ bits 7:0: 2D counter 1
+
+ Where is the command queue length (current amount of commands the queue
+ can accept) on the 310 series? (The current implementation is taken
+ from 300 series and certainly wrong...)
+*/
+
+int CmdQueLen;
+
+/* TW: FIXME: CmdQueLen is... where....? */
+#define SiSIdle \
+ { \
+ while( (MMIO_IN16(pSiS->IOBase, Q_STATUS+2) & 0x8000) != 0x8000){}; \
+ while( (MMIO_IN16(pSiS->IOBase, Q_STATUS+2) & 0x8000) != 0x8000){}; \
+ CmdQueLen=MMIO_IN16(pSiS->IOBase, Q_STATUS); \
+ }
+ /* TW: (do twice like on 300 series?) */
+
+#define SiSSetupSRCBase(base) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, SRC_ADDR, base);\
+ CmdQueLen--;
+
+#define SiSSetupSRCPitch(pitch) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT16(pSiS->IOBase, SRC_PITCH, pitch);\
+ CmdQueLen--;
+
+#define SiSSetupSRCXY(x,y) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, SRC_Y, (x)<<16 | (y) );\
+ CmdQueLen--;
+
+#define SiSSetupDSTBase(base) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, DST_ADDR, base);\
+ CmdQueLen--;
+
+#define SiSSetupDSTXY(x,y) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, DST_Y, (x)<<16 | (y) );\
+ CmdQueLen--;
+
+#define SiSSetupDSTRect(x,y) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, DST_PITCH, (y)<<16 | (x) );\
+ CmdQueLen--;
+
+#define SiSSetupDSTColorDepth(bpp) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT16(pSiS->IOBase, AGP_BASE, bpp);\
+ CmdQueLen--;
+
+#define SiSSetupRect(w,h) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, RECT_WIDTH, (h)<<16 | (w) );\
+ CmdQueLen--;
+
+#define SiSSetupPATFG(color) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, PAT_FGCOLOR, color);\
+ CmdQueLen--;
+
+#define SiSSetupPATBG(color) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, PAT_BGCOLOR, color);\
+ CmdQueLen--;
+
+#define SiSSetupSRCFG(color) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, SRC_FGCOLOR, color);\
+ CmdQueLen--;
+
+#define SiSSetupSRCBG(color) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, SRC_BGCOLOR, color);\
+ CmdQueLen--;
+
+#define SiSSetupSRCTrans(color) \
+ if (CmdQueLen <= 1) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, TRANS_SRC_KEY_HIGH, color);\
+ MMIO_OUT32(pSiS->IOBase, TRANS_SRC_KEY_LOW, color);\
+ CmdQueLen -= 2;
+
+#define SiSSetupDSTTrans(color) \
+ if (CmdQueLen <= 1) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, TRANS_DST_KEY_HIGH, color); \
+ MMIO_OUT32(pSiS->IOBase, TRANS_DST_KEY_LOW, color); \
+ CmdQueLen -= 2;
+
+#define SiSSetupMONOPAT(p0,p1) \
+ if (CmdQueLen <= 1) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, MONO_MASK, p0);\
+ MMIO_OUT32(pSiS->IOBase, MONO_MASK+4, p1);\
+ CmdQueLen=CmdQueLen-2;
+
+#define SiSSetupClipLT(left,top) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, LEFT_CLIP, ((left) & 0xFFFF) | (top)<<16 );\
+ CmdQueLen--;
+
+#define SiSSetupClipRB(right,bottom) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, RIGHT_CLIP, ((right) & 0xFFFF) | (bottom)<<16 );\
+ CmdQueLen--;
+
+#define SiSSetupROP(rop) \
+ pSiS->CommandReg = (rop) << 8;
+
+#define SiSSetupCMDFlag(flags) \
+ pSiS->CommandReg |= (flags);
+
+#define SiSDoCMD \
+ if (CmdQueLen <= 1) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, COMMAND_READY, pSiS->CommandReg); \
+ MMIO_OUT32(pSiS->IOBase, FIRE_TRIGGER, 0); \
+ CmdQueLen=CmdQueLen-2;
+
+#define SiSSetupX0Y0(x,y) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, LINE_X0, (y)<<16 | (x) );\
+ CmdQueLen--;
+
+#define SiSSetupX1Y1(x,y) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, LINE_X1, (y)<<16 | (x) );\
+ CmdQueLen--;
+
+#define SiSSetupLineCount(c) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT16(pSiS->IOBase, LINE_COUNT, c);\
+ CmdQueLen--;
+
+#define SiSSetupStylePeriod(p) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT16(pSiS->IOBase, LINE_STYLE_PERIOD, p);\
+ CmdQueLen--;
+
+#define SiSSetupStyleLow(ls) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, LINE_STYLE_0, ls);\
+ CmdQueLen--;
+
+#define SiSSetupStyleHigh(ls) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, LINE_STYLE_1, ls);\
+ CmdQueLen--;
+
+/* Trapezoid */
+#define SiSSetupYH(y,h) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, TRAP_YH, (y)<<16 | (h) );\
+ CmdQueLen --;
+
+#define SiSSetupLR(left,right) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, TRAP_LR, (right)<<16 | (left) );\
+ CmdQueLen --;
+
+#define SiSSetupdL(dxL,dyL) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, TRAP_DL, (dyL)<<16 | (dxL) );\
+ CmdQueLen --;
+
+#define SiSSetupdR(dxR,dyR) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, TRAP_DR, (dyR)<<16 | (dxR) );\
+ CmdQueLen --;
+
+#define SiSSetupEL(eL) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, TRAP_EL, eL);\
+ CmdQueLen --;
+
+#define SiSSetupER(eR) \
+ if (CmdQueLen <= 0) SiSIdle;\
+ MMIO_OUT32(pSiS->IOBase, TRAP_ER, eR);\
+ CmdQueLen --;
+
+
diff --git a/src/sis6326_video.c b/src/sis6326_video.c
new file mode 100644
index 0000000..f474755
--- /dev/null
+++ b/src/sis6326_video.c
@@ -0,0 +1,1662 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis6326_video.c,v 1.2 2003/01/29 15:42:16 eich Exp $ */
+/*
+ * Xv driver for SiS 5597/5598, 6236 and 530/620.
+ *
+ * Copyright 2002 by Thomas Winischhofer, Vienna, Austria.
+ *
+ * Based on sis_video.c which is
+ * Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan.
+ * Parts Copyright 2002 by Thomas Winischhofer, Vienna, Austria.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL INTEL, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Author:
+ * Thomas Winischhofer <thomas@winischhofer.net>
+ */
+
+#include "sis.h"
+#ifdef USE6326VIDEO
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86Resources.h"
+#include "xf86_ansic.h"
+#include "compiler.h"
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+#include "xf86fbman.h"
+#include "regionstr.h"
+
+#include "xf86xv.h"
+#include "Xv.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "dixstruct.h"
+#include "fourcc.h"
+
+#include "sis_regs.h"
+
+#define OFF_DELAY 200 /* milliseconds */
+#define FREE_DELAY 60000
+
+#define OFF_TIMER 0x01
+#define FREE_TIMER 0x02
+#define CLIENT_VIDEO_ON 0x04
+
+#define TIMER_MASK (OFF_TIMER | FREE_TIMER)
+
+#define WATCHDOG_DELAY 500000 /* Watchdog counter for Vertical Restrace waiting */
+
+static XF86VideoAdaptorPtr SIS6326SetupImageVideo(ScreenPtr);
+static void SIS6326StopVideo(ScrnInfoPtr, pointer, Bool);
+static int SIS6326SetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer);
+static int SIS6326GetPortAttribute(ScrnInfoPtr, Atom ,INT32 *, pointer);
+static void SIS6326QueryBestSize(ScrnInfoPtr, Bool, short, short, short,
+ short, unsigned int *,unsigned int *, pointer);
+static int SIS6326PutImage( ScrnInfoPtr,
+ short, short, short, short, short, short, short, short,
+ int, unsigned char*, short, short, Bool, RegionPtr, pointer);
+static int SIS6326QueryImageAttributes(ScrnInfoPtr,
+ int, unsigned short *, unsigned short *, int *, int *);
+static void SIS6326VideoTimerCallback(ScrnInfoPtr pScrn, Time now);
+static void SIS6326InitOffscreenImages(ScreenPtr pScrn);
+
+#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
+
+static Atom xvBrightness, xvContrast, xvColorKey;
+static Atom xvAutopaintColorKey, xvSetDefaults;
+
+#define IMAGE_MIN_WIDTH 32 /* Minimum and maximum image sizes */
+#define IMAGE_MIN_HEIGHT 24
+#define IMAGE_MAX_WIDTH 720 /* Are these correct for the chips ? */
+#define IMAGE_MAX_HEIGHT 576
+#define IMAGE_MAX_WIDTH_5597 384
+#define IMAGE_MAX_HEIGHT_5597 288
+
+#if 0
+static int oldH, oldW;
+#endif
+
+/****************************************************************************
+ * Raw register access : These routines directly interact with the sis's
+ * control aperature. Must not be called until after
+ * the board's pci memory has been mapped.
+ ****************************************************************************/
+
+#if 0
+static CARD32 _sisread(SISPtr pSiS, CARD32 reg)
+{
+ return *(pSiS->IOBase + reg);
+}
+
+static void _siswrite(SISPtr pSiS, CARD32 reg, CARD32 data)
+{
+ *(pSiS->IOBase + reg) = data;
+}
+#endif
+
+static CARD8 getvideoreg(SISPtr pSiS, CARD8 reg)
+{
+ CARD8 ret;
+ inSISIDXREG(SISCR, reg, ret);
+ return(ret);
+}
+
+static void setvideoreg(SISPtr pSiS, CARD8 reg, CARD8 data)
+{
+ outSISIDXREG(SISCR, reg, data);
+}
+
+static void setvideoregmask(SISPtr pSiS, CARD8 reg, CARD8 data, CARD8 mask)
+{
+ CARD8 old;
+
+ inSISIDXREG(SISCR, reg, old);
+ data = (data & mask) | (old & (~mask));
+ outSISIDXREG(SISCR, reg, data);
+}
+
+/* VBlank */
+static CARD8 vblank_active_CRT1(SISPtr pSiS)
+{
+ return (inSISREG(SISINPSTAT) & 0x08);
+}
+
+/* Scanline - unused */
+#if 0
+static CARD32 get_scanline_CRT1(SISPtr pSiS)
+{
+ CARD8 temp;
+
+ temp = getvideoreg(pSiS, 0x20);
+ temp = getvideoreg(pSiS, 0x1b);
+ return((getvideoreg(pSiS, 0x1d) << 8) | getvideoreg(pSiS, 0x1c));
+}
+#endif
+
+void SIS6326InitVideo(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL;
+ XF86VideoAdaptorPtr newAdaptor = NULL;
+ int num_adaptors;
+
+ newAdaptor = SIS6326SetupImageVideo(pScreen);
+ if(newAdaptor)
+ SIS6326InitOffscreenImages(pScreen);
+
+ num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors);
+
+ if(newAdaptor) {
+ if(!num_adaptors) {
+ num_adaptors = 1;
+ adaptors = &newAdaptor;
+ } else {
+ /* need to free this someplace */
+ newAdaptors = xalloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr*));
+ if(newAdaptors) {
+ memcpy(newAdaptors, adaptors, num_adaptors *
+ sizeof(XF86VideoAdaptorPtr));
+ newAdaptors[num_adaptors] = newAdaptor;
+ adaptors = newAdaptors;
+ num_adaptors++;
+ }
+ }
+ }
+
+ if(num_adaptors)
+ xf86XVScreenInit(pScreen, adaptors, num_adaptors);
+
+ if(newAdaptors)
+ xfree(newAdaptors);
+#if 0
+ oldW = 0; oldH = 0; /* DEBUG */
+#endif
+}
+
+/* client libraries expect an encoding */
+static XF86VideoEncodingRec DummyEncoding =
+{
+ 0,
+ "XV_IMAGE",
+ IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT,
+ {1, 1}
+};
+
+static XF86VideoEncodingRec DummyEncoding5597 =
+{
+ 0,
+ "XV_IMAGE",
+ IMAGE_MAX_WIDTH_5597, IMAGE_MAX_HEIGHT_5597,
+ {1, 1}
+};
+
+#define NUM_FORMATS 4
+
+static XF86VideoFormatRec SIS6326Formats[NUM_FORMATS] =
+{
+ { 8, PseudoColor},
+ {15, TrueColor},
+ {16, TrueColor},
+ {24, TrueColor}
+};
+
+#define NUM_ATTRIBUTES 5
+
+static XF86AttributeRec SIS6326Attributes[NUM_ATTRIBUTES] =
+{
+ {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"},
+ {XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"},
+ {XvSettable | XvGettable, 0, 7, "XV_CONTRAST"},
+ {XvSettable | XvGettable, 0, 1, "XV_AUTOPAINT_COLORKEY"},
+ {XvSettable , 0, 0, "XV_SET_DEFAULTS"}
+};
+
+#define NUM_IMAGES 6
+#define NUM_IMAGES_NOYV12 4
+#define PIXEL_FMT_YV12 FOURCC_YV12 /* 0x32315659 */
+#define PIXEL_FMT_UYVY FOURCC_UYVY /* 0x59565955 */
+#define PIXEL_FMT_YUY2 FOURCC_YUY2 /* 0x32595559 */
+#define PIXEL_FMT_I420 FOURCC_I420 /* 0x30323449 */
+#define PIXEL_FMT_RGB5 0x35315652
+#define PIXEL_FMT_RGB6 0x36315652
+
+static XF86ImageRec SIS6326Images[NUM_IMAGES] =
+{
+ XVIMAGE_YUY2, /* TW: If order is changed, SIS6326OffscreenImages must be adapted */
+ XVIMAGE_UYVY,
+ XVIMAGE_YV12,
+ XVIMAGE_I420,
+ {
+ 0x35315652,
+ XvRGB,
+ LSBFirst,
+ {'R','V','1','5',
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ 16,
+ XvPacked,
+ 1,
+/* 15, 0x001F, 0x03E0, 0x7C00, - incorrect! */
+ 15, 0x7C00, 0x03E0, 0x001F,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ {'R', 'V', 'B',0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ XvTopToBottom
+ },
+ {
+ 0x36315652,
+ XvRGB,
+ LSBFirst,
+ {'R','V','1','6',
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ 16,
+ XvPacked,
+ 1,
+/* 16, 0x001F, 0x07E0, 0xF800, - incorrect! */
+ 16, 0xF800, 0x07E0, 0x001F,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ {'R', 'V', 'B',0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ XvTopToBottom
+ }
+};
+
+static XF86ImageRec SIS6326ImagesNoYV12[NUM_IMAGES_NOYV12] =
+{
+ XVIMAGE_YUY2, /* TW: If order is changed, SIS6326OffscreenImages must be adapted */
+ XVIMAGE_UYVY,
+ {
+ 0x35315652,
+ XvRGB,
+ LSBFirst,
+ {'R','V','1','5',
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ 16,
+ XvPacked,
+ 1,
+/* 15, 0x001F, 0x03E0, 0x7C00, */
+ 15, 0x7C00, 0x03E0, 0x001F, /* TW: Should be more correct than the other... */
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ {'R', 'V', 'B',0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ XvTopToBottom
+ },
+ {
+ 0x36315652,
+ XvRGB,
+ LSBFirst,
+ {'R','V','1','6',
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ 16,
+ XvPacked,
+ 1,
+/* 16, 0x001F, 0x07E0, 0xF800, */
+ 16, 0xF800, 0x07E0, 0x001F, /* TW: Should be more correct than the other... */
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ {'R', 'V', 'B',0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ XvTopToBottom
+ }
+};
+
+typedef struct {
+ int pixelFormat;
+
+ CARD16 pitch;
+
+ CARD8 keyOP;
+
+ CARD8 HUSF;
+ CARD8 VUSF;
+ CARD8 HIntBit;
+ CARD8 wHPre;
+ CARD8 PitchMult;
+
+ CARD16 srcW;
+ CARD16 srcH;
+
+ BoxRec dstBox;
+
+ CARD32 PSY;
+ CARD32 PSV;
+ CARD32 PSU;
+ CARD8 YUVEnd;
+
+ CARD8 lineBufSize;
+
+ CARD8 (*VBlankActiveFunc)(SISPtr);
+/* CARD32 (*GetScanLineFunc)(SISPtr pSiS); */
+
+} SISOverlayRec, *SISOverlayPtr;
+
+typedef struct {
+ FBLinearPtr linear; /* TW: We now use Linear, not Area */
+ CARD32 bufAddr[2];
+
+ unsigned char currentBuf;
+
+ short drw_x, drw_y, drw_w, drw_h;
+ short src_x, src_y, src_w, src_h;
+ int id;
+ short srcPitch, height, width;
+ CARD32 totalSize;
+
+ char brightness;
+ unsigned char contrast;
+
+ RegionRec clip;
+ CARD32 colorKey;
+ Bool autopaintColorKey;
+
+ CARD32 videoStatus;
+ Time offTime;
+ Time freeTime;
+
+ short oldx1, oldx2, oldy1, oldy2;
+ int mustwait;
+
+ Bool grabbedByV4L; /* V4L stuff */
+ int pitch;
+ int offset;
+
+} SISPortPrivRec, *SISPortPrivPtr;
+
+#define GET_PORT_PRIVATE(pScrn) \
+ (SISPortPrivPtr)((SISPTR(pScrn))->adaptor->pPortPrivates[0].ptr)
+
+static void
+SIS6326SetPortDefaults (ScrnInfoPtr pScrn, SISPortPrivPtr pPriv)
+{
+ pPriv->colorKey = 0x000101fe;
+ pPriv->videoStatus = 0;
+ pPriv->brightness = 0;
+ pPriv->contrast = 4;
+ pPriv->autopaintColorKey = TRUE;
+}
+
+static void
+SIS6326ResetVideo(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+
+ /* Unlock registers */
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+ if(getvideoreg (pSiS, Index_VI6326_Passwd) != 0xa1) {
+ setvideoreg (pSiS, Index_VI6326_Passwd, 0x86);
+ if(getvideoreg (pSiS, Index_VI6326_Passwd) != 0xa1)
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Xv: Video password could not unlock video registers\n");
+ }
+
+ /* Initialize the overlay ----------------------------------- */
+
+ switch(pSiS->Chipset) {
+ case PCI_CHIP_SIS6326:
+ /* Disable overlay (D[1]) & capture (D[0]) */
+ setvideoregmask(pSiS, Index_VI6326_Control_Misc0, 0x00, 0x03);
+
+ /* What do these do? (Datasheet names these bits "reserved") */
+ setvideoregmask(pSiS, Index_VI6326_Control_Misc0, 0x00, 0x18);
+ setvideoregmask(pSiS, Index_VI6326_Control_Misc0, 0x00, 0x0c);
+
+ /* Select YUV format (D[6]) and "gfx + video" mode (D[4]), odd polarity? (D[7]) */
+ setvideoregmask(pSiS, Index_VI6326_Control_Misc0, 0x40, 0xD0);
+ /* No interrupt, no filter, disable dithering */
+ setvideoregmask(pSiS, Index_VI6326_Control_Misc1, 0x00, 0x7A);
+ /* Disable VMI (D[4:3]), Brooktree support (D[6]) and system memory framebuffer (D[7]) */
+ setvideoregmask(pSiS, Index_VI6326_Control_Misc3, 0x00, 0xF8);
+ /* Disable video decimation */
+ setvideoregmask(pSiS, Index_VI6326_Control_Misc6, 0x00, 0x80);
+ break;
+ case PCI_CHIP_SIS5597:
+ /* Disable overlay (D[1]) & capture (D[0]) */
+ setvideoregmask(pSiS, Index_VI6326_Control_Misc0, 0x00, 0x03);
+
+ /* What do these do? (Datasheet names these bits "reserved") */
+ setvideoregmask(pSiS, Index_VI6326_Control_Misc0, 0x00, 0x18);
+ setvideoregmask(pSiS, Index_VI6326_Control_Misc0, 0x00, 0x0c);
+
+ /* Select YUV format (D[6]) and "gfx + video" mode (D[4]), odd polarity? (D[7]) */
+ setvideoregmask(pSiS, Index_VI6326_Control_Misc0, 0x40, 0xD0);
+ /* No interrupt, no filter, disable dithering */
+ setvideoregmask(pSiS, Index_VI6326_Control_Misc1, 0x00, 0x7A);
+ /* Disable Brooktree support (D[6]) and system memory framebuffer (D[7]) */
+ setvideoregmask(pSiS, Index_VI6326_Control_Misc3, 0x00, 0xC0);
+ /* Disable video decimation (has a really strange effect if enabled) */
+ setvideoregmask(pSiS, Index_VI6326_Control_Misc6, 0x00, 0x80);
+ break;
+ case PCI_CHIP_SIS530:
+ /* What is this? (Bit is "reserved") */
+ setvideoregmask (pSiS, Index_VI6326_Control_Misc4, 0x40, 0x40);
+ /* Disable overlay (D[1]) */
+ setvideoregmask(pSiS, Index_VI6326_Control_Misc0, 0x00, 0x02);
+
+ /* What do these do? (Datasheet names these bits "reserved") */
+ setvideoregmask(pSiS, Index_VI6326_Control_Misc0, 0x00, 0x18);
+ setvideoregmask(pSiS, Index_VI6326_Control_Misc0, 0x00, 0x0c);
+
+ /* Select YUV format (D[6]) and "gfx + video" mode (D[4]) */
+ setvideoregmask(pSiS, Index_VI6326_Control_Misc0, 0x40, 0x50);
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Internal error: SiS6326ResetVideo() called with invalid chipset (%x)\n",
+ pSiS->Chipset);
+ return;
+ }
+
+ /* Clear format selection */
+ setvideoregmask(pSiS, Index_VI6326_Control_Misc1, 0x00, 0x04);
+ setvideoregmask(pSiS, Index_VI6326_Control_Misc4, 0x00, 0x07);
+
+ /* Select RGB Chromakey format (D[2]=0), CCIR 601 UV data format (D[1]=0) */
+ /* D[1]: 1 = 2's complement, 0 = CCIR 601 format */
+ setvideoregmask(pSiS, Index_VI6326_Control_Misc3, 0x00, 0x06);
+
+ /* Reset contrast control */
+ setvideoregmask(pSiS, Index_VI6326_Contrast_Enh_Ctrl, 0x04, 0x1F);
+
+ /* Set treshold */
+ if(pSiS->oldChipset < OC_SIS6326) {
+ CARD8 temp;
+ inSISIDXREG(SISSR, 0x33, temp); /* Synchronous DRAM Timing? */
+ if(temp & 0x01) temp = 0x50;
+ else temp = 0;
+ setvideoreg(pSiS, Index_VI6326_Play_Threshold_Low, temp);
+ setvideoreg(pSiS, Index_VI6326_Play_Threshold_High, temp);
+ } else {
+ CARD8 temp;
+ setvideoreg(pSiS, Index_VI6326_Play_Threshold_Low, 0x00);
+ setvideoreg(pSiS, Index_VI6326_Play_Threshold_High, 0x00);
+ inSISIDXREG(SISSR, 0x33, temp); /* Are we using SGRAM Timing? */
+ if(temp & 0x01) temp = 0x10;
+ else temp = 0;
+ setvideoregmask(pSiS, Index_VI6326_Control_Misc4, temp, 0x10);
+ }
+
+ /* set default properties for overlay ------------------------------- */
+
+ setvideoregmask (pSiS, Index_VI6326_Contrast_Enh_Ctrl, 0x04, 0x07);
+ setvideoreg (pSiS, Index_VI6326_Brightness, 0x20);
+
+ if(pSiS->oldChipset < OC_SIS6205A || pSiS->oldChipset > OC_SIS82204) {
+ setvideoregmask(pSiS, Index_VI6326_AlphaGraph, 0x00, 0xF8);
+ setvideoregmask(pSiS, Index_VI6326_AlphaVideo, 0xF8, 0xF8);
+ } else {
+ setvideoregmask(pSiS, Index_VI6326_AlphaGraph, 0x00, 0xE1);
+ setvideoregmask(pSiS, Index_VI6326_AlphaVideo, 0xE1, 0xE1);
+ }
+}
+
+static XF86VideoAdaptorPtr
+SIS6326SetupImageVideo(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ SISPtr pSiS = SISPTR(pScrn);
+ XF86VideoAdaptorPtr adapt;
+ SISPortPrivPtr pPriv;
+
+ if(!(adapt = xcalloc(1, sizeof(XF86VideoAdaptorRec) +
+ sizeof(SISPortPrivRec) +
+ sizeof(DevUnion))))
+ return NULL;
+
+ adapt->type = XvWindowMask | XvInputMask | XvImageMask;
+ adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
+ adapt->name = "SIS 5597/5598/6326/530/620 Video Overlay";
+ adapt->nEncodings = 1;
+ if(pSiS->oldChipset < OC_SIS6326) {
+ adapt->pEncodings = &DummyEncoding5597;
+ } else {
+ adapt->pEncodings = &DummyEncoding;
+ }
+ adapt->nFormats = NUM_FORMATS;
+ adapt->pFormats = SIS6326Formats;
+ adapt->nPorts = 1;
+ adapt->pPortPrivates = (DevUnion*)(&adapt[1]);
+
+ pPriv = (SISPortPrivPtr)(&adapt->pPortPrivates[1]);
+
+ adapt->pPortPrivates[0].ptr = (pointer)(pPriv);
+ adapt->pAttributes = SIS6326Attributes;
+ adapt->nAttributes = NUM_ATTRIBUTES;
+ if(pSiS->NoYV12 == 1) {
+ adapt->nImages = NUM_IMAGES_NOYV12;
+ adapt->pImages = SIS6326ImagesNoYV12;
+ } else {
+ adapt->nImages = NUM_IMAGES;
+ adapt->pImages = SIS6326Images;
+ }
+ adapt->PutVideo = NULL;
+ adapt->PutStill = NULL;
+ adapt->GetVideo = NULL;
+ adapt->GetStill = NULL;
+ adapt->StopVideo = SIS6326StopVideo;
+ adapt->SetPortAttribute = SIS6326SetPortAttribute;
+ adapt->GetPortAttribute = SIS6326GetPortAttribute;
+ adapt->QueryBestSize = SIS6326QueryBestSize;
+ adapt->PutImage = SIS6326PutImage;
+ adapt->QueryImageAttributes = SIS6326QueryImageAttributes;
+
+ pPriv->videoStatus = 0;
+ pPriv->currentBuf = 0;
+ pPriv->linear = NULL;
+ pPriv->grabbedByV4L= FALSE;
+
+ SIS6326SetPortDefaults(pScrn, pPriv);
+
+ /* gotta uninit this someplace */
+ REGION_INIT(pScreen, &pPriv->clip, NullBox, 0);
+
+ pSiS->adaptor = adapt;
+
+ xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
+ xvContrast = MAKE_ATOM("XV_CONTRAST");
+ xvColorKey = MAKE_ATOM("XV_COLORKEY");
+ xvAutopaintColorKey = MAKE_ATOM("XV_AUTOPAINT_COLORKEY");
+ xvSetDefaults = MAKE_ATOM("XV_SET_DEFAULTS");
+
+ SIS6326ResetVideo(pScrn);
+
+ return adapt;
+}
+
+static Bool
+RegionsEqual(RegionPtr A, RegionPtr B)
+{
+ int *dataA, *dataB;
+ int num;
+
+ num = REGION_NUM_RECTS(A);
+ if(num != REGION_NUM_RECTS(B))
+ return FALSE;
+
+ if((A->extents.x1 != B->extents.x1) ||
+ (A->extents.x2 != B->extents.x2) ||
+ (A->extents.y1 != B->extents.y1) ||
+ (A->extents.y2 != B->extents.y2))
+ return FALSE;
+
+ dataA = (int*)REGION_RECTS(A);
+ dataB = (int*)REGION_RECTS(B);
+
+ while(num--) {
+ if((dataA[0] != dataB[0]) || (dataA[1] != dataB[1]))
+ return FALSE;
+ dataA += 2;
+ dataB += 2;
+ }
+
+ return TRUE;
+}
+
+static int
+SIS6326SetPortAttribute(ScrnInfoPtr pScrn, Atom attribute,
+ INT32 value, pointer data)
+{
+ SISPortPrivPtr pPriv = (SISPortPrivPtr)data;
+
+ if(attribute == xvBrightness) {
+ if((value < -128) || (value > 127))
+ return BadValue;
+ pPriv->brightness = value;
+ } else if(attribute == xvContrast) {
+ if((value < 0) || (value > 7))
+ return BadValue;
+ pPriv->contrast = value;
+ } else if(attribute == xvColorKey) {
+ pPriv->colorKey = value;
+ REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
+ } else if (attribute == xvAutopaintColorKey) {
+ if ((value < 0) || (value > 1))
+ return BadValue;
+ pPriv->autopaintColorKey = value;
+ } else if (attribute == xvSetDefaults) {
+ SIS6326SetPortDefaults(pScrn, pPriv);
+ } else return BadMatch;
+ return Success;
+}
+
+static int
+SIS6326GetPortAttribute(
+ ScrnInfoPtr pScrn,
+ Atom attribute,
+ INT32 *value,
+ pointer data
+){
+ SISPortPrivPtr pPriv = (SISPortPrivPtr)data;
+
+ if(attribute == xvBrightness) {
+ *value = pPriv->brightness;
+ } else if(attribute == xvContrast) {
+ *value = pPriv->contrast;
+ } else if(attribute == xvColorKey) {
+ *value = pPriv->colorKey;
+ } else if (attribute == xvAutopaintColorKey)
+ *value = (pPriv->autopaintColorKey) ? 1 : 0;
+ else return BadMatch;
+ return Success;
+}
+
+static void
+SIS6326QueryBestSize(
+ ScrnInfoPtr pScrn,
+ Bool motion,
+ short vid_w, short vid_h,
+ short drw_w, short drw_h,
+ unsigned int *p_w, unsigned int *p_h,
+ pointer data
+){
+ *p_w = drw_w;
+ *p_h = drw_h;
+
+ /* TODO: report the HW limitation */
+}
+
+static void /* V 530/6326 */
+calc_scale_factor(SISPtr pSiS, SISOverlayPtr pOverlay, ScrnInfoPtr pScrn,
+ SISPortPrivPtr pPriv)
+{
+ CARD32 temp=0;
+
+ int dstW = pOverlay->dstBox.x2 - pOverlay->dstBox.x1;
+ int dstH = pOverlay->dstBox.y2 - pOverlay->dstBox.y1;
+ int srcW = pOverlay->srcW;
+ int srcH = pOverlay->srcH;
+
+#if 0
+ /* DEBUG */
+ if((oldH != dstH) || (oldW != dstW)){
+ xf86DrvMsg(0, X_INFO, "Video size %dx%d\n", dstW, dstH);
+ oldH = dstH; oldW = dstW;
+ }
+ /* /DEBUG */
+#endif
+
+ /* TW: For double scan modes, we need to double the height */
+ if(pSiS->CurrentLayout.mode->Flags & V_DBLSCAN) {
+ dstH <<= 1;
+ }
+ /* TW: For interlace modes, we need to half the height */
+ if(pSiS->CurrentLayout.mode->Flags & V_INTERLACE) {
+ dstH >>= 1;
+ }
+
+ /* Horizontal */
+ if(dstW < IMAGE_MIN_WIDTH) dstW = IMAGE_MIN_WIDTH;
+ if(dstW == srcW) {
+ pOverlay->HUSF = 0x00;
+ pOverlay->HIntBit = 0x01;
+ } else if(dstW > srcW) {
+ pOverlay->HIntBit = 0x00;
+ temp = srcW * 64 / (dstW + 1);
+ if(temp > 63) temp = 63;
+ pOverlay->HUSF = temp;
+ } else {
+ /* TW: 6326 can't scale below factor .440 - to check with 530/620 */
+ if(((dstW * 1000) / srcW) < 440) dstW = ((srcW * 440) / 1000) + 1;
+ temp = srcW / dstW;
+ if(temp > 15) temp = 15;
+ pOverlay->HIntBit = temp;
+ temp = srcW * 64 / dstW;
+ pOverlay->HUSF = temp - (pOverlay->HIntBit * 64);
+ }
+
+ /* Vertical */
+ if(dstH < IMAGE_MIN_HEIGHT) dstH = IMAGE_MIN_HEIGHT;
+ if(dstH == srcH) {
+ pOverlay->VUSF = 0x00;
+ pOverlay->PitchMult = 1;
+ } else if(dstH > srcH) {
+ temp = srcH * 64 / (dstH + 1);
+ if (temp > 63) temp = 63;
+ pOverlay->VUSF = temp;
+ pOverlay->PitchMult = 1;
+ } else {
+ /* TW: 6326 can't scale below factor .440 - to check with 530/620 */
+ if(((dstH * 1000) / srcH) < 440) dstH = ((srcH * 440) / 1000) + 1;
+ temp = srcH / dstH;
+ if(srcH % dstH) {
+ temp++;
+ pOverlay->VUSF = (srcH * 64) / (temp * dstH);
+ } else {
+ pOverlay->VUSF = 0x00;
+ }
+ pOverlay->PitchMult = temp;
+ }
+}
+
+static void /* V 530/6326 */
+calc_line_buf_size(SISOverlayPtr pOverlay)
+{
+ CARD32 I;
+ CARD32 line = pOverlay->srcW;
+
+ if( (pOverlay->pixelFormat == PIXEL_FMT_YV12) ||
+ (pOverlay->pixelFormat == PIXEL_FMT_I420) )
+ {
+ I = (line >> 5) + (((line >> 6) * 2)) + 3;
+ I <<= 5;
+ } else { /* YUV2, UYVY, RGB */
+ I = line << 1;
+ if(I & 7) I += 8;
+ }
+ I += 8;
+ I >>= 3;
+ pOverlay->lineBufSize = (CARD8)I;
+}
+
+static void /* V 530/6326 */
+merge_line_buf(SISPtr pSiS, SISPortPrivPtr pPriv, Bool enable)
+{
+ if(enable) {
+ setvideoregmask(pSiS, Index_VI6326_Control_Misc5, 0x10, 0x10);
+ } else {
+ setvideoregmask(pSiS, Index_VI6326_Control_Misc5, 0x00, 0x10);
+ }
+}
+
+static void /* V 530/6326 */
+set_format(SISPtr pSiS, SISOverlayPtr pOverlay)
+{
+ CARD8 fmt, misc0, misc1, misc4;
+
+ switch (pOverlay->pixelFormat){
+ case PIXEL_FMT_YV12:
+ case PIXEL_FMT_I420: /* V/530 V/6326 */
+ fmt = 0x80; /* D[7:6] 10 YUV2(=YUYV), 01 VYUY, 00 UYVY, 11 YVYU / 00 RGB 555, 01 RGB 565 */
+ misc0 = 0x40; /* D[6]: 1 = YUV, 0 = RGB */
+ misc4 = 0x05; /* D[1:0] 00 RGB 555, 01 YUV 422, 10 RGB 565; D[2] 1 = YUV420 mode */
+ misc1 = 0xff;
+ break;
+ case PIXEL_FMT_UYVY:
+ fmt = 0x00; /* D[7:6] 10 YUV2(=YUYV), 01 VYUY, 00 UYVY, 11 YVYU / 00 RGB 555, 01 RGB 565 */
+ misc0 = 0x40; /* D[6]: 1 = YUV, 0 = RGB */
+ misc4 = 0x00; /* D[1:0] 00 RGB 555, 01 YUV 422, 10 RGB 565; D[2] 1 = YUV420 mode */
+ misc1 = 0xff;
+ break;
+ case PIXEL_FMT_YUY2: /* V/530 V/6326 */
+ fmt = 0x80; /* D[7:6] 10 YUV2(=YUYV), 01 VYUY, 00 UYVY, 11 YVYU / 00 RGB 555, 01 RGB 565 */
+ misc0 = 0x40; /* D[6]: 1 = YUV, 0 = RGB */
+ misc4 = 0x00; /* D[1:0] 00 RGB 555, 01 YUV 422, 10 RGB 565; D[2] 1 = YUV420 mode */
+ misc1 = 0xff;
+ break;
+ case PIXEL_FMT_RGB6: /* V/530 V/6326 */
+ fmt = 0x40; /* D[7:6] 10 YUV2(=YUYV), 01 VYUY, 00 UYVY, 11 YVYU / 00 RGB 555, 01 RGB 565 */
+ misc0 = 0x00; /* D[6]: 1 = YUV, 0 = RGB */
+ misc4 = 0xff;
+ misc1 = 0x00; /* D[2] = Capture format selection (DS5597) - WDR sets this */
+ break;
+ case PIXEL_FMT_RGB5: /* V/530 V/6326 */
+ default:
+ fmt = 0x00; /* D[7:6] 10 YUV2(=YUYV), 01 VYUY, 00 UYVY, 11 YVYU / 00 RGB 555, 01 RGB 565 */
+ misc0 = 0x00; /* D[6]: 1 = YUV, 0 = RGB */
+ misc4 = 0xff;
+ misc1 = 0x04; /* D[2] = Capture format selection (DS5597) - WDR sets this */
+ break;
+ }
+
+ setvideoregmask(pSiS, Index_VI6326_VideoFormatSelect, fmt, 0xC0);
+ setvideoregmask(pSiS, Index_VI6326_Control_Misc0, misc0, 0x40);
+ if(misc4 == 0xff) {
+ setvideoregmask(pSiS, Index_VI6326_Control_Misc1, misc1, 0x04);
+ if(pSiS->oldChipset >= OC_SIS5597) {
+ setvideoregmask(pSiS, Index_VI6326_Control_Misc4, 0x00, 0x05);
+ }
+ } else {
+ if(pSiS->oldChipset >= OC_SIS5597) {
+ setvideoregmask(pSiS, Index_VI6326_Control_Misc4, misc4, 0x05);
+ }
+ setvideoregmask(pSiS, Index_VI6326_Control_Misc1, 0x00, 0x04);
+ }
+}
+
+static void /* V 6326/530 */
+set_colorkey(SISPtr pSiS, CARD32 colorkey)
+{
+ CARD8 r, g, b, s;
+
+ b = (CARD8)(colorkey & 0xFF);
+ g = (CARD8)((colorkey>>8) & 0xFF);
+ r = (CARD8)((colorkey>>16) & 0xFF);
+
+ if(pSiS->CurrentLayout.bitsPerPixel >= 24) {
+ s = b;
+ b = r;
+ r = s;
+ }
+
+ setvideoreg(pSiS, Index_VI6326_Overlay_ColorKey_Blue_Min ,(CARD8)b);
+ setvideoreg(pSiS, Index_VI6326_Overlay_ColorKey_Green_Min ,(CARD8)g);
+ setvideoreg(pSiS, Index_VI6326_Overlay_ColorKey_Red_Min ,(CARD8)r);
+
+ setvideoreg(pSiS, Index_VI6326_Overlay_ColorKey_Blue_Max ,(CARD8)b);
+ setvideoreg(pSiS, Index_VI6326_Overlay_ColorKey_Green_Max ,(CARD8)g);
+ setvideoreg(pSiS, Index_VI6326_Overlay_ColorKey_Red_Max ,(CARD8)r);
+}
+
+static void
+set_brightness(SISPtr pSiS, CARD8 brightness)
+{
+ setvideoreg(pSiS, Index_VI6326_Brightness, brightness);
+}
+
+static void
+set_contrast(SISPtr pSiS, CARD8 contrast)
+{
+ setvideoregmask(pSiS, Index_VI6326_Contrast_Enh_Ctrl, contrast, 0x07);
+}
+
+static void
+set_contrast_data(SISPtr pSiS, int value)
+{
+ unsigned long temp;
+
+ if(value < 10000) temp = 0;
+ else temp = (value - 10000) / 20000;
+ if(temp > 3) temp = 3;
+ setvideoregmask(pSiS, Index_VI6326_Contrast_Enh_Ctrl, (temp << 6), 0xC0);
+ switch(temp) {
+ case 0: temp = 2048; break;
+ case 1: temp = 4096; break;
+ case 2: temp = 8192; break;
+ case 3: temp = 16384; break;
+ }
+ temp <<= 10;
+ temp /= value;
+ setvideoreg(pSiS, Index_VI6326_Contrast_Factor, temp);
+}
+
+static void
+set_overlay(SISPtr pSiS, SISOverlayPtr pOverlay, SISPortPrivPtr pPriv, int index)
+{
+ ScrnInfoPtr pScrn = pSiS->pScrn;
+
+ CARD16 pitch=0;
+ CARD8 h_over=0, v_over=0;
+ CARD16 top, bottom, left, right;
+ CARD16 screenX = pSiS->CurrentLayout.mode->HDisplay;
+ CARD16 screenY = pSiS->CurrentLayout.mode->VDisplay;
+ CARD32 watchdog;
+
+ top = pOverlay->dstBox.y1;
+ bottom = pOverlay->dstBox.y2;
+ if(bottom > screenY) {
+ bottom = screenY;
+ }
+
+ left = pOverlay->dstBox.x1;
+ right = pOverlay->dstBox.x2;
+ if(right > screenX) {
+ right = screenX;
+ }
+
+ /* TW: DoubleScan modes require Y coordinates * 2 */
+ if(pSiS->CurrentLayout.mode->Flags & V_DBLSCAN) {
+ top <<= 1;
+ bottom <<= 1;
+ }
+ /* TW: Interlace modes require Y coordinates / 2 */
+ if(pSiS->CurrentLayout.mode->Flags & V_INTERLACE) {
+ top >>= 1;
+ bottom >>= 1;
+ }
+
+ h_over = (((left>>8) & 0x07) | ((right>>4) & 0x70));
+ v_over = (((top>>8) & 0x07) | ((bottom>>4) & 0x70));
+
+ pitch = pOverlay->pitch * pOverlay->PitchMult;
+ pitch >>= 2; /* Datasheet: Unit = double word - verified */
+ if(pitch > 0xfff) {
+ pitch = pOverlay->pitch * (0xFFF * 2 / pOverlay->pitch);
+ pOverlay->VUSF = 0x3F;
+ }
+
+ /* set color key */
+ set_colorkey(pSiS, pPriv->colorKey);
+
+ /* set color key mode */
+ setvideoregmask(pSiS, Index_VI6326_Key_Overlay_OP, pOverlay->keyOP, 0x0f);
+
+ setvideoregmask(pSiS, Index_VI6326_Control_Misc0, 0x00, 0x0c);
+ setvideoregmask(pSiS, Index_VI6326_Control_Misc0, 0x00, 0x18);
+
+ /* Set Y buf pitch */ /* Datasheet: Unit = double word - verified */
+ setvideoreg(pSiS, Index_VI6326_Disp_Y_Buf_Pitch_Low, (CARD8)(pitch));
+ setvideoregmask(pSiS, Index_VI6326_Disp_Y_Buf_Pitch_High, (CARD8)(pitch>>8), 0x0f);
+ /* Set U/V pitch if using planar formats */
+ if( (pOverlay->pixelFormat == PIXEL_FMT_YV12) ||
+ (pOverlay->pixelFormat == PIXEL_FMT_I420) ) {
+ /* Set U/V pitch */ /* Datasheet: Unit = double word - verified */
+ setvideoreg(pSiS, Index_VI6326_Disp_UV_Buf_Pitch_Low, (CARD8)pitch >> 1);
+ setvideoregmask(pSiS, Index_VI6326_Disp_UV_Buf_Pitch_High, (CARD8)(pitch >> 9), 0x0f);
+ }
+
+ /* set line buffer size */
+ setvideoreg(pSiS, Index_VI6326_Line_Buffer_Size, pOverlay->lineBufSize);
+
+ /* set scale factor */
+ setvideoreg(pSiS, Index_VI6326_Hor_Scale, (CARD8)((pOverlay->HUSF) | 0xC0));
+ setvideoregmask(pSiS, Index_VI6326_Hor_Scale_Integer, (CARD8)(pOverlay->HIntBit), 0x0F);
+ setvideoregmask(pSiS, Index_VI6326_Ver_Scale, (CARD8)(pOverlay->VUSF), 0x3F);
+
+ /* TW: We don't have to wait for vertical retrace in all cases */
+ if(pPriv->mustwait) {
+ watchdog = WATCHDOG_DELAY;
+ while ((!pOverlay->VBlankActiveFunc(pSiS)) && --watchdog);
+ if(!watchdog) xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Xv: Waiting for vertical retrace timed-out\n");
+ }
+
+ /* set destination window position */
+ setvideoreg(pSiS, Index_VI6326_Win_Hor_Disp_Start_Low, (CARD8)left);
+ setvideoreg(pSiS, Index_VI6326_Win_Hor_Disp_End_Low, (CARD8)right);
+ setvideoreg(pSiS, Index_VI6326_Win_Hor_Over, (CARD8)h_over);
+
+ setvideoreg(pSiS, Index_VI6326_Win_Ver_Disp_Start_Low, (CARD8)top);
+ setvideoreg(pSiS, Index_VI6326_Win_Ver_Disp_End_Low, (CARD8)bottom);
+ setvideoreg(pSiS, Index_VI6326_Win_Ver_Over, (CARD8)v_over);
+
+ /* Set Y start address */
+ setvideoreg (pSiS, Index_VI6326_Disp_Y_Buf_Start_Low, (CARD8)(pOverlay->PSY));
+ setvideoreg (pSiS, Index_VI6326_Disp_Y_Buf_Start_Middle, (CARD8)((pOverlay->PSY)>>8));
+ if(pSiS->oldChipset <= OC_SIS6326) { /* all old chipsets incl 6326 */
+ /* Set overflow bits */
+ setvideoregmask (pSiS, Index_VI6326_Disp_Capt_Y_Buf_Start_High,
+ (CARD8)(((pOverlay->PSY)>>12) & 0xF0), 0xF0);
+ /* Set framebuffer end address */
+ setvideoreg (pSiS, Index_VI6326_Disp_Y_End, (CARD8)(pOverlay->YUVEnd));
+ } else { /* 530/620 */
+ /* Set overflow bits */
+ setvideoregmask (pSiS, Index_VI6326_Disp_Capt_Y_Buf_Start_High,
+ (CARD8)(((pOverlay->PSY)>>13) & 0xF8), 0xF8);
+ }
+
+ /* Set U/V start addresses if using plane formats */
+ if( (pOverlay->pixelFormat == PIXEL_FMT_YV12) ||
+ (pOverlay->pixelFormat == PIXEL_FMT_I420) ) {
+
+ CARD32 PSU = pOverlay->PSU;
+ CARD32 PSV = pOverlay->PSV;
+
+ /* set U/V start address */
+ setvideoreg (pSiS, Index_VI6326_U_Buf_Start_Low, (CARD8)PSU);
+ setvideoreg (pSiS, Index_VI6326_U_Buf_Start_Middle,(CARD8)(PSU >> 8));
+
+ setvideoreg (pSiS, Index_VI6326_V_Buf_Start_Low, (CARD8)PSV);
+ setvideoreg (pSiS, Index_VI6326_V_Buf_Start_Middle,(CARD8)(PSV >> 8));
+
+ setvideoreg (pSiS, Index_VI6326_UV_Buf_Start_High,
+ (CARD8)(((PSU >> 16) & 0x0F) | ((PSV >> 12) & 0xF0)) );
+
+ if(pSiS->oldChipset > OC_SIS6326) {
+ /* Set bit 20 of the addresses in Misc5 (530/620 only) */
+ setvideoreg (pSiS, Index_VI6326_Control_Misc5,
+ (CARD8)(((PSU >> (20-1)) & 0x02) | ((PSV >> (20-2)) & 0x04)) );
+ }
+ }
+
+ /* set brightness and contrast */
+ set_brightness(pSiS, pPriv->brightness);
+ if(pSiS->oldChipset > OC_SIS6205C) {
+ set_contrast_data(pSiS, (pOverlay->dstBox.x2 - pOverlay->dstBox.x1) *
+ (pOverlay->dstBox.y2 - pOverlay->dstBox.y1));
+ set_contrast(pSiS, pPriv->contrast);
+ }
+
+ /* set format */
+ set_format(pSiS, pOverlay);
+}
+
+/* TW: Overlay MUST NOT be switched off while beam is over it */
+static void
+close_overlay(SISPtr pSiS, SISPortPrivPtr pPriv)
+{
+ CARD32 watchdog;
+
+ watchdog = WATCHDOG_DELAY;
+ while((!vblank_active_CRT1(pSiS)) && --watchdog);
+ if(pSiS->oldChipset > OC_SIS6326) {
+ /* what is this? */
+ setvideoregmask(pSiS, Index_VI6326_Control_Misc4, 0x40, 0x40);
+ }
+ /* disable overlay */
+ setvideoregmask(pSiS, Index_VI6326_Control_Misc0, 0x00, 0x02);
+}
+
+static void
+SIS6326DisplayVideo(ScrnInfoPtr pScrn, SISPortPrivPtr pPriv)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+
+ short srcPitch = pPriv->srcPitch;
+ short height = pPriv->height;
+ short width = pPriv->width;
+ SISOverlayRec overlay;
+ int srcOffsetX=0, srcOffsetY=0;
+ int sx, sy;
+ int index = 0;
+ int pitch;
+
+ memset(&overlay, 0, sizeof(overlay));
+ overlay.pixelFormat = pPriv->id;
+ overlay.pitch = srcPitch;
+ overlay.keyOP = VI6326_ROP_DestKey; /* DestKey mode */
+
+ overlay.dstBox.x1 = pPriv->drw_x - pScrn->frameX0;
+ overlay.dstBox.x2 = pPriv->drw_x + pPriv->drw_w - pScrn->frameX0;
+ overlay.dstBox.y1 = pPriv->drw_y - pScrn->frameY0;
+ overlay.dstBox.y2 = pPriv->drw_y + pPriv->drw_h - pScrn->frameY0;
+
+ if((overlay.dstBox.x1 > overlay.dstBox.x2) ||
+ (overlay.dstBox.y1 > overlay.dstBox.y2))
+ return;
+
+ if((overlay.dstBox.x2 < 0) || (overlay.dstBox.y2 < 0))
+ return;
+
+ if(overlay.dstBox.x1 < 0) {
+ srcOffsetX = pPriv->src_w * (-overlay.dstBox.x1) / pPriv->drw_w;
+ overlay.dstBox.x1 = 0;
+ }
+ if(overlay.dstBox.y1 < 0) {
+ srcOffsetY = pPriv->src_h * (-overlay.dstBox.y1) / pPriv->drw_h;
+ overlay.dstBox.y1 = 0;
+ }
+
+ switch(pPriv->id){
+ case PIXEL_FMT_YV12:
+ sx = (pPriv->src_x + srcOffsetX) & ~7;
+ sy = (pPriv->src_y + srcOffsetY) & ~1;
+ pitch = (width + 3) & ~3;
+ overlay.PSY = pPriv->bufAddr[pPriv->currentBuf] + sx + sy * pitch;
+ overlay.PSV = overlay.PSY + pitch * height;
+ overlay.PSU = overlay.PSV + ((((width >> 1) + 3) & ~3) * (height >> 1));
+ overlay.PSY >>= 2;
+ overlay.PSV >>= 2;
+ overlay.PSU >>= 2;
+ break;
+ case PIXEL_FMT_I420:
+ sx = (pPriv->src_x + srcOffsetX) & ~7;
+ sy = (pPriv->src_y + srcOffsetY) & ~1;
+ pitch = (width + 3) & ~3;
+ overlay.PSY = pPriv->bufAddr[pPriv->currentBuf] + sx + sy * pitch;
+ overlay.PSU = overlay.PSY + pitch * height;
+ overlay.PSV = overlay.PSU + ((((width >> 1) + 3) & ~3) * (height >> 1));
+ overlay.PSY >>= 2;
+ overlay.PSV >>= 2;
+ overlay.PSU >>= 2;
+ break;
+ case PIXEL_FMT_YUY2:
+ case PIXEL_FMT_UYVY:
+ case PIXEL_FMT_RGB6:
+ case PIXEL_FMT_RGB5:
+ default:
+ sx = (pPriv->src_x + srcOffsetX) & ~1;
+ sy = (pPriv->src_y + srcOffsetY);
+ overlay.PSY = (pPriv->bufAddr[pPriv->currentBuf] + sx*2 + sy*srcPitch);
+ overlay.PSY >>= 2;
+ break;
+ }
+
+ /* FIXME: Is this correct? (Is it required to set the end address?
+ * Datasheet is not clear) - (reg does not exist on 530/620)
+ */
+ overlay.YUVEnd = (pPriv->bufAddr[pPriv->currentBuf] + pPriv->totalSize) >> 14;
+
+ /* FIXME: is it possible that srcW < 0 */
+ overlay.srcW = pPriv->src_w - (sx - pPriv->src_x);
+ overlay.srcH = pPriv->src_h - (sy - pPriv->src_y);
+
+ if ( (pPriv->oldx1 != overlay.dstBox.x1) ||
+ (pPriv->oldx2 != overlay.dstBox.x2) ||
+ (pPriv->oldy1 != overlay.dstBox.y1) ||
+ (pPriv->oldy2 != overlay.dstBox.y2) ) {
+ pPriv->mustwait = 1;
+ pPriv->oldx1 = overlay.dstBox.x1; pPriv->oldx2 = overlay.dstBox.x2;
+ pPriv->oldy1 = overlay.dstBox.y1; pPriv->oldy2 = overlay.dstBox.y2;
+ }
+
+ /* calculate line buffer length */
+ calc_line_buf_size(&overlay);
+
+ overlay.VBlankActiveFunc = vblank_active_CRT1;
+/* overlay.GetScanLineFunc = get_scanline_CRT1; */
+
+ /* calculate scale factor */
+ calc_scale_factor(pSiS, &overlay, pScrn, pPriv);
+
+ /* set (not only determine) if line buffer is to be merged */
+ if(pSiS->oldChipset > OC_SIS5597) {
+ int temp;
+ if(pSiS->oldChipset <= OC_SIS6326) temp = 352;
+ else temp = 384;
+ merge_line_buf(pSiS, pPriv, (overlay.srcW > temp));
+ }
+
+ /* set overlay */
+ set_overlay(pSiS, &overlay, pPriv, index);
+
+ /* enable overlay */
+ if(pSiS->oldChipset > OC_SIS6326) {
+ setvideoregmask (pSiS, Index_VI6326_Control_Misc4, 0x40, 0x40);
+ }
+ setvideoregmask (pSiS, Index_VI6326_Control_Misc0, 0x02, 0x02);
+
+ pPriv->mustwait = 0;
+}
+
+static FBLinearPtr
+SIS6326AllocateOverlayMemory(
+ ScrnInfoPtr pScrn,
+ FBLinearPtr linear,
+ int size
+){
+ ScreenPtr pScreen;
+ FBLinearPtr new_linear;
+
+ if(linear) {
+ if(linear->size >= size)
+ return linear;
+
+ if(xf86ResizeOffscreenLinear(linear, size))
+ return linear;
+
+ xf86FreeOffscreenLinear(linear);
+ }
+
+ pScreen = screenInfo.screens[pScrn->scrnIndex];
+
+ new_linear = xf86AllocateOffscreenLinear(pScreen, size, 32,
+ NULL, NULL, NULL);
+
+ if(!new_linear) {
+ int max_size;
+
+ xf86QueryLargestOffscreenLinear(pScreen, &max_size, 32,
+ PRIORITY_EXTREME);
+
+ if(max_size < size) return NULL;
+
+ xf86PurgeUnlockedOffscreenAreas(pScreen);
+ new_linear = xf86AllocateOffscreenLinear(pScreen, size, 32,
+ NULL, NULL, NULL);
+ }
+ if (!new_linear)
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Xv: Failed to allocate %dK of video memory\n", size/1024);
+
+ return new_linear;
+}
+
+static void
+SIS6326FreeOverlayMemory(ScrnInfoPtr pScrn)
+{
+ SISPortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn);
+
+ if(pPriv->linear) {
+ xf86FreeOffscreenLinear(pPriv->linear);
+ pPriv->linear = NULL;
+ }
+}
+
+static void
+SIS6326StopVideo(ScrnInfoPtr pScrn, pointer data, Bool shutdown)
+{
+ SISPortPrivPtr pPriv = (SISPortPrivPtr)data;
+ SISPtr pSiS = SISPTR(pScrn);
+
+ if(pPriv->grabbedByV4L)
+ return;
+
+ REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
+
+ if(shutdown) {
+ if(pPriv->videoStatus & CLIENT_VIDEO_ON) {
+ close_overlay(pSiS, pPriv);
+ pPriv->mustwait = 1;
+ }
+ SIS6326FreeOverlayMemory(pScrn);
+ pPriv->videoStatus = 0;
+ pSiS->VideoTimerCallback = NULL;
+ } else {
+ if(pPriv->videoStatus & CLIENT_VIDEO_ON) {
+ pPriv->videoStatus = OFF_TIMER | CLIENT_VIDEO_ON;
+ pPriv->offTime = currentTime.milliseconds + OFF_DELAY;
+ pSiS->VideoTimerCallback = SIS6326VideoTimerCallback;
+ }
+ }
+}
+
+static int
+SIS6326PutImage(
+ ScrnInfoPtr pScrn,
+ short src_x, short src_y,
+ short drw_x, short drw_y,
+ short src_w, short src_h,
+ short drw_w, short drw_h,
+ int id, unsigned char* buf,
+ short width, short height,
+ Bool sync,
+ RegionPtr clipBoxes, pointer data
+){
+ SISPtr pSiS = SISPTR(pScrn);
+ SISPortPrivPtr pPriv = (SISPortPrivPtr)data;
+
+ int totalSize=0;
+ int depth = pSiS->CurrentLayout.bitsPerPixel >> 3;
+
+ if(pPriv->grabbedByV4L)
+ return Success;
+
+ pPriv->drw_x = drw_x;
+ pPriv->drw_y = drw_y;
+ pPriv->drw_w = drw_w;
+ pPriv->drw_h = drw_h;
+ pPriv->src_x = src_x;
+ pPriv->src_y = src_y;
+ pPriv->src_w = src_w;
+ pPriv->src_h = src_h;
+ pPriv->id = id;
+ pPriv->height = height;
+ pPriv->width = width;
+
+ /* TW: Pixel formats:
+ 1. YU12: 3 planes: H V
+ Y sample period 1 1 (8 bit per pixel)
+ V sample period 2 2 (8 bit per pixel, subsampled)
+ U sample period 2 2 (8 bit per pixel, subsampled)
+
+ Y plane is fully sampled (width*height), U and V planes
+ are sampled in 2x2 blocks, hence a group of 4 pixels requires
+ 4 + 1 + 1 = 6 bytes. The data is planar, ie in single planes
+ for Y, U and V.
+ 2. UYVY: 3 planes: H V
+ Y sample period 1 1 (8 bit per pixel)
+ V sample period 2 1 (8 bit per pixel, subsampled)
+ U sample period 2 1 (8 bit per pixel, subsampled)
+ Y plane is fully sampled (width*height), U and V planes
+ are sampled in 2x1 blocks, hence a group of 4 pixels requires
+ 4 + 2 + 2 = 8 bytes. The data is bit packed, there are no separate
+ Y, U or V planes.
+ Bit order: U0 Y0 V0 Y1 U2 Y2 V2 Y3 ...
+ 3. I420: Like YU12, but planes U and V are in reverse order.
+ 4. YUY2: Like UYVY, but order is
+ Y0 U0 Y1 V0 Y2 U2 Y3 V2 ...
+ */
+
+ switch(id){
+ case PIXEL_FMT_YV12:
+ case PIXEL_FMT_I420:
+ pPriv->srcPitch = (width + 7) & ~7;
+ /* Size = width * height * 3 / 2 */
+ totalSize = (pPriv->srcPitch * height * 3) >> 1;
+ break;
+ case PIXEL_FMT_YUY2:
+ case PIXEL_FMT_UYVY:
+ case PIXEL_FMT_RGB5:
+ case PIXEL_FMT_RGB6:
+ default:
+ pPriv->srcPitch = ((width << 1) + 3) & ~3;
+ /* Size = width * 2 * height */
+ totalSize = pPriv->srcPitch * height;
+ }
+
+ pPriv->totalSize = totalSize;
+
+ /* allocate memory (we do doublebuffering) */
+ if(!(pPriv->linear = SIS6326AllocateOverlayMemory(pScrn, pPriv->linear,
+ totalSize<<1)))
+ return BadAlloc;
+
+ /* fixup pointers */
+ pPriv->bufAddr[0] = (pPriv->linear->offset * depth);
+ pPriv->bufAddr[1] = pPriv->bufAddr[0] + totalSize;
+
+ /* copy data */
+ memcpy(pSiS->FbBase + pPriv->bufAddr[pPriv->currentBuf], buf, totalSize);
+
+ SIS6326DisplayVideo(pScrn, pPriv);
+
+ /* update cliplist */
+ if( pPriv->autopaintColorKey &&
+ (pPriv->grabbedByV4L || !RegionsEqual(&pPriv->clip, clipBoxes))) {
+ /* We always paint colorkey for V4L */
+ if (!pPriv->grabbedByV4L)
+ REGION_COPY(pScreen, &pPriv->clip, clipBoxes);
+ /* draw these */
+ /* xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes); - for X4.2 */
+ XAAFillSolidRects(pScrn, pPriv->colorKey, GXcopy, ~0,
+ REGION_NUM_RECTS(clipBoxes),
+ REGION_RECTS(clipBoxes));
+ }
+
+ pPriv->currentBuf ^= 1;
+
+ pPriv->videoStatus = CLIENT_VIDEO_ON;
+
+ pSiS->VideoTimerCallback = SIS6326VideoTimerCallback;
+
+ return Success;
+}
+
+static int
+SIS6326QueryImageAttributes(
+ ScrnInfoPtr pScrn,
+ int id,
+ unsigned short *w, unsigned short *h,
+ int *pitches, int *offsets
+){
+ SISPtr pSiS = SISPTR(pScrn);
+ int pitchY, pitchUV;
+ int size, sizeY, sizeUV;
+
+ if(*w < IMAGE_MIN_WIDTH) *w = IMAGE_MIN_WIDTH;
+ if(*h < IMAGE_MIN_HEIGHT) *h = IMAGE_MIN_HEIGHT;
+
+ if(pSiS->oldChipset < OC_SIS6326) {
+ if(*w > IMAGE_MAX_WIDTH_5597) *w = IMAGE_MAX_WIDTH_5597;
+ if(*h > IMAGE_MAX_HEIGHT_5597) *h = IMAGE_MAX_HEIGHT_5597;
+ } else {
+ if(*w > IMAGE_MAX_WIDTH) *w = IMAGE_MAX_WIDTH;
+ if(*h > IMAGE_MAX_HEIGHT) *h = IMAGE_MAX_HEIGHT;
+ }
+
+ switch(id) {
+ case PIXEL_FMT_YV12:
+ case PIXEL_FMT_I420:
+ *w = (*w + 7) & ~7;
+ *h = (*h + 1) & ~1;
+ pitchY = *w;
+ pitchUV = *w >> 1;
+ if(pitches) {
+ pitches[0] = pitchY;
+ pitches[1] = pitches[2] = pitchUV;
+ }
+ sizeY = pitchY * (*h);
+ sizeUV = pitchUV * ((*h) >> 1);
+ if(offsets) {
+ offsets[0] = 0;
+ offsets[1] = sizeY;
+ offsets[2] = sizeY + sizeUV;
+ }
+ size = sizeY + (sizeUV << 1);
+ break;
+ case PIXEL_FMT_YUY2:
+ case PIXEL_FMT_UYVY:
+ case PIXEL_FMT_RGB5:
+ case PIXEL_FMT_RGB6:
+ default:
+ *w = (*w + 1) & ~1;
+ pitchY = *w << 1;
+ if(pitches) pitches[0] = pitchY;
+ if(offsets) offsets[0] = 0;
+ size = pitchY * (*h);
+ break;
+ }
+
+ return size;
+}
+
+static void
+SIS6326VideoTimerCallback (ScrnInfoPtr pScrn, Time now)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ SISPortPrivPtr pPriv = NULL;
+ unsigned char sridx, cridx;
+
+ pSiS->VideoTimerCallback = NULL;
+
+ if(!pScrn->vtSema) return;
+
+ if(pSiS->adaptor) {
+ pPriv = GET_PORT_PRIVATE(pScrn);
+ if(!pPriv->videoStatus)
+ pPriv = NULL;
+ }
+
+ if(pPriv) {
+ if(pPriv->videoStatus & TIMER_MASK) {
+ UpdateCurrentTime();
+ if(pPriv->offTime < currentTime.milliseconds) {
+ if(pPriv->videoStatus & OFF_TIMER) {
+ /* Turn off the overlay */
+ sridx = inSISREG(SISSR); cridx = inSISREG(SISCR);
+ close_overlay(pSiS, pPriv);
+ outSISREG(SISSR, sridx); outSISREG(SISCR, cridx);
+ pPriv->mustwait = 1;
+ pPriv->videoStatus = FREE_TIMER;
+ pPriv->freeTime = currentTime.milliseconds + FREE_DELAY;
+ pSiS->VideoTimerCallback = SIS6326VideoTimerCallback;
+ } else
+ if(pPriv->videoStatus & FREE_TIMER) {
+ SIS6326FreeOverlayMemory(pScrn);
+ pPriv->mustwait = 1;
+ pPriv->videoStatus = 0;
+ }
+ } else
+ pSiS->VideoTimerCallback = SIS6326VideoTimerCallback;
+ }
+ }
+}
+
+/* TW: Offscreen surface stuff for v4l */
+
+static int
+SIS6326AllocSurface (
+ ScrnInfoPtr pScrn,
+ int id,
+ unsigned short w,
+ unsigned short h,
+ XF86SurfacePtr surface
+)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ SISPortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn);
+ int size, depth;
+
+ if((w < IMAGE_MIN_WIDTH) || (h < IMAGE_MIN_HEIGHT))
+ return BadValue;
+
+ if(pSiS->oldChipset < OC_SIS6326) {
+ if((w > IMAGE_MAX_WIDTH_5597) || (h > IMAGE_MAX_HEIGHT_5597))
+ return BadValue;
+ } else {
+ if((w > IMAGE_MAX_WIDTH) || (h > IMAGE_MAX_HEIGHT))
+ return BadValue;
+ }
+
+ if(pPriv->grabbedByV4L)
+ return BadAlloc;
+
+ depth = pSiS->CurrentLayout.bitsPerPixel >> 3;
+
+ w = (w + 1) & ~1;
+ pPriv->pitch = ((w << 1) + 63) & ~63; /* Only packed pixel modes supported */
+ size = h * pPriv->pitch;
+ pPriv->linear = SIS6326AllocateOverlayMemory(pScrn, pPriv->linear, size);
+ if(!pPriv->linear)
+ return BadAlloc;
+
+ pPriv->totalSize = size;
+
+ pPriv->offset = pPriv->linear->offset * depth;
+
+ surface->width = w;
+ surface->height = h;
+ surface->pScrn = pScrn;
+ surface->id = id;
+ surface->pitches = &pPriv->pitch;
+ surface->offsets = &pPriv->offset;
+ surface->devPrivate.ptr = (pointer)pPriv;
+
+ close_overlay(pSiS, pPriv);
+ pPriv->videoStatus = 0;
+ REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
+ pSiS->VideoTimerCallback = NULL;
+ pPriv->grabbedByV4L = TRUE;
+ return Success;
+}
+
+static int
+SIS6326StopSurface (XF86SurfacePtr surface)
+{
+ SISPortPrivPtr pPriv = (SISPortPrivPtr)(surface->devPrivate.ptr);
+ SISPtr pSiS = SISPTR(surface->pScrn);
+
+ if(pPriv->grabbedByV4L && pPriv->videoStatus) {
+ close_overlay(pSiS, pPriv);
+ pPriv->mustwait = 1;
+ pPriv->videoStatus = 0;
+ }
+ return Success;
+}
+
+static int
+SIS6326FreeSurface (XF86SurfacePtr surface)
+{
+ SISPortPrivPtr pPriv = (SISPortPrivPtr)(surface->devPrivate.ptr);
+
+ if(pPriv->grabbedByV4L) {
+ SIS6326StopSurface(surface);
+ SIS6326FreeOverlayMemory(surface->pScrn);
+ pPriv->grabbedByV4L = FALSE;
+ }
+ return Success;
+}
+
+static int
+SIS6326GetSurfaceAttribute (
+ ScrnInfoPtr pScrn,
+ Atom attribute,
+ INT32 *value
+)
+{
+ SISPortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn);
+
+ return SIS6326GetPortAttribute(pScrn, attribute, value, (pointer)pPriv);
+}
+
+static int
+SIS6326SetSurfaceAttribute(
+ ScrnInfoPtr pScrn,
+ Atom attribute,
+ INT32 value
+)
+{
+ SISPortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn);;
+
+ return SIS6326SetPortAttribute(pScrn, attribute, value, (pointer)pPriv);
+}
+
+static int
+SIS6326DisplaySurface (
+ XF86SurfacePtr surface,
+ short src_x, short src_y,
+ short drw_x, short drw_y,
+ short src_w, short src_h,
+ short drw_w, short drw_h,
+ RegionPtr clipBoxes
+)
+{
+ ScrnInfoPtr pScrn = surface->pScrn;
+ SISPortPrivPtr pPriv = (SISPortPrivPtr)(surface->devPrivate.ptr);
+
+ if(!pPriv->grabbedByV4L)
+ return Success;
+
+ pPriv->drw_x = drw_x;
+ pPriv->drw_y = drw_y;
+ pPriv->drw_w = drw_w;
+ pPriv->drw_h = drw_h;
+ pPriv->src_x = src_x;
+ pPriv->src_y = src_y;
+ pPriv->src_w = src_w;
+ pPriv->src_h = src_h;
+ pPriv->id = surface->id;
+ pPriv->height = surface->height;
+ pPriv->bufAddr[0] = surface->offsets[0];
+ pPriv->currentBuf = 0;
+ pPriv->srcPitch = surface->pitches[0];
+
+ SIS6326DisplayVideo(pScrn, pPriv);
+
+ if(pPriv->autopaintColorKey) {
+ XAAFillSolidRects(pScrn, pPriv->colorKey, GXcopy, ~0,
+ REGION_NUM_RECTS(clipBoxes),
+ REGION_RECTS(clipBoxes));
+ }
+
+ pPriv->videoStatus = CLIENT_VIDEO_ON;
+
+ return Success;
+}
+
+XF86OffscreenImageRec SIS6326OffscreenImages[2] =
+{
+ {
+ &SIS6326Images[0], /* YUV2 */
+ VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT,
+ SIS6326AllocSurface,
+ SIS6326FreeSurface,
+ SIS6326DisplaySurface,
+ SIS6326StopSurface,
+ SIS6326GetSurfaceAttribute,
+ SIS6326SetSurfaceAttribute,
+ IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT,
+ NUM_ATTRIBUTES,
+ &SIS6326Attributes[0] /* Support all attributes */
+ },
+ {
+ &SIS6326Images[1], /* UYVY */
+ VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT,
+ SIS6326AllocSurface,
+ SIS6326FreeSurface,
+ SIS6326DisplaySurface,
+ SIS6326StopSurface,
+ SIS6326GetSurfaceAttribute,
+ SIS6326SetSurfaceAttribute,
+ IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT,
+ NUM_ATTRIBUTES,
+ &SIS6326Attributes[0] /* Support all attributes */
+ },
+};
+
+static void
+SIS6326InitOffscreenImages(ScreenPtr pScrn)
+{
+ xf86XVRegisterOffscreenImages(pScrn, SIS6326OffscreenImages, 2);
+}
+#else
+int sis_foo;
+#endif
+
diff --git a/src/sis_accel.c b/src/sis_accel.c
new file mode 100644
index 0000000..a9d305f
--- /dev/null
+++ b/src/sis_accel.c
@@ -0,0 +1,651 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_accel.c,v 1.25 2003/01/29 15:42:16 eich Exp $ */
+/*
+ * Copyright 1998,1999 by Alan Hourihane, Wigan, England.
+ * Parts Copyright 2002 Thomas Winischhofer, Vienna, Austria.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, alanh@fairlite.demon.co.uk
+ * Mike Chapman <mike@paranoia.com>,
+ * Juanjo Santamarta <santamarta@ctv.es>,
+ * Mitani Hiroshi <hmitani@drl.mei.co.jp>
+ * David Thomas <davtom@dream.org.uk>
+ * Thomas Winischhofer <thomas@winischhofer.net>
+ */
+
+#if 0
+#define CTSCE /* TW: Include enhanced color expansion code */
+#endif /* This produces drawing errors sometimes */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+#include "sis_accel.h"
+#include "sis_regs.h"
+#include "sis.h"
+#include "xaarop.h"
+
+static void SiSSync(ScrnInfoPtr pScrn);
+static void SiSSetupForFillRectSolid(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask);
+static void SiSSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x,
+ int y, int w, int h);
+static void SiSSetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int xdir, int ydir, int rop,
+ unsigned int planemask, int transparency_color);
+static void SiSSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int x1, int y1, int x2,
+ int y2, int w, int h);
+static void SiSSetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
+ int patternx, int patterny, int fg, int bg,
+ int rop, unsigned int planemask);
+static void SiSSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
+ int patternx, int patterny, int x, int y,
+ int w, int h);
+#if 0
+static void SiSSetupForScreenToScreenColorExpandFill (ScrnInfoPtr pScrn,
+ int fg, int bg,
+ int rop, unsigned int planemask);
+static void SiSSubsequentScreenToScreenColorExpandFill( ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int srcx, int srcy, int offset );
+#endif
+static void SiSSetClippingRectangle ( ScrnInfoPtr pScrn,
+ int left, int top, int right, int bottom);
+static void SiSDisableClipping (ScrnInfoPtr pScrn);
+static void SiSSetupForSolidLine(ScrnInfoPtr pScrn,
+ int color, int rop, unsigned int planemask);
+static void SiSSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn,
+ int x1, int y1, int x2, int y2, int flags);
+static void SiSSubsequentSolidHorVertLine(ScrnInfoPtr pScrn,
+ int x, int y, int len, int dir);
+#ifdef CTSCE
+static void SiSSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask);
+static void SiSSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int skipleft);
+static void SiSSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno);
+#endif
+
+Bool
+SiSAccelInit(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr infoPtr;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ SISPtr pSiS = SISPTR(pScrn);
+ BoxRec AvailFBArea;
+ int topFB, i;
+ int reservedFbSize;
+ int UsableFbSize;
+ unsigned char *AvailBufBase;
+
+ pSiS->AccelInfoPtr = infoPtr = XAACreateInfoRec();
+ if (!infoPtr) return FALSE;
+
+ infoPtr->Flags = LINEAR_FRAMEBUFFER |
+ OFFSCREEN_PIXMAPS |
+ PIXMAP_CACHE;
+
+ /* Sync */
+ infoPtr->Sync = SiSSync;
+
+ /* Screen To Screen copy */
+ infoPtr->SetupForScreenToScreenCopy = SiSSetupForScreenToScreenCopy;
+ infoPtr->SubsequentScreenToScreenCopy = SiSSubsequentScreenToScreenCopy;
+ infoPtr->ScreenToScreenCopyFlags = NO_TRANSPARENCY | NO_PLANEMASK;
+
+ /* Solid fill */
+ infoPtr->SetupForSolidFill = SiSSetupForFillRectSolid;
+ infoPtr->SubsequentSolidFillRect = SiSSubsequentFillRectSolid;
+ infoPtr->SolidFillFlags = NO_PLANEMASK;
+
+ /* On 5597/5598 and 6326, clipping and lines only work
+ for 1024, 2048, 4096 logical width */
+ if(pSiS->ValidWidth) {
+ /* Clipping */
+ infoPtr->SetClippingRectangle = SiSSetClippingRectangle;
+ infoPtr->DisableClipping = SiSDisableClipping;
+ infoPtr->ClippingFlags =
+ HARDWARE_CLIP_SOLID_LINE |
+ HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY |
+ HARDWARE_CLIP_MONO_8x8_FILL |
+ HARDWARE_CLIP_SOLID_FILL ;
+
+ /* Solid Lines */
+ infoPtr->SetupForSolidLine = SiSSetupForSolidLine;
+ infoPtr->SubsequentSolidTwoPointLine = SiSSubsequentSolidTwoPointLine;
+ infoPtr->SubsequentSolidHorVertLine = SiSSubsequentSolidHorVertLine;
+ infoPtr->SolidLineFlags = NO_PLANEMASK;
+ }
+
+ if(pScrn->bitsPerPixel != 24) {
+ /* 8x8 mono pattern */
+ infoPtr->SetupForMono8x8PatternFill = SiSSetupForMono8x8PatternFill;
+ infoPtr->SubsequentMono8x8PatternFillRect = SiSSubsequentMono8x8PatternFillRect;
+ infoPtr->Mono8x8PatternFillFlags =
+ NO_PLANEMASK |
+ HARDWARE_PATTERN_PROGRAMMED_BITS |
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN |
+ BIT_ORDER_IN_BYTE_MSBFIRST;
+ }
+
+#ifdef CTSCE
+ if(pScrn->bitsPerPixel != 24) {
+ /* TW: per-scanline color expansion (using indirect method) */
+ pSiS->ColorExpandBufferNumber = 4;
+ pSiS->ColorExpandBufferCountMask = 0x03;
+ pSiS->PerColorExpandBufferSize = ((pScrn->virtualX + 31) / 32) * 4;
+
+ infoPtr->NumScanlineColorExpandBuffers = pSiS->ColorExpandBufferNumber;
+ infoPtr->ScanlineColorExpandBuffers = (unsigned char **)&pSiS->ColorExpandBufferAddr[0];
+
+ infoPtr->SetupForScanlineCPUToScreenColorExpandFill =
+ SiSSetupForScanlineCPUToScreenColorExpandFill;
+ infoPtr->SubsequentScanlineCPUToScreenColorExpandFill =
+ SiSSubsequentScanlineCPUToScreenColorExpandFill;
+ infoPtr->SubsequentColorExpandScanline =
+ SiSSubsequentColorExpandScanline;
+ infoPtr->ScanlineCPUToScreenColorExpandFillFlags =
+ NO_PLANEMASK |
+ CPU_TRANSFER_PAD_DWORD |
+ SCANLINE_PAD_DWORD |
+ BIT_ORDER_IN_BYTE_MSBFIRST |
+ LEFT_EDGE_CLIPPING;
+ } else {
+ pSiS->ColorExpandBufferNumber = 0;
+ }
+#else
+ pSiS->ColorExpandBufferNumber = 0;
+#endif
+
+ topFB = pSiS->maxxfbmem;
+
+ reservedFbSize = pSiS->ColorExpandBufferNumber * pSiS->PerColorExpandBufferSize;
+
+ UsableFbSize = topFB - reservedFbSize;
+
+ /* Layout: (Sizes do not reflect correct proportions)
+ * |--------------++++++++++++++++++++| ====================~~~~~~~~~~~~|
+ * UsableFbSize ColorExpandBuffers | TurboQueue HWCursor
+ * topFB
+ */
+
+ if(pSiS->ColorExpandBufferNumber) {
+ AvailBufBase = pSiS->FbBase + UsableFbSize;
+ for (i = 0; i < pSiS->ColorExpandBufferNumber; i++) {
+ pSiS->ColorExpandBufferAddr[i] = AvailBufBase +
+ i * pSiS->PerColorExpandBufferSize;
+ pSiS->ColorExpandBufferScreenOffset[i] = UsableFbSize +
+ i * pSiS->PerColorExpandBufferSize;
+ }
+ }
+ AvailFBArea.x1 = 0;
+ AvailFBArea.y1 = 0;
+ AvailFBArea.x2 = pScrn->displayWidth;
+ AvailFBArea.y2 = UsableFbSize / (pScrn->displayWidth * pScrn->bitsPerPixel / 8) - 1;
+
+ if (AvailFBArea.y2 < 0)
+ AvailFBArea.y2 = 32767;
+
+ if(AvailFBArea.y2 < pScrn->currentMode->VDisplay) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Not enough video RAM for accelerator. At least "
+ "%dKB needed, %dKB available\n",
+ ((((pScrn->displayWidth * pScrn->bitsPerPixel/8) /* TW: +8 for make it sure */
+ * pScrn->currentMode->VDisplay) + reservedFbSize) / 1024) + 8,
+ pSiS->maxxfbmem/1024);
+ pSiS->NoAccel = TRUE;
+ pSiS->NoXvideo = TRUE;
+ XAADestroyInfoRec(pSiS->AccelInfoPtr);
+ pSiS->AccelInfoPtr = NULL;
+ return FALSE;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Frame Buffer From (%d,%d) To (%d,%d)\n",
+ AvailFBArea.x1, AvailFBArea.y1, AvailFBArea.x2, AvailFBArea.y2);
+
+ xf86InitFBManager(pScreen, &AvailFBArea);
+
+ return(XAAInit(pScreen, infoPtr));
+}
+
+/* sync */
+static void
+SiSSync(ScrnInfoPtr pScrn) {
+ SISPtr pSiS = SISPTR(pScrn);
+ sisBLTSync;
+}
+
+/* Clipping */
+static void SiSSetClippingRectangle ( ScrnInfoPtr pScrn,
+ int left, int top, int right, int bottom)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+
+ sisBLTSync;
+ sisSETCLIPTOP(left,top);
+ sisSETCLIPBOTTOM(right,bottom);
+ pSiS->ClipEnabled = TRUE;
+}
+
+static void SiSDisableClipping (ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ pSiS->ClipEnabled = FALSE;
+}
+
+static const int sisALUConv[] =
+{
+ 0x00, /* dest = 0; 0, GXclear, 0 */
+ 0x88, /* dest &= src; DSa, GXand, 0x1 */
+ 0x44, /* dest = src & ~dest; SDna, GXandReverse, 0x2 */
+ 0xCC, /* dest = src; S, GXcopy, 0x3 */
+ 0x22, /* dest &= ~src; DSna, GXandInverted, 0x4 */
+ 0xAA, /* dest = dest; D, GXnoop, 0x5 */
+ 0x66, /* dest = ^src; DSx, GXxor, 0x6 */
+ 0xEE, /* dest |= src; DSo, GXor, 0x7 */
+ 0x11, /* dest = ~src & ~dest; DSon, GXnor, 0x8 */
+ 0x99, /* dest ^= ~src ; DSxn, GXequiv, 0x9 */
+ 0x55, /* dest = ~dest; Dn, GXInvert, 0xA */
+ 0xDD, /* dest = src|~dest ; SDno, GXorReverse, 0xB */
+ 0x33, /* dest = ~src; Sn, GXcopyInverted, 0xC */
+ 0xBB, /* dest |= ~src; DSno, GXorInverted, 0xD */
+ 0x77, /* dest = ~src|~dest; DSan, GXnand, 0xE */
+ 0xFF, /* dest = 0xFF; 1, GXset, 0xF */
+};
+/* same ROP but with Pattern as Source */
+static const int sisPatALUConv[] =
+{
+ 0x00, /* dest = 0; 0, GXclear, 0 */
+ 0xA0, /* dest &= src; DPa, GXand, 0x1 */
+ 0x50, /* dest = src & ~dest; PDna, GXandReverse, 0x2 */
+ 0xF0, /* dest = src; P, GXcopy, 0x3 */
+ 0x0A, /* dest &= ~src; DPna, GXandInverted, 0x4 */
+ 0xAA, /* dest = dest; D, GXnoop, 0x5 */
+ 0x5A, /* dest = ^src; DPx, GXxor, 0x6 */
+ 0xFA, /* dest |= src; DPo, GXor, 0x7 */
+ 0x05, /* dest = ~src & ~dest; DPon, GXnor, 0x8 */
+ 0xA5, /* dest ^= ~src ; DPxn, GXequiv, 0x9 */
+ 0x55, /* dest = ~dest; Dn, GXInvert, 0xA */
+ 0xF5, /* dest = src|~dest ; PDno, GXorReverse, 0xB */
+ 0x0F, /* dest = ~src; Pn, GXcopyInverted, 0xC */
+ 0xAF, /* dest |= ~src; DPno, GXorInverted, 0xD */
+ 0x5F, /* dest = ~src|~dest; DPan, GXnand, 0xE */
+ 0xFF, /* dest = 0xFF; 1, GXset, 0xF */
+};
+
+
+/* Screen to screen copy */
+static void
+SiSSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir,
+ int rop, unsigned int planemask,
+ int transparency_color)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ sisBLTSync;
+ sisSETPITCH(pSiS->scrnOffset, pSiS->scrnOffset);
+
+ sisSETROP(XAACopyROP[rop]);
+ pSiS->Xdirection = xdir;
+ pSiS->Ydirection = ydir;
+}
+
+static void
+SiSSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, int x2,
+ int y2, int w, int h)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int srcaddr, destaddr;
+ int op ;
+
+ op = sisCMDBLT | sisSRCVIDEO;
+ if(pSiS->Ydirection == -1) {
+ op |= sisBOTTOM2TOP;
+ srcaddr = (y1 + h - 1) * pSiS->CurrentLayout.displayWidth;
+ destaddr = (y2 + h - 1) * pSiS->CurrentLayout.displayWidth;
+ } else {
+ op |= sisTOP2BOTTOM;
+ srcaddr = y1 * pSiS->CurrentLayout.displayWidth;
+ destaddr = y2 * pSiS->CurrentLayout.displayWidth;
+ }
+ if(pSiS->Xdirection == -1) {
+ op |= sisRIGHT2LEFT;
+ srcaddr += x1 + w - 1;
+ destaddr += x2 + w - 1;
+ } else {
+ op |= sisLEFT2RIGHT;
+ srcaddr += x1;
+ destaddr += x2;
+ }
+ if (pSiS->ClipEnabled)
+ op |= sisCLIPINTRN | sisCLIPENABL;
+
+ srcaddr *= (pSiS->CurrentLayout.bitsPerPixel/8);
+ destaddr *= (pSiS->CurrentLayout.bitsPerPixel/8);
+ if(((pSiS->CurrentLayout.bitsPerPixel / 8) > 1) && (pSiS->Xdirection == -1)) {
+ srcaddr += (pSiS->CurrentLayout.bitsPerPixel/8)-1;
+ destaddr += (pSiS->CurrentLayout.bitsPerPixel/8)-1;
+ }
+
+ sisBLTSync;
+ sisSETSRCADDR(srcaddr);
+ sisSETDSTADDR(destaddr);
+ sisSETHEIGHTWIDTH(h-1, w * (pSiS->CurrentLayout.bitsPerPixel/8)-1);
+ sisSETCMD(op);
+}
+
+/* solid fill */
+static void
+SiSSetupForFillRectSolid(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned int planemask)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+
+ sisBLTSync;
+ sisSETBGROPCOL(XAACopyROP[rop], color);
+ sisSETFGROPCOL(XAACopyROP[rop], color);
+ sisSETPITCH(pSiS->scrnOffset, pSiS->scrnOffset);
+}
+
+static void
+SiSSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, int y, int w, int h)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int destaddr, op;
+
+ destaddr = y * pSiS->CurrentLayout.displayWidth + x;
+
+ op = sisCMDBLT | sisSRCBG | sisTOP2BOTTOM | sisLEFT2RIGHT;
+
+ if(pSiS->ClipEnabled)
+ op |= sisCLIPINTRN | sisCLIPENABL;
+
+ destaddr *= (pSiS->CurrentLayout.bitsPerPixel / 8);
+
+ sisBLTSync;
+ sisSETHEIGHTWIDTH(h-1, w * (pSiS->CurrentLayout.bitsPerPixel/8)-1);
+ sisSETDSTADDR(destaddr);
+ sisSETCMD(op);
+}
+
+/* 8x8 mono */
+static void
+SiSSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patternx, int patterny,
+ int fg, int bg, int rop, unsigned int planemask)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ unsigned int *patternRegPtr;
+ int i;
+
+ (void)XAAHelpPatternROP(pScrn, &fg, &bg, planemask, &rop);
+
+ sisBLTSync;
+ if(bg != -1) {
+ sisSETBGROPCOL(0xcc, bg); /* copy */
+ } else {
+ sisSETBGROPCOL(0xAA, bg); /* noop */
+ }
+ sisSETFGROPCOL(rop, fg);
+ sisSETPITCH(0, pSiS->scrnOffset);
+ sisSETSRCADDR(0);
+ patternRegPtr = (unsigned int *)sisSETPATREG();
+ pSiS->sisPatternReg[0] = pSiS->sisPatternReg[2] = patternx ;
+ pSiS->sisPatternReg[1] = pSiS->sisPatternReg[3] = patterny ;
+ for ( i = 0 ; i < 16 /* sisPatternHeight */ ; ) {
+ patternRegPtr[i++] = patternx ;
+ patternRegPtr[i++] = patterny ;
+ }
+}
+
+static void
+SiSSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patternx,
+ int patterny, int x, int y, int w, int h)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int dstaddr;
+ register unsigned char *patternRegPtr;
+ register unsigned char *srcPatternRegPtr;
+ register unsigned int *patternRegPtrL;
+ int i, k;
+ unsigned short tmp;
+ int shift;
+ int op = sisCMDCOLEXP |
+ sisTOP2BOTTOM |
+ sisLEFT2RIGHT |
+ sisPATFG |
+ sisSRCBG;
+
+ if (pSiS->ClipEnabled)
+ op |= sisCLIPINTRN | sisCLIPENABL;
+
+ dstaddr = ( y * pSiS->CurrentLayout.displayWidth + x ) *
+ pSiS->CurrentLayout.bitsPerPixel / 8;
+
+ sisBLTSync;
+
+ patternRegPtr = sisSETPATREG();
+ srcPatternRegPtr = (unsigned char *)pSiS->sisPatternReg ;
+ shift = 8 - patternx ;
+ for ( i = 0, k = patterny ; i < 8 ; i++, k++ ) {
+ tmp = srcPatternRegPtr[k]<<8 | srcPatternRegPtr[k] ;
+ tmp >>= shift ;
+ patternRegPtr[i] = tmp & 0xff;
+ }
+ patternRegPtrL = (unsigned int *)sisSETPATREG();
+ for ( i = 2 ; i < 16 /* sisPatternHeight */; ) {
+ patternRegPtrL[i++] = patternRegPtrL[0];
+ patternRegPtrL[i++] = patternRegPtrL[1];
+ }
+
+ sisSETDSTADDR(dstaddr);
+ sisSETHEIGHTWIDTH(h-1, w*(pSiS->CurrentLayout.bitsPerPixel/8)-1);
+ sisSETCMD(op);
+}
+
+/* Line */
+static void SiSSetupForSolidLine(ScrnInfoPtr pScrn,
+ int color, int rop, unsigned int planemask)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+
+ sisBLTSync;
+ sisSETBGROPCOL(XAACopyROP[rop], 0);
+ sisSETFGROPCOL(XAACopyROP[rop], color);
+}
+
+static void SiSSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn,
+ int x1, int y1, int x2, int y2, int flags)
+
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int op ;
+ int major, minor, err,K1,K2, tmp;
+
+ op = sisCMDLINE | sisSRCFG;
+
+ if ((flags & OMIT_LAST))
+ op |= sisLASTPIX;
+
+ if (pSiS->ClipEnabled)
+ op |= sisCLIPINTRN | sisCLIPENABL;
+
+ if ((major = x2 - x1) <= 0) {
+ major = -major;
+ } else
+ op |= sisXINCREASE;
+
+ if ((minor = y2 - y1) <= 0) {
+ minor = -minor;
+ } else
+ op |= sisYINCREASE;
+
+ if (minor >= major) {
+ tmp = minor;
+ minor = major;
+ major = tmp;
+ } else
+ op |= sisXMAJOR;
+
+ K1 = (minor - major)<<1;
+ K2 = minor<<1;
+ err = (minor<<1) - major;
+
+ sisBLTSync;
+ sisSETXStart(x1);
+ sisSETYStart(y1);
+ sisSETLineSteps((short)K1,(short)K2);
+ sisSETLineErrorTerm((short)err);
+ sisSETLineMajorCount((short)major);
+ sisSETCMD(op);
+}
+
+static void SiSSubsequentSolidHorVertLine(ScrnInfoPtr pScrn,
+ int x, int y, int len, int dir)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int destaddr, op;
+
+ destaddr = y * pSiS->CurrentLayout.displayWidth + x;
+
+ op = sisCMDBLT | sisSRCFG | sisTOP2BOTTOM | sisLEFT2RIGHT;
+
+ if (pSiS->ClipEnabled)
+ op |= sisCLIPINTRN | sisCLIPENABL;
+
+ destaddr *= (pSiS->CurrentLayout.bitsPerPixel / 8);
+
+ sisBLTSync;
+
+ sisSETPITCH(pSiS->scrnOffset, pSiS->scrnOffset);
+
+ if(dir == DEGREES_0) {
+ sisSETHEIGHTWIDTH(0, len * (pSiS->CurrentLayout.bitsPerPixel >> 3) - 1);
+ } else {
+ sisSETHEIGHTWIDTH(len - 1, (pSiS->CurrentLayout.bitsPerPixel >> 3) - 1);
+ }
+
+ sisSETDSTADDR(destaddr);
+ sisSETCMD(op);
+}
+
+#ifdef CTSCE
+/* TW: ----- CPU To Screen Color Expand (scanline-wise) ------ */
+static void
+SiSSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop, unsigned int planemask)
+{
+ SISPtr pSiS=SISPTR(pScrn);
+
+ pSiS->CommandReg = 0;
+
+ pSiS->CommandReg |= (sisCMDECOLEXP |
+ sisLEFT2RIGHT |
+ sisTOP2BOTTOM);
+
+ sisBLTSync;
+
+ /* TW: The combination of flags in the following
+ * is not understandable. However, this is the
+ * only combination that seems to work.
+ */
+ if(bg == -1) {
+ sisSETROPBG(0xAA); /* dst = dst (=noop) */
+ pSiS->CommandReg |= sisSRCFG;
+ } else {
+ sisSETBGROPCOL(sisPatALUConv[rop], bg);
+ pSiS->CommandReg |= sisSRCFG | sisPATBG;
+ }
+
+ sisSETFGROPCOL(sisALUConv[rop], fg);
+
+ sisSETDSTPITCH(pSiS->scrnOffset);
+}
+
+
+static void
+SiSSubsequentScanlineCPUToScreenColorExpandFill(
+ ScrnInfoPtr pScrn, int x, int y, int w,
+ int h, int skipleft)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int _x0, _y0, _x1, _y1;
+ int op = pSiS->CommandReg;
+
+ if(skipleft > 0) {
+ _x0 = x + skipleft;
+ _y0 = y;
+ _x1 = x + w;
+ _y1 = y + h;
+ sisSETCLIPTOP(_x0, _y0);
+ sisSETCLIPBOTTOM(_x1, _y1);
+ op |= sisCLIPENABL;
+ } else {
+ op &= (~(sisCLIPINTRN | sisCLIPENABL));
+ }
+
+ sisSETSRCPITCH(((((w+7)/8)+3) >> 2) * 4);
+
+ sisSETHEIGHTWIDTH(1-1, (w * (pSiS->CurrentLayout.bitsPerPixel/8)) - 1);
+
+ pSiS->xcurrent = x;
+ pSiS->ycurrent = y;
+
+ pSiS->CommandReg = op;
+}
+
+static void
+SiSSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ long cbo = pSiS->ColorExpandBufferScreenOffset[bufno];
+ int op = pSiS->CommandReg;
+ int destaddr;
+
+ destaddr = (pSiS->ycurrent * pSiS->CurrentLayout.displayWidth) + pSiS->xcurrent;
+ destaddr *= (pSiS->CurrentLayout.bitsPerPixel / 8);
+
+ /* TW: Wait until there is no color expansion command in queue */
+ /* sisBLTSync; */
+
+ sisSETSRCADDR(cbo);
+
+ sisSETDSTADDR(destaddr);
+
+ sisSETCMD(op);
+
+ pSiS->ycurrent++;
+
+ /* TW: Wait for eventual color expand commands to finish */
+ /* (needs to be done, otherwise the data in the buffer may
+ * be overwritten while accessed by the hardware)
+ */
+ while((MMIO_IN32(pSiS->IOBase, 0x8284) & 0x80000000)) {}
+
+ sisBLTSync;
+}
+#endif /* CTSCE */
+
+
diff --git a/src/sis_accel.h b/src/sis_accel.h
new file mode 100644
index 0000000..e0d2d3f
--- /dev/null
+++ b/src/sis_accel.h
@@ -0,0 +1,237 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_accel.h,v 1.2 2003/01/29 15:42:16 eich Exp $ */
+/*
+ * Copyright 1998,1999 by Alan Hourihane, Wigan, England.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, alanh@fairlite.demon.co.uk
+ * Mike Chapman <mike@paranoia.com>,
+ * Juanjo Santamarta <santamarta@ctv.es>,
+ * Mitani Hiroshi <hmitani@drl.mei.co.jp>
+ * David Thomas <davtom@dream.org.uk>
+ * Thomas Winischhofer <thomas@winischhofer.net>
+ */
+
+/* Definitions for the SIS engine communication. ------------------------------------ */
+
+/* For pre-530 chipsets only!!! */
+
+/* Engine Registers for 1st generation engines (5597/5598/6326) */
+const int sisReg32MMIO[] = {
+ 0x8280,0x8284,0x8288,0x828C,0x8290,0x8294,
+ 0x8298,0x829C,0x82A0,0x82A4,0x82A8,0x82AC
+};
+
+#define BR(x) sisReg32MMIO[x]
+
+/* These are done using Memory Mapped IO, of the registers */
+/*
+ * Modified for Sis by Xavier Ducoin (xavier@rd.lectra.fr)
+ *
+ */
+
+/* Command Reg 0 (0x82aa, [15:0]) */
+#define sisSRCBG 0x0000 /* source select */
+#define sisSRCFG 0x0001
+#define sisSRCVIDEO 0x0002
+#define sisSRCSYSTEM 0x0003
+
+#define sisPATFG 0x0004 /* pattern select */
+#define sisPATREG 0x0008
+#define sisPATBG 0x0000
+
+#define sisLEFT2RIGHT 0x0010 /* Direction select */
+#define sisRIGHT2LEFT 0x0000
+#define sisTOP2BOTTOM 0x0020
+#define sisBOTTOM2TOP 0x0000
+#define sisXINCREASE sisLEFT2RIGHT
+#define sisYINCREASE sisTOP2BOTTOM
+
+#define sisCLIPENABL 0x0040 /* Clipping select */
+#define sisCLIPINTRN 0x0080
+#define sisCLIPEXTRN 0x0000
+
+#define sisCMDBLT 0x0000 /* Command select */
+#define sisCMDBLTMSK 0x0100
+#define sisCMDCOLEXP 0x0200
+#define sisCMDLINE 0x0300
+#define sisFLGECOLEXP 0x2000
+#define sisCMDECOLEXP (sisCMDCOLEXP | sisFLGECOLEXP)
+
+#define sisLASTPIX 0x0800 /* Line parameters */
+#define sisXMAJOR 0x0400
+
+
+/* Macros to do useful things with the SIS BitBLT engine */
+
+#define sisBLTSync \
+ while(MMIO_IN16(pSiS->IOBase, BR(10) + 2) & 0x4000) {}
+
+/* According to SiS 6326 2D programming guide, 16 bits position at */
+/* 0x82A8 returns queue free. But this don't work, so don't wait */
+/* anything when turbo-queue is enabled. If there are frequent syncs */
+/* this should work. But not for xaa_benchmark :-( */
+
+/* TW: Bit 16 only applies to the hardware queue, not the software
+ * (=turbo) queue.
+ */
+
+#define sisBLTWAIT \
+ if(!pSiS->TurboQueue) { \
+ while(MMIO_IN16(pSiS->IOBase, BR(10) + 2) & 0x4000) {} \
+ } else { \
+ sisBLTSync \
+ }
+
+#define sisSETPATREG() \
+ ((unsigned char *)(pSiS->IOBase + BR(11)))
+
+#define sisSETPATREGL() \
+ ((unsigned long *)(pSiS->IOBase + BR(11)))
+
+/* trigger command */
+#define sisSETCMD(op) \
+ { \
+ unsigned long temp; \
+ MMIO_OUT16(pSiS->IOBase, BR(10) + 2, op); \
+ temp = MMIO_IN32(pSiS->IOBase, BR(10)); \
+ }
+
+/* set foreground color and fg ROP */
+#define sisSETFGROPCOL(rop, color) \
+ MMIO_OUT32(pSiS->IOBase, BR(4), ((rop << 24) | (color & 0xFFFFFF)));
+
+/* set background color and bg ROP */
+#define sisSETBGROPCOL(rop, color) \
+ MMIO_OUT32(pSiS->IOBase, BR(5), ((rop << 24) | (color & 0xFFFFFF)));
+
+/* background color */
+#define sisSETBGCOLOR(bgColor) \
+ MMIO_OUT32(pSiS->IOBase, BR(5), (bgColor));
+#if 0
+ *(volatile unsigned int *)(pSiS->IOBase + BR(5)) = (bgColor)
+#endif
+
+/* foreground color */
+#define sisSETFGCOLOR(fgColor) \
+ MMIO_OUT32(pSiS->IOBase, BR(4), (fgcolor));
+#if 0
+ *(volatile unsigned int *)(pSiS->IOBase + BR(4)) = (fgColor)
+#endif
+
+/* ROP */
+#define sisSETROPFG(op) \
+ MMIO_OUT8(pSiS->IOBase, BR(4) + 3, op);
+#if 0
+ *(volatile unsigned int *)(pSiS->IOBase + BR(4)) = ((*(volatile unsigned int *)(pSiS->IOBase + BR(4)))&0xffffff) | (op<<24)
+#endif
+
+#define sisSETROPBG(op) \
+ MMIO_OUT8(pSiS->IOBase, BR(5) + 3, op);
+#if 0
+ *(volatile unsigned int *)(pSiS->IOBase + BR(5)) = ((*(volatile unsigned int *)(pSiS->IOBase + BR(5)))&0xffffff) | (op<<24)
+#endif
+
+#define sisSETROP(op) \
+ sisSETROPFG(op); sisSETROPBG(op);
+
+/* source and dest address */
+#define sisSETSRCADDR(srcAddr) \
+ MMIO_OUT32(pSiS->IOBase, BR(0), (srcAddr & 0x3FFFFFL));
+#if 0
+ *(volatile unsigned int *)(pSiS->IOBase + BR(0)) = srcAddr & 0x3FFFFFL
+#endif
+
+#define sisSETDSTADDR(dstAddr) \
+ MMIO_OUT32(pSiS->IOBase, BR(1), (dstAddr & 0x3FFFFFL));
+#if 0
+ *(volatile unsigned int *)(pSiS->IOBase + BR(1)) = dstAddr & 0x3FFFFFL
+#endif
+
+/* pitch */
+#define sisSETPITCH(srcPitch,dstPitch) \
+ MMIO_OUT32(pSiS->IOBase, BR(2), ((((dstPitch) & 0xFFFF) << 16) | ((srcPitch) & 0xFFFF)));
+#if 0
+ *(volatile unsigned int *)(pSiS->IOBase + BR(2)) = ((dstPitch&0xFFFF)<<16)| \
+ (srcPitch&0xFFFF)
+#endif
+
+#define sisSETSRCPITCH(srcPitch) \
+ MMIO_OUT16(pSiS->IOBase, BR(2), ((srcPitch) & 0xFFFF));
+
+#define sisSETDSTPITCH(dstPitch) \
+ MMIO_OUT16(pSiS->IOBase, BR(2) + 2, ((dstPitch) & 0xFFFF));
+
+/* Height and width
+ * According to SIS 2D Engine Programming Guide
+ * height -1, width - 1 independant of Bpp
+ */
+#define sisSETHEIGHTWIDTH(Height, Width) \
+ MMIO_OUT32(pSiS->IOBase, BR(3), ((((Height) & 0xFFFF) << 16) | ((Width) & 0xFFFF)));
+#if 0
+ *(volatile unsigned int *)(pSiS->IOBase + BR(3)) = (((Height)&0xFFFF)<<16)| \
+ ((Width)&0xFFFF)
+#endif
+
+/* Clipping */
+#define sisSETCLIPTOP(x, y) \
+ MMIO_OUT32(pSiS->IOBase, BR(8), ((((y) & 0xFFFF) << 16) | ((x) & 0xFFFF)));
+#if 0
+ *(volatile unsigned int *)(pSiS->IOBase + BR(8)) = (((y)&0xFFFF)<<16)| \
+ ((x)&0xFFFF)
+#endif
+
+#define sisSETCLIPBOTTOM(x, y) \
+ MMIO_OUT32(pSiS->IOBase, BR(9), ((((y) & 0xFFFF) << 16) | ((x) & 0xFFFF)));
+#if 0
+ *(volatile unsigned int *)(pSiS->IOBase + BR(9)) = (((y)&0xFFFF)<<16)| \
+ ((x)&0xFFFF)
+#endif
+
+/* Line drawing */
+#define sisSETXStart(XStart) \
+ MMIO_OUT32(pSiS->IOBase, BR(0), ((XStart) & 0xFFFF));
+#if 0
+ *(volatile unsigned int *)(pSiS->IOBase + BR(0)) = XStart&0xFFFF
+#endif
+
+#define sisSETYStart(YStart) \
+ MMIO_OUT32(pSiS->IOBase, BR(1), ((YStart) & 0xFFFF));
+#if 0
+ *(volatile unsigned int *)(pSiS->IOBase + BR(1)) = YStart&0xFFFF
+#endif
+
+#define sisSETLineMajorCount(MajorAxisCount) \
+ MMIO_OUT32(pSiS->IOBase, BR(3), ((MajorAxisCount) & 0xFFFF));
+#if 0
+ *(volatile unsigned int *)(pSiS->IOBase + BR(3)) = MajorAxisCount&0xFFFF
+#endif
+
+#define sisSETLineSteps(K1,K2) \
+ MMIO_OUT32(pSiS->IOBase, BR(6), ((((K1) & 0xFFFF) << 16) | ((K2) & 0xFFFF)));
+#if 0
+ *(volatile unsigned int *)(pSiS->IOBase + BR(6)) = (((K1)&0xFFFF)<<16)| \
+ ((K2)&0xFFFF)
+#endif
+
+#define sisSETLineErrorTerm(ErrorTerm) \
+ MMIO_OUT16(pSiS->IOBase, BR(7), (ErrorTerm));
+#if 0
+ *(volatile unsigned short *)(pSiS->IOBase + BR(7)) = ErrorTerm
+#endif
diff --git a/src/sis_cursor.c b/src/sis_cursor.c
new file mode 100644
index 0000000..b8aed78
--- /dev/null
+++ b/src/sis_cursor.c
@@ -0,0 +1,1106 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_cursor.c,v 1.10 2003/01/30 21:43:33 tsi Exp $ */
+/*
+ * Copyright 1998,1999 by Alan Hourihane, Wigan, England.
+ * Parts Copyright 2001, 2002 by Thomas Winischhofer, Vienna, Austria.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the copyright holders not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, alanh@fairlite.demon.co.uk
+ * Mike Chapman <mike@paranoia.com>,
+ * Juanjo Santamarta <santamarta@ctv.es>,
+ * Mitani Hiroshi <hmitani@drl.mei.co.jp>
+ * David Thomas <davtom@dream.org.uk>.
+ * Thomas Winischhofer <thomas@winischhofer.net>:
+ */
+
+#include "xf86.h"
+#include "xf86PciInfo.h"
+#include "cursorstr.h"
+#include "vgaHW.h"
+
+#include "sis.h"
+#include "sis_regs.h"
+#include "sis_cursor.h"
+
+#if 0
+#define SIS300_USE_ARGB16
+#endif
+
+extern void SISWaitRetraceCRT1(ScrnInfoPtr pScrn);
+extern void SISWaitRetraceCRT2(ScrnInfoPtr pScrn);
+
+static void
+SiSShowCursor(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ unsigned char sridx, cridx;
+
+ /* TW: Backup current indices of SR and CR since we run async:ly
+ * and might be interrupting an on-going register read/write
+ */
+ sridx = inSISREG(SISSR); cridx = inSISREG(SISCR);
+
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+
+ orSISIDXREG(SISSR, 0x06, 0x40);
+
+ outSISREG(SISSR, sridx); outSISREG(SISCR, cridx);
+}
+
+static void
+SiS300ShowCursor(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+
+#ifdef SISDUALHEAD
+ if(pSiS->DualHeadMode) {
+ if(pSiS->SecondHead) {
+ /* TW: Head 2 is always CRT1 */
+ if(pSiS->UseHWARGBCursor) {
+#ifdef SIS300_USE_ARGB16
+ sis300EnableHWARGB16Cursor()
+#else
+ sis300EnableHWARGBCursor()
+#endif
+ } else {
+ sis300EnableHWCursor()
+ }
+ } else {
+ /* TW: Head 1 is always CRT2 */
+ if(pSiS->UseHWARGBCursor) {
+#ifdef SIS300_USE_ARGB16
+ sis301EnableHWARGB16Cursor()
+#else
+ sis301EnableHWARGBCursor()
+#endif
+ } else {
+ sis301EnableHWCursor()
+ }
+ }
+ } else {
+#endif
+ if(pSiS->UseHWARGBCursor) {
+#ifdef SIS300_USE_ARGB16
+ sis300EnableHWARGB16Cursor()
+#else
+ sis300EnableHWARGBCursor()
+#endif
+ if(pSiS->VBFlags & CRT2_ENABLE) {
+#ifdef SIS300_USE_ARGB16
+ sis301EnableHWARGB16Cursor()
+#else
+ sis301EnableHWARGBCursor()
+#endif
+ }
+ } else {
+ sis300EnableHWCursor()
+ if(pSiS->VBFlags & CRT2_ENABLE) {
+ sis301EnableHWCursor()
+ }
+ }
+#ifdef SISDUALHEAD
+ }
+#endif
+}
+
+/* TW: 310/325 series */
+static void
+SiS310ShowCursor(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+
+#ifdef SISDUALHEAD
+ if(pSiS->DualHeadMode) {
+ if(pSiS->SecondHead) {
+ /* TW: Head 2 is always CRT1 */
+ if(pSiS->UseHWARGBCursor) {
+ sis310EnableHWARGBCursor()
+ } else {
+ sis310EnableHWCursor()
+ }
+ } else {
+ /* TW: Head 1 is always CRT2 */
+ if(pSiS->UseHWARGBCursor) {
+ sis301EnableHWARGBCursor310()
+ } else {
+ sis301EnableHWCursor310()
+ }
+ }
+ } else {
+#endif
+ if(pSiS->UseHWARGBCursor) {
+ sis310EnableHWARGBCursor()
+ if(pSiS->VBFlags & CRT2_ENABLE) {
+ sis301EnableHWARGBCursor310()
+ }
+ } else {
+ sis310EnableHWCursor()
+ if(pSiS->VBFlags & CRT2_ENABLE) {
+ sis301EnableHWCursor310()
+ }
+ }
+#ifdef SISDUALHEAD
+ }
+#endif
+}
+
+static void
+SiSHideCursor(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ unsigned char sridx, cridx;
+
+ sridx = inSISREG(SISSR); cridx = inSISREG(SISCR);
+
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+
+ andSISIDXREG(SISSR, 0x06, 0xBF);
+
+ outSISREG(SISSR, sridx); outSISREG(SISCR, cridx);
+}
+
+static void
+SiS300HideCursor(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+
+#ifdef SISDUALHEAD
+ if(pSiS->DualHeadMode && (!pSiS->ForceCursorOff)) {
+ if(pSiS->SecondHead) {
+ /* TW: Head 2 is always CRT1 */
+ sis300DisableHWCursor()
+ sis300SetCursorPositionY(2000, 0)
+ } else {
+ /* TW: Head 1 is always CRT2 */
+ sis301DisableHWCursor()
+ sis301SetCursorPositionY(2000, 0)
+ }
+ } else {
+#endif
+ sis300DisableHWCursor()
+ sis300SetCursorPositionY(2000, 0)
+ if(pSiS->VBFlags & CRT2_ENABLE) {
+ sis301DisableHWCursor()
+ sis301SetCursorPositionY(2000, 0)
+ }
+#ifdef SISDUALHEAD
+ }
+#endif
+}
+
+/* TW: 310/325 series */
+static void
+SiS310HideCursor(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+
+#ifdef SISDUALHEAD
+ if(pSiS->DualHeadMode && (!pSiS->ForceCursorOff)) {
+ if(pSiS->SecondHead) {
+ /* TW: Head 2 is always CRT1 */
+ sis310DisableHWCursor()
+ sis310SetCursorPositionY(2000, 0)
+ } else {
+ /* TW: Head 1 is always CRT2 */
+ sis301DisableHWCursor310()
+ sis301SetCursorPositionY310(2000, 0)
+ }
+ } else {
+#endif
+ sis310DisableHWCursor()
+ sis310SetCursorPositionY(2000, 0)
+ if(pSiS->VBFlags & CRT2_ENABLE) {
+ sis301DisableHWCursor310()
+ sis301SetCursorPositionY310(2000, 0)
+ }
+#ifdef SISDUALHEAD
+ }
+#endif
+}
+
+static void
+SiSSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ unsigned char x_preset = 0;
+ unsigned char y_preset = 0;
+ int temp;
+ unsigned char sridx, cridx;
+
+ sridx = inSISREG(SISSR); cridx = inSISREG(SISCR);
+
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+
+ if (x < 0) {
+ x_preset = (-x);
+ x = 0;
+ }
+
+ if (y < 0) {
+ y_preset = (-y);
+ y = 0;
+ }
+
+ /* are we in interlaced/doublescan mode? */
+ if (pScrn->currentMode->Flags & V_INTERLACE)
+ y /= 2;
+ else if (pScrn->currentMode->Flags & V_DBLSCAN)
+ y *= 2;
+
+ outSISIDXREG(SISSR, 0x1A, x & 0xff);
+ outSISIDXREG(SISSR, 0x1B, (x & 0xff00) >> 8);
+ outSISIDXREG(SISSR, 0x1D, y & 0xff);
+
+ inSISIDXREG(SISSR, 0x1E, temp);
+ temp &= 0xF8;
+ outSISIDXREG(SISSR, 0x1E, temp | ((y >> 8) & 0x07));
+
+ outSISIDXREG(SISSR, 0x1C, x_preset);
+ outSISIDXREG(SISSR, 0x1F, y_preset);
+
+ outSISREG(SISSR, sridx); outSISREG(SISCR, cridx);
+}
+
+static void
+SiS300SetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ unsigned char x_preset = 0;
+ unsigned char y_preset = 0;
+
+ if (x < 0) {
+ x_preset = (-x);
+ x = 0;
+ }
+ if (y < 0) {
+ y_preset = (-y);
+ y = 0;
+ }
+
+ /* are we in interlaced/doublescan mode? */
+ if(pScrn->currentMode->Flags & V_INTERLACE)
+ y /= 2;
+ else if(pScrn->currentMode->Flags & V_DBLSCAN)
+ y *= 2;
+
+#ifdef SISDUALHEAD
+ if (pSiS->DualHeadMode) {
+ if (pSiS->SecondHead) {
+ /* TW: Head 2 is always CRT1 */
+ sis300SetCursorPositionX(x, x_preset)
+ sis300SetCursorPositionY(y, y_preset)
+ } else {
+ /* TW: Head 1 is always CRT2 */
+ sis301SetCursorPositionX(x+13, x_preset)
+ sis301SetCursorPositionY(y, y_preset)
+ }
+ } else {
+#endif
+ sis300SetCursorPositionX(x, x_preset)
+ sis300SetCursorPositionY(y, y_preset)
+ if(pSiS->VBFlags & CRT2_ENABLE) {
+ sis301SetCursorPositionX(x+13, x_preset)
+ sis301SetCursorPositionY(y, y_preset)
+ }
+#ifdef SISDUALHEAD
+ }
+#endif
+}
+
+static void
+SiS310SetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ unsigned char x_preset = 0;
+ unsigned char y_preset = 0;
+
+ if (x < 0) {
+ x_preset = (-x);
+ x = 0;
+ }
+ if (y < 0) {
+ y_preset = (-y);
+ y = 0;
+ }
+
+ /* are we in interlaced/doublescan mode? */
+ if(pScrn->currentMode->Flags & V_INTERLACE)
+ y /= 2;
+ else if(pScrn->currentMode->Flags & V_DBLSCAN)
+ y *= 2;
+
+#ifdef SISDUALHEAD
+ if (pSiS->DualHeadMode) {
+ if (pSiS->SecondHead) {
+ /* TW: Head 2 is always CRT1 */
+ sis310SetCursorPositionX(x, x_preset)
+ sis310SetCursorPositionY(y, y_preset)
+ } else {
+ /* TW: Head 1 is always CRT2 */
+ sis301SetCursorPositionX310(x + 17, x_preset)
+ sis301SetCursorPositionY310(y, y_preset)
+ }
+ } else {
+#endif
+ sis310SetCursorPositionX(x, x_preset)
+ sis310SetCursorPositionY(y, y_preset)
+ if (pSiS->VBFlags & CRT2_ENABLE) {
+ sis301SetCursorPositionX310(x + 17, x_preset)
+ sis301SetCursorPositionY310(y, y_preset)
+ }
+#ifdef SISDUALHEAD
+ }
+#endif
+}
+
+static void
+SiSSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ unsigned char f_red, f_green, f_blue;
+ unsigned char b_red, b_green, b_blue;
+ unsigned char sridx, cridx;
+
+ sridx = inSISREG(SISSR); cridx = inSISREG(SISCR);
+
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+
+ f_red = (fg & 0x00FF0000) >> (16+2);
+ f_green = (fg & 0x0000FF00) >> (8+2);
+ f_blue = (fg & 0x000000FF) >> 2;
+ b_red = (bg & 0x00FF0000) >> (16+2);
+ b_green = (bg & 0x0000FF00) >> (8+2);
+ b_blue = (bg & 0x000000FF) >> 2;
+
+ outSISIDXREG(SISSR, 0x14, b_red);
+ outSISIDXREG(SISSR, 0x15, b_green);
+ outSISIDXREG(SISSR, 0x16, b_blue);
+ outSISIDXREG(SISSR, 0x17, f_red);
+ outSISIDXREG(SISSR, 0x18, f_green);
+ outSISIDXREG(SISSR, 0x19, f_blue);
+
+ outSISREG(SISSR, sridx); outSISREG(SISCR, cridx);
+}
+
+static void
+SiS300SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+
+#ifdef SISDUALHEAD
+ if(pSiS->DualHeadMode) {
+ if(pSiS->SecondHead) {
+ /* TW: Head 2 is always CRT1 */
+ sis300SetCursorBGColor(bg)
+ sis300SetCursorFGColor(fg)
+ } else {
+ /* TW: Head 1 is always CRT2 */
+ sis301SetCursorBGColor(bg)
+ sis301SetCursorFGColor(fg)
+ }
+ } else {
+#endif
+ sis300SetCursorBGColor(bg)
+ sis300SetCursorFGColor(fg)
+ if(pSiS->VBFlags & CRT2_ENABLE) {
+ sis301SetCursorBGColor(bg)
+ sis301SetCursorFGColor(fg)
+ }
+#ifdef SISDUALHEAD
+ }
+#endif
+}
+
+static void
+SiS310SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+
+#ifdef SISDUALHEAD
+ if(pSiS->DualHeadMode) {
+ if(pSiS->SecondHead) {
+ /* TW: Head 2 is always CRT1 */
+ sis310SetCursorBGColor(bg)
+ sis310SetCursorFGColor(fg)
+ } else {
+ /* TW: Head 1 is always CRT2 */
+ sis301SetCursorBGColor310(bg)
+ sis301SetCursorFGColor310(fg)
+ }
+ } else {
+#endif
+ sis310SetCursorBGColor(bg)
+ sis310SetCursorFGColor(fg)
+ if(pSiS->VBFlags & CRT2_ENABLE) {
+ sis301SetCursorBGColor310(bg)
+ sis301SetCursorFGColor310(fg)
+ }
+#ifdef SISDUALHEAD
+ }
+#endif
+}
+
+static void
+SiSLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int cursor_addr;
+ unsigned char temp;
+ unsigned char sridx, cridx;
+
+ sridx = inSISREG(SISSR); cridx = inSISREG(SISCR);
+
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+
+ cursor_addr = pScrn->videoRam - 1;
+ if(pSiS->CurrentLayout.mode->Flags & V_DBLSCAN) {
+ int i;
+ for(i = 0; i < 32; i++) {
+ memcpy((unsigned char *)pSiS->FbBase + (cursor_addr * 1024) + (32 * i),
+ src + (16 * i), 16);
+ memcpy((unsigned char *)pSiS->FbBase + (cursor_addr * 1024) + (32 * i) + 16,
+ src + (16 * i), 16);
+ }
+ } else {
+ memcpy((unsigned char *)pSiS->FbBase + (cursor_addr * 1024), src, 1024);
+ }
+
+ /* copy bits [21:18] into the top bits of SR38 */
+ inSISIDXREG(SISSR, 0x38, temp);
+ temp &= 0x0F;
+ outSISIDXREG(SISSR, 0x38, temp | ((cursor_addr & 0xF00) >> 4));
+
+ if(pSiS->Chipset == PCI_CHIP_SIS530) {
+ /* store the bit [22] to SR3E */
+ if(cursor_addr & 0x1000) {
+ orSISIDXREG(SISSR, 0x3E, 0x04);
+ } else {
+ andSISIDXREG(SISSR, 0x3E, ~0x04);
+ }
+ }
+
+ /* set HW cursor pattern, use pattern 0xF */
+ orSISIDXREG(SISSR, 0x1E, 0xF0);
+
+ /* disable the hardware cursor side pattern */
+ andSISIDXREG(SISSR, 0x1E, 0xF7);
+
+ outSISREG(SISSR, sridx); outSISREG(SISCR, cridx);
+}
+
+static void
+SiS300LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int cursor_addr;
+ CARD32 status1 = 0, status2 = 0;
+
+#ifdef SISDUALHEAD
+ SISEntPtr pSiSEnt = pSiS->entityPrivate;
+#endif
+
+ cursor_addr = pScrn->videoRam - pSiS->cursorOffset - (pSiS->CursorSize/1024); /* 1K boundary */
+
+#ifdef SISDUALHEAD
+ if(pSiS->DualHeadMode) {
+ /* TW: Use the global (real) FbBase in DHM */
+ if(pSiS->CurrentLayout.mode->Flags & V_DBLSCAN) {
+ int i;
+ for(i = 0; i < 32; i++) {
+ memcpy((unsigned char *)pSiSEnt->FbBase + (cursor_addr * 1024) + (32 * i),
+ src + (16 * i), 16);
+ memcpy((unsigned char *)pSiSEnt->FbBase + (cursor_addr * 1024) + (32 * i) + 16,
+ src + (16 * i), 16);
+ }
+ } else {
+ memcpy((unsigned char *)pSiSEnt->FbBase + (cursor_addr * 1024), src, 1024);
+ }
+ } else
+#endif
+ if(pSiS->CurrentLayout.mode->Flags & V_DBLSCAN) {
+ int i;
+ for(i = 0; i < 32; i++) {
+ memcpy((unsigned char *)pSiS->FbBase + (cursor_addr * 1024) + (32 * i),
+ src + (16 * i), 16);
+ memcpy((unsigned char *)pSiS->FbBase + (cursor_addr * 1024) + (32 * i) + 16,
+ src + (16 * i), 16);
+ }
+ } else {
+ memcpy((unsigned char *)pSiS->FbBase + (cursor_addr * 1024), src, 1024);
+ }
+
+ if(pSiS->UseHWARGBCursor) {
+ if(pSiS->VBFlags & DISPTYPE_CRT1) {
+ status1 = sis300GetCursorStatus;
+ sis300DisableHWCursor()
+ if(pSiS->VBFlags & CRT2_ENABLE) {
+ status2 = sis301GetCursorStatus;
+ sis301DisableHWCursor()
+ }
+ SISWaitRetraceCRT1(pScrn);
+ sis300SwitchToMONOCursor();
+ if(pSiS->VBFlags & CRT2_ENABLE) {
+ SISWaitRetraceCRT2(pScrn);
+ sis301SwitchToMONOCursor();
+ }
+ }
+ }
+ sis300SetCursorAddress(cursor_addr);
+ sis300SetCursorPatternSelect(0);
+ if(status1) sis300SetCursorStatus(status1)
+
+ if(pSiS->VBFlags & CRT2_ENABLE) {
+ if((pSiS->UseHWARGBCursor) && (!pSiS->VBFlags & DISPTYPE_CRT1)) {
+ status2 = sis301GetCursorStatus;
+ sis301DisableHWCursor()
+ SISWaitRetraceCRT2(pScrn);
+ sis301SwitchToMONOCursor();
+ }
+ sis301SetCursorAddress(cursor_addr)
+ sis301SetCursorPatternSelect(0)
+ if(status2) sis301SetCursorStatus(status2)
+ }
+
+ pSiS->UseHWARGBCursor = FALSE;
+}
+
+static void
+SiS310LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int cursor_addr;
+ CARD32 status1 = 0, status2 = 0;
+
+#ifdef SISDUALHEAD
+ SISEntPtr pSiSEnt = pSiS->entityPrivate;
+#endif
+
+ cursor_addr = pScrn->videoRam - pSiS->cursorOffset - (pSiS->CursorSize/1024); /* 1K boundary */
+
+#ifdef SISDUALHEAD
+ if (pSiS->DualHeadMode) {
+ /* TW: Use the global (real) FbBase in DHM */
+ if(pSiS->CurrentLayout.mode->Flags & V_DBLSCAN) {
+ int i;
+ for(i = 0; i < 32; i++) {
+ memcpy((unsigned char *)pSiSEnt->FbBase + (cursor_addr * 1024) + (32 * i),
+ src + (16 * i), 16);
+ memcpy((unsigned char *)pSiSEnt->FbBase + (cursor_addr * 1024) + (32 * i) + 16,
+ src + (16 * i), 16);
+ }
+ } else {
+ memcpy((unsigned char *)pSiSEnt->FbBase + (cursor_addr * 1024), src, 1024);
+ }
+ } else
+#endif
+ if(pSiS->CurrentLayout.mode->Flags & V_DBLSCAN) {
+ int i;
+ for(i = 0; i < 32; i++) {
+ memcpy((unsigned char *)pSiS->FbBase + (cursor_addr * 1024) + (32 * i),
+ src + (16 * i), 16);
+ memcpy((unsigned char *)pSiS->FbBase + (cursor_addr * 1024) + (32 * i) + 16,
+ src + (16 * i), 16);
+ }
+ } else {
+ memcpy((unsigned char *)pSiS->FbBase + (cursor_addr * 1024), src, 1024);
+ }
+
+ if(pSiS->UseHWARGBCursor) {
+ if(pSiS->VBFlags & DISPTYPE_CRT1) {
+ status1 = sis310GetCursorStatus;
+ sis310DisableHWCursor()
+ if(pSiS->VBFlags & CRT2_ENABLE) {
+ status2 = sis301GetCursorStatus310;
+ sis301DisableHWCursor310()
+ }
+ SISWaitRetraceCRT1(pScrn);
+ sis310SwitchToMONOCursor();
+ if(pSiS->VBFlags & CRT2_ENABLE) {
+ SISWaitRetraceCRT2(pScrn);
+ sis301SwitchToMONOCursor310();
+ }
+ }
+ }
+ sis310SetCursorAddress(cursor_addr);
+ sis310SetCursorPatternSelect(0);
+ if(status1) sis310SetCursorStatus(status1)
+
+ if(pSiS->VBFlags & CRT2_ENABLE) {
+ if((pSiS->UseHWARGBCursor) && (!pSiS->VBFlags & DISPTYPE_CRT1)) {
+ status2 = sis301GetCursorStatus310;
+ sis301DisableHWCursor310()
+ SISWaitRetraceCRT2(pScrn);
+ sis301SwitchToMONOCursor310();
+ }
+ sis301SetCursorAddress310(cursor_addr)
+ sis301SetCursorPatternSelect310(0)
+ if(status2) sis301SetCursorStatus310(status2)
+ }
+
+ pSiS->UseHWARGBCursor = FALSE;
+}
+
+static Bool
+SiSUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ DisplayModePtr mode = pScrn->currentMode;
+ SISPtr pSiS = SISPTR(pScrn);
+
+ if(pSiS->Chipset != PCI_CHIP_SIS6326) return TRUE;
+ if(!(pSiS->SiS6326Flags & SIS6326_TVDETECTED)) return TRUE;
+ if((strcmp(mode->name, "PAL800x600U") == 0) ||
+ (strcmp(mode->name, "NTSC640x480U") == 0))
+ return FALSE;
+ else
+ return TRUE;
+}
+
+static Bool
+SiS300UseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ SISPtr pSiS = SISPTR(pScrn);
+ DisplayModePtr mode = pSiS->CurrentLayout.mode; /* pScrn->currentMode; */
+
+ switch (pSiS->Chipset) {
+ case PCI_CHIP_SIS300:
+ case PCI_CHIP_SIS630:
+ case PCI_CHIP_SIS540:
+ if(mode->Flags & V_INTERLACE)
+ return FALSE;
+ if((mode->Flags & V_DBLSCAN) && (pCurs->bits->height > 32))
+ return FALSE;
+ break;
+ case PCI_CHIP_SIS550:
+ case PCI_CHIP_SIS650:
+ case PCI_CHIP_SIS315:
+ case PCI_CHIP_SIS315H:
+ case PCI_CHIP_SIS315PRO:
+ case PCI_CHIP_SIS330:
+ if(mode->Flags & V_INTERLACE)
+ return FALSE;
+ if((mode->Flags & V_DBLSCAN) && (pCurs->bits->height > 32))
+ return FALSE;
+ break;
+ default:
+ if(mode->Flags & V_INTERLACE)
+ return FALSE;
+ if((mode->Flags & V_DBLSCAN) && (pCurs->bits->height > 32))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,99,0,0)
+#ifdef ARGB_CURSOR
+#ifdef SIS_ARGB_CURSOR
+static Bool
+SiSUseHWCursorARGB(ScreenPtr pScreen, CursorPtr pCurs)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ DisplayModePtr mode = pScrn->currentMode;
+ SISPtr pSiS = SISPTR(pScrn);
+
+ switch (pSiS->Chipset) {
+ case PCI_CHIP_SIS300:
+ case PCI_CHIP_SIS630:
+ case PCI_CHIP_SIS540:
+ if(mode->Flags & V_INTERLACE)
+ return FALSE;
+ if(pCurs->bits->height > 32 || pCurs->bits->width > 32)
+ return FALSE;
+ if((mode->Flags & V_DBLSCAN) && (pCurs->bits->height > 16))
+ return FALSE;
+ break;
+ case PCI_CHIP_SIS550:
+ case PCI_CHIP_SIS650:
+ case PCI_CHIP_SIS315:
+ case PCI_CHIP_SIS315H:
+ case PCI_CHIP_SIS315PRO:
+ case PCI_CHIP_SIS330:
+ if(mode->Flags & V_INTERLACE)
+ return FALSE;
+ if(pCurs->bits->height > 64 || pCurs->bits->width > 64)
+ return FALSE;
+ if((mode->Flags & V_DBLSCAN) && (pCurs->bits->height > 32))
+ return FALSE;
+ break;
+ default:
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static void SiS300LoadCursorImageARGB(ScrnInfoPtr pScrn, CursorPtr pCurs)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int cursor_addr, i, j, maxheight = 32;
+ CARD32 *src = pCurs->bits->argb, *p;
+#ifdef SIS300_USE_ARGB16
+ CARD16 *dest, *pb;
+ CARD16 temp1;
+#define MYSISPTRTYPE CARD16
+#else
+ CARD32 *pb, *dest;
+#define MYSISPTRTYPE CARD32
+#endif
+ int srcwidth = pCurs->bits->width;
+ int srcheight = pCurs->bits->height;
+ BOOLEAN sizedouble = FALSE;
+ CARD32 temp, status1 = 0, status2 = 0;
+
+#ifdef SISDUALHEAD
+ SISEntPtr pSiSEnt = pSiS->entityPrivate;
+#endif
+
+ cursor_addr = pScrn->videoRam - pSiS->cursorOffset - ((pSiS->CursorSize/1024) * 2);
+
+ if(srcwidth > 32) srcwidth = 32;
+ if(srcheight > 32) srcheight = 32;
+
+#ifdef SISDUALHEAD
+ if (pSiS->DualHeadMode)
+ /* TW: Use the global (real) FbBase in DHM */
+ dest = (MYSISPTRTYPE *)((unsigned char *)pSiSEnt->FbBase + (cursor_addr * 1024));
+ else
+#endif
+ dest = (MYSISPTRTYPE *)((unsigned char *)pSiS->FbBase + (cursor_addr * 1024));
+
+ if(pSiS->CurrentLayout.mode->Flags & V_DBLSCAN) {
+ sizedouble = TRUE;
+ if(srcheight > 16) srcheight = 16;
+ maxheight = 16;
+ }
+
+#ifdef SIS300_USE_ARGB16 /* Use 16 Bit RGB pointer */
+ for(i = 0; i < srcheight; i++) {
+ p = src;
+ pb = dest;
+ src += pCurs->bits->width;
+ for(j = 0; j < srcwidth; j++) {
+ temp = *p++;
+ if(temp & 0xffffff) {
+ temp1 = ((temp & 0xff) >> 3) |
+ ((((temp & 0xff00) >> (8 + 3)) << 5) & 0x03e0) |
+ ((((temp & 0xff0000) >> (16 + 3)) << 10) & 0x7c00);
+ } else temp1 = 0x8000;
+ *dest++ = temp1;
+ }
+ if(srcwidth < 32) {
+ for(; j < 32; j++) {
+ *dest++ = 0x8000;
+ }
+ }
+ }
+ if(srcheight < maxheight) {
+ for(; i < maxheight; i++)
+ for(j = 0; j < 32; j++) {
+ *dest++ = 0x8000;
+ }
+ if(sizedouble) {
+ for(j = 0; j < 32; j++)
+ *dest++ = 0x0000;
+ }
+ }
+#else /* Use 32bit RGB pointer - preferred, saves us from the conversion */
+ for(i = 0; i < srcheight; i++) {
+ p = src;
+ pb = dest;
+ src += pCurs->bits->width;
+ for(j = 0; j < srcwidth; j++) {
+ temp = *p++;
+/* *dest1++ = ((temp ^ 0xff000000) << 4) | (((temp ^ 0xff000000) & 0xf0000000) >> 28); */
+ if(pSiS->OptUseColorCursorBlend) {
+ if(temp & 0xffffff) {
+ if((temp & 0xff000000) > pSiS->OptColorCursorBlendThreshold) {
+ temp &= 0x00ffffff;
+ } else {
+ temp = 0xff111111;
+ }
+ } else temp = 0xff000000;
+ } else {
+ if(temp & 0xffffff) temp &= 0x00ffffff;
+ else temp = 0xff000000;
+ }
+ *dest++ = temp;
+ }
+ if(srcwidth < 32) {
+ for(; j < 32; j++) {
+ *dest++ = 0xff000000;
+ }
+ }
+ if(sizedouble) {
+ for(j = 0; j < 32; j++) {
+ *dest++ = *pb++;
+ }
+ }
+
+ }
+ if(srcheight < maxheight) {
+ for(; i < maxheight; i++) {
+ for(j = 0; j < 32; j++) {
+ *dest++ = 0xff000000;
+ }
+ if(sizedouble) {
+ for(j = 0; j < 32; j++) {
+ *dest++ = 0xff000000;
+ }
+ }
+ }
+ }
+#endif
+
+ if(!pSiS->UseHWARGBCursor) {
+ if(pSiS->VBFlags & DISPTYPE_CRT1) {
+ status1 = sis300GetCursorStatus;
+ sis300DisableHWCursor()
+ if(pSiS->VBFlags & CRT2_ENABLE) {
+ status2 = sis301GetCursorStatus;
+ sis301DisableHWCursor()
+ }
+ SISWaitRetraceCRT1(pScrn);
+ sis300SwitchToRGBCursor();
+ if(pSiS->VBFlags & CRT2_ENABLE) {
+ SISWaitRetraceCRT2(pScrn);
+ sis301SwitchToRGBCursor();
+ }
+ }
+ }
+ sis300SetCursorAddress(cursor_addr);
+ sis300SetCursorPatternSelect(0);
+ if(status1) sis300SetCursorStatus(status1)
+
+ if(pSiS->VBFlags & CRT2_ENABLE) {
+ if((!pSiS->UseHWARGBCursor) && (!pSiS->VBFlags & DISPTYPE_CRT1)) {
+ status2 = sis301GetCursorStatus;
+ sis301DisableHWCursor()
+ SISWaitRetraceCRT2(pScrn);
+ sis301SwitchToRGBCursor();
+ }
+ sis301SetCursorAddress(cursor_addr)
+ sis301SetCursorPatternSelect(0)
+ if(status2) sis301SetCursorStatus(status2)
+ }
+
+ pSiS->UseHWARGBCursor = TRUE;
+}
+
+static void SiS310LoadCursorImageARGB(ScrnInfoPtr pScrn, CursorPtr pCurs)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int cursor_addr, i, j, maxheight = 64;
+ CARD32 *src = pCurs->bits->argb, *p, *pb, *dest;
+ int srcwidth = pCurs->bits->width;
+ int srcheight = pCurs->bits->height;
+ BOOLEAN sizedouble = FALSE;
+ CARD32 status1 = 0, status2 = 0;
+
+#ifdef SISDUALHEAD
+ SISEntPtr pSiSEnt = pSiS->entityPrivate;
+#endif
+
+ cursor_addr = pScrn->videoRam - pSiS->cursorOffset - ((pSiS->CursorSize/1024) * 2);
+
+ if(srcwidth > 64) srcwidth = 64;
+ if(srcheight > 64) srcheight = 64;
+
+#ifdef SISDUALHEAD
+ if(pSiS->DualHeadMode)
+ /* TW: Use the global (real) FbBase in DHM */
+ dest = (CARD32 *)((unsigned char *)pSiSEnt->FbBase + (cursor_addr * 1024));
+ else
+#endif
+ dest = (CARD32 *)((unsigned char *)pSiS->FbBase + (cursor_addr * 1024));
+
+ if(pSiS->CurrentLayout.mode->Flags & V_DBLSCAN) {
+ sizedouble = TRUE;
+ if(srcheight > 32) srcheight = 32;
+ maxheight = 32;
+ }
+
+ for(i = 0; i < srcheight; i++) {
+ p = src;
+ pb = dest;
+ src += pCurs->bits->width;
+ for(j = 0; j < srcwidth; j++) *dest++ = *p++;
+ if(srcwidth < 64) {
+ for(; j < 64; j++) *dest++ = 0;
+ }
+ if(sizedouble) {
+ for(j = 0; j < 64; j++) {
+ *dest++ = *pb++;
+ }
+ }
+ }
+ if(srcheight < maxheight) {
+ for(; i < maxheight; i++)
+ for(j = 0; j < 64; j++) *dest++ = 0;
+ if(sizedouble) {
+ for(j = 0; j < 64; j++) *dest++ = 0;
+ }
+ }
+
+ if(!pSiS->UseHWARGBCursor) {
+ if(pSiS->VBFlags & DISPTYPE_CRT1) {
+ status1 = sis310GetCursorStatus;
+ sis310DisableHWCursor()
+ if(pSiS->VBFlags & CRT2_ENABLE) {
+ status2 = sis301GetCursorStatus310;
+ sis301DisableHWCursor310()
+ }
+ SISWaitRetraceCRT1(pScrn);
+ sis310SwitchToRGBCursor();
+ if(pSiS->VBFlags & CRT2_ENABLE) {
+ SISWaitRetraceCRT2(pScrn);
+ sis301SwitchToRGBCursor310();
+ }
+ }
+ }
+ sis310SetCursorAddress(cursor_addr);
+ sis310SetCursorPatternSelect(0);
+ if(status1) sis310SetCursorStatus(status1)
+
+ if(pSiS->VBFlags & CRT2_ENABLE) {
+ if((!pSiS->UseHWARGBCursor) && (!pSiS->VBFlags & DISPTYPE_CRT1)) {
+ status2 = sis301GetCursorStatus310;
+ sis301DisableHWCursor310()
+ SISWaitRetraceCRT2(pScrn);
+ sis301SwitchToRGBCursor310();
+ }
+ sis301SetCursorAddress310(cursor_addr)
+ sis301SetCursorPatternSelect310(0)
+ if(status2) sis301SetCursorStatus310(status2)
+ }
+
+ pSiS->UseHWARGBCursor = TRUE;
+}
+#endif
+#endif
+#endif
+
+Bool
+SiSHWCursorInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ SISPtr pSiS = SISPTR(pScrn);
+ xf86CursorInfoPtr infoPtr;
+
+ PDEBUG(ErrorF("HW Cursor Init\n"));
+ infoPtr = xf86CreateCursorInfoRec();
+ if(!infoPtr)
+ return FALSE;
+
+ pSiS->CursorInfoPtr = infoPtr;
+ pSiS->UseHWARGBCursor = FALSE;
+
+ switch (pSiS->Chipset) {
+ case PCI_CHIP_SIS300:
+ case PCI_CHIP_SIS630:
+ case PCI_CHIP_SIS540:
+ infoPtr->MaxWidth = 64;
+ infoPtr->MaxHeight = 64;
+ infoPtr->ShowCursor = SiS300ShowCursor;
+ infoPtr->HideCursor = SiS300HideCursor;
+ infoPtr->SetCursorPosition = SiS300SetCursorPosition;
+ infoPtr->SetCursorColors = SiS300SetCursorColors;
+ infoPtr->LoadCursorImage = SiS300LoadCursorImage;
+ infoPtr->UseHWCursor = SiS300UseHWCursor;
+#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,99,0,0)
+#ifdef ARGB_CURSOR
+#ifdef SIS_ARGB_CURSOR
+ if(pSiS->OptUseColorCursor) {
+ infoPtr->UseHWCursorARGB = SiSUseHWCursorARGB;
+ infoPtr->LoadCursorARGB = SiS300LoadCursorImageARGB;
+ }
+#endif
+#endif
+#endif
+ infoPtr->Flags =
+ HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
+ HARDWARE_CURSOR_INVERT_MASK |
+ HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
+ HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
+ HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK |
+ HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64;
+ break;
+ case PCI_CHIP_SIS550:
+ case PCI_CHIP_SIS650:
+ case PCI_CHIP_SIS315:
+ case PCI_CHIP_SIS315H:
+ case PCI_CHIP_SIS315PRO:
+ case PCI_CHIP_SIS330:
+ infoPtr->MaxWidth = 64;
+ infoPtr->MaxHeight = 64;
+ infoPtr->ShowCursor = SiS310ShowCursor;
+ infoPtr->HideCursor = SiS310HideCursor;
+ infoPtr->SetCursorPosition = SiS310SetCursorPosition;
+ infoPtr->SetCursorColors = SiS310SetCursorColors;
+ infoPtr->LoadCursorImage = SiS310LoadCursorImage;
+ infoPtr->UseHWCursor = SiS300UseHWCursor;
+#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,99,0,0)
+#ifdef ARGB_CURSOR
+#ifdef SIS_ARGB_CURSOR
+ if(pSiS->OptUseColorCursor) {
+ infoPtr->UseHWCursorARGB = SiSUseHWCursorARGB;
+ infoPtr->LoadCursorARGB = SiS310LoadCursorImageARGB;
+ }
+#endif
+#endif
+#endif
+ infoPtr->Flags =
+ HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
+ HARDWARE_CURSOR_INVERT_MASK |
+ HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
+ HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
+ HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK |
+ HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64;
+ break;
+ default:
+ infoPtr->MaxWidth = 64;
+ infoPtr->MaxHeight = 64;
+ infoPtr->SetCursorPosition = SiSSetCursorPosition;
+ infoPtr->ShowCursor = SiSShowCursor;
+ infoPtr->HideCursor = SiSHideCursor;
+ infoPtr->SetCursorColors = SiSSetCursorColors;
+ infoPtr->LoadCursorImage = SiSLoadCursorImage;
+ infoPtr->UseHWCursor = SiSUseHWCursor;
+ infoPtr->Flags =
+ HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
+ HARDWARE_CURSOR_INVERT_MASK |
+ HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
+ HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
+ HARDWARE_CURSOR_NIBBLE_SWAPPED |
+ HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1;
+ break;
+ }
+
+ return(xf86InitCursor(pScreen, infoPtr));
+}
diff --git a/src/sis_cursor.h b/src/sis_cursor.h
new file mode 100644
index 0000000..76258ac
--- /dev/null
+++ b/src/sis_cursor.h
@@ -0,0 +1,427 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_cursor.h,v 1.5 2003/02/06 13:14:04 eich Exp $ */
+/*
+ * Copyright 1998,1999 by Alan Hourihane, Wigan, England.
+ * Parts Copyright 2001, 2002 by Thomas Winischhofer, Vienna, Austria.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the copyright holders not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, alanh@fairlite.demon.co.uk
+ * Mike Chapman <mike@paranoia.com>,
+ * Juanjo Santamarta <santamarta@ctv.es>,
+ * Mitani Hiroshi <hmitani@drl.mei.co.jp>
+ * David Thomas <davtom@dream.org.uk>.
+ * Thomas Winischhofer <thomas@winischhofer.net>:
+ */
+
+#define CS(x) (0x8500+(x<<2))
+
+/* 300 series, CRT1 */
+
+/* 80000000 = RGB(1) - MONO(0)
+ * 40000000 = enable(1) - disable(0)
+ * 20000000 = 32(1) / 16(1) bit RGB
+ * 10000000 = "ghost"(1) - [other effect](0)
+ */
+
+#define sis300GetCursorStatus \
+ MMIO_IN32(pSiS->IOBase, CS(0)) & 0x40000000;
+
+#define sis300SetCursorStatus(status) \
+ { \
+ unsigned long temp; \
+ temp = MMIO_IN32(pSiS->IOBase, CS(0)); \
+ temp &= 0xbfffffff; \
+ temp |= status; \
+ MMIO_OUT32(pSiS->IOBase, CS(0), temp); \
+ }
+
+#define sis300EnableHWCursor() \
+ { \
+ unsigned long temp; \
+ temp = MMIO_IN32(pSiS->IOBase, CS(0)); \
+ temp &= 0x0fffffff; \
+ temp |= 0x40000000; \
+ MMIO_OUT32(pSiS->IOBase, CS(0), temp); \
+ }
+
+#define sis300EnableHWARGBCursor() \
+ { \
+ unsigned long temp; \
+ temp = MMIO_IN32(pSiS->IOBase, CS(0)); \
+ temp |= 0xF0000000; \
+ MMIO_OUT32(pSiS->IOBase, CS(0), temp); \
+ }
+
+#define sis300EnableHWARGB16Cursor() \
+ { \
+ unsigned long temp; \
+ temp = MMIO_IN32(pSiS->IOBase, CS(0)); \
+ temp &= 0x0fffffff; \
+ temp |= 0xD0000000; \
+ MMIO_OUT32(pSiS->IOBase, CS(0), temp); \
+ }
+
+#define sis300SwitchToMONOCursor() \
+ { \
+ unsigned long temp; \
+ temp = MMIO_IN32(pSiS->IOBase, CS(0)); \
+ temp &= 0x4fffffff; \
+ MMIO_OUT32(pSiS->IOBase, CS(0), temp); \
+ }
+
+#define sis300SwitchToRGBCursor() \
+ { \
+ unsigned long temp; \
+ temp = MMIO_IN32(pSiS->IOBase, CS(0)); \
+ temp |= 0xB0000000; \
+ MMIO_OUT32(pSiS->IOBase, CS(0), temp); \
+ }
+
+#define sis300DisableHWCursor()\
+ { \
+ unsigned long temp; \
+ temp = MMIO_IN32(pSiS->IOBase, CS(0)); \
+ temp &= 0xbFFFFFFF; \
+ MMIO_OUT32(pSiS->IOBase, CS(0), temp); \
+ }
+
+#define sis300SetCursorBGColor(color)\
+ MMIO_OUT32(pSiS->IOBase, CS(1), (color));
+#define sis300SetCursorFGColor(color)\
+ MMIO_OUT32(pSiS->IOBase, CS(2), (color));
+
+#define sis300SetCursorPositionX(x,preset)\
+ MMIO_OUT32(pSiS->IOBase, CS(3), ((x) | ((preset) << 16)));
+#define sis300SetCursorPositionY(y,preset)\
+ MMIO_OUT32(pSiS->IOBase, CS(4), ((y) | ((preset) << 16)));
+
+#define sis300SetCursorAddress(address)\
+ { \
+ unsigned long temp; \
+ temp = MMIO_IN32(pSiS->IOBase, CS(0)); \
+ temp &= 0xFFFF0000; \
+ temp |= address; \
+ MMIO_OUT32(pSiS->IOBase,CS(0),temp); \
+ }
+
+#define sis300SetCursorPatternSelect(pat_id)\
+ { \
+ unsigned long temp; \
+ temp = MMIO_IN32(pSiS->IOBase, CS(0)); \
+ temp &= 0xF0FFFFFF; \
+ temp |= (pat_id) << 24; \
+ MMIO_OUT32(pSiS->IOBase,CS(0),temp); \
+ }
+
+/* 300 series, CRT2 */
+
+/* 80000000 = RGB(1) - MONO(0)
+ * 40000000 = enable(1) - disable(0)
+ * 20000000 = 32(1) / 16(1) bit RGB
+ * 10000000 = unused (always "ghosting")
+ */
+
+#define sis301GetCursorStatus \
+ MMIO_IN32(pSiS->IOBase, CS(8)) & 0x40000000;
+
+#define sis301SetCursorStatus(status) \
+ { \
+ unsigned long temp; \
+ temp = MMIO_IN32(pSiS->IOBase, CS(8)); \
+ temp &= 0xbfffffff; \
+ temp |= status; \
+ MMIO_OUT32(pSiS->IOBase, CS(8), temp); \
+ }
+
+#define sis301EnableHWCursor()\
+ { \
+ unsigned long temp; \
+ temp = MMIO_IN32(pSiS->IOBase, CS(8)); \
+ temp &= 0x0fffffff; \
+ temp |= 0x40000000; \
+ MMIO_OUT32(pSiS->IOBase, CS(8), temp); \
+ }
+
+#define sis301EnableHWARGBCursor()\
+ { \
+ unsigned long temp; \
+ temp = MMIO_IN32(pSiS->IOBase, CS(8)); \
+ temp |= 0xF0000000; \
+ MMIO_OUT32(pSiS->IOBase, CS(8), temp); \
+ }
+
+#define sis301EnableHWARGB16Cursor()\
+ { \
+ unsigned long temp; \
+ temp = MMIO_IN32(pSiS->IOBase, CS(8)); \
+ temp &= 0x0FFFFFFF; \
+ temp |= 0xD0000000; \
+ MMIO_OUT32(pSiS->IOBase, CS(8), temp); \
+ }
+
+#define sis301SwitchToRGBCursor() \
+ { \
+ unsigned long temp; \
+ temp = MMIO_IN32(pSiS->IOBase, CS(8)); \
+ temp |= 0xB0000000; \
+ MMIO_OUT32(pSiS->IOBase, CS(8), temp); \
+ }
+
+#define sis301SwitchToMONOCursor() \
+ { \
+ unsigned long temp; \
+ temp = MMIO_IN32(pSiS->IOBase, CS(8)); \
+ temp &= 0x4fffffff; \
+ MMIO_OUT32(pSiS->IOBase, CS(8), temp); \
+ }
+
+#define sis301DisableHWCursor()\
+ { \
+ unsigned long temp; \
+ temp = MMIO_IN32(pSiS->IOBase, CS(8)); \
+ temp &= 0xbFFFFFFF; \
+ MMIO_OUT32(pSiS->IOBase, CS(8), temp); \
+ }
+
+#define sis301SetCursorBGColor(color)\
+ MMIO_OUT32(pSiS->IOBase, CS(9), (color));
+#define sis301SetCursorFGColor(color)\
+ MMIO_OUT32(pSiS->IOBase, CS(10), (color));
+
+#define sis301SetCursorPositionX(x,preset)\
+ MMIO_OUT32(pSiS->IOBase, CS(11), ((x) | ((preset) << 16)));
+#define sis301SetCursorPositionY(y,preset)\
+ MMIO_OUT32(pSiS->IOBase, CS(12), ((y) | ((preset) << 16)));
+
+#define sis301SetCursorAddress(address)\
+ { \
+ unsigned long temp; \
+ temp = MMIO_IN32(pSiS->IOBase, CS(8)); \
+ temp &= 0xFFFF0000; \
+ temp |= address; \
+ MMIO_OUT32(pSiS->IOBase,CS(8),temp); \
+ }
+
+#define sis301SetCursorPatternSelect(pat_id)\
+ { \
+ unsigned long temp; \
+ temp = MMIO_IN32(pSiS->IOBase, CS(8)); \
+ temp &= 0xF0FFFFFF; \
+ temp |= (pat_id) << 24; \
+ MMIO_OUT32(pSiS->IOBase,CS(8),temp); \
+ }
+
+/* 310/325/330 series CRT1 */
+
+/* 80000000 = RGB(1) - MONO(0)
+ * 40000000 = enable(1) - disable(0)
+ * 20000000 = 32(1) / 16(1) bit RGB
+ * 10000000 = "ghost"(1) - Alpha Blend(0)
+ */
+
+#define sis310GetCursorStatus \
+ MMIO_IN32(pSiS->IOBase, CS(0)) & 0x40000000;
+
+#define sis310SetCursorStatus(status) \
+ { \
+ unsigned long temp; \
+ temp = MMIO_IN32(pSiS->IOBase, CS(0)); \
+ temp &= 0xbfffffff; \
+ temp |= status; \
+ MMIO_OUT32(pSiS->IOBase, CS(0), temp); \
+ }
+
+#define sis310EnableHWCursor()\
+ { \
+ unsigned long temp; \
+ temp = MMIO_IN32(pSiS->IOBase, CS(0)); \
+ temp &= 0x0fffffff; \
+ temp |= 0x40000000; \
+ MMIO_OUT32(pSiS->IOBase, CS(0), temp); \
+ }
+
+#define sis310EnableHWARGBCursor()\
+ { \
+ unsigned long temp; \
+ temp = MMIO_IN32(pSiS->IOBase, CS(0)); \
+ temp &= 0x0FFFFFFF; \
+ temp |= 0xE0000000; \
+ MMIO_OUT32(pSiS->IOBase, CS(0), temp); \
+ }
+
+#define sis310SwitchToMONOCursor() \
+ { \
+ unsigned long temp; \
+ temp = MMIO_IN32(pSiS->IOBase, CS(0)); \
+ temp &= 0x4fffffff; \
+ MMIO_OUT32(pSiS->IOBase, CS(0), temp); \
+ }
+
+#define sis310SwitchToRGBCursor() \
+ { \
+ unsigned long temp; \
+ temp = MMIO_IN32(pSiS->IOBase, CS(0)); \
+ temp &= 0xBFFFFFFF; \
+ temp |= 0xA0000000; \
+ MMIO_OUT32(pSiS->IOBase, CS(0), temp); \
+ }
+
+#define sis310DisableHWCursor()\
+ { \
+ unsigned long temp; \
+ temp = MMIO_IN32(pSiS->IOBase, CS(0)); \
+ temp &= 0xBFFFFFFF; \
+ MMIO_OUT32(pSiS->IOBase, CS(0), temp); \
+ }
+
+#define sis310SetCursorBGColor(color)\
+ MMIO_OUT32(pSiS->IOBase, CS(1), (color));
+#define sis310SetCursorFGColor(color)\
+ MMIO_OUT32(pSiS->IOBase, CS(2), (color));
+
+#define sis310SetCursorPositionX(x,preset)\
+ MMIO_OUT32(pSiS->IOBase, CS(3), ((x) | ((preset) << 16)));
+#define sis310SetCursorPositionY(y,preset)\
+ MMIO_OUT32(pSiS->IOBase, CS(4), ((y) | ((preset) << 16)));
+
+#define sis310SetCursorAddress(address)\
+ { \
+ unsigned long temp; \
+ temp = MMIO_IN32(pSiS->IOBase, CS(0)); \
+ temp &= 0xFFF00000; \
+ temp |= address; \
+ MMIO_OUT32(pSiS->IOBase,CS(0),temp); \
+ }
+
+#define sis310SetCursorPatternSelect(pat_id)\
+ { \
+ unsigned long temp; \
+ temp = MMIO_IN32(pSiS->IOBase, CS(0)); \
+ temp &= 0xF0FFFFFF; \
+ temp |= (pat_id) << 24; \
+ MMIO_OUT32(pSiS->IOBase,CS(0),temp); \
+ }
+
+/* 310/325/330 series CRT2 */
+
+/* 80000000 = RGB(1) - MONO(0)
+ * 40000000 = enable(1) - disable(0)
+ * 20000000 = 32(1) / 16(1) bit RGB
+ * 10000000 = "ghost"(1) - Alpha Blend(0) ?
+ */
+
+#define sis301GetCursorStatus310 \
+ MMIO_IN32(pSiS->IOBase, CS(8)) & 0x40000000;
+
+#define sis301SetCursorStatus310(status) \
+ { \
+ unsigned long temp; \
+ temp = MMIO_IN32(pSiS->IOBase, CS(8)); \
+ temp &= 0xbfffffff; \
+ temp |= status; \
+ MMIO_OUT32(pSiS->IOBase, CS(8), temp); \
+ }
+
+#define sis301EnableHWCursor310()\
+ { \
+ unsigned long temp, temp1, temp2; \
+ temp1 = MMIO_IN32(pSiS->IOBase, CS(11)); \
+ temp2 = MMIO_IN32(pSiS->IOBase, CS(12)); \
+ temp = MMIO_IN32(pSiS->IOBase, CS(8)); \
+ temp &= 0x0fffffff; \
+ temp |= 0x40000000; \
+ MMIO_OUT32(pSiS->IOBase, CS(8), temp); \
+ MMIO_OUT32(pSiS->IOBase, CS(11), temp1); \
+ MMIO_OUT32(pSiS->IOBase, CS(12), temp2); \
+ }
+
+#define sis301EnableHWARGBCursor310()\
+ { \
+ unsigned long temp, temp1, temp2; \
+ temp1 = MMIO_IN32(pSiS->IOBase, CS(11)); \
+ temp2 = MMIO_IN32(pSiS->IOBase, CS(12)); \
+ temp = MMIO_IN32(pSiS->IOBase, CS(8)); \
+ temp &= 0x0FFFFFFF; \
+ temp |= 0xE0000000; \
+ MMIO_OUT32(pSiS->IOBase, CS(8), temp); \
+ MMIO_OUT32(pSiS->IOBase, CS(11), temp1); \
+ MMIO_OUT32(pSiS->IOBase, CS(12), temp2); \
+ }
+
+#define sis301SwitchToRGBCursor310() \
+ { \
+ unsigned long temp; \
+ temp = MMIO_IN32(pSiS->IOBase, CS(8)); \
+ temp &= 0xBFFFFFFF; \
+ temp |= 0xA0000000; \
+ MMIO_OUT32(pSiS->IOBase, CS(8), temp); \
+ }
+
+#define sis301SwitchToMONOCursor310() \
+ { \
+ unsigned long temp; \
+ temp = MMIO_IN32(pSiS->IOBase, CS(8)); \
+ temp &= 0x4fffffff; \
+ MMIO_OUT32(pSiS->IOBase, CS(8), temp); \
+ }
+
+#define sis301DisableHWCursor310()\
+ { \
+ unsigned long temp; \
+ temp = MMIO_IN32(pSiS->IOBase, CS(8)); \
+ temp &= 0xBFFFFFFF; \
+ MMIO_OUT32(pSiS->IOBase, CS(8), temp); \
+ }
+
+#define sis301SetCursorBGColor310(color)\
+ MMIO_OUT32(pSiS->IOBase, CS(9), (color));
+#define sis301SetCursorFGColor310(color)\
+ MMIO_OUT32(pSiS->IOBase, CS(10), (color));
+
+#define sis301SetCursorPositionX310(x,preset)\
+ MMIO_OUT32(pSiS->IOBase, CS(11), ((x) | ((preset) << 16)));
+#define sis301SetCursorPositionY310(y,preset)\
+ MMIO_OUT32(pSiS->IOBase, CS(12), ((y) | ((preset) << 16)));
+
+#define sis301SetCursorAddress310(address)\
+ { \
+ unsigned long temp; \
+ if(pSiS->sishw_ext.jChipType == SIS_315H) { \
+ if(address & 0x10000) { \
+ address &= ~0x10000; \
+ orSISIDXREG(SISSR, 0x37, 0x80); \
+ } else { \
+ andSISIDXREG(SISSR, 0x37, 0x7f); \
+ } \
+ } \
+ temp = MMIO_IN32(pSiS->IOBase, CS(8)); \
+ temp &= 0xFFF00000; \
+ temp |= address; \
+ MMIO_OUT32(pSiS->IOBase,CS(8),temp); \
+ }
+
+#define sis301SetCursorPatternSelect310(pat_id)\
+ { \
+ unsigned long temp; \
+ temp = MMIO_IN32(pSiS->IOBase, CS(8)); \
+ temp &= 0xF0FFFFFF; \
+ temp |= (pat_id) << 24; \
+ MMIO_OUT32(pSiS->IOBase,CS(8),temp); \
+ }
+
diff --git a/src/sis_dac.c b/src/sis_dac.c
new file mode 100644
index 0000000..0ce8e74
--- /dev/null
+++ b/src/sis_dac.c
@@ -0,0 +1,2148 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dac.c,v 1.30 2003/02/05 17:53:22 eich Exp $ */
+/*
+ * Copyright 1998,1999 by Alan Hourihane, Wigan, England.
+ * Parts Copyright 2001, 2002 by Thomas Winischhofer, Vienna, Austria.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the provider not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The provider makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE PROVIDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE PROVIDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane <alanh@fairlite.demon.co.uk>
+ * Mike Chapman <mike@paranoia.com>,
+ * Juanjo Santamarta <santamarta@ctv.es>,
+ * Mitani Hiroshi <hmitani@drl.mei.co.jp>
+ * David Thomas <davtom@dream.org.uk>.
+ * Thomas Winischhofer <thomas@winischhofer.net>
+ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "xf86Version.h"
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+#include "xf86DDC.h"
+
+#include "sis.h"
+#include "sis_dac.h"
+#include "sis_regs.h"
+#include "sis_vb.h"
+
+static void SiSSave(ScrnInfoPtr pScrn, SISRegPtr sisReg);
+static void SiSRestore(ScrnInfoPtr pScrn, SISRegPtr sisReg);
+
+static void SiS300Save(ScrnInfoPtr pScrn, SISRegPtr sisReg);
+static void SiS310Save(ScrnInfoPtr pScrn, SISRegPtr sisReg);
+static void SiS301Save(ScrnInfoPtr pScrn, SISRegPtr sisReg);
+static void SiS301BSave(ScrnInfoPtr pScrn, SISRegPtr sisReg);
+static void SiSLVDSChrontelSave(ScrnInfoPtr pScrn, SISRegPtr sisReg);
+static void SiS300Restore(ScrnInfoPtr pScrn, SISRegPtr sisReg);
+static void SiS310Restore(ScrnInfoPtr pScrn, SISRegPtr sisReg);
+static void SiS301Restore(ScrnInfoPtr pScrn, SISRegPtr sisReg);
+static void SiS301BRestore(ScrnInfoPtr pScrn, SISRegPtr sisReg);
+static void SiSLVDSChrontelRestore(ScrnInfoPtr pScrn, SISRegPtr sisReg);
+static void SiS301LoadPalette(ScrnInfoPtr pScrn, int numColors,
+ int *indicies, LOCO *colors, VisualPtr pVisual);
+static void SiSThreshold(ScrnInfoPtr pScrn, DisplayModePtr mode,
+ unsigned short *Low, unsigned short *High);
+static void SetBlock(CARD16 port, CARD8 from, CARD8 to, CARD8 *DataPtr);
+#if 0
+Bool SiSI2CInit(ScrnInfoPtr pScrn);
+#endif
+
+static const unsigned short ch700xidx[] = {
+ 0x00,0x07,0x08,0x0a,0x0b,0x04,0x09,0x20,0x21,0x18,0x19,0x1a,
+ 0x1b,0x1c,0x1d,0x1e,0x1f, /* 0x0e, - TW: Don't save the power register */
+ 0x01,0x03,0x06,0x0d,0x11,0x13,0x14,0x15,0x17,0x22,0x23,0x24
+ };
+
+static const unsigned short ch701xidx[] = {
+ 0x1c,0x5f,0x64,0x6f,0x70,0x71,0x72,0x73,0x74,0x76,0x78,0x7d,
+ 0x67,0x68,0x69,0x6a,0x6b,0x1e,0x00,0x01,0x02,0x04,0x03,0x05,
+ 0x06,0x07,0x08,0x15,0x1f,0x0c,0x0d,0x0e,0x0f,0x10
+ };
+
+int SiS_compute_vclk(
+ int Clock,
+ int *out_n,
+ int *out_dn,
+ int *out_div,
+ int *out_sbit,
+ int *out_scale)
+{
+ float f,x,y,t, error, min_error;
+ int n, dn, best_n=0, best_dn=0;
+
+ /*
+ * Rules
+ *
+ * VCLK = 14.318 * (Divider/Post Scalar) * (Numerator/DeNumerator)
+ * Factor = (Divider/Post Scalar)
+ * Divider is 1 or 2
+ * Post Scalar is 1, 2, 3, 4, 6 or 8
+ * Numberator ranged from 1 to 128
+ * DeNumerator ranged from 1 to 32
+ * a. VCO = VCLK/Factor, suggest range is 150 to 250 Mhz
+ * b. Post Scalar selected from 1, 2, 4 or 8 first.
+ * c. DeNumerator selected from 2.
+ *
+ * According to rule a and b, the VCO ranges that can be scaled by
+ * rule b are:
+ * 150 - 250 (Factor = 1)
+ * 75 - 125 (Factor = 2)
+ * 37.5 - 62.5 (Factor = 4)
+ * 18.75 - 31.25 (Factor = 8)
+ *
+ * The following ranges use Post Scalar 3 or 6:
+ * 125 - 150 (Factor = 1.5)
+ * 62.5 - 75 (Factor = 3)
+ * 31.25 - 37.5 (Factor = 6)
+ *
+ * Steps:
+ * 1. divide the Clock by 2 until the Clock is less or equal to 31.25.
+ * 2. if the divided Clock is range from 18.25 to 31.25, than
+ * the Factor is 1, 2, 4 or 8.
+ * 3. if the divided Clock is range from 15.625 to 18.25, than
+ * the Factor is 1.5, 3 or 6.
+ * 4. select the Numberator and DeNumberator with minimum deviation.
+ *
+ * ** this function can select VCLK ranged from 18.75 to 250 Mhz
+ */
+ f = (float) Clock;
+ f /= 1000.0;
+ if ((f > 250.0) || (f < 18.75))
+ return 0;
+
+ min_error = f;
+ y = 1.0;
+ x = f;
+ while (x > 31.25) {
+ y *= 2.0;
+ x /= 2.0;
+ }
+ if (x >= 18.25) {
+ x *= 8.0;
+ y = 8.0 / y;
+ } else if (x >= 15.625) {
+ x *= 12.0;
+ y = 12.0 / y;
+ }
+
+ t = y;
+ if (t == (float) 1.5) {
+ *out_div = 2;
+ t *= 2.0;
+ } else {
+ *out_div = 1;
+ }
+ if (t > (float) 4.0) {
+ *out_sbit = 1;
+ t /= 2.0;
+ } else {
+ *out_sbit = 0;
+ }
+
+ *out_scale = (int) t;
+
+ for (dn=2;dn<=32;dn++) {
+ for (n=1;n<=128;n++) {
+ error = x;
+ error -= ((float) 14.318 * (float) n / (float) dn);
+ if (error < (float) 0)
+ error = -error;
+ if (error < min_error) {
+ min_error = error;
+ best_n = n;
+ best_dn = dn;
+ }
+ }
+ }
+ *out_n = best_n;
+ *out_dn = best_dn;
+ PDEBUG(ErrorF("SiS_compute_vclk: Clock=%d, n=%d, dn=%d, div=%d, sbit=%d,"
+ " scale=%d\n", Clock, best_n, best_dn, *out_div,
+ *out_sbit, *out_scale));
+ return 1;
+}
+
+
+void
+SiSCalcClock(ScrnInfoPtr pScrn, int clock, int max_VLD, unsigned int *vclk)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int M, N, P , PSN, VLD , PSNx ;
+ int bestM=0, bestN=0, bestP=0, bestPSN=0, bestVLD=0;
+ double bestError, abest = 42.0, bestFout;
+ double target;
+ double Fvco, Fout;
+ double error, aerror;
+
+ /*
+ * fd = fref*(Numerator/Denumerator)*(Divider/PostScaler)
+ *
+ * M = Numerator [1:128]
+ * N = DeNumerator [1:32]
+ * VLD = Divider (Vco Loop Divider) : divide by 1, 2
+ * P = Post Scaler : divide by 1, 2, 3, 4
+ * PSN = Pre Scaler (Reference Divisor Select)
+ *
+ * result in vclk[]
+ */
+#define Midx 0
+#define Nidx 1
+#define VLDidx 2
+#define Pidx 3
+#define PSNidx 4
+#define Fref 14318180
+/* stability constraints for internal VCO -- MAX_VCO also determines
+ * the maximum Video pixel clock */
+#define MIN_VCO Fref
+#define MAX_VCO 135000000
+#define MAX_VCO_5597 353000000
+#define MAX_PSN 0 /* no pre scaler for this chip */
+#define TOLERANCE 0.01 /* search smallest M and N in this tolerance */
+
+ int M_min = 2;
+ int M_max = 128;
+
+/* abest=10000.0; */
+
+ target = clock * 1000;
+
+ if (pSiS->Chipset == PCI_CHIP_SIS5597 || pSiS->Chipset == PCI_CHIP_SIS6326){
+ int low_N = 2;
+ int high_N = 5;
+
+ PSN = 1;
+ P = 1;
+ if (target < MAX_VCO_5597 / 2)
+ P = 2;
+ if (target < MAX_VCO_5597 / 3)
+ P = 3;
+ if (target < MAX_VCO_5597 / 4)
+ P = 4;
+ if (target < MAX_VCO_5597 / 6)
+ P = 6;
+ if (target < MAX_VCO_5597 / 8)
+ P = 8;
+
+ Fvco = P * target;
+
+ for (N = low_N; N <= high_N; N++){
+ double M_desired = Fvco / Fref * N;
+ if (M_desired > M_max * max_VLD)
+ continue;
+
+ if ( M_desired > M_max ) {
+ M = M_desired / 2 + 0.5;
+ VLD = 2;
+ } else {
+ M = Fvco / Fref * N + 0.5;
+ VLD = 1;
+ }
+
+ Fout = (double)Fref * (M * VLD)/(N * P);
+
+ error = (target - Fout) / target;
+ aerror = (error < 0) ? -error : error;
+/* if (aerror < abest && abest > TOLERANCE) */
+ if (aerror < abest) {
+ abest = aerror;
+ bestError = error;
+ bestM = M;
+ bestN = N;
+ bestP = P;
+ bestPSN = PSN;
+ bestVLD = VLD;
+ bestFout = Fout;
+ }
+ }
+ }
+ else {
+ for (PSNx = 0; PSNx <= MAX_PSN ; PSNx++) {
+ int low_N, high_N;
+ double FrefVLDPSN;
+
+ PSN = !PSNx ? 1 : 4;
+
+ low_N = 2;
+ high_N = 32;
+
+ for ( VLD = 1 ; VLD <= max_VLD ; VLD++ ) {
+
+ FrefVLDPSN = (double)Fref * VLD / PSN;
+ for (N = low_N; N <= high_N; N++) {
+ double tmp = FrefVLDPSN / N;
+
+ for (P = 1; P <= 4; P++) {
+ double Fvco_desired = target * ( P );
+ double M_desired = Fvco_desired / tmp;
+
+ /* Which way will M_desired be rounded?
+ * Do all three just to be safe.
+ */
+ int M_low = M_desired - 1;
+ int M_hi = M_desired + 1;
+
+ if (M_hi < M_min || M_low > M_max)
+ continue;
+
+ if (M_low < M_min)
+ M_low = M_min;
+ if (M_hi > M_max)
+ M_hi = M_max;
+
+ for (M = M_low; M <= M_hi; M++) {
+ Fvco = tmp * M;
+ if (Fvco <= MIN_VCO)
+ continue;
+ if (Fvco > MAX_VCO)
+ break;
+
+ Fout = Fvco / ( P );
+
+ error = (target - Fout) / target;
+ aerror = (error < 0) ? -error : error;
+ if (aerror < abest) {
+ abest = aerror;
+ bestError = error;
+ bestM = M;
+ bestN = N;
+ bestP = P;
+ bestPSN = PSN;
+ bestVLD = VLD;
+ bestFout = Fout;
+ }
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO,3,
+ "Freq. selected: %.2f MHz, M=%d, N=%d, VLD=%d, P=%d, PSN=%d\n",
+ (float)(clock / 1000.), M, N, P, VLD, PSN);
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO,3,
+ "Freq. set: %.2f MHz\n", Fout / 1.0e6);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ vclk[Midx] = bestM;
+ vclk[Nidx] = bestN;
+ vclk[VLDidx] = bestVLD;
+ vclk[Pidx] = bestP;
+ vclk[PSNidx] = bestPSN;
+
+ PDEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+ "Freq. selected: %.2f MHz, M=%d, N=%d, VLD=%d, P=%d, PSN=%d\n",
+ (float)(clock / 1000.), vclk[Midx], vclk[Nidx], vclk[VLDidx],
+ vclk[Pidx], vclk[PSNidx]));
+ PDEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+ "Freq. set: %.2f MHz\n", bestFout / 1.0e6));
+ PDEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+ "VCO Freq.: %.2f MHz\n", bestFout*bestP / 1.0e6));
+}
+
+
+static void
+SiSSave(ScrnInfoPtr pScrn, SISRegPtr sisReg)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int i,max;
+
+ PDEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+ "SiSSave(ScrnInfoPtr pScrn, SISRegPtr sisReg)\n"));
+
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+
+ switch (pSiS->Chipset) {
+ case PCI_CHIP_SIS5597:
+ max=0x3C;
+ break;
+ case PCI_CHIP_SIS6326:
+ case PCI_CHIP_SIS530:
+ max=0x3F;
+ break;
+ default:
+ max=0x37;
+ break;
+ }
+
+ /* Save extended SR registers */
+ for (i = 0x06; i <= max; i++) {
+ inSISIDXREG(SISSR, i, sisReg->sisRegs3C4[i]);
+#ifdef DEBUG
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4,
+ "XR%02X Contents - %02X \n", i, sisReg->sisRegs3C4[i]);
+#endif
+#ifdef TWDEBUG
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "SR%02X - %02X \n", i,sisReg->sisRegs3C4[i]);
+#endif
+ }
+
+#ifdef TWDEBUG
+ for (i = 0x00; i <= 0x3f; i++) {
+ inSISIDXREG(SISCR, i, max);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "CR%02X - %02X \n", i,max);
+ }
+#endif
+
+ /* Save lock (will not be restored in SiSRestore()!) */
+ inSISIDXREG(SISCR, 0x80, sisReg->sisRegs3D4[0x80]);
+
+ sisReg->sisRegs3C2 = inSISREG(SISMISCR); /* Misc */
+
+ /* TW: Save TV registers */
+ if((pSiS->Chipset == PCI_CHIP_SIS6326) && (pSiS->SiS6326Flags & SIS6326_HASTV)) {
+ outSISIDXREG(SISCR, 0x80, 0x86);
+ for(i = 0x00; i <= 0x44; i++) {
+ sisReg->sis6326tv[i] = SiS6326GetTVReg(pScrn, i);
+#ifdef TWDEBUG
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "VR%02X - %02X \n", i,sisReg->sis6326tv[i]);
+#endif
+ }
+ }
+}
+
+static void
+SiSRestore(ScrnInfoPtr pScrn, SISRegPtr sisReg)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int i,max;
+ unsigned char tmp;
+#ifdef DEBUG
+ int temp;
+#endif
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4,
+ "SiSRestore(ScrnInfoPtr pScrn, SISRegPtr sisReg)\n");
+
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+
+ switch (pSiS->Chipset) {
+ case PCI_CHIP_SIS5597:
+ max = 0x3C;
+ break;
+ case PCI_CHIP_SIS6326:
+ case PCI_CHIP_SIS530:
+ max = 0x3F;
+ break;
+ default:
+ max = 0x37;
+ break;
+ }
+
+ /* Disable TV on 6326 before restoring */
+ if((pSiS->Chipset == PCI_CHIP_SIS6326) && (pSiS->SiS6326Flags & SIS6326_HASTV)) {
+ outSISIDXREG(SISCR, 0x80, 0x86);
+ tmp = SiS6326GetTVReg(pScrn, 0x00);
+ tmp &= ~0x04;
+ SiS6326SetTVReg(pScrn, 0x00, tmp);
+ }
+
+ /* Restore VCLKs */
+#if 0 /* TW: No, we didn't save SR2x-1 and SR2x-2! */
+ andSISIDXREG(SISSR, 0x38, 0xfc);
+ inSISIDXREG(SISSR, 0x13, tmp);
+ tmp &= ~0x40;
+ tmp |= (sisReg->sisRegs3C4[0x13] & 0x40);
+ outSISIDXREG(SISSR, 0x13, tmp);
+ outSISIDXREG(SISSR, 0x2a, sisReg->sisRegs3C4[0x2a]);
+ outSISIDXREG(SISSR, 0x2b, sisReg->sisRegs3C4[0x2b]);
+ orSISIDXREG(SISSR, 0x38, 0x01);
+ inSISIDXREG(SISSR, 0x13, tmp);
+ tmp &= ~0x40;
+ tmp |= (sisReg->sisRegs3C4[0x13] & 0x40);
+ outSISIDXREG(SISSR, 0x13, tmp);
+ outSISIDXREG(SISSR, 0x2a, sisReg->sisRegs3C4[0x2a]);
+ outSISIDXREG(SISSR, 0x2b, sisReg->sisRegs3C4[0x2b]);
+ andSISIDXREG(SISSR, 0x38, 0xfc);
+ orSISIDXREG(SISSR, 0x38, 0x02);
+ inSISIDXREG(SISSR, 0x13, tmp);
+ tmp &= ~0x40;
+ tmp |= (sisReg->sisRegs3C4[0x13] & 0x40);
+ outSISIDXREG(SISSR, 0x13, tmp);
+ outSISIDXREG(SISSR, 0x2a, sisReg->sisRegs3C4[0x2a]);
+ outSISIDXREG(SISSR, 0x2b, sisReg->sisRegs3C4[0x2b]);
+ andSISIDXREG(SISSR, 0x38, 0xfc);
+#endif
+
+ /* Restore other extended SR registers */
+ for (i = 0x06; i <= max; i++) {
+ if((i == 0x13) || (i == 0x2a) || (i == 0x2b)) continue;
+#ifdef DEBUG
+ inSISIDXREG(SISSR, i, temp);
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4,
+ "SR%X Contents: %02X - ", i, temp);
+#endif
+ outSISIDXREG(SISSR, i, sisReg->sisRegs3C4[i]);
+#ifdef DEBUG
+ inSISIDXREG(SISSR, i, temp);
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4,
+ "Restored to %02X - Read: %02X\n",
+ sisReg->sisRegs3C4[i], temp);
+#endif
+ }
+
+ /* Now restore VCLK (with correct SR38 setting) */
+ outSISIDXREG(SISSR, 0x13, sisReg->sisRegs3C4[0x13]);
+ outSISIDXREG(SISSR, 0x2a, sisReg->sisRegs3C4[0x2a]);
+ outSISIDXREG(SISSR, 0x2b, sisReg->sisRegs3C4[0x2b]);
+
+ /* Misc */
+ outSISREG(SISMISCW, sisReg->sisRegs3C2);
+
+ /* MemClock needs this to take effect */
+ outSISIDXREG(SISSR, 0x00, 0x01); /* Synchronous Reset */
+ usleep(10000);
+ outSISIDXREG(SISSR, 0x00, 0x03); /* End Reset */
+
+ /* TW: Restore TV registers */
+ pSiS->SiS6326Flags &= ~SIS6326_TVON;
+ if((pSiS->Chipset == PCI_CHIP_SIS6326) && (pSiS->SiS6326Flags & SIS6326_HASTV)) {
+ for(i = 0x01; i <= 0x44; i++) {
+ SiS6326SetTVReg(pScrn, i, sisReg->sis6326tv[i]);
+#ifdef TWDEBUG
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "VR%02x restored to %02x\n",
+ i, sisReg->sis6326tv[i]);
+#endif
+ }
+ tmp = SiS6326GetXXReg(pScrn, 0x13);
+ SiS6326SetXXReg(pScrn, 0x13, 0xfa);
+ tmp = SiS6326GetXXReg(pScrn, 0x14);
+ SiS6326SetXXReg(pScrn, 0x14, 0xc8);
+ if(!(sisReg->sisRegs3C4[0x0D] & 0x04)) {
+ tmp = SiS6326GetXXReg(pScrn, 0x13);
+ SiS6326SetXXReg(pScrn, 0x13, 0xf6);
+ tmp = SiS6326GetXXReg(pScrn, 0x14);
+ SiS6326SetXXReg(pScrn, 0x14, 0xbf);
+ }
+ if(sisReg->sis6326tv[0] & 0x04) pSiS->SiS6326Flags |= SIS6326_TVON;
+ }
+}
+
+/* Save SiS 300 series register contents */
+static void
+SiS300Save(ScrnInfoPtr pScrn, SISRegPtr sisReg)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int i;
+
+ PDEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+ "SiS300Save(ScrnInfoPtr pScrn, SISRegPtr sisReg)\n"));
+
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+
+ /* Save SR registers */
+ for (i = 0x00; i <= 0x3D; i++) {
+ inSISIDXREG(SISSR, i, sisReg->sisRegs3C4[i]);
+#ifdef TWDEBUG
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "SR%02X - %02X \n", i,sisReg->sisRegs3C4[i]);
+#endif
+ }
+
+ /* Save CR registers */
+ for (i = 0x00; i < 0x40; i++) {
+ inSISIDXREG(SISCR, i, sisReg->sisRegs3D4[i]);
+#ifdef TWDEBUG
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "CR%02X Contents - %02X \n", i,sisReg->sisRegs3D4[i]);
+#endif
+ }
+
+ /* Save Misc register */
+ sisReg->sisRegs3C2 = inSISREG(SISMISCR);
+
+ /* Save FQBQ and GUI timer settings */
+ if(pSiS->Chipset == PCI_CHIP_SIS630) {
+ sisReg->sisRegsPCI50 = pciReadLong(0x00000000, 0x50);
+ sisReg->sisRegsPCIA0 = pciReadLong(0x00000000, 0xA0);
+#ifdef TWDEBUG
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "PCI Config 50 = %lx\n", sisReg->sisRegsPCI50);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "PCI Config A0 = %lx\n", sisReg->sisRegsPCIA0);
+#endif
+ }
+
+ /* Save panel link/video bridge registers */
+#ifndef TWDEBUG
+ if(!pSiS->UseVESA) {
+#endif
+ if (pSiS->VBFlags & (VB_LVDS|VB_CHRONTEL))
+ (*pSiS->SiSSaveLVDSChrontel)(pScrn, sisReg);
+ if (pSiS->VBFlags & (VB_301|VB_303))
+ (*pSiS->SiSSave2)(pScrn, sisReg);
+ if (pSiS->VBFlags & (VB_301B|VB_302B|VB_30xLV|VB_30xLVX))
+ (*pSiS->SiSSave3)(pScrn, sisReg);
+#ifndef TWDEBUG
+ }
+#endif
+
+ /* Save Mode number */
+#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,99,0,0)
+ if(!(pSiS->UseVESA))
+#endif
+ pSiS->BIOSModeSave = SiS_GetSetModeID(pScrn,0xFF);
+
+#ifdef TWDEBUG
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "BIOS mode ds:449 = 0x%x\n", pSiS->BIOSModeSave);
+#endif
+}
+
+
+/* Restore SiS300 series register contents */
+static void
+SiS300Restore(ScrnInfoPtr pScrn, SISRegPtr sisReg)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int i,temp;
+ CARD32 temp1;
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4,
+ "SiS300Restore(ScrnInfoPtr pScrn, SISRegPtr sisReg)\n");
+
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+
+ /* TW: Wait for accelerator to finish on-going drawing operations. */
+ inSISIDXREG(SISSR, 0x1E, temp);
+ if(temp & (0x40|0x10|0x02)) {
+ while ( (MMIO_IN16(pSiS->IOBase, 0x8242) & 0xE000) != 0xE000){};
+ while ( (MMIO_IN16(pSiS->IOBase, 0x8242) & 0xE000) != 0xE000){};
+ while ( (MMIO_IN16(pSiS->IOBase, 0x8242) & 0xE000) != 0xE000){};
+ }
+
+ if (!(pSiS->UseVESA)) {
+ if(pSiS->VBFlags & VB_LVDS) {
+ SiS_UnLockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30);
+ SiS_DisableBridge(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30);
+ }
+ }
+
+ /* Restore extended CR registers */
+ for(i = 0x19; i < 0x40; i++) {
+ outSISIDXREG(SISCR, i, sisReg->sisRegs3D4[i]);
+ }
+
+ if(pSiS->Chipset != PCI_CHIP_SIS300) {
+ unsigned char val;
+ inSISIDXREG(SISCR, 0x1A, val);
+ if(val == sisReg->sisRegs3D4[0x19])
+ outSISIDXREG(SISCR, 0x1A, sisReg->sisRegs3D4[0x19]);
+ inSISIDXREG(SISCR,0x19,val);
+ if(val == sisReg->sisRegs3D4[0x1A])
+ outSISIDXREG(SISCR, 0x19, sisReg->sisRegs3D4[0x1A]);
+ }
+
+ /* Set (and leave) PCI_IO_ENABLE on if accelerators are on */
+ if(sisReg->sisRegs3C4[0x1e] & 0x50) {
+ sisReg->sisRegs3C4[0x20] |= 0x20;
+ outSISIDXREG(SISSR, 0x20, sisReg->sisRegs3C4[0x20]);
+ }
+
+ /* TW: If TQ is switched on, don't switch it off ever again!
+ * Therefore, always restore registers with TQ enabled.
+ */
+ if((!pSiS->NoAccel) && (pSiS->TurboQueue)) {
+ temp = (pScrn->videoRam/64) - 8;
+ sisReg->sisRegs3C4[0x26] = temp & 0xFF;
+ sisReg->sisRegs3C4[0x27] = ((temp >> 8) & 3) | 0xF0;
+ }
+
+ /* Restore extended SR registers */
+ for (i = 0x06; i <= 0x3D; i++) {
+ temp = sisReg->sisRegs3C4[i];
+ if(!(pSiS->UseVESA)) {
+ if(pSiS->VBFlags & VB_LVDS) {
+ if(i == 0x11) {
+ inSISIDXREG(SISSR,0x11,temp);
+ temp &= 0x0c;
+ temp |= (sisReg->sisRegs3C4[i] & 0xf3);
+ }
+ }
+ }
+ outSISIDXREG(SISSR, i, temp);
+ }
+
+ /* TW: Restore VCLK and ECLK */
+ if(pSiS->VBFlags & (VB_LVDS | VB_301B)) {
+ outSISIDXREG(SISSR,0x31,0x20);
+ outSISIDXREG(SISSR,0x2b,sisReg->sisRegs3C4[0x2b]);
+ outSISIDXREG(SISSR,0x2c,sisReg->sisRegs3C4[0x2c]);
+ outSISIDXREG(SISSR,0x2d,0x80);
+ outSISIDXREG(SISSR,0x31,0x10);
+ outSISIDXREG(SISSR,0x2b,sisReg->sisRegs3C4[0x2b]);
+ outSISIDXREG(SISSR,0x2c,sisReg->sisRegs3C4[0x2c]);
+ outSISIDXREG(SISSR,0x2d,0x80);
+ }
+ outSISIDXREG(SISSR,0x31,0x00);
+ outSISIDXREG(SISSR,0x2b,sisReg->sisRegs3C4[0x2b]);
+ outSISIDXREG(SISSR,0x2c,sisReg->sisRegs3C4[0x2c]);
+ outSISIDXREG(SISSR,0x2d,0x80);
+ if(pSiS->VBFlags & (VB_LVDS | VB_301B)) {
+ outSISIDXREG(SISSR,0x31,0x20);
+ outSISIDXREG(SISSR,0x2e,sisReg->sisRegs3C4[0x2e]);
+ outSISIDXREG(SISSR,0x2f,sisReg->sisRegs3C4[0x2f]);
+ outSISIDXREG(SISSR,0x31,0x10);
+ outSISIDXREG(SISSR,0x2e,sisReg->sisRegs3C4[0x2e]);
+ outSISIDXREG(SISSR,0x2f,sisReg->sisRegs3C4[0x2f]);
+ outSISIDXREG(SISSR,0x31,0x00);
+ outSISIDXREG(SISSR,0x2e,sisReg->sisRegs3C4[0x2e]);
+ outSISIDXREG(SISSR,0x2f,sisReg->sisRegs3C4[0x2f]);
+ }
+
+ /* Restore Misc register */
+ outSISREG(SISMISCW, sisReg->sisRegs3C2);
+
+ /* Restore FQBQ and GUI timer settings */
+ if(pSiS->Chipset == PCI_CHIP_SIS630) {
+ temp1 = pciReadLong(0x00000000, 0x50);
+ if(pciReadLong(0x00000000, 0x00) == 0x06301039) {
+ temp1 &= 0xf0ffffff;
+ temp1 |= (sisReg->sisRegsPCI50 & ~0xf0ffffff);
+ } else { /* 730 */
+ temp1 &= 0xfffff9ff;
+ temp1 |= (sisReg->sisRegsPCI50 & ~0xfffff9ff);
+ }
+ pciWriteLong(0x00000000, 0x50, temp1);
+
+ temp1 = pciReadLong(0x00000000, 0xA0);
+ if(pciReadLong(0x00000000, 0x00) == 0x06301039) {
+ temp1 &= 0xf0ffffff;
+ temp1 |= (sisReg->sisRegsPCIA0 & ~0xf0ffffff);
+ } else { /* 730 */
+ temp1 &= 0x00ffffff;
+ temp1 |= (sisReg->sisRegsPCIA0 & ~0x00ffffff);
+ }
+ pciWriteLong(0x00000000, 0xA0, temp1);
+ }
+
+ /* Restore panel link/video bridge registers */
+ if (!(pSiS->UseVESA)) {
+ if (pSiS->VBFlags & (VB_LVDS|VB_CHRONTEL))
+ (*pSiS->SiSRestoreLVDSChrontel)(pScrn, sisReg);
+ if (pSiS->VBFlags & (VB_301|VB_303))
+ (*pSiS->SiSRestore2)(pScrn, sisReg);
+ if (pSiS->VBFlags & (VB_301B|VB_302B|VB_30xLV|VB_30xLVX))
+ (*pSiS->SiSRestore3)(pScrn, sisReg);
+ }
+
+ /* MemClock needs this to take effect */
+ outSISIDXREG(SISSR, 0x00, 0x01); /* Synchronous Reset */
+ outSISIDXREG(SISSR, 0x00, 0x03); /* End Reset */
+
+ /* Restore mode number */
+#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,99,0,0)
+ if(!(pSiS->UseVESA))
+#endif
+ SiS_GetSetModeID(pScrn,pSiS->BIOSModeSave);
+}
+
+/* Save SiS310 series register contents */
+static void
+SiS310Save(ScrnInfoPtr pScrn, SISRegPtr sisReg)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int i;
+
+ PDEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+ "SiS310Save(ScrnInfoPtr pScrn, SISRegPtr sisReg)\n"));
+
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+
+ /* Save SR registers */
+ for (i = 0x00; i <= 0x3F; i++) {
+ inSISIDXREG(SISSR, i, sisReg->sisRegs3C4[i]);
+#ifdef DEBUG
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4,
+ "SR%02X - %02X \n", i,sisReg->sisRegs3C4[i]);
+#endif
+#ifdef TWDEBUG
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "SR%02X - %02X \n", i,sisReg->sisRegs3C4[i]);
+#endif
+ }
+
+ /* TW: Save command queue location */
+ sisReg->sisMMIO85C0 = MMIO_IN32(pSiS->IOBase, 0x85C0);
+
+ /* Save CR registers */
+ for (i = 0x00; i <= 0x5f; i++) {
+ inSISIDXREG(SISCR, i, sisReg->sisRegs3D4[i]);
+#ifdef DEBUG
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4,
+ "CR%02X - %02X \n", i,sisReg->sisRegs3D4[i]);
+#endif
+#ifdef TWDEBUG
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "CR%02X Contents - %02X \n", i,sisReg->sisRegs3D4[i]);
+#endif
+ }
+
+ /* Save Misc register */
+ sisReg->sisRegs3C2 = inSISREG(SISMISCR);
+
+ /* Save panel link/video bridge registers */
+#ifndef TWDEBUG
+ if (!pSiS->UseVESA) {
+#endif
+ if (pSiS->VBFlags & (VB_LVDS|VB_CHRONTEL))
+ (*pSiS->SiSSaveLVDSChrontel)(pScrn, sisReg);
+ if (pSiS->VBFlags & (VB_301|VB_303))
+ (*pSiS->SiSSave2)(pScrn, sisReg);
+ if (pSiS->VBFlags & (VB_301B|VB_302B|VB_30xLV|VB_30xLVX))
+ (*pSiS->SiSSave3)(pScrn, sisReg);
+#ifndef TWDEBUG
+ }
+#endif
+
+ /* Save mode number */
+#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,99,0,0)
+ if(!(pSiS->UseVESA))
+#endif
+ pSiS->BIOSModeSave = SiS_GetSetModeID(pScrn,0xFF);
+}
+
+/* Restore SiS310 series register contents */
+static void
+SiS310Restore(ScrnInfoPtr pScrn, SISRegPtr sisReg)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int i,temp;
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4,
+ "SiS310Restore(ScrnInfoPtr pScrn, SISRegPtr sisReg)\n");
+
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+
+ /* TW: Wait for accelerator to finish on-going drawing operations. */
+ inSISIDXREG(SISSR, 0x1E, temp);
+ if (temp & (0x40|0x10|0x02)) { /* TW: 0x40 = 2D, 0x10 = 3D enabled*/
+ while ( (MMIO_IN32(pSiS->IOBase, 0x85CC) & 0x80000000) != 0x80000000){};
+ while ( (MMIO_IN32(pSiS->IOBase, 0x85CC) & 0x80000000) != 0x80000000){};
+ while ( (MMIO_IN32(pSiS->IOBase, 0x85CC) & 0x80000000) != 0x80000000){};
+ }
+
+ /* Restore extended CR registers */
+ for (i = 0x19; i < 0x5C; i++) {
+ outSISIDXREG(SISCR, i, sisReg->sisRegs3D4[i]);
+ }
+
+ /* TW: Leave PCI_IO_ENABLE on if accelerators are on (Is this required?) */
+ if (sisReg->sisRegs3C4[0x1e] & 0x50) { /*0x40=2D, 0x10=3D*/
+ sisReg->sisRegs3C4[0x20] |= 0x20;
+ outSISIDXREG(SISSR, 0x20, sisReg->sisRegs3C4[0x20]);
+ }
+
+ /* TW: We reset the command queue before restoring.
+ * This might be required because we never know what
+ * console driver (like the kernel framebuffer driver)
+ * or application is running and which queue mode it
+ * uses.
+ */
+ outSISIDXREG(SISSR, 0x27, 0x1F);
+ outSISIDXREG(SISSR, 0x26, 0x01);
+
+ /* Restore extended SR registers */
+ for (i = 0x06; i <= 0x3F; i++) {
+#ifdef DEBUG
+ inSISIDXREG(SISSR, i, temp);
+#endif
+ outSISIDXREG(SISSR, i, sisReg->sisRegs3C4[i]);
+#ifdef DEBUG
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4,
+ "XR%X Contents %02X - ", i, temp);
+ inSISIDXREG(SISSR, i, temp);
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4,
+ "Restored to %02X - Read: %02X\n",
+ sisReg->sisRegs3C4[i], temp);
+#endif
+ }
+ /* TW: Restore VCLK and ECLK */
+ andSISIDXREG(SISSR,0x31,0xcf);
+ if(pSiS->VBFlags & VB_LVDS) {
+ orSISIDXREG(SISSR,0x31,0x20);
+ outSISIDXREG(SISSR,0x2b,sisReg->sisRegs3C4[0x2b]);
+ outSISIDXREG(SISSR,0x2c,sisReg->sisRegs3C4[0x2c]);
+ outSISIDXREG(SISSR,0x2d,0x80);
+ andSISIDXREG(SISSR,0x31,0xcf);
+ orSISIDXREG(SISSR,0x31,0x10);
+ outSISIDXREG(SISSR,0x2b,sisReg->sisRegs3C4[0x2b]);
+ outSISIDXREG(SISSR,0x2c,sisReg->sisRegs3C4[0x2c]);
+ outSISIDXREG(SISSR,0x2d,0x80);
+ andSISIDXREG(SISSR,0x31,0xcf);
+ outSISIDXREG(SISSR,0x2b,sisReg->sisRegs3C4[0x2b]);
+ outSISIDXREG(SISSR,0x2c,sisReg->sisRegs3C4[0x2c]);
+ outSISIDXREG(SISSR,0x2d,0x01);
+ outSISIDXREG(SISSR,0x31,0x20);
+ outSISIDXREG(SISSR,0x2e,sisReg->sisRegs3C4[0x2e]);
+ outSISIDXREG(SISSR,0x2f,sisReg->sisRegs3C4[0x2f]);
+ outSISIDXREG(SISSR,0x31,0x10);
+ outSISIDXREG(SISSR,0x2e,sisReg->sisRegs3C4[0x2e]);
+ outSISIDXREG(SISSR,0x2f,sisReg->sisRegs3C4[0x2f]);
+ outSISIDXREG(SISSR,0x31,0x00);
+ outSISIDXREG(SISSR,0x2e,sisReg->sisRegs3C4[0x2e]);
+ outSISIDXREG(SISSR,0x2f,sisReg->sisRegs3C4[0x2f]);
+ } else {
+ outSISIDXREG(SISSR,0x2b,sisReg->sisRegs3C4[0x2b]);
+ outSISIDXREG(SISSR,0x2c,sisReg->sisRegs3C4[0x2c]);
+ outSISIDXREG(SISSR,0x2d,0x01);
+ }
+
+ /* TW: Initialize read/write pointer for command queue */
+ MMIO_OUT32(pSiS->IOBase, 0x85C4, MMIO_IN32(pSiS->IOBase, 0x85C8));
+ /* TW: Restore queue location */
+ MMIO_OUT32(pSiS->IOBase, 0x85C0, sisReg->sisMMIO85C0);
+
+ /* Restore Misc register */
+ outSISREG(SISMISCW, sisReg->sisRegs3C2);
+
+ /* Restore panel link/video bridge registers */
+ if (!(pSiS->UseVESA)) {
+ if (pSiS->VBFlags & (VB_LVDS|VB_CHRONTEL))
+ (*pSiS->SiSRestoreLVDSChrontel)(pScrn, sisReg);
+ if (pSiS->VBFlags & (VB_301|VB_303))
+ (*pSiS->SiSRestore2)(pScrn, sisReg);
+ if (pSiS->VBFlags & (VB_301B|VB_302B|VB_30xLV|VB_30xLVX))
+ (*pSiS->SiSRestore3)(pScrn, sisReg);
+ }
+
+ /* MemClock needs this to take effect */
+ outSISIDXREG(SISSR, 0x00, 0x01); /* Synchronous Reset */
+ outSISIDXREG(SISSR, 0x00, 0x03); /* End Reset */
+
+ /* Restore Mode number */
+#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,99,0,0)
+ if(!(pSiS->UseVESA))
+#endif
+ SiS_GetSetModeID(pScrn,pSiS->BIOSModeSave);
+}
+
+/* Save SiS301 bridge register contents */
+static void
+SiS301Save(ScrnInfoPtr pScrn, SISRegPtr sisReg)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int i;
+ int Part1max=0, Part2max=0, Part3max=0, Part4max=0;
+
+ /* Highest register number to save/restore */
+ switch (pSiS->VGAEngine) {
+ case SIS_300_VGA:
+ Part1max = 0x1d;
+ Part2max = 0x45;
+ Part3max = 0x3e;
+ Part4max = 0x1b;
+ break;
+ case SIS_315_VGA:
+ Part1max = 0x2e; /* 0x23, but we also need 2d-2e */
+ Part2max = 0x45;
+ Part3max = 0x3e;
+ Part4max = 0x1b;
+ break;
+ }
+
+ for (i=0; i<=Part1max; i++) {
+ inSISIDXREG(SISPART1, i, sisReg->VBPart1[i]);
+#ifdef TWDEBUG
+ xf86DrvMsg(0, X_INFO, "301Save: Part1Port 0x%02x = 0x%02x\n", i, sisReg->VBPart1[i]);
+#endif
+ }
+ for (i=0; i<=Part2max; i++) {
+ inSISIDXREG(SISPART2, i, sisReg->VBPart2[i]);
+#ifdef TWDEBUG
+ xf86DrvMsg(0, X_INFO, "301Save: Part2Port 0x%02x = 0x%02x\n", i, sisReg->VBPart2[i]);
+#endif
+ }
+ for (i=0; i<=Part3max; i++) {
+ inSISIDXREG(SISPART3, i, sisReg->VBPart3[i]);
+#ifdef TWDEBUG
+ xf86DrvMsg(0, X_INFO, "301Save: Part3Port 0x%02x = 0x%02x\n", i, sisReg->VBPart3[i]);
+#endif
+ }
+ for (i=0; i<=Part4max; i++) {
+ inSISIDXREG(SISPART4, i, sisReg->VBPart4[i]);
+#ifdef TWDEBUG
+ xf86DrvMsg(0, X_INFO, "301Save: Part4Port 0x%02x = 0x%02x\n", i, sisReg->VBPart4[i]);
+#endif
+ }
+
+ sisReg->VBPart2[0] &= ~0x20; /* Disable VB Processor */
+ sisReg->sisRegs3C4[0x32] &= ~0x20; /* Disable Lock Mode */
+}
+
+/* Restore SiS301 bridge register contents */
+static void
+SiS301Restore(ScrnInfoPtr pScrn, SISRegPtr sisReg)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int Part1max=0, Part2max=0, Part3max=0, Part4max=0;
+
+ /* Highest register number to save/restore */
+ switch (pSiS->VGAEngine) {
+ case SIS_300_VGA:
+ Part1max = 0x1d;
+ Part2max = 0x45;
+ Part3max = 0x3e;
+ Part4max = 0x1b;
+ break;
+ case SIS_315_VGA:
+ Part1max = 0x23;
+ Part2max = 0x45;
+ Part3max = 0x3e;
+ Part4max = 0x1b;
+ break;
+ }
+
+ SiS_DisableBridge(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30);
+
+ SiS_UnLockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30);
+
+ /* Pre-restore Part1 */
+ outSISIDXREG(SISPART1, 0x04, 0x00);
+ outSISIDXREG(SISPART1, 0x05, 0x00);
+ outSISIDXREG(SISPART1, 0x06, 0x00);
+ outSISIDXREG(SISPART1, 0x00, sisReg->VBPart1[0]);
+ outSISIDXREG(SISPART1, 0x01, sisReg->VBPart1[1]);
+
+ /* Pre-restore Part4 */
+ outSISIDXREG(SISPART4, 0x0D, sisReg->VBPart4[0x0D]);
+ outSISIDXREG(SISPART4, 0x0C, sisReg->VBPart4[0x0C]);
+
+ if (!(sisReg->sisRegs3D4[0x30] & 0x03) &&
+ (sisReg->sisRegs3D4[0x31] & 0x20)) { /* disable CRT2 */
+ SiS_LockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30);
+ return;
+ }
+
+ /* Restore Part1 */
+ SetBlock(SISPART1, 0x02, Part1max, &(sisReg->VBPart1[0x02]));
+ switch (pSiS->VGAEngine) {
+ case SIS_300_VGA:
+ /* TW: Nothing special here. */
+ break;
+ case SIS_315_VGA:
+ /* TW: Restore extra registers on 310 series */
+ SetBlock(SISPART1, 0x2C, 0x2E, &(sisReg->VBPart1[0x2C]));
+ break;
+ }
+
+ /* Restore Part2 */
+ SetBlock(SISPART2, 0x00, Part2max, &(sisReg->VBPart2[0x00]));
+
+ /* Restore Part3 */
+ SetBlock(SISPART3, 0x00, Part3max, &(sisReg->VBPart3[0x00]));
+
+ /* Restore Part4 */
+ SetBlock(SISPART4, 0x0E, 0x11, &(sisReg->VBPart4[0x0E]));
+ SetBlock(SISPART4, 0x13, Part4max, &(sisReg->VBPart4[0x13]));
+
+ /* Post-restore Part4 (CRT2VCLK) */
+ outSISIDXREG(SISPART4, 0x0A, 0x01);
+ outSISIDXREG(SISPART4, 0x0B, sisReg->VBPart4[0x0B]);
+ outSISIDXREG(SISPART4, 0x0A, sisReg->VBPart4[0x0A]);
+ outSISIDXREG(SISPART4, 0x12, 0x00);
+ outSISIDXREG(SISPART4, 0x12, sisReg->VBPart4[0x12]);
+
+ SiS_EnableBridge(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30);
+ SiS_DisplayOn(pSiS->SiS_Pr);
+ SiS_LockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30);
+}
+
+/* Save SiS301B/302B/30xLV bridge register contents */
+static void
+SiS301BSave(ScrnInfoPtr pScrn, SISRegPtr sisReg)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int i;
+ int Part1max=0, Part2max=0, Part3max=0, Part4max=0;
+
+ switch (pSiS->VGAEngine) {
+ case SIS_300_VGA:
+ Part1max = 0x37; /* 0x1d, but we also need 2c-2e, 35-37 */
+ Part2max = 0x4d;
+ Part3max = 0x3e;
+ if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX))
+ Part4max = 0x24;
+ else
+ Part4max = 0x23;
+ break;
+ case SIS_315_VGA:
+ Part1max = 0x37; /* 0x23, but we also need 2c-2e, 35-37 */
+ Part2max = 0x4d;
+ Part3max = 0x3e;
+ if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX))
+ Part4max = 0x24;
+ else
+ Part4max = 0x23;
+ break;
+ }
+
+ for (i=0; i<=Part1max; i++) {
+ inSISIDXREG(SISPART1, i, sisReg->VBPart1[i]);
+#ifdef TWDEBUG
+ xf86DrvMsg(0, X_INFO, "301BSave: Part1Port 0x%02x = 0x%02x\n", i, sisReg->VBPart1[i]);
+#endif
+ }
+ for (i=0; i<=Part2max; i++) {
+ inSISIDXREG(SISPART2, i, sisReg->VBPart2[i]);
+#ifdef TWDEBUG
+ xf86DrvMsg(0, X_INFO, "301BSave: Part2Port 0x%02x = 0x%02x\n", i, sisReg->VBPart2[i]);
+#endif
+ }
+ for (i=0; i<=Part3max; i++) {
+ inSISIDXREG(SISPART3, i, sisReg->VBPart3[i]);
+#ifdef TWDEBUG
+ xf86DrvMsg(0, X_INFO, "301BSave: Part3Port 0x%02x = 0x%02x\n", i, sisReg->VBPart3[i]);
+#endif
+ }
+ for (i=0; i<=Part4max; i++) {
+ inSISIDXREG(SISPART4, i, sisReg->VBPart4[i]);
+#ifdef TWDEBUG
+ xf86DrvMsg(0, X_INFO, "301BSave: Part4Port 0x%02x = 0x%02x\n", i, sisReg->VBPart4[i]);
+#endif
+ }
+ sisReg->VBPart2[0] &= ~0x20; /* Disable VB Processor */
+ sisReg->sisRegs3C4[0x32] &= ~0x20; /* Disable Lock Mode */
+}
+
+/* Restore SiS301B/302B/301LV/302LV bridge register contents */
+static void
+SiS301BRestore(ScrnInfoPtr pScrn, SISRegPtr sisReg)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int Part1max=0, Part2max=0, Part3max=0, Part4max=0;
+
+ switch (pSiS->VGAEngine) {
+ case SIS_300_VGA:
+ Part1max = 0x23;
+ Part2max = 0x4d;
+ Part3max = 0x3e;
+ if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX))
+ Part4max = 0x24;
+ else
+ Part4max = 0x22;
+ break;
+ case SIS_315_VGA:
+ Part1max = 0x23;
+ Part2max = 0x4d;
+ Part3max = 0x3e;
+ if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX))
+ Part4max = 0x24;
+ else
+ Part4max = 0x22;
+ break;
+ }
+
+ SiS_DisableBridge(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30);
+
+ SiS_UnLockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30);
+
+ /* Pre-restore Part1 */
+ outSISIDXREG(SISPART1, 0x04, 0x00);
+ outSISIDXREG(SISPART1, 0x05, 0x00);
+ outSISIDXREG(SISPART1, 0x06, 0x00);
+ outSISIDXREG(SISPART1, 0x00, sisReg->VBPart1[0x00]);
+ outSISIDXREG(SISPART1, 0x01, sisReg->VBPart1[0x01]);
+ /* Mode reg 0x01 became 0x2e on 310 series (0x01 still contains FIFO) */
+ if(pSiS->VGAEngine == SIS_315_VGA)
+ outSISIDXREG(SISPART1, 0x2e, sisReg->VBPart1[0x2e]);
+
+ /* Pre-restore Part4 */
+ outSISIDXREG(SISPART4, 0x0D, sisReg->VBPart4[0x0D]);
+ outSISIDXREG(SISPART4, 0x0C, sisReg->VBPart4[0x0C]);
+
+ if (!(sisReg->sisRegs3D4[0x30] & 0x03) &&
+ (sisReg->sisRegs3D4[0x31] & 0x20)) { /* disable CRT2 */
+ SiS_LockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30);
+ return;
+ }
+
+ /* Restore Part1 */
+ SetBlock(SISPART1, 0x02, Part1max, &(sisReg->VBPart1[0x02]));
+ if(pSiS->VGAEngine == SIS_315_VGA) {
+ SetBlock(SISPART1, 0x2C, 0x2D, &(sisReg->VBPart1[0x2C]));
+ SetBlock(SISPART1, 0x35, 0x37, &(sisReg->VBPart1[0x35]));
+ }
+
+ /* Restore Part2 */
+ SetBlock(SISPART2, 0x00, Part2max, &(sisReg->VBPart2[0x00]));
+
+ /* Restore Part3 */
+ SetBlock(SISPART3, 0x00, Part3max, &(sisReg->VBPart3[0x00]));
+
+ /* Restore Part4 */
+ SetBlock(SISPART4, 0x0E, 0x11, &(sisReg->VBPart4[0x0E]));
+ SetBlock(SISPART4, 0x13, Part4max, &(sisReg->VBPart4[0x13]));
+
+ /* Post-restore Part4 (CRT2VCLK) */
+ outSISIDXREG(SISPART4, 0x0A, sisReg->VBPart4[0x0A]);
+ outSISIDXREG(SISPART4, 0x0B, sisReg->VBPart4[0x0B]);
+ outSISIDXREG(SISPART4, 0x12, 0x00);
+ outSISIDXREG(SISPART4, 0x12, sisReg->VBPart4[0x12]);
+
+ SiS_EnableBridge(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30);
+ SiS_DisplayOn(pSiS->SiS_Pr);
+ SiS_LockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30);
+}
+
+/* Save LVDS bridge (+ Chrontel) register contents */
+static void
+SiSLVDSChrontelSave(ScrnInfoPtr pScrn, SISRegPtr sisReg)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int i;
+
+ /* Save Part1 */
+ for (i=0; i<0x46; i++) {
+ inSISIDXREG(SISPART1, i, sisReg->VBPart1[i]);
+#ifdef TWDEBUG
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "LVDSSave: Part1Port 0x%02x = 0x%02x\n",
+ i, sisReg->VBPart1[i]);
+#endif
+ }
+
+ /* Save Chrontel registers */
+ if (pSiS->VBFlags & VB_CHRONTEL) {
+ if (pSiS->ChrontelType == CHRONTEL_700x) {
+ for (i=0; i<0x1D; i++) {
+ sisReg->ch70xx[i] = SiS_GetCH700x(pSiS->SiS_Pr, ch700xidx[i]);
+#ifdef TWDEBUG
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "LVDSSave: Chrontel 0x%02x = 0x%02x\n",
+ ch700xidx[i], sisReg->ch70xx[i]);
+#endif
+
+ }
+ } else {
+ for (i=0; i<34; i++) {
+ sisReg->ch70xx[i] = SiS_GetCH701x(pSiS->SiS_Pr, ch701xidx[i]);
+ }
+ }
+ }
+
+ sisReg->sisRegs3C4[0x32] &= ~0x20; /* Disable Lock Mode */
+}
+
+/* Restore LVDS bridge (+ Chrontel) register contents */
+static void
+SiSLVDSChrontelRestore(ScrnInfoPtr pScrn, SISRegPtr sisReg)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int i;
+ USHORT wtemp;
+
+ SiS_DisableBridge(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30);
+ if(pSiS->sishw_ext.jChipType == SIS_730) {
+ outSISIDXREG(SISPART1, 0x00, 0x80);
+ }
+
+ SiS_UnLockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30);
+
+ if(pSiS->VBFlags & VB_CHRONTEL) {
+ /* Restore Chrontel registers */
+ if(pSiS->ChrontelType == CHRONTEL_700x) {
+ for(i=0; i<0x11; i++) {
+ wtemp = ((sisReg->ch70xx[i]) << 8) | (ch700xidx[i] & 0x00FF);
+ SiS_SetCH700x(pSiS->SiS_Pr, wtemp);
+ }
+ } else {
+ for(i=0; i<34; i++) {
+ wtemp = ((sisReg->ch70xx[i]) << 8) | (ch701xidx[i] & 0x00FF);
+ SiS_SetCH701x(pSiS->SiS_Pr, wtemp);
+ }
+ }
+ }
+
+ /* pre-restore Part1 */
+ outSISIDXREG(SISPART1, 0x04, 0x00);
+ outSISIDXREG(SISPART1, 0x05, 0x00);
+ outSISIDXREG(SISPART1, 0x06, 0x00);
+ outSISIDXREG(SISPART1, 0x00, sisReg->VBPart1[0]);
+ if(pSiS->VGAEngine == SIS_300_VGA) {
+ outSISIDXREG(SISPART1, 0x01, (sisReg->VBPart1[1] | 0x80));
+ } else {
+ outSISIDXREG(SISPART1, 0x01, sisReg->VBPart1[1]);
+ }
+
+ if (!(sisReg->sisRegs3D4[0x30] & 0x03) &&
+ (sisReg->sisRegs3D4[0x31] & 0x20)) { /* disable CRT2 */
+ SiS_LockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30);
+ return;
+ }
+
+ /* Restore Part1 */
+ if(pSiS->VGAEngine == SIS_300_VGA) {
+ outSISIDXREG(SISPART1, 0x02, (sisReg->VBPart1[2] | 0x40));
+ } else {
+ outSISIDXREG(SISPART1, 0x02, sisReg->VBPart1[2]);
+ }
+ SetBlock(SISPART1, 0x03, 0x23, &(sisReg->VBPart1[0x03]));
+ if(pSiS->VGAEngine == SIS_315_VGA) {
+ SetBlock(SISPART1, 0x2C, 0x2E, &(sisReg->VBPart1[0x2C]));
+ SetBlock(SISPART1, 0x35, 0x37, &(sisReg->VBPart1[0x35])); /* Panel Link Scaler */
+ }
+
+ /* TW: For 550 DSTN registers */
+ if (pSiS->DSTN) {
+ SetBlock(SISPART1, 0x25, 0x2E, &(sisReg->VBPart1[0x25]));
+ SetBlock(SISPART1, 0x30, 0x45, &(sisReg->VBPart1[0x30]));
+ }
+
+ SiS_EnableBridge(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30);
+ SiS_DisplayOn(pSiS->SiS_Pr);
+ SiS_LockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30);
+}
+
+/* TW: Restore output selection registers (CR30, 31, 33, 35/38) */
+void
+SiSRestoreBridge(ScrnInfoPtr pScrn, SISRegPtr sisReg)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ unsigned char temp = 0;
+
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+
+ outSISIDXREG(SISCR, 0x30, sisReg->sisRegs3D4[0x30]);
+ outSISIDXREG(SISCR, 0x31, sisReg->sisRegs3D4[0x31]);
+ outSISIDXREG(SISCR, 0x33, sisReg->sisRegs3D4[0x33]);
+ if(pSiS->Chipset != PCI_CHIP_SIS300) {
+ switch(pSiS->VGAEngine) {
+ case SIS_300_VGA: temp = 0x35; break;
+ case SIS_315_VGA: temp = 0x38; break;
+ }
+ if(temp) {
+ outSISIDXREG(SISCR, temp, sisReg->sisRegs3D4[temp]);
+ }
+ }
+}
+
+unsigned int
+SiSddc1Read(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ unsigned char temp;
+
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+
+ /* Wait until vertical retrace is in progress. */
+ while(inSISREG(SISINPSTAT) & 0x08);
+ while(!(inSISREG(SISINPSTAT) & 0x08));
+
+ /* Get the result */
+ inSISIDXREG(SISSR, 0x11, temp);
+
+ return((temp & 0x02)>>1);
+}
+
+#if 0 /* TW: I2C functions not in use */
+/*
+static void
+SiS_I2CGetBits(I2CBusPtr b, int *clock, int *data)
+{
+ SISPtr pSiS = SISPTR(xf86Screens[b->scrnIndex]);
+ unsigned char val;
+
+ outSISIDXREG(SISSR, 0x05, 0x86);
+ inSISIDXREG(SISSR, pSiS->SiS_DDC2_Index, val);
+ *clock = (val & pSiS->SiS_DDC2_Clk) != 0;
+ *data = (val & pSiS->SiS_DDC2_Data) != 0;
+}
+
+static void
+SiS_I2CPutBits(I2CBusPtr b, int clock, int data)
+{
+ SISPtr pSiS = SISPTR(xf86Screens[b->scrnIndex]);
+ unsigned char temp;
+
+ outSISIDXREG(SISSR, 0x05, 0x86);
+ inSISIDXREG(SISSR, pSiS->SiS_DDC2_Index, temp);
+
+ temp &= ~(pSiS->SiS_DDC2_Clk | pSiS->SiS_DDC2_Data);
+
+ temp |= ((clock ? pSiS->SiS_DDC2_Clk : 0) | (data ? pSiS->SiS_DDC2_Data : 0));
+
+ outSISIDXREG(SISSR, pSiS->SiS_DDC2_Index, temp);
+}
+*/
+
+static Bool
+SiS_I2CAddress(I2CDevPtr d, I2CSlaveAddr addr)
+{
+ I2CBusPtr b = d->pI2CBus;
+ SISPtr pSiS = SISPTR(xf86Screens[b->scrnIndex]);
+ SiS_SetSwitchDDC2(pSiS->SiS_Pr);
+ return(SiS_I2C_Address(pSiS->SiS_Pr, addr));
+}
+
+static void
+SiS_I2CStop(I2CDevPtr d)
+{
+ I2CBusPtr b = d->pI2CBus;
+ SISPtr pSiS = SISPTR(xf86Screens[b->scrnIndex]);
+ SiS_I2C_Stop(pSiS->SiS_Pr);
+}
+
+static Bool
+SiS_I2CGetByte(I2CDevPtr d, I2CByte *data, Bool last)
+{
+ I2CBusPtr b = d->pI2CBus;
+ SISPtr pSiS = SISPTR(xf86Screens[b->scrnIndex]);
+ USHORT temp = SiS_I2C_GetByte(pSiS->SiS_Pr);
+ if(temp == 0xffff) return FALSE;
+ return TRUE;
+}
+
+static Bool
+SiS_I2CPutByte(I2CDevPtr d, I2CByte data)
+{
+ I2CBusPtr b = d->pI2CBus;
+ SISPtr pSiS = SISPTR(xf86Screens[b->scrnIndex]);
+ return(SiS_I2C_PutByte(pSiS->SiS_Pr, (USHORT)data));
+}
+
+Bool
+SiSI2CInit(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ I2CBusPtr I2CPtr;
+ USHORT temp, i;
+ unsigned char buffer[256];
+ xf86MonPtr pMonitor;
+
+ I2CPtr = xf86CreateI2CBusRec();
+ if(!I2CPtr) return FALSE;
+
+ pSiS->I2C = I2CPtr;
+
+ I2CPtr->BusName = "DDC";
+ I2CPtr->scrnIndex = pScrn->scrnIndex;
+/*
+ I2CPtr->I2CPutBits = SiS_I2CPutBits;
+ I2CPtr->I2CGetBits = SiS_I2CGetBits;
+*/
+ I2CPtr->I2CPutByte = SiS_I2CPutByte;
+ I2CPtr->I2CGetByte = SiS_I2CGetByte;
+ I2CPtr->I2CAddress = SiS_I2CAddress;
+ I2CPtr->I2CStop = SiS_I2CStop;
+ I2CPtr->AcknTimeout = 30;
+
+
+
+ pSiS->SiS_Pr->SiS_DDC_Index = pSiS->SiS_DDC2_Index;
+ pSiS->SiS_Pr->SiS_DDC_Data = pSiS->SiS_DDC2_Data;
+ pSiS->SiS_Pr->SiS_DDC_Clk = pSiS->SiS_DDC2_Clk;
+ pSiS->SiS_Pr->SiS_DDC_DataShift = 0x00;
+
+ if (!xf86I2CBusInit(I2CPtr)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Could not create I2C bus record\n");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+#endif
+
+#if 0 /* TW: The following function should take a threshold value
+ * from predefined tables. This is only needed on some
+ * 530 boards, which have an ESS sound device on-board.
+ * However, I don't know how to calculate the index to
+ * be submitted to this function.
+ */
+unsigned short
+SiS_CalcSpecial530Threshold(ScrnInfoPtr pScrn, DisplayModePtr mode, int index)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ static const unsigned char t640x480[3][24] = {
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,A9, /* b4 - 9d - depth 8 */
+ 0, 0,11,14,14, 0, 0, 0, 0, 0, 0,9D },
+ { 0, 0, 0, 0, 0,12,15, 0, 0, 0,92,91, /* 9c - 85 - depth 16 */
+ 0,31,31,31,31, 0, 0, 0, 0, 0, 0,85 },
+ { 0, 0, 0, 0, 0,17,22,25, 0, 0, 0,79, /* 84 - ? - depth 32 */
+ 0,31,31, 0, 0, 0, 0, 0, 0, 0, 0,6d }
+ }
+ static const unsigned char t800x600[3][24] = {
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,61,
+ 0,18,25,30,27,31,31,31, 0, 0, 0, 0 },
+ {55, 0, 0, 0, 0, 9,10,15,18,19, 0, 0,
+ ... to be continued
+
+ depthindex = (pSiS->CurrentLayout.bitsPerPixel + 1) >> 3;
+ if(depthindex == 3) return(0);
+ if(depthindex == 4) depthindex--;
+ depthindex--;
+
+ switch(mode->HDisplay) {
+ case 640:
+ if(mode->VDisplay == 480) {
+ return(t640x480[depthindex][index];
+ } else return(0);
+ case 800:
+ if(mode->VDisplay == 600) {
+ return(t800x600[depthindex][index];
+ } else return(0);
+ case 1024:
+ if(mode->VDisplay == 768) {
+ return(t1024x768[depthindex][index];
+ } else return(0);
+ case 1280:
+ if(mode->VDisplay == 1024) {
+ return(t1280x1024[depthindex][index];
+ } else return(0);
+ case 1600:
+ if(mode->VDisplay == 1200) {
+ return(t1600x1200[depthindex][index];
+ } else return(0);
+ default: return(0);
+ }
+}
+#endif
+
+/* TW: Stub */
+static void
+SiSThreshold(ScrnInfoPtr pScrn, DisplayModePtr mode,
+ unsigned short *Low, unsigned short *High)
+{
+ return;
+}
+
+
+/* Auxiliary function to find real memory clock (in Khz) */
+/* TW: Not for 530/620 if UMA (on these, the mclk is stored in SR10) */
+int
+SiSMclk(SISPtr pSiS)
+{
+ int mclk;
+ unsigned char Num, Denum, Base;
+
+ switch (pSiS->Chipset) {
+ case PCI_CHIP_SIS5597:
+ case PCI_CHIP_SIS6326:
+ case PCI_CHIP_SIS530:
+ /* Numerator */
+ inSISIDXREG(SISSR, MemClock0, Num);
+ mclk = 14318 * ((Num & 0x7f) + 1);
+
+ /* Denumerator */
+ inSISIDXREG(SISSR, MemClock1, Denum);
+ mclk = mclk / ((Denum & 0x1f) + 1);
+
+ /* Divider. Doesn't seem to work for mclk in older cards */
+ if((Num & 0x80) != 0) mclk *= 2;
+
+ /* Post-scaler. Values' meaning depends on SR13 bit 7 */
+ inSISIDXREG(SISSR, ClockBase, Base);
+ if((Base & 0x80) == 0) {
+ mclk = mclk / (((Denum & 0x60) >> 5) + 1);
+ } else {
+ /* Values 00 and 01 are reserved */
+ if ((Denum & 0x60) == 0x40) mclk /= 6;
+ if ((Denum & 0x60) == 0x60) mclk /= 8;
+ }
+ break;
+ case PCI_CHIP_SIS300:
+ case PCI_CHIP_SIS540:
+ case PCI_CHIP_SIS630:
+ case PCI_CHIP_SIS550:
+ case PCI_CHIP_SIS650:
+ case PCI_CHIP_SIS315:
+ case PCI_CHIP_SIS315H:
+ case PCI_CHIP_SIS315PRO:
+ case PCI_CHIP_SIS330:
+ /* Numerator */
+ inSISIDXREG(SISSR, 0x28, Num);
+ mclk = 14318 * ((Num & 0x7f) + 1);
+
+ /* Denumerator */
+ inSISIDXREG(SISSR, 0x29, Denum);
+ mclk = mclk / ((Denum & 0x1f) + 1);
+
+ /* Divider */
+ if((Num & 0x80) != 0) mclk *= 2;
+
+ /* Post-Scaler */
+ if((Denum & 0x80) == 0) {
+ mclk = mclk / (((Denum & 0x60) >> 5) + 1);
+ } else {
+ mclk = mclk / ((((Denum & 0x60) >> 5) + 1) * 2);
+ }
+ break;
+ default:
+ xf86DrvMsg(pSiS->pScrn->scrnIndex, X_ERROR,
+ "Internal error: SiSMClk() called with invalid chipset (0x%x)\n",
+ pSiS->Chipset);
+ mclk = 0;
+ }
+
+ return(mclk);
+}
+
+/* TW: This estimates the CRT2 clock we are going to use.
+ * The total bandwidth is to be reduced by the value
+ * returned here in order to get an idea of the maximum
+ * dotclock left for CRT1.
+ * Since we don't know yet, what mode the user chose,
+ * we return the maximum dotclock used by
+ * - either the LCD attached, or
+ * - TV
+ * For VGA2, we share the bandwith equally.
+ */
+static int
+SiSEstimateCRT2Clock(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+
+ if(pSiS->VBFlags & CRT2_LCD) {
+ if(pSiS->VBLCDFlags & (VB_LCD_320x480 | VB_LCD_800x600 | VB_LCD_640x480))
+ return 40000;
+ else if(pSiS->VBLCDFlags & (VB_LCD_1024x768 | VB_LCD_1024x600))
+ return 65000;
+ else if(pSiS->VBLCDFlags & (VB_LCD_1152x768 | VB_LCD_1280x1024 | VB_LCD_1280x960))
+ return 108000;
+ else if(pSiS->VBLCDFlags & VB_LCD_1400x1050)
+ return 122000;
+ else if(pSiS->VBLCDFlags & VB_LCD_1600x1200)
+ return 162000;
+ else
+ return 108000;
+ } else if(pSiS->VBFlags & CRT2_TV) {
+ if(pSiS->VBFlags & VB_CHRONTEL) {
+ switch(pSiS->VGAEngine) {
+ case SIS_300_VGA:
+ return 50000;
+ case SIS_315_VGA:
+ default:
+ return 70000;
+ }
+ } else if(pSiS->VBFlags & VB_SISBRIDGE) {
+ return 70000;
+ }
+ }
+
+ return 0;
+}
+
+/* Calculate the maximum dotclock */
+int SiSMemBandWidth(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+#ifdef SISDUALHEAD
+ SISEntPtr pSiSEnt = pSiS->entityPrivate;
+#endif
+
+ int bus = pSiS->BusWidth;
+ int mclk = pSiS->MemClock;
+ int bpp = pSiS->CurrentLayout.bitsPerPixel;
+ int bytesperpixel = (bpp + 7) / 8;
+ float magic=0.0, total, crt2used;
+ int crt2clock, max=0;
+ const float magic300[4] = { 1.2, 1.368421, 2.263158, 1.2};
+ const float magic630[4] = { 1.441177, 1.441177, 2.588235, 1.441177 };
+ const float magic315[4] = { 1.2, 1.368421, 1.368421, 1.2 };
+ const float magic550[4] = { 1.441177, 1.441177, 2.588235, 1.441177 };
+
+ switch (pSiS->Chipset) {
+
+ case PCI_CHIP_SIS5597:
+ total = ((mclk * (bus / 8)) * 0.7) / bytesperpixel;
+ if(total > 135000) total = 135000;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Maximum pixel clock at %d bpp is %g MHz\n",
+ bpp, total/1000);
+ return(int)(total);
+
+ case PCI_CHIP_SIS6326:
+ total = ((mclk * (bus / 8)) * 0.7) / bytesperpixel;
+ if(total > 175500) total = 175500;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Maximum pixel clock at %d bpp is %g MHz\n",
+ bpp, total/1000);
+ return(int)(total);
+
+ case PCI_CHIP_SIS530:
+ total = ((mclk * (bus / 8)) * 0.7) / bytesperpixel;
+ if(total > 230000) total = 230000;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Maximum pixel clock at %d bpp is %g MHz\n",
+ bpp, total/1000);
+ return(int)(total);
+
+ case PCI_CHIP_SIS300:
+ case PCI_CHIP_SIS540:
+ case PCI_CHIP_SIS630:
+ case PCI_CHIP_SIS315:
+ case PCI_CHIP_SIS315H:
+ case PCI_CHIP_SIS315PRO:
+ case PCI_CHIP_SIS550:
+ case PCI_CHIP_SIS650:
+ case PCI_CHIP_SIS330:
+ switch(pSiS->Chipset) {
+ case PCI_CHIP_SIS300:
+ magic = magic300[bus/64];
+ max = 540000;
+ break;
+ case PCI_CHIP_SIS540:
+ case PCI_CHIP_SIS630:
+ magic = magic630[bus/64];
+ max = 540000;
+ break;
+ case PCI_CHIP_SIS315:
+ case PCI_CHIP_SIS315H:
+ case PCI_CHIP_SIS315PRO:
+ case PCI_CHIP_SIS330:
+ magic = magic315[bus/64];
+ max = 780000;
+ break;
+ case PCI_CHIP_SIS550:
+ case PCI_CHIP_SIS650:
+ magic = magic550[bus/64];
+ max = 780000;
+ }
+
+ PDEBUG(ErrorF("mclk: %d, bus: %d, magic: %g, bpp: %d\n",
+ mclk, bus, magic, bpp));
+
+ total = mclk * bus / bpp;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Memory bandwidth at %d bpp is %g MHz\n", bpp, total/1000);
+
+ if(pSiS->VBFlags & CRT2_ENABLE) {
+
+ crt2used = 0.0;
+ crt2clock = SiSEstimateCRT2Clock(pScrn);
+ if(crt2clock) {
+ crt2used = crt2clock + 2000;
+ }
+
+#ifdef SISDUALHEAD
+ if((pSiS->DualHeadMode) && (pSiSEnt)) {
+
+ if(!pSiS->SecondHead) {
+
+ /* TW: First head = CRT2 */
+
+ if(crt2clock) {
+ /* TW: We use the mem bandwidth as max clock; this
+ * might exceed the 70% limit a bit, but that
+ * does not matter; we take care of that limit
+ * when we calc CRT1. Overall, we might use up
+ * to 85% of the memory bandwidth, which seems
+ * enough to use accel and video.
+ * The "* macic" is just to compensate the
+ * calculation below.
+ */
+ total = crt2used * magic;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Bandwidth reserved for CRT2 is %g Mhz\n",
+ crt2used/1000);
+ } else {
+ /* We don't know about the second head's
+ * depth yet. So we assume it uses the
+ * same.
+ */
+ total /= 2;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Bandwidth reserved for CRT2 is %g Mhz\n",
+ total/1000);
+ }
+
+ } else {
+
+ /* TW: Second head = CRT1 */
+
+ /* Now We know about the first head's depth,
+ * so we can calculate more accurately.
+ */
+
+ if(crt2clock) {
+ total -= (crt2used * pSiSEnt->pScrn_1->bitsPerPixel / bpp);
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Bandwidth reserved for CRT2 at %d bpp is %g Mhz\n",
+ bpp,
+ (crt2used * pSiSEnt->pScrn_1->bitsPerPixel / bpp)/1000);
+ } else {
+ total -= (pSiSEnt->maxUsedClock * pSiSEnt->pScrn_1->bitsPerPixel / bpp);
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Bandwidth reserved for CRT2 at %d bpp is %d Mhz\n",
+ bpp,
+ (pSiSEnt->maxUsedClock * pSiSEnt->pScrn_1->bitsPerPixel / bpp)/1000);
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Bandwidth available for CRT1 is %g MHz\n", total/1000);
+
+ }
+
+ } else {
+#endif
+ if(crt2clock) {
+ total -= crt2used;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Bandwidth reserved for CRT2 is %g Mhz\n", crt2used/1000);
+ } else {
+ total /= 2;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Bandwidth reserved for CRT2 is %g Mhz\n", total/1000);
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Bandwidth available for CRT1 is %g MHz\n", total/1000);
+#ifdef SISDUALHEAD
+ }
+#endif
+
+ }
+ total /= magic;
+ if(total > (max / 2)) total = max / 2;
+ return (int)(total);
+
+ default:
+ return 135000; /* guessed */
+ }
+}
+
+/* TW: Load the palette. We do this for all supported color depths
+ * in order to support gamma correction. We hereby convert the
+ * given colormap to a complete 24bit color palette and enable
+ * the correspoding bit in SR7 to enable the 24bit lookup table.
+ * Gamma correction is only supported on CRT1.
+ * Why are there 6-bit-RGB values submitted even if bpp is 16 and
+ * weight is 565? (Maybe because rgbBits is 6?)
+ */
+void
+SISLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors,
+ VisualPtr pVisual)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int i, j, index;
+
+ PDEBUG(ErrorF("SiSLoadPalette(%d)\n", numColors));
+
+#ifdef SISDUALHEAD
+ /* TW: No palette changes on CRT2 if in dual head mode */
+ if((pSiS->DualHeadMode) && (!pSiS->SecondHead)) return;
+#endif
+
+ switch(pSiS->CurrentLayout.depth) {
+#ifdef SISGAMMA
+ case 15:
+ orSISIDXREG(SISSR, 0x07, 0x04);
+ for(i=0; i<numColors; i++) {
+ index = indices[i];
+ if(index < 32) { /* Paranoia */
+ for(j=0; j<8; j++) {
+ outSISREG(SISCOLIDX, (index * 8) + j);
+ outSISREG(SISCOLDATA, colors[index].red << (8- pScrn->rgbBits));
+ outSISREG(SISCOLDATA, colors[index].green << (8 - pScrn->rgbBits));
+ outSISREG(SISCOLDATA, colors[index].blue << (8 - pScrn->rgbBits));
+ }
+ }
+ }
+ break;
+ case 16:
+ orSISIDXREG(SISSR, 0x07, 0x04);
+ for(i=0; i<numColors; i++) {
+ index = indices[i];
+ if(index < 64) { /* Paranoia */
+ for(j=0; j<4; j++) {
+ outSISREG(SISCOLIDX, (index * 4) + j);
+ outSISREG(SISCOLDATA, colors[index/2].red << (8 - pScrn->rgbBits));
+ outSISREG(SISCOLDATA, colors[index].green << (8 - pScrn->rgbBits));
+ outSISREG(SISCOLDATA, colors[index/2].blue << (8 - pScrn->rgbBits));
+ }
+ }
+ }
+ break;
+ case 24:
+ orSISIDXREG(SISSR, 0x07, 0x04);
+ for(i=0; i<numColors; i++) {
+ index = indices[i];
+ if(index < 256) { /* Paranoia */
+ outSISREG(SISCOLIDX, index);
+ outSISREG(SISCOLDATA, colors[index].red);
+ outSISREG(SISCOLDATA, colors[index].green);
+ outSISREG(SISCOLDATA, colors[index].blue);
+ }
+ }
+ break;
+#endif
+ default:
+ if(pScrn->rgbBits == 8)
+ orSISIDXREG(SISSR, 0x07, 0x04);
+ else
+ andSISIDXREG(SISSR, 0x07, ~0x04);
+ for(i=0; i<numColors; i++) {
+ index = indices[i];
+ outSISREG(SISCOLIDX, index);
+ outSISREG(SISCOLDATA, colors[index].red >> (8 - pScrn->rgbBits));
+ outSISREG(SISCOLDATA, colors[index].green >> (8 - pScrn->rgbBits));
+ outSISREG(SISCOLDATA, colors[index].blue >> (8 - pScrn->rgbBits));
+ }
+ }
+
+ switch(pSiS->VGAEngine) {
+ case SIS_300_VGA:
+ case SIS_315_VGA:
+ if(pSiS->VBFlags & CRT2_ENABLE) {
+ /* TW: Only the SiS bridges support a CRT2 palette */
+ if(pSiS->VBFlags & VB_SISBRIDGE) {
+ (*pSiS->LoadCRT2Palette)(pScrn, numColors, indices,
+ colors, pVisual);
+ }
+ }
+ break;
+ }
+
+}
+
+static void
+SiS301LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
+ LOCO *colors, VisualPtr pVisual)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int i, index;
+
+ PDEBUG(ErrorF("SiS301LoadPalette(%d)\n", numColors));
+
+ for(i=0; i<numColors; i++) {
+ index = indices[i];
+ outSISREG(SISCOL2IDX, index);
+ outSISREG(SISCOL2DATA, colors[index].red);
+ outSISREG(SISCOL2DATA, colors[index].green);
+ outSISREG(SISCOL2DATA, colors[index].blue);
+ }
+}
+
+
+#ifdef DEBUG
+/* TW: Debug function to dump registers */
+void SiSIODump(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int i, max3c4, min3d4, max3d4;
+ unsigned char temp;
+
+ switch (pSiS->Chipset) {
+ case PCI_CHIP_SIS6326:
+ max3c4 = 0x3F;
+ max3d4 = 0x19;
+ min3d4 = 0x26;
+ break;
+ case PCI_CHIP_SIS530:
+ max3c4 = 0x3F;
+ max3d4 = 0x19;
+ min3d4 = 0x26;
+ break;
+ case PCI_CHIP_SIS300:
+ case PCI_CHIP_SIS630:
+ case PCI_CHIP_SIS540:
+ max3c4 = 0x3D;
+ max3d4 = 0x37;
+ min3d4 = 0x30;
+ break;
+ case PCI_CHIP_SIS550:
+ case PCI_CHIP_SIS650:
+ case PCI_CHIP_SIS315:
+ case PCI_CHIP_SIS315H:
+ case PCI_CHIP_SIS315PRO:
+ case PCI_CHIP_SIS330:
+ max3c4 = 0x3D;
+ max3d4 = 0x5f;
+ min3d4 = 0x30;
+ break;
+ default:
+ max3c4 = 0x38;
+ max3d4 = 0x19;
+ min3d4 = 0x26;
+ }
+ /* dump Misc Registers */
+ temp = inb(pSiS->RelIO+0x4c);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Misc Output 3CC=%x\n", temp);
+
+ temp = inb(pSiS->RelIO+0x4a);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Feature Control 3CA=%x\n", temp);
+
+ /* Dump GR */
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "-------------\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Registers 3CE\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "-------------\n");
+ for (i=0; i<=8; i++) {
+ inSISIDXREG(SISGR, i, temp);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[%2x]=%2x\n", i, temp);
+ }
+
+ /* dump SR0 ~ SR4 */
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "-------------\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Registers 3C4\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "-------------\n");
+ for (i=0; i<=4; i++) {
+ inSISIDXREG(SISSR, i, temp);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[%2x]=%2x\n", i, temp);
+ }
+
+ /* dump extended SR */
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+ for (i=5; i<=max3c4; i++) {
+ inSISIDXREG(SISSR, i, temp);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[%2x]=%2x\n", i, temp);
+ }
+
+ /* dump CR0 ~ CR18 */
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "-------------\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Registers 3D4\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "-------------\n");
+ for (i=0; i<=0x18; i++) {
+ inSISIDXREG(SISCR, i, temp);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[%2x]=%2x\n", i, temp);
+ }
+ /* dump extended CR */
+ for (i=min3d4; i<=max3d4; i++) {
+ inSISIDXREG(SISCR, i, temp);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[%2x]=%2x\n", i, temp);
+ }
+}
+#endif
+
+void
+SISDACPreInit(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+
+ switch (pSiS->Chipset) {
+ case PCI_CHIP_SIS550:
+ case PCI_CHIP_SIS650:
+ case PCI_CHIP_SIS315:
+ case PCI_CHIP_SIS315H:
+ case PCI_CHIP_SIS315PRO:
+ case PCI_CHIP_SIS330:
+ pSiS->MaxClock = SiSMemBandWidth(pScrn);
+ pSiS->SiSSave = SiS310Save;
+ pSiS->SiSSave2 = SiS301Save;
+ pSiS->SiSSave3 = SiS301BSave;
+ pSiS->SiSSaveLVDSChrontel = SiSLVDSChrontelSave;
+ pSiS->SiSRestore = SiS310Restore;
+ pSiS->SiSRestore2 = SiS301Restore;
+ pSiS->SiSRestore3 = SiS301BRestore;
+ pSiS->SiSRestoreLVDSChrontel = SiSLVDSChrontelRestore;
+ pSiS->LoadCRT2Palette = SiS301LoadPalette;
+ pSiS->SetThreshold = SiSThreshold;
+ pSiS->i2cInit = NULL; /* SiSI2CInit; */
+ break;
+ case PCI_CHIP_SIS300:
+ case PCI_CHIP_SIS630:
+ case PCI_CHIP_SIS540:
+ pSiS->MaxClock = SiSMemBandWidth(pScrn);
+ pSiS->SiSSave = SiS300Save;
+ pSiS->SiSSave2 = SiS301Save;
+ pSiS->SiSSave3 = SiS301BSave;
+ pSiS->SiSSaveLVDSChrontel = SiSLVDSChrontelSave;
+ pSiS->SiSRestore = SiS300Restore;
+ pSiS->SiSRestore2 = SiS301Restore;
+ pSiS->SiSRestore3 = SiS301BRestore;
+ pSiS->SiSRestoreLVDSChrontel = SiSLVDSChrontelRestore;
+ pSiS->LoadCRT2Palette = SiS301LoadPalette;
+ pSiS->SetThreshold = SiSThreshold;
+ pSiS->i2cInit = NULL; /* SiSI2CInit; */
+ break;
+ case PCI_CHIP_SIS5597:
+ case PCI_CHIP_SIS6326:
+ case PCI_CHIP_SIS530:
+ default:
+ pSiS->MaxClock = SiSMemBandWidth(pScrn);
+ pSiS->SiSRestore = SiSRestore;
+ pSiS->SiSSave = SiSSave;
+ pSiS->SetThreshold = SiSThreshold;
+ pSiS->i2cInit = NULL;
+ break;
+ }
+}
+
+static void
+SetBlock(CARD16 port, CARD8 from, CARD8 to, CARD8 *DataPtr)
+{
+ CARD8 index;
+
+ for (index=from; index <= to; index++, DataPtr++) {
+ outSISIDXREG(port, index, *DataPtr);
+ }
+}
+
+void
+SiS6326SetTVReg(ScrnInfoPtr pScrn, CARD8 index, CARD8 data)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ outSISIDXREG(SISCR, 0xE0, index);
+ outSISIDXREG(SISCR, 0xE1, data);
+#ifdef TWDEBUG
+ xf86DrvMsg(0, X_INFO, "SiS6326: Setting Tv %02x to %02x\n", index, data);
+#endif
+}
+
+unsigned char
+SiS6326GetTVReg(ScrnInfoPtr pScrn, CARD8 index)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ unsigned char data;
+
+ outSISIDXREG(SISCR, 0xE0, index);
+ inSISIDXREG(SISCR, 0xE1, data);
+ return(data);
+}
+
+void
+SiS6326SetXXReg(ScrnInfoPtr pScrn, CARD8 index, CARD8 data)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ outSISIDXREG(SISCR, 0xE2, index);
+ outSISIDXREG(SISCR, 0xE3, data);
+}
+
+unsigned char
+SiS6326GetXXReg(ScrnInfoPtr pScrn, CARD8 index)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ unsigned char data;
+
+ outSISIDXREG(SISCR, 0xE2, index);
+ inSISIDXREG(SISCR, 0xE3, data);
+ return(data);
+}
diff --git a/src/sis_dac.h b/src/sis_dac.h
new file mode 100644
index 0000000..907a990
--- /dev/null
+++ b/src/sis_dac.h
@@ -0,0 +1,53 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dac.h,v 1.7 2003/01/29 15:42:17 eich Exp $ */
+
+int SiS_compute_vclk(int Clock, int *out_n, int *out_dn, int *out_div,
+ int *out_sbit, int *out_scale);
+void SISDACPreInit(ScrnInfoPtr pScrn);
+unsigned int SiSddc1Read(ScrnInfoPtr pScrn);
+void SISLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indicies,
+ LOCO *colors, VisualPtr pVisual);
+void SiSCalcClock(ScrnInfoPtr pScrn, int clock, int max_VLD,
+ unsigned int *vclk);
+
+void SiSIODump(ScrnInfoPtr pScrn);
+int SiSMemBandWidth(ScrnInfoPtr pScrn);
+int SiSMclk(SISPtr pSiS);
+void SiSRestoreBridge(ScrnInfoPtr pScrn, SISRegPtr sisReg);
+
+extern void SiS6326SetTVReg(ScrnInfoPtr pScrn, CARD8 index, CARD8 data);
+extern unsigned char SiS6326GetTVReg(ScrnInfoPtr pScrn, CARD8 index);
+extern void SiS6326SetXXReg(ScrnInfoPtr pScrn, CARD8 index, CARD8 data);
+extern unsigned char SiS6326GetXXReg(ScrnInfoPtr pScrn, CARD8 index);
+
+extern int SiSCalcVRate(DisplayModePtr mode);
+
+/* TW: Functions from init.c & init301.c */
+extern void SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO,USHORT BaseAddr);
+extern void SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO,USHORT BaseAddr);
+extern void SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO,USHORT BaseAddr);
+extern void SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO,USHORT BaseAddr);
+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 USHORT SiS_GetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx);
+extern void SiS_SetCH70xx(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 USHORT SiS_HandleDDC(SiS_Private *SiS_Pr, SISPtr pSiS, USHORT adaptnum,
+ USHORT DDCdatatype, unsigned char *buffer);
+extern void SiS_WhatIsThis(SiS_Private *SiS_Pr, USHORT myvbinfo);
+extern void SiS_DisplayOn(SiS_Private *SiS_Pr);
+extern unsigned char SiS_GetSetModeID(ScrnInfoPtr pScrn, unsigned char id);
+#if 0
+extern void SiS_SetSwitchDDC2(SiS_Private *SiS_Pr);
+extern USHORT SiS_I2C_GetByte(SiS_Private *SiS_Pr);
+extern Bool SiS_I2C_PutByte(SiS_Private *SiS_Pr, USHORT data);
+extern Bool SiS_I2C_Address(SiS_Private *SiS_Pr, USHORT addr);
+extern void SiS_I2C_Stop(SiS_Private *SiS_Pr);
+#endif
+
+
+
+
+
diff --git a/src/sis_dga.c b/src/sis_dga.c
new file mode 100644
index 0000000..d455679
--- /dev/null
+++ b/src/sis_dga.c
@@ -0,0 +1,412 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dga.c,v 1.5 2003/01/29 15:42:17 eich Exp $ */
+/*
+ * Copyright 2000 by Alan Hourihane, Sychdyn, North Wales, UK.
+ * Copyright 2002 by Thomas Winischhofer, Vienna, Austria
+ *
+ * Portions from radeon_dga.c which is
+ * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
+ * VA Linux Systems Inc., Fremont, California.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the providers not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The providers make no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE PROVIDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE PROVIDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ * Thomas Winischhofer <thomas@winischhofer.net>
+ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "xf86Pci.h"
+#include "xf86PciInfo.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "sis.h"
+#include "sis_regs.h"
+#include "dgaproc.h"
+
+static Bool SIS_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **,
+ int *, int *, int *);
+static Bool SIS_SetMode(ScrnInfoPtr, DGAModePtr);
+static void SIS_Sync(ScrnInfoPtr);
+static int SIS_GetViewport(ScrnInfoPtr);
+static void SIS_SetViewport(ScrnInfoPtr, int, int, int);
+static void SIS_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long);
+static void SIS_BlitRect(ScrnInfoPtr, int, int, int, int, int, int);
+static void SIS_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int,
+ unsigned long);
+
+static
+DGAFunctionRec SISDGAFuncs = {
+ SIS_OpenFramebuffer,
+ NULL,
+ SIS_SetMode,
+ SIS_SetViewport,
+ SIS_GetViewport,
+ SIS_Sync,
+ SIS_FillRect,
+ SIS_BlitRect,
+ NULL
+};
+
+static
+DGAFunctionRec SISDGAFuncs3xx = {
+ SIS_OpenFramebuffer,
+ NULL,
+ SIS_SetMode,
+ SIS_SetViewport,
+ SIS_GetViewport,
+ SIS_Sync,
+ SIS_FillRect,
+ SIS_BlitRect,
+ SIS_BlitTransRect
+};
+
+static DGAModePtr
+SISSetupDGAMode(
+ ScrnInfoPtr pScrn,
+ DGAModePtr modes,
+ int *num,
+ int bitsPerPixel,
+ int depth,
+ Bool pixmap,
+ int secondPitch,
+ unsigned long red,
+ unsigned long green,
+ unsigned long blue,
+ short visualClass
+){
+ SISPtr pSiS = SISPTR(pScrn);
+ DGAModePtr newmodes = NULL, currentMode;
+ DisplayModePtr pMode, firstMode;
+ int otherPitch, Bpp = bitsPerPixel >> 3;
+ Bool oneMore;
+
+ pMode = firstMode = pScrn->modes;
+
+ while (pMode) {
+
+ otherPitch = secondPitch ? secondPitch : pMode->HDisplay;
+
+ if(pMode->HDisplay != otherPitch) {
+
+ newmodes = xrealloc(modes, (*num + 2) * sizeof(DGAModeRec));
+ oneMore = TRUE;
+
+ } else {
+
+ newmodes = xrealloc(modes, (*num + 1) * sizeof(DGAModeRec));
+ oneMore = FALSE;
+
+ }
+
+ if(!newmodes) {
+ xfree(modes);
+ return NULL;
+ }
+ modes = newmodes;
+
+SECOND_PASS:
+
+ currentMode = modes + *num;
+ (*num)++;
+
+ currentMode->mode = pMode;
+ currentMode->flags = DGA_CONCURRENT_ACCESS;
+ if(pixmap)
+ currentMode->flags |= DGA_PIXMAP_AVAILABLE;
+ if(!pSiS->NoAccel) {
+ currentMode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT;
+ if((pSiS->VGAEngine == SIS_300_VGA) ||
+ (pSiS->VGAEngine == SIS_315_VGA) ||
+ (pSiS->VGAEngine == SIS_530_VGA)) {
+ currentMode->flags |= DGA_BLIT_RECT_TRANS;
+ }
+ }
+ if (pMode->Flags & V_DBLSCAN)
+ currentMode->flags |= DGA_DOUBLESCAN;
+ if (pMode->Flags & V_INTERLACE)
+ currentMode->flags |= DGA_INTERLACED;
+ currentMode->byteOrder = pScrn->imageByteOrder;
+ currentMode->depth = depth;
+ currentMode->bitsPerPixel = bitsPerPixel;
+ currentMode->red_mask = red;
+ currentMode->green_mask = green;
+ currentMode->blue_mask = blue;
+ currentMode->visualClass = visualClass;
+ currentMode->viewportWidth = pMode->HDisplay;
+ currentMode->viewportHeight = pMode->VDisplay;
+ currentMode->xViewportStep = 1;
+ currentMode->yViewportStep = 1;
+ currentMode->viewportFlags = DGA_FLIP_RETRACE;
+ currentMode->offset = 0;
+ currentMode->address = pSiS->FbBase;
+
+ if(oneMore) {
+
+ /* first one is narrow width */
+ currentMode->bytesPerScanline = (((pMode->HDisplay * Bpp) + 3) & ~3L);
+ currentMode->imageWidth = pMode->HDisplay;
+ currentMode->imageHeight = pMode->VDisplay;
+ currentMode->pixmapWidth = currentMode->imageWidth;
+ currentMode->pixmapHeight = currentMode->imageHeight;
+ currentMode->maxViewportX = currentMode->imageWidth -
+ currentMode->viewportWidth;
+ /* this might need to get clamped to some maximum */
+ currentMode->maxViewportY = (currentMode->imageHeight -
+ currentMode->viewportHeight);
+ oneMore = FALSE;
+ goto SECOND_PASS;
+
+ } else {
+
+ currentMode->bytesPerScanline = ((otherPitch * Bpp) + 3) & ~3L;
+ currentMode->imageWidth = otherPitch;
+ currentMode->imageHeight = pMode->VDisplay;
+ currentMode->pixmapWidth = currentMode->imageWidth;
+ currentMode->pixmapHeight = currentMode->imageHeight;
+ currentMode->maxViewportX = (currentMode->imageWidth -
+ currentMode->viewportWidth);
+ /* this might need to get clamped to some maximum */
+ currentMode->maxViewportY = (currentMode->imageHeight -
+ currentMode->viewportHeight);
+ }
+
+ pMode = pMode->next;
+ if (pMode == firstMode)
+ break;
+ }
+
+ return modes;
+}
+
+
+Bool
+SISDGAInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ SISPtr pSiS = SISPTR(pScrn);
+ DGAModePtr modes = NULL;
+ int num = 0;
+
+ /* 8 */
+#ifdef SISDUALHEAD
+ /* TW: We don't ever use 8bpp modes in dual head mode,
+ so don't offer them to DGA either
+ */
+ if(!pSiS->DualHeadMode) {
+#endif
+ modes = SISSetupDGAMode(pScrn, modes, &num, 8, 8,
+ (pScrn->bitsPerPixel == 8),
+ ((pScrn->bitsPerPixel != 8)
+ ? 0 : pScrn->displayWidth),
+ 0, 0, 0, PseudoColor);
+#ifdef SISDUALHEAD
+ }
+#endif
+
+ /* 16 */
+ modes = SISSetupDGAMode(pScrn, modes, &num, 16, 16,
+ (pScrn->bitsPerPixel == 16),
+ ((pScrn->depth != 16)
+ ? 0 : pScrn->displayWidth),
+ 0xf800, 0x07e0, 0x001f, TrueColor);
+
+ if((pSiS->VGAEngine == SIS_530_VGA) || (pSiS->VGAEngine == SIS_OLD_VGA)) {
+ /* 24 */
+ modes = SISSetupDGAMode(pScrn, modes, &num, 24, 24,
+ (pScrn->bitsPerPixel == 24),
+ ((pScrn->bitsPerPixel != 24)
+ ? 0 : pScrn->displayWidth),
+ 0xff0000, 0x00ff00, 0x0000ff, TrueColor);
+ }
+
+ if(pSiS->VGAEngine != SIS_OLD_VGA) {
+ /* 32 */
+ modes = SISSetupDGAMode(pScrn, modes, &num, 32, 24,
+ (pScrn->bitsPerPixel == 32),
+ ((pScrn->bitsPerPixel != 32)
+ ? 0 : pScrn->displayWidth),
+ 0xff0000, 0x00ff00, 0x0000ff, TrueColor);
+ }
+
+ pSiS->numDGAModes = num;
+ pSiS->DGAModes = modes;
+
+ if((pSiS->VGAEngine == SIS_300_VGA) ||
+ (pSiS->VGAEngine == SIS_315_VGA) ||
+ (pSiS->VGAEngine == SIS_530_VGA)) {
+ return DGAInit(pScreen, &SISDGAFuncs3xx, modes, num);
+ } else {
+ return DGAInit(pScreen, &SISDGAFuncs, modes, num);
+ }
+}
+
+
+static Bool
+SIS_SetMode(
+ ScrnInfoPtr pScrn,
+ DGAModePtr pMode
+){
+ static SISFBLayout BackupLayouts[MAXSCREENS];
+ int index = pScrn->pScreen->myNum;
+ SISPtr pSiS = SISPTR(pScrn);
+
+ if(!pMode) { /* restore the original mode */
+
+ if(pSiS->DGAactive) {
+ /* put the ScreenParameters back */
+ memcpy(&pSiS->CurrentLayout, &BackupLayouts[index], sizeof(SISFBLayout));
+ }
+
+ pScrn->currentMode = pSiS->CurrentLayout.mode;
+
+ (*pScrn->SwitchMode)(index, pScrn->currentMode, 0);
+ (*pScrn->AdjustFrame)(index, pScrn->frameX0, pScrn->frameY0, 0);
+ pSiS->DGAactive = FALSE;
+
+ } else { /* set new mode */
+
+ if(!pSiS->DGAactive) {
+ /* save the old parameters */
+ memcpy(&BackupLayouts[index], &pSiS->CurrentLayout, sizeof(SISFBLayout));
+ pSiS->DGAactive = TRUE;
+ }
+
+ pSiS->CurrentLayout.bitsPerPixel = pMode->bitsPerPixel;
+ pSiS->CurrentLayout.depth = pMode->depth;
+ pSiS->CurrentLayout.displayWidth = pMode->bytesPerScanline / (pMode->bitsPerPixel >> 3);
+
+ (*pScrn->SwitchMode)(index, pMode->mode, 0);
+ /* TW: Adjust viewport to 0/0 after mode switch */
+ /* This should fix the vmware-in-dualhead problems */
+ (*pScrn->AdjustFrame)(index, 0, 0, 0);
+ }
+
+ return TRUE;
+}
+
+static int
+SIS_GetViewport(
+ ScrnInfoPtr pScrn
+){
+ SISPtr pSiS = SISPTR(pScrn);
+
+ return pSiS->DGAViewportStatus;
+}
+
+static void
+SIS_SetViewport(
+ ScrnInfoPtr pScrn,
+ int x, int y,
+ int flags
+){
+ SISPtr pSiS = SISPTR(pScrn);
+
+ (*pScrn->AdjustFrame)(pScrn->pScreen->myNum, x, y, flags);
+ pSiS->DGAViewportStatus = 0; /* There are never pending Adjusts */
+}
+
+static void
+SIS_FillRect (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned long color
+){
+ SISPtr pSiS = SISPTR(pScrn);
+
+ if(pSiS->AccelInfoPtr) {
+ (*pSiS->AccelInfoPtr->SetupForSolidFill)(pScrn, color, GXcopy, ~0);
+ (*pSiS->AccelInfoPtr->SubsequentSolidFillRect)(pScrn, x, y, w, h);
+ SET_SYNC_FLAG(pSiS->AccelInfoPtr);
+ }
+}
+
+static void
+SIS_Sync(
+ ScrnInfoPtr pScrn
+){
+ SISPtr pSiS = SISPTR(pScrn);
+
+ if(pSiS->AccelInfoPtr) {
+ (*pSiS->AccelInfoPtr->Sync)(pScrn);
+ }
+}
+
+static void
+SIS_BlitRect(
+ ScrnInfoPtr pScrn,
+ int srcx, int srcy,
+ int w, int h,
+ int dstx, int dsty
+){
+ SISPtr pSiS = SISPTR(pScrn);
+
+ if(pSiS->AccelInfoPtr) {
+ int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1;
+ int ydir = (srcy < dsty) ? -1 : 1;
+
+ (*pSiS->AccelInfoPtr->SetupForScreenToScreenCopy)(
+ pScrn, xdir, ydir, GXcopy, (CARD32)~0, -1);
+ (*pSiS->AccelInfoPtr->SubsequentScreenToScreenCopy)(
+ pScrn, srcx, srcy, dstx, dsty, w, h);
+ SET_SYNC_FLAG(pSiS->AccelInfoPtr);
+ }
+}
+
+static void
+SIS_BlitTransRect(
+ ScrnInfoPtr pScrn,
+ int srcx, int srcy,
+ int w, int h,
+ int dstx, int dsty,
+ unsigned long color
+){
+ SISPtr pSiS = SISPTR(pScrn);
+
+ if(pSiS->AccelInfoPtr) {
+ int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1;
+ int ydir = (srcy < dsty) ? -1 : 1;
+
+ (*pSiS->AccelInfoPtr->SetupForScreenToScreenCopy)(
+ pScrn, xdir, ydir, GXcopy, ~0, color);
+ (*pSiS->AccelInfoPtr->SubsequentScreenToScreenCopy)(
+ pScrn, srcx, srcy, dstx, dsty, w, h);
+ SET_SYNC_FLAG(pSiS->AccelInfoPtr);
+ }
+}
+
+static Bool
+SIS_OpenFramebuffer(
+ ScrnInfoPtr pScrn,
+ char **name,
+ unsigned char **mem,
+ int *size,
+ int *offset,
+ int *flags
+){
+ SISPtr pSiS = SISPTR(pScrn);
+
+ *name = NULL; /* no special device */
+ *mem = (unsigned char*)pSiS->FbAddress;
+ *size = pSiS->maxxfbmem;
+ *offset = 0;
+ *flags = DGA_NEED_ROOT;
+
+ return TRUE;
+}
diff --git a/src/sis_dri.c b/src/sis_dri.c
new file mode 100644
index 0000000..5eb43f5
--- /dev/null
+++ b/src/sis_dri.c
@@ -0,0 +1,616 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dri.c,v 1.25 2003/01/29 15:42:17 eich Exp $ */
+
+/*
+ * DRI wrapper for 300, 540, 630, 730
+ * (310/325 series experimental and incomplete)
+ *
+ * taken and modified from tdfx_dri.c, mga_dri.c
+ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "xf86Priv.h"
+
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+#include "fb.h"
+
+#include "GL/glxtokens.h"
+
+#include "sis.h"
+#include "sis_dri.h"
+#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,99,0,0)
+#include "xf86drmCompat.h"
+#endif
+
+/* TW: Idle function for 300 series */
+#define BR(x) (0x8200 | (x) << 2)
+#define SiSIdle \
+ while((MMIO_IN16(pSiS->IOBase, BR(16)+2) & 0xE000) != 0xE000){}; \
+ while((MMIO_IN16(pSiS->IOBase, BR(16)+2) & 0xE000) != 0xE000){}; \
+ MMIO_IN16(pSiS->IOBase, 0x8240);
+
+/* TW: Idle function for 310/325 series */
+#define Q_STATUS 0x85CC
+#define SiS310Idle \
+ { \
+ while( (MMIO_IN16(pSiS->IOBase, Q_STATUS+2) & 0x8000) != 0x8000){}; \
+ while( (MMIO_IN16(pSiS->IOBase, Q_STATUS+2) & 0x8000) != 0x8000){}; \
+ while( (MMIO_IN16(pSiS->IOBase, Q_STATUS+2) & 0x8000) != 0x8000){}; \
+ MMIO_IN16(pSiS->IOBase, Q_STATUS); \
+ }
+
+
+extern void GlxSetVisualConfigs(
+ int nconfigs,
+ __GLXvisualConfig *configs,
+ void **configprivs
+);
+
+#define AGP_PAGE_SIZE 4096
+#define AGP_PAGES 2048
+#define AGP_SIZE (AGP_PAGE_SIZE * AGP_PAGES)
+#define AGP_CMDBUF_PAGES 256
+#define AGP_CMDBUF_SIZE (AGP_PAGE_SIZE * AGP_CMDBUF_PAGES)
+
+static char SISKernelDriverName[] = "sis";
+static char SISClientDriverName[] = "sis";
+
+static Bool SISInitVisualConfigs(ScreenPtr pScreen);
+static Bool SISCreateContext(ScreenPtr pScreen, VisualPtr visual,
+ drmContext hwContext, void *pVisualConfigPriv,
+ DRIContextType contextStore);
+static void SISDestroyContext(ScreenPtr pScreen, drmContext hwContext,
+ DRIContextType contextStore);
+static void SISDRISwapContext(ScreenPtr pScreen, DRISyncType syncType,
+ DRIContextType readContextType,
+ void *readContextStore,
+ DRIContextType writeContextType,
+ void *writeContextStore);
+static void SISDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index);
+static void SISDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc, CARD32 index);
+
+#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,99,0,0)
+extern Bool drmSiSAgpInit(int driSubFD, int offset, int size);
+#endif
+
+static Bool
+SISInitVisualConfigs(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ SISPtr pSIS = SISPTR(pScrn);
+ int numConfigs = 0;
+ __GLXvisualConfig *pConfigs = 0;
+ SISConfigPrivPtr pSISConfigs = 0;
+ SISConfigPrivPtr *pSISConfigPtrs = 0;
+ int i, db, z_stencil, accum;
+ Bool useZ16 = FALSE;
+
+ if(getenv("SIS_FORCE_Z16")){
+ useZ16 = TRUE;
+ }
+
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ case 24:
+ break;
+ case 16:
+ case 32:
+ numConfigs = (useZ16)?8:16;
+
+ if (!(pConfigs = (__GLXvisualConfig*)xcalloc(sizeof(__GLXvisualConfig),
+ numConfigs))) {
+ return FALSE;
+ }
+ if (!(pSISConfigs = (SISConfigPrivPtr)xcalloc(sizeof(SISConfigPrivRec),
+ numConfigs))) {
+ xfree(pConfigs);
+ return FALSE;
+ }
+ if (!(pSISConfigPtrs = (SISConfigPrivPtr*)xcalloc(sizeof(SISConfigPrivPtr),
+ numConfigs))) {
+ xfree(pConfigs);
+ xfree(pSISConfigs);
+ return FALSE;
+ }
+ for (i=0; i<numConfigs; i++)
+ pSISConfigPtrs[i] = &pSISConfigs[i];
+
+ i = 0;
+ for (accum = 0; accum <= 1; accum++) {
+ for (z_stencil=0; z_stencil<(useZ16?2:4); z_stencil++) {
+ for (db = 0; db <= 1; db++) {
+ pConfigs[i].vid = -1;
+ pConfigs[i].class = -1;
+ pConfigs[i].rgba = TRUE;
+ pConfigs[i].redSize = -1;
+ pConfigs[i].greenSize = -1;
+ pConfigs[i].blueSize = -1;
+ pConfigs[i].redMask = -1;
+ pConfigs[i].greenMask = -1;
+ pConfigs[i].blueMask = -1;
+ pConfigs[i].alphaMask = 0;
+ if (accum) {
+ pConfigs[i].accumRedSize = 16;
+ pConfigs[i].accumGreenSize = 16;
+ pConfigs[i].accumBlueSize = 16;
+ pConfigs[i].accumAlphaSize = 16;
+ } else {
+ pConfigs[i].accumRedSize = 0;
+ pConfigs[i].accumGreenSize = 0;
+ pConfigs[i].accumBlueSize = 0;
+ pConfigs[i].accumAlphaSize = 0;
+ }
+ if (db)
+ pConfigs[i].doubleBuffer = TRUE;
+ else
+ pConfigs[i].doubleBuffer = FALSE;
+ pConfigs[i].stereo = FALSE;
+ pConfigs[i].bufferSize = -1;
+ switch (z_stencil){
+ case 0:
+ pConfigs[i].depthSize = 0;
+ pConfigs[i].stencilSize = 0;
+ break;
+ case 1:
+ pConfigs[i].depthSize = 16;
+ pConfigs[i].stencilSize = 0;
+ break;
+ case 2:
+ pConfigs[i].depthSize = 32;
+ pConfigs[i].stencilSize = 0;
+ break;
+ case 3:
+ pConfigs[i].depthSize = 24;
+ pConfigs[i].stencilSize = 8;
+ break;
+ }
+ pConfigs[i].auxBuffers = 0;
+ pConfigs[i].level = 0;
+ pConfigs[i].visualRating = GLX_NONE_EXT;
+ pConfigs[i].transparentPixel = 0;
+ pConfigs[i].transparentRed = 0;
+ pConfigs[i].transparentGreen = 0;
+ pConfigs[i].transparentBlue = 0;
+ pConfigs[i].transparentAlpha = 0;
+ pConfigs[i].transparentIndex = 0;
+ i++;
+ }
+ }
+ }
+ if (i != numConfigs) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[dri] Incorrect initialization of visuals. Disabling DRI.\n");
+ return FALSE;
+ }
+ break;
+ }
+
+ pSIS->numVisualConfigs = numConfigs;
+ pSIS->pVisualConfigs = pConfigs;
+ pSIS->pVisualConfigsPriv = pSISConfigs;
+ GlxSetVisualConfigs(numConfigs, pConfigs, (void**)pSISConfigPtrs);
+
+ return TRUE;
+}
+
+Bool SISDRIScreenInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ SISPtr pSIS = SISPTR(pScrn);
+ DRIInfoPtr pDRIInfo;
+ SISDRIPtr pSISDRI;
+#if 000
+ drmVersionPtr version;
+#endif
+
+ /* Check that the GLX, DRI, and DRM modules have been loaded by testing
+ * for canonical symbols in each module. */
+ if (!xf86LoaderCheckSymbol("GlxSetVisualConfigs")) return FALSE;
+ if (!xf86LoaderCheckSymbol("DRIScreenInit")) return FALSE;
+ if (!xf86LoaderCheckSymbol("drmAvailable")) return FALSE;
+ if (!xf86LoaderCheckSymbol("DRIQueryVersion")) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[dri] SISDRIScreenInit failed (libdri.a too old)\n");
+ return FALSE;
+ }
+
+ /* Check the DRI version */
+ {
+ int major, minor, patch;
+ DRIQueryVersion(&major, &minor, &patch);
+ if (major != 4 || minor < 0) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[dri] SISDRIScreenInit failed because of a version mismatch.\n"
+ "[dri] libDRI version is %d.%d.%d but version 4.0.x is needed.\n"
+ "[dri] Disabling DRI.\n",
+ major, minor, patch);
+ return FALSE;
+ }
+ }
+
+ pDRIInfo = DRICreateInfoRec();
+ if (!pDRIInfo) return FALSE;
+ pSIS->pDRIInfo = pDRIInfo;
+
+ pDRIInfo->drmDriverName = SISKernelDriverName;
+ pDRIInfo->clientDriverName = SISClientDriverName;
+ pDRIInfo->busIdString = xalloc(64);
+ sprintf(pDRIInfo->busIdString, "PCI:%d:%d:%d",
+ ((pciConfigPtr)pSIS->PciInfo->thisCard)->busnum,
+ ((pciConfigPtr)pSIS->PciInfo->thisCard)->devnum,
+ ((pciConfigPtr)pSIS->PciInfo->thisCard)->funcnum);
+ pDRIInfo->ddxDriverMajorVersion = 0;
+ pDRIInfo->ddxDriverMinorVersion = 1;
+ pDRIInfo->ddxDriverPatchVersion = 0;
+
+ pDRIInfo->frameBufferPhysicalAddress = pSIS->FbAddress;
+
+ /* TW: This was FbMapSize which is wrong as we must not
+ * ever overwrite HWCursor and TQ area. On the other
+ * hand, using availMem here causes MTRR allocation
+ * to fail ("base is not aligned to size"). Since
+ * DRI memory management is done via framebuffer
+ * device, I assume that the size given here
+ * is NOT used for eventual memory management.
+ */
+ pDRIInfo->frameBufferSize = pSIS->FbMapSize; /* availMem; */
+
+ /* TW: scrnOffset is being calulated in sis_vga.c */
+ pDRIInfo->frameBufferStride = pSIS->scrnOffset;
+
+ pDRIInfo->ddxDrawableTableEntry = SIS_MAX_DRAWABLES;
+
+ if (SAREA_MAX_DRAWABLES < SIS_MAX_DRAWABLES)
+ pDRIInfo->maxDrawableTableEntry = SAREA_MAX_DRAWABLES;
+ else
+ pDRIInfo->maxDrawableTableEntry = SIS_MAX_DRAWABLES;
+
+#ifdef NOT_DONE
+ /* FIXME need to extend DRI protocol to pass this size back to client
+ * for SAREA mapping that includes a device private record
+ */
+ pDRIInfo->SAREASize =
+ ((sizeof(XF86DRISAREARec) + getpagesize() - 1) & getpagesize()); /* round to page */
+ /* ((sizeof(XF86DRISAREARec) + 0xfff) & 0x1000); */ /* round to page */
+ /* + shared memory device private rec */
+#else
+ /* For now the mapping works by using a fixed size defined
+ * in the SAREA header
+ */
+ if (sizeof(XF86DRISAREARec)+sizeof(SISSAREAPriv) > SAREA_MAX) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Data does not fit in SAREA\n");
+ return FALSE;
+ }
+ pDRIInfo->SAREASize = SAREA_MAX;
+#endif
+
+ if (!(pSISDRI = (SISDRIPtr)xcalloc(sizeof(SISDRIRec),1))) {
+ DRIDestroyInfoRec(pSIS->pDRIInfo);
+ pSIS->pDRIInfo=0;
+ return FALSE;
+ }
+ pDRIInfo->devPrivate = pSISDRI;
+ pDRIInfo->devPrivateSize = sizeof(SISDRIRec);
+ pDRIInfo->contextSize = sizeof(SISDRIContextRec);
+
+ pDRIInfo->CreateContext = SISCreateContext;
+ pDRIInfo->DestroyContext = SISDestroyContext;
+ pDRIInfo->SwapContext = SISDRISwapContext;
+ pDRIInfo->InitBuffers = SISDRIInitBuffers;
+ pDRIInfo->MoveBuffers = SISDRIMoveBuffers;
+ pDRIInfo->bufferRequests = DRI_ALL_WINDOWS;
+
+ if (!DRIScreenInit(pScreen, pDRIInfo, &pSIS->drmSubFD)) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[dri] DRIScreenInit failed. Disabling DRI.\n");
+ xfree(pDRIInfo->devPrivate);
+ pDRIInfo->devPrivate=0;
+ DRIDestroyInfoRec(pSIS->pDRIInfo);
+ pSIS->pDRIInfo=0;
+ pSIS->drmSubFD = -1;
+ return FALSE;
+ }
+
+#if 000
+ /* XXX Check DRM kernel version here */
+ version = drmGetVersion(info->drmFD);
+ if (version) {
+ if (version->version_major != 1 ||
+ version->version_minor < 0) {
+ /* incompatible drm version */
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[dri] SISDRIScreenInit failed because of a version mismatch.\n"
+ "[dri] sis.o kernel module version is %d.%d.%d but version 1.0.x is needed.\n"
+ "[dri] Disabling the DRI.\n",
+ version->version_major,
+ version->version_minor,
+ version->version_patchlevel);
+ drmFreeVersion(version);
+ R128DRICloseScreen(pScreen);
+ return FALSE;
+ }
+ drmFreeVersion(version);
+ }
+#endif
+
+ pSISDRI->regs.size = SISIOMAPSIZE;
+ pSISDRI->regs.map = 0;
+ if (drmAddMap(pSIS->drmSubFD, (drmHandle)pSIS->IOAddress,
+ pSISDRI->regs.size, DRM_REGISTERS, 0,
+ &pSISDRI->regs.handle)<0)
+ {
+ SISDRICloseScreen(pScreen);
+ return FALSE;
+ }
+
+ xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Registers = 0x%08lx\n",
+ pSISDRI->regs.handle);
+
+ /* AGP */
+ do{
+ pSIS->agpSize = 0;
+ pSIS->agpCmdBufSize = 0;
+ pSISDRI->AGPCmdBufSize = 0;
+
+ if (drmAgpAcquire(pSIS->drmSubFD) < 0) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAgpAcquire failed\n");
+ break;
+ }
+
+ /* TODO: default value is 2x? */
+ if (drmAgpEnable(pSIS->drmSubFD, drmAgpGetMode(pSIS->drmSubFD)&~0x0) < 0) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAgpEnable failed\n");
+ break;
+ }
+ xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] drmAgpEnabled succeeded\n");
+
+ if (drmAgpAlloc(pSIS->drmSubFD, AGP_SIZE, 0, NULL, &pSIS->agpHandle) < 0) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[drm] drmAgpAlloc failed\n");
+ drmAgpRelease(pSIS->drmSubFD);
+ break;
+ }
+
+ if (drmAgpBind(pSIS->drmSubFD, pSIS->agpHandle, 0) < 0) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[drm] drmAgpBind failed\n");
+ drmAgpFree(pSIS->drmSubFD, pSIS->agpHandle);
+ drmAgpRelease(pSIS->drmSubFD);
+
+ break;
+ }
+
+ pSIS->agpSize = AGP_SIZE;
+ pSIS->agpAddr = drmAgpBase(pSIS->drmSubFD);
+ /* pSIS->agpBase = */
+
+ pSISDRI->agp.size = pSIS->agpSize;
+ if (drmAddMap(pSIS->drmSubFD, (drmHandle)0,
+ pSISDRI->agp.size, DRM_AGP, 0,
+ &pSISDRI->agp.handle) < 0) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[drm] Failed to map public agp area\n");
+ pSISDRI->agp.size = 0;
+ break;
+ }
+
+ pSIS->agpCmdBufSize = AGP_CMDBUF_SIZE;
+ pSIS->agpCmdBufAddr = pSIS->agpAddr;
+ pSIS->agpCmdBufBase = pSIS->agpCmdBufAddr - pSIS->agpAddr +
+ pSIS->agpBase;
+ pSIS->agpCmdBufFree = 0;
+
+ pSISDRI->AGPCmdBufOffset = pSIS->agpCmdBufAddr - pSIS->agpAddr;
+ pSISDRI->AGPCmdBufSize = pSIS->agpCmdBufSize;
+
+ drmSiSAgpInit(pSIS->drmSubFD, AGP_CMDBUF_SIZE,(AGP_SIZE - AGP_CMDBUF_SIZE));
+ }
+ while(0);
+
+ /* enable IRQ */
+ pSIS->irq = drmGetInterruptFromBusID(pSIS->drmSubFD,
+ ((pciConfigPtr)pSIS->PciInfo->thisCard)->busnum,
+ ((pciConfigPtr)pSIS->PciInfo->thisCard)->devnum,
+ ((pciConfigPtr)pSIS->PciInfo->thisCard)->funcnum);
+
+ if((drmCtlInstHandler(pSIS->drmSubFD, pSIS->irq)) != 0)
+ {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "[drm] failure adding irq %d handler, stereo disabled\n",
+ pSIS->irq);
+ pSIS->irqEnabled = FALSE;
+ }
+ else
+ {
+ pSIS->irqEnabled = TRUE;
+ }
+
+ pSISDRI->irqEnabled = pSIS->irqEnabled;
+
+ if (!(SISInitVisualConfigs(pScreen))) {
+ SISDRICloseScreen(pScreen);
+ return FALSE;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] visual configs initialized.\n" );
+
+ return TRUE;
+}
+
+void
+SISDRICloseScreen(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ SISPtr pSIS = SISPTR(pScrn);
+
+ DRICloseScreen(pScreen);
+
+ if (pSIS->pDRIInfo) {
+ if (pSIS->pDRIInfo->devPrivate) {
+ xfree(pSIS->pDRIInfo->devPrivate);
+ pSIS->pDRIInfo->devPrivate=0;
+ }
+ DRIDestroyInfoRec(pSIS->pDRIInfo);
+ pSIS->pDRIInfo=0;
+ }
+ if (pSIS->pVisualConfigs) xfree(pSIS->pVisualConfigs);
+ if (pSIS->pVisualConfigsPriv) xfree(pSIS->pVisualConfigsPriv);
+
+ if(pSIS->agpSize){
+ xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Freeing agp memory\n");
+ drmAgpFree(pSIS->drmSubFD, pSIS->agpHandle);
+ xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Releasing agp module\n");
+ drmAgpRelease(pSIS->drmSubFD);
+ }
+}
+
+/* TODO: xserver receives driver's swapping event and do something
+ * according the data initialized in this function
+ */
+static Bool
+SISCreateContext(ScreenPtr pScreen, VisualPtr visual,
+ drmContext hwContext, void *pVisualConfigPriv,
+ DRIContextType contextStore)
+{
+ return TRUE;
+}
+
+static void
+SISDestroyContext(ScreenPtr pScreen, drmContext hwContext,
+ DRIContextType contextStore)
+{
+}
+
+Bool
+SISDRIFinishScreenInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ SISPtr pSiS = SISPTR(pScrn);
+ SISDRIPtr pSISDRI;
+
+ pSiS->pDRIInfo->driverSwapMethod = DRI_HIDE_X_CONTEXT;
+ /* pSiS->pDRIInfo->driverSwapMethod = DRI_SERVER_SWAP; */
+
+ pSISDRI=(SISDRIPtr)pSiS->pDRIInfo->devPrivate;
+ pSISDRI->deviceID=pSiS->Chipset;
+ pSISDRI->width=pScrn->virtualX;
+ pSISDRI->height=pScrn->virtualY;
+ pSISDRI->mem=pScrn->videoRam*1024;
+ pSISDRI->bytesPerPixel= (pScrn->bitsPerPixel+7) / 8;
+ /* TODO */
+ pSISDRI->scrnX=pSISDRI->width;
+ pSISDRI->scrnY=pSISDRI->height;
+
+/*
+ pSISDRI->textureOffset=pSiS->texOffset;
+ pSISDRI->textureSize=pSiS->texSize;
+ pSISDRI->fbOffset=pSiS->fbOffset;
+ pSISDRI->backOffset=pSiS->backOffset;
+ pSISDRI->depthOffset=pSiS->depthOffset;
+*/
+
+ /* set SAREA value */
+ {
+ SISSAREAPriv *saPriv;
+
+ saPriv=(SISSAREAPriv*)DRIGetSAREAPrivate(pScreen);
+
+ assert(saPriv);
+
+ saPriv->CtxOwner = -1;
+ saPriv->QueueLength = 0;
+ pSiS->cmdQueueLenPtr = &(saPriv->QueueLength);
+ saPriv->AGPCmdBufNext = 0;
+
+ /* frame control */
+ saPriv->FrameCount = 0;
+ if (pSiS->VGAEngine == SIS_315_VGA) { /* 310/325 series */
+#if 0
+ *(unsigned long *)(pSiS->IOBase+0x8a2c) = 0; /* FIXME: Where is this on the 310 series ? */
+#endif
+ SiS310Idle
+ } else { /* 300 series (and below) */
+ *(unsigned long *)(pSiS->IOBase+0x8a2c) = 0;
+ SiSIdle
+ }
+ }
+
+ return DRIFinishScreenInit(pScreen);
+}
+
+static void
+SISDRISwapContext(ScreenPtr pScreen, DRISyncType syncType,
+ DRIContextType oldContextType, void *oldContext,
+ DRIContextType newContextType, void *newContext)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ SISPtr pSiS = SISPTR(pScrn);
+
+#if 0
+ if ((syncType==DRI_3D_SYNC) && (oldContextType==DRI_2D_CONTEXT) &&
+ (newContextType==DRI_2D_CONTEXT)) { /* Entering from Wakeup */
+ SISSwapContextPrivate(pScreen);
+ }
+ if ((syncType==DRI_2D_SYNC) && (oldContextType==DRI_NO_CONTEXT) &&
+ (newContextType==DRI_2D_CONTEXT)) { /* Exiting from Block Handler */
+ SISLostContext(pScreen);
+ }
+#endif
+
+ /* mEndPrimitive */
+ /*
+ * TODO: do this only if X-Server get lock. If kernel supports delayed
+ * signal, needless to do this
+ */
+ if (pSiS->VGAEngine == SIS_315_VGA) {
+#if 0
+ *(pSiS->IOBase + 0x8B50) = 0xff; /* FIXME: Where is this on 310 series */
+ *(unsigned int *)(pSiS->IOBase + 0x8B60) = -1; /* FIXME: Where is this on 310 series */
+#endif
+ } else {
+ *(pSiS->IOBase + 0x8B50) = 0xff;
+ *(unsigned int *)(pSiS->IOBase + 0x8B60) = -1;
+ }
+}
+
+static void
+SISDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ SISPtr pSiS = SISPTR(pScrn);
+
+ if (pSiS->VGAEngine == SIS_315_VGA) {
+ SiS310Idle /* 310/325 series */
+ } else {
+ SiSIdle /* 300 series */
+ }
+}
+
+static void
+SISDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc, CARD32 index)
+{
+ ScreenPtr pScreen = pParent->drawable.pScreen;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ SISPtr pSiS = SISPTR(pScrn);
+
+ if (pSiS->VGAEngine == SIS_315_VGA) {
+ SiS310Idle /* 310/325 series */
+ } else {
+ SiSIdle /* 300 series and below */
+ }
+}
+
+#if 0
+void SISLostContext(ScreenPtr pScreen)
+{
+}
+
+void SISSwapContextPrivate(ScreenPtr pScreen)
+{
+}
+#endif
diff --git a/src/sis_dri.h b/src/sis_dri.h
new file mode 100644
index 0000000..55714d0
--- /dev/null
+++ b/src/sis_dri.h
@@ -0,0 +1,69 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dri.h,v 1.6 2001/05/16 13:43:17 alanh Exp $ */
+
+/* modified from tdfx_dri.h */
+
+#ifndef _SIS_DRI_
+#define _SIS_DRI_
+
+#include "xf86drm.h"
+
+#define SIS_MAX_DRAWABLES 256
+#define SISIOMAPSIZE (64*1024)
+
+typedef struct {
+ int CtxOwner;
+ int QueueLength;
+ unsigned int AGPCmdBufNext;
+ unsigned int FrameCount;
+} SISSAREAPriv;
+
+#define SIS_FRONT 0
+#define SIS_BACK 1
+#define SIS_DEPTH 2
+
+typedef struct {
+ drmHandle handle;
+ drmSize size;
+ drmAddress map;
+} sisRegion, *sisRegionPtr;
+
+typedef struct {
+ sisRegion regs, agp;
+ int deviceID;
+ int width;
+ int height;
+ int mem;
+ int bytesPerPixel;
+ int priv1;
+ int priv2;
+ int fbOffset;
+ int backOffset;
+ int depthOffset;
+ int textureOffset;
+ int textureSize;
+ unsigned int AGPCmdBufOffset;
+ unsigned int AGPCmdBufSize;
+ int irqEnabled;
+ unsigned int scrnX, scrnY;
+} SISDRIRec, *SISDRIPtr;
+
+typedef struct {
+ /* Nothing here yet */
+ int dummy;
+} SISConfigPrivRec, *SISConfigPrivPtr;
+
+typedef struct {
+ /* Nothing here yet */
+ int dummy;
+} SISDRIContextRec, *SISDRIContextPtr;
+
+#ifdef XFree86Server
+
+#include "screenint.h"
+
+Bool SISDRIScreenInit(ScreenPtr pScreen);
+void SISDRICloseScreen(ScreenPtr pScreen);
+Bool SISDRIFinishScreenInit(ScreenPtr pScreen);
+
+#endif
+#endif
diff --git a/src/sis_driver.c b/src/sis_driver.c
new file mode 100644
index 0000000..eb89fe2
--- /dev/null
+++ b/src/sis_driver.c
@@ -0,0 +1,7648 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_driver.c,v 1.86 2003/02/04 02:44:29 dawes Exp $ */
+/*
+ * Copyright 1998,1999 by Alan Hourihane, Wigan, England.
+ * Parts Copyright 2001, 2002, 2003 by Thomas Winischhofer, Vienna, Austria.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the copyright holder not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The copyright holder makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, alanh@fairlite.demon.co.uk
+ * Mike Chapman <mike@paranoia.com>,
+ * Juanjo Santamarta <santamarta@ctv.es>,
+ * Mitani Hiroshi <hmitani@drl.mei.co.jp>
+ * David Thomas <davtom@dream.org.uk>.
+ *
+ * Thomas Winischhofer <thomas@winischhofer.net>:
+ * - 310/325 series (315/550/650/651/740/M650) support
+ * - (possibly incomplete) Xabre (SiS330) support
+ * - new mode switching code for 300, 310/325 and 330 series
+ * - many fixes for 300/540/630/730 chipsets,
+ * - many fixes for 5597/5598, 6326 and 530/620 chipsets,
+ * - VESA mode switching (deprecated),
+ * - extended CRT2/video bridge handling support,
+ * - dual head support on 300, 310/325 and 330 series
+ * - 650/LVDS (up to 1400x1050), 650/Chrontel 701x support
+ * - 30xB/30xLV/30xLVX video bridge support (300, 310/325, 330 series)
+ * - Xv support for 5597/5598, 6326, 530/620 and 310/325 series
+ * - video overlay enhancements for 300 series
+ * - TV and hi-res support for the 6326
+ * - Color HW cursor support for 300(emulated), 310/325 and 330 series
+ * - etc.
+ */
+
+#include "fb.h"
+#include "xf1bpp.h"
+#include "xf4bpp.h"
+#include "mibank.h"
+#include "micmap.h"
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86Resources.h"
+#include "xf86_ansic.h"
+#include "dixstruct.h"
+#include "xf86Version.h"
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+#include "xf86cmap.h"
+#include "vgaHW.h"
+#include "xf86RAC.h"
+#include "shadowfb.h"
+#include "vbe.h"
+
+#include "sis_shadow.h"
+
+#include "mipointer.h"
+#include "mibstore.h"
+
+#include "sis.h"
+#include "sis_regs.h"
+#include "sis_vb.h"
+#include "sis_dac.h"
+
+#include "sis_driver.h"
+
+#define _XF86DGA_SERVER_
+#include "extensions/xf86dgastr.h"
+
+#include "globals.h"
+#define DPMS_SERVER
+#include "extensions/dpms.h"
+
+#ifdef XvExtension
+#include "xf86xv.h"
+#include "Xv.h"
+#endif
+
+#ifdef XF86DRI
+#include "dri.h"
+#endif
+
+/* Mandatory functions */
+static void SISIdentify(int flags);
+static Bool SISProbe(DriverPtr drv, int flags);
+static Bool SISPreInit(ScrnInfoPtr pScrn, int flags);
+static Bool SISScreenInit(int Index, ScreenPtr pScreen, int argc, char **argv);
+static Bool SISEnterVT(int scrnIndex, int flags);
+static void SISLeaveVT(int scrnIndex, int flags);
+static Bool SISCloseScreen(int scrnIndex, ScreenPtr pScreen);
+static Bool SISSaveScreen(ScreenPtr pScreen, int mode);
+static Bool SISSwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
+static void SISAdjustFrame(int scrnIndex, int x, int y, int flags);
+#ifdef SISDUALHEAD
+static Bool SISSaveScreenDH(ScreenPtr pScreen, int mode);
+#endif
+
+/* Optional functions */
+static void SISFreeScreen(int scrnIndex, int flags);
+static int SISValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose,
+ int flags);
+
+/* Internally used functions */
+static Bool SISMapMem(ScrnInfoPtr pScrn);
+static Bool SISUnmapMem(ScrnInfoPtr pScrn);
+static void SISSave(ScrnInfoPtr pScrn);
+static void SISRestore(ScrnInfoPtr pScrn);
+static void SISVESARestore(ScrnInfoPtr pScrn);
+static Bool SISModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
+static void SISModifyModeInfo(DisplayModePtr mode);
+static void SiSPreSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode);
+static void SiSPostSetMode(ScrnInfoPtr pScrn, SISRegPtr sisReg);
+static void SiS6326PostSetMode(ScrnInfoPtr pScrn, SISRegPtr sisReg);
+static Bool SiSSetVESAMode(ScrnInfoPtr pScrn, DisplayModePtr pMode);
+static void SiSBuildVesaModeList(ScrnInfoPtr pScrn, vbeInfoPtr pVbe, VbeInfoBlock *vbe);
+static UShort SiSCalcVESAModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode);
+static void SISVESASaveRestore(ScrnInfoPtr pScrn, vbeSaveRestoreFunction function);
+static void SISBridgeRestore(ScrnInfoPtr pScrn);
+static void SiSEnableTurboQueue(ScrnInfoPtr pScrn);
+unsigned char SISSearchCRT1Rate(ScrnInfoPtr pScrn, DisplayModePtr mode);
+static void SISWaitVBRetrace(ScrnInfoPtr pScrn);
+
+void SISWaitRetraceCRT1(ScrnInfoPtr pScrn);
+void SISWaitRetraceCRT2(ScrnInfoPtr pScrn);
+
+BOOLEAN SiSBridgeIsInSlaveMode(ScrnInfoPtr pScrn);
+#ifdef CYCLECRT2
+Bool SISCycleCRT2Type(int scrnIndex, DisplayModePtr mode);
+#endif
+
+#ifdef DEBUG
+static void SiSDumpModeInfo(ScrnInfoPtr pScrn, DisplayModePtr mode);
+#endif
+
+/* TW: New mode switching functions */
+extern BOOLEAN SiSBIOSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+ ScrnInfoPtr pScrn, DisplayModePtr mode, BOOLEAN IsCustom);
+extern BOOLEAN SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+ ScrnInfoPtr pScrn,USHORT ModeNo, BOOLEAN dosetpitch);
+extern USHORT SiS_CalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode);
+extern USHORT SiS_CheckCalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode, int VBFlags);
+extern void SiSRegInit(SiS_Private *SiS_Pr, USHORT BaseAddr);
+extern DisplayModePtr SiSBuildBuiltInModeList(ScrnInfoPtr pScrn);
+#ifdef SISDUALHEAD
+extern BOOLEAN SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+ ScrnInfoPtr pScrn, DisplayModePtr mode, BOOLEAN IsCustom);
+extern BOOLEAN SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+ ScrnInfoPtr pScrn, DisplayModePtr mode);
+#endif
+
+/* TW: For power management for 310/325 series */
+extern void SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr);
+extern void SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr);
+extern void SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+extern void SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+
+#ifdef SISDUALHEAD
+static int SISEntityIndex = -1;
+#endif
+
+/*
+ * This is intentionally screen-independent. It indicates the binding
+ * choice made in the first PreInit.
+ */
+static int pix24bpp = 0;
+
+/*
+ * This contains the functions needed by the server after loading the driver
+ * module. It must be supplied, and gets passed back by the SetupProc
+ * function in the dynamic case. In the static case, a reference to this
+ * is compiled in, and this requires that the name of this DriverRec be
+ * an upper-case version of the driver name.
+ */
+
+DriverRec SIS = {
+ SIS_CURRENT_VERSION,
+ SIS_DRIVER_NAME,
+ SISIdentify,
+ SISProbe,
+ SISAvailableOptions,
+ NULL,
+ 0
+};
+
+static SymTabRec SISChipsets[] = {
+ { PCI_CHIP_SIS5597, "SIS5597/5598" },
+ { PCI_CHIP_SIS530, "SIS530/620" },
+ { PCI_CHIP_SIS6326, "SIS6326/AGP/DVD" },
+ { PCI_CHIP_SIS300, "SIS300/305" },
+ { PCI_CHIP_SIS630, "SIS630/730" },
+ { PCI_CHIP_SIS540, "SIS540" },
+ { PCI_CHIP_SIS315, "SIS315" },
+ { PCI_CHIP_SIS315H, "SIS315H" },
+ { PCI_CHIP_SIS315PRO, "SIS315PRO" },
+ { PCI_CHIP_SIS550, "SIS550" },
+ { PCI_CHIP_SIS650, "SIS650/M650/651/740" },
+#ifdef INCL_SIS330 /* TW: New for SiS330 (untested) */
+ { PCI_CHIP_SIS330, "SIS330(Xabre)" },
+#endif
+ { -1, NULL }
+};
+
+static PciChipsets SISPciChipsets[] = {
+ { PCI_CHIP_SIS5597, PCI_CHIP_SIS5597, RES_SHARED_VGA },
+ { PCI_CHIP_SIS530, PCI_CHIP_SIS530, RES_SHARED_VGA },
+ { PCI_CHIP_SIS6326, PCI_CHIP_SIS6326, RES_SHARED_VGA },
+ { PCI_CHIP_SIS300, PCI_CHIP_SIS300, RES_SHARED_VGA },
+ { PCI_CHIP_SIS630, PCI_CHIP_SIS630, RES_SHARED_VGA },
+ { PCI_CHIP_SIS540, PCI_CHIP_SIS540, RES_SHARED_VGA },
+ { PCI_CHIP_SIS550, PCI_CHIP_SIS550, RES_SHARED_VGA },
+ { PCI_CHIP_SIS315, PCI_CHIP_SIS315, RES_SHARED_VGA },
+ { PCI_CHIP_SIS315H, PCI_CHIP_SIS315H, RES_SHARED_VGA },
+ { PCI_CHIP_SIS315PRO, PCI_CHIP_SIS315PRO, RES_SHARED_VGA },
+ { PCI_CHIP_SIS650, PCI_CHIP_SIS650, RES_SHARED_VGA },
+#ifdef INCL_SIS330 /* TW: New for SiS330 */
+ { PCI_CHIP_SIS330, PCI_CHIP_SIS330, RES_SHARED_VGA },
+#endif
+ { -1, -1, RES_UNDEFINED }
+};
+
+static const char *xaaSymbols[] = {
+ "XAACopyROP",
+ "XAACreateInfoRec",
+ "XAADestroyInfoRec",
+ "XAAFillSolidRects",
+ "XAAHelpPatternROP",
+ "XAAInit",
+ NULL
+};
+
+static const char *vgahwSymbols[] = {
+ "vgaHWFreeHWRec",
+ "vgaHWGetHWRec",
+ "vgaHWGetIOBase",
+ "vgaHWGetIndex",
+ "vgaHWInit",
+ "vgaHWLock",
+ "vgaHWMapMem",
+ "vgaHWProtect",
+ "vgaHWRestore",
+ "vgaHWSave",
+ "vgaHWSaveScreen",
+ "vgaHWUnlock",
+ NULL
+};
+
+static const char *miscfbSymbols[] = {
+ "xf1bppScreenInit",
+ "xf4bppScreenInit",
+ NULL
+};
+
+static const char *fbSymbols[] = {
+ "fbPictureInit",
+ "fbScreenInit",
+ NULL
+};
+
+static const char *shadowSymbols[] = {
+ "ShadowFBInit",
+ NULL
+};
+
+static const char *ramdacSymbols[] = {
+ "xf86CreateCursorInfoRec",
+ "xf86DestroyCursorInfoRec",
+ "xf86InitCursor",
+ NULL
+};
+
+static const char *ddcSymbols[] = {
+ "xf86PrintEDID",
+ "xf86SetDDCproperties",
+ "xf86InterpretEDID",
+ "xf86DoEDID_DDC1",
+#ifdef SISI2C
+ "xf86DoEDID_DDC2",
+#endif
+ NULL
+};
+
+static const char *i2cSymbols[] = {
+ "xf86I2CBusInit",
+ "xf86CreateI2CBusRec",
+ NULL
+};
+
+static const char *int10Symbols[] = {
+ "xf86FreeInt10",
+ "xf86InitInt10",
+ NULL
+};
+
+static const char *vbeSymbols[] = {
+#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,99,0,0)
+ "VBEInit",
+#else
+ "VBEExtendedInit",
+#endif
+ "vbeDoEDID",
+ "vbeFree",
+ "VBEGetVBEInfo",
+ "VBEFreeVBEInfo",
+ "VBEGetModeInfo",
+ "VBEFreeModeInfo",
+ "VBESaveRestore",
+ "VBESetVBEMode",
+ "VBEGetVBEMode",
+ "VBESetDisplayStart",
+ "VBESetGetLogicalScanlineLength",
+ NULL
+};
+
+#ifdef XF86DRI
+static const char *drmSymbols[] = {
+ "drmAddMap",
+ "drmAgpAcquire",
+ "drmAgpAlloc",
+ "drmAgpBase",
+ "drmAgpBind",
+ "drmAgpEnable",
+ "drmAgpFree",
+ "drmAgpGetMode",
+ "drmAgpRelease",
+ "drmCtlInstHandler",
+ "drmGetInterruptFromBusID",
+ "drmSiSAgpInit",
+ NULL
+};
+
+static const char *driSymbols[] = {
+ "DRICloseScreen",
+ "DRICreateInfoRec",
+ "DRIDestroyInfoRec",
+ "DRIFinishScreenInit",
+ "DRIGetSAREAPrivate",
+ "DRILock",
+ "DRIQueryVersion",
+ "DRIScreenInit",
+ "DRIUnlock",
+ "GlxSetVisualConfigs",
+ NULL
+};
+#endif
+
+#ifdef XFree86LOADER
+
+static MODULESETUPPROTO(sisSetup);
+
+static XF86ModuleVersionInfo sisVersRec =
+{
+ SIS_DRIVER_NAME,
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ SIS_MAJOR_VERSION, SIS_MINOR_VERSION, SIS_PATCHLEVEL,
+ ABI_CLASS_VIDEODRV, /* This is a video driver */
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_VIDEODRV,
+ {0,0,0,0}
+};
+
+XF86ModuleData sisModuleData = { &sisVersRec, sisSetup, NULL };
+
+pointer
+sisSetup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ static Bool setupDone = FALSE;
+
+ if (!setupDone) {
+ setupDone = TRUE;
+ xf86AddDriver(&SIS, module, 0);
+ LoaderRefSymLists(vgahwSymbols, fbSymbols, i2cSymbols, xaaSymbols,
+ miscfbSymbols, shadowSymbols, ramdacSymbols,
+ vbeSymbols, int10Symbols,
+#ifdef XF86DRI
+ drmSymbols, driSymbols,
+#endif
+ NULL);
+ return (pointer)TRUE;
+ }
+
+ if (errmaj) *errmaj = LDR_ONCEONLY;
+ return NULL;
+}
+
+#endif /* XFree86LOADER */
+
+static Bool
+SISGetRec(ScrnInfoPtr pScrn)
+{
+ /*
+ * Allocate an SISRec, and hook it into pScrn->driverPrivate.
+ * pScrn->driverPrivate is initialised to NULL, so we can check if
+ * the allocation has already been done.
+ */
+ if (pScrn->driverPrivate != NULL)
+ return TRUE;
+
+ pScrn->driverPrivate = xnfcalloc(sizeof(SISRec), 1);
+
+ /* Initialise it to 0 */
+ memset(pScrn->driverPrivate, 0, sizeof(SISRec));
+
+ return TRUE;
+}
+
+static void
+SISFreeRec(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+#ifdef SISDUALHEAD
+ SISEntPtr pSiSEnt = NULL;
+#endif
+
+ /* TW: Just to make sure... */
+ if(!pSiS) return;
+
+ pSiSEnt = pSiS->entityPrivate;
+
+ if(pSiS->pstate) xfree(pSiS->pstate);
+ pSiS->pstate = NULL;
+ if(pSiS->fonts) xfree(pSiS->fonts);
+ pSiS->fonts = NULL;
+#ifdef SISDUALHEAD
+ if(pSiSEnt) {
+ if(!pSiS->SecondHead) {
+ /* TW: Free memory only if we are first head; in case of an error
+ * during init of the second head, the server will continue -
+ * and we need the BIOS image and SiS_Private for the first
+ * head.
+ */
+ if(pSiSEnt->BIOS) xfree(pSiSEnt->BIOS);
+ pSiSEnt->BIOS = pSiS->BIOS = NULL;
+ if(pSiSEnt->SiS_Pr) xfree(pSiSEnt->SiS_Pr);
+ pSiSEnt->SiS_Pr = pSiS->SiS_Pr = NULL;
+ } else {
+ pSiS->BIOS = NULL;
+ pSiS->SiS_Pr = NULL;
+ }
+ } else {
+#endif
+ if(pSiS->BIOS) xfree(pSiS->BIOS);
+ pSiS->BIOS = NULL;
+ if(pSiS->SiS_Pr) xfree(pSiS->SiS_Pr);
+ pSiS->SiS_Pr = NULL;
+#ifdef SISDUALHEAD
+ }
+#endif
+ if (pSiS->pVbe) vbeFree(pSiS->pVbe);
+ pSiS->pVbe = NULL;
+ if (pScrn->driverPrivate == NULL)
+ return;
+ xfree(pScrn->driverPrivate);
+ pScrn->driverPrivate = NULL;
+}
+
+static void
+SISDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ unsigned char extDDC_PCR=0;
+ unsigned char crtc17, seq1;
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+ "SISDisplayPowerManagementSet(%d)\n",PowerManagementMode);
+
+ /* unlock registers */
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+
+ /* Read CR17 */
+ inSISIDXREG(SISCR, 0x17, crtc17);
+
+ /* Read SR1 */
+ inSISIDXREG(SISSR, 0x01, seq1);
+
+ if(pSiS->VBFlags & CRT2_LCD) {
+ if(((pSiS->VGAEngine == SIS_300_VGA) &&
+ (!(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)))) ||
+ ((pSiS->VGAEngine == SIS_315_VGA) &&
+ ((pSiS->VBFlags & (VB_LVDS | VB_CHRONTEL)) == VB_LVDS))) {
+ /* Read Power Control Register (SR11) */
+ inSISIDXREG(SISSR, 0x11, extDDC_PCR);
+ /* if not blanked, obtain state of LCD blank flags set by BIOS */
+ if(!pSiS->Blank) {
+ pSiS->LCDon = extDDC_PCR;
+ }
+ /* erase LCD blank flags */
+ extDDC_PCR &= ~0x0C;
+ }
+ }
+
+ switch (PowerManagementMode) {
+
+ case DPMSModeOn: /* HSync: On, VSync: On */
+
+ pSiS->Blank = FALSE;
+ seq1 &= ~0x20;
+ crtc17 |= 0x80;
+ if(pSiS->VBFlags & CRT2_LCD) {
+ if(pSiS->VGAEngine == SIS_315_VGA) {
+ if(pSiS->VBFlags & VB_CHRONTEL) {
+ SiS_Chrontel701xBLOn(pSiS->SiS_Pr);
+ } else if(pSiS->VBFlags & VB_LVDS) {
+ extDDC_PCR |= (pSiS->LCDon & 0x0C);
+ } else if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) {
+ SiS_SiS30xBLOn(pSiS->SiS_Pr,&pSiS->sishw_ext);
+ }
+ } else if(pSiS->VGAEngine == SIS_300_VGA) {
+ if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) {
+ SiS_SiS30xBLOn(pSiS->SiS_Pr,&pSiS->sishw_ext);
+ } else {
+ extDDC_PCR |= (pSiS->LCDon & 0x0C);
+ }
+ }
+ }
+ break;
+
+ case DPMSModeStandby: /* HSync: Off, VSync: On */
+ case DPMSModeSuspend: /* HSync: On, VSync: Off */
+
+ pSiS->Blank = TRUE;
+ seq1 |= 0x20 ;
+ if(pSiS->VBFlags & CRT2_LCD) {
+ if(pSiS->VGAEngine == SIS_315_VGA) {
+ if(pSiS->VBFlags & VB_CHRONTEL) {
+ SiS_Chrontel701xBLOff(pSiS->SiS_Pr);
+ } else if(pSiS->VBFlags & VB_LVDS) {
+ extDDC_PCR |= 0x08;
+ } else if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) {
+ SiS_SiS30xBLOff(pSiS->SiS_Pr,&pSiS->sishw_ext);
+ }
+ } else if(pSiS->VGAEngine == SIS_300_VGA) {
+ if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) {
+ SiS_SiS30xBLOff(pSiS->SiS_Pr,&pSiS->sishw_ext);
+ } else {
+ extDDC_PCR |= 0x08;
+ }
+ }
+ }
+ break;
+
+ case DPMSModeOff: /* HSync: Off, VSync: Off */
+
+ pSiS->Blank = TRUE;
+ seq1 |= 0x20;
+ if(pSiS->VGAEngine == SIS_300_VGA ||
+ pSiS->VGAEngine == SIS_315_VGA) {
+ /* TW: We can't switch off CRT1 if bridge is in slavemode */
+ if(pSiS->VBFlags & CRT2_ENABLE) {
+ if(!(SiSBridgeIsInSlaveMode(pScrn))) crtc17 &= ~0x80;
+ } else crtc17 &= ~0x80;
+ } else {
+ crtc17 &= ~0x80;
+ }
+ if(pSiS->VBFlags & CRT2_LCD) {
+ if(pSiS->VGAEngine == SIS_315_VGA) {
+ if(pSiS->VBFlags & VB_CHRONTEL) {
+ SiS_Chrontel701xBLOff(pSiS->SiS_Pr);
+ } else if(pSiS->VBFlags & VB_LVDS) {
+ extDDC_PCR |= 0x0C;
+ } else if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) {
+ SiS_SiS30xBLOff(pSiS->SiS_Pr,&pSiS->sishw_ext);
+ }
+ } else if(pSiS->VGAEngine == SIS_300_VGA) {
+ if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) {
+ SiS_SiS30xBLOff(pSiS->SiS_Pr,&pSiS->sishw_ext);
+ } else {
+ extDDC_PCR |= 0x0C;
+ }
+ }
+ }
+ break;
+
+ }
+
+ outSISIDXREG(SISSR, 0x01, seq1); /* Set/Clear "Display On" bit */
+
+ outSISIDXREG(SISCR, 0x17, crtc17);
+
+ if(pSiS->VBFlags & CRT2_LCD) {
+ if(((pSiS->VGAEngine == SIS_300_VGA) &&
+ (!(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)))) ||
+ ((pSiS->VGAEngine == SIS_315_VGA) &&
+ ((pSiS->VBFlags & (VB_LVDS | VB_CHRONTEL)) == VB_LVDS))) {
+ outSISIDXREG(SISSR, 0x11, extDDC_PCR);
+ }
+ }
+
+ outSISIDXREG(SISSR, 0x00, 0x01); /* Synchronous Reset */
+ usleep(10000);
+ outSISIDXREG(SISSR, 0x00, 0x03); /* End Reset */
+
+}
+
+#ifdef SISDUALHEAD
+/* TW: DPMS for dual head mode */
+static void
+SISDisplayPowerManagementSetDH(ScrnInfoPtr pScrn, int PowerManagementMode, int flags)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ unsigned char crtc17 = 0;
+ unsigned char extDDC_PCR=0;
+ unsigned char seq1 = 0;
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+ "SISDisplayPowerManagementSetDH(%d)\n",PowerManagementMode);
+
+ /* unlock registers */
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+
+ if (pSiS->SecondHead) {
+
+ /* TW: Second (slave) head is always CRT1 */
+
+ /* Read CR17 and SR01 */
+ inSISIDXREG(SISCR, 0x17, crtc17);
+ inSISIDXREG(SISSR, 0x01, seq1);
+
+ switch (PowerManagementMode)
+ {
+ case DPMSModeOn: /* HSync: On, VSync: On */
+ seq1 &= ~0x20 ;
+ crtc17 |= 0x80;
+ pSiS->BlankCRT1 = FALSE;
+ break;
+
+ case DPMSModeStandby: /* HSync: Off, VSync: On */
+ case DPMSModeSuspend: /* HSync: On, VSync: Off */
+ seq1 |= 0x20;
+ pSiS->BlankCRT1 = TRUE;
+ break;
+
+ case DPMSModeOff: /* HSync: Off, VSync: Off */
+ seq1 |= 0x20 ;
+ pSiS->BlankCRT1 = TRUE;
+ crtc17 &= ~0x80;
+ break;
+ }
+ outSISIDXREG(SISSR, 0x00, 0x01); /* Synchronous Reset */
+
+ outSISIDXREG(SISSR, 0x01, seq1); /* Set/Clear "Display On" bit */
+
+ usleep(10000);
+
+ outSISIDXREG(SISCR, 0x17, crtc17);
+
+ outSISIDXREG(SISSR, 0x00, 0x03); /* End Reset */
+
+ } else {
+
+ /* TW: Master head is always CRT2 */
+
+ /* TV can not be managed */
+ if(!(pSiS->VBFlags & CRT2_LCD)) return;
+
+ if(((pSiS->VGAEngine == SIS_300_VGA) &&
+ (!(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)))) ||
+ ((pSiS->VGAEngine == SIS_315_VGA) &&
+ ((pSiS->VBFlags & (VB_LVDS | VB_CHRONTEL)) == VB_LVDS))) {
+ /* Read Power Control Register (SR11) */
+ inSISIDXREG(SISSR, 0x11, extDDC_PCR);
+ /* if not blanked obtain state of LCD blank flags set by BIOS */
+ if(!pSiS->BlankCRT2) {
+ pSiS->LCDon = extDDC_PCR;
+ }
+ /* erase LCD blank flags */
+ extDDC_PCR &= ~0xC;
+ }
+
+ switch (PowerManagementMode) {
+
+ case DPMSModeOn:
+ pSiS->BlankCRT2 = FALSE;
+ if(pSiS->VGAEngine == SIS_315_VGA) {
+ if(pSiS->VBFlags & VB_CHRONTEL) {
+ SiS_Chrontel701xBLOn(pSiS->SiS_Pr);
+ } else if(pSiS->VBFlags & VB_LVDS) {
+ extDDC_PCR |= (pSiS->LCDon & 0x0C);
+ } else if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) {
+ SiS_SiS30xBLOn(pSiS->SiS_Pr, &pSiS->sishw_ext);
+ }
+ } else if(pSiS->VGAEngine == SIS_300_VGA) {
+ if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) {
+ SiS_SiS30xBLOn(pSiS->SiS_Pr, &pSiS->sishw_ext);
+ } else {
+ extDDC_PCR |= (pSiS->LCDon & 0x0C);
+ }
+ }
+ break;
+
+ case DPMSModeStandby:
+ case DPMSModeSuspend:
+ pSiS->BlankCRT2 = TRUE;
+ if(pSiS->VGAEngine == SIS_315_VGA) {
+ if(pSiS->VBFlags & VB_CHRONTEL) {
+ SiS_Chrontel701xBLOff(pSiS->SiS_Pr);
+ } else if(pSiS->VBFlags & VB_LVDS) {
+ extDDC_PCR |= 0x08;
+ } else if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) {
+ SiS_SiS30xBLOff(pSiS->SiS_Pr, &pSiS->sishw_ext);
+ }
+ } else if(pSiS->VGAEngine == SIS_300_VGA) {
+ if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) {
+ SiS_SiS30xBLOff(pSiS->SiS_Pr, &pSiS->sishw_ext);
+ } else {
+ extDDC_PCR |= 0x08;
+ }
+ }
+ break;
+
+ case DPMSModeOff:
+ pSiS->BlankCRT2 = TRUE;
+ if(pSiS->VGAEngine == SIS_315_VGA) {
+ if(pSiS->VBFlags & VB_CHRONTEL) {
+ SiS_Chrontel701xBLOff(pSiS->SiS_Pr);
+ } else if(pSiS->VBFlags & VB_LVDS) {
+ extDDC_PCR |= 0x0C;
+ } else if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) {
+ SiS_SiS30xBLOff(pSiS->SiS_Pr, &pSiS->sishw_ext);
+ }
+ } else if(pSiS->VGAEngine == SIS_300_VGA) {
+ if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) {
+ SiS_SiS30xBLOff(pSiS->SiS_Pr, &pSiS->sishw_ext);
+ } else {
+ extDDC_PCR |= 0x0C;
+ }
+ }
+ break;
+ }
+
+ if(((pSiS->VGAEngine == SIS_300_VGA) &&
+ (!(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)))) ||
+ ((pSiS->VGAEngine == SIS_315_VGA) &&
+ ((pSiS->VBFlags & (VB_LVDS | VB_CHRONTEL)) == VB_LVDS))) {
+ outSISIDXREG(SISSR, 0x11, extDDC_PCR);
+ }
+
+ }
+}
+#endif
+
+/* Mandatory */
+static void
+SISIdentify(int flags)
+{
+ xf86PrintChipsets(SIS_NAME, "driver for SiS chipsets", SISChipsets);
+}
+
+static void
+SIS1bppColorMap(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+
+ outSISREG(SISCOLIDX, 0x00);
+ outSISREG(SISCOLDATA, 0x00);
+ outSISREG(SISCOLDATA, 0x00);
+ outSISREG(SISCOLDATA, 0x00);
+
+ outSISREG(SISCOLIDX, 0x3f);
+ outSISREG(SISCOLDATA, 0x3f);
+ outSISREG(SISCOLDATA, 0x3f);
+ outSISREG(SISCOLDATA, 0x3f);
+}
+
+/* Mandatory */
+static Bool
+SISProbe(DriverPtr drv, int flags)
+{
+ int i;
+ GDevPtr *devSections;
+ int *usedChips;
+ int numDevSections;
+ int numUsed;
+ Bool foundScreen = FALSE;
+
+ /*
+ * The aim here is to find all cards that this driver can handle,
+ * and for the ones not already claimed by another driver, claim the
+ * slot, and allocate a ScrnInfoRec.
+ *
+ * This should be a minimal probe, and it should under no circumstances
+ * change the state of the hardware. Because a device is found, don't
+ * assume that it will be used. Don't do any initialisations other than
+ * the required ScrnInfoRec initialisations. Don't allocate any new
+ * data structures.
+ *
+ */
+
+ /*
+ * Next we check, if there has been a chipset override in the config file.
+ * For this we must find out if there is an active device section which
+ * is relevant, i.e., which has no driver specified or has THIS driver
+ * specified.
+ */
+
+ if ((numDevSections = xf86MatchDevice(SIS_DRIVER_NAME,
+ &devSections)) <= 0) {
+ /*
+ * There's no matching device section in the config file, so quit
+ * now.
+ */
+ return FALSE;
+ }
+
+ /*
+ * We need to probe the hardware first. We then need to see how this
+ * fits in with what is given in the config file, and allow the config
+ * file info to override any contradictions.
+ */
+
+ /*
+ * All of the cards this driver supports are PCI, so the "probing" just
+ * amounts to checking the PCI data that the server has already collected.
+ */
+ if (xf86GetPciVideoInfo() == NULL) {
+ /*
+ * We won't let anything in the config file override finding no
+ * PCI video cards at all. This seems reasonable now, but we'll see.
+ */
+ return FALSE;
+ }
+
+ numUsed = xf86MatchPciInstances(SIS_NAME, PCI_VENDOR_SIS,
+ SISChipsets, SISPciChipsets, devSections,
+ numDevSections, drv, &usedChips);
+
+ /* Free it since we don't need that list after this */
+ xfree(devSections);
+ if (numUsed <= 0)
+ return FALSE;
+
+ if (flags & PROBE_DETECT)
+ foundScreen = TRUE;
+ else for (i = 0; i < numUsed; i++) {
+ ScrnInfoPtr pScrn;
+#ifdef SISDUALHEAD
+ EntityInfoPtr pEnt;
+#endif
+
+ /* Allocate a ScrnInfoRec and claim the slot */
+ pScrn = NULL;
+
+ if ((pScrn = xf86ConfigPciEntity(pScrn, 0, usedChips[i],
+ SISPciChipsets, NULL, NULL,
+ NULL, NULL, NULL))) {
+ /* Fill in what we can of the ScrnInfoRec */
+ pScrn->driverVersion = SIS_CURRENT_VERSION;
+ pScrn->driverName = SIS_DRIVER_NAME;
+ pScrn->name = SIS_NAME;
+ pScrn->Probe = SISProbe;
+ pScrn->PreInit = SISPreInit;
+ pScrn->ScreenInit = SISScreenInit;
+ pScrn->SwitchMode = SISSwitchMode;
+ pScrn->AdjustFrame = SISAdjustFrame;
+ pScrn->EnterVT = SISEnterVT;
+ pScrn->LeaveVT = SISLeaveVT;
+ pScrn->FreeScreen = SISFreeScreen;
+ pScrn->ValidMode = SISValidMode;
+ foundScreen = TRUE;
+ }
+#ifdef SISDUALHEAD
+ pEnt = xf86GetEntityInfo(usedChips[i]);
+
+ /* TW: I assume these chipsets as - basically - dual head capable. */
+ if (pEnt->chipset == PCI_CHIP_SIS630 || pEnt->chipset == PCI_CHIP_SIS540 ||
+ pEnt->chipset == PCI_CHIP_SIS650 || pEnt->chipset == PCI_CHIP_SIS550 ||
+ pEnt->chipset == PCI_CHIP_SIS315 || pEnt->chipset == PCI_CHIP_SIS315H ||
+ pEnt->chipset == PCI_CHIP_SIS315PRO || pEnt->chipset == PCI_CHIP_SIS330 ||
+ pEnt->chipset == PCI_CHIP_SIS300) {
+
+ SISEntPtr pSiSEnt = NULL;
+ DevUnion *pPriv;
+
+ xf86SetEntitySharable(usedChips[i]);
+ if (SISEntityIndex < 0)
+ SISEntityIndex = xf86AllocateEntityPrivateIndex();
+ pPriv = xf86GetEntityPrivate(pScrn->entityList[0], SISEntityIndex);
+ if (!pPriv->ptr) {
+ pPriv->ptr = xnfcalloc(sizeof(SISEntRec), 1);
+ pSiSEnt = pPriv->ptr;
+ pSiSEnt->lastInstance = -1;
+ pSiSEnt->DisableDual = FALSE;
+ pSiSEnt->ErrorAfterFirst = FALSE;
+ pSiSEnt->MapCountIOBase = pSiSEnt->MapCountFbBase = 0;
+ pSiSEnt->FbBase = pSiSEnt->IOBase = NULL;
+ pSiSEnt->forceUnmapIOBase = FALSE;
+ pSiSEnt->forceUnmapFbBase = FALSE;
+#ifdef __alpha__
+ pSiSEnt->MapCountIOBaseDense = 0;
+ pSiSEnt->IOBaseDense = NULL;
+ pSiSEnt->forceUnmapIOBaseDense = FALSE;
+#endif
+ } else {
+ pSiSEnt = pPriv->ptr;
+ }
+ pSiSEnt->lastInstance++;
+ xf86SetEntityInstanceForScreen(pScrn, pScrn->entityList[0],
+ pSiSEnt->lastInstance);
+ }
+#endif
+ }
+ xfree(usedChips);
+ return foundScreen;
+}
+
+
+/* TW: If monitor section has no HSync/VRefresh data,
+ * derive it from DDC data.
+ */
+static void
+SiSSetSyncRangeFromEdid(ScrnInfoPtr pScrn, int flag)
+{
+ MonPtr mon = pScrn->monitor;
+ xf86MonPtr ddc = mon->DDC;
+ int i,j;
+ float myhhigh, myhlow;
+ int myvhigh, myvlow;
+ unsigned char temp;
+ const myhddctiming myhtiming[11] = {
+ { 1, 0x20, 31.6 }, /* rounded up by .1 */
+ { 1, 0x02, 35.3 },
+ { 1, 0x04, 37.6 },
+ { 1, 0x08, 38.0 },
+ { 1, 0x01, 38.0 },
+ { 2, 0x40, 47.0 },
+ { 2, 0x80, 48.2 },
+ { 2, 0x08, 48.5 },
+ { 2, 0x04, 56.6 },
+ { 2, 0x02, 60.1 },
+ { 2, 0x01, 80.1 }
+ };
+ const myvddctiming myvtiming[10] = {
+ { 1, 0x02, 56 },
+ { 1, 0x01, 60 },
+ { 2, 0x08, 60 },
+ { 2, 0x04, 70 },
+ { 1, 0x08, 72 },
+ { 2, 0x80, 72 },
+ { 1, 0x04, 75 },
+ { 2, 0x40, 75 },
+ { 2, 0x02, 75 },
+ { 2, 0x01, 75 }
+ };
+ /* "Future modes"; we only check the really high ones */
+ const myddcstdmodes mystdmodes[8] = {
+ { 1280, 1024, 85, 91.1 },
+ { 1600, 1200, 60, 75.0 },
+ { 1600, 1200, 65, 81.3 },
+ { 1600, 1200, 70, 87.5 },
+ { 1600, 1200, 75, 93.8 },
+ { 1600, 1200, 85, 106.3 },
+ { 1920, 1440, 60, 90.0 },
+ { 1920, 1440, 75, 112.5 }
+ };
+
+ if(flag) { /* HSync */
+ for (i = 0; i < 4; i++) {
+ if (ddc->det_mon[i].type == DS_RANGES) {
+ mon->nHsync = 1;
+ mon->hsync[0].lo = ddc->det_mon[i].section.ranges.min_h;
+ mon->hsync[0].hi = ddc->det_mon[i].section.ranges.max_h;
+ return;
+ }
+ }
+ /* If no sync ranges detected in detailed timing table, we
+ * derive them from supported VESA modes. */
+ myhlow = myhhigh = 0.0;
+ for(i=0; i<11; i++) {
+ if(myhtiming[i].whichone == 1) temp = ddc->timings1.t1;
+ else temp = ddc->timings1.t2;
+ if(temp & myhtiming[i].mask) {
+ if((i==0) || (myhlow > myhtiming[i].rate))
+ myhlow = myhtiming[i].rate;
+ }
+ if(myhtiming[10-i].whichone == 1) temp = ddc->timings1.t1;
+ else temp = ddc->timings1.t2;
+ if(temp & myhtiming[10-i].mask) {
+ if((i==0) || (myhhigh < myhtiming[10-i].rate))
+ myhhigh = myhtiming[10-i].rate;
+ }
+ }
+ for(i=0;i<STD_TIMINGS;i++) {
+ if(ddc->timings2[i].hsize > 256) {
+ for(j=0; j<8; j++) {
+ if((ddc->timings2[i].hsize == mystdmodes[j].hsize) &&
+ (ddc->timings2[i].vsize == mystdmodes[j].vsize) &&
+ (ddc->timings2[i].refresh == mystdmodes[j].refresh)) {
+ if(mystdmodes[j].hsync > myhhigh)
+ myhhigh = mystdmodes[j].hsync;
+ }
+ }
+ }
+ }
+ if((myhhigh) && (myhlow)) {
+ mon->nHsync = 1;
+ mon->hsync[0].lo = myhlow - 0.1;
+ mon->hsync[0].hi = myhhigh;
+ }
+
+
+ } else { /* Vrefresh */
+
+ for (i = 0; i < 4; i++) {
+ if (ddc->det_mon[i].type == DS_RANGES) {
+ mon->nVrefresh = 1;
+ mon->vrefresh[0].lo = ddc->det_mon[i].section.ranges.min_v;
+ mon->vrefresh[0].hi = ddc->det_mon[i].section.ranges.max_v;
+ return;
+ }
+ }
+
+ myvlow = myvhigh = 0;
+ for(i=0; i<10; i++) {
+ if(myvtiming[i].whichone == 1) temp = ddc->timings1.t1;
+ else temp = ddc->timings1.t2;
+ if(temp & myvtiming[i].mask) {
+ if((i==0) || (myvlow > myvtiming[i].rate))
+ myvlow = myvtiming[i].rate;
+ }
+ if(myvtiming[9-i].whichone == 1) temp = ddc->timings1.t1;
+ else temp = ddc->timings1.t2;
+ if(temp & myvtiming[9-i].mask) {
+ if((i==0) || (myvhigh < myvtiming[9-i].rate))
+ myvhigh = myvtiming[9-i].rate;
+ }
+ }
+ for(i=0;i<STD_TIMINGS;i++) {
+ if(ddc->timings2[i].hsize > 256) {
+ for(j=0; j<8; j++) {
+ if((ddc->timings2[i].hsize == mystdmodes[j].hsize) &&
+ (ddc->timings2[i].vsize == mystdmodes[j].vsize) &&
+ (ddc->timings2[i].refresh == mystdmodes[j].refresh)) {
+ if(mystdmodes[j].refresh > myvhigh)
+ myvhigh = mystdmodes[j].refresh;
+ }
+ }
+ }
+ }
+ if((myvhigh) && (myvlow)) {
+ mon->nVrefresh = 1;
+ mon->vrefresh[0].lo = myvlow;
+ mon->vrefresh[0].hi = myvhigh;
+ }
+
+ }
+}
+
+static xf86MonPtr
+SiSInternalDDC(ScrnInfoPtr pScrn, int crtno)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ USHORT temp, i;
+ unsigned char buffer[256];
+ xf86MonPtr pMonitor = NULL;
+
+ /* TW: If CRT1 is off, skip DDC */
+ if((pSiS->CRT1off) && (!crtno)) return NULL;
+
+ temp = SiS_HandleDDC(pSiS->SiS_Pr, pSiS, crtno, 0, &buffer[0]);
+ if((!temp) || (temp == 0xffff)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "CRT%d DDC probing failed, now trying via VBE\n", crtno + 1);
+ return(NULL);
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CRT%d DDC supported\n", crtno + 1);
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CRT%d DDC level: %s%s%s%s\n",
+ crtno + 1,
+ (temp & 0x1a) ? "" : "[none of the supported]",
+ (temp & 0x02) ? "2 " : "",
+ (temp & 0x08) ? "3 " : "",
+ (temp & 0x10) ? "4" : "");
+ if(temp & 0x02) {
+ i = 3; /* Number of retrys */
+ do {
+ temp = SiS_HandleDDC(pSiS->SiS_Pr, pSiS, crtno, 1, &buffer[0]);
+ } while((temp) && i--);
+ if(!temp) {
+ if((pMonitor = xf86InterpretEDID(pScrn->scrnIndex, &buffer[0]))) {
+ return(pMonitor);
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "CRT%d DDC EDID corrupt\n", crtno + 1);
+ return(NULL);
+ }
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "CRT%d DDC reading failed\n", crtno + 1);
+ return(NULL);
+ }
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "DDC levels 3 and 4 not supported by this driver yet.\n");
+ return(NULL);
+ }
+ }
+}
+
+static xf86MonPtr
+SiSDoPrivateDDC(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+
+#ifdef SISDUALHEAD
+ if((pSiS->DualHeadMode) && (!pSiS->SecondHead))
+ return(SiSInternalDDC(pScrn, 1));
+ else
+#endif
+ return(SiSInternalDDC(pScrn, 0));
+}
+
+/* Mandatory */
+static Bool
+SISPreInit(ScrnInfoPtr pScrn, int flags)
+{
+ SISPtr pSiS;
+ MessageType from;
+ unsigned char usScratchCR17, CR5F;
+ unsigned char usScratchCR32;
+ unsigned long int i;
+ int temp;
+ ClockRangePtr clockRanges;
+ char *mod = NULL;
+ const char *Sym = NULL;
+ int pix24flags;
+#ifdef SISDUALHEAD
+ SISEntPtr pSiSEnt = NULL;
+#endif
+ DisplayModePtr first, p, n;
+ DisplayModePtr tempmode, delmode, mymodes;
+ unsigned char srlockReg,crlockReg;
+ unsigned char tempreg;
+ xf86MonPtr pMonitor = NULL;
+ Bool didddc2;
+
+ vbeInfoPtr pVbe;
+ VbeInfoBlock *vbe;
+
+ if (flags & PROBE_DETECT) {
+ if (xf86LoadSubModule(pScrn, "vbe")) {
+ int index = xf86GetEntityInfo(pScrn->entityList[0])->index;
+
+#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,99,0,0)
+ if((pVbe = VBEInit(NULL,index))) {
+#else
+ if((pVbe = VBEExtendedInit(NULL,index,0))) {
+#endif
+ ConfiguredMonitor = vbeDoEDID(pVbe, NULL);
+ vbeFree(pVbe);
+ }
+ }
+ return TRUE;
+ }
+
+ /*
+ * Note: This function is only called once at server startup, and
+ * not at the start of each server generation. This means that
+ * only things that are persistent across server generations can
+ * be initialised here. xf86Screens[] is the array of all screens,
+ * (pScrn is a pointer to one of these). Privates allocated using
+ * xf86AllocateScrnInfoPrivateIndex() are too, and should be used
+ * for data that must persist across server generations.
+ *
+ * Per-generation data should be allocated with
+ * AllocateScreenPrivateIndex() from the ScreenInit() function.
+ */
+
+ /* Check the number of entities, and fail if it isn't one. */
+ if(pScrn->numEntities != 1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Number of entities is not 1\n");
+ return FALSE;
+ }
+
+ /* The vgahw module should be loaded here when needed */
+ if(!xf86LoadSubModule(pScrn, "vgahw")) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Could not load vgahw module\n");
+ return FALSE;
+ }
+
+ xf86LoaderReqSymLists(vgahwSymbols, NULL);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "SiS driver (31/01/03-1) by "
+ "Thomas Winischhofer <thomas@winischhofer.net>\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "See http://www.winischhofer.net/linuxsisvga.shtml "
+ "for documentation and updates\n");
+
+ /* Allocate a vgaHWRec */
+ if(!vgaHWGetHWRec(pScrn)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Could not allocate VGA private\n");
+ return FALSE;
+ }
+
+ /* Allocate the SISRec driverPrivate */
+ if(!SISGetRec(pScrn)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Could not allocate memory for pSiS private\n");
+ return FALSE;
+ }
+ pSiS = SISPTR(pScrn);
+ pSiS->pScrn = pScrn;
+
+#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,99,0,0)
+ pSiS->IODBase = 0;
+#else
+ pSiS->IODBase = pScrn->domainIOBase;
+#endif
+
+ /* Get the entity, and make sure it is PCI. */
+ pSiS->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
+ if(pSiS->pEnt->location.type != BUS_PCI) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Entity's bus type is not PCI\n");
+ SISFreeRec(pScrn);
+ return FALSE;
+ }
+
+#ifdef SISDUALHEAD
+ /* TW: Allocate an entity private if necessary */
+ if(xf86IsEntityShared(pScrn->entityList[0])) {
+ pSiSEnt = xf86GetEntityPrivate(pScrn->entityList[0],
+ SISEntityIndex)->ptr;
+ pSiS->entityPrivate = pSiSEnt;
+
+ /* TW: If something went wrong, quit here */
+ if ((pSiSEnt->DisableDual) || (pSiSEnt->ErrorAfterFirst)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "First head encountered fatal error, can't continue\n");
+ SISFreeRec(pScrn);
+ return FALSE;
+ }
+ }
+#endif
+
+ /* Find the PCI info for this screen */
+ pSiS->PciInfo = xf86GetPciInfoForEntity(pSiS->pEnt->index);
+ pSiS->PciTag = pSiS->sishw_ext.PciTag = pciTag(pSiS->PciInfo->bus,
+ pSiS->PciInfo->device, pSiS->PciInfo->func);
+
+ pSiS->Primary = xf86IsPrimaryPci(pSiS->PciInfo);
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "This adapter is %s display adapter\n",
+ (pSiS->Primary ? "primary" : "secondary"));
+
+ if(pSiS->Primary) {
+ VGAHWPTR(pScrn)->MapSize = 0x10000; /* Standard 64k VGA window */
+ if(!vgaHWMapMem(pScrn)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Could not map VGA memory\n");
+ SISFreeRec(pScrn);
+ return FALSE;
+ }
+ }
+ vgaHWGetIOBase(VGAHWPTR(pScrn));
+
+ /* TW: We "patch" the PIOOffset inside vgaHW in order to force
+ * the vgaHW module to use our relocated i/o ports.
+ */
+ VGAHWPTR(pScrn)->PIOOffset = pSiS->IODBase + (pSiS->PciInfo->ioBase[2] & 0xFFFC) - 0x380;
+
+ pSiS->pInt = NULL;
+ if(!pSiS->Primary) {
+#if !defined(__alpha__)
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Initializing display adapter through int10\n");
+#endif
+ if(xf86LoadSubModule(pScrn, "int10")) {
+ xf86LoaderReqSymLists(int10Symbols, NULL);
+#if !defined(__alpha__)
+ pSiS->pInt = xf86InitInt10(pSiS->pEnt->index);
+#endif
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Could not load int10 module\n");
+ }
+ }
+
+#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,99,0,0)
+ {
+ resRange vgamem[] = { {ResShrMemBlock,0xA0000,0xAFFFF},
+ {ResShrMemBlock,0xB0000,0xB7FFF},
+ {ResShrMemBlock,0xB8000,0xBFFFF},
+ _END };
+ xf86SetOperatingState(vgamem, pSiS->pEnt->index, ResUnusedOpr);
+ }
+#else
+ xf86SetOperatingState(resVgaMem, pSiS->pEnt->index, ResUnusedOpr);
+#endif
+
+ /* Operations for which memory access is required */
+ pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
+ /* Operations for which I/O access is required */
+ pScrn->racIoFlags = RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
+
+ /* The ramdac module should be loaded here when needed */
+ if(!xf86LoadSubModule(pScrn, "ramdac")) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Could not load ramdac module\n");
+#ifdef SISDUALHEAD
+ if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
+#endif
+ if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
+ SISFreeRec(pScrn);
+ return FALSE;
+ }
+
+ xf86LoaderReqSymLists(ramdacSymbols, NULL);
+
+ /* Set pScrn->monitor */
+ pScrn->monitor = pScrn->confScreen->monitor;
+
+ /*
+ * Set the Chipset and ChipRev, allowing config file entries to
+ * override. DANGEROUS!
+ */
+ if (pSiS->pEnt->device->chipset && *pSiS->pEnt->device->chipset) {
+ pScrn->chipset = pSiS->pEnt->device->chipset;
+ pSiS->Chipset = xf86StringToToken(SISChipsets, pScrn->chipset);
+ from = X_CONFIG;
+ } else if (pSiS->pEnt->device->chipID >= 0) {
+ pSiS->Chipset = pSiS->pEnt->device->chipID;
+ pScrn->chipset = (char *)xf86TokenToString(SISChipsets, pSiS->Chipset);
+
+ from = X_CONFIG;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n",
+ pSiS->Chipset);
+ } else {
+ from = X_PROBED;
+ pSiS->Chipset = pSiS->PciInfo->chipType;
+ pScrn->chipset = (char *)xf86TokenToString(SISChipsets, pSiS->Chipset);
+ }
+ if (pSiS->pEnt->device->chipRev >= 0) {
+ pSiS->ChipRev = pSiS->pEnt->device->chipRev;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
+ pSiS->ChipRev);
+ } else {
+ pSiS->ChipRev = pSiS->PciInfo->chipRev;
+ }
+ pSiS->sishw_ext.jChipRevision = pSiS->ChipRev;
+
+ /* TW: Determine SiS6326 chiprevision. This is not yet used for
+ * anything, but it will as soon as I found out on which revisions
+ * the hardware video overlay really works.
+ * According to SiS the only differences are:
+ * Chip name Chip type TV-Out MPEG II decoder
+ * 6326 AGP Rev. G0/H0 no no
+ * 6326 DVD Rev. D2 yes yes
+ * 6326 Rev. Cx yes yes
+ */
+ pSiS->SiS6326Flags = 0;
+ if(pSiS->Chipset == PCI_CHIP_SIS6326) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Chipset is SiS6326 %s (revision 0x%02x)\n",
+ (pSiS->ChipRev == 0xaf) ? "(Ax)" :
+ ((pSiS->ChipRev == 0x0a) ? "AGP (G0)" :
+ ((pSiS->ChipRev == 0x0b) ? "AGP (H0)" :
+ (((pSiS->ChipRev & 0xf0) == 0xd0) ? "DVD (Dx)" :
+ (((pSiS->ChipRev & 0xf0) == 0x90) ? "(9x)" :
+ (((pSiS->ChipRev & 0xf0) == 0xc0) ? "(Cx)" :
+ "(unknown)"))))),
+ pSiS->ChipRev);
+ if((pSiS->ChipRev != 0x0a) && (pSiS->ChipRev != 0x0b)) {
+ pSiS->SiS6326Flags |= SIS6326_HASTV;
+ }
+ }
+
+
+ /*
+ * This shouldn't happen because such problems should be caught in
+ * SISProbe(), but check it just in case.
+ */
+ if (pScrn->chipset == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "ChipID 0x%04X is not recognised\n", pSiS->Chipset);
+#ifdef SISDUALHEAD
+ if (pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
+#endif
+ if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
+ SISFreeRec(pScrn);
+ return FALSE;
+ }
+ if (pSiS->Chipset < 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Chipset \"%s\" is not recognised\n", pScrn->chipset);
+#ifdef SISDUALHEAD
+ if (pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
+#endif
+ if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
+ SISFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /* TW: Determine chipset and VGA engine type for new mode switching code */
+ switch(pSiS->Chipset) {
+ case PCI_CHIP_SIS300:
+ pSiS->sishw_ext.jChipType = SIS_300;
+ pSiS->VGAEngine = SIS_300_VGA;
+ break;
+ case PCI_CHIP_SIS630: /* 630 + 730 */
+ pSiS->sishw_ext.jChipType = SIS_630;
+ if(pciReadLong(0x00000000, 0x00) == 0x07301039) {
+ pSiS->sishw_ext.jChipType = SIS_730;
+ }
+ pSiS->VGAEngine = SIS_300_VGA;
+ break;
+ case PCI_CHIP_SIS540:
+ pSiS->sishw_ext.jChipType = SIS_540;
+ pSiS->VGAEngine = SIS_300_VGA;
+ break;
+ case PCI_CHIP_SIS315H:
+ pSiS->sishw_ext.jChipType = SIS_315H;
+ pSiS->VGAEngine = SIS_315_VGA;
+ break;
+ case PCI_CHIP_SIS315:
+ /* TW: Override for simplicity */
+ pSiS->Chipset = PCI_CHIP_SIS315H;
+ pSiS->sishw_ext.jChipType = SIS_315;
+ pSiS->VGAEngine = SIS_315_VGA;
+ break;
+ case PCI_CHIP_SIS315PRO:
+ /* TW: Override for simplicity */
+ pSiS->Chipset = PCI_CHIP_SIS315H;
+ pSiS->sishw_ext.jChipType = SIS_315PRO;
+ pSiS->VGAEngine = SIS_315_VGA;
+ break;
+ case PCI_CHIP_SIS550:
+ pSiS->sishw_ext.jChipType = SIS_550;
+ pSiS->VGAEngine = SIS_315_VGA;
+ break;
+ case PCI_CHIP_SIS650: /* 650 + 740 */
+ pSiS->sishw_ext.jChipType = SIS_650;
+ pSiS->VGAEngine = SIS_315_VGA;
+ break;
+ case PCI_CHIP_SIS330:
+ pSiS->sishw_ext.jChipType = SIS_330;
+ pSiS->VGAEngine = SIS_315_VGA;
+ break;
+ case PCI_CHIP_SIS530:
+ pSiS->sishw_ext.jChipType = SIS_530;
+ pSiS->VGAEngine = SIS_530_VGA;
+ break;
+ default:
+ pSiS->sishw_ext.jChipType = SIS_OLD;
+ pSiS->VGAEngine = SIS_OLD_VGA;
+ break;
+ }
+
+ /* TW: Now check if sisfb is loaded. Since sisfb only supports
+ * the 300 and 310/325 series, we only do this for these chips.
+ * We use this for checking where sisfb starts its memory
+ * heap in order to automatically detect the correct MaxXFBMem
+ * setting (which normally is given by the option of the same name).
+ * That only works if sisfb is completely running, ie with
+ * a video mode (because the fbdev will not be installed otherwise.)
+ */
+
+ pSiS->donttrustpdc = FALSE;
+ pSiS->sisfbpdc = 0;
+
+ if(pSiS->VGAEngine == SIS_300_VGA || pSiS->VGAEngine == SIS_315_VGA) {
+
+ int fd, i;
+ sisfb_info mysisfbinfo;
+ BOOL found = FALSE;
+ char name[10];
+
+ i=0;
+ do {
+ sprintf(name, "/dev/fb%1d", i);
+ if((fd = open(name, 'r'))) {
+
+ if(!ioctl(fd, SISFB_GET_INFO, &mysisfbinfo)) {
+
+ if(mysisfbinfo.sisfb_id == SISFB_ID) {
+
+ if((mysisfbinfo.sisfb_version >= 1) &&
+ (mysisfbinfo.sisfb_revision >=5) &&
+ (mysisfbinfo.sisfb_patchlevel >= 8)) {
+ /* TW: Added PCI bus/slot/func into in sisfb Version 1.5.08.
+ Check this to make sure we run on the same card as sisfb
+ */
+ if((mysisfbinfo.sisfb_pcibus == pSiS->PciInfo->bus) &&
+ (mysisfbinfo.sisfb_pcislot == pSiS->PciInfo->device) &&
+ (mysisfbinfo.sisfb_pcifunc == pSiS->PciInfo->func) ) {
+ found = TRUE;
+ }
+ } else found = TRUE;
+
+ if(found) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "%s: SiS kernel fb driver (sisfb) %d.%d.%d detected (PCI: %02d:%02d.%d)\n",
+ &name[5],
+ mysisfbinfo.sisfb_version,
+ mysisfbinfo.sisfb_revision,
+ mysisfbinfo.sisfb_patchlevel,
+ pSiS->PciInfo->bus,
+ pSiS->PciInfo->device,
+ pSiS->PciInfo->func);
+ /* TW: Added version/rev/pl in sisfb 1.4.0 */
+ if(mysisfbinfo.sisfb_version == 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Old version of sisfb found. Please update\n");
+ }
+ pSiS->sisfbMem = mysisfbinfo.heapstart;
+ /* TW: Basically, we can't trust the pdc register if sisfb is loaded */
+ pSiS->donttrustpdc = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "sisfb: memory heap starts at %dKB\n", pSiS->sisfbMem);
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "sisfb: using video mode 0x%02x\n", mysisfbinfo.fbvidmode);
+ if((mysisfbinfo.sisfb_version >= 1) &&
+ (mysisfbinfo.sisfb_revision >=5) &&
+ (mysisfbinfo.sisfb_patchlevel >= 6)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "sisfb: %sreserved hardware cursor, using %s command queue\n",
+ (mysisfbinfo.sisfb_caps & 0x80) ? "" : "not ",
+ (mysisfbinfo.sisfb_caps & 0x40) ? "SiS300 series Turbo" :
+ (mysisfbinfo.sisfb_caps & 0x20) ? "SiS310/325 series AGP" :
+ (mysisfbinfo.sisfb_caps & 0x10) ? "SiS310/325 series VRAM" :
+ (mysisfbinfo.sisfb_caps & 0x08) ? "SiS310/325 series MMIO" :
+ "no");
+ }
+ if((mysisfbinfo.sisfb_version >= 1) &&
+ (mysisfbinfo.sisfb_revision >=5) &&
+ (mysisfbinfo.sisfb_patchlevel >= 10)) {
+ /* TW: We can trust the pdc value if sisfb is of recent version */
+ pSiS->donttrustpdc = FALSE;
+ if(mysisfbinfo.sisfb_patchlevel >= 11) {
+ pSiS->sisfbpdc = mysisfbinfo.sisfb_lcdpdc;
+ }
+ }
+ }
+ }
+ }
+ close (fd);
+ }
+ i++;
+
+ } while((i <= 7) && (!found));
+ }
+
+ /*
+ * The first thing we should figure out is the depth, bpp, etc.
+ * TW: Additionally, determine the size of the HWCursor memory
+ * area.
+ */
+ switch (pSiS->VGAEngine) {
+ case SIS_300_VGA:
+ pSiS->CursorSize = 4096;
+ pix24flags = Support32bppFb |
+ SupportConvert24to32;
+ break;
+ case SIS_315_VGA:
+ pSiS->CursorSize = 16384;
+ pix24flags = Support32bppFb |
+ SupportConvert24to32;
+ break;
+ case SIS_530_VGA:
+ pSiS->CursorSize = 2048;
+ pix24flags = Support32bppFb |
+ Support24bppFb |
+ SupportConvert24to32 |
+ SupportConvert32to24;
+ break;
+ default:
+ pSiS->CursorSize = 2048;
+ pix24flags = Support24bppFb |
+ SupportConvert32to24 |
+ PreferConvert32to24;
+ break;
+ }
+
+#ifdef SISDUALHEAD
+ /* TW: In case of Dual Head, we need to determine if we are the "master" head or
+ * the "slave" head. In order to do that, we set PrimInit to DONE in the
+ * shared entity at the end of the first initialization. The second
+ * initialization then knows that some things have already been done. THIS
+ * ALWAYS ASSUMES THAT THE FIRST DEVICE INITIALIZED IS THE MASTER!
+ */
+
+ if(xf86IsEntityShared(pScrn->entityList[0])) {
+ if(pSiSEnt->lastInstance > 0) {
+ if(!xf86IsPrimInitDone(pScrn->entityList[0])) {
+ /* First Head (always CRT2) */
+ pSiS->SecondHead = FALSE;
+ pSiSEnt->pScrn_1 = pScrn;
+ pSiSEnt->CRT1ModeNo = pSiSEnt->CRT2ModeNo = -1;
+ pSiS->DualHeadMode = TRUE;
+ pSiSEnt->DisableDual = FALSE;
+ pSiSEnt->BIOS = NULL;
+ pSiSEnt->SiS_Pr = NULL;
+ } else {
+ /* Second Head (always CRT1) */
+ pSiS->SecondHead = TRUE;
+ pSiSEnt->pScrn_2 = pScrn;
+ pSiS->DualHeadMode = TRUE;
+ }
+ } else {
+ /* TW: Only one screen in config file - disable dual head mode */
+ pSiS->SecondHead = FALSE;
+ pSiS->DualHeadMode = FALSE;
+ pSiSEnt->DisableDual = TRUE;
+ }
+ } else {
+ /* TW: Entity is not shared - disable dual head mode */
+ pSiS->SecondHead = FALSE;
+ pSiS->DualHeadMode = FALSE;
+ }
+#endif
+
+ pSiS->ForceCursorOff = FALSE;
+
+ /* TW: Allocate SiS_Private (for mode switching code) and initialize it */
+ pSiS->SiS_Pr = NULL;
+#ifdef SISDUALHEAD
+ if(pSiSEnt) {
+ if(pSiSEnt->SiS_Pr) pSiS->SiS_Pr = pSiSEnt->SiS_Pr;
+ }
+#endif
+ if(!pSiS->SiS_Pr) {
+ if(!(pSiS->SiS_Pr = xnfcalloc(sizeof(SiS_Private), 1))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Could not allocate memory for SiS_Pr private\n");
+#ifdef SISDUALHEAD
+ if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
+#endif
+ if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
+ SISFreeRec(pScrn);
+ return FALSE;
+ }
+#ifdef SISDUALHEAD
+ if(pSiSEnt) pSiSEnt->SiS_Pr = pSiS->SiS_Pr;
+#endif
+ memset(pSiS->SiS_Pr, 0, sizeof(SiS_Private));
+ }
+ pSiS->SiS_Pr->SiS_Backup70xx = 0xff;
+ pSiS->SiS_Pr->SiS_CHOverScan = -1;
+ pSiS->SiS_Pr->SiS_ChSW = FALSE;
+ pSiS->SiS_Pr->CRT1UsesCustomMode = FALSE;
+
+ /* TW: Get our relocated IO registers */
+ pSiS->RelIO = (pSiS->PciInfo->ioBase[2] & 0xFFFC) + pSiS->IODBase;
+ pSiS->sishw_ext.ulIOAddress = pSiS->RelIO + 0x30;
+ xf86DrvMsg(pScrn->scrnIndex, from, "Relocated IO registers at 0x%lX\n",
+ (unsigned long)pSiS->RelIO);
+
+ /* TW: Initialize SiS Port Reg definitions for externally used
+ * BIOS emulation (init.c/init301.c) functions.
+ */
+ SiSRegInit(pSiS->SiS_Pr, pSiS->RelIO + 0x30);
+
+ /* TW: The following identifies the old chipsets. This is only
+ * partly used since the really old chips are not supported,
+ * but I keep it here for future use.
+ */
+ if(pSiS->VGAEngine == SIS_OLD_VGA || pSiS->VGAEngine == SIS_530_VGA) {
+ switch(pSiS->Chipset) {
+ case PCI_CHIP_SG86C205: /* Just for making it complete */
+ {
+ unsigned char temp;
+ sisSaveUnlockExtRegisterLock(pSiS, &srlockReg, &crlockReg);
+ inSISIDXREG(SISSR, 0x10, temp);
+ if(temp & 0x80) pSiS->oldChipset = OC_SIS6205B;
+ else pSiS->oldChipset = (pSiS->ChipRev == 0x11) ?
+ OC_SIS6205C : OC_SIS6205A;
+ break;
+ }
+ case PCI_CHIP_SIS82C204: /* Just for making it complete */
+ pSiS->oldChipset = OC_SIS82204; break;
+ case 0x6225: /* Just for making it complete */
+ pSiS->oldChipset = OC_SIS6225; break;
+ case PCI_CHIP_SIS5597:
+ pSiS->oldChipset = OC_SIS5597; break;
+ case PCI_CHIP_SIS6326:
+ pSiS->oldChipset = OC_SIS6326; break;
+ case PCI_CHIP_SIS530:
+ if((pSiS->ChipRev & 0x0f) < 0x0a)
+ pSiS->oldChipset = OC_SIS530A;
+ else pSiS->oldChipset = OC_SIS530B;
+ break;
+ default:
+ pSiS->oldChipset = OC_UNKNOWN;
+ }
+ }
+
+ if(!xf86SetDepthBpp(pScrn, 8, 8, 8, pix24flags)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "xf86SetDepthBpp() error\n");
+#ifdef SISDUALHEAD
+ if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
+#endif
+ if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
+ SISFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /* Check that the returned depth is one we support */
+ temp = 0;
+ switch(pScrn->depth) {
+ case 8:
+ case 16:
+ case 24:
+ break;
+ case 15:
+ if((pSiS->VGAEngine == SIS_300_VGA) ||
+ (pSiS->VGAEngine == SIS_315_VGA))
+ temp = 1;
+ break;
+ default:
+ temp = 1;
+ }
+
+ if(temp) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Given depth (%d) is not supported by this driver/chipset\n",
+ pScrn->depth);
+ if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
+ SISFreeRec(pScrn);
+ return FALSE;
+ }
+
+ xf86PrintDepthBpp(pScrn);
+
+ /* Get the depth24 pixmap format */
+ if(pScrn->depth == 24 && pix24bpp == 0)
+ pix24bpp = xf86GetBppFromDepth(pScrn, 24);
+
+ /*
+ * This must happen after pScrn->display has been set because
+ * xf86SetWeight references it.
+ */
+ if(pScrn->depth > 8) {
+ /* The defaults are OK for us */
+ rgb zeros = {0, 0, 0};
+
+ if(!xf86SetWeight(pScrn, zeros, zeros)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "xf86SetWeight() error\n");
+#ifdef SISDUALHEAD
+ if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
+#endif
+ if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
+ SISFreeRec(pScrn);
+ return FALSE;
+ } else {
+ Bool ret = FALSE;
+ switch(pScrn->depth) {
+ case 15:
+ if((pScrn->weight.red != 5) ||
+ (pScrn->weight.green != 5) ||
+ (pScrn->weight.blue != 5)) ret = TRUE;
+ break;
+ case 16:
+ if((pScrn->weight.red != 5) ||
+ (pScrn->weight.green != 6) ||
+ (pScrn->weight.blue != 5)) ret = TRUE;
+ break;
+ case 24:
+ if((pScrn->weight.red != 8) ||
+ (pScrn->weight.green != 8) ||
+ (pScrn->weight.blue != 8)) ret = TRUE;
+ break;
+ }
+ if(ret) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "RGB Weight %d%d%d at depth %d not supported by hardware\n",
+ pScrn->weight.red, pScrn->weight.green,
+ pScrn->weight.blue, pScrn->depth);
+#ifdef SISDUALHEAD
+ if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
+#endif
+ if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
+ SISFreeRec(pScrn);
+ return FALSE;
+ }
+ }
+ }
+
+ /* TW: Set the current layout parameters */
+ pSiS->CurrentLayout.bitsPerPixel = pScrn->bitsPerPixel;
+ pSiS->CurrentLayout.depth = pScrn->depth;
+ /* (Inside this function, we can use pScrn's contents anyway) */
+
+ if(!xf86SetDefaultVisual(pScrn, -1)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "xf86SetDefaultVisual() error\n");
+#ifdef SISDUALHEAD
+ if (pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
+#endif
+ if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
+ SISFreeRec(pScrn);
+ return FALSE;
+ } else {
+ /* We don't support DirectColor at > 8bpp */
+ if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual "
+ "(%s) is not supported at depth %d\n",
+ xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
+#ifdef SISDUALHEAD
+ if (pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
+#endif
+ if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
+ SISFreeRec(pScrn);
+ return FALSE;
+ }
+ }
+
+ /*
+ * The cmap layer needs this to be initialised.
+ */
+ {
+ Gamma zeros = {0.0, 0.0, 0.0};
+
+ if(!xf86SetGamma(pScrn, zeros)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "xf86SetGamma() error\n");
+#ifdef SISDUALHEAD
+ if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
+#endif
+ if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
+ SISFreeRec(pScrn);
+ return FALSE;
+ }
+ }
+
+ /* We use a programamble clock */
+ pScrn->progClock = TRUE;
+
+ /* Set the bits per RGB for 8bpp mode */
+ if(pScrn->depth == 8) {
+ pScrn->rgbBits = 6;
+ }
+
+ pSiS->ddc1Read = SiSddc1Read;
+
+ from = X_DEFAULT;
+
+ /* Unlock registers */
+ sisSaveUnlockExtRegisterLock(pSiS, &srlockReg, &crlockReg);
+
+ /* TW: We need no backup area (300/310/325 new mode switching code) */
+ pSiS->sishw_ext.pSR = NULL;
+ pSiS->sishw_ext.pCR = NULL;
+
+ /* TW: Read BIOS for 300 and 310/325 series customization */
+ pSiS->sishw_ext.pjVirtualRomBase = NULL;
+ pSiS->BIOS = NULL;
+ pSiS->sishw_ext.UseROM = FALSE;
+
+ if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
+#ifdef SISDUALHEAD
+ if(pSiSEnt) {
+ if(pSiSEnt->BIOS) {
+ pSiS->BIOS = pSiSEnt->BIOS;
+ pSiS->sishw_ext.pjVirtualRomBase = pSiS->BIOS;
+ }
+ }
+#endif
+ if(!pSiS->BIOS) {
+ if(!(pSiS->BIOS = xcalloc(1, BIOS_SIZE))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Could not allocate memory for video BIOS image\n");
+ } else {
+ unsigned long segstart;
+ unsigned short romptr;
+ BOOLEAN found;
+ int i;
+ static const char sis_rom_sig[] = "Silicon Integrated Systems";
+ static const char *sis_sig[10] = {
+ "300", "540", "630", "730",
+ "315", "315", "315", "5315", "6325",
+ "Xabre"
+ };
+ static const unsigned short sis_nums[10] = {
+ SIS_300, SIS_540, SIS_630, SIS_730,
+ SIS_315PRO, SIS_315H, SIS_315, SIS_550, SIS_650,
+ SIS_330
+ };
+
+ found = FALSE;
+ for(segstart=BIOS_BASE; segstart<0x000f0000; segstart+=0x00001000) {
+
+#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,99,0,0)
+ if(xf86ReadBIOS(segstart, 0, pSiS->BIOS, BIOS_SIZE) != BIOS_SIZE) continue;
+#else
+ if(xf86ReadDomainMemory(pSiS->PciTag, segstart, BIOS_SIZE, pSiS->BIOS) != BIOS_SIZE) continue;
+#endif
+
+ if((pSiS->BIOS[0] != 0x55) || (pSiS->BIOS[1] != 0xaa)) continue;
+
+ romptr = pSiS->BIOS[0x12] | (pSiS->BIOS[0x13] << 8);
+ if(romptr > (BIOS_SIZE - strlen(sis_rom_sig))) continue;
+ if(strncmp(sis_rom_sig, (char *)&pSiS->BIOS[romptr], strlen(sis_rom_sig)) != 0) continue;
+
+ romptr = pSiS->BIOS[0x14] | (pSiS->BIOS[0x15] << 8);
+ if(romptr > (BIOS_SIZE - 5)) continue;
+ for(i = 0; (i < 10) && (!found); i++) {
+ if(strncmp(sis_sig[i], (char *)&pSiS->BIOS[romptr], strlen(sis_sig[i])) == 0) {
+ if(sis_nums[i] == pSiS->sishw_ext.jChipType) {
+ found = TRUE;
+ break;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Ignoring BIOS for SiS %s at %p\n", sis_sig[i], segstart);
+ }
+ }
+ }
+ if(found) break;
+ }
+
+ if(!found) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Could not find/read video BIOS\n");
+ xfree(pSiS->BIOS);
+ pSiS->BIOS = NULL;
+ } else {
+#ifdef SISDUALHEAD
+ if(pSiSEnt) pSiSEnt->BIOS = pSiS->BIOS;
+#endif
+ pSiS->sishw_ext.pjVirtualRomBase = pSiS->BIOS;
+ romptr = pSiS->BIOS[0x16] | (pSiS->BIOS[0x17] << 8);
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Video BIOS version \"%7s\" found at %p\n",
+ &pSiS->BIOS[romptr], segstart);
+ }
+
+ }
+ }
+ if(pSiS->BIOS) pSiS->sishw_ext.UseROM = TRUE;
+ else pSiS->sishw_ext.UseROM = FALSE;
+ }
+
+ /* Evaluate options */
+ SiSOptions(pScrn);
+
+#ifdef SISDUALHEAD
+ if(pSiS->DualHeadMode) {
+ if(!pSiS->SecondHead) {
+ /* TW: Copy some option settings to entity private */
+ pSiSEnt->HWCursor = pSiS->HWCursor;
+ pSiSEnt->ForceCRT2Type = pSiS->ForceCRT2Type;
+ pSiSEnt->ForceTVType = pSiS->ForceTVType;
+ pSiSEnt->TurboQueue = pSiS->TurboQueue;
+ pSiSEnt->PDC = pSiS->PDC;
+ pSiSEnt->OptTVStand = pSiS->OptTVStand;
+ pSiSEnt->NonDefaultPAL = pSiS->NonDefaultPAL;
+ pSiSEnt->OptTVOver = pSiS->OptTVOver;
+ pSiSEnt->OptTVSOver = pSiS->OptTVSOver;
+ pSiSEnt->OptROMUsage = pSiS->OptROMUsage;
+ pSiSEnt->DSTN = pSiS->DSTN;
+ pSiSEnt->XvOnCRT2 = pSiS->XvOnCRT2;
+ pSiSEnt->NoAccel = pSiS->NoAccel;
+ pSiSEnt->NoXvideo = pSiS->NoXvideo;
+ pSiSEnt->forceCRT1 = pSiS->forceCRT1;
+ pSiSEnt->chtvlumabandwidthcvbs = pSiS->chtvlumabandwidthcvbs;
+ pSiSEnt->chtvlumabandwidthsvideo = pSiS->chtvlumabandwidthsvideo;
+ pSiSEnt->chtvlumaflickerfilter = pSiS->chtvlumaflickerfilter;
+ pSiSEnt->chtvchromabandwidth = pSiS->chtvchromabandwidth;
+ pSiSEnt->chtvchromaflickerfilter = pSiS->chtvchromaflickerfilter;
+ pSiSEnt->chtvtextenhance = pSiS->chtvtextenhance;
+ pSiSEnt->chtvcontrast = pSiS->chtvcontrast;
+ pSiSEnt->chtvcvbscolor = pSiS->chtvcvbscolor;
+ pSiSEnt->sistvedgeenhance = pSiS->sistvedgeenhance;
+ pSiSEnt->sistvantiflicker = pSiS->sistvantiflicker;
+ pSiSEnt->sistvsaturation = pSiS->sistvsaturation;
+ pSiSEnt->tvxpos = pSiS->tvxpos;
+ pSiSEnt->tvypos = pSiS->tvypos;
+ pSiSEnt->restorebyset = pSiS->restorebyset;
+ } else {
+ /* We always use same cursor type on both screens */
+ if(pSiS->HWCursor != pSiSEnt->HWCursor) {
+ pSiS->HWCursor = pSiSEnt->HWCursor;
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Ignoring inconsistent HWCursor setting\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Master head ruled: HWCursor shall be %s\n",
+ pSiS->HWCursor ? "enabled" : "disabled");
+ }
+ /* We need to use identical CRT2 Type setting */
+ if(pSiS->ForceCRT2Type != pSiSEnt->ForceCRT2Type) {
+ if(pSiS->ForceCRT2Type != CRT2_DEFAULT) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Ignoring inconsistent ForceCRT2Type setting. Master head rules\n");
+ }
+ pSiS->ForceCRT2Type = pSiSEnt->ForceCRT2Type;
+ }
+ if(pSiS->ForceTVType != pSiSEnt->ForceTVType) {
+ if(pSiS->ForceTVType != -1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Ignoring inconsistent ForceTVType setting. Master head rules\n");
+ }
+ pSiS->ForceTVType = pSiSEnt->ForceTVType;
+ }
+ /* We need identical TurboQueue setting */
+ if(pSiS->TurboQueue != pSiSEnt->TurboQueue) {
+ pSiS->TurboQueue = pSiSEnt->TurboQueue;
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Ignoring inconsistent TurboQueue setting\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Master head ruled: Turboqueue shall be %s\n",
+ pSiS->TurboQueue ? "enabled" : "disabled");
+ }
+ /* We need identical PDC setting */
+ if(pSiS->PDC != pSiSEnt->PDC) {
+ pSiS->PDC = pSiSEnt->PDC;
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Ignoring inconsistent PanelDelayCompensation setting\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Master head ruled: PanelDelayCompensation shall be %d%s\n",
+ pSiS->PDC,
+ (pSiS->PDC == -1) ? " (autodetected)" : "");
+ }
+ /* We need identical TVStandard setting */
+ if( (pSiS->OptTVStand != pSiSEnt->OptTVStand) ||
+ (pSiS->NonDefaultPAL != pSiSEnt->NonDefaultPAL) ) {
+ if(pSiS->OptTVStand != -1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Ignoring inconsistent TVStandard setting\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Master head ruled: TVStandard shall be %s\n",
+ (pSiSEnt->OptTVStand ?
+ ( (pSiSEnt->NonDefaultPAL == -1) ? "PAL" :
+ ((pSiSEnt->NonDefaultPAL) ? "PALM" : "PALN") )
+ : "NTSC"));
+ }
+ pSiS->OptTVStand = pSiSEnt->OptTVStand;
+ pSiS->NonDefaultPAL = pSiSEnt->NonDefaultPAL;
+ }
+ /* We need identical UseROMData setting */
+ if(pSiS->OptROMUsage != pSiSEnt->OptROMUsage) {
+ if(pSiS->OptROMUsage != -1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Ignoring inconsistent UseROMData setting\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Master head ruled: Video ROM data usage shall be %s\n",
+ pSiSEnt->OptROMUsage ? "enabled" : "disabled");
+ }
+ pSiS->OptROMUsage = pSiSEnt->OptROMUsage;
+ }
+ /* We need identical DSTN setting */
+ if(pSiS->DSTN != pSiSEnt->DSTN) {
+ pSiS->DSTN = pSiSEnt->DSTN;
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Ignoring inconsistent DSTN setting\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Master head ruled: DSTN shall be %s\n",
+ pSiS->DSTN ? "enabled" : "disabled");
+ }
+ /* We need identical XvOnCRT2 setting */
+ if(pSiS->XvOnCRT2 != pSiSEnt->XvOnCRT2) {
+ pSiS->XvOnCRT2 = pSiSEnt->XvOnCRT2;
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Ignoring inconsistent XvOnCRT2 setting\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Master head ruled: Xv shall be used on CRT%d\n",
+ pSiS->XvOnCRT2 ? 2 : 1);
+ }
+ /* We need identical NoAccel setting */
+ if(pSiS->NoAccel != pSiSEnt->NoAccel) {
+ pSiS->NoAccel = pSiSEnt->NoAccel;
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Ignoring inconsistent NoAccel setting\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Master head ruled: Acceleration shall be %s\n",
+ pSiS->NoAccel ? "disabled" : "enabled");
+ }
+ /* We need identical ForceCRT1 setting */
+ if(pSiS->forceCRT1 != pSiSEnt->forceCRT1) {
+ if(pSiS->forceCRT1 != -1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Ignoring inconsistent ForceCRT1 setting\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Master head ruled: CRT1 shall be %s\n",
+ pSiSEnt->forceCRT1 ? "enabled" : "disabled");
+ }
+ pSiS->forceCRT1 = pSiSEnt->forceCRT1;
+ }
+ /* We need identical TVOverscan setting */
+ if(pSiS->OptTVOver != pSiSEnt->OptTVOver) {
+ if(pSiS->OptTVOver != -1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Ignoring inconsistent CHTVOverscan setting\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Master head ruled: CHTVOverscan shall be %s\n",
+ pSiSEnt->OptTVOver ? "true (=overscan)" : "false (=underscan)");
+ }
+ pSiS->OptTVOver = pSiSEnt->OptTVOver;
+ }
+ /* We need identical TVSOverscan setting */
+ if(pSiS->OptTVSOver != pSiSEnt->OptTVSOver) {
+ if(pSiS->OptTVSOver != -1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Ignoring inconsistent CHTVSuperOverscan setting\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Master head ruled: CHTVSuperOverscan shall be %s\n",
+ pSiSEnt->OptTVSOver ? "true" : "false");
+ }
+ pSiS->OptTVSOver = pSiSEnt->OptTVSOver;
+ }
+ /* We need identical TV settings */
+ if(pSiS->chtvtype != pSiSEnt->chtvtype) {
+ if(pSiS->chtvtype != -1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Ignoring inconsistent CHTVType setting; set to %s\n",
+ (pSiSEnt->chtvtype) ? "SCART" : "HDTV");
+ }
+ pSiS->chtvtype = pSiSEnt->chtvtype;
+ }
+ if(pSiS->chtvlumabandwidthcvbs != pSiSEnt->chtvlumabandwidthcvbs) {
+ if(pSiS->chtvlumabandwidthcvbs != -1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Ignoring inconsistent CHTVLumaBandWidthCVBS setting; set to %d\n",
+ pSiSEnt->chtvlumabandwidthcvbs);
+ }
+ pSiS->chtvlumabandwidthcvbs = pSiSEnt->chtvlumabandwidthcvbs;
+ }
+ if(pSiS->chtvlumabandwidthsvideo != pSiSEnt->chtvlumabandwidthsvideo) {
+ if(pSiS->chtvlumabandwidthsvideo != -1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Ignoring inconsistent CHTVLumaBandWidthSVIDEO setting; set to %d\n",
+ pSiSEnt->chtvlumabandwidthsvideo);
+ }
+ pSiS->chtvlumabandwidthsvideo = pSiSEnt->chtvlumabandwidthsvideo;
+ }
+ if(pSiS->chtvlumaflickerfilter != pSiSEnt->chtvlumaflickerfilter) {
+ if(pSiS->chtvlumaflickerfilter != -1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Ignoring inconsistent CHTVLumaFlickerFilter setting; set to %d\n",
+ pSiSEnt->chtvlumaflickerfilter);
+ }
+ pSiS->chtvlumaflickerfilter = pSiSEnt->chtvlumaflickerfilter;
+ }
+ if(pSiS->chtvchromabandwidth != pSiSEnt->chtvchromabandwidth) {
+ if(pSiS->chtvchromabandwidth != -1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Ignoring inconsistent CHTVChromaBandWidth setting; set to %d\n",
+ pSiSEnt->chtvchromabandwidth);
+ }
+ pSiS->chtvchromabandwidth = pSiSEnt->chtvchromabandwidth;
+ }
+ if(pSiS->chtvchromaflickerfilter != pSiSEnt->chtvchromaflickerfilter) {
+ if(pSiS->chtvchromaflickerfilter != -1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Ignoring inconsistent CHTVChromaFlickerFilter setting; set to %d\n",
+ pSiSEnt->chtvchromaflickerfilter);
+ }
+ pSiS->chtvchromaflickerfilter = pSiSEnt->chtvchromaflickerfilter;
+ }
+ if(pSiS->chtvcvbscolor != pSiSEnt->chtvcvbscolor) {
+ if(pSiS->chtvcvbscolor != -1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Ignoring inconsistent CHTVCVBSColor setting; set to %s\n",
+ pSiSEnt->chtvcvbscolor ? "true" : "false");
+ }
+ pSiS->chtvcvbscolor = pSiSEnt->chtvcvbscolor;
+ }
+ if(pSiS->chtvtextenhance != pSiSEnt->chtvtextenhance) {
+ if(pSiS->chtvtextenhance != -1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Ignoring inconsistent CHTVTextEnhance setting; set to %d\n",
+ pSiSEnt->chtvtextenhance);
+ }
+ pSiS->chtvtextenhance = pSiSEnt->chtvtextenhance;
+ }
+ if(pSiS->chtvcontrast != pSiSEnt->chtvcontrast) {
+ if(pSiS->chtvcontrast != -1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Ignoring inconsistent CHTVContrast setting; set to %d\n",
+ pSiSEnt->chtvcontrast);
+ }
+ pSiS->chtvcontrast = pSiSEnt->chtvcontrast;
+ }
+ if(pSiS->sistvedgeenhance != pSiSEnt->sistvedgeenhance) {
+ if(pSiS->sistvedgeenhance != -1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Ignoring inconsistent SISTVEdgeEnhance setting; set to %d\n",
+ pSiSEnt->sistvedgeenhance);
+ }
+ pSiS->sistvedgeenhance = pSiSEnt->sistvedgeenhance;
+ }
+ if(pSiS->sistvantiflicker != pSiSEnt->sistvantiflicker) {
+ if(pSiS->sistvantiflicker != -1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Ignoring inconsistent SISTVAntiFlicker setting; set to %d\n",
+ pSiSEnt->sistvantiflicker);
+ }
+ pSiS->sistvantiflicker = pSiSEnt->sistvantiflicker;
+ }
+ if(pSiS->sistvsaturation != pSiSEnt->sistvsaturation) {
+ if(pSiS->sistvsaturation != -1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Ignoring inconsistent SISTVSaturation setting; set to %d\n",
+ pSiSEnt->sistvsaturation);
+ }
+ pSiS->sistvsaturation = pSiSEnt->sistvsaturation;
+ }
+ if(pSiS->tvxpos != pSiSEnt->tvxpos) {
+ if(pSiS->tvxpos != 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Ignoring inconsistent TVXPosOffset setting; set to %d\n",
+ pSiSEnt->tvxpos);
+ }
+ pSiS->tvxpos = pSiSEnt->tvxpos;
+ }
+ if(pSiS->tvypos != pSiSEnt->tvypos) {
+ if(pSiS->tvypos != 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Ignoring inconsistent TVYPosOffset setting; set to %d\n",
+ pSiSEnt->tvypos);
+ }
+ pSiS->tvypos = pSiSEnt->tvypos;
+ }
+ if(pSiS->restorebyset != pSiSEnt->restorebyset) {
+ pSiS->restorebyset = pSiSEnt->restorebyset;
+ }
+ }
+ }
+#endif
+ /* TW: Handle UseROMData and NoOEM options */
+ if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
+ from = X_PROBED;
+ if(pSiS->OptROMUsage == 0) {
+ pSiS->sishw_ext.UseROM = FALSE;
+ from = X_CONFIG;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Video ROM data usage is %s\n",
+ pSiS->sishw_ext.UseROM ? "enabled" : "disabled");
+
+ if(!pSiS->OptUseOEM)
+ xf86DrvMsg(pScrn->scrnIndex, from, "Internal OEM LCD/TV data usage is disabled\n");
+
+ if(pSiS->sbiosn) {
+ if(pSiS->BIOS) {
+ FILE *fd = NULL;
+ int i;
+ if((fd = fopen(pSiS->sbiosn, "w" ))) {
+ i = fwrite(pSiS->BIOS, 65536, 1, fd);
+ fclose(fd);
+ }
+ }
+ xfree(pSiS->sbiosn);
+ }
+ }
+
+ /* Do basic configuration */
+ SiSSetup(pScrn);
+
+ from = X_PROBED;
+ if (pSiS->pEnt->device->MemBase != 0) {
+ /*
+ * XXX Should check that the config file value matches one of the
+ * PCI base address values.
+ */
+ pSiS->FbAddress = pSiS->pEnt->device->MemBase;
+ from = X_CONFIG;
+ } else {
+ pSiS->FbAddress = pSiS->PciInfo->memBase[0] & 0xFFFFFFF0;
+ }
+
+ pSiS->realFbAddress = pSiS->FbAddress;
+
+#ifdef SISDUALHEAD
+ if(pSiS->DualHeadMode)
+ xf86DrvMsg(pScrn->scrnIndex, from, "Global linear framebuffer at 0x%lX\n",
+ (unsigned long)pSiS->FbAddress);
+ else
+#endif
+ xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n",
+ (unsigned long)pSiS->FbAddress);
+
+ if (pSiS->pEnt->device->IOBase != 0) {
+ /*
+ * XXX Should check that the config file value matches one of the
+ * PCI base address values.
+ */
+ pSiS->IOAddress = pSiS->pEnt->device->IOBase;
+ from = X_CONFIG;
+ } else {
+ pSiS->IOAddress = pSiS->PciInfo->memBase[1] & 0xFFFFFFF0;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "MMIO registers at 0x%lX\n",
+ (unsigned long)pSiS->IOAddress);
+ pSiS->sishw_ext.bIntegratedMMEnabled = TRUE;
+
+ /* Register the PCI-assigned resources. */
+ if(xf86RegisterResources(pSiS->pEnt->index, NULL, ResExclusive)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "xf86RegisterResources() found resource conflicts\n");
+#ifdef SISDUALHEAD
+ if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
+#endif
+ if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
+ sisRestoreExtRegisterLock(pSiS,srlockReg,crlockReg);
+ SISFreeRec(pScrn);
+ return FALSE;
+ }
+
+ from = X_PROBED;
+ if (pSiS->pEnt->device->videoRam != 0) {
+ pScrn->videoRam = pSiS->pEnt->device->videoRam;
+ from = X_CONFIG;
+ }
+
+ pSiS->RealVideoRam = pScrn->videoRam;
+ if((pSiS->Chipset == PCI_CHIP_SIS6326)
+ && (pScrn->videoRam > 4096)
+ && (from != X_CONFIG)) {
+ pScrn->videoRam = 4096;
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "SiS6326: Detected %d KB VideoRAM, limiting to %d KB\n",
+ pSiS->RealVideoRam, pScrn->videoRam);
+ } else
+ xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d KB\n",
+ pScrn->videoRam);
+
+ if((pSiS->Chipset == PCI_CHIP_SIS6326) &&
+ (pScrn->videoRam > 4096)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "SiS6326 engines do not support more than 4096KB RAM, therefore\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "TurboQueue, HWCursor, 2D acceleration and XVideo are disabled.\n");
+ pSiS->TurboQueue = FALSE;
+ pSiS->HWCursor = FALSE;
+ pSiS->NoXvideo = TRUE;
+ pSiS->NoAccel = TRUE;
+ }
+
+ pSiS->FbMapSize = pSiS->availMem = pScrn->videoRam * 1024;
+ pSiS->sishw_ext.ulVideoMemorySize = pScrn->videoRam * 1024;
+ pSiS->sishw_ext.bSkipDramSizing = TRUE;
+
+ /* TW: Calculate real availMem according to Accel/TurboQueue and
+ * HWCursur setting. Also, initialize some variables used
+ * in other modules.
+ */
+ pSiS->cursorOffset = 0;
+ switch (pSiS->VGAEngine) {
+ case SIS_300_VGA:
+ pSiS->TurboQueueLen = 512;
+ if(pSiS->TurboQueue) {
+ pSiS->availMem -= (pSiS->TurboQueueLen*1024);
+ pSiS->cursorOffset = 512;
+ }
+ if(pSiS->HWCursor) {
+ pSiS->availMem -= pSiS->CursorSize;
+ if(pSiS->OptUseColorCursor) pSiS->availMem -= pSiS->CursorSize;
+ }
+ pSiS->CmdQueLenMask = 0xFFFF;
+ pSiS->CmdQueLenFix = 0;
+ pSiS->cursorBufferNum = 0;
+#ifdef SISDUALHEAD
+ if(pSiSEnt) pSiSEnt->cursorBufferNum = 0;
+#endif
+ break;
+ case SIS_315_VGA:
+ if(pSiS->TurboQueue) {
+ pSiS->availMem -= (512*1024); /* Command Queue is 512k */
+ pSiS->cursorOffset = 512;
+ }
+ if(pSiS->HWCursor) {
+ pSiS->availMem -= pSiS->CursorSize;
+ if(pSiS->OptUseColorCursor) pSiS->availMem -= pSiS->CursorSize;
+ }
+ pSiS->cursorBufferNum = 0;
+#ifdef SISDUALHEAD
+ if(pSiSEnt) pSiSEnt->cursorBufferNum = 0;
+#endif
+ break;
+ default:
+ /* TW: cursorOffset not used in cursor functions for 530 and
+ * older chips, because the cursor is *above* the TQ.
+ * On 5597 and older revisions of the 6326, the TQ is
+ * max 32K, on newer 6326 revisions and the 530 either 30
+ * (or 32?) or 62K (or 64?). However, to make sure, we
+ * use only 30K (or 32?), but reduce the available memory
+ * by 64, and locate the TQ at the beginning of this last
+ * 64K block. (We do this that way even when using the
+ * HWCursor, because the cursor only takes 2K, and the queue
+ * does not seem to last that far anyway.)
+ * The TQ must be located at 32KB boundaries.
+ */
+ if(pSiS->RealVideoRam < 3072) {
+ if(pSiS->TurboQueue) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Not enough video RAM for TurboQueue. TurboQueue disabled\n");
+ }
+ pSiS->TurboQueue = FALSE;
+ }
+ pSiS->CmdQueMaxLen = 32;
+ if(pSiS->TurboQueue) {
+ pSiS->availMem -= (64*1024);
+ pSiS->CmdQueMaxLen = 900; /* TW: To make sure; should be 992 */
+ } else if (pSiS->HWCursor) {
+ pSiS->availMem -= pSiS->CursorSize;
+ }
+ if(pSiS->Chipset == PCI_CHIP_SIS530) {
+ /* TW: Check if Flat Panel is enabled */
+ inSISIDXREG(SISSR, 0x0e, tempreg);
+ if(!tempreg & 0x04) pSiS->availMem -= pSiS->CursorSize;
+
+ /* TW: Set up mask for MMIO register */
+ pSiS->CmdQueLenMask = (pSiS->TurboQueue) ? 0x1FFF : 0x00FF;
+ } else {
+ /* TW: TQ is never used on 6326/5597, because the accelerator
+ * always Syncs. So this is just cosmentic work. (And I
+ * am not even sure that 0x7fff is correct. MMIO 0x83a8
+ * holds 0xec0 if (30k) TQ is enabled, 0x20 if TQ disabled.
+ * The datasheet has no real explanation on the queue length
+ * if the TQ is enabled. Not syncing and waiting for a
+ * suitable queue length instead does not work.
+ */
+ pSiS->CmdQueLenMask = (pSiS->TurboQueue) ? 0x7FFF : 0x003F;
+ }
+
+ /* TW: This is to be subtracted from MMIO queue length register contents
+ * for getting the real Queue length.
+ */
+ pSiS->CmdQueLenFix = (pSiS->TurboQueue) ? 32 : 0;
+ }
+
+#ifdef SISDUALHEAD
+ /* TW: In dual head mode, we share availMem equally - so align it
+ * to 8KB; this way, the address of the FB of the second
+ * head is aligned to 4KB for mapping.
+ */
+ if (pSiS->DualHeadMode)
+ pSiS->availMem &= 0xFFFFE000;
+#endif
+
+ /* TW: Check MaxXFBMem setting */
+#ifdef SISDUALHEAD
+ /* TW: Since DRI is not supported in dual head mode, we
+ don't need MaxXFBMem setting. */
+ if (pSiS->DualHeadMode) {
+ if(pSiS->maxxfbmem) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "MaxXFBMem not used in Dual Head mode. Using all VideoRAM.\n");
+ }
+ pSiS->maxxfbmem = pSiS->availMem;
+ } else
+#endif
+ if (pSiS->maxxfbmem) {
+ if (pSiS->maxxfbmem > pSiS->availMem) {
+ if (pSiS->sisfbMem) {
+ pSiS->maxxfbmem = pSiS->sisfbMem * 1024;
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Invalid MaxXFBMem setting. Using sisfb heap start information\n");
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Invalid MaxXFBMem setting. Using all VideoRAM for framebuffer\n");
+ pSiS->maxxfbmem = pSiS->availMem;
+ }
+ } else if (pSiS->sisfbMem) {
+ if (pSiS->maxxfbmem > pSiS->sisfbMem * 1024) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "MaxXFBMem beyond sisfb heap start. Using sisfb heap start information\n");
+ pSiS->maxxfbmem = pSiS->sisfbMem * 1024;
+ }
+ }
+ } else if (pSiS->sisfbMem) {
+ pSiS->maxxfbmem = pSiS->sisfbMem * 1024;
+ }
+ else pSiS->maxxfbmem = pSiS->availMem;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using %dK of framebuffer memory\n",
+ pSiS->maxxfbmem / 1024);
+
+ /* TW: Check if the chipset supports two video overlays */
+ pSiS->Flags650 = 0;
+ if ( (!pSiS->NoXvideo) &&
+ ( pSiS->VGAEngine == SIS_300_VGA ||
+ pSiS->VGAEngine == SIS_315_VGA ||
+ pSiS->Chipset == PCI_CHIP_SIS530 ||
+ pSiS->Chipset == PCI_CHIP_SIS6326 ||
+ pSiS->Chipset == PCI_CHIP_SIS5597 ) ) {
+ pSiS->hasTwoOverlays = FALSE;
+ switch (pSiS->Chipset) {
+ case PCI_CHIP_SIS300:
+ case PCI_CHIP_SIS630:
+ case PCI_CHIP_SIS550:
+ case PCI_CHIP_SIS330: /* ? */
+ pSiS->hasTwoOverlays = TRUE;
+ break;
+ case PCI_CHIP_SIS650:
+ {
+ static const char *id650str[] = {
+ "0", "0", "0", "0",
+ "0 A0 AA", "0 A2 CA", "0", "0",
+ "0M A0", "0M A1 AA", "1 A0 AA", "1 A1 AA"
+ "0", "0", "0", "0"
+ };
+ inSISIDXREG(SISCR, 0x5F, CR5F);
+ CR5F &= 0xf0;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "SiS650 revision ID %x (SiS65%s)\n", CR5F, id650str[CR5F >> 4]);
+ if((CR5F == 0x80) || (CR5F == 0x90) || (CR5F == 0xa0) || (CR5F == 0xb0)) {
+ pSiS->hasTwoOverlays = TRUE; /* TW: This is an M650 or 651 */
+ pSiS->Flags650 |= SiS650_LARGEOVERLAY;
+ }
+ break;
+ }
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Hardware supports %s video overlay%s\n",
+ pSiS->hasTwoOverlays ? "two" : "one",
+ pSiS->hasTwoOverlays ? "s" : "");
+ }
+
+ /* TW: Backup VB connection and CRT1 on/off register */
+ if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
+ inSISIDXREG(SISCR, 0x32, pSiS->oldCR32);
+ inSISIDXREG(SISCR, 0x17, pSiS->oldCR17);
+ pSiS->postVBCR32 = pSiS->oldCR32;
+ }
+
+ if(pSiS->forceCRT1 != -1) {
+ if(pSiS->forceCRT1) pSiS->CRT1off = 0;
+ else pSiS->CRT1off = 1;
+ } else pSiS->CRT1off = -1;
+
+ /* TW: There are some strange machines out there which require a special
+ * manupulation of ISA bridge registers in order to make the Chrontel
+ * work. Try to find out if we're running on such a machine.
+ */
+ pSiS->SiS_Pr->SiS_ChSW = FALSE;
+ if(pSiS->Chipset == PCI_CHIP_SIS630) {
+ int i=0;
+ do {
+ if(mychswtable[i].subsysVendor == pSiS->PciInfo->subsysVendor &&
+ mychswtable[i].subsysCard == pSiS->PciInfo->subsysCard) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "PCI card/vendor found in list for Chrontel/ISA bridge poking\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Vendor: %s (ID %04x)\n",
+ mychswtable[i].vendorName, pSiS->PciInfo->subsysCard);
+ pSiS->SiS_Pr->SiS_ChSW = TRUE;
+ }
+ i++;
+ } while(mychswtable[i].subsysVendor != 0);
+ }
+
+ /* TW: Detect video bridge and sense connected devices */
+ SISVGAPreInit(pScrn);
+ /* TW: Detect CRT1 */
+ SISCRT1PreInit(pScrn);
+ /* TW: Detect CRT2-LCD and LCD size */
+ SISLCDPreInit(pScrn);
+ /* TW: Detect CRT2-TV and PAL/NTSC mode */
+ SISTVPreInit(pScrn);
+ /* TW: Detect CRT2-VGA */
+ SISCRT2PreInit(pScrn);
+
+ /* TW: Backup detected CRT2 devices */
+ pSiS->detectedCRT2Devices = pSiS->VBFlags & (CRT2_LCD | CRT2_TV | CRT2_VGA);
+
+ /* TW: Eventually overrule detected CRT2 type */
+ if(pSiS->ForceCRT2Type == CRT2_DEFAULT) {
+ if(pSiS->VBFlags & CRT2_VGA)
+ pSiS->ForceCRT2Type = CRT2_VGA;
+ else if(pSiS->VBFlags & CRT2_LCD)
+ pSiS->ForceCRT2Type = CRT2_LCD;
+ else if(pSiS->VBFlags & CRT2_TV)
+ pSiS->ForceCRT2Type = CRT2_TV;
+ }
+
+ switch(pSiS->ForceCRT2Type) {
+ case CRT2_TV:
+ pSiS->VBFlags = pSiS->VBFlags & ~(CRT2_LCD | CRT2_VGA);
+ if(pSiS->VBFlags & VB_VIDEOBRIDGE)
+ pSiS->VBFlags = pSiS->VBFlags | CRT2_TV;
+ else
+ pSiS->VBFlags = pSiS->VBFlags & ~(CRT2_TV);
+ break;
+ case CRT2_LCD:
+ pSiS->VBFlags = pSiS->VBFlags & ~(CRT2_TV | CRT2_VGA);
+ if((pSiS->VBFlags & VB_VIDEOBRIDGE) && (pSiS->VBLCDFlags))
+ pSiS->VBFlags = pSiS->VBFlags | CRT2_LCD;
+ else {
+ pSiS->VBFlags = pSiS->VBFlags & ~(CRT2_LCD);
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Can't force CRT2 to LCD, no panel detected\n");
+ }
+ break;
+ case CRT2_VGA:
+ if(pSiS->VBFlags & VB_LVDS) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "LVDS does not support secondary VGA\n");
+ break;
+ }
+ if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "SiS30xLV bridge does not support secondary VGA\n");
+ break;
+ }
+ pSiS->VBFlags = pSiS->VBFlags & ~(CRT2_TV | CRT2_LCD);
+ if(pSiS->VBFlags & VB_VIDEOBRIDGE)
+ pSiS->VBFlags = pSiS->VBFlags | CRT2_VGA;
+ else
+ pSiS->VBFlags = pSiS->VBFlags & ~(CRT2_VGA);
+ break;
+ default:
+ pSiS->VBFlags &= ~(CRT2_TV | CRT2_LCD | CRT2_VGA);
+ }
+
+ /* TW: Eventually overrule TV Type (SVIDEO, COMPOSITE, SCART) */
+ if(pSiS->ForceTVType != -1) {
+ if(pSiS->VBFlags & VB_SISBRIDGE) {
+ pSiS->VBFlags &= ~(TV_INTERFACE);
+ pSiS->VBFlags |= pSiS->ForceTVType;
+ }
+ }
+
+ /* TW: Handle ForceCRT1 option */
+ pSiS->CRT1changed = FALSE;
+ if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
+ usScratchCR17 = pSiS->oldCR17;
+ usScratchCR32 = pSiS->postVBCR32;
+ if(pSiS->VESA != 1) {
+ /* TW: Copy forceCRT1 option to CRT1off if option is given */
+#ifdef SISDUALHEAD
+ /* TW: In DHM, handle this option only for master head, not the slave */
+ if( (pSiS->forceCRT1 != -1) &&
+ (!(pSiS->DualHeadMode && pSiS->SecondHead)) ) {
+#else
+ if(pSiS->forceCRT1 != -1) {
+#endif
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "CRT1 detection overruled by ForceCRT1 option\n");
+ if(pSiS->forceCRT1) {
+ pSiS->CRT1off = 0;
+ if (!(usScratchCR17 & 0x80)) pSiS->CRT1changed = TRUE;
+ usScratchCR17 |= 0x80;
+ usScratchCR32 |= 0x20;
+ } else {
+ if( ! ( (pScrn->bitsPerPixel == 8) &&
+ ( (pSiS->VBFlags & VB_LVDS) ||
+ ((pSiS->VGAEngine == SIS_300_VGA) && (pSiS->VBFlags & VB_301B)) ) ) ) {
+ pSiS->CRT1off = 1;
+ if (usScratchCR17 & 0x80) pSiS->CRT1changed = TRUE;
+ usScratchCR32 &= ~0x20;
+ /* TW: We must not actually switch off CRT1 before we changed the mode! */
+ }
+ }
+ outSISIDXREG(SISCR, 0x17, usScratchCR17);
+ outSISIDXREG(SISCR, 0x32, usScratchCR32);
+ if(pSiS->CRT1changed) {
+ outSISIDXREG(SISSR, 0x00, 0x01); /* Synchronous Reset */
+ usleep(10000);
+ outSISIDXREG(SISSR, 0x00, 0x03); /* End Reset */
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "CRT1 status changed by ForceCRT1 option\n");
+ }
+ }
+ }
+ /* TW: Store the new VB connection register contents for later mode changes */
+ pSiS->newCR32 = usScratchCR32;
+ }
+
+ /* TW: Check if CRT1 used (or needed; this eg. if no CRT2 detected) */
+ if (pSiS->VBFlags & VB_VIDEOBRIDGE) {
+
+ /* TW: No CRT2 output? Then we NEED CRT1!
+ * We also need CRT1 if depth = 8 and bridge=LVDS|630+301B
+ */
+ if ( (!(pSiS->VBFlags & (CRT2_VGA | CRT2_LCD | CRT2_TV))) ||
+ ( (pScrn->bitsPerPixel == 8) &&
+ ( (pSiS->VBFlags & (VB_LVDS | VB_CHRONTEL)) ||
+ ((pSiS->VGAEngine == SIS_300_VGA) && (pSiS->VBFlags & VB_301B)) ) ) ) {
+ pSiS->CRT1off = 0;
+ }
+ /* TW: No CRT2 output? Then we can't use Xv on CRT2 */
+ if (!(pSiS->VBFlags & (CRT2_VGA | CRT2_LCD | CRT2_TV)))
+ pSiS->XvOnCRT2 = FALSE;
+
+ } else { /* TW: no video bridge? */
+
+ /* Then we NEED CRT1... */
+ pSiS->CRT1off = 0;
+ /* ... and can't use CRT2 for Xv output */
+ pSiS->XvOnCRT2 = FALSE;
+ }
+
+ /* TW: Handle TVStandard option */
+ if(pSiS->NonDefaultPAL != -1) {
+ if( (!(pSiS->VBFlags & VB_SISBRIDGE)) &&
+ (!((pSiS->VBFlags & VB_CHRONTEL)) && (pSiS->ChrontelType == CHRONTEL_701x)) ) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "PALM and PALN only supported on Chrontel 701x and SiS30x/B/LV\n");
+ pSiS->NonDefaultPAL = -1;
+ pSiS->VBFlags &= ~(TV_PALN | TV_PALM);
+ }
+ }
+ if(pSiS->NonDefaultPAL != -1) {
+ if((pSiS->Chipset == PCI_CHIP_SIS300) || (pSiS->Chipset == PCI_CHIP_SIS540)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "PALM and PALN not supported on SiS300 and SiS540\n");
+ pSiS->NonDefaultPAL = -1;
+ pSiS->VBFlags &= ~(TV_PALN | TV_PALM);
+ }
+ }
+ if(pSiS->OptTVStand != -1) {
+ if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
+ if(!(pSiS->Flags & (TV_CHSCART | TV_CHHDTV))) {
+ pSiS->VBFlags &= ~(TV_PAL | TV_NTSC | TV_PALN | TV_PALM);
+ if(pSiS->OptTVStand) pSiS->VBFlags |= TV_PAL;
+ else pSiS->VBFlags |= TV_NTSC;
+ if(pSiS->NonDefaultPAL == 1) pSiS->VBFlags |= TV_PALM;
+ else if(!pSiS->NonDefaultPAL) pSiS->VBFlags |= TV_PALN;
+ } else {
+ pSiS->OptTVStand = pSiS->NonDefaultPAL = -1;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Option TVStandard ignored for SCART and 480i HDTV\n");
+ }
+ } else if(pSiS->Chipset == PCI_CHIP_SIS6326) {
+ pSiS->SiS6326Flags &= ~SIS6326_TVPAL;
+ if(pSiS->OptTVStand) pSiS->SiS6326Flags |= SIS6326_TVPAL;
+ }
+ }
+
+ /* TW: Do some checks */
+ if(pSiS->OptTVOver != -1) {
+ if(pSiS->VBFlags & VB_CHRONTEL) {
+ pSiS->UseCHOverScan = pSiS->OptTVOver;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "CHTVOverscan option only supported on CHRONTEL 70xx\n");
+ pSiS->UseCHOverScan = -1;
+ }
+ } else pSiS->UseCHOverScan = -1;
+
+ if(pSiS->sistvedgeenhance != -1) {
+ if(!(pSiS->VBFlags & VB_301)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "SISTVEdgeEnhance option only supported on SiS301\n");
+ pSiS->sistvedgeenhance = -1;
+ }
+ }
+
+ /* TW: Determine CRT1<>CRT2 mode
+ * Note: When using VESA or if the bridge is in slavemode, display
+ * is ALWAYS in MIRROR_MODE!
+ * This requires extra checks in functions using this flag!
+ * (see sis_video.c for example)
+ */
+ if(pSiS->VBFlags & DISPTYPE_DISP2) {
+ if(pSiS->CRT1off) { /* TW: CRT2 only ------------------------------- */
+#ifdef SISDUALHEAD
+ if(pSiS->DualHeadMode) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "CRT1 not detected or forced off. Dual Head mode can't initialize.\n");
+ if(pSiSEnt) pSiSEnt->DisableDual = TRUE;
+ if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
+ if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
+ sisRestoreExtRegisterLock(pSiS,srlockReg,crlockReg);
+ SISFreeRec(pScrn);
+ return FALSE;
+ }
+#endif
+ pSiS->VBFlags |= VB_DISPMODE_SINGLE;
+ /* TW: No CRT1? Then we use the video overlay on CRT2 */
+ pSiS->XvOnCRT2 = TRUE;
+ } else /* TW: CRT1 and CRT2 - mirror or dual head ----- */
+#ifdef SISDUALHEAD
+ if(pSiS->DualHeadMode) {
+ pSiS->VBFlags |= (VB_DISPMODE_DUAL | DISPTYPE_CRT1);
+ if(pSiS->VESA != -1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "VESA option not used in Dual Head mode. VESA disabled.\n");
+ }
+ if (pSiSEnt) pSiSEnt->DisableDual = FALSE;
+ pSiS->VESA = 0;
+ } else
+#endif
+ pSiS->VBFlags |= (VB_DISPMODE_MIRROR | DISPTYPE_CRT1);
+ } else { /* TW: CRT1 only ------------------------------- */
+#ifdef SISDUALHEAD
+ if(pSiS->DualHeadMode) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "No CRT2 output selected or no bridge detected. "
+ "Dual Head mode can't initialize.\n");
+ if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
+ if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
+ sisRestoreExtRegisterLock(pSiS,srlockReg,crlockReg);
+ SISFreeRec(pScrn);
+ return FALSE;
+ }
+#endif
+ pSiS->VBFlags |= (VB_DISPMODE_SINGLE | DISPTYPE_CRT1);
+ }
+
+ if( (pSiS->VGAEngine == SIS_315_VGA) ||
+ (pSiS->VGAEngine == SIS_300_VGA) ) {
+ if ( (!pSiS->NoXvideo) &&
+ (!pSiS->hasTwoOverlays) ) {
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "Using Xv overlay on CRT%d\n",
+ pSiS->XvOnCRT2 ? 2 : 1);
+ }
+ }
+
+ /* TW: Init Ptrs for Save/Restore functions and calc MaxClock */
+ SISDACPreInit(pScrn);
+
+ /* ********** end of VBFlags setup ********** */
+
+ /* TW: VBFlags are initialized now. Back them up for SlaveMode modes. */
+ pSiS->VBFlags_backup = pSiS->VBFlags;
+
+ /* TW: Find out about paneldelaycompensation and evaluate option */
+ pSiS->sishw_ext.pdc = 0;
+
+ if(pSiS->VGAEngine == SIS_300_VGA) {
+
+ if(pSiS->VBFlags & (VB_LVDS | VB_301B | VB_302B)) {
+ /* TW: Save the current PDC if the panel is used at the moment.
+ * This seems by far the safest way to find out about it.
+ * If the system is using an old version of sisfb, we can't
+ * trust the pdc register value. If sisfb saved the pdc for
+ * us, use it.
+ */
+ if(pSiS->sisfbpdc) {
+ pSiS->sishw_ext.pdc = pSiS->sisfbpdc;
+ } else {
+ if(!(pSiS->donttrustpdc)) {
+ unsigned char tmp;
+ inSISIDXREG(SISCR, 0x30, tmp);
+ if(tmp & 0x20) {
+ inSISIDXREG(SISPART1, 0x13, pSiS->sishw_ext.pdc);
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Unable to detect LCD PanelDelayCompensation, LCD is not active\n");
+ }
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Unable to detect LCD PanelDelayCompensation, please update sisfb\n");
+ }
+ }
+ pSiS->sishw_ext.pdc &= 0x3c;
+ if(pSiS->sishw_ext.pdc) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Detected LCD PanelDelayCompensation %d\n",
+ pSiS->sishw_ext.pdc);
+ }
+
+ /* If we haven't been able to find out, use our other methods */
+ if(pSiS->sishw_ext.pdc == 0) {
+
+ int i=0;
+ do {
+ if(mypdctable[i].subsysVendor == pSiS->PciInfo->subsysVendor &&
+ mypdctable[i].subsysCard == pSiS->PciInfo->subsysCard) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "PCI card/vendor found in list for non-default PanelDelayCompensation\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Vendor: %s, card: %s (ID %04x), PanelDelayCompensation: %d\n",
+ mypdctable[i].vendorName, mypdctable[i].cardName,
+ pSiS->PciInfo->subsysCard, mypdctable[i].pdc);
+ if(pSiS->PDC == -1) {
+ pSiS->PDC = mypdctable[i].pdc;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "PanelDelayCompensation overruled by option\n");
+ }
+ break;
+ }
+ i++;
+ } while(mypdctable[i].subsysVendor != 0);
+
+ }
+
+ if(pSiS->PDC != -1) {
+ if(pSiS->BIOS) {
+ if(pSiS->VBFlags & VB_LVDS) {
+ if(pSiS->BIOS[0x220] & 0x80) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "BIOS contains custom LCD Panel Delay Compensation %d\n",
+ pSiS->BIOS[0x220] & 0x3c);
+ pSiS->BIOS[0x220] &= 0x7f;
+ }
+ }
+ if(pSiS->VBFlags & (VB_301B|VB_302B)) {
+ if(pSiS->BIOS[0x220] & 0x80) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "BIOS contains custom LCD Panel Delay Compensation %d\n",
+ ( (pSiS->VBLCDFlags & VB_LCD_1280x1024) ?
+ pSiS->BIOS[0x223] : pSiS->BIOS[0x224] ) & 0x3c);
+ pSiS->BIOS[0x220] &= 0x7f;
+ }
+ }
+ }
+ pSiS->sishw_ext.pdc = (pSiS->PDC & 0x3c);
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Using LCD Panel Delay Compensation %d\n", pSiS->PDC);
+ }
+ }
+ }
+
+#ifdef SISDUALHEAD
+ /* TW: In dual head mode, both heads (currently) share the maxxfbmem equally.
+ * If memory sharing is done differently, the following has to be changed;
+ * the other modules (eg. accel and Xv) use dhmOffset for hardware
+ * pointer settings relative to VideoRAM start and won't need to be changed.
+ */
+ if (pSiS->DualHeadMode) {
+ if (pSiS->SecondHead == FALSE) {
+ /* ===== First head (always CRT2) ===== */
+ /* We use only half of the memory available */
+ pSiS->maxxfbmem /= 2;
+ /* Initialize dhmOffset */
+ pSiS->dhmOffset = 0;
+ /* Copy framebuffer addresses & sizes to entity */
+ pSiSEnt->masterFbAddress = pSiS->FbAddress;
+ pSiSEnt->masterFbSize = pSiS->maxxfbmem;
+ pSiSEnt->slaveFbAddress = pSiS->FbAddress + pSiS->maxxfbmem;
+ pSiSEnt->slaveFbSize = pSiS->maxxfbmem;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "%dKB video RAM at 0x%lx available for master head (CRT2)\n",
+ pSiS->maxxfbmem/1024, pSiS->FbAddress);
+ } else {
+ /* ===== Second head (always CRT1) ===== */
+ /* We use only half of the memory available */
+ pSiS->maxxfbmem /= 2;
+ /* Adapt FBAddress */
+ pSiS->FbAddress += pSiS->maxxfbmem;
+ /* Initialize dhmOffset */
+ pSiS->dhmOffset = pSiS->availMem - pSiS->maxxfbmem;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "%dKB video RAM at 0x%lx available for slave head (CRT1)\n",
+ pSiS->maxxfbmem/1024, pSiS->FbAddress);
+ }
+ } else
+ pSiS->dhmOffset = 0;
+#endif
+
+ /* TW: Note: Do not use availMem for anything from now. Use
+ * maxxfbmem instead. (availMem does not take dual head
+ * mode into account.)
+ */
+
+ /* TW: Now for something completely different: DDC.
+ For 300 and 310/325 series, we provide our
+ own functions (in order to probe CRT2 as well)
+ If these fail, use the VBE.
+ All other chipsets will use VBE. No need to re-invent
+ the wheel there.
+ */
+
+ pSiS->pVbe = NULL;
+ didddc2 = FALSE;
+
+ if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
+ if(xf86LoadSubModule(pScrn, "ddc")) {
+ xf86LoaderReqSymLists(ddcSymbols, NULL);
+ if((pMonitor = SiSDoPrivateDDC(pScrn))) {
+ didddc2 = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "DDC monitor info:\n");
+ xf86PrintEDID(pMonitor);
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "End of DDC monitor info\n");
+ xf86SetDDCproperties(pScrn, pMonitor);
+ pScrn->monitor->DDC = pMonitor;
+ }
+ }
+ }
+
+#ifdef SISDUALHEAD
+ /* TW: In dual head mode, probe DDC using VBE only for CRT1 (second head) */
+ if((pSiS->DualHeadMode) && (!didddc2) && (!pSiS->SecondHead))
+ didddc2 = TRUE;
+#endif
+
+ /* TW: If CRT1 is off (eventually forced), skip DDC */
+ if((!didddc2) && (pSiS->CRT1off)) didddc2 = TRUE;
+
+ /* TW: Now (re-)load and initialize the DDC module */
+ if(!didddc2) {
+
+ if(xf86LoadSubModule(pScrn, "ddc")) {
+
+ xf86LoaderReqSymLists(ddcSymbols, NULL);
+
+ /* TW: Now load and initialize VBE module. */
+ if(xf86LoadSubModule(pScrn, "vbe")) {
+ xf86LoaderReqSymLists(vbeSymbols, NULL);
+#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,99,0,0)
+ pSiS->pVbe = VBEInit(pSiS->pInt,pSiS->pEnt->index);
+#else
+ pSiS->pVbe = VBEExtendedInit(pSiS->pInt,pSiS->pEnt->index,
+ SET_BIOS_SCRATCH | RESTORE_BIOS_SCRATCH);
+#endif
+ if(!pSiS->pVbe) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Could not initialize VBE module for DDC\n");
+ }
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Could not load VBE module for DDC\n");
+ }
+
+ if(pSiS->pVbe) {
+ if((pMonitor = vbeDoEDID(pSiS->pVbe,NULL))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "VBE DDC monitor info:\n");
+ xf86SetDDCproperties(pScrn, xf86PrintEDID(pMonitor));
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "End of VBE DDC monitor info:\n");
+ pScrn->monitor->DDC = pMonitor;
+ }
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Could not retrieve DDC data\n");
+ }
+ }
+ }
+
+#if 0 /* TW: DDC1 obviously no longer supported by SiS chipsets */
+ if (!ret && pSiS->ddc1Read)
+ xf86SetDDCproperties(pScrn, xf86PrintEDID(xf86DoEDID_DDC1(
+ pScrn->scrnIndex,vgaHWddc1SetSpeed,pSiS->ddc1Read )));
+#endif
+
+ /* end of DDC */
+
+ /* Set the min pixel clock */
+ pSiS->MinClock = 12000; /* XXX Guess, need to check this (TW: good for even 50Hz interlace) */
+ xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %d MHz\n",
+ pSiS->MinClock / 1000);
+
+ from = X_PROBED;
+ /*
+ * If the user has specified ramdac speed in the XF86Config
+ * file, we respect that setting.
+ */
+ if(pSiS->pEnt->device->dacSpeeds[0]) {
+ int speed = 0;
+ switch(pScrn->bitsPerPixel) {
+ case 8:
+ speed = pSiS->pEnt->device->dacSpeeds[DAC_BPP8];
+ break;
+ case 16:
+ speed = pSiS->pEnt->device->dacSpeeds[DAC_BPP16];
+ break;
+ case 24:
+ speed = pSiS->pEnt->device->dacSpeeds[DAC_BPP24];
+ break;
+ case 32:
+ speed = pSiS->pEnt->device->dacSpeeds[DAC_BPP32];
+ break;
+ }
+ if(speed == 0)
+ pSiS->MaxClock = pSiS->pEnt->device->dacSpeeds[0];
+ else
+ pSiS->MaxClock = speed;
+ from = X_CONFIG;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Max pixel clock is %d MHz\n",
+ pSiS->MaxClock / 1000);
+
+ /*
+ * Setup the ClockRanges, which describe what clock ranges are available,
+ * and what sort of modes they can be used for.
+ */
+ clockRanges = xnfcalloc(sizeof(ClockRange), 1);
+ clockRanges->next = NULL;
+ clockRanges->minClock = pSiS->MinClock;
+ clockRanges->maxClock = pSiS->MaxClock;
+ clockRanges->clockIndex = -1; /* programmable */
+ clockRanges->interlaceAllowed = TRUE;
+ clockRanges->doubleScanAllowed = TRUE;
+
+ /* TW: If there is no HSync or VRefresh data for the monitor,
+ derive it from DDC data. (Idea taken from radeon driver)
+ */
+ if(pScrn->monitor->DDC) {
+ if(pScrn->monitor->nHsync <= 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Substituting missing monitor HSync data by DDC data\n");
+ SiSSetSyncRangeFromEdid(pScrn, 1);
+ }
+ if(pScrn->monitor->nVrefresh <= 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Substituting missing monitor VRefresh data by DDC data\n");
+ SiSSetSyncRangeFromEdid(pScrn, 0);
+ }
+ }
+
+ /*
+ * TW: Since we have lots of built-in modes for 300/310/325/330 series
+ * with vb support, we replace the given default mode list with our
+ * own. In case the video bridge is to be used, no other than our
+ * built-in modes are supported; therefore, delete the entire modelist
+ * given.
+ */
+
+ pSiS->HaveCustomModes = FALSE;
+ if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
+ if(!(pSiS->noInternalModes)) {
+ if((mymodes = SiSBuildBuiltInModeList(pScrn))) {
+#ifdef SISDUALHEAD
+ if( (pSiS->UseVESA) ||
+ ((pSiS->DualHeadMode) && (!pSiS->SecondHead)) ||
+ ((!pSiS->DualHeadMode) && (pSiS->VBFlags & DISPTYPE_DISP2)) ) {
+#else
+ if((pSiS->UseVESA) || (pSiS->VBFlags & DISPTYPE_DISP2)) {
+#endif
+ while(pScrn->monitor->Modes)
+ xf86DeleteMode(&pScrn->monitor->Modes, pScrn->monitor->Modes);
+ pScrn->monitor->Modes = mymodes;
+ } else {
+ delmode = pScrn->monitor->Modes;
+ while(delmode) {
+ if(delmode->type & M_T_DEFAULT) {
+ tempmode = delmode->next;
+ xf86DeleteMode(&pScrn->monitor->Modes, delmode);
+ delmode = tempmode;
+ } else {
+ delmode = delmode->next;
+ }
+ }
+ tempmode = pScrn->monitor->Modes;
+ if(tempmode) pSiS->HaveCustomModes = TRUE;
+ pScrn->monitor->Modes = mymodes;
+ while(mymodes) {
+ if(!mymodes->next) break;
+ else mymodes = mymodes->next;
+ }
+ mymodes->next = tempmode;
+ if(tempmode) {
+ tempmode->prev = mymodes;
+ }
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Replaced %s mode list with built-in modes\n",
+ pSiS->HaveCustomModes ? "default" : "entire");
+#ifdef TWDEBUG
+ pScrn->modes = pScrn->monitor->Modes;
+ xf86PrintModes(pScrn);
+ pScrn->modes = NULL;
+#endif
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Building list of built-in modes failed, using XFree86 defaults\n");
+ }
+ }
+ }
+
+ /*
+ * TW: Add our built-in modes for TV on the 6326
+ */
+ if((pSiS->Chipset == PCI_CHIP_SIS6326) && (pSiS->SiS6326Flags & SIS6326_HASTV)) {
+ if(pSiS->SiS6326Flags & SIS6326_TVDETECTED) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Adding %s TV modes for 6326 to mode list:\n",
+ (pSiS->SiS6326Flags & SIS6326_TVPAL) ? "PAL" : "NTSC");
+ if(pSiS->SiS6326Flags & SIS6326_TVPAL) {
+ SiS6326PAL800x600Mode.next = pScrn->monitor->Modes;
+ pScrn->monitor->Modes = &SiS6326PAL640x480Mode;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "\"PAL800x600\" \"PAL800x600U\" \"PAL720x540\" \"PAL640x480\"\n");
+ } else {
+ SiS6326NTSC640x480Mode.next = pScrn->monitor->Modes;
+ pScrn->monitor->Modes = &SiS6326NTSC640x400Mode;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "\"NTSC640x480\" \"NTSC640x480U\" \"NTSC640x400\"\n");
+ }
+ }
+ }
+
+ /*
+ * TW: Add our built-in hi-res modes on the 6326
+ */
+ if(pSiS->Chipset == PCI_CHIP_SIS6326) {
+ if(pScrn->bitsPerPixel == 8) {
+ SiS6326SIS1600x1200_60Mode.next = pScrn->monitor->Modes;
+ pScrn->monitor->Modes = &SiS6326SIS1600x1200_60Mode;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Adding mode \"SIS1600x1200-60\" (depth 8 only)\n");
+ }
+ if(pScrn->bitsPerPixel <= 16) {
+ SiS6326SIS1280x1024_75Mode.next = pScrn->monitor->Modes;
+ pScrn->monitor->Modes = &SiS6326SIS1280x1024_75Mode;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Adding mode \"SIS1280x1024-75\" (depth 8, 15 and 16 only)\n");
+ }
+ }
+
+ if(pSiS->VGAEngine == SIS_300_VGA || pSiS->VGAEngine == SIS_315_VGA) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "\"Unknown reason\" in the following list means that the mode\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "is not supported on the chipset/bridge/current output device.\n");
+ }
+
+ /*
+ * xf86ValidateModes will check that the mode HTotal and VTotal values
+ * don't exceed the chipset's limit if pScrn->maxHValue and
+ * pScrn->maxVValue are set. Since our SISValidMode() already takes
+ * care of this, we don't worry about setting them here.
+ */
+
+ /* Select valid modes from those available */
+ /*
+ * Assuming min pitch 256, max 4096 ==> 8192
+ * Assuming min height 128, max 4096
+ */
+ i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
+ pScrn->display->modes, clockRanges,
+ NULL, 256, 8192,
+ pScrn->bitsPerPixel * 8, 128, 4096,
+ pScrn->display->virtualX,
+ pScrn->display->virtualY,
+ pSiS->maxxfbmem,
+ LOOKUP_BEST_REFRESH);
+
+ if(i == -1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "xf86ValidateModes() error\n");
+#ifdef SISDUALHEAD
+ if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
+#endif
+ if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
+ sisRestoreExtRegisterLock(pSiS,srlockReg,crlockReg);
+ SISFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /* TW: Go through mode list and mark all those modes as bad,
+ * - which are unsuitable for dual head mode (if running dhm),
+ * - which exceed the LCD panels specs (if running on LCD)
+ * - TODO: which exceed TV capabilities (if running on TV)
+ * Also, find the highest used pixelclock on the master head.
+ */
+#ifdef SISDUALHEAD
+ if(pSiS->DualHeadMode) {
+ if(!pSiS->SecondHead) pSiSEnt->maxUsedClock = 0;
+ }
+#endif
+ if((p = first = pScrn->modes)) {
+ do {
+ n = p->next;
+
+ /* TW: Check the modes if they comply with our built-in tables.
+ * This is of practical use only if the user disabled the
+ * usage of the internal (built-in) modes.
+ */
+ if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
+ if(p->type & M_T_DEFAULT) {
+ if( ( (strcmp(p->name, "320x200") != 0) &&
+ (strcmp(p->name, "320x240") != 0) &&
+ (strcmp(p->name, "400x300") != 0) &&
+ (strcmp(p->name, "512x384") != 0) ) &&
+ (p->Flags & V_DBLSCAN) ) {
+ p->status = MODE_NO_DBLESCAN;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Not using mode \"%s\" (mode not supported as doublescan)\n", p->name);
+ }
+ if( ( (strcmp(p->name, "1024x768") != 0) &&
+ (strcmp(p->name, "1280x1024") != 0) &&
+ (strcmp(p->name, "848x480") != 0) &&
+ (strcmp(p->name, "856x480") != 0)) &&
+ (p->Flags & V_INTERLACE) ) {
+ p->status = MODE_NO_INTERLACE;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Not using mode \"%s\" (mode not supported as interlaced)\n", p->name);
+ }
+ if( ( (strcmp(p->name, "320x200") == 0) ||
+ (strcmp(p->name, "320x240") == 0) ||
+ (strcmp(p->name, "400x300") == 0) ||
+ (strcmp(p->name, "512x384") == 0) ) &&
+ (!(p->Flags & V_DBLSCAN)) ) {
+ p->status = MODE_CLOCK_RANGE;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Not using mode \"%s\" (only supported as doublescan)\n", p->name);
+ }
+ }
+ }
+#ifdef SISDUALHEAD
+ /* TW: Modes that require the bridge to operate in SlaveMode
+ * are not suitable for Dual Head mode. Also check for
+ * modes that exceed panel dimension.
+ */
+ if(pSiS->DualHeadMode) {
+ if(pSiS->SecondHead == FALSE) {
+ if( (strcmp(p->name, "320x200") == 0) ||
+ (strcmp(p->name, "320x240") == 0) ||
+ (strcmp(p->name, "400x300") == 0) ||
+ (strcmp(p->name, "512x384") == 0) ||
+ (strcmp(p->name, "640x400") == 0) ) {
+ p->status = MODE_BAD;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Not using mode \"%s\" (not suitable for dual head mode)\n",
+ p->name);
+ }
+ }
+ if(pSiS->VBFlags & DISPTYPE_DISP2) {
+ if(pSiS->VBFlags & CRT2_LCD) {
+ if(pSiS->SecondHead == FALSE) {
+ if((p->HDisplay > pSiS->LCDwidth) || (p->VDisplay > pSiS->LCDheight)) {
+ p->status = MODE_PANEL;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Not using mode \"%s\" (exceeds LCD panel dimension)\n", p->name);
+ }
+ if(p->Flags & V_INTERLACE) {
+ p->status = MODE_BAD;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Not using mode \"%s\" (interlace on LCD not supported)\n",
+ p->name);
+ }
+ }
+ }
+ /* TO DO: TV */
+ }
+ /* TW: Search for the highest clock on first head in order to calculate
+ * max clock for second head (CRT1)
+ */
+ if(!pSiS->SecondHead) {
+ if((p->status == MODE_OK) && (p->Clock > pSiSEnt->maxUsedClock)) {
+ pSiSEnt->maxUsedClock = p->Clock;
+ }
+ }
+ } else {
+#endif
+ if(pSiS->VBFlags & DISPTYPE_DISP2) {
+ if(pSiS->VBFlags & CRT2_LCD) {
+ if((p->HDisplay > pSiS->LCDwidth) || (p->VDisplay > pSiS->LCDheight)) {
+ p->status = MODE_PANEL;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Not using mode \"%s\" (exceeds LCD panel dimension)\n", p->name);
+ }
+ if(p->Flags & V_INTERLACE) {
+ p->status = MODE_BAD;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Not using mode \"%s\" (interlace on LCD not supported)\n",
+ p->name);
+ }
+ }
+ }
+#ifdef SISDUALHEAD
+ }
+#endif
+ p = n;
+ } while (p != NULL && p != first);
+ }
+
+ /* Prune the modes marked as invalid */
+ xf86PruneDriverModes(pScrn);
+
+ if(i == 0 || pScrn->modes == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
+#ifdef SISDUALHEAD
+ if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
+#endif
+ if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
+ sisRestoreExtRegisterLock(pSiS,srlockReg,crlockReg);
+ SISFreeRec(pScrn);
+ return FALSE;
+ }
+
+ xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
+
+ /* Set the current mode to the first in the list */
+ pScrn->currentMode = pScrn->modes;
+
+ /* TW: Copy to CurrentLayout */
+ pSiS->CurrentLayout.mode = pScrn->currentMode;
+ pSiS->CurrentLayout.displayWidth = pScrn->displayWidth;
+
+ /* Print the list of modes being used */
+ xf86PrintModes(pScrn);
+
+#ifdef SISDUALHEAD
+ /* TW: Due to palette & timing problems we don't support 8bpp in DHM */
+ if((pSiS->DualHeadMode) && (pScrn->bitsPerPixel == 8)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Colordepth 8 not supported in Dual Head mode.\n");
+ if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
+ if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
+ sisRestoreExtRegisterLock(pSiS,srlockReg,crlockReg);
+ SISFreeRec(pScrn);
+ return FALSE;
+ }
+#endif
+
+ /* Set display resolution */
+ xf86SetDpi(pScrn, 0, 0);
+
+ /* Load bpp-specific modules */
+ switch(pScrn->bitsPerPixel) {
+ case 1:
+ mod = "xf1bpp";
+ Sym = "xf1bppScreenInit";
+ break;
+ case 4:
+ mod = "xf4bpp";
+ Sym = "xf4bppScreenInit";
+ break;
+ case 8:
+ case 16:
+ case 24:
+ case 32:
+ mod = "fb";
+ break;
+ }
+
+ if(mod && xf86LoadSubModule(pScrn, mod) == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Could not load %s module", mod);
+#ifdef SISDUALHEAD
+ if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
+#endif
+ if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
+ sisRestoreExtRegisterLock(pSiS,srlockReg,crlockReg);
+ SISFreeRec(pScrn);
+ return FALSE;
+ }
+
+ if(mod) {
+ if(Sym) {
+ xf86LoaderReqSymbols(Sym, NULL);
+ } else {
+ xf86LoaderReqSymLists(fbSymbols, NULL);
+ }
+ }
+
+ /* Load XAA if needed */
+ if(!pSiS->NoAccel) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Accel enabled\n");
+ if(!xf86LoadSubModule(pScrn, "xaa")) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Could not load xaa module\n");
+#ifdef SISDUALHEAD
+ if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
+#endif
+ if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
+ sisRestoreExtRegisterLock(pSiS,srlockReg,crlockReg);
+ SISFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(xaaSymbols, NULL);
+ }
+
+ /* Load shadowfb if needed */
+ if(pSiS->ShadowFB) {
+ if(!xf86LoadSubModule(pScrn, "shadowfb")) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Could not load shadowfb module\n");
+#ifdef SISDUALHEAD
+ if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
+#endif
+ if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
+ sisRestoreExtRegisterLock(pSiS,srlockReg,crlockReg);
+ SISFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(shadowSymbols, NULL);
+ }
+
+
+ /* TW: Now load and initialize VBE module for VESA. */
+ pSiS->UseVESA = 0;
+ if(pSiS->VESA == 1) {
+ if(!pSiS->pVbe) {
+ if(xf86LoadSubModule(pScrn, "vbe")) {
+ xf86LoaderReqSymLists(vbeSymbols, NULL);
+#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,99,0,0)
+ pSiS->pVbe = VBEInit(pSiS->pInt,pSiS->pEnt->index);
+#else
+ pSiS->pVbe = VBEExtendedInit(pSiS->pInt,pSiS->pEnt->index,
+ SET_BIOS_SCRATCH | RESTORE_BIOS_SCRATCH);
+#endif
+ }
+ }
+ if(pSiS->pVbe) {
+ vbe = VBEGetVBEInfo(pSiS->pVbe);
+ pSiS->vesamajor = (unsigned)(vbe->VESAVersion >> 8);
+ pSiS->vesaminor = vbe->VESAVersion & 0xff;
+ pSiS->vbeInfo = vbe;
+ SiSBuildVesaModeList(pScrn, pSiS->pVbe, vbe);
+ VBEFreeVBEInfo(vbe);
+ pSiS->UseVESA = 1;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Could not load and initialize VBE module. VESA disabled.\n");
+ }
+ }
+
+ if(pSiS->pVbe) {
+ vbeFree(pSiS->pVbe);
+ pSiS->pVbe = NULL;
+ }
+
+#ifdef SISDUALHEAD
+ xf86SetPrimInitDone(pScrn->entityList[0]);
+#endif
+
+ sisRestoreExtRegisterLock(pSiS,srlockReg,crlockReg);
+
+ if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
+ pSiS->pInt = NULL;
+
+ return TRUE;
+}
+
+
+/*
+ * Map the framebuffer and MMIO memory.
+ */
+
+static Bool
+SISMapMem(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS;
+ int mmioFlags;
+#ifdef SISDUALHEAD
+ SISEntPtr pSiSEnt = NULL;
+#endif
+ pSiS = SISPTR(pScrn);
+
+#ifdef SISDUALHEAD
+ pSiSEnt = pSiS->entityPrivate;
+#endif
+
+ /*
+ * Map IO registers to virtual address space
+ */
+#if !defined(__alpha__)
+ mmioFlags = VIDMEM_MMIO;
+#else
+ /*
+ * For Alpha, we need to map SPARSE memory, since we need
+ * byte/short access.
+ */
+ mmioFlags = VIDMEM_MMIO | VIDMEM_SPARSE;
+#endif
+
+#ifdef SISDUALHEAD
+ if(pSiS->DualHeadMode) {
+ pSiSEnt->MapCountIOBase++;
+ if(!(pSiSEnt->IOBase)) {
+ /* TW: Only map if not mapped previously */
+ pSiSEnt->IOBase = xf86MapPciMem(pScrn->scrnIndex, mmioFlags,
+ pSiS->PciTag, pSiS->IOAddress, 0x10000);
+ }
+ pSiS->IOBase = pSiSEnt->IOBase;
+ } else
+#endif
+ pSiS->IOBase = xf86MapPciMem(pScrn->scrnIndex, mmioFlags,
+ pSiS->PciTag, pSiS->IOAddress, 0x10000);
+
+ if(pSiS->IOBase == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Could not map MMIO area\n");
+ return FALSE;
+ }
+
+#ifdef __alpha__
+ /*
+ * for Alpha, we need to map DENSE memory as well, for
+ * setting CPUToScreenColorExpandBase.
+ */
+#ifdef SISDUALHEAD
+ if(pSiS->DualHeadMode) {
+ pSiSEnt->MapCountIOBaseDense++;
+ if(!(pSiSEnt->IOBaseDense)) {
+ /* TW: Only map if not mapped previously */
+ pSiSEnt->IOBaseDense = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO,
+ pSiS->PciTag, pSiS->IOAddress, 0x10000);
+ }
+ pSiS->IOBaseDense = pSiSEnt->IOBaseDense;
+ } else
+#endif
+ pSiS->IOBaseDense = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO,
+ pSiS->PciTag, pSiS->IOAddress, 0x10000);
+
+ if(pSiS->IOBaseDense == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Could not map MMIO dense area\n");
+ return FALSE;
+ }
+
+#endif /* __alpha__ */
+
+#ifdef SISDUALHEAD
+ if(pSiS->DualHeadMode) {
+ pSiSEnt->MapCountFbBase++;
+ if(!(pSiSEnt->FbBase)) {
+ /* TW: Only map if not mapped previously */
+ pSiSEnt->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
+ pSiS->PciTag, (unsigned long)pSiS->realFbAddress,
+ pSiS->FbMapSize);
+ pSiS->sishw_ext.pjVideoMemoryAddress = (UCHAR *)pSiSEnt->FbBase;
+ }
+ pSiS->FbBase = pSiSEnt->FbBase;
+ /* TW: Adapt FbBase (for DHM; dhmOffset is 0 otherwise) */
+ pSiS->FbBase += pSiS->dhmOffset;
+ } else {
+#endif
+ pSiS->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
+ pSiS->PciTag, (unsigned long)pSiS->FbAddress,
+ pSiS->FbMapSize);
+ pSiS->sishw_ext.pjVideoMemoryAddress = (UCHAR *)pSiS->FbBase;
+#ifdef SISDUALHEAD
+ }
+#endif
+
+ if(pSiS->FbBase == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Could not map framebuffer area\n");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * Unmap the framebuffer and MMIO memory.
+ */
+
+static Bool
+SISUnmapMem(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS;
+#ifdef SISDUALHEAD
+ SISEntPtr pSiSEnt = NULL;
+#endif
+
+ pSiS = SISPTR(pScrn);
+
+#ifdef SISDUALHEAD
+ pSiSEnt = pSiS->entityPrivate;
+#endif
+
+/* TW: In dual head mode, we must not unmap if the other head still
+ * assumes memory as mapped
+*/
+#ifdef SISDUALHEAD
+ if (pSiS->DualHeadMode) {
+ if (pSiSEnt->MapCountIOBase) {
+ pSiSEnt->MapCountIOBase--;
+ if ((pSiSEnt->MapCountIOBase == 0) || (pSiSEnt->forceUnmapIOBase)) {
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pSiSEnt->IOBase, 0x10000);
+ pSiSEnt->IOBase = NULL;
+ pSiSEnt->MapCountIOBase = 0;
+ pSiSEnt->forceUnmapIOBase = FALSE;
+ }
+ pSiS->IOBase = NULL;
+ }
+#ifdef __alpha__
+ if (pSiSEnt->MapCountIOBaseDense) {
+ pSiSEnt->MapCountIOBaseDense--;
+ if ((pSiSEnt->MapCountIOBaseDense == 0) || (pSiSEnt->forceUnmapIOBaseDense)) {
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pSiSEnt->IOBaseDense, 0x10000);
+ pSiSEnt->IOBaseDense = NULL;
+ pSiSEnt->MapCountIOBaseDense = 0;
+ pSiSEnt->forceUnmapIOBaseDense = FALSE;
+ }
+ pSiS->IOBaseDense = NULL;
+ }
+#endif /* __alpha__ */
+ if (pSiSEnt->MapCountFbBase) {
+ pSiSEnt->MapCountFbBase--;
+ if ((pSiSEnt->MapCountFbBase == 0) || (pSiSEnt->forceUnmapFbBase)) {
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pSiSEnt->FbBase, pSiS->FbMapSize);
+ pSiSEnt->FbBase = NULL;
+ pSiSEnt->MapCountFbBase = 0;
+ pSiSEnt->forceUnmapFbBase = FALSE;
+
+ }
+ pSiS->FbBase = NULL;
+ }
+ } else {
+#endif
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pSiS->IOBase, 0x10000);
+ pSiS->IOBase = NULL;
+#ifdef __alpha__
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pSiS->IOBaseDense, 0x10000);
+ pSiS->IOBaseDense = NULL;
+#endif
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pSiS->FbBase, pSiS->FbMapSize);
+ pSiS->FbBase = NULL;
+#ifdef SISDUALHEAD
+ }
+#endif
+ return TRUE;
+}
+
+/*
+ * This function saves the video state.
+ */
+static void
+SISSave(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS;
+ vgaRegPtr vgaReg;
+ SISRegPtr sisReg;
+
+ pSiS = SISPTR(pScrn);
+
+#ifdef SISDUALHEAD
+ /* TW: We always save master & slave */
+ if(pSiS->DualHeadMode && pSiS->SecondHead) return;
+#endif
+
+ vgaReg = &VGAHWPTR(pScrn)->SavedReg;
+ sisReg = &pSiS->SavedReg;
+
+ vgaHWSave(pScrn, vgaReg, VGA_SR_ALL);
+
+ sisSaveUnlockExtRegisterLock(pSiS,&sisReg->sisRegs3C4[0x05],&sisReg->sisRegs3D4[0x80]);
+
+ (*pSiS->SiSSave)(pScrn, sisReg);
+
+ if(pSiS->UseVESA) SISVESASaveRestore(pScrn, MODE_SAVE);
+
+ /* TW: Save these as they may have been changed prior to SISSave() call */
+ if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
+ sisReg->sisRegs3D4[0x17] = pSiS->oldCR17;
+ if(vgaReg->numCRTC >= 0x17) vgaReg->CRTC[0x17] = pSiS->oldCR17;
+ sisReg->sisRegs3D4[0x32] = pSiS->oldCR32;
+ }
+}
+
+/*
+ * TW: Just adapted from the std* functions in vgaHW.c
+ */
+static void
+SiS_WriteAttr(SISPtr pSiS, int index, int value)
+{
+ CARD8 tmp;
+
+ tmp = inb(pSiS->IODBase + VGA_IOBASE_COLOR + VGA_IN_STAT_1_OFFSET);
+
+ index |= 0x20;
+ outb(pSiS->IODBase + VGA_ATTR_INDEX, index);
+ outb(pSiS->IODBase + VGA_ATTR_DATA_W, value);
+}
+
+static int
+SiS_ReadAttr(SISPtr pSiS, int index)
+{
+ CARD8 tmp;
+
+ tmp = inb(pSiS->IODBase + VGA_IOBASE_COLOR + VGA_IN_STAT_1_OFFSET);
+
+ index |= 0x20;
+ outb(pSiS->IODBase + VGA_ATTR_INDEX, index);
+ return (inb(pSiS->IODBase + VGA_ATTR_DATA_R));
+}
+
+
+static void
+SiS_SaveFonts(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ unsigned char miscOut, attr10, gr4, gr5, gr6, seq2, seq4, scrn;
+#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,99,0,0)
+ CARD8 *vgaIOBase = (CARD8 *)VGAHWPTR(pScrn)->IOBase;
+#else
+ pointer vgaIOBase = VGAHWPTR(pScrn)->Base;
+#endif
+
+ if (pSiS->fonts != NULL)
+ return;
+
+ /* If in graphics mode, don't save anything */
+ attr10 = SiS_ReadAttr(pSiS, 0x10);
+ if (attr10 & 0x01)
+ return;
+
+ pSiS->fonts = xalloc(16384);
+
+ /* save the registers that are needed here */
+ miscOut = inSISREG(SISMISCR);
+ inSISIDXREG(SISGR, 0x04, gr4);
+ inSISIDXREG(SISGR, 0x05, gr5);
+ inSISIDXREG(SISGR, 0x06, gr6);
+ inSISIDXREG(SISSR, 0x02, seq2);
+ inSISIDXREG(SISSR, 0x04, seq4);
+
+ /* Force into color mode */
+ outSISREG(SISMISCW, miscOut | 0x01);
+
+ inSISIDXREG(SISSR, 0x01, scrn);
+ outSISIDXREG(SISSR, 0x00, 0x01);
+ outSISIDXREG(SISSR, 0x01, scrn | 0x20);
+ outSISIDXREG(SISSR, 0x00, 0x03);
+
+ SiS_WriteAttr(pSiS, 0x10, 0x01); /* graphics mode */
+
+ /*font1 */
+ outSISIDXREG(SISSR, 0x02, 0x04); /* write to plane 2 */
+ outSISIDXREG(SISSR, 0x04, 0x06); /* enable plane graphics */
+ outSISIDXREG(SISGR, 0x04, 0x02); /* read plane 2 */
+ outSISIDXREG(SISGR, 0x05, 0x00); /* write mode 0, read mode 0 */
+ outSISIDXREG(SISGR, 0x06, 0x05); /* set graphics */
+ slowbcopy_frombus(vgaIOBase, pSiS->fonts, 8192);
+
+ /* font2 */
+ outSISIDXREG(SISSR, 0x02, 0x08); /* write to plane 3 */
+ outSISIDXREG(SISSR, 0x04, 0x06); /* enable plane graphics */
+ outSISIDXREG(SISGR, 0x04, 0x03); /* read plane 3 */
+ outSISIDXREG(SISGR, 0x05, 0x00); /* write mode 0, read mode 0 */
+ outSISIDXREG(SISGR, 0x06, 0x05); /* set graphics */
+ slowbcopy_frombus(vgaIOBase, pSiS->fonts + 8192, 8192);
+
+ inSISIDXREG(SISSR, 0x01, scrn);
+ outSISIDXREG(SISSR, 0x00, 0x01);
+ outSISIDXREG(SISSR, 0x01, scrn & ~0x20);
+ outSISIDXREG(SISSR, 0x00, 0x03);
+
+ /* Restore clobbered registers */
+ SiS_WriteAttr(pSiS, 0x10, attr10);
+ outSISIDXREG(SISSR, 0x02, seq2);
+ outSISIDXREG(SISSR, 0x04, seq4);
+ outSISIDXREG(SISGR, 0x04, gr4);
+ outSISIDXREG(SISGR, 0x05, gr5);
+ outSISIDXREG(SISGR, 0x06, gr6);
+ outSISREG(SISMISCW, miscOut);
+}
+
+static void
+SiS_RestoreFonts(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ unsigned char miscOut, attr10, gr1, gr3, gr4, gr5, gr6, gr8, seq2, seq4, scrn;
+#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,99,0,0)
+ CARD8 *vgaIOBase = (CARD8 *)VGAHWPTR(pScrn)->IOBase;
+#else
+ pointer vgaIOBase = VGAHWPTR(pScrn)->Base;
+#endif
+
+ if (pSiS->fonts == NULL)
+ return;
+
+#if 0
+ if (pVesa->mapPhys == 0xa0000 && pVesa->curBank != 0)
+ VESABankSwitch(pScrn->pScreen, 0);
+#endif
+
+ /* save the registers that are needed here */
+ miscOut = inSISREG(SISMISCR);
+ attr10 = SiS_ReadAttr(pSiS, 0x10);
+ inSISIDXREG(SISGR, 0x01, gr1);
+ inSISIDXREG(SISGR, 0x03, gr3);
+ inSISIDXREG(SISGR, 0x04, gr4);
+ inSISIDXREG(SISGR, 0x05, gr5);
+ inSISIDXREG(SISGR, 0x06, gr6);
+ inSISIDXREG(SISGR, 0x08, gr8);
+ inSISIDXREG(SISSR, 0x02, seq2);
+ inSISIDXREG(SISSR, 0x04, seq4);
+
+ /* Force into color mode */
+ outSISREG(SISMISCW, miscOut | 0x01);
+ inSISIDXREG(SISSR, 0x01, scrn);
+ outSISIDXREG(SISSR, 0x00, 0x01);
+ outSISIDXREG(SISSR, 0x01, scrn | 0x20);
+ outSISIDXREG(SISSR, 0x00, 0x03);
+
+ SiS_WriteAttr(pSiS, 0x10, 0x01); /* graphics mode */
+ if (pScrn->depth == 4) {
+ outSISIDXREG(SISGR, 0x03, 0x00); /* don't rotate, write unmodified */
+ outSISIDXREG(SISGR, 0x08, 0xFF); /* write all bits in a byte */
+ outSISIDXREG(SISGR, 0x01, 0x00); /* all planes come from CPU */
+ }
+
+ outSISIDXREG(SISSR, 0x02, 0x04); /* write to plane 2 */
+ outSISIDXREG(SISSR, 0x04, 0x06); /* enable plane graphics */
+ outSISIDXREG(SISGR, 0x04, 0x02); /* read plane 2 */
+ outSISIDXREG(SISGR, 0x05, 0x00); /* write mode 0, read mode 0 */
+ outSISIDXREG(SISGR, 0x06, 0x05); /* set graphics */
+ slowbcopy_tobus(pSiS->fonts, vgaIOBase, 8192);
+
+ outSISIDXREG(SISSR, 0x02, 0x08); /* write to plane 3 */
+ outSISIDXREG(SISSR, 0x04, 0x06); /* enable plane graphics */
+ outSISIDXREG(SISGR, 0x04, 0x03); /* read plane 3 */
+ outSISIDXREG(SISGR, 0x05, 0x00); /* write mode 0, read mode 0 */
+ outSISIDXREG(SISGR, 0x06, 0x05); /* set graphics */
+ slowbcopy_tobus(pSiS->fonts + 8192, vgaIOBase, 8192);
+
+ inSISIDXREG(SISSR, 0x01, scrn);
+ outSISIDXREG(SISSR, 0x00, 0x01);
+ outSISIDXREG(SISSR, 0x01, scrn & ~0x20);
+ outSISIDXREG(SISSR, 0x00, 0x03);
+
+ /* restore the registers that were changed */
+ outSISREG(SISMISCW, miscOut);
+ SiS_WriteAttr(pSiS, 0x10, attr10);
+ outSISIDXREG(SISGR, 0x01, gr1);
+ outSISIDXREG(SISGR, 0x03, gr3);
+ outSISIDXREG(SISGR, 0x04, gr4);
+ outSISIDXREG(SISGR, 0x05, gr5);
+ outSISIDXREG(SISGR, 0x06, gr6);
+ outSISIDXREG(SISGR, 0x08, gr8);
+ outSISIDXREG(SISSR, 0x02, seq2);
+ outSISIDXREG(SISSR, 0x04, seq4);
+}
+
+/* TW: VESASaveRestore taken from vesa driver */
+static void
+SISVESASaveRestore(ScrnInfoPtr pScrn, vbeSaveRestoreFunction function)
+{
+ SISPtr pSiS;
+
+ pSiS = SISPTR(pScrn);
+
+ /* Query amount of memory to save state */
+ if (function == MODE_QUERY ||
+ (function == MODE_SAVE && pSiS->state == NULL)) {
+
+ /* Make sure we save at least this information in case of failure */
+ (void)VBEGetVBEMode(pSiS->pVbe, &pSiS->stateMode);
+ SiS_SaveFonts(pScrn);
+
+ if (pSiS->vesamajor > 1) {
+ if (!VBESaveRestore(pSiS->pVbe,function,(pointer)&pSiS->state,
+ &pSiS->stateSize,&pSiS->statePage))
+ return;
+
+ }
+ }
+
+ /* Save/Restore Super VGA state */
+ if (function != MODE_QUERY) {
+ Bool retval = TRUE;
+
+ if (pSiS->vesamajor > 1) {
+ if (function == MODE_RESTORE)
+ memcpy(pSiS->state, pSiS->pstate, pSiS->stateSize);
+
+ if ((retval = VBESaveRestore(pSiS->pVbe,function,
+ (pointer)&pSiS->state,
+ &pSiS->stateSize,&pSiS->statePage))
+ && function == MODE_SAVE) {
+ /* don't rely on the memory not being touched */
+ if (pSiS->pstate == NULL)
+ pSiS->pstate = xalloc(pSiS->stateSize);
+ memcpy(pSiS->pstate, pSiS->state, pSiS->stateSize);
+ }
+ }
+
+ if (function == MODE_RESTORE) {
+ VBESetVBEMode(pSiS->pVbe, pSiS->stateMode, NULL);
+ SiS_RestoreFonts(pScrn);
+ }
+#if 0
+ if (!retval)
+ return (FALSE);
+#endif
+
+ }
+#if 0
+ if ( (pSiS->vesamajor > 1) &&
+ (function == MODE_SAVE || pSiS->pstate) ) {
+ if (function == MODE_RESTORE)
+ memcpy(pSiS->state, pSiS->pstate, pSiS->stateSize);
+ if ((VBESaveRestore(pSiS->pVbe,function,
+ (pointer)&pSiS->state,
+ &pSiS->stateSize,&pSiS->statePage))) {
+ if (function == MODE_SAVE) {
+ /* don't rely on the memory not being touched */
+ if (pSiS->pstate == NULL)
+ pSiS->pstate = xalloc(pSiS->stateSize);
+ memcpy(pSiS->pstate, pSiS->state, pSiS->stateSize);
+ }
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+ "VBESaveRestore done with success\n");
+ return;
+ }
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+ "VBESaveRestore done\n");
+ } else {
+ if (function == MODE_SAVE)
+ (void)VBEGetVBEMode(pSiS->pVbe, &pSiS->stateMode);
+ else
+ VBESetVBEMode(pSiS->pVbe, pSiS->stateMode, NULL);
+ }
+#endif
+}
+
+/*
+ * Initialise a new mode. This is currently done using the
+ * "initialise struct, restore/write struct to HW" model for
+ * the old chipsets (5597/530/6326). For newer chipsets,
+ * we use either VESA or our own mode switching code.
+ */
+
+static Bool
+SISModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ vgaRegPtr vgaReg;
+ SISPtr pSiS = SISPTR(pScrn);
+ SISRegPtr sisReg;
+
+ vgaHWUnlock(hwp);
+
+ SISModifyModeInfo(mode);
+
+ /* TW: Initialize SiS Port Register definitions for externally used
+ * BIOS emulation (native code switching) functions.
+ */
+ if( pSiS->VGAEngine == SIS_300_VGA ||
+ pSiS->VGAEngine == SIS_315_VGA ) {
+ SiSRegInit(pSiS->SiS_Pr, pSiS->RelIO+0x30);
+ }
+
+ if (pSiS->UseVESA) { /* With VESA: */
+
+#ifdef SISDUALHEAD
+ /* TW: No dual head mode when using VESA */
+ if (pSiS->SecondHead) return TRUE;
+#endif
+ /*
+ * TW: This order is required:
+ * The video bridge needs to be adjusted before the
+ * BIOS is run as the BIOS sets up CRT2 according to
+ * these register settings.
+ * After the BIOS is run, the bridges and turboqueue
+ * registers need to be readjusted as the BIOS may
+ * very probably have messed them up.
+ */
+ if( pSiS->VGAEngine == SIS_300_VGA ||
+ pSiS->VGAEngine == SIS_315_VGA ) {
+ SiSPreSetMode(pScrn, mode);
+ }
+ if(!SiSSetVESAMode(pScrn, mode)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "SiSSetVESAMode() failed\n");
+ return FALSE;
+ }
+ sisSaveUnlockExtRegisterLock(pSiS,NULL,NULL);
+ if( pSiS->VGAEngine == SIS_300_VGA ||
+ pSiS->VGAEngine == SIS_315_VGA ) {
+ SiSPreSetMode(pScrn, mode);
+ SiSPostSetMode(pScrn, &pSiS->ModeReg);
+ }
+ /* TW: Prepare some register contents and set
+ * up some mode dependent variables.
+ */
+#ifdef TWDEBUG
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "REAL REGISTER CONTENTS AFTER SETMODE:\n");
+#endif
+ if (!(*pSiS->ModeInit)(pScrn, mode)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "ModeInit() failed\n");
+ return FALSE;
+ }
+
+ pScrn->vtSema = TRUE;
+
+ /* Program the registers */
+ vgaHWProtect(pScrn, TRUE);
+ (*pSiS->SiSRestore)(pScrn, &pSiS->ModeReg);
+ vgaHWProtect(pScrn, FALSE);
+ PDEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "HDisplay: %d, VDisplay: %d \n",
+ mode->HDisplay, mode->VDisplay));
+
+ } else { /* Without VESA: */
+#ifdef SISDUALHEAD
+ if(pSiS->DualHeadMode) {
+ if(!(*pSiS->ModeInit)(pScrn, mode)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "ModeInit() failed\n");
+ return FALSE;
+ }
+
+ pScrn->vtSema = TRUE;
+
+ if(!(pSiS->SecondHead)) {
+ /* TW: Head 1 (master) is always CRT2 */
+ SiSPreSetMode(pScrn, mode);
+ if (!SiSBIOSSetModeCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pScrn, mode)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "SiSBIOSSetModeCRT2() failed\n");
+ return FALSE;
+ }
+ SiSPostSetMode(pScrn, &pSiS->ModeReg);
+ } else {
+ /* TW: Head 2 (slave) is always CRT1 */
+ SiSPreSetMode(pScrn, mode);
+ if (!SiSBIOSSetModeCRT1(pSiS->SiS_Pr, &pSiS->sishw_ext, pScrn, mode, pSiS->IsCustom)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "SiSBIOSSetModeCRT1() failed\n");
+ return FALSE;
+ }
+ SiSPostSetMode(pScrn, &pSiS->ModeReg);
+ }
+ } else {
+#endif
+ if(pSiS->VGAEngine == SIS_300_VGA ||
+ pSiS->VGAEngine == SIS_315_VGA) {
+
+ /* TW: Prepare the register contents; On 300/310/325,
+ * we actually "abuse" this only for setting
+ * up some variables; the registers are NOT
+ * being written to the hardware as the BIOS
+ * emulation (native mode switching code)
+ * takes care of this.
+ */
+ if(!(*pSiS->ModeInit)(pScrn, mode)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "ModeInit() failed\n");
+ return FALSE;
+ }
+
+ pScrn->vtSema = TRUE;
+
+ /* 300/310/325 series: Use our own code for mode switching */
+ SiSPreSetMode(pScrn, mode);
+
+ if(!SiSBIOSSetMode(pSiS->SiS_Pr, &pSiS->sishw_ext, pScrn, mode, pSiS->IsCustom)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "SiSBIOSSetMode() failed\n");
+ return FALSE;
+ }
+
+ SiSPostSetMode(pScrn, &pSiS->ModeReg);
+#ifdef TWDEBUG
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "REAL REGISTER CONTENTS AFTER SETMODE:\n");
+ (*pSiS->ModeInit)(pScrn, mode);
+#endif
+ } else {
+
+ /* For other chipsets, use the old method */
+
+ /* Initialise the ModeReg values */
+ if(!vgaHWInit(pScrn, mode)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "vgaHWInit() failed\n");
+ return FALSE;
+ }
+
+ /* Reset our PIOOffset as vgaHWInit might have reset it */
+ VGAHWPTR(pScrn)->PIOOffset = pSiS->IODBase + (pSiS->PciInfo->ioBase[2] & 0xFFFC) - 0x380;
+
+ /* Prepare the register contents */
+ if(!(*pSiS->ModeInit)(pScrn, mode)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "ModeInit() failed\n");
+ return FALSE;
+ }
+
+ pScrn->vtSema = TRUE;
+
+ /* Program the registers */
+ vgaHWProtect(pScrn, TRUE);
+ vgaReg = &hwp->ModeReg;
+ sisReg = &pSiS->ModeReg;
+
+ vgaReg->Attribute[0x10] = 0x01;
+ if(pScrn->bitsPerPixel > 8) {
+ vgaReg->Graphics[0x05] = 0x00;
+ }
+
+ vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE);
+
+ (*pSiS->SiSRestore)(pScrn, sisReg);
+
+ if((pSiS->Chipset == PCI_CHIP_SIS6326) && (pSiS->SiS6326Flags & SIS6326_HASTV)) {
+ SiS6326PostSetMode(pScrn, &pSiS->ModeReg);
+ }
+
+#ifdef TWDEBUG
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "REAL REGISTER CONTENTS AFTER SETMODE:\n");
+ (*pSiS->ModeInit)(pScrn, mode);
+#endif
+
+ vgaHWProtect(pScrn, FALSE);
+ }
+#ifdef SISDUALHEAD
+ }
+#endif
+ }
+
+ /* TW: Update Currentlayout */
+ pSiS->CurrentLayout.mode = mode;
+
+ /* Debug */
+/* SiSDumpModeInfo(pScrn, mode); */
+
+ return TRUE;
+}
+
+static Bool
+SiSSetVESAMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
+{
+ SISPtr pSiS;
+ int mode;
+
+ pSiS = SISPTR(pScrn);
+
+ if (!(mode = SiSCalcVESAModeIndex(pScrn, pMode))) return FALSE;
+
+ mode |= 1 << 15; /* TW: Don't clear framebuffer */
+ mode |= 1 << 14; /* TW: Use linear adressing */
+
+ if(VBESetVBEMode(pSiS->pVbe, mode, NULL) == FALSE) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Setting VESA mode 0x%x failed\n",
+ mode & 0x0fff);
+ return (FALSE);
+ }
+
+ if(pMode->HDisplay != pScrn->virtualX)
+ VBESetLogicalScanline(pSiS->pVbe, pScrn->virtualX);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Setting VESA mode 0x%x succeeded\n",
+ mode & 0x0fff);
+
+ return (TRUE);
+}
+
+/*
+ * Restore the initial mode. To be used internally only!
+ */
+static void
+SISRestore(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ SISRegPtr sisReg = &pSiS->SavedReg;
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ vgaRegPtr vgaReg = &hwp->SavedReg;
+ Bool doit = FALSE, doitlater = FALSE;
+
+ if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
+
+#ifdef SISDUALHEAD
+ /* TW: We always restore master AND slave */
+ if(pSiS->DualHeadMode && pSiS->SecondHead) return;
+#endif
+
+ /* TW: We must not disable the sequencer if the bridge is in SlaveMode! */
+ if(!(SiSBridgeIsInSlaveMode(pScrn))) {
+ vgaHWProtect(pScrn, TRUE);
+ }
+
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL,NULL);
+#endif
+
+ /* TW: First, restore CRT1 on/off and VB connection registers */
+ outSISIDXREG(SISCR, 0x32, pSiS->oldCR32);
+ if(!(pSiS->oldCR17 & 0x80)) { /* TW: CRT1 was off */
+ if(!(SiSBridgeIsInSlaveMode(pScrn))) { /* TW: Bridge is NOT in SlaveMode now -> do it */
+ doit = TRUE;
+ } else {
+ doitlater = TRUE;
+ }
+ } else { /* TW: CRT1 was on -> do it now */
+ doit = TRUE;
+ }
+
+ if(doit) {
+ outSISIDXREG(SISCR, 0x17, pSiS->oldCR17);
+ }
+
+ /* TW: For 30xB/LV, restoring the registers does not
+ * work. We "manually" set the old mode, instead.
+ * The same applies for SiS730 machines with LVDS.
+ * Finally, this behavior can be forced by setting
+ * the option RestoreBySetMode.
+ */
+ if( ( (pSiS->restorebyset) ||
+ (pSiS->VBFlags & (VB_301B|VB_302B|VB_30xLV|VB_30xLVX)) ||
+ ((pSiS->sishw_ext.jChipType == SIS_730) && (pSiS->VBFlags & VB_LVDS)) ) &&
+ (pSiS->OldMode) ) {
+
+ if(pSiS->AccelInfoPtr) {
+ (*pSiS->AccelInfoPtr->Sync)(pScrn);
+ }
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+ "Restoring by setting old mode 0x%02x\n", pSiS->OldMode);
+
+ if( (pSiS->VBFlags & (VB_301B|VB_302B|VB_30xLV|VB_30xLVX)) &&
+ (!pSiS->restorebyset) ) {
+ if(pSiS->OldMode == 0x03) pSiS->OldMode = 0x13;
+ }
+
+ pSiS->SiS_Pr->UseCustomMode = FALSE;
+ pSiS->SiS_Pr->CRT1UsesCustomMode = FALSE;
+ SiSSetMode(pSiS->SiS_Pr, &pSiS->sishw_ext, pScrn, pSiS->OldMode, FALSE);
+#ifdef TWDEBUG
+ {
+ SISRegPtr pReg = &pSiS->ModeReg;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "REAL REGISTER CONTENTS AFTER RESTORE BY SETMODE:\n");
+ (*pSiS->SiSSave)(pScrn, pReg);
+ }
+#endif
+
+ } else {
+
+ if(pSiS->VBFlags & VB_VIDEOBRIDGE) {
+ /* TW: If a video bridge is present, we need to restore
+ * non-extended (=standard VGA) SR and CR registers
+ * before restoring the extended ones and the bridge
+ * registers itself. Unfortunately, the vgaHWRestore
+ * routine clears CR17[7] - which must not be done if
+ * the bridge is in slave mode.
+ */
+ if(!(SiSBridgeIsInSlaveMode(pScrn))) {
+ vgaHWProtect(pScrn, TRUE);
+
+ if(pSiS->Primary) {
+ vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE);
+ }
+ }
+ }
+
+ (*pSiS->SiSRestore)(pScrn, sisReg);
+
+ }
+
+ if(doitlater) {
+ outSISIDXREG(SISCR, 0x17, pSiS->oldCR17);
+ }
+
+ sisRestoreExtRegisterLock(pSiS,sisReg->sisRegs3C4[0x05],sisReg->sisRegs3D4[0x80]);
+
+ if( ( (pSiS->sishw_ext.jChipType == SIS_730) && (pSiS->VBFlags & VB_LVDS)) ||
+ (pSiS->restorebyset) ) {
+
+ /* TW: SiS730/LVDS has extreme problems restoring the text display due
+ * to over-sensible LCD panels
+ */
+
+ vgaHWProtect(pScrn, TRUE);
+
+ if(pSiS->Primary) {
+ vgaHWRestore(pScrn, vgaReg, (VGA_SR_FONTS | VGA_SR_CMAP));
+ }
+
+ vgaHWProtect(pScrn, FALSE);
+
+ } else {
+
+ vgaHWProtect(pScrn, TRUE);
+
+ if(pSiS->Primary) {
+ vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL);
+ }
+
+ vgaHWProtect(pScrn, FALSE);
+
+ }
+
+ } else { /* All other chipsets */
+
+ vgaHWProtect(pScrn, TRUE);
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL,NULL);
+#endif
+ (*pSiS->SiSRestore)(pScrn, sisReg);
+
+ vgaHWProtect(pScrn, TRUE);
+ if(pSiS->Primary) {
+ vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL);
+ }
+
+ /* TW: Restore TV. This is rather complicated, but if we don't do it,
+ * TV output will flicker terribly
+ */
+ if((pSiS->Chipset == PCI_CHIP_SIS6326) && (pSiS->SiS6326Flags & SIS6326_HASTV)) {
+ if(sisReg->sis6326tv[0] & 0x04) {
+ unsigned char tmp;
+ int val;
+
+ orSISIDXREG(SISSR, 0x01, 0x20);
+ tmp = SiS6326GetTVReg(pScrn,0x00);
+ tmp &= ~0x04;
+ while(!(inSISREG(SISINPSTAT) & 0x08)); /* Wait while NOT vb */
+ SiS6326SetTVReg(pScrn,0x00,tmp);
+ for(val=0; val < 2; val++) {
+ while(!(inSISREG(SISINPSTAT) & 0x08)); /* Wait while NOT vb */
+ while(inSISREG(SISINPSTAT) & 0x08); /* wait while vb */
+ }
+ SiS6326SetTVReg(pScrn, 0x00, sisReg->sis6326tv[0]);
+ tmp = inSISREG(SISINPSTAT);
+ outSISREG(SISAR, 0x20);
+ tmp = inSISREG(SISINPSTAT);
+ while(inSISREG(SISINPSTAT) & 0x01);
+ while(!(inSISREG(SISINPSTAT) & 0x01));
+ andSISIDXREG(SISSR, 0x01, ~0x20);
+ for(val=0; val < 10; val++) {
+ while(!(inSISREG(SISINPSTAT) & 0x08)); /* Wait while NOT vb */
+ while(inSISREG(SISINPSTAT) & 0x08); /* wait while vb */
+ }
+ andSISIDXREG(SISSR, 0x01, ~0x20);
+ }
+ }
+
+ sisRestoreExtRegisterLock(pSiS,sisReg->sisRegs3C4[5],sisReg->sisRegs3D4[0x80]);
+
+ vgaHWProtect(pScrn, FALSE);
+ }
+}
+
+static void
+SISVESARestore(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+
+ if(pSiS->UseVESA) SISVESASaveRestore(pScrn, MODE_RESTORE);
+}
+
+/* TW: Restore bridge registers - to be called BEFORE VESARestore */
+static void
+SISBridgeRestore(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+
+#ifdef SISDUALHEAD
+ /* We only restore for master head */
+ if(pSiS->DualHeadMode && pSiS->SecondHead) return;
+#endif
+
+ if(pSiS->VGAEngine == SIS_300_VGA || pSiS->VGAEngine == SIS_315_VGA) {
+ SiSRestoreBridge(pScrn, &pSiS->SavedReg);
+ }
+}
+
+/* TW: Our generic BlockHandler for Xv */
+static void
+SISBlockHandler(int i, pointer blockData, pointer pTimeout, pointer pReadmask)
+{
+ ScreenPtr pScreen = screenInfo.screens[i];
+ ScrnInfoPtr pScrn = xf86Screens[i];
+ SISPtr pSiS = SISPTR(pScrn);
+
+ pScreen->BlockHandler = pSiS->BlockHandler;
+ (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
+ pScreen->BlockHandler = SISBlockHandler;
+
+ if(pSiS->VideoTimerCallback) {
+ (*pSiS->VideoTimerCallback)(pScrn, currentTime.milliseconds);
+ }
+}
+
+/* Mandatory
+ * This gets called at the start of each server generation
+ *
+ * TW: We use pScrn and not CurrentLayout here, because the
+ * properties we use have not changed (displayWidth,
+ * depth, bitsPerPixel)
+ */
+static Bool
+SISScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+{
+ ScrnInfoPtr pScrn;
+ vgaHWPtr hwp;
+ SISPtr pSiS;
+ int ret;
+ int init_picture = 0;
+ VisualPtr visual;
+ unsigned long OnScreenSize;
+ int height, width, displayWidth;
+ unsigned char *FBStart;
+#ifdef SISDUALHEAD
+ SISEntPtr pSiSEnt = NULL;
+#endif
+
+ pScrn = xf86Screens[pScreen->myNum];
+
+ hwp = VGAHWPTR(pScrn);
+
+ pSiS = SISPTR(pScrn);
+
+ if(pSiS->UseVESA) {
+#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,99,0,0)
+ pSiS->pVbe = VBEInit(NULL, pSiS->pEnt->index);
+#else
+ pSiS->pVbe = VBEExtendedInit(NULL, pSiS->pEnt->index,
+ SET_BIOS_SCRATCH | RESTORE_BIOS_SCRATCH);
+#endif
+ }
+
+#ifdef SISDUALHEAD
+ if(pSiS->DualHeadMode) {
+ pSiSEnt = pSiS->entityPrivate;
+ pSiSEnt->refCount++;
+ }
+#endif
+
+ /* Map the VGA memory and get the VGA IO base */
+ if(pSiS->Primary) {
+ hwp->MapSize = 0x10000; /* Standard 64k VGA window */
+ if(!vgaHWMapMem(pScrn)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Could not map VGA window\n");
+ return FALSE;
+ }
+ }
+ vgaHWGetIOBase(hwp);
+
+ /* TW: Patch the PIOOffset inside vgaHW to use
+ * our relocated IO ports.
+ */
+ VGAHWPTR(pScrn)->PIOOffset = pSiS->IODBase + (pSiS->PciInfo->ioBase[2] & 0xFFFC) - 0x380;
+
+ /* Map the SIS memory and MMIO areas */
+ if(!SISMapMem(pScrn)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "SiSMapMem() failed\n");
+ return FALSE;
+ }
+
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+
+ /* TW: Enable TurboQueue so that SISSave() saves it in enabled
+ * state. If we don't do this, X will hang after a restart!
+ * (Happens for some unknown reason only when using VESA
+ * for mode switching; assumingly a BIOS issue.)
+ * This is done on 300 and 310/325 series only.
+ */
+ if(pSiS->UseVESA) {
+ SiSEnableTurboQueue(pScrn);
+ }
+
+ /* Save the current state */
+ SISSave(pScrn);
+
+ /* TW: Save the current mode number */
+ if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
+ inSISIDXREG(SISCR, 0x34, pSiS->OldMode);
+ }
+
+ /* Initialise the first mode */
+ if(!SISModeInit(pScrn, pScrn->currentMode)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "SiSModeInit() failed\n");
+ return FALSE;
+ }
+
+ /* Darken the screen for aesthetic reasons */
+ /* TW: Not using Dual Head variant on purpose; we darken
+ * the screen for both displays, and un-darken
+ * it when the second head is finished
+ */
+ SISSaveScreen(pScreen, SCREEN_SAVER_ON);
+
+ /* Set the viewport */
+ SISAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+
+ /* Clear frame buffer */
+ OnScreenSize = pScrn->displayWidth * pScrn->currentMode->VDisplay
+ * (pScrn->bitsPerPixel / 8);
+ bzero(pSiS->FbBase, OnScreenSize);
+
+ /*
+ * The next step is to setup the screen's visuals, and initialise the
+ * framebuffer code. In cases where the framebuffer's default
+ * choices for things like visual layouts and bits per RGB are OK,
+ * this may be as simple as calling the framebuffer's ScreenInit()
+ * function. If not, the visuals will need to be setup before calling
+ * a fb ScreenInit() function and fixed up after.
+ *
+ * For most PC hardware at depths >= 8, the defaults that cfb uses
+ * are not appropriate. In this driver, we fixup the visuals after.
+ */
+
+ /*
+ * Reset visual list.
+ */
+ miClearVisualTypes();
+
+ /* Setup the visuals we support. */
+
+ /*
+ * For bpp > 8, the default visuals are not acceptable because we only
+ * support TrueColor and not DirectColor.
+ */
+ if(pScrn->bitsPerPixel > 8) {
+ if(!miSetVisualTypes(pScrn->depth, TrueColorMask, pScrn->rgbBits,
+ pScrn->defaultVisual)) {
+ SISSaveScreen(pScreen, SCREEN_SAVER_OFF);
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "miSetVisualTypes() failed (bpp %d)\n", pScrn->bitsPerPixel);
+ return FALSE;
+ }
+ } else {
+ if(!miSetVisualTypes(pScrn->depth,
+ miGetDefaultVisualMask(pScrn->depth),
+ pScrn->rgbBits, pScrn->defaultVisual)) {
+ SISSaveScreen(pScreen, SCREEN_SAVER_OFF);
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "miSetVisualTypes() failed (bpp %d)\n", pScrn->bitsPerPixel);
+ return FALSE;
+ }
+ }
+
+ width = pScrn->virtualX;
+ height = pScrn->virtualY;
+ displayWidth = pScrn->displayWidth;
+
+ if(pSiS->Rotate) {
+ height = pScrn->virtualX;
+ width = pScrn->virtualY;
+ }
+
+ if(pSiS->ShadowFB) {
+ pSiS->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width);
+ pSiS->ShadowPtr = xalloc(pSiS->ShadowPitch * height);
+ displayWidth = pSiS->ShadowPitch / (pScrn->bitsPerPixel >> 3);
+ FBStart = pSiS->ShadowPtr;
+ } else {
+ pSiS->ShadowPtr = NULL;
+ FBStart = pSiS->FbBase;
+ }
+
+ if(!miSetPixmapDepths()) {
+ SISSaveScreen(pScreen, SCREEN_SAVER_OFF);
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "miSetPixmapDepths() failed\n");
+ return FALSE;
+ }
+
+#ifdef SISDUALHEAD
+ if(pSiS->SecondHead)
+ pSiS->cmdQueueLenPtr = &(SISPTR(pSiSEnt->pScrn_1)->cmdQueueLen);
+ else
+#endif
+ pSiS->cmdQueueLenPtr = &(pSiS->cmdQueueLen);
+
+ pSiS->cmdQueueLen = 0; /* TW: Force an EngineIdle() at start */
+
+#ifdef XF86DRI
+#ifdef SISDUALHEAD
+ /* TW: No DRI in dual head mode */
+ if(pSiS->DualHeadMode) {
+ pSiS->directRenderingEnabled = FALSE;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "DRI not supported in Dual Head mode\n");
+ } else
+#endif
+ /* Force the initialization of the context */
+ if(pSiS->VGAEngine != SIS_315_VGA) {
+ pSiS->directRenderingEnabled = SISDRIScreenInit(pScreen);
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_NOT_IMPLEMENTED,
+ "DRI not supported on this chipset\n");
+ pSiS->directRenderingEnabled = FALSE;
+ }
+#endif
+
+ /*
+ * Call the framebuffer layer's ScreenInit function, and fill in other
+ * pScreen fields.
+ */
+
+ switch(pScrn->bitsPerPixel) {
+ case 1:
+ ret = xf1bppScreenInit(pScreen, FBStart, width,
+ height, pScrn->xDpi, pScrn->yDpi,
+ displayWidth);
+ break;
+ case 4:
+ ret = xf4bppScreenInit(pScreen, FBStart, width,
+ height, pScrn->xDpi, pScrn->yDpi,
+ displayWidth);
+ break;
+ case 8:
+ case 16:
+ case 24:
+ case 32:
+ ret = fbScreenInit(pScreen, FBStart, width,
+ height, pScrn->xDpi, pScrn->yDpi,
+ displayWidth, pScrn->bitsPerPixel);
+
+ init_picture = 1;
+ break;
+ default:
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Internal error: invalid bpp (%d) in SISScrnInit\n",
+ pScrn->bitsPerPixel);
+ ret = FALSE;
+ break;
+ }
+ if (!ret) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "xf1bpp/xf4bpp/fbScreenInit() failed\n");
+ SISSaveScreen(pScreen, SCREEN_SAVER_OFF);
+ return FALSE;
+ }
+
+ if(pScrn->bitsPerPixel > 8) {
+ /* Fixup RGB ordering */
+ visual = pScreen->visuals + pScreen->numVisuals;
+ while (--visual >= pScreen->visuals) {
+ if ((visual->class | DynamicClass) == DirectColor) {
+ visual->offsetRed = pScrn->offset.red;
+ visual->offsetGreen = pScrn->offset.green;
+ visual->offsetBlue = pScrn->offset.blue;
+ visual->redMask = pScrn->mask.red;
+ visual->greenMask = pScrn->mask.green;
+ visual->blueMask = pScrn->mask.blue;
+ }
+ }
+ } else if(pScrn->depth == 1) {
+ SIS1bppColorMap(pScrn);
+ }
+
+ /* Initialize RENDER ext; must be after RGB ordering fixed */
+ if(init_picture) fbPictureInit(pScreen, 0, 0);
+
+ /* hardware cursor needs to wrap this layer <-- TW: what does that mean? */
+ if(!pSiS->ShadowFB) SISDGAInit(pScreen);
+
+ xf86SetBlackWhitePixels(pScreen);
+
+ if(!pSiS->NoAccel) {
+ switch(pSiS->VGAEngine) {
+ case SIS_530_VGA:
+ case SIS_300_VGA:
+ SiS300AccelInit(pScreen);
+ break;
+ case SIS_315_VGA:
+ SiS310AccelInit(pScreen);
+ break;
+ default:
+ SiSAccelInit(pScreen);
+ }
+ }
+ miInitializeBackingStore(pScreen);
+ xf86SetBackingStore(pScreen);
+ xf86SetSilkenMouse(pScreen);
+
+ /* Initialise cursor functions */
+ miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
+
+ if(pSiS->HWCursor)
+ SiSHWCursorInit(pScreen);
+
+ /* Initialise default colourmap */
+ if(!miCreateDefColormap(pScreen)) {
+ SISSaveScreen(pScreen, SCREEN_SAVER_OFF);
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "miCreateDefColormap() failed\n");
+ return FALSE;
+ }
+
+ if(!xf86HandleColormaps(pScreen, 256, (pScrn->depth == 8) ? 8 : pScrn->rgbBits,
+ SISLoadPalette, NULL,
+ CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH)) {
+ SISSaveScreen(pScreen, SCREEN_SAVER_OFF);
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "xf86HandleColormaps() failed\n");
+ return FALSE;
+ }
+
+ if(pSiS->ShadowFB) {
+ RefreshAreaFuncPtr refreshArea = SISRefreshArea;
+
+ if(pSiS->Rotate) {
+ if(!pSiS->PointerMoved) {
+ pSiS->PointerMoved = pScrn->PointerMoved;
+ pScrn->PointerMoved = SISPointerMoved;
+ }
+
+ switch(pScrn->bitsPerPixel) {
+ case 8: refreshArea = SISRefreshArea8; break;
+ case 16: refreshArea = SISRefreshArea16; break;
+ case 24: refreshArea = SISRefreshArea24; break;
+ case 32: refreshArea = SISRefreshArea32; break;
+ }
+ }
+
+ ShadowFBInit(pScreen, refreshArea);
+ }
+
+#ifdef SISDUALHEAD
+ if(pSiS->DualHeadMode)
+ /* TW: DPMS for dual head mode */
+ xf86DPMSInit(pScreen, (DPMSSetProcPtr)SISDisplayPowerManagementSetDH, 0);
+ else
+#endif
+ xf86DPMSInit(pScreen, (DPMSSetProcPtr)SISDisplayPowerManagementSet, 0);
+
+ /* Init memPhysBase and fbOffset in pScrn */
+ pScrn->memPhysBase = pSiS->FbAddress;
+ pScrn->fbOffset = 0;
+
+#ifdef XvExtension
+ if(!pSiS->NoXvideo) {
+#ifdef SISDUALHEAD
+ /* TW: On chipsets with only one overlay, we support
+ * Xv only in "real" dual head mode, not Xinerama
+ */
+ if ( ((pSiS->VGAEngine == SIS_300_VGA) ||
+ (pSiS->VGAEngine == SIS_315_VGA) )
+ &&
+ ((pSiS->hasTwoOverlays) ||
+ (!pSiS->DualHeadMode) ||
+ (noPanoramiXExtension) ) ) {
+#else
+ if ( (pSiS->VGAEngine == SIS_300_VGA) ||
+ (pSiS->VGAEngine == SIS_315_VGA) ) {
+#endif
+#ifdef SISDUALHEAD
+ if (pSiS->DualHeadMode) {
+ if ( pSiS->hasTwoOverlays ||
+ (pSiS->XvOnCRT2 && (!pSiS->SecondHead)) ||
+ ((!pSiS->XvOnCRT2 && pSiS->SecondHead)) ) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Using SiS300/310/325 series HW Xv on CRT%d\n",
+ (pSiS->SecondHead ? 1 : 2));
+ SISInitVideo(pScreen);
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Not using SiS300/310/325 series HW Xv on CRT%d\n",
+ (pSiS->SecondHead ? 1 : 2));
+ }
+ } else {
+#endif
+ if (pSiS->hasTwoOverlays)
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Using SiS300/310/325 series HW Xv\n" );
+ else
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Using SiS300/310/325 series HW Xv on CRT%d\n",
+ (pSiS->XvOnCRT2 ? 2 : 1));
+ SISInitVideo(pScreen);
+#ifdef SISDUALHEAD
+ }
+#endif
+#ifdef USE6326VIDEO
+ } else if( pSiS->Chipset == PCI_CHIP_SIS6326 ||
+ pSiS->Chipset == PCI_CHIP_SIS530 ||
+ pSiS->Chipset == PCI_CHIP_SIS5597 ) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Using SiS5597/5598/6326/530/620 HW Xv\n" );
+ SIS6326InitVideo(pScreen);
+#endif
+ } else { /* generic Xv */
+
+ XF86VideoAdaptorPtr *ptr;
+ int n;
+
+ n = xf86XVListGenericAdaptors(pScrn, &ptr);
+ if (n) {
+ xf86XVScreenInit(pScreen, ptr, n);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using generic Xv\n" );
+ }
+ if (!noPanoramiXExtension)
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "HW Xv not supported in Xinerama mode\n");
+ }
+ }
+#endif
+
+#ifdef XF86DRI
+ if(pSiS->directRenderingEnabled) {
+ /* Now that mi, drm and others have done their thing,
+ * complete the DRI setup.
+ */
+ pSiS->directRenderingEnabled = SISDRIFinishScreenInit(pScreen);
+ }
+ if(pSiS->directRenderingEnabled) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering enabled\n");
+ /* TODO */
+ /* SISSetLFBConfig(pSiS); */
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering disabled\n");
+ }
+#endif
+
+ pSiS->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = SISCloseScreen;
+#ifdef SISDUALHEAD
+ if(pSiS->DualHeadMode)
+ pScreen->SaveScreen = SISSaveScreenDH;
+ else
+#endif
+ pScreen->SaveScreen = SISSaveScreen;
+
+ /* Install BlockHandler */
+ pSiS->BlockHandler = pScreen->BlockHandler;
+ pScreen->BlockHandler = SISBlockHandler;
+
+ /* Report any unused options (only for the first generation) */
+ if(serverGeneration == 1) {
+ xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
+ }
+
+ /* Turn on the screen now */
+ /* TW: We do this in dual head mode after second head is finished */
+#ifdef SISDUALHEAD
+ if(pSiS->DualHeadMode) {
+ if(pSiS->SecondHead)
+ SISSaveScreen(pScreen, SCREEN_SAVER_OFF);
+ } else
+#endif
+ SISSaveScreen(pScreen, SCREEN_SAVER_OFF);
+
+ return TRUE;
+}
+
+/* Usually mandatory */
+Bool
+SISSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ SISPtr pSiS = SISPTR(pScrn);
+
+ if(!pSiS->NoAccel) {
+ if(pSiS->AccelInfoPtr) {
+ (*pSiS->AccelInfoPtr->Sync)(pScrn);
+ }
+ }
+
+ return SISModeInit(xf86Screens[scrnIndex], mode);
+}
+
+#ifdef CYCLECRT2
+/* TW: Cycle CRT2 output devices */
+Bool
+SISCycleCRT2Type(int scrnIndex, DisplayModePtr mode)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ SISPtr pSiS = SISPTR(pScrn);
+ int i = 0;
+
+ /* TW: Only on 300 and 310/325 series */
+ if(pSiS->VGAEngine != SIS_300_VGA &&
+ pSiS->VGAEngine != SIS_315_VGA) return FALSE;
+
+ /* TW: Only if there is a video bridge */
+ if(pSiS->VBFlags & VB_VIDEOBRIDGE) return FALSE;
+
+ /* TW: Only if there were more than 1 CRT2 devices detected */
+ if(pSiS->detectedCRT2Devices & CRT2_VGA) i++;
+ if(pSiS->detectedCRT2Devices & CRT2_LCD) i++;
+ if(pSiS->detectedCRT2Devices & CRT2_TV) i++;
+ if(i <= 1) return FALSE;
+
+ /* TW: Cycle CRT2 type */
+ i = (pSiS->VBFlags & DISPTYPE_DISP2) << 1;
+ while(!(i & pSiS->detectedCRT2Devices)) {
+ i <<= 1;
+ if(i > CRT2_VGA) i = CRT2_LCD;
+ }
+
+ /* TW: Check if mode is suitable for desired output device */
+ if(!SiS_CheckCalcModeIndex(pScrn, pScrn->currentMode,
+ ((pSiS->VBFlags & ~(DISPTYPE_DISP2)) | i))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Current mode not suitable for desired CRT2 output device\n");
+ return FALSE;
+ }
+
+ /* TW: Sync the accelerators */
+ if(!pSiS->NoAccel) {
+ if(pSiS->AccelInfoPtr) {
+ (*pSiS->AccelInfoPtr->Sync)(pScrn);
+ }
+ }
+
+ pSiS->VBFlags &= ~(DISPTYPE_DISP2);
+ pSiS->VBFlags |= i;
+
+ return SISModeInit(xf86Screens[scrnIndex], mode);
+}
+#endif
+
+/*
+ * This function is used to initialize the Start Address - the first
+ * displayed location in the video memory.
+ */
+/* Usually mandatory */
+void
+SISAdjustFrame(int scrnIndex, int x, int y, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ SISPtr pSiS;
+ vgaHWPtr hwp;
+ int base;
+ unsigned char temp;
+
+ hwp = VGAHWPTR(pScrn);
+ pSiS = SISPTR(pScrn);
+
+ base = y * pSiS->CurrentLayout.displayWidth + x;
+
+ if(pSiS->UseVESA) {
+
+ /* TW: Let BIOS adjust frame if using VESA */
+ VBESetDisplayStart(pSiS->pVbe, x, y, TRUE);
+
+ } else {
+
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+
+ if(pScrn->bitsPerPixel < 8) {
+ base = (y * pSiS->CurrentLayout.displayWidth + x + 3) >> 3;
+ } else {
+ base = y * pSiS->CurrentLayout.displayWidth + x;
+
+ /* calculate base bpp dep. */
+ switch(pSiS->CurrentLayout.bitsPerPixel) {
+ case 16:
+ base >>= 1;
+ break;
+ case 24:
+ base = ((base * 3)) >> 2;
+ base -= base % 6;
+ break;
+ case 32:
+ break;
+ default: /* 8bpp */
+ base >>= 2;
+ break;
+ }
+ }
+
+#ifdef SISDUALHEAD
+ if (pSiS->DualHeadMode) {
+ /* TW: We assume that DualHeadMode only can be true for
+ * dual head capable chipsets (and thus save the check
+ * for chipset here)
+ */
+ if (!pSiS->SecondHead) {
+ /* TW: Head 1 (master) is always CRT2 */
+ SiS_UnLockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30);
+ outSISIDXREG(SISPART1, 0x06, GETVAR8(base));
+ outSISIDXREG(SISPART1, 0x05, GETBITS(base, 15:8));
+ outSISIDXREG(SISPART1, 0x04, GETBITS(base, 23:16));
+ if (pSiS->VGAEngine == SIS_315_VGA) {
+ setSISIDXREG(SISPART1, 0x02, 0x7F, ((base >> 24) & 0x01) << 7);
+ }
+ SiS_LockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30);
+ } else {
+ /* TW: Head 2 (slave) is always CRT1 */
+ base += (pSiS->dhmOffset/4);
+ outSISIDXREG(SISCR, 0x0D, base & 0xFF);
+ outSISIDXREG(SISCR, 0x0C, (base >> 8) & 0xFF);
+ outSISIDXREG(SISSR, 0x0D, (base >> 16) & 0xFF);
+ if (pSiS->VGAEngine == SIS_315_VGA) {
+ setSISIDXREG(SISSR, 0x37, 0xFE, (base >> 24) & 0x01);
+ }
+ }
+ } else {
+#endif
+ switch (pSiS->VGAEngine) {
+ case SIS_300_VGA:
+ outSISIDXREG(SISCR, 0x0D, base & 0xFF);
+ outSISIDXREG(SISCR, 0x0C, (base >> 8) & 0xFF);
+ outSISIDXREG(SISSR, 0x0D, (base >> 16) & 0xFF);
+ if (pSiS->VBFlags & CRT2_ENABLE) {
+ SiS_UnLockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30);
+ outSISIDXREG(SISPART1, 0x06, GETVAR8(base));
+ outSISIDXREG(SISPART1, 0x05, GETBITS(base, 15:8));
+ outSISIDXREG(SISPART1, 0x04, GETBITS(base, 23:16));
+ SiS_LockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30);
+ }
+ break;
+ case SIS_315_VGA:
+ outSISIDXREG(SISCR, 0x0D, base & 0xFF);
+ outSISIDXREG(SISCR, 0x0C, (base >> 8) & 0xFF);
+ outSISIDXREG(SISSR, 0x0D, (base >> 16) & 0xFF);
+ setSISIDXREG(SISSR, 0x37, 0xFE, (base >> 24) & 0x01);
+ if (pSiS->VBFlags & CRT2_ENABLE) {
+ SiS_UnLockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30);
+ outSISIDXREG(SISPART1, 0x06, GETVAR8(base));
+ outSISIDXREG(SISPART1, 0x05, GETBITS(base, 15:8));
+ outSISIDXREG(SISPART1, 0x04, GETBITS(base, 23:16));
+ setSISIDXREG(SISPART1, 0x02, 0x7F, ((base >> 24) & 0x01) << 7);
+ SiS_LockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30);
+ }
+ break;
+ default:
+ outSISIDXREG(SISCR, 0x0D, base & 0xFF);
+ outSISIDXREG(SISCR, 0x0C, (base >> 8) & 0xFF);
+ inSISIDXREG(SISSR, 0x27, temp);
+ temp &= 0xF0;
+ temp |= (base & 0x0F0000) >> 16;
+ outSISIDXREG(SISSR, 0x27, temp);
+ }
+#ifdef SISDUALHEAD
+ }
+#endif
+ } /* if not VESA */
+
+}
+
+
+/*
+ * This is called when VT switching back to the X server. Its job is
+ * to reinitialise the video mode.
+ * Mandatory!
+ */
+static Bool
+SISEnterVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ SISPtr pSiS = SISPTR(pScrn);
+
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+
+ if(!SISModeInit(pScrn, pScrn->currentMode)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "SiSEnterVT: SISModeInit() failed\n");
+ return FALSE;
+ }
+
+ SISAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+
+#ifdef XF86DRI
+ /* TW: this is to be done AFTER switching the mode */
+ if(pSiS->directRenderingEnabled)
+ DRIUnlock(screenInfo.screens[scrnIndex]);
+#endif
+
+ return TRUE;
+}
+
+/*
+ * This is called when VT switching away from the X server. Its job is
+ * to restore the previous (text) mode.
+ * Mandatory!
+ */
+static void
+SISLeaveVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ SISPtr pSiS = SISPTR(pScrn);
+#ifdef XF86DRI
+ ScreenPtr pScreen;
+
+ /* TW: to be done before mode change */
+ if(pSiS->directRenderingEnabled) {
+ pScreen = screenInfo.screens[scrnIndex];
+ DRILock(pScreen, 0);
+ }
+#endif
+
+#ifdef SISDUALHEAD
+ if(pSiS->DualHeadMode && pSiS->SecondHead) return;
+#endif
+
+ if(pSiS->CursorInfoPtr) {
+#ifdef SISDUALHEAD
+ if(pSiS->DualHeadMode) {
+ if(!pSiS->SecondHead) {
+ pSiS->ForceCursorOff = TRUE;
+ pSiS->CursorInfoPtr->HideCursor(pScrn);
+ SISWaitVBRetrace(pScrn);
+ pSiS->ForceCursorOff = FALSE;
+ }
+ } else {
+#endif
+ pSiS->CursorInfoPtr->HideCursor(pScrn);
+ SISWaitVBRetrace(pScrn);
+#ifdef SISDUALHEAD
+ }
+#endif
+ }
+
+ SISBridgeRestore(pScrn);
+
+ if(pSiS->UseVESA) {
+
+ /* TW: This is a q&d work-around for a BIOS bug. In case we disabled CRT2,
+ * VBESaveRestore() does not restore CRT1. So we set any mode now,
+ * because VBESetVBEMode correctly restores CRT1. Afterwards, we
+ * can call VBESaveRestore to restore original mode.
+ */
+ if ( (pSiS->VBFlags & VB_VIDEOBRIDGE) && (!(pSiS->VBFlags & DISPTYPE_DISP2)) )
+ VBESetVBEMode(pSiS->pVbe, (pSiS->SISVESAModeList->n) | 0xc000, NULL);
+
+ SISVESARestore(pScrn);
+
+ } else {
+
+ SISRestore(pScrn);
+
+ }
+
+ vgaHWLock(hwp);
+}
+
+
+/*
+ * This is called at the end of each server generation. It restores the
+ * original (text) mode. It should really also unmap the video memory too.
+ * Mandatory!
+ */
+static Bool
+SISCloseScreen(int scrnIndex, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ SISPtr pSiS = SISPTR(pScrn);
+#ifdef SISDUALHEAD
+ SISEntPtr pSiSEnt = pSiS->entityPrivate;
+#endif
+
+#ifdef XF86DRI
+ if(pSiS->directRenderingEnabled) {
+ SISDRICloseScreen(pScreen);
+ pSiS->directRenderingEnabled = FALSE;
+ }
+#endif
+
+ if(pScrn->vtSema) {
+
+ if(pSiS->CursorInfoPtr) {
+#ifdef SISDUALHEAD
+ if(pSiS->DualHeadMode) {
+ if(!pSiS->SecondHead) {
+ pSiS->ForceCursorOff = TRUE;
+ pSiS->CursorInfoPtr->HideCursor(pScrn);
+ SISWaitVBRetrace(pScrn);
+ pSiS->ForceCursorOff = FALSE;
+ }
+ } else {
+#endif
+ pSiS->CursorInfoPtr->HideCursor(pScrn);
+ SISWaitVBRetrace(pScrn);
+#ifdef SISDUALHEAD
+ }
+#endif
+ }
+
+ SISBridgeRestore(pScrn);
+
+ if(pSiS->UseVESA) {
+
+ /* TW: This is a q&d work-around for a BIOS bug. In case we disabled CRT2,
+ * VBESaveRestore() does not restore CRT1. So we set any mode now,
+ * because VBESetVBEMode correctly restores CRT1. Afterwards, we
+ * can call VBESaveRestore to restore original mode.
+ */
+ if( (pSiS->VBFlags & VB_VIDEOBRIDGE) && (!(pSiS->VBFlags & DISPTYPE_DISP2)))
+ VBESetVBEMode(pSiS->pVbe, (pSiS->SISVESAModeList->n) | 0xc000, NULL);
+
+ SISVESARestore(pScrn);
+
+ } else {
+
+ SISRestore(pScrn);
+
+ }
+
+ vgaHWLock(hwp);
+ }
+
+ SISUnmapMem(pScrn);
+ vgaHWUnmapMem(pScrn);
+
+#ifdef SISDUALHEAD
+ if(pSiS->DualHeadMode) {
+ pSiSEnt = pSiS->entityPrivate;
+ pSiSEnt->refCount--;
+ }
+#endif
+
+ if(pSiS->pInt) {
+ xf86FreeInt10(pSiS->pInt);
+ pSiS->pInt = NULL;
+ }
+
+ if(pSiS->AccelInfoPtr) {
+ XAADestroyInfoRec(pSiS->AccelInfoPtr);
+ pSiS->AccelInfoPtr = NULL;
+ }
+
+ if(pSiS->CursorInfoPtr) {
+ xf86DestroyCursorInfoRec(pSiS->CursorInfoPtr);
+ pSiS->CursorInfoPtr = NULL;
+ }
+
+ if(pSiS->ShadowPtr) {
+ xfree(pSiS->ShadowPtr);
+ pSiS->ShadowPtr = NULL;
+ }
+
+ if(pSiS->DGAModes) {
+ xfree(pSiS->DGAModes);
+ pSiS->DGAModes = NULL;
+ }
+
+ if(pSiS->adaptor) {
+ xfree(pSiS->adaptor);
+ pSiS->adaptor = NULL;
+ }
+
+ pScrn->vtSema = FALSE;
+
+ /* Restore Blockhandler */
+ pScreen->BlockHandler = pSiS->BlockHandler;
+
+ pScreen->CloseScreen = pSiS->CloseScreen;
+ return (*pScreen->CloseScreen)(scrnIndex, pScreen);
+}
+
+
+/* Free up any per-generation data structures */
+
+/* Optional */
+static void
+SISFreeScreen(int scrnIndex, int flags)
+{
+ if (xf86LoaderCheckSymbol("vgaHWFreeHWRec"))
+ vgaHWFreeHWRec(xf86Screens[scrnIndex]);
+ SISFreeRec(xf86Screens[scrnIndex]);
+}
+
+
+/* Checks if a mode is suitable for the selected chipset. */
+
+/* Optional */
+static int
+SISValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ SISPtr pSiS = SISPTR(pScrn);
+
+ if(pSiS->UseVESA) {
+ if(SiSCalcVESAModeIndex(pScrn, mode))
+ return(MODE_OK);
+ else
+ return(MODE_BAD);
+ }
+ if(pSiS->VGAEngine == SIS_300_VGA || pSiS->VGAEngine == SIS_315_VGA) {
+#ifdef SISDUALHEAD
+ if((pSiS->DualHeadMode) && (pSiS->SecondHead)) {
+ /* DHM: Only check modes for CRT1 */
+ if(SiS_CalcModeIndex(pScrn, mode) < 0x14)
+ return(MODE_BAD);
+ } else
+#endif
+ if(SiS_CheckCalcModeIndex(pScrn, mode, pSiS->VBFlags) < 0x14)
+ return(MODE_BAD);
+
+ }
+
+ return(MODE_OK);
+}
+
+/* Do screen blanking */
+
+/* Mandatory */
+static Bool
+SISSaveScreen(ScreenPtr pScreen, int mode)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+
+ if ((pScrn != NULL) && pScrn->vtSema) {
+
+ SISPtr pSiS = SISPTR(pScrn);
+
+ /* enable access to extended sequencer registers */
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+
+ if(pSiS->VGAEngine == SIS_300_VGA) {
+
+ if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) {
+ if(!xf86IsUnblank(mode)) {
+ pSiS->Blank = TRUE;
+ SiS_SiS30xBLOff(pSiS->SiS_Pr,&pSiS->sishw_ext);
+ } else {
+ pSiS->Blank = FALSE;
+ SiS_SiS30xBLOn(pSiS->SiS_Pr,&pSiS->sishw_ext);
+ }
+ } else {
+ /* if not blanked obtain state of LCD blank flags set by BIOS */
+ if(!pSiS->Blank) {
+ inSISIDXREG(SISSR, 0x11, pSiS->LCDon);
+ }
+
+ if(!xf86IsUnblank(mode)) {
+ pSiS->Blank = TRUE;
+ outSISIDXREG(SISSR, 0x11, pSiS->LCDon | 0x08);
+ } else {
+ pSiS->Blank = FALSE;
+ /* don't just unblanking; use LCD state set by BIOS */
+ outSISIDXREG(SISSR, 0x11, pSiS->LCDon);
+ }
+ }
+
+ } else if(pSiS->VGAEngine == SIS_315_VGA) {
+
+ if(!pSiS->Blank) {
+ inSISIDXREG(SISSR, 0x11, pSiS->LCDon);
+ }
+
+ if(pSiS->VBFlags & VB_CHRONTEL) {
+ if(!xf86IsUnblank(mode)) {
+ pSiS->Blank = TRUE;
+ SiS_Chrontel701xBLOff(pSiS->SiS_Pr);
+ } else {
+ pSiS->Blank = FALSE;
+ SiS_Chrontel701xBLOn(pSiS->SiS_Pr);
+ }
+ } else if(pSiS->VBFlags & VB_LVDS) {
+ if(!xf86IsUnblank(mode)) {
+ pSiS->Blank = TRUE;
+ outSISIDXREG(SISSR, 0x11, pSiS->LCDon | 0x08);
+ } else {
+ pSiS->Blank = FALSE;
+ outSISIDXREG(SISSR, 0x11, pSiS->LCDon);
+ }
+ } else if(pSiS->VBFlags & (VB_301B|VB_302B|VB_30xLV|VB_30xLVX)) {
+ if(!xf86IsUnblank(mode)) {
+ pSiS->Blank = TRUE;
+ SiS_SiS30xBLOff(pSiS->SiS_Pr,&pSiS->sishw_ext);
+ } else {
+ pSiS->Blank = FALSE;
+ SiS_SiS30xBLOn(pSiS->SiS_Pr,&pSiS->sishw_ext);
+ }
+ }
+
+ }
+
+ }
+
+ return vgaHWSaveScreen(pScreen, mode);
+}
+
+#ifdef SISDUALHEAD
+/* TW: SaveScreen for dual head mode */
+static Bool
+SISSaveScreenDH(ScreenPtr pScreen, int mode)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+
+ if ((pScrn != NULL) && pScrn->vtSema) {
+
+ SISPtr pSiS = SISPTR(pScrn);
+ if (pSiS->SecondHead) {
+
+ /* Slave head is always CRT1 */
+ return vgaHWSaveScreen(pScreen, mode);
+
+ } else {
+
+ /* Master head is always CRT2 */
+
+ /* We can only blank LCD, not other CRT2 devices */
+ if(!(pSiS->VBFlags & CRT2_LCD)) return TRUE;
+
+ /* enable access to extended sequencer registers */
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+
+ if(pSiS->VGAEngine == SIS_300_VGA) {
+
+ if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) {
+ if(!xf86IsUnblank(mode)) {
+ pSiS->BlankCRT2 = TRUE;
+ SiS_SiS30xBLOff(pSiS->SiS_Pr,&pSiS->sishw_ext);
+ } else {
+ pSiS->BlankCRT2 = FALSE;
+ SiS_SiS30xBLOn(pSiS->SiS_Pr,&pSiS->sishw_ext);
+ }
+ } else {
+ /* if not blanked obtain state of LCD blank flags set by BIOS */
+ if(!pSiS->BlankCRT2) {
+ inSISIDXREG(SISSR, 0x11, pSiS->LCDon);
+ }
+
+ if (!xf86IsUnblank(mode)) {
+ pSiS->BlankCRT2 = TRUE;
+ outSISIDXREG(SISSR, 0x11, pSiS->LCDon | 0x08);
+ } else {
+ pSiS->BlankCRT2 = FALSE;
+ /* don't just unblank; use LCD state set by BIOS */
+ outSISIDXREG(SISSR, 0x11, pSiS->LCDon);
+ }
+ }
+
+ } else if(pSiS->VGAEngine == SIS_315_VGA) {
+
+ if(!pSiS->BlankCRT2) {
+ inSISIDXREG(SISSR, 0x11, pSiS->LCDon);
+ }
+
+ if(pSiS->VBFlags & VB_CHRONTEL) {
+ if(!xf86IsUnblank(mode)) {
+ pSiS->BlankCRT2 = TRUE;
+ SiS_Chrontel701xBLOff(pSiS->SiS_Pr);
+ } else {
+ pSiS->BlankCRT2 = FALSE;
+ SiS_Chrontel701xBLOn(pSiS->SiS_Pr);
+ }
+ } else if(pSiS->VBFlags & VB_LVDS) {
+ if(!xf86IsUnblank(mode)) {
+ pSiS->BlankCRT2 = TRUE;
+ outSISIDXREG(SISSR, 0x11, pSiS->LCDon | 0x08);
+ } else {
+ pSiS->BlankCRT2 = FALSE;
+ outSISIDXREG(SISSR, 0x11, pSiS->LCDon);
+ }
+ } else if(pSiS->VBFlags & (VB_301B|VB_302B|VB_30xLV|VB_30xLVX)) {
+ if(!xf86IsUnblank(mode)) {
+ pSiS->BlankCRT2 = TRUE;
+ SiS_SiS30xBLOff(pSiS->SiS_Pr,&pSiS->sishw_ext);
+ } else {
+ pSiS->BlankCRT2 = FALSE;
+ SiS_SiS30xBLOn(pSiS->SiS_Pr,&pSiS->sishw_ext);
+ }
+ }
+
+ }
+ }
+ }
+ return TRUE;
+}
+#endif
+
+#ifdef DEBUG
+/* locally used for debug */
+static void
+SiSDumpModeInfo(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Clock : %x\n", mode->Clock);
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Hz Display : %x\n", mode->CrtcHDisplay);
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Hz Blank Start : %x\n", mode->CrtcHBlankStart);
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Hz Sync Start : %x\n", mode->CrtcHSyncStart);
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Hz Sync End : %x\n", mode->CrtcHSyncEnd);
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Hz Blank End : %x\n", mode->CrtcHBlankEnd);
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Hz Total : %x\n", mode->CrtcHTotal);
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Hz Skew : %x\n", mode->CrtcHSkew);
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Hz HAdjusted : %x\n", mode->CrtcHAdjusted);
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Vt Display : %x\n", mode->CrtcVDisplay);
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Vt Blank Start : %x\n", mode->CrtcVBlankStart);
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Vt Sync Start : %x\n", mode->CrtcVSyncStart);
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Vt Sync End : %x\n", mode->CrtcVSyncEnd);
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Vt Blank End : %x\n", mode->CrtcVBlankEnd);
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Vt Total : %x\n", mode->CrtcVTotal);
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Vt VAdjusted : %x\n", mode->CrtcVAdjusted);
+}
+#endif
+
+/* local used for debug */
+static void
+SISModifyModeInfo(DisplayModePtr mode)
+{
+#if 1
+ if(mode->CrtcHBlankStart == mode->CrtcHDisplay)
+ mode->CrtcHBlankStart++;
+ if(mode->CrtcHBlankEnd == mode->CrtcHTotal)
+ mode->CrtcHBlankEnd--;
+ if(mode->CrtcVBlankStart == mode->CrtcVDisplay)
+ mode->CrtcVBlankStart++;
+ if(mode->CrtcVBlankEnd == mode->CrtcVTotal)
+ mode->CrtcVBlankEnd--;
+#endif
+}
+
+/* TW: Enable the TurboQueue (For 300 and 310/325 series only) */
+void
+SiSEnableTurboQueue(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ unsigned short SR26, SR27;
+ unsigned long temp;
+
+ switch (pSiS->VGAEngine) {
+ case SIS_300_VGA:
+ if ((!pSiS->NoAccel) && (pSiS->TurboQueue)) {
+ /* TQ size is always 512k */
+ temp = (pScrn->videoRam/64) - 8;
+ SR26 = temp & 0xFF;
+ inSISIDXREG(SISSR, 0x27, SR27);
+ SR27 &= 0xFC;
+ SR27 |= (0xF0 | ((temp >> 8) & 3));
+ outSISIDXREG(SISSR, 0x26, SR26);
+ outSISIDXREG(SISSR, 0x27, SR27);
+ }
+ break;
+ case SIS_315_VGA:
+ if (!pSiS->NoAccel) {
+ /* TW: On 310/325 series, there are three queue modes available
+ * which are chosen by setting bits 7:5 in SR26:
+ * 1. MMIO queue mode (bit 5, 0x20). The hardware will keep
+ * track of the queue, the FIFO, command parsing and so
+ * on. This is the one comparable to the 300 series.
+ * 2. VRAM queue mode (bit 6, 0x40). In this case, one will
+ * have to do queue management himself. Register 0x85c4 will
+ * hold the location of the next free queue slot, 0x85c8
+ * is the "queue read pointer" whose way of working is
+ * unknown to me. Anyway, this mode would require a
+ * translation of the MMIO commands to some kind of
+ * accelerator assembly and writing these commands
+ * to the memory location pointed to by 0x85c4.
+ * We will not use this, as nobody knows how this
+ * "assembly" works, and as it would require a complete
+ * re-write of the accelerator code.
+ * 3. AGP queue mode (bit 7, 0x80). Works as 2., but keeps the
+ * queue in AGP memory space.
+ * We go MMIO here.
+ * SR26 bit 4 is called "Bypass H/W queue".
+ * SR26 bit 1 is called "Enable Command Queue Auto Correction"
+ * SR26 bit 0 resets the queue
+ * Size of queue memory is encoded in bits 3:2 like this:
+ * 00 (0x00) 512K
+ * 01 (0x04) 1M
+ * 10 (0x08) 2M
+ * 11 (0x0C) 4M
+ * The queue location is to be written to 0x85C0.
+ */
+#if 0
+ if (pSiS->TurboQueue) {
+#endif
+ /* TW: We only use MMIO Cmd Queue, not VRAM or AGP */
+ /* TW: Set Command Queue Threshold to max value 11111b */
+ outSISIDXREG(SISSR, 0x27, 0x1F);
+ /* TW: Syncronous reset for Command Queue */
+ outSISIDXREG(SISSR, 0x26, 0x01);
+ /* TW: Do some magic (cp readport to writeport) */
+ temp = MMIO_IN32(pSiS->IOBase, 0x85C8);
+ MMIO_OUT32(pSiS->IOBase, 0x85C4, temp);
+ /* TW: Enable MMIO Command Queue mode (0x20),
+ * Enable_command_queue_auto_correction (0x02)
+ * (no idea, but sounds good, so use it)
+ * 512k (0x00) (does this apply to MMIO mode?) */
+ outSISIDXREG(SISSR, 0x26, 0x22);
+ /* TW: Calc Command Queue position (Q is always 512k)*/
+ temp = (pScrn->videoRam - 512) * 1024;
+ /* TW: Set Q position */
+ MMIO_OUT32(pSiS->IOBase, 0x85C0, temp);
+#if 0
+ } else {
+ /* TW: Is there a non-TurboQueue mode within MMIO mode? */
+ }
+#endif
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/* TW: Things to do before a ModeSwitch. We set up the
+ * video bridge configuration and the TurboQueue.
+ */
+void SiSPreSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ unsigned char usScratchCR30, usScratchCR31;
+ unsigned char usScratchCR32, usScratchCR33;
+ unsigned char usScratchCR17, usScratchCR38 = 0;
+ int vbflag, temp = 0;
+ int crt1rateindex = 0;
+
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); /* Unlock Registers */
+#endif
+
+ vbflag = pSiS->VBFlags;
+ pSiS->IsCustom = FALSE;
+
+ if(pSiS->HaveCustomModes) {
+ if(!(mode->type & M_T_DEFAULT)) {
+ pSiS->IsCustom = TRUE;
+ }
+ }
+
+ /* TW: The CR3x registers are for communicating with our BIOS emulation
+ * code (native code in init.c/init301.c) or the BIOS (via VESA)
+ */
+ inSISIDXREG(SISCR, 0x30, usScratchCR30); /* Bridge config */
+ inSISIDXREG(SISCR, 0x31, usScratchCR31); /* Bridge config */
+ usScratchCR32 = pSiS->newCR32; /* Bridge connection info (use our new value) */
+ inSISIDXREG(SISCR, 0x33, usScratchCR33); /* CRT1 refresh rate index */
+ if(pSiS->Chipset != PCI_CHIP_SIS300) {
+ switch(pSiS->VGAEngine) {
+ case SIS_300_VGA: temp = 0x35; break;
+ case SIS_315_VGA: temp = 0x38; break;
+ }
+ }
+ if(temp) inSISIDXREG(SISCR, temp, usScratchCR38); /* PAL-M, PAL-N selection */
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "VBFlags=0x%x\n", pSiS->VBFlags);
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 3,
+ "Before: CR30=0x%02x, CR31=0x%02x, CR32=0x%02x, CR33=0x%02x, CR%02x=0x%02x\n",
+ usScratchCR30, usScratchCR31, usScratchCR32, usScratchCR33, temp, usScratchCR38);
+
+ usScratchCR30 = 0;
+ usScratchCR31 &= ~0x60; /* TW: Clear VB_Drivermode & VB_OutputDisable */
+#if 0 /* TW: For future use */
+ if( (pSiS->VBFlags & VB_LVDS) ||
+ (pSiS->VBFlags & VB_301) ||
+ ( (pSiS->VBFlags & (VB_301B | VB_302B |VB_30xLV | VB_30xLVX)) &&
+ (!(pSiS->VBLCDFlags & VB_LCD_1400x1050)) ) ) {
+#endif
+ usScratchCR31 |= 0x04; /* TW: Set VB_NotSimuMode (not for 30xB/1400x1050?) */
+#if 0
+ }
+#endif
+
+ switch(vbflag & (CRT2_TV|CRT2_LCD|CRT2_VGA)) {
+ case CRT2_TV:
+ if(vbflag & TV_CHSCART) {
+ usScratchCR38 |= 0x04;
+ usScratchCR31 |= 0x01;
+ } else if(vbflag & TV_CHHDTV) {
+ usScratchCR38 |= 0x08;
+ usScratchCR31 &= ~0x01;
+ } else if(vbflag & TV_HIVISION)
+ usScratchCR30 |= 0x80;
+ else if(vbflag & TV_SVIDEO)
+ usScratchCR30 |= 0x08;
+ else if(vbflag & TV_AVIDEO)
+ usScratchCR30 |= 0x04;
+ else if(vbflag & TV_SCART)
+ usScratchCR30 |= 0x10;
+ else
+ usScratchCR30 |= 0x08; /* default: SVIDEO */
+
+ if(!(vbflag & (TV_CHSCART | TV_CHHDTV))) {
+ if(vbflag & TV_PAL) {
+ usScratchCR31 |= 0x01;
+ usScratchCR38 &= ~0xC0;
+ if( (vbflag & VB_SISBRIDGE) ||
+ ((vbflag & VB_CHRONTEL) && (pSiS->ChrontelType == CHRONTEL_701x)) ) {
+ if(vbflag & TV_PALM) usScratchCR38 |= 0x40;
+ else if(vbflag & TV_PALN) usScratchCR38 |= 0x80;
+ }
+ } else
+ usScratchCR31 &= ~0x01;
+ }
+
+ usScratchCR30 |= 0x01; /* Set SimuScanMode */
+
+ usScratchCR31 &= ~0x04; /* Clear NotSimuMode */
+ pSiS->SiS_Pr->SiS_CHOverScan = pSiS->UseCHOverScan;
+ if(pSiS->OptTVSOver == 1) {
+ pSiS->SiS_Pr->SiS_CHSOverScan = TRUE;
+ } else {
+ pSiS->SiS_Pr->SiS_CHSOverScan = FALSE;
+ }
+ break;
+ case CRT2_LCD:
+ usScratchCR30 |= 0x21; /* LCD + SimuScanMode */
+ break;
+ case CRT2_VGA:
+ usScratchCR30 |= 0x41; /* VGA2 + SimuScanMode */
+ break;
+ default:
+ usScratchCR30 |= 0x00;
+ usScratchCR31 |= 0x20; /* VB_OUTPUT_DISABLE */
+ if(pSiS->UseVESA) {
+ crt1rateindex = SISSearchCRT1Rate(pScrn, mode);
+ }
+ }
+ /* TW: for VESA: no DRIVERMODE, otherwise
+ * -) CRT2 will not be initialized correctly when using mode
+ * where LCD has to scale, and
+ * -) CRT1 will have too low rate
+ */
+ if (pSiS->UseVESA) {
+ usScratchCR31 &= 0x40; /* TW: Clear Drivermode */
+#ifdef TWDEBUG
+ usScratchCR31 |= 0x40; /* DEBUG (for non-slave mode VESA) */
+ crt1rateindex = SISSearchCRT1Rate(pScrn, mode);
+#endif
+ } else {
+ usScratchCR31 |= 0x40; /* TW: Set Drivermode */
+ if(!pSiS->IsCustom) {
+ crt1rateindex = SISSearchCRT1Rate(pScrn, mode);
+ } else {
+ crt1rateindex = usScratchCR33;
+ }
+ }
+ outSISIDXREG(SISCR, 0x30, usScratchCR30);
+ outSISIDXREG(SISCR, 0x31, usScratchCR31);
+ if(temp) {
+ usScratchCR38 &= ~0x03; /* Clear LCDA/DualEdge bits */
+ outSISIDXREG(SISCR, temp, usScratchCR38);
+ }
+
+ pSiS->SiS_Pr->SiS_UseOEM = pSiS->OptUseOEM;
+
+#ifdef SISDUALHEAD
+ if(pSiS->DualHeadMode) {
+ if(pSiS->SecondHead) {
+ /* CRT1 */
+ usScratchCR33 &= 0xf0;
+ usScratchCR33 |= (crt1rateindex & 0x0f);
+ } else {
+ /* CRT2 */
+ usScratchCR33 &= 0x0f;
+ if(vbflag & CRT2_VGA) usScratchCR33 |= ((crt1rateindex << 4) & 0xf0);
+ }
+ } else {
+#endif
+ if(vbflag & CRT2_VGA) {
+ usScratchCR33 = (crt1rateindex & 0x0f) | ((crt1rateindex & 0x0f) << 4);
+ } else {
+ usScratchCR33 = crt1rateindex & 0x0f;
+ }
+ if((!(pSiS->UseVESA)) && (vbflag & CRT2_ENABLE)) {
+#ifndef TWDEBUG
+ if(pSiS->CRT1off) usScratchCR33 &= 0xf0;
+#endif
+ }
+#ifdef SISDUALHEAD
+ }
+#endif
+ outSISIDXREG(SISCR, 0x33, usScratchCR33);
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+ "After: CR30=0x%02x, CR31=0x%02x, CR33=0x%02x\n",
+ usScratchCR30, usScratchCR31, usScratchCR33);
+
+ /* Enable TurboQueue */
+ SiSEnableTurboQueue(pScrn);
+
+ if((!pSiS->UseVESA) && (pSiS->VBFlags & CRT2_ENABLE)) {
+ /* Switch on CRT1 for modes that require the bridge in SlaveMode */
+ inSISIDXREG(SISCR, 0x17, usScratchCR17);
+ if(!(usScratchCR17 & 0x80)) {
+ orSISIDXREG(SISCR, 0x17, 0x80);
+ outSISIDXREG(SISSR, 0x00, 0x01);
+ usleep(10000);
+ outSISIDXREG(SISSR, 0x00, 0x03);
+ }
+ }
+
+}
+
+/* Functions for adjusting various TV settings */
+
+/* These are used by the PostSetMode() functions as well as
+ * the (hopefully) upcoming display properties extension/tool.
+ *
+ * There is each a Set and a Get routine. The Set functions
+ * take a value of the same range as the corresponding option.
+ * The Get routines return a value of the same range (although
+ * not necessarily the same value as previously set because
+ * of the lower resolution of the respective setting compared
+ * to the valid range).
+ * The Get routines return -2 on error (eg. hardware does not
+ * support this setting).
+ * Note: The x and y positioning routines accept a position
+ * RELATIVE to the default position. All other routines
+ * take ABSOLUTE values.
+ *
+ * The Set functions will store the property regardless if TV is
+ * currently used or not and if the hardware supports the property
+ * or not. The Get routines will return this stored
+ * value if TV is not currently used (because the register does
+ * not contain the correct value then) or if the hardware supports
+ * the respective property. This should make it easier for the
+ * display property tool because it does not have to know the
+ * hardware features.
+ *
+ * All the routines are dual head aware. It does not matter
+ * if the function is called from the CRT1 or CRT2 session.
+ * The values will be stored in pSiSEnt if we're running dual.
+ */
+
+void SiS_SetCHTVlumabandwidthcvbs(ScrnInfoPtr pScrn, int val)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+#ifdef SISDUALHEAD
+ SISEntPtr pSiSEnt = pSiS->entityPrivate;
+#endif
+
+ pSiS->chtvlumabandwidthcvbs = val;
+#ifdef SISDUALHEAD
+ if(pSiSEnt) pSiSEnt->chtvlumabandwidthcvbs = val;
+#endif
+
+ if(!(pSiS->VBFlags & CRT2_TV)) return;
+ if(!(pSiS->VBFlags & VB_CHRONTEL)) return;
+
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+
+ switch(pSiS->ChrontelType) {
+ case CHRONTEL_700x:
+ val /= 8;
+ if((val == 0) || (val == 1)) {
+ SiS_SetCH70xxANDOR(pSiS->SiS_Pr, ((val << 8) | 0x03),0xFE);
+ }
+ break;
+ case CHRONTEL_701x:
+ val /= 4;
+ if((val >= 0) && (val <= 3)) {
+ SiS_SetCH70xxANDOR(pSiS->SiS_Pr, ((val << 8) | 0x02),0xFC);
+ }
+ break;
+ }
+}
+
+int SiS_GetCHTVlumabandwidthcvbs(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+#ifdef SISDUALHEAD
+ SISEntPtr pSiSEnt = pSiS->entityPrivate;
+#endif
+
+ if(!(pSiS->VBFlags & VB_CHRONTEL && pSiS->VBFlags & CRT2_TV)) {
+#ifdef SISDUALHEAD
+ if(pSiSEnt && pSiS->DualHeadMode)
+ return (int)pSiSEnt->chtvlumabandwidthcvbs;
+ else
+#endif
+ return (int)pSiS->chtvlumabandwidthcvbs;
+ } else {
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+ switch(pSiS->ChrontelType) {
+ case CHRONTEL_700x:
+ return(int)((SiS_GetCH70xx(pSiS->SiS_Pr, 0x03) & 0x01) * 8);
+ case CHRONTEL_701x:
+ return(int)((SiS_GetCH70xx(pSiS->SiS_Pr, 0x02) & 0x03) * 4);
+ default:
+ return -2;
+ }
+ }
+}
+
+void SiS_SetCHTVlumabandwidthsvideo(ScrnInfoPtr pScrn, int val)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+#ifdef SISDUALHEAD
+ SISEntPtr pSiSEnt = pSiS->entityPrivate;
+#endif
+
+ pSiS->chtvlumabandwidthsvideo = val;
+#ifdef SISDUALHEAD
+ if(pSiSEnt) pSiSEnt->chtvlumabandwidthsvideo = val;
+#endif
+
+ if(!(pSiS->VBFlags & CRT2_TV)) return;
+ if(!(pSiS->VBFlags & VB_CHRONTEL)) return;
+
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+
+ switch(pSiS->ChrontelType) {
+ case CHRONTEL_700x:
+ val /= 6;
+ if((val >= 0) && (val <= 2)) {
+ SiS_SetCH70xxANDOR(pSiS->SiS_Pr, ((val << 9) | 0x03),0xF9);
+ }
+ break;
+ case CHRONTEL_701x:
+ val /= 4;
+ if((val >= 0) && (val <= 3)) {
+ SiS_SetCH70xxANDOR(pSiS->SiS_Pr, ((val << 10) | 0x02),0xF3);
+ }
+ break;
+ }
+}
+
+int SiS_GetCHTVlumabandwidthsvideo(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+#ifdef SISDUALHEAD
+ SISEntPtr pSiSEnt = pSiS->entityPrivate;
+#endif
+
+ if(!(pSiS->VBFlags & VB_CHRONTEL && pSiS->VBFlags & CRT2_TV)) {
+#ifdef SISDUALHEAD
+ if(pSiSEnt && pSiS->DualHeadMode)
+ return (int)pSiSEnt->chtvlumabandwidthsvideo;
+ else
+#endif
+ return (int)pSiS->chtvlumabandwidthsvideo;
+ } else {
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+ switch(pSiS->ChrontelType) {
+ case CHRONTEL_700x:
+ return(int)(((SiS_GetCH70xx(pSiS->SiS_Pr, 0x03) & 0x06) >> 1) * 6);
+ case CHRONTEL_701x:
+ return(int)(((SiS_GetCH70xx(pSiS->SiS_Pr, 0x02) & 0x0c) >> 2) * 4);
+ default:
+ return -2;
+ }
+ }
+}
+
+void SiS_SetCHTVlumaflickerfilter(ScrnInfoPtr pScrn, int val)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+#ifdef SISDUALHEAD
+ SISEntPtr pSiSEnt = pSiS->entityPrivate;
+#endif
+
+ pSiS->chtvlumaflickerfilter = val;
+#ifdef SISDUALHEAD
+ if(pSiSEnt) pSiSEnt->chtvlumaflickerfilter = val;
+#endif
+
+ if(!(pSiS->VBFlags & CRT2_TV)) return;
+ if(!(pSiS->VBFlags & VB_CHRONTEL)) return;
+
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+
+ switch(pSiS->ChrontelType) {
+ case CHRONTEL_700x:
+ val /= 6;
+ if((val >= 0) && (val <= 2)) {
+ SiS_SetCH70xxANDOR(pSiS->SiS_Pr, ((val << 10) | 0x01),0xF3);
+ }
+ break;
+ case CHRONTEL_701x:
+ val /= 4;
+ if((val >= 0) && (val <= 3)) {
+ SiS_SetCH70xxANDOR(pSiS->SiS_Pr, ((val << 10) | 0x01),0xF3);
+ }
+ break;
+ }
+}
+
+int SiS_GetCHTVlumaflickerfilter(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+#ifdef SISDUALHEAD
+ SISEntPtr pSiSEnt = pSiS->entityPrivate;
+#endif
+
+ if(!(pSiS->VBFlags & VB_CHRONTEL && pSiS->VBFlags & CRT2_TV)) {
+#ifdef SISDUALHEAD
+ if(pSiSEnt && pSiS->DualHeadMode)
+ return (int)pSiSEnt->chtvlumaflickerfilter;
+ else
+#endif
+ return (int)pSiS->chtvlumaflickerfilter;
+ } else {
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+ switch(pSiS->ChrontelType) {
+ case CHRONTEL_700x:
+ return(int)(((SiS_GetCH70xx(pSiS->SiS_Pr, 0x01) & 0x0c) >> 2) * 6);
+ case CHRONTEL_701x:
+ return(int)(((SiS_GetCH70xx(pSiS->SiS_Pr, 0x01) & 0x0c) >> 2) * 4);
+ default:
+ return -2;
+ }
+ }
+}
+
+void SiS_SetCHTVchromabandwidth(ScrnInfoPtr pScrn, int val)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+#ifdef SISDUALHEAD
+ SISEntPtr pSiSEnt = pSiS->entityPrivate;
+#endif
+
+ pSiS->chtvchromabandwidth = val;
+#ifdef SISDUALHEAD
+ if(pSiSEnt) pSiSEnt->chtvchromabandwidth = val;
+#endif
+
+ if(!(pSiS->VBFlags & CRT2_TV)) return;
+ if(!(pSiS->VBFlags & VB_CHRONTEL)) return;
+
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+
+ switch(pSiS->ChrontelType) {
+ case CHRONTEL_700x:
+ val /= 4;
+ if((val >= 0) && (val <= 3)) {
+ SiS_SetCH70xxANDOR(pSiS->SiS_Pr, ((val << 12) | 0x03),0xCF);
+ }
+ break;
+ case CHRONTEL_701x:
+ val /= 8;
+ if((val >= 0) && (val <= 1)) {
+ SiS_SetCH70xxANDOR(pSiS->SiS_Pr, ((val << 12) | 0x02),0xEF);
+ }
+ break;
+ }
+}
+
+int SiS_GetCHTVchromabandwidth(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+#ifdef SISDUALHEAD
+ SISEntPtr pSiSEnt = pSiS->entityPrivate;
+#endif
+
+ if(!(pSiS->VBFlags & VB_CHRONTEL && pSiS->VBFlags & CRT2_TV)) {
+#ifdef SISDUALHEAD
+ if(pSiSEnt && pSiS->DualHeadMode)
+ return (int)pSiSEnt->chtvchromabandwidth;
+ else
+#endif
+ return (int)pSiS->chtvchromabandwidth;
+ } else {
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+ switch(pSiS->ChrontelType) {
+ case CHRONTEL_700x:
+ return(int)(((SiS_GetCH70xx(pSiS->SiS_Pr, 0x03) & 0x30) >> 4) * 4);
+ case CHRONTEL_701x:
+ return(int)(((SiS_GetCH70xx(pSiS->SiS_Pr, 0x02) & 0x10) >> 4) * 8);
+ default:
+ return -2;
+ }
+ }
+}
+
+void SiS_SetCHTVchromaflickerfilter(ScrnInfoPtr pScrn, int val)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+#ifdef SISDUALHEAD
+ SISEntPtr pSiSEnt = pSiS->entityPrivate;
+#endif
+
+ pSiS->chtvchromaflickerfilter = val;
+#ifdef SISDUALHEAD
+ if(pSiSEnt) pSiSEnt->chtvchromaflickerfilter = val;
+#endif
+
+ if(!(pSiS->VBFlags & CRT2_TV)) return;
+ if(!(pSiS->VBFlags & VB_CHRONTEL)) return;
+
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+
+ switch(pSiS->ChrontelType) {
+ case CHRONTEL_700x:
+ val /= 6;
+ if((val >= 0) && (val <= 2)) {
+ SiS_SetCH70xxANDOR(pSiS->SiS_Pr, ((val << 12) | 0x01),0xCF);
+ }
+ break;
+ case CHRONTEL_701x:
+ val /= 4;
+ if((val >= 0) && (val <= 3)) {
+ SiS_SetCH70xxANDOR(pSiS->SiS_Pr, ((val << 12) | 0x01),0xCF);
+ }
+ break;
+ }
+}
+
+int SiS_GetCHTVchromaflickerfilter(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+#ifdef SISDUALHEAD
+ SISEntPtr pSiSEnt = pSiS->entityPrivate;
+#endif
+
+ if(!(pSiS->VBFlags & VB_CHRONTEL && pSiS->VBFlags & CRT2_TV)) {
+#ifdef SISDUALHEAD
+ if(pSiSEnt && pSiS->DualHeadMode)
+ return (int)pSiSEnt->chtvchromaflickerfilter;
+ else
+#endif
+ return (int)pSiS->chtvchromaflickerfilter;
+ } else {
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+ switch(pSiS->ChrontelType) {
+ case CHRONTEL_700x:
+ return(int)(((SiS_GetCH70xx(pSiS->SiS_Pr, 0x01) & 0x30) >> 4) * 6);
+ case CHRONTEL_701x:
+ return(int)(((SiS_GetCH70xx(pSiS->SiS_Pr, 0x01) & 0x30) >> 4) * 4);
+ default:
+ return -2;
+ }
+ }
+}
+
+void SiS_SetCHTVcvbscolor(ScrnInfoPtr pScrn, int val)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+#ifdef SISDUALHEAD
+ SISEntPtr pSiSEnt = pSiS->entityPrivate;
+#endif
+
+ pSiS->chtvcvbscolor = val ? 1 : 0;
+#ifdef SISDUALHEAD
+ if(pSiSEnt) pSiSEnt->chtvcvbscolor = pSiS->chtvcvbscolor;
+#endif
+
+ if(!(pSiS->VBFlags & CRT2_TV)) return;
+ if(!(pSiS->VBFlags & VB_CHRONTEL)) return;
+
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+
+ switch(pSiS->ChrontelType) {
+ case CHRONTEL_700x:
+ if(!val) SiS_SetCH70xxANDOR(pSiS->SiS_Pr, 0x4003,0x00);
+ else SiS_SetCH70xxANDOR(pSiS->SiS_Pr, 0x0003,~0x40);
+ break;
+ case CHRONTEL_701x:
+ if(!val) SiS_SetCH70xxANDOR(pSiS->SiS_Pr, 0x0002,~0x20);
+ else SiS_SetCH70xxANDOR(pSiS->SiS_Pr, 0x2002,0x00);
+ break;
+ }
+}
+
+int SiS_GetCHTVcvbscolor(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+#ifdef SISDUALHEAD
+ SISEntPtr pSiSEnt = pSiS->entityPrivate;
+#endif
+
+ if(!(pSiS->VBFlags & VB_CHRONTEL && pSiS->VBFlags & CRT2_TV)) {
+#ifdef SISDUALHEAD
+ if(pSiSEnt && pSiS->DualHeadMode)
+ return (int)pSiSEnt->chtvcvbscolor;
+ else
+#endif
+ return (int)pSiS->chtvcvbscolor;
+ } else {
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+ switch(pSiS->ChrontelType) {
+ case CHRONTEL_700x:
+ return(int)(((SiS_GetCH70xx(pSiS->SiS_Pr, 0x03) & 0x40) >> 6) ^ 0x01);
+ case CHRONTEL_701x:
+ return(int)(((SiS_GetCH70xx(pSiS->SiS_Pr, 0x02) & 0x20) >> 5) ^ 0x01);
+ default:
+ return -2;
+ }
+ }
+}
+
+void SiS_SetCHTVtextenhance(ScrnInfoPtr pScrn, int val)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+#ifdef SISDUALHEAD
+ SISEntPtr pSiSEnt = pSiS->entityPrivate;
+#endif
+
+ pSiS->chtvtextenhance = val;
+#ifdef SISDUALHEAD
+ if(pSiSEnt) pSiSEnt->chtvtextenhance = val;
+#endif
+
+ if(!(pSiS->VBFlags & CRT2_TV)) return;
+ if(!(pSiS->VBFlags & VB_CHRONTEL)) return;
+
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+
+ switch(pSiS->ChrontelType) {
+ case CHRONTEL_700x:
+ val /= 6;
+ if((val >= 0) && (val <= 2)) {
+ SiS_SetCH70xxANDOR(pSiS->SiS_Pr, ((val << 8) | 0x01),0xFC);
+ }
+ break;
+ case CHRONTEL_701x:
+ val /= 2;
+ if((val >= 0) && (val <= 7)) {
+ SiS_SetCH70xxANDOR(pSiS->SiS_Pr, ((val << 8) | 0x03),0xF8);
+ }
+ break;
+ }
+}
+
+int SiS_GetCHTVtextenhance(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+#ifdef SISDUALHEAD
+ SISEntPtr pSiSEnt = pSiS->entityPrivate;
+#endif
+
+ if(!(pSiS->VBFlags & VB_CHRONTEL && pSiS->VBFlags & CRT2_TV)) {
+#ifdef SISDUALHEAD
+ if(pSiSEnt && pSiS->DualHeadMode)
+ return (int)pSiSEnt->chtvtextenhance;
+ else
+#endif
+ return (int)pSiS->chtvtextenhance;
+ } else {
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+ switch(pSiS->ChrontelType) {
+ case CHRONTEL_700x:
+ return(int)((SiS_GetCH70xx(pSiS->SiS_Pr, 0x01) & 0x03) * 6);
+ case CHRONTEL_701x:
+ return(int)((SiS_GetCH70xx(pSiS->SiS_Pr, 0x03) & 0x07) * 2);
+ default:
+ return -2;
+ }
+ }
+}
+
+void SiS_SetCHTVcontrast(ScrnInfoPtr pScrn, int val)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+#ifdef SISDUALHEAD
+ SISEntPtr pSiSEnt = pSiS->entityPrivate;
+#endif
+
+ pSiS->chtvcontrast = val;
+#ifdef SISDUALHEAD
+ if(pSiSEnt) pSiSEnt->chtvcontrast = val;
+#endif
+
+ if(!(pSiS->VBFlags & CRT2_TV)) return;
+ if(!(pSiS->VBFlags & VB_CHRONTEL)) return;
+
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+
+ val /= 2;
+ if((val >= 0) && (val <= 7)) {
+ switch(pSiS->ChrontelType) {
+ case CHRONTEL_700x:
+ SiS_SetCH70xxANDOR(pSiS->SiS_Pr, ((val << 8) | 0x11),0xF8);
+ break;
+ case CHRONTEL_701x:
+ SiS_SetCH70xxANDOR(pSiS->SiS_Pr, ((val << 8) | 0x08),0xF8);
+ break;
+ }
+ }
+}
+
+int SiS_GetCHTVcontrast(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+#ifdef SISDUALHEAD
+ SISEntPtr pSiSEnt = pSiS->entityPrivate;
+#endif
+
+ if(!(pSiS->VBFlags & VB_CHRONTEL && pSiS->VBFlags & CRT2_TV)) {
+#ifdef SISDUALHEAD
+ if(pSiSEnt && pSiS->DualHeadMode)
+ return (int)pSiSEnt->chtvcontrast;
+ else
+#endif
+ return (int)pSiS->chtvcontrast;
+ } else {
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+ switch(pSiS->ChrontelType) {
+ case CHRONTEL_700x:
+ return(int)((SiS_GetCH70xx(pSiS->SiS_Pr, 0x11) & 0x07) * 2);
+ case CHRONTEL_701x:
+ return(int)((SiS_GetCH70xx(pSiS->SiS_Pr, 0x08) & 0x07) * 2);
+ default:
+ return -2;
+ }
+ }
+}
+
+void SiS_SetSISTVedgeenhance(ScrnInfoPtr pScrn, int val)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+#ifdef SISDUALHEAD
+ SISEntPtr pSiSEnt = pSiS->entityPrivate;
+#endif
+
+ pSiS->sistvedgeenhance = val;
+#ifdef SISDUALHEAD
+ if(pSiSEnt) pSiSEnt->sistvedgeenhance = val;
+#endif
+
+ if(!(pSiS->VBFlags & CRT2_TV)) return;
+ if(!(pSiS->VBFlags & VB_301)) return;
+
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+
+ val /= 2;
+ if((val >= 0) && (val <= 7)) {
+ setSISIDXREG(SISPART2,0x3A, 0x1F, (val << 5));
+ }
+}
+
+int SiS_GetSISTVedgeenhance(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+#ifdef SISDUALHEAD
+ SISEntPtr pSiSEnt = pSiS->entityPrivate;
+#endif
+
+ if(!(pSiS->VBFlags & VB_301 && pSiS->VBFlags & CRT2_TV)) {
+#ifdef SISDUALHEAD
+ if(pSiSEnt && pSiS->DualHeadMode)
+ return (int)pSiSEnt->sistvedgeenhance;
+ else
+#endif
+ return (int)pSiS->sistvedgeenhance;
+ } else {
+ unsigned char temp;
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+ inSISIDXREG(SISPART2, 0x3a, temp);
+ return(int)(((temp & 0xe0) >> 5) * 2);
+ }
+}
+
+void SiS_SetSISTVantiflicker(ScrnInfoPtr pScrn, int val)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+#ifdef SISDUALHEAD
+ SISEntPtr pSiSEnt = pSiS->entityPrivate;
+#endif
+
+ pSiS->sistvantiflicker = val;
+#ifdef SISDUALHEAD
+ if(pSiSEnt) pSiSEnt->sistvantiflicker = val;
+#endif
+
+ if(!(pSiS->VBFlags & CRT2_TV)) return;
+ if(!(pSiS->VBFlags & VB_SISBRIDGE)) return;
+
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+
+ val /= 2;
+ if((val >= 0) && (val <= 7)) {
+ setSISIDXREG(SISPART2,0x0A,0x8F, (val << 4));
+ }
+}
+
+int SiS_GetSISTVantiflicker(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+#ifdef SISDUALHEAD
+ SISEntPtr pSiSEnt = pSiS->entityPrivate;
+#endif
+
+ if(!(pSiS->VBFlags & VB_SISBRIDGE && pSiS->VBFlags & CRT2_TV)) {
+#ifdef SISDUALHEAD
+ if(pSiSEnt && pSiS->DualHeadMode)
+ return (int)pSiSEnt->sistvantiflicker;
+ else
+#endif
+ return (int)pSiS->sistvantiflicker;
+ } else {
+ unsigned char temp;
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+ inSISIDXREG(SISPART2, 0x0a, temp);
+ return(int)(((temp & 0x70) >> 4) * 2);
+ }
+}
+
+void SiS_SetSISTVsaturation(ScrnInfoPtr pScrn, int val)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+#ifdef SISDUALHEAD
+ SISEntPtr pSiSEnt = pSiS->entityPrivate;
+#endif
+
+ pSiS->sistvsaturation = val;
+#ifdef SISDUALHEAD
+ if(pSiSEnt) pSiSEnt->sistvsaturation = val;
+#endif
+
+ if(!(pSiS->VBFlags & CRT2_TV)) return;
+ if(!(pSiS->VBFlags & VB_SISBRIDGE)) return;
+
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+
+ val /= 2;
+ if((val >= 0) && (val <= 7)) {
+ setSISIDXREG(SISPART4,0x21,0xF8, val);
+ }
+}
+
+int SiS_GetSISTVsaturation(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+#ifdef SISDUALHEAD
+ SISEntPtr pSiSEnt = pSiS->entityPrivate;
+#endif
+
+ if(!(pSiS->VBFlags & VB_SISBRIDGE && pSiS->VBFlags & CRT2_TV)) {
+#ifdef SISDUALHEAD
+ if(pSiSEnt && pSiS->DualHeadMode)
+ return (int)pSiSEnt->sistvsaturation;
+ else
+#endif
+ return (int)pSiS->sistvsaturation;
+ } else {
+ unsigned char temp;
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+ inSISIDXREG(SISPART4, 0x21, temp);
+ return(int)((temp & 0x07) * 2);
+ }
+}
+
+void SiS_SetSIS6326TVantiflicker(ScrnInfoPtr pScrn, int val)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ unsigned char tmp;
+
+ pSiS->sis6326antiflicker = val;
+
+ if(!(pSiS->SiS6326Flags & SIS6326_TVDETECTED)) return;
+
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+
+ tmp = SiS6326GetTVReg(pScrn,0x00);
+ if(!(tmp & 0x04)) return;
+
+ /* Valid values: 0=off, 1=low, 2=med, 3=high, 4=adaptive */
+ if(val >= 0 && val <= 4) {
+ tmp &= 0x1f;
+ tmp |= (val << 5);
+ SiS6326SetTVReg(pScrn,0x00,tmp);
+ }
+}
+
+int SiS_GetSIS6326TVantiflicker(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ unsigned char tmp;
+
+ if(!(pSiS->SiS6326Flags & SIS6326_TVDETECTED)) {
+ return (int)pSiS->sis6326antiflicker;
+ }
+
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+
+ tmp = SiS6326GetTVReg(pScrn,0x00);
+ if(!(tmp & 0x04)) {
+ return (int)pSiS->sis6326antiflicker;
+ } else {
+ return (int)((tmp >> 5) & 0x07);
+ }
+}
+
+void SiS_SetSIS6326TVenableyfilter(ScrnInfoPtr pScrn, int val)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ unsigned char tmp;
+
+ if(val) val = 1;
+ pSiS->sis6326enableyfilter = val;
+
+ if(!(pSiS->SiS6326Flags & SIS6326_TVDETECTED)) return;
+
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+
+ tmp = SiS6326GetTVReg(pScrn,0x00);
+ if(!(tmp & 0x04)) return;
+
+ tmp = SiS6326GetTVReg(pScrn,0x43);
+ tmp &= ~0x10;
+ tmp |= ((val & 0x01) << 4);
+ SiS6326SetTVReg(pScrn,0x43,tmp);
+}
+
+int SiS_GetSIS6326TVenableyfilter(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ unsigned char tmp;
+
+ if(!(pSiS->SiS6326Flags & SIS6326_TVDETECTED)) {
+ return (int)pSiS->sis6326enableyfilter;
+ }
+
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+
+ tmp = SiS6326GetTVReg(pScrn,0x00);
+ if(!(tmp & 0x04)) {
+ return (int)pSiS->sis6326enableyfilter;
+ } else {
+ tmp = SiS6326GetTVReg(pScrn,0x43);
+ return (int)((tmp >> 4) & 0x01);
+ }
+}
+
+void SiS_SetSIS6326TVyfilterstrong(ScrnInfoPtr pScrn, int val)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ unsigned char tmp;
+
+ if(val) val = 1;
+ pSiS->sis6326yfilterstrong = val;
+
+ if(!(pSiS->SiS6326Flags & SIS6326_TVDETECTED)) return;
+
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+
+ tmp = SiS6326GetTVReg(pScrn,0x00);
+ if(!(tmp & 0x04)) return;
+
+ tmp = SiS6326GetTVReg(pScrn,0x43);
+ if(tmp & 0x10) {
+ tmp &= ~0x40;
+ tmp |= ((val & 0x01) << 6);
+ SiS6326SetTVReg(pScrn,0x43,tmp);
+ }
+}
+
+int SiS_GetSIS6326TVyfilterstrong(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ unsigned char tmp;
+
+ if(!(pSiS->SiS6326Flags & SIS6326_TVDETECTED)) {
+ return (int)pSiS->sis6326yfilterstrong;
+ }
+
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+
+ tmp = SiS6326GetTVReg(pScrn,0x00);
+ if(!(tmp & 0x04)) {
+ return (int)pSiS->sis6326yfilterstrong;
+ } else {
+ tmp = SiS6326GetTVReg(pScrn,0x43);
+ if(!(tmp & 0x10)) {
+ return (int)pSiS->sis6326yfilterstrong;
+ } else {
+ return (int)((tmp >> 6) & 0x01);
+ }
+ }
+}
+
+void SiS_SetTVxposoffset(ScrnInfoPtr pScrn, int val)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+#ifdef SISDUALHEAD
+ SISEntPtr pSiSEnt = pSiS->entityPrivate;
+#endif
+
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+
+ pSiS->tvxpos = val;
+#ifdef SISDUALHEAD
+ if(pSiSEnt) pSiSEnt->tvxpos = val;
+#endif
+
+ if(pSiS->VGAEngine == SIS_300_VGA || pSiS->VGAEngine == SIS_315_VGA) {
+
+ if(pSiS->VBFlags & CRT2_TV) {
+
+ if(pSiS->VBFlags & VB_CHRONTEL) {
+
+ int x = pSiS->tvx;
+#ifdef SISDUALHEAD
+ if(pSiSEnt && pSiS->DualHeadMode) x = pSiSEnt->tvx;
+#endif
+ switch(pSiS->ChrontelType) {
+ case CHRONTEL_700x:
+ if((val >= -32) && (val <= 32)) {
+ x += val;
+ if(x < 0) x = 0;
+ SiS_SetCH700x(pSiS->SiS_Pr, (((x & 0xff) << 8) | 0x0a));
+ SiS_SetCH70xxANDOR(pSiS->SiS_Pr, (((x & 0x0100) << 1) | 0x08),0xFD);
+ }
+ break;
+ case CHRONTEL_701x:
+ /* TO DO */
+ break;
+ }
+
+ } else if(pSiS->VBFlags & VB_SISBRIDGE) {
+
+ if((val >= -32) && (val <= 32)) {
+ unsigned char p2_1f,p2_2b,p2_2c,p2_2d,p2_43;
+ const unsigned char p2_left_ntsc[8][4] = {
+ { 0x48, 0x63, 0x49, 0xf4 },
+ { 0x45, 0x60, 0x46, 0xf1 },
+ { 0x43, 0x6e, 0x44, 0xff },
+ { 0x40, 0x6b, 0x41, 0xfc },
+ { 0x3e, 0x69, 0x3f, 0xfa },
+ { 0x3c, 0x67, 0x3d, 0xf8 },
+ { 0x39, 0x64, 0x3a, 0xf5 },
+ { 0x37, 0x62, 0x38, 0xf3 }
+ };
+ const unsigned char p2_right_ntsc[8][4] = {
+ { 0x4b, 0x66, 0x4c, 0xf7 },
+ { 0x4c, 0x67, 0x4d, 0xf8 },
+ { 0x4e, 0x69, 0x4f, 0xfa },
+ { 0x4f, 0x6a, 0x50, 0xfb },
+ { 0x51, 0x6c, 0x52, 0xfd },
+ { 0x53, 0x6e, 0x54, 0xff },
+ { 0x55, 0x60, 0x56, 0xf1 },
+ { 0x56, 0x61, 0x57, 0xf2 }
+ };
+ const unsigned char p2_left_pal[8][4] = {
+ { 0x5b, 0x66, 0x5c, 0x87 },
+ { 0x59, 0x64, 0x5a, 0x85 },
+ { 0x56, 0x61, 0x57, 0x82 },
+ { 0x53, 0x6e, 0x54, 0x8f },
+ { 0x50, 0x6b, 0x51, 0x8c },
+ { 0x4d, 0x68, 0x4e, 0x89 },
+ { 0x4a, 0x65, 0x4b, 0x86 },
+ { 0x49, 0x64, 0x4a, 0x85 }
+ };
+ const unsigned char p2_right_pal[8][4] = {
+ { 0x5f, 0x6a, 0x60, 0x8b },
+ { 0x61, 0x6c, 0x62, 0x8d },
+ { 0x63, 0x6e, 0x64, 0x8f },
+ { 0x65, 0x60, 0x66, 0x81 },
+ { 0x66, 0x61, 0x67, 0x82 },
+ { 0x68, 0x63, 0x69, 0x84 },
+ { 0x69, 0x64, 0x6a, 0x85 },
+ { 0x6b, 0x66, 0x6c, 0x87 }
+ };
+ val /= 4;
+ p2_2d = pSiS->p2_2d;
+#ifdef SISDUALHEAD
+ if(pSiSEnt && pSiS->DualHeadMode) p2_2d = pSiSEnt->p2_2d;
+#endif
+ p2_2d &= 0xf0;
+ if(val < 0) {
+ val = -val;
+ if(val == 8) val = 7;
+ if(pSiS->VBFlags & TV_PAL) {
+ p2_1f = p2_left_pal[val][0];
+ p2_2b = p2_left_pal[val][1];
+ p2_2c = p2_left_pal[val][2];
+ p2_2d |= (p2_left_pal[val][3] & 0x0f);
+ } else {
+ p2_1f = p2_left_ntsc[val][0];
+ p2_2b = p2_left_ntsc[val][1];
+ p2_2c = p2_left_ntsc[val][2];
+ p2_2d |= (p2_left_ntsc[val][3] & 0x0f);
+ }
+ } else {
+ if(val == 8) val = 7;
+ if(pSiS->VBFlags & TV_PAL) {
+ p2_1f = p2_right_pal[val][0];
+ p2_2b = p2_right_pal[val][1];
+ p2_2c = p2_right_pal[val][2];
+ p2_2d |= (p2_right_pal[val][3] & 0x0f);
+ } else {
+ p2_1f = p2_right_ntsc[val][0];
+ p2_2b = p2_right_ntsc[val][1];
+ p2_2c = p2_right_ntsc[val][2];
+ p2_2d |= (p2_right_ntsc[val][3] & 0x0f);
+ }
+ }
+ p2_43 = p2_1f + 3;
+ SISWaitRetraceCRT2(pScrn);
+ outSISIDXREG(SISPART2,0x1f,p2_1f);
+ outSISIDXREG(SISPART2,0x2b,p2_2b);
+ outSISIDXREG(SISPART2,0x2c,p2_2c);
+ outSISIDXREG(SISPART2,0x2d,p2_2d);
+ outSISIDXREG(SISPART2,0x43,p2_43);
+ }
+ }
+ }
+
+ } else if(pSiS->Chipset == PCI_CHIP_SIS6326) {
+
+ if(pSiS->SiS6326Flags & SIS6326_TVDETECTED) {
+
+ unsigned char tmp;
+ unsigned short temp1, temp2, temp3;
+
+ tmp = SiS6326GetTVReg(pScrn,0x00);
+ if(tmp & 0x04) {
+
+ temp1 = pSiS->tvx1;
+ temp2 = pSiS->tvx2;
+ temp3 = pSiS->tvx3;
+ if((val >= -16) && (val <= 16)) {
+ if(val > 0) {
+ temp1 += (val * 4);
+ temp2 += (val * 4);
+ while((temp1 > 0x0fff) || (temp2 > 0x0fff)) {
+ temp1 -= 4;
+ temp2 -= 4;
+ }
+ } else {
+ val = -val;
+ temp3 += (val * 4);
+ while(temp3 > 0x03ff) {
+ temp3 -= 4;
+ }
+ }
+ }
+ SiS6326SetTVReg(pScrn,0x3a,(temp1 & 0xff));
+ tmp = SiS6326GetTVReg(pScrn,0x3c);
+ tmp &= 0xf0;
+ tmp |= ((temp1 & 0x0f00) >> 8);
+ SiS6326SetTVReg(pScrn,0x3c,tmp);
+ SiS6326SetTVReg(pScrn,0x26,(temp2 & 0xff));
+ tmp = SiS6326GetTVReg(pScrn,0x27);
+ tmp &= 0x0f;
+ tmp |= ((temp2 & 0x0f00) >> 4);
+ SiS6326SetTVReg(pScrn,0x27,tmp);
+ SiS6326SetTVReg(pScrn,0x12,(temp3 & 0xff));
+ tmp = SiS6326GetTVReg(pScrn,0x13);
+ tmp &= ~0xC0;
+ tmp |= ((temp3 & 0x0300) >> 2);
+ SiS6326SetTVReg(pScrn,0x13,tmp);
+ }
+ }
+ }
+}
+
+int SiS_GetTVxposoffset(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+#ifdef SISDUALHEAD
+ SISEntPtr pSiSEnt = pSiS->entityPrivate;
+
+ if(pSiSEnt && pSiS->DualHeadMode)
+ return (int)pSiSEnt->tvxpos;
+ else
+#endif
+ return (int)pSiS->tvxpos;
+}
+
+void SiS_SetTVyposoffset(ScrnInfoPtr pScrn, int val)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+#ifdef SISDUALHEAD
+ SISEntPtr pSiSEnt = pSiS->entityPrivate;
+#endif
+
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+
+ pSiS->tvypos = val;
+#ifdef SISDUALHEAD
+ if(pSiSEnt) pSiSEnt->tvypos = val;
+#endif
+
+ if(pSiS->VGAEngine == SIS_300_VGA || pSiS->VGAEngine == SIS_315_VGA) {
+
+ if(pSiS->VBFlags & CRT2_TV) {
+
+ if(pSiS->VBFlags & VB_CHRONTEL) {
+
+ int y = pSiS->tvy;
+#ifdef SISDUALHEAD
+ if(pSiSEnt && pSiS->DualHeadMode) y = pSiSEnt->tvy;
+#endif
+ switch(pSiS->ChrontelType) {
+ case CHRONTEL_700x:
+ if((val >= -32) && (val <= 32)) {
+ y -= val;
+ if(y < 0) y = 0;
+ SiS_SetCH700x(pSiS->SiS_Pr, (((y & 0xff) << 8) | 0x0b));
+ SiS_SetCH70xxANDOR(pSiS->SiS_Pr, ((y & 0x0100) | 0x08),0xFE);
+ }
+ break;
+ case CHRONTEL_701x:
+ /* TO DO */
+ break;
+ }
+
+ } else if(pSiS->VBFlags & VB_SISBRIDGE) {
+
+ if((val >= -32) && (val <= 32)) {
+ char p2_01, p2_02;
+ val /= 4;
+ p2_01 = pSiS->p2_01;
+ p2_02 = pSiS->p2_02;
+#ifdef SISDUALHEAD
+ if(pSiSEnt && pSiS->DualHeadMode) {
+ p2_01 = pSiSEnt->p2_01;
+ p2_02 = pSiSEnt->p2_02;
+ }
+#endif
+ p2_01 += (val * 2);
+ p2_02 += (val * 2);
+ while((p2_01 <= 0) || (p2_02 <= 0)) {
+ p2_01 += 2;
+ p2_02 += 2;
+ }
+ SISWaitRetraceCRT2(pScrn);
+ outSISIDXREG(SISPART2,0x01,p2_01);
+ outSISIDXREG(SISPART2,0x02,p2_02);
+ }
+ }
+
+ }
+
+ } else if(pSiS->Chipset == PCI_CHIP_SIS6326) {
+
+ if(pSiS->SiS6326Flags & SIS6326_TVDETECTED) {
+
+ unsigned char tmp;
+ int temp1, limit;
+
+ tmp = SiS6326GetTVReg(pScrn,0x00);
+ if(tmp & 0x04) {
+
+ if((val >= -16) && (val <= 16)) {
+ temp1 = (unsigned short)pSiS->tvy1;
+ limit = (pSiS->SiS6326Flags & SIS6326_TVPAL) ? 625 : 525;
+ if(val > 0) {
+ temp1 += (val * 4);
+ if(temp1 > limit) temp1 -= limit;
+ } else {
+ val = -val;
+ temp1 -= (val * 2);
+ if(temp1 <= 0) temp1 += (limit -1);
+ }
+ SiS6326SetTVReg(pScrn,0x11,(temp1 & 0xff));
+ tmp = SiS6326GetTVReg(pScrn,0x13);
+ tmp &= ~0x30;
+ tmp |= ((temp1 & 0x300) >> 4);
+ SiS6326SetTVReg(pScrn,0x13,tmp);
+ if(temp1 == 1) tmp = 0x10;
+ else {
+ if(pSiS->SiS6326Flags & SIS6326_TVPAL) {
+ if((temp1 <= 3) || (temp1 >= (limit - 2))) tmp = 0x08;
+ else if(temp1 < 22) tmp = 0x02;
+ else tmp = 0x04;
+ } else {
+ if((temp1 <= 5) || (temp1 >= (limit - 4))) tmp = 0x08;
+ else if(temp1 < 19) tmp = 0x02;
+ else tmp = 0x04;
+ }
+ }
+ SiS6326SetTVReg(pScrn,0x21,tmp);
+ }
+ }
+ }
+ }
+}
+
+int SiS_GetTVyposoffset(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+#ifdef SISDUALHEAD
+ SISEntPtr pSiSEnt = pSiS->entityPrivate;
+
+ if(pSiSEnt && pSiS->DualHeadMode)
+ return (int)pSiSEnt->tvypos;
+ else
+#endif
+ return (int)pSiS->tvypos;
+}
+
+/* TW: Disable CRT1 for saving bandwidth. This doesn't work with VESA;
+ * VESA uses the bridge in SlaveMode and switching CRT1 off while the
+ * bridge is in SlaveMode not that clever...
+ */
+void SiSPostSetMode(ScrnInfoPtr pScrn, SISRegPtr sisReg)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+#ifdef SISDUALHEAD
+ SISEntPtr pSiSEnt = pSiS->entityPrivate;
+#endif
+ unsigned char usScratchCR17;
+ Bool flag = FALSE;
+ Bool doit = TRUE;
+ int temp;
+
+#ifdef TWDEBUG
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "CRT1off is %d\n", pSiS->CRT1off);
+#endif
+
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+
+ if((!pSiS->UseVESA) && (pSiS->VBFlags & CRT2_ENABLE)) {
+
+ if(pSiS->VBFlags != pSiS->VBFlags_backup) {
+ pSiS->VBFlags = pSiS->VBFlags_backup;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "VBFlags restored to %0lx\n", pSiS->VBFlags);
+ }
+
+ /* TW: -) We can't switch off CRT1 if bridge is in SlaveMode.
+ * -) If we change to a SlaveMode-Mode (like 512x384), we
+ * need to adapt VBFlags for eg. Xv.
+ */
+#ifdef SISDUALHEAD
+ if(!pSiS->DualHeadMode) {
+#endif
+ if(SiSBridgeIsInSlaveMode(pScrn)) {
+ doit = FALSE;
+ temp = pSiS->VBFlags;
+ pSiS->VBFlags &= (~VB_DISPMODE_SINGLE);
+ pSiS->VBFlags |= (VB_DISPMODE_MIRROR | DISPTYPE_DISP1);
+ if(temp != pSiS->VBFlags) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "VBFlags changed to 0x%0lx\n", pSiS->VBFlags);
+ }
+ }
+#ifdef SISDUALHEAD
+ }
+#endif
+ if(doit) {
+ inSISIDXREG(SISCR, 0x17, usScratchCR17);
+ if(pSiS->CRT1off) {
+ if(usScratchCR17 & 0x80) flag = TRUE;
+ usScratchCR17 &= ~0x80;
+ } else {
+ if(!(usScratchCR17 & 0x80)) flag = TRUE;
+ usScratchCR17 |= 0x80;
+ }
+ outSISIDXREG(SISCR, 0x17, usScratchCR17);
+ /* TW: Reset only if status changed */
+ if(flag) {
+ outSISIDXREG(SISSR, 0x00, 0x01); /* Synchronous Reset */
+ usleep(10000);
+ outSISIDXREG(SISSR, 0x00, 0x03); /* End Reset */
+ }
+ }
+ }
+
+ /* TW: Apply TV settings given by options
+ Do this even in DualHeadMode:
+ - if this is called by SetModeCRT1, CRT2 mode has been reset by SetModeCRT1
+ - if this is called by SetModeCRT2, CRT2 mode has changed (duh!)
+ -> In both cases, the settings must be re-applied.
+ */
+ if(pSiS->VBFlags & CRT2_TV) {
+ int val;
+ if(pSiS->VBFlags & VB_CHRONTEL) {
+ int mychtvlumabandwidthcvbs = pSiS->chtvlumabandwidthcvbs;
+ int mychtvlumabandwidthsvideo = pSiS->chtvlumabandwidthsvideo;
+ int mychtvlumaflickerfilter = pSiS->chtvlumaflickerfilter;
+ int mychtvchromabandwidth = pSiS->chtvchromabandwidth;
+ int mychtvchromaflickerfilter = pSiS->chtvchromaflickerfilter;
+ int mychtvcvbscolor = pSiS->chtvcvbscolor;
+ int mychtvtextenhance = pSiS->chtvtextenhance;
+ int mychtvcontrast = pSiS->chtvcontrast;
+ int mytvxpos = pSiS->tvxpos;
+ int mytvypos = pSiS->tvypos;
+#ifdef SISDUALHEAD
+ if(pSiSEnt && pSiS->DualHeadMode) {
+ mychtvlumabandwidthcvbs = pSiSEnt->chtvlumabandwidthcvbs;
+ mychtvlumabandwidthsvideo = pSiSEnt->chtvlumabandwidthsvideo;
+ mychtvlumaflickerfilter = pSiSEnt->chtvlumaflickerfilter;
+ mychtvchromabandwidth = pSiSEnt->chtvchromabandwidth;
+ mychtvchromaflickerfilter = pSiSEnt->chtvchromaflickerfilter;
+ mychtvcvbscolor = pSiSEnt->chtvcvbscolor;
+ mychtvtextenhance = pSiSEnt->chtvtextenhance;
+ mychtvcontrast = pSiSEnt->chtvcontrast;
+ mytvxpos = pSiSEnt->tvxpos;
+ mytvypos = pSiSEnt->tvypos;
+ }
+#endif
+ if((val = mychtvlumabandwidthcvbs) != -1) {
+ SiS_SetCHTVlumabandwidthcvbs(pScrn, val);
+ }
+ if((val = mychtvlumabandwidthsvideo) != -1) {
+ SiS_SetCHTVlumabandwidthsvideo(pScrn, val);
+ }
+ if((val = mychtvlumaflickerfilter) != -1) {
+ SiS_SetCHTVlumaflickerfilter(pScrn, val);
+ }
+ if((val = mychtvchromabandwidth) != -1) {
+ SiS_SetCHTVchromabandwidth(pScrn, val);
+ }
+ if((val = mychtvchromaflickerfilter) != -1) {
+ SiS_SetCHTVchromaflickerfilter(pScrn, val);
+ }
+ if((val = mychtvcvbscolor) != -1) {
+ SiS_SetCHTVcvbscolor(pScrn, val);
+ }
+ if((val = mychtvtextenhance) != -1) {
+ SiS_SetCHTVtextenhance(pScrn, val);
+ }
+ if((val = mychtvcontrast) != -1) {
+ SiS_SetCHTVcontrast(pScrn, val);
+ }
+ /* Backup default TV position registers */
+ switch(pSiS->ChrontelType) {
+ case CHRONTEL_700x:
+ pSiS->tvx = SiS_GetCH700x(pSiS->SiS_Pr, 0x0a);
+ pSiS->tvx |= (((SiS_GetCH700x(pSiS->SiS_Pr, 0x08) & 0x02) >> 1) << 8);
+ pSiS->tvy = SiS_GetCH700x(pSiS->SiS_Pr, 0x0b);
+ pSiS->tvy |= ((SiS_GetCH700x(pSiS->SiS_Pr, 0x08) & 0x01) << 8);
+#ifdef SISDUALHEAD
+ if(pSiSEnt && pSiS->DualHeadMode) {
+ pSiSEnt->tvx = pSiS->tvx;
+ pSiSEnt->tvy = pSiS->tvy;
+ }
+#endif
+ break;
+ case CHRONTEL_701x:
+ /* TO DO */
+ break;
+ }
+ if((val = mytvxpos) != 0) {
+ SiS_SetTVxposoffset(pScrn, val);
+ }
+ if((val = mytvypos) != 0) {
+ SiS_SetTVyposoffset(pScrn, val);
+ }
+ }
+ if(pSiS->VBFlags & VB_301) {
+ int mysistvedgeenhance = pSiS->sistvedgeenhance;
+#ifdef SISDUALHEAD
+ if(pSiSEnt && pSiS->DualHeadMode) {
+ mysistvedgeenhance = pSiSEnt->sistvedgeenhance;
+ }
+#endif
+ if((val = mysistvedgeenhance) != -1) {
+ SiS_SetSISTVedgeenhance(pScrn, val);
+ }
+ }
+ if(pSiS->VBFlags & VB_SISBRIDGE) {
+ int mysistvantiflicker = pSiS->sistvantiflicker;
+ int mysistvsaturation = pSiS->sistvsaturation;
+ int mytvxpos = pSiS->tvxpos;
+ int mytvypos = pSiS->tvypos;
+#ifdef SISDUALHEAD
+ if(pSiSEnt && pSiS->DualHeadMode) {
+ mysistvantiflicker = pSiSEnt->sistvantiflicker;
+ mysistvsaturation = pSiSEnt->sistvsaturation;
+ mytvxpos = pSiSEnt->tvxpos;
+ mytvypos = pSiSEnt->tvypos;
+ }
+#endif
+ /* Backup default TV position registers */
+ inSISIDXREG(SISPART2,0x2d,pSiS->p2_2d);
+ inSISIDXREG(SISPART2,0x01,pSiS->p2_01);
+ inSISIDXREG(SISPART2,0x02,pSiS->p2_02);
+#ifdef SISDUALHEAD
+ if(pSiSEnt && pSiS->DualHeadMode) {
+ pSiSEnt->p2_2d = pSiS->p2_2d;
+ pSiSEnt->p2_01 = pSiS->p2_01;
+ pSiSEnt->p2_02 = pSiS->p2_02;
+ }
+#endif
+ if((val = mysistvantiflicker) != -1) {
+ SiS_SetSISTVantiflicker(pScrn, val);
+ }
+ if((val = mysistvsaturation) != -1) {
+ SiS_SetSISTVsaturation(pScrn, val);
+ }
+ if((val = mytvxpos) != 0) {
+ SiS_SetTVxposoffset(pScrn, val);
+ }
+ if((val = mytvypos) != 0) {
+ SiS_SetTVyposoffset(pScrn, val);
+ }
+ }
+ }
+
+}
+
+/* Post-set SiS6326 TV registers */
+void SiS6326PostSetMode(ScrnInfoPtr pScrn, SISRegPtr sisReg)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ unsigned char tmp;
+ int val;
+
+ if(!(pSiS->SiS6326Flags & SIS6326_TVDETECTED)) return;
+
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+
+ /* Backup default TV position registers */
+ pSiS->tvx1 = SiS6326GetTVReg(pScrn,0x3a);
+ pSiS->tvx1 |= ((SiS6326GetTVReg(pScrn,0x3c) & 0x0f) << 8);
+ pSiS->tvx2 = SiS6326GetTVReg(pScrn,0x26);
+ pSiS->tvx2 |= ((SiS6326GetTVReg(pScrn,0x27) & 0xf0) << 4);
+ pSiS->tvx3 = SiS6326GetTVReg(pScrn,0x12);
+ pSiS->tvx3 |= ((SiS6326GetTVReg(pScrn,0x13) & 0xC0) << 2);
+ pSiS->tvy1 = SiS6326GetTVReg(pScrn,0x11);
+ pSiS->tvy1 |= ((SiS6326GetTVReg(pScrn,0x13) & 0x30) << 4);
+
+ /* TW: Handle TVPosOffset options (BEFORE switching on TV) */
+ if((val = pSiS->tvxpos) != 0) {
+ SiS_SetTVxposoffset(pScrn, val);
+ }
+ if((val = pSiS->tvypos) != 0) {
+ SiS_SetTVyposoffset(pScrn, val);
+ }
+
+ /* TW: Switch on TV output. This is rather complicated, but
+ * if we don't do it, TV output will flicker terribly.
+ */
+ if(pSiS->SiS6326Flags & SIS6326_TVON) {
+ orSISIDXREG(SISSR, 0x01, 0x20);
+ tmp = SiS6326GetTVReg(pScrn,0x00);
+ tmp &= ~0x04;
+ while(!(inSISREG(SISINPSTAT) & 0x08)); /* Wait while NOT vb */
+ SiS6326SetTVReg(pScrn,0x00,tmp);
+ for(val=0; val < 2; val++) {
+ while(!(inSISREG(SISINPSTAT) & 0x08)); /* Wait while NOT vb */
+ while(inSISREG(SISINPSTAT) & 0x08); /* wait while vb */
+ }
+ SiS6326SetTVReg(pScrn, 0x00, sisReg->sis6326tv[0]);
+ tmp = inSISREG(SISINPSTAT);
+ outSISREG(SISAR, 0x20);
+ tmp = inSISREG(SISINPSTAT);
+ while(inSISREG(SISINPSTAT) & 0x01);
+ while(!(inSISREG(SISINPSTAT) & 0x01));
+ andSISIDXREG(SISSR, 0x01, ~0x20);
+ for(val=0; val < 10; val++) {
+ while(!(inSISREG(SISINPSTAT) & 0x08)); /* Wait while NOT vb */
+ while(inSISREG(SISINPSTAT) & 0x08); /* wait while vb */
+ }
+ andSISIDXREG(SISSR, 0x01, ~0x20);
+ }
+
+ tmp = SiS6326GetTVReg(pScrn,0x00);
+ if(!(tmp & 0x04)) return;
+
+ /* TW: Apply TV settings given by options */
+ if((val = pSiS->sis6326antiflicker) != -1) {
+ SiS_SetSIS6326TVantiflicker(pScrn, val);
+ }
+ if((val = pSiS->sis6326enableyfilter) != -1) {
+ SiS_SetSIS6326TVenableyfilter(pScrn, val);
+ }
+ if((val = pSiS->sis6326yfilterstrong) != -1) {
+ SiS_SetSIS6326TVyfilterstrong(pScrn, val);
+ }
+
+}
+
+/* Check if video bridge is in slave mode */
+BOOLEAN
+SiSBridgeIsInSlaveMode(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ unsigned char usScratchP1_00;
+
+ if(!(pSiS->VBFlags & VB_VIDEOBRIDGE)) return FALSE;
+
+ inSISIDXREG(SISPART1,0x00,usScratchP1_00);
+ if( ((pSiS->VGAEngine == SIS_300_VGA) && (usScratchP1_00 & 0xa0) == 0x20) ||
+ ((pSiS->VGAEngine == SIS_315_VGA) && (usScratchP1_00 & 0x50) == 0x10) ) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+/* TW: Build a list of the VESA modes the BIOS reports as valid */
+static void
+SiSBuildVesaModeList(ScrnInfoPtr pScrn, vbeInfoPtr pVbe, VbeInfoBlock *vbe)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int i = 0;
+
+ while(vbe->VideoModePtr[i] != 0xffff) {
+ sisModeInfoPtr m;
+ VbeModeInfoBlock *mode;
+ int id = vbe->VideoModePtr[i++];
+ int bpp;
+
+ if ((mode = VBEGetModeInfo(pVbe, id)) == NULL)
+ continue;
+
+ bpp = mode->BitsPerPixel;
+
+ m = xnfcalloc(sizeof(sisModeInfoRec),1);
+ m->width = mode->XResolution;
+ m->height = mode->YResolution;
+ m->bpp = bpp;
+ m->n = id;
+ m->next = pSiS->SISVESAModeList;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "BIOS reported VESA mode 0x%x: x:%i y:%i bpp:%i\n",
+ m->n, m->width, m->height, m->bpp);
+
+ pSiS->SISVESAModeList = m;
+
+ VBEFreeModeInfo(mode);
+ }
+}
+
+/* TW: Calc VESA mode from given resolution/depth */
+static UShort
+SiSCalcVESAModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ sisModeInfoPtr m = pSiS->SISVESAModeList;
+ UShort i = (pScrn->bitsPerPixel+7)/8 - 1;
+ UShort ModeIndex = 0;
+
+ while(m) {
+ if(pScrn->bitsPerPixel == m->bpp &&
+ mode->HDisplay == m->width &&
+ mode->VDisplay == m->height)
+ return m->n;
+ m = m->next;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "No valid BIOS VESA mode found for %dx%dx%d; searching built-in table.\n",
+ mode->HDisplay, mode->VDisplay, pScrn->bitsPerPixel);
+
+ switch(mode->HDisplay) {
+ case 512:
+ if(mode->VDisplay == 384)
+ ModeIndex = VESAModeIndex_512x384[i];
+ break;
+ case 640:
+ if(mode->VDisplay == 480)
+ ModeIndex = VESAModeIndex_640x480[i];
+ break;
+ case 800:
+ if(mode->VDisplay == 600)
+ ModeIndex = VESAModeIndex_800x600[i];
+ break;
+ case 1024:
+ if(mode->VDisplay == 768)
+ ModeIndex = VESAModeIndex_1024x768[i];
+ break;
+ case 1280:
+ if(mode->VDisplay == 1024)
+ ModeIndex = VESAModeIndex_1280x1024[i];
+ break;
+ case 1600:
+ if(mode->VDisplay == 1200)
+ ModeIndex = VESAModeIndex_1600x1200[i];
+ break;
+ case 1920:
+ if(mode->VDisplay == 1440)
+ ModeIndex = VESAModeIndex_1920x1440[i];
+ break;
+ }
+
+ if(!ModeIndex) xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "No valid mode found for %dx%dx%d in built-in table either.\n",
+ mode->HDisplay, mode->VDisplay, pScrn->bitsPerPixel);
+
+ return(ModeIndex);
+}
+
+/* TW: Calculate the vertical refresh rate from a mode */
+int
+SiSCalcVRate(DisplayModePtr mode)
+{
+ float hsync, refresh = 0;
+
+ if(mode->HSync > 0.0)
+ hsync = mode->HSync;
+ else if(mode->HTotal > 0)
+ hsync = (float)mode->Clock / (float)mode->HTotal;
+ else
+ hsync = 0.0;
+
+ if(mode->VTotal > 0)
+ refresh = hsync * 1000.0 / mode->VTotal;
+
+ if(mode->Flags & V_INTERLACE)
+ refresh *= 2.0;
+
+ if(mode->Flags & V_DBLSCAN)
+ refresh /= 2.0;
+
+ if(mode->VScan > 1)
+ refresh /= mode->VScan;
+
+ if(mode->VRefresh > 0.0)
+ refresh = mode->VRefresh;
+
+ if(hsync == 0 || refresh == 0) return(0);
+
+ return((int)(refresh));
+}
+
+/* TW: Calculate CR33 (rate index) for CRT1.
+ * Calculation is done using currentmode, therefore it is
+ * recommended to set VertRefresh and HorizSync to correct
+ * values in config file.
+ */
+unsigned char
+SISSearchCRT1Rate(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int i = 0;
+ int irefresh;
+ unsigned short xres = mode->HDisplay;
+ unsigned short yres = mode->VDisplay;
+ unsigned char index;
+ BOOLEAN checksis730 = FALSE;
+
+ irefresh = SiSCalcVRate(mode);
+ if(!irefresh) {
+ if(xres == 800 || xres == 1024 || xres == 1280) return 0x02;
+ else return 0x01;
+ }
+
+ /* SiS730 has troubles on CRT2 if CRT1 is at 32bpp */
+ if( (pSiS->sishw_ext.jChipType == SIS_730) &&
+ (pSiS->VBFlags & VB_VIDEOBRIDGE) &&
+ (pSiS->CurrentLayout.bitsPerPixel == 32) ) {
+#ifdef SISDUALHEAD
+ if(pSiS->DualHeadMode) {
+ if(pSiS->SecondHead) {
+ checksis730 = TRUE;
+ }
+ } else
+#endif
+ if((!pSiS->UseVESA) && (pSiS->VBFlags & CRT2_ENABLE) && (!pSiS->CRT1off)) {
+ checksis730 = TRUE;
+ }
+ }
+
+#ifdef TWDEBUG
+ xf86DrvMsg(0, X_INFO, "Debug: CalcVRate returned %d\n", irefresh);
+#endif
+
+ /* We need the REAL refresh rate here */
+ if(mode->Flags & V_INTERLACE)
+ irefresh /= 2;
+
+ /* Do not multiply by 2 when DBLSCAN! */
+
+#ifdef TWDEBUG
+ xf86DrvMsg(0, X_INFO, "Debug: Rate after correction = %d\n", irefresh);
+#endif
+
+ index = 0;
+ while((sisx_vrate[i].idx != 0) && (sisx_vrate[i].xres <= xres)) {
+ if((sisx_vrate[i].xres == xres) && (sisx_vrate[i].yres == yres)) {
+ if((checksis730 == FALSE) || (sisx_vrate[i].SiS730valid32bpp == TRUE)) {
+ if(sisx_vrate[i].refresh == irefresh) {
+ index = sisx_vrate[i].idx;
+ break;
+ } else if(sisx_vrate[i].refresh > irefresh) {
+ if((sisx_vrate[i].refresh - irefresh) <= 3) {
+ index = sisx_vrate[i].idx;
+ } else if( ((checksis730 == FALSE) || (sisx_vrate[i - 1].SiS730valid32bpp == TRUE)) &&
+ ((irefresh - sisx_vrate[i - 1].refresh) <= 2) &&
+ (sisx_vrate[i].idx != 1) ) {
+ index = sisx_vrate[i - 1].idx;
+ }
+ break;
+ }
+ }
+ }
+ i++;
+ }
+ if(index > 0)
+ return index;
+ else {
+ /* TW: Default Rate index */
+ if(xres == 800 || xres == 1024 || xres == 1280) return 0x02;
+ else return 0x01;
+ }
+}
+
+void
+SISWaitRetraceCRT1(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int watchdog;
+ unsigned char temp;
+
+ inSISIDXREG(SISCR,0x17,temp);
+ if(!(temp & 0x80)) return;
+
+ watchdog = 65536;
+ while((!(inSISREG(SISINPSTAT) & 0x08)) && --watchdog);
+ watchdog = 65536;
+ while((inSISREG(SISINPSTAT) & 0x08) && --watchdog);
+}
+
+void
+SISWaitRetraceCRT2(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int watchdog;
+ unsigned char temp, reg;
+
+ switch(pSiS->VGAEngine) {
+ case SIS_300_VGA:
+ reg = 0x28;
+ break;
+ case SIS_315_VGA:
+ reg = 0x33;
+ break;
+ default:
+ return;
+ }
+
+ watchdog = 65536;
+ do {
+ inSISIDXREG(SISPART1, reg, temp);
+ if(temp & 0x80) break;
+ } while(--watchdog);
+ watchdog = 65536;
+ do {
+ inSISIDXREG(SISPART1, reg, temp);
+ if(!(temp & 0x80)) break;
+ } while(--watchdog);
+}
+
+static void
+SISWaitVBRetrace(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+
+#ifdef SISDUALHEAD
+ if(pSiS->DualHeadMode) {
+ if(pSiS->SecondHead)
+ SISWaitRetraceCRT1(pScrn);
+ else
+ SISWaitRetraceCRT2(pScrn);
+ } else {
+#endif
+ if(pSiS->VBFlags & DISPTYPE_DISP1) {
+ SISWaitRetraceCRT1(pScrn);
+ }
+ if(pSiS->VBFlags & DISPTYPE_DISP2) {
+ if(!(SiSBridgeIsInSlaveMode(pScrn))) {
+ SISWaitRetraceCRT2(pScrn);
+ }
+ }
+#ifdef SISDUALHEAD
+ }
+#endif
+}
+
+void
+sisSaveUnlockExtRegisterLock(SISPtr pSiS, unsigned char *reg1, unsigned char *reg2)
+{
+ register unsigned char val;
+ unsigned long mylockcalls;
+
+ pSiS->lockcalls++;
+ mylockcalls = pSiS->lockcalls;
+
+ /* check if already unlocked */
+ inSISIDXREG(SISSR, 0x05, val);
+ if(val != 0xa1) {
+ /* save State */
+ if(reg1) *reg1 = val;
+ /* unlock */
+ outSISIDXREG(SISSR, 0x05, 0x86);
+ inSISIDXREG(SISSR, 0x05, val);
+ if(val != 0xA1) {
+#ifdef TWDEBUG
+ unsigned char val1, val2;
+ int i;
+#endif
+ xf86DrvMsg(pSiS->pScrn->scrnIndex, X_ERROR,
+ "Failed to unlock sr registers (%p, %x, 0x%02x; %d)\n",
+ pSiS, pSiS->RelIO, val, mylockcalls);
+#ifdef TWDEBUG
+ for(i = 0; i <= 0x3f; i++) {
+ inSISIDXREG(SISSR, i, val1);
+ inSISIDXREG(0x3c4, i, val2);
+ xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO,
+ "SR%02d: RelIO=0x%02x 0x3c4=0x%02x (%d)\n", i, val1, val2, mylockcalls);
+ }
+#endif
+ if((pSiS->VGAEngine == SIS_OLD_VGA) || (pSiS->VGAEngine == SIS_530_VGA)) {
+ /* Emergency measure: unlock at 0x3c4, and try to enable Relocated IO ports */
+ outSISIDXREG(0x3c4,0x05,0x86);
+ andSISIDXREG(0x3c4,0x33,~0x20);
+ outSISIDXREG(SISSR, 0x05, 0x86);
+ }
+ }
+ }
+ if((pSiS->VGAEngine == SIS_OLD_VGA) || (pSiS->VGAEngine == SIS_530_VGA)) {
+ inSISIDXREG(SISCR, 0x80, val);
+ if(val != 0xa1) {
+ /* save State */
+ if(reg2) *reg2 = val;
+ outSISIDXREG(SISCR, 0x80, 0x86);
+ inSISIDXREG(SISCR, 0x80, val);
+ if(val != 0xA1) {
+ xf86DrvMsg(pSiS->pScrn->scrnIndex, X_ERROR,
+ "Failed to unlock cr registers (%p, %x, 0x%02x)\n",
+ pSiS, pSiS->RelIO, val);
+ }
+ }
+ }
+}
+
+void
+sisRestoreExtRegisterLock(SISPtr pSiS, unsigned char reg1, unsigned char reg2)
+{
+ /* restore lock */
+#ifndef UNLOCK_ALWAYS
+ outSISIDXREG(SISSR, 0x05, reg1 == 0xA1 ? 0x86 : 0x00);
+ if((pSiS->VGAEngine == SIS_OLD_VGA) || (pSiS->VGAEngine == SIS_530_VGA)) {
+ outSISIDXREG(SISCR, 0x80, reg2 == 0xA1 ? 0x86 : 0x00);
+ }
+#endif
+}
+
diff --git a/src/sis_driver.h b/src/sis_driver.h
new file mode 100644
index 0000000..8a53cae
--- /dev/null
+++ b/src/sis_driver.h
@@ -0,0 +1,512 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_driver.h,v 1.7 2003/02/04 02:44:29 dawes Exp $ */
+/*
+ * sis_driver.h
+ *
+ * Copyright 2002 by Thomas Winischhofer, Vienna, Austria.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the copyright holder not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The copyright holder makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Thomas Winischhofer <thomas@winischhofer.net>:
+ * - 310/325 series (315/550/650/651/740/M650) support
+ * - new mode switching code for 300 and 310/325 series
+ * - many fixes for 300/540/630/730 chipsets,
+ * - many fixes for 5597/5598, 6326 and 530/620 chipsets,
+ * - VESA mode switching (deprecated),
+ * - extended CRT2/video bridge handling support,
+ * - dual head support on 300 and 310/325 series
+ * - 650/LVDS (up to 1400x1050), 650/Chrontel 701x support
+ * - 30xB/30xLV/30xLVX video bridge support (300, 310/325 series)
+ * - Xv support for 5597/5598, 6326, 530/620 and 310/325 series
+ * - video overlay enhancements for 300 series
+ * - etc.
+ */
+
+/* VESA */
+/* TW: The following is included because there are BIOSes out there that
+ * report incomplete mode lists. These are 630 BIOS versions <2.01.2x
+ *
+ * -) VBE 3.0 on SiS300 and 310/325 series do not support 24 fpp modes
+ * -) Only SiS310/325 series support 1920x1440x32
+ */
+ /* 8 16 (24) 32 */
+static const UShort VESAModeIndex_512x384[] = {0x134, 0x137, 0x000, 0x000};
+static const UShort VESAModeIndex_640x480[] = {0x101, 0x111, 0x000, 0x13a};
+static const UShort VESAModeIndex_800x600[] = {0x103, 0x114, 0x000, 0x13b};
+static const UShort VESAModeIndex_1024x768[] = {0x105, 0x117, 0x000, 0x13c};
+static const UShort VESAModeIndex_1280x1024[] = {0x107, 0x11a, 0x000, 0x13d};
+static const UShort VESAModeIndex_1600x1200[] = {0x130, 0x131, 0x000, 0x13e};
+static const UShort VESAModeIndex_1920x1440[] = {0x13f, 0x140, 0x000, 0x141};
+
+/* TW: For calculating refresh rate index (CR33) */
+static const struct _sis_vrate {
+ CARD16 idx;
+ CARD16 xres;
+ CARD16 yres;
+ CARD16 refresh;
+ BOOLEAN SiS730valid32bpp;
+} sisx_vrate[] = {
+ {1, 512, 384, 60, TRUE},
+ {1, 640, 400, 72, TRUE},
+ {1, 640, 480, 60, TRUE}, {2, 640, 480, 72, TRUE}, {3, 640, 480, 75, TRUE},
+ {4, 640, 480, 85, TRUE}, {5, 640, 480, 100, TRUE}, {6, 640, 480, 120, TRUE},
+ {7, 640, 480, 160, TRUE}, {8, 640, 480, 200, TRUE},
+ {1, 720, 480, 60, TRUE},
+ {1, 720, 576, 58, TRUE},
+ {1, 800, 480, 60, TRUE}, {2, 800, 480, 75, TRUE}, {3, 800, 480, 85, TRUE},
+ {1, 800, 600, 56, TRUE}, {2, 800, 600, 60, TRUE}, {3, 800, 600, 72, TRUE},
+ {4, 800, 600, 75, TRUE}, {5, 800, 600, 85, TRUE}, {6, 800, 600, 105, TRUE},
+ {7, 800, 600, 120, TRUE}, {8, 800, 600, 160, TRUE},
+ {1, 848, 480, 39, TRUE}, {2, 848, 480, 60, TRUE},
+ {1, 856, 480, 39, TRUE}, {2, 856, 480, 60, TRUE},
+ {1, 1024, 768, 43, TRUE}, {2, 1024, 768, 60, TRUE}, {3, 1024, 768, 70, FALSE},
+ {4, 1024, 768, 75, FALSE}, {5, 1024, 768, 85, TRUE}, {6, 1024, 768, 100, TRUE},
+ {7, 1024, 768, 120, TRUE},
+ {1, 1024, 576, 60, TRUE}, {2, 1024, 576, 75, TRUE}, {3, 1024, 576, 85, TRUE},
+ {1, 1024, 600, 60, TRUE},
+ {1, 1152, 768, 60, TRUE},
+ {1, 1152, 864, 75, TRUE}, {2, 1152, 864, 84, TRUE},
+ {1, 1280, 720, 60, TRUE}, {2, 1280, 720, 75, TRUE}, {3, 1280, 720, 85, TRUE},
+ {1, 1280, 768, 60, TRUE},
+ {1, 1280, 1024, 43, TRUE}, {2, 1280, 1024, 60, TRUE}, {3, 1280, 1024, 75, TRUE},
+ {4, 1280, 1024, 85, TRUE},
+ {1, 1280, 960, 60, TRUE}, {2, 1280, 960, 85, TRUE},
+ {1, 1360, 768, 60, TRUE},
+ {1, 1400, 1050, 60, TRUE}, {2, 1400, 1050, 75, TRUE},
+ {1, 1600, 1200, 60, TRUE}, {2, 1600, 1200, 65, TRUE}, {3, 1600, 1200, 70, TRUE},
+ {4, 1600, 1200, 75, TRUE}, {5, 1600, 1200, 85, TRUE}, {6, 1600, 1200, 100, TRUE},
+ {7, 1600, 1200, 120, TRUE},
+ {1, 1920, 1440, 60, TRUE}, {2, 1920, 1440, 65, TRUE}, {3, 1920, 1440, 70, TRUE},
+ {4, 1920, 1440, 75, TRUE}, {5, 1920, 1440, 85, TRUE}, {6, 1920, 1440, 100, TRUE},
+ {1, 2048, 1536, 60, TRUE}, {2, 2048, 1536, 65, TRUE}, {3, 2048, 1536, 70, TRUE},
+ {4, 2048, 1536, 75, TRUE}, {5, 2048, 1536, 85, TRUE},
+ {0, 0, 0, 0, FALSE}
+};
+
+/* TW: Some 300-series laptops have a badly designed BIOS and make it
+ * impossible to detect the correct panel delay compensation. This
+ * table used to detect such machines by their PCI subsystem IDs;
+ * however, I don't know how reliable this method is. (With Asus
+ * machines, it is to general, ASUS uses the same ID for different
+ * boxes)
+ */
+static const pdctable mypdctable[] = {
+ { 0x1071, 0x7522, 32, "Mitac", "7521T" },
+ { 0, 0, 0, "" , "" }
+};
+
+static const chswtable mychswtable[] = {
+ { 0x1631, 0x1002, "Mitachi", "0x1002" },
+ { 0, 0, "" , "" }
+};
+
+/* TW: Our TV modes for the 6326. The data in these structures
+ * is mainly correct, but since we use our private CR and
+ * clock values anyway, small errors do no matter.
+ */
+static DisplayModeRec SiS6326PAL800x600Mode = {
+ NULL, NULL, /* prev, next */
+ "PAL800x600", /* identifier of this mode */
+ MODE_OK, /* mode status */
+ M_T_BUILTIN, /* mode type */
+ 36000, /* Clock frequency */
+ 800, /* HDisplay */
+ 848, /* HSyncStart */
+ 912, /* HSyncEnd */
+ 1008, /* HTotal */
+ 0, /* HSkew */
+ 600, /* VDisplay */
+ 600, /* VSyncStart */
+ 602, /* VSyncEnd */
+ 625, /* VTotal */
+ 0, /* VScan */
+ V_PHSYNC | V_PVSYNC, /* Flags */
+ -1, /* ClockIndex */
+ 36000, /* SynthClock */
+ 800, /* CRTC HDisplay */
+ 808, /* CRTC HBlankStart */
+ 848, /* CRTC HSyncStart */
+ 912, /* CRTC HSyncEnd */
+ 1008, /* CRTC HBlankEnd */
+ 1008, /* CRTC HTotal */
+ 0, /* CRTC HSkew */
+ 600, /* CRTC VDisplay */
+ 600, /* CRTC VBlankStart */
+ 600, /* CRTC VSyncStart */
+ 602, /* CRTC VSyncEnd */
+ 625, /* CRTC VBlankEnd */
+ 625, /* CRTC VTotal */
+ FALSE, /* CrtcHAdjusted */
+ FALSE, /* CrtcVAdjusted */
+ 0, /* PrivSize */
+ NULL, /* Private */
+ 0.0, /* HSync */
+ 0.0 /* VRefresh */
+};
+
+/* TW: Due to the scaling method this mode uses, the vertical data here
+ * does not match the CR data. But this does not matter, we use our
+ * private CR data anyway.
+ */
+static DisplayModeRec SiS6326PAL800x600UMode = {
+ NULL, /* prev */
+ &SiS6326PAL800x600Mode, /* next */
+ "PAL800x600U", /* identifier of this mode */
+ MODE_OK, /* mode status */
+ M_T_BUILTIN, /* mode type */
+ 37120, /* Clock frequency */
+ 800, /* HDisplay */
+ 872, /* HSyncStart */
+ 984, /* HSyncEnd */
+ 1088, /* HTotal */
+ 0, /* HSkew */
+ 600, /* VDisplay (548 due to scaling) */
+ 600, /* VSyncStart (584) */
+ 602, /* VSyncEnd (586) */
+ 625, /* VTotal */
+ 0, /* VScan */
+ V_PHSYNC | V_PVSYNC, /* Flags */
+ -1, /* ClockIndex */
+ 37120, /* SynthClock */
+ 800, /* CRTC HDisplay */
+ 808, /* CRTC HBlankStart */
+ 872, /* CRTC HSyncStart */
+ 984, /* CRTC HSyncEnd */
+ 1024, /* CRTC HBlankEnd */
+ 1088, /* CRTC HTotal */
+ 0, /* CRTC HSkew */
+ 600, /* CRTC VDisplay (548 due to scaling) */
+ 600, /* CRTC VBlankStart (600) */
+ 600, /* CRTC VSyncStart (584) */
+ 602, /* CRTC VSyncEnd (586) */
+ 625, /* CRTC VBlankEnd */
+ 625, /* CRTC VTotal */
+ FALSE, /* CrtcHAdjusted */
+ FALSE, /* CrtcVAdjusted */
+ 0, /* PrivSize */
+ NULL, /* Private */
+ 0.0, /* HSync */
+ 0.0 /* VRefresh */
+};
+
+static DisplayModeRec SiS6326PAL720x540Mode = {
+ NULL, /* prev */
+ &SiS6326PAL800x600UMode, /* next */
+ "PAL720x540", /* identifier of this mode */
+ MODE_OK, /* mode status */
+ M_T_BUILTIN, /* mode type */
+ 36000, /* Clock frequency */
+ 720, /* HDisplay */
+ 816, /* HSyncStart */
+ 920, /* HSyncEnd */
+ 1008, /* HTotal */
+ 0, /* HSkew */
+ 540, /* VDisplay */
+ 578, /* VSyncStart */
+ 580, /* VSyncEnd */
+ 625, /* VTotal */
+ 0, /* VScan */
+ V_PHSYNC | V_PVSYNC, /* Flags */
+ -1, /* ClockIndex */
+ 36000, /* SynthClock */
+ 720, /* CRTC HDisplay */
+ 736, /* CRTC HBlankStart */
+ 816, /* CRTC HSyncStart */
+ 920, /* CRTC HSyncEnd */
+ 1008, /* CRTC HBlankEnd */
+ 1008, /* CRTC HTotal */
+ 0, /* CRTC HSkew */
+ 540, /* CRTC VDisplay */
+ 577, /* CRTC VBlankStart */
+ 578, /* CRTC VSyncStart */
+ 580, /* CRTC VSyncEnd */
+ 625, /* CRTC VBlankEnd */
+ 625, /* CRTC VTotal */
+ FALSE, /* CrtcHAdjusted */
+ FALSE, /* CrtcVAdjusted */
+ 0, /* PrivSize */
+ NULL, /* Private */
+ 0.0, /* HSync */
+ 0.0 /* VRefresh */
+};
+
+static DisplayModeRec SiS6326PAL640x480Mode = {
+ NULL, /* prev */
+ &SiS6326PAL720x540Mode, /* next */
+ "PAL640x480", /* identifier of this mode */
+ MODE_OK, /* mode status */
+ M_T_BUILTIN, /* mode type */
+ 36000, /* Clock frequency */
+ 640, /* HDisplay */
+ 768, /* HSyncStart */
+ 920, /* HSyncEnd */
+ 1008, /* HTotal */
+ 0, /* HSkew */
+ 480, /* VDisplay */
+ 532, /* VSyncStart */
+ 534, /* VSyncEnd */
+ 625, /* VTotal */
+ 0, /* VScan */
+ V_NHSYNC | V_NVSYNC, /* Flags */
+ -1, /* ClockIndex */
+ 36000, /* SynthClock */
+ 640, /* CRTC HDisplay */
+ 648, /* CRTC HBlankStart */
+ 768, /* CRTC HSyncStart */
+ 920, /* CRTC HSyncEnd */
+ 944, /* CRTC HBlankEnd */
+ 1008, /* CRTC HTotal */
+ 0, /* CRTC HSkew */
+ 480, /* CRTC VDisplay */
+ 481, /* CRTC VBlankStart */
+ 532, /* CRTC VSyncStart */
+ 534, /* CRTC VSyncEnd */
+ 561, /* CRTC VBlankEnd */
+ 625, /* CRTC VTotal */
+ FALSE, /* CrtcHAdjusted */
+ FALSE, /* CrtcVAdjusted */
+ 0, /* PrivSize */
+ NULL, /* Private */
+ 0.0, /* HSync */
+ 0.0 /* VRefresh */
+};
+
+static DisplayModeRec SiS6326NTSC640x480Mode = {
+ NULL, NULL, /* prev, next */
+ "NTSC640x480", /* identifier of this mode */
+ MODE_OK, /* mode status */
+ M_T_BUILTIN, /* mode type */
+ 27000, /* Clock frequency */
+ 640, /* HDisplay */
+ 664, /* HSyncStart */
+ 760, /* HSyncEnd */
+ 800, /* HTotal */
+ 0, /* HSkew */
+ 480, /* VDisplay */
+ 489, /* VSyncStart */
+ 491, /* VSyncEnd */
+ 525, /* VTotal */
+ 0, /* VScan */
+ V_NHSYNC | V_NVSYNC, /* Flags */
+ -1, /* ClockIndex */
+ 27000, /* SynthClock */
+ 640, /* CRTC HDisplay */
+ 648, /* CRTC HBlankStart */
+ 664, /* CRTC HSyncStart */
+ 760, /* CRTC HSyncEnd */
+ 792, /* CRTC HBlankEnd */
+ 800, /* CRTC HTotal */
+ 0, /* CRTC HSkew */
+ 480, /* CRTC VDisplay */
+ 488, /* CRTC VBlankStart */
+ 489, /* CRTC VSyncStart */
+ 491, /* CRTC VSyncEnd */
+ 517, /* CRTC VBlankEnd */
+ 525, /* CRTC VTotal */
+ FALSE, /* CrtcHAdjusted */
+ FALSE, /* CrtcVAdjusted */
+ 0, /* PrivSize */
+ NULL, /* Private */
+ 0.0, /* HSync */
+ 0.0 /* VRefresh */
+};
+
+/* TW: Due to the scaling method this mode uses, the vertical data here
+ * does not match the CR data. But this does not matter, we use our
+ * private CR data anyway.
+ */
+static DisplayModeRec SiS6326NTSC640x480UMode = {
+ NULL, /* prev */
+ &SiS6326NTSC640x480Mode, /* next */
+ "NTSC640x480U", /* identifier of this mode */
+ MODE_OK, /* mode status */
+ M_T_BUILTIN, /* mode type */
+ 32215, /* Clock frequency */
+ 640, /* HDisplay */
+ 696, /* HSyncStart */
+ 840, /* HSyncEnd */
+ 856, /* HTotal */
+ 0, /* HSkew */
+ 480, /* VDisplay (439 due to scaling) */
+ 489, /* VSyncStart (473) */
+ 491, /* VSyncEnd (475) */
+ 525, /* VTotal */
+ 0, /* VScan */
+ V_NHSYNC | V_NVSYNC, /* Flags */
+ -1, /* ClockIndex */
+ 32215, /* SynthClock */
+ 640, /* CRTC HDisplay */
+ 656, /* CRTC HBlankStart */
+ 696, /* CRTC HSyncStart */
+ 840, /* CRTC HSyncEnd */
+ 856, /* CRTC HBlankEnd */
+ 856, /* CRTC HTotal */
+ 0, /* CRTC HSkew */
+ 480, /* CRTC VDisplay */
+ 488, /* CRTC VBlankStart */
+ 489, /* CRTC VSyncStart */
+ 491, /* CRTC VSyncEnd */
+ 517, /* CRTC VBlankEnd */
+ 525, /* CRTC VTotal */
+ FALSE, /* CrtcHAdjusted */
+ FALSE, /* CrtcVAdjusted */
+ 0, /* PrivSize */
+ NULL, /* Private */
+ 0.0, /* HSync */
+ 0.0 /* VRefresh */
+};
+
+
+static DisplayModeRec SiS6326NTSC640x400Mode = {
+ NULL, /* prev */
+ &SiS6326NTSC640x480UMode, /* next */
+ "NTSC640x400", /* identifier of this mode */
+ MODE_OK, /* mode status */
+ M_T_BUILTIN, /* mode type */
+ 27000, /* Clock frequency */
+ 640, /* HDisplay */
+ 664, /* HSyncStart */
+ 760, /* HSyncEnd */
+ 800, /* HTotal */
+ 0, /* HSkew */
+ 400, /* VDisplay */
+ 459, /* VSyncStart */
+ 461, /* VSyncEnd */
+ 525, /* VTotal */
+ 0, /* VScan */
+ V_NHSYNC | V_NVSYNC, /* Flags */
+ -1, /* ClockIndex */
+ 27000, /* SynthClock */
+ 640, /* CRTC HDisplay */
+ 648, /* CRTC HBlankStart */
+ 664, /* CRTC HSyncStart */
+ 760, /* CRTC HSyncEnd */
+ 792, /* CRTC HBlankEnd */
+ 800, /* CRTC HTotal */
+ 0, /* CRTC HSkew */
+ 400, /* CRTC VDisplay */
+ 407, /* CRTC VBlankStart */
+ 459, /* CRTC VSyncStart */
+ 461, /* CRTC VSyncEnd */
+ 490, /* CRTC VBlankEnd */
+ 525, /* CRTC VTotal */
+ FALSE, /* CrtcHAdjusted */
+ FALSE, /* CrtcVAdjusted */
+ 0, /* PrivSize */
+ NULL, /* Private */
+ 0.0, /* HSync */
+ 0.0 /* VRefresh */
+};
+
+/* TW: Built-in hi-res modes for the 6326.
+ * For some reason, our default mode lines and the
+ * clock calculation functions in sis_dac.c do no
+ * good job on higher clocks. It seems, the hardware
+ * needs some tricks so make mode with higher clock
+ * rates than ca. 120MHz work. I didn't bother trying
+ * to find out what exactly is going wrong, so I
+ * implemented two special modes instead for 1280x1024
+ * and 1600x1200. These two are automatically added
+ * to the list if they are supported with the current
+ * depth.
+ * The data in the strucures below is a proximation,
+ * in sis_vga.c the register contents are fetched from
+ * fixed tables anyway.
+ */
+static DisplayModeRec SiS6326SIS1280x1024_75Mode = {
+ NULL, /* prev */
+ NULL, /* next */
+ "SIS1280x1024-75", /* identifier of this mode */
+ MODE_OK, /* mode status */
+ M_T_BUILTIN, /* mode type */
+ 135000, /* Clock frequency */
+ 1280, /* HDisplay */
+ 1296, /* HSyncStart */
+ 1440, /* HSyncEnd */
+ 1688, /* HTotal */
+ 0, /* HSkew */
+ 1024, /* VDisplay */
+ 1025, /* VSyncStart */
+ 1028, /* VSyncEnd */
+ 1066, /* VTotal */
+ 0, /* VScan */
+ V_PHSYNC | V_PVSYNC, /* Flags */
+ -1, /* ClockIndex */
+ 135000, /* SynthClock */
+ 1280, /* CRTC HDisplay */
+ 1280, /* CRTC HBlankStart */
+ 1296, /* CRTC HSyncStart */
+ 1440, /* CRTC HSyncEnd */
+ 1680, /* CRTC HBlankEnd */
+ 1688, /* CRTC HTotal */
+ 0, /* CRTC HSkew */
+ 1024, /* CRTC VDisplay */
+ 1024, /* CRTC VBlankStart */
+ 1025, /* CRTC VSyncStart */
+ 1028, /* CRTC VSyncEnd */
+ 1065, /* CRTC VBlankEnd */
+ 1066, /* CRTC VTotal */
+ FALSE, /* CrtcHAdjusted */
+ FALSE, /* CrtcVAdjusted */
+ 0, /* PrivSize */
+ NULL, /* Private */
+ 0.0, /* HSync */
+ 0.0 /* VRefresh */
+};
+
+static DisplayModeRec SiS6326SIS1600x1200_60Mode = {
+ NULL, /* prev */
+ NULL, /* next */
+ "SIS1600x1200-60", /* identifier of this mode */
+ MODE_OK, /* mode status */
+ M_T_BUILTIN, /* mode type */
+ 162000, /* Clock frequency */
+ 1600, /* HDisplay */
+ 1664, /* HSyncStart */
+ 1856, /* HSyncEnd */
+ 2160, /* HTotal */
+ 0, /* HSkew */
+ 1200, /* VDisplay */
+ 1201, /* VSyncStart */
+ 1204, /* VSyncEnd */
+ 1250, /* VTotal */
+ 0, /* VScan */
+ V_PHSYNC | V_PVSYNC, /* Flags */
+ -1, /* ClockIndex */
+ 162000, /* SynthClock */
+ 1600, /* CRTC HDisplay */
+ 1600, /* CRTC HBlankStart */
+ 1664, /* CRTC HSyncStart */
+ 1856, /* CRTC HSyncEnd */
+ 2152, /* CRTC HBlankEnd */
+ 2160, /* CRTC HTotal */
+ 0, /* CRTC HSkew */
+ 1200, /* CRTC VDisplay */
+ 1200, /* CRTC VBlankStart */
+ 1201, /* CRTC VSyncStart */
+ 1204, /* CRTC VSyncEnd */
+ 1249, /* CRTC VBlankEnd */
+ 1250, /* CRTC VTotal */
+ FALSE, /* CrtcHAdjusted */
+ FALSE, /* CrtcVAdjusted */
+ 0, /* PrivSize */
+ NULL, /* Private */
+ 0.0, /* HSync */
+ 0.0 /* VRefresh */
+};
+
diff --git a/src/sis_opt.c b/src/sis_opt.c
new file mode 100644
index 0000000..bd8be86
--- /dev/null
+++ b/src/sis_opt.c
@@ -0,0 +1,774 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_opt.c,v 1.15 2003/02/04 02:44:29 dawes Exp $ */
+/*
+ *
+ * SiS driver option evaluation
+ *
+ * Parts Copyright 2001, 2002 by Thomas Winischhofer, Vienna, Austria
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the supplier not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The supplier makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE SUPPLIER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: ?
+ * Thomas Winischhofer <thomas@winischhofer.net>
+ */
+
+#include "xf86.h"
+#include "xf86PciInfo.h"
+#include "xf86str.h"
+#include "xf86Cursor.h"
+
+#include "sis.h"
+
+typedef enum {
+ OPTION_SW_CURSOR,
+ OPTION_HW_CURSOR,
+/* OPTION_PCI_RETRY, */
+ OPTION_NOACCEL,
+ OPTION_TURBOQUEUE,
+ OPTION_FAST_VRAM,
+ OPTION_NOHOSTBUS,
+/* OPTION_SET_MEMCLOCK, */
+ OPTION_FORCE_CRT2TYPE,
+ OPTION_SHADOW_FB,
+ OPTION_ROTATE,
+ OPTION_NOXVIDEO,
+ OPTION_VESA,
+ OPTION_MAXXFBMEM,
+ OPTION_FORCECRT1,
+ OPTION_DSTN,
+ OPTION_XVONCRT2,
+ OPTION_PDC,
+ OPTION_TVSTANDARD,
+ OPTION_USEROMDATA,
+ OPTION_NOINTERNALMODES,
+ OPTION_USEOEM,
+ OPTION_SBIOSN,
+ OPTION_NOYV12,
+ OPTION_CHTVOVERSCAN,
+ OPTION_CHTVSOVERSCAN,
+ OPTION_CHTVLUMABANDWIDTHCVBS,
+ OPTION_CHTVLUMABANDWIDTHSVIDEO,
+ OPTION_CHTVLUMAFLICKERFILTER,
+ OPTION_CHTVCHROMABANDWIDTH,
+ OPTION_CHTVCHROMAFLICKERFILTER,
+ OPTION_CHTVCVBSCOLOR,
+ OPTION_CHTVTEXTENHANCE,
+ OPTION_CHTVCONTRAST,
+ OPTION_SISTVEDGEENHANCE,
+ OPTION_SISTVANTIFLICKER,
+ OPTION_SISTVSATURATION,
+ OPTION_TVXPOSOFFSET,
+ OPTION_TVYPOSOFFSET,
+ OPTION_SIS6326ANTIFLICKER,
+ OPTION_SIS6326ENABLEYFILTER,
+ OPTION_SIS6326YFILTERSTRONG,
+ OPTION_CHTVTYPE,
+ OPTION_USERGBCURSOR,
+ OPTION_USERGBCURSORBLEND,
+ OPTION_USERGBCURSORBLENDTH,
+ OPTION_RESTOREBYSET
+} SISOpts;
+
+static const OptionInfoRec SISOptions[] = {
+ { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE },
+/* { OPTION_PCI_RETRY, "PciRetry", OPTV_BOOLEAN, {0}, FALSE }, */
+ { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_TURBOQUEUE, "TurboQueue", OPTV_BOOLEAN, {0}, FALSE },
+/* { OPTION_SET_MEMCLOCK, "SetMClk", OPTV_FREQ, {0}, -1 }, */
+ { OPTION_FAST_VRAM, "FastVram", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_NOHOSTBUS, "NoHostBus", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_FORCE_CRT2TYPE, "ForceCRT2Type", OPTV_ANYSTR, {0}, FALSE },
+ { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE },
+ { OPTION_NOXVIDEO, "NoXvideo", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_VESA, "Vesa", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_MAXXFBMEM, "MaxXFBMem", OPTV_INTEGER, {0}, -1 },
+ { OPTION_FORCECRT1, "ForceCRT1", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_DSTN, "DSTN", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_XVONCRT2, "XvOnCRT2", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_PDC, "PanelDelayCompensation", OPTV_INTEGER, {0}, -1 },
+ { OPTION_TVSTANDARD, "TVStandard", OPTV_STRING, {0}, -1 },
+ { OPTION_USEROMDATA, "UseROMData", OPTV_BOOLEAN, {0}, -1 },
+ { OPTION_NOINTERNALMODES, "NoInternalModes", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_USEOEM, "UseOEMData", OPTV_BOOLEAN, {0}, -1 },
+ { OPTION_SBIOSN, "BIOSFile", OPTV_STRING, {0}, FALSE },
+ { OPTION_NOYV12, "NoYV12", OPTV_BOOLEAN, {0}, -1 },
+ { OPTION_CHTVTYPE, "CHTVType", OPTV_BOOLEAN, {0}, -1 },
+ { OPTION_CHTVOVERSCAN, "CHTVOverscan", OPTV_BOOLEAN, {0}, -1 },
+ { OPTION_CHTVSOVERSCAN, "CHTVSuperOverscan", OPTV_BOOLEAN, {0}, -1 },
+ { OPTION_CHTVLUMABANDWIDTHCVBS, "CHTVLumaBandwidthCVBS", OPTV_INTEGER, {0}, -1 },
+ { OPTION_CHTVLUMABANDWIDTHSVIDEO, "CHTVLumaBandwidthSVIDEO",OPTV_INTEGER, {0}, -1 },
+ { OPTION_CHTVLUMAFLICKERFILTER, "CHTVLumaFlickerFilter", OPTV_INTEGER, {0}, -1 },
+ { OPTION_CHTVCHROMABANDWIDTH, "CHTVChromaBandwidth", OPTV_INTEGER, {0}, -1 },
+ { OPTION_CHTVCHROMAFLICKERFILTER, "CHTVChromaFlickerFilter",OPTV_INTEGER, {0}, -1 },
+ { OPTION_CHTVCVBSCOLOR, "CHTVCVBSColor", OPTV_BOOLEAN, {0}, -1 },
+ { OPTION_CHTVTEXTENHANCE, "CHTVTextEnhance", OPTV_INTEGER, {0}, -1 },
+ { OPTION_CHTVCONTRAST, "CHTVContrast", OPTV_INTEGER, {0}, -1 },
+ { OPTION_SISTVEDGEENHANCE, "SISTVEdgeEnhance", OPTV_INTEGER, {0}, -1 },
+ { OPTION_SISTVANTIFLICKER, "SISTVAntiFlicker", OPTV_INTEGER, {0}, -1 },
+ { OPTION_SISTVSATURATION, "SISTVSaturation", OPTV_INTEGER, {0}, -1 },
+ { OPTION_TVXPOSOFFSET, "TVXPosOffset", OPTV_INTEGER, {0}, -1 },
+ { OPTION_TVYPOSOFFSET, "TVYPosOffset", OPTV_INTEGER, {0}, -1 },
+ { OPTION_SIS6326ANTIFLICKER, "SIS6326TVAntiFlicker", OPTV_STRING, {0}, FALSE },
+ { OPTION_SIS6326ENABLEYFILTER, "SIS6326TVEnableYFilter", OPTV_BOOLEAN, {0}, -1 },
+ { OPTION_SIS6326YFILTERSTRONG, "SIS6326TVYFilterStrong", OPTV_BOOLEAN, {0}, -1 },
+ { OPTION_USERGBCURSOR, "UseColorHWCursor", OPTV_BOOLEAN, {0}, -1 },
+ { OPTION_USERGBCURSORBLEND, "ColorHWCursorBlending", OPTV_BOOLEAN, {0}, -1 },
+ { OPTION_USERGBCURSORBLENDTH, "ColorHWCursorBlendThreshold", OPTV_INTEGER, {0}, -1 },
+ { OPTION_RESTOREBYSET, "RestoreBySetMode", OPTV_BOOLEAN, {0}, -1 },
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
+};
+
+void
+SiSOptions(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ MessageType from;
+/* double temp; */
+ char *strptr;
+
+ /* Collect all of the relevant option flags (fill in pScrn->options) */
+ xf86CollectOptions(pScrn, NULL);
+
+ /* Process the options */
+ if (!(pSiS->Options = xalloc(sizeof(SISOptions))))
+ return;
+
+ memcpy(pSiS->Options, SISOptions, sizeof(SISOptions));
+
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pSiS->Options);
+
+ /* initalize some defaults */
+ pSiS->newFastVram = -1; /* TW: Default: write only; if set, read + write */
+ pSiS->NoHostBus = FALSE;
+/* pSiS->UsePCIRetry = TRUE; */
+ pSiS->TurboQueue = TRUE;
+ pSiS->HWCursor = TRUE;
+ pSiS->Rotate = FALSE;
+ pSiS->ShadowFB = FALSE;
+ pSiS->VESA = -1;
+ pSiS->NoXvideo = FALSE;
+ pSiS->maxxfbmem = 0;
+ pSiS->forceCRT1 = -1;
+ pSiS->DSTN = FALSE; /* TW: For using 550 FSTN/DSTN registers */
+ pSiS->XvOnCRT2 = FALSE; /* TW: For chipsets with only one overlay */
+ pSiS->NoYV12 = -1;
+ pSiS->PDC = -1; /* TW: Panel Delay Compensation for 300 (and 310/325) series */
+ pSiS->OptTVStand = -1;
+ pSiS->OptROMUsage = -1;
+ pSiS->noInternalModes = FALSE;
+ pSiS->OptUseOEM = -1;
+ pSiS->OptTVOver = -1;
+ pSiS->OptTVSOver = -1;
+ pSiS->chtvlumabandwidthcvbs = -1; /* TW: Chrontel TV settings */
+ pSiS->chtvlumabandwidthsvideo = -1;
+ pSiS->chtvlumaflickerfilter = -1;
+ pSiS->chtvchromabandwidth = -1;
+ pSiS->chtvchromaflickerfilter = -1;
+ pSiS->chtvcvbscolor = -1;
+ pSiS->chtvtextenhance = -1;
+ pSiS->chtvcontrast = -1;
+ pSiS->sistvedgeenhance = -1; /* TW: SiS30x TV settings */
+ pSiS->sistvantiflicker = -1;
+ pSiS->sistvsaturation = -1;
+ pSiS->sis6326antiflicker = -1; /* TW: SiS6326 TV settings */
+ pSiS->sis6326enableyfilter = -1;
+ pSiS->sis6326yfilterstrong = -1;
+ pSiS->tvxpos = 0; /* TW: Some day hopefully general TV settings */
+ pSiS->tvypos = 0;
+ pSiS->NonDefaultPAL = -1;
+ pSiS->chtvtype = -1;
+#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,99,0,0)
+ pSiS->OptUseColorCursor = 0;
+#else
+ if(pSiS->VGAEngine == SIS_300_VGA) {
+ pSiS->OptUseColorCursor = 0;
+ pSiS->OptUseColorCursorBlend = 1;
+ pSiS->OptColorCursorBlendThreshold = 0x37000000;
+ } else if(pSiS->VGAEngine == SIS_315_VGA) {
+ pSiS->OptUseColorCursor = 1;
+ }
+#endif
+ pSiS->restorebyset = 0;
+
+ if(pSiS->Chipset == PCI_CHIP_SIS530) {
+ /* TW: TQ still broken on 530/620? */
+ pSiS->TurboQueue = FALSE;
+ }
+
+ /* sw/hw cursor */
+ from = X_DEFAULT;
+ if(xf86GetOptValBool(pSiS->Options, OPTION_HW_CURSOR, &pSiS->HWCursor)) {
+ from = X_CONFIG;
+ }
+ if(xf86ReturnOptValBool(pSiS->Options, OPTION_SW_CURSOR, FALSE)) {
+ from = X_CONFIG;
+ pSiS->HWCursor = FALSE;
+ pSiS->OptUseColorCursor = 0;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
+ pSiS->HWCursor ? "HW" : "SW");
+
+#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,99,0,0)
+#ifdef ARGB_CURSOR
+#ifdef SIS_ARGB_CURSOR
+ if((pSiS->HWCursor) && ((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA))) {
+ from = X_DEFAULT;
+ if(xf86GetOptValBool(pSiS->Options, OPTION_USERGBCURSOR, &pSiS->OptUseColorCursor)) {
+ from = X_CONFIG;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Color HW cursor is %s\n",
+ pSiS->OptUseColorCursor ? "enabled" : "disabled");
+
+ if(pSiS->VGAEngine == SIS_300_VGA) {
+ from = X_DEFAULT;
+ if(xf86GetOptValBool(pSiS->Options, OPTION_USERGBCURSORBLEND, &pSiS->OptUseColorCursorBlend)) {
+ from = X_CONFIG;
+ }
+ if(pSiS->OptUseColorCursor) {
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "HW cursor color blending emulation is %s\n",
+ (pSiS->OptUseColorCursorBlend) ? "enabled" : "disabled");
+ }
+ {
+ int temp;
+ from = X_DEFAULT;
+ if(xf86GetOptValInteger(pSiS->Options, OPTION_USERGBCURSORBLENDTH, &temp)) {
+ if((temp >= 0) && (temp <= 255)) {
+ from = X_CONFIG;
+ pSiS->OptColorCursorBlendThreshold = (temp << 24);
+ } else {
+ temp = pSiS->OptColorCursorBlendThreshold >> 24;
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Illegal color HW cursor blending threshold, valid range 0-255\n");
+ }
+ }
+ if(pSiS->OptUseColorCursor) {
+ if(pSiS->OptUseColorCursorBlend) {
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "HW cursor color blending emulation threshold is %d\n", temp);
+ }
+ }
+ }
+ }
+ }
+#endif
+#endif
+#endif
+
+ /* Accel */
+ if(xf86ReturnOptValBool(pSiS->Options, OPTION_NOACCEL, FALSE)) {
+ pSiS->NoAccel = TRUE;
+ pSiS->NoXvideo = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration and Xv disabled\n");
+ }
+
+#if 0
+ /* PCI retry - TW: What the heck is/was this for? */
+ from = X_DEFAULT;
+ if(xf86GetOptValBool(pSiS->Options, OPTION_PCI_RETRY, &pSiS->UsePCIRetry)) {
+ from = X_CONFIG;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "PCI retry %s\n",
+ pSiS->UsePCIRetry ? "enabled" : "disabled");
+#endif
+
+ /* Mem clock */
+#if 0 /* TW: This is not used */
+ if(xf86GetOptValFreq(pSiS->Options, OPTION_SET_MEMCLOCK, OPTUNITS_MHZ,
+ &temp)) {
+ pSiS->MemClock = (int)(temp * 1000.0);
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Memory clock set to %.3f MHz\n", pSiS->MemClock/1000.0);
+ }
+#endif
+
+ /* Fast VRAM (not for 300/310/325 series) */
+ if((pSiS->VGAEngine != SIS_300_VGA) && (pSiS->VGAEngine != SIS_315_VGA)) {
+ from = X_DEFAULT;
+ if(xf86GetOptValBool(pSiS->Options, OPTION_FAST_VRAM, &pSiS->newFastVram)) {
+ from = X_CONFIG;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Fast VRAM %s\n",
+ (pSiS->newFastVram == -1) ? "enabled (for write only)" :
+ (pSiS->newFastVram ? "enabled (for read and write)" : "disabled"));
+ }
+
+ /* NoHostBus (5597/5598 only) */
+ if((pSiS->Chipset == PCI_CHIP_SIS5597)) {
+ from = X_DEFAULT;
+ if(xf86GetOptValBool(pSiS->Options, OPTION_NOHOSTBUS, &pSiS->NoHostBus)) {
+ from = X_CONFIG;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "SiS5597/5598 VGA-to-CPU host bus %s\n",
+ pSiS->NoHostBus ? "disabled" : "enabled");
+ }
+
+ if(pSiS->VGAEngine != SIS_315_VGA) {
+ /* Turbo QUEUE */
+ /* (TW: We always use this on 310/325 series) */
+ from = X_DEFAULT;
+ if(xf86GetOptValBool(pSiS->Options, OPTION_TURBOQUEUE, &pSiS->TurboQueue)) {
+ from = X_CONFIG;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "TurboQueue %s\n",
+ pSiS->TurboQueue ? "enabled" : "disabled");
+ }
+
+ /* Force CRT2 type (300/310/325 series only)
+ TW: SVIDEO, COMPOSITE and SCART for overriding detection
+ */
+ pSiS->ForceCRT2Type = CRT2_DEFAULT;
+ pSiS->ForceTVType = -1;
+ if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
+ strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_FORCE_CRT2TYPE);
+ if(strptr != NULL) {
+ if((!strcmp(strptr,"TV")) || (!strcmp(strptr,"tv")))
+ pSiS->ForceCRT2Type = CRT2_TV;
+ else if((!strcmp(strptr,"SVIDEO")) || (!strcmp(strptr,"svideo"))) {
+ pSiS->ForceCRT2Type = CRT2_TV;
+ pSiS->ForceTVType = TV_SVIDEO;
+ } else if((!strcmp(strptr,"COMPOSITE")) || (!strcmp(strptr,"composite"))) {
+ pSiS->ForceCRT2Type = CRT2_TV;
+ pSiS->ForceTVType = TV_AVIDEO;
+ } else if((!strcmp(strptr,"SCART")) || (!strcmp(strptr,"scart"))) {
+ pSiS->ForceCRT2Type = CRT2_TV;
+ pSiS->ForceTVType = TV_SCART;
+ } else if((!strcmp(strptr,"LCD")) || (!strcmp(strptr,"lcd")))
+ pSiS->ForceCRT2Type = CRT2_LCD;
+ else if((!strcmp(strptr,"DVI")) || (!strcmp(strptr,"dvi")))
+ pSiS->ForceCRT2Type = CRT2_LCD;
+ else if((!strcmp(strptr,"VGA")) || (!strcmp(strptr,"vga")))
+ pSiS->ForceCRT2Type = CRT2_VGA;
+ else if((!strcmp(strptr,"NONE")) || (!strcmp(strptr,"none")))
+ pSiS->ForceCRT2Type = 0;
+ else {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "\"%s\" is not a valid parameter for Option \"ForceCRT2Type\"\n", strptr);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Valid parameters are \"LCD\" (alias \"DVI\"), \"TV\", \"SVIDEO\", \"COMPOSITE\", \"SCART\", \"VGA\" or \"NONE\"\n");
+ }
+
+ if(pSiS->ForceCRT2Type != CRT2_DEFAULT)
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "CRT2 type shall be %s\n", strptr);
+ }
+ strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_CHTVTYPE);
+ if(strptr != NULL) {
+ if((!strcmp(strptr,"SCART")) || (!strcmp(strptr,"scart")))
+ pSiS->chtvtype = 1;
+ else if((!strcmp(strptr,"HDTV")) || (!strcmp(strptr,"hdtv")))
+ pSiS->chtvtype = 0;
+ else {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "\"%s\" is not a valid parameter for Option \"CHTVType\"\n", strptr);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Valid parameters are \"SCART\" or \"HDTV\"\n");
+ }
+ if(pSiS->chtvtype != -1)
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Chrontel TV type shall be %s\n", strptr);
+ }
+ }
+
+ /* ShadowFB */
+ from = X_DEFAULT;
+ if(xf86GetOptValBool(pSiS->Options, OPTION_SHADOW_FB, &pSiS->ShadowFB)) {
+ from = X_CONFIG;
+ }
+ if(pSiS->ShadowFB) {
+ pSiS->NoAccel = TRUE;
+ pSiS->NoXvideo = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "Using \"Shadow Frame Buffer\" - acceleration and Xv disabled\n");
+ }
+
+ /* Rotate */
+ if((strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_ROTATE))) {
+ if(!xf86NameCmp(strptr, "CW")) {
+ pSiS->ShadowFB = TRUE;
+ pSiS->NoAccel = TRUE;
+ pSiS->NoXvideo = TRUE;
+ pSiS->HWCursor = FALSE;
+ pSiS->Rotate = 1;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Rotating screen clockwise (acceleration and Xv disabled)\n");
+ } else
+ if(!xf86NameCmp(strptr, "CCW")) {
+ pSiS->ShadowFB = TRUE;
+ pSiS->NoAccel = TRUE;
+ pSiS->NoXvideo = TRUE;
+ pSiS->HWCursor = FALSE;
+ pSiS->Rotate = -1;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Rotating screen counter clockwise (acceleration and Xv disabled)\n");
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "\"%s\" is not a valid parameter for Option \"Rotate\"\n", strptr);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Valid parameters are \"CW\" or \"CCW\"\n");
+ }
+ }
+
+ /* RestoreBySetMode */
+ /* TW: Set this to force the driver to set the old mode instead of restoring
+ * the register contents. This can be used to overcome problems with
+ * LCD panels and video bridges.
+ */
+ if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
+ Bool val;
+ if(xf86GetOptValBool(pSiS->Options, OPTION_RESTOREBYSET, &val)) {
+ if(val) pSiS->restorebyset = TRUE;
+ else pSiS->restorebyset = FALSE;
+ }
+ }
+
+ /* NOXvideo:
+ * Set this to TRUE to disable Xv hardware video acceleration
+ */
+ if(!pSiS->NoAccel) {
+ if(xf86ReturnOptValBool(pSiS->Options, OPTION_NOXVIDEO, FALSE)) {
+ pSiS->NoXvideo = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "XVideo extension disabled\n");
+ }
+
+ if(!pSiS->NoXvideo) {
+ Bool val;
+ if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
+ /* TW: XvOnCRT2:
+ * On chipsets with only one overlay (315, 650), the user should
+ * choose to display the overlay on CRT1 or CRT2. By setting this
+ * option to TRUE, the overlay will be displayed on CRT2. The
+ * default is: CRT1 if only CRT1 available, CRT2 if only CRT2
+ * available, and CRT1 if both is available and detected.
+ */
+ if(xf86GetOptValBool(pSiS->Options, OPTION_XVONCRT2, &val)) {
+ if(val) pSiS->XvOnCRT2 = TRUE;
+ else pSiS->XvOnCRT2 = FALSE;
+ }
+ }
+ if((pSiS->VGAEngine == SIS_OLD_VGA) || (pSiS->VGAEngine == SIS_530_VGA)) {
+ /* TW: NoYV12 (for 5597/5598, 6326 and 530/620 only)
+ * YV12 has problems with videos larger than 384x288. So
+ * allow the user to disable YV12 support to force the
+ * application to use YUV2 instead.
+ */
+ if(xf86GetOptValBool(pSiS->Options, OPTION_NOYV12, &val)) {
+ if(val) pSiS->NoYV12 = 1;
+ else pSiS->NoYV12 = 0;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Xv YV12/I420 support is %s\n",
+ pSiS->NoYV12 ? "disabled" : "enabled");
+ }
+ }
+ }
+ }
+
+ /* TW: VESA - DEPRECATED
+ * This option is for forcing the driver to use
+ * the VESA BIOS extension for mode switching.
+ */
+ {
+ Bool val;
+
+ if(xf86GetOptValBool(pSiS->Options, OPTION_VESA, &val)) {
+ if(val) pSiS->VESA = 1;
+ else pSiS->VESA = 0;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "VESA: VESA usage shall be %s\n",
+ val ? "enabled":"disabled");
+ }
+ }
+
+ /* TW: MaxXFBMem
+ * With the option "MaxXFBMem" you can limit the amount of video memory X
+ * uses for screen and off-screen buffers. This option should be used if
+ * you intend to use DRI/DRM. The framebuffer driver required for DRM will
+ * start its memory heap at 12MB if it detects more than 16MB, at 8MB if
+ * between 8 and 16MB are available, otherwise at 4MB. So, if you limit
+ * the amount of memory X uses, you avoid a clash between the framebuffer
+ * driver and X as regards overwriting memory portions of each other.
+ * The amount is to be specified in KB.
+ */
+ if(xf86GetOptValULong(pSiS->Options, OPTION_MAXXFBMEM,
+ &pSiS->maxxfbmem)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "MaxXFBMem: Framebuffer memory shall be limited to %d KB\n",
+ pSiS->maxxfbmem);
+ pSiS->maxxfbmem *= 1024;
+ }
+
+ if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
+ /* TW: ForceCRT1 (300/310/325 series only)
+ * This option can be used to force CRT1 to be switched on/off. Its
+ * intention is mainly for old monitors that can't be detected
+ * automatically. This is only useful on machines with a video bridge.
+ * In normal cases, this option won't be necessary.
+ */
+ Bool val;
+ if(xf86GetOptValBool(pSiS->Options, OPTION_FORCECRT1, &val)) {
+ if(val) pSiS->forceCRT1 = 1;
+ else pSiS->forceCRT1 = 0;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "CRT1 shall be forced to %s\n",
+ val ? "ON" : "OFF");
+ }
+ }
+
+ if(pSiS->Chipset == PCI_CHIP_SIS550) {
+ /* TW: SiS 550 DSTN/FSTN
+ * This is for notifying the driver to use the DSTN registers on 550.
+ * DSTN/FSTN is a special LCD port of the SiS550 (notably not the 551
+ * and 552, which I don't know how to detect) that uses an extended
+ * register range. The only effect of this option is that the driver
+ * saves and restores these registers. DSTN display modes are chosen
+ * by using resultion 320x480x8 or 320x480x16.
+ */
+ if(xf86ReturnOptValBool(pSiS->Options, OPTION_DSTN, FALSE)) {
+ pSiS->DSTN = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "SiS 550 DSTN/FSTN enabled\n");
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "SiS 550 DSTN/FSTN disabled\n");
+ }
+ }
+
+ /* TW: PanelDelayCompensation (300/310/325 series only)
+ * This might be required if the LCD panel shows "small waves".
+ * The parameter is an integer, usually either 4, 32 or 24.
+ * Why this option? Simply because SiS did poor BIOS design.
+ * The PDC value depends on the very LCD panel used in a
+ * particular machine. For most panels, the driver is able
+ * to detect the correct value. However, some panels require
+ * a different setting. The value given must be within the mask 0x3c.
+ */
+ if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
+ if(xf86GetOptValInteger(pSiS->Options, OPTION_PDC, &pSiS->PDC)) {
+ if(pSiS->PDC & ~0x3c) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Illegal PanelDelayCompensation value\n");
+ pSiS->PDC = -1;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Panel delay compensation shall be %d\n",
+ pSiS->PDC);
+ }
+ }
+ }
+
+ /* TW: TVStandard (300/310/325 series and 6326 w/ TV only)
+ * This option is for overriding the autodetection of
+ * the BIOS option for PAL / NTSC
+ */
+ if((pSiS->VGAEngine == SIS_300_VGA) ||
+ (pSiS->VGAEngine == SIS_315_VGA) ||
+ ((pSiS->Chipset == PCI_CHIP_SIS6326) && (pSiS->SiS6326Flags & SIS6326_HASTV))) {
+ strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_TVSTANDARD);
+ if(strptr != NULL) {
+ if((!strcmp(strptr,"PAL")) || (!strcmp(strptr,"pal")))
+ pSiS->OptTVStand = 1;
+ else if((!strcmp(strptr,"PALM")) || (!strcmp(strptr,"palm"))) {
+ pSiS->OptTVStand = 1;
+ pSiS->NonDefaultPAL = 1;
+ } else if((!strcmp(strptr,"PALN")) || (!strcmp(strptr,"paln"))) {
+ pSiS->OptTVStand = 1;
+ pSiS->NonDefaultPAL = 0;
+ } else if((!strcmp(strptr,"NTSC")) || (!strcmp(strptr,"ntsc")))
+ pSiS->OptTVStand = 0;
+ else {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "\"%s\" is not a valid parameter for Option \"TVStandard\"\n", strptr);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Valid options are \"PAL\", \"PALM\", \"PALN\" or \"NTSC\"\n");
+ }
+
+ if(pSiS->OptTVStand != -1) {
+ if(pSiS->Chipset == PCI_CHIP_SIS6326) {
+ pSiS->NonDefaultPAL = -1;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "TV Standard shall be %s\n",
+ pSiS->OptTVStand ? "PAL" : "NTSC");
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "TV Standard shall be %s\n",
+ (pSiS->OptTVStand ?
+ ( (pSiS->NonDefaultPAL == -1) ? "PAL" :
+ ((pSiS->NonDefaultPAL) ? "PALM" : "PALN") )
+ : "NTSC"));
+ }
+ }
+ }
+ }
+
+ /* TW: TVOverscan (300/310/325 series only)
+ * This option is for overriding the BIOS option for
+ * TV Overscan. Some BIOS don't even have such an option.
+ * This is only effective on LVDS+CHRONTEL 70xx systems.
+ */
+ if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
+ Bool val;
+ if(xf86GetOptValBool(pSiS->Options, OPTION_CHTVOVERSCAN, &val)) {
+ if(val) pSiS->OptTVOver = 1;
+ else pSiS->OptTVOver = 0;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Chrontel: TV overscan shall be %s\n",
+ val ? "enabled":"disabled");
+ }
+ if(xf86GetOptValBool(pSiS->Options, OPTION_CHTVSOVERSCAN, &pSiS->OptTVSOver)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Chrontel: TV super overscan shall be %s\n",
+ pSiS->OptTVSOver ? "enabled":"disabled");
+ }
+ }
+
+ /* TW: UseROMData (300/310/325 series only)
+ * This option is enabling/disabling usage of some machine
+ * specific data from the BIOS ROM. This option can - and
+ * should - be used in case the driver makes problems
+ * because SiS changed the location of this data.
+ * TW: NoOEM (300/310/325 series only)
+ * The driver contains quite a lot data for OEM LCD panels
+ * and TV connector specifics which override the defaults.
+ * If this data is incorrect, the TV may lose color and
+ * the LCD panel might show some strange effects. Use this
+ * option to disable the usage of this data.
+ */
+ if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
+ Bool val;
+ if(xf86GetOptValBool(pSiS->Options, OPTION_USEROMDATA, &val)) {
+ if(val) pSiS->OptROMUsage = 1;
+ else pSiS->OptROMUsage = 0;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Video ROM data usage shall be %s\n",
+ val ? "enabled":"disabled");
+ }
+ if(xf86GetOptValBool(pSiS->Options, OPTION_USEOEM, &val)) {
+ if(val) pSiS->OptUseOEM = 1;
+ else pSiS->OptUseOEM = 0;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Internal LCD/TV OEM data usage shall be %s\n",
+ val ? "enabled":"disabled");
+ }
+ pSiS->sbiosn = NULL;
+ strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_SBIOSN);
+ if(strptr != NULL) {
+ pSiS->sbiosn = xalloc(strlen(strptr)+1);
+ if(pSiS->sbiosn) strcpy(pSiS->sbiosn, strptr);
+ }
+ }
+
+ /* TW: NoInternalModes (300/310/325 series only)
+ * Since the mode switching code for these chipsets is a
+ * Asm-to-C translation of BIOS code, we only have timings
+ * for a pre-defined number of modes. The default behavior
+ * is to replace XFree's default modes with a mode list
+ * generated out of the known and supported modes. Use
+ * this option to disable this. However, even if using
+ * out built-in mode list will NOT make it possible to
+ * use modelines.
+ */
+ if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
+ from = X_DEFAULT;
+ if(xf86GetOptValBool(pSiS->Options, OPTION_NOINTERNALMODES, &pSiS->noInternalModes))
+ from = X_CONFIG;
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "Usage of built-in modes is %s\n",
+ pSiS->noInternalModes ? "disabled":"enabled");
+ }
+
+ /* TW: Various parameters for TV output via SiS bridge, Chrontel or SiS6326 */
+ if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
+ int tmp = 0;
+ xf86GetOptValInteger(pSiS->Options, OPTION_CHTVLUMABANDWIDTHCVBS,
+ &pSiS->chtvlumabandwidthcvbs);
+ xf86GetOptValInteger(pSiS->Options, OPTION_CHTVLUMABANDWIDTHSVIDEO,
+ &pSiS->chtvlumabandwidthsvideo);
+ xf86GetOptValInteger(pSiS->Options, OPTION_CHTVLUMAFLICKERFILTER,
+ &pSiS->chtvlumaflickerfilter);
+ xf86GetOptValInteger(pSiS->Options, OPTION_CHTVCHROMABANDWIDTH,
+ &pSiS->chtvchromabandwidth);
+ xf86GetOptValInteger(pSiS->Options, OPTION_CHTVCHROMAFLICKERFILTER,
+ &pSiS->chtvchromaflickerfilter);
+ xf86GetOptValBool(pSiS->Options, OPTION_CHTVCVBSCOLOR,
+ &pSiS->chtvcvbscolor);
+ xf86GetOptValInteger(pSiS->Options, OPTION_CHTVTEXTENHANCE,
+ &pSiS->chtvtextenhance);
+ xf86GetOptValInteger(pSiS->Options, OPTION_CHTVCONTRAST,
+ &pSiS->chtvcontrast);
+ xf86GetOptValInteger(pSiS->Options, OPTION_SISTVEDGEENHANCE,
+ &pSiS->sistvedgeenhance);
+ xf86GetOptValInteger(pSiS->Options, OPTION_SISTVANTIFLICKER,
+ &pSiS->sistvantiflicker);
+ xf86GetOptValInteger(pSiS->Options, OPTION_SISTVSATURATION,
+ &pSiS->sistvsaturation);
+ xf86GetOptValInteger(pSiS->Options, OPTION_TVXPOSOFFSET,
+ &pSiS->tvxpos);
+ xf86GetOptValInteger(pSiS->Options, OPTION_TVYPOSOFFSET,
+ &pSiS->tvypos);
+ if(pSiS->tvxpos > 32) { pSiS->tvxpos = 32; tmp = 1; }
+ if(pSiS->tvxpos < -32) { pSiS->tvxpos = -32; tmp = 1; }
+ if(pSiS->tvypos > 32) { pSiS->tvypos = 32; tmp = 1; }
+ if(pSiS->tvypos < -32) { pSiS->tvypos = -32; tmp = 1; }
+ if(tmp) xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Illegal TV x or y offset. Range is from -32 to 32\n");
+ }
+ if((pSiS->Chipset == PCI_CHIP_SIS6326) && (pSiS->SiS6326Flags & SIS6326_HASTV)) {
+ int tmp = 0;
+ strptr = (char *)xf86GetOptValString(pSiS->Options, OPTION_SIS6326ANTIFLICKER);
+ if (strptr != NULL) {
+ if((!strcmp(strptr,"OFF")) || (!strcmp(strptr,"off")))
+ pSiS->sis6326antiflicker = 0;
+ else if((!strcmp(strptr,"LOW")) || (!strcmp(strptr,"low")))
+ pSiS->sis6326antiflicker = 1;
+ else if((!strcmp(strptr,"MED")) || (!strcmp(strptr,"med")))
+ pSiS->sis6326antiflicker = 2;
+ else if((!strcmp(strptr,"HIGH")) || (!strcmp(strptr,"high")))
+ pSiS->sis6326antiflicker = 3;
+ else if((!strcmp(strptr,"ADAPTIVE")) || (!strcmp(strptr,"adaptive")))
+ pSiS->sis6326antiflicker = 4;
+ else {
+ pSiS->sis6326antiflicker = -1;
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "\"%s\" is not a valid parameter for Option \"SIS6326TVAntiFlicker\"\n", strptr);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Valid parameters are \"OFF\", \"LOW\", \"MED\", \"HIGH\" or \"ADAPTIVE\"\n");
+ }
+ }
+ xf86GetOptValBool(pSiS->Options, OPTION_SIS6326ENABLEYFILTER,
+ &pSiS->sis6326enableyfilter);
+ xf86GetOptValBool(pSiS->Options, OPTION_SIS6326YFILTERSTRONG,
+ &pSiS->sis6326yfilterstrong);
+ xf86GetOptValInteger(pSiS->Options, OPTION_TVXPOSOFFSET,
+ &pSiS->tvxpos);
+ xf86GetOptValInteger(pSiS->Options, OPTION_TVYPOSOFFSET,
+ &pSiS->tvypos);
+ if(pSiS->tvxpos > 16) { pSiS->tvxpos = 16; tmp = 1; }
+ if(pSiS->tvxpos < -16) { pSiS->tvxpos = -16; tmp = 1; }
+ if(pSiS->tvypos > 16) { pSiS->tvypos = 16; tmp = 1; }
+ if(pSiS->tvypos < -16) { pSiS->tvypos = -16; tmp = 1; }
+ if(tmp) xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Illegal TV x or y offset. Range is from -16 to 16\n");
+ }
+}
+
+const OptionInfoRec *
+SISAvailableOptions(int chipid, int busid)
+{
+ return SISOptions;
+}
diff --git a/src/sis_regs.h b/src/sis_regs.h
new file mode 100644
index 0000000..928f1dc
--- /dev/null
+++ b/src/sis_regs.h
@@ -0,0 +1,587 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_regs.h,v 1.17 2003/01/29 15:42:17 eich Exp $ */
+/*
+ * Copyright 1998,1999 by Alan Hourihane, Wigan, England.
+ * Parts Copyright 2001, 2002 by Thomas Winischhofer, Vienna, Austria.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the copyright holder not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The copyright holder makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE PROVIDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE PROVIDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, alanh@fairlite.demon.co.uk
+ * Mike Chapman <mike@paranoia.com>,
+ * Juanjo Santamarta <santamarta@ctv.es>,
+ * Mitani Hiroshi <hmitani@drl.mei.co.jp>
+ * David Thomas <davtom@dream.org.uk>
+ *
+ * Thomas Winischhofer <thomas@winischhofer.net>
+ * - 310/325 series (315/550/650/651/740/M650) support
+ * - (possibly incomplete) Xabre (SiS330) support
+ * - new mode switching code for 300, 310/325 and 330 series
+ * - many fixes for 300/540/630/730 chipsets,
+ * - many fixes for 5597/5598, 6326 and 530/620 chipsets,
+ * - VESA mode switching (deprecated),
+ * - extended CRT2/video bridge handling support,
+ * - dual head support on 300, 310/325 and 330 series
+ * - 650/LVDS (up to 1400x1050), 650/Chrontel 701x support
+ * - 30xB/30xLV/30xLVX video bridge support (300, 310/325, 330 series)
+ * - Xv support for 5597/5598, 6326, 530/620 and 310/325 series
+ * - video overlay enhancements for 300 series
+ * - TV and hi-res support for the 6326
+ * - etc.
+ */
+
+/* For general use --------------------------------------------------------------- */
+
+#define inSISREG(base) inb(base)
+#define outSISREG(base,val) outb(base,val)
+#define orSISREG(base,val) do { \
+ unsigned char __Temp = inb(base); \
+ outSISREG(base, __Temp | (val)); \
+ } while (0)
+#define andSISREG(base,val) do { \
+ unsigned char __Temp = inb(base); \
+ outSISREG(base, __Temp & (val)); \
+ } while (0)
+
+#define inSISIDXREG(base,idx,var) do { \
+ outb(base,idx); var=inb((base)+1); \
+ } while (0)
+#define outSISIDXREG(base,idx,val) do { \
+ outb(base,idx); outb((base)+1,val); \
+ } while (0)
+#define orSISIDXREG(base,idx,val) do { \
+ unsigned char __Temp; \
+ outb(base,idx); \
+ __Temp = inb((base)+1)|(val); \
+ outSISIDXREG(base,idx,__Temp); \
+ } while (0)
+#define andSISIDXREG(base,idx,and) do { \
+ unsigned char __Temp; \
+ outb(base,idx); \
+ __Temp = inb((base)+1)&(and); \
+ outSISIDXREG(base,idx,__Temp); \
+ } while (0)
+#define setSISIDXREG(base,idx,and,or) do { \
+ unsigned char __Temp; \
+ outb(base,idx); \
+ __Temp = (inb((base)+1)&(and))|(or); \
+ outSISIDXREG(base,idx,__Temp); \
+ } while (0)
+
+#define BITMASK(h,l) (((unsigned)(1U << ((h)-(l)+1))-1)<<(l))
+#define GENMASK(mask) BITMASK(1?mask,0?mask)
+
+#define GETBITS(var,mask) (((var) & GENMASK(mask)) >> (0?mask))
+#define SETBITS(val,mask) ((val) << (0?mask))
+#define SETBIT(n) (1<<(n))
+
+#define GETBITSTR(val,from,to) ((GETBITS(val,from)) << (0?to))
+#define SETVARBITS(var,val,from,to) (((var)&(~(GENMASK(to)))) | \
+ GETBITSTR(val,from,to))
+#define GETVAR8(var) ((var)&0xFF)
+#define SETVAR8(var,val) (var) = GETVAR8(val)
+
+/* #define VGA_RELIO_BASE 0x380 */
+
+#define AROFFSET 0x40 /* VGA_ATTR_INDEX - VGA_RELIO_BASE */
+#define ARROFFSET 0x41 /* VGA_ATTR_DATA_R - VGA_RELIO_BASE */
+#define GROFFSET 0x4e /* VGA_GRAPH_INDEX - VGA_RELIO_BASE */
+#define SROFFSET 0x44 /* VGA_SEQ_INDEX - VGA_RELIO_BASE */
+#define CROFFSET 0x54 /* VGA_CRTC_INDEX_OFFSET + VGA_IOBASE_COLOR - VGA_RELIO_BASE */
+#define MISCROFFSET 0x4c /* VGA_MISC_OUT_R - VGA_RELIO_BASE */
+#define MISCWOFFSET 0x42 /* VGA_MISC_OUT_W - VGA_RELIO_BASE */
+#define INPUTSTATOFFSET 0x5A
+#define PART1OFFSET 0x04
+#define PART2OFFSET 0x10
+#define PART3OFFSET 0x12
+#define PART4OFFSET 0x14
+#define PART5OFFSET 0x16
+#define VIDEOOFFSET 0x02
+#define COLREGOFFSET 0x48
+
+#define SISAR pSiS->RelIO + AROFFSET
+#define SISARR pSiS->RelIO + ARROFFSET
+#define SISGR pSiS->RelIO + GROFFSET
+#define SISSR pSiS->RelIO + SROFFSET
+#define SISCR pSiS->RelIO + CROFFSET
+#define SISMISCR pSiS->RelIO + MISCROFFSET
+#define SISMISCW pSiS->RelIO + MISCWOFFSET
+#define SISINPSTAT pSiS->RelIO + INPUTSTATOFFSET
+#define SISPART1 pSiS->RelIO + PART1OFFSET
+#define SISPART2 pSiS->RelIO + PART2OFFSET
+#define SISPART3 pSiS->RelIO + PART3OFFSET
+#define SISPART4 pSiS->RelIO + PART4OFFSET
+#define SISPART5 pSiS->RelIO + PART5OFFSET
+#define SISVID pSiS->RelIO + VIDEOOFFSET
+#define SISCOLIDX pSiS->RelIO + COLREGOFFSET
+#define SISCOLDATA pSiS->RelIO + COLREGOFFSET + 1
+#define SISCOL2IDX SISPART5
+#define SISCOL2DATA SISPART5 + 1
+
+
+#define vc_index_offset 0x00 /* Video capture - unused */
+#define vc_data_offset 0x01
+#define vi_index_offset VIDEOOFFSET
+#define vi_data_offset (VIDEOOFFSET + 1)
+#define crt2_index_offset PART1OFFSET
+#define crt2_port_offset (PART1OFFSET + 1)
+#define sr_index_offset SROFFSET
+#define sr_data_offset (SROFFSET + 1)
+#define cr_index_offset CROFFSET
+#define cr_data_offset (CROFFSET + 1)
+#define input_stat INPUTSTATOFFSET
+
+/* For old chipsets (5597/5598, 6326, 530/620) ------------ */
+/* SR (3C4) */
+#define BankReg 0x06
+#define ClockReg 0x07
+#define CPUThreshold 0x08
+#define CRTThreshold 0x09
+#define CRTCOff 0x0A
+#define DualBanks 0x0B
+#define MMIOEnable 0x0B
+#define RAMSize 0x0C
+#define Mode64 0x0C
+#define ExtConfStatus1 0x0E
+#define ClockBase 0x13
+#define LinearAdd0 0x20
+#define LinearAdd1 0x21
+#define GraphEng 0x27
+#define MemClock0 0x28
+#define MemClock1 0x29
+#define XR2A 0x2A
+#define XR2B 0x2B
+#define TurboQueueBase 0x2C
+#define FBSize 0x2F
+#define ExtMiscCont5 0x34
+#define ExtMiscCont9 0x3C
+
+/* 3x4 */
+#define Offset 0x13
+
+/* SiS Registers for 300, 540, 630, 730, 315, 550, 650, 740 ---------------------- */
+
+/* VGA standard register */
+#define Index_SR_Graphic_Mode 0x06
+#define Index_SR_RAMDAC_Ctrl 0x07
+#define Index_SR_Threshold_Ctrl1 0x08
+#define Index_SR_Threshold_Ctrl2 0x09
+#define Index_SR_Misc_Ctrl 0x0F
+#define Index_SR_DDC 0x11
+#define Index_SR_Feature_Connector_Ctrl 0x12
+#define Index_SR_DRAM_Sizing 0x14
+#define Index_SR_DRAM_State_Machine_Ctrl 0x15
+#define Index_SR_AGP_PCI_State_Machine 0x21
+#define Index_SR_Internal_MCLK0 0x28
+#define Index_SR_Internal_MCLK1 0x29
+#define Index_SR_Internal_DCLK1 0x2B
+#define Index_SR_Internal_DCLK2 0x2C
+#define Index_SR_Internal_DCLK3 0x2D
+#define Index_SR_Ext_Clock_Sel 0x32
+#define Index_SR_Int_Status 0x34
+#define Index_SR_Int_Enable 0x35
+#define Index_SR_Int_Reset 0x36
+#define Index_SR_Power_On_Trap 0x38
+#define Index_SR_Power_On_Trap2 0x39
+#define Index_SR_Power_On_Trap3 0x3A
+
+/* video registers (300/630/730/315/550/650/740 only) */
+#define Index_VI_Passwd 0x00
+
+/* Video overlay horizontal start/end, unit=screen pixels */
+#define Index_VI_Win_Hor_Disp_Start_Low 0x01
+#define Index_VI_Win_Hor_Disp_End_Low 0x02
+#define Index_VI_Win_Hor_Over 0x03 /* Overflow */
+
+/* Video overlay vertical start/end, unit=screen pixels */
+#define Index_VI_Win_Ver_Disp_Start_Low 0x04
+#define Index_VI_Win_Ver_Disp_End_Low 0x05
+#define Index_VI_Win_Ver_Over 0x06 /* Overflow */
+
+/* Y Plane (4:2:0) or YUV (4:2:2) buffer start address, unit=word */
+#define Index_VI_Disp_Y_Buf_Start_Low 0x07
+#define Index_VI_Disp_Y_Buf_Start_Middle 0x08
+#define Index_VI_Disp_Y_Buf_Start_High 0x09
+
+/* U Plane (4:2:0) buffer start address, unit=word */
+#define Index_VI_U_Buf_Start_Low 0x0A
+#define Index_VI_U_Buf_Start_Middle 0x0B
+#define Index_VI_U_Buf_Start_High 0x0C
+
+/* V Plane (4:2:0) buffer start address, unit=word */
+#define Index_VI_V_Buf_Start_Low 0x0D
+#define Index_VI_V_Buf_Start_Middle 0x0E
+#define Index_VI_V_Buf_Start_High 0x0F
+
+/* Pitch for Y, UV Planes, unit=word */
+#define Index_VI_Disp_Y_Buf_Pitch_Low 0x10
+#define Index_VI_Disp_UV_Buf_Pitch_Low 0x11
+#define Index_VI_Disp_Y_UV_Buf_Pitch_Middle 0x12
+
+/* What is this ? */
+#define Index_VI_Disp_Y_Buf_Preset_Low 0x13
+#define Index_VI_Disp_Y_Buf_Preset_Middle 0x14
+
+#define Index_VI_UV_Buf_Preset_Low 0x15
+#define Index_VI_UV_Buf_Preset_Middle 0x16
+#define Index_VI_Disp_Y_UV_Buf_Preset_High 0x17
+
+/* Scaling control registers */
+#define Index_VI_Hor_Post_Up_Scale_Low 0x18
+#define Index_VI_Hor_Post_Up_Scale_High 0x19
+#define Index_VI_Ver_Up_Scale_Low 0x1A
+#define Index_VI_Ver_Up_Scale_High 0x1B
+#define Index_VI_Scale_Control 0x1C
+
+/* Playback line buffer control */
+#define Index_VI_Play_Threshold_Low 0x1D
+#define Index_VI_Play_Threshold_High 0x1E
+#define Index_VI_Line_Buffer_Size 0x1F
+
+/* Destination color key */
+#define Index_VI_Overlay_ColorKey_Red_Min 0x20
+#define Index_VI_Overlay_ColorKey_Green_Min 0x21
+#define Index_VI_Overlay_ColorKey_Blue_Min 0x22
+#define Index_VI_Overlay_ColorKey_Red_Max 0x23
+#define Index_VI_Overlay_ColorKey_Green_Max 0x24
+#define Index_VI_Overlay_ColorKey_Blue_Max 0x25
+
+/* Source color key, YUV color space */
+#define Index_VI_Overlay_ChromaKey_Red_Y_Min 0x26
+#define Index_VI_Overlay_ChromaKey_Green_U_Min 0x27
+#define Index_VI_Overlay_ChromaKey_Blue_V_Min 0x28
+#define Index_VI_Overlay_ChromaKey_Red_Y_Max 0x29
+#define Index_VI_Overlay_ChromaKey_Green_U_Max 0x2A
+#define Index_VI_Overlay_ChromaKey_Blue_V_Max 0x2B
+
+/* Contrast enhancement and brightness control */
+#define Index_VI_Contrast_Factor 0x2C /* obviously unused/undefined */
+#define Index_VI_Brightness 0x2D
+#define Index_VI_Contrast_Enh_Ctrl 0x2E
+
+#define Index_VI_Key_Overlay_OP 0x2F
+
+#define Index_VI_Control_Misc0 0x30
+#define Index_VI_Control_Misc1 0x31
+#define Index_VI_Control_Misc2 0x32
+
+/* TW: Subpicture registers */
+#define Index_VI_SubPict_Buf_Start_Low 0x33
+#define Index_VI_SubPict_Buf_Start_Middle 0x34
+#define Index_VI_SubPict_Buf_Start_High 0x35
+
+/* TW: What is this ? */
+#define Index_VI_SubPict_Buf_Preset_Low 0x36
+#define Index_VI_SubPict_Buf_Preset_Middle 0x37
+
+/* TW: Subpicture pitch, unit=16 bytes */
+#define Index_VI_SubPict_Buf_Pitch 0x38
+
+/* TW: Subpicture scaling control */
+#define Index_VI_SubPict_Hor_Scale_Low 0x39
+#define Index_VI_SubPict_Hor_Scale_High 0x3A
+#define Index_VI_SubPict_Vert_Scale_Low 0x3B
+#define Index_VI_SubPict_Vert_Scale_High 0x3C
+
+#define Index_VI_SubPict_Scale_Control 0x3D
+/* (0x40 = enable/disable subpicture) */
+
+/* TW: Subpicture line buffer control */
+#define Index_VI_SubPict_Threshold 0x3E
+
+/* TW: What is this? */
+#define Index_VI_FIFO_Max 0x3F
+
+/* TW: Subpicture palette; 16 colors, total 32 bytes address space */
+#define Index_VI_SubPict_Pal_Base_Low 0x40
+#define Index_VI_SubPict_Pal_Base_High 0x41
+
+/* I wish I knew how to use these ... */
+#define Index_MPEG_Read_Ctrl0 0x60 /* MPEG auto flip */
+#define Index_MPEG_Read_Ctrl1 0x61 /* MPEG auto flip */
+#define Index_MPEG_Read_Ctrl2 0x62 /* MPEG auto flip */
+#define Index_MPEG_Read_Ctrl3 0x63 /* MPEG auto flip */
+
+/* TW: MPEG AutoFlip scale */
+#define Index_MPEG_Ver_Up_Scale_Low 0x64
+#define Index_MPEG_Ver_Up_Scale_High 0x65
+
+#define Index_MPEG_Y_Buf_Preset_Low 0x66
+#define Index_MPEG_Y_Buf_Preset_Middle 0x67
+#define Index_MPEG_UV_Buf_Preset_Low 0x68
+#define Index_MPEG_UV_Buf_Preset_Middle 0x69
+#define Index_MPEG_Y_UV_Buf_Preset_High 0x6A
+
+/* TW: The following registers only exist on the 310/325 series */
+
+/* TW: Bit 16:24 of Y_U_V buf start address (?) */
+#define Index_VI_Y_Buf_Start_Over 0x6B
+#define Index_VI_U_Buf_Start_Over 0x6C
+#define Index_VI_V_Buf_Start_Over 0x6D
+
+#define Index_VI_Disp_Y_Buf_Pitch_High 0x6E
+#define Index_VI_Disp_UV_Buf_Pitch_High 0x6F
+
+/* Hue and saturation */
+#define Index_VI_Hue 0x70
+#define Index_VI_Saturation 0x71
+
+#define Index_VI_SubPict_Start_Over 0x72
+#define Index_VI_SubPict_Buf_Pitch_High 0x73
+
+#define Index_VI_Control_Misc3 0x74
+
+
+/* TW: Bits (and helpers) for Index_VI_Control_Misc0 */
+#define VI_Misc0_Enable_Overlay 0x02
+#define VI_Misc0_420_Plane_Enable 0x04 /* Select Plane or Packed mode */
+#define VI_Misc0_422_Enable 0x20 /* Select 422 or 411 mode */
+#define VI_Misc0_Fmt_YVU420P 0x0C /* YUV420 Planar (I420, YV12) */
+#define VI_Misc0_Fmt_YUYV 0x28 /* YUYV Packed (YUY2) */
+#define VI_Misc0_Fmt_UYVY 0x08 /* (UYVY) */
+
+/* TW: Bits for Index_VI_Control_Misc1 */
+/* #define VI_Misc1_? 0x01 */
+#define VI_Misc1_BOB_Enable 0x02
+#define VI_Misc1_Line_Merge 0x04
+#define VI_Misc1_Field_Mode 0x08
+/* #define VI_Misc1_? 0x10 */
+#define VI_Misc1_Non_Interleave 0x20 /* 300 series only? */
+#define VI_Misc1_Buf_Addr_Lock 0x20 /* 310 series only? */
+/* #define VI_Misc1_? 0x40 */
+/* #define VI_Misc1_? 0x80 */
+
+/* TW: Bits for Index_VI_Control_Misc2 */
+#define VI_Misc2_Select_Video2 0x01
+#define VI_Misc2_Video2_On_Top 0x02
+/* #define VI_Misc2_? 0x04 */
+#define VI_Misc2_Vertical_Interpol 0x08
+#define VI_Misc2_Dual_Line_Merge 0x10
+#define VI_Misc2_All_Line_Merge 0x20 /* 310 series only? */
+#define VI_Misc2_Auto_Flip_Enable 0x40 /* 300 series only? */
+#define VI_Misc2_Video_Reg_Write_Enable 0x80 /* 310 series only? */
+
+/* TW: Bits for Index_VI_Control_Misc3 */
+#define VI_Misc3_Submit_Video_1 0x01 /* AKA "address ready" */
+#define VI_Misc3_Submit_Video_2 0x02 /* AKA "address ready" */
+#define VI_Misc3_Submit_SubPict 0x04 /* AKA "address ready" */
+
+/* TW: Values for Index_VI_Key_Overlay_OP (0x2F) */
+#define VI_ROP_Never 0x00
+#define VI_ROP_DestKey 0x03
+#define VI_ROP_Always 0x0F
+
+
+/* video registers (6326 and 530/620) --------------- */
+#define Index_VI6326_Passwd 0x80
+
+/* Video overlay horizontal start/end, unit=screen pixels */
+#define Index_VI6326_Win_Hor_Disp_Start_Low 0x81
+#define Index_VI6326_Win_Hor_Disp_End_Low 0x82
+#define Index_VI6326_Win_Hor_Over 0x83 /* Overflow */
+
+/* Video overlay vertical start/end, unit=screen pixels */
+#define Index_VI6326_Win_Ver_Disp_Start_Low 0x84
+#define Index_VI6326_Win_Ver_Disp_End_Low 0x85
+#define Index_VI6326_Win_Ver_Over 0x86 /* Overflow */
+
+/* Y Plane (4:2:0) or YUV (4:2:2) buffer start address, unit=dword */
+#define Index_VI6326_Disp_Y_Buf_Start_Low 0x8A
+#define Index_VI6326_Disp_Y_Buf_Start_Middle 0x8B
+#define Index_VI6326_Disp_Capt_Y_Buf_Start_High 0x89 /* 6326: 7:4 display, 3:0 capture */
+ /* 530/620: 7:3 display. 2:0 reserved */
+/* End address of Y plane (in 16k unit) - 6326 ONLY */
+#define Index_VI6326_Disp_Y_End 0x8D
+
+/* U Plane (4:2:0) buffer start address, unit=dword */
+#define Index_VI6326_U_Buf_Start_Low 0xB7
+#define Index_VI6326_U_Buf_Start_Middle 0xB8
+
+/* V Plane (4:2:0) buffer start address, unit=dword */
+#define Index_VI6326_V_Buf_Start_Low 0xBA
+#define Index_VI6326_V_Buf_Start_Middle 0xBB
+
+/* U/V plane start address overflow bits 19:16 */
+#define Index_VI6326_UV_Buf_Start_High 0xB9
+
+/* Pitch for Y, UV Planes, unit=dword(6326 & 530/620) */
+#define Index_VI6326_Disp_Y_Buf_Pitch_Low 0x8C /* 7:0 */
+#define Index_VI6326_Disp_Y_Buf_Pitch_High 0x8E /* 11:8 (3:0 here) */
+
+#define Index_VI6326_Disp_UV_Buf_Pitch_Low 0xBC /* 7:0 */
+#define Index_VI6326_Disp_UV_Buf_Pitch_High 0xBD /* 11:8 (3:0 here) */
+
+/* Scaling control registers */
+#define Index_VI6326_Hor_Scale 0x92
+#define Index_VI6326_Hor_Scale_Integer 0x94
+#define Index_VI6326_Ver_Scale 0x93
+
+/* Playback line buffer control */
+#define Index_VI6326_Play_Threshold_Low 0x9E
+#define Index_VI6326_Play_Threshold_High 0x9F
+#define Index_VI6326_Line_Buffer_Size 0xA0 /* 530 & 6326: quad-word */
+
+/* Destination color key */
+#define Index_VI6326_Overlay_ColorKey_Red_Min 0x97
+#define Index_VI6326_Overlay_ColorKey_Green_Min 0x96
+#define Index_VI6326_Overlay_ColorKey_Blue_Min 0x95
+#define Index_VI6326_Overlay_ColorKey_Red_Max 0xA3
+#define Index_VI6326_Overlay_ColorKey_Green_Max 0xA2
+#define Index_VI6326_Overlay_ColorKey_Blue_Max 0xA1
+
+/* Source color key */
+#define Index_VI6326_Overlay_ChromaKey_Red_Y_Min 0x9C
+#define Index_VI6326_Overlay_ChromaKey_Green_U_Min 0x9B
+#define Index_VI6326_Overlay_ChromaKey_Blue_V_Min 0x9A
+#define Index_VI6326_Overlay_ChromaKey_Red_Y_Max 0xA6
+#define Index_VI6326_Overlay_ChromaKey_Green_U_Max 0xA5
+#define Index_VI6326_Overlay_ChromaKey_Blue_V_Max 0xA4
+
+/* Contrast enhancement and brightness control */
+#define Index_VI6326_Contrast_Factor 0xB3
+#define Index_VI6326_Brightness 0xB4
+#define Index_VI6326_Contrast_Enh_Ctrl 0xB5
+
+/* Alpha (ALL 6326 only?) */
+#define Index_VI6326_AlphaGraph 0xA7
+#define Index_VI6326_AlphaVideo 0xA8
+
+#define Index_VI6326_Key_Overlay_OP 0xA9
+
+#define Index_VI6326_Control_Misc0 0x98
+#define Index_VI6326_Control_Misc1 0x99 /* (Datasheet: 6326 ONLY - not correct?) */
+#define Index_VI6326_Control_Misc3 0x9D
+#define Index_VI6326_Control_Misc4 0xB6
+#define Index_VI6326_VideoFormatSelect Index_VI6326_Ver_Scale
+#define Index_VI6326_Control_Misc5 0xBE /* (Datasheet: 530/620 ONLY - not correct) */
+#define Index_VI6326_Control_Misc6 0xB2 /* 5597 and 6326 only! */
+
+/* TW: What is this? not a register, obviously */
+#define Index_VI6326_FIFO_Max 0x3F
+
+/* TW: Bits (and helpers) for Index_VI6326_Control_Misc0 */
+#define VI6326_Misc0_EnableCapture 0x01 /* 1 = on, 0 = off (6326 only) */
+#define VI6326_Misc0_EnableOverlay 0x02 /* 1 = on, 0 = off */
+#define VI6326_Misc0_VideoOnly 0x10 /* 1 = video only, 0 = gfx + video */
+#define VI6326_Misc0_CaptureInterlace 0x20 /* 1 = capture data is interlace, 0 = not (6326 only) */
+#define VI6326_Misc0_VideoFormat 0x40 /* 1 = YUV, 0 = RGB */
+#define VI6326_Misc0_FieldPolarity 0x80 /* 1 = *Odd / Even, 0 = Odd / *Even (6326 only) */
+
+/* TW: Bits for Index_VI6326_Control_Misc1 (ALL 6326 ONLY) */
+#define VI6326_Misc1_EnableYUVCapture 0x01 /* 0 = RGB, 1 = YUV */
+#define VI6326_Misc1_EnableCaptureDithering 0x02 /* 0 = disable, 1 = enable */
+#define VI6326_Misc1_CaptureFormat555 0x04 /* 1 = 555, 0 = 565 */
+#define VI6326_Misc1_FilterModeMask 0x38
+#define VI6326_Misc1_FilterMode0 0x00 /* 1 */
+#define VI6326_Misc1_FilterMode1 0x08 /* 1/8(1+3z^-1+3z^-2+z^-3)*/
+#define VI6326_Misc1_FilterMode2 0x10 /* 1/4(1+2z^-1+z^-2) */
+#define VI6326_Misc1_FilterMode3 0x18 /* 1/2(1+z^-1) */
+#define VI6326_Misc1_FilterMode4 0x20 /* 1/8(1+2z^-1+2z^-2+2z^-3+z^-4) */
+#define VI6326_Misc1_EnableVBSyncIRQ 0x40 /* 1 = Enable IRQ on vertical blank */
+#define VI6326_Misc1_ClearVBSyncIRQ 0x80 /* Clear pending irq */
+
+/* TW: Bits for Index_VI6326_Control_Misc3 */
+#define VI6326_Misc3_UVCaptureFormat 0x01 /* 1 = 2's complement, 0 = CCIR 601 (6326 only) */
+#define VI6326_Misc3_UVOverlayFormat 0x02 /* 1 = 2's complement, 0 = CCIR 601 */
+#define VI6326_Misc3_ChromaKeyFormat 0x04 /* 1 = YUV, 0 = RGB */
+#define VI6326_Misc3_VMIAccess 0x08 /* 1 = enable, 0 = disable (6326 only) */
+#define VI6326_Misc3_VMIEnable 0x10 /* 1 = enable, 0 = disable (6326 only) */
+#define VI6326_Misc3_VMIIRQ 0x20 /* 1 = enable, 0 = disable (6326 only) */
+#define VI6326_Misc3_BT819A 0x40 /* 1 = enable, 0 = disable (6326 only) */
+#define VI6326_Misc3_SystemMemFB 0x80 /* 1 = enable, 0 = disable (6326 only) */
+
+/* TW: Bits for Index_VI6326_Control_Misc4 */
+#define VI6326_Misc4_CPUVideoFormatMask 0x03
+#define VI6326_Misc4_CPUVideoFormatRGB555 0x00
+#define VI6326_Misc4_CPUVideoFormatYUV422 0x01
+#define VI6326_Misc4_CPUVideoFormatRGB565 0x02
+#define VI6326_Misc4_EnableYUV420 0x04 /* 1 = enable, 0 = disable */
+/** #define WHATISTHIS 0x40 */
+
+/* TW: Bits for Index_VI6326_Control_Misc5 (all 530/620 only) */
+#define VI6326_Misc5_LineBufferMerge 0x10 /* 0 = disable, 1=enable */
+#define VI6326_Misc5_VPlaneBit20 0x04
+#define VI6326_Misc5_UPlaneBit20 0x02
+
+/* TW: Bits for Index_VI6326_Control_Misc6 (5597 and 6326 only) */
+#define VI6326_Misc6_Decimation 0x80 /* 0=disable 1=enable video decimation */
+
+/* Video format selection */
+#define VI_6326_VideoUYVY422 0x00
+#define VI_6326_VideoVYUY422 0x40
+#define VI_6326_VideoYUYV422 0x80
+#define VI_6326_VideoYVYU422 0xC0
+#define VI_6326_VideoRGB555 0x00
+#define VI_6326_VideoRGB565 0x40
+
+/* TW: Values for Index_VI6326_Key_Overlay_OP */
+#define VI6326_ROP_Never 0x00
+#define VI6326_ROP_DestKey 0x03
+#define VI6326_ROP_Always 0x0F
+
+/* --- end of 6326 video registers ---------------------------------- */
+
+/* TW register base (6326 only) */
+#define Index_TV6326_TVOutIndex 0xE0
+#define Index_TV6326_TVOutData 0xE1
+
+/*
+ * CRT_2 function control register ---------------------------------
+ */
+#define Index_CRT2_FC_CONTROL 0x00
+#define Index_CRT2_FC_SCREEN_HIGH 0x04
+#define Index_CRT2_FC_SCREEN_MID 0x05
+#define Index_CRT2_FC_SCREEN_LOW 0x06
+#define Index_CRT2_FC_ENABLE_WRITE 0x24
+#define Index_CRT2_FC_VR 0x25
+#define Index_CRT2_FC_VCount 0x27
+#define Index_CRT2_FC_VCount1 0x28
+
+#define Index_310_CRT2_FC_VR 0x30 /* d[1] = vertical retrace */
+#define Index_310_CRT2_FC_RT 0x33 /* d[7] = retrace in progress */
+
+/* video attributes - these should probably be configurable on the fly
+ * so users with different desktop sizes can keep
+ * captured data off the desktop
+ */
+#define _VINWID 704
+#define _VINHGT _VINHGT_NTSC
+#define _VINHGT_NTSC 240
+#define _VINHGT_PAL 290
+#define _VIN_WINDOW (704 * 291 * 2)
+#define _VBI_WINDOW (704 * 64 * 2)
+
+#define _VIN_FIELD_EVEN 1
+#define _VIN_FIELD_ODD 2
+#define _VIN_FIELD_BOTH 4
+
+
+/* i2c registers (TW; not on 300/310/325 series) */
+#define X_INDEXREG 0x14
+#define X_PORTREG 0x15
+#define X_DATA 0x0f
+#define I2C_SCL 0x00
+#define I2C_SDA 0x01
+#define I2C_DELAY 10
+
+/* mmio registers for video */
+#define REG_PRIM_CRT_COUNTER 0x8514
+
+/* TW: MPEG MMIO registers (630 and later) ----------------------------------------- */
+
+/* Not public (yet?) */
+
diff --git a/src/sis_setup.c b/src/sis_setup.c
new file mode 100644
index 0000000..a26d191
--- /dev/null
+++ b/src/sis_setup.c
@@ -0,0 +1,528 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_setup.c,v 1.9 2003/02/04 02:44:29 dawes Exp $ */
+/*
+ * Basic hardware and memory detection
+ *
+ * Copyright 1998,1999 by Alan Hourihane, Wigan, England.
+ * Parts Copyright 2001, 2002 by Thomas Winischhofer, Vienna, Austria.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the copyright holder not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The copyright holder makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, alanh@fairlite.demon.co.uk
+ * Mike Chapman <mike@paranoia.com>,
+ * Juanjo Santamarta <santamarta@ctv.es>,
+ * Mitani Hiroshi <hmitani@drl.mei.co.jp>
+ * David Thomas <davtom@dream.org.uk>.
+ * Thomas Winischhofer <thomas@winischhofer.net>
+ */
+
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+#include "xf86.h"
+#include "fb.h"
+#include "xf1bpp.h"
+#include "xf4bpp.h"
+#include "xf86_OSproc.h"
+#include "xf86Resources.h"
+#include "xf86_ansic.h"
+#include "xf86Version.h"
+
+#include "xf86pciBus.h"
+#include "xf86cmap.h"
+
+#include "sis.h"
+#include "sis_regs.h"
+#include "sis_dac.h"
+
+#define _XF86DGA_SERVER_
+#include "extensions/xf86dgastr.h"
+
+#include "globals.h"
+#define DPMS_SERVER
+#include "extensions/dpms.h"
+
+static const char *dramTypeStr[] = {
+ "Fast Page DRAM",
+ "2 cycle EDO RAM",
+ "1 cycle EDO RAM",
+ "SDRAM/SGRAM",
+ "SDRAM",
+ "SGRAM",
+ "ESDRAM",
+ "DDR RAM", /* for 550/650 */
+ "DDR RAM", /* for 550/650 */
+ "" };
+
+/* TW: MCLK tables for SiS6326 */
+static const int SiS6326MCLKIndex[4][8] = {
+ { 10, 12, 14, 16, 17, 18, 19, 7 }, /* SGRAM */
+ { 4, 6, 8, 10, 11, 12, 13, 3 }, /* Fast Page */
+ { 9, 11, 12, 13, 15, 16, 5, 7 }, /* 2 cycle EDO */
+ { 10, 12, 14, 16, 17, 18, 19, 7 } /* ? (Not 1 cycle EDO) */
+};
+
+static const struct _sis6326mclk {
+ CARD16 mclk;
+ unsigned char sr13;
+ unsigned char sr28;
+ unsigned char sr29;
+} SiS6326MCLK[] = {
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 45, 0, 0x2b, 0x26 },
+ { 53, 0, 0x49, 0xe4 },
+ { 55, 0, 0x7c, 0xe7 },
+ { 56, 0, 0x7c, 0xe7 },
+ { 60, 0, 0x42, 0xe3 },
+ { 61, 0, 0x21, 0xe1 },
+ { 65, 0, 0x5a, 0xe4 },
+ { 66, 0, 0x5a, 0xe4 },
+ { 70, 0, 0x61, 0xe4 },
+ { 75, 0, 0x3e, 0xe2 },
+ { 80, 0, 0x42, 0xe2 },
+ { 83, 0, 0xb3, 0xc5 },
+ { 85, 0, 0x5e, 0xe3 },
+ { 90, 0, 0xae, 0xc4 },
+ {100, 0, 0x37, 0xe1 },
+ {115, 0, 0x78, 0x0e },
+ {134, 0, 0x4a, 0xa3 }
+};
+
+/* For 5597, 6326, 530/620 */
+static void
+sisOldSetup(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int ramsize[8] = { 1, 2, 4, 0, 0, 2, 4, 8};
+ int buswidth[8] = {32, 64, 64, 0, 0, 32, 32, 64 };
+ int clockTable[4] = { 66, 75, 83, 100 };
+ int ramtype[4] = { 5, 0, 1, 3 };
+ int config;
+ int temp, i;
+ unsigned char sr23, sr33, sr34, sr37;
+#if 0
+ unsigned char newsr13, newsr28, newsr29;
+#endif
+ pciConfigPtr pdptr, *systemPCIdevices = NULL;
+
+ if(pSiS->Chipset == PCI_CHIP_SIS5597) {
+ inSISIDXREG(SISSR, FBSize, temp);
+ pScrn->videoRam = ((temp & 0x07) + 1) * 256;
+ inSISIDXREG(SISSR, Mode64, temp);
+ if(temp & 0x06) {
+ pScrn->videoRam *= 2;
+ pSiS->BusWidth = 64;
+ } else pSiS->BusWidth = 32;
+ } else {
+ inSISIDXREG(SISSR, RAMSize, temp);
+ config = ((temp & 0x10) >> 2 ) | ((temp & 0x6) >> 1);
+ pScrn->videoRam = ramsize[config] * 1024;
+ pSiS->BusWidth = buswidth[config];
+ }
+
+ if(pSiS->Chipset == PCI_CHIP_SIS530) {
+
+ inSISIDXREG(SISSR, 0x0D, temp);
+ pSiS->Flags &= ~(UMA);
+ if(temp & 0x01) {
+ pSiS->Flags |= UMA; /* TW: Shared fb mode */
+ inSISIDXREG(SISSR, 0x10, temp);
+ pSiS->MemClock = clockTable[temp & 0x03] * 1000;
+ } else pSiS->MemClock = SiSMclk(pSiS); /* TW: Local fb mode */
+
+ } else if(pSiS->Chipset == PCI_CHIP_SIS6326) {
+
+ inSISIDXREG(SISSR,0x0e,temp);
+ i = temp & 0x03;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Detected DRAM type: %s\n",
+ dramTypeStr[ramtype[i]]);
+
+ temp = (temp >> 5) & 0x07;
+ i = SiS6326MCLKIndex[i][temp];
+ pSiS->MemClock = SiS6326MCLK[i].mclk;
+#if 0
+ /* TW: Correct invalid MCLK settings by old BIOSes */
+ newsr13 = SiS6326MCLK[i].sr13;
+ newsr28 = SiS6326MCLK[i].sr28;
+ newsr29 = SiS6326MCLK[i].sr29;
+ if((pSiS->ChipRev == 0x92) ||
+ (pSiS->ChipRev == 0xd1) ||
+ (pSiS->ChipRev == 0xd2)) {
+ if(pSiS->MemClock == 60) {
+ newsr28 = 0xae;
+ newsr29 = 0xc4;
+ }
+ }
+#endif
+ pSiS->MemClock *= 1000;
+#if 0
+ inSISIDXREG(SISSR, 0x13, temp);
+ temp &= 0x80;
+ temp |= (newsr13 & 0x80);
+ outSISIDXREG(SISSR,0x13,temp);
+ outSISIDXREG(SISSR,0x28,newsr28);
+ outSISIDXREG(SISSR,0x29,newsr29);
+#endif
+
+ } else {
+
+ pSiS->MemClock = SiSMclk(pSiS);
+
+ }
+
+ pSiS->Flags &= ~(SYNCDRAM | RAMFLAG);
+ if(pSiS->oldChipset >= OC_SIS82204) {
+ inSISIDXREG(SISSR, 0x23, sr23);
+ inSISIDXREG(SISSR, 0x33, sr33);
+ inSISIDXREG(SISSR, 0x34, sr34);
+ if(sr33 & 0x09) { /* 5597: Sync DRAM timing | One cycle EDO ram; */
+ pSiS->Flags |= (sr33 & SYNCDRAM); /* 6326: Enable SGRam timing | One cycle EDO ram */
+ pSiS->Flags |= RAMFLAG; /* 530: Enable SGRAM timing | reserved (0) */
+ } else if(sr23 & 0x20) { /* 5597, 6326: EDO DRAM enabled */
+ pSiS->Flags |= SYNCDRAM; /* 530/620: reserved (0) */
+ }
+ }
+
+ pSiS->Flags &= ~(ESS137xPRESENT);
+ if(pSiS->Chipset == PCI_CHIP_SIS530) {
+ if(pSiS->oldChipset == OC_SIS530A) {
+ if((systemPCIdevices = xf86GetPciConfigInfo())) {
+ i = 0;
+ while((pdptr = systemPCIdevices[i])) {
+ if((pdptr->pci_vendor == 0x1274) &&
+ ((pdptr->pci_device == 0x5000) ||
+ ((pdptr->pci_device & 0xFFF0) == 0x1370))) {
+ pSiS->Flags |= ESS137xPRESENT;
+ break;
+ }
+ i++;
+ }
+ }
+ if(pSiS->Flags & ESS137xPRESENT) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "SiS530/620: Found ESS device\n");
+ }
+ }
+ }
+
+ pSiS->Flags &= ~(SECRETFLAG);
+ if(pSiS->oldChipset >= OC_SIS5597) {
+ inSISIDXREG(SISSR, 0x37, sr37);
+ if(sr37 & 0x80) pSiS->Flags |= SECRETFLAG;
+ }
+
+ pSiS->Flags &= ~(A6326REVAB);
+ if(pSiS->Chipset == PCI_CHIP_SIS6326) {
+ if(((pSiS->ChipRev & 0x0f) == 0x0a) ||
+ ((pSiS->ChipRev & 0x0f) == 0x0b)) {
+ pSiS->Flags |= A6326REVAB;
+ }
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Detected memory clock: %3.3f MHz\n",
+ pSiS->MemClock/1000.0);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Detected DRAM bus width: %d bit\n",
+ pSiS->BusWidth);
+}
+
+static void
+sis300Setup(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ const int bus[4] = {32, 64, 128, 32};
+ const int adaptermclk[8] = { 66, 83, 100, 133,
+ 100, 100, 100, 100};
+ const int adaptermclk300[8] = { 125, 125, 125, 100,
+ 100, 100, 100, 100};
+ unsigned int config;
+ unsigned char temp;
+ int cpubuswidth;
+ int from = X_PROBED;
+
+ pSiS->MemClock = SiSMclk(pSiS);
+
+ inSISIDXREG(SISSR, 0x14, config);
+ pScrn->videoRam = ((config & 0x3F) + 1) * 1024;
+ cpubuswidth = bus[config >> 6];
+
+ switch(pSiS->Chipset) {
+ case PCI_CHIP_SIS300:
+ pSiS->BusWidth = cpubuswidth;
+ break;
+ case PCI_CHIP_SIS540:
+ pSiS->BusWidth = 64;
+ from = X_INFO;
+ break;
+ case PCI_CHIP_SIS630:
+ pSiS->BusWidth = 64;
+ from = X_INFO;
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Internal error: sis300setup() called with invalid chipset!\n");
+ pSiS->BusWidth = 64;
+ from = X_INFO;
+ }
+
+ inSISIDXREG(SISSR, 0x3A, config);
+ config &= 0x03;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Detected DRAM type: %s\n",
+ dramTypeStr[config+4]);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Detected memory clock: %3.3f MHz\n",
+ pSiS->MemClock/1000.0);
+
+ if(pSiS->Chipset == PCI_CHIP_SIS300) {
+ if(pSiS->ChipRev > 0x13) {
+ inSISIDXREG(SISSR, 0x3A, temp);
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "(Adapter assumes MCLK being %d Mhz)\n",
+ adaptermclk300[(temp & 0x07)]);
+ }
+ } else {
+ inSISIDXREG(SISSR, 0x1A, temp);
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "(Adapter assumes MCLK being %d Mhz)\n",
+ adaptermclk[(temp & 0x07)]);
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "%s DRAM bus width: %d bit\n",
+ (from == X_PROBED) ? "Detected" : "Assuming",
+ pSiS->BusWidth);
+}
+
+/* TW: for 315, 315H, 315PRO, 330 */
+static void
+sis310Setup(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int busSDR[4] = {64, 64, 128, 128};
+ int busDDR[4] = {32, 32, 64, 64};
+ int busDDRA[4] = {64+32, 64+32 , (64+32)*2, (64+32)*2};
+ unsigned int config, config1, config2;
+ char *dramTypeStr310[] = {
+ "Single Channel 1 rank SDR SDRAM",
+ "Single Channel 1 rank SDR SGRAM",
+ "Single Channel 1 rank DDR SDRAM",
+ "Single Channel 1 rank DDR SGRAM",
+ "Single Channel 2 rank SDR SDRAM",
+ "Single Channel 2 rank SDR SGRAM",
+ "Single Channel 2 rank DDR SDRAM",
+ "Single Channel 2 rank DDR SGRAM",
+ "Asymmetric SDR SDRAM",
+ "Asymmetric SDR SGRAM",
+ "Asymmetric DDR SDRAM",
+ "Asymmetric DDR SGRAM",
+ "Dual channel SDR SDRAM",
+ "Dual channel SDR SGRAM",
+ "Dual channel DDR SDRAM",
+ "Dual channel DDR SGRAM"};
+ char *dramTypeStr330[] = {
+ "Single Channel SDR SDRAM",
+ "",
+ "Single Channel DDR SDRAM",
+ "",
+ "--unknown--",
+ "",
+ "--unknown--",
+ "",
+ "Asymetric Dual Channel SDR SDRAM",
+ "",
+ "Asymetric Dual Channel DDR SDRAM",
+ "",
+ "Dual channel SDR SDRAM",
+ "",
+ "Dual channel DDR SDRAM",
+ ""};
+
+ inSISIDXREG(SISSR, 0x14, config);
+ config1 = (config & 0x0C) >> 2;
+ inSISIDXREG(SISSR, 0x3A, config2);
+ config2 &= 0x03;
+
+ pScrn->videoRam = (1 << ((config & 0xF0) >> 4)) * 1024;
+
+ if(pSiS->Chipset == PCI_CHIP_SIS330) {
+
+ if(config1) pScrn->videoRam <<= 1;
+
+ } else {
+
+ /* If SINGLE_CHANNEL_2_RANK or DUAL_CHANNEL_1_RANK -> mem * 2 */
+ if((config1 == 0x01) || (config1 == 0x03))
+ pScrn->videoRam <<= 1;
+
+ /* If DDR asymetric -> mem * 1,5 */
+ if(config1 == 0x02)
+ pScrn->videoRam += pScrn->videoRam/2;
+
+ }
+
+ pSiS->MemClock = SiSMclk(pSiS);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Detected DRAM type: %s\n",
+ (pSiS->Chipset == PCI_CHIP_SIS330) ?
+ dramTypeStr330[(config1 * 4) + (config2 & 0x02)] :
+ dramTypeStr310[(config1 * 4) + config2]);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Detected memory clock: %3.3f MHz\n",
+ pSiS->MemClock/1000.0);
+
+ /* TW: DDR -> mclk * 2 - needed for bandwidth calculation */
+ if(pSiS->Chipset == PCI_CHIP_SIS330) {
+ if(config2 & 0x02) {
+ pSiS->MemClock *= 2;
+ if(config1 == 0x02) {
+ pSiS->BusWidth = busDDRA[0];
+ } else {
+ pSiS->BusWidth = busDDR[(config & 0x02)];
+ }
+ } else {
+ if(config1 == 0x02) {
+ pSiS->BusWidth = busDDRA[2];
+ } else {
+ pSiS->BusWidth = busSDR[(config & 0x02)];
+ }
+ }
+ } else {
+ if(config2 & 0x02) pSiS->MemClock *= 2;
+ if(config1 == 0x02)
+ pSiS->BusWidth = busDDRA[(config & 0x03)];
+ else if(config2 & 0x02)
+ pSiS->BusWidth = busDDR[(config & 0x03)];
+ else
+ pSiS->BusWidth = busSDR[(config & 0x03)];
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Detected DRAM bus width: %d bit\n",
+ pSiS->BusWidth);
+}
+
+/* TW: for 550, 650, 740 */
+static void
+sis550Setup(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ unsigned int config;
+ CARD8 pcimemcode;
+
+ /* TW: Some of the following is guessed; however,
+ since our mode switching code is omniscient
+ anyway, we only need some reasonable values
+ to prevent X from deleting modes from the
+ list
+ */
+
+ inSISIDXREG(SISSR, 0x14, config);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Detected DRAM type: %s\n",
+ dramTypeStr[(((config & 0x80) >> 7) << 2) + 4]);
+
+ pSiS->MemClock = SiSMclk(pSiS);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Detected memory clock: %3.3f MHz\n",
+ pSiS->MemClock/1000.0);
+
+ /* TW: DDR -> Mclk * 2 - needed for bandwidth calculation */
+ if(config & 0x80) pSiS->MemClock *= 2;
+
+ pSiS->BusWidth = (config & 0x40) ? 128 : 64;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Detected DRAM bus width: %d bit\n",
+ pSiS->BusWidth);
+
+ pScrn->videoRam = (((config & 0x3F) + 1) * 4) * 1024;
+
+ /* TW: Some 550 BIOSes don't seem to set SR14 correctly. We have
+ * to read PCI configuration in order to get a correct size.
+ */
+ if (pSiS->Chipset == PCI_CHIP_SIS550) {
+ if((pScrn->videoRam != 4*1024) &&
+ (pScrn->videoRam != 8*1024) &&
+ (pScrn->videoRam != 16*1024) &&
+ (pScrn->videoRam != 24*1024) &&
+ (pScrn->videoRam != 32*1024) &&
+ (pScrn->videoRam != 48*1024) &&
+ (pScrn->videoRam != 64*1024) &&
+ (pScrn->videoRam != 96*1024) &&
+ (pScrn->videoRam != 128*1024) &&
+ (pScrn->videoRam != 256*1024)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Invalid memory size (%d) encountered, reading PCI configuration\n",
+ pScrn->videoRam);
+ pcimemcode = pciReadByte(0x00000000, 0x63);
+ pScrn->videoRam = (1 << (((pcimemcode & 0x70) >> 4) + 21)) / 1024;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "PCI config reported %dKB video RAM\n", pScrn->videoRam);
+ }
+ }
+}
+
+void
+SiSSetup(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+
+ pSiS->Flags = 0;
+ pSiS->VBFlags = 0;
+
+ switch (SISPTR(pScrn)->Chipset) {
+ case PCI_CHIP_SIS5597:
+ case PCI_CHIP_SIS6326:
+ case PCI_CHIP_SIS530:
+ sisOldSetup(pScrn);
+ break;
+ case PCI_CHIP_SIS300:
+ case PCI_CHIP_SIS630: /* +730 */
+ case PCI_CHIP_SIS540:
+ sis300Setup(pScrn);
+ break;
+ case PCI_CHIP_SIS315:
+ case PCI_CHIP_SIS315H:
+ case PCI_CHIP_SIS315PRO:
+ case PCI_CHIP_SIS330:
+ sis310Setup(pScrn);
+ break;
+ case PCI_CHIP_SIS550:
+ case PCI_CHIP_SIS650: /* + 740 */
+ sis550Setup(pScrn);
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Internal error: SiSSetup() called with invalid Chipset (0x%x)\n",
+ pSiS->Chipset);
+ break;
+ }
+}
+
+
diff --git a/src/sis_shadow.c b/src/sis_shadow.c
new file mode 100644
index 0000000..dfc920e
--- /dev/null
+++ b/src/sis_shadow.c
@@ -0,0 +1,250 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_shadow.c,v 1.4 2003/01/29 15:42:17 eich Exp $ */
+/*
+ * Copyright (c) 1999, The XFree86 Project Inc.
+ * based on code written by Mark Vojkovich <markv@valinux.com>
+ *
+ * TW: This module doesn't use CurrentLayout, because it is never
+ * active when DGA is active and vice versa.
+ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86Resources.h"
+#include "xf86_ansic.h"
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+#include "sis.h"
+#include "servermd.h"
+
+#include "sis_shadow.h"
+
+void
+SISRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int width, height, Bpp, FBPitch;
+ unsigned char *src, *dst;
+
+ Bpp = pScrn->bitsPerPixel >> 3;
+ FBPitch = BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel);
+
+ while(num--) {
+ width = (pbox->x2 - pbox->x1) * Bpp;
+ height = pbox->y2 - pbox->y1;
+ src = pSiS->ShadowPtr + (pbox->y1 * pSiS->ShadowPitch) +
+ (pbox->x1 * Bpp);
+ dst = pSiS->FbBase + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp);
+
+ while(height--) {
+ memcpy(dst, src, width);
+ dst += FBPitch;
+ src += pSiS->ShadowPitch;
+ }
+
+ pbox++;
+ }
+}
+
+void
+SISPointerMoved(int index, int x, int y)
+{
+ ScrnInfoPtr pScrn = xf86Screens[index];
+ SISPtr pSiS = SISPTR(pScrn);
+ int newX, newY;
+
+ if(pSiS->Rotate == 1) {
+ newX = pScrn->pScreen->height - y - 1;
+ newY = x;
+ } else {
+ newX = y;
+ newY = pScrn->pScreen->width - x - 1;
+ }
+
+ (*pSiS->PointerMoved)(index, newX, newY);
+}
+
+void
+SISRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int count, width, height, y1, y2, dstPitch, srcPitch;
+ CARD8 *dstPtr, *srcPtr, *src;
+ CARD32 *dst;
+
+ dstPitch = pScrn->displayWidth;
+ srcPitch = -pSiS->Rotate * pSiS->ShadowPitch;
+
+ while(num--) {
+ width = pbox->x2 - pbox->x1;
+ y1 = pbox->y1 & ~3;
+ y2 = (pbox->y2 + 3) & ~3;
+ height = (y2 - y1) >> 2; /* in dwords */
+
+ if(pSiS->Rotate == 1) {
+ dstPtr = pSiS->FbBase +
+ (pbox->x1 * dstPitch) + pScrn->virtualX - y2;
+ srcPtr = pSiS->ShadowPtr + ((1 - y2) * srcPitch) + pbox->x1;
+ } else {
+ dstPtr = pSiS->FbBase +
+ ((pScrn->virtualY - pbox->x2) * dstPitch) + y1;
+ srcPtr = pSiS->ShadowPtr + (y1 * srcPitch) + pbox->x2 - 1;
+ }
+
+ while(width--) {
+ src = srcPtr;
+ dst = (CARD32*)dstPtr;
+ count = height;
+ while(count--) {
+ *(dst++) = src[0] | (src[srcPitch] << 8) |
+ (src[srcPitch * 2] << 16) |
+ (src[srcPitch * 3] << 24);
+ src += srcPitch * 4;
+ }
+ srcPtr += pSiS->Rotate;
+ dstPtr += dstPitch;
+ }
+
+ pbox++;
+ }
+}
+
+
+void
+SISRefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int count, width, height, y1, y2, dstPitch, srcPitch;
+ CARD16 *dstPtr, *srcPtr, *src;
+ CARD32 *dst;
+
+ dstPitch = pScrn->displayWidth;
+ srcPitch = -pSiS->Rotate * pSiS->ShadowPitch >> 1;
+
+ while(num--) {
+ width = pbox->x2 - pbox->x1;
+ y1 = pbox->y1 & ~1;
+ y2 = (pbox->y2 + 1) & ~1;
+ height = (y2 - y1) >> 1; /* in dwords */
+
+ if(pSiS->Rotate == 1) {
+ dstPtr = (CARD16*)pSiS->FbBase +
+ (pbox->x1 * dstPitch) + pScrn->virtualX - y2;
+ srcPtr = (CARD16*)pSiS->ShadowPtr +
+ ((1 - y2) * srcPitch) + pbox->x1;
+ } else {
+ dstPtr = (CARD16*)pSiS->FbBase +
+ ((pScrn->virtualY - pbox->x2) * dstPitch) + y1;
+ srcPtr = (CARD16*)pSiS->ShadowPtr +
+ (y1 * srcPitch) + pbox->x2 - 1;
+ }
+
+ while(width--) {
+ src = srcPtr;
+ dst = (CARD32*)dstPtr;
+ count = height;
+ while(count--) {
+ *(dst++) = src[0] | (src[srcPitch] << 16);
+ src += srcPitch * 2;
+ }
+ srcPtr += pSiS->Rotate;
+ dstPtr += dstPitch;
+ }
+
+ pbox++;
+ }
+}
+
+
+/* this one could be faster */
+void
+SISRefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int count, width, height, y1, y2, dstPitch, srcPitch;
+ CARD8 *dstPtr, *srcPtr, *src;
+ CARD32 *dst;
+
+ dstPitch = BitmapBytePad(pScrn->displayWidth * 24);
+ srcPitch = -pSiS->Rotate * pSiS->ShadowPitch;
+
+ while(num--) {
+ width = pbox->x2 - pbox->x1;
+ y1 = pbox->y1 & ~3;
+ y2 = (pbox->y2 + 3) & ~3;
+ height = (y2 - y1) >> 2; /* blocks of 3 dwords */
+
+ if(pSiS->Rotate == 1) {
+ dstPtr = pSiS->FbBase +
+ (pbox->x1 * dstPitch) + ((pScrn->virtualX - y2) * 3);
+ srcPtr = pSiS->ShadowPtr + ((1 - y2) * srcPitch) + (pbox->x1 * 3);
+ } else {
+ dstPtr = pSiS->FbBase +
+ ((pScrn->virtualY - pbox->x2) * dstPitch) + (y1 * 3);
+ srcPtr = pSiS->ShadowPtr + (y1 * srcPitch) + (pbox->x2 * 3) - 3;
+ }
+
+ while(width--) {
+ src = srcPtr;
+ dst = (CARD32*)dstPtr;
+ count = height;
+ while(count--) {
+ dst[0] = src[0] | (src[1] << 8) | (src[2] << 16) |
+ (src[srcPitch] << 24);
+ dst[1] = src[srcPitch + 1] | (src[srcPitch + 2] << 8) |
+ (src[srcPitch * 2] << 16) |
+ (src[(srcPitch * 2) + 1] << 24);
+ dst[2] = src[(srcPitch * 2) + 2] | (src[srcPitch * 3] << 8) |
+ (src[(srcPitch * 3) + 1] << 16) |
+ (src[(srcPitch * 3) + 2] << 24);
+ dst += 3;
+ src += srcPitch * 4;
+ }
+ srcPtr += pSiS->Rotate * 3;
+ dstPtr += dstPitch;
+ }
+
+ pbox++;
+ }
+}
+
+void
+SISRefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int count, width, height, dstPitch, srcPitch;
+ CARD32 *dstPtr, *srcPtr, *src, *dst;
+
+ dstPitch = pScrn->displayWidth;
+ srcPitch = -pSiS->Rotate * pSiS->ShadowPitch >> 2;
+
+ while(num--) {
+ width = pbox->x2 - pbox->x1;
+ height = pbox->y2 - pbox->y1;
+
+ if(pSiS->Rotate == 1) {
+ dstPtr = (CARD32*)pSiS->FbBase +
+ (pbox->x1 * dstPitch) + pScrn->virtualX - pbox->y2;
+ srcPtr = (CARD32*)pSiS->ShadowPtr +
+ ((1 - pbox->y2) * srcPitch) + pbox->x1;
+ } else {
+ dstPtr = (CARD32*)pSiS->FbBase +
+ ((pScrn->virtualY - pbox->x2) * dstPitch) + pbox->y1;
+ srcPtr = (CARD32*)pSiS->ShadowPtr +
+ (pbox->y1 * srcPitch) + pbox->x2 - 1;
+ }
+
+ while(width--) {
+ src = srcPtr;
+ dst = dstPtr;
+ count = height;
+ while(count--) {
+ *(dst++) = *src;
+ src += srcPitch;
+ }
+ srcPtr += pSiS->Rotate;
+ dstPtr += dstPitch;
+ }
+
+ pbox++;
+ }
+}
diff --git a/src/sis_vb.c b/src/sis_vb.c
new file mode 100644
index 0000000..d8ed114
--- /dev/null
+++ b/src/sis_vb.c
@@ -0,0 +1,353 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_vb.c,v 1.10 2003/01/29 15:42:17 eich Exp $ */
+/*
+ * Video bridge detection and configuration for 300 and 310/325 series
+ *
+ * Copyright 2002 by Thomas Winischhofer, Vienna, Austria
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Thomas Winischhofer not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Thomas Winischhofer makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THOMAS WINISCHHOFER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THOMAS WINISCHHOFER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Thomas Winischhofer <thomas@winischhofer.net>
+ * (Completely rewritten)
+ */
+
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "compiler.h"
+#include "xf86PciInfo.h"
+
+#include "sis.h"
+#include "sis_regs.h"
+#include "sis_vb.h"
+
+static const SiS_LCD_StStruct SiS300_LCD_Type[]=
+{
+ { VB_LCD_1024x768, 1024, 768, LCD_1024x768, 1}, /* 0 - invalid */
+ { VB_LCD_800x600, 800, 600, LCD_800x600, 0}, /* 1 */
+ { VB_LCD_1024x768, 1024, 768, LCD_1024x768, 1}, /* 2 */
+ { VB_LCD_1280x1024,1280, 1024, LCD_1280x1024, 2}, /* 3 */
+ { VB_LCD_1280x960, 1280, 960, LCD_1280x960, 3}, /* 4 */
+ { VB_LCD_640x480, 640, 480, LCD_640x480, 4}, /* 5 */
+ { VB_LCD_1024x600, 1024, 600, LCD_1024x600, 10}, /* 6 */
+ { VB_LCD_1152x768, 1152, 768, LCD_1152x768, 7}, /* 7 */
+ { VB_LCD_320x480, 320, 480, LCD_320x480, 6}, /* 8 */
+ { VB_LCD_1024x768, 1024, 768, LCD_1024x768, 1}, /* 9 */
+ { VB_LCD_1024x768, 1024, 768, LCD_1024x768, 1}, /* a */
+ { VB_LCD_1024x768, 1024, 768, LCD_1024x768, 1}, /* b */
+ { VB_LCD_1024x768, 1024, 768, LCD_1024x768, 1}, /* c */
+ { VB_LCD_1024x768, 1024, 768, LCD_1024x768, 1}, /* d */
+ { VB_LCD_1024x768, 1024, 768, LCD_1024x768, 1}, /* e */
+ { VB_LCD_1024x768, 1024, 768, LCD_1024x768, 1}, /* f */
+};
+
+static const SiS_LCD_StStruct SiS310_LCD_Type[]=
+{
+ { VB_LCD_1024x768, 1024, 768, LCD_1024x768, 1}, /* 0 - invalid */
+ { VB_LCD_800x600, 800, 600, LCD_800x600, 0}, /* 1 */
+ { VB_LCD_1024x768, 1024, 768, LCD_1024x768, 1}, /* 2 */
+ { VB_LCD_1280x1024, 1280,1024, LCD_1280x1024, 2}, /* 3 */
+ { VB_LCD_640x480, 640, 480, LCD_640x480, 4}, /* 4 */
+ { VB_LCD_1024x600, 1024, 600, LCD_1024x600, 10}, /* 5 */
+ { VB_LCD_1152x864, 1152, 864, LCD_1152x864, 11}, /* 6 */
+ { VB_LCD_1280x960, 1280, 960, LCD_1280x960, 3}, /* 7 */
+ { VB_LCD_1152x768, 1152, 768, LCD_1152x768, 7}, /* 8 */
+ { VB_LCD_1400x1050, 1400,1050, LCD_1400x1050, 8}, /* 9 */
+ { VB_LCD_1280x768, 1280, 768, LCD_1280x768, 9}, /* a */
+ { VB_LCD_1600x1200, 1600,1200, LCD_1600x1200, 5}, /* b */
+ { VB_LCD_320x480, 320, 480, LCD_320x480, 6}, /* c */
+ { VB_LCD_1024x768, 1024, 768, LCD_1024x768, 1}, /* d */
+ { VB_LCD_1024x768, 1024, 768, LCD_1024x768, 1}, /* e */
+ { VB_LCD_1024x768, 1024, 768, LCD_1024x768, 1} /* f */
+};
+
+static const char *panelres[] = {
+ "800x600",
+ "1024x768",
+ "1280x1024",
+ "1280x960",
+ "640x480",
+ "1600x1200",
+ "320x480",
+ "1152x768",
+ "1400x1050",
+ "1280x768",
+ "1024x600",
+ "1152x864"
+};
+
+/* Detect CRT1 */
+void SISCRT1PreInit(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ unsigned char CR32, SR17;
+ unsigned char CRT1Detected = 0;
+ unsigned char OtherDevices = 0;
+
+ if(!(pSiS->VBFlags & VB_VIDEOBRIDGE)) {
+ pSiS->CRT1off = 0;
+ return;
+ }
+
+#ifdef SISDUALHEAD
+ if(pSiS->DualHeadMode && pSiS->SecondHead) {
+ pSiS->CRT1off = 0;
+ return;
+ }
+#endif
+
+ inSISIDXREG(SISCR, 0x32, CR32);
+ inSISIDXREG(SISSR, 0x17, SR17);
+
+ if ( (pSiS->VGAEngine == SIS_300_VGA) &&
+ (pSiS->Chipset != PCI_CHIP_SIS300) &&
+ (SR17 & 0x0F) ) {
+
+ if(SR17 & 0x01) CRT1Detected = 1;
+ if(SR17 & 0x0E) OtherDevices = 1;
+
+ } else {
+
+ if(CR32 & 0x20) CRT1Detected = 1;
+ if(CR32 & 0x5F) OtherDevices = 1;
+
+ }
+
+ if(pSiS->CRT1off == -1) {
+ if(!CRT1Detected) {
+
+ /* BIOS detected no CRT1. */
+ /* If other devices exist, switch it off */
+ if(OtherDevices) pSiS->CRT1off = 1;
+ else pSiS->CRT1off = 0;
+
+ } else {
+
+ /* BIOS detected CRT1, leave/switch it on */
+ pSiS->CRT1off = 0;
+
+ }
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "%sCRT1 connection detected\n",
+ CRT1Detected ? "" : "No ");
+}
+
+/* Detect CRT2-LCD and LCD size */
+void SISLCDPreInit(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ unsigned char CR32, SR17, CR36, CR37;
+ USHORT textindex;
+
+ if(!(pSiS->VBFlags & VB_VIDEOBRIDGE)) {
+ return;
+ }
+
+ inSISIDXREG(SISCR, 0x32, CR32);
+ inSISIDXREG(SISSR, 0x17, SR17);
+
+ if( (pSiS->VGAEngine == SIS_300_VGA) &&
+ (pSiS->Chipset != PCI_CHIP_SIS300) &&
+ (SR17 & 0x0F) ) {
+ if(SR17 & 0x02)
+ pSiS->VBFlags |= CRT2_LCD;
+ } else {
+ if(CR32 & 0x08)
+ pSiS->VBFlags |= CRT2_LCD;
+ }
+
+ if(pSiS->VBFlags & CRT2_LCD) {
+ inSISIDXREG(SISCR, 0x36, CR36);
+ inSISIDXREG(SISCR, 0x37, CR37);
+ if((pSiS->VGAEngine == SIS_315_VGA) && (!CR36)) {
+ /* TW: Old 650/301LV BIOS version "forgot" to set CR36, CR37 */
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "BIOS-provided LCD information invalid, probing myself...\n");
+ if(pSiS->VBFlags & VB_LVDS) pSiS->SiS_Pr->SiS_IF_DEF_LVDS = 1;
+ else pSiS->SiS_Pr->SiS_IF_DEF_LVDS = 0;
+ SiS_GetPanelID(pSiS->SiS_Pr, &pSiS->sishw_ext);
+ inSISIDXREG(SISCR, 0x36, CR36);
+ inSISIDXREG(SISCR, 0x37, CR37);
+ }
+ if(pSiS->VGAEngine == SIS_300_VGA) {
+ pSiS->VBLCDFlags |= SiS300_LCD_Type[(CR36 & 0x0f)].VBLCD_lcdflag;
+ pSiS->LCDheight = SiS300_LCD_Type[(CR36 & 0x0f)].LCDheight;
+ pSiS->LCDwidth = SiS300_LCD_Type[(CR36 & 0x0f)].LCDwidth;
+ pSiS->sishw_ext.ulCRT2LCDType = SiS300_LCD_Type[(CR36 & 0x0f)].LCDtype;
+ textindex = SiS300_LCD_Type[(CR36 & 0x0f)].LCDrestextindex;
+ } else {
+ pSiS->VBLCDFlags |= SiS310_LCD_Type[(CR36 & 0x0f)].VBLCD_lcdflag;
+ pSiS->LCDheight = SiS310_LCD_Type[(CR36 & 0x0f)].LCDheight;
+ pSiS->LCDwidth = SiS310_LCD_Type[(CR36 & 0x0f)].LCDwidth;
+ pSiS->sishw_ext.ulCRT2LCDType = SiS310_LCD_Type[(CR36 & 0x0f)].LCDtype;
+ textindex = SiS310_LCD_Type[(CR36 & 0x0f)].LCDrestextindex;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Detected LCD panel resolution %s (type %d, %s%s)\n",
+ panelres[textindex],
+ (pSiS->VGAEngine == SIS_315_VGA) ? ((CR36 & 0x0f) - 1) : ((CR36 & 0xf0) >> 4),
+ (pSiS->VBFlags & VB_LVDS) ?
+ (CR37 & 0x10 ? "non-expanding, " : "expanding, ") :
+ ( ((pSiS->VBFlags & VB_301B) && (pSiS->VGAEngine == SIS_300_VGA)) ?
+ (CR37 & 0x10 ? "non-expanding, " : "expanding, ") :
+ (CR37 & 0x10 ? "self-scaling, " : "non-self-scaling, ") ),
+ CR37 & 0x01 ? "RGB18" : "RGB24");
+ }
+}
+
+/* Detect CRT2-TV connector type and PAL/NTSC flag */
+void SISTVPreInit(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ unsigned char SR16, SR17, SR38, CR32, CR38=0, CR79;
+ int temp = 0;
+
+ if(!(pSiS->VBFlags & VB_VIDEOBRIDGE))
+ return;
+
+ inSISIDXREG(SISCR, 0x32, CR32);
+ inSISIDXREG(SISSR, 0x17, SR17);
+ inSISIDXREG(SISSR, 0x16, SR16);
+ inSISIDXREG(SISSR, 0x38, SR38);
+ switch(pSiS->VGAEngine) {
+ case SIS_300_VGA:
+ if(pSiS->Chipset != PCI_CHIP_SIS300) temp = 0x35;
+ break;
+ case SIS_315_VGA:
+ temp = 0x38;
+ break;
+ }
+ if(temp) {
+ inSISIDXREG(SISCR, temp, CR38);
+ }
+
+#ifdef TWDEBUG
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "(vb.c: SR17=%02x CR32=%02x)\n", SR17, CR32);
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "(vb.c: SR16=%02x SR38=%02x)\n", SR16, SR38);
+#endif
+
+ if( (pSiS->VGAEngine == SIS_300_VGA) &&
+ (pSiS->Chipset != PCI_CHIP_SIS300) &&
+ (SR17 & 0x0F) ) {
+
+ if(SR17 & 0x04)
+ pSiS->VBFlags |= CRT2_TV;
+
+ if(SR17 & 0x20)
+ pSiS->VBFlags |= TV_SVIDEO;
+ else if (SR17 & 0x10)
+ pSiS->VBFlags |= TV_AVIDEO;
+
+ if(pSiS->VBFlags & (TV_SVIDEO | TV_AVIDEO)) {
+ if(SR16 & 0x20)
+ pSiS->VBFlags |= TV_PAL;
+ else
+ pSiS->VBFlags |= TV_NTSC;
+ }
+
+ } else {
+
+ if(CR32 & 0x47)
+ pSiS->VBFlags |= CRT2_TV;
+
+ if(CR32 & 0x04)
+ pSiS->VBFlags |= TV_SCART;
+ else if(CR32 & 0x02)
+ pSiS->VBFlags |= TV_SVIDEO;
+ else if(CR32 & 0x01)
+ pSiS->VBFlags |= TV_AVIDEO;
+ else if(CR32 & 0x40)
+ pSiS->VBFlags |= (TV_SVIDEO | TV_HIVISION);
+ else if((CR38 & 0x04) && (pSiS->VBFlags & VB_CHRONTEL))
+ pSiS->VBFlags |= (TV_CHSCART | TV_PAL);
+ else if((CR38 & 0x08) && (pSiS->VBFlags & VB_CHRONTEL))
+ pSiS->VBFlags |= (TV_CHHDTV | TV_NTSC);
+
+ if(pSiS->VBFlags & (TV_SCART | TV_SVIDEO | TV_AVIDEO | TV_HIVISION)) {
+ if( (pSiS->Chipset == PCI_CHIP_SIS550) || /* TW: ? */
+ (pSiS->Chipset == PCI_CHIP_SIS650) ) {
+ inSISIDXREG(SISCR, 0x79, CR79);
+ if(CR79 & 0x20) {
+ pSiS->VBFlags |= TV_PAL;
+ if(CR38 & 0x40) pSiS->VBFlags |= TV_PALM;
+ else if(CR38 & 0x80) pSiS->VBFlags |= TV_PALN;
+ } else
+ pSiS->VBFlags |= TV_NTSC;
+ } else if(pSiS->VGAEngine == SIS_300_VGA) {
+ /* TW: Should be SR38 here as well, but this
+ * does not work. Looks like a BIOS bug (2.04.5c).
+ */
+ if(SR16 & 0x20)
+ pSiS->VBFlags |= TV_PAL;
+ else
+ pSiS->VBFlags |= TV_NTSC;
+ } else { /* 315, 330 */
+ if(SR38 & 0x01) {
+ pSiS->VBFlags |= TV_PAL;
+ if(CR38 & 0x40) pSiS->VBFlags |= TV_PALM;
+ else if(CR38 & 0x80) pSiS->VBFlags |= TV_PALN;
+ } else
+ pSiS->VBFlags |= TV_NTSC;
+ }
+ }
+ }
+ if(pSiS->VBFlags & (TV_SCART | TV_SVIDEO | TV_AVIDEO | TV_HIVISION | TV_CHSCART | TV_CHHDTV)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "%sTV standard %s\n",
+ (pSiS->VBFlags & (TV_CHSCART | TV_CHHDTV)) ? "Using " : "Detected default ",
+ (pSiS->VBFlags & TV_NTSC) ?
+ ((pSiS->VBFlags & TV_CHHDTV) ? "480i HDTV" : "NTSC") :
+ ((pSiS->VBFlags & TV_PALM) ? "PALM" :
+ ((pSiS->VBFlags & TV_PALN) ? "PALN" : "PAL")));
+ }
+}
+
+/* Detect CRT2-VGA */
+void SISCRT2PreInit(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ unsigned char SR17, CR32;
+
+ if (!(pSiS->VBFlags & VB_VIDEOBRIDGE))
+ return;
+
+ /* CRT2-VGA not supported on LVDS and 30xLV(X) */
+ if (pSiS->VBFlags & (VB_LVDS|VB_30xLV|VB_30xLVX))
+ return;
+
+ inSISIDXREG(SISCR, 0x32, CR32);
+ inSISIDXREG(SISSR, 0x17, SR17);
+
+ if( (pSiS->VGAEngine == SIS_300_VGA) &&
+ (pSiS->Chipset != PCI_CHIP_SIS300) &&
+ (SR17 & 0x0F) ) {
+
+ if(SR17 & 0x08)
+ pSiS->VBFlags |= CRT2_VGA;
+
+ } else {
+
+ if(CR32 & 0x10)
+ pSiS->VBFlags |= CRT2_VGA;
+
+ }
+}
+
+
+
diff --git a/src/sis_vga.c b/src/sis_vga.c
new file mode 100644
index 0000000..0ab8b8d
--- /dev/null
+++ b/src/sis_vga.c
@@ -0,0 +1,1535 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_vga.c,v 1.16 2003/01/29 15:42:17 eich Exp $ */
+/*
+ * Mode setup and video bridge detection
+ *
+ * Copyright 1998,1999 by Alan Hourihane, Wigan, England.
+ * Parts Copyright 2001, 2002 by Thomas Winischhofer, Vienna, Austria.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the copyright holder not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The copyright holder makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, alanh@fairlite.demon.co.uk
+ * Mike Chapman <mike@paranoia.com>,
+ * Juanjo Santamarta <santamarta@ctv.es>,
+ * Mitani Hiroshi <hmitani@drl.mei.co.jp>
+ * David Thomas <davtom@dream.org.uk>.
+ * Thomas Winischhofer <thomas@winischhofer.net>
+ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "xf86Version.h"
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+#include "sis.h"
+#include "sis_regs.h"
+#include "sis_dac.h"
+
+#define Midx 0
+#define Nidx 1
+#define VLDidx 2
+#define Pidx 3
+#define PSNidx 4
+#define Fref 14318180
+/* stability constraints for internal VCO -- MAX_VCO also determines
+ * the maximum Video pixel clock */
+#define MIN_VCO Fref
+#define MAX_VCO 135000000
+#define MAX_VCO_5597 353000000
+#define MAX_PSN 0 /* no pre scaler for this chip */
+#define TOLERANCE 0.01 /* search smallest M and N in this tolerance */
+
+
+static Bool SISInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
+static Bool SIS300Init(ScrnInfoPtr pScrn, DisplayModePtr mode);
+/* TW: To be used internally only */
+int SISDoSense(ScrnInfoPtr pScrn, int tempbl, int tempbh, int tempcl, int tempch);
+void SISSense30x(ScrnInfoPtr pScrn);
+int SIS6326DoSense(ScrnInfoPtr pScrn, int tempbh, int tempbl, int tempch, int tempcl);
+void SISSense6326(ScrnInfoPtr pScrn);
+static void SiS6326TVDelay(ScrnInfoPtr pScrn, int delay);
+
+const CARD8 SiS6326TVRegs1_NTSC[6][14] = {
+ {0x81,0x3f,0x49,0x1b,0xa9,0x03,0x00,0x09,0x08,0x7d,0x00,0x88,0x30,0x60},
+ {0x81,0x3f,0x49,0x1d,0xa0,0x03,0x00,0x09,0x08,0x7d,0x00,0x88,0x30,0x60},
+ {0x81,0x45,0x24,0x8e,0x26,0x0b,0x00,0x09,0x02,0xfe,0x00,0x09,0x51,0x60},
+ {0x81,0x45,0x24,0x8e,0x26,0x07,0x00,0x29,0x04,0x30,0x10,0x3b,0x61,0x60},
+ {0x81,0x3f,0x24,0x8e,0x26,0x09,0x00,0x09,0x02,0x30,0x10,0x3b,0x51,0x60},
+ {0x83,0x5d,0x21,0xbe,0x75,0x03,0x00,0x09,0x08,0x42,0x10,0x4d,0x61,0x79} /* 640x480u */
+};
+
+const CARD8 SiS6326TVRegs2_NTSC[6][54] = {
+ {0x11, 0x17, 0x03, 0x09, 0x94, 0x02, 0x05, 0x06, 0x09, 0x50, 0x0C,
+ 0x0C, 0x06, 0x0D, 0x04, 0x0A, 0x94, 0x06, 0x0D, 0x04, 0x0A, 0x94,
+ 0xFC, 0xDF, 0x94, 0x1F, 0x4A, 0x03, 0x71, 0x07, 0x97, 0x10, 0x40,
+ 0x48, 0x00, 0x26, 0xB6, 0x10, 0x5C, 0xEC, 0x21, 0x2E, 0xBE, 0x10,
+ 0x64, 0xF4, 0x21, 0x13, 0x75, 0x08, 0x31, 0x6A, 0x01, 0xA0},
+ {0x11, 0x17, 0x03, 0x0A, 0x94, 0x02, 0x05, 0x06, 0x09, 0x50, 0x0C,
+ 0x0D, 0x06, 0x0D, 0x04, 0x0A, 0x94, 0x06, 0x0D, 0x04, 0x0A, 0x94,
+ 0xFF, 0xDF, 0x94, 0x1F, 0x4A, 0x03, 0x71, 0x07, 0x97, 0x10, 0x40,
+ 0x48, 0x00, 0x26, 0xB6, 0x10, 0x5C, 0xEC, 0x21, 0x2E, 0xBE, 0x10,
+ 0x64, 0xF4, 0x21, 0x13, 0x75, 0x08, 0x31, 0x6A, 0x01, 0xA0},
+ {0x11, 0x17, 0x03, 0x0A, 0x94, 0x02, 0x05, 0x06, 0x09, 0x50, 0x0C,
+ 0x0D, 0x06, 0x0D, 0x04, 0x0A, 0x94, 0x06, 0x0D, 0x04, 0x0A, 0x94,
+ 0xFF, 0xDF, 0x94, 0x3F, 0x8C, 0x06, 0xCE, 0x07, 0x27, 0x30, 0x73,
+ 0x7B, 0x00, 0x48, 0x68, 0x30, 0xB2, 0xD2, 0x52, 0x50, 0x70, 0x30,
+ 0xBA, 0xDA, 0x52, 0xDC, 0x02, 0xD1, 0x53, 0xF7, 0x02, 0xA0},
+ {0x11, 0x17, 0x03, 0x09, 0x94, 0x02, 0x05, 0x06, 0x09, 0x50, 0x0C,
+ 0x0C, 0x06, 0x0D, 0x04, 0x0A, 0x94, 0x06, 0x0D, 0x04, 0x0A, 0x94,
+ 0xDC, 0xDF, 0x94, 0x3F, 0x8C, 0x06, 0xCE, 0x07, 0x27, 0x30, 0x73,
+ 0x7B, 0x00, 0x48, 0x68, 0x30, 0xB2, 0xD2, 0x52, 0x50, 0x70, 0x30,
+ 0xBA, 0xDA, 0x52, 0x00, 0x02, 0xF5, 0x53, 0xF7, 0x02, 0xA0},
+ {0x11, 0x17, 0x03, 0x09, 0x94, 0x02, 0x05, 0x06, 0x09, 0x50, 0x0C,
+ 0x0C, 0x06, 0x0D, 0x04, 0x0A, 0x94, 0x06, 0x0D, 0x04, 0x0A, 0x94,
+ 0xDC, 0xDF, 0x94, 0x3F, 0x8C, 0x06, 0xCE, 0x07, 0x27, 0x30, 0x73,
+ 0x7B, 0x00, 0x48, 0x68, 0x30, 0xB2, 0xD2, 0x52, 0x50, 0x70, 0x30,
+ 0xBA, 0xDA, 0x52, 0xDC, 0x02, 0xD1, 0x53, 0xF7, 0x02, 0xA0},
+ {0x11, 0x17, 0x03, 0x09, 0x94, 0x02, 0x05, 0x06, 0x09, 0x50, 0x0C, /* 640x480u */
+ 0x0C, 0x06, 0x0D, 0x04, 0x0A, 0x94, 0x06, 0x0D, 0x04, 0x0A, 0x94,
+ 0xDC, 0xDF, 0x94, 0xAF, 0x95, 0x06, 0xDD, 0x07, 0x5F, 0x30, 0x7E,
+ 0x86, 0x00, 0x4C, 0xA4, 0x30, 0xE3, 0x3B, 0x62, 0x54, 0xAC, 0x30,
+ 0xEB, 0x43, 0x62, 0x48, 0x34, 0x3D, 0x63, 0x29, 0x03, 0xA0}
+};
+
+const CARD8 SiS6326TVRegs1_PAL[6][14] = {
+ {0x81,0x2d,0xc8,0x07,0xb2,0x0b,0x00,0x09,0x02,0xed,0x00,0xf8,0x30,0x40},
+ {0x80,0x2d,0xa4,0x03,0xd9,0x0b,0x00,0x09,0x02,0xed,0x10,0xf8,0x71,0x40},
+ {0x81,0x2d,0xa4,0x03,0xd9,0x0b,0x00,0x09,0x02,0xed,0x10,0xf8,0x71,0x40},
+ {0x81,0x2d,0xa4,0x03,0xd9,0x0b,0x00,0x09,0x02,0x8f,0x10,0x9a,0x71,0x40},
+ {0x83,0x63,0xa1,0x7a,0xa3,0x0a,0x00,0x09,0x02,0xb5,0x11,0xc0,0x81,0x59}, /* 800x600u */
+ {0x81,0x63,0xa4,0x03,0xd9,0x01,0x00,0x09,0x10,0x9f,0x10,0xaa,0x71,0x59} /* 720x540 */
+};
+
+const CARD8 SiS6326TVRegs2_PAL[6][54] = {
+ {0x15, 0x4E, 0x35, 0x6E, 0x94, 0x02, 0x04, 0x38, 0x3A, 0x50, 0x3D,
+ 0x70, 0x06, 0x3E, 0x35, 0x6D, 0x94, 0x05, 0x3F, 0x36, 0x6E, 0x94,
+ 0xE5, 0xDF, 0x94, 0xEF, 0x5A, 0x03, 0x7F, 0x07, 0xFF, 0x10, 0x4E,
+ 0x56, 0x00, 0x2B, 0x23, 0x20, 0xB4, 0xAC, 0x31, 0x33, 0x2B, 0x20,
+ 0xBC, 0xB4, 0x31, 0x83, 0xE1, 0x78, 0x31, 0xD6, 0x01, 0xA0},
+ {0x15, 0x4E, 0x35, 0x6E, 0x94, 0x02, 0x04, 0x38, 0x3A, 0x50, 0x3D,
+ 0x70, 0x06, 0x3E, 0x35, 0x6D, 0x94, 0x05, 0x3F, 0x36, 0x6E, 0x94,
+ 0xE5, 0xDF, 0x94, 0xDF, 0xB2, 0x07, 0xFB, 0x07, 0xF7, 0x30, 0x90,
+ 0x98, 0x00, 0x4F, 0x3F, 0x40, 0x62, 0x52, 0x73, 0x57, 0x47, 0x40,
+ 0x6A, 0x5A, 0x73, 0x03, 0xC1, 0xF8, 0x63, 0xB6, 0x03, 0xA0},
+ {0x15, 0x4E, 0x35, 0x6E, 0x94, 0x02, 0x04, 0x38, 0x3A, 0x50, 0x3D,
+ 0x70, 0x06, 0x3E, 0x35, 0x6D, 0x94, 0x05, 0x3F, 0x36, 0x6E, 0x94,
+ 0xE5, 0xDF, 0x94, 0xDF, 0xB2, 0x07, 0xFB, 0x07, 0xF7, 0x30, 0x90,
+ 0x98, 0x00, 0x4F, 0x3F, 0x40, 0x62, 0x52, 0x73, 0x57, 0x47, 0x40,
+ 0x6A, 0x5A, 0x73, 0x03, 0xC1, 0xF8, 0x63, 0xB6, 0x03, 0xA0},
+ {0x15, 0x4E, 0x35, 0x6E, 0x94, 0x02, 0x04, 0x38, 0x3A, 0x50, 0x3D,
+ 0x70, 0x06, 0x3E, 0x35, 0x6D, 0x94, 0x05, 0x3F, 0x36, 0x6E, 0x94,
+ 0xE5, 0xDF, 0x94, 0xDF, 0xB2, 0x07, 0xFB, 0x07, 0xF7, 0x30, 0x90,
+ 0x98, 0x00, 0x4F, 0x3F, 0x40, 0x62, 0x52, 0x73, 0x57, 0x47, 0x40,
+ 0x6A, 0x5A, 0x73, 0xA0, 0xC1, 0x95, 0x73, 0xB6, 0x03, 0xA0},
+ {0x15, 0x4E, 0x35, 0x6E, 0x94, 0x02, 0x04, 0x38, 0x3A, 0x50, 0x3D, /* 800x600u */
+ 0x70, 0x06, 0x3E, 0x35, 0x6D, 0x94, 0x05, 0x3F, 0x36, 0x6E, 0x94,
+ 0xE5, 0xDF, 0x94, 0x7F, 0xBD, 0x08, 0x0E, 0x07, 0x47, 0x40, 0x9D,
+ 0xA5, 0x00, 0x54, 0x94, 0x40, 0xA4, 0xE4, 0x73, 0x5C, 0x9C, 0x40,
+ 0xAC, 0xEC, 0x73, 0x0B, 0x0E, 0x00, 0x84, 0x03, 0x04, 0xA0},
+ {0x15, 0x4E, 0x35, 0x6E, 0x94, 0x02, 0x04, 0x38, 0x3A, 0x50, 0x3D, /* 720x540 */
+ 0x70, 0x06, 0x3E, 0x35, 0x6D, 0x94, 0x05, 0x3F, 0x36, 0x6E, 0x94,
+ 0xE5, 0xDF, 0x94, 0xDF, 0xB0, 0x07, 0xFB, 0x07, 0xF7, 0x30, 0x9D,
+ 0xA5, 0x00, 0x4F, 0x3F, 0x40, 0x62, 0x52, 0x73, 0x57, 0x47, 0x40,
+ 0x6A, 0x5A, 0x73, 0xA0, 0xC1, 0x95, 0x73, 0xB6, 0x03, 0xA0}
+};
+
+const CARD8 SiS6326TVRegs1[14] = {
+ 0x00,0x01,0x02,0x03,0x04,0x11,0x12,0x13,0x21,0x26,0x27,0x3a,0x3c,0x43
+};
+
+const CARD8 SiS6326CR[9][15] = {
+ {0x79,0x63,0x64,0x1d,0x6a,0x93,0x00,0x6f,0xf0,0x58,0x8a,0x57,0x57,0x70,0x20}, /* PAL 800x600 */
+ {0x79,0x4f,0x50,0x95,0x60,0x93,0x00,0x6f,0xba,0x14,0x86,0xdf,0xe0,0x30,0x00}, /* PAL 640x480 */
+ {0x5f,0x4f,0x50,0x82,0x53,0x9f,0x00,0x0b,0x3e,0xe9,0x8b,0xdf,0xe7,0x04,0x00}, /* NTSC 640x480 */
+ {0x5f,0x4f,0x50,0x82,0x53,0x9f,0x00,0x0b,0x3e,0xcb,0x8d,0x8f,0x96,0xe9,0x00}, /* NTSC 640x400 */
+ {0x83,0x63,0x64,0x1f,0x6d,0x9b,0x00,0x6f,0xf0,0x48,0x0a,0x23,0x57,0x70,0x20}, /* PAL 800x600u */
+ {0x79,0x59,0x5b,0x1d,0x66,0x93,0x00,0x6f,0xf0,0x42,0x04,0x1b,0x40,0x70,0x20}, /* PAL 720x540 */
+ {0x66,0x4f,0x51,0x0a,0x57,0x89,0x00,0x0b,0x3e,0xd9,0x0b,0xb6,0xe7,0x04,0x00}, /* NTSC 640x480u */
+ {0xce,0x9f,0x9f,0x92,0xa4,0x16,0x00,0x28,0x5a,0x00,0x04,0xff,0xff,0x29,0x39}, /* 1280x1024-75 */
+ {0x09,0xc7,0xc7,0x0d,0xd2,0x0a,0x01,0xe0,0x10,0xb0,0x04,0xaf,0xaf,0xe1,0x1f} /* 1600x1200-60 */
+};
+
+/* Initialize a display mode on 5597/5598, 6326 and 530/620 */
+static Bool
+SISInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ SISRegPtr pReg = &pSiS->ModeReg;
+ vgaRegPtr vgaReg = &VGAHWPTR(pScrn)->ModeReg;
+ unsigned char temp;
+ int mclk = pSiS->MemClock;
+ int offset;
+ int clock = mode->Clock;
+ int width = mode->HDisplay;
+ int height = mode->VDisplay;
+ int rate = SiSCalcVRate(mode);
+ int buswidth = pSiS->BusWidth;
+ unsigned int vclk[5];
+ unsigned short CRT_CPUthresholdLow;
+ unsigned short CRT_CPUthresholdHigh;
+ unsigned short CRT_ENGthreshold;
+ double a, b, c;
+ int d, factor;
+ int num, denum, div, sbit, scale;
+ BOOL sis6326tvmode, sis6326himode;
+
+ PDEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "SISInit()\n"));
+
+ /* Save the registers for further processing */
+ (*pSiS->SiSSave)(pScrn, pReg);
+
+ /* TW: Determine if chosen mode is suitable for TV on the 6326
+ and if the mode is one of our special hi-res modes.
+ */
+ sis6326tvmode = FALSE;
+ sis6326himode = FALSE;
+ if(pSiS->Chipset == PCI_CHIP_SIS6326) {
+ if(pSiS->SiS6326Flags & SIS6326_HASTV) {
+ if((pSiS->SiS6326Flags & SIS6326_TVDETECTED) &&
+ ((strcmp(mode->name, "PAL800x600") == 0) || /* TW: Special TV modes */
+ (strcmp(mode->name, "PAL800x600U") == 0) ||
+ (strcmp(mode->name, "PAL720x540") == 0) ||
+ (strcmp(mode->name, "PAL640x480") == 0) ||
+ (strcmp(mode->name, "NTSC640x480") == 0) ||
+ (strcmp(mode->name, "NTSC640x480U") == 0) ||
+ (strcmp(mode->name, "NTSC640x400") == 0))) {
+ sis6326tvmode = TRUE;
+ } else {
+ pReg->sis6326tv[0x00] &= 0xfb;
+ }
+ }
+ if((strcmp(mode->name, "SIS1280x1024-75") == 0) || /* TW: Special high-res modes */
+ (strcmp(mode->name, "SIS1600x1200-60") == 0)) {
+ sis6326himode = TRUE;
+ }
+ }
+
+#ifdef UNLOCK_ALWAYS
+ outSISIDXREG(SISSR, 0x05, 0x86);
+#endif
+
+ pReg->sisRegs3C4[0x06] &= 0x01;
+
+ /* set interlace */
+ if(!(mode->Flags & V_INTERLACE)) {
+ offset = pSiS->CurrentLayout.displayWidth >> 3;
+ } else {
+ offset = pSiS->CurrentLayout.displayWidth >> 2;
+ pReg->sisRegs3C4[0x06] |= 0x20;
+ }
+
+ /* Enable Linear and Enhanced Gfx Mode */
+ pReg->sisRegs3C4[0x06] |= 0x82;
+
+ /* Enable MMIO at PCI Register 14H (D[6:5]: 11) */
+ pReg->sisRegs3C4[0x0B] |= 0x60;
+
+ /* Enable 32bit mem access (D7), read-ahead cache (D4) */
+ pReg->sisRegs3C4[0x0C] |= 0xA0;
+
+ /* TW: Some speed-up stuff */
+ switch(pSiS->Chipset) {
+ case PCI_CHIP_SIS5597:
+ /* TW: enable host bus */
+ if(pSiS->NoHostBus) {
+ pReg->sisRegs3C4[0x34] &= ~0x08;
+ } else {
+ pReg->sisRegs3C4[0x34] |= 0x08;
+ }
+ /* TW: fall through */
+ case PCI_CHIP_SIS6326:
+ case PCI_CHIP_SIS530:
+ /* TW: Enable "dual segment register mode" (D2) and "i/o gating while
+ * write buffer is not empty" (D3)
+ */
+ pReg->sisRegs3C4[0x0B] |= 0x0C;
+ }
+
+ /* set colordepth */
+ if(pSiS->Chipset == PCI_CHIP_SIS530) {
+ pReg->sisRegs3C4[0x09] &= 0x7F;
+ }
+ switch(pSiS->CurrentLayout.bitsPerPixel) {
+ case 8:
+ break;
+ case 16:
+ offset <<= 1;
+ if(pSiS->CurrentLayout.depth == 15)
+ pReg->sisRegs3C4[0x06] |= 0x04;
+ else
+ pReg->sisRegs3C4[0x06] |= 0x08;
+ break;
+ case 24:
+ offset += (offset << 1);
+ pReg->sisRegs3C4[0x06] |= 0x10;
+ pReg->sisRegs3C4[0x0B] |= 0x90;
+ break;
+ case 32:
+ if(pSiS->Chipset == PCI_CHIP_SIS530) {
+ offset <<= 2;
+ pReg->sisRegs3C4[0x06] |= 0x10;
+ pReg->sisRegs3C4[0x0B] |= 0x90;
+ pReg->sisRegs3C4[0x09] |= 0x80;
+ } else return FALSE;
+ break;
+ }
+
+ /* save screen pitch for acceleration functions */
+ pSiS->scrnOffset = pSiS->CurrentLayout.displayWidth *
+ ((pSiS->CurrentLayout.bitsPerPixel + 7) / 8);
+
+ /* set linear framebuffer addresses */
+ switch(pScrn->videoRam) {
+ case 512:
+ temp = 0x00; break;
+ case 1024:
+ temp = 0x20; break;
+ case 2048:
+ temp = 0x40; break;
+ case 4096:
+ temp = 0x60; break;
+ case 8192:
+ temp = 0x80; break;
+ default:
+ temp = 0x20;
+ }
+ pReg->sisRegs3C4[0x20] = (pSiS->FbAddress & 0x07F80000) >> 19;
+ pReg->sisRegs3C4[0x21] = ((pSiS->FbAddress & 0xF8000000) >> 27) | temp;
+
+ /* Set screen offset */
+ vgaReg->CRTC[0x13] = offset & 0xFF;
+
+ /* Set CR registers for our built-in TV and hi-res modes */
+ if((sis6326tvmode) || (sis6326himode)) {
+
+ int index,i;
+
+ /* TW: We need our very private data for hi-res and TV modes */
+ if(sis6326himode) {
+ if(strcmp(mode->name, "SIS1280x1024-75") == 0) index = 7;
+ else index = 8;
+ } else {
+ if(pSiS->SiS6326Flags & SIS6326_TVPAL) {
+ switch(width) {
+ case 800:
+ if((strcmp(mode->name, "PAL800x600U") == 0))
+ index = 4;
+ else
+ index = 0;
+ break;
+ case 720:
+ index = 5;
+ break;
+ case 640:
+ default:
+ index = 1;
+ }
+ } else {
+ switch(height) {
+ case 400:
+ index = 3;
+ break;
+ case 480:
+ default:
+ if((strcmp(mode->name, "NTSC640x480U") == 0))
+ index = 6;
+ else
+ index = 2;
+ }
+ }
+ }
+ for(i=0; i<=5; i++) {
+ vgaReg->CRTC[i] = SiS6326CR[index][i];
+ }
+ pReg->sisRegs3C4[0x12] = SiS6326CR[index][6];
+ vgaReg->CRTC[6] = SiS6326CR[index][7];
+ vgaReg->CRTC[7] = SiS6326CR[index][8];
+ vgaReg->CRTC[0x10] = SiS6326CR[index][9];
+ vgaReg->CRTC[0x11] = SiS6326CR[index][10];
+ vgaReg->CRTC[0x12] = SiS6326CR[index][11];
+ vgaReg->CRTC[0x15] = SiS6326CR[index][12];
+ vgaReg->CRTC[0x16] = SiS6326CR[index][13];
+ vgaReg->CRTC[9] &= ~0x20;
+ vgaReg->CRTC[9] |= (SiS6326CR[index][14] & 0x20);
+ pReg->sisRegs3C4[0x0A] = ((offset & 0xF00) >> 4) | (SiS6326CR[index][14] & 0x0f);
+
+ } else {
+
+ /* Set extended vertical overflow register */
+ pReg->sisRegs3C4[0x0A] = ((offset & 0xF00) >> 4) |
+ (((mode->CrtcVTotal-2) & 0x400) >> 10 ) |
+ (((mode->CrtcVDisplay-1) & 0x400) >> 9 ) |
+/* (((mode->CrtcVSyncStart-1) & 0x400) >> 8 ) | */
+ (((mode->CrtcVBlankStart-1)& 0x400) >> 8 ) |
+/* (((mode->CrtcVBlankStart-1)& 0x400) >> 7 ); */
+ (((mode->CrtcVSyncStart) & 0x400) >> 7 );
+
+ /* Set extended horizontal overflow register */
+ pReg->sisRegs3C4[0x12] &= 0xE0;
+ pReg->sisRegs3C4[0x12] |= (
+ (((mode->CrtcHTotal >> 3) - 5) & 0x100) >> 8 |
+ (((mode->CrtcHDisplay >> 3) - 1) & 0x100) >> 7 |
+/* (((mode->CrtcHSyncStart >> 3) - 1) & 0x100) >> 6 | */
+ (((mode->CrtcHBlankStart >> 3) - 1) & 0x100) >> 6 |
+ ((mode->CrtcHSyncStart >> 3) & 0x100) >> 5 |
+ (((mode->CrtcHBlankEnd >> 3) - 1) & 0x40) >> 2);
+ }
+
+#ifdef TWDEBUG
+ xf86DrvMsg(0, X_INFO, "HDisplay %d HSyncStart %d HSyncEnd %d HTotal %d\n",
+ mode->CrtcHDisplay, mode->CrtcHSyncStart,
+ mode->CrtcHSyncEnd, mode->CrtcHTotal);
+ xf86DrvMsg(0, X_INFO, "HBlankSt %d HBlankE %d\n",
+ mode->CrtcHBlankStart, mode->CrtcHBlankEnd);
+
+ xf86DrvMsg(0, X_INFO, "VDisplay %d VSyncStart %d VSyncEnd %d VTotal %d\n",
+ mode->CrtcVDisplay, mode->CrtcVSyncStart,
+ mode->CrtcVSyncEnd, mode->CrtcVTotal);
+ xf86DrvMsg(0, X_INFO, "VBlankSt %d VBlankE %d\n",
+ mode->CrtcVBlankStart, mode->CrtcVBlankEnd);
+#endif
+
+ /* enable (or disable) line compare */
+ if(mode->CrtcVDisplay >= 1024)
+ pReg->sisRegs3C4[0x38] |= 0x04;
+ else
+ pReg->sisRegs3C4[0x38] &= 0xFB;
+
+ /* Enable (or disable) high speed DCLK (some 6326 and 530/620 only) */
+ if( ( (pSiS->Chipset == PCI_CHIP_SIS6326) &&
+ ( (pSiS->ChipRev == 0xd0) || (pSiS->ChipRev == 0xd1) ||
+ (pSiS->ChipRev == 0xd2) || (pSiS->ChipRev == 0x92) ||
+ (pSiS->Flags & A6326REVAB) ) ) ||
+ (pSiS->oldChipset > OC_SIS6326) ) {
+ if( (pSiS->CurrentLayout.bitsPerPixel == 24) ||
+ (pSiS->CurrentLayout.bitsPerPixel == 32) ||
+ (mode->CrtcHDisplay >= 1280) )
+ pReg->sisRegs3C4[0x3E] |= 0x01;
+ else
+ pReg->sisRegs3C4[0x3E] &= 0xFE;
+ }
+
+ /* We use the internal VCLK */
+ pReg->sisRegs3C4[0x38] &= 0xFC;
+
+ /* Set VCLK */
+ if((sis6326tvmode) || (sis6326himode)) {
+ /* TW: For our built-in modes, the calculation is not suitable */
+ if(sis6326himode) {
+ if((strcmp(mode->name, "SIS1280x1024-75") == 0)) {
+ pReg->sisRegs3C4[0x2A] = 0x5d; /* 1280x1024-75 */
+ pReg->sisRegs3C4[0x2B] = 0xa4;
+ } else {
+ pReg->sisRegs3C4[0x2A] = 0x59; /* 1600x1200-60 */
+ pReg->sisRegs3C4[0x2B] = 0xa3;
+ }
+ pReg->sisRegs3C4[0x13] &= ~0x40;
+ } else {
+ if(pSiS->SiS6326Flags & SIS6326_TVPAL) {
+ /* PAL: 31.500 Mhz */
+ if((strcmp(mode->name, "PAL800x600U") == 0)) {
+ pReg->sisRegs3C4[0x2A] = 0x46;
+ pReg->sisRegs3C4[0x2B] = 0x49;
+ } else {
+ pReg->sisRegs3C4[0x2A] = 0xab;
+ pReg->sisRegs3C4[0x2B] = 0xe9;
+ }
+ pReg->sisRegs3C4[0x13] &= ~0x40;
+ } else {
+ /* NTSC: 27.000 Mhz */
+ if((strcmp(mode->name, "NTSC640x480U") == 0)) {
+ pReg->sisRegs3C4[0x2A] = 0x5a;
+ pReg->sisRegs3C4[0x2B] = 0x65;
+ } else {
+ pReg->sisRegs3C4[0x2A] = 0x29;
+ pReg->sisRegs3C4[0x2B] = 0xe2;
+ }
+ pReg->sisRegs3C4[0x13] |= 0x40;
+ }
+ }
+ } else if(SiS_compute_vclk(clock, &num, &denum, &div, &sbit, &scale)) {
+ pReg->sisRegs3C4[0x2A] = (num - 1) & 0x7f ;
+ pReg->sisRegs3C4[0x2A] |= (div == 2) ? 0x80 : 0;
+ pReg->sisRegs3C4[0x2B] = ((denum - 1) & 0x1f);
+ pReg->sisRegs3C4[0x2B] |= (((scale -1) & 3) << 5);
+
+ /* When setting VCLK, we should set SR13 first */
+ if(sbit)
+ pReg->sisRegs3C4[0x13] |= 0x40;
+ else
+ pReg->sisRegs3C4[0x13] &= 0xBF;
+
+#ifdef TWDEBUG
+ xf86DrvMsg(0, X_INFO, "2a: %x 2b: %x 13: %x clock %d\n",
+ pReg->sisRegs3C4[0x2A], pReg->sisRegs3C4[0x2B], pReg->sisRegs3C4[0x13], clock);
+#endif
+
+ } else {
+ /* if SiS_compute_vclk cannot handle the requested clock, try sisCalcClock */
+ SiSCalcClock(pScrn, clock, 2, vclk);
+
+ pReg->sisRegs3C4[0x2A] = (vclk[Midx] - 1) & 0x7f;
+ pReg->sisRegs3C4[0x2A] |= ((vclk[VLDidx] == 2) ? 1 : 0) << 7;
+
+ /* bits [4:0] contain denumerator */
+ pReg->sisRegs3C4[0x2B] = (vclk[Nidx] - 1) & 0x1f;
+
+ if (vclk[Pidx] <= 4){
+ /* postscale 1,2,3,4 */
+ pReg->sisRegs3C4[0x2B] |= (vclk[Pidx] - 1) << 5;
+ pReg->sisRegs3C4[0x13] &= 0xBF;
+ } else {
+ /* postscale 6,8 */
+ pReg->sisRegs3C4[0x2B] |= ((vclk[Pidx] / 2) - 1) << 5;
+ pReg->sisRegs3C4[0x13] |= 0x40;
+ }
+ pReg->sisRegs3C4[0x2B] |= 0x80 ; /* gain for high frequency */
+ }
+
+ /* High speed DAC */
+ if(clock > 135000)
+ pReg->sisRegs3C4[0x07] |= 0x02;
+
+ /* Programmable Clock */
+ pReg->sisRegs3C2 = inb(SISMISCR) | 0x0C;
+
+ /* 1 or 2 cycle DRAM (set by option FastVram) */
+ if(pSiS->newFastVram == -1) {
+ pReg->sisRegs3C4[0x34] |= 0x80;
+ pReg->sisRegs3C4[0x34] &= ~0x40;
+ } else if(pSiS->newFastVram == 1)
+ pReg->sisRegs3C4[0x34] |= 0xC0;
+ else
+ pReg->sisRegs3C4[0x34] &= ~0xC0;
+
+ /* Logical line length */
+ pSiS->ValidWidth = TRUE;
+ pReg->sisRegs3C4[0x27] &= 0xCF;
+ if(pSiS->CurrentLayout.bitsPerPixel == 24) {
+ /* Invalid logical width */
+ pReg->sisRegs3C4[0x27] |= 0x30;
+ pSiS->ValidWidth = FALSE;
+ } else {
+ switch(pScrn->virtualX * (pSiS->CurrentLayout.bitsPerPixel >> 3)) {
+ case 1024:
+ pReg->sisRegs3C4[0x27] |= 0x00;
+ break;
+ case 2048:
+ pReg->sisRegs3C4[0x27] |= 0x10;
+ break;
+ case 4096:
+ pReg->sisRegs3C4[0x27] |= 0x20;
+ break;
+ default:
+ /* Invalid logical width */
+ pReg->sisRegs3C4[0x27] |= 0x30;
+ pSiS->ValidWidth = FALSE;
+ break;
+ }
+ }
+
+ /* Acceleration stuff */
+ if(!pSiS->NoAccel) {
+ pReg->sisRegs3C4[0x27] |= 0x40; /* Enable engine programming registers */
+ if( (pSiS->TurboQueue) && /* Handle TurboQueue */
+ ( (pSiS->Chipset != PCI_CHIP_SIS530) ||
+ (pSiS->CurrentLayout.bitsPerPixel != 24) ) ) {
+ pReg->sisRegs3C4[0x27] |= 0x80; /* Enable TQ */
+ if((pSiS->Chipset == PCI_CHIP_SIS530) ||
+ ((pSiS->Chipset == PCI_CHIP_SIS6326 &&
+ (pSiS->ChipRev == 0xd0 || pSiS->ChipRev == 0xd1 ||
+ pSiS->ChipRev == 0xd2 || pSiS->ChipRev == 0x92 ||
+ pSiS->ChipRev == 0x0a || pSiS->ChipRev == 0x1a ||
+ pSiS->ChipRev == 0x2a || pSiS->ChipRev == 0x0b ||
+ pSiS->ChipRev == 0x1b || pSiS->ChipRev == 0x2b) ) ) ) {
+ /* pReg->sisRegs3C4[0x3D] |= 0x80; */ /* Queue is 62K (530/620 specs) */
+ pReg->sisRegs3C4[0x3D] &= 0x7F; /* Queue is 30K (530/620 specs) */
+ }
+ /* TW: Locate the TQ at the beginning of the last 64K block of
+ * video RAM. The address is to be specified in 32K steps.
+ */
+ pReg->sisRegs3C4[0x2C] = (pScrn->videoRam - 64) / 32;
+ if(pSiS->Chipset != PCI_CHIP_SIS530) { /* 530/620: Reserved (don't touch) */
+ pReg->sisRegs3C4[0x3C] &= 0xFC; /* 6326: Queue is all for 2D */
+ } /* 5597: Must be 0 */
+ } else {
+ pReg->sisRegs3C4[0x27] &= 0x7F;
+ }
+ }
+
+ /* TW: No idea what this does. The Windows driver does it, so we do it as well */
+ if(pSiS->Chipset == PCI_CHIP_SIS6326) {
+ if((pSiS->ChipRev == 0xd0) || (pSiS->ChipRev == 0xd1) ||
+ (pSiS->ChipRev == 0xd2) || (pSiS->ChipRev == 0x92) ||
+ (pSiS->Flags & A6326REVAB)) {
+ if((pSiS->Flags & (SYNCDRAM | RAMFLAG)) == (SYNCDRAM | RAMFLAG)) {
+ if(!(pReg->sisRegs3C4[0x0E] & 0x03)) {
+ pReg->sisRegs3C4[0x3E] |= 0x02;
+ }
+ }
+ }
+ }
+
+
+ /* Set memclock */
+#if 0
+ /* TW: We don't need to do this; the SetMClk option was not used since 4.0. */
+ if((pSiS->Chipset == PCI_CHIP_SIS5597) || (pSiS->Chipset == PCI_CHIP_SIS6326)) {
+ if(pSiS->MemClock > 66000) {
+ SiSCalcClock(pScrn, pSiS->MemClock, 1, vclk);
+
+ pReg->sisRegs3C4[0x28] = (vclk[Midx] - 1) & 0x7f ;
+ pReg->sisRegs3C4[0x28] |= ((vclk[VLDidx] == 2 ) ? 1 : 0 ) << 7 ;
+ pReg->sisRegs3C4[0x29] = (vclk[Nidx] -1) & 0x1f ; /* bits [4:0] contain denumerator -MC */
+ if(vclk[Pidx] <= 4) {
+ pReg->sisRegs3C4[0x29] |= (vclk[Pidx] - 1) << 5 ; /* postscale 1,2,3,4 */
+ pReg->sisRegs3C4[0x13] &= 0x7F;
+ } else {
+ pReg->sisRegs3C4[0x29] |= ((vclk[Pidx] / 2) - 1) << 5 ; /* postscale 6,8 */
+ pReg->sisRegs3C4[0x13] |= 0x80;
+ }
+ /* Check programmed memory clock. Enable only to check the above code */
+/*
+ mclk = 14318 * ((pReg->sisRegs3C4[0x28] & 0x7f) + 1);
+ mclk /= ((pReg->sisRegs3C4[0x29] & 0x0f) + 1);
+ if(!(pReg->sisRegs3C4[0x13] & 0x80)) {
+ mclk /= (((pReg->sisRegs3C4[0x29] & 0x60) >> 5) + 1);
+ } else {
+ if ((pReg->sisRegs3C4[0x29] & 0x60) == 0x40) mclk /= 6;
+ if ((pReg->sisRegs3C4[0x29] & 0x60) == 0x60) mclk /= 8;
+ }
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO,2,
+ "Setting memory clock to %.3f MHz\n",
+ mclk/1000.0);
+*/
+ }
+ }
+#endif
+
+ /* TW: set threshold values (rewritten) */
+ /*
+ * CPU/CRT Threshold: FIFO
+ * MCLK ___________ VCLK
+ * cpu/engine <---o o--------->|___________| -----------> CRT
+ * ^ ^ ^ ^
+ * \ / | |
+ * \ / |< gap >|
+ * \ / | |
+ * selector switch Thrsh. low high
+ *
+ * CRT consumes the data in the FIFO during scanline display. When the
+ * amount of data in the FIFO reaches the Threshold low value, the selector
+ * switch will switch to the right, and the FIFO will be refilled with data.
+ * When the amount of data in the FIFO reaches the Threshold high value, the
+ * selector switch will switch to the left and allows the CPU and the chip
+ * engines to access video RAM.
+ *
+ * The Threshold low values should be increased at higher bpps, simply because
+ * there is more data needed for the CRT. When Threshold low and high are very
+ * close to each other, the selector switch will be activated more often, which
+ * decreases performance.
+ *
+ */
+ switch(pSiS->Chipset) {
+ case PCI_CHIP_SIS5597: factor = 65; break;
+ case PCI_CHIP_SIS6326: factor = 30; break;
+ case PCI_CHIP_SIS530: factor = (pSiS->Flags & UMA) ? 60 : 30; break;
+ default: factor = (pScrn->videoRam > (1024*1024)) ? 24 : 12;
+ }
+ a = width * height * rate * 1.40 * factor * ((pSiS->CurrentLayout.bitsPerPixel + 1) / 8);
+ b = (mclk / 1000) * 999488.0 * (buswidth / 8);
+ c = ((a / b) + 1.0) / 2;
+ d = (int)c + 2;
+
+#ifdef TWDEBUG
+ xf86DrvMsg(0, X_INFO,
+ "Debug: w %d h %d r %d mclk %d bus %d factor %d bpp %d\n",
+ width, height, rate, mclk/1000, buswidth, factor,
+ pSiS->CurrentLayout.bitsPerPixel);
+ xf86DrvMsg(0, X_INFO, "Debug: a %f b %f c %f d %d (flags %x)\n",
+ a, b, c, d, pSiS->Flags);
+#endif
+
+ CRT_CPUthresholdLow = d;
+ if((pSiS->Flags & (RAMFLAG | SYNCDRAM)) == (RAMFLAG | SYNCDRAM)) {
+ CRT_CPUthresholdLow += 2;
+ }
+ CRT_CPUthresholdHigh = CRT_CPUthresholdLow + 3;
+
+ CRT_ENGthreshold = 0x0F;
+
+#ifdef TWDEBUG
+ xf86DrvMsg(0, X_INFO, "Debug: Thlow %d thhigh %d\n",
+ CRT_CPUthresholdLow, CRT_CPUthresholdHigh);
+#endif
+
+#if 0 /* TW: See comment in sis_dac.c on why this is commented */
+ if(pSiS->Chipset == PCI_CHIP_SIS530) {
+ if((pSiS->oldChipset == OC_SIS530A) &&
+ (pSiS->Flags & UMA) &&
+ (mclk == 100000) &&
+ (pSiS->Flags & ESS137xPRESENT)) {
+ if(!(pSiS->Flags & SECRETFLAG)) index = 0;
+ if((temp = SiS_CalcSpecial530Threshold(pSiS, mode, index)) {
+ CRT_CPUthresholdLow = temp;
+ break;
+ }
+ }
+ }
+#endif
+
+ switch(pSiS->Chipset) {
+ case PCI_CHIP_SIS530:
+ if(CRT_CPUthresholdLow > 0x1f) CRT_CPUthresholdLow = 0x1f;
+ CRT_CPUthresholdHigh = 0x1f;
+ break;
+ case PCI_CHIP_SIS5597:
+ case PCI_CHIP_SIS6326:
+ default:
+ if(CRT_CPUthresholdLow > 0x0f) CRT_CPUthresholdLow = 0x0f;
+ if(CRT_CPUthresholdHigh > 0x0f) CRT_CPUthresholdHigh = 0x0f;
+ }
+
+ pReg->sisRegs3C4[0x08] = ((CRT_CPUthresholdLow & 0x0F) << 4) |
+ (CRT_ENGthreshold & 0x0F);
+
+ pReg->sisRegs3C4[0x09] &= 0xF0;
+ pReg->sisRegs3C4[0x09] |= (CRT_CPUthresholdHigh & 0x0F);
+
+ pReg->sisRegs3C4[0x3F] &= 0xEB;
+ pReg->sisRegs3C4[0x3F] |= (CRT_CPUthresholdHigh & 0x10) |
+ ((CRT_CPUthresholdLow & 0x10) >> 2);
+
+ if(pSiS->oldChipset >= OC_SIS530A) {
+ pReg->sisRegs3C4[0x3F] &= 0xDF;
+ pReg->sisRegs3C4[0x3F] |= 0x58;
+ }
+
+ /* TW: Set SiS6326 TV registers */
+ if((pSiS->Chipset == PCI_CHIP_SIS6326) && (sis6326tvmode)) {
+ unsigned char tmp;
+ int index=0, i, j, k;
+
+ if(pSiS->SiS6326Flags & SIS6326_TVPAL) {
+ pReg->sisRegs3C4[0x0D] |= 0x04;
+ switch(width) {
+ case 800:
+ if((strcmp(mode->name, "PAL800x600U") == 0)) index = 4;
+ else index = 3;
+ break;
+ case 720:
+ index = 5;
+ break;
+ case 640:
+ default:
+ index = 2;
+ break;
+ }
+ for(i=0; i<14; i++) {
+ pReg->sis6326tv[SiS6326TVRegs1[i]] = SiS6326TVRegs1_PAL[index][i];
+ }
+ } else {
+ pReg->sisRegs3C4[0x0D] &= ~0x04;
+ if((strcmp(mode->name, "NTSC640x480U") == 0)) index = 5;
+ else index = 4;
+ for(i=0; i<14; i++) {
+ pReg->sis6326tv[SiS6326TVRegs1[i]] = SiS6326TVRegs1_NTSC[index][i];
+ }
+ }
+ tmp = pReg->sis6326tv[0x43];
+ if(pSiS->SiS6326Flags & SIS6326_TVCVBS) tmp |= 0x10;
+ tmp |= 0x08;
+ pReg->sis6326tv[0x43] = tmp;
+ j = 0; k = 0;
+ for(i=0; i<=0x44; i++) {
+ if(SiS6326TVRegs1[j] == i) {
+ j++;
+ continue;
+ }
+ if(pSiS->SiS6326Flags & SIS6326_TVPAL) {
+ tmp = SiS6326TVRegs2_PAL[index][k];
+ } else {
+ tmp = SiS6326TVRegs2_NTSC[index][k];
+ }
+ pReg->sis6326tv[i] = tmp;
+ k++;
+ }
+ pReg->sis6326tv[0x43] |= 0x08;
+ if((pSiS->ChipRev == 0xc1) || (pSiS->ChipRev == 0xc2)) {
+ pReg->sis6326tv[0x43] &= ~0x08;
+ }
+
+ tmp = pReg->sis6326tv[0];
+ tmp |= 0x18;
+ if(pSiS->SiS6326Flags & SIS6326_TVCVBS) tmp &= ~0x10;
+ else tmp &= ~0x08;
+ tmp |= 0x04;
+ pReg->sis6326tv[0] = tmp;
+ }
+
+ return(TRUE);
+}
+
+/* TW: Init a mode for SiS 300 and 310/325 series
+ * The original intention of the followling procedure was
+ * to initialize various registers for the selected mode.
+ * This was actually done to a structure, not the hardware.
+ * (SiSRestore would write the structure to the hardware
+ * registers.)
+ * This function is now only used for setting up some
+ * variables (eg. scrnOffset).
+ */
+Bool
+SIS300Init(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ SISRegPtr pReg = &pSiS->ModeReg;
+ unsigned short temp;
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4, "SIS300Init()\n");
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4,
+ "virtualX = %d depth = %d Logical width = %d\n",
+ pScrn->virtualX, pSiS->CurrentLayout.bitsPerPixel,
+ pScrn->virtualX * pSiS->CurrentLayout.bitsPerPixel/8);
+
+ /* Copy current register settings to structure */
+ (*pSiS->SiSSave)(pScrn, pReg);
+
+ /* TW: Calculate Offset/Display Pitch */
+ pSiS->scrnOffset = pSiS->CurrentLayout.displayWidth *
+ ((pSiS->CurrentLayout.bitsPerPixel+7)/8);
+ pSiS->scrnPitch = pSiS->scrnOffset;
+ if (mode->Flags & V_INTERLACE) pSiS->scrnPitch <<= 1;
+
+#ifdef UNLOCK_ALWAYS
+ outSISIDXREG(SISSR, 0x05, 0x86);
+#endif
+
+ switch(pSiS->CurrentLayout.bitsPerPixel) {
+ case 8:
+ pSiS->DstColor = 0x0000;
+ pSiS->SiS310_AccelDepth = 0x00000000;
+ break;
+ case 16:
+ if(pSiS->CurrentLayout.depth == 15)
+ pSiS->DstColor = (short) 0x4000;
+ else
+ pSiS->DstColor = (short) 0x8000;
+ pSiS->SiS310_AccelDepth = 0x00010000;
+ break;
+ case 24:
+ break;
+ case 32:
+ pSiS->DstColor = (short) 0xC000;
+ pSiS->SiS310_AccelDepth = 0x00020000;
+ break;
+ }
+
+ /* TW: Enable PCI LINEAR ADDRESSING (0x80), MMIO (0x01), PCI_IO (0x20) */
+ pReg->sisRegs3C4[0x20] = 0xA1;
+
+/* TW: Now initialize TurboQueue. TB is always located at the very top of
+ * the videoRAM (notably NOT the x framebuffer memory, which can/should
+ * be limited by MaxXFbMem when using DRI). Also, enable the accelerators.
+ */
+ if (!pSiS->NoAccel) {
+ pReg->sisRegs3C4[0x1E] |= 0x42; /* TW: Enable 2D accelerator */
+ pReg->sisRegs3C4[0x1E] |= 0x18; /* TW: Enable 3D accelerator */
+ switch (pSiS->VGAEngine) {
+ case SIS_300_VGA:
+ if(pSiS->TurboQueue) { /* set Turbo Queue as 512k */
+ temp = ((pScrn->videoRam/64)-8); /* TW: 8=512k, 4=256k, 2=128k, 1=64k */
+ pReg->sisRegs3C4[0x26] = temp & 0xFF;
+ pReg->sisRegs3C4[0x27] =
+ (pReg->sisRegs3C4[0x27] & 0xfc) | (((temp >> 8) & 3) | 0xF0);
+ } /* TW: line above new for saving D2&3 of status register */
+ break;
+ case SIS_315_VGA:
+ /* See comments in sis_driver.c */
+ pReg->sisRegs3C4[0x27] = 0x1F;
+ pReg->sisRegs3C4[0x26] = 0x22;
+ pReg->sisMMIO85C0 = (pScrn->videoRam - 512) * 1024;
+ break;
+ }
+ }
+
+ return(TRUE);
+}
+
+int
+SISDoSense(ScrnInfoPtr pScrn, int tempbl, int tempbh, int tempcl, int tempch)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int temp;
+
+ outSISIDXREG(SISPART4,0x11,tempbl);
+ temp = tempbh | tempcl;
+ setSISIDXREG(SISPART4,0x10,0xe0,temp);
+ usleep(200000);
+ tempch &= 0x7f;
+ inSISIDXREG(SISPART4,0x03,temp);
+ temp ^= 0x0e;
+ temp &= tempch;
+ return(temp);
+}
+
+/* TW: Sense connected devices on 30x */
+void SISSense30x(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ unsigned char backupP4_0d,biosflag;
+ unsigned char testsvhs_tempbl, testsvhs_tempbh;
+ unsigned char testsvhs_tempcl, testsvhs_tempch;
+ unsigned char testcvbs_tempbl, testcvbs_tempbh;
+ unsigned char testcvbs_tempcl, testcvbs_tempch;
+ unsigned char testvga2_tempbl, testvga2_tempbh;
+ unsigned char testvga2_tempcl, testvga2_tempch;
+ int myflag, result;
+ unsigned short temp;
+
+ inSISIDXREG(SISPART4,0x0d,backupP4_0d);
+ outSISIDXREG(SISPART4,0x0d,(backupP4_0d | 0x04));
+
+ if(pSiS->VGAEngine == SIS_315_VGA) {
+ if(pSiS->sishw_ext.UseROM) {
+ temp = 0xf3;
+ if(pSiS->Chipset == PCI_CHIP_SIS330) temp = 0x11b;
+ if(pSiS->BIOS[temp] & 0x08) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "SiS30x: Video bridge has (unsupported) DVI combo connector\n");
+ orSISIDXREG(SISCR, 0x32, 0x80);
+ } else {
+ andSISIDXREG(SISCR, 0x32, 0x7f);
+ }
+ }
+ }
+
+ if(pSiS->VGAEngine == SIS_300_VGA) {
+
+ if(pSiS->sishw_ext.UseROM) {
+ testvga2_tempbh = pSiS->BIOS[0xf9]; testvga2_tempbl = pSiS->BIOS[0xf8];
+ testsvhs_tempbh = pSiS->BIOS[0xfb]; testsvhs_tempbl = pSiS->BIOS[0xfa];
+ testcvbs_tempbh = pSiS->BIOS[0xfd]; testcvbs_tempbl = pSiS->BIOS[0xfc];
+ biosflag = pSiS->BIOS[0xfe];
+ } else {
+ testvga2_tempbh = 0x00; testvga2_tempbl = 0xd1;
+ testsvhs_tempbh = 0x00; testsvhs_tempbl = 0xb9;
+ testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xb3;
+ biosflag = 0;
+ }
+ if(pSiS->VBFlags & (VB_301B|VB_302B|VB_30xLV|VB_30xLVX)) {
+ testvga2_tempbh = 0x01; testvga2_tempbl = 0x90;
+ testsvhs_tempbh = 0x01; testsvhs_tempbl = 0x6b;
+ testcvbs_tempbh = 0x01; testcvbs_tempbl = 0x74;
+ }
+ inSISIDXREG(SISPART4,0x01,myflag);
+ if(myflag & 0x04) {
+ testvga2_tempbh = 0x00; testvga2_tempbl = 0xfd;
+ testsvhs_tempbh = 0x00; testsvhs_tempbl = 0xdd;
+ testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xee;
+ }
+ testvga2_tempch = 0x0e; testvga2_tempcl = 0x08;
+ testsvhs_tempch = 0x06; testsvhs_tempcl = 0x04;
+ testcvbs_tempch = 0x08; testcvbs_tempcl = 0x04;
+
+ } else if((pSiS->Chipset == PCI_CHIP_SIS315) ||
+ (pSiS->Chipset == PCI_CHIP_SIS315H) ||
+ (pSiS->Chipset == PCI_CHIP_SIS315PRO)) {
+
+ if(pSiS->sishw_ext.UseROM) {
+ testvga2_tempbh = pSiS->BIOS[0xbe]; testvga2_tempbl = pSiS->BIOS[0xbd];
+ testsvhs_tempbh = pSiS->BIOS[0xc0]; testsvhs_tempbl = pSiS->BIOS[0xbf];
+ testcvbs_tempbh = pSiS->BIOS[0xc2]; testcvbs_tempbl = pSiS->BIOS[0xc1];
+ biosflag = pSiS->BIOS[0xf3];
+ } else {
+ testvga2_tempbh = 0x00; testvga2_tempbl = 0xd1;
+ testsvhs_tempbh = 0x00; testsvhs_tempbl = 0xb9;
+ testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xb3;
+ biosflag = 0;
+ }
+ if(pSiS->VBFlags & (VB_301B|VB_302B|VB_30xLV|VB_30xLVX)) {
+ if(pSiS->sishw_ext.UseROM) {
+ testvga2_tempbh = pSiS->BIOS[0xc4]; testvga2_tempbl = pSiS->BIOS[0xc3];
+ testsvhs_tempbh = pSiS->BIOS[0xc6]; testsvhs_tempbl = pSiS->BIOS[0xc5];
+ testcvbs_tempbh = pSiS->BIOS[0xc8]; testcvbs_tempbl = pSiS->BIOS[0xc7];
+ } else {
+ testvga2_tempbh = 0x01; testvga2_tempbl = 0x90;
+ testsvhs_tempbh = 0x01; testsvhs_tempbl = 0x6b;
+ testcvbs_tempbh = 0x01; testcvbs_tempbl = 0x74;
+ }
+ }
+ inSISIDXREG(SISPART4,0x01,myflag);
+ if(myflag & 0x04) {
+ testvga2_tempbh = 0x00; testvga2_tempbl = 0xfd;
+ testsvhs_tempbh = 0x00; testsvhs_tempbl = 0xdd;
+ testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xee;
+ }
+ testvga2_tempch = 0x0e; testvga2_tempcl = 0x08;
+ testsvhs_tempch = 0x06; testsvhs_tempcl = 0x04;
+ testcvbs_tempch = 0x08; testcvbs_tempcl = 0x04;
+
+ } else if(pSiS->Chipset == PCI_CHIP_SIS330) {
+
+ if(pSiS->sishw_ext.UseROM) {
+ testvga2_tempbh = pSiS->BIOS[0xe6]; testvga2_tempbl = pSiS->BIOS[0xe5];
+ testsvhs_tempbh = pSiS->BIOS[0xe8]; testsvhs_tempbl = pSiS->BIOS[0xe7];
+ testcvbs_tempbh = pSiS->BIOS[0xea]; testcvbs_tempbl = pSiS->BIOS[0xe9];
+ biosflag = pSiS->BIOS[0x11b];
+ } else {
+ testvga2_tempbh = 0x00; testvga2_tempbl = 0xd1;
+ testsvhs_tempbh = 0x00; testsvhs_tempbl = 0xb9;
+ testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xb3;
+ biosflag = 0;
+ }
+ if(pSiS->VBFlags & (VB_301B|VB_302B|VB_30xLV|VB_30xLVX)) {
+ if(pSiS->sishw_ext.UseROM) {
+ testvga2_tempbh = pSiS->BIOS[0xec]; testvga2_tempbl = pSiS->BIOS[0xeb];
+ testsvhs_tempbh = pSiS->BIOS[0xee]; testsvhs_tempbl = pSiS->BIOS[0xed];
+ testcvbs_tempbh = pSiS->BIOS[0xf0]; testcvbs_tempbl = pSiS->BIOS[0xef];
+ } else {
+ testvga2_tempbh = 0x01; testvga2_tempbl = 0x90;
+ testsvhs_tempbh = 0x01; testsvhs_tempbl = 0x6b;
+ testcvbs_tempbh = 0x01; testcvbs_tempbl = 0x74;
+ }
+ }
+ inSISIDXREG(SISPART4,0x01,myflag);
+ if(myflag & 0x04) {
+ testvga2_tempbh = 0x00; testvga2_tempbl = 0xfd;
+ testsvhs_tempbh = 0x00; testsvhs_tempbl = 0xdd;
+ testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xee;
+ }
+ testvga2_tempch = 0x0e; testvga2_tempcl = 0x08;
+ testsvhs_tempch = 0x06; testsvhs_tempcl = 0x04;
+ testcvbs_tempch = 0x08; testcvbs_tempcl = 0x04;
+
+ } else { /* 550?, 650, 740 */
+
+ if(pSiS->sishw_ext.UseROM) {
+ testvga2_tempbh = pSiS->BIOS[0xbe]; testvga2_tempbl = pSiS->BIOS[0xbd];
+ testsvhs_tempbh = pSiS->BIOS[0xc0]; testsvhs_tempbl = pSiS->BIOS[0xbf];
+ testcvbs_tempbh = pSiS->BIOS[0xc2]; testcvbs_tempbl = pSiS->BIOS[0xc1];
+ biosflag = pSiS->BIOS[0xf3];
+ } else {
+ testvga2_tempbh = 0x00; testvga2_tempbl = 0xd1;
+ testsvhs_tempbh = 0x00; testsvhs_tempbl = 0xb9;
+ testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xb3;
+ biosflag = 0;
+ }
+ testvga2_tempch = 0x0e; testvga2_tempcl = 0x08;
+ testsvhs_tempch = 0x06; testsvhs_tempcl = 0x04;
+ testcvbs_tempch = 0x08; testcvbs_tempcl = 0x04;
+
+ /* TW: Different BIOS versions use different values for the 301LV.
+ These values are from the newest versions 1.10.6? and 1.10.7?.
+ I have no idea if these values are suitable for the 301B as well.
+ */
+
+ if(pSiS->VBFlags & (VB_301B|VB_302B|VB_30xLV|VB_30xLVX)) {
+ if(pSiS->sishw_ext.UseROM) {
+ testvga2_tempbh = pSiS->BIOS[0xc4]; testvga2_tempbl = pSiS->BIOS[0xc3];
+ testsvhs_tempbh = pSiS->BIOS[0xc6]; testsvhs_tempbl = pSiS->BIOS[0xc5];
+ testcvbs_tempbh = pSiS->BIOS[0xc8]; testcvbs_tempbl = pSiS->BIOS[0xc7];
+ biosflag = pSiS->BIOS[0xf3];
+ } else {
+ testvga2_tempbh = 0x01; testvga2_tempbl = 0x90;
+ testsvhs_tempbh = 0x02; testsvhs_tempbl = 0x00;
+ testcvbs_tempbh = 0x01; testcvbs_tempbl = 0x00;
+ biosflag = 0;
+ }
+ testvga2_tempch = 0x0e; testvga2_tempcl = 0x08;
+ testsvhs_tempch = 0x04; testsvhs_tempcl = 0x08;
+ testcvbs_tempch = 0x08; testcvbs_tempcl = 0x08;
+ }
+
+ }
+
+ /* TW: No VGA2 or SCART on LV bridges */
+ if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) {
+ testvga2_tempbh = testvga2_tempbl = 0x00;
+ testvga2_tempch = testvga2_tempcl = 0x00;
+ }
+
+ if(testvga2_tempch || testvga2_tempcl || testvga2_tempbh || testvga2_tempbl) {
+#ifdef TWDEBUG
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "SiS30x: Scanning for VGA2/SCART (%x %x %x %x)\n",
+ testvga2_tempbh, testvga2_tempbl, testvga2_tempch, testvga2_tempcl);
+#endif
+
+ result = SISDoSense(pScrn, testvga2_tempbl, testvga2_tempbh,
+ testvga2_tempcl, testvga2_tempch);
+ if(result) {
+ if(biosflag & 0x01) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "SiS30x: Detected TV connected to SCART output\n");
+ pSiS->VBFlags |= TV_SCART;
+ orSISIDXREG(SISCR, 0x32, 0x04);
+ pSiS->postVBCR32 |= 0x04;
+ } else if(!(pSiS->VBFlags & (VB_30xLV|VB_30xLVX))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "SiS30x: Detected secondary VGA connection\n");
+ pSiS->VBFlags |= VGA2_CONNECTED;
+ orSISIDXREG(SISCR, 0x32, 0x10);
+ pSiS->postVBCR32 |= 0x10;
+ }
+ }
+ }
+
+#ifdef TWDEBUG
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "SiS30x: Scanning for TV (%x %x %x %x; %x %x %x %x)\n",
+ testsvhs_tempbh, testsvhs_tempbl, testsvhs_tempch, testsvhs_tempcl,
+ testcvbs_tempbh, testcvbs_tempbl, testcvbs_tempch, testcvbs_tempcl);
+#endif
+
+ result = SISDoSense(pScrn, testsvhs_tempbl, testsvhs_tempbh,
+ testsvhs_tempcl, testsvhs_tempch);
+ if(result) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "SiS30x: Detected TV connected to SVIDEO output\n");
+ /* TW: So we can be sure that there IS a SVIDEO output */
+ pSiS->VBFlags |= TV_SVIDEO;
+ orSISIDXREG(SISCR, 0x32, 0x02);
+ pSiS->postVBCR32 |= 0x02;
+ }
+
+ if((biosflag & 0x02) || (!(result))) {
+
+ result = SISDoSense(pScrn, testcvbs_tempbl, testcvbs_tempbh,
+ testcvbs_tempcl, testcvbs_tempch);
+ if(result) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "SiS30x: Detected TV connected to COMPOSITE output\n");
+ /* TW: So we can be sure that there IS a CVBS output */
+ pSiS->VBFlags |= TV_AVIDEO;
+ orSISIDXREG(SISCR, 0x32, 0x01);
+ pSiS->postVBCR32 |= 0x01;
+ }
+ }
+ SISDoSense(pScrn, 0, 0, 0, 0);
+
+ outSISIDXREG(SISPART4,0x0d,backupP4_0d);
+}
+
+static void
+SiS6326TVDelay(ScrnInfoPtr pScrn, int delay)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int i;
+ unsigned char temp;
+
+ for(i=0; i<delay; i++) {
+ inSISIDXREG(SISSR, 0x05, temp);
+ }
+}
+
+int
+SIS6326DoSense(ScrnInfoPtr pScrn, int tempbh, int tempbl, int tempch, int tempcl)
+{
+ unsigned char temp;
+
+ SiS6326SetTVReg(pScrn, 0x42, tempbl);
+ temp = SiS6326GetTVReg(pScrn, 0x43);
+ temp &= 0xfc;
+ temp |= tempbh;
+ SiS6326SetTVReg(pScrn, 0x43, temp);
+ SiS6326TVDelay(pScrn, 0x1000);
+ temp = SiS6326GetTVReg(pScrn, 0x43);
+ temp |= 0x04;
+ SiS6326SetTVReg(pScrn, 0x43, temp);
+ SiS6326TVDelay(pScrn, 0x8000);
+ temp = SiS6326GetTVReg(pScrn, 0x44);
+ if(!(tempch & temp)) tempcl = 0;
+ return(tempcl);
+}
+
+void
+SISSense6326(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ unsigned char temp;
+ int result;
+
+ pSiS->SiS6326Flags &= (SIS6326_HASTV | SIS6326_TVPAL);
+ temp = SiS6326GetTVReg(pScrn, 0x43);
+ temp &= 0xfb;
+ SiS6326SetTVReg(pScrn, 0x43, temp);
+ result = SIS6326DoSense(pScrn, 0x01, 0xb0, 0x06, SIS6326_TVSVIDEO); /* 0x02 */
+ pSiS->SiS6326Flags |= result;
+ result = SIS6326DoSense(pScrn, 0x01, 0xa0, 0x01, SIS6326_TVCVBS); /* 0x04 */
+ pSiS->SiS6326Flags |= result;
+ temp = SiS6326GetTVReg(pScrn, 0x43);
+ temp &= 0xfb;
+ SiS6326SetTVReg(pScrn, 0x43, temp);
+ if(pSiS->SiS6326Flags & (SIS6326_TVSVIDEO | SIS6326_TVCVBS)) {
+ pSiS->SiS6326Flags |= SIS6326_TVDETECTED;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "SiS6326: Detected TV connected to %s output\n",
+ (pSiS->SiS6326Flags & SIS6326_TVSVIDEO) ?
+ "SVIDEO" : "COMPOSITE");
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "SiS6326: No TV detected\n");
+ }
+}
+
+/* TW: Detect video bridge and set VBFlags accordingly */
+void SISVGAPreInit(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int temp,temp1,temp2;
+ int upperlimitlvds, lowerlimitlvds;
+ int upperlimitch, lowerlimitch;
+ int chronteltype, chrontelidreg;
+ static const char *ChrontelTypeStr[] = {
+ "7004",
+ "7005",
+ "7007",
+ "7006",
+ "7008",
+ "7013",
+ "7019",
+ "7020",
+ "(unknown)"
+ };
+
+ switch (pSiS->Chipset) {
+ case PCI_CHIP_SIS300:
+ case PCI_CHIP_SIS630:
+ case PCI_CHIP_SIS540:
+ case PCI_CHIP_SIS550:
+ case PCI_CHIP_SIS650:
+ case PCI_CHIP_SIS315:
+ case PCI_CHIP_SIS315H:
+ case PCI_CHIP_SIS315PRO:
+ case PCI_CHIP_SIS330:
+ pSiS->ModeInit = SIS300Init;
+ break;
+ default:
+ pSiS->ModeInit = SISInit;
+ }
+
+ if((pSiS->Chipset == PCI_CHIP_SIS6326) && (pSiS->SiS6326Flags & SIS6326_HASTV)) {
+ unsigned char sr0d;
+ inSISIDXREG(SISSR, 0x0d, sr0d);
+ if(sr0d & 0x04) {
+ pSiS->SiS6326Flags |= SIS6326_TVPAL;
+ }
+ SISSense6326(pScrn);
+ }
+
+ pSiS->VBFlags = 0; /* reset VBFlags */
+
+ /* TW: Videobridges only available for 300/310/325 series */
+ if((pSiS->VGAEngine != SIS_300_VGA) && (pSiS->VGAEngine != SIS_315_VGA))
+ return;
+
+ inSISIDXREG(SISPART4, 0x00, temp);
+ temp &= 0x0F;
+ if (temp == 1) {
+ inSISIDXREG(SISPART4, 0x01, temp1);
+ temp1 &= 0xff;
+ if (temp1 >= 0xE0) {
+ pSiS->VBFlags |= VB_30xLVX;
+ pSiS->sishw_ext.ujVBChipID = VB_CHIP_301LVX;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Detected SiS301LVX video bridge (Revision 0x%x)\n",
+ temp1);
+ } else if (temp1 >= 0xD0) {
+ pSiS->VBFlags |= VB_30xLV;
+ pSiS->sishw_ext.ujVBChipID = VB_CHIP_301LV;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Detected SiS301LV video bridge (Revision 0x%x)\n",
+ temp1);
+ } else if (temp1 >= 0xB0) {
+ pSiS->VBFlags |= VB_301B;
+ pSiS->sishw_ext.ujVBChipID = VB_CHIP_301B;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Detected SiS301B video bridge (Revision 0x%x)\n",
+ temp1);
+ } else {
+ pSiS->VBFlags |= VB_301;
+ pSiS->sishw_ext.ujVBChipID = VB_CHIP_301;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Detected SiS301 video bridge (Revision 0x%x)\n",
+ temp1);
+ }
+ if (pSiS->VBFlags & (VB_30xLV | VB_30xLVX)) {
+ inSISIDXREG(SISCR, 0x38, temp);
+ if((temp & 0x03) == 0x03) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "[SiS301LV/LVX: LCD channel A]\n");
+ }
+ }
+
+ SISSense30x(pScrn);
+
+ } else if (temp == 2) {
+
+ inSISIDXREG(SISPART4, 0x01, temp1);
+ temp1 &= 0xff;
+ if (temp1 >= 0xE0) {
+ pSiS->VBFlags |= VB_30xLVX;
+ pSiS->sishw_ext.ujVBChipID = VB_CHIP_302LVX;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Detected SiS302LVX video bridge (Revision 0x%x)\n",
+ temp1);
+ } else if (temp1 >= 0xD0) {
+ pSiS->VBFlags |= VB_30xLV;
+ pSiS->sishw_ext.ujVBChipID = VB_CHIP_302LV;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Detected SiS302LV video bridge (Revision 0x%x)\n",
+ temp1);
+ } else {
+ pSiS->VBFlags |= VB_302B;
+ pSiS->sishw_ext.ujVBChipID = VB_CHIP_302B;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Detected SiS302B video bridge (Revision 0x%x)\n",
+ temp1);
+ }
+ if (pSiS->VBFlags & (VB_302B | VB_30xLV | VB_30xLVX)) {
+ inSISIDXREG(SISCR, 0x38, temp);
+ if((temp & 0x03) == 0x03) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "[SiS302B/LV/LVX: LCD channel A]\n");
+ }
+ }
+
+ SISSense30x(pScrn);
+
+ } else if (temp == 3) {
+
+ pSiS->VBFlags |= VB_303;
+ pSiS->sishw_ext.ujVBChipID = VB_CHIP_303;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Detected SiS303 video bridge\n");
+
+ } else {
+
+ pSiS->sishw_ext.ujVBChipID = VB_CHIP_UNKNOWN;
+ inSISIDXREG(SISCR, 0x37, temp);
+ temp = (temp >> 1) & 0x07;
+#if 0 /* TW: This does not seem to be used on any machine */
+ if ( (temp == 0) || (temp == 1)) {
+ pSiS->VBFlags|=VB_301; /* TW: 301 ? */
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Detected SiS301 video bridge (Irregular bridge type %d)\n", temp);
+ }
+#endif
+ if(pSiS->VGAEngine == SIS_300_VGA) {
+ lowerlimitlvds = 2; upperlimitlvds = 4;
+ lowerlimitch = 4; upperlimitch = 5;
+ chronteltype = 1; chrontelidreg = 0x25;
+ } else {
+ lowerlimitlvds = 2; upperlimitlvds = 3;
+ lowerlimitch = 3; upperlimitch = 3;
+ chronteltype = 2; chrontelidreg = 0x4b;
+ }
+
+ if((temp >= lowerlimitlvds) && (temp <= upperlimitlvds)) {
+ pSiS->VBFlags |= VB_LVDS;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Detected LVDS transmitter (Bridge type %d)\n", temp);
+ if(pSiS->Chipset == PCI_CHIP_SIS650) {
+ inSISIDXREG(SISCR, 0x38, temp1);
+ if(temp1 & 0x02) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "[LVDS: LCD channel A]\n");
+ }
+ if(temp1 & 0x08) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "[LVDS: HDTV]\n");
+ }
+ if(temp1 & 0x08) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "[LVDS: SCART]\n");
+ }
+ }
+ }
+ if((temp >= lowerlimitch) && (temp <= upperlimitch)) {
+ /* TW: Set global for init301.c */
+ pSiS->SiS_Pr->SiS_IF_DEF_CH70xx = chronteltype;
+
+ if(chronteltype == 1) {
+ /* TW: Do something mysterious (found in Mitac BIOS) */
+ SiS_WhatIsThis(pSiS->SiS_Pr, 0x9c);
+ }
+
+ /* TW: Read Chrontel version number */
+ temp1 = SiS_GetCH70xx(pSiS->SiS_Pr, chrontelidreg);
+ if(chronteltype == 1) {
+ /* TW: See Chrontel TB31 for explanation */
+ temp2 = SiS_GetCH700x(pSiS->SiS_Pr, 0x0e);
+ if(((temp2 & 0x07) == 0x01) || (temp & 0x04)) {
+ SiS_SetCH700x(pSiS->SiS_Pr, 0x0b0e);
+ SiS_DDC2Delay(pSiS->SiS_Pr, 300);
+ }
+ temp2 = SiS_GetCH70xx(pSiS->SiS_Pr, chrontelidreg);
+ if(temp2 != temp1) temp1 = temp2;
+ }
+ if(temp1 == 0xFFFF) { /* 0xFFFF = error reading DDC port */
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Detected Chrontel 70xx, but encountered error reading I2C port\n");
+ }
+ /* TW: We only support device ids 0x19-200; other values may indicate DDC problems */
+ else if((temp1 >= 0x19) && (temp1 <= 200)) {
+ pSiS->VBFlags |= VB_CHRONTEL;
+ switch (temp1) {
+ case 0x32: temp2 = 0; pSiS->ChrontelType = CHRONTEL_700x; break;
+ case 0x3A: temp2 = 1; pSiS->ChrontelType = CHRONTEL_700x; break;
+ case 0x50: temp2 = 2; pSiS->ChrontelType = CHRONTEL_700x; break;
+ case 0x2A: temp2 = 3; pSiS->ChrontelType = CHRONTEL_700x; break;
+ case 0x40: temp2 = 4; pSiS->ChrontelType = CHRONTEL_700x; break;
+ case 0x22: temp2 = 5; pSiS->ChrontelType = CHRONTEL_700x; break;
+ case 0x19: temp2 = 6; pSiS->ChrontelType = CHRONTEL_701x; break;
+ case 0x20: temp2 = 7; pSiS->ChrontelType = CHRONTEL_701x; break; /* ID for 7020? */
+ default: temp2 = 8; pSiS->ChrontelType = CHRONTEL_701x; break;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Detected Chrontel %s TV encoder (ID 0x%02x; bridge type %d)\n",
+ ChrontelTypeStr[temp2], temp1, temp);
+
+ /* TW: Sense connected TV's */
+
+ if(chronteltype == 1) {
+
+ /* Chrontel 700x */
+
+ /* TW: Read power status */
+ temp1 = SiS_GetCH700x(pSiS->SiS_Pr, 0x0e); /* Power status */
+ if((temp1 & 0x03) != 0x03) {
+ /* TW: Power all outputs */
+ SiS_SetCH700x(pSiS->SiS_Pr, 0x0B0E);
+ SiS_DDC2Delay(pSiS->SiS_Pr, 0x96);
+ }
+ /* TW: Sense connected TV devices */
+ SiS_SetCH700x(pSiS->SiS_Pr, 0x0110);
+ SiS_DDC2Delay(pSiS->SiS_Pr, 0x96);
+ SiS_SetCH700x(pSiS->SiS_Pr, 0x0010);
+ SiS_DDC2Delay(pSiS->SiS_Pr, 0x96);
+ temp1 = SiS_GetCH700x(pSiS->SiS_Pr, 0x10);
+ if(!(temp1 & 0x08)) temp1 = 0x02;
+ else if(!(temp1 & 0x02)) temp1 = 0x01;
+ else temp1 = 0;
+
+ } else {
+
+ /* Chrontel 701x */
+
+ /* TW: Backup Power register */
+ temp1 = SiS_GetCH701x(pSiS->SiS_Pr, 0x49);
+
+ /* TW: Enable TV path */
+ SiS_SetCH701x(pSiS->SiS_Pr, 0x2049);
+
+ SiS_DDC2Delay(pSiS->SiS_Pr, 0x96);
+
+ /* TW: Sense connected TV devices */
+ temp2 = SiS_GetCH701x(pSiS->SiS_Pr, 0x20);
+ temp2 |= 0x01;
+ SiS_SetCH701x(pSiS->SiS_Pr, (temp2 << 8) | 0x20);
+
+ SiS_DDC2Delay(pSiS->SiS_Pr, 0x96);
+
+ temp2 ^= 0x01;
+ SiS_SetCH701x(pSiS->SiS_Pr, (temp2 << 8) | 0x20);
+
+ SiS_DDC2Delay(pSiS->SiS_Pr, 0x96);
+
+ temp2 = SiS_GetCH701x(pSiS->SiS_Pr, 0x20);
+
+ /* TW: Restore Power register */
+ SiS_SetCH701x(pSiS->SiS_Pr, (temp1 << 8) | 0x49);
+
+ temp1 = 0;
+ if(temp2 & 0x02) temp1 |= 0x01;
+ if(temp2 & 0x10) temp1 |= 0x01;
+ if(temp2 & 0x04) temp1 |= 0x02;
+
+ if( (temp1 & 0x01) && (temp1 & 0x02) ) temp1 = 0x04;
+
+ }
+
+ switch(temp1) {
+ case 0x01:
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Chrontel: Detected TV connected to COMPOSITE output\n");
+ /* TW: So we can be sure that there IS a CVBS output */
+ pSiS->VBFlags |= TV_AVIDEO;
+ orSISIDXREG(SISCR, 0x32, 0x01);
+ pSiS->postVBCR32 |= 0x01;
+ break;
+ case 0x02:
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Chrontel: Detected TV connected to SVIDEO output\n");
+ /* TW: So we can be sure that there IS a SVIDEO output */
+ pSiS->VBFlags |= TV_SVIDEO;
+ orSISIDXREG(SISCR, 0x32, 0x02);
+ pSiS->postVBCR32 |= 0x02;
+ break;
+ case 0x04:
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Chrontel: Detected TV connected to SCART output or 480i HDTV\n");
+ if(pSiS->chtvtype == -1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Chrontel: Use CHTVType option to select either SCART or HDTV\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Chrontel: Using SCART by default\n");
+ pSiS->chtvtype = 1;
+ }
+ if(pSiS->chtvtype)
+ pSiS->VBFlags |= TV_CHSCART;
+ else
+ pSiS->VBFlags |= TV_CHHDTV;
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Chrontel: No TV detected.\n");
+ }
+
+ } else if(temp1==0) {
+ /* TW: This indicates a communication problem, but it only occures if there
+ * is no TV attached.
+ */
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Detected Chrontel TV encoder in promiscuous state (DDC/I2C mix-up)\n");
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Chrontel: Unsupported device id (%d) detected\n",temp1);
+ }
+ if(chronteltype == 1) {
+ /* TW: Do something mysterious (found in Mitac BIOS) */
+ SiS_WhatIsThis(pSiS->SiS_Pr, 0x00);
+ }
+ }
+ if ((pSiS->VGAEngine == SIS_300_VGA) && (temp == 3)) {
+ pSiS->VBFlags |= VB_TRUMPION;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Detected Trumpion Zurac (I/II/III) LVDS scaler\n");
+ }
+ if (temp > upperlimitlvds) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Detected unknown bridge type (%d)\n", temp);
+ }
+ }
+}
+
+
diff --git a/src/sis_video.c b/src/sis_video.c
new file mode 100644
index 0000000..35a14a7
--- /dev/null
+++ b/src/sis_video.c
@@ -0,0 +1,2454 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_video.c,v 1.10 2003/02/04 02:44:29 dawes Exp $ */
+/*
+ * Xv driver for SiS 300 and 310/325 series.
+ *
+ * (Based on the mga Xv driver by Mark Vojkovich and i810 Xv
+ * driver by Jonathan Bian <jonathan.bian@intel.com>.)
+ *
+ * Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan.
+ * Copyright 2002,2003 by Thomas Winischhofer, Vienna, Austria.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL INTEL, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Sung-Ching Lin <sclin@sis.com.tw>
+ *
+ * Thomas Winischhofer <thomas@winischhofer.net>:
+ * - 310/325 series (315/550/650/651/740/M650) support
+ * - (possibly incomplete) Xabre (SiS330) support
+ * - new mode switching code for 300, 310/325 and 330 series
+ * - many fixes for 300/540/630/730 chipsets,
+ * - many fixes for 5597/5598, 6326 and 530/620 chipsets,
+ * - VESA mode switching (deprecated),
+ * - extended CRT2/video bridge handling support,
+ * - dual head support on 300, 310/325 and 330 series
+ * - 650/LVDS (up to 1400x1050), 650/Chrontel 701x support
+ * - 30xB/30xLV/30xLVX video bridge support (300, 310/325, 330 series)
+ * - Xv support for 5597/5598, 6326, 530/620 and 310/325 series
+ * - video overlay enhancements for 300 series
+ * - TV and hi-res support for the 6326
+ * - etc.
+ *
+ * TW: This supports the following chipsets:
+ * SiS300: No registers >0x65, offers one overlay
+ * SiS630/730: No registers >0x6b, offers two overlays (one used for CRT1, one for CRT2)
+ * SiS550: Full register range, offers two overlays (one used for CRT1, one for CRT2)
+ * SiS315: Full register range, offers one overlay (used for both CRT1 and CRT2 alt.)
+ * SiS650/740: Full register range, offers one overlay (used for both CRT1 and CRT2 alt.)
+ * SiSM650/651: Full register range, two overlays (one used for CRT1, one for CRT2)
+ *
+ * Help for reading the code:
+ * 315/550/650/740/M650/651 = SIS_315_VGA
+ * 300/630/730 = SIS_300_VGA
+ * For chipsets with 2 overlays, hasTwoOverlays will be true
+ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86Resources.h"
+#include "xf86_ansic.h"
+#include "compiler.h"
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+#include "xf86fbman.h"
+#include "regionstr.h"
+
+#include "sis.h"
+#include "xf86xv.h"
+#include "Xv.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "dixstruct.h"
+#include "fourcc.h"
+
+#include "sis_regs.h"
+
+#define OFF_DELAY 200 /* milliseconds */
+#define FREE_DELAY 60000
+
+#define OFF_TIMER 0x01
+#define FREE_TIMER 0x02
+#define CLIENT_VIDEO_ON 0x04
+
+#define TIMER_MASK (OFF_TIMER | FREE_TIMER)
+
+#define WATCHDOG_DELAY 500000 /* Watchdog counter for Vertical Restrace waiting */
+
+static XF86VideoAdaptorPtr SISSetupImageVideo(ScreenPtr);
+static void SISStopVideo(ScrnInfoPtr, pointer, Bool);
+static int SISSetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer);
+static int SISGetPortAttribute(ScrnInfoPtr, Atom ,INT32 *, pointer);
+static void SISQueryBestSize(ScrnInfoPtr, Bool, short, short, short,
+ short, unsigned int *,unsigned int *, pointer);
+static int SISPutImage( ScrnInfoPtr,
+ short, short, short, short, short, short, short, short,
+ int, unsigned char*, short, short, Bool, RegionPtr, pointer);
+static int SISQueryImageAttributes(ScrnInfoPtr,
+ int, unsigned short *, unsigned short *, int *, int *);
+static void SISVideoTimerCallback(ScrnInfoPtr pScrn, Time now);
+static void SISInitOffscreenImages(ScreenPtr pScrn);
+
+#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
+
+extern BOOLEAN SiSBridgeIsInSlaveMode(ScrnInfoPtr pScrn);
+
+#define IMAGE_MIN_WIDTH 32 /* Minimum and maximum source image sizes */
+#define IMAGE_MIN_HEIGHT 24
+#define IMAGE_MAX_WIDTH 720
+#define IMAGE_MAX_HEIGHT 576
+#define IMAGE_MAX_WIDTH_M650 1920
+#define IMAGE_MAX_HEIGHT_M650 1080
+
+#define OVERLAY_MIN_WIDTH 32 /* Minimum overlay sizes */
+#define OVERLAY_MIN_HEIGHT 24
+
+#define DISPMODE_SINGLE1 0x1 /* TW: CRT1 only */
+#define DISPMODE_SINGLE2 0x2 /* TW: CRT2 only */
+#define DISPMODE_MIRROR 0x4 /* TW: CRT1 + CRT2 MIRROR (see note below) */
+
+#ifdef SISDUALHEAD
+#define HEADOFFSET (pSiS->dhmOffset)
+#endif
+
+/* TW: Note on "MIRROR":
+ * When using VESA on machines with an enabled video bridge, this means
+ * a real mirror. CRT1 and CRT2 have the exact same resolution and
+ * refresh rate. The same applies to modes which require the bridge to
+ * operate in slave mode.
+ * When not using VESA and the bridge is not in slave mode otherwise,
+ * CRT1 and CRT2 have the same resolution but possibly a different
+ * refresh rate.
+ */
+
+/****************************************************************************
+ * Raw register access : These routines directly interact with the sis's
+ * control aperature. Must not be called until after
+ * the board's pci memory has been mapped.
+ ****************************************************************************/
+
+#if 0
+static CARD32 _sisread(SISPtr pSiS, CARD32 reg)
+{
+ return *(pSiS->IOBase + reg);
+}
+
+static void _siswrite(SISPtr pSiS, CARD32 reg, CARD32 data)
+{
+ *(pSiS->IOBase + reg) = data;
+}
+#endif
+
+static CARD8 getvideoreg(SISPtr pSiS, CARD8 reg)
+{
+ CARD8 ret;
+ inSISIDXREG(SISVID, reg, ret);
+ return(ret);
+}
+
+static void setvideoreg(SISPtr pSiS, CARD8 reg, CARD8 data)
+{
+ outSISIDXREG(SISVID, reg, data);
+}
+
+static void setvideoregmask(SISPtr pSiS, CARD8 reg, CARD8 data, CARD8 mask)
+{
+ CARD8 old;
+
+ inSISIDXREG(SISVID, reg, old);
+ data = (data & mask) | (old & (~mask));
+ outSISIDXREG(SISVID, reg, data);
+}
+
+static void setsrregmask(SISPtr pSiS, CARD8 reg, CARD8 data, CARD8 mask)
+{
+ CARD8 old;
+
+ inSISIDXREG(SISSR, reg, old);
+ data = (data & mask) | (old & (~mask));
+ outSISIDXREG(SISSR, reg, data);
+}
+
+#if 0
+static CARD8 getsisreg(SISPtr pSiS, CARD8 index_offset, CARD8 reg)
+{
+ CARD8 ret;
+ inSISIDXREG(index_offset, reg, ret);
+ return(ret);
+}
+#endif
+
+/* VBlank */
+static CARD8 vblank_active_CRT1(SISPtr pSiS)
+{
+ return (inSISREG(SISINPSTAT) & 0x08);
+}
+
+static CARD8 vblank_active_CRT2(SISPtr pSiS)
+{
+ CARD8 ret;
+ if(pSiS->VGAEngine == SIS_315_VGA) {
+ inSISIDXREG(SISPART1, Index_310_CRT2_FC_VR, ret);
+ } else {
+ inSISIDXREG(SISPART1, Index_CRT2_FC_VR, ret);
+ }
+ return((ret & 0x02) ^ 0x02);
+}
+
+/* Scanline - unused */
+#if 0
+static CARD32 get_scanline_CRT1(SISPtr pSiS)
+{
+ CARD32 line;
+
+ _siswrite (pSiS, REG_PRIM_CRT_COUNTER, 0x00000001);
+ line = _sisread (pSiS, REG_PRIM_CRT_COUNTER);
+
+ return ((line >> 16) & 0x07FF);
+}
+
+static CARD32 get_scanline_CRT2(SISPtr pSiS)
+{
+ CARD32 line;
+
+ line = (CARD32)(getsisreg(pSiS, SISPART1, Index_CRT2_FC_VCount1) & 0x70) * 16
+ + getsisreg(pSiS, SISPART1, Index_CRT2_FC_VCount);
+
+ return line;
+}
+#endif
+
+void SISInitVideo(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL;
+ XF86VideoAdaptorPtr newAdaptor = NULL;
+ int num_adaptors;
+
+ newAdaptor = SISSetupImageVideo(pScreen);
+ if(newAdaptor)
+ SISInitOffscreenImages(pScreen);
+
+ num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors);
+
+ if(newAdaptor) {
+ if(!num_adaptors) {
+ num_adaptors = 1;
+ adaptors = &newAdaptor;
+ } else {
+ /* need to free this someplace */
+ newAdaptors = xalloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr*));
+ if(newAdaptors) {
+ memcpy(newAdaptors, adaptors, num_adaptors *
+ sizeof(XF86VideoAdaptorPtr));
+ newAdaptors[num_adaptors] = newAdaptor;
+ adaptors = newAdaptors;
+ num_adaptors++;
+ }
+ }
+ }
+
+ if(num_adaptors)
+ xf86XVScreenInit(pScreen, adaptors, num_adaptors);
+
+ if(newAdaptors)
+ xfree(newAdaptors);
+}
+
+/* client libraries expect an encoding */
+static XF86VideoEncodingRec DummyEncoding =
+{
+ 0,
+ "XV_IMAGE",
+ IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT,
+ {1, 1}
+};
+
+static XF86VideoEncodingRec DummyEncoding_M650 =
+{
+ 0,
+ "XV_IMAGE",
+ IMAGE_MAX_WIDTH_M650, IMAGE_MAX_HEIGHT_M650,
+ {1, 1}
+};
+
+#define NUM_FORMATS 3
+
+static XF86VideoFormatRec SISFormats[NUM_FORMATS] =
+{
+ { 8, PseudoColor},
+ {16, TrueColor},
+ {24, TrueColor}
+};
+
+#define NUM_ATTRIBUTES_300 5
+#define NUM_ATTRIBUTES_325 7
+
+static XF86AttributeRec SISAttributes_300[NUM_ATTRIBUTES_300] =
+{
+ {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"},
+ {XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"},
+ {XvSettable | XvGettable, 0, 7, "XV_CONTRAST"},
+ {XvSettable | XvGettable, 0, 1, "XV_AUTOPAINT_COLORKEY"},
+ {XvSettable , 0, 0, "XV_SET_DEFAULTS"}
+};
+
+static XF86AttributeRec SISAttributes_325[NUM_ATTRIBUTES_325] =
+{
+ {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"},
+ {XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"},
+ {XvSettable | XvGettable, 0, 7, "XV_CONTRAST"},
+ {XvSettable | XvGettable, -7, 7, "XV_SATURATION"},
+ {XvSettable | XvGettable, -8, 7, "XV_HUE"},
+ {XvSettable | XvGettable, 0, 1, "XV_AUTOPAINT_COLORKEY"},
+ {XvSettable , 0, 0, "XV_SET_DEFAULTS"}
+};
+
+#define NUM_IMAGES 6
+#define PIXEL_FMT_YV12 FOURCC_YV12 /* 0x32315659 */
+#define PIXEL_FMT_UYVY FOURCC_UYVY /* 0x59565955 */
+#define PIXEL_FMT_YUY2 FOURCC_YUY2 /* 0x32595559 */
+#define PIXEL_FMT_I420 FOURCC_I420 /* 0x30323449 */
+#define PIXEL_FMT_RGB5 0x35315652
+#define PIXEL_FMT_RGB6 0x36315652
+
+static XF86ImageRec SISImages[NUM_IMAGES] =
+{
+ XVIMAGE_YUY2, /* TW: If order is changed, SISOffscreenImages must be adapted */
+ XVIMAGE_YV12,
+ XVIMAGE_UYVY,
+ XVIMAGE_I420
+ ,
+ { /* RGB 555 */
+ 0x35315652,
+ XvRGB,
+ LSBFirst,
+ {'R','V','1','5',
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ 16,
+ XvPacked,
+ 1,
+/* 15, 0x001F, 0x03E0, 0x7C00, - incorrect! */
+ 15, 0x7C00, 0x03E0, 0x001F,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ {'R', 'V', 'B',0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ XvTopToBottom
+ },
+ { /* RGB 565 */
+ 0x36315652,
+ XvRGB,
+ LSBFirst,
+ {'R','V','1','6',
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ 16,
+ XvPacked,
+ 1,
+/* 16, 0x001F, 0x07E0, 0xF800, - incorrect! */
+ 16, 0xF800, 0x07E0, 0x001F,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ {'R', 'V', 'B',0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ XvTopToBottom
+ }
+};
+
+typedef struct {
+ int pixelFormat;
+
+ CARD16 pitch;
+ CARD16 origPitch;
+
+ CARD8 keyOP;
+ CARD16 HUSF;
+ CARD16 VUSF;
+ CARD8 IntBit;
+ CARD8 wHPre;
+
+ CARD16 srcW;
+ CARD16 srcH;
+
+ BoxRec dstBox;
+
+ CARD32 PSY;
+ CARD32 PSV;
+ CARD32 PSU;
+ CARD8 bobEnable;
+
+ CARD8 contrastCtrl;
+ CARD8 contrastFactor;
+
+ CARD8 lineBufSize;
+
+ CARD8 (*VBlankActiveFunc)(SISPtr);
+#if 0
+ CARD32 (*GetScanLineFunc)(SISPtr pSiS);
+#endif
+
+ CARD16 SCREENheight;
+
+#if 0
+ /* TW: The following are not used yet */
+ CARD16 SubPictHUSF; /* Subpicture scaling */
+ CARD16 SubpictVUSF;
+ CARD8 SubpictIntBit;
+ CARD8 SubPictwHPre;
+ CARD16 SubPictsrcW; /* Subpicture source width */
+ CARD16 SubPictsrcH; /* Subpicture source height */
+ BoxRec SubPictdstBox; /* SubPicture destination box */
+ CARD32 SubPictAddr; /* SubPicture address */
+ CARD32 SubPictPitch; /* SubPicture pitch */
+ CARD32 SubPictOrigPitch; /* SubPicture real pitch (needed for scaling twice) */
+ CARD32 SubPictPreset; /* Subpicture Preset */
+
+ CARD32 MPEG_Y; /* MPEG Y Buffer Addr */
+ CARD32 MPEG_UV; /* MPEG UV Buffer Addr */
+#endif
+
+} SISOverlayRec, *SISOverlayPtr;
+
+typedef struct {
+ FBLinearPtr linear; /* TW: We now use Linear, not Area */
+ CARD32 bufAddr[2];
+
+ unsigned char currentBuf;
+
+ short drw_x, drw_y, drw_w, drw_h;
+ short src_x, src_y, src_w, src_h;
+ int id;
+ short srcPitch, height;
+
+ char brightness;
+ unsigned char contrast;
+ char hue;
+ char saturation;
+
+ RegionRec clip;
+ CARD32 colorKey;
+ Bool autopaintColorKey;
+
+ CARD32 videoStatus;
+ Time offTime;
+ Time freeTime;
+
+ CARD32 displayMode;
+ Bool bridgeIsSlave;
+
+ Bool hasTwoOverlays; /* TW: Chipset has two overlays */
+ Bool dualHeadMode; /* TW: We're running in DHM */
+
+ Bool needToScale; /* TW: Need to scale video */
+
+ int shiftValue; /* 550/650 need word addr/pitch, 630 double word */
+
+ short oldx1, oldx2, oldy1, oldy2;
+ int mustwait;
+
+ Bool grabbedByV4L; /* V4L stuff */
+ int pitch;
+ int offset;
+
+} SISPortPrivRec, *SISPortPrivPtr;
+
+#define GET_PORT_PRIVATE(pScrn) \
+ (SISPortPrivPtr)((SISPTR(pScrn))->adaptor->pPortPrivates[0].ptr)
+
+static void
+SISSetPortDefaults (ScrnInfoPtr pScrn, SISPortPrivPtr pPriv)
+{
+ pPriv->colorKey = 0x000101fe;
+ pPriv->videoStatus = 0;
+ pPriv->brightness = 0;
+ pPriv->contrast = 4;
+ pPriv->hue = 0;
+ pPriv->saturation = 0;
+ pPriv->autopaintColorKey = TRUE;
+}
+
+static void
+SISResetVideo(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ SISPortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn);
+
+ /* Unlock registers */
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+ if (getvideoreg (pSiS, Index_VI_Passwd) != 0xa1) {
+ setvideoreg (pSiS, Index_VI_Passwd, 0x86);
+ if (getvideoreg (pSiS, Index_VI_Passwd) != 0xa1)
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Xv: Video password could not unlock registers\n");
+ }
+
+ /* Initialize first overlay (CRT1) ------------------------------- */
+
+ /* Write-enable video registers */
+ setvideoregmask(pSiS, Index_VI_Control_Misc2, 0x80, 0x81);
+
+ /* Disable overlay */
+ setvideoregmask(pSiS, Index_VI_Control_Misc0, 0x00, 0x02);
+
+ /* Disable bobEnable */
+ setvideoregmask(pSiS, Index_VI_Control_Misc1, 0x02, 0x02);
+
+ /* Reset scale control and contrast */
+ setvideoregmask(pSiS, Index_VI_Scale_Control, 0x60, 0x60);
+ setvideoregmask(pSiS, Index_VI_Contrast_Enh_Ctrl, 0x04, 0x1F);
+
+ setvideoreg(pSiS, Index_VI_Disp_Y_Buf_Preset_Low, 0x00);
+ setvideoreg(pSiS, Index_VI_Disp_Y_Buf_Preset_Middle, 0x00);
+ setvideoreg(pSiS, Index_VI_UV_Buf_Preset_Low, 0x00);
+ setvideoreg(pSiS, Index_VI_UV_Buf_Preset_Middle, 0x00);
+ setvideoreg(pSiS, Index_VI_Disp_Y_UV_Buf_Preset_High, 0x00);
+ setvideoreg(pSiS, Index_VI_Play_Threshold_Low, 0x00);
+ setvideoreg(pSiS, Index_VI_Play_Threshold_High, 0x00);
+
+ /* Initialize second overlay (CRT2) ---- only for 630/730, 550, M650/651 */
+ if (pPriv->hasTwoOverlays) {
+ /* Write-enable video registers */
+ setvideoregmask(pSiS, Index_VI_Control_Misc2, 0x81, 0x81);
+
+ /* Disable overlay */
+ setvideoregmask(pSiS, Index_VI_Control_Misc0, 0x00, 0x02);
+
+ /* Disable bobEnable */
+ setvideoregmask(pSiS, Index_VI_Control_Misc1, 0x02, 0x02);
+
+ /* Reset scale control and contrast */
+ setvideoregmask(pSiS, Index_VI_Scale_Control, 0x60, 0x60);
+ setvideoregmask(pSiS, Index_VI_Contrast_Enh_Ctrl, 0x04, 0x1F);
+
+ setvideoreg(pSiS, Index_VI_Disp_Y_Buf_Preset_Low, 0x00);
+ setvideoreg(pSiS, Index_VI_Disp_Y_Buf_Preset_Middle, 0x00);
+ setvideoreg(pSiS, Index_VI_UV_Buf_Preset_Low, 0x00);
+ setvideoreg(pSiS, Index_VI_UV_Buf_Preset_Middle, 0x00);
+ setvideoreg(pSiS, Index_VI_Disp_Y_UV_Buf_Preset_High, 0x00);
+ setvideoreg(pSiS, Index_VI_Play_Threshold_Low, 0x00);
+ setvideoreg(pSiS, Index_VI_Play_Threshold_High, 0x00);
+ }
+
+ /* set default properties for overlay 1 (CRT1) -------------------------- */
+ setvideoregmask (pSiS, Index_VI_Control_Misc2, 0x00, 0x01);
+ setvideoregmask (pSiS, Index_VI_Contrast_Enh_Ctrl, 0x04, 0x07);
+ setvideoreg (pSiS, Index_VI_Brightness, 0x20);
+ if (pSiS->VGAEngine == SIS_315_VGA) {
+ setvideoreg (pSiS, Index_VI_Hue, 0x00);
+ setvideoreg (pSiS, Index_VI_Saturation, 0x00);
+ }
+
+ /* set default properties for overlay 2(CRT2) only 630/730 and 550 ------ */
+ if (pPriv->hasTwoOverlays) {
+ setvideoregmask (pSiS, Index_VI_Control_Misc2, 0x01, 0x01);
+ setvideoregmask (pSiS, Index_VI_Contrast_Enh_Ctrl, 0x04, 0x07);
+ setvideoreg (pSiS, Index_VI_Brightness, 0x20);
+ if (pSiS->VGAEngine == SIS_315_VGA) {
+ setvideoreg (pSiS, Index_VI_Hue, 0x00);
+ setvideoreg (pSiS, Index_VI_Saturation, 0x00);
+ }
+ }
+}
+
+/* TW: Set display mode (single CRT1/CRT2, mirror).
+ * MIRROR mode is only available on chipsets with two overlays.
+ * On the other chipsets, if only CRT1 or only CRT2 are used,
+ * the correct display CRT is chosen automatically. If both
+ * CRT1 and CRT2 are connected, the user can choose between CRT1 and
+ * CRT2 by using the option XvOnCRT2.
+ */
+static void
+set_dispmode(ScrnInfoPtr pScrn, SISPortPrivPtr pPriv)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+
+ pPriv->dualHeadMode = pPriv->bridgeIsSlave = FALSE;
+
+ if(SiSBridgeIsInSlaveMode(pScrn)) pPriv->bridgeIsSlave = TRUE;
+
+ if( (pSiS->VBFlags & VB_DISPMODE_MIRROR) ||
+ ((pPriv->bridgeIsSlave) && (pSiS->VBFlags & DISPTYPE_DISP2)) ) {
+ if(pPriv->hasTwoOverlays)
+ pPriv->displayMode = DISPMODE_MIRROR; /* TW: CRT1 + CRT2 (2 overlays) */
+ else if(pSiS->XvOnCRT2)
+ pPriv->displayMode = DISPMODE_SINGLE2;
+ else
+ pPriv->displayMode = DISPMODE_SINGLE1;
+ } else {
+#ifdef SISDUALHEAD
+ if(pSiS->DualHeadMode) {
+ pPriv->dualHeadMode = TRUE;
+ if(pSiS->SecondHead)
+ /* TW: Slave is always CRT1 */
+ pPriv->displayMode = DISPMODE_SINGLE1;
+ else
+ /* TW: Master is always CRT2 */
+ pPriv->displayMode = DISPMODE_SINGLE2;
+ } else
+#endif
+ if(pSiS->VBFlags & DISPTYPE_DISP1) {
+ pPriv->displayMode = DISPMODE_SINGLE1; /* TW: CRT1 only */
+ } else {
+ pPriv->displayMode = DISPMODE_SINGLE2; /* TW: CRT2 only */
+ }
+ }
+}
+
+static void
+set_disptype_regs(ScrnInfoPtr pScrn, SISPortPrivPtr pPriv)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+
+ /* TW:
+ * SR06[7:6]
+ * Bit 7: Enable overlay 2 on CRT2
+ * Bit 6: Enable overlay 1 on CRT2
+ * SR32[7:6]
+ * Bit 7: DCLK/TCLK overlay 2
+ * 0=DCLK (overlay on CRT1)
+ * 1=TCLK (overlay on CRT2)
+ * Bit 6: DCLK/TCLK overlay 1
+ * 0=DCLK (overlay on CRT1)
+ * 1=TCLK (overlay on CRT2)
+ *
+ * On chipsets with two overlays, we can freely select and also
+ * have a mirror mode. However, we use overlay 1 for CRT1 and
+ * overlay 2 for CRT2.
+ * For chipsets with only one overlay, user must choose whether
+ * to display the overlay on CRT1 or CRT2 by setting XvOnCRT2
+ * to TRUE (CRT2) or FALSE (CRT1). The hardware does not
+ * support any kind of "Mirror" mode on these chipsets.
+ */
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+ switch (pPriv->displayMode)
+ {
+ case DISPMODE_SINGLE1: /* TW: CRT1 only */
+ if (pPriv->hasTwoOverlays) {
+ if (pPriv->dualHeadMode) {
+ setsrregmask (pSiS, 0x06, 0x00, 0x40);
+ setsrregmask (pSiS, 0x32, 0x00, 0x40);
+ } else {
+ setsrregmask (pSiS, 0x06, 0x00, 0xc0);
+ setsrregmask (pSiS, 0x32, 0x00, 0xc0);
+ }
+ } else {
+ setsrregmask (pSiS, 0x06, 0x00, 0xc0);
+ setsrregmask (pSiS, 0x32, 0x00, 0xc0);
+ }
+ break;
+ case DISPMODE_SINGLE2: /* TW: CRT2 only */
+ if (pPriv->hasTwoOverlays) {
+ if (pPriv->dualHeadMode) {
+ setsrregmask (pSiS, 0x06, 0x80, 0x80);
+ setsrregmask (pSiS, 0x32, 0x80, 0x80);
+ } else {
+ setsrregmask (pSiS, 0x06, 0x80, 0xc0);
+ setsrregmask (pSiS, 0x32, 0x80, 0xc0);
+ }
+ } else {
+ setsrregmask (pSiS, 0x06, 0x40, 0xc0);
+ setsrregmask (pSiS, 0x32, 0x40, 0xc0);
+ }
+ break;
+ case DISPMODE_MIRROR: /* TW: CRT1 + CRT2 */
+ default:
+ setsrregmask (pSiS, 0x06, 0x80, 0xc0);
+ setsrregmask (pSiS, 0x32, 0x80, 0xc0);
+ break;
+ }
+}
+
+static XF86VideoAdaptorPtr
+SISSetupImageVideo(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ SISPtr pSiS = SISPTR(pScrn);
+ XF86VideoAdaptorPtr adapt;
+ SISPortPrivPtr pPriv;
+
+ if(!(adapt = xcalloc(1, sizeof(XF86VideoAdaptorRec) +
+ sizeof(SISPortPrivRec) +
+ sizeof(DevUnion))))
+ return NULL;
+
+ adapt->type = XvWindowMask | XvInputMask | XvImageMask;
+ adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
+ adapt->name = "SIS 300/310/325 series Video Overlay";
+ adapt->nEncodings = 1;
+ if(pSiS->Flags650 & SiS650_LARGEOVERLAY) {
+ adapt->pEncodings = &DummyEncoding_M650;
+ } else {
+ adapt->pEncodings = &DummyEncoding;
+ }
+ adapt->nFormats = NUM_FORMATS;
+ adapt->pFormats = SISFormats;
+ adapt->nPorts = 1;
+ adapt->pPortPrivates = (DevUnion*)(&adapt[1]);
+
+ pPriv = (SISPortPrivPtr)(&adapt->pPortPrivates[1]);
+
+ adapt->pPortPrivates[0].ptr = (pointer)(pPriv);
+ adapt->nImages = NUM_IMAGES;
+ if(pSiS->VGAEngine == SIS_300_VGA) {
+ adapt->pAttributes = SISAttributes_300;
+ adapt->nAttributes = NUM_ATTRIBUTES_300;
+ } else {
+ adapt->pAttributes = SISAttributes_325;
+ adapt->nAttributes = NUM_ATTRIBUTES_325;
+ }
+ adapt->pImages = SISImages;
+ adapt->PutVideo = NULL;
+ adapt->PutStill = NULL;
+ adapt->GetVideo = NULL;
+ adapt->GetStill = NULL;
+ adapt->StopVideo = SISStopVideo;
+ adapt->SetPortAttribute = SISSetPortAttribute;
+ adapt->GetPortAttribute = SISGetPortAttribute;
+ adapt->QueryBestSize = SISQueryBestSize;
+ adapt->PutImage = SISPutImage;
+ adapt->QueryImageAttributes = SISQueryImageAttributes;
+
+ pPriv->videoStatus = 0;
+ pPriv->currentBuf = 0;
+ pPriv->linear = NULL;
+ pPriv->grabbedByV4L= FALSE;
+
+ SISSetPortDefaults(pScrn, pPriv);
+
+ /* gotta uninit this someplace */
+ REGION_INIT(pScreen, &pPriv->clip, NullBox, 0);
+
+ pSiS->adaptor = adapt;
+
+ pSiS->xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
+ pSiS->xvContrast = MAKE_ATOM("XV_CONTRAST");
+ pSiS->xvColorKey = MAKE_ATOM("XV_COLORKEY");
+ if(pSiS->VGAEngine == SIS_315_VGA) {
+ pSiS->xvSaturation = MAKE_ATOM("XV_SATURATION");
+ pSiS->xvHue = MAKE_ATOM("XV_HUE");
+ }
+ pSiS->xvAutopaintColorKey = MAKE_ATOM("XV_AUTOPAINT_COLORKEY");
+ pSiS->xvSetDefaults = MAKE_ATOM("XV_SET_DEFAULTS");
+
+ /* TW: Setup chipset type helpers */
+ if (pSiS->hasTwoOverlays)
+ pPriv->hasTwoOverlays = TRUE;
+ else
+ pPriv->hasTwoOverlays = FALSE;
+
+ /* TW: 300 series require double words for addresses and pitches,
+ * 310/325 series accept word.
+ */
+ switch (pSiS->VGAEngine) {
+ case SIS_315_VGA:
+ pPriv->shiftValue = 1;
+ break;
+ case SIS_300_VGA:
+ default:
+ pPriv->shiftValue = 2;
+ break;
+ }
+
+ /* Set displayMode according to VBFlags */
+ set_dispmode(pScrn, pPriv);
+
+ /* Set SR(06, 32) registers according to DISPMODE */
+ set_disptype_regs(pScrn, pPriv);
+
+ SISResetVideo(pScrn);
+
+ return adapt;
+}
+
+static Bool
+RegionsEqual(RegionPtr A, RegionPtr B)
+{
+ int *dataA, *dataB;
+ int num;
+
+ num = REGION_NUM_RECTS(A);
+ if(num != REGION_NUM_RECTS(B))
+ return FALSE;
+
+ if((A->extents.x1 != B->extents.x1) ||
+ (A->extents.x2 != B->extents.x2) ||
+ (A->extents.y1 != B->extents.y1) ||
+ (A->extents.y2 != B->extents.y2))
+ return FALSE;
+
+ dataA = (int*)REGION_RECTS(A);
+ dataB = (int*)REGION_RECTS(B);
+
+ while(num--) {
+ if((dataA[0] != dataB[0]) || (dataA[1] != dataB[1]))
+ return FALSE;
+ dataA += 2;
+ dataB += 2;
+ }
+
+ return TRUE;
+}
+
+static int
+SISSetPortAttribute(ScrnInfoPtr pScrn, Atom attribute,
+ INT32 value, pointer data)
+{
+ SISPortPrivPtr pPriv = (SISPortPrivPtr)data;
+ SISPtr pSiS = SISPTR(pScrn);
+
+ if(attribute == pSiS->xvBrightness) {
+ if((value < -128) || (value > 127))
+ return BadValue;
+ pPriv->brightness = value;
+ } else if(attribute == pSiS->xvContrast) {
+ if((value < 0) || (value > 7))
+ return BadValue;
+ pPriv->contrast = value;
+ } else if(attribute == pSiS->xvColorKey) {
+ pPriv->colorKey = value;
+ REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
+ } else if(attribute == pSiS->xvAutopaintColorKey) {
+ if ((value < 0) || (value > 1))
+ return BadValue;
+ pPriv->autopaintColorKey = value;
+ } else if(attribute == pSiS->xvSetDefaults) {
+ SISSetPortDefaults(pScrn, pPriv);
+ } else if(pSiS->VGAEngine == SIS_315_VGA) {
+ if(attribute == pSiS->xvHue) {
+ if((value < -8) || (value > 7))
+ return BadValue;
+ pPriv->hue = value;
+ } else if(attribute == pSiS->xvSaturation) {
+ if((value < -7) || (value > 7))
+ return BadValue;
+ pPriv->saturation = value;
+ } else return BadMatch;
+ } else return BadMatch;
+ return Success;
+}
+
+static int
+SISGetPortAttribute(
+ ScrnInfoPtr pScrn,
+ Atom attribute,
+ INT32 *value,
+ pointer data
+){
+ SISPortPrivPtr pPriv = (SISPortPrivPtr)data;
+ SISPtr pSiS = SISPTR(pScrn);
+
+ if(attribute == pSiS->xvBrightness) {
+ *value = pPriv->brightness;
+ } else if(attribute == pSiS->xvContrast) {
+ *value = pPriv->contrast;
+ } else if(attribute == pSiS->xvColorKey) {
+ *value = pPriv->colorKey;
+ } else if (attribute == pSiS->xvAutopaintColorKey) {
+ *value = (pPriv->autopaintColorKey) ? 1 : 0;
+ } else if(pSiS->VGAEngine == SIS_315_VGA) {
+ if(attribute == pSiS->xvHue) {
+ *value = pPriv->hue;
+ } else if(attribute == pSiS->xvSaturation) {
+ *value = pPriv->saturation;
+ } else return BadMatch;
+ } else return BadMatch;
+ return Success;
+}
+
+static void
+SISQueryBestSize(
+ ScrnInfoPtr pScrn,
+ Bool motion,
+ short vid_w, short vid_h,
+ short drw_w, short drw_h,
+ unsigned int *p_w, unsigned int *p_h,
+ pointer data
+){
+ *p_w = drw_w;
+ *p_h = drw_h;
+}
+
+static void
+calc_scale_factor(SISOverlayPtr pOverlay, ScrnInfoPtr pScrn,
+ SISPortPrivPtr pPriv, int index, int iscrt2)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ CARD32 I=0,mult=0;
+ int flag=0;
+
+ int dstW = pOverlay->dstBox.x2 - pOverlay->dstBox.x1;
+ int dstH = pOverlay->dstBox.y2 - pOverlay->dstBox.y1;
+ int srcW = pOverlay->srcW;
+ int srcH = pOverlay->srcH;
+ CARD16 LCDheight = pSiS->LCDheight;
+ int srcPitch = pOverlay->origPitch;
+ int origdstH = dstH;
+
+ /* TW: Stretch image due to idiotic LCD "auto"-scaling on LVDS (and 630+301B) */
+ if(pSiS->VBFlags & CRT2_LCD) {
+ if(pPriv->bridgeIsSlave) {
+ if(pSiS->VBFlags & VB_LVDS) {
+ dstH = (dstH * LCDheight) / pOverlay->SCREENheight;
+ } else if( (pSiS->VGAEngine == SIS_300_VGA) &&
+ (pSiS->VBFlags & (VB_301B|VB_302B|VB_30xLV|VB_30xLVX)) ) {
+ dstH = (dstH * LCDheight) / pOverlay->SCREENheight;
+ }
+ } else if(iscrt2) {
+ if (pSiS->VBFlags & VB_LVDS) {
+ dstH = (dstH * LCDheight) / pOverlay->SCREENheight;
+ if (pPriv->displayMode == DISPMODE_MIRROR) flag = 1;
+ } else if ( (pSiS->VGAEngine == SIS_300_VGA) &&
+ (pSiS->VBFlags & (VB_301B|VB_302B|VB_30xLV|VB_30xLVX)) ) {
+ dstH = (dstH * LCDheight) / pOverlay->SCREENheight;
+ if (pPriv->displayMode == DISPMODE_MIRROR) flag = 1;
+ }
+ }
+ }
+ /* TW: For double scan modes, we need to double the height
+ * (Perhaps we also need to scale LVDS, but I'm not sure.)
+ * On 310/325 series, we need to double the width as well.
+ * Interlace mode vice versa.
+ */
+ if(pSiS->CurrentLayout.mode->Flags & V_DBLSCAN) {
+ dstH = origdstH << 1;
+ flag = 0;
+ if(pSiS->VGAEngine == SIS_315_VGA) {
+ dstW <<= 1;
+ }
+ }
+ if(pSiS->CurrentLayout.mode->Flags & V_INTERLACE) {
+ dstH = origdstH >> 1;
+ flag = 0;
+ }
+
+ if(dstW < OVERLAY_MIN_WIDTH) dstW = OVERLAY_MIN_WIDTH;
+ if (dstW == srcW) {
+ pOverlay->HUSF = 0x00;
+ pOverlay->IntBit = 0x05;
+ pOverlay->wHPre = 0;
+ } else if (dstW > srcW) {
+ dstW += 2;
+ pOverlay->HUSF = (srcW << 16) / dstW;
+ pOverlay->IntBit = 0x04;
+ pOverlay->wHPre = 0;
+ } else {
+ int tmpW = dstW;
+
+ /* TW: It seems, the hardware can't scale below factor .125 (=1/8) if the
+ pitch isn't a multiple of 256.
+ TODO: Test this on the 310/325 series!
+ */
+ if((srcPitch % 256) || (srcPitch < 256)) {
+ if(((dstW * 1000) / srcW) < 125) dstW = tmpW = ((srcW * 125) / 1000) + 1;
+ }
+
+ I = 0;
+ pOverlay->IntBit = 0x01;
+ while (srcW >= tmpW) {
+ tmpW <<= 1;
+ I++;
+ }
+ pOverlay->wHPre = (CARD8)(I - 1);
+ dstW <<= (I - 1);
+ if ((srcW % dstW))
+ pOverlay->HUSF = ((srcW - dstW) << 16) / dstW;
+ else
+ pOverlay->HUSF = 0x00;
+ }
+
+ if(dstH < OVERLAY_MIN_HEIGHT) dstH = OVERLAY_MIN_HEIGHT;
+ if (dstH == srcH) {
+ pOverlay->VUSF = 0x00;
+ pOverlay->IntBit |= 0x0A;
+ } else if (dstH > srcH) {
+ dstH += 0x02;
+ pOverlay->VUSF = (srcH << 16) / dstH;
+ pOverlay->IntBit |= 0x08;
+ } else {
+ CARD32 realI;
+
+ I = realI = srcH / dstH;
+ pOverlay->IntBit |= 0x02;
+
+ if (I < 2) {
+ pOverlay->VUSF = ((srcH - dstH) << 16) / dstH;
+ /* TW: Needed for LCD-scaling modes */
+ if ((flag) && (mult = (srcH / origdstH)) >= 2)
+ pOverlay->pitch /= mult;
+ } else {
+#if 0
+ if (((pOverlay->bobEnable & 0x08) == 0x00) &&
+ (((srcPitch * I)>>2) > 0xFFF)){
+ pOverlay->bobEnable |= 0x08;
+ srcPitch >>= 1;
+ }
+#endif
+ if (((srcPitch * I)>>2) > 0xFFF) {
+ I = (0xFFF*2/srcPitch);
+ pOverlay->VUSF = 0xFFFF;
+ } else {
+ dstH = I * dstH;
+ if (srcH % dstH)
+ pOverlay->VUSF = ((srcH - dstH) << 16) / dstH;
+ else
+ pOverlay->VUSF = 0x00;
+ }
+ /* set video frame buffer offset */
+ pOverlay->pitch = (CARD16)(srcPitch*I);
+ }
+ }
+}
+
+static void
+set_line_buf_size(SISOverlayPtr pOverlay)
+{
+ CARD8 preHIDF;
+ CARD32 I;
+ CARD32 line = pOverlay->srcW;
+
+ if ( (pOverlay->pixelFormat == PIXEL_FMT_YV12) ||
+ (pOverlay->pixelFormat == PIXEL_FMT_I420) )
+ {
+ preHIDF = pOverlay->wHPre & 0x07;
+ switch (preHIDF)
+ {
+ case 3 :
+ if ((line & 0xffffff00) == line)
+ I = (line >> 8);
+ else
+ I = (line >> 8) + 1;
+ pOverlay->lineBufSize = (CARD8)(I * 32 - 1);
+ break;
+ case 4 :
+ if ((line & 0xfffffe00) == line)
+ I = (line >> 9);
+ else
+ I = (line >> 9) + 1;
+ pOverlay->lineBufSize = (CARD8)(I * 64 - 1);
+ break;
+ case 5 :
+ if ((line & 0xfffffc00) == line)
+ I = (line >> 10);
+ else
+ I = (line >> 10) + 1;
+ pOverlay->lineBufSize = (CARD8)(I * 128 - 1);
+ break;
+ case 6 :
+ if ((line & 0xfffff800) == line)
+ I = (line >> 11);
+ else
+ I = (line >> 11) + 1;
+ pOverlay->lineBufSize = (CARD8)(I * 256 - 1);
+ break;
+ default :
+ if ((line & 0xffffff80) == line)
+ I = (line >> 7);
+ else
+ I = (line >> 7) + 1;
+ pOverlay->lineBufSize = (CARD8)(I * 16 - 1);
+ break;
+ }
+ } else { /* YUV2, UYVY */
+ if ((line & 0xffffff8) == line)
+ I = (line >> 3);
+ else
+ I = (line >> 3) + 1;
+ pOverlay->lineBufSize = (CARD8)(I - 1);
+ }
+}
+
+static void
+merge_line_buf(SISPtr pSiS, SISPortPrivPtr pPriv, Bool enable)
+{
+ if(enable) {
+ switch (pPriv->displayMode){
+ case DISPMODE_SINGLE1:
+ if (pPriv->hasTwoOverlays) {
+ if (pPriv->dualHeadMode) {
+ /* line merge */
+ setvideoregmask(pSiS, Index_VI_Control_Misc2, 0x00, 0x11);
+ setvideoregmask(pSiS, Index_VI_Control_Misc1, 0x04, 0x04);
+ } else {
+ /* dual line merge */
+ setvideoregmask(pSiS, Index_VI_Control_Misc2, 0x10, 0x11);
+ setvideoregmask(pSiS, Index_VI_Control_Misc1, 0x00, 0x04);
+ }
+ } else {
+ setvideoregmask(pSiS, Index_VI_Control_Misc2, 0x10, 0x11);
+ setvideoregmask(pSiS, Index_VI_Control_Misc1, 0x00, 0x04);
+ }
+ break;
+ case DISPMODE_SINGLE2:
+ if (pPriv->hasTwoOverlays) {
+ if (pPriv->dualHeadMode) {
+ /* line merge */
+ setvideoregmask(pSiS, Index_VI_Control_Misc2, 0x01, 0x11);
+ setvideoregmask(pSiS, Index_VI_Control_Misc1, 0x04, 0x04);
+ } else {
+ /* line merge */
+ setvideoregmask(pSiS, Index_VI_Control_Misc2, 0x01, 0x11);
+ setvideoregmask(pSiS, Index_VI_Control_Misc1, 0x04, 0x04);
+ }
+ } else {
+ setvideoregmask(pSiS, Index_VI_Control_Misc2, 0x10, 0x11);
+ setvideoregmask(pSiS, Index_VI_Control_Misc1, 0x00, 0x04);
+ }
+ break;
+ case DISPMODE_MIRROR:
+ default:
+ /* line merge */
+ setvideoregmask(pSiS, Index_VI_Control_Misc2, 0x00, 0x11);
+ setvideoregmask(pSiS, Index_VI_Control_Misc1, 0x04, 0x04);
+ if (pPriv->hasTwoOverlays) {
+ /* line merge */
+ setvideoregmask(pSiS, Index_VI_Control_Misc2, 0x01, 0x11);
+ setvideoregmask(pSiS, Index_VI_Control_Misc1, 0x04, 0x04);
+ }
+ break;
+ }
+ } else {
+ switch (pPriv->displayMode) {
+ case DISPMODE_SINGLE1:
+ setvideoregmask(pSiS, Index_VI_Control_Misc2, 0x00, 0x11);
+ setvideoregmask(pSiS, Index_VI_Control_Misc1, 0x00, 0x04);
+ break;
+ case DISPMODE_SINGLE2:
+ if (pPriv->hasTwoOverlays) {
+ setvideoregmask(pSiS, Index_VI_Control_Misc2, 0x01, 0x11);
+ setvideoregmask(pSiS, Index_VI_Control_Misc1, 0x00, 0x04);
+ } else {
+ setvideoregmask(pSiS, Index_VI_Control_Misc2, 0x00, 0x11);
+ setvideoregmask(pSiS, Index_VI_Control_Misc1, 0x00, 0x04);
+ }
+ break;
+ case DISPMODE_MIRROR:
+ default:
+ setvideoregmask(pSiS, Index_VI_Control_Misc2, 0x00, 0x11);
+ setvideoregmask(pSiS, Index_VI_Control_Misc1, 0x00, 0x04);
+ if (pPriv->hasTwoOverlays) {
+ setvideoregmask(pSiS, Index_VI_Control_Misc2, 0x01, 0x11);
+ setvideoregmask(pSiS, Index_VI_Control_Misc1, 0x00, 0x04);
+ }
+ break;
+ }
+ }
+}
+
+static void
+set_format(SISPtr pSiS, SISOverlayPtr pOverlay)
+{
+ CARD8 fmt;
+
+ switch (pOverlay->pixelFormat){
+ case PIXEL_FMT_YV12:
+ case PIXEL_FMT_I420:
+ fmt = 0x0c;
+ break;
+ case PIXEL_FMT_YUY2:
+ fmt = 0x28;
+ break;
+ case PIXEL_FMT_UYVY:
+ fmt = 0x08;
+ break;
+ case PIXEL_FMT_RGB5: /* D[5:4] : 00 RGB555, 01 RGB 565 */
+ fmt = 0x00;
+ break;
+ case PIXEL_FMT_RGB6:
+ fmt = 0x10;
+ break;
+ default:
+ fmt = 0x00;
+ break;
+ }
+ setvideoregmask(pSiS, Index_VI_Control_Misc0, fmt, 0x7c);
+}
+
+static void
+set_colorkey(SISPtr pSiS, CARD32 colorkey)
+{
+ CARD8 r, g, b;
+
+ b = (CARD8)(colorkey & 0xFF);
+ g = (CARD8)((colorkey>>8) & 0xFF);
+ r = (CARD8)((colorkey>>16) & 0xFF);
+
+ /* Activate the colorkey mode */
+ setvideoreg(pSiS, Index_VI_Overlay_ColorKey_Blue_Min ,(CARD8)b);
+ setvideoreg(pSiS, Index_VI_Overlay_ColorKey_Green_Min ,(CARD8)g);
+ setvideoreg(pSiS, Index_VI_Overlay_ColorKey_Red_Min ,(CARD8)r);
+
+ setvideoreg(pSiS, Index_VI_Overlay_ColorKey_Blue_Max ,(CARD8)b);
+ setvideoreg(pSiS, Index_VI_Overlay_ColorKey_Green_Max ,(CARD8)g);
+ setvideoreg(pSiS, Index_VI_Overlay_ColorKey_Red_Max ,(CARD8)r);
+}
+
+static void
+set_brightness(SISPtr pSiS, CARD8 brightness)
+{
+ setvideoreg(pSiS, Index_VI_Brightness, brightness);
+}
+
+static void
+set_contrast(SISPtr pSiS, CARD8 contrast)
+{
+ setvideoregmask(pSiS, Index_VI_Contrast_Enh_Ctrl, contrast, 0x07);
+}
+
+/* 310/325 series only */
+static void
+set_saturation(SISPtr pSiS, char saturation)
+{
+ CARD8 temp = 0;
+
+ if(saturation < 0) {
+ temp |= 0x88;
+ saturation = -saturation;
+ }
+ temp |= (saturation & 0x07);
+ temp |= ((saturation & 0x07) << 4);
+
+ setvideoreg(pSiS, Index_VI_Saturation, temp);
+}
+
+/* 310/325 series only */
+static void
+set_hue(SISPtr pSiS, CARD8 hue)
+{
+ setvideoreg(pSiS, Index_VI_Hue, (hue & 0x08) ? (hue ^ 0x07) : hue);
+}
+
+#ifdef NOT_YET_IMPLEMENTED /* ----------- TW: FOR FUTURE USE -------------------- */
+
+/* TW: Set Alpha */
+static void
+set_alpha(SISPtr pSiS, CARD8 alpha)
+{
+ CARD8 data;
+
+ data = getvideoreg(pSiS, Index_VI_Key_Overlay_OP);
+ data &= 0x0F;
+ setvideoreg(pSiS,Index_VI_Key_Overlay_OP, data | (alpha << 4));
+}
+
+/* TW: Set SubPicture Start Address (yet unused) */
+static void
+set_subpict_start_offset(SISPtr pSiS, SISOverlayPtr pOverlay, int index)
+{
+ CARD32 temp;
+ CARD8 data;
+
+ temp = pOverlay->SubPictAddr >> 4; /* TW: 630 <-> 315 shiftValue? */
+
+ setvideoreg(pSiS,Index_VI_SubPict_Buf_Start_Low, temp & 0xFF);
+ setvideoreg(pSiS,Index_VI_SubPict_Buf_Start_Middle, (temp>>8) & 0xFF);
+ setvideoreg(pSiS,Index_VI_SubPict_Buf_Start_High, (temp>>16) & 0x3F);
+ if (pSiS->VGAEngine == SIS_315_VGA) {
+ setvideoreg(pSiS,Index_VI_SubPict_Start_Over, (temp>>22) & 0x01);
+ /* Submit SubPict offset ? */
+ /* data=getvideoreg(pSiS,Index_VI_Control_Misc3); */
+ setvideoreg(pSiS,Index_VI_Control_Misc3, (1 << index) | 0x04);
+ }
+}
+
+/* TW: Set SubPicture Pitch (yet unused) */
+static void
+set_subpict_pitch(SISPtr pSiS, SISOverlayPtr pOverlay, int index)
+{
+ CARD32 temp;
+ CARD8 data;
+
+ temp = pOverlay->SubPictPitch >> 4; /* TW: 630 <-> 315 shiftValue? */
+
+ setvideoreg(pSiS,Index_VI_SubPict_Buf_Pitch, temp & 0xFF);
+ if (pSiS->VGAEngine == SIS_315_VGA) {
+ setvideoreg(pSiS,Index_VI_SubPict_Buf_Pitch_High, (temp>>8) & 0xFF);
+ /* Submit SubPict pitch ? */
+ /* data=getvideoreg(pSiS,Index_VI_Control_Misc3); */
+ setvideoreg(pSiS,Index_VI_Control_Misc3, (1 << index) | 0x04);
+ }
+}
+
+/* TW: Calculate and set SubPicture scaling (untested, unused yet) */
+static void
+set_subpict_scale_factor(SISOverlayPtr pOverlay, ScrnInfoPtr pScrn,
+ SISPortPrivPtr pPriv, int index, int iscrt2)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ CARD32 I=0,mult=0;
+ int flag=0;
+
+ int dstW = pOverlay->SubPictdstBox.x2 - pOverlay->SubPictdstBox.x1;
+ int dstH = pOverlay->SubPictdstBox.y2 - pOverlay->SubPictdstBox.y1;
+ int srcW = pOverlay->SubPictsrcW;
+ int srcH = pOverlay->SubPictsrcH;
+ CARD16 LCDheight = pSiS->LCDheight;
+ int srcPitch = pOverlay->SubPictOrigPitch;
+ int origdstH = dstH;
+
+ /* TW: Stretch image due to idiotic LCD "auto"-scaling */
+ /* INCOMPLETE - See set_scale_factor() */
+ if ( (pPriv->bridgeIsSlave) && (pSiS->VBFlags & CRT2_LCD) ) {
+ dstH = (dstH * LCDheight) / pOverlay->SCREENheight;
+ } else if ((index) && (pSiS->VBFlags & CRT2_LCD)) {
+ dstH = (dstH * LCDheight) / pOverlay->SCREENheight;
+ if (pPriv->displayMode == DISPMODE_MIRROR) flag = 1;
+ }
+
+ if (dstW == srcW) {
+ pOverlay->SubPictHUSF = 0x00;
+ pOverlay->SubPictIntBit = 0x01;
+ } else if (dstW > srcW) {
+ pOverlay->SubPictHUSF = (srcW << 16) / dstW;
+ pOverlay->SubPictIntBit = 0x00;
+ } else {
+ int tmpW = dstW;
+
+ I = 0x00;
+ while (srcW >= tmpW) {
+ tmpW <<= 1;
+ I++;
+ }
+ pOverlay->SubPictwHPre = (CARD8)(I - 1);
+ dstW <<= (I - 1);
+ if ((srcW % dstW))
+ pOverlay->SubPictHUSF = ((srcW - dstW) << 16) / dstW;
+ else
+ pOverlay->SubPictHUSF = 0x00;
+
+ pOverlay->SubPictIntBit = 0x01;
+ }
+
+ if (dstH == srcH) {
+ pOverlay->SubPictVUSF = 0x00;
+ pOverlay->SubPictIntBit |= 0x02;
+ } else if (dstH > srcH) {
+ dstH += 0x02;
+ pOverlay->SubPictVUSF = (srcH << 16) / dstH;
+ /* pOverlay->SubPictIntBit |= 0x00; */
+ } else {
+ CARD32 realI;
+
+ I = realI = srcH / dstH;
+ pOverlay->SubPictIntBit |= 0x02;
+
+ if (I < 2) {
+ pOverlay->SubPictVUSF = ((srcH - dstH) << 16) / dstH;
+ /* TW: Needed for LCD-scaling modes */
+ if ((flag) && (mult = (srcH / origdstH)) >= 2)
+ pOverlay->SubPictPitch /= mult;
+ } else {
+ if (((srcPitch * I)>>2) > 0xFFF) {
+ I = (0xFFF*2/srcPitch);
+ pOverlay->SubPictVUSF = 0xFFFF;
+ } else {
+ dstH = I * dstH;
+ if (srcH % dstH)
+ pOverlay->SubPictVUSF = ((srcH - dstH) << 16) / dstH;
+ else
+ pOverlay->SubPictVUSF = 0x00;
+ }
+ /* set video frame buffer offset */
+ pOverlay->SubPictPitch = (CARD16)(srcPitch*I);
+ }
+ }
+ /* set SubPicture scale factor */
+ setvideoreg (pSiS, Index_VI_SubPict_Hor_Scale_Low, (CARD8)(pOverlay->SubPictHUSF));
+ setvideoreg (pSiS, Index_VI_SubPict_Hor_Scale_High, (CARD8)((pOverlay->SubPictHUSF)>>8));
+ setvideoreg (pSiS, Index_VI_SubPict_Vert_Scale_Low, (CARD8)(pOverlay->SubPictVUSF));
+ setvideoreg (pSiS, Index_VI_SubPict_Vert_Scale_High,(CARD8)((pOverlay->SubPictVUSF)>>8));
+
+ setvideoregmask (pSiS, Index_VI_SubPict_Scale_Control,
+ (pOverlay->SubPictIntBit << 3) |
+ (pOverlay->SubPictwHPre), 0x7f);
+}
+
+/* TW: Set SubPicture Preset (yet unused) */
+static void
+set_subpict_preset(SISPtr pSiS, SISOverlayPtr pOverlay)
+{
+ CARD32 temp;
+ CARD8 data;
+
+ temp = pOverlay->SubPictPreset >> 4; /* TW: 630 <-> 315 ? */
+
+ setvideoreg(pSiS,Index_VI_SubPict_Buf_Preset_Low, temp & 0xFF);
+ setvideoreg(pSiS,Index_VI_SubPict_Buf_Preset_Middle, (temp>>8) & 0xFF);
+ data = getvideoreg(pSiS,Index_VI_SubPict_Buf_Start_High);
+ if (temp > 0xFFFF)
+ data |= 0x40;
+ else
+ data &= ~0x40;
+ setvideoreg(pSiS,Index_VI_SubPict_Buf_Start_High, data);
+}
+
+static void
+enable_subpict_overlay(SISPtr pSiS, Bool enable)
+{
+ setvideoregmask(pSiS, Index_VI_SubPict_Scale_Control,
+ enable ? 0x40 : 0x00,
+ 0x40);
+}
+
+/* TW: Set overlay for subpicture */
+static void
+set_subpict_overlay(SISPtr pSiS, SISOverlayPtr pOverlay, SISPortPrivPtr pPriv, int index)
+{
+ ScrnInfoPtr pScrn = pSiS->pScrn;
+
+ set_subpict_pitch(pSiS, &overlay, index);
+ set_subpict_start_offset(pSiS, &overlay, index);
+ set_subpict_scale_factor(&overlay, pScrn, pPriv, index);
+ /* set_subpict_preset(pSiS, &overlay); */
+ /* enable_subpict_overlay(pSiS, 1); */
+}
+
+
+/* TW: Set MPEG Field Preset (yet unused) */
+static void
+set_mpegfield_preset(SISPtr pSiS, SISOverlayPtr pOverlay)
+{
+ setvideoreg(pSiS,Index_MPEG_Y_Buf_Preset_Low, pOverlay->MPEG_Y & 0xFF);
+ setvideoreg(pSiS,Index_MPEG_Y_Buf_Preset_Middle, (pOverlay->MPEG_Y>>8) & 0xFF);
+
+ setvideoreg(pSiS,Index_MPEG_UV_Buf_Preset_Low, pOverlay->MPEG_UV & 0xFF);
+ setvideoreg(pSiS,Index_MPEG_UV_Buf_Preset_Middle, (pOverlay->MPEG_UV>>8) & 0xFF);
+
+ setvideoreg(pSiS,Index_MPEG_Y_UV_Buf_Preset_High,
+ ((pOverlay->MPEG_Y>>16) & 0x0F) | ((pOverlay->MPEG_UV>>12) & 0xF0));
+}
+
+static void
+set_mpegfield_scale(SISPtr pSiS, SISOverlayPtr pOverlay)
+{
+ /* Empty for now */
+}
+
+#endif /* ------------------------------------------------------------------- */
+
+static void
+set_overlay(SISPtr pSiS, SISOverlayPtr pOverlay, SISPortPrivPtr pPriv, int index)
+{
+ ScrnInfoPtr pScrn = pSiS->pScrn;
+
+ CARD16 pitch=0;
+ CARD8 h_over=0, v_over=0;
+ CARD16 top, bottom, left, right;
+ CARD16 screenX = pSiS->CurrentLayout.mode->HDisplay;
+ CARD16 screenY = pSiS->CurrentLayout.mode->VDisplay;
+ CARD8 data;
+ CARD32 watchdog;
+
+ top = pOverlay->dstBox.y1;
+ bottom = pOverlay->dstBox.y2;
+ if (bottom > screenY) {
+ bottom = screenY;
+ }
+
+ left = pOverlay->dstBox.x1;
+ right = pOverlay->dstBox.x2;
+ if (right > screenX) {
+ right = screenX;
+ }
+
+ /* TW: DoubleScan modes require Y coordinates * 2 */
+ if(pSiS->CurrentLayout.mode->Flags & V_DBLSCAN) {
+ top <<= 1;
+ bottom <<= 1;
+ }
+ /* TW: Interlace modes require Y coordinates / 2 */
+ if(pSiS->CurrentLayout.mode->Flags & V_INTERLACE) {
+ top >>= 1;
+ bottom >>= 1;
+ }
+
+ h_over = (((left>>8) & 0x0f) | ((right>>4) & 0xf0));
+ v_over = (((top>>8) & 0x0f) | ((bottom>>4) & 0xf0));
+
+ pitch = pOverlay->pitch >> pPriv->shiftValue;
+
+ /* set line buffer size */
+ setvideoreg(pSiS, Index_VI_Line_Buffer_Size, pOverlay->lineBufSize);
+
+ /* set color key mode */
+ setvideoregmask (pSiS, Index_VI_Key_Overlay_OP, pOverlay->keyOP, 0x0f);
+
+ /* TW: We don't have to wait for vertical retrace in all cases */
+ if(pPriv->mustwait) {
+ watchdog = WATCHDOG_DELAY;
+ while (pOverlay->VBlankActiveFunc(pSiS) && --watchdog);
+ watchdog = WATCHDOG_DELAY;
+ while ((!pOverlay->VBlankActiveFunc(pSiS)) && --watchdog);
+ if (!watchdog) xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Xv: Waiting for vertical retrace timed-out\n");
+ }
+
+ /* Unlock address registers */
+ data = getvideoreg(pSiS, Index_VI_Control_Misc1);
+ setvideoreg (pSiS, Index_VI_Control_Misc1, data | 0x20);
+ /* TEST: Is this required? */
+ setvideoreg (pSiS, Index_VI_Control_Misc1, data | 0x20);
+ /* TEST end */
+
+ /* TEST: Is this required? */
+ if (pSiS->Chipset == SIS_315_VGA)
+ setvideoreg (pSiS, Index_VI_Control_Misc3, 0x00);
+ /* TEST end */
+
+ /* Set Y buf pitch */
+ setvideoreg (pSiS, Index_VI_Disp_Y_Buf_Pitch_Low, (CARD8)(pitch));
+ setvideoregmask (pSiS, Index_VI_Disp_Y_UV_Buf_Pitch_Middle, (CARD8)(pitch>>8), 0x0f);
+
+ /* Set Y start address */
+ setvideoreg (pSiS, Index_VI_Disp_Y_Buf_Start_Low, (CARD8)(pOverlay->PSY));
+ setvideoreg (pSiS, Index_VI_Disp_Y_Buf_Start_Middle, (CARD8)((pOverlay->PSY)>>8));
+ setvideoreg (pSiS, Index_VI_Disp_Y_Buf_Start_High, (CARD8)((pOverlay->PSY)>>16));
+
+ /* set 310/325 series overflow bits for Y plane */
+ if (pSiS->VGAEngine == SIS_315_VGA) {
+ setvideoreg (pSiS, Index_VI_Disp_Y_Buf_Pitch_High, (CARD8)(pitch>>12));
+ setvideoreg (pSiS, Index_VI_Y_Buf_Start_Over, ((CARD8)((pOverlay->PSY)>>24) & 0x01));
+ }
+
+ /* Set U/V data if using plane formats */
+ if ( (pOverlay->pixelFormat == PIXEL_FMT_YV12) ||
+ (pOverlay->pixelFormat == PIXEL_FMT_I420) ) {
+
+ CARD32 PSU=0, PSV=0;
+
+ PSU = pOverlay->PSU;
+ PSV = pOverlay->PSV;
+
+ /* Set U/V pitch */
+ setvideoreg (pSiS, Index_VI_Disp_UV_Buf_Pitch_Low, (CARD8)(pitch >> 1));
+ setvideoregmask (pSiS, Index_VI_Disp_Y_UV_Buf_Pitch_Middle, (CARD8)(pitch >> 5), 0xf0);
+
+ /* set U/V start address */
+ setvideoreg (pSiS, Index_VI_U_Buf_Start_Low, (CARD8)PSU);
+ setvideoreg (pSiS, Index_VI_U_Buf_Start_Middle,(CARD8)(PSU>>8));
+ setvideoreg (pSiS, Index_VI_U_Buf_Start_High, (CARD8)(PSU>>16));
+
+ setvideoreg (pSiS, Index_VI_V_Buf_Start_Low, (CARD8)PSV);
+ setvideoreg (pSiS, Index_VI_V_Buf_Start_Middle,(CARD8)(PSV>>8));
+ setvideoreg (pSiS, Index_VI_V_Buf_Start_High, (CARD8)(PSV>>16));
+
+ /* 310/325 series overflow bits */
+ if (pSiS->VGAEngine == SIS_315_VGA) {
+ setvideoreg (pSiS, Index_VI_Disp_UV_Buf_Pitch_High, (CARD8)(pitch>>13));
+ setvideoreg (pSiS, Index_VI_U_Buf_Start_Over, ((CARD8)(PSU>>24) & 0x01));
+ setvideoreg (pSiS, Index_VI_V_Buf_Start_Over, ((CARD8)(PSV>>24) & 0x01));
+ }
+ }
+
+ if (pSiS->VGAEngine == SIS_315_VGA) {
+ /* Trigger register copy for 310 series */
+ setvideoreg(pSiS, Index_VI_Control_Misc3, 1 << index);
+ }
+
+ /* set scale factor */
+ setvideoreg (pSiS, Index_VI_Hor_Post_Up_Scale_Low, (CARD8)(pOverlay->HUSF));
+ setvideoreg (pSiS, Index_VI_Hor_Post_Up_Scale_High,(CARD8)((pOverlay->HUSF)>>8));
+ setvideoreg (pSiS, Index_VI_Ver_Up_Scale_Low, (CARD8)(pOverlay->VUSF));
+ setvideoreg (pSiS, Index_VI_Ver_Up_Scale_High, (CARD8)((pOverlay->VUSF)>>8));
+
+ setvideoregmask (pSiS, Index_VI_Scale_Control, (pOverlay->IntBit << 3)
+ |(pOverlay->wHPre), 0x7f);
+
+ /* set destination window position */
+ setvideoreg(pSiS, Index_VI_Win_Hor_Disp_Start_Low, (CARD8)left);
+ setvideoreg(pSiS, Index_VI_Win_Hor_Disp_End_Low, (CARD8)right);
+ setvideoreg(pSiS, Index_VI_Win_Hor_Over, (CARD8)h_over);
+
+ setvideoreg(pSiS, Index_VI_Win_Ver_Disp_Start_Low, (CARD8)top);
+ setvideoreg(pSiS, Index_VI_Win_Ver_Disp_End_Low, (CARD8)bottom);
+ setvideoreg(pSiS, Index_VI_Win_Ver_Over, (CARD8)v_over);
+
+ setvideoregmask(pSiS, Index_VI_Control_Misc1, pOverlay->bobEnable, 0x1a);
+
+ /* Lock the address registers */
+ setvideoregmask(pSiS, Index_VI_Control_Misc1, 0x00, 0x20);
+}
+
+/* TW: Overlay MUST NOT be switched off while beam is over it */
+static void
+close_overlay(SISPtr pSiS, SISPortPrivPtr pPriv)
+{
+ CARD32 watchdog;
+
+ if ((pPriv->displayMode == DISPMODE_SINGLE2) ||
+ (pPriv->displayMode == DISPMODE_MIRROR)) {
+ if (pPriv->hasTwoOverlays) {
+ setvideoregmask (pSiS, Index_VI_Control_Misc2, 0x01, 0x01);
+ watchdog = WATCHDOG_DELAY;
+ while(vblank_active_CRT2(pSiS) && --watchdog);
+ watchdog = WATCHDOG_DELAY;
+ while((!vblank_active_CRT2(pSiS)) && --watchdog);
+ setvideoregmask(pSiS, Index_VI_Control_Misc0, 0x00, 0x02);
+ watchdog = WATCHDOG_DELAY;
+ while(vblank_active_CRT2(pSiS) && --watchdog);
+ watchdog = WATCHDOG_DELAY;
+ while((!vblank_active_CRT2(pSiS)) && --watchdog);
+ } else if (pPriv->displayMode == DISPMODE_SINGLE2) {
+ setvideoregmask (pSiS, Index_VI_Control_Misc2, 0x00, 0x01);
+ watchdog = WATCHDOG_DELAY;
+ while(vblank_active_CRT1(pSiS) && --watchdog);
+ watchdog = WATCHDOG_DELAY;
+ while((!vblank_active_CRT1(pSiS)) && --watchdog);
+ setvideoregmask(pSiS, Index_VI_Control_Misc0, 0x00, 0x02);
+ watchdog = WATCHDOG_DELAY;
+ while(vblank_active_CRT1(pSiS) && --watchdog);
+ watchdog = WATCHDOG_DELAY;
+ while((!vblank_active_CRT1(pSiS)) && --watchdog);
+ }
+ }
+ if ((pPriv->displayMode == DISPMODE_SINGLE1) ||
+ (pPriv->displayMode == DISPMODE_MIRROR)) {
+ setvideoregmask (pSiS, Index_VI_Control_Misc2, 0x00, 0x01);
+ watchdog = WATCHDOG_DELAY;
+ while(vblank_active_CRT1(pSiS) && --watchdog);
+ watchdog = WATCHDOG_DELAY;
+ while((!vblank_active_CRT1(pSiS)) && --watchdog);
+ setvideoregmask(pSiS, Index_VI_Control_Misc0, 0x00, 0x02);
+ watchdog = WATCHDOG_DELAY;
+ while(vblank_active_CRT1(pSiS) && --watchdog);
+ watchdog = WATCHDOG_DELAY;
+ while((!vblank_active_CRT1(pSiS)) && --watchdog);
+ }
+}
+
+static void
+SISDisplayVideo(ScrnInfoPtr pScrn, SISPortPrivPtr pPriv)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+
+ short srcPitch = pPriv->srcPitch;
+ short height = pPriv->height;
+ SISOverlayRec overlay;
+ int srcOffsetX=0, srcOffsetY=0;
+ int sx, sy;
+ int index = 0, iscrt2 = 0;
+
+ memset(&overlay, 0, sizeof(overlay));
+ overlay.pixelFormat = pPriv->id;
+ overlay.pitch = overlay.origPitch = srcPitch;
+ overlay.keyOP = 0x03; /* DestKey mode */
+ /* overlay.bobEnable = 0x02; */
+ overlay.bobEnable = 0x00; /* Disable BOB (whatever that is) */
+
+ overlay.SCREENheight = pSiS->CurrentLayout.mode->VDisplay;
+
+ overlay.dstBox.x1 = pPriv->drw_x - pScrn->frameX0;
+ overlay.dstBox.x2 = pPriv->drw_x + pPriv->drw_w - pScrn->frameX0;
+ overlay.dstBox.y1 = pPriv->drw_y - pScrn->frameY0;
+ overlay.dstBox.y2 = pPriv->drw_y + pPriv->drw_h - pScrn->frameY0;
+
+ if((overlay.dstBox.x1 > overlay.dstBox.x2) ||
+ (overlay.dstBox.y1 > overlay.dstBox.y2))
+ return;
+
+ if((overlay.dstBox.x2 < 0) || (overlay.dstBox.y2 < 0))
+ return;
+
+ if(overlay.dstBox.x1 < 0) {
+ srcOffsetX = pPriv->src_w * (-overlay.dstBox.x1) / pPriv->drw_w;
+ overlay.dstBox.x1 = 0;
+ }
+ if(overlay.dstBox.y1 < 0) {
+ srcOffsetY = pPriv->src_h * (-overlay.dstBox.y1) / pPriv->drw_h;
+ overlay.dstBox.y1 = 0;
+ }
+
+ switch(pPriv->id){
+ case PIXEL_FMT_YV12:
+ sx = (pPriv->src_x + srcOffsetX) & ~7;
+ sy = (pPriv->src_y + srcOffsetY) & ~1;
+ overlay.PSY = pPriv->bufAddr[pPriv->currentBuf] + sx + sy*srcPitch;
+ overlay.PSV = pPriv->bufAddr[pPriv->currentBuf] + height*srcPitch + ((sx + sy*srcPitch/2) >> 1);
+ overlay.PSU = pPriv->bufAddr[pPriv->currentBuf] + height*srcPitch*5/4 + ((sx + sy*srcPitch/2) >> 1);
+#ifdef SISDUALHEAD
+ overlay.PSY += HEADOFFSET;
+ overlay.PSV += HEADOFFSET;
+ overlay.PSU += HEADOFFSET;
+#endif
+ overlay.PSY >>= pPriv->shiftValue;
+ overlay.PSV >>= pPriv->shiftValue;
+ overlay.PSU >>= pPriv->shiftValue;
+ break;
+ case PIXEL_FMT_I420:
+ sx = (pPriv->src_x + srcOffsetX) & ~7;
+ sy = (pPriv->src_y + srcOffsetY) & ~1;
+ overlay.PSY = pPriv->bufAddr[pPriv->currentBuf] + sx + sy*srcPitch;
+ overlay.PSV = pPriv->bufAddr[pPriv->currentBuf] + height*srcPitch*5/4 + ((sx + sy*srcPitch/2) >> 1);
+ overlay.PSU = pPriv->bufAddr[pPriv->currentBuf] + height*srcPitch + ((sx + sy*srcPitch/2) >> 1);
+#ifdef SISDUALHEAD
+ overlay.PSY += HEADOFFSET;
+ overlay.PSV += HEADOFFSET;
+ overlay.PSU += HEADOFFSET;
+#endif
+ overlay.PSY >>= pPriv->shiftValue;
+ overlay.PSV >>= pPriv->shiftValue;
+ overlay.PSU >>= pPriv->shiftValue;
+ break;
+ case PIXEL_FMT_YUY2:
+ case PIXEL_FMT_UYVY:
+ case PIXEL_FMT_RGB6:
+ case PIXEL_FMT_RGB5:
+ default:
+ sx = (pPriv->src_x + srcOffsetX) & ~1;
+ sy = (pPriv->src_y + srcOffsetY);
+ overlay.PSY = (pPriv->bufAddr[pPriv->currentBuf] + sx*2 + sy*srcPitch);
+#ifdef SISDUALHEAD
+ overlay.PSY += HEADOFFSET;
+#endif
+ overlay.PSY >>= pPriv->shiftValue;
+ break;
+ }
+
+ /* FIXME: is it possible that srcW < 0 */
+ overlay.srcW = pPriv->src_w - (sx - pPriv->src_x);
+ overlay.srcH = pPriv->src_h - (sy - pPriv->src_y);
+
+ if ( (pPriv->oldx1 != overlay.dstBox.x1) ||
+ (pPriv->oldx2 != overlay.dstBox.x2) ||
+ (pPriv->oldy1 != overlay.dstBox.y1) ||
+ (pPriv->oldy2 != overlay.dstBox.y2) ) {
+ pPriv->mustwait = 1;
+ pPriv->oldx1 = overlay.dstBox.x1; pPriv->oldx2 = overlay.dstBox.x2;
+ pPriv->oldy1 = overlay.dstBox.y1; pPriv->oldy2 = overlay.dstBox.y2;
+ }
+
+ /* TW: setup dispmode (MIRROR, SINGLEx) */
+ set_dispmode(pScrn, pPriv);
+
+ /* TW: set display mode SR06,32 (CRT1, CRT2 or mirror) */
+ set_disptype_regs(pScrn, pPriv);
+
+ /* set (not only calc) merge line buffer */
+ merge_line_buf(pSiS, pPriv, (overlay.srcW > 384));
+
+ /* calculate (not set!) line buffer length */
+ set_line_buf_size(&overlay);
+
+ if (pPriv->displayMode == DISPMODE_SINGLE2) {
+ if (pPriv->hasTwoOverlays) {
+ /* TW: On chips with two overlays we use
+ * overlay 2 for CRT2 */
+ index = 1; iscrt2 = 1;
+ } else {
+ /* TW: On chips with only one overlay we
+ * use that only overlay for CRT2 */
+ index = 0; iscrt2 = 1;
+ }
+ overlay.VBlankActiveFunc = vblank_active_CRT2;
+ /* overlay.GetScanLineFunc = get_scanline_CRT2; */
+ } else {
+ index = 0; iscrt2 = 0;
+ overlay.VBlankActiveFunc = vblank_active_CRT1;
+ /* overlay.GetScanLineFunc = get_scanline_CRT1; */
+ }
+
+ /* TW: Do the following in a loop for CRT1 and CRT2 ----------------- */
+MIRROR:
+
+ /* calculate (not set!) scale factor */
+ calc_scale_factor(&overlay, pScrn, pPriv, index, iscrt2);
+
+ /* Select video1 (used for CRT1) or video2 (used for CRT2) */
+ setvideoregmask(pSiS, Index_VI_Control_Misc2, index, 0x01);
+
+ /* set format */
+ set_format(pSiS, &overlay);
+
+ /* set color key */
+ set_colorkey(pSiS, pPriv->colorKey);
+
+ /* set brightness, contrast, hue and saturation */
+ set_brightness(pSiS, pPriv->brightness);
+ set_contrast(pSiS, pPriv->contrast);
+ if (pSiS->VGAEngine == SIS_315_VGA) {
+ set_hue(pSiS, pPriv->hue);
+ set_saturation(pSiS, pPriv->saturation);
+ }
+
+ /* set overlay */
+ set_overlay(pSiS, &overlay, pPriv, index);
+
+ /* enable overlay */
+ setvideoregmask (pSiS, Index_VI_Control_Misc0, 0x02, 0x02);
+
+ if(index == 0 &&
+ pPriv->displayMode == DISPMODE_MIRROR &&
+ pPriv->hasTwoOverlays) {
+ index = 1; iscrt2 = 1;
+ overlay.VBlankActiveFunc = vblank_active_CRT2;
+ /* overlay.GetScanLineFunc = get_scanline_CRT2; */
+ goto MIRROR;
+ }
+ pPriv->mustwait = 0;
+}
+
+static FBLinearPtr
+SISAllocateOverlayMemory(
+ ScrnInfoPtr pScrn,
+ FBLinearPtr linear,
+ int size
+){
+ ScreenPtr pScreen;
+ FBLinearPtr new_linear;
+
+ if(linear) {
+ if(linear->size >= size)
+ return linear;
+
+ if(xf86ResizeOffscreenLinear(linear, size))
+ return linear;
+
+ xf86FreeOffscreenLinear(linear);
+ }
+
+ pScreen = screenInfo.screens[pScrn->scrnIndex];
+
+ new_linear = xf86AllocateOffscreenLinear(pScreen, size, 8,
+ NULL, NULL, NULL);
+
+ if(!new_linear) {
+ int max_size;
+
+ xf86QueryLargestOffscreenLinear(pScreen, &max_size, 8,
+ PRIORITY_EXTREME);
+
+ if(max_size < size) return NULL;
+
+ xf86PurgeUnlockedOffscreenAreas(pScreen);
+ new_linear = xf86AllocateOffscreenLinear(pScreen, size, 8,
+ NULL, NULL, NULL);
+ }
+ if (!new_linear)
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Xv: Failed to allocate %dK of video memory\n", size/1024);
+#ifdef TWDEBUG
+ else
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Xv: Allocated %dK of video memory\n", size/1024);
+#endif
+
+ return new_linear;
+}
+
+static void
+SISFreeOverlayMemory(ScrnInfoPtr pScrn)
+{
+ SISPortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn);
+
+ if(pPriv->linear) {
+ xf86FreeOffscreenLinear(pPriv->linear);
+ pPriv->linear = NULL;
+ }
+}
+
+static void
+SISStopVideo(ScrnInfoPtr pScrn, pointer data, Bool shutdown)
+{
+ SISPortPrivPtr pPriv = (SISPortPrivPtr)data;
+ SISPtr pSiS = SISPTR(pScrn);
+
+ if(pPriv->grabbedByV4L)
+ return;
+
+ REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
+
+ if(shutdown) {
+ if(pPriv->videoStatus & CLIENT_VIDEO_ON) {
+ close_overlay(pSiS, pPriv);
+ pPriv->mustwait = 1;
+ }
+ SISFreeOverlayMemory(pScrn);
+ pPriv->videoStatus = 0;
+ pSiS->VideoTimerCallback = NULL;
+ } else {
+ if(pPriv->videoStatus & CLIENT_VIDEO_ON) {
+ pPriv->videoStatus = OFF_TIMER | CLIENT_VIDEO_ON;
+ pPriv->offTime = currentTime.milliseconds + OFF_DELAY;
+ pSiS->VideoTimerCallback = SISVideoTimerCallback;
+ }
+ }
+}
+
+static int
+SISPutImage(
+ ScrnInfoPtr pScrn,
+ short src_x, short src_y,
+ short drw_x, short drw_y,
+ short src_w, short src_h,
+ short drw_w, short drw_h,
+ int id, unsigned char* buf,
+ short width, short height,
+ Bool sync,
+ RegionPtr clipBoxes, pointer data
+){
+ SISPtr pSiS = SISPTR(pScrn);
+ SISPortPrivPtr pPriv = (SISPortPrivPtr)data;
+
+ int totalSize=0;
+ int depth = pSiS->CurrentLayout.bitsPerPixel >> 3;
+
+ if(pPriv->grabbedByV4L)
+ return Success;
+
+ pPriv->drw_x = drw_x;
+ pPriv->drw_y = drw_y;
+ pPriv->drw_w = drw_w;
+ pPriv->drw_h = drw_h;
+ pPriv->src_x = src_x;
+ pPriv->src_y = src_y;
+ pPriv->src_w = src_w;
+ pPriv->src_h = src_h;
+ pPriv->id = id;
+ pPriv->height = height;
+
+ /* TW: Pixel formats:
+ 1. YU12: 3 planes: H V
+ Y sample period 1 1 (8 bit per pixel)
+ V sample period 2 2 (8 bit per pixel, subsampled)
+ U sample period 2 2 (8 bit per pixel, subsampled)
+
+ Y plane is fully sampled (width*height), U and V planes
+ are sampled in 2x2 blocks, hence a group of 4 pixels requires
+ 4 + 1 + 1 = 6 bytes. The data is planar, ie in single planes
+ for Y, U and V.
+ 2. UYVY: 3 planes: H V
+ Y sample period 1 1 (8 bit per pixel)
+ V sample period 2 1 (8 bit per pixel, subsampled)
+ U sample period 2 1 (8 bit per pixel, subsampled)
+ Y plane is fully sampled (width*height), U and V planes
+ are sampled in 2x1 blocks, hence a group of 4 pixels requires
+ 4 + 2 + 2 = 8 bytes. The data is bit packed, there are no separate
+ Y, U or V planes.
+ Bit order: U0 Y0 V0 Y1 U2 Y2 V2 Y3 ...
+ 3. I420: Like YU12, but planes U and V are in reverse order.
+ 4. YUY2: Like UYVY, but order is
+ Y0 U0 Y1 V0 Y2 U2 Y3 V2 ...
+ */
+
+ switch(id){
+ case PIXEL_FMT_YV12:
+ case PIXEL_FMT_I420:
+ pPriv->srcPitch = (width + 7) & ~7;
+ /* Size = width * height * 3 / 2 */
+ totalSize = (pPriv->srcPitch * height * 3) >> 1; /* Verified */
+ break;
+ case PIXEL_FMT_YUY2:
+ case PIXEL_FMT_UYVY:
+ case PIXEL_FMT_RGB6:
+ case PIXEL_FMT_RGB5:
+ default:
+ pPriv->srcPitch = ((width << 1) + 3) & ~3; /* Verified */
+ /* Size = width * 2 * height */
+ totalSize = pPriv->srcPitch * height;
+ }
+
+ /* allocate memory (we do doublebuffering) */
+ if(!(pPriv->linear = SISAllocateOverlayMemory(pScrn, pPriv->linear,
+ totalSize<<1)))
+ return BadAlloc;
+
+ /* fixup pointers */
+ pPriv->bufAddr[0] = (pPriv->linear->offset * depth);
+ pPriv->bufAddr[1] = pPriv->bufAddr[0] + totalSize;
+
+ /* copy data */
+ /* TODO: subimage */
+ memcpy(pSiS->FbBase + pPriv->bufAddr[pPriv->currentBuf], buf, totalSize);
+
+ SISDisplayVideo(pScrn, pPriv);
+
+ /* update cliplist */
+ if(pPriv->autopaintColorKey &&
+ (pPriv->grabbedByV4L || !RegionsEqual(&pPriv->clip, clipBoxes))) {
+ /* We always paint colorkey for V4L */
+ if (!pPriv->grabbedByV4L)
+ REGION_COPY(pScreen, &pPriv->clip, clipBoxes);
+ /* draw these */
+ /* xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes); - for X4.2 */
+ XAAFillSolidRects(pScrn, pPriv->colorKey, GXcopy, ~0,
+ REGION_NUM_RECTS(clipBoxes),
+ REGION_RECTS(clipBoxes));
+ }
+
+ pPriv->currentBuf ^= 1;
+
+ pPriv->videoStatus = CLIENT_VIDEO_ON;
+
+ pSiS->VideoTimerCallback = SISVideoTimerCallback;
+
+ return Success;
+}
+
+static int
+SISQueryImageAttributes(
+ ScrnInfoPtr pScrn,
+ int id,
+ unsigned short *w, unsigned short *h,
+ int *pitches, int *offsets
+){
+ int pitchY, pitchUV;
+ int size, sizeY, sizeUV;
+ SISPtr pSiS = SISPTR(pScrn);
+
+ if(*w < IMAGE_MIN_WIDTH) *w = IMAGE_MIN_WIDTH;
+ if(*h < IMAGE_MIN_HEIGHT) *h = IMAGE_MIN_HEIGHT;
+
+ if(pSiS->Flags650 & SiS650_LARGEOVERLAY) {
+ if(*w > IMAGE_MAX_WIDTH_M650) *w = IMAGE_MAX_WIDTH_M650;
+ if(*h > IMAGE_MAX_HEIGHT_M650) *h = IMAGE_MAX_HEIGHT_M650;
+ } else {
+ if(*w > IMAGE_MAX_WIDTH) *w = IMAGE_MAX_WIDTH;
+ if(*h > IMAGE_MAX_HEIGHT) *h = IMAGE_MAX_HEIGHT;
+ }
+
+ switch(id) {
+ case PIXEL_FMT_YV12:
+ case PIXEL_FMT_I420:
+ *w = (*w + 7) & ~7;
+ *h = (*h + 1) & ~1;
+ pitchY = *w;
+ pitchUV = *w >> 1;
+ if(pitches) {
+ pitches[0] = pitchY;
+ pitches[1] = pitches[2] = pitchUV;
+ }
+ sizeY = pitchY * (*h);
+ sizeUV = pitchUV * ((*h) >> 1);
+ if(offsets) {
+ offsets[0] = 0;
+ offsets[1] = sizeY;
+ offsets[2] = sizeY + sizeUV;
+ }
+ size = sizeY + (sizeUV << 1);
+ break;
+ case PIXEL_FMT_YUY2:
+ case PIXEL_FMT_UYVY:
+ case PIXEL_FMT_RGB6:
+ case PIXEL_FMT_RGB5:
+ default:
+ *w = (*w + 1) & ~1;
+ pitchY = *w << 1;
+ if(pitches) pitches[0] = pitchY;
+ if(offsets) offsets[0] = 0;
+ size = pitchY * (*h);
+ break;
+ }
+
+ return size;
+}
+
+static void
+SISVideoTimerCallback (ScrnInfoPtr pScrn, Time now)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ SISPortPrivPtr pPriv = NULL;
+ unsigned char sridx, cridx;
+
+ pSiS->VideoTimerCallback = NULL;
+
+ if(!pScrn->vtSema) return;
+
+ if (pSiS->adaptor) {
+ pPriv = GET_PORT_PRIVATE(pScrn);
+ if(!pPriv->videoStatus)
+ pPriv = NULL;
+ }
+
+ if (pPriv) {
+ if(pPriv->videoStatus & TIMER_MASK) {
+ UpdateCurrentTime();
+ if(pPriv->offTime < currentTime.milliseconds) {
+ if(pPriv->videoStatus & OFF_TIMER) {
+ /* Turn off the overlay */
+ sridx = inSISREG(SISSR); cridx = inSISREG(SISCR);
+ close_overlay(pSiS, pPriv);
+ outSISREG(SISSR, sridx); outSISREG(SISCR, cridx);
+ pPriv->mustwait = 1;
+ pPriv->videoStatus = FREE_TIMER;
+ pPriv->freeTime = currentTime.milliseconds + FREE_DELAY;
+ pSiS->VideoTimerCallback = SISVideoTimerCallback;
+ } else
+ if(pPriv->videoStatus & FREE_TIMER) {
+ SISFreeOverlayMemory(pScrn);
+ pPriv->mustwait = 1;
+ pPriv->videoStatus = 0;
+ }
+ } else
+ pSiS->VideoTimerCallback = SISVideoTimerCallback;
+ }
+ }
+}
+
+/* TW: Offscreen surface stuff */
+
+static int
+SISAllocSurface (
+ ScrnInfoPtr pScrn,
+ int id,
+ unsigned short w,
+ unsigned short h,
+ XF86SurfacePtr surface
+)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ SISPortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn);
+ int size, depth;
+
+#ifdef TWDEBUG
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Xv: SISAllocSurface called\n");
+#endif
+
+ if((w < IMAGE_MIN_WIDTH) || (h < IMAGE_MIN_HEIGHT))
+ return BadValue;
+ if(pSiS->Flags650 & SiS650_LARGEOVERLAY) {
+ if((w > IMAGE_MAX_WIDTH_M650) || (h > IMAGE_MAX_HEIGHT_M650))
+ return BadValue;
+ } else {
+ if((w > IMAGE_MAX_WIDTH) || (h > IMAGE_MAX_HEIGHT))
+ return BadValue;
+ }
+
+ if(pPriv->grabbedByV4L)
+ return BadAlloc;
+
+ depth = pSiS->CurrentLayout.bitsPerPixel >> 3;
+ w = (w + 1) & ~1;
+ pPriv->pitch = ((w << 1) + 63) & ~63; /* Only packed pixel modes supported */
+ size = h * pPriv->pitch; /* / depth; - Why? */
+ pPriv->linear = SISAllocateOverlayMemory(pScrn, pPriv->linear, size);
+ if(!pPriv->linear)
+ return BadAlloc;
+
+ pPriv->offset = pPriv->linear->offset * depth;
+
+ surface->width = w;
+ surface->height = h;
+ surface->pScrn = pScrn;
+ surface->id = id;
+ surface->pitches = &pPriv->pitch;
+ surface->offsets = &pPriv->offset;
+ surface->devPrivate.ptr = (pointer)pPriv;
+
+ close_overlay(pSiS, pPriv);
+ pPriv->videoStatus = 0;
+ REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
+ pSiS->VideoTimerCallback = NULL;
+ pPriv->grabbedByV4L = TRUE;
+ return Success;
+}
+
+static int
+SISStopSurface (XF86SurfacePtr surface)
+{
+ SISPortPrivPtr pPriv = (SISPortPrivPtr)(surface->devPrivate.ptr);
+ SISPtr pSiS = SISPTR(surface->pScrn);
+
+ if(pPriv->grabbedByV4L && pPriv->videoStatus) {
+ close_overlay(pSiS, pPriv);
+ pPriv->mustwait = 1;
+ pPriv->videoStatus = 0;
+ }
+ return Success;
+}
+
+static int
+SISFreeSurface (XF86SurfacePtr surface)
+{
+ SISPortPrivPtr pPriv = (SISPortPrivPtr)(surface->devPrivate.ptr);
+
+ if(pPriv->grabbedByV4L) {
+ SISStopSurface(surface);
+ SISFreeOverlayMemory(surface->pScrn);
+ pPriv->grabbedByV4L = FALSE;
+ }
+ return Success;
+}
+
+static int
+SISGetSurfaceAttribute (
+ ScrnInfoPtr pScrn,
+ Atom attribute,
+ INT32 *value
+)
+{
+ SISPortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn);
+
+ return SISGetPortAttribute(pScrn, attribute, value, (pointer)pPriv);
+}
+
+static int
+SISSetSurfaceAttribute(
+ ScrnInfoPtr pScrn,
+ Atom attribute,
+ INT32 value
+)
+{
+ SISPortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn);;
+
+ return SISSetPortAttribute(pScrn, attribute, value, (pointer)pPriv);
+}
+
+static int
+SISDisplaySurface (
+ XF86SurfacePtr surface,
+ short src_x, short src_y,
+ short drw_x, short drw_y,
+ short src_w, short src_h,
+ short drw_w, short drw_h,
+ RegionPtr clipBoxes
+)
+{
+ ScrnInfoPtr pScrn = surface->pScrn;
+ SISPortPrivPtr pPriv = (SISPortPrivPtr)(surface->devPrivate.ptr);
+
+#ifdef TWDEBUG
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Xv: DisplaySurface called\n");
+#endif
+
+ if(!pPriv->grabbedByV4L)
+ return Success;
+
+ pPriv->drw_x = drw_x;
+ pPriv->drw_y = drw_y;
+ pPriv->drw_w = drw_w;
+ pPriv->drw_h = drw_h;
+ pPriv->src_x = src_x;
+ pPriv->src_y = src_y;
+ pPriv->src_w = src_w;
+ pPriv->src_h = src_h;
+ pPriv->id = surface->id;
+ pPriv->height = surface->height;
+ pPriv->bufAddr[0] = surface->offsets[0];
+ pPriv->currentBuf = 0;
+ pPriv->srcPitch = surface->pitches[0];
+
+ SISDisplayVideo(pScrn, pPriv);
+
+ if(pPriv->autopaintColorKey) {
+ XAAFillSolidRects(pScrn, pPriv->colorKey, GXcopy, ~0,
+ REGION_NUM_RECTS(clipBoxes),
+ REGION_RECTS(clipBoxes));
+ }
+
+ pPriv->videoStatus = CLIENT_VIDEO_ON;
+
+ return Success;
+}
+
+#define NUMOFFSCRIMAGES 4
+
+static XF86OffscreenImageRec SISOffscreenImages_300[NUMOFFSCRIMAGES] =
+{
+ {
+ &SISImages[0], /* YUV2 */
+ VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT,
+ SISAllocSurface,
+ SISFreeSurface,
+ SISDisplaySurface,
+ SISStopSurface,
+ SISGetSurfaceAttribute,
+ SISSetSurfaceAttribute,
+ IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT,
+ NUM_ATTRIBUTES_300,
+ &SISAttributes_300[0] /* Support all attributes */
+ },
+ {
+ &SISImages[2], /* UYVY */
+ VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT,
+ SISAllocSurface,
+ SISFreeSurface,
+ SISDisplaySurface,
+ SISStopSurface,
+ SISGetSurfaceAttribute,
+ SISSetSurfaceAttribute,
+ IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT,
+ NUM_ATTRIBUTES_300,
+ &SISAttributes_300[0] /* Support all attributes */
+ }
+ ,
+ {
+ &SISImages[4], /* RV15 */
+ VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT,
+ SISAllocSurface,
+ SISFreeSurface,
+ SISDisplaySurface,
+ SISStopSurface,
+ SISGetSurfaceAttribute,
+ SISSetSurfaceAttribute,
+ IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT,
+ NUM_ATTRIBUTES_300,
+ &SISAttributes_300[0] /* Support all attributes */
+ },
+ {
+ &SISImages[5], /* RV16 */
+ VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT,
+ SISAllocSurface,
+ SISFreeSurface,
+ SISDisplaySurface,
+ SISStopSurface,
+ SISGetSurfaceAttribute,
+ SISSetSurfaceAttribute,
+ IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT,
+ NUM_ATTRIBUTES_300,
+ &SISAttributes_300[0] /* Support all attributes */
+ }
+};
+
+static XF86OffscreenImageRec SISOffscreenImages_325[NUMOFFSCRIMAGES] =
+{
+ {
+ &SISImages[0], /* YUV2 */
+ VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT,
+ SISAllocSurface,
+ SISFreeSurface,
+ SISDisplaySurface,
+ SISStopSurface,
+ SISGetSurfaceAttribute,
+ SISSetSurfaceAttribute,
+ IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT,
+ NUM_ATTRIBUTES_325,
+ &SISAttributes_325[0] /* Support all attributes */
+ },
+ {
+ &SISImages[2], /* UYVY */
+ VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT,
+ SISAllocSurface,
+ SISFreeSurface,
+ SISDisplaySurface,
+ SISStopSurface,
+ SISGetSurfaceAttribute,
+ SISSetSurfaceAttribute,
+ IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT,
+ NUM_ATTRIBUTES_325,
+ &SISAttributes_325[0] /* Support all attributes */
+ }
+ ,
+ {
+ &SISImages[4], /* RV15 */
+ VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT,
+ SISAllocSurface,
+ SISFreeSurface,
+ SISDisplaySurface,
+ SISStopSurface,
+ SISGetSurfaceAttribute,
+ SISSetSurfaceAttribute,
+ IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT,
+ NUM_ATTRIBUTES_325,
+ &SISAttributes_325[0] /* Support all attributes */
+ },
+ {
+ &SISImages[5], /* RV16 */
+ VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT,
+ SISAllocSurface,
+ SISFreeSurface,
+ SISDisplaySurface,
+ SISStopSurface,
+ SISGetSurfaceAttribute,
+ SISSetSurfaceAttribute,
+ IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT,
+ NUM_ATTRIBUTES_325,
+ &SISAttributes_325[0] /* Support all attributes */
+ }
+};
+
+static XF86OffscreenImageRec SISOffscreenImages_M650[NUMOFFSCRIMAGES] =
+{
+ {
+ &SISImages[0], /* YUV2 */
+ VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT,
+ SISAllocSurface,
+ SISFreeSurface,
+ SISDisplaySurface,
+ SISStopSurface,
+ SISGetSurfaceAttribute,
+ SISSetSurfaceAttribute,
+ IMAGE_MAX_WIDTH_M650, IMAGE_MAX_HEIGHT_M650,
+ NUM_ATTRIBUTES_325,
+ &SISAttributes_325[0] /* Support all attributes */
+ },
+ {
+ &SISImages[2], /* UYVY */
+ VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT,
+ SISAllocSurface,
+ SISFreeSurface,
+ SISDisplaySurface,
+ SISStopSurface,
+ SISGetSurfaceAttribute,
+ SISSetSurfaceAttribute,
+ IMAGE_MAX_WIDTH_M650, IMAGE_MAX_HEIGHT_M650,
+ NUM_ATTRIBUTES_325,
+ &SISAttributes_325[0] /* Support all attributes */
+ }
+ ,
+ {
+ &SISImages[4], /* RV15 */
+ VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT,
+ SISAllocSurface,
+ SISFreeSurface,
+ SISDisplaySurface,
+ SISStopSurface,
+ SISGetSurfaceAttribute,
+ SISSetSurfaceAttribute,
+ IMAGE_MAX_WIDTH_M650, IMAGE_MAX_HEIGHT_M650,
+ NUM_ATTRIBUTES_325,
+ &SISAttributes_325[0] /* Support all attributes */
+ },
+ {
+ &SISImages[5], /* RV16 */
+ VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT,
+ SISAllocSurface,
+ SISFreeSurface,
+ SISDisplaySurface,
+ SISStopSurface,
+ SISGetSurfaceAttribute,
+ SISSetSurfaceAttribute,
+ IMAGE_MAX_WIDTH_M650, IMAGE_MAX_HEIGHT_M650,
+ NUM_ATTRIBUTES_325,
+ &SISAttributes_325[0] /* Support all attributes */
+ }
+};
+
+static void
+SISInitOffscreenImages(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ SISPtr pSiS = SISPTR(pScrn);
+
+ if(pSiS->VGAEngine == SIS_300_VGA) {
+ xf86XVRegisterOffscreenImages(pScreen, SISOffscreenImages_300, NUMOFFSCRIMAGES);
+ } else {
+ if(pSiS->Flags650 & SiS650_LARGEOVERLAY) {
+ xf86XVRegisterOffscreenImages(pScreen, SISOffscreenImages_M650, NUMOFFSCRIMAGES);
+ } else {
+ xf86XVRegisterOffscreenImages(pScreen, SISOffscreenImages_325, NUMOFFSCRIMAGES);
+ }
+ }
+}
diff --git a/src/vgatypes.h b/src/vgatypes.h
new file mode 100644
index 0000000..d377dee
--- /dev/null
+++ b/src/vgatypes.h
@@ -0,0 +1,368 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/vgatypes.h,v 1.3 2003/02/10 01:14:16 tsi Exp $ */
+
+#ifndef _VGATYPES_
+#define _VGATYPES_
+
+#ifdef LINUX_XF86
+#include "xf86Pci.h"
+#endif
+
+#ifdef LINUX_KERNEL /* TW: We don't want the X driver to depend on kernel source */
+#include <linux/ioctl.h>
+#endif
+
+#ifndef TC
+#define far
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef TRUE
+#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 PUCHAR
+typedef UCHAR far *PUCHAR;
+#endif
+
+#ifndef PUSHORT
+typedef USHORT far *PUSHORT;
+#endif
+
+#ifndef PULONG
+typedef ULONG far *PULONG;
+#endif
+
+#ifndef PVOID
+typedef void far *PVOID;
+#endif
+#ifndef VOID
+typedef void VOID;
+#endif
+
+#ifndef BOOLEAN
+typedef UCHAR BOOLEAN;
+#endif
+
+#ifndef WINCE_HEADER
+#ifndef bool
+typedef UCHAR bool;
+#endif
+#endif /*WINCE_HEADER*/
+
+#ifndef VBIOS_VER_MAX_LENGTH
+#define VBIOS_VER_MAX_LENGTH 4
+#endif
+
+#ifndef LINUX_KERNEL /* For kernel, this is defined in sisfb.h */
+#ifndef WIN2000
+#ifndef SIS_CHIP_TYPE
+typedef enum _SIS_CHIP_TYPE {
+ SIS_VGALegacy = 0,
+#ifdef LINUX_XF86
+ SIS_530, /* TW */
+ SIS_OLD, /* TW */
+#endif
+ SIS_300,
+ SIS_630,
+ SIS_730,
+ SIS_540,
+ SIS_315H, /* SiS 310 */
+ SIS_315,
+ SIS_315PRO, /* SiS 325 */
+ SIS_550,
+ SIS_650,
+ SIS_740,
+ SIS_330,
+ MAX_SIS_CHIP
+} SIS_CHIP_TYPE;
+#endif
+#endif
+#endif
+
+#ifndef WIN2000
+#ifndef SIS_VB_CHIP_TYPE
+typedef enum _SIS_VB_CHIP_TYPE {
+ VB_CHIP_Legacy = 0,
+ VB_CHIP_301,
+ VB_CHIP_301B,
+ VB_CHIP_301LV,
+ VB_CHIP_301LVX,
+ VB_CHIP_302,
+ VB_CHIP_302B,
+ VB_CHIP_302LV,
+ VB_CHIP_302LVX,
+ VB_CHIP_303,
+ VB_CHIP_UNKNOWN, /* other video bridge or no video bridge */
+ MAX_VB_CHIP
+} SIS_VB_CHIP_TYPE;
+#endif
+#endif
+
+#ifndef WIN2000
+#ifndef SIS_LCD_TYPE
+typedef enum _SIS_LCD_TYPE {
+ LCD_INVALID = 0,
+ LCD_800x600,
+ LCD_1024x768,
+ LCD_1280x1024,
+ LCD_1280x960,
+ LCD_640x480,
+ LCD_1600x1200,
+ LCD_1920x1440,
+ LCD_2048x1536,
+ LCD_320x480, /* TW: FSTN */
+ LCD_1400x1050,
+ LCD_1152x864,
+ LCD_1152x768,
+ LCD_1280x768,
+ LCD_1024x600,
+ LCD_UNKNOWN
+} SIS_LCD_TYPE;
+#endif
+#endif
+
+#ifndef WIN2000 /* mark by Paul, Move definition to sisv.h*/
+#ifndef PSIS_DSReg
+typedef struct _SIS_DSReg
+{
+ UCHAR jIdx;
+ UCHAR jVal;
+} SIS_DSReg, *PSIS_DSReg;
+#endif
+
+#ifndef SIS_HW_DEVICE_INFO
+
+typedef struct _SIS_HW_DEVICE_INFO SIS_HW_DEVICE_INFO, *PSIS_HW_DEVICE_INFO;
+
+typedef BOOLEAN (*PSIS_QUERYSPACE) (PSIS_HW_DEVICE_INFO, ULONG, ULONG, ULONG *);
+
+
+struct _SIS_HW_DEVICE_INFO
+{
+ PVOID pDevice; /* The pointer to the physical device data structure
+ in each OS or NULL for unused. */
+ UCHAR *pjVirtualRomBase; /* base virtual address of VBIOS ROM Space */
+ /* or base virtual address of ROM image file. */
+ /* if NULL, then read from pjROMImage; */
+ /* Note:ROM image file is the file of VBIOS ROM */
+
+ BOOLEAN UseROM; /* TW: Use the ROM image if provided */
+
+ UCHAR *pjCustomizedROMImage;/* base virtual address of ROM image file. */
+ /* wincE:ROM image file is the file for OEM */
+ /* customized table */
+ /* Linux: not used */
+ /* NT : not used */
+ /* Note : pjCustomizedROMImage=NULL if no ROM image file */
+
+ UCHAR *pjVideoMemoryAddress;/* base virtual memory address */
+ /* of Linear VGA memory */
+
+ ULONG ulVideoMemorySize; /* size, in bytes, of the memory on the board */
+ ULONG ulIOAddress; /* base I/O address of VGA ports (0x3B0) */
+ UCHAR jChipType; /* Used to Identify SiS Graphics Chip */
+ /* defined in the data structure type */
+ /* "SIS_CHIP_TYPE" */
+
+ UCHAR jChipRevision; /* Used to Identify SiS Graphics Chip Revision */
+ UCHAR ujVBChipID; /* the ID of video bridge */
+ /* defined in the data structure type */
+ /* "SIS_VB_CHIP_TYPE" */
+
+ USHORT usExternalChip; /* NO VB or other video bridge(not */
+ /* SiS video bridge) */
+ /* if ujVBChipID = VB_CHIP_UNKNOWN, */
+ /* then bit0=1 : LVDS,bit1=1 : trumpion, */
+ /* bit2=1 : CH7005 & no video bridge if */
+ /* usExternalChip = 0. */
+ /* Note: CR37[3:1]: */
+ /* 001:SiS 301 */
+ /* 010:LVDS */
+ /* 011:Trumpion LVDS Scaling Chip */
+ /* 100:LVDS(LCD-out)+Chrontel 7005 */
+ /* 101:Single Chrontel 7005 */
+ /* TW: This has changed on 310/325 series! */
+
+ ULONG ulCRT2LCDType; /* defined in the data structure type */
+ /* "SIS_LCD_TYPE" */
+
+ BOOLEAN bIntegratedMMEnabled;/* supporting integration MM enable */
+
+ BOOLEAN bSkipDramSizing; /* True: Skip video memory sizing. */
+ PSIS_DSReg pSR; /* restore SR registers in initial function. */
+ /* end data :(idx, val) = (FF, FF). */
+ /* Note : restore SR registers if */
+ /* bSkipDramSizing = TRUE */
+
+ PSIS_DSReg pCR; /* restore CR registers in initial function. */
+ /* end data :(idx, val) = (FF, FF) */
+ /* Note : restore cR registers if */
+ /* bSkipDramSizing = TRUE */
+
+ PSIS_QUERYSPACE pQueryVGAConfigSpace; /* Get/Set VGA Configuration */
+ /* space */
+
+ PSIS_QUERYSPACE pQueryNorthBridgeSpace;/* Get/Set North Bridge */
+ /* space */
+
+ UCHAR szVBIOSVer[VBIOS_VER_MAX_LENGTH];
+
+ UCHAR pdc; /* TW: PanelDelayCompensation */
+
+#ifdef LINUX_XF86
+ PCITAG PciTag; /* PCI Tag for Linux XF86 */
+#endif
+};
+#endif
+#endif
+
+
+/* TW: Addtional IOCTL for communication sisfb <> X driver */
+/* If changing this, sisfb.h must also be changed (for sisfb) */
+
+#ifdef LINUX_XF86 /* We don't want the X driver to depend on the kernel source */
+
+/* TW: ioctl for identifying and giving some info (esp. memory heap start) */
+#define SISFB_GET_INFO 0x80046ef8 /* Wow, what a terrible hack... */
+
+/* TW: Structure argument for SISFB_GET_INFO ioctl */
+typedef struct _SISFB_INFO sisfb_info, *psisfb_info;
+
+struct _SISFB_INFO {
+ unsigned long sisfb_id; /* for identifying sisfb */
+#ifndef SISFB_ID
+#define SISFB_ID 0x53495346 /* Identify myself with 'SISF' */
+#endif
+ int chip_id; /* PCI ID of detected chip */
+ int memory; /* video memory in KB which sisfb manages */
+ int heapstart; /* heap start (= sisfb "mem" argument) in KB */
+ unsigned char fbvidmode; /* current sisfb mode */
+
+ unsigned char sisfb_version;
+ unsigned char sisfb_revision;
+ unsigned char sisfb_patchlevel;
+
+ unsigned char sisfb_caps; /* sisfb's capabilities */
+
+ int sisfb_tqlen; /* turbo queue length (in KB) */
+
+ unsigned int sisfb_pcibus; /* The card's PCI ID */
+ unsigned int sisfb_pcislot;
+ unsigned int sisfb_pcifunc;
+
+ unsigned char sisfb_lcdpdc;
+
+ char reserved[236]; /* for future use */
+};
+#endif
+
+#ifndef WIN2000
+#ifndef WINCE_HEADER
+#ifndef BUS_DATA_TYPE
+typedef enum _BUS_DATA_TYPE {
+ ConfigurationSpaceUndefined = -1,
+ Cmos,
+ EisaConfiguration,
+ Pos,
+ CbusConfiguration,
+ PCIConfiguration,
+ VMEConfiguration,
+ NuBusConfiguration,
+ PCMCIAConfiguration,
+ MPIConfiguration,
+ MPSAConfiguration,
+ PNPISAConfiguration,
+ MaximumBusDataType
+} BUS_DATA_TYPE, *PBUS_DATA_TYPE;
+#endif
+#endif /* WINCE_HEADER */
+
+#ifndef PCI_TYPE0_ADDRESSES
+#define PCI_TYPE0_ADDRESSES 6
+#endif
+
+#ifndef PCI_TYPE1_ADDRESSES
+#define PCI_TYPE1_ADDRESSES 2
+#endif
+
+#ifndef WINCE_HEADER
+#ifndef PCI_COMMON_CONFIG
+typedef struct _PCI_COMMON_CONFIG {
+ USHORT VendorID; /* (ro) */
+ USHORT DeviceID; /* (ro) */
+ USHORT Command; /* Device control */
+ USHORT Status;
+ UCHAR RevisionID; /* (ro) */
+ UCHAR ProgIf; /* (ro) */
+ UCHAR SubClass; /* (ro) */
+ UCHAR BaseClass; /* (ro) */
+ UCHAR CacheLineSize; /* (ro+) */
+ UCHAR LatencyTimer; /* (ro+) */
+ UCHAR HeaderType; /* (ro) */
+ UCHAR BIST; /* Built in self test */
+
+ union {
+ struct _PCI_HEADER_TYPE_0 {
+ ULONG BaseAddresses[PCI_TYPE0_ADDRESSES];
+ ULONG CIS;
+ USHORT SubVendorID;
+ USHORT SubSystemID;
+ ULONG ROMBaseAddress;
+ ULONG Reserved2[2];
+
+ UCHAR InterruptLine; /* */
+ UCHAR InterruptPin; /* (ro) */
+ UCHAR MinimumGrant; /* (ro) */
+ UCHAR MaximumLatency; /* (ro) */
+ } type0;
+
+
+ } u;
+
+ UCHAR DeviceSpecific[192];
+
+} PCI_COMMON_CONFIG, *PPCI_COMMON_CONFIG;
+#endif
+#endif /* WINCE_HEADER */
+
+#ifndef FIELD_OFFSET
+#define FIELD_OFFSET(type, field) ((LONG)&(((type *)0)->field))
+#endif
+
+#ifndef PCI_COMMON_HDR_LENGTH
+#define PCI_COMMON_HDR_LENGTH (FIELD_OFFSET (PCI_COMMON_CONFIG, DeviceSpecific))
+#endif
+#endif
+
+#endif
diff --git a/src/vstruct.h b/src/vstruct.h
new file mode 100644
index 0000000..7005986
--- /dev/null
+++ b/src/vstruct.h
@@ -0,0 +1,571 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/vstruct.h,v 1.3 2003/02/10 01:14:17 tsi Exp $ */
+
+#ifdef _INIT_
+#define EXTERN
+#else
+#define EXTERN extern
+#endif /* _INIT_ */
+
+#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;
+
+/*add for LCDA*/
+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;
+} 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_ModeInfo;
+ USHORT Ext_Point;
+ USHORT Ext_VESAID;
+ UCHAR Ext_VESAMEMSize;
+ UCHAR Ext_RESINFO;
+ UCHAR VB_ExtTVFlickerIndex;
+ UCHAR VB_ExtTVEdgeIndex;
+ UCHAR VB_ExtTVYFilterIndex;
+ UCHAR REFindex;
+} SiS_ExtStruct;
+
+typedef struct _SiS_Ext2Struct
+{
+ USHORT Ext_InfoFlag;
+ UCHAR Ext_CRT1CRTC;
+ UCHAR Ext_CRTVCLK;
+ UCHAR Ext_CRT2CRTC;
+ UCHAR ModeID;
+ USHORT XRes;
+ USHORT YRes;
+ USHORT ROM_OFFSET;
+} 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_ECLKDataStruct
+{
+ UCHAR SR2E,SR2F,SR30;
+ USHORT CLOCK;
+} SiS_ECLKDataStruct;
+
+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];
+
+typedef struct _SiS_Private
+{
+#ifdef LINUX_KERNEL
+ USHORT RelIO;
+#endif
+ USHORT SiS_P3c4;
+ USHORT SiS_P3d4;
+ USHORT SiS_P3c0;
+ USHORT SiS_P3ce;
+ USHORT SiS_P3c2;
+ USHORT SiS_P3ca;
+ USHORT SiS_P3c6;
+ USHORT SiS_P3c7;
+ USHORT SiS_P3c8;
+ USHORT SiS_P3c9;
+ USHORT SiS_P3da;
+ USHORT SiS_Part1Port;
+ USHORT SiS_Part2Port;
+ USHORT SiS_Part3Port;
+ USHORT SiS_Part4Port;
+ USHORT SiS_Part5Port;
+ USHORT SiS_IF_DEF_LVDS;
+ USHORT SiS_IF_DEF_TRUMPION;
+ USHORT SiS_IF_DEF_DSTN;
+ USHORT SiS_IF_DEF_FSTN;
+ USHORT SiS_IF_DEF_CH70xx;
+ USHORT SiS_IF_DEF_HiVision;
+ UCHAR SiS_VGAINFO;
+ BOOLEAN SiS_UseROM;
+ int SiS_CHOverScan;
+ BOOLEAN SiS_CHSOverScan;
+ BOOLEAN SiS_ChSW;
+ int SiS_UseOEM;
+ USHORT SiS_Backup70xx;
+ USHORT SiS_CRT1Mode;
+ USHORT SiS_flag_clearbuffer;
+ int SiS_RAMType;
+ UCHAR SiS_ChannelAB;
+ UCHAR SiS_DataBusWidth;
+ USHORT SiS_ModeType;
+ USHORT SiS_VBInfo;
+ USHORT SiS_LCDResInfo;
+ USHORT SiS_LCDTypeInfo;
+ USHORT SiS_LCDInfo;
+ USHORT SiS_VBType;
+ USHORT SiS_VBExtInfo;
+ USHORT SiS_HiVision;
+ 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_Clk;
+ USHORT SiS_DDC_DataShift;
+ USHORT SiS_DDC_DeviceAddr;
+ USHORT SiS_DDC_ReadAddr;
+ USHORT SiS_DDC_SecAddr;
+ USHORT SiS_Panel800x600;
+ USHORT SiS_Panel1024x768;
+ USHORT SiS_Panel1280x1024;
+ USHORT SiS_Panel1600x1200;
+ USHORT SiS_Panel1280x960;
+ USHORT SiS_Panel1400x1050;
+ USHORT SiS_Panel320x480;
+ USHORT SiS_Panel1152x768;
+ USHORT SiS_Panel1280x768;
+ USHORT SiS_Panel1024x600;
+ USHORT SiS_Panel640x480;
+ USHORT SiS_Panel1152x864;
+ USHORT SiS_PanelMax;
+ USHORT SiS_PanelMinLVDS;
+ USHORT SiS_PanelMin301;
+ USHORT SiS_ChrontelInit;
+
+ /* Pointers: */
+ 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;
+ const SiS_ECLKDataStruct *SiS_ECLKData;
+ const SiS_VCLKDataStruct *SiS_VCLKData;
+ const SiS_VBVCLKDataStruct *SiS_VBVCLKData;
+ const SiS_StResInfoStruct *SiS_StResInfo;
+ const SiS_ModeResInfoStruct *SiS_ModeResInfo;
+ const UCHAR *SiS_ScreenOffset;
+
+ const UCHAR *pSiS_OutputSelect;
+ const UCHAR *pSiS_SoftSetting;
+
+ const DRAM4Type *SiS_SR15; /* pointer : point to array */
+#ifndef LINUX_XF86
+ 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; /*301b*/
+ const USHORT *pSiS_VideoSenseData2;
+ const USHORT *pSiS_YCSenseData2;
+#endif
+ 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 SiS_LCDDataStruct *SiS_StLCD1024x768Data;
+ const SiS_LCDDataStruct *SiS_ExtLCD1024x768Data;
+ const SiS_LCDDataStruct *SiS_St2LCD1024x768Data;
+ const SiS_LCDDataStruct *SiS_StLCD1280x1024Data;
+ const SiS_LCDDataStruct *SiS_ExtLCD1280x1024Data;
+ const SiS_LCDDataStruct *SiS_St2LCD1280x1024Data;
+ const SiS_LCDDataStruct *SiS_NoScaleData1024x768;
+ const SiS_LCDDataStruct *SiS_NoScaleData1280x1024;
+ const SiS_LCDDataStruct *SiS_LCD1280x960Data;
+ const SiS_LCDDataStruct *SiS_NoScaleData1400x1050;
+ const SiS_LCDDataStruct *SiS_NoScaleData1600x1200;
+ const SiS_LCDDataStruct *SiS_StLCD1400x1050Data;
+ const SiS_LCDDataStruct *SiS_StLCD1600x1200Data;
+ const SiS_LCDDataStruct *SiS_ExtLCD1400x1050Data;
+ const SiS_LCDDataStruct *SiS_ExtLCD1600x1200Data;
+ const SiS_TVDataStruct *SiS_StPALData;
+ const SiS_TVDataStruct *SiS_ExtPALData;
+ const SiS_TVDataStruct *SiS_StNTSCData;
+ const SiS_TVDataStruct *SiS_ExtNTSCData;
+#ifdef oldHV
+ const SiS_TVDataStruct *SiS_St1HiTVData;
+ const SiS_TVDataStruct *SiS_St2HiTVData;
+ const SiS_TVDataStruct *SiS_ExtHiTVData;
+#endif
+ const UCHAR *SiS_NTSCTiming;
+ const UCHAR *SiS_PALTiming;
+#ifdef oldHV
+ const UCHAR *SiS_HiTVExtTiming;
+ const UCHAR *SiS_HiTVSt1Timing;
+ const UCHAR *SiS_HiTVSt2Timing;
+ const UCHAR *SiS_HiTVTextTiming;
+ const UCHAR *SiS_HiTVGroup3Data;
+ const UCHAR *SiS_HiTVGroup3Simu;
+ const UCHAR *SiS_HiTVGroup3Text;
+#endif
+ const SiS_PanelDelayTblStruct *SiS_PanelDelayTbl;
+ const SiS_PanelDelayTblStruct *SiS_PanelDelayTblLVDS;
+ 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_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_LVDS320x480Data_1;
+ const SiS_LVDSDataStruct *SiS_LCDA1400x1050Data_1;
+ const SiS_LVDSDataStruct *SiS_LCDA1400x1050Data_2;
+ const SiS_LVDSDataStruct *SiS_LCDA1600x1200Data_1;
+ const SiS_LVDSDataStruct *SiS_LCDA1600x1200Data_2;
+ const SiS_LVDSDataStruct *SiS_LVDSXXXxXXXData_1;
+ const SiS_LVDSDataStruct *SiS_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_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 *LVDS1024x768Des_1;
+ const SiS_LVDSDesStruct *LVDS1280x1024Des_1;
+ const SiS_LVDSDesStruct *LVDS1400x1050Des_1;
+ const SiS_LVDSDesStruct *LVDS1600x1200Des_1;
+ const SiS_LVDSDesStruct *LVDS1024x768Des_2;
+ const SiS_LVDSDesStruct *LVDS1280x1024Des_2;
+ const SiS_LVDSDesStruct *LVDS1400x1050Des_2;
+ const SiS_LVDSDesStruct *LVDS1600x1200Des_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_CHTVCRT1UNTSC;
+ const SiS_LVDSCRT1DataStruct *SiS_CHTVCRT1ONTSC;
+ const SiS_LVDSCRT1DataStruct *SiS_CHTVCRT1UPAL;
+ const SiS_LVDSCRT1DataStruct *SiS_CHTVCRT1OPAL;
+ const SiS_LVDSCRT1DataStruct *SiS_CHTVCRT1SOPAL;
+
+ const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1320x480_1;
+
+ const SiS_LCDACRT1DataStruct *SiS_LCDACRT1800x600_1;
+ const SiS_LCDACRT1DataStruct *SiS_LCDACRT11024x768_1;
+ const SiS_LCDACRT1DataStruct *SiS_LCDACRT11280x1024_1;
+ const SiS_LCDACRT1DataStruct *SiS_LCDACRT11400x1050_1;
+ const SiS_LCDACRT1DataStruct *SiS_LCDACRT11600x1200_1;
+ const SiS_LCDACRT1DataStruct *SiS_LCDACRT1800x600_1_H;
+ const SiS_LCDACRT1DataStruct *SiS_LCDACRT11024x768_1_H;
+ const SiS_LCDACRT1DataStruct *SiS_LCDACRT11280x1024_1_H;
+ const SiS_LCDACRT1DataStruct *SiS_LCDACRT11400x1050_1_H;
+ const SiS_LCDACRT1DataStruct *SiS_LCDACRT11600x1200_1_H;
+ const SiS_LCDACRT1DataStruct *SiS_LCDACRT1800x600_2;
+ const SiS_LCDACRT1DataStruct *SiS_LCDACRT11024x768_2;
+ const SiS_LCDACRT1DataStruct *SiS_LCDACRT11280x1024_2;
+ const SiS_LCDACRT1DataStruct *SiS_LCDACRT11400x1050_2;
+ const SiS_LCDACRT1DataStruct *SiS_LCDACRT11600x1200_2;
+ const SiS_LCDACRT1DataStruct *SiS_LCDACRT1800x600_2_H;
+ const SiS_LCDACRT1DataStruct *SiS_LCDACRT11024x768_2_H;
+ const SiS_LCDACRT1DataStruct *SiS_LCDACRT11280x1024_2_H;
+ const SiS_LCDACRT1DataStruct *SiS_LCDACRT11400x1050_2_H;
+ const SiS_LCDACRT1DataStruct *SiS_LCDACRT11600x1200_2_H;
+
+ /* TW: New for 650/301LV */
+ const SiS_Part2PortTblStruct *SiS_CRT2Part2_1024x768_1;
+ const SiS_Part2PortTblStruct *SiS_CRT2Part2_1280x1024_1;
+ const SiS_Part2PortTblStruct *SiS_CRT2Part2_1400x1050_1;
+ const SiS_Part2PortTblStruct *SiS_CRT2Part2_1600x1200_1;
+ const SiS_Part2PortTblStruct *SiS_CRT2Part2_1024x768_2;
+ const SiS_Part2PortTblStruct *SiS_CRT2Part2_1280x1024_2;
+ const SiS_Part2PortTblStruct *SiS_CRT2Part2_1400x1050_2;
+ const SiS_Part2PortTblStruct *SiS_CRT2Part2_1600x1200_2;
+ const SiS_Part2PortTblStruct *SiS_CRT2Part2_1024x768_3;
+ const SiS_Part2PortTblStruct *SiS_CRT2Part2_1280x1024_3;
+ const SiS_Part2PortTblStruct *SiS_CRT2Part2_1400x1050_3;
+ const SiS_Part2PortTblStruct *SiS_CRT2Part2_1600x1200_3;
+
+ 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;
+
+ 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 CModeFlag;
+ USHORT CInfoFlag;
+ BOOLEAN SiS_CHPALM;
+ BOOLEAN SiS_CHPALN;
+} SiS_Private;
+
+#endif
+