1 /* $XFree86$ */
2 /* $XdotOrg$ */
3 /*
4 * Mode initializing code (CRT2 section)
5 * for SiS 300/305/540/630/730 and
6 * SiS 315/550/650/M650/651/661FX/M661xX/740/741(GX)/M741/330/660/M660/760/M760
7 * (Universal module for Linux kernel framebuffer and XFree86/X.org 4.x)
8 *
9 * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
10 *
11 * If distributed as part of the Linux kernel, the following license terms
12 * apply:
13 *
14 * * This program is free software; you can redistribute it and/or modify
15 * * it under the terms of the GNU General Public License as published by
16 * * the Free Software Foundation; either version 2 of the named License,
17 * * or any later version.
18 * *
19 * * This program is distributed in the hope that it will be useful,
20 * * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * * GNU General Public License for more details.
23 * *
24 * * You should have received a copy of the GNU General Public License
25 * * along with this program; if not, write to the Free Software
26 * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
27 *
28 * Otherwise, the following license terms apply:
29 *
30 * * Redistribution and use in source and binary forms, with or without
31 * * modification, are permitted provided that the following conditions
32 * * are met:
33 * * 1) Redistributions of source code must retain the above copyright
34 * * notice, this list of conditions and the following disclaimer.
35 * * 2) Redistributions in binary form must reproduce the above copyright
36 * * notice, this list of conditions and the following disclaimer in the
37 * * documentation and/or other materials provided with the distribution.
38 * * 3) The name of the author may not be used to endorse or promote products
39 * * derived from this software without specific prior written permission.
40 * *
41 * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
42 * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
43 * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
44 * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
45 * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46 * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
47 * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
48 * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
49 * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
50 * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51 *
52 * Author: Thomas Winischhofer <thomas@winischhofer.net>
53 *
54 * Formerly based on non-functional code-fragements for 300 series by SiS, Inc.
55 * Used by permission.
56 *
57 * TW says: This code looks awful, I know. But please don't do anything about
58 * this otherwise debugging will be hell.
59 * The code is extremely fragile as regards the different chipsets, different
60 * video bridges and combinations thereof. If anything is changed, extreme
61 * care has to be taken that that change doesn't break it for other chipsets,
62 * bridges or combinations thereof.
63 * All comments in this file are by me, regardless if marked TW or not.
64 *
65 */
66
67 #if 1
68 #define SET_EMI /* 302LV/ELV: Set EMI values */
69 #endif
70
71 #define COMPAL_HACK /* Needed for Compal 1400x1050 (EMI) */
72 #define COMPAQ_HACK /* Needed for Inventec/Compaq 1280x1024 (EMI) */
73 #define ASUS_HACK /* Needed for Asus A2H 1024x768 (EMI) */
74
75 #include "init301.h"
76
77 #ifdef SIS300
78 #include "oem300.h"
79 #endif
80
81 #ifdef SIS315H
82 #include "oem310.h"
83 #endif
84
85 #define SiS_I2CDELAY 1000
86 #define SiS_I2CDELAYSHORT 150
87
88 static USHORT SiS_GetBIOSLCDResInfo(SiS_Private *SiS_Pr);
89
90 /*********************************************/
91 /* HELPER: Lock/Unlock CRT2 */
92 /*********************************************/
93
94 void
SiS_UnLockCRT2(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)95 SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
96 {
97 if(HwInfo->jChipType >= SIS_315H)
98 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
99 else
100 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
101 }
102
103 void
SiS_LockCRT2(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)104 SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
105 {
106 if(HwInfo->jChipType >= SIS_315H)
107 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
108 else
109 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
110 }
111
112 /*********************************************/
113 /* HELPER: Write SR11 */
114 /*********************************************/
115
116 static void
SiS_SetRegSR11ANDOR(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,USHORT DataAND,USHORT DataOR)117 SiS_SetRegSR11ANDOR(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT DataAND, USHORT DataOR)
118 {
119 if(HwInfo->jChipType >= SIS_661) {
120 DataAND &= 0x0f;
121 DataOR &= 0x0f;
122 }
123 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,DataAND,DataOR);
124 }
125
126 /*********************************************/
127 /* HELPER: Get Pointer to LCD structure */
128 /*********************************************/
129
130 #ifdef SIS315H
131 static UCHAR *
GetLCDStructPtr661(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)132 GetLCDStructPtr661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
133 {
134 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
135 UCHAR *myptr = NULL;
136 USHORT romindex = 0;
137
138 /* Use the BIOS tables only for LVDS panels; DVI is unreliable
139 * due to the variaty of panels the BIOS doesn't know about.
140 */
141
142 if((SiS_Pr->SiS_ROMNew) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
143 myptr = (UCHAR *)SiS_LCDStruct661;
144 romindex = SISGETROMW(0x100);
145 if(romindex) {
146 romindex += ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x7d) & 0x1f) * 26);
147 myptr = &ROMAddr[romindex];
148 }
149 }
150 return myptr;
151 }
152
153 static USHORT
GetLCDStructPtr661_2(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)154 GetLCDStructPtr661_2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
155 {
156 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
157 USHORT romptr = 0;
158
159 /* Use the BIOS tables only for LVDS panels; DVI is unreliable
160 * due to the variaty of panels the BIOS doesn't know about.
161 */
162
163 if((SiS_Pr->SiS_ROMNew) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
164 romptr = SISGETROMW(0x102);
165 romptr += ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) * SiS_Pr->SiS661LCD2TableSize);
166 }
167
168 return(romptr);
169 }
170 #endif
171
172 /*********************************************/
173 /* Adjust Rate for CRT2 */
174 /*********************************************/
175
176 static BOOLEAN
SiS_AdjustCRT2Rate(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,USHORT * i,PSIS_HW_INFO HwInfo)177 SiS_AdjustCRT2Rate(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
178 USHORT RefreshRateTableIndex, USHORT *i,
179 PSIS_HW_INFO HwInfo)
180 {
181 USHORT checkmask=0,modeid,infoflag;
182
183 modeid = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].ModeID;
184
185 if(SiS_Pr->SiS_VBType & VB_SISVB) {
186
187 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
188
189 checkmask |= SupportRAMDAC2;
190 if(HwInfo->jChipType >= SIS_315H) {
191 checkmask |= SupportRAMDAC2_135;
192 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
193 checkmask |= SupportRAMDAC2_162;
194 if(SiS_Pr->SiS_VBType & VB_SIS301C) {
195 checkmask |= SupportRAMDAC2_202;
196 }
197 }
198 }
199
200 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
201
202 checkmask |= SupportLCD;
203 if(HwInfo->jChipType >= SIS_315H) {
204 if(SiS_Pr->SiS_VBType & VB_SISVB) {
205 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
206 if(modeid == 0x2e) checkmask |= Support64048060Hz;
207 }
208 }
209 }
210
211 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
212
213 checkmask |= SupportHiVision;
214
215 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750|SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
216
217 checkmask |= SupportTV;
218 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
219 checkmask |= SupportTV1024;
220 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
221 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
222 checkmask |= SupportYPbPr750p;
223 }
224 }
225 }
226
227 }
228
229 } else { /* LVDS */
230
231 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
232 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
233 checkmask |= SupportCHTV;
234 }
235 }
236
237 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
238 checkmask |= SupportLCD;
239 }
240
241 }
242
243 /* Look backwards in table for matching CRT2 mode */
244 for(; SiS_Pr->SiS_RefIndex[RefreshRateTableIndex+(*i)].ModeID == modeid; (*i)--) {
245 infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag;
246 if(infoflag & checkmask) return TRUE;
247 if((*i) == 0) break;
248 }
249
250 /* Look through the whole mode-section of the table from the beginning
251 * for a matching CRT2 mode if no mode was found yet.
252 */
253 for((*i) = 0; ; (*i)++) {
254 if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].ModeID != modeid) {
255 return FALSE;
256 }
257 infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag;
258 if(infoflag & checkmask) return TRUE;
259 }
260 return TRUE;
261 }
262
263 /*********************************************/
264 /* Get rate index */
265 /*********************************************/
266
267 USHORT
SiS_GetRatePtr(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,PSIS_HW_INFO HwInfo)268 SiS_GetRatePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
269 PSIS_HW_INFO HwInfo)
270 {
271 SHORT LCDRefreshIndex[] = { 0x00, 0x00, 0x01, 0x01,
272 0x01, 0x01, 0x01, 0x01,
273 0x01, 0x01, 0x01, 0x01,
274 0x01, 0x01, 0x01, 0x01,
275 0x00, 0x00, 0x00, 0x00 };
276 USHORT RefreshRateTableIndex,i,backup_i;
277 USHORT modeflag,index,temp,backupindex;
278
279 /* Do NOT check for UseCustomMode here, will skrew up FIFO */
280 if(ModeNo == 0xfe) return 0;
281
282 if(ModeNo <= 0x13) {
283 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
284 } else {
285 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
286 }
287
288 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
289 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
290 if(modeflag & HalfDCLK) return 0;
291 }
292 }
293
294 if(ModeNo < 0x14) return 0xFFFF;
295
296 index = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x33) >> SiS_Pr->SiS_SelectCRT2Rate) & 0x0F;
297 backupindex = index;
298
299 if(index > 0) index--;
300
301 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
302 if(SiS_Pr->SiS_VBType & VB_SISVB) {
303 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
304 if(SiS_Pr->SiS_VBType & VB_NoLCD) index = 0;
305 else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index = backupindex = 0;
306 }
307 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
308 if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) {
309 temp = LCDRefreshIndex[SiS_GetBIOSLCDResInfo(SiS_Pr)];
310 if(index > temp) index = temp;
311 }
312 }
313 } else {
314 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) index = 0;
315 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
316 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) index = 0;
317 }
318 }
319 }
320
321 RefreshRateTableIndex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
322 ModeNo = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].ModeID;
323
324 if(HwInfo->jChipType >= SIS_315H) {
325 if(!(SiS_Pr->SiS_VBInfo & DriverMode)) {
326 if( (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x105) ||
327 (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x107) ) {
328 if(backupindex <= 1) RefreshRateTableIndex++;
329 }
330 }
331 }
332
333 i = 0;
334 do {
335 if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + i].ModeID != ModeNo) break;
336 temp = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + i].Ext_InfoFlag;
337 temp &= ModeInfoFlag;
338 if(temp < SiS_Pr->SiS_ModeType) break;
339 i++;
340 index--;
341 } while(index != 0xFFFF);
342
343 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
344 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
345 temp = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + i - 1].Ext_InfoFlag;
346 if(temp & InterlaceMode) i++;
347 }
348 }
349
350 i--;
351
352 if((SiS_Pr->SiS_SetFlag & ProgrammingCRT2) && (!(SiS_Pr->SiS_VBInfo & DisableCRT2Display))) {
353 backup_i = i;
354 if(!(SiS_AdjustCRT2Rate(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, &i, HwInfo))) {
355 i = backup_i;
356 }
357 }
358
359 return(RefreshRateTableIndex + i);
360 }
361
362 /*********************************************/
363 /* STORE CRT2 INFO in CR34 */
364 /*********************************************/
365
366 static void
SiS_SaveCRT2Info(SiS_Private * SiS_Pr,USHORT ModeNo)367 SiS_SaveCRT2Info(SiS_Private *SiS_Pr, USHORT ModeNo)
368 {
369 USHORT temp1,temp2;
370
371 /* Store CRT1 ModeNo in CR34 */
372 SiS_SetReg(SiS_Pr->SiS_P3d4,0x34,ModeNo);
373 temp1 = (SiS_Pr->SiS_VBInfo & SetInSlaveMode) >> 8;
374 temp2 = ~(SetInSlaveMode >> 8);
375 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x31,temp2,temp1);
376 }
377
378 /*********************************************/
379 /* HELPER: GET SOME DATA FROM BIOS ROM */
380 /*********************************************/
381
382 #ifdef SIS300
383 static BOOLEAN
SiS_CR36BIOSWord23b(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)384 SiS_CR36BIOSWord23b(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
385 {
386 UCHAR *ROMAddr = (UCHAR *)HwInfo->pjVirtualRomBase;
387 USHORT temp,temp1;
388
389 if(SiS_Pr->SiS_UseROM) {
390 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
391 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xff) >> 4);
392 temp1 = SISGETROMW(0x23b);
393 if(temp1 & temp) return TRUE;
394 }
395 }
396 return FALSE;
397 }
398
399 static BOOLEAN
SiS_CR36BIOSWord23d(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)400 SiS_CR36BIOSWord23d(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
401 {
402 UCHAR *ROMAddr = (UCHAR *)HwInfo->pjVirtualRomBase;
403 USHORT temp,temp1;
404
405 if(SiS_Pr->SiS_UseROM) {
406 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
407 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xff) >> 4);
408 temp1 = SISGETROMW(0x23d);
409 if(temp1 & temp) return TRUE;
410 }
411 }
412 return FALSE;
413 }
414 #endif
415
416 /*********************************************/
417 /* HELPER: DELAY FUNCTIONS */
418 /*********************************************/
419
420 void
SiS_DDC2Delay(SiS_Private * SiS_Pr,USHORT delaytime)421 SiS_DDC2Delay(SiS_Private *SiS_Pr, USHORT delaytime)
422 {
423 USHORT i, j;
424
425 for(i=0; i<delaytime; i++) {
426 j += SiS_GetReg(SiS_Pr->SiS_P3c4,0x05);
427 }
428 }
429
430 static void
SiS_GenericDelay(SiS_Private * SiS_Pr,USHORT delay)431 SiS_GenericDelay(SiS_Private *SiS_Pr, USHORT delay)
432 {
433 USHORT temp,flag;
434
435 flag = SiS_GetRegByte(0x61) & 0x10;
436
437 while(delay) {
438 temp = SiS_GetRegByte(0x61) & 0x10;
439 if(temp == flag) continue;
440 flag = temp;
441 delay--;
442 }
443 }
444
445 #ifdef SIS315H
446 static void
SiS_LongDelay(SiS_Private * SiS_Pr,USHORT delay)447 SiS_LongDelay(SiS_Private *SiS_Pr, USHORT delay)
448 {
449 while(delay--) {
450 SiS_GenericDelay(SiS_Pr,0x19df);
451 }
452 }
453 #endif
454
455 static void
SiS_ShortDelay(SiS_Private * SiS_Pr,USHORT delay)456 SiS_ShortDelay(SiS_Private *SiS_Pr, USHORT delay)
457 {
458 while(delay--) {
459 SiS_GenericDelay(SiS_Pr,0x42);
460 }
461 }
462
463 static void
SiS_PanelDelay(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,USHORT DelayTime)464 SiS_PanelDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT DelayTime)
465 {
466 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
467 USHORT PanelID, DelayIndex, Delay=0;
468
469 if(HwInfo->jChipType < SIS_315H) {
470
471 #ifdef SIS300
472
473 PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
474 if(SiS_Pr->SiS_VBType & VB_SISVB) {
475 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x10)) PanelID = 0x12;
476 }
477 DelayIndex = PanelID >> 4;
478 if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) {
479 Delay = 3;
480 } else {
481 if(DelayTime >= 2) DelayTime -= 2;
482 if(!(DelayTime & 0x01)) {
483 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
484 } else {
485 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
486 }
487 if(SiS_Pr->SiS_UseROM) {
488 if(ROMAddr[0x220] & 0x40) {
489 if(!(DelayTime & 0x01)) Delay = (USHORT)ROMAddr[0x225];
490 else Delay = (USHORT)ROMAddr[0x226];
491 }
492 }
493 }
494 SiS_ShortDelay(SiS_Pr, Delay);
495
496 #endif /* SIS300 */
497
498 } else {
499
500 #ifdef SIS315H
501
502 if((HwInfo->jChipType >= SIS_661) ||
503 (HwInfo->jChipType <= SIS_315PRO) ||
504 (HwInfo->jChipType == SIS_330)) {
505
506 if(!(DelayTime & 0x01)) {
507 SiS_DDC2Delay(SiS_Pr, 0x1000);
508 } else {
509 SiS_DDC2Delay(SiS_Pr, 0x4000);
510 }
511
512 } else if((SiS_Pr->SiS_IF_DEF_LVDS == 1) /* ||
513 (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
514 (SiS_Pr->SiS_CustomT == CUT_CLEVO1400) */ ) { /* 315 series, LVDS; Special */
515
516 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
517 PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
518 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1400) {
519 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1b) & 0x10)) PanelID = 0x12;
520 }
521 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
522 DelayIndex = PanelID & 0x0f;
523 } else {
524 DelayIndex = PanelID >> 4;
525 }
526 if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) {
527 Delay = 3;
528 } else {
529 if(DelayTime >= 2) DelayTime -= 2;
530 if(!(DelayTime & 0x01)) {
531 Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[0];
532 } else {
533 Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[1];
534 }
535 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
536 if(ROMAddr[0x13c] & 0x40) {
537 if(!(DelayTime & 0x01)) {
538 Delay = (USHORT)ROMAddr[0x17e];
539 } else {
540 Delay = (USHORT)ROMAddr[0x17f];
541 }
542 }
543 }
544 }
545 SiS_ShortDelay(SiS_Pr, Delay);
546 }
547
548 } else if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 315 series, all bridges */
549
550 DelayIndex = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
551 if(!(DelayTime & 0x01)) {
552 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
553 } else {
554 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
555 }
556 Delay <<= 8;
557 SiS_DDC2Delay(SiS_Pr, Delay);
558
559 }
560
561 #endif /* SIS315H */
562
563 }
564 }
565
566 #ifdef SIS315H
567 static void
SiS_PanelDelayLoop(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,USHORT DelayTime,USHORT DelayLoop)568 SiS_PanelDelayLoop(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
569 USHORT DelayTime, USHORT DelayLoop)
570 {
571 int i;
572 for(i=0; i<DelayLoop; i++) {
573 SiS_PanelDelay(SiS_Pr, HwInfo, DelayTime);
574 }
575 }
576 #endif
577
578 /*********************************************/
579 /* HELPER: WAIT-FOR-RETRACE FUNCTIONS */
580 /*********************************************/
581
582 void
SiS_WaitRetrace1(SiS_Private * SiS_Pr)583 SiS_WaitRetrace1(SiS_Private *SiS_Pr)
584 {
585 USHORT watchdog;
586
587 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
588 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80)) return;
589
590 watchdog = 65535;
591 while((SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
592 watchdog = 65535;
593 while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
594 }
595
596 static void
SiS_WaitRetrace2(SiS_Private * SiS_Pr,USHORT reg)597 SiS_WaitRetrace2(SiS_Private *SiS_Pr, USHORT reg)
598 {
599 USHORT watchdog;
600
601 watchdog = 65535;
602 while((SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02) && --watchdog);
603 watchdog = 65535;
604 while((!(SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02)) && --watchdog);
605 }
606
607 static void
SiS_WaitVBRetrace(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)608 SiS_WaitVBRetrace(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
609 {
610 if(HwInfo->jChipType < SIS_315H) {
611 #ifdef SIS300
612 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
613 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return;
614 }
615 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x80)) {
616 SiS_WaitRetrace1(SiS_Pr);
617 } else {
618 SiS_WaitRetrace2(SiS_Pr, 0x25);
619 }
620 #endif
621 } else {
622 #ifdef SIS315H
623 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) {
624 SiS_WaitRetrace1(SiS_Pr);
625 } else {
626 SiS_WaitRetrace2(SiS_Pr, 0x30);
627 }
628 #endif
629 }
630 }
631
632 static void
SiS_VBWait(SiS_Private * SiS_Pr)633 SiS_VBWait(SiS_Private *SiS_Pr)
634 {
635 USHORT tempal,temp,i,j;
636
637 temp = 0;
638 for(i=0; i<3; i++) {
639 for(j=0; j<100; j++) {
640 tempal = SiS_GetRegByte(SiS_Pr->SiS_P3da);
641 if(temp & 0x01) {
642 if((tempal & 0x08)) continue;
643 else break;
644 } else {
645 if(!(tempal & 0x08)) continue;
646 else break;
647 }
648 }
649 temp ^= 0x01;
650 }
651 }
652
653 static void
SiS_VBLongWait(SiS_Private * SiS_Pr)654 SiS_VBLongWait(SiS_Private *SiS_Pr)
655 {
656 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
657 SiS_VBWait(SiS_Pr);
658 } else {
659 SiS_WaitRetrace1(SiS_Pr);
660 }
661 }
662
663 /*********************************************/
664 /* HELPER: MISC */
665 /*********************************************/
666
667 #ifdef SIS300
668 static BOOLEAN
SiS_Is301B(SiS_Private * SiS_Pr)669 SiS_Is301B(SiS_Private *SiS_Pr)
670 {
671 if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01) >= 0xb0) return TRUE;
672 return FALSE;
673 }
674 #endif
675
676 static BOOLEAN
SiS_CRT2IsLCD(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)677 SiS_CRT2IsLCD(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
678 {
679 USHORT flag;
680
681 if(HwInfo->jChipType == SIS_730) {
682 flag = SiS_GetReg(SiS_Pr->SiS_P3c4,0x13);
683 if(flag & 0x20) return TRUE;
684 }
685 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
686 if(flag & 0x20) return TRUE;
687 return FALSE;
688 }
689
690 BOOLEAN
SiS_IsDualEdge(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)691 SiS_IsDualEdge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
692 {
693 #ifdef SIS315H
694 USHORT flag;
695
696 if(HwInfo->jChipType >= SIS_315H) {
697 if((HwInfo->jChipType != SIS_650) || (SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) {
698 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
699 if(flag & EnableDualEdge) return TRUE;
700 }
701 }
702 #endif
703 return FALSE;
704 }
705
706 BOOLEAN
SiS_IsVAMode(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)707 SiS_IsVAMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
708 {
709 #ifdef SIS315H
710 USHORT flag;
711
712 if(HwInfo->jChipType >= SIS_315H) {
713 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
714 if((flag & EnableDualEdge) && (flag & SetToLCDA)) return TRUE;
715 }
716 #endif
717 return FALSE;
718 }
719
720 #ifdef SIS315H
721 static BOOLEAN
SiS_IsVAorLCD(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)722 SiS_IsVAorLCD(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
723 {
724 if(SiS_IsVAMode(SiS_Pr,HwInfo)) return TRUE;
725 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) return TRUE;
726 return FALSE;
727 }
728 #endif
729
730 static BOOLEAN
SiS_IsDualLink(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)731 SiS_IsDualLink(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
732 {
733 #ifdef SIS315H
734 if(HwInfo->jChipType >= SIS_315H) {
735 if((SiS_CRT2IsLCD(SiS_Pr, HwInfo)) ||
736 (SiS_IsVAMode(SiS_Pr, HwInfo))) {
737 if(SiS_Pr->SiS_LCDInfo & LCDDualLink) return TRUE;
738 }
739 }
740 #endif
741 return FALSE;
742 }
743
744 #ifdef SIS315H
745 static BOOLEAN
SiS_TVEnabled(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)746 SiS_TVEnabled(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
747 {
748 if((SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) != 0x0c) return TRUE;
749 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS301LV302LV)) {
750 if(SiS_GetReg(SiS_Pr->SiS_Part2Port,0x4d) & 0x10) return TRUE;
751 }
752 return FALSE;
753 }
754 #endif
755
756 #ifdef SIS315H
757 static BOOLEAN
SiS_LCDAEnabled(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)758 SiS_LCDAEnabled(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
759 {
760 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) return TRUE;
761 return FALSE;
762 }
763 #endif
764
765 #ifdef SIS315H
766 static BOOLEAN
SiS_WeHaveBacklightCtrl(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)767 SiS_WeHaveBacklightCtrl(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
768 {
769 if((HwInfo->jChipType >= SIS_315H) && (HwInfo->jChipType < SIS_661)) {
770 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0x10) return TRUE;
771 }
772 return FALSE;
773 }
774 #endif
775
776 #ifdef SIS315H
777 static BOOLEAN
SiS_IsNotM650orLater(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)778 SiS_IsNotM650orLater(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
779 {
780 USHORT flag;
781
782 if(HwInfo->jChipType == SIS_650) {
783 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f);
784 flag &= 0xF0;
785 /* Check for revision != A0 only */
786 if((flag == 0xe0) || (flag == 0xc0) ||
787 (flag == 0xb0) || (flag == 0x90)) return FALSE;
788 } else if(HwInfo->jChipType >= SIS_661) return FALSE;
789 return TRUE;
790 }
791 #endif
792
793 #ifdef SIS315H
794 static BOOLEAN
SiS_IsYPbPr(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)795 SiS_IsYPbPr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
796 {
797 USHORT flag;
798
799 if(HwInfo->jChipType >= SIS_315H) {
800 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
801 if(flag & EnableCHYPbPr) return TRUE; /* = YPrPb = 0x08 */
802 }
803 return FALSE;
804 }
805 #endif
806
807 #ifdef SIS315H
808 static BOOLEAN
SiS_IsChScart(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)809 SiS_IsChScart(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
810 {
811 USHORT flag;
812
813 if(HwInfo->jChipType >= SIS_315H) {
814 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
815 if(flag & EnableCHScart) return TRUE; /* = Scart = 0x04 */
816 }
817 return FALSE;
818 }
819 #endif
820
821 #ifdef SIS315H
822 static BOOLEAN
SiS_IsTVOrYPbPrOrScart(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)823 SiS_IsTVOrYPbPrOrScart(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
824 {
825 USHORT flag;
826
827 if(HwInfo->jChipType >= SIS_315H) {
828 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
829 if(flag & SetCRT2ToTV) return TRUE;
830 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
831 if(flag & EnableCHYPbPr) return TRUE; /* = YPrPb = 0x08 */
832 if(flag & EnableCHScart) return TRUE; /* = Scart = 0x04 - TW */
833 } else {
834 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
835 if(flag & SetCRT2ToTV) return TRUE;
836 }
837 return FALSE;
838 }
839 #endif
840
841 #ifdef SIS315H
842 static BOOLEAN
SiS_IsLCDOrLCDA(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)843 SiS_IsLCDOrLCDA(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
844 {
845 USHORT flag;
846
847 if(HwInfo->jChipType >= SIS_315H) {
848 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
849 if(flag & SetCRT2ToLCD) return TRUE;
850 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
851 if(flag & SetToLCDA) return TRUE;
852 } else {
853 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
854 if(flag & SetCRT2ToLCD) return TRUE;
855 }
856 return FALSE;
857 }
858 #endif
859
860 static BOOLEAN
SiS_BridgeIsOn(SiS_Private * SiS_Pr)861 SiS_BridgeIsOn(SiS_Private *SiS_Pr)
862 {
863 USHORT flag;
864
865 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
866 return TRUE;
867 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
868 flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
869 if((flag == 1) || (flag == 2)) return TRUE;
870 }
871 return FALSE;
872 }
873
874 static BOOLEAN
SiS_BridgeIsEnabled(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)875 SiS_BridgeIsEnabled(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
876 {
877 USHORT flag;
878
879 if(SiS_BridgeIsOn(SiS_Pr)) {
880 flag = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
881 if(HwInfo->jChipType < SIS_315H) {
882 flag &= 0xa0;
883 if((flag == 0x80) || (flag == 0x20)) return TRUE;
884 } else {
885 flag &= 0x50;
886 if((flag == 0x40) || (flag == 0x10)) return TRUE;
887 }
888 }
889 return FALSE;
890 }
891
892 static BOOLEAN
SiS_BridgeInSlavemode(SiS_Private * SiS_Pr)893 SiS_BridgeInSlavemode(SiS_Private *SiS_Pr)
894 {
895 USHORT flag1;
896
897 flag1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
898 if(flag1 & (SetInSlaveMode >> 8)) return TRUE;
899 return FALSE;
900 }
901
902 /*********************************************/
903 /* GET VIDEO BRIDGE CONFIG INFO */
904 /*********************************************/
905
906 /* Setup general purpose IO for Chrontel communication */
907 void
SiS_SetChrontelGPIO(SiS_Private * SiS_Pr,USHORT myvbinfo)908 SiS_SetChrontelGPIO(SiS_Private *SiS_Pr, USHORT myvbinfo)
909 {
910 unsigned long acpibase;
911 unsigned short temp;
912
913 if(!(SiS_Pr->SiS_ChSW)) return;
914
915 #ifndef LINUX_XF86
916 SiS_SetRegLong(0xcf8,0x80000874); /* get ACPI base */
917 acpibase = SiS_GetRegLong(0xcfc);
918 #else
919 acpibase = pciReadLong(0x00000800, 0x74);
920 #endif
921 acpibase &= 0xFFFF;
922 temp = SiS_GetRegShort((USHORT)(acpibase + 0x3c)); /* ACPI register 0x3c: GP Event 1 I/O mode select */
923 temp &= 0xFEFF;
924 SiS_SetRegShort((USHORT)(acpibase + 0x3c), temp);
925 temp = SiS_GetRegShort((USHORT)(acpibase + 0x3c));
926 temp = SiS_GetRegShort((USHORT)(acpibase + 0x3a)); /* ACPI register 0x3a: GP Pin Level (low/high) */
927 temp &= 0xFEFF;
928 if(!(myvbinfo & SetCRT2ToTV)) temp |= 0x0100;
929 SiS_SetRegShort((USHORT)(acpibase + 0x3a), temp);
930 temp = SiS_GetRegShort((USHORT)(acpibase + 0x3a));
931 }
932
933 void
SiS_GetVBInfo(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,PSIS_HW_INFO HwInfo,int checkcrt2mode)934 SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
935 PSIS_HW_INFO HwInfo, int checkcrt2mode)
936 {
937 USHORT tempax,tempbx,temp;
938 USHORT modeflag, resinfo=0;
939
940 if(ModeNo <= 0x13) {
941 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
942 } else if(SiS_Pr->UseCustomMode) {
943 modeflag = SiS_Pr->CModeFlag;
944 } else {
945 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
946 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
947 }
948
949 SiS_Pr->SiS_SetFlag = 0;
950
951 SiS_Pr->SiS_ModeType = modeflag & ModeInfoFlag;
952
953 tempbx = 0;
954 if(SiS_BridgeIsOn(SiS_Pr)) {
955 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
956 #if 0
957 if(HwInfo->jChipType < SIS_661) {
958 /* NO - YPbPr not set yet ! */
959 if(SiS_Pr->SiS_YPbPr & <all ypbpr except 525i>) {
960 temp &= (SetCRT2ToHiVision | SwitchCRT2 | SetSimuScanMode); /* 0x83 */
961 temp |= SetCRT2ToHiVision; /* 0x80 */
962 }
963 if(SiS_Pr->SiS_YPbPr & <ypbpr525i>) {
964 temp &= (SetCRT2ToHiVision | SwitchCRT2 | SetSimuScanMode); /* 0x83 */
965 temp |= SetCRT2ToSVIDEO; /* 0x08 */
966 }
967 }
968 #endif
969 tempbx |= temp;
970 tempax = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) << 8;
971 tempax &= (DriverMode | LoadDACFlag | SetNotSimuMode | SetPALTV);
972 tempbx |= tempax;
973
974 #ifdef SIS315H
975 if(HwInfo->jChipType >= SIS_315H) {
976 if(SiS_Pr->SiS_VBType & (VB_SIS301C|VB_SIS302B|VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)) {
977 if(ModeNo == 0x03) {
978 /* Mode 0x03 is never in driver mode */
979 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf);
980 }
981 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8))) {
982 /* Reset LCDA setting if not driver mode */
983 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
984 }
985 if(IS_SIS650) {
986 if(SiS_Pr->SiS_UseLCDA) {
987 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) {
988 if((ModeNo <= 0x13) || (!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) {
989 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA));
990 }
991 }
992 }
993 }
994 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
995 if((temp & (EnableDualEdge | SetToLCDA)) == (EnableDualEdge | SetToLCDA)) {
996 tempbx |= SetCRT2ToLCDA;
997 }
998 }
999
1000 if(SiS_Pr->SiS_VBType & (VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)) {
1001 tempbx &= ~(SetCRT2ToRAMDAC);
1002 }
1003
1004 if(HwInfo->jChipType >= SIS_661) {
1005 tempbx &= ~(SetCRT2ToYPbPr525750 | SetCRT2ToHiVision);
1006 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1007 if(SiS_Pr->SiS_VBType & (VB_SIS301C|VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)) {
1008 if(temp & 0x04) {
1009 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
1010 if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
1011 else tempbx |= SetCRT2ToYPbPr525750;
1012 }
1013 } else if(SiS_Pr->SiS_VBType & (VB_SIS301 | VB_SIS301B | VB_SIS302B)) {
1014 if(temp & 0x04) {
1015 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
1016 if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
1017 }
1018 }
1019 }
1020
1021 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1022 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1023 if(temp & SetToLCDA) {
1024 tempbx |= SetCRT2ToLCDA;
1025 }
1026 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1027 if(temp & EnableCHYPbPr) {
1028 tempbx |= SetCRT2ToCHYPbPr;
1029 }
1030 }
1031 }
1032 }
1033
1034 #endif /* SIS315H */
1035
1036 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1037 temp = SetCRT2ToSVIDEO |
1038 SetCRT2ToAVIDEO |
1039 SetCRT2ToSCART |
1040 SetCRT2ToLCDA |
1041 SetCRT2ToLCD |
1042 SetCRT2ToRAMDAC |
1043 SetCRT2ToHiVision |
1044 SetCRT2ToYPbPr525750;
1045 } else {
1046 if(HwInfo->jChipType >= SIS_315H) {
1047 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1048 temp = SetCRT2ToAVIDEO |
1049 SetCRT2ToSVIDEO |
1050 SetCRT2ToSCART |
1051 SetCRT2ToLCDA |
1052 SetCRT2ToLCD |
1053 SetCRT2ToCHYPbPr;
1054 } else {
1055 temp = SetCRT2ToLCDA |
1056 SetCRT2ToLCD;
1057 }
1058 } else {
1059 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1060 temp = SetCRT2ToTV | SetCRT2ToLCD;
1061 } else {
1062 temp = SetCRT2ToLCD;
1063 }
1064 }
1065 }
1066
1067 if(!(tempbx & temp)) {
1068 tempax = DisableCRT2Display;
1069 tempbx = 0;
1070 }
1071
1072 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1073 USHORT clearmask = ( DriverMode |
1074 DisableCRT2Display |
1075 LoadDACFlag |
1076 SetNotSimuMode |
1077 SetInSlaveMode |
1078 SetPALTV |
1079 SwitchCRT2 |
1080 SetSimuScanMode );
1081 if(tempbx & SetCRT2ToLCDA) tempbx &= (clearmask | SetCRT2ToLCDA);
1082 if(tempbx & SetCRT2ToRAMDAC) tempbx &= (clearmask | SetCRT2ToRAMDAC);
1083 if(tempbx & SetCRT2ToLCD) tempbx &= (clearmask | SetCRT2ToLCD);
1084 if(tempbx & SetCRT2ToSCART) tempbx &= (clearmask | SetCRT2ToSCART);
1085 if(tempbx & SetCRT2ToHiVision) tempbx &= (clearmask | SetCRT2ToHiVision);
1086 if(tempbx & SetCRT2ToYPbPr525750) tempbx &= (clearmask | SetCRT2ToYPbPr525750);
1087 } else {
1088 if(HwInfo->jChipType >= SIS_315H) {
1089 if(tempbx & SetCRT2ToLCDA) {
1090 tempbx &= (0xFF00|SwitchCRT2|SetSimuScanMode);
1091 }
1092 }
1093 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1094 if(tempbx & SetCRT2ToTV) {
1095 tempbx &= (0xFF00|SetCRT2ToTV|SwitchCRT2|SetSimuScanMode);
1096 }
1097 }
1098 if(tempbx & SetCRT2ToLCD) {
1099 tempbx &= (0xFF00|SetCRT2ToLCD|SwitchCRT2|SetSimuScanMode);
1100 }
1101 if(HwInfo->jChipType >= SIS_315H) {
1102 if(tempbx & SetCRT2ToLCDA) {
1103 tempbx |= SetCRT2ToLCD;
1104 }
1105 }
1106 }
1107
1108 if(tempax & DisableCRT2Display) {
1109 if(!(tempbx & (SwitchCRT2 | SetSimuScanMode))) {
1110 tempbx = SetSimuScanMode | DisableCRT2Display;
1111 }
1112 }
1113
1114 if(!(tempbx & DriverMode)) tempbx |= SetSimuScanMode;
1115
1116 /* LVDS/CHRONTEL (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */
1117 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
1118 if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
1119 ((SiS_Pr->SiS_VBType & VB_NoLCD) && (tempbx & SetCRT2ToLCD)) ) {
1120 modeflag &= (~CRT2Mode);
1121 }
1122 }
1123
1124 if(!(tempbx & SetSimuScanMode)) {
1125 if(tempbx & SwitchCRT2) {
1126 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1127 if( (HwInfo->jChipType >= SIS_315H) &&
1128 (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) ) {
1129 if(resinfo != SIS_RI_1600x1200) {
1130 tempbx |= SetSimuScanMode;
1131 }
1132 } else {
1133 tempbx |= SetSimuScanMode;
1134 }
1135 }
1136 } else {
1137 if(SiS_BridgeIsEnabled(SiS_Pr,HwInfo)) {
1138 if(!(tempbx & DriverMode)) {
1139 if(SiS_BridgeInSlavemode(SiS_Pr)) {
1140 tempbx |= SetSimuScanMode;
1141 }
1142 }
1143 }
1144 }
1145 }
1146
1147 if(!(tempbx & DisableCRT2Display)) {
1148 if(tempbx & DriverMode) {
1149 if(tempbx & SetSimuScanMode) {
1150 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1151 if( (HwInfo->jChipType >= SIS_315H) &&
1152 (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) ) {
1153 if(resinfo != SIS_RI_1600x1200) {
1154 tempbx |= SetInSlaveMode;
1155 }
1156 } else {
1157 tempbx |= SetInSlaveMode;
1158 }
1159 }
1160 }
1161 } else {
1162 tempbx |= SetInSlaveMode;
1163 }
1164 }
1165
1166 }
1167
1168 SiS_Pr->SiS_VBInfo = tempbx;
1169
1170 if(HwInfo->jChipType == SIS_630) {
1171 SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo);
1172 }
1173
1174 #ifdef TWDEBUG
1175 #ifdef LINUX_KERNEL
1176 printk(KERN_DEBUG "sisfb: (VBInfo= 0x%04x, SetFlag=0x%04x)\n",
1177 SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
1178 #endif
1179 #ifdef LINUX_XF86
1180 xf86DrvMsgVerb(0, X_PROBED, 3, "(init301: VBInfo=0x%04x, SetFlag=0x%04x)\n",
1181 SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
1182 #endif
1183 #endif
1184 }
1185
1186 /*********************************************/
1187 /* DETERMINE YPbPr MODE */
1188 /*********************************************/
1189
1190 void
SiS_SetYPbPr(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)1191 SiS_SetYPbPr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
1192 {
1193
1194 UCHAR temp;
1195
1196 /* Note: This variable is only used on 30xLV systems.
1197 * CR38 has a different meaning on LVDS/CH7019 systems.
1198 * On 661 and later, these bits moved to CR35.
1199 *
1200 * On 301, 301B, only HiVision 1080i is supported.
1201 * On 30xLV, 301C, only YPbPr 1080i is supported.
1202 */
1203
1204 SiS_Pr->SiS_YPbPr = 0;
1205 if(HwInfo->jChipType >= SIS_661) return;
1206
1207 if(SiS_Pr->SiS_VBType) {
1208 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1209 SiS_Pr->SiS_YPbPr = YPbPrHiVision;
1210 }
1211 }
1212
1213 if(HwInfo->jChipType >= SIS_315H) {
1214 if(SiS_Pr->SiS_VBType & (VB_SIS301LV302LV | VB_SIS301C)) {
1215 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1216 if(temp & 0x08) {
1217 switch((temp >> 4)) {
1218 case 0x00: SiS_Pr->SiS_YPbPr = YPbPr525i; break;
1219 case 0x01: SiS_Pr->SiS_YPbPr = YPbPr525p; break;
1220 case 0x02: SiS_Pr->SiS_YPbPr = YPbPr750p; break;
1221 case 0x03: SiS_Pr->SiS_YPbPr = YPbPrHiVision; break;
1222 }
1223 }
1224 }
1225 }
1226
1227 }
1228
1229 /*********************************************/
1230 /* DETERMINE TVMode flag */
1231 /*********************************************/
1232
1233 void
SiS_SetTVMode(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,PSIS_HW_INFO HwInfo)1234 SiS_SetTVMode(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, PSIS_HW_INFO HwInfo)
1235 {
1236 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
1237 USHORT temp, temp1, resinfo = 0, romindex = 0;
1238 UCHAR OutputSelect = *SiS_Pr->pSiS_OutputSelect;
1239
1240 SiS_Pr->SiS_TVMode = 0;
1241
1242 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
1243 if(SiS_Pr->UseCustomMode) return;
1244
1245 if(ModeNo > 0x13) {
1246 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1247 }
1248
1249 if(HwInfo->jChipType < SIS_661) {
1250
1251 if(SiS_Pr->SiS_VBInfo & SetPALTV) SiS_Pr->SiS_TVMode |= TVSetPAL;
1252
1253 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1254 temp = 0;
1255 if((HwInfo->jChipType == SIS_630) ||
1256 (HwInfo->jChipType == SIS_730)) {
1257 temp = 0x35;
1258 romindex = 0xfe;
1259 } else if(HwInfo->jChipType >= SIS_315H) {
1260 temp = 0x38;
1261 romindex = 0xf3;
1262 if(HwInfo->jChipType >= SIS_330) romindex = 0x11b;
1263 }
1264 if(temp) {
1265 if(romindex && SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
1266 OutputSelect = ROMAddr[romindex];
1267 if(!(OutputSelect & EnablePALMN)) {
1268 SiS_SetRegAND(SiS_Pr->SiS_P3d4,temp,0x3F);
1269 }
1270 }
1271 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,temp);
1272 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1273 if(temp1 & EnablePALM) { /* 0x40 */
1274 SiS_Pr->SiS_TVMode |= TVSetPALM;
1275 SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1276 } else if(temp1 & EnablePALN) { /* 0x80 */
1277 SiS_Pr->SiS_TVMode |= TVSetPALN;
1278 }
1279 } else {
1280 if(temp1 & EnableNTSCJ) { /* 0x40 */
1281 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1282 }
1283 }
1284 }
1285 /* Translate HiVision/YPbPr to our new flags */
1286 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1287 if(SiS_Pr->SiS_YPbPr == YPbPr750p) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1288 else if(SiS_Pr->SiS_YPbPr == YPbPr525p) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1289 else if(SiS_Pr->SiS_YPbPr == YPbPrHiVision) SiS_Pr->SiS_TVMode |= TVSetHiVision;
1290 else SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1291 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p | TVSetYPbPr525i)) {
1292 SiS_Pr->SiS_VBInfo &= ~SetCRT2ToHiVision;
1293 SiS_Pr->SiS_VBInfo |= SetCRT2ToYPbPr525750;
1294 } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
1295 SiS_Pr->SiS_TVMode |= TVSetPAL;
1296 }
1297 }
1298 } else if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1299 if(SiS_Pr->SiS_CHOverScan) {
1300 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
1301 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1302 if((temp & TVOverScan) || (SiS_Pr->SiS_CHOverScan == 1)) {
1303 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1304 }
1305 } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1306 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79);
1307 if((temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1)) {
1308 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1309 }
1310 }
1311 if(SiS_Pr->SiS_CHSOverScan) {
1312 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1313 }
1314 }
1315 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1316 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1317 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1318 if(temp & EnablePALM) SiS_Pr->SiS_TVMode |= TVSetPALM;
1319 else if(temp & EnablePALN) SiS_Pr->SiS_TVMode |= TVSetPALN;
1320 } else {
1321 if(temp & EnableNTSCJ) {
1322 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1323 }
1324 }
1325 }
1326 }
1327
1328 } else { /* 661 and later */
1329
1330 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1331 if(temp1 & 0x01) {
1332 SiS_Pr->SiS_TVMode |= TVSetPAL;
1333 if(temp1 & 0x08) {
1334 SiS_Pr->SiS_TVMode |= TVSetPALN;
1335 } else if(temp1 & 0x04) {
1336 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1337 SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1338 }
1339 SiS_Pr->SiS_TVMode |= TVSetPALM;
1340 }
1341 } else {
1342 if(temp1 & 0x02) {
1343 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1344 }
1345 }
1346 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1347 if(SiS_Pr->SiS_CHOverScan) {
1348 if((temp1 & 0x10) || (SiS_Pr->SiS_CHOverScan == 1)) {
1349 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1350 }
1351 }
1352 }
1353 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1354 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1355 temp1 &= 0xe0;
1356 if(temp1 == 0x00) SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1357 else if(temp1 == 0x20) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1358 else if(temp1 == 0x40) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1359 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1360 SiS_Pr->SiS_TVMode |= (TVSetHiVision | TVSetPAL);
1361 }
1362 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750 | SetCRT2ToHiVision)) {
1363 if(resinfo == SIS_RI_800x480 || resinfo == SIS_RI_1024x576 || resinfo == SIS_RI_1280x720) {
1364 SiS_Pr->SiS_TVMode |= TVAspect169;
1365 } else {
1366 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x39);
1367 if(temp1 & 0x02) {
1368 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetHiVision)) {
1369 SiS_Pr->SiS_TVMode |= TVAspect169;
1370 } else {
1371 SiS_Pr->SiS_TVMode |= TVAspect43LB;
1372 }
1373 } else {
1374 SiS_Pr->SiS_TVMode |= TVAspect43;
1375 }
1376 }
1377 }
1378 }
1379 }
1380
1381 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) SiS_Pr->SiS_TVMode |= TVSetPAL;
1382
1383 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1384
1385 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1386 SiS_Pr->SiS_TVMode |= TVSetPAL;
1387 SiS_Pr->SiS_TVMode &= ~(TVSetPALM | TVSetPALN | TVSetNTSCJ);
1388 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1389 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525i | TVSetYPbPr525p | TVSetYPbPr750p)) {
1390 SiS_Pr->SiS_TVMode &= ~(TVSetPAL | TVSetNTSCJ | TVSetPALM | TVSetPALN);
1391 }
1392 }
1393
1394 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
1395 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
1396 SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
1397 }
1398 }
1399
1400 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
1401 /* BIOS sets TVNTSC1024 without checking 525p here. Wrong? */
1402 if(!(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr525p | TVSetYPbPr750p))) {
1403 if(resinfo == SIS_RI_1024x768) {
1404 SiS_Pr->SiS_TVMode |= TVSetNTSC1024;
1405 }
1406 }
1407 }
1408
1409 SiS_Pr->SiS_TVMode |= TVRPLLDIV2XO;
1410 if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) &&
1411 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
1412 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1413 } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
1414 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1415 } else if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
1416 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
1417 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1418 }
1419 }
1420
1421 }
1422
1423 SiS_Pr->SiS_VBInfo &= ~SetPALTV;
1424
1425 #ifdef TWDEBUG
1426 xf86DrvMsg(0, X_INFO, "(init301: TVMode %x, VBInfo %x)\n", SiS_Pr->SiS_TVMode, SiS_Pr->SiS_VBInfo);
1427 #endif
1428 }
1429
1430 /*********************************************/
1431 /* GET LCD INFO */
1432 /*********************************************/
1433
1434 static USHORT
SiS_GetBIOSLCDResInfo(SiS_Private * SiS_Pr)1435 SiS_GetBIOSLCDResInfo(SiS_Private *SiS_Pr)
1436 {
1437 USHORT temp = SiS_Pr->SiS_LCDResInfo;
1438 /* Translate my LCDResInfo to BIOS value */
1439 if(temp == Panel_1280x768_2) temp = Panel_1280x768;
1440 if(temp == Panel_1280x768_3) temp = Panel_1280x768;
1441 return temp;
1442 }
1443
1444 static void
SiS_GetLCDInfoBIOS(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)1445 SiS_GetLCDInfoBIOS(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
1446 {
1447 #ifdef SIS315H
1448 UCHAR *ROMAddr;
1449 USHORT temp;
1450
1451 #ifdef TWDEBUG
1452 xf86DrvMsg(0, X_INFO, "Paneldata driver: [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n",
1453 SiS_Pr->PanelHT, SiS_Pr->PanelVT,
1454 SiS_Pr->PanelHRS, SiS_Pr->PanelHRE,
1455 SiS_Pr->PanelVRS, SiS_Pr->PanelVRE,
1456 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK,
1457 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A,
1458 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B);
1459 #endif
1460
1461 if((ROMAddr = GetLCDStructPtr661(SiS_Pr, HwInfo))) {
1462 if((temp = SISGETROMW(6)) != SiS_Pr->PanelHT) {
1463 SiS_Pr->SiS_NeedRomModeData = TRUE;
1464 SiS_Pr->PanelHT = temp;
1465 }
1466 if((temp = SISGETROMW(8)) != SiS_Pr->PanelVT) {
1467 SiS_Pr->SiS_NeedRomModeData = TRUE;
1468 SiS_Pr->PanelVT = temp;
1469 }
1470 SiS_Pr->PanelHRS = SISGETROMW(10);
1471 SiS_Pr->PanelHRE = SISGETROMW(12);
1472 SiS_Pr->PanelVRS = SISGETROMW(14);
1473 SiS_Pr->PanelVRE = SISGETROMW(16);
1474 SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
1475 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].CLOCK =
1476 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].CLOCK = (USHORT)((UCHAR)ROMAddr[18]);
1477 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2B =
1478 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_A = ROMAddr[19];
1479 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2C =
1480 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_B = ROMAddr[20];
1481
1482 #ifdef TWDEBUG
1483 xf86DrvMsg(0, X_INFO, "Paneldata BIOS: [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n",
1484 SiS_Pr->PanelHT, SiS_Pr->PanelVT,
1485 SiS_Pr->PanelHRS, SiS_Pr->PanelHRE,
1486 SiS_Pr->PanelVRS, SiS_Pr->PanelVRE,
1487 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK,
1488 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A,
1489 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B);
1490 #endif
1491
1492 }
1493 #endif
1494 }
1495
1496 void
SiS_GetLCDResInfo(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,PSIS_HW_INFO HwInfo)1497 SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
1498 PSIS_HW_INFO HwInfo)
1499 {
1500 #ifdef SIS300
1501 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
1502 #endif
1503 #ifdef SIS315H
1504 UCHAR *myptr = NULL;
1505 #endif
1506 USHORT temp,modeflag,resinfo=0;
1507 const unsigned char SiS300SeriesLCDRes[] =
1508 { 0, 1, 2, 3, 7, 4, 5, 8,
1509 0, 0, 10, 0, 0, 0, 0, 15 };
1510
1511 SiS_Pr->SiS_LCDResInfo = 0;
1512 SiS_Pr->SiS_LCDTypeInfo = 0;
1513 SiS_Pr->SiS_LCDInfo = 0;
1514 SiS_Pr->PanelHRS = 999; /* HSync start */
1515 SiS_Pr->PanelHRE = 999; /* HSync end */
1516 SiS_Pr->PanelVRS = 999; /* VSync start */
1517 SiS_Pr->PanelVRE = 999; /* VSync end */
1518 SiS_Pr->SiS_NeedRomModeData = FALSE;
1519
1520 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return;
1521
1522 if(ModeNo <= 0x13) {
1523 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
1524 } else if(SiS_Pr->UseCustomMode) {
1525 modeflag = SiS_Pr->CModeFlag;
1526 } else {
1527 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1528 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1529 }
1530
1531 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
1532 if(!temp) return;
1533
1534 if((HwInfo->jChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
1535 SiS_Pr->SiS_LCDTypeInfo = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x7c) >> 2;
1536 } else if((HwInfo->jChipType < SIS_315H) || (HwInfo->jChipType >= SIS_661)) {
1537 SiS_Pr->SiS_LCDTypeInfo = temp >> 4;
1538 } else {
1539 SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1;
1540 }
1541 temp &= 0x0f;
1542 if(HwInfo->jChipType < SIS_315H) {
1543 /* Translate 300 series LCDRes to 315 series for unified usage */
1544 temp = SiS300SeriesLCDRes[temp];
1545 }
1546
1547 if(HwInfo->jChipType == SIS_550) {
1548 if(temp == Panel310_640x480_2) temp = Panel_640x480_2;
1549 if(temp == Panel310_640x480_3) temp = Panel_640x480_3;
1550 }
1551
1552 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { /* SiS LVDS */
1553 if(temp == Panel310_1280x768) {
1554 temp = Panel_1280x768_2;
1555 #ifdef SIS315H
1556 if((myptr = GetLCDStructPtr661(SiS_Pr, HwInfo))) {
1557 if((myptr[8] | (myptr[9] << 8)) == 798) temp = Panel_1280x768_3;
1558 }
1559 #endif
1560 }
1561 }
1562
1563 SiS_Pr->SiS_LCDResInfo = temp;
1564
1565 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1566 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
1567 SiS_Pr->SiS_LCDResInfo = Panel_Barco1366;
1568 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
1569 SiS_Pr->SiS_LCDResInfo = Panel_848x480;
1570 }
1571 }
1572
1573 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1574 if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)
1575 SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMin301;
1576 } else {
1577 if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMinLVDS)
1578 SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS;
1579 }
1580
1581 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1582 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1583
1584 switch(SiS_Pr->SiS_LCDResInfo) {
1585 case Panel_320x480: SiS_Pr->PanelXRes = 320; SiS_Pr->PanelYRes = 480;
1586 SiS_Pr->PanelHT = 400; SiS_Pr->PanelVT = 525;
1587 SiS_Pr->PanelVCLKIdx300 = VCLK28;
1588 SiS_Pr->PanelVCLKIdx315 = VCLK28;
1589 break;
1590 case Panel_640x480_2:
1591 case Panel_640x480_3: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
1592 SiS_Pr->PanelVRS = 24; SiS_Pr->PanelVRE = 3;
1593 SiS_Pr->PanelVCLKIdx300 = VCLK28;
1594 SiS_Pr->PanelVCLKIdx315 = VCLK28;
1595 break;
1596 case Panel_640x480: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
1597 SiS_Pr->PanelVRE = 3;
1598 SiS_Pr->PanelVCLKIdx300 = VCLK28;
1599 SiS_Pr->PanelVCLKIdx315 = VCLK28;
1600 break;
1601 case Panel_800x600: SiS_Pr->PanelXRes = 800; SiS_Pr->PanelYRes = 600;
1602 SiS_Pr->PanelHT = 1056; SiS_Pr->PanelVT = 628;
1603 SiS_Pr->PanelHRS = 40; SiS_Pr->PanelHRE = 128;
1604 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 4;
1605 SiS_Pr->PanelVCLKIdx300 = VCLK40;
1606 SiS_Pr->PanelVCLKIdx315 = VCLK40;
1607 break;
1608 case Panel_1024x600: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 600;
1609 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 800;
1610 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
1611 SiS_Pr->PanelVRS = 2 /* 88 */ ; SiS_Pr->PanelVRE = 6;
1612 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1613 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1614 break;
1615 case Panel_1024x768: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768;
1616 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1617 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
1618 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1619 if(HwInfo->jChipType < SIS_315H) {
1620 SiS_Pr->PanelHRS = 23;
1621 SiS_Pr->PanelVRE = 5;
1622 }
1623 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1624 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1625 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1626 break;
1627 case Panel_1152x768: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 768;
1628 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1629 SiS_Pr->PanelHRS = 24;
1630 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1631 if(HwInfo->jChipType < SIS_315H) {
1632 SiS_Pr->PanelHRS = 23;
1633 SiS_Pr->PanelVRE = 5;
1634 }
1635 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1636 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1637 break;
1638 case Panel_1152x864: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 864;
1639 break;
1640 case Panel_1280x720: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 720;
1641 SiS_Pr->PanelHT = 1650; SiS_Pr->PanelVT = 750;
1642 SiS_Pr->PanelHRS = 110; SiS_Pr->PanelHRE = 40;
1643 SiS_Pr->PanelVRS = 5; SiS_Pr->PanelVRE = 5;
1644 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x720;
1645 /* Data above for TMDS (projector); get from BIOS for LVDS */
1646 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1647 break;
1648 case Panel_1280x768: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768;
1649 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 802;
1650 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRS = 112;
1651 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1652 SiS_Pr->PanelVCLKIdx300 = VCLK81_300;
1653 SiS_Pr->PanelVCLKIdx315 = VCLK81_315;
1654 break;
1655 case Panel_1280x768_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768;
1656 SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 806;
1657 SiS_Pr->PanelHRS = 16; SiS_Pr->PanelHRE = 64;
1658 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1659 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_2;
1660 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1661 break;
1662 case Panel_1280x768_3: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768;
1663 SiS_Pr->PanelHT = 1664; SiS_Pr->PanelVT = 798;
1664 SiS_Pr->PanelHRS = 64; SiS_Pr->PanelHRE = 128;
1665 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 7;
1666 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_3;
1667 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1668 break;
1669 case Panel_1280x800: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800;
1670 SiS_Pr->PanelHT = 1656; SiS_Pr->PanelVT = 841; /* 1408, 816 */
1671 SiS_Pr->PanelHRS = 32; SiS_Pr->PanelHRE = 312; /* 16, 64 */
1672 SiS_Pr->PanelVRS = 16; SiS_Pr->PanelVRE = 8; /* 4, 3 */
1673 SiS_Pr->PanelVCLKIdx315 = VCLK83_315;
1674 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1675 break;
1676 case Panel_1280x960: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 960;
1677 SiS_Pr->PanelHT = 1800; SiS_Pr->PanelVT = 1000;
1678 SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
1679 SiS_Pr->PanelVCLKIdx315 = VCLK108_3_315;
1680 if(resinfo == SIS_RI_1280x1024) {
1681 SiS_Pr->PanelVCLKIdx300 = VCLK100_300;
1682 SiS_Pr->PanelVCLKIdx315 = VCLK100_315;
1683 }
1684 break;
1685 case Panel_1280x1024: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024;
1686 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1687 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1688 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1689 SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
1690 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1691 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1692 break;
1693 case Panel_1400x1050: SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050;
1694 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1695 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112; /* HRE OK for LVDS, not for LCDA */
1696 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1697 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1698 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1699 break;
1700 case Panel_1600x1200: SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200;
1701 SiS_Pr->PanelHT = 2160; SiS_Pr->PanelVT = 1250;
1702 SiS_Pr->PanelHRS = 64; SiS_Pr->PanelHRE = 192;
1703 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1704 SiS_Pr->PanelVCLKIdx315 = VCLK162_315;
1705 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1706 break;
1707 case Panel_1680x1050: SiS_Pr->PanelXRes = 1680; SiS_Pr->PanelYRes = 1050;
1708 SiS_Pr->PanelHT = 1900; SiS_Pr->PanelVT = 1066;
1709 SiS_Pr->PanelHRS = 26; SiS_Pr->PanelHRE = 76;
1710 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1711 SiS_Pr->PanelVCLKIdx315 = VCLK121_315;
1712 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1713 break;
1714 case Panel_Custom: SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX;
1715 SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY;
1716 SiS_Pr->PanelHT = SiS_Pr->CHTotal;
1717 SiS_Pr->PanelVT = SiS_Pr->CVTotal;
1718 if(SiS_Pr->CP_PreferredIndex != -1) {
1719 SiS_Pr->PanelXRes = SiS_Pr->CP_HDisplay[SiS_Pr->CP_PreferredIndex];
1720 SiS_Pr->PanelYRes = SiS_Pr->CP_VDisplay[SiS_Pr->CP_PreferredIndex];
1721 SiS_Pr->PanelHT = SiS_Pr->CP_HTotal[SiS_Pr->CP_PreferredIndex];
1722 SiS_Pr->PanelVT = SiS_Pr->CP_VTotal[SiS_Pr->CP_PreferredIndex];
1723 SiS_Pr->PanelHRS = SiS_Pr->CP_HSyncStart[SiS_Pr->CP_PreferredIndex];
1724 SiS_Pr->PanelHRE = SiS_Pr->CP_HSyncEnd[SiS_Pr->CP_PreferredIndex];
1725 SiS_Pr->PanelVRS = SiS_Pr->CP_VSyncStart[SiS_Pr->CP_PreferredIndex];
1726 SiS_Pr->PanelVRE = SiS_Pr->CP_VSyncEnd[SiS_Pr->CP_PreferredIndex];
1727 SiS_Pr->PanelHRS -= SiS_Pr->PanelXRes;
1728 SiS_Pr->PanelHRE -= SiS_Pr->PanelHRS;
1729 SiS_Pr->PanelVRS -= SiS_Pr->PanelYRes;
1730 SiS_Pr->PanelVRE -= SiS_Pr->PanelVRS;
1731 }
1732 break;
1733 case Panel_Barco1366: SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024;
1734 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1735 break;
1736 case Panel_848x480: SiS_Pr->PanelXRes = 848; SiS_Pr->PanelYRes = 480;
1737 SiS_Pr->PanelHT = 1088; SiS_Pr->PanelVT = 525;
1738 break;
1739 default: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768;
1740 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1741 break;
1742 }
1743
1744 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
1745 SiS_Pr->SiS_LCDInfo = temp & ~0x000e;
1746
1747 if(!(SiS_Pr->UsePanelScaler)) SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1748 else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1749
1750 #ifdef SIS315H
1751 if(HwInfo->jChipType >= SIS_661) {
1752 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1753 if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1754 }
1755 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
1756 if(SiS_Pr->SiS_ROMNew) {
1757 if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1758 } else if((myptr = GetLCDStructPtr661(SiS_Pr, HwInfo))) {
1759 if(myptr[2] & 0x01) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1760 }
1761 }
1762 } else if(HwInfo->jChipType >= SIS_315H) {
1763 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1764 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1765 }
1766 if((SiS_Pr->SiS_ROMNew) && (!(SiS_Pr->PanelSelfDetected))) {
1767 SiS_Pr->SiS_LCDInfo &= ~(LCDRGB18Bit);
1768 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1769 if(temp & 0x01) SiS_Pr->SiS_LCDInfo |= LCDRGB18Bit;
1770 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
1771 if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1772 }
1773 }
1774 }
1775 #endif
1776
1777 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1778 /* Always center screen on LVDS (if scaling is disabled) */
1779 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1780 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
1781 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
1782 /* Always center screen on SiS LVDS (if scaling is disabled) */
1783 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1784 } else {
1785 /* By default, pass 1:1 on SiS TMDS (if scaling is disabled) */
1786 SiS_Pr->SiS_LCDInfo |= LCDPass11;
1787 if(SiS_Pr->CenterScreen == 1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1788 }
1789 }
1790
1791 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1792 if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
1793 SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20; /* neg h/v sync, RGB24(D0 = 0) */
1794 }
1795 }
1796
1797 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1798 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
1799 if(modeflag & NoSupportLCDScale) {
1800 /* No scaling for this mode on any panel */
1801 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1802 }
1803 switch(SiS_Pr->SiS_LCDResInfo) {
1804 case Panel_Custom:
1805 /* For non-standard LCD resolution, we let the panel scale */
1806 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1807 break;
1808 case Panel_1280x720:
1809 if(SiS_Pr->PanelHT == 1650) {
1810 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1811 }
1812 case Panel_1280x768: /* TMDS only */
1813 /* No idea about the timing and zoom factors */
1814 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1815 break;
1816 case Panel_1280x960:
1817 SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1818 break;
1819 case Panel_1280x1024:
1820 if(SiS_Pr->SiS_VBType & VB_SISTMDS) {
1821 if(ModeNo == 0x7c || ModeNo == 0x7d || ModeNo == 0x7e ||
1822 ModeNo == 0x79 || ModeNo == 0x75 || ModeNo == 0x78 ||
1823 ModeNo == 0x14 || ModeNo == 0x15 || ModeNo == 0x16) {
1824 /* We do not scale to 1280x720/800/960 (B/C bridges only) */
1825 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1826 }
1827 if(((HwInfo->jChipType >= SIS_315H) &&
1828 (ModeNo == 0x23 || ModeNo == 0x24 || ModeNo == 0x25)) ||
1829 ((HwInfo->jChipType < SIS_315H) &&
1830 (ModeNo == 0x55 || ModeNo == 0x5a || ModeNo == 0x5b))) {
1831 /* We do not scale to 1280x768 (B/C bridges only) */
1832 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1833 }
1834 }
1835 break;
1836 case Panel_1400x1050:
1837 if(SiS_Pr->SiS_VBType & VB_SISTMDS) {
1838 if(ModeNo == 0x7c || ModeNo == 0x7d || ModeNo == 0x7e ||
1839 ModeNo == 0x79 || ModeNo == 0x75 || ModeNo == 0x78 ||
1840 ModeNo == 0x14 || ModeNo == 0x15 || ModeNo == 0x16 ||
1841 ModeNo == 0x23 || ModeNo == 0x24 || ModeNo == 0x25) {
1842 /* Do not scale to 1280x720/768/800/960 (B/C bridges only) */
1843 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1844 }
1845 }
1846 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
1847 if(ModeNo == 0x79 || ModeNo == 0x75 || ModeNo == 0x78) {
1848 if(SiS_Pr->UsePanelScaler == -1) {
1849 /* Do not scale to 1280x720 by default (LVDS bridges) */
1850 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1851 }
1852 }
1853 }
1854 if(ModeNo == 0x3a || ModeNo == 0x4d || ModeNo == 0x65) {
1855 /* Do not scale to 1280x1024 (all bridges) */
1856 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1857 }
1858 break;
1859 case Panel_1600x1200:
1860 if(SiS_Pr->SiS_VBType & VB_SISTMDS) {
1861 /* No idea about the timing and zoom factors (C bridge only) */
1862 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1863 }
1864 break;
1865 }
1866 }
1867 }
1868
1869 #ifdef SIS300
1870 if(HwInfo->jChipType < SIS_315H) {
1871 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1872 if(SiS_Pr->SiS_UseROM) {
1873 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
1874 if(!(ROMAddr[0x235] & 0x02)) {
1875 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
1876 }
1877 }
1878 }
1879 } else if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
1880 if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
1881 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
1882 }
1883 }
1884 }
1885 #endif
1886
1887 /* Special cases */
1888 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
1889 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
1890 }
1891
1892 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) {
1893 SiS_Pr->SiS_LCDInfo |= LCDPass11;
1894 }
1895
1896 if(SiS_Pr->UseCustomMode) {
1897 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
1898 }
1899
1900 /* (In)validate LCDPass11 flag */
1901 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
1902 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1903 }
1904
1905 /* Special cases */
1906 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
1907 (SiS_Pr->SiS_IF_DEF_DSTN) ||
1908 (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
1909 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
1910 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ) {
1911 SiS_Pr->PanelHRS = 999;
1912 SiS_Pr->PanelHRE = 999;
1913 }
1914
1915 if( (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
1916 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
1917 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ) {
1918 SiS_Pr->PanelVRS = 999;
1919 SiS_Pr->PanelVRE = 999;
1920 }
1921
1922 #ifdef SIS315H
1923 if((HwInfo->jChipType >= SIS_315H) && (HwInfo->jChipType < SIS_661)) {
1924 if(!(SiS_Pr->SiS_ROMNew)) {
1925 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
1926 /* Enable 302LV/302ELV dual link mode.
1927 * For 661, this is done above.
1928 */
1929 if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) &&
1930 (SiS_Pr->SiS_LCDResInfo == Panel_1024x768)) {
1931 /* (Sets this in SenseLCD; new paneltypes) */
1932 SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1933 }
1934 if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
1935 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
1936 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
1937 (SiS_Pr->SiS_LCDResInfo == Panel_1680x1050)) {
1938 SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1939 }
1940 }
1941 }
1942 }
1943 #endif
1944
1945 if(!((HwInfo->jChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
1946
1947 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1948 if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
1949 if(ModeNo == 0x12) {
1950 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
1951 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
1952 }
1953 } else if(ModeNo > 0x13) {
1954 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
1955 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
1956 if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) {
1957 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
1958 }
1959 }
1960 }
1961 }
1962 }
1963 }
1964
1965 if(modeflag & HalfDCLK) {
1966 if(SiS_Pr->SiS_IF_DEF_TRUMPION == 1) {
1967 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
1968 } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1969 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
1970 } else if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) {
1971 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
1972 } else if(ModeNo > 0x13) {
1973 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
1974 if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
1975 } else if(SiS_Pr->SiS_LCDResInfo == Panel_800x600) {
1976 if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
1977 }
1978 }
1979 }
1980
1981 }
1982
1983 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
1984 if(SiS_Pr->SiS_VBInfo & SetNotSimuMode) {
1985 SiS_Pr->SiS_SetFlag |= LCDVESATiming;
1986 }
1987 } else {
1988 SiS_Pr->SiS_SetFlag |= LCDVESATiming;
1989 }
1990
1991 #ifdef LINUX_KERNEL
1992 #ifdef TWDEBUG
1993 printk(KERN_DEBUG "sisfb: (LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n",
1994 SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo);
1995 #endif
1996 #endif
1997 #ifdef LINUX_XF86
1998 xf86DrvMsgVerb(0, X_PROBED, 4,
1999 "(init301: LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x SetFlag=0x%04x)\n",
2000 SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo, SiS_Pr->SiS_SetFlag);
2001 #endif
2002 }
2003
2004 /*********************************************/
2005 /* GET VCLK */
2006 /*********************************************/
2007
2008 USHORT
SiS_GetVCLK2Ptr(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo)2009 SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2010 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
2011 {
2012 USHORT CRT2Index,VCLKIndex=0,VCLKIndexGEN=0;
2013 USHORT modeflag,resinfo,tempbx;
2014 const UCHAR *CHTVVCLKPtr = NULL;
2015
2016 if(ModeNo <= 0x13) {
2017 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2018 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
2019 CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2020 VCLKIndexGEN = (SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)) >> 2) & 0x03;
2021 } else {
2022 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2023 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2024 CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2025 VCLKIndexGEN = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
2026 if(HwInfo->jChipType < SIS_315H) VCLKIndexGEN &= 0x3f;
2027 }
2028
2029 if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 30x/B/LV */
2030
2031 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2032
2033 CRT2Index >>= 6;
2034 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /* LCD */
2035
2036 if(HwInfo->jChipType < SIS_315H) {
2037 VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2038 } else {
2039 VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2040 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2041 VCLKIndex = VCLKIndexGEN;
2042 switch(resinfo) {
2043 case SIS_RI_1280x720: VCLKIndex = VCLK_1280x720;
2044 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x720) {
2045 if(SiS_Pr->PanelHT == 1344) {
2046 VCLKIndex = VCLK_1280x720_2;
2047 }
2048 }
2049 break;
2050 case SIS_RI_720x480: VCLKIndex = VCLK_720x480; break;
2051 case SIS_RI_720x576: VCLKIndex = VCLK_720x576; break;
2052 case SIS_RI_768x576: VCLKIndex = VCLK_768x576; break;
2053 case SIS_RI_848x480: VCLKIndex = VCLK_848x480; break;
2054 case SIS_RI_856x480: VCLKIndex = VCLK_856x480; break;
2055 case SIS_RI_800x480: VCLKIndex = VCLK_800x480; break;
2056 case SIS_RI_1024x576: VCLKIndex = VCLK_1024x576; break;
2057 case SIS_RI_1152x864: VCLKIndex = VCLK_1152x864; break;
2058 case SIS_RI_1360x768: VCLKIndex = VCLK_1360x768; break;
2059 }
2060
2061 if(ModeNo <= 0x13) {
2062 if(HwInfo->jChipType <= SIS_315PRO) {
2063 if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
2064 } else {
2065 if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x00;
2066 }
2067 }
2068 if(HwInfo->jChipType <= SIS_315PRO) {
2069 if(VCLKIndex == 0) VCLKIndex = 0x41;
2070 if(VCLKIndex == 1) VCLKIndex = 0x43;
2071 if(VCLKIndex == 4) VCLKIndex = 0x44;
2072 }
2073 }
2074 }
2075
2076 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* TV */
2077
2078 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
2079 if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = HiTVVCLKDIV2;
2080 else VCLKIndex = HiTVVCLK;
2081 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
2082 if(modeflag & Charx8Dot) VCLKIndex = HiTVSimuVCLK;
2083 else VCLKIndex = HiTVTextVCLK;
2084 }
2085 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) VCLKIndex = YPbPr750pVCLK;
2086 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) VCLKIndex = TVVCLKDIV2;
2087 else if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = TVVCLKDIV2;
2088 else VCLKIndex = TVVCLK;
2089
2090 if(HwInfo->jChipType < SIS_315H) VCLKIndex += TVCLKBASE_300;
2091 else VCLKIndex += TVCLKBASE_315;
2092
2093 } else { /* VGA2 */
2094
2095 VCLKIndex = VCLKIndexGEN;
2096 if(HwInfo->jChipType < SIS_315H) {
2097 if(ModeNo > 0x13) {
2098 if( (HwInfo->jChipType == SIS_630) &&
2099 (HwInfo->jChipRevision >= 0x30)) {
2100 if(VCLKIndex == 0x14) VCLKIndex = 0x34;
2101 }
2102 /* Better VGA2 clock for 1280x1024@75 */
2103 if(VCLKIndex == 0x17) VCLKIndex = 0x45;
2104 }
2105 }
2106 }
2107
2108 } else { /* If not programming CRT2 */
2109
2110 VCLKIndex = VCLKIndexGEN;
2111 if(HwInfo->jChipType < SIS_315H) {
2112 if(ModeNo > 0x13) {
2113 if( (HwInfo->jChipType != SIS_630) &&
2114 (HwInfo->jChipType != SIS_300) ) {
2115 if(VCLKIndex == 0x1b) VCLKIndex = 0x35;
2116 }
2117 }
2118 }
2119 }
2120
2121 } else { /* LVDS */
2122
2123 VCLKIndex = CRT2Index;
2124
2125 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2126
2127 if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
2128
2129 VCLKIndex &= 0x1f;
2130 tempbx = 0;
2131 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2132 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2133 tempbx += 2;
2134 if(SiS_Pr->SiS_ModeType > ModeVGA) {
2135 if(SiS_Pr->SiS_CHSOverScan) tempbx = 8;
2136 }
2137 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
2138 tempbx = 4;
2139 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2140 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
2141 tempbx = 6;
2142 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2143 }
2144 }
2145 switch(tempbx) {
2146 case 0: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUNTSC; break;
2147 case 1: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKONTSC; break;
2148 case 2: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPAL; break;
2149 case 3: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break;
2150 case 4: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALM; break;
2151 case 5: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALM; break;
2152 case 6: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALN; break;
2153 case 7: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALN; break;
2154 case 8: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKSOPAL; break;
2155 default: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break;
2156 }
2157 VCLKIndex = CHTVVCLKPtr[VCLKIndex];
2158
2159 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2160
2161 if(HwInfo->jChipType < SIS_315H) {
2162 VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2163 } else {
2164 VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2165 }
2166
2167 /* Special Timing: Barco iQ Pro R series */
2168 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) VCLKIndex = 0x44;
2169
2170 /* Special Timing: 848x480 parallel lvds */
2171 if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
2172 if(HwInfo->jChipType < SIS_315H) {
2173 VCLKIndex = VCLK34_300;
2174 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2175 } else {
2176 VCLKIndex = VCLK34_315;
2177 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2178 }
2179 }
2180
2181 } else {
2182
2183 VCLKIndex = VCLKIndexGEN;
2184 if(HwInfo->jChipType < SIS_315H) {
2185 if(ModeNo > 0x13) {
2186 if( (HwInfo->jChipType == SIS_630) &&
2187 (HwInfo->jChipRevision >= 0x30) ) {
2188 if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
2189 }
2190 }
2191 }
2192 }
2193
2194 } else { /* if not programming CRT2 */
2195
2196 VCLKIndex = VCLKIndexGEN;
2197 if(HwInfo->jChipType < SIS_315H) {
2198 if(ModeNo > 0x13) {
2199 if( (HwInfo->jChipType != SIS_630) &&
2200 (HwInfo->jChipType != SIS_300) ) {
2201 if(VCLKIndex == 0x1b) VCLKIndex = 0x35;
2202 }
2203 #if 0
2204 if(HwInfo->jChipType == SIS_730) {
2205 if(VCLKIndex == 0x0b) VCLKIndex = 0x40; /* 1024x768-70 */
2206 if(VCLKIndex == 0x0d) VCLKIndex = 0x41; /* 1024x768-75 */
2207 }
2208 #endif
2209 }
2210 }
2211
2212 }
2213
2214 }
2215
2216 #ifdef TWDEBUG
2217 xf86DrvMsg(0, X_INFO, "VCLKIndex %d (0x%x)\n", VCLKIndex, VCLKIndex);
2218 #endif
2219
2220 return(VCLKIndex);
2221 }
2222
2223 /*********************************************/
2224 /* SET CRT2 MODE TYPE REGISTERS */
2225 /*********************************************/
2226
2227 static void
SiS_SetCRT2ModeRegs(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,PSIS_HW_INFO HwInfo)2228 SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2229 PSIS_HW_INFO HwInfo)
2230 {
2231 USHORT i,j,modeflag;
2232 USHORT tempbl,tempcl,tempah=0;
2233 #ifdef SIS315H
2234 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
2235 USHORT tempah2, tempbl2;
2236 #endif
2237
2238 if(ModeNo <= 0x13) {
2239 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2240 } else if(SiS_Pr->UseCustomMode) {
2241 modeflag = SiS_Pr->CModeFlag;
2242 } else {
2243 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2244 }
2245
2246 /* BIOS does not do this (neither 301 nor LVDS) */
2247 /* (But it's harmless; see SetCRT2Offset) */
2248 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0x00); /* fix write part1 index 0 BTDRAM bit Bug */
2249
2250 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
2251
2252 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40);
2253 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2E,0xF7);
2254
2255 } else {
2256
2257 for(i=0,j=4; i<3; i++,j++) SiS_SetReg(SiS_Pr->SiS_Part1Port,j,0);
2258 if(HwInfo->jChipType >= SIS_315H) {
2259 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0x7F);
2260 }
2261
2262 tempcl = SiS_Pr->SiS_ModeType;
2263
2264 if(HwInfo->jChipType < SIS_315H) {
2265
2266 #ifdef SIS300 /* ---- 300 series ---- */
2267
2268 /* For 301BDH: (with LCD via LVDS) */
2269 if(SiS_Pr->SiS_VBType & VB_NoLCD) {
2270 tempbl = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32);
2271 tempbl &= 0xef;
2272 tempbl |= 0x02;
2273 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2274 tempbl |= 0x10;
2275 tempbl &= 0xfd;
2276 }
2277 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,tempbl);
2278 }
2279
2280 if(ModeNo > 0x13) {
2281 tempcl -= ModeVGA;
2282 if((tempcl > 0) || (tempcl == 0)) { /* tempcl is USHORT -> always true! */
2283 tempah = ((0x10 >> tempcl) | 0x80);
2284 }
2285 } else tempah = 0x80;
2286
2287 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0xA0;
2288
2289 #endif /* SIS300 */
2290
2291 } else {
2292
2293 #ifdef SIS315H /* ------- 315/330 series ------ */
2294
2295 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
2296 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
2297 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x08);
2298 }
2299 }
2300
2301 if(ModeNo > 0x13) {
2302 tempcl -= ModeVGA;
2303 if((tempcl > 0) || (tempcl == 0)) { /* tempcl is USHORT -> always true! */
2304 tempah = (0x08 >> tempcl);
2305 if (tempah == 0) tempah = 1;
2306 tempah |= 0x40;
2307 }
2308 } else tempah = 0x40;
2309
2310 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50;
2311
2312 #endif /* SIS315H */
2313
2314 }
2315
2316 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2317
2318 if(HwInfo->jChipType < SIS_315H) {
2319 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2320 } else {
2321 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2322 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2323 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
2324 if(IS_SIS740) {
2325 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2326 } else {
2327 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2328 }
2329 }
2330 }
2331
2332 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2333
2334 tempah = 0x01;
2335 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
2336 tempah |= 0x02;
2337 }
2338 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2339 tempah ^= 0x05;
2340 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
2341 tempah ^= 0x01;
2342 }
2343 }
2344
2345 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2346
2347 if(HwInfo->jChipType < SIS_315H) {
2348
2349 tempah = (tempah << 5) & 0xFF;
2350 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2351 tempah = (tempah >> 5) & 0xFF;
2352
2353 } else {
2354
2355 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF8,tempah);
2356
2357 }
2358
2359 if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
2360 tempah |= 0x10;
2361 }
2362
2363 if((HwInfo->jChipType < SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301)) {
2364 if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
2365 (SiS_Pr->SiS_LCDResInfo == Panel_1280x960)) {
2366 tempah |= 0x80;
2367 }
2368 } else {
2369 tempah |= 0x80;
2370 }
2371
2372 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2373 if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p))) {
2374 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2375 tempah |= 0x20;
2376 }
2377 }
2378 }
2379
2380 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah);
2381
2382 tempah = 0;
2383
2384 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempah |= 0x40;
2385
2386 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2387 if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) {
2388 tempah |= 0x40;
2389 }
2390 }
2391
2392 if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
2393 (SiS_Pr->SiS_LCDResInfo == Panel_1280x960) ||
2394 ((SiS_Pr->SiS_LCDResInfo == Panel_Custom) &&
2395 (SiS_Pr->CP_MaxX >= 1280) && (SiS_Pr->CP_MaxY >= 960))) {
2396 tempah |= 0x80;
2397 }
2398
2399 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0C,tempah);
2400
2401 } else { /* LVDS */
2402
2403 if(HwInfo->jChipType >= SIS_315H) {
2404
2405 /* LVDS can only be slave in 8bpp modes */
2406 tempah = 0x80;
2407 if((modeflag & CRT2Mode) && (SiS_Pr->SiS_ModeType > ModeVGA)) {
2408 if(SiS_Pr->SiS_VBInfo & DriverMode) {
2409 tempah |= 0x02;
2410 }
2411 }
2412
2413 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
2414 tempah |= 0x02;
2415 }
2416
2417 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2418 tempah ^= 0x01;
2419 }
2420
2421 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
2422 tempah = 1;
2423 }
2424
2425 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah);
2426
2427 } else {
2428
2429 tempah = 0;
2430 if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
2431 tempah |= 0x02;
2432 }
2433 tempah <<= 5;
2434
2435 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2436
2437 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2438
2439 }
2440
2441 }
2442
2443 } /* LCDA */
2444
2445 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2446
2447 if(HwInfo->jChipType >= SIS_315H) {
2448
2449 #ifdef SIS315H
2450
2451 unsigned char bridgerev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01);
2452
2453 /* The following is nearly unpreditable and varies from machine
2454 * to machine. Especially the 301DH seems to be a real trouble
2455 * maker. Some BIOSes simply set the registers (like in the
2456 * NoLCD-if-statements here), some set them according to the
2457 * LCDA stuff. It is very likely that some machines are not
2458 * treated correctly in the following, very case-orientated
2459 * code. What do I do then...?
2460 */
2461
2462 /* 740 variants match for 30xB, 301B-DH, 30xLV */
2463
2464 if(!(IS_SIS740)) {
2465 tempah = 0x04; /* For all bridges */
2466 tempbl = 0xfb;
2467 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2468 tempah = 0x00;
2469 if(SiS_IsDualEdge(SiS_Pr, HwInfo)) {
2470 tempbl = 0xff;
2471 }
2472 }
2473 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2474 }
2475
2476 /* The following two are responsible for eventually wrong colors
2477 * in TV output. The DH (VB_NoLCD) conditions are unknown; the
2478 * b0 was found in some 651 machine (Pim; P4_23=0xe5); the b1 version
2479 * in a 650 box (Jake). What is the criteria?
2480 */
2481
2482 if((IS_SIS740) || (HwInfo->jChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
2483 tempah = 0x30;
2484 tempbl = 0xc0;
2485 if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2486 ((SiS_Pr->SiS_ROMNew) && (!(ROMAddr[0x5b] & 0x04)))) {
2487 tempah = 0x00;
2488 tempbl = 0x00;
2489 }
2490 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,tempah);
2491 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,tempbl);
2492 } else if(SiS_Pr->SiS_VBType & VB_SIS301) {
2493 /* Fixes "TV-blue-bug" on 315+301 */
2494 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xcf); /* For 301 */
2495 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2496 } else if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
2497 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30); /* For 30xLV */
2498 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);
2499 } else if((SiS_Pr->SiS_VBType & VB_NoLCD) && (bridgerev == 0xb0)) {
2500 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30); /* For 30xB-DH rev b0 (or "DH on 651"?) */
2501 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);
2502 } else {
2503 tempah = 0x30; tempah2 = 0xc0; /* For 30xB (and 301BDH rev b1) */
2504 tempbl = 0xcf; tempbl2 = 0x3f;
2505 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2506 tempah = tempah2 = 0x00;
2507 if(SiS_IsDualEdge(SiS_Pr, HwInfo)) {
2508 tempbl = tempbl2 = 0xff;
2509 }
2510 }
2511 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2512 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2513 }
2514
2515 if(IS_SIS740) {
2516 tempah = 0x80;
2517 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x00;
2518 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,0x7f,tempah);
2519 } else {
2520 tempah = 0x00;
2521 tempbl = 0x7f;
2522 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2523 tempbl = 0xff;
2524 if(!(SiS_IsDualEdge(SiS_Pr, HwInfo))) tempah = 0x80;
2525 }
2526 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
2527 }
2528
2529 #if 0
2530 if(SiS_Pr->SiS_VBType & VB_SIS301C) {
2531 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3a,0xc0);
2532 }
2533 #endif
2534
2535 #endif /* SIS315H */
2536
2537 } else if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
2538
2539 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2540
2541 if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2542 ( (SiS_Pr->SiS_VBType & VB_NoLCD) &&
2543 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ) ) {
2544 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x23,0x7F);
2545 } else {
2546 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x23,0x80);
2547 }
2548
2549 }
2550
2551 } else { /* LVDS */
2552
2553 #ifdef SIS315H
2554 if(HwInfo->jChipType >= SIS_315H) {
2555
2556 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
2557
2558 tempah = 0x04;
2559 tempbl = 0xfb;
2560 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2561 tempah = 0x00;
2562 if(SiS_IsDualEdge(SiS_Pr, HwInfo)) tempbl = 0xff;
2563 }
2564 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2565
2566 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
2567 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
2568 }
2569
2570 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
2571
2572 } else if(HwInfo->jChipType == SIS_550) {
2573
2574 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
2575 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
2576
2577 }
2578
2579 }
2580 #endif
2581
2582 }
2583
2584 }
2585
2586 /*********************************************/
2587 /* GET RESOLUTION DATA */
2588 /*********************************************/
2589
2590 USHORT
SiS_GetResInfo(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex)2591 SiS_GetResInfo(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex)
2592 {
2593 if(ModeNo <= 0x13) return((USHORT)SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo);
2594 else return((USHORT)SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO);
2595 }
2596
2597 static void
SiS_GetCRT2ResInfo(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,PSIS_HW_INFO HwInfo)2598 SiS_GetCRT2ResInfo(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
2599 PSIS_HW_INFO HwInfo)
2600 {
2601 USHORT xres,yres,modeflag=0,resindex;
2602
2603 if(SiS_Pr->UseCustomMode) {
2604 xres = SiS_Pr->CHDisplay;
2605 if(SiS_Pr->CModeFlag & HalfDCLK) xres *= 2;
2606 SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
2607 yres = SiS_Pr->CVDisplay;
2608 if(SiS_Pr->CModeFlag & DoubleScanMode) yres *= 2;
2609 SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
2610 return;
2611 }
2612
2613 resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex);
2614
2615 if(ModeNo <= 0x13) {
2616 xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
2617 yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
2618 } else {
2619 xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
2620 yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
2621 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2622 }
2623
2624 if(!SiS_Pr->SiS_IF_DEF_DSTN && !SiS_Pr->SiS_IF_DEF_FSTN) {
2625
2626 if((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
2627 if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
2628 if(yres == 350) yres = 400;
2629 }
2630 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
2631 if(ModeNo == 0x12) yres = 400;
2632 }
2633 }
2634
2635 if(modeflag & HalfDCLK) xres *= 2;
2636 if(modeflag & DoubleScanMode) yres *= 2;
2637
2638 }
2639
2640 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
2641
2642 #if 0
2643 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCDA | SetCRT2ToLCD | SetCRT2ToHiVision)) {
2644 if(xres == 720) xres = 640;
2645 }
2646 #endif
2647
2648 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2649 switch(SiS_Pr->SiS_LCDResInfo) {
2650 case Panel_1024x768:
2651 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
2652 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2653 if(yres == 350) yres = 357;
2654 if(yres == 400) yres = 420;
2655 if(yres == 480) yres = 525;
2656 }
2657 }
2658 break;
2659 case Panel_1280x1024:
2660 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2661 /* BIOS bug - does this regardless of scaling */
2662 if(yres == 400) yres = 405;
2663 }
2664 if(yres == 350) yres = 360;
2665 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
2666 if(yres == 360) yres = 375;
2667 }
2668 break;
2669 case Panel_1600x1200:
2670 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
2671 if(yres == 1024) yres = 1056;
2672 }
2673 break;
2674 }
2675 }
2676
2677 } else {
2678
2679 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2680 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVision)) {
2681 if(xres == 720) xres = 640;
2682 }
2683 } else if(xres == 720) xres = 640;
2684
2685 if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
2686 yres = 400;
2687 if(HwInfo->jChipType >= SIS_315H) {
2688 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
2689 } else {
2690 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
2691 }
2692 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) yres = 480;
2693 }
2694
2695 }
2696 SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
2697 SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
2698 }
2699
2700 /*********************************************/
2701 /* GET CRT2 TIMING DATA */
2702 /*********************************************/
2703
2704 static BOOLEAN
SiS_GetLVDSCRT1Ptr(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,USHORT * ResIndex,USHORT * DisplayType)2705 SiS_GetLVDSCRT1Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2706 USHORT RefreshRateTableIndex, USHORT *ResIndex,
2707 USHORT *DisplayType)
2708 {
2709 USHORT modeflag=0;
2710
2711 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2712 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2713 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return FALSE;
2714 }
2715 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
2716 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return FALSE;
2717 } else
2718 return FALSE;
2719
2720 if(ModeNo <= 0x13) {
2721 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2722 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2723 } else {
2724 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2725 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2726 }
2727
2728 (*ResIndex) &= 0x3F;
2729
2730 if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
2731 (*DisplayType) = 18;
2732 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
2733 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2734 (*DisplayType) += 2;
2735 if(SiS_Pr->SiS_ModeType > ModeVGA) {
2736 if(SiS_Pr->SiS_CHSOverScan) (*DisplayType) = 99;
2737 }
2738 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
2739 (*DisplayType) = 18; /* PALM uses NTSC data */
2740 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
2741 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
2742 (*DisplayType) = 20; /* PALN uses PAL data */
2743 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
2744 }
2745 }
2746 } else {
2747 switch(SiS_Pr->SiS_LCDResInfo) {
2748 case Panel_640x480: (*DisplayType) = 50; break;
2749 case Panel_640x480_2: (*DisplayType) = 52; break;
2750 case Panel_640x480_3: (*DisplayType) = 54; break;
2751 case Panel_800x600: (*DisplayType) = 0; break;
2752 case Panel_1024x600: (*DisplayType) = 23; break;
2753 case Panel_1024x768: (*DisplayType) = 4; break;
2754 case Panel_1152x768: (*DisplayType) = 27; break;
2755 case Panel_1280x768: (*DisplayType) = 40; break;
2756 case Panel_1280x1024: (*DisplayType) = 8; break;
2757 case Panel_1400x1050: (*DisplayType) = 14; break;
2758 case Panel_1600x1200: (*DisplayType) = 36; break;
2759 default: return FALSE;
2760 }
2761
2762 if(modeflag & HalfDCLK) (*DisplayType)++;
2763
2764 switch(SiS_Pr->SiS_LCDResInfo) {
2765 case Panel_640x480:
2766 case Panel_640x480_2:
2767 case Panel_640x480_3:
2768 break;
2769 default:
2770 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) (*DisplayType) += 2;
2771 }
2772
2773 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
2774 (*DisplayType) = 12;
2775 if(modeflag & HalfDCLK) (*DisplayType)++;
2776 }
2777 }
2778
2779 #if 0
2780 if(SiS_Pr->SiS_IF_DEF_FSTN) {
2781 if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel320x480){
2782 (*DisplayType) = 22;
2783 }
2784 }
2785 #endif
2786
2787 return TRUE;
2788 }
2789
2790 static void
SiS_GetCRT2Ptr(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,USHORT * CRT2Index,USHORT * ResIndex,PSIS_HW_INFO HwInfo)2791 SiS_GetCRT2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
2792 USHORT RefreshRateTableIndex,USHORT *CRT2Index,USHORT *ResIndex,
2793 PSIS_HW_INFO HwInfo)
2794 {
2795 USHORT tempbx=0,tempal=0,resinfo=0;
2796
2797 if(ModeNo <= 0x13) {
2798 tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2799 } else {
2800 tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2801 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2802 }
2803
2804 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_IF_DEF_LVDS == 0)) {
2805
2806 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { /* LCD */
2807
2808 tempbx = SiS_Pr->SiS_LCDResInfo;
2809 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 32;
2810
2811 if(SiS_Pr->SiS_LCDResInfo == Panel_1680x1050) {
2812 if (resinfo == SIS_RI_1280x800) tempal = 9;
2813 else if(resinfo == SIS_RI_1400x1050) tempal = 11;
2814 }
2815
2816 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { /* Pass 1:1 only (center-screen handled outside) */
2817 tempbx = 100;
2818 if(ModeNo >= 0x13) {
2819 tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
2820 if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes == 1280) &&
2821 (SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].YRes == 768)) {
2822 /* Special for Fujitsu 7911 (VL-17WDX8), others custom */
2823 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768) tempal = 0x08;
2824 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768_2) tempal = 0x0f;
2825 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768_3) tempal = 0x10;
2826 }
2827 }
2828 }
2829
2830 #ifdef SIS315H
2831 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
2832 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
2833 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2834 tempbx = 200;
2835 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
2836 }
2837 }
2838 }
2839 #endif
2840
2841 } else { /* TV */
2842
2843 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
2844 /* if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_TVMode &= (~TVSetTVSimuMode); */
2845 tempbx = 2;
2846 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2847 tempbx = 13;
2848 if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) tempbx = 14;
2849 }
2850 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2851 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempbx = 7;
2852 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempbx = 6;
2853 else tempbx = 5;
2854 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5;
2855 } else {
2856 if(SiS_Pr->SiS_TVMode & TVSetPAL) tempbx = 3;
2857 else tempbx = 4;
2858 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5;
2859 }
2860
2861 }
2862
2863 tempal &= 0x3F;
2864
2865 if(ModeNo > 0x13) {
2866 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) {
2867 if(tempal == 6) tempal = 7;
2868 if((resinfo == SIS_RI_720x480) ||
2869 (resinfo == SIS_RI_720x576) ||
2870 (resinfo == SIS_RI_768x576)) {
2871 tempal = 6;
2872 if(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetPALN)) {
2873 if(resinfo == SIS_RI_720x480) tempal = 9;
2874 }
2875 }
2876 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2877 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
2878 if(resinfo == SIS_RI_1024x768) tempal = 8;
2879 }
2880 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
2881 if((resinfo == SIS_RI_720x576) ||
2882 (resinfo == SIS_RI_768x576)) {
2883 tempal = 8;
2884 }
2885 if(resinfo == SIS_RI_1280x720) tempal = 9;
2886 }
2887 }
2888 }
2889 }
2890
2891 *CRT2Index = tempbx;
2892 *ResIndex = tempal;
2893
2894 } else { /* LVDS, 301B-DH (if running on LCD) */
2895
2896 tempbx = 0;
2897 if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
2898 tempbx = 10;
2899 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2900 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2901 tempbx += 2;
2902 if(SiS_Pr->SiS_ModeType > ModeVGA) {
2903 if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
2904 }
2905 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
2906 tempbx = 90;
2907 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2908 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
2909 tempbx = 92;
2910 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2911 }
2912 }
2913 } else {
2914 switch(SiS_Pr->SiS_LCDResInfo) {
2915 case Panel_640x480: tempbx = 6; break;
2916 case Panel_640x480_2: tempbx = 30; break;
2917 case Panel_640x480_3: tempbx = 30; break;
2918 case Panel_800x600: tempbx = 0; break;
2919 case Panel_1024x600: tempbx = 15; break;
2920 case Panel_1024x768: tempbx = 2; break;
2921 case Panel_1152x768: tempbx = 17; break;
2922 case Panel_1280x768: tempbx = 18; break;
2923 case Panel_1280x1024: tempbx = 4; break;
2924 case Panel_1400x1050: tempbx = 8; break;
2925 case Panel_1600x1200: tempbx = 21; break;
2926 case Panel_Barco1366: tempbx = 80; break;
2927 }
2928
2929 switch(SiS_Pr->SiS_LCDResInfo) {
2930 case Panel_640x480:
2931 case Panel_640x480_2:
2932 case Panel_640x480_3:
2933 break;
2934 default:
2935 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
2936 }
2937
2938 if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempbx = 7;
2939
2940 if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
2941 tempbx = 82;
2942 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
2943 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
2944 tempbx = 84;
2945 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
2946 }
2947
2948 }
2949
2950 if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
2951 if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) tempal = 7;
2952 if(HwInfo->jChipType < SIS_315H) {
2953 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) tempal++;
2954 }
2955 }
2956
2957 (*CRT2Index) = tempbx;
2958 (*ResIndex) = tempal & 0x1F;
2959 }
2960 }
2961
2962 static void
SiS_GetRAMDAC2DATA(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo)2963 SiS_GetRAMDAC2DATA(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
2964 USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo)
2965 {
2966 USHORT tempax=0,tempbx=0;
2967 USHORT temp1=0,modeflag=0,tempcx=0;
2968 USHORT index;
2969
2970 SiS_Pr->SiS_RVBHCMAX = 1;
2971 SiS_Pr->SiS_RVBHCFACT = 1;
2972
2973 if(ModeNo <= 0x13) {
2974
2975 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2976 index = SiS_GetModePtr(SiS_Pr,ModeNo,ModeIdIndex);
2977
2978 tempax = SiS_Pr->SiS_StandTable[index].CRTC[0];
2979 tempbx = SiS_Pr->SiS_StandTable[index].CRTC[6];
2980 temp1 = SiS_Pr->SiS_StandTable[index].CRTC[7];
2981
2982 } else {
2983
2984 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2985 index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
2986
2987 tempax = SiS_Pr->SiS_CRT1Table[index].CR[0];
2988 tempax |= (SiS_Pr->SiS_CRT1Table[index].CR[14] << 8);
2989 tempax &= 0x03FF;
2990 tempbx = SiS_Pr->SiS_CRT1Table[index].CR[6];
2991 tempcx = SiS_Pr->SiS_CRT1Table[index].CR[13] << 8;
2992 tempcx &= 0x0100;
2993 tempcx <<= 2;
2994 tempbx |= tempcx;
2995 temp1 = SiS_Pr->SiS_CRT1Table[index].CR[7];
2996
2997 }
2998
2999 if(temp1 & 0x01) tempbx |= 0x0100;
3000 if(temp1 & 0x20) tempbx |= 0x0200;
3001
3002 tempax += 5;
3003
3004 /* Charx8Dot is no more used (and assumed), so we set it */
3005 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
3006 modeflag |= Charx8Dot;
3007 }
3008
3009 if(modeflag & Charx8Dot) tempax *= 8;
3010 else tempax *= 9;
3011
3012 if(modeflag & HalfDCLK) tempax <<= 1;
3013
3014 tempbx++;
3015
3016 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3017 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = tempbx;
3018 }
3019
3020 static void
SiS_GetCRT2DataLVDS(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo)3021 SiS_GetCRT2DataLVDS(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
3022 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
3023 {
3024 USHORT CRT2Index, ResIndex;
3025 const SiS_LVDSDataStruct *LVDSData = NULL;
3026
3027 SiS_GetCRT2ResInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
3028
3029 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3030 SiS_Pr->SiS_RVBHCMAX = 1;
3031 SiS_Pr->SiS_RVBHCFACT = 1;
3032 SiS_Pr->SiS_NewFlickerMode = 0;
3033 SiS_Pr->SiS_RVBHRS = 50;
3034 SiS_Pr->SiS_RY1COE = 0;
3035 SiS_Pr->SiS_RY2COE = 0;
3036 SiS_Pr->SiS_RY3COE = 0;
3037 SiS_Pr->SiS_RY4COE = 0;
3038 }
3039
3040 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3041
3042 #ifdef SIS315H
3043 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3044 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
3045 if(SiS_Pr->UseCustomMode) {
3046 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->CHTotal;
3047 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3048 } else {
3049 if(ModeNo < 0x13) {
3050 ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3051 } else {
3052 ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
3053 /* Special for our 3 types, others custom (works with default) */
3054 if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes == 1280) &&
3055 (SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].YRes == 768)) {
3056 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768) ResIndex = 0x08;
3057 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768_2) ResIndex = 0x0f;
3058 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768_3) ResIndex = 0x10;
3059 }
3060 /* Special for 1280x720 TMDS <> LVDS */
3061 if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes == 1280) &&
3062 (SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].YRes == 720)) {
3063 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x720) {
3064 if(SiS_Pr->PanelHT == 1344) ResIndex = 0x12;
3065 }
3066 }
3067 }
3068 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAHT;
3069 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAVT;
3070 SiS_Pr->SiS_HT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDHT;
3071 SiS_Pr->SiS_VT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDVT;
3072 }
3073 } else {
3074 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3075 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3076 }
3077 } else {
3078 /* This handles custom modes and custom panels */
3079 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3080 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3081 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3082 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3083 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT - (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE);
3084 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT - (SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE);
3085 }
3086
3087 SiS_CalcLCDACRT1Timing(SiS_Pr,ModeNo,ModeIdIndex);
3088
3089 #endif
3090
3091 } else {
3092
3093 /* 301BDH needs LVDS Data */
3094 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3095 SiS_Pr->SiS_IF_DEF_LVDS = 1;
3096 }
3097
3098 SiS_GetCRT2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
3099 &CRT2Index, &ResIndex, HwInfo);
3100
3101 /* 301BDH needs LVDS Data */
3102 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3103 SiS_Pr->SiS_IF_DEF_LVDS = 0;
3104 }
3105
3106 switch (CRT2Index) {
3107 case 0: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1; break;
3108 case 1: LVDSData = SiS_Pr->SiS_LVDS800x600Data_2; break;
3109 case 2: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break;
3110 case 3: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_2; break;
3111 case 4: LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_1; break;
3112 case 5: LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_2; break;
3113 case 6: LVDSData = SiS_Pr->SiS_LVDS640x480Data_1; break;
3114 case 7: LVDSData = SiS_Pr->SiS_LVDSXXXxXXXData_1; break;
3115 case 8: LVDSData = SiS_Pr->SiS_LVDS1400x1050Data_1; break;
3116 case 9: LVDSData = SiS_Pr->SiS_LVDS1400x1050Data_2; break;
3117 case 10: LVDSData = SiS_Pr->SiS_CHTVUNTSCData; break;
3118 case 11: LVDSData = SiS_Pr->SiS_CHTVONTSCData; break;
3119 case 12: LVDSData = SiS_Pr->SiS_CHTVUPALData; break;
3120 case 13: LVDSData = SiS_Pr->SiS_CHTVOPALData; break;
3121 case 14: LVDSData = SiS_Pr->SiS_LVDS320x480Data_1; break;
3122 case 15: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1; break;
3123 case 16: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_2; break;
3124 case 17: LVDSData = SiS_Pr->SiS_LVDS1152x768Data_1; break;
3125 case 18: LVDSData = SiS_Pr->SiS_LVDS1152x768Data_2; break;
3126 case 19: LVDSData = SiS_Pr->SiS_LVDS1280x768Data_1; break;
3127 case 20: LVDSData = SiS_Pr->SiS_LVDS1280x768Data_2; break;
3128 case 21: LVDSData = SiS_Pr->SiS_LVDS1600x1200Data_1; break;
3129 case 22: LVDSData = SiS_Pr->SiS_LVDS1600x1200Data_2; break;
3130 case 30: LVDSData = SiS_Pr->SiS_LVDS640x480Data_2; break;
3131 case 80: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1; break;
3132 case 81: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2; break;
3133 case 82: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1; break;
3134 case 83: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_2; break;
3135 case 84: LVDSData = SiS_Pr->SiS_LVDS848x480Data_1; break;
3136 case 85: LVDSData = SiS_Pr->SiS_LVDS848x480Data_2; break;
3137 case 90: LVDSData = SiS_Pr->SiS_CHTVUPALMData; break;
3138 case 91: LVDSData = SiS_Pr->SiS_CHTVOPALMData; break;
3139 case 92: LVDSData = SiS_Pr->SiS_CHTVUPALNData; break;
3140 case 93: LVDSData = SiS_Pr->SiS_CHTVOPALNData; break;
3141 case 99: LVDSData = SiS_Pr->SiS_CHTVSOPALData; break; /* Super Overscan */
3142 default: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break;
3143 }
3144
3145 SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT;
3146 SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT;
3147 SiS_Pr->SiS_HT = (LVDSData+ResIndex)->LCDHT;
3148 SiS_Pr->SiS_VT = (LVDSData+ResIndex)->LCDVT;
3149
3150 if(!(SiS_Pr->SiS_VBType & VB_SISVB)) {
3151 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
3152 if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
3153 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3154 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3155 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3156 if(ResIndex < 0x08) {
3157 SiS_Pr->SiS_HDE = 1280;
3158 SiS_Pr->SiS_VDE = 1024;
3159 }
3160 }
3161 }
3162 }
3163 }
3164 }
3165 }
3166
3167 static void
SiS_GetCRT2Data301(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo)3168 SiS_GetCRT2Data301(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
3169 USHORT RefreshRateTableIndex,
3170 PSIS_HW_INFO HwInfo)
3171 {
3172 UCHAR *ROMAddr = NULL;
3173 USHORT tempax,tempbx,modeflag,romptr=0;
3174 USHORT resinfo,CRT2Index,ResIndex;
3175 const SiS_LCDDataStruct *LCDPtr = NULL;
3176 const SiS_TVDataStruct *TVPtr = NULL;
3177 #ifdef SIS315H
3178 SHORT resinfo661;
3179 #endif
3180
3181 if(ModeNo <= 0x13) {
3182 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3183 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
3184 } else if(SiS_Pr->UseCustomMode) {
3185 modeflag = SiS_Pr->CModeFlag;
3186 resinfo = 0;
3187 } else {
3188 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3189 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
3190 #ifdef SIS315H
3191 resinfo661 = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].ROMMODEIDX661;
3192 if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
3193 (SiS_Pr->SiS_SetFlag & LCDVESATiming) &&
3194 (resinfo661 >= 0) &&
3195 (SiS_Pr->SiS_NeedRomModeData) ) {
3196 if((ROMAddr = GetLCDStructPtr661(SiS_Pr, HwInfo))) {
3197 if((romptr = (SISGETROMW(21)))) {
3198 romptr += (resinfo661 * 10);
3199 ROMAddr = HwInfo->pjVirtualRomBase;
3200 }
3201 }
3202 }
3203 #endif
3204 }
3205
3206 SiS_Pr->SiS_NewFlickerMode = 0;
3207 SiS_Pr->SiS_RVBHRS = 50;
3208 SiS_Pr->SiS_RY1COE = 0;
3209 SiS_Pr->SiS_RY2COE = 0;
3210 SiS_Pr->SiS_RY3COE = 0;
3211 SiS_Pr->SiS_RY4COE = 0;
3212
3213 SiS_GetCRT2ResInfo(SiS_Pr,ModeNo,ModeIdIndex,HwInfo);
3214
3215 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC){
3216
3217 if(SiS_Pr->UseCustomMode) {
3218
3219 SiS_Pr->SiS_RVBHCMAX = 1;
3220 SiS_Pr->SiS_RVBHCFACT = 1;
3221 SiS_Pr->SiS_VGAHT = SiS_Pr->CHTotal;
3222 SiS_Pr->SiS_VGAVT = SiS_Pr->CVTotal;
3223 SiS_Pr->SiS_HT = SiS_Pr->CHTotal;
3224 SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3225 SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE;
3226 SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE;
3227
3228 } else {
3229
3230 SiS_GetRAMDAC2DATA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
3231
3232 }
3233
3234 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
3235
3236 SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3237 &CRT2Index,&ResIndex,HwInfo);
3238
3239 switch(CRT2Index) {
3240 case 2: TVPtr = SiS_Pr->SiS_ExtHiTVData; break;
3241 case 3: TVPtr = SiS_Pr->SiS_ExtPALData; break;
3242 case 4: TVPtr = SiS_Pr->SiS_ExtNTSCData; break;
3243 case 5: TVPtr = SiS_Pr->SiS_Ext525iData; break;
3244 case 6: TVPtr = SiS_Pr->SiS_Ext525pData; break;
3245 case 7: TVPtr = SiS_Pr->SiS_Ext750pData; break;
3246 case 8: TVPtr = SiS_Pr->SiS_StPALData; break;
3247 case 9: TVPtr = SiS_Pr->SiS_StNTSCData; break;
3248 case 10: TVPtr = SiS_Pr->SiS_St525iData; break;
3249 case 11: TVPtr = SiS_Pr->SiS_St525pData; break;
3250 case 12: TVPtr = SiS_Pr->SiS_St750pData; break;
3251 case 13: TVPtr = SiS_Pr->SiS_St1HiTVData; break;
3252 case 14: TVPtr = SiS_Pr->SiS_St2HiTVData; break;
3253 default: TVPtr = SiS_Pr->SiS_StPALData; break;
3254 }
3255
3256 SiS_Pr->SiS_RVBHCMAX = (TVPtr+ResIndex)->RVBHCMAX;
3257 SiS_Pr->SiS_RVBHCFACT = (TVPtr+ResIndex)->RVBHCFACT;
3258 SiS_Pr->SiS_VGAHT = (TVPtr+ResIndex)->VGAHT;
3259 SiS_Pr->SiS_VGAVT = (TVPtr+ResIndex)->VGAVT;
3260 SiS_Pr->SiS_HDE = (TVPtr+ResIndex)->TVHDE;
3261 SiS_Pr->SiS_VDE = (TVPtr+ResIndex)->TVVDE;
3262 SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->RVBHRS;
3263 SiS_Pr->SiS_NewFlickerMode = (TVPtr+ResIndex)->FlickerMode;
3264 if(modeflag & HalfDCLK) {
3265 SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->HALFRVBHRS;
3266 }
3267
3268 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
3269
3270 if((resinfo == SIS_RI_1024x768) ||
3271 (resinfo == SIS_RI_1280x1024) ||
3272 (resinfo == SIS_RI_1280x720)) {
3273 SiS_Pr->SiS_NewFlickerMode = 0x40;
3274 }
3275
3276 if(SiS_Pr->SiS_VGAVDE == 350) SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
3277
3278 SiS_Pr->SiS_HT = ExtHiTVHT;
3279 SiS_Pr->SiS_VT = ExtHiTVVT;
3280 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
3281 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
3282 SiS_Pr->SiS_HT = StHiTVHT;
3283 SiS_Pr->SiS_VT = StHiTVVT;
3284 #if 0
3285 if(!(modeflag & Charx8Dot)) {
3286 SiS_Pr->SiS_HT = StHiTextTVHT;
3287 SiS_Pr->SiS_VT = StHiTextTVVT;
3288 }
3289 #endif
3290 }
3291 }
3292
3293 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3294
3295 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
3296 SiS_Pr->SiS_HT = 1650;
3297 SiS_Pr->SiS_VT = 750;
3298 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
3299 SiS_Pr->SiS_HT = NTSCHT;
3300 SiS_Pr->SiS_VT = NTSCVT;
3301 } else {
3302 SiS_Pr->SiS_HT = NTSCHT;
3303 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3304 SiS_Pr->SiS_VT = NTSCVT;
3305 }
3306
3307 } else {
3308
3309 SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
3310 SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
3311 SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
3312 SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
3313
3314 if(modeflag & HalfDCLK) {
3315 SiS_Pr->SiS_RY1COE = 0x00;
3316 SiS_Pr->SiS_RY2COE = 0xf4;
3317 SiS_Pr->SiS_RY3COE = 0x10;
3318 SiS_Pr->SiS_RY4COE = 0x38;
3319 }
3320
3321 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
3322 SiS_Pr->SiS_HT = NTSCHT;
3323 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3324 SiS_Pr->SiS_VT = NTSCVT;
3325 } else {
3326 SiS_Pr->SiS_HT = PALHT;
3327 SiS_Pr->SiS_VT = PALVT;
3328 }
3329
3330 }
3331
3332 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3333
3334 SiS_Pr->SiS_RVBHCMAX = 1;
3335 SiS_Pr->SiS_RVBHCFACT = 1;
3336
3337 if(SiS_Pr->UseCustomMode) {
3338
3339 SiS_Pr->SiS_VGAHT = SiS_Pr->CHTotal;
3340 SiS_Pr->SiS_VGAVT = SiS_Pr->CVTotal;
3341 SiS_Pr->SiS_HT = SiS_Pr->CHTotal;
3342 SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3343 SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE;
3344 SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE;
3345
3346 } else {
3347
3348 BOOLEAN gotit = FALSE;
3349
3350 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
3351
3352 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
3353 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
3354 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3355 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3356 gotit = TRUE;
3357
3358 } else if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) && (romptr) && (ROMAddr) ) {
3359
3360 #ifdef SIS315H
3361 SiS_Pr->SiS_RVBHCMAX = ROMAddr[romptr];
3362 SiS_Pr->SiS_RVBHCFACT = ROMAddr[romptr+1];
3363 SiS_Pr->SiS_VGAHT = ROMAddr[romptr+2] | ((ROMAddr[romptr+3] & 0x0f) << 8);
3364 SiS_Pr->SiS_VGAVT = ROMAddr[romptr+4] | ((ROMAddr[romptr+3] & 0xf0) << 4);
3365 SiS_Pr->SiS_HT = ROMAddr[romptr+5] | ((ROMAddr[romptr+6] & 0x0f) << 8);
3366 SiS_Pr->SiS_VT = ROMAddr[romptr+7] | ((ROMAddr[romptr+6] & 0xf0) << 4);
3367 if(SiS_Pr->SiS_VGAHT) gotit = TRUE;
3368 #endif
3369
3370 }
3371
3372 if(!gotit) {
3373
3374 SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3375 &CRT2Index,&ResIndex,HwInfo);
3376
3377 switch(CRT2Index) {
3378 case Panel_1024x768 : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break;
3379 case Panel_1024x768 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data; break;
3380 case Panel_1280x720 :
3381 case Panel_1280x720 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x720Data; break;
3382 case Panel_1280x768_2 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x768_2Data; break;
3383 case Panel_1280x768_2+ 32: LCDPtr = SiS_Pr->SiS_StLCD1280x768_2Data; break;
3384 case Panel_1280x768_3 :
3385 case Panel_1280x768_3+ 32: LCDPtr = SiS_Pr->SiS_LCD1280x768_3Data; break;
3386 case Panel_1280x800 :
3387 case Panel_1280x800 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x800Data; break;
3388 case Panel_1280x960 :
3389 case Panel_1280x960 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x960Data; break;
3390 case Panel_1280x1024 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data; break;
3391 case Panel_1280x1024 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
3392 case Panel_1400x1050 : LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data; break;
3393 case Panel_1400x1050 + 32: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data; break;
3394 case Panel_1600x1200 : LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data; break;
3395 case Panel_1600x1200 + 32: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data; break;
3396 case Panel_1680x1050 :
3397 case Panel_1680x1050 + 32: LCDPtr = SiS_Pr->SiS_LCD1680x1050Data; break;
3398 case 100 : LCDPtr = SiS_Pr->SiS_NoScaleData; break;
3399 #ifdef SIS315H
3400 case 200 : LCDPtr = SiS310_ExtCompaq1280x1024Data; break;
3401 case 201 : LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
3402 #endif
3403 default : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break;
3404 }
3405
3406 #ifdef TWDEBUG
3407 xf86DrvMsg(0, X_INFO, "GetCRT2Data: Index %d ResIndex %d\n", CRT2Index, ResIndex);
3408 #endif
3409
3410 SiS_Pr->SiS_RVBHCMAX = (LCDPtr+ResIndex)->RVBHCMAX;
3411 SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
3412 SiS_Pr->SiS_VGAHT = (LCDPtr+ResIndex)->VGAHT;
3413 SiS_Pr->SiS_VGAVT = (LCDPtr+ResIndex)->VGAVT;
3414 SiS_Pr->SiS_HT = (LCDPtr+ResIndex)->LCDHT;
3415 SiS_Pr->SiS_VT = (LCDPtr+ResIndex)->LCDVT;
3416
3417 }
3418
3419 tempax = SiS_Pr->PanelXRes;
3420 tempbx = SiS_Pr->PanelYRes;
3421
3422 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3423 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
3424 if(HwInfo->jChipType < SIS_315H) {
3425 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3426 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3427 }
3428 } else {
3429 if (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
3430 else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
3431 else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
3432 else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
3433 else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3434 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3435 }
3436 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960) {
3437 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 700;
3438 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 800;
3439 else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
3440 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
3441 if (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
3442 else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
3443 else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
3444 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) {
3445 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
3446 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 875;
3447 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 1000;
3448 }
3449 }
3450
3451 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3452 tempax = SiS_Pr->SiS_VGAHDE;
3453 tempbx = SiS_Pr->SiS_VGAVDE;
3454 }
3455
3456 SiS_Pr->SiS_HDE = tempax;
3457 SiS_Pr->SiS_VDE = tempbx;
3458 }
3459 }
3460 }
3461
3462 static void
SiS_GetCRT2Data(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo)3463 SiS_GetCRT2Data(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
3464 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
3465 {
3466
3467 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3468
3469 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
3470 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
3471 } else {
3472 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3473 /* Need LVDS Data for LCD on 301B-DH */
3474 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
3475 } else {
3476 SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
3477 }
3478 }
3479
3480 } else {
3481
3482 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
3483
3484 }
3485 }
3486
3487 /*********************************************/
3488 /* GET LVDS DES (SKEW) DATA */
3489 /*********************************************/
3490
3491 static void
SiS_GetLVDSDesPtr(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,USHORT * PanelIndex,USHORT * ResIndex,PSIS_HW_INFO HwInfo)3492 SiS_GetLVDSDesPtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
3493 USHORT RefreshRateTableIndex, USHORT *PanelIndex,
3494 USHORT *ResIndex, PSIS_HW_INFO HwInfo)
3495 {
3496 USHORT modeflag;
3497
3498 if(ModeNo <= 0x13) {
3499 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3500 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3501 } else {
3502 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3503 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
3504 }
3505
3506 (*ResIndex) &= 0x1F;
3507 (*PanelIndex) = 0;
3508
3509 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
3510 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
3511 (*PanelIndex) = 50;
3512 if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) (*PanelIndex) += 2;
3513 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*PanelIndex) += 1;
3514 /* Nothing special needed for SOverscan */
3515 /* PALM uses NTSC data, PALN uses PAL data */
3516 }
3517 }
3518
3519 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3520 *PanelIndex = SiS_Pr->SiS_LCDTypeInfo;
3521 if(HwInfo->jChipType >= SIS_661) {
3522 /* As long as we don's use the BIOS tables, we
3523 * need to convert the TypeInfo as for 315 series
3524 */
3525 (*PanelIndex) = SiS_Pr->SiS_LCDResInfo - 1;
3526 }
3527 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3528 (*PanelIndex) += 16;
3529 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
3530 (*PanelIndex) = 32;
3531 if(modeflag & HalfDCLK) (*PanelIndex)++;
3532 }
3533 }
3534 }
3535
3536 if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
3537 if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) {
3538 (*ResIndex) = 7;
3539 if(HwInfo->jChipType < SIS_315H) {
3540 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) (*ResIndex)++;
3541 }
3542 }
3543 }
3544 }
3545
3546 static void
SiS_GetLVDSDesData(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo)3547 SiS_GetLVDSDesData(SiS_Private *SiS_Pr, USHORT ModeNo,USHORT ModeIdIndex,
3548 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
3549 {
3550 USHORT modeflag;
3551 USHORT PanelIndex,ResIndex;
3552 const SiS_LVDSDesStruct *PanelDesPtr = NULL;
3553
3554 SiS_Pr->SiS_LCDHDES = 0;
3555 SiS_Pr->SiS_LCDVDES = 0;
3556
3557 if( (SiS_Pr->UseCustomMode) ||
3558 (SiS_Pr->SiS_LCDResInfo == Panel_Custom) ||
3559 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
3560 ((SiS_Pr->SiS_VBType & VB_SISVB) &&
3561 (SiS_Pr->SiS_LCDInfo & DontExpandLCD) &&
3562 (SiS_Pr->SiS_LCDInfo & LCDPass11)) ) {
3563 return;
3564 }
3565
3566 if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3567
3568 #ifdef SIS315H
3569 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3570 /* non-pass 1:1 only, see above */
3571 if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
3572 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
3573 }
3574 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
3575 SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
3576 }
3577 }
3578 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3579 switch(SiS_Pr->SiS_CustomT) {
3580 case CUT_UNIWILL1024:
3581 case CUT_UNIWILL10242:
3582 case CUT_CLEVO1400:
3583 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3584 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3585 }
3586 break;
3587 }
3588 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
3589 if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
3590 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3591 }
3592 }
3593 }
3594 #endif
3595
3596 } else {
3597
3598 SiS_GetLVDSDesPtr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
3599 &PanelIndex, &ResIndex, HwInfo);
3600
3601 switch(PanelIndex) {
3602 case 0: PanelDesPtr = SiS_Pr->SiS_PanelType00_1; break; /* --- */
3603 case 1: PanelDesPtr = SiS_Pr->SiS_PanelType01_1; break;
3604 case 2: PanelDesPtr = SiS_Pr->SiS_PanelType02_1; break;
3605 case 3: PanelDesPtr = SiS_Pr->SiS_PanelType03_1; break;
3606 case 4: PanelDesPtr = SiS_Pr->SiS_PanelType04_1; break;
3607 case 5: PanelDesPtr = SiS_Pr->SiS_PanelType05_1; break;
3608 case 6: PanelDesPtr = SiS_Pr->SiS_PanelType06_1; break;
3609 case 7: PanelDesPtr = SiS_Pr->SiS_PanelType07_1; break;
3610 case 8: PanelDesPtr = SiS_Pr->SiS_PanelType08_1; break;
3611 case 9: PanelDesPtr = SiS_Pr->SiS_PanelType09_1; break;
3612 case 10: PanelDesPtr = SiS_Pr->SiS_PanelType0a_1; break;
3613 case 11: PanelDesPtr = SiS_Pr->SiS_PanelType0b_1; break;
3614 case 12: PanelDesPtr = SiS_Pr->SiS_PanelType0c_1; break;
3615 case 13: PanelDesPtr = SiS_Pr->SiS_PanelType0d_1; break;
3616 case 14: PanelDesPtr = SiS_Pr->SiS_PanelType0e_1; break;
3617 case 15: PanelDesPtr = SiS_Pr->SiS_PanelType0f_1; break;
3618 case 16: PanelDesPtr = SiS_Pr->SiS_PanelType00_2; break; /* --- */
3619 case 17: PanelDesPtr = SiS_Pr->SiS_PanelType01_2; break;
3620 case 18: PanelDesPtr = SiS_Pr->SiS_PanelType02_2; break;
3621 case 19: PanelDesPtr = SiS_Pr->SiS_PanelType03_2; break;
3622 case 20: PanelDesPtr = SiS_Pr->SiS_PanelType04_2; break;
3623 case 21: PanelDesPtr = SiS_Pr->SiS_PanelType05_2; break;
3624 case 22: PanelDesPtr = SiS_Pr->SiS_PanelType06_2; break;
3625 case 23: PanelDesPtr = SiS_Pr->SiS_PanelType07_2; break;
3626 case 24: PanelDesPtr = SiS_Pr->SiS_PanelType08_2; break;
3627 case 25: PanelDesPtr = SiS_Pr->SiS_PanelType09_2; break;
3628 case 26: PanelDesPtr = SiS_Pr->SiS_PanelType0a_2; break;
3629 case 27: PanelDesPtr = SiS_Pr->SiS_PanelType0b_2; break;
3630 case 28: PanelDesPtr = SiS_Pr->SiS_PanelType0c_2; break;
3631 case 29: PanelDesPtr = SiS_Pr->SiS_PanelType0d_2; break;
3632 case 30: PanelDesPtr = SiS_Pr->SiS_PanelType0e_2; break;
3633 case 31: PanelDesPtr = SiS_Pr->SiS_PanelType0f_2; break;
3634 case 32: PanelDesPtr = SiS_Pr->SiS_PanelTypeNS_1; break; /* pass 1:1 */
3635 case 33: PanelDesPtr = SiS_Pr->SiS_PanelTypeNS_2; break;
3636 case 50: PanelDesPtr = SiS_Pr->SiS_CHTVUNTSCDesData; break; /* TV */
3637 case 51: PanelDesPtr = SiS_Pr->SiS_CHTVONTSCDesData; break;
3638 case 52: PanelDesPtr = SiS_Pr->SiS_CHTVUPALDesData; break;
3639 case 53: PanelDesPtr = SiS_Pr->SiS_CHTVOPALDesData; break;
3640 default: return;
3641 }
3642
3643 SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
3644 SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;
3645
3646 if((ModeNo <= 0x13) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
3647 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3648 if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3649 if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 632;
3650 } else if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) {
3651 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
3652 if(SiS_Pr->SiS_LCDResInfo >= Panel_1024x768) {
3653 if(HwInfo->jChipType < SIS_315H) {
3654 if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320;
3655 } else {
3656 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) SiS_Pr->SiS_LCDHDES = 480;
3657 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 804;
3658 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 704;
3659 if(!(modeflag & HalfDCLK)) {
3660 SiS_Pr->SiS_LCDHDES = 320;
3661 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 632;
3662 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 542;
3663 }
3664 }
3665 }
3666 }
3667 }
3668 }
3669 }
3670 }
3671
3672 /*********************************************/
3673 /* DISABLE VIDEO BRIDGE */
3674 /*********************************************/
3675
3676 /* NEVER use any variables (VBInfo), this will be called
3677 * from outside the context of modeswitch!
3678 * MUST call getVBType before calling this
3679 */
3680 void
SiS_DisableBridge(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)3681 SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
3682 {
3683 #ifdef SIS315H
3684 USHORT tempah,pushax=0,modenum;
3685 #endif
3686 USHORT temp=0;
3687
3688 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3689
3690 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { /* ===== For 30xB/LV ===== */
3691
3692 if(HwInfo->jChipType < SIS_315H) {
3693
3694 #ifdef SIS300 /* 300 series */
3695
3696 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
3697 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3698 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
3699 } else {
3700 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
3701 }
3702 SiS_PanelDelay(SiS_Pr, HwInfo, 3);
3703 }
3704 if(SiS_Is301B(SiS_Pr)) {
3705 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);
3706 SiS_ShortDelay(SiS_Pr,1);
3707 }
3708 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
3709 SiS_DisplayOff(SiS_Pr);
3710 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3711 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
3712 SiS_UnLockCRT2(SiS_Pr,HwInfo);
3713 if(!(SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
3714 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
3715 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
3716 }
3717 if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ||
3718 (!(SiS_CR36BIOSWord23d(SiS_Pr, HwInfo))) ) {
3719 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
3720 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3721 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
3722 } else {
3723 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
3724 }
3725 }
3726
3727 #endif /* SIS300 */
3728
3729 } else {
3730
3731 #ifdef SIS315H /* 315 series */
3732
3733 BOOLEAN custom1 = ((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
3734 (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) ? TRUE : FALSE;
3735
3736 modenum = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34) & 0x7f;
3737
3738 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3739
3740 #ifdef SET_EMI
3741 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
3742 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
3743 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
3744 }
3745 }
3746 #endif
3747 if( (modenum <= 0x13) ||
3748 (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
3749 (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ) {
3750 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
3751 if(custom1) SiS_PanelDelay(SiS_Pr, HwInfo, 3);
3752 }
3753
3754 if(!custom1) {
3755 SiS_DDC2Delay(SiS_Pr,0xff00);
3756 SiS_DDC2Delay(SiS_Pr,0xe000);
3757 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
3758 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
3759 if(IS_SIS740) {
3760 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
3761 }
3762 SiS_PanelDelay(SiS_Pr, HwInfo, 3);
3763 }
3764
3765 }
3766
3767 if(!(SiS_IsNotM650orLater(SiS_Pr, HwInfo))) {
3768 tempah = 0xef;
3769 if(SiS_IsVAMode(SiS_Pr,HwInfo)) tempah = 0xf7;
3770 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
3771 }
3772
3773 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3774 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,~0x10);
3775 }
3776
3777 tempah = 0x3f;
3778 if(SiS_IsDualEdge(SiS_Pr,HwInfo)) {
3779 tempah = 0x7f;
3780 if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) tempah = 0xbf;
3781 }
3782 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
3783
3784 if((SiS_IsVAMode(SiS_Pr,HwInfo)) ||
3785 ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && (modenum <= 0x13))) {
3786
3787 SiS_DisplayOff(SiS_Pr);
3788 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3789 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
3790 }
3791 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3792 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
3793
3794 }
3795
3796 if((!(SiS_IsVAMode(SiS_Pr,HwInfo))) ||
3797 ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && (modenum <= 0x13))) {
3798
3799 if(!(SiS_IsDualEdge(SiS_Pr,HwInfo))) {
3800 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
3801 SiS_DisplayOff(SiS_Pr);
3802 }
3803 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
3804
3805 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3806 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
3807 }
3808
3809 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3810 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
3811 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
3812 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
3813 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
3814
3815 }
3816
3817 if(SiS_IsNotM650orLater(SiS_Pr,HwInfo)) {
3818 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
3819 }
3820
3821 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3822
3823 if(!custom1) {
3824
3825 if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
3826 if(!(SiS_CRT2IsLCD(SiS_Pr,HwInfo))) {
3827 if(!(SiS_IsDualEdge(SiS_Pr,HwInfo))) {
3828 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
3829 }
3830 }
3831 }
3832
3833 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
3834
3835 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
3836 if(SiS_IsVAorLCD(SiS_Pr, HwInfo)) {
3837 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 20);
3838 }
3839 }
3840
3841 } else {
3842
3843 if((SiS_IsVAMode(SiS_Pr,HwInfo)) ||
3844 (!(SiS_IsDualEdge(SiS_Pr,HwInfo)))) {
3845 if((!(SiS_WeHaveBacklightCtrl(SiS_Pr, HwInfo))) ||
3846 (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo)))) {
3847 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
3848 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
3849 SiS_PanelDelay(SiS_Pr, HwInfo, 4);
3850 }
3851 }
3852
3853 }
3854 }
3855
3856 #endif /* SIS315H */
3857
3858 }
3859
3860 } else { /* ============ For 301 ================ */
3861
3862 if(HwInfo->jChipType < SIS_315H) {
3863 #ifdef SIS300
3864 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
3865 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
3866 SiS_PanelDelay(SiS_Pr, HwInfo, 3);
3867 }
3868 #endif
3869 }
3870
3871 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF); /* disable VB */
3872 SiS_DisplayOff(SiS_Pr);
3873
3874 if(HwInfo->jChipType >= SIS_315H) {
3875 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
3876 }
3877
3878 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); /* disable lock mode */
3879
3880 if(HwInfo->jChipType >= SIS_315H) {
3881 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
3882 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
3883 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
3884 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
3885 } else {
3886 #ifdef SIS300
3887 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); /* disable CRT2 */
3888 if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ||
3889 (!(SiS_CR36BIOSWord23d(SiS_Pr,HwInfo))) ) {
3890 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
3891 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
3892 }
3893 #endif
3894 }
3895
3896 }
3897
3898 } else { /* ============ For LVDS =============*/
3899
3900 if(HwInfo->jChipType < SIS_315H) {
3901
3902 #ifdef SIS300 /* 300 series */
3903
3904 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
3905 SiS_SetCH700x(SiS_Pr,0x090E);
3906 }
3907
3908 if(HwInfo->jChipType == SIS_730) {
3909 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
3910 SiS_WaitVBRetrace(SiS_Pr,HwInfo);
3911 }
3912 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
3913 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
3914 SiS_PanelDelay(SiS_Pr, HwInfo, 3);
3915 }
3916 } else {
3917 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
3918 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
3919 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
3920 SiS_WaitVBRetrace(SiS_Pr,HwInfo);
3921 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {
3922 SiS_DisplayOff(SiS_Pr);
3923 }
3924 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
3925 SiS_PanelDelay(SiS_Pr, HwInfo, 3);
3926 }
3927 }
3928 }
3929 }
3930
3931 SiS_DisplayOff(SiS_Pr);
3932
3933 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3934
3935 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
3936 SiS_UnLockCRT2(SiS_Pr,HwInfo);
3937 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
3938 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
3939
3940 if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ||
3941 (!(SiS_CR36BIOSWord23d(SiS_Pr,HwInfo))) ) {
3942 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
3943 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
3944 }
3945
3946 #endif /* SIS300 */
3947
3948 } else {
3949
3950 #ifdef SIS315H /* 315 series */
3951
3952 if(!(SiS_IsNotM650orLater(SiS_Pr,HwInfo))) {
3953 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,~0x18);
3954 }
3955
3956 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
3957
3958 if(HwInfo->jChipType == SIS_740) {
3959 temp = SiS_GetCH701x(SiS_Pr,0x61);
3960 if(temp < 1) {
3961 SiS_SetCH701x(SiS_Pr,0xac76);
3962 SiS_SetCH701x(SiS_Pr,0x0066);
3963 }
3964
3965 if( (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
3966 (SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo)) ) {
3967 SiS_SetCH701x(SiS_Pr,0x3e49);
3968 }
3969 }
3970
3971 if( (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
3972 (SiS_IsVAMode(SiS_Pr,HwInfo)) ) {
3973 SiS_Chrontel701xBLOff(SiS_Pr);
3974 SiS_Chrontel701xOff(SiS_Pr,HwInfo);
3975 }
3976
3977 if(HwInfo->jChipType != SIS_740) {
3978 if( (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
3979 (SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo)) ) {
3980 SiS_SetCH701x(SiS_Pr,0x0149);
3981 }
3982 }
3983
3984 }
3985
3986 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
3987 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
3988 SiS_PanelDelay(SiS_Pr, HwInfo, 3);
3989 }
3990
3991 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
3992 (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
3993 (!(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo))) ) {
3994 SiS_DisplayOff(SiS_Pr);
3995 }
3996
3997 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
3998 (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
3999 (!(SiS_IsVAMode(SiS_Pr,HwInfo))) ) {
4000 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4001 }
4002
4003 if(HwInfo->jChipType == SIS_740) {
4004 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4005 }
4006
4007 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4008
4009 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4010 (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
4011 (!(SiS_IsVAMode(SiS_Pr,HwInfo))) ) {
4012 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4013 }
4014
4015 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4016 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4017 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4018 if(HwInfo->jChipType == SIS_550) {
4019 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xbf);
4020 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xef);
4021 }
4022 }
4023 } else {
4024 if(HwInfo->jChipType == SIS_740) {
4025 if(SiS_IsLCDOrLCDA(SiS_Pr,HwInfo)) {
4026 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4027 }
4028 } else if(SiS_IsVAMode(SiS_Pr,HwInfo)) {
4029 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4030 }
4031 }
4032
4033 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4034 if(SiS_IsDualEdge(SiS_Pr,HwInfo)) {
4035 /* SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff); */
4036 } else {
4037 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
4038 }
4039 }
4040
4041 SiS_UnLockCRT2(SiS_Pr,HwInfo);
4042
4043 if(HwInfo->jChipType == SIS_550) {
4044 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); /* DirectDVD PAL?*/
4045 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); /* VB clock / 4 ? */
4046 } else if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4047 (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
4048 (!(SiS_IsVAMode(SiS_Pr,HwInfo))) ) {
4049 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4050 }
4051
4052 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4053 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4054 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4055 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
4056 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
4057 }
4058 }
4059 }
4060
4061 #endif /* SIS315H */
4062
4063 } /* 315 series */
4064
4065 } /* LVDS */
4066
4067 }
4068
4069 /*********************************************/
4070 /* ENABLE VIDEO BRIDGE */
4071 /*********************************************/
4072
4073 /* NEVER use any variables (VBInfo), this will be called
4074 * from outside the context of a mode switch!
4075 * MUST call getVBType before calling this
4076 */
4077 void
SiS_EnableBridge(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)4078 SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
4079 {
4080 USHORT temp=0,tempah;
4081 #ifdef SIS315H
4082 USHORT temp1,pushax=0;
4083 BOOLEAN delaylong = FALSE;
4084 #endif
4085
4086 if(SiS_Pr->SiS_VBType & VB_SISVB) {
4087
4088 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { /* ====== For 301B et al ====== */
4089
4090 if(HwInfo->jChipType < SIS_315H) {
4091
4092 #ifdef SIS300 /* 300 series */
4093
4094 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4095 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4096 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4097 } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
4098 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
4099 }
4100 if(SiS_Pr->SiS_VBType & (VB_SIS301LV302LV | VB_NoLCD)) {
4101 if(!(SiS_CR36BIOSWord23d(SiS_Pr, HwInfo))) {
4102 SiS_PanelDelay(SiS_Pr, HwInfo, 0);
4103 }
4104 }
4105 }
4106
4107 if((SiS_Pr->SiS_VBType & VB_NoLCD) &&
4108 (SiS_CRT2IsLCD(SiS_Pr, HwInfo))) {
4109
4110 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* Enable CRT2 */
4111 SiS_DisplayOn(SiS_Pr);
4112 SiS_UnLockCRT2(SiS_Pr,HwInfo);
4113 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4114 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4115 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4116 } else {
4117 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4118 }
4119 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4120 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4121 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
4122 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4123 }
4124 SiS_WaitVBRetrace(SiS_Pr,HwInfo);
4125 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00);
4126 }
4127 }
4128
4129 } else {
4130
4131 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
4132 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4133 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4134 if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4135 }
4136 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4137 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4138 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */
4139 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
4140 SiS_DisplayOn(SiS_Pr);
4141 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4142 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4143 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4144 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
4145 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4146 }
4147 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4148 }
4149 }
4150 }
4151
4152 }
4153
4154
4155 #endif /* SIS300 */
4156
4157 } else {
4158
4159 #ifdef SIS315H /* 315 series */
4160
4161 UCHAR r30=0, r31=0, r32=0, r33=0, cr36=0;
4162 /* USHORT emidelay=0; */
4163
4164 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4165 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef);
4166 #ifdef SET_EMI
4167 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
4168 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4169 }
4170 #endif
4171 }
4172
4173 if(!(SiS_IsNotM650orLater(SiS_Pr, HwInfo))) {
4174 tempah = 0x10;
4175 if(SiS_LCDAEnabled(SiS_Pr, HwInfo)) {
4176 if(SiS_TVEnabled(SiS_Pr, HwInfo)) tempah = 0x18;
4177 else tempah = 0x08;
4178 }
4179 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah);
4180 }
4181
4182 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4183
4184 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
4185 SiS_DisplayOff(SiS_Pr);
4186 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
4187 if(IS_SIS740) {
4188 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
4189 }
4190
4191 if(SiS_IsVAorLCD(SiS_Pr, HwInfo)) {
4192 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
4193 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 2);
4194 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4195 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 2);
4196 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
4197 SiS_GenericDelay(SiS_Pr, 0x4500);
4198 }
4199 }
4200 }
4201
4202 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {
4203 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10);
4204 delaylong = TRUE;
4205 }
4206
4207 }
4208
4209 if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
4210
4211 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
4212 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4213 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4214 if(!(tempah & SetCRT2ToRAMDAC)) {
4215 if(!(SiS_LCDAEnabled(SiS_Pr, HwInfo))) temp |= 0x20;
4216 }
4217 }
4218 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4219
4220 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
4221
4222 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4223 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4224
4225 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4226 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
4227 }
4228
4229 } else {
4230
4231 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20);
4232
4233 }
4234
4235 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
4236 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4237
4238 tempah = 0xc0;
4239 if(SiS_IsDualEdge(SiS_Pr, HwInfo)) {
4240 tempah = 0x80;
4241 if(!(SiS_IsVAMode(SiS_Pr, HwInfo))) tempah = 0x40;
4242 }
4243 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4244
4245 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4246
4247 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
4248
4249 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10);
4250 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4251
4252 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
4253 #ifdef SET_EMI
4254 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
4255 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4256 }
4257 #endif
4258 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
4259 #ifdef SET_EMI
4260 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
4261
4262 cr36 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
4263
4264 if(SiS_Pr->SiS_ROMNew) {
4265 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
4266 USHORT romptr = GetLCDStructPtr661_2(SiS_Pr, HwInfo);
4267 if(romptr) {
4268 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20);
4269 SiS_Pr->EMI_30 = 0;
4270 SiS_Pr->EMI_31 = ROMAddr[romptr + 14];
4271 SiS_Pr->EMI_32 = ROMAddr[romptr + 15];
4272 SiS_Pr->EMI_33 = ROMAddr[romptr + 16];
4273 if(ROMAddr[romptr + 1] & 0x10) SiS_Pr->EMI_30 = 0x40;
4274 /* emidelay = SISGETROMW((romptr + 0x22)); */
4275 SiS_Pr->HaveEMI = SiS_Pr->HaveEMILCD = SiS_Pr->OverruleEMI = TRUE;
4276 }
4277 }
4278
4279 /* (P4_30|0x40) */
4280 /* Compal 1400x1050: 0x05, 0x60, 0x00 YES (1.10.7w; CR36=69) */
4281 /* Compal 1400x1050: 0x0d, 0x70, 0x40 YES (1.10.7x; CR36=69) */
4282 /* Acer 1280x1024: 0x12, 0xd0, 0x6b NO (1.10.9k; CR36=73) */
4283 /* Compaq 1280x1024: 0x0d, 0x70, 0x6b YES (1.12.04b; CR36=03) */
4284 /* Clevo 1024x768: 0x05, 0x60, 0x33 NO (1.10.8e; CR36=12, DL!) */
4285 /* Clevo 1024x768: 0x0d, 0x70, 0x40 (if type == 3) YES (1.10.8y; CR36=?2) */
4286 /* Clevo 1024x768: 0x05, 0x60, 0x33 (if type != 3) YES (1.10.8y; CR36=?2) */
4287 /* Asus 1024x768: ? ? (1.10.8o; CR36=?2) */
4288 /* Asus 1024x768: 0x08, 0x10, 0x3c (problematic) YES (1.10.8q; CR36=22) */
4289
4290 if(SiS_Pr->HaveEMI) {
4291 r30 = SiS_Pr->EMI_30; r31 = SiS_Pr->EMI_31;
4292 r32 = SiS_Pr->EMI_32; r33 = SiS_Pr->EMI_33;
4293 } else {
4294 r30 = 0;
4295 }
4296
4297 /* EMI_30 is read at driver start; however, the BIOS sets this
4298 * (if it is used) only if the LCD is in use. In case we caught
4299 * the machine while on TV output, this bit is not set and we
4300 * don't know if it should be set - hence our detection is wrong.
4301 * Work-around this here:
4302 */
4303
4304 if((!SiS_Pr->HaveEMI) || (!SiS_Pr->HaveEMILCD)) {
4305 switch((cr36 & 0x0f)) {
4306 case 2:
4307 r30 |= 0x40;
4308 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) r30 &= ~0x40;
4309 if(!SiS_Pr->HaveEMI) {
4310 r31 = 0x05; r32 = 0x60; r33 = 0x33;
4311 if((cr36 & 0xf0) == 0x30) {
4312 r31 = 0x0d; r32 = 0x70; r33 = 0x40;
4313 }
4314 }
4315 break;
4316 case 3: /* 1280x1024 */
4317 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) r30 |= 0x40;
4318 if(!SiS_Pr->HaveEMI) {
4319 r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4320 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4321 r31 = 0x0d; r32 = 0x70; r33 = 0x6b;
4322 }
4323 }
4324 break;
4325 case 9: /* 1400x1050 */
4326 r30 |= 0x40;
4327 if(!SiS_Pr->HaveEMI) {
4328 r31 = 0x05; r32 = 0x60; r33 = 0x00;
4329 if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4330 r31 = 0x0d; r32 = 0x70; r33 = 0x40; /* BIOS values */
4331 }
4332 }
4333 break;
4334 case 11: /* 1600x1200 - unknown */
4335 r30 |= 0x40;
4336 if(!SiS_Pr->HaveEMI) {
4337 r31 = 0x05; r32 = 0x60; r33 = 0x00;
4338 }
4339 }
4340 }
4341
4342 /* BIOS values don't work so well sometimes */
4343 if(!SiS_Pr->OverruleEMI) {
4344 #ifdef COMPAL_HACK
4345 if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4346 if((cr36 & 0x0f) == 0x09) {
4347 r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x00;
4348 }
4349 }
4350 #endif
4351 #ifdef COMPAQ_HACK
4352 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4353 if((cr36 & 0x0f) == 0x03) {
4354 r30 = 0x20; r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4355 }
4356 }
4357 #endif
4358 #ifdef ASUS_HACK
4359 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4360 if((cr36 & 0x0f) == 0x02) {
4361 /* r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 2 */
4362 /* r30 = 0x20; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 3 */
4363 /* r30 = 0x60; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 4 */
4364 /* r30 = 0x20; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 5 */
4365 }
4366 }
4367 #endif
4368 }
4369
4370 if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) {
4371 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20);
4372 }
4373 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,r31);
4374 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,r32);
4375 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x33,r33);
4376 if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) {
4377 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
4378 } else {
4379 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x00);
4380 }
4381
4382 if( (SiS_LCDAEnabled(SiS_Pr, HwInfo)) ||
4383 (SiS_CRT2IsLCD(SiS_Pr, HwInfo)) ) {
4384 if(r30 & 0x40) {
4385 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 5);
4386 if(delaylong) {
4387 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 5);
4388 delaylong = FALSE;
4389 }
4390 SiS_WaitVBRetrace(SiS_Pr,HwInfo);
4391 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4392 SiS_GenericDelay(SiS_Pr, 0x500);
4393 }
4394 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40);
4395 }
4396 }
4397 }
4398 #endif
4399 }
4400
4401 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4402 if(SiS_IsVAorLCD(SiS_Pr, HwInfo)) {
4403 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10);
4404 if(delaylong) {
4405 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10);
4406 }
4407 SiS_WaitVBRetrace(SiS_Pr,HwInfo);
4408 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
4409 SiS_GenericDelay(SiS_Pr, 0x500);
4410 }
4411 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4412 }
4413 }
4414
4415 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4416 SiS_DisplayOn(SiS_Pr);
4417 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xff);
4418
4419 }
4420
4421 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4422 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4423 }
4424
4425 #endif /* SIS315H */
4426
4427 }
4428
4429 } else { /* ============ For 301 ================ */
4430
4431 if(HwInfo->jChipType < SIS_315H) {
4432 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4433 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
4434 SiS_PanelDelay(SiS_Pr, HwInfo, 0);
4435 }
4436 }
4437
4438 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
4439 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4440 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4441 if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4442 }
4443 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4444
4445 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
4446
4447 if(HwInfo->jChipType >= SIS_315H) {
4448 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4449 if(!(temp & 0x80)) {
4450 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80); /* BVBDOENABLE=1 */
4451 }
4452 }
4453
4454 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */
4455
4456 SiS_VBLongWait(SiS_Pr);
4457 SiS_DisplayOn(SiS_Pr);
4458 if(HwInfo->jChipType >= SIS_315H) {
4459 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4460 }
4461 SiS_VBLongWait(SiS_Pr);
4462
4463 if(HwInfo->jChipType < SIS_315H) {
4464 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4465 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4466 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00);
4467 }
4468 }
4469
4470 }
4471
4472 } else { /* =================== For LVDS ================== */
4473
4474 if(HwInfo->jChipType < SIS_315H) {
4475
4476 #ifdef SIS300 /* 300 series */
4477
4478 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4479 if(HwInfo->jChipType == SIS_730) {
4480 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4481 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4482 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4483 }
4484 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
4485 if(!(SiS_CR36BIOSWord23d(SiS_Pr,HwInfo))) {
4486 SiS_PanelDelay(SiS_Pr, HwInfo, 0);
4487 }
4488 }
4489
4490 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4491 SiS_DisplayOn(SiS_Pr);
4492 SiS_UnLockCRT2(SiS_Pr,HwInfo);
4493 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4494 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4495 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4496 } else {
4497 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4498 }
4499
4500 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4501 if(!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) {
4502 SiS_WaitVBRetrace(SiS_Pr, HwInfo);
4503 SiS_SetCH700x(SiS_Pr,0x0B0E);
4504 }
4505 }
4506
4507 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4508 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4509 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4510 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
4511 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4512 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4513 }
4514 SiS_WaitVBRetrace(SiS_Pr, HwInfo);
4515 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00);
4516 }
4517 }
4518 }
4519
4520 #endif /* SIS300 */
4521
4522 } else {
4523
4524 #ifdef SIS315H /* 315 series */
4525
4526 if(!(SiS_IsNotM650orLater(SiS_Pr,HwInfo))) {
4527 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x18);
4528 }
4529
4530 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4531 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4532 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
4533 SiS_PanelDelay(SiS_Pr, HwInfo, 0);
4534 }
4535 }
4536
4537 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4538 SiS_UnLockCRT2(SiS_Pr,HwInfo);
4539
4540 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4541
4542 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4543 temp = SiS_GetCH701x(SiS_Pr,0x66);
4544 temp &= 0x20;
4545 SiS_Chrontel701xBLOff(SiS_Pr);
4546 }
4547
4548 if(HwInfo->jChipType != SIS_550) {
4549 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4550 }
4551
4552 if(HwInfo->jChipType == SIS_740) {
4553 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4554 if(SiS_IsLCDOrLCDA(SiS_Pr, HwInfo)) {
4555 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4556 }
4557 }
4558 }
4559
4560 temp1 = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4561 if(!(temp1 & 0x80)) {
4562 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
4563 }
4564
4565 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4566 if(temp) {
4567 SiS_Chrontel701xBLOn(SiS_Pr, HwInfo);
4568 }
4569 }
4570
4571 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4572 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4573 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4574 if(HwInfo->jChipType == SIS_550) {
4575 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x40);
4576 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x10);
4577 }
4578 }
4579 } else if(SiS_IsVAMode(SiS_Pr,HwInfo)) {
4580 if(HwInfo->jChipType != SIS_740) {
4581 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4582 }
4583 }
4584
4585 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4586 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4587 }
4588
4589 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4590 if(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo)) {
4591 SiS_Chrontel701xOn(SiS_Pr,HwInfo);
4592 }
4593 if( (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
4594 (SiS_IsLCDOrLCDA(SiS_Pr,HwInfo)) ) {
4595 SiS_ChrontelDoSomething1(SiS_Pr,HwInfo);
4596 }
4597 }
4598
4599 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4600 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4601 if( (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
4602 (SiS_IsLCDOrLCDA(SiS_Pr,HwInfo)) ) {
4603 SiS_Chrontel701xBLOn(SiS_Pr, HwInfo);
4604 SiS_ChrontelInitTVVSync(SiS_Pr,HwInfo);
4605 }
4606 }
4607 } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4608 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4609 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4610 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4611 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00);
4612 }
4613 }
4614 }
4615
4616 #endif /* SIS315H */
4617
4618 } /* 310 series */
4619
4620 } /* LVDS */
4621
4622 }
4623
4624 /*********************************************/
4625 /* SET PART 1 REGISTER GROUP */
4626 /*********************************************/
4627
4628 /* Set CRT2 OFFSET / PITCH */
4629 static void
SiS_SetCRT2Offset(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RRTI,PSIS_HW_INFO HwInfo)4630 SiS_SetCRT2Offset(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
4631 USHORT RRTI, PSIS_HW_INFO HwInfo)
4632 {
4633 USHORT offset;
4634 UCHAR temp;
4635
4636 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return;
4637
4638 offset = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,RRTI,HwInfo);
4639
4640 if((SiS_Pr->SiS_LCDResInfo == Panel_640x480_2) ||
4641 (SiS_Pr->SiS_LCDResInfo == Panel_640x480_3)) {
4642 offset >>= 1;
4643 }
4644
4645 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(offset & 0xFF));
4646 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,(offset >> 8));
4647 temp = (UCHAR)(((offset >> 3) & 0xFF) + 1);
4648 if(offset % 8) temp++;
4649 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,temp);
4650 }
4651
4652 /* Set CRT2 sync and PanelLink mode */
4653 static void
SiS_SetCRT2Sync(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo)4654 SiS_SetCRT2Sync(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT RefreshRateTableIndex,
4655 PSIS_HW_INFO HwInfo)
4656 {
4657 USHORT tempah=0,tempbl,infoflag;
4658
4659 tempbl = 0xC0;
4660
4661 if(SiS_Pr->UseCustomMode) {
4662 infoflag = SiS_Pr->CInfoFlag;
4663 } else {
4664 infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
4665 }
4666
4667 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { /* LVDS */
4668
4669 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
4670 tempah = 0;
4671 } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) {
4672 tempah = SiS_Pr->SiS_LCDInfo;
4673 } else tempah = infoflag >> 8;
4674 tempah &= 0xC0;
4675 tempah |= 0x20;
4676 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4677 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4678 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
4679 (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
4680 tempah |= 0xf0;
4681 }
4682 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
4683 (SiS_Pr->SiS_IF_DEF_DSTN) ||
4684 (SiS_Pr->SiS_IF_DEF_TRUMPION) ||
4685 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ) {
4686 tempah |= 0x30;
4687 }
4688 }
4689 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
4690 if(HwInfo->jChipType >= SIS_315H) {
4691 tempah >>= 3;
4692 tempah &= 0x18;
4693 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xE7,tempah);
4694 /* Don't care about 12/18/24 bit mode - TV is via VGA, not PL */
4695 } else {
4696 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,0xe0);
4697 }
4698 } else {
4699 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4700 }
4701
4702 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
4703
4704 if(HwInfo->jChipType < SIS_315H) {
4705
4706 #ifdef SIS300 /* ---- 300 series --- */
4707
4708 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { /* 630 - 301B(-DH) */
4709
4710 tempah = infoflag >> 8;
4711 tempbl = 0;
4712 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4713 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4714 tempah = SiS_Pr->SiS_LCDInfo;
4715 tempbl = (tempah >> 6) & 0x03;
4716 }
4717 }
4718 tempah &= 0xC0;
4719 tempah |= 0x20;
4720 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4721 tempah |= 0xc0;
4722 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4723 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
4724 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
4725 }
4726
4727 } else { /* 630 - 301 */
4728
4729 tempah = infoflag >> 8;
4730 tempah &= 0xC0;
4731 tempah |= 0x20;
4732 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4733 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4734
4735 }
4736
4737 #endif /* SIS300 */
4738
4739 } else {
4740
4741 #ifdef SIS315H /* ------- 315 series ------ */
4742
4743 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { /* 315 - LVDS */
4744
4745 tempbl = 0;
4746 if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
4747 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
4748 tempah = infoflag >> 8;
4749 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4750 tempbl = ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6);
4751 }
4752 } else if((SiS_Pr->SiS_CustomT == CUT_CLEVO1400) &&
4753 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)) {
4754 tempah = infoflag >> 8;
4755 tempbl = 0x03;
4756 } else {
4757 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
4758 tempbl = (tempah >> 6) & 0x03;
4759 tempbl |= 0x08;
4760 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempbl |= 0x04;
4761 }
4762 tempah &= 0xC0;
4763 tempah |= 0x20;
4764 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4765 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) tempah |= 0xc0;
4766 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4767 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
4768 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4769 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
4770 }
4771 }
4772
4773 } else { /* 315 - TMDS */
4774
4775 tempah = tempbl = infoflag >> 8;
4776 if(!SiS_Pr->UseCustomMode) {
4777 tempbl = 0;
4778 if((SiS_Pr->SiS_VBType & VB_SIS301C) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
4779 if(ModeNo <= 0x13) {
4780 tempah = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
4781 }
4782 }
4783 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
4784 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4785 tempah = SiS_Pr->SiS_LCDInfo;
4786 tempbl = (tempah >> 6) & 0x03;
4787 }
4788 }
4789 }
4790 tempah &= 0xC0;
4791 tempah |= 0x20;
4792 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4793 if(SiS_Pr->SiS_VBType & VB_NoLCD) {
4794 /* Imitate BIOS bug */
4795 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempah |= 0xc0;
4796 }
4797 if((SiS_Pr->SiS_VBType & VB_SIS301C) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
4798 tempah >>= 3;
4799 tempah &= 0x18;
4800 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xe7,tempah);
4801 } else {
4802 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4803 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
4804 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4805 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
4806 }
4807 }
4808 }
4809
4810 }
4811 #endif /* SIS315H */
4812 }
4813 }
4814 }
4815
4816 /* Set CRT2 FIFO on 300/630/730 */
4817 #ifdef SIS300
4818 static void
SiS_SetCRT2FIFO_300(SiS_Private * SiS_Pr,USHORT ModeNo,PSIS_HW_INFO HwInfo)4819 SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,USHORT ModeNo,
4820 PSIS_HW_INFO HwInfo)
4821 {
4822 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
4823 USHORT temp,index;
4824 USHORT modeidindex,refreshratetableindex;
4825 USHORT VCLK=0,MCLK,colorth=0,data2=0;
4826 USHORT tempal, tempah, tempbx, tempcl, tempax;
4827 USHORT CRT1ModeNo,CRT2ModeNo;
4828 USHORT SelectRate_backup;
4829 ULONG data,eax;
4830 const UCHAR LatencyFactor[] = {
4831 97, 88, 86, 79, 77, 00, /*; 64 bit BQ=2 */
4832 00, 87, 85, 78, 76, 54, /*; 64 bit BQ=1 */
4833 97, 88, 86, 79, 77, 00, /*; 128 bit BQ=2 */
4834 00, 79, 77, 70, 68, 48, /*; 128 bit BQ=1 */
4835 80, 72, 69, 63, 61, 00, /*; 64 bit BQ=2 */
4836 00, 70, 68, 61, 59, 37, /*; 64 bit BQ=1 */
4837 86, 77, 75, 68, 66, 00, /*; 128 bit BQ=2 */
4838 00, 68, 66, 59, 57, 37 /*; 128 bit BQ=1 */
4839 };
4840 const UCHAR LatencyFactor730[] = {
4841 69, 63, 61,
4842 86, 79, 77,
4843 103, 96, 94,
4844 120,113,111,
4845 137,130,128, /* <-- last entry, data below */
4846 137,130,128, /* to avoid using illegal values */
4847 137,130,128,
4848 137,130,128,
4849 137,130,128,
4850 137,130,128,
4851 137,130,128,
4852 137,130,128,
4853 137,130,128,
4854 137,130,128,
4855 137,130,128,
4856 137,130,128,
4857 };
4858 const UCHAR ThLowB[] = {
4859 81, 4, 72, 6, 88, 8,120,12,
4860 55, 4, 54, 6, 66, 8, 90,12,
4861 42, 4, 45, 6, 55, 8, 75,12
4862 };
4863 const UCHAR ThTiming[] = {
4864 1, 2, 2, 3, 0, 1, 1, 2
4865 };
4866
4867 SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;
4868
4869 if(!SiS_Pr->CRT1UsesCustomMode) {
4870
4871 CRT1ModeNo = SiS_Pr->SiS_CRT1Mode; /* get CRT1 ModeNo */
4872 SiS_SearchModeID(SiS_Pr, &CRT1ModeNo, &modeidindex);
4873 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
4874 SiS_Pr->SiS_SelectCRT2Rate = 0;
4875 refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT1ModeNo, modeidindex, HwInfo);
4876
4877 if(CRT1ModeNo >= 0x13) {
4878 index = SiS_Pr->SiS_RefIndex[refreshratetableindex].Ext_CRTVCLK;
4879 index &= 0x3F;
4880 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; /* Get VCLK */
4881
4882 colorth = SiS_GetColorDepth(SiS_Pr,CRT1ModeNo,modeidindex); /* Get colordepth */
4883 colorth >>= 1;
4884 if(!colorth) colorth++;
4885 }
4886
4887 } else {
4888
4889 CRT1ModeNo = 0xfe;
4890 VCLK = SiS_Pr->CSRClock_CRT1; /* Get VCLK */
4891 data2 = (SiS_Pr->CModeFlag_CRT1 & ModeInfoFlag) - 2;
4892 switch(data2) { /* Get color depth */
4893 case 0 : colorth = 1; break;
4894 case 1 : colorth = 1; break;
4895 case 2 : colorth = 2; break;
4896 case 3 : colorth = 2; break;
4897 case 4 : colorth = 3; break;
4898 case 5 : colorth = 4; break;
4899 default: colorth = 2;
4900 }
4901
4902 }
4903
4904 if(CRT1ModeNo >= 0x13) {
4905 if(HwInfo->jChipType == SIS_300) {
4906 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A);
4907 } else {
4908 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A);
4909 }
4910 index &= 0x07;
4911 MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK; /* Get MCLK */
4912
4913 data2 = (colorth * VCLK) / MCLK;
4914
4915 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
4916 temp = ((temp & 0x00FF) >> 6) << 1;
4917 if(temp == 0) temp = 1;
4918 temp <<= 2;
4919 temp &= 0xff;
4920
4921 data2 = temp - data2;
4922
4923 if((28 * 16) % data2) {
4924 data2 = (28 * 16) / data2;
4925 data2++;
4926 } else {
4927 data2 = (28 * 16) / data2;
4928 }
4929
4930 if(HwInfo->jChipType == SIS_300) {
4931
4932 tempah = SiS_GetReg(SiS_Pr->SiS_P3c4,0x18);
4933 tempah &= 0x62;
4934 tempah >>= 1;
4935 tempal = tempah;
4936 tempah >>= 3;
4937 tempal |= tempah;
4938 tempal &= 0x07;
4939 tempcl = ThTiming[tempal];
4940 tempbx = SiS_GetReg(SiS_Pr->SiS_P3c4,0x16);
4941 tempbx >>= 6;
4942 tempah = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
4943 tempah >>= 4;
4944 tempah &= 0x0c;
4945 tempbx |= tempah;
4946 tempbx <<= 1;
4947 tempal = ThLowB[tempbx + 1];
4948 tempal *= tempcl;
4949 tempal += ThLowB[tempbx];
4950 data = tempal;
4951
4952 } else if(HwInfo->jChipType == SIS_730) {
4953
4954 #ifndef LINUX_XF86
4955 SiS_SetRegLong(0xcf8,0x80000050);
4956 eax = SiS_GetRegLong(0xcfc);
4957 #else
4958 eax = pciReadLong(0x00000000, 0x50);
4959 #endif
4960 tempal = (USHORT)(eax >> 8);
4961 tempal &= 0x06;
4962 tempal <<= 5;
4963
4964 #ifndef LINUX_XF86
4965 SiS_SetRegLong(0xcf8,0x800000A0);
4966 eax = SiS_GetRegLong(0xcfc);
4967 #else
4968 eax = pciReadLong(0x00000000, 0xA0);
4969 #endif
4970 temp = (USHORT)(eax >> 28);
4971 temp &= 0x0F;
4972 tempal |= temp;
4973
4974 tempbx = tempal; /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */
4975 tempbx = 0; /* -- do it like the BIOS anyway... */
4976 tempax = tempbx;
4977 tempbx &= 0xc0;
4978 tempbx >>= 6;
4979 tempax &= 0x0f;
4980 tempax *= 3;
4981 tempbx += tempax;
4982
4983 data = LatencyFactor730[tempbx];
4984 data += 15;
4985 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
4986 if(!(temp & 0x80)) data += 5;
4987
4988 } else {
4989
4990 index = 0;
4991 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
4992 if(temp & 0x0080) index += 12;
4993
4994 #ifndef LINUX_XF86
4995 SiS_SetRegLong(0xcf8,0x800000A0);
4996 eax = SiS_GetRegLong(0xcfc);
4997 #else
4998 /* We use pci functions X offers. We use tag 0, because
4999 * we want to read/write to the host bridge (which is always
5000 * 00:00.0 on 630, 730 and 540), not the VGA device.
5001 */
5002 eax = pciReadLong(0x00000000, 0xA0);
5003 #endif
5004 temp = (USHORT)(eax >> 24);
5005 if(!(temp&0x01)) index += 24;
5006
5007 #ifndef LINUX_XF86
5008 SiS_SetRegLong(0xcf8,0x80000050);
5009 eax = SiS_GetRegLong(0xcfc);
5010 #else
5011 eax = pciReadLong(0x00000000, 0x50);
5012 #endif
5013 temp=(USHORT)(eax >> 24);
5014 if(temp & 0x01) index += 6;
5015
5016 temp = (temp & 0x0F) >> 1;
5017 index += temp;
5018
5019 data = LatencyFactor[index];
5020 data += 15;
5021 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
5022 if(!(temp & 0x80)) data += 5;
5023 }
5024
5025 data += data2; /* CRT1 Request Period */
5026
5027 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5028 SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5029
5030 if(!SiS_Pr->UseCustomMode) {
5031
5032 CRT2ModeNo = ModeNo;
5033 SiS_SearchModeID(SiS_Pr, &CRT2ModeNo, &modeidindex);
5034
5035 refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT2ModeNo, modeidindex, HwInfo);
5036
5037 index = SiS_GetVCLK2Ptr(SiS_Pr,CRT2ModeNo,modeidindex,
5038 refreshratetableindex,HwInfo);
5039 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; /* Get VCLK */
5040
5041 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
5042 if(SiS_Pr->SiS_UseROM) {
5043 if(ROMAddr[0x220] & 0x01) {
5044 VCLK = ROMAddr[0x229] | (ROMAddr[0x22a] << 8);
5045 }
5046 }
5047 }
5048
5049 } else {
5050
5051 CRT2ModeNo = 0xfe;
5052 VCLK = SiS_Pr->CSRClock; /* Get VCLK */
5053
5054 }
5055
5056 colorth = SiS_GetColorDepth(SiS_Pr,CRT2ModeNo,modeidindex); /* Get colordepth */
5057 colorth >>= 1;
5058 if(!colorth) colorth++;
5059
5060 data = data * VCLK * colorth;
5061 if(data % (MCLK << 4)) {
5062 data = data / (MCLK << 4);
5063 data++;
5064 } else {
5065 data = data / (MCLK << 4);
5066 }
5067
5068 if(data <= 6) data = 6;
5069 if(data > 0x14) data = 0x14;
5070
5071 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x01);
5072 if(HwInfo->jChipType == SIS_300) {
5073 if(data <= 0x0f) temp = (temp & (~0x1F)) | 0x13;
5074 else temp = (temp & (~0x1F)) | 0x16;
5075 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
5076 temp = (temp & (~0x1F)) | 0x13;
5077 }
5078 } else {
5079 if( ( (HwInfo->jChipType == SIS_630) ||
5080 (HwInfo->jChipType == SIS_730) ) &&
5081 (HwInfo->jChipRevision >= 0x30) ) /* 630s or 730(s?) */
5082 {
5083 temp = (temp & (~0x1F)) | 0x1b;
5084 } else {
5085 temp = (temp & (~0x1F)) | 0x16;
5086 }
5087 }
5088 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0xe0,temp);
5089
5090 if( (HwInfo->jChipType == SIS_630) &&
5091 (HwInfo->jChipRevision >= 0x30) ) /* 630s, NOT 730 */
5092 {
5093 if(data > 0x13) data = 0x13;
5094 }
5095 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,0xe0,data);
5096
5097 } else { /* If mode <= 0x13, we just restore everything */
5098
5099 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5100 SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5101
5102 }
5103 }
5104 #endif
5105
5106 /* Set CRT2 FIFO on 315/330 series */
5107 #ifdef SIS315H
5108 static void
SiS_SetCRT2FIFO_310(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)5109 SiS_SetCRT2FIFO_310(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
5110 {
5111 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3B);
5112 if( (HwInfo->jChipType == SIS_760) &&
5113 (SiS_Pr->SiS_SysFlags & SF_760LFB) &&
5114 (SiS_Pr->SiS_ModeType == Mode32Bpp) &&
5115 (SiS_Pr->SiS_VGAHDE >= 1280) &&
5116 (SiS_Pr->SiS_VGAVDE >= 1024) ) {
5117 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x03);
5118 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3b);
5119 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5120 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x01);
5121 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5122 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,0x6e);
5123 } else {
5124 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3f,0x04);
5125 }
5126
5127 }
5128 #endif
5129
5130 static USHORT
SiS_GetVGAHT2(SiS_Private * SiS_Pr)5131 SiS_GetVGAHT2(SiS_Private *SiS_Pr)
5132 {
5133 ULONG tempax,tempbx;
5134
5135 tempbx = (SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) * SiS_Pr->SiS_RVBHCMAX;
5136 tempax = (SiS_Pr->SiS_VT - SiS_Pr->SiS_VDE) * SiS_Pr->SiS_RVBHCFACT;
5137 tempax = (tempax * SiS_Pr->SiS_HT) / tempbx;
5138 return((USHORT)tempax);
5139 }
5140
5141 /* Set Part 1 / SiS bridge slave mode */
5142 static void
SiS_SetGroup1_301(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,PSIS_HW_INFO HwInfo,USHORT RefreshRateTableIndex)5143 SiS_SetGroup1_301(SiS_Private *SiS_Pr, USHORT ModeNo,USHORT ModeIdIndex,
5144 PSIS_HW_INFO HwInfo,USHORT RefreshRateTableIndex)
5145 {
5146 USHORT push1,push2;
5147 USHORT tempax,tempbx,tempcx,temp;
5148 USHORT resinfo,modeflag,xres=0;
5149 unsigned char p1_7, p1_8;
5150
5151 if(ModeNo <= 0x13) {
5152 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5153 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
5154 } else if(SiS_Pr->UseCustomMode) {
5155 modeflag = SiS_Pr->CModeFlag;
5156 resinfo = 0;
5157 xres = SiS_Pr->CHDisplay;
5158 } else {
5159 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5160 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
5161 xres = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes;
5162 }
5163
5164 /* The following is only done if bridge is in slave mode: */
5165
5166 if((HwInfo->jChipType >= SIS_661) && (ModeNo > 0x13)) {
5167 if(xres >= 1600) {
5168 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x31,0x04);
5169 }
5170 }
5171
5172 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0xff); /* set MAX HT */
5173
5174 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) modeflag |= Charx8Dot;
5175
5176 if(modeflag & Charx8Dot) tempcx = 0x08;
5177 else tempcx = 0x09;
5178
5179 tempax = SiS_Pr->SiS_VGAHDE; /* 0x04 Horizontal Display End */
5180 if(modeflag & HalfDCLK) tempax >>= 1;
5181 tempax = ((tempax / tempcx) - 1) & 0xff;
5182 tempbx = tempax;
5183
5184 temp = tempax;
5185 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,temp);
5186
5187 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5188 if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
5189 temp += 2;
5190 }
5191 }
5192 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
5193 if(resinfo == SIS_RI_800x600) temp -= 2;
5194 }
5195 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x05,temp); /* 0x05 Horizontal Display Start */
5196
5197 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x06,0x03); /* 0x06 Horizontal Blank end */
5198
5199 tempax = 0xFFFF;
5200 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempax = SiS_GetVGAHT2(SiS_Pr);
5201 if(tempax >= SiS_Pr->SiS_VGAHT) tempax = SiS_Pr->SiS_VGAHT;
5202 if(modeflag & HalfDCLK) tempax >>= 1;
5203 tempax = (tempax / tempcx) - 5;
5204 tempcx = tempax;
5205
5206 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
5207 temp = tempcx - 1;
5208 if(!(modeflag & HalfDCLK)) {
5209 temp -= 6;
5210 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
5211 temp -= 2;
5212 if(ModeNo > 0x13) temp -= 10;
5213 }
5214 }
5215 } else {
5216 tempcx = (tempcx + tempbx) >> 1;
5217 temp = (tempcx & 0x00FF) + 2;
5218 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5219 temp--;
5220 if(!(modeflag & HalfDCLK)) {
5221 if((modeflag & Charx8Dot)) {
5222 temp += 4;
5223 if(SiS_Pr->SiS_VGAHDE >= 800) temp -= 6;
5224 if(HwInfo->jChipType >= SIS_315H) {
5225 if(SiS_Pr->SiS_VGAHDE == 800) temp += 2;
5226 }
5227 }
5228 }
5229 } else {
5230 if(!(modeflag & HalfDCLK)) {
5231 temp -= 4;
5232 if((SiS_Pr->SiS_LCDResInfo != Panel_1280x960) &&
5233 (SiS_Pr->SiS_LCDResInfo != Panel_1600x1200)) {
5234 if(SiS_Pr->SiS_VGAHDE >= 800) {
5235 temp -= 7;
5236 if(HwInfo->jChipType < SIS_315H) {
5237 if(SiS_Pr->SiS_ModeType == ModeEGA) {
5238 if(SiS_Pr->SiS_VGAVDE == 1024) {
5239 temp += 15;
5240 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024)
5241 temp += 7;
5242 }
5243 }
5244 }
5245 if(SiS_Pr->SiS_LCDResInfo != Panel_1400x1050) {
5246 if(SiS_Pr->SiS_VGAHDE >= 1280) {
5247 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) temp += 28;
5248 }
5249 }
5250 }
5251 }
5252 }
5253 }
5254 }
5255
5256 p1_7 = temp;
5257 p1_8 = 0x00;
5258
5259 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5260 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
5261 if(ModeNo <= 0x01) {
5262 p1_7 = 0x2a;
5263 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) p1_8 = 0x61;
5264 else p1_8 = 0x41;
5265 } else if(SiS_Pr->SiS_ModeType == ModeText) {
5266 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) p1_7 = 0x54;
5267 else p1_7 = 0x55;
5268 p1_8 = 0x00;
5269 } else if(ModeNo <= 0x13) {
5270 if(modeflag & HalfDCLK) {
5271 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
5272 p1_7 = 0x30;
5273 p1_8 = 0x03;
5274 } else {
5275 p1_7 = 0x2f;
5276 p1_8 = 0x02;
5277 }
5278 } else {
5279 p1_7 = 0x5b;
5280 p1_8 = 0x03;
5281 }
5282 } else if( ((HwInfo->jChipType >= SIS_315H) &&
5283 ((ModeNo == 0x50) || (ModeNo == 0x56) || (ModeNo == 0x53))) ||
5284 ((HwInfo->jChipType < SIS_315H) &&
5285 (resinfo == SIS_RI_320x200 || resinfo == SIS_RI_320x240)) ) {
5286 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
5287 p1_7 = 0x30,
5288 p1_8 = 0x03;
5289 } else {
5290 p1_7 = 0x2f;
5291 p1_8 = 0x03;
5292 }
5293 }
5294 }
5295 }
5296
5297 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
5298 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p)) {
5299 p1_7 = 0x63;
5300 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) p1_7 = 0x55;
5301 }
5302 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
5303 if(!(modeflag & HalfDCLK)) {
5304 p1_7 = 0xb2;
5305 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
5306 p1_7 = 0xab;
5307 }
5308 }
5309 } else {
5310 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
5311 if(modeflag & HalfDCLK) p1_7 = 0x30;
5312 }
5313 }
5314 }
5315
5316 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,p1_7); /* 0x07 Horizontal Retrace Start */
5317 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,p1_8); /* 0x08 Horizontal Retrace End */
5318
5319 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x03); /* 0x18 SR08 (FIFO Threshold?) */
5320
5321 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x19,0xF0);
5322
5323 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,0xFF); /* 0x09 Set Max VT */
5324
5325 tempcx = 0x121;
5326 tempbx = SiS_Pr->SiS_VGAVDE; /* 0x0E Vertical Display End */
5327 if (tempbx == 357) tempbx = 350;
5328 else if(tempbx == 360) tempbx = 350;
5329 else if(tempbx == 375) tempbx = 350;
5330 else if(tempbx == 405) tempbx = 400;
5331 else if(tempbx == 420) tempbx = 400;
5332 else if(tempbx == 525) tempbx = 480;
5333 push2 = tempbx;
5334 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5335 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5336 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
5337 if (tempbx == 350) tempbx += 5;
5338 else if(tempbx == 480) tempbx += 5;
5339 }
5340 }
5341 }
5342 tempbx -= 2;
5343 temp = tempbx & 0x00FF;
5344 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,temp); /* 0x10 vertical Blank Start */
5345
5346 tempbx = push2;
5347 tempbx--;
5348 temp = tempbx & 0x00FF;
5349 #if 0
5350 /* Missing code from 630/301B 2.04.5a and 650/302LV 1.10.6s (calles int 2f) */
5351 if(xxx()) {
5352 if(temp == 0xdf) temp = 0xda;
5353 }
5354 #endif
5355 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp);
5356
5357 temp = 0;
5358 if(modeflag & DoubleScanMode) temp |= 0x80;
5359 if(HwInfo->jChipType >= SIS_661) {
5360 if(tempbx & 0x0200) temp |= 0x20;
5361 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x0B,0x5F,temp);
5362 if(tempbx & 0x0100) tempcx |= 0x000a;
5363 if(tempbx & 0x0400) tempcx |= 0x1200;
5364 } else {
5365 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,temp);
5366 if(tempbx & 0x0100) tempcx |= 0x0002;
5367 if(tempbx & 0x0400) tempcx |= 0x0600;
5368 }
5369
5370 if(tempbx & 0x0200) tempcx |= 0x0040;
5371
5372 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,0x00); /* 0x11 Vertical Blank End */
5373
5374 tempax = (SiS_Pr->SiS_VGAVT - tempbx) >> 2;
5375
5376 if((ModeNo > 0x13) || (HwInfo->jChipType < SIS_315H)) {
5377 if(resinfo != SIS_RI_1280x1024) {
5378 tempbx += (tempax << 1);
5379 }
5380 } else if(HwInfo->jChipType >= SIS_315H) {
5381 if(SiS_Pr->SiS_LCDResInfo != Panel_1400x1050) {
5382 tempbx += (tempax << 1);
5383 }
5384 }
5385
5386 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
5387 tempbx -= 10;
5388 } else {
5389 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
5390 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
5391 tempbx += 40;
5392 if(HwInfo->jChipType >= SIS_315H) {
5393 if(SiS_Pr->SiS_VGAHDE == 800) tempbx += 10;
5394 }
5395 }
5396 }
5397 }
5398 tempax >>= 2;
5399 tempax++;
5400 tempax += tempbx;
5401 push1 = tempax;
5402 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
5403 if(tempbx <= 513) {
5404 if(tempax >= 513) tempbx = 513;
5405 }
5406 }
5407 temp = tempbx & 0x00FF;
5408 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp); /* 0x0C Vertical Retrace Start */
5409
5410 tempbx--;
5411 temp = tempbx & 0x00FF;
5412 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,temp);
5413
5414 if(tempbx & 0x0100) tempcx |= 0x0008;
5415
5416 if(tempbx & 0x0200) {
5417 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x0B,0x20);
5418 }
5419 tempbx++;
5420
5421 if(tempbx & 0x0100) tempcx |= 0x0004;
5422 if(tempbx & 0x0200) tempcx |= 0x0080;
5423 if(tempbx & 0x0400) {
5424 if(HwInfo->jChipType >= SIS_661) tempcx |= 0x0800;
5425 else if(SiS_Pr->SiS_VBType & VB_SIS301) tempcx |= 0x0800;
5426 else tempcx |= 0x0C00;
5427 }
5428
5429 tempbx = push1;
5430 temp = tempbx & 0x000F;
5431 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,temp); /* 0x0D vertical Retrace End */
5432
5433 if(tempbx & 0x0010) tempcx |= 0x2000;
5434
5435 temp = tempcx & 0x00FF;
5436 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp); /* 0x0A CR07 */
5437
5438 temp = (tempcx & 0xFF00) >> 8;
5439 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp); /* 0x17 SR0A */
5440
5441 tempax = modeflag;
5442 temp = (tempax & 0xFF00) >> 8;
5443 temp = (temp >> 1) & 0x09;
5444 if(!(SiS_Pr->SiS_VBType & VB_SIS301)) temp |= 0x01; /* Always 8 dotclock */
5445 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* 0x16 SR01 */
5446
5447 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,0x00); /* 0x0F CR14 */
5448
5449 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,0x00); /* 0x12 CR17 */
5450
5451 temp = 0x00;
5452 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5453 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
5454 temp = 0x80;
5455 }
5456 }
5457 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* 0x1A SR0E */
5458
5459 temp = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
5460 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);
5461 }
5462
5463 /* Setup panel link
5464 * This is used for LVDS, LCDA and Chrontel TV output
5465 * 300/LVDS+TV, 300/301B-DH, 315/LVDS+TV, 315/LCDA
5466 */
5467 static void
SiS_SetGroup1_LVDS(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,PSIS_HW_INFO HwInfo,USHORT RefreshRateTableIndex)5468 SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
5469 PSIS_HW_INFO HwInfo, USHORT RefreshRateTableIndex)
5470 {
5471 USHORT modeflag,resinfo;
5472 USHORT push2,tempax,tempbx,tempcx,temp;
5473 ULONG tempeax=0,tempebx,tempecx,tempvcfact=0;
5474 BOOLEAN islvds = FALSE, issis = FALSE, chkdclkfirst = FALSE;
5475 #ifdef SIS300
5476 USHORT crt2crtc;
5477 #endif
5478 #ifdef SIS315H
5479 USHORT pushcx;
5480 #endif
5481
5482 if(ModeNo <= 0x13) {
5483 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5484 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
5485 #ifdef SIS300
5486 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
5487 #endif
5488 } else if(SiS_Pr->UseCustomMode) {
5489 modeflag = SiS_Pr->CModeFlag;
5490 resinfo = 0;
5491 #ifdef SIS300
5492 crt2crtc = 0;
5493 #endif
5494 } else {
5495 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5496 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
5497 #ifdef SIS300
5498 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
5499 #endif
5500 }
5501
5502 /* is lvds if really LVDS, or SiS 301B-DH with external LVDS transmitter */
5503 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
5504 ((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBType & VB_NoLCD))) {
5505 islvds = TRUE;
5506 }
5507
5508 /* is really sis if sis bridge, but not 301B-DH */
5509 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
5510 issis = TRUE;
5511 }
5512
5513 if((HwInfo->jChipType >= SIS_315H) && (islvds) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA))) {
5514 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
5515 chkdclkfirst = TRUE;
5516 }
5517 }
5518
5519 #ifdef SIS315H
5520 if((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
5521 if(IS_SIS330) {
5522 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5523 } else if(IS_SIS740) {
5524 if(islvds) {
5525 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5526 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x03);
5527 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5528 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5529 }
5530 } else {
5531 if(islvds) {
5532 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5533 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x00);
5534 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5535 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2D,0x0f);
5536 if(SiS_Pr->SiS_VBType & VB_SIS301C) {
5537 if((SiS_Pr->SiS_LCDResInfo == Panel_1024x768) ||
5538 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
5539 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x20);
5540 }
5541 }
5542 }
5543 }
5544 }
5545 #endif
5546
5547 /* Horizontal */
5548
5549 tempax = SiS_Pr->SiS_LCDHDES;
5550 if(islvds) {
5551 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5552 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
5553 if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) &&
5554 (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
5555 tempax -= 8;
5556 }
5557 }
5558 }
5559 }
5560
5561 temp = (tempax & 0x0007);
5562 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* BPLHDESKEW[2:0] */
5563 temp = (tempax >> 3) & 0x00FF;
5564 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* BPLHDESKEW[10:3] */
5565
5566 tempbx = SiS_Pr->SiS_HDE;
5567 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5568 if((SiS_Pr->SiS_LCDResInfo == Panel_640x480_2) ||
5569 (SiS_Pr->SiS_LCDResInfo == Panel_640x480_3)) {
5570 tempbx >>= 1;
5571 }
5572 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5573 tempbx = SiS_Pr->PanelXRes;
5574 }
5575 }
5576
5577 tempax += tempbx;
5578 if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;
5579
5580 temp = tempax;
5581 if(temp & 0x07) temp += 8;
5582 temp >>= 3;
5583 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp); /* BPLHDEE */
5584
5585 tempcx = (SiS_Pr->SiS_HT - tempbx) >> 2;
5586
5587 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5588 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5589 if(SiS_Pr->PanelHRS != 999) tempcx = SiS_Pr->PanelHRS;
5590 }
5591 }
5592
5593 tempcx += tempax;
5594 if(tempcx >= SiS_Pr->SiS_HT) tempcx -= SiS_Pr->SiS_HT;
5595
5596 temp = (tempcx >> 3) & 0x00FF;
5597 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5598 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5599 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5600 switch(ModeNo) {
5601 case 0x04:
5602 case 0x05:
5603 case 0x0d: temp = 0x56; break;
5604 case 0x10: temp = 0x60; break;
5605 case 0x13: temp = 0x5f; break;
5606 case 0x40:
5607 case 0x41:
5608 case 0x4f:
5609 case 0x43:
5610 case 0x44:
5611 case 0x62:
5612 case 0x56:
5613 case 0x53:
5614 case 0x5d:
5615 case 0x5e: temp = 0x54; break;
5616 }
5617 }
5618 }
5619 }
5620 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,temp); /* BPLHRS */
5621
5622 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5623 temp += 2;
5624 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5625 temp += 8;
5626 if(SiS_Pr->PanelHRE != 999) {
5627 temp = tempcx + SiS_Pr->PanelHRE;
5628 if(temp >= SiS_Pr->SiS_HT) temp -= SiS_Pr->SiS_HT;
5629 temp >>= 3;
5630 }
5631 }
5632 } else {
5633 temp += 10;
5634 }
5635
5636 temp &= 0x1F;
5637 temp |= ((tempcx & 0x07) << 5);
5638 #if 0
5639 if(SiS_Pr->SiS_IF_DEF_FSTN) temp = 0x20; /* WRONG? BIOS loads cl, not ah */
5640 #endif
5641 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,temp); /* BPLHRE */
5642
5643 /* Vertical */
5644
5645 tempax = SiS_Pr->SiS_VGAVDE;
5646 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5647 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5648 tempax = SiS_Pr->PanelYRes;
5649 }
5650 }
5651
5652 tempbx = SiS_Pr->SiS_LCDVDES + tempax;
5653 if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5654
5655 push2 = tempbx;
5656
5657 tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE;
5658 if(HwInfo->jChipType < SIS_315H) {
5659 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5660 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5661 tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->PanelYRes;
5662 }
5663 }
5664 }
5665 if(islvds) tempcx >>= 1;
5666 else tempcx >>= 2;
5667
5668 if( (SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
5669 (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) &&
5670 (SiS_Pr->PanelVRS != 999) ) {
5671 tempcx = SiS_Pr->PanelVRS;
5672 tempbx += tempcx;
5673 if(issis) tempbx++;
5674 } else {
5675 tempbx += tempcx;
5676 if(HwInfo->jChipType < SIS_315H) tempbx++;
5677 else if(issis) tempbx++;
5678 }
5679
5680 if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT; /* BPLVRS */
5681
5682 temp = tempbx & 0x00FF;
5683 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5684 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5685 if(ModeNo == 0x10) temp = 0xa9;
5686 }
5687 }
5688 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);
5689
5690 tempcx >>= 3;
5691 tempcx++;
5692
5693 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5694 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5695 if(SiS_Pr->PanelVRE != 999) tempcx = SiS_Pr->PanelVRE;
5696 }
5697 }
5698
5699 tempcx += tempbx;
5700 temp = tempcx & 0x000F;
5701 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp); /* BPLVRE */
5702
5703 temp = ((tempbx >> 8) & 0x07) << 3;
5704 if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
5705 if(SiS_Pr->SiS_HDE != 640) {
5706 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
5707 }
5708 } else if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
5709 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) temp |= 0x40;
5710 tempbx = 0x87;
5711 if((HwInfo->jChipType >= SIS_315H) ||
5712 (HwInfo->jChipRevision >= 0x30)) {
5713 tempbx = 0x07;
5714 if((SiS_Pr->SiS_IF_DEF_CH70xx == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
5715 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x03) temp |= 0x80;
5716 }
5717 /* Chrontel 701x operates in 24bit mode (8-8-8, 2x12bit mutliplexed) via VGA2 */
5718 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5719 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5720 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x10) temp |= 0x80;
5721 } else {
5722 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80;
5723 }
5724 }
5725 }
5726 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,tempbx,temp);
5727
5728 tempbx = push2; /* BPLVDEE */
5729
5730 tempcx = SiS_Pr->SiS_LCDVDES; /* BPLVDES */
5731
5732 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5733 switch(SiS_Pr->SiS_LCDResInfo) {
5734 case Panel_640x480:
5735 tempbx = SiS_Pr->SiS_VGAVDE - 1;
5736 tempcx = SiS_Pr->SiS_VGAVDE;
5737 break;
5738 case Panel_800x600:
5739 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5740 if(resinfo == SIS_RI_800x600) tempcx++;
5741 }
5742 break;
5743 case Panel_1024x600:
5744 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5745 if(resinfo == SIS_RI_1024x600) tempcx++;
5746 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
5747 if(resinfo == SIS_RI_800x600) tempcx++;
5748 }
5749 }
5750 break;
5751 case Panel_1024x768:
5752 if(HwInfo->jChipType < SIS_315H) {
5753 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5754 if(resinfo == SIS_RI_1024x768) tempcx++;
5755 }
5756 }
5757 break;
5758 }
5759 }
5760
5761 temp = ((tempbx >> 8) & 0x07) << 3;
5762 temp = temp | ((tempcx >> 8) & 0x07);
5763 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1D,temp);
5764 /* if(SiS_Pr->SiS_IF_DEF_FSTN) tempbx++; */
5765 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1C,tempbx);
5766 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1B,tempcx);
5767
5768 /* Vertical scaling */
5769
5770 if(HwInfo->jChipType < SIS_315H) {
5771
5772 #ifdef SIS300 /* 300 series */
5773 tempeax = SiS_Pr->SiS_VGAVDE << 6;
5774 temp = (tempeax % (ULONG)SiS_Pr->SiS_VDE);
5775 tempeax = tempeax / (ULONG)SiS_Pr->SiS_VDE;
5776 if(temp) tempeax++;
5777
5778 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) tempeax = 0x3F;
5779
5780 temp = (USHORT)(tempeax & 0x00FF);
5781 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,temp); /* BPLVCFACT */
5782 tempvcfact = temp;
5783 #endif /* SIS300 */
5784
5785 } else {
5786
5787 #ifdef SIS315H /* 315 series */
5788 tempeax = SiS_Pr->SiS_VGAVDE << 18;
5789 tempebx = SiS_Pr->SiS_VDE;
5790 temp = (tempeax % tempebx);
5791 tempeax = tempeax / tempebx;
5792 if(temp) tempeax++;
5793 tempvcfact = tempeax;
5794
5795 temp = (USHORT)(tempeax & 0x00FF);
5796 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,temp);
5797 temp = (USHORT)((tempeax & 0x00FF00) >> 8);
5798 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,temp);
5799 temp = (USHORT)((tempeax & 0x00030000) >> 16);
5800 if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
5801 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,temp);
5802
5803 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV)) {
5804 temp = (USHORT)(tempeax & 0x00FF);
5805 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3c,temp);
5806 temp = (USHORT)((tempeax & 0x00FF00) >> 8);
5807 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3b,temp);
5808 temp = (USHORT)(((tempeax & 0x00030000) >> 16) << 6);
5809 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0x3f,temp);
5810 temp = 0;
5811 if(SiS_Pr->SiS_VDE != SiS_Pr->SiS_VGAVDE) temp |= 0x08;
5812 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x30,0xf3,temp);
5813 }
5814 #endif
5815
5816 }
5817
5818 /* Horizontal scaling */
5819
5820 tempeax = SiS_Pr->SiS_VGAHDE; /* 1f = ( (VGAHDE * 65536) / ( (VGAHDE * 65536) / HDE ) ) - 1*/
5821 if(chkdclkfirst) {
5822 if(modeflag & HalfDCLK) tempeax >>= 1;
5823 }
5824 tempebx = tempeax << 16;
5825 if(SiS_Pr->SiS_HDE == tempeax) {
5826 tempecx = 0xFFFF;
5827 } else {
5828 tempecx = tempebx / SiS_Pr->SiS_HDE;
5829 if(HwInfo->jChipType >= SIS_315H) {
5830 if(tempebx % SiS_Pr->SiS_HDE) tempecx++;
5831 }
5832 }
5833
5834 if(HwInfo->jChipType >= SIS_315H) {
5835 tempeax = (tempebx / tempecx) - 1;
5836 } else {
5837 tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1;
5838 }
5839 tempecx = (tempecx << 16) | (tempeax & 0xFFFF);
5840 temp = (USHORT)(tempecx & 0x00FF);
5841 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1F,temp);
5842
5843 if(HwInfo->jChipType >= SIS_315H) {
5844 tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
5845 tempbx = (USHORT)(tempeax & 0xFFFF);
5846 } else {
5847 tempeax = SiS_Pr->SiS_VGAVDE << 6;
5848 tempbx = tempvcfact & 0x3f;
5849 if(tempbx == 0) tempbx = 64;
5850 tempeax /= tempbx;
5851 tempbx = (USHORT)(tempeax & 0xFFFF);
5852 }
5853 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tempbx--;
5854 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
5855 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) tempbx = 1;
5856 else if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) tempbx = 1;
5857 }
5858
5859 temp = ((tempbx >> 8) & 0x07) << 3;
5860 temp = temp | ((tempecx >> 8) & 0x07);
5861 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x20,temp);
5862 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x21,tempbx);
5863
5864 tempecx >>= 16; /* BPLHCFACT */
5865 if(!chkdclkfirst) {
5866 if(modeflag & HalfDCLK) tempecx >>= 1;
5867 }
5868 temp = (USHORT)((tempecx & 0xFF00) >> 8);
5869 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x22,temp);
5870 temp = (USHORT)(tempecx & 0x00FF);
5871 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp);
5872
5873 #ifdef SIS315H
5874 if(HwInfo->jChipType >= SIS_315H) {
5875 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5876 if((islvds) || (SiS_Pr->SiS_VBInfo & VB_SIS301LV302LV)) {
5877 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x20);
5878 }
5879 } else {
5880 if(islvds) {
5881 if(HwInfo->jChipType == SIS_740) {
5882 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
5883 } else {
5884 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x23);
5885 }
5886 }
5887 }
5888 }
5889 #endif
5890
5891 #ifdef SIS300
5892 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5893 int i;
5894 UCHAR TrumpMode13[4] = { 0x01, 0x10, 0x2c, 0x00 };
5895 UCHAR TrumpMode10_1[4] = { 0x01, 0x10, 0x27, 0x00 };
5896 UCHAR TrumpMode10_2[4] = { 0x01, 0x16, 0x10, 0x00 };
5897
5898 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xbf);
5899 for(i=0; i<5; i++) {
5900 SiS_SetTrumpionBlock(SiS_Pr, &SiS300_TrumpionData[crt2crtc][0]);
5901 }
5902 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5903 if(ModeNo == 0x13) {
5904 for(i=0; i<4; i++) {
5905 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode13[0]);
5906 }
5907 } else if(ModeNo == 0x10) {
5908 for(i=0; i<4; i++) {
5909 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_1[0]);
5910 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_2[0]);
5911 }
5912 }
5913 }
5914 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
5915 }
5916 #endif
5917
5918 #ifdef SIS315H
5919 if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
5920 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x25,0x00);
5921 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x26,0x00);
5922 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x27,0x00);
5923 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x28,0x87);
5924 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x29,0x5A);
5925 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2A,0x4B);
5926 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x07,0x03);
5927 tempax = SiS_Pr->SiS_HDE; /* Blps = lcdhdee(lcdhdes+HDE) + 64 */
5928 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
5929 SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1;
5930 tempax += 64;
5931 temp = tempax & 0x00FF;
5932 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,temp);
5933 temp = ((tempax & 0xFF00) >> 8) << 3;
5934 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp);
5935 tempax += 32; /* Blpe=lBlps+32 */
5936 temp = tempax & 0x00FF;
5937 if(SiS_Pr->SiS_IF_DEF_FSTN) temp = 0;
5938 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,temp);
5939 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3A,0x00); /* Bflml=0 */
5940 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x007,0x00);
5941
5942 tempax = SiS_Pr->SiS_VDE;
5943 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
5944 SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1;
5945 tempax >>= 1;
5946 temp = tempax & 0x00FF;
5947 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3B,temp);
5948 temp = ((tempax & 0xFF00) >> 8) << 3;
5949 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);
5950
5951 tempeax = SiS_Pr->SiS_HDE;
5952 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
5953 SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempeax >>= 1;
5954 tempeax <<= 2; /* BDxFIFOSTOP = (HDE*4)/128 */
5955 tempebx = 128;
5956 temp = (USHORT)(tempeax % tempebx);
5957 tempeax = tempeax / tempebx;
5958 if(temp) tempeax++;
5959 temp = (USHORT)(tempeax & 0x003F);
5960 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x45,~0x0FF,temp);
5961 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3F,0x00); /* BDxWadrst0 */
5962 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3E,0x00);
5963 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3D,0x10);
5964 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x040,0x00);
5965
5966 tempax = SiS_Pr->SiS_HDE;
5967 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
5968 SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1;
5969 tempax >>= 4; /* BDxWadroff = HDE*4/8/8 */
5970 pushcx = tempax;
5971 temp = tempax & 0x00FF;
5972 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,temp);
5973 temp = ((tempax & 0xFF00) >> 8) << 3;
5974 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x0F8,temp);
5975
5976 tempax = SiS_Pr->SiS_VDE; /* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
5977 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
5978 SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1;
5979 tempeax = (tempax * pushcx);
5980 tempebx = 0x00100000 + tempeax;
5981 temp = (USHORT)tempebx & 0x000000FF;
5982 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,temp);
5983 temp = (USHORT)((tempebx & 0x0000FF00) >> 8);
5984 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,temp);
5985 temp = (USHORT)((tempebx & 0x00FF0000) >> 16);
5986 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,temp);
5987 temp = (USHORT)(((tempebx & 0x01000000) >> 24) << 7);
5988 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x080,temp);
5989
5990 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x03);
5991 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0x50);
5992 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,0x00);
5993 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x01);
5994 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0x38);
5995
5996 if(SiS_Pr->SiS_IF_DEF_FSTN) {
5997 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2b,0x02);
5998 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2c,0x00);
5999 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x00);
6000 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,0x0c);
6001 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,0x00);
6002 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,0x00);
6003 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,0x80);
6004 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,0xA0);
6005 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3a,0x00);
6006 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3b,0xf0);
6007 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3c,0x00);
6008 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3d,0x10);
6009 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3e,0x00);
6010 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3f,0x00);
6011 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,0x10);
6012 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,0x25);
6013 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,0x80);
6014 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,0x14);
6015 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x44,0x03);
6016 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,0x0a);
6017 }
6018 }
6019 #endif /* SIS315H */
6020 }
6021
6022 /* Set Part 1 */
6023 static void
SiS_SetGroup1(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,PSIS_HW_INFO HwInfo,USHORT RefreshRateTableIndex)6024 SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
6025 PSIS_HW_INFO HwInfo, USHORT RefreshRateTableIndex)
6026 {
6027 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
6028 USHORT temp=0, tempax=0, tempbx=0, tempcx=0, bridgeadd=0;
6029 USHORT pushbx=0, CRT1Index=0, modeflag, resinfo=0;
6030 #ifdef SIS315H
6031 USHORT tempbl=0;
6032 #endif
6033
6034 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
6035 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
6036 return;
6037 }
6038
6039 if(ModeNo <= 0x13) {
6040 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6041 } else if(SiS_Pr->UseCustomMode) {
6042 modeflag = SiS_Pr->CModeFlag;
6043 } else {
6044 CRT1Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
6045 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
6046 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6047 }
6048
6049 SiS_SetCRT2Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
6050
6051 if( ! ((HwInfo->jChipType >= SIS_315H) &&
6052 (SiS_Pr->SiS_IF_DEF_LVDS == 1) &&
6053 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
6054
6055 if(HwInfo->jChipType < SIS_315H ) {
6056 #ifdef SIS300
6057 SiS_SetCRT2FIFO_300(SiS_Pr, ModeNo, HwInfo);
6058 #endif
6059 } else {
6060 #ifdef SIS315H
6061 SiS_SetCRT2FIFO_310(SiS_Pr, HwInfo);
6062 #endif
6063 }
6064
6065 /* 1. Horizontal setup */
6066
6067 if(HwInfo->jChipType < SIS_315H ) {
6068
6069 #ifdef SIS300 /* ------------- 300 series --------------*/
6070
6071 temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
6072 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp); /* CRT2 Horizontal Total */
6073
6074 temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
6075 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp); /* CRT2 Horizontal Total Overflow [7:4] */
6076
6077 temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */
6078 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp); /* CRT2 Horizontal Display Enable End */
6079
6080 pushbx = SiS_Pr->SiS_VGAHDE + 12; /* bx BTVGA2HRS 0x0B,0x0C */
6081 tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2;
6082 tempbx = pushbx + tempcx;
6083 tempcx <<= 1;
6084 tempcx += tempbx;
6085
6086 bridgeadd = 12;
6087
6088 #endif /* SIS300 */
6089
6090 } else {
6091
6092 #ifdef SIS315H /* ------------------- 315/330 series --------------- */
6093
6094 tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HT 0x08,0x09 */
6095 if(modeflag & HalfDCLK) {
6096 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6097 tempcx >>= 1;
6098 } else {
6099 tempax = SiS_Pr->SiS_VGAHDE >> 1;
6100 tempcx = SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE + tempax;
6101 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
6102 tempcx = SiS_Pr->SiS_HT - tempax;
6103 }
6104 }
6105 }
6106 tempcx--;
6107 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,tempcx); /* CRT2 Horizontal Total */
6108 temp = (tempcx >> 4) & 0xF0;
6109 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp); /* CRT2 Horizontal Total Overflow [7:4] */
6110
6111 tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HDEE 0x0A,0x0C */
6112 tempbx = SiS_Pr->SiS_VGAHDE;
6113 tempcx -= tempbx;
6114 tempcx >>= 2;
6115 if(modeflag & HalfDCLK) {
6116 tempbx >>= 1;
6117 tempcx >>= 1;
6118 }
6119 tempbx += 16;
6120
6121 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,tempbx); /* CRT2 Horizontal Display Enable End */
6122
6123 pushbx = tempbx;
6124 tempcx >>= 1;
6125 tempbx += tempcx;
6126 tempcx += tempbx;
6127
6128 bridgeadd = 16;
6129
6130 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6131 if(HwInfo->jChipType >= SIS_661) {
6132 if((SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
6133 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
6134 if(resinfo == SIS_RI_1280x1024) {
6135 tempcx = (tempcx & 0xff00) | 0x30;
6136 } else if(resinfo == SIS_RI_1600x1200) {
6137 tempcx = (tempcx & 0xff00) | 0xff;
6138 }
6139 }
6140 }
6141 }
6142
6143 #endif /* SIS315H */
6144
6145 } /* 315/330 series */
6146
6147 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6148
6149 if(SiS_Pr->UseCustomMode) {
6150 tempbx = SiS_Pr->CHSyncStart + bridgeadd;
6151 tempcx = SiS_Pr->CHSyncEnd + bridgeadd;
6152 tempax = SiS_Pr->SiS_VGAHT;
6153 if(modeflag & HalfDCLK) tempax >>= 1;
6154 tempax--;
6155 if(tempcx > tempax) tempcx = tempax;
6156 }
6157
6158 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6159 unsigned char cr4, cr14, cr5, cr15;
6160 if(SiS_Pr->UseCustomMode) {
6161 cr4 = SiS_Pr->CCRT1CRTC[4];
6162 cr14 = SiS_Pr->CCRT1CRTC[14];
6163 cr5 = SiS_Pr->CCRT1CRTC[5];
6164 cr15 = SiS_Pr->CCRT1CRTC[15];
6165 } else {
6166 cr4 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
6167 cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
6168 cr5 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
6169 cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
6170 }
6171 tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3; /* (VGAHRS-3)*8 */
6172 tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3; /* (VGAHRE-3)*8 */
6173 tempcx &= 0x00FF;
6174 tempcx |= (tempbx & 0xFF00);
6175 tempbx += bridgeadd;
6176 tempcx += bridgeadd;
6177 tempax = SiS_Pr->SiS_VGAHT;
6178 if(modeflag & HalfDCLK) tempax >>= 1;
6179 tempax--;
6180 if(tempcx > tempax) tempcx = tempax;
6181 }
6182
6183 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6184 tempbx = 1040;
6185 tempcx = 1044; /* HWCursor bug! */
6186 }
6187
6188 }
6189
6190 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,tempbx); /* CRT2 Horizontal Retrace Start */
6191
6192 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,tempcx); /* CRT2 Horizontal Retrace End */
6193
6194 temp = ((tempbx >> 8) & 0x0F) | ((pushbx >> 4) & 0xF0);
6195 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp); /* Overflow */
6196
6197 /* 2. Vertical setup */
6198
6199 tempcx = SiS_Pr->SiS_VGAVT - 1;
6200 temp = tempcx & 0x00FF;
6201
6202 if(HwInfo->jChipType < SIS_661) {
6203 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6204 if(HwInfo->jChipType < SIS_315H) {
6205 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6206 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
6207 temp--;
6208 }
6209 }
6210 } else {
6211 temp--;
6212 }
6213 } else if(HwInfo->jChipType >= SIS_315H) {
6214 temp--;
6215 }
6216 }
6217 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp); /* CRT2 Vertical Total */
6218
6219 tempbx = SiS_Pr->SiS_VGAVDE - 1;
6220 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,tempbx); /* CRT2 Vertical Display Enable End */
6221
6222 temp = ((tempbx >> 5) & 0x38) | ((tempcx >> 8) & 0x07);
6223 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,temp); /* Overflow */
6224
6225 if((HwInfo->jChipType >= SIS_315H) && (HwInfo->jChipType < SIS_661)) {
6226 tempbx++;
6227 tempax = tempbx;
6228 tempcx++;
6229 tempcx -= tempax;
6230 tempcx >>= 2;
6231 tempbx += tempcx;
6232 if(tempcx < 4) tempcx = 4;
6233 tempcx >>= 2;
6234 tempcx += tempbx;
6235 tempcx++;
6236 } else {
6237 tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1; /* BTVGA2VRS 0x10,0x11 */
6238 tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1; /* BTVGA2VRE 0x11 */
6239 }
6240
6241 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6242 if(SiS_Pr->UseCustomMode) {
6243 tempbx = SiS_Pr->CVSyncStart;
6244 tempcx = SiS_Pr->CVSyncEnd;
6245 }
6246 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6247 unsigned char cr8, cr7, cr13;
6248 if(SiS_Pr->UseCustomMode) {
6249 cr8 = SiS_Pr->CCRT1CRTC[8];
6250 cr7 = SiS_Pr->CCRT1CRTC[7];
6251 cr13 = SiS_Pr->CCRT1CRTC[13];
6252 tempcx = SiS_Pr->CCRT1CRTC[9];
6253 } else {
6254 cr8 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8];
6255 cr7 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
6256 cr13 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
6257 tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
6258 }
6259 tempbx = cr8;
6260 if(cr7 & 0x04) tempbx |= 0x0100;
6261 if(cr7 & 0x80) tempbx |= 0x0200;
6262 if(cr13 & 0x08) tempbx |= 0x0400;
6263 }
6264 }
6265 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,tempbx); /* CRT2 Vertical Retrace Start */
6266
6267 temp = ((tempbx >> 4) & 0x70) | (tempcx & 0x0F);
6268 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,temp); /* CRT2 Vert. Retrace End; Overflow */
6269
6270 /* 3. Panel delay compensation */
6271
6272 if(HwInfo->jChipType < SIS_315H) {
6273
6274 #ifdef SIS300 /* ---------- 300 series -------------- */
6275
6276 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6277 temp = 0x20;
6278 if(HwInfo->jChipType == SIS_300) {
6279 temp = 0x10;
6280 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) temp = 0x2c;
6281 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6282 }
6283 if(SiS_Pr->SiS_VBType & VB_SIS301) {
6284 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6285 }
6286 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960) temp = 0x24;
6287 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) temp = 0x2c;
6288 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x08;
6289 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6290 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) temp = 0x2c;
6291 else temp = 0x20;
6292 }
6293 if(SiS_Pr->SiS_UseROM) {
6294 if(ROMAddr[0x220] & 0x80) {
6295 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision)
6296 temp = ROMAddr[0x221];
6297 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)
6298 temp = ROMAddr[0x222];
6299 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)
6300 temp = ROMAddr[0x223];
6301 else
6302 temp = ROMAddr[0x224];
6303 temp &= 0x3c;
6304 }
6305 }
6306 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6307 if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC & 0x3c;
6308 }
6309
6310 } else {
6311 temp = 0x20;
6312 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
6313 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) temp = 0x04;
6314 }
6315 if(SiS_Pr->SiS_UseROM) {
6316 if(ROMAddr[0x220] & 0x80) {
6317 temp = ROMAddr[0x220] & 0x3c;
6318 }
6319 }
6320 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6321 if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC & 0x3c;
6322 }
6323 }
6324
6325 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
6326
6327 #endif /* SIS300 */
6328
6329 } else {
6330
6331 #ifdef SIS315H /* --------------- 315/330 series ---------------*/
6332
6333 if(HwInfo->jChipType < SIS_661) {
6334
6335 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6336
6337 if(HwInfo->jChipType == SIS_740) temp = 0x03;
6338 else temp = 0x00;
6339
6340 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x0a;
6341 tempbl = 0xF0;
6342 if(HwInfo->jChipType == SIS_650) {
6343 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6344 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F;
6345 }
6346 }
6347
6348 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) {
6349 temp = 0x08;
6350 tempbl = 0;
6351 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
6352 if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0;
6353 }
6354 }
6355
6356 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp); /* Panel Link Delay Compensation */
6357 }
6358
6359 } /* < 661 */
6360
6361 tempax = 0;
6362 if(modeflag & DoubleScanMode) tempax |= 0x80;
6363 if(modeflag & HalfDCLK) tempax |= 0x40;
6364 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax);
6365
6366 #endif /* SIS315H */
6367
6368 }
6369
6370 } /* Slavemode */
6371
6372 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6373 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
6374 /* For 301BDH with LCD, we set up the Panel Link */
6375 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
6376 } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6377 SiS_SetGroup1_301(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
6378 }
6379 } else {
6380 if(HwInfo->jChipType < SIS_315H) {
6381 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
6382 } else {
6383 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6384 if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
6385 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex, HwInfo,RefreshRateTableIndex);
6386 }
6387 } else {
6388 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex, HwInfo,RefreshRateTableIndex);
6389 }
6390 }
6391 }
6392 }
6393
6394 /*********************************************/
6395 /* SET PART 2 REGISTER GROUP */
6396 /*********************************************/
6397
6398 #ifdef SIS315H
6399 static UCHAR *
SiS_GetGroup2CLVXPtr(SiS_Private * SiS_Pr,int tabletype,PSIS_HW_INFO HwInfo)6400 SiS_GetGroup2CLVXPtr(SiS_Private *SiS_Pr, int tabletype, PSIS_HW_INFO HwInfo)
6401 {
6402 const UCHAR *tableptr = NULL;
6403 USHORT a, b, p = 0;
6404
6405 a = SiS_Pr->SiS_VGAHDE;
6406 b = SiS_Pr->SiS_HDE;
6407 if(tabletype) {
6408 a = SiS_Pr->SiS_VGAVDE;
6409 b = SiS_Pr->SiS_VDE;
6410 }
6411
6412 if(a < b) {
6413 tableptr = SiS_Part2CLVX_1;
6414 } else if(a == b) {
6415 tableptr = SiS_Part2CLVX_2;
6416 } else {
6417 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6418 tableptr = SiS_Part2CLVX_4;
6419 } else {
6420 tableptr = SiS_Part2CLVX_3;
6421 }
6422 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6423 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) tableptr = SiS_Part2CLVX_3;
6424 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tableptr = SiS_Part2CLVX_3;
6425 else tableptr = SiS_Part2CLVX_5;
6426 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6427 tableptr = SiS_Part2CLVX_6;
6428 }
6429 do {
6430 if((tableptr[p] | tableptr[p+1] << 8) == a) break;
6431 p += 0x42;
6432 } while((tableptr[p] | tableptr[p+1] << 8) != 0xffff);
6433 if((tableptr[p] | tableptr[p+1] << 8) == 0xffff) p -= 0x42;
6434 }
6435 p += 2;
6436 return((UCHAR *)&tableptr[p]);
6437 }
6438
6439 static void
SiS_SetGroup2_C_ELV(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo)6440 SiS_SetGroup2_C_ELV(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
6441 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
6442 {
6443 UCHAR *tableptr;
6444 int i, j;
6445 UCHAR temp;
6446
6447 if(!(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV))) return;
6448
6449 tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 0, HwInfo);
6450 for(i = 0x80, j = 0; i <= 0xbf; i++, j++) {
6451 SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6452 }
6453 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6454 tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 1, HwInfo);
6455 for(i = 0xc0, j = 0; i <= 0xff; i++, j++) {
6456 SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6457 }
6458 }
6459 temp = 0x10;
6460 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp |= 0x04;
6461 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xeb,temp);
6462 }
6463
6464 static BOOLEAN
SiS_GetCRT2Part2Ptr(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,USHORT * CRT2Index,USHORT * ResIndex,PSIS_HW_INFO HwInfo)6465 SiS_GetCRT2Part2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
6466 USHORT RefreshRateTableIndex,USHORT *CRT2Index,
6467 USHORT *ResIndex,PSIS_HW_INFO HwInfo)
6468 {
6469
6470 if(HwInfo->jChipType < SIS_315H) return FALSE;
6471
6472 if(ModeNo <= 0x13)
6473 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6474 else
6475 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6476
6477 (*ResIndex) &= 0x3f;
6478 (*CRT2Index) = 0;
6479
6480 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6481 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6482 (*CRT2Index) = 200;
6483 }
6484 }
6485
6486 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
6487 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6488 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) (*CRT2Index) = 206;
6489 }
6490 }
6491 return(((*CRT2Index) != 0));
6492 }
6493 #endif
6494
6495 #ifdef SIS300
6496 static void
SiS_Group2LCDSpecial(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,USHORT ModeNo,USHORT crt2crtc)6497 SiS_Group2LCDSpecial(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo, USHORT crt2crtc)
6498 {
6499 USHORT tempcx;
6500 const UCHAR atable[] = {
6501 0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,
6502 0xab,0x87,0xab,0x9e,0xe7,0x02,0x02
6503 };
6504
6505 if(!SiS_Pr->UseCustomMode) {
6506 if( ( ( (HwInfo->jChipType == SIS_630) ||
6507 (HwInfo->jChipType == SIS_730) ) &&
6508 (HwInfo->jChipRevision > 2) ) &&
6509 (SiS_Pr->SiS_LCDResInfo == Panel_1024x768) &&
6510 (!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) &&
6511 (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
6512 if(ModeNo == 0x13) {
6513 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xB9);
6514 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0xCC);
6515 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xA6);
6516 } else {
6517 if((crt2crtc & 0x3F) == 4) {
6518 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x2B);
6519 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x13);
6520 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xE5);
6521 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0x08);
6522 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xE2);
6523 }
6524 }
6525 }
6526
6527 if(HwInfo->jChipType < SIS_315H) {
6528 if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
6529 crt2crtc &= 0x1f;
6530 tempcx = 0;
6531 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6532 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6533 tempcx += 7;
6534 }
6535 }
6536 tempcx += crt2crtc;
6537 if(crt2crtc >= 4) {
6538 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xff);
6539 }
6540
6541 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6542 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6543 if(crt2crtc == 4) {
6544 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x28);
6545 }
6546 }
6547 }
6548 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x18);
6549 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
6550 }
6551 }
6552 }
6553 }
6554
6555 /* For ECS A907. Highly preliminary. */
6556 static void
SiS_Set300Part2Regs(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,USHORT ModeNo)6557 SiS_Set300Part2Regs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
6558 USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
6559 USHORT ModeNo)
6560 {
6561 USHORT crt2crtc, resindex;
6562 int i,j;
6563 const SiS_Part2PortTblStruct *CRT2Part2Ptr = NULL;
6564
6565 if(HwInfo->jChipType != SIS_300) return;
6566 if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) return;
6567 if(SiS_Pr->UseCustomMode) return;
6568
6569 if(ModeNo <= 0x13) {
6570 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6571 } else {
6572 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6573 }
6574
6575 resindex = crt2crtc & 0x3F;
6576 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6577 else CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2;
6578
6579 /* The BIOS code (1.16.51,56) is obviously a fragment! */
6580 if(ModeNo > 0x13) {
6581 CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6582 resindex = 4;
6583 }
6584
6585 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
6586 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
6587 for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
6588 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6589 }
6590 for(j = 0x1c; j <= 0x1d; i++, j++ ) {
6591 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6592 }
6593 for(j = 0x1f; j <= 0x21; i++, j++ ) {
6594 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6595 }
6596 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
6597 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
6598 }
6599 #endif
6600
6601 static void
SiS_SetTVSpecial(SiS_Private * SiS_Pr,USHORT ModeNo)6602 SiS_SetTVSpecial(SiS_Private *SiS_Pr, USHORT ModeNo)
6603 {
6604 if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) return;
6605 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) return;
6606 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) return;
6607
6608 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
6609 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6610 const UCHAR specialtv[] = {
6611 0xa7,0x07,0xf2,0x6e,0x17,0x8b,0x73,0x53,
6612 0x13,0x40,0x34,0xf4,0x63,0xbb,0xcc,0x7a,
6613 0x58,0xe4,0x73,0xda,0x13
6614 };
6615 int i, j;
6616 for(i = 0x1c, j = 0; i <= 0x30; i++, j++) {
6617 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,specialtv[j]);
6618 }
6619 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,0x72);
6620 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750)) {
6621 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6622 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14);
6623 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1b);
6624 } else {
6625 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14); /* 15 */
6626 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1a); /* 1b */
6627 }
6628 }
6629 }
6630 } else {
6631 if((ModeNo == 0x38) || (ModeNo == 0x4a) || (ModeNo == 0x64) ||
6632 (ModeNo == 0x52) || (ModeNo == 0x58) || (ModeNo == 0x5c)) {
6633 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b); /* 21 */
6634 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54); /* 5a */
6635 } else {
6636 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1a); /* 21 */
6637 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x53); /* 5a */
6638 }
6639 }
6640 }
6641
6642 static void
SiS_SetGroup2_Tail(SiS_Private * SiS_Pr,USHORT ModeNo)6643 SiS_SetGroup2_Tail(SiS_Private *SiS_Pr, USHORT ModeNo)
6644 {
6645 USHORT temp;
6646
6647 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6648 if(SiS_Pr->SiS_VGAVDE == 525) {
6649 temp = 0xc3;
6650 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6651 temp++;
6652 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp += 2;
6653 }
6654 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6655 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xb3);
6656 } else if(SiS_Pr->SiS_VGAVDE == 420) {
6657 temp = 0x4d;
6658 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6659 temp++;
6660 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp++;
6661 }
6662 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6663 }
6664 }
6665
6666 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6667 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
6668 if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
6669 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x1a,0x03);
6670 /* Not always for LV, see SetGrp2 */
6671 }
6672 temp = 1;
6673 if(ModeNo <= 0x13) temp = 3;
6674 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0b,temp);
6675 }
6676 #if 0
6677 /* 651+301C, for 1280x768 - do I really need that? */
6678 if((SiS_Pr->SiS_PanelXRes == 1280) && (SiS_Pr->SiS_PanelYRes == 768)) {
6679 if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) {
6680 if(((SiS_Pr->SiS_HDE == 640) && (SiS_Pr->SiS_VDE == 480)) ||
6681 ((SiS_Pr->SiS_HDE == 320) && (SiS_Pr->SiS_VDE == 240))) {
6682 SiS_SetReg(SiS_Part2Port,0x01,0x2b);
6683 SiS_SetReg(SiS_Part2Port,0x02,0x13);
6684 SiS_SetReg(SiS_Part2Port,0x04,0xe5);
6685 SiS_SetReg(SiS_Part2Port,0x05,0x08);
6686 SiS_SetReg(SiS_Part2Port,0x06,0xe2);
6687 SiS_SetReg(SiS_Part2Port,0x1c,0x21);
6688 SiS_SetReg(SiS_Part2Port,0x1d,0x45);
6689 SiS_SetReg(SiS_Part2Port,0x1f,0x0b);
6690 SiS_SetReg(SiS_Part2Port,0x20,0x00);
6691 SiS_SetReg(SiS_Part2Port,0x21,0xa9);
6692 SiS_SetReg(SiS_Part2Port,0x23,0x0b);
6693 SiS_SetReg(SiS_Part2Port,0x25,0x04);
6694 }
6695 }
6696 }
6697 #endif
6698 }
6699 }
6700
6701 static void
SiS_SetGroup2(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo)6702 SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
6703 PSIS_HW_INFO HwInfo)
6704 {
6705 USHORT i, j, tempax, tempbx, tempcx, tempch, tempcl, temp;
6706 USHORT push2, modeflag, crt2crtc, bridgeoffset;
6707 ULONG longtemp;
6708 const UCHAR *PhasePoint;
6709 const UCHAR *TimingPoint;
6710 #ifdef SIS315H
6711 USHORT resindex, CRT2Index;
6712 const SiS_Part2PortTblStruct *CRT2Part2Ptr = NULL;
6713
6714 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
6715 #endif
6716
6717 if(ModeNo <= 0x13) {
6718 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6719 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6720 } else if(SiS_Pr->UseCustomMode) {
6721 modeflag = SiS_Pr->CModeFlag;
6722 crt2crtc = 0;
6723 } else {
6724 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6725 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6726 }
6727
6728 temp = 0;
6729 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO)) temp |= 0x08;
6730 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO)) temp |= 0x04;
6731 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) temp |= 0x02;
6732 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp |= 0x01;
6733
6734 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) temp |= 0x10;
6735
6736 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x00,temp);
6737
6738 PhasePoint = SiS_Pr->SiS_PALPhase;
6739 TimingPoint = SiS_Pr->SiS_PALTiming;
6740
6741 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6742
6743 TimingPoint = SiS_Pr->SiS_HiTVExtTiming;
6744 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6745 TimingPoint = SiS_Pr->SiS_HiTVSt2Timing;
6746 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
6747 TimingPoint = SiS_Pr->SiS_HiTVSt1Timing;
6748 #if 0
6749 if(!(modeflag & Charx8Dot)) TimingPoint = SiS_Pr->SiS_HiTVTextTiming;
6750 #endif
6751 }
6752 }
6753
6754 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6755
6756 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) TimingPoint = &SiS_YPbPrTable[2][0];
6757 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) TimingPoint = &SiS_YPbPrTable[1][0];
6758 else TimingPoint = &SiS_YPbPrTable[0][0];
6759
6760 PhasePoint = SiS_Pr->SiS_NTSCPhase;
6761
6762 } else if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6763
6764 if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
6765 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6766 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6767 PhasePoint = SiS_Pr->SiS_PALPhase2;
6768 }
6769
6770 } else {
6771
6772 TimingPoint = SiS_Pr->SiS_NTSCTiming;
6773 PhasePoint = SiS_Pr->SiS_NTSCPhase;
6774 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
6775 PhasePoint = SiS_Pr->SiS_PALPhase;
6776 }
6777
6778 if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
6779 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6780 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6781 PhasePoint = SiS_Pr->SiS_NTSCPhase2;
6782 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
6783 PhasePoint = SiS_Pr->SiS_PALPhase2;
6784 }
6785 }
6786
6787 }
6788
6789 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6790 PhasePoint = SiS_Pr->SiS_PALMPhase;
6791 if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
6792 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6793 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6794 PhasePoint = SiS_Pr->SiS_PALMPhase2;
6795 }
6796 }
6797
6798 if(SiS_Pr->SiS_TVMode & TVSetPALN) {
6799 PhasePoint = SiS_Pr->SiS_PALNPhase;
6800 if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
6801 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6802 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6803 PhasePoint = SiS_Pr->SiS_PALNPhase2;
6804 }
6805 }
6806
6807 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6808 PhasePoint = SiS_Pr->SiS_SpecialPhase;
6809 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6810 PhasePoint = SiS_Pr->SiS_SpecialPhaseM;
6811 } else if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
6812 PhasePoint = SiS_Pr->SiS_SpecialPhaseJ;
6813 }
6814 }
6815
6816 for(i=0x31, j=0; i<=0x34; i++, j++) {
6817 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,PhasePoint[j]);
6818 }
6819
6820 for(i=0x01, j=0; i<=0x2D; i++, j++) {
6821 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
6822 }
6823 for(i=0x39; i<=0x45; i++, j++) {
6824 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
6825 }
6826
6827 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6828 if(SiS_Pr->SiS_ModeType != ModeText) {
6829 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
6830 }
6831 }
6832
6833 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x0A,SiS_Pr->SiS_NewFlickerMode);
6834
6835 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x35,SiS_Pr->SiS_RY1COE);
6836 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x36,SiS_Pr->SiS_RY2COE);
6837 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x37,SiS_Pr->SiS_RY3COE);
6838 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x38,SiS_Pr->SiS_RY4COE);
6839
6840 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempax = 950;
6841 else if(SiS_Pr->SiS_TVMode & TVSetPAL) tempax = 520;
6842 else tempax = 440; /* NTSC, YPbPr 525, 750 */
6843
6844 if( ( (!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) && (SiS_Pr->SiS_VDE <= tempax) ) ||
6845 ( (SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) &&
6846 ((SiS_Pr->SiS_VGAHDE == 1024) || (SiS_Pr->SiS_VDE <= tempax)) ) ) {
6847
6848 tempax -= SiS_Pr->SiS_VDE;
6849 tempax >>= 2;
6850 tempax &= 0x00ff;
6851
6852 temp = tempax + (USHORT)TimingPoint[0];
6853 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
6854
6855 temp = tempax + (USHORT)TimingPoint[1];
6856 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
6857
6858 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) && (SiS_Pr->SiS_VGAHDE >= 1024)) {
6859 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6860 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b); /* 19 */
6861 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54); /* 52 */
6862 } else {
6863 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x17);
6864 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1d);
6865 }
6866 }
6867
6868 }
6869
6870 tempcx = SiS_Pr->SiS_HT;
6871 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempcx >>= 1;
6872 tempcx--;
6873 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) tempcx--;
6874 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1B,tempcx);
6875 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0xF0,((tempcx >> 8) & 0x0f));
6876
6877 tempcx = SiS_Pr->SiS_HT >> 1;
6878 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempcx >>= 1;
6879 tempcx += 7;
6880 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
6881 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,((tempcx << 4) & 0xf0));
6882
6883 tempbx = TimingPoint[j] | (TimingPoint[j+1] << 8);
6884 tempbx += tempcx;
6885 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x24,tempbx);
6886 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0F,((tempbx >> 4) & 0xf0));
6887
6888 tempbx += 8;
6889 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6890 tempbx -= 4;
6891 tempcx = tempbx;
6892 }
6893 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x29,0x0F,((tempbx << 4) & 0xf0));
6894
6895 j += 2;
6896 tempcx += (TimingPoint[j] | (TimingPoint[j+1] << 8));
6897 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x27,tempcx);
6898 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x28,0x0F,((tempcx >> 4) & 0xf0));
6899
6900 tempcx += 8;
6901 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
6902 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2A,0x0F,((tempcx << 4) & 0xf0));
6903
6904 tempcx = SiS_Pr->SiS_HT >> 1;
6905 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempcx >>= 1;
6906 j += 2;
6907 tempcx -= (TimingPoint[j] | ((TimingPoint[j+1]) << 8));
6908 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2D,0x0F,((tempcx << 4) & 0xf0));
6909
6910 tempcx -= 11;
6911 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
6912 tempcx = SiS_GetVGAHT2(SiS_Pr) - 1;
6913 }
6914 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2E,tempcx);
6915
6916 tempbx = SiS_Pr->SiS_VDE;
6917 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6918 if(SiS_Pr->SiS_VGAVDE == 360) tempbx = 746;
6919 if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 746;
6920 if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 853;
6921 } else if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
6922 (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p))) ) {
6923 tempbx >>= 1;
6924 if(HwInfo->jChipType >= SIS_315H) {
6925 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
6926 if((ModeNo <= 0x13) && (crt2crtc == 1)) tempbx++;
6927 } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6928 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6929 if(crt2crtc == 4) tempbx++;
6930 }
6931 }
6932 }
6933 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6934 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6935 if((ModeNo == 0x2f) || (ModeNo == 0x5d) || (ModeNo == 0x5e)) tempbx++;
6936 }
6937 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
6938 if(ModeNo == 0x03) tempbx++; /* From 1.10.7w - doesn't make sense */
6939 }
6940 }
6941 }
6942 tempbx -= 2;
6943 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2F,tempbx);
6944
6945 temp = (tempcx >> 8) & 0x0F;
6946 temp |= ((tempbx >> 2) & 0xC0);
6947 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
6948 temp |= 0x10;
6949 if(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO) temp |= 0x20;
6950 }
6951 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,temp);
6952
6953 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302LV | VB_SIS302ELV)) {
6954 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xdf,((tempbx & 0x0400) >> 5));
6955 }
6956
6957 #if 0
6958 /* TEST qqqq */
6959 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6960 for(i=0x01, j=0; i<=0x2D; i++, j++) {
6961 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
6962 }
6963 for(i=0x39; i<=0x45; i++, j++) {
6964 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
6965 }
6966 }
6967 #endif
6968
6969 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
6970 tempbx = SiS_Pr->SiS_VDE;
6971 if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
6972 (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) ) {
6973 tempbx >>= 1;
6974 }
6975 tempbx -= 3;
6976 temp = ((tempbx >> 3) & 0x60) | 0x18;
6977 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x46,temp);
6978 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x47,tempbx);
6979
6980 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302LV | VB_SIS302ELV)) {
6981 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xbf,((tempbx & 0x0400) >> 4));
6982 }
6983 }
6984
6985 tempbx = 0;
6986 if(!(modeflag & HalfDCLK)) {
6987 if(SiS_Pr->SiS_VGAHDE >= SiS_Pr->SiS_HDE) {
6988 tempax = 0;
6989 tempbx |= 0x20;
6990 }
6991 }
6992
6993 tempch = tempcl = 0x01;
6994 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6995 if(SiS_Pr->SiS_VGAHDE >= 1024) {
6996 if((!(modeflag & HalfDCLK)) || (HwInfo->jChipType < SIS_315H)) {
6997 tempch = 0x19;
6998 tempcl = 0x20;
6999 if(SiS_Pr->SiS_VGAHDE >= 1280) {
7000 tempch = 0x14;
7001 tempbx &= ~0x20;
7002 }
7003 }
7004 }
7005 }
7006
7007 if(!(tempbx & 0x20)) {
7008 if(modeflag & HalfDCLK) tempcl <<= 1;
7009 longtemp = ((SiS_Pr->SiS_VGAHDE * tempch) / tempcl) << 13;
7010 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) longtemp <<= 3;
7011 tempax = longtemp / SiS_Pr->SiS_HDE;
7012 if(longtemp % SiS_Pr->SiS_HDE) tempax++;
7013 tempbx |= ((tempax >> 8) & 0x1F);
7014 tempcx = tempax >> 13;
7015 }
7016
7017 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,tempax);
7018 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,tempbx);
7019
7020 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
7021
7022 tempcx &= 0x07;
7023 if(tempbx & 0x20) tempcx = 0;
7024 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xF8,tempcx);
7025
7026 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7027 tempbx = 0x0382;
7028 tempcx = 0x007e;
7029 } else {
7030 tempbx = 0x0369;
7031 tempcx = 0x0061;
7032 }
7033 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4B,tempbx);
7034 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4C,tempcx);
7035 temp = (tempcx & 0x0300) >> 6;
7036 temp |= ((tempbx >> 8) & 0x03);
7037 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7038 temp |= 0x10;
7039 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp |= 0x20;
7040 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp |= 0x40;
7041 }
7042 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4D,temp);
7043
7044 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7045 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,(temp - 3));
7046
7047 SiS_SetTVSpecial(SiS_Pr, ModeNo);
7048
7049 if(SiS_Pr->SiS_VBType & VB_SIS301C) {
7050 temp = 0;
7051 if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
7052 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xf7,temp);
7053 }
7054
7055 }
7056
7057 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7058 if(!(SiS_Pr->SiS_TVMode & TVSetNTSC1024)) {
7059 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
7060 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,(temp - 1));
7061 }
7062 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF);
7063 }
7064
7065 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7066 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
7067 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,0x00);
7068 }
7069 }
7070
7071 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) return;
7072
7073 /* From here: Part2 LCD setup */
7074
7075 tempbx = SiS_Pr->SiS_HDE;
7076 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
7077 tempbx--; /* RHACTE = HDE - 1 */
7078 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2C,tempbx);
7079 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,((tempbx >> 4) & 0xf0));
7080
7081 temp = 0x01;
7082 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7083 if(SiS_Pr->SiS_ModeType == ModeEGA) {
7084 if(SiS_Pr->SiS_VGAHDE >= 1024) {
7085 temp = 0x02;
7086 if(HwInfo->jChipType >= SIS_315H) {
7087 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7088 temp = 0x01;
7089 }
7090 }
7091 }
7092 }
7093 }
7094 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,temp);
7095
7096 tempbx = SiS_Pr->SiS_VDE - 1;
7097 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x03,tempbx);
7098 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0C,0xF8,((tempbx >> 8) & 0x07));
7099
7100 tempcx = SiS_Pr->SiS_VT - 1;
7101 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x19,tempcx);
7102 temp = (tempcx >> 3) & 0xE0;
7103 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
7104 /* Enable dithering; only do this for 32bpp mode */
7105 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
7106 temp |= 0x10;
7107 }
7108 }
7109 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1A,0x0f,temp);
7110
7111 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x09,0xF0);
7112 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x0A,0xF0);
7113
7114 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB);
7115 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF);
7116
7117 #ifdef SIS315H
7118 if(SiS_GetCRT2Part2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7119 &CRT2Index, &resindex, HwInfo)) {
7120 switch(CRT2Index) {
7121 case 200: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1; break;
7122 case 206: CRT2Part2Ptr = SiS310_CRT2Part2_Asus1024x768_3; break;
7123 default: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_3; break;
7124 }
7125
7126 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
7127 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
7128 for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
7129 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7130 }
7131 for(j = 0x1c; j <= 0x1d; i++, j++ ) {
7132 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7133 }
7134 for(j = 0x1f; j <= 0x21; i++, j++ ) {
7135 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7136 }
7137 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
7138 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
7139
7140 SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7141
7142
7143 } else {
7144 #endif
7145
7146 /* Checked for 1024x768, 1280x1024, 1400x1050, 1600x1200 */
7147 /* Clevo dual-link 1024x768 */
7148 /* Compaq 1280x1024 has HT 1696 sometimes (calculation OK, if given HT is correct) */
7149 /* Acer: OK, but uses different setting for VESA timing at 640/800/1024 and 640x400 */
7150
7151 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7152 if((SiS_Pr->SiS_LCDInfo & LCDPass11) || (SiS_Pr->PanelYRes == SiS_Pr->SiS_VDE)) {
7153 tempbx = SiS_Pr->SiS_VDE - 1;
7154 tempcx = SiS_Pr->SiS_VT - 1;
7155 } else {
7156 tempbx = SiS_Pr->SiS_VDE + ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7157 tempcx = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7158 }
7159 } else {
7160 tempbx = SiS_Pr->PanelYRes;
7161 tempcx = SiS_Pr->SiS_VT;
7162 tempax = 1;
7163 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7164 tempax = SiS_Pr->PanelYRes;
7165 /* if(SiS_Pr->SiS_VGAVDE == 525) tempax += 0x3c; */ /* 651+301C */
7166 if(SiS_Pr->PanelYRes < SiS_Pr->SiS_VDE) {
7167 tempax = tempcx = 0;
7168 } else {
7169 tempax -= SiS_Pr->SiS_VDE;
7170 }
7171 tempax >>= 1;
7172 }
7173 tempcx -= tempax; /* lcdvdes */
7174 tempbx -= tempax; /* lcdvdee */
7175 }
7176
7177 /* Non-expanding: lcdvdes = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */
7178
7179 #ifdef TWDEBUG
7180 xf86DrvMsg(0, X_INFO, "lcdvdes 0x%x lcdvdee 0x%x\n", tempcx, tempbx);
7181 #endif
7182
7183 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,tempcx); /* lcdvdes */
7184 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,tempbx); /* lcdvdee */
7185
7186 temp = (tempbx >> 5) & 0x38;
7187 temp |= ((tempcx >> 8) & 0x07);
7188 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
7189
7190 tempax = SiS_Pr->SiS_VDE;
7191 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7192 tempax = SiS_Pr->PanelYRes;
7193 }
7194 tempcx = (SiS_Pr->SiS_VT - tempax) >> 4;
7195 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7196 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7197 tempcx = (SiS_Pr->SiS_VT - tempax) / 10;
7198 }
7199 }
7200
7201 tempbx = ((SiS_Pr->SiS_VT + SiS_Pr->SiS_VDE) >> 1) - 1;
7202 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7203 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7204 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { /* ? */
7205 tempax = SiS_Pr->SiS_VT - SiS_Pr->PanelYRes;
7206 if(tempax % 4) { tempax >>= 2; tempax++; }
7207 else { tempax >>= 2; }
7208 tempbx -= (tempax - 1);
7209 } else {
7210 tempbx -= 10;
7211 if(tempbx <= SiS_Pr->SiS_VDE) tempbx = SiS_Pr->SiS_VDE + 1;
7212 }
7213 }
7214 }
7215 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
7216 tempbx++;
7217 if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (crt2crtc == 6)) {
7218 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7219 tempbx = 770;
7220 tempcx = 3;
7221 }
7222 }
7223 }
7224
7225 /* non-expanding: lcdvrs = ((VT + VDE) / 2) - 10 */
7226
7227 if(SiS_Pr->UseCustomMode) {
7228 tempbx = SiS_Pr->CVSyncStart;
7229 }
7230
7231 #ifdef TWDEBUG
7232 xf86DrvMsg(0, X_INFO, "lcdvrs 0x%x\n", tempbx);
7233 #endif
7234
7235 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,tempbx); /* lcdvrs */
7236
7237 temp = (tempbx >> 4) & 0xF0;
7238 tempbx += (tempcx + 1);
7239 temp |= (tempbx & 0x0F);
7240
7241 if(SiS_Pr->UseCustomMode) {
7242 temp &= 0xf0;
7243 temp |= (SiS_Pr->CVSyncEnd & 0x0f);
7244 }
7245
7246 #ifdef TWDEBUG
7247 xf86DrvMsg(0, X_INFO, "lcdvre[3:0] 0x%x\n", (temp & 0x0f));
7248 #endif
7249
7250 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
7251
7252 #ifdef SIS300
7253 SiS_Group2LCDSpecial(SiS_Pr, HwInfo, ModeNo, crt2crtc);
7254 #endif
7255
7256 bridgeoffset = 7;
7257 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) bridgeoffset += 2;
7258 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV)) bridgeoffset++;
7259 if(SiS_IsDualLink(SiS_Pr, HwInfo)) bridgeoffset++;
7260
7261 temp = 0;
7262 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7263 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7264 temp = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7265 if(SiS_IsDualLink(SiS_Pr, HwInfo)) temp >>= 1;
7266 }
7267 }
7268 temp += bridgeoffset;
7269 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1F,temp); /* lcdhdes */
7270 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0F,((temp >> 4) & 0xf0));
7271
7272 tempcx = SiS_Pr->SiS_HT;
7273 tempax = tempbx = SiS_Pr->SiS_HDE;
7274 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7275 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7276 tempax = SiS_Pr->PanelXRes;
7277 tempbx = SiS_Pr->PanelXRes - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7278 }
7279 }
7280 if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
7281 tempcx >>= 1;
7282 tempbx >>= 1;
7283 tempax >>= 1;
7284 }
7285
7286 #ifdef TWDEBUG
7287 xf86DrvMsg(0, X_INFO, "lcdhdee 0x%x\n", tempbx);
7288 #endif
7289
7290 tempbx += bridgeoffset;
7291
7292 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,tempbx); /* lcdhdee */
7293 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0xF0,((tempbx >> 8) & 0x0f));
7294
7295 tempcx = (tempcx - tempax) >> 2;
7296
7297 tempbx += tempcx;
7298 push2 = tempbx;
7299
7300 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7301 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7302 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
7303 if(SiS_Pr->SiS_HDE == 1280) tempbx = (tempbx & 0xff00) | 0x47;
7304 }
7305 }
7306 }
7307
7308 if(SiS_Pr->UseCustomMode) {
7309 tempbx = SiS_Pr->CHSyncStart;
7310 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
7311 tempbx += bridgeoffset;
7312 }
7313
7314 #ifdef TWDEBUG
7315 xf86DrvMsg(0, X_INFO, "lcdhrs 0x%x\n", tempbx);
7316 #endif
7317
7318 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1C,tempbx); /* lcdhrs */
7319 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,((tempbx >> 4) & 0xf0));
7320
7321 tempbx = push2;
7322
7323 tempcx <<= 1;
7324 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7325 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) tempcx >>= 2;
7326 }
7327 tempbx += tempcx;
7328
7329 if(SiS_Pr->UseCustomMode) {
7330 tempbx = SiS_Pr->CHSyncEnd;
7331 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
7332 tempbx += bridgeoffset;
7333 }
7334
7335 #ifdef TWDEBUG
7336 xf86DrvMsg(0, X_INFO, "lcdhre 0x%x\n", tempbx);
7337 #endif
7338
7339 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,tempbx); /* lcdhre */
7340
7341 SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7342
7343 #ifdef SIS300
7344 SiS_Set300Part2Regs(SiS_Pr, HwInfo, ModeIdIndex, RefreshRateTableIndex, ModeNo);
7345 #endif
7346 #ifdef SIS315H
7347 } /* CRT2-LCD from table */
7348 #endif
7349 }
7350
7351 /*********************************************/
7352 /* SET PART 3 REGISTER GROUP */
7353 /*********************************************/
7354
7355 static void
SiS_SetGroup3(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,PSIS_HW_INFO HwInfo)7356 SiS_SetGroup3(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7357 PSIS_HW_INFO HwInfo)
7358 {
7359 USHORT i;
7360 const UCHAR *tempdi;
7361
7362 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
7363
7364 #ifndef SIS_CP
7365 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x00,0x00);
7366 #else
7367 SIS_CP_INIT301_CP
7368 #endif
7369
7370 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7371 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7372 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7373 } else {
7374 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xF5);
7375 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xB7);
7376 }
7377
7378 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7379 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7380 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7381 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x3D,0xA8);
7382 }
7383
7384 tempdi = NULL;
7385 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7386 tempdi = SiS_Pr->SiS_HiTVGroup3Data;
7387 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
7388 tempdi = SiS_Pr->SiS_HiTVGroup3Simu;
7389 }
7390 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7391 if(!(SiS_Pr->SiS_TVMode & TVSetYPbPr525i)) {
7392 tempdi = SiS_HiTVGroup3_1;
7393 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempdi = SiS_HiTVGroup3_2;
7394 }
7395 }
7396 if(tempdi) {
7397 for(i=0; i<=0x3E; i++) {
7398 SiS_SetReg(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
7399 }
7400 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV)) {
7401 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
7402 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x28,0x3f);
7403 }
7404 }
7405 }
7406
7407 #ifdef SIS_CP
7408 SIS_CP_INIT301_CP2
7409 #endif
7410 }
7411
7412 /*********************************************/
7413 /* SET PART 4 REGISTER GROUP */
7414 /*********************************************/
7415
7416 #ifdef SIS315H
7417 static void
SiS_ShiftXPos(SiS_Private * SiS_Pr,int shift)7418 SiS_ShiftXPos(SiS_Private *SiS_Pr, int shift)
7419 {
7420 USHORT temp, temp1, temp2;
7421
7422 temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x1f);
7423 temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x20);
7424 temp = (USHORT)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7425 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,temp);
7426 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0f,((temp >> 4) & 0xf0));
7427 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x2b) & 0x0f;
7428 temp = (USHORT)((int)(temp) + shift);
7429 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2b,0xf0,(temp & 0x0f));
7430 temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7431 temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x42);
7432 temp = (USHORT)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7433 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,temp);
7434 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x42,0x0f,((temp >> 4) & 0xf0));
7435 }
7436
7437 static void
SiS_SetGroup4_C_ELV(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,USHORT ModeNo,USHORT ModeIdIndex)7438 SiS_SetGroup4_C_ELV(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
7439 USHORT ModeNo, USHORT ModeIdIndex)
7440 {
7441 USHORT temp, temp1, resinfo = 0;
7442
7443 if(!(SiS_Pr->SiS_VBType & VB_SIS301C)) return;
7444 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToHiVision | SetCRT2ToYPbPr525750))) return;
7445
7446 if(ModeNo > 0x13) {
7447 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
7448 }
7449
7450 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3a,0x08);
7451 temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x3a);
7452 if(!(temp & 0x01)) {
7453 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3a,0xdf);
7454 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xfc);
7455 if(HwInfo->jChipType < SIS_661) {
7456 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xf8);
7457 }
7458 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0xfb);
7459 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp = 0x0000;
7460 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp = 0x0002;
7461 else if(SiS_Pr->SiS_TVMode & TVSetHiVision) temp = 0x0400;
7462 else temp = 0x0402;
7463 if(HwInfo->jChipType >= SIS_661) {
7464 temp1 = 0;
7465 if(SiS_Pr->SiS_TVMode & TVAspect43) temp1 = 4;
7466 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0f,0xfb,temp1);
7467 if(SiS_Pr->SiS_TVMode & TVAspect43LB) temp |= 0x01;
7468 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0x7c,(temp & 0xff));
7469 } else {
7470 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x3b) & 0x03;
7471 if(temp1 == 0x01) temp |= 0x01;
7472 if(temp1 == 0x03) temp |= 0x04; /* ? why not 0x10? */
7473 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xf8,(temp & 0xff));
7474 }
7475 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7476
7477 if(HwInfo->jChipType >= SIS_661) { /* ? */
7478 if(SiS_Pr->SiS_TVMode & TVAspect43) {
7479 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
7480 if(resinfo == SIS_RI_1024x768) {
7481 SiS_ShiftXPos(SiS_Pr, 97);
7482 } else {
7483 SiS_ShiftXPos(SiS_Pr, 111);
7484 }
7485 } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
7486 SiS_ShiftXPos(SiS_Pr, 136);
7487 }
7488 }
7489 }
7490 }
7491 }
7492 #endif
7493
7494 static void
SiS_SetCRT2VCLK(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo)7495 SiS_SetCRT2VCLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7496 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
7497 {
7498 USHORT vclkindex;
7499 USHORT temp, reg1, reg2;
7500
7501 if(SiS_Pr->UseCustomMode) {
7502 reg1 = SiS_Pr->CSR2B;
7503 reg2 = SiS_Pr->CSR2C;
7504 } else {
7505 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7506 HwInfo);
7507 reg1 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
7508 reg2 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
7509 }
7510
7511 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
7512 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
7513 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x57);
7514 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,0x46);
7515 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1f,0xf6);
7516 } else {
7517 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7518 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7519 }
7520 } else {
7521 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x01);
7522 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7523 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7524 }
7525 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x12,0x00);
7526 temp = 0x08;
7527 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) temp |= 0x20;
7528 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,temp);
7529 }
7530
7531 static void
SiS_SetGroup4(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo)7532 SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7533 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
7534 {
7535 USHORT tempax,tempcx,tempbx,modeflag,temp,resinfo;
7536 ULONG tempebx,tempeax,templong;
7537
7538 if(ModeNo <= 0x13) {
7539 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7540 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
7541 } else if(SiS_Pr->UseCustomMode) {
7542 modeflag = SiS_Pr->CModeFlag;
7543 resinfo = 0;
7544 } else {
7545 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7546 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
7547 }
7548
7549 if(HwInfo->jChipType >= SIS_315H) {
7550 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
7551 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7552 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7553 }
7554 }
7555 }
7556
7557 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302LV)) {
7558 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7559 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x10,0x9f);
7560 }
7561 }
7562
7563 if(HwInfo->jChipType >= SIS_315H) {
7564 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7565 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
7566 if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
7567 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
7568 }
7569 #ifdef SET_EMI
7570 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
7571 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
7572 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
7573 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
7574 }
7575 #endif
7576 }
7577 return;
7578 }
7579 }
7580
7581 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x13,SiS_Pr->SiS_RVBHCFACT);
7582
7583 tempbx = SiS_Pr->SiS_RVBHCMAX;
7584 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x14,tempbx);
7585
7586 temp = (tempbx >> 1) & 0x80;
7587
7588 tempcx = SiS_Pr->SiS_VGAHT - 1;
7589 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x16,tempcx);
7590
7591 temp |= ((tempcx >> 5) & 0x78);
7592
7593 tempcx = SiS_Pr->SiS_VGAVT - 1;
7594 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempcx -= 5;
7595 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x17,tempcx);
7596
7597 temp |= ((tempcx >> 8) & 0x07);
7598 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x15,temp);
7599
7600 tempbx = SiS_Pr->SiS_VGAHDE;
7601 if(modeflag & HalfDCLK) tempbx >>= 1;
7602 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
7603
7604 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7605 temp = 0;
7606 if(tempbx > 800) temp = 0x60;
7607 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7608 temp = 0;
7609 if(tempbx == 1024) temp = 0xA0;
7610 else if(tempbx > 1024) temp = 0xC0;
7611 } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
7612 temp = 0;
7613 if(tempbx >= 1280) temp = 0x40;
7614 else if(tempbx >= 1024) temp = 0x20;
7615 } else {
7616 temp = 0x80;
7617 if(tempbx >= 1024) temp = 0xA0;
7618 }
7619
7620 if(SiS_Pr->SiS_VBType & VB_SIS301) {
7621 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) temp |= 0x0A;
7622 }
7623
7624 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0E,0x10,temp);
7625
7626 tempeax = SiS_Pr->SiS_VGAVDE;
7627 tempebx = SiS_Pr->SiS_VDE;
7628 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7629 if(!(temp & 0xE0)) tempebx >>=1;
7630 }
7631
7632 tempcx = SiS_Pr->SiS_RVBHRS;
7633 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x18,tempcx);
7634 tempcx >>= 8;
7635 tempcx |= 0x40;
7636
7637 if(tempeax <= tempebx) {
7638 tempcx ^= 0x40;
7639 } else {
7640 tempeax -= tempebx;
7641 }
7642
7643 tempeax *= (256 * 1024);
7644 templong = tempeax % tempebx;
7645 tempeax /= tempebx;
7646 if(templong) tempeax++;
7647
7648 temp = (USHORT)(tempeax & 0x000000FF);
7649 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1B,temp);
7650 temp = (USHORT)((tempeax & 0x0000FF00) >> 8);
7651 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1A,temp);
7652 temp = (USHORT)((tempeax >> 12) & 0x70); /* sic! */
7653 temp |= (tempcx & 0x4F);
7654 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x19,temp);
7655
7656 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
7657
7658 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1C,0x28);
7659
7660 /* Calc Linebuffer max address and set/clear decimode */
7661 tempbx = 0;
7662 if(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p)) tempbx = 0x08;
7663 tempax = SiS_Pr->SiS_VGAHDE;
7664 if(modeflag & HalfDCLK) tempax >>= 1;
7665 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempax >>= 1;
7666 if(tempax > 800) {
7667 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7668 tempax -= 800;
7669 } else { /* 651+301C: Only if TVNoHiviNoYPbPr */
7670 tempbx = 0x08;
7671 if(tempax == 1024) tempax *= 25;
7672 else tempax *= 20;
7673 temp = tempax % 32;
7674 tempax /= 32;
7675 if(temp) tempax++;
7676 tempax++;
7677 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) ||
7678 (SiS_Pr->SiS_TVMode & TVSetYPbPr525i)) {
7679 if(resinfo == SIS_RI_1024x768) {
7680 /* Otherwise white line at right edge */
7681 tempax = (tempax & 0xff00) | 0x20;
7682 }
7683 }
7684 }
7685 }
7686 tempax--;
7687 temp = ((tempax >> 4) & 0x30) | tempbx;
7688 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1D,tempax);
7689 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1E,temp);
7690
7691 temp = 0x0036; tempbx = 0xD0;
7692 if((IS_SIS550650740660) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
7693 temp = 0x0026; tempbx = 0xC0; /* See En/DisableBridge() */
7694 }
7695 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7696 if(!(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetHiVision | TVSetYPbPr750p | TVSetYPbPr525p))) {
7697 temp |= 0x01;
7698 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7699 if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
7700 temp &= ~0x01;
7701 }
7702 }
7703 }
7704 }
7705 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,tempbx,temp);
7706
7707 tempbx = SiS_Pr->SiS_HT >> 1;
7708 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
7709 tempbx -= 2;
7710 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x22,tempbx);
7711 temp = (tempbx >> 5) & 0x38;
7712 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp);
7713
7714 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
7715 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7716 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7717 /* LCD-too-dark-error-source, see FinalizeLCD() */
7718 }
7719 if(HwInfo->jChipType >= SIS_315H) {
7720 if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
7721 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
7722 }
7723 }
7724 #ifdef SET_EMI
7725 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
7726 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
7727 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
7728 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
7729 }
7730 #endif
7731 }
7732
7733 } /* 301B */
7734
7735 SiS_SetCRT2VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
7736 }
7737
7738 /*********************************************/
7739 /* SET PART 5 REGISTER GROUP */
7740 /*********************************************/
7741
7742 static void
SiS_SetGroup5(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,PSIS_HW_INFO HwInfo)7743 SiS_SetGroup5(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7744 PSIS_HW_INFO HwInfo)
7745 {
7746
7747 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
7748
7749 if(SiS_Pr->SiS_ModeType == ModeVGA) {
7750 if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))) {
7751 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
7752 SiS_LoadDAC(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
7753 }
7754 }
7755 }
7756
7757 /*********************************************/
7758 /* MODIFY CRT1 GROUP FOR SLAVE MODE */
7759 /*********************************************/
7760
7761 static void
SiS_ModCRT1CRTC(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo)7762 SiS_ModCRT1CRTC(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7763 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
7764 {
7765 USHORT tempah,i,modeflag,j;
7766 USHORT ResIndex,DisplayType;
7767 const SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr=NULL;
7768
7769 if(ModeNo <= 0x13) modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7770 else modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7771
7772 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
7773 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
7774 (SiS_Pr->SiS_CustomT == CUT_PANEL848))
7775 return;
7776
7777 if(!(SiS_GetLVDSCRT1Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7778 &ResIndex, &DisplayType))) {
7779 return;
7780 }
7781
7782 if(HwInfo->jChipType < SIS_315H) {
7783 if(SiS_Pr->SiS_SetFlag & SetDOSMode) return;
7784 }
7785
7786 switch(DisplayType) {
7787 case 0 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1; break;
7788 case 1 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1_H; break;
7789 case 2 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2; break;
7790 case 3 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2_H; break;
7791 case 4 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1; break;
7792 case 5 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1_H; break;
7793 case 6 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2; break;
7794 case 7 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2_H; break;
7795 case 8 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1; break;
7796 case 9 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1_H; break;
7797 case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2; break;
7798 case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2_H; break;
7799 case 12: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1; break;
7800 case 13: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H; break;
7801 case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_1; break;
7802 case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_1_H; break;
7803 case 16: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_2; break;
7804 case 17: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_2_H; break;
7805 case 18: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC; break;
7806 case 19: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC; break;
7807 case 20: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL; break;
7808 case 21: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL; break;
7809 case 22: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x480_1; break; /* FSTN */
7810 case 23: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1; break;
7811 case 24: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1_H; break;
7812 case 25: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2; break;
7813 case 26: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2_H; break;
7814 case 27: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_1; break;
7815 case 28: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_1_H; break;
7816 case 29: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_2; break;
7817 case 30: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_2_H; break;
7818 case 36: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_1; break;
7819 case 37: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_1_H; break;
7820 case 38: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_2; break;
7821 case 39: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_2_H; break;
7822 case 40: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_1; break;
7823 case 41: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_1_H; break;
7824 case 42: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_2; break;
7825 case 43: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_2_H; break;
7826 case 50: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1; break;
7827 case 51: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1_H; break;
7828 case 52: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_2; break;
7829 case 53: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_2_H; break;
7830 case 54: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_3; break;
7831 case 55: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_3_H; break;
7832 case 99: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1SOPAL; break;
7833 default: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1; break;
7834 }
7835
7836 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
7837
7838 tempah = (LVDSCRT1Ptr + ResIndex)->CR[0];
7839 SiS_SetReg(SiS_Pr->SiS_P3d4,0x00,tempah);
7840
7841 for(i=0x02,j=1;i<=0x05;i++,j++){
7842 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
7843 SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
7844 }
7845 for(i=0x06,j=5;i<=0x07;i++,j++){
7846 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
7847 SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
7848 }
7849 for(i=0x10,j=7;i<=0x11;i++,j++){
7850 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
7851 SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
7852 }
7853 for(i=0x15,j=9;i<=0x16;i++,j++){
7854 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
7855 SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
7856 }
7857 for(i=0x0A,j=11;i<=0x0C;i++,j++){
7858 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
7859 SiS_SetReg(SiS_Pr->SiS_P3c4,i,tempah);
7860 }
7861
7862 tempah = (LVDSCRT1Ptr + ResIndex)->CR[14];
7863 tempah &= 0xE0;
7864 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);
7865
7866 tempah = (LVDSCRT1Ptr + ResIndex)->CR[14];
7867 tempah &= 0x01;
7868 tempah <<= 5;
7869 if(modeflag & DoubleScanMode) tempah |= 0x080;
7870 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
7871 }
7872
7873 /*********************************************/
7874 /* SET CRT2 ECLK */
7875 /*********************************************/
7876
7877 static void
SiS_SetCRT2ECLK(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo)7878 SiS_SetCRT2ECLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7879 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
7880 {
7881 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
7882 USHORT clkbase, vclkindex=0;
7883 UCHAR sr2b, sr2c;
7884
7885 if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) || (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
7886 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
7887 if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK & 0x3f) == 2) {
7888 RefreshRateTableIndex--;
7889 }
7890 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
7891 RefreshRateTableIndex, HwInfo);
7892 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
7893 } else {
7894 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
7895 RefreshRateTableIndex, HwInfo);
7896 }
7897
7898 sr2b = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
7899 sr2c = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
7900
7901 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
7902 if(SiS_Pr->SiS_UseROM) {
7903 if(ROMAddr[0x220] & 0x01) {
7904 sr2b = ROMAddr[0x227];
7905 sr2c = ROMAddr[0x228];
7906 }
7907 }
7908 }
7909
7910 clkbase = 0x02B;
7911 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
7912 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
7913 clkbase += 3;
7914 }
7915 }
7916
7917 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x20);
7918 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
7919 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
7920 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x10);
7921 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
7922 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
7923 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x00);
7924 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
7925 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
7926 }
7927
7928 /*********************************************/
7929 /* SET UP CHRONTEL CHIPS */
7930 /*********************************************/
7931
7932 static void
SiS_SetCHTVReg(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex)7933 SiS_SetCHTVReg(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7934 USHORT RefreshRateTableIndex)
7935 {
7936 USHORT temp, tempbx, tempcl;
7937 USHORT TVType, resindex;
7938 const SiS_CHTVRegDataStruct *CHTVRegData = NULL;
7939
7940 if(ModeNo <= 0x13)
7941 tempcl = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
7942 else
7943 tempcl = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
7944
7945 TVType = 0;
7946 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
7947 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7948 TVType += 2;
7949 if(SiS_Pr->SiS_ModeType > ModeVGA) {
7950 if(SiS_Pr->SiS_CHSOverScan) TVType = 8;
7951 }
7952 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7953 TVType = 4;
7954 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
7955 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
7956 TVType = 6;
7957 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
7958 }
7959 }
7960 switch(TVType) {
7961 case 0: CHTVRegData = SiS_Pr->SiS_CHTVReg_UNTSC; break;
7962 case 1: CHTVRegData = SiS_Pr->SiS_CHTVReg_ONTSC; break;
7963 case 2: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPAL; break;
7964 case 3: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break;
7965 case 4: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALM; break;
7966 case 5: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALM; break;
7967 case 6: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALN; break;
7968 case 7: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALN; break;
7969 case 8: CHTVRegData = SiS_Pr->SiS_CHTVReg_SOPAL; break;
7970 default: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break;
7971 }
7972 resindex = tempcl & 0x3F;
7973
7974 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
7975
7976 #ifdef SIS300
7977
7978 /* Chrontel 7005 - I assume that it does not come with a 315 series chip */
7979
7980 /* We don't support modes >800x600 */
7981 if (resindex > 5) return;
7982
7983 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7984 SiS_SetCH700x(SiS_Pr,0x4304); /* 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
7985 SiS_SetCH700x(SiS_Pr,0x6909); /* Black level for PAL (105)*/
7986 } else {
7987 SiS_SetCH700x(SiS_Pr,0x0304); /* upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
7988 SiS_SetCH700x(SiS_Pr,0x7109); /* Black level for NTSC (113)*/
7989 }
7990
7991 temp = CHTVRegData[resindex].Reg[0];
7992 tempbx=((temp&0x00FF)<<8)|0x00; /* Mode register */
7993 SiS_SetCH700x(SiS_Pr,tempbx);
7994 temp = CHTVRegData[resindex].Reg[1];
7995 tempbx=((temp&0x00FF)<<8)|0x07; /* Start active video register */
7996 SiS_SetCH700x(SiS_Pr,tempbx);
7997 temp = CHTVRegData[resindex].Reg[2];
7998 tempbx=((temp&0x00FF)<<8)|0x08; /* Position overflow register */
7999 SiS_SetCH700x(SiS_Pr,tempbx);
8000 temp = CHTVRegData[resindex].Reg[3];
8001 tempbx=((temp&0x00FF)<<8)|0x0A; /* Horiz Position register */
8002 SiS_SetCH700x(SiS_Pr,tempbx);
8003 temp = CHTVRegData[resindex].Reg[4];
8004 tempbx=((temp&0x00FF)<<8)|0x0B; /* Vertical Position register */
8005 SiS_SetCH700x(SiS_Pr,tempbx);
8006
8007 /* Set minimum flicker filter for Luma channel (SR1-0=00),
8008 minimum text enhancement (S3-2=10),
8009 maximum flicker filter for Chroma channel (S5-4=10)
8010 =00101000=0x28 (When reading, S1-0->S3-2, and S3-2->S1-0!)
8011 */
8012 SiS_SetCH700x(SiS_Pr,0x2801);
8013
8014 /* Set video bandwidth
8015 High bandwith Luma composite video filter(S0=1)
8016 low bandwith Luma S-video filter (S2-1=00)
8017 disable peak filter in S-video channel (S3=0)
8018 high bandwidth Chroma Filter (S5-4=11)
8019 =00110001=0x31
8020 */
8021 SiS_SetCH700x(SiS_Pr,0xb103); /* old: 3103 */
8022
8023 /* Register 0x3D does not exist in non-macrovision register map
8024 (Maybe this is a macrovision register?)
8025 */
8026 #ifndef SIS_CP
8027 SiS_SetCH70xx(SiS_Pr,0x003D);
8028 #endif
8029
8030 /* Register 0x10 only contains 1 writable bit (S0) for sensing,
8031 all other bits a read-only. Macrovision?
8032 */
8033 SiS_SetCH70xxANDOR(SiS_Pr,0x0010,0x1F);
8034
8035 /* Register 0x11 only contains 3 writable bits (S0-S2) for
8036 contrast enhancement (set to 010 -> gain 1 Yout = 17/16*(Yin-30) )
8037 */
8038 SiS_SetCH70xxANDOR(SiS_Pr,0x0211,0xF8);
8039
8040 /* Clear DSEN
8041 */
8042 SiS_SetCH70xxANDOR(SiS_Pr,0x001C,0xEF);
8043
8044 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) { /* ---- NTSC ---- */
8045 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) {
8046 if(resindex == 0x04) { /* 640x480 overscan: Mode 16 */
8047 SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off */
8048 SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE); /* ACIV on, no need to set FSCI */
8049 } else if(resindex == 0x05) { /* 800x600 overscan: Mode 23 */
8050 SiS_SetCH70xxANDOR(SiS_Pr,0x0118,0xF0); /* 0x18-0x1f: FSCI 469,762,048 */
8051 SiS_SetCH70xxANDOR(SiS_Pr,0x0C19,0xF0);
8052 SiS_SetCH70xxANDOR(SiS_Pr,0x001A,0xF0);
8053 SiS_SetCH70xxANDOR(SiS_Pr,0x001B,0xF0);
8054 SiS_SetCH70xxANDOR(SiS_Pr,0x001C,0xF0);
8055 SiS_SetCH70xxANDOR(SiS_Pr,0x001D,0xF0);
8056 SiS_SetCH70xxANDOR(SiS_Pr,0x001E,0xF0);
8057 SiS_SetCH70xxANDOR(SiS_Pr,0x001F,0xF0);
8058 SiS_SetCH70xxANDOR(SiS_Pr,0x0120,0xEF); /* Loop filter on for mode 23 */
8059 SiS_SetCH70xxANDOR(SiS_Pr,0x0021,0xFE); /* ACIV off, need to set FSCI */
8060 }
8061 } else {
8062 if(resindex == 0x04) { /* ----- 640x480 underscan; Mode 17 */
8063 SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off */
8064 SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);
8065 } else if(resindex == 0x05) { /* ----- 800x600 underscan: Mode 24 */
8066 #if 0
8067 SiS_SetCH70xxANDOR(SiS_Pr,0x0118,0xF0); /* (FSCI was 0x1f1c71c7 - this is for mode 22) */
8068 SiS_SetCH70xxANDOR(SiS_Pr,0x0919,0xF0); /* FSCI for mode 24 is 428,554,851 */
8069 SiS_SetCH70xxANDOR(SiS_Pr,0x081A,0xF0); /* 198b3a63 */
8070 SiS_SetCH70xxANDOR(SiS_Pr,0x0b1B,0xF0);
8071 SiS_SetCH70xxANDOR(SiS_Pr,0x041C,0xF0);
8072 SiS_SetCH70xxANDOR(SiS_Pr,0x011D,0xF0);
8073 SiS_SetCH70xxANDOR(SiS_Pr,0x061E,0xF0);
8074 SiS_SetCH70xxANDOR(SiS_Pr,0x051F,0xF0);
8075 SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off for mode 24 */
8076 SiS_SetCH70xxANDOR(SiS_Pr,0x0021,0xFE); /* ACIV off, need to set FSCI */
8077 #endif /* All alternatives wrong (datasheet wrong?), don't use FSCI */
8078 SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off */
8079 SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);
8080 }
8081 }
8082 } else { /* ---- PAL ---- */
8083 /* We don't play around with FSCI in PAL mode */
8084 if(resindex == 0x04) {
8085 SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off */
8086 SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE); /* ACIV on */
8087 } else {
8088 SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off */
8089 SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE); /* ACIV on */
8090 }
8091 }
8092
8093 #endif /* 300 */
8094
8095 } else {
8096
8097 /* Chrontel 7019 - assumed that it does not come with a 300 series chip */
8098
8099 #ifdef SIS315H
8100
8101 /* We don't support modes >1024x768 */
8102 if (resindex > 6) return;
8103
8104 temp = CHTVRegData[resindex].Reg[0];
8105 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
8106 temp |= 0x10;
8107 }
8108 tempbx=((temp & 0x00FF) << 8) | 0x00;
8109 SiS_SetCH701x(SiS_Pr,tempbx);
8110
8111 temp = CHTVRegData[resindex].Reg[1];
8112 tempbx=((temp & 0x00FF) << 8) | 0x01;
8113 SiS_SetCH701x(SiS_Pr,tempbx);
8114
8115 temp = CHTVRegData[resindex].Reg[2];
8116 tempbx=((temp & 0x00FF) << 8) | 0x02;
8117 SiS_SetCH701x(SiS_Pr,tempbx);
8118
8119 temp = CHTVRegData[resindex].Reg[3];
8120 tempbx=((temp & 0x00FF) << 8) | 0x04;
8121 SiS_SetCH701x(SiS_Pr,tempbx);
8122
8123 temp = CHTVRegData[resindex].Reg[4];
8124 tempbx=((temp & 0x00FF) << 8) | 0x03;
8125 SiS_SetCH701x(SiS_Pr,tempbx);
8126
8127 temp = CHTVRegData[resindex].Reg[5];
8128 tempbx=((temp & 0x00FF) << 8) | 0x05;
8129 SiS_SetCH701x(SiS_Pr,tempbx);
8130
8131 temp = CHTVRegData[resindex].Reg[6];
8132 tempbx=((temp & 0x00FF) << 8) | 0x06;
8133 SiS_SetCH701x(SiS_Pr,tempbx);
8134
8135 temp = CHTVRegData[resindex].Reg[7];
8136 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
8137 temp = 0x66;
8138 }
8139 tempbx=((temp & 0x00FF) << 8) | 0x07;
8140 SiS_SetCH701x(SiS_Pr,tempbx);
8141
8142 temp = CHTVRegData[resindex].Reg[8];
8143 tempbx=((temp & 0x00FF) << 8) | 0x08;
8144 SiS_SetCH701x(SiS_Pr,tempbx);
8145
8146 temp = CHTVRegData[resindex].Reg[9];
8147 tempbx=((temp & 0x00FF) << 8) | 0x15;
8148 SiS_SetCH701x(SiS_Pr,tempbx);
8149
8150 temp = CHTVRegData[resindex].Reg[10];
8151 tempbx=((temp & 0x00FF) << 8) | 0x1f;
8152 SiS_SetCH701x(SiS_Pr,tempbx);
8153
8154 temp = CHTVRegData[resindex].Reg[11];
8155 tempbx=((temp & 0x00FF) << 8) | 0x0c;
8156 SiS_SetCH701x(SiS_Pr,tempbx);
8157
8158 temp = CHTVRegData[resindex].Reg[12];
8159 tempbx=((temp & 0x00FF) << 8) | 0x0d;
8160 SiS_SetCH701x(SiS_Pr,tempbx);
8161
8162 temp = CHTVRegData[resindex].Reg[13];
8163 tempbx=((temp & 0x00FF) << 8) | 0x0e;
8164 SiS_SetCH701x(SiS_Pr,tempbx);
8165
8166 temp = CHTVRegData[resindex].Reg[14];
8167 tempbx=((temp & 0x00FF) << 8) | 0x0f;
8168 SiS_SetCH701x(SiS_Pr,tempbx);
8169
8170 temp = CHTVRegData[resindex].Reg[15];
8171 tempbx=((temp & 0x00FF) << 8) | 0x10;
8172 SiS_SetCH701x(SiS_Pr,tempbx);
8173
8174 temp = SiS_GetCH701x(SiS_Pr,0x21) & ~0x02;
8175 /* D1 should be set for PAL, PAL-N and NTSC-J,
8176 but I won't do that for PAL unless somebody
8177 tells me to do so. Since the BIOS uses
8178 non-default CIV values and blacklevels,
8179 this might be compensated anyway.
8180 */
8181 if(SiS_Pr->SiS_TVMode & (TVSetPALN | TVSetNTSCJ)) temp |= 0x02;
8182 SiS_SetCH701x(SiS_Pr,((temp << 8) | 0x21));
8183
8184 #endif /* 315 */
8185
8186 }
8187
8188 #ifdef SIS_CP
8189 SIS_CP_INIT301_CP3
8190 #endif
8191
8192 }
8193
8194 void
SiS_Chrontel701xBLOn(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)8195 SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8196 {
8197 USHORT temp;
8198
8199 /* Enable Chrontel 7019 LCD panel backlight */
8200 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8201 if(HwInfo->jChipType == SIS_740) {
8202 SiS_SetCH701x(SiS_Pr,0x6566);
8203 } else {
8204 temp = SiS_GetCH701x(SiS_Pr,0x66);
8205 temp |= 0x20;
8206 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
8207 }
8208 }
8209 }
8210
8211 void
SiS_Chrontel701xBLOff(SiS_Private * SiS_Pr)8212 SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr)
8213 {
8214 USHORT temp;
8215
8216 /* Disable Chrontel 7019 LCD panel backlight */
8217 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8218 temp = SiS_GetCH701x(SiS_Pr,0x66);
8219 temp &= 0xDF;
8220 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
8221 }
8222 }
8223
8224 #ifdef SIS315H /* ----------- 315 series only ---------- */
8225
8226 static void
SiS_ChrontelPowerSequencing(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)8227 SiS_ChrontelPowerSequencing(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8228 {
8229 UCHAR regtable[] = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
8230 UCHAR table1024_740[] = { 0x01, 0x02, 0x01, 0x01, 0x01 };
8231 UCHAR table1400_740[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 };
8232 UCHAR asus1024_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8233 UCHAR asus1400_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8234 UCHAR table1024_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8235 UCHAR table1400_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8236 UCHAR *tableptr = NULL;
8237 int i;
8238
8239 /* Set up Power up/down timing */
8240
8241 if(HwInfo->jChipType == SIS_740) {
8242 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8243 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1024_740;
8244 else tableptr = table1024_740;
8245 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8246 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8247 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8248 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1400_740;
8249 else tableptr = table1400_740;
8250 } else return;
8251 } else {
8252 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8253 tableptr = table1024_650;
8254 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8255 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8256 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8257 tableptr = table1400_650;
8258 } else return;
8259 }
8260
8261 for(i=0; i<5; i++) {
8262 SiS_SetCH701x(SiS_Pr,(tableptr[i] << 8) | regtable[i]);
8263 }
8264 }
8265
8266 static void
SiS_SetCH701xForLCD(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)8267 SiS_SetCH701xForLCD(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8268 {
8269 UCHAR regtable[] = { 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
8270 0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66 };
8271 UCHAR table1024_740[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8272 0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44 };
8273 UCHAR table1280_740[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8274 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 };
8275 UCHAR table1400_740[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8276 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 };
8277 UCHAR table1600_740[] = { 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8278 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44 };
8279 UCHAR table1024_650[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8280 0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02 };
8281 UCHAR table1280_650[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8282 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02 };
8283 UCHAR table1400_650[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xef,
8284 0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02 };
8285 UCHAR table1600_650[] = { 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8286 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a };
8287 UCHAR *tableptr = NULL;
8288 USHORT tempbh;
8289 int i;
8290
8291 if(HwInfo->jChipType == SIS_740) {
8292 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tableptr = table1024_740;
8293 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_740;
8294 else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_740;
8295 else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_740;
8296 else return;
8297 } else {
8298 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tableptr = table1024_650;
8299 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_650;
8300 else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_650;
8301 else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_650;
8302 else return;
8303 }
8304
8305 tempbh = SiS_GetCH701x(SiS_Pr,0x74);
8306 if((tempbh == 0xf6) || (tempbh == 0xc7)) {
8307 tempbh = SiS_GetCH701x(SiS_Pr,0x73);
8308 if(tempbh == 0xc8) {
8309 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) return;
8310 } else if(tempbh == 0xdb) {
8311 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) return;
8312 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) return;
8313 } else if(tempbh == 0xde) {
8314 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) return;
8315 }
8316 }
8317
8318 if(HwInfo->jChipType == SIS_740) tempbh = 0x0d;
8319 else tempbh = 0x0c;
8320
8321 for(i = 0; i < tempbh; i++) {
8322 SiS_SetCH701x(SiS_Pr,(tableptr[i] << 8) | regtable[i]);
8323 }
8324 SiS_ChrontelPowerSequencing(SiS_Pr,HwInfo);
8325 tempbh = SiS_GetCH701x(SiS_Pr,0x1e);
8326 tempbh |= 0xc0;
8327 SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x1e);
8328
8329 if(HwInfo->jChipType == SIS_740) {
8330 tempbh = SiS_GetCH701x(SiS_Pr,0x1c);
8331 tempbh &= 0xfb;
8332 SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x1c);
8333 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8334 tempbh = SiS_GetCH701x(SiS_Pr,0x64);
8335 tempbh |= 0x40;
8336 SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x64);
8337 tempbh = SiS_GetCH701x(SiS_Pr,0x03);
8338 tempbh &= 0x3f;
8339 SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x03);
8340 }
8341 }
8342
8343 static void
SiS_ChrontelResetVSync(SiS_Private * SiS_Pr)8344 SiS_ChrontelResetVSync(SiS_Private *SiS_Pr)
8345 {
8346 unsigned char temp, temp1;
8347
8348 temp1 = SiS_GetCH701x(SiS_Pr,0x49);
8349 SiS_SetCH701x(SiS_Pr,0x3e49);
8350 temp = SiS_GetCH701x(SiS_Pr,0x47);
8351 temp &= 0x7f; /* Use external VSYNC */
8352 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
8353 SiS_LongDelay(SiS_Pr,3);
8354 temp = SiS_GetCH701x(SiS_Pr,0x47);
8355 temp |= 0x80; /* Use internal VSYNC */
8356 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
8357 SiS_SetCH701x(SiS_Pr,(temp1 << 8) | 0x49);
8358 }
8359
8360 void
SiS_Chrontel701xOn(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)8361 SiS_Chrontel701xOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8362 {
8363 USHORT temp;
8364
8365 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8366 if(HwInfo->jChipType == SIS_740) {
8367 temp = SiS_GetCH701x(SiS_Pr,0x1c);
8368 temp |= 0x04; /* Invert XCLK phase */
8369 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c);
8370 }
8371 if(SiS_IsYPbPr(SiS_Pr, HwInfo)) {
8372 temp = SiS_GetCH701x(SiS_Pr,0x01);
8373 temp &= 0x3f;
8374 temp |= 0x80; /* Enable YPrPb (HDTV) */
8375 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x01);
8376 }
8377 if(SiS_IsChScart(SiS_Pr, HwInfo)) {
8378 temp = SiS_GetCH701x(SiS_Pr,0x01);
8379 temp &= 0x3f;
8380 temp |= 0xc0; /* Enable SCART + CVBS */
8381 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x01);
8382 }
8383 if(HwInfo->jChipType == SIS_740) {
8384 SiS_ChrontelResetVSync(SiS_Pr);
8385 SiS_SetCH701x(SiS_Pr,0x2049); /* Enable TV path */
8386 } else {
8387 SiS_SetCH701x(SiS_Pr,0x2049); /* Enable TV path */
8388 temp = SiS_GetCH701x(SiS_Pr,0x49);
8389 if(SiS_IsYPbPr(SiS_Pr,HwInfo)) {
8390 temp = SiS_GetCH701x(SiS_Pr,0x73);
8391 temp |= 0x60;
8392 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x73);
8393 }
8394 temp = SiS_GetCH701x(SiS_Pr,0x47);
8395 temp &= 0x7f;
8396 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
8397 SiS_LongDelay(SiS_Pr,2);
8398 temp = SiS_GetCH701x(SiS_Pr,0x47);
8399 temp |= 0x80;
8400 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
8401 }
8402 }
8403 }
8404
8405 void
SiS_Chrontel701xOff(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)8406 SiS_Chrontel701xOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8407 {
8408 USHORT temp;
8409
8410 /* Complete power down of LVDS */
8411 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8412 if(HwInfo->jChipType == SIS_740) {
8413 SiS_LongDelay(SiS_Pr,1);
8414 SiS_GenericDelay(SiS_Pr,0x16ff);
8415 SiS_SetCH701x(SiS_Pr,0xac76);
8416 SiS_SetCH701x(SiS_Pr,0x0066);
8417 } else {
8418 SiS_LongDelay(SiS_Pr,2);
8419 temp = SiS_GetCH701x(SiS_Pr,0x76);
8420 temp &= 0xfc;
8421 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
8422 SiS_SetCH701x(SiS_Pr,0x0066);
8423 }
8424 }
8425 }
8426
8427 static void
SiS_ChrontelResetDB(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)8428 SiS_ChrontelResetDB(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8429 {
8430 USHORT temp;
8431
8432 if(HwInfo->jChipType == SIS_740) {
8433
8434 temp = SiS_GetCH701x(SiS_Pr,0x4a); /* Version ID */
8435 temp &= 0x01;
8436 if(!temp) {
8437
8438 if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo)) {
8439 temp = SiS_GetCH701x(SiS_Pr,0x49);
8440 SiS_SetCH701x(SiS_Pr,0x3e49);
8441 }
8442 /* Reset Chrontel 7019 datapath */
8443 SiS_SetCH701x(SiS_Pr,0x1048);
8444 SiS_LongDelay(SiS_Pr,1);
8445 SiS_SetCH701x(SiS_Pr,0x1848);
8446
8447 if(SiS_WeHaveBacklightCtrl(SiS_Pr, HwInfo)) {
8448 SiS_ChrontelResetVSync(SiS_Pr);
8449 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x49);
8450 }
8451
8452 } else {
8453
8454 /* Clear/set/clear GPIO */
8455 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8456 temp &= 0xef;
8457 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
8458 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8459 temp |= 0x10;
8460 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
8461 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8462 temp &= 0xef;
8463 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
8464 temp = SiS_GetCH701x(SiS_Pr,0x61);
8465 if(!temp) {
8466 SiS_SetCH701xForLCD(SiS_Pr, HwInfo);
8467 }
8468 }
8469
8470 } else { /* 650 */
8471 /* Reset Chrontel 7019 datapath */
8472 SiS_SetCH701x(SiS_Pr,0x1048);
8473 SiS_LongDelay(SiS_Pr,1);
8474 SiS_SetCH701x(SiS_Pr,0x1848);
8475 }
8476 }
8477
8478 void
SiS_ChrontelInitTVVSync(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)8479 SiS_ChrontelInitTVVSync(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8480 {
8481 USHORT temp;
8482
8483 if(HwInfo->jChipType == SIS_740) {
8484
8485 if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo)) {
8486 SiS_ChrontelResetVSync(SiS_Pr);
8487 }
8488
8489 } else {
8490
8491 SiS_SetCH701x(SiS_Pr,0xaf76); /* Power up LVDS block */
8492 temp = SiS_GetCH701x(SiS_Pr,0x49);
8493 temp &= 1;
8494 if(temp != 1) { /* TV block powered? (0 = yes, 1 = no) */
8495 temp = SiS_GetCH701x(SiS_Pr,0x47);
8496 temp &= 0x70;
8497 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47); /* enable VSYNC */
8498 SiS_LongDelay(SiS_Pr,3);
8499 temp = SiS_GetCH701x(SiS_Pr,0x47);
8500 temp |= 0x80;
8501 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47); /* disable VSYNC */
8502 }
8503
8504 }
8505 }
8506
8507 static void
SiS_ChrontelDoSomething3(SiS_Private * SiS_Pr,USHORT ModeNo,PSIS_HW_INFO HwInfo)8508 SiS_ChrontelDoSomething3(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_INFO HwInfo)
8509 {
8510 USHORT temp,temp1;
8511
8512 if(HwInfo->jChipType == SIS_740) {
8513
8514 temp = SiS_GetCH701x(SiS_Pr,0x61);
8515 if(temp < 1) {
8516 temp++;
8517 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61);
8518 }
8519 SiS_SetCH701x(SiS_Pr,0x4566); /* Panel power on */
8520 SiS_SetCH701x(SiS_Pr,0xaf76); /* All power on */
8521 SiS_LongDelay(SiS_Pr,1);
8522 SiS_GenericDelay(SiS_Pr,0x16ff);
8523
8524 } else { /* 650 */
8525
8526 temp1 = 0;
8527 temp = SiS_GetCH701x(SiS_Pr,0x61);
8528 if(temp < 2) {
8529 temp++;
8530 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61);
8531 temp1 = 1;
8532 }
8533 SiS_SetCH701x(SiS_Pr,0xac76);
8534 temp = SiS_GetCH701x(SiS_Pr,0x66);
8535 temp |= 0x5f;
8536 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
8537 if(ModeNo > 0x13) {
8538 if(SiS_WeHaveBacklightCtrl(SiS_Pr, HwInfo)) {
8539 SiS_GenericDelay(SiS_Pr,0x3ff);
8540 } else {
8541 SiS_GenericDelay(SiS_Pr,0x2ff);
8542 }
8543 } else {
8544 if(!temp1)
8545 SiS_GenericDelay(SiS_Pr,0x2ff);
8546 }
8547 temp = SiS_GetCH701x(SiS_Pr,0x76);
8548 temp |= 0x03;
8549 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
8550 temp = SiS_GetCH701x(SiS_Pr,0x66);
8551 temp &= 0x7f;
8552 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
8553 SiS_LongDelay(SiS_Pr,1);
8554
8555 }
8556 }
8557
8558 static void
SiS_ChrontelDoSomething2(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)8559 SiS_ChrontelDoSomething2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8560 {
8561 USHORT temp,tempcl,tempch;
8562
8563 SiS_LongDelay(SiS_Pr, 1);
8564 tempcl = 3;
8565 tempch = 0;
8566
8567 do {
8568 temp = SiS_GetCH701x(SiS_Pr,0x66);
8569 temp &= 0x04; /* PLL stable? -> bail out */
8570 if(temp == 0x04) break;
8571
8572 if(HwInfo->jChipType == SIS_740) {
8573 /* Power down LVDS output, PLL normal operation */
8574 SiS_SetCH701x(SiS_Pr,0xac76);
8575 }
8576
8577 SiS_SetCH701xForLCD(SiS_Pr,HwInfo);
8578
8579 if(tempcl == 0) {
8580 if(tempch == 3) break;
8581 SiS_ChrontelResetDB(SiS_Pr,HwInfo);
8582 tempcl = 3;
8583 tempch++;
8584 }
8585 tempcl--;
8586 temp = SiS_GetCH701x(SiS_Pr,0x76);
8587 temp &= 0xfb; /* Reset PLL */
8588 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
8589 SiS_LongDelay(SiS_Pr,2);
8590 temp = SiS_GetCH701x(SiS_Pr,0x76);
8591 temp |= 0x04; /* PLL normal operation */
8592 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
8593 if(HwInfo->jChipType == SIS_740) {
8594 SiS_SetCH701x(SiS_Pr,0xe078); /* PLL loop filter */
8595 } else {
8596 SiS_SetCH701x(SiS_Pr,0x6078);
8597 }
8598 SiS_LongDelay(SiS_Pr,2);
8599 } while(0);
8600
8601 SiS_SetCH701x(SiS_Pr,0x0077); /* MV? */
8602 }
8603
8604 void
SiS_ChrontelDoSomething1(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)8605 SiS_ChrontelDoSomething1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8606 {
8607 USHORT temp;
8608
8609 temp = SiS_GetCH701x(SiS_Pr,0x03);
8610 temp |= 0x80; /* Set datapath 1 to TV */
8611 temp &= 0xbf; /* Set datapath 2 to LVDS */
8612 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x03);
8613
8614 if(HwInfo->jChipType == SIS_740) {
8615
8616 temp = SiS_GetCH701x(SiS_Pr,0x1c);
8617 temp &= 0xfb; /* Normal XCLK phase */
8618 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c);
8619
8620 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8621
8622 temp = SiS_GetCH701x(SiS_Pr,0x64);
8623 temp |= 0x40; /* ? Bit not defined */
8624 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x64);
8625
8626 temp = SiS_GetCH701x(SiS_Pr,0x03);
8627 temp &= 0x3f; /* D1 input to both LVDS and TV */
8628 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x03);
8629
8630 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) {
8631 SiS_SetCH701x(SiS_Pr,0x4063); /* LVDS off */
8632 SiS_LongDelay(SiS_Pr, 1);
8633 SiS_SetCH701x(SiS_Pr,0x0063); /* LVDS on */
8634 SiS_ChrontelResetDB(SiS_Pr, HwInfo);
8635 SiS_ChrontelDoSomething2(SiS_Pr, HwInfo);
8636 SiS_ChrontelDoSomething3(SiS_Pr, 0, HwInfo);
8637 } else {
8638 temp = SiS_GetCH701x(SiS_Pr,0x66);
8639 if(temp != 0x45) {
8640 SiS_ChrontelResetDB(SiS_Pr, HwInfo);
8641 SiS_ChrontelDoSomething2(SiS_Pr, HwInfo);
8642 SiS_ChrontelDoSomething3(SiS_Pr, 0, HwInfo);
8643 }
8644 }
8645
8646 } else { /* 650 */
8647
8648 SiS_ChrontelResetDB(SiS_Pr,HwInfo);
8649 SiS_ChrontelDoSomething2(SiS_Pr,HwInfo);
8650 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34);
8651 SiS_ChrontelDoSomething3(SiS_Pr,temp,HwInfo);
8652 SiS_SetCH701x(SiS_Pr,0xaf76); /* All power on, LVDS normal operation */
8653
8654 }
8655
8656 }
8657 #endif /* 315 series */
8658
8659 /*********************************************/
8660 /* MAIN: SET CRT2 REGISTER GROUP */
8661 /*********************************************/
8662
8663 BOOLEAN
SiS_SetCRT2Group(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,USHORT ModeNo)8664 SiS_SetCRT2Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
8665 {
8666 #ifdef SIS300
8667 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
8668 #endif
8669 USHORT ModeIdIndex, RefreshRateTableIndex;
8670 #if 0
8671 USHORT temp;
8672 #endif
8673
8674 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
8675
8676 if(!SiS_Pr->UseCustomMode) {
8677 SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex);
8678 } else {
8679 ModeIdIndex = 0;
8680 }
8681
8682 /* Used for shifting CR33 */
8683 SiS_Pr->SiS_SelectCRT2Rate = 4;
8684
8685 SiS_UnLockCRT2(SiS_Pr, HwInfo);
8686
8687 RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
8688
8689 SiS_SaveCRT2Info(SiS_Pr,ModeNo);
8690
8691 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8692 SiS_DisableBridge(SiS_Pr,HwInfo);
8693 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (HwInfo->jChipType == SIS_730)) {
8694 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,0x80);
8695 }
8696 SiS_SetCRT2ModeRegs(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
8697 }
8698
8699 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
8700 SiS_LockCRT2(SiS_Pr, HwInfo);
8701 SiS_DisplayOn(SiS_Pr);
8702 return TRUE;
8703 }
8704
8705 SiS_GetCRT2Data(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
8706
8707 /* Set up Panel Link for LVDS and LCDA */
8708 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
8709 if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
8710 ((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ||
8711 ((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) ) {
8712 SiS_GetLVDSDesData(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
8713 }
8714
8715 #ifdef LINUX_XF86
8716 #ifdef TWDEBUG
8717 xf86DrvMsg(0, X_INFO, "(init301: LCDHDES 0x%03x LCDVDES 0x%03x)\n", SiS_Pr->SiS_LCDHDES, SiS_Pr->SiS_LCDVDES);
8718 xf86DrvMsg(0, X_INFO, "(init301: HDE 0x%03x VDE 0x%03x)\n", SiS_Pr->SiS_HDE, SiS_Pr->SiS_VDE);
8719 xf86DrvMsg(0, X_INFO, "(init301: VGAHDE 0x%03x VGAVDE 0x%03x)\n", SiS_Pr->SiS_VGAHDE, SiS_Pr->SiS_VGAVDE);
8720 xf86DrvMsg(0, X_INFO, "(init301: HT 0x%03x VT 0x%03x)\n", SiS_Pr->SiS_HT, SiS_Pr->SiS_VT);
8721 xf86DrvMsg(0, X_INFO, "(init301: VGAHT 0x%03x VGAVT 0x%03x)\n", SiS_Pr->SiS_VGAHT, SiS_Pr->SiS_VGAVT);
8722 #endif
8723 #endif
8724
8725 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8726 SiS_SetGroup1(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
8727 }
8728
8729 if(SiS_Pr->SiS_VBType & VB_SISVB) {
8730
8731 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8732
8733 SiS_SetGroup2(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
8734 #ifdef SIS315H
8735 SiS_SetGroup2_C_ELV(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
8736 #endif
8737 SiS_SetGroup3(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
8738 SiS_SetGroup4(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
8739 #ifdef SIS315H
8740 SiS_SetGroup4_C_ELV(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
8741 #endif
8742 SiS_SetGroup5(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
8743
8744 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex, HwInfo);
8745
8746 /* For 301BDH (Panel link initialization): */
8747 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
8748 if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) {
8749 if(!((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10)))) {
8750 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
8751 SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,
8752 RefreshRateTableIndex,HwInfo);
8753 }
8754 }
8755 }
8756 SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,
8757 RefreshRateTableIndex,HwInfo);
8758 }
8759 }
8760
8761 } else {
8762
8763 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex, HwInfo);
8764
8765 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
8766 SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwInfo);
8767 }
8768
8769 SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwInfo);
8770
8771 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8772 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
8773 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
8774 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8775 #ifdef SIS315H
8776 SiS_SetCH701xForLCD(SiS_Pr,HwInfo);
8777 #endif
8778 }
8779 }
8780 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8781 SiS_SetCHTVReg(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8782 }
8783 }
8784 }
8785
8786 }
8787
8788 #ifdef SIS300
8789 if(HwInfo->jChipType < SIS_315H) {
8790 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8791 if(SiS_Pr->SiS_UseOEM) {
8792 if((SiS_Pr->SiS_UseROM) && (SiS_Pr->SiS_UseOEM == -1)) {
8793 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
8794 SiS_OEM300Setting(SiS_Pr,HwInfo,ModeNo,ModeIdIndex,
8795 RefreshRateTableIndex);
8796 }
8797 } else {
8798 SiS_OEM300Setting(SiS_Pr,HwInfo,ModeNo,ModeIdIndex,
8799 RefreshRateTableIndex);
8800 }
8801 }
8802 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
8803 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
8804 (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
8805 SetOEMLCDData2(SiS_Pr, HwInfo, ModeNo, ModeIdIndex,RefreshRateTableIndex);
8806 }
8807 if(HwInfo->jChipType == SIS_730) {
8808 SiS_DisplayOn(SiS_Pr);
8809 }
8810 }
8811 }
8812 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
8813 if(HwInfo->jChipType != SIS_730) {
8814 SiS_DisplayOn(SiS_Pr);
8815 }
8816 }
8817 }
8818 #endif
8819
8820 #ifdef SIS315H
8821 if(HwInfo->jChipType >= SIS_315H) {
8822 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8823 if(HwInfo->jChipType < SIS_661) {
8824 SiS_FinalizeLCD(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
8825 SiS_OEM310Setting(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
8826 } else {
8827 SiS_OEM661Setting(SiS_Pr, HwInfo, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8828 }
8829 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40);
8830 }
8831 }
8832 #endif
8833
8834 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8835 SiS_EnableBridge(SiS_Pr, HwInfo);
8836 }
8837
8838 SiS_DisplayOn(SiS_Pr);
8839
8840 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
8841 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8842 /* Disable LCD panel when using TV */
8843 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFF,0x0C);
8844 } else {
8845 /* Disable TV when using LCD */
8846 SiS_SetCH70xxANDOR(SiS_Pr,0x010E,0xF8);
8847 }
8848 }
8849
8850 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8851 SiS_LockCRT2(SiS_Pr,HwInfo);
8852 }
8853
8854 return TRUE;
8855 }
8856
8857
8858 /*********************************************/
8859 /* ENABLE/DISABLE LCD BACKLIGHT (SIS) */
8860 /*********************************************/
8861
8862 void
SiS_SiS30xBLOn(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)8863 SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8864 {
8865 /* Switch on LCD backlight on SiS30xLV */
8866 SiS_DDC2Delay(SiS_Pr,0xff00);
8867 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
8868 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
8869 SiS_WaitVBRetrace(SiS_Pr,HwInfo);
8870 }
8871 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x01)) {
8872 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
8873 }
8874 }
8875
8876 void
SiS_SiS30xBLOff(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)8877 SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8878 {
8879 /* Switch off LCD backlight on SiS30xLV */
8880 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
8881 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
8882 SiS_DDC2Delay(SiS_Pr,0xe000);
8883 }
8884
8885 /*********************************************/
8886 /* DDC RELATED FUNCTIONS */
8887 /*********************************************/
8888
8889 static void
SiS_SetupDDCN(SiS_Private * SiS_Pr)8890 SiS_SetupDDCN(SiS_Private *SiS_Pr)
8891 {
8892 SiS_Pr->SiS_DDC_NData = ~SiS_Pr->SiS_DDC_Data;
8893 SiS_Pr->SiS_DDC_NClk = ~SiS_Pr->SiS_DDC_Clk;
8894 if((SiS_Pr->SiS_DDC_Index == 0x11) && (SiS_Pr->SiS_SensibleSR11)) {
8895 SiS_Pr->SiS_DDC_NData &= 0x0f;
8896 SiS_Pr->SiS_DDC_NClk &= 0x0f;
8897 }
8898 }
8899
8900 #ifdef SIS300
8901 static UCHAR *
SiS_SetTrumpBlockLoop(SiS_Private * SiS_Pr,UCHAR * dataptr)8902 SiS_SetTrumpBlockLoop(SiS_Private *SiS_Pr, UCHAR *dataptr)
8903 {
8904 int i, j, num;
8905 USHORT tempah,temp;
8906 UCHAR *mydataptr;
8907
8908 for(i=0; i<20; i++) { /* Do 20 attempts to write */
8909 mydataptr = dataptr;
8910 num = *mydataptr++;
8911 if(!num) return mydataptr;
8912 if(i) {
8913 SiS_SetStop(SiS_Pr);
8914 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT*2);
8915 }
8916 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
8917 tempah = SiS_Pr->SiS_DDC_DeviceAddr;
8918 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write DAB (S0=0=write) */
8919 if(temp) continue; /* (ERROR: no ack) */
8920 tempah = *mydataptr++;
8921 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write register number */
8922 if(temp) continue; /* (ERROR: no ack) */
8923 for(j=0; j<num; j++) {
8924 tempah = *mydataptr++;
8925 temp = SiS_WriteDDC2Data(SiS_Pr,tempah);/* Write DAB (S0=0=write) */
8926 if(temp) break;
8927 }
8928 if(temp) continue;
8929 if(SiS_SetStop(SiS_Pr)) continue;
8930 return mydataptr;
8931 }
8932 return NULL;
8933 }
8934
8935 static BOOLEAN
SiS_SetTrumpionBlock(SiS_Private * SiS_Pr,UCHAR * dataptr)8936 SiS_SetTrumpionBlock(SiS_Private *SiS_Pr, UCHAR *dataptr)
8937 {
8938 SiS_Pr->SiS_DDC_DeviceAddr = 0xF0; /* DAB (Device Address Byte) */
8939 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
8940 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
8941 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
8942 SiS_SetupDDCN(SiS_Pr);
8943
8944 SiS_SetSwitchDDC2(SiS_Pr);
8945
8946 while(*dataptr) {
8947 dataptr = SiS_SetTrumpBlockLoop(SiS_Pr, dataptr);
8948 if(!dataptr) return FALSE;
8949 }
8950 #ifdef TWDEBUG
8951 xf86DrvMsg(0, X_INFO, "Trumpion block success\n");
8952 #endif
8953 return TRUE;
8954 }
8955 #endif
8956
8957 /* The Chrontel 700x is connected to the 630/730 via
8958 * the 630/730's DDC/I2C port.
8959 *
8960 * On 630(S)T chipset, the index changed from 0x11 to
8961 * 0x0a, possibly for working around the DDC problems
8962 */
8963
8964 static BOOLEAN
SiS_SetChReg(SiS_Private * SiS_Pr,USHORT tempbx,USHORT myor)8965 SiS_SetChReg(SiS_Private *SiS_Pr, USHORT tempbx, USHORT myor)
8966 {
8967 USHORT tempah,temp,i;
8968
8969 for(i=0; i<20; i++) { /* Do 20 attempts to write */
8970 if(i) {
8971 SiS_SetStop(SiS_Pr);
8972 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
8973 }
8974 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
8975 tempah = SiS_Pr->SiS_DDC_DeviceAddr;
8976 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write DAB (S0=0=write) */
8977 if(temp) continue; /* (ERROR: no ack) */
8978 tempah = tempbx & 0x00FF; /* Write RAB */
8979 tempah |= myor; /* (700x: set bit 7, see datasheet) */
8980 temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
8981 if(temp) continue; /* (ERROR: no ack) */
8982 tempah = (tempbx & 0xFF00) >> 8;
8983 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write data */
8984 if(temp) continue; /* (ERROR: no ack) */
8985 if(SiS_SetStop(SiS_Pr)) continue; /* Set stop condition */
8986 SiS_Pr->SiS_ChrontelInit = 1;
8987 return TRUE;
8988 }
8989 return FALSE;
8990 }
8991
8992 #ifdef SIS300
8993 /* Write Trumpion register */
8994 void
SiS_SetTrumpReg(SiS_Private * SiS_Pr,USHORT tempbx)8995 SiS_SetTrumpReg(SiS_Private *SiS_Pr, USHORT tempbx)
8996 {
8997 SiS_Pr->SiS_DDC_DeviceAddr = 0xF0; /* DAB (Device Address Byte) */
8998 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
8999 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
9000 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
9001 SiS_SetupDDCN(SiS_Pr);
9002 SiS_SetChReg(SiS_Pr, tempbx, 0);
9003 }
9004 #endif
9005
9006 /* Write to Chrontel 700x */
9007 /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
9008 void
SiS_SetCH700x(SiS_Private * SiS_Pr,USHORT tempbx)9009 SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempbx)
9010 {
9011 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */
9012
9013 if(!(SiS_Pr->SiS_ChrontelInit)) {
9014 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9015 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
9016 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
9017 SiS_SetupDDCN(SiS_Pr);
9018 }
9019
9020 if( (!(SiS_SetChReg(SiS_Pr, tempbx, 0x80))) &&
9021 (!(SiS_Pr->SiS_ChrontelInit)) ) {
9022 SiS_Pr->SiS_DDC_Index = 0x0a; /* Bit 7 = SC; Bit 6 = SD */
9023 SiS_Pr->SiS_DDC_Data = 0x80; /* Bitmask in IndexReg for Data */
9024 SiS_Pr->SiS_DDC_Clk = 0x40; /* Bitmask in IndexReg for Clk */
9025 SiS_SetupDDCN(SiS_Pr);
9026
9027 SiS_SetChReg(SiS_Pr, tempbx, 0x80);
9028 }
9029 }
9030
9031 /* Write to Chrontel 701x */
9032 /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
9033 void
SiS_SetCH701x(SiS_Private * SiS_Pr,USHORT tempbx)9034 SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempbx)
9035 {
9036 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9037 SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */
9038 SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */
9039 SiS_SetupDDCN(SiS_Pr);
9040 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */
9041 SiS_SetChReg(SiS_Pr, tempbx, 0);
9042 }
9043
9044 void
SiS_SetCH70xx(SiS_Private * SiS_Pr,USHORT tempbx)9045 SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
9046 {
9047 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
9048 SiS_SetCH700x(SiS_Pr,tempbx);
9049 else
9050 SiS_SetCH701x(SiS_Pr,tempbx);
9051 }
9052
9053 static USHORT
SiS_GetChReg(SiS_Private * SiS_Pr,USHORT myor)9054 SiS_GetChReg(SiS_Private *SiS_Pr, USHORT myor)
9055 {
9056 USHORT tempah,temp,i;
9057
9058 for(i=0; i<20; i++) { /* Do 20 attempts to read */
9059 if(i) {
9060 SiS_SetStop(SiS_Pr);
9061 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9062 }
9063 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
9064 tempah = SiS_Pr->SiS_DDC_DeviceAddr;
9065 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write DAB (S0=0=write) */
9066 if(temp) continue; /* (ERROR: no ack) */
9067 tempah = SiS_Pr->SiS_DDC_ReadAddr | myor; /* Write RAB (700x: | 0x80) */
9068 temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
9069 if(temp) continue; /* (ERROR: no ack) */
9070 if (SiS_SetStart(SiS_Pr)) continue; /* Re-start */
9071 tempah = SiS_Pr->SiS_DDC_DeviceAddr | 0x01;/* DAB | 0x01 = Read */
9072 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* DAB (S0=1=read) */
9073 if(temp) continue; /* (ERROR: no ack) */
9074 tempah = SiS_ReadDDC2Data(SiS_Pr,tempah); /* Read byte */
9075 if(SiS_SetStop(SiS_Pr)) continue; /* Stop condition */
9076 SiS_Pr->SiS_ChrontelInit = 1;
9077 return(tempah);
9078 }
9079 return 0xFFFF;
9080 }
9081
9082 #ifdef SIS300
9083 /* Read from Trumpion */
9084 USHORT
SiS_GetTrumpReg(SiS_Private * SiS_Pr,USHORT tempbx)9085 SiS_GetTrumpReg(SiS_Private *SiS_Pr, USHORT tempbx)
9086 {
9087 SiS_Pr->SiS_DDC_DeviceAddr = 0xF0; /* DAB */
9088 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9089 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
9090 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
9091 SiS_SetupDDCN(SiS_Pr);
9092 SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9093 return(SiS_GetChReg(SiS_Pr,0));
9094 }
9095 #endif
9096
9097 /* Read from Chrontel 700x */
9098 /* Parameter is [Register no (S7-S0)] */
9099 USHORT
SiS_GetCH700x(SiS_Private * SiS_Pr,USHORT tempbx)9100 SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempbx)
9101 {
9102 USHORT result;
9103
9104 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */
9105
9106 if(!(SiS_Pr->SiS_ChrontelInit)) {
9107 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9108 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
9109 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
9110 SiS_SetupDDCN(SiS_Pr);
9111 }
9112
9113 SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9114
9115 if( ((result = SiS_GetChReg(SiS_Pr,0x80)) == 0xFFFF) &&
9116 (!SiS_Pr->SiS_ChrontelInit) ) {
9117
9118 SiS_Pr->SiS_DDC_Index = 0x0a;
9119 SiS_Pr->SiS_DDC_Data = 0x80;
9120 SiS_Pr->SiS_DDC_Clk = 0x40;
9121 SiS_SetupDDCN(SiS_Pr);
9122
9123 result = SiS_GetChReg(SiS_Pr,0x80);
9124 }
9125 return(result);
9126 }
9127
9128 /* Read from Chrontel 701x */
9129 /* Parameter is [Register no (S7-S0)] */
9130 USHORT
SiS_GetCH701x(SiS_Private * SiS_Pr,USHORT tempbx)9131 SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempbx)
9132 {
9133 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9134 SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */
9135 SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */
9136 SiS_SetupDDCN(SiS_Pr);
9137 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */
9138
9139 SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9140
9141 return(SiS_GetChReg(SiS_Pr,0));
9142 }
9143
9144 /* Read from Chrontel 70xx */
9145 /* Parameter is [Register no (S7-S0)] */
9146 USHORT
SiS_GetCH70xx(SiS_Private * SiS_Pr,USHORT tempbx)9147 SiS_GetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
9148 {
9149 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
9150 return(SiS_GetCH700x(SiS_Pr, tempbx));
9151 else
9152 return(SiS_GetCH701x(SiS_Pr, tempbx));
9153 }
9154
9155 /* Our own DDC functions */
9156 USHORT
SiS_InitDDCRegs(SiS_Private * SiS_Pr,unsigned long VBFlags,int VGAEngine,USHORT adaptnum,USHORT DDCdatatype,BOOLEAN checkcr32)9157 SiS_InitDDCRegs(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
9158 USHORT adaptnum, USHORT DDCdatatype, BOOLEAN checkcr32)
9159 {
9160 unsigned char ddcdtype[] = { 0xa0, 0xa0, 0xa0, 0xa2, 0xa6 };
9161 unsigned char flag, cr32;
9162 USHORT temp = 0, myadaptnum = adaptnum;
9163
9164 if(adaptnum != 0) {
9165 if(!(VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) return 0xFFFF;
9166 if((VBFlags & VB_30xBDH) && (adaptnum == 1)) return 0xFFFF;
9167 }
9168
9169 /* adapternum for SiS bridges: 0 = CRT1, 1 = LCD, 2 = VGA2 */
9170
9171 SiS_Pr->SiS_ChrontelInit = 0; /* force re-detection! */
9172
9173 SiS_Pr->SiS_DDC_SecAddr = 0;
9174 SiS_Pr->SiS_DDC_DeviceAddr = ddcdtype[DDCdatatype];
9175 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_P3c4;
9176 SiS_Pr->SiS_DDC_Index = 0x11;
9177 flag = 0xff;
9178
9179 cr32 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x32);
9180
9181 #if 0
9182 if(VBFlags & VB_SISBRIDGE) {
9183 if(myadaptnum == 0) {
9184 if(!(cr32 & 0x20)) {
9185 myadaptnum = 2;
9186 if(!(cr32 & 0x10)) {
9187 myadaptnum = 1;
9188 if(!(cr32 & 0x08)) {
9189 myadaptnum = 0;
9190 }
9191 }
9192 }
9193 }
9194 }
9195 #endif
9196
9197 if(VGAEngine == SIS_300_VGA) { /* 300 series */
9198
9199 if(myadaptnum != 0) {
9200 flag = 0;
9201 if(VBFlags & VB_SISBRIDGE) {
9202 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9203 SiS_Pr->SiS_DDC_Index = 0x0f;
9204 }
9205 }
9206
9207 if(!(VBFlags & VB_301)) {
9208 if((cr32 & 0x80) && (checkcr32)) {
9209 if(myadaptnum >= 1) {
9210 if(!(cr32 & 0x08)) {
9211 myadaptnum = 1;
9212 if(!(cr32 & 0x10)) return 0xFFFF;
9213 }
9214 }
9215 }
9216 }
9217
9218 temp = 4 - (myadaptnum * 2);
9219 if(flag) temp = 0;
9220
9221 } else { /* 315/330 series */
9222
9223 /* here we simplify: 0 = CRT1, 1 = CRT2 (VGA, LCD) */
9224
9225 if(VBFlags & VB_SISBRIDGE) {
9226 if(myadaptnum == 2) {
9227 myadaptnum = 1;
9228 }
9229 }
9230
9231 if(myadaptnum == 1) {
9232 flag = 0;
9233 if(VBFlags & VB_SISBRIDGE) {
9234 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9235 SiS_Pr->SiS_DDC_Index = 0x0f;
9236 }
9237 }
9238
9239 if((cr32 & 0x80) && (checkcr32)) {
9240 if(myadaptnum >= 1) {
9241 if(!(cr32 & 0x08)) {
9242 myadaptnum = 1;
9243 if(!(cr32 & 0x10)) return 0xFFFF;
9244 }
9245 }
9246 }
9247
9248 temp = myadaptnum;
9249 if(myadaptnum == 1) {
9250 temp = 0;
9251 if(VBFlags & VB_LVDS) flag = 0xff;
9252 }
9253
9254 if(flag) temp = 0;
9255 }
9256
9257 SiS_Pr->SiS_DDC_Data = 0x02 << temp;
9258 SiS_Pr->SiS_DDC_Clk = 0x01 << temp;
9259
9260 SiS_SetupDDCN(SiS_Pr);
9261
9262 #ifdef TWDEBUG
9263 xf86DrvMsg(0, X_INFO, "DDC Port %x Index %x Shift %d\n",
9264 SiS_Pr->SiS_DDC_Port, SiS_Pr->SiS_DDC_Index, temp);
9265 #endif
9266
9267 return 0;
9268 }
9269
9270 USHORT
SiS_WriteDABDDC(SiS_Private * SiS_Pr)9271 SiS_WriteDABDDC(SiS_Private *SiS_Pr)
9272 {
9273 if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9274 if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr)) {
9275 return 0xFFFF;
9276 }
9277 if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_SecAddr)) {
9278 return 0xFFFF;
9279 }
9280 return(0);
9281 }
9282
9283 USHORT
SiS_PrepareReadDDC(SiS_Private * SiS_Pr)9284 SiS_PrepareReadDDC(SiS_Private *SiS_Pr)
9285 {
9286 if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9287 if(SiS_WriteDDC2Data(SiS_Pr, (SiS_Pr->SiS_DDC_DeviceAddr | 0x01))) {
9288 return 0xFFFF;
9289 }
9290 return(0);
9291 }
9292
9293 USHORT
SiS_PrepareDDC(SiS_Private * SiS_Pr)9294 SiS_PrepareDDC(SiS_Private *SiS_Pr)
9295 {
9296 if(SiS_WriteDABDDC(SiS_Pr)) SiS_WriteDABDDC(SiS_Pr);
9297 if(SiS_PrepareReadDDC(SiS_Pr)) return(SiS_PrepareReadDDC(SiS_Pr));
9298 return(0);
9299 }
9300
9301 void
SiS_SendACK(SiS_Private * SiS_Pr,USHORT yesno)9302 SiS_SendACK(SiS_Private *SiS_Pr, USHORT yesno)
9303 {
9304 SiS_SetSCLKLow(SiS_Pr);
9305 if(yesno) {
9306 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9307 SiS_Pr->SiS_DDC_Index,
9308 SiS_Pr->SiS_DDC_NData,
9309 SiS_Pr->SiS_DDC_Data);
9310 } else {
9311 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9312 SiS_Pr->SiS_DDC_Index,
9313 SiS_Pr->SiS_DDC_NData,
9314 0);
9315 }
9316 SiS_SetSCLKHigh(SiS_Pr);
9317 }
9318
9319 USHORT
SiS_DoProbeDDC(SiS_Private * SiS_Pr)9320 SiS_DoProbeDDC(SiS_Private *SiS_Pr)
9321 {
9322 unsigned char mask, value;
9323 USHORT temp, ret=0;
9324 BOOLEAN failed = FALSE;
9325
9326 SiS_SetSwitchDDC2(SiS_Pr);
9327 if(SiS_PrepareDDC(SiS_Pr)) {
9328 SiS_SetStop(SiS_Pr);
9329 #ifdef TWDEBUG
9330 xf86DrvMsg(0, X_INFO, "Probe: Prepare failed\n");
9331 #endif
9332 return(0xFFFF);
9333 }
9334 mask = 0xf0;
9335 value = 0x20;
9336 if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9337 temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
9338 SiS_SendACK(SiS_Pr, 0);
9339 if(temp == 0) {
9340 mask = 0xff;
9341 value = 0xff;
9342 } else {
9343 failed = TRUE;
9344 ret = 0xFFFF;
9345 #ifdef TWDEBUG
9346 xf86DrvMsg(0, X_INFO, "Probe: Read 1 failed\n");
9347 #endif
9348 }
9349 }
9350 if(failed == FALSE) {
9351 temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
9352 SiS_SendACK(SiS_Pr, 1);
9353 temp &= mask;
9354 if(temp == value) ret = 0;
9355 else {
9356 ret = 0xFFFF;
9357 #ifdef TWDEBUG
9358 xf86DrvMsg(0, X_INFO, "Probe: Read 2 failed\n");
9359 #endif
9360 if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9361 if(temp == 0x30) ret = 0;
9362 }
9363 }
9364 }
9365 SiS_SetStop(SiS_Pr);
9366 return(ret);
9367 }
9368
9369 USHORT
SiS_ProbeDDC(SiS_Private * SiS_Pr)9370 SiS_ProbeDDC(SiS_Private *SiS_Pr)
9371 {
9372 USHORT flag;
9373
9374 flag = 0x180;
9375 SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
9376 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x02;
9377 SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;
9378 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x08;
9379 SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;
9380 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x10;
9381 if(!(flag & 0x1a)) flag = 0;
9382 return(flag);
9383 }
9384
9385 USHORT
SiS_ReadDDC(SiS_Private * SiS_Pr,USHORT DDCdatatype,unsigned char * buffer)9386 SiS_ReadDDC(SiS_Private *SiS_Pr, USHORT DDCdatatype, unsigned char *buffer)
9387 {
9388 USHORT flag, length, i;
9389 unsigned char chksum,gotcha;
9390
9391 if(DDCdatatype > 4) return 0xFFFF;
9392
9393 flag = 0;
9394 SiS_SetSwitchDDC2(SiS_Pr);
9395 if(!(SiS_PrepareDDC(SiS_Pr))) {
9396 length = 127;
9397 if(DDCdatatype != 1) length = 255;
9398 chksum = 0;
9399 gotcha = 0;
9400 for(i=0; i<length; i++) {
9401 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
9402 chksum += buffer[i];
9403 gotcha |= buffer[i];
9404 SiS_SendACK(SiS_Pr, 0);
9405 }
9406 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
9407 chksum += buffer[i];
9408 SiS_SendACK(SiS_Pr, 1);
9409 if(gotcha) flag = (USHORT)chksum;
9410 else flag = 0xFFFF;
9411 } else {
9412 flag = 0xFFFF;
9413 }
9414 SiS_SetStop(SiS_Pr);
9415 return(flag);
9416 }
9417
9418 /* Our private DDC functions
9419
9420 It complies somewhat with the corresponding VESA function
9421 in arguments and return values.
9422
9423 Since this is probably called before the mode is changed,
9424 we use our pre-detected pSiS-values instead of SiS_Pr as
9425 regards chipset and video bridge type.
9426
9427 Arguments:
9428 adaptnum: 0=CRT1, 1=LCD, 2=VGA2
9429 CRT2 DDC is only supported on SiS301, 301B, 302B.
9430 DDCdatatype: 0=Probe, 1=EDID, 2=EDID+VDIF, 3=EDID V2 (P&D), 4=EDID V2 (FPDI-2)
9431 buffer: ptr to 256 data bytes which will be filled with read data.
9432
9433 Returns 0xFFFF if error, otherwise
9434 if DDCdatatype > 0: Returns 0 if reading OK (included a correct checksum)
9435 if DDCdatatype = 0: Returns supported DDC modes
9436
9437 */
9438 USHORT
SiS_HandleDDC(SiS_Private * SiS_Pr,unsigned long VBFlags,int VGAEngine,USHORT adaptnum,USHORT DDCdatatype,unsigned char * buffer)9439 SiS_HandleDDC(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
9440 USHORT adaptnum, USHORT DDCdatatype, unsigned char *buffer)
9441 {
9442 unsigned char sr1f,cr17=1;
9443 USHORT result;
9444
9445 if(adaptnum > 2) return 0xFFFF;
9446 if(DDCdatatype > 4) return 0xFFFF;
9447 if((!(VBFlags & VB_VIDEOBRIDGE)) && (adaptnum > 0)) return 0xFFFF;
9448 if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, FALSE) == 0xFFFF) return 0xFFFF;
9449
9450 sr1f = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f);
9451 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1f,0x3f,0x04);
9452 if(VGAEngine == SIS_300_VGA) {
9453 cr17 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80;
9454 if(!cr17) {
9455 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x17,0x80);
9456 SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x01);
9457 SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x03);
9458 }
9459 }
9460 if((sr1f) || (!cr17)) {
9461 SiS_WaitRetrace1(SiS_Pr);
9462 SiS_WaitRetrace1(SiS_Pr);
9463 SiS_WaitRetrace1(SiS_Pr);
9464 SiS_WaitRetrace1(SiS_Pr);
9465 }
9466
9467 if(DDCdatatype == 0) {
9468 result = SiS_ProbeDDC(SiS_Pr);
9469 } else {
9470 result = SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer);
9471 }
9472 SiS_SetReg(SiS_Pr->SiS_P3c4,0x1f,sr1f);
9473 if(VGAEngine == SIS_300_VGA) {
9474 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x17,0x7f,cr17);
9475 }
9476 return result;
9477 }
9478
9479 #ifdef LINUX_XF86
9480
9481 static BOOLEAN
checkedid1(unsigned char * buffer)9482 checkedid1(unsigned char *buffer)
9483 {
9484 /* Check header */
9485 if((buffer[0] != 0x00) ||
9486 (buffer[1] != 0xff) ||
9487 (buffer[2] != 0xff) ||
9488 (buffer[3] != 0xff) ||
9489 (buffer[4] != 0xff) ||
9490 (buffer[5] != 0xff) ||
9491 (buffer[6] != 0xff) ||
9492 (buffer[7] != 0x00))
9493 return FALSE;
9494
9495 /* Check EDID version and revision */
9496 if((buffer[0x12] != 1) || (buffer[0x13] > 4)) return FALSE;
9497
9498 /* Check week of manufacture for sanity */
9499 if(buffer[0x10] > 53) return FALSE;
9500
9501 /* Check year of manufacture for sanity */
9502 if(buffer[0x11] > 40) return FALSE;
9503
9504 return TRUE;
9505 }
9506
9507 static BOOLEAN
checkedid2(unsigned char * buffer)9508 checkedid2(unsigned char *buffer)
9509 {
9510 USHORT year = buffer[6] | (buffer[7] << 8);
9511
9512 /* Check EDID version */
9513 if((buffer[0] & 0xf0) != 0x20) return FALSE;
9514
9515 /* Check week of manufacture for sanity */
9516 if(buffer[5] > 53) return FALSE;
9517
9518 /* Check year of manufacture for sanity */
9519 if((year != 0) && ((year < 1990) || (year > 2030))) return FALSE;
9520
9521 return TRUE;
9522 }
9523
9524 /* Sense the LCD parameters (CR36, CR37) via DDC */
9525 /* SiS30x(B) only */
9526 USHORT
SiS_SenseLCDDDC(SiS_Private * SiS_Pr,SISPtr pSiS)9527 SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS)
9528 {
9529 USHORT DDCdatatype, paneltype, flag, xres=0, yres=0;
9530 USHORT index, myindex, lumsize, numcodes;
9531 unsigned char cr37=0, seekcode;
9532 BOOLEAN checkexpand = FALSE;
9533 int retry, i;
9534 unsigned char buffer[256];
9535
9536 for(i=0; i<7; i++) SiS_Pr->CP_DataValid[i] = FALSE;
9537 SiS_Pr->CP_HaveCustomData = FALSE;
9538 SiS_Pr->CP_MaxX = SiS_Pr->CP_MaxY = SiS_Pr->CP_MaxClock = 0;
9539 SiS_Pr->CP_PreferredX = SiS_Pr->CP_PreferredY = 0;
9540 SiS_Pr->CP_PreferredIndex = -1;
9541
9542 if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) return 0;
9543 if(pSiS->VBFlags & VB_30xBDH) return 0;
9544
9545 if(SiS_InitDDCRegs(SiS_Pr, pSiS->VBFlags, pSiS->VGAEngine, 1, 0, FALSE) == 0xFFFF) return 0;
9546
9547 SiS_Pr->SiS_DDC_SecAddr = 0x00;
9548
9549 /* Probe supported DA's */
9550 flag = SiS_ProbeDDC(SiS_Pr);
9551 #ifdef TWDEBUG
9552 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO,
9553 "CRT2 DDC capabilities 0x%x\n", flag);
9554 #endif
9555 if(flag & 0x10) {
9556 SiS_Pr->SiS_DDC_DeviceAddr = 0xa6; /* EDID V2 (FP) */
9557 DDCdatatype = 4;
9558 } else if(flag & 0x08) {
9559 SiS_Pr->SiS_DDC_DeviceAddr = 0xa2; /* EDID V2 (P&D-D Monitor) */
9560 DDCdatatype = 3;
9561 } else if(flag & 0x02) {
9562 SiS_Pr->SiS_DDC_DeviceAddr = 0xa0; /* EDID V1 */
9563 DDCdatatype = 1;
9564 } else return 0; /* no DDC support (or no device attached) */
9565
9566 /* Read the entire EDID */
9567 retry = 2;
9568 do {
9569 if(SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer)) {
9570 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9571 "CRT2: DDC read failed (attempt %d), %s\n",
9572 (3-retry), (retry == 1) ? "giving up" : "retrying");
9573 retry--;
9574 if(retry == 0) return 0xFFFF;
9575 } else break;
9576 } while(1);
9577
9578 #ifdef TWDEBUG
9579 for(i=0; i<256; i+=16) {
9580 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9581 "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
9582 buffer[i], buffer[i+1], buffer[i+2], buffer[i+3],
9583 buffer[i+4], buffer[i+5], buffer[i+6], buffer[i+7],
9584 buffer[i+8], buffer[i+9], buffer[i+10], buffer[i+11],
9585 buffer[i+12], buffer[i+13], buffer[i+14], buffer[i+15]);
9586 }
9587 #endif
9588
9589 /* Analyze EDID and retrieve LCD panel information */
9590 paneltype = 0;
9591 switch(DDCdatatype) {
9592 case 1: /* Analyze EDID V1 */
9593 /* Catch a few clear cases: */
9594 if(!(checkedid1(buffer))) {
9595 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9596 "CRT2: EDID corrupt\n");
9597 return 0;
9598 }
9599
9600 if(!(buffer[0x14] & 0x80)) {
9601 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9602 "CRT2: Attached display expects analog input (0x%02x)\n",
9603 buffer[0x14]);
9604 return 0;
9605 }
9606
9607 if((buffer[0x18] & 0x18) != 0x08) {
9608 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9609 "CRT2: Attached display is not of RGB but of %s type (0x%02x)\n",
9610 ((buffer[0x18] & 0x18) == 0x00) ? "monochrome/greyscale" :
9611 ( ((buffer[0x18] & 0x18) == 0x10) ? "non-RGB multicolor" :
9612 "undefined"),
9613 buffer[0x18]);
9614 return 0;
9615 }
9616
9617 /* Now analyze the first Detailed Timing Block and see
9618 * if the preferred timing mode is stored there. If so,
9619 * check if this is a standard panel for which we already
9620 * know the timing.
9621 */
9622
9623 paneltype = Panel_Custom;
9624 checkexpand = FALSE;
9625
9626 if(buffer[0x18] & 0x02) {
9627
9628 xres = buffer[0x38] | ((buffer[0x3a] & 0xf0) << 4);
9629 yres = buffer[0x3b] | ((buffer[0x3d] & 0xf0) << 4);
9630
9631 SiS_Pr->CP_PreferredX = xres;
9632 SiS_Pr->CP_PreferredY = yres;
9633
9634 switch(xres) {
9635 #if 0 /* Treat as custom */
9636 case 800:
9637 if(yres == 600) {
9638 paneltype = Panel_800x600;
9639 checkexpand = TRUE;
9640 }
9641 break;
9642 #endif
9643 case 1024:
9644 if(yres == 768) {
9645 paneltype = Panel_1024x768;
9646 checkexpand = TRUE;
9647 }
9648 break;
9649 case 1280:
9650 if(yres == 1024) {
9651 paneltype = Panel_1280x1024;
9652 checkexpand = TRUE;
9653 } else if(yres == 960) {
9654 if(pSiS->VGAEngine == SIS_300_VGA) {
9655 paneltype = Panel300_1280x960;
9656 } else {
9657 paneltype = Panel310_1280x960;
9658 }
9659 } else if(yres == 768) {
9660 if( ((buffer[0x36] | (buffer[0x37] << 8)) == 8100) &&
9661 ((buffer[0x39] | ((buffer[0x3a] & 0x0f) << 8)) == (1688 - 1280)) &&
9662 ((buffer[0x3c] | ((buffer[0x3d] & 0x0f) << 8)) == (802 - 768)) ) {
9663 paneltype = Panel_1280x768;
9664 checkexpand = FALSE;
9665 cr37 |= 0x10;
9666 }
9667 }
9668 break;
9669 case 1400:
9670 if(pSiS->VGAEngine == SIS_315_VGA) {
9671 if(yres == 1050) {
9672 paneltype = Panel310_1400x1050;
9673 checkexpand = TRUE;
9674 }
9675 }
9676 break;
9677 #if 0 /* Treat this as custom, as we have no valid timing data yet */
9678 case 1600:
9679 if(pSiS->VGAEngine == SIS_315_VGA) {
9680 if(pSiS->VBFlags & VB_301C) {
9681 if(yres == 1200) {
9682 paneltype = Panel310_1600x1200;
9683 checkexpand = TRUE;
9684 }
9685 }
9686 }
9687 break;
9688 #endif
9689 }
9690
9691 if(paneltype != Panel_Custom) {
9692 if((buffer[0x47] & 0x18) == 0x18) {
9693 cr37 |= ((((buffer[0x47] & 0x06) ^ 0x06) << 5) | 0x20);
9694 } else {
9695 /* What now? There is no digital separate output timing... */
9696 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
9697 "CRT2: Unable to retrieve Sync polarity information\n");
9698 cr37 |= 0xc0; /* Default */
9699 }
9700 }
9701
9702 }
9703
9704 /* If we still don't know what panel this is, we take it
9705 * as a custom panel and derive the timing data from the
9706 * detailed timing blocks
9707 */
9708 if(paneltype == Panel_Custom) {
9709
9710 BOOLEAN havesync = FALSE;
9711 int i, temp, base = 0x36;
9712 unsigned long estpack;
9713 unsigned short estx[] = {
9714 720, 720, 640, 640, 640, 640, 800, 800,
9715 800, 800, 832,1024,1024,1024,1024,1280,
9716 1152
9717 };
9718 unsigned short esty[] = {
9719 400, 400, 480, 480, 480, 480, 600, 600,
9720 600, 600, 624, 768, 768, 768, 768,1024,
9721 870
9722 };
9723
9724 paneltype = 0;
9725 SiS_Pr->CP_Supports64048075 = TRUE;
9726
9727 /* Find the maximum resolution */
9728
9729 /* 1. From Established timings */
9730 estpack = (buffer[0x23] << 9) | (buffer[0x24] << 1) | ((buffer[0x25] >> 7) & 0x01);
9731 for(i=16; i>=0; i--) {
9732 if(estpack & (1 << i)) {
9733 if(estx[16 - i] > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = estx[16 - i];
9734 if(esty[16 - i] > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = esty[16 - i];
9735 }
9736 }
9737
9738 /* 2. From Standard Timings */
9739 for(i=0x26; i < 0x36; i+=2) {
9740 if((buffer[i] != 0x01) && (buffer[i+1] != 0x01)) {
9741 temp = (buffer[i] + 31) * 8;
9742 if(temp > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = temp;
9743 switch((buffer[i+1] & 0xc0) >> 6) {
9744 case 0x03: temp = temp * 9 / 16; break;
9745 case 0x02: temp = temp * 4 / 5; break;
9746 case 0x01: temp = temp * 3 / 4; break;
9747 }
9748 if(temp > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = temp;
9749 }
9750 }
9751
9752 /* Now extract the Detailed Timings and convert them into modes */
9753
9754 for(i = 0; i < 4; i++, base += 18) {
9755
9756 /* Is this a detailed timing block or a monitor descriptor? */
9757 if(buffer[base] || buffer[base+1] || buffer[base+2]) {
9758
9759 xres = buffer[base+2] | ((buffer[base+4] & 0xf0) << 4);
9760 yres = buffer[base+5] | ((buffer[base+7] & 0xf0) << 4);
9761
9762 SiS_Pr->CP_HDisplay[i] = xres;
9763 SiS_Pr->CP_HSyncStart[i] = xres + (buffer[base+8] | ((buffer[base+11] & 0xc0) << 2));
9764 SiS_Pr->CP_HSyncEnd[i] = SiS_Pr->CP_HSyncStart[i] + (buffer[base+9] | ((buffer[base+11] & 0x30) << 4));
9765 SiS_Pr->CP_HTotal[i] = xres + (buffer[base+3] | ((buffer[base+4] & 0x0f) << 8));
9766 SiS_Pr->CP_HBlankStart[i] = xres + 1;
9767 SiS_Pr->CP_HBlankEnd[i] = SiS_Pr->CP_HTotal[i];
9768
9769 SiS_Pr->CP_VDisplay[i] = yres;
9770 SiS_Pr->CP_VSyncStart[i] = yres + (((buffer[base+10] & 0xf0) >> 4) | ((buffer[base+11] & 0x0c) << 2));
9771 SiS_Pr->CP_VSyncEnd[i] = SiS_Pr->CP_VSyncStart[i] + ((buffer[base+10] & 0x0f) | ((buffer[base+11] & 0x03) << 4));
9772 SiS_Pr->CP_VTotal[i] = yres + (buffer[base+6] | ((buffer[base+7] & 0x0f) << 8));
9773 SiS_Pr->CP_VBlankStart[i] = yres + 1;
9774 SiS_Pr->CP_VBlankEnd[i] = SiS_Pr->CP_VTotal[i];
9775
9776 SiS_Pr->CP_Clock[i] = (buffer[base] | (buffer[base+1] << 8)) * 10;
9777
9778 SiS_Pr->CP_DataValid[i] = TRUE;
9779
9780 /* Sort out invalid timings, interlace and too high clocks */
9781 if((SiS_Pr->CP_HDisplay[i] & 7) ||
9782 (SiS_Pr->CP_HDisplay[i] > SiS_Pr->CP_HSyncStart[i]) ||
9783 (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HSyncEnd[i]) ||
9784 (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HTotal[i]) ||
9785 (SiS_Pr->CP_HSyncStart[i] >= SiS_Pr->CP_HSyncEnd[i]) ||
9786 (SiS_Pr->CP_HSyncStart[i] > SiS_Pr->CP_HTotal[i]) ||
9787 (SiS_Pr->CP_HSyncEnd[i] > SiS_Pr->CP_HTotal[i]) ||
9788 (SiS_Pr->CP_VDisplay[i] > SiS_Pr->CP_VSyncStart[i]) ||
9789 (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VSyncEnd[i]) ||
9790 (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VTotal[i]) ||
9791 (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VSyncEnd[i]) ||
9792 (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VTotal[i]) ||
9793 (SiS_Pr->CP_VSyncEnd[i] > SiS_Pr->CP_VTotal[i]) ||
9794 (((pSiS->VBFlags & VB_301C) && (SiS_Pr->CP_Clock[i] > 162500)) ||
9795 ((!(pSiS->VBFlags & VB_301C)) && (SiS_Pr->CP_Clock[i] > 108200))) ||
9796 (buffer[base+17] & 0x80)) {
9797
9798 SiS_Pr->CP_DataValid[i] = FALSE;
9799
9800 } else {
9801
9802 paneltype = Panel_Custom;
9803
9804 SiS_Pr->CP_HaveCustomData = TRUE;
9805
9806 if(xres > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = xres;
9807 if(yres > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = yres;
9808 if(SiS_Pr->CP_Clock[i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = SiS_Pr->CP_Clock[i];
9809
9810 if((SiS_Pr->CP_PreferredX == xres) && (SiS_Pr->CP_PreferredY == yres)) {
9811 SiS_Pr->CP_PreferredIndex = i;
9812 }
9813
9814 SiS_Pr->CP_Vendor = buffer[9] | (buffer[8] << 8);
9815 SiS_Pr->CP_Product = buffer[10] | (buffer[11] << 8);
9816
9817 /* By default we drive the LCD at 75Hz in 640x480 mode; if
9818 * the panel does not provide this mode, use 60hz
9819 */
9820 if(!(buffer[0x23] & 0x04)) SiS_Pr->CP_Supports64048075 = FALSE;
9821
9822 /* We must assume the panel can scale, since we have
9823 * no scaling data
9824 */
9825 checkexpand = FALSE;
9826 cr37 |= 0x10;
9827
9828 /* Extract the sync polarisation information. This only works
9829 * if the Flags indicate a digital separate output.
9830 */
9831 if((buffer[base+17] & 0x18) == 0x18) {
9832 SiS_Pr->CP_HSync_P[i] = (buffer[base+17] & 0x02) ? TRUE : FALSE;
9833 SiS_Pr->CP_VSync_P[i] = (buffer[base+17] & 0x04) ? TRUE : FALSE;
9834 SiS_Pr->CP_SyncValid[i] = TRUE;
9835 if(!havesync) {
9836 cr37 |= ((((buffer[base+17] & 0x06) ^ 0x06) << 5) | 0x20);
9837 havesync = TRUE;
9838 }
9839 } else {
9840 SiS_Pr->CP_SyncValid[i] = FALSE;
9841 }
9842 }
9843 }
9844 }
9845 if(!havesync) {
9846 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
9847 "CRT2: Unable to retrieve Sync polarity information\n");
9848 }
9849 }
9850
9851 if(paneltype && checkexpand) {
9852 /* If any of the Established low-res modes is supported, the
9853 * panel can scale automatically. For 800x600 panels, we only
9854 * check the even lower ones.
9855 */
9856 if(paneltype == Panel_800x600) {
9857 if(buffer[0x23] & 0xfc) cr37 |= 0x10;
9858 } else {
9859 if(buffer[0x23]) cr37 |= 0x10;
9860 }
9861 }
9862
9863 break;
9864
9865 case 3: /* Analyze EDID V2 */
9866 case 4:
9867 index = 0;
9868
9869 if(!(checkedid2(buffer))) {
9870 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9871 "CRT2: EDID corrupt\n");
9872 return 0;
9873 }
9874
9875 if((buffer[0x41] & 0x0f) == 0x03) {
9876 index = 0x42 + 3;
9877 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9878 "CRT2: Display supports TMDS input on primary interface\n");
9879 } else if((buffer[0x41] & 0xf0) == 0x30) {
9880 index = 0x46 + 3;
9881 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9882 "CRT2: Display supports TMDS input on secondary interface\n");
9883 } else {
9884 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9885 "CRT2: Display does not support TMDS video interface (0x%02x)\n",
9886 buffer[0x41]);
9887 return 0;
9888 }
9889
9890 paneltype = Panel_Custom;
9891 SiS_Pr->CP_MaxX = xres = buffer[0x76] | (buffer[0x77] << 8);
9892 SiS_Pr->CP_MaxY = yres = buffer[0x78] | (buffer[0x79] << 8);
9893 switch(xres) {
9894 #if 0
9895 case 800:
9896 if(yres == 600) {
9897 paneltype = Panel_800x600;
9898 checkexpand = TRUE;
9899 }
9900 break;
9901 #endif
9902 case 1024:
9903 if(yres == 768) {
9904 paneltype = Panel_1024x768;
9905 checkexpand = TRUE;
9906 }
9907 break;
9908 case 1280:
9909 if(yres == 960) {
9910 if(pSiS->VGAEngine == SIS_315_VGA) {
9911 paneltype = Panel310_1280x960;
9912 } else {
9913 paneltype = Panel300_1280x960;
9914 }
9915 } else if(yres == 1024) {
9916 paneltype = Panel_1280x1024;
9917 checkexpand = TRUE;
9918 }
9919 /* 1280x768 treated as custom here */
9920 break;
9921 case 1400:
9922 if(pSiS->VGAEngine == SIS_315_VGA) {
9923 if(yres == 1050) {
9924 paneltype = Panel310_1400x1050;
9925 checkexpand = TRUE;
9926 }
9927 }
9928 break;
9929 #if 0 /* Treat this one as custom since we have no timing data yet */
9930 case 1600:
9931 if(pSiS->VGAEngine == SIS_315_VGA) {
9932 if(pSiS->VBFlags & VB_301C) {
9933 if(yres == 1200) {
9934 paneltype = Panel310_1600x1200;
9935 checkexpand = TRUE;
9936 }
9937 }
9938 }
9939 break;
9940 #endif
9941 }
9942
9943 /* Determine if RGB18 or RGB24 */
9944 if(index) {
9945 if((buffer[index] == 0x20) || (buffer[index] == 0x34)) {
9946 cr37 |= 0x01;
9947 }
9948 }
9949
9950 if(checkexpand) {
9951 /* TODO - for now, we let the panel scale */
9952 cr37 |= 0x10;
9953 }
9954
9955 /* Now seek 4-Byte Timing codes and extract sync pol info */
9956 index = 0x80;
9957 if(buffer[0x7e] & 0x20) { /* skip Luminance Table (if provided) */
9958 lumsize = buffer[0x80] & 0x1f;
9959 if(buffer[0x80] & 0x80) lumsize *= 3;
9960 lumsize++; /* luminance header byte */
9961 index += lumsize;
9962 }
9963 index += (((buffer[0x7e] & 0x1c) >> 2) * 8); /* skip Frequency Ranges */
9964 index += ((buffer[0x7e] & 0x03) * 27); /* skip Detailed Range Limits */
9965 numcodes = (buffer[0x7f] & 0xf8) >> 3;
9966 if(numcodes) {
9967 myindex = index;
9968 seekcode = (xres - 256) / 16;
9969 for(i=0; i<numcodes; i++) {
9970 if(buffer[myindex] == seekcode) break;
9971 myindex += 4;
9972 }
9973 if(buffer[myindex] == seekcode) {
9974 cr37 |= ((((buffer[myindex + 1] & 0x0c) ^ 0x0c) << 4) | 0x20);
9975 } else {
9976 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
9977 "CRT2: Unable to retrieve Sync polarity information\n");
9978 }
9979 } else {
9980 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
9981 "CRT2: Unable to retrieve Sync polarity information\n");
9982 }
9983
9984 /* Now seek the detailed timing descriptions for custom panels */
9985 if(paneltype == Panel_Custom) {
9986
9987 SiS_Pr->CP_Supports64048075 = TRUE;
9988
9989 index += (numcodes * 4);
9990 numcodes = buffer[0x7f] & 0x07;
9991 for(i=0; i<numcodes; i++, index += 18) {
9992 xres = buffer[index+2] | ((buffer[index+4] & 0xf0) << 4);
9993 yres = buffer[index+5] | ((buffer[index+7] & 0xf0) << 4);
9994
9995 SiS_Pr->CP_HDisplay[i] = xres;
9996 SiS_Pr->CP_HSyncStart[i] = xres + (buffer[index+8] | ((buffer[index+11] & 0xc0) << 2));
9997 SiS_Pr->CP_HSyncEnd[i] = SiS_Pr->CP_HSyncStart[i] + (buffer[index+9] | ((buffer[index+11] & 0x30) << 4));
9998 SiS_Pr->CP_HTotal[i] = xres + (buffer[index+3] | ((buffer[index+4] & 0x0f) << 8));
9999 SiS_Pr->CP_HBlankStart[i] = xres + 1;
10000 SiS_Pr->CP_HBlankEnd[i] = SiS_Pr->CP_HTotal[i];
10001
10002 SiS_Pr->CP_VDisplay[i] = yres;
10003 SiS_Pr->CP_VSyncStart[i] = yres + (((buffer[index+10] & 0xf0) >> 4) | ((buffer[index+11] & 0x0c) << 2));
10004 SiS_Pr->CP_VSyncEnd[i] = SiS_Pr->CP_VSyncStart[i] + ((buffer[index+10] & 0x0f) | ((buffer[index+11] & 0x03) << 4));
10005 SiS_Pr->CP_VTotal[i] = yres + (buffer[index+6] | ((buffer[index+7] & 0x0f) << 8));
10006 SiS_Pr->CP_VBlankStart[i] = yres + 1;
10007 SiS_Pr->CP_VBlankEnd[i] = SiS_Pr->CP_VTotal[i];
10008
10009 SiS_Pr->CP_Clock[i] = (buffer[index] | (buffer[index+1] << 8)) * 10;
10010
10011 SiS_Pr->CP_DataValid[i] = TRUE;
10012
10013 if((SiS_Pr->CP_HDisplay[i] & 7) ||
10014 (SiS_Pr->CP_HDisplay[i] > SiS_Pr->CP_HSyncStart[i]) ||
10015 (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HSyncEnd[i]) ||
10016 (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HTotal[i]) ||
10017 (SiS_Pr->CP_HSyncStart[i] >= SiS_Pr->CP_HSyncEnd[i]) ||
10018 (SiS_Pr->CP_HSyncStart[i] > SiS_Pr->CP_HTotal[i]) ||
10019 (SiS_Pr->CP_HSyncEnd[i] > SiS_Pr->CP_HTotal[i]) ||
10020 (SiS_Pr->CP_VDisplay[i] > SiS_Pr->CP_VSyncStart[i]) ||
10021 (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VSyncEnd[i]) ||
10022 (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VTotal[i]) ||
10023 (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VSyncEnd[i]) ||
10024 (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VTotal[i]) ||
10025 (SiS_Pr->CP_VSyncEnd[i] > SiS_Pr->CP_VTotal[i]) ||
10026 (((pSiS->VBFlags & VB_301C) && (SiS_Pr->CP_Clock[i] > 162500)) ||
10027 ((!(pSiS->VBFlags & VB_301C)) && (SiS_Pr->CP_Clock[i] > 108200))) ||
10028 (buffer[index + 17] & 0x80)) {
10029
10030 SiS_Pr->CP_DataValid[i] = FALSE;
10031
10032 } else {
10033
10034 SiS_Pr->CP_HaveCustomData = TRUE;
10035
10036 if(SiS_Pr->CP_Clock[i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = SiS_Pr->CP_Clock[i];
10037
10038 if((SiS_Pr->CP_MaxX == xres) && (SiS_Pr->CP_MaxY == yres)) {
10039 SiS_Pr->CP_PreferredIndex = i;
10040 }
10041
10042 SiS_Pr->CP_HSync_P[i] = (buffer[index + 17] & 0x02) ? TRUE : FALSE;
10043 SiS_Pr->CP_VSync_P[i] = (buffer[index + 17] & 0x04) ? TRUE : FALSE;
10044 SiS_Pr->CP_SyncValid[i] = TRUE;
10045
10046 SiS_Pr->CP_Vendor = buffer[2] | (buffer[1] << 8);
10047 SiS_Pr->CP_Product = buffer[3] | (buffer[4] << 8);
10048
10049 /* We must assume the panel can scale, since we have
10050 * no scaling data
10051 */
10052 cr37 |= 0x10;
10053
10054 }
10055 }
10056
10057 }
10058
10059 break;
10060
10061 }
10062
10063 /* 1280x960 panels are always RGB24, unable to scale and use
10064 * high active sync polarity
10065 */
10066 if(pSiS->VGAEngine == SIS_315_VGA) {
10067 if(paneltype == Panel310_1280x960) cr37 &= 0x0e;
10068 } else {
10069 if(paneltype == Panel300_1280x960) cr37 &= 0x0e;
10070 }
10071
10072 for(i = 0; i < 7; i++) {
10073 if(SiS_Pr->CP_DataValid[i]) {
10074 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10075 "Non-standard LCD timing data no. %d:\n", i);
10076 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10077 " HDisplay %d HSync %d HSyncEnd %d HTotal %d\n",
10078 SiS_Pr->CP_HDisplay[i], SiS_Pr->CP_HSyncStart[i],
10079 SiS_Pr->CP_HSyncEnd[i], SiS_Pr->CP_HTotal[i]);
10080 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10081 " VDisplay %d VSync %d VSyncEnd %d VTotal %d\n",
10082 SiS_Pr->CP_VDisplay[i], SiS_Pr->CP_VSyncStart[i],
10083 SiS_Pr->CP_VSyncEnd[i], SiS_Pr->CP_VTotal[i]);
10084 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10085 " Pixel clock: %3.3fMhz\n", (float)SiS_Pr->CP_Clock[i] / 1000);
10086 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO,
10087 " To use this, add \"%dx%d\" to the list of Modes in the Screen section\n",
10088 SiS_Pr->CP_HDisplay[i],
10089 SiS_Pr->CP_VDisplay[i]);
10090 }
10091 }
10092
10093 if(paneltype) {
10094 if(!SiS_Pr->CP_PreferredX) SiS_Pr->CP_PreferredX = SiS_Pr->CP_MaxX;
10095 if(!SiS_Pr->CP_PreferredY) SiS_Pr->CP_PreferredY = SiS_Pr->CP_MaxY;
10096 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x32,0x08);
10097 SiS_SetReg(SiS_Pr->SiS_P3d4,0x36,paneltype);
10098 cr37 &= 0xf1;
10099 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x37,0x0c,cr37);
10100 SiS_Pr->PanelSelfDetected = TRUE;
10101 #ifdef TWDEBUG
10102 xf86DrvMsgVerb(pSiS->pScrn->scrnIndex, X_PROBED, 3,
10103 "CRT2: [DDC LCD results: 0x%02x, 0x%02x]\n", paneltype, cr37);
10104 #endif
10105 } else {
10106 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x32,~0x08);
10107 SiS_SetReg(SiS_Pr->SiS_P3d4,0x36,0x00);
10108 }
10109 return 0;
10110 }
10111
10112 USHORT
SiS_SenseVGA2DDC(SiS_Private * SiS_Pr,SISPtr pSiS)10113 SiS_SenseVGA2DDC(SiS_Private *SiS_Pr, SISPtr pSiS)
10114 {
10115 USHORT DDCdatatype,flag;
10116 BOOLEAN foundcrt = FALSE;
10117 int retry;
10118 unsigned char buffer[256];
10119
10120 if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) return 0;
10121
10122 if(SiS_InitDDCRegs(SiS_Pr, pSiS->VBFlags, pSiS->VGAEngine, 2, 0, FALSE) == 0xFFFF) return 0;
10123
10124 SiS_Pr->SiS_DDC_SecAddr = 0x00;
10125
10126 /* Probe supported DA's */
10127 flag = SiS_ProbeDDC(SiS_Pr);
10128 if(flag & 0x10) {
10129 SiS_Pr->SiS_DDC_DeviceAddr = 0xa6; /* EDID V2 (FP) */
10130 DDCdatatype = 4;
10131 } else if(flag & 0x08) {
10132 SiS_Pr->SiS_DDC_DeviceAddr = 0xa2; /* EDID V2 (P&D-D Monitor) */
10133 DDCdatatype = 3;
10134 } else if(flag & 0x02) {
10135 SiS_Pr->SiS_DDC_DeviceAddr = 0xa0; /* EDID V1 */
10136 DDCdatatype = 1;
10137 } else {
10138 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10139 "Do DDC answer\n");
10140 return 0; /* no DDC support (or no device attached) */
10141 }
10142
10143 /* Read the entire EDID */
10144 retry = 2;
10145 do {
10146 if(SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer)) {
10147 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10148 "CRT2: DDC read failed (attempt %d), %s\n",
10149 (3-retry), (retry == 1) ? "giving up" : "retrying");
10150 retry--;
10151 if(retry == 0) return 0xFFFF;
10152 } else break;
10153 } while(1);
10154
10155 /* Analyze EDID. We don't have many chances to
10156 * distinguish a flat panel from a CRT...
10157 */
10158 switch(DDCdatatype) {
10159 case 1:
10160 if(!(checkedid1(buffer))) {
10161 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10162 "CRT2: EDID corrupt\n");
10163 return 0;
10164 }
10165 if(buffer[0x14] & 0x80) { /* Display uses digital input */
10166 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10167 "CRT2: Attached display expects digital input\n");
10168 return 0;
10169 }
10170 SiS_Pr->CP_Vendor = buffer[9] | (buffer[8] << 8);
10171 SiS_Pr->CP_Product = buffer[10] | (buffer[11] << 8);
10172 foundcrt = TRUE;
10173 break;
10174 case 3:
10175 case 4:
10176 if(!(checkedid2(buffer))) {
10177 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10178 "CRT2: EDID corrupt\n");
10179 return 0;
10180 }
10181 if( ((buffer[0x41] & 0x0f) != 0x01) && /* Display does not support analog input */
10182 ((buffer[0x41] & 0x0f) != 0x02) &&
10183 ((buffer[0x41] & 0xf0) != 0x10) &&
10184 ((buffer[0x41] & 0xf0) != 0x20) ) {
10185 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10186 "CRT2: Attached display does not support analog input (0x%02x)\n",
10187 buffer[0x41]);
10188 return 0;
10189 }
10190 SiS_Pr->CP_Vendor = buffer[2] | (buffer[1] << 8);
10191 SiS_Pr->CP_Product = buffer[3] | (buffer[4] << 8);
10192 foundcrt = TRUE;
10193 break;
10194 }
10195
10196 if(foundcrt) {
10197 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x32,0x10);
10198 }
10199 return(0);
10200 }
10201
10202 #endif
10203
10204 void
SiS_SetCH70xxANDOR(SiS_Private * SiS_Pr,USHORT tempax,USHORT tempbh)10205 SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, USHORT tempax,USHORT tempbh)
10206 {
10207 USHORT tempbl;
10208
10209 tempbl = SiS_GetCH70xx(SiS_Pr,(tempax & 0x00FF));
10210 tempbl = (((tempbl & tempbh) << 8) | tempax);
10211 SiS_SetCH70xx(SiS_Pr,tempbl);
10212 }
10213
10214 /* Generic I2C functions for Chrontel & DDC --------- */
10215
10216 void
SiS_SetSwitchDDC2(SiS_Private * SiS_Pr)10217 SiS_SetSwitchDDC2(SiS_Private *SiS_Pr)
10218 {
10219 SiS_SetSCLKHigh(SiS_Pr);
10220 SiS_WaitRetrace1(SiS_Pr);
10221
10222 SiS_SetSCLKLow(SiS_Pr);
10223 SiS_WaitRetrace1(SiS_Pr);
10224 }
10225
10226 USHORT
SiS_ReadDDC1Bit(SiS_Private * SiS_Pr)10227 SiS_ReadDDC1Bit(SiS_Private *SiS_Pr)
10228 {
10229 SiS_WaitRetrace1(SiS_Pr);
10230 return((SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x02) >> 1);
10231 }
10232
10233 /* Set I2C start condition */
10234 /* This is done by a SD high-to-low transition while SC is high */
10235 USHORT
SiS_SetStart(SiS_Private * SiS_Pr)10236 SiS_SetStart(SiS_Private *SiS_Pr)
10237 {
10238 if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */
10239 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10240 SiS_Pr->SiS_DDC_Index,
10241 SiS_Pr->SiS_DDC_NData,
10242 SiS_Pr->SiS_DDC_Data); /* SD->high */
10243 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */
10244 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10245 SiS_Pr->SiS_DDC_Index,
10246 SiS_Pr->SiS_DDC_NData,
10247 0x00); /* SD->low = start condition */
10248 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->low) */
10249 return 0;
10250 }
10251
10252 /* Set I2C stop condition */
10253 /* This is done by a SD low-to-high transition while SC is high */
10254 USHORT
SiS_SetStop(SiS_Private * SiS_Pr)10255 SiS_SetStop(SiS_Private *SiS_Pr)
10256 {
10257 if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */
10258 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10259 SiS_Pr->SiS_DDC_Index,
10260 SiS_Pr->SiS_DDC_NData,
10261 0x00); /* SD->low */
10262 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */
10263 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10264 SiS_Pr->SiS_DDC_Index,
10265 SiS_Pr->SiS_DDC_NData,
10266 SiS_Pr->SiS_DDC_Data); /* SD->high = stop condition */
10267 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->high) */
10268 return 0;
10269 }
10270
10271 /* Write 8 bits of data */
10272 USHORT
SiS_WriteDDC2Data(SiS_Private * SiS_Pr,USHORT tempax)10273 SiS_WriteDDC2Data(SiS_Private *SiS_Pr, USHORT tempax)
10274 {
10275 USHORT i,flag,temp;
10276
10277 flag = 0x80;
10278 for(i=0; i<8; i++) {
10279 SiS_SetSCLKLow(SiS_Pr); /* SC->low */
10280 if(tempax & flag) {
10281 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10282 SiS_Pr->SiS_DDC_Index,
10283 SiS_Pr->SiS_DDC_NData,
10284 SiS_Pr->SiS_DDC_Data); /* Write bit (1) to SD */
10285 } else {
10286 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10287 SiS_Pr->SiS_DDC_Index,
10288 SiS_Pr->SiS_DDC_NData,
10289 0x00); /* Write bit (0) to SD */
10290 }
10291 SiS_SetSCLKHigh(SiS_Pr); /* SC->high */
10292 flag >>= 1;
10293 }
10294 temp = SiS_CheckACK(SiS_Pr); /* Check acknowledge */
10295 return(temp);
10296 }
10297
10298 USHORT
SiS_ReadDDC2Data(SiS_Private * SiS_Pr,USHORT tempax)10299 SiS_ReadDDC2Data(SiS_Private *SiS_Pr, USHORT tempax)
10300 {
10301 USHORT i,temp,getdata;
10302
10303 getdata=0;
10304 for(i=0; i<8; i++) {
10305 getdata <<= 1;
10306 SiS_SetSCLKLow(SiS_Pr);
10307 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10308 SiS_Pr->SiS_DDC_Index,
10309 SiS_Pr->SiS_DDC_NData,
10310 SiS_Pr->SiS_DDC_Data);
10311 SiS_SetSCLKHigh(SiS_Pr);
10312 temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
10313 if(temp & SiS_Pr->SiS_DDC_Data) getdata |= 0x01;
10314 }
10315 return(getdata);
10316 }
10317
10318 USHORT
SiS_SetSCLKLow(SiS_Private * SiS_Pr)10319 SiS_SetSCLKLow(SiS_Private *SiS_Pr)
10320 {
10321 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10322 SiS_Pr->SiS_DDC_Index,
10323 SiS_Pr->SiS_DDC_NClk,
10324 0x00); /* SetSCLKLow() */
10325 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
10326 return 0;
10327 }
10328
10329 USHORT
SiS_SetSCLKHigh(SiS_Private * SiS_Pr)10330 SiS_SetSCLKHigh(SiS_Private *SiS_Pr)
10331 {
10332 USHORT temp, watchdog=1000;
10333
10334 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10335 SiS_Pr->SiS_DDC_Index,
10336 SiS_Pr->SiS_DDC_NClk,
10337 SiS_Pr->SiS_DDC_Clk); /* SetSCLKHigh() */
10338 do {
10339 temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
10340 } while((!(temp & SiS_Pr->SiS_DDC_Clk)) && --watchdog);
10341 if (!watchdog) {
10342 #ifdef TWDEBUG
10343 xf86DrvMsg(0, X_INFO, "SetClkHigh failed\n");
10344 #endif
10345 return 0xFFFF;
10346 }
10347 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
10348 return 0;
10349 }
10350
10351 /* Check I2C acknowledge */
10352 /* Returns 0 if ack ok, non-0 if ack not ok */
10353 USHORT
SiS_CheckACK(SiS_Private * SiS_Pr)10354 SiS_CheckACK(SiS_Private *SiS_Pr)
10355 {
10356 USHORT tempah;
10357
10358 SiS_SetSCLKLow(SiS_Pr); /* (SC->low) */
10359 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10360 SiS_Pr->SiS_DDC_Index,
10361 SiS_Pr->SiS_DDC_NData,
10362 SiS_Pr->SiS_DDC_Data); /* (SD->high) */
10363 SiS_SetSCLKHigh(SiS_Pr); /* SC->high = clock impulse for ack */
10364 tempah = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); /* Read SD */
10365 SiS_SetSCLKLow(SiS_Pr); /* SC->low = end of clock impulse */
10366 if(tempah & SiS_Pr->SiS_DDC_Data) return(1); /* Ack OK if bit = 0 */
10367 else return(0);
10368 }
10369
10370 /* End of I2C functions ----------------------- */
10371
10372
10373 /* =============== SiS 315/330 O.E.M. ================= */
10374
10375 #ifdef SIS315H
10376
10377 static USHORT
GetRAMDACromptr(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)10378 GetRAMDACromptr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
10379 {
10380 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
10381 USHORT romptr;
10382
10383 if(HwInfo->jChipType < SIS_330) {
10384 romptr = SISGETROMW(0x128);
10385 if(SiS_Pr->SiS_VBType & VB_SIS301B302B)
10386 romptr = SISGETROMW(0x12a);
10387 } else {
10388 romptr = SISGETROMW(0x1a8);
10389 if(SiS_Pr->SiS_VBType & VB_SIS301B302B)
10390 romptr = SISGETROMW(0x1aa);
10391 }
10392 return(romptr);
10393 }
10394
10395 static USHORT
GetLCDromptr(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)10396 GetLCDromptr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
10397 {
10398 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
10399 USHORT romptr;
10400
10401 if(HwInfo->jChipType < SIS_330) {
10402 romptr = SISGETROMW(0x120);
10403 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
10404 romptr = SISGETROMW(0x122);
10405 } else {
10406 romptr = SISGETROMW(0x1a0);
10407 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
10408 romptr = SISGETROMW(0x1a2);
10409 }
10410 return(romptr);
10411 }
10412
10413 static USHORT
GetTVromptr(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)10414 GetTVromptr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
10415 {
10416 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
10417 USHORT romptr;
10418
10419 if(HwInfo->jChipType < SIS_330) {
10420 romptr = SISGETROMW(0x114);
10421 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
10422 romptr = SISGETROMW(0x11a);
10423 } else {
10424 romptr = SISGETROMW(0x194);
10425 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
10426 romptr = SISGETROMW(0x19a);
10427 }
10428 return(romptr);
10429 }
10430
10431 static USHORT
GetLCDPtrIndexBIOS(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)10432 GetLCDPtrIndexBIOS(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
10433 {
10434 USHORT index;
10435
10436 if((IS_SIS650) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
10437 if(!(SiS_IsNotM650orLater(SiS_Pr, HwInfo))) {
10438 if((index = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0)) {
10439 index >>= 4;
10440 index *= 3;
10441 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
10442 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
10443 return index;
10444 }
10445 }
10446 }
10447
10448 index = SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F;
10449 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) index -= 5;
10450 else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 6;
10451 index--;
10452 index *= 3;
10453 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
10454 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
10455 return index;
10456 }
10457
10458 static USHORT
GetLCDPtrIndex(SiS_Private * SiS_Pr)10459 GetLCDPtrIndex(SiS_Private *SiS_Pr)
10460 {
10461 USHORT index;
10462
10463 index = ((SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F) - 1) * 3;
10464 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
10465 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
10466 return index;
10467 }
10468
10469 static USHORT
GetTVPtrIndex(SiS_Private * SiS_Pr)10470 GetTVPtrIndex(SiS_Private *SiS_Pr)
10471 {
10472 USHORT index;
10473
10474 index = 0;
10475 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
10476 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index = 2;
10477
10478 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) index = 0;
10479
10480 index <<= 1;
10481
10482 if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) &&
10483 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
10484 index++;
10485 }
10486
10487 return index;
10488 }
10489
10490 static ULONG
GetOEMTVPtr661_2_GEN(SiS_Private * SiS_Pr,int addme)10491 GetOEMTVPtr661_2_GEN(SiS_Private *SiS_Pr, int addme)
10492 {
10493 USHORT index = 0, temp = 0;
10494
10495 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
10496 if(SiS_Pr->SiS_TVMode & TVSetPALM) index = 2;
10497 if(SiS_Pr->SiS_TVMode & TVSetPALN) index = 3;
10498 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 6;
10499 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
10500 index = 4;
10501 if(SiS_Pr->SiS_TVMode & TVSetPALM) index++;
10502 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 7;
10503 }
10504
10505 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
10506 if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
10507 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
10508 index += addme;
10509 temp++;
10510 }
10511 temp += 0x0100;
10512 }
10513 return(ULONG)(index | (temp << 16));
10514 }
10515
10516 static ULONG
GetOEMTVPtr661_2_OLD(SiS_Private * SiS_Pr)10517 GetOEMTVPtr661_2_OLD(SiS_Private *SiS_Pr)
10518 {
10519 return(GetOEMTVPtr661_2_GEN(SiS_Pr, 8));
10520 }
10521
10522 #if 0
10523 static ULONG
10524 GetOEMTVPtr661_2_NEW(SiS_Private *SiS_Pr)
10525 {
10526 return(GetOEMTVPtr661_2_GEN(SiS_Pr, 6));
10527 }
10528 #endif
10529
10530 static int
GetOEMTVPtr661(SiS_Private * SiS_Pr)10531 GetOEMTVPtr661(SiS_Private *SiS_Pr)
10532 {
10533 int index = 0;
10534
10535 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 2;
10536 if(SiS_Pr->SiS_ROMNew) {
10537 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 4;
10538 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 6;
10539 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 8;
10540 if(SiS_Pr->SiS_TVMode & TVSetHiVision) index = 10;
10541 } else {
10542 if(SiS_Pr->SiS_TVMode & TVSetHiVision) index = 4;
10543 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 6;
10544 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 8;
10545 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 10;
10546 }
10547
10548 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) index++;
10549
10550 return index;
10551 }
10552
10553 static void
SetDelayComp(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,USHORT ModeNo)10554 SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
10555 {
10556 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
10557 USHORT delay=0,index,myindex,temp,romptr=0;
10558 BOOLEAN dochiptest = TRUE;
10559
10560 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10561 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x20,0xbf);
10562 } else {
10563 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x35,0x7f);
10564 }
10565
10566 /* Find delay (from ROM, internal tables, PCI subsystem) */
10567
10568 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) { /* ------------ VGA */
10569
10570 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10571 romptr = GetRAMDACromptr(SiS_Pr, HwInfo);
10572 }
10573 if(romptr) delay = ROMAddr[romptr];
10574 else {
10575 delay = 0x04;
10576 if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
10577 if(IS_SIS650) {
10578 delay = 0x0a;
10579 } else if(IS_SIS740) {
10580 delay = 0x00;
10581 } else if(HwInfo->jChipType < SIS_330) {
10582 delay = 0x0c;
10583 } else {
10584 delay = 0x0c;
10585 }
10586 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
10587 delay = 0x00;
10588 }
10589 }
10590
10591 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD|SetCRT2ToLCDA)) { /* ---------- LCD/LCDA */
10592
10593 BOOLEAN gotitfrompci = FALSE;
10594
10595 /* Could we detect a PDC for LCD or did we get a user-defined? If yes, use it */
10596
10597 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
10598 if(SiS_Pr->PDC != -1) {
10599 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((SiS_Pr->PDC >> 1) & 0x0f));
10600 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((SiS_Pr->PDC & 0x01) << 7));
10601 return;
10602 }
10603 } else {
10604 if(SiS_Pr->PDCA != -1) {
10605 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((SiS_Pr->PDCA << 3) & 0xf0));
10606 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((SiS_Pr->PDCA & 0x01) << 6));
10607 return;
10608 }
10609 }
10610
10611 /* Custom Panel? */
10612
10613 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) {
10614 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10615 delay = 0x00;
10616 if((SiS_Pr->PanelXRes <= 1280) && (SiS_Pr->PanelYRes <= 1024)) {
10617 delay = 0x20;
10618 }
10619 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,delay);
10620 } else {
10621 delay = 0x0c;
10622 if(SiS_Pr->SiS_VBType & VB_SIS301C) delay = 0x03;
10623 else if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
10624 if(IS_SIS740) delay = 0x01;
10625 else delay = 0x03;
10626 }
10627 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,delay);
10628 }
10629 return;
10630 }
10631
10632 /* This is a piece of typical SiS crap: They code the OEM LCD
10633 * delay into the code, at no defined place in the BIOS.
10634 * We now have to start doing a PCI subsystem check here.
10635 */
10636
10637 switch(SiS_Pr->SiS_CustomT) {
10638 case CUT_COMPAQ1280:
10639 case CUT_COMPAQ12802:
10640 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
10641 gotitfrompci = TRUE;
10642 dochiptest = FALSE;
10643 delay = 0x03;
10644 }
10645 break;
10646 case CUT_CLEVO1400:
10647 case CUT_CLEVO14002:
10648 gotitfrompci = TRUE;
10649 dochiptest = FALSE;
10650 delay = 0x02;
10651 break;
10652 case CUT_CLEVO1024:
10653 case CUT_CLEVO10242:
10654 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10655 gotitfrompci = TRUE;
10656 dochiptest = FALSE;
10657 delay = 0x33;
10658 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
10659 delay &= 0x0f;
10660 }
10661 break;
10662 }
10663
10664 /* Could we find it through the PCI ID? If no, use ROM or table */
10665
10666 if(!gotitfrompci) {
10667
10668 index = GetLCDPtrIndexBIOS(SiS_Pr, HwInfo);
10669 myindex = GetLCDPtrIndex(SiS_Pr);
10670
10671 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
10672
10673 if(SiS_IsNotM650orLater(SiS_Pr, HwInfo)) {
10674
10675 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10676 /* Always use the second pointer on 650; some BIOSes */
10677 /* still carry old 301 data at the first location */
10678 /* romptr = SISGETROMW(0x120); */
10679 /* if(SiS_Pr->SiS_VBType & VB_SIS302LV) */
10680 romptr = SISGETROMW(0x122);
10681 if(!romptr) return;
10682 delay = ROMAddr[(romptr + index)];
10683 } else {
10684 delay = SiS310_LCDDelayCompensation_650301LV[myindex];
10685 }
10686
10687 } else {
10688
10689 delay = SiS310_LCDDelayCompensation_651301LV[myindex];
10690 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV))
10691 delay = SiS310_LCDDelayCompensation_651302LV[myindex];
10692
10693 }
10694
10695 } else if(SiS_Pr->SiS_UseROM &&
10696 (!(SiS_Pr->SiS_ROMNew)) &&
10697 (SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) &&
10698 (SiS_Pr->SiS_LCDResInfo != Panel_1280x768) &&
10699 (SiS_Pr->SiS_LCDResInfo != Panel_1280x960)) {
10700
10701 /* Data for 1280x1024 wrong in 301B BIOS */
10702 romptr = GetLCDromptr(SiS_Pr, HwInfo);
10703 if(!romptr) return;
10704 delay = ROMAddr[(romptr + index)];
10705
10706 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
10707
10708 if(IS_SIS740) delay = 0x03;
10709 else delay = 0x00;
10710
10711 } else {
10712
10713 delay = SiS310_LCDDelayCompensation_301[myindex];
10714 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
10715 if(IS_SIS740) delay = 0x01;
10716 else if(HwInfo->jChipType <= SIS_315PRO) delay = SiS310_LCDDelayCompensation_3xx301LV[myindex];
10717 else delay = SiS310_LCDDelayCompensation_650301LV[myindex];
10718 } else if(SiS_Pr->SiS_VBType & VB_SIS301C) {
10719 if(IS_SIS740) delay = 0x01; /* ? */
10720 else delay = 0x03;
10721 } else if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
10722 if(IS_SIS740) delay = 0x01;
10723 else delay = SiS310_LCDDelayCompensation_3xx301B[myindex];
10724 }
10725
10726 }
10727
10728 } /* got it from PCI */
10729
10730 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10731 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,((delay << 4) & 0xf0));
10732 dochiptest = FALSE;
10733 }
10734
10735 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* ------------ TV */
10736
10737 index = GetTVPtrIndex(SiS_Pr);
10738
10739 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
10740
10741 if(SiS_IsNotM650orLater(SiS_Pr,HwInfo)) {
10742
10743 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10744 /* Always use the second pointer on 650; some BIOSes */
10745 /* still carry old 301 data at the first location */
10746 /* romptr = SISGETROMW(0x114); */
10747 /* if(SiS_Pr->SiS_VBType & VB_SIS302LV) */
10748 romptr = SISGETROMW(0x11a);
10749 if(!romptr) return;
10750 delay = ROMAddr[romptr + index];
10751
10752 } else {
10753
10754 delay = SiS310_TVDelayCompensation_301B[index];
10755
10756 }
10757
10758 } else {
10759
10760 switch(SiS_Pr->SiS_CustomT) {
10761 case CUT_COMPAQ1280:
10762 case CUT_COMPAQ12802:
10763 case CUT_CLEVO1400:
10764 case CUT_CLEVO14002:
10765 delay = 0x02;
10766 dochiptest = FALSE;
10767 break;
10768 case CUT_CLEVO1024:
10769 case CUT_CLEVO10242:
10770 delay = 0x03;
10771 dochiptest = FALSE;
10772 break;
10773 default:
10774 delay = SiS310_TVDelayCompensation_651301LV[index];
10775 if(SiS_Pr->SiS_VBType & VB_SIS302LV) {
10776 delay = SiS310_TVDelayCompensation_651302LV[index];
10777 }
10778 }
10779 }
10780
10781 } else if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10782
10783 romptr = GetTVromptr(SiS_Pr, HwInfo);
10784 if(!romptr) return;
10785 delay = ROMAddr[romptr + index];
10786
10787 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
10788
10789 delay = SiS310_TVDelayCompensation_LVDS[index];
10790
10791 } else {
10792
10793 delay = SiS310_TVDelayCompensation_301[index];
10794 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
10795 if(IS_SIS740) {
10796 delay = SiS310_TVDelayCompensation_740301B[index];
10797 /* LV: use 301 data? BIOS bug? */
10798 } else {
10799 delay = SiS310_TVDelayCompensation_301B[index];
10800 if(SiS_Pr->SiS_VBType & VB_SIS301C) delay = 0x02;
10801 }
10802 }
10803
10804 }
10805
10806 if(SiS_LCDAEnabled(SiS_Pr, HwInfo)) {
10807 delay &= 0x0f;
10808 dochiptest = FALSE;
10809 }
10810
10811 } else return;
10812
10813 /* Write delay */
10814
10815 if(SiS_Pr->SiS_VBType & VB_SISVB) {
10816
10817 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && dochiptest) {
10818
10819 temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0) >> 4;
10820 if(temp == 8) { /* 1400x1050 BIOS (COMPAL) */
10821 delay &= 0x0f;
10822 delay |= 0xb0;
10823 } else if(temp == 6) {
10824 delay &= 0x0f;
10825 delay |= 0xc0;
10826 } else if(temp > 7) { /* 1280x1024 BIOS (which one?) */
10827 delay = 0x35;
10828 }
10829 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
10830
10831 } else {
10832
10833 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
10834
10835 }
10836
10837 } else { /* LVDS */
10838
10839 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10840 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
10841 } else {
10842 if(IS_SIS650 && (SiS_Pr->SiS_IF_DEF_CH70xx != 0)) {
10843 delay <<= 4;
10844 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,delay);
10845 } else {
10846 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
10847 }
10848 }
10849
10850 }
10851
10852 }
10853
10854 static void
SetAntiFlicker(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,USHORT ModeNo,USHORT ModeIdIndex)10855 SetAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
10856 USHORT ModeNo,USHORT ModeIdIndex)
10857 {
10858 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
10859 USHORT index,temp,temp1,romptr=0;
10860
10861 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p|TVSetYPbPr525p)) return;
10862
10863 if(ModeNo<=0x13)
10864 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex;
10865 else
10866 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex;
10867
10868 temp = GetTVPtrIndex(SiS_Pr);
10869 temp >>= 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10870 temp1 = temp;
10871
10872 if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
10873 if(HwInfo->jChipType >= SIS_661) {
10874 temp1 = GetOEMTVPtr661(SiS_Pr);
10875 temp1 >>= 1;
10876 romptr = SISGETROMW(0x260);
10877 if(HwInfo->jChipType >= SIS_760) {
10878 romptr = SISGETROMW(0x360);
10879 }
10880 } else if(HwInfo->jChipType >= SIS_330) {
10881 romptr = SISGETROMW(0x192);
10882 } else {
10883 romptr = SISGETROMW(0x112);
10884 }
10885 }
10886
10887 if(romptr) {
10888 temp1 <<= 1;
10889 temp = ROMAddr[romptr + temp1 + index];
10890 } else {
10891 temp = SiS310_TVAntiFlick1[temp][index];
10892 }
10893 temp <<= 4;
10894
10895 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8f,temp); /* index 0A D[6:4] */
10896 }
10897
10898 static void
SetEdgeEnhance(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,USHORT ModeNo,USHORT ModeIdIndex)10899 SetEdgeEnhance(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
10900 USHORT ModeNo,USHORT ModeIdIndex)
10901 {
10902 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
10903 USHORT index,temp,temp1,romptr=0;
10904
10905 temp = temp1 = GetTVPtrIndex(SiS_Pr) >> 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10906
10907 if(ModeNo <= 0x13)
10908 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;
10909 else
10910 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;
10911
10912 if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
10913 if(HwInfo->jChipType >= SIS_661) {
10914 romptr = SISGETROMW(0x26c);
10915 if(HwInfo->jChipType >= SIS_760) {
10916 romptr = SISGETROMW(0x36c);
10917 }
10918 temp1 = GetOEMTVPtr661(SiS_Pr);
10919 temp1 >>= 1;
10920 } else if(HwInfo->jChipType >= SIS_330) {
10921 romptr = SISGETROMW(0x1a4);
10922 } else {
10923 romptr = SISGETROMW(0x124);
10924 }
10925 }
10926
10927 if(romptr) {
10928 temp1 <<= 1;
10929 temp = ROMAddr[romptr + temp1 + index];
10930 } else {
10931 temp = SiS310_TVEdge1[temp][index];
10932 }
10933 temp <<= 5;
10934 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x3A,0x1F,temp); /* index 0A D[7:5] */
10935 }
10936
10937 static void
SetYFilter(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,USHORT ModeNo,USHORT ModeIdIndex)10938 SetYFilter(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
10939 USHORT ModeNo,USHORT ModeIdIndex)
10940 {
10941 USHORT index, temp, i, j;
10942
10943 if(ModeNo <= 0x13) {
10944 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
10945 } else {
10946 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
10947 }
10948
10949 temp = GetTVPtrIndex(SiS_Pr) >> 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10950
10951 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp = 1; /* NTSC-J uses PAL */
10952 else if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 3; /* PAL-M */
10953 else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 4; /* PAL-N */
10954 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp = 1; /* HiVision uses PAL */
10955
10956 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
10957 for(i=0x35, j=0; i<=0x38; i++, j++) {
10958 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
10959 }
10960 for(i=0x48; i<=0x4A; i++, j++) {
10961 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
10962 }
10963 } else {
10964 for(i=0x35, j=0; i<=0x38; i++, j++) {
10965 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter1[temp][index][j]);
10966 }
10967 }
10968 }
10969
10970 static void
SetPhaseIncr(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,USHORT ModeNo,USHORT ModeIdIndex)10971 SetPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
10972 USHORT ModeNo,USHORT ModeIdIndex)
10973 {
10974 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
10975 USHORT index,temp,i,j,resinfo,romptr=0;
10976 ULONG lindex;
10977
10978 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
10979
10980 /* NTSC-J data not in BIOS, and already set in SetGroup2 */
10981 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) return;
10982
10983 if((HwInfo->jChipType >= SIS_661) || SiS_Pr->SiS_ROMNew) {
10984 lindex = GetOEMTVPtr661_2_OLD(SiS_Pr) & 0xffff;
10985 lindex <<= 2;
10986 for(j=0, i=0x31; i<=0x34; i++, j++) {
10987 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS661_TVPhase[lindex + j]);
10988 }
10989 return;
10990 }
10991
10992 /* PAL-M, PAL-N not in BIOS, and already set in SetGroup2 */
10993 if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) return;
10994
10995 if(ModeNo<=0x13) {
10996 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
10997 } else {
10998 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
10999 }
11000
11001 temp = GetTVPtrIndex(SiS_Pr);
11002 /* 0: NTSC Graphics, 1: NTSC Text, 2: PAL Graphics,
11003 * 3: PAL Text, 4: HiTV Graphics 5: HiTV Text
11004 */
11005 if(SiS_Pr->SiS_UseROM) {
11006 romptr = SISGETROMW(0x116);
11007 if(HwInfo->jChipType >= SIS_330) {
11008 romptr = SISGETROMW(0x196);
11009 }
11010 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
11011 romptr = SISGETROMW(0x11c);
11012 if(HwInfo->jChipType >= SIS_330) {
11013 romptr = SISGETROMW(0x19c);
11014 }
11015 if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode))) {
11016 romptr = SISGETROMW(0x116);
11017 if(HwInfo->jChipType >= SIS_330) {
11018 romptr = SISGETROMW(0x196);
11019 }
11020 }
11021 }
11022 }
11023 if(romptr) {
11024 romptr += (temp << 2);
11025 for(j=0, i=0x31; i<=0x34; i++, j++) {
11026 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
11027 }
11028 } else {
11029 index = temp % 2;
11030 temp >>= 1; /* 0:NTSC, 1:PAL, 2:HiTV */
11031 for(j=0, i=0x31; i<=0x34; i++, j++) {
11032 if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV))
11033 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
11034 else if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || (SiS_Pr->SiS_TVMode & TVSetTVSimuMode))
11035 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr2[temp][index][j]);
11036 else
11037 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
11038 }
11039 }
11040
11041 if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision))) {
11042 if((!(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetYPbPr525p | TVSetYPbPr750p))) && (ModeNo > 0x13)) {
11043 if((resinfo == SIS_RI_640x480) ||
11044 (resinfo == SIS_RI_800x600)) {
11045 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x21);
11046 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0xf0);
11047 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xf5);
11048 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7f);
11049 } else if(resinfo == SIS_RI_1024x768) {
11050 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x1e);
11051 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0x8b);
11052 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xfb);
11053 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7b);
11054 }
11055 }
11056 }
11057 }
11058
11059 void
SiS_OEM310Setting(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,USHORT ModeNo,USHORT ModeIdIndex)11060 SiS_OEM310Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11061 USHORT ModeNo,USHORT ModeIdIndex)
11062 {
11063 SetDelayComp(SiS_Pr,HwInfo,ModeNo);
11064
11065 if(SiS_Pr->UseCustomMode) return;
11066
11067 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
11068 SetAntiFlicker(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11069 SetPhaseIncr(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11070 SetYFilter(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11071 if(SiS_Pr->SiS_VBType & VB_SIS301) {
11072 SetEdgeEnhance(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11073 }
11074 }
11075 }
11076
11077 static void
SetDelayComp661(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,USHORT ModeNo,USHORT ModeIdIndex,USHORT RTI)11078 SetDelayComp661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo,
11079 USHORT ModeIdIndex, USHORT RTI)
11080 {
11081 USHORT delay = 0, romptr = 0, index;
11082 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11083
11084 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToRAMDAC)))
11085 return;
11086
11087 /* 1. New ROM: VGA2 and LCD/LCDA-Pass1:1 */
11088
11089 if(SiS_Pr->SiS_ROMNew) {
11090 if((SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) ||
11091 ((SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
11092 (SiS_Pr->SiS_LCDInfo & LCDPass11))) {
11093 index = 25;
11094 if(SiS_Pr->UseCustomMode) {
11095 index = SiS_Pr->CSRClock;
11096 } else if(ModeNo > 0x13) {
11097 index = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RTI,HwInfo);
11098 index = SiS_Pr->SiS_VCLKData[index].CLOCK;
11099 }
11100 if(index < 25) index = 25;
11101 index = ((index / 25) - 1) << 1;
11102 if((ROMAddr[0x5b] & 0x80) || (SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD))) {
11103 index++;
11104 }
11105 romptr = SISGETROMW(0x104); /* 0x4ae */
11106 delay = ROMAddr[romptr + index];
11107 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD)) {
11108 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
11109 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
11110 } else {
11111 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
11112 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
11113 }
11114 return;
11115 }
11116 }
11117
11118 /* 2. Old ROM: VGA2 and LCD/LCDA-Pass 1:1 */
11119
11120 if(SiS_Pr->UseCustomMode) delay = 0x04;
11121 else if(ModeNo <= 0x13) delay = 0x04;
11122 else delay = (SiS_Pr->SiS_RefIndex[RTI].Ext_PDC >> 4);
11123 delay |= (delay << 8);
11124
11125 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
11126
11127 /* 3. TV */
11128
11129 index = GetOEMTVPtr661(SiS_Pr);
11130 if(SiS_Pr->SiS_ROMNew) {
11131 romptr = SISGETROMW(0x106); /* 0x4ba */
11132 delay = ROMAddr[romptr + index];
11133 } else {
11134 delay = 0x04;
11135 }
11136
11137 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11138
11139 /* 4. LCD, LCDA (for new ROM only LV and non-Pass 1:1) */
11140
11141 if( (SiS_Pr->SiS_LCDResInfo != Panel_Custom) &&
11142 ((romptr = GetLCDStructPtr661_2(SiS_Pr, HwInfo))) ) {
11143
11144 /* For LV, the BIOS must know about the correct value */
11145 delay = ROMAddr[romptr + 0x0d]; /* LCD */
11146 delay |= (ROMAddr[romptr + 0x0c] << 8); /* LCDA */
11147
11148 } else {
11149
11150 /* TMDS: Set our own, since BIOS has no idea - TODO: Find out about values */
11151 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
11152 if((SiS_Pr->PanelXRes <= 1024) && (SiS_Pr->PanelYRes <= 768)) {
11153 delay = 0x0404;
11154 } else if((SiS_Pr->PanelXRes <= 1280) && (SiS_Pr->PanelYRes <= 1024)) {
11155 delay = 0x0404;
11156 } else if((SiS_Pr->PanelXRes <= 1400) && (SiS_Pr->PanelYRes <= 1050)) {
11157 delay = 0x1004;
11158 } else
11159 delay = 0x0000;
11160 }
11161
11162 /* Override by detected or user-set values */
11163 /* (but only if, for some reason, we can't read value from BIOS) */
11164 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->PDC != -1)) {
11165 delay = SiS_Pr->PDC & 0x1f;
11166 }
11167 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) && (SiS_Pr->PDCA != -1)) {
11168 delay = (SiS_Pr->PDCA & 0x1f) << 8;
11169 }
11170
11171 }
11172
11173 }
11174
11175 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
11176 delay >>= 8;
11177 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
11178 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
11179 } else {
11180 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
11181 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
11182 }
11183 }
11184
11185 static void
SetCRT2SyncDither661(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,USHORT ModeNo,USHORT RTI)11186 SetCRT2SyncDither661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo, USHORT RTI)
11187 {
11188 USHORT infoflag;
11189 UCHAR temp;
11190
11191 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11192
11193 if(ModeNo <= 0x13) {
11194 infoflag = SiS_GetRegByte(SiS_Pr->SiS_P3ca+2);
11195 } else if(SiS_Pr->UseCustomMode) {
11196 infoflag = SiS_Pr->CInfoFlag;
11197 } else {
11198 infoflag = SiS_Pr->SiS_RefIndex[RTI].Ext_InfoFlag;
11199 }
11200 infoflag &= 0xc0;
11201
11202 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
11203 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
11204 temp &= 0x3f;
11205 temp |= infoflag;
11206 } else {
11207 if(temp & 0x20) infoflag = temp;
11208 }
11209 if(temp & 0x01) infoflag |= 0x01;
11210
11211 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
11212 temp = 0x0c;
11213 if(infoflag & 0x01) temp ^= 0x14; /* BIOS: 18, wrong */
11214 temp |= (infoflag >> 6);
11215 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xe0,temp);
11216 } else {
11217 temp = 0;
11218 if(infoflag & 0x01) temp |= 0x80;
11219 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0x7f,temp);
11220 temp = 0x30;
11221 if(infoflag & 0x01) temp = 0x20;
11222 infoflag &= 0xc0;
11223 temp |= infoflag;
11224 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0f,temp);
11225 }
11226
11227 }
11228 }
11229
11230 static void
SetPanelParms661(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo)11231 SetPanelParms661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
11232 {
11233 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11234 USHORT romptr, temp1, temp2;
11235
11236 if(SiS_Pr->SiS_VBType & (VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV)) {
11237 if(SiS_Pr->LVDSHL != -1) {
11238 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
11239 }
11240 }
11241
11242 if(SiS_Pr->SiS_ROMNew) {
11243
11244 if((romptr = GetLCDStructPtr661_2(SiS_Pr, HwInfo))) {
11245 if(SiS_Pr->SiS_VBType & (VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV)) {
11246 temp1 = (ROMAddr[romptr] & 0x03) | 0x0c;
11247 temp2 = 0xfc;
11248 if(SiS_Pr->LVDSHL != -1) {
11249 temp1 &= 0xfc;
11250 temp2 = 0xf3;
11251 }
11252 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,temp2,temp1);
11253 }
11254 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
11255 temp1 = (ROMAddr[romptr + 1] & 0x80) >> 1;
11256 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0d,0xbf,temp1);
11257 }
11258 }
11259
11260 }
11261 }
11262
11263 void
SiS_OEM661Setting(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,USHORT ModeNo,USHORT ModeIdIndex,USHORT RRTI)11264 SiS_OEM661Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11265 USHORT ModeNo,USHORT ModeIdIndex, USHORT RRTI)
11266 {
11267 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11268
11269 SetDelayComp661(SiS_Pr,HwInfo,ModeNo,ModeIdIndex,RRTI);
11270
11271 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11272 SetCRT2SyncDither661(SiS_Pr,HwInfo,ModeNo,RRTI);
11273 SetPanelParms661(SiS_Pr,HwInfo);
11274 }
11275
11276 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
11277 SetPhaseIncr(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11278 SetYFilter(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11279 SetAntiFlicker(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11280 if(SiS_Pr->SiS_VBType & VB_SIS301) {
11281 SetEdgeEnhance(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11282 }
11283 }
11284 }
11285 }
11286
11287 /* FinalizeLCD
11288 * This finalizes some CRT2 registers for the very panel used.
11289 * If we have a backup if these registers, we use it; otherwise
11290 * we set the register according to most BIOSes. However, this
11291 * function looks quite different in every BIOS, so you better
11292 * pray that we have a backup...
11293 */
11294 void
SiS_FinalizeLCD(SiS_Private * SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,PSIS_HW_INFO HwInfo)11295 SiS_FinalizeLCD(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
11296 PSIS_HW_INFO HwInfo)
11297 {
11298 USHORT tempcl,tempch,tempbl,tempbh,tempbx,tempax,temp;
11299 USHORT resinfo,modeflag;
11300
11301 if(!(SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) return;
11302
11303 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11304 if(SiS_Pr->LVDSHL != -1) {
11305 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
11306 }
11307 }
11308
11309 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
11310 if(SiS_Pr->UseCustomMode) return;
11311
11312 switch(SiS_Pr->SiS_CustomT) {
11313 case CUT_COMPAQ1280:
11314 case CUT_COMPAQ12802:
11315 case CUT_CLEVO1400:
11316 case CUT_CLEVO14002:
11317 return;
11318 }
11319
11320 if(ModeNo <= 0x13) {
11321 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
11322 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
11323 } else {
11324 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
11325 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
11326 }
11327
11328 if(IS_SIS650) {
11329 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4, 0x5f) & 0xf0)) {
11330 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
11331 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x02);
11332 } else {
11333 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
11334 }
11335 }
11336 }
11337
11338 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
11339 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11340 /* Maybe all panels? */
11341 if(SiS_Pr->LVDSHL == -1) {
11342 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
11343 }
11344 return;
11345 }
11346 }
11347
11348 if(SiS_Pr->SiS_CustomT == CUT_CLEVO10242) {
11349 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11350 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11351 if(SiS_Pr->LVDSHL == -1) {
11352 /* Maybe all panels? */
11353 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
11354 }
11355 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
11356 tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
11357 if(tempch == 3) {
11358 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
11359 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
11360 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
11361 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
11362 }
11363 }
11364 return;
11365 }
11366 }
11367 }
11368
11369 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11370 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11371 #ifdef SET_EMI
11372 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
11373 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
11374 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
11375 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
11376 }
11377 #endif
11378 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
11379 if(SiS_Pr->LVDSHL == -1) {
11380 /* Maybe ACER only? */
11381 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
11382 }
11383 }
11384 tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
11385 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
11386 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
11387 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1f,0x76);
11388 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11389 if(tempch == 0x03) {
11390 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
11391 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
11392 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
11393 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
11394 }
11395 if((SiS_Pr->Backup == TRUE) && (SiS_Pr->Backup_Mode == ModeNo)) {
11396 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,SiS_Pr->Backup_14);
11397 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,SiS_Pr->Backup_15);
11398 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,SiS_Pr->Backup_16);
11399 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,SiS_Pr->Backup_17);
11400 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,SiS_Pr->Backup_18);
11401 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,SiS_Pr->Backup_19);
11402 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,SiS_Pr->Backup_1a);
11403 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,SiS_Pr->Backup_1b);
11404 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,SiS_Pr->Backup_1c);
11405 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,SiS_Pr->Backup_1d);
11406 } else if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { /* 1.10.8w */
11407 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x90);
11408 if(ModeNo <= 0x13) {
11409 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x11);
11410 if((resinfo == 0) || (resinfo == 2)) return;
11411 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x18);
11412 if((resinfo == 1) || (resinfo == 3)) return;
11413 }
11414 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
11415 if((ModeNo > 0x13) && (resinfo == SIS_RI_1024x768)) {
11416 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02); /* 1.10.7u */
11417 #if 0
11418 tempbx = 806; /* 0x326 */ /* other older BIOSes */
11419 tempbx--;
11420 temp = tempbx & 0xff;
11421 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);
11422 temp = (tempbx >> 8) & 0x03;
11423 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1d,0xf8,temp);
11424 #endif
11425 }
11426 } else if(ModeNo <= 0x13) {
11427 if(ModeNo <= 1) {
11428 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x70);
11429 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xff);
11430 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
11431 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
11432 }
11433 if(!(modeflag & HalfDCLK)) {
11434 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x20);
11435 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,0x1a);
11436 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,0x28);
11437 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,0x00);
11438 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x4c);
11439 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
11440 if(ModeNo == 0x12) {
11441 switch(tempch) {
11442 case 0:
11443 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
11444 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
11445 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,0x10);
11446 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
11447 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x48);
11448 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
11449 break;
11450 case 2:
11451 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
11452 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
11453 break;
11454 case 3:
11455 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
11456 break;
11457 }
11458 }
11459 }
11460 }
11461 }
11462 } else {
11463 tempcl = tempbh = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
11464 tempcl &= 0x0f;
11465 tempbh &= 0x70;
11466 tempbh >>= 4;
11467 tempbl = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x04);
11468 tempbx = (tempbh << 8) | tempbl;
11469 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11470 if((resinfo == SIS_RI_1024x768) || (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD))) {
11471 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
11472 tempbx = 770;
11473 } else {
11474 if(tempbx > 770) tempbx = 770;
11475 if(SiS_Pr->SiS_VGAVDE < 600) {
11476 tempax = 768 - SiS_Pr->SiS_VGAVDE;
11477 tempax >>= 4; /* 1.10.7w; 1.10.6s: 3; */
11478 if(SiS_Pr->SiS_VGAVDE <= 480) tempax >>= 4; /* 1.10.7w; 1.10.6s: < 480; >>=1; */
11479 tempbx -= tempax;
11480 }
11481 }
11482 } else return;
11483 }
11484 temp = tempbx & 0xff;
11485 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,temp);
11486 temp = ((tempbx & 0xff00) >> 4) | tempcl;
11487 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,temp);
11488 }
11489 }
11490 }
11491
11492 #endif
11493
11494 /* ================= SiS 300 O.E.M. ================== */
11495
11496 #ifdef SIS300
11497
11498 void
SetOEMLCDData2(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefTabIndex)11499 SetOEMLCDData2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11500 USHORT ModeNo,USHORT ModeIdIndex, USHORT RefTabIndex)
11501 {
11502 USHORT crt2crtc=0, modeflag, myindex=0;
11503 UCHAR temp;
11504 int i;
11505
11506 if(ModeNo <= 0x13) {
11507 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
11508 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
11509 } else {
11510 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
11511 crt2crtc = SiS_Pr->SiS_RefIndex[RefTabIndex].Ext_CRT2CRTC;
11512 }
11513
11514 crt2crtc &= 0x3f;
11515
11516 if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
11517 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xdf);
11518 }
11519
11520 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
11521 if(modeflag & HalfDCLK) myindex = 1;
11522
11523 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
11524 for(i=0; i<7; i++) {
11525 if(barco_p1[myindex][crt2crtc][i][0]) {
11526 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,
11527 barco_p1[myindex][crt2crtc][i][0],
11528 barco_p1[myindex][crt2crtc][i][2],
11529 barco_p1[myindex][crt2crtc][i][1]);
11530 }
11531 }
11532 }
11533 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
11534 if(temp & 0x80) {
11535 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x18);
11536 temp++;
11537 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);
11538 }
11539 }
11540 }
11541
11542 static USHORT
GetOEMLCDPtr(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,int Flag)11543 GetOEMLCDPtr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, int Flag)
11544 {
11545 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11546 USHORT tempbx=0,romptr=0;
11547 UCHAR customtable300[] = {
11548 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
11549 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
11550 };
11551 UCHAR customtable630[] = {
11552 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
11553 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
11554 };
11555
11556 if(HwInfo->jChipType == SIS_300) {
11557
11558 tempbx = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0x0f) - 2;
11559 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 4;
11560 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11561 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 3;
11562 }
11563 if(SiS_Pr->SiS_UseROM) {
11564 if(ROMAddr[0x235] & 0x80) {
11565 tempbx = SiS_Pr->SiS_LCDTypeInfo;
11566 if(Flag) {
11567 romptr = SISGETROMW(0x255);
11568 if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
11569 else tempbx = customtable300[SiS_Pr->SiS_LCDTypeInfo];
11570 if(tempbx == 0xFF) return 0xFFFF;
11571 }
11572 tempbx <<= 1;
11573 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
11574 }
11575 }
11576
11577 } else {
11578
11579 if(Flag) {
11580 if(SiS_Pr->SiS_UseROM) {
11581 romptr = SISGETROMW(0x255);
11582 if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
11583 else tempbx = 0xff;
11584 } else {
11585 tempbx = customtable630[SiS_Pr->SiS_LCDTypeInfo];
11586 }
11587 if(tempbx == 0xFF) return 0xFFFF;
11588 tempbx <<= 2;
11589 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
11590 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
11591 return tempbx;
11592 }
11593 tempbx = SiS_Pr->SiS_LCDTypeInfo << 2;
11594 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
11595 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
11596 }
11597 return tempbx;
11598 }
11599
11600 static void
SetOEMLCDDelay(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,USHORT ModeNo,USHORT ModeIdIndex)11601 SetOEMLCDDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11602 USHORT ModeNo,USHORT ModeIdIndex)
11603 {
11604 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11605 USHORT index,temp,romptr=0;
11606
11607 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
11608
11609 if(SiS_Pr->SiS_UseROM) {
11610 if(!(ROMAddr[0x237] & 0x01)) return;
11611 if(!(ROMAddr[0x237] & 0x02)) return;
11612 romptr = SISGETROMW(0x24b);
11613 }
11614
11615 /* The Panel Compensation Delay should be set according to tables
11616 * here. Unfortunately, various BIOS versions don't case about
11617 * a uniform way using eg. ROM byte 0x220, but use different
11618 * hard coded delays (0x04, 0x20, 0x18) in SetGroup1().
11619 * Thus we don't set this if the user select a custom pdc or if
11620 * we otherwise detected a valid pdc.
11621 */
11622 if(SiS_Pr->PDC != -1) return;
11623
11624 temp = GetOEMLCDPtr(SiS_Pr,HwInfo, 0);
11625
11626 if(SiS_Pr->UseCustomMode)
11627 index = 0;
11628 else
11629 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
11630
11631 if(HwInfo->jChipType != SIS_300) {
11632 if(romptr) {
11633 romptr += (temp * 2);
11634 romptr = SISGETROMW(romptr);
11635 romptr += index;
11636 temp = ROMAddr[romptr];
11637 } else {
11638 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11639 temp = SiS300_OEMLCDDelay2[temp][index];
11640 } else {
11641 temp = SiS300_OEMLCDDelay3[temp][index];
11642 }
11643 }
11644 } else {
11645 if(SiS_Pr->SiS_UseROM && (ROMAddr[0x235] & 0x80)) {
11646 if(romptr) {
11647 romptr += (temp * 2);
11648 romptr = SISGETROMW(romptr);
11649 romptr += index;
11650 temp = ROMAddr[romptr];
11651 } else {
11652 temp = SiS300_OEMLCDDelay5[temp][index];
11653 }
11654 } else {
11655 if(SiS_Pr->SiS_UseROM) {
11656 romptr = ROMAddr[0x249] | (ROMAddr[0x24a] << 8);
11657 if(romptr) {
11658 romptr += (temp * 2);
11659 romptr = SISGETROMW(romptr);
11660 romptr += index;
11661 temp = ROMAddr[romptr];
11662 } else {
11663 temp = SiS300_OEMLCDDelay4[temp][index];
11664 }
11665 } else {
11666 temp = SiS300_OEMLCDDelay4[temp][index];
11667 }
11668 }
11669 }
11670 temp &= 0x3c;
11671 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* index 0A D[6:4] */
11672 }
11673
11674 static void
SetOEMLCDData(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,USHORT ModeNo,USHORT ModeIdIndex)11675 SetOEMLCDData(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11676 USHORT ModeNo,USHORT ModeIdIndex)
11677 {
11678 #if 0 /* Unfinished; Data table missing */
11679 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11680 USHORT index,temp;
11681
11682 if (SiS_Pr->SiS_UseROM) {
11683 if(!(ROMAddr[0x237] & 0x01)) return;
11684 if(!(ROMAddr[0x237] & 0x04)) return;
11685 /* No rom pointer in BIOS header! */
11686 }
11687
11688 temp = GetOEMLCDPtr(SiS_Pr,HwInfo, 1);
11689 if(temp = 0xFFFF) return;
11690
11691 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDHIndex;
11692 for(i=0x14, j=0; i<=0x17; i++, j++) {
11693 SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDHData[temp][index][j]);
11694 }
11695 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1a, 0xf8, (SiS300_LCDHData[temp][index][j] & 0x07));
11696
11697 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDVIndex;
11698 SiS_SetReg(SiS_SiS_Part1Port,0x18, SiS300_LCDVData[temp][index][0]);
11699 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x19, 0xF0, SiS300_LCDVData[temp][index][1]);
11700 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1A, 0xC7, (SiS300_LCDVData[temp][index][2] & 0x38));
11701 for(i=0x1b, j=3; i<=0x1d; i++, j++) {
11702 SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDVData[temp][index][j]);
11703 }
11704 #endif
11705 }
11706
11707 static USHORT
GetOEMTVPtr(SiS_Private * SiS_Pr)11708 GetOEMTVPtr(SiS_Private *SiS_Pr)
11709 {
11710 USHORT index;
11711
11712 index = 0;
11713 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) index += 4;
11714 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11715 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) index += 2;
11716 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index += 3;
11717 else if(SiS_Pr->SiS_TVMode & TVSetPAL) index += 1;
11718 } else {
11719 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) index += 2;
11720 if(SiS_Pr->SiS_TVMode & TVSetPAL) index += 1;
11721 }
11722 return index;
11723 }
11724
11725 static void
SetOEMTVDelay(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,USHORT ModeNo,USHORT ModeIdIndex)11726 SetOEMTVDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11727 USHORT ModeNo,USHORT ModeIdIndex)
11728 {
11729 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11730 USHORT index,temp,romptr=0;
11731
11732 if(SiS_Pr->SiS_UseROM) {
11733 if(!(ROMAddr[0x238] & 0x01)) return;
11734 if(!(ROMAddr[0x238] & 0x02)) return;
11735 romptr = SISGETROMW(0x241);
11736 }
11737
11738 temp = GetOEMTVPtr(SiS_Pr);
11739
11740 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVDelayIndex;
11741
11742 if(romptr) {
11743 romptr += (temp * 2);
11744 romptr = SISGETROMW(romptr);
11745 romptr += index;
11746 temp = ROMAddr[romptr];
11747 } else {
11748 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11749 temp = SiS300_OEMTVDelay301[temp][index];
11750 } else {
11751 temp = SiS300_OEMTVDelayLVDS[temp][index];
11752 }
11753 }
11754 temp &= 0x3c;
11755 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);
11756 }
11757
11758 static void
SetOEMAntiFlicker(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,USHORT ModeNo,USHORT ModeIdIndex)11759 SetOEMAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11760 USHORT ModeNo, USHORT ModeIdIndex)
11761 {
11762 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11763 USHORT index,temp,romptr=0;
11764
11765 if(SiS_Pr->SiS_UseROM) {
11766 if(!(ROMAddr[0x238] & 0x01)) return;
11767 if(!(ROMAddr[0x238] & 0x04)) return;
11768 romptr = SISGETROMW(0x243);
11769 }
11770
11771 temp = GetOEMTVPtr(SiS_Pr);
11772
11773 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVFlickerIndex;
11774
11775 if(romptr) {
11776 romptr += (temp * 2);
11777 romptr = SISGETROMW(romptr);
11778 romptr += index;
11779 temp = ROMAddr[romptr];
11780 } else {
11781 temp = SiS300_OEMTVFlicker[temp][index];
11782 }
11783 temp &= 0x70;
11784 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8F,temp);
11785 }
11786
11787 static void
SetOEMPhaseIncr(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,USHORT ModeNo,USHORT ModeIdIndex)11788 SetOEMPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11789 USHORT ModeNo,USHORT ModeIdIndex)
11790 {
11791 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11792 USHORT index,i,j,temp,romptr=0;
11793
11794 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) return;
11795
11796 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetNTSCJ | TVSetPALM | TVSetPALN)) return;
11797
11798 if(SiS_Pr->SiS_UseROM) {
11799 if(!(ROMAddr[0x238] & 0x01)) return;
11800 if(!(ROMAddr[0x238] & 0x08)) return;
11801 romptr = SISGETROMW(0x245);
11802 }
11803
11804 temp = GetOEMTVPtr(SiS_Pr);
11805
11806 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVPhaseIndex;
11807
11808 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
11809 for(i=0x31, j=0; i<=0x34; i++, j++) {
11810 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase2[temp][index][j]);
11811 }
11812 } else {
11813 if(romptr) {
11814 romptr += (temp * 2);
11815 romptr = SISGETROMW(romptr);
11816 romptr += (index * 4);
11817 for(i=0x31, j=0; i<=0x34; i++, j++) {
11818 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
11819 }
11820 } else {
11821 for(i=0x31, j=0; i<=0x34; i++, j++) {
11822 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase1[temp][index][j]);
11823 }
11824 }
11825 }
11826 }
11827
11828 static void
SetOEMYFilter(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,USHORT ModeNo,USHORT ModeIdIndex)11829 SetOEMYFilter(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11830 USHORT ModeNo,USHORT ModeIdIndex)
11831 {
11832 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11833 USHORT index,temp,i,j,romptr=0;
11834
11835 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSCART | SetCRT2ToHiVision | SetCRT2ToYPbPr525750)) return;
11836
11837 if(SiS_Pr->SiS_UseROM) {
11838 if(!(ROMAddr[0x238] & 0x01)) return;
11839 if(!(ROMAddr[0x238] & 0x10)) return;
11840 romptr = SISGETROMW(0x247);
11841 }
11842
11843 temp = GetOEMTVPtr(SiS_Pr);
11844
11845 if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
11846 else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 9;
11847 /* NTSCJ uses NTSC filters */
11848
11849 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVYFilterIndex;
11850
11851 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
11852 for(i=0x35, j=0; i<=0x38; i++, j++) {
11853 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
11854 }
11855 for(i=0x48; i<=0x4A; i++, j++) {
11856 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
11857 }
11858 } else {
11859 if((romptr) && (!(SiS_Pr->SiS_TVMode & (TVSetPALM|TVSetPALN)))) {
11860 romptr += (temp * 2);
11861 romptr = SISGETROMW(romptr);
11862 romptr += (index * 4);
11863 for(i=0x35, j=0; i<=0x38; i++, j++) {
11864 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
11865 }
11866 } else {
11867 for(i=0x35, j=0; i<=0x38; i++, j++) {
11868 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter1[temp][index][j]);
11869 }
11870 }
11871 }
11872 }
11873
11874 static USHORT
SiS_SearchVBModeID(SiS_Private * SiS_Pr,USHORT * ModeNo)11875 SiS_SearchVBModeID(SiS_Private *SiS_Pr, USHORT *ModeNo)
11876 {
11877 USHORT ModeIdIndex;
11878 UCHAR VGAINFO = SiS_Pr->SiS_VGAINFO;
11879
11880 if(*ModeNo <= 5) *ModeNo |= 1;
11881
11882 for(ModeIdIndex=0; ; ModeIdIndex++) {
11883 if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == *ModeNo) break;
11884 if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == 0xFF) return 0;
11885 }
11886
11887 if(*ModeNo != 0x07) {
11888 if(*ModeNo > 0x03) return ModeIdIndex;
11889 if(VGAINFO & 0x80) return ModeIdIndex;
11890 ModeIdIndex++;
11891 }
11892
11893 if(VGAINFO & 0x10) ModeIdIndex++; /* 400 lines */
11894 /* else 350 lines */
11895 return ModeIdIndex;
11896 }
11897
11898 void
SiS_OEM300Setting(SiS_Private * SiS_Pr,PSIS_HW_INFO HwInfo,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefTableIndex)11899 SiS_OEM300Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11900 USHORT ModeNo, USHORT ModeIdIndex, USHORT RefTableIndex)
11901 {
11902 USHORT OEMModeIdIndex=0;
11903
11904 if(!SiS_Pr->UseCustomMode) {
11905 OEMModeIdIndex = SiS_SearchVBModeID(SiS_Pr,&ModeNo);
11906 if(!(OEMModeIdIndex)) return;
11907 }
11908
11909 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
11910 SetOEMLCDDelay(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
11911 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
11912 SetOEMLCDData(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
11913 }
11914 }
11915 if(SiS_Pr->UseCustomMode) return;
11916 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
11917 SetOEMTVDelay(SiS_Pr, HwInfo, ModeNo,OEMModeIdIndex);
11918 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11919 SetOEMAntiFlicker(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
11920 SetOEMPhaseIncr(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
11921 SetOEMYFilter(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
11922 }
11923 }
11924 }
11925 #endif
11926
11927