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 break;
655 case 768:
656 if(VGAEngine == SIS_300_VGA) {
657 ModeIndex = ModeIndex_300_1280x768[Depth];
658 } else {
659 ModeIndex = ModeIndex_310_1280x768[Depth];
660 }
661 break;
662 case 800:
663 if(VGAEngine == SIS_315_VGA) {
664 ModeIndex = ModeIndex_1280x800[Depth];
665 }
666 break;
667 case 854:
668 if(VGAEngine == SIS_315_VGA) {
669 ModeIndex = ModeIndex_1280x854[Depth];
670 }
671 break;
672 case 960:
673 ModeIndex = ModeIndex_1280x960[Depth];
674 break;
675 case 1024:
676 ModeIndex = ModeIndex_1280x1024[Depth];
677 break;
678 }
679 break;
680 case 1360:
681 if(VGAEngine == SIS_315_VGA) {
682 if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth];
683 }
684 break;
685 case 1400:
686 if(VGAEngine == SIS_315_VGA) {
687 if(VBFlags2 & VB2_LCDOVER1280BRIDGE) {
688 if(VDisplay == 1050) ModeIndex = ModeIndex_1400x1050[Depth];
689 }
690 }
691 break;
692 case 1600:
693 if(VGAEngine == SIS_315_VGA) {
694 if(VBFlags2 & VB2_LCDOVER1280BRIDGE) {
695 if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
696 }
697 }
698 break;
699#ifndef VB_FORBID_CRT2LCD_OVER_1600
700 case 1680:
701 if(VGAEngine == SIS_315_VGA) {
702 if(VBFlags2 & VB2_LCDOVER1280BRIDGE) {
703 if(VDisplay == 1050) ModeIndex = ModeIndex_1680x1050[Depth];
704 }
705 }
706 break;
707 case 1920:
708 if(VGAEngine == SIS_315_VGA) {
709 if(VBFlags2 & VB2_LCDOVER1600BRIDGE) {
710 if(VDisplay == 1440) ModeIndex = ModeIndex_1920x1440[Depth];
711 }
712 }
713 break;
714 case 2048:
715 if(VGAEngine == SIS_315_VGA) {
716 if(VBFlags2 & VB2_LCDOVER1600BRIDGE) {
717 if(VDisplay == 1536) ModeIndex = ModeIndex_310_2048x1536[Depth];
718 }
719 }
720 break;
721#endif
722 }
723 }
724
725 return ModeIndex;
726}
727
728unsigned short
729SiS_GetModeID_TV(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay, int Depth,
730 unsigned int VBFlags2)
731{
732 unsigned short ModeIndex = 0;
733
734 if(VBFlags2 & VB2_CHRONTEL) {
735
736 switch(HDisplay)
737 {
738 case 512:
739 if(VGAEngine == SIS_315_VGA) {
740 if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
741 }
742 break;
743 case 640:
744 if(VDisplay == 480) ModeIndex = ModeIndex_640x480[Depth];
745 else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth];
746 break;
747 case 800:
748 if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
749 break;
750 case 1024:
751 if(VGAEngine == SIS_315_VGA) {
752 if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
753 }
754 break;
755 }
756
757 } else if(VBFlags2 & VB2_SISTVBRIDGE) {
758
759 switch(HDisplay)
760 {
761 case 320:
762 if(VDisplay == 200) ModeIndex = ModeIndex_320x200[Depth];
763 else if(VDisplay == 240) ModeIndex = ModeIndex_320x240[Depth];
764 break;
765 case 400:
766 if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
767 break;
768 case 512:
769 if( ((VBFlags & TV_YPBPR) && (VBFlags & (TV_YPBPR750P | TV_YPBPR1080I))) ||
770 (VBFlags & TV_HIVISION) ||
771 ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL)) ) {
772 if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
773 }
774 break;
775 case 640:
776 if(VDisplay == 480) ModeIndex = ModeIndex_640x480[Depth];
777 else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth];
778 break;
779 case 720:
780 if((!(VBFlags & TV_HIVISION)) && (!((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I)))) {
781 if(VDisplay == 480) {
782 ModeIndex = ModeIndex_720x480[Depth];
783 } else if(VDisplay == 576) {
784 if( ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR750P)) ||
785 ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL)) )
786 ModeIndex = ModeIndex_720x576[Depth];
787 }
788 }
789 break;
790 case 768:
791 if((!(VBFlags & TV_HIVISION)) && (!((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I)))) {
792 if( ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR750P)) ||
793 ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL)) ) {
794 if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
795 }
796 }
797 break;
798 case 800:
799 if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
800 else if(VDisplay == 480) {
801 if(!((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR750P))) {
802 ModeIndex = ModeIndex_800x480[Depth];
803 }
804 }
805 break;
806 case 960:
807 if(VGAEngine == SIS_315_VGA) {
808 if(VDisplay == 600) {
809 if((VBFlags & TV_HIVISION) || ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I))) {
810 ModeIndex = ModeIndex_960x600[Depth];
811 }
812 }
813 }
814 break;
815 case 1024:
816 if(VDisplay == 768) {
817 if(VBFlags2 & VB2_30xBLV) {
818 ModeIndex = ModeIndex_1024x768[Depth];
819 }
820 } else if(VDisplay == 576) {
821 if( (VBFlags & TV_HIVISION) ||
822 ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I)) ||
823 ((VBFlags2 & VB2_30xBLV) &&
824 ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL))) ) {
825 ModeIndex = ModeIndex_1024x576[Depth];
826 }
827 }
828 break;
829 case 1280:
830 if(VDisplay == 720) {
831 if((VBFlags & TV_HIVISION) ||
832 ((VBFlags & TV_YPBPR) && (VBFlags & (TV_YPBPR1080I | TV_YPBPR750P)))) {
833 ModeIndex = ModeIndex_1280x720[Depth];
834 }
835 } else if(VDisplay == 1024) {
836 if((VBFlags & TV_HIVISION) ||
837 ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I))) {
838 ModeIndex = ModeIndex_1280x1024[Depth];
839 }
840 }
841 break;
842 }
843 }
844 return ModeIndex;
845}
846
847unsigned short
848SiS_GetModeID_VGA2(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay, int Depth,
849 unsigned int VBFlags2)
850{
851 if(!(VBFlags2 & VB2_SISVGA2BRIDGE)) return 0;
852
853 if(HDisplay >= 1920) return 0;
854
855 switch(HDisplay)
856 {
857 case 1600:
858 if(VDisplay == 1200) {
859 if(VGAEngine != SIS_315_VGA) return 0;
860 if(!(VBFlags2 & VB2_30xB)) return 0;
861 }
862 break;
863 case 1680:
864 if(VDisplay == 1050) {
865 if(VGAEngine != SIS_315_VGA) return 0;
866 if(!(VBFlags2 & VB2_30xB)) return 0;
867 }
868 break;
869 }
870
871 return SiS_GetModeID(VGAEngine, 0, HDisplay, VDisplay, Depth, false, 0, 0);
872}
873
874
875
876
877
878
879void
880SiS_SetReg(SISIOADDRESS port, u8 index, u8 data)
881{
882 outb(index, port);
883 outb(data, port + 1);
884}
885
886void
887SiS_SetRegByte(SISIOADDRESS port, u8 data)
888{
889 outb(data, port);
890}
891
892void
893SiS_SetRegShort(SISIOADDRESS port, u16 data)
894{
895 outw(data, port);
896}
897
898void
899SiS_SetRegLong(SISIOADDRESS port, u32 data)
900{
901 outl(data, port);
902}
903
904u8
905SiS_GetReg(SISIOADDRESS port, u8 index)
906{
907 outb(index, port);
908 return inb(port + 1);
909}
910
911u8
912SiS_GetRegByte(SISIOADDRESS port)
913{
914 return inb(port);
915}
916
917u16
918SiS_GetRegShort(SISIOADDRESS port)
919{
920 return inw(port);
921}
922
923u32
924SiS_GetRegLong(SISIOADDRESS port)
925{
926 return inl(port);
927}
928
929void
930SiS_SetRegANDOR(SISIOADDRESS Port, u8 Index, u8 DataAND, u8 DataOR)
931{
932 u8 temp;
933
934 temp = SiS_GetReg(Port, Index);
935 temp = (temp & (DataAND)) | DataOR;
936 SiS_SetReg(Port, Index, temp);
937}
938
939void
940SiS_SetRegAND(SISIOADDRESS Port, u8 Index, u8 DataAND)
941{
942 u8 temp;
943
944 temp = SiS_GetReg(Port, Index);
945 temp &= DataAND;
946 SiS_SetReg(Port, Index, temp);
947}
948
949void
950SiS_SetRegOR(SISIOADDRESS Port, u8 Index, u8 DataOR)
951{
952 u8 temp;
953
954 temp = SiS_GetReg(Port, Index);
955 temp |= DataOR;
956 SiS_SetReg(Port, Index, temp);
957}
958
959
960
961
962
963void
964SiS_DisplayOn(struct SiS_Private *SiS_Pr)
965{
966 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x01,0xDF);
967}
968
969void
970SiS_DisplayOff(struct SiS_Private *SiS_Pr)
971{
972 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x01,0x20);
973}
974
975
976
977
978
979
980void
981SiSRegInit(struct SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr)
982{
983 SiS_Pr->SiS_P3c4 = BaseAddr + 0x14;
984 SiS_Pr->SiS_P3d4 = BaseAddr + 0x24;
985 SiS_Pr->SiS_P3c0 = BaseAddr + 0x10;
986 SiS_Pr->SiS_P3ce = BaseAddr + 0x1e;
987 SiS_Pr->SiS_P3c2 = BaseAddr + 0x12;
988 SiS_Pr->SiS_P3ca = BaseAddr + 0x1a;
989 SiS_Pr->SiS_P3c6 = BaseAddr + 0x16;
990 SiS_Pr->SiS_P3c7 = BaseAddr + 0x17;
991 SiS_Pr->SiS_P3c8 = BaseAddr + 0x18;
992 SiS_Pr->SiS_P3c9 = BaseAddr + 0x19;
993 SiS_Pr->SiS_P3cb = BaseAddr + 0x1b;
994 SiS_Pr->SiS_P3cc = BaseAddr + 0x1c;
995 SiS_Pr->SiS_P3cd = BaseAddr + 0x1d;
996 SiS_Pr->SiS_P3da = BaseAddr + 0x2a;
997 SiS_Pr->SiS_Part1Port = BaseAddr + SIS_CRT2_PORT_04;
998 SiS_Pr->SiS_Part2Port = BaseAddr + SIS_CRT2_PORT_10;
999 SiS_Pr->SiS_Part3Port = BaseAddr + SIS_CRT2_PORT_12;
1000 SiS_Pr->SiS_Part4Port = BaseAddr + SIS_CRT2_PORT_14;
1001 SiS_Pr->SiS_Part5Port = BaseAddr + SIS_CRT2_PORT_14 + 2;
1002 SiS_Pr->SiS_DDC_Port = BaseAddr + 0x14;
1003 SiS_Pr->SiS_VidCapt = BaseAddr + SIS_VIDEO_CAPTURE;
1004 SiS_Pr->SiS_VidPlay = BaseAddr + SIS_VIDEO_PLAYBACK;
1005}
1006
1007
1008
1009
1010
1011static void
1012SiS_GetSysFlags(struct SiS_Private *SiS_Pr)
1013{
1014 unsigned char cr5f, temp1, temp2;
1015
1016
1017
1018 SiS_Pr->SiS_SensibleSR11 = false;
1019 SiS_Pr->SiS_MyCR63 = 0x63;
1020 if(SiS_Pr->ChipType >= SIS_330) {
1021 SiS_Pr->SiS_MyCR63 = 0x53;
1022 if(SiS_Pr->ChipType >= SIS_661) {
1023 SiS_Pr->SiS_SensibleSR11 = true;
1024 }
1025 }
1026
1027
1028
1029 SiS_Pr->SiS_SysFlags = 0;
1030 if(SiS_Pr->ChipType == SIS_650) {
1031 cr5f = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0;
1032 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x5c,0x07);
1033 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5c) & 0xf8;
1034 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x5c,0xf8);
1035 temp2 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5c) & 0xf8;
1036 if((!temp1) || (temp2)) {
1037 switch(cr5f) {
1038 case 0x80:
1039 case 0x90:
1040 case 0xc0:
1041 SiS_Pr->SiS_SysFlags |= SF_IsM650;
1042 break;
1043 case 0xa0:
1044 case 0xb0:
1045 case 0xe0:
1046 SiS_Pr->SiS_SysFlags |= SF_Is651;
1047 break;
1048 }
1049 } else {
1050 switch(cr5f) {
1051 case 0x90:
1052 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5c) & 0xf8;
1053 switch(temp1) {
1054 case 0x00: SiS_Pr->SiS_SysFlags |= SF_IsM652; break;
1055 case 0x40: SiS_Pr->SiS_SysFlags |= SF_IsM653; break;
1056 default: SiS_Pr->SiS_SysFlags |= SF_IsM650; break;
1057 }
1058 break;
1059 case 0xb0:
1060 SiS_Pr->SiS_SysFlags |= SF_Is652;
1061 break;
1062 default:
1063 SiS_Pr->SiS_SysFlags |= SF_IsM650;
1064 break;
1065 }
1066 }
1067 }
1068
1069 if(SiS_Pr->ChipType >= SIS_760 && SiS_Pr->ChipType <= SIS_761) {
1070 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0x30) {
1071 SiS_Pr->SiS_SysFlags |= SF_760LFB;
1072 }
1073 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0xf0) {
1074 SiS_Pr->SiS_SysFlags |= SF_760UMA;
1075 }
1076 }
1077}
1078
1079
1080
1081
1082
1083static void
1084SiSInitPCIetc(struct SiS_Private *SiS_Pr)
1085{
1086 switch(SiS_Pr->ChipType) {
1087#ifdef CONFIG_FB_SIS_300
1088 case SIS_300:
1089 case SIS_540:
1090 case SIS_630:
1091 case SIS_730:
1092
1093
1094
1095
1096
1097 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x20,0xa1);
1098
1099
1100
1101
1102
1103 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x5A);
1104 break;
1105#endif
1106#ifdef CONFIG_FB_SIS_315
1107 case SIS_315H:
1108 case SIS_315:
1109 case SIS_315PRO:
1110 case SIS_650:
1111 case SIS_740:
1112 case SIS_330:
1113 case SIS_661:
1114 case SIS_741:
1115 case SIS_660:
1116 case SIS_760:
1117 case SIS_761:
1118 case SIS_340:
1119 case XGI_40:
1120
1121 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x20,0xa1);
1122
1123
1124
1125
1126
1127
1128 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0xDA);
1129 break;
1130 case XGI_20:
1131 case SIS_550:
1132
1133 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x20,0xa1);
1134
1135
1136
1137
1138 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1E,0x60,0x40);
1139 break;
1140#endif
1141 default:
1142 break;
1143 }
1144}
1145
1146
1147
1148
1149
1150static
1151void
1152SiSSetLVDSetc(struct SiS_Private *SiS_Pr)
1153{
1154 unsigned short temp;
1155
1156 SiS_Pr->SiS_IF_DEF_LVDS = 0;
1157 SiS_Pr->SiS_IF_DEF_TRUMPION = 0;
1158 SiS_Pr->SiS_IF_DEF_CH70xx = 0;
1159 SiS_Pr->SiS_IF_DEF_CONEX = 0;
1160
1161 SiS_Pr->SiS_ChrontelInit = 0;
1162
1163 if(SiS_Pr->ChipType == XGI_20) return;
1164
1165
1166 temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
1167 if((temp == 1) || (temp == 2)) return;
1168
1169 switch(SiS_Pr->ChipType) {
1170#ifdef CONFIG_FB_SIS_300
1171 case SIS_540:
1172 case SIS_630:
1173 case SIS_730:
1174 temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x37) & 0x0e) >> 1;
1175 if((temp >= 2) && (temp <= 5)) SiS_Pr->SiS_IF_DEF_LVDS = 1;
1176 if(temp == 3) SiS_Pr->SiS_IF_DEF_TRUMPION = 1;
1177 if((temp == 4) || (temp == 5)) {
1178
1179 SiS_Pr->SiS_Backup70xx = SiS_GetCH700x(SiS_Pr, 0x0e);
1180 SiS_Pr->SiS_IF_DEF_CH70xx = 1;
1181 }
1182 break;
1183#endif
1184#ifdef CONFIG_FB_SIS_315
1185 case SIS_550:
1186 case SIS_650:
1187 case SIS_740:
1188 case SIS_330:
1189 temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x37) & 0x0e) >> 1;
1190 if((temp >= 2) && (temp <= 3)) SiS_Pr->SiS_IF_DEF_LVDS = 1;
1191 if(temp == 3) SiS_Pr->SiS_IF_DEF_CH70xx = 2;
1192 break;
1193 case SIS_661:
1194 case SIS_741:
1195 case SIS_660:
1196 case SIS_760:
1197 case SIS_761:
1198 case SIS_340:
1199 case XGI_20:
1200 case XGI_40:
1201 temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & 0xe0) >> 5;
1202 if((temp >= 2) && (temp <= 3)) SiS_Pr->SiS_IF_DEF_LVDS = 1;
1203 if(temp == 3) SiS_Pr->SiS_IF_DEF_CH70xx = 2;
1204 if(temp == 4) SiS_Pr->SiS_IF_DEF_CONEX = 1;
1205 break;
1206#endif
1207 default:
1208 break;
1209 }
1210}
1211
1212
1213
1214
1215
1216void
1217SiS_SetEnableDstn(struct SiS_Private *SiS_Pr, int enable)
1218{
1219 SiS_Pr->SiS_IF_DEF_DSTN = enable ? 1 : 0;
1220}
1221
1222void
1223SiS_SetEnableFstn(struct SiS_Private *SiS_Pr, int enable)
1224{
1225 SiS_Pr->SiS_IF_DEF_FSTN = enable ? 1 : 0;
1226}
1227
1228
1229
1230
1231
1232unsigned short
1233SiS_GetModeFlag(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
1234 unsigned short ModeIdIndex)
1235{
1236 if(SiS_Pr->UseCustomMode) {
1237 return SiS_Pr->CModeFlag;
1238 } else if(ModeNo <= 0x13) {
1239 return SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
1240 } else {
1241 return SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1242 }
1243}
1244
1245
1246
1247
1248
1249bool
1250SiSDetermineROMLayout661(struct SiS_Private *SiS_Pr)
1251{
1252 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
1253 unsigned short romversoffs, romvmaj = 1, romvmin = 0;
1254
1255 if(SiS_Pr->ChipType >= XGI_20) {
1256
1257 return false;
1258 } else if(SiS_Pr->ChipType >= SIS_761) {
1259
1260 return true;
1261 } else if(SiS_Pr->ChipType >= SIS_661) {
1262 if((ROMAddr[0x1a] == 'N') &&
1263 (ROMAddr[0x1b] == 'e') &&
1264 (ROMAddr[0x1c] == 'w') &&
1265 (ROMAddr[0x1d] == 'V')) {
1266 return true;
1267 }
1268 romversoffs = ROMAddr[0x16] | (ROMAddr[0x17] << 8);
1269 if(romversoffs) {
1270 if((ROMAddr[romversoffs+1] == '.') || (ROMAddr[romversoffs+4] == '.')) {
1271 romvmaj = ROMAddr[romversoffs] - '0';
1272 romvmin = ((ROMAddr[romversoffs+2] -'0') * 10) + (ROMAddr[romversoffs+3] - '0');
1273 }
1274 }
1275 if((romvmaj != 0) || (romvmin >= 92)) {
1276 return true;
1277 }
1278 } else if(IS_SIS650740) {
1279 if((ROMAddr[0x1a] == 'N') &&
1280 (ROMAddr[0x1b] == 'e') &&
1281 (ROMAddr[0x1c] == 'w') &&
1282 (ROMAddr[0x1d] == 'V')) {
1283 return true;
1284 }
1285 }
1286 return false;
1287}
1288
1289static void
1290SiSDetermineROMUsage(struct SiS_Private *SiS_Pr)
1291{
1292 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
1293 unsigned short romptr = 0;
1294
1295 SiS_Pr->SiS_UseROM = false;
1296 SiS_Pr->SiS_ROMNew = false;
1297 SiS_Pr->SiS_PWDOffset = 0;
1298
1299 if(SiS_Pr->ChipType >= XGI_20) return;
1300
1301 if((ROMAddr) && (SiS_Pr->UseROM)) {
1302 if(SiS_Pr->ChipType == SIS_300) {
1303
1304
1305
1306
1307 if((ROMAddr[3] == 0xe9) && ((ROMAddr[5] << 8) | ROMAddr[4]) > 0x21a)
1308 SiS_Pr->SiS_UseROM = true;
1309 } else if(SiS_Pr->ChipType < SIS_315H) {
1310
1311
1312
1313 SiS_Pr->SiS_UseROM = true;
1314 } else {
1315
1316 SiS_Pr->SiS_UseROM = true;
1317 if((SiS_Pr->SiS_ROMNew = SiSDetermineROMLayout661(SiS_Pr))) {
1318 SiS_Pr->SiS_EMIOffset = 14;
1319 SiS_Pr->SiS_PWDOffset = 17;
1320 SiS_Pr->SiS661LCD2TableSize = 36;
1321
1322 if((romptr = SISGETROMW(0x0102))) {
1323 if(ROMAddr[romptr + (32 * 16)] == 0xff)
1324 SiS_Pr->SiS661LCD2TableSize = 32;
1325 else if(ROMAddr[romptr + (34 * 16)] == 0xff)
1326 SiS_Pr->SiS661LCD2TableSize = 34;
1327 else if(ROMAddr[romptr + (36 * 16)] == 0xff)
1328 SiS_Pr->SiS661LCD2TableSize = 36;
1329 else if( (ROMAddr[romptr + (38 * 16)] == 0xff) ||
1330 (ROMAddr[0x6F] & 0x01) ) {
1331 SiS_Pr->SiS661LCD2TableSize = 38;
1332 SiS_Pr->SiS_EMIOffset = 16;
1333 SiS_Pr->SiS_PWDOffset = 19;
1334 }
1335 }
1336 }
1337 }
1338 }
1339}
1340
1341
1342
1343
1344
1345static void
1346SiS_SetSegRegLower(struct SiS_Private *SiS_Pr, unsigned short value)
1347{
1348 unsigned short temp;
1349
1350 value &= 0x00ff;
1351 temp = SiS_GetRegByte(SiS_Pr->SiS_P3cb) & 0xf0;
1352 temp |= (value >> 4);
1353 SiS_SetRegByte(SiS_Pr->SiS_P3cb, temp);
1354 temp = SiS_GetRegByte(SiS_Pr->SiS_P3cd) & 0xf0;
1355 temp |= (value & 0x0f);
1356 SiS_SetRegByte(SiS_Pr->SiS_P3cd, temp);
1357}
1358
1359static void
1360SiS_SetSegRegUpper(struct SiS_Private *SiS_Pr, unsigned short value)
1361{
1362 unsigned short temp;
1363
1364 value &= 0x00ff;
1365 temp = SiS_GetRegByte(SiS_Pr->SiS_P3cb) & 0x0f;
1366 temp |= (value & 0xf0);
1367 SiS_SetRegByte(SiS_Pr->SiS_P3cb, temp);
1368 temp = SiS_GetRegByte(SiS_Pr->SiS_P3cd) & 0x0f;
1369 temp |= (value << 4);
1370 SiS_SetRegByte(SiS_Pr->SiS_P3cd, temp);
1371}
1372
1373static void
1374SiS_SetSegmentReg(struct SiS_Private *SiS_Pr, unsigned short value)
1375{
1376 SiS_SetSegRegLower(SiS_Pr, value);
1377 SiS_SetSegRegUpper(SiS_Pr, value);
1378}
1379
1380static void
1381SiS_ResetSegmentReg(struct SiS_Private *SiS_Pr)
1382{
1383 SiS_SetSegmentReg(SiS_Pr, 0);
1384}
1385
1386static void
1387SiS_SetSegmentRegOver(struct SiS_Private *SiS_Pr, unsigned short value)
1388{
1389 unsigned short temp = value >> 8;
1390
1391 temp &= 0x07;
1392 temp |= (temp << 4);
1393 SiS_SetReg(SiS_Pr->SiS_P3c4,0x1d,temp);
1394 SiS_SetSegmentReg(SiS_Pr, value);
1395}
1396
1397static void
1398SiS_ResetSegmentRegOver(struct SiS_Private *SiS_Pr)
1399{
1400 SiS_SetSegmentRegOver(SiS_Pr, 0);
1401}
1402
1403static void
1404SiS_ResetSegmentRegisters(struct SiS_Private *SiS_Pr)
1405{
1406 if((IS_SIS65x) || (SiS_Pr->ChipType >= SIS_661)) {
1407 SiS_ResetSegmentReg(SiS_Pr);
1408 SiS_ResetSegmentRegOver(SiS_Pr);
1409 }
1410}
1411
1412
1413
1414
1415
1416static
1417void
1418SiS_GetVBType(struct SiS_Private *SiS_Pr)
1419{
1420 unsigned short flag = 0, rev = 0, nolcd = 0;
1421 unsigned short p4_0f, p4_25, p4_27;
1422
1423 SiS_Pr->SiS_VBType = 0;
1424
1425 if((SiS_Pr->SiS_IF_DEF_LVDS) || (SiS_Pr->SiS_IF_DEF_CONEX))
1426 return;
1427
1428 if(SiS_Pr->ChipType == XGI_20)
1429 return;
1430
1431 flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
1432
1433 if(flag > 3)
1434 return;
1435
1436 rev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01);
1437
1438 if(flag >= 2) {
1439 SiS_Pr->SiS_VBType = VB_SIS302B;
1440 } else if(flag == 1) {
1441 if(rev >= 0xC0) {
1442 SiS_Pr->SiS_VBType = VB_SIS301C;
1443 } else if(rev >= 0xB0) {
1444 SiS_Pr->SiS_VBType = VB_SIS301B;
1445
1446 nolcd = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x23);
1447 if(!(nolcd & 0x02)) SiS_Pr->SiS_VBType |= VB_NoLCD;
1448 } else {
1449 SiS_Pr->SiS_VBType = VB_SIS301;
1450 }
1451 }
1452 if(SiS_Pr->SiS_VBType & (VB_SIS301B | VB_SIS301C | VB_SIS302B)) {
1453 if(rev >= 0xE0) {
1454 flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x39);
1455 if(flag == 0xff) SiS_Pr->SiS_VBType = VB_SIS302LV;
1456 else SiS_Pr->SiS_VBType = VB_SIS301C;
1457 } else if(rev >= 0xD0) {
1458 SiS_Pr->SiS_VBType = VB_SIS301LV;
1459 }
1460 }
1461 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV)) {
1462 p4_0f = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x0f);
1463 p4_25 = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x25);
1464 p4_27 = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x27);
1465 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0x7f);
1466 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x25,0x08);
1467 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,0xfd);
1468 if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x08) {
1469 SiS_Pr->SiS_VBType |= VB_UMC;
1470 }
1471 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x27,p4_27);
1472 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x25,p4_25);
1473 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0f,p4_0f);
1474 }
1475}
1476
1477
1478
1479
1480
1481static bool
1482SiS_CheckMemorySize(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
1483 unsigned short ModeIdIndex)
1484{
1485 unsigned short AdapterMemSize = SiS_Pr->VideoMemorySize / (1024*1024);
1486 unsigned short modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
1487 unsigned short memorysize = ((modeflag & MemoryInfoFlag) >> MemorySizeShift) + 1;
1488
1489 if(!AdapterMemSize) return true;
1490
1491 if(AdapterMemSize < memorysize) return false;
1492 return true;
1493}
1494
1495
1496
1497
1498
1499#ifdef CONFIG_FB_SIS_315
1500static unsigned char
1501SiS_Get310DRAMType(struct SiS_Private *SiS_Pr)
1502{
1503 unsigned char data;
1504
1505 if((*SiS_Pr->pSiS_SoftSetting) & SoftDRAMType) {
1506 data = (*SiS_Pr->pSiS_SoftSetting) & 0x03;
1507 } else {
1508 if(SiS_Pr->ChipType >= XGI_20) {
1509
1510 data = 0;
1511 } else if(SiS_Pr->ChipType >= SIS_340) {
1512
1513 data = 0;
1514 } else if(SiS_Pr->ChipType >= SIS_661) {
1515 if(SiS_Pr->SiS_ROMNew) {
1516 data = ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0xc0) >> 6);
1517 } else {
1518 data = SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0x07;
1519 }
1520 } else if(IS_SIS550650740) {
1521 data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x07;
1522 } else {
1523 data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3a) & 0x03;
1524 if(SiS_Pr->ChipType == SIS_330) {
1525 if(data > 1) {
1526 switch(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0x30) {
1527 case 0x00: data = 1; break;
1528 case 0x10: data = 3; break;
1529 case 0x20: data = 3; break;
1530 case 0x30: data = 2; break;
1531 }
1532 } else {
1533 data = 0;
1534 }
1535 }
1536 }
1537 }
1538
1539 return data;
1540}
1541
1542static unsigned short
1543SiS_GetMCLK(struct SiS_Private *SiS_Pr)
1544{
1545 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
1546 unsigned short index;
1547
1548 index = SiS_Get310DRAMType(SiS_Pr);
1549 if(SiS_Pr->ChipType >= SIS_661) {
1550 if(SiS_Pr->SiS_ROMNew) {
1551 return((unsigned short)(SISGETROMW((0x90 + (index * 5) + 3))));
1552 }
1553 return(SiS_Pr->SiS_MCLKData_0[index].CLOCK);
1554 } else if(index >= 4) {
1555 return(SiS_Pr->SiS_MCLKData_1[index - 4].CLOCK);
1556 } else {
1557 return(SiS_Pr->SiS_MCLKData_0[index].CLOCK);
1558 }
1559}
1560#endif
1561
1562
1563
1564
1565
1566static void
1567SiS_ClearBuffer(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
1568{
1569 unsigned char SISIOMEMTYPE *memaddr = SiS_Pr->VideoMemoryAddress;
1570 unsigned int memsize = SiS_Pr->VideoMemorySize;
1571 unsigned short SISIOMEMTYPE *pBuffer;
1572 int i;
1573
1574 if(!memaddr || !memsize) return;
1575
1576 if(SiS_Pr->SiS_ModeType >= ModeEGA) {
1577 if(ModeNo > 0x13) {
1578 memset_io(memaddr, 0, memsize);
1579 } else {
1580 pBuffer = (unsigned short SISIOMEMTYPE *)memaddr;
1581 for(i = 0; i < 0x4000; i++) writew(0x0000, &pBuffer[i]);
1582 }
1583 } else if(SiS_Pr->SiS_ModeType < ModeCGA) {
1584 pBuffer = (unsigned short SISIOMEMTYPE *)memaddr;
1585 for(i = 0; i < 0x4000; i++) writew(0x0720, &pBuffer[i]);
1586 } else {
1587 memset_io(memaddr, 0, 0x8000);
1588 }
1589}
1590
1591
1592
1593
1594
1595bool
1596SiS_SearchModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo,
1597 unsigned short *ModeIdIndex)
1598{
1599 unsigned char VGAINFO = SiS_Pr->SiS_VGAINFO;
1600
1601 if((*ModeNo) <= 0x13) {
1602
1603 if((*ModeNo) <= 0x05) (*ModeNo) |= 0x01;
1604
1605 for((*ModeIdIndex) = 0; ;(*ModeIdIndex)++) {
1606 if(SiS_Pr->SiS_SModeIDTable[(*ModeIdIndex)].St_ModeID == (*ModeNo)) break;
1607 if(SiS_Pr->SiS_SModeIDTable[(*ModeIdIndex)].St_ModeID == 0xFF) return false;
1608 }
1609
1610 if((*ModeNo) == 0x07) {
1611 if(VGAINFO & 0x10) (*ModeIdIndex)++;
1612
1613 }
1614 if((*ModeNo) <= 0x03) {
1615 if(!(VGAINFO & 0x80)) (*ModeIdIndex)++;
1616 if(VGAINFO & 0x10) (*ModeIdIndex)++;
1617
1618 }
1619
1620
1621 } else {
1622
1623 for((*ModeIdIndex) = 0; ;(*ModeIdIndex)++) {
1624 if(SiS_Pr->SiS_EModeIDTable[(*ModeIdIndex)].Ext_ModeID == (*ModeNo)) break;
1625 if(SiS_Pr->SiS_EModeIDTable[(*ModeIdIndex)].Ext_ModeID == 0xFF) return false;
1626 }
1627
1628 }
1629 return true;
1630}
1631
1632
1633
1634
1635
1636unsigned short
1637SiS_GetModePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
1638{
1639 unsigned short index;
1640
1641 if(ModeNo <= 0x13) {
1642 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_StTableIndex;
1643 } else {
1644 if(SiS_Pr->SiS_ModeType <= ModeEGA) index = 0x1B;
1645 else index = 0x0F;
1646 }
1647 return index;
1648}
1649
1650
1651
1652
1653
1654unsigned short
1655SiS_GetRefCRTVCLK(struct SiS_Private *SiS_Pr, unsigned short Index, int UseWide)
1656{
1657 if(SiS_Pr->SiS_RefIndex[Index].Ext_InfoFlag & HaveWideTiming) {
1658 if(UseWide == 1) {
1659 return SiS_Pr->SiS_RefIndex[Index].Ext_CRTVCLK_WIDE;
1660 } else {
1661 return SiS_Pr->SiS_RefIndex[Index].Ext_CRTVCLK_NORM;
1662 }
1663 } else {
1664 return SiS_Pr->SiS_RefIndex[Index].Ext_CRTVCLK;
1665 }
1666}
1667
1668unsigned short
1669SiS_GetRefCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short Index, int UseWide)
1670{
1671 if(SiS_Pr->SiS_RefIndex[Index].Ext_InfoFlag & HaveWideTiming) {
1672 if(UseWide == 1) {
1673 return SiS_Pr->SiS_RefIndex[Index].Ext_CRT1CRTC_WIDE;
1674 } else {
1675 return SiS_Pr->SiS_RefIndex[Index].Ext_CRT1CRTC_NORM;
1676 }
1677 } else {
1678 return SiS_Pr->SiS_RefIndex[Index].Ext_CRT1CRTC;
1679 }
1680}
1681
1682
1683
1684
1685
1686static bool
1687SiS_DoLowModeTest(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
1688{
1689 unsigned short temp, temp1, temp2;
1690
1691 if((ModeNo != 0x03) && (ModeNo != 0x10) && (ModeNo != 0x12))
1692 return true;
1693 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x11);
1694 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x11,0x80);
1695 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x00);
1696 SiS_SetReg(SiS_Pr->SiS_P3d4,0x00,0x55);
1697 temp2 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x00);
1698 SiS_SetReg(SiS_Pr->SiS_P3d4,0x00,temp1);
1699 SiS_SetReg(SiS_Pr->SiS_P3d4,0x11,temp);
1700 if((SiS_Pr->ChipType >= SIS_315H) ||
1701 (SiS_Pr->ChipType == SIS_300)) {
1702 if(temp2 == 0x55) return false;
1703 else return true;
1704 } else {
1705 if(temp2 != 0x55) return true;
1706 else {
1707 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01);
1708 return false;
1709 }
1710 }
1711}
1712
1713static void
1714SiS_SetLowModeTest(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
1715{
1716 if(SiS_DoLowModeTest(SiS_Pr, ModeNo)) {
1717 SiS_Pr->SiS_SetFlag |= LowModeTests;
1718 }
1719}
1720
1721
1722
1723
1724
1725static void
1726SiS_OpenCRTC(struct SiS_Private *SiS_Pr)
1727{
1728 if(IS_SIS650) {
1729 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
1730 if(IS_SIS651) SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x51,0x20);
1731 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
1732 } else if(IS_SIS661741660760) {
1733 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x61,0xf7);
1734 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
1735 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
1736 if(!SiS_Pr->SiS_ROMNew) {
1737 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x3a,0xef);
1738 }
1739 }
1740}
1741
1742static void
1743SiS_CloseCRTC(struct SiS_Private *SiS_Pr)
1744{
1745#if 0
1746 unsigned short temp1 = 0, temp2 = 0;
1747
1748 if(IS_SIS661741660760) {
1749 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
1750 temp1 = 0xa0; temp2 = 0x08;
1751 }
1752 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x51,0x1f,temp1);
1753 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x56,0xe7,temp2);
1754 }
1755#endif
1756}
1757
1758static void
1759SiS_HandleCRT1(struct SiS_Private *SiS_Pr)
1760{
1761
1762 SiS_SetRegAND(SiS_Pr->SiS_P3d4,SiS_Pr->SiS_MyCR63,0xbf);
1763#if 0
1764 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x15) & 0x01)) {
1765 if((SiS_GetReg(SiS_Pr->SiS_P3c4,0x15) & 0x0a) ||
1766 (SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x01)) {
1767 SiS_SetRegOR(SiS_Pr->SiS_P3d4,SiS_Pr->SiS_MyCR63,0x40);
1768 }
1769 }
1770#endif
1771}
1772
1773
1774
1775
1776
1777unsigned short
1778SiS_GetColorDepth(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
1779 unsigned short ModeIdIndex)
1780{
1781 static const unsigned short ColorDepth[6] = { 1, 2, 4, 4, 6, 8 };
1782 unsigned short modeflag;
1783 short index;
1784
1785
1786 if(ModeNo == 0xfe) {
1787 modeflag = SiS_Pr->CModeFlag;
1788 } else if(ModeNo <= 0x13) {
1789 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
1790 } else {
1791 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1792 }
1793
1794 index = (modeflag & ModeTypeMask) - ModeEGA;
1795 if(index < 0) index = 0;
1796 return ColorDepth[index];
1797}
1798
1799
1800
1801
1802
1803unsigned short
1804SiS_GetOffset(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
1805 unsigned short ModeIdIndex, unsigned short RRTI)
1806{
1807 unsigned short xres, temp, colordepth, infoflag;
1808
1809 if(SiS_Pr->UseCustomMode) {
1810 infoflag = SiS_Pr->CInfoFlag;
1811 xres = SiS_Pr->CHDisplay;
1812 } else {
1813 infoflag = SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag;
1814 xres = SiS_Pr->SiS_RefIndex[RRTI].XRes;
1815 }
1816
1817 colordepth = SiS_GetColorDepth(SiS_Pr, ModeNo, ModeIdIndex);
1818
1819 temp = xres / 16;
1820 if(infoflag & InterlaceMode) temp <<= 1;
1821 temp *= colordepth;
1822 if(xres % 16) temp += (colordepth >> 1);
1823
1824 return temp;
1825}
1826
1827
1828
1829
1830
1831static void
1832SiS_SetSeqRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex)
1833{
1834 unsigned char SRdata;
1835 int i;
1836
1837 SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x03);
1838
1839
1840 SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[0] | 0x20;
1841
1842
1843 if((SiS_Pr->SiS_VBType & VB_SISVB) || (SiS_Pr->SiS_IF_DEF_LVDS)) {
1844
1845 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
1846 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) SRdata |= 0x01;
1847 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) SRdata |= 0x01;
1848
1849 }
1850
1851 SiS_SetReg(SiS_Pr->SiS_P3c4,0x01,SRdata);
1852
1853 for(i = 2; i <= 4; i++) {
1854 SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[i - 1];
1855 SiS_SetReg(SiS_Pr->SiS_P3c4,i,SRdata);
1856 }
1857}
1858
1859
1860
1861
1862
1863static void
1864SiS_SetMiscRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex)
1865{
1866 unsigned char Miscdata;
1867
1868 Miscdata = SiS_Pr->SiS_StandTable[StandTableIndex].MISC;
1869
1870 if(SiS_Pr->ChipType < SIS_661) {
1871 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
1872 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
1873 Miscdata |= 0x0C;
1874 }
1875 }
1876 }
1877
1878 SiS_SetRegByte(SiS_Pr->SiS_P3c2,Miscdata);
1879}
1880
1881
1882
1883
1884
1885static void
1886SiS_SetCRTCRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex)
1887{
1888 unsigned char CRTCdata;
1889 unsigned short i;
1890
1891
1892 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
1893
1894 for(i = 0; i <= 0x18; i++) {
1895 CRTCdata = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[i];
1896 SiS_SetReg(SiS_Pr->SiS_P3d4,i,CRTCdata);
1897 }
1898
1899 if(SiS_Pr->ChipType >= SIS_661) {
1900 SiS_OpenCRTC(SiS_Pr);
1901 for(i = 0x13; i <= 0x14; i++) {
1902 CRTCdata = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[i];
1903 SiS_SetReg(SiS_Pr->SiS_P3d4,i,CRTCdata);
1904 }
1905 } else if( ( (SiS_Pr->ChipType == SIS_630) ||
1906 (SiS_Pr->ChipType == SIS_730) ) &&
1907 (SiS_Pr->ChipRevision >= 0x30) ) {
1908 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
1909 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
1910 SiS_SetReg(SiS_Pr->SiS_P3d4,0x18,0xFE);
1911 }
1912 }
1913 }
1914}
1915
1916
1917
1918
1919
1920static void
1921SiS_SetATTRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex)
1922{
1923 unsigned char ARdata;
1924 unsigned short i;
1925
1926 for(i = 0; i <= 0x13; i++) {
1927 ARdata = SiS_Pr->SiS_StandTable[StandTableIndex].ATTR[i];
1928
1929 if(i == 0x13) {
1930
1931
1932
1933 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
1934 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) ARdata = 0;
1935 }
1936 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1937 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1938 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
1939 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata = 0;
1940 }
1941 }
1942 }
1943 if(SiS_Pr->ChipType >= SIS_661) {
1944 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD)) {
1945 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata = 0;
1946 }
1947 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
1948 if(SiS_Pr->ChipType >= SIS_315H) {
1949 if(IS_SIS550650740660) {
1950
1951 if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
1952 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata = 0;
1953 } else {
1954 ARdata = 0;
1955 }
1956 }
1957 } else {
1958 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata = 0;
1959 }
1960 }
1961 }
1962 SiS_GetRegByte(SiS_Pr->SiS_P3da);
1963 SiS_SetRegByte(SiS_Pr->SiS_P3c0,i);
1964 SiS_SetRegByte(SiS_Pr->SiS_P3c0,ARdata);
1965 }
1966
1967 SiS_GetRegByte(SiS_Pr->SiS_P3da);
1968 SiS_SetRegByte(SiS_Pr->SiS_P3c0,0x14);
1969 SiS_SetRegByte(SiS_Pr->SiS_P3c0,0x00);
1970
1971 SiS_GetRegByte(SiS_Pr->SiS_P3da);
1972 SiS_SetRegByte(SiS_Pr->SiS_P3c0,0x20);
1973 SiS_GetRegByte(SiS_Pr->SiS_P3da);
1974}
1975
1976
1977
1978
1979
1980static void
1981SiS_SetGRCRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex)
1982{
1983 unsigned char GRdata;
1984 unsigned short i;
1985
1986 for(i = 0; i <= 0x08; i++) {
1987 GRdata = SiS_Pr->SiS_StandTable[StandTableIndex].GRC[i];
1988 SiS_SetReg(SiS_Pr->SiS_P3ce,i,GRdata);
1989 }
1990
1991 if(SiS_Pr->SiS_ModeType > ModeVGA) {
1992
1993 SiS_SetRegAND(SiS_Pr->SiS_P3ce,0x05,0xBF);
1994 }
1995}
1996
1997
1998
1999
2000
2001static void
2002SiS_ClearExt1Regs(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
2003{
2004 unsigned short i;
2005
2006 for(i = 0x0A; i <= 0x0E; i++) {
2007 SiS_SetReg(SiS_Pr->SiS_P3c4,i,0x00);
2008 }
2009
2010 if(SiS_Pr->ChipType >= SIS_315H) {
2011 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x37,0xFE);
2012 if(ModeNo <= 0x13) {
2013 if(ModeNo == 0x06 || ModeNo >= 0x0e) {
2014 SiS_SetReg(SiS_Pr->SiS_P3c4,0x0e,0x20);
2015 }
2016 }
2017 }
2018}
2019
2020
2021
2022
2023
2024static void
2025SiS_ResetCRT1VCLK(struct SiS_Private *SiS_Pr)
2026{
2027 if(SiS_Pr->ChipType >= SIS_315H) {
2028 if(SiS_Pr->ChipType < SIS_661) {
2029 if(SiS_Pr->SiS_IF_DEF_LVDS == 0) return;
2030 }
2031 } else {
2032 if((SiS_Pr->SiS_IF_DEF_LVDS == 0) &&
2033 (!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) ) {
2034 return;
2035 }
2036 }
2037
2038 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x31,0xcf,0x20);
2039 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VCLKData[1].SR2B);
2040 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VCLKData[1].SR2C);
2041 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x80);
2042 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x31,0xcf,0x10);
2043 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VCLKData[0].SR2B);
2044 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VCLKData[0].SR2C);
2045 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x80);
2046}
2047
2048
2049
2050
2051
2052static void
2053SiS_SetCRT1Sync(struct SiS_Private *SiS_Pr, unsigned short RRTI)
2054{
2055 unsigned short sync;
2056
2057 if(SiS_Pr->UseCustomMode) {
2058 sync = SiS_Pr->CInfoFlag >> 8;
2059 } else {
2060 sync = SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag >> 8;
2061 }
2062
2063 sync &= 0xC0;
2064 sync |= 0x2f;
2065 SiS_SetRegByte(SiS_Pr->SiS_P3c2,sync);
2066}
2067
2068
2069
2070
2071
2072static void
2073SiS_SetCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
2074 unsigned short ModeIdIndex, unsigned short RRTI)
2075{
2076 unsigned short temp, i, j, modeflag;
2077 unsigned char *crt1data = NULL;
2078
2079 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
2080
2081 if(SiS_Pr->UseCustomMode) {
2082
2083 crt1data = &SiS_Pr->CCRT1CRTC[0];
2084
2085 } else {
2086
2087 temp = SiS_GetRefCRT1CRTC(SiS_Pr, RRTI, SiS_Pr->SiS_UseWide);
2088
2089
2090 if((temp == 0x20) && (SiS_Pr->Alternate1600x1200)) temp = 0x57;
2091
2092 crt1data = (unsigned char *)&SiS_Pr->SiS_CRT1Table[temp].CR[0];
2093
2094 }
2095
2096
2097 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
2098
2099 for(i = 0, j = 0; i <= 7; i++, j++) {
2100 SiS_SetReg(SiS_Pr->SiS_P3d4,j,crt1data[i]);
2101 }
2102 for(j = 0x10; i <= 10; i++, j++) {
2103 SiS_SetReg(SiS_Pr->SiS_P3d4,j,crt1data[i]);
2104 }
2105 for(j = 0x15; i <= 12; i++, j++) {
2106 SiS_SetReg(SiS_Pr->SiS_P3d4,j,crt1data[i]);
2107 }
2108 for(j = 0x0A; i <= 15; i++, j++) {
2109 SiS_SetReg(SiS_Pr->SiS_P3c4,j,crt1data[i]);
2110 }
2111
2112 SiS_SetReg(SiS_Pr->SiS_P3c4,0x0E,crt1data[16] & 0xE0);
2113
2114 temp = (crt1data[16] & 0x01) << 5;
2115 if(modeflag & DoubleScanMode) temp |= 0x80;
2116 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0x5F,temp);
2117
2118 if(SiS_Pr->SiS_ModeType > ModeVGA) {
2119 SiS_SetReg(SiS_Pr->SiS_P3d4,0x14,0x4F);
2120 }
2121
2122#ifdef CONFIG_FB_SIS_315
2123 if(SiS_Pr->ChipType == XGI_20) {
2124 SiS_SetReg(SiS_Pr->SiS_P3d4,0x04,crt1data[4] - 1);
2125 if(!(temp = crt1data[5] & 0x1f)) {
2126 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x0c,0xfb);
2127 }
2128 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x05,0xe0,((temp - 1) & 0x1f));
2129 temp = (crt1data[16] >> 5) + 3;
2130 if(temp > 7) temp -= 7;
2131 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0e,0x1f,(temp << 5));
2132 }
2133#endif
2134}
2135
2136
2137
2138
2139
2140
2141
2142static void
2143SiS_SetCRT1Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
2144 unsigned short ModeIdIndex, unsigned short RRTI)
2145{
2146 unsigned short temp, DisplayUnit, infoflag;
2147
2148 if(SiS_Pr->UseCustomMode) {
2149 infoflag = SiS_Pr->CInfoFlag;
2150 } else {
2151 infoflag = SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag;
2152 }
2153
2154 DisplayUnit = SiS_GetOffset(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
2155
2156 temp = (DisplayUnit >> 8) & 0x0f;
2157 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0xF0,temp);
2158
2159 SiS_SetReg(SiS_Pr->SiS_P3d4,0x13,DisplayUnit & 0xFF);
2160
2161 if(infoflag & InterlaceMode) DisplayUnit >>= 1;
2162
2163 DisplayUnit <<= 5;
2164 temp = (DisplayUnit >> 8) + 1;
2165 if(DisplayUnit & 0xff) temp++;
2166 if(SiS_Pr->ChipType == XGI_20) {
2167 if(ModeNo == 0x4a || ModeNo == 0x49) temp--;
2168 }
2169 SiS_SetReg(SiS_Pr->SiS_P3c4,0x10,temp);
2170}
2171
2172
2173
2174
2175
2176static void
2177SiS_SetCRT1VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
2178 unsigned short ModeIdIndex, unsigned short RRTI)
2179{
2180 unsigned short index = 0, clka, clkb;
2181
2182 if(SiS_Pr->UseCustomMode) {
2183 clka = SiS_Pr->CSR2B;
2184 clkb = SiS_Pr->CSR2C;
2185 } else {
2186 index = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
2187 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) &&
2188 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2189
2190 if((index == 0x21) && (SiS_Pr->Alternate1600x1200)) index = 0x72;
2191 clka = SiS_Pr->SiS_VBVCLKData[index].Part4_A;
2192 clkb = SiS_Pr->SiS_VBVCLKData[index].Part4_B;
2193 } else {
2194 clka = SiS_Pr->SiS_VCLKData[index].SR2B;
2195 clkb = SiS_Pr->SiS_VCLKData[index].SR2C;
2196 }
2197 }
2198
2199 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x31,0xCF);
2200
2201 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2b,clka);
2202 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2c,clkb);
2203
2204 if(SiS_Pr->ChipType >= SIS_315H) {
2205#ifdef CONFIG_FB_SIS_315
2206 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x01);
2207 if(SiS_Pr->ChipType == XGI_20) {
2208 unsigned short mf = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
2209 if(mf & HalfDCLK) {
2210 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2b,SiS_GetReg(SiS_Pr->SiS_P3c4,0x2b));
2211 clkb = SiS_GetReg(SiS_Pr->SiS_P3c4,0x2c);
2212 clkb = (((clkb & 0x1f) << 1) + 1) | (clkb & 0xe0);
2213 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2c,clkb);
2214 }
2215 }
2216#endif
2217 } else {
2218 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x80);
2219 }
2220}
2221
2222
2223
2224
2225
2226#ifdef CONFIG_FB_SIS_300
2227void
2228SiS_GetFIFOThresholdIndex300(struct SiS_Private *SiS_Pr, unsigned short *idx1,
2229 unsigned short *idx2)
2230{
2231 unsigned short temp1, temp2;
2232 static const unsigned char ThTiming[8] = {
2233 1, 2, 2, 3, 0, 1, 1, 2
2234 };
2235
2236 temp1 = temp2 = (SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x62) >> 1;
2237 (*idx2) = (unsigned short)(ThTiming[((temp2 >> 3) | temp1) & 0x07]);
2238 (*idx1) = (unsigned short)(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) >> 6) & 0x03;
2239 (*idx1) |= (unsigned short)(((SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) >> 4) & 0x0c));
2240 (*idx1) <<= 1;
2241}
2242
2243static unsigned short
2244SiS_GetFIFOThresholdA300(unsigned short idx1, unsigned short idx2)
2245{
2246 static const unsigned char ThLowA[8 * 3] = {
2247 61, 3,52, 5,68, 7,100,11,
2248 43, 3,42, 5,54, 7, 78,11,
2249 34, 3,37, 5,47, 7, 67,11
2250 };
2251
2252 return (unsigned short)((ThLowA[idx1 + 1] * idx2) + ThLowA[idx1]);
2253}
2254
2255unsigned short
2256SiS_GetFIFOThresholdB300(unsigned short idx1, unsigned short idx2)
2257{
2258 static const unsigned char ThLowB[8 * 3] = {
2259 81, 4,72, 6,88, 8,120,12,
2260 55, 4,54, 6,66, 8, 90,12,
2261 42, 4,45, 6,55, 8, 75,12
2262 };
2263
2264 return (unsigned short)((ThLowB[idx1 + 1] * idx2) + ThLowB[idx1]);
2265}
2266
2267static unsigned short
2268SiS_DoCalcDelay(struct SiS_Private *SiS_Pr, unsigned short MCLK, unsigned short VCLK,
2269 unsigned short colordepth, unsigned short key)
2270{
2271 unsigned short idx1, idx2;
2272 unsigned int longtemp = VCLK * colordepth;
2273
2274 SiS_GetFIFOThresholdIndex300(SiS_Pr, &idx1, &idx2);
2275
2276 if(key == 0) {
2277 longtemp *= SiS_GetFIFOThresholdA300(idx1, idx2);
2278 } else {
2279 longtemp *= SiS_GetFIFOThresholdB300(idx1, idx2);
2280 }
2281 idx1 = longtemp % (MCLK * 16);
2282 longtemp /= (MCLK * 16);
2283 if(idx1) longtemp++;
2284 return (unsigned short)longtemp;
2285}
2286
2287static unsigned short
2288SiS_CalcDelay(struct SiS_Private *SiS_Pr, unsigned short VCLK,
2289 unsigned short colordepth, unsigned short MCLK)
2290{
2291 unsigned short temp1, temp2;
2292
2293 temp2 = SiS_DoCalcDelay(SiS_Pr, MCLK, VCLK, colordepth, 0);
2294 temp1 = SiS_DoCalcDelay(SiS_Pr, MCLK, VCLK, colordepth, 1);
2295 if(temp1 < 4) temp1 = 4;
2296 temp1 -= 4;
2297 if(temp2 < temp1) temp2 = temp1;
2298 return temp2;
2299}
2300
2301static void
2302SiS_SetCRT1FIFO_300(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
2303 unsigned short RefreshRateTableIndex)
2304{
2305 unsigned short ThresholdLow = 0;
2306 unsigned short temp, index, VCLK, MCLK, colorth;
2307 static const unsigned short colortharray[6] = { 1, 1, 2, 2, 3, 4 };
2308
2309 if(ModeNo > 0x13) {
2310
2311
2312 if(SiS_Pr->UseCustomMode) {
2313 VCLK = SiS_Pr->CSRClock;
2314 } else {
2315 index = SiS_GetRefCRTVCLK(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWide);
2316 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
2317 }
2318
2319
2320 colorth = colortharray[(SiS_Pr->SiS_ModeType - ModeEGA)];
2321
2322
2323 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A) & 0x07;
2324 MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;
2325
2326 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xc3;
2327 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x16,0x3c,temp);
2328
2329 do {
2330 ThresholdLow = SiS_CalcDelay(SiS_Pr, VCLK, colorth, MCLK) + 1;
2331 if(ThresholdLow < 0x13) break;
2332 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x16,0xfc);
2333 ThresholdLow = 0x13;
2334 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) >> 6;
2335 if(!temp) break;
2336 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x16,0x3f,((temp - 1) << 6));
2337 } while(0);
2338
2339 } else ThresholdLow = 2;
2340
2341
2342 temp = (ThresholdLow << 4) | 0x0f;
2343 SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,temp);
2344
2345 temp = (ThresholdLow & 0x10) << 1;
2346 if(ModeNo > 0x13) temp |= 0x40;
2347 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0f,0x9f,temp);
2348
2349
2350 SiS_SetReg(SiS_Pr->SiS_P3c4,0x3B,0x09);
2351
2352
2353 temp = ThresholdLow + 3;
2354 if(temp > 0x0f) temp = 0x0f;
2355 SiS_SetReg(SiS_Pr->SiS_P3c4,0x09,temp);
2356}
2357
2358unsigned short
2359SiS_GetLatencyFactor630(struct SiS_Private *SiS_Pr, unsigned short index)
2360{
2361 static const unsigned char LatencyFactor[] = {
2362 97, 88, 86, 79, 77, 0,
2363 0, 87, 85, 78, 76, 54,
2364 97, 88, 86, 79, 77, 0,
2365 0, 79, 77, 70, 68, 48,
2366 80, 72, 69, 63, 61, 0,
2367 0, 70, 68, 61, 59, 37,
2368 86, 77, 75, 68, 66, 0,
2369 0, 68, 66, 59, 57, 37
2370 };
2371 static const unsigned char LatencyFactor730[] = {
2372 69, 63, 61,
2373 86, 79, 77,
2374 103, 96, 94,
2375 120,113,111,
2376 137,130,128
2377 };
2378
2379 if(SiS_Pr->ChipType == SIS_730) {
2380 return (unsigned short)LatencyFactor730[index];
2381 } else {
2382 return (unsigned short)LatencyFactor[index];
2383 }
2384}
2385
2386static unsigned short
2387SiS_CalcDelay2(struct SiS_Private *SiS_Pr, unsigned char key)
2388{
2389 unsigned short index;
2390
2391 if(SiS_Pr->ChipType == SIS_730) {
2392 index = ((key & 0x0f) * 3) + ((key & 0xc0) >> 6);
2393 } else {
2394 index = (key & 0xe0) >> 5;
2395 if(key & 0x10) index += 6;
2396 if(!(key & 0x01)) index += 24;
2397 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80) index += 12;
2398 }
2399 return SiS_GetLatencyFactor630(SiS_Pr, index);
2400}
2401
2402static void
2403SiS_SetCRT1FIFO_630(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
2404 unsigned short RefreshRateTableIndex)
2405{
2406 unsigned short ThresholdLow = 0;
2407 unsigned short i, data, VCLK, MCLK16, colorth = 0;
2408 unsigned int templ, datal;
2409 const unsigned char *queuedata = NULL;
2410 static const unsigned char FQBQData[21] = {
2411 0x01,0x21,0x41,0x61,0x81,
2412 0x31,0x51,0x71,0x91,0xb1,
2413 0x00,0x20,0x40,0x60,0x80,
2414 0x30,0x50,0x70,0x90,0xb0,
2415 0xff
2416 };
2417 static const unsigned char FQBQData730[16] = {
2418 0x34,0x74,0xb4,
2419 0x23,0x63,0xa3,
2420 0x12,0x52,0x92,
2421 0x01,0x41,0x81,
2422 0x00,0x40,0x80,
2423 0xff
2424 };
2425 static const unsigned short colortharray[6] = {
2426 1, 1, 2, 2, 3, 4
2427 };
2428
2429 i = 0;
2430
2431 if (SiS_Pr->ChipType == SIS_730)
2432 queuedata = &FQBQData730[0];
2433 else
2434 queuedata = &FQBQData[0];
2435
2436 if(ModeNo > 0x13) {
2437
2438
2439 if(SiS_Pr->UseCustomMode) {
2440 VCLK = SiS_Pr->CSRClock;
2441 } else {
2442 data = SiS_GetRefCRTVCLK(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWide);
2443 VCLK = SiS_Pr->SiS_VCLKData[data].CLOCK;
2444 }
2445
2446
2447 data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A) & 0x07;
2448 MCLK16 = SiS_Pr->SiS_MCLKData_0[data].CLOCK * 16;
2449
2450
2451 colorth = colortharray[(SiS_Pr->SiS_ModeType - ModeEGA)];
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
2632 if (VCLK < 234) data = 0x02;
2633 }
2634
2635 if(SiS_Pr->ChipType < SIS_315H) {
2636 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xFC,data);
2637 } else {
2638 if(SiS_Pr->ChipType > SIS_315PRO) {
2639 if(ModeNo > 0x13) data &= 0xfc;
2640 }
2641 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xF8,data);
2642 }
2643
2644 }
2645}
2646
2647static void
2648SiS_SetCRT1ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
2649 unsigned short ModeIdIndex, unsigned short RRTI)
2650{
2651 unsigned short data, infoflag = 0, modeflag;
2652#ifdef CONFIG_FB_SIS_315
2653 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
2654 unsigned short data2, data3;
2655#endif
2656
2657 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
2658
2659 if(SiS_Pr->UseCustomMode) {
2660 infoflag = SiS_Pr->CInfoFlag;
2661 } else {
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 GENBITSMASK(mask) GENMASK(1?mask,0?mask)
3323#define GETBITS(var,mask) (((var) & GENBITSMASK(mask)) >> (0?mask))
3324#define GETBITSTR(val,from,to) ((GETBITS(val,from)) << (0?to))
3325#endif
3326
3327void
3328SiS_CalcCRRegisters(struct SiS_Private *SiS_Pr, int depth)
3329{
3330 int x = 1;
3331
3332 SiS_Pr->CCRT1CRTC[0] = ((SiS_Pr->CHTotal >> 3) - 5) & 0xff;
3333 SiS_Pr->CCRT1CRTC[1] = (SiS_Pr->CHDisplay >> 3) - 1;
3334 SiS_Pr->CCRT1CRTC[2] = (SiS_Pr->CHBlankStart >> 3) - 1;
3335 SiS_Pr->CCRT1CRTC[3] = (((SiS_Pr->CHBlankEnd >> 3) - 1) & 0x1F) | 0x80;
3336 SiS_Pr->CCRT1CRTC[4] = (SiS_Pr->CHSyncStart >> 3) + 3;
3337 SiS_Pr->CCRT1CRTC[5] = ((((SiS_Pr->CHBlankEnd >> 3) - 1) & 0x20) << 2) |
3338 (((SiS_Pr->CHSyncEnd >> 3) + 3) & 0x1F);
3339
3340 SiS_Pr->CCRT1CRTC[6] = (SiS_Pr->CVTotal - 2) & 0xFF;
3341 SiS_Pr->CCRT1CRTC[7] = (((SiS_Pr->CVTotal - 2) & 0x100) >> 8)
3342 | (((SiS_Pr->CVDisplay - 1) & 0x100) >> 7)
3343 | (((SiS_Pr->CVSyncStart - x) & 0x100) >> 6)
3344 | (((SiS_Pr->CVBlankStart- 1) & 0x100) >> 5)
3345 | 0x10
3346 | (((SiS_Pr->CVTotal - 2) & 0x200) >> 4)
3347 | (((SiS_Pr->CVDisplay - 1) & 0x200) >> 3)
3348 | (((SiS_Pr->CVSyncStart - x) & 0x200) >> 2);
3349
3350 SiS_Pr->CCRT1CRTC[16] = ((((SiS_Pr->CVBlankStart - 1) & 0x200) >> 4) >> 5);
3351
3352 if(depth != 8) {
3353 if(SiS_Pr->CHDisplay >= 1600) SiS_Pr->CCRT1CRTC[16] |= 0x60;
3354 else if(SiS_Pr->CHDisplay >= 640) SiS_Pr->CCRT1CRTC[16] |= 0x40;
3355 }
3356
3357 SiS_Pr->CCRT1CRTC[8] = (SiS_Pr->CVSyncStart - x) & 0xFF;
3358 SiS_Pr->CCRT1CRTC[9] = ((SiS_Pr->CVSyncEnd - x) & 0x0F) | 0x80;
3359 SiS_Pr->CCRT1CRTC[10] = (SiS_Pr->CVDisplay - 1) & 0xFF;
3360 SiS_Pr->CCRT1CRTC[11] = (SiS_Pr->CVBlankStart - 1) & 0xFF;
3361 SiS_Pr->CCRT1CRTC[12] = (SiS_Pr->CVBlankEnd - 1) & 0xFF;
3362
3363 SiS_Pr->CCRT1CRTC[13] =
3364 GETBITSTR((SiS_Pr->CVTotal -2), 10:10, 0:0) |
3365 GETBITSTR((SiS_Pr->CVDisplay -1), 10:10, 1:1) |
3366 GETBITSTR((SiS_Pr->CVBlankStart-1), 10:10, 2:2) |
3367 GETBITSTR((SiS_Pr->CVSyncStart -x), 10:10, 3:3) |
3368 GETBITSTR((SiS_Pr->CVBlankEnd -1), 8:8, 4:4) |
3369 GETBITSTR((SiS_Pr->CVSyncEnd ), 4:4, 5:5) ;
3370
3371 SiS_Pr->CCRT1CRTC[14] =
3372 GETBITSTR((SiS_Pr->CHTotal >> 3) - 5, 9:8, 1:0) |
3373 GETBITSTR((SiS_Pr->CHDisplay >> 3) - 1, 9:8, 3:2) |
3374 GETBITSTR((SiS_Pr->CHBlankStart >> 3) - 1, 9:8, 5:4) |
3375 GETBITSTR((SiS_Pr->CHSyncStart >> 3) + 3, 9:8, 7:6) ;
3376
3377
3378 SiS_Pr->CCRT1CRTC[15] =
3379 GETBITSTR((SiS_Pr->CHBlankEnd >> 3) - 1, 7:6, 1:0) |
3380 GETBITSTR((SiS_Pr->CHSyncEnd >> 3) + 3, 5:5, 2:2) ;
3381}
3382
3383void
3384SiS_CalcLCDACRT1Timing(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
3385 unsigned short ModeIdIndex)
3386{
3387 unsigned short modeflag, tempax, tempbx = 0, remaining = 0;
3388 unsigned short VGAHDE = SiS_Pr->SiS_VGAHDE;
3389 int i, j;
3390
3391
3392 if(SiS_Pr->SiS_LCDInfo & LCDPass11) return;
3393
3394 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
3395
3396 if(modeflag & HalfDCLK) VGAHDE >>= 1;
3397
3398 SiS_Pr->CHDisplay = VGAHDE;
3399 SiS_Pr->CHBlankStart = VGAHDE;
3400
3401 SiS_Pr->CVDisplay = SiS_Pr->SiS_VGAVDE;
3402 SiS_Pr->CVBlankStart = SiS_Pr->SiS_VGAVDE;
3403
3404 if(SiS_Pr->ChipType < SIS_315H) {
3405#ifdef CONFIG_FB_SIS_300
3406 tempbx = SiS_Pr->SiS_VGAHT;
3407 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3408 tempbx = SiS_Pr->PanelHT;
3409 }
3410 if(modeflag & HalfDCLK) tempbx >>= 1;
3411 remaining = tempbx % 8;
3412#endif
3413 } else {
3414#ifdef CONFIG_FB_SIS_315
3415
3416 tempbx = SiS_Pr->PanelHT - SiS_Pr->PanelXRes;
3417 tempax = SiS_Pr->SiS_VGAHDE;
3418 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3419 tempax = SiS_Pr->PanelXRes;
3420 }
3421 tempbx += tempax;
3422 if(modeflag & HalfDCLK) tempbx -= VGAHDE;
3423#endif
3424 }
3425 SiS_Pr->CHTotal = SiS_Pr->CHBlankEnd = tempbx;
3426
3427 if(SiS_Pr->ChipType < SIS_315H) {
3428#ifdef CONFIG_FB_SIS_300
3429 if(SiS_Pr->SiS_VGAHDE == SiS_Pr->PanelXRes) {
3430 SiS_Pr->CHSyncStart = SiS_Pr->SiS_VGAHDE + ((SiS_Pr->PanelHRS + 1) & ~1);
3431 SiS_Pr->CHSyncEnd = SiS_Pr->CHSyncStart + SiS_Pr->PanelHRE;
3432 if(modeflag & HalfDCLK) {
3433 SiS_Pr->CHSyncStart >>= 1;
3434 SiS_Pr->CHSyncEnd >>= 1;
3435 }
3436 } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3437 tempax = (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) >> 1;
3438 tempbx = (SiS_Pr->PanelHRS + 1) & ~1;
3439 if(modeflag & HalfDCLK) {
3440 tempax >>= 1;
3441 tempbx >>= 1;
3442 }
3443 SiS_Pr->CHSyncStart = (VGAHDE + tempax + tempbx + 7) & ~7;
3444 tempax = SiS_Pr->PanelHRE + 7;
3445 if(modeflag & HalfDCLK) tempax >>= 1;
3446 SiS_Pr->CHSyncEnd = (SiS_Pr->CHSyncStart + tempax) & ~7;
3447 } else {
3448 SiS_Pr->CHSyncStart = SiS_Pr->SiS_VGAHDE;
3449 if(modeflag & HalfDCLK) {
3450 SiS_Pr->CHSyncStart >>= 1;
3451 tempax = ((SiS_Pr->CHTotal - SiS_Pr->CHSyncStart) / 3) << 1;
3452 SiS_Pr->CHSyncEnd = SiS_Pr->CHSyncStart + tempax;
3453 } else {
3454 SiS_Pr->CHSyncEnd = (SiS_Pr->CHSyncStart + (SiS_Pr->CHTotal / 10) + 7) & ~7;
3455 SiS_Pr->CHSyncStart += 8;
3456 }
3457 }
3458#endif
3459 } else {
3460#ifdef CONFIG_FB_SIS_315
3461 tempax = VGAHDE;
3462 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3463 tempbx = SiS_Pr->PanelXRes;
3464 if(modeflag & HalfDCLK) tempbx >>= 1;
3465 tempax += ((tempbx - tempax) >> 1);
3466 }
3467 tempax += SiS_Pr->PanelHRS;
3468 SiS_Pr->CHSyncStart = tempax;
3469 tempax += SiS_Pr->PanelHRE;
3470 SiS_Pr->CHSyncEnd = tempax;
3471#endif
3472 }
3473
3474 tempbx = SiS_Pr->PanelVT - SiS_Pr->PanelYRes;
3475 tempax = SiS_Pr->SiS_VGAVDE;
3476 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3477 tempax = SiS_Pr->PanelYRes;
3478 } else if(SiS_Pr->ChipType < SIS_315H) {
3479#ifdef CONFIG_FB_SIS_300
3480
3481 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3482 if((tempax + tempbx) == 438) tempbx += 16;
3483 } else if((SiS_Pr->SiS_LCDResInfo == Panel_800x600) ||
3484 (SiS_Pr->SiS_LCDResInfo == Panel_1024x600)) {
3485 tempax = 0;
3486 tempbx = SiS_Pr->SiS_VGAVT;
3487 }
3488#endif
3489 }
3490 SiS_Pr->CVTotal = SiS_Pr->CVBlankEnd = tempbx + tempax;
3491
3492 tempax = SiS_Pr->SiS_VGAVDE;
3493 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3494 tempax += (SiS_Pr->PanelYRes - tempax) >> 1;
3495 }
3496 tempax += SiS_Pr->PanelVRS;
3497 SiS_Pr->CVSyncStart = tempax;
3498 tempax += SiS_Pr->PanelVRE;
3499 SiS_Pr->CVSyncEnd = tempax;
3500 if(SiS_Pr->ChipType < SIS_315H) {
3501 SiS_Pr->CVSyncStart--;
3502 SiS_Pr->CVSyncEnd--;
3503 }
3504
3505 SiS_CalcCRRegisters(SiS_Pr, 8);
3506 SiS_Pr->CCRT1CRTC[15] &= ~0xF8;
3507 SiS_Pr->CCRT1CRTC[15] |= (remaining << 4);
3508 SiS_Pr->CCRT1CRTC[16] &= ~0xE0;
3509
3510 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
3511
3512 for(i = 0, j = 0; i <= 7; i++, j++) {
3513 SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
3514 }
3515 for(j = 0x10; i <= 10; i++, j++) {
3516 SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
3517 }
3518 for(j = 0x15; i <= 12; i++, j++) {
3519 SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
3520 }
3521 for(j = 0x0A; i <= 15; i++, j++) {
3522 SiS_SetReg(SiS_Pr->SiS_P3c4,j,SiS_Pr->CCRT1CRTC[i]);
3523 }
3524
3525 tempax = SiS_Pr->CCRT1CRTC[16] & 0xE0;
3526 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1F,tempax);
3527
3528 tempax = (SiS_Pr->CCRT1CRTC[16] & 0x01) << 5;
3529 if(modeflag & DoubleScanMode) tempax |= 0x80;
3530 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0x5F,tempax);
3531
3532}
3533
3534void
3535SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata,
3536 int xres, int yres,
3537 struct fb_var_screeninfo *var, bool writeres
3538)
3539{
3540 unsigned short HRE, HBE, HRS, HDE;
3541 unsigned short VRE, VBE, VRS, VDE;
3542 unsigned char sr_data, cr_data;
3543 int B, C, D, E, F, temp;
3544
3545 sr_data = crdata[14];
3546
3547
3548 HDE = crdata[1] | ((unsigned short)(sr_data & 0x0C) << 6);
3549 E = HDE + 1;
3550
3551
3552 HRS = crdata[4] | ((unsigned short)(sr_data & 0xC0) << 2);
3553 F = HRS - E - 3;
3554
3555 sr_data = crdata[15];
3556 cr_data = crdata[5];
3557
3558
3559 HBE = (crdata[3] & 0x1f) |
3560 ((unsigned short)(cr_data & 0x80) >> 2) |
3561 ((unsigned short)(sr_data & 0x03) << 6);
3562
3563
3564 HRE = (cr_data & 0x1f) | ((sr_data & 0x04) << 3);
3565
3566 temp = HBE - ((E - 1) & 255);
3567 B = (temp > 0) ? temp : (temp + 256);
3568
3569 temp = HRE - ((E + F + 3) & 63);
3570 C = (temp > 0) ? temp : (temp + 64);
3571
3572 D = B - F - C;
3573
3574 if(writeres) var->xres = xres = E * 8;
3575 var->left_margin = D * 8;
3576 var->right_margin = F * 8;
3577 var->hsync_len = C * 8;
3578
3579
3580 sr_data = crdata[13];
3581 cr_data = crdata[7];
3582
3583
3584 VDE = crdata[10] |
3585 ((unsigned short)(cr_data & 0x02) << 7) |
3586 ((unsigned short)(cr_data & 0x40) << 3) |
3587 ((unsigned short)(sr_data & 0x02) << 9);
3588 E = VDE + 1;
3589
3590
3591 VRS = crdata[8] |
3592 ((unsigned short)(cr_data & 0x04) << 6) |
3593 ((unsigned short)(cr_data & 0x80) << 2) |
3594 ((unsigned short)(sr_data & 0x08) << 7);
3595 F = VRS + 1 - E;
3596
3597
3598 VBE = crdata[12] | ((unsigned short)(sr_data & 0x10) << 4);
3599 temp = VBE - ((E - 1) & 511);
3600 B = (temp > 0) ? temp : (temp + 512);
3601
3602
3603 VRE = (crdata[9] & 0x0f) | ((sr_data & 0x20) >> 1);
3604 temp = VRE - ((E + F - 1) & 31);
3605 C = (temp > 0) ? temp : (temp + 32);
3606
3607 D = B - F - C;
3608
3609 if(writeres) var->yres = yres = E;
3610 var->upper_margin = D;
3611 var->lower_margin = F;
3612 var->vsync_len = C;
3613
3614 if((xres == 320) && ((yres == 200) || (yres == 240))) {
3615
3616
3617
3618
3619
3620
3621 var->left_margin = (400 - 376);
3622 var->right_margin = (328 - 320);
3623 var->hsync_len = (376 - 328);
3624
3625 }
3626
3627}
3628
3629
3630
3631
3632