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