aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/sis/init301.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/video/sis/init301.c
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'drivers/video/sis/init301.c')
-rw-r--r--drivers/video/sis/init301.c12239
1 files changed, 12239 insertions, 0 deletions
diff --git a/drivers/video/sis/init301.c b/drivers/video/sis/init301.c
new file mode 100644
index 000000000000..2bc5b8097910
--- /dev/null
+++ b/drivers/video/sis/init301.c
@@ -0,0 +1,12239 @@
1/* $XFree86$ */
2/* $XdotOrg$ */
3/*
4 * Mode initializing code (CRT2 section)
5 * for SiS 300/305/540/630/730 and
6 * SiS 315/550/650/M650/651/661FX/M661xX/740/741(GX)/M741/330/660/M660/760/M760
7 * (Universal module for Linux kernel framebuffer and XFree86/X.org 4.x)
8 *
9 * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
10 *
11 * If distributed as part of the Linux kernel, the following license terms
12 * apply:
13 *
14 * * This program is free software; you can redistribute it and/or modify
15 * * it under the terms of the GNU General Public License as published by
16 * * the Free Software Foundation; either version 2 of the named License,
17 * * or any later version.
18 * *
19 * * This program is distributed in the hope that it will be useful,
20 * * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * * GNU General Public License for more details.
23 * *
24 * * You should have received a copy of the GNU General Public License
25 * * along with this program; if not, write to the Free Software
26 * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
27 *
28 * Otherwise, the following license terms apply:
29 *
30 * * Redistribution and use in source and binary forms, with or without
31 * * modification, are permitted provided that the following conditions
32 * * are met:
33 * * 1) Redistributions of source code must retain the above copyright
34 * * notice, this list of conditions and the following disclaimer.
35 * * 2) Redistributions in binary form must reproduce the above copyright
36 * * notice, this list of conditions and the following disclaimer in the
37 * * documentation and/or other materials provided with the distribution.
38 * * 3) The name of the author may not be used to endorse or promote products
39 * * derived from this software without specific prior written permission.
40 * *
41 * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
42 * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
43 * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
44 * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
45 * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46 * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
47 * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
48 * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
49 * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
50 * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51 *
52 * Author: Thomas Winischhofer <thomas@winischhofer.net>
53 *
54 * Formerly based on non-functional code-fragements for 300 series by SiS, Inc.
55 * Used by permission.
56 *
57 * TW says: This code looks awful, I know. But please don't do anything about
58 * this otherwise debugging will be hell.
59 * The code is extremely fragile as regards the different chipsets, different
60 * video bridges and combinations thereof. If anything is changed, extreme
61 * care has to be taken that that change doesn't break it for other chipsets,
62 * bridges or combinations thereof.
63 * All comments in this file are by me, regardless if marked TW or not.
64 *
65 */
66
67#if 1
68#define SET_EMI /* 302LV/ELV: Set EMI values */
69#endif
70
71#define COMPAL_HACK /* Needed for Compal 1400x1050 (EMI) */
72#define COMPAQ_HACK /* Needed for Inventec/Compaq 1280x1024 (EMI) */
73#define ASUS_HACK /* Needed for Asus A2H 1024x768 (EMI) */
74
75#include "init301.h"
76
77#ifdef SIS300
78#include "oem300.h"
79#endif
80
81#ifdef SIS315H
82#include "oem310.h"
83#endif
84
85#define SiS_I2CDELAY 1000
86#define SiS_I2CDELAYSHORT 150
87
88static USHORT SiS_GetBIOSLCDResInfo(SiS_Private *SiS_Pr);
89
90/*********************************************/
91/* HELPER: Lock/Unlock CRT2 */
92/*********************************************/
93
94void
95SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
96{
97 if(HwInfo->jChipType >= SIS_315H)
98 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
99 else
100 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
101}
102
103void
104SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
105{
106 if(HwInfo->jChipType >= SIS_315H)
107 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
108 else
109 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
110}
111
112/*********************************************/
113/* HELPER: Write SR11 */
114/*********************************************/
115
116static void
117SiS_SetRegSR11ANDOR(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT DataAND, USHORT DataOR)
118{
119 if(HwInfo->jChipType >= SIS_661) {
120 DataAND &= 0x0f;
121 DataOR &= 0x0f;
122 }
123 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,DataAND,DataOR);
124}
125
126/*********************************************/
127/* HELPER: Get Pointer to LCD structure */
128/*********************************************/
129
130#ifdef SIS315H
131static UCHAR *
132GetLCDStructPtr661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
133{
134 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
135 UCHAR *myptr = NULL;
136 USHORT romindex = 0, reg = 0, idx = 0;
137
138 /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
139 * due to the variaty of panels the BIOS doesn't know about.
140 * Exception: If the BIOS has better knowledge (such as in case
141 * of machines with a 301C and a panel that does not support DDC)
142 * use the BIOS data as well.
143 */
144
145 if((SiS_Pr->SiS_ROMNew) &&
146 ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) || (!SiS_Pr->PanelSelfDetected))) {
147
148 if(HwInfo->jChipType < SIS_661) reg = 0x3c;
149 else reg = 0x7d;
150
151 idx = (SiS_GetReg(SiS_Pr->SiS_P3d4,reg) & 0x1f) * 26;
152
153 if(idx < (8*26)) {
154 myptr = (UCHAR *)&SiS_LCDStruct661[idx];
155 }
156 romindex = SISGETROMW(0x100);
157 if(romindex) {
158 romindex += idx;
159 myptr = &ROMAddr[romindex];
160 }
161 }
162 return myptr;
163}
164
165static USHORT
166GetLCDStructPtr661_2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
167{
168 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
169 USHORT romptr = 0;
170
171 /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
172 * due to the variaty of panels the BIOS doesn't know about.
173 * Exception: If the BIOS has better knowledge (such as in case
174 * of machines with a 301C and a panel that does not support DDC)
175 * use the BIOS data as well.
176 */
177
178 if((SiS_Pr->SiS_ROMNew) &&
179 ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) || (!SiS_Pr->PanelSelfDetected))) {
180 romptr = SISGETROMW(0x102);
181 romptr += ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) * SiS_Pr->SiS661LCD2TableSize);
182 }
183
184 return(romptr);
185}
186#endif
187
188/*********************************************/
189/* Adjust Rate for CRT2 */
190/*********************************************/
191
192static BOOLEAN
193SiS_AdjustCRT2Rate(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
194 USHORT RRTI, USHORT *i, PSIS_HW_INFO HwInfo)
195{
196 USHORT checkmask=0,modeid,infoflag;
197
198 modeid = SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID;
199
200 if(SiS_Pr->SiS_VBType & VB_SISVB) {
201
202 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
203
204 checkmask |= SupportRAMDAC2;
205 if(HwInfo->jChipType >= SIS_315H) {
206 checkmask |= SupportRAMDAC2_135;
207 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
208 checkmask |= SupportRAMDAC2_162;
209 if(SiS_Pr->SiS_VBType & VB_SIS301C) {
210 checkmask |= SupportRAMDAC2_202;
211 }
212 }
213 }
214
215 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
216
217 checkmask |= SupportLCD;
218 if(HwInfo->jChipType >= SIS_315H) {
219 if(SiS_Pr->SiS_VBType & VB_SISVB) {
220 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
221 if(modeid == 0x2e) checkmask |= Support64048060Hz;
222 }
223 }
224 }
225
226 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
227
228 checkmask |= SupportHiVision;
229
230 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750|SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
231
232 checkmask |= SupportTV;
233 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
234 checkmask |= SupportTV1024;
235 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
236 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
237 checkmask |= SupportYPbPr750p;
238 }
239 }
240 }
241
242 }
243
244 } else { /* LVDS */
245
246 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
247 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
248 checkmask |= SupportCHTV;
249 }
250 }
251
252 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
253 checkmask |= SupportLCD;
254 }
255
256 }
257
258 /* Look backwards in table for matching CRT2 mode */
259 for(; SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID == modeid; (*i)--) {
260 infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
261 if(infoflag & checkmask) return TRUE;
262 if((*i) == 0) break;
263 }
264
265 /* Look through the whole mode-section of the table from the beginning
266 * for a matching CRT2 mode if no mode was found yet.
267 */
268 for((*i) = 0; ; (*i)++) {
269 if(SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID != modeid) break;
270 infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
271 if(infoflag & checkmask) return TRUE;
272 }
273 return FALSE;
274}
275
276/*********************************************/
277/* Get rate index */
278/*********************************************/
279
280USHORT
281SiS_GetRatePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
282 PSIS_HW_INFO HwInfo)
283{
284 SHORT LCDRefreshIndex[] = { 0x00, 0x00, 0x01, 0x01,
285 0x01, 0x01, 0x01, 0x01,
286 0x01, 0x01, 0x01, 0x01,
287 0x01, 0x01, 0x01, 0x01,
288 0x00, 0x00, 0x00, 0x00 };
289 USHORT RRTI,i,backup_i;
290 USHORT modeflag,index,temp,backupindex;
291
292 /* Do NOT check for UseCustomMode here, will skrew up FIFO */
293 if(ModeNo == 0xfe) return 0;
294
295 if(ModeNo <= 0x13) {
296 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
297 } else {
298 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
299 }
300
301 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
302 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
303 if(modeflag & HalfDCLK) return 0;
304 }
305 }
306
307 if(ModeNo < 0x14) return 0xFFFF;
308
309 index = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x33) >> SiS_Pr->SiS_SelectCRT2Rate) & 0x0F;
310 backupindex = index;
311
312 if(index > 0) index--;
313
314 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
315 if(SiS_Pr->SiS_VBType & VB_SISVB) {
316 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
317 if(SiS_Pr->SiS_VBType & VB_NoLCD) index = 0;
318 else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index = backupindex = 0;
319 }
320 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
321 if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) {
322 temp = LCDRefreshIndex[SiS_GetBIOSLCDResInfo(SiS_Pr)];
323 if(index > temp) index = temp;
324 }
325 }
326 } else {
327 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) index = 0;
328 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
329 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) index = 0;
330 }
331 }
332 }
333
334 RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
335 ModeNo = SiS_Pr->SiS_RefIndex[RRTI].ModeID;
336
337 if(HwInfo->jChipType >= SIS_315H) {
338 if(!(SiS_Pr->SiS_VBInfo & DriverMode)) {
339 if( (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x105) ||
340 (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x107) ) {
341 if(backupindex <= 1) RRTI++;
342 }
343 }
344 }
345
346 i = 0;
347 do {
348 if(SiS_Pr->SiS_RefIndex[RRTI + i].ModeID != ModeNo) break;
349 temp = SiS_Pr->SiS_RefIndex[RRTI + i].Ext_InfoFlag;
350 temp &= ModeTypeMask;
351 if(temp < SiS_Pr->SiS_ModeType) break;
352 i++;
353 index--;
354 } while(index != 0xFFFF);
355
356 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
357 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
358 temp = SiS_Pr->SiS_RefIndex[RRTI + i - 1].Ext_InfoFlag;
359 if(temp & InterlaceMode) i++;
360 }
361 }
362
363 i--;
364
365 if((SiS_Pr->SiS_SetFlag & ProgrammingCRT2) && (!(SiS_Pr->SiS_VBInfo & DisableCRT2Display))) {
366 backup_i = i;
367 if(!(SiS_AdjustCRT2Rate(SiS_Pr, ModeNo, ModeIdIndex, RRTI, &i, HwInfo))) {
368 i = backup_i;
369 }
370 }
371
372 return(RRTI + i);
373}
374
375/*********************************************/
376/* STORE CRT2 INFO in CR34 */
377/*********************************************/
378
379static void
380SiS_SaveCRT2Info(SiS_Private *SiS_Pr, USHORT ModeNo)
381{
382 USHORT temp1,temp2;
383
384 /* Store CRT1 ModeNo in CR34 */
385 SiS_SetReg(SiS_Pr->SiS_P3d4,0x34,ModeNo);
386 temp1 = (SiS_Pr->SiS_VBInfo & SetInSlaveMode) >> 8;
387 temp2 = ~(SetInSlaveMode >> 8);
388 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x31,temp2,temp1);
389}
390
391/*********************************************/
392/* HELPER: GET SOME DATA FROM BIOS ROM */
393/*********************************************/
394
395#ifdef SIS300
396static BOOLEAN
397SiS_CR36BIOSWord23b(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
398{
399 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
400 USHORT temp,temp1;
401
402 if(SiS_Pr->SiS_UseROM) {
403 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
404 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
405 temp1 = SISGETROMW(0x23b);
406 if(temp1 & temp) return TRUE;
407 }
408 }
409 return FALSE;
410}
411
412static BOOLEAN
413SiS_CR36BIOSWord23d(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
414{
415 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
416 USHORT temp,temp1;
417
418 if(SiS_Pr->SiS_UseROM) {
419 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
420 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
421 temp1 = SISGETROMW(0x23d);
422 if(temp1 & temp) return TRUE;
423 }
424 }
425 return FALSE;
426}
427#endif
428
429/*********************************************/
430/* HELPER: DELAY FUNCTIONS */
431/*********************************************/
432
433void
434SiS_DDC2Delay(SiS_Private *SiS_Pr, USHORT delaytime)
435{
436 USHORT i, j;
437
438 for(i=0; i<delaytime; i++) {
439 j += SiS_GetReg(SiS_Pr->SiS_P3c4,0x05);
440 }
441}
442
443#if defined(SIS300) || defined(SIS315H)
444static void
445SiS_GenericDelay(SiS_Private *SiS_Pr, USHORT delay)
446{
447 USHORT temp,flag;
448
449 flag = SiS_GetRegByte(0x61) & 0x10;
450
451 while(delay) {
452 temp = SiS_GetRegByte(0x61) & 0x10;
453 if(temp == flag) continue;
454 flag = temp;
455 delay--;
456 }
457}
458#endif
459
460#ifdef SIS315H
461static void
462SiS_LongDelay(SiS_Private *SiS_Pr, USHORT delay)
463{
464 while(delay--) {
465 SiS_GenericDelay(SiS_Pr,0x19df);
466 }
467}
468#endif
469
470#if defined(SIS300) || defined(SIS315H)
471static void
472SiS_ShortDelay(SiS_Private *SiS_Pr, USHORT delay)
473{
474 while(delay--) {
475 SiS_GenericDelay(SiS_Pr,0x42);
476 }
477}
478#endif
479
480static void
481SiS_PanelDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT DelayTime)
482{
483#if defined(SIS300) || defined(SIS315H)
484 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
485 USHORT PanelID, DelayIndex, Delay=0;
486#endif
487
488 if(HwInfo->jChipType < 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 = (USHORT)ROMAddr[0x225];
510 else Delay = (USHORT)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((HwInfo->jChipType >= SIS_661) ||
523 (HwInfo->jChipType <= SIS_315PRO) ||
524 (HwInfo->jChipType == 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 = (USHORT)ROMAddr[0x17e];
560 } else {
561 Delay = (USHORT)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
588static void
589SiS_PanelDelayLoop(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
590 USHORT DelayTime, USHORT DelayLoop)
591{
592 int i;
593 for(i=0; i<DelayLoop; i++) {
594 SiS_PanelDelay(SiS_Pr, HwInfo, DelayTime);
595 }
596}
597#endif
598
599/*********************************************/
600/* HELPER: WAIT-FOR-RETRACE FUNCTIONS */
601/*********************************************/
602
603void
604SiS_WaitRetrace1(SiS_Private *SiS_Pr)
605{
606 USHORT watchdog;
607
608 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
609 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80)) return;
610
611 watchdog = 65535;
612 while((SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
613 watchdog = 65535;
614 while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
615}
616
617#if defined(SIS300) || defined(SIS315H)
618static void
619SiS_WaitRetrace2(SiS_Private *SiS_Pr, USHORT reg)
620{
621 USHORT watchdog;
622
623 watchdog = 65535;
624 while((SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02) && --watchdog);
625 watchdog = 65535;
626 while((!(SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02)) && --watchdog);
627}
628#endif
629
630static void
631SiS_WaitVBRetrace(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
632{
633 if(HwInfo->jChipType < SIS_315H) {
634#ifdef SIS300
635 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
636 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return;
637 }
638 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x80)) {
639 SiS_WaitRetrace1(SiS_Pr);
640 } else {
641 SiS_WaitRetrace2(SiS_Pr, 0x25);
642 }
643#endif
644 } else {
645#ifdef SIS315H
646 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) {
647 SiS_WaitRetrace1(SiS_Pr);
648 } else {
649 SiS_WaitRetrace2(SiS_Pr, 0x30);
650 }
651#endif
652 }
653}
654
655static void
656SiS_VBWait(SiS_Private *SiS_Pr)
657{
658 USHORT tempal,temp,i,j;
659
660 temp = 0;
661 for(i=0; i<3; i++) {
662 for(j=0; j<100; j++) {
663 tempal = SiS_GetRegByte(SiS_Pr->SiS_P3da);
664 if(temp & 0x01) {
665 if((tempal & 0x08)) continue;
666 else break;
667 } else {
668 if(!(tempal & 0x08)) continue;
669 else break;
670 }
671 }
672 temp ^= 0x01;
673 }
674}
675
676static void
677SiS_VBLongWait(SiS_Private *SiS_Pr)
678{
679 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
680 SiS_VBWait(SiS_Pr);
681 } else {
682 SiS_WaitRetrace1(SiS_Pr);
683 }
684}
685
686/*********************************************/
687/* HELPER: MISC */
688/*********************************************/
689
690#ifdef SIS300
691static BOOLEAN
692SiS_Is301B(SiS_Private *SiS_Pr)
693{
694 if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01) >= 0xb0) return TRUE;
695 return FALSE;
696}
697#endif
698
699static BOOLEAN
700SiS_CRT2IsLCD(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
701{
702 USHORT flag;
703
704 if(HwInfo->jChipType == SIS_730) {
705 flag = SiS_GetReg(SiS_Pr->SiS_P3c4,0x13);
706 if(flag & 0x20) return TRUE;
707 }
708 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
709 if(flag & 0x20) return TRUE;
710 return FALSE;
711}
712
713BOOLEAN
714SiS_IsDualEdge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
715{
716#ifdef SIS315H
717 USHORT flag;
718
719 if(HwInfo->jChipType >= SIS_315H) {
720 if((HwInfo->jChipType != SIS_650) || (SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) {
721 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
722 if(flag & EnableDualEdge) return TRUE;
723 }
724 }
725#endif
726 return FALSE;
727}
728
729BOOLEAN
730SiS_IsVAMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
731{
732#ifdef SIS315H
733 USHORT flag;
734
735 if(HwInfo->jChipType >= SIS_315H) {
736 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
737 if((flag & EnableDualEdge) && (flag & SetToLCDA)) return TRUE;
738 }
739#endif
740 return FALSE;
741}
742
743#ifdef SIS315H
744static BOOLEAN
745SiS_IsVAorLCD(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
746{
747 if(SiS_IsVAMode(SiS_Pr,HwInfo)) return TRUE;
748 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) return TRUE;
749 return FALSE;
750}
751#endif
752
753static BOOLEAN
754SiS_IsDualLink(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
755{
756#ifdef SIS315H
757 if(HwInfo->jChipType >= SIS_315H) {
758 if((SiS_CRT2IsLCD(SiS_Pr, HwInfo)) ||
759 (SiS_IsVAMode(SiS_Pr, HwInfo))) {
760 if(SiS_Pr->SiS_LCDInfo & LCDDualLink) return TRUE;
761 }
762 }
763#endif
764 return FALSE;
765}
766
767#ifdef SIS315H
768static BOOLEAN
769SiS_TVEnabled(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
770{
771 if((SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) != 0x0c) return TRUE;
772 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS301LV302LV)) {
773 if(SiS_GetReg(SiS_Pr->SiS_Part2Port,0x4d) & 0x10) return TRUE;
774 }
775 return FALSE;
776}
777#endif
778
779#ifdef SIS315H
780static BOOLEAN
781SiS_LCDAEnabled(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
782{
783 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) return TRUE;
784 return FALSE;
785}
786#endif
787
788#ifdef SIS315H
789static BOOLEAN
790SiS_WeHaveBacklightCtrl(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
791{
792 if((HwInfo->jChipType >= SIS_315H) && (HwInfo->jChipType < SIS_661)) {
793 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0x10) return TRUE;
794 }
795 return FALSE;
796}
797#endif
798
799#ifdef SIS315H
800static BOOLEAN
801SiS_IsNotM650orLater(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
802{
803 USHORT flag;
804
805 if(HwInfo->jChipType == SIS_650) {
806 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f);
807 flag &= 0xF0;
808 /* Check for revision != A0 only */
809 if((flag == 0xe0) || (flag == 0xc0) ||
810 (flag == 0xb0) || (flag == 0x90)) return FALSE;
811 } else if(HwInfo->jChipType >= SIS_661) return FALSE;
812 return TRUE;
813}
814#endif
815
816#ifdef SIS315H
817static BOOLEAN
818SiS_IsYPbPr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
819{
820 USHORT flag;
821
822 if(HwInfo->jChipType >= SIS_315H) {
823 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
824 if(flag & EnableCHYPbPr) return TRUE; /* = YPrPb = 0x08 */
825 }
826 return FALSE;
827}
828#endif
829
830#ifdef SIS315H
831static BOOLEAN
832SiS_IsChScart(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
833{
834 USHORT flag;
835
836 if(HwInfo->jChipType >= SIS_315H) {
837 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
838 if(flag & EnableCHScart) return TRUE; /* = Scart = 0x04 */
839 }
840 return FALSE;
841}
842#endif
843
844#ifdef SIS315H
845static BOOLEAN
846SiS_IsTVOrYPbPrOrScart(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
847{
848 USHORT flag;
849
850 if(HwInfo->jChipType >= SIS_315H) {
851 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
852 if(flag & SetCRT2ToTV) return TRUE;
853 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
854 if(flag & EnableCHYPbPr) return TRUE; /* = YPrPb = 0x08 */
855 if(flag & EnableCHScart) return TRUE; /* = Scart = 0x04 - TW */
856 } else {
857 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
858 if(flag & SetCRT2ToTV) return TRUE;
859 }
860 return FALSE;
861}
862#endif
863
864#ifdef SIS315H
865static BOOLEAN
866SiS_IsLCDOrLCDA(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
867{
868 USHORT flag;
869
870 if(HwInfo->jChipType >= SIS_315H) {
871 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
872 if(flag & SetCRT2ToLCD) return TRUE;
873 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
874 if(flag & SetToLCDA) return TRUE;
875 } else {
876 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
877 if(flag & SetCRT2ToLCD) return TRUE;
878 }
879 return FALSE;
880}
881#endif
882
883static BOOLEAN
884SiS_BridgeIsOn(SiS_Private *SiS_Pr)
885{
886 USHORT flag;
887
888 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
889 return TRUE;
890 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
891 flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
892 if((flag == 1) || (flag == 2)) return TRUE;
893 }
894 return FALSE;
895}
896
897static BOOLEAN
898SiS_BridgeIsEnabled(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
899{
900 USHORT flag;
901
902 if(SiS_BridgeIsOn(SiS_Pr)) {
903 flag = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
904 if(HwInfo->jChipType < SIS_315H) {
905 flag &= 0xa0;
906 if((flag == 0x80) || (flag == 0x20)) return TRUE;
907 } else {
908 flag &= 0x50;
909 if((flag == 0x40) || (flag == 0x10)) return TRUE;
910 }
911 }
912 return FALSE;
913}
914
915static BOOLEAN
916SiS_BridgeInSlavemode(SiS_Private *SiS_Pr)
917{
918 USHORT flag1;
919
920 flag1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
921 if(flag1 & (SetInSlaveMode >> 8)) return TRUE;
922 return FALSE;
923}
924
925/*********************************************/
926/* GET VIDEO BRIDGE CONFIG INFO */
927/*********************************************/
928
929/* Setup general purpose IO for Chrontel communication */
930void
931SiS_SetChrontelGPIO(SiS_Private *SiS_Pr, USHORT myvbinfo)
932{
933 unsigned long acpibase;
934 unsigned short temp;
935
936 if(!(SiS_Pr->SiS_ChSW)) return;
937
938#ifdef LINUX_KERNEL
939 SiS_SetRegLong(0xcf8,0x80000874); /* get ACPI base */
940 acpibase = SiS_GetRegLong(0xcfc);
941#else
942 acpibase = pciReadLong(0x00000800, 0x74);
943#endif
944 acpibase &= 0xFFFF;
945 temp = SiS_GetRegShort((USHORT)(acpibase + 0x3c)); /* ACPI register 0x3c: GP Event 1 I/O mode select */
946 temp &= 0xFEFF;
947 SiS_SetRegShort((USHORT)(acpibase + 0x3c), temp);
948 temp = SiS_GetRegShort((USHORT)(acpibase + 0x3c));
949 temp = SiS_GetRegShort((USHORT)(acpibase + 0x3a)); /* ACPI register 0x3a: GP Pin Level (low/high) */
950 temp &= 0xFEFF;
951 if(!(myvbinfo & SetCRT2ToTV)) temp |= 0x0100;
952 SiS_SetRegShort((USHORT)(acpibase + 0x3a), temp);
953 temp = SiS_GetRegShort((USHORT)(acpibase + 0x3a));
954}
955
956void
957SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
958 PSIS_HW_INFO HwInfo, int checkcrt2mode)
959{
960 USHORT tempax,tempbx,temp;
961 USHORT modeflag, resinfo=0;
962
963 if(ModeNo <= 0x13) {
964 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
965 } else if(SiS_Pr->UseCustomMode) {
966 modeflag = SiS_Pr->CModeFlag;
967 } else {
968 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
969 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
970 }
971
972 SiS_Pr->SiS_SetFlag = 0;
973
974 SiS_Pr->SiS_ModeType = modeflag & ModeTypeMask;
975
976 tempbx = 0;
977 if(SiS_BridgeIsOn(SiS_Pr)) {
978 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
979#if 0
980 if(HwInfo->jChipType < SIS_661) {
981 /* NO - YPbPr not set yet ! */
982 if(SiS_Pr->SiS_YPbPr & <all ypbpr except 525i>) {
983 temp &= (SetCRT2ToHiVision | SwitchCRT2 | SetSimuScanMode); /* 0x83 */
984 temp |= SetCRT2ToHiVision; /* 0x80 */
985 }
986 if(SiS_Pr->SiS_YPbPr & <ypbpr525i>) {
987 temp &= (SetCRT2ToHiVision | SwitchCRT2 | SetSimuScanMode); /* 0x83 */
988 temp |= SetCRT2ToSVIDEO; /* 0x08 */
989 }
990 }
991#endif
992 tempbx |= temp;
993 tempax = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) << 8;
994 tempax &= (DriverMode | LoadDACFlag | SetNotSimuMode | SetPALTV);
995 tempbx |= tempax;
996
997#ifdef SIS315H
998 if(HwInfo->jChipType >= SIS_315H) {
999 if(SiS_Pr->SiS_VBType & VB_SISLCDA) {
1000 if(ModeNo == 0x03) {
1001 /* Mode 0x03 is never in driver mode */
1002 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf);
1003 }
1004 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8))) {
1005 /* Reset LCDA setting if not driver mode */
1006 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
1007 }
1008 if(IS_SIS650) {
1009 if(SiS_Pr->SiS_UseLCDA) {
1010 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) {
1011 if((ModeNo <= 0x13) || (!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) {
1012 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA));
1013 }
1014 }
1015 }
1016 }
1017 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1018 if((temp & (EnableDualEdge | SetToLCDA)) == (EnableDualEdge | SetToLCDA)) {
1019 tempbx |= SetCRT2ToLCDA;
1020 }
1021 }
1022
1023 if(SiS_Pr->SiS_VBType & (VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)) {
1024 tempbx &= ~(SetCRT2ToRAMDAC);
1025 }
1026
1027 if(HwInfo->jChipType >= SIS_661) {
1028 tempbx &= ~(SetCRT2ToYPbPr525750 | SetCRT2ToHiVision);
1029 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1030 if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1031 if(temp & 0x04) {
1032 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
1033 if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
1034 else tempbx |= SetCRT2ToYPbPr525750;
1035 }
1036 } else if(SiS_Pr->SiS_VBType & VB_SISHIVISION) {
1037 if(temp & 0x04) {
1038 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
1039 if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
1040 }
1041 }
1042 }
1043
1044 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1045 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1046 if(temp & SetToLCDA) {
1047 tempbx |= SetCRT2ToLCDA;
1048 }
1049 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1050 if(temp & EnableCHYPbPr) {
1051 tempbx |= SetCRT2ToCHYPbPr;
1052 }
1053 }
1054 }
1055 }
1056
1057#endif /* SIS315H */
1058
1059 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1060 temp = SetCRT2ToSVIDEO |
1061 SetCRT2ToAVIDEO |
1062 SetCRT2ToSCART |
1063 SetCRT2ToLCDA |
1064 SetCRT2ToLCD |
1065 SetCRT2ToRAMDAC |
1066 SetCRT2ToHiVision |
1067 SetCRT2ToYPbPr525750;
1068 } else {
1069 if(HwInfo->jChipType >= SIS_315H) {
1070 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1071 temp = SetCRT2ToAVIDEO |
1072 SetCRT2ToSVIDEO |
1073 SetCRT2ToSCART |
1074 SetCRT2ToLCDA |
1075 SetCRT2ToLCD |
1076 SetCRT2ToCHYPbPr;
1077 } else {
1078 temp = SetCRT2ToLCDA |
1079 SetCRT2ToLCD;
1080 }
1081 } else {
1082 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1083 temp = SetCRT2ToTV | SetCRT2ToLCD;
1084 } else {
1085 temp = SetCRT2ToLCD;
1086 }
1087 }
1088 }
1089
1090 if(!(tempbx & temp)) {
1091 tempax = DisableCRT2Display;
1092 tempbx = 0;
1093 }
1094
1095 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1096 USHORT clearmask = ( DriverMode |
1097 DisableCRT2Display |
1098 LoadDACFlag |
1099 SetNotSimuMode |
1100 SetInSlaveMode |
1101 SetPALTV |
1102 SwitchCRT2 |
1103 SetSimuScanMode );
1104 if(tempbx & SetCRT2ToLCDA) tempbx &= (clearmask | SetCRT2ToLCDA);
1105 if(tempbx & SetCRT2ToRAMDAC) tempbx &= (clearmask | SetCRT2ToRAMDAC);
1106 if(tempbx & SetCRT2ToLCD) tempbx &= (clearmask | SetCRT2ToLCD);
1107 if(tempbx & SetCRT2ToSCART) tempbx &= (clearmask | SetCRT2ToSCART);
1108 if(tempbx & SetCRT2ToHiVision) tempbx &= (clearmask | SetCRT2ToHiVision);
1109 if(tempbx & SetCRT2ToYPbPr525750) tempbx &= (clearmask | SetCRT2ToYPbPr525750);
1110 } else {
1111 if(HwInfo->jChipType >= SIS_315H) {
1112 if(tempbx & SetCRT2ToLCDA) {
1113 tempbx &= (0xFF00|SwitchCRT2|SetSimuScanMode);
1114 }
1115 }
1116 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1117 if(tempbx & SetCRT2ToTV) {
1118 tempbx &= (0xFF00|SetCRT2ToTV|SwitchCRT2|SetSimuScanMode);
1119 }
1120 }
1121 if(tempbx & SetCRT2ToLCD) {
1122 tempbx &= (0xFF00|SetCRT2ToLCD|SwitchCRT2|SetSimuScanMode);
1123 }
1124 if(HwInfo->jChipType >= SIS_315H) {
1125 if(tempbx & SetCRT2ToLCDA) {
1126 tempbx |= SetCRT2ToLCD;
1127 }
1128 }
1129 }
1130
1131 if(tempax & DisableCRT2Display) {
1132 if(!(tempbx & (SwitchCRT2 | SetSimuScanMode))) {
1133 tempbx = SetSimuScanMode | DisableCRT2Display;
1134 }
1135 }
1136
1137 if(!(tempbx & DriverMode)) tempbx |= SetSimuScanMode;
1138
1139 /* LVDS/CHRONTEL (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */
1140 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
1141 if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
1142 ((SiS_Pr->SiS_VBType & VB_NoLCD) && (tempbx & SetCRT2ToLCD)) ) {
1143 modeflag &= (~CRT2Mode);
1144 }
1145 }
1146
1147 if(!(tempbx & SetSimuScanMode)) {
1148 if(tempbx & SwitchCRT2) {
1149 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1150 if( (HwInfo->jChipType >= SIS_315H) &&
1151 (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) ) {
1152 if(resinfo != SIS_RI_1600x1200) {
1153 tempbx |= SetSimuScanMode;
1154 }
1155 } else {
1156 tempbx |= SetSimuScanMode;
1157 }
1158 }
1159 } else {
1160 if(SiS_BridgeIsEnabled(SiS_Pr,HwInfo)) {
1161 if(!(tempbx & DriverMode)) {
1162 if(SiS_BridgeInSlavemode(SiS_Pr)) {
1163 tempbx |= SetSimuScanMode;
1164 }
1165 }
1166 }
1167 }
1168 }
1169
1170 if(!(tempbx & DisableCRT2Display)) {
1171 if(tempbx & DriverMode) {
1172 if(tempbx & SetSimuScanMode) {
1173 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1174 if( (HwInfo->jChipType >= SIS_315H) &&
1175 (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) ) {
1176 if(resinfo != SIS_RI_1600x1200) {
1177 tempbx |= SetInSlaveMode;
1178 }
1179 } else {
1180 tempbx |= SetInSlaveMode;
1181 }
1182 }
1183 }
1184 } else {
1185 tempbx |= SetInSlaveMode;
1186 }
1187 }
1188
1189 }
1190
1191 SiS_Pr->SiS_VBInfo = tempbx;
1192
1193 if(HwInfo->jChipType == SIS_630) {
1194 SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo);
1195 }
1196
1197#ifdef TWDEBUG
1198#ifdef LINUX_KERNEL
1199 printk(KERN_DEBUG "sisfb: (VBInfo= 0x%04x, SetFlag=0x%04x)\n",
1200 SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
1201#endif
1202#ifdef LINUX_XF86
1203 xf86DrvMsgVerb(0, X_PROBED, 3, "(init301: VBInfo=0x%04x, SetFlag=0x%04x)\n",
1204 SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
1205#endif
1206#endif
1207}
1208
1209/*********************************************/
1210/* DETERMINE YPbPr MODE */
1211/*********************************************/
1212
1213void
1214SiS_SetYPbPr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
1215{
1216
1217 UCHAR temp;
1218
1219 /* Note: This variable is only used on 30xLV systems.
1220 * CR38 has a different meaning on LVDS/CH7019 systems.
1221 * On 661 and later, these bits moved to CR35.
1222 *
1223 * On 301, 301B, only HiVision 1080i is supported.
1224 * On 30xLV, 301C, only YPbPr 1080i is supported.
1225 */
1226
1227 SiS_Pr->SiS_YPbPr = 0;
1228 if(HwInfo->jChipType >= SIS_661) return;
1229
1230 if(SiS_Pr->SiS_VBType) {
1231 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1232 SiS_Pr->SiS_YPbPr = YPbPrHiVision;
1233 }
1234 }
1235
1236 if(HwInfo->jChipType >= SIS_315H) {
1237 if(SiS_Pr->SiS_VBType & (VB_SIS301LV302LV | VB_SIS301C)) {
1238 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1239 if(temp & 0x08) {
1240 switch((temp >> 4)) {
1241 case 0x00: SiS_Pr->SiS_YPbPr = YPbPr525i; break;
1242 case 0x01: SiS_Pr->SiS_YPbPr = YPbPr525p; break;
1243 case 0x02: SiS_Pr->SiS_YPbPr = YPbPr750p; break;
1244 case 0x03: SiS_Pr->SiS_YPbPr = YPbPrHiVision; break;
1245 }
1246 }
1247 }
1248 }
1249
1250}
1251
1252/*********************************************/
1253/* DETERMINE TVMode flag */
1254/*********************************************/
1255
1256void
1257SiS_SetTVMode(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, PSIS_HW_INFO HwInfo)
1258{
1259 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
1260 USHORT temp, temp1, resinfo = 0, romindex = 0;
1261 UCHAR OutputSelect = *SiS_Pr->pSiS_OutputSelect;
1262
1263 SiS_Pr->SiS_TVMode = 0;
1264
1265 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
1266 if(SiS_Pr->UseCustomMode) return;
1267
1268 if(ModeNo > 0x13) {
1269 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1270 }
1271
1272 if(HwInfo->jChipType < SIS_661) {
1273
1274 if(SiS_Pr->SiS_VBInfo & SetPALTV) SiS_Pr->SiS_TVMode |= TVSetPAL;
1275
1276 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1277 temp = 0;
1278 if((HwInfo->jChipType == SIS_630) ||
1279 (HwInfo->jChipType == SIS_730)) {
1280 temp = 0x35;
1281 romindex = 0xfe;
1282 } else if(HwInfo->jChipType >= SIS_315H) {
1283 temp = 0x38;
1284 romindex = 0xf3;
1285 if(HwInfo->jChipType >= SIS_330) romindex = 0x11b;
1286 }
1287 if(temp) {
1288 if(romindex && SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
1289 OutputSelect = ROMAddr[romindex];
1290 if(!(OutputSelect & EnablePALMN)) {
1291 SiS_SetRegAND(SiS_Pr->SiS_P3d4,temp,0x3F);
1292 }
1293 }
1294 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,temp);
1295 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1296 if(temp1 & EnablePALM) { /* 0x40 */
1297 SiS_Pr->SiS_TVMode |= TVSetPALM;
1298 SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1299 } else if(temp1 & EnablePALN) { /* 0x80 */
1300 SiS_Pr->SiS_TVMode |= TVSetPALN;
1301 }
1302 } else {
1303 if(temp1 & EnableNTSCJ) { /* 0x40 */
1304 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1305 }
1306 }
1307 }
1308 /* Translate HiVision/YPbPr to our new flags */
1309 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1310 if(SiS_Pr->SiS_YPbPr == YPbPr750p) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1311 else if(SiS_Pr->SiS_YPbPr == YPbPr525p) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1312 else if(SiS_Pr->SiS_YPbPr == YPbPrHiVision) SiS_Pr->SiS_TVMode |= TVSetHiVision;
1313 else SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1314 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p | TVSetYPbPr525i)) {
1315 SiS_Pr->SiS_VBInfo &= ~SetCRT2ToHiVision;
1316 SiS_Pr->SiS_VBInfo |= SetCRT2ToYPbPr525750;
1317 } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
1318 SiS_Pr->SiS_TVMode |= TVSetPAL;
1319 }
1320 }
1321 } else if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1322 if(SiS_Pr->SiS_CHOverScan) {
1323 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
1324 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1325 if((temp & TVOverScan) || (SiS_Pr->SiS_CHOverScan == 1)) {
1326 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1327 }
1328 } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1329 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79);
1330 if((temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1)) {
1331 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1332 }
1333 }
1334 if(SiS_Pr->SiS_CHSOverScan) {
1335 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1336 }
1337 }
1338 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1339 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1340 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1341 if(temp & EnablePALM) SiS_Pr->SiS_TVMode |= TVSetPALM;
1342 else if(temp & EnablePALN) SiS_Pr->SiS_TVMode |= TVSetPALN;
1343 } else {
1344 if(temp & EnableNTSCJ) {
1345 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1346 }
1347 }
1348 }
1349 }
1350
1351 } else { /* 661 and later */
1352
1353 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1354 if(temp1 & 0x01) {
1355 SiS_Pr->SiS_TVMode |= TVSetPAL;
1356 if(temp1 & 0x08) {
1357 SiS_Pr->SiS_TVMode |= TVSetPALN;
1358 } else if(temp1 & 0x04) {
1359 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1360 SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1361 }
1362 SiS_Pr->SiS_TVMode |= TVSetPALM;
1363 }
1364 } else {
1365 if(temp1 & 0x02) {
1366 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1367 }
1368 }
1369 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1370 if(SiS_Pr->SiS_CHOverScan) {
1371 if((temp1 & 0x10) || (SiS_Pr->SiS_CHOverScan == 1)) {
1372 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1373 }
1374 }
1375 }
1376 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1377 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1378 temp1 &= 0xe0;
1379 if(temp1 == 0x00) SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1380 else if(temp1 == 0x20) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1381 else if(temp1 == 0x40) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1382 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1383 SiS_Pr->SiS_TVMode |= (TVSetHiVision | TVSetPAL);
1384 }
1385 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750 | SetCRT2ToHiVision)) {
1386 if(resinfo == SIS_RI_800x480 || resinfo == SIS_RI_1024x576 || resinfo == SIS_RI_1280x720) {
1387 SiS_Pr->SiS_TVMode |= TVAspect169;
1388 } else {
1389 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x39);
1390 if(temp1 & 0x02) {
1391 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetHiVision)) {
1392 SiS_Pr->SiS_TVMode |= TVAspect169;
1393 } else {
1394 SiS_Pr->SiS_TVMode |= TVAspect43LB;
1395 }
1396 } else {
1397 SiS_Pr->SiS_TVMode |= TVAspect43;
1398 }
1399 }
1400 }
1401 }
1402 }
1403
1404 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) SiS_Pr->SiS_TVMode |= TVSetPAL;
1405
1406 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1407
1408 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1409 SiS_Pr->SiS_TVMode |= TVSetPAL;
1410 SiS_Pr->SiS_TVMode &= ~(TVSetPALM | TVSetPALN | TVSetNTSCJ);
1411 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1412 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525i | TVSetYPbPr525p | TVSetYPbPr750p)) {
1413 SiS_Pr->SiS_TVMode &= ~(TVSetPAL | TVSetNTSCJ | TVSetPALM | TVSetPALN);
1414 }
1415 }
1416
1417 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
1418 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
1419 SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
1420 }
1421 }
1422
1423 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
1424 /* BIOS sets TVNTSC1024 without checking 525p here. Wrong? */
1425 if(!(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr525p | TVSetYPbPr750p))) {
1426 if(resinfo == SIS_RI_1024x768) {
1427 SiS_Pr->SiS_TVMode |= TVSetNTSC1024;
1428 }
1429 }
1430 }
1431
1432 SiS_Pr->SiS_TVMode |= TVRPLLDIV2XO;
1433 if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) &&
1434 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
1435 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1436 } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
1437 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1438 } else if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
1439 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
1440 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1441 }
1442 }
1443
1444 }
1445
1446 SiS_Pr->SiS_VBInfo &= ~SetPALTV;
1447
1448#ifdef TWDEBUG
1449 xf86DrvMsg(0, X_INFO, "(init301: TVMode %x, VBInfo %x)\n", SiS_Pr->SiS_TVMode, SiS_Pr->SiS_VBInfo);
1450#endif
1451}
1452
1453/*********************************************/
1454/* GET LCD INFO */
1455/*********************************************/
1456
1457static USHORT
1458SiS_GetBIOSLCDResInfo(SiS_Private *SiS_Pr)
1459{
1460 USHORT temp = SiS_Pr->SiS_LCDResInfo;
1461 /* Translate my LCDResInfo to BIOS value */
1462 if(temp == Panel_1280x768_2) temp = Panel_1280x768;
1463 if(temp == Panel_1280x800_2) temp = Panel_1280x800;
1464 return temp;
1465}
1466
1467static void
1468SiS_GetLCDInfoBIOS(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
1469{
1470#ifdef SIS315H
1471 UCHAR *ROMAddr;
1472 USHORT temp;
1473
1474#ifdef TWDEBUG
1475 xf86DrvMsg(0, X_INFO, "Paneldata driver: [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n",
1476 SiS_Pr->PanelHT, SiS_Pr->PanelVT,
1477 SiS_Pr->PanelHRS, SiS_Pr->PanelHRE,
1478 SiS_Pr->PanelVRS, SiS_Pr->PanelVRE,
1479 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK,
1480 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A,
1481 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B);
1482#endif
1483
1484 if((ROMAddr = GetLCDStructPtr661(SiS_Pr, HwInfo))) {
1485 if((temp = SISGETROMW(6)) != SiS_Pr->PanelHT) {
1486 SiS_Pr->SiS_NeedRomModeData = TRUE;
1487 SiS_Pr->PanelHT = temp;
1488 }
1489 if((temp = SISGETROMW(8)) != SiS_Pr->PanelVT) {
1490 SiS_Pr->SiS_NeedRomModeData = TRUE;
1491 SiS_Pr->PanelVT = temp;
1492 }
1493 SiS_Pr->PanelHRS = SISGETROMW(10);
1494 SiS_Pr->PanelHRE = SISGETROMW(12);
1495 SiS_Pr->PanelVRS = SISGETROMW(14);
1496 SiS_Pr->PanelVRE = SISGETROMW(16);
1497 SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
1498 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].CLOCK =
1499 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].CLOCK = (USHORT)((UCHAR)ROMAddr[18]);
1500 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2B =
1501 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_A = ROMAddr[19];
1502 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2C =
1503 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_B = ROMAddr[20];
1504
1505#ifdef TWDEBUG
1506 xf86DrvMsg(0, X_INFO, "Paneldata BIOS: [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n",
1507 SiS_Pr->PanelHT, SiS_Pr->PanelVT,
1508 SiS_Pr->PanelHRS, SiS_Pr->PanelHRE,
1509 SiS_Pr->PanelVRS, SiS_Pr->PanelVRE,
1510 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK,
1511 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A,
1512 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B);
1513#endif
1514
1515 }
1516#endif
1517}
1518
1519static void
1520SiS_CheckScaling(SiS_Private *SiS_Pr, USHORT resinfo, const UCHAR *nonscalingmodes)
1521{
1522 int i = 0;
1523 while(nonscalingmodes[i] != 0xff) {
1524 if(nonscalingmodes[i++] == resinfo) {
1525 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ||
1526 (SiS_Pr->UsePanelScaler == -1)) {
1527 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1528 }
1529 break;
1530 }
1531 }
1532}
1533
1534void
1535SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
1536 PSIS_HW_INFO HwInfo)
1537{
1538#ifdef SIS300
1539 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
1540 const unsigned char SiS300SeriesLCDRes[] =
1541 { 0, 1, 2, 3, 7, 4, 5, 8,
1542 0, 0, 10, 0, 0, 0, 0, 15 };
1543#endif
1544#ifdef SIS315H
1545 UCHAR *myptr = NULL;
1546#endif
1547 USHORT temp,modeflag,resinfo=0,modexres=0,modeyres=0;
1548 BOOLEAN panelcanscale = FALSE;
1549
1550 SiS_Pr->SiS_LCDResInfo = 0;
1551 SiS_Pr->SiS_LCDTypeInfo = 0;
1552 SiS_Pr->SiS_LCDInfo = 0;
1553 SiS_Pr->PanelHRS = 999; /* HSync start */
1554 SiS_Pr->PanelHRE = 999; /* HSync end */
1555 SiS_Pr->PanelVRS = 999; /* VSync start */
1556 SiS_Pr->PanelVRE = 999; /* VSync end */
1557 SiS_Pr->SiS_NeedRomModeData = FALSE;
1558
1559 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return;
1560
1561 if(ModeNo <= 0x13) {
1562 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
1563 } else if(SiS_Pr->UseCustomMode) {
1564 modeflag = SiS_Pr->CModeFlag;
1565 } else {
1566 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1567 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1568 modexres = SiS_Pr->SiS_ModeResInfo[resinfo].HTotal;
1569 modeyres = SiS_Pr->SiS_ModeResInfo[resinfo].VTotal;
1570 }
1571
1572 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
1573
1574 /* For broken BIOSes: Assume 1024x768 */
1575 if(temp == 0) temp = 0x02;
1576
1577 if((HwInfo->jChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
1578 SiS_Pr->SiS_LCDTypeInfo = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x7c) >> 2;
1579 } else if((HwInfo->jChipType < SIS_315H) || (HwInfo->jChipType >= SIS_661)) {
1580 SiS_Pr->SiS_LCDTypeInfo = temp >> 4;
1581 } else {
1582 SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1;
1583 }
1584 temp &= 0x0f;
1585#ifdef SIS300
1586 if(HwInfo->jChipType < SIS_315H) {
1587 /* Very old BIOSes only know 7 sizes (NetVista 2179, 1.01g) */
1588 if(SiS_Pr->SiS_VBType & VB_SIS301) {
1589 if(temp < 0x0f) temp &= 0x07;
1590 }
1591 /* Translate 300 series LCDRes to 315 series for unified usage */
1592 temp = SiS300SeriesLCDRes[temp];
1593 }
1594#endif
1595
1596 /* Translate to our internal types */
1597 if(HwInfo->jChipType == SIS_550) {
1598 if(temp == Panel310_640x480_2) temp = Panel_640x480_2;
1599 if(temp == Panel310_640x480_3) temp = Panel_640x480_3;
1600 }
1601
1602 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { /* SiS LVDS */
1603 if(temp == Panel310_1280x768) {
1604 temp = Panel_1280x768_2;
1605 }
1606 if(SiS_Pr->SiS_ROMNew) {
1607 if(temp == Panel661_1280x800) {
1608 temp = Panel_1280x800_2;
1609 }
1610 }
1611 }
1612
1613 SiS_Pr->SiS_LCDResInfo = temp;
1614
1615 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1616 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
1617 SiS_Pr->SiS_LCDResInfo = Panel_Barco1366;
1618 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
1619 SiS_Pr->SiS_LCDResInfo = Panel_848x480;
1620 }
1621 }
1622
1623 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1624 if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)
1625 SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMin301;
1626 } else {
1627 if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMinLVDS)
1628 SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS;
1629 }
1630
1631 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
1632 SiS_Pr->SiS_LCDInfo = temp & ~0x000e;
1633 /* Need temp below! */
1634
1635 /* These can't scale no matter what */
1636 switch(SiS_Pr->SiS_LCDResInfo) {
1637 case Panel_1280x960:
1638 SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1639 }
1640
1641 panelcanscale = (SiS_Pr->SiS_LCDInfo & DontExpandLCD) ? TRUE : FALSE;
1642
1643 if(!SiS_Pr->UsePanelScaler) SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1644 else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1645
1646 /* Dual link, Pass 1:1 BIOS default, etc. */
1647#ifdef SIS315H
1648 if(HwInfo->jChipType >= SIS_661) {
1649 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1650 if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1651 }
1652 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
1653 if(SiS_Pr->SiS_ROMNew) {
1654 if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1655 } else if((myptr = GetLCDStructPtr661(SiS_Pr, HwInfo))) {
1656 if(myptr[2] & 0x01) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1657 }
1658 }
1659 } else if(HwInfo->jChipType >= SIS_315H) {
1660 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1661 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1662 }
1663 if((SiS_Pr->SiS_ROMNew) && (!(SiS_Pr->PanelSelfDetected))) {
1664 SiS_Pr->SiS_LCDInfo &= ~(LCDRGB18Bit);
1665 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1666 if(temp & 0x01) SiS_Pr->SiS_LCDInfo |= LCDRGB18Bit;
1667 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
1668 if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1669 }
1670 } else if(!(SiS_Pr->SiS_ROMNew)) {
1671 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
1672 if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) &&
1673 (SiS_Pr->SiS_LCDResInfo == Panel_1024x768)) {
1674 SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1675 }
1676 if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
1677 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
1678 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
1679 (SiS_Pr->SiS_LCDResInfo == Panel_1680x1050)) {
1680 SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1681 }
1682 }
1683 }
1684 }
1685#endif
1686
1687 /* Pass 1:1 */
1688 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
1689 /* Always center screen on LVDS (if scaling is disabled) */
1690 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1691 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
1692 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
1693 /* Always center screen on SiS LVDS (if scaling is disabled) */
1694 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1695 } else {
1696 /* By default, pass 1:1 on SiS TMDS (if scaling is supported) */
1697 if(panelcanscale) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1698 if(SiS_Pr->CenterScreen == 1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1699 }
1700 }
1701
1702 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1703 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1704
1705 switch(SiS_Pr->SiS_LCDResInfo) {
1706 case Panel_320x480: SiS_Pr->PanelXRes = 320; SiS_Pr->PanelYRes = 480;
1707 SiS_Pr->PanelHT = 400; SiS_Pr->PanelVT = 525;
1708 SiS_Pr->PanelVCLKIdx300 = VCLK28;
1709 SiS_Pr->PanelVCLKIdx315 = VCLK28;
1710 break;
1711 case Panel_640x480_2:
1712 case Panel_640x480_3: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
1713 SiS_Pr->PanelVRS = 24; SiS_Pr->PanelVRE = 3;
1714 SiS_Pr->PanelVCLKIdx300 = VCLK28;
1715 SiS_Pr->PanelVCLKIdx315 = VCLK28;
1716 break;
1717 case Panel_640x480: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
1718 SiS_Pr->PanelVRE = 3;
1719 SiS_Pr->PanelVCLKIdx300 = VCLK28;
1720 SiS_Pr->PanelVCLKIdx315 = VCLK28;
1721 break;
1722 case Panel_800x600: SiS_Pr->PanelXRes = 800; SiS_Pr->PanelYRes = 600;
1723 SiS_Pr->PanelHT = 1056; SiS_Pr->PanelVT = 628;
1724 SiS_Pr->PanelHRS = 40; SiS_Pr->PanelHRE = 128;
1725 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 4;
1726 SiS_Pr->PanelVCLKIdx300 = VCLK40;
1727 SiS_Pr->PanelVCLKIdx315 = VCLK40;
1728 break;
1729 case Panel_1024x600: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 600;
1730 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 800;
1731 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
1732 SiS_Pr->PanelVRS = 2 /* 88 */ ; SiS_Pr->PanelVRE = 6;
1733 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1734 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1735 break;
1736 case Panel_1024x768: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768;
1737 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1738 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
1739 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1740 if(HwInfo->jChipType < SIS_315H) {
1741 SiS_Pr->PanelHRS = 23;
1742 SiS_Pr->PanelVRE = 5;
1743 }
1744 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1745 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1746 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1747 break;
1748 case Panel_1152x768: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 768;
1749 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1750 SiS_Pr->PanelHRS = 24;
1751 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1752 if(HwInfo->jChipType < SIS_315H) {
1753 SiS_Pr->PanelHRS = 23;
1754 SiS_Pr->PanelVRE = 5;
1755 }
1756 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1757 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1758 break;
1759 case Panel_1152x864: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 864;
1760 break;
1761 case Panel_1280x720: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 720;
1762 SiS_Pr->PanelHT = 1650; SiS_Pr->PanelVT = 750;
1763 SiS_Pr->PanelHRS = 110; SiS_Pr->PanelHRE = 40;
1764 SiS_Pr->PanelVRS = 5; SiS_Pr->PanelVRE = 5;
1765 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x720;
1766 /* Data above for TMDS (projector); get from BIOS for LVDS */
1767 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1768 break;
1769 case Panel_1280x768: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768;
1770 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1771 SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 806;
1772 SiS_Pr->PanelVCLKIdx300 = VCLK81_300; /* ? */
1773 SiS_Pr->PanelVCLKIdx315 = VCLK81_315; /* ? */
1774 } else {
1775 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 802;
1776 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRS = 112;
1777 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1778 SiS_Pr->PanelVCLKIdx300 = VCLK81_300;
1779 SiS_Pr->PanelVCLKIdx315 = VCLK81_315;
1780 }
1781 break;
1782 case Panel_1280x768_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768;
1783 SiS_Pr->PanelHT = 1660; SiS_Pr->PanelVT = 806;
1784 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1785 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1786 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_2;
1787 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1788 break;
1789 case Panel_1280x800: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800;
1790 SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 816;
1791 SiS_Pr->PanelHRS = 21; SiS_Pr->PanelHRE = 24;
1792 SiS_Pr->PanelVRS = 4; SiS_Pr->PanelVRE = 3;
1793 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315;
1794 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1795 break;
1796 case Panel_1280x800_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800;
1797 SiS_Pr->PanelHT = 1552; SiS_Pr->PanelVT = 812;
1798 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1799 SiS_Pr->PanelVRS = 4; SiS_Pr->PanelVRE = 3;
1800 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315_2;
1801 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1802 break;
1803 case Panel_1280x960: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 960;
1804 SiS_Pr->PanelHT = 1800; SiS_Pr->PanelVT = 1000;
1805 SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
1806 SiS_Pr->PanelVCLKIdx315 = VCLK108_3_315;
1807 if(resinfo == SIS_RI_1280x1024) {
1808 SiS_Pr->PanelVCLKIdx300 = VCLK100_300;
1809 SiS_Pr->PanelVCLKIdx315 = VCLK100_315;
1810 }
1811 break;
1812 case Panel_1280x1024: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024;
1813 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1814 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1815 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1816 SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
1817 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1818 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1819 break;
1820 case Panel_1400x1050: SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050;
1821 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1822 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112; /* HRE OK for LVDS, not for LCDA */
1823 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1824 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1825 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1826 break;
1827 case Panel_1600x1200: SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200;
1828 SiS_Pr->PanelHT = 2160; SiS_Pr->PanelVT = 1250;
1829 SiS_Pr->PanelHRS = 64; SiS_Pr->PanelHRE = 192;
1830 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1831 SiS_Pr->PanelVCLKIdx315 = VCLK162_315;
1832 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1833 break;
1834 case Panel_1680x1050: SiS_Pr->PanelXRes = 1680; SiS_Pr->PanelYRes = 1050;
1835 SiS_Pr->PanelHT = 1900; SiS_Pr->PanelVT = 1066;
1836 SiS_Pr->PanelHRS = 26; SiS_Pr->PanelHRE = 76;
1837 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1838 SiS_Pr->PanelVCLKIdx315 = VCLK121_315;
1839 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1840 break;
1841 case Panel_Barco1366: SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024;
1842 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1843 break;
1844 case Panel_848x480: SiS_Pr->PanelXRes = 848; SiS_Pr->PanelYRes = 480;
1845 SiS_Pr->PanelHT = 1088; SiS_Pr->PanelVT = 525;
1846 break;
1847 case Panel_Custom: SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX;
1848 SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY;
1849 SiS_Pr->PanelHT = SiS_Pr->CHTotal;
1850 SiS_Pr->PanelVT = SiS_Pr->CVTotal;
1851 if(SiS_Pr->CP_PreferredIndex != -1) {
1852 SiS_Pr->PanelXRes = SiS_Pr->CP_HDisplay[SiS_Pr->CP_PreferredIndex];
1853 SiS_Pr->PanelYRes = SiS_Pr->CP_VDisplay[SiS_Pr->CP_PreferredIndex];
1854 SiS_Pr->PanelHT = SiS_Pr->CP_HTotal[SiS_Pr->CP_PreferredIndex];
1855 SiS_Pr->PanelVT = SiS_Pr->CP_VTotal[SiS_Pr->CP_PreferredIndex];
1856 SiS_Pr->PanelHRS = SiS_Pr->CP_HSyncStart[SiS_Pr->CP_PreferredIndex];
1857 SiS_Pr->PanelHRE = SiS_Pr->CP_HSyncEnd[SiS_Pr->CP_PreferredIndex];
1858 SiS_Pr->PanelVRS = SiS_Pr->CP_VSyncStart[SiS_Pr->CP_PreferredIndex];
1859 SiS_Pr->PanelVRE = SiS_Pr->CP_VSyncEnd[SiS_Pr->CP_PreferredIndex];
1860 SiS_Pr->PanelHRS -= SiS_Pr->PanelXRes;
1861 SiS_Pr->PanelHRE -= SiS_Pr->PanelHRS;
1862 SiS_Pr->PanelVRS -= SiS_Pr->PanelYRes;
1863 SiS_Pr->PanelVRE -= SiS_Pr->PanelVRS;
1864 if(SiS_Pr->CP_PrefClock) {
1865 int idx;
1866 SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
1867 SiS_Pr->PanelVCLKIdx300 = VCLK_CUSTOM_300;
1868 if(HwInfo->jChipType < SIS_315H) idx = VCLK_CUSTOM_300;
1869 else idx = VCLK_CUSTOM_315;
1870 SiS_Pr->SiS_VCLKData[idx].CLOCK =
1871 SiS_Pr->SiS_VBVCLKData[idx].CLOCK = SiS_Pr->CP_PrefClock;
1872 SiS_Pr->SiS_VCLKData[idx].SR2B =
1873 SiS_Pr->SiS_VBVCLKData[idx].Part4_A = SiS_Pr->CP_PrefSR2B;
1874 SiS_Pr->SiS_VCLKData[idx].SR2C =
1875 SiS_Pr->SiS_VBVCLKData[idx].Part4_B = SiS_Pr->CP_PrefSR2C;
1876 }
1877 }
1878 break;
1879 default: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768;
1880 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1881 break;
1882 }
1883
1884 /* Special cases */
1885 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
1886 (SiS_Pr->SiS_IF_DEF_DSTN) ||
1887 (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
1888 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
1889 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ) {
1890 SiS_Pr->PanelHRS = 999;
1891 SiS_Pr->PanelHRE = 999;
1892 }
1893
1894 if( (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
1895 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
1896 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ) {
1897 SiS_Pr->PanelVRS = 999;
1898 SiS_Pr->PanelVRE = 999;
1899 }
1900
1901 /* DontExpand overrule */
1902 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
1903
1904 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (modeflag & NoSupportLCDScale)) {
1905 /* No scaling for this mode on any panel (LCD=CRT2)*/
1906 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1907 }
1908
1909 switch(SiS_Pr->SiS_LCDResInfo) {
1910
1911 case Panel_Custom:
1912 case Panel_1152x864:
1913 case Panel_1280x768: /* TMDS only */
1914 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1915 break;
1916
1917 case Panel_800x600: {
1918 static const UCHAR nonscalingmodes[] = {
1919 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, 0xff
1920 };
1921 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1922 break;
1923 }
1924 case Panel_1024x768: {
1925 static const UCHAR nonscalingmodes[] = {
1926 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1927 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1928 0xff
1929 };
1930 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1931 break;
1932 }
1933 case Panel_1280x720: {
1934 static const UCHAR nonscalingmodes[] = {
1935 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1936 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1937 0xff
1938 };
1939 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1940 if(SiS_Pr->PanelHT == 1650) {
1941 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1942 }
1943 break;
1944 }
1945 case Panel_1280x768_2: { /* LVDS only */
1946 static const UCHAR nonscalingmodes[] = {
1947 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1948 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1949 SIS_RI_1152x768,0xff
1950 };
1951 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1952 switch(resinfo) {
1953 case SIS_RI_1280x720: if(SiS_Pr->UsePanelScaler == -1) {
1954 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1955 }
1956 break;
1957 }
1958 break;
1959 }
1960 case Panel_1280x800: { /* SiS TMDS special (Averatec 6200 series) */
1961 static const UCHAR nonscalingmodes[] = {
1962 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1963 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1964 SIS_RI_1152x768,SIS_RI_1280x720,SIS_RI_1280x768,0xff
1965 };
1966 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1967 break;
1968 }
1969 case Panel_1280x800_2: { /* SiS LVDS */
1970 static const UCHAR nonscalingmodes[] = {
1971 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1972 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1973 SIS_RI_1152x768,0xff
1974 };
1975 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1976 switch(resinfo) {
1977 case SIS_RI_1280x720:
1978 case SIS_RI_1280x768: if(SiS_Pr->UsePanelScaler == -1) {
1979 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1980 }
1981 break;
1982 }
1983 break;
1984 }
1985 case Panel_1280x960: {
1986 static const UCHAR 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,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
1990 0xff
1991 };
1992 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1993 break;
1994 }
1995 case Panel_1280x1024: {
1996 static const UCHAR nonscalingmodes[] = {
1997 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1998 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1999 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2000 SIS_RI_1280x960,0xff
2001 };
2002 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2003 break;
2004 }
2005 case Panel_1400x1050: {
2006 static const UCHAR nonscalingmodes[] = {
2007 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2008 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2009 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x768,SIS_RI_1280x800,SIS_RI_1280x960,
2010 0xff
2011 };
2012 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2013 switch(resinfo) {
2014 case SIS_RI_1280x720: if(SiS_Pr->UsePanelScaler == -1) {
2015 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2016 }
2017 break;
2018 case SIS_RI_1280x1024: SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2019 break;
2020 }
2021 break;
2022 }
2023 case Panel_1600x1200: {
2024 static const UCHAR nonscalingmodes[] = {
2025 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2026 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2027 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2028 SIS_RI_1280x960,SIS_RI_1360x768,SIS_RI_1360x1024,0xff
2029 };
2030 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2031 break;
2032 }
2033 case Panel_1680x1050: {
2034 static const UCHAR nonscalingmodes[] = {
2035 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2036 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2037 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x960,SIS_RI_1360x768,SIS_RI_1360x1024,
2038 0xff
2039 };
2040 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2041 break;
2042 }
2043 }
2044 }
2045
2046 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2047 if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
2048 SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20; /* neg h/v sync, RGB24(D0 = 0) */
2049 }
2050 }
2051
2052#ifdef SIS300
2053 if(HwInfo->jChipType < SIS_315H) {
2054 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2055 if(SiS_Pr->SiS_UseROM) {
2056 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
2057 if(!(ROMAddr[0x235] & 0x02)) {
2058 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2059 }
2060 }
2061 }
2062 } else if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
2063 if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
2064 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2065 }
2066 }
2067 }
2068#endif
2069
2070 /* Special cases */
2071
2072 if(modexres == SiS_Pr->PanelXRes && modeyres == SiS_Pr->PanelYRes) {
2073 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2074 }
2075
2076 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
2077 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2078 }
2079
2080 switch(SiS_Pr->SiS_LCDResInfo) {
2081 case Panel_640x480:
2082 SiS_Pr->SiS_LCDInfo |= LCDPass11;
2083 break;
2084 case Panel_1280x800:
2085 /* Don't pass 1:1 by default (TMDS special) */
2086 if(SiS_Pr->CenterScreen == -1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2087 break;
2088 case Panel_1280x960:
2089 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2090 break;
2091 case Panel_Custom:
2092 if((!SiS_Pr->CP_PrefClock) ||
2093 (modexres > SiS_Pr->PanelXRes) || (modeyres > SiS_Pr->PanelYRes)) {
2094 SiS_Pr->SiS_LCDInfo |= LCDPass11;
2095 }
2096 break;
2097 }
2098
2099 if(SiS_Pr->UseCustomMode) {
2100 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2101 }
2102
2103 /* (In)validate LCDPass11 flag */
2104 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2105 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2106 }
2107
2108 /* LVDS DDA */
2109 if(!((HwInfo->jChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
2110
2111 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
2112 if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
2113 if(ModeNo == 0x12) {
2114 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
2115 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2116 }
2117 } else if(ModeNo > 0x13) {
2118 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
2119 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2120 if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) {
2121 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2122 }
2123 }
2124 }
2125 }
2126 }
2127 }
2128
2129 if(modeflag & HalfDCLK) {
2130 if(SiS_Pr->SiS_IF_DEF_TRUMPION == 1) {
2131 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2132 } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
2133 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2134 } else if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) {
2135 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2136 } else if(ModeNo > 0x13) {
2137 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
2138 if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2139 } else if(SiS_Pr->SiS_LCDResInfo == Panel_800x600) {
2140 if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2141 }
2142 }
2143 }
2144
2145 }
2146
2147 /* VESA timing */
2148 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2149 if(SiS_Pr->SiS_VBInfo & SetNotSimuMode) {
2150 SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2151 }
2152 } else {
2153 SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2154 }
2155
2156#ifdef LINUX_KERNEL
2157#ifdef TWDEBUG
2158 printk(KERN_DEBUG "sisfb: (LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n",
2159 SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo);
2160#endif
2161#endif
2162#ifdef LINUX_XF86
2163 xf86DrvMsgVerb(0, X_PROBED, 4,
2164 "(init301: LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x SetFlag=0x%04x)\n",
2165 SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo, SiS_Pr->SiS_SetFlag);
2166#endif
2167}
2168
2169/*********************************************/
2170/* GET VCLK */
2171/*********************************************/
2172
2173USHORT
2174SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2175 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
2176{
2177 USHORT CRT2Index,VCLKIndex=0,VCLKIndexGEN=0;
2178 USHORT modeflag,resinfo,tempbx;
2179 const UCHAR *CHTVVCLKPtr = NULL;
2180
2181 if(ModeNo <= 0x13) {
2182 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2183 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
2184 CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2185 VCLKIndexGEN = (SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)) >> 2) & 0x03;
2186 } else {
2187 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2188 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2189 CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2190 VCLKIndexGEN = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
2191 if(HwInfo->jChipType < SIS_315H) VCLKIndexGEN &= 0x3f;
2192 }
2193
2194 if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 30x/B/LV */
2195
2196 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2197
2198 CRT2Index >>= 6;
2199 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /* LCD */
2200
2201 if(HwInfo->jChipType < SIS_315H) {
2202 VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2203 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2204 VCLKIndex = VCLKIndexGEN;
2205 }
2206 } else {
2207 VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2208 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2209 switch(resinfo) {
2210 /* Only those whose IndexGEN doesn't match VBVCLK array */
2211 case SIS_RI_1280x720: VCLKIndex = VCLK_1280x720; break;
2212 case SIS_RI_720x480: VCLKIndex = VCLK_720x480; break;
2213 case SIS_RI_720x576: VCLKIndex = VCLK_720x576; break;
2214 case SIS_RI_768x576: VCLKIndex = VCLK_768x576; break;
2215 case SIS_RI_848x480: VCLKIndex = VCLK_848x480; break;
2216 case SIS_RI_856x480: VCLKIndex = VCLK_856x480; break;
2217 case SIS_RI_800x480: VCLKIndex = VCLK_800x480; break;
2218 case SIS_RI_1024x576: VCLKIndex = VCLK_1024x576; break;
2219 case SIS_RI_1152x864: VCLKIndex = VCLK_1152x864; break;
2220 case SIS_RI_1360x768: VCLKIndex = VCLK_1360x768; break;
2221 default: VCLKIndex = VCLKIndexGEN;
2222 }
2223
2224 if(ModeNo <= 0x13) {
2225 if(HwInfo->jChipType <= SIS_315PRO) {
2226 if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
2227 } else {
2228 if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x00;
2229 }
2230 }
2231 if(HwInfo->jChipType <= SIS_315PRO) {
2232 if(VCLKIndex == 0) VCLKIndex = 0x41;
2233 if(VCLKIndex == 1) VCLKIndex = 0x43;
2234 if(VCLKIndex == 4) VCLKIndex = 0x44;
2235 }
2236 }
2237 }
2238
2239 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* TV */
2240
2241 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
2242 if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = HiTVVCLKDIV2;
2243 else VCLKIndex = HiTVVCLK;
2244 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
2245 if(modeflag & Charx8Dot) VCLKIndex = HiTVSimuVCLK;
2246 else VCLKIndex = HiTVTextVCLK;
2247 }
2248 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) VCLKIndex = YPbPr750pVCLK;
2249 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) VCLKIndex = TVVCLKDIV2;
2250 else if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = TVVCLKDIV2;
2251 else VCLKIndex = TVVCLK;
2252
2253 if(HwInfo->jChipType < SIS_315H) VCLKIndex += TVCLKBASE_300;
2254 else VCLKIndex += TVCLKBASE_315;
2255
2256 } else { /* VGA2 */
2257
2258 VCLKIndex = VCLKIndexGEN;
2259 if(HwInfo->jChipType < SIS_315H) {
2260 if(ModeNo > 0x13) {
2261 if( (HwInfo->jChipType == SIS_630) &&
2262 (HwInfo->jChipRevision >= 0x30)) {
2263 if(VCLKIndex == 0x14) VCLKIndex = 0x34;
2264 }
2265 /* Better VGA2 clock for 1280x1024@75 */
2266 if(VCLKIndex == 0x17) VCLKIndex = 0x45;
2267 }
2268 }
2269 }
2270
2271 } else { /* If not programming CRT2 */
2272
2273 VCLKIndex = VCLKIndexGEN;
2274 if(HwInfo->jChipType < SIS_315H) {
2275 if(ModeNo > 0x13) {
2276 if( (HwInfo->jChipType != SIS_630) &&
2277 (HwInfo->jChipType != SIS_300) ) {
2278 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2279 }
2280 }
2281 }
2282 }
2283
2284 } else { /* LVDS */
2285
2286 VCLKIndex = CRT2Index;
2287
2288 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2289
2290 if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
2291
2292 VCLKIndex &= 0x1f;
2293 tempbx = 0;
2294 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2295 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2296 tempbx += 2;
2297 if(SiS_Pr->SiS_ModeType > ModeVGA) {
2298 if(SiS_Pr->SiS_CHSOverScan) tempbx = 8;
2299 }
2300 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
2301 tempbx = 4;
2302 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2303 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
2304 tempbx = 6;
2305 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2306 }
2307 }
2308 switch(tempbx) {
2309 case 0: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUNTSC; break;
2310 case 1: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKONTSC; break;
2311 case 2: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPAL; break;
2312 case 3: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break;
2313 case 4: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALM; break;
2314 case 5: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALM; break;
2315 case 6: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALN; break;
2316 case 7: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALN; break;
2317 case 8: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKSOPAL; break;
2318 default: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break;
2319 }
2320 VCLKIndex = CHTVVCLKPtr[VCLKIndex];
2321
2322 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2323
2324 if(HwInfo->jChipType < SIS_315H) {
2325 VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2326 } else {
2327 VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2328 }
2329
2330 /* Special Timing: Barco iQ Pro R series */
2331 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) VCLKIndex = 0x44;
2332
2333 /* Special Timing: 848x480 parallel lvds */
2334 if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
2335 if(HwInfo->jChipType < SIS_315H) {
2336 VCLKIndex = VCLK34_300;
2337 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2338 } else {
2339 VCLKIndex = VCLK34_315;
2340 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2341 }
2342 }
2343
2344 } else {
2345
2346 VCLKIndex = VCLKIndexGEN;
2347 if(HwInfo->jChipType < SIS_315H) {
2348 if(ModeNo > 0x13) {
2349 if( (HwInfo->jChipType == SIS_630) &&
2350 (HwInfo->jChipRevision >= 0x30) ) {
2351 if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
2352 }
2353 }
2354 }
2355 }
2356
2357 } else { /* if not programming CRT2 */
2358
2359 VCLKIndex = VCLKIndexGEN;
2360 if(HwInfo->jChipType < SIS_315H) {
2361 if(ModeNo > 0x13) {
2362 if( (HwInfo->jChipType != SIS_630) &&
2363 (HwInfo->jChipType != SIS_300) ) {
2364 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2365 }
2366#if 0
2367 if(HwInfo->jChipType == SIS_730) {
2368 if(VCLKIndex == 0x0b) VCLKIndex = 0x40; /* 1024x768-70 */
2369 if(VCLKIndex == 0x0d) VCLKIndex = 0x41; /* 1024x768-75 */
2370 }
2371#endif
2372 }
2373 }
2374
2375 }
2376
2377 }
2378
2379#ifdef TWDEBUG
2380 xf86DrvMsg(0, X_INFO, "VCLKIndex %d (0x%x)\n", VCLKIndex, VCLKIndex);
2381#endif
2382
2383 return(VCLKIndex);
2384}
2385
2386/*********************************************/
2387/* SET CRT2 MODE TYPE REGISTERS */
2388/*********************************************/
2389
2390static void
2391SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2392 PSIS_HW_INFO HwInfo)
2393{
2394 USHORT i,j,modeflag;
2395 USHORT tempcl,tempah=0;
2396#if defined(SIS300) || defined(SIS315H)
2397 USHORT tempbl;
2398#endif
2399#ifdef SIS315H
2400 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
2401 USHORT tempah2, tempbl2;
2402#endif
2403
2404 if(ModeNo <= 0x13) {
2405 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2406 } else if(SiS_Pr->UseCustomMode) {
2407 modeflag = SiS_Pr->CModeFlag;
2408 } else {
2409 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2410 }
2411
2412 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
2413
2414 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40);
2415 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2E,0xF7);
2416
2417 } else {
2418
2419 for(i=0,j=4; i<3; i++,j++) SiS_SetReg(SiS_Pr->SiS_Part1Port,j,0);
2420 if(HwInfo->jChipType >= SIS_315H) {
2421 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0x7F);
2422 }
2423
2424 tempcl = SiS_Pr->SiS_ModeType;
2425
2426 if(HwInfo->jChipType < SIS_315H) {
2427
2428#ifdef SIS300 /* ---- 300 series ---- */
2429
2430 /* For 301BDH: (with LCD via LVDS) */
2431 if(SiS_Pr->SiS_VBType & VB_NoLCD) {
2432 tempbl = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32);
2433 tempbl &= 0xef;
2434 tempbl |= 0x02;
2435 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2436 tempbl |= 0x10;
2437 tempbl &= 0xfd;
2438 }
2439 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,tempbl);
2440 }
2441
2442 if(ModeNo > 0x13) {
2443 tempcl -= ModeVGA;
2444 if((tempcl > 0) || (tempcl == 0)) { /* tempcl is USHORT -> always true! */
2445 tempah = ((0x10 >> tempcl) | 0x80);
2446 }
2447 } else tempah = 0x80;
2448
2449 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0xA0;
2450
2451#endif /* SIS300 */
2452
2453 } else {
2454
2455#ifdef SIS315H /* ------- 315/330 series ------ */
2456
2457 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
2458 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
2459 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x08);
2460 }
2461 }
2462
2463 if(ModeNo > 0x13) {
2464 tempcl -= ModeVGA;
2465 if((tempcl > 0) || (tempcl == 0)) { /* tempcl is USHORT -> always true! */
2466 tempah = (0x08 >> tempcl);
2467 if (tempah == 0) tempah = 1;
2468 tempah |= 0x40;
2469 }
2470 } else tempah = 0x40;
2471
2472 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50;
2473
2474#endif /* SIS315H */
2475
2476 }
2477
2478 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2479
2480 if(HwInfo->jChipType < SIS_315H) {
2481 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2482 } else {
2483 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2484 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2485 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
2486 if(IS_SIS740) {
2487 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2488 } else {
2489 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2490 }
2491 }
2492 }
2493
2494 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2495
2496 tempah = 0x01;
2497 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
2498 tempah |= 0x02;
2499 }
2500 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2501 tempah ^= 0x05;
2502 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
2503 tempah ^= 0x01;
2504 }
2505 }
2506
2507 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2508
2509 if(HwInfo->jChipType < SIS_315H) {
2510
2511 tempah = (tempah << 5) & 0xFF;
2512 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2513 tempah = (tempah >> 5) & 0xFF;
2514
2515 } else {
2516
2517 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF8,tempah);
2518
2519 }
2520
2521 if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
2522 tempah |= 0x10;
2523 }
2524
2525 tempah |= 0x80;
2526 if(SiS_Pr->SiS_VBType & VB_SIS301) {
2527 if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah &= ~0x80;
2528 }
2529
2530 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2531 if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p))) {
2532 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2533 tempah |= 0x20;
2534 }
2535 }
2536 }
2537
2538 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah);
2539
2540 tempah = 0x80;
2541 if(SiS_Pr->SiS_VBType & VB_SIS301) {
2542 if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah = 0;
2543 }
2544
2545 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempah |= 0x40;
2546
2547 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2548 if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) {
2549 tempah |= 0x40;
2550 }
2551 }
2552
2553 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0C,tempah);
2554
2555 } else { /* LVDS */
2556
2557 if(HwInfo->jChipType >= SIS_315H) {
2558
2559#ifdef SIS315H
2560 /* LVDS can only be slave in 8bpp modes */
2561 tempah = 0x80;
2562 if((modeflag & CRT2Mode) && (SiS_Pr->SiS_ModeType > ModeVGA)) {
2563 if(SiS_Pr->SiS_VBInfo & DriverMode) {
2564 tempah |= 0x02;
2565 }
2566 }
2567
2568 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
2569 tempah |= 0x02;
2570 }
2571
2572 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2573 tempah ^= 0x01;
2574 }
2575
2576 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
2577 tempah = 1;
2578 }
2579
2580 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah);
2581#endif
2582
2583 } else {
2584
2585#ifdef SIS300
2586 tempah = 0;
2587 if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
2588 tempah |= 0x02;
2589 }
2590 tempah <<= 5;
2591
2592 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2593
2594 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2595#endif
2596
2597 }
2598
2599 }
2600
2601 } /* LCDA */
2602
2603 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2604
2605 if(HwInfo->jChipType >= SIS_315H) {
2606
2607#ifdef SIS315H
2608 unsigned char bridgerev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01);
2609
2610 /* The following is nearly unpreditable and varies from machine
2611 * to machine. Especially the 301DH seems to be a real trouble
2612 * maker. Some BIOSes simply set the registers (like in the
2613 * NoLCD-if-statements here), some set them according to the
2614 * LCDA stuff. It is very likely that some machines are not
2615 * treated correctly in the following, very case-orientated
2616 * code. What do I do then...?
2617 */
2618
2619 /* 740 variants match for 30xB, 301B-DH, 30xLV */
2620
2621 if(!(IS_SIS740)) {
2622 tempah = 0x04; /* For all bridges */
2623 tempbl = 0xfb;
2624 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2625 tempah = 0x00;
2626 if(SiS_IsDualEdge(SiS_Pr, HwInfo)) {
2627 tempbl = 0xff;
2628 }
2629 }
2630 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2631 }
2632
2633 /* The following two are responsible for eventually wrong colors
2634 * in TV output. The DH (VB_NoLCD) conditions are unknown; the
2635 * b0 was found in some 651 machine (Pim; P4_23=0xe5); the b1 version
2636 * in a 650 box (Jake). What is the criteria?
2637 */
2638
2639 if((IS_SIS740) || (HwInfo->jChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
2640 tempah = 0x30;
2641 tempbl = 0xc0;
2642 if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2643 ((SiS_Pr->SiS_ROMNew) && (!(ROMAddr[0x5b] & 0x04)))) {
2644 tempah = 0x00;
2645 tempbl = 0x00;
2646 }
2647 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,tempah);
2648 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,tempbl);
2649 } else if(SiS_Pr->SiS_VBType & VB_SIS301) {
2650 /* Fixes "TV-blue-bug" on 315+301 */
2651 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xcf); /* For 301 */
2652 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2653 } else if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
2654 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30); /* For 30xLV */
2655 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);
2656 } else if((SiS_Pr->SiS_VBType & VB_NoLCD) && (bridgerev == 0xb0)) {
2657 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30); /* For 30xB-DH rev b0 (or "DH on 651"?) */
2658 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);
2659 } else {
2660 tempah = 0x30; tempah2 = 0xc0; /* For 30xB (and 301BDH rev b1) */
2661 tempbl = 0xcf; tempbl2 = 0x3f;
2662 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2663 tempah = tempah2 = 0x00;
2664 if(SiS_IsDualEdge(SiS_Pr, HwInfo)) {
2665 tempbl = tempbl2 = 0xff;
2666 }
2667 }
2668 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2669 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2670 }
2671
2672 if(IS_SIS740) {
2673 tempah = 0x80;
2674 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x00;
2675 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,0x7f,tempah);
2676 } else {
2677 tempah = 0x00;
2678 tempbl = 0x7f;
2679 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2680 tempbl = 0xff;
2681 if(!(SiS_IsDualEdge(SiS_Pr, HwInfo))) tempah = 0x80;
2682 }
2683 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
2684 }
2685
2686#endif /* SIS315H */
2687
2688 } else if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
2689
2690#ifdef SIS300
2691 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2692
2693 if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2694 ((SiS_Pr->SiS_VBType & VB_NoLCD) &&
2695 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD))) {
2696 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x23,0x7F);
2697 } else {
2698 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x23,0x80);
2699 }
2700#endif
2701
2702 }
2703
2704 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
2705 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x0D,0x80);
2706 if(SiS_Pr->SiS_VBType & VB_SIS301C) {
2707 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3A,0xC0);
2708 }
2709 }
2710
2711 } else { /* LVDS */
2712
2713#ifdef SIS315H
2714 if(HwInfo->jChipType >= SIS_315H) {
2715
2716 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
2717
2718 tempah = 0x04;
2719 tempbl = 0xfb;
2720 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2721 tempah = 0x00;
2722 if(SiS_IsDualEdge(SiS_Pr, HwInfo)) tempbl = 0xff;
2723 }
2724 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2725
2726 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
2727 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
2728 }
2729
2730 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
2731
2732 } else if(HwInfo->jChipType == SIS_550) {
2733
2734 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
2735 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
2736
2737 }
2738
2739 }
2740#endif
2741
2742 }
2743
2744}
2745
2746/*********************************************/
2747/* GET RESOLUTION DATA */
2748/*********************************************/
2749
2750USHORT
2751SiS_GetResInfo(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex)
2752{
2753 if(ModeNo <= 0x13) return((USHORT)SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo);
2754 else return((USHORT)SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO);
2755}
2756
2757static void
2758SiS_GetCRT2ResInfo(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
2759 PSIS_HW_INFO HwInfo)
2760{
2761 USHORT xres,yres,modeflag=0,resindex;
2762
2763 if(SiS_Pr->UseCustomMode) {
2764 xres = SiS_Pr->CHDisplay;
2765 if(SiS_Pr->CModeFlag & HalfDCLK) xres *= 2;
2766 SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
2767 yres = SiS_Pr->CVDisplay;
2768 if(SiS_Pr->CModeFlag & DoubleScanMode) yres *= 2;
2769 SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
2770 return;
2771 }
2772
2773 resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex);
2774
2775 if(ModeNo <= 0x13) {
2776 xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
2777 yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
2778 } else {
2779 xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
2780 yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
2781 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2782 }
2783
2784 if(!SiS_Pr->SiS_IF_DEF_DSTN && !SiS_Pr->SiS_IF_DEF_FSTN) {
2785
2786 if((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
2787 if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
2788 if(yres == 350) yres = 400;
2789 }
2790 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
2791 if(ModeNo == 0x12) yres = 400;
2792 }
2793 }
2794
2795 if(modeflag & HalfDCLK) xres *= 2;
2796 if(modeflag & DoubleScanMode) yres *= 2;
2797
2798 }
2799
2800 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
2801
2802#if 0
2803 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCDA | SetCRT2ToLCD | SetCRT2ToHiVision)) {
2804 if(xres == 720) xres = 640;
2805 }
2806#endif
2807
2808 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2809 switch(SiS_Pr->SiS_LCDResInfo) {
2810 case Panel_1024x768:
2811 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
2812 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2813 if(yres == 350) yres = 357;
2814 if(yres == 400) yres = 420;
2815 if(yres == 480) yres = 525;
2816 }
2817 }
2818 break;
2819 case Panel_1280x1024:
2820 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2821 /* BIOS bug - does this regardless of scaling */
2822 if(yres == 400) yres = 405;
2823 }
2824 if(yres == 350) yres = 360;
2825 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
2826 if(yres == 360) yres = 375;
2827 }
2828 break;
2829 case Panel_1600x1200:
2830 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
2831 if(yres == 1024) yres = 1056;
2832 }
2833 break;
2834 }
2835 }
2836
2837 } else {
2838
2839 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2840 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVision)) {
2841 if(xres == 720) xres = 640;
2842 }
2843 } else if(xres == 720) xres = 640;
2844
2845 if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
2846 yres = 400;
2847 if(HwInfo->jChipType >= SIS_315H) {
2848 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
2849 } else {
2850 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
2851 }
2852 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) yres = 480;
2853 }
2854
2855 }
2856 SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
2857 SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
2858}
2859
2860/*********************************************/
2861/* GET CRT2 TIMING DATA */
2862/*********************************************/
2863
2864static BOOLEAN
2865SiS_GetLVDSCRT1Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2866 USHORT RefreshRateTableIndex, USHORT *ResIndex,
2867 USHORT *DisplayType)
2868 {
2869 USHORT modeflag=0;
2870
2871 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2872 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2873 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return FALSE;
2874 }
2875 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
2876 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return FALSE;
2877 } else
2878 return FALSE;
2879
2880 if(ModeNo <= 0x13) {
2881 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2882 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2883 } else {
2884 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2885 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2886 }
2887
2888 (*ResIndex) &= 0x3F;
2889
2890 if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
2891 (*DisplayType) = 18;
2892 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
2893 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2894 (*DisplayType) += 2;
2895 if(SiS_Pr->SiS_ModeType > ModeVGA) {
2896 if(SiS_Pr->SiS_CHSOverScan) (*DisplayType) = 99;
2897 }
2898 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
2899 (*DisplayType) = 18; /* PALM uses NTSC data */
2900 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
2901 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
2902 (*DisplayType) = 20; /* PALN uses PAL data */
2903 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
2904 }
2905 }
2906 } else {
2907 switch(SiS_Pr->SiS_LCDResInfo) {
2908 case Panel_640x480: (*DisplayType) = 50; break;
2909 case Panel_640x480_2: (*DisplayType) = 52; break;
2910 case Panel_640x480_3: (*DisplayType) = 54; break;
2911 case Panel_800x600: (*DisplayType) = 0; break;
2912 case Panel_1024x600: (*DisplayType) = 23; break;
2913 case Panel_1024x768: (*DisplayType) = 4; break;
2914 case Panel_1152x768: (*DisplayType) = 27; break;
2915 case Panel_1280x768: (*DisplayType) = 40; break;
2916 case Panel_1280x1024: (*DisplayType) = 8; break;
2917 case Panel_1400x1050: (*DisplayType) = 14; break;
2918 case Panel_1600x1200: (*DisplayType) = 36; break;
2919 default: return FALSE;
2920 }
2921
2922 if(modeflag & HalfDCLK) (*DisplayType)++;
2923
2924 switch(SiS_Pr->SiS_LCDResInfo) {
2925 case Panel_640x480:
2926 case Panel_640x480_2:
2927 case Panel_640x480_3:
2928 break;
2929 default:
2930 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) (*DisplayType) += 2;
2931 }
2932
2933 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
2934 (*DisplayType) = 12;
2935 if(modeflag & HalfDCLK) (*DisplayType)++;
2936 }
2937 }
2938
2939#if 0
2940 if(SiS_Pr->SiS_IF_DEF_FSTN) {
2941 if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel320x480){
2942 (*DisplayType) = 22;
2943 }
2944 }
2945#endif
2946
2947 return TRUE;
2948}
2949
2950static void
2951SiS_GetCRT2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
2952 USHORT RefreshRateTableIndex,USHORT *CRT2Index,USHORT *ResIndex,
2953 PSIS_HW_INFO HwInfo)
2954{
2955 USHORT tempbx=0,tempal=0,resinfo=0;
2956
2957 if(ModeNo <= 0x13) {
2958 tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2959 } else {
2960 tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2961 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2962 }
2963
2964 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_IF_DEF_LVDS == 0)) {
2965
2966 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { /* LCD */
2967
2968 tempbx = SiS_Pr->SiS_LCDResInfo;
2969 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 32;
2970
2971 if(SiS_Pr->SiS_LCDResInfo == Panel_1680x1050) {
2972 if (resinfo == SIS_RI_1280x800) tempal = 9;
2973 else if(resinfo == SIS_RI_1400x1050) tempal = 11;
2974 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x800) ||
2975 (SiS_Pr->SiS_LCDResInfo == Panel_1280x800_2)) {
2976 if (resinfo == SIS_RI_1280x768) tempal = 9;
2977 }
2978
2979 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
2980 /* Pass 1:1 only (center-screen handled outside) */
2981 /* This is never called for the panel's native resolution */
2982 /* since Pass1:1 will not be set in this case */
2983 tempbx = 100;
2984 if(ModeNo >= 0x13) {
2985 tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
2986 }
2987 }
2988
2989#ifdef SIS315H
2990 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
2991 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
2992 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2993 tempbx = 200;
2994 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
2995 }
2996 }
2997 }
2998#endif
2999
3000 } else { /* TV */
3001
3002 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
3003 /* if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_TVMode &= (~TVSetTVSimuMode); */
3004 tempbx = 2;
3005 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
3006 tempbx = 13;
3007 if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) tempbx = 14;
3008 }
3009 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3010 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempbx = 7;
3011 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempbx = 6;
3012 else tempbx = 5;
3013 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5;
3014 } else {
3015 if(SiS_Pr->SiS_TVMode & TVSetPAL) tempbx = 3;
3016 else tempbx = 4;
3017 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5;
3018 }
3019
3020 }
3021
3022 tempal &= 0x3F;
3023
3024 if(ModeNo > 0x13) {
3025 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) {
3026 if(tempal == 6) tempal = 7;
3027 if((resinfo == SIS_RI_720x480) ||
3028 (resinfo == SIS_RI_720x576) ||
3029 (resinfo == SIS_RI_768x576)) {
3030 tempal = 6;
3031 if(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetPALN)) {
3032 if(resinfo == SIS_RI_720x480) tempal = 9;
3033 }
3034 }
3035 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3036 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
3037 if(resinfo == SIS_RI_1024x768) tempal = 8;
3038 }
3039 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
3040 if((resinfo == SIS_RI_720x576) ||
3041 (resinfo == SIS_RI_768x576)) {
3042 tempal = 8;
3043 }
3044 if(resinfo == SIS_RI_1280x720) tempal = 9;
3045 }
3046 }
3047 }
3048 }
3049
3050 *CRT2Index = tempbx;
3051 *ResIndex = tempal;
3052
3053 } else { /* LVDS, 301B-DH (if running on LCD) */
3054
3055 tempbx = 0;
3056 if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
3057
3058 tempbx = 10;
3059 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
3060 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
3061 tempbx += 2;
3062 if(SiS_Pr->SiS_ModeType > ModeVGA) {
3063 if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
3064 }
3065 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
3066 tempbx = 90;
3067 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
3068 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
3069 tempbx = 92;
3070 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
3071 }
3072 }
3073
3074 } else {
3075
3076 switch(SiS_Pr->SiS_LCDResInfo) {
3077 case Panel_640x480: tempbx = 6; break;
3078 case Panel_640x480_2:
3079 case Panel_640x480_3: tempbx = 30; break;
3080 case Panel_800x600: tempbx = 0; break;
3081 case Panel_1024x600: tempbx = 15; break;
3082 case Panel_1024x768: tempbx = 2; break;
3083 case Panel_1152x768: tempbx = 17; break;
3084 case Panel_1280x768: tempbx = 18; break;
3085 case Panel_1280x1024: tempbx = 4; break;
3086 case Panel_1400x1050: tempbx = 8; break;
3087 case Panel_1600x1200: tempbx = 21; break;
3088 case Panel_Barco1366: tempbx = 80; break;
3089 }
3090
3091 switch(SiS_Pr->SiS_LCDResInfo) {
3092 case Panel_640x480:
3093 case Panel_640x480_2:
3094 case Panel_640x480_3:
3095 break;
3096 default:
3097 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3098 }
3099
3100 if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempbx = 7;
3101
3102 if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
3103 tempbx = 82;
3104 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3105 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
3106 tempbx = 84;
3107 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3108 }
3109
3110 if((SiS_Pr->SiS_CustomT != CUT_BARCO1366) &&
3111 (SiS_Pr->SiS_CustomT != CUT_PANEL848)) {
3112 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) &&
3113 (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
3114 tempal = 0;
3115 }
3116 }
3117
3118 }
3119
3120 (*CRT2Index) = tempbx;
3121 (*ResIndex) = tempal & 0x1F;
3122 }
3123}
3124
3125static void
3126SiS_GetRAMDAC2DATA(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
3127 USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo)
3128{
3129 USHORT tempax=0,tempbx=0;
3130 USHORT temp1=0,modeflag=0,tempcx=0;
3131 USHORT index;
3132
3133 SiS_Pr->SiS_RVBHCMAX = 1;
3134 SiS_Pr->SiS_RVBHCFACT = 1;
3135
3136 if(ModeNo <= 0x13) {
3137
3138 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3139 index = SiS_GetModePtr(SiS_Pr,ModeNo,ModeIdIndex);
3140
3141 tempax = SiS_Pr->SiS_StandTable[index].CRTC[0];
3142 tempbx = SiS_Pr->SiS_StandTable[index].CRTC[6];
3143 temp1 = SiS_Pr->SiS_StandTable[index].CRTC[7];
3144
3145 } else {
3146
3147 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3148 index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
3149
3150 tempax = SiS_Pr->SiS_CRT1Table[index].CR[0];
3151 tempax |= (SiS_Pr->SiS_CRT1Table[index].CR[14] << 8);
3152 tempax &= 0x03FF;
3153 tempbx = SiS_Pr->SiS_CRT1Table[index].CR[6];
3154 tempcx = SiS_Pr->SiS_CRT1Table[index].CR[13] << 8;
3155 tempcx &= 0x0100;
3156 tempcx <<= 2;
3157 tempbx |= tempcx;
3158 temp1 = SiS_Pr->SiS_CRT1Table[index].CR[7];
3159
3160 }
3161
3162 if(temp1 & 0x01) tempbx |= 0x0100;
3163 if(temp1 & 0x20) tempbx |= 0x0200;
3164
3165 tempax += 5;
3166
3167 /* Charx8Dot is no more used (and assumed), so we set it */
3168 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
3169 modeflag |= Charx8Dot;
3170 }
3171
3172 if(modeflag & Charx8Dot) tempax *= 8;
3173 else tempax *= 9;
3174
3175 if(modeflag & HalfDCLK) tempax <<= 1;
3176
3177 tempbx++;
3178
3179 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3180 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = tempbx;
3181}
3182
3183static void
3184SiS_GetCRT2DataLVDS(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
3185 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
3186{
3187 USHORT CRT2Index, ResIndex;
3188 const SiS_LVDSDataStruct *LVDSData = NULL;
3189
3190 SiS_GetCRT2ResInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
3191
3192 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3193 SiS_Pr->SiS_RVBHCMAX = 1;
3194 SiS_Pr->SiS_RVBHCFACT = 1;
3195 SiS_Pr->SiS_NewFlickerMode = 0;
3196 SiS_Pr->SiS_RVBHRS = 50;
3197 SiS_Pr->SiS_RY1COE = 0;
3198 SiS_Pr->SiS_RY2COE = 0;
3199 SiS_Pr->SiS_RY3COE = 0;
3200 SiS_Pr->SiS_RY4COE = 0;
3201 }
3202
3203 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3204
3205#ifdef SIS315H
3206 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3207 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
3208 if(SiS_Pr->UseCustomMode) {
3209 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->CHTotal;
3210 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3211 } else {
3212 if(ModeNo < 0x13) {
3213 ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3214 } else {
3215 ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
3216 }
3217 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAHT;
3218 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAVT;
3219 SiS_Pr->SiS_HT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDHT;
3220 SiS_Pr->SiS_VT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDVT;
3221 }
3222 } else {
3223 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3224 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3225 }
3226 } else {
3227 /* This handles custom modes and custom panels */
3228 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3229 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3230 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3231 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3232 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT - (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE);
3233 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT - (SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE);
3234 }
3235
3236 SiS_CalcLCDACRT1Timing(SiS_Pr,ModeNo,ModeIdIndex);
3237
3238#endif
3239
3240 } else {
3241
3242 /* 301BDH needs LVDS Data */
3243 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3244 SiS_Pr->SiS_IF_DEF_LVDS = 1;
3245 }
3246
3247 SiS_GetCRT2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
3248 &CRT2Index, &ResIndex, HwInfo);
3249
3250 /* 301BDH needs LVDS Data */
3251 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3252 SiS_Pr->SiS_IF_DEF_LVDS = 0;
3253 }
3254
3255 switch (CRT2Index) {
3256 case 0: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1; break;
3257 case 1: LVDSData = SiS_Pr->SiS_LVDS800x600Data_2; break;
3258 case 2: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break;
3259 case 3: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_2; break;
3260 case 4: LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_1; break;
3261 case 5: LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_2; break;
3262 case 6: LVDSData = SiS_Pr->SiS_LVDS640x480Data_1; break;
3263 case 7: LVDSData = SiS_Pr->SiS_LVDSXXXxXXXData_1; break;
3264 case 8: LVDSData = SiS_Pr->SiS_LVDS1400x1050Data_1; break;
3265 case 9: LVDSData = SiS_Pr->SiS_LVDS1400x1050Data_2; break;
3266 case 10: LVDSData = SiS_Pr->SiS_CHTVUNTSCData; break;
3267 case 11: LVDSData = SiS_Pr->SiS_CHTVONTSCData; break;
3268 case 12: LVDSData = SiS_Pr->SiS_CHTVUPALData; break;
3269 case 13: LVDSData = SiS_Pr->SiS_CHTVOPALData; break;
3270 case 14: LVDSData = SiS_Pr->SiS_LVDS320x480Data_1; break;
3271 case 15: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1; break;
3272 case 16: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_2; break;
3273 case 17: LVDSData = SiS_Pr->SiS_LVDS1152x768Data_1; break;
3274 case 18: LVDSData = SiS_Pr->SiS_LVDS1152x768Data_2; break;
3275 case 19: LVDSData = SiS_Pr->SiS_LVDS1280x768Data_1; break;
3276 case 20: LVDSData = SiS_Pr->SiS_LVDS1280x768Data_2; break;
3277 case 21: LVDSData = SiS_Pr->SiS_LVDS1600x1200Data_1; break;
3278 case 22: LVDSData = SiS_Pr->SiS_LVDS1600x1200Data_2; break;
3279 case 30: LVDSData = SiS_Pr->SiS_LVDS640x480Data_2; break;
3280 case 80: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1; break;
3281 case 81: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2; break;
3282 case 82: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1; break;
3283 case 83: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_2; break;
3284 case 84: LVDSData = SiS_Pr->SiS_LVDS848x480Data_1; break;
3285 case 85: LVDSData = SiS_Pr->SiS_LVDS848x480Data_2; break;
3286 case 90: LVDSData = SiS_Pr->SiS_CHTVUPALMData; break;
3287 case 91: LVDSData = SiS_Pr->SiS_CHTVOPALMData; break;
3288 case 92: LVDSData = SiS_Pr->SiS_CHTVUPALNData; break;
3289 case 93: LVDSData = SiS_Pr->SiS_CHTVOPALNData; break;
3290 case 99: LVDSData = SiS_Pr->SiS_CHTVSOPALData; break; /* Super Overscan */
3291 default: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break;
3292 }
3293
3294 SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT;
3295 SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT;
3296 SiS_Pr->SiS_HT = (LVDSData+ResIndex)->LCDHT;
3297 SiS_Pr->SiS_VT = (LVDSData+ResIndex)->LCDVT;
3298
3299 if(!(SiS_Pr->SiS_VBType & VB_SISVB)) {
3300 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
3301 if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
3302 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3303 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3304 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3305 if(ResIndex < 0x08) {
3306 SiS_Pr->SiS_HDE = 1280;
3307 SiS_Pr->SiS_VDE = 1024;
3308 }
3309 }
3310 }
3311 }
3312 }
3313 }
3314}
3315
3316static void
3317SiS_GetCRT2Data301(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
3318 USHORT RefreshRateTableIndex,
3319 PSIS_HW_INFO HwInfo)
3320{
3321 UCHAR *ROMAddr = NULL;
3322 USHORT tempax,tempbx,modeflag,romptr=0;
3323 USHORT resinfo,CRT2Index,ResIndex;
3324 const SiS_LCDDataStruct *LCDPtr = NULL;
3325 const SiS_TVDataStruct *TVPtr = NULL;
3326#ifdef SIS315H
3327 SHORT resinfo661;
3328#endif
3329
3330 if(ModeNo <= 0x13) {
3331 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3332 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
3333 } else if(SiS_Pr->UseCustomMode) {
3334 modeflag = SiS_Pr->CModeFlag;
3335 resinfo = 0;
3336 } else {
3337 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3338 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
3339#ifdef SIS315H
3340 resinfo661 = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].ROMMODEIDX661;
3341 if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
3342 (SiS_Pr->SiS_SetFlag & LCDVESATiming) &&
3343 (resinfo661 >= 0) &&
3344 (SiS_Pr->SiS_NeedRomModeData) ) {
3345 if((ROMAddr = GetLCDStructPtr661(SiS_Pr, HwInfo))) {
3346 if((romptr = (SISGETROMW(21)))) {
3347 romptr += (resinfo661 * 10);
3348 ROMAddr = HwInfo->pjVirtualRomBase;
3349 }
3350 }
3351 }
3352#endif
3353 }
3354
3355 SiS_Pr->SiS_NewFlickerMode = 0;
3356 SiS_Pr->SiS_RVBHRS = 50;
3357 SiS_Pr->SiS_RY1COE = 0;
3358 SiS_Pr->SiS_RY2COE = 0;
3359 SiS_Pr->SiS_RY3COE = 0;
3360 SiS_Pr->SiS_RY4COE = 0;
3361
3362 SiS_GetCRT2ResInfo(SiS_Pr,ModeNo,ModeIdIndex,HwInfo);
3363
3364 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC){
3365
3366 if(SiS_Pr->UseCustomMode) {
3367
3368 SiS_Pr->SiS_RVBHCMAX = 1;
3369 SiS_Pr->SiS_RVBHCFACT = 1;
3370 SiS_Pr->SiS_VGAHT = SiS_Pr->CHTotal;
3371 SiS_Pr->SiS_VGAVT = SiS_Pr->CVTotal;
3372 SiS_Pr->SiS_HT = SiS_Pr->CHTotal;
3373 SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3374 SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE;
3375 SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE;
3376
3377 } else {
3378
3379 SiS_GetRAMDAC2DATA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
3380
3381 }
3382
3383 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
3384
3385 SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3386 &CRT2Index,&ResIndex,HwInfo);
3387
3388 switch(CRT2Index) {
3389 case 2: TVPtr = SiS_Pr->SiS_ExtHiTVData; break;
3390 case 3: TVPtr = SiS_Pr->SiS_ExtPALData; break;
3391 case 4: TVPtr = SiS_Pr->SiS_ExtNTSCData; break;
3392 case 5: TVPtr = SiS_Pr->SiS_Ext525iData; break;
3393 case 6: TVPtr = SiS_Pr->SiS_Ext525pData; break;
3394 case 7: TVPtr = SiS_Pr->SiS_Ext750pData; break;
3395 case 8: TVPtr = SiS_Pr->SiS_StPALData; break;
3396 case 9: TVPtr = SiS_Pr->SiS_StNTSCData; break;
3397 case 10: TVPtr = SiS_Pr->SiS_St525iData; break;
3398 case 11: TVPtr = SiS_Pr->SiS_St525pData; break;
3399 case 12: TVPtr = SiS_Pr->SiS_St750pData; break;
3400 case 13: TVPtr = SiS_Pr->SiS_St1HiTVData; break;
3401 case 14: TVPtr = SiS_Pr->SiS_St2HiTVData; break;
3402 default: TVPtr = SiS_Pr->SiS_StPALData; break;
3403 }
3404
3405 SiS_Pr->SiS_RVBHCMAX = (TVPtr+ResIndex)->RVBHCMAX;
3406 SiS_Pr->SiS_RVBHCFACT = (TVPtr+ResIndex)->RVBHCFACT;
3407 SiS_Pr->SiS_VGAHT = (TVPtr+ResIndex)->VGAHT;
3408 SiS_Pr->SiS_VGAVT = (TVPtr+ResIndex)->VGAVT;
3409 SiS_Pr->SiS_HDE = (TVPtr+ResIndex)->TVHDE;
3410 SiS_Pr->SiS_VDE = (TVPtr+ResIndex)->TVVDE;
3411 SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->RVBHRS;
3412 SiS_Pr->SiS_NewFlickerMode = (TVPtr+ResIndex)->FlickerMode;
3413 if(modeflag & HalfDCLK) {
3414 SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->HALFRVBHRS;
3415 }
3416
3417 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
3418
3419 if((resinfo == SIS_RI_1024x768) ||
3420 (resinfo == SIS_RI_1280x1024) ||
3421 (resinfo == SIS_RI_1280x720)) {
3422 SiS_Pr->SiS_NewFlickerMode = 0x40;
3423 }
3424
3425 if(SiS_Pr->SiS_VGAVDE == 350) SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
3426
3427 SiS_Pr->SiS_HT = ExtHiTVHT;
3428 SiS_Pr->SiS_VT = ExtHiTVVT;
3429 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
3430 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
3431 SiS_Pr->SiS_HT = StHiTVHT;
3432 SiS_Pr->SiS_VT = StHiTVVT;
3433#if 0
3434 if(!(modeflag & Charx8Dot)) {
3435 SiS_Pr->SiS_HT = StHiTextTVHT;
3436 SiS_Pr->SiS_VT = StHiTextTVVT;
3437 }
3438#endif
3439 }
3440 }
3441
3442 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3443
3444 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
3445 SiS_Pr->SiS_HT = 1650;
3446 SiS_Pr->SiS_VT = 750;
3447 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
3448 SiS_Pr->SiS_HT = NTSCHT;
3449 SiS_Pr->SiS_VT = NTSCVT;
3450 } else {
3451 SiS_Pr->SiS_HT = NTSCHT;
3452 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3453 SiS_Pr->SiS_VT = NTSCVT;
3454 }
3455
3456 } else {
3457
3458 SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
3459 SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
3460 SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
3461 SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
3462
3463 if(modeflag & HalfDCLK) {
3464 SiS_Pr->SiS_RY1COE = 0x00;
3465 SiS_Pr->SiS_RY2COE = 0xf4;
3466 SiS_Pr->SiS_RY3COE = 0x10;
3467 SiS_Pr->SiS_RY4COE = 0x38;
3468 }
3469
3470 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
3471 SiS_Pr->SiS_HT = NTSCHT;
3472 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3473 SiS_Pr->SiS_VT = NTSCVT;
3474 } else {
3475 SiS_Pr->SiS_HT = PALHT;
3476 SiS_Pr->SiS_VT = PALVT;
3477 }
3478
3479 }
3480
3481 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3482
3483 SiS_Pr->SiS_RVBHCMAX = 1;
3484 SiS_Pr->SiS_RVBHCFACT = 1;
3485
3486 if(SiS_Pr->UseCustomMode) {
3487
3488 SiS_Pr->SiS_VGAHT = SiS_Pr->CHTotal;
3489 SiS_Pr->SiS_VGAVT = SiS_Pr->CVTotal;
3490 SiS_Pr->SiS_HT = SiS_Pr->CHTotal;
3491 SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3492 SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE;
3493 SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE;
3494
3495 } else {
3496
3497 BOOLEAN gotit = FALSE;
3498
3499 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
3500
3501 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
3502 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
3503 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3504 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3505 gotit = TRUE;
3506
3507 } else if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) && (romptr) && (ROMAddr) ) {
3508
3509#ifdef SIS315H
3510 SiS_Pr->SiS_RVBHCMAX = ROMAddr[romptr];
3511 SiS_Pr->SiS_RVBHCFACT = ROMAddr[romptr+1];
3512 SiS_Pr->SiS_VGAHT = ROMAddr[romptr+2] | ((ROMAddr[romptr+3] & 0x0f) << 8);
3513 SiS_Pr->SiS_VGAVT = ROMAddr[romptr+4] | ((ROMAddr[romptr+3] & 0xf0) << 4);
3514 SiS_Pr->SiS_HT = ROMAddr[romptr+5] | ((ROMAddr[romptr+6] & 0x0f) << 8);
3515 SiS_Pr->SiS_VT = ROMAddr[romptr+7] | ((ROMAddr[romptr+6] & 0xf0) << 4);
3516 if(SiS_Pr->SiS_VGAHT) gotit = TRUE;
3517 else {
3518 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
3519 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
3520 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
3521 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
3522 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3523 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3524 gotit = TRUE;
3525 }
3526#endif
3527
3528 }
3529
3530 if(!gotit) {
3531
3532 SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3533 &CRT2Index,&ResIndex,HwInfo);
3534
3535 switch(CRT2Index) {
3536 case Panel_1024x768 : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break;
3537 case Panel_1024x768 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data; break;
3538 case Panel_1280x720 :
3539 case Panel_1280x720 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x720Data; break;
3540 case Panel_1280x768_2 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x768_2Data; break;
3541 case Panel_1280x768_2+ 32: LCDPtr = SiS_Pr->SiS_StLCD1280x768_2Data; break;
3542 case Panel_1280x800 :
3543 case Panel_1280x800 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x800Data; break;
3544 case Panel_1280x800_2 :
3545 case Panel_1280x800_2+ 32: LCDPtr = SiS_Pr->SiS_LCD1280x800_2Data; break;
3546 case Panel_1280x960 :
3547 case Panel_1280x960 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x960Data; break;
3548 case Panel_1280x1024 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data; break;
3549 case Panel_1280x1024 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
3550 case Panel_1400x1050 : LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data; break;
3551 case Panel_1400x1050 + 32: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data; break;
3552 case Panel_1600x1200 : LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data; break;
3553 case Panel_1600x1200 + 32: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data; break;
3554 case Panel_1680x1050 :
3555 case Panel_1680x1050 + 32: LCDPtr = SiS_Pr->SiS_LCD1680x1050Data; break;
3556 case 100 : LCDPtr = SiS_Pr->SiS_NoScaleData; break;
3557#ifdef SIS315H
3558 case 200 : LCDPtr = SiS310_ExtCompaq1280x1024Data; break;
3559 case 201 : LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
3560#endif
3561 default : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break;
3562 }
3563
3564#ifdef TWDEBUG
3565 xf86DrvMsg(0, X_INFO, "GetCRT2Data: Index %d ResIndex %d\n", CRT2Index, ResIndex);
3566#endif
3567
3568 SiS_Pr->SiS_RVBHCMAX = (LCDPtr+ResIndex)->RVBHCMAX;
3569 SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
3570 SiS_Pr->SiS_VGAHT = (LCDPtr+ResIndex)->VGAHT;
3571 SiS_Pr->SiS_VGAVT = (LCDPtr+ResIndex)->VGAVT;
3572 SiS_Pr->SiS_HT = (LCDPtr+ResIndex)->LCDHT;
3573 SiS_Pr->SiS_VT = (LCDPtr+ResIndex)->LCDVT;
3574
3575 }
3576
3577 tempax = SiS_Pr->PanelXRes;
3578 tempbx = SiS_Pr->PanelYRes;
3579
3580 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3581 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
3582 if(HwInfo->jChipType < SIS_315H) {
3583 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3584 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3585 }
3586 } else {
3587 if (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
3588 else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
3589 else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
3590 else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
3591 else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3592 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3593 }
3594 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960) {
3595 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 700;
3596 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 800;
3597 else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
3598 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
3599 if (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
3600 else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
3601 else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
3602 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) {
3603 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
3604 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 875;
3605 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 1000;
3606 }
3607 }
3608
3609 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3610 tempax = SiS_Pr->SiS_VGAHDE;
3611 tempbx = SiS_Pr->SiS_VGAVDE;
3612 }
3613
3614 SiS_Pr->SiS_HDE = tempax;
3615 SiS_Pr->SiS_VDE = tempbx;
3616 }
3617 }
3618}
3619
3620static void
3621SiS_GetCRT2Data(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
3622 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
3623{
3624
3625 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3626
3627 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
3628 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
3629 } else {
3630 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3631 /* Need LVDS Data for LCD on 301B-DH */
3632 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
3633 } else {
3634 SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
3635 }
3636 }
3637
3638 } else {
3639
3640 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
3641
3642 }
3643}
3644
3645/*********************************************/
3646/* GET LVDS DES (SKEW) DATA */
3647/*********************************************/
3648
3649static void
3650SiS_GetLVDSDesPtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
3651 USHORT RefreshRateTableIndex, USHORT *PanelIndex,
3652 USHORT *ResIndex, PSIS_HW_INFO HwInfo)
3653{
3654 USHORT modeflag;
3655
3656 if(ModeNo <= 0x13) {
3657 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3658 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3659 } else {
3660 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3661 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
3662 }
3663
3664 (*ResIndex) &= 0x1F;
3665 (*PanelIndex) = 0;
3666
3667 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
3668 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
3669 (*PanelIndex) = 50;
3670 if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) (*PanelIndex) += 2;
3671 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*PanelIndex) += 1;
3672 /* Nothing special needed for SOverscan */
3673 /* PALM uses NTSC data, PALN uses PAL data */
3674 }
3675 }
3676
3677 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3678 *PanelIndex = SiS_Pr->SiS_LCDTypeInfo;
3679 if(HwInfo->jChipType >= SIS_661) {
3680 /* As long as we don's use the BIOS tables, we
3681 * need to convert the TypeInfo as for 315 series
3682 */
3683 (*PanelIndex) = SiS_Pr->SiS_LCDResInfo - 1;
3684 }
3685 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3686 (*PanelIndex) += 16;
3687 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
3688 (*PanelIndex) = 32;
3689 if(modeflag & HalfDCLK) (*PanelIndex)++;
3690 }
3691 }
3692 }
3693
3694 if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
3695 if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) {
3696 (*ResIndex) = 7;
3697 if(HwInfo->jChipType < SIS_315H) {
3698 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) (*ResIndex)++;
3699 }
3700 }
3701 }
3702}
3703
3704static void
3705SiS_GetLVDSDesData(SiS_Private *SiS_Pr, USHORT ModeNo,USHORT ModeIdIndex,
3706 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
3707{
3708 USHORT modeflag;
3709 USHORT PanelIndex,ResIndex;
3710 const SiS_LVDSDesStruct *PanelDesPtr = NULL;
3711
3712 SiS_Pr->SiS_LCDHDES = 0;
3713 SiS_Pr->SiS_LCDVDES = 0;
3714
3715 if( (SiS_Pr->UseCustomMode) ||
3716 (SiS_Pr->SiS_LCDResInfo == Panel_Custom) ||
3717 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
3718 ((SiS_Pr->SiS_VBType & VB_SISVB) &&
3719 (SiS_Pr->SiS_LCDInfo & DontExpandLCD) &&
3720 (SiS_Pr->SiS_LCDInfo & LCDPass11)) ) {
3721 return;
3722 }
3723
3724 if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3725
3726#ifdef SIS315H
3727 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3728 /* non-pass 1:1 only, see above */
3729 if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
3730 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
3731 }
3732 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
3733 SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
3734 }
3735 }
3736 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3737 switch(SiS_Pr->SiS_CustomT) {
3738 case CUT_UNIWILL1024:
3739 case CUT_UNIWILL10242:
3740 case CUT_CLEVO1400:
3741 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3742 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3743 }
3744 break;
3745 }
3746 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
3747 if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
3748 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3749 }
3750 }
3751 }
3752#endif
3753
3754 } else {
3755
3756 SiS_GetLVDSDesPtr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
3757 &PanelIndex, &ResIndex, HwInfo);
3758
3759 switch(PanelIndex) {
3760 case 0: PanelDesPtr = SiS_Pr->SiS_PanelType00_1; break; /* --- */
3761 case 1: PanelDesPtr = SiS_Pr->SiS_PanelType01_1; break;
3762 case 2: PanelDesPtr = SiS_Pr->SiS_PanelType02_1; break;
3763 case 3: PanelDesPtr = SiS_Pr->SiS_PanelType03_1; break;
3764 case 4: PanelDesPtr = SiS_Pr->SiS_PanelType04_1; break;
3765 case 5: PanelDesPtr = SiS_Pr->SiS_PanelType05_1; break;
3766 case 6: PanelDesPtr = SiS_Pr->SiS_PanelType06_1; break;
3767 case 7: PanelDesPtr = SiS_Pr->SiS_PanelType07_1; break;
3768 case 8: PanelDesPtr = SiS_Pr->SiS_PanelType08_1; break;
3769 case 9: PanelDesPtr = SiS_Pr->SiS_PanelType09_1; break;
3770 case 10: PanelDesPtr = SiS_Pr->SiS_PanelType0a_1; break;
3771 case 11: PanelDesPtr = SiS_Pr->SiS_PanelType0b_1; break;
3772 case 12: PanelDesPtr = SiS_Pr->SiS_PanelType0c_1; break;
3773 case 13: PanelDesPtr = SiS_Pr->SiS_PanelType0d_1; break;
3774 case 14: PanelDesPtr = SiS_Pr->SiS_PanelType0e_1; break;
3775 case 15: PanelDesPtr = SiS_Pr->SiS_PanelType0f_1; break;
3776 case 16: PanelDesPtr = SiS_Pr->SiS_PanelType00_2; break; /* --- */
3777 case 17: PanelDesPtr = SiS_Pr->SiS_PanelType01_2; break;
3778 case 18: PanelDesPtr = SiS_Pr->SiS_PanelType02_2; break;
3779 case 19: PanelDesPtr = SiS_Pr->SiS_PanelType03_2; break;
3780 case 20: PanelDesPtr = SiS_Pr->SiS_PanelType04_2; break;
3781 case 21: PanelDesPtr = SiS_Pr->SiS_PanelType05_2; break;
3782 case 22: PanelDesPtr = SiS_Pr->SiS_PanelType06_2; break;
3783 case 23: PanelDesPtr = SiS_Pr->SiS_PanelType07_2; break;
3784 case 24: PanelDesPtr = SiS_Pr->SiS_PanelType08_2; break;
3785 case 25: PanelDesPtr = SiS_Pr->SiS_PanelType09_2; break;
3786 case 26: PanelDesPtr = SiS_Pr->SiS_PanelType0a_2; break;
3787 case 27: PanelDesPtr = SiS_Pr->SiS_PanelType0b_2; break;
3788 case 28: PanelDesPtr = SiS_Pr->SiS_PanelType0c_2; break;
3789 case 29: PanelDesPtr = SiS_Pr->SiS_PanelType0d_2; break;
3790 case 30: PanelDesPtr = SiS_Pr->SiS_PanelType0e_2; break;
3791 case 31: PanelDesPtr = SiS_Pr->SiS_PanelType0f_2; break;
3792 case 32: PanelDesPtr = SiS_Pr->SiS_PanelTypeNS_1; break; /* pass 1:1 */
3793 case 33: PanelDesPtr = SiS_Pr->SiS_PanelTypeNS_2; break;
3794 case 50: PanelDesPtr = SiS_Pr->SiS_CHTVUNTSCDesData; break; /* TV */
3795 case 51: PanelDesPtr = SiS_Pr->SiS_CHTVONTSCDesData; break;
3796 case 52: PanelDesPtr = SiS_Pr->SiS_CHTVUPALDesData; break;
3797 case 53: PanelDesPtr = SiS_Pr->SiS_CHTVOPALDesData; break;
3798 default: return;
3799 }
3800
3801 SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
3802 SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;
3803
3804 if((ModeNo <= 0x13) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
3805 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3806 if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3807 if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 632;
3808 } else if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) {
3809 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
3810 if(SiS_Pr->SiS_LCDResInfo >= Panel_1024x768) {
3811 if(HwInfo->jChipType < SIS_315H) {
3812 if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320;
3813 } else {
3814 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) SiS_Pr->SiS_LCDHDES = 480;
3815 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 804;
3816 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 704;
3817 if(!(modeflag & HalfDCLK)) {
3818 SiS_Pr->SiS_LCDHDES = 320;
3819 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 632;
3820 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 542;
3821 }
3822 }
3823 }
3824 }
3825 }
3826 }
3827 }
3828}
3829
3830/*********************************************/
3831/* DISABLE VIDEO BRIDGE */
3832/*********************************************/
3833
3834/* NEVER use any variables (VBInfo), this will be called
3835 * from outside the context of modeswitch!
3836 * MUST call getVBType before calling this
3837 */
3838void
3839SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
3840{
3841#ifdef SIS315H
3842 USHORT tempah,pushax=0,modenum;
3843#endif
3844 USHORT temp=0;
3845
3846 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3847
3848 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { /* ===== For 30xB/LV ===== */
3849
3850 if(HwInfo->jChipType < SIS_315H) {
3851
3852#ifdef SIS300 /* 300 series */
3853
3854 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
3855 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3856 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
3857 } else {
3858 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
3859 }
3860 SiS_PanelDelay(SiS_Pr, HwInfo, 3);
3861 }
3862 if(SiS_Is301B(SiS_Pr)) {
3863 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);
3864 SiS_ShortDelay(SiS_Pr,1);
3865 }
3866 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
3867 SiS_DisplayOff(SiS_Pr);
3868 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3869 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
3870 SiS_UnLockCRT2(SiS_Pr,HwInfo);
3871 if(!(SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
3872 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
3873 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
3874 }
3875 if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ||
3876 (!(SiS_CR36BIOSWord23d(SiS_Pr, HwInfo))) ) {
3877 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
3878 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3879 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
3880 } else {
3881 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
3882 }
3883 }
3884
3885#endif /* SIS300 */
3886
3887 } else {
3888
3889#ifdef SIS315H /* 315 series */
3890
3891 BOOLEAN custom1 = ((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
3892 (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) ? TRUE : FALSE;
3893
3894 modenum = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34) & 0x7f;
3895
3896 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3897
3898#ifdef SET_EMI
3899 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
3900 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
3901 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
3902 }
3903 }
3904#endif
3905 if( (modenum <= 0x13) ||
3906 (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
3907 (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ) {
3908 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
3909 if(custom1) SiS_PanelDelay(SiS_Pr, HwInfo, 3);
3910 }
3911
3912 if(!custom1) {
3913 SiS_DDC2Delay(SiS_Pr,0xff00);
3914 SiS_DDC2Delay(SiS_Pr,0xe000);
3915 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
3916 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
3917 if(IS_SIS740) {
3918 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
3919 }
3920 SiS_PanelDelay(SiS_Pr, HwInfo, 3);
3921 }
3922
3923 }
3924
3925 if(!(SiS_IsNotM650orLater(SiS_Pr, HwInfo))) {
3926 if(HwInfo->jChipType < SIS_340) {
3927 tempah = 0xef;
3928 if(SiS_IsVAMode(SiS_Pr,HwInfo)) tempah = 0xf7;
3929 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
3930 }
3931 }
3932
3933 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3934 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,~0x10);
3935 }
3936
3937 tempah = 0x3f;
3938 if(SiS_IsDualEdge(SiS_Pr,HwInfo)) {
3939 tempah = 0x7f;
3940 if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) tempah = 0xbf;
3941 }
3942 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
3943
3944 if((SiS_IsVAMode(SiS_Pr,HwInfo)) ||
3945 ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && (modenum <= 0x13))) {
3946
3947 SiS_DisplayOff(SiS_Pr);
3948 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3949 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
3950 }
3951 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3952 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
3953
3954 }
3955
3956 if((!(SiS_IsVAMode(SiS_Pr,HwInfo))) ||
3957 ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && (modenum <= 0x13))) {
3958
3959 if(!(SiS_IsDualEdge(SiS_Pr,HwInfo))) {
3960 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
3961 SiS_DisplayOff(SiS_Pr);
3962 }
3963 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
3964
3965 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3966 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
3967 }
3968
3969 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3970 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
3971 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
3972 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
3973 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
3974
3975 }
3976
3977 if(SiS_IsNotM650orLater(SiS_Pr,HwInfo)) {
3978 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
3979 }
3980
3981 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3982
3983 if(!custom1) {
3984
3985 if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
3986 if(!(SiS_CRT2IsLCD(SiS_Pr,HwInfo))) {
3987 if(!(SiS_IsDualEdge(SiS_Pr,HwInfo))) {
3988 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
3989 }
3990 }
3991 }
3992
3993 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
3994
3995 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
3996 if(SiS_IsVAorLCD(SiS_Pr, HwInfo)) {
3997 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 20);
3998 }
3999 }
4000
4001 } else {
4002
4003 if((SiS_IsVAMode(SiS_Pr,HwInfo)) ||
4004 (!(SiS_IsDualEdge(SiS_Pr,HwInfo)))) {
4005 if((!(SiS_WeHaveBacklightCtrl(SiS_Pr, HwInfo))) ||
4006 (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo)))) {
4007 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
4008 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
4009 SiS_PanelDelay(SiS_Pr, HwInfo, 4);
4010 }
4011 }
4012
4013 }
4014 }
4015
4016#endif /* SIS315H */
4017
4018 }
4019
4020 } else { /* ============ For 301 ================ */
4021
4022 if(HwInfo->jChipType < SIS_315H) {
4023#ifdef SIS300
4024 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
4025 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
4026 SiS_PanelDelay(SiS_Pr, HwInfo, 3);
4027 }
4028#endif
4029 }
4030
4031 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF); /* disable VB */
4032 SiS_DisplayOff(SiS_Pr);
4033
4034 if(HwInfo->jChipType >= SIS_315H) {
4035 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4036 }
4037
4038 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); /* disable lock mode */
4039
4040 if(HwInfo->jChipType >= SIS_315H) {
4041 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
4042 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
4043 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4044 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
4045 } else {
4046#ifdef SIS300
4047 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); /* disable CRT2 */
4048 if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ||
4049 (!(SiS_CR36BIOSWord23d(SiS_Pr,HwInfo))) ) {
4050 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
4051 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
4052 }
4053#endif
4054 }
4055
4056 }
4057
4058 } else { /* ============ For LVDS =============*/
4059
4060 if(HwInfo->jChipType < SIS_315H) {
4061
4062#ifdef SIS300 /* 300 series */
4063
4064 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4065 SiS_SetCH700x(SiS_Pr,0x090E);
4066 }
4067
4068 if(HwInfo->jChipType == SIS_730) {
4069 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4070 SiS_WaitVBRetrace(SiS_Pr,HwInfo);
4071 }
4072 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
4073 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
4074 SiS_PanelDelay(SiS_Pr, HwInfo, 3);
4075 }
4076 } else {
4077 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4078 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4079 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
4080 SiS_WaitVBRetrace(SiS_Pr,HwInfo);
4081 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {
4082 SiS_DisplayOff(SiS_Pr);
4083 }
4084 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
4085 SiS_PanelDelay(SiS_Pr, HwInfo, 3);
4086 }
4087 }
4088 }
4089 }
4090
4091 SiS_DisplayOff(SiS_Pr);
4092
4093 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4094
4095 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4096 SiS_UnLockCRT2(SiS_Pr,HwInfo);
4097 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
4098 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
4099
4100 if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ||
4101 (!(SiS_CR36BIOSWord23d(SiS_Pr,HwInfo))) ) {
4102 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
4103 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
4104 }
4105
4106#endif /* SIS300 */
4107
4108 } else {
4109
4110#ifdef SIS315H /* 315 series */
4111
4112 if(!(SiS_IsNotM650orLater(SiS_Pr,HwInfo))) {
4113 if(HwInfo->jChipType < SIS_340) {
4114 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,~0x18);
4115 }
4116 }
4117
4118 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4119
4120 if(HwInfo->jChipType == SIS_740) {
4121 temp = SiS_GetCH701x(SiS_Pr,0x61);
4122 if(temp < 1) {
4123 SiS_SetCH701x(SiS_Pr,0xac76);
4124 SiS_SetCH701x(SiS_Pr,0x0066);
4125 }
4126
4127 if( (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
4128 (SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo)) ) {
4129 SiS_SetCH701x(SiS_Pr,0x3e49);
4130 }
4131 }
4132
4133 if( (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
4134 (SiS_IsVAMode(SiS_Pr,HwInfo)) ) {
4135 SiS_Chrontel701xBLOff(SiS_Pr);
4136 SiS_Chrontel701xOff(SiS_Pr,HwInfo);
4137 }
4138
4139 if(HwInfo->jChipType != SIS_740) {
4140 if( (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
4141 (SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo)) ) {
4142 SiS_SetCH701x(SiS_Pr,0x0149);
4143 }
4144 }
4145
4146 }
4147
4148 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4149 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
4150 SiS_PanelDelay(SiS_Pr, HwInfo, 3);
4151 }
4152
4153 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4154 (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
4155 (!(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo))) ) {
4156 SiS_DisplayOff(SiS_Pr);
4157 }
4158
4159 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4160 (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
4161 (!(SiS_IsVAMode(SiS_Pr,HwInfo))) ) {
4162 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4163 }
4164
4165 if(HwInfo->jChipType == SIS_740) {
4166 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4167 }
4168
4169 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4170
4171 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4172 (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
4173 (!(SiS_IsVAMode(SiS_Pr,HwInfo))) ) {
4174 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4175 }
4176
4177 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4178 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4179 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4180 if(HwInfo->jChipType == SIS_550) {
4181 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xbf);
4182 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xef);
4183 }
4184 }
4185 } else {
4186 if(HwInfo->jChipType == SIS_740) {
4187 if(SiS_IsLCDOrLCDA(SiS_Pr,HwInfo)) {
4188 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4189 }
4190 } else if(SiS_IsVAMode(SiS_Pr,HwInfo)) {
4191 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4192 }
4193 }
4194
4195 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4196 if(SiS_IsDualEdge(SiS_Pr,HwInfo)) {
4197 /* SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff); */
4198 } else {
4199 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
4200 }
4201 }
4202
4203 SiS_UnLockCRT2(SiS_Pr,HwInfo);
4204
4205 if(HwInfo->jChipType == SIS_550) {
4206 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); /* DirectDVD PAL?*/
4207 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); /* VB clock / 4 ? */
4208 } else if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4209 (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
4210 (!(SiS_IsVAMode(SiS_Pr,HwInfo))) ) {
4211 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4212 }
4213
4214 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4215 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4216 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4217 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
4218 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
4219 }
4220 }
4221 }
4222
4223#endif /* SIS315H */
4224
4225 } /* 315 series */
4226
4227 } /* LVDS */
4228
4229}
4230
4231/*********************************************/
4232/* ENABLE VIDEO BRIDGE */
4233/*********************************************/
4234
4235/* NEVER use any variables (VBInfo), this will be called
4236 * from outside the context of a mode switch!
4237 * MUST call getVBType before calling this
4238 */
4239void
4240SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
4241{
4242 USHORT temp=0,tempah;
4243#ifdef SIS315H
4244 USHORT temp1,pushax=0;
4245 BOOLEAN delaylong = FALSE;
4246#endif
4247
4248 if(SiS_Pr->SiS_VBType & VB_SISVB) {
4249
4250 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { /* ====== For 301B et al ====== */
4251
4252 if(HwInfo->jChipType < SIS_315H) {
4253
4254#ifdef SIS300 /* 300 series */
4255
4256 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4257 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4258 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4259 } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
4260 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
4261 }
4262 if(SiS_Pr->SiS_VBType & (VB_SIS301LV302LV | VB_NoLCD)) {
4263 if(!(SiS_CR36BIOSWord23d(SiS_Pr, HwInfo))) {
4264 SiS_PanelDelay(SiS_Pr, HwInfo, 0);
4265 }
4266 }
4267 }
4268
4269 if((SiS_Pr->SiS_VBType & VB_NoLCD) &&
4270 (SiS_CRT2IsLCD(SiS_Pr, HwInfo))) {
4271
4272 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* Enable CRT2 */
4273 SiS_DisplayOn(SiS_Pr);
4274 SiS_UnLockCRT2(SiS_Pr,HwInfo);
4275 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4276 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4277 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4278 } else {
4279 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4280 }
4281 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4282 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4283 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
4284 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4285 }
4286 SiS_WaitVBRetrace(SiS_Pr,HwInfo);
4287 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00);
4288 }
4289 }
4290
4291 } else {
4292
4293 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
4294 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4295 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4296 if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4297 }
4298 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4299 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4300 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */
4301 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
4302 SiS_DisplayOn(SiS_Pr);
4303 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4304 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4305 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4306 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
4307 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4308 }
4309 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4310 }
4311 }
4312 }
4313
4314 }
4315
4316
4317#endif /* SIS300 */
4318
4319 } else {
4320
4321#ifdef SIS315H /* 315 series */
4322
4323#ifdef SET_EMI
4324 UCHAR r30=0, r31=0, r32=0, r33=0, cr36=0;
4325 /* USHORT emidelay=0; */
4326#endif
4327
4328 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4329 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef);
4330#ifdef SET_EMI
4331 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
4332 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4333 }
4334#endif
4335 }
4336
4337 if(!(SiS_IsNotM650orLater(SiS_Pr, HwInfo))) {
4338 if(HwInfo->jChipType < SIS_340) {
4339 tempah = 0x10;
4340 if(SiS_LCDAEnabled(SiS_Pr, HwInfo)) {
4341 if(SiS_TVEnabled(SiS_Pr, HwInfo)) tempah = 0x18;
4342 else tempah = 0x08;
4343 }
4344 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah);
4345 }
4346 }
4347
4348 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4349
4350 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
4351 SiS_DisplayOff(SiS_Pr);
4352 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
4353 if(IS_SIS740) {
4354 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
4355 }
4356
4357 if(SiS_IsVAorLCD(SiS_Pr, HwInfo)) {
4358 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
4359 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 2);
4360 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4361 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 2);
4362 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
4363 SiS_GenericDelay(SiS_Pr, 0x4500);
4364 }
4365 }
4366 }
4367
4368 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {
4369 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10);
4370 delaylong = TRUE;
4371 }
4372
4373 }
4374
4375 if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
4376
4377 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
4378 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4379 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4380 if(!(tempah & SetCRT2ToRAMDAC)) {
4381 if(!(SiS_LCDAEnabled(SiS_Pr, HwInfo))) temp |= 0x20;
4382 }
4383 }
4384 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4385
4386 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
4387
4388 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4389 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4390
4391 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4392 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
4393 }
4394
4395 } else {
4396
4397 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20);
4398
4399 }
4400
4401 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
4402 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4403
4404 tempah = 0xc0;
4405 if(SiS_IsDualEdge(SiS_Pr, HwInfo)) {
4406 tempah = 0x80;
4407 if(!(SiS_IsVAMode(SiS_Pr, HwInfo))) tempah = 0x40;
4408 }
4409 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4410
4411 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4412
4413 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
4414
4415 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10);
4416 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4417
4418 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
4419#ifdef SET_EMI
4420 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
4421 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4422 SiS_GenericDelay(SiS_Pr, 0x500);
4423 }
4424#endif
4425 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
4426
4427 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
4428#ifdef SET_EMI
4429 cr36 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
4430
4431 if(SiS_Pr->SiS_ROMNew) {
4432 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
4433 USHORT romptr = GetLCDStructPtr661_2(SiS_Pr, HwInfo);
4434 if(romptr) {
4435 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4436 SiS_Pr->EMI_30 = 0;
4437 SiS_Pr->EMI_31 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 0];
4438 SiS_Pr->EMI_32 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 1];
4439 SiS_Pr->EMI_33 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 2];
4440 if(ROMAddr[romptr + 1] & 0x10) SiS_Pr->EMI_30 = 0x40;
4441 /* emidelay = SISGETROMW((romptr + 0x22)); */
4442 SiS_Pr->HaveEMI = SiS_Pr->HaveEMILCD = SiS_Pr->OverruleEMI = TRUE;
4443 }
4444 }
4445
4446 /* (P4_30|0x40) */
4447 /* Compal 1400x1050: 0x05, 0x60, 0x00 YES (1.10.7w; CR36=69) */
4448 /* Compal 1400x1050: 0x0d, 0x70, 0x40 YES (1.10.7x; CR36=69) */
4449 /* Acer 1280x1024: 0x12, 0xd0, 0x6b NO (1.10.9k; CR36=73) */
4450 /* Compaq 1280x1024: 0x0d, 0x70, 0x6b YES (1.12.04b; CR36=03) */
4451 /* Clevo 1024x768: 0x05, 0x60, 0x33 NO (1.10.8e; CR36=12, DL!) */
4452 /* Clevo 1024x768: 0x0d, 0x70, 0x40 (if type == 3) YES (1.10.8y; CR36=?2) */
4453 /* Clevo 1024x768: 0x05, 0x60, 0x33 (if type != 3) YES (1.10.8y; CR36=?2) */
4454 /* Asus 1024x768: ? ? (1.10.8o; CR36=?2) */
4455 /* Asus 1024x768: 0x08, 0x10, 0x3c (problematic) YES (1.10.8q; CR36=22) */
4456
4457 if(SiS_Pr->HaveEMI) {
4458 r30 = SiS_Pr->EMI_30; r31 = SiS_Pr->EMI_31;
4459 r32 = SiS_Pr->EMI_32; r33 = SiS_Pr->EMI_33;
4460 } else {
4461 r30 = 0;
4462 }
4463
4464 /* EMI_30 is read at driver start; however, the BIOS sets this
4465 * (if it is used) only if the LCD is in use. In case we caught
4466 * the machine while on TV output, this bit is not set and we
4467 * don't know if it should be set - hence our detection is wrong.
4468 * Work-around this here:
4469 */
4470
4471 if((!SiS_Pr->HaveEMI) || (!SiS_Pr->HaveEMILCD)) {
4472 switch((cr36 & 0x0f)) {
4473 case 2:
4474 r30 |= 0x40;
4475 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) r30 &= ~0x40;
4476 if(!SiS_Pr->HaveEMI) {
4477 r31 = 0x05; r32 = 0x60; r33 = 0x33;
4478 if((cr36 & 0xf0) == 0x30) {
4479 r31 = 0x0d; r32 = 0x70; r33 = 0x40;
4480 }
4481 }
4482 break;
4483 case 3: /* 1280x1024 */
4484 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) r30 |= 0x40;
4485 if(!SiS_Pr->HaveEMI) {
4486 r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4487 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4488 r31 = 0x0d; r32 = 0x70; r33 = 0x6b;
4489 }
4490 }
4491 break;
4492 case 9: /* 1400x1050 */
4493 r30 |= 0x40;
4494 if(!SiS_Pr->HaveEMI) {
4495 r31 = 0x05; r32 = 0x60; r33 = 0x00;
4496 if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4497 r31 = 0x0d; r32 = 0x70; r33 = 0x40; /* BIOS values */
4498 }
4499 }
4500 break;
4501 case 11: /* 1600x1200 - unknown */
4502 r30 |= 0x40;
4503 if(!SiS_Pr->HaveEMI) {
4504 r31 = 0x05; r32 = 0x60; r33 = 0x00;
4505 }
4506 }
4507 }
4508
4509 /* BIOS values don't work so well sometimes */
4510 if(!SiS_Pr->OverruleEMI) {
4511#ifdef COMPAL_HACK
4512 if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4513 if((cr36 & 0x0f) == 0x09) {
4514 r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x00;
4515 }
4516 }
4517#endif
4518#ifdef COMPAQ_HACK
4519 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4520 if((cr36 & 0x0f) == 0x03) {
4521 r30 = 0x20; r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4522 }
4523 }
4524#endif
4525#ifdef ASUS_HACK
4526 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4527 if((cr36 & 0x0f) == 0x02) {
4528 /* r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 2 */
4529 /* r30 = 0x20; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 3 */
4530 /* r30 = 0x60; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 4 */
4531 /* r30 = 0x20; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 5 */
4532 }
4533 }
4534#endif
4535 }
4536
4537 if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) {
4538 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4539 SiS_GenericDelay(SiS_Pr, 0x500);
4540 }
4541 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,r31);
4542 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,r32);
4543 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x33,r33);
4544#endif /* SET_EMI */
4545
4546 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
4547
4548#ifdef SET_EMI
4549 if( (SiS_LCDAEnabled(SiS_Pr, HwInfo)) ||
4550 (SiS_CRT2IsLCD(SiS_Pr, HwInfo)) ) {
4551 if(r30 & 0x40) {
4552 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 5);
4553 if(delaylong) {
4554 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 5);
4555 delaylong = FALSE;
4556 }
4557 SiS_WaitVBRetrace(SiS_Pr,HwInfo);
4558 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4559 SiS_GenericDelay(SiS_Pr, 0x500);
4560 }
4561 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40); /* Enable */
4562 }
4563 }
4564#endif
4565 }
4566 }
4567
4568 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4569 if(SiS_IsVAorLCD(SiS_Pr, HwInfo)) {
4570 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10);
4571 if(delaylong) {
4572 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10);
4573 }
4574 SiS_WaitVBRetrace(SiS_Pr,HwInfo);
4575 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
4576 SiS_GenericDelay(SiS_Pr, 0x500);
4577 }
4578 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4579 }
4580 }
4581
4582 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4583 SiS_DisplayOn(SiS_Pr);
4584 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xff);
4585
4586 }
4587
4588 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4589 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4590 }
4591
4592#endif /* SIS315H */
4593
4594 }
4595
4596 } else { /* ============ For 301 ================ */
4597
4598 if(HwInfo->jChipType < SIS_315H) {
4599 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4600 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
4601 SiS_PanelDelay(SiS_Pr, HwInfo, 0);
4602 }
4603 }
4604
4605 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
4606 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4607 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4608 if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4609 }
4610 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4611
4612 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
4613
4614 if(HwInfo->jChipType >= SIS_315H) {
4615 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4616 if(!(temp & 0x80)) {
4617 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80); /* BVBDOENABLE=1 */
4618 }
4619 }
4620
4621 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */
4622
4623 SiS_VBLongWait(SiS_Pr);
4624 SiS_DisplayOn(SiS_Pr);
4625 if(HwInfo->jChipType >= SIS_315H) {
4626 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4627 }
4628 SiS_VBLongWait(SiS_Pr);
4629
4630 if(HwInfo->jChipType < SIS_315H) {
4631 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4632 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4633 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00);
4634 }
4635 }
4636
4637 }
4638
4639 } else { /* =================== For LVDS ================== */
4640
4641 if(HwInfo->jChipType < SIS_315H) {
4642
4643#ifdef SIS300 /* 300 series */
4644
4645 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4646 if(HwInfo->jChipType == SIS_730) {
4647 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4648 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4649 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4650 }
4651 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
4652 if(!(SiS_CR36BIOSWord23d(SiS_Pr,HwInfo))) {
4653 SiS_PanelDelay(SiS_Pr, HwInfo, 0);
4654 }
4655 }
4656
4657 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4658 SiS_DisplayOn(SiS_Pr);
4659 SiS_UnLockCRT2(SiS_Pr,HwInfo);
4660 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4661 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4662 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4663 } else {
4664 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4665 }
4666
4667 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4668 if(!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) {
4669 SiS_WaitVBRetrace(SiS_Pr, HwInfo);
4670 SiS_SetCH700x(SiS_Pr,0x0B0E);
4671 }
4672 }
4673
4674 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4675 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4676 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4677 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
4678 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4679 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4680 }
4681 SiS_WaitVBRetrace(SiS_Pr, HwInfo);
4682 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00);
4683 }
4684 }
4685 }
4686
4687#endif /* SIS300 */
4688
4689 } else {
4690
4691#ifdef SIS315H /* 315 series */
4692
4693 if(!(SiS_IsNotM650orLater(SiS_Pr,HwInfo))) {
4694 if(HwInfo->jChipType < SIS_340) {
4695 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x18);
4696 }
4697 }
4698
4699 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4700 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4701 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
4702 SiS_PanelDelay(SiS_Pr, HwInfo, 0);
4703 }
4704 }
4705
4706 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4707 SiS_UnLockCRT2(SiS_Pr,HwInfo);
4708
4709 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4710
4711 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4712 temp = SiS_GetCH701x(SiS_Pr,0x66);
4713 temp &= 0x20;
4714 SiS_Chrontel701xBLOff(SiS_Pr);
4715 }
4716
4717 if(HwInfo->jChipType != SIS_550) {
4718 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4719 }
4720
4721 if(HwInfo->jChipType == SIS_740) {
4722 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4723 if(SiS_IsLCDOrLCDA(SiS_Pr, HwInfo)) {
4724 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4725 }
4726 }
4727 }
4728
4729 temp1 = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4730 if(!(temp1 & 0x80)) {
4731 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
4732 }
4733
4734 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4735 if(temp) {
4736 SiS_Chrontel701xBLOn(SiS_Pr, HwInfo);
4737 }
4738 }
4739
4740 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4741 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4742 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4743 if(HwInfo->jChipType == SIS_550) {
4744 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x40);
4745 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x10);
4746 }
4747 }
4748 } else if(SiS_IsVAMode(SiS_Pr,HwInfo)) {
4749 if(HwInfo->jChipType != SIS_740) {
4750 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4751 }
4752 }
4753
4754 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4755 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4756 }
4757
4758 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4759 if(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo)) {
4760 SiS_Chrontel701xOn(SiS_Pr,HwInfo);
4761 }
4762 if( (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
4763 (SiS_IsLCDOrLCDA(SiS_Pr,HwInfo)) ) {
4764 SiS_ChrontelDoSomething1(SiS_Pr,HwInfo);
4765 }
4766 }
4767
4768 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4769 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4770 if( (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
4771 (SiS_IsLCDOrLCDA(SiS_Pr,HwInfo)) ) {
4772 SiS_Chrontel701xBLOn(SiS_Pr, HwInfo);
4773 SiS_ChrontelInitTVVSync(SiS_Pr,HwInfo);
4774 }
4775 }
4776 } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4777 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4778 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4779 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4780 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00);
4781 }
4782 }
4783 }
4784
4785#endif /* SIS315H */
4786
4787 } /* 310 series */
4788
4789 } /* LVDS */
4790
4791}
4792
4793/*********************************************/
4794/* SET PART 1 REGISTER GROUP */
4795/*********************************************/
4796
4797/* Set CRT2 OFFSET / PITCH */
4798static void
4799SiS_SetCRT2Offset(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
4800 USHORT RRTI, PSIS_HW_INFO HwInfo)
4801{
4802 USHORT offset;
4803 UCHAR temp;
4804
4805 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return;
4806
4807 offset = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,RRTI,HwInfo);
4808
4809 if((SiS_Pr->SiS_LCDResInfo == Panel_640x480_2) ||
4810 (SiS_Pr->SiS_LCDResInfo == Panel_640x480_3)) {
4811 offset >>= 1;
4812 }
4813
4814 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(offset & 0xFF));
4815 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,(offset >> 8));
4816 temp = (UCHAR)(((offset >> 3) & 0xFF) + 1);
4817 if(offset % 8) temp++;
4818 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,temp);
4819}
4820
4821/* Set CRT2 sync and PanelLink mode */
4822static void
4823SiS_SetCRT2Sync(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT RefreshRateTableIndex,
4824 PSIS_HW_INFO HwInfo)
4825{
4826 USHORT tempah=0,tempbl,infoflag;
4827
4828 tempbl = 0xC0;
4829
4830 if(SiS_Pr->UseCustomMode) {
4831 infoflag = SiS_Pr->CInfoFlag;
4832 } else {
4833 infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
4834 }
4835
4836 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { /* LVDS */
4837
4838 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
4839 tempah = 0;
4840 } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) {
4841 tempah = SiS_Pr->SiS_LCDInfo;
4842 } else tempah = infoflag >> 8;
4843 tempah &= 0xC0;
4844 tempah |= 0x20;
4845 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4846 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4847 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
4848 (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
4849 tempah |= 0xf0;
4850 }
4851 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
4852 (SiS_Pr->SiS_IF_DEF_DSTN) ||
4853 (SiS_Pr->SiS_IF_DEF_TRUMPION) ||
4854 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ) {
4855 tempah |= 0x30;
4856 }
4857 }
4858 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
4859 if(HwInfo->jChipType >= SIS_315H) {
4860 tempah >>= 3;
4861 tempah &= 0x18;
4862 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xE7,tempah);
4863 /* Don't care about 12/18/24 bit mode - TV is via VGA, not PL */
4864 } else {
4865 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,0xe0);
4866 }
4867 } else {
4868 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4869 }
4870
4871 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
4872
4873 if(HwInfo->jChipType < SIS_315H) {
4874
4875#ifdef SIS300 /* ---- 300 series --- */
4876
4877 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { /* 630 - 301B(-DH) */
4878
4879 tempah = infoflag >> 8;
4880 tempbl = 0;
4881 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4882 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4883 tempah = SiS_Pr->SiS_LCDInfo;
4884 tempbl = (tempah >> 6) & 0x03;
4885 }
4886 }
4887 tempah &= 0xC0;
4888 tempah |= 0x20;
4889 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4890 tempah |= 0xc0;
4891 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4892 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
4893 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
4894 }
4895
4896 } else { /* 630 - 301 */
4897
4898 tempah = infoflag >> 8;
4899 tempah &= 0xC0;
4900 tempah |= 0x20;
4901 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4902 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4903
4904 }
4905
4906#endif /* SIS300 */
4907
4908 } else {
4909
4910#ifdef SIS315H /* ------- 315 series ------ */
4911
4912 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { /* 315 - LVDS */
4913
4914 tempbl = 0;
4915 if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
4916 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
4917 tempah = infoflag >> 8;
4918 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4919 tempbl = ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6);
4920 }
4921 } else if((SiS_Pr->SiS_CustomT == CUT_CLEVO1400) &&
4922 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)) {
4923 tempah = infoflag >> 8;
4924 tempbl = 0x03;
4925 } else {
4926 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
4927 tempbl = (tempah >> 6) & 0x03;
4928 tempbl |= 0x08;
4929 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempbl |= 0x04;
4930 }
4931 tempah &= 0xC0;
4932 tempah |= 0x20;
4933 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4934 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) tempah |= 0xc0;
4935 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4936 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
4937 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4938 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
4939 }
4940 }
4941
4942 } else { /* 315 - TMDS */
4943
4944 tempah = tempbl = infoflag >> 8;
4945 if(!SiS_Pr->UseCustomMode) {
4946 tempbl = 0;
4947 if((SiS_Pr->SiS_VBType & VB_SIS301C) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
4948 if(ModeNo <= 0x13) {
4949 tempah = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
4950 }
4951 }
4952 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
4953 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
4954 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4955 tempah = SiS_Pr->SiS_LCDInfo;
4956 tempbl = (tempah >> 6) & 0x03;
4957 }
4958 }
4959 }
4960 }
4961 tempah &= 0xC0;
4962 tempah |= 0x20;
4963 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4964 if(SiS_Pr->SiS_VBType & VB_NoLCD) {
4965 /* Imitate BIOS bug */
4966 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempah |= 0xc0;
4967 }
4968 if((SiS_Pr->SiS_VBType & VB_SIS301C) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
4969 tempah >>= 3;
4970 tempah &= 0x18;
4971 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xe7,tempah);
4972 } else {
4973 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4974 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
4975 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4976 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
4977 }
4978 }
4979 }
4980
4981 }
4982#endif /* SIS315H */
4983 }
4984 }
4985}
4986
4987/* Set CRT2 FIFO on 300/630/730 */
4988#ifdef SIS300
4989static void
4990SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,USHORT ModeNo,
4991 PSIS_HW_INFO HwInfo)
4992{
4993 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
4994 USHORT temp,index;
4995 USHORT modeidindex,refreshratetableindex;
4996 USHORT VCLK=0,MCLK,colorth=0,data2=0;
4997 USHORT tempal, tempah, tempbx, tempcl, tempax;
4998 USHORT CRT1ModeNo,CRT2ModeNo;
4999 USHORT SelectRate_backup;
5000 ULONG data,eax;
5001 const UCHAR LatencyFactor[] = {
5002 97, 88, 86, 79, 77, 00, /*; 64 bit BQ=2 */
5003 00, 87, 85, 78, 76, 54, /*; 64 bit BQ=1 */
5004 97, 88, 86, 79, 77, 00, /*; 128 bit BQ=2 */
5005 00, 79, 77, 70, 68, 48, /*; 128 bit BQ=1 */
5006 80, 72, 69, 63, 61, 00, /*; 64 bit BQ=2 */
5007 00, 70, 68, 61, 59, 37, /*; 64 bit BQ=1 */
5008 86, 77, 75, 68, 66, 00, /*; 128 bit BQ=2 */
5009 00, 68, 66, 59, 57, 37 /*; 128 bit BQ=1 */
5010 };
5011 const UCHAR LatencyFactor730[] = {
5012 69, 63, 61,
5013 86, 79, 77,
5014 103, 96, 94,
5015 120,113,111,
5016 137,130,128, /* <-- last entry, data below */
5017 137,130,128, /* to avoid using illegal values */
5018 137,130,128,
5019 137,130,128,
5020 137,130,128,
5021 137,130,128,
5022 137,130,128,
5023 137,130,128,
5024 137,130,128,
5025 137,130,128,
5026 137,130,128,
5027 137,130,128,
5028 };
5029 const UCHAR ThLowB[] = {
5030 81, 4, 72, 6, 88, 8,120,12,
5031 55, 4, 54, 6, 66, 8, 90,12,
5032 42, 4, 45, 6, 55, 8, 75,12
5033 };
5034 const UCHAR ThTiming[] = {
5035 1, 2, 2, 3, 0, 1, 1, 2
5036 };
5037
5038 SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;
5039
5040 if(!SiS_Pr->CRT1UsesCustomMode) {
5041
5042 CRT1ModeNo = SiS_Pr->SiS_CRT1Mode; /* get CRT1 ModeNo */
5043 SiS_SearchModeID(SiS_Pr, &CRT1ModeNo, &modeidindex);
5044 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
5045 SiS_Pr->SiS_SelectCRT2Rate = 0;
5046 refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT1ModeNo, modeidindex, HwInfo);
5047
5048 if(CRT1ModeNo >= 0x13) {
5049 index = SiS_Pr->SiS_RefIndex[refreshratetableindex].Ext_CRTVCLK;
5050 index &= 0x3F;
5051 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; /* Get VCLK */
5052
5053 colorth = SiS_GetColorDepth(SiS_Pr,CRT1ModeNo,modeidindex); /* Get colordepth */
5054 colorth >>= 1;
5055 if(!colorth) colorth++;
5056 }
5057
5058 } else {
5059
5060 CRT1ModeNo = 0xfe;
5061 VCLK = SiS_Pr->CSRClock_CRT1; /* Get VCLK */
5062 data2 = (SiS_Pr->CModeFlag_CRT1 & ModeTypeMask) - 2;
5063 switch(data2) { /* Get color depth */
5064 case 0 : colorth = 1; break;
5065 case 1 : colorth = 1; break;
5066 case 2 : colorth = 2; break;
5067 case 3 : colorth = 2; break;
5068 case 4 : colorth = 3; break;
5069 case 5 : colorth = 4; break;
5070 default: colorth = 2;
5071 }
5072
5073 }
5074
5075 if(CRT1ModeNo >= 0x13) {
5076 if(HwInfo->jChipType == SIS_300) {
5077 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A);
5078 } else {
5079 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A);
5080 }
5081 index &= 0x07;
5082 MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK; /* Get MCLK */
5083
5084 data2 = (colorth * VCLK) / MCLK;
5085
5086 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
5087 temp = ((temp & 0x00FF) >> 6) << 1;
5088 if(temp == 0) temp = 1;
5089 temp <<= 2;
5090 temp &= 0xff;
5091
5092 data2 = temp - data2;
5093
5094 if((28 * 16) % data2) {
5095 data2 = (28 * 16) / data2;
5096 data2++;
5097 } else {
5098 data2 = (28 * 16) / data2;
5099 }
5100
5101 if(HwInfo->jChipType == SIS_300) {
5102
5103 tempah = SiS_GetReg(SiS_Pr->SiS_P3c4,0x18);
5104 tempah &= 0x62;
5105 tempah >>= 1;
5106 tempal = tempah;
5107 tempah >>= 3;
5108 tempal |= tempah;
5109 tempal &= 0x07;
5110 tempcl = ThTiming[tempal];
5111 tempbx = SiS_GetReg(SiS_Pr->SiS_P3c4,0x16);
5112 tempbx >>= 6;
5113 tempah = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
5114 tempah >>= 4;
5115 tempah &= 0x0c;
5116 tempbx |= tempah;
5117 tempbx <<= 1;
5118 tempal = ThLowB[tempbx + 1];
5119 tempal *= tempcl;
5120 tempal += ThLowB[tempbx];
5121 data = tempal;
5122
5123 } else if(HwInfo->jChipType == SIS_730) {
5124
5125#ifdef LINUX_KERNEL
5126 SiS_SetRegLong(0xcf8,0x80000050);
5127 eax = SiS_GetRegLong(0xcfc);
5128#else
5129 eax = pciReadLong(0x00000000, 0x50);
5130#endif
5131 tempal = (USHORT)(eax >> 8);
5132 tempal &= 0x06;
5133 tempal <<= 5;
5134
5135#ifdef LINUX_KERNEL
5136 SiS_SetRegLong(0xcf8,0x800000A0);
5137 eax = SiS_GetRegLong(0xcfc);
5138#else
5139 eax = pciReadLong(0x00000000, 0xA0);
5140#endif
5141 temp = (USHORT)(eax >> 28);
5142 temp &= 0x0F;
5143 tempal |= temp;
5144
5145 tempbx = tempal; /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */
5146 tempbx = 0; /* -- do it like the BIOS anyway... */
5147 tempax = tempbx;
5148 tempbx &= 0xc0;
5149 tempbx >>= 6;
5150 tempax &= 0x0f;
5151 tempax *= 3;
5152 tempbx += tempax;
5153
5154 data = LatencyFactor730[tempbx];
5155 data += 15;
5156 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
5157 if(!(temp & 0x80)) data += 5;
5158
5159 } else {
5160
5161 index = 0;
5162 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
5163 if(temp & 0x0080) index += 12;
5164
5165#ifdef LINUX_KERNEL
5166 SiS_SetRegLong(0xcf8,0x800000A0);
5167 eax = SiS_GetRegLong(0xcfc);
5168#else
5169 /* We use pci functions X offers. We use tag 0, because
5170 * we want to read/write to the host bridge (which is always
5171 * 00:00.0 on 630, 730 and 540), not the VGA device.
5172 */
5173 eax = pciReadLong(0x00000000, 0xA0);
5174#endif
5175 temp = (USHORT)(eax >> 24);
5176 if(!(temp&0x01)) index += 24;
5177
5178#ifdef LINUX_KERNEL
5179 SiS_SetRegLong(0xcf8,0x80000050);
5180 eax = SiS_GetRegLong(0xcfc);
5181#else
5182 eax = pciReadLong(0x00000000, 0x50);
5183#endif
5184 temp=(USHORT)(eax >> 24);
5185 if(temp & 0x01) index += 6;
5186
5187 temp = (temp & 0x0F) >> 1;
5188 index += temp;
5189
5190 data = LatencyFactor[index];
5191 data += 15;
5192 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
5193 if(!(temp & 0x80)) data += 5;
5194 }
5195
5196 data += data2; /* CRT1 Request Period */
5197
5198 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5199 SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5200
5201 if(!SiS_Pr->UseCustomMode) {
5202
5203 CRT2ModeNo = ModeNo;
5204 SiS_SearchModeID(SiS_Pr, &CRT2ModeNo, &modeidindex);
5205
5206 refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT2ModeNo, modeidindex, HwInfo);
5207
5208 index = SiS_GetVCLK2Ptr(SiS_Pr,CRT2ModeNo,modeidindex,
5209 refreshratetableindex,HwInfo);
5210 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; /* Get VCLK */
5211
5212 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
5213 if(SiS_Pr->SiS_UseROM) {
5214 if(ROMAddr[0x220] & 0x01) {
5215 VCLK = ROMAddr[0x229] | (ROMAddr[0x22a] << 8);
5216 }
5217 }
5218 }
5219
5220 } else {
5221
5222 CRT2ModeNo = 0xfe;
5223 VCLK = SiS_Pr->CSRClock; /* Get VCLK */
5224
5225 }
5226
5227 colorth = SiS_GetColorDepth(SiS_Pr,CRT2ModeNo,modeidindex); /* Get colordepth */
5228 colorth >>= 1;
5229 if(!colorth) colorth++;
5230
5231 data = data * VCLK * colorth;
5232 if(data % (MCLK << 4)) {
5233 data = data / (MCLK << 4);
5234 data++;
5235 } else {
5236 data = data / (MCLK << 4);
5237 }
5238
5239 if(data <= 6) data = 6;
5240 if(data > 0x14) data = 0x14;
5241
5242 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x01);
5243 if(HwInfo->jChipType == SIS_300) {
5244 if(data <= 0x0f) temp = (temp & (~0x1F)) | 0x13;
5245 else temp = (temp & (~0x1F)) | 0x16;
5246 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
5247 temp = (temp & (~0x1F)) | 0x13;
5248 }
5249 } else {
5250 if( ( (HwInfo->jChipType == SIS_630) ||
5251 (HwInfo->jChipType == SIS_730) ) &&
5252 (HwInfo->jChipRevision >= 0x30) ) /* 630s or 730(s?) */
5253 {
5254 temp = (temp & (~0x1F)) | 0x1b;
5255 } else {
5256 temp = (temp & (~0x1F)) | 0x16;
5257 }
5258 }
5259 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0xe0,temp);
5260
5261 if( (HwInfo->jChipType == SIS_630) &&
5262 (HwInfo->jChipRevision >= 0x30) ) /* 630s, NOT 730 */
5263 {
5264 if(data > 0x13) data = 0x13;
5265 }
5266 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,0xe0,data);
5267
5268 } else { /* If mode <= 0x13, we just restore everything */
5269
5270 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5271 SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5272
5273 }
5274}
5275#endif
5276
5277/* Set CRT2 FIFO on 315/330 series */
5278#ifdef SIS315H
5279static void
5280SiS_SetCRT2FIFO_310(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
5281{
5282 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3B);
5283 if( (HwInfo->jChipType == SIS_760) &&
5284 (SiS_Pr->SiS_SysFlags & SF_760LFB) &&
5285 (SiS_Pr->SiS_ModeType == Mode32Bpp) &&
5286 (SiS_Pr->SiS_VGAHDE >= 1280) &&
5287 (SiS_Pr->SiS_VGAVDE >= 1024) ) {
5288 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x03);
5289 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3b);
5290 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5291 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x01);
5292 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5293 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,0x6e);
5294 } else {
5295 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3f,0x04);
5296 }
5297
5298}
5299#endif
5300
5301static USHORT
5302SiS_GetVGAHT2(SiS_Private *SiS_Pr)
5303{
5304 ULONG tempax,tempbx;
5305
5306 tempbx = (SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) * SiS_Pr->SiS_RVBHCMAX;
5307 tempax = (SiS_Pr->SiS_VT - SiS_Pr->SiS_VDE) * SiS_Pr->SiS_RVBHCFACT;
5308 tempax = (tempax * SiS_Pr->SiS_HT) / tempbx;
5309 return((USHORT)tempax);
5310}
5311
5312/* Set Part 1 / SiS bridge slave mode */
5313static void
5314SiS_SetGroup1_301(SiS_Private *SiS_Pr, USHORT ModeNo,USHORT ModeIdIndex,
5315 PSIS_HW_INFO HwInfo,USHORT RefreshRateTableIndex)
5316{
5317 USHORT push1,push2;
5318 USHORT tempax,tempbx,tempcx,temp;
5319 USHORT resinfo,modeflag,xres=0;
5320 unsigned char p1_7, p1_8;
5321
5322 if(ModeNo <= 0x13) {
5323 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5324 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
5325 } else if(SiS_Pr->UseCustomMode) {
5326 modeflag = SiS_Pr->CModeFlag;
5327 resinfo = 0;
5328 xres = SiS_Pr->CHDisplay;
5329 } else {
5330 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5331 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
5332 xres = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes;
5333 }
5334
5335 /* The following is only done if bridge is in slave mode: */
5336
5337 if((HwInfo->jChipType >= SIS_661) && (ModeNo > 0x13)) {
5338 if(xres >= 1600) {
5339 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x31,0x04);
5340 }
5341 }
5342
5343 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0xff); /* set MAX HT */
5344
5345 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) modeflag |= Charx8Dot;
5346
5347 if(modeflag & Charx8Dot) tempcx = 0x08;
5348 else tempcx = 0x09;
5349
5350 tempax = SiS_Pr->SiS_VGAHDE; /* 0x04 Horizontal Display End */
5351 if(modeflag & HalfDCLK) tempax >>= 1;
5352 tempax = ((tempax / tempcx) - 1) & 0xff;
5353 tempbx = tempax;
5354
5355 temp = tempax;
5356 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,temp);
5357
5358 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5359 if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
5360 temp += 2;
5361 }
5362 }
5363 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
5364 if(resinfo == SIS_RI_800x600) temp -= 2;
5365 }
5366 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x05,temp); /* 0x05 Horizontal Display Start */
5367
5368 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x06,0x03); /* 0x06 Horizontal Blank end */
5369
5370 tempax = 0xFFFF;
5371 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempax = SiS_GetVGAHT2(SiS_Pr);
5372 if(tempax >= SiS_Pr->SiS_VGAHT) tempax = SiS_Pr->SiS_VGAHT;
5373 if(modeflag & HalfDCLK) tempax >>= 1;
5374 tempax = (tempax / tempcx) - 5;
5375 tempcx = tempax;
5376
5377 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
5378 temp = tempcx - 1;
5379 if(!(modeflag & HalfDCLK)) {
5380 temp -= 6;
5381 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
5382 temp -= 2;
5383 if(ModeNo > 0x13) temp -= 10;
5384 }
5385 }
5386 } else {
5387 tempcx = (tempcx + tempbx) >> 1;
5388 temp = (tempcx & 0x00FF) + 2;
5389 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5390 temp--;
5391 if(!(modeflag & HalfDCLK)) {
5392 if((modeflag & Charx8Dot)) {
5393 temp += 4;
5394 if(SiS_Pr->SiS_VGAHDE >= 800) temp -= 6;
5395 if(HwInfo->jChipType >= SIS_315H) {
5396 if(SiS_Pr->SiS_VGAHDE == 800) temp += 2;
5397 }
5398 }
5399 }
5400 } else {
5401 if(!(modeflag & HalfDCLK)) {
5402 temp -= 4;
5403 if((SiS_Pr->SiS_LCDResInfo != Panel_1280x960) &&
5404 (SiS_Pr->SiS_LCDResInfo != Panel_1600x1200)) {
5405 if(SiS_Pr->SiS_VGAHDE >= 800) {
5406 temp -= 7;
5407 if(HwInfo->jChipType < SIS_315H) {
5408 if(SiS_Pr->SiS_ModeType == ModeEGA) {
5409 if(SiS_Pr->SiS_VGAVDE == 1024) {
5410 temp += 15;
5411 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024)
5412 temp += 7;
5413 }
5414 }
5415 }
5416 if(SiS_Pr->SiS_LCDResInfo != Panel_1400x1050) {
5417 if(SiS_Pr->SiS_VGAHDE >= 1280) {
5418 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) temp += 28;
5419 }
5420 }
5421 }
5422 }
5423 }
5424 }
5425 }
5426
5427 p1_7 = temp;
5428 p1_8 = 0x00;
5429
5430 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5431 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
5432 if(ModeNo <= 0x01) {
5433 p1_7 = 0x2a;
5434 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) p1_8 = 0x61;
5435 else p1_8 = 0x41;
5436 } else if(SiS_Pr->SiS_ModeType == ModeText) {
5437 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) p1_7 = 0x54;
5438 else p1_7 = 0x55;
5439 p1_8 = 0x00;
5440 } else if(ModeNo <= 0x13) {
5441 if(modeflag & HalfDCLK) {
5442 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
5443 p1_7 = 0x30;
5444 p1_8 = 0x03;
5445 } else {
5446 p1_7 = 0x2f;
5447 p1_8 = 0x02;
5448 }
5449 } else {
5450 p1_7 = 0x5b;
5451 p1_8 = 0x03;
5452 }
5453 } else if( ((HwInfo->jChipType >= SIS_315H) &&
5454 ((ModeNo == 0x50) || (ModeNo == 0x56) || (ModeNo == 0x53))) ||
5455 ((HwInfo->jChipType < SIS_315H) &&
5456 (resinfo == SIS_RI_320x200 || resinfo == SIS_RI_320x240)) ) {
5457 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
5458 p1_7 = 0x30,
5459 p1_8 = 0x03;
5460 } else {
5461 p1_7 = 0x2f;
5462 p1_8 = 0x03;
5463 }
5464 }
5465 }
5466 }
5467
5468 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
5469 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p)) {
5470 p1_7 = 0x63;
5471 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) p1_7 = 0x55;
5472 }
5473 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
5474 if(!(modeflag & HalfDCLK)) {
5475 p1_7 = 0xb2;
5476 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
5477 p1_7 = 0xab;
5478 }
5479 }
5480 } else {
5481 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
5482 if(modeflag & HalfDCLK) p1_7 = 0x30;
5483 }
5484 }
5485 }
5486
5487 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,p1_7); /* 0x07 Horizontal Retrace Start */
5488 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,p1_8); /* 0x08 Horizontal Retrace End */
5489
5490 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x03); /* 0x18 SR08 (FIFO Threshold?) */
5491
5492 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x19,0xF0);
5493
5494 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,0xFF); /* 0x09 Set Max VT */
5495
5496 tempcx = 0x121;
5497 tempbx = SiS_Pr->SiS_VGAVDE; /* 0x0E Vertical Display End */
5498 if (tempbx == 357) tempbx = 350;
5499 else if(tempbx == 360) tempbx = 350;
5500 else if(tempbx == 375) tempbx = 350;
5501 else if(tempbx == 405) tempbx = 400;
5502 else if(tempbx == 420) tempbx = 400;
5503 else if(tempbx == 525) tempbx = 480;
5504 push2 = tempbx;
5505 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5506 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5507 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
5508 if (tempbx == 350) tempbx += 5;
5509 else if(tempbx == 480) tempbx += 5;
5510 }
5511 }
5512 }
5513 tempbx -= 2;
5514 temp = tempbx & 0x00FF;
5515 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,temp); /* 0x10 vertical Blank Start */
5516
5517 tempbx = push2;
5518 tempbx--;
5519 temp = tempbx & 0x00FF;
5520#if 0
5521 /* Missing code from 630/301B 2.04.5a and 650/302LV 1.10.6s (calles int 2f) */
5522 if(xxx()) {
5523 if(temp == 0xdf) temp = 0xda;
5524 }
5525#endif
5526 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp);
5527
5528 temp = 0;
5529 if(modeflag & DoubleScanMode) temp |= 0x80;
5530 if(HwInfo->jChipType >= SIS_661) {
5531 if(tempbx & 0x0200) temp |= 0x20;
5532 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x0B,0x5F,temp);
5533 if(tempbx & 0x0100) tempcx |= 0x000a;
5534 if(tempbx & 0x0400) tempcx |= 0x1200;
5535 } else {
5536 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,temp);
5537 if(tempbx & 0x0100) tempcx |= 0x0002;
5538 if(tempbx & 0x0400) tempcx |= 0x0600;
5539 }
5540
5541 if(tempbx & 0x0200) tempcx |= 0x0040;
5542
5543 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,0x00); /* 0x11 Vertical Blank End */
5544
5545 tempax = (SiS_Pr->SiS_VGAVT - tempbx) >> 2;
5546
5547 if((ModeNo > 0x13) || (HwInfo->jChipType < SIS_315H)) {
5548 if(resinfo != SIS_RI_1280x1024) {
5549 tempbx += (tempax << 1);
5550 }
5551 } else if(HwInfo->jChipType >= SIS_315H) {
5552 if(SiS_Pr->SiS_LCDResInfo != Panel_1400x1050) {
5553 tempbx += (tempax << 1);
5554 }
5555 }
5556
5557 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
5558 tempbx -= 10;
5559 } else {
5560 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
5561 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
5562 tempbx += 40;
5563 if(HwInfo->jChipType >= SIS_315H) {
5564 if(SiS_Pr->SiS_VGAHDE == 800) tempbx += 10;
5565 }
5566 }
5567 }
5568 }
5569 tempax >>= 2;
5570 tempax++;
5571 tempax += tempbx;
5572 push1 = tempax;
5573 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
5574 if(tempbx <= 513) {
5575 if(tempax >= 513) tempbx = 513;
5576 }
5577 }
5578 temp = tempbx & 0x00FF;
5579 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp); /* 0x0C Vertical Retrace Start */
5580
5581 tempbx--;
5582 temp = tempbx & 0x00FF;
5583 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,temp);
5584
5585 if(tempbx & 0x0100) tempcx |= 0x0008;
5586
5587 if(tempbx & 0x0200) {
5588 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x0B,0x20);
5589 }
5590 tempbx++;
5591
5592 if(tempbx & 0x0100) tempcx |= 0x0004;
5593 if(tempbx & 0x0200) tempcx |= 0x0080;
5594 if(tempbx & 0x0400) {
5595 if(HwInfo->jChipType >= SIS_661) tempcx |= 0x0800;
5596 else if(SiS_Pr->SiS_VBType & VB_SIS301) tempcx |= 0x0800;
5597 else tempcx |= 0x0C00;
5598 }
5599
5600 tempbx = push1;
5601 temp = tempbx & 0x000F;
5602 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,temp); /* 0x0D vertical Retrace End */
5603
5604 if(tempbx & 0x0010) tempcx |= 0x2000;
5605
5606 temp = tempcx & 0x00FF;
5607 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp); /* 0x0A CR07 */
5608
5609 temp = (tempcx & 0xFF00) >> 8;
5610 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp); /* 0x17 SR0A */
5611
5612 tempax = modeflag;
5613 temp = (tempax & 0xFF00) >> 8;
5614 temp = (temp >> 1) & 0x09;
5615 if(!(SiS_Pr->SiS_VBType & VB_SIS301)) temp |= 0x01; /* Always 8 dotclock */
5616 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* 0x16 SR01 */
5617
5618 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,0x00); /* 0x0F CR14 */
5619
5620 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,0x00); /* 0x12 CR17 */
5621
5622 temp = 0x00;
5623 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5624 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
5625 temp = 0x80;
5626 }
5627 }
5628 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* 0x1A SR0E */
5629
5630 temp = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
5631 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);
5632}
5633
5634/* Setup panel link
5635 * This is used for LVDS, LCDA and Chrontel TV output
5636 * 300/LVDS+TV, 300/301B-DH, 315/LVDS+TV, 315/LCDA
5637 */
5638static void
5639SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
5640 PSIS_HW_INFO HwInfo, USHORT RefreshRateTableIndex)
5641{
5642 USHORT modeflag,resinfo;
5643 USHORT push2,tempax,tempbx,tempcx,temp;
5644 ULONG tempeax=0,tempebx,tempecx,tempvcfact=0;
5645 BOOLEAN islvds = FALSE, issis = FALSE, chkdclkfirst = FALSE;
5646#ifdef SIS300
5647 USHORT crt2crtc;
5648#endif
5649#ifdef SIS315H
5650 USHORT pushcx;
5651#endif
5652
5653 if(ModeNo <= 0x13) {
5654 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5655 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
5656#ifdef SIS300
5657 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
5658#endif
5659 } else if(SiS_Pr->UseCustomMode) {
5660 modeflag = SiS_Pr->CModeFlag;
5661 resinfo = 0;
5662#ifdef SIS300
5663 crt2crtc = 0;
5664#endif
5665 } else {
5666 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5667 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
5668#ifdef SIS300
5669 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
5670#endif
5671 }
5672
5673 /* is lvds if really LVDS, or 301B-DH with external LVDS transmitter */
5674 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
5675 islvds = TRUE;
5676 }
5677
5678 /* is really sis if sis bridge, but not 301B-DH */
5679 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
5680 issis = TRUE;
5681 }
5682
5683 if((HwInfo->jChipType >= SIS_315H) && (islvds) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA))) {
5684 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
5685 chkdclkfirst = TRUE;
5686 }
5687 }
5688
5689#ifdef SIS315H
5690 if((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
5691 if(IS_SIS330) {
5692 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5693 } else if(IS_SIS740) {
5694 if(islvds) {
5695 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5696 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x03);
5697 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5698 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5699 }
5700 } else {
5701 if(islvds) {
5702 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5703 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x00);
5704 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5705 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2D,0x0f);
5706 if(SiS_Pr->SiS_VBType & VB_SIS301C) {
5707 if((SiS_Pr->SiS_LCDResInfo == Panel_1024x768) ||
5708 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
5709 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x20);
5710 }
5711 }
5712 }
5713 }
5714 }
5715#endif
5716
5717 /* Horizontal */
5718
5719 tempax = SiS_Pr->SiS_LCDHDES;
5720 if(islvds) {
5721 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5722 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
5723 if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) &&
5724 (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
5725 tempax -= 8;
5726 }
5727 }
5728 }
5729 }
5730
5731 temp = (tempax & 0x0007);
5732 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* BPLHDESKEW[2:0] */
5733 temp = (tempax >> 3) & 0x00FF;
5734 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* BPLHDESKEW[10:3] */
5735
5736 tempbx = SiS_Pr->SiS_HDE;
5737 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5738 if((SiS_Pr->SiS_LCDResInfo == Panel_640x480_2) ||
5739 (SiS_Pr->SiS_LCDResInfo == Panel_640x480_3)) {
5740 tempbx >>= 1;
5741 }
5742 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5743 tempbx = SiS_Pr->PanelXRes;
5744 }
5745 }
5746
5747 tempax += tempbx;
5748 if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;
5749
5750 temp = tempax;
5751 if(temp & 0x07) temp += 8;
5752 temp >>= 3;
5753 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp); /* BPLHDEE */
5754
5755 tempcx = (SiS_Pr->SiS_HT - tempbx) >> 2;
5756
5757 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5758 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5759 if(SiS_Pr->PanelHRS != 999) tempcx = SiS_Pr->PanelHRS;
5760 }
5761 }
5762
5763 tempcx += tempax;
5764 if(tempcx >= SiS_Pr->SiS_HT) tempcx -= SiS_Pr->SiS_HT;
5765
5766 temp = (tempcx >> 3) & 0x00FF;
5767 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5768 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5769 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5770 switch(ModeNo) {
5771 case 0x04:
5772 case 0x05:
5773 case 0x0d: temp = 0x56; break;
5774 case 0x10: temp = 0x60; break;
5775 case 0x13: temp = 0x5f; break;
5776 case 0x40:
5777 case 0x41:
5778 case 0x4f:
5779 case 0x43:
5780 case 0x44:
5781 case 0x62:
5782 case 0x56:
5783 case 0x53:
5784 case 0x5d:
5785 case 0x5e: temp = 0x54; break;
5786 }
5787 }
5788 }
5789 }
5790 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,temp); /* BPLHRS */
5791
5792 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5793 temp += 2;
5794 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5795 temp += 8;
5796 if(SiS_Pr->PanelHRE != 999) {
5797 temp = tempcx + SiS_Pr->PanelHRE;
5798 if(temp >= SiS_Pr->SiS_HT) temp -= SiS_Pr->SiS_HT;
5799 temp >>= 3;
5800 }
5801 }
5802 } else {
5803 temp += 10;
5804 }
5805
5806 temp &= 0x1F;
5807 temp |= ((tempcx & 0x07) << 5);
5808#if 0
5809 if(SiS_Pr->SiS_IF_DEF_FSTN) temp = 0x20; /* WRONG? BIOS loads cl, not ah */
5810#endif
5811 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,temp); /* BPLHRE */
5812
5813 /* Vertical */
5814
5815 tempax = SiS_Pr->SiS_VGAVDE;
5816 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5817 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5818 tempax = SiS_Pr->PanelYRes;
5819 }
5820 }
5821
5822 tempbx = SiS_Pr->SiS_LCDVDES + tempax;
5823 if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5824
5825 push2 = tempbx;
5826
5827 tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE;
5828 if(HwInfo->jChipType < SIS_315H) {
5829 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5830 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5831 tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->PanelYRes;
5832 }
5833 }
5834 }
5835 if(islvds) tempcx >>= 1;
5836 else tempcx >>= 2;
5837
5838 if( (SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
5839 (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) &&
5840 (SiS_Pr->PanelVRS != 999) ) {
5841 tempcx = SiS_Pr->PanelVRS;
5842 tempbx += tempcx;
5843 if(issis) tempbx++;
5844 } else {
5845 tempbx += tempcx;
5846 if(HwInfo->jChipType < SIS_315H) tempbx++;
5847 else if(issis) tempbx++;
5848 }
5849
5850 if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT; /* BPLVRS */
5851
5852 temp = tempbx & 0x00FF;
5853 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5854 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5855 if(ModeNo == 0x10) temp = 0xa9;
5856 }
5857 }
5858 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);
5859
5860 tempcx >>= 3;
5861 tempcx++;
5862
5863 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5864 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5865 if(SiS_Pr->PanelVRE != 999) tempcx = SiS_Pr->PanelVRE;
5866 }
5867 }
5868
5869 tempcx += tempbx;
5870 temp = tempcx & 0x000F;
5871 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp); /* BPLVRE */
5872
5873 temp = ((tempbx >> 8) & 0x07) << 3;
5874 if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
5875 if(SiS_Pr->SiS_HDE != 640) {
5876 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
5877 }
5878 } else if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
5879 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) temp |= 0x40;
5880 tempbx = 0x87;
5881 if((HwInfo->jChipType >= SIS_315H) ||
5882 (HwInfo->jChipRevision >= 0x30)) {
5883 tempbx = 0x07;
5884 if((SiS_Pr->SiS_IF_DEF_CH70xx == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
5885 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x03) temp |= 0x80;
5886 }
5887 /* Chrontel 701x operates in 24bit mode (8-8-8, 2x12bit mutliplexed) via VGA2 */
5888 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5889 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5890 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x10) temp |= 0x80;
5891 } else {
5892 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80;
5893 }
5894 }
5895 }
5896 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,tempbx,temp);
5897
5898 tempbx = push2; /* BPLVDEE */
5899
5900 tempcx = SiS_Pr->SiS_LCDVDES; /* BPLVDES */
5901
5902 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5903 switch(SiS_Pr->SiS_LCDResInfo) {
5904 case Panel_640x480:
5905 tempbx = SiS_Pr->SiS_VGAVDE - 1;
5906 tempcx = SiS_Pr->SiS_VGAVDE;
5907 break;
5908 case Panel_800x600:
5909 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5910 if(resinfo == SIS_RI_800x600) tempcx++;
5911 }
5912 break;
5913 case Panel_1024x600:
5914 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5915 if(resinfo == SIS_RI_1024x600) tempcx++;
5916 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
5917 if(resinfo == SIS_RI_800x600) tempcx++;
5918 }
5919 }
5920 break;
5921 case Panel_1024x768:
5922 if(HwInfo->jChipType < SIS_315H) {
5923 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5924 if(resinfo == SIS_RI_1024x768) tempcx++;
5925 }
5926 }
5927 break;
5928 }
5929 }
5930
5931 temp = ((tempbx >> 8) & 0x07) << 3;
5932 temp = temp | ((tempcx >> 8) & 0x07);
5933 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1D,temp);
5934 /* if(SiS_Pr->SiS_IF_DEF_FSTN) tempbx++; */
5935 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1C,tempbx);
5936 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1B,tempcx);
5937
5938 /* Vertical scaling */
5939
5940 if(HwInfo->jChipType < SIS_315H) {
5941
5942#ifdef SIS300 /* 300 series */
5943 tempeax = SiS_Pr->SiS_VGAVDE << 6;
5944 temp = (tempeax % (ULONG)SiS_Pr->SiS_VDE);
5945 tempeax = tempeax / (ULONG)SiS_Pr->SiS_VDE;
5946 if(temp) tempeax++;
5947
5948 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) tempeax = 0x3F;
5949
5950 temp = (USHORT)(tempeax & 0x00FF);
5951 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,temp); /* BPLVCFACT */
5952 tempvcfact = temp;
5953#endif /* SIS300 */
5954
5955 } else {
5956
5957#ifdef SIS315H /* 315 series */
5958 tempeax = SiS_Pr->SiS_VGAVDE << 18;
5959 tempebx = SiS_Pr->SiS_VDE;
5960 temp = (tempeax % tempebx);
5961 tempeax = tempeax / tempebx;
5962 if(temp) tempeax++;
5963 tempvcfact = tempeax;
5964
5965 temp = (USHORT)(tempeax & 0x00FF);
5966 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,temp);
5967 temp = (USHORT)((tempeax & 0x00FF00) >> 8);
5968 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,temp);
5969 temp = (USHORT)((tempeax & 0x00030000) >> 16);
5970 if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
5971 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,temp);
5972
5973 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV)) {
5974 temp = (USHORT)(tempeax & 0x00FF);
5975 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3c,temp);
5976 temp = (USHORT)((tempeax & 0x00FF00) >> 8);
5977 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3b,temp);
5978 temp = (USHORT)(((tempeax & 0x00030000) >> 16) << 6);
5979 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0x3f,temp);
5980 temp = 0;
5981 if(SiS_Pr->SiS_VDE != SiS_Pr->SiS_VGAVDE) temp |= 0x08;
5982 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x30,0xf3,temp);
5983 }
5984#endif
5985
5986 }
5987
5988 /* Horizontal scaling */
5989
5990 tempeax = SiS_Pr->SiS_VGAHDE; /* 1f = ( (VGAHDE * 65536) / ( (VGAHDE * 65536) / HDE ) ) - 1*/
5991 if(chkdclkfirst) {
5992 if(modeflag & HalfDCLK) tempeax >>= 1;
5993 }
5994 tempebx = tempeax << 16;
5995 if(SiS_Pr->SiS_HDE == tempeax) {
5996 tempecx = 0xFFFF;
5997 } else {
5998 tempecx = tempebx / SiS_Pr->SiS_HDE;
5999 if(HwInfo->jChipType >= SIS_315H) {
6000 if(tempebx % SiS_Pr->SiS_HDE) tempecx++;
6001 }
6002 }
6003
6004 if(HwInfo->jChipType >= SIS_315H) {
6005 tempeax = (tempebx / tempecx) - 1;
6006 } else {
6007 tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1;
6008 }
6009 tempecx = (tempecx << 16) | (tempeax & 0xFFFF);
6010 temp = (USHORT)(tempecx & 0x00FF);
6011 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1F,temp);
6012
6013 if(HwInfo->jChipType >= SIS_315H) {
6014 tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
6015 tempbx = (USHORT)(tempeax & 0xFFFF);
6016 } else {
6017 tempeax = SiS_Pr->SiS_VGAVDE << 6;
6018 tempbx = tempvcfact & 0x3f;
6019 if(tempbx == 0) tempbx = 64;
6020 tempeax /= tempbx;
6021 tempbx = (USHORT)(tempeax & 0xFFFF);
6022 }
6023 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tempbx--;
6024 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
6025 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) tempbx = 1;
6026 else if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) tempbx = 1;
6027 }
6028
6029 temp = ((tempbx >> 8) & 0x07) << 3;
6030 temp = temp | ((tempecx >> 8) & 0x07);
6031 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x20,temp);
6032 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x21,tempbx);
6033
6034 tempecx >>= 16; /* BPLHCFACT */
6035 if(!chkdclkfirst) {
6036 if(modeflag & HalfDCLK) tempecx >>= 1;
6037 }
6038 temp = (USHORT)((tempecx & 0xFF00) >> 8);
6039 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x22,temp);
6040 temp = (USHORT)(tempecx & 0x00FF);
6041 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp);
6042
6043#ifdef SIS315H
6044 if(HwInfo->jChipType >= SIS_315H) {
6045 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
6046 if((islvds) || (SiS_Pr->SiS_VBInfo & VB_SIS301LV302LV)) {
6047 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x20);
6048 }
6049 } else {
6050 if(islvds) {
6051 if(HwInfo->jChipType == SIS_740) {
6052 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
6053 } else {
6054 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x23);
6055 }
6056 }
6057 }
6058 }
6059#endif
6060
6061#ifdef SIS300
6062 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
6063 int i;
6064 UCHAR TrumpMode13[4] = { 0x01, 0x10, 0x2c, 0x00 };
6065 UCHAR TrumpMode10_1[4] = { 0x01, 0x10, 0x27, 0x00 };
6066 UCHAR TrumpMode10_2[4] = { 0x01, 0x16, 0x10, 0x00 };
6067
6068 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xbf);
6069 for(i=0; i<5; i++) {
6070 SiS_SetTrumpionBlock(SiS_Pr, &SiS300_TrumpionData[crt2crtc][0]);
6071 }
6072 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6073 if(ModeNo == 0x13) {
6074 for(i=0; i<4; i++) {
6075 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode13[0]);
6076 }
6077 } else if(ModeNo == 0x10) {
6078 for(i=0; i<4; i++) {
6079 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_1[0]);
6080 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_2[0]);
6081 }
6082 }
6083 }
6084 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
6085 }
6086#endif
6087
6088#ifdef SIS315H
6089 if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
6090 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x25,0x00);
6091 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x26,0x00);
6092 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x27,0x00);
6093 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x28,0x87);
6094 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x29,0x5A);
6095 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2A,0x4B);
6096 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x07,0x03);
6097 tempax = SiS_Pr->SiS_HDE; /* Blps = lcdhdee(lcdhdes+HDE) + 64 */
6098 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
6099 SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1;
6100 tempax += 64;
6101 temp = tempax & 0x00FF;
6102 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,temp);
6103 temp = ((tempax & 0xFF00) >> 8) << 3;
6104 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp);
6105 tempax += 32; /* Blpe=lBlps+32 */
6106 temp = tempax & 0x00FF;
6107 if(SiS_Pr->SiS_IF_DEF_FSTN) temp = 0;
6108 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,temp);
6109 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3A,0x00); /* Bflml=0 */
6110 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x007,0x00);
6111
6112 tempax = SiS_Pr->SiS_VDE;
6113 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
6114 SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1;
6115 tempax >>= 1;
6116 temp = tempax & 0x00FF;
6117 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3B,temp);
6118 temp = ((tempax & 0xFF00) >> 8) << 3;
6119 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);
6120
6121 tempeax = SiS_Pr->SiS_HDE;
6122 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
6123 SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempeax >>= 1;
6124 tempeax <<= 2; /* BDxFIFOSTOP = (HDE*4)/128 */
6125 tempebx = 128;
6126 temp = (USHORT)(tempeax % tempebx);
6127 tempeax = tempeax / tempebx;
6128 if(temp) tempeax++;
6129 temp = (USHORT)(tempeax & 0x003F);
6130 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x45,~0x0FF,temp);
6131 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3F,0x00); /* BDxWadrst0 */
6132 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3E,0x00);
6133 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3D,0x10);
6134 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x040,0x00);
6135
6136 tempax = SiS_Pr->SiS_HDE;
6137 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
6138 SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1;
6139 tempax >>= 4; /* BDxWadroff = HDE*4/8/8 */
6140 pushcx = tempax;
6141 temp = tempax & 0x00FF;
6142 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,temp);
6143 temp = ((tempax & 0xFF00) >> 8) << 3;
6144 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x0F8,temp);
6145
6146 tempax = SiS_Pr->SiS_VDE; /* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
6147 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
6148 SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1;
6149 tempeax = (tempax * pushcx);
6150 tempebx = 0x00100000 + tempeax;
6151 temp = (USHORT)tempebx & 0x000000FF;
6152 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,temp);
6153 temp = (USHORT)((tempebx & 0x0000FF00) >> 8);
6154 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,temp);
6155 temp = (USHORT)((tempebx & 0x00FF0000) >> 16);
6156 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,temp);
6157 temp = (USHORT)(((tempebx & 0x01000000) >> 24) << 7);
6158 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x080,temp);
6159
6160 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x03);
6161 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0x50);
6162 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,0x00);
6163 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x01);
6164 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0x38);
6165
6166 if(SiS_Pr->SiS_IF_DEF_FSTN) {
6167 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2b,0x02);
6168 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2c,0x00);
6169 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x00);
6170 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,0x0c);
6171 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,0x00);
6172 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,0x00);
6173 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,0x80);
6174 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,0xA0);
6175 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3a,0x00);
6176 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3b,0xf0);
6177 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3c,0x00);
6178 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3d,0x10);
6179 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3e,0x00);
6180 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3f,0x00);
6181 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,0x10);
6182 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,0x25);
6183 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,0x80);
6184 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,0x14);
6185 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x44,0x03);
6186 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,0x0a);
6187 }
6188 }
6189#endif /* SIS315H */
6190}
6191
6192/* Set Part 1 */
6193static void
6194SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
6195 PSIS_HW_INFO HwInfo, USHORT RefreshRateTableIndex)
6196{
6197#if defined(SIS300) || defined(SIS315H)
6198 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
6199#endif
6200 USHORT temp=0, tempax=0, tempbx=0, tempcx=0, bridgeadd=0;
6201 USHORT pushbx=0, CRT1Index=0, modeflag, resinfo=0;
6202#ifdef SIS315H
6203 USHORT tempbl=0;
6204#endif
6205
6206 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
6207 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
6208 return;
6209 }
6210
6211 if(ModeNo <= 0x13) {
6212 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6213 } else if(SiS_Pr->UseCustomMode) {
6214 modeflag = SiS_Pr->CModeFlag;
6215 } else {
6216 CRT1Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
6217 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
6218 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6219 }
6220
6221 SiS_SetCRT2Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
6222
6223 if( ! ((HwInfo->jChipType >= SIS_315H) &&
6224 (SiS_Pr->SiS_IF_DEF_LVDS == 1) &&
6225 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
6226
6227 if(HwInfo->jChipType < SIS_315H ) {
6228#ifdef SIS300
6229 SiS_SetCRT2FIFO_300(SiS_Pr, ModeNo, HwInfo);
6230#endif
6231 } else {
6232#ifdef SIS315H
6233 SiS_SetCRT2FIFO_310(SiS_Pr, HwInfo);
6234#endif
6235 }
6236
6237 /* 1. Horizontal setup */
6238
6239 if(HwInfo->jChipType < SIS_315H ) {
6240
6241#ifdef SIS300 /* ------------- 300 series --------------*/
6242
6243 temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
6244 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp); /* CRT2 Horizontal Total */
6245
6246 temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
6247 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp); /* CRT2 Horizontal Total Overflow [7:4] */
6248
6249 temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */
6250 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp); /* CRT2 Horizontal Display Enable End */
6251
6252 pushbx = SiS_Pr->SiS_VGAHDE + 12; /* bx BTVGA2HRS 0x0B,0x0C */
6253 tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2;
6254 tempbx = pushbx + tempcx;
6255 tempcx <<= 1;
6256 tempcx += tempbx;
6257
6258 bridgeadd = 12;
6259
6260#endif /* SIS300 */
6261
6262 } else {
6263
6264#ifdef SIS315H /* ------------------- 315/330 series --------------- */
6265
6266 tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HT 0x08,0x09 */
6267 if(modeflag & HalfDCLK) {
6268 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6269 tempcx >>= 1;
6270 } else {
6271 tempax = SiS_Pr->SiS_VGAHDE >> 1;
6272 tempcx = SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE + tempax;
6273 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
6274 tempcx = SiS_Pr->SiS_HT - tempax;
6275 }
6276 }
6277 }
6278 tempcx--;
6279 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,tempcx); /* CRT2 Horizontal Total */
6280 temp = (tempcx >> 4) & 0xF0;
6281 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp); /* CRT2 Horizontal Total Overflow [7:4] */
6282
6283 tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HDEE 0x0A,0x0C */
6284 tempbx = SiS_Pr->SiS_VGAHDE;
6285 tempcx -= tempbx;
6286 tempcx >>= 2;
6287 if(modeflag & HalfDCLK) {
6288 tempbx >>= 1;
6289 tempcx >>= 1;
6290 }
6291 tempbx += 16;
6292
6293 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,tempbx); /* CRT2 Horizontal Display Enable End */
6294
6295 pushbx = tempbx;
6296 tempcx >>= 1;
6297 tempbx += tempcx;
6298 tempcx += tempbx;
6299
6300 bridgeadd = 16;
6301
6302 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6303 if(HwInfo->jChipType >= SIS_661) {
6304 if((SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
6305 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
6306 if(resinfo == SIS_RI_1280x1024) {
6307 tempcx = (tempcx & 0xff00) | 0x30;
6308 } else if(resinfo == SIS_RI_1600x1200) {
6309 tempcx = (tempcx & 0xff00) | 0xff;
6310 }
6311 }
6312 }
6313 }
6314
6315#endif /* SIS315H */
6316
6317 } /* 315/330 series */
6318
6319 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6320
6321 if(SiS_Pr->UseCustomMode) {
6322 tempbx = SiS_Pr->CHSyncStart + bridgeadd;
6323 tempcx = SiS_Pr->CHSyncEnd + bridgeadd;
6324 tempax = SiS_Pr->SiS_VGAHT;
6325 if(modeflag & HalfDCLK) tempax >>= 1;
6326 tempax--;
6327 if(tempcx > tempax) tempcx = tempax;
6328 }
6329
6330 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6331 unsigned char cr4, cr14, cr5, cr15;
6332 if(SiS_Pr->UseCustomMode) {
6333 cr4 = SiS_Pr->CCRT1CRTC[4];
6334 cr14 = SiS_Pr->CCRT1CRTC[14];
6335 cr5 = SiS_Pr->CCRT1CRTC[5];
6336 cr15 = SiS_Pr->CCRT1CRTC[15];
6337 } else {
6338 cr4 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
6339 cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
6340 cr5 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
6341 cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
6342 }
6343 tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3; /* (VGAHRS-3)*8 */
6344 tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3; /* (VGAHRE-3)*8 */
6345 tempcx &= 0x00FF;
6346 tempcx |= (tempbx & 0xFF00);
6347 tempbx += bridgeadd;
6348 tempcx += bridgeadd;
6349 tempax = SiS_Pr->SiS_VGAHT;
6350 if(modeflag & HalfDCLK) tempax >>= 1;
6351 tempax--;
6352 if(tempcx > tempax) tempcx = tempax;
6353 }
6354
6355 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6356 tempbx = 1040;
6357 tempcx = 1044; /* HWCursor bug! */
6358 }
6359
6360 }
6361
6362 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,tempbx); /* CRT2 Horizontal Retrace Start */
6363
6364 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,tempcx); /* CRT2 Horizontal Retrace End */
6365
6366 temp = ((tempbx >> 8) & 0x0F) | ((pushbx >> 4) & 0xF0);
6367 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp); /* Overflow */
6368
6369 /* 2. Vertical setup */
6370
6371 tempcx = SiS_Pr->SiS_VGAVT - 1;
6372 temp = tempcx & 0x00FF;
6373
6374 if(HwInfo->jChipType < SIS_661) {
6375 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6376 if(HwInfo->jChipType < SIS_315H) {
6377 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6378 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
6379 temp--;
6380 }
6381 }
6382 } else {
6383 temp--;
6384 }
6385 } else if(HwInfo->jChipType >= SIS_315H) {
6386 temp--;
6387 }
6388 }
6389 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp); /* CRT2 Vertical Total */
6390
6391 tempbx = SiS_Pr->SiS_VGAVDE - 1;
6392 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,tempbx); /* CRT2 Vertical Display Enable End */
6393
6394 temp = ((tempbx >> 5) & 0x38) | ((tempcx >> 8) & 0x07);
6395 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,temp); /* Overflow */
6396
6397 if((HwInfo->jChipType >= SIS_315H) && (HwInfo->jChipType < SIS_661)) {
6398 tempbx++;
6399 tempax = tempbx;
6400 tempcx++;
6401 tempcx -= tempax;
6402 tempcx >>= 2;
6403 tempbx += tempcx;
6404 if(tempcx < 4) tempcx = 4;
6405 tempcx >>= 2;
6406 tempcx += tempbx;
6407 tempcx++;
6408 } else {
6409 tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1; /* BTVGA2VRS 0x10,0x11 */
6410 tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1; /* BTVGA2VRE 0x11 */
6411 }
6412
6413 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6414 if(SiS_Pr->UseCustomMode) {
6415 tempbx = SiS_Pr->CVSyncStart;
6416 tempcx = SiS_Pr->CVSyncEnd;
6417 }
6418 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6419 unsigned char cr8, cr7, cr13;
6420 if(SiS_Pr->UseCustomMode) {
6421 cr8 = SiS_Pr->CCRT1CRTC[8];
6422 cr7 = SiS_Pr->CCRT1CRTC[7];
6423 cr13 = SiS_Pr->CCRT1CRTC[13];
6424 tempcx = SiS_Pr->CCRT1CRTC[9];
6425 } else {
6426 cr8 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8];
6427 cr7 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
6428 cr13 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
6429 tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
6430 }
6431 tempbx = cr8;
6432 if(cr7 & 0x04) tempbx |= 0x0100;
6433 if(cr7 & 0x80) tempbx |= 0x0200;
6434 if(cr13 & 0x08) tempbx |= 0x0400;
6435 }
6436 }
6437 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,tempbx); /* CRT2 Vertical Retrace Start */
6438
6439 temp = ((tempbx >> 4) & 0x70) | (tempcx & 0x0F);
6440 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,temp); /* CRT2 Vert. Retrace End; Overflow */
6441
6442 /* 3. Panel delay compensation */
6443
6444 if(HwInfo->jChipType < SIS_315H) {
6445
6446#ifdef SIS300 /* ---------- 300 series -------------- */
6447
6448 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6449 temp = 0x20;
6450 if(HwInfo->jChipType == SIS_300) {
6451 temp = 0x10;
6452 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) temp = 0x2c;
6453 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6454 }
6455 if(SiS_Pr->SiS_VBType & VB_SIS301) {
6456 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6457 }
6458 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960) temp = 0x24;
6459 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) temp = 0x2c;
6460 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x08;
6461 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6462 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) temp = 0x2c;
6463 else temp = 0x20;
6464 }
6465 if(SiS_Pr->SiS_UseROM) {
6466 if(ROMAddr[0x220] & 0x80) {
6467 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision)
6468 temp = ROMAddr[0x221];
6469 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)
6470 temp = ROMAddr[0x222];
6471 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)
6472 temp = ROMAddr[0x223];
6473 else
6474 temp = ROMAddr[0x224];
6475 temp &= 0x3c;
6476 }
6477 }
6478 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6479 if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC & 0x3c;
6480 }
6481
6482 } else {
6483 temp = 0x20;
6484 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
6485 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) temp = 0x04;
6486 }
6487 if(SiS_Pr->SiS_UseROM) {
6488 if(ROMAddr[0x220] & 0x80) {
6489 temp = ROMAddr[0x220] & 0x3c;
6490 }
6491 }
6492 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6493 if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC & 0x3c;
6494 }
6495 }
6496
6497 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
6498
6499#endif /* SIS300 */
6500
6501 } else {
6502
6503#ifdef SIS315H /* --------------- 315/330 series ---------------*/
6504
6505 if(HwInfo->jChipType < SIS_661) {
6506
6507 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6508
6509 if(HwInfo->jChipType == SIS_740) temp = 0x03;
6510 else temp = 0x00;
6511
6512 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x0a;
6513 tempbl = 0xF0;
6514 if(HwInfo->jChipType == SIS_650) {
6515 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6516 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F;
6517 }
6518 }
6519
6520 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) {
6521 temp = 0x08;
6522 tempbl = 0;
6523 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
6524 if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0;
6525 }
6526 }
6527
6528 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp); /* Panel Link Delay Compensation */
6529 }
6530
6531 } /* < 661 */
6532
6533 tempax = 0;
6534 if(modeflag & DoubleScanMode) tempax |= 0x80;
6535 if(modeflag & HalfDCLK) tempax |= 0x40;
6536 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax);
6537
6538#endif /* SIS315H */
6539
6540 }
6541
6542 } /* Slavemode */
6543
6544 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6545 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
6546 /* For 301BDH with LCD, we set up the Panel Link */
6547 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
6548 } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6549 SiS_SetGroup1_301(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
6550 }
6551 } else {
6552 if(HwInfo->jChipType < SIS_315H) {
6553 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
6554 } else {
6555 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6556 if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
6557 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex, HwInfo,RefreshRateTableIndex);
6558 }
6559 } else {
6560 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex, HwInfo,RefreshRateTableIndex);
6561 }
6562 }
6563 }
6564}
6565
6566/*********************************************/
6567/* SET PART 2 REGISTER GROUP */
6568/*********************************************/
6569
6570#ifdef SIS315H
6571static UCHAR *
6572SiS_GetGroup2CLVXPtr(SiS_Private *SiS_Pr, int tabletype, PSIS_HW_INFO HwInfo)
6573{
6574 const UCHAR *tableptr = NULL;
6575 USHORT a, b, p = 0;
6576
6577 a = SiS_Pr->SiS_VGAHDE;
6578 b = SiS_Pr->SiS_HDE;
6579 if(tabletype) {
6580 a = SiS_Pr->SiS_VGAVDE;
6581 b = SiS_Pr->SiS_VDE;
6582 }
6583
6584 if(a < b) {
6585 tableptr = SiS_Part2CLVX_1;
6586 } else if(a == b) {
6587 tableptr = SiS_Part2CLVX_2;
6588 } else {
6589 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6590 tableptr = SiS_Part2CLVX_4;
6591 } else {
6592 tableptr = SiS_Part2CLVX_3;
6593 }
6594 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6595 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) tableptr = SiS_Part2CLVX_3;
6596 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tableptr = SiS_Part2CLVX_3;
6597 else tableptr = SiS_Part2CLVX_5;
6598 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6599 tableptr = SiS_Part2CLVX_6;
6600 }
6601 do {
6602 if((tableptr[p] | tableptr[p+1] << 8) == a) break;
6603 p += 0x42;
6604 } while((tableptr[p] | tableptr[p+1] << 8) != 0xffff);
6605 if((tableptr[p] | tableptr[p+1] << 8) == 0xffff) p -= 0x42;
6606 }
6607 p += 2;
6608 return((UCHAR *)&tableptr[p]);
6609}
6610
6611static void
6612SiS_SetGroup2_C_ELV(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
6613 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
6614{
6615 UCHAR *tableptr;
6616 int i, j;
6617 UCHAR temp;
6618
6619 if(!(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV))) return;
6620
6621 tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 0, HwInfo);
6622 for(i = 0x80, j = 0; i <= 0xbf; i++, j++) {
6623 SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6624 }
6625 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6626 tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 1, HwInfo);
6627 for(i = 0xc0, j = 0; i <= 0xff; i++, j++) {
6628 SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6629 }
6630 }
6631 temp = 0x10;
6632 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp |= 0x04;
6633 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xeb,temp);
6634}
6635
6636static BOOLEAN
6637SiS_GetCRT2Part2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
6638 USHORT RefreshRateTableIndex,USHORT *CRT2Index,
6639 USHORT *ResIndex,PSIS_HW_INFO HwInfo)
6640{
6641
6642 if(HwInfo->jChipType < SIS_315H) return FALSE;
6643
6644 if(ModeNo <= 0x13)
6645 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6646 else
6647 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6648
6649 (*ResIndex) &= 0x3f;
6650 (*CRT2Index) = 0;
6651
6652 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6653 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6654 (*CRT2Index) = 200;
6655 }
6656 }
6657
6658 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
6659 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6660 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) (*CRT2Index) = 206;
6661 }
6662 }
6663 return(((*CRT2Index) != 0));
6664}
6665#endif
6666
6667#ifdef SIS300
6668static void
6669SiS_Group2LCDSpecial(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo, USHORT crt2crtc)
6670{
6671 USHORT tempcx;
6672 const UCHAR atable[] = {
6673 0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,
6674 0xab,0x87,0xab,0x9e,0xe7,0x02,0x02
6675 };
6676
6677 if(!SiS_Pr->UseCustomMode) {
6678 if( ( ( (HwInfo->jChipType == SIS_630) ||
6679 (HwInfo->jChipType == SIS_730) ) &&
6680 (HwInfo->jChipRevision > 2) ) &&
6681 (SiS_Pr->SiS_LCDResInfo == Panel_1024x768) &&
6682 (!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) &&
6683 (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
6684 if(ModeNo == 0x13) {
6685 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xB9);
6686 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0xCC);
6687 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xA6);
6688 } else {
6689 if((crt2crtc & 0x3F) == 4) {
6690 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x2B);
6691 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x13);
6692 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xE5);
6693 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0x08);
6694 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xE2);
6695 }
6696 }
6697 }
6698
6699 if(HwInfo->jChipType < SIS_315H) {
6700 if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
6701 crt2crtc &= 0x1f;
6702 tempcx = 0;
6703 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6704 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6705 tempcx += 7;
6706 }
6707 }
6708 tempcx += crt2crtc;
6709 if(crt2crtc >= 4) {
6710 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xff);
6711 }
6712
6713 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6714 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6715 if(crt2crtc == 4) {
6716 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x28);
6717 }
6718 }
6719 }
6720 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x18);
6721 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
6722 }
6723 }
6724 }
6725}
6726
6727/* For ECS A907. Highly preliminary. */
6728static void
6729SiS_Set300Part2Regs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
6730 USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
6731 USHORT ModeNo)
6732{
6733 USHORT crt2crtc, resindex;
6734 int i,j;
6735 const SiS_Part2PortTblStruct *CRT2Part2Ptr = NULL;
6736
6737 if(HwInfo->jChipType != SIS_300) return;
6738 if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) return;
6739 if(SiS_Pr->UseCustomMode) return;
6740
6741 if(ModeNo <= 0x13) {
6742 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6743 } else {
6744 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6745 }
6746
6747 resindex = crt2crtc & 0x3F;
6748 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6749 else CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2;
6750
6751 /* The BIOS code (1.16.51,56) is obviously a fragment! */
6752 if(ModeNo > 0x13) {
6753 CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6754 resindex = 4;
6755 }
6756
6757 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
6758 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
6759 for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
6760 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6761 }
6762 for(j = 0x1c; j <= 0x1d; i++, j++ ) {
6763 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6764 }
6765 for(j = 0x1f; j <= 0x21; i++, j++ ) {
6766 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6767 }
6768 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
6769 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
6770}
6771#endif
6772
6773static void
6774SiS_SetTVSpecial(SiS_Private *SiS_Pr, USHORT ModeNo)
6775{
6776 if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) return;
6777 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) return;
6778 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) return;
6779
6780 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
6781 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6782 const UCHAR specialtv[] = {
6783 0xa7,0x07,0xf2,0x6e,0x17,0x8b,0x73,0x53,
6784 0x13,0x40,0x34,0xf4,0x63,0xbb,0xcc,0x7a,
6785 0x58,0xe4,0x73,0xda,0x13
6786 };
6787 int i, j;
6788 for(i = 0x1c, j = 0; i <= 0x30; i++, j++) {
6789 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,specialtv[j]);
6790 }
6791 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,0x72);
6792 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750)) {
6793 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6794 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14);
6795 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1b);
6796 } else {
6797 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14); /* 15 */
6798 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1a); /* 1b */
6799 }
6800 }
6801 }
6802 } else {
6803 if((ModeNo == 0x38) || (ModeNo == 0x4a) || (ModeNo == 0x64) ||
6804 (ModeNo == 0x52) || (ModeNo == 0x58) || (ModeNo == 0x5c)) {
6805 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b); /* 21 */
6806 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54); /* 5a */
6807 } else {
6808 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1a); /* 21 */
6809 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x53); /* 5a */
6810 }
6811 }
6812}
6813
6814static void
6815SiS_SetGroup2_Tail(SiS_Private *SiS_Pr, USHORT ModeNo)
6816{
6817 USHORT temp;
6818
6819 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6820 if(SiS_Pr->SiS_VGAVDE == 525) {
6821 temp = 0xc3;
6822 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6823 temp++;
6824 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp += 2;
6825 }
6826 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6827 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xb3);
6828 } else if(SiS_Pr->SiS_VGAVDE == 420) {
6829 temp = 0x4d;
6830 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6831 temp++;
6832 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp++;
6833 }
6834 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6835 }
6836 }
6837
6838 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6839 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
6840 if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
6841 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x1a,0x03);
6842 /* Not always for LV, see SetGrp2 */
6843 }
6844 temp = 1;
6845 if(ModeNo <= 0x13) temp = 3;
6846 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0b,temp);
6847 }
6848#if 0
6849 /* 651+301C, for 1280x768 - do I really need that? */
6850 if((SiS_Pr->SiS_PanelXRes == 1280) && (SiS_Pr->SiS_PanelYRes == 768)) {
6851 if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) {
6852 if(((SiS_Pr->SiS_HDE == 640) && (SiS_Pr->SiS_VDE == 480)) ||
6853 ((SiS_Pr->SiS_HDE == 320) && (SiS_Pr->SiS_VDE == 240))) {
6854 SiS_SetReg(SiS_Part2Port,0x01,0x2b);
6855 SiS_SetReg(SiS_Part2Port,0x02,0x13);
6856 SiS_SetReg(SiS_Part2Port,0x04,0xe5);
6857 SiS_SetReg(SiS_Part2Port,0x05,0x08);
6858 SiS_SetReg(SiS_Part2Port,0x06,0xe2);
6859 SiS_SetReg(SiS_Part2Port,0x1c,0x21);
6860 SiS_SetReg(SiS_Part2Port,0x1d,0x45);
6861 SiS_SetReg(SiS_Part2Port,0x1f,0x0b);
6862 SiS_SetReg(SiS_Part2Port,0x20,0x00);
6863 SiS_SetReg(SiS_Part2Port,0x21,0xa9);
6864 SiS_SetReg(SiS_Part2Port,0x23,0x0b);
6865 SiS_SetReg(SiS_Part2Port,0x25,0x04);
6866 }
6867 }
6868 }
6869#endif
6870 }
6871}
6872
6873static void
6874SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
6875 PSIS_HW_INFO HwInfo)
6876{
6877 USHORT i, j, tempax, tempbx, tempcx, tempch, tempcl, temp;
6878 USHORT push2, modeflag, crt2crtc, bridgeoffset;
6879 ULONG longtemp;
6880 const UCHAR *PhasePoint;
6881 const UCHAR *TimingPoint;
6882#ifdef SIS315H
6883 USHORT resindex, CRT2Index;
6884 const SiS_Part2PortTblStruct *CRT2Part2Ptr = NULL;
6885
6886 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
6887#endif
6888
6889 if(ModeNo <= 0x13) {
6890 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6891 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6892 } else if(SiS_Pr->UseCustomMode) {
6893 modeflag = SiS_Pr->CModeFlag;
6894 crt2crtc = 0;
6895 } else {
6896 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6897 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6898 }
6899
6900 temp = 0;
6901 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO)) temp |= 0x08;
6902 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO)) temp |= 0x04;
6903 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) temp |= 0x02;
6904 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp |= 0x01;
6905
6906 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) temp |= 0x10;
6907
6908 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x00,temp);
6909
6910 PhasePoint = SiS_Pr->SiS_PALPhase;
6911 TimingPoint = SiS_Pr->SiS_PALTiming;
6912
6913 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6914
6915 TimingPoint = SiS_Pr->SiS_HiTVExtTiming;
6916 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6917 TimingPoint = SiS_Pr->SiS_HiTVSt2Timing;
6918 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
6919 TimingPoint = SiS_Pr->SiS_HiTVSt1Timing;
6920#if 0
6921 if(!(modeflag & Charx8Dot)) TimingPoint = SiS_Pr->SiS_HiTVTextTiming;
6922#endif
6923 }
6924 }
6925
6926 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6927
6928 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) TimingPoint = &SiS_YPbPrTable[2][0];
6929 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) TimingPoint = &SiS_YPbPrTable[1][0];
6930 else TimingPoint = &SiS_YPbPrTable[0][0];
6931
6932 PhasePoint = SiS_Pr->SiS_NTSCPhase;
6933
6934 } else if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6935
6936 if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
6937 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6938 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6939 PhasePoint = SiS_Pr->SiS_PALPhase2;
6940 }
6941
6942 } else {
6943
6944 TimingPoint = SiS_Pr->SiS_NTSCTiming;
6945 PhasePoint = SiS_Pr->SiS_NTSCPhase;
6946 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
6947 PhasePoint = SiS_Pr->SiS_PALPhase;
6948 }
6949
6950 if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
6951 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6952 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6953 PhasePoint = SiS_Pr->SiS_NTSCPhase2;
6954 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
6955 PhasePoint = SiS_Pr->SiS_PALPhase2;
6956 }
6957 }
6958
6959 }
6960
6961 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6962 PhasePoint = SiS_Pr->SiS_PALMPhase;
6963 if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
6964 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6965 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6966 PhasePoint = SiS_Pr->SiS_PALMPhase2;
6967 }
6968 }
6969
6970 if(SiS_Pr->SiS_TVMode & TVSetPALN) {
6971 PhasePoint = SiS_Pr->SiS_PALNPhase;
6972 if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
6973 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6974 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6975 PhasePoint = SiS_Pr->SiS_PALNPhase2;
6976 }
6977 }
6978
6979 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6980 PhasePoint = SiS_Pr->SiS_SpecialPhase;
6981 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6982 PhasePoint = SiS_Pr->SiS_SpecialPhaseM;
6983 } else if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
6984 PhasePoint = SiS_Pr->SiS_SpecialPhaseJ;
6985 }
6986 }
6987
6988 for(i=0x31, j=0; i<=0x34; i++, j++) {
6989 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,PhasePoint[j]);
6990 }
6991
6992 for(i=0x01, j=0; i<=0x2D; i++, j++) {
6993 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
6994 }
6995 for(i=0x39; i<=0x45; i++, j++) {
6996 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
6997 }
6998
6999 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7000 if(SiS_Pr->SiS_ModeType != ModeText) {
7001 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
7002 }
7003 }
7004
7005 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x0A,SiS_Pr->SiS_NewFlickerMode);
7006
7007 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x35,SiS_Pr->SiS_RY1COE);
7008 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x36,SiS_Pr->SiS_RY2COE);
7009 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x37,SiS_Pr->SiS_RY3COE);
7010 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x38,SiS_Pr->SiS_RY4COE);
7011
7012 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempax = 950;
7013 else if(SiS_Pr->SiS_TVMode & TVSetPAL) tempax = 520;
7014 else tempax = 440; /* NTSC, YPbPr 525, 750 */
7015
7016 if( ( (!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) && (SiS_Pr->SiS_VDE <= tempax) ) ||
7017 ( (SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) &&
7018 ((SiS_Pr->SiS_VGAHDE == 1024) || (SiS_Pr->SiS_VDE <= tempax)) ) ) {
7019
7020 tempax -= SiS_Pr->SiS_VDE;
7021 tempax >>= 2;
7022 tempax &= 0x00ff;
7023
7024 temp = tempax + (USHORT)TimingPoint[0];
7025 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
7026
7027 temp = tempax + (USHORT)TimingPoint[1];
7028 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
7029
7030 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) && (SiS_Pr->SiS_VGAHDE >= 1024)) {
7031 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7032 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b); /* 19 */
7033 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54); /* 52 */
7034 } else {
7035 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x17);
7036 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1d);
7037 }
7038 }
7039
7040 }
7041
7042 tempcx = SiS_Pr->SiS_HT;
7043 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempcx >>= 1;
7044 tempcx--;
7045 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) tempcx--;
7046 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1B,tempcx);
7047 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0xF0,((tempcx >> 8) & 0x0f));
7048
7049 tempcx = SiS_Pr->SiS_HT >> 1;
7050 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempcx >>= 1;
7051 tempcx += 7;
7052 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
7053 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,((tempcx << 4) & 0xf0));
7054
7055 tempbx = TimingPoint[j] | (TimingPoint[j+1] << 8);
7056 tempbx += tempcx;
7057 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x24,tempbx);
7058 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0F,((tempbx >> 4) & 0xf0));
7059
7060 tempbx += 8;
7061 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7062 tempbx -= 4;
7063 tempcx = tempbx;
7064 }
7065 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x29,0x0F,((tempbx << 4) & 0xf0));
7066
7067 j += 2;
7068 tempcx += (TimingPoint[j] | (TimingPoint[j+1] << 8));
7069 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x27,tempcx);
7070 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x28,0x0F,((tempcx >> 4) & 0xf0));
7071
7072 tempcx += 8;
7073 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
7074 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2A,0x0F,((tempcx << 4) & 0xf0));
7075
7076 tempcx = SiS_Pr->SiS_HT >> 1;
7077 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempcx >>= 1;
7078 j += 2;
7079 tempcx -= (TimingPoint[j] | ((TimingPoint[j+1]) << 8));
7080 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2D,0x0F,((tempcx << 4) & 0xf0));
7081
7082 tempcx -= 11;
7083 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
7084 tempcx = SiS_GetVGAHT2(SiS_Pr) - 1;
7085 }
7086 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2E,tempcx);
7087
7088 tempbx = SiS_Pr->SiS_VDE;
7089 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7090 if(SiS_Pr->SiS_VGAVDE == 360) tempbx = 746;
7091 if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 746;
7092 if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 853;
7093 } else if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
7094 (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p))) ) {
7095 tempbx >>= 1;
7096 if(HwInfo->jChipType >= SIS_315H) {
7097 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
7098 if((ModeNo <= 0x13) && (crt2crtc == 1)) tempbx++;
7099 } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7100 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
7101 if(crt2crtc == 4) tempbx++;
7102 }
7103 }
7104 }
7105 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7106 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7107 if((ModeNo == 0x2f) || (ModeNo == 0x5d) || (ModeNo == 0x5e)) tempbx++;
7108 }
7109 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
7110 if(ModeNo == 0x03) tempbx++; /* From 1.10.7w - doesn't make sense */
7111 }
7112 }
7113 }
7114 tempbx -= 2;
7115 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2F,tempbx);
7116
7117 temp = (tempcx >> 8) & 0x0F;
7118 temp |= ((tempbx >> 2) & 0xC0);
7119 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
7120 temp |= 0x10;
7121 if(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO) temp |= 0x20;
7122 }
7123 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,temp);
7124
7125 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302LV | VB_SIS302ELV)) {
7126 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xdf,((tempbx & 0x0400) >> 5));
7127 }
7128
7129#if 0
7130 /* TEST qqqq */
7131 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7132 for(i=0x01, j=0; i<=0x2D; i++, j++) {
7133 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
7134 }
7135 for(i=0x39; i<=0x45; i++, j++) {
7136 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
7137 }
7138 }
7139#endif
7140
7141 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
7142 tempbx = SiS_Pr->SiS_VDE;
7143 if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
7144 (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) ) {
7145 tempbx >>= 1;
7146 }
7147 tempbx -= 3;
7148 temp = ((tempbx >> 3) & 0x60) | 0x18;
7149 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x46,temp);
7150 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x47,tempbx);
7151
7152 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302LV | VB_SIS302ELV)) {
7153 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xbf,((tempbx & 0x0400) >> 4));
7154 }
7155 }
7156
7157 tempbx = 0;
7158 if(!(modeflag & HalfDCLK)) {
7159 if(SiS_Pr->SiS_VGAHDE >= SiS_Pr->SiS_HDE) {
7160 tempax = 0;
7161 tempbx |= 0x20;
7162 }
7163 }
7164
7165 tempch = tempcl = 0x01;
7166 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7167 if(SiS_Pr->SiS_VGAHDE >= 1024) {
7168 if((!(modeflag & HalfDCLK)) || (HwInfo->jChipType < SIS_315H)) {
7169 tempch = 0x19;
7170 tempcl = 0x20;
7171 if(SiS_Pr->SiS_VGAHDE >= 1280) {
7172 tempch = 0x14;
7173 tempbx &= ~0x20;
7174 }
7175 }
7176 }
7177 }
7178
7179 if(!(tempbx & 0x20)) {
7180 if(modeflag & HalfDCLK) tempcl <<= 1;
7181 longtemp = ((SiS_Pr->SiS_VGAHDE * tempch) / tempcl) << 13;
7182 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) longtemp <<= 3;
7183 tempax = longtemp / SiS_Pr->SiS_HDE;
7184 if(longtemp % SiS_Pr->SiS_HDE) tempax++;
7185 tempbx |= ((tempax >> 8) & 0x1F);
7186 tempcx = tempax >> 13;
7187 }
7188
7189 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,tempax);
7190 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,tempbx);
7191
7192 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
7193
7194 tempcx &= 0x07;
7195 if(tempbx & 0x20) tempcx = 0;
7196 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xF8,tempcx);
7197
7198 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7199 tempbx = 0x0382;
7200 tempcx = 0x007e;
7201 } else {
7202 tempbx = 0x0369;
7203 tempcx = 0x0061;
7204 }
7205 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4B,tempbx);
7206 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4C,tempcx);
7207 temp = (tempcx & 0x0300) >> 6;
7208 temp |= ((tempbx >> 8) & 0x03);
7209 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7210 temp |= 0x10;
7211 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp |= 0x20;
7212 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp |= 0x40;
7213 }
7214 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4D,temp);
7215
7216 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7217 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,(temp - 3));
7218
7219 SiS_SetTVSpecial(SiS_Pr, ModeNo);
7220
7221 if(SiS_Pr->SiS_VBType & VB_SIS301C) {
7222 temp = 0;
7223 if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
7224 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xf7,temp);
7225 }
7226
7227 }
7228
7229 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7230 if(!(SiS_Pr->SiS_TVMode & TVSetNTSC1024)) {
7231 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
7232 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,(temp - 1));
7233 }
7234 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF);
7235 }
7236
7237 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7238 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
7239 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,0x00);
7240 }
7241 }
7242
7243 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) return;
7244
7245 /* From here: Part2 LCD setup */
7246
7247 tempbx = SiS_Pr->SiS_HDE;
7248 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
7249 tempbx--; /* RHACTE = HDE - 1 */
7250 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2C,tempbx);
7251 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,((tempbx >> 4) & 0xf0));
7252
7253 temp = 0x01;
7254 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7255 if(SiS_Pr->SiS_ModeType == ModeEGA) {
7256 if(SiS_Pr->SiS_VGAHDE >= 1024) {
7257 temp = 0x02;
7258 if(HwInfo->jChipType >= SIS_315H) {
7259 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7260 temp = 0x01;
7261 }
7262 }
7263 }
7264 }
7265 }
7266 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,temp);
7267
7268 tempbx = SiS_Pr->SiS_VDE - 1;
7269 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x03,tempbx);
7270 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0C,0xF8,((tempbx >> 8) & 0x07));
7271
7272 tempcx = SiS_Pr->SiS_VT - 1;
7273 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x19,tempcx);
7274 temp = (tempcx >> 3) & 0xE0;
7275 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
7276 /* Enable dithering; only do this for 32bpp mode */
7277 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
7278 temp |= 0x10;
7279 }
7280 }
7281 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1A,0x0f,temp);
7282
7283 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x09,0xF0);
7284 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x0A,0xF0);
7285
7286 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB);
7287 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF);
7288
7289#ifdef SIS315H
7290 if(SiS_GetCRT2Part2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7291 &CRT2Index, &resindex, HwInfo)) {
7292 switch(CRT2Index) {
7293 case 200: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1; break;
7294 case 206: CRT2Part2Ptr = SiS310_CRT2Part2_Asus1024x768_3; break;
7295 default: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_3; break;
7296 }
7297
7298 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
7299 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
7300 for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
7301 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7302 }
7303 for(j = 0x1c; j <= 0x1d; i++, j++ ) {
7304 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7305 }
7306 for(j = 0x1f; j <= 0x21; i++, j++ ) {
7307 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7308 }
7309 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
7310 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
7311
7312 SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7313
7314
7315 } else {
7316#endif
7317
7318 /* Checked for 1024x768, 1280x1024, 1400x1050, 1600x1200 */
7319 /* Clevo dual-link 1024x768 */
7320 /* Compaq 1280x1024 has HT 1696 sometimes (calculation OK, if given HT is correct) */
7321 /* Acer: OK, but uses different setting for VESA timing at 640/800/1024 and 640x400 */
7322
7323 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7324 if((SiS_Pr->SiS_LCDInfo & LCDPass11) || (SiS_Pr->PanelYRes == SiS_Pr->SiS_VDE)) {
7325 tempbx = SiS_Pr->SiS_VDE - 1;
7326 tempcx = SiS_Pr->SiS_VT - 1;
7327 } else {
7328 tempbx = SiS_Pr->SiS_VDE + ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7329 tempcx = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7330 }
7331 } else {
7332 tempbx = SiS_Pr->PanelYRes;
7333 tempcx = SiS_Pr->SiS_VT;
7334 tempax = 1;
7335 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7336 tempax = SiS_Pr->PanelYRes;
7337 /* if(SiS_Pr->SiS_VGAVDE == 525) tempax += 0x3c; */ /* 651+301C */
7338 if(SiS_Pr->PanelYRes < SiS_Pr->SiS_VDE) {
7339 tempax = tempcx = 0;
7340 } else {
7341 tempax -= SiS_Pr->SiS_VDE;
7342 }
7343 tempax >>= 1;
7344 }
7345 tempcx -= tempax; /* lcdvdes */
7346 tempbx -= tempax; /* lcdvdee */
7347 }
7348
7349 /* Non-expanding: lcdvdes = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */
7350
7351#ifdef TWDEBUG
7352 xf86DrvMsg(0, X_INFO, "lcdvdes 0x%x lcdvdee 0x%x\n", tempcx, tempbx);
7353#endif
7354
7355 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,tempcx); /* lcdvdes */
7356 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,tempbx); /* lcdvdee */
7357
7358 temp = (tempbx >> 5) & 0x38;
7359 temp |= ((tempcx >> 8) & 0x07);
7360 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
7361
7362 tempax = SiS_Pr->SiS_VDE;
7363 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7364 tempax = SiS_Pr->PanelYRes;
7365 }
7366 tempcx = (SiS_Pr->SiS_VT - tempax) >> 4;
7367 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7368 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7369 tempcx = (SiS_Pr->SiS_VT - tempax) / 10;
7370 }
7371 }
7372
7373 tempbx = ((SiS_Pr->SiS_VT + SiS_Pr->SiS_VDE) >> 1) - 1;
7374 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7375 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7376 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { /* ? */
7377 tempax = SiS_Pr->SiS_VT - SiS_Pr->PanelYRes;
7378 if(tempax % 4) { tempax >>= 2; tempax++; }
7379 else { tempax >>= 2; }
7380 tempbx -= (tempax - 1);
7381 } else {
7382 tempbx -= 10;
7383 if(tempbx <= SiS_Pr->SiS_VDE) tempbx = SiS_Pr->SiS_VDE + 1;
7384 }
7385 }
7386 }
7387 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
7388 tempbx++;
7389 if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (crt2crtc == 6)) {
7390 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7391 tempbx = 770;
7392 tempcx = 3;
7393 }
7394 }
7395 }
7396
7397 /* non-expanding: lcdvrs = ((VT + VDE) / 2) - 10 */
7398
7399 if(SiS_Pr->UseCustomMode) {
7400 tempbx = SiS_Pr->CVSyncStart;
7401 }
7402
7403#ifdef TWDEBUG
7404 xf86DrvMsg(0, X_INFO, "lcdvrs 0x%x\n", tempbx);
7405#endif
7406
7407 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,tempbx); /* lcdvrs */
7408
7409 temp = (tempbx >> 4) & 0xF0;
7410 tempbx += (tempcx + 1);
7411 temp |= (tempbx & 0x0F);
7412
7413 if(SiS_Pr->UseCustomMode) {
7414 temp &= 0xf0;
7415 temp |= (SiS_Pr->CVSyncEnd & 0x0f);
7416 }
7417
7418#ifdef TWDEBUG
7419 xf86DrvMsg(0, X_INFO, "lcdvre[3:0] 0x%x\n", (temp & 0x0f));
7420#endif
7421
7422 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
7423
7424#ifdef SIS300
7425 SiS_Group2LCDSpecial(SiS_Pr, HwInfo, ModeNo, crt2crtc);
7426#endif
7427
7428 bridgeoffset = 7;
7429 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) bridgeoffset += 2;
7430 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV)) bridgeoffset++;
7431 if(SiS_IsDualLink(SiS_Pr, HwInfo)) bridgeoffset++;
7432
7433 temp = 0;
7434 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7435 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7436 temp = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7437 if(SiS_IsDualLink(SiS_Pr, HwInfo)) temp >>= 1;
7438 }
7439 }
7440 temp += bridgeoffset;
7441 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1F,temp); /* lcdhdes */
7442 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0F,((temp >> 4) & 0xf0));
7443
7444 tempcx = SiS_Pr->SiS_HT;
7445 tempax = tempbx = SiS_Pr->SiS_HDE;
7446 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7447 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7448 tempax = SiS_Pr->PanelXRes;
7449 tempbx = SiS_Pr->PanelXRes - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7450 }
7451 }
7452 if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
7453 tempcx >>= 1;
7454 tempbx >>= 1;
7455 tempax >>= 1;
7456 }
7457
7458#ifdef TWDEBUG
7459 xf86DrvMsg(0, X_INFO, "lcdhdee 0x%x\n", tempbx);
7460#endif
7461
7462 tempbx += bridgeoffset;
7463
7464 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,tempbx); /* lcdhdee */
7465 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0xF0,((tempbx >> 8) & 0x0f));
7466
7467 tempcx = (tempcx - tempax) >> 2;
7468
7469 tempbx += tempcx;
7470 push2 = tempbx;
7471
7472 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7473 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7474 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
7475 if(SiS_Pr->SiS_HDE == 1280) tempbx = (tempbx & 0xff00) | 0x47;
7476 }
7477 }
7478 }
7479
7480 if(SiS_Pr->UseCustomMode) {
7481 tempbx = SiS_Pr->CHSyncStart;
7482 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
7483 tempbx += bridgeoffset;
7484 }
7485
7486#ifdef TWDEBUG
7487 xf86DrvMsg(0, X_INFO, "lcdhrs 0x%x\n", tempbx);
7488#endif
7489
7490 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1C,tempbx); /* lcdhrs */
7491 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,((tempbx >> 4) & 0xf0));
7492
7493 tempbx = push2;
7494
7495 tempcx <<= 1;
7496 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7497 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) tempcx >>= 2;
7498 }
7499 tempbx += tempcx;
7500
7501 if(SiS_Pr->UseCustomMode) {
7502 tempbx = SiS_Pr->CHSyncEnd;
7503 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
7504 tempbx += bridgeoffset;
7505 }
7506
7507#ifdef TWDEBUG
7508 xf86DrvMsg(0, X_INFO, "lcdhre 0x%x\n", tempbx);
7509#endif
7510
7511 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,tempbx); /* lcdhre */
7512
7513 SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7514
7515#ifdef SIS300
7516 SiS_Set300Part2Regs(SiS_Pr, HwInfo, ModeIdIndex, RefreshRateTableIndex, ModeNo);
7517#endif
7518#ifdef SIS315H
7519 } /* CRT2-LCD from table */
7520#endif
7521}
7522
7523/*********************************************/
7524/* SET PART 3 REGISTER GROUP */
7525/*********************************************/
7526
7527static void
7528SiS_SetGroup3(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7529 PSIS_HW_INFO HwInfo)
7530{
7531 USHORT i;
7532 const UCHAR *tempdi;
7533
7534 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
7535
7536#ifndef SIS_CP
7537 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x00,0x00);
7538#else
7539 SIS_CP_INIT301_CP
7540#endif
7541
7542 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7543 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7544 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7545 } else {
7546 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xF5);
7547 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xB7);
7548 }
7549
7550 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7551 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7552 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7553 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x3D,0xA8);
7554 }
7555
7556 tempdi = NULL;
7557 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7558 tempdi = SiS_Pr->SiS_HiTVGroup3Data;
7559 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
7560 tempdi = SiS_Pr->SiS_HiTVGroup3Simu;
7561 }
7562 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7563 if(!(SiS_Pr->SiS_TVMode & TVSetYPbPr525i)) {
7564 tempdi = SiS_HiTVGroup3_1;
7565 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempdi = SiS_HiTVGroup3_2;
7566 }
7567 }
7568 if(tempdi) {
7569 for(i=0; i<=0x3E; i++) {
7570 SiS_SetReg(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
7571 }
7572 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV)) {
7573 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
7574 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x28,0x3f);
7575 }
7576 }
7577 }
7578
7579#ifdef SIS_CP
7580 SIS_CP_INIT301_CP2
7581#endif
7582}
7583
7584/*********************************************/
7585/* SET PART 4 REGISTER GROUP */
7586/*********************************************/
7587
7588#ifdef SIS315H
7589static void
7590SiS_ShiftXPos(SiS_Private *SiS_Pr, int shift)
7591{
7592 USHORT temp, temp1, temp2;
7593
7594 temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x1f);
7595 temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x20);
7596 temp = (USHORT)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7597 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,temp);
7598 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0f,((temp >> 4) & 0xf0));
7599 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x2b) & 0x0f;
7600 temp = (USHORT)((int)(temp) + shift);
7601 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2b,0xf0,(temp & 0x0f));
7602 temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7603 temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x42);
7604 temp = (USHORT)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7605 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,temp);
7606 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x42,0x0f,((temp >> 4) & 0xf0));
7607}
7608
7609static void
7610SiS_SetGroup4_C_ELV(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
7611 USHORT ModeNo, USHORT ModeIdIndex)
7612{
7613 USHORT temp, temp1, resinfo = 0;
7614
7615 if(!(SiS_Pr->SiS_VBType & VB_SIS301C)) return;
7616 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToHiVision | SetCRT2ToYPbPr525750))) return;
7617
7618 if(ModeNo > 0x13) {
7619 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
7620 }
7621
7622 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3a,0x08);
7623 temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x3a);
7624 if(!(temp & 0x01)) {
7625 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3a,0xdf);
7626 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xfc);
7627 if((HwInfo->jChipType < SIS_661) && (!(SiS_Pr->SiS_ROMNew))) {
7628 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xf8);
7629 }
7630 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0xfb);
7631 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp = 0x0000;
7632 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp = 0x0002;
7633 else if(SiS_Pr->SiS_TVMode & TVSetHiVision) temp = 0x0400;
7634 else temp = 0x0402;
7635 if((HwInfo->jChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
7636 temp1 = 0;
7637 if(SiS_Pr->SiS_TVMode & TVAspect43) temp1 = 4;
7638 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0f,0xfb,temp1);
7639 if(SiS_Pr->SiS_TVMode & TVAspect43LB) temp |= 0x01;
7640 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0x7c,(temp & 0xff));
7641 } else {
7642 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x3b) & 0x03;
7643 if(temp1 == 0x01) temp |= 0x01;
7644 if(temp1 == 0x03) temp |= 0x04; /* ? why not 0x10? */
7645 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xf8,(temp & 0xff));
7646 }
7647 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7648 if(ModeNo > 0x13) {
7649 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3b,0xfd);
7650 }
7651
7652 if(HwInfo->jChipType >= SIS_661) { /* ? */
7653 if(SiS_Pr->SiS_TVMode & TVAspect43) {
7654 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
7655 if(resinfo == SIS_RI_1024x768) {
7656 SiS_ShiftXPos(SiS_Pr, 97);
7657 } else {
7658 SiS_ShiftXPos(SiS_Pr, 111);
7659 }
7660 } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
7661 SiS_ShiftXPos(SiS_Pr, 136);
7662 }
7663 }
7664 }
7665 }
7666}
7667#endif
7668
7669static void
7670SiS_SetCRT2VCLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7671 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
7672{
7673 USHORT vclkindex;
7674 USHORT temp, reg1, reg2;
7675
7676 if(SiS_Pr->UseCustomMode) {
7677 reg1 = SiS_Pr->CSR2B;
7678 reg2 = SiS_Pr->CSR2C;
7679 } else {
7680 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7681 HwInfo);
7682 reg1 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
7683 reg2 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
7684 }
7685
7686 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
7687 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
7688 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x57);
7689 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,0x46);
7690 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1f,0xf6);
7691 } else {
7692 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7693 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7694 }
7695 } else {
7696 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x01);
7697 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7698 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7699 }
7700 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x12,0x00);
7701 temp = 0x08;
7702 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) temp |= 0x20;
7703 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,temp);
7704}
7705
7706static void
7707SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7708 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
7709{
7710 USHORT tempax,tempcx,tempbx,modeflag,temp,resinfo;
7711 ULONG tempebx,tempeax,templong;
7712
7713 if(ModeNo <= 0x13) {
7714 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7715 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
7716 } else if(SiS_Pr->UseCustomMode) {
7717 modeflag = SiS_Pr->CModeFlag;
7718 resinfo = 0;
7719 } else {
7720 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7721 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
7722 }
7723
7724 if(HwInfo->jChipType >= SIS_315H) {
7725 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
7726 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7727 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7728 }
7729 }
7730 }
7731
7732 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302LV)) {
7733 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7734 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x10,0x9f);
7735 }
7736 }
7737
7738 if(HwInfo->jChipType >= SIS_315H) {
7739 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7740 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
7741 if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
7742 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
7743 } else {
7744 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,~0x20);
7745 }
7746
7747 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
7748 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
7749#ifdef SET_EMI
7750 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
7751#endif
7752 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
7753 }
7754 }
7755 return;
7756 }
7757 }
7758
7759 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x13,SiS_Pr->SiS_RVBHCFACT);
7760
7761 tempbx = SiS_Pr->SiS_RVBHCMAX;
7762 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x14,tempbx);
7763
7764 temp = (tempbx >> 1) & 0x80;
7765
7766 tempcx = SiS_Pr->SiS_VGAHT - 1;
7767 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x16,tempcx);
7768
7769 temp |= ((tempcx >> 5) & 0x78);
7770
7771 tempcx = SiS_Pr->SiS_VGAVT - 1;
7772 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempcx -= 5;
7773 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x17,tempcx);
7774
7775 temp |= ((tempcx >> 8) & 0x07);
7776 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x15,temp);
7777
7778 tempbx = SiS_Pr->SiS_VGAHDE;
7779 if(modeflag & HalfDCLK) tempbx >>= 1;
7780 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
7781
7782 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7783 temp = 0;
7784 if(tempbx > 800) temp = 0x60;
7785 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7786 temp = 0;
7787 if(tempbx == 1024) temp = 0xA0;
7788 else if(tempbx > 1024) temp = 0xC0;
7789 } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
7790 temp = 0;
7791 if(tempbx >= 1280) temp = 0x40;
7792 else if(tempbx >= 1024) temp = 0x20;
7793 } else {
7794 temp = 0x80;
7795 if(tempbx >= 1024) temp = 0xA0;
7796 }
7797
7798 if(SiS_Pr->SiS_VBType & VB_SIS301) {
7799 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) temp |= 0x0A;
7800 }
7801
7802 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0E,0x10,temp);
7803
7804 tempeax = SiS_Pr->SiS_VGAVDE;
7805 tempebx = SiS_Pr->SiS_VDE;
7806 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7807 if(!(temp & 0xE0)) tempebx >>=1;
7808 }
7809
7810 tempcx = SiS_Pr->SiS_RVBHRS;
7811 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x18,tempcx);
7812 tempcx >>= 8;
7813 tempcx |= 0x40;
7814
7815 if(tempeax <= tempebx) {
7816 tempcx ^= 0x40;
7817 } else {
7818 tempeax -= tempebx;
7819 }
7820
7821 tempeax *= (256 * 1024);
7822 templong = tempeax % tempebx;
7823 tempeax /= tempebx;
7824 if(templong) tempeax++;
7825
7826 temp = (USHORT)(tempeax & 0x000000FF);
7827 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1B,temp);
7828 temp = (USHORT)((tempeax & 0x0000FF00) >> 8);
7829 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1A,temp);
7830 temp = (USHORT)((tempeax >> 12) & 0x70); /* sic! */
7831 temp |= (tempcx & 0x4F);
7832 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x19,temp);
7833
7834 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
7835
7836 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1C,0x28);
7837
7838 /* Calc Linebuffer max address and set/clear decimode */
7839 tempbx = 0;
7840 if(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p)) tempbx = 0x08;
7841 tempax = SiS_Pr->SiS_VGAHDE;
7842 if(modeflag & HalfDCLK) tempax >>= 1;
7843 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempax >>= 1;
7844 if(tempax > 800) {
7845 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7846 tempax -= 800;
7847 } else { /* 651+301C: Only if TVNoHiviNoYPbPr */
7848 tempbx = 0x08;
7849 if(tempax == 1024) tempax *= 25;
7850 else tempax *= 20;
7851 temp = tempax % 32;
7852 tempax /= 32;
7853 if(temp) tempax++;
7854 tempax++;
7855 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) ||
7856 (SiS_Pr->SiS_TVMode & TVSetYPbPr525i)) {
7857 if(resinfo == SIS_RI_1024x768) {
7858 /* Otherwise white line at right edge */
7859 tempax = (tempax & 0xff00) | 0x20;
7860 }
7861 }
7862 }
7863 }
7864 tempax--;
7865 temp = ((tempax >> 4) & 0x30) | tempbx;
7866 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1D,tempax);
7867 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1E,temp);
7868
7869 temp = 0x0036; tempbx = 0xD0;
7870 if((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
7871 temp = 0x0026; tempbx = 0xC0; /* See En/DisableBridge() */
7872 }
7873 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7874 if(!(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetHiVision | TVSetYPbPr750p | TVSetYPbPr525p))) {
7875 temp |= 0x01;
7876 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7877 if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
7878 temp &= ~0x01;
7879 }
7880 }
7881 }
7882 }
7883 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,tempbx,temp);
7884
7885 tempbx = SiS_Pr->SiS_HT >> 1;
7886 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
7887 tempbx -= 2;
7888 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x22,tempbx);
7889 temp = (tempbx >> 5) & 0x38;
7890 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp);
7891
7892 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
7893 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7894 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7895 /* LCD-too-dark-error-source, see FinalizeLCD() */
7896 }
7897 if(HwInfo->jChipType >= SIS_315H) {
7898 if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
7899 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
7900 } else {
7901 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,~0x20);
7902 }
7903 }
7904 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
7905 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
7906#ifdef SET_EMI
7907 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
7908#endif
7909 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
7910 }
7911 }
7912
7913 } /* 301B */
7914
7915 SiS_SetCRT2VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
7916}
7917
7918/*********************************************/
7919/* SET PART 5 REGISTER GROUP */
7920/*********************************************/
7921
7922static void
7923SiS_SetGroup5(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7924 PSIS_HW_INFO HwInfo)
7925{
7926
7927 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
7928
7929 if(SiS_Pr->SiS_ModeType == ModeVGA) {
7930 if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))) {
7931 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
7932 SiS_LoadDAC(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
7933 }
7934 }
7935}
7936
7937/*********************************************/
7938/* MODIFY CRT1 GROUP FOR SLAVE MODE */
7939/*********************************************/
7940
7941static void
7942SiS_ModCRT1CRTC(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7943 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
7944{
7945 USHORT tempah,i,modeflag,j;
7946 USHORT ResIndex,DisplayType;
7947 const SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr=NULL;
7948
7949 if(ModeNo <= 0x13) modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7950 else modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7951
7952 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
7953 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
7954 (SiS_Pr->SiS_CustomT == CUT_PANEL848))
7955 return;
7956
7957 if(!(SiS_GetLVDSCRT1Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7958 &ResIndex, &DisplayType))) {
7959 return;
7960 }
7961
7962 if(HwInfo->jChipType < SIS_315H) {
7963 if(SiS_Pr->SiS_SetFlag & SetDOSMode) return;
7964 }
7965
7966 switch(DisplayType) {
7967 case 0 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1; break;
7968 case 1 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1_H; break;
7969 case 2 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2; break;
7970 case 3 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2_H; break;
7971 case 4 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1; break;
7972 case 5 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1_H; break;
7973 case 6 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2; break;
7974 case 7 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2_H; break;
7975 case 8 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1; break;
7976 case 9 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1_H; break;
7977 case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2; break;
7978 case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2_H; break;
7979 case 12: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1; break;
7980 case 13: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H; break;
7981 case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_1; break;
7982 case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_1_H; break;
7983 case 16: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_2; break;
7984 case 17: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_2_H; break;
7985 case 18: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC; break;
7986 case 19: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC; break;
7987 case 20: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL; break;
7988 case 21: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL; break;
7989 case 22: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x480_1; break; /* FSTN */
7990 case 23: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1; break;
7991 case 24: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1_H; break;
7992 case 25: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2; break;
7993 case 26: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2_H; break;
7994 case 27: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_1; break;
7995 case 28: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_1_H; break;
7996 case 29: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_2; break;
7997 case 30: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_2_H; break;
7998 case 36: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_1; break;
7999 case 37: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_1_H; break;
8000 case 38: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_2; break;
8001 case 39: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_2_H; break;
8002 case 40: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_1; break;
8003 case 41: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_1_H; break;
8004 case 42: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_2; break;
8005 case 43: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_2_H; break;
8006 case 50: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1; break;
8007 case 51: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1_H; break;
8008 case 52: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_2; break;
8009 case 53: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_2_H; break;
8010 case 54: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_3; break;
8011 case 55: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_3_H; break;
8012 case 99: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1SOPAL; break;
8013 default: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1; break;
8014 }
8015
8016 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
8017
8018 tempah = (LVDSCRT1Ptr + ResIndex)->CR[0];
8019 SiS_SetReg(SiS_Pr->SiS_P3d4,0x00,tempah);
8020
8021 for(i=0x02,j=1;i<=0x05;i++,j++){
8022 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
8023 SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
8024 }
8025 for(i=0x06,j=5;i<=0x07;i++,j++){
8026 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
8027 SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
8028 }
8029 for(i=0x10,j=7;i<=0x11;i++,j++){
8030 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
8031 SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
8032 }
8033 for(i=0x15,j=9;i<=0x16;i++,j++){
8034 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
8035 SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
8036 }
8037 for(i=0x0A,j=11;i<=0x0C;i++,j++){
8038 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
8039 SiS_SetReg(SiS_Pr->SiS_P3c4,i,tempah);
8040 }
8041
8042 tempah = (LVDSCRT1Ptr + ResIndex)->CR[14];
8043 tempah &= 0xE0;
8044 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);
8045
8046 tempah = (LVDSCRT1Ptr + ResIndex)->CR[14];
8047 tempah &= 0x01;
8048 tempah <<= 5;
8049 if(modeflag & DoubleScanMode) tempah |= 0x080;
8050 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
8051}
8052
8053/*********************************************/
8054/* SET CRT2 ECLK */
8055/*********************************************/
8056
8057static void
8058SiS_SetCRT2ECLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
8059 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
8060{
8061 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
8062 USHORT clkbase, vclkindex=0;
8063 UCHAR sr2b, sr2c;
8064
8065 if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) || (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
8066 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
8067 if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK & 0x3f) == 2) {
8068 RefreshRateTableIndex--;
8069 }
8070 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
8071 RefreshRateTableIndex, HwInfo);
8072 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
8073 } else {
8074 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
8075 RefreshRateTableIndex, HwInfo);
8076 }
8077
8078 sr2b = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
8079 sr2c = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
8080
8081 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
8082 if(SiS_Pr->SiS_UseROM) {
8083 if(ROMAddr[0x220] & 0x01) {
8084 sr2b = ROMAddr[0x227];
8085 sr2c = ROMAddr[0x228];
8086 }
8087 }
8088 }
8089
8090 clkbase = 0x02B;
8091 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
8092 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
8093 clkbase += 3;
8094 }
8095 }
8096
8097 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x20);
8098 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
8099 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
8100 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x10);
8101 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
8102 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
8103 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x00);
8104 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
8105 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
8106}
8107
8108/*********************************************/
8109/* SET UP CHRONTEL CHIPS */
8110/*********************************************/
8111
8112static void
8113SiS_SetCHTVReg(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
8114 USHORT RefreshRateTableIndex)
8115{
8116#if defined(SIS300) || defined(SIS315H)
8117 USHORT temp, tempbx;
8118#endif
8119 USHORT tempcl;
8120 USHORT TVType, resindex;
8121 const SiS_CHTVRegDataStruct *CHTVRegData = NULL;
8122
8123 if(ModeNo <= 0x13)
8124 tempcl = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
8125 else
8126 tempcl = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
8127
8128 TVType = 0;
8129 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
8130 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
8131 TVType += 2;
8132 if(SiS_Pr->SiS_ModeType > ModeVGA) {
8133 if(SiS_Pr->SiS_CHSOverScan) TVType = 8;
8134 }
8135 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
8136 TVType = 4;
8137 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
8138 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
8139 TVType = 6;
8140 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
8141 }
8142 }
8143 switch(TVType) {
8144 case 0: CHTVRegData = SiS_Pr->SiS_CHTVReg_UNTSC; break;
8145 case 1: CHTVRegData = SiS_Pr->SiS_CHTVReg_ONTSC; break;
8146 case 2: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPAL; break;
8147 case 3: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break;
8148 case 4: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALM; break;
8149 case 5: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALM; break;
8150 case 6: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALN; break;
8151 case 7: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALN; break;
8152 case 8: CHTVRegData = SiS_Pr->SiS_CHTVReg_SOPAL; break;
8153 default: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break;
8154 }
8155 resindex = tempcl & 0x3F;
8156
8157 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
8158
8159#ifdef SIS300
8160
8161 /* Chrontel 7005 - I assume that it does not come with a 315 series chip */
8162
8163 /* We don't support modes >800x600 */
8164 if (resindex > 5) return;
8165
8166 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
8167 SiS_SetCH700x(SiS_Pr,0x4304); /* 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
8168 SiS_SetCH700x(SiS_Pr,0x6909); /* Black level for PAL (105)*/
8169 } else {
8170 SiS_SetCH700x(SiS_Pr,0x0304); /* upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
8171 SiS_SetCH700x(SiS_Pr,0x7109); /* Black level for NTSC (113)*/
8172 }
8173
8174 temp = CHTVRegData[resindex].Reg[0];
8175 tempbx=((temp&0x00FF)<<8)|0x00; /* Mode register */
8176 SiS_SetCH700x(SiS_Pr,tempbx);
8177 temp = CHTVRegData[resindex].Reg[1];
8178 tempbx=((temp&0x00FF)<<8)|0x07; /* Start active video register */
8179 SiS_SetCH700x(SiS_Pr,tempbx);
8180 temp = CHTVRegData[resindex].Reg[2];
8181 tempbx=((temp&0x00FF)<<8)|0x08; /* Position overflow register */
8182 SiS_SetCH700x(SiS_Pr,tempbx);
8183 temp = CHTVRegData[resindex].Reg[3];
8184 tempbx=((temp&0x00FF)<<8)|0x0A; /* Horiz Position register */
8185 SiS_SetCH700x(SiS_Pr,tempbx);
8186 temp = CHTVRegData[resindex].Reg[4];
8187 tempbx=((temp&0x00FF)<<8)|0x0B; /* Vertical Position register */
8188 SiS_SetCH700x(SiS_Pr,tempbx);
8189
8190 /* Set minimum flicker filter for Luma channel (SR1-0=00),
8191 minimum text enhancement (S3-2=10),
8192 maximum flicker filter for Chroma channel (S5-4=10)
8193 =00101000=0x28 (When reading, S1-0->S3-2, and S3-2->S1-0!)
8194 */
8195 SiS_SetCH700x(SiS_Pr,0x2801);
8196
8197 /* Set video bandwidth
8198 High bandwith Luma composite video filter(S0=1)
8199 low bandwith Luma S-video filter (S2-1=00)
8200 disable peak filter in S-video channel (S3=0)
8201 high bandwidth Chroma Filter (S5-4=11)
8202 =00110001=0x31
8203 */
8204 SiS_SetCH700x(SiS_Pr,0xb103); /* old: 3103 */
8205
8206 /* Register 0x3D does not exist in non-macrovision register map
8207 (Maybe this is a macrovision register?)
8208 */
8209#ifndef SIS_CP
8210 SiS_SetCH70xx(SiS_Pr,0x003D);
8211#endif
8212
8213 /* Register 0x10 only contains 1 writable bit (S0) for sensing,
8214 all other bits a read-only. Macrovision?
8215 */
8216 SiS_SetCH70xxANDOR(SiS_Pr,0x0010,0x1F);
8217
8218 /* Register 0x11 only contains 3 writable bits (S0-S2) for
8219 contrast enhancement (set to 010 -> gain 1 Yout = 17/16*(Yin-30) )
8220 */
8221 SiS_SetCH70xxANDOR(SiS_Pr,0x0211,0xF8);
8222
8223 /* Clear DSEN
8224 */
8225 SiS_SetCH70xxANDOR(SiS_Pr,0x001C,0xEF);
8226
8227 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) { /* ---- NTSC ---- */
8228 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) {
8229 if(resindex == 0x04) { /* 640x480 overscan: Mode 16 */
8230 SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off */
8231 SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE); /* ACIV on, no need to set FSCI */
8232 } else if(resindex == 0x05) { /* 800x600 overscan: Mode 23 */
8233 SiS_SetCH70xxANDOR(SiS_Pr,0x0118,0xF0); /* 0x18-0x1f: FSCI 469,762,048 */
8234 SiS_SetCH70xxANDOR(SiS_Pr,0x0C19,0xF0);
8235 SiS_SetCH70xxANDOR(SiS_Pr,0x001A,0xF0);
8236 SiS_SetCH70xxANDOR(SiS_Pr,0x001B,0xF0);
8237 SiS_SetCH70xxANDOR(SiS_Pr,0x001C,0xF0);
8238 SiS_SetCH70xxANDOR(SiS_Pr,0x001D,0xF0);
8239 SiS_SetCH70xxANDOR(SiS_Pr,0x001E,0xF0);
8240 SiS_SetCH70xxANDOR(SiS_Pr,0x001F,0xF0);
8241 SiS_SetCH70xxANDOR(SiS_Pr,0x0120,0xEF); /* Loop filter on for mode 23 */
8242 SiS_SetCH70xxANDOR(SiS_Pr,0x0021,0xFE); /* ACIV off, need to set FSCI */
8243 }
8244 } else {
8245 if(resindex == 0x04) { /* ----- 640x480 underscan; Mode 17 */
8246 SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off */
8247 SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);
8248 } else if(resindex == 0x05) { /* ----- 800x600 underscan: Mode 24 */
8249#if 0
8250 SiS_SetCH70xxANDOR(SiS_Pr,0x0118,0xF0); /* (FSCI was 0x1f1c71c7 - this is for mode 22) */
8251 SiS_SetCH70xxANDOR(SiS_Pr,0x0919,0xF0); /* FSCI for mode 24 is 428,554,851 */
8252 SiS_SetCH70xxANDOR(SiS_Pr,0x081A,0xF0); /* 198b3a63 */
8253 SiS_SetCH70xxANDOR(SiS_Pr,0x0b1B,0xF0);
8254 SiS_SetCH70xxANDOR(SiS_Pr,0x041C,0xF0);
8255 SiS_SetCH70xxANDOR(SiS_Pr,0x011D,0xF0);
8256 SiS_SetCH70xxANDOR(SiS_Pr,0x061E,0xF0);
8257 SiS_SetCH70xxANDOR(SiS_Pr,0x051F,0xF0);
8258 SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off for mode 24 */
8259 SiS_SetCH70xxANDOR(SiS_Pr,0x0021,0xFE); /* ACIV off, need to set FSCI */
8260#endif /* All alternatives wrong (datasheet wrong?), don't use FSCI */
8261 SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off */
8262 SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);
8263 }
8264 }
8265 } else { /* ---- PAL ---- */
8266 /* We don't play around with FSCI in PAL mode */
8267 if(resindex == 0x04) {
8268 SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off */
8269 SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE); /* ACIV on */
8270 } else {
8271 SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off */
8272 SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE); /* ACIV on */
8273 }
8274 }
8275
8276#endif /* 300 */
8277
8278 } else {
8279
8280 /* Chrontel 7019 - assumed that it does not come with a 300 series chip */
8281
8282#ifdef SIS315H
8283
8284 /* We don't support modes >1024x768 */
8285 if (resindex > 6) return;
8286
8287 temp = CHTVRegData[resindex].Reg[0];
8288 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
8289 temp |= 0x10;
8290 }
8291 tempbx=((temp & 0x00FF) << 8) | 0x00;
8292 SiS_SetCH701x(SiS_Pr,tempbx);
8293
8294 temp = CHTVRegData[resindex].Reg[1];
8295 tempbx=((temp & 0x00FF) << 8) | 0x01;
8296 SiS_SetCH701x(SiS_Pr,tempbx);
8297
8298 temp = CHTVRegData[resindex].Reg[2];
8299 tempbx=((temp & 0x00FF) << 8) | 0x02;
8300 SiS_SetCH701x(SiS_Pr,tempbx);
8301
8302 temp = CHTVRegData[resindex].Reg[3];
8303 tempbx=((temp & 0x00FF) << 8) | 0x04;
8304 SiS_SetCH701x(SiS_Pr,tempbx);
8305
8306 temp = CHTVRegData[resindex].Reg[4];
8307 tempbx=((temp & 0x00FF) << 8) | 0x03;
8308 SiS_SetCH701x(SiS_Pr,tempbx);
8309
8310 temp = CHTVRegData[resindex].Reg[5];
8311 tempbx=((temp & 0x00FF) << 8) | 0x05;
8312 SiS_SetCH701x(SiS_Pr,tempbx);
8313
8314 temp = CHTVRegData[resindex].Reg[6];
8315 tempbx=((temp & 0x00FF) << 8) | 0x06;
8316 SiS_SetCH701x(SiS_Pr,tempbx);
8317
8318 temp = CHTVRegData[resindex].Reg[7];
8319 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
8320 temp = 0x66;
8321 }
8322 tempbx=((temp & 0x00FF) << 8) | 0x07;
8323 SiS_SetCH701x(SiS_Pr,tempbx);
8324
8325 temp = CHTVRegData[resindex].Reg[8];
8326 tempbx=((temp & 0x00FF) << 8) | 0x08;
8327 SiS_SetCH701x(SiS_Pr,tempbx);
8328
8329 temp = CHTVRegData[resindex].Reg[9];
8330 tempbx=((temp & 0x00FF) << 8) | 0x15;
8331 SiS_SetCH701x(SiS_Pr,tempbx);
8332
8333 temp = CHTVRegData[resindex].Reg[10];
8334 tempbx=((temp & 0x00FF) << 8) | 0x1f;
8335 SiS_SetCH701x(SiS_Pr,tempbx);
8336
8337 temp = CHTVRegData[resindex].Reg[11];
8338 tempbx=((temp & 0x00FF) << 8) | 0x0c;
8339 SiS_SetCH701x(SiS_Pr,tempbx);
8340
8341 temp = CHTVRegData[resindex].Reg[12];
8342 tempbx=((temp & 0x00FF) << 8) | 0x0d;
8343 SiS_SetCH701x(SiS_Pr,tempbx);
8344
8345 temp = CHTVRegData[resindex].Reg[13];
8346 tempbx=((temp & 0x00FF) << 8) | 0x0e;
8347 SiS_SetCH701x(SiS_Pr,tempbx);
8348
8349 temp = CHTVRegData[resindex].Reg[14];
8350 tempbx=((temp & 0x00FF) << 8) | 0x0f;
8351 SiS_SetCH701x(SiS_Pr,tempbx);
8352
8353 temp = CHTVRegData[resindex].Reg[15];
8354 tempbx=((temp & 0x00FF) << 8) | 0x10;
8355 SiS_SetCH701x(SiS_Pr,tempbx);
8356
8357 temp = SiS_GetCH701x(SiS_Pr,0x21) & ~0x02;
8358 /* D1 should be set for PAL, PAL-N and NTSC-J,
8359 but I won't do that for PAL unless somebody
8360 tells me to do so. Since the BIOS uses
8361 non-default CIV values and blacklevels,
8362 this might be compensated anyway.
8363 */
8364 if(SiS_Pr->SiS_TVMode & (TVSetPALN | TVSetNTSCJ)) temp |= 0x02;
8365 SiS_SetCH701x(SiS_Pr,((temp << 8) | 0x21));
8366
8367#endif /* 315 */
8368
8369 }
8370
8371#ifdef SIS_CP
8372 SIS_CP_INIT301_CP3
8373#endif
8374
8375}
8376
8377void
8378SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8379{
8380 USHORT temp;
8381
8382 /* Enable Chrontel 7019 LCD panel backlight */
8383 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8384 if(HwInfo->jChipType == SIS_740) {
8385 SiS_SetCH701x(SiS_Pr,0x6566);
8386 } else {
8387 temp = SiS_GetCH701x(SiS_Pr,0x66);
8388 temp |= 0x20;
8389 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
8390 }
8391 }
8392}
8393
8394void
8395SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr)
8396{
8397 USHORT temp;
8398
8399 /* Disable Chrontel 7019 LCD panel backlight */
8400 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8401 temp = SiS_GetCH701x(SiS_Pr,0x66);
8402 temp &= 0xDF;
8403 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
8404 }
8405}
8406
8407#ifdef SIS315H /* ----------- 315 series only ---------- */
8408
8409static void
8410SiS_ChrontelPowerSequencing(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8411{
8412 UCHAR regtable[] = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
8413 UCHAR table1024_740[] = { 0x01, 0x02, 0x01, 0x01, 0x01 };
8414 UCHAR table1400_740[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 };
8415 UCHAR asus1024_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8416 UCHAR asus1400_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8417 UCHAR table1024_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8418 UCHAR table1400_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8419 UCHAR *tableptr = NULL;
8420 int i;
8421
8422 /* Set up Power up/down timing */
8423
8424 if(HwInfo->jChipType == SIS_740) {
8425 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8426 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1024_740;
8427 else tableptr = table1024_740;
8428 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8429 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8430 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8431 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1400_740;
8432 else tableptr = table1400_740;
8433 } else return;
8434 } else {
8435 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8436 tableptr = table1024_650;
8437 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8438 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8439 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8440 tableptr = table1400_650;
8441 } else return;
8442 }
8443
8444 for(i=0; i<5; i++) {
8445 SiS_SetCH701x(SiS_Pr,(tableptr[i] << 8) | regtable[i]);
8446 }
8447}
8448
8449static void
8450SiS_SetCH701xForLCD(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8451{
8452 UCHAR regtable[] = { 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
8453 0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66 };
8454 UCHAR table1024_740[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8455 0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44 };
8456 UCHAR table1280_740[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8457 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 };
8458 UCHAR table1400_740[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8459 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 };
8460 UCHAR table1600_740[] = { 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8461 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44 };
8462 UCHAR table1024_650[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8463 0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02 };
8464 UCHAR table1280_650[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8465 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02 };
8466 UCHAR table1400_650[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xef,
8467 0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02 };
8468 UCHAR table1600_650[] = { 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8469 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a };
8470 UCHAR *tableptr = NULL;
8471 USHORT tempbh;
8472 int i;
8473
8474 if(HwInfo->jChipType == SIS_740) {
8475 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tableptr = table1024_740;
8476 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_740;
8477 else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_740;
8478 else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_740;
8479 else return;
8480 } else {
8481 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tableptr = table1024_650;
8482 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_650;
8483 else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_650;
8484 else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_650;
8485 else return;
8486 }
8487
8488 tempbh = SiS_GetCH701x(SiS_Pr,0x74);
8489 if((tempbh == 0xf6) || (tempbh == 0xc7)) {
8490 tempbh = SiS_GetCH701x(SiS_Pr,0x73);
8491 if(tempbh == 0xc8) {
8492 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) return;
8493 } else if(tempbh == 0xdb) {
8494 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) return;
8495 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) return;
8496 } else if(tempbh == 0xde) {
8497 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) return;
8498 }
8499 }
8500
8501 if(HwInfo->jChipType == SIS_740) tempbh = 0x0d;
8502 else tempbh = 0x0c;
8503
8504 for(i = 0; i < tempbh; i++) {
8505 SiS_SetCH701x(SiS_Pr,(tableptr[i] << 8) | regtable[i]);
8506 }
8507 SiS_ChrontelPowerSequencing(SiS_Pr,HwInfo);
8508 tempbh = SiS_GetCH701x(SiS_Pr,0x1e);
8509 tempbh |= 0xc0;
8510 SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x1e);
8511
8512 if(HwInfo->jChipType == SIS_740) {
8513 tempbh = SiS_GetCH701x(SiS_Pr,0x1c);
8514 tempbh &= 0xfb;
8515 SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x1c);
8516 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8517 tempbh = SiS_GetCH701x(SiS_Pr,0x64);
8518 tempbh |= 0x40;
8519 SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x64);
8520 tempbh = SiS_GetCH701x(SiS_Pr,0x03);
8521 tempbh &= 0x3f;
8522 SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x03);
8523 }
8524}
8525
8526static void
8527SiS_ChrontelResetVSync(SiS_Private *SiS_Pr)
8528{
8529 unsigned char temp, temp1;
8530
8531 temp1 = SiS_GetCH701x(SiS_Pr,0x49);
8532 SiS_SetCH701x(SiS_Pr,0x3e49);
8533 temp = SiS_GetCH701x(SiS_Pr,0x47);
8534 temp &= 0x7f; /* Use external VSYNC */
8535 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
8536 SiS_LongDelay(SiS_Pr,3);
8537 temp = SiS_GetCH701x(SiS_Pr,0x47);
8538 temp |= 0x80; /* Use internal VSYNC */
8539 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
8540 SiS_SetCH701x(SiS_Pr,(temp1 << 8) | 0x49);
8541}
8542
8543static void
8544SiS_Chrontel701xOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8545{
8546 USHORT temp;
8547
8548 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8549 if(HwInfo->jChipType == SIS_740) {
8550 temp = SiS_GetCH701x(SiS_Pr,0x1c);
8551 temp |= 0x04; /* Invert XCLK phase */
8552 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c);
8553 }
8554 if(SiS_IsYPbPr(SiS_Pr, HwInfo)) {
8555 temp = SiS_GetCH701x(SiS_Pr,0x01);
8556 temp &= 0x3f;
8557 temp |= 0x80; /* Enable YPrPb (HDTV) */
8558 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x01);
8559 }
8560 if(SiS_IsChScart(SiS_Pr, HwInfo)) {
8561 temp = SiS_GetCH701x(SiS_Pr,0x01);
8562 temp &= 0x3f;
8563 temp |= 0xc0; /* Enable SCART + CVBS */
8564 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x01);
8565 }
8566 if(HwInfo->jChipType == SIS_740) {
8567 SiS_ChrontelResetVSync(SiS_Pr);
8568 SiS_SetCH701x(SiS_Pr,0x2049); /* Enable TV path */
8569 } else {
8570 SiS_SetCH701x(SiS_Pr,0x2049); /* Enable TV path */
8571 temp = SiS_GetCH701x(SiS_Pr,0x49);
8572 if(SiS_IsYPbPr(SiS_Pr,HwInfo)) {
8573 temp = SiS_GetCH701x(SiS_Pr,0x73);
8574 temp |= 0x60;
8575 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x73);
8576 }
8577 temp = SiS_GetCH701x(SiS_Pr,0x47);
8578 temp &= 0x7f;
8579 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
8580 SiS_LongDelay(SiS_Pr,2);
8581 temp = SiS_GetCH701x(SiS_Pr,0x47);
8582 temp |= 0x80;
8583 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
8584 }
8585 }
8586}
8587
8588static void
8589SiS_Chrontel701xOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8590{
8591 USHORT temp;
8592
8593 /* Complete power down of LVDS */
8594 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8595 if(HwInfo->jChipType == SIS_740) {
8596 SiS_LongDelay(SiS_Pr,1);
8597 SiS_GenericDelay(SiS_Pr,0x16ff);
8598 SiS_SetCH701x(SiS_Pr,0xac76);
8599 SiS_SetCH701x(SiS_Pr,0x0066);
8600 } else {
8601 SiS_LongDelay(SiS_Pr,2);
8602 temp = SiS_GetCH701x(SiS_Pr,0x76);
8603 temp &= 0xfc;
8604 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
8605 SiS_SetCH701x(SiS_Pr,0x0066);
8606 }
8607 }
8608}
8609
8610static void
8611SiS_ChrontelResetDB(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8612{
8613 USHORT temp;
8614
8615 if(HwInfo->jChipType == SIS_740) {
8616
8617 temp = SiS_GetCH701x(SiS_Pr,0x4a); /* Version ID */
8618 temp &= 0x01;
8619 if(!temp) {
8620
8621 if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo)) {
8622 temp = SiS_GetCH701x(SiS_Pr,0x49);
8623 SiS_SetCH701x(SiS_Pr,0x3e49);
8624 }
8625 /* Reset Chrontel 7019 datapath */
8626 SiS_SetCH701x(SiS_Pr,0x1048);
8627 SiS_LongDelay(SiS_Pr,1);
8628 SiS_SetCH701x(SiS_Pr,0x1848);
8629
8630 if(SiS_WeHaveBacklightCtrl(SiS_Pr, HwInfo)) {
8631 SiS_ChrontelResetVSync(SiS_Pr);
8632 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x49);
8633 }
8634
8635 } else {
8636
8637 /* Clear/set/clear GPIO */
8638 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8639 temp &= 0xef;
8640 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
8641 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8642 temp |= 0x10;
8643 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
8644 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8645 temp &= 0xef;
8646 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
8647 temp = SiS_GetCH701x(SiS_Pr,0x61);
8648 if(!temp) {
8649 SiS_SetCH701xForLCD(SiS_Pr, HwInfo);
8650 }
8651 }
8652
8653 } else { /* 650 */
8654 /* Reset Chrontel 7019 datapath */
8655 SiS_SetCH701x(SiS_Pr,0x1048);
8656 SiS_LongDelay(SiS_Pr,1);
8657 SiS_SetCH701x(SiS_Pr,0x1848);
8658 }
8659}
8660
8661static void
8662SiS_ChrontelInitTVVSync(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8663{
8664 USHORT temp;
8665
8666 if(HwInfo->jChipType == SIS_740) {
8667
8668 if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo)) {
8669 SiS_ChrontelResetVSync(SiS_Pr);
8670 }
8671
8672 } else {
8673
8674 SiS_SetCH701x(SiS_Pr,0xaf76); /* Power up LVDS block */
8675 temp = SiS_GetCH701x(SiS_Pr,0x49);
8676 temp &= 1;
8677 if(temp != 1) { /* TV block powered? (0 = yes, 1 = no) */
8678 temp = SiS_GetCH701x(SiS_Pr,0x47);
8679 temp &= 0x70;
8680 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47); /* enable VSYNC */
8681 SiS_LongDelay(SiS_Pr,3);
8682 temp = SiS_GetCH701x(SiS_Pr,0x47);
8683 temp |= 0x80;
8684 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47); /* disable VSYNC */
8685 }
8686
8687 }
8688}
8689
8690static void
8691SiS_ChrontelDoSomething3(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_INFO HwInfo)
8692{
8693 USHORT temp,temp1;
8694
8695 if(HwInfo->jChipType == SIS_740) {
8696
8697 temp = SiS_GetCH701x(SiS_Pr,0x61);
8698 if(temp < 1) {
8699 temp++;
8700 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61);
8701 }
8702 SiS_SetCH701x(SiS_Pr,0x4566); /* Panel power on */
8703 SiS_SetCH701x(SiS_Pr,0xaf76); /* All power on */
8704 SiS_LongDelay(SiS_Pr,1);
8705 SiS_GenericDelay(SiS_Pr,0x16ff);
8706
8707 } else { /* 650 */
8708
8709 temp1 = 0;
8710 temp = SiS_GetCH701x(SiS_Pr,0x61);
8711 if(temp < 2) {
8712 temp++;
8713 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61);
8714 temp1 = 1;
8715 }
8716 SiS_SetCH701x(SiS_Pr,0xac76);
8717 temp = SiS_GetCH701x(SiS_Pr,0x66);
8718 temp |= 0x5f;
8719 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
8720 if(ModeNo > 0x13) {
8721 if(SiS_WeHaveBacklightCtrl(SiS_Pr, HwInfo)) {
8722 SiS_GenericDelay(SiS_Pr,0x3ff);
8723 } else {
8724 SiS_GenericDelay(SiS_Pr,0x2ff);
8725 }
8726 } else {
8727 if(!temp1)
8728 SiS_GenericDelay(SiS_Pr,0x2ff);
8729 }
8730 temp = SiS_GetCH701x(SiS_Pr,0x76);
8731 temp |= 0x03;
8732 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
8733 temp = SiS_GetCH701x(SiS_Pr,0x66);
8734 temp &= 0x7f;
8735 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
8736 SiS_LongDelay(SiS_Pr,1);
8737
8738 }
8739}
8740
8741static void
8742SiS_ChrontelDoSomething2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8743{
8744 USHORT temp,tempcl,tempch;
8745
8746 SiS_LongDelay(SiS_Pr, 1);
8747 tempcl = 3;
8748 tempch = 0;
8749
8750 do {
8751 temp = SiS_GetCH701x(SiS_Pr,0x66);
8752 temp &= 0x04; /* PLL stable? -> bail out */
8753 if(temp == 0x04) break;
8754
8755 if(HwInfo->jChipType == SIS_740) {
8756 /* Power down LVDS output, PLL normal operation */
8757 SiS_SetCH701x(SiS_Pr,0xac76);
8758 }
8759
8760 SiS_SetCH701xForLCD(SiS_Pr,HwInfo);
8761
8762 if(tempcl == 0) {
8763 if(tempch == 3) break;
8764 SiS_ChrontelResetDB(SiS_Pr,HwInfo);
8765 tempcl = 3;
8766 tempch++;
8767 }
8768 tempcl--;
8769 temp = SiS_GetCH701x(SiS_Pr,0x76);
8770 temp &= 0xfb; /* Reset PLL */
8771 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
8772 SiS_LongDelay(SiS_Pr,2);
8773 temp = SiS_GetCH701x(SiS_Pr,0x76);
8774 temp |= 0x04; /* PLL normal operation */
8775 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
8776 if(HwInfo->jChipType == SIS_740) {
8777 SiS_SetCH701x(SiS_Pr,0xe078); /* PLL loop filter */
8778 } else {
8779 SiS_SetCH701x(SiS_Pr,0x6078);
8780 }
8781 SiS_LongDelay(SiS_Pr,2);
8782 } while(0);
8783
8784 SiS_SetCH701x(SiS_Pr,0x0077); /* MV? */
8785}
8786
8787static void
8788SiS_ChrontelDoSomething1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8789{
8790 USHORT temp;
8791
8792 temp = SiS_GetCH701x(SiS_Pr,0x03);
8793 temp |= 0x80; /* Set datapath 1 to TV */
8794 temp &= 0xbf; /* Set datapath 2 to LVDS */
8795 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x03);
8796
8797 if(HwInfo->jChipType == SIS_740) {
8798
8799 temp = SiS_GetCH701x(SiS_Pr,0x1c);
8800 temp &= 0xfb; /* Normal XCLK phase */
8801 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c);
8802
8803 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8804
8805 temp = SiS_GetCH701x(SiS_Pr,0x64);
8806 temp |= 0x40; /* ? Bit not defined */
8807 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x64);
8808
8809 temp = SiS_GetCH701x(SiS_Pr,0x03);
8810 temp &= 0x3f; /* D1 input to both LVDS and TV */
8811 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x03);
8812
8813 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) {
8814 SiS_SetCH701x(SiS_Pr,0x4063); /* LVDS off */
8815 SiS_LongDelay(SiS_Pr, 1);
8816 SiS_SetCH701x(SiS_Pr,0x0063); /* LVDS on */
8817 SiS_ChrontelResetDB(SiS_Pr, HwInfo);
8818 SiS_ChrontelDoSomething2(SiS_Pr, HwInfo);
8819 SiS_ChrontelDoSomething3(SiS_Pr, 0, HwInfo);
8820 } else {
8821 temp = SiS_GetCH701x(SiS_Pr,0x66);
8822 if(temp != 0x45) {
8823 SiS_ChrontelResetDB(SiS_Pr, HwInfo);
8824 SiS_ChrontelDoSomething2(SiS_Pr, HwInfo);
8825 SiS_ChrontelDoSomething3(SiS_Pr, 0, HwInfo);
8826 }
8827 }
8828
8829 } else { /* 650 */
8830
8831 SiS_ChrontelResetDB(SiS_Pr,HwInfo);
8832 SiS_ChrontelDoSomething2(SiS_Pr,HwInfo);
8833 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34);
8834 SiS_ChrontelDoSomething3(SiS_Pr,temp,HwInfo);
8835 SiS_SetCH701x(SiS_Pr,0xaf76); /* All power on, LVDS normal operation */
8836
8837 }
8838
8839}
8840#endif /* 315 series */
8841
8842/*********************************************/
8843/* MAIN: SET CRT2 REGISTER GROUP */
8844/*********************************************/
8845
8846BOOLEAN
8847SiS_SetCRT2Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
8848{
8849#ifdef SIS300
8850 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
8851#endif
8852 USHORT ModeIdIndex, RefreshRateTableIndex;
8853#if 0
8854 USHORT temp;
8855#endif
8856
8857 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
8858
8859 if(!SiS_Pr->UseCustomMode) {
8860 SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex);
8861 } else {
8862 ModeIdIndex = 0;
8863 }
8864
8865 /* Used for shifting CR33 */
8866 SiS_Pr->SiS_SelectCRT2Rate = 4;
8867
8868 SiS_UnLockCRT2(SiS_Pr, HwInfo);
8869
8870 RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
8871
8872 SiS_SaveCRT2Info(SiS_Pr,ModeNo);
8873
8874 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8875 SiS_DisableBridge(SiS_Pr,HwInfo);
8876 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (HwInfo->jChipType == SIS_730)) {
8877 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,0x80);
8878 }
8879 SiS_SetCRT2ModeRegs(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
8880 }
8881
8882 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
8883 SiS_LockCRT2(SiS_Pr, HwInfo);
8884 SiS_DisplayOn(SiS_Pr);
8885 return TRUE;
8886 }
8887
8888 SiS_GetCRT2Data(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
8889
8890 /* Set up Panel Link for LVDS and LCDA */
8891 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
8892 if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
8893 ((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ||
8894 ((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) ) {
8895 SiS_GetLVDSDesData(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
8896 }
8897
8898#ifdef LINUX_XF86
8899#ifdef TWDEBUG
8900 xf86DrvMsg(0, X_INFO, "(init301: LCDHDES 0x%03x LCDVDES 0x%03x)\n", SiS_Pr->SiS_LCDHDES, SiS_Pr->SiS_LCDVDES);
8901 xf86DrvMsg(0, X_INFO, "(init301: HDE 0x%03x VDE 0x%03x)\n", SiS_Pr->SiS_HDE, SiS_Pr->SiS_VDE);
8902 xf86DrvMsg(0, X_INFO, "(init301: VGAHDE 0x%03x VGAVDE 0x%03x)\n", SiS_Pr->SiS_VGAHDE, SiS_Pr->SiS_VGAVDE);
8903 xf86DrvMsg(0, X_INFO, "(init301: HT 0x%03x VT 0x%03x)\n", SiS_Pr->SiS_HT, SiS_Pr->SiS_VT);
8904 xf86DrvMsg(0, X_INFO, "(init301: VGAHT 0x%03x VGAVT 0x%03x)\n", SiS_Pr->SiS_VGAHT, SiS_Pr->SiS_VGAVT);
8905#endif
8906#endif
8907
8908 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8909 SiS_SetGroup1(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
8910 }
8911
8912 if(SiS_Pr->SiS_VBType & VB_SISVB) {
8913
8914 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8915
8916 SiS_SetGroup2(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
8917#ifdef SIS315H
8918 SiS_SetGroup2_C_ELV(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
8919#endif
8920 SiS_SetGroup3(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
8921 SiS_SetGroup4(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
8922#ifdef SIS315H
8923 SiS_SetGroup4_C_ELV(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
8924#endif
8925 SiS_SetGroup5(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
8926
8927 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex, HwInfo);
8928
8929 /* For 301BDH (Panel link initialization): */
8930 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
8931 if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) {
8932 if(!((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10)))) {
8933 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
8934 SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,
8935 RefreshRateTableIndex,HwInfo);
8936 }
8937 }
8938 }
8939 SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,
8940 RefreshRateTableIndex,HwInfo);
8941 }
8942 }
8943
8944 } else {
8945
8946 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex, HwInfo);
8947
8948 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
8949 SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwInfo);
8950 }
8951
8952 SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwInfo);
8953
8954 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8955 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
8956 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
8957 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8958#ifdef SIS315H
8959 SiS_SetCH701xForLCD(SiS_Pr,HwInfo);
8960#endif
8961 }
8962 }
8963 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8964 SiS_SetCHTVReg(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8965 }
8966 }
8967 }
8968
8969 }
8970
8971#ifdef SIS300
8972 if(HwInfo->jChipType < SIS_315H) {
8973 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8974 if(SiS_Pr->SiS_UseOEM) {
8975 if((SiS_Pr->SiS_UseROM) && (SiS_Pr->SiS_UseOEM == -1)) {
8976 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
8977 SiS_OEM300Setting(SiS_Pr,HwInfo,ModeNo,ModeIdIndex,
8978 RefreshRateTableIndex);
8979 }
8980 } else {
8981 SiS_OEM300Setting(SiS_Pr,HwInfo,ModeNo,ModeIdIndex,
8982 RefreshRateTableIndex);
8983 }
8984 }
8985 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
8986 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
8987 (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
8988 SetOEMLCDData2(SiS_Pr, HwInfo, ModeNo, ModeIdIndex,RefreshRateTableIndex);
8989 }
8990 SiS_DisplayOn(SiS_Pr);
8991 }
8992 }
8993 }
8994#endif
8995
8996#ifdef SIS315H
8997 if(HwInfo->jChipType >= SIS_315H) {
8998 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8999 if(HwInfo->jChipType < SIS_661) {
9000 SiS_FinalizeLCD(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
9001 SiS_OEM310Setting(SiS_Pr, HwInfo, ModeNo, ModeIdIndex, RefreshRateTableIndex);
9002 } else {
9003 SiS_OEM661Setting(SiS_Pr, HwInfo, ModeNo, ModeIdIndex, RefreshRateTableIndex);
9004 }
9005 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40);
9006 }
9007 }
9008#endif
9009
9010 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
9011 SiS_EnableBridge(SiS_Pr, HwInfo);
9012 }
9013
9014 SiS_DisplayOn(SiS_Pr);
9015
9016 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
9017 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
9018 /* Disable LCD panel when using TV */
9019 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFF,0x0C);
9020 } else {
9021 /* Disable TV when using LCD */
9022 SiS_SetCH70xxANDOR(SiS_Pr,0x010E,0xF8);
9023 }
9024 }
9025
9026 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
9027 SiS_LockCRT2(SiS_Pr,HwInfo);
9028 }
9029
9030 return TRUE;
9031}
9032
9033
9034/*********************************************/
9035/* ENABLE/DISABLE LCD BACKLIGHT (SIS) */
9036/*********************************************/
9037
9038void
9039SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
9040{
9041 /* Switch on LCD backlight on SiS30xLV */
9042 SiS_DDC2Delay(SiS_Pr,0xff00);
9043 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
9044 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
9045 SiS_WaitVBRetrace(SiS_Pr,HwInfo);
9046 }
9047 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x01)) {
9048 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
9049 }
9050}
9051
9052void
9053SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
9054{
9055 /* Switch off LCD backlight on SiS30xLV */
9056 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
9057 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
9058 SiS_DDC2Delay(SiS_Pr,0xe000);
9059}
9060
9061/*********************************************/
9062/* DDC RELATED FUNCTIONS */
9063/*********************************************/
9064
9065static void
9066SiS_SetupDDCN(SiS_Private *SiS_Pr)
9067{
9068 SiS_Pr->SiS_DDC_NData = ~SiS_Pr->SiS_DDC_Data;
9069 SiS_Pr->SiS_DDC_NClk = ~SiS_Pr->SiS_DDC_Clk;
9070 if((SiS_Pr->SiS_DDC_Index == 0x11) && (SiS_Pr->SiS_SensibleSR11)) {
9071 SiS_Pr->SiS_DDC_NData &= 0x0f;
9072 SiS_Pr->SiS_DDC_NClk &= 0x0f;
9073 }
9074}
9075
9076#ifdef SIS300
9077static UCHAR *
9078SiS_SetTrumpBlockLoop(SiS_Private *SiS_Pr, UCHAR *dataptr)
9079{
9080 int i, j, num;
9081 USHORT tempah,temp;
9082 UCHAR *mydataptr;
9083
9084 for(i=0; i<20; i++) { /* Do 20 attempts to write */
9085 mydataptr = dataptr;
9086 num = *mydataptr++;
9087 if(!num) return mydataptr;
9088 if(i) {
9089 SiS_SetStop(SiS_Pr);
9090 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT*2);
9091 }
9092 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
9093 tempah = SiS_Pr->SiS_DDC_DeviceAddr;
9094 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write DAB (S0=0=write) */
9095 if(temp) continue; /* (ERROR: no ack) */
9096 tempah = *mydataptr++;
9097 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write register number */
9098 if(temp) continue; /* (ERROR: no ack) */
9099 for(j=0; j<num; j++) {
9100 tempah = *mydataptr++;
9101 temp = SiS_WriteDDC2Data(SiS_Pr,tempah);/* Write DAB (S0=0=write) */
9102 if(temp) break;
9103 }
9104 if(temp) continue;
9105 if(SiS_SetStop(SiS_Pr)) continue;
9106 return mydataptr;
9107 }
9108 return NULL;
9109}
9110
9111static BOOLEAN
9112SiS_SetTrumpionBlock(SiS_Private *SiS_Pr, UCHAR *dataptr)
9113{
9114 SiS_Pr->SiS_DDC_DeviceAddr = 0xF0; /* DAB (Device Address Byte) */
9115 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9116 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
9117 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
9118 SiS_SetupDDCN(SiS_Pr);
9119
9120 SiS_SetSwitchDDC2(SiS_Pr);
9121
9122 while(*dataptr) {
9123 dataptr = SiS_SetTrumpBlockLoop(SiS_Pr, dataptr);
9124 if(!dataptr) return FALSE;
9125 }
9126#ifdef TWDEBUG
9127 xf86DrvMsg(0, X_INFO, "Trumpion block success\n");
9128#endif
9129 return TRUE;
9130}
9131#endif
9132
9133/* The Chrontel 700x is connected to the 630/730 via
9134 * the 630/730's DDC/I2C port.
9135 *
9136 * On 630(S)T chipset, the index changed from 0x11 to
9137 * 0x0a, possibly for working around the DDC problems
9138 */
9139
9140static BOOLEAN
9141SiS_SetChReg(SiS_Private *SiS_Pr, USHORT tempbx, USHORT myor)
9142{
9143 USHORT tempah,temp,i;
9144
9145 for(i=0; i<20; i++) { /* Do 20 attempts to write */
9146 if(i) {
9147 SiS_SetStop(SiS_Pr);
9148 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9149 }
9150 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
9151 tempah = SiS_Pr->SiS_DDC_DeviceAddr;
9152 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write DAB (S0=0=write) */
9153 if(temp) continue; /* (ERROR: no ack) */
9154 tempah = tempbx & 0x00FF; /* Write RAB */
9155 tempah |= myor; /* (700x: set bit 7, see datasheet) */
9156 temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
9157 if(temp) continue; /* (ERROR: no ack) */
9158 tempah = (tempbx & 0xFF00) >> 8;
9159 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write data */
9160 if(temp) continue; /* (ERROR: no ack) */
9161 if(SiS_SetStop(SiS_Pr)) continue; /* Set stop condition */
9162 SiS_Pr->SiS_ChrontelInit = 1;
9163 return TRUE;
9164 }
9165 return FALSE;
9166}
9167
9168#if 0
9169#ifdef SIS300
9170/* Write Trumpion register */
9171static void
9172SiS_SetTrumpReg(SiS_Private *SiS_Pr, USHORT tempbx)
9173{
9174 SiS_Pr->SiS_DDC_DeviceAddr = 0xF0; /* DAB (Device Address Byte) */
9175 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9176 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
9177 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
9178 SiS_SetupDDCN(SiS_Pr);
9179 SiS_SetChReg(SiS_Pr, tempbx, 0);
9180}
9181#endif
9182#endif
9183
9184/* Write to Chrontel 700x */
9185/* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
9186void
9187SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempbx)
9188{
9189 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */
9190
9191 if(!(SiS_Pr->SiS_ChrontelInit)) {
9192 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9193 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
9194 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
9195 SiS_SetupDDCN(SiS_Pr);
9196 }
9197
9198 if( (!(SiS_SetChReg(SiS_Pr, tempbx, 0x80))) &&
9199 (!(SiS_Pr->SiS_ChrontelInit)) ) {
9200 SiS_Pr->SiS_DDC_Index = 0x0a; /* Bit 7 = SC; Bit 6 = SD */
9201 SiS_Pr->SiS_DDC_Data = 0x80; /* Bitmask in IndexReg for Data */
9202 SiS_Pr->SiS_DDC_Clk = 0x40; /* Bitmask in IndexReg for Clk */
9203 SiS_SetupDDCN(SiS_Pr);
9204
9205 SiS_SetChReg(SiS_Pr, tempbx, 0x80);
9206 }
9207}
9208
9209/* Write to Chrontel 701x */
9210/* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
9211void
9212SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempbx)
9213{
9214 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9215 SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */
9216 SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */
9217 SiS_SetupDDCN(SiS_Pr);
9218 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */
9219 SiS_SetChReg(SiS_Pr, tempbx, 0);
9220}
9221
9222void
9223SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
9224{
9225 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
9226 SiS_SetCH700x(SiS_Pr,tempbx);
9227 else
9228 SiS_SetCH701x(SiS_Pr,tempbx);
9229}
9230
9231static USHORT
9232SiS_GetChReg(SiS_Private *SiS_Pr, USHORT myor)
9233{
9234 USHORT tempah,temp,i;
9235
9236 for(i=0; i<20; i++) { /* Do 20 attempts to read */
9237 if(i) {
9238 SiS_SetStop(SiS_Pr);
9239 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9240 }
9241 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
9242 tempah = SiS_Pr->SiS_DDC_DeviceAddr;
9243 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write DAB (S0=0=write) */
9244 if(temp) continue; /* (ERROR: no ack) */
9245 tempah = SiS_Pr->SiS_DDC_ReadAddr | myor; /* Write RAB (700x: | 0x80) */
9246 temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
9247 if(temp) continue; /* (ERROR: no ack) */
9248 if (SiS_SetStart(SiS_Pr)) continue; /* Re-start */
9249 tempah = SiS_Pr->SiS_DDC_DeviceAddr | 0x01;/* DAB | 0x01 = Read */
9250 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* DAB (S0=1=read) */
9251 if(temp) continue; /* (ERROR: no ack) */
9252 tempah = SiS_ReadDDC2Data(SiS_Pr,tempah); /* Read byte */
9253 if(SiS_SetStop(SiS_Pr)) continue; /* Stop condition */
9254 SiS_Pr->SiS_ChrontelInit = 1;
9255 return(tempah);
9256 }
9257 return 0xFFFF;
9258}
9259
9260#if 0
9261#ifdef SIS300
9262/* Read from Trumpion */
9263static USHORT
9264SiS_GetTrumpReg(SiS_Private *SiS_Pr, USHORT tempbx)
9265{
9266 SiS_Pr->SiS_DDC_DeviceAddr = 0xF0; /* DAB */
9267 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9268 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
9269 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
9270 SiS_SetupDDCN(SiS_Pr);
9271 SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9272 return(SiS_GetChReg(SiS_Pr,0));
9273}
9274#endif
9275#endif
9276
9277/* Read from Chrontel 700x */
9278/* Parameter is [Register no (S7-S0)] */
9279USHORT
9280SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempbx)
9281{
9282 USHORT result;
9283
9284 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */
9285
9286 if(!(SiS_Pr->SiS_ChrontelInit)) {
9287 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9288 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
9289 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
9290 SiS_SetupDDCN(SiS_Pr);
9291 }
9292
9293 SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9294
9295 if( ((result = SiS_GetChReg(SiS_Pr,0x80)) == 0xFFFF) &&
9296 (!SiS_Pr->SiS_ChrontelInit) ) {
9297
9298 SiS_Pr->SiS_DDC_Index = 0x0a;
9299 SiS_Pr->SiS_DDC_Data = 0x80;
9300 SiS_Pr->SiS_DDC_Clk = 0x40;
9301 SiS_SetupDDCN(SiS_Pr);
9302
9303 result = SiS_GetChReg(SiS_Pr,0x80);
9304 }
9305 return(result);
9306}
9307
9308/* Read from Chrontel 701x */
9309/* Parameter is [Register no (S7-S0)] */
9310USHORT
9311SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempbx)
9312{
9313 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9314 SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */
9315 SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */
9316 SiS_SetupDDCN(SiS_Pr);
9317 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */
9318
9319 SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9320
9321 return(SiS_GetChReg(SiS_Pr,0));
9322}
9323
9324/* Read from Chrontel 70xx */
9325/* Parameter is [Register no (S7-S0)] */
9326USHORT
9327SiS_GetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
9328{
9329 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
9330 return(SiS_GetCH700x(SiS_Pr, tempbx));
9331 else
9332 return(SiS_GetCH701x(SiS_Pr, tempbx));
9333}
9334
9335/* Our own DDC functions */
9336static USHORT
9337SiS_InitDDCRegs(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
9338 USHORT adaptnum, USHORT DDCdatatype, BOOLEAN checkcr32)
9339{
9340 unsigned char ddcdtype[] = { 0xa0, 0xa0, 0xa0, 0xa2, 0xa6 };
9341 unsigned char flag, cr32;
9342 USHORT temp = 0, myadaptnum = adaptnum;
9343
9344 if(adaptnum != 0) {
9345 if(!(VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) return 0xFFFF;
9346 if((VBFlags & VB_30xBDH) && (adaptnum == 1)) return 0xFFFF;
9347 }
9348
9349 /* adapternum for SiS bridges: 0 = CRT1, 1 = LCD, 2 = VGA2 */
9350
9351 SiS_Pr->SiS_ChrontelInit = 0; /* force re-detection! */
9352
9353 SiS_Pr->SiS_DDC_SecAddr = 0;
9354 SiS_Pr->SiS_DDC_DeviceAddr = ddcdtype[DDCdatatype];
9355 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_P3c4;
9356 SiS_Pr->SiS_DDC_Index = 0x11;
9357 flag = 0xff;
9358
9359 cr32 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x32);
9360
9361#if 0
9362 if(VBFlags & VB_SISBRIDGE) {
9363 if(myadaptnum == 0) {
9364 if(!(cr32 & 0x20)) {
9365 myadaptnum = 2;
9366 if(!(cr32 & 0x10)) {
9367 myadaptnum = 1;
9368 if(!(cr32 & 0x08)) {
9369 myadaptnum = 0;
9370 }
9371 }
9372 }
9373 }
9374 }
9375#endif
9376
9377 if(VGAEngine == SIS_300_VGA) { /* 300 series */
9378
9379 if(myadaptnum != 0) {
9380 flag = 0;
9381 if(VBFlags & VB_SISBRIDGE) {
9382 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9383 SiS_Pr->SiS_DDC_Index = 0x0f;
9384 }
9385 }
9386
9387 if(!(VBFlags & VB_301)) {
9388 if((cr32 & 0x80) && (checkcr32)) {
9389 if(myadaptnum >= 1) {
9390 if(!(cr32 & 0x08)) {
9391 myadaptnum = 1;
9392 if(!(cr32 & 0x10)) return 0xFFFF;
9393 }
9394 }
9395 }
9396 }
9397
9398 temp = 4 - (myadaptnum * 2);
9399 if(flag) temp = 0;
9400
9401 } else { /* 315/330 series */
9402
9403 /* here we simplify: 0 = CRT1, 1 = CRT2 (VGA, LCD) */
9404
9405 if(VBFlags & VB_SISBRIDGE) {
9406 if(myadaptnum == 2) {
9407 myadaptnum = 1;
9408 }
9409 }
9410
9411 if(myadaptnum == 1) {
9412 flag = 0;
9413 if(VBFlags & VB_SISBRIDGE) {
9414 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9415 SiS_Pr->SiS_DDC_Index = 0x0f;
9416 }
9417 }
9418
9419 if((cr32 & 0x80) && (checkcr32)) {
9420 if(myadaptnum >= 1) {
9421 if(!(cr32 & 0x08)) {
9422 myadaptnum = 1;
9423 if(!(cr32 & 0x10)) return 0xFFFF;
9424 }
9425 }
9426 }
9427
9428 temp = myadaptnum;
9429 if(myadaptnum == 1) {
9430 temp = 0;
9431 if(VBFlags & VB_LVDS) flag = 0xff;
9432 }
9433
9434 if(flag) temp = 0;
9435 }
9436
9437 SiS_Pr->SiS_DDC_Data = 0x02 << temp;
9438 SiS_Pr->SiS_DDC_Clk = 0x01 << temp;
9439
9440 SiS_SetupDDCN(SiS_Pr);
9441
9442#ifdef TWDEBUG
9443 xf86DrvMsg(0, X_INFO, "DDC Port %x Index %x Shift %d\n",
9444 SiS_Pr->SiS_DDC_Port, SiS_Pr->SiS_DDC_Index, temp);
9445#endif
9446
9447 return 0;
9448}
9449
9450static USHORT
9451SiS_WriteDABDDC(SiS_Private *SiS_Pr)
9452{
9453 if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9454 if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr)) {
9455 return 0xFFFF;
9456 }
9457 if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_SecAddr)) {
9458 return 0xFFFF;
9459 }
9460 return(0);
9461}
9462
9463static USHORT
9464SiS_PrepareReadDDC(SiS_Private *SiS_Pr)
9465{
9466 if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9467 if(SiS_WriteDDC2Data(SiS_Pr, (SiS_Pr->SiS_DDC_DeviceAddr | 0x01))) {
9468 return 0xFFFF;
9469 }
9470 return(0);
9471}
9472
9473static USHORT
9474SiS_PrepareDDC(SiS_Private *SiS_Pr)
9475{
9476 if(SiS_WriteDABDDC(SiS_Pr)) SiS_WriteDABDDC(SiS_Pr);
9477 if(SiS_PrepareReadDDC(SiS_Pr)) return(SiS_PrepareReadDDC(SiS_Pr));
9478 return(0);
9479}
9480
9481static void
9482SiS_SendACK(SiS_Private *SiS_Pr, USHORT yesno)
9483{
9484 SiS_SetSCLKLow(SiS_Pr);
9485 if(yesno) {
9486 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9487 SiS_Pr->SiS_DDC_Index,
9488 SiS_Pr->SiS_DDC_NData,
9489 SiS_Pr->SiS_DDC_Data);
9490 } else {
9491 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9492 SiS_Pr->SiS_DDC_Index,
9493 SiS_Pr->SiS_DDC_NData,
9494 0);
9495 }
9496 SiS_SetSCLKHigh(SiS_Pr);
9497}
9498
9499static USHORT
9500SiS_DoProbeDDC(SiS_Private *SiS_Pr)
9501{
9502 unsigned char mask, value;
9503 USHORT temp, ret=0;
9504 BOOLEAN failed = FALSE;
9505
9506 SiS_SetSwitchDDC2(SiS_Pr);
9507 if(SiS_PrepareDDC(SiS_Pr)) {
9508 SiS_SetStop(SiS_Pr);
9509#ifdef TWDEBUG
9510 xf86DrvMsg(0, X_INFO, "Probe: Prepare failed\n");
9511#endif
9512 return(0xFFFF);
9513 }
9514 mask = 0xf0;
9515 value = 0x20;
9516 if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9517 temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
9518 SiS_SendACK(SiS_Pr, 0);
9519 if(temp == 0) {
9520 mask = 0xff;
9521 value = 0xff;
9522 } else {
9523 failed = TRUE;
9524 ret = 0xFFFF;
9525#ifdef TWDEBUG
9526 xf86DrvMsg(0, X_INFO, "Probe: Read 1 failed\n");
9527#endif
9528 }
9529 }
9530 if(failed == FALSE) {
9531 temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
9532 SiS_SendACK(SiS_Pr, 1);
9533 temp &= mask;
9534 if(temp == value) ret = 0;
9535 else {
9536 ret = 0xFFFF;
9537#ifdef TWDEBUG
9538 xf86DrvMsg(0, X_INFO, "Probe: Read 2 failed\n");
9539#endif
9540 if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9541 if(temp == 0x30) ret = 0;
9542 }
9543 }
9544 }
9545 SiS_SetStop(SiS_Pr);
9546 return(ret);
9547}
9548
9549static USHORT
9550SiS_ProbeDDC(SiS_Private *SiS_Pr)
9551{
9552 USHORT flag;
9553
9554 flag = 0x180;
9555 SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
9556 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x02;
9557 SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;
9558 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x08;
9559 SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;
9560 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x10;
9561 if(!(flag & 0x1a)) flag = 0;
9562 return(flag);
9563}
9564
9565static USHORT
9566SiS_ReadDDC(SiS_Private *SiS_Pr, USHORT DDCdatatype, unsigned char *buffer)
9567{
9568 USHORT flag, length, i;
9569 unsigned char chksum,gotcha;
9570
9571 if(DDCdatatype > 4) return 0xFFFF;
9572
9573 flag = 0;
9574 SiS_SetSwitchDDC2(SiS_Pr);
9575 if(!(SiS_PrepareDDC(SiS_Pr))) {
9576 length = 127;
9577 if(DDCdatatype != 1) length = 255;
9578 chksum = 0;
9579 gotcha = 0;
9580 for(i=0; i<length; i++) {
9581 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
9582 chksum += buffer[i];
9583 gotcha |= buffer[i];
9584 SiS_SendACK(SiS_Pr, 0);
9585 }
9586 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
9587 chksum += buffer[i];
9588 SiS_SendACK(SiS_Pr, 1);
9589 if(gotcha) flag = (USHORT)chksum;
9590 else flag = 0xFFFF;
9591 } else {
9592 flag = 0xFFFF;
9593 }
9594 SiS_SetStop(SiS_Pr);
9595 return(flag);
9596}
9597
9598/* Our private DDC functions
9599
9600 It complies somewhat with the corresponding VESA function
9601 in arguments and return values.
9602
9603 Since this is probably called before the mode is changed,
9604 we use our pre-detected pSiS-values instead of SiS_Pr as
9605 regards chipset and video bridge type.
9606
9607 Arguments:
9608 adaptnum: 0=CRT1(analog), 1=CRT2/LCD(digital), 2=CRT2/VGA2(analog)
9609 CRT2 DDC is only supported on SiS301, 301B, 301C, 302B.
9610 LCDA is CRT1, but DDC is read from CRT2 port.
9611 DDCdatatype: 0=Probe, 1=EDID, 2=EDID+VDIF, 3=EDID V2 (P&D), 4=EDID V2 (FPDI-2)
9612 buffer: ptr to 256 data bytes which will be filled with read data.
9613
9614 Returns 0xFFFF if error, otherwise
9615 if DDCdatatype > 0: Returns 0 if reading OK (included a correct checksum)
9616 if DDCdatatype = 0: Returns supported DDC modes
9617
9618 */
9619USHORT
9620SiS_HandleDDC(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
9621 USHORT adaptnum, USHORT DDCdatatype, unsigned char *buffer)
9622{
9623 unsigned char sr1f,cr17=1;
9624 USHORT result;
9625
9626 if(adaptnum > 2) return 0xFFFF;
9627 if(DDCdatatype > 4) return 0xFFFF;
9628 if((!(VBFlags & VB_VIDEOBRIDGE)) && (adaptnum > 0)) return 0xFFFF;
9629 if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, FALSE) == 0xFFFF) return 0xFFFF;
9630
9631 sr1f = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f);
9632 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1f,0x3f,0x04);
9633 if(VGAEngine == SIS_300_VGA) {
9634 cr17 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80;
9635 if(!cr17) {
9636 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x17,0x80);
9637 SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x01);
9638 SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x03);
9639 }
9640 }
9641 if((sr1f) || (!cr17)) {
9642 SiS_WaitRetrace1(SiS_Pr);
9643 SiS_WaitRetrace1(SiS_Pr);
9644 SiS_WaitRetrace1(SiS_Pr);
9645 SiS_WaitRetrace1(SiS_Pr);
9646 }
9647
9648 if(DDCdatatype == 0) {
9649 result = SiS_ProbeDDC(SiS_Pr);
9650 } else {
9651 result = SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer);
9652 if((!result) && (DDCdatatype == 1)) {
9653 if((buffer[0] == 0x00) && (buffer[1] == 0xff) &&
9654 (buffer[2] == 0xff) && (buffer[3] == 0xff) &&
9655 (buffer[4] == 0xff) && (buffer[5] == 0xff) &&
9656 (buffer[6] == 0xff) && (buffer[7] == 0x00) &&
9657 (buffer[0x12] == 1)) {
9658 if(adaptnum == 1) {
9659 if(!(buffer[0x14] & 0x80)) result = 0xFFFE;
9660 } else {
9661 if(buffer[0x14] & 0x80) result = 0xFFFE;
9662 }
9663 }
9664 }
9665 }
9666 SiS_SetReg(SiS_Pr->SiS_P3c4,0x1f,sr1f);
9667 if(VGAEngine == SIS_300_VGA) {
9668 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x17,0x7f,cr17);
9669 }
9670 return result;
9671}
9672
9673#ifdef LINUX_XF86
9674
9675static BOOLEAN
9676checkedid1(unsigned char *buffer)
9677{
9678 /* Check header */
9679 if((buffer[0] != 0x00) ||
9680 (buffer[1] != 0xff) ||
9681 (buffer[2] != 0xff) ||
9682 (buffer[3] != 0xff) ||
9683 (buffer[4] != 0xff) ||
9684 (buffer[5] != 0xff) ||
9685 (buffer[6] != 0xff) ||
9686 (buffer[7] != 0x00))
9687 return FALSE;
9688
9689 /* Check EDID version and revision */
9690 if((buffer[0x12] != 1) || (buffer[0x13] > 4)) return FALSE;
9691
9692 /* Check week of manufacture for sanity */
9693 if(buffer[0x10] > 53) return FALSE;
9694
9695 /* Check year of manufacture for sanity */
9696 if(buffer[0x11] > 40) return FALSE;
9697
9698 return TRUE;
9699}
9700
9701static BOOLEAN
9702checkedid2(unsigned char *buffer)
9703{
9704 USHORT year = buffer[6] | (buffer[7] << 8);
9705
9706 /* Check EDID version */
9707 if((buffer[0] & 0xf0) != 0x20) return FALSE;
9708
9709 /* Check week of manufacture for sanity */
9710 if(buffer[5] > 53) return FALSE;
9711
9712 /* Check year of manufacture for sanity */
9713 if((year != 0) && ((year < 1990) || (year > 2030))) return FALSE;
9714
9715 return TRUE;
9716}
9717
9718/* Sense the LCD parameters (CR36, CR37) via DDC */
9719/* SiS30x(B) only */
9720USHORT
9721SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS)
9722{
9723 USHORT DDCdatatype, paneltype, flag, xres=0, yres=0;
9724 USHORT index, myindex, lumsize, numcodes, panelvendor, panelproduct;
9725 int maxx=0, maxy=0, prefx=0, prefy=0;
9726 unsigned char cr37=0, seekcode;
9727 BOOLEAN checkexpand = FALSE;
9728 BOOLEAN havesync = FALSE;
9729 BOOLEAN indb = FALSE;
9730 int retry, i;
9731 unsigned char buffer[256];
9732
9733 for(i=0; i<7; i++) SiS_Pr->CP_DataValid[i] = FALSE;
9734 SiS_Pr->CP_HaveCustomData = FALSE;
9735 SiS_Pr->CP_MaxX = SiS_Pr->CP_MaxY = SiS_Pr->CP_MaxClock = 0;
9736 SiS_Pr->CP_PreferredX = SiS_Pr->CP_PreferredY = 0;
9737 SiS_Pr->CP_PreferredIndex = -1;
9738 SiS_Pr->CP_PrefClock = 0;
9739 SiS_Pr->PanelSelfDetected = FALSE;
9740
9741 if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) return 0;
9742 if(pSiS->VBFlags & VB_30xBDH) return 0;
9743
9744 if(SiS_InitDDCRegs(SiS_Pr, pSiS->VBFlags, pSiS->VGAEngine, 1, 0, FALSE) == 0xFFFF) return 0;
9745
9746 SiS_Pr->SiS_DDC_SecAddr = 0x00;
9747
9748 /* Probe supported DA's */
9749 flag = SiS_ProbeDDC(SiS_Pr);
9750#ifdef TWDEBUG
9751 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO,
9752 "CRT2 DDC capabilities 0x%x\n", flag);
9753#endif
9754 if(flag & 0x10) {
9755 SiS_Pr->SiS_DDC_DeviceAddr = 0xa6; /* EDID V2 (FP) */
9756 DDCdatatype = 4;
9757 } else if(flag & 0x08) {
9758 SiS_Pr->SiS_DDC_DeviceAddr = 0xa2; /* EDID V2 (P&D-D Monitor) */
9759 DDCdatatype = 3;
9760 } else if(flag & 0x02) {
9761 SiS_Pr->SiS_DDC_DeviceAddr = 0xa0; /* EDID V1 */
9762 DDCdatatype = 1;
9763 } else return 0; /* no DDC support (or no device attached) */
9764
9765 /* Read the entire EDID */
9766 retry = 2;
9767 do {
9768 if(SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer)) {
9769 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9770 "CRT2: DDC read failed (attempt %d), %s\n",
9771 (3-retry), (retry == 1) ? "giving up" : "retrying");
9772 retry--;
9773 if(retry == 0) return 0xFFFF;
9774 } else break;
9775 } while(1);
9776
9777#ifdef TWDEBUG
9778 for(i=0; i<256; i+=16) {
9779 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9780 "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
9781 buffer[i], buffer[i+1], buffer[i+2], buffer[i+3],
9782 buffer[i+4], buffer[i+5], buffer[i+6], buffer[i+7],
9783 buffer[i+8], buffer[i+9], buffer[i+10], buffer[i+11],
9784 buffer[i+12], buffer[i+13], buffer[i+14], buffer[i+15]);
9785 }
9786#endif
9787
9788 /* Analyze EDID and retrieve LCD panel information */
9789 paneltype = 0;
9790 switch(DDCdatatype) {
9791 case 1: /* Analyze EDID V1 */
9792 /* Catch a few clear cases: */
9793 if(!(checkedid1(buffer))) {
9794 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9795 "LCD sense: EDID corrupt\n");
9796 return 0;
9797 }
9798
9799 if(!(buffer[0x14] & 0x80)) {
9800 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9801 "LCD sense: Attached display expects analog input (0x%02x)\n",
9802 buffer[0x14]);
9803 return 0;
9804 }
9805
9806 if((buffer[0x18] & 0x18) != 0x08) {
9807 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9808 "LCD sense: Warning: Attached display is not of RGB but of %s type (0x%02x)\n",
9809 ((buffer[0x18] & 0x18) == 0x00) ? "monochrome/greyscale" :
9810 ( ((buffer[0x18] & 0x18) == 0x10) ? "non-RGB multicolor" :
9811 "undefined"),
9812 buffer[0x18]);
9813 }
9814
9815 /* Now analyze the first Detailed Timing Block and see
9816 * if the preferred timing mode is stored there. If so,
9817 * check if this is a standard panel for which we already
9818 * know the timing.
9819 */
9820
9821 paneltype = Panel_Custom;
9822 checkexpand = FALSE;
9823
9824 panelvendor = buffer[9] | (buffer[8] << 8);
9825 panelproduct = buffer[10] | (buffer[11] << 8);
9826
9827 /* Overrule bogus preferred modes from database */
9828 if((indb = SiS_FindPanelFromDB(pSiS, panelvendor, panelproduct, &maxx, &maxy, &prefx, &prefy))) {
9829 if(prefx) SiS_Pr->CP_PreferredX = xres = prefx;
9830 if(prefy) SiS_Pr->CP_PreferredY = yres = prefy;
9831 }
9832
9833 if(buffer[0x18] & 0x02) {
9834
9835 USHORT pclk = (buffer[0x36] | (buffer[0x37] << 8));
9836 USHORT phb = (buffer[0x39] | ((buffer[0x3a] & 0x0f) << 8));
9837 USHORT pvb = (buffer[0x3c] | ((buffer[0x3d] & 0x0f) << 8));
9838
9839 if(!xres) SiS_Pr->CP_PreferredX = xres = buffer[0x38] | ((buffer[0x3a] & 0xf0) << 4);
9840 if(!yres) SiS_Pr->CP_PreferredY = yres = buffer[0x3b] | ((buffer[0x3d] & 0xf0) << 4);
9841
9842 switch(xres) {
9843#if 0 /* Treat as custom */
9844 case 800:
9845 if(yres == 600) {
9846 paneltype = Panel_800x600;
9847 checkexpand = TRUE;
9848 }
9849 break;
9850#endif
9851 case 1024:
9852 if(yres == 768) {
9853 paneltype = Panel_1024x768;
9854 checkexpand = TRUE;
9855 }
9856 break;
9857 case 1280:
9858 if(yres == 1024) {
9859 paneltype = Panel_1280x1024;
9860 checkexpand = TRUE;
9861 } else if(yres == 960) {
9862 if(pSiS->VGAEngine == SIS_300_VGA) {
9863 paneltype = Panel300_1280x960;
9864 } else {
9865 paneltype = Panel310_1280x960;
9866 }
9867 } else if(yres == 768) {
9868 if( (pclk == 8100) &&
9869 (phb == (1688 - 1280)) &&
9870 (pvb == (802 - 768)) ) {
9871 paneltype = Panel_1280x768;
9872 checkexpand = FALSE;
9873 cr37 |= 0x10;
9874 }
9875 } else if(yres == 800) {
9876 if( (pclk == 6900) &&
9877 (phb == (1408 - 1280)) &&
9878 (pvb == (816 - 800)) ) {
9879 paneltype = Panel_1280x800;
9880 }
9881 }
9882 break;
9883 case 1400:
9884 if(pSiS->VGAEngine == SIS_315_VGA) {
9885 if(yres == 1050) {
9886 paneltype = Panel310_1400x1050;
9887 checkexpand = TRUE;
9888 }
9889 }
9890 break;
9891 case 1600:
9892 if(pSiS->VGAEngine == SIS_315_VGA) {
9893 if(pSiS->VBFlags & VB_301C) {
9894 if(yres == 1200) {
9895 paneltype = Panel310_1600x1200;
9896 checkexpand = TRUE;
9897 }
9898 }
9899 }
9900 break;
9901 }
9902
9903 /* Save sync: This is used if "Pass 1:1" is off; in this case
9904 * we always use the panel's native mode = this "preferred mode"
9905 * we just have been analysing. Hence, we also need its sync.
9906 */
9907 if((buffer[0x47] & 0x18) == 0x18) {
9908 cr37 |= ((((buffer[0x47] & 0x06) ^ 0x06) << 5) | 0x20);
9909 havesync = TRUE;
9910 } else {
9911 /* What now? There is no digital separate output timing... */
9912 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
9913 "LCD sense: Unable to retrieve Sync polarity information\n");
9914 cr37 |= 0xc0; /* Default */
9915 }
9916
9917 }
9918
9919 /* Check against our database; eg. Sanyo Z2 projector reports
9920 * 1024x768 as preferred mode, although it supports 1280x720
9921 * natively in non-HDCP mode. Treat such wrongly reporting
9922 * panels as custom and fixup actual maximum resolutions.
9923 */
9924 if(paneltype != Panel_Custom) {
9925 if(indb) {
9926 paneltype = Panel_Custom;
9927 SiS_Pr->CP_MaxX = maxx;
9928 SiS_Pr->CP_MaxY = maxy;
9929 /* Leave preferred unchanged (MUST contain a valid mode!) */
9930 }
9931 }
9932
9933 /* If we still don't know what panel this is, we take it
9934 * as a custom panel and derive the timing data from the
9935 * detailed timing blocks
9936 */
9937 if(paneltype == Panel_Custom) {
9938
9939 int i, temp, base = 0x36;
9940 unsigned long estpack;
9941 const unsigned short estx[] = {
9942 720, 720, 640, 640, 640, 640, 800, 800,
9943 800, 800, 832,1024,1024,1024,1024,1280,
9944 1152
9945 };
9946 const unsigned short esty[] = {
9947 400, 400, 480, 480, 480, 480, 600, 600,
9948 600, 600, 624, 768, 768, 768, 768,1024,
9949 870
9950 };
9951 const int estclk[] = {
9952 0, 0, 25100, 0, 31500, 31500, 36100, 40000,
9953 50100, 49500, 0, 0, 65100, 75200, 78700,135200,
9954 0
9955 };
9956
9957 paneltype = 0;
9958 SiS_Pr->CP_Supports64048075 = TRUE;
9959
9960 /* Find the maximum resolution */
9961
9962 /* 1. From Established timings */
9963 estpack = (buffer[0x23] << 9) | (buffer[0x24] << 1) | ((buffer[0x25] >> 7) & 0x01);
9964 for(i=16; i>=0; i--) {
9965 if(estpack & (1 << i)) {
9966 if(estx[16 - i] > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = estx[16 - i];
9967 if(esty[16 - i] > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = esty[16 - i];
9968 if(estclk[16 - i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = estclk[16 - i];
9969 }
9970 }
9971
9972 /* By default we drive the LCD at 75Hz in 640x480 mode; if
9973 * the panel does not provide this mode, use 60hz
9974 */
9975 if(!(buffer[0x23] & 0x04)) SiS_Pr->CP_Supports64048075 = FALSE;
9976
9977 /* 2. From Standard Timings */
9978 for(i=0x26; i < 0x36; i+=2) {
9979 if((buffer[i] != 0x01) && (buffer[i+1] != 0x01)) {
9980 temp = (buffer[i] + 31) * 8;
9981 if(temp > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = temp;
9982 switch((buffer[i+1] & 0xc0) >> 6) {
9983 case 0x03: temp = temp * 9 / 16; break;
9984 case 0x02: temp = temp * 4 / 5; break;
9985 case 0x01: temp = temp * 3 / 4; break;
9986 }
9987 if(temp > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = temp;
9988 }
9989 }
9990
9991 /* Now extract the Detailed Timings and convert them into modes */
9992
9993 for(i = 0; i < 4; i++, base += 18) {
9994
9995 /* Is this a detailed timing block or a monitor descriptor? */
9996 if(buffer[base] || buffer[base+1] || buffer[base+2]) {
9997
9998 xres = buffer[base+2] | ((buffer[base+4] & 0xf0) << 4);
9999 yres = buffer[base+5] | ((buffer[base+7] & 0xf0) << 4);
10000
10001 SiS_Pr->CP_HDisplay[i] = xres;
10002 SiS_Pr->CP_HSyncStart[i] = xres + (buffer[base+8] | ((buffer[base+11] & 0xc0) << 2));
10003 SiS_Pr->CP_HSyncEnd[i] = SiS_Pr->CP_HSyncStart[i] + (buffer[base+9] | ((buffer[base+11] & 0x30) << 4));
10004 SiS_Pr->CP_HTotal[i] = xres + (buffer[base+3] | ((buffer[base+4] & 0x0f) << 8));
10005 SiS_Pr->CP_HBlankStart[i] = xres + 1;
10006 SiS_Pr->CP_HBlankEnd[i] = SiS_Pr->CP_HTotal[i];
10007
10008 SiS_Pr->CP_VDisplay[i] = yres;
10009 SiS_Pr->CP_VSyncStart[i] = yres + (((buffer[base+10] & 0xf0) >> 4) | ((buffer[base+11] & 0x0c) << 2));
10010 SiS_Pr->CP_VSyncEnd[i] = SiS_Pr->CP_VSyncStart[i] + ((buffer[base+10] & 0x0f) | ((buffer[base+11] & 0x03) << 4));
10011 SiS_Pr->CP_VTotal[i] = yres + (buffer[base+6] | ((buffer[base+7] & 0x0f) << 8));
10012 SiS_Pr->CP_VBlankStart[i] = yres + 1;
10013 SiS_Pr->CP_VBlankEnd[i] = SiS_Pr->CP_VTotal[i];
10014
10015 SiS_Pr->CP_Clock[i] = (buffer[base] | (buffer[base+1] << 8)) * 10;
10016
10017 SiS_Pr->CP_DataValid[i] = TRUE;
10018
10019 /* Sort out invalid timings, interlace and too high clocks */
10020 if((SiS_Pr->CP_HDisplay[i] & 7) ||
10021 (SiS_Pr->CP_HDisplay[i] > SiS_Pr->CP_HSyncStart[i]) ||
10022 (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HSyncEnd[i]) ||
10023 (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HTotal[i]) ||
10024 (SiS_Pr->CP_HSyncStart[i] >= SiS_Pr->CP_HSyncEnd[i]) ||
10025 (SiS_Pr->CP_HSyncStart[i] > SiS_Pr->CP_HTotal[i]) ||
10026 (SiS_Pr->CP_HSyncEnd[i] > SiS_Pr->CP_HTotal[i]) ||
10027 (SiS_Pr->CP_VDisplay[i] > SiS_Pr->CP_VSyncStart[i]) ||
10028 (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VSyncEnd[i]) ||
10029 (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VTotal[i]) ||
10030 (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VSyncEnd[i]) ||
10031 (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VTotal[i]) ||
10032 (SiS_Pr->CP_VSyncEnd[i] > SiS_Pr->CP_VTotal[i]) ||
10033 (((pSiS->VBFlags & VB_301C) && (SiS_Pr->CP_Clock[i] > 162500)) ||
10034 ((!(pSiS->VBFlags & VB_301C)) &&
10035 ((SiS_Pr->CP_Clock[i] > 108200) || (SiS_Pr->CP_VDisplay[i] > 1024) ||
10036 (SiS_Pr->CP_HDisplay[i] > 1600)))) ||
10037 (buffer[base+17] & 0x80)) {
10038
10039 SiS_Pr->CP_DataValid[i] = FALSE;
10040
10041 } else {
10042
10043 SiS_Pr->CP_HaveCustomData = TRUE;
10044
10045 if(xres > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = xres;
10046 if(yres > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = yres;
10047 if(SiS_Pr->CP_Clock[i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = SiS_Pr->CP_Clock[i];
10048
10049 if((SiS_Pr->CP_PreferredX == xres) && (SiS_Pr->CP_PreferredY == yres)) {
10050 SiS_Pr->CP_PreferredIndex = i;
10051 SiS_MakeClockRegs(pSiS->pScrn, SiS_Pr->CP_Clock[i], &SiS_Pr->CP_PrefSR2B, &SiS_Pr->CP_PrefSR2C);
10052 SiS_Pr->CP_PrefClock = (SiS_Pr->CP_Clock[i] / 1000) + 1;
10053 }
10054
10055 /* Extract the sync polarisation information. This only works
10056 * if the Flags indicate a digital separate output.
10057 */
10058 if((buffer[base+17] & 0x18) == 0x18) {
10059 SiS_Pr->CP_HSync_P[i] = (buffer[base+17] & 0x02) ? TRUE : FALSE;
10060 SiS_Pr->CP_VSync_P[i] = (buffer[base+17] & 0x04) ? TRUE : FALSE;
10061 SiS_Pr->CP_SyncValid[i] = TRUE;
10062 if((i == SiS_Pr->CP_PreferredIndex) && (!havesync)) {
10063 cr37 |= ((((buffer[base+17] & 0x06) ^ 0x06) << 5) | 0x20);
10064 havesync = TRUE;
10065 }
10066 } else {
10067 SiS_Pr->CP_SyncValid[i] = FALSE;
10068 }
10069
10070 }
10071
10072 } else if((!buffer[base]) && (!buffer[base+1]) && (!buffer[base+2]) && (!buffer[base+4])) {
10073
10074 /* Maximum pixclock from Monitor Range Limits */
10075 if((buffer[base+3] == 0xfd) && (buffer[base+9] != 0xff)) {
10076 int maxclk = buffer[base+9] * 10;
10077 /* More than 170 is not supported anyway */
10078 if(maxclk <= 170) SiS_Pr->CP_MaxClock = maxclk * 1000;
10079 }
10080
10081 }
10082
10083 }
10084
10085 if(SiS_Pr->CP_MaxX && SiS_Pr->CP_MaxY) {
10086 paneltype = Panel_Custom;
10087 checkexpand = FALSE;
10088 cr37 |= 0x10;
10089 SiS_Pr->CP_Vendor = panelvendor;
10090 SiS_Pr->CP_Product = panelproduct;
10091 }
10092
10093 }
10094
10095 if(paneltype && checkexpand) {
10096 /* If any of the Established low-res modes is supported, the
10097 * panel can scale automatically. For 800x600 panels, we only
10098 * check the even lower ones.
10099 */
10100 if(paneltype == Panel_800x600) {
10101 if(buffer[0x23] & 0xfc) cr37 |= 0x10;
10102 } else {
10103 if(buffer[0x23]) cr37 |= 0x10;
10104 }
10105 }
10106
10107 break;
10108
10109 case 3: /* Analyze EDID V2 */
10110 case 4:
10111 index = 0;
10112
10113 if(!(checkedid2(buffer))) {
10114 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10115 "LCD sense: EDID corrupt\n");
10116 return 0;
10117 }
10118
10119 if((buffer[0x41] & 0x0f) == 0x03) {
10120 index = 0x42 + 3;
10121 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10122 "LCD sense: Display supports TMDS input on primary interface\n");
10123 } else if((buffer[0x41] & 0xf0) == 0x30) {
10124 index = 0x46 + 3;
10125 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10126 "LCD sense: Display supports TMDS input on secondary interface\n");
10127 } else {
10128 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10129 "LCD sense: Display does not support TMDS video interface (0x%02x)\n",
10130 buffer[0x41]);
10131 return 0;
10132 }
10133
10134 SiS_Pr->CP_Vendor = panelvendor = buffer[2] | (buffer[1] << 8);
10135 SiS_Pr->CP_Product = panelproduct = buffer[3] | (buffer[4] << 8);
10136
10137 paneltype = Panel_Custom;
10138 SiS_Pr->CP_MaxX = SiS_Pr->CP_PreferredX = xres = buffer[0x76] | (buffer[0x77] << 8);
10139 SiS_Pr->CP_MaxY = SiS_Pr->CP_PreferredY = yres = buffer[0x78] | (buffer[0x79] << 8);
10140
10141 switch(xres) {
10142#if 0
10143 case 800:
10144 if(yres == 600) {
10145 paneltype = Panel_800x600;
10146 checkexpand = TRUE;
10147 }
10148 break;
10149#endif
10150 case 1024:
10151 if(yres == 768) {
10152 paneltype = Panel_1024x768;
10153 checkexpand = TRUE;
10154 }
10155 break;
10156 case 1280:
10157 if(yres == 960) {
10158 if(pSiS->VGAEngine == SIS_315_VGA) {
10159 paneltype = Panel310_1280x960;
10160 } else {
10161 paneltype = Panel300_1280x960;
10162 }
10163 } else if(yres == 1024) {
10164 paneltype = Panel_1280x1024;
10165 checkexpand = TRUE;
10166 }
10167 /* 1280x768 treated as custom here */
10168 break;
10169 case 1400:
10170 if(pSiS->VGAEngine == SIS_315_VGA) {
10171 if(yres == 1050) {
10172 paneltype = Panel310_1400x1050;
10173 checkexpand = TRUE;
10174 }
10175 }
10176 break;
10177 case 1600:
10178 if(pSiS->VGAEngine == SIS_315_VGA) {
10179 if(pSiS->VBFlags & VB_301C) {
10180 if(yres == 1200) {
10181 paneltype = Panel310_1600x1200;
10182 checkexpand = TRUE;
10183 }
10184 }
10185 }
10186 break;
10187 }
10188
10189 /* Determine if RGB18 or RGB24 */
10190 if(index) {
10191 if((buffer[index] == 0x20) || (buffer[index] == 0x34)) {
10192 cr37 |= 0x01;
10193 }
10194 }
10195
10196 if(checkexpand) {
10197 /* TODO - for now, we let the panel scale */
10198 cr37 |= 0x10;
10199 }
10200
10201 /* Now seek 4-Byte Timing codes and extract sync pol info */
10202 index = 0x80;
10203 if(buffer[0x7e] & 0x20) { /* skip Luminance Table (if provided) */
10204 lumsize = buffer[0x80] & 0x1f;
10205 if(buffer[0x80] & 0x80) lumsize *= 3;
10206 lumsize++; /* luminance header byte */
10207 index += lumsize;
10208 }
10209#if 0 /* "pixel rate" = pixel clock? */
10210 if(buffer[0x7e] & 0x1c) {
10211 for(i=0; i<((buffer[0x7e] & 0x1c) >> 2); i++) {
10212 if(buffer[index + (i*8) + 6] && (buffer[index + (i*8) + 7] & 0x0f)) {
10213 int clk = (buffer[index + (i*8) + 6] | ((buffer[index + (i*8) + 7] & 0x0f) << 4)) * 1000;
10214 if(clk > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = clk;
10215 }
10216 }
10217 }
10218#endif
10219 index += (((buffer[0x7e] & 0x1c) >> 2) * 8); /* skip Frequency Ranges */
10220 if(buffer[0x7e] & 0x03) {
10221 for(i=0; i<(buffer[0x7e] & 0x03); i++) {
10222 if((buffer[index + (i*27) + 9]) || (buffer[index + (i*27) + 10])) {
10223 int clk = ((buffer[index + (i*27) + 9]) | ((buffer[index + (i*27) + 9]) << 8)) * 10;
10224 if(clk > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = clk;
10225 }
10226 }
10227 }
10228 index += ((buffer[0x7e] & 0x03) * 27); /* skip Detailed Range Limits */
10229 numcodes = (buffer[0x7f] & 0xf8) >> 3;
10230 if(numcodes) {
10231 myindex = index;
10232 seekcode = (xres - 256) / 16;
10233 for(i=0; i<numcodes; i++) {
10234 if(buffer[myindex] == seekcode) break;
10235 myindex += 4;
10236 }
10237 if(buffer[myindex] == seekcode) {
10238 cr37 |= ((((buffer[myindex + 1] & 0x0c) ^ 0x0c) << 4) | 0x20);
10239 havesync = TRUE;
10240 } else {
10241 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
10242 "LCD sense: Unable to retrieve Sync polarity information\n");
10243 }
10244 } else {
10245 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
10246 "LCD sense: Unable to retrieve Sync polarity information\n");
10247 }
10248
10249 /* Check against our database; Eg. Sanyo projector reports
10250 * 1024x768 in non-HDPC mode, although it supports 1280x720.
10251 * Treat such wrongly reporting panels as custom.
10252 */
10253 if(paneltype != Panel_Custom) {
10254 int maxx, maxy, prefx, prefy;
10255 if((SiS_FindPanelFromDB(pSiS, panelvendor, panelproduct, &maxx, &maxy, &prefx, &prefy))) {
10256 paneltype = Panel_Custom;
10257 SiS_Pr->CP_MaxX = maxx;
10258 SiS_Pr->CP_MaxY = maxy;
10259 cr37 |= 0x10;
10260 /* Leave preferred unchanged (MUST be a valid mode!) */
10261 }
10262 }
10263
10264 /* Now seek the detailed timing descriptions for custom panels */
10265 if(paneltype == Panel_Custom) {
10266
10267 SiS_Pr->CP_Supports64048075 = TRUE;
10268
10269 index += (numcodes * 4);
10270 numcodes = buffer[0x7f] & 0x07;
10271 for(i=0; i<numcodes; i++, index += 18) {
10272 xres = buffer[index+2] | ((buffer[index+4] & 0xf0) << 4);
10273 yres = buffer[index+5] | ((buffer[index+7] & 0xf0) << 4);
10274
10275 SiS_Pr->CP_HDisplay[i] = xres;
10276 SiS_Pr->CP_HSyncStart[i] = xres + (buffer[index+8] | ((buffer[index+11] & 0xc0) << 2));
10277 SiS_Pr->CP_HSyncEnd[i] = SiS_Pr->CP_HSyncStart[i] + (buffer[index+9] | ((buffer[index+11] & 0x30) << 4));
10278 SiS_Pr->CP_HTotal[i] = xres + (buffer[index+3] | ((buffer[index+4] & 0x0f) << 8));
10279 SiS_Pr->CP_HBlankStart[i] = xres + 1;
10280 SiS_Pr->CP_HBlankEnd[i] = SiS_Pr->CP_HTotal[i];
10281
10282 SiS_Pr->CP_VDisplay[i] = yres;
10283 SiS_Pr->CP_VSyncStart[i] = yres + (((buffer[index+10] & 0xf0) >> 4) | ((buffer[index+11] & 0x0c) << 2));
10284 SiS_Pr->CP_VSyncEnd[i] = SiS_Pr->CP_VSyncStart[i] + ((buffer[index+10] & 0x0f) | ((buffer[index+11] & 0x03) << 4));
10285 SiS_Pr->CP_VTotal[i] = yres + (buffer[index+6] | ((buffer[index+7] & 0x0f) << 8));
10286 SiS_Pr->CP_VBlankStart[i] = yres + 1;
10287 SiS_Pr->CP_VBlankEnd[i] = SiS_Pr->CP_VTotal[i];
10288
10289 SiS_Pr->CP_Clock[i] = (buffer[index] | (buffer[index+1] << 8)) * 10;
10290
10291 SiS_Pr->CP_DataValid[i] = TRUE;
10292
10293 if((SiS_Pr->CP_HDisplay[i] & 7) ||
10294 (SiS_Pr->CP_HDisplay[i] > SiS_Pr->CP_HSyncStart[i]) ||
10295 (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HSyncEnd[i]) ||
10296 (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HTotal[i]) ||
10297 (SiS_Pr->CP_HSyncStart[i] >= SiS_Pr->CP_HSyncEnd[i]) ||
10298 (SiS_Pr->CP_HSyncStart[i] > SiS_Pr->CP_HTotal[i]) ||
10299 (SiS_Pr->CP_HSyncEnd[i] > SiS_Pr->CP_HTotal[i]) ||
10300 (SiS_Pr->CP_VDisplay[i] > SiS_Pr->CP_VSyncStart[i]) ||
10301 (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VSyncEnd[i]) ||
10302 (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VTotal[i]) ||
10303 (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VSyncEnd[i]) ||
10304 (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VTotal[i]) ||
10305 (SiS_Pr->CP_VSyncEnd[i] > SiS_Pr->CP_VTotal[i]) ||
10306 (((pSiS->VBFlags & VB_301C) && (SiS_Pr->CP_Clock[i] > 162500)) ||
10307 ((!(pSiS->VBFlags & VB_301C)) &&
10308 ((SiS_Pr->CP_Clock[i] > 108200) || (SiS_Pr->CP_VDisplay[i] > 1024)))) ||
10309 (buffer[index + 17] & 0x80)) {
10310
10311 SiS_Pr->CP_DataValid[i] = FALSE;
10312
10313 } else {
10314
10315 SiS_Pr->CP_HaveCustomData = TRUE;
10316
10317 if(SiS_Pr->CP_Clock[i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = SiS_Pr->CP_Clock[i];
10318
10319 if((SiS_Pr->CP_PreferredX == xres) && (SiS_Pr->CP_PreferredY == yres)) {
10320 SiS_Pr->CP_PreferredIndex = i;
10321 SiS_MakeClockRegs(pSiS->pScrn, SiS_Pr->CP_Clock[i], &SiS_Pr->CP_PrefSR2B, &SiS_Pr->CP_PrefSR2C);
10322 SiS_Pr->CP_PrefClock = (SiS_Pr->CP_Clock[i] / 1000) + 1;
10323 if(!havesync) {
10324 cr37 |= ((((buffer[index + 17] & 0x06) ^ 0x06) << 5) | 0x20);
10325 havesync = TRUE;
10326 }
10327 }
10328
10329 SiS_Pr->CP_HSync_P[i] = (buffer[index + 17] & 0x02) ? TRUE : FALSE;
10330 SiS_Pr->CP_VSync_P[i] = (buffer[index + 17] & 0x04) ? TRUE : FALSE;
10331 SiS_Pr->CP_SyncValid[i] = TRUE;
10332
10333 }
10334 }
10335
10336 cr37 |= 0x10;
10337
10338 }
10339
10340 break;
10341
10342 }
10343
10344 /* 1280x960 panels are always RGB24, unable to scale and use
10345 * high active sync polarity
10346 */
10347 if(pSiS->VGAEngine == SIS_315_VGA) {
10348 if(paneltype == Panel310_1280x960) cr37 &= 0x0e;
10349 } else {
10350 if(paneltype == Panel300_1280x960) cr37 &= 0x0e;
10351 }
10352
10353 for(i = 0; i < 7; i++) {
10354 if(SiS_Pr->CP_DataValid[i]) {
10355 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10356 "Non-standard LCD/DVI-D timing data no. %d:\n", i);
10357 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10358 " HDisplay %d HSync %d HSyncEnd %d HTotal %d\n",
10359 SiS_Pr->CP_HDisplay[i], SiS_Pr->CP_HSyncStart[i],
10360 SiS_Pr->CP_HSyncEnd[i], SiS_Pr->CP_HTotal[i]);
10361 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10362 " VDisplay %d VSync %d VSyncEnd %d VTotal %d\n",
10363 SiS_Pr->CP_VDisplay[i], SiS_Pr->CP_VSyncStart[i],
10364 SiS_Pr->CP_VSyncEnd[i], SiS_Pr->CP_VTotal[i]);
10365 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10366 " Pixel clock: %3.3fMhz\n", (float)SiS_Pr->CP_Clock[i] / 1000);
10367 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO,
10368 " To use this, add \"%dx%d\" to the list of Modes in the Screen section\n",
10369 SiS_Pr->CP_HDisplay[i],
10370 SiS_Pr->CP_VDisplay[i]);
10371 }
10372 }
10373
10374 if(paneltype) {
10375 if(!SiS_Pr->CP_PreferredX) SiS_Pr->CP_PreferredX = SiS_Pr->CP_MaxX;
10376 if(!SiS_Pr->CP_PreferredY) SiS_Pr->CP_PreferredY = SiS_Pr->CP_MaxY;
10377 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x32,0x08);
10378 SiS_SetReg(SiS_Pr->SiS_P3d4,0x36,paneltype);
10379 cr37 &= 0xf1;
10380 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x37,0x0c,cr37);
10381 SiS_Pr->PanelSelfDetected = TRUE;
10382#ifdef TWDEBUG
10383 xf86DrvMsgVerb(pSiS->pScrn->scrnIndex, X_PROBED, 3,
10384 "LCD sense: [DDC LCD results: 0x%02x, 0x%02x]\n", paneltype, cr37);
10385#endif
10386 } else {
10387 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x32,~0x08);
10388 SiS_SetReg(SiS_Pr->SiS_P3d4,0x36,0x00);
10389 }
10390 return 0;
10391}
10392
10393USHORT
10394SiS_SenseVGA2DDC(SiS_Private *SiS_Pr, SISPtr pSiS)
10395{
10396 USHORT DDCdatatype,flag;
10397 BOOLEAN foundcrt = FALSE;
10398 int retry;
10399 unsigned char buffer[256];
10400
10401 if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) return 0;
10402
10403 if(SiS_InitDDCRegs(SiS_Pr, pSiS->VBFlags, pSiS->VGAEngine, 2, 0, FALSE) == 0xFFFF) return 0;
10404
10405 SiS_Pr->SiS_DDC_SecAddr = 0x00;
10406
10407 /* Probe supported DA's */
10408 flag = SiS_ProbeDDC(SiS_Pr);
10409 if(flag & 0x10) {
10410 SiS_Pr->SiS_DDC_DeviceAddr = 0xa6; /* EDID V2 (FP) */
10411 DDCdatatype = 4;
10412 } else if(flag & 0x08) {
10413 SiS_Pr->SiS_DDC_DeviceAddr = 0xa2; /* EDID V2 (P&D-D Monitor) */
10414 DDCdatatype = 3;
10415 } else if(flag & 0x02) {
10416 SiS_Pr->SiS_DDC_DeviceAddr = 0xa0; /* EDID V1 */
10417 DDCdatatype = 1;
10418 } else {
10419 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10420 "VGA2 sense: Do DDC answer\n");
10421 return 0; /* no DDC support (or no device attached) */
10422 }
10423
10424 /* Read the entire EDID */
10425 retry = 2;
10426 do {
10427 if(SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer)) {
10428 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10429 "VGA2 sense: DDC read failed (attempt %d), %s\n",
10430 (3-retry), (retry == 1) ? "giving up" : "retrying");
10431 retry--;
10432 if(retry == 0) return 0xFFFF;
10433 } else break;
10434 } while(1);
10435
10436 /* Analyze EDID. We don't have many chances to
10437 * distinguish a flat panel from a CRT...
10438 */
10439 switch(DDCdatatype) {
10440 case 1:
10441 if(!(checkedid1(buffer))) {
10442 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_ERROR,
10443 "VGA2 sense: EDID corrupt\n");
10444 return 0;
10445 }
10446 if(buffer[0x14] & 0x80) { /* Display uses digital input */
10447 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_ERROR,
10448 "VGA2 sense: Attached display expects digital input\n");
10449 return 0;
10450 }
10451 SiS_Pr->CP_Vendor = buffer[9] | (buffer[8] << 8);
10452 SiS_Pr->CP_Product = buffer[10] | (buffer[11] << 8);
10453 foundcrt = TRUE;
10454 break;
10455 case 3:
10456 case 4:
10457 if(!(checkedid2(buffer))) {
10458 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_ERROR,
10459 "VGA2 sense: EDID corrupt\n");
10460 return 0;
10461 }
10462 if( ((buffer[0x41] & 0x0f) != 0x01) && /* Display does not support analog input */
10463 ((buffer[0x41] & 0x0f) != 0x02) &&
10464 ((buffer[0x41] & 0xf0) != 0x10) &&
10465 ((buffer[0x41] & 0xf0) != 0x20) ) {
10466 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_ERROR,
10467 "VGA2 sense: Attached display does not support analog input (0x%02x)\n",
10468 buffer[0x41]);
10469 return 0;
10470 }
10471 SiS_Pr->CP_Vendor = buffer[2] | (buffer[1] << 8);
10472 SiS_Pr->CP_Product = buffer[3] | (buffer[4] << 8);
10473 foundcrt = TRUE;
10474 break;
10475 }
10476
10477 if(foundcrt) {
10478 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x32,0x10);
10479 }
10480 return(0);
10481}
10482
10483#endif
10484
10485void
10486SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, USHORT tempax,USHORT tempbh)
10487{
10488 USHORT tempbl;
10489
10490 tempbl = SiS_GetCH70xx(SiS_Pr,(tempax & 0x00FF));
10491 tempbl = (((tempbl & tempbh) << 8) | tempax);
10492 SiS_SetCH70xx(SiS_Pr,tempbl);
10493}
10494
10495/* Generic I2C functions for Chrontel & DDC --------- */
10496
10497static void
10498SiS_SetSwitchDDC2(SiS_Private *SiS_Pr)
10499{
10500 SiS_SetSCLKHigh(SiS_Pr);
10501 SiS_WaitRetrace1(SiS_Pr);
10502
10503 SiS_SetSCLKLow(SiS_Pr);
10504 SiS_WaitRetrace1(SiS_Pr);
10505}
10506
10507USHORT
10508SiS_ReadDDC1Bit(SiS_Private *SiS_Pr)
10509{
10510 SiS_WaitRetrace1(SiS_Pr);
10511 return((SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x02) >> 1);
10512}
10513
10514/* Set I2C start condition */
10515/* This is done by a SD high-to-low transition while SC is high */
10516static USHORT
10517SiS_SetStart(SiS_Private *SiS_Pr)
10518{
10519 if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */
10520 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10521 SiS_Pr->SiS_DDC_Index,
10522 SiS_Pr->SiS_DDC_NData,
10523 SiS_Pr->SiS_DDC_Data); /* SD->high */
10524 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */
10525 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10526 SiS_Pr->SiS_DDC_Index,
10527 SiS_Pr->SiS_DDC_NData,
10528 0x00); /* SD->low = start condition */
10529 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->low) */
10530 return 0;
10531}
10532
10533/* Set I2C stop condition */
10534/* This is done by a SD low-to-high transition while SC is high */
10535static USHORT
10536SiS_SetStop(SiS_Private *SiS_Pr)
10537{
10538 if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */
10539 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10540 SiS_Pr->SiS_DDC_Index,
10541 SiS_Pr->SiS_DDC_NData,
10542 0x00); /* SD->low */
10543 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */
10544 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10545 SiS_Pr->SiS_DDC_Index,
10546 SiS_Pr->SiS_DDC_NData,
10547 SiS_Pr->SiS_DDC_Data); /* SD->high = stop condition */
10548 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->high) */
10549 return 0;
10550}
10551
10552/* Write 8 bits of data */
10553static USHORT
10554SiS_WriteDDC2Data(SiS_Private *SiS_Pr, USHORT tempax)
10555{
10556 USHORT i,flag,temp;
10557
10558 flag = 0x80;
10559 for(i=0; i<8; i++) {
10560 SiS_SetSCLKLow(SiS_Pr); /* SC->low */
10561 if(tempax & flag) {
10562 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10563 SiS_Pr->SiS_DDC_Index,
10564 SiS_Pr->SiS_DDC_NData,
10565 SiS_Pr->SiS_DDC_Data); /* Write bit (1) to SD */
10566 } else {
10567 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10568 SiS_Pr->SiS_DDC_Index,
10569 SiS_Pr->SiS_DDC_NData,
10570 0x00); /* Write bit (0) to SD */
10571 }
10572 SiS_SetSCLKHigh(SiS_Pr); /* SC->high */
10573 flag >>= 1;
10574 }
10575 temp = SiS_CheckACK(SiS_Pr); /* Check acknowledge */
10576 return(temp);
10577}
10578
10579static USHORT
10580SiS_ReadDDC2Data(SiS_Private *SiS_Pr, USHORT tempax)
10581{
10582 USHORT i,temp,getdata;
10583
10584 getdata=0;
10585 for(i=0; i<8; i++) {
10586 getdata <<= 1;
10587 SiS_SetSCLKLow(SiS_Pr);
10588 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10589 SiS_Pr->SiS_DDC_Index,
10590 SiS_Pr->SiS_DDC_NData,
10591 SiS_Pr->SiS_DDC_Data);
10592 SiS_SetSCLKHigh(SiS_Pr);
10593 temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
10594 if(temp & SiS_Pr->SiS_DDC_Data) getdata |= 0x01;
10595 }
10596 return(getdata);
10597}
10598
10599static USHORT
10600SiS_SetSCLKLow(SiS_Private *SiS_Pr)
10601{
10602 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10603 SiS_Pr->SiS_DDC_Index,
10604 SiS_Pr->SiS_DDC_NClk,
10605 0x00); /* SetSCLKLow() */
10606 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
10607 return 0;
10608}
10609
10610static USHORT
10611SiS_SetSCLKHigh(SiS_Private *SiS_Pr)
10612{
10613 USHORT temp, watchdog=1000;
10614
10615 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10616 SiS_Pr->SiS_DDC_Index,
10617 SiS_Pr->SiS_DDC_NClk,
10618 SiS_Pr->SiS_DDC_Clk); /* SetSCLKHigh() */
10619 do {
10620 temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
10621 } while((!(temp & SiS_Pr->SiS_DDC_Clk)) && --watchdog);
10622 if (!watchdog) {
10623#ifdef TWDEBUG
10624 xf86DrvMsg(0, X_INFO, "SetClkHigh failed\n");
10625#endif
10626 return 0xFFFF;
10627 }
10628 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
10629 return 0;
10630}
10631
10632/* Check I2C acknowledge */
10633/* Returns 0 if ack ok, non-0 if ack not ok */
10634static USHORT
10635SiS_CheckACK(SiS_Private *SiS_Pr)
10636{
10637 USHORT tempah;
10638
10639 SiS_SetSCLKLow(SiS_Pr); /* (SC->low) */
10640 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10641 SiS_Pr->SiS_DDC_Index,
10642 SiS_Pr->SiS_DDC_NData,
10643 SiS_Pr->SiS_DDC_Data); /* (SD->high) */
10644 SiS_SetSCLKHigh(SiS_Pr); /* SC->high = clock impulse for ack */
10645 tempah = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); /* Read SD */
10646 SiS_SetSCLKLow(SiS_Pr); /* SC->low = end of clock impulse */
10647 if(tempah & SiS_Pr->SiS_DDC_Data) return(1); /* Ack OK if bit = 0 */
10648 else return(0);
10649}
10650
10651/* End of I2C functions ----------------------- */
10652
10653
10654/* =============== SiS 315/330 O.E.M. ================= */
10655
10656#ifdef SIS315H
10657
10658static USHORT
10659GetRAMDACromptr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
10660{
10661 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
10662 USHORT romptr;
10663
10664 if(HwInfo->jChipType < SIS_330) {
10665 romptr = SISGETROMW(0x128);
10666 if(SiS_Pr->SiS_VBType & VB_SIS301B302B)
10667 romptr = SISGETROMW(0x12a);
10668 } else {
10669 romptr = SISGETROMW(0x1a8);
10670 if(SiS_Pr->SiS_VBType & VB_SIS301B302B)
10671 romptr = SISGETROMW(0x1aa);
10672 }
10673 return(romptr);
10674}
10675
10676static USHORT
10677GetLCDromptr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
10678{
10679 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
10680 USHORT romptr;
10681
10682 if(HwInfo->jChipType < SIS_330) {
10683 romptr = SISGETROMW(0x120);
10684 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
10685 romptr = SISGETROMW(0x122);
10686 } else {
10687 romptr = SISGETROMW(0x1a0);
10688 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
10689 romptr = SISGETROMW(0x1a2);
10690 }
10691 return(romptr);
10692}
10693
10694static USHORT
10695GetTVromptr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
10696{
10697 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
10698 USHORT romptr;
10699
10700 if(HwInfo->jChipType < SIS_330) {
10701 romptr = SISGETROMW(0x114);
10702 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
10703 romptr = SISGETROMW(0x11a);
10704 } else {
10705 romptr = SISGETROMW(0x194);
10706 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
10707 romptr = SISGETROMW(0x19a);
10708 }
10709 return(romptr);
10710}
10711
10712static USHORT
10713GetLCDPtrIndexBIOS(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
10714{
10715 USHORT index;
10716
10717 if((IS_SIS650) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
10718 if(!(SiS_IsNotM650orLater(SiS_Pr, HwInfo))) {
10719 if((index = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0)) {
10720 index >>= 4;
10721 index *= 3;
10722 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
10723 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
10724 return index;
10725 }
10726 }
10727 }
10728
10729 index = SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F;
10730 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) index -= 5;
10731 else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 6;
10732 index--;
10733 index *= 3;
10734 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
10735 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
10736 return index;
10737}
10738
10739static USHORT
10740GetLCDPtrIndex(SiS_Private *SiS_Pr)
10741{
10742 USHORT index;
10743
10744 index = ((SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F) - 1) * 3;
10745 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
10746 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
10747 return index;
10748}
10749
10750static USHORT
10751GetTVPtrIndex(SiS_Private *SiS_Pr)
10752{
10753 USHORT index;
10754
10755 index = 0;
10756 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
10757 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index = 2;
10758
10759 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) index = 0;
10760
10761 index <<= 1;
10762
10763 if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) &&
10764 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
10765 index++;
10766 }
10767
10768 return index;
10769}
10770
10771static ULONG
10772GetOEMTVPtr661_2_GEN(SiS_Private *SiS_Pr, int addme)
10773{
10774 USHORT index = 0, temp = 0;
10775
10776 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
10777 if(SiS_Pr->SiS_TVMode & TVSetPALM) index = 2;
10778 if(SiS_Pr->SiS_TVMode & TVSetPALN) index = 3;
10779 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 6;
10780 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
10781 index = 4;
10782 if(SiS_Pr->SiS_TVMode & TVSetPALM) index++;
10783 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 7;
10784 }
10785
10786 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
10787 if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
10788 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
10789 index += addme;
10790 temp++;
10791 }
10792 temp += 0x0100;
10793 }
10794 return(ULONG)(index | (temp << 16));
10795}
10796
10797static ULONG
10798GetOEMTVPtr661_2_OLD(SiS_Private *SiS_Pr)
10799{
10800 return(GetOEMTVPtr661_2_GEN(SiS_Pr, 8));
10801}
10802
10803#if 0
10804static ULONG
10805GetOEMTVPtr661_2_NEW(SiS_Private *SiS_Pr)
10806{
10807 return(GetOEMTVPtr661_2_GEN(SiS_Pr, 6));
10808}
10809#endif
10810
10811static int
10812GetOEMTVPtr661(SiS_Private *SiS_Pr)
10813{
10814 int index = 0;
10815
10816 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 2;
10817 if(SiS_Pr->SiS_ROMNew) {
10818 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 4;
10819 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 6;
10820 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 8;
10821 if(SiS_Pr->SiS_TVMode & TVSetHiVision) index = 10;
10822 } else {
10823 if(SiS_Pr->SiS_TVMode & TVSetHiVision) index = 4;
10824 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 6;
10825 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 8;
10826 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 10;
10827 }
10828
10829 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) index++;
10830
10831 return index;
10832}
10833
10834static void
10835SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
10836{
10837 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
10838 USHORT delay=0,index,myindex,temp,romptr=0;
10839 BOOLEAN dochiptest = TRUE;
10840
10841 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10842 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x20,0xbf);
10843 } else {
10844 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x35,0x7f);
10845 }
10846
10847 /* Find delay (from ROM, internal tables, PCI subsystem) */
10848
10849 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) { /* ------------ VGA */
10850
10851 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10852 romptr = GetRAMDACromptr(SiS_Pr, HwInfo);
10853 }
10854 if(romptr) delay = ROMAddr[romptr];
10855 else {
10856 delay = 0x04;
10857 if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
10858 if(IS_SIS650) {
10859 delay = 0x0a;
10860 } else if(IS_SIS740) {
10861 delay = 0x00;
10862 } else if(HwInfo->jChipType < SIS_330) {
10863 delay = 0x0c;
10864 } else {
10865 delay = 0x0c;
10866 }
10867 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
10868 delay = 0x00;
10869 }
10870 }
10871
10872 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD|SetCRT2ToLCDA)) { /* ---------- LCD/LCDA */
10873
10874 BOOLEAN gotitfrompci = FALSE;
10875
10876 /* Could we detect a PDC for LCD or did we get a user-defined? If yes, use it */
10877
10878 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
10879 if(SiS_Pr->PDC != -1) {
10880 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((SiS_Pr->PDC >> 1) & 0x0f));
10881 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((SiS_Pr->PDC & 0x01) << 7));
10882 return;
10883 }
10884 } else {
10885 if(SiS_Pr->PDCA != -1) {
10886 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((SiS_Pr->PDCA << 3) & 0xf0));
10887 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((SiS_Pr->PDCA & 0x01) << 6));
10888 return;
10889 }
10890 }
10891
10892 /* Custom Panel? */
10893
10894 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) {
10895 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10896 delay = 0x00;
10897 if((SiS_Pr->PanelXRes <= 1280) && (SiS_Pr->PanelYRes <= 1024)) {
10898 delay = 0x20;
10899 }
10900 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,delay);
10901 } else {
10902 delay = 0x0c;
10903 if(SiS_Pr->SiS_VBType & VB_SIS301C) delay = 0x03;
10904 else if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
10905 if(IS_SIS740) delay = 0x01;
10906 else delay = 0x03;
10907 }
10908 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,delay);
10909 }
10910 return;
10911 }
10912
10913 /* This is a piece of typical SiS crap: They code the OEM LCD
10914 * delay into the code, at no defined place in the BIOS.
10915 * We now have to start doing a PCI subsystem check here.
10916 */
10917
10918 switch(SiS_Pr->SiS_CustomT) {
10919 case CUT_COMPAQ1280:
10920 case CUT_COMPAQ12802:
10921 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
10922 gotitfrompci = TRUE;
10923 dochiptest = FALSE;
10924 delay = 0x03;
10925 }
10926 break;
10927 case CUT_CLEVO1400:
10928 case CUT_CLEVO14002:
10929 gotitfrompci = TRUE;
10930 dochiptest = FALSE;
10931 delay = 0x02;
10932 break;
10933 case CUT_CLEVO1024:
10934 case CUT_CLEVO10242:
10935 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10936 gotitfrompci = TRUE;
10937 dochiptest = FALSE;
10938 delay = 0x33;
10939 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
10940 delay &= 0x0f;
10941 }
10942 break;
10943 }
10944
10945 /* Could we find it through the PCI ID? If no, use ROM or table */
10946
10947 if(!gotitfrompci) {
10948
10949 index = GetLCDPtrIndexBIOS(SiS_Pr, HwInfo);
10950 myindex = GetLCDPtrIndex(SiS_Pr);
10951
10952 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
10953
10954 if(SiS_IsNotM650orLater(SiS_Pr, HwInfo)) {
10955
10956 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10957 /* Always use the second pointer on 650; some BIOSes */
10958 /* still carry old 301 data at the first location */
10959 /* romptr = SISGETROMW(0x120); */
10960 /* if(SiS_Pr->SiS_VBType & VB_SIS302LV) */
10961 romptr = SISGETROMW(0x122);
10962 if(!romptr) return;
10963 delay = ROMAddr[(romptr + index)];
10964 } else {
10965 delay = SiS310_LCDDelayCompensation_650301LV[myindex];
10966 }
10967
10968 } else {
10969
10970 delay = SiS310_LCDDelayCompensation_651301LV[myindex];
10971 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV))
10972 delay = SiS310_LCDDelayCompensation_651302LV[myindex];
10973
10974 }
10975
10976 } else if(SiS_Pr->SiS_UseROM &&
10977 (!(SiS_Pr->SiS_ROMNew)) &&
10978 (SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) &&
10979 (SiS_Pr->SiS_LCDResInfo != Panel_1280x768) &&
10980 (SiS_Pr->SiS_LCDResInfo != Panel_1280x960)) {
10981
10982 /* Data for 1280x1024 wrong in 301B BIOS */
10983 romptr = GetLCDromptr(SiS_Pr, HwInfo);
10984 if(!romptr) return;
10985 delay = ROMAddr[(romptr + index)];
10986
10987 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
10988
10989 if(IS_SIS740) delay = 0x03;
10990 else delay = 0x00;
10991
10992 } else {
10993
10994 delay = SiS310_LCDDelayCompensation_301[myindex];
10995 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
10996 if(IS_SIS740) delay = 0x01;
10997 else if(HwInfo->jChipType <= SIS_315PRO) delay = SiS310_LCDDelayCompensation_3xx301LV[myindex];
10998 else delay = SiS310_LCDDelayCompensation_650301LV[myindex];
10999 } else if(SiS_Pr->SiS_VBType & VB_SIS301C) {
11000 if(IS_SIS740) delay = 0x01; /* ? */
11001 else delay = 0x03;
11002 } else if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
11003 if(IS_SIS740) delay = 0x01;
11004 else delay = SiS310_LCDDelayCompensation_3xx301B[myindex];
11005 }
11006
11007 }
11008
11009 } /* got it from PCI */
11010
11011 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
11012 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,((delay << 4) & 0xf0));
11013 dochiptest = FALSE;
11014 }
11015
11016 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* ------------ TV */
11017
11018 index = GetTVPtrIndex(SiS_Pr);
11019
11020 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
11021
11022 if(SiS_IsNotM650orLater(SiS_Pr,HwInfo)) {
11023
11024 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
11025 /* Always use the second pointer on 650; some BIOSes */
11026 /* still carry old 301 data at the first location */
11027 /* romptr = SISGETROMW(0x114); */
11028 /* if(SiS_Pr->SiS_VBType & VB_SIS302LV) */
11029 romptr = SISGETROMW(0x11a);
11030 if(!romptr) return;
11031 delay = ROMAddr[romptr + index];
11032
11033 } else {
11034
11035 delay = SiS310_TVDelayCompensation_301B[index];
11036
11037 }
11038
11039 } else {
11040
11041 switch(SiS_Pr->SiS_CustomT) {
11042 case CUT_COMPAQ1280:
11043 case CUT_COMPAQ12802:
11044 case CUT_CLEVO1400:
11045 case CUT_CLEVO14002:
11046 delay = 0x02;
11047 dochiptest = FALSE;
11048 break;
11049 case CUT_CLEVO1024:
11050 case CUT_CLEVO10242:
11051 delay = 0x03;
11052 dochiptest = FALSE;
11053 break;
11054 default:
11055 delay = SiS310_TVDelayCompensation_651301LV[index];
11056 if(SiS_Pr->SiS_VBType & VB_SIS302LV) {
11057 delay = SiS310_TVDelayCompensation_651302LV[index];
11058 }
11059 }
11060 }
11061
11062 } else if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
11063
11064 romptr = GetTVromptr(SiS_Pr, HwInfo);
11065 if(!romptr) return;
11066 delay = ROMAddr[romptr + index];
11067
11068 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
11069
11070 delay = SiS310_TVDelayCompensation_LVDS[index];
11071
11072 } else {
11073
11074 delay = SiS310_TVDelayCompensation_301[index];
11075 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
11076 if(IS_SIS740) {
11077 delay = SiS310_TVDelayCompensation_740301B[index];
11078 /* LV: use 301 data? BIOS bug? */
11079 } else {
11080 delay = SiS310_TVDelayCompensation_301B[index];
11081 if(SiS_Pr->SiS_VBType & VB_SIS301C) delay = 0x02;
11082 }
11083 }
11084
11085 }
11086
11087 if(SiS_LCDAEnabled(SiS_Pr, HwInfo)) {
11088 delay &= 0x0f;
11089 dochiptest = FALSE;
11090 }
11091
11092 } else return;
11093
11094 /* Write delay */
11095
11096 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11097
11098 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && dochiptest) {
11099
11100 temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0) >> 4;
11101 if(temp == 8) { /* 1400x1050 BIOS (COMPAL) */
11102 delay &= 0x0f;
11103 delay |= 0xb0;
11104 } else if(temp == 6) {
11105 delay &= 0x0f;
11106 delay |= 0xc0;
11107 } else if(temp > 7) { /* 1280x1024 BIOS (which one?) */
11108 delay = 0x35;
11109 }
11110 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
11111
11112 } else {
11113
11114 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
11115
11116 }
11117
11118 } else { /* LVDS */
11119
11120 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
11121 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
11122 } else {
11123 if(IS_SIS650 && (SiS_Pr->SiS_IF_DEF_CH70xx != 0)) {
11124 delay <<= 4;
11125 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,delay);
11126 } else {
11127 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
11128 }
11129 }
11130
11131 }
11132
11133}
11134
11135static void
11136SetAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11137 USHORT ModeNo,USHORT ModeIdIndex)
11138{
11139 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11140 USHORT index,temp,temp1,romptr=0;
11141
11142 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p|TVSetYPbPr525p)) return;
11143
11144 if(ModeNo<=0x13)
11145 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex;
11146 else
11147 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex;
11148
11149 temp = GetTVPtrIndex(SiS_Pr);
11150 temp >>= 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
11151 temp1 = temp;
11152
11153 if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
11154 if(HwInfo->jChipType >= SIS_661) {
11155 temp1 = GetOEMTVPtr661(SiS_Pr);
11156 temp1 >>= 1;
11157 romptr = SISGETROMW(0x260);
11158 if(HwInfo->jChipType >= SIS_760) {
11159 romptr = SISGETROMW(0x360);
11160 }
11161 } else if(HwInfo->jChipType >= SIS_330) {
11162 romptr = SISGETROMW(0x192);
11163 } else {
11164 romptr = SISGETROMW(0x112);
11165 }
11166 }
11167
11168 if(romptr) {
11169 temp1 <<= 1;
11170 temp = ROMAddr[romptr + temp1 + index];
11171 } else {
11172 temp = SiS310_TVAntiFlick1[temp][index];
11173 }
11174 temp <<= 4;
11175
11176 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8f,temp); /* index 0A D[6:4] */
11177}
11178
11179static void
11180SetEdgeEnhance(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11181 USHORT ModeNo,USHORT ModeIdIndex)
11182{
11183 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11184 USHORT index,temp,temp1,romptr=0;
11185
11186 temp = temp1 = GetTVPtrIndex(SiS_Pr) >> 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
11187
11188 if(ModeNo <= 0x13)
11189 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;
11190 else
11191 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;
11192
11193 if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
11194 if(HwInfo->jChipType >= SIS_661) {
11195 romptr = SISGETROMW(0x26c);
11196 if(HwInfo->jChipType >= SIS_760) {
11197 romptr = SISGETROMW(0x36c);
11198 }
11199 temp1 = GetOEMTVPtr661(SiS_Pr);
11200 temp1 >>= 1;
11201 } else if(HwInfo->jChipType >= SIS_330) {
11202 romptr = SISGETROMW(0x1a4);
11203 } else {
11204 romptr = SISGETROMW(0x124);
11205 }
11206 }
11207
11208 if(romptr) {
11209 temp1 <<= 1;
11210 temp = ROMAddr[romptr + temp1 + index];
11211 } else {
11212 temp = SiS310_TVEdge1[temp][index];
11213 }
11214 temp <<= 5;
11215 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x3A,0x1F,temp); /* index 0A D[7:5] */
11216}
11217
11218static void
11219SetYFilter(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11220 USHORT ModeNo,USHORT ModeIdIndex)
11221{
11222 USHORT index, temp, i, j;
11223
11224 if(ModeNo <= 0x13) {
11225 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
11226 } else {
11227 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
11228 }
11229
11230 temp = GetTVPtrIndex(SiS_Pr) >> 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
11231
11232 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp = 1; /* NTSC-J uses PAL */
11233 else if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 3; /* PAL-M */
11234 else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 4; /* PAL-N */
11235 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp = 1; /* HiVision uses PAL */
11236
11237 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
11238 for(i=0x35, j=0; i<=0x38; i++, j++) {
11239 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
11240 }
11241 for(i=0x48; i<=0x4A; i++, j++) {
11242 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
11243 }
11244 } else {
11245 for(i=0x35, j=0; i<=0x38; i++, j++) {
11246 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter1[temp][index][j]);
11247 }
11248 }
11249}
11250
11251static void
11252SetPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11253 USHORT ModeNo,USHORT ModeIdIndex)
11254{
11255 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11256 USHORT index,temp,i,j,resinfo,romptr=0;
11257 ULONG lindex;
11258
11259 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
11260
11261 /* NTSC-J data not in BIOS, and already set in SetGroup2 */
11262 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) return;
11263
11264 if((HwInfo->jChipType >= SIS_661) || SiS_Pr->SiS_ROMNew) {
11265 lindex = GetOEMTVPtr661_2_OLD(SiS_Pr) & 0xffff;
11266 lindex <<= 2;
11267 for(j=0, i=0x31; i<=0x34; i++, j++) {
11268 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS661_TVPhase[lindex + j]);
11269 }
11270 return;
11271 }
11272
11273 /* PAL-M, PAL-N not in BIOS, and already set in SetGroup2 */
11274 if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) return;
11275
11276 if(ModeNo<=0x13) {
11277 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
11278 } else {
11279 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
11280 }
11281
11282 temp = GetTVPtrIndex(SiS_Pr);
11283 /* 0: NTSC Graphics, 1: NTSC Text, 2: PAL Graphics,
11284 * 3: PAL Text, 4: HiTV Graphics 5: HiTV Text
11285 */
11286 if(SiS_Pr->SiS_UseROM) {
11287 romptr = SISGETROMW(0x116);
11288 if(HwInfo->jChipType >= SIS_330) {
11289 romptr = SISGETROMW(0x196);
11290 }
11291 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
11292 romptr = SISGETROMW(0x11c);
11293 if(HwInfo->jChipType >= SIS_330) {
11294 romptr = SISGETROMW(0x19c);
11295 }
11296 if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode))) {
11297 romptr = SISGETROMW(0x116);
11298 if(HwInfo->jChipType >= SIS_330) {
11299 romptr = SISGETROMW(0x196);
11300 }
11301 }
11302 }
11303 }
11304 if(romptr) {
11305 romptr += (temp << 2);
11306 for(j=0, i=0x31; i<=0x34; i++, j++) {
11307 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
11308 }
11309 } else {
11310 index = temp % 2;
11311 temp >>= 1; /* 0:NTSC, 1:PAL, 2:HiTV */
11312 for(j=0, i=0x31; i<=0x34; i++, j++) {
11313 if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV))
11314 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
11315 else if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || (SiS_Pr->SiS_TVMode & TVSetTVSimuMode))
11316 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr2[temp][index][j]);
11317 else
11318 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
11319 }
11320 }
11321
11322 if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision))) {
11323 if((!(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetYPbPr525p | TVSetYPbPr750p))) && (ModeNo > 0x13)) {
11324 if((resinfo == SIS_RI_640x480) ||
11325 (resinfo == SIS_RI_800x600)) {
11326 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x21);
11327 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0xf0);
11328 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xf5);
11329 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7f);
11330 } else if(resinfo == SIS_RI_1024x768) {
11331 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x1e);
11332 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0x8b);
11333 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xfb);
11334 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7b);
11335 }
11336 }
11337 }
11338}
11339
11340static void
11341SetDelayComp661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo,
11342 USHORT ModeIdIndex, USHORT RTI)
11343{
11344 USHORT delay = 0, romptr = 0, index, lcdpdcindex;
11345 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11346
11347 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToRAMDAC)))
11348 return;
11349
11350 /* 1. New ROM: VGA2 and LCD/LCDA-Pass1:1 */
11351 /* (If a custom mode is used, Pass1:1 is always set; hence we do this:) */
11352
11353 if(SiS_Pr->SiS_ROMNew) {
11354 if((SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) ||
11355 ((SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
11356 (SiS_Pr->SiS_LCDInfo & LCDPass11))) {
11357 index = 25;
11358 if(SiS_Pr->UseCustomMode) {
11359 index = SiS_Pr->CSRClock;
11360 } else if(ModeNo > 0x13) {
11361 index = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RTI,HwInfo);
11362 index = SiS_Pr->SiS_VCLKData[index].CLOCK;
11363 }
11364 if(index < 25) index = 25;
11365 index = ((index / 25) - 1) << 1;
11366 if((ROMAddr[0x5b] & 0x80) || (SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD))) {
11367 index++;
11368 }
11369 romptr = SISGETROMW(0x104);
11370 delay = ROMAddr[romptr + index];
11371 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD)) {
11372 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
11373 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
11374 } else {
11375 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
11376 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
11377 }
11378 return;
11379 }
11380 }
11381
11382 /* 2. Old ROM: VGA2 and LCD/LCDA-Pass 1:1 */
11383
11384 if(SiS_Pr->UseCustomMode) delay = 0x04;
11385 else if(ModeNo <= 0x13) delay = 0x04;
11386 else delay = (SiS_Pr->SiS_RefIndex[RTI].Ext_PDC >> 4);
11387 delay |= (delay << 8);
11388
11389 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
11390
11391 /* 3. TV */
11392
11393 index = GetOEMTVPtr661(SiS_Pr);
11394 if(SiS_Pr->SiS_ROMNew) {
11395 romptr = SISGETROMW(0x106);
11396 if(SiS_Pr->SiS_VBType & VB_UMC) romptr += 12;
11397 delay = ROMAddr[romptr + index];
11398 } else {
11399 delay = 0x04;
11400 if(index > 3) delay = 0;
11401 }
11402
11403 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11404
11405 /* 4. LCD, LCDA (for new ROM only LV and non-Pass 1:1) */
11406
11407 if( (SiS_Pr->SiS_LCDResInfo != Panel_Custom) &&
11408 ((romptr = GetLCDStructPtr661_2(SiS_Pr, HwInfo))) ) {
11409
11410 lcdpdcindex = (SiS_Pr->SiS_VBType & VB_UMC) ? 14 : 12;
11411
11412 /* For LVDS (and sometimes TMDS), the BIOS must know about the correct value */
11413 delay = ROMAddr[romptr + lcdpdcindex + 1]; /* LCD */
11414 delay |= (ROMAddr[romptr + lcdpdcindex] << 8); /* LCDA */
11415
11416 } else {
11417
11418 /* TMDS: Set our own, since BIOS has no idea */
11419 /* (This is done on >=661 only, since <661 is calling this only for LVDS) */
11420 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
11421 switch(SiS_Pr->SiS_LCDResInfo) {
11422 case Panel_1024x768: delay = 0x0008; break;
11423 case Panel_1280x720: delay = 0x0004; break;
11424 case Panel_1280x768:
11425 case Panel_1280x768_2:delay = 0x0004; break;
11426 case Panel_1280x800:
11427 case Panel_1280x800_2:delay = 0x0004; break; /* Verified for 1280x800 */
11428 case Panel_1280x1024: delay = 0x1e04; break;
11429 case Panel_1400x1050: delay = 0x0004; break;
11430 case Panel_1600x1200: delay = 0x0400; break;
11431 case Panel_1680x1050: delay = 0x0e04; break;
11432 default:
11433 if((SiS_Pr->PanelXRes <= 1024) && (SiS_Pr->PanelYRes <= 768)) {
11434 delay = 0x0008;
11435 } else if((SiS_Pr->PanelXRes == 1280) && (SiS_Pr->PanelYRes == 1024)) {
11436 delay = 0x1e04;
11437 } else if((SiS_Pr->PanelXRes <= 1400) && (SiS_Pr->PanelYRes <= 1050)) {
11438 delay = 0x0004;
11439 } else if((SiS_Pr->PanelXRes <= 1600) && (SiS_Pr->PanelYRes <= 1200)) {
11440 delay = 0x0400;
11441 } else
11442 delay = 0x0e04;
11443 break;
11444 }
11445 }
11446
11447 /* Override by detected or user-set values */
11448 /* (but only if, for some reason, we can't read value from BIOS) */
11449 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->PDC != -1)) {
11450 delay = SiS_Pr->PDC & 0x1f;
11451 }
11452 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) && (SiS_Pr->PDCA != -1)) {
11453 delay = (SiS_Pr->PDCA & 0x1f) << 8;
11454 }
11455
11456 }
11457
11458 }
11459
11460 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
11461 delay >>= 8;
11462 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
11463 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
11464 } else {
11465 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
11466 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
11467 }
11468}
11469
11470static void
11471SetCRT2SyncDither661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo, USHORT RTI)
11472{
11473 USHORT infoflag;
11474 UCHAR temp;
11475
11476 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11477
11478 if(ModeNo <= 0x13) {
11479 infoflag = SiS_GetRegByte(SiS_Pr->SiS_P3ca+2);
11480 } else if(SiS_Pr->UseCustomMode) {
11481 infoflag = SiS_Pr->CInfoFlag;
11482 } else {
11483 infoflag = SiS_Pr->SiS_RefIndex[RTI].Ext_InfoFlag;
11484 }
11485
11486 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
11487 infoflag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37); /* No longer check D5 */
11488 }
11489
11490 infoflag &= 0xc0;
11491
11492 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
11493 temp = (infoflag >> 6) | 0x0c;
11494 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
11495 temp ^= 0x04;
11496 if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x10;
11497 }
11498 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xe0,temp);
11499 } else {
11500 temp = 0x30;
11501 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) temp = 0x20;
11502 temp |= infoflag;
11503 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0f,temp);
11504 temp = 0;
11505 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
11506 if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x80;
11507 }
11508 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0x7f,temp);
11509 }
11510
11511 }
11512}
11513
11514static void
11515SetPanelParms661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
11516{
11517 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11518 USHORT romptr, temp1, temp2;
11519
11520 if(SiS_Pr->SiS_VBType & (VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV)) {
11521 if(SiS_Pr->LVDSHL != -1) {
11522 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
11523 }
11524 }
11525
11526 if(SiS_Pr->SiS_ROMNew) {
11527
11528 if((romptr = GetLCDStructPtr661_2(SiS_Pr, HwInfo))) {
11529 if(SiS_Pr->SiS_VBType & (VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV)) {
11530 temp1 = (ROMAddr[romptr] & 0x03) | 0x0c;
11531 temp2 = 0xfc;
11532 if(SiS_Pr->LVDSHL != -1) {
11533 temp1 &= 0xfc;
11534 temp2 = 0xf3;
11535 }
11536 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,temp2,temp1);
11537 }
11538 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
11539 temp1 = (ROMAddr[romptr + 1] & 0x80) >> 1;
11540 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0d,0xbf,temp1);
11541 }
11542 }
11543
11544 }
11545}
11546
11547static void
11548SiS_OEM310Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11549 USHORT ModeNo,USHORT ModeIdIndex,USHORT RRTI)
11550{
11551 if((SiS_Pr->SiS_ROMNew) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
11552 SetDelayComp661(SiS_Pr,HwInfo,ModeNo,ModeIdIndex,RRTI);
11553 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11554 SetCRT2SyncDither661(SiS_Pr,HwInfo,ModeNo,RRTI);
11555 SetPanelParms661(SiS_Pr,HwInfo);
11556 }
11557 } else {
11558 SetDelayComp(SiS_Pr,HwInfo,ModeNo);
11559 }
11560
11561 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
11562 SetAntiFlicker(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11563 SetPhaseIncr(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11564 SetYFilter(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11565 if(SiS_Pr->SiS_VBType & VB_SIS301) {
11566 SetEdgeEnhance(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11567 }
11568 }
11569}
11570
11571static void
11572SiS_OEM661Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11573 USHORT ModeNo,USHORT ModeIdIndex, USHORT RRTI)
11574{
11575 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11576
11577 SetDelayComp661(SiS_Pr,HwInfo,ModeNo,ModeIdIndex,RRTI);
11578
11579 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11580 SetCRT2SyncDither661(SiS_Pr,HwInfo,ModeNo,RRTI);
11581 SetPanelParms661(SiS_Pr,HwInfo);
11582 }
11583
11584 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
11585 SetPhaseIncr(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11586 SetYFilter(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11587 SetAntiFlicker(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11588 if(SiS_Pr->SiS_VBType & VB_SIS301) {
11589 SetEdgeEnhance(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11590 }
11591 }
11592 }
11593}
11594
11595/* FinalizeLCD
11596 * This finalizes some CRT2 registers for the very panel used.
11597 * If we have a backup if these registers, we use it; otherwise
11598 * we set the register according to most BIOSes. However, this
11599 * function looks quite different in every BIOS, so you better
11600 * pray that we have a backup...
11601 */
11602static void
11603SiS_FinalizeLCD(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
11604 PSIS_HW_INFO HwInfo)
11605{
11606 USHORT tempcl,tempch,tempbl,tempbh,tempbx,tempax,temp;
11607 USHORT resinfo,modeflag;
11608
11609 if(!(SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) return;
11610 if(SiS_Pr->SiS_ROMNew) return;
11611
11612 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11613 if(SiS_Pr->LVDSHL != -1) {
11614 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
11615 }
11616 }
11617
11618 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
11619 if(SiS_Pr->UseCustomMode) return;
11620
11621 switch(SiS_Pr->SiS_CustomT) {
11622 case CUT_COMPAQ1280:
11623 case CUT_COMPAQ12802:
11624 case CUT_CLEVO1400:
11625 case CUT_CLEVO14002:
11626 return;
11627 }
11628
11629 if(ModeNo <= 0x13) {
11630 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
11631 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
11632 } else {
11633 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
11634 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
11635 }
11636
11637 if(IS_SIS650) {
11638 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4, 0x5f) & 0xf0)) {
11639 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
11640 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x02);
11641 } else {
11642 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
11643 }
11644 }
11645 }
11646
11647 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
11648 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11649 /* Maybe all panels? */
11650 if(SiS_Pr->LVDSHL == -1) {
11651 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
11652 }
11653 return;
11654 }
11655 }
11656
11657 if(SiS_Pr->SiS_CustomT == CUT_CLEVO10242) {
11658 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11659 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11660 if(SiS_Pr->LVDSHL == -1) {
11661 /* Maybe all panels? */
11662 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
11663 }
11664 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
11665 tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
11666 if(tempch == 3) {
11667 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
11668 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
11669 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
11670 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
11671 }
11672 }
11673 return;
11674 }
11675 }
11676 }
11677
11678 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11679 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11680 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
11681 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
11682#ifdef SET_EMI
11683 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
11684#endif
11685 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
11686 }
11687 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
11688 if(SiS_Pr->LVDSHL == -1) {
11689 /* Maybe ACER only? */
11690 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
11691 }
11692 }
11693 tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
11694 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
11695 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
11696 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1f,0x76);
11697 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11698 if(tempch == 0x03) {
11699 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
11700 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
11701 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
11702 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
11703 }
11704 if((SiS_Pr->Backup == TRUE) && (SiS_Pr->Backup_Mode == ModeNo)) {
11705 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,SiS_Pr->Backup_14);
11706 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,SiS_Pr->Backup_15);
11707 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,SiS_Pr->Backup_16);
11708 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,SiS_Pr->Backup_17);
11709 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,SiS_Pr->Backup_18);
11710 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,SiS_Pr->Backup_19);
11711 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,SiS_Pr->Backup_1a);
11712 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,SiS_Pr->Backup_1b);
11713 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,SiS_Pr->Backup_1c);
11714 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,SiS_Pr->Backup_1d);
11715 } else if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { /* 1.10.8w */
11716 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x90);
11717 if(ModeNo <= 0x13) {
11718 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x11);
11719 if((resinfo == 0) || (resinfo == 2)) return;
11720 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x18);
11721 if((resinfo == 1) || (resinfo == 3)) return;
11722 }
11723 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
11724 if((ModeNo > 0x13) && (resinfo == SIS_RI_1024x768)) {
11725 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02); /* 1.10.7u */
11726#if 0
11727 tempbx = 806; /* 0x326 */ /* other older BIOSes */
11728 tempbx--;
11729 temp = tempbx & 0xff;
11730 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);
11731 temp = (tempbx >> 8) & 0x03;
11732 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1d,0xf8,temp);
11733#endif
11734 }
11735 } else if(ModeNo <= 0x13) {
11736 if(ModeNo <= 1) {
11737 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x70);
11738 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xff);
11739 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
11740 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
11741 }
11742 if(!(modeflag & HalfDCLK)) {
11743 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x20);
11744 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,0x1a);
11745 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,0x28);
11746 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,0x00);
11747 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x4c);
11748 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
11749 if(ModeNo == 0x12) {
11750 switch(tempch) {
11751 case 0:
11752 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
11753 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
11754 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,0x10);
11755 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
11756 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x48);
11757 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
11758 break;
11759 case 2:
11760 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
11761 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
11762 break;
11763 case 3:
11764 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
11765 break;
11766 }
11767 }
11768 }
11769 }
11770 }
11771 } else {
11772 tempcl = tempbh = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
11773 tempcl &= 0x0f;
11774 tempbh &= 0x70;
11775 tempbh >>= 4;
11776 tempbl = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x04);
11777 tempbx = (tempbh << 8) | tempbl;
11778 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11779 if((resinfo == SIS_RI_1024x768) || (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD))) {
11780 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
11781 tempbx = 770;
11782 } else {
11783 if(tempbx > 770) tempbx = 770;
11784 if(SiS_Pr->SiS_VGAVDE < 600) {
11785 tempax = 768 - SiS_Pr->SiS_VGAVDE;
11786 tempax >>= 4; /* 1.10.7w; 1.10.6s: 3; */
11787 if(SiS_Pr->SiS_VGAVDE <= 480) tempax >>= 4; /* 1.10.7w; 1.10.6s: < 480; >>=1; */
11788 tempbx -= tempax;
11789 }
11790 }
11791 } else return;
11792 }
11793 temp = tempbx & 0xff;
11794 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,temp);
11795 temp = ((tempbx & 0xff00) >> 4) | tempcl;
11796 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,temp);
11797 }
11798 }
11799}
11800
11801#endif
11802
11803/* ================= SiS 300 O.E.M. ================== */
11804
11805#ifdef SIS300
11806
11807static void
11808SetOEMLCDData2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11809 USHORT ModeNo,USHORT ModeIdIndex, USHORT RefTabIndex)
11810{
11811 USHORT crt2crtc=0, modeflag, myindex=0;
11812 UCHAR temp;
11813 int i;
11814
11815 if(ModeNo <= 0x13) {
11816 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
11817 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
11818 } else {
11819 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
11820 crt2crtc = SiS_Pr->SiS_RefIndex[RefTabIndex].Ext_CRT2CRTC;
11821 }
11822
11823 crt2crtc &= 0x3f;
11824
11825 if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
11826 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xdf);
11827 }
11828
11829 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
11830 if(modeflag & HalfDCLK) myindex = 1;
11831
11832 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
11833 for(i=0; i<7; i++) {
11834 if(barco_p1[myindex][crt2crtc][i][0]) {
11835 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,
11836 barco_p1[myindex][crt2crtc][i][0],
11837 barco_p1[myindex][crt2crtc][i][2],
11838 barco_p1[myindex][crt2crtc][i][1]);
11839 }
11840 }
11841 }
11842 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
11843 if(temp & 0x80) {
11844 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x18);
11845 temp++;
11846 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);
11847 }
11848 }
11849}
11850
11851static USHORT
11852GetOEMLCDPtr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, int Flag)
11853{
11854 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11855 USHORT tempbx=0,romptr=0;
11856 UCHAR customtable300[] = {
11857 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
11858 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
11859 };
11860 UCHAR customtable630[] = {
11861 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
11862 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
11863 };
11864
11865 if(HwInfo->jChipType == SIS_300) {
11866
11867 tempbx = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0x0f;
11868 if(SiS_Pr->SiS_VBType & VB_SIS301) tempbx &= 0x07;
11869 tempbx -= 2;
11870 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 4;
11871 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11872 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 3;
11873 }
11874 if(SiS_Pr->SiS_UseROM) {
11875 if(ROMAddr[0x235] & 0x80) {
11876 tempbx = SiS_Pr->SiS_LCDTypeInfo;
11877 if(Flag) {
11878 romptr = SISGETROMW(0x255);
11879 if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
11880 else tempbx = customtable300[SiS_Pr->SiS_LCDTypeInfo];
11881 if(tempbx == 0xFF) return 0xFFFF;
11882 }
11883 tempbx <<= 1;
11884 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
11885 }
11886 }
11887
11888 } else {
11889
11890 if(Flag) {
11891 if(SiS_Pr->SiS_UseROM) {
11892 romptr = SISGETROMW(0x255);
11893 if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
11894 else tempbx = 0xff;
11895 } else {
11896 tempbx = customtable630[SiS_Pr->SiS_LCDTypeInfo];
11897 }
11898 if(tempbx == 0xFF) return 0xFFFF;
11899 tempbx <<= 2;
11900 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
11901 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
11902 return tempbx;
11903 }
11904 tempbx = SiS_Pr->SiS_LCDTypeInfo << 2;
11905 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
11906 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
11907
11908 }
11909
11910 return tempbx;
11911}
11912
11913static void
11914SetOEMLCDDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11915 USHORT ModeNo,USHORT ModeIdIndex)
11916{
11917 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11918 USHORT index,temp,romptr=0;
11919
11920 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
11921
11922 if(SiS_Pr->SiS_UseROM) {
11923 if(!(ROMAddr[0x237] & 0x01)) return;
11924 if(!(ROMAddr[0x237] & 0x02)) return;
11925 romptr = SISGETROMW(0x24b);
11926 }
11927
11928 /* The Panel Compensation Delay should be set according to tables
11929 * here. Unfortunately, various BIOS versions don't case about
11930 * a uniform way using eg. ROM byte 0x220, but use different
11931 * hard coded delays (0x04, 0x20, 0x18) in SetGroup1().
11932 * Thus we don't set this if the user select a custom pdc or if
11933 * we otherwise detected a valid pdc.
11934 */
11935 if(SiS_Pr->PDC != -1) return;
11936
11937 temp = GetOEMLCDPtr(SiS_Pr,HwInfo, 0);
11938
11939 if(SiS_Pr->UseCustomMode)
11940 index = 0;
11941 else
11942 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
11943
11944 if(HwInfo->jChipType != SIS_300) {
11945 if(romptr) {
11946 romptr += (temp * 2);
11947 romptr = SISGETROMW(romptr);
11948 romptr += index;
11949 temp = ROMAddr[romptr];
11950 } else {
11951 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11952 temp = SiS300_OEMLCDDelay2[temp][index];
11953 } else {
11954 temp = SiS300_OEMLCDDelay3[temp][index];
11955 }
11956 }
11957 } else {
11958 if(SiS_Pr->SiS_UseROM && (ROMAddr[0x235] & 0x80)) {
11959 if(romptr) {
11960 romptr += (temp * 2);
11961 romptr = SISGETROMW(romptr);
11962 romptr += index;
11963 temp = ROMAddr[romptr];
11964 } else {
11965 temp = SiS300_OEMLCDDelay5[temp][index];
11966 }
11967 } else {
11968 if(SiS_Pr->SiS_UseROM) {
11969 romptr = ROMAddr[0x249] | (ROMAddr[0x24a] << 8);
11970 if(romptr) {
11971 romptr += (temp * 2);
11972 romptr = SISGETROMW(romptr);
11973 romptr += index;
11974 temp = ROMAddr[romptr];
11975 } else {
11976 temp = SiS300_OEMLCDDelay4[temp][index];
11977 }
11978 } else {
11979 temp = SiS300_OEMLCDDelay4[temp][index];
11980 }
11981 }
11982 }
11983 temp &= 0x3c;
11984 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* index 0A D[6:4] */
11985}
11986
11987static void
11988SetOEMLCDData(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11989 USHORT ModeNo,USHORT ModeIdIndex)
11990{
11991#if 0 /* Unfinished; Data table missing */
11992 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11993 USHORT index,temp;
11994
11995 if((SiS_Pr->SiS_UseROM) {
11996 if(!(ROMAddr[0x237] & 0x01)) return;
11997 if(!(ROMAddr[0x237] & 0x04)) return;
11998 /* No rom pointer in BIOS header! */
11999 }
12000
12001 temp = GetOEMLCDPtr(SiS_Pr,HwInfo, 1);
12002 if(temp = 0xFFFF) return;
12003
12004 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDHIndex;
12005 for(i=0x14, j=0; i<=0x17; i++, j++) {
12006 SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDHData[temp][index][j]);
12007 }
12008 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1a, 0xf8, (SiS300_LCDHData[temp][index][j] & 0x07));
12009
12010 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDVIndex;
12011 SiS_SetReg(SiS_SiS_Part1Port,0x18, SiS300_LCDVData[temp][index][0]);
12012 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x19, 0xF0, SiS300_LCDVData[temp][index][1]);
12013 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1A, 0xC7, (SiS300_LCDVData[temp][index][2] & 0x38));
12014 for(i=0x1b, j=3; i<=0x1d; i++, j++) {
12015 SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDVData[temp][index][j]);
12016 }
12017#endif
12018}
12019
12020static USHORT
12021GetOEMTVPtr(SiS_Private *SiS_Pr)
12022{
12023 USHORT index;
12024
12025 index = 0;
12026 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) index += 4;
12027 if(SiS_Pr->SiS_VBType & VB_SISVB) {
12028 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) index += 2;
12029 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index += 3;
12030 else if(SiS_Pr->SiS_TVMode & TVSetPAL) index += 1;
12031 } else {
12032 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) index += 2;
12033 if(SiS_Pr->SiS_TVMode & TVSetPAL) index += 1;
12034 }
12035 return index;
12036}
12037
12038static void
12039SetOEMTVDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
12040 USHORT ModeNo,USHORT ModeIdIndex)
12041{
12042 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
12043 USHORT index,temp,romptr=0;
12044
12045 if(SiS_Pr->SiS_UseROM) {
12046 if(!(ROMAddr[0x238] & 0x01)) return;
12047 if(!(ROMAddr[0x238] & 0x02)) return;
12048 romptr = SISGETROMW(0x241);
12049 }
12050
12051 temp = GetOEMTVPtr(SiS_Pr);
12052
12053 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVDelayIndex;
12054
12055 if(romptr) {
12056 romptr += (temp * 2);
12057 romptr = SISGETROMW(romptr);
12058 romptr += index;
12059 temp = ROMAddr[romptr];
12060 } else {
12061 if(SiS_Pr->SiS_VBType & VB_SISVB) {
12062 temp = SiS300_OEMTVDelay301[temp][index];
12063 } else {
12064 temp = SiS300_OEMTVDelayLVDS[temp][index];
12065 }
12066 }
12067 temp &= 0x3c;
12068 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);
12069}
12070
12071static void
12072SetOEMAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
12073 USHORT ModeNo, USHORT ModeIdIndex)
12074{
12075 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
12076 USHORT index,temp,romptr=0;
12077
12078 if(SiS_Pr->SiS_UseROM) {
12079 if(!(ROMAddr[0x238] & 0x01)) return;
12080 if(!(ROMAddr[0x238] & 0x04)) return;
12081 romptr = SISGETROMW(0x243);
12082 }
12083
12084 temp = GetOEMTVPtr(SiS_Pr);
12085
12086 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVFlickerIndex;
12087
12088 if(romptr) {
12089 romptr += (temp * 2);
12090 romptr = SISGETROMW(romptr);
12091 romptr += index;
12092 temp = ROMAddr[romptr];
12093 } else {
12094 temp = SiS300_OEMTVFlicker[temp][index];
12095 }
12096 temp &= 0x70;
12097 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8F,temp);
12098}
12099
12100static void
12101SetOEMPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
12102 USHORT ModeNo,USHORT ModeIdIndex)
12103{
12104 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
12105 USHORT index,i,j,temp,romptr=0;
12106
12107 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) return;
12108
12109 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetNTSCJ | TVSetPALM | TVSetPALN)) return;
12110
12111 if(SiS_Pr->SiS_UseROM) {
12112 if(!(ROMAddr[0x238] & 0x01)) return;
12113 if(!(ROMAddr[0x238] & 0x08)) return;
12114 romptr = SISGETROMW(0x245);
12115 }
12116
12117 temp = GetOEMTVPtr(SiS_Pr);
12118
12119 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVPhaseIndex;
12120
12121 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
12122 for(i=0x31, j=0; i<=0x34; i++, j++) {
12123 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase2[temp][index][j]);
12124 }
12125 } else {
12126 if(romptr) {
12127 romptr += (temp * 2);
12128 romptr = SISGETROMW(romptr);
12129 romptr += (index * 4);
12130 for(i=0x31, j=0; i<=0x34; i++, j++) {
12131 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
12132 }
12133 } else {
12134 for(i=0x31, j=0; i<=0x34; i++, j++) {
12135 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase1[temp][index][j]);
12136 }
12137 }
12138 }
12139}
12140
12141static void
12142SetOEMYFilter(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
12143 USHORT ModeNo,USHORT ModeIdIndex)
12144{
12145 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
12146 USHORT index,temp,i,j,romptr=0;
12147
12148 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSCART | SetCRT2ToHiVision | SetCRT2ToYPbPr525750)) return;
12149
12150 if(SiS_Pr->SiS_UseROM) {
12151 if(!(ROMAddr[0x238] & 0x01)) return;
12152 if(!(ROMAddr[0x238] & 0x10)) return;
12153 romptr = SISGETROMW(0x247);
12154 }
12155
12156 temp = GetOEMTVPtr(SiS_Pr);
12157
12158 if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
12159 else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 9;
12160 /* NTSCJ uses NTSC filters */
12161
12162 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVYFilterIndex;
12163
12164 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
12165 for(i=0x35, j=0; i<=0x38; i++, j++) {
12166 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
12167 }
12168 for(i=0x48; i<=0x4A; i++, j++) {
12169 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
12170 }
12171 } else {
12172 if((romptr) && (!(SiS_Pr->SiS_TVMode & (TVSetPALM|TVSetPALN)))) {
12173 romptr += (temp * 2);
12174 romptr = SISGETROMW(romptr);
12175 romptr += (index * 4);
12176 for(i=0x35, j=0; i<=0x38; i++, j++) {
12177 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
12178 }
12179 } else {
12180 for(i=0x35, j=0; i<=0x38; i++, j++) {
12181 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter1[temp][index][j]);
12182 }
12183 }
12184 }
12185}
12186
12187static USHORT
12188SiS_SearchVBModeID(SiS_Private *SiS_Pr, USHORT *ModeNo)
12189{
12190 USHORT ModeIdIndex;
12191 UCHAR VGAINFO = SiS_Pr->SiS_VGAINFO;
12192
12193 if(*ModeNo <= 5) *ModeNo |= 1;
12194
12195 for(ModeIdIndex=0; ; ModeIdIndex++) {
12196 if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == *ModeNo) break;
12197 if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == 0xFF) return 0;
12198 }
12199
12200 if(*ModeNo != 0x07) {
12201 if(*ModeNo > 0x03) return ModeIdIndex;
12202 if(VGAINFO & 0x80) return ModeIdIndex;
12203 ModeIdIndex++;
12204 }
12205
12206 if(VGAINFO & 0x10) ModeIdIndex++; /* 400 lines */
12207 /* else 350 lines */
12208 return ModeIdIndex;
12209}
12210
12211static void
12212SiS_OEM300Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
12213 USHORT ModeNo, USHORT ModeIdIndex, USHORT RefTableIndex)
12214{
12215 USHORT OEMModeIdIndex=0;
12216
12217 if(!SiS_Pr->UseCustomMode) {
12218 OEMModeIdIndex = SiS_SearchVBModeID(SiS_Pr,&ModeNo);
12219 if(!(OEMModeIdIndex)) return;
12220 }
12221
12222 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
12223 SetOEMLCDDelay(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
12224 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
12225 SetOEMLCDData(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
12226 }
12227 }
12228 if(SiS_Pr->UseCustomMode) return;
12229 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
12230 SetOEMTVDelay(SiS_Pr, HwInfo, ModeNo,OEMModeIdIndex);
12231 if(SiS_Pr->SiS_VBType & VB_SISVB) {
12232 SetOEMAntiFlicker(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
12233 SetOEMPhaseIncr(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
12234 SetOEMYFilter(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
12235 }
12236 }
12237}
12238#endif
12239