1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59#ifdef HAVE_CONFIG_H
60#include "config.h"
61#endif
62
63#include "init.h"
64
65#ifdef SIS300
66#include "300vtbl.h"
67#endif
68
69#ifdef SIS315H
70#include "310vtbl.h"
71#endif
72
73#if defined(ALLOC_PRAGMA)
74#pragma alloc_text(PAGE,SiSSetMode)
75#endif
76
77
78
79
80
81#if defined(SIS300) || defined(SIS315H)
82static void
83InitCommonPointer(struct SiS_Private *SiS_Pr)
84{
85 SiS_Pr->SiS_SModeIDTable = SiS_SModeIDTable;
86 SiS_Pr->SiS_StResInfo = SiS_StResInfo;
87 SiS_Pr->SiS_ModeResInfo = SiS_ModeResInfo;
88 SiS_Pr->SiS_StandTable = SiS_StandTable;
89
90 SiS_Pr->SiS_NTSCTiming = SiS_NTSCTiming;
91 SiS_Pr->SiS_PALTiming = SiS_PALTiming;
92 SiS_Pr->SiS_HiTVSt1Timing = SiS_HiTVSt1Timing;
93 SiS_Pr->SiS_HiTVSt2Timing = SiS_HiTVSt2Timing;
94
95 SiS_Pr->SiS_HiTVExtTiming = SiS_HiTVExtTiming;
96 SiS_Pr->SiS_HiTVGroup3Data = SiS_HiTVGroup3Data;
97 SiS_Pr->SiS_HiTVGroup3Simu = SiS_HiTVGroup3Simu;
98#if 0
99 SiS_Pr->SiS_HiTVTextTiming = SiS_HiTVTextTiming;
100 SiS_Pr->SiS_HiTVGroup3Text = SiS_HiTVGroup3Text;
101#endif
102
103 SiS_Pr->SiS_StPALData = SiS_StPALData;
104 SiS_Pr->SiS_ExtPALData = SiS_ExtPALData;
105 SiS_Pr->SiS_StNTSCData = SiS_StNTSCData;
106 SiS_Pr->SiS_ExtNTSCData = SiS_ExtNTSCData;
107 SiS_Pr->SiS_St1HiTVData = SiS_StHiTVData;
108 SiS_Pr->SiS_St2HiTVData = SiS_St2HiTVData;
109 SiS_Pr->SiS_ExtHiTVData = SiS_ExtHiTVData;
110 SiS_Pr->SiS_St525iData = SiS_StNTSCData;
111 SiS_Pr->SiS_St525pData = SiS_St525pData;
112 SiS_Pr->SiS_St750pData = SiS_St750pData;
113 SiS_Pr->SiS_Ext525iData = SiS_ExtNTSCData;
114 SiS_Pr->SiS_Ext525pData = SiS_ExtNTSCData;
115 SiS_Pr->SiS_Ext750pData = SiS_Ext750pData;
116
117 SiS_Pr->pSiS_OutputSelect = &SiS_OutputSelect;
118 SiS_Pr->pSiS_SoftSetting = &SiS_SoftSetting;
119
120 SiS_Pr->SiS_LCD1280x720Data = SiS_LCD1280x720Data;
121 SiS_Pr->SiS_StLCD1280x768_2Data = SiS_StLCD1280x768_2Data;
122 SiS_Pr->SiS_ExtLCD1280x768_2Data = SiS_ExtLCD1280x768_2Data;
123 SiS_Pr->SiS_LCD1280x800Data = SiS_LCD1280x800Data;
124 SiS_Pr->SiS_LCD1280x800_2Data = SiS_LCD1280x800_2Data;
125 SiS_Pr->SiS_LCD1280x854Data = SiS_LCD1280x854Data;
126 SiS_Pr->SiS_LCD1280x960Data = SiS_LCD1280x960Data;
127 SiS_Pr->SiS_StLCD1400x1050Data = SiS_StLCD1400x1050Data;
128 SiS_Pr->SiS_ExtLCD1400x1050Data = SiS_ExtLCD1400x1050Data;
129 SiS_Pr->SiS_LCD1680x1050Data = SiS_LCD1680x1050Data;
130 SiS_Pr->SiS_StLCD1600x1200Data = SiS_StLCD1600x1200Data;
131 SiS_Pr->SiS_ExtLCD1600x1200Data = SiS_ExtLCD1600x1200Data;
132 SiS_Pr->SiS_NoScaleData = SiS_NoScaleData;
133
134 SiS_Pr->SiS_LVDS320x240Data_1 = SiS_LVDS320x240Data_1;
135 SiS_Pr->SiS_LVDS320x240Data_2 = SiS_LVDS320x240Data_2;
136 SiS_Pr->SiS_LVDS640x480Data_1 = SiS_LVDS640x480Data_1;
137 SiS_Pr->SiS_LVDS800x600Data_1 = SiS_LVDS800x600Data_1;
138 SiS_Pr->SiS_LVDS1024x600Data_1 = SiS_LVDS1024x600Data_1;
139 SiS_Pr->SiS_LVDS1024x768Data_1 = SiS_LVDS1024x768Data_1;
140
141 SiS_Pr->SiS_LVDSCRT1320x240_1 = SiS_LVDSCRT1320x240_1;
142 SiS_Pr->SiS_LVDSCRT1320x240_2 = SiS_LVDSCRT1320x240_2;
143 SiS_Pr->SiS_LVDSCRT1320x240_2_H = SiS_LVDSCRT1320x240_2_H;
144 SiS_Pr->SiS_LVDSCRT1320x240_3 = SiS_LVDSCRT1320x240_3;
145 SiS_Pr->SiS_LVDSCRT1320x240_3_H = SiS_LVDSCRT1320x240_3_H;
146 SiS_Pr->SiS_LVDSCRT1640x480_1 = SiS_LVDSCRT1640x480_1;
147 SiS_Pr->SiS_LVDSCRT1640x480_1_H = SiS_LVDSCRT1640x480_1_H;
148#if 0
149 SiS_Pr->SiS_LVDSCRT11024x600_1 = SiS_LVDSCRT11024x600_1;
150 SiS_Pr->SiS_LVDSCRT11024x600_1_H = SiS_LVDSCRT11024x600_1_H;
151 SiS_Pr->SiS_LVDSCRT11024x600_2 = SiS_LVDSCRT11024x600_2;
152 SiS_Pr->SiS_LVDSCRT11024x600_2_H = SiS_LVDSCRT11024x600_2_H;
153#endif
154
155 SiS_Pr->SiS_CHTVUNTSCData = SiS_CHTVUNTSCData;
156 SiS_Pr->SiS_CHTVONTSCData = SiS_CHTVONTSCData;
157
158 SiS_Pr->SiS_PanelMinLVDS = Panel_800x600;
159 SiS_Pr->SiS_PanelMin301 = Panel_1024x768;
160}
161#endif
162
163#ifdef SIS300
164static void
165InitTo300Pointer(struct SiS_Private *SiS_Pr)
166{
167 InitCommonPointer(SiS_Pr);
168
169 SiS_Pr->SiS_VBModeIDTable = SiS300_VBModeIDTable;
170 SiS_Pr->SiS_EModeIDTable = SiS300_EModeIDTable;
171 SiS_Pr->SiS_RefIndex = SiS300_RefIndex;
172 SiS_Pr->SiS_CRT1Table = SiS300_CRT1Table;
173 if(SiS_Pr->ChipType == SIS_300) {
174 SiS_Pr->SiS_MCLKData_0 = SiS300_MCLKData_300;
175 } else {
176 SiS_Pr->SiS_MCLKData_0 = SiS300_MCLKData_630;
177 }
178 SiS_Pr->SiS_VCLKData = SiS300_VCLKData;
179 SiS_Pr->SiS_VBVCLKData = (struct SiS_VBVCLKData *)SiS300_VCLKData;
180
181 SiS_Pr->SiS_SR15 = SiS300_SR15;
182
183 SiS_Pr->SiS_PanelDelayTbl = SiS300_PanelDelayTbl;
184 SiS_Pr->SiS_PanelDelayTblLVDS = SiS300_PanelDelayTbl;
185
186 SiS_Pr->SiS_ExtLCD1024x768Data = SiS300_ExtLCD1024x768Data;
187 SiS_Pr->SiS_St2LCD1024x768Data = SiS300_St2LCD1024x768Data;
188 SiS_Pr->SiS_ExtLCD1280x1024Data = SiS300_ExtLCD1280x1024Data;
189 SiS_Pr->SiS_St2LCD1280x1024Data = SiS300_St2LCD1280x1024Data;
190
191 SiS_Pr->SiS_CRT2Part2_1024x768_1 = SiS300_CRT2Part2_1024x768_1;
192 SiS_Pr->SiS_CRT2Part2_1024x768_2 = SiS300_CRT2Part2_1024x768_2;
193 SiS_Pr->SiS_CRT2Part2_1024x768_3 = SiS300_CRT2Part2_1024x768_3;
194
195 SiS_Pr->SiS_CHTVUPALData = SiS300_CHTVUPALData;
196 SiS_Pr->SiS_CHTVOPALData = SiS300_CHTVOPALData;
197 SiS_Pr->SiS_CHTVUPALMData = SiS_CHTVUNTSCData;
198 SiS_Pr->SiS_CHTVOPALMData = SiS_CHTVONTSCData;
199 SiS_Pr->SiS_CHTVUPALNData = SiS300_CHTVUPALData;
200 SiS_Pr->SiS_CHTVOPALNData = SiS300_CHTVOPALData;
201 SiS_Pr->SiS_CHTVSOPALData = SiS300_CHTVSOPALData;
202
203 SiS_Pr->SiS_LVDS848x480Data_1 = SiS300_LVDS848x480Data_1;
204 SiS_Pr->SiS_LVDS848x480Data_2 = SiS300_LVDS848x480Data_2;
205 SiS_Pr->SiS_LVDSBARCO1024Data_1 = SiS300_LVDSBARCO1024Data_1;
206 SiS_Pr->SiS_LVDSBARCO1366Data_1 = SiS300_LVDSBARCO1366Data_1;
207 SiS_Pr->SiS_LVDSBARCO1366Data_2 = SiS300_LVDSBARCO1366Data_2;
208
209 SiS_Pr->SiS_PanelType04_1a = SiS300_PanelType04_1a;
210 SiS_Pr->SiS_PanelType04_2a = SiS300_PanelType04_2a;
211 SiS_Pr->SiS_PanelType04_1b = SiS300_PanelType04_1b;
212 SiS_Pr->SiS_PanelType04_2b = SiS300_PanelType04_2b;
213
214 SiS_Pr->SiS_CHTVCRT1UNTSC = SiS300_CHTVCRT1UNTSC;
215 SiS_Pr->SiS_CHTVCRT1ONTSC = SiS300_CHTVCRT1ONTSC;
216 SiS_Pr->SiS_CHTVCRT1UPAL = SiS300_CHTVCRT1UPAL;
217 SiS_Pr->SiS_CHTVCRT1OPAL = SiS300_CHTVCRT1OPAL;
218 SiS_Pr->SiS_CHTVCRT1SOPAL = SiS300_CHTVCRT1SOPAL;
219 SiS_Pr->SiS_CHTVReg_UNTSC = SiS300_CHTVReg_UNTSC;
220 SiS_Pr->SiS_CHTVReg_ONTSC = SiS300_CHTVReg_ONTSC;
221 SiS_Pr->SiS_CHTVReg_UPAL = SiS300_CHTVReg_UPAL;
222 SiS_Pr->SiS_CHTVReg_OPAL = SiS300_CHTVReg_OPAL;
223 SiS_Pr->SiS_CHTVReg_UPALM = SiS300_CHTVReg_UNTSC;
224 SiS_Pr->SiS_CHTVReg_OPALM = SiS300_CHTVReg_ONTSC;
225 SiS_Pr->SiS_CHTVReg_UPALN = SiS300_CHTVReg_UPAL;
226 SiS_Pr->SiS_CHTVReg_OPALN = SiS300_CHTVReg_OPAL;
227 SiS_Pr->SiS_CHTVReg_SOPAL = SiS300_CHTVReg_SOPAL;
228 SiS_Pr->SiS_CHTVVCLKUNTSC = SiS300_CHTVVCLKUNTSC;
229 SiS_Pr->SiS_CHTVVCLKONTSC = SiS300_CHTVVCLKONTSC;
230 SiS_Pr->SiS_CHTVVCLKUPAL = SiS300_CHTVVCLKUPAL;
231 SiS_Pr->SiS_CHTVVCLKOPAL = SiS300_CHTVVCLKOPAL;
232 SiS_Pr->SiS_CHTVVCLKUPALM = SiS300_CHTVVCLKUNTSC;
233 SiS_Pr->SiS_CHTVVCLKOPALM = SiS300_CHTVVCLKONTSC;
234 SiS_Pr->SiS_CHTVVCLKUPALN = SiS300_CHTVVCLKUPAL;
235 SiS_Pr->SiS_CHTVVCLKOPALN = SiS300_CHTVVCLKOPAL;
236 SiS_Pr->SiS_CHTVVCLKSOPAL = SiS300_CHTVVCLKSOPAL;
237}
238#endif
239
240#ifdef SIS315H
241static void
242InitTo310Pointer(struct SiS_Private *SiS_Pr)
243{
244 InitCommonPointer(SiS_Pr);
245
246 SiS_Pr->SiS_EModeIDTable = SiS310_EModeIDTable;
247 SiS_Pr->SiS_RefIndex = SiS310_RefIndex;
248 SiS_Pr->SiS_CRT1Table = SiS310_CRT1Table;
249 if(SiS_Pr->ChipType >= SIS_340) {
250 SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_340;
251 } else if(SiS_Pr->ChipType >= SIS_761) {
252 SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_761;
253 } else if(SiS_Pr->ChipType >= SIS_760) {
254 SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_760;
255 } else if(SiS_Pr->ChipType >= SIS_661) {
256 SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_660;
257 } else if(SiS_Pr->ChipType == SIS_330) {
258 SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_330;
259 } else if(SiS_Pr->ChipType > SIS_315PRO) {
260 SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_650;
261 } else {
262 SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_315;
263 }
264 if(SiS_Pr->ChipType >= SIS_340) {
265 SiS_Pr->SiS_MCLKData_1 = SiS310_MCLKData_1_340;
266 } else {
267 SiS_Pr->SiS_MCLKData_1 = SiS310_MCLKData_1;
268 }
269 SiS_Pr->SiS_VCLKData = SiS310_VCLKData;
270 SiS_Pr->SiS_VBVCLKData = SiS310_VBVCLKData;
271
272 SiS_Pr->SiS_SR15 = SiS310_SR15;
273
274 SiS_Pr->SiS_PanelDelayTbl = SiS310_PanelDelayTbl;
275 SiS_Pr->SiS_PanelDelayTblLVDS = SiS310_PanelDelayTblLVDS;
276
277 SiS_Pr->SiS_St2LCD1024x768Data = SiS310_St2LCD1024x768Data;
278 SiS_Pr->SiS_ExtLCD1024x768Data = SiS310_ExtLCD1024x768Data;
279 SiS_Pr->SiS_St2LCD1280x1024Data = SiS310_St2LCD1280x1024Data;
280 SiS_Pr->SiS_ExtLCD1280x1024Data = SiS310_ExtLCD1280x1024Data;
281
282 SiS_Pr->SiS_CRT2Part2_1024x768_1 = SiS310_CRT2Part2_1024x768_1;
283
284 SiS_Pr->SiS_CHTVUPALData = SiS310_CHTVUPALData;
285 SiS_Pr->SiS_CHTVOPALData = SiS310_CHTVOPALData;
286 SiS_Pr->SiS_CHTVUPALMData = SiS310_CHTVUPALMData;
287 SiS_Pr->SiS_CHTVOPALMData = SiS310_CHTVOPALMData;
288 SiS_Pr->SiS_CHTVUPALNData = SiS310_CHTVUPALNData;
289 SiS_Pr->SiS_CHTVOPALNData = SiS310_CHTVOPALNData;
290 SiS_Pr->SiS_CHTVSOPALData = SiS310_CHTVSOPALData;
291
292 SiS_Pr->SiS_CHTVCRT1UNTSC = SiS310_CHTVCRT1UNTSC;
293 SiS_Pr->SiS_CHTVCRT1ONTSC = SiS310_CHTVCRT1ONTSC;
294 SiS_Pr->SiS_CHTVCRT1UPAL = SiS310_CHTVCRT1UPAL;
295 SiS_Pr->SiS_CHTVCRT1OPAL = SiS310_CHTVCRT1OPAL;
296 SiS_Pr->SiS_CHTVCRT1SOPAL = SiS310_CHTVCRT1OPAL;
297
298 SiS_Pr->SiS_CHTVReg_UNTSC = SiS310_CHTVReg_UNTSC;
299 SiS_Pr->SiS_CHTVReg_ONTSC = SiS310_CHTVReg_ONTSC;
300 SiS_Pr->SiS_CHTVReg_UPAL = SiS310_CHTVReg_UPAL;
301 SiS_Pr->SiS_CHTVReg_OPAL = SiS310_CHTVReg_OPAL;
302 SiS_Pr->SiS_CHTVReg_UPALM = SiS310_CHTVReg_UPALM;
303 SiS_Pr->SiS_CHTVReg_OPALM = SiS310_CHTVReg_OPALM;
304 SiS_Pr->SiS_CHTVReg_UPALN = SiS310_CHTVReg_UPALN;
305 SiS_Pr->SiS_CHTVReg_OPALN = SiS310_CHTVReg_OPALN;
306 SiS_Pr->SiS_CHTVReg_SOPAL = SiS310_CHTVReg_OPAL;
307
308 SiS_Pr->SiS_CHTVVCLKUNTSC = SiS310_CHTVVCLKUNTSC;
309 SiS_Pr->SiS_CHTVVCLKONTSC = SiS310_CHTVVCLKONTSC;
310 SiS_Pr->SiS_CHTVVCLKUPAL = SiS310_CHTVVCLKUPAL;
311 SiS_Pr->SiS_CHTVVCLKOPAL = SiS310_CHTVVCLKOPAL;
312 SiS_Pr->SiS_CHTVVCLKUPALM = SiS310_CHTVVCLKUPALM;
313 SiS_Pr->SiS_CHTVVCLKOPALM = SiS310_CHTVVCLKOPALM;
314 SiS_Pr->SiS_CHTVVCLKUPALN = SiS310_CHTVVCLKUPALN;
315 SiS_Pr->SiS_CHTVVCLKOPALN = SiS310_CHTVVCLKOPALN;
316 SiS_Pr->SiS_CHTVVCLKSOPAL = SiS310_CHTVVCLKOPAL;
317}
318#endif
319
320bool
321SiSInitPtr(struct SiS_Private *SiS_Pr)
322{
323 if(SiS_Pr->ChipType < SIS_315H) {
324#ifdef SIS300
325 InitTo300Pointer(SiS_Pr);
326#else
327 return false;
328#endif
329 } else {
330#ifdef SIS315H
331 InitTo310Pointer(SiS_Pr);
332#else
333 return false;
334#endif
335 }
336 return true;
337}
338
339
340
341
342
343#ifndef SIS_XORG_XF86
344static
345#endif
346unsigned short
347SiS_GetModeID(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay,
348 int Depth, bool FSTN, int LCDwidth, int LCDheight)
349{
350 unsigned short ModeIndex = 0;
351
352 switch(HDisplay)
353 {
354 case 320:
355 if(VDisplay == 200) ModeIndex = ModeIndex_320x200[Depth];
356 else if(VDisplay == 240) {
357 if((VBFlags & CRT2_LCD) && (FSTN))
358 ModeIndex = ModeIndex_320x240_FSTN[Depth];
359 else
360 ModeIndex = ModeIndex_320x240[Depth];
361 }
362 break;
363 case 400:
364 if((!(VBFlags & CRT1_LCDA)) || ((LCDwidth >= 800) && (LCDwidth >= 600))) {
365 if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
366 }
367 break;
368 case 512:
369 if((!(VBFlags & CRT1_LCDA)) || ((LCDwidth >= 1024) && (LCDwidth >= 768))) {
370 if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
371 }
372 break;
373 case 640:
374 if(VDisplay == 480) ModeIndex = ModeIndex_640x480[Depth];
375 else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth];
376 break;
377 case 720:
378 if(VDisplay == 480) ModeIndex = ModeIndex_720x480[Depth];
379 else if(VDisplay == 576) ModeIndex = ModeIndex_720x576[Depth];
380 break;
381 case 768:
382 if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
383 break;
384 case 800:
385 if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
386 else if(VDisplay == 480) ModeIndex = ModeIndex_800x480[Depth];
387 break;
388 case 848:
389 if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth];
390 break;
391 case 856:
392 if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth];
393 break;
394 case 960:
395 if(VGAEngine == SIS_315_VGA) {
396 if(VDisplay == 540) ModeIndex = ModeIndex_960x540[Depth];
397 else if(VDisplay == 600) ModeIndex = ModeIndex_960x600[Depth];
398 }
399 break;
400 case 1024:
401 if(VDisplay == 576) ModeIndex = ModeIndex_1024x576[Depth];
402 else if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
403 else if(VGAEngine == SIS_300_VGA) {
404 if(VDisplay == 600) ModeIndex = ModeIndex_1024x600[Depth];
405 }
406 break;
407 case 1152:
408 if(VDisplay == 864) ModeIndex = ModeIndex_1152x864[Depth];
409 if(VGAEngine == SIS_300_VGA) {
410 if(VDisplay == 768) ModeIndex = ModeIndex_1152x768[Depth];
411 }
412 break;
413 case 1280:
414 switch(VDisplay) {
415 case 720:
416 ModeIndex = ModeIndex_1280x720[Depth];
417 break;
418 case 768:
419 if(VGAEngine == SIS_300_VGA) {
420 ModeIndex = ModeIndex_300_1280x768[Depth];
421 } else {
422 ModeIndex = ModeIndex_310_1280x768[Depth];
423 }
424 break;
425 case 800:
426 if(VGAEngine == SIS_315_VGA) {
427 ModeIndex = ModeIndex_1280x800[Depth];
428 }
429 break;
430 case 854:
431 if(VGAEngine == SIS_315_VGA) {
432 ModeIndex = ModeIndex_1280x854[Depth];
433 }
434 break;
435 case 960:
436 ModeIndex = ModeIndex_1280x960[Depth];
437 break;
438 case 1024:
439 ModeIndex = ModeIndex_1280x1024[Depth];
440 break;
441 }
442 break;
443 case 1360:
444 if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth];
445 if(VGAEngine == SIS_300_VGA) {
446 if(VDisplay == 1024) ModeIndex = ModeIndex_300_1360x1024[Depth];
447 }
448 break;
449 case 1400:
450 if(VGAEngine == SIS_315_VGA) {
451 if(VDisplay == 1050) {
452 ModeIndex = ModeIndex_1400x1050[Depth];
453 }
454 }
455 break;
456 case 1600:
457 if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
458 break;
459 case 1680:
460 if(VGAEngine == SIS_315_VGA) {
461 if(VDisplay == 1050) ModeIndex = ModeIndex_1680x1050[Depth];
462 }
463 break;
464 case 1920:
465 if(VDisplay == 1440) ModeIndex = ModeIndex_1920x1440[Depth];
466 else if(VGAEngine == SIS_315_VGA) {
467 if(VDisplay == 1080) ModeIndex = ModeIndex_1920x1080[Depth];
468 }
469 break;
470 case 2048:
471 if(VDisplay == 1536) {
472 if(VGAEngine == SIS_300_VGA) {
473 ModeIndex = ModeIndex_300_2048x1536[Depth];
474 } else {
475 ModeIndex = ModeIndex_310_2048x1536[Depth];
476 }
477 }
478 break;
479 }
480
481 return ModeIndex;
482}
483
484unsigned short
485SiS_GetModeID_LCD(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay,
486 int Depth, bool FSTN, unsigned short CustomT, int LCDwidth, int LCDheight,
487 unsigned int VBFlags2)
488{
489 unsigned short ModeIndex = 0;
490
491 if(VBFlags2 & (VB2_LVDS | VB2_30xBDH)) {
492
493 switch(HDisplay)
494 {
495 case 320:
496 if((CustomT != CUT_PANEL848) && (CustomT != CUT_PANEL856)) {
497 if(VDisplay == 200) {
498 if(!FSTN) ModeIndex = ModeIndex_320x200[Depth];
499 } else if(VDisplay == 240) {
500 if(!FSTN) ModeIndex = ModeIndex_320x240[Depth];
501 else if(VGAEngine == SIS_315_VGA) {
502 ModeIndex = ModeIndex_320x240_FSTN[Depth];
503 }
504 }
505 }
506 break;
507 case 400:
508 if((CustomT != CUT_PANEL848) && (CustomT != CUT_PANEL856)) {
509 if(!((VGAEngine == SIS_300_VGA) && (VBFlags2 & VB2_TRUMPION))) {
510 if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
511 }
512 }
513 break;
514 case 512:
515 if((CustomT != CUT_PANEL848) && (CustomT != CUT_PANEL856)) {
516 if(!((VGAEngine == SIS_300_VGA) && (VBFlags2 & VB2_TRUMPION))) {
517 if(LCDwidth >= 1024 && LCDwidth != 1152 && LCDheight >= 768) {
518 if(VDisplay == 384) {
519 ModeIndex = ModeIndex_512x384[Depth];
520 }
521 }
522 }
523 }
524 break;
525 case 640:
526 if(VDisplay == 480) ModeIndex = ModeIndex_640x480[Depth];
527 else if(VDisplay == 400) {
528 if((CustomT != CUT_PANEL848) && (CustomT != CUT_PANEL856))
529 ModeIndex = ModeIndex_640x400[Depth];
530 }
531 break;
532 case 800:
533 if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
534 break;
535 case 848:
536 if(CustomT == CUT_PANEL848) {
537 if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth];
538 }
539 break;
540 case 856:
541 if(CustomT == CUT_PANEL856) {
542 if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth];
543 }
544 break;
545 case 1024:
546 if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
547 else if(VGAEngine == SIS_300_VGA) {
548 if((VDisplay == 600) && (LCDheight == 600)) {
549 ModeIndex = ModeIndex_1024x600[Depth];
550 }
551 }
552 break;
553 case 1152:
554 if(VGAEngine == SIS_300_VGA) {
555 if((VDisplay == 768) && (LCDheight == 768)) {
556 ModeIndex = ModeIndex_1152x768[Depth];
557 }
558 }
559 break;
560 case 1280:
561 if(VDisplay == 1024) ModeIndex = ModeIndex_1280x1024[Depth];
562 else if(VGAEngine == SIS_315_VGA) {
563 if((VDisplay == 768) && (LCDheight == 768)) {
564 ModeIndex = ModeIndex_310_1280x768[Depth];
565 }
566 }
567 break;
568 case 1360:
569 if(VGAEngine == SIS_300_VGA) {
570 if(CustomT == CUT_BARCO1366) {
571 if(VDisplay == 1024) ModeIndex = ModeIndex_300_1360x1024[Depth];
572 }
573 }
574 if(CustomT == CUT_PANEL848) {
575 if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth];
576 }
577 break;
578 case 1400:
579 if(VGAEngine == SIS_315_VGA) {
580 if(VDisplay == 1050) ModeIndex = ModeIndex_1400x1050[Depth];
581 }
582 break;
583 case 1600:
584 if(VGAEngine == SIS_315_VGA) {
585 if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
586 }
587 break;
588 }
589
590 } else if(VBFlags2 & VB2_SISBRIDGE) {
591
592 switch(HDisplay)
593 {
594 case 320:
595 if(VDisplay == 200) ModeIndex = ModeIndex_320x200[Depth];
596 else if(VDisplay == 240) ModeIndex = ModeIndex_320x240[Depth];
597 break;
598 case 400:
599 if(LCDwidth >= 800 && LCDheight >= 600) {
600 if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
601 }
602 break;
603 case 512:
604 if(LCDwidth >= 1024 && LCDheight >= 768 && LCDwidth != 1152) {
605 if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
606 }
607 break;
608 case 640:
609 if(VDisplay == 480) ModeIndex = ModeIndex_640x480[Depth];
610 else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth];
611 break;
612 case 720:
613 if(VGAEngine == SIS_315_VGA) {
614 if(VDisplay == 480) ModeIndex = ModeIndex_720x480[Depth];
615 else if(VDisplay == 576) ModeIndex = ModeIndex_720x576[Depth];
616 }
617 break;
618 case 768:
619 if(VGAEngine == SIS_315_VGA) {
620 if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
621 }
622 break;
623 case 800:
624 if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
625 if(VGAEngine == SIS_315_VGA) {
626 if(VDisplay == 480) ModeIndex = ModeIndex_800x480[Depth];
627 }
628 break;
629 case 848:
630 if(VGAEngine == SIS_315_VGA) {
631 if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth];
632 }
633 break;
634 case 856:
635 if(VGAEngine == SIS_315_VGA) {
636 if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth];
637 }
638 break;
639 case 960:
640 if(VGAEngine == SIS_315_VGA) {
641 if(VDisplay == 540) ModeIndex = ModeIndex_960x540[Depth];
642 else if(VDisplay == 600) ModeIndex = ModeIndex_960x600[Depth];
643 }
644 break;
645 case 1024:
646 if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
647 if(VGAEngine == SIS_315_VGA) {
648 if(VDisplay == 576) ModeIndex = ModeIndex_1024x576[Depth];
649 }
650 break;
651 case 1152:
652 if(VGAEngine == SIS_315_VGA) {
653 if(VDisplay == 864) ModeIndex = ModeIndex_1152x864[Depth];
654 }
655 break;
656 case 1280:
657 switch(VDisplay) {
658 case 720:
659 ModeIndex = ModeIndex_1280x720[Depth];
660 case 768:
661 if(VGAEngine == SIS_300_VGA) {
662 ModeIndex = ModeIndex_300_1280x768[Depth];
663 } else {
664 ModeIndex = ModeIndex_310_1280x768[Depth];
665 }
666 break;
667 case 800:
668 if(VGAEngine == SIS_315_VGA) {
669 ModeIndex = ModeIndex_1280x800[Depth];
670 }
671 break;
672 case 854:
673 if(VGAEngine == SIS_315_VGA) {
674 ModeIndex = ModeIndex_1280x854[Depth];
675 }
676 break;
677 case 960:
678 ModeIndex = ModeIndex_1280x960[Depth];
679 break;
680 case 1024:
681 ModeIndex = ModeIndex_1280x1024[Depth];
682 break;
683 }
684 break;
685 case 1360:
686 if(VGAEngine == SIS_315_VGA) {
687 if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth];
688 }
689 break;
690 case 1400:
691 if(VGAEngine == SIS_315_VGA) {
692 if(VBFlags2 & VB2_LCDOVER1280BRIDGE) {
693 if(VDisplay == 1050) ModeIndex = ModeIndex_1400x1050[Depth];
694 }
695 }
696 break;
697 case 1600:
698 if(VGAEngine == SIS_315_VGA) {
699 if(VBFlags2 & VB2_LCDOVER1280BRIDGE) {
700 if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
701 }
702 }
703 break;
704#ifndef VB_FORBID_CRT2LCD_OVER_1600
705 case 1680:
706 if(VGAEngine == SIS_315_VGA) {
707 if(VBFlags2 & VB2_LCDOVER1280BRIDGE) {
708 if(VDisplay == 1050) ModeIndex = ModeIndex_1680x1050[Depth];
709 }
710 }
711 break;
712 case 1920:
713 if(VGAEngine == SIS_315_VGA) {
714 if(VBFlags2 & VB2_LCDOVER1600BRIDGE) {
715 if(VDisplay == 1440) ModeIndex = ModeIndex_1920x1440[Depth];
716 }
717 }
718 break;
719 case 2048:
720 if(VGAEngine == SIS_315_VGA) {
721 if(VBFlags2 & VB2_LCDOVER1600BRIDGE) {
722 if(VDisplay == 1536) ModeIndex = ModeIndex_310_2048x1536[Depth];
723 }
724 }
725 break;
726#endif
727 }
728 }
729
730 return ModeIndex;
731}
732
733unsigned short
734SiS_GetModeID_TV(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay, int Depth,
735 unsigned int VBFlags2)
736{
737 unsigned short ModeIndex = 0;
738
739 if(VBFlags2 & VB2_CHRONTEL) {
740
741 switch(HDisplay)
742 {
743 case 512:
744 if(VGAEngine == SIS_315_VGA) {
745 if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
746 }
747 break;
748 case 640:
749 if(VDisplay == 480) ModeIndex = ModeIndex_640x480[Depth];
750 else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth];
751 break;
752 case 800:
753 if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
754 break;
755 case 1024:
756 if(VGAEngine == SIS_315_VGA) {
757 if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
758 }
759 break;
760 }
761
762 } else if(VBFlags2 & VB2_SISTVBRIDGE) {
763
764 switch(HDisplay)
765 {
766 case 320:
767 if(VDisplay == 200) ModeIndex = ModeIndex_320x200[Depth];
768 else if(VDisplay == 240) ModeIndex = ModeIndex_320x240[Depth];
769 break;
770 case 400:
771 if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
772 break;
773 case 512:
774 if( ((VBFlags & TV_YPBPR) && (VBFlags & (TV_YPBPR750P | TV_YPBPR1080I))) ||
775 (VBFlags & TV_HIVISION) ||
776 ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL)) ) {
777 if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
778 }
779 break;
780 case 640:
781 if(VDisplay == 480) ModeIndex = ModeIndex_640x480[Depth];
782 else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth];
783 break;
784 case 720:
785 if((!(VBFlags & TV_HIVISION)) && (!((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I)))) {
786 if(VDisplay == 480) {
787 ModeIndex = ModeIndex_720x480[Depth];
788 } else if(VDisplay == 576) {
789 if( ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR750P)) ||
790 ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL)) )
791 ModeIndex = ModeIndex_720x576[Depth];
792 }
793 }
794 break;
795 case 768:
796 if((!(VBFlags & TV_HIVISION)) && (!((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I)))) {
797 if( ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR750P)) ||
798 ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL)) ) {
799 if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
800 }
801 }
802 break;
803 case 800:
804 if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
805 else if(VDisplay == 480) {
806 if(!((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR750P))) {
807 ModeIndex = ModeIndex_800x480[Depth];
808 }
809 }
810 break;
811 case 960:
812 if(VGAEngine == SIS_315_VGA) {
813 if(VDisplay == 600) {
814 if((VBFlags & TV_HIVISION) || ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I))) {
815 ModeIndex = ModeIndex_960x600[Depth];
816 }
817 }
818 }
819 break;
820 case 1024:
821 if(VDisplay == 768) {
822 if(VBFlags2 & VB2_30xBLV) {
823 ModeIndex = ModeIndex_1024x768[Depth];
824 }
825 } else if(VDisplay == 576) {
826 if( (VBFlags & TV_HIVISION) ||
827 ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I)) ||
828 ((VBFlags2 & VB2_30xBLV) &&
829 ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL))) ) {
830 ModeIndex = ModeIndex_1024x576[Depth];
831 }
832 }
833 break;
834 case 1280:
835 if(VDisplay == 720) {
836 if((VBFlags & TV_HIVISION) ||
837 ((VBFlags & TV_YPBPR) && (VBFlags & (TV_YPBPR1080I | TV_YPBPR750P)))) {
838 ModeIndex = ModeIndex_1280x720[Depth];
839 }
840 } else if(VDisplay == 1024) {
841 if((VBFlags & TV_HIVISION) ||
842 ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I))) {
843 ModeIndex = ModeIndex_1280x1024[Depth];
844 }
845 }
846 break;
847 }
848 }
849 return ModeIndex;
850}
851
852unsigned short
853SiS_GetModeID_VGA2(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay, int Depth,
854 unsigned int VBFlags2)
855{
856 if(!(VBFlags2 & VB2_SISVGA2BRIDGE)) return 0;
857
858 if(HDisplay >= 1920) return 0;
859
860 switch(HDisplay)
861 {
862 case 1600:
863 if(VDisplay == 1200) {
864 if(VGAEngine != SIS_315_VGA) return 0;
865 if(!(VBFlags2 & VB2_30xB)) return 0;
866 }
867 break;
868 case 1680:
869 if(VDisplay == 1050) {
870 if(VGAEngine != SIS_315_VGA) return 0;
871 if(!(VBFlags2 & VB2_30xB)) return 0;
872 }
873 break;
874 }
875
876 return SiS_GetModeID(VGAEngine, 0, HDisplay, VDisplay, Depth, false, 0, 0);
877}
878
879
880
881
882
883
884void
885SiS_SetReg(SISIOADDRESS port, unsigned short index, unsigned short data)
886{
887 OutPortByte(port, index);
888 OutPortByte(port + 1, data);
889}
890
891void
892SiS_SetRegByte(SISIOADDRESS port, unsigned short data)
893{
894 OutPortByte(port, data);
895}
896
897void
898SiS_SetRegShort(SISIOADDRESS port, unsigned short data)
899{
900 OutPortWord(port, data);
901}
902
903void
904SiS_SetRegLong(SISIOADDRESS port, unsigned int data)
905{
906 OutPortLong(port, data);
907}
908
909unsigned char
910SiS_GetReg(SISIOADDRESS port, unsigned short index)
911{
912 OutPortByte(port, index);
913 return(InPortByte(port + 1));
914}
915
916unsigned char
917SiS_GetRegByte(SISIOADDRESS port)
918{
919 return(InPortByte(port));
920}
921
922unsigned short
923SiS_GetRegShort(SISIOADDRESS port)
924{
925 return(InPortWord(port));
926}
927
928unsigned int
929SiS_GetRegLong(SISIOADDRESS port)
930{
931 return(InPortLong(port));
932}
933
934void
935SiS_SetRegANDOR(SISIOADDRESS Port, unsigned short Index, unsigned short DataAND, unsigned short DataOR)
936{
937 unsigned short temp;
938
939 temp = SiS_GetReg(Port, Index);
940 temp = (temp & (DataAND)) | DataOR;
941 SiS_SetReg(Port, Index, temp);
942}
943
944void
945SiS_SetRegAND(SISIOADDRESS Port, unsigned short Index, unsigned short DataAND)
946{
947 unsigned short temp;
948
949 temp = SiS_GetReg(Port, Index);
950 temp &= DataAND;
951 SiS_SetReg(Port, Index, temp);
952}
953
954void
955SiS_SetRegOR(SISIOADDRESS Port, unsigned short Index, unsigned short DataOR)
956{
957 unsigned short temp;
958
959 temp = SiS_GetReg(Port, Index);
960 temp |= DataOR;
961 SiS_SetReg(Port, Index, temp);
962}
963
964
965
966
967
968void
969SiS_DisplayOn(struct SiS_Private *SiS_Pr)
970{
971 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x01,0xDF);
972}
973
974void
975SiS_DisplayOff(struct SiS_Private *SiS_Pr)
976{
977 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x01,0x20);
978}
979
980
981
982
983
984
985void
986SiSRegInit(struct SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr)
987{
988 SiS_Pr->SiS_P3c4 = BaseAddr + 0x14;
989 SiS_Pr->SiS_P3d4 = BaseAddr + 0x24;
990 SiS_Pr->SiS_P3c0 = BaseAddr + 0x10;
991 SiS_Pr->SiS_P3ce = BaseAddr + 0x1e;
992 SiS_Pr->SiS_P3c2 = BaseAddr + 0x12;
993 SiS_Pr->SiS_P3ca = BaseAddr + 0x1a;
994 SiS_Pr->SiS_P3c6 = BaseAddr + 0x16;
995 SiS_Pr->SiS_P3c7 = BaseAddr + 0x17;
996 SiS_Pr->SiS_P3c8 = BaseAddr + 0x18;
997 SiS_Pr->SiS_P3c9 = BaseAddr + 0x19;
998 SiS_Pr->SiS_P3cb = BaseAddr + 0x1b;
999 SiS_Pr->SiS_P3cc = BaseAddr + 0x1c;
1000 SiS_Pr->SiS_P3cd = BaseAddr + 0x1d;
1001 SiS_Pr->SiS_P3da = BaseAddr + 0x2a;
1002 SiS_Pr->SiS_Part1Port = BaseAddr + SIS_CRT2_PORT_04;
1003 SiS_Pr->SiS_Part2Port = BaseAddr + SIS_CRT2_PORT_10;
1004 SiS_Pr->SiS_Part3Port = BaseAddr + SIS_CRT2_PORT_12;
1005 SiS_Pr->SiS_Part4Port = BaseAddr + SIS_CRT2_PORT_14;
1006 SiS_Pr->SiS_Part5Port = BaseAddr + SIS_CRT2_PORT_14 + 2;
1007 SiS_Pr->SiS_DDC_Port = BaseAddr + 0x14;
1008 SiS_Pr->SiS_VidCapt = BaseAddr + SIS_VIDEO_CAPTURE;
1009 SiS_Pr->SiS_VidPlay = BaseAddr + SIS_VIDEO_PLAYBACK;
1010}
1011
1012
1013
1014
1015
1016static void
1017SiS_GetSysFlags(struct SiS_Private *SiS_Pr)
1018{
1019 unsigned char cr5f, temp1, temp2;
1020
1021
1022
1023 SiS_Pr->SiS_SensibleSR11 = false;
1024 SiS_Pr->SiS_MyCR63 = 0x63;
1025 if(SiS_Pr->ChipType >= SIS_330) {
1026 SiS_Pr->SiS_MyCR63 = 0x53;
1027 if(SiS_Pr->ChipType >= SIS_661) {
1028 SiS_Pr->SiS_SensibleSR11 = true;
1029 }
1030 }
1031
1032
1033
1034 SiS_Pr->SiS_SysFlags = 0;
1035 if(SiS_Pr->ChipType == SIS_650) {
1036 cr5f = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0;
1037 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x5c,0x07);
1038 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5c) & 0xf8;
1039 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x5c,0xf8);
1040 temp2 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5c) & 0xf8;
1041 if((!temp1) || (temp2)) {
1042 switch(cr5f) {
1043 case 0x80:
1044 case 0x90:
1045 case 0xc0:
1046 SiS_Pr->SiS_SysFlags |= SF_IsM650;
1047 break;
1048 case 0xa0:
1049 case 0xb0:
1050 case 0xe0:
1051 SiS_Pr->SiS_SysFlags |= SF_Is651;
1052 break;
1053 }
1054 } else {
1055 switch(cr5f) {
1056 case 0x90:
1057 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5c) & 0xf8;
1058 switch(temp1) {
1059 case 0x00: SiS_Pr->SiS_SysFlags |= SF_IsM652; break;
1060 case 0x40: SiS_Pr->SiS_SysFlags |= SF_IsM653; break;
1061 default: SiS_Pr->SiS_SysFlags |= SF_IsM650; break;
1062 }
1063 break;
1064 case 0xb0:
1065 SiS_Pr->SiS_SysFlags |= SF_Is652;
1066 break;
1067 default:
1068 SiS_Pr->SiS_SysFlags |= SF_IsM650;
1069 break;
1070 }
1071 }
1072 }
1073
1074 if(SiS_Pr->ChipType >= SIS_760 && SiS_Pr->ChipType <= SIS_761) {
1075 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0x30) {
1076 SiS_Pr->SiS_SysFlags |= SF_760LFB;
1077 }
1078 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0xf0) {
1079 SiS_Pr->SiS_SysFlags |= SF_760UMA;
1080 }
1081 }
1082}
1083
1084
1085
1086
1087
1088static void
1089SiSInitPCIetc(struct SiS_Private *SiS_Pr)
1090{
1091 switch(SiS_Pr->ChipType) {
1092#ifdef SIS300
1093 case SIS_300:
1094 case SIS_540:
1095 case SIS_630:
1096 case SIS_730:
1097
1098
1099
1100
1101
1102 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x20,0xa1);
1103
1104
1105
1106
1107
1108 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x5A);
1109 break;
1110#endif
1111#ifdef SIS315H
1112 case SIS_315H:
1113 case SIS_315:
1114 case SIS_315PRO:
1115 case SIS_650:
1116 case SIS_740:
1117 case SIS_330:
1118 case SIS_661:
1119 case SIS_741:
1120 case SIS_660:
1121 case SIS_760:
1122 case SIS_761:
1123 case SIS_340:
1124 case XGI_40:
1125
1126 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x20,0xa1);
1127
1128
1129
1130
1131
1132
1133 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0xDA);
1134 break;
1135 case XGI_20:
1136 case SIS_550:
1137
1138 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x20,0xa1);
1139
1140
1141
1142
1143 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1E,0x60,0x40);
1144 break;
1145#endif
1146 default:
1147 break;
1148 }
1149}
1150
1151
1152
1153
1154
1155#ifdef SIS_LINUX_KERNEL
1156static
1157#endif
1158void
1159SiSSetLVDSetc(struct SiS_Private *SiS_Pr)
1160{
1161 unsigned short temp;
1162
1163 SiS_Pr->SiS_IF_DEF_LVDS = 0;
1164 SiS_Pr->SiS_IF_DEF_TRUMPION = 0;
1165 SiS_Pr->SiS_IF_DEF_CH70xx = 0;
1166 SiS_Pr->SiS_IF_DEF_CONEX = 0;
1167
1168 SiS_Pr->SiS_ChrontelInit = 0;
1169
1170 if(SiS_Pr->ChipType == XGI_20) return;
1171
1172
1173 temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
1174 if((temp == 1) || (temp == 2)) return;
1175
1176 switch(SiS_Pr->ChipType) {
1177#ifdef SIS300
1178 case SIS_540:
1179 case SIS_630:
1180 case SIS_730:
1181 temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x37) & 0x0e) >> 1;
1182 if((temp >= 2) && (temp <= 5)) SiS_Pr->SiS_IF_DEF_LVDS = 1;
1183 if(temp == 3) SiS_Pr->SiS_IF_DEF_TRUMPION = 1;
1184 if((temp == 4) || (temp == 5)) {
1185
1186 SiS_Pr->SiS_Backup70xx = SiS_GetCH700x(SiS_Pr, 0x0e);
1187 SiS_Pr->SiS_IF_DEF_CH70xx = 1;
1188 }
1189 break;
1190#endif
1191#ifdef SIS315H
1192 case SIS_550:
1193 case SIS_650:
1194 case SIS_740:
1195 case SIS_330:
1196 temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x37) & 0x0e) >> 1;
1197 if((temp >= 2) && (temp <= 3)) SiS_Pr->SiS_IF_DEF_LVDS = 1;
1198 if(temp == 3) SiS_Pr->SiS_IF_DEF_CH70xx = 2;
1199 break;
1200 case SIS_661:
1201 case SIS_741:
1202 case SIS_660:
1203 case SIS_760:
1204 case SIS_761:
1205 case SIS_340:
1206 case XGI_20:
1207 case XGI_40:
1208 temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & 0xe0) >> 5;
1209 if((temp >= 2) && (temp <= 3)) SiS_Pr->SiS_IF_DEF_LVDS = 1;
1210 if(temp == 3) SiS_Pr->SiS_IF_DEF_CH70xx = 2;
1211 if(temp == 4) SiS_Pr->SiS_IF_DEF_CONEX = 1;
1212 break;
1213#endif
1214 default:
1215 break;
1216 }
1217}
1218
1219
1220
1221
1222
1223void
1224SiS_SetEnableDstn(struct SiS_Private *SiS_Pr, int enable)
1225{
1226 SiS_Pr->SiS_IF_DEF_DSTN = enable ? 1 : 0;
1227}
1228
1229void
1230SiS_SetEnableFstn(struct SiS_Private *SiS_Pr, int enable)
1231{
1232 SiS_Pr->SiS_IF_DEF_FSTN = enable ? 1 : 0;
1233}
1234
1235
1236
1237
1238
1239unsigned short
1240SiS_GetModeFlag(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
1241 unsigned short ModeIdIndex)
1242{
1243 if(SiS_Pr->UseCustomMode) {
1244 return SiS_Pr->CModeFlag;
1245 } else if(ModeNo <= 0x13) {
1246 return SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
1247 } else {
1248 return SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1249 }
1250}
1251
1252
1253
1254
1255
1256bool
1257SiSDetermineROMLayout661(struct SiS_Private *SiS_Pr)
1258{
1259 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
1260 unsigned short romversoffs, romvmaj = 1, romvmin = 0;
1261
1262 if(SiS_Pr->ChipType >= XGI_20) {
1263
1264 return false;
1265 } else if(SiS_Pr->ChipType >= SIS_761) {
1266
1267 return true;
1268 } else if(SiS_Pr->ChipType >= SIS_661) {
1269 if((ROMAddr[0x1a] == 'N') &&
1270 (ROMAddr[0x1b] == 'e') &&
1271 (ROMAddr[0x1c] == 'w') &&
1272 (ROMAddr[0x1d] == 'V')) {
1273 return true;
1274 }
1275 romversoffs = ROMAddr[0x16] | (ROMAddr[0x17] << 8);
1276 if(romversoffs) {
1277 if((ROMAddr[romversoffs+1] == '.') || (ROMAddr[romversoffs+4] == '.')) {
1278 romvmaj = ROMAddr[romversoffs] - '0';
1279 romvmin = ((ROMAddr[romversoffs+2] -'0') * 10) + (ROMAddr[romversoffs+3] - '0');
1280 }
1281 }
1282 if((romvmaj != 0) || (romvmin >= 92)) {
1283 return true;
1284 }
1285 } else if(IS_SIS650740) {
1286 if((ROMAddr[0x1a] == 'N') &&
1287 (ROMAddr[0x1b] == 'e') &&
1288 (ROMAddr[0x1c] == 'w') &&
1289 (ROMAddr[0x1d] == 'V')) {
1290 return true;
1291 }
1292 }
1293 return false;
1294}
1295
1296static void
1297SiSDetermineROMUsage(struct SiS_Private *SiS_Pr)
1298{
1299 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
1300 unsigned short romptr = 0;
1301
1302 SiS_Pr->SiS_UseROM = false;
1303 SiS_Pr->SiS_ROMNew = false;
1304 SiS_Pr->SiS_PWDOffset = 0;
1305
1306 if(SiS_Pr->ChipType >= XGI_20) return;
1307
1308 if((ROMAddr) && (SiS_Pr->UseROM)) {
1309 if(SiS_Pr->ChipType == SIS_300) {
1310
1311
1312
1313
1314 if((ROMAddr[3] == 0xe9) && ((ROMAddr[5] << 8) | ROMAddr[4]) > 0x21a)
1315 SiS_Pr->SiS_UseROM = true;
1316 } else if(SiS_Pr->ChipType < SIS_315H) {
1317
1318
1319
1320 SiS_Pr->SiS_UseROM = true;
1321 } else {
1322
1323 SiS_Pr->SiS_UseROM = true;
1324 if((SiS_Pr->SiS_ROMNew = SiSDetermineROMLayout661(SiS_Pr))) {
1325 SiS_Pr->SiS_EMIOffset = 14;
1326 SiS_Pr->SiS_PWDOffset = 17;
1327 SiS_Pr->SiS661LCD2TableSize = 36;
1328
1329 if((romptr = SISGETROMW(0x0102))) {
1330 if(ROMAddr[romptr + (32 * 16)] == 0xff)
1331 SiS_Pr->SiS661LCD2TableSize = 32;
1332 else if(ROMAddr[romptr + (34 * 16)] == 0xff)
1333 SiS_Pr->SiS661LCD2TableSize = 34;
1334 else if(ROMAddr[romptr + (36 * 16)] == 0xff)
1335 SiS_Pr->SiS661LCD2TableSize = 36;
1336 else if( (ROMAddr[romptr + (38 * 16)] == 0xff) ||
1337 (ROMAddr[0x6F] & 0x01) ) {
1338 SiS_Pr->SiS661LCD2TableSize = 38;
1339 SiS_Pr->SiS_EMIOffset = 16;
1340 SiS_Pr->SiS_PWDOffset = 19;
1341 }
1342 }
1343 }
1344 }
1345 }
1346}
1347
1348
1349
1350
1351
1352static void
1353SiS_SetSegRegLower(struct SiS_Private *SiS_Pr, unsigned short value)
1354{
1355 unsigned short temp;
1356
1357 value &= 0x00ff;
1358 temp = SiS_GetRegByte(SiS_Pr->SiS_P3cb) & 0xf0;
1359 temp |= (value >> 4);
1360 SiS_SetRegByte(SiS_Pr->SiS_P3cb, temp);
1361 temp = SiS_GetRegByte(SiS_Pr->SiS_P3cd) & 0xf0;
1362 temp |= (value & 0x0f);
1363 SiS_SetRegByte(SiS_Pr->SiS_P3cd, temp);
1364}
1365
1366static void
1367SiS_SetSegRegUpper(struct SiS_Private *SiS_Pr, unsigned short value)
1368{
1369 unsigned short temp;
1370
1371 value &= 0x00ff;
1372 temp = SiS_GetRegByte(SiS_Pr->SiS_P3cb) & 0x0f;
1373 temp |= (value & 0xf0);
1374 SiS_SetRegByte(SiS_Pr->SiS_P3cb, temp);
1375 temp = SiS_GetRegByte(SiS_Pr->SiS_P3cd) & 0x0f;
1376 temp |= (value << 4);
1377 SiS_SetRegByte(SiS_Pr->SiS_P3cd, temp);
1378}
1379
1380static void
1381SiS_SetSegmentReg(struct SiS_Private *SiS_Pr, unsigned short value)
1382{
1383 SiS_SetSegRegLower(SiS_Pr, value);
1384 SiS_SetSegRegUpper(SiS_Pr, value);
1385}
1386
1387static void
1388SiS_ResetSegmentReg(struct SiS_Private *SiS_Pr)
1389{
1390 SiS_SetSegmentReg(SiS_Pr, 0);
1391}
1392
1393static void
1394SiS_SetSegmentRegOver(struct SiS_Private *SiS_Pr, unsigned short value)
1395{
1396 unsigned short temp = value >> 8;
1397
1398 temp &= 0x07;
1399 temp |= (temp << 4);
1400 SiS_SetReg(SiS_Pr->SiS_P3c4,0x1d,temp);
1401 SiS_SetSegmentReg(SiS_Pr, value);
1402}
1403
1404static void
1405SiS_ResetSegmentRegOver(struct SiS_Private *SiS_Pr)
1406{
1407 SiS_SetSegmentRegOver(SiS_Pr, 0);
1408}
1409
1410static void
1411SiS_ResetSegmentRegisters(struct SiS_Private *SiS_Pr)
1412{
1413 if((IS_SIS65x) || (SiS_Pr->ChipType >= SIS_661)) {
1414 SiS_ResetSegmentReg(SiS_Pr);
1415 SiS_ResetSegmentRegOver(SiS_Pr);
1416 }
1417}
1418
1419
1420
1421
1422
1423#ifdef SIS_LINUX_KERNEL
1424static
1425#endif
1426void
1427SiS_GetVBType(struct SiS_Private *SiS_Pr)
1428{
1429 unsigned short flag = 0, rev = 0, nolcd = 0;
1430 unsigned short p4_0f, p4_25, p4_27;
1431
1432 SiS_Pr->SiS_VBType = 0;
1433
1434 if((SiS_Pr->SiS_IF_DEF_LVDS) || (SiS_Pr->SiS_IF_DEF_CONEX))
1435 return;
1436
1437 if(SiS_Pr->ChipType == XGI_20)
1438 return;
1439
1440 flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
1441
1442 if(flag > 3)
1443 return;
1444
1445 rev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01);
1446
1447 if(flag >= 2) {
1448 SiS_Pr->SiS_VBType = VB_SIS302B;
1449 } else if(flag == 1) {
1450 if(rev >= 0xC0) {
1451 SiS_Pr->SiS_VBType = VB_SIS301C;
1452 } else if(rev >= 0xB0) {
1453 SiS_Pr->SiS_VBType = VB_SIS301B;
1454
1455 nolcd = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x23);
1456 if(!(nolcd & 0x02)) SiS_Pr->SiS_VBType |= VB_NoLCD;
1457 } else {
1458 SiS_Pr->SiS_VBType = VB_SIS301;
1459 }
1460 }
1461 if(SiS_Pr->SiS_VBType & (VB_SIS301B | VB_SIS301C | VB_SIS302B)) {
1462 if(rev >= 0xE0) {
1463 flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x39);
1464 if(flag == 0xff) SiS_Pr->SiS_VBType = VB_SIS302LV;
1465 else SiS_Pr->SiS_VBType = VB_SIS301C;
1466 } else if(rev >= 0xD0) {
1467 SiS_Pr->SiS_VBType = VB_SIS301LV;
1468 }
1469 }
1470 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV)) {
1471 p4_0f = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x0f);
1472 p4_25 = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x25);
1473 p4_27 = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x27);
1474 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0x7f);
1475 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x25,0x08);
1476 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,0xfd);
1477 if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x08) {
1478 SiS_Pr->SiS_VBType |= VB_UMC;
1479 }
1480 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x27,p4_27);
1481 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x25,p4_25);
1482 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0f,p4_0f);
1483 }
1484}
1485
1486
1487
1488
1489
1490#ifdef SIS_LINUX_KERNEL
1491static bool
1492SiS_CheckMemorySize(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
1493 unsigned short ModeIdIndex)
1494{
1495 unsigned short AdapterMemSize = SiS_Pr->VideoMemorySize / (1024*1024);
1496 unsigned short modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
1497 unsigned short memorysize = ((modeflag & MemoryInfoFlag) >> MemorySizeShift) + 1;
1498
1499 if(!AdapterMemSize) return true;
1500
1501 if(AdapterMemSize < memorysize) return false;
1502 return true;
1503}
1504#endif
1505
1506
1507
1508
1509
1510#ifdef SIS315H
1511static unsigned char
1512SiS_Get310DRAMType(struct SiS_Private *SiS_Pr)
1513{
1514 unsigned char data;
1515
1516 if((*SiS_Pr->pSiS_SoftSetting) & SoftDRAMType) {
1517 data = (*SiS_Pr->pSiS_SoftSetting) & 0x03;
1518 } else {
1519 if(SiS_Pr->ChipType >= XGI_20) {
1520
1521 data = 0;
1522 } else if(SiS_Pr->ChipType >= SIS_340) {
1523
1524 data = 0;
1525 } if(SiS_Pr->ChipType >= SIS_661) {
1526 if(SiS_Pr->SiS_ROMNew) {
1527 data = ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0xc0) >> 6);
1528 } else {
1529 data = SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0x07;
1530 }
1531 } else if(IS_SIS550650740) {
1532 data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x07;
1533 } else {
1534 data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3a) & 0x03;
1535 if(SiS_Pr->ChipType == SIS_330) {
1536 if(data > 1) {
1537 switch(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0x30) {
1538 case 0x00: data = 1; break;
1539 case 0x10: data = 3; break;
1540 case 0x20: data = 3; break;
1541 case 0x30: data = 2; break;
1542 }
1543 } else {
1544 data = 0;
1545 }
1546 }
1547 }
1548 }
1549
1550 return data;
1551}
1552
1553static unsigned short
1554SiS_GetMCLK(struct SiS_Private *SiS_Pr)
1555{
1556 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
1557 unsigned short index;
1558
1559 index = SiS_Get310DRAMType(SiS_Pr);
1560 if(SiS_Pr->ChipType >= SIS_661) {
1561 if(SiS_Pr->SiS_ROMNew) {
1562 return((unsigned short)(SISGETROMW((0x90 + (index * 5) + 3))));
1563 }
1564 return(SiS_Pr->SiS_MCLKData_0[index].CLOCK);
1565 } else if(index >= 4) {
1566 return(SiS_Pr->SiS_MCLKData_1[index - 4].CLOCK);
1567 } else {
1568 return(SiS_Pr->SiS_MCLKData_0[index].CLOCK);
1569 }
1570}
1571#endif
1572
1573
1574
1575
1576
1577#ifdef SIS_LINUX_KERNEL
1578static void
1579SiS_ClearBuffer(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
1580{
1581 unsigned char SISIOMEMTYPE *memaddr = SiS_Pr->VideoMemoryAddress;
1582 unsigned int memsize = SiS_Pr->VideoMemorySize;
1583 unsigned short SISIOMEMTYPE *pBuffer;
1584 int i;
1585
1586 if(!memaddr || !memsize) return;
1587
1588 if(SiS_Pr->SiS_ModeType >= ModeEGA) {
1589 if(ModeNo > 0x13) {
1590 SiS_SetMemory(memaddr, memsize, 0);
1591 } else {
1592 pBuffer = (unsigned short SISIOMEMTYPE *)memaddr;
1593 for(i = 0; i < 0x4000; i++) writew(0x0000, &pBuffer[i]);
1594 }
1595 } else if(SiS_Pr->SiS_ModeType < ModeCGA) {
1596 pBuffer = (unsigned short SISIOMEMTYPE *)memaddr;
1597 for(i = 0; i < 0x4000; i++) writew(0x0720, &pBuffer[i]);
1598 } else {
1599 SiS_SetMemory(memaddr, 0x8000, 0);
1600 }
1601}
1602#endif
1603
1604
1605
1606
1607
1608bool
1609SiS_SearchModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo,
1610 unsigned short *ModeIdIndex)
1611{
1612 unsigned char VGAINFO = SiS_Pr->SiS_VGAINFO;
1613
1614 if((*ModeNo) <= 0x13) {
1615
1616 if((*ModeNo) <= 0x05) (*ModeNo) |= 0x01;
1617
1618 for((*ModeIdIndex) = 0; ;(*ModeIdIndex)++) {
1619 if(SiS_Pr->SiS_SModeIDTable[(*ModeIdIndex)].St_ModeID == (*ModeNo)) break;
1620 if(SiS_Pr->SiS_SModeIDTable[(*ModeIdIndex)].St_ModeID == 0xFF) return false;
1621 }
1622
1623 if((*ModeNo) == 0x07) {
1624 if(VGAINFO & 0x10) (*ModeIdIndex)++;
1625
1626 }
1627 if((*ModeNo) <= 0x03) {
1628 if(!(VGAINFO & 0x80)) (*ModeIdIndex)++;
1629 if(VGAINFO & 0x10) (*ModeIdIndex)++;
1630
1631 }
1632
1633
1634 } else {
1635
1636 for((*ModeIdIndex) = 0; ;(*ModeIdIndex)++) {
1637 if(SiS_Pr->SiS_EModeIDTable[(*ModeIdIndex)].Ext_ModeID == (*ModeNo)) break;
1638 if(SiS_Pr->SiS_EModeIDTable[(*ModeIdIndex)].Ext_ModeID == 0xFF) return false;
1639 }
1640
1641 }
1642 return true;
1643}
1644
1645
1646
1647
1648
1649unsigned short
1650SiS_GetModePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
1651{
1652 unsigned short index;
1653
1654 if(ModeNo <= 0x13) {
1655 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_StTableIndex;
1656 } else {
1657 if(SiS_Pr->SiS_ModeType <= ModeEGA) index = 0x1B;
1658 else index = 0x0F;
1659 }
1660 return index;
1661}
1662
1663
1664
1665
1666
1667unsigned short
1668SiS_GetRefCRTVCLK(struct SiS_Private *SiS_Pr, unsigned short Index, int UseWide)
1669{
1670 if(SiS_Pr->SiS_RefIndex[Index].Ext_InfoFlag & HaveWideTiming) {
1671 if(UseWide == 1) {
1672 return SiS_Pr->SiS_RefIndex[Index].Ext_CRTVCLK_WIDE;
1673 } else {
1674 return SiS_Pr->SiS_RefIndex[Index].Ext_CRTVCLK_NORM;
1675 }
1676 } else {
1677 return SiS_Pr->SiS_RefIndex[Index].Ext_CRTVCLK;
1678 }
1679}
1680
1681unsigned short
1682SiS_GetRefCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short Index, int UseWide)
1683{
1684 if(SiS_Pr->SiS_RefIndex[Index].Ext_InfoFlag & HaveWideTiming) {
1685 if(UseWide == 1) {
1686 return SiS_Pr->SiS_RefIndex[Index].Ext_CRT1CRTC_WIDE;
1687 } else {
1688 return SiS_Pr->SiS_RefIndex[Index].Ext_CRT1CRTC_NORM;
1689 }
1690 } else {
1691 return SiS_Pr->SiS_RefIndex[Index].Ext_CRT1CRTC;
1692 }
1693}
1694
1695
1696
1697
1698
1699static bool
1700SiS_DoLowModeTest(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
1701{
1702 unsigned short temp, temp1, temp2;
1703
1704 if((ModeNo != 0x03) && (ModeNo != 0x10) && (ModeNo != 0x12))
1705 return true;
1706 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x11);
1707 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x11,0x80);
1708 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x00);
1709 SiS_SetReg(SiS_Pr->SiS_P3d4,0x00,0x55);
1710 temp2 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x00);
1711 SiS_SetReg(SiS_Pr->SiS_P3d4,0x00,temp1);
1712 SiS_SetReg(SiS_Pr->SiS_P3d4,0x11,temp);
1713 if((SiS_Pr->ChipType >= SIS_315H) ||
1714 (SiS_Pr->ChipType == SIS_300)) {
1715 if(temp2 == 0x55) return false;
1716 else return true;
1717 } else {
1718 if(temp2 != 0x55) return true;
1719 else {
1720 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01);
1721 return false;
1722 }
1723 }
1724}
1725
1726static void
1727SiS_SetLowModeTest(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
1728{
1729 if(SiS_DoLowModeTest(SiS_Pr, ModeNo)) {
1730 SiS_Pr->SiS_SetFlag |= LowModeTests;
1731 }
1732}
1733
1734
1735
1736
1737
1738static void
1739SiS_OpenCRTC(struct SiS_Private *SiS_Pr)
1740{
1741 if(IS_SIS650) {
1742 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
1743 if(IS_SIS651) SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x51,0x20);
1744 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
1745 } else if(IS_SIS661741660760) {
1746 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x61,0xf7);
1747 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
1748 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
1749 if(!SiS_Pr->SiS_ROMNew) {
1750 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x3a,0xef);
1751 }
1752 }
1753}
1754
1755static void
1756SiS_CloseCRTC(struct SiS_Private *SiS_Pr)
1757{
1758#if 0
1759 unsigned short temp1 = 0, temp2 = 0;
1760
1761 if(IS_SIS661741660760) {
1762 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
1763 temp1 = 0xa0; temp2 = 0x08;
1764 }
1765 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x51,0x1f,temp1);
1766 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x56,0xe7,temp2);
1767 }
1768#endif
1769}
1770
1771static void
1772SiS_HandleCRT1(struct SiS_Private *SiS_Pr)
1773{
1774
1775 SiS_SetRegAND(SiS_Pr->SiS_P3d4,SiS_Pr->SiS_MyCR63,0xbf);
1776#if 0
1777 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x15) & 0x01)) {
1778 if((SiS_GetReg(SiS_Pr->SiS_P3c4,0x15) & 0x0a) ||
1779 (SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x01)) {
1780 SiS_SetRegOR(SiS_Pr->SiS_P3d4,SiS_Pr->SiS_MyCR63,0x40);
1781 }
1782 }
1783#endif
1784}
1785
1786
1787
1788
1789
1790unsigned short
1791SiS_GetColorDepth(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
1792 unsigned short ModeIdIndex)
1793{
1794 static const unsigned short ColorDepth[6] = { 1, 2, 4, 4, 6, 8 };
1795 unsigned short modeflag;
1796 short index;
1797
1798
1799 if(ModeNo == 0xfe) {
1800 modeflag = SiS_Pr->CModeFlag;
1801 } else if(ModeNo <= 0x13) {
1802 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
1803 } else {
1804 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1805 }
1806
1807 index = (modeflag & ModeTypeMask) - ModeEGA;
1808 if(index < 0) index = 0;
1809 return ColorDepth[index];
1810}
1811
1812
1813
1814
1815
1816unsigned short
1817SiS_GetOffset(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
1818 unsigned short ModeIdIndex, unsigned short RRTI)
1819{
1820 unsigned short xres, temp, colordepth, infoflag;
1821
1822 if(SiS_Pr->UseCustomMode) {
1823 infoflag = SiS_Pr->CInfoFlag;
1824 xres = SiS_Pr->CHDisplay;
1825 } else {
1826 infoflag = SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag;
1827 xres = SiS_Pr->SiS_RefIndex[RRTI].XRes;
1828 }
1829
1830 colordepth = SiS_GetColorDepth(SiS_Pr, ModeNo, ModeIdIndex);
1831
1832 temp = xres / 16;
1833 if(infoflag & InterlaceMode) temp <<= 1;
1834 temp *= colordepth;
1835 if(xres % 16) temp += (colordepth >> 1);
1836
1837 return temp;
1838}
1839
1840
1841
1842
1843
1844static void
1845SiS_SetSeqRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex)
1846{
1847 unsigned char SRdata;
1848 int i;
1849
1850 SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x03);
1851
1852
1853 SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[0] | 0x20;
1854
1855
1856 if((SiS_Pr->SiS_VBType & VB_SISVB) || (SiS_Pr->SiS_IF_DEF_LVDS)) {
1857
1858 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
1859 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) SRdata |= 0x01;
1860 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) SRdata |= 0x01;
1861
1862 }
1863
1864 SiS_SetReg(SiS_Pr->SiS_P3c4,0x01,SRdata);
1865
1866 for(i = 2; i <= 4; i++) {
1867 SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[i - 1];
1868 SiS_SetReg(SiS_Pr->SiS_P3c4,i,SRdata);
1869 }
1870}
1871
1872
1873
1874
1875
1876static void
1877SiS_SetMiscRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex)
1878{
1879 unsigned char Miscdata;
1880
1881 Miscdata = SiS_Pr->SiS_StandTable[StandTableIndex].MISC;
1882
1883 if(SiS_Pr->ChipType < SIS_661) {
1884 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
1885 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
1886 Miscdata |= 0x0C;
1887 }
1888 }
1889 }
1890
1891 SiS_SetRegByte(SiS_Pr->SiS_P3c2,Miscdata);
1892}
1893
1894
1895
1896
1897
1898static void
1899SiS_SetCRTCRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex)
1900{
1901 unsigned char CRTCdata;
1902 unsigned short i;
1903
1904
1905 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
1906
1907 for(i = 0; i <= 0x18; i++) {
1908 CRTCdata = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[i];
1909 SiS_SetReg(SiS_Pr->SiS_P3d4,i,CRTCdata);
1910 }
1911
1912 if(SiS_Pr->ChipType >= SIS_661) {
1913 SiS_OpenCRTC(SiS_Pr);
1914 for(i = 0x13; i <= 0x14; i++) {
1915 CRTCdata = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[i];
1916 SiS_SetReg(SiS_Pr->SiS_P3d4,i,CRTCdata);
1917 }
1918 } else if( ( (SiS_Pr->ChipType == SIS_630) ||
1919 (SiS_Pr->ChipType == SIS_730) ) &&
1920 (SiS_Pr->ChipRevision >= 0x30) ) {
1921 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
1922 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
1923 SiS_SetReg(SiS_Pr->SiS_P3d4,0x18,0xFE);
1924 }
1925 }
1926 }
1927}
1928
1929
1930
1931
1932
1933static void
1934SiS_SetATTRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex)
1935{
1936 unsigned char ARdata;
1937 unsigned short i;
1938
1939 for(i = 0; i <= 0x13; i++) {
1940 ARdata = SiS_Pr->SiS_StandTable[StandTableIndex].ATTR[i];
1941
1942 if(i == 0x13) {
1943
1944
1945
1946 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
1947 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) ARdata = 0;
1948 }
1949 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1950 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1951 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
1952 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata = 0;
1953 }
1954 }
1955 }
1956 if(SiS_Pr->ChipType >= SIS_661) {
1957 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD)) {
1958 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata = 0;
1959 }
1960 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
1961 if(SiS_Pr->ChipType >= SIS_315H) {
1962 if(IS_SIS550650740660) {
1963
1964 if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
1965 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata = 0;
1966 } else {
1967 ARdata = 0;
1968 }
1969 }
1970 } else {
1971 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata = 0;
1972 }
1973 }
1974 }
1975 SiS_GetRegByte(SiS_Pr->SiS_P3da);
1976 SiS_SetRegByte(SiS_Pr->SiS_P3c0,i);
1977 SiS_SetRegByte(SiS_Pr->SiS_P3c0,ARdata);
1978 }
1979
1980 SiS_GetRegByte(SiS_Pr->SiS_P3da);
1981 SiS_SetRegByte(SiS_Pr->SiS_P3c0,0x14);
1982 SiS_SetRegByte(SiS_Pr->SiS_P3c0,0x00);
1983
1984 SiS_GetRegByte(SiS_Pr->SiS_P3da);
1985 SiS_SetRegByte(SiS_Pr->SiS_P3c0,0x20);
1986 SiS_GetRegByte(SiS_Pr->SiS_P3da);
1987}
1988
1989
1990
1991
1992
1993static void
1994SiS_SetGRCRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex)
1995{
1996 unsigned char GRdata;
1997 unsigned short i;
1998
1999 for(i = 0; i <= 0x08; i++) {
2000 GRdata = SiS_Pr->SiS_StandTable[StandTableIndex].GRC[i];
2001 SiS_SetReg(SiS_Pr->SiS_P3ce,i,GRdata);
2002 }
2003
2004 if(SiS_Pr->SiS_ModeType > ModeVGA) {
2005
2006 SiS_SetRegAND(SiS_Pr->SiS_P3ce,0x05,0xBF);
2007 }
2008}
2009
2010
2011
2012
2013
2014static void
2015SiS_ClearExt1Regs(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
2016{
2017 unsigned short i;
2018
2019 for(i = 0x0A; i <= 0x0E; i++) {
2020 SiS_SetReg(SiS_Pr->SiS_P3c4,i,0x00);
2021 }
2022
2023 if(SiS_Pr->ChipType >= SIS_315H) {
2024 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x37,0xFE);
2025 if(ModeNo <= 0x13) {
2026 if(ModeNo == 0x06 || ModeNo >= 0x0e) {
2027 SiS_SetReg(SiS_Pr->SiS_P3c4,0x0e,0x20);
2028 }
2029 }
2030 }
2031}
2032
2033
2034
2035
2036
2037static void
2038SiS_ResetCRT1VCLK(struct SiS_Private *SiS_Pr)
2039{
2040 if(SiS_Pr->ChipType >= SIS_315H) {
2041 if(SiS_Pr->ChipType < SIS_661) {
2042 if(SiS_Pr->SiS_IF_DEF_LVDS == 0) return;
2043 }
2044 } else {
2045 if((SiS_Pr->SiS_IF_DEF_LVDS == 0) &&
2046 (!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) ) {
2047 return;
2048 }
2049 }
2050
2051 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x31,0xcf,0x20);
2052 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VCLKData[1].SR2B);
2053 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VCLKData[1].SR2C);
2054 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x80);
2055 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x31,0xcf,0x10);
2056 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VCLKData[0].SR2B);
2057 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VCLKData[0].SR2C);
2058 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x80);
2059}
2060
2061
2062
2063
2064
2065static void
2066SiS_SetCRT1Sync(struct SiS_Private *SiS_Pr, unsigned short RRTI)
2067{
2068 unsigned short sync;
2069
2070 if(SiS_Pr->UseCustomMode) {
2071 sync = SiS_Pr->CInfoFlag >> 8;
2072 } else {
2073 sync = SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag >> 8;
2074 }
2075
2076 sync &= 0xC0;
2077 sync |= 0x2f;
2078 SiS_SetRegByte(SiS_Pr->SiS_P3c2,sync);
2079}
2080
2081
2082
2083
2084
2085static void
2086SiS_SetCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
2087 unsigned short ModeIdIndex, unsigned short RRTI)
2088{
2089 unsigned short temp, i, j, modeflag;
2090 unsigned char *crt1data = NULL;
2091
2092 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
2093
2094 if(SiS_Pr->UseCustomMode) {
2095
2096 crt1data = &SiS_Pr->CCRT1CRTC[0];
2097
2098 } else {
2099
2100 temp = SiS_GetRefCRT1CRTC(SiS_Pr, RRTI, SiS_Pr->SiS_UseWide);
2101
2102
2103 if((temp == 0x20) && (SiS_Pr->Alternate1600x1200)) temp = 0x57;
2104
2105 crt1data = (unsigned char *)&SiS_Pr->SiS_CRT1Table[temp].CR[0];
2106
2107 }
2108
2109
2110 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
2111
2112 for(i = 0, j = 0; i <= 7; i++, j++) {
2113 SiS_SetReg(SiS_Pr->SiS_P3d4,j,crt1data[i]);
2114 }
2115 for(j = 0x10; i <= 10; i++, j++) {
2116 SiS_SetReg(SiS_Pr->SiS_P3d4,j,crt1data[i]);
2117 }
2118 for(j = 0x15; i <= 12; i++, j++) {
2119 SiS_SetReg(SiS_Pr->SiS_P3d4,j,crt1data[i]);
2120 }
2121 for(j = 0x0A; i <= 15; i++, j++) {
2122 SiS_SetReg(SiS_Pr->SiS_P3c4,j,crt1data[i]);
2123 }
2124
2125 SiS_SetReg(SiS_Pr->SiS_P3c4,0x0E,crt1data[16] & 0xE0);
2126
2127 temp = (crt1data[16] & 0x01) << 5;
2128 if(modeflag & DoubleScanMode) temp |= 0x80;
2129 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0x5F,temp);
2130
2131 if(SiS_Pr->SiS_ModeType > ModeVGA) {
2132 SiS_SetReg(SiS_Pr->SiS_P3d4,0x14,0x4F);
2133 }
2134
2135#ifdef SIS315H
2136 if(SiS_Pr->ChipType == XGI_20) {
2137 SiS_SetReg(SiS_Pr->SiS_P3d4,0x04,crt1data[4] - 1);
2138 if(!(temp = crt1data[5] & 0x1f)) {
2139 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x0c,0xfb);
2140 }
2141 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x05,0xe0,((temp - 1) & 0x1f));
2142 temp = (crt1data[16] >> 5) + 3;
2143 if(temp > 7) temp -= 7;
2144 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0e,0x1f,(temp << 5));
2145 }
2146#endif
2147}
2148
2149
2150
2151
2152
2153
2154
2155static void
2156SiS_SetCRT1Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
2157 unsigned short ModeIdIndex, unsigned short RRTI)
2158{
2159 unsigned short temp, DisplayUnit, infoflag;
2160
2161 if(SiS_Pr->UseCustomMode) {
2162 infoflag = SiS_Pr->CInfoFlag;
2163 } else {
2164 infoflag = SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag;
2165 }
2166
2167 DisplayUnit = SiS_GetOffset(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
2168
2169 temp = (DisplayUnit >> 8) & 0x0f;
2170 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0xF0,temp);
2171
2172 SiS_SetReg(SiS_Pr->SiS_P3d4,0x13,DisplayUnit & 0xFF);
2173
2174 if(infoflag & InterlaceMode) DisplayUnit >>= 1;
2175
2176 DisplayUnit <<= 5;
2177 temp = (DisplayUnit >> 8) + 1;
2178 if(DisplayUnit & 0xff) temp++;
2179 if(SiS_Pr->ChipType == XGI_20) {
2180 if(ModeNo == 0x4a || ModeNo == 0x49) temp--;
2181 }
2182 SiS_SetReg(SiS_Pr->SiS_P3c4,0x10,temp);
2183}
2184
2185
2186
2187
2188
2189static void
2190SiS_SetCRT1VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
2191 unsigned short ModeIdIndex, unsigned short RRTI)
2192{
2193 unsigned short index = 0, clka, clkb;
2194
2195 if(SiS_Pr->UseCustomMode) {
2196 clka = SiS_Pr->CSR2B;
2197 clkb = SiS_Pr->CSR2C;
2198 } else {
2199 index = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
2200 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) &&
2201 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2202
2203 if((index == 0x21) && (SiS_Pr->Alternate1600x1200)) index = 0x72;
2204 clka = SiS_Pr->SiS_VBVCLKData[index].Part4_A;
2205 clkb = SiS_Pr->SiS_VBVCLKData[index].Part4_B;
2206 } else {
2207 clka = SiS_Pr->SiS_VCLKData[index].SR2B;
2208 clkb = SiS_Pr->SiS_VCLKData[index].SR2C;
2209 }
2210 }
2211
2212 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x31,0xCF);
2213
2214 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2b,clka);
2215 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2c,clkb);
2216
2217 if(SiS_Pr->ChipType >= SIS_315H) {
2218#ifdef SIS315H
2219 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x01);
2220 if(SiS_Pr->ChipType == XGI_20) {
2221 unsigned short mf = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
2222 if(mf & HalfDCLK) {
2223 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2b,SiS_GetReg(SiS_Pr->SiS_P3c4,0x2b));
2224 clkb = SiS_GetReg(SiS_Pr->SiS_P3c4,0x2c);
2225 clkb = (((clkb & 0x1f) << 1) + 1) | (clkb & 0xe0);
2226 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2c,clkb);
2227 }
2228 }
2229#endif
2230 } else {
2231 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x80);
2232 }
2233}
2234
2235
2236
2237
2238
2239#ifdef SIS300
2240void
2241SiS_GetFIFOThresholdIndex300(struct SiS_Private *SiS_Pr, unsigned short *idx1,
2242 unsigned short *idx2)
2243{
2244 unsigned short temp1, temp2;
2245 static const unsigned char ThTiming[8] = {
2246 1, 2, 2, 3, 0, 1, 1, 2
2247 };
2248
2249 temp1 = temp2 = (SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x62) >> 1;
2250 (*idx2) = (unsigned short)(ThTiming[((temp2 >> 3) | temp1) & 0x07]);
2251 (*idx1) = (unsigned short)(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) >> 6) & 0x03;
2252 (*idx1) |= (unsigned short)(((SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) >> 4) & 0x0c));
2253 (*idx1) <<= 1;
2254}
2255
2256static unsigned short
2257SiS_GetFIFOThresholdA300(unsigned short idx1, unsigned short idx2)
2258{
2259 static const unsigned char ThLowA[8 * 3] = {
2260 61, 3,52, 5,68, 7,100,11,
2261 43, 3,42, 5,54, 7, 78,11,
2262 34, 3,37, 5,47, 7, 67,11
2263 };
2264
2265 return (unsigned short)((ThLowA[idx1 + 1] * idx2) + ThLowA[idx1]);
2266}
2267
2268unsigned short
2269SiS_GetFIFOThresholdB300(unsigned short idx1, unsigned short idx2)
2270{
2271 static const unsigned char ThLowB[8 * 3] = {
2272 81, 4,72, 6,88, 8,120,12,
2273 55, 4,54, 6,66, 8, 90,12,
2274 42, 4,45, 6,55, 8, 75,12
2275 };
2276
2277 return (unsigned short)((ThLowB[idx1 + 1] * idx2) + ThLowB[idx1]);
2278}
2279
2280static unsigned short
2281SiS_DoCalcDelay(struct SiS_Private *SiS_Pr, unsigned short MCLK, unsigned short VCLK,
2282 unsigned short colordepth, unsigned short key)
2283{
2284 unsigned short idx1, idx2;
2285 unsigned int longtemp = VCLK * colordepth;
2286
2287 SiS_GetFIFOThresholdIndex300(SiS_Pr, &idx1, &idx2);
2288
2289 if(key == 0) {
2290 longtemp *= SiS_GetFIFOThresholdA300(idx1, idx2);
2291 } else {
2292 longtemp *= SiS_GetFIFOThresholdB300(idx1, idx2);
2293 }
2294 idx1 = longtemp % (MCLK * 16);
2295 longtemp /= (MCLK * 16);
2296 if(idx1) longtemp++;
2297 return (unsigned short)longtemp;
2298}
2299
2300static unsigned short
2301SiS_CalcDelay(struct SiS_Private *SiS_Pr, unsigned short VCLK,
2302 unsigned short colordepth, unsigned short MCLK)
2303{
2304 unsigned short temp1, temp2;
2305
2306 temp2 = SiS_DoCalcDelay(SiS_Pr, MCLK, VCLK, colordepth, 0);
2307 temp1 = SiS_DoCalcDelay(SiS_Pr, MCLK, VCLK, colordepth, 1);
2308 if(temp1 < 4) temp1 = 4;
2309 temp1 -= 4;
2310 if(temp2 < temp1) temp2 = temp1;
2311 return temp2;
2312}
2313
2314static void
2315SiS_SetCRT1FIFO_300(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
2316 unsigned short RefreshRateTableIndex)
2317{
2318 unsigned short ThresholdLow = 0;
2319 unsigned short temp, index, VCLK, MCLK, colorth;
2320 static const unsigned short colortharray[6] = { 1, 1, 2, 2, 3, 4 };
2321
2322 if(ModeNo > 0x13) {
2323
2324
2325 if(SiS_Pr->UseCustomMode) {
2326 VCLK = SiS_Pr->CSRClock;
2327 } else {
2328 index = SiS_GetRefCRTVCLK(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWide);
2329 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
2330 }
2331
2332
2333 colorth = colortharray[(SiS_Pr->SiS_ModeType - ModeEGA)];
2334
2335
2336 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A) & 0x07;
2337 MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;
2338
2339 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xc3;
2340 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x16,0x3c,temp);
2341
2342 do {
2343 ThresholdLow = SiS_CalcDelay(SiS_Pr, VCLK, colorth, MCLK) + 1;
2344 if(ThresholdLow < 0x13) break;
2345 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x16,0xfc);
2346 ThresholdLow = 0x13;
2347 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) >> 6;
2348 if(!temp) break;
2349 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x16,0x3f,((temp - 1) << 6));
2350 } while(0);
2351
2352 } else ThresholdLow = 2;
2353
2354
2355 temp = (ThresholdLow << 4) | 0x0f;
2356 SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,temp);
2357
2358 temp = (ThresholdLow & 0x10) << 1;
2359 if(ModeNo > 0x13) temp |= 0x40;
2360 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0f,0x9f,temp);
2361
2362
2363 SiS_SetReg(SiS_Pr->SiS_P3c4,0x3B,0x09);
2364
2365
2366 temp = ThresholdLow + 3;
2367 if(temp > 0x0f) temp = 0x0f;
2368 SiS_SetReg(SiS_Pr->SiS_P3c4,0x09,temp);
2369}
2370
2371unsigned short
2372SiS_GetLatencyFactor630(struct SiS_Private *SiS_Pr, unsigned short index)
2373{
2374 static const unsigned char LatencyFactor[] = {
2375 97, 88, 86, 79, 77, 0,
2376 0, 87, 85, 78, 76, 54,
2377 97, 88, 86, 79, 77, 0,
2378 0, 79, 77, 70, 68, 48,
2379 80, 72, 69, 63, 61, 0,
2380 0, 70, 68, 61, 59, 37,
2381 86, 77, 75, 68, 66, 0,
2382 0, 68, 66, 59, 57, 37
2383 };
2384 static const unsigned char LatencyFactor730[] = {
2385 69, 63, 61,
2386 86, 79, 77,
2387 103, 96, 94,
2388 120,113,111,
2389 137,130,128
2390 };
2391
2392 if(SiS_Pr->ChipType == SIS_730) {
2393 return (unsigned short)LatencyFactor730[index];
2394 } else {
2395 return (unsigned short)LatencyFactor[index];
2396 }
2397}
2398
2399static unsigned short
2400SiS_CalcDelay2(struct SiS_Private *SiS_Pr, unsigned char key)
2401{
2402 unsigned short index;
2403
2404 if(SiS_Pr->ChipType == SIS_730) {
2405 index = ((key & 0x0f) * 3) + ((key & 0xc0) >> 6);
2406 } else {
2407 index = (key & 0xe0) >> 5;
2408 if(key & 0x10) index += 6;
2409 if(!(key & 0x01)) index += 24;
2410 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80) index += 12;
2411 }
2412 return SiS_GetLatencyFactor630(SiS_Pr, index);
2413}
2414
2415static void
2416SiS_SetCRT1FIFO_630(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
2417 unsigned short RefreshRateTableIndex)
2418{
2419 unsigned short ThresholdLow = 0;
2420 unsigned short i, data, VCLK, MCLK16, colorth = 0;
2421 unsigned int templ, datal;
2422 const unsigned char *queuedata = NULL;
2423 static const unsigned char FQBQData[21] = {
2424 0x01,0x21,0x41,0x61,0x81,
2425 0x31,0x51,0x71,0x91,0xb1,
2426 0x00,0x20,0x40,0x60,0x80,
2427 0x30,0x50,0x70,0x90,0xb0,
2428 0xff
2429 };
2430 static const unsigned char FQBQData730[16] = {
2431 0x34,0x74,0xb4,
2432 0x23,0x63,0xa3,
2433 0x12,0x52,0x92,
2434 0x01,0x41,0x81,
2435 0x00,0x40,0x80,
2436 0xff
2437 };
2438 static const unsigned short colortharray[6] = {
2439 1, 1, 2, 2, 3, 4
2440 };
2441
2442 i = 0;
2443
2444 if(ModeNo > 0x13) {
2445
2446
2447 if(SiS_Pr->UseCustomMode) {
2448 VCLK = SiS_Pr->CSRClock;
2449 } else {
2450 data = SiS_GetRefCRTVCLK(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWide);
2451 VCLK = SiS_Pr->SiS_VCLKData[data].CLOCK;
2452 }
2453
2454
2455 data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A) & 0x07;
2456 MCLK16 = SiS_Pr->SiS_MCLKData_0[data].CLOCK * 16;
2457
2458
2459 colorth = colortharray[(SiS_Pr->SiS_ModeType - ModeEGA)];
2460
2461 if(SiS_Pr->ChipType == SIS_730) {
2462 queuedata = &FQBQData730[0];
2463 } else {
2464 queuedata = &FQBQData[0];
2465 }
2466
2467 do {
2468 templ = SiS_CalcDelay2(SiS_Pr, queuedata[i]) * VCLK * colorth;
2469
2470 datal = templ % MCLK16;
2471 templ = (templ / MCLK16) + 1;
2472 if(datal) templ++;
2473
2474 if(templ > 0x13) {
2475 if(queuedata[i + 1] == 0xFF) {
2476 ThresholdLow = 0x13;
2477 break;
2478 }
2479 i++;
2480 } else {
2481 ThresholdLow = templ;
2482 break;
2483 }
2484 } while(queuedata[i] != 0xFF);
2485
2486 } else {
2487
2488 if(SiS_Pr->ChipType != SIS_730) i = 9;
2489 ThresholdLow = 0x02;
2490
2491 }
2492
2493
2494 data = ((ThresholdLow & 0x0f) << 4) | 0x0f;
2495 SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,data);
2496
2497 data = (ThresholdLow & 0x10) << 1;
2498 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xDF,data);
2499
2500
2501 SiS_SetReg(SiS_Pr->SiS_P3c4,0x3B,0x09);
2502
2503
2504 data = ThresholdLow + 3;
2505 if(data > 0x0f) data = 0x0f;
2506 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x09,0x80,data);
2507
2508
2509#ifdef SIS_LINUX_KERNEL
2510 templ = sisfb_read_nbridge_pci_dword(SiS_Pr, 0x50);
2511#else
2512 templ = pciReadLong(0x00000000, 0x50);
2513#endif
2514
2515 if(SiS_Pr->ChipType == SIS_730) {
2516
2517 templ &= 0xfffff9ff;
2518 templ |= ((queuedata[i] & 0xc0) << 3);
2519
2520 } else {
2521
2522 templ &= 0xf0ffffff;
2523 if( (ModeNo <= 0x13) &&
2524 (SiS_Pr->ChipType == SIS_630) &&
2525 (SiS_Pr->ChipRevision >= 0x30) ) {
2526 templ |= 0x0b000000;
2527 } else {
2528 templ |= ((queuedata[i] & 0xf0) << 20);
2529 }
2530
2531 }
2532
2533#ifdef SIS_LINUX_KERNEL
2534 sisfb_write_nbridge_pci_dword(SiS_Pr, 0x50, templ);
2535 templ = sisfb_read_nbridge_pci_dword(SiS_Pr, 0xA0);
2536#else
2537 pciWriteLong(0x00000000, 0x50, templ);
2538 templ = pciReadLong(0x00000000, 0xA0);
2539#endif
2540
2541
2542 if(SiS_Pr->ChipType == SIS_730) {
2543
2544 templ &= 0x00ffffff;
2545 datal = queuedata[i] << 8;
2546 templ |= (((datal & 0x0f00) | ((datal & 0x3000) >> 8)) << 20);
2547
2548 } else {
2549
2550 templ &= 0xf0ffffff;
2551 templ |= ((queuedata[i] & 0x0f) << 24);
2552
2553 }
2554
2555#ifdef SIS_LINUX_KERNEL
2556 sisfb_write_nbridge_pci_dword(SiS_Pr, 0xA0, templ);
2557#else
2558 pciWriteLong(0x00000000, 0xA0, templ);
2559#endif
2560}
2561#endif
2562
2563#ifdef SIS315H
2564static void
2565SiS_SetCRT1FIFO_310(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2566{
2567 unsigned short modeflag;
2568
2569
2570 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x3D,0xFE);
2571
2572 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
2573
2574 SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0xAE);
2575 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x09,0xF0);
2576 if(ModeNo > 0x13) {
2577 if(SiS_Pr->ChipType >= XGI_20) {
2578 SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0x34);
2579 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x3D,0x01);
2580 } else if(SiS_Pr->ChipType >= SIS_661) {
2581 if(!(modeflag & HalfDCLK)) {
2582 SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0x34);
2583 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x3D,0x01);
2584 }
2585 } else {
2586 if((!(modeflag & DoubleScanMode)) || (!(modeflag & HalfDCLK))) {
2587 SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0x34);
2588 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x3D,0x01);
2589 }
2590 }
2591 }
2592}
2593#endif
2594
2595
2596
2597
2598
2599static void
2600SiS_SetVCLKState(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
2601 unsigned short RefreshRateTableIndex, unsigned short ModeIdIndex)
2602{
2603 unsigned short data = 0, VCLK = 0, index = 0;
2604
2605 if(ModeNo > 0x13) {
2606 if(SiS_Pr->UseCustomMode) {
2607 VCLK = SiS_Pr->CSRClock;
2608 } else {
2609 index = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
2610 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
2611 }
2612 }
2613
2614 if(SiS_Pr->ChipType < SIS_315H) {
2615#ifdef SIS300
2616 if(VCLK > 150) data |= 0x80;
2617 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0x7B,data);
2618
2619 data = 0x00;
2620 if(VCLK >= 150) data |= 0x08;
2621 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xF7,data);
2622#endif
2623 } else if(SiS_Pr->ChipType < XGI_20) {
2624#ifdef SIS315H
2625 if(VCLK >= 166) data |= 0x0c;
2626 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xf3,data);
2627
2628 if(VCLK >= 166) {
2629 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1f,0xe7);
2630 }
2631#endif
2632 } else {
2633#ifdef SIS315H
2634 if(VCLK >= 200) data |= 0x0c;
2635 if(SiS_Pr->ChipType == XGI_20) data &= ~0x04;
2636 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xf3,data);
2637 if(SiS_Pr->ChipType != XGI_20) {
2638 data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xe7;
2639 if(VCLK < 200) data |= 0x10;
2640 SiS_SetReg(SiS_Pr->SiS_P3c4,0x1f,data);
2641 }
2642#endif
2643 }
2644
2645
2646 if(SiS_Pr->ChipType >= SIS_661) {
2647
2648 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xE8,0x10);
2649
2650 } else {
2651
2652 data = 0x03;
2653 if(VCLK >= 260) data = 0x00;
2654 else if(VCLK >= 160) data = 0x01;
2655 else if(VCLK >= 135) data = 0x02;
2656
2657 if(SiS_Pr->ChipType == SIS_540) {
2658 if((VCLK == 203) || (VCLK < 234)) data = 0x02;
2659 }
2660
2661 if(SiS_Pr->ChipType < SIS_315H) {
2662 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xFC,data);
2663 } else {
2664 if(SiS_Pr->ChipType > SIS_315PRO) {
2665 if(ModeNo > 0x13) data &= 0xfc;
2666 }
2667 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xF8,data);
2668 }
2669
2670 }
2671}
2672
2673static void
2674SiS_SetCRT1ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
2675 unsigned short ModeIdIndex, unsigned short RRTI)
2676{
2677 unsigned short data, infoflag = 0, modeflag, resindex;
2678#ifdef SIS315H
2679 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
2680 unsigned short data2, data3;
2681#endif
2682
2683 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
2684
2685 if(SiS_Pr->UseCustomMode) {
2686 infoflag = SiS_Pr->CInfoFlag;
2687 } else {
2688 resindex = SiS_GetResInfo(SiS_Pr, ModeNo, ModeIdIndex);
2689 if(ModeNo > 0x13) {
2690 infoflag = SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag;
2691 }
2692 }
2693
2694
2695 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1F,0x3F);
2696
2697 data = 0;
2698 if(ModeNo > 0x13) {
2699 if(SiS_Pr->SiS_ModeType > ModeEGA) {
2700 data |= 0x02;
2701 data |= ((SiS_Pr->SiS_ModeType - ModeVGA) << 2);
2702 }
2703 if(infoflag & InterlaceMode) data |= 0x20;
2704 }
2705 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x06,0xC0,data);
2706
2707 if(SiS_Pr->ChipType != SIS_300) {
2708 data = 0;
2709 if(infoflag & InterlaceMode) {
2710
2711 int hrs = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x04) |
2712 ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x0b) & 0xc0) << 2)) - 3;
2713 int hto = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x00) |
2714 ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x0b) & 0x03) << 8)) + 5;
2715 data = hrs - (hto >> 1) + 3;
2716 }
2717 SiS_SetReg(SiS_Pr->SiS_P3d4,0x19,data);
2718 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x1a,0xFC,((data >> 8) & 0x03));
2719 }
2720
2721 if(modeflag & HalfDCLK) {
2722 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x01,0x08);
2723 }
2724
2725 data = 0;
2726 if(modeflag & LineCompareOff) data = 0x08;
2727 if(SiS_Pr->ChipType == SIS_300) {
2728 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xF7,data);
2729 } else {
2730 if(SiS_Pr->ChipType >= XGI_20) data |= 0x20;
2731 if(SiS_Pr->SiS_ModeType == ModeEGA) {
2732 if(ModeNo > 0x13) {
2733 data |= 0x40;
2734 }
2735 }
2736 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xB7,data);
2737 }
2738
2739#ifdef SIS315H
2740 if(SiS_Pr->ChipType >= SIS_315H) {
2741 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x31,0xfb);
2742 }
2743
2744 if(SiS_Pr->ChipType == SIS_315PRO) {
2745
2746 data = SiS_Pr->SiS_SR15[(2 * 4) + SiS_Get310DRAMType(SiS_Pr)];
2747 if(SiS_Pr->SiS_ModeType == ModeText) {
2748 data &= 0xc7;
2749 } else {
2750 data2 = SiS_GetOffset(SiS_Pr, ModeNo, ModeIdIndex, RRTI) >> 1;
2751 if(infoflag & InterlaceMode) data2 >>= 1;
2752 data3 = SiS_GetColorDepth(SiS_Pr, ModeNo, ModeIdIndex) >> 1;
2753 if(data3) data2 /= data3;
2754 if(data2 >= 0x50) {
2755 data &= 0x0f;
2756 data |= 0x50;
2757 }
2758 }
2759 SiS_SetReg(SiS_Pr->SiS_P3c4,0x17,data);
2760
2761 } else if((SiS_Pr->ChipType == SIS_330) || (SiS_Pr->SiS_SysFlags & SF_760LFB)) {
2762
2763 data = SiS_Get310DRAMType(SiS_Pr);
2764 if(SiS_Pr->ChipType == SIS_330) {
2765 data = SiS_Pr->SiS_SR15[(2 * 4) + data];
2766 } else {
2767 if(SiS_Pr->SiS_ROMNew) data = ROMAddr[0xf6];
2768 else if(SiS_Pr->SiS_UseROM) data = ROMAddr[0x100 + data];
2769 else data = 0xba;
2770 }
2771 if(SiS_Pr->SiS_ModeType <= ModeEGA) {
2772 data &= 0xc7;
2773 } else {
2774 if(SiS_Pr->UseCustomMode) {
2775 data2 = SiS_Pr->CSRClock;
2776 } else {
2777 data2 = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
2778 data2 = SiS_Pr->SiS_VCLKData[data2].CLOCK;
2779 }
2780
2781 data3 = SiS_GetColorDepth(SiS_Pr, ModeNo, ModeIdIndex) >> 1;
2782 if(data3) data2 *= data3;
2783
2784 data2 = ((unsigned int)(SiS_GetMCLK(SiS_Pr) * 1024)) / data2;
2785
2786 if(SiS_Pr->ChipType == SIS_330) {
2787 if(SiS_Pr->SiS_ModeType != Mode16Bpp) {
2788 if (data2 >= 0x19c) data = 0xba;
2789 else if(data2 >= 0x140) data = 0x7a;
2790 else if(data2 >= 0x101) data = 0x3a;
2791 else if(data2 >= 0xf5) data = 0x32;
2792 else if(data2 >= 0xe2) data = 0x2a;
2793 else if(data2 >= 0xc4) data = 0x22;
2794 else if(data2 >= 0xac) data = 0x1a;
2795 else if(data2 >= 0x9e) data = 0x12;
2796 else if(data2 >= 0x8e) data = 0x0a;
2797 else data = 0x02;
2798 } else {
2799 if(data2 >= 0x127) data = 0xba;
2800 else data = 0x7a;
2801 }
2802 } else {
2803 if (data2 >= 0x190) data = 0xba;
2804 else if(data2 >= 0xff) data = 0x7a;
2805 else if(data2 >= 0xd3) data = 0x3a;
2806 else if(data2 >= 0xa9) data = 0x1a;
2807 else if(data2 >= 0x93) data = 0x0a;
2808 else data = 0x02;
2809 }
2810 }
2811 SiS_SetReg(SiS_Pr->SiS_P3c4,0x17,data);
2812
2813 }
2814
2815
2816#endif
2817
2818 data = 0x60;
2819 if(SiS_Pr->SiS_ModeType != ModeText) {
2820 data ^= 0x60;
2821 if(SiS_Pr->SiS_ModeType != ModeEGA) {
2822 data ^= 0xA0;
2823 }
2824 }
2825 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x21,0x1F,data);
2826
2827 SiS_SetVCLKState(SiS_Pr, ModeNo, RRTI, ModeIdIndex);
2828
2829#ifdef SIS315H
2830 if(((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) ||
2831 (SiS_Pr->ChipType == XGI_40)) {
2832 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40) {
2833 SiS_SetReg(SiS_Pr->SiS_P3d4,0x52,0x2c);
2834 } else {
2835 SiS_SetReg(SiS_Pr->SiS_P3d4,0x52,0x6c);
2836 }
2837 } else if(SiS_Pr->ChipType == XGI_20) {
2838 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40) {
2839 SiS_SetReg(SiS_Pr->SiS_P3d4,0x52,0x33);
2840 } else {
2841 SiS_SetReg(SiS_Pr->SiS_P3d4,0x52,0x73);
2842 }
2843 SiS_SetReg(SiS_Pr->SiS_P3d4,0x51,0x02);
2844 }
2845#endif
2846}
2847
2848#ifdef SIS315H
2849static void
2850SiS_SetupDualChip(struct SiS_Private *SiS_Pr)
2851{
2852#if 0
2853
2854 SISIOADDRESS P2_3c2 = SiS_Pr->IOAddress2 + 0x12;
2855 SISIOADDRESS P2_3c4 = SiS_Pr->IOAddress2 + 0x14;
2856 SISIOADDRESS P2_3ce = SiS_Pr->IOAddress2 + 0x1e;
2857 int i;
2858
2859 if((SiS_Pr->ChipRevision != 0) ||
2860 (!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x3a) & 0x04)))
2861 return;
2862
2863 for(i = 0; i <= 4; i++) {
2864 SiS_SetReg(P2_3c4,i,SiS_GetReg(SiS_Pr->SiS_P3c4,i));
2865 }
2866 for(i = 0; i <= 8; i++) {
2867 SiS_SetReg(P2_3ce,i,SiS_GetReg(SiS_Pr->SiS_P3ce,i));
2868 }
2869 SiS_SetReg(P2_3c4,0x05,0x86);
2870 SiS_SetReg(P2_3c4,0x06,SiS_GetReg(SiS_Pr->SiS_P3c4,0x06));
2871 SiS_SetReg(P2_3c4,0x21,SiS_GetReg(SiS_Pr->SiS_P3c4,0x21));
2872 SiS_SetRegByte(P2_3c2,SiS_GetRegByte(SiS_Pr->SiS_P3cc));
2873 SiS_SetReg(P2_3c4,0x05,0x00);
2874#endif
2875}
2876#endif
2877
2878
2879
2880
2881
2882static void
2883SiS_WriteDAC(struct SiS_Private *SiS_Pr, SISIOADDRESS DACData, unsigned short shiftflag,
2884 unsigned short dl, unsigned short ah, unsigned short al, unsigned short dh)
2885{
2886 unsigned short d1, d2, d3;
2887
2888 switch(dl) {
2889 case 0: d1 = dh; d2 = ah; d3 = al; break;
2890 case 1: d1 = ah; d2 = al; d3 = dh; break;
2891 default: d1 = al; d2 = dh; d3 = ah;
2892 }
2893 SiS_SetRegByte(DACData, (d1 << shiftflag));
2894 SiS_SetRegByte(DACData, (d2 << shiftflag));
2895 SiS_SetRegByte(DACData, (d3 << shiftflag));
2896}
2897
2898void
2899SiS_LoadDAC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2900{
2901 unsigned short data, data2, time, i, j, k, m, n, o;
2902 unsigned short si, di, bx, sf;
2903 SISIOADDRESS DACAddr, DACData;
2904 const unsigned char *table = NULL;
2905
2906 data = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex) & DACInfoFlag;
2907
2908 j = time = 64;
2909 if(data == 0x00) table = SiS_MDA_DAC;
2910 else if(data == 0x08) table = SiS_CGA_DAC;
2911 else if(data == 0x10) table = SiS_EGA_DAC;
2912 else if(data == 0x18) {
2913 j = 16;
2914 time = 256;
2915 table = SiS_VGA_DAC;
2916 }
2917
2918 if( ( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
2919 (SiS_Pr->SiS_VBType & VB_NoLCD) ) ||
2920 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) ||
2921 (!(SiS_Pr->SiS_SetFlag & ProgrammingCRT2)) ) {
2922 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF);
2923 DACAddr = SiS_Pr->SiS_P3c8;
2924 DACData = SiS_Pr->SiS_P3c9;
2925 sf = 0;
2926 } else {
2927 DACAddr = SiS_Pr->SiS_Part5Port;
2928 DACData = SiS_Pr->SiS_Part5Port + 1;
2929 sf = 2;
2930 }
2931
2932 SiS_SetRegByte(DACAddr,0x00);
2933
2934 for(i = 0; i < j; i++) {
2935 data = table[i];
2936 for(k = 0; k < 3; k++) {
2937 data2 = 0;
2938 if(data & 0x01) data2 += 0x2A;
2939 if(data & 0x02) data2 += 0x15;
2940 SiS_SetRegByte(DACData, (data2 << sf));
2941 data >>= 2;
2942 }
2943 }
2944
2945 if(time == 256) {
2946 for(i = 16; i < 32; i++) {
2947 data = table[i] << sf;
2948 for(k = 0; k < 3; k++) SiS_SetRegByte(DACData, data);
2949 }
2950 si = 32;
2951 for(m = 0; m < 9; m++) {
2952 di = si;
2953 bx = si + 4;
2954 for(n = 0; n < 3; n++) {
2955 for(o = 0; o < 5; o++) {
2956 SiS_WriteDAC(SiS_Pr, DACData, sf, n, table[di], table[bx], table[si]);
2957 si++;
2958 }
2959 si -= 2;
2960 for(o = 0; o < 3; o++) {
2961 SiS_WriteDAC(SiS_Pr, DACData, sf, n, table[di], table[si], table[bx]);
2962 si--;
2963 }
2964 }
2965 si += 5;
2966 }
2967 }
2968}
2969
2970
2971
2972
2973
2974static void
2975SiS_SetCRT1Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2976{
2977 unsigned short StandTableIndex, RefreshRateTableIndex;
2978
2979 SiS_Pr->SiS_CRT1Mode = ModeNo;
2980
2981 StandTableIndex = SiS_GetModePtr(SiS_Pr, ModeNo, ModeIdIndex);
2982
2983 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
2984 if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchCRT2)) {
2985 SiS_DisableBridge(SiS_Pr);
2986 }
2987 }
2988
2989 SiS_ResetSegmentRegisters(SiS_Pr);
2990
2991 SiS_SetSeqRegs(SiS_Pr, StandTableIndex);
2992 SiS_SetMiscRegs(SiS_Pr, StandTableIndex);
2993 SiS_SetCRTCRegs(SiS_Pr, StandTableIndex);
2994 SiS_SetATTRegs(SiS_Pr, StandTableIndex);
2995 SiS_SetGRCRegs(SiS_Pr, StandTableIndex);
2996 SiS_ClearExt1Regs(SiS_Pr, ModeNo);
2997 SiS_ResetCRT1VCLK(SiS_Pr);
2998
2999 SiS_Pr->SiS_SelectCRT2Rate = 0;
3000 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
3001
3002#ifdef SIS_XORG_XF86
3003 xf86DrvMsgVerb(0, X_PROBED, 4, "(init: VBType=0x%04x, VBInfo=0x%04x)\n",
3004 SiS_Pr->SiS_VBType, SiS_Pr->SiS_VBInfo);
3005#endif
3006
3007 if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) {
3008 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
3009 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
3010 }
3011 }
3012
3013 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
3014 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
3015 }
3016
3017 RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex);
3018
3019 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3020 SiS_Pr->SiS_SetFlag &= ~ProgrammingCRT2;
3021 }
3022
3023 if(RefreshRateTableIndex != 0xFFFF) {
3024 SiS_SetCRT1Sync(SiS_Pr, RefreshRateTableIndex);
3025 SiS_SetCRT1CRTC(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3026 SiS_SetCRT1Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3027 SiS_SetCRT1VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3028 }
3029
3030 switch(SiS_Pr->ChipType) {
3031#ifdef SIS300
3032 case SIS_300:
3033 SiS_SetCRT1FIFO_300(SiS_Pr, ModeNo, RefreshRateTableIndex);
3034 break;
3035 case SIS_540:
3036 case SIS_630:
3037 case SIS_730:
3038 SiS_SetCRT1FIFO_630(SiS_Pr, ModeNo, RefreshRateTableIndex);
3039 break;
3040#endif
3041 default:
3042#ifdef SIS315H
3043 if(SiS_Pr->ChipType == XGI_20) {
3044 unsigned char sr2b = 0, sr2c = 0;
3045 switch(ModeNo) {
3046 case 0x00:
3047 case 0x01: sr2b = 0x4e; sr2c = 0xe9; break;
3048 case 0x04:
3049 case 0x05:
3050 case 0x0d: sr2b = 0x1b; sr2c = 0xe3; break;
3051 }
3052 if(sr2b) {
3053 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2b,sr2b);
3054 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2c,sr2c);
3055 SiS_SetRegByte(SiS_Pr->SiS_P3c2,(SiS_GetRegByte(SiS_Pr->SiS_P3cc) | 0x0c));
3056 }
3057 }
3058 SiS_SetCRT1FIFO_310(SiS_Pr, ModeNo, ModeIdIndex);
3059#endif
3060 break;
3061 }
3062
3063 SiS_SetCRT1ModeRegs(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3064
3065#ifdef SIS315H
3066 if(SiS_Pr->ChipType == XGI_40) {
3067 SiS_SetupDualChip(SiS_Pr);
3068 }
3069#endif
3070
3071 SiS_LoadDAC(SiS_Pr, ModeNo, ModeIdIndex);
3072
3073#ifdef SIS_LINUX_KERNEL
3074 if(SiS_Pr->SiS_flag_clearbuffer) {
3075 SiS_ClearBuffer(SiS_Pr, ModeNo);
3076 }
3077#endif
3078
3079 if(!(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchCRT2 | SetCRT2ToLCDA))) {
3080 SiS_WaitRetrace1(SiS_Pr);
3081 SiS_DisplayOn(SiS_Pr);
3082 }
3083}
3084
3085
3086
3087
3088
3089static void
3090SiS_InitVB(struct SiS_Private *SiS_Pr)
3091{
3092 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
3093
3094 SiS_Pr->Init_P4_0E = 0;
3095 if(SiS_Pr->SiS_ROMNew) {
3096 SiS_Pr->Init_P4_0E = ROMAddr[0x82];
3097 } else if(SiS_Pr->ChipType >= XGI_40) {
3098 if(SiS_Pr->SiS_XGIROM) {
3099 SiS_Pr->Init_P4_0E = ROMAddr[0x80];
3100 }
3101 }
3102}
3103
3104static void
3105SiS_ResetVB(struct SiS_Private *SiS_Pr)
3106{
3107#ifdef SIS315H
3108 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
3109 unsigned short temp;
3110
3111
3112 if(SiS_Pr->SiS_UseROM) {
3113 if(SiS_Pr->ChipType < SIS_330) {
3114 temp = ROMAddr[VB310Data_1_2_Offset] | 0x40;
3115 if(SiS_Pr->SiS_ROMNew) temp = ROMAddr[0x80] | 0x40;
3116 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp);
3117 } else if(SiS_Pr->ChipType >= SIS_661 && SiS_Pr->ChipType < XGI_20) {
3118 temp = ROMAddr[0x7e] | 0x40;
3119 if(SiS_Pr->SiS_ROMNew) temp = ROMAddr[0x80] | 0x40;
3120 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp);
3121 }
3122 } else if(SiS_Pr->ChipType >= XGI_40) {
3123 temp = 0x40;
3124 if(SiS_Pr->SiS_XGIROM) temp |= ROMAddr[0x7e];
3125
3126 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp);
3127 }
3128#endif
3129}
3130
3131
3132
3133
3134
3135static void
3136SiS_StrangeStuff(struct SiS_Private *SiS_Pr)
3137{
3138
3139
3140
3141
3142#ifdef SIS315H
3143 if((IS_SIS651) || (IS_SISM650) ||
3144 SiS_Pr->ChipType == SIS_340 ||
3145 SiS_Pr->ChipType == XGI_40) {
3146 SiS_SetReg(SiS_Pr->SiS_VidCapt, 0x3f, 0x00);
3147 SiS_SetReg(SiS_Pr->SiS_VidCapt, 0x00, 0x00);
3148 SiS_SetReg(SiS_Pr->SiS_VidPlay, 0x00, 0x86);
3149 SiS_SetRegAND(SiS_Pr->SiS_VidPlay, 0x30, 0xfe);
3150 SiS_SetRegAND(SiS_Pr->SiS_VidPlay, 0x3f, 0xef);
3151 }
3152
3153#endif
3154}
3155
3156
3157
3158
3159
3160static void
3161SiS_Handle760(struct SiS_Private *SiS_Pr)
3162{
3163#ifdef SIS315H
3164 unsigned int somebase;
3165 unsigned char temp1, temp2, temp3;
3166
3167 if( (SiS_Pr->ChipType != SIS_760) ||
3168 ((SiS_GetReg(SiS_Pr->SiS_P3d4, 0x5c) & 0xf8) != 0x80) ||
3169 (!(SiS_Pr->SiS_SysFlags & SF_760LFB)) ||
3170 (!(SiS_Pr->SiS_SysFlags & SF_760UMA)) )
3171 return;
3172
3173#ifdef SIS_LINUX_KERNEL
3174 somebase = sisfb_read_mio_pci_word(SiS_Pr, 0x74);
3175#else
3176 somebase = pciReadWord(0x00001000, 0x74);
3177#endif
3178 somebase &= 0xffff;
3179
3180 if(somebase == 0) return;
3181
3182 temp3 = SiS_GetRegByte((somebase + 0x85)) & 0xb7;
3183
3184 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40) {
3185 temp1 = 0x21;
3186 temp2 = 0x03;
3187 temp3 |= 0x08;
3188 } else {
3189 temp1 = 0x25;
3190 temp2 = 0x0b;
3191 }
3192
3193#ifdef SIS_LINUX_KERNEL
3194 sisfb_write_nbridge_pci_byte(SiS_Pr, 0x7e, temp1);
3195 sisfb_write_nbridge_pci_byte(SiS_Pr, 0x8d, temp2);
3196#else
3197 pciWriteByte(0x00000000, 0x7e, temp1);
3198 pciWriteByte(0x00000000, 0x8d, temp2);
3199#endif
3200
3201 SiS_SetRegByte((somebase + 0x85), temp3);
3202#endif
3203}
3204
3205
3206
3207
3208
3209#ifdef SIS_XORG_XF86
3210static void
3211SiS_SetPitchCRT1(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn)
3212{
3213 SISPtr pSiS = SISPTR(pScrn);
3214 unsigned short HDisplay = pSiS->scrnPitch >> 3;
3215
3216 SiS_SetReg(SiS_Pr->SiS_P3d4,0x13,(HDisplay & 0xFF));
3217 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0xF0,(HDisplay >> 8));
3218}
3219
3220static void
3221SiS_SetPitchCRT2(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn)
3222{
3223 SISPtr pSiS = SISPTR(pScrn);
3224 unsigned short HDisplay = pSiS->scrnPitch2 >> 3;
3225
3226
3227 if(pSiS->VGAEngine == SIS_315_VGA)
3228 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2F, 0x01);
3229 else
3230 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24, 0x01);
3231
3232 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(HDisplay & 0xFF));
3233 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0xF0,(HDisplay >> 8));
3234}
3235
3236static void
3237SiS_SetPitch(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn)
3238{
3239 SISPtr pSiS = SISPTR(pScrn);
3240 bool isslavemode = false;
3241
3242 if( (pSiS->VBFlags2 & VB2_VIDEOBRIDGE) &&
3243 ( ((pSiS->VGAEngine == SIS_300_VGA) &&
3244 (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0xa0) == 0x20) ||
3245 ((pSiS->VGAEngine == SIS_315_VGA) &&
3246 (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x50) == 0x10) ) ) {
3247 isslavemode = true;
3248 }
3249
3250
3251 if((pSiS->VBFlags & DISPTYPE_DISP1) || (isslavemode)) {
3252 SiS_SetPitchCRT1(SiS_Pr, pScrn);
3253 }
3254
3255 if((pSiS->VBFlags & DISPTYPE_DISP2) && (!isslavemode)) {
3256 SiS_SetPitchCRT2(SiS_Pr, pScrn);
3257 }
3258}
3259#endif
3260
3261
3262
3263
3264
3265#ifdef SIS_XORG_XF86
3266
3267bool
3268SiSSetMode(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, unsigned short ModeNo, bool dosetpitch)
3269#else
3270bool
3271SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
3272#endif
3273{
3274 SISIOADDRESS BaseAddr = SiS_Pr->IOAddress;
3275 unsigned short RealModeNo, ModeIdIndex;
3276 unsigned char backupreg = 0;
3277#ifdef SIS_LINUX_KERNEL
3278 unsigned short KeepLockReg;
3279
3280 SiS_Pr->UseCustomMode = false;
3281 SiS_Pr->CRT1UsesCustomMode = false;
3282#endif
3283
3284 SiS_Pr->SiS_flag_clearbuffer = 0;
3285
3286 if(SiS_Pr->UseCustomMode) {
3287 ModeNo = 0xfe;
3288 } else {
3289#ifdef SIS_LINUX_KERNEL
3290 if(!(ModeNo & 0x80)) SiS_Pr->SiS_flag_clearbuffer = 1;
3291#endif
3292 ModeNo &= 0x7f;
3293 }
3294
3295
3296 RealModeNo = ModeNo;
3297 if(ModeNo == 0x5b) ModeNo = 0x56;
3298
3299 SiSInitPtr(SiS_Pr);
3300 SiSRegInit(SiS_Pr, BaseAddr);
3301 SiS_GetSysFlags(SiS_Pr);
3302
3303 SiS_Pr->SiS_VGAINFO = 0x11;
3304#if defined(SIS_XORG_XF86) && (defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__) || defined(__amd64__) || defined(__x86_64__))
3305 if(pScrn) SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
3306#endif
3307
3308#ifdef SIS_LINUX_KERNEL
3309 KeepLockReg = SiS_GetReg(SiS_Pr->SiS_P3c4,0x05);
3310#endif
3311 SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86);
3312
3313 SiSInitPCIetc(SiS_Pr);
3314 SiSSetLVDSetc(SiS_Pr);
3315 SiSDetermineROMUsage(SiS_Pr);
3316
3317 SiS_UnLockCRT2(SiS_Pr);
3318
3319 if(!SiS_Pr->UseCustomMode) {
3320 if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return false;
3321 } else {
3322 ModeIdIndex = 0;
3323 }
3324
3325 SiS_GetVBType(SiS_Pr);
3326
3327
3328 SiS_InitVB(SiS_Pr);
3329 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
3330 if(SiS_Pr->ChipType >= SIS_315H) {
3331 SiS_ResetVB(SiS_Pr);
3332 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x32,0x10);
3333 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x00,0x0c);
3334 backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
3335 } else {
3336 backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
3337 }
3338 }
3339
3340
3341 SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, (SiS_Pr->UseCustomMode) ? 0 : 1);
3342 SiS_SetYPbPr(SiS_Pr);
3343 SiS_SetTVMode(SiS_Pr, ModeNo, ModeIdIndex);
3344 SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex);
3345 SiS_SetLowModeTest(SiS_Pr, ModeNo);
3346
3347#ifdef SIS_LINUX_KERNEL
3348
3349 if(!SiS_CheckMemorySize(SiS_Pr, ModeNo, ModeIdIndex)) {
3350 return false;
3351 }
3352#endif
3353
3354 SiS_OpenCRTC(SiS_Pr);
3355
3356 if(SiS_Pr->UseCustomMode) {
3357 SiS_Pr->CRT1UsesCustomMode = true;
3358 SiS_Pr->CSRClock_CRT1 = SiS_Pr->CSRClock;
3359 SiS_Pr->CModeFlag_CRT1 = SiS_Pr->CModeFlag;
3360 } else {
3361 SiS_Pr->CRT1UsesCustomMode = false;
3362 }
3363
3364
3365 if( (SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SetCRT2ToLCDA)) ||
3366 (!(SiS_Pr->SiS_VBInfo & SwitchCRT2)) ) {
3367 SiS_SetCRT1Group(SiS_Pr, ModeNo, ModeIdIndex);
3368 }
3369
3370
3371 if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchCRT2 | SetCRT2ToLCDA)) {
3372 if( (SiS_Pr->SiS_VBType & VB_SISVB) ||
3373 (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
3374 (SiS_Pr->SiS_IF_DEF_CH70xx != 0) ||
3375 (SiS_Pr->SiS_IF_DEF_TRUMPION != 0) ) {
3376 SiS_SetCRT2Group(SiS_Pr, RealModeNo);
3377 }
3378 }
3379
3380 SiS_HandleCRT1(SiS_Pr);
3381
3382 SiS_StrangeStuff(SiS_Pr);
3383
3384 SiS_DisplayOn(SiS_Pr);
3385 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF);
3386
3387#ifdef SIS315H
3388 if(SiS_Pr->ChipType >= SIS_315H) {
3389 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
3390 if(!(SiS_IsDualEdge(SiS_Pr))) {
3391 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
3392 }
3393 }
3394 }
3395#endif
3396
3397 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
3398 if(SiS_Pr->ChipType >= SIS_315H) {
3399#ifdef SIS315H
3400 if(!SiS_Pr->SiS_ROMNew) {
3401 if(SiS_IsVAMode(SiS_Pr)) {
3402 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01);
3403 } else {
3404 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x35,0xFE);
3405 }
3406 }
3407
3408 SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,backupreg);
3409
3410 if((IS_SIS650) && (SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & 0xfc)) {
3411 if((ModeNo == 0x03) || (ModeNo == 0x10)) {
3412 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x51,0x80);
3413 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x56,0x08);
3414 }
3415 }
3416
3417 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & SetCRT2ToLCD) {
3418 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
3419 }
3420#endif
3421 } else if((SiS_Pr->ChipType == SIS_630) ||
3422 (SiS_Pr->ChipType == SIS_730)) {
3423 SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,backupreg);
3424 }
3425 }
3426
3427#ifdef SIS_XORG_XF86
3428 if(pScrn) {
3429
3430 if((ModeNo > 0x13) && (dosetpitch)) {
3431 SiS_SetPitch(SiS_Pr, pScrn);
3432 }
3433
3434
3435 SiS_GetSetModeID(pScrn, ModeNo);
3436 }
3437#endif
3438
3439 SiS_CloseCRTC(SiS_Pr);
3440
3441 SiS_Handle760(SiS_Pr);
3442
3443#ifdef SIS_LINUX_KERNEL
3444
3445 if(KeepLockReg != 0xA1) SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x00);
3446#endif
3447
3448 return true;
3449}
3450
3451
3452
3453
3454
3455
3456#ifdef SIS_XORG_XF86
3457bool
3458SiSBIOSSetMode(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
3459 DisplayModePtr mode, bool IsCustom)
3460{
3461 SISPtr pSiS = SISPTR(pScrn);
3462 unsigned short ModeNo = 0;
3463
3464 SiS_Pr->UseCustomMode = false;
3465
3466 if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
3467
3468 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting custom mode %dx%d\n",
3469 SiS_Pr->CHDisplay,
3470 (mode->Flags & V_INTERLACE ? SiS_Pr->CVDisplay * 2 :
3471 (mode->Flags & V_DBLSCAN ? SiS_Pr->CVDisplay / 2 :
3472 SiS_Pr->CVDisplay)));
3473
3474 } else {
3475
3476
3477 ModeNo = SiS_GetModeNumber(pScrn, mode, pSiS->VBFlags);
3478 if(!ModeNo) return false;
3479
3480 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting standard mode 0x%x\n", ModeNo);
3481
3482 }
3483
3484 return(SiSSetMode(SiS_Pr, pScrn, ModeNo, true));
3485}
3486
3487
3488
3489
3490
3491
3492bool
3493SiSBIOSSetModeCRT2(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
3494 DisplayModePtr mode, bool IsCustom)
3495{
3496 SISIOADDRESS BaseAddr = SiS_Pr->IOAddress;
3497 SISPtr pSiS = SISPTR(pScrn);
3498#ifdef SISDUALHEAD
3499 SISEntPtr pSiSEnt = pSiS->entityPrivate;
3500#endif
3501 unsigned short ModeIdIndex;
3502 unsigned short ModeNo = 0;
3503 unsigned char backupreg = 0;
3504
3505 SiS_Pr->UseCustomMode = false;
3506
3507
3508
3509
3510
3511
3512 if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
3513
3514 ModeNo = 0xfe;
3515
3516 } else {
3517
3518 ModeNo = SiS_GetModeNumber(pScrn, mode, pSiS->VBFlags);
3519 if(!ModeNo) return false;
3520
3521 }
3522
3523 SiSRegInit(SiS_Pr, BaseAddr);
3524 SiSInitPtr(SiS_Pr);
3525 SiS_GetSysFlags(SiS_Pr);
3526#if defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__) || defined(__amd64__) || defined(__x86_64__)
3527 SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
3528#else
3529 SiS_Pr->SiS_VGAINFO = 0x11;
3530#endif
3531
3532 SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86);
3533
3534 SiSInitPCIetc(SiS_Pr);
3535 SiSSetLVDSetc(SiS_Pr);
3536 SiSDetermineROMUsage(SiS_Pr);
3537
3538
3539#ifdef SISDUALHEAD
3540 if(pSiS->DualHeadMode) {
3541 pSiSEnt->CRT2ModeNo = ModeNo;
3542 pSiSEnt->CRT2DMode = mode;
3543 pSiSEnt->CRT2IsCustom = IsCustom;
3544 pSiSEnt->CRT2CR30 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
3545 pSiSEnt->CRT2CR31 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
3546 pSiSEnt->CRT2CR35 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
3547 pSiSEnt->CRT2CR38 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
3548#if 0
3549
3550 if(pSiSEnt->CRT1ModeNo == -1) {
3551 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
3552 "Setting CRT2 mode delayed until after setting CRT1 mode\n");
3553 return true;
3554 }
3555#endif
3556 pSiSEnt->CRT2ModeSet = true;
3557 }
3558#endif
3559
3560 if(SiS_Pr->UseCustomMode) {
3561
3562 unsigned short temptemp = SiS_Pr->CVDisplay;
3563
3564 if(SiS_Pr->CModeFlag & DoubleScanMode) temptemp >>= 1;
3565 else if(SiS_Pr->CInfoFlag & InterlaceMode) temptemp <<= 1;
3566
3567 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
3568 "Setting custom mode %dx%d on CRT2\n",
3569 SiS_Pr->CHDisplay, temptemp);
3570
3571 } else {
3572
3573 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
3574 "Setting standard mode 0x%x on CRT2\n", ModeNo);
3575
3576 }
3577
3578 SiS_UnLockCRT2(SiS_Pr);
3579
3580 if(!SiS_Pr->UseCustomMode) {
3581 if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return false;
3582 } else {
3583 ModeIdIndex = 0;
3584 }
3585
3586 SiS_GetVBType(SiS_Pr);
3587
3588 SiS_InitVB(SiS_Pr);
3589 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
3590 if(SiS_Pr->ChipType >= SIS_315H) {
3591 SiS_ResetVB(SiS_Pr);
3592 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x32,0x10);
3593 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x00,0x0c);
3594 backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
3595 } else {
3596 backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
3597 }
3598 }
3599
3600
3601 if(!SiS_Pr->UseCustomMode) {
3602 SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, 1);
3603 } else {
3604
3605 SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, 0);
3606 }
3607 SiS_SetYPbPr(SiS_Pr);
3608 SiS_SetTVMode(SiS_Pr, ModeNo, ModeIdIndex);
3609 SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex);
3610 SiS_SetLowModeTest(SiS_Pr, ModeNo);
3611
3612 SiS_ResetSegmentRegisters(SiS_Pr);
3613
3614
3615 if( (SiS_Pr->SiS_VBType & VB_SISVB) ||
3616 (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
3617 (SiS_Pr->SiS_IF_DEF_CH70xx != 0) ||
3618 (SiS_Pr->SiS_IF_DEF_TRUMPION != 0) ) {
3619 SiS_SetCRT2Group(SiS_Pr, ModeNo);
3620 }
3621
3622 SiS_StrangeStuff(SiS_Pr);
3623
3624 SiS_DisplayOn(SiS_Pr);
3625 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF);
3626
3627 if(SiS_Pr->ChipType >= SIS_315H) {
3628 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
3629 if(!(SiS_IsDualEdge(SiS_Pr))) {
3630 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
3631 }
3632 }
3633 }
3634
3635 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
3636 if(SiS_Pr->ChipType >= SIS_315H) {
3637 if(!SiS_Pr->SiS_ROMNew) {
3638 if(SiS_IsVAMode(SiS_Pr)) {
3639 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01);
3640 } else {
3641 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x35,0xFE);
3642 }
3643 }
3644
3645 SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,backupreg);
3646
3647 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & SetCRT2ToLCD) {
3648 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
3649 }
3650 } else if((SiS_Pr->ChipType == SIS_630) ||
3651 (SiS_Pr->ChipType == SIS_730)) {
3652 SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,backupreg);
3653 }
3654 }
3655
3656
3657 SiS_SetPitchCRT2(SiS_Pr, pScrn);
3658
3659 SiS_Handle760(SiS_Pr);
3660
3661 return true;
3662}
3663
3664
3665
3666
3667
3668
3669bool
3670SiSBIOSSetModeCRT1(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
3671 DisplayModePtr mode, bool IsCustom)
3672{
3673 SISIOADDRESS BaseAddr = SiS_Pr->IOAddress;
3674 SISPtr pSiS = SISPTR(pScrn);
3675 unsigned short ModeIdIndex, ModeNo = 0;
3676 unsigned char backupreg = 0;
3677#ifdef SISDUALHEAD
3678 SISEntPtr pSiSEnt = pSiS->entityPrivate;
3679 unsigned char backupcr30, backupcr31, backupcr38, backupcr35, backupp40d=0;
3680 bool backupcustom;
3681#endif
3682
3683 SiS_Pr->UseCustomMode = false;
3684
3685 if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
3686
3687 unsigned short temptemp = SiS_Pr->CVDisplay;
3688
3689 if(SiS_Pr->CModeFlag & DoubleScanMode) temptemp >>= 1;
3690 else if(SiS_Pr->CInfoFlag & InterlaceMode) temptemp <<= 1;
3691
3692 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
3693 "Setting custom mode %dx%d on CRT1\n",
3694 SiS_Pr->CHDisplay, temptemp);
3695 ModeNo = 0xfe;
3696
3697 } else {
3698
3699 ModeNo = SiS_GetModeNumber(pScrn, mode, 0);
3700 if(!ModeNo) return false;
3701
3702 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
3703 "Setting standard mode 0x%x on CRT1\n", ModeNo);
3704 }
3705
3706 SiSInitPtr(SiS_Pr);
3707 SiSRegInit(SiS_Pr, BaseAddr);
3708 SiS_GetSysFlags(SiS_Pr);
3709#if defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__) || defined(__amd64__) || defined(__x86_64__)
3710 SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
3711#else
3712 SiS_Pr->SiS_VGAINFO = 0x11;
3713#endif
3714
3715 SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86);
3716
3717 SiSInitPCIetc(SiS_Pr);
3718 SiSSetLVDSetc(SiS_Pr);
3719 SiSDetermineROMUsage(SiS_Pr);
3720
3721 SiS_UnLockCRT2(SiS_Pr);
3722
3723 if(!SiS_Pr->UseCustomMode) {
3724 if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return false;
3725 } else {
3726 ModeIdIndex = 0;
3727 }
3728
3729
3730 SiS_GetVBType(SiS_Pr);
3731
3732 SiS_InitVB(SiS_Pr);
3733 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
3734 if(SiS_Pr->ChipType >= SIS_315H) {
3735 backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
3736 } else {
3737 backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
3738 }
3739 }
3740
3741
3742
3743 SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, 0);
3744 SiS_SetYPbPr(SiS_Pr);
3745 SiS_SetTVMode(SiS_Pr, ModeNo, ModeIdIndex);
3746 SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex);
3747 SiS_SetLowModeTest(SiS_Pr, ModeNo);
3748
3749 SiS_OpenCRTC(SiS_Pr);
3750
3751
3752 SiS_SetCRT1Group(SiS_Pr, ModeNo, ModeIdIndex);
3753 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
3754 SiS_SetCRT2Group(SiS_Pr, ModeNo);
3755 }
3756
3757
3758 SiS_SetPitchCRT1(SiS_Pr, pScrn);
3759
3760 SiS_HandleCRT1(SiS_Pr);
3761
3762 SiS_StrangeStuff(SiS_Pr);
3763
3764 SiS_CloseCRTC(SiS_Pr);
3765
3766#ifdef SISDUALHEAD
3767 if(pSiS->DualHeadMode) {
3768 pSiSEnt->CRT1ModeNo = ModeNo;
3769 pSiSEnt->CRT1DMode = mode;
3770 }
3771#endif
3772
3773 if(SiS_Pr->UseCustomMode) {
3774 SiS_Pr->CRT1UsesCustomMode = true;
3775 SiS_Pr->CSRClock_CRT1 = SiS_Pr->CSRClock;
3776 SiS_Pr->CModeFlag_CRT1 = SiS_Pr->CModeFlag;
3777 } else {
3778 SiS_Pr->CRT1UsesCustomMode = false;
3779 }
3780
3781
3782#ifdef SISDUALHEAD
3783 if(pSiS->DualHeadMode) {
3784 if(pSiSEnt->CRT2ModeNo != -1) {
3785 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
3786 "(Re-)Setting mode for CRT2\n");
3787 backupcustom = SiS_Pr->UseCustomMode;
3788 backupcr30 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
3789 backupcr31 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
3790 backupcr35 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
3791 backupcr38 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
3792 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3793
3794 if(pSiSEnt->CRT2ModeSet) {
3795 backupp40d = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x0d) & 0x08;
3796 }
3797 }
3798 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
3799 SiS_SetReg(SiS_Pr->SiS_P3d4,0x30,pSiSEnt->CRT2CR30);
3800 SiS_SetReg(SiS_Pr->SiS_P3d4,0x31,pSiSEnt->CRT2CR31);
3801 SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,pSiSEnt->CRT2CR35);
3802 SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,pSiSEnt->CRT2CR38);
3803 }
3804
3805 SiSBIOSSetModeCRT2(SiS_Pr, pSiSEnt->pScrn_1,
3806 pSiSEnt->CRT2DMode, pSiSEnt->CRT2IsCustom);
3807
3808 SiS_SetReg(SiS_Pr->SiS_P3d4,0x30,backupcr30);
3809 SiS_SetReg(SiS_Pr->SiS_P3d4,0x31,backupcr31);
3810 SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,backupcr35);
3811 SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,backupcr38);
3812 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3813 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0d, ~0x08, backupp40d);
3814 }
3815 SiS_Pr->UseCustomMode = backupcustom;
3816 }
3817 }
3818#endif
3819
3820
3821
3822
3823
3824 SiS_DisplayOn(SiS_Pr);
3825 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF);
3826
3827 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
3828 if(SiS_Pr->ChipType >= SIS_315H) {
3829 SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,backupreg);
3830 } else if((SiS_Pr->ChipType == SIS_630) ||
3831 (SiS_Pr->ChipType == SIS_730)) {
3832 SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,backupreg);
3833 }
3834 }
3835
3836 SiS_Handle760(SiS_Pr);
3837
3838
3839 SiS_GetSetModeID(pScrn,ModeNo);
3840
3841 return true;
3842}
3843#endif
3844
3845#ifndef GETBITSTR
3846#define BITMASK(h,l) (((unsigned)(1U << ((h)-(l)+1))-1)<<(l))
3847#define GENMASK(mask) BITMASK(1?mask,0?mask)
3848#define GETBITS(var,mask) (((var) & GENMASK(mask)) >> (0?mask))
3849#define GETBITSTR(val,from,to) ((GETBITS(val,from)) << (0?to))
3850#endif
3851
3852void
3853SiS_CalcCRRegisters(struct SiS_Private *SiS_Pr, int depth)
3854{
3855 int x = 1;
3856
3857 SiS_Pr->CCRT1CRTC[0] = ((SiS_Pr->CHTotal >> 3) - 5) & 0xff;
3858 SiS_Pr->CCRT1CRTC[1] = (SiS_Pr->CHDisplay >> 3) - 1;
3859 SiS_Pr->CCRT1CRTC[2] = (SiS_Pr->CHBlankStart >> 3) - 1;
3860 SiS_Pr->CCRT1CRTC[3] = (((SiS_Pr->CHBlankEnd >> 3) - 1) & 0x1F) | 0x80;
3861 SiS_Pr->CCRT1CRTC[4] = (SiS_Pr->CHSyncStart >> 3) + 3;
3862 SiS_Pr->CCRT1CRTC[5] = ((((SiS_Pr->CHBlankEnd >> 3) - 1) & 0x20) << 2) |
3863 (((SiS_Pr->CHSyncEnd >> 3) + 3) & 0x1F);
3864
3865 SiS_Pr->CCRT1CRTC[6] = (SiS_Pr->CVTotal - 2) & 0xFF;
3866 SiS_Pr->CCRT1CRTC[7] = (((SiS_Pr->CVTotal - 2) & 0x100) >> 8)
3867 | (((SiS_Pr->CVDisplay - 1) & 0x100) >> 7)
3868 | (((SiS_Pr->CVSyncStart - x) & 0x100) >> 6)
3869 | (((SiS_Pr->CVBlankStart- 1) & 0x100) >> 5)
3870 | 0x10
3871 | (((SiS_Pr->CVTotal - 2) & 0x200) >> 4)
3872 | (((SiS_Pr->CVDisplay - 1) & 0x200) >> 3)
3873 | (((SiS_Pr->CVSyncStart - x) & 0x200) >> 2);
3874
3875 SiS_Pr->CCRT1CRTC[16] = ((((SiS_Pr->CVBlankStart - 1) & 0x200) >> 4) >> 5);
3876
3877 if(depth != 8) {
3878 if(SiS_Pr->CHDisplay >= 1600) SiS_Pr->CCRT1CRTC[16] |= 0x60;
3879 else if(SiS_Pr->CHDisplay >= 640) SiS_Pr->CCRT1CRTC[16] |= 0x40;
3880 }
3881
3882 SiS_Pr->CCRT1CRTC[8] = (SiS_Pr->CVSyncStart - x) & 0xFF;
3883 SiS_Pr->CCRT1CRTC[9] = ((SiS_Pr->CVSyncEnd - x) & 0x0F) | 0x80;
3884 SiS_Pr->CCRT1CRTC[10] = (SiS_Pr->CVDisplay - 1) & 0xFF;
3885 SiS_Pr->CCRT1CRTC[11] = (SiS_Pr->CVBlankStart - 1) & 0xFF;
3886 SiS_Pr->CCRT1CRTC[12] = (SiS_Pr->CVBlankEnd - 1) & 0xFF;
3887
3888 SiS_Pr->CCRT1CRTC[13] =
3889 GETBITSTR((SiS_Pr->CVTotal -2), 10:10, 0:0) |
3890 GETBITSTR((SiS_Pr->CVDisplay -1), 10:10, 1:1) |
3891 GETBITSTR((SiS_Pr->CVBlankStart-1), 10:10, 2:2) |
3892 GETBITSTR((SiS_Pr->CVSyncStart -x), 10:10, 3:3) |
3893 GETBITSTR((SiS_Pr->CVBlankEnd -1), 8:8, 4:4) |
3894 GETBITSTR((SiS_Pr->CVSyncEnd ), 4:4, 5:5) ;
3895
3896 SiS_Pr->CCRT1CRTC[14] =
3897 GETBITSTR((SiS_Pr->CHTotal >> 3) - 5, 9:8, 1:0) |
3898 GETBITSTR((SiS_Pr->CHDisplay >> 3) - 1, 9:8, 3:2) |
3899 GETBITSTR((SiS_Pr->CHBlankStart >> 3) - 1, 9:8, 5:4) |
3900 GETBITSTR((SiS_Pr->CHSyncStart >> 3) + 3, 9:8, 7:6) ;
3901
3902
3903 SiS_Pr->CCRT1CRTC[15] =
3904 GETBITSTR((SiS_Pr->CHBlankEnd >> 3) - 1, 7:6, 1:0) |
3905 GETBITSTR((SiS_Pr->CHSyncEnd >> 3) + 3, 5:5, 2:2) ;
3906}
3907
3908void
3909SiS_CalcLCDACRT1Timing(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
3910 unsigned short ModeIdIndex)
3911{
3912 unsigned short modeflag, tempax, tempbx = 0, remaining = 0;
3913 unsigned short VGAHDE = SiS_Pr->SiS_VGAHDE;
3914 int i, j;
3915
3916
3917 if(SiS_Pr->SiS_LCDInfo & LCDPass11) return;
3918
3919 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
3920
3921 if(modeflag & HalfDCLK) VGAHDE >>= 1;
3922
3923 SiS_Pr->CHDisplay = VGAHDE;
3924 SiS_Pr->CHBlankStart = VGAHDE;
3925
3926 SiS_Pr->CVDisplay = SiS_Pr->SiS_VGAVDE;
3927 SiS_Pr->CVBlankStart = SiS_Pr->SiS_VGAVDE;
3928
3929 if(SiS_Pr->ChipType < SIS_315H) {
3930#ifdef SIS300
3931 tempbx = SiS_Pr->SiS_VGAHT;
3932 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3933 tempbx = SiS_Pr->PanelHT;
3934 }
3935 if(modeflag & HalfDCLK) tempbx >>= 1;
3936 remaining = tempbx % 8;
3937#endif
3938 } else {
3939#ifdef SIS315H
3940
3941 tempbx = SiS_Pr->PanelHT - SiS_Pr->PanelXRes;
3942 tempax = SiS_Pr->SiS_VGAHDE;
3943 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3944 tempax = SiS_Pr->PanelXRes;
3945 }
3946 tempbx += tempax;
3947 if(modeflag & HalfDCLK) tempbx -= VGAHDE;
3948#endif
3949 }
3950 SiS_Pr->CHTotal = SiS_Pr->CHBlankEnd = tempbx;
3951
3952 if(SiS_Pr->ChipType < SIS_315H) {
3953#ifdef SIS300
3954 if(SiS_Pr->SiS_VGAHDE == SiS_Pr->PanelXRes) {
3955 SiS_Pr->CHSyncStart = SiS_Pr->SiS_VGAHDE + ((SiS_Pr->PanelHRS + 1) & ~1);
3956 SiS_Pr->CHSyncEnd = SiS_Pr->CHSyncStart + SiS_Pr->PanelHRE;
3957 if(modeflag & HalfDCLK) {
3958 SiS_Pr->CHSyncStart >>= 1;
3959 SiS_Pr->CHSyncEnd >>= 1;
3960 }
3961 } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3962 tempax = (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) >> 1;
3963 tempbx = (SiS_Pr->PanelHRS + 1) & ~1;
3964 if(modeflag & HalfDCLK) {
3965 tempax >>= 1;
3966 tempbx >>= 1;
3967 }
3968 SiS_Pr->CHSyncStart = (VGAHDE + tempax + tempbx + 7) & ~7;
3969 tempax = SiS_Pr->PanelHRE + 7;
3970 if(modeflag & HalfDCLK) tempax >>= 1;
3971 SiS_Pr->CHSyncEnd = (SiS_Pr->CHSyncStart + tempax) & ~7;
3972 } else {
3973 SiS_Pr->CHSyncStart = SiS_Pr->SiS_VGAHDE;
3974 if(modeflag & HalfDCLK) {
3975 SiS_Pr->CHSyncStart >>= 1;
3976 tempax = ((SiS_Pr->CHTotal - SiS_Pr->CHSyncStart) / 3) << 1;
3977 SiS_Pr->CHSyncEnd = SiS_Pr->CHSyncStart + tempax;
3978 } else {
3979 SiS_Pr->CHSyncEnd = (SiS_Pr->CHSyncStart + (SiS_Pr->CHTotal / 10) + 7) & ~7;
3980 SiS_Pr->CHSyncStart += 8;
3981 }
3982 }
3983#endif
3984 } else {
3985#ifdef SIS315H
3986 tempax = VGAHDE;
3987 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3988 tempbx = SiS_Pr->PanelXRes;
3989 if(modeflag & HalfDCLK) tempbx >>= 1;
3990 tempax += ((tempbx - tempax) >> 1);
3991 }
3992 tempax += SiS_Pr->PanelHRS;
3993 SiS_Pr->CHSyncStart = tempax;
3994 tempax += SiS_Pr->PanelHRE;
3995 SiS_Pr->CHSyncEnd = tempax;
3996#endif
3997 }
3998
3999 tempbx = SiS_Pr->PanelVT - SiS_Pr->PanelYRes;
4000 tempax = SiS_Pr->SiS_VGAVDE;
4001 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
4002 tempax = SiS_Pr->PanelYRes;
4003 } else if(SiS_Pr->ChipType < SIS_315H) {
4004#ifdef SIS300
4005
4006 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
4007 if((tempax + tempbx) == 438) tempbx += 16;
4008 } else if((SiS_Pr->SiS_LCDResInfo == Panel_800x600) ||
4009 (SiS_Pr->SiS_LCDResInfo == Panel_1024x600)) {
4010 tempax = 0;
4011 tempbx = SiS_Pr->SiS_VGAVT;
4012 }
4013#endif
4014 }
4015 SiS_Pr->CVTotal = SiS_Pr->CVBlankEnd = tempbx + tempax;
4016
4017 tempax = SiS_Pr->SiS_VGAVDE;
4018 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
4019 tempax += (SiS_Pr->PanelYRes - tempax) >> 1;
4020 }
4021 tempax += SiS_Pr->PanelVRS;
4022 SiS_Pr->CVSyncStart = tempax;
4023 tempax += SiS_Pr->PanelVRE;
4024 SiS_Pr->CVSyncEnd = tempax;
4025 if(SiS_Pr->ChipType < SIS_315H) {
4026 SiS_Pr->CVSyncStart--;
4027 SiS_Pr->CVSyncEnd--;
4028 }
4029
4030 SiS_CalcCRRegisters(SiS_Pr, 8);
4031 SiS_Pr->CCRT1CRTC[15] &= ~0xF8;
4032 SiS_Pr->CCRT1CRTC[15] |= (remaining << 4);
4033 SiS_Pr->CCRT1CRTC[16] &= ~0xE0;
4034
4035 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
4036
4037 for(i = 0, j = 0; i <= 7; i++, j++) {
4038 SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
4039 }
4040 for(j = 0x10; i <= 10; i++, j++) {
4041 SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
4042 }
4043 for(j = 0x15; i <= 12; i++, j++) {
4044 SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
4045 }
4046 for(j = 0x0A; i <= 15; i++, j++) {
4047 SiS_SetReg(SiS_Pr->SiS_P3c4,j,SiS_Pr->CCRT1CRTC[i]);
4048 }
4049
4050 tempax = SiS_Pr->CCRT1CRTC[16] & 0xE0;
4051 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1F,tempax);
4052
4053 tempax = (SiS_Pr->CCRT1CRTC[16] & 0x01) << 5;
4054 if(modeflag & DoubleScanMode) tempax |= 0x80;
4055 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0x5F,tempax);
4056
4057#ifdef SIS_XORG_XF86
4058#ifdef TWDEBUG
4059 xf86DrvMsg(0, X_INFO, "%d %d %d %d %d %d %d %d (%d %d %d %d)\n",
4060 SiS_Pr->CHDisplay, SiS_Pr->CHSyncStart, SiS_Pr->CHSyncEnd, SiS_Pr->CHTotal,
4061 SiS_Pr->CVDisplay, SiS_Pr->CVSyncStart, SiS_Pr->CVSyncEnd, SiS_Pr->CVTotal,
4062 SiS_Pr->CHBlankStart, SiS_Pr->CHBlankEnd, SiS_Pr->CVBlankStart, SiS_Pr->CVBlankEnd);
4063 xf86DrvMsg(0, X_INFO, " {{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
4064 SiS_Pr->CCRT1CRTC[0], SiS_Pr->CCRT1CRTC[1],
4065 SiS_Pr->CCRT1CRTC[2], SiS_Pr->CCRT1CRTC[3],
4066 SiS_Pr->CCRT1CRTC[4], SiS_Pr->CCRT1CRTC[5],
4067 SiS_Pr->CCRT1CRTC[6], SiS_Pr->CCRT1CRTC[7]);
4068 xf86DrvMsg(0, X_INFO, " 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
4069 SiS_Pr->CCRT1CRTC[8], SiS_Pr->CCRT1CRTC[9],
4070 SiS_Pr->CCRT1CRTC[10], SiS_Pr->CCRT1CRTC[11],
4071 SiS_Pr->CCRT1CRTC[12], SiS_Pr->CCRT1CRTC[13],
4072 SiS_Pr->CCRT1CRTC[14], SiS_Pr->CCRT1CRTC[15]);
4073 xf86DrvMsg(0, X_INFO, " 0x%02x}},\n", SiS_Pr->CCRT1CRTC[16]);
4074#endif
4075#endif
4076}
4077
4078void
4079SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata,
4080 int xres, int yres,
4081#ifdef SIS_XORG_XF86
4082 DisplayModePtr current
4083#endif
4084#ifdef SIS_LINUX_KERNEL
4085 struct fb_var_screeninfo *var, bool writeres
4086#endif
4087)
4088{
4089 unsigned short HRE, HBE, HRS, HBS, HDE, HT;
4090 unsigned short VRE, VBE, VRS, VBS, VDE, VT;
4091 unsigned char sr_data, cr_data, cr_data2;
4092 int A, B, C, D, E, F, temp;
4093
4094 sr_data = crdata[14];
4095
4096
4097 HT = crdata[0] | ((unsigned short)(sr_data & 0x03) << 8);
4098 A = HT + 5;
4099
4100
4101 HDE = crdata[1] | ((unsigned short)(sr_data & 0x0C) << 6);
4102 E = HDE + 1;
4103
4104
4105 HRS = crdata[4] | ((unsigned short)(sr_data & 0xC0) << 2);
4106 F = HRS - E - 3;
4107
4108
4109 HBS = crdata[2] | ((unsigned short)(sr_data & 0x30) << 4);
4110
4111 sr_data = crdata[15];
4112 cr_data = crdata[5];
4113
4114
4115 HBE = (crdata[3] & 0x1f) |
4116 ((unsigned short)(cr_data & 0x80) >> 2) |
4117 ((unsigned short)(sr_data & 0x03) << 6);
4118
4119
4120 HRE = (cr_data & 0x1f) | ((sr_data & 0x04) << 3);
4121
4122 temp = HBE - ((E - 1) & 255);
4123 B = (temp > 0) ? temp : (temp + 256);
4124
4125 temp = HRE - ((E + F + 3) & 63);
4126 C = (temp > 0) ? temp : (temp + 64);
4127
4128 D = B - F - C;
4129
4130#ifdef SIS_XORG_XF86
4131 current->HDisplay = (E * 8);
4132 current->HSyncStart = (E * 8) + (F * 8);
4133 current->HSyncEnd = (E * 8) + (F * 8) + (C * 8);
4134 current->HTotal = (E * 8) + (F * 8) + (C * 8) + (D * 8);
4135#ifdef TWDEBUG
4136 xf86DrvMsg(0, X_INFO,
4137 "H: A %d B %d C %d D %d E %d F %d HT %d HDE %d HRS %d HBS %d HBE %d HRE %d\n",
4138 A, B, C, D, E, F, HT, HDE, HRS, HBS, HBE, HRE);
4139#else
4140 (void)VBS; (void)HBS; (void)A;
4141#endif
4142#endif
4143#ifdef SIS_LINUX_KERNEL
4144 if(writeres) var->xres = xres = E * 8;
4145 var->left_margin = D * 8;
4146 var->right_margin = F * 8;
4147 var->hsync_len = C * 8;
4148#endif
4149
4150
4151 sr_data = crdata[13];
4152 cr_data = crdata[7];
4153
4154
4155 VT = crdata[6] |
4156 ((unsigned short)(cr_data & 0x01) << 8) |
4157 ((unsigned short)(cr_data & 0x20) << 4) |
4158 ((unsigned short)(sr_data & 0x01) << 10);
4159 A = VT + 2;
4160
4161
4162 VDE = crdata[10] |
4163 ((unsigned short)(cr_data & 0x02) << 7) |
4164 ((unsigned short)(cr_data & 0x40) << 3) |
4165 ((unsigned short)(sr_data & 0x02) << 9);
4166 E = VDE + 1;
4167
4168
4169 VRS = crdata[8] |
4170 ((unsigned short)(cr_data & 0x04) << 6) |
4171 ((unsigned short)(cr_data & 0x80) << 2) |
4172 ((unsigned short)(sr_data & 0x08) << 7);
4173 F = VRS + 1 - E;
4174
4175 cr_data2 = (crdata[16] & 0x01) << 5;
4176
4177
4178 VBS = crdata[11] |
4179 ((unsigned short)(cr_data & 0x08) << 5) |
4180 ((unsigned short)(cr_data2 & 0x20) << 4) |
4181 ((unsigned short)(sr_data & 0x04) << 8);
4182
4183
4184 VBE = crdata[12] | ((unsigned short)(sr_data & 0x10) << 4);
4185 temp = VBE - ((E - 1) & 511);
4186 B = (temp > 0) ? temp : (temp + 512);
4187
4188
4189 VRE = (crdata[9] & 0x0f) | ((sr_data & 0x20) >> 1);
4190 temp = VRE - ((E + F - 1) & 31);
4191 C = (temp > 0) ? temp : (temp + 32);
4192
4193 D = B - F - C;
4194
4195#ifdef SIS_XORG_XF86
4196 current->VDisplay = VDE + 1;
4197 current->VSyncStart = VRS + 1;
4198 current->VSyncEnd = ((VRS & ~0x1f) | VRE) + 1;
4199 if(VRE <= (VRS & 0x1f)) current->VSyncEnd += 32;
4200 current->VTotal = E + D + C + F;
4201#if 0
4202 current->VDisplay = E;
4203 current->VSyncStart = E + D;
4204 current->VSyncEnd = E + D + C;
4205 current->VTotal = E + D + C + F;
4206#endif
4207#ifdef TWDEBUG
4208 xf86DrvMsg(0, X_INFO,
4209 "V: A %d B %d C %d D %d E %d F %d VT %d VDE %d VRS %d VBS %d VBE %d VRE %d\n",
4210 A, B, C, D, E, F, VT, VDE, VRS, VBS, VBE, VRE);
4211#endif
4212#endif
4213#ifdef SIS_LINUX_KERNEL
4214 if(writeres) var->yres = yres = E;
4215 var->upper_margin = D;
4216 var->lower_margin = F;
4217 var->vsync_len = C;
4218#endif
4219
4220 if((xres == 320) && ((yres == 200) || (yres == 240))) {
4221
4222
4223
4224
4225
4226
4227#ifdef SIS_XORG_XF86
4228 current->HDisplay = 320;
4229 current->HSyncStart = 328;
4230 current->HSyncEnd = 376;
4231 current->HTotal = 400;
4232#endif
4233#ifdef SIS_LINUX_KERNEL
4234 var->left_margin = (400 - 376);
4235 var->right_margin = (328 - 320);
4236 var->hsync_len = (376 - 328);
4237#endif
4238
4239 }
4240
4241}
4242
4243
4244
4245
4246