1 /* $XFree86$ */
2 /* $XdotOrg$ */
3 /*
4 * Mode initializing code (CRT2 section)
5 * for SiS 300/305/540/630/730,
6 * SiS 315/550/[M]650/651/[M]661[FGM]X/[M]74x[GX]/330/[M]76x[GX],
7 * XGI V3XT/V5/V8, Z7
8 * (Universal module for Linux kernel framebuffer and X.org/XFree86 4.x)
9 *
10 * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
11 *
12 * If distributed as part of the Linux kernel, the following license terms
13 * apply:
14 *
15 * * This program is free software; you can redistribute it and/or modify
16 * * it under the terms of the GNU General Public License as published by
17 * * the Free Software Foundation; either version 2 of the named License,
18 * * or any later version.
19 * *
20 * * This program is distributed in the hope that it will be useful,
21 * * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * * GNU General Public License for more details.
24 * *
25 * * You should have received a copy of the GNU General Public License
26 * * along with this program; if not, write to the Free Software
27 * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
28 *
29 * Otherwise, the following license terms apply:
30 *
31 * * Redistribution and use in source and binary forms, with or without
32 * * modification, are permitted provided that the following conditions
33 * * are met:
34 * * 1) Redistributions of source code must retain the above copyright
35 * * notice, this list of conditions and the following disclaimer.
36 * * 2) Redistributions in binary form must reproduce the above copyright
37 * * notice, this list of conditions and the following disclaimer in the
38 * * documentation and/or other materials provided with the distribution.
39 * * 3) The name of the author may not be used to endorse or promote products
40 * * derived from this software without specific prior written permission.
41 * *
42 * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
43 * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
44 * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
45 * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
46 * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
47 * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
48 * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
49 * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
50 * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
51 * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
52 *
53 * Author: Thomas Winischhofer <thomas@winischhofer.net>
54 *
55 * Formerly based on non-functional code-fragements for 300 series by SiS, Inc.
56 * Used by permission.
57 *
58 */
59
60 #ifdef HAVE_CONFIG_H
61 #include "config.h"
62 #endif
63
64 #if 1
65 #define SET_EMI /* 302LV/ELV: Set EMI values */
66 #endif
67
68 #if 1
69 #define SET_PWD /* 301/302LV: Set PWD */
70 #endif
71
72 #define COMPAL_HACK /* Needed for Compal 1400x1050 (EMI) */
73 #define COMPAQ_HACK /* Needed for Inventec/Compaq 1280x1024 (EMI) */
74 #define ASUS_HACK /* Needed for Asus A2H 1024x768 (EMI) */
75
76 #include "init301.h"
77
78 #ifdef SIS300
79 #include "oem300.h"
80 #endif
81
82 #ifdef SIS315H
83 #include "oem310.h"
84 #endif
85
86 #define SiS_I2CDELAY 1000
87 #define SiS_I2CDELAYSHORT 150
88
89 static unsigned short SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr);
90 #ifdef SIS_LINUX_KERNEL
91 static void SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);
92 #endif
93
94 /*********************************************/
95 /* HELPER: Lock/Unlock CRT2 */
96 /*********************************************/
97
98 void
99 SiS_UnLockCRT2(struct SiS_Private *SiS_Pr)
100 {
101 if(SiS_Pr->ChipType == XGI_20)
102 return;
103 else if(SiS_Pr->ChipType >= SIS_315H)
104 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
105 else
106 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
107 }
108
109 #ifdef SIS_LINUX_KERNEL
110 static
111 #endif
112 void
113 SiS_LockCRT2(struct SiS_Private *SiS_Pr)
114 {
115 if(SiS_Pr->ChipType == XGI_20)
116 return;
117 else if(SiS_Pr->ChipType >= SIS_315H)
118 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
119 else
120 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
121 }
122
123 /*********************************************/
124 /* HELPER: Write SR11 */
125 /*********************************************/
126
127 static void
128 SiS_SetRegSR11ANDOR(struct SiS_Private *SiS_Pr, unsigned short DataAND, unsigned short DataOR)
129 {
130 if(SiS_Pr->ChipType >= SIS_661) {
131 DataAND &= 0x0f;
132 DataOR &= 0x0f;
133 }
134 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,DataAND,DataOR);
135 }
136
137 /*********************************************/
138 /* HELPER: Get Pointer to LCD structure */
139 /*********************************************/
140
141 #ifdef SIS315H
142 static unsigned char *
143 GetLCDStructPtr661(struct SiS_Private *SiS_Pr)
144 {
145 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
146 unsigned char *myptr = NULL;
147 unsigned short romindex = 0, reg = 0, idx = 0;
148
149 /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
150 * due to the variaty of panels the BIOS doesn't know about.
151 * Exception: If the BIOS has better knowledge (such as in case
152 * of machines with a 301C and a panel that does not support DDC)
153 * use the BIOS data as well.
154 */
155
156 if((SiS_Pr->SiS_ROMNew) &&
157 ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) {
158
159 if(SiS_Pr->ChipType < SIS_661) reg = 0x3c;
160 else reg = 0x7d;
161
162 idx = (SiS_GetReg(SiS_Pr->SiS_P3d4,reg) & 0x1f) * 26;
163
164 if(idx < (8*26)) {
165 myptr = (unsigned char *)&SiS_LCDStruct661[idx];
166 }
167 romindex = SISGETROMW(0x100);
168 if(romindex) {
169 romindex += idx;
170 myptr = &ROMAddr[romindex];
171 }
172 }
173 return myptr;
174 }
175
176 static unsigned short
177 GetLCDStructPtr661_2(struct SiS_Private *SiS_Pr)
178 {
179 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
180 unsigned short romptr = 0;
181
182 /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
183 * due to the variaty of panels the BIOS doesn't know about.
184 * Exception: If the BIOS has better knowledge (such as in case
185 * of machines with a 301C and a panel that does not support DDC)
186 * use the BIOS data as well.
187 */
188
189 if((SiS_Pr->SiS_ROMNew) &&
190 ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) {
191 romptr = SISGETROMW(0x102);
192 romptr += ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) * SiS_Pr->SiS661LCD2TableSize);
193 }
194
195 return romptr;
196 }
197 #endif
198
199 /*********************************************/
200 /* Adjust Rate for CRT2 */
201 /*********************************************/
202
203 static bool
204 SiS_AdjustCRT2Rate(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
205 unsigned short RRTI, unsigned short *i)
206 {
207 unsigned short checkmask=0, modeid, infoflag;
208
209 modeid = SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID;
210
211 if(SiS_Pr->SiS_VBType & VB_SISVB) {
212
213 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
214
215 checkmask |= SupportRAMDAC2;
216 if(SiS_Pr->ChipType >= SIS_315H) {
217 checkmask |= SupportRAMDAC2_135;
218 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
219 checkmask |= SupportRAMDAC2_162;
220 if(SiS_Pr->SiS_VBType & VB_SISRAMDAC202) {
221 checkmask |= SupportRAMDAC2_202;
222 }
223 }
224 }
225
226 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
227
228 checkmask |= SupportLCD;
229 if(SiS_Pr->ChipType >= SIS_315H) {
230 if(SiS_Pr->SiS_VBType & VB_SISVB) {
231 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
232 if(modeid == 0x2e) checkmask |= Support64048060Hz;
233 }
234 }
235 }
236
237 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
238
239 checkmask |= SupportHiVision;
240
241 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750|SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
242
243 checkmask |= SupportTV;
244 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
245 checkmask |= SupportTV1024;
246 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
247 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
248 checkmask |= SupportYPbPr750p;
249 }
250 }
251 }
252
253 }
254
255 } else { /* LVDS */
256
257 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
258 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
259 checkmask |= SupportCHTV;
260 }
261 }
262
263 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
264 checkmask |= SupportLCD;
265 }
266
267 }
268
269 /* Look backwards in table for matching CRT2 mode */
270 for(; SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID == modeid; (*i)--) {
271 infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
272 if(infoflag & checkmask) return true;
273 if((*i) == 0) break;
274 }
275
276 /* Look through the whole mode-section of the table from the beginning
277 * for a matching CRT2 mode if no mode was found yet.
278 */
279 for((*i) = 0; ; (*i)++) {
280 if(SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID != modeid) break;
281 infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
282 if(infoflag & checkmask) return true;
283 }
284 return false;
285 }
286
287 /*********************************************/
288 /* Get rate index */
289 /*********************************************/
290
291 unsigned short
292 SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
293 {
294 unsigned short RRTI,i,backup_i;
295 unsigned short modeflag,index,temp,backupindex;
296 static const unsigned short LCDRefreshIndex[] = {
297 0x00, 0x00, 0x01, 0x01,
298 0x01, 0x01, 0x01, 0x01,
299 0x01, 0x01, 0x01, 0x01,
300 0x01, 0x01, 0x01, 0x01,
301 0x00, 0x00, 0x00, 0x00
302 };
303
304 /* Do NOT check for UseCustomMode here, will skrew up FIFO */
305 if(ModeNo == 0xfe) return 0;
306
307 if(ModeNo <= 0x13) {
308 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
309 } else {
310 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
311 }
312
313 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
314 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
315 if(modeflag & HalfDCLK) return 0;
316 }
317 }
318
319 if(ModeNo < 0x14) return 0xFFFF;
320
321 index = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x33) >> SiS_Pr->SiS_SelectCRT2Rate) & 0x0F;
322 backupindex = index;
323
324 if(index > 0) index--;
325
326 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
327 if(SiS_Pr->SiS_VBType & VB_SISVB) {
328 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
329 if(SiS_Pr->SiS_VBType & VB_NoLCD) index = 0;
330 else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index = backupindex = 0;
331 }
332 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
333 if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) {
334 temp = LCDRefreshIndex[SiS_GetBIOSLCDResInfo(SiS_Pr)];
335 if(index > temp) index = temp;
336 }
337 }
338 } else {
339 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) index = 0;
340 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
341 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) index = 0;
342 }
343 }
344 }
345
346 RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
347 ModeNo = SiS_Pr->SiS_RefIndex[RRTI].ModeID;
348
349 if(SiS_Pr->ChipType >= SIS_315H) {
350 if(!(SiS_Pr->SiS_VBInfo & DriverMode)) {
351 if( (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x105) ||
352 (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x107) ) {
353 if(backupindex <= 1) RRTI++;
354 }
355 }
356 }
357
358 i = 0;
359 do {
360 if(SiS_Pr->SiS_RefIndex[RRTI + i].ModeID != ModeNo) break;
361 temp = SiS_Pr->SiS_RefIndex[RRTI + i].Ext_InfoFlag;
362 temp &= ModeTypeMask;
363 if(temp < SiS_Pr->SiS_ModeType) break;
364 i++;
365 index--;
366 } while(index != 0xFFFF);
367
368 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
369 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
370 temp = SiS_Pr->SiS_RefIndex[RRTI + i - 1].Ext_InfoFlag;
371 if(temp & InterlaceMode) i++;
372 }
373 }
374
375 i--;
376
377 if((SiS_Pr->SiS_SetFlag & ProgrammingCRT2) && (!(SiS_Pr->SiS_VBInfo & DisableCRT2Display))) {
378 backup_i = i;
379 if(!(SiS_AdjustCRT2Rate(SiS_Pr, ModeNo, ModeIdIndex, RRTI, &i))) {
380 i = backup_i;
381 }
382 }
383
384 return (RRTI + i);
385 }
386
387 /*********************************************/
388 /* STORE CRT2 INFO in CR34 */
389 /*********************************************/
390
391 static void
392 SiS_SaveCRT2Info(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
393 {
394 unsigned short temp1, temp2;
395
396 /* Store CRT1 ModeNo in CR34 */
397 SiS_SetReg(SiS_Pr->SiS_P3d4,0x34,ModeNo);
398 temp1 = (SiS_Pr->SiS_VBInfo & SetInSlaveMode) >> 8;
399 temp2 = ~(SetInSlaveMode >> 8);
400 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x31,temp2,temp1);
401 }
402
403 /*********************************************/
404 /* HELPER: GET SOME DATA FROM BIOS ROM */
405 /*********************************************/
406
407 #ifdef SIS300
408 static bool
409 SiS_CR36BIOSWord23b(struct SiS_Private *SiS_Pr)
410 {
411 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
412 unsigned short temp,temp1;
413
414 if(SiS_Pr->SiS_UseROM) {
415 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
416 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
417 temp1 = SISGETROMW(0x23b);
418 if(temp1 & temp) return true;
419 }
420 }
421 return false;
422 }
423
424 static bool
425 SiS_CR36BIOSWord23d(struct SiS_Private *SiS_Pr)
426 {
427 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
428 unsigned short temp,temp1;
429
430 if(SiS_Pr->SiS_UseROM) {
431 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
432 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
433 temp1 = SISGETROMW(0x23d);
434 if(temp1 & temp) return true;
435 }
436 }
437 return false;
438 }
439 #endif
440
441 /*********************************************/
442 /* HELPER: DELAY FUNCTIONS */
443 /*********************************************/
444
445 void
446 SiS_DDC2Delay(struct SiS_Private *SiS_Pr, unsigned int delaytime)
447 {
448 while (delaytime-- > 0)
449 SiS_GetReg(SiS_Pr->SiS_P3c4, 0x05);
450 }
451
452 #if defined(SIS300) || defined(SIS315H)
453 static void
454 SiS_GenericDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
455 {
456 SiS_DDC2Delay(SiS_Pr, delay * 36);
457 }
458 #endif
459
460 #ifdef SIS315H
461 static void
462 SiS_LongDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
463 {
464 while(delay--) {
465 SiS_GenericDelay(SiS_Pr, 6623);
466 }
467 }
468 #endif
469
470 #if defined(SIS300) || defined(SIS315H)
471 static void
472 SiS_ShortDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
473 {
474 while(delay--) {
475 SiS_GenericDelay(SiS_Pr, 66);
476 }
477 }
478 #endif
479
480 static void
481 SiS_PanelDelay(struct SiS_Private *SiS_Pr, unsigned short DelayTime)
482 {
483 #if defined(SIS300) || defined(SIS315H)
484 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
485 unsigned short PanelID, DelayIndex, Delay=0;
486 #endif
487
488 if(SiS_Pr->ChipType < SIS_315H) {
489
490 #ifdef SIS300
491
492 PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
493 if(SiS_Pr->SiS_VBType & VB_SISVB) {
494 if(SiS_Pr->SiS_VBType & VB_SIS301) PanelID &= 0xf7;
495 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x10)) PanelID = 0x12;
496 }
497 DelayIndex = PanelID >> 4;
498 if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) {
499 Delay = 3;
500 } else {
501 if(DelayTime >= 2) DelayTime -= 2;
502 if(!(DelayTime & 0x01)) {
503 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
504 } else {
505 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
506 }
507 if(SiS_Pr->SiS_UseROM) {
508 if(ROMAddr[0x220] & 0x40) {
509 if(!(DelayTime & 0x01)) Delay = (unsigned short)ROMAddr[0x225];
510 else Delay = (unsigned short)ROMAddr[0x226];
511 }
512 }
513 }
514 SiS_ShortDelay(SiS_Pr, Delay);
515
516 #endif /* SIS300 */
517
518 } else {
519
520 #ifdef SIS315H
521
522 if((SiS_Pr->ChipType >= SIS_661) ||
523 (SiS_Pr->ChipType <= SIS_315PRO) ||
524 (SiS_Pr->ChipType == SIS_330) ||
525 (SiS_Pr->SiS_ROMNew)) {
526
527 if(!(DelayTime & 0x01)) {
528 SiS_DDC2Delay(SiS_Pr, 0x1000);
529 } else {
530 SiS_DDC2Delay(SiS_Pr, 0x4000);
531 }
532
533 } else if((SiS_Pr->SiS_IF_DEF_LVDS == 1) /* ||
534 (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
535 (SiS_Pr->SiS_CustomT == CUT_CLEVO1400) */ ) { /* 315 series, LVDS; Special */
536
537 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
538 PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
539 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1400) {
540 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1b) & 0x10)) PanelID = 0x12;
541 }
542 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
543 DelayIndex = PanelID & 0x0f;
544 } else {
545 DelayIndex = PanelID >> 4;
546 }
547 if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) {
548 Delay = 3;
549 } else {
550 if(DelayTime >= 2) DelayTime -= 2;
551 if(!(DelayTime & 0x01)) {
552 Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[0];
553 } else {
554 Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[1];
555 }
556 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
557 if(ROMAddr[0x13c] & 0x40) {
558 if(!(DelayTime & 0x01)) {
559 Delay = (unsigned short)ROMAddr[0x17e];
560 } else {
561 Delay = (unsigned short)ROMAddr[0x17f];
562 }
563 }
564 }
565 }
566 SiS_ShortDelay(SiS_Pr, Delay);
567 }
568
569 } else if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 315 series, all bridges */
570
571 DelayIndex = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
572 if(!(DelayTime & 0x01)) {
573 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
574 } else {
575 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
576 }
577 Delay <<= 8;
578 SiS_DDC2Delay(SiS_Pr, Delay);
579
580 }
581
582 #endif /* SIS315H */
583
584 }
585 }
586
587 #ifdef SIS315H
588 static void
589 SiS_PanelDelayLoop(struct SiS_Private *SiS_Pr, unsigned short DelayTime, unsigned short DelayLoop)
590 {
591 int i;
592 for(i = 0; i < DelayLoop; i++) {
593 SiS_PanelDelay(SiS_Pr, DelayTime);
594 }
595 }
596 #endif
597
598 /*********************************************/
599 /* HELPER: WAIT-FOR-RETRACE FUNCTIONS */
600 /*********************************************/
601
602 void
603 SiS_WaitRetrace1(struct SiS_Private *SiS_Pr)
604 {
605 unsigned short watchdog;
606
607 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
608 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80)) return;
609
610 watchdog = 65535;
611 while((SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
612 watchdog = 65535;
613 while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
614 }
615
616 #if defined(SIS300) || defined(SIS315H)
617 static void
618 SiS_WaitRetrace2(struct SiS_Private *SiS_Pr, unsigned short reg)
619 {
620 unsigned short watchdog;
621
622 watchdog = 65535;
623 while((SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02) && --watchdog);
624 watchdog = 65535;
625 while((!(SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02)) && --watchdog);
626 }
627 #endif
628
629 static void
630 SiS_WaitVBRetrace(struct SiS_Private *SiS_Pr)
631 {
632 if(SiS_Pr->ChipType < SIS_315H) {
633 #ifdef SIS300
634 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
635 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return;
636 }
637 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x80)) {
638 SiS_WaitRetrace1(SiS_Pr);
639 } else {
640 SiS_WaitRetrace2(SiS_Pr, 0x25);
641 }
642 #endif
643 } else {
644 #ifdef SIS315H
645 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) {
646 SiS_WaitRetrace1(SiS_Pr);
647 } else {
648 SiS_WaitRetrace2(SiS_Pr, 0x30);
649 }
650 #endif
651 }
652 }
653
654 static void
655 SiS_VBWait(struct SiS_Private *SiS_Pr)
656 {
657 unsigned short tempal,temp,i,j;
658
659 temp = 0;
660 for(i = 0; i < 3; i++) {
661 for(j = 0; j < 100; j++) {
662 tempal = SiS_GetRegByte(SiS_Pr->SiS_P3da);
663 if(temp & 0x01) {
664 if((tempal & 0x08)) continue;
665 else break;
666 } else {
667 if(!(tempal & 0x08)) continue;
668 else break;
669 }
670 }
671 temp ^= 0x01;
672 }
673 }
674
675 static void
676 SiS_VBLongWait(struct SiS_Private *SiS_Pr)
677 {
678 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
679 SiS_VBWait(SiS_Pr);
680 } else {
681 SiS_WaitRetrace1(SiS_Pr);
682 }
683 }
684
685 /*********************************************/
686 /* HELPER: MISC */
687 /*********************************************/
688
689 #ifdef SIS300
690 static bool
691 SiS_Is301B(struct SiS_Private *SiS_Pr)
692 {
693 if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01) >= 0xb0) return true;
694 return false;
695 }
696 #endif
697
698 static bool
699 SiS_CRT2IsLCD(struct SiS_Private *SiS_Pr)
700 {
701 if(SiS_Pr->ChipType == SIS_730) {
702 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x20) return true;
703 }
704 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & 0x20) return true;
705 return false;
706 }
707
708 bool
709 SiS_IsDualEdge(struct SiS_Private *SiS_Pr)
710 {
711 #ifdef SIS315H
712 if(SiS_Pr->ChipType >= SIS_315H) {
713 if((SiS_Pr->ChipType != SIS_650) || (SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) {
714 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableDualEdge) return true;
715 }
716 }
717 #endif
718 return false;
719 }
720
721 bool
722 SiS_IsVAMode(struct SiS_Private *SiS_Pr)
723 {
724 #ifdef SIS315H
725 unsigned short flag;
726
727 if(SiS_Pr->ChipType >= SIS_315H) {
728 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
729 if((flag & EnableDualEdge) && (flag & SetToLCDA)) return true;
730 }
731 #endif
732 return false;
733 }
734
735 #ifdef SIS315H
736 static bool
737 SiS_IsVAorLCD(struct SiS_Private *SiS_Pr)
738 {
739 if(SiS_IsVAMode(SiS_Pr)) return true;
740 if(SiS_CRT2IsLCD(SiS_Pr)) return true;
741 return false;
742 }
743 #endif
744
745 static bool
746 SiS_IsDualLink(struct SiS_Private *SiS_Pr)
747 {
748 #ifdef SIS315H
749 if(SiS_Pr->ChipType >= SIS_315H) {
750 if((SiS_CRT2IsLCD(SiS_Pr)) ||
751 (SiS_IsVAMode(SiS_Pr))) {
752 if(SiS_Pr->SiS_LCDInfo & LCDDualLink) return true;
753 }
754 }
755 #endif
756 return false;
757 }
758
759 #ifdef SIS315H
760 static bool
761 SiS_TVEnabled(struct SiS_Private *SiS_Pr)
762 {
763 if((SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) != 0x0c) return true;
764 if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
765 if(SiS_GetReg(SiS_Pr->SiS_Part2Port,0x4d) & 0x10) return true;
766 }
767 return false;
768 }
769 #endif
770
771 #ifdef SIS315H
772 static bool
773 SiS_LCDAEnabled(struct SiS_Private *SiS_Pr)
774 {
775 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) return true;
776 return false;
777 }
778 #endif
779
780 #ifdef SIS315H
781 static bool
782 SiS_WeHaveBacklightCtrl(struct SiS_Private *SiS_Pr)
783 {
784 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
785 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0x10) return true;
786 }
787 return false;
788 }
789 #endif
790
791 #ifdef SIS315H
792 static bool
793 SiS_IsNotM650orLater(struct SiS_Private *SiS_Pr)
794 {
795 unsigned short flag;
796
797 if(SiS_Pr->ChipType == SIS_650) {
798 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0;
799 /* Check for revision != A0 only */
800 if((flag == 0xe0) || (flag == 0xc0) ||
801 (flag == 0xb0) || (flag == 0x90)) return false;
802 } else if(SiS_Pr->ChipType >= SIS_661) return false;
803 return true;
804 }
805 #endif
806
807 #ifdef SIS315H
808 static bool
809 SiS_IsYPbPr(struct SiS_Private *SiS_Pr)
810 {
811 if(SiS_Pr->ChipType >= SIS_315H) {
812 /* YPrPb = 0x08 */
813 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHYPbPr) return true;
814 }
815 return false;
816 }
817 #endif
818
819 #ifdef SIS315H
820 static bool
821 SiS_IsChScart(struct SiS_Private *SiS_Pr)
822 {
823 if(SiS_Pr->ChipType >= SIS_315H) {
824 /* Scart = 0x04 */
825 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHScart) return true;
826 }
827 return false;
828 }
829 #endif
830
831 #ifdef SIS315H
832 static bool
833 SiS_IsTVOrYPbPrOrScart(struct SiS_Private *SiS_Pr)
834 {
835 unsigned short flag;
836
837 if(SiS_Pr->ChipType >= SIS_315H) {
838 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
839 if(flag & SetCRT2ToTV) return true;
840 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
841 if(flag & EnableCHYPbPr) return true; /* = YPrPb = 0x08 */
842 if(flag & EnableCHScart) return true; /* = Scart = 0x04 - TW */
843 } else {
844 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
845 if(flag & SetCRT2ToTV) return true;
846 }
847 return false;
848 }
849 #endif
850
851 #ifdef SIS315H
852 static bool
853 SiS_IsLCDOrLCDA(struct SiS_Private *SiS_Pr)
854 {
855 unsigned short flag;
856
857 if(SiS_Pr->ChipType >= SIS_315H) {
858 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
859 if(flag & SetCRT2ToLCD) return true;
860 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
861 if(flag & SetToLCDA) return true;
862 } else {
863 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
864 if(flag & SetCRT2ToLCD) return true;
865 }
866 return false;
867 }
868 #endif
869
870 static bool
871 SiS_HaveBridge(struct SiS_Private *SiS_Pr)
872 {
873 unsigned short flag;
874
875 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
876 return true;
877 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
878 flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
879 if((flag == 1) || (flag == 2)) return true;
880 }
881 return false;
882 }
883
884 static bool
885 SiS_BridgeIsEnabled(struct SiS_Private *SiS_Pr)
886 {
887 unsigned short flag;
888
889 if(SiS_HaveBridge(SiS_Pr)) {
890 flag = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
891 if(SiS_Pr->ChipType < SIS_315H) {
892 flag &= 0xa0;
893 if((flag == 0x80) || (flag == 0x20)) return true;
894 } else {
895 flag &= 0x50;
896 if((flag == 0x40) || (flag == 0x10)) return true;
897 }
898 }
899 return false;
900 }
901
902 static bool
903 SiS_BridgeInSlavemode(struct SiS_Private *SiS_Pr)
904 {
905 unsigned short flag1;
906
907 flag1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
908 if(flag1 & (SetInSlaveMode >> 8)) return true;
909 return false;
910 }
911
912 /*********************************************/
913 /* GET VIDEO BRIDGE CONFIG INFO */
914 /*********************************************/
915
916 /* Setup general purpose IO for Chrontel communication */
917 #ifdef SIS300
918 void
919 SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo)
920 {
921 unsigned int acpibase;
922 unsigned short temp;
923
924 if(!(SiS_Pr->SiS_ChSW)) return;
925
926 #ifdef SIS_LINUX_KERNEL
927 acpibase = sisfb_read_lpc_pci_dword(SiS_Pr, 0x74);
928 #else
929 acpibase = pciReadLong(0x00000800, 0x74);
930 #endif
931 acpibase &= 0xFFFF;
932 if(!acpibase) return;
933 temp = SiS_GetRegShort((acpibase + 0x3c)); /* ACPI register 0x3c: GP Event 1 I/O mode select */
934 temp &= 0xFEFF;
935 SiS_SetRegShort((acpibase + 0x3c), temp);
936 temp = SiS_GetRegShort((acpibase + 0x3c));
937 temp = SiS_GetRegShort((acpibase + 0x3a)); /* ACPI register 0x3a: GP Pin Level (low/high) */
938 temp &= 0xFEFF;
939 if(!(myvbinfo & SetCRT2ToTV)) temp |= 0x0100;
940 SiS_SetRegShort((acpibase + 0x3a), temp);
941 temp = SiS_GetRegShort((acpibase + 0x3a));
942 }
943 #endif
944
945 void
946 SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
947 unsigned short ModeIdIndex, int checkcrt2mode)
948 {
949 unsigned short tempax, tempbx, temp;
950 unsigned short modeflag, resinfo = 0;
951
952 SiS_Pr->SiS_SetFlag = 0;
953
954 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
955
956 SiS_Pr->SiS_ModeType = modeflag & ModeTypeMask;
957
958 if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
959 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
960 }
961
962 tempbx = 0;
963
964 if(SiS_HaveBridge(SiS_Pr)) {
965
966 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
967 tempbx |= temp;
968 tempax = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) << 8;
969 tempax &= (DriverMode | LoadDACFlag | SetNotSimuMode | SetPALTV);
970 tempbx |= tempax;
971
972 #ifdef SIS315H
973 if(SiS_Pr->ChipType >= SIS_315H) {
974 if(SiS_Pr->SiS_VBType & VB_SISLCDA) {
975 if(ModeNo == 0x03) {
976 /* Mode 0x03 is never in driver mode */
977 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf);
978 }
979 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8))) {
980 /* Reset LCDA setting if not driver mode */
981 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
982 }
983 if(IS_SIS650) {
984 if(SiS_Pr->SiS_UseLCDA) {
985 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) {
986 if((ModeNo <= 0x13) || (!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) {
987 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA));
988 }
989 }
990 }
991 }
992 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
993 if((temp & (EnableDualEdge | SetToLCDA)) == (EnableDualEdge | SetToLCDA)) {
994 tempbx |= SetCRT2ToLCDA;
995 }
996 }
997
998 if(SiS_Pr->ChipType >= SIS_661) { /* New CR layout */
999 tempbx &= ~(SetCRT2ToYPbPr525750 | SetCRT2ToHiVision);
1000 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & 0x04) {
1001 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
1002 if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
1003 else if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1004 tempbx |= SetCRT2ToYPbPr525750;
1005 }
1006 }
1007 }
1008
1009 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1010 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1011 if(temp & SetToLCDA) {
1012 tempbx |= SetCRT2ToLCDA;
1013 }
1014 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1015 if(temp & EnableCHYPbPr) {
1016 tempbx |= SetCRT2ToCHYPbPr;
1017 }
1018 }
1019 }
1020 }
1021
1022 #endif /* SIS315H */
1023
1024 if(!(SiS_Pr->SiS_VBType & VB_SISVGA2)) {
1025 tempbx &= ~(SetCRT2ToRAMDAC);
1026 }
1027
1028 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1029 temp = SetCRT2ToSVIDEO |
1030 SetCRT2ToAVIDEO |
1031 SetCRT2ToSCART |
1032 SetCRT2ToLCDA |
1033 SetCRT2ToLCD |
1034 SetCRT2ToRAMDAC |
1035 SetCRT2ToHiVision |
1036 SetCRT2ToYPbPr525750;
1037 } else {
1038 if(SiS_Pr->ChipType >= SIS_315H) {
1039 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1040 temp = SetCRT2ToAVIDEO |
1041 SetCRT2ToSVIDEO |
1042 SetCRT2ToSCART |
1043 SetCRT2ToLCDA |
1044 SetCRT2ToLCD |
1045 SetCRT2ToCHYPbPr;
1046 } else {
1047 temp = SetCRT2ToLCDA |
1048 SetCRT2ToLCD;
1049 }
1050 } else {
1051 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1052 temp = SetCRT2ToTV | SetCRT2ToLCD;
1053 } else {
1054 temp = SetCRT2ToLCD;
1055 }
1056 }
1057 }
1058
1059 if(!(tempbx & temp)) {
1060 tempax = DisableCRT2Display;
1061 tempbx = 0;
1062 }
1063
1064 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1065
1066 unsigned short clearmask = ( DriverMode |
1067 DisableCRT2Display |
1068 LoadDACFlag |
1069 SetNotSimuMode |
1070 SetInSlaveMode |
1071 SetPALTV |
1072 SwitchCRT2 |
1073 SetSimuScanMode );
1074
1075 if(tempbx & SetCRT2ToLCDA) tempbx &= (clearmask | SetCRT2ToLCDA);
1076 if(tempbx & SetCRT2ToRAMDAC) tempbx &= (clearmask | SetCRT2ToRAMDAC);
1077 if(tempbx & SetCRT2ToLCD) tempbx &= (clearmask | SetCRT2ToLCD);
1078 if(tempbx & SetCRT2ToSCART) tempbx &= (clearmask | SetCRT2ToSCART);
1079 if(tempbx & SetCRT2ToHiVision) tempbx &= (clearmask | SetCRT2ToHiVision);
1080 if(tempbx & SetCRT2ToYPbPr525750) tempbx &= (clearmask | SetCRT2ToYPbPr525750);
1081
1082 } else {
1083
1084 if(SiS_Pr->ChipType >= SIS_315H) {
1085 if(tempbx & SetCRT2ToLCDA) {
1086 tempbx &= (0xFF00|SwitchCRT2|SetSimuScanMode);
1087 }
1088 }
1089 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1090 if(tempbx & SetCRT2ToTV) {
1091 tempbx &= (0xFF00|SetCRT2ToTV|SwitchCRT2|SetSimuScanMode);
1092 }
1093 }
1094 if(tempbx & SetCRT2ToLCD) {
1095 tempbx &= (0xFF00|SetCRT2ToLCD|SwitchCRT2|SetSimuScanMode);
1096 }
1097 if(SiS_Pr->ChipType >= SIS_315H) {
1098 if(tempbx & SetCRT2ToLCDA) {
1099 tempbx |= SetCRT2ToLCD;
1100 }
1101 }
1102
1103 }
1104
1105 if(tempax & DisableCRT2Display) {
1106 if(!(tempbx & (SwitchCRT2 | SetSimuScanMode))) {
1107 tempbx = SetSimuScanMode | DisableCRT2Display;
1108 }
1109 }
1110
1111 if(!(tempbx & DriverMode)) tempbx |= SetSimuScanMode;
1112
1113 /* LVDS/CHRONTEL (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */
1114 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
1115 if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
1116 ((SiS_Pr->SiS_VBType & VB_NoLCD) && (tempbx & SetCRT2ToLCD)) ) {
1117 modeflag &= (~CRT2Mode);
1118 }
1119 }
1120
1121 if(!(tempbx & SetSimuScanMode)) {
1122 if(tempbx & SwitchCRT2) {
1123 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1124 if(resinfo != SIS_RI_1600x1200) {
1125 tempbx |= SetSimuScanMode;
1126 }
1127 }
1128 } else {
1129 if(SiS_BridgeIsEnabled(SiS_Pr)) {
1130 if(!(tempbx & DriverMode)) {
1131 if(SiS_BridgeInSlavemode(SiS_Pr)) {
1132 tempbx |= SetSimuScanMode;
1133 }
1134 }
1135 }
1136 }
1137 }
1138
1139 if(!(tempbx & DisableCRT2Display)) {
1140 if(tempbx & DriverMode) {
1141 if(tempbx & SetSimuScanMode) {
1142 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1143 if(resinfo != SIS_RI_1600x1200) {
1144 tempbx |= SetInSlaveMode;
1145 }
1146 }
1147 }
1148 } else {
1149 tempbx |= SetInSlaveMode;
1150 }
1151 }
1152
1153 }
1154
1155 SiS_Pr->SiS_VBInfo = tempbx;
1156
1157 #ifdef SIS300
1158 if(SiS_Pr->ChipType == SIS_630) {
1159 SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo);
1160 }
1161 #endif
1162
1163 #ifdef SIS_LINUX_KERNEL
1164 #if 0
1165 printk(KERN_DEBUG "sisfb: (init301: VBInfo= 0x%04x, SetFlag=0x%04x)\n",
1166 SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
1167 #endif
1168 #endif
1169 #ifdef SIS_XORG_XF86
1170 #ifdef TWDEBUG
1171 xf86DrvMsg(0, X_PROBED, "(init301: VBInfo=0x%04x, SetFlag=0x%04x)\n",
1172 SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
1173 #endif
1174 #endif
1175 }
1176
1177 /*********************************************/
1178 /* DETERMINE YPbPr MODE */
1179 /*********************************************/
1180
1181 void
1182 SiS_SetYPbPr(struct SiS_Private *SiS_Pr)
1183 {
1184
1185 unsigned char temp;
1186
1187 /* Note: This variable is only used on 30xLV systems.
1188 * CR38 has a different meaning on LVDS/CH7019 systems.
1189 * On 661 and later, these bits moved to CR35.
1190 *
1191 * On 301, 301B, only HiVision 1080i is supported.
1192 * On 30xLV, 301C, only YPbPr 1080i is supported.
1193 */
1194
1195 SiS_Pr->SiS_YPbPr = 0;
1196 if(SiS_Pr->ChipType >= SIS_661) return;
1197
1198 if(SiS_Pr->SiS_VBType) {
1199 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1200 SiS_Pr->SiS_YPbPr = YPbPrHiVision;
1201 }
1202 }
1203
1204 if(SiS_Pr->ChipType >= SIS_315H) {
1205 if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1206 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1207 if(temp & 0x08) {
1208 switch((temp >> 4)) {
1209 case 0x00: SiS_Pr->SiS_YPbPr = YPbPr525i; break;
1210 case 0x01: SiS_Pr->SiS_YPbPr = YPbPr525p; break;
1211 case 0x02: SiS_Pr->SiS_YPbPr = YPbPr750p; break;
1212 case 0x03: SiS_Pr->SiS_YPbPr = YPbPrHiVision; break;
1213 }
1214 }
1215 }
1216 }
1217
1218 }
1219
1220 /*********************************************/
1221 /* DETERMINE TVMode flag */
1222 /*********************************************/
1223
1224 void
1225 SiS_SetTVMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
1226 {
1227 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
1228 unsigned short temp, temp1, resinfo = 0, romindex = 0;
1229 unsigned char OutputSelect = *SiS_Pr->pSiS_OutputSelect;
1230
1231 SiS_Pr->SiS_TVMode = 0;
1232
1233 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
1234 if(SiS_Pr->UseCustomMode) return;
1235
1236 if(ModeNo > 0x13) {
1237 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1238 }
1239
1240 if(SiS_Pr->ChipType < SIS_661) {
1241
1242 if(SiS_Pr->SiS_VBInfo & SetPALTV) SiS_Pr->SiS_TVMode |= TVSetPAL;
1243
1244 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1245 temp = 0;
1246 if((SiS_Pr->ChipType == SIS_630) ||
1247 (SiS_Pr->ChipType == SIS_730)) {
1248 temp = 0x35;
1249 romindex = 0xfe;
1250 } else if(SiS_Pr->ChipType >= SIS_315H) {
1251 temp = 0x38;
1252 if(SiS_Pr->ChipType < XGI_20) {
1253 romindex = 0xf3;
1254 if(SiS_Pr->ChipType >= SIS_330) romindex = 0x11b;
1255 }
1256 }
1257 if(temp) {
1258 if(romindex && SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
1259 OutputSelect = ROMAddr[romindex];
1260 if(!(OutputSelect & EnablePALMN)) {
1261 SiS_SetRegAND(SiS_Pr->SiS_P3d4,temp,0x3F);
1262 }
1263 }
1264 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,temp);
1265 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1266 if(temp1 & EnablePALM) { /* 0x40 */
1267 SiS_Pr->SiS_TVMode |= TVSetPALM;
1268 SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1269 } else if(temp1 & EnablePALN) { /* 0x80 */
1270 SiS_Pr->SiS_TVMode |= TVSetPALN;
1271 }
1272 } else {
1273 if(temp1 & EnableNTSCJ) { /* 0x40 */
1274 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1275 }
1276 }
1277 }
1278 /* Translate HiVision/YPbPr to our new flags */
1279 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1280 if(SiS_Pr->SiS_YPbPr == YPbPr750p) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1281 else if(SiS_Pr->SiS_YPbPr == YPbPr525p) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1282 else if(SiS_Pr->SiS_YPbPr == YPbPrHiVision) SiS_Pr->SiS_TVMode |= TVSetHiVision;
1283 else SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1284 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p | TVSetYPbPr525i)) {
1285 SiS_Pr->SiS_VBInfo &= ~SetCRT2ToHiVision;
1286 SiS_Pr->SiS_VBInfo |= SetCRT2ToYPbPr525750;
1287 } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
1288 SiS_Pr->SiS_TVMode |= TVSetPAL;
1289 }
1290 }
1291 } else if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1292 if(SiS_Pr->SiS_CHOverScan) {
1293 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
1294 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1295 if((temp & TVOverScan) || (SiS_Pr->SiS_CHOverScan == 1)) {
1296 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1297 }
1298 } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1299 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79);
1300 if((temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1)) {
1301 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1302 }
1303 }
1304 if(SiS_Pr->SiS_CHSOverScan) {
1305 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1306 }
1307 }
1308 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1309 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1310 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1311 if(temp & EnablePALM) SiS_Pr->SiS_TVMode |= TVSetPALM;
1312 else if(temp & EnablePALN) SiS_Pr->SiS_TVMode |= TVSetPALN;
1313 } else {
1314 if(temp & EnableNTSCJ) {
1315 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1316 }
1317 }
1318 }
1319 }
1320
1321 } else { /* 661 and later */
1322
1323 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1324 if(temp1 & 0x01) {
1325 SiS_Pr->SiS_TVMode |= TVSetPAL;
1326 if(temp1 & 0x08) {
1327 SiS_Pr->SiS_TVMode |= TVSetPALN;
1328 } else if(temp1 & 0x04) {
1329 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1330 SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1331 }
1332 SiS_Pr->SiS_TVMode |= TVSetPALM;
1333 }
1334 } else {
1335 if(temp1 & 0x02) {
1336 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1337 }
1338 }
1339 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1340 if(SiS_Pr->SiS_CHOverScan) {
1341 if((temp1 & 0x10) || (SiS_Pr->SiS_CHOverScan == 1)) {
1342 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1343 }
1344 }
1345 }
1346 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1347 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1348 temp1 &= 0xe0;
1349 if(temp1 == 0x00) SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1350 else if(temp1 == 0x20) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1351 else if(temp1 == 0x40) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1352 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1353 SiS_Pr->SiS_TVMode |= (TVSetHiVision | TVSetPAL);
1354 }
1355 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750 | SetCRT2ToHiVision)) {
1356 if(resinfo == SIS_RI_800x480 || resinfo == SIS_RI_1024x576 || resinfo == SIS_RI_1280x720) {
1357 SiS_Pr->SiS_TVMode |= TVAspect169;
1358 } else {
1359 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x39);
1360 if(temp1 & 0x02) {
1361 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetHiVision)) {
1362 SiS_Pr->SiS_TVMode |= TVAspect169;
1363 } else {
1364 SiS_Pr->SiS_TVMode |= TVAspect43LB;
1365 }
1366 } else {
1367 SiS_Pr->SiS_TVMode |= TVAspect43;
1368 }
1369 }
1370 }
1371 }
1372 }
1373
1374 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) SiS_Pr->SiS_TVMode |= TVSetPAL;
1375
1376 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1377
1378 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1379 SiS_Pr->SiS_TVMode |= TVSetPAL;
1380 SiS_Pr->SiS_TVMode &= ~(TVSetPALM | TVSetPALN | TVSetNTSCJ);
1381 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1382 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525i | TVSetYPbPr525p | TVSetYPbPr750p)) {
1383 SiS_Pr->SiS_TVMode &= ~(TVSetPAL | TVSetNTSCJ | TVSetPALM | TVSetPALN);
1384 }
1385 }
1386
1387 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
1388 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
1389 SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
1390 }
1391 }
1392
1393 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
1394 if(resinfo == SIS_RI_1024x768) {
1395 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
1396 SiS_Pr->SiS_TVMode |= TVSet525p1024;
1397 } else if(!(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p))) {
1398 SiS_Pr->SiS_TVMode |= TVSetNTSC1024;
1399 }
1400 }
1401 }
1402
1403 SiS_Pr->SiS_TVMode |= TVRPLLDIV2XO;
1404 if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) &&
1405 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
1406 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1407 } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
1408 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1409 } else if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) {
1410 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
1411 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1412 }
1413 }
1414
1415 }
1416
1417 SiS_Pr->SiS_VBInfo &= ~SetPALTV;
1418
1419 #ifdef SIS_XORG_XF86
1420 #ifdef TWDEBUG
1421 xf86DrvMsg(0, X_INFO, "(init301: TVMode %x, VBInfo %x)\n", SiS_Pr->SiS_TVMode, SiS_Pr->SiS_VBInfo);
1422 #endif
1423 #endif
1424 }
1425
1426 /*********************************************/
1427 /* GET LCD INFO */
1428 /*********************************************/
1429
1430 static unsigned short
1431 SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr)
1432 {
1433 unsigned short temp = SiS_Pr->SiS_LCDResInfo;
1434 /* Translate my LCDResInfo to BIOS value */
1435 switch(temp) {
1436 case Panel_1280x768_2: temp = Panel_1280x768; break;
1437 case Panel_1280x800_2: temp = Panel_1280x800; break;
1438 case Panel_1280x854: temp = Panel661_1280x854; break;
1439 }
1440 return temp;
1441 }
1442
1443 static void
1444 SiS_GetLCDInfoBIOS(struct SiS_Private *SiS_Pr)
1445 {
1446 #ifdef SIS315H
1447 unsigned char *ROMAddr;
1448 unsigned short temp;
1449
1450 #ifdef SIS_XORG_XF86
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 #endif
1461
1462 if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
1463 if((temp = SISGETROMW(6)) != SiS_Pr->PanelHT) {
1464 SiS_Pr->SiS_NeedRomModeData = true;
1465 SiS_Pr->PanelHT = temp;
1466 }
1467 if((temp = SISGETROMW(8)) != SiS_Pr->PanelVT) {
1468 SiS_Pr->SiS_NeedRomModeData = true;
1469 SiS_Pr->PanelVT = temp;
1470 }
1471 SiS_Pr->PanelHRS = SISGETROMW(10);
1472 SiS_Pr->PanelHRE = SISGETROMW(12);
1473 SiS_Pr->PanelVRS = SISGETROMW(14);
1474 SiS_Pr->PanelVRE = SISGETROMW(16);
1475 SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
1476 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].CLOCK =
1477 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].CLOCK = (unsigned short)((unsigned char)ROMAddr[18]);
1478 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2B =
1479 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_A = ROMAddr[19];
1480 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2C =
1481 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_B = ROMAddr[20];
1482
1483 #ifdef SIS_XORG_XF86
1484 #ifdef TWDEBUG
1485 xf86DrvMsg(0, X_INFO, "Paneldata BIOS: [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n",
1486 SiS_Pr->PanelHT, SiS_Pr->PanelVT,
1487 SiS_Pr->PanelHRS, SiS_Pr->PanelHRE,
1488 SiS_Pr->PanelVRS, SiS_Pr->PanelVRE,
1489 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK,
1490 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A,
1491 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B);
1492 #endif
1493 #endif
1494
1495 }
1496 #endif
1497 }
1498
1499 static void
1500 SiS_CheckScaling(struct SiS_Private *SiS_Pr, unsigned short resinfo,
1501 const unsigned char *nonscalingmodes)
1502 {
1503 int i = 0;
1504 while(nonscalingmodes[i] != 0xff) {
1505 if(nonscalingmodes[i++] == resinfo) {
1506 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ||
1507 (SiS_Pr->UsePanelScaler == -1)) {
1508 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1509 }
1510 break;
1511 }
1512 }
1513 }
1514
1515 void
1516 SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
1517 {
1518 unsigned short temp,modeflag,resinfo=0,modexres=0,modeyres=0;
1519 bool panelcanscale = false;
1520 #ifdef SIS300
1521 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
1522 static const unsigned char SiS300SeriesLCDRes[] =
1523 { 0, 1, 2, 3, 7, 4, 5, 8,
1524 0, 0, 10, 0, 0, 0, 0, 15 };
1525 #endif
1526 #ifdef SIS315H
1527 unsigned char *myptr = NULL;
1528 #endif
1529
1530 SiS_Pr->SiS_LCDResInfo = 0;
1531 SiS_Pr->SiS_LCDTypeInfo = 0;
1532 SiS_Pr->SiS_LCDInfo = 0;
1533 SiS_Pr->PanelHRS = 999; /* HSync start */
1534 SiS_Pr->PanelHRE = 999; /* HSync end */
1535 SiS_Pr->PanelVRS = 999; /* VSync start */
1536 SiS_Pr->PanelVRE = 999; /* VSync end */
1537 SiS_Pr->SiS_NeedRomModeData = false;
1538
1539 /* Alternative 1600x1200@60 timing for 1600x1200 LCDA */
1540 SiS_Pr->Alternate1600x1200 = false;
1541
1542 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return;
1543
1544 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
1545
1546 if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
1547 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1548 modexres = SiS_Pr->SiS_ModeResInfo[resinfo].HTotal;
1549 modeyres = SiS_Pr->SiS_ModeResInfo[resinfo].VTotal;
1550 }
1551
1552 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
1553
1554 /* For broken BIOSes: Assume 1024x768 */
1555 if(temp == 0) temp = 0x02;
1556
1557 if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
1558 SiS_Pr->SiS_LCDTypeInfo = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x7c) >> 2;
1559 } else if((SiS_Pr->ChipType < SIS_315H) || (SiS_Pr->ChipType >= SIS_661)) {
1560 SiS_Pr->SiS_LCDTypeInfo = temp >> 4;
1561 } else {
1562 SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1;
1563 }
1564 temp &= 0x0f;
1565 #ifdef SIS300
1566 if(SiS_Pr->ChipType < SIS_315H) {
1567 /* Very old BIOSes only know 7 sizes (NetVista 2179, 1.01g) */
1568 if(SiS_Pr->SiS_VBType & VB_SIS301) {
1569 if(temp < 0x0f) temp &= 0x07;
1570 }
1571 /* Translate 300 series LCDRes to 315 series for unified usage */
1572 temp = SiS300SeriesLCDRes[temp];
1573 }
1574 #endif
1575
1576 /* Translate to our internal types */
1577 #ifdef SIS315H
1578 if(SiS_Pr->ChipType == SIS_550) {
1579 if (temp == Panel310_1152x768) temp = Panel_320x240_2; /* Verified working */
1580 else if(temp == Panel310_320x240_2) temp = Panel_320x240_2;
1581 else if(temp == Panel310_320x240_3) temp = Panel_320x240_3;
1582 } else if(SiS_Pr->ChipType >= SIS_661) {
1583 if(temp == Panel661_1280x854) temp = Panel_1280x854;
1584 }
1585 #endif
1586
1587 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { /* SiS LVDS */
1588 if(temp == Panel310_1280x768) {
1589 temp = Panel_1280x768_2;
1590 }
1591 if(SiS_Pr->SiS_ROMNew) {
1592 if(temp == Panel661_1280x800) {
1593 temp = Panel_1280x800_2;
1594 }
1595 }
1596 }
1597
1598 SiS_Pr->SiS_LCDResInfo = temp;
1599
1600 #ifdef SIS300
1601 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1602 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
1603 SiS_Pr->SiS_LCDResInfo = Panel_Barco1366;
1604 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
1605 SiS_Pr->SiS_LCDResInfo = Panel_848x480;
1606 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL856) {
1607 SiS_Pr->SiS_LCDResInfo = Panel_856x480;
1608 }
1609 }
1610 #endif
1611
1612 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1613 if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)
1614 SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMin301;
1615 } else {
1616 if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMinLVDS)
1617 SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS;
1618 }
1619
1620 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
1621 SiS_Pr->SiS_LCDInfo = temp & ~0x000e;
1622 /* Need temp below! */
1623
1624 /* These must/can't scale no matter what */
1625 switch(SiS_Pr->SiS_LCDResInfo) {
1626 case Panel_320x240_1:
1627 case Panel_320x240_2:
1628 case Panel_320x240_3:
1629 case Panel_1280x960:
1630 SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1631 break;
1632 case Panel_640x480:
1633 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1634 }
1635
1636 panelcanscale = (bool)(SiS_Pr->SiS_LCDInfo & DontExpandLCD);
1637
1638 if(!SiS_Pr->UsePanelScaler) SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1639 else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1640
1641 /* Dual link, Pass 1:1 BIOS default, etc. */
1642 #ifdef SIS315H
1643 if(SiS_Pr->ChipType >= SIS_661) {
1644 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1645 if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1646 }
1647 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1648 if(SiS_Pr->SiS_ROMNew) {
1649 if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1650 } else if((myptr = GetLCDStructPtr661(SiS_Pr))) {
1651 if(myptr[2] & 0x01) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1652 }
1653 }
1654 } else if(SiS_Pr->ChipType >= SIS_315H) {
1655 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1656 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1657 }
1658 if((SiS_Pr->SiS_ROMNew) && (!(SiS_Pr->PanelSelfDetected))) {
1659 SiS_Pr->SiS_LCDInfo &= ~(LCDRGB18Bit);
1660 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1661 if(temp & 0x01) SiS_Pr->SiS_LCDInfo |= LCDRGB18Bit;
1662 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1663 if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1664 }
1665 } else if(!(SiS_Pr->SiS_ROMNew)) {
1666 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1667 if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) &&
1668 (SiS_Pr->SiS_LCDResInfo == Panel_1024x768)) {
1669 SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1670 }
1671 if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
1672 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
1673 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
1674 (SiS_Pr->SiS_LCDResInfo == Panel_1680x1050)) {
1675 SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1676 }
1677 }
1678 }
1679 }
1680 #endif
1681
1682 /* Pass 1:1 */
1683 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
1684 /* Always center screen on LVDS (if scaling is disabled) */
1685 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1686 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
1687 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
1688 /* Always center screen on SiS LVDS (if scaling is disabled) */
1689 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1690 } else {
1691 /* By default, pass 1:1 on SiS TMDS (if scaling is supported) */
1692 if(panelcanscale) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1693 if(SiS_Pr->CenterScreen == 1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1694 }
1695 }
1696
1697 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1698 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1699
1700 switch(SiS_Pr->SiS_LCDResInfo) {
1701 case Panel_320x240_1:
1702 case Panel_320x240_2:
1703 case Panel_320x240_3: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
1704 SiS_Pr->PanelVRS = 24; SiS_Pr->PanelVRE = 3;
1705 SiS_Pr->PanelVCLKIdx300 = VCLK28;
1706 SiS_Pr->PanelVCLKIdx315 = VCLK28;
1707 break;
1708 case Panel_640x480: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
1709 SiS_Pr->PanelVRE = 3;
1710 SiS_Pr->PanelVCLKIdx300 = VCLK28;
1711 SiS_Pr->PanelVCLKIdx315 = VCLK28;
1712 break;
1713 case Panel_800x600: SiS_Pr->PanelXRes = 800; SiS_Pr->PanelYRes = 600;
1714 SiS_Pr->PanelHT = 1056; SiS_Pr->PanelVT = 628;
1715 SiS_Pr->PanelHRS = 40; SiS_Pr->PanelHRE = 128;
1716 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 4;
1717 SiS_Pr->PanelVCLKIdx300 = VCLK40;
1718 SiS_Pr->PanelVCLKIdx315 = VCLK40;
1719 break;
1720 case Panel_1024x600: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 600;
1721 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 800;
1722 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
1723 SiS_Pr->PanelVRS = 2 /* 88 */ ; SiS_Pr->PanelVRE = 6;
1724 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1725 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1726 break;
1727 case Panel_1024x768: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768;
1728 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1729 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
1730 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1731 if(SiS_Pr->ChipType < SIS_315H) {
1732 SiS_Pr->PanelHRS = 23;
1733 SiS_Pr->PanelVRE = 5;
1734 }
1735 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1736 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1737 SiS_GetLCDInfoBIOS(SiS_Pr);
1738 break;
1739 case Panel_1152x768: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 768;
1740 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1741 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
1742 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1743 if(SiS_Pr->ChipType < SIS_315H) {
1744 SiS_Pr->PanelHRS = 23;
1745 SiS_Pr->PanelVRE = 5;
1746 }
1747 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1748 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1749 break;
1750 case Panel_1152x864: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 864;
1751 break;
1752 case Panel_1280x720: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 720;
1753 SiS_Pr->PanelHT = 1650; SiS_Pr->PanelVT = 750;
1754 SiS_Pr->PanelHRS = 110; SiS_Pr->PanelHRE = 40;
1755 SiS_Pr->PanelVRS = 5; SiS_Pr->PanelVRE = 5;
1756 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x720;
1757 /* Data above for TMDS (projector); get from BIOS for LVDS */
1758 SiS_GetLCDInfoBIOS(SiS_Pr);
1759 break;
1760 case Panel_1280x768: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768;
1761 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1762 SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 806;
1763 SiS_Pr->PanelVCLKIdx300 = VCLK81_300; /* ? */
1764 SiS_Pr->PanelVCLKIdx315 = VCLK81_315; /* ? */
1765 } else {
1766 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 802;
1767 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRS = 112;
1768 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1769 SiS_Pr->PanelVCLKIdx300 = VCLK81_300;
1770 SiS_Pr->PanelVCLKIdx315 = VCLK81_315;
1771 }
1772 break;
1773 case Panel_1280x768_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768;
1774 SiS_Pr->PanelHT = 1660; SiS_Pr->PanelVT = 806;
1775 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1776 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1777 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_2;
1778 SiS_GetLCDInfoBIOS(SiS_Pr);
1779 break;
1780 case Panel_1280x800: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800;
1781 SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 816;
1782 SiS_Pr->PanelHRS = 21; SiS_Pr->PanelHRE = 24;
1783 SiS_Pr->PanelVRS = 4; SiS_Pr->PanelVRE = 3;
1784 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315;
1785 SiS_GetLCDInfoBIOS(SiS_Pr);
1786 break;
1787 case Panel_1280x800_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800;
1788 SiS_Pr->PanelHT = 1552; SiS_Pr->PanelVT = 812;
1789 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1790 SiS_Pr->PanelVRS = 4; SiS_Pr->PanelVRE = 3;
1791 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315_2;
1792 SiS_GetLCDInfoBIOS(SiS_Pr);
1793 break;
1794 case Panel_1280x854: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 854;
1795 SiS_Pr->PanelHT = 1664; SiS_Pr->PanelVT = 861;
1796 SiS_Pr->PanelHRS = 16; SiS_Pr->PanelHRE = 112;
1797 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1798 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x854;
1799 SiS_GetLCDInfoBIOS(SiS_Pr);
1800 break;
1801 case Panel_1280x960: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 960;
1802 SiS_Pr->PanelHT = 1800; SiS_Pr->PanelVT = 1000;
1803 SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
1804 SiS_Pr->PanelVCLKIdx315 = VCLK108_3_315;
1805 if(resinfo == SIS_RI_1280x1024) {
1806 SiS_Pr->PanelVCLKIdx300 = VCLK100_300;
1807 SiS_Pr->PanelVCLKIdx315 = VCLK100_315;
1808 }
1809 break;
1810 case Panel_1280x1024: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024;
1811 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1812 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1813 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1814 SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
1815 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1816 SiS_GetLCDInfoBIOS(SiS_Pr);
1817 break;
1818 case Panel_1400x1050: SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050;
1819 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1820 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1821 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1822 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1823 SiS_GetLCDInfoBIOS(SiS_Pr);
1824 break;
1825 case Panel_1600x1200: SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200;
1826 SiS_Pr->PanelHT = 2160; SiS_Pr->PanelVT = 1250;
1827 SiS_Pr->PanelHRS = 64; SiS_Pr->PanelHRE = 192;
1828 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1829 SiS_Pr->PanelVCLKIdx315 = VCLK162_315;
1830 if(SiS_Pr->SiS_VBType & VB_SISTMDSLCDA) {
1831 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
1832 SiS_Pr->PanelHT = 1760; SiS_Pr->PanelVT = 1235;
1833 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 32;
1834 SiS_Pr->PanelVRS = 2; SiS_Pr->PanelVRE = 4;
1835 SiS_Pr->PanelVCLKIdx315 = VCLK130_315;
1836 SiS_Pr->Alternate1600x1200 = true;
1837 }
1838 } else if(SiS_Pr->SiS_IF_DEF_LVDS) {
1839 SiS_Pr->PanelHT = 2048; SiS_Pr->PanelVT = 1320;
1840 SiS_Pr->PanelHRS = SiS_Pr->PanelHRE = 999;
1841 SiS_Pr->PanelVRS = SiS_Pr->PanelVRE = 999;
1842 }
1843 SiS_GetLCDInfoBIOS(SiS_Pr);
1844 break;
1845 case Panel_1680x1050: SiS_Pr->PanelXRes = 1680; SiS_Pr->PanelYRes = 1050;
1846 SiS_Pr->PanelHT = 1900; SiS_Pr->PanelVT = 1066;
1847 SiS_Pr->PanelHRS = 26; SiS_Pr->PanelHRE = 76;
1848 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1849 SiS_Pr->PanelVCLKIdx315 = VCLK121_315;
1850 SiS_GetLCDInfoBIOS(SiS_Pr);
1851 break;
1852 case Panel_Barco1366: SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024;
1853 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1854 break;
1855 case Panel_848x480: SiS_Pr->PanelXRes = 848; SiS_Pr->PanelYRes = 480;
1856 SiS_Pr->PanelHT = 1088; SiS_Pr->PanelVT = 525;
1857 break;
1858 case Panel_856x480: SiS_Pr->PanelXRes = 856; SiS_Pr->PanelYRes = 480;
1859 SiS_Pr->PanelHT = 1088; SiS_Pr->PanelVT = 525;
1860 break;
1861 case Panel_Custom: SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX;
1862 SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY;
1863 SiS_Pr->PanelHT = SiS_Pr->CHTotal;
1864 SiS_Pr->PanelVT = SiS_Pr->CVTotal;
1865 if(SiS_Pr->CP_PreferredIndex != -1) {
1866 SiS_Pr->PanelXRes = SiS_Pr->CP_HDisplay[SiS_Pr->CP_PreferredIndex];
1867 SiS_Pr->PanelYRes = SiS_Pr->CP_VDisplay[SiS_Pr->CP_PreferredIndex];
1868 SiS_Pr->PanelHT = SiS_Pr->CP_HTotal[SiS_Pr->CP_PreferredIndex];
1869 SiS_Pr->PanelVT = SiS_Pr->CP_VTotal[SiS_Pr->CP_PreferredIndex];
1870 SiS_Pr->PanelHRS = SiS_Pr->CP_HSyncStart[SiS_Pr->CP_PreferredIndex];
1871 SiS_Pr->PanelHRE = SiS_Pr->CP_HSyncEnd[SiS_Pr->CP_PreferredIndex];
1872 SiS_Pr->PanelVRS = SiS_Pr->CP_VSyncStart[SiS_Pr->CP_PreferredIndex];
1873 SiS_Pr->PanelVRE = SiS_Pr->CP_VSyncEnd[SiS_Pr->CP_PreferredIndex];
1874 SiS_Pr->PanelHRS -= SiS_Pr->PanelXRes;
1875 SiS_Pr->PanelHRE -= SiS_Pr->PanelHRS;
1876 SiS_Pr->PanelVRS -= SiS_Pr->PanelYRes;
1877 SiS_Pr->PanelVRE -= SiS_Pr->PanelVRS;
1878 if(SiS_Pr->CP_PrefClock) {
1879 int idx;
1880 SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
1881 SiS_Pr->PanelVCLKIdx300 = VCLK_CUSTOM_300;
1882 if(SiS_Pr->ChipType < SIS_315H) idx = VCLK_CUSTOM_300;
1883 else idx = VCLK_CUSTOM_315;
1884 SiS_Pr->SiS_VCLKData[idx].CLOCK =
1885 SiS_Pr->SiS_VBVCLKData[idx].CLOCK = SiS_Pr->CP_PrefClock;
1886 SiS_Pr->SiS_VCLKData[idx].SR2B =
1887 SiS_Pr->SiS_VBVCLKData[idx].Part4_A = SiS_Pr->CP_PrefSR2B;
1888 SiS_Pr->SiS_VCLKData[idx].SR2C =
1889 SiS_Pr->SiS_VBVCLKData[idx].Part4_B = SiS_Pr->CP_PrefSR2C;
1890 }
1891 }
1892 break;
1893 default: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768;
1894 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1895 break;
1896 }
1897
1898 /* Special cases */
1899 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
1900 (SiS_Pr->SiS_IF_DEF_DSTN) ||
1901 (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
1902 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
1903 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
1904 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
1905 SiS_Pr->PanelHRS = 999;
1906 SiS_Pr->PanelHRE = 999;
1907 }
1908
1909 if( (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
1910 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
1911 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
1912 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
1913 SiS_Pr->PanelVRS = 999;
1914 SiS_Pr->PanelVRE = 999;
1915 }
1916
1917 /* DontExpand overrule */
1918 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
1919
1920 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (modeflag & NoSupportLCDScale)) {
1921 /* No scaling for this mode on any panel (LCD=CRT2)*/
1922 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1923 }
1924
1925 switch(SiS_Pr->SiS_LCDResInfo) {
1926
1927 case Panel_Custom:
1928 case Panel_1152x864:
1929 case Panel_1280x768: /* TMDS only */
1930 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1931 break;
1932
1933 case Panel_800x600: {
1934 static const unsigned char nonscalingmodes[] = {
1935 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, 0xff
1936 };
1937 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1938 break;
1939 }
1940 case Panel_1024x768: {
1941 static const unsigned char nonscalingmodes[] = {
1942 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1943 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1944 0xff
1945 };
1946 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1947 break;
1948 }
1949 case Panel_1280x720: {
1950 static const unsigned char nonscalingmodes[] = {
1951 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1952 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1953 0xff
1954 };
1955 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1956 if(SiS_Pr->PanelHT == 1650) {
1957 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1958 }
1959 break;
1960 }
1961 case Panel_1280x768_2: { /* LVDS only */
1962 static const unsigned char nonscalingmodes[] = {
1963 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1964 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1965 SIS_RI_1152x768,0xff
1966 };
1967 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1968 switch(resinfo) {
1969 case SIS_RI_1280x720: if(SiS_Pr->UsePanelScaler == -1) {
1970 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1971 }
1972 break;
1973 }
1974 break;
1975 }
1976 case Panel_1280x800: { /* SiS TMDS special (Averatec 6200 series) */
1977 static const unsigned char nonscalingmodes[] = {
1978 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1979 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1980 SIS_RI_1152x768,SIS_RI_1280x720,SIS_RI_1280x768,0xff
1981 };
1982 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1983 break;
1984 }
1985 case Panel_1280x800_2: { /* SiS LVDS */
1986 static const unsigned char nonscalingmodes[] = {
1987 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1988 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1989 SIS_RI_1152x768,0xff
1990 };
1991 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1992 switch(resinfo) {
1993 case SIS_RI_1280x720:
1994 case SIS_RI_1280x768: if(SiS_Pr->UsePanelScaler == -1) {
1995 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1996 }
1997 break;
1998 }
1999 break;
2000 }
2001 case Panel_1280x854: { /* SiS LVDS */
2002 static const unsigned char nonscalingmodes[] = {
2003 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2004 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2005 SIS_RI_1152x768,0xff
2006 };
2007 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2008 switch(resinfo) {
2009 case SIS_RI_1280x720:
2010 case SIS_RI_1280x768:
2011 case SIS_RI_1280x800: if(SiS_Pr->UsePanelScaler == -1) {
2012 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2013 }
2014 break;
2015 }
2016 break;
2017 }
2018 case Panel_1280x960: {
2019 static const unsigned char nonscalingmodes[] = {
2020 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2021 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2022 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2023 SIS_RI_1280x854,0xff
2024 };
2025 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2026 break;
2027 }
2028 case Panel_1280x1024: {
2029 static const unsigned char nonscalingmodes[] = {
2030 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2031 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2032 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2033 SIS_RI_1280x854,SIS_RI_1280x960,0xff
2034 };
2035 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2036 break;
2037 }
2038 case Panel_1400x1050: {
2039 static const unsigned char nonscalingmodes[] = {
2040 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2041 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2042 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x768,SIS_RI_1280x800,SIS_RI_1280x854,
2043 SIS_RI_1280x960,0xff
2044 };
2045 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2046 switch(resinfo) {
2047 case SIS_RI_1280x720: if(SiS_Pr->UsePanelScaler == -1) {
2048 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2049 }
2050 break;
2051 case SIS_RI_1280x1024: SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2052 break;
2053 }
2054 break;
2055 }
2056 case Panel_1600x1200: {
2057 static const unsigned char nonscalingmodes[] = {
2058 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2059 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2060 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2061 SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,SIS_RI_1360x1024,0xff
2062 };
2063 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2064 break;
2065 }
2066 case Panel_1680x1050: {
2067 static const unsigned char nonscalingmodes[] = {
2068 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2069 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2070 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,
2071 SIS_RI_1360x1024,0xff
2072 };
2073 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2074 break;
2075 }
2076 }
2077 }
2078
2079 #ifdef SIS300
2080 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2081 if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
2082 SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20; /* neg h/v sync, RGB24(D0 = 0) */
2083 }
2084 }
2085
2086 if(SiS_Pr->ChipType < SIS_315H) {
2087 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2088 if(SiS_Pr->SiS_UseROM) {
2089 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
2090 if(!(ROMAddr[0x235] & 0x02)) {
2091 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2092 }
2093 }
2094 }
2095 } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2096 if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
2097 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2098 }
2099 }
2100 }
2101 #endif
2102
2103 /* Special cases */
2104
2105 if(modexres == SiS_Pr->PanelXRes && modeyres == SiS_Pr->PanelYRes) {
2106 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2107 }
2108
2109 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
2110 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2111 }
2112
2113 switch(SiS_Pr->SiS_LCDResInfo) {
2114 case Panel_640x480:
2115 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2116 break;
2117 case Panel_1280x800:
2118 /* Don't pass 1:1 by default (TMDS special) */
2119 if(SiS_Pr->CenterScreen == -1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2120 break;
2121 case Panel_1280x960:
2122 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2123 break;
2124 case Panel_Custom:
2125 if((!SiS_Pr->CP_PrefClock) ||
2126 (modexres > SiS_Pr->PanelXRes) || (modeyres > SiS_Pr->PanelYRes)) {
2127 SiS_Pr->SiS_LCDInfo |= LCDPass11;
2128 }
2129 break;
2130 }
2131
2132 if((SiS_Pr->UseCustomMode) || (SiS_Pr->SiS_CustomT == CUT_UNKNOWNLCD)) {
2133 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2134 }
2135
2136 /* (In)validate LCDPass11 flag */
2137 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2138 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2139 }
2140
2141 /* LVDS DDA */
2142 if(!((SiS_Pr->ChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
2143
2144 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
2145 if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
2146 if(ModeNo == 0x12) {
2147 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
2148 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2149 }
2150 } else if(ModeNo > 0x13) {
2151 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
2152 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2153 if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) {
2154 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2155 }
2156 }
2157 }
2158 }
2159 }
2160 }
2161
2162 if(modeflag & HalfDCLK) {
2163 if(SiS_Pr->SiS_IF_DEF_TRUMPION == 1) {
2164 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2165 } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
2166 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2167 } else if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) {
2168 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2169 } else if(ModeNo > 0x13) {
2170 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
2171 if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2172 } else if(SiS_Pr->SiS_LCDResInfo == Panel_800x600) {
2173 if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2174 }
2175 }
2176 }
2177
2178 }
2179
2180 /* VESA timing */
2181 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2182 if(SiS_Pr->SiS_VBInfo & SetNotSimuMode) {
2183 SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2184 }
2185 } else {
2186 SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2187 }
2188
2189 #ifdef SIS_LINUX_KERNEL
2190 #if 0
2191 printk(KERN_DEBUG "sisfb: (LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n",
2192 SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo);
2193 #endif
2194 #endif
2195 #ifdef SIS_XORG_XF86
2196 xf86DrvMsgVerb(0, X_PROBED, 4,
2197 "(init301: LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x SetFlag=0x%04x)\n",
2198 SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo, SiS_Pr->SiS_SetFlag);
2199 #endif
2200 }
2201
2202 /*********************************************/
2203 /* GET VCLK */
2204 /*********************************************/
2205
2206 unsigned short
2207 SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
2208 unsigned short RefreshRateTableIndex)
2209 {
2210 unsigned short CRT2Index, VCLKIndex = 0, VCLKIndexGEN = 0, VCLKIndexGENCRT = 0;
2211 unsigned short modeflag, resinfo, tempbx;
2212 const unsigned char *CHTVVCLKPtr = NULL;
2213
2214 if(ModeNo <= 0x13) {
2215 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2216 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
2217 CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2218 VCLKIndexGEN = (SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)) >> 2) & 0x03;
2219 VCLKIndexGENCRT = VCLKIndexGEN;
2220 } else {
2221 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2222 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2223 CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2224 VCLKIndexGEN = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
2225 VCLKIndexGENCRT = SiS_GetRefCRTVCLK(SiS_Pr, RefreshRateTableIndex,
2226 (SiS_Pr->SiS_SetFlag & ProgrammingCRT2) ? SiS_Pr->SiS_UseWideCRT2 : SiS_Pr->SiS_UseWide);
2227 }
2228
2229 if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 30x/B/LV */
2230
2231 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2232
2233 CRT2Index >>= 6;
2234 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /* LCD */
2235
2236 if(SiS_Pr->ChipType < SIS_315H) {
2237 VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2238 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2239 VCLKIndex = VCLKIndexGEN;
2240 }
2241 } else {
2242 VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2243 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2244 switch(resinfo) {
2245 /* Correct those whose IndexGEN doesn't match VBVCLK array */
2246 case SIS_RI_720x480: VCLKIndex = VCLK_720x480; break;
2247 case SIS_RI_720x576: VCLKIndex = VCLK_720x576; break;
2248 case SIS_RI_768x576: VCLKIndex = VCLK_768x576; break;
2249 case SIS_RI_848x480: VCLKIndex = VCLK_848x480; break;
2250 case SIS_RI_856x480: VCLKIndex = VCLK_856x480; break;
2251 case SIS_RI_800x480: VCLKIndex = VCLK_800x480; break;
2252 case SIS_RI_1024x576: VCLKIndex = VCLK_1024x576; break;
2253 case SIS_RI_1152x864: VCLKIndex = VCLK_1152x864; break;
2254 case SIS_RI_1280x720: VCLKIndex = VCLK_1280x720; break;
2255 case SIS_RI_1360x768: VCLKIndex = VCLK_1360x768; break;
2256 default: VCLKIndex = VCLKIndexGEN;
2257 }
2258
2259 if(ModeNo <= 0x13) {
2260 if(SiS_Pr->ChipType <= SIS_315PRO) {
2261 if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
2262 } else {
2263 if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x00;
2264 }
2265 }
2266 if(SiS_Pr->ChipType <= SIS_315PRO) {
2267 if(VCLKIndex == 0) VCLKIndex = 0x41;
2268 if(VCLKIndex == 1) VCLKIndex = 0x43;
2269 if(VCLKIndex == 4) VCLKIndex = 0x44;
2270 }
2271 }
2272 }
2273
2274 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* TV */
2275
2276 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
2277 if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = HiTVVCLKDIV2;
2278 else VCLKIndex = HiTVVCLK;
2279 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) VCLKIndex = HiTVSimuVCLK;
2280 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) VCLKIndex = YPbPr750pVCLK;
2281 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) VCLKIndex = TVVCLKDIV2;
2282 else if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = TVVCLKDIV2;
2283 else VCLKIndex = TVVCLK;
2284
2285 if(SiS_Pr->ChipType < SIS_315H) VCLKIndex += TVCLKBASE_300;
2286 else VCLKIndex += TVCLKBASE_315;
2287
2288 } else { /* VGA2 */
2289
2290 VCLKIndex = VCLKIndexGENCRT;
2291 if(SiS_Pr->ChipType < SIS_315H) {
2292 if(ModeNo > 0x13) {
2293 if( (SiS_Pr->ChipType == SIS_630) &&
2294 (SiS_Pr->ChipRevision >= 0x30)) {
2295 if(VCLKIndex == 0x14) VCLKIndex = 0x34;
2296 }
2297 /* Better VGA2 clock for 1280x1024@75 */
2298 if(VCLKIndex == 0x17) VCLKIndex = 0x45;
2299 }
2300 }
2301 }
2302
2303 } else { /* If not programming CRT2 */
2304
2305 VCLKIndex = VCLKIndexGENCRT;
2306 if(SiS_Pr->ChipType < SIS_315H) {
2307 if(ModeNo > 0x13) {
2308 if( (SiS_Pr->ChipType != SIS_630) &&
2309 (SiS_Pr->ChipType != SIS_300) ) {
2310 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2311 }
2312 }
2313 }
2314 }
2315
2316 } else { /* LVDS */
2317
2318 VCLKIndex = CRT2Index;
2319
2320 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2321
2322 if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
2323
2324 VCLKIndex &= 0x1f;
2325 tempbx = 0;
2326 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2327 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2328 tempbx += 2;
2329 if(SiS_Pr->SiS_ModeType > ModeVGA) {
2330 if(SiS_Pr->SiS_CHSOverScan) tempbx = 8;
2331 }
2332 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
2333 tempbx = 4;
2334 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2335 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
2336 tempbx = 6;
2337 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2338 }
2339 }
2340 switch(tempbx) {
2341 case 0: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUNTSC; break;
2342 case 1: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKONTSC; break;
2343 case 2: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPAL; break;
2344 case 3: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break;
2345 case 4: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALM; break;
2346 case 5: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALM; break;
2347 case 6: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALN; break;
2348 case 7: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALN; break;
2349 case 8: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKSOPAL; break;
2350 default: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break;
2351 }
2352 VCLKIndex = CHTVVCLKPtr[VCLKIndex];
2353
2354 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2355
2356 if(SiS_Pr->ChipType < SIS_315H) {
2357 VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2358 } else {
2359 VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2360 }
2361
2362 #ifdef SIS300
2363 /* Special Timing: Barco iQ Pro R series */
2364 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) VCLKIndex = 0x44;
2365
2366 /* Special Timing: 848x480 and 856x480 parallel lvds panels */
2367 if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
2368 if(SiS_Pr->ChipType < SIS_315H) {
2369 VCLKIndex = VCLK34_300;
2370 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2371 } else {
2372 VCLKIndex = VCLK34_315;
2373 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2374 }
2375 }
2376 #endif
2377
2378 } else {
2379
2380 VCLKIndex = VCLKIndexGENCRT;
2381 if(SiS_Pr->ChipType < SIS_315H) {
2382 if(ModeNo > 0x13) {
2383 if( (SiS_Pr->ChipType == SIS_630) &&
2384 (SiS_Pr->ChipRevision >= 0x30) ) {
2385 if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
2386 }
2387 }
2388 }
2389 }
2390
2391 } else { /* if not programming CRT2 */
2392
2393 VCLKIndex = VCLKIndexGENCRT;
2394 if(SiS_Pr->ChipType < SIS_315H) {
2395 if(ModeNo > 0x13) {
2396 if( (SiS_Pr->ChipType != SIS_630) &&
2397 (SiS_Pr->ChipType != SIS_300) ) {
2398 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2399 }
2400 #if 0
2401 if(SiS_Pr->ChipType == SIS_730) {
2402 if(VCLKIndex == 0x0b) VCLKIndex = 0x40; /* 1024x768-70 */
2403 if(VCLKIndex == 0x0d) VCLKIndex = 0x41; /* 1024x768-75 */
2404 }
2405 #endif
2406 }
2407 }
2408
2409 }
2410
2411 }
2412
2413 #ifdef SIS_XORG_XF86
2414 #ifdef TWDEBUG
2415 xf86DrvMsg(0, X_INFO, "VCLKIndex %d (0x%x)\n", VCLKIndex, VCLKIndex);
2416 #endif
2417 #endif
2418
2419 return VCLKIndex;
2420 }
2421
2422 /*********************************************/
2423 /* SET CRT2 MODE TYPE REGISTERS */
2424 /*********************************************/
2425
2426 static void
2427 SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2428 {
2429 unsigned short i, j, modeflag, tempah=0;
2430 short tempcl;
2431 #if defined(SIS300) || defined(SIS315H)
2432 unsigned short tempbl;
2433 #endif
2434 #ifdef SIS315H
2435 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
2436 unsigned short tempah2, tempbl2;
2437 #endif
2438
2439 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
2440
2441 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
2442
2443 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40);
2444 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2E,0xF7);
2445
2446 } else {
2447
2448 for(i=0,j=4; i<3; i++,j++) SiS_SetReg(SiS_Pr->SiS_Part1Port,j,0);
2449 if(SiS_Pr->ChipType >= SIS_315H) {
2450 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0x7F);
2451 }
2452
2453 tempcl = SiS_Pr->SiS_ModeType;
2454
2455 if(SiS_Pr->ChipType < SIS_315H) {
2456
2457 #ifdef SIS300 /* ---- 300 series ---- */
2458
2459 /* For 301BDH: (with LCD via LVDS) */
2460 if(SiS_Pr->SiS_VBType & VB_NoLCD) {
2461 tempbl = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32);
2462 tempbl &= 0xef;
2463 tempbl |= 0x02;
2464 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2465 tempbl |= 0x10;
2466 tempbl &= 0xfd;
2467 }
2468 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,tempbl);
2469 }
2470
2471 if(ModeNo > 0x13) {
2472 tempcl -= ModeVGA;
2473 if(tempcl >= 0) {
2474 tempah = ((0x10 >> tempcl) | 0x80);
2475 }
2476 } else tempah = 0x80;
2477
2478 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0xA0;
2479
2480 #endif /* SIS300 */
2481
2482 } else {
2483
2484 #ifdef SIS315H /* ------- 315/330 series ------ */
2485
2486 if(ModeNo > 0x13) {
2487 tempcl -= ModeVGA;
2488 if(tempcl >= 0) {
2489 tempah = (0x08 >> tempcl);
2490 if (tempah == 0) tempah = 1;
2491 tempah |= 0x40;
2492 }
2493 } else tempah = 0x40;
2494
2495 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50;
2496
2497 #endif /* SIS315H */
2498
2499 }
2500
2501 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2502
2503 if(SiS_Pr->ChipType < SIS_315H) {
2504 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2505 } else {
2506 #ifdef SIS315H
2507 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2508 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2509 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
2510 if(IS_SIS740) {
2511 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2512 } else {
2513 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2514 }
2515 }
2516 #endif
2517 }
2518
2519 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2520
2521 tempah = 0x01;
2522 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
2523 tempah |= 0x02;
2524 }
2525 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2526 tempah ^= 0x05;
2527 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
2528 tempah ^= 0x01;
2529 }
2530 }
2531
2532 if(SiS_Pr->ChipType < SIS_315H) {
2533
2534 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2535
2536 tempah = (tempah << 5) & 0xFF;
2537 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2538 tempah = (tempah >> 5) & 0xFF;
2539
2540 } else {
2541
2542 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x08;
2543 else if(!(SiS_IsDualEdge(SiS_Pr))) tempah |= 0x08;
2544 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF0,tempah);
2545 tempah &= ~0x08;
2546
2547 }
2548
2549 if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
2550 tempah |= 0x10;
2551 }
2552
2553 tempah |= 0x80;
2554 if(SiS_Pr->SiS_VBType & VB_SIS301) {
2555 if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah &= ~0x80;
2556 }
2557
2558 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2559 if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p))) {
2560 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2561 tempah |= 0x20;
2562 }
2563 }
2564 }
2565
2566 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah);
2567
2568 tempah = 0x80;
2569 if(SiS_Pr->SiS_VBType & VB_SIS301) {
2570 if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah = 0;
2571 }
2572
2573 if(SiS_IsDualLink(SiS_Pr)) tempah |= 0x40;
2574
2575 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2576 if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) {
2577 tempah |= 0x40;
2578 }
2579 }
2580
2581 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0C,tempah);
2582
2583 } else { /* LVDS */
2584
2585 if(SiS_Pr->ChipType >= SIS_315H) {
2586
2587 #ifdef SIS315H
2588 /* LVDS can only be slave in 8bpp modes */
2589 tempah = 0x80;
2590 if((modeflag & CRT2Mode) && (SiS_Pr->SiS_ModeType > ModeVGA)) {
2591 if(SiS_Pr->SiS_VBInfo & DriverMode) {
2592 tempah |= 0x02;
2593 }
2594 }
2595
2596 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) tempah |= 0x02;
2597
2598 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempah ^= 0x01;
2599
2600 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 1;
2601
2602 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah);
2603 #endif
2604
2605 } else {
2606
2607 #ifdef SIS300
2608 tempah = 0;
2609 if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
2610 tempah |= 0x02;
2611 }
2612 tempah <<= 5;
2613
2614 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2615
2616 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2617 #endif
2618
2619 }
2620
2621 }
2622
2623 } /* LCDA */
2624
2625 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2626
2627 if(SiS_Pr->ChipType >= SIS_315H) {
2628
2629 #ifdef SIS315H
2630 /* unsigned char bridgerev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01); */
2631
2632 /* The following is nearly unpreditable and varies from machine
2633 * to machine. Especially the 301DH seems to be a real trouble
2634 * maker. Some BIOSes simply set the registers (like in the
2635 * NoLCD-if-statements here), some set them according to the
2636 * LCDA stuff. It is very likely that some machines are not
2637 * treated correctly in the following, very case-orientated
2638 * code. What do I do then...?
2639 */
2640
2641 /* 740 variants match for 30xB, 301B-DH, 30xLV */
2642
2643 if(!(IS_SIS740)) {
2644 tempah = 0x04; /* For all bridges */
2645 tempbl = 0xfb;
2646 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2647 tempah = 0x00;
2648 if(SiS_IsDualEdge(SiS_Pr)) {
2649 tempbl = 0xff;
2650 }
2651 }
2652 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2653 }
2654
2655 /* The following two are responsible for eventually wrong colors
2656 * in TV output. The DH (VB_NoLCD) conditions are unknown; the
2657 * b0 was found in some 651 machine (Pim; P4_23=0xe5); the b1 version
2658 * in a 650 box (Jake). What is the criteria?
2659 * Addendum: Another combination 651+301B-DH(b1) (Rapo) needs same
2660 * treatment like the 651+301B-DH(b0) case. Seems more to be the
2661 * chipset than the bridge revision.
2662 */
2663
2664 if((IS_SIS740) || (SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
2665 tempah = 0x30;
2666 tempbl = 0xc0;
2667 if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2668 ((SiS_Pr->SiS_ROMNew) && (!(ROMAddr[0x5b] & 0x04)))) {
2669 tempah = 0x00;
2670 tempbl = 0x00;
2671 }
2672 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,tempah);
2673 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,tempbl);
2674 } else if(SiS_Pr->SiS_VBType & VB_SIS301) {
2675 /* Fixes "TV-blue-bug" on 315+301 */
2676 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xcf); /* For 301 */
2677 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2678 } else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
2679 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30); /* For 30xLV */
2680 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);
2681 } else if(SiS_Pr->SiS_VBType & VB_NoLCD) { /* For 301B-DH */
2682 tempah = 0x30; tempah2 = 0xc0;
2683 tempbl = 0xcf; tempbl2 = 0x3f;
2684 if(SiS_Pr->SiS_TVBlue == 0) {
2685 tempah = tempah2 = 0x00;
2686 } else if(SiS_Pr->SiS_TVBlue == -1) {
2687 /* Set on 651/M650, clear on 315/650 */
2688 if(!(IS_SIS65x)) /* (bridgerev != 0xb0) */ {
2689 tempah = tempah2 = 0x00;
2690 }
2691 }
2692 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2693 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2694 } else {
2695 tempah = 0x30; tempah2 = 0xc0; /* For 30xB, 301C */
2696 tempbl = 0xcf; tempbl2 = 0x3f;
2697 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2698 tempah = tempah2 = 0x00;
2699 if(SiS_IsDualEdge(SiS_Pr)) {
2700 tempbl = tempbl2 = 0xff;
2701 }
2702 }
2703 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2704 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2705 }
2706
2707 if(IS_SIS740) {
2708 tempah = 0x80;
2709 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x00;
2710 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,0x7f,tempah);
2711 } else {
2712 tempah = 0x00;
2713 tempbl = 0x7f;
2714 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2715 tempbl = 0xff;
2716 if(!(SiS_IsDualEdge(SiS_Pr))) tempah = 0x80;
2717 }
2718 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
2719 }
2720
2721 #endif /* SIS315H */
2722
2723 } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2724
2725 #ifdef SIS300
2726 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2727
2728 if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2729 ((SiS_Pr->SiS_VBType & VB_NoLCD) &&
2730 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD))) {
2731 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x23,0x7F);
2732 } else {
2733 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x23,0x80);
2734 }
2735 #endif
2736
2737 }
2738
2739 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2740 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x0D,0x80);
2741 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
2742 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3A,0xC0);
2743 }
2744 }
2745
2746 } else { /* LVDS */
2747
2748 #ifdef SIS315H
2749 if(SiS_Pr->ChipType >= SIS_315H) {
2750
2751 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
2752
2753 tempah = 0x04;
2754 tempbl = 0xfb;
2755 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2756 tempah = 0x00;
2757 if(SiS_IsDualEdge(SiS_Pr)) tempbl = 0xff;
2758 }
2759 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2760
2761 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
2762 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
2763 }
2764
2765 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
2766
2767 } else if(SiS_Pr->ChipType == SIS_550) {
2768
2769 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
2770 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
2771
2772 }
2773
2774 }
2775 #endif
2776
2777 }
2778
2779 }
2780
2781 /*********************************************/
2782 /* GET RESOLUTION DATA */
2783 /*********************************************/
2784
2785 unsigned short
2786 SiS_GetResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2787 {
2788 if(ModeNo <= 0x13)
2789 return ((unsigned short)SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo);
2790 else
2791 return ((unsigned short)SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO);
2792 }
2793
2794 static void
2795 SiS_GetCRT2ResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2796 {
2797 unsigned short xres, yres, modeflag=0, resindex;
2798
2799 if(SiS_Pr->UseCustomMode) {
2800 xres = SiS_Pr->CHDisplay;
2801 if(SiS_Pr->CModeFlag & HalfDCLK) xres <<= 1;
2802 SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
2803 /* DoubleScanMode-check done in CheckCalcCustomMode()! */
2804 SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = SiS_Pr->CVDisplay;
2805 return;
2806 }
2807
2808 resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex);
2809
2810 if(ModeNo <= 0x13) {
2811 xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
2812 yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
2813 } else {
2814 xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
2815 yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
2816 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2817 }
2818
2819 if(!SiS_Pr->SiS_IF_DEF_DSTN && !SiS_Pr->SiS_IF_DEF_FSTN) {
2820
2821 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
2822 if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
2823 if(yres == 350) yres = 400;
2824 }
2825 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
2826 if(ModeNo == 0x12) yres = 400;
2827 }
2828 }
2829
2830 if(modeflag & HalfDCLK) xres <<= 1;
2831 if(modeflag & DoubleScanMode) yres <<= 1;
2832
2833 }
2834
2835 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
2836
2837 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2838 switch(SiS_Pr->SiS_LCDResInfo) {
2839 case Panel_1024x768:
2840 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
2841 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2842 if(yres == 350) yres = 357;
2843 if(yres == 400) yres = 420;
2844 if(yres == 480) yres = 525;
2845 }
2846 }
2847 break;
2848 case Panel_1280x1024:
2849 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2850 /* BIOS bug - does this regardless of scaling */
2851 if(yres == 400) yres = 405;
2852 }
2853 if(yres == 350) yres = 360;
2854 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
2855 if(yres == 360) yres = 375;
2856 }
2857 break;
2858 case Panel_1600x1200:
2859 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
2860 if(yres == 1024) yres = 1056;
2861 }
2862 break;
2863 }
2864 }
2865
2866 } else {
2867
2868 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2869 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVision)) {
2870 if(xres == 720) xres = 640;
2871 }
2872 } else if(xres == 720) xres = 640;
2873
2874 if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
2875 yres = 400;
2876 if(SiS_Pr->ChipType >= SIS_315H) {
2877 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
2878 } else {
2879 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
2880 }
2881 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) yres = 480;
2882 }
2883
2884 }
2885 SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
2886 SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
2887 }
2888
2889 /*********************************************/
2890 /* GET CRT2 TIMING DATA */
2891 /*********************************************/
2892
2893 static void
2894 SiS_GetCRT2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
2895 unsigned short RefreshRateTableIndex, unsigned short *CRT2Index,
2896 unsigned short *ResIndex)
2897 {
2898 unsigned short tempbx=0, tempal=0, resinfo=0;
2899
2900 if(ModeNo <= 0x13) {
2901 tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2902 } else {
2903 tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2904 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2905 }
2906
2907 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_IF_DEF_LVDS == 0)) {
2908
2909 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { /* LCD */
2910
2911 tempbx = SiS_Pr->SiS_LCDResInfo;
2912 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 32;
2913
2914 /* patch index */
2915 if(SiS_Pr->SiS_LCDResInfo == Panel_1680x1050) {
2916 if (resinfo == SIS_RI_1280x800) tempal = 9;
2917 else if(resinfo == SIS_RI_1400x1050) tempal = 11;
2918 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x800) ||
2919 (SiS_Pr->SiS_LCDResInfo == Panel_1280x800_2) ||
2920 (SiS_Pr->SiS_LCDResInfo == Panel_1280x854)) {
2921 if (resinfo == SIS_RI_1280x768) tempal = 9;
2922 }
2923
2924 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
2925 /* Pass 1:1 only (center-screen handled outside) */
2926 /* This is never called for the panel's native resolution */
2927 /* since Pass1:1 will not be set in this case */
2928 tempbx = 100;
2929 if(ModeNo >= 0x13) {
2930 tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
2931 }
2932 }
2933
2934 #ifdef SIS315H
2935 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
2936 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
2937 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2938 tempbx = 200;
2939 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
2940 }
2941 }
2942 }
2943 #endif
2944
2945 } else { /* TV */
2946
2947 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
2948 /* if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_TVMode &= (~TVSetTVSimuMode); */
2949 tempbx = 2;
2950 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2951 tempbx = 13;
2952 if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) tempbx = 14;
2953 }
2954 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2955 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempbx = 7;
2956 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempbx = 6;
2957 else tempbx = 5;
2958 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5;
2959 } else {
2960 if(SiS_Pr->SiS_TVMode & TVSetPAL) tempbx = 3;
2961 else tempbx = 4;
2962 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5;
2963 }
2964
2965 }
2966
2967 tempal &= 0x3F;
2968
2969 if(ModeNo > 0x13) {
2970 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) {
2971 switch(resinfo) {
2972 case SIS_RI_720x480:
2973 tempal = 6;
2974 if(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetPALN)) tempal = 9;
2975 break;
2976 case SIS_RI_720x576:
2977 case SIS_RI_768x576:
2978 case SIS_RI_1024x576: /* Not in NTSC or YPBPR mode (except 1080i)! */
2979 tempal = 6;
2980 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2981 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempal = 8;
2982 }
2983 break;
2984 case SIS_RI_800x480:
2985 tempal = 4;
2986 break;
2987 case SIS_RI_512x384:
2988 case SIS_RI_1024x768:
2989 tempal = 7;
2990 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2991 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempal = 8;
2992 }
2993 break;
2994 case SIS_RI_1280x720:
2995 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2996 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempal = 9;
2997 }
2998 break;
2999 }
3000 }
3001 }
3002
3003 *CRT2Index = tempbx;
3004 *ResIndex = tempal;
3005
3006 } else { /* LVDS, 301B-DH (if running on LCD) */
3007
3008 tempbx = 0;
3009 if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
3010
3011 tempbx = 90;
3012 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
3013 tempbx = 92;
3014 if(SiS_Pr->SiS_ModeType > ModeVGA) {
3015 if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
3016 }
3017 if(SiS_Pr->SiS_TVMode & TVSetPALM) tempbx = 94;
3018 else if(SiS_Pr->SiS_TVMode & TVSetPALN) tempbx = 96;
3019 }
3020 if(tempbx != 99) {
3021 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx++;
3022 }
3023
3024 } else {
3025
3026 switch(SiS_Pr->SiS_LCDResInfo) {
3027 case Panel_640x480: tempbx = 12; break;
3028 case Panel_320x240_1: tempbx = 10; break;
3029 case Panel_320x240_2:
3030 case Panel_320x240_3: tempbx = 14; break;
3031 case Panel_800x600: tempbx = 16; break;
3032 case Panel_1024x600: tempbx = 18; break;
3033 case Panel_1152x768:
3034 case Panel_1024x768: tempbx = 20; break;
3035 case Panel_1280x768: tempbx = 22; break;
3036 case Panel_1280x1024: tempbx = 24; break;
3037 case Panel_1400x1050: tempbx = 26; break;
3038 case Panel_1600x1200: tempbx = 28; break;
3039 #ifdef SIS300
3040 case Panel_Barco1366: tempbx = 80; break;
3041 #endif
3042 }
3043
3044 switch(SiS_Pr->SiS_LCDResInfo) {
3045 case Panel_320x240_1:
3046 case Panel_320x240_2:
3047 case Panel_320x240_3:
3048 case Panel_640x480:
3049 break;
3050 default:
3051 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3052 }
3053
3054 if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempbx = 30;
3055
3056 #ifdef SIS300
3057 if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
3058 tempbx = 82;
3059 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3060 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
3061 tempbx = 84;
3062 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3063 }
3064 #endif
3065
3066 }
3067
3068 (*CRT2Index) = tempbx;
3069 (*ResIndex) = tempal & 0x1F;
3070 }
3071 }
3072
3073 static void
3074 SiS_GetRAMDAC2DATA(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3075 unsigned short RefreshRateTableIndex)
3076 {
3077 unsigned short tempax=0, tempbx=0, index, dotclock;
3078 unsigned short temp1=0, modeflag=0, tempcx=0;
3079
3080 SiS_Pr->SiS_RVBHCMAX = 1;
3081 SiS_Pr->SiS_RVBHCFACT = 1;
3082
3083 if(ModeNo <= 0x13) {
3084
3085 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3086 index = SiS_GetModePtr(SiS_Pr,ModeNo,ModeIdIndex);
3087
3088 tempax = SiS_Pr->SiS_StandTable[index].CRTC[0];
3089 tempbx = SiS_Pr->SiS_StandTable[index].CRTC[6];
3090 temp1 = SiS_Pr->SiS_StandTable[index].CRTC[7];
3091
3092 dotclock = (modeflag & Charx8Dot) ? 8 : 9;
3093
3094 } else {
3095
3096 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3097 index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);
3098
3099 tempax = SiS_Pr->SiS_CRT1Table[index].CR[0];
3100 tempax |= (SiS_Pr->SiS_CRT1Table[index].CR[14] << 8);
3101 tempax &= 0x03FF;
3102 tempbx = SiS_Pr->SiS_CRT1Table[index].CR[6];
3103 tempcx = SiS_Pr->SiS_CRT1Table[index].CR[13] << 8;
3104 tempcx &= 0x0100;
3105 tempcx <<= 2;
3106 tempbx |= tempcx;
3107 temp1 = SiS_Pr->SiS_CRT1Table[index].CR[7];
3108
3109 dotclock = 8;
3110
3111 }
3112
3113 if(temp1 & 0x01) tempbx |= 0x0100;
3114 if(temp1 & 0x20) tempbx |= 0x0200;
3115
3116 tempax += 5;
3117 tempax *= dotclock;
3118 if(modeflag & HalfDCLK) tempax <<= 1;
3119
3120 tempbx++;
3121
3122 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3123 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = tempbx;
3124 }
3125
3126 static void
3127 SiS_CalcPanelLinkTiming(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
3128 unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex)
3129 {
3130 unsigned short ResIndex;
3131
3132 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3133 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
3134 if(SiS_Pr->UseCustomMode) {
3135 ResIndex = SiS_Pr->CHTotal;
3136 if(SiS_Pr->CModeFlag & HalfDCLK) ResIndex <<= 1;
3137 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = ResIndex;
3138 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3139 } else {
3140 if(ModeNo < 0x13) {
3141 ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3142 } else {
3143 ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
3144 }
3145 if(ResIndex == 0x09) {
3146 if(SiS_Pr->Alternate1600x1200) ResIndex = 0x20; /* 1600x1200 LCDA */
3147 else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) ResIndex = 0x21; /* 1600x1200 LVDS */
3148 }
3149 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAHT;
3150 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAVT;
3151 SiS_Pr->SiS_HT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDHT;
3152 SiS_Pr->SiS_VT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDVT;
3153 }
3154 } else {
3155 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3156 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3157 }
3158 } else {
3159 /* This handles custom modes and custom panels */
3160 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3161 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3162 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3163 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3164 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT - (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE);
3165 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT - (SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE);
3166 }
3167 }
3168
3169 static void
3170 SiS_GetCRT2DataLVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3171 unsigned short RefreshRateTableIndex)
3172 {
3173 unsigned short CRT2Index, ResIndex, backup;
3174 const struct SiS_LVDSData *LVDSData = NULL;
3175
3176 SiS_GetCRT2ResInfo(SiS_Pr, ModeNo, ModeIdIndex);
3177
3178 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3179 SiS_Pr->SiS_RVBHCMAX = 1;
3180 SiS_Pr->SiS_RVBHCFACT = 1;
3181 SiS_Pr->SiS_NewFlickerMode = 0;
3182 SiS_Pr->SiS_RVBHRS = 50;
3183 SiS_Pr->SiS_RY1COE = 0;
3184 SiS_Pr->SiS_RY2COE = 0;
3185 SiS_Pr->SiS_RY3COE = 0;
3186 SiS_Pr->SiS_RY4COE = 0;
3187 SiS_Pr->SiS_RVBHRS2 = 0;
3188 }
3189
3190 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3191
3192 #ifdef SIS315H
3193 SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3194 SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
3195 #endif
3196
3197 } else {
3198
3199 /* 301BDH needs LVDS Data */
3200 backup = SiS_Pr->SiS_IF_DEF_LVDS;
3201 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3202 SiS_Pr->SiS_IF_DEF_LVDS = 1;
3203 }
3204
3205 SiS_GetCRT2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
3206 &CRT2Index, &ResIndex);
3207
3208 SiS_Pr->SiS_IF_DEF_LVDS = backup;
3209
3210 switch(CRT2Index) {
3211 case 10: LVDSData = SiS_Pr->SiS_LVDS320x240Data_1; break;
3212 case 14: LVDSData = SiS_Pr->SiS_LVDS320x240Data_2; break;
3213 case 12: LVDSData = SiS_Pr->SiS_LVDS640x480Data_1; break;
3214 case 16: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1; break;
3215 case 18: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1; break;
3216 case 20: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break;
3217 #ifdef SIS300
3218 case 80: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1; break;
3219 case 81: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2; break;
3220 case 82: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1; break;
3221 case 84: LVDSData = SiS_Pr->SiS_LVDS848x480Data_1; break;
3222 case 85: LVDSData = SiS_Pr->SiS_LVDS848x480Data_2; break;
3223 #endif
3224 case 90: LVDSData = SiS_Pr->SiS_CHTVUNTSCData; break;
3225 case 91: LVDSData = SiS_Pr->SiS_CHTVONTSCData; break;
3226 case 92: LVDSData = SiS_Pr->SiS_CHTVUPALData; break;
3227 case 93: LVDSData = SiS_Pr->SiS_CHTVOPALData; break;
3228 case 94: LVDSData = SiS_Pr->SiS_CHTVUPALMData; break;
3229 case 95: LVDSData = SiS_Pr->SiS_CHTVOPALMData; break;
3230 case 96: LVDSData = SiS_Pr->SiS_CHTVUPALNData; break;
3231 case 97: LVDSData = SiS_Pr->SiS_CHTVOPALNData; break;
3232 case 99: LVDSData = SiS_Pr->SiS_CHTVSOPALData; break;
3233 }
3234
3235 if(LVDSData) {
3236 SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT;
3237 SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT;
3238 SiS_Pr->SiS_HT = (LVDSData+ResIndex)->LCDHT;
3239 SiS_Pr->SiS_VT = (LVDSData+ResIndex)->LCDVT;
3240 } else {
3241 SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3242 }
3243
3244 if( (!(SiS_Pr->SiS_VBType & VB_SISVB)) &&
3245 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
3246 (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) ) {
3247 if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ||
3248 (SiS_Pr->SiS_SetFlag & SetDOSMode) ) {
3249 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3250 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3251 #ifdef SIS300
3252 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3253 if(ResIndex < 0x08) {
3254 SiS_Pr->SiS_HDE = 1280;
3255 SiS_Pr->SiS_VDE = 1024;
3256 }
3257 }
3258 #endif
3259 }
3260 }
3261 }
3262 }
3263
3264 static void
3265 SiS_GetCRT2Data301(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3266 unsigned short RefreshRateTableIndex)
3267 {
3268 unsigned char *ROMAddr = NULL;
3269 unsigned short tempax, tempbx, modeflag, romptr=0;
3270 unsigned short resinfo, CRT2Index, ResIndex;
3271 const struct SiS_LCDData *LCDPtr = NULL;
3272 const struct SiS_TVData *TVPtr = NULL;
3273 #ifdef SIS315H
3274 short resinfo661;
3275 #endif
3276
3277 if(ModeNo <= 0x13) {
3278 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3279 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
3280 } else if(SiS_Pr->UseCustomMode) {
3281 modeflag = SiS_Pr->CModeFlag;
3282 resinfo = 0;
3283 } else {
3284 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3285 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
3286 #ifdef SIS315H
3287 resinfo661 = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].ROMMODEIDX661;
3288 if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
3289 (SiS_Pr->SiS_SetFlag & LCDVESATiming) &&
3290 (resinfo661 >= 0) &&
3291 (SiS_Pr->SiS_NeedRomModeData) ) {
3292 if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
3293 if((romptr = (SISGETROMW(21)))) {
3294 romptr += (resinfo661 * 10);
3295 ROMAddr = SiS_Pr->VirtualRomBase;
3296 }
3297 }
3298 }
3299 #endif
3300 }
3301
3302 SiS_Pr->SiS_NewFlickerMode = 0;
3303 SiS_Pr->SiS_RVBHRS = 50;
3304 SiS_Pr->SiS_RY1COE = 0;
3305 SiS_Pr->SiS_RY2COE = 0;
3306 SiS_Pr->SiS_RY3COE = 0;
3307 SiS_Pr->SiS_RY4COE = 0;
3308 SiS_Pr->SiS_RVBHRS2 = 0;
3309
3310 SiS_GetCRT2ResInfo(SiS_Pr,ModeNo,ModeIdIndex);
3311
3312 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
3313
3314 if(SiS_Pr->UseCustomMode) {
3315
3316 SiS_Pr->SiS_RVBHCMAX = 1;
3317 SiS_Pr->SiS_RVBHCFACT = 1;
3318 SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE;
3319 SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE;
3320
3321 tempax = SiS_Pr->CHTotal;
3322 if(modeflag & HalfDCLK) tempax <<= 1;
3323 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3324 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3325
3326 } else {
3327
3328 SiS_GetRAMDAC2DATA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3329
3330 }
3331
3332 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
3333
3334 SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3335 &CRT2Index,&ResIndex);
3336
3337 switch(CRT2Index) {
3338 case 2: TVPtr = SiS_Pr->SiS_ExtHiTVData; break;
3339 case 3: TVPtr = SiS_Pr->SiS_ExtPALData; break;
3340 case 4: TVPtr = SiS_Pr->SiS_ExtNTSCData; break;
3341 case 5: TVPtr = SiS_Pr->SiS_Ext525iData; break;
3342 case 6: TVPtr = SiS_Pr->SiS_Ext525pData; break;
3343 case 7: TVPtr = SiS_Pr->SiS_Ext750pData; break;
3344 case 8: TVPtr = SiS_Pr->SiS_StPALData; break;
3345 case 9: TVPtr = SiS_Pr->SiS_StNTSCData; break;
3346 case 10: TVPtr = SiS_Pr->SiS_St525iData; break;
3347 case 11: TVPtr = SiS_Pr->SiS_St525pData; break;
3348 case 12: TVPtr = SiS_Pr->SiS_St750pData; break;
3349 case 13: TVPtr = SiS_Pr->SiS_St1HiTVData; break;
3350 case 14: TVPtr = SiS_Pr->SiS_St2HiTVData; break;
3351 default: TVPtr = SiS_Pr->SiS_StPALData; break;
3352 }
3353
3354 SiS_Pr->SiS_RVBHCMAX = (TVPtr+ResIndex)->RVBHCMAX;
3355 SiS_Pr->SiS_RVBHCFACT = (TVPtr+ResIndex)->RVBHCFACT;
3356 SiS_Pr->SiS_VGAHT = (TVPtr+ResIndex)->VGAHT;
3357 SiS_Pr->SiS_VGAVT = (TVPtr+ResIndex)->VGAVT;
3358 SiS_Pr->SiS_HDE = (TVPtr+ResIndex)->TVHDE;
3359 SiS_Pr->SiS_VDE = (TVPtr+ResIndex)->TVVDE;
3360 SiS_Pr->SiS_RVBHRS2 = (TVPtr+ResIndex)->RVBHRS2 & 0x0fff;
3361 if(modeflag & HalfDCLK) {
3362 SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->HALFRVBHRS;
3363 if(SiS_Pr->SiS_RVBHRS2) {
3364 SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
3365 tempax = ((TVPtr+ResIndex)->RVBHRS2 >> 12) & 0x07;
3366 if((TVPtr+ResIndex)->RVBHRS2 & 0x8000) SiS_Pr->SiS_RVBHRS2 -= tempax;
3367 else SiS_Pr->SiS_RVBHRS2 += tempax;
3368 }
3369 } else {
3370 SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->RVBHRS;
3371 }
3372 SiS_Pr->SiS_NewFlickerMode = ((TVPtr+ResIndex)->FlickerMode) << 7;
3373
3374 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
3375
3376 if((resinfo == SIS_RI_960x600) ||
3377 (resinfo == SIS_RI_1024x768) ||
3378 (resinfo == SIS_RI_1280x1024) ||
3379 (resinfo == SIS_RI_1280x720)) {
3380 SiS_Pr->SiS_NewFlickerMode = 0x40;
3381 }
3382
3383 if(SiS_Pr->SiS_VGAVDE == 350) SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
3384
3385 SiS_Pr->SiS_HT = ExtHiTVHT;
3386 SiS_Pr->SiS_VT = ExtHiTVVT;
3387 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
3388 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
3389 SiS_Pr->SiS_HT = StHiTVHT;
3390 SiS_Pr->SiS_VT = StHiTVVT;
3391 }
3392 }
3393
3394 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3395
3396 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
3397 SiS_Pr->SiS_HT = 1650;
3398 SiS_Pr->SiS_VT = 750;
3399 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
3400 SiS_Pr->SiS_HT = NTSCHT;
3401 if(SiS_Pr->SiS_TVMode & TVSet525p1024) SiS_Pr->SiS_HT = NTSC2HT;
3402 SiS_Pr->SiS_VT = NTSCVT;
3403 } else {
3404 SiS_Pr->SiS_HT = NTSCHT;
3405 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3406 SiS_Pr->SiS_VT = NTSCVT;
3407 }
3408
3409 } else {
3410
3411 SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
3412 SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
3413 SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
3414 SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
3415
3416 if(modeflag & HalfDCLK) {
3417 SiS_Pr->SiS_RY1COE = 0x00;
3418 SiS_Pr->SiS_RY2COE = 0xf4;
3419 SiS_Pr->SiS_RY3COE = 0x10;
3420 SiS_Pr->SiS_RY4COE = 0x38;
3421 }
3422
3423 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
3424 SiS_Pr->SiS_HT = NTSCHT;
3425 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3426 SiS_Pr->SiS_VT = NTSCVT;
3427 } else {
3428 SiS_Pr->SiS_HT = PALHT;
3429 SiS_Pr->SiS_VT = PALVT;
3430 }
3431
3432 }
3433
3434 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3435
3436 SiS_Pr->SiS_RVBHCMAX = 1;
3437 SiS_Pr->SiS_RVBHCFACT = 1;
3438
3439 if(SiS_Pr->UseCustomMode) {
3440
3441 SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE;
3442 SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE;
3443
3444 tempax = SiS_Pr->CHTotal;
3445 if(modeflag & HalfDCLK) tempax <<= 1;
3446 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3447 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3448
3449 } else {
3450
3451 bool gotit = false;
3452
3453 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
3454
3455 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
3456 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
3457 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3458 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3459 gotit = true;
3460
3461 } else if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) && (romptr) && (ROMAddr) ) {
3462
3463 #ifdef SIS315H
3464 SiS_Pr->SiS_RVBHCMAX = ROMAddr[romptr];
3465 SiS_Pr->SiS_RVBHCFACT = ROMAddr[romptr+1];
3466 SiS_Pr->SiS_VGAHT = ROMAddr[romptr+2] | ((ROMAddr[romptr+3] & 0x0f) << 8);
3467 SiS_Pr->SiS_VGAVT = (ROMAddr[romptr+4] << 4) | ((ROMAddr[romptr+3] & 0xf0) >> 4);
3468 SiS_Pr->SiS_HT = ROMAddr[romptr+5] | ((ROMAddr[romptr+6] & 0x0f) << 8);
3469 SiS_Pr->SiS_VT = (ROMAddr[romptr+7] << 4) | ((ROMAddr[romptr+6] & 0xf0) >> 4);
3470 SiS_Pr->SiS_RVBHRS2 = ROMAddr[romptr+8] | ((ROMAddr[romptr+9] & 0x0f) << 8);
3471 if((SiS_Pr->SiS_RVBHRS2) && (modeflag & HalfDCLK)) {
3472 SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
3473 tempax = (ROMAddr[romptr+9] >> 4) & 0x07;
3474 if(ROMAddr[romptr+9] & 0x80) SiS_Pr->SiS_RVBHRS2 -= tempax;
3475 else SiS_Pr->SiS_RVBHRS2 += tempax;
3476 }
3477 if(SiS_Pr->SiS_VGAHT) gotit = true;
3478 else {
3479 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
3480 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
3481 SiS_Pr->SiS_RVBHCMAX = 1;
3482 SiS_Pr->SiS_RVBHCFACT = 1;
3483 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
3484 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
3485 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3486 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3487 SiS_Pr->SiS_RVBHRS2 = 0;
3488 gotit = true;
3489 }
3490 #endif
3491
3492 }
3493
3494 if(!gotit) {
3495
3496 SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3497 &CRT2Index,&ResIndex);
3498
3499 switch(CRT2Index) {
3500 case Panel_1024x768 : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break;
3501 case Panel_1024x768 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data; break;
3502 case Panel_1280x720 :
3503 case Panel_1280x720 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x720Data; break;
3504 case Panel_1280x768_2 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x768_2Data; break;
3505 case Panel_1280x768_2+ 32: LCDPtr = SiS_Pr->SiS_StLCD1280x768_2Data; break;
3506 case Panel_1280x800 :
3507 case Panel_1280x800 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x800Data; break;
3508 case Panel_1280x800_2 :
3509 case Panel_1280x800_2+ 32: LCDPtr = SiS_Pr->SiS_LCD1280x800_2Data; break;
3510 case Panel_1280x854 :
3511 case Panel_1280x854 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x854Data; break;
3512 case Panel_1280x960 :
3513 case Panel_1280x960 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x960Data; break;
3514 case Panel_1280x1024 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data; break;
3515 case Panel_1280x1024 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
3516 case Panel_1400x1050 : LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data; break;
3517 case Panel_1400x1050 + 32: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data; break;
3518 case Panel_1600x1200 : LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data; break;
3519 case Panel_1600x1200 + 32: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data; break;
3520 case Panel_1680x1050 :
3521 case Panel_1680x1050 + 32: LCDPtr = SiS_Pr->SiS_LCD1680x1050Data; break;
3522 case 100 : LCDPtr = SiS_Pr->SiS_NoScaleData; break;
3523 #ifdef SIS315H
3524 case 200 : LCDPtr = SiS310_ExtCompaq1280x1024Data; break;
3525 case 201 : LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
3526 #endif
3527 default : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break;
3528 }
3529
3530 #ifdef SIS_XORG_XF86
3531 #ifdef TWDEBUG
3532 xf86DrvMsg(0, X_INFO, "GetCRT2Data: Index %d ResIndex %d\n", CRT2Index, ResIndex);
3533 #endif
3534 #endif
3535
3536 SiS_Pr->SiS_RVBHCMAX = (LCDPtr+ResIndex)->RVBHCMAX;
3537 SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
3538 SiS_Pr->SiS_VGAHT = (LCDPtr+ResIndex)->VGAHT;
3539 SiS_Pr->SiS_VGAVT = (LCDPtr+ResIndex)->VGAVT;
3540 SiS_Pr->SiS_HT = (LCDPtr+ResIndex)->LCDHT;
3541 SiS_Pr->SiS_VT = (LCDPtr+ResIndex)->LCDVT;
3542
3543 }
3544
3545 tempax = SiS_Pr->PanelXRes;
3546 tempbx = SiS_Pr->PanelYRes;
3547
3548 switch(SiS_Pr->SiS_LCDResInfo) {
3549 case Panel_1024x768:
3550 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
3551 if(SiS_Pr->ChipType < SIS_315H) {
3552 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3553 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3554 }
3555 } else {
3556 if (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
3557 else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
3558 else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
3559 else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
3560 else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3561 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3562 }
3563 break;
3564 case Panel_1280x960:
3565 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 700;
3566 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 800;
3567 else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
3568 break;
3569 case Panel_1280x1024:
3570 if (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
3571 else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
3572 else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
3573 break;
3574 case Panel_1600x1200:
3575 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
3576 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 875;
3577 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 1000;
3578 }
3579 break;
3580 }
3581
3582 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3583 tempax = SiS_Pr->SiS_VGAHDE;
3584 tempbx = SiS_Pr->SiS_VGAVDE;
3585 }
3586
3587 SiS_Pr->SiS_HDE = tempax;
3588 SiS_Pr->SiS_VDE = tempbx;
3589 }
3590 }
3591 }
3592
3593 static void
3594 SiS_GetCRT2Data(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3595 unsigned short RefreshRateTableIndex)
3596 {
3597
3598 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3599
3600 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
3601 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3602 } else {
3603 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3604 /* Need LVDS Data for LCD on 301B-DH */
3605 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3606 } else {
3607 SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3608 }
3609 }
3610
3611 } else {
3612
3613 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3614
3615 }
3616 }
3617
3618 /*********************************************/
3619 /* GET LVDS DES (SKEW) DATA */
3620 /*********************************************/
3621
3622 static const struct SiS_LVDSDes *
3623 SiS_GetLVDSDesPtr(struct SiS_Private *SiS_Pr)
3624 {
3625 const struct SiS_LVDSDes *PanelDesPtr = NULL;
3626
3627 #ifdef SIS300
3628 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3629
3630 if(SiS_Pr->ChipType < SIS_315H) {
3631 if(SiS_Pr->SiS_LCDTypeInfo == 4) {
3632 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3633 PanelDesPtr = SiS_Pr->SiS_PanelType04_1a;
3634 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3635 PanelDesPtr = SiS_Pr->SiS_PanelType04_2a;
3636 }
3637 } else if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
3638 PanelDesPtr = SiS_Pr->SiS_PanelType04_1b;
3639 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3640 PanelDesPtr = SiS_Pr->SiS_PanelType04_2b;
3641 }
3642 }
3643 }
3644 }
3645 }
3646 #endif
3647 return PanelDesPtr;
3648 }
3649
3650 static void
3651 SiS_GetLVDSDesData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3652 unsigned short RefreshRateTableIndex)
3653 {
3654 unsigned short modeflag, ResIndex;
3655 const struct SiS_LVDSDes *PanelDesPtr = NULL;
3656
3657 SiS_Pr->SiS_LCDHDES = 0;
3658 SiS_Pr->SiS_LCDVDES = 0;
3659
3660 /* Some special cases */
3661 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3662
3663 /* Trumpion */
3664 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
3665 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3666 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3667 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3668 }
3669 }
3670 return;
3671 }
3672
3673 /* 640x480 on LVDS */
3674 if(SiS_Pr->ChipType < SIS_315H) {
3675 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480 && SiS_Pr->SiS_LCDTypeInfo == 3) {
3676 SiS_Pr->SiS_LCDHDES = 8;
3677 if (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
3678 else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
3679 else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
3680 return;
3681 }
3682 }
3683
3684 } /* LCD */
3685
3686 if( (SiS_Pr->UseCustomMode) ||
3687 (SiS_Pr->SiS_LCDResInfo == Panel_Custom) ||
3688 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
3689 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ||
3690 (SiS_Pr->SiS_LCDInfo & LCDPass11) ) {
3691 return;
3692 }
3693
3694 if(ModeNo <= 0x13) ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3695 else ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
3696
3697 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3698
3699 #ifdef SIS315H
3700 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3701 /* non-pass 1:1 only, see above */
3702 if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
3703 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
3704 }
3705 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
3706 SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
3707 }
3708 }
3709 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3710 switch(SiS_Pr->SiS_CustomT) {
3711 case CUT_UNIWILL1024:
3712 case CUT_UNIWILL10242:
3713 case CUT_CLEVO1400:
3714 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3715 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3716 }
3717 break;
3718 }
3719 switch(SiS_Pr->SiS_LCDResInfo) {
3720 case Panel_1280x1024:
3721 if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
3722 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3723 }
3724 break;
3725 case Panel_1280x800: /* Verified for Averatec 6240 */
3726 case Panel_1280x800_2: /* Verified for Asus A4L */
3727 case Panel_1280x854: /* Not verified yet FIXME */
3728 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3729 break;
3730 }
3731 }
3732 #endif
3733
3734 } else {
3735
3736 if((SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
3737
3738 if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
3739 if(ResIndex <= 3) SiS_Pr->SiS_LCDHDES = 256;
3740 }
3741
3742 } else if((PanelDesPtr = SiS_GetLVDSDesPtr(SiS_Pr))) {
3743
3744 SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
3745 SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;
3746
3747 } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3748
3749 if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
3750 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
3751 }
3752 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
3753 SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
3754 } else {
3755 if(SiS_Pr->ChipType < SIS_315H) {
3756 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3757 } else {
3758 switch(SiS_Pr->SiS_LCDResInfo) {
3759 case Panel_800x600:
3760 case Panel_1024x768:
3761 case Panel_1280x1024:
3762 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
3763 break;
3764 case Panel_1400x1050:
3765 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3766 break;
3767 }
3768 }
3769 }
3770
3771 } else {
3772
3773 if(SiS_Pr->ChipType < SIS_315H) {
3774 #ifdef SIS300
3775 switch(SiS_Pr->SiS_LCDResInfo) {
3776 case Panel_800x600:
3777 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3778 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3779 } else {
3780 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT + 3;
3781 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
3782 if(SiS_Pr->SiS_VGAVDE == 400) SiS_Pr->SiS_LCDVDES -= 2;
3783 else SiS_Pr->SiS_LCDVDES -= 4;
3784 }
3785 break;
3786 case Panel_1024x768:
3787 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3788 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3789 } else {
3790 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
3791 if(SiS_Pr->SiS_VGAVDE <= 400) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 8;
3792 if(SiS_Pr->SiS_VGAVDE <= 350) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 12;
3793 }
3794 break;
3795 case Panel_1024x600:
3796 default:
3797 if( (SiS_Pr->SiS_VGAHDE == SiS_Pr->PanelXRes) &&
3798 (SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) ) {
3799 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3800 } else {
3801 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
3802 }
3803 break;
3804 }
3805
3806 switch(SiS_Pr->SiS_LCDTypeInfo) {
3807 case 1:
3808 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
3809 break;
3810 case 3: /* 640x480 only? */
3811 SiS_Pr->SiS_LCDHDES = 8;
3812 if (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
3813 else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
3814 else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
3815 break;
3816 }
3817 #endif
3818 } else {
3819 #ifdef SIS315H
3820 switch(SiS_Pr->SiS_LCDResInfo) {
3821 case Panel_1024x768:
3822 case Panel_1280x1024:
3823 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3824 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3825 }
3826 break;
3827 case Panel_320x240_1:
3828 case Panel_320x240_2:
3829 case Panel_320x240_3:
3830 SiS_Pr->SiS_LCDVDES = 524;
3831 break;
3832 }
3833 #endif
3834 }
3835 }
3836
3837 if((ModeNo <= 0x13) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
3838 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3839 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3840 if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 632;
3841 } else if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) {
3842 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
3843 if(SiS_Pr->SiS_LCDResInfo >= Panel_1024x768) {
3844 if(SiS_Pr->ChipType < SIS_315H) {
3845 if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320;
3846 } else {
3847 #ifdef SIS315H
3848 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) SiS_Pr->SiS_LCDHDES = 480;
3849 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 804;
3850 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 704;
3851 if(!(modeflag & HalfDCLK)) {
3852 SiS_Pr->SiS_LCDHDES = 320;
3853 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 632;
3854 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 542;
3855 }
3856 #endif
3857 }
3858 }
3859 }
3860 }
3861 }
3862 }
3863 }
3864
3865 /*********************************************/
3866 /* DISABLE VIDEO BRIDGE */
3867 /*********************************************/
3868
3869 #ifdef SIS315H
3870 static int
3871 SiS_HandlePWD(struct SiS_Private *SiS_Pr)
3872 {
3873 int ret = 0;
3874 #ifdef SET_PWD
3875 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
3876 unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
3877 unsigned char drivermode = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40;
3878 unsigned short temp;
3879
3880 if( (SiS_Pr->SiS_VBType & VB_SISPWD) &&
3881 (romptr) &&
3882 (SiS_Pr->SiS_PWDOffset) ) {
3883 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2b,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 0]);
3884 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2c,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 1]);
3885 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2d,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 2]);
3886 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2e,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 3]);
3887 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2f,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 4]);
3888 temp = 0x00;
3889 if((ROMAddr[romptr + 2] & (0x06 << 1)) && !drivermode) {
3890 temp = 0x80;
3891 ret = 1;
3892 }
3893 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x27,0x7f,temp);
3894 #ifdef SIS_XORG_XF86
3895 #ifdef TWDEBUG
3896 xf86DrvMsg(0, 0, "Setting PWD %x\n", temp);
3897 #endif
3898 #endif
3899 }
3900 #endif
3901 return ret;
3902 }
3903 #endif
3904
3905 /* NEVER use any variables (VBInfo), this will be called
3906 * from outside the context of modeswitch!
3907 * MUST call getVBType before calling this
3908 */
3909 void
3910 SiS_DisableBridge(struct SiS_Private *SiS_Pr)
3911 {
3912 #ifdef SIS315H
3913 unsigned short tempah, pushax=0, modenum;
3914 #endif
3915 unsigned short temp=0;
3916
3917 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3918
3919 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* ===== For 30xB/C/LV ===== */
3920
3921 if(SiS_Pr->ChipType < SIS_315H) {
3922
3923 #ifdef SIS300 /* 300 series */
3924
3925 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
3926 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3927 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
3928 } else {
3929 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
3930 }
3931 SiS_PanelDelay(SiS_Pr, 3);
3932 }
3933 if(SiS_Is301B(SiS_Pr)) {
3934 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);
3935 SiS_ShortDelay(SiS_Pr,1);
3936 }
3937 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
3938 SiS_DisplayOff(SiS_Pr);
3939 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3940 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
3941 SiS_UnLockCRT2(SiS_Pr);
3942 if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) {
3943 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
3944 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
3945 }
3946 if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
3947 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
3948 SiS_PanelDelay(SiS_Pr, 2);
3949 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3950 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
3951 } else {
3952 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
3953 }
3954 }
3955
3956 #endif /* SIS300 */
3957
3958 } else {
3959
3960 #ifdef SIS315H /* 315 series */
3961
3962 int didpwd = 0;
3963 bool custom1 = (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
3964 (SiS_Pr->SiS_CustomT == CUT_CLEVO1400);
3965
3966 modenum = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34) & 0x7f;
3967
3968 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3969
3970 #ifdef SET_EMI
3971 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
3972 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
3973 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
3974 }
3975 }
3976 #endif
3977
3978 didpwd = SiS_HandlePWD(SiS_Pr);
3979
3980 if( (modenum <= 0x13) ||
3981 (SiS_IsVAMode(SiS_Pr)) ||
3982 (!(SiS_IsDualEdge(SiS_Pr))) ) {
3983 if(!didpwd) {
3984 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfe);
3985 if(custom1) SiS_PanelDelay(SiS_Pr, 3);
3986 } else {
3987 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfc);
3988 }
3989 }
3990
3991 if(!custom1) {
3992 SiS_DDC2Delay(SiS_Pr,0xff00);
3993 SiS_DDC2Delay(SiS_Pr,0xe000);
3994 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
3995 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
3996 if(IS_SIS740) {
3997 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
3998 }
3999 SiS_PanelDelay(SiS_Pr, 3);
4000 }
4001
4002 }
4003
4004 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4005 /* if(SiS_Pr->ChipType < SIS_340) {*/
4006 tempah = 0xef;
4007 if(SiS_IsVAMode(SiS_Pr)) tempah = 0xf7;
4008 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
4009 /*}*/
4010 }
4011
4012 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4013 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,~0x10);
4014 }
4015
4016 tempah = 0x3f;
4017 if(SiS_IsDualEdge(SiS_Pr)) {
4018 tempah = 0x7f;
4019 if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0xbf;
4020 }
4021 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4022
4023 if((SiS_IsVAMode(SiS_Pr)) ||
4024 ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
4025
4026 SiS_DisplayOff(SiS_Pr);
4027 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4028 SiS_PanelDelay(SiS_Pr, 2);
4029 }
4030 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4031 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
4032
4033 }
4034
4035 if((!(SiS_IsVAMode(SiS_Pr))) ||
4036 ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
4037
4038 if(!(SiS_IsDualEdge(SiS_Pr))) {
4039 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
4040 SiS_DisplayOff(SiS_Pr);
4041 }
4042 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4043
4044 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4045 SiS_PanelDelay(SiS_Pr, 2);
4046 }
4047
4048 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4049 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
4050 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
4051 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4052 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
4053
4054 }
4055
4056 if(SiS_IsNotM650orLater(SiS_Pr)) {
4057 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4058 }
4059
4060 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4061
4062 if( (!(SiS_IsVAMode(SiS_Pr))) &&
4063 (!(SiS_CRT2IsLCD(SiS_Pr))) &&
4064 (!(SiS_IsDualEdge(SiS_Pr))) ) {
4065
4066 if(custom1) SiS_PanelDelay(SiS_Pr, 2);
4067 if(!didpwd) {
4068 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
4069 }
4070 if(custom1) SiS_PanelDelay(SiS_Pr, 4);
4071 }
4072
4073 if(!custom1) {
4074 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4075 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4076 if(SiS_IsVAorLCD(SiS_Pr)) {
4077 SiS_PanelDelayLoop(SiS_Pr, 3, 20);
4078 }
4079 }
4080 }
4081
4082 }
4083
4084 #endif /* SIS315H */
4085
4086 }
4087
4088 } else { /* ============ For 301 ================ */
4089
4090 if(SiS_Pr->ChipType < SIS_315H) {
4091 #ifdef SIS300
4092 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4093 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4094 SiS_PanelDelay(SiS_Pr, 3);
4095 }
4096 #endif
4097 }
4098
4099 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF); /* disable VB */
4100 SiS_DisplayOff(SiS_Pr);
4101
4102 if(SiS_Pr->ChipType >= SIS_315H) {
4103 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4104 }
4105
4106 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); /* disable lock mode */
4107
4108 if(SiS_Pr->ChipType >= SIS_315H) {
4109 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
4110 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
4111 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4112 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
4113 } else {
4114 #ifdef SIS300
4115 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); /* disable CRT2 */
4116 if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4117 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4118 SiS_PanelDelay(SiS_Pr, 2);
4119 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4120 }
4121 #endif
4122 }
4123
4124 }
4125
4126 } else { /* ============ For LVDS =============*/
4127
4128 if(SiS_Pr->ChipType < SIS_315H) {
4129
4130 #ifdef SIS300 /* 300 series */
4131
4132 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4133 SiS_SetCH700x(SiS_Pr,0x0E,0x09);
4134 }
4135
4136 if(SiS_Pr->ChipType == SIS_730) {
4137 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4138 SiS_WaitVBRetrace(SiS_Pr);
4139 }
4140 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4141 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4142 SiS_PanelDelay(SiS_Pr, 3);
4143 }
4144 } else {
4145 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4146 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4147 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4148 SiS_WaitVBRetrace(SiS_Pr);
4149 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {
4150 SiS_DisplayOff(SiS_Pr);
4151 }
4152 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4153 SiS_PanelDelay(SiS_Pr, 3);
4154 }
4155 }
4156 }
4157 }
4158
4159 SiS_DisplayOff(SiS_Pr);
4160
4161 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4162
4163 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4164 SiS_UnLockCRT2(SiS_Pr);
4165 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
4166 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
4167
4168 if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4169 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4170 SiS_PanelDelay(SiS_Pr, 2);
4171 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4172 }
4173
4174 #endif /* SIS300 */
4175
4176 } else {
4177
4178 #ifdef SIS315H /* 315 series */
4179
4180 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4181 /*if(SiS_Pr->ChipType < SIS_340) { */ /* XGI needs this */
4182 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,~0x18);
4183 /* } */
4184 }
4185
4186 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4187
4188 if(SiS_Pr->ChipType == SIS_740) {
4189 temp = SiS_GetCH701x(SiS_Pr,0x61);
4190 if(temp < 1) {
4191 SiS_SetCH701x(SiS_Pr,0x76,0xac);
4192 SiS_SetCH701x(SiS_Pr,0x66,0x00);
4193 }
4194
4195 if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4196 (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
4197 SiS_SetCH701x(SiS_Pr,0x49,0x3e);
4198 }
4199 }
4200
4201 if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4202 (SiS_IsVAMode(SiS_Pr)) ) {
4203 SiS_Chrontel701xBLOff(SiS_Pr);
4204 SiS_Chrontel701xOff(SiS_Pr);
4205 }
4206
4207 if(SiS_Pr->ChipType != SIS_740) {
4208 if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4209 (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
4210 SiS_SetCH701x(SiS_Pr,0x49,0x01);
4211 }
4212 }
4213
4214 }
4215
4216 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4217 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4218 SiS_PanelDelay(SiS_Pr, 3);
4219 }
4220
4221 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4222 (!(SiS_IsDualEdge(SiS_Pr))) ||
4223 (!(SiS_IsTVOrYPbPrOrScart(SiS_Pr))) ) {
4224 SiS_DisplayOff(SiS_Pr);
4225 }
4226
4227 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4228 (!(SiS_IsDualEdge(SiS_Pr))) ||
4229 (!(SiS_IsVAMode(SiS_Pr))) ) {
4230 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4231 }
4232
4233 if(SiS_Pr->ChipType == SIS_740) {
4234 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4235 }
4236
4237 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4238
4239 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4240 (!(SiS_IsDualEdge(SiS_Pr))) ||
4241 (!(SiS_IsVAMode(SiS_Pr))) ) {
4242 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4243 }
4244
4245 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4246 if(SiS_CRT2IsLCD(SiS_Pr)) {
4247 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4248 if(SiS_Pr->ChipType == SIS_550) {
4249 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xbf);
4250 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xef);
4251 }
4252 }
4253 } else {
4254 if(SiS_Pr->ChipType == SIS_740) {
4255 if(SiS_IsLCDOrLCDA(SiS_Pr)) {
4256 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4257 }
4258 } else if(SiS_IsVAMode(SiS_Pr)) {
4259 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4260 }
4261 }
4262
4263 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4264 if(SiS_IsDualEdge(SiS_Pr)) {
4265 /* SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff); */
4266 } else {
4267 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
4268 }
4269 }
4270
4271 SiS_UnLockCRT2(SiS_Pr);
4272
4273 if(SiS_Pr->ChipType == SIS_550) {
4274 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); /* DirectDVD PAL?*/
4275 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); /* VB clock / 4 ? */
4276 } else if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4277 (!(SiS_IsDualEdge(SiS_Pr))) ||
4278 (!(SiS_IsVAMode(SiS_Pr))) ) {
4279 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4280 }
4281
4282 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4283 if(SiS_CRT2IsLCD(SiS_Pr)) {
4284 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4285 SiS_PanelDelay(SiS_Pr, 2);
4286 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4287 }
4288 }
4289 }
4290
4291 #endif /* SIS315H */
4292
4293 } /* 315 series */
4294
4295 } /* LVDS */
4296
4297 }
4298
4299 /*********************************************/
4300 /* ENABLE VIDEO BRIDGE */
4301 /*********************************************/
4302
4303 /* NEVER use any variables (VBInfo), this will be called
4304 * from outside the context of a mode switch!
4305 * MUST call getVBType before calling this
4306 */
4307 #ifdef SIS_LINUX_KERNEL
4308 static
4309 #endif
4310 void
4311 SiS_EnableBridge(struct SiS_Private *SiS_Pr)
4312 {
4313 unsigned short temp=0, tempah;
4314 #ifdef SIS315H
4315 unsigned short temp1, pushax=0;
4316 bool delaylong = false;
4317 #endif
4318
4319 if(SiS_Pr->SiS_VBType & VB_SISVB) {
4320
4321 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* ====== For 301B et al ====== */
4322
4323 if(SiS_Pr->ChipType < SIS_315H) {
4324
4325 #ifdef SIS300 /* 300 series */
4326
4327 if(SiS_CRT2IsLCD(SiS_Pr)) {
4328 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4329 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4330 } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
4331 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4332 }
4333 if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_NoLCD)) {
4334 if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
4335 SiS_PanelDelay(SiS_Pr, 0);
4336 }
4337 }
4338 }
4339
4340 if((SiS_Pr->SiS_VBType & VB_NoLCD) &&
4341 (SiS_CRT2IsLCD(SiS_Pr))) {
4342
4343 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* Enable CRT2 */
4344 SiS_DisplayOn(SiS_Pr);
4345 SiS_UnLockCRT2(SiS_Pr);
4346 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4347 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4348 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4349 } else {
4350 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4351 }
4352 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4353 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4354 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4355 SiS_PanelDelay(SiS_Pr, 1);
4356 }
4357 SiS_WaitVBRetrace(SiS_Pr);
4358 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4359 }
4360 }
4361
4362 } else {
4363
4364 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
4365 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4366 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4367 if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4368 }
4369 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4370 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4371 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */
4372 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
4373 SiS_DisplayOn(SiS_Pr);
4374 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4375 if(SiS_CRT2IsLCD(SiS_Pr)) {
4376 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4377 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4378 SiS_PanelDelay(SiS_Pr, 1);
4379 }
4380 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4381 }
4382 }
4383 }
4384
4385 }
4386
4387
4388 #endif /* SIS300 */
4389
4390 } else {
4391
4392 #ifdef SIS315H /* 315 series */
4393
4394 #ifdef SET_EMI
4395 unsigned char r30=0, r31=0, r32=0, r33=0, cr36=0;
4396 int didpwd = 0;
4397 /* unsigned short emidelay=0; */
4398 #endif
4399
4400 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4401 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef);
4402 #ifdef SET_EMI
4403 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4404 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4405 }
4406 #endif
4407 }
4408
4409 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4410 /*if(SiS_Pr->ChipType < SIS_340) { */
4411 tempah = 0x10;
4412 if(SiS_LCDAEnabled(SiS_Pr)) {
4413 if(SiS_TVEnabled(SiS_Pr)) tempah = 0x18;
4414 else tempah = 0x08;
4415 }
4416 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah);
4417 /*}*/
4418 }
4419
4420 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4421
4422 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
4423 SiS_DisplayOff(SiS_Pr);
4424 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
4425 if(IS_SIS740) {
4426 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
4427 }
4428
4429 didpwd = SiS_HandlePWD(SiS_Pr);
4430
4431 if(SiS_IsVAorLCD(SiS_Pr)) {
4432 if(!didpwd) {
4433 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
4434 SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4435 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4436 SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4437 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4438 SiS_GenericDelay(SiS_Pr, 17664);
4439 }
4440 }
4441 } else {
4442 SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4443 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4444 SiS_GenericDelay(SiS_Pr, 17664);
4445 }
4446 }
4447 }
4448
4449 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {
4450 SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4451 delaylong = true;
4452 }
4453
4454 }
4455
4456 if(!(SiS_IsVAMode(SiS_Pr))) {
4457
4458 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
4459 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4460 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4461 if(!(tempah & SetCRT2ToRAMDAC)) {
4462 if(!(SiS_LCDAEnabled(SiS_Pr))) temp |= 0x20;
4463 }
4464 }
4465 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4466
4467 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
4468
4469 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4470 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4471
4472 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4473 SiS_PanelDelay(SiS_Pr, 2);
4474 }
4475
4476 } else {
4477
4478 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20);
4479
4480 }
4481
4482 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
4483 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4484
4485 if(SiS_Pr->SiS_VBType & VB_SISPOWER) {
4486 if( (SiS_LCDAEnabled(SiS_Pr)) ||
4487 (SiS_CRT2IsLCD(SiS_Pr)) ) {
4488 /* Enable "LVDS PLL power on" (even on 301C) */
4489 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);
4490 /* Enable "LVDS Driver Power on" (even on 301C) */
4491 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x7f);
4492 }
4493 }
4494
4495 tempah = 0xc0;
4496 if(SiS_IsDualEdge(SiS_Pr)) {
4497 tempah = 0x80;
4498 if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0x40;
4499 }
4500 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4501
4502 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4503
4504 SiS_PanelDelay(SiS_Pr, 2);
4505
4506 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10);
4507 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4508
4509 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
4510 #ifdef SET_EMI
4511 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4512 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4513 SiS_GenericDelay(SiS_Pr, 2048);
4514 }
4515 #endif
4516 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
4517
4518 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4519 #ifdef SET_EMI
4520 cr36 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
4521
4522 if(SiS_Pr->SiS_ROMNew) {
4523 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
4524 unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
4525 if(romptr) {
4526 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4527 SiS_Pr->EMI_30 = 0;
4528 SiS_Pr->EMI_31 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 0];
4529 SiS_Pr->EMI_32 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 1];
4530 SiS_Pr->EMI_33 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 2];
4531 if(ROMAddr[romptr + 1] & 0x10) SiS_Pr->EMI_30 = 0x40;
4532 /* emidelay = SISGETROMW((romptr + 0x22)); */
4533 SiS_Pr->HaveEMI = SiS_Pr->HaveEMILCD = SiS_Pr->OverruleEMI = true;
4534 }
4535 }
4536
4537 /* (P4_30|0x40) */
4538 /* Compal 1400x1050: 0x05, 0x60, 0x00 YES (1.10.7w; CR36=69) */
4539 /* Compal 1400x1050: 0x0d, 0x70, 0x40 YES (1.10.7x; CR36=69) */
4540 /* Acer 1280x1024: 0x12, 0xd0, 0x6b NO (1.10.9k; CR36=73) */
4541 /* Compaq 1280x1024: 0x0d, 0x70, 0x6b YES (1.12.04b; CR36=03) */
4542 /* Clevo 1024x768: 0x05, 0x60, 0x33 NO (1.10.8e; CR36=12, DL!) */
4543 /* Clevo 1024x768: 0x0d, 0x70, 0x40 (if type == 3) YES (1.10.8y; CR36=?2) */
4544 /* Clevo 1024x768: 0x05, 0x60, 0x33 (if type != 3) YES (1.10.8y; CR36=?2) */
4545 /* Asus 1024x768: ? ? (1.10.8o; CR36=?2) */
4546 /* Asus 1024x768: 0x08, 0x10, 0x3c (problematic) YES (1.10.8q; CR36=22) */
4547
4548 if(SiS_Pr->HaveEMI) {
4549 r30 = SiS_Pr->EMI_30; r31 = SiS_Pr->EMI_31;
4550 r32 = SiS_Pr->EMI_32; r33 = SiS_Pr->EMI_33;
4551 } else {
4552 r30 = 0;
4553 }
4554
4555 /* EMI_30 is read at driver start; however, the BIOS sets this
4556 * (if it is used) only if the LCD is in use. In case we caught
4557 * the machine while on TV output, this bit is not set and we
4558 * don't know if it should be set - hence our detection is wrong.
4559 * Work-around this here:
4560 */
4561
4562 if((!SiS_Pr->HaveEMI) || (!SiS_Pr->HaveEMILCD)) {
4563 switch((cr36 & 0x0f)) {
4564 case 2:
4565 r30 |= 0x40;
4566 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) r30 &= ~0x40;
4567 if(!SiS_Pr->HaveEMI) {
4568 r31 = 0x05; r32 = 0x60; r33 = 0x33;
4569 if((cr36 & 0xf0) == 0x30) {
4570 r31 = 0x0d; r32 = 0x70; r33 = 0x40;
4571 }
4572 }
4573 break;
4574 case 3: /* 1280x1024 */
4575 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) r30 |= 0x40;
4576 if(!SiS_Pr->HaveEMI) {
4577 r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4578 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4579 r31 = 0x0d; r32 = 0x70; r33 = 0x6b;
4580 }
4581 }
4582 break;
4583 case 9: /* 1400x1050 */
4584 r30 |= 0x40;
4585 if(!SiS_Pr->HaveEMI) {
4586 r31 = 0x05; r32 = 0x60; r33 = 0x00;
4587 if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4588 r31 = 0x0d; r32 = 0x70; r33 = 0x40; /* BIOS values */
4589 }
4590 }
4591 break;
4592 case 11: /* 1600x1200 - unknown */
4593 r30 |= 0x40;
4594 if(!SiS_Pr->HaveEMI) {
4595 r31 = 0x05; r32 = 0x60; r33 = 0x00;
4596 }
4597 }
4598 }
4599
4600 /* BIOS values don't work so well sometimes */
4601 if(!SiS_Pr->OverruleEMI) {
4602 #ifdef COMPAL_HACK
4603 if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4604 if((cr36 & 0x0f) == 0x09) {
4605 r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x00;
4606 }
4607 }
4608 #endif
4609 #ifdef COMPAQ_HACK
4610 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4611 if((cr36 & 0x0f) == 0x03) {
4612 r30 = 0x20; r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4613 }
4614 }
4615 #endif
4616 #ifdef ASUS_HACK
4617 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4618 if((cr36 & 0x0f) == 0x02) {
4619 /* r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 2 */
4620 /* r30 = 0x20; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 3 */
4621 /* r30 = 0x60; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 4 */
4622 /* r30 = 0x20; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 5 */
4623 }
4624 }
4625 #endif
4626 }
4627
4628 if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) {
4629 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4630 SiS_GenericDelay(SiS_Pr, 2048);
4631 }
4632 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,r31);
4633 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,r32);
4634 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x33,r33);
4635 #endif /* SET_EMI */
4636
4637 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
4638
4639 #ifdef SET_EMI
4640 if( (SiS_LCDAEnabled(SiS_Pr)) ||
4641 (SiS_CRT2IsLCD(SiS_Pr)) ) {
4642 if(r30 & 0x40) {
4643 /*SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x2a,0x80);*/
4644 SiS_PanelDelayLoop(SiS_Pr, 3, 5);
4645 if(delaylong) {
4646 SiS_PanelDelayLoop(SiS_Pr, 3, 5);
4647 delaylong = false;
4648 }
4649 SiS_WaitVBRetrace(SiS_Pr);
4650 SiS_WaitVBRetrace(SiS_Pr);
4651 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4652 SiS_GenericDelay(SiS_Pr, 1280);
4653 }
4654 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40); /* Enable */
4655 /*SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);*/
4656 }
4657 }
4658 #endif
4659 }
4660 }
4661
4662 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4663 if(SiS_IsVAorLCD(SiS_Pr)) {
4664 SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4665 if(delaylong) {
4666 SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4667 }
4668 SiS_WaitVBRetrace(SiS_Pr);
4669 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4670 SiS_GenericDelay(SiS_Pr, 2048);
4671 SiS_WaitVBRetrace(SiS_Pr);
4672 }
4673 if(!didpwd) {
4674 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4675 } else {
4676 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x03);
4677 }
4678 }
4679 }
4680
4681 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4682 SiS_DisplayOn(SiS_Pr);
4683 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xff);
4684
4685 }
4686
4687 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4688 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4689 }
4690
4691 #endif /* SIS315H */
4692
4693 }
4694
4695 } else { /* ============ For 301 ================ */
4696
4697 if(SiS_Pr->ChipType < SIS_315H) {
4698 if(SiS_CRT2IsLCD(SiS_Pr)) {
4699 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4700 SiS_PanelDelay(SiS_Pr, 0);
4701 }
4702 }
4703
4704 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
4705 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4706 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4707 if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4708 }
4709 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4710
4711 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
4712
4713 if(SiS_Pr->ChipType >= SIS_315H) {
4714 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4715 if(!(temp & 0x80)) {
4716 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80); /* BVBDOENABLE=1 */
4717 }
4718 }
4719
4720 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */
4721
4722 SiS_VBLongWait(SiS_Pr);
4723 SiS_DisplayOn(SiS_Pr);
4724 if(SiS_Pr->ChipType >= SIS_315H) {
4725 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4726 }
4727 SiS_VBLongWait(SiS_Pr);
4728
4729 if(SiS_Pr->ChipType < SIS_315H) {
4730 if(SiS_CRT2IsLCD(SiS_Pr)) {
4731 SiS_PanelDelay(SiS_Pr, 1);
4732 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4733 }
4734 }
4735
4736 }
4737
4738 } else { /* =================== For LVDS ================== */
4739
4740 if(SiS_Pr->ChipType < SIS_315H) {
4741
4742 #ifdef SIS300 /* 300 series */
4743
4744 if(SiS_CRT2IsLCD(SiS_Pr)) {
4745 if(SiS_Pr->ChipType == SIS_730) {
4746 SiS_PanelDelay(SiS_Pr, 1);
4747 SiS_PanelDelay(SiS_Pr, 1);
4748 SiS_PanelDelay(SiS_Pr, 1);
4749 }
4750 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4751 if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
4752 SiS_PanelDelay(SiS_Pr, 0);
4753 }
4754 }
4755
4756 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4757 SiS_DisplayOn(SiS_Pr);
4758 SiS_UnLockCRT2(SiS_Pr);
4759 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4760 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4761 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4762 } else {
4763 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4764 }
4765
4766 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4767 if(!(SiS_CRT2IsLCD(SiS_Pr))) {
4768 SiS_WaitVBRetrace(SiS_Pr);
4769 SiS_SetCH700x(SiS_Pr,0x0E,0x0B);
4770 }
4771 }
4772
4773 if(SiS_CRT2IsLCD(SiS_Pr)) {
4774 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4775 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4776 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4777 SiS_PanelDelay(SiS_Pr, 1);
4778 SiS_PanelDelay(SiS_Pr, 1);
4779 }
4780 SiS_WaitVBRetrace(SiS_Pr);
4781 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4782 }
4783 }
4784 }
4785
4786 #endif /* SIS300 */
4787
4788 } else {
4789
4790 #ifdef SIS315H /* 315 series */
4791
4792 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4793 /*if(SiS_Pr->ChipType < SIS_340) {*/ /* XGI needs this */
4794 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x18);
4795 /*}*/
4796 }
4797
4798 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4799 if(SiS_CRT2IsLCD(SiS_Pr)) {
4800 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4801 SiS_PanelDelay(SiS_Pr, 0);
4802 }
4803 }
4804
4805 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4806 SiS_UnLockCRT2(SiS_Pr);
4807
4808 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4809
4810 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4811 temp = SiS_GetCH701x(SiS_Pr,0x66);
4812 temp &= 0x20;
4813 SiS_Chrontel701xBLOff(SiS_Pr);
4814 }
4815
4816 if(SiS_Pr->ChipType != SIS_550) {
4817 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4818 }
4819
4820 if(SiS_Pr->ChipType == SIS_740) {
4821 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4822 if(SiS_IsLCDOrLCDA(SiS_Pr)) {
4823 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4824 }
4825 }
4826 }
4827
4828 temp1 = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4829 if(!(temp1 & 0x80)) {
4830 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
4831 }
4832
4833 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4834 if(temp) {
4835 SiS_Chrontel701xBLOn(SiS_Pr);
4836 }
4837 }
4838
4839 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4840 if(SiS_CRT2IsLCD(SiS_Pr)) {
4841 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4842 if(SiS_Pr->ChipType == SIS_550) {
4843 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x40);
4844 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x10);
4845 }
4846 }
4847 } else if(SiS_IsVAMode(SiS_Pr)) {
4848 if(SiS_Pr->ChipType != SIS_740) {
4849 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4850 }
4851 }
4852
4853 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4854 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4855 }
4856
4857 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4858 if(SiS_IsTVOrYPbPrOrScart(SiS_Pr)) {
4859 SiS_Chrontel701xOn(SiS_Pr);
4860 }
4861 if( (SiS_IsVAMode(SiS_Pr)) ||
4862 (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
4863 SiS_ChrontelDoSomething1(SiS_Pr);
4864 }
4865 }
4866
4867 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4868 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4869 if( (SiS_IsVAMode(SiS_Pr)) ||
4870 (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
4871 SiS_Chrontel701xBLOn(SiS_Pr);
4872 SiS_ChrontelInitTVVSync(SiS_Pr);
4873 }
4874 }
4875 } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4876 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4877 if(SiS_CRT2IsLCD(SiS_Pr)) {
4878 SiS_PanelDelay(SiS_Pr, 1);
4879 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4880 }
4881 }
4882 }
4883
4884 #endif /* SIS315H */
4885
4886 } /* 310 series */
4887
4888 } /* LVDS */
4889
4890 }
4891
4892 /*********************************************/
4893 /* SET PART 1 REGISTER GROUP */
4894 /*********************************************/
4895
4896 /* Set CRT2 OFFSET / PITCH */
4897 static void
4898 SiS_SetCRT2Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
4899 unsigned short RRTI)
4900 {
4901 unsigned short offset;
4902 unsigned char temp;
4903
4904 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return;
4905
4906 offset = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,RRTI);
4907
4908 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(offset & 0xFF));
4909 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,(offset >> 8));
4910
4911 temp = (unsigned char)(((offset >> 3) & 0xFF) + 1);
4912 if(offset & 0x07) temp++;
4913 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,temp);
4914 }
4915
4916 /* Set CRT2 sync and PanelLink mode */
4917 static void
4918 SiS_SetCRT2Sync(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RefreshRateTableIndex)
4919 {
4920 unsigned short tempah=0, tempbl, infoflag;
4921
4922 tempbl = 0xC0;
4923
4924 if(SiS_Pr->UseCustomMode) {
4925 infoflag = SiS_Pr->CInfoFlag;
4926 } else {
4927 infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
4928 }
4929
4930 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { /* LVDS */
4931
4932 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
4933 tempah = 0;
4934 } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) {
4935 tempah = SiS_Pr->SiS_LCDInfo;
4936 } else tempah = infoflag >> 8;
4937 tempah &= 0xC0;
4938 tempah |= 0x20;
4939 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4940 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4941 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
4942 (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
4943 tempah |= 0xf0;
4944 }
4945 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
4946 (SiS_Pr->SiS_IF_DEF_DSTN) ||
4947 (SiS_Pr->SiS_IF_DEF_TRUMPION) ||
4948 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
4949 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
4950 tempah |= 0x30;
4951 }
4952 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
4953 (SiS_Pr->SiS_IF_DEF_DSTN) ) {
4954 tempah &= ~0xc0;
4955 }
4956 }
4957 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
4958 if(SiS_Pr->ChipType >= SIS_315H) {
4959 tempah >>= 3;
4960 tempah &= 0x18;
4961 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xE7,tempah);
4962 /* Don't care about 12/18/24 bit mode - TV is via VGA, not PL */
4963 } else {
4964 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,0xe0);
4965 }
4966 } else {
4967 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4968 }
4969
4970 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
4971
4972 if(SiS_Pr->ChipType < SIS_315H) {
4973
4974 #ifdef SIS300 /* ---- 300 series --- */
4975
4976 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* 630 - 301B(-DH) */
4977
4978 tempah = infoflag >> 8;
4979 tempbl = 0;
4980 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4981 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4982 tempah = SiS_Pr->SiS_LCDInfo;
4983 tempbl = (tempah >> 6) & 0x03;
4984 }
4985 }
4986 tempah &= 0xC0;
4987 tempah |= 0x20;
4988 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4989 tempah |= 0xc0;
4990 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4991 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
4992 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
4993 }
4994
4995 } else { /* 630 - 301 */
4996
4997 tempah = ((infoflag >> 8) & 0xc0) | 0x20;
4998 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4999 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5000
5001 }
5002
5003 #endif /* SIS300 */
5004
5005 } else {
5006
5007 #ifdef SIS315H /* ------- 315 series ------ */
5008
5009 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { /* 315 - LVDS */
5010
5011 tempbl = 0;
5012 if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
5013 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
5014 tempah = infoflag >> 8;
5015 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
5016 tempbl = ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6);
5017 }
5018 } else if((SiS_Pr->SiS_CustomT == CUT_CLEVO1400) &&
5019 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)) {
5020 tempah = infoflag >> 8;
5021 tempbl = 0x03;
5022 } else {
5023 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
5024 tempbl = (tempah >> 6) & 0x03;
5025 tempbl |= 0x08;
5026 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempbl |= 0x04;
5027 }
5028 tempah &= 0xC0;
5029 tempah |= 0x20;
5030 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5031 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) tempah |= 0xc0;
5032 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5033 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
5034 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5035 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
5036 }
5037 }
5038
5039 } else { /* 315 - TMDS */
5040
5041 tempah = tempbl = infoflag >> 8;
5042 if(!SiS_Pr->UseCustomMode) {
5043 tempbl = 0;
5044 if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
5045 if(ModeNo <= 0x13) {
5046 tempah = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
5047 }
5048 }
5049 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5050 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5051 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
5052 tempah = SiS_Pr->SiS_LCDInfo;
5053 tempbl = (tempah >> 6) & 0x03;
5054 }
5055 }
5056 }
5057 }
5058 tempah &= 0xC0;
5059 tempah |= 0x20;
5060 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5061 if(SiS_Pr->SiS_VBType & VB_NoLCD) {
5062 /* Imitate BIOS bug */
5063 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempah |= 0xc0;
5064 }
5065 if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
5066 tempah >>= 3;
5067 tempah &= 0x18;
5068 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xe7,tempah);
5069 } else {
5070 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5071 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
5072 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5073 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
5074 }
5075 }
5076 }
5077
5078 }
5079 #endif /* SIS315H */
5080 }
5081 }
5082 }
5083
5084 /* Set CRT2 FIFO on 300/540/630/730 */
5085 #ifdef SIS300
5086 static void
5087 SiS_SetCRT2FIFO_300(struct SiS_Private *SiS_Pr,unsigned short ModeNo)
5088 {
5089 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
5090 unsigned short temp, index, modeidindex, refreshratetableindex;
5091 unsigned short VCLK = 0, MCLK, colorth = 0, data2 = 0;
5092 unsigned short tempbx, tempcl, CRT1ModeNo, CRT2ModeNo, SelectRate_backup;
5093 unsigned int data, pci50, pciA0;
5094 static const unsigned char colortharray[] = {
5095 1, 1, 2, 2, 3, 4
5096 };
5097
5098 SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;
5099
5100 if(!SiS_Pr->CRT1UsesCustomMode) {
5101
5102 CRT1ModeNo = SiS_Pr->SiS_CRT1Mode; /* get CRT1 ModeNo */
5103 SiS_SearchModeID(SiS_Pr, &CRT1ModeNo, &modeidindex);
5104 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
5105 SiS_Pr->SiS_SelectCRT2Rate = 0;
5106 refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT1ModeNo, modeidindex);
5107
5108 if(CRT1ModeNo >= 0x13) {
5109 /* Get VCLK */
5110 index = SiS_GetRefCRTVCLK(SiS_Pr, refreshratetableindex, SiS_Pr->SiS_UseWide);
5111 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
5112
5113 /* Get colordepth */
5114 colorth = SiS_GetColorDepth(SiS_Pr,CRT1ModeNo,modeidindex) >> 1;
5115 if(!colorth) colorth++;
5116 }
5117
5118 } else {
5119
5120 CRT1ModeNo = 0xfe;
5121
5122 /* Get VCLK */
5123 VCLK = SiS_Pr->CSRClock_CRT1;
5124
5125 /* Get color depth */
5126 colorth = colortharray[((SiS_Pr->CModeFlag_CRT1 & ModeTypeMask) - 2)];
5127
5128 }
5129
5130 if(CRT1ModeNo >= 0x13) {
5131 /* Get MCLK */
5132 if(SiS_Pr->ChipType == SIS_300) {
5133 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A);
5134 } else {
5135 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A);
5136 }
5137 index &= 0x07;
5138 MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;
5139
5140 temp = ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) >> 6) & 0x03) << 1;
5141 if(!temp) temp++;
5142 temp <<= 2;
5143
5144 data2 = temp - ((colorth * VCLK) / MCLK);
5145
5146 temp = (28 * 16) % data2;
5147 data2 = (28 * 16) / data2;
5148 if(temp) data2++;
5149
5150 if(SiS_Pr->ChipType == SIS_300) {
5151
5152 SiS_GetFIFOThresholdIndex300(SiS_Pr, &tempbx, &tempcl);
5153 data = SiS_GetFIFOThresholdB300(tempbx, tempcl);
5154
5155 } else {
5156
5157 #ifdef SIS_LINUX_KERNEL
5158 pci50 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0x50);
5159 pciA0 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0xa0);
5160 #else
5161 pci50 = pciReadLong(0x00000000, 0x50);
5162 pciA0 = pciReadLong(0x00000000, 0xA0);
5163 #endif
5164
5165 if(SiS_Pr->ChipType == SIS_730) {
5166
5167 index = (unsigned short)(((pciA0 >> 28) & 0x0f) * 3);
5168 index += (unsigned short)(((pci50 >> 9)) & 0x03);
5169
5170 /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */
5171 index = 0; /* -- do it like the BIOS anyway... */
5172
5173 } else {
5174
5175 pci50 >>= 24;
5176 pciA0 >>= 24;
5177
5178 index = (pci50 >> 1) & 0x07;
5179
5180 if(pci50 & 0x01) index += 6;
5181 if(!(pciA0 & 0x01)) index += 24;
5182
5183 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80) index += 12;
5184
5185 }
5186
5187 data = SiS_GetLatencyFactor630(SiS_Pr, index) + 15;
5188 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80)) data += 5;
5189
5190 }
5191
5192 data += data2; /* CRT1 Request Period */
5193
5194 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5195 SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5196
5197 if(!SiS_Pr->UseCustomMode) {
5198
5199 CRT2ModeNo = ModeNo;
5200 SiS_SearchModeID(SiS_Pr, &CRT2ModeNo, &modeidindex);
5201
5202 refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT2ModeNo, modeidindex);
5203
5204 /* Get VCLK */
5205 index = SiS_GetVCLK2Ptr(SiS_Pr, CRT2ModeNo, modeidindex, refreshratetableindex);
5206 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
5207
5208 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
5209 if(SiS_Pr->SiS_UseROM) {
5210 if(ROMAddr[0x220] & 0x01) {
5211 VCLK = ROMAddr[0x229] | (ROMAddr[0x22a] << 8);
5212 }
5213 }
5214 }
5215
5216 } else {
5217
5218 /* Get VCLK */
5219 CRT2ModeNo = 0xfe;
5220 VCLK = SiS_Pr->CSRClock;
5221
5222 }
5223
5224 /* Get colordepth */
5225 colorth = SiS_GetColorDepth(SiS_Pr,CRT2ModeNo,modeidindex) >> 1;
5226 if(!colorth) colorth++;
5227
5228 data = data * VCLK * colorth;
5229 temp = data % (MCLK << 4);
5230 data = data / (MCLK << 4);
5231 if(temp) data++;
5232
5233 if(data < 6) data = 6;
5234 else if(data > 0x14) data = 0x14;
5235
5236 if(SiS_Pr->ChipType == SIS_300) {
5237 temp = 0x16;
5238 if((data <= 0x0f) || (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024))
5239 temp = 0x13;
5240 } else {
5241 temp = 0x16;
5242 if(( (SiS_Pr->ChipType == SIS_630) ||
5243 (SiS_Pr->ChipType == SIS_730) ) &&
5244 (SiS_Pr->ChipRevision >= 0x30))
5245 temp = 0x1b;
5246 }
5247 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0xe0,temp);
5248
5249 if((SiS_Pr->ChipType == SIS_630) &&
5250 (SiS_Pr->ChipRevision >= 0x30)) {
5251 if(data > 0x13) data = 0x13;
5252 }
5253 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,0xe0,data);
5254
5255 } else { /* If mode <= 0x13, we just restore everything */
5256
5257 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5258 SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5259
5260 }
5261 }
5262 #endif
5263
5264 /* Set CRT2 FIFO on 315/330 series */
5265 #ifdef SIS315H
5266 static void
5267 SiS_SetCRT2FIFO_310(struct SiS_Private *SiS_Pr)
5268 {
5269 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3B);
5270 if( (SiS_Pr->ChipType == SIS_760) &&
5271 (SiS_Pr->SiS_SysFlags & SF_760LFB) &&
5272 (SiS_Pr->SiS_ModeType == Mode32Bpp) &&
5273 (SiS_Pr->SiS_VGAHDE >= 1280) &&
5274 (SiS_Pr->SiS_VGAVDE >= 1024) ) {
5275 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x03);
5276 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3b);
5277 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5278 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x01);
5279 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5280 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,0x6e);
5281 } else {
5282 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3f,0x04);
5283 }
5284
5285 }
5286 #endif
5287
5288 static unsigned short
5289 SiS_GetVGAHT2(struct SiS_Private *SiS_Pr)
5290 {
5291 unsigned int tempax,tempbx;
5292
5293 tempbx = (SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) * SiS_Pr->SiS_RVBHCMAX;
5294 tempax = (SiS_Pr->SiS_VT - SiS_Pr->SiS_VDE) * SiS_Pr->SiS_RVBHCFACT;
5295 tempax = (tempax * SiS_Pr->SiS_HT) / tempbx;
5296 return (unsigned short)tempax;
5297 }
5298
5299 /* Set Part 1 / SiS bridge slave mode */
5300 static void
5301 SiS_SetGroup1_301(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,
5302 unsigned short RefreshRateTableIndex)
5303 {
5304 unsigned short temp, modeflag, i, j, xres=0, VGAVDE;
5305 static const unsigned short CRTranslation[] = {
5306 /* CR0 CR1 CR2 CR3 CR4 CR5 CR6 CR7 */
5307 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
5308 /* CR8 CR9 SR0A SR0B SR0C SR0D SR0E CR0F */
5309 0x00, 0x0b, 0x17, 0x18, 0x19, 0x00, 0x1a, 0x00,
5310 /* CR10 CR11 CR12 CR13 CR14 CR15 CR16 CR17 */
5311 0x0c, 0x0d, 0x0e, 0x00, 0x0f, 0x10, 0x11, 0x00
5312 };
5313
5314 if(ModeNo <= 0x13) {
5315 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5316 } else if(SiS_Pr->UseCustomMode) {
5317 modeflag = SiS_Pr->CModeFlag;
5318 xres = SiS_Pr->CHDisplay;
5319 } else {
5320 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5321 xres = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes;
5322 }
5323
5324 /* The following is only done if bridge is in slave mode: */
5325
5326 if(SiS_Pr->ChipType >= SIS_315H) {
5327 if(xres >= 1600) { /* BIOS: == 1600 */
5328 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x31,0x04);
5329 }
5330 }
5331
5332 SiS_Pr->CHTotal = 8224; /* Max HT, 0x2020, results in 0x3ff in registers */
5333
5334 SiS_Pr->CHDisplay = SiS_Pr->SiS_VGAHDE;
5335 if(modeflag & HalfDCLK) SiS_Pr->CHDisplay >>= 1;
5336
5337 SiS_Pr->CHBlankStart = SiS_Pr->CHDisplay;
5338 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5339 SiS_Pr->CHBlankStart += 16;
5340 }
5341
5342 SiS_Pr->CHBlankEnd = 32;
5343 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5344 if(xres == 1600) SiS_Pr->CHBlankEnd += 80;
5345 }
5346
5347 temp = SiS_Pr->SiS_VGAHT - 96;
5348 if(!(modeflag & HalfDCLK)) temp -= 32;
5349 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
5350 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x04);
5351 temp |= ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x0b) & 0xc0) << 2);
5352 temp -= 3;
5353 temp <<= 3;
5354 } else {
5355 if(SiS_Pr->SiS_RVBHRS2) temp = SiS_Pr->SiS_RVBHRS2;
5356 }
5357 SiS_Pr->CHSyncStart = temp;
5358
5359 SiS_Pr->CHSyncEnd = 0xffe8; /* results in 0x2000 in registers */
5360
5361 SiS_Pr->CVTotal = 2049; /* Max VT, 0x0801, results in 0x7ff in registers */
5362
5363 VGAVDE = SiS_Pr->SiS_VGAVDE;
5364 if (VGAVDE == 357) VGAVDE = 350;
5365 else if(VGAVDE == 360) VGAVDE = 350;
5366 else if(VGAVDE == 375) VGAVDE = 350;
5367 else if(VGAVDE == 405) VGAVDE = 400;
5368 else if(VGAVDE == 420) VGAVDE = 400;
5369 else if(VGAVDE == 525) VGAVDE = 480;
5370 else if(VGAVDE == 1056) VGAVDE = 1024;
5371 SiS_Pr->CVDisplay = VGAVDE;
5372
5373 SiS_Pr->CVBlankStart = SiS_Pr->CVDisplay;
5374
5375 SiS_Pr->CVBlankEnd = 1;
5376 if(ModeNo == 0x3c) SiS_Pr->CVBlankEnd = 226;
5377
5378 temp = (SiS_Pr->SiS_VGAVT - VGAVDE) >> 1;
5379 SiS_Pr->CVSyncStart = VGAVDE + temp;
5380
5381 temp >>= 3;
5382 SiS_Pr->CVSyncEnd = SiS_Pr->CVSyncStart + temp;
5383
5384 SiS_CalcCRRegisters(SiS_Pr, 0);
5385 SiS_Pr->CCRT1CRTC[16] &= ~0xE0;
5386
5387 for(i = 0; i <= 7; i++) {
5388 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[i]);
5389 }
5390 for(i = 0x10, j = 8; i <= 0x12; i++, j++) {
5391 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5392 }
5393 for(i = 0x15, j = 11; i <= 0x16; i++, j++) {
5394 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5395 }
5396 for(i = 0x0a, j = 13; i <= 0x0c; i++, j++) {
5397 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5398 }
5399
5400 temp = SiS_Pr->CCRT1CRTC[16] & 0xE0;
5401 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x0E],0x1F,temp);
5402
5403 temp = (SiS_Pr->CCRT1CRTC[16] & 0x01) << 5;
5404 if(modeflag & DoubleScanMode) temp |= 0x80;
5405 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x09],0x5F,temp);
5406
5407 temp = 0;
5408 temp |= (SiS_GetReg(SiS_Pr->SiS_P3c4,0x01) & 0x01);
5409 if(modeflag & HalfDCLK) temp |= 0x08;
5410 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* SR01: HalfDCLK[3], 8/9 div dotclock[0] */
5411
5412 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,0x00); /* CR14: (text mode: underline location) */
5413 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,0x00); /* CR17: n/a */
5414
5415 temp = 0;
5416 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5417 temp = (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) << 7;
5418 }
5419 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* SR0E, dither[7] */
5420
5421 temp = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
5422 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp); /* ? */
5423
5424 #ifdef SIS_XORG_XF86
5425 #ifdef TWDEBUG
5426 xf86DrvMsg(0, X_INFO, "%d %d %d %d %d %d %d %d (%d %d %d %d)\n",
5427 SiS_Pr->CHDisplay, SiS_Pr->CHSyncStart, SiS_Pr->CHSyncEnd, SiS_Pr->CHTotal,
5428 SiS_Pr->CVDisplay, SiS_Pr->CVSyncStart, SiS_Pr->CVSyncEnd, SiS_Pr->CVTotal,
5429 SiS_Pr->CHBlankStart, SiS_Pr->CHBlankEnd, SiS_Pr->CVBlankStart, SiS_Pr->CVBlankEnd);
5430
5431 xf86DrvMsg(0, X_INFO, " {{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
5432 SiS_Pr->CCRT1CRTC[0], SiS_Pr->CCRT1CRTC[1],
5433 SiS_Pr->CCRT1CRTC[2], SiS_Pr->CCRT1CRTC[3],
5434 SiS_Pr->CCRT1CRTC[4], SiS_Pr->CCRT1CRTC[5],
5435 SiS_Pr->CCRT1CRTC[6], SiS_Pr->CCRT1CRTC[7]);
5436 xf86DrvMsg(0, X_INFO, " 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
5437 SiS_Pr->CCRT1CRTC[8], SiS_Pr->CCRT1CRTC[9],
5438 SiS_Pr->CCRT1CRTC[10], SiS_Pr->CCRT1CRTC[11],
5439 SiS_Pr->CCRT1CRTC[12], SiS_Pr->CCRT1CRTC[13],
5440 SiS_Pr->CCRT1CRTC[14], SiS_Pr->CCRT1CRTC[15]);
5441 xf86DrvMsg(0, X_INFO, " 0x%02x}},\n", SiS_Pr->CCRT1CRTC[16]);
5442 #endif
5443 #endif
5444 }
5445
5446 /* Setup panel link
5447 * This is used for LVDS, LCDA and Chrontel TV output
5448 * 300/LVDS+TV, 300/301B-DH, 315/LVDS+TV, 315/LCDA
5449 */
5450 static void
5451 SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
5452 unsigned short RefreshRateTableIndex)
5453 {
5454 unsigned short modeflag, resinfo = 0;
5455 unsigned short push2, tempax, tempbx, tempcx, temp;
5456 unsigned int tempeax = 0, tempebx, tempecx, tempvcfact = 0;
5457 bool islvds = false, issis = false, chkdclkfirst = false;
5458 #ifdef SIS300
5459 unsigned short crt2crtc = 0;
5460 #endif
5461 #ifdef SIS315H
5462 unsigned short pushcx;
5463 #endif
5464
5465 if(ModeNo <= 0x13) {
5466 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5467 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
5468 #ifdef SIS300
5469 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
5470 #endif
5471 } else if(SiS_Pr->UseCustomMode) {
5472 modeflag = SiS_Pr->CModeFlag;
5473 } else {
5474 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5475 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
5476 #ifdef SIS300
5477 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
5478 #endif
5479 }
5480
5481 /* is lvds if really LVDS, or 301B-DH with external LVDS transmitter */
5482 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
5483 islvds = true;
5484 }
5485
5486 /* is really sis if sis bridge, but not 301B-DH */
5487 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
5488 issis = true;
5489 }
5490
5491 if((SiS_Pr->ChipType >= SIS_315H) && (islvds) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA))) {
5492 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
5493 chkdclkfirst = true;
5494 }
5495 }
5496
5497 #ifdef SIS315H
5498 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
5499 if(IS_SIS330) {
5500 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5501 } else if(IS_SIS740) {
5502 if(islvds) {
5503 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5504 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x03);
5505 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5506 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5507 }
5508 } else {
5509 if(islvds) {
5510 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5511 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x00);
5512 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5513 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2D,0x0f);
5514 if(SiS_Pr->SiS_VBType & VB_SIS30xC) {
5515 if((SiS_Pr->SiS_LCDResInfo == Panel_1024x768) ||
5516 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
5517 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x20);
5518 }
5519 }
5520 }
5521 }
5522 }
5523 #endif
5524
5525 /* Horizontal */
5526
5527 tempax = SiS_Pr->SiS_LCDHDES;
5528 if(islvds) {
5529 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5530 if(!SiS_Pr->SiS_IF_DEF_FSTN && !SiS_Pr->SiS_IF_DEF_DSTN) {
5531 if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) &&
5532 (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
5533 tempax -= 8;
5534 }
5535 }
5536 }
5537 }
5538
5539 temp = (tempax & 0x0007);
5540 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* BPLHDESKEW[2:0] */
5541 temp = (tempax >> 3) & 0x00FF;
5542 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* BPLHDESKEW[10:3] */
5543
5544 tempbx = SiS_Pr->SiS_HDE;
5545 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5546 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5547 tempbx = SiS_Pr->PanelXRes;
5548 }
5549 if((SiS_Pr->SiS_LCDResInfo == Panel_320x240_1) ||
5550 (SiS_Pr->SiS_LCDResInfo == Panel_320x240_2) ||
5551 (SiS_Pr->SiS_LCDResInfo == Panel_320x240_3)) {
5552 tempbx >>= 1;
5553 }
5554 }
5555
5556 tempax += tempbx;
5557 if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;
5558
5559 temp = tempax;
5560 if(temp & 0x07) temp += 8;
5561 temp >>= 3;
5562 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp); /* BPLHDEE */
5563
5564 tempcx = (SiS_Pr->SiS_HT - tempbx) >> 2;
5565
5566 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5567 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5568 if(SiS_Pr->PanelHRS != 999) tempcx = SiS_Pr->PanelHRS;
5569 }
5570 }
5571
5572 tempcx += tempax;
5573 if(tempcx >= SiS_Pr->SiS_HT) tempcx -= SiS_Pr->SiS_HT;
5574
5575 temp = (tempcx >> 3) & 0x00FF;
5576 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5577 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5578 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5579 switch(ModeNo) {
5580 case 0x04:
5581 case 0x05:
5582 case 0x0d: temp = 0x56; break;
5583 case 0x10: temp = 0x60; break;
5584 case 0x13: temp = 0x5f; break;
5585 case 0x40:
5586 case 0x41:
5587 case 0x4f:
5588 case 0x43:
5589 case 0x44:
5590 case 0x62:
5591 case 0x56:
5592 case 0x53:
5593 case 0x5d:
5594 case 0x5e: temp = 0x54; break;
5595 }
5596 }
5597 }
5598 }
5599 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,temp); /* BPLHRS */
5600
5601 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5602 temp += 2;
5603 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5604 temp += 8;
5605 if(SiS_Pr->PanelHRE != 999) {
5606 temp = tempcx + SiS_Pr->PanelHRE;
5607 if(temp >= SiS_Pr->SiS_HT) temp -= SiS_Pr->SiS_HT;
5608 temp >>= 3;
5609 }
5610 }
5611 } else {
5612 temp += 10;
5613 }
5614
5615 temp &= 0x1F;
5616 temp |= ((tempcx & 0x07) << 5);
5617 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,temp); /* BPLHRE */
5618
5619 /* Vertical */
5620
5621 tempax = SiS_Pr->SiS_VGAVDE;
5622 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5623 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5624 tempax = SiS_Pr->PanelYRes;
5625 }
5626 }
5627
5628 tempbx = SiS_Pr->SiS_LCDVDES + tempax;
5629 if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5630
5631 push2 = tempbx;
5632
5633 tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE;
5634 if(SiS_Pr->ChipType < SIS_315H) {
5635 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5636 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5637 tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->PanelYRes;
5638 }
5639 }
5640 }
5641 if(islvds) tempcx >>= 1;
5642 else tempcx >>= 2;
5643
5644 if( (SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
5645 (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) &&
5646 (SiS_Pr->PanelVRS != 999) ) {
5647 tempcx = SiS_Pr->PanelVRS;
5648 tempbx += tempcx;
5649 if(issis) tempbx++;
5650 } else {
5651 tempbx += tempcx;
5652 if(SiS_Pr->ChipType < SIS_315H) tempbx++;
5653 else if(issis) tempbx++;
5654 }
5655
5656 if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5657
5658 temp = tempbx & 0x00FF;
5659 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5660 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5661 if(ModeNo == 0x10) temp = 0xa9;
5662 }
5663 }
5664 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp); /* BPLVRS */
5665
5666 tempcx >>= 3;
5667 tempcx++;
5668
5669 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5670 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5671 if(SiS_Pr->PanelVRE != 999) tempcx = SiS_Pr->PanelVRE;
5672 }
5673 }
5674
5675 tempcx += tempbx;
5676 temp = tempcx & 0x000F;
5677 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp); /* BPLVRE */
5678
5679 temp = ((tempbx >> 8) & 0x07) << 3;
5680 if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
5681 if(SiS_Pr->SiS_HDE != 640) {
5682 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
5683 }
5684 } else if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
5685 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) temp |= 0x40;
5686 tempbx = 0x87;
5687 if((SiS_Pr->ChipType >= SIS_315H) ||
5688 (SiS_Pr->ChipRevision >= 0x30)) {
5689 tempbx = 0x07;
5690 if((SiS_Pr->SiS_IF_DEF_CH70xx == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
5691 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x03) temp |= 0x80;
5692 }
5693 /* Chrontel 701x operates in 24bit mode (8-8-8, 2x12bit multiplexed) via VGA2 */
5694 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5695 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5696 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x10) temp |= 0x80;
5697 } else {
5698 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80;
5699 }
5700 }
5701 }
5702 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,tempbx,temp);
5703
5704 tempbx = push2; /* BPLVDEE */
5705
5706 tempcx = SiS_Pr->SiS_LCDVDES; /* BPLVDES */
5707
5708 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5709 switch(SiS_Pr->SiS_LCDResInfo) {
5710 case Panel_640x480:
5711 tempbx = SiS_Pr->SiS_VGAVDE - 1;
5712 tempcx = SiS_Pr->SiS_VGAVDE;
5713 break;
5714 case Panel_800x600:
5715 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5716 if(resinfo == SIS_RI_800x600) tempcx++;
5717 }
5718 break;
5719 case Panel_1024x600:
5720 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5721 if(resinfo == SIS_RI_1024x600) tempcx++;
5722 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
5723 if(resinfo == SIS_RI_800x600) tempcx++;
5724 }
5725 }
5726 break;
5727 case Panel_1024x768:
5728 if(SiS_Pr->ChipType < SIS_315H) {
5729 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5730 if(resinfo == SIS_RI_1024x768) tempcx++;
5731 }
5732 }
5733 break;
5734 }
5735 }
5736
5737 temp = ((tempbx >> 8) & 0x07) << 3;
5738 temp |= ((tempcx >> 8) & 0x07);
5739 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1D,temp);
5740 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1C,tempbx);
5741 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1B,tempcx);
5742
5743 /* Vertical scaling */
5744
5745 if(SiS_Pr->ChipType < SIS_315H) {
5746
5747 #ifdef SIS300 /* 300 series */
5748 tempeax = SiS_Pr->SiS_VGAVDE << 6;
5749 temp = (tempeax % (unsigned int)SiS_Pr->SiS_VDE);
5750 tempeax = tempeax / (unsigned int)SiS_Pr->SiS_VDE;
5751 if(temp) tempeax++;
5752
5753 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) tempeax = 0x3F;
5754
5755 temp = (unsigned short)(tempeax & 0x00FF);
5756 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,temp); /* BPLVCFACT */
5757 tempvcfact = temp;
5758 #endif /* SIS300 */
5759
5760 } else {
5761
5762 #ifdef SIS315H /* 315 series */
5763 tempeax = SiS_Pr->SiS_VGAVDE << 18;
5764 tempebx = SiS_Pr->SiS_VDE;
5765 temp = (tempeax % tempebx);
5766 tempeax = tempeax / tempebx;
5767 if(temp) tempeax++;
5768 tempvcfact = tempeax;
5769
5770 temp = (unsigned short)(tempeax & 0x00FF);
5771 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,temp);
5772 temp = (unsigned short)((tempeax & 0x00FF00) >> 8);
5773 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,temp);
5774 temp = (unsigned short)((tempeax & 0x00030000) >> 16);
5775 if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
5776 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,temp);
5777
5778 if(SiS_Pr->SiS_VBType & VB_SISPART4SCALER) {
5779 temp = (unsigned short)(tempeax & 0x00FF);
5780 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3c,temp);
5781 temp = (unsigned short)((tempeax & 0x00FF00) >> 8);
5782 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3b,temp);
5783 temp = (unsigned short)(((tempeax & 0x00030000) >> 16) << 6);
5784 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0x3f,temp);
5785 temp = 0;
5786 if(SiS_Pr->SiS_VDE != SiS_Pr->SiS_VGAVDE) temp |= 0x08;
5787 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x30,0xf3,temp);
5788 }
5789 #endif
5790
5791 }
5792
5793 /* Horizontal scaling */
5794
5795 tempeax = SiS_Pr->SiS_VGAHDE; /* 1f = ( (VGAHDE * 65536) / ( (VGAHDE * 65536) / HDE ) ) - 1*/
5796 if(chkdclkfirst) {
5797 if(modeflag & HalfDCLK) tempeax >>= 1;
5798 }
5799 tempebx = tempeax << 16;
5800 if(SiS_Pr->SiS_HDE == tempeax) {
5801 tempecx = 0xFFFF;
5802 } else {
5803 tempecx = tempebx / SiS_Pr->SiS_HDE;
5804 if(SiS_Pr->ChipType >= SIS_315H) {
5805 if(tempebx % SiS_Pr->SiS_HDE) tempecx++;
5806 }
5807 }
5808
5809 if(SiS_Pr->ChipType >= SIS_315H) {
5810 tempeax = (tempebx / tempecx) - 1;
5811 } else {
5812 tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1;
5813 }
5814 tempecx = (tempecx << 16) | (tempeax & 0xFFFF);
5815 temp = (unsigned short)(tempecx & 0x00FF);
5816 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1F,temp);
5817
5818 if(SiS_Pr->ChipType >= SIS_315H) {
5819 tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
5820 tempbx = (unsigned short)(tempeax & 0xFFFF);
5821 } else {
5822 tempeax = SiS_Pr->SiS_VGAVDE << 6;
5823 tempbx = tempvcfact & 0x3f;
5824 if(tempbx == 0) tempbx = 64;
5825 tempeax /= tempbx;
5826 tempbx = (unsigned short)(tempeax & 0xFFFF);
5827 }
5828 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tempbx--;
5829 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
5830 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) tempbx = 1;
5831 else if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) tempbx = 1;
5832 }
5833
5834 temp = ((tempbx >> 8) & 0x07) << 3;
5835 temp = temp | ((tempecx >> 8) & 0x07);
5836 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x20,temp);
5837 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x21,tempbx);
5838
5839 tempecx >>= 16; /* BPLHCFACT */
5840 if(!chkdclkfirst) {
5841 if(modeflag & HalfDCLK) tempecx >>= 1;
5842 }
5843 temp = (unsigned short)((tempecx & 0xFF00) >> 8);
5844 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x22,temp);
5845 temp = (unsigned short)(tempecx & 0x00FF);
5846 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp);
5847
5848 #ifdef SIS315H
5849 if(SiS_Pr->ChipType >= SIS_315H) {
5850 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5851 if((islvds) || (SiS_Pr->SiS_VBInfo & VB_SISLVDS)) {
5852 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x20);
5853 }
5854 } else {
5855 if(islvds) {
5856 if(SiS_Pr->ChipType == SIS_740) {
5857 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
5858 } else {
5859 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x23);
5860 }
5861 }
5862 }
5863 }
5864 #endif
5865
5866 #ifdef SIS300
5867 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5868 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
5869 unsigned char *trumpdata;
5870 int i, j = crt2crtc;
5871 unsigned char TrumpMode13[4] = { 0x01, 0x10, 0x2c, 0x00 };
5872 unsigned char TrumpMode10_1[4] = { 0x01, 0x10, 0x27, 0x00 };
5873 unsigned char TrumpMode10_2[4] = { 0x01, 0x16, 0x10, 0x00 };
5874
5875 if(SiS_Pr->SiS_UseROM) {
5876 trumpdata = &ROMAddr[0x8001 + (j * 80)];
5877 } else {
5878 if(SiS_Pr->SiS_LCDTypeInfo == 0x0e) j += 7;
5879 trumpdata = &SiS300_TrumpionData[j][0];
5880 }
5881
5882 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xbf);
5883 for(i=0; i<5; i++) {
5884 SiS_SetTrumpionBlock(SiS_Pr, trumpdata);
5885 }
5886 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5887 if(ModeNo == 0x13) {
5888 for(i=0; i<4; i++) {
5889 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode13[0]);
5890 }
5891 } else if(ModeNo == 0x10) {
5892 for(i=0; i<4; i++) {
5893 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_1[0]);
5894 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_2[0]);
5895 }
5896 }
5897 }
5898 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
5899 }
5900 #endif
5901
5902 #ifdef SIS315H
5903 if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
5904 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x25,0x00);
5905 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x26,0x00);
5906 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x27,0x00);
5907 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x28,0x87);
5908 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x29,0x5A);
5909 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2A,0x4B);
5910 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x07,0x03);
5911 tempax = SiS_Pr->SiS_HDE; /* Blps = lcdhdee(lcdhdes+HDE) + 64 */
5912 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5913 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5914 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
5915 tempax += 64;
5916 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,tempax & 0xff);
5917 temp = (tempax >> 8) << 3;
5918 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp);
5919 tempax += 32; /* Blpe = lBlps+32 */
5920 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,tempax & 0xff);
5921 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3A,0x00); /* Bflml = 0 */
5922 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x007);
5923
5924 tempax = SiS_Pr->SiS_VDE;
5925 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5926 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5927 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
5928 tempax >>= 1;
5929 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3B,tempax & 0xff);
5930 temp = (tempax >> 8) << 3;
5931 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);
5932
5933 tempeax = SiS_Pr->SiS_HDE;
5934 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5935 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5936 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempeax >>= 1;
5937 tempeax <<= 2; /* BDxFIFOSTOP = (HDE*4)/128 */
5938 temp = tempeax & 0x7f;
5939 tempeax >>= 7;
5940 if(temp) tempeax++;
5941 temp = tempeax & 0x3f;
5942 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,temp);
5943 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3F,0x00); /* BDxWadrst0 */
5944 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3E,0x00);
5945 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3D,0x10);
5946 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x040);
5947
5948 tempax = SiS_Pr->SiS_HDE;
5949 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5950 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5951 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
5952 tempax >>= 4; /* BDxWadroff = HDE*4/8/8 */
5953 pushcx = tempax;
5954 temp = tempax & 0x00FF;
5955 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,temp);
5956 temp = ((tempax & 0xFF00) >> 8) << 3;
5957 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x0F8,temp);
5958
5959 tempax = SiS_Pr->SiS_VDE; /* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
5960 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
5961 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5962 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
5963 tempeax = tempax * pushcx;
5964 temp = tempeax & 0xFF;
5965 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,temp);
5966 temp = (tempeax & 0xFF00) >> 8;
5967 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,temp);
5968 temp = ((tempeax & 0xFF0000) >> 16) | 0x10;
5969 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,temp);
5970 temp = ((tempeax & 0x01000000) >> 24) << 7;
5971 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x080,temp);
5972
5973 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x03);
5974 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0x50);
5975 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,0x00);
5976 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x01);
5977 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0x38);
5978
5979 if(SiS_Pr->SiS_IF_DEF_FSTN) {
5980 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2b,0x02);
5981 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2c,0x00);
5982 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x00);
5983 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,0x0c);
5984 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,0x00);
5985 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,0x00);
5986 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,0x80);
5987 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,0xA0);
5988 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3a,0x00);
5989 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3b,0xf0);
5990 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3c,0x00);
5991 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3d,0x10);
5992 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3e,0x00);
5993 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3f,0x00);
5994 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,0x10);
5995 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,0x25);
5996 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,0x80);
5997 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,0x14);
5998 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x44,0x03);
5999 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,0x0a);
6000 }
6001 }
6002 #endif /* SIS315H */
6003 }
6004
6005 /* Set Part 1 */
6006 static void
6007 SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6008 unsigned short RefreshRateTableIndex)
6009 {
6010 #if defined(SIS300) || defined(SIS315H)
6011 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
6012 #endif
6013 unsigned short temp=0, tempax=0, tempbx=0, tempcx=0, bridgeadd=0;
6014 unsigned short pushbx=0, CRT1Index=0, modeflag, resinfo=0;
6015 #ifdef SIS315H
6016 unsigned short tempbl=0;
6017 #endif
6018
6019 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
6020 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6021 return;
6022 }
6023
6024 if(ModeNo <= 0x13) {
6025 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6026 } else if(SiS_Pr->UseCustomMode) {
6027 modeflag = SiS_Pr->CModeFlag;
6028 } else {
6029 CRT1Index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);
6030 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
6031 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6032 }
6033
6034 SiS_SetCRT2Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6035
6036 if( ! ((SiS_Pr->ChipType >= SIS_315H) &&
6037 (SiS_Pr->SiS_IF_DEF_LVDS == 1) &&
6038 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
6039
6040 if(SiS_Pr->ChipType < SIS_315H ) {
6041 #ifdef SIS300
6042 SiS_SetCRT2FIFO_300(SiS_Pr, ModeNo);
6043 #endif
6044 } else {
6045 #ifdef SIS315H
6046 SiS_SetCRT2FIFO_310(SiS_Pr);
6047 #endif
6048 }
6049
6050 /* 1. Horizontal setup */
6051
6052 if(SiS_Pr->ChipType < SIS_315H ) {
6053
6054 #ifdef SIS300 /* ------------- 300 series --------------*/
6055
6056 temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
6057 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp); /* CRT2 Horizontal Total */
6058
6059 temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
6060 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp); /* CRT2 Horizontal Total Overflow [7:4] */
6061
6062 temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */
6063 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp); /* CRT2 Horizontal Display Enable End */
6064
6065 pushbx = SiS_Pr->SiS_VGAHDE + 12; /* bx BTVGA2HRS 0x0B,0x0C */
6066 tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2;
6067 tempbx = pushbx + tempcx;
6068 tempcx <<= 1;
6069 tempcx += tempbx;
6070
6071 bridgeadd = 12;
6072
6073 #endif /* SIS300 */
6074
6075 } else {
6076
6077 #ifdef SIS315H /* ------------------- 315/330 series --------------- */
6078
6079 tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HT 0x08,0x09 */
6080 if(modeflag & HalfDCLK) {
6081 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6082 tempcx >>= 1;
6083 } else {
6084 tempax = SiS_Pr->SiS_VGAHDE >> 1;
6085 tempcx = SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE + tempax;
6086 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
6087 tempcx = SiS_Pr->SiS_HT - tempax;
6088 }
6089 }
6090 }
6091 tempcx--;
6092 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,tempcx); /* CRT2 Horizontal Total */
6093 temp = (tempcx >> 4) & 0xF0;
6094 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp); /* CRT2 Horizontal Total Overflow [7:4] */
6095
6096 tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HDEE 0x0A,0x0C */
6097 tempbx = SiS_Pr->SiS_VGAHDE;
6098 tempcx -= tempbx;
6099 tempcx >>= 2;
6100 if(modeflag & HalfDCLK) {
6101 tempbx >>= 1;
6102 tempcx >>= 1;
6103 }
6104 tempbx += 16;
6105
6106 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,tempbx); /* CRT2 Horizontal Display Enable End */
6107
6108 pushbx = tempbx;
6109 tempcx >>= 1;
6110 tempbx += tempcx;
6111 tempcx += tempbx;
6112
6113 bridgeadd = 16;
6114
6115 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6116 if(SiS_Pr->ChipType >= SIS_661) {
6117 if((SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
6118 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
6119 if(resinfo == SIS_RI_1280x1024) {
6120 tempcx = (tempcx & 0xff00) | 0x30;
6121 } else if(resinfo == SIS_RI_1600x1200) {
6122 tempcx = (tempcx & 0xff00) | 0xff;
6123 }
6124 }
6125 }
6126 }
6127
6128 #endif /* SIS315H */
6129
6130 } /* 315/330 series */
6131
6132 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6133
6134 if(SiS_Pr->UseCustomMode) {
6135 tempbx = SiS_Pr->CHSyncStart + bridgeadd;
6136 tempcx = SiS_Pr->CHSyncEnd + bridgeadd;
6137 tempax = SiS_Pr->SiS_VGAHT;
6138 if(modeflag & HalfDCLK) tempax >>= 1;
6139 tempax--;
6140 if(tempcx > tempax) tempcx = tempax;
6141 }
6142
6143 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6144 unsigned char cr4, cr14, cr5, cr15;
6145 if(SiS_Pr->UseCustomMode) {
6146 cr4 = SiS_Pr->CCRT1CRTC[4];
6147 cr14 = SiS_Pr->CCRT1CRTC[14];
6148 cr5 = SiS_Pr->CCRT1CRTC[5];
6149 cr15 = SiS_Pr->CCRT1CRTC[15];
6150 } else {
6151 cr4 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
6152 cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
6153 cr5 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
6154 cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
6155 }
6156 tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3; /* (VGAHRS-3)*8 */
6157 tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3; /* (VGAHRE-3)*8 */
6158 tempcx &= 0x00FF;
6159 tempcx |= (tempbx & 0xFF00);
6160 tempbx += bridgeadd;
6161 tempcx += bridgeadd;
6162 tempax = SiS_Pr->SiS_VGAHT;
6163 if(modeflag & HalfDCLK) tempax >>= 1;
6164 tempax--;
6165 if(tempcx > tempax) tempcx = tempax;
6166 }
6167
6168 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {
6169 tempbx = 1040;
6170 tempcx = 1044; /* HWCursor bug! */
6171 }
6172
6173 }
6174
6175 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,tempbx); /* CRT2 Horizontal Retrace Start */
6176
6177 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,tempcx); /* CRT2 Horizontal Retrace End */
6178
6179 temp = ((tempbx >> 8) & 0x0F) | ((pushbx >> 4) & 0xF0);
6180 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp); /* Overflow */
6181
6182 /* 2. Vertical setup */
6183
6184 tempcx = SiS_Pr->SiS_VGAVT - 1;
6185 temp = tempcx & 0x00FF;
6186
6187 if(SiS_Pr->ChipType < SIS_661) {
6188 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6189 if(SiS_Pr->ChipType < SIS_315H) {
6190 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6191 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
6192 temp--;
6193 }
6194 }
6195 } else {
6196 temp--;
6197 }
6198 } else if(SiS_Pr->ChipType >= SIS_315H) {
6199 temp--;
6200 }
6201 }
6202 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp); /* CRT2 Vertical Total */
6203
6204 tempbx = SiS_Pr->SiS_VGAVDE - 1;
6205 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,tempbx); /* CRT2 Vertical Display Enable End */
6206
6207 temp = ((tempbx >> 5) & 0x38) | ((tempcx >> 8) & 0x07);
6208 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,temp); /* Overflow */
6209
6210 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
6211 tempbx++;
6212 tempax = tempbx;
6213 tempcx++;
6214 tempcx -= tempax;
6215 tempcx >>= 2;
6216 tempbx += tempcx;
6217 if(tempcx < 4) tempcx = 4;
6218 tempcx >>= 2;
6219 tempcx += tempbx;
6220 tempcx++;
6221 } else {
6222 tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1; /* BTVGA2VRS 0x10,0x11 */
6223 tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1; /* BTVGA2VRE 0x11 */
6224 }
6225
6226 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6227 if(SiS_Pr->UseCustomMode) {
6228 tempbx = SiS_Pr->CVSyncStart;
6229 tempcx = SiS_Pr->CVSyncEnd;
6230 }
6231 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6232 unsigned char cr8, cr7, cr13;
6233 if(SiS_Pr->UseCustomMode) {
6234 cr8 = SiS_Pr->CCRT1CRTC[8];
6235 cr7 = SiS_Pr->CCRT1CRTC[7];
6236 cr13 = SiS_Pr->CCRT1CRTC[13];
6237 tempcx = SiS_Pr->CCRT1CRTC[9];
6238 } else {
6239 cr8 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8];
6240 cr7 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
6241 cr13 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
6242 tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
6243 }
6244 tempbx = cr8;
6245 if(cr7 & 0x04) tempbx |= 0x0100;
6246 if(cr7 & 0x80) tempbx |= 0x0200;
6247 if(cr13 & 0x08) tempbx |= 0x0400;
6248 }
6249 }
6250 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,tempbx); /* CRT2 Vertical Retrace Start */
6251
6252 temp = ((tempbx >> 4) & 0x70) | (tempcx & 0x0F);
6253 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,temp); /* CRT2 Vert. Retrace End; Overflow */
6254
6255 /* 3. Panel delay compensation */
6256
6257 if(SiS_Pr->ChipType < SIS_315H) {
6258
6259 #ifdef SIS300 /* ---------- 300 series -------------- */
6260
6261 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6262 temp = 0x20;
6263 if(SiS_Pr->ChipType == SIS_300) {
6264 temp = 0x10;
6265 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) temp = 0x2c;
6266 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6267 }
6268 if(SiS_Pr->SiS_VBType & VB_SIS301) {
6269 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6270 }
6271 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960) temp = 0x24;
6272 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) temp = 0x2c;
6273 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x08;
6274 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6275 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) temp = 0x2c;
6276 else temp = 0x20;
6277 }
6278 if(SiS_Pr->SiS_UseROM) {
6279 if(ROMAddr[0x220] & 0x80) {
6280 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision)
6281 temp = ROMAddr[0x221];
6282 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)
6283 temp = ROMAddr[0x222];
6284 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)
6285 temp = ROMAddr[0x223];
6286 else
6287 temp = ROMAddr[0x224];
6288 }
6289 }
6290 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6291 if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC;
6292 }
6293
6294 } else {
6295 temp = 0x20;
6296 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
6297 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) temp = 0x04;
6298 }
6299 if(SiS_Pr->SiS_UseROM) {
6300 if(ROMAddr[0x220] & 0x80) {
6301 temp = ROMAddr[0x220];
6302 }
6303 }
6304 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6305 if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC;
6306 }
6307 }
6308
6309 temp &= 0x3c;
6310
6311 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
6312
6313 #endif /* SIS300 */
6314
6315 } else {
6316
6317 #ifdef SIS315H /* --------------- 315/330 series ---------------*/
6318
6319 if(SiS_Pr->ChipType < SIS_661) {
6320
6321 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6322
6323 if(SiS_Pr->ChipType == SIS_740) temp = 0x03;
6324 else temp = 0x00;
6325
6326 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x0a;
6327 tempbl = 0xF0;
6328 if(SiS_Pr->ChipType == SIS_650) {
6329 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6330 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F;
6331 }
6332 }
6333
6334 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) {
6335 temp = 0x08;
6336 tempbl = 0;
6337 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
6338 if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0;
6339 }
6340 }
6341
6342 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp); /* Panel Link Delay Compensation */
6343 }
6344
6345 } /* < 661 */
6346
6347 tempax = 0;
6348 if(modeflag & DoubleScanMode) tempax |= 0x80;
6349 if(modeflag & HalfDCLK) tempax |= 0x40;
6350 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax);
6351
6352 #endif /* SIS315H */
6353
6354 }
6355
6356 } /* Slavemode */
6357
6358 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6359 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
6360 /* For 301BDH with LCD, we set up the Panel Link */
6361 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6362 } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6363 SiS_SetGroup1_301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6364 }
6365 } else {
6366 if(SiS_Pr->ChipType < SIS_315H) {
6367 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6368 } else {
6369 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6370 if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
6371 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex);
6372 }
6373 } else {
6374 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex);
6375 }
6376 }
6377 }
6378 }
6379
6380 /*********************************************/
6381 /* SET PART 2 REGISTER GROUP */
6382 /*********************************************/
6383
6384 #ifdef SIS315H
6385 static unsigned char *
6386 SiS_GetGroup2CLVXPtr(struct SiS_Private *SiS_Pr, int tabletype)
6387 {
6388 const unsigned char *tableptr = NULL;
6389 unsigned short a, b, p = 0;
6390
6391 a = SiS_Pr->SiS_VGAHDE;
6392 b = SiS_Pr->SiS_HDE;
6393 if(tabletype) {
6394 a = SiS_Pr->SiS_VGAVDE;
6395 b = SiS_Pr->SiS_VDE;
6396 }
6397
6398 if(a < b) {
6399 tableptr = SiS_Part2CLVX_1;
6400 } else if(a == b) {
6401 tableptr = SiS_Part2CLVX_2;
6402 } else {
6403 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6404 tableptr = SiS_Part2CLVX_4;
6405 } else {
6406 tableptr = SiS_Part2CLVX_3;
6407 }
6408 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6409 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) tableptr = SiS_Part2CLVX_3;
6410 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tableptr = SiS_Part2CLVX_3;
6411 else tableptr = SiS_Part2CLVX_5;
6412 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6413 tableptr = SiS_Part2CLVX_6;
6414 }
6415 do {
6416 if((tableptr[p] | tableptr[p+1] << 8) == a) break;
6417 p += 0x42;
6418 } while((tableptr[p] | tableptr[p+1] << 8) != 0xffff);
6419 if((tableptr[p] | tableptr[p+1] << 8) == 0xffff) p -= 0x42;
6420 }
6421 p += 2;
6422 return ((unsigned char *)&tableptr[p]);
6423 }
6424
6425 static void
6426 SiS_SetGroup2_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6427 unsigned short RefreshRateTableIndex)
6428 {
6429 unsigned char *tableptr;
6430 unsigned char temp;
6431 int i, j;
6432
6433 if(!(SiS_Pr->SiS_VBType & VB_SISTAP4SCALER)) return;
6434
6435 tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 0);
6436 for(i = 0x80, j = 0; i <= 0xbf; i++, j++) {
6437 SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6438 }
6439 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6440 tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 1);
6441 for(i = 0xc0, j = 0; i <= 0xff; i++, j++) {
6442 SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6443 }
6444 }
6445 temp = 0x10;
6446 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp |= 0x04;
6447 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xeb,temp);
6448 }
6449
6450 static bool
6451 SiS_GetCRT2Part2Ptr(struct SiS_Private *SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,
6452 unsigned short RefreshRateTableIndex,unsigned short *CRT2Index,
6453 unsigned short *ResIndex)
6454 {
6455
6456 if(SiS_Pr->ChipType < SIS_315H) return false;
6457
6458 if(ModeNo <= 0x13)
6459 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6460 else
6461 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6462
6463 (*ResIndex) &= 0x3f;
6464 (*CRT2Index) = 0;
6465
6466 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6467 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6468 (*CRT2Index) = 200;
6469 }
6470 }
6471
6472 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
6473 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6474 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) (*CRT2Index) = 206;
6475 }
6476 }
6477 return (((*CRT2Index) != 0));
6478 }
6479 #endif
6480
6481 #ifdef SIS300
6482 static void
6483 SiS_Group2LCDSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short crt2crtc)
6484 {
6485 unsigned short tempcx;
6486 static const unsigned char atable[] = {
6487 0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,
6488 0xab,0x87,0xab,0x9e,0xe7,0x02,0x02
6489 };
6490
6491 if(!SiS_Pr->UseCustomMode) {
6492 if( ( ( (SiS_Pr->ChipType == SIS_630) ||
6493 (SiS_Pr->ChipType == SIS_730) ) &&
6494 (SiS_Pr->ChipRevision > 2) ) &&
6495 (SiS_Pr->SiS_LCDResInfo == Panel_1024x768) &&
6496 (!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) &&
6497 (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
6498 if(ModeNo == 0x13) {
6499 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xB9);
6500 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0xCC);
6501 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xA6);
6502 } else if((crt2crtc & 0x3F) == 4) {
6503 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x2B);
6504 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x13);
6505 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xE5);
6506 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0x08);
6507 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xE2);
6508 }
6509 }
6510
6511 if(SiS_Pr->ChipType < SIS_315H) {
6512 if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
6513 crt2crtc &= 0x1f;
6514 tempcx = 0;
6515 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6516 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6517 tempcx += 7;
6518 }
6519 }
6520 tempcx += crt2crtc;
6521 if(crt2crtc >= 4) {
6522 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xff);
6523 }
6524
6525 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6526 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6527 if(crt2crtc == 4) {
6528 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x28);
6529 }
6530 }
6531 }
6532 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x18);
6533 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
6534 }
6535 }
6536 }
6537 }
6538
6539 /* For ECS A907. Highly preliminary. */
6540 static void
6541 SiS_Set300Part2Regs(struct SiS_Private *SiS_Pr, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex,
6542 unsigned short ModeNo)
6543 {
6544 const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
6545 unsigned short crt2crtc, resindex;
6546 int i, j;
6547
6548 if(SiS_Pr->ChipType != SIS_300) return;
6549 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;
6550 if(SiS_Pr->UseCustomMode) return;
6551
6552 if(ModeNo <= 0x13) {
6553 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6554 } else {
6555 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6556 }
6557
6558 resindex = crt2crtc & 0x3F;
6559 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6560 else CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2;
6561
6562 /* The BIOS code (1.16.51,56) is obviously a fragment! */
6563 if(ModeNo > 0x13) {
6564 CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6565 resindex = 4;
6566 }
6567
6568 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
6569 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
6570 for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
6571 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6572 }
6573 for(j = 0x1c; j <= 0x1d; i++, j++ ) {
6574 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6575 }
6576 for(j = 0x1f; j <= 0x21; i++, j++ ) {
6577 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6578 }
6579 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
6580 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
6581 }
6582 #endif
6583
6584 static void
6585 SiS_SetTVSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
6586 {
6587 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;
6588 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) return;
6589 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) return;
6590
6591 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
6592 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6593 const unsigned char specialtv[] = {
6594 0xa7,0x07,0xf2,0x6e,0x17,0x8b,0x73,0x53,
6595 0x13,0x40,0x34,0xf4,0x63,0xbb,0xcc,0x7a,
6596 0x58,0xe4,0x73,0xda,0x13
6597 };
6598 int i, j;
6599 for(i = 0x1c, j = 0; i <= 0x30; i++, j++) {
6600 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,specialtv[j]);
6601 }
6602 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,0x72);
6603 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750)) {
6604 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6605 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14);
6606 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1b);
6607 } else {
6608 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14); /* 15 */
6609 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1a); /* 1b */
6610 }
6611 }
6612 }
6613 } else {
6614 if((ModeNo == 0x38) || (ModeNo == 0x4a) || (ModeNo == 0x64) ||
6615 (ModeNo == 0x52) || (ModeNo == 0x58) || (ModeNo == 0x5c)) {
6616 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b); /* 21 */
6617 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54); /* 5a */
6618 } else {
6619 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1a); /* 21 */
6620 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x53); /* 5a */
6621 }
6622 }
6623 }
6624
6625 static void
6626 SiS_SetGroup2_Tail(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
6627 {
6628 unsigned short temp;
6629
6630 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6631 if(SiS_Pr->SiS_VGAVDE == 525) {
6632 temp = 0xc3;
6633 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6634 temp++;
6635 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp += 2;
6636 }
6637 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6638 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xb3);
6639 } else if(SiS_Pr->SiS_VGAVDE == 420) {
6640 temp = 0x4d;
6641 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6642 temp++;
6643 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp++;
6644 }
6645 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6646 }
6647 }
6648
6649 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6650 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
6651 if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
6652 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x1a,0x03);
6653 /* Not always for LV, see SetGrp2 */
6654 }
6655 temp = 1;
6656 if(ModeNo <= 0x13) temp = 3;
6657 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0b,temp);
6658 }
6659 #if 0
6660 /* 651+301C, for 1280x768 - do I really need that? */
6661 if((SiS_Pr->SiS_PanelXRes == 1280) && (SiS_Pr->SiS_PanelYRes == 768)) {
6662 if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) {
6663 if(((SiS_Pr->SiS_HDE == 640) && (SiS_Pr->SiS_VDE == 480)) ||
6664 ((SiS_Pr->SiS_HDE == 320) && (SiS_Pr->SiS_VDE == 240))) {
6665 SiS_SetReg(SiS_Part2Port,0x01,0x2b);
6666 SiS_SetReg(SiS_Part2Port,0x02,0x13);
6667 SiS_SetReg(SiS_Part2Port,0x04,0xe5);
6668 SiS_SetReg(SiS_Part2Port,0x05,0x08);
6669 SiS_SetReg(SiS_Part2Port,0x06,0xe2);
6670 SiS_SetReg(SiS_Part2Port,0x1c,0x21);
6671 SiS_SetReg(SiS_Part2Port,0x1d,0x45);
6672 SiS_SetReg(SiS_Part2Port,0x1f,0x0b);
6673 SiS_SetReg(SiS_Part2Port,0x20,0x00);
6674 SiS_SetReg(SiS_Part2Port,0x21,0xa9);
6675 SiS_SetReg(SiS_Part2Port,0x23,0x0b);
6676 SiS_SetReg(SiS_Part2Port,0x25,0x04);
6677 }
6678 }
6679 }
6680 #endif
6681 }
6682 }
6683
6684 static void
6685 SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6686 unsigned short RefreshRateTableIndex)
6687 {
6688 unsigned short i, j, tempax, tempbx, tempcx, tempch, tempcl, temp;
6689 unsigned short push2, modeflag, crt2crtc, bridgeoffset;
6690 unsigned int longtemp, PhaseIndex;
6691 bool newtvphase;
6692 const unsigned char *TimingPoint;
6693 #ifdef SIS315H
6694 unsigned short resindex, CRT2Index;
6695 const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
6696
6697 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
6698 #endif
6699
6700 if(ModeNo <= 0x13) {
6701 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6702 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6703 } else if(SiS_Pr->UseCustomMode) {
6704 modeflag = SiS_Pr->CModeFlag;
6705 crt2crtc = 0;
6706 } else {
6707 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6708 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6709 }
6710
6711 temp = 0;
6712 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO)) temp |= 0x08;
6713 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO)) temp |= 0x04;
6714 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) temp |= 0x02;
6715 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp |= 0x01;
6716
6717 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) temp |= 0x10;
6718
6719 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x00,temp);
6720
6721 PhaseIndex = 0x01; /* SiS_PALPhase */
6722 TimingPoint = SiS_Pr->SiS_PALTiming;
6723
6724 newtvphase = false;
6725 if( (SiS_Pr->SiS_VBType & VB_SIS30xBLV) &&
6726 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6727 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6728 newtvphase = true;
6729 }
6730
6731 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6732
6733 TimingPoint = SiS_Pr->SiS_HiTVExtTiming;
6734 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6735 TimingPoint = SiS_Pr->SiS_HiTVSt2Timing;
6736 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
6737 TimingPoint = SiS_Pr->SiS_HiTVSt1Timing;
6738 }
6739 }
6740
6741 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6742
6743 i = 0;
6744 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) i = 2;
6745 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) i = 1;
6746
6747 TimingPoint = &SiS_YPbPrTable[i][0];
6748
6749 PhaseIndex = 0x00; /* SiS_NTSCPhase */
6750
6751 } else if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6752
6753 if(newtvphase) PhaseIndex = 0x09; /* SiS_PALPhase2 */
6754
6755 } else {
6756
6757 TimingPoint = SiS_Pr->SiS_NTSCTiming;
6758 PhaseIndex = (SiS_Pr->SiS_TVMode & TVSetNTSCJ) ? 0x01 : 0x00; /* SiS_PALPhase : SiS_NTSCPhase */
6759 if(newtvphase) PhaseIndex += 8; /* SiS_PALPhase2 : SiS_NTSCPhase2 */
6760
6761 }
6762
6763 if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) {
6764 PhaseIndex = (SiS_Pr->SiS_TVMode & TVSetPALM) ? 0x02 : 0x03; /* SiS_PALMPhase : SiS_PALNPhase */
6765 if(newtvphase) PhaseIndex += 8; /* SiS_PALMPhase2 : SiS_PALNPhase2 */
6766 }
6767
6768 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6769 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6770 PhaseIndex = 0x05; /* SiS_SpecialPhaseM */
6771 } else if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
6772 PhaseIndex = 0x11; /* SiS_SpecialPhaseJ */
6773 } else {
6774 PhaseIndex = 0x10; /* SiS_SpecialPhase */
6775 }
6776 }
6777
6778 for(i = 0x31, j = 0; i <= 0x34; i++, j++) {
6779 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[(PhaseIndex * 4) + j]);
6780 }
6781
6782 for(i = 0x01, j = 0; i <= 0x2D; i++, j++) {
6783 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
6784 }
6785 for(i = 0x39; i <= 0x45; i++, j++) {
6786 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
6787 }
6788
6789 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6790 if(SiS_Pr->SiS_ModeType != ModeText) {
6791 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
6792 }
6793 }
6794
6795 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x0A,SiS_Pr->SiS_NewFlickerMode);
6796
6797 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x35,SiS_Pr->SiS_RY1COE);
6798 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x36,SiS_Pr->SiS_RY2COE);
6799 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x37,SiS_Pr->SiS_RY3COE);
6800 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x38,SiS_Pr->SiS_RY4COE);
6801
6802 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempax = 950;
6803 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempax = 680;
6804 else if(SiS_Pr->SiS_TVMode & TVSetPAL) tempax = 520;
6805 else tempax = 440; /* NTSC, YPbPr 525 */
6806
6807 if( ((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) && (SiS_Pr->SiS_VDE <= tempax)) ||
6808 ( (SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) &&
6809 ((SiS_Pr->SiS_VGAHDE == 1024) || (SiS_Pr->SiS_VDE <= tempax)) ) ) {
6810
6811 tempax -= SiS_Pr->SiS_VDE;
6812 tempax >>= 1;
6813 if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) {
6814 tempax >>= 1;
6815 }
6816 tempax &= 0x00ff;
6817
6818 temp = tempax + (unsigned short)TimingPoint[0];
6819 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
6820
6821 temp = tempax + (unsigned short)TimingPoint[1];
6822 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
6823
6824 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) && (SiS_Pr->SiS_VGAHDE >= 1024)) {
6825 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6826 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b);
6827 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54);
6828 } else {
6829 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x17);
6830 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1d);
6831 }
6832 }
6833
6834 }
6835
6836 tempcx = SiS_Pr->SiS_HT;
6837 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
6838 tempcx--;
6839 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) tempcx--;
6840 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1B,tempcx);
6841 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0xF0,((tempcx >> 8) & 0x0f));
6842
6843 tempcx = SiS_Pr->SiS_HT >> 1;
6844 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
6845 tempcx += 7;
6846 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
6847 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,((tempcx << 4) & 0xf0));
6848
6849 tempbx = TimingPoint[j] | (TimingPoint[j+1] << 8);
6850 tempbx += tempcx;
6851 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x24,tempbx);
6852 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0F,((tempbx >> 4) & 0xf0));
6853
6854 tempbx += 8;
6855 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6856 tempbx -= 4;
6857 tempcx = tempbx;
6858 }
6859 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x29,0x0F,((tempbx << 4) & 0xf0));
6860
6861 j += 2;
6862 tempcx += (TimingPoint[j] | (TimingPoint[j+1] << 8));
6863 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x27,tempcx);
6864 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x28,0x0F,((tempcx >> 4) & 0xf0));
6865
6866 tempcx += 8;
6867 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
6868 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2A,0x0F,((tempcx << 4) & 0xf0));
6869
6870 tempcx = SiS_Pr->SiS_HT >> 1;
6871 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
6872 j += 2;
6873 tempcx -= (TimingPoint[j] | ((TimingPoint[j+1]) << 8));
6874 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2D,0x0F,((tempcx << 4) & 0xf0));
6875
6876 tempcx -= 11;
6877 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
6878 tempcx = SiS_GetVGAHT2(SiS_Pr) - 1;
6879 }
6880 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2E,tempcx);
6881
6882 tempbx = SiS_Pr->SiS_VDE;
6883 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6884 if(SiS_Pr->SiS_VGAVDE == 360) tempbx = 746;
6885 if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 746;
6886 if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 853;
6887 } else if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
6888 (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p))) ) {
6889 tempbx >>= 1;
6890 if(SiS_Pr->ChipType >= SIS_315H) {
6891 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
6892 if((ModeNo <= 0x13) && (crt2crtc == 1)) tempbx++;
6893 } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6894 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6895 if(crt2crtc == 4) tempbx++;
6896 }
6897 }
6898 }
6899 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6900 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6901 if((ModeNo == 0x2f) || (ModeNo == 0x5d) || (ModeNo == 0x5e)) tempbx++;
6902 }
6903 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
6904 if(ModeNo == 0x03) tempbx++; /* From 1.10.7w - doesn't make sense */
6905 }
6906 }
6907 }
6908 tempbx -= 2;
6909 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2F,tempbx);
6910
6911 temp = (tempcx >> 8) & 0x0F;
6912 temp |= ((tempbx >> 2) & 0xC0);
6913 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
6914 temp |= 0x10;
6915 if(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO) temp |= 0x20;
6916 }
6917 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,temp);
6918
6919 if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {
6920 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xdf,((tempbx & 0x0400) >> 5));
6921 }
6922
6923 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
6924 tempbx = SiS_Pr->SiS_VDE;
6925 if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
6926 (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) ) {
6927 tempbx >>= 1;
6928 }
6929 tempbx -= 3;
6930 temp = ((tempbx >> 3) & 0x60) | 0x18;
6931 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x46,temp);
6932 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x47,tempbx);
6933
6934 if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {
6935 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xbf,((tempbx & 0x0400) >> 4));
6936 }
6937 }
6938
6939 tempbx = 0;
6940 if(!(modeflag & HalfDCLK)) {
6941 if(SiS_Pr->SiS_VGAHDE >= SiS_Pr->SiS_HDE) {
6942 tempax = 0;
6943 tempbx |= 0x20;
6944 }
6945 }
6946
6947 tempch = tempcl = 0x01;
6948 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6949 if(SiS_Pr->SiS_VGAHDE >= 960) {
6950 if((!(modeflag & HalfDCLK)) || (SiS_Pr->ChipType < SIS_315H)) {
6951 tempcl = 0x20;
6952 if(SiS_Pr->SiS_VGAHDE >= 1280) {
6953 tempch = 20;
6954 tempbx &= ~0x20;
6955 } else if(SiS_Pr->SiS_VGAHDE >= 1024) {
6956 tempch = 25;
6957 } else {
6958 tempch = 25; /* OK */
6959 }
6960 }
6961 }
6962 }
6963
6964 if(!(tempbx & 0x20)) {
6965 if(modeflag & HalfDCLK) tempcl <<= 1;
6966 longtemp = ((SiS_Pr->SiS_VGAHDE * tempch) / tempcl) << 13;
6967 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) longtemp <<= 3;
6968 tempax = longtemp / SiS_Pr->SiS_HDE;
6969 if(longtemp % SiS_Pr->SiS_HDE) tempax++;
6970 tempbx |= ((tempax >> 8) & 0x1F);
6971 tempcx = tempax >> 13;
6972 }
6973
6974 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,tempax);
6975 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,tempbx);
6976
6977 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
6978
6979 tempcx &= 0x07;
6980 if(tempbx & 0x20) tempcx = 0;
6981 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xF8,tempcx);
6982
6983 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6984 tempbx = 0x0382;
6985 tempcx = 0x007e;
6986 } else {
6987 tempbx = 0x0369;
6988 tempcx = 0x0061;
6989 }
6990 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4B,tempbx);
6991 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4C,tempcx);
6992 temp = (tempcx & 0x0300) >> 6;
6993 temp |= ((tempbx >> 8) & 0x03);
6994 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6995 temp |= 0x10;
6996 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp |= 0x20;
6997 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp |= 0x40;
6998 }
6999 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4D,temp);
7000
7001 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7002 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,(temp - 3));
7003
7004 SiS_SetTVSpecial(SiS_Pr, ModeNo);
7005
7006 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
7007 temp = 0;
7008 if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
7009 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xf7,temp);
7010 }
7011
7012 }
7013
7014 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7015 if(!(SiS_Pr->SiS_TVMode & TVSetNTSC1024)) {
7016 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
7017 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,(temp - 1));
7018 }
7019 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF);
7020 }
7021
7022 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7023 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
7024 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,0x00);
7025 }
7026 }
7027
7028 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) return;
7029
7030 /* From here: Part2 LCD setup */
7031
7032 tempbx = SiS_Pr->SiS_HDE;
7033 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7034 tempbx--; /* RHACTE = HDE - 1 */
7035 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2C,tempbx);
7036 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,((tempbx >> 4) & 0xf0));
7037
7038 temp = 0x01;
7039 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7040 if(SiS_Pr->SiS_ModeType == ModeEGA) {
7041 if(SiS_Pr->SiS_VGAHDE >= 1024) {
7042 temp = 0x02;
7043 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7044 temp = 0x01;
7045 }
7046 }
7047 }
7048 }
7049 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,temp);
7050
7051 tempbx = SiS_Pr->SiS_VDE - 1;
7052 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x03,tempbx);
7053 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0C,0xF8,((tempbx >> 8) & 0x07));
7054
7055 tempcx = SiS_Pr->SiS_VT - 1;
7056 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x19,tempcx);
7057 temp = (tempcx >> 3) & 0xE0;
7058 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
7059 /* Enable dithering; only do this for 32bpp mode */
7060 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
7061 temp |= 0x10;
7062 }
7063 }
7064 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1A,0x0f,temp);
7065
7066 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x09,0xF0);
7067 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x0A,0xF0);
7068
7069 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB);
7070 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF);
7071
7072 #ifdef SIS315H
7073 if(SiS_GetCRT2Part2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7074 &CRT2Index, &resindex)) {
7075 switch(CRT2Index) {
7076 case 206: CRT2Part2Ptr = SiS310_CRT2Part2_Asus1024x768_3; break;
7077 default:
7078 case 200: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1; break;
7079 }
7080
7081 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
7082 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
7083 for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
7084 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7085 }
7086 for(j = 0x1c; j <= 0x1d; i++, j++ ) {
7087 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7088 }
7089 for(j = 0x1f; j <= 0x21; i++, j++ ) {
7090 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7091 }
7092 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
7093 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
7094
7095 SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7096
7097 } else {
7098 #endif
7099
7100 /* Checked for 1024x768, 1280x1024, 1400x1050, 1600x1200 */
7101 /* Clevo dual-link 1024x768 */
7102 /* Compaq 1280x1024 has HT 1696 sometimes (calculation OK, if given HT is correct) */
7103 /* Acer: OK, but uses different setting for VESA timing at 640/800/1024 and 640x400 */
7104
7105 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7106 if((SiS_Pr->SiS_LCDInfo & LCDPass11) || (SiS_Pr->PanelYRes == SiS_Pr->SiS_VDE)) {
7107 tempbx = SiS_Pr->SiS_VDE - 1;
7108 tempcx = SiS_Pr->SiS_VT - 1;
7109 } else {
7110 tempbx = SiS_Pr->SiS_VDE + ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7111 tempcx = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7112 }
7113 } else {
7114 tempbx = SiS_Pr->PanelYRes;
7115 tempcx = SiS_Pr->SiS_VT;
7116 tempax = 1;
7117 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7118 tempax = SiS_Pr->PanelYRes;
7119 /* if(SiS_Pr->SiS_VGAVDE == 525) tempax += 0x3c; */ /* 651+301C */
7120 if(SiS_Pr->PanelYRes < SiS_Pr->SiS_VDE) {
7121 tempax = tempcx = 0;
7122 } else {
7123 tempax -= SiS_Pr->SiS_VDE;
7124 }
7125 tempax >>= 1;
7126 }
7127 tempcx -= tempax; /* lcdvdes */
7128 tempbx -= tempax; /* lcdvdee */
7129 }
7130
7131 /* Non-expanding: lcdvdes = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */
7132
7133 #ifdef SIS_XORG_XF86
7134 #ifdef TWDEBUG
7135 xf86DrvMsg(0, X_INFO, "lcdvdes 0x%x lcdvdee 0x%x\n", tempcx, tempbx);
7136 #endif
7137 #endif
7138
7139 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,tempcx); /* lcdvdes */
7140 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,tempbx); /* lcdvdee */
7141
7142 temp = (tempbx >> 5) & 0x38;
7143 temp |= ((tempcx >> 8) & 0x07);
7144 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
7145
7146 tempax = SiS_Pr->SiS_VDE;
7147 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7148 tempax = SiS_Pr->PanelYRes;
7149 }
7150 tempcx = (SiS_Pr->SiS_VT - tempax) >> 4;
7151 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7152 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7153 tempcx = (SiS_Pr->SiS_VT - tempax) / 10;
7154 }
7155 }
7156
7157 tempbx = ((SiS_Pr->SiS_VT + SiS_Pr->SiS_VDE) >> 1) - 1;
7158 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7159 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7160 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { /* ? */
7161 tempax = SiS_Pr->SiS_VT - SiS_Pr->PanelYRes;
7162 if(tempax % 4) { tempax >>= 2; tempax++; }
7163 else { tempax >>= 2; }
7164 tempbx -= (tempax - 1);
7165 } else {
7166 tempbx -= 10;
7167 if(tempbx <= SiS_Pr->SiS_VDE) tempbx = SiS_Pr->SiS_VDE + 1;
7168 }
7169 }
7170 }
7171 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
7172 tempbx++;
7173 if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (crt2crtc == 6)) {
7174 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7175 tempbx = 770;
7176 tempcx = 3;
7177 }
7178 }
7179 }
7180
7181 /* non-expanding: lcdvrs = ((VT + VDE) / 2) - 10 */
7182
7183 if(SiS_Pr->UseCustomMode) {
7184 tempbx = SiS_Pr->CVSyncStart;
7185 }
7186
7187 #ifdef SIS_XORG_XF86
7188 #ifdef TWDEBUG
7189 xf86DrvMsg(0, X_INFO, "lcdvrs 0x%x\n", tempbx);
7190 #endif
7191 #endif
7192
7193 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,tempbx); /* lcdvrs */
7194
7195 temp = (tempbx >> 4) & 0xF0;
7196 tempbx += (tempcx + 1);
7197 temp |= (tempbx & 0x0F);
7198
7199 if(SiS_Pr->UseCustomMode) {
7200 temp &= 0xf0;
7201 temp |= (SiS_Pr->CVSyncEnd & 0x0f);
7202 }
7203
7204 #ifdef SIS_XORG_XF86
7205 #ifdef TWDEBUG
7206 xf86DrvMsg(0, X_INFO, "lcdvre[3:0] 0x%x\n", (temp & 0x0f));
7207 #endif
7208 #endif
7209
7210 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
7211
7212 #ifdef SIS300
7213 SiS_Group2LCDSpecial(SiS_Pr, ModeNo, crt2crtc);
7214 #endif
7215
7216 bridgeoffset = 7;
7217 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) bridgeoffset += 2;
7218 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) bridgeoffset += 2; /* OK for Averatec 1280x800 (301C) */
7219 if(SiS_IsDualLink(SiS_Pr)) bridgeoffset++;
7220 else if(SiS_Pr->SiS_VBType & VB_SIS302LV) bridgeoffset++; /* OK for Asus A4L 1280x800 */
7221 /* Higher bridgeoffset shifts to the LEFT */
7222
7223 temp = 0;
7224 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7225 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7226 temp = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7227 if(SiS_IsDualLink(SiS_Pr)) temp >>= 1;
7228 }
7229 }
7230 temp += bridgeoffset;
7231 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1F,temp); /* lcdhdes */
7232 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0F,((temp >> 4) & 0xf0));
7233
7234 tempcx = SiS_Pr->SiS_HT;
7235 tempax = tempbx = SiS_Pr->SiS_HDE;
7236 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7237 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7238 tempax = SiS_Pr->PanelXRes;
7239 tempbx = SiS_Pr->PanelXRes - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7240 }
7241 }
7242 if(SiS_IsDualLink(SiS_Pr)) {
7243 tempcx >>= 1;
7244 tempbx >>= 1;
7245 tempax >>= 1;
7246 }
7247
7248 #ifdef SIS_XORG_XF86
7249 #ifdef TWDEBUG
7250 xf86DrvMsg(0, X_INFO, "lcdhdee 0x%x\n", tempbx);
7251 #endif
7252 #endif
7253
7254 tempbx += bridgeoffset;
7255
7256 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,tempbx); /* lcdhdee */
7257 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0xF0,((tempbx >> 8) & 0x0f));
7258
7259 tempcx = (tempcx - tempax) >> 2;
7260
7261 tempbx += tempcx;
7262 push2 = tempbx;
7263
7264 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7265 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7266 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
7267 if(SiS_Pr->SiS_HDE == 1280) tempbx = (tempbx & 0xff00) | 0x47;
7268 }
7269 }
7270 }
7271
7272 if(SiS_Pr->UseCustomMode) {
7273 tempbx = SiS_Pr->CHSyncStart;
7274 if(modeflag & HalfDCLK) tempbx <<= 1;
7275 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7276 tempbx += bridgeoffset;
7277 }
7278
7279 #ifdef SIS_XORG_XF86
7280 #ifdef TWDEBUG
7281 xf86DrvMsg(0, X_INFO, "lcdhrs 0x%x\n", tempbx);
7282 #endif
7283 #endif
7284
7285 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1C,tempbx); /* lcdhrs */
7286 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,((tempbx >> 4) & 0xf0));
7287
7288 tempbx = push2;
7289
7290 tempcx <<= 1;
7291 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7292 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) tempcx >>= 2;
7293 }
7294 tempbx += tempcx;
7295
7296 if(SiS_Pr->UseCustomMode) {
7297 tempbx = SiS_Pr->CHSyncEnd;
7298 if(modeflag & HalfDCLK) tempbx <<= 1;
7299 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7300 tempbx += bridgeoffset;
7301 }
7302
7303 #ifdef SIS_XORG_XF86
7304 #ifdef TWDEBUG
7305 xf86DrvMsg(0, X_INFO, "lcdhre 0x%x\n", tempbx);
7306 #endif
7307 #endif
7308
7309 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,tempbx); /* lcdhre */
7310
7311 SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7312
7313 #ifdef SIS300
7314 SiS_Set300Part2Regs(SiS_Pr, ModeIdIndex, RefreshRateTableIndex, ModeNo);
7315 #endif
7316 #ifdef SIS315H
7317 } /* CRT2-LCD from table */
7318 #endif
7319 }
7320
7321 /*********************************************/
7322 /* SET PART 3 REGISTER GROUP */
7323 /*********************************************/
7324
7325 static void
7326 SiS_SetGroup3(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7327 {
7328 unsigned short i;
7329 const unsigned char *tempdi;
7330
7331 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
7332
7333 #ifndef SIS_CP
7334 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x00,0x00);
7335 #else
7336 SIS_CP_INIT301_CP
7337 #endif
7338
7339 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7340 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7341 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7342 } else {
7343 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xF5);
7344 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xB7);
7345 }
7346
7347 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7348 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7349 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7350 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x3D,0xA8);
7351 }
7352
7353 tempdi = NULL;
7354 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7355 tempdi = SiS_Pr->SiS_HiTVGroup3Data;
7356 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
7357 tempdi = SiS_Pr->SiS_HiTVGroup3Simu;
7358 }
7359 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7360 if(!(SiS_Pr->SiS_TVMode & TVSetYPbPr525i)) {
7361 tempdi = SiS_HiTVGroup3_1;
7362 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempdi = SiS_HiTVGroup3_2;
7363 }
7364 }
7365 if(tempdi) {
7366 for(i=0; i<=0x3E; i++) {
7367 SiS_SetReg(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
7368 }
7369 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
7370 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
7371 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x28,0x3f);
7372 }
7373 }
7374 }
7375
7376 #ifdef SIS_CP
7377 SIS_CP_INIT301_CP2
7378 #endif
7379 }
7380
7381 /*********************************************/
7382 /* SET PART 4 REGISTER GROUP */
7383 /*********************************************/
7384
7385 #ifdef SIS315H
7386 #if 0
7387 static void
7388 SiS_ShiftXPos(struct SiS_Private *SiS_Pr, int shift)
7389 {
7390 unsigned short temp, temp1, temp2;
7391
7392 temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x1f);
7393 temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x20);
7394 temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7395 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,temp);
7396 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0f,((temp >> 4) & 0xf0));
7397 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x2b) & 0x0f;
7398 temp = (unsigned short)((int)(temp) + shift);
7399 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2b,0xf0,(temp & 0x0f));
7400 temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7401 temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x42);
7402 temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7403 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,temp);
7404 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x42,0x0f,((temp >> 4) & 0xf0));
7405 }
7406 #endif
7407
7408 static void
7409 SiS_SetGroup4_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7410 {
7411 unsigned short temp, temp1, resinfo = 0;
7412 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
7413
7414 if(!(SiS_Pr->SiS_VBType & VB_SIS30xCLV)) return;
7415 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToHiVision | SetCRT2ToYPbPr525750))) return;
7416
7417 if(SiS_Pr->ChipType >= XGI_20) return;
7418
7419 if((SiS_Pr->ChipType >= SIS_661) && (SiS_Pr->SiS_ROMNew)) {
7420 if(!(ROMAddr[0x61] & 0x04)) return;
7421 }
7422
7423 if(ModeNo > 0x13) {
7424 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
7425 }
7426
7427 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3a,0x08);
7428 temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x3a);
7429 if(!(temp & 0x01)) {
7430 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3a,0xdf);
7431 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xfc);
7432 if((SiS_Pr->ChipType < SIS_661) && (!(SiS_Pr->SiS_ROMNew))) {
7433 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xf8);
7434 }
7435 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0xfb);
7436 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp = 0x0000;
7437 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp = 0x0002;
7438 else if(SiS_Pr->SiS_TVMode & TVSetHiVision) temp = 0x0400;
7439 else temp = 0x0402;
7440 if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
7441 temp1 = 0;
7442 if(SiS_Pr->SiS_TVMode & TVAspect43) temp1 = 4;
7443 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0f,0xfb,temp1);
7444 if(SiS_Pr->SiS_TVMode & TVAspect43LB) temp |= 0x01;
7445 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0x7c,(temp & 0xff));
7446 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7447 if(ModeNo > 0x13) {
7448 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x39,0xfd);
7449 }
7450 } else {
7451 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x3b) & 0x03;
7452 if(temp1 == 0x01) temp |= 0x01;
7453 if(temp1 == 0x03) temp |= 0x04; /* ? why not 0x10? */
7454 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xf8,(temp & 0xff));
7455 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7456 if(ModeNo > 0x13) {
7457 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3b,0xfd);
7458 }
7459 }
7460
7461 #if 0
7462 if(SiS_Pr->ChipType >= SIS_661) { /* ? */
7463 if(SiS_Pr->SiS_TVMode & TVAspect43) {
7464 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
7465 if(resinfo == SIS_RI_1024x768) {
7466 SiS_ShiftXPos(SiS_Pr, 97);
7467 } else {
7468 SiS_ShiftXPos(SiS_Pr, 111);
7469 }
7470 } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
7471 SiS_ShiftXPos(SiS_Pr, 136);
7472 }
7473 }
7474 }
7475 #endif
7476
7477 }
7478
7479 }
7480 #endif
7481
7482 static void
7483 SiS_SetCRT2VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7484 unsigned short RefreshRateTableIndex)
7485 {
7486 unsigned short vclkindex, temp, reg1, reg2;
7487
7488 if(SiS_Pr->UseCustomMode) {
7489 reg1 = SiS_Pr->CSR2B;
7490 reg2 = SiS_Pr->CSR2C;
7491 } else {
7492 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
7493 reg1 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
7494 reg2 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
7495 }
7496
7497 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7498 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {
7499 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x57);
7500 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,0x46);
7501 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1f,0xf6);
7502 } else {
7503 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7504 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7505 }
7506 } else {
7507 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x01);
7508 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7509 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7510 }
7511 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x12,0x00);
7512 temp = 0x08;
7513 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) temp |= 0x20;
7514 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,temp);
7515 }
7516
7517 static void
7518 SiS_SetDualLinkEtc(struct SiS_Private *SiS_Pr)
7519 {
7520 if(SiS_Pr->ChipType >= SIS_315H) {
7521 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
7522 if((SiS_CRT2IsLCD(SiS_Pr)) ||
7523 (SiS_IsVAMode(SiS_Pr))) {
7524 if(SiS_Pr->SiS_LCDInfo & LCDDualLink) {
7525 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
7526 } else {
7527 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,~0x20);
7528 }
7529 }
7530 }
7531 }
7532 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
7533 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
7534 #ifdef SET_EMI
7535 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
7536 #endif
7537 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
7538 }
7539 }
7540
7541 static void
7542 SiS_SetGroup4(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7543 unsigned short RefreshRateTableIndex)
7544 {
7545 unsigned short tempax, tempcx, tempbx, modeflag, temp, resinfo;
7546 unsigned int tempebx, tempeax, templong;
7547
7548 if(ModeNo <= 0x13) {
7549 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7550 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
7551 } else if(SiS_Pr->UseCustomMode) {
7552 modeflag = SiS_Pr->CModeFlag;
7553 resinfo = 0;
7554 } else {
7555 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7556 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
7557 }
7558
7559 if(SiS_Pr->ChipType >= SIS_315H) {
7560 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
7561 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7562 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7563 }
7564 }
7565 }
7566
7567 if(SiS_Pr->SiS_VBType & (VB_SIS30xCLV | VB_SIS302LV)) {
7568 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7569 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x10,0x9f);
7570 }
7571 }
7572
7573 if(SiS_Pr->ChipType >= SIS_315H) {
7574 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7575 SiS_SetDualLinkEtc(SiS_Pr);
7576 return;
7577 }
7578 }
7579
7580 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x13,SiS_Pr->SiS_RVBHCFACT);
7581
7582 tempbx = SiS_Pr->SiS_RVBHCMAX;
7583 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x14,tempbx);
7584
7585 temp = (tempbx >> 1) & 0x80;
7586
7587 tempcx = SiS_Pr->SiS_VGAHT - 1;
7588 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x16,tempcx);
7589
7590 temp |= ((tempcx >> 5) & 0x78);
7591
7592 tempcx = SiS_Pr->SiS_VGAVT - 1;
7593 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempcx -= 5;
7594 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x17,tempcx);
7595
7596 temp |= ((tempcx >> 8) & 0x07);
7597 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x15,temp);
7598
7599 tempbx = SiS_Pr->SiS_VGAHDE;
7600 if(modeflag & HalfDCLK) tempbx >>= 1;
7601 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7602
7603 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7604 temp = 0;
7605 if(tempbx > 800) temp = 0x60;
7606 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7607 temp = 0;
7608 if(tempbx > 1024) temp = 0xC0;
7609 else if(tempbx >= 960) temp = 0xA0;
7610 } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
7611 temp = 0;
7612 if(tempbx >= 1280) temp = 0x40;
7613 else if(tempbx >= 1024) temp = 0x20;
7614 } else {
7615 temp = 0x80;
7616 if(tempbx >= 1024) temp = 0xA0;
7617 }
7618
7619 temp |= SiS_Pr->Init_P4_0E;
7620
7621 if(SiS_Pr->SiS_VBType & VB_SIS301) {
7622 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
7623 temp &= 0xf0;
7624 temp |= 0x0A;
7625 }
7626 }
7627
7628 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0E,0x10,temp);
7629
7630 tempeax = SiS_Pr->SiS_VGAVDE;
7631 tempebx = SiS_Pr->SiS_VDE;
7632 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7633 if(!(temp & 0xE0)) tempebx >>=1;
7634 }
7635
7636 tempcx = SiS_Pr->SiS_RVBHRS;
7637 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x18,tempcx);
7638 tempcx >>= 8;
7639 tempcx |= 0x40;
7640
7641 if(tempeax <= tempebx) {
7642 tempcx ^= 0x40;
7643 } else {
7644 tempeax -= tempebx;
7645 }
7646
7647 tempeax *= (256 * 1024);
7648 templong = tempeax % tempebx;
7649 tempeax /= tempebx;
7650 if(templong) tempeax++;
7651
7652 temp = (unsigned short)(tempeax & 0x000000FF);
7653 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1B,temp);
7654 temp = (unsigned short)((tempeax & 0x0000FF00) >> 8);
7655 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1A,temp);
7656 temp = (unsigned short)((tempeax >> 12) & 0x70); /* sic! */
7657 temp |= (tempcx & 0x4F);
7658 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x19,temp);
7659
7660 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7661
7662 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1C,0x28);
7663
7664 /* Calc Linebuffer max address and set/clear decimode */
7665 tempbx = 0;
7666 if(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p)) tempbx = 0x08;
7667 tempax = SiS_Pr->SiS_VGAHDE;
7668 if(modeflag & HalfDCLK) tempax >>= 1;
7669 if(SiS_IsDualLink(SiS_Pr)) tempax >>= 1;
7670 if(tempax > 800) {
7671 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7672 tempax -= 800;
7673 } else {
7674 tempbx = 0x08;
7675 if(tempax == 960) tempax *= 25; /* Correct */
7676 else if(tempax == 1024) tempax *= 25;
7677 else tempax *= 20;
7678 temp = tempax % 32;
7679 tempax /= 32;
7680 if(temp) tempax++;
7681 tempax++;
7682 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7683 if(resinfo == SIS_RI_1024x768 ||
7684 resinfo == SIS_RI_1024x576 ||
7685 resinfo == SIS_RI_1280x1024 ||
7686 resinfo == SIS_RI_1280x720) {
7687 /* Otherwise white line or garbage at right edge */
7688 tempax = (tempax & 0xff00) | 0x20;
7689 }
7690 }
7691 }
7692 }
7693 tempax--;
7694 temp = ((tempax >> 4) & 0x30) | tempbx;
7695 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1D,tempax);
7696 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1E,temp);
7697
7698 temp = 0x0036; tempbx = 0xD0;
7699 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
7700 temp = 0x0026; tempbx = 0xC0; /* See En/DisableBridge() */
7701 }
7702 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7703 if(!(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetHiVision | TVSetYPbPr750p | TVSetYPbPr525p))) {
7704 temp |= 0x01;
7705 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7706 if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
7707 temp &= ~0x01;
7708 }
7709 }
7710 }
7711 }
7712 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,tempbx,temp);
7713
7714 tempbx = SiS_Pr->SiS_HT >> 1;
7715 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7716 tempbx -= 2;
7717 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x22,tempbx);
7718 temp = (tempbx >> 5) & 0x38;
7719 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp);
7720
7721 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
7722 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7723 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7724 /* LCD-too-dark-error-source, see FinalizeLCD() */
7725 }
7726 }
7727
7728 SiS_SetDualLinkEtc(SiS_Pr);
7729
7730 } /* 301B */
7731
7732 SiS_SetCRT2VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
7733 }
7734
7735 /*********************************************/
7736 /* SET PART 5 REGISTER GROUP */
7737 /*********************************************/
7738
7739 static void
7740 SiS_SetGroup5(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7741 {
7742
7743 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
7744
7745 if(SiS_Pr->SiS_ModeType == ModeVGA) {
7746 if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))) {
7747 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
7748 SiS_LoadDAC(SiS_Pr, ModeNo, ModeIdIndex);
7749 }
7750 }
7751 }
7752
7753 /*********************************************/
7754 /* MODIFY CRT1 GROUP FOR SLAVE MODE */
7755 /*********************************************/
7756
7757 static bool
7758 SiS_GetLVDSCRT1Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7759 unsigned short RefreshRateTableIndex, unsigned short *ResIndex,
7760 unsigned short *DisplayType)
7761 {
7762 unsigned short modeflag = 0;
7763 bool checkhd = true;
7764
7765 /* Pass 1:1 not supported here */
7766
7767 if(ModeNo <= 0x13) {
7768 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7769 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
7770 } else {
7771 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7772 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
7773 }
7774
7775 (*ResIndex) &= 0x3F;
7776
7777 if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
7778
7779 (*DisplayType) = 80;
7780 if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
7781 (*DisplayType) = 82;
7782 if(SiS_Pr->SiS_ModeType > ModeVGA) {
7783 if(SiS_Pr->SiS_CHSOverScan) (*DisplayType) = 84;
7784 }
7785 }
7786 if((*DisplayType) != 84) {
7787 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
7788 }
7789
7790 } else {
7791
7792 (*DisplayType = 0);
7793 switch(SiS_Pr->SiS_LCDResInfo) {
7794 case Panel_320x240_1: (*DisplayType) = 50;
7795 checkhd = false;
7796 break;
7797 case Panel_320x240_2: (*DisplayType) = 14;
7798 break;
7799 case Panel_320x240_3: (*DisplayType) = 18;
7800 break;
7801 case Panel_640x480: (*DisplayType) = 10;
7802 break;
7803 case Panel_1024x600: (*DisplayType) = 26;
7804 break;
7805 default: return true;
7806 }
7807
7808 if(checkhd) {
7809 if(modeflag & HalfDCLK) (*DisplayType)++;
7810 }
7811
7812 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
7813 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) (*DisplayType) += 2;
7814 }
7815
7816 }
7817
7818 return true;
7819 }
7820
7821 static void
7822 SiS_ModCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7823 unsigned short RefreshRateTableIndex)
7824 {
7825 unsigned short tempah, i, modeflag, j, ResIndex, DisplayType;
7826 const struct SiS_LVDSCRT1Data *LVDSCRT1Ptr=NULL;
7827 static const unsigned short CRIdx[] = {
7828 0x00, 0x02, 0x03, 0x04, 0x05, 0x06,
7829 0x07, 0x10, 0x11, 0x15, 0x16
7830 };
7831
7832 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
7833 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
7834 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
7835 (SiS_Pr->SiS_CustomT == CUT_PANEL856) )
7836 return;
7837
7838 if(SiS_Pr->SiS_IF_DEF_LVDS) {
7839 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
7840 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;
7841 }
7842 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
7843 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;
7844 } else return;
7845
7846 if(SiS_Pr->SiS_LCDInfo & LCDPass11) return;
7847
7848 if(SiS_Pr->ChipType < SIS_315H) {
7849 if(SiS_Pr->SiS_SetFlag & SetDOSMode) return;
7850 }
7851
7852 if(!(SiS_GetLVDSCRT1Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7853 &ResIndex, &DisplayType))) {
7854 return;
7855 }
7856
7857 switch(DisplayType) {
7858 case 50: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_1; break; /* xSTN */
7859 case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2; break; /* xSTN */
7860 case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2_H; break; /* xSTN */
7861 case 18: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3; break; /* xSTN */
7862 case 19: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3_H; break; /* xSTN */
7863 case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1; break;
7864 case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1_H; break;
7865 #if 0 /* Works better with calculated numbers */
7866 case 26: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1; break;
7867 case 27: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1_H; break;
7868 case 28: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2; break;
7869 case 29: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2_H; break;
7870 #endif
7871 case 80: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC; break;
7872 case 81: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC; break;
7873 case 82: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL; break;
7874 case 83: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL; break;
7875 case 84: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1SOPAL; break;
7876 }
7877
7878 if(LVDSCRT1Ptr) {
7879
7880 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
7881
7882 for(i = 0; i <= 10; i++) {
7883 tempah = (LVDSCRT1Ptr + ResIndex)->CR[i];
7884 SiS_SetReg(SiS_Pr->SiS_P3d4,CRIdx[i],tempah);
7885 }
7886
7887 for(i = 0x0A, j = 11; i <= 0x0C; i++, j++) {
7888 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
7889 SiS_SetReg(SiS_Pr->SiS_P3c4,i,tempah);
7890 }
7891
7892 tempah = (LVDSCRT1Ptr + ResIndex)->CR[14] & 0xE0;
7893 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);
7894
7895 if(ModeNo <= 0x13) modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7896 else modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7897
7898 tempah = ((LVDSCRT1Ptr + ResIndex)->CR[14] & 0x01) << 5;
7899 if(modeflag & DoubleScanMode) tempah |= 0x80;
7900 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
7901
7902 } else {
7903
7904 SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
7905
7906 }
7907 }
7908
7909 /*********************************************/
7910 /* SET CRT2 ECLK */
7911 /*********************************************/
7912
7913 static void
7914 SiS_SetCRT2ECLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7915 unsigned short RefreshRateTableIndex)
7916 {
7917 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
7918 unsigned short clkbase, vclkindex = 0;
7919 unsigned char sr2b, sr2c;
7920
7921 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
7922 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
7923 if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK == 2) {
7924 RefreshRateTableIndex--;
7925 }
7926 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
7927 RefreshRateTableIndex);
7928 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
7929 } else {
7930 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
7931 RefreshRateTableIndex);
7932 }
7933
7934 sr2b = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
7935 sr2c = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
7936
7937 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
7938 if(SiS_Pr->SiS_UseROM) {
7939 if(ROMAddr[0x220] & 0x01) {
7940 sr2b = ROMAddr[0x227];
7941 sr2c = ROMAddr[0x228];
7942 }
7943 }
7944 }
7945
7946 clkbase = 0x02B;
7947 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
7948 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
7949 clkbase += 3;
7950 }
7951 }
7952
7953 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x20);
7954 SiS_SetReg