1/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/init.c,v 1.3 2002/24/04 01:16:16 dawes Exp $ */
2/*
3 * Mode switching code (CRT1 section) for SiS 300/540/630/730/315/550/650/740
4 * (Universal module for Linux kernel framebuffer and XFree86 4.x)
5 *
6 * Assembler-To-C translation
7 * Parts Copyright 2002 by Thomas Winischhofer <thomas@winischhofer.net>
8 *
9 * Based on BIOS
10 *     1.10.07 (1.10a) for SiS650/LVDS+CH7019
11 *     1.07.1b for SiS650/301(B/LV)
12 *     2.04.50 (I) and 2.04.5c (II), 2.07a for SiS630/301(B)
13 *     2.02.3b, 2.03.02 and 2.04.5c for 630/LVDS/LVDS+CH7005
14 *     1.09b for 315/301(B)
15 *
16 * Permission to use, copy, modify, distribute, and sell this software and its
17 * documentation for any purpose is hereby granted without fee, provided that
18 * the above copyright notice appear in all copies and that both that
19 * copyright notice and this permission notice appear in supporting
20 * documentation, and that the name of the copyright holder not be used in
21 * advertising or publicity pertaining to distribution of the software without
22 * specific, written prior permission.  The copyright holder makes no representations
23 * about the suitability of this software for any purpose.  It is provided
24 * "as is" without express or implied warranty.
25 *
26 * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
27 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
28 * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
29 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
30 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
31 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
32 * PERFORMANCE OF THIS SOFTWARE.
33 *
34 */
35
36#include "init.h"
37
38#ifdef SIS300
39#include "300vtbl.h"
40#endif
41
42#ifdef SIS315H
43#include "310vtbl.h"
44#endif
45
46#ifdef LINUX_XF86
47BOOLEAN SiSBIOSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
48                       ScrnInfoPtr pScrn, DisplayModePtr mode);
49#ifdef SISDUALHEAD     /* TW: For dual head */
50BOOLEAN SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
51                       ScrnInfoPtr pScrn, DisplayModePtr mode);
52BOOLEAN SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
53                       ScrnInfoPtr pScrn, DisplayModePtr mode);
54#endif /* dual head */
55#endif /* linux_xf86 */
56
57#ifdef LINUXBIOS
58BOOLEAN SiSInit(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
59#endif
60
61#ifdef LINUX_XF86
62BOOLEAN SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
63                   ScrnInfoPtr pScrn,USHORT ModeNo, BOOLEAN dosetpitch);
64#else
65BOOLEAN SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
66                   USHORT ModeNo);
67#endif
68
69#if defined(ALLOC_PRAGMA)
70#pragma alloc_text(PAGE,SiSSetMode)
71#pragma alloc_text(PAGE,SiSInit)
72#endif
73
74void DelaySeconds(int seconds);
75void DebugCode(SiS_Private *SiS_Pr, UCHAR code);
76
77#ifdef LINUX_XF86
78/* TW: Mode table for X driver */
79const UShort  ModeIndex_320x480[]      = {0x5A, 0x5B, 0x00, 0x00};  /* DSTN/FSTN */
80const UShort  ModeIndex_512x384[]      = {0x52, 0x58, 0x00, 0x5c};
81const UShort  ModeIndex_640x480[]      = {0x2E, 0x44, 0x00, 0x62};
82const UShort  ModeIndex_720x480[]      = {0x31, 0x33, 0x00, 0x35};
83const UShort  ModeIndex_720x576[]      = {0x32, 0x34, 0x00, 0x36};
84const UShort  ModeIndex_800x480[]      = {0x70, 0x7a, 0x00, 0x76};  /* 310/325 series only */
85const UShort  ModeIndex_800x600[]      = {0x30, 0x47, 0x00, 0x63};
86const UShort  ModeIndex_1024x768[]     = {0x38, 0x4A, 0x00, 0x64};
87const UShort  ModeIndex_1024x576[]     = {0x71, 0x74, 0x00, 0x77};  /* 310/325 series only */
88const UShort  ModeIndex_1024x600[]     = {0x20, 0x21, 0x00, 0x22};  /* 300 series only */
89const UShort  ModeIndex_1280x1024[]    = {0x3A, 0x4D, 0x00, 0x65};
90const UShort  ModeIndex_300_1280x960[] = {0x6e, 0x6f, 0x00, 0x7b};
91const UShort  ModeIndex_310_1280x960[] = {0x7C, 0x7D, 0x00, 0x7E};
92const UShort  ModeIndex_1152x768[]     = {0x23, 0x24, 0x00, 0x25};  /* 300 series only */
93const UShort  ModeIndex_1280x768[]     = {0x23, 0x24, 0x00, 0x25};  /* 310/325 series only */
94const UShort  ModeIndex_1280x720[]     = {0x79, 0x75, 0x00, 0x78};  /* 310/325 series only */
95const UShort  ModeIndex_1400x1050[]    = {0x26, 0x27, 0x00, 0x28};  /* 310/325 series only */
96const UShort  ModeIndex_1600x1200[]    = {0x3C, 0x3D, 0x00, 0x66};
97const UShort  ModeIndex_1920x1440[]    = {0x68, 0x69, 0x00, 0x6B};
98const UShort  ModeIndex_2048x1536[]    = {0x6c, 0x6d, 0x00, 0x6e};  /* 310/325 series only */
99#endif
100
101void
102DelaySeconds(int seconds)
103{
104  int i;
105#ifdef WIN2000
106  int j;
107#endif
108
109  for (i=0;i<seconds;i++) {
110#ifdef TC
111    delay(1000);
112#endif
113
114#ifdef WIN2000
115    for (j=0;j<20000;j++)
116      VideoPortStallExecution(50);
117#endif
118
119#ifdef WINCE_HEADER
120#endif
121
122#ifdef LINUX_KERNEL
123#endif
124  }
125}
126
127void
128DebugCode(SiS_Private *SiS_Pr, UCHAR code)
129{
130  OutPortByte(0x80, code);
131  DelaySeconds(0x3);
132}
133
134#ifdef SIS300
135void
136InitTo300Pointer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
137{
138   SiS_Pr->SiS_SModeIDTable  = (SiS_StStruct *)SiS300_SModeIDTable;
139   SiS_Pr->SiS_VBModeIDTable = (SiS_VBModeStruct *)SiS300_VBModeIDTable;
140   SiS_Pr->SiS_StandTable    = (SiS_StandTableStruct *)SiS300_StandTable;
141   SiS_Pr->SiS_EModeIDTable  = (SiS_ExtStruct *)SiS300_EModeIDTable;
142   SiS_Pr->SiS_RefIndex      = (SiS_Ext2Struct *)SiS300_RefIndex;
143   SiS_Pr->SiS_CRT1Table     = (SiS_CRT1TableStruct *)SiS300_CRT1Table;
144   if(HwDeviceExtension->jChipType == SIS_300) {
145      SiS_Pr->SiS_MCLKData_0    = (SiS_MCLKDataStruct *)SiS300_MCLKData_300; /* 300 */
146   } else {
147      SiS_Pr->SiS_MCLKData_0    = (SiS_MCLKDataStruct *)SiS300_MCLKData_630; /* 630 */
148   }
149   SiS_Pr->SiS_ECLKData      = (SiS_ECLKDataStruct *)SiS300_ECLKData;
150   SiS_Pr->SiS_VCLKData      = (SiS_VCLKDataStruct *)SiS300_VCLKData;
151   SiS_Pr->SiS_VBVCLKData    = (SiS_VBVCLKDataStruct *)SiS300_VCLKData;
152   SiS_Pr->SiS_ScreenOffset  = SiS300_ScreenOffset;
153   SiS_Pr->SiS_StResInfo     = (SiS_StResInfoStruct *)SiS300_StResInfo;
154   SiS_Pr->SiS_ModeResInfo   = (SiS_ModeResInfoStruct *)SiS300_ModeResInfo;
155
156   SiS_Pr->pSiS_OutputSelect = &SiS300_OutputSelect;
157   SiS_Pr->pSiS_SoftSetting  = &SiS300_SoftSetting;
158
159   SiS_Pr->SiS_SR15  = SiS300_SR15;
160
161#ifndef LINUX_XF86
162   SiS_Pr->pSiS_SR07 = &SiS300_SR07;
163   SiS_Pr->SiS_CR40  = SiS300_CR40;
164   SiS_Pr->SiS_CR49  = SiS300_CR49;
165   SiS_Pr->pSiS_SR1F = &SiS300_SR1F;
166   SiS_Pr->pSiS_SR21 = &SiS300_SR21;
167   SiS_Pr->pSiS_SR22 = &SiS300_SR22;
168   SiS_Pr->pSiS_SR23 = &SiS300_SR23;
169   SiS_Pr->pSiS_SR24 = &SiS300_SR24;
170   SiS_Pr->SiS_SR25  = SiS300_SR25;
171   SiS_Pr->pSiS_SR31 = &SiS300_SR31;
172   SiS_Pr->pSiS_SR32 = &SiS300_SR32;
173   SiS_Pr->pSiS_SR33 = &SiS300_SR33;
174   SiS_Pr->pSiS_CRT2Data_1_2  = &SiS300_CRT2Data_1_2;
175   SiS_Pr->pSiS_CRT2Data_4_D  = &SiS300_CRT2Data_4_D;
176   SiS_Pr->pSiS_CRT2Data_4_E  = &SiS300_CRT2Data_4_E;
177   SiS_Pr->pSiS_CRT2Data_4_10 = &SiS300_CRT2Data_4_10;
178   SiS_Pr->pSiS_RGBSenseData    = &SiS300_RGBSenseData;
179   SiS_Pr->pSiS_VideoSenseData  = &SiS300_VideoSenseData;
180   SiS_Pr->pSiS_YCSenseData     = &SiS300_YCSenseData;
181   SiS_Pr->pSiS_RGBSenseData2   = &SiS300_RGBSenseData2;
182   SiS_Pr->pSiS_VideoSenseData2 = &SiS300_VideoSenseData2;
183   SiS_Pr->pSiS_YCSenseData2    = &SiS300_YCSenseData2;
184#endif
185
186   SiS_Pr->SiS_NTSCPhase  = SiS300_NTSCPhase;
187   SiS_Pr->SiS_PALPhase   = SiS300_PALPhase;
188   SiS_Pr->SiS_NTSCPhase2 = SiS300_NTSCPhase2;
189   SiS_Pr->SiS_PALPhase2  = SiS300_PALPhase2;
190   SiS_Pr->SiS_PALMPhase  = SiS300_PALMPhase;
191   SiS_Pr->SiS_PALNPhase  = SiS300_PALNPhase;
192   SiS_Pr->SiS_PALMPhase2 = SiS300_PALMPhase2;
193   SiS_Pr->SiS_PALNPhase2 = SiS300_PALNPhase2;
194
195   SiS_Pr->SiS_StLCD1024x768Data    = (SiS_LCDDataStruct *)SiS300_StLCD1024x768Data;
196   SiS_Pr->SiS_ExtLCD1024x768Data   = (SiS_LCDDataStruct *)SiS300_ExtLCD1024x768Data;
197   SiS_Pr->SiS_St2LCD1024x768Data   = (SiS_LCDDataStruct *)SiS300_St2LCD1024x768Data;
198   SiS_Pr->SiS_StLCD1280x1024Data   = (SiS_LCDDataStruct *)SiS300_StLCD1280x1024Data;
199   SiS_Pr->SiS_ExtLCD1280x1024Data  = (SiS_LCDDataStruct *)SiS300_ExtLCD1280x1024Data;
200   SiS_Pr->SiS_St2LCD1280x1024Data  = (SiS_LCDDataStruct *)SiS300_St2LCD1280x1024Data;
201   SiS_Pr->SiS_NoScaleData1024x768  = (SiS_LCDDataStruct *)SiS300_NoScaleData1024x768;
202   SiS_Pr->SiS_NoScaleData1280x1024 = (SiS_LCDDataStruct *)SiS300_NoScaleData1280x1024;
203   SiS_Pr->SiS_LCD1280x960Data      = (SiS_LCDDataStruct *)SiS300_LCD1280x960Data;
204   SiS_Pr->SiS_ExtLCD1400x1050Data  = (SiS_LCDDataStruct *)SiS300_ExtLCD1400x1050Data;
205   SiS_Pr->SiS_ExtLCD1600x1200Data  = (SiS_LCDDataStruct *)SiS300_ExtLCD1600x1200Data;
206   SiS_Pr->SiS_StLCD1400x1050Data   = (SiS_LCDDataStruct *)SiS300_StLCD1400x1050Data;
207   SiS_Pr->SiS_StLCD1600x1200Data   = (SiS_LCDDataStruct *)SiS300_StLCD1600x1200Data;
208   SiS_Pr->SiS_NoScaleData1400x1050 = (SiS_LCDDataStruct *)SiS300_NoScaleData1400x1050;
209   SiS_Pr->SiS_NoScaleData1600x1200 = (SiS_LCDDataStruct *)SiS300_NoScaleData1600x1200;
210
211   SiS_Pr->SiS_StPALData   = (SiS_TVDataStruct *)SiS300_StPALData;
212   SiS_Pr->SiS_ExtPALData  = (SiS_TVDataStruct *)SiS300_ExtPALData;
213   SiS_Pr->SiS_StNTSCData  = (SiS_TVDataStruct *)SiS300_StNTSCData;
214   SiS_Pr->SiS_ExtNTSCData = (SiS_TVDataStruct *)SiS300_ExtNTSCData;
215#ifdef oldHV
216   SiS_Pr->SiS_St1HiTVData = (SiS_TVDataStruct *)SiS300_St1HiTVData;
217   SiS_Pr->SiS_St2HiTVData = (SiS_TVDataStruct *)SiS300_St2HiTVData;
218   SiS_Pr->SiS_ExtHiTVData = (SiS_TVDataStruct *)SiS300_ExtHiTVData;
219#endif
220
221   SiS_Pr->SiS_NTSCTiming     = SiS300_NTSCTiming;
222   SiS_Pr->SiS_PALTiming      = SiS300_PALTiming;
223#ifdef oldHV
224   SiS_Pr->SiS_HiTVSt1Timing  = SiS300_HiTVSt1Timing;
225   SiS_Pr->SiS_HiTVSt2Timing  = SiS300_HiTVSt2Timing;
226   SiS_Pr->SiS_HiTVTextTiming = SiS300_HiTVTextTiming;
227   SiS_Pr->SiS_HiTVGroup3Data = SiS300_HiTVGroup3Data;
228   SiS_Pr->SiS_HiTVGroup3Simu = SiS300_HiTVGroup3Simu;
229   SiS_Pr->SiS_HiTVGroup3Text = SiS300_HiTVGroup3Text;
230#endif
231
232   SiS_Pr->SiS_PanelDelayTbl     = (SiS_PanelDelayTblStruct *)SiS300_PanelDelayTbl;
233   SiS_Pr->SiS_PanelDelayTblLVDS = (SiS_PanelDelayTblStruct *)SiS300_PanelDelayTblLVDS;
234
235   SiS_Pr->SiS_LVDS800x600Data_1   = (SiS_LVDSDataStruct *)SiS300_LVDS800x600Data_1;
236   SiS_Pr->SiS_LVDS800x600Data_2   = (SiS_LVDSDataStruct *)SiS300_LVDS800x600Data_2;
237   SiS_Pr->SiS_LVDS1024x768Data_1  = (SiS_LVDSDataStruct *)SiS300_LVDS1024x768Data_1;
238   SiS_Pr->SiS_LVDS1024x768Data_2  = (SiS_LVDSDataStruct *)SiS300_LVDS1024x768Data_2;
239   SiS_Pr->SiS_LVDS1280x1024Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS1280x1024Data_1;
240   SiS_Pr->SiS_LVDS1280x1024Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS1280x1024Data_2;
241   SiS_Pr->SiS_LVDS1280x960Data_1  = (SiS_LVDSDataStruct *)SiS300_LVDS1280x1024Data_1;
242   SiS_Pr->SiS_LVDS1280x960Data_2  = (SiS_LVDSDataStruct *)SiS300_LVDS1280x1024Data_2;
243   SiS_Pr->SiS_LVDS1400x1050Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS1400x1050Data_1;
244   SiS_Pr->SiS_LVDS1400x1050Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS1400x1050Data_2;
245   SiS_Pr->SiS_LVDS1024x600Data_1  = (SiS_LVDSDataStruct *)SiS300_LVDS1024x600Data_1;
246   SiS_Pr->SiS_LVDS1024x600Data_2  = (SiS_LVDSDataStruct *)SiS300_LVDS1024x600Data_2;
247   SiS_Pr->SiS_LVDS1152x768Data_1  = (SiS_LVDSDataStruct *)SiS300_LVDS1152x768Data_1;
248   SiS_Pr->SiS_LVDS1152x768Data_2  = (SiS_LVDSDataStruct *)SiS300_LVDS1152x768Data_2;
249   SiS_Pr->SiS_LVDSXXXxXXXData_1   = (SiS_LVDSDataStruct *)SiS300_LVDSXXXxXXXData_1;
250   SiS_Pr->SiS_LVDS320x480Data_1   = (SiS_LVDSDataStruct *)SiS300_LVDS320x480Data_1;
251   SiS_Pr->SiS_LVDS640x480Data_1   = (SiS_LVDSDataStruct *)SiS300_LVDS640x480Data_1;
252   SiS_Pr->SiS_LCDA1400x1050Data_1 = (SiS_LVDSDataStruct *)SiS300_LCDA1400x1050Data_1;
253   SiS_Pr->SiS_LCDA1400x1050Data_2 = (SiS_LVDSDataStruct *)SiS300_LCDA1400x1050Data_2;
254   SiS_Pr->SiS_LCDA1600x1200Data_1 = (SiS_LVDSDataStruct *)SiS300_LCDA1600x1200Data_1;
255   SiS_Pr->SiS_LCDA1600x1200Data_2 = (SiS_LVDSDataStruct *)SiS300_LCDA1600x1200Data_2;
256   SiS_Pr->SiS_CHTVUNTSCData = (SiS_LVDSDataStruct *)SiS300_CHTVUNTSCData;
257   SiS_Pr->SiS_CHTVONTSCData = (SiS_LVDSDataStruct *)SiS300_CHTVONTSCData;
258   SiS_Pr->SiS_CHTVUPALData  = (SiS_LVDSDataStruct *)SiS300_CHTVUPALData;
259   SiS_Pr->SiS_CHTVOPALData  = (SiS_LVDSDataStruct *)SiS300_CHTVOPALData;
260   SiS_Pr->SiS_PanelType00_1 = (SiS_LVDSDesStruct *)SiS300_PanelType00_1;
261   SiS_Pr->SiS_PanelType01_1 = (SiS_LVDSDesStruct *)SiS300_PanelType01_1;
262   SiS_Pr->SiS_PanelType02_1 = (SiS_LVDSDesStruct *)SiS300_PanelType02_1;
263   SiS_Pr->SiS_PanelType03_1 = (SiS_LVDSDesStruct *)SiS300_PanelType03_1;
264   SiS_Pr->SiS_PanelType04_1 = (SiS_LVDSDesStruct *)SiS300_PanelType04_1;
265   SiS_Pr->SiS_PanelType05_1 = (SiS_LVDSDesStruct *)SiS300_PanelType05_1;
266   SiS_Pr->SiS_PanelType06_1 = (SiS_LVDSDesStruct *)SiS300_PanelType06_1;
267   SiS_Pr->SiS_PanelType07_1 = (SiS_LVDSDesStruct *)SiS300_PanelType07_1;
268   SiS_Pr->SiS_PanelType08_1 = (SiS_LVDSDesStruct *)SiS300_PanelType08_1;
269   SiS_Pr->SiS_PanelType09_1 = (SiS_LVDSDesStruct *)SiS300_PanelType09_1;
270   SiS_Pr->SiS_PanelType0a_1 = (SiS_LVDSDesStruct *)SiS300_PanelType0a_1;
271   SiS_Pr->SiS_PanelType0b_1 = (SiS_LVDSDesStruct *)SiS300_PanelType0b_1;
272   SiS_Pr->SiS_PanelType0c_1 = (SiS_LVDSDesStruct *)SiS300_PanelType0c_1;
273   SiS_Pr->SiS_PanelType0d_1 = (SiS_LVDSDesStruct *)SiS300_PanelType0d_1;
274   SiS_Pr->SiS_PanelType0e_1 = (SiS_LVDSDesStruct *)SiS300_PanelType0e_1;
275   SiS_Pr->SiS_PanelType0f_1 = (SiS_LVDSDesStruct *)SiS300_PanelType0f_1;
276   SiS_Pr->SiS_PanelType00_2 = (SiS_LVDSDesStruct *)SiS300_PanelType00_2;
277   SiS_Pr->SiS_PanelType01_2 = (SiS_LVDSDesStruct *)SiS300_PanelType01_2;
278   SiS_Pr->SiS_PanelType02_2 = (SiS_LVDSDesStruct *)SiS300_PanelType02_2;
279   SiS_Pr->SiS_PanelType03_2 = (SiS_LVDSDesStruct *)SiS300_PanelType03_2;
280   SiS_Pr->SiS_PanelType04_2 = (SiS_LVDSDesStruct *)SiS300_PanelType04_2;
281   SiS_Pr->SiS_PanelType05_2 = (SiS_LVDSDesStruct *)SiS300_PanelType05_2;
282   SiS_Pr->SiS_PanelType06_2 = (SiS_LVDSDesStruct *)SiS300_PanelType06_2;
283   SiS_Pr->SiS_PanelType07_2 = (SiS_LVDSDesStruct *)SiS300_PanelType07_2;
284   SiS_Pr->SiS_PanelType08_2 = (SiS_LVDSDesStruct *)SiS300_PanelType08_2;
285   SiS_Pr->SiS_PanelType09_2 = (SiS_LVDSDesStruct *)SiS300_PanelType09_2;
286   SiS_Pr->SiS_PanelType0a_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0a_2;
287   SiS_Pr->SiS_PanelType0b_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0b_2;
288   SiS_Pr->SiS_PanelType0c_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0c_2;
289   SiS_Pr->SiS_PanelType0d_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0d_2;
290   SiS_Pr->SiS_PanelType0e_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0e_2;
291   SiS_Pr->SiS_PanelType0f_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0f_2;
292   SiS_Pr->SiS_CHTVUNTSCDesData = (SiS_LVDSDesStruct *)SiS300_CHTVUNTSCDesData;
293   SiS_Pr->SiS_CHTVONTSCDesData = (SiS_LVDSDesStruct *)SiS300_CHTVONTSCDesData;
294   SiS_Pr->SiS_CHTVUPALDesData  = (SiS_LVDSDesStruct *)SiS300_CHTVUPALDesData;
295   SiS_Pr->SiS_CHTVOPALDesData  = (SiS_LVDSDesStruct *)SiS300_CHTVOPALDesData;
296   SiS_Pr->SiS_LVDSCRT1800x600_1     = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT1800x600_1;
297   SiS_Pr->SiS_LVDSCRT11024x768_1    = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x768_1;
298   SiS_Pr->SiS_LVDSCRT11280x1024_1   = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11280x1024_1;
299   SiS_Pr->SiS_LVDSCRT11024x600_1    = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x600_1;
300   SiS_Pr->SiS_LVDSCRT11152x768_1    = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11152x768_1;
301   SiS_Pr->SiS_LVDSCRT1800x600_1_H   = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT1800x600_1_H;
302   SiS_Pr->SiS_LVDSCRT11024x768_1_H  = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x768_1_H;
303   SiS_Pr->SiS_LVDSCRT11280x1024_1_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11280x1024_1_H;
304   SiS_Pr->SiS_LVDSCRT11024x600_1_H  = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x600_1_H;
305   SiS_Pr->SiS_LVDSCRT11152x768_1_H  = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11152x768_1_H;
306   SiS_Pr->SiS_LVDSCRT1800x600_2     = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT1800x600_2;
307   SiS_Pr->SiS_LVDSCRT11024x768_2    = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x768_2;
308   SiS_Pr->SiS_LVDSCRT11280x1024_2   = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11280x1024_2;
309   SiS_Pr->SiS_LVDSCRT11024x600_2    = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x600_2;
310   SiS_Pr->SiS_LVDSCRT11152x768_2    = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11152x768_2;
311   SiS_Pr->SiS_LVDSCRT1800x600_2_H   = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT1800x600_2_H;
312   SiS_Pr->SiS_LVDSCRT11024x768_2_H  = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x768_2_H;
313   SiS_Pr->SiS_LVDSCRT11280x1024_2_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11280x1024_2_H;
314   SiS_Pr->SiS_LVDSCRT11024x600_2_H  = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x600_2_H;
315   SiS_Pr->SiS_LVDSCRT11152x768_2_H  = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11152x768_2_H;
316   SiS_Pr->SiS_CHTVCRT1UNTSC = (SiS_LVDSCRT1DataStruct *)SiS300_CHTVCRT1UNTSC;
317   SiS_Pr->SiS_CHTVCRT1ONTSC = (SiS_LVDSCRT1DataStruct *)SiS300_CHTVCRT1ONTSC;
318   SiS_Pr->SiS_CHTVCRT1UPAL  = (SiS_LVDSCRT1DataStruct *)SiS300_CHTVCRT1UPAL;
319   SiS_Pr->SiS_CHTVCRT1OPAL  = (SiS_LVDSCRT1DataStruct *)SiS300_CHTVCRT1OPAL;
320   SiS_Pr->SiS_CHTVReg_UNTSC = (SiS_CHTVRegDataStruct *)SiS300_CHTVReg_UNTSC;
321   SiS_Pr->SiS_CHTVReg_ONTSC = (SiS_CHTVRegDataStruct *)SiS300_CHTVReg_ONTSC;
322   SiS_Pr->SiS_CHTVReg_UPAL  = (SiS_CHTVRegDataStruct *)SiS300_CHTVReg_UPAL;
323   SiS_Pr->SiS_CHTVReg_OPAL  = (SiS_CHTVRegDataStruct *)SiS300_CHTVReg_OPAL;
324   SiS_Pr->SiS_CHTVVCLKUNTSC = SiS300_CHTVVCLKUNTSC;
325   SiS_Pr->SiS_CHTVVCLKONTSC = SiS300_CHTVVCLKONTSC;
326   SiS_Pr->SiS_CHTVVCLKUPAL  = SiS300_CHTVVCLKUPAL;
327   SiS_Pr->SiS_CHTVVCLKOPAL  = SiS300_CHTVVCLKOPAL;
328
329   /* TW: LCDResInfo will on 300 series be translated to 310/325 series definitions */
330   SiS_Pr->SiS_Panel320x480   = Panel_320x480;
331   SiS_Pr->SiS_Panel640x480   = Panel_640x480;
332   SiS_Pr->SiS_Panel800x600   = Panel_800x600;
333   SiS_Pr->SiS_Panel1024x768  = Panel_1024x768;
334   SiS_Pr->SiS_Panel1280x1024 = Panel_1280x1024;
335   SiS_Pr->SiS_Panel1280x960  = Panel_1280x960;
336   SiS_Pr->SiS_Panel1024x600  = Panel_1024x600;
337   SiS_Pr->SiS_Panel1152x768  = Panel_1152x768;
338   SiS_Pr->SiS_Panel1600x1200 = 16;  		/* TW: Something illegal */
339   SiS_Pr->SiS_Panel1400x1050 = 16;  		/* TW: Something illegal */
340   SiS_Pr->SiS_Panel1152x864  = 16;   		/* TW: Something illegal */
341   SiS_Pr->SiS_Panel1280x768  = 16;   		/* TW: Something illegal */
342   SiS_Pr->SiS_PanelMax       = Panel_320x480;     /* TW: highest value */
343   SiS_Pr->SiS_PanelMinLVDS   = Panel_800x600;     /* TW: Lowest value LVDS */
344   SiS_Pr->SiS_PanelMin301    = Panel_1024x768;    /* TW: lowest value 301 */
345}
346#endif
347
348#ifdef SIS315H
349void
350InitTo310Pointer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
351{
352   SiS_Pr->SiS_SModeIDTable  = (SiS_StStruct *)SiS310_SModeIDTable;
353   SiS_Pr->SiS_StandTable    = (SiS_StandTableStruct *)SiS310_StandTable;
354   SiS_Pr->SiS_EModeIDTable  = (SiS_ExtStruct *)SiS310_EModeIDTable;
355   SiS_Pr->SiS_RefIndex      = (SiS_Ext2Struct *)SiS310_RefIndex;
356   SiS_Pr->SiS_CRT1Table     = (SiS_CRT1TableStruct *)SiS310_CRT1Table;
357   /* TW: MCLK is different */
358   if(HwDeviceExtension->jChipType > SIS_315PRO) {
359      SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS310_MCLKData_0_650;  /* 550, 650 */
360   } else {
361      SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS310_MCLKData_0_315;  /* 315 */
362   }
363   SiS_Pr->SiS_MCLKData_1    = (SiS_MCLKDataStruct *)SiS310_MCLKData_1;
364   SiS_Pr->SiS_ECLKData      = (SiS_ECLKDataStruct *)SiS310_ECLKData;
365   SiS_Pr->SiS_VCLKData      = (SiS_VCLKDataStruct *)SiS310_VCLKData;
366   SiS_Pr->SiS_VBVCLKData    = (SiS_VBVCLKDataStruct *)SiS310_VBVCLKData;
367   SiS_Pr->SiS_ScreenOffset  = SiS310_ScreenOffset;
368   SiS_Pr->SiS_StResInfo     = (SiS_StResInfoStruct *)SiS310_StResInfo;
369   SiS_Pr->SiS_ModeResInfo   = (SiS_ModeResInfoStruct *)SiS310_ModeResInfo;
370
371   SiS_Pr->pSiS_OutputSelect = &SiS310_OutputSelect;
372   SiS_Pr->pSiS_SoftSetting  = &SiS310_SoftSetting;
373
374   SiS_Pr->SiS_SR15  = SiS310_SR15;
375
376#ifndef LINUX_XF86
377   SiS_Pr->pSiS_SR07 = &SiS310_SR07;
378   SiS_Pr->SiS_CR40  = SiS310_CR40;
379   SiS_Pr->SiS_CR49  = SiS310_CR49;
380   SiS_Pr->pSiS_SR1F = &SiS310_SR1F;
381   SiS_Pr->pSiS_SR21 = &SiS310_SR21;
382   SiS_Pr->pSiS_SR22 = &SiS310_SR22;
383   SiS_Pr->pSiS_SR23 = &SiS310_SR23;
384   SiS_Pr->pSiS_SR24 = &SiS310_SR24;
385   SiS_Pr->SiS_SR25  = SiS310_SR25;
386   SiS_Pr->pSiS_SR31 = &SiS310_SR31;
387   SiS_Pr->pSiS_SR32 = &SiS310_SR32;
388   SiS_Pr->pSiS_SR33 = &SiS310_SR33;
389   SiS_Pr->pSiS_CRT2Data_1_2  = &SiS310_CRT2Data_1_2;
390   SiS_Pr->pSiS_CRT2Data_4_D  = &SiS310_CRT2Data_4_D;
391   SiS_Pr->pSiS_CRT2Data_4_E  = &SiS310_CRT2Data_4_E;
392   SiS_Pr->pSiS_CRT2Data_4_10 = &SiS310_CRT2Data_4_10;
393   SiS_Pr->pSiS_RGBSenseData    = &SiS310_RGBSenseData;
394   SiS_Pr->pSiS_VideoSenseData  = &SiS310_VideoSenseData;
395   SiS_Pr->pSiS_YCSenseData     = &SiS310_YCSenseData;
396   SiS_Pr->pSiS_RGBSenseData2   = &SiS310_RGBSenseData2;
397   SiS_Pr->pSiS_VideoSenseData2 = &SiS310_VideoSenseData2;
398   SiS_Pr->pSiS_YCSenseData2    = &SiS310_YCSenseData2;
399#endif
400
401   SiS_Pr->SiS_NTSCPhase    = SiS310_NTSCPhase;
402   SiS_Pr->SiS_PALPhase     = SiS310_PALPhase;
403   SiS_Pr->SiS_NTSCPhase2   = SiS310_NTSCPhase2;
404   SiS_Pr->SiS_PALPhase2    = SiS310_PALPhase2;
405   SiS_Pr->SiS_PALMPhase    = SiS310_PALMPhase;
406   SiS_Pr->SiS_PALNPhase    = SiS310_PALNPhase;
407   SiS_Pr->SiS_PALMPhase2   = SiS310_PALMPhase2;
408   SiS_Pr->SiS_PALNPhase2   = SiS310_PALNPhase2;
409   SiS_Pr->SiS_SpecialPhase = SiS310_SpecialPhase;
410
411   SiS_Pr->SiS_StLCD1024x768Data    = (SiS_LCDDataStruct *)SiS310_StLCD1024x768Data;
412   SiS_Pr->SiS_ExtLCD1024x768Data   = (SiS_LCDDataStruct *)SiS310_ExtLCD1024x768Data;
413   SiS_Pr->SiS_St2LCD1024x768Data   = (SiS_LCDDataStruct *)SiS310_St2LCD1024x768Data;
414   SiS_Pr->SiS_StLCD1280x1024Data   = (SiS_LCDDataStruct *)SiS310_StLCD1280x1024Data;
415   SiS_Pr->SiS_ExtLCD1280x1024Data  = (SiS_LCDDataStruct *)SiS310_ExtLCD1280x1024Data;
416   SiS_Pr->SiS_St2LCD1280x1024Data  = (SiS_LCDDataStruct *)SiS310_St2LCD1280x1024Data;
417   SiS_Pr->SiS_NoScaleData1024x768  = (SiS_LCDDataStruct *)SiS310_NoScaleData1024x768;
418   SiS_Pr->SiS_NoScaleData1280x1024 = (SiS_LCDDataStruct *)SiS310_NoScaleData1280x1024;
419   SiS_Pr->SiS_LCD1280x960Data      = (SiS_LCDDataStruct *)SiS310_LCD1280x960Data;
420   SiS_Pr->SiS_ExtLCD1400x1050Data  = (SiS_LCDDataStruct *)SiS310_ExtLCD1400x1050Data;
421   SiS_Pr->SiS_ExtLCD1600x1200Data  = (SiS_LCDDataStruct *)SiS310_ExtLCD1600x1200Data;
422   SiS_Pr->SiS_StLCD1400x1050Data   = (SiS_LCDDataStruct *)SiS310_StLCD1400x1050Data;
423   SiS_Pr->SiS_StLCD1600x1200Data   = (SiS_LCDDataStruct *)SiS310_StLCD1600x1200Data;
424   SiS_Pr->SiS_NoScaleData1400x1050 = (SiS_LCDDataStruct *)SiS310_NoScaleData1400x1050;
425   SiS_Pr->SiS_NoScaleData1600x1200 = (SiS_LCDDataStruct *)SiS310_NoScaleData1600x1200;
426
427   SiS_Pr->SiS_StPALData   = (SiS_TVDataStruct *)SiS310_StPALData;
428   SiS_Pr->SiS_ExtPALData  = (SiS_TVDataStruct *)SiS310_ExtPALData;
429   SiS_Pr->SiS_StNTSCData  = (SiS_TVDataStruct *)SiS310_StNTSCData;
430   SiS_Pr->SiS_ExtNTSCData = (SiS_TVDataStruct *)SiS310_ExtNTSCData;
431#ifdef oldHV
432   SiS_Pr->SiS_St1HiTVData = (SiS_TVDataStruct *)SiS310_St1HiTVData;
433   SiS_Pr->SiS_St2HiTVData = (SiS_TVDataStruct *)SiS310_St2HiTVData;
434   SiS_Pr->SiS_ExtHiTVData = (SiS_TVDataStruct *)SiS310_ExtHiTVData;
435#endif
436
437   SiS_Pr->SiS_NTSCTiming     = SiS310_NTSCTiming;
438   SiS_Pr->SiS_PALTiming      = SiS310_PALTiming;
439#ifdef oldHV
440   SiS_Pr->SiS_HiTVSt1Timing  = SiS310_HiTVSt1Timing;
441   SiS_Pr->SiS_HiTVSt2Timing  = SiS310_HiTVSt2Timing;
442   SiS_Pr->SiS_HiTVTextTiming = SiS310_HiTVTextTiming;
443   SiS_Pr->SiS_HiTVExtTiming  = SiS310_HiTVExtTiming;
444   SiS_Pr->SiS_HiTVGroup3Data = SiS310_HiTVGroup3Data;
445   SiS_Pr->SiS_HiTVGroup3Simu = SiS310_HiTVGroup3Simu;
446   SiS_Pr->SiS_HiTVGroup3Text = SiS310_HiTVGroup3Text;
447#endif
448
449   SiS_Pr->SiS_PanelDelayTbl = (SiS_PanelDelayTblStruct *)SiS310_PanelDelayTbl;
450   SiS_Pr->SiS_PanelDelayTblLVDS = (SiS_PanelDelayTblStruct *)SiS310_PanelDelayTblLVDS;
451
452   SiS_Pr->SiS_LVDS800x600Data_1   = (SiS_LVDSDataStruct *)SiS310_LVDS800x600Data_1;
453   SiS_Pr->SiS_LVDS800x600Data_2   = (SiS_LVDSDataStruct *)SiS310_LVDS800x600Data_2;
454   SiS_Pr->SiS_LVDS1024x768Data_1  = (SiS_LVDSDataStruct *)SiS310_LVDS1024x768Data_1;
455   SiS_Pr->SiS_LVDS1024x768Data_2  = (SiS_LVDSDataStruct *)SiS310_LVDS1024x768Data_2;
456   SiS_Pr->SiS_LVDS1280x1024Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS1280x1024Data_1;
457   SiS_Pr->SiS_LVDS1280x1024Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS1280x1024Data_2;
458   SiS_Pr->SiS_LVDS1280x960Data_1  = (SiS_LVDSDataStruct *)SiS310_LVDS1280x960Data_1;
459   SiS_Pr->SiS_LVDS1280x960Data_2  = (SiS_LVDSDataStruct *)SiS310_LVDS1280x960Data_2;
460   SiS_Pr->SiS_LVDS1400x1050Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS1400x1050Data_1;
461   SiS_Pr->SiS_LVDS1400x1050Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS1400x1050Data_2;
462   SiS_Pr->SiS_LVDS1024x600Data_1  = (SiS_LVDSDataStruct *)SiS310_LVDS1024x600Data_1;
463   SiS_Pr->SiS_LVDS1024x600Data_2  = (SiS_LVDSDataStruct *)SiS310_LVDS1024x600Data_2;
464   SiS_Pr->SiS_LVDS1152x768Data_1  = (SiS_LVDSDataStruct *)SiS310_LVDS1152x768Data_1;
465   SiS_Pr->SiS_LVDS1152x768Data_2  = (SiS_LVDSDataStruct *)SiS310_LVDS1152x768Data_2;
466   SiS_Pr->SiS_LVDSXXXxXXXData_1   = (SiS_LVDSDataStruct *)SiS310_LVDSXXXxXXXData_1;
467   SiS_Pr->SiS_LVDS320x480Data_1   = (SiS_LVDSDataStruct *)SiS310_LVDS320x480Data_1;
468   SiS_Pr->SiS_LVDS640x480Data_1   = (SiS_LVDSDataStruct *)SiS310_LVDS640x480Data_1;
469   SiS_Pr->SiS_LCDA1400x1050Data_1  = (SiS_LVDSDataStruct *)SiS310_LCDA1400x1050Data_1;
470   SiS_Pr->SiS_LCDA1400x1050Data_2  = (SiS_LVDSDataStruct *)SiS310_LCDA1400x1050Data_2;
471   SiS_Pr->SiS_LCDA1600x1200Data_1  = (SiS_LVDSDataStruct *)SiS310_LCDA1600x1200Data_1;
472   SiS_Pr->SiS_LCDA1600x1200Data_2  = (SiS_LVDSDataStruct *)SiS310_LCDA1600x1200Data_2;
473   SiS_Pr->SiS_CHTVUNTSCData = (SiS_LVDSDataStruct *)SiS310_CHTVUNTSCData;
474   SiS_Pr->SiS_CHTVONTSCData = (SiS_LVDSDataStruct *)SiS310_CHTVONTSCData;
475   SiS_Pr->SiS_CHTVUPALData  = (SiS_LVDSDataStruct *)SiS310_CHTVUPALData;
476   SiS_Pr->SiS_CHTVOPALData  = (SiS_LVDSDataStruct *)SiS310_CHTVOPALData;
477   SiS_Pr->SiS_PanelType00_1 = (SiS_LVDSDesStruct *)SiS310_PanelType00_1;
478   SiS_Pr->SiS_PanelType01_1 = (SiS_LVDSDesStruct *)SiS310_PanelType01_1;
479   SiS_Pr->SiS_PanelType02_1 = (SiS_LVDSDesStruct *)SiS310_PanelType02_1;
480   SiS_Pr->SiS_PanelType03_1 = (SiS_LVDSDesStruct *)SiS310_PanelType03_1;
481   SiS_Pr->SiS_PanelType04_1 = (SiS_LVDSDesStruct *)SiS310_PanelType04_1;
482   SiS_Pr->SiS_PanelType05_1 = (SiS_LVDSDesStruct *)SiS310_PanelType05_1;
483   SiS_Pr->SiS_PanelType06_1 = (SiS_LVDSDesStruct *)SiS310_PanelType06_1;
484   SiS_Pr->SiS_PanelType07_1 = (SiS_LVDSDesStruct *)SiS310_PanelType07_1;
485   SiS_Pr->SiS_PanelType08_1 = (SiS_LVDSDesStruct *)SiS310_PanelType08_1;
486   SiS_Pr->SiS_PanelType09_1 = (SiS_LVDSDesStruct *)SiS310_PanelType09_1;
487   SiS_Pr->SiS_PanelType0a_1 = (SiS_LVDSDesStruct *)SiS310_PanelType0a_1;
488   SiS_Pr->SiS_PanelType0b_1 = (SiS_LVDSDesStruct *)SiS310_PanelType0b_1;
489   SiS_Pr->SiS_PanelType0c_1 = (SiS_LVDSDesStruct *)SiS310_PanelType0c_1;
490   SiS_Pr->SiS_PanelType0d_1 = (SiS_LVDSDesStruct *)SiS310_PanelType0d_1;
491   SiS_Pr->SiS_PanelType0e_1 = (SiS_LVDSDesStruct *)SiS310_PanelType0e_1;
492   SiS_Pr->SiS_PanelType0f_1 = (SiS_LVDSDesStruct *)SiS310_PanelType0f_1;
493   SiS_Pr->SiS_PanelType00_2 = (SiS_LVDSDesStruct *)SiS310_PanelType00_2;
494   SiS_Pr->SiS_PanelType01_2 = (SiS_LVDSDesStruct *)SiS310_PanelType01_2;
495   SiS_Pr->SiS_PanelType02_2 = (SiS_LVDSDesStruct *)SiS310_PanelType02_2;
496   SiS_Pr->SiS_PanelType03_2 = (SiS_LVDSDesStruct *)SiS310_PanelType03_2;
497   SiS_Pr->SiS_PanelType04_2 = (SiS_LVDSDesStruct *)SiS310_PanelType04_2;
498   SiS_Pr->SiS_PanelType05_2 = (SiS_LVDSDesStruct *)SiS310_PanelType05_2;
499   SiS_Pr->SiS_PanelType06_2 = (SiS_LVDSDesStruct *)SiS310_PanelType06_2;
500   SiS_Pr->SiS_PanelType07_2 = (SiS_LVDSDesStruct *)SiS310_PanelType07_2;
501   SiS_Pr->SiS_PanelType08_2 = (SiS_LVDSDesStruct *)SiS310_PanelType08_2;
502   SiS_Pr->SiS_PanelType09_2 = (SiS_LVDSDesStruct *)SiS310_PanelType09_2;
503   SiS_Pr->SiS_PanelType0a_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0a_2;
504   SiS_Pr->SiS_PanelType0b_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0b_2;
505   SiS_Pr->SiS_PanelType0c_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0c_2;
506   SiS_Pr->SiS_PanelType0d_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0d_2;
507   SiS_Pr->SiS_PanelType0e_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0e_2;
508   SiS_Pr->SiS_PanelType0f_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0f_2;
509
510   SiS_Pr->LVDS1024x768Des_1  = (SiS_LVDSDesStruct *)SiS310_PanelType1076_1;
511   SiS_Pr->LVDS1280x1024Des_1 = (SiS_LVDSDesStruct *)SiS310_PanelType1210_1;
512   SiS_Pr->LVDS1400x1050Des_1 = (SiS_LVDSDesStruct *)SiS310_PanelType1296_1 ;
513   SiS_Pr->LVDS1600x1200Des_1 = (SiS_LVDSDesStruct *)SiS310_PanelType1600_1 ;
514   SiS_Pr->LVDS1024x768Des_2  = (SiS_LVDSDesStruct *)SiS310_PanelType1076_2;
515   SiS_Pr->LVDS1280x1024Des_2 = (SiS_LVDSDesStruct *)SiS310_PanelType1210_2;
516   SiS_Pr->LVDS1400x1050Des_2 = (SiS_LVDSDesStruct *)SiS310_PanelType1296_2;
517   SiS_Pr->LVDS1600x1200Des_2 = (SiS_LVDSDesStruct *)SiS310_PanelType1600_2 ;
518
519   /* TW: New from 650/301LV BIOS */
520   SiS_Pr->SiS_CRT2Part2_1024x768_1  = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1024x768_1;
521   SiS_Pr->SiS_CRT2Part2_1280x1024_1 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1280x1024_1;
522   SiS_Pr->SiS_CRT2Part2_1400x1050_1 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1400x1050_1;
523   SiS_Pr->SiS_CRT2Part2_1600x1200_1 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1600x1200_1;
524   SiS_Pr->SiS_CRT2Part2_1024x768_2  = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1024x768_2;
525   SiS_Pr->SiS_CRT2Part2_1280x1024_2 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1280x1024_2;
526   SiS_Pr->SiS_CRT2Part2_1400x1050_2 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1400x1050_2;
527   SiS_Pr->SiS_CRT2Part2_1600x1200_2 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1600x1200_2;
528   SiS_Pr->SiS_CRT2Part2_1024x768_3  = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1024x768_3;
529   SiS_Pr->SiS_CRT2Part2_1280x1024_3 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1280x1024_3;
530   SiS_Pr->SiS_CRT2Part2_1400x1050_3 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1400x1050_3;
531   SiS_Pr->SiS_CRT2Part2_1600x1200_3 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1600x1200_3;
532
533   SiS_Pr->SiS_CHTVUNTSCDesData = (SiS_LVDSDesStruct *)SiS310_CHTVUNTSCDesData;
534   SiS_Pr->SiS_CHTVONTSCDesData = (SiS_LVDSDesStruct *)SiS310_CHTVONTSCDesData;
535   SiS_Pr->SiS_CHTVUPALDesData  = (SiS_LVDSDesStruct *)SiS310_CHTVUPALDesData;
536   SiS_Pr->SiS_CHTVOPALDesData  = (SiS_LVDSDesStruct *)SiS310_CHTVOPALDesData;
537
538   SiS_Pr->SiS_LVDSCRT1800x600_1     = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1800x600_1;
539   SiS_Pr->SiS_LVDSCRT11024x768_1    = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x768_1;
540   SiS_Pr->SiS_LVDSCRT11280x1024_1   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x1024_1;
541   SiS_Pr->SiS_LVDSCRT11400x1050_1   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11400x1050_1;
542   SiS_Pr->SiS_LVDSCRT11024x600_1    = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x600_1;
543   SiS_Pr->SiS_LVDSCRT11152x768_1    = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11152x768_1;
544   SiS_Pr->SiS_LVDSCRT11600x1200_1   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11600x1200_1;
545   SiS_Pr->SiS_LVDSCRT1800x600_1_H   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1800x600_1_H;
546   SiS_Pr->SiS_LVDSCRT11024x768_1_H  = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x768_1_H;
547   SiS_Pr->SiS_LVDSCRT11280x1024_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x1024_1_H;
548   SiS_Pr->SiS_LVDSCRT11400x1050_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11400x1050_1_H;
549   SiS_Pr->SiS_LVDSCRT11024x600_1_H  = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x600_1_H;
550   SiS_Pr->SiS_LVDSCRT11152x768_1_H  = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11152x768_1_H;
551   SiS_Pr->SiS_LVDSCRT11600x1200_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11600x1200_1_H;
552   SiS_Pr->SiS_LVDSCRT1800x600_2     = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1800x600_2;
553   SiS_Pr->SiS_LVDSCRT11024x768_2    = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x768_2;
554   SiS_Pr->SiS_LVDSCRT11280x1024_2   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x1024_2;
555   SiS_Pr->SiS_LVDSCRT11400x1050_2   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11400x1050_2;
556   SiS_Pr->SiS_LVDSCRT11024x600_2    = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x600_2;
557   SiS_Pr->SiS_LVDSCRT11152x768_2    = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11152x768_2;
558   SiS_Pr->SiS_LVDSCRT11600x1200_2   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11600x1200_2;
559   SiS_Pr->SiS_LVDSCRT1800x600_2_H   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1800x600_2_H;
560   SiS_Pr->SiS_LVDSCRT11024x768_2_H  = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x768_2_H;
561   SiS_Pr->SiS_LVDSCRT11280x1024_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x1024_2_H;
562   SiS_Pr->SiS_LVDSCRT11400x1050_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11400x1050_2_H;
563   SiS_Pr->SiS_LVDSCRT11024x600_2_H  = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x600_2_H;
564   SiS_Pr->SiS_LVDSCRT11152x768_2_H  = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11152x768_2_H;
565   SiS_Pr->SiS_LVDSCRT11600x1200_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11600x1200_2_H;
566   SiS_Pr->SiS_LVDSCRT1XXXxXXX_1     = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1XXXxXXX_1;
567   SiS_Pr->SiS_LVDSCRT1320x480_1     = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1320x480_1;
568   SiS_Pr->SiS_CHTVCRT1UNTSC = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1UNTSC;
569   SiS_Pr->SiS_CHTVCRT1ONTSC = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1ONTSC;
570   SiS_Pr->SiS_CHTVCRT1UPAL  = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1UPAL;
571   SiS_Pr->SiS_CHTVCRT1OPAL  = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1OPAL;
572   SiS_Pr->SiS_CHTVReg_UNTSC = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_UNTSC;
573   SiS_Pr->SiS_CHTVReg_ONTSC = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_ONTSC;
574   SiS_Pr->SiS_CHTVReg_UPAL  = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_UPAL;
575   SiS_Pr->SiS_CHTVReg_OPAL  = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_OPAL;
576   SiS_Pr->SiS_LCDACRT1800x600_1     = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT1800x600_1;
577   SiS_Pr->SiS_LCDACRT11024x768_1    = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11024x768_1;
578   SiS_Pr->SiS_LCDACRT11280x1024_1   = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11280x1024_1;
579   SiS_Pr->SiS_LCDACRT11400x1050_1   = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11400x1050_1;
580   SiS_Pr->SiS_LCDACRT11600x1200_1   = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11600x1200_1;
581   SiS_Pr->SiS_LCDACRT1800x600_1_H   = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT1800x600_1_H;
582   SiS_Pr->SiS_LCDACRT11024x768_1_H  = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11024x768_1_H;
583   SiS_Pr->SiS_LCDACRT11280x1024_1_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11280x1024_1_H;
584   SiS_Pr->SiS_LCDACRT11400x1050_1_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11400x1050_1_H;
585   SiS_Pr->SiS_LCDACRT11600x1200_1_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11600x1200_1_H;
586   SiS_Pr->SiS_LCDACRT1800x600_2     = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT1800x600_2;
587   SiS_Pr->SiS_LCDACRT11024x768_2    = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11024x768_2;
588   SiS_Pr->SiS_LCDACRT11280x1024_2   = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11280x1024_2;
589   SiS_Pr->SiS_LCDACRT11400x1050_2   = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11400x1050_2;
590   SiS_Pr->SiS_LCDACRT11600x1200_2   = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11600x1200_2;
591   SiS_Pr->SiS_LCDACRT1800x600_2_H   = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT1800x600_2_H;
592   SiS_Pr->SiS_LCDACRT11024x768_2_H  = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11024x768_2_H;
593   SiS_Pr->SiS_LCDACRT11280x1024_2_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11280x1024_2_H;
594   SiS_Pr->SiS_LCDACRT11400x1050_2_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11400x1050_2_H;
595   SiS_Pr->SiS_LCDACRT11600x1200_2_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11600x1200_2_H;
596   SiS_Pr->SiS_CHTVVCLKUNTSC = SiS310_CHTVVCLKUNTSC;
597   SiS_Pr->SiS_CHTVVCLKONTSC = SiS310_CHTVVCLKONTSC;
598   SiS_Pr->SiS_CHTVVCLKUPAL  = SiS310_CHTVVCLKUPAL;
599   SiS_Pr->SiS_CHTVVCLKOPAL  = SiS310_CHTVVCLKOPAL;
600
601   SiS_Pr->SiS_Panel320x480   = Panel_320x480;
602   SiS_Pr->SiS_Panel640x480   = Panel_640x480;
603   SiS_Pr->SiS_Panel800x600   = Panel_800x600;
604   SiS_Pr->SiS_Panel1024x768  = Panel_1024x768;
605   SiS_Pr->SiS_Panel1280x1024 = Panel_1280x1024;
606   SiS_Pr->SiS_Panel1280x960  = Panel_1280x960;
607   SiS_Pr->SiS_Panel1600x1200 = Panel_1600x1200;
608   SiS_Pr->SiS_Panel1400x1050 = Panel_1400x1050;
609   SiS_Pr->SiS_Panel1152x768  = Panel_1152x768;
610   SiS_Pr->SiS_Panel1152x864  = Panel_1152x864;
611   SiS_Pr->SiS_Panel1280x768  = Panel_1280x768;
612   SiS_Pr->SiS_Panel1024x600  = Panel_1024x600;
613   SiS_Pr->SiS_PanelMax       = Panel_320x480;    /* TW: highest value */
614   SiS_Pr->SiS_PanelMinLVDS   = Panel_800x600;    /* TW: lowest value LVDS/LCDA */
615   SiS_Pr->SiS_PanelMin301    = Panel_1024x768;   /* TW: lowest value 301 */
616}
617#endif
618
619#ifdef LINUXBIOS
620/* -------------- SiSInit -----------------*/
621/* TW: I degraded this for LINUXBIOS only, because we
622 *     don't need this otherwise
623 */
624BOOLEAN
625SiSInit(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
626{
627   UCHAR  *ROMAddr  = HwDeviceExtension->pjVirtualRomBase;
628   ULONG   FBAddr   = (ULONG)HwDeviceExtension->pjVideoMemoryAddress;
629   USHORT  BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
630   UCHAR   i, temp=0;
631   UCHAR   SR11;
632#ifdef LINUX_KERNEL
633   UCHAR   temp1;
634   ULONG   base;
635#endif
636   UCHAR   SR13=0, SR14=0, SR16=0
637   UCHAR   SR17=0, SR19=0, SR1A=0;
638#ifdef SIS300
639   UCHAR   SR18=0, SR12=0;
640#endif
641#ifdef SIS315H
642   UCHAR   CR37=0, CR38=0, CR79=0,
643   UCHAR   CR7A=0, CR7B=0, CR7C=0;
644   UCHAR   SR1B=0, SR15=0;
645   PSIS_DSReg pSR;
646   ULONG   Temp;
647#endif
648   UCHAR   VBIOSVersion[5];
649
650   if(FBAddr==0)    return (FALSE);
651   if(BaseAddr==0)  return (FALSE);
652
653   SiS_SetReg3((USHORT)(BaseAddr+0x12),  0x67);  /* Misc */
654
655#ifdef SIS315H
656   if(HwDeviceExtension->jChipType > SIS_315PRO) {
657     if(!HwDeviceExtension->bIntegratedMMEnabled)
658     	return (FALSE);
659   }
660#endif
661
662   SiS_MemoryCopy(VBIOSVersion,HwDeviceExtension->szVBIOSVer,4);
663   VBIOSVersion[4]= 0x00;
664
665   SiSDetermineROMUsage(SiS_Pr, HwDeviceExtension, ROMAddr);
666
667   /* TW: Init pointers */
668#ifdef SIS315H
669   if((HwDeviceExtension->jChipType == SIS_315H) ||
670      (HwDeviceExtension->jChipType == SIS_315PRO) ||
671      (HwDeviceExtension->jChipType == SIS_550) ||
672      (HwDeviceExtension->jChipType == SIS_640) ||
673      (HwDeviceExtension->jChipType == SIS_740) ||
674      (HwDeviceExtension->jChipType == SIS_650))
675     InitTo310Pointer(SiS_Pr, HwDeviceExtension);
676#endif
677
678#ifdef SIS300
679   if((HwDeviceExtension->jChipType == SIS_540) ||
680      (HwDeviceExtension->jChipType == SIS_630) ||
681      (HwDeviceExtension->jChipType == SIS_730) ||
682      (HwDeviceExtension->jChipType == SIS_300))
683     InitTo300Pointer(SiS_Pr, HwDeviceExtension);
684#endif
685
686   /* TW: Set SiS Register definitions */
687   SiSRegInit(SiS_Pr, BaseAddr);
688
689   /* TW: Determine LVDS/CH70xx/TRUMPION */
690   SiS_Set_LVDS_TRUMPION(SiS_Pr, HwDeviceExtension);
691
692   /* TW: Unlock registers */
693   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86);
694
695#ifdef LINUX_KERNEL
696
697#ifdef SIS300                                         	    /* Set SR14 */
698   if((HwDeviceExtension->jChipType==SIS_540) ||
699      (HwDeviceExtension->jChipType==SIS_630) ||
700      (HwDeviceExtension->jChipType==SIS_730)) {
701     base=0x80000060;
702     OutPortLong(base,0xcf8);
703     temp1 = InPortLong(0xcfc);
704     temp1 >>= (16+8+4);
705     temp1 &= 0x07;
706     temp1++;
707     temp1 = 1 << temp1;
708     SR14 = temp1 - 1;
709     base = 0x80000064;
710     OutPortLong(base,0xcf8);
711     temp1 = InPortLong(0xcfc);
712     temp1 &= 0x00000020;
713     if(temp1) 	SR14 |= 0x80;
714     else      	SR14 |= 0x40;
715   }
716#endif
717
718#ifdef SIS315H                                              /* Set SR14 */
719   if(HwDeviceExtension->jChipType==SIS_550) {
720     base = 0x80000060;
721     OutPortLong(base,0xcf8);
722     temp1 = InPortLong(0xcfc);
723     temp1 >>= (16+8+4);
724     temp1 &= 0x07;
725     temp1++;
726     temp1 = 1 << temp1;
727     SR14 = temp1 - 1;
728     base = 0x80000064;
729     OutPortLong(base,0xcf8);
730     temp1 = InPortLong(0xcfc);
731     temp1 &= 0x00000020;
732     if(temp1)  SR14 |= 0x80;
733     else       SR14 |= 0x40;
734   }
735
736   if((HwDeviceExtension->jChipType == SIS_640) ||      /* Set SR14 */
737      (HwDeviceExtension->jChipType == SIS_740) ||
738      (HwDeviceExtension->jChipType == SIS_650)) {
739     base = 0x80000064;
740     OutPortLong(base,0xcf8);
741     temp1=InPortLong(0xcfc);
742     temp1 >>= 4;
743     temp1 &= 0x07;
744     if(temp1 > 2) {
745       temp = temp1;
746       switch(temp) {
747        case 3: temp1 = 0x07;  break;
748        case 4: temp1 = 0x0F;  break;
749        case 5: temp1 = 0x1F;  break;
750        case 6: temp1 = 0x05;  break;
751        case 7: temp1 = 0x17;  break;
752        case 8: break;
753        case 9: break;
754       }
755     }
756     SR14 = temp1;
757     base = 0x8000007C;
758     OutPortLong(base,0xcf8);
759     temp1 = InPortLong(0xcfc);
760     temp1 &= 0x00000020;
761     if(temp1)  SR14 |= 0x80;
762   }
763#endif
764
765#endif  /* Linux kernel */
766
767#ifdef SIS300
768   if((HwDeviceExtension->jChipType == SIS_540)||
769      (HwDeviceExtension->jChipType == SIS_630)||
770      (HwDeviceExtension->jChipType == SIS_730)) {
771     SR12 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x12);
772     SR13 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13);
773     SR14 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
774     SR16 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16);
775     SR17 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17);
776     SR18 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x18);
777     SR19 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x19);
778     SR1A = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1A);
779   } else if(HwDeviceExtension->jChipType == SIS_300){
780     SR13 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13);
781     SR14 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
782   }
783#endif
784#ifdef SIS315H
785   if((HwDeviceExtension->jChipType == SIS_550) ||
786      (HwDeviceExtension->jChipType == SIS_640) ||
787      (HwDeviceExtension->jChipType == SIS_740) ||
788      (HwDeviceExtension->jChipType == SIS_650)) {
789     SR19 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x19);
790     SR19 = (SR19)||0x01;  /* TW: ??? || ??? */
791     if(SR19==0x00) {
792     	SR13 = 0x22;
793     	SR14 = 0x00;
794    	SR15 = 0x01;
795     	SR16 = 0x00;
796     	SR17 = 0x00;
797     	SR1A = 0x00;
798     	SR1B = 0x00;
799     	CR37 = 0x00;
800     	CR38 = 0x00;
801     	CR79 = 0x00;
802     	CR7A = 0x00;
803     	CR7B = 0x00;
804     	CR7C = 0x00;
805     } else {
806     	SR13 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13);
807     	SR14 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
808     	SR15 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x15);
809     	SR16 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16);
810     	SR17 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17);
811     	SR1A = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1A);
812     	SR1B = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1B);
813     	CR37 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37);  /* TW: Was 0x02 - why? */
814     	CR38 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
815     	CR79 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3d4,0x79);
816     	CR7A = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3d4,0x7A);
817     	CR7B = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3d4,0x7B);
818     	CR7C = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3d4,0x7C);
819     }
820   }
821#endif
822
823   /* Reset extended registers */
824
825   for(i=0x06; i< 0x20; i++) SiS_SetReg1(SiS_Pr->SiS_P3c4,i,0);
826   for(i=0x21; i<=0x27; i++) SiS_SetReg1(SiS_Pr->SiS_P3c4,i,0);
827   for(i=0x31; i<=0x3D; i++) SiS_SetReg1(SiS_Pr->SiS_P3c4,i,0);
828
829#ifdef SIS300
830   if((HwDeviceExtension->jChipType == SIS_540) ||
831      (HwDeviceExtension->jChipType == SIS_630) ||
832      (HwDeviceExtension->jChipType == SIS_730) ||
833      (HwDeviceExtension->jChipType == SIS_300)) {
834     	for(i=0x38; i<=0x3F; i++) SiS_SetReg1(SiS_Pr->SiS_P3d4,i,0);
835   }
836#endif
837
838#ifdef SIS315H
839   if((HwDeviceExtension->jChipType == SIS_315H) ||
840      (HwDeviceExtension->jChipType == SIS_315PRO) ||
841      (HwDeviceExtension->jChipType == SIS_550) ||
842      (HwDeviceExtension->jChipType == SIS_640) ||
843      (HwDeviceExtension->jChipType == SIS_740) ||
844      (HwDeviceExtension->jChipType == SIS_650)) {
845   	for(i=0x12; i<=0x1B; i++) SiS_SetReg1(SiS_Pr->SiS_P3c4,i,0);
846   	for(i=0x79; i<=0x7C; i++) SiS_SetReg1(SiS_Pr->SiS_P3d4,i,0);
847   }
848#endif
849
850   /* Restore Extended Registers */
851
852#ifdef SIS300
853   if((HwDeviceExtension->jChipType == SIS_540) ||
854      (HwDeviceExtension->jChipType == SIS_630) ||
855      (HwDeviceExtension->jChipType == SIS_730)) {
856     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x12,SR12);
857     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,SR13);
858     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,SR14);
859     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,SR16);
860     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x17,SR17);
861     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x18,SR18);
862     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x19,SR19);
863     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1A,SR1A);
864   }
865#endif
866
867#ifdef SIS315H
868   if((HwDeviceExtension->jChipType == SIS_550) ||
869      (HwDeviceExtension->jChipType == SIS_640) ||
870      (HwDeviceExtension->jChipType == SIS_740) ||
871      (HwDeviceExtension->jChipType == SIS_650)) {
872     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,SR13);
873     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,SR14);
874     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x15,SR15);
875     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,SR16);
876     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x17,SR17);
877     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x19,SR19);
878     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1A,SR1A);
879     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1B,SR1B);
880     SiS_SetReg1(SiS_Pr->SiS_P3d4,0x37,CR37);
881     SiS_SetReg1(SiS_Pr->SiS_P3d4,0x38,CR38);
882     SiS_SetReg1(SiS_Pr->SiS_P3d4,0x79,CR79);
883     SiS_SetReg1(SiS_Pr->SiS_P3d4,0x7A,CR7A);
884     SiS_SetReg1(SiS_Pr->SiS_P3d4,0x7B,CR7B);
885     SiS_SetReg1(SiS_Pr->SiS_P3d4,0x7C,CR7C);
886   }
887#endif
888
889#ifdef SIS300
890   if((HwDeviceExtension->jChipType==SIS_540) ||
891      (HwDeviceExtension->jChipType==SIS_630) ||
892      (HwDeviceExtension->jChipType==SIS_730)) {
893     	temp = (UCHAR)SR1A & 0x03;
894   } else if(HwDeviceExtension->jChipType==SIS_300) {
895        /* TW: Nothing */
896   }
897#endif
898#ifdef SIS315H
899   if((HwDeviceExtension->jChipType == SIS_315H )||
900      (HwDeviceExtension->jChipType == SIS_315PRO)) {
901      	if((*SiS_Pr->pSiS_SoftSetting & SoftDRAMType) == 0){
902          	temp = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x3A) & 0x03;
903        }
904   }
905   if((HwDeviceExtension->jChipType == SIS_550) ||
906      (HwDeviceExtension->jChipType == SIS_640) ||
907      (HwDeviceExtension->jChipType == SIS_740) ||
908      (HwDeviceExtension->jChipType == SIS_650)) {
909        if((*SiS_Pr->pSiS_SoftSetting & SoftDRAMType) == 0){
910          	temp = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x07;
911        }
912   }
913#endif
914
915   SiS_Pr->SiS_RAMType = temp;
916   SiS_SetMemoryClock(SiS_Pr, ROMAddr, HwDeviceExtension);
917
918   /* Set default register contents */
919
920   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x07,*SiS_Pr->pSiS_SR07); 		/* DAC speed */
921
922   if((HwDeviceExtension->jChipType != SIS_540) &&
923      (HwDeviceExtension->jChipType != SIS_630) &&
924      (HwDeviceExtension->jChipType != SIS_730)){
925     	for(i=0x15;i<0x1C;i++) {
926       	    SiS_SetReg1(SiS_Pr->SiS_P3c4,i,SiS_Pr->SiS_SR15[i-0x15][SiS_Pr->SiS_RAMType]);
927     	}
928   }
929
930#ifdef SIS315H
931   if ((HwDeviceExtension->jChipType == SIS_315H ) ||
932       (HwDeviceExtension->jChipType == SIS_315PRO)) {
933     	for(i=0x40;i<=0x44;i++) {
934       	    SiS_SetReg1(SiS_Pr->SiS_P3d4,i,SiS_Pr->SiS_CR40[i-0x40][SiS_Pr->SiS_RAMType]);
935     	}
936     	SiS_SetReg1(SiS_Pr->SiS_P3d4,0x48,0x23);
937     	SiS_SetReg1(SiS_Pr->SiS_P3d4,0x49,SiS_Pr->SiS_CR49[0]);
938    /*  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x25,SiS_Pr->SiS_SR25[0]);  */
939   }
940#endif
941
942   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1F,*SiS_Pr->pSiS_SR1F); 	/* DAC pedestal */
943   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x20,0xA0);
944   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x23,*SiS_Pr->pSiS_SR23);
945   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x24,*SiS_Pr->pSiS_SR24);
946   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x25,SiS_Pr->SiS_SR25[0]);
947
948#ifdef SIS300
949   if(HwDeviceExtension->jChipType == SIS_300) {
950     	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x21,0x84);
951     	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x22,0x00);
952   }
953#endif
954
955   SR11 = 0x0F;
956   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x11,SR11);		/* Power Management & DDC port */
957
958   SiS_UnLockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr);
959   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,0x00);
960   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x02,*SiS_Pr->pSiS_CRT2Data_1_2);
961
962#ifdef SIS315H
963   if((HwDeviceExtension->jChipType == SIS_315H) ||
964      (HwDeviceExtension->jChipType == SIS_315PRO) ||
965      (HwDeviceExtension->jChipType == SIS_550) ||
966      (HwDeviceExtension->jChipType == SIS_640) ||
967      (HwDeviceExtension->jChipType == SIS_740) ||
968      (HwDeviceExtension->jChipType == SIS_650))
969     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2E,0x08);    /* use VB */
970#endif
971
972   temp = *SiS_Pr->pSiS_SR32;
973   if(SiS_BridgeIsOn(SiS_Pr, BaseAddr)) {
974     	temp &= 0xEF;
975   }
976   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
977
978#ifdef SIS315H
979   if((HwDeviceExtension->jChipType == SIS_315H) ||
980      (HwDeviceExtension->jChipType == SIS_315PRO)) {
981     HwDeviceExtension->pQueryVGAConfigSpace(HwDeviceExtension,0x50,0,&Temp);
982     Temp >>= 20;
983     Temp &= 0xF;
984     if (Temp != 1) {
985     	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x25,SiS_Pr->SiS_SR25[1]);
986     	SiS_SetReg1(SiS_Pr->SiS_P3d4,0x49,SiS_Pr->SiS_CR49[1]);
987     }
988
989     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x27,0x1F);
990
991     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,*SiS_Pr->pSiS_SR31);
992     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,*SiS_Pr->pSiS_SR32);
993     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x33,*SiS_Pr->pSiS_SR33);
994   }
995#endif
996
997   if (SiS_BridgeIsOn(SiS_Pr, BaseAddr) == 0) {
998     	if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
999       		SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x00,0x1C);
1000       		SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0D,*SiS_Pr->pSiS_CRT2Data_4_D);
1001       		SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0E,*SiS_Pr->pSiS_CRT2Data_4_E);
1002       		SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x10,*SiS_Pr->pSiS_CRT2Data_4_10);
1003       		SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0F,0x3F);
1004     	}
1005     	SiS_LockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr);
1006   }
1007   SiS_SetReg1(SiS_Pr->SiS_P3d4,0x83,0x00);
1008
1009#ifdef SIS315H
1010   if ((HwDeviceExtension->jChipType==SIS_315H) ||
1011       (HwDeviceExtension->jChipType==SIS_315PRO)) {
1012       	if (HwDeviceExtension->bSkipDramSizing==TRUE) {
1013         	SiS_SetDRAMModeRegister(SiS_Pr, ROMAddr,HwDeviceExtension);
1014         	pSR = HwDeviceExtension->pSR;
1015         	if (pSR!=NULL) {
1016           		while (pSR->jIdx!=0xFF) {
1017             			SiS_SetReg1(SiS_Pr->SiS_P3c4,pSR->jIdx,pSR->jVal);
1018             			pSR++;
1019           		}
1020         	}
1021       } else SiS_SetDRAMSize_310(SiS_Pr, HwDeviceExtension);
1022   }
1023#endif
1024
1025#ifdef SIS315H
1026   if((HwDeviceExtension->jChipType==SIS_550)){
1027       /* SetDRAMConfig begin */
1028/*     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x12,SR12);
1029       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,SR13);
1030       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,SR14);
1031       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,SR16);
1032       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x17,SR17);
1033       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x18,SR18);
1034       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x19,SR19);
1035       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1A,SR1A);   */
1036       /* SetDRAMConfig end */
1037   }
1038#endif
1039
1040#ifdef SIS300
1041   if(HwDeviceExtension->jChipType == SIS_300) {
1042       	if (HwDeviceExtension->bSkipDramSizing == TRUE) {
1043/*       	SiS_SetDRAMModeRegister(ROMAddr,HwDeviceExtension);
1044         	temp = (HwDeviceExtension->pSR)->jVal;
1045         	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,temp);
1046         	temp = (HwDeviceExtension->pSR)->jVal;
1047         	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,temp);   */
1048       } else {
1049#ifdef TC
1050         	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,SR13);
1051         	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,SR14);
1052         	SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x15,0xFF,0x04);
1053#else
1054         	SiS_SetDRAMSize_300(SiS_Pr, HwDeviceExtension);
1055         	SiS_SetDRAMSize_300(SiS_Pr, HwDeviceExtension);
1056#endif
1057       }
1058   }
1059   if((HwDeviceExtension->jChipType==SIS_540)||
1060      (HwDeviceExtension->jChipType==SIS_630)||
1061      (HwDeviceExtension->jChipType==SIS_730)) {
1062   }
1063/* SetDRAMSize end */
1064#endif /* SIS300 */
1065
1066   /* Set default Ext2Regs */
1067   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x21,*SiS_Pr->pSiS_SR21);
1068   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x22,*SiS_Pr->pSiS_SR22);
1069
1070
1071#ifdef LINUXBIOS       /* TW: This is not needed for our purposes */
1072   SiS_DetectMonitor(SiS_Pr, HwDeviceExtension,BaseAddr);    /* Sense CRT1 */
1073   SiS_GetSenseStatus(SiS_Pr, HwDeviceExtension,ROMAddr);    /* Sense CRT2 */
1074#endif
1075
1076   return(TRUE);
1077}
1078
1079void
1080SiS_Set_LVDS_TRUMPION(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
1081{
1082  USHORT temp = 0;
1083
1084#ifdef SiS300
1085  if((HwDeviceExtension->jChipType == SIS_540) ||
1086     (HwDeviceExtension->jChipType == SIS_630) ||
1087     (HwDeviceExtension->jChipType == SIS_730)) {
1088        /* TW: Read POWER_ON_TRAP and copy to CR37 */
1089    	temp = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1A);
1090    	temp = (temp & 0xE0) >> 4;
1091   	SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x37,0xF1,temp);
1092  }
1093#endif
1094#ifdef SIS315H
1095  if((HwDeviceExtension->jChipType == SIS_640) ||
1096     (HwDeviceExtension->jChipType == SIS_740) ||
1097     (HwDeviceExtension->jChipType == SIS_650)) {
1098  }
1099#endif
1100
1101   SiSSetLVDSetc(SiS_Pr, HwDeviceExtension, 0);
1102}
1103
1104/* ===============  SiS 300 dram sizing begin  =============== */
1105#ifdef SIS300
1106void
1107SiS_SetDRAMSize_300(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
1108{
1109   ULONG   FBAddr = (ULONG)HwDeviceExtension->pjVideoMemoryAddress;
1110   USHORT  SR13, SR14=0, buswidth, Done;
1111   SHORT   i, j, k;
1112   USHORT  data, TotalCapacity, PhysicalAdrOtherPage=0;
1113   ULONG   Addr;
1114   UCHAR   temp;
1115   int     PseudoRankCapacity, PseudoTotalCapacity, PseudoAdrPinCount;
1116   int     RankCapacity, AdrPinCount, BankNumHigh, BankNumMid, MB2Bank;
1117   int     PageCapacity, PhysicalAdrHigh, PhysicalAdrHalfPage;
1118
1119   SiSSetMode(SiS_Pr, HwDeviceExtension, 0x2e);
1120
1121   SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x01,0x20);        /* Turn OFF Display  */
1122
1123   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,0x00);
1124   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,0xBF);
1125
1126   buswidth = SiS_ChkBUSWidth_300(SiS_Pr, FBAddr);
1127
1128   MB2Bank = 16;
1129   Done = 0;
1130   for(i=6; i>=0; i--) {
1131      if(Done == 1) break;
1132      PseudoRankCapacity = 1 << i;
1133      for(j=4; j>=1; j--) {
1134         if(Done == 1) break;
1135         PseudoTotalCapacity = PseudoRankCapacity * j;
1136         PseudoAdrPinCount = 15 - j;
1137         if(PseudoTotalCapacity <= 64) {
1138            for(k=0; k<=16; k++) {
1139               if(Done == 1) break;
1140               RankCapacity = buswidth * SiS_DRAMType[k][3];
1141               AdrPinCount = SiS_DRAMType[k][2] + SiS_DRAMType[k][0];
1142               if(RankCapacity == PseudoRankCapacity)
1143                 if(AdrPinCount <= PseudoAdrPinCount) {
1144                    if(j == 3) {             /* Rank No */
1145                       BankNumHigh = RankCapacity * MB2Bank * 3 - 1;
1146                       BankNumMid = RankCapacity * MB2Bank * 1 - 1;
1147                    } else {
1148                       BankNumHigh = RankCapacity * MB2Bank * j - 1;
1149                       BankNumMid = RankCapacity * MB2Bank * j / 2 - 1;
1150                    }
1151                    PageCapacity = (1 << SiS_DRAMType[k][1]) * buswidth * 4;
1152                    PhysicalAdrHigh = BankNumHigh;
1153                    PhysicalAdrHalfPage = (PageCapacity / 2 + PhysicalAdrHigh) % PageCapacity;
1154                    PhysicalAdrOtherPage = PageCapacity * SiS_DRAMType[k][2] + PhysicalAdrHigh;
1155                    /* Write data */
1156                    /*Test*/
1157                    SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x15,0xFB);
1158                    SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x15,0x04);
1159                    /*/Test*/
1160                    TotalCapacity = SiS_DRAMType[k][3] * buswidth;
1161                    SR13 = SiS_DRAMType[k][4];
1162                    if(buswidth == 4) SR14 = (TotalCapacity - 1) | 0x80;
1163                    if(buswidth == 2) SR14 = (TotalCapacity - 1) | 0x40;
1164                    if(buswidth == 1) SR14 = (TotalCapacity - 1) | 0x00;
1165                    SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,SR13);
1166                    SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,SR14);
1167
1168                    Addr = FBAddr + (BankNumHigh) * 64 * 1024 + PhysicalAdrHigh;
1169                    *((USHORT *)(Addr)) = (USHORT)PhysicalAdrHigh;
1170                    Addr = FBAddr + (BankNumMid) * 64 * 1024 + PhysicalAdrHigh;
1171                    *((USHORT *)(Addr)) = (USHORT)BankNumMid;
1172                    Addr = FBAddr + (BankNumHigh) * 64 * 1024 + PhysicalAdrHalfPage;
1173                    *((USHORT *)(Addr)) = (USHORT)PhysicalAdrHalfPage;
1174                    Addr = FBAddr + (BankNumHigh) * 64 * 1024 + PhysicalAdrOtherPage;
1175                    *((USHORT *)(Addr)) = PhysicalAdrOtherPage;
1176
1177                    /* Read data */
1178                    Addr = FBAddr + (BankNumHigh) * 64 * 1024 + PhysicalAdrHigh;
1179                    data = *((USHORT *)(Addr));
1180                    if(data == PhysicalAdrHigh) Done = 1;
1181                 }  /* if struct */
1182            }  /* for loop (k) */
1183         }  /* if struct */
1184      }  /* for loop (j) */
1185   }  /* for loop (i) */
1186}
1187
1188USHORT
1189SiS_ChkBUSWidth_300(SiS_Private *SiS_Pr, ULONG FBAddress)
1190{
1191   PULONG  pVideoMemory;
1192
1193   pVideoMemory = (PULONG)FBAddress;
1194
1195   pVideoMemory[0] = 0x01234567L;
1196   pVideoMemory[1] = 0x456789ABL;
1197   pVideoMemory[2] = 0x89ABCDEFL;
1198   pVideoMemory[3] = 0xCDEF0123L;
1199   if (pVideoMemory[3]==0xCDEF0123L) {  /* Channel A 128bit */
1200     return(4);
1201   }
1202   if (pVideoMemory[1]==0x456789ABL) {  /* Channel B 64bit */
1203     return(2);
1204   }
1205   return(1);
1206}
1207#endif
1208/* ===============  SiS 300 dram sizing end    =============== */
1209
1210/* ============  SiS 310/325 dram sizing begin  ============== */
1211#ifdef SIS315H
1212
1213/* TW: Moved Get310DRAMType further down */
1214
1215void
1216SiS_Delay15us(SiS_Private *SiS_Pr, ULONG ulMicrsoSec)
1217{
1218}
1219
1220void
1221SiS_SDR_MRS(SiS_Private *SiS_Pr, )
1222{
1223   USHORT  data;
1224
1225   data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16);
1226   data &= 0x3F;          		        /* SR16 D7=0, D6=0 */
1227   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,data);   	/* enable mode register set(MRS) low */
1228   SiS_Delay15us(SiS_Pr, 0x100);
1229   data |= 0x80;          		        /* SR16 D7=1, D6=0 */
1230   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,data);   	/* enable mode register set(MRS) high */
1231   SiS_Delay15us(SiS_Pr, 0x100);
1232}
1233
1234void
1235SiS_DDR_MRS(SiS_Private *SiS_Pr)
1236{
1237   USHORT  data;
1238
1239   /* SR16 <- 1F,DF,2F,AF */
1240
1241   /* enable DLL of DDR SD/SGRAM , SR16 D4=1 */
1242   data=SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16);
1243   data &= 0x0F;
1244   data |= 0x10;
1245   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,data);
1246
1247   if (!(SiS_Pr->SiS_SR15[1][SiS_Pr->SiS_RAMType] & 0x10))
1248     data &= 0x0F;
1249
1250   /* SR16 D7=1,D6=1 */
1251   data |= 0xC0;
1252   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,data);
1253
1254   /* SR16 D7=1,D6=0,D5=1,D4=0 */
1255   data &= 0x0F;
1256   data |= 0x20;
1257   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,data);
1258   if (!(SiS_Pr->SiS_SR15[1][SiS_Pr->SiS_RAMType] & 0x10))
1259     data &= 0x0F;
1260
1261   /* SR16 D7=1 */
1262   data |= 0x80;
1263   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,data);
1264}
1265
1266void
1267SiS_SetDRAMModeRegister(SiS_Private *SiS_Pr, UCHAR *ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
1268{
1269    if (SiS_Get310DRAMType(ROMAddr,HwDeviceExtension) < 2)
1270        SiS_SDR_MRS(SiS_Pr);
1271    else
1272        /* SR16 <- 0F,CF,0F,8F */
1273        SiS_DDR_MRS(SiS_Pr);
1274}
1275
1276void
1277SiS_DisableRefresh(SiS_Private *SiS_Pr)
1278{
1279   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x17,0xF8);
1280   SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x19,0x03);
1281}
1282
1283void
1284SiS_EnableRefresh(SiS_Private *SiS_Pr, UCHAR *ROMAddr)
1285{
1286   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x17,SiS_Pr->SiS_SR15[2][SiS_Pr->SiS_RAMType]);
1287   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x19,SiS_Pr->SiS_SR15[4][SiS_Pr->SiS_RAMType]);
1288}
1289
1290void
1291SiS_DisableChannelInterleaving(SiS_Private *SiS_Pr, int index,
1292                               USHORT SiS_DDRDRAM_TYPE[][5])
1293{
1294   USHORT  data;
1295
1296   data=SiS_GetReg1(SiS_Pr->SiS_P3c4,0x15);
1297   data &= 0x1F;
1298   switch (SiS_DDRDRAM_TYPE[index][3])
1299   {
1300     case 64: data |= 0; 	break;
1301     case 32: data |= 0x20;	break;
1302     case 16: data |= 0x40;     break;
1303     case 4:  data |= 0x60;     break;
1304   }
1305   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x15,data);
1306}
1307
1308void
1309SiS_SetDRAMSizingType(SiS_Private *SiS_Pr, int index, USHORT DRAMTYPE_TABLE[][5])
1310{
1311   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,DRAMTYPE_TABLE[index][4]);
1312   /* should delay 50 ns */
1313}
1314
1315void
1316SiS_CheckBusWidth_310(SiS_Private *SiS_Pr, UCHAR *ROMAddress,ULONG FBAddress,
1317                      PSIS_HW_DEVICE_INFO HwDeviceExtension)
1318{
1319   USHORT  data;
1320   PULONG volatile pVideoMemory;
1321
1322   pVideoMemory = (PULONG)FBAddress;
1323   if(SiS_Get310DRAMType(ROMAddress,HwDeviceExtension) < 2) {
1324
1325     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,0x00);
1326     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,0x12);
1327     /* should delay */
1328     SiS_SDR_MRS(SiS_Pr);
1329
1330     SiS_Pr->SiS_ChannelAB = 0;
1331     SiS_Pr->SiS_DataBusWidth = 128;
1332     pVideoMemory[0] = 0x01234567L;
1333     pVideoMemory[1] = 0x456789ABL;
1334     pVideoMemory[2] = 0x89ABCDEFL;
1335     pVideoMemory[3] = 0xCDEF0123L;
1336     pVideoMemory[4] = 0x55555555L;
1337     pVideoMemory[5] = 0x55555555L;
1338     pVideoMemory[6] = 0xFFFFFFFFL;
1339     pVideoMemory[7] = 0xFFFFFFFFL;
1340     if ((pVideoMemory[3]!=0xCDEF0123L) || (pVideoMemory[2] != 0x89ABCDEFL)) {
1341       /*Channel A 64Bit */
1342       SiS_Pr->SiS_DataBusWidth = 64;
1343       SiS_Pr->SiS_ChannelAB = 0;
1344       data=SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
1345       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,(USHORT)(data & 0xFD));
1346     }
1347
1348     if ((pVideoMemory[1]!=0x456789ABL) || (pVideoMemory[0] != 0x01234567L)) {
1349       /*Channel B 64Bit */
1350       SiS_Pr->SiS_DataBusWidth = 64;
1351       SiS_Pr->SiS_ChannelAB = 1;
1352       data=SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
1353       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,(USHORT)((data&0xFD)|0x01));
1354     }
1355     return;
1356
1357   } else {
1358     /* DDR Dual channel */
1359     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,0x00);
1360     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,0x02); /* Channel A, 64bit */
1361     /* should delay */
1362     SiS_DDR_MRS(SiS_Pr);
1363
1364     SiS_Pr->SiS_ChannelAB = 0;
1365     SiS_Pr->SiS_DataBusWidth = 64;
1366     pVideoMemory[0] = 0x01234567L;
1367     pVideoMemory[1] = 0x456789ABL;
1368     pVideoMemory[2] = 0x89ABCDEFL;
1369     pVideoMemory[3] = 0xCDEF0123L;
1370     pVideoMemory[4] = 0x55555555L;
1371     pVideoMemory[5] = 0x55555555L;
1372     pVideoMemory[6] = 0xAAAAAAAAL;
1373     pVideoMemory[7] = 0xAAAAAAAAL;
1374
1375     if (pVideoMemory[1] == 0x456789ABL) {
1376       if (pVideoMemory[0] == 0x01234567L) {
1377         /* Channel A 64bit */
1378         return;
1379       }
1380     } else {
1381       if (pVideoMemory[0] == 0x01234567L) {
1382         /* Channel A 32bit */
1383         SiS_Pr->SiS_DataBusWidth = 32;
1384         SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,0x00);
1385         return;
1386       }
1387     }
1388
1389     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,0x03); /* Channel B, 64bit */
1390     SiS_DDR_MRS(SiS_Pr);
1391
1392     SiS_Pr->SiS_ChannelAB = 1;
1393     SiS_Pr->SiS_DataBusWidth = 64;
1394     pVideoMemory[0] = 0x01234567L;
1395     pVideoMemory[1] = 0x456789ABL;
1396     pVideoMemory[2] = 0x89ABCDEFL;
1397     pVideoMemory[3] = 0xCDEF0123L;
1398     pVideoMemory[4] = 0x55555555L;
1399     pVideoMemory[5] = 0x55555555L;
1400     pVideoMemory[6] = 0xAAAAAAAAL;
1401     pVideoMemory[7] = 0xAAAAAAAAL;
1402     if (pVideoMemory[1] == 0x456789ABL) {
1403       /* Channel B 64 */
1404       if (pVideoMemory[0] == 0x01234567L) {
1405         /* Channel B 64bit */
1406         return;
1407       } else {
1408         /* error */
1409       }
1410     } else {
1411       if (pVideoMemory[0] == 0x01234567L) {
1412         /* Channel B 32 */
1413         SiS_Pr->SiS_DataBusWidth = 32;
1414         SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,0x01);
1415       } else {
1416         /* error */
1417       }
1418     }
1419   }
1420}
1421
1422int
1423SiS_SetRank(SiS_Private *SiS_Pr, int index,UCHAR RankNo,USHORT DRAMTYPE_TABLE[][5])
1424{
1425  USHORT  data;
1426  int RankSize;
1427
1428  if ((RankNo==2)&&(DRAMTYPE_TABLE[index][0]==2))
1429         return 0;
1430
1431  RankSize = DRAMTYPE_TABLE[index][3]/2 * SiS_Pr->SiS_DataBusWidth / 32;
1432
1433  if (RankNo * RankSize <= 128) {
1434    data = 0;
1435    while((RankSize >>= 1) > 0) {
1436      data += 0x10;
1437    }
1438    data |= (RankNo - 1) << 2;
1439    data |= (SiS_Pr->SiS_DataBusWidth / 64) & 2;
1440    data |= SiS_Pr->SiS_ChannelAB;
1441    SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,data);
1442    /* should delay */
1443    SiS_SDR_MRS(SiS_Pr);
1444    return 1;
1445  } else
1446    return 0;
1447}
1448
1449int
1450SiS_SetDDRChannel(SiS_Private *SiS_Pr, int index,UCHAR ChannelNo,
1451                  USHORT DRAMTYPE_TABLE[][5])
1452{
1453  USHORT  data;
1454  int RankSize;
1455
1456  RankSize = DRAMTYPE_TABLE[index][3]/2 * SiS_Pr->SiS_DataBusWidth / 32;
1457  /* RankSize = DRAMTYPE_TABLE[index][3]; */
1458  if (ChannelNo * RankSize <= 128) {
1459    data = 0;
1460    while((RankSize >>= 1) > 0) {
1461      data += 0x10;
1462    }
1463    if(ChannelNo == 2) data |= 0x0C;
1464    data |= (SiS_Pr->SiS_DataBusWidth / 32) & 2;
1465    data |= SiS_Pr->SiS_ChannelAB;
1466    SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,data);
1467    /* should delay */
1468    SiS_DDR_MRS(SiS_Pr);
1469    return 1;
1470  } else
1471    return 0;
1472}
1473
1474int
1475SiS_CheckColumn(SiS_Private *SiS_Pr, int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress)
1476{
1477  int i;
1478  ULONG Increment,Position;
1479
1480  /*Increment = 1<<(DRAMTYPE_TABLE[index][2] + SiS_Pr->SiS_DataBusWidth / 64 + 1); */
1481  Increment = 1 << (10 + SiS_Pr->SiS_DataBusWidth / 64);
1482
1483  for (i=0,Position=0;i<2;i++) {
1484         *((PULONG)(FBAddress + Position)) = Position;
1485         Position += Increment;
1486  }
1487
1488  for (i=0,Position=0;i<2;i++) {
1489/*    if (FBAddress[Position]!=Position) */
1490         if((*(PULONG)(FBAddress + Position)) != Position)
1491                return 0;
1492         Position += Increment;
1493  }
1494  return 1;
1495}
1496
1497int
1498SiS_CheckBanks(SiS_Private *SiS_Pr, int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress)
1499{
1500  int i;
1501  ULONG Increment,Position;
1502  Increment = 1 << (DRAMTYPE_TABLE[index][2] + SiS_Pr->SiS_DataBusWidth / 64 + 2);
1503
1504  for (i=0,Position=0;i<4;i++) {
1505/*    FBAddress[Position]=Position; */
1506    *((PULONG)(FBAddress + Position)) = Position;
1507    Position += Increment;
1508  }
1509
1510  for (i=0,Position=0;i<4;i++) {
1511/*    if (FBAddress[Position]!=Position) */
1512    if((*(PULONG)(FBAddress + Position)) != Position)
1513      return 0;
1514    Position += Increment;
1515  }
1516  return 1;
1517}
1518
1519int
1520SiS_CheckRank(SiS_Private *SiS_Pr, int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress)
1521{
1522  int i;
1523  ULONG Increment,Position;
1524  Increment = 1<<(DRAMTYPE_TABLE[index][2] + DRAMTYPE_TABLE[index][1] +
1525                  DRAMTYPE_TABLE[index][0] + SiS_Pr->SiS_DataBusWidth / 64 + RankNo);
1526
1527  for (i=0,Position=0;i<2;i++) {
1528/*    FBAddress[Position]=Position; */
1529    *((PULONG)(FBAddress+Position))=Position;
1530    /* *((PULONG)(FBAddress))=Position; */
1531    Position += Increment;
1532  }
1533
1534  for (i=0,Position=0;i<2;i++) {
1535/*    if (FBAddress[Position]!=Position) */
1536         if ( (*(PULONG) (FBAddress + Position)) !=Position)
1537    /*if ( (*(PULONG) (FBAddress )) !=Position) */
1538      return 0;
1539    Position += Increment;
1540  }
1541  return 1;
1542}
1543
1544int
1545SiS_CheckDDRRank(SiS_Private *SiS_Pr, int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress)
1546{
1547  ULONG Increment,Position;
1548  USHORT  data;
1549
1550  Increment = 1<<(DRAMTYPE_TABLE[index][2] + DRAMTYPE_TABLE[index][1] +
1551                  DRAMTYPE_TABLE[index][0] + SiS_Pr->SiS_DataBusWidth / 64 + RankNo);
1552
1553  Increment += Increment/2;
1554
1555  Position =0;
1556  *((PULONG)(FBAddress+Position + 0)) = 0x01234567;
1557  *((PULONG)(FBAddress+Position + 1)) = 0x456789AB;
1558  *((PULONG)(FBAddress+Position + 2)) = 0x55555555;
1559  *((PULONG)(FBAddress+Position + 3)) = 0x55555555;
1560  *((PULONG)(FBAddress+Position + 4)) = 0xAAAAAAAA;
1561  *((PULONG)(FBAddress+Position + 5)) = 0xAAAAAAAA;
1562
1563  if ( (*(PULONG) (FBAddress + 1)) == 0x456789AB)
1564    return 1;
1565
1566  if ( (*(PULONG) (FBAddress + 0)) == 0x01234567)
1567    return 0;
1568
1569  data=SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
1570  data &= 0xF3;
1571  data |= 0x08;
1572  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,data);
1573  data=SiS_GetReg1(SiS_Pr->SiS_P3c4,0x15);
1574  data += 0x20;
1575  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x15,data);
1576
1577  return 1;
1578}
1579
1580int
1581SiS_CheckRanks(SiS_Private *SiS_Pr, int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress)
1582{
1583  int r;
1584
1585  for (r=RankNo;r>=1;r--) {
1586    if (!SiS_CheckRank(SiS_Pr, r, index, DRAMTYPE_TABLE, FBAddress))
1587      return 0;
1588  }
1589  if (!SiS_CheckBanks(SiS_Pr, index, DRAMTYPE_TABLE, FBAddress))
1590    return 0;
1591
1592  if (!SiS_CheckColumn(SiS_Pr, index, DRAMTYPE_TABLE, FBAddress))
1593    return 0;
1594
1595  return 1;
1596}
1597
1598int
1599SiS_CheckDDRRanks(SiS_Private *SiS_Pr, int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],
1600                  ULONG FBAddress)
1601{
1602  int r;
1603
1604  for (r=RankNo;r>=1;r--) {
1605    if (!SiS_CheckDDRRank(SiS_Pr, r,index,DRAMTYPE_TABLE,FBAddress))
1606      return 0;
1607  }
1608  if (!SiS_CheckBanks(SiS_Pr, index,DRAMTYPE_TABLE,FBAddress))
1609    return 0;
1610
1611  if (!SiS_CheckColumn(SiS_Pr, index,DRAMTYPE_TABLE,FBAddress))
1612    return 0;
1613
1614  return 1;
1615}
1616
1617int
1618SiS_SDRSizing(SiS_Private *SiS_Pr, ULONG FBAddress)
1619{
1620  int    i;
1621  UCHAR  j;
1622
1623  for (i=0;i<13;i++) {
1624    SiS_SetDRAMSizingType(SiS_Pr, i, SiS_SDRDRAM_TYPE);
1625    for (j=2;j>0;j--) {
1626      if (!SiS_SetRank(SiS_Pr, i,(UCHAR) j, SiS_SDRDRAM_TYPE))
1627        continue;
1628      else {
1629        if (SiS_CheckRanks(SiS_Pr, j,i,SiS_SDRDRAM_TYPE, FBAddress))
1630          return 1;
1631      }
1632    }
1633  }
1634  return 0;
1635}
1636
1637int
1638SiS_DDRSizing(SiS_Private *SiS_Pr, ULONG FBAddress)
1639{
1640
1641  int    i;
1642  UCHAR  j;
1643
1644  for (i=0; i<4; i++){
1645    SiS_SetDRAMSizingType(SiS_Pr, i, SiS_DDRDRAM_TYPE);
1646    SiS_DisableChannelInterleaving(SiS_Pr, i, SiS_DDRDRAM_TYPE);
1647    for (j=2; j>0; j--) {
1648      SiS_SetDDRChannel(SiS_Pr, i, j, SiS_DDRDRAM_TYPE);
1649      if (!SiS_SetRank(SiS_Pr, i, (UCHAR) j, SiS_DDRDRAM_TYPE))
1650        continue;
1651      else {
1652        if (SiS_CheckDDRRanks(SiS_Pr, j, i, SiS_DDRDRAM_TYPE, FBAddress))
1653          return 1;
1654      }
1655    }
1656  }
1657  return 0;
1658}
1659
1660/*
1661 check if read cache pointer is correct
1662*/
1663void
1664SiS_VerifyMclk(SiS_Private *SiS_Pr, ULONG FBAddr)
1665{
1666   PUCHAR  pVideoMemory = (PUCHAR) FBAddr;
1667   UCHAR   i, j;
1668   USHORT  Temp,SR21;
1669
1670   pVideoMemory[0] = 0xaa;  /* alan */
1671   pVideoMemory[16] = 0x55; /* note: PCI read cache is off */
1672
1673   if((pVideoMemory[0] != 0xaa) || (pVideoMemory[16] != 0x55)) {
1674     for (i=0,j=16; i<2; i++,j+=16)  {
1675       SR21 = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x21);
1676       Temp = SR21 & 0xFB;           /* disable PCI post write buffer empty gating */
1677       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x21,Temp);
1678
1679       Temp = SiS_GetReg1(SiS_Pr->SiS_P3c4, 0x3C);
1680       Temp |= 0x01;                 /* MCLK reset */
1681       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x3C,Temp);
1682       Temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x3C);
1683       Temp &= 0xFE;                 /* MCLK normal operation */
1684       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x3C,Temp);
1685       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x21,SR21);
1686
1687       pVideoMemory[16+j] = j;
1688       if(pVideoMemory[16+j] == j) {
1689         pVideoMemory[j] = j;
1690         break;
1691       }
1692     }
1693   }
1694}
1695
1696/* TW: Is this a 315E? */
1697int
1698Is315E(SiS_Private *SiS_Pr)
1699{
1700   USHORT  data;
1701
1702   data = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5F);
1703   if(data & 0x10) return 1;
1704   else return 0;
1705}
1706
1707/* TW: For 315 only */
1708void
1709SiS_SetDRAMSize_310(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
1710{
1711   UCHAR  *ROMAddr  = HwDeviceExtension->pjVirtualRomBase;
1712   ULONG   FBAddr   = (ULONG)HwDeviceExtension->pjVideoMemoryAddress;
1713   USHORT  data;
1714
1715#ifdef SIS301	    /* TW: SIS301 ??? */
1716   /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x30,0x40);   */
1717#endif
1718#ifdef SIS302       /* TW: SIS302 ??? */
1719   SiS_SetReg1(SiS_Pr->SiS_P3d4,0x30,0x4D);  /* alan,should change value */
1720   SiS_SetReg1(SiS_Pr->SiS_P3d4,0x31,0xc0);  /* alan,should change value */
1721   SiS_SetReg1(SiS_Pr->SiS_P3d4,0x34,0x3F);  /* alan,should change value */
1722#endif
1723
1724   SiSSetMode(SiS_Pr, HwDeviceExtension, 0x2e);
1725
1726   data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x21);
1727   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x21,0xDF);                 /* disable read cache */
1728
1729   SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x01,0x20);                  /* Turn OFF Display */
1730
1731   SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x16,0x0F);                  /* assume lowest speed DRAM */
1732
1733   SiS_SetDRAMModeRegister(SiS_Pr, ROMAddr, HwDeviceExtension);
1734   SiS_DisableRefresh(SiS_Pr);
1735   SiS_CheckBusWidth_310(SiS_Pr, ROMAddr, FBAddr, HwDeviceExtension);
1736
1737   SiS_VerifyMclk(SiS_Pr, FBAddr);
1738
1739   if(SiS_Get310DRAMType(SiS_Pr, ROMAddr, HwDeviceExtension) < 2)
1740     SiS_SDRSizing(SiS_Pr, FBAddr);
1741   else
1742     SiS_DDRSizing(SiS_Pr, FBAddr);
1743
1744   if(Is315E(SiS_Pr)) {
1745     data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
1746     if((data & 0x0C) == 0x0C) { 	/* dual channel */
1747     	if((data & 0xF0) > 0x40)
1748     	  data = (data & 0x0F) | 0x40;
1749     } else { 				/* single channel */
1750     	if((data & 0xF0) > 0x50)
1751     	  data = (data & 0x0F) | 0x50;
1752     }
1753   }
1754
1755   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,SiS_Pr->SiS_SR15[1][SiS_Pr->SiS_RAMType]);  /* restore SR16 */
1756
1757   SiS_EnableRefresh(SiS_Pr, ROMAddr);
1758   SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x21,0x20);      	/* enable read cache */
1759}
1760#endif
1761
1762void
1763SiS_SetMemoryClock(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension)
1764{
1765   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x28,SiS_Pr->SiS_MCLKData_0[SiS_Pr->SiS_RAMType].SR28);
1766   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x29,SiS_Pr->SiS_MCLKData_0[SiS_Pr->SiS_RAMType].SR29);
1767   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2A,SiS_Pr->SiS_MCLKData_0[SiS_Pr->SiS_RAMType].SR2A);
1768   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2E,SiS_Pr->SiS_ECLKData[SiS_Pr->SiS_RAMType].SR2E);
1769   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2F,SiS_Pr->SiS_ECLKData[SiS_Pr->SiS_RAMType].SR2F);
1770   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x30,SiS_Pr->SiS_ECLKData[SiS_Pr->SiS_RAMType].SR30);
1771
1772#ifdef SIS315H
1773   if (Is315E(SiS_Pr)) {
1774     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x28,0x3B); /* 143 */
1775     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x29,0x22);
1776     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2E,0x3B); /* 143 */
1777     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2F,0x22);
1778   }
1779#endif
1780}
1781
1782#endif /* ifdef LINUXBIOS */
1783
1784#ifdef SIS315H
1785UCHAR
1786SiS_Get310DRAMType(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension)
1787{
1788   UCHAR   data;
1789
1790   if(*SiS_Pr->pSiS_SoftSetting & SoftDRAMType) {
1791     data = *SiS_Pr->pSiS_SoftSetting & 0x03;
1792   } else {
1793     if(HwDeviceExtension->jChipType > SIS_315PRO) {
1794        data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x07;
1795     } else {	/* TW: 315 */
1796        data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x3a) & 0x03;
1797     }
1798   }
1799
1800   return data;
1801}
1802#endif
1803
1804/* SiSInit END */
1805
1806/* ----------------------------------------- */
1807
1808void SiSRegInit(SiS_Private *SiS_Pr, USHORT BaseAddr)
1809{
1810   SiS_Pr->SiS_P3c4 = BaseAddr + 0x14;
1811   SiS_Pr->SiS_P3d4 = BaseAddr + 0x24;
1812   SiS_Pr->SiS_P3c0 = BaseAddr + 0x10;
1813   SiS_Pr->SiS_P3ce = BaseAddr + 0x1e;
1814   SiS_Pr->SiS_P3c2 = BaseAddr + 0x12;
1815   SiS_Pr->SiS_P3ca = BaseAddr + 0x1a;
1816   SiS_Pr->SiS_P3c6 = BaseAddr + 0x16;
1817   SiS_Pr->SiS_P3c7 = BaseAddr + 0x17;
1818   SiS_Pr->SiS_P3c8 = BaseAddr + 0x18;
1819   SiS_Pr->SiS_P3c9 = BaseAddr + 0x19;
1820   SiS_Pr->SiS_P3da = BaseAddr + 0x2A;
1821   SiS_Pr->SiS_Part1Port = BaseAddr + SIS_CRT2_PORT_04;   /* Digital video interface registers (LCD) */
1822   SiS_Pr->SiS_Part2Port = BaseAddr + SIS_CRT2_PORT_10;   /* 301 TV Encoder registers */
1823   SiS_Pr->SiS_Part3Port = BaseAddr + SIS_CRT2_PORT_12;   /* 301 Macrovision registers */
1824   SiS_Pr->SiS_Part4Port = BaseAddr + SIS_CRT2_PORT_14;   /* 301 VGA2 (and LCD) registers */
1825   SiS_Pr->SiS_Part5Port = BaseAddr + SIS_CRT2_PORT_14+2; /* 301 palette address port registers */
1826   SiS_Pr->SiS_DDC_Port = BaseAddr + 0x14;                /* DDC Port ( = P3C4, SR11/0A) */
1827}
1828
1829void
1830SiSInitPCIetc(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
1831{
1832/* #ifdef LINUX_XF86 */
1833   if ((HwDeviceExtension->jChipType == SIS_540)||
1834       (HwDeviceExtension->jChipType == SIS_630)||
1835       (HwDeviceExtension->jChipType == SIS_730)||
1836       (HwDeviceExtension->jChipType == SIS_300)) {
1837       /* TW: Set - PCI LINEAR ADDRESSING ENABLE (0x80)
1838		  - PCI IO ENABLE  (0x20)
1839		  - MMIO ENABLE (0x1)
1840  	*/
1841       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x20,0xa1);
1842       /* TW: Enable 2D (0x42) & 3D accelerator (0x18) */
1843       SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1E,0xFF,0x5A);
1844   }
1845   if((HwDeviceExtension->jChipType == SIS_315H)||
1846      (HwDeviceExtension->jChipType == SIS_315PRO)||
1847      (HwDeviceExtension->jChipType == SIS_550)||
1848      (HwDeviceExtension->jChipType == SIS_640)||
1849      (HwDeviceExtension->jChipType == SIS_740)||
1850      (HwDeviceExtension->jChipType == SIS_650)) {
1851      /* TW: This seems to be done the same way on these chipsets */
1852      SiS_SetReg1(SiS_Pr->SiS_P3c4,0x20,0xa1);
1853      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1E,0xFF,0x5A);
1854   }
1855/* #endif */
1856}
1857
1858void
1859SiSSetLVDSetc(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo)
1860{
1861   ULONG   temp;
1862
1863   SiS_Pr->SiS_IF_DEF_LVDS = 0;
1864   SiS_Pr->SiS_IF_DEF_TRUMPION = 0;
1865   SiS_Pr->SiS_IF_DEF_CH70xx = 0;
1866   SiS_Pr->SiS_IF_DEF_HiVision = 0;
1867   SiS_Pr->SiS_IF_DEF_DSTN = 0;
1868   SiS_Pr->SiS_IF_DEF_FSTN = 0;
1869
1870   SiS_Pr->SiS_ChrontelInit = 0;
1871
1872   if((ModeNo == 0x5a) || (ModeNo == 0x5b)) {
1873   	SiS_Pr->SiS_IF_DEF_DSTN = 1;   /* for 550 dstn */
1874   	SiS_Pr->SiS_IF_DEF_FSTN = 1;   /* for fstn */
1875   }
1876
1877#ifdef SIS300
1878   if((HwDeviceExtension->jChipType == SIS_540) ||
1879      (HwDeviceExtension->jChipType == SIS_630) ||
1880      (HwDeviceExtension->jChipType == SIS_730))
1881    {
1882        /* TW: Check for SiS30x first */
1883        temp = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x00);
1884	if((temp == 1) || (temp == 2)) return;
1885      	temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37);
1886      	temp = (temp & 0x0E) >> 1;
1887      	if((temp >= 2) && (temp <= 5)) SiS_Pr->SiS_IF_DEF_LVDS = 1;
1888      	if(temp == 3)   SiS_Pr->SiS_IF_DEF_TRUMPION = 1;
1889      	if((temp == 4) || (temp == 5)) {
1890		/* TW: Save power status (and error check) */
1891		SiS_Pr->SiS_Backup70xx = SiS_GetCH700x(SiS_Pr, 0x0e);
1892		SiS_Pr->SiS_IF_DEF_CH70xx = 1;
1893        }
1894   }
1895#endif
1896#ifdef SIS315H
1897   if((HwDeviceExtension->jChipType == SIS_550) ||
1898      (HwDeviceExtension->jChipType == SIS_640) ||
1899      (HwDeviceExtension->jChipType == SIS_740) ||
1900      (HwDeviceExtension->jChipType == SIS_650))
1901    {
1902        /* TW: CR37 is different on 310/325 series */
1903        if (SiS_Pr->SiS_IF_DEF_FSTN)                       /* fstn: set CR37=0x04 */
1904             SiS_SetReg1(SiS_Pr->SiS_P3d4,0x37,0x04);      /* (fake LVDS bridge) */
1905
1906	temp=SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37);
1907      	temp = (temp & 0x0E) >> 1;
1908      	if((temp >= 2) && (temp <= 3)) SiS_Pr->SiS_IF_DEF_LVDS = 1;
1909      	if(temp == 3)  {
1910			SiS_Pr->SiS_IF_DEF_CH70xx = 2;
1911        }
1912	/* SiS_Pr->SiS_IF_DEF_HiVision = 1; */
1913    }
1914#endif
1915}
1916
1917void
1918SiSInitPtr(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
1919{
1920#ifdef SIS315H
1921   if((HwDeviceExtension->jChipType == SIS_315H) ||
1922      (HwDeviceExtension->jChipType == SIS_315PRO) ||
1923      (HwDeviceExtension->jChipType == SIS_550) ||
1924      (HwDeviceExtension->jChipType == SIS_640) ||
1925      (HwDeviceExtension->jChipType == SIS_740) ||
1926      (HwDeviceExtension->jChipType == SIS_650))
1927     InitTo310Pointer(SiS_Pr, HwDeviceExtension);
1928#endif
1929
1930#ifdef SIS300
1931   if ((HwDeviceExtension->jChipType == SIS_540) ||
1932       (HwDeviceExtension->jChipType == SIS_630) ||
1933       (HwDeviceExtension->jChipType == SIS_730) ||
1934       (HwDeviceExtension->jChipType == SIS_300))
1935     InitTo300Pointer(SiS_Pr, HwDeviceExtension);
1936#endif
1937}
1938
1939void
1940SiSDetermineROMUsage(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, UCHAR *ROMAddr)
1941{
1942   if((ROMAddr) && (HwDeviceExtension->UseROM)) {
1943     if((ROMAddr[0x00] != 0x55) || (ROMAddr[0x01] != 0xAA)) {
1944        SiS_Pr->SiS_UseROM = FALSE;
1945     } else if(HwDeviceExtension->jChipType < SIS_315H) {
1946        /* TW: We don't use the ROM image if BIOS version < 2.0.0 as
1947         *     such old BIOSes don't have the needed data at the
1948	 *     expected locations
1949	 */
1950        if(ROMAddr[0x06] < '2')  SiS_Pr->SiS_UseROM = FALSE;
1951	else                     SiS_Pr->SiS_UseROM = TRUE;
1952     } else {
1953        /* TW: TODO: Check this for 310/325 series */
1954	SiS_Pr->SiS_UseROM = TRUE;
1955     }
1956   } else SiS_Pr->SiS_UseROM = FALSE;
1957
1958}
1959
1960/*
1961 	=========================================
1962 	======== SiS SetMode Functions ==========
1963 	=========================================
1964*/
1965#ifdef LINUX_XF86
1966/* TW: This is used for non-Dual-Head mode from X */
1967BOOLEAN
1968SiSBIOSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, ScrnInfoPtr pScrn,
1969               DisplayModePtr mode)
1970{
1971   UShort  ModeNo=0;
1972
1973   ModeNo = SiS_CalcModeIndex(pScrn, mode);
1974   if(!ModeNo) return FALSE;
1975
1976   xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting mode 0x%x\n", ModeNo);
1977
1978   return(SiSSetMode(SiS_Pr, HwDeviceExtension, pScrn, ModeNo, TRUE));
1979}
1980
1981#ifdef SISDUALHEAD
1982/* TW: Set CRT1 mode (used for dual head) */
1983BOOLEAN
1984SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, ScrnInfoPtr pScrn,
1985               DisplayModePtr mode)
1986{
1987   ULONG   temp;
1988   USHORT  ModeIdIndex;
1989   UCHAR  *ROMAddr  = HwDeviceExtension->pjVirtualRomBase;
1990   USHORT  BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
1991   SISPtr  pSiS = SISPTR(pScrn);
1992   SISEntPtr pSiSEnt = pSiS->entityPrivate;
1993
1994   UShort  ModeNo=0;
1995
1996   ModeNo = SiS_CalcModeIndex(pScrn, mode);
1997   if(!ModeNo) return FALSE;
1998
1999   xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting mode 0x%x on CRT1\n", ModeNo);
2000
2001   SiSInitPtr(SiS_Pr, HwDeviceExtension);
2002
2003   SiSRegInit(SiS_Pr, BaseAddr);
2004
2005   SiS_Pr->SiS_VGAINFO = SiS_GetSetMMIOReg(pScrn, 0x489, 0xff);
2006
2007   SiSInitPCIetc(SiS_Pr, HwDeviceExtension);
2008
2009   SiSSetLVDSetc(SiS_Pr, HwDeviceExtension, ModeNo);
2010
2011   SiSDetermineROMUsage(SiS_Pr, HwDeviceExtension, ROMAddr);
2012
2013   /* TW: We don't clear the buffer under X */
2014   SiS_Pr->SiS_flag_clearbuffer=0;
2015
2016   /* 1.Openkey */
2017   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86);
2018
2019   SiS_UnLockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr);
2020
2021   /* 2.Get ModeID Table  */
2022   temp = SiS_SearchModeID(SiS_Pr, ROMAddr,&ModeNo,&ModeIdIndex);
2023   if(temp == 0)  return(0);
2024
2025   /* TW: Determine VBType (301,301B,301LV,302B,302LV) */
2026   SiS_GetVBType(SiS_Pr, BaseAddr,HwDeviceExtension);
2027
2028   /* TW: Get VB information (connectors, connected devices) */
2029   SiS_GetVBInfo(SiS_Pr, BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
2030   SiS_SetHiVision(SiS_Pr, BaseAddr,HwDeviceExtension);
2031   SiS_GetLCDResInfo(SiS_Pr, ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
2032
2033   /* TW: I am not sure the flag's name is correct */
2034   if(HwDeviceExtension->jChipType >= SIS_315H) {
2035      if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x08)  {
2036          if(ModeNo != 0x10)  SiS_Pr->SiS_SetFlag |= CRT2IsVGA;
2037      }
2038   }
2039
2040   /* TW: Set mode on CRT1 */
2041   SiS_SetCRT1Group(SiS_Pr, ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex,BaseAddr);
2042
2043   pSiSEnt->CRT1ModeNo = ModeNo;
2044   pSiSEnt->CRT1DMode = mode;
2045
2046   /* TW: SetPitch: Adapt to virtual size & position */
2047   if(ModeNo > 0x13) {
2048      SiS_SetPitchCRT1(SiS_Pr, pScrn, BaseAddr);
2049   }
2050
2051   /* We have to reset CRT2 if changing mode on CRT1 */
2052   if(pSiSEnt->CRT2ModeNo != -1) {
2053        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "(Re-)Setting mode 0x%x on CRT2\n",
2054				pSiSEnt->CRT2ModeNo);
2055	SiSBIOSSetModeCRT2(SiS_Pr, HwDeviceExtension, pSiSEnt->pScrn_1,
2056				pSiSEnt->CRT2DMode);
2057   }
2058
2059   if((HwDeviceExtension->jChipType > SIS_315PRO) && (SiS_Pr->SiS_IF_DEF_LVDS == 0)) {
2060      /* TW: *** For 650 only! *** */
2061      SiS_HandleCRT1(SiS_Pr);
2062   }
2063
2064   SiS_DisplayOn(SiS_Pr);
2065   SiS_SetReg3(SiS_Pr->SiS_P3c6,0xFF);
2066
2067   if((HwDeviceExtension->jChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 0)) {
2068      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
2069          SiS_Handle301B_1400x1050(SiS_Pr, ModeNo);
2070      }
2071   }
2072
2073   /* Backup/Set ModeNo in MMIO */
2074   SiS_GetSetModeID(pScrn,ModeNo);
2075
2076   return TRUE;
2077}
2078
2079/* TW: Set CRT2 mode (used for dual head) */
2080BOOLEAN
2081SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, ScrnInfoPtr pScrn,
2082               DisplayModePtr mode)
2083{
2084   ULONG   temp;
2085   USHORT  ModeIdIndex;
2086   UCHAR  *ROMAddr  = HwDeviceExtension->pjVirtualRomBase;
2087   USHORT  BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
2088   UShort  ModeNo   = 0;
2089   SISPtr  pSiS     = SISPTR(pScrn);
2090   SISEntPtr pSiSEnt = pSiS->entityPrivate;
2091
2092   ModeNo = SiS_CalcModeIndex(pScrn, mode);
2093   if(!ModeNo) return FALSE;
2094
2095   SiSInitPtr(SiS_Pr, HwDeviceExtension);
2096
2097   SiSRegInit(SiS_Pr, BaseAddr);
2098
2099   SiS_Pr->SiS_VGAINFO = SiS_GetSetMMIOReg(pScrn, 0x489, 0xff);
2100
2101   SiSInitPCIetc(SiS_Pr, HwDeviceExtension);
2102
2103   SiSSetLVDSetc(SiS_Pr, HwDeviceExtension, ModeNo);
2104
2105   SiSDetermineROMUsage(SiS_Pr, HwDeviceExtension, ROMAddr);
2106
2107   /* TW: We don't clear the buffer under X */
2108   SiS_Pr->SiS_flag_clearbuffer=0;
2109
2110   /* TW: Save ModeNo so we can set it from within SetMode for CRT1 */
2111   pSiSEnt->CRT2ModeNo = ModeNo;
2112   pSiSEnt->CRT2DMode = mode;
2113
2114   /* TW: We can't set CRT2 mode before CRT1 mode is set */
2115   if(pSiSEnt->CRT1ModeNo == -1) {
2116   	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2117		"Setting CRT2 mode delayed until after setting CRT1 mode\n");
2118   	return TRUE;
2119   }
2120
2121   xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting mode 0x%x on CRT2\n", ModeNo);
2122
2123   /* 1.Openkey */
2124   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86);
2125
2126   SiS_UnLockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr);
2127
2128   /* 2.Get ModeID */
2129   temp = SiS_SearchModeID(SiS_Pr, ROMAddr,&ModeNo,&ModeIdIndex);
2130   if(temp == 0)  return(0);
2131
2132   /* TW: Determine VBType (301,301B,301LV,302B,302LV) */
2133   SiS_GetVBType(SiS_Pr, BaseAddr,HwDeviceExtension);
2134
2135   /* TW: Get VB information (connectors, connected devices) */
2136   SiS_GetVBInfo(SiS_Pr, BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
2137   SiS_SetHiVision(SiS_Pr, BaseAddr,HwDeviceExtension);
2138   SiS_GetLCDResInfo(SiS_Pr, ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
2139
2140   if(HwDeviceExtension->jChipType >= SIS_315H) {
2141      if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x08)  {
2142          /* TW: I am not sure the flag's name is correct */
2143          if(ModeNo != 0x10)  SiS_Pr->SiS_SetFlag |= CRT2IsVGA;
2144      }
2145   }
2146
2147   /* Set mode on CRT2 */
2148   switch (HwDeviceExtension->ujVBChipID) {
2149     case VB_CHIP_301:
2150     case VB_CHIP_301B:
2151     case VB_CHIP_301LV:
2152     case VB_CHIP_301LVX:
2153     case VB_CHIP_302:
2154     case VB_CHIP_302B:
2155     case VB_CHIP_302LV:
2156     case VB_CHIP_302LVX:
2157        SiS_SetCRT2Group301(SiS_Pr, BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
2158        break;
2159     case VB_CHIP_303:
2160        break;
2161     case VB_CHIP_UNKNOWN:
2162        if (SiS_Pr->SiS_IF_DEF_LVDS == 1 || SiS_Pr->SiS_IF_DEF_CH70xx == 1 ||
2163	                                               SiS_Pr->SiS_IF_DEF_TRUMPION != 0)
2164             	SiS_SetCRT2Group301(SiS_Pr,BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
2165        break;
2166   }
2167
2168   SiS_DisplayOn(SiS_Pr);
2169   SiS_SetReg3(SiS_Pr->SiS_P3c6,0xFF);
2170
2171   if((HwDeviceExtension->jChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 0)) {
2172      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
2173          SiS_Handle301B_1400x1050(SiS_Pr, ModeNo);
2174      }
2175   }
2176
2177   /* TW: SetPitch: Adapt to virtual size & position */
2178   if(ModeNo > 0x13) {
2179       SiS_SetPitchCRT2(SiS_Pr, pScrn, BaseAddr);
2180   }
2181
2182   return TRUE;
2183}
2184#endif /* Dualhead */
2185#endif /* Linux_XF86 */
2186
2187#ifdef LINUX_XF86
2188/* TW: We need pScrn for setting the pitch correctly */
2189BOOLEAN
2190SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,ScrnInfoPtr pScrn,USHORT ModeNo, BOOLEAN dosetpitch)
2191#else
2192BOOLEAN
2193SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo)
2194#endif
2195{
2196   ULONG   temp;
2197   USHORT  ModeIdIndex,KeepLockReg;
2198   UCHAR  *ROMAddr  = HwDeviceExtension->pjVirtualRomBase;
2199   USHORT  BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
2200
2201   SiSInitPtr(SiS_Pr, HwDeviceExtension);
2202
2203   SiSRegInit(SiS_Pr, BaseAddr);
2204
2205#ifdef LINUX_XF86
2206   if(pScrn) SiS_Pr->SiS_VGAINFO = SiS_GetSetMMIOReg(pScrn, 0x489, 0xff);
2207   else
2208#endif
2209         SiS_Pr->SiS_VGAINFO = 0x11;
2210
2211   SiSInitPCIetc(SiS_Pr, HwDeviceExtension);
2212
2213   SiSSetLVDSetc(SiS_Pr, HwDeviceExtension, ModeNo);
2214
2215   SiSDetermineROMUsage(SiS_Pr, HwDeviceExtension, ROMAddr);
2216
2217   /* TW: Shift the clear-buffer-bit away */
2218   ModeNo = ((ModeNo & 0x80) << 8) | (ModeNo & 0x7f);
2219
2220#ifdef LINUX_XF86
2221   /* TW: We never clear the buffer in X */
2222   ModeNo |= 0x8000;
2223#endif
2224
2225   if(ModeNo & 0x8000) {
2226     	ModeNo &= 0x007F;
2227     	SiS_Pr->SiS_flag_clearbuffer = 0;
2228   } else {
2229     	SiS_Pr->SiS_flag_clearbuffer = 1;
2230   }
2231
2232   /* 1.Openkey */
2233   KeepLockReg = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x05);
2234   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86);
2235
2236   SiS_UnLockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr);
2237
2238   /* 2.Get ModeID Table  */
2239   temp = SiS_SearchModeID(SiS_Pr,ROMAddr,&ModeNo,&ModeIdIndex);
2240   if(temp == 0) return(0);
2241
2242   /* TW: Determine VBType (301,301B,301LV,302B,302LV) */
2243   SiS_GetVBType(SiS_Pr,BaseAddr,HwDeviceExtension);
2244
2245   /* TW: Init/restore some VB registers */
2246   if(HwDeviceExtension->jChipType >= SIS_315H) {
2247      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
2248         if(ROMAddr && SiS_Pr->SiS_UseROM) {
2249           temp = ROMAddr[VB310Data_1_2_Offset];
2250	   temp |= 0x40;
2251           SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x02,temp);
2252	   SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x32,0x10);
2253         }
2254      }
2255   }
2256
2257   /* TW: Get VB information (connectors, connected devices) */
2258   SiS_GetVBInfo(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
2259   SiS_SetHiVision(SiS_Pr,BaseAddr,HwDeviceExtension);
2260   SiS_GetLCDResInfo(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
2261
2262   /* 3. Check memory size */
2263   temp = SiS_CheckMemorySize(SiS_Pr,ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex);
2264   if(!temp) return(0);
2265
2266   if(HwDeviceExtension->jChipType >= SIS_315H) {
2267      if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x08)  {
2268          /* TW: I am not sure the flag's name is correct */
2269          if(ModeNo != 0x10)  SiS_Pr->SiS_SetFlag |= CRT2IsVGA;
2270      }
2271   }
2272
2273   /* TW: Set mode on CRT1 */
2274   if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SetCRT2ToLCDA)) {
2275   	SiS_SetCRT1Group(SiS_Pr,ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex,BaseAddr);
2276   } else {
2277     if(!(SiS_Pr->SiS_VBInfo & SwitchToCRT2)) {
2278       	SiS_SetCRT1Group(SiS_Pr,ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex,BaseAddr);
2279     }
2280   }
2281
2282   /* TW: Set mode on CRT2 */
2283   if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchToCRT2 | SetCRT2ToLCDA)) {
2284     switch (HwDeviceExtension->ujVBChipID) {
2285     case VB_CHIP_301:
2286     case VB_CHIP_301B:
2287     case VB_CHIP_301LV:
2288     case VB_CHIP_301LVX:
2289     case VB_CHIP_302:
2290     case VB_CHIP_302B:
2291     case VB_CHIP_302LV:
2292     case VB_CHIP_302LVX:
2293        SiS_SetCRT2Group301(SiS_Pr,BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
2294        break;
2295     case VB_CHIP_303:
2296        break;
2297     case VB_CHIP_UNKNOWN:
2298	if(SiS_Pr->SiS_IF_DEF_LVDS == 1   ||
2299	   SiS_Pr->SiS_IF_DEF_CH70xx != 0 ||
2300	   SiS_Pr->SiS_IF_DEF_TRUMPION != 0)
2301             	SiS_SetCRT2Group301(SiS_Pr,BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
2302        break;
2303     }
2304   }
2305
2306
2307   if((HwDeviceExtension->jChipType > SIS_315PRO) && (SiS_Pr->SiS_IF_DEF_LVDS == 0)) {
2308      /* TW: For 650 only! */
2309      SiS_HandleCRT1(SiS_Pr);
2310   }
2311
2312   SiS_DisplayOn(SiS_Pr);
2313   SiS_SetReg3(SiS_Pr->SiS_P3c6,0xFF);
2314
2315   if((HwDeviceExtension->jChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 0)) {
2316      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
2317          SiS_Handle301B_1400x1050(SiS_Pr, ModeNo);
2318      }
2319   }
2320
2321#ifdef LINUX_XF86
2322   if(pScrn) {
2323      /* TW: SetPitch: Adapt to virtual size & position */
2324      if((ModeNo > 0x13) && (dosetpitch)) {
2325         SiS_SetPitch(SiS_Pr, pScrn, BaseAddr);
2326      }
2327
2328      /* Backup/Set ModeNo in MMIO */
2329      SiS_GetSetModeID(pScrn, ModeNo);
2330   }
2331#endif
2332
2333#ifndef LINUX_XF86      /* TW: We never lock registers in XF86 */
2334   if(KeepLockReg == 0xA1) SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86);
2335   else SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x00);
2336#endif
2337
2338   return TRUE;
2339}
2340
2341void
2342SetEnableDstn(SiS_Private *SiS_Pr)	/* TW: Called from sis_main.c */
2343{
2344   /* For 550 dstn */
2345   SiS_Pr->SiS_IF_DEF_DSTN = 1;
2346}
2347
2348void
2349SiS_HandleCRT1(SiS_Private *SiS_Pr)
2350{
2351  /* TW: Do this on 650 only! */
2352
2353  /* TW: No, we don't do this at all. There is a new
2354   * CRT1-is-connected-at-boot-time logic in the 650, which
2355   * confuses our own. So just clear the bit and skip the rest.
2356   */
2357
2358  SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x63,0xbf);
2359
2360}
2361
2362void
2363SiS_Handle301B_1400x1050(SiS_Private *SiS_Pr, USHORT ModeNo)
2364{
2365  if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30) & SetCRT2ToLCD) {
2366     if(ModeNo <= 0x13) {
2367        if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & (SetNotSimuMode >> 8)) {
2368	   SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xFC);
2369	}
2370     }
2371  }
2372}
2373
2374void
2375SiS_SetCRT1Group(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
2376                 USHORT ModeNo,USHORT ModeIdIndex,USHORT BaseAddr)
2377{
2378  USHORT  StandTableIndex,RefreshRateTableIndex;
2379
2380  SiS_Pr->SiS_CRT1Mode = ModeNo;
2381  StandTableIndex = SiS_GetModePtr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex);
2382  if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
2383    if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchToCRT2)) {
2384       SiS_DisableBridge(SiS_Pr,HwDeviceExtension,BaseAddr);
2385    }
2386  }
2387
2388  SiS_SetSeqRegs(SiS_Pr,ROMAddr,StandTableIndex);
2389  SiS_SetMiscRegs(SiS_Pr,ROMAddr,StandTableIndex);
2390  SiS_SetCRTCRegs(SiS_Pr,ROMAddr,HwDeviceExtension,StandTableIndex);
2391  SiS_SetATTRegs(SiS_Pr,ROMAddr,StandTableIndex,ModeNo,HwDeviceExtension);
2392  SiS_SetGRCRegs(SiS_Pr,ROMAddr,StandTableIndex);
2393  SiS_ClearExt1Regs(SiS_Pr,HwDeviceExtension);
2394  SiS_ResetCRT1VCLK(SiS_Pr,ROMAddr,HwDeviceExtension);
2395
2396  SiS_Pr->SiS_SelectCRT2Rate = 0;
2397  SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
2398
2399#ifdef LINUX_XF86
2400  xf86DrvMsg(0, X_PROBED, "(init: VBType=0x%04x, VBInfo=0x%04x)\n",
2401                    SiS_Pr->SiS_VBType, SiS_Pr->SiS_VBInfo);
2402#endif
2403
2404  if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) {
2405     if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2406        SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
2407     }
2408  }
2409
2410  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
2411	SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
2412  }
2413
2414  RefreshRateTableIndex = SiS_GetRatePtrCRT2(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
2415
2416  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2417	SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
2418  }
2419
2420  if (RefreshRateTableIndex != 0xFFFF) {
2421    	SiS_SetSync(SiS_Pr,ROMAddr,RefreshRateTableIndex);
2422    	SiS_SetCRT1CRTC(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwDeviceExtension);
2423    	SiS_SetCRT1Offset(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwDeviceExtension);
2424    	SiS_SetCRT1VCLK(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,RefreshRateTableIndex);
2425  }
2426
2427#ifdef SIS300
2428  if(HwDeviceExtension->jChipType == SIS_300){
2429     	SiS_SetCRT1FIFO_300(SiS_Pr,ROMAddr,ModeNo,HwDeviceExtension,RefreshRateTableIndex);
2430  }
2431  if((HwDeviceExtension->jChipType == SIS_630)||
2432     (HwDeviceExtension->jChipType == SIS_730)||
2433     (HwDeviceExtension->jChipType == SIS_540)) {
2434     	SiS_SetCRT1FIFO_630(SiS_Pr,ROMAddr,ModeNo,HwDeviceExtension,RefreshRateTableIndex);
2435  }
2436#endif
2437#ifdef SIS315H
2438  if(HwDeviceExtension->jChipType >= SIS_315H) {
2439     	SiS_SetCRT1FIFO_310(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
2440  }
2441#endif
2442
2443  SiS_SetCRT1ModeRegs(SiS_Pr,ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex,RefreshRateTableIndex);
2444
2445  SiS_LoadDAC(SiS_Pr,HwDeviceExtension,ROMAddr,ModeNo,ModeIdIndex);
2446
2447#ifndef LINUX_XF86
2448  if(SiS_Pr->SiS_flag_clearbuffer) {
2449        SiS_ClearBuffer(SiS_Pr,HwDeviceExtension,ModeNo);
2450  }
2451#endif
2452
2453  if(!(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchToCRT2 | SetCRT2ToLCDA))) {
2454        SiS_LongWait(SiS_Pr);
2455        SiS_DisplayOn(SiS_Pr);
2456  }
2457}
2458
2459#ifdef LINUX_XF86
2460void
2461SiS_SetPitch(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, UShort BaseAddr)
2462{
2463   SISPtr pSiS = SISPTR(pScrn);
2464
2465   /* TW: We need to set pitch for CRT1 if bridge is in SlaveMode, too */
2466   if( (pSiS->VBFlags & DISPTYPE_DISP1) ||
2467       ( (pSiS->VBFlags & VB_VIDEOBRIDGE) &&
2468         ( ((pSiS->VGAEngine == SIS_300_VGA) && (SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0xa0) == 0x20) ||
2469           ((pSiS->VGAEngine == SIS_315_VGA) && (SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x50) == 0x10) ) ) ) {
2470   	SiS_SetPitchCRT1(SiS_Pr, pScrn, BaseAddr);
2471   }
2472   if (pSiS->VBFlags & DISPTYPE_DISP2) {
2473   	SiS_SetPitchCRT2(SiS_Pr, pScrn, BaseAddr);
2474   }
2475}
2476
2477void
2478SiS_SetPitchCRT1(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, UShort BaseAddr)
2479{
2480    SISPtr pSiS = SISPTR(pScrn);
2481    ULong  HDisplay,temp;
2482
2483    HDisplay = pSiS->scrnPitch / 8;
2484    SiS_SetReg1(SiS_Pr->SiS_P3d4, 0x13, (HDisplay & 0xFF));
2485    temp = (SiS_GetReg1(SiS_Pr->SiS_P3c4, 0x0E) & 0xF0) | (HDisplay>>8);
2486    SiS_SetReg1(SiS_Pr->SiS_P3c4, 0x0E, temp);
2487}
2488
2489void
2490SiS_SetPitchCRT2(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, UShort BaseAddr)
2491{
2492    SISPtr pSiS = SISPTR(pScrn);
2493    ULong  HDisplay,temp;
2494
2495    HDisplay = pSiS->scrnPitch / 8;
2496
2497    /* Unlock CRT2 */
2498    if (pSiS->VGAEngine == SIS_315_VGA)
2499        SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2F, 0xFF, 0x01);
2500    else
2501        SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x24, 0xFF, 0x01);
2502
2503    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07, (HDisplay & 0xFF));
2504    temp = (SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x09) & 0xF0) | ((HDisplay >> 8) & 0xFF);
2505    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x09, temp);
2506}
2507#endif
2508
2509/* TW: Checked against 650/301 and 630/301B BIOS */
2510/* TW: Re-written for 650/301LVx 1.10.6s BIOS */
2511void
2512SiS_GetVBType(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension)
2513{
2514  USHORT flag=0, rev=0, nolcd=0;
2515
2516  SiS_Pr->SiS_VBType = 0;
2517
2518  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) return;
2519
2520  flag = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x00);
2521
2522  /* TW: Illegal values not welcome... */
2523  if(flag > 10) return;
2524
2525  rev = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x01);
2526
2527  if (flag >= 2) {
2528        SiS_Pr->SiS_VBType = VB_SIS302B;
2529  } else if (flag == 1) {
2530        SiS_Pr->SiS_VBType = VB_SIS301;
2531        if(rev >= 0xB0) {
2532            	SiS_Pr->SiS_VBType = VB_SIS301B;
2533		if(HwDeviceExtension->jChipType >= SIS_315H) {
2534    		    nolcd = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x23);
2535                    if(!(nolcd & 0x02))
2536       	                SiS_Pr->SiS_VBType |= VB_NoLCD;
2537		}
2538        }
2539  }
2540  if(SiS_Pr->SiS_VBType & (VB_SIS301B | VB_SIS302B)) {
2541        if(rev >= 0xD0) {
2542	        SiS_Pr->SiS_VBType &= ~(VB_SIS301B | VB_SIS302B);
2543          	SiS_Pr->SiS_VBType |= VB_SIS30xLV;
2544		SiS_Pr->SiS_VBType &= ~(VB_NoLCD);
2545		if(rev >= 0xE0) {
2546		    SiS_Pr->SiS_VBType &= ~(VB_SIS30xLV);
2547		    SiS_Pr->SiS_VBType |= VB_SIS30xNEW;
2548		}
2549        }
2550  }
2551}
2552
2553/* TW: Checked against 650/301LVx 1.10.6s */
2554BOOLEAN
2555SiS_SearchModeID(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT *ModeNo,USHORT *ModeIdIndex)
2556{
2557   UCHAR VGAINFO = SiS_Pr->SiS_VGAINFO;
2558
2559   if(*ModeNo <= 0x13) {
2560
2561      if((*ModeNo) <= 5) (*ModeNo) |= 1;
2562
2563      for (*ModeIdIndex=0;;(*ModeIdIndex)++) {
2564         if (SiS_Pr->SiS_SModeIDTable[*ModeIdIndex].St_ModeID == (*ModeNo)) break;
2565         if (SiS_Pr->SiS_SModeIDTable[*ModeIdIndex].St_ModeID == 0xFF)   return FALSE;
2566      }
2567
2568      if(*ModeNo == 0x07) {
2569          if(VGAINFO & 0x10) (*ModeIdIndex)++;   /* 400 lines */
2570          /* else 350 lines */
2571      }
2572      if(*ModeNo <= 3) {
2573         if(!(VGAINFO & 0x80)) (*ModeIdIndex)++;
2574         if(VGAINFO & 0x10)    (*ModeIdIndex)++; /* 400 lines  */
2575         /* else 350 lines  */
2576      }
2577      /* else 200 lines  */
2578
2579   } else {
2580
2581      for (*ModeIdIndex=0;;(*ModeIdIndex)++) {
2582         if (SiS_Pr->SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == (*ModeNo)) break;
2583         if (SiS_Pr->SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF)   return FALSE;
2584      }
2585
2586   }
2587   return TRUE;
2588}
2589
2590/* For SiS 300 oem util: Search VBModeID */
2591BOOLEAN
2592SiS_SearchVBModeID(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT *ModeNo)
2593{
2594   USHORT ModeIdIndex;
2595   UCHAR VGAINFO = SiS_Pr->SiS_VGAINFO;
2596
2597   if(*ModeNo <= 5) *ModeNo |= 1;
2598
2599   for(ModeIdIndex=0; ; ModeIdIndex++) {
2600       if (SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == *ModeNo) break;
2601       if (SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == 0xFF)   return FALSE;
2602   }
2603
2604   if(*ModeNo != 0x07) {
2605        if(*ModeNo > 0x03) return ((BOOLEAN)ModeIdIndex);
2606	if(VGAINFO & 0x80) return ((BOOLEAN)ModeIdIndex);
2607	ModeIdIndex++;
2608   }
2609   if(VGAINFO & 0x10) ModeIdIndex++;   /* 400 lines */
2610	                               /* else 350 lines */
2611   return ((BOOLEAN)ModeIdIndex);
2612}
2613
2614/* TW: Checked against 630/301B, 315 1.09 and 650/301LVx 1.10.6s BIOS */
2615/* TW: Modified */
2616BOOLEAN
2617SiS_CheckMemorySize(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
2618                    USHORT ModeNo,USHORT ModeIdIndex)
2619{
2620  USHORT memorysize,modeflag;
2621  ULONG  temp;
2622
2623  if (ModeNo<=0x13) {
2624      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2625  } else {
2626      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2627  }
2628
2629  memorysize = modeflag & MemoryInfoFlag;
2630  memorysize >>= MemorySizeShift;			/* Get required memory size */
2631  memorysize++;
2632
2633  temp = GetDRAMSize(SiS_Pr, HwDeviceExtension);       	/* Get adapter memory size */
2634  temp /= (1024*1024);   				/* (in MB) */
2635
2636  if(temp < memorysize) return(FALSE);
2637  else return(TRUE);
2638}
2639
2640UCHAR
2641SiS_GetModePtr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
2642{
2643   UCHAR index;
2644
2645   if(ModeNo<=0x13) {
2646     	index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_StTableIndex;
2647   } else {
2648     	if(SiS_Pr->SiS_ModeType <= 0x02) index=0x1B;    /* 02 -> ModeEGA  */
2649     	else index=0x0F;
2650   }
2651   return index;
2652}
2653
2654/* TW: Checked against 300, 650/LVDS (1.10.07, 1.10a) and 650/301LV BIOS */
2655void
2656SiS_SetSeqRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex)
2657{
2658   UCHAR SRdata;
2659   USHORT i;
2660
2661   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x00,0x03);           	/* Set SR0  */
2662
2663   SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[0];
2664
2665   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
2666      	if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
2667        	SRdata |= 0x01;
2668        }
2669   }
2670   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2671     if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
2672       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2673         if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2674           SRdata |= 0x01;        			/* 8 dot clock  */
2675         }
2676       }
2677     }
2678     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2679       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2680         SRdata |= 0x01;          			/* 8 dot clock  */
2681       }
2682     }
2683   }
2684
2685   SRdata |= 0x20;                			/* screen off  */
2686
2687   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x01,SRdata);
2688
2689   for(i=02;i<=04;i++) {
2690       	SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[i-1];
2691     	SiS_SetReg1(SiS_Pr->SiS_P3c4,i,SRdata);
2692   }
2693}
2694
2695/* Checked against 300, 650/301LVx 1.10.6s and 650/LVDS 1.10.07 BIOS */
2696void
2697SiS_SetMiscRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex)
2698{
2699   UCHAR Miscdata;
2700
2701   Miscdata = SiS_Pr->SiS_StandTable[StandTableIndex].MISC;
2702
2703   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
2704      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
2705        Miscdata |= 0x0C;
2706      }
2707    }
2708
2709   SiS_SetReg3(SiS_Pr->SiS_P3c2,Miscdata);
2710}
2711
2712/* Checked against 300, 650/LVDS (1.10.07) and 650/301LVx (1.10.6s) BIOS (630 code still there!) */
2713void
2714SiS_SetCRTCRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
2715                USHORT StandTableIndex)
2716{
2717  UCHAR CRTCdata;
2718  USHORT i;
2719
2720  SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);                       /* Unlock CRTC */
2721
2722  for(i=0;i<=0x18;i++) {
2723     CRTCdata=SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[i];
2724     SiS_SetReg1(SiS_Pr->SiS_P3d4,i,CRTCdata);                     /* Set CRTC(3d4) */
2725  }
2726  if( ( (HwDeviceExtension->jChipType == SIS_630) ||
2727        (HwDeviceExtension->jChipType == SIS_730) )  &&
2728      (HwDeviceExtension->jChipRevision >= 0x30) ) {       	   /* for 630S0 */
2729    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2730      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
2731        SiS_SetReg1(SiS_Pr->SiS_P3d4,0x18,0xFE);
2732      }
2733    }
2734  }
2735}
2736
2737/* TW: Checked against 300, 650/LVDS (1.10.07), 650/301LVx (1.10.6s) and 630/301B BIOS */
2738void
2739SiS_SetATTRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex,USHORT ModeNo,
2740               PSIS_HW_DEVICE_INFO HwDeviceExtension)
2741{
2742   UCHAR ARdata;
2743   USHORT i;
2744
2745   for(i=0;i<=0x13;i++) {
2746    ARdata = SiS_Pr->SiS_StandTable[StandTableIndex].ATTR[i];
2747    if(i == 0x13) {
2748      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
2749        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)  ARdata=0;
2750      }
2751      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2752        if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
2753          if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2754            if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata=0;
2755          }
2756        }
2757      }
2758      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2759        if(HwDeviceExtension->jChipType >= SIS_315H) {
2760	  /* TW: From 650/LVDS 1.10.07, 1.10a; 650/301LVx 1.10.6s */
2761	  ARdata = 0;
2762	} else {
2763          if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2764	     ARdata=0;
2765          }
2766	}
2767      }
2768    }
2769    SiS_GetReg2(SiS_Pr->SiS_P3da);                              /* reset 3da  */
2770    SiS_SetReg3(SiS_Pr->SiS_P3c0,i);                            /* set index  */
2771    SiS_SetReg3(SiS_Pr->SiS_P3c0,ARdata);                       /* set data   */
2772   }
2773   SiS_GetReg2(SiS_Pr->SiS_P3da);                               /* reset 3da  */
2774   SiS_SetReg3(SiS_Pr->SiS_P3c0,0x14);                          /* set index  */
2775   SiS_SetReg3(SiS_Pr->SiS_P3c0,0x00);                          /* set data   */
2776
2777   SiS_GetReg2(SiS_Pr->SiS_P3da);                               /* Enable Attribute  */
2778   SiS_SetReg3(SiS_Pr->SiS_P3c0,0x20);
2779}
2780
2781/* TW: Checked against 300, 650/LVDS (1.10.07, 1.10a) and 650/301LV BIOS */
2782void
2783SiS_SetGRCRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex)
2784{
2785   UCHAR GRdata;
2786   USHORT i;
2787
2788   for(i=0;i<=0x08;i++) {
2789     GRdata = SiS_Pr->SiS_StandTable[StandTableIndex].GRC[i]; 	  	/* Get GR from file */
2790     SiS_SetReg1(SiS_Pr->SiS_P3ce,i,GRdata);                    /* Set GR(3ce) */
2791   }
2792
2793   if(SiS_Pr->SiS_ModeType > ModeVGA) {
2794     SiS_SetRegAND(SiS_Pr->SiS_P3ce,0x05,0xBF);			/* 256 color disable */
2795   }
2796}
2797
2798/* TW: Checked against 650/LVDS (1.10.07, 1.10a), 650/301LVx (1.10.6s) and 630/301B BIOS */
2799void
2800SiS_ClearExt1Regs(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
2801{
2802  USHORT i;
2803
2804  for(i=0x0A;i<=0x0E;i++) SiS_SetReg1(SiS_Pr->SiS_P3c4,i,0x00);      /* Clear SR0A-SR0E */
2805
2806  /* TW: New from 650/LVDS/301LV BIOSes: */
2807  if(HwDeviceExtension->jChipType >= SIS_315H) {
2808     SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x37,0xFE);
2809  }
2810}
2811
2812/* TW: Checked against 300, 650/LVDS (1.10.07) and 650/301LV BIOS */
2813void
2814SiS_SetSync(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT RefreshRateTableIndex)
2815{
2816  USHORT sync;
2817  USHORT temp;
2818
2819  sync = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag >> 8;
2820
2821  sync &= 0xC0;
2822  temp = 0x2F | sync;
2823  SiS_SetReg3(SiS_Pr->SiS_P3c2,temp);                                 /* Set Misc(3c2) */
2824}
2825
2826/* TW: Checked against 300, 650/LVDS (1.10.07) and 650/301LVx (1.10.6s) BIOS */
2827void
2828SiS_SetCRT1CRTC(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
2829                USHORT RefreshRateTableIndex,
2830		PSIS_HW_DEVICE_INFO HwDeviceExtension)
2831{
2832  UCHAR  index;
2833  USHORT tempah,i,modeflag,j;
2834#ifdef SIS315H
2835  USHORT temp;
2836  USHORT ResInfo,DisplayType;
2837  const SiS_LCDACRT1DataStruct *LCDACRT1Ptr = NULL;
2838#endif
2839
2840  SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);		/*unlock cr0-7  */
2841
2842  if(ModeNo<=0x13) {
2843        modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2844  } else {
2845        modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2846  }
2847
2848  if((SiS_Pr->SiS_IF_DEF_LVDS == 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2849
2850#ifdef SIS315H
2851
2852     /* LCDA */
2853
2854     temp = SiS_GetLCDACRT1Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
2855                       RefreshRateTableIndex,&ResInfo,&DisplayType);
2856
2857     switch(DisplayType) {
2858      case Panel_800x600       : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT1800x600_1;           break;
2859      case Panel_1024x768      : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_1;          break;
2860      case Panel_1280x1024     : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_1;         break;
2861      case Panel_1400x1050     : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11400x1050_1;         break;
2862      case Panel_1600x1200     : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11600x1200_1;         break;
2863      case Panel_800x600 + 16  : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT1800x600_1_H;         break;
2864      case Panel_1024x768 + 16 : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_1_H;        break;
2865      case Panel_1280x1024 + 16: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_1_H;       break;
2866      case Panel_1400x1050 + 16: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11400x1050_1_H;       break;
2867      case Panel_1600x1200 + 16: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11600x1200_1_H;       break;
2868      case Panel_800x600 + 32  : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT1800x600_2;           break;
2869      case Panel_1024x768 + 32 : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_2;          break;
2870      case Panel_1280x1024 + 32: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_2;         break;
2871      case Panel_1400x1050 + 32: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11400x1050_2;         break;
2872      case Panel_1600x1200 + 32: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11600x1200_2;         break;
2873      case Panel_800x600 + 48  : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT1800x600_2_H;         break;
2874      case Panel_1024x768 + 48 : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_2_H;        break;
2875      case Panel_1280x1024 + 48: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_2_H;       break;
2876      case Panel_1400x1050 + 48: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11400x1050_2_H;       break;
2877      case Panel_1600x1200 + 48: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11600x1200_2_H;       break;
2878      default:                   LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_1;          break;
2879     }
2880
2881     tempah = (LCDACRT1Ptr+ResInfo)->CR[0];
2882     SiS_SetReg1(SiS_Pr->SiS_P3d4,0x00,tempah);
2883     for(i=0x01,j=1;i<=0x07;i++,j++){
2884       tempah = (LCDACRT1Ptr+ResInfo)->CR[j];
2885       SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
2886     }
2887     for(i=0x10,j=8;i<=0x12;i++,j++){
2888       tempah = (LCDACRT1Ptr+ResInfo)->CR[j];
2889       SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
2890     }
2891     for(i=0x15,j=11;i<=0x16;i++,j++){
2892       tempah =(LCDACRT1Ptr+ResInfo)->CR[j];
2893       SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
2894     }
2895     for(i=0x0A,j=13;i<=0x0C;i++,j++){
2896       tempah = (LCDACRT1Ptr+ResInfo)->CR[j];
2897       SiS_SetReg1(SiS_Pr->SiS_P3c4,i,tempah);
2898     }
2899
2900     tempah = (LCDACRT1Ptr+ResInfo)->CR[16];
2901     tempah &= 0x0E0;
2902     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x0E,tempah);
2903
2904     tempah = (LCDACRT1Ptr+ResInfo)->CR[16];
2905     tempah &= 0x01;
2906     tempah <<= 5;
2907     if(modeflag & DoubleScanMode)  tempah |= 0x080;
2908     SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
2909
2910#endif
2911
2912  } else {
2913
2914     /* LVDS, 301, 301B, 301LV, 302LV, ... (non-LCDA) */
2915
2916     index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;  	/* Get index */
2917     if(HwDeviceExtension->jChipType < SIS_315H) {
2918        index &= 0x3F;
2919     }
2920
2921     for(i=0,j=0;i<=07;i++,j++) {
2922       tempah=SiS_Pr->SiS_CRT1Table[index].CR[i];
2923       SiS_SetReg1(SiS_Pr->SiS_P3d4,j,tempah);
2924     }
2925     for(j=0x10;i<=10;i++,j++) {
2926       tempah=SiS_Pr->SiS_CRT1Table[index].CR[i];
2927       SiS_SetReg1(SiS_Pr->SiS_P3d4,j,tempah);
2928     }
2929     for(j=0x15;i<=12;i++,j++) {
2930       tempah=SiS_Pr->SiS_CRT1Table[index].CR[i];
2931       SiS_SetReg1(SiS_Pr->SiS_P3d4,j,tempah);
2932     }
2933     for(j=0x0A;i<=15;i++,j++) {
2934       tempah=SiS_Pr->SiS_CRT1Table[index].CR[i];
2935       SiS_SetReg1(SiS_Pr->SiS_P3c4,j,tempah);
2936     }
2937
2938     tempah = SiS_Pr->SiS_CRT1Table[index].CR[16];
2939     tempah &= 0xE0;
2940     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x0E,tempah);
2941
2942     tempah = SiS_Pr->SiS_CRT1Table[index].CR[16];
2943     tempah &= 0x01;
2944     tempah <<= 5;
2945     if(modeflag & DoubleScanMode)  tempah |= 0x80;
2946     SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0xDF,tempah);
2947
2948  }
2949
2950  if(SiS_Pr->SiS_ModeType > ModeVGA) SiS_SetReg1(SiS_Pr->SiS_P3d4,0x14,0x4F);
2951}
2952
2953BOOLEAN
2954SiS_GetLCDACRT1Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
2955		   USHORT RefreshRateTableIndex,USHORT *ResInfo,
2956		   USHORT *DisplayType)
2957 {
2958  USHORT tempbx=0,modeflag=0;
2959  USHORT CRT2CRTC=0;
2960
2961  if(ModeNo<=0x13) {
2962  	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2963  	CRT2CRTC = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2964  } else {
2965  	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2966  	CRT2CRTC = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2967  }
2968
2969  tempbx = SiS_Pr->SiS_LCDResInfo;
2970
2971  if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) tempbx += 32;
2972  if(modeflag & HalfDCLK)                   tempbx += 16;
2973
2974  *ResInfo = CRT2CRTC & 0x3F;
2975  *DisplayType = tempbx;
2976
2977  return 1;
2978}
2979
2980/* TW: Set offset and pitch - partly overruled by SetPitch() in XF86 */
2981/* TW: Checked against 650/LVDS (1.10.07), 650/301LV and 315 BIOS */
2982void
2983SiS_SetCRT1Offset(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
2984                  USHORT RefreshRateTableIndex,
2985		  PSIS_HW_DEVICE_INFO HwDeviceExtension)
2986{
2987   USHORT temp, DisplayUnit, infoflag;
2988
2989   infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
2990
2991   DisplayUnit = SiS_GetOffset(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
2992                     RefreshRateTableIndex,HwDeviceExtension);
2993
2994   temp = (DisplayUnit >> 8) & 0x0f;
2995   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0xF0,temp);
2996
2997   temp = DisplayUnit & 0xFF;
2998   SiS_SetReg1(SiS_Pr->SiS_P3d4,0x13,temp);
2999
3000   if(infoflag & InterlaceMode) DisplayUnit >>= 1;
3001
3002   DisplayUnit <<= 5;
3003   temp = (DisplayUnit & 0xff00) >> 8;
3004   if (DisplayUnit & 0xff) temp++;
3005   temp++;
3006   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x10,temp);
3007}
3008
3009/* TW: New from 650/LVDS 1.10.07, 630/301B and 630/LVDS BIOS */
3010void
3011SiS_ResetCRT1VCLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension)
3012{
3013   USHORT index;
3014
3015   /* TW: We only need to do this if Panel Link is to be
3016    *     initialized, thus on 630/LVDS/301B, and 650/LVDS
3017    */
3018   if(HwDeviceExtension->jChipType >= SIS_315H) {
3019       if (SiS_Pr->SiS_IF_DEF_LVDS == 0)  return;
3020   } else {
3021       if( (SiS_Pr->SiS_IF_DEF_LVDS == 0) &&
3022           (!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) ) {
3023	   return;
3024      }
3025   }
3026
3027   if(HwDeviceExtension->jChipType >= SIS_315H) {
3028   	SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x31,0xCF,0x20);
3029   } else {
3030   	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x20);
3031   }
3032   index = 1;
3033   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VCLKData[index].SR2B);
3034   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VCLKData[index].SR2C);
3035   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2D,0x80);
3036   if(HwDeviceExtension->jChipType >= SIS_315H) {
3037   	SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x31,0xcf,0x10);
3038   } else {
3039   	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x10);
3040   }
3041   index = 0;
3042   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VCLKData[index].SR2B);
3043   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VCLKData[index].SR2C);
3044   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2D,0x80);
3045}
3046
3047/* TW: Checked against 300, 650/LVDS, 650/301LVx, 315, 630/301B, 630/LVDS BIOS */
3048void
3049SiS_SetCRT1VCLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
3050                PSIS_HW_DEVICE_INFO HwDeviceExtension,
3051		USHORT RefreshRateTableIndex)
3052{
3053  USHORT  index;
3054
3055  index = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
3056	                  RefreshRateTableIndex,HwDeviceExtension);
3057
3058  if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
3059                       && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) ){
3060
3061    	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x31,0xCF);
3062
3063    	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VBVCLKData[index].Part4_A);
3064    	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VBVCLKData[index].Part4_B);
3065
3066    	if(HwDeviceExtension->jChipType >= SIS_315H) {
3067		SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2D,0x01);
3068   	} else {
3069    		SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2D,0x80);
3070    	}
3071
3072  } else {
3073
3074	if(HwDeviceExtension->jChipType >= SIS_315H) {
3075	    SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x31,0xCF);
3076	} else {
3077	    SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x00);
3078	}
3079
3080    	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VCLKData[index].SR2B);
3081    	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VCLKData[index].SR2C);
3082
3083    	if(HwDeviceExtension->jChipType >= SIS_315H) {
3084	    SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2D,0x01);
3085	} else {
3086      	    SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2D,0x80);
3087        }
3088  }
3089}
3090
3091
3092/* TW: Checked against 300, 630/LVDS, 650/LVDS and 315 BIOS */
3093void
3094SiS_SetCRT1ModeRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
3095                    USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex)
3096{
3097  USHORT data,data2,data3;
3098  USHORT infoflag=0,modeflag;
3099  USHORT resindex,xres;
3100
3101  if(ModeNo > 0x13) {
3102    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3103    	infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
3104  } else {
3105    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3106  }
3107
3108  SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1F,0x3F); 		/* DAC pedestal */
3109
3110  if(ModeNo > 0x13) data = infoflag;
3111  else data = 0;
3112
3113  data2 = 0;
3114  if(ModeNo > 0x13) {
3115    if(SiS_Pr->SiS_ModeType > 0x02) {
3116       data2 |= 0x02;
3117       data3 = (SiS_Pr->SiS_ModeType - ModeVGA) << 2;
3118       data2 |= data3;
3119    }
3120  }
3121  if(data & InterlaceMode) data2 |= 0x20;
3122  SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x06,0xC0, data2);
3123
3124  resindex = SiS_GetResInfo(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex);
3125  if(ModeNo <= 0x13) {
3126      	xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
3127  } else {
3128      	xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
3129  }
3130
3131  if(HwDeviceExtension->jChipType != SIS_300) {
3132     data = 0x0000;
3133     if(infoflag & InterlaceMode) {
3134        if(xres == 1024) data = 0x0035;
3135        else data = 0x0048;
3136     }
3137     data2 = data & 0x00FF;
3138     SiS_SetReg1(SiS_Pr->SiS_P3d4,0x19,data2);
3139     data2 = (data & 0xFF00) >> 8;
3140     SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x1a,0xFC,data2);
3141  }
3142
3143  if(modeflag & HalfDCLK) {
3144     SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x01,0x08);
3145  }
3146
3147  if(HwDeviceExtension->jChipType == SIS_300) {
3148     if(modeflag & LineCompareOff) {
3149        SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x0F,0x08);
3150     } else {
3151        SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x0F,0xF7);
3152     }
3153  } else if(HwDeviceExtension->jChipType < SIS_315H) {
3154     if(modeflag & LineCompareOff) {
3155        SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xB7,0x08);
3156     } else {
3157        SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x0F,0xB7);
3158     }
3159     /* 630 BIOS does something for mode 0x12 here */
3160  } else {
3161     if(modeflag & LineCompareOff) {
3162        SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xB7,0x08);
3163     } else {
3164        SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x0F,0xB7);
3165     }
3166  }
3167
3168  if(HwDeviceExtension->jChipType != SIS_300) {
3169     if(SiS_Pr->SiS_ModeType == ModeEGA) {
3170        if(ModeNo > 0x13) {
3171  	   SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x0F,0x40);
3172        }
3173     }
3174  }
3175
3176#ifdef SIS315H
3177  /* TW: 315 BIOS sets SR17 at this point */
3178  if(HwDeviceExtension->jChipType == SIS_315PRO) {
3179      data = SiS_Get310DRAMType(SiS_Pr,ROMAddr,HwDeviceExtension);
3180      data = SiS_Pr->SiS_SR15[2][data];
3181      if(SiS_Pr->SiS_ModeType == ModeText) {
3182          data &= 0xc7;
3183      } else {
3184          data2 = SiS_GetOffset(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
3185                                RefreshRateTableIndex,HwDeviceExtension);
3186	  data2 >>= 1;
3187	  if(infoflag & InterlaceMode) data2 >>= 1;
3188	  data3 = SiS_GetColorDepth(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex);
3189	  data3 >>= 1;
3190	  if(data3 == 0) data3++;
3191	  data2 /= data3;
3192	  if(data2 >= 0x50) {
3193	      data &= 0x0f;
3194	      data |= 0x50;
3195	  }
3196      }
3197      SiS_SetReg1(SiS_Pr->SiS_P3c4,0x17,data);
3198  }
3199#endif
3200
3201  data = 0x60;
3202  if(SiS_Pr->SiS_ModeType != ModeText) {
3203      data ^= 0x60;
3204      if(SiS_Pr->SiS_ModeType != ModeEGA) {
3205        data ^= 0xA0;
3206      }
3207  }
3208  SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x21,0x1F,data);
3209
3210  SiS_SetVCLKState(SiS_Pr,ROMAddr,HwDeviceExtension,ModeNo,RefreshRateTableIndex,ModeIdIndex);
3211
3212#ifdef SIS315H
3213  if(HwDeviceExtension->jChipType >= SIS_315H) {
3214    if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x40) {
3215        SiS_SetReg1(SiS_Pr->SiS_P3d4,0x52,0x2c);
3216    } else {
3217        SiS_SetReg1(SiS_Pr->SiS_P3d4,0x52,0x6c);
3218    }
3219  }
3220#endif
3221}
3222
3223/* TW: Checked against 300, 315, 650/LVDS, 650/301LVx, 630/301B and 630/LVDS BIOS */
3224void
3225SiS_SetVCLKState(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
3226                 USHORT ModeNo,USHORT RefreshRateTableIndex,
3227                 USHORT ModeIdIndex)
3228{
3229  USHORT data, data2=0;
3230  USHORT VCLK, index=0;
3231
3232  if (ModeNo <= 0x13) VCLK = 0;
3233  else {
3234     index = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
3235	               RefreshRateTableIndex,HwDeviceExtension);
3236     VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
3237  }
3238
3239  if(HwDeviceExtension->jChipType < SIS_315H) {		/* 300 series */
3240
3241    data2 = 0x00;
3242    if(VCLK > 150) data2 |= 0x80;
3243    SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0x7B,data2); 	/* DAC speed */
3244
3245    data2 = 0x00;
3246    if(VCLK >= 150) data2 |= 0x08;       	/* VCLK > 150 */
3247    SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xF7,data2);
3248
3249  } else { 						/* 310/325 series */
3250
3251    data = 0;
3252    if(VCLK >= 166) data |= 0x0c;         	/* TW: Was 200; is 166 in 650 and 315 BIOSes */
3253    SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xf3,data);
3254
3255    if(VCLK >= 166) {				/* TW: Was 200, is 166 in 650 and 315 BIOSes */
3256       SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1f,0xe7);
3257    }
3258  }
3259
3260  data2 = 0x03;
3261  if((VCLK >= 135) && (VCLK < 160)) data2 = 0x02;
3262  if((VCLK >= 160) && (VCLK < 260)) data2 = 0x01;
3263  if(VCLK >= 260) data2 = 0x00;
3264  /* disable 24bit palette RAM gamma correction  */
3265  if(HwDeviceExtension->jChipType == SIS_540) {
3266    	if((VCLK == 203) || (VCLK < 234)) data2 = 0x02;
3267  }
3268  if(HwDeviceExtension->jChipType < SIS_315H) {
3269      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xFC,data2);  	/* DAC speed */
3270  } else {
3271      if(HwDeviceExtension->jChipType > SIS_315PRO) {
3272         /* TW: This "if" is done in 650/LVDS/301LV BIOSes; Not in 315 BIOS */
3273         if(ModeNo > 0x13) data2 &= 0xfc;
3274      }
3275      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xF8,data2);  	/* DAC speed */
3276  }
3277}
3278
3279/* TW: Checked against 650/301LVx 1.10.6s, 315, 630/301B BIOS */
3280void
3281SiS_LoadDAC(SiS_Private *SiS_Pr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
3282            UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
3283{
3284   USHORT data,data2;
3285   USHORT time,i,j,k;
3286   USHORT m,n,o;
3287   USHORT si,di,bx,dl;
3288   USHORT al,ah,dh;
3289   USHORT DACAddr, DACData, shiftflag;
3290   const USHORT *table = NULL;
3291
3292   if (ModeNo<=0x13)
3293        data = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3294   else
3295        data = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3296
3297
3298	data &= DACInfoFlag;
3299	time = 64;
3300	if(data == 0x00) table = SiS_MDA_DAC;
3301	if(data == 0x08) table = SiS_CGA_DAC;
3302	if(data == 0x10) table = SiS_EGA_DAC;
3303	if(data == 0x18) {
3304	   time = 256;
3305	   table = SiS_VGA_DAC;
3306	}
3307	if(time == 256) j = 16;
3308	else            j = time;
3309
3310	if( ( (HwDeviceExtension->jChipType < SIS_315H) &&         /* 630/301B */
3311	      (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
3312	      (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) )         ||
3313	    (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)            ||     /* LCDA */
3314	    (!(SiS_Pr->SiS_SetFlag & ProgrammingCRT2)) ) {         /* Programming CRT1 */
3315	   DACAddr = SiS_Pr->SiS_P3c8;
3316	   DACData = SiS_Pr->SiS_P3c9;
3317	   shiftflag = 0;
3318	   SiS_SetReg3(SiS_Pr->SiS_P3c6,0xFF);
3319	} else {
3320	   shiftflag = 1;
3321	   DACAddr = SiS_Pr->SiS_Part5Port;
3322	   DACData = SiS_Pr->SiS_Part5Port + 1;
3323	}
3324
3325	SiS_SetReg3(DACAddr,0x00);
3326
3327	for(i=0; i<j; i++) {
3328	   data = table[i];
3329	   for(k=0; k<3; k++) {
3330		data2 = 0;
3331		if(data & 0x01) data2 = 0x2A;
3332		if(data & 0x02) data2 += 0x15;
3333		if(shiftflag) data2 <<= 2;
3334		SiS_SetReg3(DACData,data2);
3335		data >>= 2;
3336	   }
3337	}
3338
3339	if(time == 256) {
3340	   for(i = 16; i < 32; i++) {
3341		data = table[i];
3342		if(shiftflag) data <<= 2;
3343		for(k=0; k<3; k++) SiS_SetReg3(DACData,data);
3344	   }
3345	   si = 32;
3346	   for(m = 0; m < 9; m++) {
3347	      di = si;
3348	      bx = si + 4;
3349	      dl = 0;
3350	      for(n = 0; n < 3; n++) {
3351		 for(o = 0; o < 5; o++) {
3352		    dh = table[si];
3353		    ah = table[di];
3354		    al = table[bx];
3355		    si++;
3356		    SiS_WriteDAC(SiS_Pr,DACData,shiftflag,dl,ah,al,dh);
3357		 }
3358		 si -= 2;
3359		 for(o = 0; o < 3; o++) {
3360		    dh = table[bx];
3361		    ah = table[di];
3362		    al = table[si];
3363		    si--;
3364		    SiS_WriteDAC(SiS_Pr,DACData,shiftflag,dl,ah,al,dh);
3365		 }
3366		 dl++;
3367	      }            /* for n < 3 */
3368	      si += 5;
3369	   }               /* for m < 9 */
3370	}
3371
3372}
3373
3374void
3375SiS_WriteDAC(SiS_Private *SiS_Pr, USHORT DACData, USHORT shiftflag,
3376             USHORT dl, USHORT ah, USHORT al, USHORT dh)
3377{
3378  USHORT temp;
3379  USHORT bh,bl;
3380
3381  bh = ah;
3382  bl = al;
3383  if(dl != 0) {
3384    temp = bh;
3385    bh = dh;
3386    dh = temp;
3387    if(dl == 1) {
3388       temp = bl;
3389       bl = dh;
3390       dh = temp;
3391    } else {
3392       temp = bl;
3393       bl = bh;
3394       bh = temp;
3395    }
3396  }
3397  if(shiftflag) {
3398     dh <<= 2;
3399     bh <<= 2;
3400     bl <<= 2;
3401  }
3402  SiS_SetReg3(DACData,(USHORT)dh);
3403  SiS_SetReg3(DACData,(USHORT)bh);
3404  SiS_SetReg3(DACData,(USHORT)bl);
3405}
3406
3407ULONG
3408GetDRAMSize(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
3409{
3410  ULONG   AdapterMemorySize = 0;
3411#ifdef SIS315H
3412  USHORT  counter;
3413#endif
3414
3415#ifdef SIS315H
3416  if ((HwDeviceExtension->jChipType == SIS_315H) ||
3417      (HwDeviceExtension->jChipType == SIS_315PRO)) {
3418    	counter = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
3419	AdapterMemorySize = 1 << ((counter & 0xF0) >> 4);
3420	counter >>= 2;
3421	counter &= 0x03;
3422	if(counter == 0x02) {
3423		AdapterMemorySize += (AdapterMemorySize / 2);      /* DDR asymetric */
3424	} else if(counter != 0) {
3425		AdapterMemorySize <<= 1;                           /* SINGLE_CHANNEL_2_RANK or DUAL_CHANNEL_1_RANK */
3426	}
3427	AdapterMemorySize *= (1024*1024);
3428
3429  } else if((HwDeviceExtension->jChipType == SIS_550) ||
3430            (HwDeviceExtension->jChipType == SIS_640) ||
3431            (HwDeviceExtension->jChipType == SIS_740) ||
3432            (HwDeviceExtension->jChipType == SIS_650)) {
3433      		counter = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14) & 0x3F;
3434      		counter++;
3435      		AdapterMemorySize = counter * 4;
3436      		AdapterMemorySize *= (1024*1024);
3437  }
3438#endif
3439
3440#ifdef SIS300
3441  if ((HwDeviceExtension->jChipType==SIS_300) ||
3442      (HwDeviceExtension->jChipType==SIS_540) ||
3443      (HwDeviceExtension->jChipType==SIS_630) ||
3444      (HwDeviceExtension->jChipType==SIS_730)) {
3445      	AdapterMemorySize = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14) & 0x3F;
3446      	AdapterMemorySize++;
3447      	AdapterMemorySize *= (1024*1024);
3448  }
3449#endif
3450
3451  return AdapterMemorySize;
3452}
3453
3454#ifndef LINUX_XF86
3455void
3456SiS_ClearBuffer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo)
3457{
3458  PVOID   VideoMemoryAddress = (PVOID)HwDeviceExtension->pjVideoMemoryAddress;
3459  ULONG   AdapterMemorySize  = (ULONG)HwDeviceExtension->ulVideoMemorySize;
3460  PUSHORT pBuffer;
3461  int i;
3462
3463  if (SiS_Pr->SiS_ModeType>=ModeEGA) {
3464    if(ModeNo > 0x13) {
3465      AdapterMemorySize = GetDRAMSize(SiS_Pr, HwDeviceExtension);
3466      SiS_SetMemory(VideoMemoryAddress,AdapterMemorySize,0);
3467    } else {
3468      pBuffer = VideoMemoryAddress;
3469      for(i=0; i<0x4000; i++)
3470         pBuffer[i] = 0x0000;
3471    }
3472  } else {
3473    pBuffer = VideoMemoryAddress;
3474    if (SiS_Pr->SiS_ModeType < ModeCGA) {
3475      for(i=0; i<0x4000; i++)
3476         pBuffer[i] = 0x0720;
3477    } else {
3478      SiS_SetMemory(VideoMemoryAddress,0x8000,0);
3479    }
3480  }
3481}
3482#endif
3483
3484void
3485SiS_DisplayOn(SiS_Private *SiS_Pr)
3486{
3487   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x01,0xDF,0x00);
3488}
3489
3490void
3491SiS_DisplayOff(SiS_Private *SiS_Pr)
3492{
3493   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x01,0xDF,0x20);
3494}
3495
3496
3497/* ========================================== */
3498/*  SR CRTC GR */
3499void
3500SiS_SetReg1(USHORT port, USHORT index, USHORT data)
3501{
3502   OutPortByte(port,index);
3503   OutPortByte(port+1,data);
3504}
3505
3506/* ========================================== */
3507/*  AR(3C0) */
3508void
3509SiS_SetReg2(SiS_Private *SiS_Pr, USHORT port, USHORT index, USHORT data)
3510{
3511   InPortByte(port+0x3da-0x3c0);
3512   OutPortByte(SiS_Pr->SiS_P3c0,index);
3513   OutPortByte(SiS_Pr->SiS_P3c0,data);
3514   OutPortByte(SiS_Pr->SiS_P3c0,0x20);
3515}
3516
3517void
3518SiS_SetReg3(USHORT port, USHORT data)
3519{
3520   OutPortByte(port,data);
3521}
3522
3523void
3524SiS_SetReg4(USHORT port, ULONG data)
3525{
3526   OutPortLong(port,data);
3527}
3528
3529UCHAR SiS_GetReg1(USHORT port, USHORT index)
3530{
3531   UCHAR   data;
3532
3533   OutPortByte(port,index);
3534   data = InPortByte(port+1);
3535
3536   return(data);
3537}
3538
3539UCHAR
3540SiS_GetReg2(USHORT port)
3541{
3542   UCHAR   data;
3543
3544   data= InPortByte(port);
3545
3546   return(data);
3547}
3548
3549ULONG
3550SiS_GetReg3(USHORT port)
3551{
3552   ULONG   data;
3553
3554   data = InPortLong(port);
3555
3556   return(data);
3557}
3558
3559void
3560SiS_ClearDAC(SiS_Private *SiS_Pr, ULONG port)
3561{
3562   int i;
3563
3564   OutPortByte(port, 0);
3565   port++;
3566   for (i=0; i < (256 * 3); i++) {
3567      OutPortByte(port, 0);
3568   }
3569
3570}
3571
3572
3573/* TW: Checked against 650/LVDS (1.10.07), 650/301LVx (1.10.6s) and 315 BIOS */
3574#ifdef SIS315H
3575void
3576SiS_SetCRT1FIFO_310(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
3577                PSIS_HW_DEVICE_INFO HwDeviceExtension)
3578{
3579  USHORT modeflag;
3580
3581  SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x3D,0xFE);  /* disable auto-threshold */
3582
3583  if(ModeNo > 0x13) {
3584    modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3585    if( (!(modeflag & DoubleScanMode)) || (!(modeflag & HalfDCLK))) {
3586       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x08,0x34);
3587       SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x09,0xF0);
3588       SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x3D,0x01);
3589    } else {
3590       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x08,0xAE);
3591       SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x09,0xF0);
3592    }
3593  } else {
3594    SiS_SetReg1(SiS_Pr->SiS_P3c4,0x08,0xAE);
3595    SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x09,0xF0);
3596  }
3597}
3598#endif
3599
3600#ifdef SIS300
3601void
3602SiS_SetCRT1FIFO_300(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,PSIS_HW_DEVICE_INFO HwDeviceExtension,
3603                    USHORT RefreshRateTableIndex)
3604{
3605  USHORT  ThresholdLow = 0;
3606  USHORT  index, VCLK, MCLK, colorth=0;
3607  USHORT  tempah, temp;
3608
3609  if(ModeNo > 0x13) {
3610
3611     index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
3612     index &= 0x3F;
3613     VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;             /* Get VCLK  */
3614
3615     switch (SiS_Pr->SiS_ModeType - ModeEGA) {     /* Get half colordepth */
3616        case 0 : colorth = 1; break;
3617        case 1 : colorth = 1; break;
3618        case 2 : colorth = 2; break;
3619        case 3 : colorth = 2; break;
3620        case 4 : colorth = 3; break;
3621        case 5 : colorth = 4; break;
3622     }
3623
3624     index = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x3A);
3625     index &= 0x07;
3626     MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;           /* Get MCLK  */
3627
3628     tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x35);
3629     tempah &= 0xc3;
3630     SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x16,0x3c,tempah);
3631
3632     do {
3633        ThresholdLow = SiS_CalcDelay(SiS_Pr, ROMAddr, VCLK, colorth, MCLK);
3634        ThresholdLow++;
3635        if(ThresholdLow < 0x13) break;
3636        SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x16,0xfc);
3637        ThresholdLow = 0x13;
3638        tempah = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16);
3639        tempah >>= 6;
3640        if(!(tempah)) break;
3641        tempah--;
3642        tempah <<= 6;
3643        SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x16,0x3f,tempah);
3644     } while(0);
3645
3646  } else ThresholdLow = 2;
3647
3648  /* Write CRT/CPU threshold low, CRT/Engine threshold high */
3649  temp = (ThresholdLow << 4) | 0x0f;
3650  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x08,temp);
3651
3652  temp = (ThresholdLow & 0x10) << 1;
3653  if(ModeNo > 0x13) temp |= 0x40;
3654  SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0f,0x9f,temp);
3655
3656  /* What is this? */
3657  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x3B,0x09);
3658
3659  /* Write CRT/CPU threshold high */
3660  temp = ThresholdLow + 3;
3661  if(temp > 0x0f) temp = 0x0f;
3662  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x09,temp);
3663}
3664
3665USHORT
3666SiS_CalcDelay(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT VCLK, USHORT colordepth, USHORT MCLK)
3667{
3668  USHORT tempax, tempbx;
3669
3670  tempbx = SiS_DoCalcDelay(SiS_Pr, MCLK, VCLK, colordepth, 0);
3671  tempax = SiS_DoCalcDelay(SiS_Pr, MCLK, VCLK, colordepth, 1);
3672  if(tempax < 4) tempax = 4;
3673  tempax -= 4;
3674  if(tempbx < tempax) tempbx = tempax;
3675  return(tempbx);
3676}
3677
3678USHORT
3679SiS_DoCalcDelay(SiS_Private *SiS_Pr, USHORT MCLK, USHORT VCLK, USHORT colordepth, USHORT key)
3680{
3681  const UCHAR ThLowA[]   = { 61, 3,52, 5,68, 7,100,11,
3682                             43, 3,42, 5,54, 7, 78,11,
3683                             34, 3,37, 5,47, 7, 67,11 };
3684
3685  const UCHAR ThLowB[]   = { 81, 4,72, 6,88, 8,120,12,
3686                             55, 4,54, 6,66, 8, 90,12,
3687                             42, 4,45, 6,55, 8, 75,12 };
3688
3689  const UCHAR ThTiming[] = {  1, 2, 2, 3, 0, 1,  1, 2 };
3690
3691  USHORT tempah, tempal, tempcl, tempbx, temp;
3692  ULONG  longtemp;
3693
3694  tempah = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x18);
3695  tempah &= 0x62;
3696  tempah >>= 1;
3697  tempal = tempah;
3698  tempah >>= 3;
3699  tempal |= tempah;
3700  tempal &= 0x07;
3701  tempcl = ThTiming[tempal];
3702  tempbx = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16);
3703  tempbx >>= 6;
3704  tempah = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
3705  tempah >>= 4;
3706  tempah &= 0x0c;
3707  tempbx |= tempah;
3708  tempbx <<= 1;
3709  if(key == 0) {
3710     tempal = ThLowA[tempbx + 1];
3711     tempal *= tempcl;
3712     tempal += ThLowA[tempbx];
3713  } else {
3714     tempal = ThLowB[tempbx + 1];
3715     tempal *= tempcl;
3716     tempal += ThLowB[tempbx];
3717  }
3718  longtemp = tempal * VCLK * colordepth;
3719  temp = longtemp % (MCLK * 16);
3720  longtemp /= (MCLK * 16);
3721  if(temp) longtemp++;
3722  return((USHORT)longtemp);
3723}
3724
3725
3726void
3727SiS_SetCRT1FIFO_630(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,PSIS_HW_DEVICE_INFO HwDeviceExtension,
3728                    USHORT RefreshRateTableIndex)
3729{
3730  USHORT  i,index,data,VCLK,MCLK,colorth=0;
3731  ULONG   B,eax,bl,data2;
3732  USHORT  ThresholdLow=0;
3733  UCHAR   FQBQData[]= { 0x01,0x21,0x41,0x61,0x81,
3734                        0x31,0x51,0x71,0x91,0xb1,
3735                        0x00,0x20,0x40,0x60,0x80,
3736                        0x30,0x50,0x70,0x90,0xb0,0xFF};
3737
3738  i=0;
3739  if(ModeNo >= 0x13) {
3740    index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
3741    index &= 0x3F;
3742    VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;             /* Get VCLK  */
3743
3744    index = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1A);
3745    index &= 0x07;
3746    MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;           /* Get MCLK  */
3747
3748    data2 = SiS_Pr->SiS_ModeType - ModeEGA;	  /* Get half colordepth */
3749    switch (data2) {
3750        case 0 : colorth = 1; break;
3751        case 1 : colorth = 1; break;
3752        case 2 : colorth = 2; break;
3753        case 3 : colorth = 2; break;
3754        case 4 : colorth = 3; break;
3755        case 5 : colorth = 4; break;
3756    }
3757
3758    do{
3759       B = SiS_CalcDelay2(SiS_Pr, ROMAddr, FQBQData[i]) * VCLK * colorth;
3760       bl = B / (MCLK * 16);
3761
3762       if (B==bl*16*MCLK) {
3763         bl = bl + 1;
3764       } else {
3765         bl = bl + 2;
3766       }
3767
3768       if(bl > 0x13) {
3769          if(FQBQData[i+1] == 0xFF) {
3770             ThresholdLow = 0x13;
3771             break;
3772          }
3773          i++;
3774       } else {
3775          ThresholdLow = bl;
3776          break;
3777       }
3778    } while(FQBQData[i] != 0xFF);
3779  }
3780  else {
3781    ThresholdLow = 0x02;
3782  }
3783
3784  /* Write foreground and background queue */
3785  data2 = FQBQData[i];
3786  data2 = (data2 & 0xf0)>>4;
3787  data2 <<= 24;
3788
3789#ifndef LINUX_XF86
3790  SiS_SetReg4(0xcf8,0x80000050);
3791  eax = SiS_GetReg3(0xcfc);
3792  eax &= 0xf0ffffff;
3793  eax |= data2;
3794  SiS_SetReg4(0xcfc,eax);
3795#else
3796  /* We use pci functions X offers. We use pcitag 0, because
3797   * we want to read/write to the host bridge (which is always
3798   * 00:00.0 on 630, 730 and 540), not the VGA device.
3799   */
3800  eax = pciReadLong(0x00000000, 0x50);
3801  eax &= 0xf0ffffff;
3802  eax |= data2;
3803  pciWriteLong(0x00000000, 0x50, eax);
3804#endif
3805
3806  /* TODO: write GUI grant timer (PCI config 0xA3) */
3807
3808  /* Write CRT/CPU threshold low, CRT/Engine threshold high */
3809  data = ((ThresholdLow & 0x0f) << 4) | 0x0f;
3810  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x08,data);
3811
3812  data = (ThresholdLow & 0x10) << 1;
3813  SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xDF,data);
3814
3815  /* What is this? */
3816  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x3B,0x09);
3817
3818  /* Write CRT/CPU threshold high (gap = 3) */
3819  data = ThresholdLow + 3;
3820  if(data > 0x0f) data = 0x0f;
3821  SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x09,0x80,data);
3822}
3823
3824USHORT
3825SiS_CalcDelay2(SiS_Private *SiS_Pr, UCHAR *ROMAddr,UCHAR key)
3826{
3827  USHORT data,index;
3828  UCHAR  LatencyFactor[] ={ 97, 88, 86, 79, 77, 00,       /*; 64  bit    BQ=2   */
3829                            00, 87, 85, 78, 76, 54,       /*; 64  bit    BQ=1   */
3830                            97, 88, 86, 79, 77, 00,       /*; 128 bit    BQ=2   */
3831                            00, 79, 77, 70, 68, 48,       /*; 128 bit    BQ=1   */
3832                            80, 72, 69, 63, 61, 00,       /*; 64  bit    BQ=2   */
3833                            00, 70, 68, 61, 59, 37,       /*; 64  bit    BQ=1   */
3834                            86, 77, 75, 68, 66, 00,       /*; 128 bit    BQ=2   */
3835                            00, 68, 66, 59, 57, 37};      /*; 128 bit    BQ=1   */
3836
3837  index = (key & 0xE0) >> 5;
3838  if(key & 0x10) index +=6;
3839  if(!(key & 0x01)) index += 24;
3840  data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
3841  if(data & 0x0080) index += 12;
3842
3843  data = LatencyFactor[index];
3844  return(data);
3845}
3846#endif
3847
3848/* =============== Autodetection ================ */
3849/*             I N C O M P L E T E                */
3850
3851BOOLEAN
3852SiS_GetPanelID(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
3853{
3854  const USHORT PanelTypeTable300[16] = {
3855      0xc101, 0xc117, 0x0121, 0xc135, 0xc142, 0xc152, 0xc162, 0xc072,
3856      0xc181, 0xc192, 0xc1a1, 0xc1b6, 0xc1c2, 0xc0d2, 0xc1e2, 0xc1f2
3857  };
3858  const USHORT PanelTypeTable31030x[16] = {
3859      0xc102, 0xc112, 0x0122, 0xc132, 0xc142, 0xc152, 0xc169, 0xc179,
3860      0x0189, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
3861  };
3862  const USHORT PanelTypeTable310LVDS[16] = {
3863      0xc111, 0xc122, 0xc133, 0xc144, 0xc155, 0xc166, 0xc177, 0xc188,
3864      0xc199, 0xc0aa, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
3865  };
3866  USHORT tempax,tempbx,tempah,temp;
3867
3868  if(HwDeviceExtension->jChipType < SIS_315H) {
3869
3870    tempax = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x18);
3871    tempbx = tempax & 0x0F;
3872    if(!(tempax & 0x10)){
3873      if(SiS_Pr->SiS_IF_DEF_LVDS == 1){
3874        tempbx = 0;
3875        temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x38);
3876        if(temp & 0x40) tempbx |= 0x08;
3877        if(temp & 0x20) tempbx |= 0x02;
3878        if(temp & 0x01) tempbx |= 0x01;
3879        temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x39);
3880        if(temp & 0x80) tempbx |= 0x04;
3881      } else {
3882        return 0;
3883      }
3884    }
3885    tempbx = PanelTypeTable300[tempbx];
3886    tempbx |= LCDSync;
3887    temp = tempbx & 0x00FF;
3888    SiS_SetReg1(SiS_Pr->SiS_P3d4,0x36,temp);
3889    temp = (tempbx & 0xFF00) >> 8;
3890    SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x37,~(LCDSyncBit|LCDRGB18Bit),temp);
3891
3892  } else {
3893
3894    tempax = tempah = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1a);
3895    tempax &= 0x1e;
3896    tempax >>= 1;
3897    if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
3898       if(tempax == 0) {
3899           /* TODO: Include HUGE detection routine
3900	            (Probably not worth bothering)
3901	    */
3902           return 0;
3903       }
3904       temp = tempax & 0xff;
3905       tempax--;
3906       tempbx = PanelTypeTable310LVDS[tempax];
3907    } else {
3908       tempbx = PanelTypeTable31030x[tempax];
3909       temp = tempbx & 0xff;
3910    }
3911    SiS_SetReg1(SiS_Pr->SiS_P3d4,0x36,temp);
3912    tempbx = (tempbx & 0xff00) >> 8;
3913    temp = tempbx & 0xc1;
3914    SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x37,~(LCDSyncBit|LCDRGB18Bit),temp);
3915    if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
3916       temp = tempbx & 0x04;
3917       SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x39,0xfb,temp);
3918    }
3919
3920  }
3921  return 1;
3922}
3923
3924
3925#ifdef LINUXBIOS
3926
3927void
3928SiS_DetectMonitor(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
3929{
3930  UCHAR  DAC_TEST_PARMS[] = {0x0F,0x0F,0x0F};
3931  UCHAR  DAC_CLR_PARMS[]  = {0x00,0x00,0x00};
3932  USHORT SR1F;
3933
3934  SR1F = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1F);		/* backup DAC pedestal */
3935  SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1F,0x04);
3936
3937  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
3938    if(!(SiS_BridgeIsOn(SiS_Pr, BaseAddr))) {
3939      SiS_SetReg1(SiS_Pr->SiS_P3d4,0x30,0x41);
3940    }
3941  }
3942
3943  SiSSetMode(SiS_Pr,HwDeviceExtension,0x2E);
3944  if(HwDeviceExtension->jChipType > SIS_315PRO) {
3945     /* TW: On 650 only - enable CRT1 */
3946     SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x63,0xbf);
3947  }
3948  SiS_SetReg3(SiS_Pr->SiS_P3c6,0xff);
3949  SiS_ClearDAC(SiS_Pr, SiS_Pr->SiS_P3c8);
3950  SiS_LongWait(SiS_Pr);
3951  SiS_LongWait(SiS_Pr);
3952  SiS_LongWait(SiS_Pr);
3953  SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x32,0xDF,0x00);
3954  if(SiS_TestMonitorType(SiS_Pr, DAC_TEST_PARMS[0],DAC_TEST_PARMS[1],DAC_TEST_PARMS[2])) {
3955    SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x32,0xDF,0x20);
3956  } else if(SiS_TestMonitorType(SiS_Pr, DAC_TEST_PARMS[0],DAC_TEST_PARMS[1],DAC_TEST_PARMS[2])) {
3957    SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x32,0xDF,0x20);
3958  }
3959  SiS_TestMonitorType(SiS_Pr, DAC_CLR_PARMS[0],DAC_CLR_PARMS[1],DAC_CLR_PARMS[2]);
3960
3961  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1F,SR1F);
3962}
3963
3964USHORT
3965SiS_TestMonitorType(SiS_Private *SiS_Pr, UCHAR R_DAC,UCHAR G_DAC,UCHAR B_DAC)
3966{
3967   USHORT temp,tempbx;
3968
3969   tempbx = R_DAC * 0x4d + G_DAC * 0x97 + B_DAC * 0x1c;
3970   if((tempbx & 0x00ff) > 0x80) tempbx += 0x100;
3971   tempbx = (tempbx & 0xFF00) >> 8;
3972   R_DAC = (UCHAR) tempbx;
3973   G_DAC = (UCHAR) tempbx;
3974   B_DAC = (UCHAR) tempbx;
3975
3976   SiS_SetReg3(SiS_Pr->SiS_P3c8,0x00);
3977   SiS_SetReg3(SiS_Pr->SiS_P3c9,R_DAC);
3978   SiS_SetReg3(SiS_Pr->SiS_P3c9,G_DAC);
3979   SiS_SetReg3(SiS_Pr->SiS_P3c9,B_DAC);
3980   SiS_LongWait(SiS_Pr);
3981   temp=SiS_GetReg2(SiS_Pr->SiS_P3c2);
3982   if(temp & 0x10) return(1);
3983   else return(0);
3984}
3985
3986void
3987SiS_GetSenseStatus(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,UCHAR *ROMAddr)
3988{
3989  USHORT tempax=0,tempbx,tempcx,temp;
3990  USHORT P2reg0=0,SenseModeNo=0,OutputSelect=*SiS_Pr->pSiS_OutputSelect;
3991  USHORT ModeIdIndex,i;
3992  USHORT BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
3993
3994  if(SiS_Pr->SiS_IF_DEF_LVDS == 1){
3995    SiS_GetPanelID(SiS_Pr);
3996    temp=LCDSense;
3997    temp=temp|SiS_SenseCHTV(SiS_Pr);
3998    tempbx=~(LCDSense|AVIDEOSense|SVIDEOSense);
3999    SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x32,tempbx,temp);
4000  } else {       /* for 301 */
4001    if(SiS_Pr->SiS_IF_DEF_HiVision==1) {  /* for HiVision */
4002      tempax=SiS_GetReg1(SiS_Pr->SiS_P3c4,0x38);
4003      temp=tempax&0x01;
4004      tempax=SiS_GetReg1(SiS_Pr->SiS_P3c4,0x3A);
4005      temp=temp|(tempax&0x02);
4006      SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x32,0xA0,temp);
4007    } else {
4008      if(SiS_BridgeIsOn(SiS_Pr, BaseAddr)==0) {    /* TW: Inserted "==0" */
4009        P2reg0 = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x00);
4010        if(!(SiS_BridgeIsEnable(SiS_Pr, BaseAddr,HwDeviceExtension))) {
4011          SenseModeNo=0x2e;
4012          temp = SiS_SearchModeID(SiS_Pr, ROMAddr,&SenseModeNo,&ModeIdIndex);
4013          SiS_Pr->SiS_SetFlag = 0x00;
4014          SiS_Pr->SiS_ModeType = ModeVGA;
4015          SiS_Pr->SiS_VBInfo = SetCRT2ToRAMDAC |LoadDACFlag |SetInSlaveMode;
4016          SiS_SetCRT2Group301(SiS_Pr, BaseAddr,ROMAddr,SenseModeNo,HwDeviceExtension);
4017          for(i=0;i<20;i++) {
4018            SiS_LongWait(SiS_Pr);
4019          }
4020        }
4021        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x00,0x1c);
4022        tempax=0;
4023        tempbx=*SiS_Pr->pSiS_RGBSenseData;
4024	if(SiS_Is301B(SiS_Pr, BaseAddr)){
4025                tempbx=*SiS_Pr->pSiS_RGBSenseData2;
4026        }
4027        tempcx=0x0E08;
4028        if(SiS_Sense(SiS_Pr, tempbx,tempcx)){
4029          if(SiS_Sense(SiS_Pr, tempbx,tempcx)){
4030            tempax=tempax|Monitor2Sense;
4031          }
4032        }
4033        tempbx=*SiS_Pr->pSiS_YCSenseData;
4034        if(SiS_Is301B(SiS_Pr, BaseAddr)){
4035               tempbx=*SiS_Pr->pSiS_YCSenseData2;
4036        }
4037        tempcx=0x0604;
4038        if(SiS_Sense(SiS_Pr, tempbx,tempcx)){
4039          if(SiS_Sense(SiS_Pr,tempbx,tempcx)){
4040            tempax=tempax|SVIDEOSense;
4041          }
4042        }
4043
4044	if(ROMAddr && SiS_Pr->SiS_UseROM) {
4045#ifdef SIS300
4046	   if((HwDeviceExtension->jChipType==SIS_630)||
4047              (HwDeviceExtension->jChipType==SIS_730)) {
4048		OutputSelect = ROMAddr[0xfe];
4049	   }
4050#endif
4051#ifdef SIS315H
4052	   if(HwDeviceExtension->jChipType >= SIS_315H) {
4053	        OutputSelect = ROMAddr[0xf3];
4054	   }
4055#endif
4056        }
4057        if(OutputSelect&BoardTVType){
4058          tempbx=*SiS_Pr->pSiS_VideoSenseData;
4059          if(SiS_Is301B(SiS_Pr, BaseAddr)){
4060             tempbx=*SiS_Pr->pSiS_VideoSenseData2;
4061          }
4062          tempcx=0x0804;
4063          if(SiS_Sense(SiS_Pr, tempbx,tempcx)){
4064            if(SiS_Sense(SiS_Pr, tempbx,tempcx)){
4065              tempax=tempax|AVIDEOSense;
4066            }
4067          }
4068        } else {
4069          if(!(tempax&SVIDEOSense)){
4070            tempbx=*SiS_Pr->pSiS_VideoSenseData;
4071            if(SiS_Is301B(SiS_Pr, BaseAddr)){
4072              tempbx=*SiS_Pr->pSiS_VideoSenseData2;
4073            }
4074            tempcx=0x0804;
4075            if(SiS_Sense(SiS_Pr,tempbx,tempcx)){
4076              if(SiS_Sense(SiS_Pr, tempbx,tempcx)){
4077                tempax=tempax|AVIDEOSense;
4078              }
4079            }
4080          }
4081        }
4082      }
4083
4084      if(SiS_SenseLCD(SiS_Pr, HwDeviceExtension)){
4085        tempax=tempax|LCDSense;
4086      }
4087
4088      tempbx=0;
4089      tempcx=0;
4090      SiS_Sense(SiS_Pr, tempbx,tempcx);
4091
4092      if(SiS_Pr->SiS_VBType & (VB_SIS30xLV|VB_SIS30xLVX)){   /* TW: prev. 301LV|302LV */
4093         tempax &= 0x00ef;   /* 301lv to disable CRT2*/
4094      }
4095      SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x32,~0xDF,tempax);
4096      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x00,P2reg0);
4097      if(!(P2reg0&0x20)) {
4098        SiS_Pr->SiS_VBInfo = DisableCRT2Display;
4099        SiS_SetCRT2Group301(SiS_Pr,BaseAddr,ROMAddr,SenseModeNo,HwDeviceExtension);
4100      }
4101    }
4102  }
4103}
4104
4105BOOLEAN
4106SiS_Sense(SiS_Private *SiS_Pr, USHORT tempbx,USHORT tempcx)
4107{
4108  USHORT temp,i,tempch;
4109
4110  temp = tempbx & 0xFF;
4111  SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x11,temp);
4112  temp = (tempbx & 0xFF00) >> 8;
4113  temp |= (tempcx & 0x00FF);
4114  SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,~0x1F,temp);
4115
4116  for(i=0; i<10; i++) SiS_LongWait(SiS_Pr);
4117
4118  tempch = (tempcx & 0x7F00) >> 8;
4119  temp = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x03);
4120  temp ^= 0x0E;
4121  temp &= tempch;
4122  if(temp>0) return 1;
4123  else return 0;
4124}
4125
4126USHORT
4127SiS_SenseLCD(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
4128{
4129  USHORT temp;
4130
4131  temp=SiS_GetPanelID(SiS_Pr);
4132  if(!temp)  temp=SiS_GetLCDDDCInfo(SiS_Pr, HwDeviceExtension);
4133  return(temp);
4134}
4135
4136BOOLEAN
4137SiS_GetLCDDDCInfo(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
4138{
4139  USHORT temp;
4140  /*add lcd sense*/
4141  if(HwDeviceExtension->ulCRT2LCDType==LCD_UNKNOWN)
4142    	return 0;
4143  else{
4144     	temp=(USHORT)HwDeviceExtension->ulCRT2LCDType;
4145     	SiS_SetReg1(SiS_Pr->SiS_P3d4,0x36,temp);
4146  	return 1;
4147  }
4148}
4149
4150USHORT
4151SiS_SenseCHTV(SiS_Private *SiS_Pr)
4152{
4153  USHORT temp,push0e,status;
4154
4155  status=0;
4156  push0e = SiS_GetCH700x(SiS_Pr, 0x0e);
4157  push0e = (push0e << 8) | 0x0e;
4158  SiS_SetCH700x(SiS_Pr, 0x0b0e);
4159  SiS_SetCH700x(SiS_Pr, 0x0110);
4160  SiS_SetCH700x(SiS_Pr, 0x0010);
4161  temp = SiS_GetCH700x(SiS_Pr, 0x10);
4162  if(temp & 0x08) status |= SVIDEOSense;
4163  if(temp & 0x02) status |= AVIDEOSense;
4164  SiS_SetCH700x(SiS_Pr, push0e);
4165  return(status);
4166}
4167#endif /* LINUXBIOS */
4168
4169/*  ================ for TC only =================  */
4170
4171#ifdef TC
4172
4173int
4174INT1AReturnCode(union REGS regs)
4175{
4176  if (regs.x.cflag)
4177  {
4178    /*printf("Error to find pci device!\n"); */
4179    return 1;
4180  }
4181
4182  switch(regs.h.ah)
4183  {
4184    case 0: return 0;
4185            break;
4186    case 0x81: printf("Function not support\n");
4187               break;
4188    case 0x83: printf("bad vendor id\n");
4189               break;
4190    case 0x86: printf("device not found\n");
4191               break;
4192    case 0x87: printf("bad register number\n");
4193               break;
4194    case 0x88: printf("set failed\n");
4195               break;
4196    case 0x89: printf("buffer too small");
4197               break;
4198  }
4199  return 1;
4200}
4201
4202unsigned
4203FindPCIIOBase(unsigned index,unsigned deviceid)
4204{
4205  union REGS regs;
4206
4207  regs.h.ah = 0xb1;  /*PCI_FUNCTION_ID */
4208  regs.h.al = 0x02;  /*FIND_PCI_DEVICE */
4209  regs.x.cx = deviceid;
4210  regs.x.dx = 0x1039;
4211  regs.x.si = index;  /* find n-th device */
4212
4213  int86(0x1A, &regs, &regs);
4214
4215  if (INT1AReturnCode(regs)!=0)
4216    return 0;
4217
4218  /* regs.h.bh *//* bus number */
4219  /* regs.h.bl *//* device number */
4220  regs.h.ah = 0xb1;  /*PCI_FUNCTION_ID */
4221  regs.h.al = 0x09;  /*READ_CONFIG_WORD */
4222  regs.x.cx = deviceid;
4223  regs.x.dx = 0x1039;
4224  regs.x.di = 0x18;  /* register number */
4225  int86(0x1A, &regs, &regs);
4226
4227  if (INT1AReturnCode(regs)!=0)
4228    return 0;
4229  return regs.x.cx;
4230}
4231
4232
4233void
4234main(int argc, char *argv[])
4235{
4236  SIS_HW_DEVICE_INFO  HwDeviceExtension;
4237  USHORT temp;
4238  USHORT ModeNo;
4239
4240  /*HwDeviceExtension.pjVirtualRomBase =(PUCHAR) MK_FP(0xC000,0); */
4241  /*HwDeviceExtension.pjVideoMemoryAddress = (PUCHAR)MK_FP(0xA000,0);*/
4242
4243#ifdef SIS300
4244  HwDeviceExtension.ulIOAddress = (FindPCIIOBase(0,0x6300)&0xFF80) + 0x30;
4245  HwDeviceExtension.jChipType = SIS_630;
4246#endif
4247
4248#ifdef SIS315H
4249//  HwDeviceExtension.ulIOAddress = (FindPCIIOBase(0,0x5315)&0xFF80) + 0x30;
4250//  HwDeviceExtension.jChipType = SIS_550;
4251  HwDeviceExtension.ulIOAddress = (FindPCIIOBase(0,0x325)&0xFF80) + 0x30;
4252  HwDeviceExtension.jChipType = SIS_315H;
4253#endif
4254
4255  HwDeviceExtension.ujVBChipID = VB_CHIP_301;
4256  strcpy(HwDeviceExtension.szVBIOSVer,"0.84");
4257  HwDeviceExtension.bSkipDramSizing = FALSE;
4258  HwDeviceExtension.ulVideoMemorySize = 0;
4259  if(argc==2) {
4260    ModeNo=atoi(argv[1]);
4261  }
4262  else {
4263    ModeNo=0x2e;
4264    /*ModeNo=0x37; */ /* 1024x768x 4bpp */
4265    /*ModeNo=0x38; *//* 1024x768x 8bpp */
4266    /*ModeNo=0x4A; *//* 1024x768x 16bpp */
4267    /*ModeNo=0x47;*/ /* 800x600x 16bpp */
4268  }
4269 /* SiSInit(SiS_Pr, &HwDeviceExtension);*/
4270  SiSSetMode(SiS_Pr, &HwDeviceExtension, ModeNo);
4271}
4272#endif /* TC END */
4273
4274/* ================ LINUX XFREE86 ====================== */
4275
4276/* Helper functions */
4277
4278#ifdef LINUX_XF86
4279USHORT
4280SiS_CalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode)
4281{
4282   SISPtr pSiS = SISPTR(pScrn);
4283   UShort i = (pSiS->CurrentLayout.bitsPerPixel+7)/8 - 1;
4284   UShort ModeIndex = 0;
4285
4286   switch(mode->HDisplay)
4287   {
4288     case 320:
4289          if(mode->VDisplay == 480) {
4290                ModeIndex = ModeIndex_320x480[i];
4291	  }
4292          break;
4293     case 512:
4294          if(mode->VDisplay == 384) {
4295             ModeIndex = ModeIndex_512x384[i];
4296	  }
4297          break;
4298     case 640:
4299          if(mode->VDisplay == 480) {
4300             ModeIndex = ModeIndex_640x480[i];
4301	  }
4302          break;
4303     case 720:
4304          if(mode->VDisplay == 480) {
4305                ModeIndex = ModeIndex_720x480[i];
4306          } else if(mode->VDisplay == 576) {
4307                ModeIndex = ModeIndex_720x576[i];
4308          }
4309          break;
4310     case 800:
4311	  if(mode->VDisplay == 600) {
4312             ModeIndex = ModeIndex_800x600[i];
4313	  } else if(pSiS->VGAEngine == SIS_315_VGA) {
4314	     if(mode->VDisplay == 480) {
4315	           ModeIndex = ModeIndex_800x480[i];
4316             }
4317	  }
4318          break;
4319     case 1024:
4320          if(mode->VDisplay == 768) {
4321	        ModeIndex = ModeIndex_1024x768[i];
4322	  } else if(pSiS->VGAEngine == SIS_315_VGA) {
4323	     if(mode->VDisplay == 576) {
4324	        ModeIndex = ModeIndex_1024x576[i];
4325             }
4326	  } else if(pSiS->VGAEngine == SIS_300_VGA) {
4327	     if(mode->VDisplay == 600) {
4328	        ModeIndex = ModeIndex_1024x600[i];
4329             }
4330	  }
4331          break;
4332     case 1152:
4333          if(pSiS->VGAEngine == SIS_300_VGA) {
4334	     if(mode->VDisplay == 768) {
4335	        ModeIndex = ModeIndex_1152x768[i];
4336             }
4337	  }
4338	  break;
4339     case 1280:
4340          if(mode->VDisplay == 960) {
4341             if(pSiS->VGAEngine == SIS_300_VGA) {
4342	        ModeIndex = ModeIndex_300_1280x960[i];
4343             } else {
4344                ModeIndex = ModeIndex_310_1280x960[i];
4345             }
4346	  } else if (mode->VDisplay == 1024) {
4347	     ModeIndex = ModeIndex_1280x1024[i];
4348	  } else if(pSiS->VGAEngine == SIS_315_VGA) {
4349	     if (mode->VDisplay == 768) {
4350	        ModeIndex = ModeIndex_1280x768[i];
4351	     } else if (mode->VDisplay == 720) {
4352	        ModeIndex = ModeIndex_1280x720[i];
4353             }
4354	  }
4355          break;
4356     case 1400:
4357          if(pSiS->VGAEngine == SIS_315_VGA) {
4358	     if(mode->VDisplay == 1050) {
4359	        ModeIndex = ModeIndex_1400x1050[i];
4360             }
4361	  }
4362          break;
4363     case 1600:
4364          if(mode->VDisplay == 1200) {
4365             ModeIndex = ModeIndex_1600x1200[i];
4366	  }
4367          break;
4368     case 1920:
4369          if(mode->VDisplay == 1440) {
4370             ModeIndex = ModeIndex_1920x1440[i];
4371	  }
4372          break;
4373     case 2048:
4374          if(pSiS->VGAEngine == SIS_315_VGA) {
4375	     if(mode->VDisplay == 1536) {
4376	         ModeIndex = ModeIndex_2048x1536[i];
4377             }
4378	  }
4379          break;
4380   }
4381
4382   return(ModeIndex);
4383}
4384
4385USHORT
4386SiS_CheckCalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode, int VBFlags)
4387{
4388   SISPtr pSiS = SISPTR(pScrn);
4389   UShort i = (pSiS->CurrentLayout.bitsPerPixel+7)/8 - 1;
4390   UShort ModeIndex = 0;
4391
4392   if(VBFlags & CRT2_LCD) {
4393
4394      if( (mode->HDisplay <= pSiS->LCDwidth) &&
4395          (mode->VDisplay <= pSiS->LCDheight) ) {
4396
4397        if(VBFlags & VB_LVDS) {        		/* LCD on LVDS */
4398
4399          switch(mode->HDisplay)
4400  	  {
4401	  case 512:
4402		if(mode->VDisplay == 384) {
4403		   ModeIndex = ModeIndex_512x384[i];
4404		}
4405		break;
4406	  case 640:
4407		if(mode->VDisplay == 480) {
4408		   ModeIndex = ModeIndex_640x480[i];
4409		}
4410		break;
4411	  case 800:
4412		if(mode->VDisplay == 600) {
4413		   ModeIndex = ModeIndex_800x600[i];
4414		}
4415		break;
4416	  case 1024:
4417		if(mode->VDisplay == 768) {
4418		   ModeIndex = ModeIndex_1024x768[i];
4419		} else if(pSiS->VGAEngine == SIS_300_VGA) {
4420		   if(mode->VDisplay == 600) {
4421		      ModeIndex = ModeIndex_1024x600[i];
4422		   }
4423		}
4424		break;
4425	  case 1152:
4426		if(pSiS->VGAEngine == SIS_300_VGA) {
4427		   if(mode->VDisplay == 768) {
4428			ModeIndex = ModeIndex_1152x768[i];
4429		   }
4430		}
4431		break;
4432	  case 1280:
4433		if(mode->VDisplay == 1024) {
4434		   ModeIndex = ModeIndex_1280x1024[i];
4435		} else if(pSiS->VGAEngine == SIS_315_VGA) {
4436		   if(mode->VDisplay == 768) {
4437		      ModeIndex = ModeIndex_1280x768[i];
4438		   }
4439		}
4440		break;
4441	  case 1400:
4442	        if(mode->VDisplay == 1050) {
4443		   if(pSiS->VGAEngine == SIS_315_VGA) {
4444		      ModeIndex = ModeIndex_1400x1050[i];
4445		   }
4446		}
4447		break;
4448          }
4449
4450        } else {                       	 	/* LCD on 301(B) */
4451
4452          switch(mode->HDisplay)
4453	  {
4454	  case 512:
4455		if(mode->VDisplay == 384) {
4456		   ModeIndex = ModeIndex_512x384[i];
4457		}
4458		break;
4459	  case 640:
4460		if(mode->VDisplay == 480) {
4461		   ModeIndex = ModeIndex_640x480[i];
4462		}
4463		break;
4464	  case 800:
4465		if(mode->VDisplay == 600) {
4466		   ModeIndex = ModeIndex_800x600[i];
4467		}
4468		break;
4469	  case 1024:
4470		if(mode->VDisplay == 768) {
4471		   ModeIndex = ModeIndex_1024x768[i];
4472		} /* else if(pSiS->VGAEngine == SIS_300_VGA) {  --  not supported on 301(B) --
4473		   if(mode->VDisplay == 600) {
4474			ModeIndex = ModeIndex_1024x600[i];
4475		   }
4476		} */
4477		break;
4478	  case 1152:  /* not supported on 301(B) */
4479		break;
4480	  case 1280:
4481		if(mode->VDisplay == 960) {
4482		   if(pSiS->VGAEngine == SIS_300_VGA) {
4483		      ModeIndex = ModeIndex_300_1280x960[i];
4484		   } else {
4485		      ModeIndex = ModeIndex_310_1280x960[i];
4486		   }
4487                } else if (mode->VDisplay == 1024) {
4488	             ModeIndex = ModeIndex_1280x1024[i];
4489	        }
4490	  case 1600:
4491		if(mode->VDisplay == 1200) {
4492		   ModeIndex = ModeIndex_1600x1200[i];
4493		}
4494		break;
4495	  }
4496
4497        }
4498
4499      }
4500
4501   } else if(VBFlags & CRT2_TV) {
4502
4503      if(VBFlags & VB_CHRONTEL) {		/* TV on Chrontel */
4504
4505        switch(mode->HDisplay)
4506	{
4507      	case 512:
4508		if(mode->VDisplay == 384) {
4509		   ModeIndex = ModeIndex_512x384[i];
4510		}
4511		break;
4512	case 640:
4513		if(mode->VDisplay == 480) {
4514		   ModeIndex = ModeIndex_640x480[i];
4515		}
4516		break;
4517	case 800:
4518		if(mode->VDisplay == 600) {
4519		   ModeIndex = ModeIndex_800x600[i];
4520		}
4521		break;
4522	case 1024:
4523		if(mode->VDisplay == 768) {
4524		   if(pSiS->VGAEngine == SIS_315_VGA) {
4525		      ModeIndex = ModeIndex_1024x768[i];
4526		   }
4527		}
4528		break;
4529        }
4530
4531      } else {				    /* TV on 301(B) */
4532
4533        switch(mode->HDisplay)
4534	{
4535      	case 512:
4536		if(mode->VDisplay == 384) {
4537		   ModeIndex = ModeIndex_512x384[i];
4538		}
4539		break;
4540	case 640:
4541		if(mode->VDisplay == 480) {
4542		   ModeIndex = ModeIndex_640x480[i];
4543		}
4544		break;
4545	case 720:
4546                if(mode->VDisplay == 480) {
4547                   ModeIndex = ModeIndex_720x480[i];
4548                } else if(mode->VDisplay == 576) {
4549                   ModeIndex = ModeIndex_720x576[i];
4550                }
4551                break;
4552	case 800:
4553		if(mode->VDisplay == 600) {
4554		   ModeIndex = ModeIndex_800x600[i];
4555		}
4556		break;
4557	case 1024:
4558		if(mode->VDisplay == 768) {
4559		   if(VBFlags & (VB_301B|VB_302B|VB_30xLV|VB_30xLVX)) {
4560		      ModeIndex = ModeIndex_1024x768[i];
4561		   }
4562		}
4563		break;
4564        }
4565
4566      }
4567
4568   } else if(VBFlags & CRT2_VGA) {		/* CRT2 is VGA2 */
4569
4570	switch(mode->HDisplay)
4571	{
4572	case 512:
4573		if(mode->VDisplay == 384) {
4574		    ModeIndex = ModeIndex_512x384[i];
4575		}
4576		break;
4577	case 640:
4578		if(mode->VDisplay == 480) {
4579		   ModeIndex = ModeIndex_640x480[i];
4580		}
4581		break;
4582	case 800:
4583		if(mode->VDisplay == 600) {
4584		   ModeIndex = ModeIndex_800x600[i];
4585		} else if(pSiS->VGAEngine == SIS_315_VGA) {
4586		   if(mode->VDisplay == 480) {
4587			ModeIndex = ModeIndex_800x480[i];
4588		   }
4589		}
4590		break;
4591	case 1024:
4592		if(mode->VDisplay == 768) {
4593			ModeIndex = ModeIndex_1024x768[i];
4594		} else if(pSiS->VGAEngine == SIS_315_VGA) {
4595		   if(mode->VDisplay == 576) {
4596			ModeIndex = ModeIndex_1024x576[i];
4597		   }
4598		}
4599		break;
4600	case 1152:
4601		if(pSiS->VGAEngine == SIS_300_VGA) {
4602		   if(mode->VDisplay == 768) {
4603			ModeIndex = ModeIndex_1152x768[i];
4604		   }
4605		}
4606		break;
4607	case 1280:
4608		if (mode->VDisplay == 1024) {
4609		   ModeIndex = ModeIndex_1280x1024[i];
4610		} else if(pSiS->VGAEngine == SIS_315_VGA) {
4611		   if (mode->VDisplay == 768) {
4612			ModeIndex = ModeIndex_1280x768[i];
4613		   } else if (mode->VDisplay == 720) {
4614			ModeIndex = ModeIndex_1280x720[i];
4615		   }
4616		}
4617		break;
4618	case 1400:
4619		if(pSiS->VGAEngine == SIS_315_VGA) {
4620		   ModeIndex = ModeIndex_1400x1050[i];
4621		}
4622		break;
4623	}
4624
4625   } else {				/* CRT1 only, no CRT2 */
4626
4627       ModeIndex = SiS_CalcModeIndex(pScrn, mode);
4628
4629   }
4630
4631   return(ModeIndex);
4632}
4633
4634#define MODEID_OFF 0x449
4635
4636unsigned char
4637SiS_GetSetModeID(ScrnInfoPtr pScrn, unsigned char id)
4638{
4639    return(SiS_GetSetMMIOReg(pScrn, MODEID_OFF, id));
4640}
4641
4642unsigned char
4643SiS_GetSetMMIOReg(ScrnInfoPtr pScrn, USHORT offset, unsigned char value)
4644{
4645    unsigned char ret;
4646    unsigned char *base;
4647    SISPtr pSiS = SISPTR(pScrn);
4648    BOOLEAN mapped;
4649
4650    if(pSiS->IOBase) {
4651    	base = (unsigned char *)pSiS->IOBase;
4652	mapped = FALSE;
4653    } else {
4654        base = xf86MapVidMem(pScrn->scrnIndex, VIDMEM_MMIO, 0, 0x2000);
4655	if(!base) {
4656	     xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
4657	          "(init.c: Could not MMIO area!)\n");
4658	     return 0;
4659	}
4660	mapped = TRUE;
4661    }
4662
4663    ret = *(base + offset);
4664
4665    /* value != 0xff means: set register */
4666    if (value != 0xff)
4667	*(base + offset) = value;
4668
4669    if(mapped) xf86UnMapVidMem(pScrn->scrnIndex, base, 0x2000);
4670
4671    return ret;
4672}
4673
4674#endif
4675
4676
4677
4678