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