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