Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
init301.c
Go to the documentation of this file.
1 /* $XFree86$ */
2 /* $XdotOrg$ */
3 /*
4  * Mode initializing code (CRT2 section)
5  * for SiS 300/305/540/630/730,
6  * SiS 315/550/[M]650/651/[M]661[FGM]X/[M]74x[GX]/330/[M]76x[GX],
7  * XGI V3XT/V5/V8, Z7
8  * (Universal module for Linux kernel framebuffer and X.org/XFree86 4.x)
9  *
10  * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
11  *
12  * If distributed as part of the Linux kernel, the following license terms
13  * apply:
14  *
15  * * This program is free software; you can redistribute it and/or modify
16  * * it under the terms of the GNU General Public License as published by
17  * * the Free Software Foundation; either version 2 of the named License,
18  * * or any later version.
19  * *
20  * * This program is distributed in the hope that it will be useful,
21  * * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23  * * GNU General Public License for more details.
24  * *
25  * * You should have received a copy of the GNU General Public License
26  * * along with this program; if not, write to the Free Software
27  * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
28  *
29  * Otherwise, the following license terms apply:
30  *
31  * * Redistribution and use in source and binary forms, with or without
32  * * modification, are permitted provided that the following conditions
33  * * are met:
34  * * 1) Redistributions of source code must retain the above copyright
35  * * notice, this list of conditions and the following disclaimer.
36  * * 2) Redistributions in binary form must reproduce the above copyright
37  * * notice, this list of conditions and the following disclaimer in the
38  * * documentation and/or other materials provided with the distribution.
39  * * 3) The name of the author may not be used to endorse or promote products
40  * * derived from this software without specific prior written permission.
41  * *
42  * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
43  * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
44  * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
45  * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
46  * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
47  * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
48  * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
49  * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
50  * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
51  * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
52  *
53  * Author: Thomas Winischhofer <[email protected]>
54  *
55  * Formerly based on non-functional code-fragements for 300 series by SiS, Inc.
56  * Used by permission.
57  *
58  */
59 
60 #if 1
61 #define SET_EMI /* 302LV/ELV: Set EMI values */
62 #endif
63 
64 #if 1
65 #define SET_PWD /* 301/302LV: Set PWD */
66 #endif
67 
68 #define COMPAL_HACK /* Needed for Compal 1400x1050 (EMI) */
69 #define COMPAQ_HACK /* Needed for Inventec/Compaq 1280x1024 (EMI) */
70 #define ASUS_HACK /* Needed for Asus A2H 1024x768 (EMI) */
71 
72 #include "init301.h"
73 
74 #ifdef CONFIG_FB_SIS_300
75 #include "oem300.h"
76 #endif
77 
78 #ifdef CONFIG_FB_SIS_315
79 #include "oem310.h"
80 #endif
81 
82 #define SiS_I2CDELAY 1000
83 #define SiS_I2CDELAYSHORT 150
84 
85 static unsigned short SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr);
86 static void SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);
87 
88 /*********************************************/
89 /* HELPER: Lock/Unlock CRT2 */
90 /*********************************************/
91 
92 void
93 SiS_UnLockCRT2(struct SiS_Private *SiS_Pr)
94 {
95  if(SiS_Pr->ChipType == XGI_20)
96  return;
97  else if(SiS_Pr->ChipType >= SIS_315H)
98  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
99  else
100  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
101 }
102 
103 static
104 void
105 SiS_LockCRT2(struct SiS_Private *SiS_Pr)
106 {
107  if(SiS_Pr->ChipType == XGI_20)
108  return;
109  else if(SiS_Pr->ChipType >= SIS_315H)
110  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
111  else
112  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
113 }
114 
115 /*********************************************/
116 /* HELPER: Write SR11 */
117 /*********************************************/
118 
119 static void
120 SiS_SetRegSR11ANDOR(struct SiS_Private *SiS_Pr, unsigned short DataAND, unsigned short DataOR)
121 {
122  if(SiS_Pr->ChipType >= SIS_661) {
123  DataAND &= 0x0f;
124  DataOR &= 0x0f;
125  }
126  SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,DataAND,DataOR);
127 }
128 
129 /*********************************************/
130 /* HELPER: Get Pointer to LCD structure */
131 /*********************************************/
132 
133 #ifdef CONFIG_FB_SIS_315
134 static unsigned char *
135 GetLCDStructPtr661(struct SiS_Private *SiS_Pr)
136 {
137  unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
138  unsigned char *myptr = NULL;
139  unsigned short romindex = 0, reg = 0, idx = 0;
140 
141  /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
142  * due to the variaty of panels the BIOS doesn't know about.
143  * Exception: If the BIOS has better knowledge (such as in case
144  * of machines with a 301C and a panel that does not support DDC)
145  * use the BIOS data as well.
146  */
147 
148  if((SiS_Pr->SiS_ROMNew) &&
149  ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) {
150 
151  if(SiS_Pr->ChipType < SIS_661) reg = 0x3c;
152  else reg = 0x7d;
153 
154  idx = (SiS_GetReg(SiS_Pr->SiS_P3d4,reg) & 0x1f) * 26;
155 
156  if(idx < (8*26)) {
157  myptr = (unsigned char *)&SiS_LCDStruct661[idx];
158  }
159  romindex = SISGETROMW(0x100);
160  if(romindex) {
161  romindex += idx;
162  myptr = &ROMAddr[romindex];
163  }
164  }
165  return myptr;
166 }
167 
168 static unsigned short
169 GetLCDStructPtr661_2(struct SiS_Private *SiS_Pr)
170 {
171  unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
172  unsigned short romptr = 0;
173 
174  /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
175  * due to the variaty of panels the BIOS doesn't know about.
176  * Exception: If the BIOS has better knowledge (such as in case
177  * of machines with a 301C and a panel that does not support DDC)
178  * use the BIOS data as well.
179  */
180 
181  if((SiS_Pr->SiS_ROMNew) &&
182  ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) {
183  romptr = SISGETROMW(0x102);
184  romptr += ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) * SiS_Pr->SiS661LCD2TableSize);
185  }
186 
187  return romptr;
188 }
189 #endif
190 
191 /*********************************************/
192 /* Adjust Rate for CRT2 */
193 /*********************************************/
194 
195 static bool
196 SiS_AdjustCRT2Rate(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
197  unsigned short RRTI, unsigned short *i)
198 {
199  unsigned short checkmask=0, modeid, infoflag;
200 
201  modeid = SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID;
202 
203  if(SiS_Pr->SiS_VBType & VB_SISVB) {
204 
205  if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
206 
207  checkmask |= SupportRAMDAC2;
208  if(SiS_Pr->ChipType >= SIS_315H) {
209  checkmask |= SupportRAMDAC2_135;
210  if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
211  checkmask |= SupportRAMDAC2_162;
212  if(SiS_Pr->SiS_VBType & VB_SISRAMDAC202) {
213  checkmask |= SupportRAMDAC2_202;
214  }
215  }
216  }
217 
218  } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
219 
220  checkmask |= SupportLCD;
221  if(SiS_Pr->ChipType >= SIS_315H) {
222  if(SiS_Pr->SiS_VBType & VB_SISVB) {
223  if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
224  if(modeid == 0x2e) checkmask |= Support64048060Hz;
225  }
226  }
227  }
228 
229  } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
230 
231  checkmask |= SupportHiVision;
232 
234 
235  checkmask |= SupportTV;
236  if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
237  checkmask |= SupportTV1024;
238  if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
239  if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
240  checkmask |= SupportYPbPr750p;
241  }
242  }
243  }
244 
245  }
246 
247  } else { /* LVDS */
248 
249  if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
250  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
251  checkmask |= SupportCHTV;
252  }
253  }
254 
255  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
256  checkmask |= SupportLCD;
257  }
258 
259  }
260 
261  /* Look backwards in table for matching CRT2 mode */
262  for(; SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID == modeid; (*i)--) {
263  infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
264  if(infoflag & checkmask) return true;
265  if((*i) == 0) break;
266  }
267 
268  /* Look through the whole mode-section of the table from the beginning
269  * for a matching CRT2 mode if no mode was found yet.
270  */
271  for((*i) = 0; ; (*i)++) {
272  if(SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID != modeid) break;
273  infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
274  if(infoflag & checkmask) return true;
275  }
276  return false;
277 }
278 
279 /*********************************************/
280 /* Get rate index */
281 /*********************************************/
282 
283 unsigned short
284 SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
285 {
286  unsigned short RRTI,i,backup_i;
287  unsigned short modeflag,index,temp,backupindex;
288  static const unsigned short LCDRefreshIndex[] = {
289  0x00, 0x00, 0x01, 0x01,
290  0x01, 0x01, 0x01, 0x01,
291  0x01, 0x01, 0x01, 0x01,
292  0x01, 0x01, 0x01, 0x01,
293  0x00, 0x00, 0x00, 0x00
294  };
295 
296  /* Do NOT check for UseCustomMode here, will skrew up FIFO */
297  if(ModeNo == 0xfe) return 0;
298 
299  if(ModeNo <= 0x13) {
300  modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
301  } else {
302  modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
303  }
304 
305  if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
306  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
307  if(modeflag & HalfDCLK) return 0;
308  }
309  }
310 
311  if(ModeNo < 0x14) return 0xFFFF;
312 
313  index = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x33) >> SiS_Pr->SiS_SelectCRT2Rate) & 0x0F;
314  backupindex = index;
315 
316  if(index > 0) index--;
317 
318  if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
319  if(SiS_Pr->SiS_VBType & VB_SISVB) {
320  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
321  if(SiS_Pr->SiS_VBType & VB_NoLCD) index = 0;
322  else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index = backupindex = 0;
323  }
324  if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
325  if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) {
326  temp = LCDRefreshIndex[SiS_GetBIOSLCDResInfo(SiS_Pr)];
327  if(index > temp) index = temp;
328  }
329  }
330  } else {
331  if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) index = 0;
332  if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
333  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) index = 0;
334  }
335  }
336  }
337 
338  RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
339  ModeNo = SiS_Pr->SiS_RefIndex[RRTI].ModeID;
340 
341  if(SiS_Pr->ChipType >= SIS_315H) {
342  if(!(SiS_Pr->SiS_VBInfo & DriverMode)) {
343  if( (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x105) ||
344  (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x107) ) {
345  if(backupindex <= 1) RRTI++;
346  }
347  }
348  }
349 
350  i = 0;
351  do {
352  if(SiS_Pr->SiS_RefIndex[RRTI + i].ModeID != ModeNo) break;
353  temp = SiS_Pr->SiS_RefIndex[RRTI + i].Ext_InfoFlag;
354  temp &= ModeTypeMask;
355  if(temp < SiS_Pr->SiS_ModeType) break;
356  i++;
357  index--;
358  } while(index != 0xFFFF);
359 
360  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
361  if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
362  temp = SiS_Pr->SiS_RefIndex[RRTI + i - 1].Ext_InfoFlag;
363  if(temp & InterlaceMode) i++;
364  }
365  }
366 
367  i--;
368 
369  if((SiS_Pr->SiS_SetFlag & ProgrammingCRT2) && (!(SiS_Pr->SiS_VBInfo & DisableCRT2Display))) {
370  backup_i = i;
371  if(!(SiS_AdjustCRT2Rate(SiS_Pr, ModeNo, ModeIdIndex, RRTI, &i))) {
372  i = backup_i;
373  }
374  }
375 
376  return (RRTI + i);
377 }
378 
379 /*********************************************/
380 /* STORE CRT2 INFO in CR34 */
381 /*********************************************/
382 
383 static void
384 SiS_SaveCRT2Info(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
385 {
386  unsigned short temp1, temp2;
387 
388  /* Store CRT1 ModeNo in CR34 */
389  SiS_SetReg(SiS_Pr->SiS_P3d4,0x34,ModeNo);
390  temp1 = (SiS_Pr->SiS_VBInfo & SetInSlaveMode) >> 8;
391  temp2 = ~(SetInSlaveMode >> 8);
392  SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x31,temp2,temp1);
393 }
394 
395 /*********************************************/
396 /* HELPER: GET SOME DATA FROM BIOS ROM */
397 /*********************************************/
398 
399 #ifdef CONFIG_FB_SIS_300
400 static bool
401 SiS_CR36BIOSWord23b(struct SiS_Private *SiS_Pr)
402 {
403  unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
404  unsigned short temp,temp1;
405 
406  if(SiS_Pr->SiS_UseROM) {
407  if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
408  temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
409  temp1 = SISGETROMW(0x23b);
410  if(temp1 & temp) return true;
411  }
412  }
413  return false;
414 }
415 
416 static bool
417 SiS_CR36BIOSWord23d(struct SiS_Private *SiS_Pr)
418 {
419  unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
420  unsigned short temp,temp1;
421 
422  if(SiS_Pr->SiS_UseROM) {
423  if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
424  temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
425  temp1 = SISGETROMW(0x23d);
426  if(temp1 & temp) return true;
427  }
428  }
429  return false;
430 }
431 #endif
432 
433 /*********************************************/
434 /* HELPER: DELAY FUNCTIONS */
435 /*********************************************/
436 
437 void
438 SiS_DDC2Delay(struct SiS_Private *SiS_Pr, unsigned int delaytime)
439 {
440  while (delaytime-- > 0)
441  SiS_GetReg(SiS_Pr->SiS_P3c4, 0x05);
442 }
443 
444 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
445 static void
446 SiS_GenericDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
447 {
448  SiS_DDC2Delay(SiS_Pr, delay * 36);
449 }
450 #endif
451 
452 #ifdef CONFIG_FB_SIS_315
453 static void
454 SiS_LongDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
455 {
456  while(delay--) {
457  SiS_GenericDelay(SiS_Pr, 6623);
458  }
459 }
460 #endif
461 
462 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
463 static void
464 SiS_ShortDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
465 {
466  while(delay--) {
467  SiS_GenericDelay(SiS_Pr, 66);
468  }
469 }
470 #endif
471 
472 static void
473 SiS_PanelDelay(struct SiS_Private *SiS_Pr, unsigned short DelayTime)
474 {
475 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
476  unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
477  unsigned short PanelID, DelayIndex, Delay=0;
478 #endif
479 
480  if(SiS_Pr->ChipType < SIS_315H) {
481 
482 #ifdef CONFIG_FB_SIS_300
483 
484  PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
485  if(SiS_Pr->SiS_VBType & VB_SISVB) {
486  if(SiS_Pr->SiS_VBType & VB_SIS301) PanelID &= 0xf7;
487  if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x10)) PanelID = 0x12;
488  }
489  DelayIndex = PanelID >> 4;
490  if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) {
491  Delay = 3;
492  } else {
493  if(DelayTime >= 2) DelayTime -= 2;
494  if(!(DelayTime & 0x01)) {
495  Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
496  } else {
497  Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
498  }
499  if(SiS_Pr->SiS_UseROM) {
500  if(ROMAddr[0x220] & 0x40) {
501  if(!(DelayTime & 0x01)) Delay = (unsigned short)ROMAddr[0x225];
502  else Delay = (unsigned short)ROMAddr[0x226];
503  }
504  }
505  }
506  SiS_ShortDelay(SiS_Pr, Delay);
507 
508 #endif /* CONFIG_FB_SIS_300 */
509 
510  } else {
511 
512 #ifdef CONFIG_FB_SIS_315
513 
514  if((SiS_Pr->ChipType >= SIS_661) ||
515  (SiS_Pr->ChipType <= SIS_315PRO) ||
516  (SiS_Pr->ChipType == SIS_330) ||
517  (SiS_Pr->SiS_ROMNew)) {
518 
519  if(!(DelayTime & 0x01)) {
520  SiS_DDC2Delay(SiS_Pr, 0x1000);
521  } else {
522  SiS_DDC2Delay(SiS_Pr, 0x4000);
523  }
524 
525  } else if((SiS_Pr->SiS_IF_DEF_LVDS == 1) /* ||
526  (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
527  (SiS_Pr->SiS_CustomT == CUT_CLEVO1400) */ ) { /* 315 series, LVDS; Special */
528 
529  if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
530  PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
531  if(SiS_Pr->SiS_CustomT == CUT_CLEVO1400) {
532  if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1b) & 0x10)) PanelID = 0x12;
533  }
534  if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
535  DelayIndex = PanelID & 0x0f;
536  } else {
537  DelayIndex = PanelID >> 4;
538  }
539  if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) {
540  Delay = 3;
541  } else {
542  if(DelayTime >= 2) DelayTime -= 2;
543  if(!(DelayTime & 0x01)) {
544  Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[0];
545  } else {
546  Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[1];
547  }
548  if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
549  if(ROMAddr[0x13c] & 0x40) {
550  if(!(DelayTime & 0x01)) {
551  Delay = (unsigned short)ROMAddr[0x17e];
552  } else {
553  Delay = (unsigned short)ROMAddr[0x17f];
554  }
555  }
556  }
557  }
558  SiS_ShortDelay(SiS_Pr, Delay);
559  }
560 
561  } else if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 315 series, all bridges */
562 
563  DelayIndex = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
564  if(!(DelayTime & 0x01)) {
565  Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
566  } else {
567  Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
568  }
569  Delay <<= 8;
570  SiS_DDC2Delay(SiS_Pr, Delay);
571 
572  }
573 
574 #endif /* CONFIG_FB_SIS_315 */
575 
576  }
577 }
578 
579 #ifdef CONFIG_FB_SIS_315
580 static void
581 SiS_PanelDelayLoop(struct SiS_Private *SiS_Pr, unsigned short DelayTime, unsigned short DelayLoop)
582 {
583  int i;
584  for(i = 0; i < DelayLoop; i++) {
585  SiS_PanelDelay(SiS_Pr, DelayTime);
586  }
587 }
588 #endif
589 
590 /*********************************************/
591 /* HELPER: WAIT-FOR-RETRACE FUNCTIONS */
592 /*********************************************/
593 
594 void
596 {
597  unsigned short watchdog;
598 
599  if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
600  if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80)) return;
601 
602  watchdog = 65535;
603  while((SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
604  watchdog = 65535;
605  while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
606 }
607 
608 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
609 static void
610 SiS_WaitRetrace2(struct SiS_Private *SiS_Pr, unsigned short reg)
611 {
612  unsigned short watchdog;
613 
614  watchdog = 65535;
615  while((SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02) && --watchdog);
616  watchdog = 65535;
617  while((!(SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02)) && --watchdog);
618 }
619 #endif
620 
621 static void
622 SiS_WaitVBRetrace(struct SiS_Private *SiS_Pr)
623 {
624  if(SiS_Pr->ChipType < SIS_315H) {
625 #ifdef CONFIG_FB_SIS_300
626  if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
627  if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return;
628  }
629  if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x80)) {
630  SiS_WaitRetrace1(SiS_Pr);
631  } else {
632  SiS_WaitRetrace2(SiS_Pr, 0x25);
633  }
634 #endif
635  } else {
636 #ifdef CONFIG_FB_SIS_315
637  if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) {
638  SiS_WaitRetrace1(SiS_Pr);
639  } else {
640  SiS_WaitRetrace2(SiS_Pr, 0x30);
641  }
642 #endif
643  }
644 }
645 
646 static void
647 SiS_VBWait(struct SiS_Private *SiS_Pr)
648 {
649  unsigned short tempal,temp,i,j;
650 
651  temp = 0;
652  for(i = 0; i < 3; i++) {
653  for(j = 0; j < 100; j++) {
654  tempal = SiS_GetRegByte(SiS_Pr->SiS_P3da);
655  if(temp & 0x01) {
656  if((tempal & 0x08)) continue;
657  else break;
658  } else {
659  if(!(tempal & 0x08)) continue;
660  else break;
661  }
662  }
663  temp ^= 0x01;
664  }
665 }
666 
667 static void
668 SiS_VBLongWait(struct SiS_Private *SiS_Pr)
669 {
670  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
671  SiS_VBWait(SiS_Pr);
672  } else {
673  SiS_WaitRetrace1(SiS_Pr);
674  }
675 }
676 
677 /*********************************************/
678 /* HELPER: MISC */
679 /*********************************************/
680 
681 #ifdef CONFIG_FB_SIS_300
682 static bool
683 SiS_Is301B(struct SiS_Private *SiS_Pr)
684 {
685  if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01) >= 0xb0) return true;
686  return false;
687 }
688 #endif
689 
690 static bool
691 SiS_CRT2IsLCD(struct SiS_Private *SiS_Pr)
692 {
693  if(SiS_Pr->ChipType == SIS_730) {
694  if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x20) return true;
695  }
696  if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & 0x20) return true;
697  return false;
698 }
699 
700 bool
702 {
703 #ifdef CONFIG_FB_SIS_315
704  if(SiS_Pr->ChipType >= SIS_315H) {
705  if((SiS_Pr->ChipType != SIS_650) || (SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) {
706  if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableDualEdge) return true;
707  }
708  }
709 #endif
710  return false;
711 }
712 
713 bool
714 SiS_IsVAMode(struct SiS_Private *SiS_Pr)
715 {
716 #ifdef CONFIG_FB_SIS_315
717  unsigned short flag;
718 
719  if(SiS_Pr->ChipType >= SIS_315H) {
720  flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
721  if((flag & EnableDualEdge) && (flag & SetToLCDA)) return true;
722  }
723 #endif
724  return false;
725 }
726 
727 #ifdef CONFIG_FB_SIS_315
728 static bool
729 SiS_IsVAorLCD(struct SiS_Private *SiS_Pr)
730 {
731  if(SiS_IsVAMode(SiS_Pr)) return true;
732  if(SiS_CRT2IsLCD(SiS_Pr)) return true;
733  return false;
734 }
735 #endif
736 
737 static bool
738 SiS_IsDualLink(struct SiS_Private *SiS_Pr)
739 {
740 #ifdef CONFIG_FB_SIS_315
741  if(SiS_Pr->ChipType >= SIS_315H) {
742  if((SiS_CRT2IsLCD(SiS_Pr)) ||
743  (SiS_IsVAMode(SiS_Pr))) {
744  if(SiS_Pr->SiS_LCDInfo & LCDDualLink) return true;
745  }
746  }
747 #endif
748  return false;
749 }
750 
751 #ifdef CONFIG_FB_SIS_315
752 static bool
753 SiS_TVEnabled(struct SiS_Private *SiS_Pr)
754 {
755  if((SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) != 0x0c) return true;
756  if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
757  if(SiS_GetReg(SiS_Pr->SiS_Part2Port,0x4d) & 0x10) return true;
758  }
759  return false;
760 }
761 #endif
762 
763 #ifdef CONFIG_FB_SIS_315
764 static bool
765 SiS_LCDAEnabled(struct SiS_Private *SiS_Pr)
766 {
767  if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) return true;
768  return false;
769 }
770 #endif
771 
772 #ifdef CONFIG_FB_SIS_315
773 static bool
774 SiS_WeHaveBacklightCtrl(struct SiS_Private *SiS_Pr)
775 {
776  if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
777  if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0x10) return true;
778  }
779  return false;
780 }
781 #endif
782 
783 #ifdef CONFIG_FB_SIS_315
784 static bool
785 SiS_IsNotM650orLater(struct SiS_Private *SiS_Pr)
786 {
787  unsigned short flag;
788 
789  if(SiS_Pr->ChipType == SIS_650) {
790  flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0;
791  /* Check for revision != A0 only */
792  if((flag == 0xe0) || (flag == 0xc0) ||
793  (flag == 0xb0) || (flag == 0x90)) return false;
794  } else if(SiS_Pr->ChipType >= SIS_661) return false;
795  return true;
796 }
797 #endif
798 
799 #ifdef CONFIG_FB_SIS_315
800 static bool
801 SiS_IsYPbPr(struct SiS_Private *SiS_Pr)
802 {
803  if(SiS_Pr->ChipType >= SIS_315H) {
804  /* YPrPb = 0x08 */
805  if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHYPbPr) return true;
806  }
807  return false;
808 }
809 #endif
810 
811 #ifdef CONFIG_FB_SIS_315
812 static bool
813 SiS_IsChScart(struct SiS_Private *SiS_Pr)
814 {
815  if(SiS_Pr->ChipType >= SIS_315H) {
816  /* Scart = 0x04 */
817  if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHScart) return true;
818  }
819  return false;
820 }
821 #endif
822 
823 #ifdef CONFIG_FB_SIS_315
824 static bool
825 SiS_IsTVOrYPbPrOrScart(struct SiS_Private *SiS_Pr)
826 {
827  unsigned short flag;
828 
829  if(SiS_Pr->ChipType >= SIS_315H) {
830  flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
831  if(flag & SetCRT2ToTV) return true;
832  flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
833  if(flag & EnableCHYPbPr) return true; /* = YPrPb = 0x08 */
834  if(flag & EnableCHScart) return true; /* = Scart = 0x04 - TW */
835  } else {
836  flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
837  if(flag & SetCRT2ToTV) return true;
838  }
839  return false;
840 }
841 #endif
842 
843 #ifdef CONFIG_FB_SIS_315
844 static bool
845 SiS_IsLCDOrLCDA(struct SiS_Private *SiS_Pr)
846 {
847  unsigned short flag;
848 
849  if(SiS_Pr->ChipType >= SIS_315H) {
850  flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
851  if(flag & SetCRT2ToLCD) return true;
852  flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
853  if(flag & SetToLCDA) return true;
854  } else {
855  flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
856  if(flag & SetCRT2ToLCD) return true;
857  }
858  return false;
859 }
860 #endif
861 
862 static bool
863 SiS_HaveBridge(struct SiS_Private *SiS_Pr)
864 {
865  unsigned short flag;
866 
867  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
868  return true;
869  } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
870  flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
871  if((flag == 1) || (flag == 2)) return true;
872  }
873  return false;
874 }
875 
876 static bool
877 SiS_BridgeIsEnabled(struct SiS_Private *SiS_Pr)
878 {
879  unsigned short flag;
880 
881  if(SiS_HaveBridge(SiS_Pr)) {
882  flag = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
883  if(SiS_Pr->ChipType < SIS_315H) {
884  flag &= 0xa0;
885  if((flag == 0x80) || (flag == 0x20)) return true;
886  } else {
887  flag &= 0x50;
888  if((flag == 0x40) || (flag == 0x10)) return true;
889  }
890  }
891  return false;
892 }
893 
894 static bool
895 SiS_BridgeInSlavemode(struct SiS_Private *SiS_Pr)
896 {
897  unsigned short flag1;
898 
899  flag1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
900  if(flag1 & (SetInSlaveMode >> 8)) return true;
901  return false;
902 }
903 
904 /*********************************************/
905 /* GET VIDEO BRIDGE CONFIG INFO */
906 /*********************************************/
907 
908 /* Setup general purpose IO for Chrontel communication */
909 #ifdef CONFIG_FB_SIS_300
910 void
911 SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo)
912 {
913  unsigned int acpibase;
914  unsigned short temp;
915 
916  if(!(SiS_Pr->SiS_ChSW)) return;
917 
918  acpibase = sisfb_read_lpc_pci_dword(SiS_Pr, 0x74);
919  acpibase &= 0xFFFF;
920  if(!acpibase) return;
921  temp = SiS_GetRegShort((acpibase + 0x3c)); /* ACPI register 0x3c: GP Event 1 I/O mode select */
922  temp &= 0xFEFF;
923  SiS_SetRegShort((acpibase + 0x3c), temp);
924  temp = SiS_GetRegShort((acpibase + 0x3c));
925  temp = SiS_GetRegShort((acpibase + 0x3a)); /* ACPI register 0x3a: GP Pin Level (low/high) */
926  temp &= 0xFEFF;
927  if(!(myvbinfo & SetCRT2ToTV)) temp |= 0x0100;
928  SiS_SetRegShort((acpibase + 0x3a), temp);
929  temp = SiS_GetRegShort((acpibase + 0x3a));
930 }
931 #endif
932 
933 void
934 SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
935  unsigned short ModeIdIndex, int checkcrt2mode)
936 {
937  unsigned short tempax, tempbx, temp;
938  unsigned short modeflag, resinfo = 0;
939 
940  SiS_Pr->SiS_SetFlag = 0;
941 
942  modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
943 
944  SiS_Pr->SiS_ModeType = modeflag & ModeTypeMask;
945 
946  if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
947  resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
948  }
949 
950  tempbx = 0;
951 
952  if(SiS_HaveBridge(SiS_Pr)) {
953 
954  temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
955  tempbx |= temp;
956  tempax = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) << 8;
957  tempax &= (DriverMode | LoadDACFlag | SetNotSimuMode | SetPALTV);
958  tempbx |= tempax;
959 
960 #ifdef CONFIG_FB_SIS_315
961  if(SiS_Pr->ChipType >= SIS_315H) {
962  if(SiS_Pr->SiS_VBType & VB_SISLCDA) {
963  if(ModeNo == 0x03) {
964  /* Mode 0x03 is never in driver mode */
965  SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf);
966  }
967  if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8))) {
968  /* Reset LCDA setting if not driver mode */
969  SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
970  }
971  if(IS_SIS650) {
972  if(SiS_Pr->SiS_UseLCDA) {
973  if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) {
974  if((ModeNo <= 0x13) || (!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) {
975  SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA));
976  }
977  }
978  }
979  }
980  temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
981  if((temp & (EnableDualEdge | SetToLCDA)) == (EnableDualEdge | SetToLCDA)) {
982  tempbx |= SetCRT2ToLCDA;
983  }
984  }
985 
986  if(SiS_Pr->ChipType >= SIS_661) { /* New CR layout */
988  if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & 0x04) {
989  temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
990  if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
991  else if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
992  tempbx |= SetCRT2ToYPbPr525750;
993  }
994  }
995  }
996 
997  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
998  temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
999  if(temp & SetToLCDA) {
1000  tempbx |= SetCRT2ToLCDA;
1001  }
1002  if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1003  if(temp & EnableCHYPbPr) {
1004  tempbx |= SetCRT2ToCHYPbPr;
1005  }
1006  }
1007  }
1008  }
1009 
1010 #endif /* CONFIG_FB_SIS_315 */
1011 
1012  if(!(SiS_Pr->SiS_VBType & VB_SISVGA2)) {
1013  tempbx &= ~(SetCRT2ToRAMDAC);
1014  }
1015 
1016  if(SiS_Pr->SiS_VBType & VB_SISVB) {
1017  temp = SetCRT2ToSVIDEO |
1018  SetCRT2ToAVIDEO |
1019  SetCRT2ToSCART |
1020  SetCRT2ToLCDA |
1021  SetCRT2ToLCD |
1022  SetCRT2ToRAMDAC |
1025  } else {
1026  if(SiS_Pr->ChipType >= SIS_315H) {
1027  if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1028  temp = SetCRT2ToAVIDEO |
1029  SetCRT2ToSVIDEO |
1030  SetCRT2ToSCART |
1031  SetCRT2ToLCDA |
1032  SetCRT2ToLCD |
1034  } else {
1035  temp = SetCRT2ToLCDA |
1036  SetCRT2ToLCD;
1037  }
1038  } else {
1039  if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1040  temp = SetCRT2ToTV | SetCRT2ToLCD;
1041  } else {
1042  temp = SetCRT2ToLCD;
1043  }
1044  }
1045  }
1046 
1047  if(!(tempbx & temp)) {
1048  tempax = DisableCRT2Display;
1049  tempbx = 0;
1050  }
1051 
1052  if(SiS_Pr->SiS_VBType & VB_SISVB) {
1053 
1054  unsigned short clearmask = ( DriverMode |
1056  LoadDACFlag |
1057  SetNotSimuMode |
1058  SetInSlaveMode |
1059  SetPALTV |
1060  SwitchCRT2 |
1061  SetSimuScanMode );
1062 
1063  if(tempbx & SetCRT2ToLCDA) tempbx &= (clearmask | SetCRT2ToLCDA);
1064  if(tempbx & SetCRT2ToRAMDAC) tempbx &= (clearmask | SetCRT2ToRAMDAC);
1065  if(tempbx & SetCRT2ToLCD) tempbx &= (clearmask | SetCRT2ToLCD);
1066  if(tempbx & SetCRT2ToSCART) tempbx &= (clearmask | SetCRT2ToSCART);
1067  if(tempbx & SetCRT2ToHiVision) tempbx &= (clearmask | SetCRT2ToHiVision);
1068  if(tempbx & SetCRT2ToYPbPr525750) tempbx &= (clearmask | SetCRT2ToYPbPr525750);
1069 
1070  } else {
1071 
1072  if(SiS_Pr->ChipType >= SIS_315H) {
1073  if(tempbx & SetCRT2ToLCDA) {
1074  tempbx &= (0xFF00|SwitchCRT2|SetSimuScanMode);
1075  }
1076  }
1077  if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1078  if(tempbx & SetCRT2ToTV) {
1079  tempbx &= (0xFF00|SetCRT2ToTV|SwitchCRT2|SetSimuScanMode);
1080  }
1081  }
1082  if(tempbx & SetCRT2ToLCD) {
1083  tempbx &= (0xFF00|SetCRT2ToLCD|SwitchCRT2|SetSimuScanMode);
1084  }
1085  if(SiS_Pr->ChipType >= SIS_315H) {
1086  if(tempbx & SetCRT2ToLCDA) {
1087  tempbx |= SetCRT2ToLCD;
1088  }
1089  }
1090 
1091  }
1092 
1093  if(tempax & DisableCRT2Display) {
1094  if(!(tempbx & (SwitchCRT2 | SetSimuScanMode))) {
1096  }
1097  }
1098 
1099  if(!(tempbx & DriverMode)) tempbx |= SetSimuScanMode;
1100 
1101  /* LVDS/CHRONTEL (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */
1102  if(SiS_Pr->SiS_ModeType <= ModeVGA) {
1103  if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
1104  ((SiS_Pr->SiS_VBType & VB_NoLCD) && (tempbx & SetCRT2ToLCD)) ) {
1105  modeflag &= (~CRT2Mode);
1106  }
1107  }
1108 
1109  if(!(tempbx & SetSimuScanMode)) {
1110  if(tempbx & SwitchCRT2) {
1111  if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1112  if(resinfo != SIS_RI_1600x1200) {
1113  tempbx |= SetSimuScanMode;
1114  }
1115  }
1116  } else {
1117  if(SiS_BridgeIsEnabled(SiS_Pr)) {
1118  if(!(tempbx & DriverMode)) {
1119  if(SiS_BridgeInSlavemode(SiS_Pr)) {
1120  tempbx |= SetSimuScanMode;
1121  }
1122  }
1123  }
1124  }
1125  }
1126 
1127  if(!(tempbx & DisableCRT2Display)) {
1128  if(tempbx & DriverMode) {
1129  if(tempbx & SetSimuScanMode) {
1130  if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1131  if(resinfo != SIS_RI_1600x1200) {
1132  tempbx |= SetInSlaveMode;
1133  }
1134  }
1135  }
1136  } else {
1137  tempbx |= SetInSlaveMode;
1138  }
1139  }
1140 
1141  }
1142 
1143  SiS_Pr->SiS_VBInfo = tempbx;
1144 
1145 #ifdef CONFIG_FB_SIS_300
1146  if(SiS_Pr->ChipType == SIS_630) {
1147  SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo);
1148  }
1149 #endif
1150 
1151 #if 0
1152  printk(KERN_DEBUG "sisfb: (init301: VBInfo= 0x%04x, SetFlag=0x%04x)\n",
1153  SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
1154 #endif
1155 }
1156 
1157 /*********************************************/
1158 /* DETERMINE YPbPr MODE */
1159 /*********************************************/
1160 
1161 void
1162 SiS_SetYPbPr(struct SiS_Private *SiS_Pr)
1163 {
1164 
1165  unsigned char temp;
1166 
1167  /* Note: This variable is only used on 30xLV systems.
1168  * CR38 has a different meaning on LVDS/CH7019 systems.
1169  * On 661 and later, these bits moved to CR35.
1170  *
1171  * On 301, 301B, only HiVision 1080i is supported.
1172  * On 30xLV, 301C, only YPbPr 1080i is supported.
1173  */
1174 
1175  SiS_Pr->SiS_YPbPr = 0;
1176  if(SiS_Pr->ChipType >= SIS_661) return;
1177 
1178  if(SiS_Pr->SiS_VBType) {
1179  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1180  SiS_Pr->SiS_YPbPr = YPbPrHiVision;
1181  }
1182  }
1183 
1184  if(SiS_Pr->ChipType >= SIS_315H) {
1185  if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1186  temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1187  if(temp & 0x08) {
1188  switch((temp >> 4)) {
1189  case 0x00: SiS_Pr->SiS_YPbPr = YPbPr525i; break;
1190  case 0x01: SiS_Pr->SiS_YPbPr = YPbPr525p; break;
1191  case 0x02: SiS_Pr->SiS_YPbPr = YPbPr750p; break;
1192  case 0x03: SiS_Pr->SiS_YPbPr = YPbPrHiVision; break;
1193  }
1194  }
1195  }
1196  }
1197 
1198 }
1199 
1200 /*********************************************/
1201 /* DETERMINE TVMode flag */
1202 /*********************************************/
1203 
1204 void
1205 SiS_SetTVMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
1206 {
1207  unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
1208  unsigned short temp, temp1, resinfo = 0, romindex = 0;
1209  unsigned char OutputSelect = *SiS_Pr->pSiS_OutputSelect;
1210 
1211  SiS_Pr->SiS_TVMode = 0;
1212 
1213  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
1214  if(SiS_Pr->UseCustomMode) return;
1215 
1216  if(ModeNo > 0x13) {
1217  resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1218  }
1219 
1220  if(SiS_Pr->ChipType < SIS_661) {
1221 
1222  if(SiS_Pr->SiS_VBInfo & SetPALTV) SiS_Pr->SiS_TVMode |= TVSetPAL;
1223 
1224  if(SiS_Pr->SiS_VBType & VB_SISVB) {
1225  temp = 0;
1226  if((SiS_Pr->ChipType == SIS_630) ||
1227  (SiS_Pr->ChipType == SIS_730)) {
1228  temp = 0x35;
1229  romindex = 0xfe;
1230  } else if(SiS_Pr->ChipType >= SIS_315H) {
1231  temp = 0x38;
1232  if(SiS_Pr->ChipType < XGI_20) {
1233  romindex = 0xf3;
1234  if(SiS_Pr->ChipType >= SIS_330) romindex = 0x11b;
1235  }
1236  }
1237  if(temp) {
1238  if(romindex && SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
1239  OutputSelect = ROMAddr[romindex];
1240  if(!(OutputSelect & EnablePALMN)) {
1241  SiS_SetRegAND(SiS_Pr->SiS_P3d4,temp,0x3F);
1242  }
1243  }
1244  temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,temp);
1245  if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1246  if(temp1 & EnablePALM) { /* 0x40 */
1247  SiS_Pr->SiS_TVMode |= TVSetPALM;
1248  SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1249  } else if(temp1 & EnablePALN) { /* 0x80 */
1250  SiS_Pr->SiS_TVMode |= TVSetPALN;
1251  }
1252  } else {
1253  if(temp1 & EnableNTSCJ) { /* 0x40 */
1254  SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1255  }
1256  }
1257  }
1258  /* Translate HiVision/YPbPr to our new flags */
1259  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1260  if(SiS_Pr->SiS_YPbPr == YPbPr750p) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1261  else if(SiS_Pr->SiS_YPbPr == YPbPr525p) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1262  else if(SiS_Pr->SiS_YPbPr == YPbPrHiVision) SiS_Pr->SiS_TVMode |= TVSetHiVision;
1263  else SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1265  SiS_Pr->SiS_VBInfo &= ~SetCRT2ToHiVision;
1266  SiS_Pr->SiS_VBInfo |= SetCRT2ToYPbPr525750;
1267  } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
1268  SiS_Pr->SiS_TVMode |= TVSetPAL;
1269  }
1270  }
1271  } else if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1272  if(SiS_Pr->SiS_CHOverScan) {
1273  if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
1274  temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1275  if((temp & TVOverScan) || (SiS_Pr->SiS_CHOverScan == 1)) {
1276  SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1277  }
1278  } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1279  temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79);
1280  if((temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1)) {
1281  SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1282  }
1283  }
1284  if(SiS_Pr->SiS_CHSOverScan) {
1285  SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1286  }
1287  }
1288  if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1289  temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1290  if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1291  if(temp & EnablePALM) SiS_Pr->SiS_TVMode |= TVSetPALM;
1292  else if(temp & EnablePALN) SiS_Pr->SiS_TVMode |= TVSetPALN;
1293  } else {
1294  if(temp & EnableNTSCJ) {
1295  SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1296  }
1297  }
1298  }
1299  }
1300 
1301  } else { /* 661 and later */
1302 
1303  temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1304  if(temp1 & 0x01) {
1305  SiS_Pr->SiS_TVMode |= TVSetPAL;
1306  if(temp1 & 0x08) {
1307  SiS_Pr->SiS_TVMode |= TVSetPALN;
1308  } else if(temp1 & 0x04) {
1309  if(SiS_Pr->SiS_VBType & VB_SISVB) {
1310  SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1311  }
1312  SiS_Pr->SiS_TVMode |= TVSetPALM;
1313  }
1314  } else {
1315  if(temp1 & 0x02) {
1316  SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1317  }
1318  }
1319  if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1320  if(SiS_Pr->SiS_CHOverScan) {
1321  if((temp1 & 0x10) || (SiS_Pr->SiS_CHOverScan == 1)) {
1322  SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1323  }
1324  }
1325  }
1326  if(SiS_Pr->SiS_VBType & VB_SISVB) {
1327  if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1328  temp1 &= 0xe0;
1329  if(temp1 == 0x00) SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1330  else if(temp1 == 0x20) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1331  else if(temp1 == 0x40) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1332  } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1333  SiS_Pr->SiS_TVMode |= (TVSetHiVision | TVSetPAL);
1334  }
1336  if(resinfo == SIS_RI_800x480 || resinfo == SIS_RI_1024x576 || resinfo == SIS_RI_1280x720) {
1337  SiS_Pr->SiS_TVMode |= TVAspect169;
1338  } else {
1339  temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x39);
1340  if(temp1 & 0x02) {
1341  if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetHiVision)) {
1342  SiS_Pr->SiS_TVMode |= TVAspect169;
1343  } else {
1344  SiS_Pr->SiS_TVMode |= TVAspect43LB;
1345  }
1346  } else {
1347  SiS_Pr->SiS_TVMode |= TVAspect43;
1348  }
1349  }
1350  }
1351  }
1352  }
1353 
1354  if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) SiS_Pr->SiS_TVMode |= TVSetPAL;
1355 
1356  if(SiS_Pr->SiS_VBType & VB_SISVB) {
1357 
1358  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1359  SiS_Pr->SiS_TVMode |= TVSetPAL;
1360  SiS_Pr->SiS_TVMode &= ~(TVSetPALM | TVSetPALN | TVSetNTSCJ);
1361  } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1363  SiS_Pr->SiS_TVMode &= ~(TVSetPAL | TVSetNTSCJ | TVSetPALM | TVSetPALN);
1364  }
1365  }
1366 
1367  if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
1368  if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
1369  SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
1370  }
1371  }
1372 
1373  if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
1374  if(resinfo == SIS_RI_1024x768) {
1375  if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
1376  SiS_Pr->SiS_TVMode |= TVSet525p1024;
1377  } else if(!(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p))) {
1378  SiS_Pr->SiS_TVMode |= TVSetNTSC1024;
1379  }
1380  }
1381  }
1382 
1383  SiS_Pr->SiS_TVMode |= TVRPLLDIV2XO;
1384  if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) &&
1385  (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
1386  SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1387  } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
1388  SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1389  } else if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) {
1390  if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
1391  SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1392  }
1393  }
1394 
1395  }
1396 
1397  SiS_Pr->SiS_VBInfo &= ~SetPALTV;
1398 }
1399 
1400 /*********************************************/
1401 /* GET LCD INFO */
1402 /*********************************************/
1403 
1404 static unsigned short
1405 SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr)
1406 {
1407  unsigned short temp = SiS_Pr->SiS_LCDResInfo;
1408  /* Translate my LCDResInfo to BIOS value */
1409  switch(temp) {
1410  case Panel_1280x768_2: temp = Panel_1280x768; break;
1411  case Panel_1280x800_2: temp = Panel_1280x800; break;
1412  case Panel_1280x854: temp = Panel661_1280x854; break;
1413  }
1414  return temp;
1415 }
1416 
1417 static void
1418 SiS_GetLCDInfoBIOS(struct SiS_Private *SiS_Pr)
1419 {
1420 #ifdef CONFIG_FB_SIS_315
1421  unsigned char *ROMAddr;
1422  unsigned short temp;
1423 
1424  if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
1425  if((temp = SISGETROMW(6)) != SiS_Pr->PanelHT) {
1426  SiS_Pr->SiS_NeedRomModeData = true;
1427  SiS_Pr->PanelHT = temp;
1428  }
1429  if((temp = SISGETROMW(8)) != SiS_Pr->PanelVT) {
1430  SiS_Pr->SiS_NeedRomModeData = true;
1431  SiS_Pr->PanelVT = temp;
1432  }
1433  SiS_Pr->PanelHRS = SISGETROMW(10);
1434  SiS_Pr->PanelHRE = SISGETROMW(12);
1435  SiS_Pr->PanelVRS = SISGETROMW(14);
1436  SiS_Pr->PanelVRE = SISGETROMW(16);
1437  SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
1438  SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].CLOCK =
1439  SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].CLOCK = (unsigned short)((unsigned char)ROMAddr[18]);
1440  SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2B =
1441  SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_A = ROMAddr[19];
1442  SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2C =
1443  SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_B = ROMAddr[20];
1444 
1445  }
1446 #endif
1447 }
1448 
1449 static void
1450 SiS_CheckScaling(struct SiS_Private *SiS_Pr, unsigned short resinfo,
1451  const unsigned char *nonscalingmodes)
1452 {
1453  int i = 0;
1454  while(nonscalingmodes[i] != 0xff) {
1455  if(nonscalingmodes[i++] == resinfo) {
1456  if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ||
1457  (SiS_Pr->UsePanelScaler == -1)) {
1458  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1459  }
1460  break;
1461  }
1462  }
1463 }
1464 
1465 void
1466 SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
1467 {
1468  unsigned short temp,modeflag,resinfo=0,modexres=0,modeyres=0;
1469  bool panelcanscale = false;
1470 #ifdef CONFIG_FB_SIS_300
1471  unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
1472  static const unsigned char SiS300SeriesLCDRes[] =
1473  { 0, 1, 2, 3, 7, 4, 5, 8,
1474  0, 0, 10, 0, 0, 0, 0, 15 };
1475 #endif
1476 #ifdef CONFIG_FB_SIS_315
1477  unsigned char *myptr = NULL;
1478 #endif
1479 
1480  SiS_Pr->SiS_LCDResInfo = 0;
1481  SiS_Pr->SiS_LCDTypeInfo = 0;
1482  SiS_Pr->SiS_LCDInfo = 0;
1483  SiS_Pr->PanelHRS = 999; /* HSync start */
1484  SiS_Pr->PanelHRE = 999; /* HSync end */
1485  SiS_Pr->PanelVRS = 999; /* VSync start */
1486  SiS_Pr->PanelVRE = 999; /* VSync end */
1487  SiS_Pr->SiS_NeedRomModeData = false;
1488 
1489  /* Alternative 1600x1200@60 timing for 1600x1200 LCDA */
1490  SiS_Pr->Alternate1600x1200 = false;
1491 
1492  if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return;
1493 
1494  modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
1495 
1496  if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
1497  resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1498  modexres = SiS_Pr->SiS_ModeResInfo[resinfo].HTotal;
1499  modeyres = SiS_Pr->SiS_ModeResInfo[resinfo].VTotal;
1500  }
1501 
1502  temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
1503 
1504  /* For broken BIOSes: Assume 1024x768 */
1505  if(temp == 0) temp = 0x02;
1506 
1507  if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
1508  SiS_Pr->SiS_LCDTypeInfo = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x7c) >> 2;
1509  } else if((SiS_Pr->ChipType < SIS_315H) || (SiS_Pr->ChipType >= SIS_661)) {
1510  SiS_Pr->SiS_LCDTypeInfo = temp >> 4;
1511  } else {
1512  SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1;
1513  }
1514  temp &= 0x0f;
1515 #ifdef CONFIG_FB_SIS_300
1516  if(SiS_Pr->ChipType < SIS_315H) {
1517  /* Very old BIOSes only know 7 sizes (NetVista 2179, 1.01g) */
1518  if(SiS_Pr->SiS_VBType & VB_SIS301) {
1519  if(temp < 0x0f) temp &= 0x07;
1520  }
1521  /* Translate 300 series LCDRes to 315 series for unified usage */
1522  temp = SiS300SeriesLCDRes[temp];
1523  }
1524 #endif
1525 
1526  /* Translate to our internal types */
1527 #ifdef CONFIG_FB_SIS_315
1528  if(SiS_Pr->ChipType == SIS_550) {
1529  if (temp == Panel310_1152x768) temp = Panel_320x240_2; /* Verified working */
1530  else if(temp == Panel310_320x240_2) temp = Panel_320x240_2;
1531  else if(temp == Panel310_320x240_3) temp = Panel_320x240_3;
1532  } else if(SiS_Pr->ChipType >= SIS_661) {
1533  if(temp == Panel661_1280x854) temp = Panel_1280x854;
1534  }
1535 #endif
1536 
1537  if(SiS_Pr->SiS_VBType & VB_SISLVDS) { /* SiS LVDS */
1538  if(temp == Panel310_1280x768) {
1539  temp = Panel_1280x768_2;
1540  }
1541  if(SiS_Pr->SiS_ROMNew) {
1542  if(temp == Panel661_1280x800) {
1543  temp = Panel_1280x800_2;
1544  }
1545  }
1546  }
1547 
1548  SiS_Pr->SiS_LCDResInfo = temp;
1549 
1550 #ifdef CONFIG_FB_SIS_300
1551  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1552  if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
1553  SiS_Pr->SiS_LCDResInfo = Panel_Barco1366;
1554  } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
1555  SiS_Pr->SiS_LCDResInfo = Panel_848x480;
1556  } else if(SiS_Pr->SiS_CustomT == CUT_PANEL856) {
1557  SiS_Pr->SiS_LCDResInfo = Panel_856x480;
1558  }
1559  }
1560 #endif
1561 
1562  if(SiS_Pr->SiS_VBType & VB_SISVB) {
1563  if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)
1564  SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMin301;
1565  } else {
1566  if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMinLVDS)
1567  SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS;
1568  }
1569 
1570  temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
1571  SiS_Pr->SiS_LCDInfo = temp & ~0x000e;
1572  /* Need temp below! */
1573 
1574  /* These must/can't scale no matter what */
1575  switch(SiS_Pr->SiS_LCDResInfo) {
1576  case Panel_320x240_1:
1577  case Panel_320x240_2:
1578  case Panel_320x240_3:
1579  case Panel_1280x960:
1580  SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1581  break;
1582  case Panel_640x480:
1583  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1584  }
1585 
1586  panelcanscale = (bool)(SiS_Pr->SiS_LCDInfo & DontExpandLCD);
1587 
1588  if(!SiS_Pr->UsePanelScaler) SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1589  else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1590 
1591  /* Dual link, Pass 1:1 BIOS default, etc. */
1592 #ifdef CONFIG_FB_SIS_315
1593  if(SiS_Pr->ChipType >= SIS_661) {
1594  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1595  if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1596  }
1597  if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1598  if(SiS_Pr->SiS_ROMNew) {
1599  if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1600  } else if((myptr = GetLCDStructPtr661(SiS_Pr))) {
1601  if(myptr[2] & 0x01) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1602  }
1603  }
1604  } else if(SiS_Pr->ChipType >= SIS_315H) {
1605  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1606  if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1607  }
1608  if((SiS_Pr->SiS_ROMNew) && (!(SiS_Pr->PanelSelfDetected))) {
1609  SiS_Pr->SiS_LCDInfo &= ~(LCDRGB18Bit);
1610  temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1611  if(temp & 0x01) SiS_Pr->SiS_LCDInfo |= LCDRGB18Bit;
1612  if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1613  if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1614  }
1615  } else if(!(SiS_Pr->SiS_ROMNew)) {
1616  if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1617  if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) &&
1618  (SiS_Pr->SiS_LCDResInfo == Panel_1024x768)) {
1619  SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1620  }
1621  if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
1622  (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
1623  (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
1624  (SiS_Pr->SiS_LCDResInfo == Panel_1680x1050)) {
1625  SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1626  }
1627  }
1628  }
1629  }
1630 #endif
1631 
1632  /* Pass 1:1 */
1633  if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
1634  /* Always center screen on LVDS (if scaling is disabled) */
1635  SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1636  } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
1637  if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
1638  /* Always center screen on SiS LVDS (if scaling is disabled) */
1639  SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1640  } else {
1641  /* By default, pass 1:1 on SiS TMDS (if scaling is supported) */
1642  if(panelcanscale) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1643  if(SiS_Pr->CenterScreen == 1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1644  }
1645  }
1646 
1647  SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1648  SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1649 
1650  switch(SiS_Pr->SiS_LCDResInfo) {
1651  case Panel_320x240_1:
1652  case Panel_320x240_2:
1653  case Panel_320x240_3: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
1654  SiS_Pr->PanelVRS = 24; SiS_Pr->PanelVRE = 3;
1655  SiS_Pr->PanelVCLKIdx300 = VCLK28;
1656  SiS_Pr->PanelVCLKIdx315 = VCLK28;
1657  break;
1658  case Panel_640x480: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
1659  SiS_Pr->PanelVRE = 3;
1660  SiS_Pr->PanelVCLKIdx300 = VCLK28;
1661  SiS_Pr->PanelVCLKIdx315 = VCLK28;
1662  break;
1663  case Panel_800x600: SiS_Pr->PanelXRes = 800; SiS_Pr->PanelYRes = 600;
1664  SiS_Pr->PanelHT = 1056; SiS_Pr->PanelVT = 628;
1665  SiS_Pr->PanelHRS = 40; SiS_Pr->PanelHRE = 128;
1666  SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 4;
1667  SiS_Pr->PanelVCLKIdx300 = VCLK40;
1668  SiS_Pr->PanelVCLKIdx315 = VCLK40;
1669  break;
1670  case Panel_1024x600: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 600;
1671  SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 800;
1672  SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
1673  SiS_Pr->PanelVRS = 2 /* 88 */ ; SiS_Pr->PanelVRE = 6;
1674  SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1675  SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1676  break;
1677  case Panel_1024x768: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768;
1678  SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1679  SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
1680  SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1681  if(SiS_Pr->ChipType < SIS_315H) {
1682  SiS_Pr->PanelHRS = 23;
1683  SiS_Pr->PanelVRE = 5;
1684  }
1685  SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1686  SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1687  SiS_GetLCDInfoBIOS(SiS_Pr);
1688  break;
1689  case Panel_1152x768: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 768;
1690  SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1691  SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
1692  SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1693  if(SiS_Pr->ChipType < SIS_315H) {
1694  SiS_Pr->PanelHRS = 23;
1695  SiS_Pr->PanelVRE = 5;
1696  }
1697  SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1698  SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1699  break;
1700  case Panel_1152x864: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 864;
1701  break;
1702  case Panel_1280x720: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 720;
1703  SiS_Pr->PanelHT = 1650; SiS_Pr->PanelVT = 750;
1704  SiS_Pr->PanelHRS = 110; SiS_Pr->PanelHRE = 40;
1705  SiS_Pr->PanelVRS = 5; SiS_Pr->PanelVRE = 5;
1706  SiS_Pr->PanelVCLKIdx315 = VCLK_1280x720;
1707  /* Data above for TMDS (projector); get from BIOS for LVDS */
1708  SiS_GetLCDInfoBIOS(SiS_Pr);
1709  break;
1710  case Panel_1280x768: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768;
1711  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1712  SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 806;
1713  SiS_Pr->PanelVCLKIdx300 = VCLK81_300; /* ? */
1714  SiS_Pr->PanelVCLKIdx315 = VCLK81_315; /* ? */
1715  } else {
1716  SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 802;
1717  SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRS = 112;
1718  SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1719  SiS_Pr->PanelVCLKIdx300 = VCLK81_300;
1720  SiS_Pr->PanelVCLKIdx315 = VCLK81_315;
1721  }
1722  break;
1723  case Panel_1280x768_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768;
1724  SiS_Pr->PanelHT = 1660; SiS_Pr->PanelVT = 806;
1725  SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1726  SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1727  SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_2;
1728  SiS_GetLCDInfoBIOS(SiS_Pr);
1729  break;
1730  case Panel_1280x800: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800;
1731  SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 816;
1732  SiS_Pr->PanelHRS = 21; SiS_Pr->PanelHRE = 24;
1733  SiS_Pr->PanelVRS = 4; SiS_Pr->PanelVRE = 3;
1735  SiS_GetLCDInfoBIOS(SiS_Pr);
1736  break;
1737  case Panel_1280x800_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800;
1738  SiS_Pr->PanelHT = 1552; SiS_Pr->PanelVT = 812;
1739  SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1740  SiS_Pr->PanelVRS = 4; SiS_Pr->PanelVRE = 3;
1742  SiS_GetLCDInfoBIOS(SiS_Pr);
1743  break;
1744  case Panel_1280x854: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 854;
1745  SiS_Pr->PanelHT = 1664; SiS_Pr->PanelVT = 861;
1746  SiS_Pr->PanelHRS = 16; SiS_Pr->PanelHRE = 112;
1747  SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1748  SiS_Pr->PanelVCLKIdx315 = VCLK_1280x854;
1749  SiS_GetLCDInfoBIOS(SiS_Pr);
1750  break;
1751  case Panel_1280x960: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 960;
1752  SiS_Pr->PanelHT = 1800; SiS_Pr->PanelVT = 1000;
1753  SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
1754  SiS_Pr->PanelVCLKIdx315 = VCLK108_3_315;
1755  if(resinfo == SIS_RI_1280x1024) {
1756  SiS_Pr->PanelVCLKIdx300 = VCLK100_300;
1757  SiS_Pr->PanelVCLKIdx315 = VCLK100_315;
1758  }
1759  break;
1760  case Panel_1280x1024: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024;
1761  SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1762  SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1763  SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1764  SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
1765  SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1766  SiS_GetLCDInfoBIOS(SiS_Pr);
1767  break;
1768  case Panel_1400x1050: SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050;
1769  SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1770  SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1771  SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1772  SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1773  SiS_GetLCDInfoBIOS(SiS_Pr);
1774  break;
1775  case Panel_1600x1200: SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200;
1776  SiS_Pr->PanelHT = 2160; SiS_Pr->PanelVT = 1250;
1777  SiS_Pr->PanelHRS = 64; SiS_Pr->PanelHRE = 192;
1778  SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1779  SiS_Pr->PanelVCLKIdx315 = VCLK162_315;
1780  if(SiS_Pr->SiS_VBType & VB_SISTMDSLCDA) {
1781  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
1782  SiS_Pr->PanelHT = 1760; SiS_Pr->PanelVT = 1235;
1783  SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 32;
1784  SiS_Pr->PanelVRS = 2; SiS_Pr->PanelVRE = 4;
1785  SiS_Pr->PanelVCLKIdx315 = VCLK130_315;
1786  SiS_Pr->Alternate1600x1200 = true;
1787  }
1788  } else if(SiS_Pr->SiS_IF_DEF_LVDS) {
1789  SiS_Pr->PanelHT = 2048; SiS_Pr->PanelVT = 1320;
1790  SiS_Pr->PanelHRS = SiS_Pr->PanelHRE = 999;
1791  SiS_Pr->PanelVRS = SiS_Pr->PanelVRE = 999;
1792  }
1793  SiS_GetLCDInfoBIOS(SiS_Pr);
1794  break;
1795  case Panel_1680x1050: SiS_Pr->PanelXRes = 1680; SiS_Pr->PanelYRes = 1050;
1796  SiS_Pr->PanelHT = 1900; SiS_Pr->PanelVT = 1066;
1797  SiS_Pr->PanelHRS = 26; SiS_Pr->PanelHRE = 76;
1798  SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1799  SiS_Pr->PanelVCLKIdx315 = VCLK121_315;
1800  SiS_GetLCDInfoBIOS(SiS_Pr);
1801  break;
1802  case Panel_Barco1366: SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024;
1803  SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1804  break;
1805  case Panel_848x480: SiS_Pr->PanelXRes = 848; SiS_Pr->PanelYRes = 480;
1806  SiS_Pr->PanelHT = 1088; SiS_Pr->PanelVT = 525;
1807  break;
1808  case Panel_856x480: SiS_Pr->PanelXRes = 856; SiS_Pr->PanelYRes = 480;
1809  SiS_Pr->PanelHT = 1088; SiS_Pr->PanelVT = 525;
1810  break;
1811  case Panel_Custom: SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX;
1812  SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY;
1813  SiS_Pr->PanelHT = SiS_Pr->CHTotal;
1814  SiS_Pr->PanelVT = SiS_Pr->CVTotal;
1815  if(SiS_Pr->CP_PreferredIndex != -1) {
1816  SiS_Pr->PanelXRes = SiS_Pr->CP_HDisplay[SiS_Pr->CP_PreferredIndex];
1817  SiS_Pr->PanelYRes = SiS_Pr->CP_VDisplay[SiS_Pr->CP_PreferredIndex];
1818  SiS_Pr->PanelHT = SiS_Pr->CP_HTotal[SiS_Pr->CP_PreferredIndex];
1819  SiS_Pr->PanelVT = SiS_Pr->CP_VTotal[SiS_Pr->CP_PreferredIndex];
1820  SiS_Pr->PanelHRS = SiS_Pr->CP_HSyncStart[SiS_Pr->CP_PreferredIndex];
1821  SiS_Pr->PanelHRE = SiS_Pr->CP_HSyncEnd[SiS_Pr->CP_PreferredIndex];
1822  SiS_Pr->PanelVRS = SiS_Pr->CP_VSyncStart[SiS_Pr->CP_PreferredIndex];
1823  SiS_Pr->PanelVRE = SiS_Pr->CP_VSyncEnd[SiS_Pr->CP_PreferredIndex];
1824  SiS_Pr->PanelHRS -= SiS_Pr->PanelXRes;
1825  SiS_Pr->PanelHRE -= SiS_Pr->PanelHRS;
1826  SiS_Pr->PanelVRS -= SiS_Pr->PanelYRes;
1827  SiS_Pr->PanelVRE -= SiS_Pr->PanelVRS;
1828  if(SiS_Pr->CP_PrefClock) {
1829  int idx;
1830  SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
1831  SiS_Pr->PanelVCLKIdx300 = VCLK_CUSTOM_300;
1832  if(SiS_Pr->ChipType < SIS_315H) idx = VCLK_CUSTOM_300;
1833  else idx = VCLK_CUSTOM_315;
1834  SiS_Pr->SiS_VCLKData[idx].CLOCK =
1835  SiS_Pr->SiS_VBVCLKData[idx].CLOCK = SiS_Pr->CP_PrefClock;
1836  SiS_Pr->SiS_VCLKData[idx].SR2B =
1837  SiS_Pr->SiS_VBVCLKData[idx].Part4_A = SiS_Pr->CP_PrefSR2B;
1838  SiS_Pr->SiS_VCLKData[idx].SR2C =
1839  SiS_Pr->SiS_VBVCLKData[idx].Part4_B = SiS_Pr->CP_PrefSR2C;
1840  }
1841  }
1842  break;
1843  default: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768;
1844  SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1845  break;
1846  }
1847 
1848  /* Special cases */
1849  if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
1850  (SiS_Pr->SiS_IF_DEF_DSTN) ||
1851  (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
1852  (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
1853  (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
1854  (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
1855  SiS_Pr->PanelHRS = 999;
1856  SiS_Pr->PanelHRE = 999;
1857  }
1858 
1859  if( (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
1860  (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
1861  (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
1862  (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
1863  SiS_Pr->PanelVRS = 999;
1864  SiS_Pr->PanelVRE = 999;
1865  }
1866 
1867  /* DontExpand overrule */
1868  if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
1869 
1870  if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (modeflag & NoSupportLCDScale)) {
1871  /* No scaling for this mode on any panel (LCD=CRT2)*/
1872  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1873  }
1874 
1875  switch(SiS_Pr->SiS_LCDResInfo) {
1876 
1877  case Panel_Custom:
1878  case Panel_1152x864:
1879  case Panel_1280x768: /* TMDS only */
1880  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1881  break;
1882 
1883  case Panel_800x600: {
1884  static const unsigned char nonscalingmodes[] = {
1886  };
1887  SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1888  break;
1889  }
1890  case Panel_1024x768: {
1891  static const unsigned char nonscalingmodes[] = {
1894  0xff
1895  };
1896  SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1897  break;
1898  }
1899  case Panel_1280x720: {
1900  static const unsigned char nonscalingmodes[] = {
1903  0xff
1904  };
1905  SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1906  if(SiS_Pr->PanelHT == 1650) {
1907  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1908  }
1909  break;
1910  }
1911  case Panel_1280x768_2: { /* LVDS only */
1912  static const unsigned char nonscalingmodes[] = {
1915  SIS_RI_1152x768,0xff
1916  };
1917  SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1918  switch(resinfo) {
1919  case SIS_RI_1280x720: if(SiS_Pr->UsePanelScaler == -1) {
1920  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1921  }
1922  break;
1923  }
1924  break;
1925  }
1926  case Panel_1280x800: { /* SiS TMDS special (Averatec 6200 series) */
1927  static const unsigned char nonscalingmodes[] = {
1931  };
1932  SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1933  break;
1934  }
1935  case Panel_1280x800_2: { /* SiS LVDS */
1936  static const unsigned char nonscalingmodes[] = {
1939  SIS_RI_1152x768,0xff
1940  };
1941  SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1942  switch(resinfo) {
1943  case SIS_RI_1280x720:
1944  case SIS_RI_1280x768: if(SiS_Pr->UsePanelScaler == -1) {
1945  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1946  }
1947  break;
1948  }
1949  break;
1950  }
1951  case Panel_1280x854: { /* SiS LVDS */
1952  static const unsigned char nonscalingmodes[] = {
1955  SIS_RI_1152x768,0xff
1956  };
1957  SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1958  switch(resinfo) {
1959  case SIS_RI_1280x720:
1960  case SIS_RI_1280x768:
1961  case SIS_RI_1280x800: if(SiS_Pr->UsePanelScaler == -1) {
1962  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1963  }
1964  break;
1965  }
1966  break;
1967  }
1968  case Panel_1280x960: {
1969  static const unsigned char nonscalingmodes[] = {
1973  SIS_RI_1280x854,0xff
1974  };
1975  SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1976  break;
1977  }
1978  case Panel_1280x1024: {
1979  static const unsigned char nonscalingmodes[] = {
1984  };
1985  SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1986  break;
1987  }
1988  case Panel_1400x1050: {
1989  static const unsigned char nonscalingmodes[] = {
1993  SIS_RI_1280x960,0xff
1994  };
1995  SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1996  switch(resinfo) {
1997  case SIS_RI_1280x720: if(SiS_Pr->UsePanelScaler == -1) {
1998  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1999  }
2000  break;
2001  case SIS_RI_1280x1024: SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2002  break;
2003  }
2004  break;
2005  }
2006  case Panel_1600x1200: {
2007  static const unsigned char nonscalingmodes[] = {
2012  };
2013  SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2014  break;
2015  }
2016  case Panel_1680x1050: {
2017  static const unsigned char nonscalingmodes[] = {
2021  SIS_RI_1360x1024,0xff
2022  };
2023  SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2024  break;
2025  }
2026  }
2027  }
2028 
2029 #ifdef CONFIG_FB_SIS_300
2030  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2031  if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
2032  SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20; /* neg h/v sync, RGB24(D0 = 0) */
2033  }
2034  }
2035 
2036  if(SiS_Pr->ChipType < SIS_315H) {
2037  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2038  if(SiS_Pr->SiS_UseROM) {
2039  if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
2040  if(!(ROMAddr[0x235] & 0x02)) {
2041  SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2042  }
2043  }
2044  }
2045  } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2046  if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
2047  SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2048  }
2049  }
2050  }
2051 #endif
2052 
2053  /* Special cases */
2054 
2055  if(modexres == SiS_Pr->PanelXRes && modeyres == SiS_Pr->PanelYRes) {
2056  SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2057  }
2058 
2059  if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
2060  SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2061  }
2062 
2063  switch(SiS_Pr->SiS_LCDResInfo) {
2064  case Panel_640x480:
2065  SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2066  break;
2067  case Panel_1280x800:
2068  /* Don't pass 1:1 by default (TMDS special) */
2069  if(SiS_Pr->CenterScreen == -1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2070  break;
2071  case Panel_1280x960:
2072  SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2073  break;
2074  case Panel_Custom:
2075  if((!SiS_Pr->CP_PrefClock) ||
2076  (modexres > SiS_Pr->PanelXRes) || (modeyres > SiS_Pr->PanelYRes)) {
2077  SiS_Pr->SiS_LCDInfo |= LCDPass11;
2078  }
2079  break;
2080  }
2081 
2082  if((SiS_Pr->UseCustomMode) || (SiS_Pr->SiS_CustomT == CUT_UNKNOWNLCD)) {
2083  SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2084  }
2085 
2086  /* (In)validate LCDPass11 flag */
2087  if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2088  SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2089  }
2090 
2091  /* LVDS DDA */
2092  if(!((SiS_Pr->ChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
2093 
2094  if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
2095  if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
2096  if(ModeNo == 0x12) {
2097  if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
2098  SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2099  }
2100  } else if(ModeNo > 0x13) {
2101  if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
2102  if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2103  if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) {
2104  SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2105  }
2106  }
2107  }
2108  }
2109  }
2110  }
2111 
2112  if(modeflag & HalfDCLK) {
2113  if(SiS_Pr->SiS_IF_DEF_TRUMPION == 1) {
2114  SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2115  } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
2116  SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2117  } else if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) {
2118  SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2119  } else if(ModeNo > 0x13) {
2120  if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
2121  if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2122  } else if(SiS_Pr->SiS_LCDResInfo == Panel_800x600) {
2123  if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2124  }
2125  }
2126  }
2127 
2128  }
2129 
2130  /* VESA timing */
2131  if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2132  if(SiS_Pr->SiS_VBInfo & SetNotSimuMode) {
2133  SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2134  }
2135  } else {
2136  SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2137  }
2138 
2139 #if 0
2140  printk(KERN_DEBUG "sisfb: (LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n",
2141  SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo);
2142 #endif
2143 }
2144 
2145 /*********************************************/
2146 /* GET VCLK */
2147 /*********************************************/
2148 
2149 unsigned short
2150 SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
2151  unsigned short RefreshRateTableIndex)
2152 {
2153  unsigned short CRT2Index, VCLKIndex = 0, VCLKIndexGEN = 0, VCLKIndexGENCRT = 0;
2154  unsigned short modeflag, resinfo, tempbx;
2155  const unsigned char *CHTVVCLKPtr = NULL;
2156 
2157  if(ModeNo <= 0x13) {
2158  modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2159  resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
2160  CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2161  VCLKIndexGEN = (SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)) >> 2) & 0x03;
2162  VCLKIndexGENCRT = VCLKIndexGEN;
2163  } else {
2164  modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2165  resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2166  CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2167  VCLKIndexGEN = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
2168  VCLKIndexGENCRT = SiS_GetRefCRTVCLK(SiS_Pr, RefreshRateTableIndex,
2169  (SiS_Pr->SiS_SetFlag & ProgrammingCRT2) ? SiS_Pr->SiS_UseWideCRT2 : SiS_Pr->SiS_UseWide);
2170  }
2171 
2172  if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 30x/B/LV */
2173 
2174  if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2175 
2176  CRT2Index >>= 6;
2177  if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /* LCD */
2178 
2179  if(SiS_Pr->ChipType < SIS_315H) {
2180  VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2181  if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2182  VCLKIndex = VCLKIndexGEN;
2183  }
2184  } else {
2185  VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2186  if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2187  switch(resinfo) {
2188  /* Correct those whose IndexGEN doesn't match VBVCLK array */
2189  case SIS_RI_720x480: VCLKIndex = VCLK_720x480; break;
2190  case SIS_RI_720x576: VCLKIndex = VCLK_720x576; break;
2191  case SIS_RI_768x576: VCLKIndex = VCLK_768x576; break;
2192  case SIS_RI_848x480: VCLKIndex = VCLK_848x480; break;
2193  case SIS_RI_856x480: VCLKIndex = VCLK_856x480; break;
2194  case SIS_RI_800x480: VCLKIndex = VCLK_800x480; break;
2195  case SIS_RI_1024x576: VCLKIndex = VCLK_1024x576; break;
2196  case SIS_RI_1152x864: VCLKIndex = VCLK_1152x864; break;
2197  case SIS_RI_1280x720: VCLKIndex = VCLK_1280x720; break;
2198  case SIS_RI_1360x768: VCLKIndex = VCLK_1360x768; break;
2199  default: VCLKIndex = VCLKIndexGEN;
2200  }
2201 
2202  if(ModeNo <= 0x13) {
2203  if(SiS_Pr->ChipType <= SIS_315PRO) {
2204  if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
2205  } else {
2206  if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x00;
2207  }
2208  }
2209  if(SiS_Pr->ChipType <= SIS_315PRO) {
2210  if(VCLKIndex == 0) VCLKIndex = 0x41;
2211  if(VCLKIndex == 1) VCLKIndex = 0x43;
2212  if(VCLKIndex == 4) VCLKIndex = 0x44;
2213  }
2214  }
2215  }
2216 
2217  } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* TV */
2218 
2219  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
2220  if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = HiTVVCLKDIV2;
2221  else VCLKIndex = HiTVVCLK;
2222  if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) VCLKIndex = HiTVSimuVCLK;
2223  } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) VCLKIndex = YPbPr750pVCLK;
2224  else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) VCLKIndex = TVVCLKDIV2;
2225  else if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = TVVCLKDIV2;
2226  else VCLKIndex = TVVCLK;
2227 
2228  if(SiS_Pr->ChipType < SIS_315H) VCLKIndex += TVCLKBASE_300;
2229  else VCLKIndex += TVCLKBASE_315;
2230 
2231  } else { /* VGA2 */
2232 
2233  VCLKIndex = VCLKIndexGENCRT;
2234  if(SiS_Pr->ChipType < SIS_315H) {
2235  if(ModeNo > 0x13) {
2236  if( (SiS_Pr->ChipType == SIS_630) &&
2237  (SiS_Pr->ChipRevision >= 0x30)) {
2238  if(VCLKIndex == 0x14) VCLKIndex = 0x34;
2239  }
2240  /* Better VGA2 clock for 1280x1024@75 */
2241  if(VCLKIndex == 0x17) VCLKIndex = 0x45;
2242  }
2243  }
2244  }
2245 
2246  } else { /* If not programming CRT2 */
2247 
2248  VCLKIndex = VCLKIndexGENCRT;
2249  if(SiS_Pr->ChipType < SIS_315H) {
2250  if(ModeNo > 0x13) {
2251  if( (SiS_Pr->ChipType != SIS_630) &&
2252  (SiS_Pr->ChipType != SIS_300) ) {
2253  if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2254  }
2255  }
2256  }
2257  }
2258 
2259  } else { /* LVDS */
2260 
2261  VCLKIndex = CRT2Index;
2262 
2263  if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2264 
2265  if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
2266 
2267  VCLKIndex &= 0x1f;
2268  tempbx = 0;
2269  if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2270  if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2271  tempbx += 2;
2272  if(SiS_Pr->SiS_ModeType > ModeVGA) {
2273  if(SiS_Pr->SiS_CHSOverScan) tempbx = 8;
2274  }
2275  if(SiS_Pr->SiS_TVMode & TVSetPALM) {
2276  tempbx = 4;
2277  if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2278  } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
2279  tempbx = 6;
2280  if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2281  }
2282  }
2283  switch(tempbx) {
2284  case 0: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUNTSC; break;
2285  case 1: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKONTSC; break;
2286  case 2: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPAL; break;
2287  case 3: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break;
2288  case 4: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALM; break;
2289  case 5: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALM; break;
2290  case 6: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALN; break;
2291  case 7: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALN; break;
2292  case 8: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKSOPAL; break;
2293  default: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break;
2294  }
2295  VCLKIndex = CHTVVCLKPtr[VCLKIndex];
2296 
2297  } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2298 
2299  if(SiS_Pr->ChipType < SIS_315H) {
2300  VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2301  } else {
2302  VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2303  }
2304 
2305 #ifdef CONFIG_FB_SIS_300
2306  /* Special Timing: Barco iQ Pro R series */
2307  if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) VCLKIndex = 0x44;
2308 
2309  /* Special Timing: 848x480 and 856x480 parallel lvds panels */
2310  if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
2311  if(SiS_Pr->ChipType < SIS_315H) {
2312  VCLKIndex = VCLK34_300;
2313  /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2314  } else {
2315  VCLKIndex = VCLK34_315;
2316  /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2317  }
2318  }
2319 #endif
2320 
2321  } else {
2322 
2323  VCLKIndex = VCLKIndexGENCRT;
2324  if(SiS_Pr->ChipType < SIS_315H) {
2325  if(ModeNo > 0x13) {
2326  if( (SiS_Pr->ChipType == SIS_630) &&
2327  (SiS_Pr->ChipRevision >= 0x30) ) {
2328  if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
2329  }
2330  }
2331  }
2332  }
2333 
2334  } else { /* if not programming CRT2 */
2335 
2336  VCLKIndex = VCLKIndexGENCRT;
2337  if(SiS_Pr->ChipType < SIS_315H) {
2338  if(ModeNo > 0x13) {
2339  if( (SiS_Pr->ChipType != SIS_630) &&
2340  (SiS_Pr->ChipType != SIS_300) ) {
2341  if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2342  }
2343 #if 0
2344  if(SiS_Pr->ChipType == SIS_730) {
2345  if(VCLKIndex == 0x0b) VCLKIndex = 0x40; /* 1024x768-70 */
2346  if(VCLKIndex == 0x0d) VCLKIndex = 0x41; /* 1024x768-75 */
2347  }
2348 #endif
2349  }
2350  }
2351 
2352  }
2353 
2354  }
2355 
2356  return VCLKIndex;
2357 }
2358 
2359 /*********************************************/
2360 /* SET CRT2 MODE TYPE REGISTERS */
2361 /*********************************************/
2362 
2363 static void
2364 SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2365 {
2366  unsigned short i, j, modeflag, tempah=0;
2367  short tempcl;
2368 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
2369  unsigned short tempbl;
2370 #endif
2371 #ifdef CONFIG_FB_SIS_315
2372  unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
2373  unsigned short tempah2, tempbl2;
2374 #endif
2375 
2376  modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
2377 
2378  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
2379 
2380  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40);
2381  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2E,0xF7);
2382 
2383  } else {
2384 
2385  for(i=0,j=4; i<3; i++,j++) SiS_SetReg(SiS_Pr->SiS_Part1Port,j,0);
2386  if(SiS_Pr->ChipType >= SIS_315H) {
2387  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0x7F);
2388  }
2389 
2390  tempcl = SiS_Pr->SiS_ModeType;
2391 
2392  if(SiS_Pr->ChipType < SIS_315H) {
2393 
2394 #ifdef CONFIG_FB_SIS_300 /* ---- 300 series ---- */
2395 
2396  /* For 301BDH: (with LCD via LVDS) */
2397  if(SiS_Pr->SiS_VBType & VB_NoLCD) {
2398  tempbl = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32);
2399  tempbl &= 0xef;
2400  tempbl |= 0x02;
2401  if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2402  tempbl |= 0x10;
2403  tempbl &= 0xfd;
2404  }
2405  SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,tempbl);
2406  }
2407 
2408  if(ModeNo > 0x13) {
2409  tempcl -= ModeVGA;
2410  if(tempcl >= 0) {
2411  tempah = ((0x10 >> tempcl) | 0x80);
2412  }
2413  } else tempah = 0x80;
2414 
2415  if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0xA0;
2416 
2417 #endif /* CONFIG_FB_SIS_300 */
2418 
2419  } else {
2420 
2421 #ifdef CONFIG_FB_SIS_315 /* ------- 315/330 series ------ */
2422 
2423  if(ModeNo > 0x13) {
2424  tempcl -= ModeVGA;
2425  if(tempcl >= 0) {
2426  tempah = (0x08 >> tempcl);
2427  if (tempah == 0) tempah = 1;
2428  tempah |= 0x40;
2429  }
2430  } else tempah = 0x40;
2431 
2432  if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50;
2433 
2434 #endif /* CONFIG_FB_SIS_315 */
2435 
2436  }
2437 
2438  if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2439 
2440  if(SiS_Pr->ChipType < SIS_315H) {
2441  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2442  } else {
2443 #ifdef CONFIG_FB_SIS_315
2444  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2445  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2446  } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
2447  if(IS_SIS740) {
2448  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2449  } else {
2450  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2451  }
2452  }
2453 #endif
2454  }
2455 
2456  if(SiS_Pr->SiS_VBType & VB_SISVB) {
2457 
2458  tempah = 0x01;
2459  if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
2460  tempah |= 0x02;
2461  }
2462  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2463  tempah ^= 0x05;
2464  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
2465  tempah ^= 0x01;
2466  }
2467  }
2468 
2469  if(SiS_Pr->ChipType < SIS_315H) {
2470 
2471  if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2472 
2473  tempah = (tempah << 5) & 0xFF;
2474  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2475  tempah = (tempah >> 5) & 0xFF;
2476 
2477  } else {
2478 
2479  if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x08;
2480  else if(!(SiS_IsDualEdge(SiS_Pr))) tempah |= 0x08;
2481  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF0,tempah);
2482  tempah &= ~0x08;
2483 
2484  }
2485 
2486  if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
2487  tempah |= 0x10;
2488  }
2489 
2490  tempah |= 0x80;
2491  if(SiS_Pr->SiS_VBType & VB_SIS301) {
2492  if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah &= ~0x80;
2493  }
2494 
2495  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2496  if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p))) {
2497  if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2498  tempah |= 0x20;
2499  }
2500  }
2501  }
2502 
2503  SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah);
2504 
2505  tempah = 0x80;
2506  if(SiS_Pr->SiS_VBType & VB_SIS301) {
2507  if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah = 0;
2508  }
2509 
2510  if(SiS_IsDualLink(SiS_Pr)) tempah |= 0x40;
2511 
2512  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2513  if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) {
2514  tempah |= 0x40;
2515  }
2516  }
2517 
2518  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0C,tempah);
2519 
2520  } else { /* LVDS */
2521 
2522  if(SiS_Pr->ChipType >= SIS_315H) {
2523 
2524 #ifdef CONFIG_FB_SIS_315
2525  /* LVDS can only be slave in 8bpp modes */
2526  tempah = 0x80;
2527  if((modeflag & CRT2Mode) && (SiS_Pr->SiS_ModeType > ModeVGA)) {
2528  if(SiS_Pr->SiS_VBInfo & DriverMode) {
2529  tempah |= 0x02;
2530  }
2531  }
2532 
2533  if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) tempah |= 0x02;
2534 
2535  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempah ^= 0x01;
2536 
2537  if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 1;
2538 
2539  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah);
2540 #endif
2541 
2542  } else {
2543 
2544 #ifdef CONFIG_FB_SIS_300
2545  tempah = 0;
2546  if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
2547  tempah |= 0x02;
2548  }
2549  tempah <<= 5;
2550 
2551  if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2552 
2553  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2554 #endif
2555 
2556  }
2557 
2558  }
2559 
2560  } /* LCDA */
2561 
2562  if(SiS_Pr->SiS_VBType & VB_SISVB) {
2563 
2564  if(SiS_Pr->ChipType >= SIS_315H) {
2565 
2566 #ifdef CONFIG_FB_SIS_315
2567  /* unsigned char bridgerev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01); */
2568 
2569  /* The following is nearly unpreditable and varies from machine
2570  * to machine. Especially the 301DH seems to be a real trouble
2571  * maker. Some BIOSes simply set the registers (like in the
2572  * NoLCD-if-statements here), some set them according to the
2573  * LCDA stuff. It is very likely that some machines are not
2574  * treated correctly in the following, very case-orientated
2575  * code. What do I do then...?
2576  */
2577 
2578  /* 740 variants match for 30xB, 301B-DH, 30xLV */
2579 
2580  if(!(IS_SIS740)) {
2581  tempah = 0x04; /* For all bridges */
2582  tempbl = 0xfb;
2583  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2584  tempah = 0x00;
2585  if(SiS_IsDualEdge(SiS_Pr)) {
2586  tempbl = 0xff;
2587  }
2588  }
2589  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2590  }
2591 
2592  /* The following two are responsible for eventually wrong colors
2593  * in TV output. The DH (VB_NoLCD) conditions are unknown; the
2594  * b0 was found in some 651 machine (Pim; P4_23=0xe5); the b1 version
2595  * in a 650 box (Jake). What is the criteria?
2596  * Addendum: Another combination 651+301B-DH(b1) (Rapo) needs same
2597  * treatment like the 651+301B-DH(b0) case. Seems more to be the
2598  * chipset than the bridge revision.
2599  */
2600 
2601  if((IS_SIS740) || (SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
2602  tempah = 0x30;
2603  tempbl = 0xc0;
2604  if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2605  ((SiS_Pr->SiS_ROMNew) && (!(ROMAddr[0x5b] & 0x04)))) {
2606  tempah = 0x00;
2607  tempbl = 0x00;
2608  }
2609  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,tempah);
2610  SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,tempbl);
2611  } else if(SiS_Pr->SiS_VBType & VB_SIS301) {
2612  /* Fixes "TV-blue-bug" on 315+301 */
2613  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xcf); /* For 301 */
2614  SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2615  } else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
2616  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30); /* For 30xLV */
2617  SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);
2618  } else if(SiS_Pr->SiS_VBType & VB_NoLCD) { /* For 301B-DH */
2619  tempah = 0x30; tempah2 = 0xc0;
2620  tempbl = 0xcf; tempbl2 = 0x3f;
2621  if(SiS_Pr->SiS_TVBlue == 0) {
2622  tempah = tempah2 = 0x00;
2623  } else if(SiS_Pr->SiS_TVBlue == -1) {
2624  /* Set on 651/M650, clear on 315/650 */
2625  if(!(IS_SIS65x)) /* (bridgerev != 0xb0) */ {
2626  tempah = tempah2 = 0x00;
2627  }
2628  }
2629  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2630  SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2631  } else {
2632  tempah = 0x30; tempah2 = 0xc0; /* For 30xB, 301C */
2633  tempbl = 0xcf; tempbl2 = 0x3f;
2634  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2635  tempah = tempah2 = 0x00;
2636  if(SiS_IsDualEdge(SiS_Pr)) {
2637  tempbl = tempbl2 = 0xff;
2638  }
2639  }
2640  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2641  SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2642  }
2643 
2644  if(IS_SIS740) {
2645  tempah = 0x80;
2646  if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x00;
2647  SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,0x7f,tempah);
2648  } else {
2649  tempah = 0x00;
2650  tempbl = 0x7f;
2651  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2652  tempbl = 0xff;
2653  if(!(SiS_IsDualEdge(SiS_Pr))) tempah = 0x80;
2654  }
2655  SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
2656  }
2657 
2658 #endif /* CONFIG_FB_SIS_315 */
2659 
2660  } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2661 
2662 #ifdef CONFIG_FB_SIS_300
2663  SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2664 
2665  if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2666  ((SiS_Pr->SiS_VBType & VB_NoLCD) &&
2667  (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD))) {
2668  SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x23,0x7F);
2669  } else {
2670  SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x23,0x80);
2671  }
2672 #endif
2673 
2674  }
2675 
2676  if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2677  SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x0D,0x80);
2678  if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
2679  SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3A,0xC0);
2680  }
2681  }
2682 
2683  } else { /* LVDS */
2684 
2685 #ifdef CONFIG_FB_SIS_315
2686  if(SiS_Pr->ChipType >= SIS_315H) {
2687 
2688  if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
2689 
2690  tempah = 0x04;
2691  tempbl = 0xfb;
2692  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2693  tempah = 0x00;
2694  if(SiS_IsDualEdge(SiS_Pr)) tempbl = 0xff;
2695  }
2696  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2697 
2698  if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
2699  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
2700  }
2701 
2702  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
2703 
2704  } else if(SiS_Pr->ChipType == SIS_550) {
2705 
2706  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
2707  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
2708 
2709  }
2710 
2711  }
2712 #endif
2713 
2714  }
2715 
2716 }
2717 
2718 /*********************************************/
2719 /* GET RESOLUTION DATA */
2720 /*********************************************/
2721 
2722 unsigned short
2723 SiS_GetResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2724 {
2725  if(ModeNo <= 0x13)
2726  return ((unsigned short)SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo);
2727  else
2728  return ((unsigned short)SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO);
2729 }
2730 
2731 static void
2732 SiS_GetCRT2ResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2733 {
2734  unsigned short xres, yres, modeflag=0, resindex;
2735 
2736  if(SiS_Pr->UseCustomMode) {
2737  xres = SiS_Pr->CHDisplay;
2738  if(SiS_Pr->CModeFlag & HalfDCLK) xres <<= 1;
2739  SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
2740  /* DoubleScanMode-check done in CheckCalcCustomMode()! */
2741  SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = SiS_Pr->CVDisplay;
2742  return;
2743  }
2744 
2745  resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex);
2746 
2747  if(ModeNo <= 0x13) {
2748  xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
2749  yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
2750  } else {
2751  xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
2752  yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
2753  modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2754  }
2755 
2756  if(!SiS_Pr->SiS_IF_DEF_DSTN && !SiS_Pr->SiS_IF_DEF_FSTN) {
2757 
2758  if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
2759  if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
2760  if(yres == 350) yres = 400;
2761  }
2762  if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
2763  if(ModeNo == 0x12) yres = 400;
2764  }
2765  }
2766 
2767  if(modeflag & HalfDCLK) xres <<= 1;
2768  if(modeflag & DoubleScanMode) yres <<= 1;
2769 
2770  }
2771 
2772  if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
2773 
2774  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2775  switch(SiS_Pr->SiS_LCDResInfo) {
2776  case Panel_1024x768:
2777  if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
2778  if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2779  if(yres == 350) yres = 357;
2780  if(yres == 400) yres = 420;
2781  if(yres == 480) yres = 525;
2782  }
2783  }
2784  break;
2785  case Panel_1280x1024:
2786  if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2787  /* BIOS bug - does this regardless of scaling */
2788  if(yres == 400) yres = 405;
2789  }
2790  if(yres == 350) yres = 360;
2791  if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
2792  if(yres == 360) yres = 375;
2793  }
2794  break;
2795  case Panel_1600x1200:
2796  if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
2797  if(yres == 1024) yres = 1056;
2798  }
2799  break;
2800  }
2801  }
2802 
2803  } else {
2804 
2805  if(SiS_Pr->SiS_VBType & VB_SISVB) {
2806  if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVision)) {
2807  if(xres == 720) xres = 640;
2808  }
2809  } else if(xres == 720) xres = 640;
2810 
2811  if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
2812  yres = 400;
2813  if(SiS_Pr->ChipType >= SIS_315H) {
2814  if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
2815  } else {
2816  if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
2817  }
2818  if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) yres = 480;
2819  }
2820 
2821  }
2822  SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
2823  SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
2824 }
2825 
2826 /*********************************************/
2827 /* GET CRT2 TIMING DATA */
2828 /*********************************************/
2829 
2830 static void
2831 SiS_GetCRT2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
2832  unsigned short RefreshRateTableIndex, unsigned short *CRT2Index,
2833  unsigned short *ResIndex)
2834 {
2835  unsigned short tempbx=0, tempal=0, resinfo=0;
2836 
2837  if(ModeNo <= 0x13) {
2838  tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2839  } else {
2840  tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2841  resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2842  }
2843 
2844  if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_IF_DEF_LVDS == 0)) {
2845 
2846  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { /* LCD */
2847 
2848  tempbx = SiS_Pr->SiS_LCDResInfo;
2849  if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 32;
2850 
2851  /* patch index */
2852  if(SiS_Pr->SiS_LCDResInfo == Panel_1680x1050) {
2853  if (resinfo == SIS_RI_1280x800) tempal = 9;
2854  else if(resinfo == SIS_RI_1400x1050) tempal = 11;
2855  } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x800) ||
2856  (SiS_Pr->SiS_LCDResInfo == Panel_1280x800_2) ||
2857  (SiS_Pr->SiS_LCDResInfo == Panel_1280x854)) {
2858  if (resinfo == SIS_RI_1280x768) tempal = 9;
2859  }
2860 
2861  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
2862  /* Pass 1:1 only (center-screen handled outside) */
2863  /* This is never called for the panel's native resolution */
2864  /* since Pass1:1 will not be set in this case */
2865  tempbx = 100;
2866  if(ModeNo >= 0x13) {
2867  tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
2868  }
2869  }
2870 
2871 #ifdef CONFIG_FB_SIS_315
2872  if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
2873  if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
2874  if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2875  tempbx = 200;
2876  if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
2877  }
2878  }
2879  }
2880 #endif
2881 
2882  } else { /* TV */
2883 
2884  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
2885  /* if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_TVMode &= (~TVSetTVSimuMode); */
2886  tempbx = 2;
2887  if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2888  tempbx = 13;
2889  if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) tempbx = 14;
2890  }
2891  } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2892  if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempbx = 7;
2893  else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempbx = 6;
2894  else tempbx = 5;
2895  if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5;
2896  } else {
2897  if(SiS_Pr->SiS_TVMode & TVSetPAL) tempbx = 3;
2898  else tempbx = 4;
2899  if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5;
2900  }
2901 
2902  }
2903 
2904  tempal &= 0x3F;
2905 
2906  if(ModeNo > 0x13) {
2907  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) {
2908  switch(resinfo) {
2909  case SIS_RI_720x480:
2910  tempal = 6;
2911  if(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetPALN)) tempal = 9;
2912  break;
2913  case SIS_RI_720x576:
2914  case SIS_RI_768x576:
2915  case SIS_RI_1024x576: /* Not in NTSC or YPBPR mode (except 1080i)! */
2916  tempal = 6;
2917  if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2918  if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempal = 8;
2919  }
2920  break;
2921  case SIS_RI_800x480:
2922  tempal = 4;
2923  break;
2924  case SIS_RI_512x384:
2925  case SIS_RI_1024x768:
2926  tempal = 7;
2927  if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2928  if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempal = 8;
2929  }
2930  break;
2931  case SIS_RI_1280x720:
2932  if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2933  if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempal = 9;
2934  }
2935  break;
2936  }
2937  }
2938  }
2939 
2940  *CRT2Index = tempbx;
2941  *ResIndex = tempal;
2942 
2943  } else { /* LVDS, 301B-DH (if running on LCD) */
2944 
2945  tempbx = 0;
2946  if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
2947 
2948  tempbx = 90;
2949  if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2950  tempbx = 92;
2951  if(SiS_Pr->SiS_ModeType > ModeVGA) {
2952  if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
2953  }
2954  if(SiS_Pr->SiS_TVMode & TVSetPALM) tempbx = 94;
2955  else if(SiS_Pr->SiS_TVMode & TVSetPALN) tempbx = 96;
2956  }
2957  if(tempbx != 99) {
2958  if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx++;
2959  }
2960 
2961  } else {
2962 
2963  switch(SiS_Pr->SiS_LCDResInfo) {
2964  case Panel_640x480: tempbx = 12; break;
2965  case Panel_320x240_1: tempbx = 10; break;
2966  case Panel_320x240_2:
2967  case Panel_320x240_3: tempbx = 14; break;
2968  case Panel_800x600: tempbx = 16; break;
2969  case Panel_1024x600: tempbx = 18; break;
2970  case Panel_1152x768:
2971  case Panel_1024x768: tempbx = 20; break;
2972  case Panel_1280x768: tempbx = 22; break;
2973  case Panel_1280x1024: tempbx = 24; break;
2974  case Panel_1400x1050: tempbx = 26; break;
2975  case Panel_1600x1200: tempbx = 28; break;
2976 #ifdef CONFIG_FB_SIS_300
2977  case Panel_Barco1366: tempbx = 80; break;
2978 #endif
2979  }
2980 
2981  switch(SiS_Pr->SiS_LCDResInfo) {
2982  case Panel_320x240_1:
2983  case Panel_320x240_2:
2984  case Panel_320x240_3:
2985  case Panel_640x480:
2986  break;
2987  default:
2988  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
2989  }
2990 
2991  if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempbx = 30;
2992 
2993 #ifdef CONFIG_FB_SIS_300
2994  if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
2995  tempbx = 82;
2996  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
2997  } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
2998  tempbx = 84;
2999  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3000  }
3001 #endif
3002 
3003  }
3004 
3005  (*CRT2Index) = tempbx;
3006  (*ResIndex) = tempal & 0x1F;
3007  }
3008 }
3009 
3010 static void
3011 SiS_GetRAMDAC2DATA(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3012  unsigned short RefreshRateTableIndex)
3013 {
3014  unsigned short tempax=0, tempbx=0, index, dotclock;
3015  unsigned short temp1=0, modeflag=0, tempcx=0;
3016 
3017  SiS_Pr->SiS_RVBHCMAX = 1;
3018  SiS_Pr->SiS_RVBHCFACT = 1;
3019 
3020  if(ModeNo <= 0x13) {
3021 
3022  modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3023  index = SiS_GetModePtr(SiS_Pr,ModeNo,ModeIdIndex);
3024 
3025  tempax = SiS_Pr->SiS_StandTable[index].CRTC[0];
3026  tempbx = SiS_Pr->SiS_StandTable[index].CRTC[6];
3027  temp1 = SiS_Pr->SiS_StandTable[index].CRTC[7];
3028 
3029  dotclock = (modeflag & Charx8Dot) ? 8 : 9;
3030 
3031  } else {
3032 
3033  modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3034  index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);
3035 
3036  tempax = SiS_Pr->SiS_CRT1Table[index].CR[0];
3037  tempax |= (SiS_Pr->SiS_CRT1Table[index].CR[14] << 8);
3038  tempax &= 0x03FF;
3039  tempbx = SiS_Pr->SiS_CRT1Table[index].CR[6];
3040  tempcx = SiS_Pr->SiS_CRT1Table[index].CR[13] << 8;
3041  tempcx &= 0x0100;
3042  tempcx <<= 2;
3043  tempbx |= tempcx;
3044  temp1 = SiS_Pr->SiS_CRT1Table[index].CR[7];
3045 
3046  dotclock = 8;
3047 
3048  }
3049 
3050  if(temp1 & 0x01) tempbx |= 0x0100;
3051  if(temp1 & 0x20) tempbx |= 0x0200;
3052 
3053  tempax += 5;
3054  tempax *= dotclock;
3055  if(modeflag & HalfDCLK) tempax <<= 1;
3056 
3057  tempbx++;
3058 
3059  SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3060  SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = tempbx;
3061 }
3062 
3063 static void
3064 SiS_CalcPanelLinkTiming(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
3065  unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex)
3066 {
3067  unsigned short ResIndex;
3068 
3069  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3070  if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
3071  if(SiS_Pr->UseCustomMode) {
3072  ResIndex = SiS_Pr->CHTotal;
3073  if(SiS_Pr->CModeFlag & HalfDCLK) ResIndex <<= 1;
3074  SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = ResIndex;
3075  SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3076  } else {
3077  if(ModeNo < 0x13) {
3078  ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3079  } else {
3080  ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
3081  }
3082  if(ResIndex == 0x09) {
3083  if(SiS_Pr->Alternate1600x1200) ResIndex = 0x20; /* 1600x1200 LCDA */
3084  else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) ResIndex = 0x21; /* 1600x1200 LVDS */
3085  }
3086  SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAHT;
3087  SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAVT;
3088  SiS_Pr->SiS_HT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDHT;
3089  SiS_Pr->SiS_VT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDVT;
3090  }
3091  } else {
3092  SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3093  SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3094  }
3095  } else {
3096  /* This handles custom modes and custom panels */
3097  SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3098  SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3099  SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3100  SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3101  SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT - (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE);
3102  SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT - (SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE);
3103  }
3104 }
3105 
3106 static void
3107 SiS_GetCRT2DataLVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3108  unsigned short RefreshRateTableIndex)
3109 {
3110  unsigned short CRT2Index, ResIndex, backup;
3111  const struct SiS_LVDSData *LVDSData = NULL;
3112 
3113  SiS_GetCRT2ResInfo(SiS_Pr, ModeNo, ModeIdIndex);
3114 
3115  if(SiS_Pr->SiS_VBType & VB_SISVB) {
3116  SiS_Pr->SiS_RVBHCMAX = 1;
3117  SiS_Pr->SiS_RVBHCFACT = 1;
3118  SiS_Pr->SiS_NewFlickerMode = 0;
3119  SiS_Pr->SiS_RVBHRS = 50;
3120  SiS_Pr->SiS_RY1COE = 0;
3121  SiS_Pr->SiS_RY2COE = 0;
3122  SiS_Pr->SiS_RY3COE = 0;
3123  SiS_Pr->SiS_RY4COE = 0;
3124  SiS_Pr->SiS_RVBHRS2 = 0;
3125  }
3126 
3127  if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3128 
3129 #ifdef CONFIG_FB_SIS_315
3130  SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3131  SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
3132 #endif
3133 
3134  } else {
3135 
3136  /* 301BDH needs LVDS Data */
3137  backup = SiS_Pr->SiS_IF_DEF_LVDS;
3138  if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3139  SiS_Pr->SiS_IF_DEF_LVDS = 1;
3140  }
3141 
3142  SiS_GetCRT2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
3143  &CRT2Index, &ResIndex);
3144 
3145  SiS_Pr->SiS_IF_DEF_LVDS = backup;
3146 
3147  switch(CRT2Index) {
3148  case 10: LVDSData = SiS_Pr->SiS_LVDS320x240Data_1; break;
3149  case 14: LVDSData = SiS_Pr->SiS_LVDS320x240Data_2; break;
3150  case 12: LVDSData = SiS_Pr->SiS_LVDS640x480Data_1; break;
3151  case 16: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1; break;
3152  case 18: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1; break;
3153  case 20: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break;
3154 #ifdef CONFIG_FB_SIS_300
3155  case 80: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1; break;
3156  case 81: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2; break;
3157  case 82: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1; break;
3158  case 84: LVDSData = SiS_Pr->SiS_LVDS848x480Data_1; break;
3159  case 85: LVDSData = SiS_Pr->SiS_LVDS848x480Data_2; break;
3160 #endif
3161  case 90: LVDSData = SiS_Pr->SiS_CHTVUNTSCData; break;
3162  case 91: LVDSData = SiS_Pr->SiS_CHTVONTSCData; break;
3163  case 92: LVDSData = SiS_Pr->SiS_CHTVUPALData; break;
3164  case 93: LVDSData = SiS_Pr->SiS_CHTVOPALData; break;
3165  case 94: LVDSData = SiS_Pr->SiS_CHTVUPALMData; break;
3166  case 95: LVDSData = SiS_Pr->SiS_CHTVOPALMData; break;
3167  case 96: LVDSData = SiS_Pr->SiS_CHTVUPALNData; break;
3168  case 97: LVDSData = SiS_Pr->SiS_CHTVOPALNData; break;
3169  case 99: LVDSData = SiS_Pr->SiS_CHTVSOPALData; break;
3170  }
3171 
3172  if(LVDSData) {
3173  SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT;
3174  SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT;
3175  SiS_Pr->SiS_HT = (LVDSData+ResIndex)->LCDHT;
3176  SiS_Pr->SiS_VT = (LVDSData+ResIndex)->LCDVT;
3177  } else {
3178  SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3179  }
3180 
3181  if( (!(SiS_Pr->SiS_VBType & VB_SISVB)) &&
3182  (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
3183  (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) ) {
3184  if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ||
3185  (SiS_Pr->SiS_SetFlag & SetDOSMode) ) {
3186  SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3187  SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3188 #ifdef CONFIG_FB_SIS_300
3189  if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3190  if(ResIndex < 0x08) {
3191  SiS_Pr->SiS_HDE = 1280;
3192  SiS_Pr->SiS_VDE = 1024;
3193  }
3194  }
3195 #endif
3196  }
3197  }
3198  }
3199 }
3200 
3201 static void
3202 SiS_GetCRT2Data301(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3203  unsigned short RefreshRateTableIndex)
3204 {
3205  unsigned char *ROMAddr = NULL;
3206  unsigned short tempax, tempbx, modeflag, romptr=0;
3207  unsigned short resinfo, CRT2Index, ResIndex;
3208  const struct SiS_LCDData *LCDPtr = NULL;
3209  const struct SiS_TVData *TVPtr = NULL;
3210 #ifdef CONFIG_FB_SIS_315
3211  short resinfo661;
3212 #endif
3213 
3214  if(ModeNo <= 0x13) {
3215  modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3216  resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
3217  } else if(SiS_Pr->UseCustomMode) {
3218  modeflag = SiS_Pr->CModeFlag;
3219  resinfo = 0;
3220  } else {
3221  modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3222  resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
3223 #ifdef CONFIG_FB_SIS_315
3224  resinfo661 = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].ROMMODEIDX661;
3225  if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
3226  (SiS_Pr->SiS_SetFlag & LCDVESATiming) &&
3227  (resinfo661 >= 0) &&
3228  (SiS_Pr->SiS_NeedRomModeData) ) {
3229  if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
3230  if((romptr = (SISGETROMW(21)))) {
3231  romptr += (resinfo661 * 10);
3232  ROMAddr = SiS_Pr->VirtualRomBase;
3233  }
3234  }
3235  }
3236 #endif
3237  }
3238 
3239  SiS_Pr->SiS_NewFlickerMode = 0;
3240  SiS_Pr->SiS_RVBHRS = 50;
3241  SiS_Pr->SiS_RY1COE = 0;
3242  SiS_Pr->SiS_RY2COE = 0;
3243  SiS_Pr->SiS_RY3COE = 0;
3244  SiS_Pr->SiS_RY4COE = 0;
3245  SiS_Pr->SiS_RVBHRS2 = 0;
3246 
3247  SiS_GetCRT2ResInfo(SiS_Pr,ModeNo,ModeIdIndex);
3248 
3249  if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
3250 
3251  if(SiS_Pr->UseCustomMode) {
3252 
3253  SiS_Pr->SiS_RVBHCMAX = 1;
3254  SiS_Pr->SiS_RVBHCFACT = 1;
3255  SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE;
3256  SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE;
3257 
3258  tempax = SiS_Pr->CHTotal;
3259  if(modeflag & HalfDCLK) tempax <<= 1;
3260  SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3261  SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3262 
3263  } else {
3264 
3265  SiS_GetRAMDAC2DATA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3266 
3267  }
3268 
3269  } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
3270 
3271  SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3272  &CRT2Index,&ResIndex);
3273 
3274  switch(CRT2Index) {
3275  case 2: TVPtr = SiS_Pr->SiS_ExtHiTVData; break;
3276  case 3: TVPtr = SiS_Pr->SiS_ExtPALData; break;
3277  case 4: TVPtr = SiS_Pr->SiS_ExtNTSCData; break;
3278  case 5: TVPtr = SiS_Pr->SiS_Ext525iData; break;
3279  case 6: TVPtr = SiS_Pr->SiS_Ext525pData; break;
3280  case 7: TVPtr = SiS_Pr->SiS_Ext750pData; break;
3281  case 8: TVPtr = SiS_Pr->SiS_StPALData; break;
3282  case 9: TVPtr = SiS_Pr->SiS_StNTSCData; break;
3283  case 10: TVPtr = SiS_Pr->SiS_St525iData; break;
3284  case 11: TVPtr = SiS_Pr->SiS_St525pData; break;
3285  case 12: TVPtr = SiS_Pr->SiS_St750pData; break;
3286  case 13: TVPtr = SiS_Pr->SiS_St1HiTVData; break;
3287  case 14: TVPtr = SiS_Pr->SiS_St2HiTVData; break;
3288  default: TVPtr = SiS_Pr->SiS_StPALData; break;
3289  }
3290 
3291  SiS_Pr->SiS_RVBHCMAX = (TVPtr+ResIndex)->RVBHCMAX;
3292  SiS_Pr->SiS_RVBHCFACT = (TVPtr+ResIndex)->RVBHCFACT;
3293  SiS_Pr->SiS_VGAHT = (TVPtr+ResIndex)->VGAHT;
3294  SiS_Pr->SiS_VGAVT = (TVPtr+ResIndex)->VGAVT;
3295  SiS_Pr->SiS_HDE = (TVPtr+ResIndex)->TVHDE;
3296  SiS_Pr->SiS_VDE = (TVPtr+ResIndex)->TVVDE;
3297  SiS_Pr->SiS_RVBHRS2 = (TVPtr+ResIndex)->RVBHRS2 & 0x0fff;
3298  if(modeflag & HalfDCLK) {
3299  SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->HALFRVBHRS;
3300  if(SiS_Pr->SiS_RVBHRS2) {
3301  SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
3302  tempax = ((TVPtr+ResIndex)->RVBHRS2 >> 12) & 0x07;
3303  if((TVPtr+ResIndex)->RVBHRS2 & 0x8000) SiS_Pr->SiS_RVBHRS2 -= tempax;
3304  else SiS_Pr->SiS_RVBHRS2 += tempax;
3305  }
3306  } else {
3307  SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->RVBHRS;
3308  }
3309  SiS_Pr->SiS_NewFlickerMode = ((TVPtr+ResIndex)->FlickerMode) << 7;
3310 
3311  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
3312 
3313  if((resinfo == SIS_RI_960x600) ||
3314  (resinfo == SIS_RI_1024x768) ||
3315  (resinfo == SIS_RI_1280x1024) ||
3316  (resinfo == SIS_RI_1280x720)) {
3317  SiS_Pr->SiS_NewFlickerMode = 0x40;
3318  }
3319 
3320  if(SiS_Pr->SiS_VGAVDE == 350) SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
3321 
3322  SiS_Pr->SiS_HT = ExtHiTVHT;
3323  SiS_Pr->SiS_VT = ExtHiTVVT;
3324  if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
3325  if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
3326  SiS_Pr->SiS_HT = StHiTVHT;
3327  SiS_Pr->SiS_VT = StHiTVVT;
3328  }
3329  }
3330 
3331  } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3332 
3333  if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
3334  SiS_Pr->SiS_HT = 1650;
3335  SiS_Pr->SiS_VT = 750;
3336  } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
3337  SiS_Pr->SiS_HT = NTSCHT;
3338  if(SiS_Pr->SiS_TVMode & TVSet525p1024) SiS_Pr->SiS_HT = NTSC2HT;
3339  SiS_Pr->SiS_VT = NTSCVT;
3340  } else {
3341  SiS_Pr->SiS_HT = NTSCHT;
3342  if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3343  SiS_Pr->SiS_VT = NTSCVT;
3344  }
3345 
3346  } else {
3347 
3348  SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
3349  SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
3350  SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
3351  SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
3352 
3353  if(modeflag & HalfDCLK) {
3354  SiS_Pr->SiS_RY1COE = 0x00;
3355  SiS_Pr->SiS_RY2COE = 0xf4;
3356  SiS_Pr->SiS_RY3COE = 0x10;
3357  SiS_Pr->SiS_RY4COE = 0x38;
3358  }
3359 
3360  if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
3361  SiS_Pr->SiS_HT = NTSCHT;
3362  if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3363  SiS_Pr->SiS_VT = NTSCVT;
3364  } else {
3365  SiS_Pr->SiS_HT = PALHT;
3366  SiS_Pr->SiS_VT = PALVT;
3367  }
3368 
3369  }
3370 
3371  } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3372 
3373  SiS_Pr->SiS_RVBHCMAX = 1;
3374  SiS_Pr->SiS_RVBHCFACT = 1;
3375 
3376  if(SiS_Pr->UseCustomMode) {
3377 
3378  SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE;
3379  SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE;
3380 
3381  tempax = SiS_Pr->CHTotal;
3382  if(modeflag & HalfDCLK) tempax <<= 1;
3383  SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3384  SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3385 
3386  } else {
3387 
3388  bool gotit = false;
3389 
3390  if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
3391 
3392  SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
3393  SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
3394  SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3395  SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3396  gotit = true;
3397 
3398  } else if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) && (romptr) && (ROMAddr) ) {
3399 
3400 #ifdef CONFIG_FB_SIS_315
3401  SiS_Pr->SiS_RVBHCMAX = ROMAddr[romptr];
3402  SiS_Pr->SiS_RVBHCFACT = ROMAddr[romptr+1];
3403  SiS_Pr->SiS_VGAHT = ROMAddr[romptr+2] | ((ROMAddr[romptr+3] & 0x0f) << 8);
3404  SiS_Pr->SiS_VGAVT = (ROMAddr[romptr+4] << 4) | ((ROMAddr[romptr+3] & 0xf0) >> 4);
3405  SiS_Pr->SiS_HT = ROMAddr[romptr+5] | ((ROMAddr[romptr+6] & 0x0f) << 8);
3406  SiS_Pr->SiS_VT = (ROMAddr[romptr+7] << 4) | ((ROMAddr[romptr+6] & 0xf0) >> 4);
3407  SiS_Pr->SiS_RVBHRS2 = ROMAddr[romptr+8] | ((ROMAddr[romptr+9] & 0x0f) << 8);
3408  if((SiS_Pr->SiS_RVBHRS2) && (modeflag & HalfDCLK)) {
3409  SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
3410  tempax = (ROMAddr[romptr+9] >> 4) & 0x07;
3411  if(ROMAddr[romptr+9] & 0x80) SiS_Pr->SiS_RVBHRS2 -= tempax;
3412  else SiS_Pr->SiS_RVBHRS2 += tempax;
3413  }
3414  if(SiS_Pr->SiS_VGAHT) gotit = true;
3415  else {
3416  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
3417  SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
3418  SiS_Pr->SiS_RVBHCMAX = 1;
3419  SiS_Pr->SiS_RVBHCFACT = 1;
3420  SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
3421  SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
3422  SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3423  SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3424  SiS_Pr->SiS_RVBHRS2 = 0;
3425  gotit = true;
3426  }
3427 #endif
3428 
3429  }
3430 
3431  if(!gotit) {
3432 
3433  SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3434  &CRT2Index,&ResIndex);
3435 
3436  switch(CRT2Index) {
3437  case Panel_1024x768 : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break;
3438  case Panel_1024x768 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data; break;
3439  case Panel_1280x720 :
3440  case Panel_1280x720 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x720Data; break;
3441  case Panel_1280x768_2 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x768_2Data; break;
3442  case Panel_1280x768_2+ 32: LCDPtr = SiS_Pr->SiS_StLCD1280x768_2Data; break;
3443  case Panel_1280x800 :
3444  case Panel_1280x800 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x800Data; break;
3445  case Panel_1280x800_2 :
3446  case Panel_1280x800_2+ 32: LCDPtr = SiS_Pr->SiS_LCD1280x800_2Data; break;
3447  case Panel_1280x854 :
3448  case Panel_1280x854 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x854Data; break;
3449  case Panel_1280x960 :
3450  case Panel_1280x960 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x960Data; break;
3451  case Panel_1280x1024 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data; break;
3452  case Panel_1280x1024 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
3453  case Panel_1400x1050 : LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data; break;
3454  case Panel_1400x1050 + 32: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data; break;
3455  case Panel_1600x1200 : LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data; break;
3456  case Panel_1600x1200 + 32: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data; break;
3457  case Panel_1680x1050 :
3458  case Panel_1680x1050 + 32: LCDPtr = SiS_Pr->SiS_LCD1680x1050Data; break;
3459  case 100 : LCDPtr = SiS_Pr->SiS_NoScaleData; break;
3460 #ifdef CONFIG_FB_SIS_315
3461  case 200 : LCDPtr = SiS310_ExtCompaq1280x1024Data; break;
3462  case 201 : LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
3463 #endif
3464  default : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break;
3465  }
3466 
3467  SiS_Pr->SiS_RVBHCMAX = (LCDPtr+ResIndex)->RVBHCMAX;
3468  SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
3469  SiS_Pr->SiS_VGAHT = (LCDPtr+ResIndex)->VGAHT;
3470  SiS_Pr->SiS_VGAVT = (LCDPtr+ResIndex)->VGAVT;
3471  SiS_Pr->SiS_HT = (LCDPtr+ResIndex)->LCDHT;
3472  SiS_Pr->SiS_VT = (LCDPtr+ResIndex)->LCDVT;
3473 
3474  }
3475 
3476  tempax = SiS_Pr->PanelXRes;
3477  tempbx = SiS_Pr->PanelYRes;
3478 
3479  switch(SiS_Pr->SiS_LCDResInfo) {
3480  case Panel_1024x768:
3481  if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
3482  if(SiS_Pr->ChipType < SIS_315H) {
3483  if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3484  else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3485  }
3486  } else {
3487  if (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
3488  else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
3489  else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
3490  else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
3491  else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3492  else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3493  }
3494  break;
3495  case Panel_1280x960:
3496  if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 700;
3497  else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 800;
3498  else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
3499  break;
3500  case Panel_1280x1024:
3501  if (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
3502  else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
3503  else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
3504  break;
3505  case Panel_1600x1200:
3506  if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
3507  if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 875;
3508  else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 1000;
3509  }
3510  break;
3511  }
3512 
3513  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3514  tempax = SiS_Pr->SiS_VGAHDE;
3515  tempbx = SiS_Pr->SiS_VGAVDE;
3516  }
3517 
3518  SiS_Pr->SiS_HDE = tempax;
3519  SiS_Pr->SiS_VDE = tempbx;
3520  }
3521  }
3522 }
3523 
3524 static void
3525 SiS_GetCRT2Data(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3526  unsigned short RefreshRateTableIndex)
3527 {
3528 
3529  if(SiS_Pr->SiS_VBType & VB_SISVB) {
3530 
3531  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
3532  SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3533  } else {
3534  if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3535  /* Need LVDS Data for LCD on 301B-DH */
3536  SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3537  } else {
3538  SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3539  }
3540  }
3541 
3542  } else {
3543 
3544  SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3545 
3546  }
3547 }
3548 
3549 /*********************************************/
3550 /* GET LVDS DES (SKEW) DATA */
3551 /*********************************************/
3552 
3553 static const struct SiS_LVDSDes *
3554 SiS_GetLVDSDesPtr(struct SiS_Private *SiS_Pr)
3555 {
3556  const struct SiS_LVDSDes *PanelDesPtr = NULL;
3557 
3558 #ifdef CONFIG_FB_SIS_300
3559  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3560 
3561  if(SiS_Pr->ChipType < SIS_315H) {
3562  if(SiS_Pr->SiS_LCDTypeInfo == 4) {
3563  if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3564  PanelDesPtr = SiS_Pr->SiS_PanelType04_1a;
3565  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3566  PanelDesPtr = SiS_Pr->SiS_PanelType04_2a;
3567  }
3568  } else if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
3569  PanelDesPtr = SiS_Pr->SiS_PanelType04_1b;
3570  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3571  PanelDesPtr = SiS_Pr->SiS_PanelType04_2b;
3572  }
3573  }
3574  }
3575  }
3576  }
3577 #endif
3578  return PanelDesPtr;
3579 }
3580 
3581 static void
3582 SiS_GetLVDSDesData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3583  unsigned short RefreshRateTableIndex)
3584 {
3585  unsigned short modeflag, ResIndex;
3586  const struct SiS_LVDSDes *PanelDesPtr = NULL;
3587 
3588  SiS_Pr->SiS_LCDHDES = 0;
3589  SiS_Pr->SiS_LCDVDES = 0;
3590 
3591  /* Some special cases */
3592  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3593 
3594  /* Trumpion */
3595  if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
3596  if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3597  if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3598  SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3599  }
3600  }
3601  return;
3602  }
3603 
3604  /* 640x480 on LVDS */
3605  if(SiS_Pr->ChipType < SIS_315H) {
3606  if(SiS_Pr->SiS_LCDResInfo == Panel_640x480 && SiS_Pr->SiS_LCDTypeInfo == 3) {
3607  SiS_Pr->SiS_LCDHDES = 8;
3608  if (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
3609  else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
3610  else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
3611  return;
3612  }
3613  }
3614 
3615  } /* LCD */
3616 
3617  if( (SiS_Pr->UseCustomMode) ||
3618  (SiS_Pr->SiS_LCDResInfo == Panel_Custom) ||
3619  (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
3620  (SiS_Pr->SiS_CustomT == CUT_PANEL856) ||
3621  (SiS_Pr->SiS_LCDInfo & LCDPass11) ) {
3622  return;
3623  }
3624 
3625  if(ModeNo <= 0x13) ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3626  else ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
3627 
3628  if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3629 
3630 #ifdef CONFIG_FB_SIS_315
3631  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3632  /* non-pass 1:1 only, see above */
3633  if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
3634  SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
3635  }
3636  if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
3637  SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
3638  }
3639  }
3640  if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3641  switch(SiS_Pr->SiS_CustomT) {
3642  case CUT_UNIWILL1024:
3643  case CUT_UNIWILL10242:
3644  case CUT_CLEVO1400:
3645  if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3646  SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3647  }
3648  break;
3649  }
3650  switch(SiS_Pr->SiS_LCDResInfo) {
3651  case Panel_1280x1024:
3652  if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
3653  SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3654  }
3655  break;
3656  case Panel_1280x800: /* Verified for Averatec 6240 */
3657  case Panel_1280x800_2: /* Verified for Asus A4L */
3658  case Panel_1280x854: /* Not verified yet FIXME */
3659  SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3660  break;
3661  }
3662  }
3663 #endif
3664 
3665  } else {
3666 
3667  if((SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
3668 
3669  if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
3670  if(ResIndex <= 3) SiS_Pr->SiS_LCDHDES = 256;
3671  }
3672 
3673  } else if((PanelDesPtr = SiS_GetLVDSDesPtr(SiS_Pr))) {
3674 
3675  SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
3676  SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;
3677 
3678  } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3679 
3680  if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
3681  SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
3682  }
3683  if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
3684  SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
3685  } else {
3686  if(SiS_Pr->ChipType < SIS_315H) {
3687  SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3688  } else {
3689  switch(SiS_Pr->SiS_LCDResInfo) {
3690  case Panel_800x600:
3691  case Panel_1024x768:
3692  case Panel_1280x1024:
3693  SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
3694  break;
3695  case Panel_1400x1050:
3696  SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3697  break;
3698  }
3699  }
3700  }
3701 
3702  } else {
3703 
3704  if(SiS_Pr->ChipType < SIS_315H) {
3705 #ifdef CONFIG_FB_SIS_300
3706  switch(SiS_Pr->SiS_LCDResInfo) {
3707  case Panel_800x600:
3708  if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3709  SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3710  } else {
3711  SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT + 3;
3712  SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
3713  if(SiS_Pr->SiS_VGAVDE == 400) SiS_Pr->SiS_LCDVDES -= 2;
3714  else SiS_Pr->SiS_LCDVDES -= 4;
3715  }
3716  break;
3717  case Panel_1024x768:
3718  if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3719  SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3720  } else {
3721  SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
3722  if(SiS_Pr->SiS_VGAVDE <= 400) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 8;
3723  if(SiS_Pr->SiS_VGAVDE <= 350) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 12;
3724  }
3725  break;
3726  case Panel_1024x600:
3727  default:
3728  if( (SiS_Pr->SiS_VGAHDE == SiS_Pr->PanelXRes) &&
3729  (SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) ) {
3730  SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3731  } else {
3732  SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
3733  }
3734  break;
3735  }
3736 
3737  switch(SiS_Pr->SiS_LCDTypeInfo) {
3738  case 1:
3739  SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
3740  break;
3741  case 3: /* 640x480 only? */
3742  SiS_Pr->SiS_LCDHDES = 8;
3743  if (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
3744  else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
3745  else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
3746  break;
3747  }
3748 #endif
3749  } else {
3750 #ifdef CONFIG_FB_SIS_315
3751  switch(SiS_Pr->SiS_LCDResInfo) {
3752  case Panel_1024x768:
3753  case Panel_1280x1024:
3754  if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3755  SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3756  }
3757  break;
3758  case Panel_320x240_1:
3759  case Panel_320x240_2:
3760  case Panel_320x240_3:
3761  SiS_Pr->SiS_LCDVDES = 524;
3762  break;
3763  }
3764 #endif
3765  }
3766  }
3767 
3768  if((ModeNo <= 0x13) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
3769  modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3770  if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3771  if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 632;
3772  } else if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) {
3773  if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
3774  if(SiS_Pr->SiS_LCDResInfo >= Panel_1024x768) {
3775  if(SiS_Pr->ChipType < SIS_315H) {
3776  if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320;
3777  } else {
3778 #ifdef CONFIG_FB_SIS_315
3779  if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) SiS_Pr->SiS_LCDHDES = 480;
3780  if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 804;
3781  if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 704;
3782  if(!(modeflag & HalfDCLK)) {
3783  SiS_Pr->SiS_LCDHDES = 320;
3784  if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 632;
3785  if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 542;
3786  }
3787 #endif
3788  }
3789  }
3790  }
3791  }
3792  }
3793  }
3794 }
3795 
3796 /*********************************************/
3797 /* DISABLE VIDEO BRIDGE */
3798 /*********************************************/
3799 
3800 #ifdef CONFIG_FB_SIS_315
3801 static int
3802 SiS_HandlePWD(struct SiS_Private *SiS_Pr)
3803 {
3804  int ret = 0;
3805 #ifdef SET_PWD
3806  unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
3807  unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
3808  unsigned char drivermode = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40;
3809  unsigned short temp;
3810 
3811  if( (SiS_Pr->SiS_VBType & VB_SISPWD) &&
3812  (romptr) &&
3813  (SiS_Pr->SiS_PWDOffset) ) {
3814  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2b,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 0]);
3815  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2c,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 1]);
3816  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2d,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 2]);
3817  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2e,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 3]);
3818  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2f,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 4]);
3819  temp = 0x00;
3820  if((ROMAddr[romptr + 2] & (0x06 << 1)) && !drivermode) {
3821  temp = 0x80;
3822  ret = 1;
3823  }
3824  SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x27,0x7f,temp);
3825  }
3826 #endif
3827  return ret;
3828 }
3829 #endif
3830 
3831 /* NEVER use any variables (VBInfo), this will be called
3832  * from outside the context of modeswitch!
3833  * MUST call getVBType before calling this
3834  */
3835 void
3837 {
3838 #ifdef CONFIG_FB_SIS_315
3839  unsigned short tempah, pushax=0, modenum;
3840 #endif
3841  unsigned short temp=0;
3842 
3843  if(SiS_Pr->SiS_VBType & VB_SISVB) {
3844 
3845  if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* ===== For 30xB/C/LV ===== */
3846 
3847  if(SiS_Pr->ChipType < SIS_315H) {
3848 
3849 #ifdef CONFIG_FB_SIS_300 /* 300 series */
3850 
3851  if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
3852  if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3853  SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
3854  } else {
3855  SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
3856  }
3857  SiS_PanelDelay(SiS_Pr, 3);
3858  }
3859  if(SiS_Is301B(SiS_Pr)) {
3860  SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);
3861  SiS_ShortDelay(SiS_Pr,1);
3862  }
3863  SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
3864  SiS_DisplayOff(SiS_Pr);
3865  SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3866  SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
3867  SiS_UnLockCRT2(SiS_Pr);
3868  if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) {
3869  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
3870  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
3871  }
3872  if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
3873  (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
3874  SiS_PanelDelay(SiS_Pr, 2);
3875  if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3876  SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
3877  } else {
3878  SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
3879  }
3880  }
3881 
3882 #endif /* CONFIG_FB_SIS_300 */
3883 
3884  } else {
3885 
3886 #ifdef CONFIG_FB_SIS_315 /* 315 series */
3887 
3888  int didpwd = 0;
3889  bool custom1 = (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
3890  (SiS_Pr->SiS_CustomT == CUT_CLEVO1400);
3891 
3892  modenum = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34) & 0x7f;
3893 
3894  if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3895 
3896 #ifdef SET_EMI
3897  if(SiS_Pr->SiS_VBType & VB_SISEMI) {
3898  if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
3899  SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
3900  }
3901  }
3902 #endif
3903 
3904  didpwd = SiS_HandlePWD(SiS_Pr);
3905 
3906  if( (modenum <= 0x13) ||
3907  (SiS_IsVAMode(SiS_Pr)) ||
3908  (!(SiS_IsDualEdge(SiS_Pr))) ) {
3909  if(!didpwd) {
3910  SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfe);
3911  if(custom1) SiS_PanelDelay(SiS_Pr, 3);
3912  } else {
3913  SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfc);
3914  }
3915  }
3916 
3917  if(!custom1) {
3918  SiS_DDC2Delay(SiS_Pr,0xff00);
3919  SiS_DDC2Delay(SiS_Pr,0xe000);
3920  SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
3921  pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
3922  if(IS_SIS740) {
3923  SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
3924  }
3925  SiS_PanelDelay(SiS_Pr, 3);
3926  }
3927 
3928  }
3929 
3930  if(!(SiS_IsNotM650orLater(SiS_Pr))) {
3931  /* if(SiS_Pr->ChipType < SIS_340) {*/
3932  tempah = 0xef;
3933  if(SiS_IsVAMode(SiS_Pr)) tempah = 0xf7;
3934  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
3935  /*}*/
3936  }
3937 
3938  if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3939  SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,~0x10);
3940  }
3941 
3942  tempah = 0x3f;
3943  if(SiS_IsDualEdge(SiS_Pr)) {
3944  tempah = 0x7f;
3945  if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0xbf;
3946  }
3947  SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
3948 
3949  if((SiS_IsVAMode(SiS_Pr)) ||
3950  ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
3951 
3952  SiS_DisplayOff(SiS_Pr);
3953  if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3954  SiS_PanelDelay(SiS_Pr, 2);
3955  }
3956  SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3957  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
3958 
3959  }
3960 
3961  if((!(SiS_IsVAMode(SiS_Pr))) ||
3962  ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
3963 
3964  if(!(SiS_IsDualEdge(SiS_Pr))) {
3965  SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
3966  SiS_DisplayOff(SiS_Pr);
3967  }
3968  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
3969 
3970  if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3971  SiS_PanelDelay(SiS_Pr, 2);
3972  }
3973 
3974  SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3975  temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
3976  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
3977  SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
3978  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
3979 
3980  }
3981 
3982  if(SiS_IsNotM650orLater(SiS_Pr)) {
3983  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
3984  }
3985 
3986  if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3987 
3988  if( (!(SiS_IsVAMode(SiS_Pr))) &&
3989  (!(SiS_CRT2IsLCD(SiS_Pr))) &&
3990  (!(SiS_IsDualEdge(SiS_Pr))) ) {
3991 
3992  if(custom1) SiS_PanelDelay(SiS_Pr, 2);
3993  if(!didpwd) {
3994  SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
3995  }
3996  if(custom1) SiS_PanelDelay(SiS_Pr, 4);
3997  }
3998 
3999  if(!custom1) {
4000  SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4001  if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4002  if(SiS_IsVAorLCD(SiS_Pr)) {
4003  SiS_PanelDelayLoop(SiS_Pr, 3, 20);
4004  }
4005  }
4006  }
4007 
4008  }
4009 
4010 #endif /* CONFIG_FB_SIS_315 */
4011 
4012  }
4013 
4014  } else { /* ============ For 301 ================ */
4015 
4016  if(SiS_Pr->ChipType < SIS_315H) {
4017 #ifdef CONFIG_FB_SIS_300
4018  if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4019  SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4020  SiS_PanelDelay(SiS_Pr, 3);
4021  }
4022 #endif
4023  }
4024 
4025  SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF); /* disable VB */
4026  SiS_DisplayOff(SiS_Pr);
4027 
4028  if(SiS_Pr->ChipType >= SIS_315H) {
4029  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4030  }
4031 
4032  SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); /* disable lock mode */
4033 
4034  if(SiS_Pr->ChipType >= SIS_315H) {
4035  temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
4036  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
4037  SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4038  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
4039  } else {
4040 #ifdef CONFIG_FB_SIS_300
4041  SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); /* disable CRT2 */
4042  if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4043  (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4044  SiS_PanelDelay(SiS_Pr, 2);
4045  SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4046  }
4047 #endif
4048  }
4049 
4050  }
4051 
4052  } else { /* ============ For LVDS =============*/
4053 
4054  if(SiS_Pr->ChipType < SIS_315H) {
4055 
4056 #ifdef CONFIG_FB_SIS_300 /* 300 series */
4057 
4058  if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4059  SiS_SetCH700x(SiS_Pr,0x0E,0x09);
4060  }
4061 
4062  if(SiS_Pr->ChipType == SIS_730) {
4063  if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4064  SiS_WaitVBRetrace(SiS_Pr);
4065  }
4066  if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4067  SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4068  SiS_PanelDelay(SiS_Pr, 3);
4069  }
4070  } else {
4071  if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4072  if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4073  if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4074  SiS_WaitVBRetrace(SiS_Pr);
4075  if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {
4076  SiS_DisplayOff(SiS_Pr);
4077  }
4078  SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4079  SiS_PanelDelay(SiS_Pr, 3);
4080  }
4081  }
4082  }
4083  }
4084 
4085  SiS_DisplayOff(SiS_Pr);
4086 
4087  SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4088 
4089  SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4090  SiS_UnLockCRT2(SiS_Pr);
4091  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
4092  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
4093 
4094  if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4095  (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4096  SiS_PanelDelay(SiS_Pr, 2);
4097  SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4098  }
4099 
4100 #endif /* CONFIG_FB_SIS_300 */
4101 
4102  } else {
4103 
4104 #ifdef CONFIG_FB_SIS_315 /* 315 series */
4105 
4106  if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4107  /*if(SiS_Pr->ChipType < SIS_340) { */ /* XGI needs this */
4108  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,~0x18);
4109  /* } */
4110  }
4111 
4112  if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4113 
4114  if(SiS_Pr->ChipType == SIS_740) {
4115  temp = SiS_GetCH701x(SiS_Pr,0x61);
4116  if(temp < 1) {
4117  SiS_SetCH701x(SiS_Pr,0x76,0xac);
4118  SiS_SetCH701x(SiS_Pr,0x66,0x00);
4119  }
4120 
4121  if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4122  (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
4123  SiS_SetCH701x(SiS_Pr,0x49,0x3e);
4124  }
4125  }
4126 
4127  if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4128  (SiS_IsVAMode(SiS_Pr)) ) {
4129  SiS_Chrontel701xBLOff(SiS_Pr);
4130  SiS_Chrontel701xOff(SiS_Pr);
4131  }
4132 
4133  if(SiS_Pr->ChipType != SIS_740) {
4134  if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4135  (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
4136  SiS_SetCH701x(SiS_Pr,0x49,0x01);
4137  }
4138  }
4139 
4140  }
4141 
4142  if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4143  SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4144  SiS_PanelDelay(SiS_Pr, 3);
4145  }
4146 
4147  if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4148  (!(SiS_IsDualEdge(SiS_Pr))) ||
4149  (!(SiS_IsTVOrYPbPrOrScart(SiS_Pr))) ) {
4150  SiS_DisplayOff(SiS_Pr);
4151  }
4152 
4153  if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4154  (!(SiS_IsDualEdge(SiS_Pr))) ||
4155  (!(SiS_IsVAMode(SiS_Pr))) ) {
4156  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4157  }
4158 
4159  if(SiS_Pr->ChipType == SIS_740) {
4160  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4161  }
4162 
4163  SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4164 
4165  if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4166  (!(SiS_IsDualEdge(SiS_Pr))) ||
4167  (!(SiS_IsVAMode(SiS_Pr))) ) {
4168  SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4169  }
4170 
4171  if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4172  if(SiS_CRT2IsLCD(SiS_Pr)) {
4173  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4174  if(SiS_Pr->ChipType == SIS_550) {
4175  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xbf);
4176  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xef);
4177  }
4178  }
4179  } else {
4180  if(SiS_Pr->ChipType == SIS_740) {
4181  if(SiS_IsLCDOrLCDA(SiS_Pr)) {
4182  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4183  }
4184  } else if(SiS_IsVAMode(SiS_Pr)) {
4185  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4186  }
4187  }
4188 
4189  if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4190  if(SiS_IsDualEdge(SiS_Pr)) {
4191  /* SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff); */
4192  } else {
4193  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
4194  }
4195  }
4196 
4197  SiS_UnLockCRT2(SiS_Pr);
4198 
4199  if(SiS_Pr->ChipType == SIS_550) {
4200  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); /* DirectDVD PAL?*/
4201  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); /* VB clock / 4 ? */
4202  } else if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4203  (!(SiS_IsDualEdge(SiS_Pr))) ||
4204  (!(SiS_IsVAMode(SiS_Pr))) ) {
4205  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4206  }
4207 
4208  if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4209  if(SiS_CRT2IsLCD(SiS_Pr)) {
4210  if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4211  SiS_PanelDelay(SiS_Pr, 2);
4212  SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4213  }
4214  }
4215  }
4216 
4217 #endif /* CONFIG_FB_SIS_315 */
4218 
4219  } /* 315 series */
4220 
4221  } /* LVDS */
4222 
4223 }
4224 
4225 /*********************************************/
4226 /* ENABLE VIDEO BRIDGE */
4227 /*********************************************/
4228 
4229 /* NEVER use any variables (VBInfo), this will be called
4230  * from outside the context of a mode switch!
4231  * MUST call getVBType before calling this
4232  */
4233 static
4234 void
4235 SiS_EnableBridge(struct SiS_Private *SiS_Pr)
4236 {
4237  unsigned short temp=0, tempah;
4238 #ifdef CONFIG_FB_SIS_315
4239  unsigned short temp1, pushax=0;
4240  bool delaylong = false;
4241 #endif
4242 
4243  if(SiS_Pr->SiS_VBType & VB_SISVB) {
4244 
4245  if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* ====== For 301B et al ====== */
4246 
4247  if(SiS_Pr->ChipType < SIS_315H) {
4248 
4249 #ifdef CONFIG_FB_SIS_300 /* 300 series */
4250 
4251  if(SiS_CRT2IsLCD(SiS_Pr)) {
4252  if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4253  SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4254  } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
4255  SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4256  }
4257  if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_NoLCD)) {
4258  if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
4259  SiS_PanelDelay(SiS_Pr, 0);
4260  }
4261  }
4262  }
4263 
4264  if((SiS_Pr->SiS_VBType & VB_NoLCD) &&
4265  (SiS_CRT2IsLCD(SiS_Pr))) {
4266 
4267  SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* Enable CRT2 */
4268  SiS_DisplayOn(SiS_Pr);
4269  SiS_UnLockCRT2(SiS_Pr);
4270  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4271  if(SiS_BridgeInSlavemode(SiS_Pr)) {
4272  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4273  } else {
4274  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4275  }
4276  if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4277  if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4278  if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4279  SiS_PanelDelay(SiS_Pr, 1);
4280  }
4281  SiS_WaitVBRetrace(SiS_Pr);
4282  SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4283  }
4284  }
4285 
4286  } else {
4287 
4288  temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
4289  if(SiS_BridgeInSlavemode(SiS_Pr)) {
4290  tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4291  if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4292  }
4293  SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4294  SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4295  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */
4296  SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
4297  SiS_DisplayOn(SiS_Pr);
4298  if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4299  if(SiS_CRT2IsLCD(SiS_Pr)) {
4300  if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4301  if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4302  SiS_PanelDelay(SiS_Pr, 1);
4303  }
4304  SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4305  }
4306  }
4307  }
4308 
4309  }
4310 
4311 
4312 #endif /* CONFIG_FB_SIS_300 */
4313 
4314  } else {
4315 
4316 #ifdef CONFIG_FB_SIS_315 /* 315 series */
4317 
4318 #ifdef SET_EMI
4319  unsigned char r30=0, r31=0, r32=0, r33=0, cr36=0;
4320  int didpwd = 0;
4321  /* unsigned short emidelay=0; */
4322 #endif
4323 
4324  if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4325  SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef);
4326 #ifdef SET_EMI
4327  if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4328  SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4329  }
4330 #endif
4331  }
4332 
4333  if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4334  /*if(SiS_Pr->ChipType < SIS_340) { */
4335  tempah = 0x10;
4336  if(SiS_LCDAEnabled(SiS_Pr)) {
4337  if(SiS_TVEnabled(SiS_Pr)) tempah = 0x18;
4338  else tempah = 0x08;
4339  }
4340  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah);
4341  /*}*/
4342  }
4343 
4344  if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4345 
4346  SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
4347  SiS_DisplayOff(SiS_Pr);
4348  pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
4349  if(IS_SIS740) {
4350  SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
4351  }
4352 
4353  didpwd = SiS_HandlePWD(SiS_Pr);
4354 
4355  if(SiS_IsVAorLCD(SiS_Pr)) {
4356  if(!didpwd) {
4357  if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
4358  SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4359  SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4360  SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4361  if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4362  SiS_GenericDelay(SiS_Pr, 17664);
4363  }
4364  }
4365  } else {
4366  SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4367  if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4368  SiS_GenericDelay(SiS_Pr, 17664);
4369  }
4370  }
4371  }
4372 
4373  if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {
4374  SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4375  delaylong = true;
4376  }
4377 
4378  }
4379 
4380  if(!(SiS_IsVAMode(SiS_Pr))) {
4381 
4382  temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
4383  if(SiS_BridgeInSlavemode(SiS_Pr)) {
4384  tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4385  if(!(tempah & SetCRT2ToRAMDAC)) {
4386  if(!(SiS_LCDAEnabled(SiS_Pr))) temp |= 0x20;
4387  }
4388  }
4389  SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4390 
4391  SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
4392 
4393  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4394  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4395 
4396  if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4397  SiS_PanelDelay(SiS_Pr, 2);
4398  }
4399 
4400  } else {
4401 
4402  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20);
4403 
4404  }
4405 
4406  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
4407  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4408 
4409  if(SiS_Pr->SiS_VBType & VB_SISPOWER) {
4410  if( (SiS_LCDAEnabled(SiS_Pr)) ||
4411  (SiS_CRT2IsLCD(SiS_Pr)) ) {
4412  /* Enable "LVDS PLL power on" (even on 301C) */
4413  SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);
4414  /* Enable "LVDS Driver Power on" (even on 301C) */
4415  SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x7f);
4416  }
4417  }
4418 
4419  tempah = 0xc0;
4420  if(SiS_IsDualEdge(SiS_Pr)) {
4421  tempah = 0x80;
4422  if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0x40;
4423  }
4424  SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4425 
4426  if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4427 
4428  SiS_PanelDelay(SiS_Pr, 2);
4429 
4430  SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10);
4431  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4432 
4433  if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
4434 #ifdef SET_EMI
4435  if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4436  SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4437  SiS_GenericDelay(SiS_Pr, 2048);
4438  }
4439 #endif
4440  SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
4441 
4442  if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4443 #ifdef SET_EMI
4444  cr36 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
4445 
4446  if(SiS_Pr->SiS_ROMNew) {
4447  unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
4448  unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
4449  if(romptr) {
4450  SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4451  SiS_Pr->EMI_30 = 0;
4452  SiS_Pr->EMI_31 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 0];
4453  SiS_Pr->EMI_32 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 1];
4454  SiS_Pr->EMI_33 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 2];
4455  if(ROMAddr[romptr + 1] & 0x10) SiS_Pr->EMI_30 = 0x40;
4456  /* emidelay = SISGETROMW((romptr + 0x22)); */
4457  SiS_Pr->HaveEMI = SiS_Pr->HaveEMILCD = SiS_Pr->OverruleEMI = true;
4458  }
4459  }
4460 
4461  /* (P4_30|0x40) */
4462  /* Compal 1400x1050: 0x05, 0x60, 0x00 YES (1.10.7w; CR36=69) */
4463  /* Compal 1400x1050: 0x0d, 0x70, 0x40 YES (1.10.7x; CR36=69) */
4464  /* Acer 1280x1024: 0x12, 0xd0, 0x6b NO (1.10.9k; CR36=73) */
4465  /* Compaq 1280x1024: 0x0d, 0x70, 0x6b YES (1.12.04b; CR36=03) */
4466  /* Clevo 1024x768: 0x05, 0x60, 0x33 NO (1.10.8e; CR36=12, DL!) */
4467  /* Clevo 1024x768: 0x0d, 0x70, 0x40 (if type == 3) YES (1.10.8y; CR36=?2) */
4468  /* Clevo 1024x768: 0x05, 0x60, 0x33 (if type != 3) YES (1.10.8y; CR36=?2) */
4469  /* Asus 1024x768: ? ? (1.10.8o; CR36=?2) */
4470  /* Asus 1024x768: 0x08, 0x10, 0x3c (problematic) YES (1.10.8q; CR36=22) */
4471 
4472  if(SiS_Pr->HaveEMI) {
4473  r30 = SiS_Pr->EMI_30; r31 = SiS_Pr->EMI_31;
4474  r32 = SiS_Pr->EMI_32; r33 = SiS_Pr->EMI_33;
4475  } else {
4476  r30 = 0;
4477  }
4478 
4479  /* EMI_30 is read at driver start; however, the BIOS sets this
4480  * (if it is used) only if the LCD is in use. In case we caught
4481  * the machine while on TV output, this bit is not set and we
4482  * don't know if it should be set - hence our detection is wrong.
4483  * Work-around this here:
4484  */
4485 
4486  if((!SiS_Pr->HaveEMI) || (!SiS_Pr->HaveEMILCD)) {
4487  switch((cr36 & 0x0f)) {
4488  case 2:
4489  r30 |= 0x40;
4490  if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) r30 &= ~0x40;
4491  if(!SiS_Pr->HaveEMI) {
4492  r31 = 0x05; r32 = 0x60; r33 = 0x33;
4493  if((cr36 & 0xf0) == 0x30) {
4494  r31 = 0x0d; r32 = 0x70; r33 = 0x40;
4495  }
4496  }
4497  break;
4498  case 3: /* 1280x1024 */
4499  if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) r30 |= 0x40;
4500  if(!SiS_Pr->HaveEMI) {
4501  r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4502  if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4503  r31 = 0x0d; r32 = 0x70; r33 = 0x6b;
4504  }
4505  }
4506  break;
4507  case 9: /* 1400x1050 */
4508  r30 |= 0x40;
4509  if(!SiS_Pr->HaveEMI) {
4510  r31 = 0x05; r32 = 0x60; r33 = 0x00;
4511  if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4512  r31 = 0x0d; r32 = 0x70; r33 = 0x40; /* BIOS values */
4513  }
4514  }
4515  break;
4516  case 11: /* 1600x1200 - unknown */
4517  r30 |= 0x40;
4518  if(!SiS_Pr->HaveEMI) {
4519  r31 = 0x05; r32 = 0x60; r33 = 0x00;
4520  }
4521  }
4522  }
4523 
4524  /* BIOS values don't work so well sometimes */
4525  if(!SiS_Pr->OverruleEMI) {
4526 #ifdef COMPAL_HACK
4527  if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4528  if((cr36 & 0x0f) == 0x09) {
4529  r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x00;
4530  }
4531  }
4532 #endif
4533 #ifdef COMPAQ_HACK
4534  if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4535  if((cr36 & 0x0f) == 0x03) {
4536  r30 = 0x20; r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4537  }
4538  }
4539 #endif
4540 #ifdef ASUS_HACK
4541  if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4542  if((cr36 & 0x0f) == 0x02) {
4543  /* r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 2 */
4544  /* r30 = 0x20; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 3 */
4545  /* r30 = 0x60; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 4 */
4546  /* r30 = 0x20; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 5 */
4547  }
4548  }
4549 #endif
4550  }
4551 
4552  if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) {
4553  SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4554  SiS_GenericDelay(SiS_Pr, 2048);
4555  }
4556  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,r31);
4557  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,r32);
4558  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x33,r33);
4559 #endif /* SET_EMI */
4560 
4561  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
4562 
4563 #ifdef SET_EMI
4564  if( (SiS_LCDAEnabled(SiS_Pr)) ||
4565  (SiS_CRT2IsLCD(SiS_Pr)) ) {
4566  if(r30 & 0x40) {
4567  /*SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x2a,0x80);*/
4568  SiS_PanelDelayLoop(SiS_Pr, 3, 5);
4569  if(delaylong) {
4570  SiS_PanelDelayLoop(SiS_Pr, 3, 5);
4571  delaylong = false;
4572  }
4573  SiS_WaitVBRetrace(SiS_Pr);
4574  SiS_WaitVBRetrace(SiS_Pr);
4575  if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4576  SiS_GenericDelay(SiS_Pr, 1280);
4577  }
4578  SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40); /* Enable */
4579  /*SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);*/
4580  }
4581  }
4582 #endif
4583  }
4584  }
4585 
4586  if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4587  if(SiS_IsVAorLCD(SiS_Pr)) {
4588  SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4589  if(delaylong) {
4590  SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4591  }
4592  SiS_WaitVBRetrace(SiS_Pr);
4593  if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4594  SiS_GenericDelay(SiS_Pr, 2048);
4595  SiS_WaitVBRetrace(SiS_Pr);
4596  }
4597  if(!didpwd) {
4598  SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4599  } else {
4600  SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x03);
4601  }
4602  }
4603  }
4604 
4605  SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4606  SiS_DisplayOn(SiS_Pr);
4607  SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xff);
4608 
4609  }
4610 
4611  if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4612  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4613  }
4614 
4615 #endif /* CONFIG_FB_SIS_315 */
4616 
4617  }
4618 
4619  } else { /* ============ For 301 ================ */
4620 
4621  if(SiS_Pr->ChipType < SIS_315H) {
4622  if(SiS_CRT2IsLCD(SiS_Pr)) {
4623  SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4624  SiS_PanelDelay(SiS_Pr, 0);
4625  }
4626  }
4627 
4628  temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
4629  if(SiS_BridgeInSlavemode(SiS_Pr)) {
4630  tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4631  if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4632  }
4633  SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4634 
4635  SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
4636 
4637  if(SiS_Pr->ChipType >= SIS_315H) {
4638  temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4639  if(!(temp & 0x80)) {
4640  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80); /* BVBDOENABLE=1 */
4641  }
4642  }
4643 
4644  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */
4645 
4646  SiS_VBLongWait(SiS_Pr);
4647  SiS_DisplayOn(SiS_Pr);
4648  if(SiS_Pr->ChipType >= SIS_315H) {
4649  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4650  }
4651  SiS_VBLongWait(SiS_Pr);
4652 
4653  if(SiS_Pr->ChipType < SIS_315H) {
4654  if(SiS_CRT2IsLCD(SiS_Pr)) {
4655  SiS_PanelDelay(SiS_Pr, 1);
4656  SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4657  }
4658  }
4659 
4660  }
4661 
4662  } else { /* =================== For LVDS ================== */
4663 
4664  if(SiS_Pr->ChipType < SIS_315H) {
4665 
4666 #ifdef CONFIG_FB_SIS_300 /* 300 series */
4667 
4668  if(SiS_CRT2IsLCD(SiS_Pr)) {
4669  if(SiS_Pr->ChipType == SIS_730) {
4670  SiS_PanelDelay(SiS_Pr, 1);
4671  SiS_PanelDelay(SiS_Pr, 1);
4672  SiS_PanelDelay(SiS_Pr, 1);
4673  }
4674  SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4675  if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
4676  SiS_PanelDelay(SiS_Pr, 0);
4677  }
4678  }
4679 
4680  SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4681  SiS_DisplayOn(SiS_Pr);
4682  SiS_UnLockCRT2(SiS_Pr);
4683  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4684  if(SiS_BridgeInSlavemode(SiS_Pr)) {
4685  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4686  } else {
4687  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4688  }
4689 
4690  if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4691  if(!(SiS_CRT2IsLCD(SiS_Pr))) {
4692  SiS_WaitVBRetrace(SiS_Pr);
4693  SiS_SetCH700x(SiS_Pr,0x0E,0x0B);
4694  }
4695  }
4696 
4697  if(SiS_CRT2IsLCD(SiS_Pr)) {
4698  if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4699  if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4700  if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4701  SiS_PanelDelay(SiS_Pr, 1);
4702  SiS_PanelDelay(SiS_Pr, 1);
4703  }
4704  SiS_WaitVBRetrace(SiS_Pr);
4705  SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4706  }
4707  }
4708  }
4709 
4710 #endif /* CONFIG_FB_SIS_300 */
4711 
4712  } else {
4713 
4714 #ifdef CONFIG_FB_SIS_315 /* 315 series */
4715 
4716  if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4717  /*if(SiS_Pr->ChipType < SIS_340) {*/ /* XGI needs this */
4718  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x18);
4719  /*}*/
4720  }
4721 
4722  if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4723  if(SiS_CRT2IsLCD(SiS_Pr)) {
4724  SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4725  SiS_PanelDelay(SiS_Pr, 0);
4726  }
4727  }
4728 
4729  SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4730  SiS_UnLockCRT2(SiS_Pr);
4731 
4732  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4733 
4734  if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4735  temp = SiS_GetCH701x(SiS_Pr,0x66);
4736  temp &= 0x20;
4737  SiS_Chrontel701xBLOff(SiS_Pr);
4738  }
4739 
4740  if(SiS_Pr->ChipType != SIS_550) {
4741  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4742  }
4743 
4744  if(SiS_Pr->ChipType == SIS_740) {
4745  if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4746  if(SiS_IsLCDOrLCDA(SiS_Pr)) {
4747  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4748  }
4749  }
4750  }
4751 
4752  temp1 = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4753  if(!(temp1 & 0x80)) {
4754  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
4755  }
4756 
4757  if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4758  if(temp) {
4759  SiS_Chrontel701xBLOn(SiS_Pr);
4760  }
4761  }
4762 
4763  if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4764  if(SiS_CRT2IsLCD(SiS_Pr)) {
4765  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4766  if(SiS_Pr->ChipType == SIS_550) {
4767  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x40);
4768  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x10);
4769  }
4770  }
4771  } else if(SiS_IsVAMode(SiS_Pr)) {
4772  if(SiS_Pr->ChipType != SIS_740) {
4773  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4774  }
4775  }
4776 
4777  if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4778  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4779  }
4780 
4781  if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4782  if(SiS_IsTVOrYPbPrOrScart(SiS_Pr)) {
4783  SiS_Chrontel701xOn(SiS_Pr);
4784  }
4785  if( (SiS_IsVAMode(SiS_Pr)) ||
4786  (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
4787  SiS_ChrontelDoSomething1(SiS_Pr);
4788  }
4789  }
4790 
4791  if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4792  if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4793  if( (SiS_IsVAMode(SiS_Pr)) ||
4794  (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
4795  SiS_Chrontel701xBLOn(SiS_Pr);
4796  SiS_ChrontelInitTVVSync(SiS_Pr);
4797  }
4798  }
4799  } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4800  if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4801  if(SiS_CRT2IsLCD(SiS_Pr)) {
4802  SiS_PanelDelay(SiS_Pr, 1);
4803  SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4804  }
4805  }
4806  }
4807 
4808 #endif /* CONFIG_FB_SIS_315 */
4809 
4810  } /* 310 series */
4811 
4812  } /* LVDS */
4813 
4814 }
4815 
4816 /*********************************************/
4817 /* SET PART 1 REGISTER GROUP */
4818 /*********************************************/
4819 
4820 /* Set CRT2 OFFSET / PITCH */
4821 static void
4822 SiS_SetCRT2Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
4823  unsigned short RRTI)
4824 {
4825  unsigned short offset;
4826  unsigned char temp;
4827 
4828  if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return;
4829 
4830  offset = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,RRTI);
4831 
4832  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(offset & 0xFF));
4833  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,(offset >> 8));
4834 
4835  temp = (unsigned char)(((offset >> 3) & 0xFF) + 1);
4836  if(offset & 0x07) temp++;
4837  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,temp);
4838 }
4839 
4840 /* Set CRT2 sync and PanelLink mode */
4841 static void
4842 SiS_SetCRT2Sync(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RefreshRateTableIndex)
4843 {
4844  unsigned short tempah=0, tempbl, infoflag;
4845 
4846  tempbl = 0xC0;
4847 
4848  if(SiS_Pr->UseCustomMode) {
4849  infoflag = SiS_Pr->CInfoFlag;
4850  } else {
4851  infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
4852  }
4853 
4854  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { /* LVDS */
4855 
4856  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
4857  tempah = 0;
4858  } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) {
4859  tempah = SiS_Pr->SiS_LCDInfo;
4860  } else tempah = infoflag >> 8;
4861  tempah &= 0xC0;
4862  tempah |= 0x20;
4863  if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4864  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4865  if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
4866  (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
4867  tempah |= 0xf0;
4868  }
4869  if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
4870  (SiS_Pr->SiS_IF_DEF_DSTN) ||
4871  (SiS_Pr->SiS_IF_DEF_TRUMPION) ||
4872  (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
4873  (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
4874  tempah |= 0x30;
4875  }
4876  if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
4877  (SiS_Pr->SiS_IF_DEF_DSTN) ) {
4878  tempah &= ~0xc0;
4879  }
4880  }
4881  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
4882  if(SiS_Pr->ChipType >= SIS_315H) {
4883  tempah >>= 3;
4884  tempah &= 0x18;
4885  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xE7,tempah);
4886  /* Don't care about 12/18/24 bit mode - TV is via VGA, not PL */
4887  } else {
4888  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,0xe0);
4889  }
4890  } else {
4891  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4892  }
4893 
4894  } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
4895 
4896  if(SiS_Pr->ChipType < SIS_315H) {
4897 
4898 #ifdef CONFIG_FB_SIS_300 /* ---- 300 series --- */
4899 
4900  if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* 630 - 301B(-DH) */
4901 
4902  tempah = infoflag >> 8;
4903  tempbl = 0;
4904  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4905  if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4906  tempah = SiS_Pr->SiS_LCDInfo;
4907  tempbl = (tempah >> 6) & 0x03;
4908  }
4909  }
4910  tempah &= 0xC0;
4911  tempah |= 0x20;
4912  if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4913  tempah |= 0xc0;
4914  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4915  if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
4916  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
4917  }
4918 
4919  } else { /* 630 - 301 */
4920 
4921  tempah = ((infoflag >> 8) & 0xc0) | 0x20;
4922  if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4923  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4924 
4925  }
4926 
4927 #endif /* CONFIG_FB_SIS_300 */
4928 
4929  } else {
4930 
4931 #ifdef CONFIG_FB_SIS_315 /* ------- 315 series ------ */
4932 
4933  if(SiS_Pr->SiS_VBType & VB_SISLVDS) { /* 315 - LVDS */
4934 
4935  tempbl = 0;
4936  if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
4937  (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
4938  tempah = infoflag >> 8;
4939  if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4940  tempbl = ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6);
4941  }
4942  } else if((SiS_Pr->SiS_CustomT == CUT_CLEVO1400) &&
4943  (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)) {
4944  tempah = infoflag >> 8;
4945  tempbl = 0x03;
4946  } else {
4947  tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
4948  tempbl = (tempah >> 6) & 0x03;
4949  tempbl |= 0x08;
4950  if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempbl |= 0x04;
4951  }
4952  tempah &= 0xC0;
4953  tempah |= 0x20;
4954  if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4955  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) tempah |= 0xc0;
4956  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4957  if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
4958  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4959  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
4960  }
4961  }
4962 
4963  } else { /* 315 - TMDS */
4964 
4965  tempah = tempbl = infoflag >> 8;
4966  if(!SiS_Pr->UseCustomMode) {
4967  tempbl = 0;
4968  if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
4969  if(ModeNo <= 0x13) {
4970  tempah = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
4971  }
4972  }
4973  if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
4974  if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
4975  if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4976  tempah = SiS_Pr->SiS_LCDInfo;
4977  tempbl = (tempah >> 6) & 0x03;
4978  }
4979  }
4980  }
4981  }
4982  tempah &= 0xC0;
4983  tempah |= 0x20;
4984  if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4985  if(SiS_Pr->SiS_VBType & VB_NoLCD) {
4986  /* Imitate BIOS bug */
4987  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempah |= 0xc0;
4988  }
4989  if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
4990  tempah >>= 3;
4991  tempah &= 0x18;
4992  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xe7,tempah);
4993  } else {
4994  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4995  if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
4996  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4997  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
4998  }
4999  }
5000  }
5001 
5002  }
5003 #endif /* CONFIG_FB_SIS_315 */
5004  }
5005  }
5006 }
5007 
5008 /* Set CRT2 FIFO on 300/540/630/730 */
5009 #ifdef CONFIG_FB_SIS_300
5010 static void
5011 SiS_SetCRT2FIFO_300(struct SiS_Private *SiS_Pr,unsigned short ModeNo)
5012 {
5013  unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
5014  unsigned short temp, index, modeidindex, refreshratetableindex;
5015  unsigned short VCLK = 0, MCLK, colorth = 0, data2 = 0;
5016  unsigned short tempbx, tempcl, CRT1ModeNo, CRT2ModeNo, SelectRate_backup;
5017  unsigned int data, pci50, pciA0;
5018  static const unsigned char colortharray[] = {
5019  1, 1, 2, 2, 3, 4
5020  };
5021 
5022  SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;
5023 
5024  if(!SiS_Pr->CRT1UsesCustomMode) {
5025 
5026  CRT1ModeNo = SiS_Pr->SiS_CRT1Mode; /* get CRT1 ModeNo */
5027  SiS_SearchModeID(SiS_Pr, &CRT1ModeNo, &modeidindex);
5028  SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
5029  SiS_Pr->SiS_SelectCRT2Rate = 0;
5030  refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT1ModeNo, modeidindex);
5031 
5032  if(CRT1ModeNo >= 0x13) {
5033  /* Get VCLK */
5034  index = SiS_GetRefCRTVCLK(SiS_Pr, refreshratetableindex, SiS_Pr->SiS_UseWide);
5035  VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
5036 
5037  /* Get colordepth */
5038  colorth = SiS_GetColorDepth(SiS_Pr,CRT1ModeNo,modeidindex) >> 1;
5039  if(!colorth) colorth++;
5040  }
5041 
5042  } else {
5043 
5044  CRT1ModeNo = 0xfe;
5045 
5046  /* Get VCLK */
5047  VCLK = SiS_Pr->CSRClock_CRT1;
5048 
5049  /* Get color depth */
5050  colorth = colortharray[((SiS_Pr->CModeFlag_CRT1 & ModeTypeMask) - 2)];
5051 
5052  }
5053 
5054  if(CRT1ModeNo >= 0x13) {
5055  /* Get MCLK */
5056  if(SiS_Pr->ChipType == SIS_300) {
5057  index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A);
5058  } else {
5059  index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A);
5060  }
5061  index &= 0x07;
5062  MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;
5063 
5064  temp = ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) >> 6) & 0x03) << 1;
5065  if(!temp) temp++;
5066  temp <<= 2;
5067 
5068  data2 = temp - ((colorth * VCLK) / MCLK);
5069 
5070  temp = (28 * 16) % data2;
5071  data2 = (28 * 16) / data2;
5072  if(temp) data2++;
5073 
5074  if(SiS_Pr->ChipType == SIS_300) {
5075 
5076  SiS_GetFIFOThresholdIndex300(SiS_Pr, &tempbx, &tempcl);
5077  data = SiS_GetFIFOThresholdB300(tempbx, tempcl);
5078 
5079  } else {
5080 
5081  pci50 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0x50);
5082  pciA0 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0xa0);
5083 
5084  if(SiS_Pr->ChipType == SIS_730) {
5085 
5086  index = (unsigned short)(((pciA0 >> 28) & 0x0f) * 3);
5087  index += (unsigned short)(((pci50 >> 9)) & 0x03);
5088 
5089  /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */
5090  index = 0; /* -- do it like the BIOS anyway... */
5091 
5092  } else {
5093 
5094  pci50 >>= 24;
5095  pciA0 >>= 24;
5096 
5097  index = (pci50 >> 1) & 0x07;
5098 
5099  if(pci50 & 0x01) index += 6;
5100  if(!(pciA0 & 0x01)) index += 24;
5101 
5102  if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80) index += 12;
5103 
5104  }
5105 
5106  data = SiS_GetLatencyFactor630(SiS_Pr, index) + 15;
5107  if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80)) data += 5;
5108 
5109  }
5110 
5111  data += data2; /* CRT1 Request Period */
5112 
5113  SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5114  SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5115 
5116  if(!SiS_Pr->UseCustomMode) {
5117 
5118  CRT2ModeNo = ModeNo;
5119  SiS_SearchModeID(SiS_Pr, &CRT2ModeNo, &modeidindex);
5120 
5121  refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT2ModeNo, modeidindex);
5122 
5123  /* Get VCLK */
5124  index = SiS_GetVCLK2Ptr(SiS_Pr, CRT2ModeNo, modeidindex, refreshratetableindex);
5125  VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
5126 
5127  if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
5128  if(SiS_Pr->SiS_UseROM) {
5129  if(ROMAddr[0x220] & 0x01) {
5130  VCLK = ROMAddr[0x229] | (ROMAddr[0x22a] << 8);
5131  }
5132  }
5133  }
5134 
5135  } else {
5136 
5137  /* Get VCLK */
5138  CRT2ModeNo = 0xfe;
5139  VCLK = SiS_Pr->CSRClock;
5140 
5141  }
5142 
5143  /* Get colordepth */
5144  colorth = SiS_GetColorDepth(SiS_Pr,CRT2ModeNo,modeidindex) >> 1;
5145  if(!colorth) colorth++;
5146 
5147  data = data * VCLK * colorth;
5148  temp = data % (MCLK << 4);
5149  data = data / (MCLK << 4);
5150  if(temp) data++;
5151 
5152  if(data < 6) data = 6;
5153  else if(data > 0x14) data = 0x14;
5154 
5155  if(SiS_Pr->ChipType == SIS_300) {
5156  temp = 0x16;
5157  if((data <= 0x0f) || (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024))
5158  temp = 0x13;
5159  } else {
5160  temp = 0x16;
5161  if(( (SiS_Pr->ChipType == SIS_630) ||
5162  (SiS_Pr->ChipType == SIS_730) ) &&
5163  (SiS_Pr->ChipRevision >= 0x30))
5164  temp = 0x1b;
5165  }