root/drivers/video/fbdev/sis/init301.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. SiS_UnLockCRT2
  2. SiS_LockCRT2
  3. SiS_SetRegSR11ANDOR
  4. GetLCDStructPtr661
  5. GetLCDStructPtr661_2
  6. SiS_AdjustCRT2Rate
  7. SiS_GetRatePtr
  8. SiS_SaveCRT2Info
  9. SiS_CR36BIOSWord23b
  10. SiS_CR36BIOSWord23d
  11. SiS_DDC2Delay
  12. SiS_GenericDelay
  13. SiS_LongDelay
  14. SiS_ShortDelay
  15. SiS_PanelDelay
  16. SiS_PanelDelayLoop
  17. SiS_WaitRetrace1
  18. SiS_WaitRetrace2
  19. SiS_WaitVBRetrace
  20. SiS_VBWait
  21. SiS_VBLongWait
  22. SiS_Is301B
  23. SiS_CRT2IsLCD
  24. SiS_IsDualEdge
  25. SiS_IsVAMode
  26. SiS_IsVAorLCD
  27. SiS_IsDualLink
  28. SiS_TVEnabled
  29. SiS_LCDAEnabled
  30. SiS_WeHaveBacklightCtrl
  31. SiS_IsNotM650orLater
  32. SiS_IsYPbPr
  33. SiS_IsChScart
  34. SiS_IsTVOrYPbPrOrScart
  35. SiS_IsLCDOrLCDA
  36. SiS_HaveBridge
  37. SiS_BridgeIsEnabled
  38. SiS_BridgeInSlavemode
  39. SiS_SetChrontelGPIO
  40. SiS_GetVBInfo
  41. SiS_SetYPbPr
  42. SiS_SetTVMode
  43. SiS_GetBIOSLCDResInfo
  44. SiS_GetLCDInfoBIOS
  45. SiS_CheckScaling
  46. SiS_GetLCDResInfo
  47. SiS_GetVCLK2Ptr
  48. SiS_SetCRT2ModeRegs
  49. SiS_GetResInfo
  50. SiS_GetCRT2ResInfo
  51. SiS_GetCRT2Ptr
  52. SiS_GetRAMDAC2DATA
  53. SiS_CalcPanelLinkTiming
  54. SiS_GetCRT2DataLVDS
  55. SiS_GetCRT2Data301
  56. SiS_GetCRT2Data
  57. SiS_GetLVDSDesPtr
  58. SiS_GetLVDSDesData
  59. SiS_HandlePWD
  60. SiS_DisableBridge
  61. SiS_EnableBridge
  62. SiS_SetCRT2Offset
  63. SiS_SetCRT2Sync
  64. SiS_SetCRT2FIFO_300
  65. SiS_SetCRT2FIFO_310
  66. SiS_GetVGAHT2
  67. SiS_SetGroup1_301
  68. SiS_SetGroup1_LVDS
  69. SiS_SetGroup1
  70. SiS_GetGroup2CLVXPtr
  71. SiS_SetGroup2_C_ELV
  72. SiS_GetCRT2Part2Ptr
  73. SiS_Group2LCDSpecial
  74. SiS_Set300Part2Regs
  75. SiS_SetTVSpecial
  76. SiS_SetGroup2_Tail
  77. SiS_SetGroup2
  78. SiS_SetGroup3
  79. SiS_ShiftXPos
  80. SiS_SetGroup4_C_ELV
  81. SiS_SetCRT2VCLK
  82. SiS_SetDualLinkEtc
  83. SiS_SetGroup4
  84. SiS_SetGroup5
  85. SiS_GetLVDSCRT1Ptr
  86. SiS_ModCRT1CRTC
  87. SiS_SetCRT2ECLK
  88. SiS_SetCHTVReg
  89. SiS_Chrontel701xBLOn
  90. SiS_Chrontel701xBLOff
  91. SiS_ChrontelPowerSequencing
  92. SiS_SetCH701xForLCD
  93. SiS_ChrontelResetVSync
  94. SiS_Chrontel701xOn
  95. SiS_Chrontel701xOff
  96. SiS_ChrontelResetDB
  97. SiS_ChrontelInitTVVSync
  98. SiS_ChrontelDoSomething3
  99. SiS_ChrontelDoSomething2
  100. SiS_ChrontelDoSomething1
  101. SiS_SetCRT2Group
  102. SiS_SiS30xBLOn
  103. SiS_SiS30xBLOff
  104. SiS_SetupDDCN
  105. SiS_SetTrumpBlockLoop
  106. SiS_SetTrumpionBlock
  107. SiS_SetChReg
  108. SiS_SetCH700x
  109. SiS_SetCH701x
  110. SiS_SetCH70xx
  111. SiS_GetChReg
  112. SiS_GetCH700x
  113. SiS_GetCH701x
  114. SiS_GetCH70xx
  115. SiS_SetCH70xxANDOR
  116. SiS_InitDDCRegs
  117. SiS_WriteDABDDC
  118. SiS_PrepareReadDDC
  119. SiS_PrepareDDC
  120. SiS_SendACK
  121. SiS_DoProbeDDC
  122. SiS_ProbeDDC
  123. SiS_ReadDDC
  124. SiS_HandleDDC
  125. SiS_SetSwitchDDC2
  126. SiS_ReadDDC1Bit
  127. SiS_SetStart
  128. SiS_SetStop
  129. SiS_WriteDDC2Data
  130. SiS_ReadDDC2Data
  131. SiS_SetSCLKLow
  132. SiS_SetSCLKHigh
  133. SiS_CheckACK
  134. GetRAMDACromptr
  135. GetLCDromptr
  136. GetTVromptr
  137. GetLCDPtrIndexBIOS
  138. GetLCDPtrIndex
  139. GetTVPtrIndex
  140. GetOEMTVPtr661_2_GEN
  141. GetOEMTVPtr661_2_OLD
  142. GetOEMTVPtr661_2_NEW
  143. GetOEMTVPtr661
  144. SetDelayComp
  145. SetAntiFlicker
  146. SetEdgeEnhance
  147. SetYFilter
  148. SetPhaseIncr
  149. SetDelayComp661
  150. SetCRT2SyncDither661
  151. SetPanelParms661
  152. SiS_OEM310Setting
  153. SiS_OEM661Setting
  154. SiS_FinalizeLCD
  155. SetOEMLCDData2
  156. GetOEMLCDPtr
  157. SetOEMLCDDelay
  158. SetOEMLCDData
  159. GetOEMTVPtr
  160. SetOEMTVDelay
  161. SetOEMAntiFlicker
  162. SetOEMPhaseIncr
  163. SetOEMYFilter
  164. SiS_SearchVBModeID
  165. SiS_OEM300Setting

   1 /* $XFree86$ */
   2 /* $XdotOrg$ */
   3 /*
   4  * Mode initializing code (CRT2 section)
   5  * for SiS 300/305/540/630/730,
   6  *     SiS 315/550/[M]650/651/[M]661[FGM]X/[M]74x[GX]/330/[M]76x[GX],
   7  *     XGI V3XT/V5/V8, Z7
   8  * (Universal module for Linux kernel framebuffer and X.org/XFree86 4.x)
   9  *
  10  * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
  11  *
  12  * If distributed as part of the Linux kernel, the following license terms
  13  * apply:
  14  *
  15  * * This program is free software; you can redistribute it and/or modify
  16  * * it under the terms of the GNU General Public License as published by
  17  * * the Free Software Foundation; either version 2 of the named License,
  18  * * or any later version.
  19  * *
  20  * * This program is distributed in the hope that it will be useful,
  21  * * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22  * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  23  * * GNU General Public License for more details.
  24  * *
  25  * * You should have received a copy of the GNU General Public License
  26  * * along with this program; if not, write to the Free Software
  27  * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
  28  *
  29  * Otherwise, the following license terms apply:
  30  *
  31  * * Redistribution and use in source and binary forms, with or without
  32  * * modification, are permitted provided that the following conditions
  33  * * are met:
  34  * * 1) Redistributions of source code must retain the above copyright
  35  * *    notice, this list of conditions and the following disclaimer.
  36  * * 2) Redistributions in binary form must reproduce the above copyright
  37  * *    notice, this list of conditions and the following disclaimer in the
  38  * *    documentation and/or other materials provided with the distribution.
  39  * * 3) The name of the author may not be used to endorse or promote products
  40  * *    derived from this software without specific prior written permission.
  41  * *
  42  * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  43  * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  44  * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  45  * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  46  * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  47  * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  48  * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  49  * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  50  * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  51  * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  52  *
  53  * Author:      Thomas Winischhofer <thomas@winischhofer.net>
  54  *
  55  * Formerly based on non-functional code-fragements for 300 series by SiS, Inc.
  56  * Used by permission.
  57  *
  58  */
  59 
  60 #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 const unsigned char SiS_YPbPrTable[3][64] = {
  86   {
  87     0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c,
  88     0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a,
  89     0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x1b,
  90     0x0c,0x50,0x00,0x97,0x00,0xda,0x4a,0x17,
  91     0x7d,0x05,0x4b,0x00,0x00,0xe2,0x00,0x02,
  92     0x03,0x0a,0x65,0x9d /*0x8d*/,0x08,0x92,0x8f,0x40,
  93     0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x53 /*0x50*/,
  94     0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00
  95   },
  96   {
  97     0x33,0x06,0x06,0x09,0x0b,0x0c,0x0c,0x0c,
  98     0x98,0x0a,0x01,0x0d,0x06,0x0d,0x04,0x0a,
  99     0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x3f,
 100     0x0c,0x50,0xb2,0x9f,0x16,0x59,0x4f,0x13,
 101     0xad,0x11,0xad,0x1d,0x40,0x8a,0x3d,0xb8,
 102     0x51,0x5e,0x60,0x49,0x7d,0x92,0x0f,0x40,
 103     0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x4e,
 104     0x43,0x41,0x11,0x00,0xfc,0xff,0x32,0x00
 105   },
 106   {
 107 #if 0 /* OK, but sticks to left edge */
 108     0x13,0x1d,0xe8,0x09,0x09,0xed,0x0c,0x0c,
 109     0x98,0x0a,0x01,0x0c,0x06,0x0d,0x04,0x0a,
 110     0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x3f,
 111     0xed,0x50,0x70,0x9f,0x16,0x59,0x21 /*0x2b*/,0x13,
 112     0x27,0x0b,0x27,0xfc,0x30,0x27,0x1c,0xb0,
 113     0x4b,0x4b,0x65 /*0x6f*/,0x2f,0x63,0x92,0x0f,0x40,
 114     0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x27,
 115     0x00,0x40,0x11,0x00,0xfc,0xff,0x32,0x00
 116 #endif
 117 #if 1 /* Perfect */
 118     0x23,0x2d,0xe8,0x09,0x09,0xed,0x0c,0x0c,
 119     0x98,0x0a,0x01,0x0c,0x06,0x0d,0x04,0x0a,
 120     0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x3f,
 121     0xed,0x50,0x70,0x9f,0x16,0x59,0x60,0x13,
 122     0x27,0x0b,0x27,0xfc,0x30,0x27,0x1c,0xb0,
 123     0x4b,0x4b,0x6f,0x2f,0x63,0x92,0x0f,0x40,
 124     0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x73,
 125     0x00,0x40,0x11,0x00,0xfc,0xff,0x32,0x00
 126 #endif
 127   }
 128 };
 129 
 130 static const unsigned char SiS_TVPhase[] =
 131 {
 132         0x21,0xED,0xBA,0x08,    /* 0x00 SiS_NTSCPhase */
 133         0x2A,0x05,0xE3,0x00,    /* 0x01 SiS_PALPhase */
 134         0x21,0xE4,0x2E,0x9B,    /* 0x02 SiS_PALMPhase */
 135         0x21,0xF4,0x3E,0xBA,    /* 0x03 SiS_PALNPhase */
 136         0x1E,0x8B,0xA2,0xA7,
 137         0x1E,0x83,0x0A,0xE0,    /* 0x05 SiS_SpecialPhaseM */
 138         0x00,0x00,0x00,0x00,
 139         0x00,0x00,0x00,0x00,
 140         0x21,0xF0,0x7B,0xD6,    /* 0x08 SiS_NTSCPhase2 */
 141         0x2A,0x09,0x86,0xE9,    /* 0x09 SiS_PALPhase2 */
 142         0x21,0xE6,0xEF,0xA4,    /* 0x0a SiS_PALMPhase2 */
 143         0x21,0xF6,0x94,0x46,    /* 0x0b SiS_PALNPhase2 */
 144         0x1E,0x8B,0xA2,0xA7,
 145         0x1E,0x83,0x0A,0xE0,    /* 0x0d SiS_SpecialPhaseM */
 146         0x00,0x00,0x00,0x00,
 147         0x00,0x00,0x00,0x00,
 148         0x1e,0x8c,0x5c,0x7a,    /* 0x10 SiS_SpecialPhase */
 149         0x25,0xd4,0xfd,0x5e     /* 0x11 SiS_SpecialPhaseJ */
 150 };
 151 
 152 static const unsigned char SiS_HiTVGroup3_1[] = {
 153     0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x13,
 154     0xb1, 0x41, 0x62, 0x62, 0xff, 0xf4, 0x45, 0xa6,
 155     0x25, 0x2f, 0x67, 0xf6, 0xbf, 0xff, 0x8e, 0x20,
 156     0xac, 0xda, 0x60, 0xfe, 0x6a, 0x9a, 0x06, 0x10,
 157     0xd1, 0x04, 0x18, 0x0a, 0xff, 0x80, 0x00, 0x80,
 158     0x3b, 0x77, 0x00, 0xef, 0xe0, 0x10, 0xb0, 0xe0,
 159     0x10, 0x4f, 0x0f, 0x0f, 0x05, 0x0f, 0x08, 0x6e,
 160     0x1a, 0x1f, 0x25, 0x2a, 0x4c, 0xaa, 0x01
 161 };
 162 
 163 static const unsigned char SiS_HiTVGroup3_2[] = {
 164     0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x7a,
 165     0x54, 0x41, 0xe7, 0xe7, 0xff, 0xf4, 0x45, 0xa6,
 166     0x25, 0x2f, 0x67, 0xf6, 0xbf, 0xff, 0x8e, 0x20,
 167     0xac, 0x6a, 0x60, 0x2b, 0x52, 0xcd, 0x61, 0x10,
 168     0x51, 0x04, 0x18, 0x0a, 0x1f, 0x80, 0x00, 0x80,
 169     0xff, 0xa4, 0x04, 0x2b, 0x94, 0x21, 0x72, 0x94,
 170     0x26, 0x05, 0x01, 0x0f, 0xed, 0x0f, 0x0a, 0x64,
 171     0x18, 0x1d, 0x23, 0x28, 0x4c, 0xaa, 0x01
 172 };
 173 
 174 /* 301C / 302ELV extended Part2 TV registers (4 tap scaler) */
 175 
 176 static const unsigned char SiS_Part2CLVX_1[] = {
 177     0x00,0x00,
 178     0x00,0x20,0x00,0x00,0x7F,0x20,0x02,0x7F,0x7D,0x20,0x04,0x7F,0x7D,0x1F,0x06,0x7E,
 179     0x7C,0x1D,0x09,0x7E,0x7C,0x1B,0x0B,0x7E,0x7C,0x19,0x0E,0x7D,0x7C,0x17,0x11,0x7C,
 180     0x7C,0x14,0x14,0x7C,0x7C,0x11,0x17,0x7C,0x7D,0x0E,0x19,0x7C,0x7E,0x0B,0x1B,0x7C,
 181     0x7E,0x09,0x1D,0x7C,0x7F,0x06,0x1F,0x7C,0x7F,0x04,0x20,0x7D,0x00,0x02,0x20,0x7E
 182 };
 183 
 184 static const unsigned char SiS_Part2CLVX_2[] = {
 185     0x00,0x00,
 186     0x00,0x20,0x00,0x00,0x7F,0x20,0x02,0x7F,0x7D,0x20,0x04,0x7F,0x7D,0x1F,0x06,0x7E,
 187     0x7C,0x1D,0x09,0x7E,0x7C,0x1B,0x0B,0x7E,0x7C,0x19,0x0E,0x7D,0x7C,0x17,0x11,0x7C,
 188     0x7C,0x14,0x14,0x7C,0x7C,0x11,0x17,0x7C,0x7D,0x0E,0x19,0x7C,0x7E,0x0B,0x1B,0x7C,
 189     0x7E,0x09,0x1D,0x7C,0x7F,0x06,0x1F,0x7C,0x7F,0x04,0x20,0x7D,0x00,0x02,0x20,0x7E
 190 };
 191 
 192 static const unsigned char SiS_Part2CLVX_3[] = {  /* NTSC, 525i, 525p */
 193     0xE0,0x01,
 194     0x04,0x1A,0x04,0x7E,0x03,0x1A,0x06,0x7D,0x01,0x1A,0x08,0x7D,0x00,0x19,0x0A,0x7D,
 195     0x7F,0x19,0x0C,0x7C,0x7E,0x18,0x0E,0x7C,0x7E,0x17,0x10,0x7B,0x7D,0x15,0x12,0x7C,
 196     0x7D,0x13,0x13,0x7D,0x7C,0x12,0x15,0x7D,0x7C,0x10,0x17,0x7D,0x7C,0x0E,0x18,0x7E,
 197     0x7D,0x0C,0x19,0x7E,0x7D,0x0A,0x19,0x00,0x7D,0x08,0x1A,0x01,0x7E,0x06,0x1A,0x02,
 198     0x58,0x02,
 199     0x07,0x14,0x07,0x7E,0x06,0x14,0x09,0x7D,0x05,0x14,0x0A,0x7D,0x04,0x13,0x0B,0x7E,
 200     0x03,0x13,0x0C,0x7E,0x02,0x12,0x0D,0x7F,0x01,0x12,0x0E,0x7F,0x01,0x11,0x0F,0x7F,
 201     0x00,0x10,0x10,0x00,0x7F,0x0F,0x11,0x01,0x7F,0x0E,0x12,0x01,0x7E,0x0D,0x12,0x03,
 202     0x7E,0x0C,0x13,0x03,0x7E,0x0B,0x13,0x04,0x7E,0x0A,0x14,0x04,0x7D,0x09,0x14,0x06,
 203     0x00,0x03,
 204     0x09,0x0F,0x09,0x7F,0x08,0x0F,0x09,0x00,0x07,0x0F,0x0A,0x00,0x06,0x0F,0x0A,0x01,
 205     0x06,0x0E,0x0B,0x01,0x05,0x0E,0x0B,0x02,0x04,0x0E,0x0C,0x02,0x04,0x0D,0x0C,0x03,
 206     0x03,0x0D,0x0D,0x03,0x02,0x0C,0x0D,0x05,0x02,0x0C,0x0E,0x04,0x01,0x0B,0x0E,0x06,
 207     0x01,0x0B,0x0E,0x06,0x00,0x0A,0x0F,0x07,0x00,0x0A,0x0F,0x07,0x00,0x09,0x0F,0x08,
 208     0xFF,0xFF
 209 };
 210 
 211 static const unsigned char SiS_Part2CLVX_4[] = {   /* PAL */
 212     0x58,0x02,
 213     0x05,0x19,0x05,0x7D,0x03,0x19,0x06,0x7E,0x02,0x19,0x08,0x7D,0x01,0x18,0x0A,0x7D,
 214     0x00,0x18,0x0C,0x7C,0x7F,0x17,0x0E,0x7C,0x7E,0x16,0x0F,0x7D,0x7E,0x14,0x11,0x7D,
 215     0x7D,0x13,0x13,0x7D,0x7D,0x11,0x14,0x7E,0x7D,0x0F,0x16,0x7E,0x7D,0x0E,0x17,0x7E,
 216     0x7D,0x0C,0x18,0x7F,0x7D,0x0A,0x18,0x01,0x7D,0x08,0x19,0x02,0x7D,0x06,0x19,0x04,
 217     0x00,0x03,
 218     0x08,0x12,0x08,0x7E,0x07,0x12,0x09,0x7E,0x06,0x12,0x0A,0x7E,0x05,0x11,0x0B,0x7F,
 219     0x04,0x11,0x0C,0x7F,0x03,0x11,0x0C,0x00,0x03,0x10,0x0D,0x00,0x02,0x0F,0x0E,0x01,
 220     0x01,0x0F,0x0F,0x01,0x01,0x0E,0x0F,0x02,0x00,0x0D,0x10,0x03,0x7F,0x0C,0x11,0x04,
 221     0x7F,0x0C,0x11,0x04,0x7F,0x0B,0x11,0x05,0x7E,0x0A,0x12,0x06,0x7E,0x09,0x12,0x07,
 222     0x40,0x02,
 223     0x04,0x1A,0x04,0x7E,0x02,0x1B,0x05,0x7E,0x01,0x1A,0x07,0x7E,0x00,0x1A,0x09,0x7D,
 224     0x7F,0x19,0x0B,0x7D,0x7E,0x18,0x0D,0x7D,0x7D,0x17,0x10,0x7C,0x7D,0x15,0x12,0x7C,
 225     0x7C,0x14,0x14,0x7C,0x7C,0x12,0x15,0x7D,0x7C,0x10,0x17,0x7D,0x7C,0x0D,0x18,0x7F,
 226     0x7D,0x0B,0x19,0x7F,0x7D,0x09,0x1A,0x00,0x7D,0x07,0x1A,0x02,0x7E,0x05,0x1B,0x02,
 227     0xFF,0xFF
 228 };
 229 
 230 static const unsigned char SiS_Part2CLVX_5[] = {   /* 750p */
 231     0x00,0x03,
 232     0x05,0x19,0x05,0x7D,0x03,0x19,0x06,0x7E,0x02,0x19,0x08,0x7D,0x01,0x18,0x0A,0x7D,
 233     0x00,0x18,0x0C,0x7C,0x7F,0x17,0x0E,0x7C,0x7E,0x16,0x0F,0x7D,0x7E,0x14,0x11,0x7D,
 234     0x7D,0x13,0x13,0x7D,0x7D,0x11,0x14,0x7E,0x7D,0x0F,0x16,0x7E,0x7D,0x0E,0x17,0x7E,
 235     0x7D,0x0C,0x18,0x7F,0x7D,0x0A,0x18,0x01,0x7D,0x08,0x19,0x02,0x7D,0x06,0x19,0x04,
 236     0xFF,0xFF
 237 };
 238 
 239 static const unsigned char SiS_Part2CLVX_6[] = {   /* 1080i */
 240     0x00,0x04,
 241     0x04,0x1A,0x04,0x7E,0x02,0x1B,0x05,0x7E,0x01,0x1A,0x07,0x7E,0x00,0x1A,0x09,0x7D,
 242     0x7F,0x19,0x0B,0x7D,0x7E,0x18,0x0D,0x7D,0x7D,0x17,0x10,0x7C,0x7D,0x15,0x12,0x7C,
 243     0x7C,0x14,0x14,0x7C,0x7C,0x12,0x15,0x7D,0x7C,0x10,0x17,0x7D,0x7C,0x0D,0x18,0x7F,
 244     0x7D,0x0B,0x19,0x7F,0x7D,0x09,0x1A,0x00,0x7D,0x07,0x1A,0x02,0x7E,0x05,0x1B,0x02,
 245     0xFF,0xFF,
 246 };
 247 
 248 #ifdef CONFIG_FB_SIS_315
 249 /* 661 et al LCD data structure (2.03.00) */
 250 static const unsigned char SiS_LCDStruct661[] = {
 251     /* 1024x768 */
 252 /*  type|CR37|   HDE   |   VDE   |    HT   |    VT   |   hss    | hse   */
 253     0x02,0xC0,0x00,0x04,0x00,0x03,0x40,0x05,0x26,0x03,0x10,0x00,0x88,
 254     0x00,0x02,0x00,0x06,0x00,0x41,0x5A,0x64,0x00,0x00,0x00,0x00,0x04,
 255     /*  | vss     |    vse  |clck|  clock  |CRT2DataP|CRT2DataP|idx     */
 256     /*                                        VESA    non-VESA  noscale */
 257     /* 1280x1024 */
 258     0x03,0xC0,0x00,0x05,0x00,0x04,0x98,0x06,0x2A,0x04,0x30,0x00,0x70,
 259     0x00,0x01,0x00,0x03,0x00,0x6C,0xF8,0x2F,0x00,0x00,0x00,0x00,0x08,
 260     /* 1400x1050 */
 261     0x09,0x20,0x78,0x05,0x1A,0x04,0x98,0x06,0x2A,0x04,0x18,0x00,0x38,
 262     0x00,0x01,0x00,0x03,0x00,0x6C,0xF8,0x2F,0x00,0x00,0x00,0x00,0x09,
 263     /* 1600x1200 */
 264     0x0B,0xE0,0x40,0x06,0xB0,0x04,0x70,0x08,0xE2,0x04,0x40,0x00,0xC0,
 265     0x00,0x01,0x00,0x03,0x00,0xA2,0x70,0x24,0x00,0x00,0x00,0x00,0x0A,
 266     /* 1280x768 (_2) */
 267     0x0A,0xE0,0x00,0x05,0x00,0x03,0x7C,0x06,0x26,0x03,0x30,0x00,0x70,
 268     0x00,0x03,0x00,0x06,0x00,0x4D,0xC8,0x48,0x00,0x00,0x00,0x00,0x06,
 269     /* 1280x720 */
 270     0x0E,0xE0,0x00,0x05,0xD0,0x02,0x80,0x05,0x26,0x03,0x10,0x00,0x20,
 271     0x00,0x01,0x00,0x06,0x00,0x45,0x9C,0x62,0x00,0x00,0x00,0x00,0x05,
 272     /* 1280x800 (_2) */
 273     0x0C,0xE0,0x00,0x05,0x20,0x03,0x10,0x06,0x2C,0x03,0x30,0x00,0x70,
 274     0x00,0x04,0x00,0x03,0x00,0x49,0xCE,0x1E,0x00,0x00,0x00,0x00,0x09,
 275     /* 1680x1050 */
 276     0x0D,0xE0,0x90,0x06,0x1A,0x04,0x6C,0x07,0x2A,0x04,0x1A,0x00,0x4C,
 277     0x00,0x03,0x00,0x06,0x00,0x79,0xBE,0x44,0x00,0x00,0x00,0x00,0x06,
 278     /* 1280x800_3 */
 279     0x0C,0xE0,0x00,0x05,0x20,0x03,0xAA,0x05,0x2E,0x03,0x30,0x00,0x50,
 280     0x00,0x04,0x00,0x03,0x00,0x47,0xA9,0x10,0x00,0x00,0x00,0x00,0x07,
 281     /* 800x600 */
 282     0x01,0xC0,0x20,0x03,0x58,0x02,0x20,0x04,0x74,0x02,0x2A,0x00,0x80,
 283     0x00,0x06,0x00,0x04,0x00,0x28,0x63,0x4B,0x00,0x00,0x00,0x00,0x00,
 284     /* 1280x854 */
 285     0x08,0xE0,0x00,0x05,0x56,0x03,0x80,0x06,0x5d,0x03,0x10,0x00,0x70,
 286     0x00,0x01,0x00,0x03,0x00,0x54,0x75,0x13,0x00,0x00,0x00,0x00,0x08
 287 };
 288 #endif
 289 
 290 #ifdef CONFIG_FB_SIS_300
 291 static unsigned char SiS300_TrumpionData[14][80] = {
 292   { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
 293     0x20,0x03,0x0B,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x10,0x00,0x00,0x04,0x23,
 294     0x00,0x00,0x03,0x28,0x03,0x10,0x05,0x08,0x40,0x10,0x00,0x10,0x04,0x23,0x00,0x23,
 295     0x03,0x11,0x60,0xBC,0x01,0xFF,0x03,0xFF,0x19,0x01,0x00,0x05,0x09,0x04,0x04,0x05,
 296     0x04,0x0C,0x09,0x05,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5A,0x01,0xBE,0x01,0x00 },
 297   { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x27,0x00,0x80,0x02,
 298     0x20,0x03,0x07,0x00,0x5E,0x01,0x0D,0x02,0x60,0x0C,0x30,0x11,0x00,0x00,0x04,0x23,
 299     0x00,0x00,0x03,0x80,0x03,0x28,0x06,0x08,0x40,0x11,0x00,0x11,0x04,0x23,0x00,0x23,
 300     0x03,0x11,0x60,0x90,0x01,0xFF,0x0F,0xF4,0x19,0x01,0x00,0x05,0x01,0x00,0x04,0x05,
 301     0x04,0x0C,0x02,0x01,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEC,0x57,0x01,0xBE,0x01,0x00 },
 302   { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x8A,0x00,0xD8,0x02,
 303     0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,
 304     0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,
 305     0x03,0x11,0x60,0xD9,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,
 306     0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x59,0x01,0xBE,0x01,0x00 },
 307   { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x72,0x00,0xD8,0x02,
 308     0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,
 309     0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,
 310     0x03,0x11,0x60,0xDA,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,
 311     0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
 312   { 0x02,0x0A,0x02,0x00,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
 313     0x20,0x03,0x16,0x00,0xE0,0x01,0x0D,0x02,0x60,0x0C,0x30,0x98,0x00,0x00,0x04,0x23,
 314     0x00,0x01,0x03,0x45,0x03,0x48,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x23,0x00,0x23,
 315     0x03,0x11,0x60,0xF4,0x01,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x05,0x01,0x00,0x05,0x05,
 316     0x04,0x0C,0x08,0x05,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5B,0x01,0xBE,0x01,0x00 },
 317   { 0x02,0x0A,0x02,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0xBF,0x00,0x20,0x03,
 318     0x20,0x04,0x0D,0x00,0x58,0x02,0x71,0x02,0x80,0x0C,0x30,0x9A,0x00,0xFA,0x03,0x1D,
 319     0x00,0x01,0x03,0x22,0x03,0x28,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x1D,0x00,0x1D,
 320     0x03,0x11,0x60,0x39,0x03,0x40,0x05,0xF4,0x18,0x07,0x02,0x06,0x04,0x01,0x06,0x0B,
 321     0x02,0x0A,0x20,0x19,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5B,0x01,0xBE,0x01,0x00 },
 322   { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0xEF,0x00,0x00,0x04,
 323     0x40,0x05,0x13,0x00,0x00,0x03,0x26,0x03,0x88,0x0C,0x30,0x90,0x00,0x00,0x04,0x23,
 324     0x00,0x01,0x03,0x24,0x03,0x28,0x06,0x08,0x40,0x90,0x00,0x90,0x04,0x23,0x00,0x23,
 325     0x03,0x11,0x60,0x40,0x05,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x08,0x01,0x00,0x08,0x01,
 326     0x00,0x08,0x01,0x01,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5B,0x01,0xBE,0x01,0x00 },
 327   /* variant 2 */
 328   { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
 329     0x20,0x03,0x15,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x18,0x00,0x00,0x04,0x23,
 330     0x00,0x01,0x03,0x44,0x03,0x28,0x06,0x08,0x40,0x18,0x00,0x18,0x04,0x23,0x00,0x23,
 331     0x03,0x11,0x60,0xA6,0x01,0xFF,0x03,0xFF,0x19,0x01,0x00,0x05,0x13,0x04,0x04,0x05,
 332     0x04,0x0C,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
 333   { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
 334     0x20,0x03,0x15,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x18,0x00,0x00,0x04,0x23,
 335     0x00,0x01,0x03,0x44,0x03,0x28,0x06,0x08,0x40,0x18,0x00,0x18,0x04,0x23,0x00,0x23,
 336     0x03,0x11,0x60,0xA6,0x01,0xFF,0x03,0xFF,0x19,0x01,0x00,0x05,0x13,0x04,0x04,0x05,
 337     0x04,0x0C,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
 338   { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x8A,0x00,0xD8,0x02,
 339     0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,
 340     0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,
 341     0x03,0x11,0x60,0xDA,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,
 342     0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
 343   { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x72,0x00,0xD8,0x02,
 344     0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,
 345     0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,
 346     0x03,0x11,0x60,0xDA,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,
 347     0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
 348   { 0x02,0x0A,0x02,0x00,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
 349     0x20,0x03,0x16,0x00,0xE0,0x01,0x0D,0x02,0x60,0x0C,0x30,0x98,0x00,0x00,0x04,0x23,
 350     0x00,0x01,0x03,0x45,0x03,0x48,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x23,0x00,0x23,
 351     0x03,0x11,0x60,0xF4,0x01,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x05,0x01,0x00,0x05,0x05,
 352     0x04,0x0C,0x08,0x05,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEA,0x58,0x01,0xBE,0x01,0x00 },
 353   { 0x02,0x0A,0x02,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0xBF,0x00,0x20,0x03,
 354     0x20,0x04,0x0D,0x00,0x58,0x02,0x71,0x02,0x80,0x0C,0x30,0x9A,0x00,0xFA,0x03,0x1D,
 355     0x00,0x01,0x03,0x22,0x03,0x28,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x1D,0x00,0x1D,
 356     0x03,0x11,0x60,0x39,0x03,0x40,0x05,0xF4,0x18,0x07,0x02,0x06,0x04,0x01,0x06,0x0B,
 357     0x02,0x0A,0x20,0x19,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEA,0x58,0x01,0xBE,0x01,0x00 },
 358   { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0xEF,0x00,0x00,0x04,
 359     0x40,0x05,0x13,0x00,0x00,0x03,0x26,0x03,0x88,0x0C,0x30,0x90,0x00,0x00,0x04,0x23,
 360     0x00,0x01,0x03,0x24,0x03,0x28,0x06,0x08,0x40,0x90,0x00,0x90,0x04,0x23,0x00,0x23,
 361     0x03,0x11,0x60,0x40,0x05,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x08,0x01,0x00,0x08,0x01,
 362     0x00,0x08,0x01,0x01,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEA,0x58,0x01,0xBE,0x01,0x00 }
 363 };
 364 #endif
 365 
 366 #ifdef CONFIG_FB_SIS_315
 367 static void     SiS_Chrontel701xOn(struct SiS_Private *SiS_Pr);
 368 static void     SiS_Chrontel701xOff(struct SiS_Private *SiS_Pr);
 369 static void     SiS_ChrontelInitTVVSync(struct SiS_Private *SiS_Pr);
 370 static void     SiS_ChrontelDoSomething1(struct SiS_Private *SiS_Pr);
 371 #endif /* 315 */
 372 
 373 #ifdef CONFIG_FB_SIS_300
 374 static  bool    SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr);
 375 #endif
 376 
 377 static unsigned short   SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags,
 378                                 int VGAEngine, unsigned short adaptnum, unsigned short DDCdatatype,
 379                                 bool checkcr32, unsigned int VBFlags2);
 380 static unsigned short   SiS_ProbeDDC(struct SiS_Private *SiS_Pr);
 381 static unsigned short   SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype,
 382                                 unsigned char *buffer);
 383 static void             SiS_SetSwitchDDC2(struct SiS_Private *SiS_Pr);
 384 static unsigned short   SiS_SetStart(struct SiS_Private *SiS_Pr);
 385 static unsigned short   SiS_SetStop(struct SiS_Private *SiS_Pr);
 386 static unsigned short   SiS_SetSCLKLow(struct SiS_Private *SiS_Pr);
 387 static unsigned short   SiS_SetSCLKHigh(struct SiS_Private *SiS_Pr);
 388 static unsigned short   SiS_ReadDDC2Data(struct SiS_Private *SiS_Pr);
 389 static unsigned short   SiS_WriteDDC2Data(struct SiS_Private *SiS_Pr, unsigned short tempax);
 390 static unsigned short   SiS_CheckACK(struct SiS_Private *SiS_Pr);
 391 static unsigned short   SiS_WriteDABDDC(struct SiS_Private *SiS_Pr);
 392 static unsigned short   SiS_PrepareReadDDC(struct SiS_Private *SiS_Pr);
 393 static unsigned short   SiS_PrepareDDC(struct SiS_Private *SiS_Pr);
 394 static void             SiS_SendACK(struct SiS_Private *SiS_Pr, unsigned short yesno);
 395 static unsigned short   SiS_DoProbeDDC(struct SiS_Private *SiS_Pr);
 396 
 397 #ifdef CONFIG_FB_SIS_300
 398 static void             SiS_OEM300Setting(struct SiS_Private *SiS_Pr,
 399                                 unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefTabindex);
 400 static void             SetOEMLCDData2(struct SiS_Private *SiS_Pr,
 401                                 unsigned short ModeNo, unsigned short ModeIdIndex,unsigned short RefTableIndex);
 402 #endif
 403 #ifdef CONFIG_FB_SIS_315
 404 static void             SiS_OEM310Setting(struct SiS_Private *SiS_Pr,
 405                                 unsigned short ModeNo,unsigned short ModeIdIndex, unsigned short RRTI);
 406 static void             SiS_OEM661Setting(struct SiS_Private *SiS_Pr,
 407                                 unsigned short ModeNo,unsigned short ModeIdIndex, unsigned short RRTI);
 408 static void             SiS_FinalizeLCD(struct SiS_Private *, unsigned short, unsigned short);
 409 #endif
 410 
 411 static unsigned short   SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr);
 412 static void             SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);
 413 
 414 /*********************************************/
 415 /*         HELPER: Lock/Unlock CRT2          */
 416 /*********************************************/
 417 
 418 void
 419 SiS_UnLockCRT2(struct SiS_Private *SiS_Pr)
 420 {
 421    if(SiS_Pr->ChipType == XGI_20)
 422       return;
 423    else if(SiS_Pr->ChipType >= SIS_315H)
 424       SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
 425    else
 426       SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
 427 }
 428 
 429 static
 430 void
 431 SiS_LockCRT2(struct SiS_Private *SiS_Pr)
 432 {
 433    if(SiS_Pr->ChipType == XGI_20)
 434       return;
 435    else if(SiS_Pr->ChipType >= SIS_315H)
 436       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
 437    else
 438       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
 439 }
 440 
 441 /*********************************************/
 442 /*            HELPER: Write SR11             */
 443 /*********************************************/
 444 
 445 static void
 446 SiS_SetRegSR11ANDOR(struct SiS_Private *SiS_Pr, unsigned short DataAND, unsigned short DataOR)
 447 {
 448    if(SiS_Pr->ChipType >= SIS_661) {
 449       DataAND &= 0x0f;
 450       DataOR  &= 0x0f;
 451    }
 452    SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,DataAND,DataOR);
 453 }
 454 
 455 /*********************************************/
 456 /*    HELPER: Get Pointer to LCD structure   */
 457 /*********************************************/
 458 
 459 #ifdef CONFIG_FB_SIS_315
 460 static unsigned char *
 461 GetLCDStructPtr661(struct SiS_Private *SiS_Pr)
 462 {
 463    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
 464    unsigned char  *myptr = NULL;
 465    unsigned short romindex = 0, reg = 0, idx = 0;
 466 
 467    /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
 468     * due to the variaty of panels the BIOS doesn't know about.
 469     * Exception: If the BIOS has better knowledge (such as in case
 470     * of machines with a 301C and a panel that does not support DDC)
 471     * use the BIOS data as well.
 472     */
 473 
 474    if((SiS_Pr->SiS_ROMNew) &&
 475       ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) {
 476 
 477       if(SiS_Pr->ChipType < SIS_661) reg = 0x3c;
 478       else                           reg = 0x7d;
 479 
 480       idx = (SiS_GetReg(SiS_Pr->SiS_P3d4,reg) & 0x1f) * 26;
 481 
 482       if(idx < (8*26)) {
 483          myptr = (unsigned char *)&SiS_LCDStruct661[idx];
 484       }
 485       romindex = SISGETROMW(0x100);
 486       if(romindex) {
 487          romindex += idx;
 488          myptr = &ROMAddr[romindex];
 489       }
 490    }
 491    return myptr;
 492 }
 493 
 494 static unsigned short
 495 GetLCDStructPtr661_2(struct SiS_Private *SiS_Pr)
 496 {
 497    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
 498    unsigned short romptr = 0;
 499 
 500    /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
 501     * due to the variaty of panels the BIOS doesn't know about.
 502     * Exception: If the BIOS has better knowledge (such as in case
 503     * of machines with a 301C and a panel that does not support DDC)
 504     * use the BIOS data as well.
 505     */
 506 
 507    if((SiS_Pr->SiS_ROMNew) &&
 508       ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) {
 509       romptr = SISGETROMW(0x102);
 510       romptr += ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) * SiS_Pr->SiS661LCD2TableSize);
 511    }
 512 
 513    return romptr;
 514 }
 515 #endif
 516 
 517 /*********************************************/
 518 /*           Adjust Rate for CRT2            */
 519 /*********************************************/
 520 
 521 static bool
 522 SiS_AdjustCRT2Rate(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
 523                 unsigned short RRTI, unsigned short *i)
 524 {
 525    unsigned short checkmask=0, modeid, infoflag;
 526 
 527    modeid = SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID;
 528 
 529    if(SiS_Pr->SiS_VBType & VB_SISVB) {
 530 
 531       if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
 532 
 533          checkmask |= SupportRAMDAC2;
 534          if(SiS_Pr->ChipType >= SIS_315H) {
 535             checkmask |= SupportRAMDAC2_135;
 536             if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
 537                checkmask |= SupportRAMDAC2_162;
 538                if(SiS_Pr->SiS_VBType & VB_SISRAMDAC202) {
 539                   checkmask |= SupportRAMDAC2_202;
 540                }
 541             }
 542          }
 543 
 544       } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
 545 
 546          checkmask |= SupportLCD;
 547          if(SiS_Pr->ChipType >= SIS_315H) {
 548             if(SiS_Pr->SiS_VBType & VB_SISVB) {
 549                if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
 550                   if(modeid == 0x2e) checkmask |= Support64048060Hz;
 551                }
 552             }
 553          }
 554 
 555       } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
 556 
 557          checkmask |= SupportHiVision;
 558 
 559       } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750|SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
 560 
 561          checkmask |= SupportTV;
 562          if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
 563             checkmask |= SupportTV1024;
 564             if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
 565                if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
 566                   checkmask |= SupportYPbPr750p;
 567                }
 568             }
 569          }
 570 
 571       }
 572 
 573    } else {     /* LVDS */
 574 
 575       if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
 576          if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
 577             checkmask |= SupportCHTV;
 578          }
 579       }
 580 
 581       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
 582          checkmask |= SupportLCD;
 583       }
 584 
 585    }
 586 
 587    /* Look backwards in table for matching CRT2 mode */
 588    for(; SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID == modeid; (*i)--) {
 589       infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
 590       if(infoflag & checkmask) return true;
 591       if((*i) == 0) break;
 592    }
 593 
 594    /* Look through the whole mode-section of the table from the beginning
 595     * for a matching CRT2 mode if no mode was found yet.
 596     */
 597    for((*i) = 0; ; (*i)++) {
 598       if(SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID != modeid) break;
 599       infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
 600       if(infoflag & checkmask) return true;
 601    }
 602    return false;
 603 }
 604 
 605 /*********************************************/
 606 /*              Get rate index               */
 607 /*********************************************/
 608 
 609 unsigned short
 610 SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
 611 {
 612    unsigned short RRTI,i,backup_i;
 613    unsigned short modeflag,index,temp,backupindex;
 614    static const unsigned short LCDRefreshIndex[] = {
 615                 0x00, 0x00, 0x01, 0x01,
 616                 0x01, 0x01, 0x01, 0x01,
 617                 0x01, 0x01, 0x01, 0x01,
 618                 0x01, 0x01, 0x01, 0x01,
 619                 0x00, 0x00, 0x00, 0x00
 620    };
 621 
 622    /* Do NOT check for UseCustomMode here, will skrew up FIFO */
 623    if(ModeNo == 0xfe) return 0;
 624 
 625    if(ModeNo <= 0x13) {
 626       modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
 627    } else {
 628       modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
 629    }
 630 
 631    if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
 632       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
 633          if(modeflag & HalfDCLK) return 0;
 634       }
 635    }
 636 
 637    if(ModeNo < 0x14) return 0xFFFF;
 638 
 639    index = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x33) >> SiS_Pr->SiS_SelectCRT2Rate) & 0x0F;
 640    backupindex = index;
 641 
 642    if(index > 0) index--;
 643 
 644    if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
 645       if(SiS_Pr->SiS_VBType & VB_SISVB) {
 646          if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
 647             if(SiS_Pr->SiS_VBType & VB_NoLCD)            index = 0;
 648             else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index = backupindex = 0;
 649          }
 650          if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
 651             if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) {
 652                temp = LCDRefreshIndex[SiS_GetBIOSLCDResInfo(SiS_Pr)];
 653                if(index > temp) index = temp;
 654             }
 655          }
 656       } else {
 657          if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) index = 0;
 658          if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
 659             if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) index = 0;
 660          }
 661       }
 662    }
 663 
 664    RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
 665    ModeNo = SiS_Pr->SiS_RefIndex[RRTI].ModeID;
 666 
 667    if(SiS_Pr->ChipType >= SIS_315H) {
 668       if(!(SiS_Pr->SiS_VBInfo & DriverMode)) {
 669          if( (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x105) ||
 670              (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x107) ) {
 671             if(backupindex <= 1) RRTI++;
 672          }
 673       }
 674    }
 675 
 676    i = 0;
 677    do {
 678       if(SiS_Pr->SiS_RefIndex[RRTI + i].ModeID != ModeNo) break;
 679       temp = SiS_Pr->SiS_RefIndex[RRTI + i].Ext_InfoFlag;
 680       temp &= ModeTypeMask;
 681       if(temp < SiS_Pr->SiS_ModeType) break;
 682       i++;
 683       index--;
 684    } while(index != 0xFFFF);
 685 
 686    if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
 687       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
 688          temp = SiS_Pr->SiS_RefIndex[RRTI + i - 1].Ext_InfoFlag;
 689          if(temp & InterlaceMode) i++;
 690       }
 691    }
 692 
 693    i--;
 694 
 695    if((SiS_Pr->SiS_SetFlag & ProgrammingCRT2) && (!(SiS_Pr->SiS_VBInfo & DisableCRT2Display))) {
 696       backup_i = i;
 697       if(!(SiS_AdjustCRT2Rate(SiS_Pr, ModeNo, ModeIdIndex, RRTI, &i))) {
 698          i = backup_i;
 699       }
 700    }
 701 
 702    return (RRTI + i);
 703 }
 704 
 705 /*********************************************/
 706 /*            STORE CRT2 INFO in CR34        */
 707 /*********************************************/
 708 
 709 static void
 710 SiS_SaveCRT2Info(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
 711 {
 712    unsigned short temp1, temp2;
 713 
 714    /* Store CRT1 ModeNo in CR34 */
 715    SiS_SetReg(SiS_Pr->SiS_P3d4,0x34,ModeNo);
 716    temp1 = (SiS_Pr->SiS_VBInfo & SetInSlaveMode) >> 8;
 717    temp2 = ~(SetInSlaveMode >> 8);
 718    SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x31,temp2,temp1);
 719 }
 720 
 721 /*********************************************/
 722 /*    HELPER: GET SOME DATA FROM BIOS ROM    */
 723 /*********************************************/
 724 
 725 #ifdef CONFIG_FB_SIS_300
 726 static bool
 727 SiS_CR36BIOSWord23b(struct SiS_Private *SiS_Pr)
 728 {
 729    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
 730    unsigned short temp,temp1;
 731 
 732    if(SiS_Pr->SiS_UseROM) {
 733       if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
 734          temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
 735          temp1 = SISGETROMW(0x23b);
 736          if(temp1 & temp) return true;
 737       }
 738    }
 739    return false;
 740 }
 741 
 742 static bool
 743 SiS_CR36BIOSWord23d(struct SiS_Private *SiS_Pr)
 744 {
 745    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
 746    unsigned short temp,temp1;
 747 
 748    if(SiS_Pr->SiS_UseROM) {
 749       if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
 750          temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
 751          temp1 = SISGETROMW(0x23d);
 752          if(temp1 & temp) return true;
 753       }
 754    }
 755    return false;
 756 }
 757 #endif
 758 
 759 /*********************************************/
 760 /*          HELPER: DELAY FUNCTIONS          */
 761 /*********************************************/
 762 
 763 void
 764 SiS_DDC2Delay(struct SiS_Private *SiS_Pr, unsigned int delaytime)
 765 {
 766    while (delaytime-- > 0)
 767       SiS_GetReg(SiS_Pr->SiS_P3c4, 0x05);
 768 }
 769 
 770 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
 771 static void
 772 SiS_GenericDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
 773 {
 774    SiS_DDC2Delay(SiS_Pr, delay * 36);
 775 }
 776 #endif
 777 
 778 #ifdef CONFIG_FB_SIS_315
 779 static void
 780 SiS_LongDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
 781 {
 782    while(delay--) {
 783       SiS_GenericDelay(SiS_Pr, 6623);
 784    }
 785 }
 786 #endif
 787 
 788 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
 789 static void
 790 SiS_ShortDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
 791 {
 792    while(delay--) {
 793       SiS_GenericDelay(SiS_Pr, 66);
 794    }
 795 }
 796 #endif
 797 
 798 static void
 799 SiS_PanelDelay(struct SiS_Private *SiS_Pr, unsigned short DelayTime)
 800 {
 801 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
 802    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
 803    unsigned short PanelID, DelayIndex, Delay=0;
 804 #endif
 805 
 806    if(SiS_Pr->ChipType < SIS_315H) {
 807 
 808 #ifdef CONFIG_FB_SIS_300
 809 
 810       PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
 811       if(SiS_Pr->SiS_VBType & VB_SISVB) {
 812          if(SiS_Pr->SiS_VBType & VB_SIS301) PanelID &= 0xf7;
 813          if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x10)) PanelID = 0x12;
 814       }
 815       DelayIndex = PanelID >> 4;
 816       if((DelayTime >= 2) && ((PanelID & 0x0f) == 1))  {
 817          Delay = 3;
 818       } else {
 819          if(DelayTime >= 2) DelayTime -= 2;
 820          if(!(DelayTime & 0x01)) {
 821             Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
 822          } else {
 823             Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
 824          }
 825          if(SiS_Pr->SiS_UseROM) {
 826             if(ROMAddr[0x220] & 0x40) {
 827                if(!(DelayTime & 0x01)) Delay = (unsigned short)ROMAddr[0x225];
 828                else                    Delay = (unsigned short)ROMAddr[0x226];
 829             }
 830          }
 831       }
 832       SiS_ShortDelay(SiS_Pr, Delay);
 833 
 834 #endif  /* CONFIG_FB_SIS_300 */
 835 
 836    } else {
 837 
 838 #ifdef CONFIG_FB_SIS_315
 839 
 840       if((SiS_Pr->ChipType >= SIS_661)    ||
 841          (SiS_Pr->ChipType <= SIS_315PRO) ||
 842          (SiS_Pr->ChipType == SIS_330)    ||
 843          (SiS_Pr->SiS_ROMNew)) {
 844 
 845          if(!(DelayTime & 0x01)) {
 846             SiS_DDC2Delay(SiS_Pr, 0x1000);
 847          } else {
 848             SiS_DDC2Delay(SiS_Pr, 0x4000);
 849          }
 850 
 851       } else if (SiS_Pr->SiS_IF_DEF_LVDS == 1) {                        /* 315 series, LVDS; Special */
 852 
 853          if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
 854             PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
 855             if(SiS_Pr->SiS_CustomT == CUT_CLEVO1400) {
 856                if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1b) & 0x10)) PanelID = 0x12;
 857             }
 858             if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
 859                DelayIndex = PanelID & 0x0f;
 860             } else {
 861                DelayIndex = PanelID >> 4;
 862             }
 863             if((DelayTime >= 2) && ((PanelID & 0x0f) == 1))  {
 864                Delay = 3;
 865             } else {
 866                if(DelayTime >= 2) DelayTime -= 2;
 867                if(!(DelayTime & 0x01)) {
 868                   Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[0];
 869                 } else {
 870                   Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[1];
 871                }
 872                if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
 873                   if(ROMAddr[0x13c] & 0x40) {
 874                      if(!(DelayTime & 0x01)) {
 875                         Delay = (unsigned short)ROMAddr[0x17e];
 876                      } else {
 877                         Delay = (unsigned short)ROMAddr[0x17f];
 878                      }
 879                   }
 880                }
 881             }
 882             SiS_ShortDelay(SiS_Pr, Delay);
 883          }
 884 
 885       } else if(SiS_Pr->SiS_VBType & VB_SISVB) {                        /* 315 series, all bridges */
 886 
 887          DelayIndex = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
 888          if(!(DelayTime & 0x01)) {
 889             Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
 890          } else {
 891             Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
 892          }
 893          Delay <<= 8;
 894          SiS_DDC2Delay(SiS_Pr, Delay);
 895 
 896       }
 897 
 898 #endif /* CONFIG_FB_SIS_315 */
 899 
 900    }
 901 }
 902 
 903 #ifdef CONFIG_FB_SIS_315
 904 static void
 905 SiS_PanelDelayLoop(struct SiS_Private *SiS_Pr, unsigned short DelayTime, unsigned short DelayLoop)
 906 {
 907    int i;
 908    for(i = 0; i < DelayLoop; i++) {
 909       SiS_PanelDelay(SiS_Pr, DelayTime);
 910    }
 911 }
 912 #endif
 913 
 914 /*********************************************/
 915 /*    HELPER: WAIT-FOR-RETRACE FUNCTIONS     */
 916 /*********************************************/
 917 
 918 void
 919 SiS_WaitRetrace1(struct SiS_Private *SiS_Pr)
 920 {
 921    unsigned short watchdog;
 922 
 923    if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
 924    if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80)) return;
 925 
 926    watchdog = 65535;
 927    while((SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
 928    watchdog = 65535;
 929    while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
 930 }
 931 
 932 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
 933 static void
 934 SiS_WaitRetrace2(struct SiS_Private *SiS_Pr, unsigned short reg)
 935 {
 936    unsigned short watchdog;
 937 
 938    watchdog = 65535;
 939    while((SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02) && --watchdog);
 940    watchdog = 65535;
 941    while((!(SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02)) && --watchdog);
 942 }
 943 #endif
 944 
 945 static void
 946 SiS_WaitVBRetrace(struct SiS_Private *SiS_Pr)
 947 {
 948    if(SiS_Pr->ChipType < SIS_315H) {
 949 #ifdef CONFIG_FB_SIS_300
 950       if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
 951          if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return;
 952       }
 953       if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x80)) {
 954          SiS_WaitRetrace1(SiS_Pr);
 955       } else {
 956          SiS_WaitRetrace2(SiS_Pr, 0x25);
 957       }
 958 #endif
 959    } else {
 960 #ifdef CONFIG_FB_SIS_315
 961       if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) {
 962          SiS_WaitRetrace1(SiS_Pr);
 963       } else {
 964          SiS_WaitRetrace2(SiS_Pr, 0x30);
 965       }
 966 #endif
 967    }
 968 }
 969 
 970 static void
 971 SiS_VBWait(struct SiS_Private *SiS_Pr)
 972 {
 973    unsigned short tempal,temp,i,j;
 974 
 975    temp = 0;
 976    for(i = 0; i < 3; i++) {
 977      for(j = 0; j < 100; j++) {
 978         tempal = SiS_GetRegByte(SiS_Pr->SiS_P3da);
 979         if(temp & 0x01) {
 980            if((tempal & 0x08))  continue;
 981            else break;
 982         } else {
 983            if(!(tempal & 0x08)) continue;
 984            else break;
 985         }
 986      }
 987      temp ^= 0x01;
 988    }
 989 }
 990 
 991 static void
 992 SiS_VBLongWait(struct SiS_Private *SiS_Pr)
 993 {
 994    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
 995       SiS_VBWait(SiS_Pr);
 996    } else {
 997       SiS_WaitRetrace1(SiS_Pr);
 998    }
 999 }
1000 
1001 /*********************************************/
1002 /*               HELPER: MISC                */
1003 /*********************************************/
1004 
1005 #ifdef CONFIG_FB_SIS_300
1006 static bool
1007 SiS_Is301B(struct SiS_Private *SiS_Pr)
1008 {
1009    if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01) >= 0xb0) return true;
1010    return false;
1011 }
1012 #endif
1013 
1014 static bool
1015 SiS_CRT2IsLCD(struct SiS_Private *SiS_Pr)
1016 {
1017    if(SiS_Pr->ChipType == SIS_730) {
1018       if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x20) return true;
1019    }
1020    if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & 0x20) return true;
1021    return false;
1022 }
1023 
1024 bool
1025 SiS_IsDualEdge(struct SiS_Private *SiS_Pr)
1026 {
1027 #ifdef CONFIG_FB_SIS_315
1028    if(SiS_Pr->ChipType >= SIS_315H) {
1029       if((SiS_Pr->ChipType != SIS_650) || (SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) {
1030          if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableDualEdge) return true;
1031       }
1032    }
1033 #endif
1034    return false;
1035 }
1036 
1037 bool
1038 SiS_IsVAMode(struct SiS_Private *SiS_Pr)
1039 {
1040 #ifdef CONFIG_FB_SIS_315
1041    unsigned short flag;
1042 
1043    if(SiS_Pr->ChipType >= SIS_315H) {
1044       flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1045       if((flag & EnableDualEdge) && (flag & SetToLCDA)) return true;
1046    }
1047 #endif
1048    return false;
1049 }
1050 
1051 #ifdef CONFIG_FB_SIS_315
1052 static bool
1053 SiS_IsVAorLCD(struct SiS_Private *SiS_Pr)
1054 {
1055    if(SiS_IsVAMode(SiS_Pr))  return true;
1056    if(SiS_CRT2IsLCD(SiS_Pr)) return true;
1057    return false;
1058 }
1059 #endif
1060 
1061 static bool
1062 SiS_IsDualLink(struct SiS_Private *SiS_Pr)
1063 {
1064 #ifdef CONFIG_FB_SIS_315
1065    if(SiS_Pr->ChipType >= SIS_315H) {
1066       if((SiS_CRT2IsLCD(SiS_Pr)) ||
1067          (SiS_IsVAMode(SiS_Pr))) {
1068          if(SiS_Pr->SiS_LCDInfo & LCDDualLink) return true;
1069       }
1070    }
1071 #endif
1072    return false;
1073 }
1074 
1075 #ifdef CONFIG_FB_SIS_315
1076 static bool
1077 SiS_TVEnabled(struct SiS_Private *SiS_Pr)
1078 {
1079    if((SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) != 0x0c) return true;
1080    if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1081       if(SiS_GetReg(SiS_Pr->SiS_Part2Port,0x4d) & 0x10) return true;
1082    }
1083    return false;
1084 }
1085 #endif
1086 
1087 #ifdef CONFIG_FB_SIS_315
1088 static bool
1089 SiS_LCDAEnabled(struct SiS_Private *SiS_Pr)
1090 {
1091    if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) return true;
1092    return false;
1093 }
1094 #endif
1095 
1096 #ifdef CONFIG_FB_SIS_315
1097 static bool
1098 SiS_WeHaveBacklightCtrl(struct SiS_Private *SiS_Pr)
1099 {
1100    if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
1101       if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0x10) return true;
1102    }
1103    return false;
1104 }
1105 #endif
1106 
1107 #ifdef CONFIG_FB_SIS_315
1108 static bool
1109 SiS_IsNotM650orLater(struct SiS_Private *SiS_Pr)
1110 {
1111    unsigned short flag;
1112 
1113    if(SiS_Pr->ChipType == SIS_650) {
1114       flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0;
1115       /* Check for revision != A0 only */
1116       if((flag == 0xe0) || (flag == 0xc0) ||
1117          (flag == 0xb0) || (flag == 0x90)) return false;
1118    } else if(SiS_Pr->ChipType >= SIS_661) return false;
1119    return true;
1120 }
1121 #endif
1122 
1123 #ifdef CONFIG_FB_SIS_315
1124 static bool
1125 SiS_IsYPbPr(struct SiS_Private *SiS_Pr)
1126 {
1127    if(SiS_Pr->ChipType >= SIS_315H) {
1128       /* YPrPb = 0x08 */
1129       if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHYPbPr) return true;
1130    }
1131    return false;
1132 }
1133 #endif
1134 
1135 #ifdef CONFIG_FB_SIS_315
1136 static bool
1137 SiS_IsChScart(struct SiS_Private *SiS_Pr)
1138 {
1139    if(SiS_Pr->ChipType >= SIS_315H) {
1140       /* Scart = 0x04 */
1141       if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHScart) return true;
1142    }
1143    return false;
1144 }
1145 #endif
1146 
1147 #ifdef CONFIG_FB_SIS_315
1148 static bool
1149 SiS_IsTVOrYPbPrOrScart(struct SiS_Private *SiS_Pr)
1150 {
1151    unsigned short flag;
1152 
1153    if(SiS_Pr->ChipType >= SIS_315H) {
1154       flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
1155       if(flag & SetCRT2ToTV)        return true;
1156       flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1157       if(flag & EnableCHYPbPr)      return true;  /* = YPrPb = 0x08 */
1158       if(flag & EnableCHScart)      return true;  /* = Scart = 0x04 - TW */
1159    } else {
1160       flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
1161       if(flag & SetCRT2ToTV)        return true;
1162    }
1163    return false;
1164 }
1165 #endif
1166 
1167 #ifdef CONFIG_FB_SIS_315
1168 static bool
1169 SiS_IsLCDOrLCDA(struct SiS_Private *SiS_Pr)
1170 {
1171    unsigned short flag;
1172 
1173    if(SiS_Pr->ChipType >= SIS_315H) {
1174       flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
1175       if(flag & SetCRT2ToLCD) return true;
1176       flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1177       if(flag & SetToLCDA)    return true;
1178    } else {
1179       flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
1180       if(flag & SetCRT2ToLCD) return true;
1181    }
1182    return false;
1183 }
1184 #endif
1185 
1186 static bool
1187 SiS_HaveBridge(struct SiS_Private *SiS_Pr)
1188 {
1189    unsigned short flag;
1190 
1191    if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1192       return true;
1193    } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
1194       flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
1195       if((flag == 1) || (flag == 2)) return true;
1196    }
1197    return false;
1198 }
1199 
1200 static bool
1201 SiS_BridgeIsEnabled(struct SiS_Private *SiS_Pr)
1202 {
1203    unsigned short flag;
1204 
1205    if(SiS_HaveBridge(SiS_Pr)) {
1206       flag = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
1207       if(SiS_Pr->ChipType < SIS_315H) {
1208         flag &= 0xa0;
1209         if((flag == 0x80) || (flag == 0x20)) return true;
1210       } else {
1211         flag &= 0x50;
1212         if((flag == 0x40) || (flag == 0x10)) return true;
1213       }
1214    }
1215    return false;
1216 }
1217 
1218 static bool
1219 SiS_BridgeInSlavemode(struct SiS_Private *SiS_Pr)
1220 {
1221    unsigned short flag1;
1222 
1223    flag1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
1224    if(flag1 & (SetInSlaveMode >> 8)) return true;
1225    return false;
1226 }
1227 
1228 /*********************************************/
1229 /*       GET VIDEO BRIDGE CONFIG INFO        */
1230 /*********************************************/
1231 
1232 /* Setup general purpose IO for Chrontel communication */
1233 #ifdef CONFIG_FB_SIS_300
1234 void
1235 SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo)
1236 {
1237    unsigned int   acpibase;
1238    unsigned short temp;
1239 
1240    if(!(SiS_Pr->SiS_ChSW)) return;
1241 
1242    acpibase = sisfb_read_lpc_pci_dword(SiS_Pr, 0x74);
1243    acpibase &= 0xFFFF;
1244    if(!acpibase) return;
1245    temp = SiS_GetRegShort((acpibase + 0x3c));   /* ACPI register 0x3c: GP Event 1 I/O mode select */
1246    temp &= 0xFEFF;
1247    SiS_SetRegShort((acpibase + 0x3c), temp);
1248    temp = SiS_GetRegShort((acpibase + 0x3c));
1249    temp = SiS_GetRegShort((acpibase + 0x3a));   /* ACPI register 0x3a: GP Pin Level (low/high) */
1250    temp &= 0xFEFF;
1251    if(!(myvbinfo & SetCRT2ToTV)) temp |= 0x0100;
1252    SiS_SetRegShort((acpibase + 0x3a), temp);
1253    temp = SiS_GetRegShort((acpibase + 0x3a));
1254 }
1255 #endif
1256 
1257 void
1258 SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
1259                 unsigned short ModeIdIndex, int checkcrt2mode)
1260 {
1261    unsigned short tempax, tempbx, temp;
1262    unsigned short modeflag, resinfo = 0;
1263 
1264    SiS_Pr->SiS_SetFlag = 0;
1265 
1266    modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
1267 
1268    SiS_Pr->SiS_ModeType = modeflag & ModeTypeMask;
1269 
1270    if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
1271       resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1272    }
1273 
1274    tempbx = 0;
1275 
1276    if(SiS_HaveBridge(SiS_Pr)) {
1277 
1278         temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
1279         tempbx |= temp;
1280         tempax = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) << 8;
1281         tempax &= (DriverMode | LoadDACFlag | SetNotSimuMode | SetPALTV);
1282         tempbx |= tempax;
1283 
1284 #ifdef CONFIG_FB_SIS_315
1285         if(SiS_Pr->ChipType >= SIS_315H) {
1286            if(SiS_Pr->SiS_VBType & VB_SISLCDA) {
1287               if(ModeNo == 0x03) {
1288                  /* Mode 0x03 is never in driver mode */
1289                  SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf);
1290               }
1291               if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8))) {
1292                  /* Reset LCDA setting if not driver mode */
1293                  SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
1294               }
1295               if(IS_SIS650) {
1296                  if(SiS_Pr->SiS_UseLCDA) {
1297                     if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) {
1298                        if((ModeNo <= 0x13) || (!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) {
1299                           SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA));
1300                        }
1301                     }
1302                  }
1303               }
1304               temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1305               if((temp & (EnableDualEdge | SetToLCDA)) == (EnableDualEdge | SetToLCDA)) {
1306                  tempbx |= SetCRT2ToLCDA;
1307               }
1308            }
1309 
1310            if(SiS_Pr->ChipType >= SIS_661) { /* New CR layout */
1311               tempbx &= ~(SetCRT2ToYPbPr525750 | SetCRT2ToHiVision);
1312               if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & 0x04) {
1313                  temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
1314                  if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
1315                  else if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1316                     tempbx |= SetCRT2ToYPbPr525750;
1317                  }
1318               }
1319            }
1320 
1321            if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1322               temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1323               if(temp & SetToLCDA) {
1324                  tempbx |= SetCRT2ToLCDA;
1325               }
1326               if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1327                  if(temp & EnableCHYPbPr) {
1328                     tempbx |= SetCRT2ToCHYPbPr;
1329                  }
1330               }
1331            }
1332         }
1333 
1334 #endif  /* CONFIG_FB_SIS_315 */
1335 
1336         if(!(SiS_Pr->SiS_VBType & VB_SISVGA2)) {
1337            tempbx &= ~(SetCRT2ToRAMDAC);
1338         }
1339 
1340         if(SiS_Pr->SiS_VBType & VB_SISVB) {
1341            temp = SetCRT2ToSVIDEO   |
1342                   SetCRT2ToAVIDEO   |
1343                   SetCRT2ToSCART    |
1344                   SetCRT2ToLCDA     |
1345                   SetCRT2ToLCD      |
1346                   SetCRT2ToRAMDAC   |
1347                   SetCRT2ToHiVision |
1348                   SetCRT2ToYPbPr525750;
1349         } else {
1350            if(SiS_Pr->ChipType >= SIS_315H) {
1351               if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1352                  temp = SetCRT2ToAVIDEO |
1353                         SetCRT2ToSVIDEO |
1354                         SetCRT2ToSCART  |
1355                         SetCRT2ToLCDA   |
1356                         SetCRT2ToLCD    |
1357                         SetCRT2ToCHYPbPr;
1358               } else {
1359                  temp = SetCRT2ToLCDA   |
1360                         SetCRT2ToLCD;
1361               }
1362            } else {
1363               if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1364                  temp = SetCRT2ToTV | SetCRT2ToLCD;
1365               } else {
1366                  temp = SetCRT2ToLCD;
1367               }
1368            }
1369         }
1370 
1371         if(!(tempbx & temp)) {
1372            tempax = DisableCRT2Display;
1373            tempbx = 0;
1374         }
1375 
1376         if(SiS_Pr->SiS_VBType & VB_SISVB) {
1377 
1378            unsigned short clearmask = ( DriverMode |
1379                                 DisableCRT2Display |
1380                                 LoadDACFlag        |
1381                                 SetNotSimuMode     |
1382                                 SetInSlaveMode     |
1383                                 SetPALTV           |
1384                                 SwitchCRT2         |
1385                                 SetSimuScanMode );
1386 
1387            if(tempbx & SetCRT2ToLCDA)        tempbx &= (clearmask | SetCRT2ToLCDA);
1388            if(tempbx & SetCRT2ToRAMDAC)      tempbx &= (clearmask | SetCRT2ToRAMDAC);
1389            if(tempbx & SetCRT2ToLCD)         tempbx &= (clearmask | SetCRT2ToLCD);
1390            if(tempbx & SetCRT2ToSCART)       tempbx &= (clearmask | SetCRT2ToSCART);
1391            if(tempbx & SetCRT2ToHiVision)    tempbx &= (clearmask | SetCRT2ToHiVision);
1392            if(tempbx & SetCRT2ToYPbPr525750) tempbx &= (clearmask | SetCRT2ToYPbPr525750);
1393 
1394         } else {
1395 
1396            if(SiS_Pr->ChipType >= SIS_315H) {
1397               if(tempbx & SetCRT2ToLCDA) {
1398                  tempbx &= (0xFF00|SwitchCRT2|SetSimuScanMode);
1399               }
1400            }
1401            if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1402               if(tempbx & SetCRT2ToTV) {
1403                  tempbx &= (0xFF00|SetCRT2ToTV|SwitchCRT2|SetSimuScanMode);
1404               }
1405            }
1406            if(tempbx & SetCRT2ToLCD) {
1407               tempbx &= (0xFF00|SetCRT2ToLCD|SwitchCRT2|SetSimuScanMode);
1408            }
1409            if(SiS_Pr->ChipType >= SIS_315H) {
1410               if(tempbx & SetCRT2ToLCDA) {
1411                  tempbx |= SetCRT2ToLCD;
1412               }
1413            }
1414 
1415         }
1416 
1417         if(tempax & DisableCRT2Display) {
1418            if(!(tempbx & (SwitchCRT2 | SetSimuScanMode))) {
1419               tempbx = SetSimuScanMode | DisableCRT2Display;
1420            }
1421         }
1422 
1423         if(!(tempbx & DriverMode)) tempbx |= SetSimuScanMode;
1424 
1425         /* LVDS/CHRONTEL (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */
1426         if(SiS_Pr->SiS_ModeType <= ModeVGA) {
1427            if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
1428                ((SiS_Pr->SiS_VBType & VB_NoLCD) && (tempbx & SetCRT2ToLCD)) ) {
1429               modeflag &= (~CRT2Mode);
1430            }
1431         }
1432 
1433         if(!(tempbx & SetSimuScanMode)) {
1434            if(tempbx & SwitchCRT2) {
1435               if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1436                  if(resinfo != SIS_RI_1600x1200) {
1437                     tempbx |= SetSimuScanMode;
1438                  }
1439               }
1440            } else {
1441               if(SiS_BridgeIsEnabled(SiS_Pr)) {
1442                  if(!(tempbx & DriverMode)) {
1443                     if(SiS_BridgeInSlavemode(SiS_Pr)) {
1444                        tempbx |= SetSimuScanMode;
1445                     }
1446                  }
1447               }
1448            }
1449         }
1450 
1451         if(!(tempbx & DisableCRT2Display)) {
1452            if(tempbx & DriverMode) {
1453               if(tempbx & SetSimuScanMode) {
1454                  if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1455                     if(resinfo != SIS_RI_1600x1200) {
1456                        tempbx |= SetInSlaveMode;
1457                     }
1458                  }
1459               }
1460            } else {
1461               tempbx |= SetInSlaveMode;
1462            }
1463         }
1464 
1465    }
1466 
1467    SiS_Pr->SiS_VBInfo = tempbx;
1468 
1469 #ifdef CONFIG_FB_SIS_300
1470    if(SiS_Pr->ChipType == SIS_630) {
1471       SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo);
1472    }
1473 #endif
1474 
1475 #if 0
1476    printk(KERN_DEBUG "sisfb: (init301: VBInfo= 0x%04x, SetFlag=0x%04x)\n",
1477       SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
1478 #endif
1479 }
1480 
1481 /*********************************************/
1482 /*           DETERMINE YPbPr MODE            */
1483 /*********************************************/
1484 
1485 void
1486 SiS_SetYPbPr(struct SiS_Private *SiS_Pr)
1487 {
1488 
1489    unsigned char temp;
1490 
1491    /* Note: This variable is only used on 30xLV systems.
1492     * CR38 has a different meaning on LVDS/CH7019 systems.
1493     * On 661 and later, these bits moved to CR35.
1494     *
1495     * On 301, 301B, only HiVision 1080i is supported.
1496     * On 30xLV, 301C, only YPbPr 1080i is supported.
1497     */
1498 
1499    SiS_Pr->SiS_YPbPr = 0;
1500    if(SiS_Pr->ChipType >= SIS_661) return;
1501 
1502    if(SiS_Pr->SiS_VBType) {
1503       if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1504          SiS_Pr->SiS_YPbPr = YPbPrHiVision;
1505       }
1506    }
1507 
1508    if(SiS_Pr->ChipType >= SIS_315H) {
1509       if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1510          temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1511          if(temp & 0x08) {
1512             switch((temp >> 4)) {
1513             case 0x00: SiS_Pr->SiS_YPbPr = YPbPr525i;     break;
1514             case 0x01: SiS_Pr->SiS_YPbPr = YPbPr525p;     break;
1515             case 0x02: SiS_Pr->SiS_YPbPr = YPbPr750p;     break;
1516             case 0x03: SiS_Pr->SiS_YPbPr = YPbPrHiVision; break;
1517             }
1518          }
1519       }
1520    }
1521 
1522 }
1523 
1524 /*********************************************/
1525 /*           DETERMINE TVMode flag           */
1526 /*********************************************/
1527 
1528 void
1529 SiS_SetTVMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
1530 {
1531    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
1532    unsigned short temp, temp1, resinfo = 0, romindex = 0;
1533    unsigned char  OutputSelect = *SiS_Pr->pSiS_OutputSelect;
1534 
1535    SiS_Pr->SiS_TVMode = 0;
1536 
1537    if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
1538    if(SiS_Pr->UseCustomMode) return;
1539 
1540    if(ModeNo > 0x13) {
1541       resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1542    }
1543 
1544    if(SiS_Pr->ChipType < SIS_661) {
1545 
1546       if(SiS_Pr->SiS_VBInfo & SetPALTV) SiS_Pr->SiS_TVMode |= TVSetPAL;
1547 
1548       if(SiS_Pr->SiS_VBType & VB_SISVB) {
1549          temp = 0;
1550          if((SiS_Pr->ChipType == SIS_630) ||
1551             (SiS_Pr->ChipType == SIS_730)) {
1552             temp = 0x35;
1553             romindex = 0xfe;
1554          } else if(SiS_Pr->ChipType >= SIS_315H) {
1555             temp = 0x38;
1556             if(SiS_Pr->ChipType < XGI_20) {
1557                romindex = 0xf3;
1558                if(SiS_Pr->ChipType >= SIS_330) romindex = 0x11b;
1559             }
1560          }
1561          if(temp) {
1562             if(romindex && SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
1563                OutputSelect = ROMAddr[romindex];
1564                if(!(OutputSelect & EnablePALMN)) {
1565                   SiS_SetRegAND(SiS_Pr->SiS_P3d4,temp,0x3F);
1566                }
1567             }
1568             temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,temp);
1569             if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1570                if(temp1 & EnablePALM) {         /* 0x40 */
1571                   SiS_Pr->SiS_TVMode |= TVSetPALM;
1572                   SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1573                } else if(temp1 & EnablePALN) {  /* 0x80 */
1574                   SiS_Pr->SiS_TVMode |= TVSetPALN;
1575                }
1576             } else {
1577                if(temp1 & EnableNTSCJ) {        /* 0x40 */
1578                   SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1579                }
1580             }
1581          }
1582          /* Translate HiVision/YPbPr to our new flags */
1583          if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1584             if(SiS_Pr->SiS_YPbPr == YPbPr750p)          SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1585             else if(SiS_Pr->SiS_YPbPr == YPbPr525p)     SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1586             else if(SiS_Pr->SiS_YPbPr == YPbPrHiVision) SiS_Pr->SiS_TVMode |= TVSetHiVision;
1587             else                                        SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1588             if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p | TVSetYPbPr525i)) {
1589                SiS_Pr->SiS_VBInfo &= ~SetCRT2ToHiVision;
1590                SiS_Pr->SiS_VBInfo |= SetCRT2ToYPbPr525750;
1591             } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
1592                SiS_Pr->SiS_TVMode |= TVSetPAL;
1593             }
1594          }
1595       } else if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1596          if(SiS_Pr->SiS_CHOverScan) {
1597             if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
1598                temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1599                if((temp & TVOverScan) || (SiS_Pr->SiS_CHOverScan == 1)) {
1600                   SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1601                }
1602             } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1603                temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79);
1604                if((temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1)) {
1605                   SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1606                }
1607             }
1608             if(SiS_Pr->SiS_CHSOverScan) {
1609                SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1610             }
1611          }
1612          if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1613             temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1614             if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1615                if(temp & EnablePALM)      SiS_Pr->SiS_TVMode |= TVSetPALM;
1616                else if(temp & EnablePALN) SiS_Pr->SiS_TVMode |= TVSetPALN;
1617             } else {
1618                if(temp & EnableNTSCJ) {
1619                   SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1620                }
1621             }
1622          }
1623       }
1624 
1625    } else {  /* 661 and later */
1626 
1627       temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1628       if(temp1 & 0x01) {
1629          SiS_Pr->SiS_TVMode |= TVSetPAL;
1630          if(temp1 & 0x08) {
1631             SiS_Pr->SiS_TVMode |= TVSetPALN;
1632          } else if(temp1 & 0x04) {
1633             if(SiS_Pr->SiS_VBType & VB_SISVB) {
1634                SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1635             }
1636             SiS_Pr->SiS_TVMode |= TVSetPALM;
1637          }
1638       } else {
1639          if(temp1 & 0x02) {
1640             SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1641          }
1642       }
1643       if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1644          if(SiS_Pr->SiS_CHOverScan) {
1645             if((temp1 & 0x10) || (SiS_Pr->SiS_CHOverScan == 1)) {
1646                SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1647             }
1648          }
1649       }
1650       if(SiS_Pr->SiS_VBType & VB_SISVB) {
1651          if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1652             temp1 &= 0xe0;
1653             if(temp1 == 0x00)      SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1654             else if(temp1 == 0x20) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1655             else if(temp1 == 0x40) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1656          } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1657             SiS_Pr->SiS_TVMode |= (TVSetHiVision | TVSetPAL);
1658          }
1659          if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750 | SetCRT2ToHiVision)) {
1660             if(resinfo == SIS_RI_800x480 || resinfo == SIS_RI_1024x576 || resinfo == SIS_RI_1280x720) {
1661                SiS_Pr->SiS_TVMode |= TVAspect169;
1662             } else {
1663                temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x39);
1664                if(temp1 & 0x02) {
1665                   if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetHiVision)) {
1666                      SiS_Pr->SiS_TVMode |= TVAspect169;
1667                   } else {
1668                      SiS_Pr->SiS_TVMode |= TVAspect43LB;
1669                   }
1670                } else {
1671                   SiS_Pr->SiS_TVMode |= TVAspect43;
1672                }
1673             }
1674          }
1675       }
1676    }
1677 
1678    if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) SiS_Pr->SiS_TVMode |= TVSetPAL;
1679 
1680    if(SiS_Pr->SiS_VBType & VB_SISVB) {
1681 
1682       if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1683          SiS_Pr->SiS_TVMode |= TVSetPAL;
1684          SiS_Pr->SiS_TVMode &= ~(TVSetPALM | TVSetPALN | TVSetNTSCJ);
1685       } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1686          if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525i | TVSetYPbPr525p | TVSetYPbPr750p)) {
1687             SiS_Pr->SiS_TVMode &= ~(TVSetPAL | TVSetNTSCJ | TVSetPALM | TVSetPALN);
1688          }
1689       }
1690 
1691       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
1692          if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
1693             SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
1694          }
1695       }
1696 
1697       if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
1698          if(resinfo == SIS_RI_1024x768) {
1699             if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
1700                SiS_Pr->SiS_TVMode |= TVSet525p1024;
1701             } else if(!(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p))) {
1702                SiS_Pr->SiS_TVMode |= TVSetNTSC1024;
1703             }
1704          }
1705       }
1706 
1707       SiS_Pr->SiS_TVMode |= TVRPLLDIV2XO;
1708       if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) &&
1709          (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
1710          SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1711       } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
1712          SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1713       } else if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) {
1714          if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
1715             SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1716          }
1717       }
1718 
1719    }
1720 
1721    SiS_Pr->SiS_VBInfo &= ~SetPALTV;
1722 }
1723 
1724 /*********************************************/
1725 /*               GET LCD INFO                */
1726 /*********************************************/
1727 
1728 static unsigned short
1729 SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr)
1730 {
1731    unsigned short temp = SiS_Pr->SiS_LCDResInfo;
1732    /* Translate my LCDResInfo to BIOS value */
1733    switch(temp) {
1734    case Panel_1280x768_2: temp = Panel_1280x768;    break;
1735    case Panel_1280x800_2: temp = Panel_1280x800;    break;
1736    case Panel_1280x854:   temp = Panel661_1280x854; break;
1737    }
1738    return temp;
1739 }
1740 
1741 static void
1742 SiS_GetLCDInfoBIOS(struct SiS_Private *SiS_Pr)
1743 {
1744 #ifdef CONFIG_FB_SIS_315
1745    unsigned char  *ROMAddr;
1746    unsigned short temp;
1747 
1748    if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
1749       if((temp = SISGETROMW(6)) != SiS_Pr->PanelHT) {
1750          SiS_Pr->SiS_NeedRomModeData = true;
1751          SiS_Pr->PanelHT  = temp;
1752       }
1753       if((temp = SISGETROMW(8)) != SiS_Pr->PanelVT) {
1754          SiS_Pr->SiS_NeedRomModeData = true;
1755          SiS_Pr->PanelVT  = temp;
1756       }
1757       SiS_Pr->PanelHRS = SISGETROMW(10);
1758       SiS_Pr->PanelHRE = SISGETROMW(12);
1759       SiS_Pr->PanelVRS = SISGETROMW(14);
1760       SiS_Pr->PanelVRE = SISGETROMW(16);
1761       SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
1762       SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].CLOCK =
1763          SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].CLOCK = (unsigned short)((unsigned char)ROMAddr[18]);
1764       SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2B =
1765          SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_A = ROMAddr[19];
1766       SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2C =
1767          SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_B = ROMAddr[20];
1768 
1769    }
1770 #endif
1771 }
1772 
1773 static void
1774 SiS_CheckScaling(struct SiS_Private *SiS_Pr, unsigned short resinfo,
1775                         const unsigned char *nonscalingmodes)
1776 {
1777    int i = 0;
1778    while(nonscalingmodes[i] != 0xff) {
1779       if(nonscalingmodes[i++] == resinfo) {
1780          if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ||
1781             (SiS_Pr->UsePanelScaler == -1)) {
1782             SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1783          }
1784          break;
1785       }
1786    }
1787 }
1788 
1789 void
1790 SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
1791 {
1792   unsigned short temp,modeflag,resinfo=0,modexres=0,modeyres=0;
1793   bool panelcanscale = false;
1794 #ifdef CONFIG_FB_SIS_300
1795   unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
1796   static const unsigned char SiS300SeriesLCDRes[] =
1797           { 0,  1,  2,  3,  7,  4,  5,  8,
1798             0,  0, 10,  0,  0,  0,  0, 15 };
1799 #endif
1800 #ifdef CONFIG_FB_SIS_315
1801   unsigned char   *myptr = NULL;
1802 #endif
1803 
1804   SiS_Pr->SiS_LCDResInfo  = 0;
1805   SiS_Pr->SiS_LCDTypeInfo = 0;
1806   SiS_Pr->SiS_LCDInfo     = 0;
1807   SiS_Pr->PanelHRS        = 999; /* HSync start */
1808   SiS_Pr->PanelHRE        = 999; /* HSync end */
1809   SiS_Pr->PanelVRS        = 999; /* VSync start */
1810   SiS_Pr->PanelVRE        = 999; /* VSync end */
1811   SiS_Pr->SiS_NeedRomModeData = false;
1812 
1813   /* Alternative 1600x1200@60 timing for 1600x1200 LCDA */
1814   SiS_Pr->Alternate1600x1200 = false;
1815 
1816   if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return;
1817 
1818   modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
1819 
1820   if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
1821      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1822      modexres = SiS_Pr->SiS_ModeResInfo[resinfo].HTotal;
1823      modeyres = SiS_Pr->SiS_ModeResInfo[resinfo].VTotal;
1824   }
1825 
1826   temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
1827 
1828   /* For broken BIOSes: Assume 1024x768 */
1829   if(temp == 0) temp = 0x02;
1830 
1831   if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
1832      SiS_Pr->SiS_LCDTypeInfo = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x7c) >> 2;
1833   } else if((SiS_Pr->ChipType < SIS_315H) || (SiS_Pr->ChipType >= SIS_661)) {
1834      SiS_Pr->SiS_LCDTypeInfo = temp >> 4;
1835   } else {
1836      SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1;
1837   }
1838   temp &= 0x0f;
1839 #ifdef CONFIG_FB_SIS_300
1840   if(SiS_Pr->ChipType < SIS_315H) {
1841      /* Very old BIOSes only know 7 sizes (NetVista 2179, 1.01g) */
1842      if(SiS_Pr->SiS_VBType & VB_SIS301) {
1843         if(temp < 0x0f) temp &= 0x07;
1844      }
1845      /* Translate 300 series LCDRes to 315 series for unified usage */
1846      temp = SiS300SeriesLCDRes[temp];
1847   }
1848 #endif
1849 
1850   /* Translate to our internal types */
1851 #ifdef CONFIG_FB_SIS_315
1852   if(SiS_Pr->ChipType == SIS_550) {
1853      if     (temp == Panel310_1152x768)  temp = Panel_320x240_2; /* Verified working */
1854      else if(temp == Panel310_320x240_2) temp = Panel_320x240_2;
1855      else if(temp == Panel310_320x240_3) temp = Panel_320x240_3;
1856   } else if(SiS_Pr->ChipType >= SIS_661) {
1857      if(temp == Panel661_1280x854)       temp = Panel_1280x854;
1858   }
1859 #endif
1860 
1861   if(SiS_Pr->SiS_VBType & VB_SISLVDS) {         /* SiS LVDS */
1862      if(temp == Panel310_1280x768) {
1863         temp = Panel_1280x768_2;
1864      }
1865      if(SiS_Pr->SiS_ROMNew) {
1866         if(temp == Panel661_1280x800) {
1867            temp = Panel_1280x800_2;
1868         }
1869      }
1870   }
1871 
1872   SiS_Pr->SiS_LCDResInfo = temp;
1873 
1874 #ifdef CONFIG_FB_SIS_300
1875   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1876      if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
1877         SiS_Pr->SiS_LCDResInfo = Panel_Barco1366;
1878      } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
1879         SiS_Pr->SiS_LCDResInfo = Panel_848x480;
1880      } else if(SiS_Pr->SiS_CustomT == CUT_PANEL856) {
1881         SiS_Pr->SiS_LCDResInfo = Panel_856x480;
1882      }
1883   }
1884 #endif
1885 
1886   if(SiS_Pr->SiS_VBType & VB_SISVB) {
1887      if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)
1888         SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMin301;
1889   } else {
1890      if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMinLVDS)
1891         SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS;
1892   }
1893 
1894   temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
1895   SiS_Pr->SiS_LCDInfo = temp & ~0x000e;
1896   /* Need temp below! */
1897 
1898   /* These must/can't scale no matter what */
1899   switch(SiS_Pr->SiS_LCDResInfo) {
1900   case Panel_320x240_1:
1901   case Panel_320x240_2:
1902   case Panel_320x240_3:
1903   case Panel_1280x960:
1904       SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1905       break;
1906   case Panel_640x480:
1907       SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1908   }
1909 
1910   panelcanscale = (bool)(SiS_Pr->SiS_LCDInfo & DontExpandLCD);
1911 
1912   if(!SiS_Pr->UsePanelScaler)          SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1913   else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1914 
1915   /* Dual link, Pass 1:1 BIOS default, etc. */
1916 #ifdef CONFIG_FB_SIS_315
1917   if(SiS_Pr->ChipType >= SIS_661) {
1918      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1919         if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1920      }
1921      if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1922         if(SiS_Pr->SiS_ROMNew) {
1923            if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1924         } else if((myptr = GetLCDStructPtr661(SiS_Pr))) {
1925            if(myptr[2] & 0x01) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1926         }
1927      }
1928   } else if(SiS_Pr->ChipType >= SIS_315H) {
1929      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1930         if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1931      }
1932      if((SiS_Pr->SiS_ROMNew) && (!(SiS_Pr->PanelSelfDetected))) {
1933         SiS_Pr->SiS_LCDInfo &= ~(LCDRGB18Bit);
1934         temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1935         if(temp & 0x01) SiS_Pr->SiS_LCDInfo |= LCDRGB18Bit;
1936         if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1937            if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1938         }
1939      } else if(!(SiS_Pr->SiS_ROMNew)) {
1940         if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1941            if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) &&
1942               (SiS_Pr->SiS_LCDResInfo == Panel_1024x768)) {
1943               SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1944            }
1945            if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
1946               (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
1947               (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
1948               (SiS_Pr->SiS_LCDResInfo == Panel_1680x1050)) {
1949               SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1950            }
1951         }
1952      }
1953   }
1954 #endif
1955 
1956   /* Pass 1:1 */
1957   if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
1958      /* Always center screen on LVDS (if scaling is disabled) */
1959      SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1960   } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
1961      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
1962         /* Always center screen on SiS LVDS (if scaling is disabled) */
1963         SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1964      } else {
1965         /* By default, pass 1:1 on SiS TMDS (if scaling is supported) */
1966         if(panelcanscale)             SiS_Pr->SiS_LCDInfo |= LCDPass11;
1967         if(SiS_Pr->CenterScreen == 1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1968      }
1969   }
1970 
1971   SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1972   SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1973 
1974   switch(SiS_Pr->SiS_LCDResInfo) {
1975      case Panel_320x240_1:
1976      case Panel_320x240_2:
1977      case Panel_320x240_3:  SiS_Pr->PanelXRes =  640; SiS_Pr->PanelYRes =  480;
1978                             SiS_Pr->PanelVRS  =   24; SiS_Pr->PanelVRE  =    3;
1979                             SiS_Pr->PanelVCLKIdx300 = VCLK28;
1980                             SiS_Pr->PanelVCLKIdx315 = VCLK28;
1981                             break;
1982      case Panel_640x480:    SiS_Pr->PanelXRes =  640; SiS_Pr->PanelYRes =  480;
1983                                                       SiS_Pr->PanelVRE  =    3;
1984                             SiS_Pr->PanelVCLKIdx300 = VCLK28;
1985                             SiS_Pr->PanelVCLKIdx315 = VCLK28;
1986                             break;
1987      case Panel_800x600:    SiS_Pr->PanelXRes =  800; SiS_Pr->PanelYRes =  600;
1988                             SiS_Pr->PanelHT   = 1056; SiS_Pr->PanelVT   =  628;
1989                             SiS_Pr->PanelHRS  =   40; SiS_Pr->PanelHRE  =  128;
1990                             SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    4;
1991                             SiS_Pr->PanelVCLKIdx300 = VCLK40;
1992                             SiS_Pr->PanelVCLKIdx315 = VCLK40;
1993                             break;
1994      case Panel_1024x600:   SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  600;
1995                             SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  800;
1996                             SiS_Pr->PanelHRS  =   24; SiS_Pr->PanelHRE  =  136;
1997                             SiS_Pr->PanelVRS  =    2 /* 88 */ ; SiS_Pr->PanelVRE  =    6;
1998                             SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1999                             SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
2000                             break;
2001      case Panel_1024x768:   SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  768;
2002                             SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  806;
2003                             SiS_Pr->PanelHRS  =   24; SiS_Pr->PanelHRE  =  136;
2004                             SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
2005                             if(SiS_Pr->ChipType < SIS_315H) {
2006                                SiS_Pr->PanelHRS = 23;
2007                                                       SiS_Pr->PanelVRE  =    5;
2008                             }
2009                             SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
2010                             SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
2011                             SiS_GetLCDInfoBIOS(SiS_Pr);
2012                             break;
2013      case Panel_1152x768:   SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes =  768;
2014                             SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  806;
2015                             SiS_Pr->PanelHRS  =   24; SiS_Pr->PanelHRE  =  136;
2016                             SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
2017                             if(SiS_Pr->ChipType < SIS_315H) {
2018                                SiS_Pr->PanelHRS = 23;
2019                                                       SiS_Pr->PanelVRE  =    5;
2020                             }
2021                             SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
2022                             SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
2023                             break;
2024      case Panel_1152x864:   SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes =  864;
2025                             break;
2026      case Panel_1280x720:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  720;
2027                             SiS_Pr->PanelHT   = 1650; SiS_Pr->PanelVT   =  750;
2028                             SiS_Pr->PanelHRS  =  110; SiS_Pr->PanelHRE  =   40;
2029                             SiS_Pr->PanelVRS  =    5; SiS_Pr->PanelVRE  =    5;
2030                             SiS_Pr->PanelVCLKIdx315 = VCLK_1280x720;
2031                             /* Data above for TMDS (projector); get from BIOS for LVDS */
2032                             SiS_GetLCDInfoBIOS(SiS_Pr);
2033                             break;
2034      case Panel_1280x768:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  768;
2035                             if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2036                                SiS_Pr->PanelHT   = 1408; SiS_Pr->PanelVT   =  806;
2037                                SiS_Pr->PanelVCLKIdx300 = VCLK81_300; /* ? */
2038                                SiS_Pr->PanelVCLKIdx315 = VCLK81_315; /* ? */
2039                             } else {
2040                                SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   =  802;
2041                                SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112;
2042                                SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
2043                                SiS_Pr->PanelVCLKIdx300 = VCLK81_300;
2044                                SiS_Pr->PanelVCLKIdx315 = VCLK81_315;
2045                             }
2046                             break;
2047      case Panel_1280x768_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  768;
2048                             SiS_Pr->PanelHT   = 1660; SiS_Pr->PanelVT   =  806;
2049                             SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112;
2050                             SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
2051                             SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_2;
2052                             SiS_GetLCDInfoBIOS(SiS_Pr);
2053                             break;
2054      case Panel_1280x800:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  800;
2055                             SiS_Pr->PanelHT   = 1408; SiS_Pr->PanelVT   =  816;
2056                             SiS_Pr->PanelHRS   =  21; SiS_Pr->PanelHRE  =   24;
2057                             SiS_Pr->PanelVRS   =   4; SiS_Pr->PanelVRE  =    3;
2058                             SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315;
2059                             SiS_GetLCDInfoBIOS(SiS_Pr);
2060                             break;
2061      case Panel_1280x800_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  800;
2062                             SiS_Pr->PanelHT   = 1552; SiS_Pr->PanelVT   =  812;
2063                             SiS_Pr->PanelHRS   =  48; SiS_Pr->PanelHRE  =  112;
2064                             SiS_Pr->PanelVRS   =   4; SiS_Pr->PanelVRE  =    3;
2065                             SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315_2;
2066                             SiS_GetLCDInfoBIOS(SiS_Pr);
2067                             break;
2068      case Panel_1280x854:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  854;
2069                             SiS_Pr->PanelHT   = 1664; SiS_Pr->PanelVT   =  861;
2070                             SiS_Pr->PanelHRS   =  16; SiS_Pr->PanelHRE  =  112;
2071                             SiS_Pr->PanelVRS   =   1; SiS_Pr->PanelVRE  =    3;
2072                             SiS_Pr->PanelVCLKIdx315 = VCLK_1280x854;
2073                             SiS_GetLCDInfoBIOS(SiS_Pr);
2074                             break;
2075      case Panel_1280x960:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  960;
2076                             SiS_Pr->PanelHT   = 1800; SiS_Pr->PanelVT   = 1000;
2077                             SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
2078                             SiS_Pr->PanelVCLKIdx315 = VCLK108_3_315;
2079                             if(resinfo == SIS_RI_1280x1024) {
2080                                SiS_Pr->PanelVCLKIdx300 = VCLK100_300;
2081                                SiS_Pr->PanelVCLKIdx315 = VCLK100_315;
2082                             }
2083                             break;
2084      case Panel_1280x1024:  SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024;
2085                             SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   = 1066;
2086                             SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112;
2087                             SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    3;
2088                             SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
2089                             SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
2090                             SiS_GetLCDInfoBIOS(SiS_Pr);
2091                             break;
2092      case Panel_1400x1050:  SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050;
2093                             SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   = 1066;
2094                             SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112;
2095                             SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    3;
2096                             SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
2097                             SiS_GetLCDInfoBIOS(SiS_Pr);
2098                             break;
2099      case Panel_1600x1200:  SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200;
2100                             SiS_Pr->PanelHT   = 2160; SiS_Pr->PanelVT   = 1250;
2101                             SiS_Pr->PanelHRS  =   64; SiS_Pr->PanelHRE  =  192;
2102                             SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    3;
2103                             SiS_Pr->PanelVCLKIdx315 = VCLK162_315;
2104                             if(SiS_Pr->SiS_VBType & VB_SISTMDSLCDA) {
2105                                if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
2106                                   SiS_Pr->PanelHT  = 1760; SiS_Pr->PanelVT  = 1235;
2107                                   SiS_Pr->PanelHRS =   48; SiS_Pr->PanelHRE =   32;
2108                                   SiS_Pr->PanelVRS =    2; SiS_Pr->PanelVRE =    4;
2109                                   SiS_Pr->PanelVCLKIdx315 = VCLK130_315;
2110                                   SiS_Pr->Alternate1600x1200 = true;
2111                                }
2112                             } else if(SiS_Pr->SiS_IF_DEF_LVDS) {
2113                                SiS_Pr->PanelHT  = 2048; SiS_Pr->PanelVT  = 1320;
2114                                SiS_Pr->PanelHRS = SiS_Pr->PanelHRE = 999;
2115                                SiS_Pr->PanelVRS = SiS_Pr->PanelVRE = 999;
2116                             }
2117                             SiS_GetLCDInfoBIOS(SiS_Pr);
2118                             break;
2119      case Panel_1680x1050:  SiS_Pr->PanelXRes = 1680; SiS_Pr->PanelYRes = 1050;
2120                             SiS_Pr->PanelHT   = 1900; SiS_Pr->PanelVT   = 1066;
2121                             SiS_Pr->PanelHRS  =   26; SiS_Pr->PanelHRE  =   76;
2122                             SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
2123                             SiS_Pr->PanelVCLKIdx315 = VCLK121_315;
2124                             SiS_GetLCDInfoBIOS(SiS_Pr);
2125                             break;
2126      case Panel_Barco1366:  SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024;
2127                             SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   = 1066;
2128                             break;
2129      case Panel_848x480:    SiS_Pr->PanelXRes =  848; SiS_Pr->PanelYRes =  480;
2130                             SiS_Pr->PanelHT   = 1088; SiS_Pr->PanelVT   =  525;
2131                             break;
2132      case Panel_856x480:    SiS_Pr->PanelXRes =  856; SiS_Pr->PanelYRes =  480;
2133                             SiS_Pr->PanelHT   = 1088; SiS_Pr->PanelVT   =  525;
2134                             break;
2135      case Panel_Custom:     SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX;
2136                             SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY;
2137                             SiS_Pr->PanelHT   = SiS_Pr->CHTotal;
2138                             SiS_Pr->PanelVT   = SiS_Pr->CVTotal;
2139                             if(SiS_Pr->CP_PreferredIndex != -1) {
2140                                SiS_Pr->PanelXRes = SiS_Pr->CP_HDisplay[SiS_Pr->CP_PreferredIndex];
2141                                SiS_Pr->PanelYRes = SiS_Pr->CP_VDisplay[SiS_Pr->CP_PreferredIndex];
2142                                SiS_Pr->PanelHT   = SiS_Pr->CP_HTotal[SiS_Pr->CP_PreferredIndex];
2143                                SiS_Pr->PanelVT   = SiS_Pr->CP_VTotal[SiS_Pr->CP_PreferredIndex];
2144                                SiS_Pr->PanelHRS  = SiS_Pr->CP_HSyncStart[SiS_Pr->CP_PreferredIndex];
2145                                SiS_Pr->PanelHRE  = SiS_Pr->CP_HSyncEnd[SiS_Pr->CP_PreferredIndex];
2146                                SiS_Pr->PanelVRS  = SiS_Pr->CP_VSyncStart[SiS_Pr->CP_PreferredIndex];
2147                                SiS_Pr->PanelVRE  = SiS_Pr->CP_VSyncEnd[SiS_Pr->CP_PreferredIndex];
2148                                SiS_Pr->PanelHRS -= SiS_Pr->PanelXRes;
2149                                SiS_Pr->PanelHRE -= SiS_Pr->PanelHRS;
2150                                SiS_Pr->PanelVRS -= SiS_Pr->PanelYRes;
2151                                SiS_Pr->PanelVRE -= SiS_Pr->PanelVRS;
2152                                if(SiS_Pr->CP_PrefClock) {
2153                                   int idx;
2154                                   SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
2155                                   SiS_Pr->PanelVCLKIdx300 = VCLK_CUSTOM_300;
2156                                   if(SiS_Pr->ChipType < SIS_315H) idx = VCLK_CUSTOM_300;
2157                                   else                             idx = VCLK_CUSTOM_315;
2158                                   SiS_Pr->SiS_VCLKData[idx].CLOCK =
2159                                      SiS_Pr->SiS_VBVCLKData[idx].CLOCK = SiS_Pr->CP_PrefClock;
2160                                   SiS_Pr->SiS_VCLKData[idx].SR2B =
2161                                      SiS_Pr->SiS_VBVCLKData[idx].Part4_A = SiS_Pr->CP_PrefSR2B;
2162                                   SiS_Pr->SiS_VCLKData[idx].SR2C =
2163                                      SiS_Pr->SiS_VBVCLKData[idx].Part4_B = SiS_Pr->CP_PrefSR2C;
2164                                }
2165                             }
2166                             break;
2167      default:               SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  768;
2168                             SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  806;
2169                             break;
2170   }
2171 
2172   /* Special cases */
2173   if( (SiS_Pr->SiS_IF_DEF_FSTN)              ||
2174       (SiS_Pr->SiS_IF_DEF_DSTN)              ||
2175       (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
2176       (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
2177       (SiS_Pr->SiS_CustomT == CUT_PANEL848)  ||
2178       (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
2179      SiS_Pr->PanelHRS = 999;
2180      SiS_Pr->PanelHRE = 999;
2181   }
2182 
2183   if( (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
2184       (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
2185       (SiS_Pr->SiS_CustomT == CUT_PANEL848)  ||
2186       (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
2187      SiS_Pr->PanelVRS = 999;
2188      SiS_Pr->PanelVRE = 999;
2189   }
2190 
2191   /* DontExpand overrule */
2192   if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
2193 
2194      if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (modeflag & NoSupportLCDScale)) {
2195         /* No scaling for this mode on any panel (LCD=CRT2)*/
2196         SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2197      }
2198 
2199      switch(SiS_Pr->SiS_LCDResInfo) {
2200 
2201      case Panel_Custom:
2202      case Panel_1152x864:
2203      case Panel_1280x768:       /* TMDS only */
2204         SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2205         break;
2206 
2207      case Panel_800x600: {
2208         static const unsigned char nonscalingmodes[] = {
2209            SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, 0xff
2210         };
2211         SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2212         break;
2213      }
2214      case Panel_1024x768: {
2215         static const unsigned char nonscalingmodes[] = {
2216            SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2217            SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2218            0xff
2219         };
2220         SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2221         break;
2222      }
2223      case Panel_1280x720: {
2224         static const unsigned char nonscalingmodes[] = {
2225            SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2226            SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2227            0xff
2228         };
2229         SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2230         if(SiS_Pr->PanelHT == 1650) {
2231            SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2232         }
2233         break;
2234      }
2235      case Panel_1280x768_2: {  /* LVDS only */
2236         static const unsigned char nonscalingmodes[] = {
2237            SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2238            SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2239            SIS_RI_1152x768,0xff
2240         };
2241         SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2242         switch(resinfo) {
2243         case SIS_RI_1280x720:  if(SiS_Pr->UsePanelScaler == -1) {
2244                                   SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2245                                }
2246                                break;
2247         }
2248         break;
2249      }
2250      case Panel_1280x800: {     /* SiS TMDS special (Averatec 6200 series) */
2251         static const unsigned char nonscalingmodes[] = {
2252            SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2253            SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2254            SIS_RI_1152x768,SIS_RI_1280x720,SIS_RI_1280x768,0xff
2255         };
2256         SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2257         break;
2258      }
2259      case Panel_1280x800_2:  {  /* SiS LVDS */
2260         static const unsigned char nonscalingmodes[] = {
2261            SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2262            SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2263            SIS_RI_1152x768,0xff
2264         };
2265         SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2266         switch(resinfo) {
2267         case SIS_RI_1280x720:
2268         case SIS_RI_1280x768:  if(SiS_Pr->UsePanelScaler == -1) {
2269                                   SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2270                                }
2271                                break;
2272         }
2273         break;
2274      }
2275      case Panel_1280x854: {     /* SiS LVDS */
2276         static const unsigned char nonscalingmodes[] = {
2277            SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2278            SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2279            SIS_RI_1152x768,0xff
2280         };
2281         SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2282         switch(resinfo) {
2283         case SIS_RI_1280x720:
2284         case SIS_RI_1280x768:
2285         case SIS_RI_1280x800:  if(SiS_Pr->UsePanelScaler == -1) {
2286                                   SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2287                                }
2288                                break;
2289         }
2290         break;
2291      }
2292      case Panel_1280x960: {
2293         static const unsigned char nonscalingmodes[] = {
2294            SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2295            SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2296            SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2297            SIS_RI_1280x854,0xff
2298         };
2299         SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2300         break;
2301      }
2302      case Panel_1280x1024: {
2303         static const unsigned char nonscalingmodes[] = {
2304            SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2305            SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2306            SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2307            SIS_RI_1280x854,SIS_RI_1280x960,0xff
2308         };
2309         SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2310         break;
2311      }
2312      case Panel_1400x1050: {
2313         static const unsigned char nonscalingmodes[] = {
2314              SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2315              SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2316              SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x768,SIS_RI_1280x800,SIS_RI_1280x854,
2317              SIS_RI_1280x960,0xff
2318         };
2319         SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2320         switch(resinfo) {
2321         case SIS_RI_1280x720:  if(SiS_Pr->UsePanelScaler == -1) {
2322                                   SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2323                                }
2324                                break;
2325         case SIS_RI_1280x1024: SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2326                                break;
2327         }
2328         break;
2329      }
2330      case Panel_1600x1200: {
2331         static const unsigned char nonscalingmodes[] = {
2332              SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2333              SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2334              SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2335              SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,SIS_RI_1360x1024,0xff
2336         };
2337         SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2338         break;
2339      }
2340      case Panel_1680x1050: {
2341         static const unsigned char nonscalingmodes[] = {
2342              SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2343              SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2344              SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,
2345              SIS_RI_1360x1024,0xff
2346         };
2347         SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2348         break;
2349      }
2350      }
2351   }
2352 
2353 #ifdef CONFIG_FB_SIS_300
2354   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2355      if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
2356         SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20;   /* neg h/v sync, RGB24(D0 = 0) */
2357      }
2358   }
2359 
2360   if(SiS_Pr->ChipType < SIS_315H) {
2361      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2362         if(SiS_Pr->SiS_UseROM) {
2363            if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
2364               if(!(ROMAddr[0x235] & 0x02)) {
2365                  SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2366               }
2367            }
2368         }
2369      } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2370         if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
2371            SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2372         }
2373      }
2374   }
2375 #endif
2376 
2377   /* Special cases */
2378 
2379   if(modexres == SiS_Pr->PanelXRes && modeyres == SiS_Pr->PanelYRes) {
2380      SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2381   }
2382 
2383   if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
2384      SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2385   }
2386 
2387   switch(SiS_Pr->SiS_LCDResInfo) {
2388   case Panel_640x480:
2389      SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2390      break;
2391   case Panel_1280x800:
2392      /* Don't pass 1:1 by default (TMDS special) */
2393      if(SiS_Pr->CenterScreen == -1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2394      break;
2395   case Panel_1280x960:
2396      SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2397      break;
2398   case Panel_Custom:
2399      if((!SiS_Pr->CP_PrefClock) ||
2400         (modexres > SiS_Pr->PanelXRes) || (modeyres > SiS_Pr->PanelYRes)) {
2401         SiS_Pr->SiS_LCDInfo |= LCDPass11;
2402      }
2403      break;
2404   }
2405 
2406   if((SiS_Pr->UseCustomMode) || (SiS_Pr->SiS_CustomT == CUT_UNKNOWNLCD)) {
2407      SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2408   }
2409 
2410   /* (In)validate LCDPass11 flag */
2411   if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2412      SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2413   }
2414 
2415   /* LVDS DDA */
2416   if(!((SiS_Pr->ChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
2417 
2418      if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
2419         if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
2420            if(ModeNo == 0x12) {
2421               if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
2422                  SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2423               }
2424            } else if(ModeNo > 0x13) {
2425               if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
2426                  if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2427                     if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) {
2428                        SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2429                     }
2430                  }
2431               }
2432            }
2433         }
2434      }
2435 
2436      if(modeflag & HalfDCLK) {
2437         if(SiS_Pr->SiS_IF_DEF_TRUMPION == 1) {
2438            SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2439         } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
2440            SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2441         } else if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) {
2442            SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2443         } else if(ModeNo > 0x13) {
2444            if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
2445               if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2446            } else if(SiS_Pr->SiS_LCDResInfo == Panel_800x600) {
2447               if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2448            }
2449         }
2450      }
2451 
2452   }
2453 
2454   /* VESA timing */
2455   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2456      if(SiS_Pr->SiS_VBInfo & SetNotSimuMode) {
2457         SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2458      }
2459   } else {
2460      SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2461   }
2462 
2463 #if 0
2464   printk(KERN_DEBUG "sisfb: (LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n",
2465         SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo);
2466 #endif
2467 }
2468 
2469 /*********************************************/
2470 /*                 GET VCLK                  */
2471 /*********************************************/
2472 
2473 unsigned short
2474 SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
2475                 unsigned short RefreshRateTableIndex)
2476 {
2477   unsigned short CRT2Index, VCLKIndex = 0, VCLKIndexGEN = 0, VCLKIndexGENCRT = 0;
2478   unsigned short resinfo, tempbx;
2479   const unsigned char *CHTVVCLKPtr = NULL;
2480 
2481   if(ModeNo <= 0x13) {
2482      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
2483      CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2484      VCLKIndexGEN = (SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)) >> 2) & 0x03;
2485      VCLKIndexGENCRT = VCLKIndexGEN;
2486   } else {
2487      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2488      CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2489      VCLKIndexGEN = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
2490      VCLKIndexGENCRT = SiS_GetRefCRTVCLK(SiS_Pr, RefreshRateTableIndex,
2491                 (SiS_Pr->SiS_SetFlag & ProgrammingCRT2) ? SiS_Pr->SiS_UseWideCRT2 : SiS_Pr->SiS_UseWide);
2492   }
2493 
2494   if(SiS_Pr->SiS_VBType & VB_SISVB) {    /* 30x/B/LV */
2495 
2496      if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2497 
2498         CRT2Index >>= 6;
2499         if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {       /*  LCD */
2500 
2501            if(SiS_Pr->ChipType < SIS_315H) {
2502               VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2503               if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2504                  VCLKIndex = VCLKIndexGEN;
2505               }
2506            } else {
2507               VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2508               if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2509                  switch(resinfo) {
2510                  /* Correct those whose IndexGEN doesn't match VBVCLK array */
2511                  case SIS_RI_720x480:  VCLKIndex = VCLK_720x480;  break;
2512                  case SIS_RI_720x576:  VCLKIndex = VCLK_720x576;  break;
2513                  case SIS_RI_768x576:  VCLKIndex = VCLK_768x576;  break;
2514                  case SIS_RI_848x480:  VCLKIndex = VCLK_848x480;  break;
2515                  case SIS_RI_856x480:  VCLKIndex = VCLK_856x480;  break;
2516                  case SIS_RI_800x480:  VCLKIndex = VCLK_800x480;  break;
2517                  case SIS_RI_1024x576: VCLKIndex = VCLK_1024x576; break;
2518                  case SIS_RI_1152x864: VCLKIndex = VCLK_1152x864; break;
2519                  case SIS_RI_1280x720: VCLKIndex = VCLK_1280x720; break;
2520                  case SIS_RI_1360x768: VCLKIndex = VCLK_1360x768; break;
2521                  default:              VCLKIndex = VCLKIndexGEN;
2522                  }
2523 
2524                  if(ModeNo <= 0x13) {
2525                     if(SiS_Pr->ChipType <= SIS_315PRO) {
2526                        if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
2527                     } else {
2528                        if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x00;
2529                     }
2530                  }
2531                  if(SiS_Pr->ChipType <= SIS_315PRO) {
2532                     if(VCLKIndex == 0) VCLKIndex = 0x41;
2533                     if(VCLKIndex == 1) VCLKIndex = 0x43;
2534                     if(VCLKIndex == 4) VCLKIndex = 0x44;
2535                  }
2536               }
2537            }
2538 
2539         } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {                   /*  TV */
2540 
2541            if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
2542               if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO)        VCLKIndex = HiTVVCLKDIV2;
2543               else                                         VCLKIndex = HiTVVCLK;
2544               if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)     VCLKIndex = HiTVSimuVCLK;
2545            } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)  VCLKIndex = YPbPr750pVCLK;
2546            else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)    VCLKIndex = TVVCLKDIV2;
2547            else if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO)      VCLKIndex = TVVCLKDIV2;
2548            else                                            VCLKIndex = TVVCLK;
2549 
2550            if(SiS_Pr->ChipType < SIS_315H) VCLKIndex += TVCLKBASE_300;
2551            else                            VCLKIndex += TVCLKBASE_315;
2552 
2553         } else {                                                        /* VGA2 */
2554 
2555            VCLKIndex = VCLKIndexGENCRT;
2556            if(SiS_Pr->ChipType < SIS_315H) {
2557               if(ModeNo > 0x13) {
2558                  if( (SiS_Pr->ChipType == SIS_630) &&
2559                      (SiS_Pr->ChipRevision >= 0x30)) {
2560                     if(VCLKIndex == 0x14) VCLKIndex = 0x34;
2561                  }
2562                  /* Better VGA2 clock for 1280x1024@75 */
2563                  if(VCLKIndex == 0x17) VCLKIndex = 0x45;
2564               }
2565            }
2566         }
2567 
2568      } else {   /* If not programming CRT2 */
2569 
2570         VCLKIndex = VCLKIndexGENCRT;
2571         if(SiS_Pr->ChipType < SIS_315H) {
2572            if(ModeNo > 0x13) {
2573               if( (SiS_Pr->ChipType != SIS_630) &&
2574                   (SiS_Pr->ChipType != SIS_300) ) {
2575                  if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2576               }
2577            }
2578         }
2579      }
2580 
2581   } else {       /*   LVDS  */
2582 
2583      VCLKIndex = CRT2Index;
2584 
2585      if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2586 
2587         if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
2588 
2589            VCLKIndex &= 0x1f;
2590            tempbx = 0;
2591            if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2592            if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2593               tempbx += 2;
2594               if(SiS_Pr->SiS_ModeType > ModeVGA) {
2595                  if(SiS_Pr->SiS_CHSOverScan) tempbx = 8;
2596               }
2597               if(SiS_Pr->SiS_TVMode & TVSetPALM) {
2598                  tempbx = 4;
2599                  if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2600               } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
2601                  tempbx = 6;
2602                  if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2603               }
2604            }
2605            switch(tempbx) {
2606              case  0: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUNTSC;  break;
2607              case  1: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKONTSC;  break;
2608              case  2: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPAL;   break;
2609              case  3: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL;   break;
2610              case  4: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALM;  break;
2611              case  5: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALM;  break;
2612              case  6: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALN;  break;
2613              case  7: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALN;  break;
2614              case  8: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKSOPAL;  break;
2615              default: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL;   break;
2616            }
2617            VCLKIndex = CHTVVCLKPtr[VCLKIndex];
2618 
2619         } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2620 
2621            if(SiS_Pr->ChipType < SIS_315H) {
2622               VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2623            } else {
2624               VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2625            }
2626 
2627 #ifdef CONFIG_FB_SIS_300
2628            /* Special Timing: Barco iQ Pro R series */
2629            if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) VCLKIndex = 0x44;
2630 
2631            /* Special Timing: 848x480 and 856x480 parallel lvds panels */
2632            if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
2633               if(SiS_Pr->ChipType < SIS_315H) {
2634                  VCLKIndex = VCLK34_300;
2635                  /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2636               } else {
2637                  VCLKIndex = VCLK34_315;
2638                  /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2639               }
2640            }
2641 #endif
2642 
2643         } else {
2644 
2645            VCLKIndex = VCLKIndexGENCRT;
2646            if(SiS_Pr->ChipType < SIS_315H) {
2647               if(ModeNo > 0x13) {
2648                  if( (SiS_Pr->ChipType == SIS_630) &&
2649                      (SiS_Pr->ChipRevision >= 0x30) ) {
2650                     if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
2651                  }
2652               }
2653            }
2654         }
2655 
2656      } else {  /* if not programming CRT2 */
2657 
2658         VCLKIndex = VCLKIndexGENCRT;
2659         if(SiS_Pr->ChipType < SIS_315H) {
2660            if(ModeNo > 0x13) {
2661               if( (SiS_Pr->ChipType != SIS_630) &&
2662                   (SiS_Pr->ChipType != SIS_300) ) {
2663                  if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2664               }
2665 #if 0
2666               if(SiS_Pr->ChipType == SIS_730) {
2667                  if(VCLKIndex == 0x0b) VCLKIndex = 0x40;   /* 1024x768-70 */
2668                  if(VCLKIndex == 0x0d) VCLKIndex = 0x41;   /* 1024x768-75 */
2669               }
2670 #endif
2671            }
2672         }
2673 
2674      }
2675 
2676   }
2677 
2678   return VCLKIndex;
2679 }
2680 
2681 /*********************************************/
2682 /*        SET CRT2 MODE TYPE REGISTERS       */
2683 /*********************************************/
2684 
2685 static void
2686 SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2687 {
2688   unsigned short i, j, modeflag, tempah=0;
2689   short tempcl;
2690 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
2691   unsigned short tempbl;
2692 #endif
2693 #ifdef CONFIG_FB_SIS_315
2694   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
2695   unsigned short tempah2, tempbl2;
2696 #endif
2697 
2698   modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
2699 
2700   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
2701 
2702      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40);
2703      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2E,0xF7);
2704 
2705   } else {
2706 
2707      for(i=0,j=4; i<3; i++,j++) SiS_SetReg(SiS_Pr->SiS_Part1Port,j,0);
2708      if(SiS_Pr->ChipType >= SIS_315H) {
2709         SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0x7F);
2710      }
2711 
2712      tempcl = SiS_Pr->SiS_ModeType;
2713 
2714      if(SiS_Pr->ChipType < SIS_315H) {
2715 
2716 #ifdef CONFIG_FB_SIS_300    /* ---- 300 series ---- */
2717 
2718         /* For 301BDH: (with LCD via LVDS) */
2719         if(SiS_Pr->SiS_VBType & VB_NoLCD) {
2720            tempbl = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32);
2721            tempbl &= 0xef;
2722            tempbl |= 0x02;
2723            if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2724               tempbl |= 0x10;
2725               tempbl &= 0xfd;
2726            }
2727            SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,tempbl);
2728         }
2729 
2730         if(ModeNo > 0x13) {
2731            tempcl -= ModeVGA;
2732            if(tempcl >= 0) {
2733               tempah = ((0x10 >> tempcl) | 0x80);
2734            }
2735         } else tempah = 0x80;
2736 
2737         if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)  tempah ^= 0xA0;
2738 
2739 #endif  /* CONFIG_FB_SIS_300 */
2740 
2741      } else {
2742 
2743 #ifdef CONFIG_FB_SIS_315    /* ------- 315/330 series ------ */
2744 
2745         if(ModeNo > 0x13) {
2746            tempcl -= ModeVGA;
2747            if(tempcl >= 0) {
2748               tempah = (0x08 >> tempcl);
2749               if (tempah == 0) tempah = 1;
2750               tempah |= 0x40;
2751            }
2752         } else tempah = 0x40;
2753 
2754         if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50;
2755 
2756 #endif  /* CONFIG_FB_SIS_315 */
2757 
2758      }
2759 
2760      if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2761 
2762      if(SiS_Pr->ChipType < SIS_315H) {
2763         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2764      } else {
2765 #ifdef CONFIG_FB_SIS_315
2766         if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2767            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2768         } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
2769            if(IS_SIS740) {
2770               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2771            } else {
2772               SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2773            }
2774         }
2775 #endif
2776      }
2777 
2778      if(SiS_Pr->SiS_VBType & VB_SISVB) {
2779 
2780         tempah = 0x01;
2781         if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
2782            tempah |= 0x02;
2783         }
2784         if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2785            tempah ^= 0x05;
2786            if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
2787               tempah ^= 0x01;
2788            }
2789         }
2790 
2791         if(SiS_Pr->ChipType < SIS_315H) {
2792 
2793            if(SiS_Pr->SiS_VBInfo & DisableCRT2Display)  tempah = 0;
2794 
2795            tempah = (tempah << 5) & 0xFF;
2796            SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2797            tempah = (tempah >> 5) & 0xFF;
2798 
2799         } else {
2800 
2801            if(SiS_Pr->SiS_VBInfo & DisableCRT2Display)  tempah = 0x08;
2802            else if(!(SiS_IsDualEdge(SiS_Pr)))           tempah |= 0x08;
2803            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF0,tempah);
2804            tempah &= ~0x08;
2805 
2806         }
2807 
2808         if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
2809            tempah |= 0x10;
2810         }
2811 
2812         tempah |= 0x80;
2813         if(SiS_Pr->SiS_VBType & VB_SIS301) {
2814            if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah &= ~0x80;
2815         }
2816 
2817         if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2818            if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p))) {
2819               if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2820                  tempah |= 0x20;
2821               }
2822            }
2823         }
2824 
2825         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah);
2826 
2827         tempah = 0x80;
2828         if(SiS_Pr->SiS_VBType & VB_SIS301) {
2829            if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah = 0;
2830         }
2831 
2832         if(SiS_IsDualLink(SiS_Pr)) tempah |= 0x40;
2833 
2834         if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2835            if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) {
2836               tempah |= 0x40;
2837            }
2838         }
2839 
2840         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0C,tempah);
2841 
2842      } else {  /* LVDS */
2843 
2844         if(SiS_Pr->ChipType >= SIS_315H) {
2845 
2846 #ifdef CONFIG_FB_SIS_315
2847            /* LVDS can only be slave in 8bpp modes */
2848            tempah = 0x80;
2849            if((modeflag & CRT2Mode) && (SiS_Pr->SiS_ModeType > ModeVGA)) {
2850               if(SiS_Pr->SiS_VBInfo & DriverMode) {
2851                  tempah |= 0x02;
2852               }
2853            }
2854 
2855            if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))  tempah |= 0x02;
2856 
2857            if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)        tempah ^= 0x01;
2858 
2859            if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 1;
2860 
2861            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah);
2862 #endif
2863 
2864         } else {
2865 
2866 #ifdef CONFIG_FB_SIS_300
2867            tempah = 0;
2868            if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
2869               tempah |= 0x02;
2870            }
2871            tempah <<= 5;
2872 
2873            if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2874 
2875            SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2876 #endif
2877 
2878         }
2879 
2880      }
2881 
2882   }  /* LCDA */
2883 
2884   if(SiS_Pr->SiS_VBType & VB_SISVB) {
2885 
2886      if(SiS_Pr->ChipType >= SIS_315H) {
2887 
2888 #ifdef CONFIG_FB_SIS_315
2889         /* unsigned char bridgerev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01); */
2890 
2891         /* The following is nearly unpreditable and varies from machine
2892          * to machine. Especially the 301DH seems to be a real trouble
2893          * maker. Some BIOSes simply set the registers (like in the
2894          * NoLCD-if-statements here), some set them according to the
2895          * LCDA stuff. It is very likely that some machines are not
2896          * treated correctly in the following, very case-orientated
2897          * code. What do I do then...?
2898          */
2899 
2900         /* 740 variants match for 30xB, 301B-DH, 30xLV */
2901 
2902         if(!(IS_SIS740)) {
2903            tempah = 0x04;                                                  /* For all bridges */
2904            tempbl = 0xfb;
2905            if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2906               tempah = 0x00;
2907               if(SiS_IsDualEdge(SiS_Pr)) {
2908                  tempbl = 0xff;
2909               }
2910            }
2911            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2912         }
2913 
2914         /* The following two are responsible for eventually wrong colors
2915          * in TV output. The DH (VB_NoLCD) conditions are unknown; the
2916          * b0 was found in some 651 machine (Pim; P4_23=0xe5); the b1 version
2917          * in a 650 box (Jake). What is the criteria?
2918          * Addendum: Another combination 651+301B-DH(b1) (Rapo) needs same
2919          * treatment like the 651+301B-DH(b0) case. Seems more to be the
2920          * chipset than the bridge revision.
2921          */
2922 
2923         if((IS_SIS740) || (SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
2924            tempah = 0x30;
2925            tempbl = 0xc0;
2926            if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2927               ((SiS_Pr->SiS_ROMNew) && (!(ROMAddr[0x5b] & 0x04)))) {
2928               tempah = 0x00;
2929               tempbl = 0x00;
2930            }
2931            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,tempah);
2932            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,tempbl);
2933         } else if(SiS_Pr->SiS_VBType & VB_SIS301) {
2934            /* Fixes "TV-blue-bug" on 315+301 */
2935            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xcf);      /* For 301   */
2936            SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2937         } else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
2938            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);       /* For 30xLV */
2939            SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);
2940         } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {              /* For 301B-DH */
2941            tempah = 0x30; tempah2 = 0xc0;
2942            tempbl = 0xcf; tempbl2 = 0x3f;
2943            if(SiS_Pr->SiS_TVBlue == 0) {
2944                  tempah = tempah2 = 0x00;
2945            } else if(SiS_Pr->SiS_TVBlue == -1) {
2946               /* Set on 651/M650, clear on 315/650 */
2947               if(!(IS_SIS65x)) /* (bridgerev != 0xb0) */ {
2948                  tempah = tempah2 = 0x00;
2949               }
2950            }
2951            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2952            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2953         } else {
2954            tempah = 0x30; tempah2 = 0xc0;                      /* For 30xB, 301C */
2955            tempbl = 0xcf; tempbl2 = 0x3f;
2956            if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2957               tempah = tempah2 = 0x00;
2958               if(SiS_IsDualEdge(SiS_Pr)) {
2959                  tempbl = tempbl2 = 0xff;
2960               }
2961            }
2962            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2963            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2964         }
2965 
2966         if(IS_SIS740) {
2967            tempah = 0x80;
2968            if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x00;
2969            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,0x7f,tempah);
2970         } else {
2971            tempah = 0x00;
2972            tempbl = 0x7f;
2973            if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2974               tempbl = 0xff;
2975               if(!(SiS_IsDualEdge(SiS_Pr))) tempah = 0x80;
2976            }
2977            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
2978         }
2979 
2980 #endif /* CONFIG_FB_SIS_315 */
2981 
2982      } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2983 
2984 #ifdef CONFIG_FB_SIS_300
2985         SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2986 
2987         if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2988            ((SiS_Pr->SiS_VBType & VB_NoLCD) &&
2989             (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD))) {
2990            SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x23,0x7F);
2991         } else {
2992            SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x23,0x80);
2993         }
2994 #endif
2995 
2996      }
2997 
2998      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2999         SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x0D,0x80);
3000         if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
3001            SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3A,0xC0);
3002         }
3003      }
3004 
3005   } else {  /* LVDS */
3006 
3007 #ifdef CONFIG_FB_SIS_315
3008      if(SiS_Pr->ChipType >= SIS_315H) {
3009 
3010         if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
3011 
3012            tempah = 0x04;
3013            tempbl = 0xfb;
3014            if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3015               tempah = 0x00;
3016               if(SiS_IsDualEdge(SiS_Pr)) tempbl = 0xff;
3017            }
3018            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
3019 
3020            if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
3021               SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
3022            }
3023 
3024            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
3025 
3026         } else if(SiS_Pr->ChipType == SIS_550) {
3027 
3028            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
3029            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
3030 
3031         }
3032 
3033      }
3034 #endif
3035 
3036   }
3037 
3038 }
3039 
3040 /*********************************************/
3041 /*            GET RESOLUTION DATA            */
3042 /*********************************************/
3043 
3044 unsigned short
3045 SiS_GetResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
3046 {
3047    if(ModeNo <= 0x13)
3048       return ((unsigned short)SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo);
3049    else
3050       return ((unsigned short)SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO);
3051 }
3052 
3053 static void
3054 SiS_GetCRT2ResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
3055 {
3056    unsigned short xres, yres, modeflag=0, resindex;
3057 
3058    if(SiS_Pr->UseCustomMode) {
3059       xres = SiS_Pr->CHDisplay;
3060       if(SiS_Pr->CModeFlag & HalfDCLK) xres <<= 1;
3061       SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
3062       /* DoubleScanMode-check done in CheckCalcCustomMode()! */
3063       SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = SiS_Pr->CVDisplay;
3064       return;
3065    }
3066 
3067    resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex);
3068 
3069    if(ModeNo <= 0x13) {
3070       xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
3071       yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
3072    } else {
3073       xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
3074       yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
3075       modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3076    }
3077 
3078    if(!SiS_Pr->SiS_IF_DEF_DSTN && !SiS_Pr->SiS_IF_DEF_FSTN) {
3079 
3080       if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
3081          if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
3082             if(yres == 350) yres = 400;
3083          }
3084          if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
3085             if(ModeNo == 0x12) yres = 400;
3086          }
3087       }
3088 
3089       if(modeflag & HalfDCLK)       xres <<= 1;
3090       if(modeflag & DoubleScanMode) yres <<= 1;
3091 
3092    }
3093 
3094    if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
3095 
3096       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3097          switch(SiS_Pr->SiS_LCDResInfo) {
3098            case Panel_1024x768:
3099               if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
3100                  if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
3101                     if(yres == 350) yres = 357;
3102                     if(yres == 400) yres = 420;
3103                     if(yres == 480) yres = 525;
3104                  }
3105               }
3106               break;
3107            case Panel_1280x1024:
3108               if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
3109                  /* BIOS bug - does this regardless of scaling */
3110                  if(yres == 400) yres = 405;
3111               }
3112               if(yres == 350) yres = 360;
3113               if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
3114                  if(yres == 360) yres = 375;
3115               }
3116               break;
3117            case Panel_1600x1200:
3118               if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
3119                  if(yres == 1024) yres = 1056;
3120               }
3121               break;
3122          }
3123       }
3124 
3125    } else {
3126 
3127       if(SiS_Pr->SiS_VBType & VB_SISVB) {
3128          if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVision)) {
3129             if(xres == 720) xres = 640;
3130          }
3131       } else if(xres == 720) xres = 640;
3132 
3133       if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
3134          yres = 400;
3135          if(SiS_Pr->ChipType >= SIS_315H) {
3136             if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
3137          } else {
3138             if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
3139          }
3140          if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) yres = 480;
3141       }
3142 
3143    }
3144    SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
3145    SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
3146 }
3147 
3148 /*********************************************/
3149 /*           GET CRT2 TIMING DATA            */
3150 /*********************************************/
3151 
3152 static void
3153 SiS_GetCRT2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3154                unsigned short RefreshRateTableIndex, unsigned short *CRT2Index,
3155                unsigned short *ResIndex)
3156 {
3157   unsigned short tempbx=0, tempal=0, resinfo=0;
3158 
3159   if(ModeNo <= 0x13) {
3160      tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3161   } else {
3162      tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
3163      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
3164   }
3165 
3166   if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_IF_DEF_LVDS == 0)) {
3167 
3168      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {                            /* LCD */
3169 
3170         tempbx = SiS_Pr->SiS_LCDResInfo;
3171         if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 32;
3172 
3173         /* patch index */
3174         if(SiS_Pr->SiS_LCDResInfo == Panel_1680x1050) {
3175            if     (resinfo == SIS_RI_1280x800)  tempal =  9;
3176            else if(resinfo == SIS_RI_1400x1050) tempal = 11;
3177         } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x800) ||
3178                   (SiS_Pr->SiS_LCDResInfo == Panel_1280x800_2) ||
3179                   (SiS_Pr->SiS_LCDResInfo == Panel_1280x854)) {
3180            if     (resinfo == SIS_RI_1280x768)  tempal =  9;
3181         }
3182 
3183         if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3184            /* Pass 1:1 only (center-screen handled outside) */
3185            /* This is never called for the panel's native resolution */
3186            /* since Pass1:1 will not be set in this case */
3187            tempbx = 100;
3188            if(ModeNo >= 0x13) {
3189               tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
3190            }
3191         }
3192 
3193 #ifdef CONFIG_FB_SIS_315
3194         if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
3195            if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
3196               if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
3197                  tempbx = 200;
3198                  if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
3199               }
3200            }
3201         }
3202 #endif
3203 
3204      } else {                                                   /* TV */
3205 
3206         if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
3207            /* if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_TVMode &= (~TVSetTVSimuMode); */
3208            tempbx = 2;
3209            if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
3210               tempbx = 13;
3211               if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) tempbx = 14;
3212            }
3213         } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3214            if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)      tempbx = 7;
3215            else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempbx = 6;
3216            else                                         tempbx = 5;
3217            if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)     tempbx += 5;
3218         } else {
3219            if(SiS_Pr->SiS_TVMode & TVSetPAL)            tempbx = 3;
3220            else                                         tempbx = 4;
3221            if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)     tempbx += 5;
3222         }
3223 
3224      }
3225 
3226      tempal &= 0x3F;
3227 
3228      if(ModeNo > 0x13) {
3229         if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) {
3230            switch(resinfo) {
3231            case SIS_RI_720x480:
3232               tempal = 6;
3233               if(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetPALN))   tempal = 9;
3234               break;
3235            case SIS_RI_720x576:
3236            case SIS_RI_768x576:
3237            case SIS_RI_1024x576: /* Not in NTSC or YPBPR mode (except 1080i)! */
3238               tempal = 6;
3239               if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3240                  if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)        tempal = 8;
3241               }
3242               break;
3243            case SIS_RI_800x480:
3244               tempal = 4;
3245               break;
3246            case SIS_RI_512x384:
3247            case SIS_RI_1024x768:
3248               tempal = 7;
3249               if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3250                  if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)        tempal = 8;
3251               }
3252               break;
3253            case SIS_RI_1280x720:
3254               if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3255                  if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)        tempal = 9;
3256               }
3257               break;
3258            }
3259         }
3260      }
3261 
3262      *CRT2Index = tempbx;
3263      *ResIndex = tempal;
3264 
3265   } else {   /* LVDS, 301B-DH (if running on LCD) */
3266 
3267      tempbx = 0;
3268      if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
3269 
3270         tempbx = 90;
3271         if(SiS_Pr->SiS_TVMode & TVSetPAL) {
3272            tempbx = 92;
3273            if(SiS_Pr->SiS_ModeType > ModeVGA) {
3274               if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
3275            }
3276            if(SiS_Pr->SiS_TVMode & TVSetPALM)      tempbx = 94;
3277            else if(SiS_Pr->SiS_TVMode & TVSetPALN) tempbx = 96;
3278         }
3279         if(tempbx != 99) {
3280            if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx++;
3281         }
3282 
3283      } else {
3284 
3285         switch(SiS_Pr->SiS_LCDResInfo) {
3286         case Panel_640x480:   tempbx = 12; break;
3287         case Panel_320x240_1: tempbx = 10; break;
3288         case Panel_320x240_2:
3289         case Panel_320x240_3: tempbx = 14; break;
3290         case Panel_800x600:   tempbx = 16; break;
3291         case Panel_1024x600:  tempbx = 18; break;
3292         case Panel_1152x768:
3293         case Panel_1024x768:  tempbx = 20; break;
3294         case Panel_1280x768:  tempbx = 22; break;
3295         case Panel_1280x1024: tempbx = 24; break;
3296         case Panel_1400x1050: tempbx = 26; break;
3297         case Panel_1600x1200: tempbx = 28; break;
3298 #ifdef CONFIG_FB_SIS_300
3299         case Panel_Barco1366: tempbx = 80; break;
3300 #endif
3301         }
3302 
3303         switch(SiS_Pr->SiS_LCDResInfo) {
3304         case Panel_320x240_1:
3305         case Panel_320x240_2:
3306         case Panel_320x240_3:
3307         case Panel_640x480:
3308            break;
3309         default:
3310            if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3311         }
3312 
3313         if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempbx = 30;
3314 
3315 #ifdef CONFIG_FB_SIS_300
3316         if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
3317            tempbx = 82;
3318            if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3319         } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
3320            tempbx = 84;
3321            if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3322         }
3323 #endif
3324 
3325      }
3326 
3327      (*CRT2Index) = tempbx;
3328      (*ResIndex) = tempal & 0x1F;
3329   }
3330 }
3331 
3332 static void
3333 SiS_GetRAMDAC2DATA(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3334                 unsigned short RefreshRateTableIndex)
3335 {
3336   unsigned short tempax=0, tempbx=0, index, dotclock;
3337   unsigned short temp1=0, modeflag=0, tempcx=0;
3338 
3339   SiS_Pr->SiS_RVBHCMAX  = 1;
3340   SiS_Pr->SiS_RVBHCFACT = 1;
3341 
3342   if(ModeNo <= 0x13) {
3343 
3344      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3345      index = SiS_GetModePtr(SiS_Pr,ModeNo,ModeIdIndex);
3346 
3347      tempax = SiS_Pr->SiS_StandTable[index].CRTC[0];
3348      tempbx = SiS_Pr->SiS_StandTable[index].CRTC[6];
3349      temp1 = SiS_Pr->SiS_StandTable[index].CRTC[7];
3350 
3351      dotclock = (modeflag & Charx8Dot) ? 8 : 9;
3352 
3353   } else {
3354 
3355      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3356      index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);
3357 
3358      tempax = SiS_Pr->SiS_CRT1Table[index].CR[0];
3359      tempax |= (SiS_Pr->SiS_CRT1Table[index].CR[14] << 8);
3360      tempax &= 0x03FF;
3361      tempbx = SiS_Pr->SiS_CRT1Table[index].CR[6];
3362      tempcx = SiS_Pr->SiS_CRT1Table[index].CR[13] << 8;
3363      tempcx &= 0x0100;
3364      tempcx <<= 2;
3365      tempbx |= tempcx;
3366      temp1  = SiS_Pr->SiS_CRT1Table[index].CR[7];
3367 
3368      dotclock = 8;
3369 
3370   }
3371 
3372   if(temp1 & 0x01) tempbx |= 0x0100;
3373   if(temp1 & 0x20) tempbx |= 0x0200;
3374 
3375   tempax += 5;
3376   tempax *= dotclock;
3377   if(modeflag & HalfDCLK) tempax <<= 1;
3378 
3379   tempbx++;
3380 
3381   SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3382   SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = tempbx;
3383 }
3384 
3385 static void
3386 SiS_CalcPanelLinkTiming(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
3387                 unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex)
3388 {
3389    unsigned short ResIndex;
3390 
3391    if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3392       if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
3393          if(SiS_Pr->UseCustomMode) {
3394             ResIndex = SiS_Pr->CHTotal;
3395             if(SiS_Pr->CModeFlag & HalfDCLK) ResIndex <<= 1;
3396             SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = ResIndex;
3397             SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3398          } else {
3399             if(ModeNo < 0x13) {
3400                ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3401             } else {
3402                ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
3403             }
3404             if(ResIndex == 0x09) {
3405                if(SiS_Pr->Alternate1600x1200)        ResIndex = 0x20; /* 1600x1200 LCDA */
3406                else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) ResIndex = 0x21; /* 1600x1200 LVDS */
3407             }
3408             SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAHT;
3409             SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAVT;
3410             SiS_Pr->SiS_HT    = SiS_Pr->SiS_NoScaleData[ResIndex].LCDHT;
3411             SiS_Pr->SiS_VT    = SiS_Pr->SiS_NoScaleData[ResIndex].LCDVT;
3412          }
3413       } else {
3414          SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3415          SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3416       }
3417    } else {
3418       /* This handles custom modes and custom panels */
3419       SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3420       SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3421       SiS_Pr->SiS_HT  = SiS_Pr->PanelHT;
3422       SiS_Pr->SiS_VT  = SiS_Pr->PanelVT;
3423       SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT - (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE);
3424       SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT - (SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE);
3425    }
3426 }
3427 
3428 static void
3429 SiS_GetCRT2DataLVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3430                     unsigned short RefreshRateTableIndex)
3431 {
3432    unsigned short CRT2Index, ResIndex, backup;
3433    const struct SiS_LVDSData *LVDSData = NULL;
3434 
3435    SiS_GetCRT2ResInfo(SiS_Pr, ModeNo, ModeIdIndex);
3436 
3437    if(SiS_Pr->SiS_VBType & VB_SISVB) {
3438       SiS_Pr->SiS_RVBHCMAX  = 1;
3439       SiS_Pr->SiS_RVBHCFACT = 1;
3440       SiS_Pr->SiS_NewFlickerMode = 0;
3441       SiS_Pr->SiS_RVBHRS = 50;
3442       SiS_Pr->SiS_RY1COE = 0;
3443       SiS_Pr->SiS_RY2COE = 0;
3444       SiS_Pr->SiS_RY3COE = 0;
3445       SiS_Pr->SiS_RY4COE = 0;
3446       SiS_Pr->SiS_RVBHRS2 = 0;
3447    }
3448 
3449    if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3450 
3451 #ifdef CONFIG_FB_SIS_315
3452       SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3453       SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
3454 #endif
3455 
3456    } else {
3457 
3458       /* 301BDH needs LVDS Data */
3459       backup = SiS_Pr->SiS_IF_DEF_LVDS;
3460       if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3461          SiS_Pr->SiS_IF_DEF_LVDS = 1;
3462       }
3463 
3464       SiS_GetCRT2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
3465                                             &CRT2Index, &ResIndex);
3466 
3467       SiS_Pr->SiS_IF_DEF_LVDS = backup;
3468 
3469       switch(CRT2Index) {
3470          case 10: LVDSData = SiS_Pr->SiS_LVDS320x240Data_1;    break;
3471          case 14: LVDSData = SiS_Pr->SiS_LVDS320x240Data_2;    break;
3472          case 12: LVDSData = SiS_Pr->SiS_LVDS640x480Data_1;    break;
3473          case 16: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1;    break;
3474          case 18: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1;   break;
3475          case 20: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1;   break;
3476 #ifdef CONFIG_FB_SIS_300
3477          case 80: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1;  break;
3478          case 81: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2;  break;
3479          case 82: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1;  break;
3480          case 84: LVDSData = SiS_Pr->SiS_LVDS848x480Data_1;    break;
3481          case 85: LVDSData = SiS_Pr->SiS_LVDS848x480Data_2;    break;
3482 #endif
3483          case 90: LVDSData = SiS_Pr->SiS_CHTVUNTSCData;        break;
3484          case 91: LVDSData = SiS_Pr->SiS_CHTVONTSCData;        break;
3485          case 92: LVDSData = SiS_Pr->SiS_CHTVUPALData;         break;
3486          case 93: LVDSData = SiS_Pr->SiS_CHTVOPALData;         break;
3487          case 94: LVDSData = SiS_Pr->SiS_CHTVUPALMData;        break;
3488          case 95: LVDSData = SiS_Pr->SiS_CHTVOPALMData;        break;
3489          case 96: LVDSData = SiS_Pr->SiS_CHTVUPALNData;        break;
3490          case 97: LVDSData = SiS_Pr->SiS_CHTVOPALNData;        break;
3491          case 99: LVDSData = SiS_Pr->SiS_CHTVSOPALData;        break;
3492       }
3493 
3494       if(LVDSData) {
3495          SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT;
3496          SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT;
3497          SiS_Pr->SiS_HT    = (LVDSData+ResIndex)->LCDHT;
3498          SiS_Pr->SiS_VT    = (LVDSData+ResIndex)->LCDVT;
3499       } else {
3500          SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3501       }
3502 
3503       if( (!(SiS_Pr->SiS_VBType & VB_SISVB)) &&
3504           (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
3505           (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) ) {
3506          if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ||
3507              (SiS_Pr->SiS_SetFlag & SetDOSMode) ) {
3508             SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3509             SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3510 #ifdef CONFIG_FB_SIS_300
3511             if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3512                if(ResIndex < 0x08) {
3513                   SiS_Pr->SiS_HDE = 1280;
3514                   SiS_Pr->SiS_VDE = 1024;
3515                }
3516             }
3517 #endif
3518          }
3519       }
3520    }
3521 }
3522 
3523 static void
3524 SiS_GetCRT2Data301(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3525                 unsigned short RefreshRateTableIndex)
3526 {
3527   unsigned char  *ROMAddr = NULL;
3528   unsigned short tempax, tempbx, modeflag, romptr=0;
3529   unsigned short resinfo, CRT2Index, ResIndex;
3530   const struct SiS_LCDData *LCDPtr = NULL;
3531   const struct SiS_TVData  *TVPtr  = NULL;
3532 #ifdef CONFIG_FB_SIS_315
3533   short resinfo661;
3534 #endif
3535 
3536   if(ModeNo <= 0x13) {
3537      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3538      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
3539   } else if(SiS_Pr->UseCustomMode) {
3540      modeflag = SiS_Pr->CModeFlag;
3541      resinfo = 0;
3542   } else {
3543      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3544      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
3545 #ifdef CONFIG_FB_SIS_315
3546      resinfo661 = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].ROMMODEIDX661;
3547      if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)   &&
3548          (SiS_Pr->SiS_SetFlag & LCDVESATiming) &&
3549          (resinfo661 >= 0)                     &&
3550          (SiS_Pr->SiS_NeedRomModeData) ) {
3551         if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
3552            if((romptr = (SISGETROMW(21)))) {
3553               romptr += (resinfo661 * 10);
3554               ROMAddr = SiS_Pr->VirtualRomBase;
3555            }
3556         }
3557      }
3558 #endif
3559   }
3560 
3561   SiS_Pr->SiS_NewFlickerMode = 0;
3562   SiS_Pr->SiS_RVBHRS = 50;
3563   SiS_Pr->SiS_RY1COE = 0;
3564   SiS_Pr->SiS_RY2COE = 0;
3565   SiS_Pr->SiS_RY3COE = 0;
3566   SiS_Pr->SiS_RY4COE = 0;
3567   SiS_Pr->SiS_RVBHRS2 = 0;
3568 
3569   SiS_GetCRT2ResInfo(SiS_Pr,ModeNo,ModeIdIndex);
3570 
3571   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
3572 
3573      if(SiS_Pr->UseCustomMode) {
3574 
3575         SiS_Pr->SiS_RVBHCMAX  = 1;
3576         SiS_Pr->SiS_RVBHCFACT = 1;
3577         SiS_Pr->SiS_HDE       = SiS_Pr->SiS_VGAHDE;
3578         SiS_Pr->SiS_VDE       = SiS_Pr->SiS_VGAVDE;
3579 
3580         tempax = SiS_Pr->CHTotal;
3581         if(modeflag & HalfDCLK) tempax <<= 1;
3582         SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3583         SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3584 
3585      } else {
3586 
3587         SiS_GetRAMDAC2DATA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3588 
3589      }
3590 
3591   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
3592 
3593      SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3594                     &CRT2Index,&ResIndex);
3595 
3596      switch(CRT2Index) {
3597         case  2: TVPtr = SiS_Pr->SiS_ExtHiTVData;   break;
3598         case  3: TVPtr = SiS_Pr->SiS_ExtPALData;    break;
3599         case  4: TVPtr = SiS_Pr->SiS_ExtNTSCData;   break;
3600         case  5: TVPtr = SiS_Pr->SiS_Ext525iData;   break;
3601         case  6: TVPtr = SiS_Pr->SiS_Ext525pData;   break;
3602         case  7: TVPtr = SiS_Pr->SiS_Ext750pData;   break;
3603         case  8: TVPtr = SiS_Pr->SiS_StPALData;     break;
3604         case  9: TVPtr = SiS_Pr->SiS_StNTSCData;    break;
3605         case 10: TVPtr = SiS_Pr->SiS_St525iData;    break;
3606         case 11: TVPtr = SiS_Pr->SiS_St525pData;    break;
3607         case 12: TVPtr = SiS_Pr->SiS_St750pData;    break;
3608         case 13: TVPtr = SiS_Pr->SiS_St1HiTVData;   break;
3609         case 14: TVPtr = SiS_Pr->SiS_St2HiTVData;   break;
3610         default: TVPtr = SiS_Pr->SiS_StPALData;     break;
3611      }
3612 
3613      SiS_Pr->SiS_RVBHCMAX  = (TVPtr+ResIndex)->RVBHCMAX;
3614      SiS_Pr->SiS_RVBHCFACT = (TVPtr+ResIndex)->RVBHCFACT;
3615      SiS_Pr->SiS_VGAHT     = (TVPtr+ResIndex)->VGAHT;
3616      SiS_Pr->SiS_VGAVT     = (TVPtr+ResIndex)->VGAVT;
3617      SiS_Pr->SiS_HDE       = (TVPtr+ResIndex)->TVHDE;
3618      SiS_Pr->SiS_VDE       = (TVPtr+ResIndex)->TVVDE;
3619      SiS_Pr->SiS_RVBHRS2   = (TVPtr+ResIndex)->RVBHRS2 & 0x0fff;
3620      if(modeflag & HalfDCLK) {
3621         SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->HALFRVBHRS;
3622         if(SiS_Pr->SiS_RVBHRS2) {
3623            SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
3624            tempax = ((TVPtr+ResIndex)->RVBHRS2 >> 12) & 0x07;
3625            if((TVPtr+ResIndex)->RVBHRS2 & 0x8000) SiS_Pr->SiS_RVBHRS2 -= tempax;
3626            else                                   SiS_Pr->SiS_RVBHRS2 += tempax;
3627         }
3628      } else {
3629         SiS_Pr->SiS_RVBHRS    = (TVPtr+ResIndex)->RVBHRS;
3630      }
3631      SiS_Pr->SiS_NewFlickerMode = ((TVPtr+ResIndex)->FlickerMode) << 7;
3632 
3633      if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
3634 
3635         if((resinfo == SIS_RI_960x600)   ||
3636            (resinfo == SIS_RI_1024x768)  ||
3637            (resinfo == SIS_RI_1280x1024) ||
3638            (resinfo == SIS_RI_1280x720)) {
3639            SiS_Pr->SiS_NewFlickerMode = 0x40;
3640         }
3641 
3642         if(SiS_Pr->SiS_VGAVDE == 350) SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
3643 
3644         SiS_Pr->SiS_HT = ExtHiTVHT;
3645         SiS_Pr->SiS_VT = ExtHiTVVT;
3646         if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
3647            if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
3648               SiS_Pr->SiS_HT = StHiTVHT;
3649               SiS_Pr->SiS_VT = StHiTVVT;
3650            }
3651         }
3652 
3653      } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3654 
3655         if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
3656            SiS_Pr->SiS_HT = 1650;
3657            SiS_Pr->SiS_VT = 750;
3658         } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
3659            SiS_Pr->SiS_HT = NTSCHT;
3660            if(SiS_Pr->SiS_TVMode & TVSet525p1024) SiS_Pr->SiS_HT = NTSC2HT;
3661            SiS_Pr->SiS_VT = NTSCVT;
3662         } else {
3663            SiS_Pr->SiS_HT = NTSCHT;
3664            if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3665            SiS_Pr->SiS_VT = NTSCVT;
3666         }
3667 
3668      } else {
3669 
3670         SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
3671         SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
3672         SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
3673         SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
3674 
3675         if(modeflag & HalfDCLK) {
3676            SiS_Pr->SiS_RY1COE = 0x00;
3677            SiS_Pr->SiS_RY2COE = 0xf4;
3678            SiS_Pr->SiS_RY3COE = 0x10;
3679            SiS_Pr->SiS_RY4COE = 0x38;
3680         }
3681 
3682         if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
3683            SiS_Pr->SiS_HT = NTSCHT;
3684            if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3685            SiS_Pr->SiS_VT = NTSCVT;
3686         } else {
3687            SiS_Pr->SiS_HT = PALHT;
3688            SiS_Pr->SiS_VT = PALVT;
3689         }
3690 
3691      }
3692 
3693   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3694 
3695      SiS_Pr->SiS_RVBHCMAX  = 1;
3696      SiS_Pr->SiS_RVBHCFACT = 1;
3697 
3698      if(SiS_Pr->UseCustomMode) {
3699 
3700         SiS_Pr->SiS_HDE   = SiS_Pr->SiS_VGAHDE;
3701         SiS_Pr->SiS_VDE   = SiS_Pr->SiS_VGAVDE;
3702 
3703         tempax = SiS_Pr->CHTotal;
3704         if(modeflag & HalfDCLK) tempax <<= 1;
3705         SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3706         SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3707 
3708      } else {
3709 
3710         bool gotit = false;
3711 
3712         if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
3713 
3714            SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
3715            SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
3716            SiS_Pr->SiS_HT    = SiS_Pr->PanelHT;
3717            SiS_Pr->SiS_VT    = SiS_Pr->PanelVT;
3718            gotit = true;
3719 
3720         } else if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) && (romptr) && (ROMAddr) ) {
3721 
3722 #ifdef CONFIG_FB_SIS_315
3723            SiS_Pr->SiS_RVBHCMAX  = ROMAddr[romptr];
3724            SiS_Pr->SiS_RVBHCFACT = ROMAddr[romptr+1];
3725            SiS_Pr->SiS_VGAHT     = ROMAddr[romptr+2] | ((ROMAddr[romptr+3] & 0x0f) << 8);
3726            SiS_Pr->SiS_VGAVT     = (ROMAddr[romptr+4] << 4) | ((ROMAddr[romptr+3] & 0xf0) >> 4);
3727            SiS_Pr->SiS_HT        = ROMAddr[romptr+5] | ((ROMAddr[romptr+6] & 0x0f) << 8);
3728            SiS_Pr->SiS_VT        = (ROMAddr[romptr+7] << 4) | ((ROMAddr[romptr+6] & 0xf0) >> 4);
3729            SiS_Pr->SiS_RVBHRS2   = ROMAddr[romptr+8] | ((ROMAddr[romptr+9] & 0x0f) << 8);
3730            if((SiS_Pr->SiS_RVBHRS2) && (modeflag & HalfDCLK)) {
3731               SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
3732               tempax = (ROMAddr[romptr+9] >> 4) & 0x07;
3733               if(ROMAddr[romptr+9] & 0x80) SiS_Pr->SiS_RVBHRS2 -= tempax;
3734               else                         SiS_Pr->SiS_RVBHRS2 += tempax;
3735            }
3736            if(SiS_Pr->SiS_VGAHT) gotit = true;
3737            else {
3738               SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
3739               SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
3740               SiS_Pr->SiS_RVBHCMAX  = 1;
3741               SiS_Pr->SiS_RVBHCFACT = 1;
3742               SiS_Pr->SiS_VGAHT   = SiS_Pr->PanelHT;
3743               SiS_Pr->SiS_VGAVT   = SiS_Pr->PanelVT;
3744               SiS_Pr->SiS_HT      = SiS_Pr->PanelHT;
3745               SiS_Pr->SiS_VT      = SiS_Pr->PanelVT;
3746               SiS_Pr->SiS_RVBHRS2 = 0;
3747               gotit = true;
3748            }
3749 #endif
3750 
3751         }
3752 
3753         if(!gotit) {
3754 
3755            SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3756                           &CRT2Index,&ResIndex);
3757 
3758            switch(CRT2Index) {
3759               case Panel_1024x768      : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;   break;
3760               case Panel_1024x768  + 32: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data;   break;
3761               case Panel_1280x720      :
3762               case Panel_1280x720  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x720Data;      break;
3763               case Panel_1280x768_2    : LCDPtr = SiS_Pr->SiS_ExtLCD1280x768_2Data; break;
3764               case Panel_1280x768_2+ 32: LCDPtr = SiS_Pr->SiS_StLCD1280x768_2Data;  break;
3765               case Panel_1280x800      :
3766               case Panel_1280x800  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x800Data;      break;
3767               case Panel_1280x800_2    :
3768               case Panel_1280x800_2+ 32: LCDPtr = SiS_Pr->SiS_LCD1280x800_2Data;    break;
3769               case Panel_1280x854      :
3770               case Panel_1280x854  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x854Data;      break;
3771               case Panel_1280x960      :
3772               case Panel_1280x960  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x960Data;      break;
3773               case Panel_1280x1024     : LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data;  break;
3774               case Panel_1280x1024 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data;  break;
3775               case Panel_1400x1050     : LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data;  break;
3776               case Panel_1400x1050 + 32: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data;   break;
3777               case Panel_1600x1200     : LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data;  break;
3778               case Panel_1600x1200 + 32: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data;   break;
3779               case Panel_1680x1050     :
3780               case Panel_1680x1050 + 32: LCDPtr = SiS_Pr->SiS_LCD1680x1050Data;     break;
3781               case 100                 : LCDPtr = SiS_Pr->SiS_NoScaleData;          break;
3782 #ifdef CONFIG_FB_SIS_315
3783               case 200                 : LCDPtr = SiS310_ExtCompaq1280x1024Data;    break;
3784               case 201                 : LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data;  break;
3785 #endif
3786               default                  : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;   break;
3787            }
3788 
3789            SiS_Pr->SiS_RVBHCMAX  = (LCDPtr+ResIndex)->RVBHCMAX;
3790            SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
3791            SiS_Pr->SiS_VGAHT     = (LCDPtr+ResIndex)->VGAHT;
3792            SiS_Pr->SiS_VGAVT     = (LCDPtr+ResIndex)->VGAVT;
3793            SiS_Pr->SiS_HT        = (LCDPtr+ResIndex)->LCDHT;
3794            SiS_Pr->SiS_VT        = (LCDPtr+ResIndex)->LCDVT;
3795 
3796         }
3797 
3798         tempax = SiS_Pr->PanelXRes;
3799         tempbx = SiS_Pr->PanelYRes;
3800 
3801         switch(SiS_Pr->SiS_LCDResInfo) {
3802         case Panel_1024x768:
3803            if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
3804               if(SiS_Pr->ChipType < SIS_315H) {
3805                  if     (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3806                  else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3807               }
3808            } else {
3809               if     (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
3810               else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
3811               else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
3812               else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
3813               else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3814               else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3815            }
3816            break;
3817         case Panel_1280x960:
3818            if     (SiS_Pr->SiS_VGAVDE == 350)  tempbx = 700;
3819            else if(SiS_Pr->SiS_VGAVDE == 400)  tempbx = 800;
3820            else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
3821            break;
3822         case Panel_1280x1024:
3823            if     (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
3824            else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
3825            else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
3826            break;
3827         case Panel_1600x1200:
3828            if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
3829               if     (SiS_Pr->SiS_VGAVDE == 350)  tempbx = 875;
3830               else if(SiS_Pr->SiS_VGAVDE == 400)  tempbx = 1000;
3831            }
3832            break;
3833         }
3834 
3835         if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3836            tempax = SiS_Pr->SiS_VGAHDE;
3837            tempbx = SiS_Pr->SiS_VGAVDE;
3838         }
3839 
3840         SiS_Pr->SiS_HDE = tempax;
3841         SiS_Pr->SiS_VDE = tempbx;
3842      }
3843   }
3844 }
3845 
3846 static void
3847 SiS_GetCRT2Data(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3848                 unsigned short RefreshRateTableIndex)
3849 {
3850 
3851    if(SiS_Pr->SiS_VBType & VB_SISVB) {
3852 
3853       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
3854          SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3855       } else {
3856          if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3857             /* Need LVDS Data for LCD on 301B-DH */
3858             SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3859          } else {
3860             SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3861          }
3862       }
3863 
3864    } else {
3865 
3866       SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3867 
3868    }
3869 }
3870 
3871 /*********************************************/
3872 /*         GET LVDS DES (SKEW) DATA          */
3873 /*********************************************/
3874 
3875 static const struct SiS_LVDSDes *
3876 SiS_GetLVDSDesPtr(struct SiS_Private *SiS_Pr)
3877 {
3878    const struct SiS_LVDSDes *PanelDesPtr = NULL;
3879 
3880 #ifdef CONFIG_FB_SIS_300
3881    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3882 
3883       if(SiS_Pr->ChipType < SIS_315H) {
3884          if(SiS_Pr->SiS_LCDTypeInfo == 4) {
3885             if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3886                PanelDesPtr = SiS_Pr->SiS_PanelType04_1a;
3887                if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3888                   PanelDesPtr = SiS_Pr->SiS_PanelType04_2a;
3889                }
3890             } else if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
3891                PanelDesPtr = SiS_Pr->SiS_PanelType04_1b;
3892                if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3893                   PanelDesPtr = SiS_Pr->SiS_PanelType04_2b;
3894                }
3895             }
3896          }
3897       }
3898    }
3899 #endif
3900    return PanelDesPtr;
3901 }
3902 
3903 static void
3904 SiS_GetLVDSDesData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3905                    unsigned short RefreshRateTableIndex)
3906 {
3907   unsigned short modeflag, ResIndex;
3908   const struct SiS_LVDSDes *PanelDesPtr = NULL;
3909 
3910   SiS_Pr->SiS_LCDHDES = 0;
3911   SiS_Pr->SiS_LCDVDES = 0;
3912 
3913   /* Some special cases */
3914   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3915 
3916      /* Trumpion */
3917      if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
3918         if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3919            if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3920               SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3921            }
3922         }
3923         return;
3924      }
3925 
3926      /* 640x480 on LVDS */
3927      if(SiS_Pr->ChipType < SIS_315H) {
3928         if(SiS_Pr->SiS_LCDResInfo == Panel_640x480 && SiS_Pr->SiS_LCDTypeInfo == 3) {
3929            SiS_Pr->SiS_LCDHDES = 8;
3930            if     (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
3931            else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
3932            else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
3933            return;
3934         }
3935      }
3936 
3937   } /* LCD */
3938 
3939   if( (SiS_Pr->UseCustomMode)                    ||
3940       (SiS_Pr->SiS_LCDResInfo == Panel_Custom)   ||
3941       (SiS_Pr->SiS_CustomT == CUT_PANEL848)      ||
3942       (SiS_Pr->SiS_CustomT == CUT_PANEL856)      ||
3943       (SiS_Pr->SiS_LCDInfo & LCDPass11) ) {
3944      return;
3945   }
3946 
3947   if(ModeNo <= 0x13) ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3948   else               ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
3949 
3950   if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3951 
3952 #ifdef CONFIG_FB_SIS_315
3953      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3954         /* non-pass 1:1 only, see above */
3955         if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
3956            SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
3957         }
3958         if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
3959            SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
3960         }
3961      }
3962      if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3963         switch(SiS_Pr->SiS_CustomT) {
3964         case CUT_UNIWILL1024:
3965         case CUT_UNIWILL10242:
3966         case CUT_CLEVO1400:
3967            if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3968               SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3969            }
3970            break;
3971         }
3972         switch(SiS_Pr->SiS_LCDResInfo) {
3973         case Panel_1280x1024:
3974            if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
3975               SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3976            }
3977            break;
3978         case Panel_1280x800:    /* Verified for Averatec 6240 */
3979         case Panel_1280x800_2:  /* Verified for Asus A4L */
3980         case Panel_1280x854:    /* Not verified yet FIXME */
3981            SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3982            break;
3983         }
3984      }
3985 #endif
3986 
3987   } else {
3988 
3989      if((SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
3990 
3991         if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
3992            if(ResIndex <= 3) SiS_Pr->SiS_LCDHDES = 256;
3993         }
3994 
3995      } else if((PanelDesPtr = SiS_GetLVDSDesPtr(SiS_Pr))) {
3996 
3997         SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
3998         SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;
3999 
4000      } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
4001 
4002         if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
4003            SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
4004         }
4005         if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
4006            SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
4007         } else {
4008            if(SiS_Pr->ChipType < SIS_315H) {
4009               SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
4010            } else {
4011               switch(SiS_Pr->SiS_LCDResInfo) {
4012               case Panel_800x600:
4013               case Panel_1024x768:
4014               case Panel_1280x1024:
4015                  SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
4016                  break;
4017               case Panel_1400x1050:
4018                  SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
4019                  break;
4020               }
4021            }
4022         }
4023 
4024      } else {
4025 
4026         if(SiS_Pr->ChipType < SIS_315H) {
4027 #ifdef CONFIG_FB_SIS_300
4028            switch(SiS_Pr->SiS_LCDResInfo) {
4029            case Panel_800x600:
4030               if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
4031                  SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
4032               } else {
4033                  SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT + 3;
4034                  SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
4035                  if(SiS_Pr->SiS_VGAVDE == 400) SiS_Pr->SiS_LCDVDES -= 2;
4036                  else                          SiS_Pr->SiS_LCDVDES -= 4;
4037               }
4038               break;
4039            case Panel_1024x768:
4040               if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
4041                  SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
4042               } else {
4043                  SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
4044                  if(SiS_Pr->SiS_VGAVDE <= 400) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 8;
4045                  if(SiS_Pr->SiS_VGAVDE <= 350) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 12;
4046               }
4047               break;
4048            case Panel_1024x600:
4049            default:
4050               if( (SiS_Pr->SiS_VGAHDE == SiS_Pr->PanelXRes) &&
4051                   (SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) ) {
4052                  SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
4053               } else {
4054                  SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
4055               }
4056               break;
4057            }
4058 
4059            switch(SiS_Pr->SiS_LCDTypeInfo) {
4060            case 1:
4061               SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
4062               break;
4063            case 3: /* 640x480 only? */
4064               SiS_Pr->SiS_LCDHDES = 8;
4065               if     (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
4066               else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
4067               else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
4068               break;
4069            }
4070 #endif
4071         } else {
4072 #ifdef CONFIG_FB_SIS_315
4073            switch(SiS_Pr->SiS_LCDResInfo) {
4074            case Panel_1024x768:
4075            case Panel_1280x1024:
4076               if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
4077                  SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
4078               }
4079               break;
4080            case Panel_320x240_1:
4081            case Panel_320x240_2:
4082            case Panel_320x240_3:
4083               SiS_Pr->SiS_LCDVDES = 524;
4084               break;
4085            }
4086 #endif
4087         }
4088      }
4089 
4090      if((ModeNo <= 0x13) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
4091         modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
4092         if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
4093            if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 632;
4094         } else if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) {
4095            if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
4096               if(SiS_Pr->SiS_LCDResInfo >= Panel_1024x768) {
4097                  if(SiS_Pr->ChipType < SIS_315H) {
4098                     if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320;
4099                  } else {
4100 #ifdef CONFIG_FB_SIS_315
4101                     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)  SiS_Pr->SiS_LCDHDES = 480;
4102                     if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 804;
4103                     if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 704;
4104                     if(!(modeflag & HalfDCLK)) {
4105                        SiS_Pr->SiS_LCDHDES = 320;
4106                        if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 632;
4107                        if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 542;
4108                     }
4109 #endif
4110                  }
4111               }
4112            }
4113         }
4114      }
4115   }
4116 }
4117 
4118 /*********************************************/
4119 /*           DISABLE VIDEO BRIDGE            */
4120 /*********************************************/
4121 
4122 #ifdef CONFIG_FB_SIS_315
4123 static int
4124 SiS_HandlePWD(struct SiS_Private *SiS_Pr)
4125 {
4126    int ret = 0;
4127 #ifdef SET_PWD
4128    unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
4129    unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
4130    unsigned char  drivermode = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40;
4131    unsigned short temp;
4132 
4133    if( (SiS_Pr->SiS_VBType & VB_SISPWD) &&
4134        (romptr)                         &&
4135        (SiS_Pr->SiS_PWDOffset) ) {
4136       SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2b,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 0]);
4137       SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2c,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 1]);
4138       SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2d,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 2]);
4139       SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2e,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 3]);
4140       SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2f,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 4]);
4141       temp = 0x00;
4142       if((ROMAddr[romptr + 2] & (0x06 << 1)) && !drivermode) {
4143          temp = 0x80;
4144          ret = 1;
4145       }
4146       SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x27,0x7f,temp);
4147    }
4148 #endif
4149    return ret;
4150 }
4151 #endif
4152 
4153 /* NEVER use any variables (VBInfo), this will be called
4154  * from outside the context of modeswitch!
4155  * MUST call getVBType before calling this
4156  */
4157 void
4158 SiS_DisableBridge(struct SiS_Private *SiS_Pr)
4159 {
4160 #ifdef CONFIG_FB_SIS_315
4161   unsigned short tempah, pushax=0, modenum;
4162 #endif
4163   unsigned short temp=0;
4164 
4165   if(SiS_Pr->SiS_VBType & VB_SISVB) {
4166 
4167      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {            /* ===== For 30xB/C/LV ===== */
4168 
4169         if(SiS_Pr->ChipType < SIS_315H) {
4170 
4171 #ifdef CONFIG_FB_SIS_300           /* 300 series */
4172 
4173            if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4174               if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4175                  SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
4176               } else {
4177                  SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4178               }
4179               SiS_PanelDelay(SiS_Pr, 3);
4180            }
4181            if(SiS_Is301B(SiS_Pr)) {
4182               SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);
4183               SiS_ShortDelay(SiS_Pr,1);
4184            }
4185            SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
4186            SiS_DisplayOff(SiS_Pr);
4187            SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4188            SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4189            SiS_UnLockCRT2(SiS_Pr);
4190            if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) {
4191               SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
4192               SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
4193            }
4194            if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4195                (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4196               SiS_PanelDelay(SiS_Pr, 2);
4197               if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4198                  SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
4199               } else {
4200                  SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4201               }
4202            }
4203 
4204 #endif  /* CONFIG_FB_SIS_300 */
4205 
4206         } else {
4207 
4208 #ifdef CONFIG_FB_SIS_315           /* 315 series */
4209 
4210            int didpwd = 0;
4211            bool custom1 = (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
4212                           (SiS_Pr->SiS_CustomT == CUT_CLEVO1400);
4213 
4214            modenum = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34) & 0x7f;
4215 
4216            if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4217 
4218 #ifdef SET_EMI
4219               if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4220                  if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
4221                     SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4222                  }
4223               }
4224 #endif
4225 
4226               didpwd = SiS_HandlePWD(SiS_Pr);
4227 
4228               if( (modenum <= 0x13)           ||
4229                   (SiS_IsVAMode(SiS_Pr))      ||
4230                   (!(SiS_IsDualEdge(SiS_Pr))) ) {
4231                  if(!didpwd) {
4232                     SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfe);
4233                     if(custom1) SiS_PanelDelay(SiS_Pr, 3);
4234                  } else {
4235                     SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfc);
4236                  }
4237               }
4238 
4239               if(!custom1) {
4240                  SiS_DDC2Delay(SiS_Pr,0xff00);
4241                  SiS_DDC2Delay(SiS_Pr,0xe000);
4242                  SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
4243                  pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
4244                  if(IS_SIS740) {
4245                     SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
4246                  }
4247                  SiS_PanelDelay(SiS_Pr, 3);
4248               }
4249 
4250            }
4251 
4252            if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4253               /* if(SiS_Pr->ChipType < SIS_340) {*/
4254                  tempah = 0xef;
4255                  if(SiS_IsVAMode(SiS_Pr)) tempah = 0xf7;
4256                  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
4257               /*}*/
4258            }
4259 
4260            if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4261               SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,~0x10);
4262            }
4263 
4264            tempah = 0x3f;
4265            if(SiS_IsDualEdge(SiS_Pr)) {
4266               tempah = 0x7f;
4267               if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0xbf;
4268            }
4269            SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4270 
4271            if((SiS_IsVAMode(SiS_Pr)) ||
4272               ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
4273 
4274               SiS_DisplayOff(SiS_Pr);
4275               if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4276                  SiS_PanelDelay(SiS_Pr, 2);
4277               }
4278               SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4279               SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
4280 
4281            }
4282 
4283            if((!(SiS_IsVAMode(SiS_Pr))) ||
4284               ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
4285 
4286               if(!(SiS_IsDualEdge(SiS_Pr))) {
4287                  SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
4288                  SiS_DisplayOff(SiS_Pr);
4289               }
4290               SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4291 
4292               if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4293                  SiS_PanelDelay(SiS_Pr, 2);
4294               }
4295 
4296               SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4297               temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
4298               SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
4299               SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4300               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
4301 
4302            }
4303 
4304            if(SiS_IsNotM650orLater(SiS_Pr)) {
4305               SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4306            }
4307 
4308            if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4309 
4310               if( (!(SiS_IsVAMode(SiS_Pr)))  &&
4311                   (!(SiS_CRT2IsLCD(SiS_Pr))) &&
4312                   (!(SiS_IsDualEdge(SiS_Pr))) ) {
4313 
4314                  if(custom1) SiS_PanelDelay(SiS_Pr, 2);
4315                  if(!didpwd) {
4316                     SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
4317                  }
4318                  if(custom1) SiS_PanelDelay(SiS_Pr, 4);
4319               }
4320 
4321               if(!custom1) {
4322                  SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4323                  if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4324                     if(SiS_IsVAorLCD(SiS_Pr)) {
4325                        SiS_PanelDelayLoop(SiS_Pr, 3, 20);
4326                     }
4327                  }
4328               }
4329 
4330            }
4331 
4332 #endif /* CONFIG_FB_SIS_315 */
4333 
4334         }
4335 
4336      } else {     /* ============ For 301 ================ */
4337 
4338         if(SiS_Pr->ChipType < SIS_315H) {
4339 #ifdef CONFIG_FB_SIS_300
4340            if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4341               SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4342               SiS_PanelDelay(SiS_Pr, 3);
4343            }
4344 #endif
4345         }
4346 
4347         SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);           /* disable VB */
4348         SiS_DisplayOff(SiS_Pr);
4349 
4350         if(SiS_Pr->ChipType >= SIS_315H) {
4351            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4352         }
4353 
4354         SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);                /* disable lock mode */
4355 
4356         if(SiS_Pr->ChipType >= SIS_315H) {
4357             temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
4358             SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
4359             SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4360             SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
4361         } else {
4362 #ifdef CONFIG_FB_SIS_300
4363             SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);            /* disable CRT2 */
4364             if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4365                 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4366                 SiS_PanelDelay(SiS_Pr, 2);
4367                 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4368             }
4369 #endif
4370         }
4371 
4372       }
4373 
4374   } else {     /* ============ For LVDS =============*/
4375 
4376     if(SiS_Pr->ChipType < SIS_315H) {
4377 
4378 #ifdef CONFIG_FB_SIS_300        /* 300 series */
4379 
4380         if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4381            SiS_SetCH700x(SiS_Pr,0x0E,0x09);
4382         }
4383 
4384         if(SiS_Pr->ChipType == SIS_730) {
4385            if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4386               SiS_WaitVBRetrace(SiS_Pr);
4387            }
4388            if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4389               SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4390               SiS_PanelDelay(SiS_Pr, 3);
4391            }
4392         } else {
4393            if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4394               if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4395                  if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4396                     SiS_WaitVBRetrace(SiS_Pr);
4397                     if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {
4398                        SiS_DisplayOff(SiS_Pr);
4399                     }
4400                     SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4401                     SiS_PanelDelay(SiS_Pr, 3);
4402                  }
4403               }
4404            }
4405         }
4406 
4407         SiS_DisplayOff(SiS_Pr);
4408 
4409         SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4410 
4411         SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4412         SiS_UnLockCRT2(SiS_Pr);
4413         SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
4414         SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
4415 
4416         if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4417             (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4418            SiS_PanelDelay(SiS_Pr, 2);
4419            SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4420         }
4421 
4422 #endif  /* CONFIG_FB_SIS_300 */
4423 
4424     } else {
4425 
4426 #ifdef CONFIG_FB_SIS_315        /* 315 series */
4427 
4428         if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4429            /*if(SiS_Pr->ChipType < SIS_340) { */ /* XGI needs this */
4430               SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,~0x18);
4431            /* } */
4432         }
4433 
4434         if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4435 
4436            if(SiS_Pr->ChipType == SIS_740) {
4437               temp = SiS_GetCH701x(SiS_Pr,0x61);
4438               if(temp < 1) {
4439                  SiS_SetCH701x(SiS_Pr,0x76,0xac);
4440                  SiS_SetCH701x(SiS_Pr,0x66,0x00);
4441               }
4442 
4443               if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4444                   (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
4445                  SiS_SetCH701x(SiS_Pr,0x49,0x3e);
4446               }
4447            }
4448 
4449            if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4450                (SiS_IsVAMode(SiS_Pr)) ) {
4451               SiS_Chrontel701xBLOff(SiS_Pr);
4452               SiS_Chrontel701xOff(SiS_Pr);
4453            }
4454 
4455            if(SiS_Pr->ChipType != SIS_740) {
4456               if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4457                   (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
4458                  SiS_SetCH701x(SiS_Pr,0x49,0x01);
4459               }
4460            }
4461 
4462         }
4463 
4464         if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4465            SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4466            SiS_PanelDelay(SiS_Pr, 3);
4467         }
4468 
4469         if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
4470             (!(SiS_IsDualEdge(SiS_Pr))) ||
4471             (!(SiS_IsTVOrYPbPrOrScart(SiS_Pr))) ) {
4472            SiS_DisplayOff(SiS_Pr);
4473         }
4474 
4475         if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
4476             (!(SiS_IsDualEdge(SiS_Pr))) ||
4477             (!(SiS_IsVAMode(SiS_Pr))) ) {
4478            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4479         }
4480 
4481         if(SiS_Pr->ChipType == SIS_740) {
4482            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4483         }
4484 
4485         SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4486 
4487         if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
4488             (!(SiS_IsDualEdge(SiS_Pr))) ||
4489             (!(SiS_IsVAMode(SiS_Pr))) ) {
4490            SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4491         }
4492 
4493         if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4494            if(SiS_CRT2IsLCD(SiS_Pr)) {
4495               SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4496               if(SiS_Pr->ChipType == SIS_550) {
4497                  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xbf);
4498                  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xef);
4499               }
4500            }
4501         } else {
4502            if(SiS_Pr->ChipType == SIS_740) {
4503               if(SiS_IsLCDOrLCDA(SiS_Pr)) {
4504                  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4505               }
4506            } else if(SiS_IsVAMode(SiS_Pr)) {
4507               SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4508            }
4509         }
4510 
4511         if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4512            if(SiS_IsDualEdge(SiS_Pr)) {
4513               /* SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff); */
4514            } else {
4515               SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
4516            }
4517         }
4518 
4519         SiS_UnLockCRT2(SiS_Pr);
4520 
4521         if(SiS_Pr->ChipType == SIS_550) {
4522            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); /* DirectDVD PAL?*/
4523            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); /* VB clock / 4 ? */
4524         } else if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
4525                    (!(SiS_IsDualEdge(SiS_Pr))) ||
4526                    (!(SiS_IsVAMode(SiS_Pr))) ) {
4527            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4528         }
4529 
4530         if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4531            if(SiS_CRT2IsLCD(SiS_Pr)) {
4532               if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4533                  SiS_PanelDelay(SiS_Pr, 2);
4534                  SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4535               }
4536            }
4537         }
4538 
4539 #endif  /* CONFIG_FB_SIS_315 */
4540 
4541     }  /* 315 series */
4542 
4543   }  /* LVDS */
4544 
4545 }
4546 
4547 /*********************************************/
4548 /*            ENABLE VIDEO BRIDGE            */
4549 /*********************************************/
4550 
4551 /* NEVER use any variables (VBInfo), this will be called
4552  * from outside the context of a mode switch!
4553  * MUST call getVBType before calling this
4554  */
4555 static
4556 void
4557 SiS_EnableBridge(struct SiS_Private *SiS_Pr)
4558 {
4559   unsigned short temp=0, tempah;
4560 #ifdef CONFIG_FB_SIS_315
4561   unsigned short temp1, pushax=0;
4562   bool delaylong = false;
4563 #endif
4564 
4565   if(SiS_Pr->SiS_VBType & VB_SISVB) {
4566 
4567     if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {             /* ====== For 301B et al  ====== */
4568 
4569       if(SiS_Pr->ChipType < SIS_315H) {
4570 
4571 #ifdef CONFIG_FB_SIS_300     /* 300 series */
4572 
4573          if(SiS_CRT2IsLCD(SiS_Pr)) {
4574             if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4575                SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4576             } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
4577                SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4578             }
4579             if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_NoLCD)) {
4580                if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
4581                   SiS_PanelDelay(SiS_Pr, 0);
4582                }
4583             }
4584          }
4585 
4586          if((SiS_Pr->SiS_VBType & VB_NoLCD) &&
4587             (SiS_CRT2IsLCD(SiS_Pr))) {
4588 
4589             SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                   /* Enable CRT2 */
4590             SiS_DisplayOn(SiS_Pr);
4591             SiS_UnLockCRT2(SiS_Pr);
4592             SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4593             if(SiS_BridgeInSlavemode(SiS_Pr)) {
4594                SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4595             } else {
4596                SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4597             }
4598             if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4599                if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4600                   if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4601                      SiS_PanelDelay(SiS_Pr, 1);
4602                   }
4603                   SiS_WaitVBRetrace(SiS_Pr);
4604                   SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4605                }
4606             }
4607 
4608          } else {
4609 
4610             temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;             /* lock mode */
4611             if(SiS_BridgeInSlavemode(SiS_Pr)) {
4612                tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4613                if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4614             }
4615             SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4616             SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4617             SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20);        /* enable VB processor */
4618             SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
4619             SiS_DisplayOn(SiS_Pr);
4620             if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4621                if(SiS_CRT2IsLCD(SiS_Pr)) {
4622                   if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4623                      if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4624                         SiS_PanelDelay(SiS_Pr, 1);
4625                      }
4626                      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4627                   }
4628                }
4629             }
4630 
4631          }
4632 
4633 
4634 #endif /* CONFIG_FB_SIS_300 */
4635 
4636       } else {
4637 
4638 #ifdef CONFIG_FB_SIS_315    /* 315 series */
4639 
4640 #ifdef SET_EMI
4641          unsigned char   r30=0, r31=0, r32=0, r33=0, cr36=0;
4642          int didpwd = 0;
4643          /* unsigned short  emidelay=0; */
4644 #endif
4645 
4646          if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4647             SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef);
4648 #ifdef SET_EMI
4649             if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4650                SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4651             }
4652 #endif
4653          }
4654 
4655          if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4656             /*if(SiS_Pr->ChipType < SIS_340) { */
4657                tempah = 0x10;
4658                if(SiS_LCDAEnabled(SiS_Pr)) {
4659                   if(SiS_TVEnabled(SiS_Pr)) tempah = 0x18;
4660                   else                      tempah = 0x08;
4661                }
4662                SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah);
4663             /*}*/
4664          }
4665 
4666          if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4667 
4668             SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
4669             SiS_DisplayOff(SiS_Pr);
4670             pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
4671             if(IS_SIS740) {
4672                SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
4673             }
4674 
4675             didpwd = SiS_HandlePWD(SiS_Pr);
4676 
4677             if(SiS_IsVAorLCD(SiS_Pr)) {
4678                if(!didpwd) {
4679                   if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
4680                      SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4681                      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4682                      SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4683                      if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4684                         SiS_GenericDelay(SiS_Pr, 17664);
4685                      }
4686                   }
4687                } else {
4688                   SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4689                   if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4690                      SiS_GenericDelay(SiS_Pr, 17664);
4691                   }
4692                }
4693             }
4694 
4695             if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {
4696                SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4697                delaylong = true;
4698             }
4699 
4700          }
4701 
4702          if(!(SiS_IsVAMode(SiS_Pr))) {
4703 
4704             temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
4705             if(SiS_BridgeInSlavemode(SiS_Pr)) {
4706                tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4707                if(!(tempah & SetCRT2ToRAMDAC)) {
4708                   if(!(SiS_LCDAEnabled(SiS_Pr))) temp |= 0x20;
4709                }
4710             }
4711             SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4712 
4713             SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                   /* enable CRT2 */
4714 
4715             SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4716             SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4717 
4718             if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4719                SiS_PanelDelay(SiS_Pr, 2);
4720             }
4721 
4722          } else {
4723 
4724             SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20);
4725 
4726          }
4727 
4728          SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
4729          SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4730 
4731          if(SiS_Pr->SiS_VBType & VB_SISPOWER) {
4732             if( (SiS_LCDAEnabled(SiS_Pr)) ||
4733                 (SiS_CRT2IsLCD(SiS_Pr)) ) {
4734                /* Enable "LVDS PLL power on" (even on 301C) */
4735                SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);
4736                /* Enable "LVDS Driver Power on" (even on 301C) */
4737                SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x7f);
4738             }
4739          }
4740 
4741          tempah = 0xc0;
4742          if(SiS_IsDualEdge(SiS_Pr)) {
4743             tempah = 0x80;
4744             if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0x40;
4745          }
4746          SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4747 
4748          if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4749 
4750             SiS_PanelDelay(SiS_Pr, 2);
4751 
4752             SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10);
4753             SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4754 
4755             if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
4756 #ifdef SET_EMI
4757                if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4758                   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4759                   SiS_GenericDelay(SiS_Pr, 2048);
4760                }
4761 #endif
4762                SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
4763 
4764                if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4765 #ifdef SET_EMI
4766                   cr36 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
4767 
4768                   if(SiS_Pr->SiS_ROMNew) {
4769                      unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
4770                      unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
4771                      if(romptr) {
4772                         SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4773                         SiS_Pr->EMI_30 = 0;
4774                         SiS_Pr->EMI_31 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 0];
4775                         SiS_Pr->EMI_32 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 1];
4776                         SiS_Pr->EMI_33 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 2];
4777                         if(ROMAddr[romptr + 1] & 0x10) SiS_Pr->EMI_30 = 0x40;
4778                         /* emidelay = SISGETROMW((romptr + 0x22)); */
4779                         SiS_Pr->HaveEMI = SiS_Pr->HaveEMILCD = SiS_Pr->OverruleEMI = true;
4780                      }
4781                   }
4782 
4783                   /*                                              (P4_30|0x40)  */
4784                   /* Compal 1400x1050: 0x05, 0x60, 0x00                YES  (1.10.7w;  CR36=69)      */
4785                   /* Compal 1400x1050: 0x0d, 0x70, 0x40                YES  (1.10.7x;  CR36=69)      */
4786                   /* Acer   1280x1024: 0x12, 0xd0, 0x6b                NO   (1.10.9k;  CR36=73)      */
4787                   /* Compaq 1280x1024: 0x0d, 0x70, 0x6b                YES  (1.12.04b; CR36=03)      */
4788                   /* Clevo   1024x768: 0x05, 0x60, 0x33                NO   (1.10.8e;  CR36=12, DL!) */
4789                   /* Clevo   1024x768: 0x0d, 0x70, 0x40 (if type == 3) YES  (1.10.8y;  CR36=?2)      */
4790                   /* Clevo   1024x768: 0x05, 0x60, 0x33 (if type != 3) YES  (1.10.8y;  CR36=?2)      */
4791                   /* Asus    1024x768: ?                                ?   (1.10.8o;  CR36=?2)      */
4792                   /* Asus    1024x768: 0x08, 0x10, 0x3c (problematic)  YES  (1.10.8q;  CR36=22)      */
4793 
4794                   if(SiS_Pr->HaveEMI) {
4795                      r30 = SiS_Pr->EMI_30; r31 = SiS_Pr->EMI_31;
4796                      r32 = SiS_Pr->EMI_32; r33 = SiS_Pr->EMI_33;
4797                   } else {
4798                      r30 = 0;
4799                   }
4800 
4801                   /* EMI_30 is read at driver start; however, the BIOS sets this
4802                    * (if it is used) only if the LCD is in use. In case we caught
4803                    * the machine while on TV output, this bit is not set and we
4804                    * don't know if it should be set - hence our detection is wrong.
4805                    * Work-around this here:
4806                    */
4807 
4808                   if((!SiS_Pr->HaveEMI) || (!SiS_Pr->HaveEMILCD)) {
4809                      switch((cr36 & 0x0f)) {
4810                      case 2:
4811                         r30 |= 0x40;
4812                         if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) r30 &= ~0x40;
4813                         if(!SiS_Pr->HaveEMI) {
4814                            r31 = 0x05; r32 = 0x60; r33 = 0x33;
4815                            if((cr36 & 0xf0) == 0x30) {
4816                               r31 = 0x0d; r32 = 0x70; r33 = 0x40;
4817                            }
4818                         }
4819                         break;
4820                      case 3:  /* 1280x1024 */
4821                         if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) r30 |= 0x40;
4822                         if(!SiS_Pr->HaveEMI) {
4823                            r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4824                            if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4825                               r31 = 0x0d; r32 = 0x70; r33 = 0x6b;
4826                            }
4827                         }
4828                         break;
4829                      case 9:  /* 1400x1050 */
4830                         r30 |= 0x40;
4831                         if(!SiS_Pr->HaveEMI) {
4832                            r31 = 0x05; r32 = 0x60; r33 = 0x00;
4833                            if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4834                               r31 = 0x0d; r32 = 0x70; r33 = 0x40;  /* BIOS values */
4835                            }
4836                         }
4837                         break;
4838                      case 11: /* 1600x1200 - unknown */
4839                         r30 |= 0x40;
4840                         if(!SiS_Pr->HaveEMI) {
4841                            r31 = 0x05; r32 = 0x60; r33 = 0x00;
4842                         }
4843                      }
4844                   }
4845 
4846                   /* BIOS values don't work so well sometimes */
4847                   if(!SiS_Pr->OverruleEMI) {
4848 #ifdef COMPAL_HACK
4849                      if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4850                         if((cr36 & 0x0f) == 0x09) {
4851                            r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x00;
4852                         }
4853                      }
4854 #endif
4855 #ifdef COMPAQ_HACK
4856                      if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4857                         if((cr36 & 0x0f) == 0x03) {
4858                            r30 = 0x20; r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4859                         }
4860                      }
4861 #endif
4862 #ifdef ASUS_HACK
4863                      if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4864                         if((cr36 & 0x0f) == 0x02) {
4865                            /* r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x33;  */   /* rev 2 */
4866                            /* r30 = 0x20; r31 = 0x05; r32 = 0x60; r33 = 0x33;  */   /* rev 3 */
4867                            /* r30 = 0x60; r31 = 0x0d; r32 = 0x70; r33 = 0x40;  */   /* rev 4 */
4868                            /* r30 = 0x20; r31 = 0x0d; r32 = 0x70; r33 = 0x40;  */   /* rev 5 */
4869                         }
4870                      }
4871 #endif
4872                   }
4873 
4874                   if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) {
4875                      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4876                      SiS_GenericDelay(SiS_Pr, 2048);
4877                   }
4878                   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,r31);
4879                   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,r32);
4880                   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x33,r33);
4881 #endif  /* SET_EMI */
4882 
4883                   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
4884 
4885 #ifdef SET_EMI
4886                   if( (SiS_LCDAEnabled(SiS_Pr)) ||
4887                       (SiS_CRT2IsLCD(SiS_Pr)) ) {
4888                      if(r30 & 0x40) {
4889                         /*SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x2a,0x80);*/
4890                         SiS_PanelDelayLoop(SiS_Pr, 3, 5);
4891                         if(delaylong) {
4892                            SiS_PanelDelayLoop(SiS_Pr, 3, 5);
4893                            delaylong = false;
4894                         }
4895                         SiS_WaitVBRetrace(SiS_Pr);
4896                         SiS_WaitVBRetrace(SiS_Pr);
4897                         if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4898                            SiS_GenericDelay(SiS_Pr, 1280);
4899                         }
4900                         SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40);   /* Enable */
4901                         /*SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);*/
4902                      }
4903                   }
4904 #endif
4905                }
4906             }
4907 
4908             if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4909                if(SiS_IsVAorLCD(SiS_Pr)) {
4910                   SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4911                   if(delaylong) {
4912                      SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4913                   }
4914                   SiS_WaitVBRetrace(SiS_Pr);
4915                   if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4916                      SiS_GenericDelay(SiS_Pr, 2048);
4917                      SiS_WaitVBRetrace(SiS_Pr);
4918                   }
4919                   if(!didpwd) {
4920                      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4921                   } else {
4922                      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x03);
4923                   }
4924                }
4925             }
4926 
4927             SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4928             SiS_DisplayOn(SiS_Pr);
4929             SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xff);
4930 
4931          }
4932 
4933          if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4934             SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4935          }
4936 
4937 #endif /* CONFIG_FB_SIS_315 */
4938 
4939       }
4940 
4941     } else {    /* ============  For 301 ================ */
4942 
4943        if(SiS_Pr->ChipType < SIS_315H) {
4944           if(SiS_CRT2IsLCD(SiS_Pr)) {
4945              SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4946              SiS_PanelDelay(SiS_Pr, 0);
4947           }
4948        }
4949 
4950        temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;          /* lock mode */
4951        if(SiS_BridgeInSlavemode(SiS_Pr)) {
4952           tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4953           if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4954        }
4955        SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4956 
4957        SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                  /* enable CRT2 */
4958 
4959        if(SiS_Pr->ChipType >= SIS_315H) {
4960           temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4961           if(!(temp & 0x80)) {
4962              SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);         /* BVBDOENABLE=1 */
4963           }
4964        }
4965 
4966        SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20);     /* enable VB processor */
4967 
4968        SiS_VBLongWait(SiS_Pr);
4969        SiS_DisplayOn(SiS_Pr);
4970        if(SiS_Pr->ChipType >= SIS_315H) {
4971           SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4972        }
4973        SiS_VBLongWait(SiS_Pr);
4974 
4975        if(SiS_Pr->ChipType < SIS_315H) {
4976           if(SiS_CRT2IsLCD(SiS_Pr)) {
4977              SiS_PanelDelay(SiS_Pr, 1);
4978              SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4979           }
4980        }
4981 
4982     }
4983 
4984   } else {   /* =================== For LVDS ================== */
4985 
4986     if(SiS_Pr->ChipType < SIS_315H) {
4987 
4988 #ifdef CONFIG_FB_SIS_300    /* 300 series */
4989 
4990        if(SiS_CRT2IsLCD(SiS_Pr)) {
4991           if(SiS_Pr->ChipType == SIS_730) {
4992              SiS_PanelDelay(SiS_Pr, 1);
4993              SiS_PanelDelay(SiS_Pr, 1);
4994              SiS_PanelDelay(SiS_Pr, 1);
4995           }
4996           SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4997           if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
4998              SiS_PanelDelay(SiS_Pr, 0);
4999           }
5000        }
5001 
5002        SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
5003        SiS_DisplayOn(SiS_Pr);
5004        SiS_UnLockCRT2(SiS_Pr);
5005        SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
5006        if(SiS_BridgeInSlavemode(SiS_Pr)) {
5007           SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
5008        } else {
5009           SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
5010        }
5011 
5012        if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
5013           if(!(SiS_CRT2IsLCD(SiS_Pr))) {
5014              SiS_WaitVBRetrace(SiS_Pr);
5015              SiS_SetCH700x(SiS_Pr,0x0E,0x0B);
5016           }
5017        }
5018 
5019        if(SiS_CRT2IsLCD(SiS_Pr)) {
5020           if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
5021              if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
5022                 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
5023                    SiS_PanelDelay(SiS_Pr, 1);
5024                    SiS_PanelDelay(SiS_Pr, 1);
5025                 }
5026                 SiS_WaitVBRetrace(SiS_Pr);
5027                 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
5028              }
5029           }
5030        }
5031 
5032 #endif  /* CONFIG_FB_SIS_300 */
5033 
5034     } else {
5035 
5036 #ifdef CONFIG_FB_SIS_315    /* 315 series */
5037 
5038        if(!(SiS_IsNotM650orLater(SiS_Pr))) {
5039           /*if(SiS_Pr->ChipType < SIS_340) {*/  /* XGI needs this */
5040              SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x18);
5041           /*}*/
5042        }
5043 
5044        if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
5045           if(SiS_CRT2IsLCD(SiS_Pr)) {
5046              SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
5047              SiS_PanelDelay(SiS_Pr, 0);
5048           }
5049        }
5050 
5051        SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
5052        SiS_UnLockCRT2(SiS_Pr);
5053 
5054        SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
5055 
5056        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
5057           temp = SiS_GetCH701x(SiS_Pr,0x66);
5058           temp &= 0x20;
5059           SiS_Chrontel701xBLOff(SiS_Pr);
5060        }
5061 
5062        if(SiS_Pr->ChipType != SIS_550) {
5063           SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
5064        }
5065 
5066        if(SiS_Pr->ChipType == SIS_740) {
5067           if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
5068              if(SiS_IsLCDOrLCDA(SiS_Pr)) {
5069                 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
5070              }
5071           }
5072        }
5073 
5074        temp1 = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
5075        if(!(temp1 & 0x80)) {
5076           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
5077        }
5078 
5079        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
5080           if(temp) {
5081              SiS_Chrontel701xBLOn(SiS_Pr);
5082           }
5083        }
5084 
5085        if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
5086           if(SiS_CRT2IsLCD(SiS_Pr)) {
5087              SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
5088              if(SiS_Pr->ChipType == SIS_550) {
5089                 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x40);
5090                 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x10);
5091              }
5092           }
5093        } else if(SiS_IsVAMode(SiS_Pr)) {
5094           if(SiS_Pr->ChipType != SIS_740) {
5095              SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
5096           }
5097        }
5098 
5099        if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
5100           SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
5101        }
5102 
5103        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
5104           if(SiS_IsTVOrYPbPrOrScart(SiS_Pr)) {
5105              SiS_Chrontel701xOn(SiS_Pr);
5106           }
5107           if( (SiS_IsVAMode(SiS_Pr)) ||
5108               (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
5109              SiS_ChrontelDoSomething1(SiS_Pr);
5110           }
5111        }
5112 
5113        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
5114           if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
5115              if( (SiS_IsVAMode(SiS_Pr)) ||
5116                  (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
5117                 SiS_Chrontel701xBLOn(SiS_Pr);
5118                 SiS_ChrontelInitTVVSync(SiS_Pr);
5119              }
5120           }
5121        } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
5122           if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
5123              if(SiS_CRT2IsLCD(SiS_Pr)) {
5124                 SiS_PanelDelay(SiS_Pr, 1);
5125                 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
5126              }
5127           }
5128        }
5129 
5130 #endif  /* CONFIG_FB_SIS_315 */
5131 
5132     } /* 310 series */
5133 
5134   }  /* LVDS */
5135 
5136 }
5137 
5138 /*********************************************/
5139 /*         SET PART 1 REGISTER GROUP         */
5140 /*********************************************/
5141 
5142 /* Set CRT2 OFFSET / PITCH */
5143 static void
5144 SiS_SetCRT2Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
5145                 unsigned short RRTI)
5146 {
5147    unsigned short offset;
5148    unsigned char  temp;
5149 
5150    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return;
5151 
5152    offset = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,RRTI);
5153 
5154    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(offset & 0xFF));
5155    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,(offset >> 8));
5156 
5157    temp = (unsigned char)(((offset >> 3) & 0xFF) + 1);
5158    if(offset & 0x07) temp++;
5159    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,temp);
5160 }
5161 
5162 /* Set CRT2 sync and PanelLink mode */
5163 static void
5164 SiS_SetCRT2Sync(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RefreshRateTableIndex)
5165 {
5166    unsigned short tempah=0, tempbl, infoflag;
5167 
5168    tempbl = 0xC0;
5169 
5170    if(SiS_Pr->UseCustomMode) {
5171       infoflag = SiS_Pr->CInfoFlag;
5172    } else {
5173       infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
5174    }
5175 
5176    if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {                                   /* LVDS */
5177 
5178       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5179          tempah = 0;
5180       } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) {
5181          tempah = SiS_Pr->SiS_LCDInfo;
5182       } else tempah = infoflag >> 8;
5183       tempah &= 0xC0;
5184       tempah |= 0x20;
5185       if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5186       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5187          if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
5188             (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
5189             tempah |= 0xf0;
5190          }
5191          if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
5192              (SiS_Pr->SiS_IF_DEF_DSTN) ||
5193              (SiS_Pr->SiS_IF_DEF_TRUMPION) ||
5194              (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
5195              (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
5196             tempah |= 0x30;
5197          }
5198          if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
5199              (SiS_Pr->SiS_IF_DEF_DSTN) ) {
5200             tempah &= ~0xc0;
5201          }
5202       }
5203       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5204          if(SiS_Pr->ChipType >= SIS_315H) {
5205             tempah >>= 3;
5206             tempah &= 0x18;
5207             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xE7,tempah);
5208             /* Don't care about 12/18/24 bit mode - TV is via VGA, not PL */
5209          } else {
5210             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,0xe0);
5211          }
5212       } else {
5213          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5214       }
5215 
5216    } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5217 
5218       if(SiS_Pr->ChipType < SIS_315H) {
5219 
5220 #ifdef CONFIG_FB_SIS_300  /* ---- 300 series --- */
5221 
5222          if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {                        /* 630 - 301B(-DH) */
5223 
5224             tempah = infoflag >> 8;
5225             tempbl = 0;
5226             if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5227                if(SiS_Pr->SiS_LCDInfo & LCDSync) {
5228                   tempah = SiS_Pr->SiS_LCDInfo;
5229                   tempbl = (tempah >> 6) & 0x03;
5230                }
5231             }
5232             tempah &= 0xC0;
5233             tempah |= 0x20;
5234             if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5235             tempah |= 0xc0;
5236             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5237             if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
5238                SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
5239             }
5240 
5241          } else {                                                       /* 630 - 301 */
5242 
5243             tempah = ((infoflag >> 8) & 0xc0) | 0x20;
5244             if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5245             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5246 
5247          }
5248 
5249 #endif /* CONFIG_FB_SIS_300 */
5250 
5251       } else {
5252 
5253 #ifdef CONFIG_FB_SIS_315  /* ------- 315 series ------ */
5254 
5255          if(SiS_Pr->SiS_VBType & VB_SISLVDS) {                  /* 315 - LVDS */
5256 
5257             tempbl = 0;
5258             if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
5259                (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
5260                tempah = infoflag >> 8;
5261                if(SiS_Pr->SiS_LCDInfo & LCDSync) {
5262                  tempbl = ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6);
5263                }
5264             } else if((SiS_Pr->SiS_CustomT == CUT_CLEVO1400)  &&
5265                       (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)) {
5266                tempah = infoflag >> 8;
5267                tempbl = 0x03;
5268             } else {
5269                tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
5270                tempbl = (tempah >> 6) & 0x03;
5271                tempbl |= 0x08;
5272                if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempbl |= 0x04;
5273             }
5274             tempah &= 0xC0;
5275             tempah |= 0x20;
5276             if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5277             if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)   tempah |= 0xc0;
5278             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5279             if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
5280                if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5281                   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
5282                }
5283             }
5284 
5285          } else {                                                       /* 315 - TMDS */
5286 
5287             tempah = tempbl = infoflag >> 8;
5288             if(!SiS_Pr->UseCustomMode) {
5289                tempbl = 0;
5290                if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
5291                   if(ModeNo <= 0x13) {
5292                      tempah = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
5293                   }
5294                }
5295                if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5296                   if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5297                     if(SiS_Pr->SiS_LCDInfo & LCDSync) {
5298                        tempah = SiS_Pr->SiS_LCDInfo;
5299                        tempbl = (tempah >> 6) & 0x03;
5300                     }
5301                   }
5302                }
5303             }
5304             tempah &= 0xC0;
5305             tempah |= 0x20;
5306             if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5307             if(SiS_Pr->SiS_VBType & VB_NoLCD) {
5308                /* Imitate BIOS bug */
5309                if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)  tempah |= 0xc0;
5310             }
5311             if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
5312                tempah >>= 3;
5313                tempah &= 0x18;
5314                SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xe7,tempah);
5315             } else {
5316                SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5317                if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
5318                   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5319                      SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
5320                   }
5321                }
5322             }
5323 
5324          }
5325 #endif  /* CONFIG_FB_SIS_315 */
5326       }
5327    }
5328 }
5329 
5330 /* Set CRT2 FIFO on 300/540/630/730 */
5331 #ifdef CONFIG_FB_SIS_300
5332 static void
5333 SiS_SetCRT2FIFO_300(struct SiS_Private *SiS_Pr,unsigned short ModeNo)
5334 {
5335   unsigned char  *ROMAddr  = SiS_Pr->VirtualRomBase;
5336   unsigned short temp, index, modeidindex, refreshratetableindex;
5337   unsigned short VCLK = 0, MCLK, colorth = 0, data2 = 0;
5338   unsigned short tempbx, tempcl, CRT1ModeNo, CRT2ModeNo, SelectRate_backup;
5339   unsigned int   data, pci50, pciA0;
5340   static const unsigned char colortharray[] = {
5341         1, 1, 2, 2, 3, 4
5342   };
5343 
5344   SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;
5345 
5346   if(!SiS_Pr->CRT1UsesCustomMode) {
5347 
5348      CRT1ModeNo = SiS_Pr->SiS_CRT1Mode;                                 /* get CRT1 ModeNo */
5349      SiS_SearchModeID(SiS_Pr, &CRT1ModeNo, &modeidindex);
5350      SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
5351      SiS_Pr->SiS_SelectCRT2Rate = 0;
5352      refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT1ModeNo, modeidindex);
5353 
5354      if(CRT1ModeNo >= 0x13) {
5355         /* Get VCLK */
5356         index = SiS_GetRefCRTVCLK(SiS_Pr, refreshratetableindex, SiS_Pr->SiS_UseWide);
5357         VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
5358 
5359         /* Get colordepth */
5360         colorth = SiS_GetColorDepth(SiS_Pr,CRT1ModeNo,modeidindex) >> 1;
5361         if(!colorth) colorth++;
5362      }
5363 
5364   } else {
5365 
5366      CRT1ModeNo = 0xfe;
5367 
5368      /* Get VCLK */
5369      VCLK = SiS_Pr->CSRClock_CRT1;
5370 
5371      /* Get color depth */
5372      colorth = colortharray[((SiS_Pr->CModeFlag_CRT1 & ModeTypeMask) - 2)];
5373 
5374   }
5375 
5376   if(CRT1ModeNo >= 0x13) {
5377      /* Get MCLK */
5378      if(SiS_Pr->ChipType == SIS_300) {
5379         index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A);
5380      } else {
5381         index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A);
5382      }
5383      index &= 0x07;
5384      MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;
5385 
5386      temp = ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) >> 6) & 0x03) << 1;
5387      if(!temp) temp++;
5388      temp <<= 2;
5389 
5390      data2 = temp - ((colorth * VCLK) / MCLK);
5391 
5392      temp = (28 * 16) % data2;
5393      data2 = (28 * 16) / data2;
5394      if(temp) data2++;
5395 
5396      if(SiS_Pr->ChipType == SIS_300) {
5397 
5398         SiS_GetFIFOThresholdIndex300(SiS_Pr, &tempbx, &tempcl);
5399         data = SiS_GetFIFOThresholdB300(tempbx, tempcl);
5400 
5401      } else {
5402 
5403         pci50 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0x50);
5404         pciA0 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0xa0);
5405 
5406         if(SiS_Pr->ChipType == SIS_730) {
5407 
5408            index = (unsigned short)(((pciA0 >> 28) & 0x0f) * 3);
5409            index += (unsigned short)(((pci50 >> 9)) & 0x03);
5410 
5411            /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */
5412            index = 0;  /* -- do it like the BIOS anyway... */
5413 
5414         } else {
5415 
5416            pci50 >>= 24;
5417            pciA0 >>= 24;
5418 
5419            index = (pci50 >> 1) & 0x07;
5420 
5421            if(pci50 & 0x01)    index += 6;
5422            if(!(pciA0 & 0x01)) index += 24;
5423 
5424            if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80) index += 12;
5425 
5426         }
5427 
5428         data = SiS_GetLatencyFactor630(SiS_Pr, index) + 15;
5429         if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80)) data += 5;
5430 
5431      }
5432 
5433      data += data2;                                             /* CRT1 Request Period */
5434 
5435      SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5436      SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5437 
5438      if(!SiS_Pr->UseCustomMode) {
5439 
5440         CRT2ModeNo = ModeNo;
5441         SiS_SearchModeID(SiS_Pr, &CRT2ModeNo, &modeidindex);
5442 
5443         refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT2ModeNo, modeidindex);
5444 
5445         /* Get VCLK  */
5446         index = SiS_GetVCLK2Ptr(SiS_Pr, CRT2ModeNo, modeidindex, refreshratetableindex);
5447         VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
5448 
5449         if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
5450            if(SiS_Pr->SiS_UseROM) {
5451               if(ROMAddr[0x220] & 0x01) {
5452                  VCLK = ROMAddr[0x229] | (ROMAddr[0x22a] << 8);
5453               }
5454            }
5455         }
5456 
5457      } else {
5458 
5459         /* Get VCLK */
5460         CRT2ModeNo = 0xfe;
5461         VCLK = SiS_Pr->CSRClock;
5462 
5463      }
5464 
5465      /* Get colordepth */
5466      colorth = SiS_GetColorDepth(SiS_Pr,CRT2ModeNo,modeidindex) >> 1;
5467      if(!colorth) colorth++;
5468 
5469      data = data * VCLK * colorth;
5470      temp = data % (MCLK << 4);
5471      data = data / (MCLK << 4);
5472      if(temp) data++;
5473 
5474      if(data < 6) data = 6;
5475      else if(data > 0x14) data = 0x14;
5476 
5477      if(SiS_Pr->ChipType == SIS_300) {
5478         temp = 0x16;
5479         if((data <= 0x0f) || (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024))
5480            temp = 0x13;
5481      } else {
5482         temp = 0x16;
5483         if(( (SiS_Pr->ChipType == SIS_630) ||
5484              (SiS_Pr->ChipType == SIS_730) )  &&
5485            (SiS_Pr->ChipRevision >= 0x30))
5486            temp = 0x1b;
5487      }
5488      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0xe0,temp);
5489 
5490      if((SiS_Pr->ChipType == SIS_630) &&
5491         (SiS_Pr->ChipRevision >= 0x30)) {
5492         if(data > 0x13) data = 0x13;
5493      }
5494      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,0xe0,data);
5495 
5496   } else {  /* If mode <= 0x13, we just restore everything */
5497 
5498      SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5499      SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5500 
5501   }
5502 }
5503 #endif
5504 
5505 /* Set CRT2 FIFO on 315/330 series */
5506 #ifdef CONFIG_FB_SIS_315
5507 static void
5508 SiS_SetCRT2FIFO_310(struct SiS_Private *SiS_Pr)
5509 {
5510   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3B);
5511   if( (SiS_Pr->ChipType == SIS_760)      &&
5512       (SiS_Pr->SiS_SysFlags & SF_760LFB)  &&
5513       (SiS_Pr->SiS_ModeType == Mode32Bpp) &&
5514       (SiS_Pr->SiS_VGAHDE >= 1280)        &&
5515       (SiS_Pr->SiS_VGAVDE >= 1024) ) {
5516      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x03);
5517      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3b);
5518      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5519      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x01);
5520      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5521      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,0x6e);
5522   } else {
5523      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3f,0x04);
5524   }
5525 
5526 }
5527 #endif
5528 
5529 static unsigned short
5530 SiS_GetVGAHT2(struct SiS_Private *SiS_Pr)
5531 {
5532   unsigned int tempax,tempbx;
5533 
5534   tempbx = (SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) * SiS_Pr->SiS_RVBHCMAX;
5535   tempax = (SiS_Pr->SiS_VT - SiS_Pr->SiS_VDE) * SiS_Pr->SiS_RVBHCFACT;
5536   tempax = (tempax * SiS_Pr->SiS_HT) / tempbx;
5537   return (unsigned short)tempax;
5538 }
5539 
5540 /* Set Part 1 / SiS bridge slave mode */
5541 static void
5542 SiS_SetGroup1_301(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,
5543                   unsigned short RefreshRateTableIndex)
5544 {
5545   unsigned short temp, modeflag, i, j, xres=0, VGAVDE;
5546   static const unsigned short CRTranslation[] = {
5547        /* CR0   CR1   CR2   CR3   CR4   CR5   CR6   CR7   */
5548           0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
5549        /* CR8   CR9   SR0A  SR0B  SR0C  SR0D  SR0E  CR0F  */
5550           0x00, 0x0b, 0x17, 0x18, 0x19, 0x00, 0x1a, 0x00,
5551        /* CR10  CR11  CR12  CR13  CR14  CR15  CR16  CR17  */
5552           0x0c, 0x0d, 0x0e, 0x00, 0x0f, 0x10, 0x11, 0x00
5553   };
5554 
5555   if(ModeNo <= 0x13) {
5556      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5557   } else if(SiS_Pr->UseCustomMode) {
5558      modeflag = SiS_Pr->CModeFlag;
5559      xres = SiS_Pr->CHDisplay;
5560   } else {
5561      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5562      xres = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes;
5563   }
5564 
5565   /* The following is only done if bridge is in slave mode: */
5566 
5567   if(SiS_Pr->ChipType >= SIS_315H) {
5568      if(xres >= 1600) {  /* BIOS: == 1600 */
5569         SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x31,0x04);
5570      }
5571   }
5572 
5573   SiS_Pr->CHTotal = 8224;  /* Max HT, 0x2020, results in 0x3ff in registers */
5574 
5575   SiS_Pr->CHDisplay = SiS_Pr->SiS_VGAHDE;
5576   if(modeflag & HalfDCLK) SiS_Pr->CHDisplay >>= 1;
5577 
5578   SiS_Pr->CHBlankStart = SiS_Pr->CHDisplay;
5579   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5580      SiS_Pr->CHBlankStart += 16;
5581   }
5582 
5583   SiS_Pr->CHBlankEnd = 32;
5584   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5585      if(xres == 1600) SiS_Pr->CHBlankEnd += 80;
5586   }
5587 
5588   temp = SiS_Pr->SiS_VGAHT - 96;
5589   if(!(modeflag & HalfDCLK)) temp -= 32;
5590   if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
5591      temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x04);
5592      temp |= ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x0b) & 0xc0) << 2);
5593      temp -= 3;
5594      temp <<= 3;
5595   } else {
5596      if(SiS_Pr->SiS_RVBHRS2) temp = SiS_Pr->SiS_RVBHRS2;
5597   }
5598   SiS_Pr->CHSyncStart = temp;
5599 
5600   SiS_Pr->CHSyncEnd = 0xffe8;   /* results in 0x2000 in registers */
5601 
5602   SiS_Pr->CVTotal = 2049;       /* Max VT, 0x0801, results in 0x7ff in registers */
5603 
5604   VGAVDE = SiS_Pr->SiS_VGAVDE;
5605   if     (VGAVDE ==  357) VGAVDE =  350;
5606   else if(VGAVDE ==  360) VGAVDE =  350;
5607   else if(VGAVDE ==  375) VGAVDE =  350;
5608   else if(VGAVDE ==  405) VGAVDE =  400;
5609   else if(VGAVDE ==  420) VGAVDE =  400;
5610   else if(VGAVDE ==  525) VGAVDE =  480;
5611   else if(VGAVDE == 1056) VGAVDE = 1024;
5612   SiS_Pr->CVDisplay = VGAVDE;
5613 
5614   SiS_Pr->CVBlankStart = SiS_Pr->CVDisplay;
5615 
5616   SiS_Pr->CVBlankEnd = 1;
5617   if(ModeNo == 0x3c) SiS_Pr->CVBlankEnd = 226;
5618 
5619   temp = (SiS_Pr->SiS_VGAVT - VGAVDE) >> 1;
5620   SiS_Pr->CVSyncStart = VGAVDE + temp;
5621 
5622   temp >>= 3;
5623   SiS_Pr->CVSyncEnd = SiS_Pr->CVSyncStart + temp;
5624 
5625   SiS_CalcCRRegisters(SiS_Pr, 0);
5626   SiS_Pr->CCRT1CRTC[16] &= ~0xE0;
5627 
5628   for(i = 0; i <= 7; i++) {
5629      SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[i]);
5630   }
5631   for(i = 0x10, j = 8; i <= 0x12; i++, j++) {
5632      SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5633   }
5634   for(i = 0x15, j = 11; i <= 0x16; i++, j++) {
5635      SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5636   }
5637   for(i = 0x0a, j = 13; i <= 0x0c; i++, j++) {
5638      SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5639   }
5640 
5641   temp = SiS_Pr->CCRT1CRTC[16] & 0xE0;
5642   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x0E],0x1F,temp);
5643 
5644   temp = (SiS_Pr->CCRT1CRTC[16] & 0x01) << 5;
5645   if(modeflag & DoubleScanMode) temp |= 0x80;
5646   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x09],0x5F,temp);
5647 
5648   temp = 0;
5649   temp |= (SiS_GetReg(SiS_Pr->SiS_P3c4,0x01) & 0x01);
5650   if(modeflag & HalfDCLK) temp |= 0x08;
5651   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp);                  /* SR01: HalfDCLK[3], 8/9 div dotclock[0] */
5652 
5653   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,0x00);                  /* CR14: (text mode: underline location) */
5654   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,0x00);                  /* CR17: n/a */
5655 
5656   temp = 0;
5657   if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5658      temp = (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) << 7;
5659   }
5660   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp);                  /* SR0E, dither[7] */
5661 
5662   temp = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
5663   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);                  /* ? */
5664 }
5665 
5666 /* Setup panel link
5667  * This is used for LVDS, LCDA and Chrontel TV output
5668  * 300/LVDS+TV, 300/301B-DH, 315/LVDS+TV, 315/LCDA
5669  */
5670 static void
5671 SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
5672                 unsigned short RefreshRateTableIndex)
5673 {
5674   unsigned short modeflag, resinfo = 0;
5675   unsigned short push2, tempax, tempbx, tempcx, temp;
5676   unsigned int   tempeax = 0, tempebx, tempecx, tempvcfact = 0;
5677   bool islvds = false, issis  = false, chkdclkfirst = false;
5678 #ifdef CONFIG_FB_SIS_300
5679   unsigned short crt2crtc = 0;
5680 #endif
5681 #ifdef CONFIG_FB_SIS_315
5682   unsigned short pushcx;
5683 #endif
5684 
5685   if(ModeNo <= 0x13) {
5686      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5687      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
5688 #ifdef CONFIG_FB_SIS_300
5689      crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
5690 #endif
5691   } else if(SiS_Pr->UseCustomMode) {
5692      modeflag = SiS_Pr->CModeFlag;
5693   } else {
5694      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5695      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
5696 #ifdef CONFIG_FB_SIS_300
5697      crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
5698 #endif
5699   }
5700 
5701   /* is lvds if really LVDS, or 301B-DH with external LVDS transmitter */
5702   if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
5703      islvds = true;
5704   }
5705 
5706   /* is really sis if sis bridge, but not 301B-DH */
5707   if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
5708      issis = true;
5709   }
5710 
5711   if((SiS_Pr->ChipType >= SIS_315H) && (islvds) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA))) {
5712      if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
5713         chkdclkfirst = true;
5714      }
5715   }
5716 
5717 #ifdef CONFIG_FB_SIS_315
5718   if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
5719      if(IS_SIS330) {
5720         SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5721      } else if(IS_SIS740) {
5722         if(islvds) {
5723            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5724            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x03);
5725         } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5726            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5727         }
5728      } else {
5729         if(islvds) {
5730            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5731            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x00);
5732         } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5733            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2D,0x0f);
5734            if(SiS_Pr->SiS_VBType & VB_SIS30xC) {
5735               if((SiS_Pr->SiS_LCDResInfo == Panel_1024x768) ||
5736                  (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
5737                  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x20);
5738               }
5739            }
5740         }
5741      }
5742   }
5743 #endif
5744 
5745   /* Horizontal */
5746 
5747   tempax = SiS_Pr->SiS_LCDHDES;
5748   if(islvds) {
5749      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5750         if(!SiS_Pr->SiS_IF_DEF_FSTN && !SiS_Pr->SiS_IF_DEF_DSTN) {
5751            if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) &&
5752               (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
5753               tempax -= 8;
5754            }
5755         }
5756      }
5757   }
5758 
5759   temp = (tempax & 0x0007);
5760   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp);                  /* BPLHDESKEW[2:0]   */
5761   temp = (tempax >> 3) & 0x00FF;
5762   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp);                  /* BPLHDESKEW[10:3]  */
5763 
5764   tempbx = SiS_Pr->SiS_HDE;
5765   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5766      if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5767         tempbx = SiS_Pr->PanelXRes;
5768      }
5769      if((SiS_Pr->SiS_LCDResInfo == Panel_320x240_1) ||
5770         (SiS_Pr->SiS_LCDResInfo == Panel_320x240_2) ||
5771         (SiS_Pr->SiS_LCDResInfo == Panel_320x240_3)) {
5772         tempbx >>= 1;
5773      }
5774   }
5775 
5776   tempax += tempbx;
5777   if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;
5778 
5779   temp = tempax;
5780   if(temp & 0x07) temp += 8;
5781   temp >>= 3;
5782   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp);                  /* BPLHDEE  */
5783 
5784   tempcx = (SiS_Pr->SiS_HT - tempbx) >> 2;
5785 
5786   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5787      if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5788         if(SiS_Pr->PanelHRS != 999) tempcx = SiS_Pr->PanelHRS;
5789      }
5790   }
5791 
5792   tempcx += tempax;
5793   if(tempcx >= SiS_Pr->SiS_HT) tempcx -= SiS_Pr->SiS_HT;
5794 
5795   temp = (tempcx >> 3) & 0x00FF;
5796   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5797      if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5798         if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5799            switch(ModeNo) {
5800            case 0x04:
5801            case 0x05:
5802            case 0x0d: temp = 0x56; break;
5803            case 0x10: temp = 0x60; break;
5804            case 0x13: temp = 0x5f; break;
5805            case 0x40:
5806            case 0x41:
5807            case 0x4f:
5808            case 0x43:
5809            case 0x44:
5810            case 0x62:
5811            case 0x56:
5812            case 0x53:
5813            case 0x5d:
5814            case 0x5e: temp = 0x54; break;
5815            }
5816         }
5817      }
5818   }
5819   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,temp);                  /* BPLHRS */
5820 
5821   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5822      temp += 2;
5823      if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5824         temp += 8;
5825         if(SiS_Pr->PanelHRE != 999) {
5826            temp = tempcx + SiS_Pr->PanelHRE;
5827            if(temp >= SiS_Pr->SiS_HT) temp -= SiS_Pr->SiS_HT;
5828            temp >>= 3;
5829         }
5830      }
5831   } else {
5832      temp += 10;
5833   }
5834 
5835   temp &= 0x1F;
5836   temp |= ((tempcx & 0x07) << 5);
5837   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,temp);                  /* BPLHRE */
5838 
5839   /* Vertical */
5840 
5841   tempax = SiS_Pr->SiS_VGAVDE;
5842   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5843      if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5844         tempax = SiS_Pr->PanelYRes;
5845      }
5846   }
5847 
5848   tempbx = SiS_Pr->SiS_LCDVDES + tempax;
5849   if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5850 
5851   push2 = tempbx;
5852 
5853   tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE;
5854   if(SiS_Pr->ChipType < SIS_315H) {
5855      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5856         if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5857            tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->PanelYRes;
5858         }
5859      }
5860   }
5861   if(islvds) tempcx >>= 1;
5862   else       tempcx >>= 2;
5863 
5864   if( (SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
5865       (!(SiS_Pr->SiS_LCDInfo & LCDPass11))                  &&
5866       (SiS_Pr->PanelVRS != 999) ) {
5867      tempcx = SiS_Pr->PanelVRS;
5868      tempbx += tempcx;
5869      if(issis) tempbx++;
5870   } else {
5871      tempbx += tempcx;
5872      if(SiS_Pr->ChipType < SIS_315H) tempbx++;
5873      else if(issis)                   tempbx++;
5874   }
5875 
5876   if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5877 
5878   temp = tempbx & 0x00FF;
5879   if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5880      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5881         if(ModeNo == 0x10) temp = 0xa9;
5882      }
5883   }
5884   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);                  /* BPLVRS */
5885 
5886   tempcx >>= 3;
5887   tempcx++;
5888 
5889   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5890      if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5891         if(SiS_Pr->PanelVRE != 999) tempcx = SiS_Pr->PanelVRE;
5892      }
5893   }
5894 
5895   tempcx += tempbx;
5896   temp = tempcx & 0x000F;
5897   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp);        /* BPLVRE  */
5898 
5899   temp = ((tempbx >> 8) & 0x07) << 3;
5900   if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
5901      if(SiS_Pr->SiS_HDE != 640) {
5902         if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE)  temp |= 0x40;
5903      }
5904   } else if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
5905   if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA)          temp |= 0x40;
5906   tempbx = 0x87;
5907   if((SiS_Pr->ChipType >= SIS_315H) ||
5908      (SiS_Pr->ChipRevision >= 0x30)) {
5909      tempbx = 0x07;
5910      if((SiS_Pr->SiS_IF_DEF_CH70xx == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
5911         if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x03)    temp |= 0x80;
5912      }
5913      /* Chrontel 701x operates in 24bit mode (8-8-8, 2x12bit multiplexed) via VGA2 */
5914      if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5915         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5916            if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x10)      temp |= 0x80;
5917         } else {
5918            if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80;
5919         }
5920      }
5921   }
5922   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,tempbx,temp);
5923 
5924   tempbx = push2;                                               /* BPLVDEE */
5925 
5926   tempcx = SiS_Pr->SiS_LCDVDES;                                 /* BPLVDES */
5927 
5928   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5929      switch(SiS_Pr->SiS_LCDResInfo) {
5930      case Panel_640x480:
5931         tempbx = SiS_Pr->SiS_VGAVDE - 1;
5932         tempcx = SiS_Pr->SiS_VGAVDE;
5933         break;
5934      case Panel_800x600:
5935         if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5936            if(resinfo == SIS_RI_800x600) tempcx++;
5937         }
5938         break;
5939      case Panel_1024x600:
5940         if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5941            if(resinfo == SIS_RI_1024x600) tempcx++;
5942            if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
5943               if(resinfo == SIS_RI_800x600) tempcx++;
5944            }
5945         }
5946         break;
5947      case Panel_1024x768:
5948         if(SiS_Pr->ChipType < SIS_315H) {
5949            if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5950               if(resinfo == SIS_RI_1024x768) tempcx++;
5951            }
5952         }
5953         break;
5954      }
5955   }
5956 
5957   temp = ((tempbx >> 8) & 0x07) << 3;
5958   temp |= ((tempcx >> 8) & 0x07);
5959   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1D,temp);
5960   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1C,tempbx);
5961   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1B,tempcx);
5962 
5963   /* Vertical scaling */
5964 
5965   if(SiS_Pr->ChipType < SIS_315H) {
5966 
5967 #ifdef CONFIG_FB_SIS_300      /* 300 series */
5968      tempeax = SiS_Pr->SiS_VGAVDE << 6;
5969      temp = (tempeax % (unsigned int)SiS_Pr->SiS_VDE);
5970      tempeax = tempeax / (unsigned int)SiS_Pr->SiS_VDE;
5971      if(temp) tempeax++;
5972 
5973      if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) tempeax = 0x3F;
5974 
5975      temp = (unsigned short)(tempeax & 0x00FF);
5976      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,temp);       /* BPLVCFACT */
5977      tempvcfact = temp;
5978 #endif /* CONFIG_FB_SIS_300 */
5979 
5980   } else {
5981 
5982 #ifdef CONFIG_FB_SIS_315  /* 315 series */
5983      tempeax = SiS_Pr->SiS_VGAVDE << 18;
5984      tempebx = SiS_Pr->SiS_VDE;
5985      temp = (tempeax % tempebx);
5986      tempeax = tempeax / tempebx;
5987      if(temp) tempeax++;
5988      tempvcfact = tempeax;
5989 
5990      temp = (unsigned short)(tempeax & 0x00FF);
5991      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,temp);
5992      temp = (unsigned short)((tempeax & 0x00FF00) >> 8);
5993      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,temp);
5994      temp = (unsigned short)((tempeax & 0x00030000) >> 16);
5995      if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
5996      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,temp);
5997 
5998      if(SiS_Pr->SiS_VBType & VB_SISPART4SCALER) {
5999         temp = (unsigned short)(tempeax & 0x00FF);
6000         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3c,temp);
6001         temp = (unsigned short)((tempeax & 0x00FF00) >> 8);
6002         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3b,temp);
6003         temp = (unsigned short)(((tempeax & 0x00030000) >> 16) << 6);
6004         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0x3f,temp);
6005         temp = 0;
6006         if(SiS_Pr->SiS_VDE != SiS_Pr->SiS_VGAVDE) temp |= 0x08;
6007         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x30,0xf3,temp);
6008      }
6009 #endif
6010 
6011   }
6012 
6013   /* Horizontal scaling */
6014 
6015   tempeax = SiS_Pr->SiS_VGAHDE;         /* 1f = ( (VGAHDE * 65536) / ( (VGAHDE * 65536) / HDE ) ) - 1*/
6016   if(chkdclkfirst) {
6017      if(modeflag & HalfDCLK) tempeax >>= 1;
6018   }
6019   tempebx = tempeax << 16;
6020   if(SiS_Pr->SiS_HDE == tempeax) {
6021      tempecx = 0xFFFF;
6022   } else {
6023      tempecx = tempebx / SiS_Pr->SiS_HDE;
6024      if(SiS_Pr->ChipType >= SIS_315H) {
6025         if(tempebx % SiS_Pr->SiS_HDE) tempecx++;
6026      }
6027   }
6028 
6029   if(SiS_Pr->ChipType >= SIS_315H) {
6030      tempeax = (tempebx / tempecx) - 1;
6031   } else {
6032      tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1;
6033   }
6034   tempecx = (tempecx << 16) | (tempeax & 0xFFFF);
6035   temp = (unsigned short)(tempecx & 0x00FF);
6036   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1F,temp);
6037 
6038   if(SiS_Pr->ChipType >= SIS_315H) {
6039      tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
6040      tempbx = (unsigned short)(tempeax & 0xFFFF);
6041   } else {
6042      tempeax = SiS_Pr->SiS_VGAVDE << 6;
6043      tempbx = tempvcfact & 0x3f;
6044      if(tempbx == 0) tempbx = 64;
6045      tempeax /= tempbx;
6046      tempbx = (unsigned short)(tempeax & 0xFFFF);
6047   }
6048   if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tempbx--;
6049   if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
6050      if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) tempbx = 1;
6051      else if(SiS_Pr->SiS_LCDResInfo != Panel_640x480)             tempbx = 1;
6052   }
6053 
6054   temp = ((tempbx >> 8) & 0x07) << 3;
6055   temp = temp | ((tempecx >> 8) & 0x07);
6056   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x20,temp);
6057   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x21,tempbx);
6058 
6059   tempecx >>= 16;                                               /* BPLHCFACT  */
6060   if(!chkdclkfirst) {
6061      if(modeflag & HalfDCLK) tempecx >>= 1;
6062   }
6063   temp = (unsigned short)((tempecx & 0xFF00) >> 8);
6064   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x22,temp);
6065   temp = (unsigned short)(tempecx & 0x00FF);
6066   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp);
6067 
6068 #ifdef CONFIG_FB_SIS_315
6069   if(SiS_Pr->ChipType >= SIS_315H) {
6070      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
6071         if((islvds) || (SiS_Pr->SiS_VBInfo & VB_SISLVDS)) {
6072            SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x20);
6073         }
6074      } else {
6075         if(islvds) {
6076            if(SiS_Pr->ChipType == SIS_740) {
6077               SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
6078            } else {
6079               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x23);
6080            }
6081         }
6082      }
6083   }
6084 #endif
6085 
6086 #ifdef CONFIG_FB_SIS_300
6087   if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
6088      unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
6089      unsigned char *trumpdata;
6090      int   i, j = crt2crtc;
6091      unsigned char TrumpMode13[4]   = { 0x01, 0x10, 0x2c, 0x00 };
6092      unsigned char TrumpMode10_1[4] = { 0x01, 0x10, 0x27, 0x00 };
6093      unsigned char TrumpMode10_2[4] = { 0x01, 0x16, 0x10, 0x00 };
6094 
6095      if(SiS_Pr->SiS_UseROM) {
6096         trumpdata = &ROMAddr[0x8001 + (j * 80)];
6097      } else {
6098         if(SiS_Pr->SiS_LCDTypeInfo == 0x0e) j += 7;
6099         trumpdata = &SiS300_TrumpionData[j][0];
6100      }
6101 
6102      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xbf);
6103      for(i=0; i<5; i++) {
6104         SiS_SetTrumpionBlock(SiS_Pr, trumpdata);
6105      }
6106      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6107         if(ModeNo == 0x13) {
6108            for(i=0; i<4; i++) {
6109               SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode13[0]);
6110            }
6111         } else if(ModeNo == 0x10) {
6112            for(i=0; i<4; i++) {
6113               SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_1[0]);
6114               SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_2[0]);
6115            }
6116         }
6117      }
6118      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
6119   }
6120 #endif
6121 
6122 #ifdef CONFIG_FB_SIS_315
6123   if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
6124      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x25,0x00);
6125      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x26,0x00);
6126      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x27,0x00);
6127      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x28,0x87);
6128      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x29,0x5A);
6129      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2A,0x4B);
6130      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x07,0x03);
6131      tempax = SiS_Pr->SiS_HDE;                                  /* Blps = lcdhdee(lcdhdes+HDE) + 64 */
6132      if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
6133         SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
6134         SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
6135      tempax += 64;
6136      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,tempax & 0xff);
6137      temp = (tempax >> 8) << 3;
6138      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp);
6139      tempax += 32;                                              /* Blpe = lBlps+32 */
6140      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,tempax & 0xff);
6141      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3A,0x00);               /* Bflml = 0 */
6142      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x007);
6143 
6144      tempax = SiS_Pr->SiS_VDE;
6145      if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
6146         SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
6147         SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
6148      tempax >>= 1;
6149      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3B,tempax & 0xff);
6150      temp = (tempax >> 8) << 3;
6151      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);
6152 
6153      tempeax = SiS_Pr->SiS_HDE;
6154      if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
6155         SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
6156         SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempeax >>= 1;
6157      tempeax <<= 2;                                             /* BDxFIFOSTOP = (HDE*4)/128 */
6158      temp = tempeax & 0x7f;
6159      tempeax >>= 7;
6160      if(temp) tempeax++;
6161      temp = tempeax & 0x3f;
6162      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,temp);
6163      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3F,0x00);               /* BDxWadrst0 */
6164      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3E,0x00);
6165      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3D,0x10);
6166      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x040);
6167 
6168      tempax = SiS_Pr->SiS_HDE;
6169      if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
6170         SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
6171         SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
6172      tempax >>= 4;                                              /* BDxWadroff = HDE*4/8/8 */
6173      pushcx = tempax;
6174      temp = tempax & 0x00FF;
6175      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,temp);
6176      temp = ((tempax & 0xFF00) >> 8) << 3;
6177      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port, 0x44, 0x07, temp);
6178 
6179      tempax = SiS_Pr->SiS_VDE;                                  /* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
6180      if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
6181         SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
6182         SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
6183      tempeax = tempax * pushcx;
6184      temp = tempeax & 0xFF;
6185      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,temp);
6186      temp = (tempeax & 0xFF00) >> 8;
6187      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,temp);
6188      temp = ((tempeax & 0xFF0000) >> 16) | 0x10;
6189      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,temp);
6190      temp = ((tempeax & 0x01000000) >> 24) << 7;
6191      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port, 0x3C, 0x7F, temp);
6192 
6193      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x03);
6194      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0x50);
6195      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,0x00);
6196      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x01);
6197      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0x38);
6198 
6199      if(SiS_Pr->SiS_IF_DEF_FSTN) {
6200         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2b,0x02);
6201         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2c,0x00);
6202         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x00);
6203         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,0x0c);
6204         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,0x00);
6205         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,0x00);
6206         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,0x80);
6207         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,0xA0);
6208         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3a,0x00);
6209         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3b,0xf0);
6210         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3c,0x00);
6211         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3d,0x10);
6212         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3e,0x00);
6213         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3f,0x00);
6214         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,0x10);
6215         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,0x25);
6216         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,0x80);
6217         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,0x14);
6218         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x44,0x03);
6219         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,0x0a);
6220      }
6221   }
6222 #endif  /* CONFIG_FB_SIS_315 */
6223 }
6224 
6225 /* Set Part 1 */
6226 static void
6227 SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6228                 unsigned short RefreshRateTableIndex)
6229 {
6230 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
6231   unsigned char   *ROMAddr = SiS_Pr->VirtualRomBase;
6232 #endif
6233   unsigned short  temp=0, tempax=0, tempbx=0, tempcx=0, bridgeadd=0;
6234   unsigned short  pushbx=0, CRT1Index=0, modeflag, resinfo=0;
6235 #ifdef CONFIG_FB_SIS_315
6236   unsigned short  tempbl=0;
6237 #endif
6238 
6239   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
6240      SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6241      return;
6242   }
6243 
6244   if(ModeNo <= 0x13) {
6245      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6246   } else if(SiS_Pr->UseCustomMode) {
6247      modeflag = SiS_Pr->CModeFlag;
6248   } else {
6249      CRT1Index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);
6250      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
6251      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6252   }
6253 
6254   SiS_SetCRT2Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6255 
6256   if( ! ((SiS_Pr->ChipType >= SIS_315H) &&
6257          (SiS_Pr->SiS_IF_DEF_LVDS == 1) &&
6258          (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
6259 
6260      if(SiS_Pr->ChipType < SIS_315H ) {
6261 #ifdef CONFIG_FB_SIS_300
6262         SiS_SetCRT2FIFO_300(SiS_Pr, ModeNo);
6263 #endif
6264      } else {
6265 #ifdef CONFIG_FB_SIS_315
6266         SiS_SetCRT2FIFO_310(SiS_Pr);
6267 #endif
6268      }
6269 
6270      /* 1. Horizontal setup */
6271 
6272      if(SiS_Pr->ChipType < SIS_315H ) {
6273 
6274 #ifdef CONFIG_FB_SIS_300   /* ------------- 300 series --------------*/
6275 
6276         temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF;                   /* BTVGA2HT 0x08,0x09 */
6277         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp);              /* CRT2 Horizontal Total */
6278 
6279         temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
6280         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp);    /* CRT2 Horizontal Total Overflow [7:4] */
6281 
6282         temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF;                 /* BTVGA2HDEE 0x0A,0x0C */
6283         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp);              /* CRT2 Horizontal Display Enable End */
6284 
6285         pushbx = SiS_Pr->SiS_VGAHDE + 12;                         /* bx  BTVGA2HRS 0x0B,0x0C */
6286         tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2;
6287         tempbx = pushbx + tempcx;
6288         tempcx <<= 1;
6289         tempcx += tempbx;
6290 
6291         bridgeadd = 12;
6292 
6293 #endif /* CONFIG_FB_SIS_300 */
6294 
6295      } else {
6296 
6297 #ifdef CONFIG_FB_SIS_315  /* ------------------- 315/330 series --------------- */
6298 
6299         tempcx = SiS_Pr->SiS_VGAHT;                               /* BTVGA2HT 0x08,0x09 */
6300         if(modeflag & HalfDCLK) {
6301            if(SiS_Pr->SiS_VBType & VB_SISVB) {
6302               tempcx >>= 1;
6303            } else {
6304               tempax = SiS_Pr->SiS_VGAHDE >> 1;
6305               tempcx = SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE + tempax;
6306               if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
6307                  tempcx = SiS_Pr->SiS_HT - tempax;
6308               }
6309            }
6310         }
6311         tempcx--;
6312         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,tempcx);            /* CRT2 Horizontal Total */
6313         temp = (tempcx >> 4) & 0xF0;
6314         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp);    /* CRT2 Horizontal Total Overflow [7:4] */
6315 
6316         tempcx = SiS_Pr->SiS_VGAHT;                               /* BTVGA2HDEE 0x0A,0x0C */
6317         tempbx = SiS_Pr->SiS_VGAHDE;
6318         tempcx -= tempbx;
6319         tempcx >>= 2;
6320         if(modeflag & HalfDCLK) {
6321            tempbx >>= 1;
6322            tempcx >>= 1;
6323         }
6324         tempbx += 16;
6325 
6326         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,tempbx);            /* CRT2 Horizontal Display Enable End */
6327 
6328         pushbx = tempbx;
6329         tempcx >>= 1;
6330         tempbx += tempcx;
6331         tempcx += tempbx;
6332 
6333         bridgeadd = 16;
6334 
6335         if(SiS_Pr->SiS_VBType & VB_SISVB) {
6336            if(SiS_Pr->ChipType >= SIS_661) {
6337               if((SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
6338                  (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
6339                  if(resinfo == SIS_RI_1280x1024) {
6340                     tempcx = (tempcx & 0xff00) | 0x30;
6341                  } else if(resinfo == SIS_RI_1600x1200) {
6342                     tempcx = (tempcx & 0xff00) | 0xff;
6343                  }
6344               }
6345            }
6346         }
6347 
6348 #endif  /* CONFIG_FB_SIS_315 */
6349 
6350      }  /* 315/330 series */
6351 
6352      if(SiS_Pr->SiS_VBType & VB_SISVB) {
6353 
6354         if(SiS_Pr->UseCustomMode) {
6355            tempbx = SiS_Pr->CHSyncStart + bridgeadd;
6356            tempcx = SiS_Pr->CHSyncEnd + bridgeadd;
6357            tempax = SiS_Pr->SiS_VGAHT;
6358            if(modeflag & HalfDCLK) tempax >>= 1;
6359            tempax--;
6360            if(tempcx > tempax) tempcx = tempax;
6361         }
6362 
6363         if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6364            unsigned char cr4, cr14, cr5, cr15;
6365            if(SiS_Pr->UseCustomMode) {
6366               cr4  = SiS_Pr->CCRT1CRTC[4];
6367               cr14 = SiS_Pr->CCRT1CRTC[14];
6368               cr5  = SiS_Pr->CCRT1CRTC[5];
6369               cr15 = SiS_Pr->CCRT1CRTC[15];
6370            } else {
6371               cr4  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
6372               cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
6373               cr5  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
6374               cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
6375            }
6376            tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3;                /* (VGAHRS-3)*8 */
6377            tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3;   /* (VGAHRE-3)*8 */
6378            tempcx &= 0x00FF;
6379            tempcx |= (tempbx & 0xFF00);
6380            tempbx += bridgeadd;
6381            tempcx += bridgeadd;
6382            tempax = SiS_Pr->SiS_VGAHT;
6383            if(modeflag & HalfDCLK) tempax >>= 1;
6384            tempax--;
6385            if(tempcx > tempax) tempcx = tempax;
6386         }
6387 
6388         if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {
6389            tempbx = 1040;
6390            tempcx = 1044;   /* HWCursor bug! */
6391         }
6392 
6393      }
6394 
6395      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,tempbx);               /* CRT2 Horizontal Retrace Start */
6396 
6397      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,tempcx);               /* CRT2 Horizontal Retrace End */
6398 
6399      temp = ((tempbx >> 8) & 0x0F) | ((pushbx >> 4) & 0xF0);
6400      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp);                 /* Overflow */
6401 
6402      /* 2. Vertical setup */
6403 
6404      tempcx = SiS_Pr->SiS_VGAVT - 1;
6405      temp = tempcx & 0x00FF;
6406 
6407      if(SiS_Pr->ChipType < SIS_661) {
6408         if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6409            if(SiS_Pr->ChipType < SIS_315H) {
6410               if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6411                  if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
6412                     temp--;
6413                  }
6414               }
6415            } else {
6416               temp--;
6417            }
6418         } else if(SiS_Pr->ChipType >= SIS_315H) {
6419            temp--;
6420         }
6421      }
6422      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp);                 /* CRT2 Vertical Total */
6423 
6424      tempbx = SiS_Pr->SiS_VGAVDE - 1;
6425      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,tempbx);               /* CRT2 Vertical Display Enable End */
6426 
6427      temp = ((tempbx >> 5) & 0x38) | ((tempcx >> 8) & 0x07);
6428      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,temp);                 /* Overflow */
6429 
6430      if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
6431         tempbx++;
6432         tempax = tempbx;
6433         tempcx++;
6434         tempcx -= tempax;
6435         tempcx >>= 2;
6436         tempbx += tempcx;
6437         if(tempcx < 4) tempcx = 4;
6438         tempcx >>= 2;
6439         tempcx += tempbx;
6440         tempcx++;
6441      } else {
6442         tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1;                 /*  BTVGA2VRS     0x10,0x11   */
6443         tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1;  /*  BTVGA2VRE     0x11        */
6444      }
6445 
6446      if(SiS_Pr->SiS_VBType & VB_SISVB) {
6447         if(SiS_Pr->UseCustomMode) {
6448            tempbx = SiS_Pr->CVSyncStart;
6449            tempcx = SiS_Pr->CVSyncEnd;
6450         }
6451         if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6452            unsigned char cr8, cr7, cr13;
6453            if(SiS_Pr->UseCustomMode) {
6454               cr8    = SiS_Pr->CCRT1CRTC[8];
6455               cr7    = SiS_Pr->CCRT1CRTC[7];
6456               cr13   = SiS_Pr->CCRT1CRTC[13];
6457               tempcx = SiS_Pr->CCRT1CRTC[9];
6458            } else {
6459               cr8    = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8];
6460               cr7    = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
6461               cr13   = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
6462               tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
6463            }
6464            tempbx = cr8;
6465            if(cr7  & 0x04) tempbx |= 0x0100;
6466            if(cr7  & 0x80) tempbx |= 0x0200;
6467            if(cr13 & 0x08) tempbx |= 0x0400;
6468         }
6469      }
6470      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,tempbx);               /* CRT2 Vertical Retrace Start */
6471 
6472      temp = ((tempbx >> 4) & 0x70) | (tempcx & 0x0F);
6473      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,temp);                 /* CRT2 Vert. Retrace End; Overflow */
6474 
6475      /* 3. Panel delay compensation */
6476 
6477      if(SiS_Pr->ChipType < SIS_315H) {
6478 
6479 #ifdef CONFIG_FB_SIS_300  /* ---------- 300 series -------------- */
6480 
6481         if(SiS_Pr->SiS_VBType & VB_SISVB) {
6482            temp = 0x20;
6483            if(SiS_Pr->ChipType == SIS_300) {
6484               temp = 0x10;
6485               if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)  temp = 0x2c;
6486               if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6487            }
6488            if(SiS_Pr->SiS_VBType & VB_SIS301) {
6489               if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6490            }
6491            if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960)     temp = 0x24;
6492            if(SiS_Pr->SiS_LCDResInfo == Panel_Custom)       temp = 0x2c;
6493            if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)             temp = 0x08;
6494            if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6495               if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)       temp = 0x2c;
6496               else                                          temp = 0x20;
6497            }
6498            if(SiS_Pr->SiS_UseROM) {
6499               if(ROMAddr[0x220] & 0x80) {
6500                  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision)
6501                     temp = ROMAddr[0x221];
6502                  else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)
6503                     temp = ROMAddr[0x222];
6504                  else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)
6505                     temp = ROMAddr[0x223];
6506                  else
6507                     temp = ROMAddr[0x224];
6508               }
6509            }
6510            if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6511               if(SiS_Pr->PDC != -1)  temp = SiS_Pr->PDC;
6512            }
6513 
6514         } else {
6515            temp = 0x20;
6516            if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
6517               if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) temp = 0x04;
6518            }
6519            if(SiS_Pr->SiS_UseROM) {
6520               if(ROMAddr[0x220] & 0x80) {
6521                  temp = ROMAddr[0x220];
6522               }
6523            }
6524            if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6525               if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC;
6526            }
6527         }
6528 
6529         temp &= 0x3c;
6530 
6531         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);   /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
6532 
6533 #endif  /* CONFIG_FB_SIS_300 */
6534 
6535      } else {
6536 
6537 #ifdef CONFIG_FB_SIS_315   /* --------------- 315/330 series ---------------*/
6538 
6539         if(SiS_Pr->ChipType < SIS_661) {
6540 
6541            if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6542 
6543               if(SiS_Pr->ChipType == SIS_740) temp = 0x03;
6544               else                            temp = 0x00;
6545 
6546               if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x0a;
6547               tempbl = 0xF0;
6548               if(SiS_Pr->ChipType == SIS_650) {
6549                  if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6550                     if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F;
6551                  }
6552               }
6553 
6554               if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) {
6555                  temp = 0x08;
6556                  tempbl = 0;
6557                  if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
6558                     if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0;
6559                  }
6560               }
6561 
6562               SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp);      /* Panel Link Delay Compensation */
6563            }
6564 
6565         } /* < 661 */
6566 
6567         tempax = 0;
6568         if(modeflag & DoubleScanMode) tempax |= 0x80;
6569         if(modeflag & HalfDCLK)       tempax |= 0x40;
6570         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax);
6571 
6572 #endif  /* CONFIG_FB_SIS_315 */
6573 
6574      }
6575 
6576   }  /* Slavemode */
6577 
6578   if(SiS_Pr->SiS_VBType & VB_SISVB) {
6579      if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
6580         /* For 301BDH with LCD, we set up the Panel Link */
6581         SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6582      } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6583         SiS_SetGroup1_301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6584      }
6585   } else {
6586      if(SiS_Pr->ChipType < SIS_315H) {
6587         SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6588      } else {
6589         if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6590            if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
6591               SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex);
6592            }
6593         } else {
6594            SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex);
6595         }
6596      }
6597   }
6598 }
6599 
6600 /*********************************************/
6601 /*         SET PART 2 REGISTER GROUP         */
6602 /*********************************************/
6603 
6604 #ifdef CONFIG_FB_SIS_315
6605 static unsigned char *
6606 SiS_GetGroup2CLVXPtr(struct SiS_Private *SiS_Pr, int tabletype)
6607 {
6608    const unsigned char *tableptr = NULL;
6609    unsigned short      a, b, p = 0;
6610 
6611    a = SiS_Pr->SiS_VGAHDE;
6612    b = SiS_Pr->SiS_HDE;
6613    if(tabletype) {
6614       a = SiS_Pr->SiS_VGAVDE;
6615       b = SiS_Pr->SiS_VDE;
6616    }
6617 
6618    if(a < b) {
6619       tableptr = SiS_Part2CLVX_1;
6620    } else if(a == b) {
6621       tableptr = SiS_Part2CLVX_2;
6622    } else {
6623       if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6624          tableptr = SiS_Part2CLVX_4;
6625       } else {
6626          tableptr = SiS_Part2CLVX_3;
6627       }
6628       if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6629          if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i)        tableptr = SiS_Part2CLVX_3;
6630          else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)   tableptr = SiS_Part2CLVX_3;
6631          else                                           tableptr = SiS_Part2CLVX_5;
6632       } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6633          tableptr = SiS_Part2CLVX_6;
6634       }
6635       do {
6636          if((tableptr[p] | tableptr[p+1] << 8) == a) break;
6637          p += 0x42;
6638       } while((tableptr[p] | tableptr[p+1] << 8) != 0xffff);
6639       if((tableptr[p] | tableptr[p+1] << 8) == 0xffff) p -= 0x42;
6640    }
6641    p += 2;
6642    return ((unsigned char *)&tableptr[p]);
6643 }
6644 
6645 static void
6646 SiS_SetGroup2_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6647                     unsigned short RefreshRateTableIndex)
6648 {
6649    unsigned char *tableptr;
6650    unsigned char temp;
6651    int i, j;
6652 
6653    if(!(SiS_Pr->SiS_VBType & VB_SISTAP4SCALER)) return;
6654 
6655    tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 0);
6656    for(i = 0x80, j = 0; i <= 0xbf; i++, j++) {
6657       SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6658    }
6659    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6660       tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 1);
6661       for(i = 0xc0, j = 0; i <= 0xff; i++, j++) {
6662          SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6663       }
6664    }
6665    temp = 0x10;
6666    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp |= 0x04;
6667    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xeb,temp);
6668 }
6669 
6670 static bool
6671 SiS_GetCRT2Part2Ptr(struct SiS_Private *SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,
6672                     unsigned short RefreshRateTableIndex,unsigned short *CRT2Index,
6673                     unsigned short *ResIndex)
6674 {
6675 
6676   if(SiS_Pr->ChipType < SIS_315H) return false;
6677 
6678   if(ModeNo <= 0x13)
6679      (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6680   else
6681      (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6682 
6683   (*ResIndex) &= 0x3f;
6684   (*CRT2Index) = 0;
6685 
6686   if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6687      if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6688         (*CRT2Index) = 200;
6689      }
6690   }
6691 
6692   if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
6693      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6694         if(SiS_Pr->SiS_SetFlag & LCDVESATiming) (*CRT2Index) = 206;
6695      }
6696   }
6697   return (((*CRT2Index) != 0));
6698 }
6699 #endif
6700 
6701 #ifdef CONFIG_FB_SIS_300
6702 static void
6703 SiS_Group2LCDSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short crt2crtc)
6704 {
6705    unsigned short tempcx;
6706    static const unsigned char atable[] = {
6707        0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,
6708        0xab,0x87,0xab,0x9e,0xe7,0x02,0x02
6709    };
6710 
6711    if(!SiS_Pr->UseCustomMode) {
6712       if( ( ( (SiS_Pr->ChipType == SIS_630) ||
6713               (SiS_Pr->ChipType == SIS_730) ) &&
6714             (SiS_Pr->ChipRevision > 2) )  &&
6715           (SiS_Pr->SiS_LCDResInfo == Panel_1024x768) &&
6716           (!(SiS_Pr->SiS_SetFlag & LCDVESATiming))  &&
6717           (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
6718          if(ModeNo == 0x13) {
6719             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xB9);
6720             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0xCC);
6721             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xA6);
6722          } else if((crt2crtc & 0x3F) == 4) {
6723             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x2B);
6724             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x13);
6725             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xE5);
6726             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0x08);
6727             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xE2);
6728          }
6729       }
6730 
6731       if(SiS_Pr->ChipType < SIS_315H) {
6732          if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
6733             crt2crtc &= 0x1f;
6734             tempcx = 0;
6735             if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6736                if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6737                   tempcx += 7;
6738                }
6739             }
6740             tempcx += crt2crtc;
6741             if(crt2crtc >= 4) {
6742                SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xff);
6743             }
6744 
6745             if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6746                if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6747                   if(crt2crtc == 4) {
6748                      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x28);
6749                   }
6750                }
6751             }
6752             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x18);
6753             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
6754          }
6755       }
6756    }
6757 }
6758 
6759 /* For ECS A907. Highly preliminary. */
6760 static void
6761 SiS_Set300Part2Regs(struct SiS_Private *SiS_Pr, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex,
6762                     unsigned short ModeNo)
6763 {
6764   const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
6765   unsigned short crt2crtc, resindex;
6766   int i, j;
6767 
6768   if(SiS_Pr->ChipType != SIS_300) return;
6769   if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;
6770   if(SiS_Pr->UseCustomMode) return;
6771 
6772   if(ModeNo <= 0x13) {
6773      crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6774   } else {
6775      crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6776   }
6777 
6778   resindex = crt2crtc & 0x3F;
6779   if(SiS_Pr->SiS_SetFlag & LCDVESATiming) CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6780   else                                    CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2;
6781 
6782   /* The BIOS code (1.16.51,56) is obviously a fragment! */
6783   if(ModeNo > 0x13) {
6784      CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6785      resindex = 4;
6786   }
6787 
6788   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
6789   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
6790   for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
6791      SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6792   }
6793   for(j = 0x1c; j <= 0x1d; i++, j++ ) {
6794      SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6795   }
6796   for(j = 0x1f; j <= 0x21; i++, j++ ) {
6797      SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6798   }
6799   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
6800   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
6801 }
6802 #endif
6803 
6804 static void
6805 SiS_SetTVSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
6806 {
6807   if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;
6808   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) return;
6809   if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) return;
6810 
6811   if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
6812      if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6813         static const unsigned char specialtv[] = {
6814                 0xa7,0x07,0xf2,0x6e,0x17,0x8b,0x73,0x53,
6815                 0x13,0x40,0x34,0xf4,0x63,0xbb,0xcc,0x7a,
6816                 0x58,0xe4,0x73,0xda,0x13
6817         };
6818         int i, j;
6819         for(i = 0x1c, j = 0; i <= 0x30; i++, j++) {
6820            SiS_SetReg(SiS_Pr->SiS_Part2Port,i,specialtv[j]);
6821         }
6822         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,0x72);
6823         if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750)) {
6824            if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6825               SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14);
6826               SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1b);
6827            } else {
6828               SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14);  /* 15 */
6829               SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1a);  /* 1b */
6830            }
6831         }
6832      }
6833   } else {
6834      if((ModeNo == 0x38) || (ModeNo == 0x4a) || (ModeNo == 0x64) ||
6835         (ModeNo == 0x52) || (ModeNo == 0x58) || (ModeNo == 0x5c)) {
6836         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b);  /* 21 */
6837         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54);  /* 5a */
6838      } else {
6839         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1a);  /* 21 */
6840         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x53);  /* 5a */
6841      }
6842   }
6843 }
6844 
6845 static void
6846 SiS_SetGroup2_Tail(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
6847 {
6848   unsigned short temp;
6849 
6850   if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6851      if(SiS_Pr->SiS_VGAVDE == 525) {
6852         temp = 0xc3;
6853         if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6854            temp++;
6855            if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp += 2;
6856         }
6857         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6858         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xb3);
6859      } else if(SiS_Pr->SiS_VGAVDE == 420) {
6860         temp = 0x4d;
6861         if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6862            temp++;
6863            if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp++;
6864         }
6865         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6866      }
6867   }
6868 
6869   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6870      if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
6871         if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
6872            SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x1a,0x03);
6873            /* Not always for LV, see SetGrp2 */
6874         }
6875         temp = 1;
6876         if(ModeNo <= 0x13) temp = 3;
6877         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0b,temp);
6878      }
6879 #if 0
6880      /* 651+301C, for 1280x768 - do I really need that? */
6881      if((SiS_Pr->SiS_PanelXRes == 1280) && (SiS_Pr->SiS_PanelYRes == 768)) {
6882         if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) {
6883            if(((SiS_Pr->SiS_HDE == 640) && (SiS_Pr->SiS_VDE == 480)) ||
6884               ((SiS_Pr->SiS_HDE == 320) && (SiS_Pr->SiS_VDE == 240))) {
6885               SiS_SetReg(SiS_Part2Port,0x01,0x2b);
6886               SiS_SetReg(SiS_Part2Port,0x02,0x13);
6887               SiS_SetReg(SiS_Part2Port,0x04,0xe5);
6888               SiS_SetReg(SiS_Part2Port,0x05,0x08);
6889               SiS_SetReg(SiS_Part2Port,0x06,0xe2);
6890               SiS_SetReg(SiS_Part2Port,0x1c,0x21);
6891               SiS_SetReg(SiS_Part2Port,0x1d,0x45);
6892               SiS_SetReg(SiS_Part2Port,0x1f,0x0b);
6893               SiS_SetReg(SiS_Part2Port,0x20,0x00);
6894               SiS_SetReg(SiS_Part2Port,0x21,0xa9);
6895               SiS_SetReg(SiS_Part2Port,0x23,0x0b);
6896               SiS_SetReg(SiS_Part2Port,0x25,0x04);
6897            }
6898         }
6899      }
6900 #endif
6901   }
6902 }
6903 
6904 static void
6905 SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6906                 unsigned short RefreshRateTableIndex)
6907 {
6908   unsigned short i, j, tempax, tempbx, tempcx, tempch, tempcl, temp;
6909   unsigned short push2, modeflag, crt2crtc, bridgeoffset;
6910   unsigned int   longtemp, PhaseIndex;
6911   bool           newtvphase;
6912   const unsigned char *TimingPoint;
6913 #ifdef CONFIG_FB_SIS_315
6914   unsigned short resindex, CRT2Index;
6915   const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
6916 
6917   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
6918 #endif
6919 
6920   if(ModeNo <= 0x13) {
6921      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6922      crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6923   } else if(SiS_Pr->UseCustomMode) {
6924      modeflag = SiS_Pr->CModeFlag;
6925      crt2crtc = 0;
6926   } else {
6927      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6928      crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6929   }
6930 
6931   temp = 0;
6932   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO)) temp |= 0x08;
6933   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO)) temp |= 0x04;
6934   if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART)     temp |= 0x02;
6935   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)  temp |= 0x01;
6936 
6937   if(!(SiS_Pr->SiS_TVMode & TVSetPAL))        temp |= 0x10;
6938 
6939   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x00,temp);
6940 
6941   PhaseIndex  = 0x01; /* SiS_PALPhase */
6942   TimingPoint = SiS_Pr->SiS_PALTiming;
6943 
6944   newtvphase = false;
6945   if( (SiS_Pr->SiS_VBType & VB_SIS30xBLV) &&
6946       ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6947         (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6948      newtvphase = true;
6949   }
6950 
6951   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6952 
6953      TimingPoint = SiS_Pr->SiS_HiTVExtTiming;
6954      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6955         TimingPoint = SiS_Pr->SiS_HiTVSt2Timing;
6956         if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
6957            TimingPoint = SiS_Pr->SiS_HiTVSt1Timing;
6958         }
6959      }
6960 
6961   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6962 
6963      i = 0;
6964      if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)      i = 2;
6965      else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) i = 1;
6966 
6967      TimingPoint = &SiS_YPbPrTable[i][0];
6968 
6969      PhaseIndex = 0x00; /* SiS_NTSCPhase */
6970 
6971   } else if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6972 
6973      if(newtvphase) PhaseIndex = 0x09; /* SiS_PALPhase2 */
6974 
6975   } else {
6976 
6977      TimingPoint = SiS_Pr->SiS_NTSCTiming;
6978      PhaseIndex  = (SiS_Pr->SiS_TVMode & TVSetNTSCJ) ? 0x01 : 0x00;     /* SiS_PALPhase : SiS_NTSCPhase */
6979      if(newtvphase) PhaseIndex += 8;                                    /* SiS_PALPhase2 : SiS_NTSCPhase2 */
6980 
6981   }
6982 
6983   if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) {
6984      PhaseIndex = (SiS_Pr->SiS_TVMode & TVSetPALM) ? 0x02 : 0x03;       /* SiS_PALMPhase : SiS_PALNPhase */
6985      if(newtvphase) PhaseIndex += 8;                                    /* SiS_PALMPhase2 : SiS_PALNPhase2 */
6986   }
6987 
6988   if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6989      if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6990         PhaseIndex = 0x05; /* SiS_SpecialPhaseM */
6991      } else if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
6992         PhaseIndex = 0x11; /* SiS_SpecialPhaseJ */
6993      } else {
6994         PhaseIndex = 0x10; /* SiS_SpecialPhase */
6995      }
6996   }
6997 
6998   for(i = 0x31, j = 0; i <= 0x34; i++, j++) {
6999      SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[(PhaseIndex * 4) + j]);
7000   }
7001 
7002   for(i = 0x01, j = 0; i <= 0x2D; i++, j++) {
7003      SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
7004   }
7005   for(i = 0x39; i <= 0x45; i++, j++) {
7006      SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
7007   }
7008 
7009   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7010      if(SiS_Pr->SiS_ModeType != ModeText) {
7011         SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
7012      }
7013   }
7014 
7015   SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x0A,SiS_Pr->SiS_NewFlickerMode);
7016 
7017   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x35,SiS_Pr->SiS_RY1COE);
7018   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x36,SiS_Pr->SiS_RY2COE);
7019   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x37,SiS_Pr->SiS_RY3COE);
7020   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x38,SiS_Pr->SiS_RY4COE);
7021 
7022   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)    tempax = 950;
7023   else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)  tempax = 680;
7024   else if(SiS_Pr->SiS_TVMode & TVSetPAL)        tempax = 520;
7025   else                                          tempax = 440; /* NTSC, YPbPr 525 */
7026 
7027   if( ((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) && (SiS_Pr->SiS_VDE <= tempax)) ||
7028       ( (SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) &&
7029         ((SiS_Pr->SiS_VGAHDE == 1024) || (SiS_Pr->SiS_VDE <= tempax)) ) ) {
7030 
7031      tempax -= SiS_Pr->SiS_VDE;
7032      tempax >>= 1;
7033      if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) {
7034         tempax >>= 1;
7035      }
7036      tempax &= 0x00ff;
7037 
7038      temp = tempax + (unsigned short)TimingPoint[0];
7039      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
7040 
7041      temp = tempax + (unsigned short)TimingPoint[1];
7042      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
7043 
7044      if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) && (SiS_Pr->SiS_VGAHDE >= 1024)) {
7045         if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7046            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b);
7047            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54);
7048         } else {
7049            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x17);
7050            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1d);
7051         }
7052      }
7053 
7054   }
7055 
7056   tempcx = SiS_Pr->SiS_HT;
7057   if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
7058   tempcx--;
7059   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) tempcx--;
7060   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1B,tempcx);
7061   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0xF0,((tempcx >> 8) & 0x0f));
7062 
7063   tempcx = SiS_Pr->SiS_HT >> 1;
7064   if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
7065   tempcx += 7;
7066   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
7067   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,((tempcx << 4) & 0xf0));
7068 
7069   tempbx = TimingPoint[j] | (TimingPoint[j+1] << 8);
7070   tempbx += tempcx;
7071   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x24,tempbx);
7072   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0F,((tempbx >> 4) & 0xf0));
7073 
7074   tempbx += 8;
7075   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7076      tempbx -= 4;
7077      tempcx = tempbx;
7078   }
7079   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x29,0x0F,((tempbx << 4) & 0xf0));
7080 
7081   j += 2;
7082   tempcx += (TimingPoint[j] | (TimingPoint[j+1] << 8));
7083   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x27,tempcx);
7084   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x28,0x0F,((tempcx >> 4) & 0xf0));
7085 
7086   tempcx += 8;
7087   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
7088   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2A,0x0F,((tempcx << 4) & 0xf0));
7089 
7090   tempcx = SiS_Pr->SiS_HT >> 1;
7091   if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
7092   j += 2;
7093   tempcx -= (TimingPoint[j] | ((TimingPoint[j+1]) << 8));
7094   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2D,0x0F,((tempcx << 4) & 0xf0));
7095 
7096   tempcx -= 11;
7097   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
7098      tempcx = SiS_GetVGAHT2(SiS_Pr) - 1;
7099   }
7100   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2E,tempcx);
7101 
7102   tempbx = SiS_Pr->SiS_VDE;
7103   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7104      if(SiS_Pr->SiS_VGAVDE == 360) tempbx = 746;
7105      if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 746;
7106      if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 853;
7107   } else if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
7108              (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p))) ) {
7109      tempbx >>= 1;
7110      if(SiS_Pr->ChipType >= SIS_315H) {
7111         if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
7112            if((ModeNo <= 0x13) && (crt2crtc == 1)) tempbx++;
7113         } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7114            if(SiS_Pr->SiS_ModeType <= ModeVGA) {
7115               if(crt2crtc == 4) tempbx++;
7116            }
7117         }
7118      }
7119      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7120         if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7121            if((ModeNo == 0x2f) || (ModeNo == 0x5d) || (ModeNo == 0x5e)) tempbx++;
7122         }
7123         if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
7124            if(ModeNo == 0x03) tempbx++; /* From 1.10.7w - doesn't make sense */
7125         }
7126      }
7127   }
7128   tempbx -= 2;
7129   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2F,tempbx);
7130 
7131   temp = (tempcx >> 8) & 0x0F;
7132   temp |= ((tempbx >> 2) & 0xC0);
7133   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
7134      temp |= 0x10;
7135      if(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO) temp |= 0x20;
7136   }
7137   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,temp);
7138 
7139   if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {
7140      SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xdf,((tempbx & 0x0400) >> 5));
7141   }
7142 
7143   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7144      tempbx = SiS_Pr->SiS_VDE;
7145      if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
7146          (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) ) {
7147         tempbx >>= 1;
7148      }
7149      tempbx -= 3;
7150      temp = ((tempbx >> 3) & 0x60) | 0x18;
7151      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x46,temp);
7152      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x47,tempbx);
7153 
7154      if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {
7155         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xbf,((tempbx & 0x0400) >> 4));
7156      }
7157   }
7158 
7159   tempbx = 0;
7160   if(!(modeflag & HalfDCLK)) {
7161      if(SiS_Pr->SiS_VGAHDE >= SiS_Pr->SiS_HDE) {
7162         tempax = 0;
7163         tempbx |= 0x20;
7164      }
7165   }
7166 
7167   tempch = tempcl = 0x01;
7168   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7169      if(SiS_Pr->SiS_VGAHDE >= 960) {
7170         if((!(modeflag & HalfDCLK)) || (SiS_Pr->ChipType < SIS_315H)) {
7171            tempcl = 0x20;
7172            if(SiS_Pr->SiS_VGAHDE >= 1280) {
7173               tempch = 20;
7174               tempbx &= ~0x20;
7175            } else {
7176               tempch = 25; /* OK */
7177            }
7178         }
7179      }
7180   }
7181 
7182   if(!(tempbx & 0x20)) {
7183      if(modeflag & HalfDCLK) tempcl <<= 1;
7184      longtemp = ((SiS_Pr->SiS_VGAHDE * tempch) / tempcl) << 13;
7185      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) longtemp <<= 3;
7186      tempax = longtemp / SiS_Pr->SiS_HDE;
7187      if(longtemp % SiS_Pr->SiS_HDE) tempax++;
7188      tempbx |= ((tempax >> 8) & 0x1F);
7189      tempcx = tempax >> 13;
7190   }
7191 
7192   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,tempax);
7193   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,tempbx);
7194 
7195   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7196 
7197      tempcx &= 0x07;
7198      if(tempbx & 0x20) tempcx = 0;
7199      SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xF8,tempcx);
7200 
7201      if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7202         tempbx = 0x0382;
7203         tempcx = 0x007e;
7204      } else {
7205         tempbx = 0x0369;
7206         tempcx = 0x0061;
7207      }
7208      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4B,tempbx);
7209      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4C,tempcx);
7210      temp = (tempcx & 0x0300) >> 6;
7211      temp |= ((tempbx >> 8) & 0x03);
7212      if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7213         temp |= 0x10;
7214         if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)      temp |= 0x20;
7215         else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp |= 0x40;
7216      }
7217      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4D,temp);
7218 
7219      temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7220      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,(temp - 3));
7221 
7222      SiS_SetTVSpecial(SiS_Pr, ModeNo);
7223 
7224      if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
7225         temp = 0;
7226         if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
7227         SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xf7,temp);
7228      }
7229 
7230   }
7231 
7232   if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7233      if(!(SiS_Pr->SiS_TVMode & TVSetNTSC1024)) {
7234         temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
7235         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,(temp - 1));
7236      }
7237      SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF);
7238   }
7239 
7240   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7241      if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
7242         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,0x00);
7243      }
7244   }
7245 
7246   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) return;
7247 
7248   /* From here: Part2 LCD setup */
7249 
7250   tempbx = SiS_Pr->SiS_HDE;
7251   if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7252   tempbx--;                                     /* RHACTE = HDE - 1 */
7253   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2C,tempbx);
7254   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,((tempbx >> 4) & 0xf0));
7255 
7256   temp = 0x01;
7257   if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7258      if(SiS_Pr->SiS_ModeType == ModeEGA) {
7259         if(SiS_Pr->SiS_VGAHDE >= 1024) {
7260            temp = 0x02;
7261            if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7262               temp = 0x01;
7263            }
7264         }
7265      }
7266   }
7267   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,temp);
7268 
7269   tempbx = SiS_Pr->SiS_VDE - 1;
7270   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x03,tempbx);
7271   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0C,0xF8,((tempbx >> 8) & 0x07));
7272 
7273   tempcx = SiS_Pr->SiS_VT - 1;
7274   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x19,tempcx);
7275   temp = (tempcx >> 3) & 0xE0;
7276   if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
7277      /* Enable dithering; only do this for 32bpp mode */
7278      if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
7279         temp |= 0x10;
7280      }
7281   }
7282   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1A,0x0f,temp);
7283 
7284   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x09,0xF0);
7285   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x0A,0xF0);
7286 
7287   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB);
7288   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF);
7289 
7290 #ifdef CONFIG_FB_SIS_315
7291   if(SiS_GetCRT2Part2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7292                                                 &CRT2Index, &resindex)) {
7293       switch(CRT2Index) {
7294         case 206: CRT2Part2Ptr = SiS310_CRT2Part2_Asus1024x768_3;    break;
7295         default:
7296         case 200: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;   break;
7297       }
7298 
7299       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
7300       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
7301       for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
7302         SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7303       }
7304       for(j = 0x1c; j <= 0x1d; i++, j++ ) {
7305         SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7306       }
7307       for(j = 0x1f; j <= 0x21; i++, j++ ) {
7308         SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7309       }
7310       SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
7311       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
7312 
7313       SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7314 
7315   } else {
7316 #endif
7317 
7318     /* Checked for 1024x768, 1280x1024, 1400x1050, 1600x1200 */
7319     /*             Clevo dual-link 1024x768 */
7320     /*             Compaq 1280x1024 has HT 1696 sometimes (calculation OK, if given HT is correct)  */
7321     /*             Acer: OK, but uses different setting for VESA timing at 640/800/1024 and 640x400 */
7322 
7323     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7324        if((SiS_Pr->SiS_LCDInfo & LCDPass11) || (SiS_Pr->PanelYRes == SiS_Pr->SiS_VDE)) {
7325           tempbx = SiS_Pr->SiS_VDE - 1;
7326           tempcx = SiS_Pr->SiS_VT - 1;
7327        } else {
7328           tempbx = SiS_Pr->SiS_VDE + ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7329           tempcx = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7330        }
7331     } else {
7332        tempbx = SiS_Pr->PanelYRes;
7333        tempcx = SiS_Pr->SiS_VT;
7334        tempax = 1;
7335        if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7336           tempax = SiS_Pr->PanelYRes;
7337           /* if(SiS_Pr->SiS_VGAVDE == 525) tempax += 0x3c;   */  /* 651+301C */
7338           if(SiS_Pr->PanelYRes < SiS_Pr->SiS_VDE) {
7339              tempax = tempcx = 0;
7340           } else {
7341              tempax -= SiS_Pr->SiS_VDE;
7342           }
7343           tempax >>= 1;
7344        }
7345        tempcx -= tempax; /* lcdvdes */
7346        tempbx -= tempax; /* lcdvdee */
7347     }
7348 
7349     /* Non-expanding: lcdvdes = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */
7350 
7351     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,tempcx);      /* lcdvdes  */
7352     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,tempbx);      /* lcdvdee  */
7353 
7354     temp = (tempbx >> 5) & 0x38;
7355     temp |= ((tempcx >> 8) & 0x07);
7356     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
7357 
7358     tempax = SiS_Pr->SiS_VDE;
7359     if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7360        tempax = SiS_Pr->PanelYRes;
7361     }
7362     tempcx = (SiS_Pr->SiS_VT - tempax) >> 4;
7363     if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7364        if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7365           tempcx = (SiS_Pr->SiS_VT - tempax) / 10;
7366        }
7367     }
7368 
7369     tempbx = ((SiS_Pr->SiS_VT + SiS_Pr->SiS_VDE) >> 1) - 1;
7370     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7371        if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7372           if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { /* ? */
7373              tempax = SiS_Pr->SiS_VT - SiS_Pr->PanelYRes;
7374              if(tempax % 4) { tempax >>= 2; tempax++; }
7375              else           { tempax >>= 2;           }
7376              tempbx -= (tempax - 1);
7377           } else {
7378              tempbx -= 10;
7379              if(tempbx <= SiS_Pr->SiS_VDE) tempbx = SiS_Pr->SiS_VDE + 1;
7380           }
7381        }
7382     }
7383     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
7384        tempbx++;
7385        if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (crt2crtc == 6)) {
7386           if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7387              tempbx = 770;
7388              tempcx = 3;
7389           }
7390        }
7391     }
7392 
7393     /* non-expanding: lcdvrs = ((VT + VDE) / 2) - 10 */
7394 
7395     if(SiS_Pr->UseCustomMode) {
7396        tempbx = SiS_Pr->CVSyncStart;
7397     }
7398 
7399     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,tempbx);          /* lcdvrs */
7400 
7401     temp = (tempbx >> 4) & 0xF0;
7402     tempbx += (tempcx + 1);
7403     temp |= (tempbx & 0x0F);
7404 
7405     if(SiS_Pr->UseCustomMode) {
7406        temp &= 0xf0;
7407        temp |= (SiS_Pr->CVSyncEnd & 0x0f);
7408     }
7409 
7410     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
7411 
7412 #ifdef CONFIG_FB_SIS_300
7413     SiS_Group2LCDSpecial(SiS_Pr, ModeNo, crt2crtc);
7414 #endif
7415 
7416     bridgeoffset = 7;
7417     if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)       bridgeoffset += 2;
7418     if(SiS_Pr->SiS_VBType & VB_SIS30xCLV)       bridgeoffset += 2; /* OK for Averatec 1280x800 (301C) */
7419     if(SiS_IsDualLink(SiS_Pr))                  bridgeoffset++;
7420     else if(SiS_Pr->SiS_VBType & VB_SIS302LV)   bridgeoffset++;    /* OK for Asus A4L 1280x800 */
7421     /* Higher bridgeoffset shifts to the LEFT */
7422 
7423     temp = 0;
7424     if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7425        if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7426           temp = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7427           if(SiS_IsDualLink(SiS_Pr)) temp >>= 1;
7428        }
7429     }
7430     temp += bridgeoffset;
7431     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1F,temp);             /* lcdhdes */
7432     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0F,((temp >> 4) & 0xf0));
7433 
7434     tempcx = SiS_Pr->SiS_HT;
7435     tempax = tempbx = SiS_Pr->SiS_HDE;
7436     if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7437        if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7438           tempax = SiS_Pr->PanelXRes;
7439           tempbx = SiS_Pr->PanelXRes - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7440        }
7441     }
7442     if(SiS_IsDualLink(SiS_Pr)) {
7443        tempcx >>= 1;
7444        tempbx >>= 1;
7445        tempax >>= 1;
7446     }
7447 
7448     tempbx += bridgeoffset;
7449 
7450     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,tempbx);          /* lcdhdee */
7451     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0xF0,((tempbx >> 8) & 0x0f));
7452 
7453     tempcx = (tempcx - tempax) >> 2;
7454 
7455     tempbx += tempcx;
7456     push2 = tempbx;
7457 
7458     if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7459        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7460           if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
7461              if(SiS_Pr->SiS_HDE == 1280) tempbx = (tempbx & 0xff00) | 0x47;
7462           }
7463        }
7464     }
7465 
7466     if(SiS_Pr->UseCustomMode) {
7467        tempbx = SiS_Pr->CHSyncStart;
7468        if(modeflag & HalfDCLK) tempbx <<= 1;
7469        if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7470        tempbx += bridgeoffset;
7471     }
7472 
7473     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1C,tempbx);          /* lcdhrs */
7474     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,((tempbx >> 4) & 0xf0));
7475 
7476     tempbx = push2;
7477 
7478     tempcx <<= 1;
7479     if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7480        if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) tempcx >>= 2;
7481     }
7482     tempbx += tempcx;
7483 
7484     if(SiS_Pr->UseCustomMode) {
7485        tempbx = SiS_Pr->CHSyncEnd;
7486        if(modeflag & HalfDCLK) tempbx <<= 1;
7487        if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7488        tempbx += bridgeoffset;
7489     }
7490 
7491     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,tempbx);          /* lcdhre */
7492 
7493     SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7494 
7495 #ifdef CONFIG_FB_SIS_300
7496     SiS_Set300Part2Regs(SiS_Pr, ModeIdIndex, RefreshRateTableIndex, ModeNo);
7497 #endif
7498 #ifdef CONFIG_FB_SIS_315
7499   } /* CRT2-LCD from table */
7500 #endif
7501 }
7502 
7503 /*********************************************/
7504 /*         SET PART 3 REGISTER GROUP         */
7505 /*********************************************/
7506 
7507 static void
7508 SiS_SetGroup3(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7509 {
7510   unsigned short i;
7511   const unsigned char *tempdi;
7512 
7513   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
7514 
7515 #ifndef SIS_CP
7516   SiS_SetReg(SiS_Pr->SiS_Part3Port,0x00,0x00);
7517 #else
7518   SIS_CP_INIT301_CP
7519 #endif
7520 
7521   if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7522      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7523      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7524   } else {
7525      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xF5);
7526      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xB7);
7527   }
7528 
7529   if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7530      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7531      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7532      SiS_SetReg(SiS_Pr->SiS_Part3Port,0x3D,0xA8);
7533   }
7534 
7535   tempdi = NULL;
7536   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7537      tempdi = SiS_Pr->SiS_HiTVGroup3Data;
7538      if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
7539         tempdi = SiS_Pr->SiS_HiTVGroup3Simu;
7540      }
7541   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7542      if(!(SiS_Pr->SiS_TVMode & TVSetYPbPr525i)) {
7543         tempdi = SiS_HiTVGroup3_1;
7544         if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempdi = SiS_HiTVGroup3_2;
7545      }
7546   }
7547   if(tempdi) {
7548      for(i=0; i<=0x3E; i++) {
7549         SiS_SetReg(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
7550      }
7551      if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
7552         if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
7553            SiS_SetReg(SiS_Pr->SiS_Part3Port,0x28,0x3f);
7554         }
7555      }
7556   }
7557 
7558 #ifdef SIS_CP
7559   SIS_CP_INIT301_CP2
7560 #endif
7561 }
7562 
7563 /*********************************************/
7564 /*         SET PART 4 REGISTER GROUP         */
7565 /*********************************************/
7566 
7567 #ifdef CONFIG_FB_SIS_315
7568 #if 0
7569 static void
7570 SiS_ShiftXPos(struct SiS_Private *SiS_Pr, int shift)
7571 {
7572    unsigned short temp, temp1, temp2;
7573 
7574    temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x1f);
7575    temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x20);
7576    temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7577    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,temp);
7578    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0f,((temp >> 4) & 0xf0));
7579    temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x2b) & 0x0f;
7580    temp = (unsigned short)((int)(temp) + shift);
7581    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2b,0xf0,(temp & 0x0f));
7582    temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7583    temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x42);
7584    temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7585    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,temp);
7586    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x42,0x0f,((temp >> 4) & 0xf0));
7587 }
7588 #endif
7589 
7590 static void
7591 SiS_SetGroup4_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7592 {
7593    unsigned short temp, temp1;
7594    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
7595 
7596    if(!(SiS_Pr->SiS_VBType & VB_SIS30xCLV)) return;
7597    if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToHiVision | SetCRT2ToYPbPr525750))) return;
7598 
7599    if(SiS_Pr->ChipType >= XGI_20) return;
7600 
7601    if((SiS_Pr->ChipType >= SIS_661) && (SiS_Pr->SiS_ROMNew)) {
7602       if(!(ROMAddr[0x61] & 0x04)) return;
7603    }
7604 
7605    SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3a,0x08);
7606    temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x3a);
7607    if(!(temp & 0x01)) {
7608       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3a,0xdf);
7609       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xfc);
7610       if((SiS_Pr->ChipType < SIS_661) && (!(SiS_Pr->SiS_ROMNew))) {
7611          SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xf8);
7612       }
7613       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0xfb);
7614       if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)      temp = 0x0000;
7615       else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp = 0x0002;
7616       else if(SiS_Pr->SiS_TVMode & TVSetHiVision)  temp = 0x0400;
7617       else                                         temp = 0x0402;
7618       if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
7619          temp1 = 0;
7620          if(SiS_Pr->SiS_TVMode & TVAspect43) temp1 = 4;
7621          SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0f,0xfb,temp1);
7622          if(SiS_Pr->SiS_TVMode & TVAspect43LB) temp |= 0x01;
7623          SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0x7c,(temp & 0xff));
7624          SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7625          if(ModeNo > 0x13) {
7626             SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x39,0xfd);
7627          }
7628       } else {
7629          temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x3b) & 0x03;
7630          if(temp1 == 0x01) temp |= 0x01;
7631          if(temp1 == 0x03) temp |= 0x04;  /* ? why not 0x10? */
7632          SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xf8,(temp & 0xff));
7633          SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7634          if(ModeNo > 0x13) {
7635             SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3b,0xfd);
7636          }
7637       }
7638 
7639 #if 0
7640       if(SiS_Pr->ChipType >= SIS_661) {                 /* ? */
7641          if(SiS_Pr->SiS_TVMode & TVAspect43) {
7642             if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
7643                if(resinfo == SIS_RI_1024x768) {
7644                   SiS_ShiftXPos(SiS_Pr, 97);
7645                } else {
7646                   SiS_ShiftXPos(SiS_Pr, 111);
7647                }
7648             } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
7649                SiS_ShiftXPos(SiS_Pr, 136);
7650             }
7651          }
7652       }
7653 #endif
7654 
7655    }
7656 
7657 }
7658 #endif
7659 
7660 static void
7661 SiS_SetCRT2VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7662                  unsigned short RefreshRateTableIndex)
7663 {
7664   unsigned short vclkindex, temp, reg1, reg2;
7665 
7666   if(SiS_Pr->UseCustomMode) {
7667      reg1 = SiS_Pr->CSR2B;
7668      reg2 = SiS_Pr->CSR2C;
7669   } else {
7670      vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
7671      reg1 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
7672      reg2 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
7673   }
7674 
7675   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7676      if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {
7677         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x57);
7678         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,0x46);
7679         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1f,0xf6);
7680      } else {
7681         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7682         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7683      }
7684   } else {
7685      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x01);
7686      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7687      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7688   }
7689   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x12,0x00);
7690   temp = 0x08;
7691   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) temp |= 0x20;
7692   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,temp);
7693 }
7694 
7695 static void
7696 SiS_SetDualLinkEtc(struct SiS_Private *SiS_Pr)
7697 {
7698   if(SiS_Pr->ChipType >= SIS_315H) {
7699      if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
7700         if((SiS_CRT2IsLCD(SiS_Pr)) ||
7701            (SiS_IsVAMode(SiS_Pr))) {
7702            if(SiS_Pr->SiS_LCDInfo & LCDDualLink) {
7703               SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
7704            } else {
7705               SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,~0x20);
7706            }
7707         }
7708      }
7709   }
7710   if(SiS_Pr->SiS_VBType & VB_SISEMI) {
7711      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
7712 #ifdef SET_EMI
7713      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
7714 #endif
7715      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
7716   }
7717 }
7718 
7719 static void
7720 SiS_SetGroup4(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7721                 unsigned short RefreshRateTableIndex)
7722 {
7723   unsigned short tempax, tempcx, tempbx, modeflag, temp, resinfo;
7724   unsigned int   tempebx, tempeax, templong;
7725 
7726   if(ModeNo <= 0x13) {
7727      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7728      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
7729   } else if(SiS_Pr->UseCustomMode) {
7730      modeflag = SiS_Pr->CModeFlag;
7731      resinfo = 0;
7732   } else {
7733      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7734      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
7735   }
7736 
7737   if(SiS_Pr->ChipType >= SIS_315H) {
7738      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
7739         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7740            SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7741         }
7742      }
7743   }
7744 
7745   if(SiS_Pr->SiS_VBType & (VB_SIS30xCLV | VB_SIS302LV)) {
7746      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7747         SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x10,0x9f);
7748      }
7749   }
7750 
7751   if(SiS_Pr->ChipType >= SIS_315H) {
7752      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7753         SiS_SetDualLinkEtc(SiS_Pr);
7754         return;
7755      }
7756   }
7757 
7758   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x13,SiS_Pr->SiS_RVBHCFACT);
7759 
7760   tempbx = SiS_Pr->SiS_RVBHCMAX;
7761   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x14,tempbx);
7762 
7763   temp = (tempbx >> 1) & 0x80;
7764 
7765   tempcx = SiS_Pr->SiS_VGAHT - 1;
7766   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x16,tempcx);
7767 
7768   temp |= ((tempcx >> 5) & 0x78);
7769 
7770   tempcx = SiS_Pr->SiS_VGAVT - 1;
7771   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempcx -= 5;
7772   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x17,tempcx);
7773 
7774   temp |= ((tempcx >> 8) & 0x07);
7775   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x15,temp);
7776 
7777   tempbx = SiS_Pr->SiS_VGAHDE;
7778   if(modeflag & HalfDCLK)    tempbx >>= 1;
7779   if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7780 
7781   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7782      temp = 0;
7783      if(tempbx > 800)        temp = 0x60;
7784   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7785      temp = 0;
7786      if(tempbx > 1024)       temp = 0xC0;
7787      else if(tempbx >= 960)  temp = 0xA0;
7788   } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
7789      temp = 0;
7790      if(tempbx >= 1280)      temp = 0x40;
7791      else if(tempbx >= 1024) temp = 0x20;
7792   } else {
7793      temp = 0x80;
7794      if(tempbx >= 1024)      temp = 0xA0;
7795   }
7796 
7797   temp |= SiS_Pr->Init_P4_0E;
7798 
7799   if(SiS_Pr->SiS_VBType & VB_SIS301) {
7800      if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
7801         temp &= 0xf0;
7802         temp |= 0x0A;
7803      }
7804   }
7805 
7806   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0E,0x10,temp);
7807 
7808   tempeax = SiS_Pr->SiS_VGAVDE;
7809   tempebx = SiS_Pr->SiS_VDE;
7810   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7811      if(!(temp & 0xE0)) tempebx >>=1;
7812   }
7813 
7814   tempcx = SiS_Pr->SiS_RVBHRS;
7815   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x18,tempcx);
7816   tempcx >>= 8;
7817   tempcx |= 0x40;
7818 
7819   if(tempeax <= tempebx) {
7820      tempcx ^= 0x40;
7821   } else {
7822      tempeax -= tempebx;
7823   }
7824 
7825   tempeax *= (256 * 1024);
7826   templong = tempeax % tempebx;
7827   tempeax /= tempebx;
7828   if(templong) tempeax++;
7829 
7830   temp = (unsigned short)(tempeax & 0x000000FF);
7831   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1B,temp);
7832   temp = (unsigned short)((tempeax & 0x0000FF00) >> 8);
7833   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1A,temp);
7834   temp = (unsigned short)((tempeax >> 12) & 0x70); /* sic! */
7835   temp |= (tempcx & 0x4F);
7836   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x19,temp);
7837 
7838   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7839 
7840      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1C,0x28);
7841 
7842      /* Calc Linebuffer max address and set/clear decimode */
7843      tempbx = 0;
7844      if(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p)) tempbx = 0x08;
7845      tempax = SiS_Pr->SiS_VGAHDE;
7846      if(modeflag & HalfDCLK)    tempax >>= 1;
7847      if(SiS_IsDualLink(SiS_Pr)) tempax >>= 1;
7848      if(tempax > 800) {
7849         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7850            tempax -= 800;
7851         } else {
7852            tempbx = 0x08;
7853            if(tempax == 960)       tempax *= 25; /* Correct */
7854            else if(tempax == 1024) tempax *= 25;
7855            else                    tempax *= 20;
7856            temp = tempax % 32;
7857            tempax /= 32;
7858            if(temp) tempax++;
7859            tempax++;
7860            if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7861               if(resinfo == SIS_RI_1024x768 ||
7862                  resinfo == SIS_RI_1024x576 ||
7863                  resinfo == SIS_RI_1280x1024 ||
7864                  resinfo == SIS_RI_1280x720) {
7865                  /* Otherwise white line or garbage at right edge */
7866                  tempax = (tempax & 0xff00) | 0x20;
7867               }
7868            }
7869         }
7870      }
7871      tempax--;
7872      temp = ((tempax >> 4) & 0x30) | tempbx;
7873      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1D,tempax);
7874      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1E,temp);
7875 
7876      temp = 0x0036; tempbx = 0xD0;
7877      if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
7878         temp = 0x0026; tempbx = 0xC0; /* See En/DisableBridge() */
7879      }
7880      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7881         if(!(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetHiVision | TVSetYPbPr750p | TVSetYPbPr525p))) {
7882            temp |= 0x01;
7883            if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7884               if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
7885                  temp &= ~0x01;
7886               }
7887            }
7888         }
7889      }
7890      SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,tempbx,temp);
7891 
7892      tempbx = SiS_Pr->SiS_HT >> 1;
7893      if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7894      tempbx -= 2;
7895      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x22,tempbx);
7896      temp = (tempbx >> 5) & 0x38;
7897      SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp);
7898 
7899      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
7900         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7901            SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7902            /* LCD-too-dark-error-source, see FinalizeLCD() */
7903         }
7904      }
7905 
7906      SiS_SetDualLinkEtc(SiS_Pr);
7907 
7908   }  /* 301B */
7909 
7910   SiS_SetCRT2VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
7911 }
7912 
7913 /*********************************************/
7914 /*         SET PART 5 REGISTER GROUP         */
7915 /*********************************************/
7916 
7917 static void
7918 SiS_SetGroup5(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7919 {
7920 
7921   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)  return;
7922 
7923   if(SiS_Pr->SiS_ModeType == ModeVGA) {
7924      if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))) {
7925         SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
7926         SiS_LoadDAC(SiS_Pr, ModeNo, ModeIdIndex);
7927      }
7928   }
7929 }
7930 
7931 /*********************************************/
7932 /*     MODIFY CRT1 GROUP FOR SLAVE MODE      */
7933 /*********************************************/
7934 
7935 static bool
7936 SiS_GetLVDSCRT1Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7937                    unsigned short RefreshRateTableIndex, unsigned short *ResIndex,
7938                    unsigned short *DisplayType)
7939  {
7940   unsigned short modeflag = 0;
7941   bool checkhd = true;
7942 
7943   /* Pass 1:1 not supported here */
7944 
7945   if(ModeNo <= 0x13) {
7946      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7947      (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
7948   } else {
7949      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7950      (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
7951   }
7952 
7953   (*ResIndex) &= 0x3F;
7954 
7955   if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
7956 
7957      (*DisplayType) = 80;
7958      if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
7959         (*DisplayType) = 82;
7960         if(SiS_Pr->SiS_ModeType > ModeVGA) {
7961            if(SiS_Pr->SiS_CHSOverScan) (*DisplayType) = 84;
7962         }
7963      }
7964      if((*DisplayType) != 84) {
7965         if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
7966      }
7967 
7968   } else {
7969 
7970      (*DisplayType = 0);
7971      switch(SiS_Pr->SiS_LCDResInfo) {
7972      case Panel_320x240_1: (*DisplayType) = 50;
7973                            checkhd = false;
7974                            break;
7975      case Panel_320x240_2: (*DisplayType) = 14;
7976                            break;
7977      case Panel_320x240_3: (*DisplayType) = 18;
7978                            break;
7979      case Panel_640x480:   (*DisplayType) = 10;
7980                            break;
7981      case Panel_1024x600:  (*DisplayType) = 26;
7982                            break;
7983      default: return true;
7984      }
7985 
7986      if(checkhd) {
7987         if(modeflag & HalfDCLK) (*DisplayType)++;
7988      }
7989 
7990      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
7991         if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) (*DisplayType) += 2;
7992      }
7993 
7994   }
7995 
7996   return true;
7997 }
7998 
7999 static void
8000 SiS_ModCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
8001                 unsigned short RefreshRateTableIndex)
8002 {
8003   unsigned short tempah, i, modeflag, j, ResIndex, DisplayType;
8004   const struct SiS_LVDSCRT1Data *LVDSCRT1Ptr=NULL;
8005   static const unsigned short CRIdx[] = {
8006         0x00, 0x02, 0x03, 0x04, 0x05, 0x06,
8007         0x07, 0x10, 0x11, 0x15, 0x16
8008   };
8009 
8010   if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
8011      (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
8012      (SiS_Pr->SiS_CustomT == CUT_PANEL848)  ||
8013      (SiS_Pr->SiS_CustomT == CUT_PANEL856) )
8014      return;
8015 
8016   if(SiS_Pr->SiS_IF_DEF_LVDS) {
8017      if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
8018         if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;
8019      }
8020   } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
8021      if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;
8022   } else return;
8023 
8024   if(SiS_Pr->SiS_LCDInfo & LCDPass11) return;
8025 
8026   if(SiS_Pr->ChipType < SIS_315H) {
8027      if(SiS_Pr->SiS_SetFlag & SetDOSMode) return;
8028   }
8029 
8030   if(!(SiS_GetLVDSCRT1Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
8031                           &ResIndex, &DisplayType))) {
8032      return;
8033   }
8034 
8035   switch(DisplayType) {
8036     case 50: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_1;           break; /* xSTN */
8037     case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2;           break; /* xSTN */
8038     case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2_H;         break; /* xSTN */
8039     case 18: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3;           break; /* xSTN */
8040     case 19: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3_H;         break; /* xSTN */
8041     case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1;           break;
8042     case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1_H;         break;
8043 #if 0 /* Works better with calculated numbers */
8044     case 26: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1;          break;
8045     case 27: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1_H;        break;
8046     case 28: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2;          break;
8047     case 29: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2_H;        break;
8048 #endif
8049     case 80: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC;               break;
8050     case 81: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC;               break;
8051     case 82: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL;                break;
8052     case 83: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL;                break;
8053     case 84: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1SOPAL;               break;
8054   }
8055 
8056   if(LVDSCRT1Ptr) {
8057 
8058      SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
8059 
8060      for(i = 0; i <= 10; i++) {
8061         tempah = (LVDSCRT1Ptr + ResIndex)->CR[i];
8062         SiS_SetReg(SiS_Pr->SiS_P3d4,CRIdx[i],tempah);
8063      }
8064 
8065      for(i = 0x0A, j = 11; i <= 0x0C; i++, j++) {
8066         tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
8067         SiS_SetReg(SiS_Pr->SiS_P3c4,i,tempah);
8068      }
8069 
8070      tempah = (LVDSCRT1Ptr + ResIndex)->CR[14] & 0xE0;
8071      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);
8072 
8073      if(ModeNo <= 0x13) modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
8074      else               modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
8075 
8076      tempah = ((LVDSCRT1Ptr + ResIndex)->CR[14] & 0x01) << 5;
8077      if(modeflag & DoubleScanMode) tempah |= 0x80;
8078      SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
8079 
8080   } else {
8081 
8082      SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
8083 
8084   }
8085 }
8086 
8087 /*********************************************/
8088 /*              SET CRT2 ECLK                */
8089 /*********************************************/
8090 
8091 static void
8092 SiS_SetCRT2ECLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
8093            unsigned short RefreshRateTableIndex)
8094 {
8095   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
8096   unsigned short clkbase, vclkindex = 0;
8097   unsigned char  sr2b, sr2c;
8098 
8099   if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
8100      SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
8101      if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK == 2) {
8102         RefreshRateTableIndex--;
8103      }
8104      vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
8105                                     RefreshRateTableIndex);
8106      SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
8107   } else {
8108      vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
8109                                     RefreshRateTableIndex);
8110   }
8111 
8112   sr2b = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
8113   sr2c = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
8114 
8115   if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
8116      if(SiS_Pr->SiS_UseROM) {
8117         if(ROMAddr[0x220] & 0x01) {
8118            sr2b = ROMAddr[0x227];
8119            sr2c = ROMAddr[0x228];
8120         }
8121      }
8122   }
8123 
8124   clkbase = 0x02B;
8125   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
8126      if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
8127         clkbase += 3;
8128      }
8129   }
8130 
8131   SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x20);
8132   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
8133   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
8134   SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x10);
8135   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
8136   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
8137   SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x00);
8138   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
8139   SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
8140 }
8141 
8142 /*********************************************/
8143 /*           SET UP CHRONTEL CHIPS           */
8144 /*********************************************/
8145 
8146 static void
8147 SiS_SetCHTVReg(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
8148                unsigned short RefreshRateTableIndex)
8149 {
8150    unsigned short TVType, resindex;
8151    const struct SiS_CHTVRegData *CHTVRegData = NULL;
8152 
8153    if(ModeNo <= 0x13)
8154       resindex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
8155    else
8156       resindex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
8157 
8158    resindex &= 0x3F;
8159 
8160    TVType = 0;
8161    if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
8162    if(SiS_Pr->SiS_TVMode & TVSetPAL) {
8163       TVType += 2;
8164       if(SiS_Pr->SiS_ModeType > ModeVGA) {
8165          if(SiS_Pr->SiS_CHSOverScan) TVType = 8;
8166       }
8167       if(SiS_Pr->SiS_TVMode & TVSetPALM) {
8168          TVType = 4;
8169          if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
8170       } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
8171          TVType = 6;
8172          if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
8173       }
8174    }
8175 
8176    switch(TVType) {
8177       case  0: CHTVRegData = SiS_Pr->SiS_CHTVReg_UNTSC; break;
8178       case  1: CHTVRegData = SiS_Pr->SiS_CHTVReg_ONTSC; break;
8179       case  2: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPAL;  break;
8180       case  3: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL;  break;
8181       case  4: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALM; break;
8182       case  5: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALM; break;
8183       case  6: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALN; break;
8184       case  7: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALN; break;
8185       case  8: CHTVRegData = SiS_Pr->SiS_CHTVReg_SOPAL; break;
8186       default: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL;  break;
8187    }
8188 
8189 
8190    if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
8191 
8192 #ifdef CONFIG_FB_SIS_300
8193 
8194       /* Chrontel 7005 - I assume that it does not come with a 315 series chip */
8195 
8196       /* We don't support modes >800x600 */
8197       if (resindex > 5) return;
8198 
8199       if(SiS_Pr->SiS_TVMode & TVSetPAL) {
8200          SiS_SetCH700x(SiS_Pr,0x04,0x43);  /* 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
8201          SiS_SetCH700x(SiS_Pr,0x09,0x69);  /* Black level for PAL (105)*/
8202       } else {
8203          SiS_SetCH700x(SiS_Pr,0x04,0x03);   /* upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
8204          SiS_SetCH700x(SiS_Pr,0x09,0x71);   /* Black level for NTSC (113)*/
8205       }
8206 
8207       SiS_SetCH700x(SiS_Pr,0x00,CHTVRegData[resindex].Reg[0]);  /* Mode register */
8208       SiS_SetCH700x(SiS_Pr,0x07,CHTVRegData[resindex].Reg[1]);  /* Start active video register */
8209       SiS_SetCH700x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[2]);  /* Position overflow register */
8210       SiS_SetCH700x(SiS_Pr,0x0a,CHTVRegData[resindex].Reg[3]);  /* Horiz Position register */
8211       SiS_SetCH700x(SiS_Pr,0x0b,CHTVRegData[resindex].Reg[4]);  /* Vertical Position register */
8212 
8213       /* Set minimum flicker filter for Luma channel (SR1-0=00),
8214                 minimum text enhancement (S3-2=10),
8215                 maximum flicker filter for Chroma channel (S5-4=10)
8216                 =00101000=0x28 (When reading, S1-0->S3-2, and S3-2->S1-0!)
8217        */
8218       SiS_SetCH700x(SiS_Pr,0x01,0x28);
8219 
8220       /* Set video bandwidth
8221             High bandwidth Luma composite video filter(S0=1)
8222             low bandwidth Luma S-video filter (S2-1=00)
8223             disable peak filter in S-video channel (S3=0)
8224             high bandwidth Chroma Filter (S5-4=11)
8225             =00110001=0x31
8226       */
8227       SiS_SetCH700x(SiS_Pr,0x03,0xb1);       /* old: 3103 */
8228 
8229       /* Register 0x3D does not exist in non-macrovision register map
8230             (Maybe this is a macrovision register?)
8231        */
8232 #ifndef SIS_CP
8233       SiS_SetCH70xx(SiS_Pr,0x3d,0x00);
8234 #endif
8235 
8236       /* Register 0x10 only contains 1 writable bit (S0) for sensing,
8237              all other bits a read-only. Macrovision?
8238        */
8239       SiS_SetCH70xxANDOR(SiS_Pr,0x10,0x00,0x1F);
8240 
8241       /* Register 0x11 only contains 3 writable bits (S0-S2) for
8242              contrast enhancement (set to 010 -> gain 1 Yout = 17/16*(Yin-30) )
8243        */
8244       SiS_SetCH70xxANDOR(SiS_Pr,0x11,0x02,0xF8);
8245 
8246       /* Clear DSEN
8247        */
8248       SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xEF);
8249 
8250       if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {            /* ---- NTSC ---- */
8251          if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) {
8252             if(resindex == 0x04) {                      /* 640x480 overscan: Mode 16 */
8253                SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);       /* loop filter off */
8254                SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);       /* ACIV on, no need to set FSCI */
8255             } else if(resindex == 0x05) {               /* 800x600 overscan: Mode 23 */
8256                SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0);       /* 0x18-0x1f: FSCI 469,762,048 */
8257                SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x0C,0xF0);
8258                SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x00,0xF0);
8259                SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x00,0xF0);
8260                SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xF0);
8261                SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x00,0xF0);
8262                SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x00,0xF0);
8263                SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x00,0xF0);
8264                SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x01,0xEF);       /* Loop filter on for mode 23 */
8265                SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE);       /* ACIV off, need to set FSCI */
8266             }
8267          } else {
8268             if(resindex == 0x04) {                      /* ----- 640x480 underscan; Mode 17 */
8269                SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);       /* loop filter off */
8270                SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);
8271             } else if(resindex == 0x05) {               /* ----- 800x600 underscan: Mode 24 */
8272 #if 0
8273                SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0);       /* (FSCI was 0x1f1c71c7 - this is for mode 22) */
8274                SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x09,0xF0);       /* FSCI for mode 24 is 428,554,851 */
8275                SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x08,0xF0);       /* 198b3a63 */
8276                SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x0b,0xF0);
8277                SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x04,0xF0);
8278                SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x01,0xF0);
8279                SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x06,0xF0);
8280                SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x05,0xF0);
8281                SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);       /* loop filter off for mode 24 */
8282                SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE);       * ACIV off, need to set FSCI */
8283 #endif         /* All alternatives wrong (datasheet wrong?), don't use FSCI */
8284                SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);        /* loop filter off */
8285                SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);
8286             }
8287          }
8288       } else {                                          /* ---- PAL ---- */
8289         /* We don't play around with FSCI in PAL mode */
8290         SiS_SetCH70xxANDOR(SiS_Pr, 0x20, 0x00, 0xEF);   /* loop filter off */
8291         SiS_SetCH70xxANDOR(SiS_Pr, 0x21, 0x01, 0xFE);   /* ACIV on */
8292       }
8293 
8294 #endif  /* 300 */
8295 
8296    } else {
8297 
8298       /* Chrontel 7019 - assumed that it does not come with a 300 series chip */
8299 
8300 #ifdef CONFIG_FB_SIS_315
8301 
8302       unsigned short temp;
8303 
8304       /* We don't support modes >1024x768 */
8305       if (resindex > 6) return;
8306 
8307       temp = CHTVRegData[resindex].Reg[0];
8308       if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp |= 0x10;
8309       SiS_SetCH701x(SiS_Pr,0x00,temp);
8310 
8311       SiS_SetCH701x(SiS_Pr,0x01,CHTVRegData[resindex].Reg[1]);
8312       SiS_SetCH701x(SiS_Pr,0x02,CHTVRegData[resindex].Reg[2]);
8313       SiS_SetCH701x(SiS_Pr,0x04,CHTVRegData[resindex].Reg[3]);
8314       SiS_SetCH701x(SiS_Pr,0x03,CHTVRegData[resindex].Reg[4]);
8315       SiS_SetCH701x(SiS_Pr,0x05,CHTVRegData[resindex].Reg[5]);
8316       SiS_SetCH701x(SiS_Pr,0x06,CHTVRegData[resindex].Reg[6]);
8317 
8318       temp = CHTVRegData[resindex].Reg[7];
8319       if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp = 0x66;
8320       SiS_SetCH701x(SiS_Pr,0x07,temp);
8321 
8322       SiS_SetCH701x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[8]);
8323       SiS_SetCH701x(SiS_Pr,0x15,CHTVRegData[resindex].Reg[9]);
8324       SiS_SetCH701x(SiS_Pr,0x1f,CHTVRegData[resindex].Reg[10]);
8325       SiS_SetCH701x(SiS_Pr,0x0c,CHTVRegData[resindex].Reg[11]);
8326       SiS_SetCH701x(SiS_Pr,0x0d,CHTVRegData[resindex].Reg[12]);
8327       SiS_SetCH701x(SiS_Pr,0x0e,CHTVRegData[resindex].Reg[13]);
8328       SiS_SetCH701x(SiS_Pr,0x0f,CHTVRegData[resindex].Reg[14]);
8329       SiS_SetCH701x(SiS_Pr,0x10,CHTVRegData[resindex].Reg[15]);
8330 
8331       temp = SiS_GetCH701x(SiS_Pr,0x21) & ~0x02;
8332       /* D1 should be set for PAL, PAL-N and NTSC-J,
8333          but I won't do that for PAL unless somebody
8334          tells me to do so. Since the BIOS uses
8335          non-default CIV values and blacklevels,
8336          this might be compensated anyway.
8337        */
8338       if(SiS_Pr->SiS_TVMode & (TVSetPALN | TVSetNTSCJ)) temp |= 0x02;
8339       SiS_SetCH701x(SiS_Pr,0x21,temp);
8340 
8341 #endif  /* 315 */
8342 
8343    }
8344 
8345 #ifdef SIS_CP
8346    SIS_CP_INIT301_CP3
8347 #endif
8348 
8349 }
8350 
8351 #ifdef CONFIG_FB_SIS_315  /* ----------- 315 series only ---------- */
8352 
8353 void
8354 SiS_Chrontel701xBLOn(struct SiS_Private *SiS_Pr)
8355 {
8356    unsigned short temp;
8357 
8358    /* Enable Chrontel 7019 LCD panel backlight */
8359    if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8360       if(SiS_Pr->ChipType == SIS_740) {
8361          SiS_SetCH701x(SiS_Pr,0x66,0x65);
8362       } else {
8363          temp = SiS_GetCH701x(SiS_Pr,0x66);
8364          temp |= 0x20;
8365          SiS_SetCH701x(SiS_Pr,0x66,temp);
8366       }
8367    }
8368 }
8369 
8370 void
8371 SiS_Chrontel701xBLOff(struct SiS_Private *SiS_Pr)
8372 {
8373    unsigned short temp;
8374 
8375    /* Disable Chrontel 7019 LCD panel backlight */
8376    if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8377       temp = SiS_GetCH701x(SiS_Pr,0x66);
8378       temp &= 0xDF;
8379       SiS_SetCH701x(SiS_Pr,0x66,temp);
8380    }
8381 }
8382 
8383 static void
8384 SiS_ChrontelPowerSequencing(struct SiS_Private *SiS_Pr)
8385 {
8386   static const unsigned char regtable[]      = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
8387   static const unsigned char table1024_740[] = { 0x01, 0x02, 0x01, 0x01, 0x01 };
8388   static const unsigned char table1400_740[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 };
8389   static const unsigned char asus1024_740[]  = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8390   static const unsigned char asus1400_740[]  = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8391   static const unsigned char table1024_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8392   static const unsigned char table1400_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8393   const unsigned char *tableptr = NULL;
8394   int i;
8395 
8396   /* Set up Power up/down timing */
8397 
8398   if(SiS_Pr->ChipType == SIS_740) {
8399      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8400         if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1024_740;
8401         else                                      tableptr = table1024_740;
8402      } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8403                (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8404                (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8405         if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1400_740;
8406         else                                      tableptr = table1400_740;
8407      } else return;
8408   } else {
8409      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8410         tableptr = table1024_650;
8411      } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8412                (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8413                (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8414         tableptr = table1400_650;
8415      } else return;
8416   }
8417 
8418   for(i=0; i<5; i++) {
8419      SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]);
8420   }
8421 }
8422 
8423 static void
8424 SiS_SetCH701xForLCD(struct SiS_Private *SiS_Pr)
8425 {
8426   const unsigned char *tableptr = NULL;
8427   unsigned short tempbh;
8428   int i;
8429   static const unsigned char regtable[] = {
8430                 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
8431                 0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66
8432   };
8433   static const unsigned char table1024_740[] = {
8434                 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8435                 0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44
8436   };
8437   static const unsigned char table1280_740[] = {
8438                 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8439                 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44
8440   };
8441   static const unsigned char table1400_740[] = {
8442                 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8443                 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44
8444   };
8445   static const unsigned char table1600_740[] = {
8446                 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8447                 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44
8448   };
8449   static const unsigned char table1024_650[] = {
8450                 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8451                 0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02
8452   };
8453   static const unsigned char table1280_650[] = {
8454                 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8455                 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02
8456   };
8457   static const unsigned char table1400_650[] = {
8458                 0x60, 0x03, 0x11, 0x00, 0x40, 0xef,
8459                 0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02
8460   };
8461   static const unsigned char table1600_650[] = {
8462                 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8463                 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a
8464   };
8465 
8466   if(SiS_Pr->ChipType == SIS_740) {
8467      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)       tableptr = table1024_740;
8468      else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_740;
8469      else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_740;
8470      else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_740;
8471      else return;
8472   } else {
8473      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)       tableptr = table1024_650;
8474      else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_650;
8475      else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_650;
8476      else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_650;
8477      else return;
8478   }
8479 
8480   tempbh = SiS_GetCH701x(SiS_Pr,0x74);
8481   if((tempbh == 0xf6) || (tempbh == 0xc7)) {
8482      tempbh = SiS_GetCH701x(SiS_Pr,0x73);
8483      if(tempbh == 0xc8) {
8484         if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) return;
8485      } else if(tempbh == 0xdb) {
8486         if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) return;
8487         if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) return;
8488      } else if(tempbh == 0xde) {
8489         if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) return;
8490      }
8491   }
8492 
8493   if(SiS_Pr->ChipType == SIS_740) tempbh = 0x0d;
8494   else                            tempbh = 0x0c;
8495 
8496   for(i = 0; i < tempbh; i++) {
8497      SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]);
8498   }
8499   SiS_ChrontelPowerSequencing(SiS_Pr);
8500   tempbh = SiS_GetCH701x(SiS_Pr,0x1e);
8501   tempbh |= 0xc0;
8502   SiS_SetCH701x(SiS_Pr,0x1e,tempbh);
8503 
8504   if(SiS_Pr->ChipType == SIS_740) {
8505      tempbh = SiS_GetCH701x(SiS_Pr,0x1c);
8506      tempbh &= 0xfb;
8507      SiS_SetCH701x(SiS_Pr,0x1c,tempbh);
8508      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8509      tempbh = SiS_GetCH701x(SiS_Pr,0x64);
8510      tempbh |= 0x40;
8511      SiS_SetCH701x(SiS_Pr,0x64,tempbh);
8512      tempbh = SiS_GetCH701x(SiS_Pr,0x03);
8513      tempbh &= 0x3f;
8514      SiS_SetCH701x(SiS_Pr,0x03,tempbh);
8515   }
8516 }
8517 
8518 static void
8519 SiS_ChrontelResetVSync(struct SiS_Private *SiS_Pr)
8520 {
8521   unsigned char temp, temp1;
8522 
8523   temp1 = SiS_GetCH701x(SiS_Pr,0x49);
8524   SiS_SetCH701x(SiS_Pr,0x49,0x3e);
8525   temp = SiS_GetCH701x(SiS_Pr,0x47);
8526   temp &= 0x7f; /* Use external VSYNC */
8527   SiS_SetCH701x(SiS_Pr,0x47,temp);
8528   SiS_LongDelay(SiS_Pr, 3);
8529   temp = SiS_GetCH701x(SiS_Pr,0x47);
8530   temp |= 0x80; /* Use internal VSYNC */
8531   SiS_SetCH701x(SiS_Pr,0x47,temp);
8532   SiS_SetCH701x(SiS_Pr,0x49,temp1);
8533 }
8534 
8535 static void
8536 SiS_Chrontel701xOn(struct SiS_Private *SiS_Pr)
8537 {
8538   unsigned short temp;
8539 
8540   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8541      if(SiS_Pr->ChipType == SIS_740) {
8542         temp = SiS_GetCH701x(SiS_Pr,0x1c);
8543         temp |= 0x04;   /* Invert XCLK phase */
8544         SiS_SetCH701x(SiS_Pr,0x1c,temp);
8545      }
8546      if(SiS_IsYPbPr(SiS_Pr)) {
8547         temp = SiS_GetCH701x(SiS_Pr,0x01);
8548         temp &= 0x3f;
8549         temp |= 0x80;   /* Enable YPrPb (HDTV) */
8550         SiS_SetCH701x(SiS_Pr,0x01,temp);
8551      }
8552      if(SiS_IsChScart(SiS_Pr)) {
8553         temp = SiS_GetCH701x(SiS_Pr,0x01);
8554         temp &= 0x3f;
8555         temp |= 0xc0;   /* Enable SCART + CVBS */
8556         SiS_SetCH701x(SiS_Pr,0x01,temp);
8557      }
8558      if(SiS_Pr->ChipType == SIS_740) {
8559         SiS_ChrontelResetVSync(SiS_Pr);
8560         SiS_SetCH701x(SiS_Pr,0x49,0x20);   /* Enable TV path */
8561      } else {
8562         SiS_SetCH701x(SiS_Pr,0x49,0x20);   /* Enable TV path */
8563         temp = SiS_GetCH701x(SiS_Pr,0x49);
8564         if(SiS_IsYPbPr(SiS_Pr)) {
8565            temp = SiS_GetCH701x(SiS_Pr,0x73);
8566            temp |= 0x60;
8567            SiS_SetCH701x(SiS_Pr,0x73,temp);
8568         }
8569         temp = SiS_GetCH701x(SiS_Pr,0x47);
8570         temp &= 0x7f;
8571         SiS_SetCH701x(SiS_Pr,0x47,temp);
8572         SiS_LongDelay(SiS_Pr, 2);
8573         temp = SiS_GetCH701x(SiS_Pr,0x47);
8574         temp |= 0x80;
8575         SiS_SetCH701x(SiS_Pr,0x47,temp);
8576      }
8577   }
8578 }
8579 
8580 static void
8581 SiS_Chrontel701xOff(struct SiS_Private *SiS_Pr)
8582 {
8583   unsigned short temp;
8584 
8585   /* Complete power down of LVDS */
8586   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8587      if(SiS_Pr->ChipType == SIS_740) {
8588         SiS_LongDelay(SiS_Pr, 1);
8589         SiS_GenericDelay(SiS_Pr, 5887);
8590         SiS_SetCH701x(SiS_Pr,0x76,0xac);
8591         SiS_SetCH701x(SiS_Pr,0x66,0x00);
8592      } else {
8593         SiS_LongDelay(SiS_Pr, 2);
8594         temp = SiS_GetCH701x(SiS_Pr,0x76);
8595         temp &= 0xfc;
8596         SiS_SetCH701x(SiS_Pr,0x76,temp);
8597         SiS_SetCH701x(SiS_Pr,0x66,0x00);
8598      }
8599   }
8600 }
8601 
8602 static void
8603 SiS_ChrontelResetDB(struct SiS_Private *SiS_Pr)
8604 {
8605      unsigned short temp;
8606 
8607      if(SiS_Pr->ChipType == SIS_740) {
8608 
8609         temp = SiS_GetCH701x(SiS_Pr,0x4a);  /* Version ID */
8610         temp &= 0x01;
8611         if(!temp) {
8612 
8613            if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8614               temp = SiS_GetCH701x(SiS_Pr,0x49);
8615               SiS_SetCH701x(SiS_Pr,0x49,0x3e);
8616            }
8617 
8618            /* Reset Chrontel 7019 datapath */
8619            SiS_SetCH701x(SiS_Pr,0x48,0x10);
8620            SiS_LongDelay(SiS_Pr, 1);
8621            SiS_SetCH701x(SiS_Pr,0x48,0x18);
8622 
8623            if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8624               SiS_ChrontelResetVSync(SiS_Pr);
8625               SiS_SetCH701x(SiS_Pr,0x49,temp);
8626            }
8627 
8628         } else {
8629 
8630            /* Clear/set/clear GPIO */
8631            temp = SiS_GetCH701x(SiS_Pr,0x5c);
8632            temp &= 0xef;
8633            SiS_SetCH701x(SiS_Pr,0x5c,temp);
8634            temp = SiS_GetCH701x(SiS_Pr,0x5c);
8635            temp |= 0x10;
8636            SiS_SetCH701x(SiS_Pr,0x5c,temp);
8637            temp = SiS_GetCH701x(SiS_Pr,0x5c);
8638            temp &= 0xef;
8639            SiS_SetCH701x(SiS_Pr,0x5c,temp);
8640            temp = SiS_GetCH701x(SiS_Pr,0x61);
8641            if(!temp) {
8642               SiS_SetCH701xForLCD(SiS_Pr);
8643            }
8644         }
8645 
8646      } else { /* 650 */
8647         /* Reset Chrontel 7019 datapath */
8648         SiS_SetCH701x(SiS_Pr,0x48,0x10);
8649         SiS_LongDelay(SiS_Pr, 1);
8650         SiS_SetCH701x(SiS_Pr,0x48,0x18);
8651      }
8652 }
8653 
8654 static void
8655 SiS_ChrontelInitTVVSync(struct SiS_Private *SiS_Pr)
8656 {
8657      unsigned short temp;
8658 
8659      if(SiS_Pr->ChipType == SIS_740) {
8660 
8661         if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8662            SiS_ChrontelResetVSync(SiS_Pr);
8663         }
8664 
8665      } else {
8666 
8667         SiS_SetCH701x(SiS_Pr,0x76,0xaf);  /* Power up LVDS block */
8668         temp = SiS_GetCH701x(SiS_Pr,0x49);
8669         temp &= 1;
8670         if(temp != 1) {  /* TV block powered? (0 = yes, 1 = no) */
8671            temp = SiS_GetCH701x(SiS_Pr,0x47);
8672            temp &= 0x70;
8673            SiS_SetCH701x(SiS_Pr,0x47,temp);  /* enable VSYNC */
8674            SiS_LongDelay(SiS_Pr, 3);
8675            temp = SiS_GetCH701x(SiS_Pr,0x47);
8676            temp |= 0x80;
8677            SiS_SetCH701x(SiS_Pr,0x47,temp);  /* disable VSYNC */
8678         }
8679 
8680      }
8681 }
8682 
8683 static void
8684 SiS_ChrontelDoSomething3(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
8685 {
8686      unsigned short temp,temp1;
8687 
8688      if(SiS_Pr->ChipType == SIS_740) {
8689 
8690         temp = SiS_GetCH701x(SiS_Pr,0x61);
8691         if(temp < 1) {
8692            temp++;
8693            SiS_SetCH701x(SiS_Pr,0x61,temp);
8694         }
8695         SiS_SetCH701x(SiS_Pr,0x66,0x45);  /* Panel power on */
8696         SiS_SetCH701x(SiS_Pr,0x76,0xaf);  /* All power on */
8697         SiS_LongDelay(SiS_Pr, 1);
8698         SiS_GenericDelay(SiS_Pr, 5887);
8699 
8700      } else {  /* 650 */
8701 
8702         temp1 = 0;
8703         temp = SiS_GetCH701x(SiS_Pr,0x61);
8704         if(temp < 2) {
8705            temp++;
8706            SiS_SetCH701x(SiS_Pr,0x61,temp);
8707            temp1 = 1;
8708         }
8709         SiS_SetCH701x(SiS_Pr,0x76,0xac);
8710         temp = SiS_GetCH701x(SiS_Pr,0x66);
8711         temp |= 0x5f;
8712         SiS_SetCH701x(SiS_Pr,0x66,temp);
8713         if(ModeNo > 0x13) {
8714            if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8715               SiS_GenericDelay(SiS_Pr, 1023);
8716            } else {
8717               SiS_GenericDelay(SiS_Pr, 767);
8718            }
8719         } else {
8720            if(!temp1)
8721               SiS_GenericDelay(SiS_Pr, 767);
8722         }
8723         temp = SiS_GetCH701x(SiS_Pr,0x76);
8724         temp |= 0x03;
8725         SiS_SetCH701x(SiS_Pr,0x76,temp);
8726         temp = SiS_GetCH701x(SiS_Pr,0x66);
8727         temp &= 0x7f;
8728         SiS_SetCH701x(SiS_Pr,0x66,temp);
8729         SiS_LongDelay(SiS_Pr, 1);
8730 
8731      }
8732 }
8733 
8734 static void
8735 SiS_ChrontelDoSomething2(struct SiS_Private *SiS_Pr)
8736 {
8737      unsigned short temp;
8738 
8739      SiS_LongDelay(SiS_Pr, 1);
8740 
8741      do {
8742        temp = SiS_GetCH701x(SiS_Pr,0x66);
8743        temp &= 0x04;  /* PLL stable? -> bail out */
8744        if(temp == 0x04) break;
8745 
8746        if(SiS_Pr->ChipType == SIS_740) {
8747           /* Power down LVDS output, PLL normal operation */
8748           SiS_SetCH701x(SiS_Pr,0x76,0xac);
8749        }
8750 
8751        SiS_SetCH701xForLCD(SiS_Pr);
8752 
8753        temp = SiS_GetCH701x(SiS_Pr,0x76);
8754        temp &= 0xfb;  /* Reset PLL */
8755        SiS_SetCH701x(SiS_Pr,0x76,temp);
8756        SiS_LongDelay(SiS_Pr, 2);
8757        temp = SiS_GetCH701x(SiS_Pr,0x76);
8758        temp |= 0x04;  /* PLL normal operation */
8759        SiS_SetCH701x(SiS_Pr,0x76,temp);
8760        if(SiS_Pr->ChipType == SIS_740) {
8761           SiS_SetCH701x(SiS_Pr,0x78,0xe0);      /* PLL loop filter */
8762        } else {
8763           SiS_SetCH701x(SiS_Pr,0x78,0x60);
8764        }
8765        SiS_LongDelay(SiS_Pr, 2);
8766     } while(0);
8767 
8768     SiS_SetCH701x(SiS_Pr,0x77,0x00);  /* MV? */
8769 }
8770 
8771 static void
8772 SiS_ChrontelDoSomething1(struct SiS_Private *SiS_Pr)
8773 {
8774      unsigned short temp;
8775 
8776      temp = SiS_GetCH701x(SiS_Pr,0x03);
8777      temp |= 0x80;      /* Set datapath 1 to TV   */
8778      temp &= 0xbf;      /* Set datapath 2 to LVDS */
8779      SiS_SetCH701x(SiS_Pr,0x03,temp);
8780 
8781      if(SiS_Pr->ChipType == SIS_740) {
8782 
8783         temp = SiS_GetCH701x(SiS_Pr,0x1c);
8784         temp &= 0xfb;   /* Normal XCLK phase */
8785         SiS_SetCH701x(SiS_Pr,0x1c,temp);
8786 
8787         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8788 
8789         temp = SiS_GetCH701x(SiS_Pr,0x64);
8790         temp |= 0x40;   /* ? Bit not defined */
8791         SiS_SetCH701x(SiS_Pr,0x64,temp);
8792 
8793         temp = SiS_GetCH701x(SiS_Pr,0x03);
8794         temp &= 0x3f;   /* D1 input to both LVDS and TV */
8795         SiS_SetCH701x(SiS_Pr,0x03,temp);
8796 
8797         if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) {
8798            SiS_SetCH701x(SiS_Pr,0x63,0x40); /* LVDS off */
8799            SiS_LongDelay(SiS_Pr, 1);
8800            SiS_SetCH701x(SiS_Pr,0x63,0x00); /* LVDS on */
8801            SiS_ChrontelResetDB(SiS_Pr);
8802            SiS_ChrontelDoSomething2(SiS_Pr);
8803            SiS_ChrontelDoSomething3(SiS_Pr, 0);
8804         } else {
8805            temp = SiS_GetCH701x(SiS_Pr,0x66);
8806            if(temp != 0x45) {
8807               SiS_ChrontelResetDB(SiS_Pr);
8808               SiS_ChrontelDoSomething2(SiS_Pr);
8809               SiS_ChrontelDoSomething3(SiS_Pr, 0);
8810            }
8811         }
8812 
8813      } else { /* 650 */
8814 
8815         SiS_ChrontelResetDB(SiS_Pr);
8816         SiS_ChrontelDoSomething2(SiS_Pr);
8817         temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34);
8818         SiS_ChrontelDoSomething3(SiS_Pr,temp);
8819         SiS_SetCH701x(SiS_Pr,0x76,0xaf);  /* All power on, LVDS normal operation */
8820 
8821      }
8822 
8823 }
8824 #endif  /* 315 series  */
8825 
8826 /*********************************************/
8827 /*      MAIN: SET CRT2 REGISTER GROUP        */
8828 /*********************************************/
8829 
8830 bool
8831 SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
8832 {
8833 #ifdef CONFIG_FB_SIS_300
8834    unsigned char  *ROMAddr  = SiS_Pr->VirtualRomBase;
8835 #endif
8836    unsigned short ModeIdIndex, RefreshRateTableIndex;
8837 
8838    SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
8839 
8840    if(!SiS_Pr->UseCustomMode) {
8841       SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex);
8842    } else {
8843       ModeIdIndex = 0;
8844    }
8845 
8846    /* Used for shifting CR33 */
8847    SiS_Pr->SiS_SelectCRT2Rate = 4;
8848 
8849    SiS_UnLockCRT2(SiS_Pr);
8850 
8851    RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex);
8852 
8853    SiS_SaveCRT2Info(SiS_Pr,ModeNo);
8854 
8855    if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8856       SiS_DisableBridge(SiS_Pr);
8857       if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->ChipType == SIS_730)) {
8858          SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,0x80);
8859       }
8860       SiS_SetCRT2ModeRegs(SiS_Pr, ModeNo, ModeIdIndex);
8861    }
8862 
8863    if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
8864       SiS_LockCRT2(SiS_Pr);
8865       SiS_DisplayOn(SiS_Pr);
8866       return true;
8867    }
8868 
8869    SiS_GetCRT2Data(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8870 
8871    /* Set up Panel Link for LVDS and LCDA */
8872    SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
8873    if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
8874        ((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ||
8875        ((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS30xBLV)) ) {
8876       SiS_GetLVDSDesData(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8877    }
8878 
8879    if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8880       SiS_SetGroup1(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8881    }
8882 
8883    if(SiS_Pr->SiS_VBType & VB_SISVB) {
8884 
8885       if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8886 
8887          SiS_SetGroup2(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8888 #ifdef CONFIG_FB_SIS_315
8889          SiS_SetGroup2_C_ELV(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8890 #endif
8891          SiS_SetGroup3(SiS_Pr, ModeNo, ModeIdIndex);
8892          SiS_SetGroup4(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8893 #ifdef CONFIG_FB_SIS_315
8894          SiS_SetGroup4_C_ELV(SiS_Pr, ModeNo, ModeIdIndex);
8895 #endif
8896          SiS_SetGroup5(SiS_Pr, ModeNo, ModeIdIndex);
8897 
8898          SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex);
8899 
8900          /* For 301BDH (Panel link initialization): */
8901          if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
8902 
8903             if(!((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10)))) {
8904                if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
8905                   SiS_ModCRT1CRTC(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8906                }
8907             }
8908             SiS_SetCRT2ECLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8909          }
8910       }
8911 
8912    } else {
8913 
8914       SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex);
8915 
8916       SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8917 
8918       SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8919 
8920       if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8921          if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
8922             if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
8923                if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8924 #ifdef CONFIG_FB_SIS_315
8925                   SiS_SetCH701xForLCD(SiS_Pr);
8926 #endif
8927                }
8928             }
8929             if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8930                SiS_SetCHTVReg(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8931             }
8932          }
8933       }
8934 
8935    }
8936 
8937 #ifdef CONFIG_FB_SIS_300
8938    if(SiS_Pr->ChipType < SIS_315H) {
8939       if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8940          if(SiS_Pr->SiS_UseOEM) {
8941             if((SiS_Pr->SiS_UseROM) && (SiS_Pr->SiS_UseOEM == -1)) {
8942                if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
8943                   SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8944                }
8945             } else {
8946                SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8947             }
8948          }
8949          if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
8950             if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
8951                (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
8952                SetOEMLCDData2(SiS_Pr, ModeNo, ModeIdIndex,RefreshRateTableIndex);
8953             }
8954             SiS_DisplayOn(SiS_Pr);
8955          }
8956       }
8957    }
8958 #endif
8959 
8960 #ifdef CONFIG_FB_SIS_315
8961    if(SiS_Pr->ChipType >= SIS_315H) {
8962       if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8963          if(SiS_Pr->ChipType < SIS_661) {
8964             SiS_FinalizeLCD(SiS_Pr, ModeNo, ModeIdIndex);
8965             SiS_OEM310Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8966          } else {
8967             SiS_OEM661Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8968          }
8969          SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40);
8970       }
8971    }
8972 #endif
8973 
8974    if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8975       SiS_EnableBridge(SiS_Pr);
8976    }
8977 
8978    SiS_DisplayOn(SiS_Pr);
8979 
8980    if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
8981       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8982          /* Disable LCD panel when using TV */
8983          SiS_SetRegSR11ANDOR(SiS_Pr,0xFF,0x0C);
8984       } else {
8985          /* Disable TV when using LCD */
8986          SiS_SetCH70xxANDOR(SiS_Pr,0x0e,0x01,0xf8);
8987       }
8988    }
8989 
8990    if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8991       SiS_LockCRT2(SiS_Pr);
8992    }
8993 
8994    return true;
8995 }
8996 
8997 
8998 /*********************************************/
8999 /*     ENABLE/DISABLE LCD BACKLIGHT (SIS)    */
9000 /*********************************************/
9001 
9002 void
9003 SiS_SiS30xBLOn(struct SiS_Private *SiS_Pr)
9004 {
9005   /* Switch on LCD backlight on SiS30xLV */
9006   SiS_DDC2Delay(SiS_Pr,0xff00);
9007   if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
9008      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
9009      SiS_WaitVBRetrace(SiS_Pr);
9010   }
9011   if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x01)) {
9012      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
9013   }
9014 }
9015 
9016 void
9017 SiS_SiS30xBLOff(struct SiS_Private *SiS_Pr)
9018 {
9019   /* Switch off LCD backlight on SiS30xLV */
9020   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
9021   SiS_DDC2Delay(SiS_Pr,0xff00);
9022 }
9023 
9024 /*********************************************/
9025 /*          DDC RELATED FUNCTIONS            */
9026 /*********************************************/
9027 
9028 static void
9029 SiS_SetupDDCN(struct SiS_Private *SiS_Pr)
9030 {
9031   SiS_Pr->SiS_DDC_NData = ~SiS_Pr->SiS_DDC_Data;
9032   SiS_Pr->SiS_DDC_NClk  = ~SiS_Pr->SiS_DDC_Clk;
9033   if((SiS_Pr->SiS_DDC_Index == 0x11) && (SiS_Pr->SiS_SensibleSR11)) {
9034      SiS_Pr->SiS_DDC_NData &= 0x0f;
9035      SiS_Pr->SiS_DDC_NClk  &= 0x0f;
9036   }
9037 }
9038 
9039 #ifdef CONFIG_FB_SIS_300
9040 static unsigned char *
9041 SiS_SetTrumpBlockLoop(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
9042 {
9043   int i, j, num;
9044   unsigned short tempah,temp;
9045   unsigned char *mydataptr;
9046 
9047   for(i=0; i<20; i++) {                         /* Do 20 attempts to write */
9048      mydataptr = dataptr;
9049      num = *mydataptr++;
9050      if(!num) return mydataptr;
9051      if(i) {
9052         SiS_SetStop(SiS_Pr);
9053         SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 2);
9054      }
9055      if(SiS_SetStart(SiS_Pr)) continue;         /* Set start condition */
9056      tempah = SiS_Pr->SiS_DDC_DeviceAddr;
9057      temp = SiS_WriteDDC2Data(SiS_Pr,tempah);   /* Write DAB (S0=0=write) */
9058      if(temp) continue;                         /*    (ERROR: no ack) */
9059      tempah = *mydataptr++;
9060      temp = SiS_WriteDDC2Data(SiS_Pr,tempah);   /* Write register number */
9061      if(temp) continue;                         /*    (ERROR: no ack) */
9062      for(j=0; j<num; j++) {
9063         tempah = *mydataptr++;
9064         temp = SiS_WriteDDC2Data(SiS_Pr,tempah);/* Write DAB (S0=0=write) */
9065         if(temp) break;
9066      }
9067      if(temp) continue;
9068      if(SiS_SetStop(SiS_Pr)) continue;
9069      return mydataptr;
9070   }
9071   return NULL;
9072 }
9073 
9074 static bool
9075 SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
9076 {
9077   SiS_Pr->SiS_DDC_DeviceAddr = 0xF0;            /* DAB (Device Address Byte) */
9078   SiS_Pr->SiS_DDC_Index = 0x11;                 /* Bit 0 = SC;  Bit 1 = SD */
9079   SiS_Pr->SiS_DDC_Data  = 0x02;                 /* Bitmask in IndexReg for Data */
9080   SiS_Pr->SiS_DDC_Clk   = 0x01;                 /* Bitmask in IndexReg for Clk */
9081   SiS_SetupDDCN(SiS_Pr);
9082 
9083   SiS_SetSwitchDDC2(SiS_Pr);
9084 
9085   while(*dataptr) {
9086      dataptr = SiS_SetTrumpBlockLoop(SiS_Pr, dataptr);
9087      if(!dataptr) return false;
9088   }
9089   return true;
9090 }
9091 #endif
9092 
9093 /* The Chrontel 700x is connected to the 630/730 via
9094  * the 630/730's DDC/I2C port.
9095  *
9096  * On 630(S)T chipset, the index changed from 0x11 to
9097  * 0x0a, possibly for working around the DDC problems
9098  */
9099 
9100 static bool
9101 SiS_SetChReg(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val, unsigned short myor)
9102 {
9103   unsigned short temp, i;
9104 
9105   for(i=0; i<20; i++) {                         /* Do 20 attempts to write */
9106      if(i) {
9107         SiS_SetStop(SiS_Pr);
9108         SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4);
9109      }
9110      if(SiS_SetStart(SiS_Pr)) continue;                                 /* Set start condition */
9111      temp = SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr);      /* Write DAB (S0=0=write) */
9112      if(temp) continue;                                                 /*    (ERROR: no ack) */
9113      temp = SiS_WriteDDC2Data(SiS_Pr, (reg | myor));                    /* Write RAB (700x: set bit 7, see datasheet) */
9114      if(temp) continue;                                                 /*    (ERROR: no ack) */
9115      temp = SiS_WriteDDC2Data(SiS_Pr, val);                             /* Write data */
9116      if(temp) continue;                                                 /*    (ERROR: no ack) */
9117      if(SiS_SetStop(SiS_Pr)) continue;                                  /* Set stop condition */
9118      SiS_Pr->SiS_ChrontelInit = 1;
9119      return true;
9120   }
9121   return false;
9122 }
9123 
9124 /* Write to Chrontel 700x */
9125 void
9126 SiS_SetCH700x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
9127 {
9128   SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;            /* DAB (Device Address Byte) */
9129 
9130   SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9131 
9132   if(!(SiS_Pr->SiS_ChrontelInit)) {
9133      SiS_Pr->SiS_DDC_Index = 0x11;              /* Bit 0 = SC;  Bit 1 = SD */
9134      SiS_Pr->SiS_DDC_Data  = 0x02;              /* Bitmask in IndexReg for Data */
9135      SiS_Pr->SiS_DDC_Clk   = 0x01;              /* Bitmask in IndexReg for Clk */
9136      SiS_SetupDDCN(SiS_Pr);
9137   }
9138 
9139   if( (!(SiS_SetChReg(SiS_Pr, reg, val, 0x80))) &&
9140       (!(SiS_Pr->SiS_ChrontelInit)) ) {
9141      SiS_Pr->SiS_DDC_Index = 0x0a;
9142      SiS_Pr->SiS_DDC_Data  = 0x80;
9143      SiS_Pr->SiS_DDC_Clk   = 0x40;
9144      SiS_SetupDDCN(SiS_Pr);
9145 
9146      SiS_SetChReg(SiS_Pr, reg, val, 0x80);
9147   }
9148 }
9149 
9150 /* Write to Chrontel 701x */
9151 /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
9152 void
9153 SiS_SetCH701x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
9154 {
9155   SiS_Pr->SiS_DDC_Index = 0x11;                 /* Bit 0 = SC;  Bit 1 = SD */
9156   SiS_Pr->SiS_DDC_Data  = 0x08;                 /* Bitmask in IndexReg for Data */
9157   SiS_Pr->SiS_DDC_Clk   = 0x04;                 /* Bitmask in IndexReg for Clk */
9158   SiS_SetupDDCN(SiS_Pr);
9159   SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;            /* DAB (Device Address Byte) */
9160   SiS_SetChReg(SiS_Pr, reg, val, 0);
9161 }
9162 
9163 static
9164 void
9165 SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
9166 {
9167   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
9168      SiS_SetCH700x(SiS_Pr, reg, val);
9169   else
9170      SiS_SetCH701x(SiS_Pr, reg, val);
9171 }
9172 
9173 static unsigned short
9174 SiS_GetChReg(struct SiS_Private *SiS_Pr, unsigned short myor)
9175 {
9176   unsigned short tempah, temp, i;
9177 
9178   for(i=0; i<20; i++) {                         /* Do 20 attempts to read */
9179      if(i) {
9180         SiS_SetStop(SiS_Pr);
9181         SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4);
9182      }
9183      if(SiS_SetStart(SiS_Pr)) continue;                                 /* Set start condition */
9184      temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr);       /* Write DAB (S0=0=write) */
9185      if(temp) continue;                                                 /*        (ERROR: no ack) */
9186      temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_ReadAddr | myor);  /* Write RAB (700x: | 0x80) */
9187      if(temp) continue;                                                 /*        (ERROR: no ack) */
9188      if (SiS_SetStart(SiS_Pr)) continue;                                /* Re-start */
9189      temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr | 0x01);/* DAB (S0=1=read) */
9190      if(temp) continue;                                                 /*        (ERROR: no ack) */
9191      tempah = SiS_ReadDDC2Data(SiS_Pr);                                 /* Read byte */
9192      if(SiS_SetStop(SiS_Pr)) continue;                                  /* Stop condition */
9193      SiS_Pr->SiS_ChrontelInit = 1;
9194      return tempah;
9195   }
9196   return 0xFFFF;
9197 }
9198 
9199 /* Read from Chrontel 700x */
9200 /* Parameter is [Register no (S7-S0)] */
9201 unsigned short
9202 SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short tempbx)
9203 {
9204   unsigned short result;
9205 
9206   SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;            /* DAB */
9207 
9208   SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9209 
9210   if(!(SiS_Pr->SiS_ChrontelInit)) {
9211      SiS_Pr->SiS_DDC_Index = 0x11;              /* Bit 0 = SC;  Bit 1 = SD */
9212      SiS_Pr->SiS_DDC_Data  = 0x02;              /* Bitmask in IndexReg for Data */
9213      SiS_Pr->SiS_DDC_Clk   = 0x01;              /* Bitmask in IndexReg for Clk */
9214      SiS_SetupDDCN(SiS_Pr);
9215   }
9216 
9217   SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9218 
9219   if( ((result = SiS_GetChReg(SiS_Pr,0x80)) == 0xFFFF) &&
9220       (!SiS_Pr->SiS_ChrontelInit) ) {
9221 
9222      SiS_Pr->SiS_DDC_Index = 0x0a;
9223      SiS_Pr->SiS_DDC_Data  = 0x80;
9224      SiS_Pr->SiS_DDC_Clk   = 0x40;
9225      SiS_SetupDDCN(SiS_Pr);
9226 
9227      result = SiS_GetChReg(SiS_Pr,0x80);
9228   }
9229   return result;
9230 }
9231 
9232 /* Read from Chrontel 701x */
9233 /* Parameter is [Register no (S7-S0)] */
9234 unsigned short
9235 SiS_GetCH701x(struct SiS_Private *SiS_Pr, unsigned short tempbx)
9236 {
9237   SiS_Pr->SiS_DDC_Index = 0x11;                 /* Bit 0 = SC;  Bit 1 = SD */
9238   SiS_Pr->SiS_DDC_Data  = 0x08;                 /* Bitmask in IndexReg for Data */
9239   SiS_Pr->SiS_DDC_Clk   = 0x04;                 /* Bitmask in IndexReg for Clk */
9240   SiS_SetupDDCN(SiS_Pr);
9241   SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;            /* DAB */
9242 
9243   SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9244 
9245   return SiS_GetChReg(SiS_Pr,0);
9246 }
9247 
9248 /* Read from Chrontel 70xx */
9249 /* Parameter is [Register no (S7-S0)] */
9250 static
9251 unsigned short
9252 SiS_GetCH70xx(struct SiS_Private *SiS_Pr, unsigned short tempbx)
9253 {
9254   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
9255      return SiS_GetCH700x(SiS_Pr, tempbx);
9256   else
9257      return SiS_GetCH701x(SiS_Pr, tempbx);
9258 }
9259 
9260 void
9261 SiS_SetCH70xxANDOR(struct SiS_Private *SiS_Pr, unsigned short reg,
9262                 unsigned char myor, unsigned short myand)
9263 {
9264   unsigned short tempbl;
9265 
9266   tempbl = (SiS_GetCH70xx(SiS_Pr, (reg & 0xFF)) & myand) | myor;
9267   SiS_SetCH70xx(SiS_Pr, reg, tempbl);
9268 }
9269 
9270 /* Our own DDC functions */
9271 static
9272 unsigned short
9273 SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
9274                 unsigned short adaptnum, unsigned short DDCdatatype, bool checkcr32,
9275                 unsigned int VBFlags2)
9276 {
9277      unsigned char ddcdtype[] = { 0xa0, 0xa0, 0xa0, 0xa2, 0xa6 };
9278      unsigned char flag, cr32;
9279      unsigned short        temp = 0, myadaptnum = adaptnum;
9280 
9281      if(adaptnum != 0) {
9282         if(!(VBFlags2 & VB2_SISTMDSBRIDGE)) return 0xFFFF;
9283         if((VBFlags2 & VB2_30xBDH) && (adaptnum == 1)) return 0xFFFF;
9284      }
9285 
9286      /* adapternum for SiS bridges: 0 = CRT1, 1 = LCD, 2 = VGA2 */
9287 
9288      SiS_Pr->SiS_ChrontelInit = 0;   /* force re-detection! */
9289 
9290      SiS_Pr->SiS_DDC_SecAddr = 0;
9291      SiS_Pr->SiS_DDC_DeviceAddr = ddcdtype[DDCdatatype];
9292      SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_P3c4;
9293      SiS_Pr->SiS_DDC_Index = 0x11;
9294      flag = 0xff;
9295 
9296      cr32 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x32);
9297 
9298 #if 0
9299      if(VBFlags2 & VB2_SISBRIDGE) {
9300         if(myadaptnum == 0) {
9301            if(!(cr32 & 0x20)) {
9302               myadaptnum = 2;
9303               if(!(cr32 & 0x10)) {
9304                  myadaptnum = 1;
9305                  if(!(cr32 & 0x08)) {
9306                     myadaptnum = 0;
9307                  }
9308               }
9309            }
9310         }
9311      }
9312 #endif
9313 
9314      if(VGAEngine == SIS_300_VGA) {             /* 300 series */
9315 
9316         if(myadaptnum != 0) {
9317            flag = 0;
9318            if(VBFlags2 & VB2_SISBRIDGE) {
9319               SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9320               SiS_Pr->SiS_DDC_Index = 0x0f;
9321            }
9322         }
9323 
9324         if(!(VBFlags2 & VB2_301)) {
9325            if((cr32 & 0x80) && (checkcr32)) {
9326               if(myadaptnum >= 1) {
9327                  if(!(cr32 & 0x08)) {
9328                      myadaptnum = 1;
9329                      if(!(cr32 & 0x10)) return 0xFFFF;
9330                  }
9331               }
9332            }
9333         }
9334 
9335         temp = 4 - (myadaptnum * 2);
9336         if(flag) temp = 0;
9337 
9338      } else {                                           /* 315/330 series */
9339 
9340         /* here we simplify: 0 = CRT1, 1 = CRT2 (VGA, LCD) */
9341 
9342         if(VBFlags2 & VB2_SISBRIDGE) {
9343            if(myadaptnum == 2) {
9344               myadaptnum = 1;
9345            }
9346         }
9347 
9348         if(myadaptnum == 1) {
9349            flag = 0;
9350            if(VBFlags2 & VB2_SISBRIDGE) {
9351               SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9352               SiS_Pr->SiS_DDC_Index = 0x0f;
9353            }
9354         }
9355 
9356         if((cr32 & 0x80) && (checkcr32)) {
9357            if(myadaptnum >= 1) {
9358               if(!(cr32 & 0x08)) {
9359                  myadaptnum = 1;
9360                  if(!(cr32 & 0x10)) return 0xFFFF;
9361               }
9362            }
9363         }
9364 
9365         temp = myadaptnum;
9366         if(myadaptnum == 1) {
9367            temp = 0;
9368            if(VBFlags2 & VB2_LVDS) flag = 0xff;
9369         }
9370 
9371         if(flag) temp = 0;
9372     }
9373 
9374     SiS_Pr->SiS_DDC_Data = 0x02 << temp;
9375     SiS_Pr->SiS_DDC_Clk  = 0x01 << temp;
9376 
9377     SiS_SetupDDCN(SiS_Pr);
9378 
9379     return 0;
9380 }
9381 
9382 static unsigned short
9383 SiS_WriteDABDDC(struct SiS_Private *SiS_Pr)
9384 {
9385    if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9386    if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr)) {
9387       return 0xFFFF;
9388    }
9389    if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_SecAddr)) {
9390       return 0xFFFF;
9391    }
9392    return 0;
9393 }
9394 
9395 static unsigned short
9396 SiS_PrepareReadDDC(struct SiS_Private *SiS_Pr)
9397 {
9398    if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9399    if(SiS_WriteDDC2Data(SiS_Pr, (SiS_Pr->SiS_DDC_DeviceAddr | 0x01))) {
9400       return 0xFFFF;
9401    }
9402    return 0;
9403 }
9404 
9405 static unsigned short
9406 SiS_PrepareDDC(struct SiS_Private *SiS_Pr)
9407 {
9408    if(SiS_WriteDABDDC(SiS_Pr)) SiS_WriteDABDDC(SiS_Pr);
9409    if(SiS_PrepareReadDDC(SiS_Pr)) return (SiS_PrepareReadDDC(SiS_Pr));
9410    return 0;
9411 }
9412 
9413 static void
9414 SiS_SendACK(struct SiS_Private *SiS_Pr, unsigned short yesno)
9415 {
9416    SiS_SetSCLKLow(SiS_Pr);
9417    if(yesno) {
9418       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9419                       SiS_Pr->SiS_DDC_Index,
9420                       SiS_Pr->SiS_DDC_NData,
9421                       SiS_Pr->SiS_DDC_Data);
9422    } else {
9423       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9424                       SiS_Pr->SiS_DDC_Index,
9425                       SiS_Pr->SiS_DDC_NData,
9426                       0);
9427    }
9428    SiS_SetSCLKHigh(SiS_Pr);
9429 }
9430 
9431 static unsigned short
9432 SiS_DoProbeDDC(struct SiS_Private *SiS_Pr)
9433 {
9434     unsigned char mask, value;
9435     unsigned short  temp, ret=0;
9436     bool failed = false;
9437 
9438     SiS_SetSwitchDDC2(SiS_Pr);
9439     if(SiS_PrepareDDC(SiS_Pr)) {
9440          SiS_SetStop(SiS_Pr);
9441          return 0xFFFF;
9442     }
9443     mask = 0xf0;
9444     value = 0x20;
9445     if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9446        temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9447        SiS_SendACK(SiS_Pr, 0);
9448        if(temp == 0) {
9449            mask = 0xff;
9450            value = 0xff;
9451        } else {
9452            failed = true;
9453            ret = 0xFFFF;
9454        }
9455     }
9456     if(!failed) {
9457        temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9458        SiS_SendACK(SiS_Pr, 1);
9459        temp &= mask;
9460        if(temp == value) ret = 0;
9461        else {
9462           ret = 0xFFFF;
9463           if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9464              if(temp == 0x30) ret = 0;
9465           }
9466        }
9467     }
9468     SiS_SetStop(SiS_Pr);
9469     return ret;
9470 }
9471 
9472 static
9473 unsigned short
9474 SiS_ProbeDDC(struct SiS_Private *SiS_Pr)
9475 {
9476    unsigned short flag;
9477 
9478    flag = 0x180;
9479    SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
9480    if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x02;
9481    SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;
9482    if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x08;
9483    SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;
9484    if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x10;
9485    if(!(flag & 0x1a)) flag = 0;
9486    return flag;
9487 }
9488 
9489 static
9490 unsigned short
9491 SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype, unsigned char *buffer)
9492 {
9493    unsigned short flag, length, i;
9494    unsigned char chksum,gotcha;
9495 
9496    if(DDCdatatype > 4) return 0xFFFF;
9497 
9498    flag = 0;
9499    SiS_SetSwitchDDC2(SiS_Pr);
9500    if(!(SiS_PrepareDDC(SiS_Pr))) {
9501       length = 127;
9502       if(DDCdatatype != 1) length = 255;
9503       chksum = 0;
9504       gotcha = 0;
9505       for(i=0; i<length; i++) {
9506          buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9507          chksum += buffer[i];
9508          gotcha |= buffer[i];
9509          SiS_SendACK(SiS_Pr, 0);
9510       }
9511       buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9512       chksum += buffer[i];
9513       SiS_SendACK(SiS_Pr, 1);
9514       if(gotcha) flag = (unsigned short)chksum;
9515       else flag = 0xFFFF;
9516    } else {
9517       flag = 0xFFFF;
9518    }
9519    SiS_SetStop(SiS_Pr);
9520    return flag;
9521 }
9522 
9523 /* Our private DDC functions
9524 
9525    It complies somewhat with the corresponding VESA function
9526    in arguments and return values.
9527 
9528    Since this is probably called before the mode is changed,
9529    we use our pre-detected pSiS-values instead of SiS_Pr as
9530    regards chipset and video bridge type.
9531 
9532    Arguments:
9533        adaptnum: 0=CRT1(analog), 1=CRT2/LCD(digital), 2=CRT2/VGA2(analog)
9534                  CRT2 DDC is only supported on SiS301, 301B, 301C, 302B.
9535                  LCDA is CRT1, but DDC is read from CRT2 port.
9536        DDCdatatype: 0=Probe, 1=EDID, 2=EDID+VDIF, 3=EDID V2 (P&D), 4=EDID V2 (FPDI-2)
9537        buffer: ptr to 256 data bytes which will be filled with read data.
9538 
9539    Returns 0xFFFF if error, otherwise
9540        if DDCdatatype > 0:  Returns 0 if reading OK (included a correct checksum)
9541        if DDCdatatype = 0:  Returns supported DDC modes
9542 
9543  */
9544 unsigned short
9545 SiS_HandleDDC(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
9546               unsigned short adaptnum, unsigned short DDCdatatype, unsigned char *buffer,
9547               unsigned int VBFlags2)
9548 {
9549    unsigned char  sr1f, cr17=1;
9550    unsigned short result;
9551 
9552    if(adaptnum > 2)
9553       return 0xFFFF;
9554 
9555    if(DDCdatatype > 4)
9556       return 0xFFFF;
9557 
9558    if((!(VBFlags2 & VB2_VIDEOBRIDGE)) && (adaptnum > 0))
9559       return 0xFFFF;
9560 
9561    if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, false, VBFlags2) == 0xFFFF)
9562       return 0xFFFF;
9563 
9564    sr1f = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f);
9565    SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1f,0x3f,0x04);
9566    if(VGAEngine == SIS_300_VGA) {
9567       cr17 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80;
9568       if(!cr17) {
9569          SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x17,0x80);
9570          SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x01);
9571          SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x03);
9572       }
9573    }
9574    if((sr1f) || (!cr17)) {
9575       SiS_WaitRetrace1(SiS_Pr);
9576       SiS_WaitRetrace1(SiS_Pr);
9577       SiS_WaitRetrace1(SiS_Pr);
9578       SiS_WaitRetrace1(SiS_Pr);
9579    }
9580 
9581    if(DDCdatatype == 0) {
9582       result = SiS_ProbeDDC(SiS_Pr);
9583    } else {
9584       result = SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer);
9585       if((!result) && (DDCdatatype == 1)) {
9586          if((buffer[0] == 0x00) && (buffer[1] == 0xff) &&
9587             (buffer[2] == 0xff) && (buffer[3] == 0xff) &&
9588             (buffer[4] == 0xff) && (buffer[5] == 0xff) &&
9589             (buffer[6] == 0xff) && (buffer[7] == 0x00) &&
9590             (buffer[0x12] == 1)) {
9591             if(!SiS_Pr->DDCPortMixup) {
9592                if(adaptnum == 1) {
9593                   if(!(buffer[0x14] & 0x80)) result = 0xFFFE;
9594                } else {
9595                   if(buffer[0x14] & 0x80)    result = 0xFFFE;
9596                }
9597             }
9598          }
9599       }
9600    }
9601    SiS_SetReg(SiS_Pr->SiS_P3c4,0x1f,sr1f);
9602    if(VGAEngine == SIS_300_VGA) {
9603       SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x17,0x7f,cr17);
9604    }
9605    return result;
9606 }
9607 
9608 /* Generic I2C functions for Chrontel & DDC --------- */
9609 
9610 static void
9611 SiS_SetSwitchDDC2(struct SiS_Private *SiS_Pr)
9612 {
9613   SiS_SetSCLKHigh(SiS_Pr);
9614   SiS_WaitRetrace1(SiS_Pr);
9615 
9616   SiS_SetSCLKLow(SiS_Pr);
9617   SiS_WaitRetrace1(SiS_Pr);
9618 }
9619 
9620 unsigned short
9621 SiS_ReadDDC1Bit(struct SiS_Private *SiS_Pr)
9622 {
9623    SiS_WaitRetrace1(SiS_Pr);
9624    return ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x02) >> 1);
9625 }
9626 
9627 /* Set I2C start condition */
9628 /* This is done by a SD high-to-low transition while SC is high */
9629 static unsigned short
9630 SiS_SetStart(struct SiS_Private *SiS_Pr)
9631 {
9632   if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;                     /* (SC->low)  */
9633   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9634                   SiS_Pr->SiS_DDC_Index,
9635                   SiS_Pr->SiS_DDC_NData,
9636                   SiS_Pr->SiS_DDC_Data);                        /* SD->high */
9637   if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;                    /* SC->high */
9638   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9639                   SiS_Pr->SiS_DDC_Index,
9640                   SiS_Pr->SiS_DDC_NData,
9641                   0x00);                                        /* SD->low = start condition */
9642   if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;                    /* (SC->low) */
9643   return 0;
9644 }
9645 
9646 /* Set I2C stop condition */
9647 /* This is done by a SD low-to-high transition while SC is high */
9648 static unsigned short
9649 SiS_SetStop(struct SiS_Private *SiS_Pr)
9650 {
9651   if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;                     /* (SC->low) */
9652   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9653                   SiS_Pr->SiS_DDC_Index,
9654                   SiS_Pr->SiS_DDC_NData,
9655                   0x00);                                        /* SD->low   */
9656   if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;                    /* SC->high  */
9657   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9658                   SiS_Pr->SiS_DDC_Index,
9659                   SiS_Pr->SiS_DDC_NData,
9660                   SiS_Pr->SiS_DDC_Data);                        /* SD->high = stop condition */
9661   if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;                    /* (SC->high) */
9662   return 0;
9663 }
9664 
9665 /* Write 8 bits of data */
9666 static unsigned short
9667 SiS_WriteDDC2Data(struct SiS_Private *SiS_Pr, unsigned short tempax)
9668 {
9669   unsigned short i,flag,temp;
9670 
9671   flag = 0x80;
9672   for(i = 0; i < 8; i++) {
9673     SiS_SetSCLKLow(SiS_Pr);                                     /* SC->low */
9674     if(tempax & flag) {
9675       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9676                       SiS_Pr->SiS_DDC_Index,
9677                       SiS_Pr->SiS_DDC_NData,
9678                       SiS_Pr->SiS_DDC_Data);                    /* Write bit (1) to SD */
9679     } else {
9680       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9681                       SiS_Pr->SiS_DDC_Index,
9682                       SiS_Pr->SiS_DDC_NData,
9683                       0x00);                                    /* Write bit (0) to SD */
9684     }
9685     SiS_SetSCLKHigh(SiS_Pr);                                    /* SC->high */
9686     flag >>= 1;
9687   }
9688   temp = SiS_CheckACK(SiS_Pr);                                  /* Check acknowledge */
9689   return temp;
9690 }
9691 
9692 static unsigned short
9693 SiS_ReadDDC2Data(struct SiS_Private *SiS_Pr)
9694 {
9695   unsigned short i, temp, getdata;
9696 
9697   getdata = 0;
9698   for(i = 0; i < 8; i++) {
9699     getdata <<= 1;
9700     SiS_SetSCLKLow(SiS_Pr);
9701     SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9702                     SiS_Pr->SiS_DDC_Index,
9703                     SiS_Pr->SiS_DDC_NData,
9704                     SiS_Pr->SiS_DDC_Data);
9705     SiS_SetSCLKHigh(SiS_Pr);
9706     temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
9707     if(temp & SiS_Pr->SiS_DDC_Data) getdata |= 0x01;
9708   }
9709   return getdata;
9710 }
9711 
9712 static unsigned short
9713 SiS_SetSCLKLow(struct SiS_Private *SiS_Pr)
9714 {
9715   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9716                   SiS_Pr->SiS_DDC_Index,
9717                   SiS_Pr->SiS_DDC_NClk,
9718                   0x00);                                        /* SetSCLKLow()  */
9719   SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9720   return 0;
9721 }
9722 
9723 static unsigned short
9724 SiS_SetSCLKHigh(struct SiS_Private *SiS_Pr)
9725 {
9726   unsigned short temp, watchdog=1000;
9727 
9728   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9729                   SiS_Pr->SiS_DDC_Index,
9730                   SiS_Pr->SiS_DDC_NClk,
9731                   SiS_Pr->SiS_DDC_Clk);                         /* SetSCLKHigh()  */
9732   do {
9733     temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
9734   } while((!(temp & SiS_Pr->SiS_DDC_Clk)) && --watchdog);
9735   if (!watchdog) {
9736         return 0xFFFF;
9737   }
9738   SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9739   return 0;
9740 }
9741 
9742 /* Check I2C acknowledge */
9743 /* Returns 0 if ack ok, non-0 if ack not ok */
9744 static unsigned short
9745 SiS_CheckACK(struct SiS_Private *SiS_Pr)
9746 {
9747   unsigned short tempah;
9748 
9749   SiS_SetSCLKLow(SiS_Pr);                                          /* (SC->low) */
9750   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9751                   SiS_Pr->SiS_DDC_Index,
9752                   SiS_Pr->SiS_DDC_NData,
9753                   SiS_Pr->SiS_DDC_Data);                           /* (SD->high) */
9754   SiS_SetSCLKHigh(SiS_Pr);                                         /* SC->high = clock impulse for ack */
9755   tempah = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); /* Read SD */
9756   SiS_SetSCLKLow(SiS_Pr);                                          /* SC->low = end of clock impulse */
9757   if(tempah & SiS_Pr->SiS_DDC_Data) return 1;                      /* Ack OK if bit = 0 */
9758   return 0;
9759 }
9760 
9761 /* End of I2C functions ----------------------- */
9762 
9763 
9764 /* =============== SiS 315/330 O.E.M. ================= */
9765 
9766 #ifdef CONFIG_FB_SIS_315
9767 
9768 static unsigned short
9769 GetRAMDACromptr(struct SiS_Private *SiS_Pr)
9770 {
9771   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
9772   unsigned short romptr;
9773 
9774   if(SiS_Pr->ChipType < SIS_330) {
9775      romptr = SISGETROMW(0x128);
9776      if(SiS_Pr->SiS_VBType & VB_SIS30xB)
9777         romptr = SISGETROMW(0x12a);
9778   } else {
9779      romptr = SISGETROMW(0x1a8);
9780      if(SiS_Pr->SiS_VBType & VB_SIS30xB)
9781         romptr = SISGETROMW(0x1aa);
9782   }
9783   return romptr;
9784 }
9785 
9786 static unsigned short
9787 GetLCDromptr(struct SiS_Private *SiS_Pr)
9788 {
9789   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
9790   unsigned short romptr;
9791 
9792   if(SiS_Pr->ChipType < SIS_330) {
9793      romptr = SISGETROMW(0x120);
9794      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9795         romptr = SISGETROMW(0x122);
9796   } else {
9797      romptr = SISGETROMW(0x1a0);
9798      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9799         romptr = SISGETROMW(0x1a2);
9800   }
9801   return romptr;
9802 }
9803 
9804 static unsigned short
9805 GetTVromptr(struct SiS_Private *SiS_Pr)
9806 {
9807   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
9808   unsigned short romptr;
9809 
9810   if(SiS_Pr->ChipType < SIS_330) {
9811      romptr = SISGETROMW(0x114);
9812      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9813         romptr = SISGETROMW(0x11a);
9814   } else {
9815      romptr = SISGETROMW(0x194);
9816      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9817         romptr = SISGETROMW(0x19a);
9818   }
9819   return romptr;
9820 }
9821 
9822 static unsigned short
9823 GetLCDPtrIndexBIOS(struct SiS_Private *SiS_Pr)
9824 {
9825   unsigned short index;
9826 
9827   if((IS_SIS650) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
9828      if(!(SiS_IsNotM650orLater(SiS_Pr))) {
9829         if((index = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0)) {
9830            index >>= 4;
9831            index *= 3;
9832            if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9833            else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9834            return index;
9835         }
9836      }
9837   }
9838 
9839   index = SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F;
9840   if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)      index -= 5;
9841   if(SiS_Pr->SiS_VBType & VB_SIS301C) {  /* 1.15.20 and later (not VB specific) */
9842      if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 5;
9843      if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768) index -= 5;
9844   } else {
9845      if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 6;
9846   }
9847   index--;
9848   index *= 3;
9849   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9850   else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9851   return index;
9852 }
9853 
9854 static unsigned short
9855 GetLCDPtrIndex(struct SiS_Private *SiS_Pr)
9856 {
9857   unsigned short index;
9858 
9859   index = ((SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F) - 1) * 3;
9860   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)         index += 2;
9861   else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9862   return index;
9863 }
9864 
9865 static unsigned short
9866 GetTVPtrIndex(struct SiS_Private *SiS_Pr)
9867 {
9868   unsigned short index;
9869 
9870   index = 0;
9871   if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
9872   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index = 2;
9873 
9874   if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) index = 0;
9875 
9876   index <<= 1;
9877 
9878   if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) &&
9879      (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
9880      index++;
9881   }
9882 
9883   return index;
9884 }
9885 
9886 static unsigned int
9887 GetOEMTVPtr661_2_GEN(struct SiS_Private *SiS_Pr, int addme)
9888 {
9889    unsigned short index = 0, temp = 0;
9890 
9891    if(SiS_Pr->SiS_TVMode & TVSetPAL)   index = 1;
9892    if(SiS_Pr->SiS_TVMode & TVSetPALM)  index = 2;
9893    if(SiS_Pr->SiS_TVMode & TVSetPALN)  index = 3;
9894    if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 6;
9895    if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
9896       index = 4;
9897       if(SiS_Pr->SiS_TVMode & TVSetPALM)  index++;
9898       if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 7;
9899    }
9900 
9901    if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
9902       if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
9903          (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
9904          index += addme;
9905          temp++;
9906       }
9907       temp += 0x0100;
9908    }
9909    return (unsigned int)(index | (temp << 16));
9910 }
9911 
9912 static unsigned int
9913 GetOEMTVPtr661_2_OLD(struct SiS_Private *SiS_Pr)
9914 {
9915    return (GetOEMTVPtr661_2_GEN(SiS_Pr, 8));
9916 }
9917 
9918 #if 0
9919 static unsigned int
9920 GetOEMTVPtr661_2_NEW(struct SiS_Private *SiS_Pr)
9921 {
9922    return (GetOEMTVPtr661_2_GEN(SiS_Pr, 6));
9923 }
9924 #endif
9925 
9926 static int
9927 GetOEMTVPtr661(struct SiS_Private *SiS_Pr)
9928 {
9929    int index = 0;
9930 
9931    if(SiS_Pr->SiS_TVMode & TVSetPAL)          index = 2;
9932    if(SiS_Pr->SiS_ROMNew) {
9933       if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 4;
9934       if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 6;
9935       if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 8;
9936       if(SiS_Pr->SiS_TVMode & TVSetHiVision)  index = 10;
9937    } else {
9938       if(SiS_Pr->SiS_TVMode & TVSetHiVision)  index = 4;
9939       if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 6;
9940       if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 8;
9941       if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 10;
9942    }
9943 
9944    if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) index++;
9945 
9946    return index;
9947 }
9948 
9949 static void
9950 SetDelayComp(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
9951 {
9952   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
9953   unsigned short delay=0,index,myindex,temp,romptr=0;
9954   bool dochiptest = true;
9955 
9956   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
9957      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x20,0xbf);
9958   } else {
9959      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x35,0x7f);
9960   }
9961 
9962   /* Find delay (from ROM, internal tables, PCI subsystem) */
9963 
9964   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {                    /* ------------ VGA */
9965 
9966      if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
9967         romptr = GetRAMDACromptr(SiS_Pr);
9968      }
9969      if(romptr) delay = ROMAddr[romptr];
9970      else {
9971         delay = 0x04;
9972         if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
9973            if(IS_SIS650) {
9974               delay = 0x0a;
9975            } else if(IS_SIS740) {
9976               delay = 0x00;
9977            } else {
9978               delay = 0x0c;
9979            }
9980         } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
9981            delay = 0x00;
9982         }
9983      }
9984 
9985   } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD|SetCRT2ToLCDA)) {  /* ---------- LCD/LCDA */
9986 
9987      bool gotitfrompci = false;
9988 
9989      /* Could we detect a PDC for LCD or did we get a user-defined? If yes, use it */
9990 
9991      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
9992         if(SiS_Pr->PDC != -1) {
9993            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((SiS_Pr->PDC >> 1) & 0x0f));
9994            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((SiS_Pr->PDC & 0x01) << 7));
9995            return;
9996         }
9997      } else {
9998         if(SiS_Pr->PDCA != -1) {
9999            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((SiS_Pr->PDCA << 3) & 0xf0));
10000            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((SiS_Pr->PDCA & 0x01) << 6));
10001            return;
10002         }
10003      }
10004 
10005      /* Custom Panel? */
10006 
10007      if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) {
10008         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10009            delay = 0x00;
10010            if((SiS_Pr->PanelXRes <= 1280) && (SiS_Pr->PanelYRes <= 1024)) {
10011               delay = 0x20;
10012            }
10013            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,delay);
10014         } else {
10015            delay = 0x0c;
10016            if(SiS_Pr->SiS_VBType & VB_SIS301C) {
10017               delay = 0x03;
10018               if((SiS_Pr->PanelXRes > 1280) && (SiS_Pr->PanelYRes > 1024)) {
10019                  delay = 0x00;
10020               }
10021            } else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10022               if(IS_SIS740) delay = 0x01;
10023               else          delay = 0x03;
10024            }
10025            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,delay);
10026         }
10027         return;
10028      }
10029 
10030      /* This is a piece of typical SiS crap: They code the OEM LCD
10031       * delay into the code, at no defined place in the BIOS.
10032       * We now have to start doing a PCI subsystem check here.
10033       */
10034 
10035      switch(SiS_Pr->SiS_CustomT) {
10036      case CUT_COMPAQ1280:
10037      case CUT_COMPAQ12802:
10038         if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
10039            gotitfrompci = true;
10040            dochiptest = false;
10041            delay = 0x03;
10042         }
10043         break;
10044      case CUT_CLEVO1400:
10045      case CUT_CLEVO14002:
10046         gotitfrompci = true;
10047         dochiptest = false;
10048         delay = 0x02;
10049         break;
10050      case CUT_CLEVO1024:
10051      case CUT_CLEVO10242:
10052         if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10053            gotitfrompci = true;
10054            dochiptest = false;
10055            delay = 0x33;
10056            SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
10057            delay &= 0x0f;
10058         }
10059         break;
10060      }
10061 
10062      /* Could we find it through the PCI ID? If no, use ROM or table */
10063 
10064      if(!gotitfrompci) {
10065 
10066         index = GetLCDPtrIndexBIOS(SiS_Pr);
10067         myindex = GetLCDPtrIndex(SiS_Pr);
10068 
10069         if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
10070 
10071            if(SiS_IsNotM650orLater(SiS_Pr)) {
10072 
10073               if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10074                  /* Always use the second pointer on 650; some BIOSes */
10075                  /* still carry old 301 data at the first location    */
10076                  /* romptr = SISGETROMW(0x120);                       */
10077                  /* if(SiS_Pr->SiS_VBType & VB_SIS302LV)              */
10078                  romptr = SISGETROMW(0x122);
10079                  if(!romptr) return;
10080                  delay = ROMAddr[(romptr + index)];
10081               } else {
10082                  delay = SiS310_LCDDelayCompensation_650301LV[myindex];
10083               }
10084 
10085           } else {
10086 
10087              delay = SiS310_LCDDelayCompensation_651301LV[myindex];
10088              if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV))
10089                 delay = SiS310_LCDDelayCompensation_651302LV[myindex];
10090 
10091           }
10092 
10093         } else if(SiS_Pr->SiS_UseROM                          &&
10094                   (!(SiS_Pr->SiS_ROMNew))                     &&
10095                   (SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) &&
10096                   (SiS_Pr->SiS_LCDResInfo != Panel_1280x768)  &&
10097                   (SiS_Pr->SiS_LCDResInfo != Panel_1280x960)  &&
10098                   (SiS_Pr->SiS_LCDResInfo != Panel_1600x1200)  &&
10099                   ((romptr = GetLCDromptr(SiS_Pr)))) {
10100 
10101            /* Data for 1280x1024 wrong in 301B BIOS */
10102            /* Data for 1600x1200 wrong in 301C BIOS */
10103            delay = ROMAddr[(romptr + index)];
10104 
10105         } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
10106 
10107            if(IS_SIS740) delay = 0x03;
10108            else          delay = 0x00;
10109 
10110         } else {
10111 
10112            delay = SiS310_LCDDelayCompensation_301[myindex];
10113            if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10114               if(IS_SIS740) delay = 0x01;
10115               else if(SiS_Pr->ChipType <= SIS_315PRO) delay = SiS310_LCDDelayCompensation_3xx301LV[myindex];
10116               else          delay = SiS310_LCDDelayCompensation_650301LV[myindex];
10117            } else if(SiS_Pr->SiS_VBType & VB_SIS301C) {
10118               if(IS_SIS740) delay = 0x01;  /* ? */
10119               else          delay = 0x03;
10120               if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) delay = 0x00; /* experience */
10121            } else if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
10122               if(IS_SIS740) delay = 0x01;
10123               else          delay = SiS310_LCDDelayCompensation_3xx301B[myindex];
10124            }
10125 
10126         }
10127 
10128      }  /* got it from PCI */
10129 
10130      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10131         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,((delay << 4) & 0xf0));
10132         dochiptest = false;
10133      }
10134 
10135   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {                 /* ------------ TV */
10136 
10137      index = GetTVPtrIndex(SiS_Pr);
10138 
10139      if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
10140 
10141         if(SiS_IsNotM650orLater(SiS_Pr)) {
10142 
10143            if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10144               /* Always use the second pointer on 650; some BIOSes */
10145               /* still carry old 301 data at the first location    */
10146               /* romptr = SISGETROMW(0x114);                       */
10147               /* if(SiS_Pr->SiS_VBType & VB_SIS302LV)              */
10148               romptr = SISGETROMW(0x11a);
10149               if(!romptr) return;
10150               delay = ROMAddr[romptr + index];
10151 
10152            } else {
10153 
10154               delay = SiS310_TVDelayCompensation_301B[index];
10155 
10156            }
10157 
10158         } else {
10159 
10160            switch(SiS_Pr->SiS_CustomT) {
10161            case CUT_COMPAQ1280:
10162            case CUT_COMPAQ12802:
10163            case CUT_CLEVO1400:
10164            case CUT_CLEVO14002:
10165               delay = 0x02;
10166               dochiptest = false;
10167               break;
10168            case CUT_CLEVO1024:
10169            case CUT_CLEVO10242:
10170               delay = 0x03;
10171               dochiptest = false;
10172               break;
10173            default:
10174               delay = SiS310_TVDelayCompensation_651301LV[index];
10175               if(SiS_Pr->SiS_VBType & VB_SIS302LV) {
10176                  delay = SiS310_TVDelayCompensation_651302LV[index];
10177               }
10178            }
10179         }
10180 
10181      } else if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10182 
10183         romptr = GetTVromptr(SiS_Pr);
10184         if(!romptr) return;
10185         delay = ROMAddr[romptr + index];
10186 
10187      } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
10188 
10189         delay = SiS310_TVDelayCompensation_LVDS[index];
10190 
10191      } else {
10192 
10193         delay = SiS310_TVDelayCompensation_301[index];
10194         if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10195            if(IS_SIS740) {
10196               delay = SiS310_TVDelayCompensation_740301B[index];
10197               /* LV: use 301 data? BIOS bug? */
10198            } else {
10199               delay = SiS310_TVDelayCompensation_301B[index];
10200               if(SiS_Pr->SiS_VBType & VB_SIS301C) delay = 0x02;
10201            }
10202         }
10203 
10204      }
10205 
10206      if(SiS_LCDAEnabled(SiS_Pr)) {
10207         delay &= 0x0f;
10208         dochiptest = false;
10209      }
10210 
10211   } else return;
10212 
10213   /* Write delay */
10214 
10215   if(SiS_Pr->SiS_VBType & VB_SISVB) {
10216 
10217      if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS) && dochiptest) {
10218 
10219         temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0) >> 4;
10220         if(temp == 8) {         /* 1400x1050 BIOS (COMPAL) */
10221            delay &= 0x0f;
10222            delay |= 0xb0;
10223         } else if(temp == 6) {
10224            delay &= 0x0f;
10225            delay |= 0xc0;
10226         } else if(temp > 7) {   /* 1280x1024 BIOS (which one?) */
10227            delay = 0x35;
10228         }
10229         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
10230 
10231      } else {
10232 
10233         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
10234 
10235      }
10236 
10237   } else {  /* LVDS */
10238 
10239      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10240         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
10241      } else {
10242         if(IS_SIS650 && (SiS_Pr->SiS_IF_DEF_CH70xx != 0)) {
10243            delay <<= 4;
10244            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,delay);
10245         } else {
10246            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
10247         }
10248      }
10249 
10250   }
10251 
10252 }
10253 
10254 static void
10255 SetAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10256 {
10257   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
10258   unsigned short index,temp,temp1,romptr=0;
10259 
10260   if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p|TVSetYPbPr525p)) return;
10261 
10262   if(ModeNo<=0x13)
10263      index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex;
10264   else
10265      index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex;
10266 
10267   temp = GetTVPtrIndex(SiS_Pr);
10268   temp >>= 1;     /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10269   temp1 = temp;
10270 
10271   if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
10272      if(SiS_Pr->ChipType >= SIS_661) {
10273         temp1 = GetOEMTVPtr661(SiS_Pr);
10274         temp1 >>= 1;
10275         romptr = SISGETROMW(0x260);
10276         if(SiS_Pr->ChipType >= SIS_760) {
10277            romptr = SISGETROMW(0x360);
10278         }
10279      } else if(SiS_Pr->ChipType >= SIS_330) {
10280         romptr = SISGETROMW(0x192);
10281      } else {
10282         romptr = SISGETROMW(0x112);
10283      }
10284   }
10285 
10286   if(romptr) {
10287      temp1 <<= 1;
10288      temp = ROMAddr[romptr + temp1 + index];
10289   } else {
10290      temp = SiS310_TVAntiFlick1[temp][index];
10291   }
10292   temp <<= 4;
10293 
10294   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8f,temp);  /* index 0A D[6:4] */
10295 }
10296 
10297 static void
10298 SetEdgeEnhance(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10299 {
10300   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
10301   unsigned short index,temp,temp1,romptr=0;
10302 
10303   temp = temp1 = GetTVPtrIndex(SiS_Pr) >> 1;    /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10304 
10305   if(ModeNo <= 0x13)
10306      index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;
10307   else
10308      index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;
10309 
10310   if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
10311      if(SiS_Pr->ChipType >= SIS_661) {
10312         romptr = SISGETROMW(0x26c);
10313         if(SiS_Pr->ChipType >= SIS_760) {
10314            romptr = SISGETROMW(0x36c);
10315         }
10316         temp1 = GetOEMTVPtr661(SiS_Pr);
10317         temp1 >>= 1;
10318      } else if(SiS_Pr->ChipType >= SIS_330) {
10319         romptr = SISGETROMW(0x1a4);
10320      } else {
10321         romptr = SISGETROMW(0x124);
10322      }
10323   }
10324 
10325   if(romptr) {
10326      temp1 <<= 1;
10327      temp = ROMAddr[romptr + temp1 + index];
10328   } else {
10329      temp = SiS310_TVEdge1[temp][index];
10330   }
10331   temp <<= 5;
10332   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x3A,0x1F,temp);  /* index 0A D[7:5] */
10333 }
10334 
10335 static void
10336 SetYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10337 {
10338   unsigned short index, temp, i, j;
10339 
10340   if(ModeNo <= 0x13) {
10341      index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
10342   } else {
10343      index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
10344   }
10345 
10346   temp = GetTVPtrIndex(SiS_Pr) >> 1;  /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10347 
10348   if(SiS_Pr->SiS_TVMode & TVSetNTSCJ)        temp = 1;  /* NTSC-J uses PAL */
10349   else if(SiS_Pr->SiS_TVMode & TVSetPALM)    temp = 3;  /* PAL-M */
10350   else if(SiS_Pr->SiS_TVMode & TVSetPALN)    temp = 4;  /* PAL-N */
10351   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp = 1;  /* HiVision uses PAL */
10352 
10353   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10354      for(i=0x35, j=0; i<=0x38; i++, j++) {
10355         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
10356      }
10357      for(i=0x48; i<=0x4A; i++, j++) {
10358         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
10359      }
10360   } else {
10361      for(i=0x35, j=0; i<=0x38; i++, j++) {
10362         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter1[temp][index][j]);
10363      }
10364   }
10365 }
10366 
10367 static void
10368 SetPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10369 {
10370   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
10371   unsigned short index,temp,i,j,resinfo,romptr=0;
10372   unsigned int  lindex;
10373 
10374   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
10375 
10376   /* NTSC-J data not in BIOS, and already set in SetGroup2 */
10377   if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) return;
10378 
10379   if((SiS_Pr->ChipType >= SIS_661) || SiS_Pr->SiS_ROMNew) {
10380      lindex = GetOEMTVPtr661_2_OLD(SiS_Pr) & 0xffff;
10381      lindex <<= 2;
10382      for(j=0, i=0x31; i<=0x34; i++, j++) {
10383         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[lindex + j]);
10384      }
10385      return;
10386   }
10387 
10388   /* PAL-M, PAL-N not in BIOS, and already set in SetGroup2 */
10389   if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) return;
10390 
10391   if(ModeNo<=0x13) {
10392      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
10393   } else {
10394      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
10395   }
10396 
10397   temp = GetTVPtrIndex(SiS_Pr);
10398   /* 0: NTSC Graphics, 1: NTSC Text,    2: PAL Graphics,
10399    * 3: PAL Text,      4: HiTV Graphics 5: HiTV Text
10400    */
10401   if(SiS_Pr->SiS_UseROM) {
10402      romptr = SISGETROMW(0x116);
10403      if(SiS_Pr->ChipType >= SIS_330) {
10404         romptr = SISGETROMW(0x196);
10405      }
10406      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10407         romptr = SISGETROMW(0x11c);
10408         if(SiS_Pr->ChipType >= SIS_330) {
10409            romptr = SISGETROMW(0x19c);
10410         }
10411         if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode))) {
10412            romptr = SISGETROMW(0x116);
10413            if(SiS_Pr->ChipType >= SIS_330) {
10414               romptr = SISGETROMW(0x196);
10415            }
10416         }
10417      }
10418   }
10419   if(romptr) {
10420      romptr += (temp << 2);
10421      for(j=0, i=0x31; i<=0x34; i++, j++) {
10422         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
10423      }
10424   } else {
10425      index = temp % 2;
10426      temp >>= 1;          /* 0:NTSC, 1:PAL, 2:HiTV */
10427      for(j=0, i=0x31; i<=0x34; i++, j++) {
10428         if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV))
10429            SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
10430         else if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || (SiS_Pr->SiS_TVMode & TVSetTVSimuMode))
10431            SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr2[temp][index][j]);
10432         else
10433            SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
10434      }
10435   }
10436 
10437   if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision))) {
10438      if((!(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetYPbPr525p | TVSetYPbPr750p))) && (ModeNo > 0x13)) {
10439         if((resinfo == SIS_RI_640x480) ||
10440            (resinfo == SIS_RI_800x600)) {
10441            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x21);
10442            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0xf0);
10443            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xf5);
10444            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7f);
10445         } else if(resinfo == SIS_RI_1024x768) {
10446            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x1e);
10447            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0x8b);
10448            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xfb);
10449            SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7b);
10450         }
10451      }
10452   }
10453 }
10454 
10455 static void
10456 SetDelayComp661(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
10457                 unsigned short ModeIdIndex, unsigned short RTI)
10458 {
10459    unsigned short delay = 0, romptr = 0, index, lcdpdcindex;
10460    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
10461 
10462    if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToRAMDAC)))
10463       return;
10464 
10465    /* 1. New ROM: VGA2 and LCD/LCDA-Pass1:1 */
10466    /* (If a custom mode is used, Pass1:1 is always set; hence we do this:) */
10467 
10468    if(SiS_Pr->SiS_ROMNew) {
10469       if((SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)                         ||
10470          ((SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
10471           (SiS_Pr->SiS_LCDInfo & LCDPass11))) {
10472          index = 25;
10473          if(SiS_Pr->UseCustomMode) {
10474             index = SiS_Pr->CSRClock;
10475          } else if(ModeNo > 0x13) {
10476             index = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RTI);
10477             index = SiS_Pr->SiS_VCLKData[index].CLOCK;
10478          }
10479          if(index < 25) index = 25;
10480          index = ((index / 25) - 1) << 1;
10481          if((ROMAddr[0x5b] & 0x80) || (SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD))) {
10482             index++;
10483          }
10484          romptr = SISGETROMW(0x104);
10485          delay = ROMAddr[romptr + index];
10486          if(SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD)) {
10487             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
10488             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
10489          } else {
10490             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
10491             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
10492          }
10493          return;
10494       }
10495    }
10496 
10497    /* 2. Old ROM: VGA2 and LCD/LCDA-Pass 1:1 */
10498 
10499    if(SiS_Pr->UseCustomMode) delay = 0x04;
10500    else if(ModeNo <= 0x13)   delay = 0x04;
10501    else                      delay = (SiS_Pr->SiS_RefIndex[RTI].Ext_PDC >> 4);
10502    delay |= (delay << 8);
10503 
10504    if(SiS_Pr->ChipType >= XGI_20) {
10505 
10506       delay = 0x0606;
10507       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10508 
10509          delay = 0x0404;
10510          if(SiS_Pr->SiS_XGIROM) {
10511              index = GetTVPtrIndex(SiS_Pr);
10512              if((romptr = SISGETROMW(0x35e))) {
10513                 delay = (ROMAddr[romptr + index] & 0x0f) << 1;
10514                 delay |= (delay << 8);
10515              }
10516          }
10517 
10518          if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
10519             if(SiS_Pr->ChipType == XGI_40 && SiS_Pr->ChipRevision == 0x02) {
10520                delay -= 0x0404;
10521             }
10522          }
10523       }
10524 
10525    } else if(SiS_Pr->ChipType >= SIS_340) {
10526 
10527       delay = 0x0606;
10528       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10529          delay = 0x0404;
10530       }
10531       /* TODO (eventually) */
10532 
10533    } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10534 
10535       /* 3. TV */
10536 
10537       index = GetOEMTVPtr661(SiS_Pr);
10538       if(SiS_Pr->SiS_ROMNew) {
10539          romptr = SISGETROMW(0x106);
10540          if(SiS_Pr->SiS_VBType & VB_UMC) romptr += 12;
10541          delay = ROMAddr[romptr + index];
10542       } else {
10543          delay = 0x04;
10544          if(index > 3) delay = 0;
10545       }
10546 
10547    } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10548 
10549       /* 4. LCD, LCDA (for new ROM only LV and non-Pass 1:1) */
10550 
10551       if( (SiS_Pr->SiS_LCDResInfo != Panel_Custom) &&
10552           ((romptr = GetLCDStructPtr661_2(SiS_Pr))) ) {
10553 
10554          lcdpdcindex = (SiS_Pr->SiS_VBType & VB_UMC) ? 14 : 12;
10555 
10556          /* For LVDS (and sometimes TMDS), the BIOS must know about the correct value */
10557          delay = ROMAddr[romptr + lcdpdcindex + 1];     /* LCD  */
10558          delay |= (ROMAddr[romptr + lcdpdcindex] << 8); /* LCDA */
10559 
10560       } else {
10561 
10562          /* TMDS: Set our own, since BIOS has no idea */
10563          /* (This is done on >=661 only, since <661 is calling this only for LVDS) */
10564          if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
10565             switch(SiS_Pr->SiS_LCDResInfo) {
10566             case Panel_1024x768:  delay = 0x0008; break;
10567             case Panel_1280x720:  delay = 0x0004; break;
10568             case Panel_1280x768:
10569             case Panel_1280x768_2:delay = 0x0004; break;
10570             case Panel_1280x800:
10571             case Panel_1280x800_2:delay = 0x0004; break; /* Verified for 1280x800 */
10572             case Panel_1280x854:  delay = 0x0004; break; /* FIXME */
10573             case Panel_1280x1024: delay = 0x1e04; break;
10574             case Panel_1400x1050: delay = 0x0004; break;
10575             case Panel_1600x1200: delay = 0x0400; break;
10576             case Panel_1680x1050: delay = 0x0e04; break;
10577             default:
10578                if((SiS_Pr->PanelXRes <= 1024) && (SiS_Pr->PanelYRes <= 768)) {
10579                   delay = 0x0008;
10580                } else if((SiS_Pr->PanelXRes == 1280) && (SiS_Pr->PanelYRes == 1024)) {
10581                   delay = 0x1e04;
10582                } else if((SiS_Pr->PanelXRes <= 1400) && (SiS_Pr->PanelYRes <= 1050)) {
10583                   delay = 0x0004;
10584                } else if((SiS_Pr->PanelXRes <= 1600) && (SiS_Pr->PanelYRes <= 1200)) {
10585                   delay = 0x0400;
10586                } else
10587                   delay = 0x0e04;
10588                break;
10589             }
10590          }
10591 
10592          /* Override by detected or user-set values */
10593          /* (but only if, for some reason, we can't read value from BIOS) */
10594          if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->PDC != -1)) {
10595             delay = SiS_Pr->PDC & 0x1f;
10596          }
10597          if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) && (SiS_Pr->PDCA != -1)) {
10598             delay = (SiS_Pr->PDCA & 0x1f) << 8;
10599          }
10600 
10601       }
10602 
10603    }
10604 
10605    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10606       delay >>= 8;
10607       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
10608       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
10609    } else {
10610       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
10611       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
10612    }
10613 }
10614 
10615 static void
10616 SetCRT2SyncDither661(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RTI)
10617 {
10618    unsigned short infoflag;
10619    unsigned char  temp;
10620 
10621    if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10622 
10623       if(ModeNo <= 0x13) {
10624          infoflag = SiS_GetRegByte(SiS_Pr->SiS_P3ca+2);
10625       } else if(SiS_Pr->UseCustomMode) {
10626          infoflag = SiS_Pr->CInfoFlag;
10627       } else {
10628          infoflag = SiS_Pr->SiS_RefIndex[RTI].Ext_InfoFlag;
10629       }
10630 
10631       if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
10632          infoflag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37); /* No longer check D5 */
10633       }
10634 
10635       infoflag &= 0xc0;
10636 
10637       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
10638          temp = (infoflag >> 6) | 0x0c;
10639          if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
10640             temp ^= 0x04;
10641             if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x10;
10642          }
10643          SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xe0,temp);
10644       } else {
10645          temp = 0x30;
10646          if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) temp = 0x20;
10647          temp |= infoflag;
10648          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0f,temp);
10649          temp = 0;
10650          if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
10651             if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x80;
10652          }
10653          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0x7f,temp);
10654       }
10655 
10656    }
10657 }
10658 
10659 static void
10660 SetPanelParms661(struct SiS_Private *SiS_Pr)
10661 {
10662    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
10663    unsigned short romptr, temp1, temp2;
10664 
10665    if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_SIS30xC)) {
10666       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x24,0x0f);
10667    }
10668 
10669    if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10670       if(SiS_Pr->LVDSHL != -1) {
10671          SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
10672       }
10673    }
10674 
10675    if(SiS_Pr->SiS_ROMNew) {
10676 
10677       if((romptr = GetLCDStructPtr661_2(SiS_Pr))) {
10678          if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10679             temp1 = (ROMAddr[romptr] & 0x03) | 0x0c;
10680             temp2 = 0xfc;
10681             if(SiS_Pr->LVDSHL != -1) {
10682               temp1 &= 0xfc;
10683               temp2 = 0xf3;
10684             }
10685             SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,temp2,temp1);
10686          }
10687          if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
10688             temp1 = (ROMAddr[romptr + 1] & 0x80) >> 1;
10689             SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0d,0xbf,temp1);
10690          }
10691       }
10692 
10693    }
10694 }
10695 
10696 static void
10697 SiS_OEM310Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RRTI)
10698 {
10699    if((SiS_Pr->SiS_ROMNew) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
10700       SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
10701       if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10702          SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI);
10703          SetPanelParms661(SiS_Pr);
10704       }
10705    } else {
10706       SetDelayComp(SiS_Pr,ModeNo);
10707    }
10708 
10709    if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
10710       SetAntiFlicker(SiS_Pr,ModeNo,ModeIdIndex);
10711       SetPhaseIncr(SiS_Pr,ModeNo,ModeIdIndex);
10712       SetYFilter(SiS_Pr,ModeNo,ModeIdIndex);
10713       if(SiS_Pr->SiS_VBType & VB_SIS301) {
10714          SetEdgeEnhance(SiS_Pr,ModeNo,ModeIdIndex);
10715       }
10716    }
10717 }
10718 
10719 static void
10720 SiS_OEM661Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
10721                         unsigned short ModeIdIndex, unsigned short RRTI)
10722 {
10723    if(SiS_Pr->SiS_VBType & VB_SISVB) {
10724 
10725       SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
10726 
10727       if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10728          SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI);
10729          SetPanelParms661(SiS_Pr);
10730       }
10731 
10732       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10733          SetPhaseIncr(SiS_Pr, ModeNo, ModeIdIndex);
10734          SetYFilter(SiS_Pr, ModeNo, ModeIdIndex);
10735          SetAntiFlicker(SiS_Pr, ModeNo, ModeIdIndex);
10736          if(SiS_Pr->SiS_VBType & VB_SIS301) {
10737             SetEdgeEnhance(SiS_Pr, ModeNo, ModeIdIndex);
10738          }
10739       }
10740    }
10741 }
10742 
10743 /* FinalizeLCD
10744  * This finalizes some CRT2 registers for the very panel used.
10745  * If we have a backup if these registers, we use it; otherwise
10746  * we set the register according to most BIOSes. However, this
10747  * function looks quite different in every BIOS, so you better
10748  * pray that we have a backup...
10749  */
10750 static void
10751 SiS_FinalizeLCD(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10752 {
10753   unsigned short tempcl,tempch,tempbl,tempbh,tempbx,tempax,temp;
10754   unsigned short resinfo,modeflag;
10755 
10756   if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) return;
10757   if(SiS_Pr->SiS_ROMNew) return;
10758 
10759   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10760      if(SiS_Pr->LVDSHL != -1) {
10761         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
10762      }
10763   }
10764 
10765   if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
10766   if(SiS_Pr->UseCustomMode) return;
10767 
10768   switch(SiS_Pr->SiS_CustomT) {
10769   case CUT_COMPAQ1280:
10770   case CUT_COMPAQ12802:
10771   case CUT_CLEVO1400:
10772   case CUT_CLEVO14002:
10773      return;
10774   }
10775 
10776   if(ModeNo <= 0x13) {
10777      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
10778      modeflag =  SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
10779   } else {
10780      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
10781      modeflag =  SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
10782   }
10783 
10784   if(IS_SIS650) {
10785      if(!(SiS_GetReg(SiS_Pr->SiS_P3d4, 0x5f) & 0xf0)) {
10786         if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
10787            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x02);
10788         } else {
10789            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
10790         }
10791      }
10792   }
10793 
10794   if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
10795      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10796         /* Maybe all panels? */
10797         if(SiS_Pr->LVDSHL == -1) {
10798            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10799         }
10800         return;
10801      }
10802   }
10803 
10804   if(SiS_Pr->SiS_CustomT == CUT_CLEVO10242) {
10805      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10806         if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10807            if(SiS_Pr->LVDSHL == -1) {
10808               /* Maybe all panels? */
10809               SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10810            }
10811            if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10812               tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
10813               if(tempch == 3) {
10814                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10815                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
10816                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
10817                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
10818               }
10819            }
10820            return;
10821         }
10822      }
10823   }
10824 
10825   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10826      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10827         if(SiS_Pr->SiS_VBType & VB_SISEMI) {
10828            SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
10829 #ifdef SET_EMI
10830            SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
10831 #endif
10832            SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
10833         }
10834      } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
10835         if(SiS_Pr->LVDSHL == -1) {
10836            /* Maybe ACER only? */
10837            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10838         }
10839      }
10840      tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
10841      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10842         if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
10843            SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1f,0x76);
10844         } else if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10845            if(tempch == 0x03) {
10846               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10847               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
10848               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
10849               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
10850            }
10851            if(SiS_Pr->Backup && (SiS_Pr->Backup_Mode == ModeNo)) {
10852               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,SiS_Pr->Backup_14);
10853               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,SiS_Pr->Backup_15);
10854               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,SiS_Pr->Backup_16);
10855               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,SiS_Pr->Backup_17);
10856               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,SiS_Pr->Backup_18);
10857               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,SiS_Pr->Backup_19);
10858               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,SiS_Pr->Backup_1a);
10859               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,SiS_Pr->Backup_1b);
10860               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,SiS_Pr->Backup_1c);
10861               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,SiS_Pr->Backup_1d);
10862            } else if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {  /* 1.10.8w */
10863               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x90);
10864               if(ModeNo <= 0x13) {
10865                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x11);
10866                  if((resinfo == 0) || (resinfo == 2)) return;
10867                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x18);
10868                  if((resinfo == 1) || (resinfo == 3)) return;
10869               }
10870               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10871               if((ModeNo > 0x13) && (resinfo == SIS_RI_1024x768)) {
10872                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);  /* 1.10.7u */
10873 #if 0
10874                  tempbx = 806;  /* 0x326 */                      /* other older BIOSes */
10875                  tempbx--;
10876                  temp = tempbx & 0xff;
10877                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);
10878                  temp = (tempbx >> 8) & 0x03;
10879                  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1d,0xf8,temp);
10880 #endif
10881               }
10882            } else if(ModeNo <= 0x13) {
10883               if(ModeNo <= 1) {
10884                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x70);
10885                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xff);
10886                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
10887                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
10888               }
10889               if(!(modeflag & HalfDCLK)) {
10890                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x20);
10891                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,0x1a);
10892                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,0x28);
10893                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,0x00);
10894                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x4c);
10895                  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
10896                  if(ModeNo == 0x12) {
10897                     switch(tempch) {
10898                        case 0:
10899                           SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
10900                           SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
10901                           SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,0x10);
10902                           SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
10903                           SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x48);
10904                           SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
10905                           break;
10906                        case 2:
10907                           SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
10908                           SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
10909                           break;
10910                        case 3:
10911                           SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
10912                           break;
10913                     }
10914                  }
10915               }
10916            }
10917         }
10918      } else {
10919         tempcl = tempbh = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
10920         tempcl &= 0x0f;
10921         tempbh &= 0x70;
10922         tempbh >>= 4;
10923         tempbl = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x04);
10924         tempbx = (tempbh << 8) | tempbl;
10925         if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10926            if((resinfo == SIS_RI_1024x768) || (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD))) {
10927               if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
10928                  tempbx = 770;
10929               } else {
10930                  if(tempbx > 770) tempbx = 770;
10931                  if(SiS_Pr->SiS_VGAVDE < 600) {
10932                     tempax = 768 - SiS_Pr->SiS_VGAVDE;
10933                     tempax >>= 4;                                /* 1.10.7w; 1.10.6s: 3;  */
10934                     if(SiS_Pr->SiS_VGAVDE <= 480)  tempax >>= 4; /* 1.10.7w; 1.10.6s: < 480; >>=1; */
10935                     tempbx -= tempax;
10936                  }
10937               }
10938            } else return;
10939         }
10940         temp = tempbx & 0xff;
10941         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,temp);
10942         temp = ((tempbx & 0xff00) >> 4) | tempcl;
10943         SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,temp);
10944      }
10945   }
10946 }
10947 
10948 #endif
10949 
10950 /*  =================  SiS 300 O.E.M. ================== */
10951 
10952 #ifdef CONFIG_FB_SIS_300
10953 
10954 static void
10955 SetOEMLCDData2(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,
10956                 unsigned short RefTabIndex)
10957 {
10958   unsigned short crt2crtc=0, modeflag, myindex=0;
10959   unsigned char  temp;
10960   int i;
10961 
10962   if(ModeNo <= 0x13) {
10963      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
10964      crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
10965   } else {
10966      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
10967      crt2crtc = SiS_Pr->SiS_RefIndex[RefTabIndex].Ext_CRT2CRTC;
10968   }
10969 
10970   crt2crtc &= 0x3f;
10971 
10972   if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
10973      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xdf);
10974   }
10975 
10976   if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
10977      if(modeflag & HalfDCLK) myindex = 1;
10978 
10979      if(SiS_Pr->SiS_SetFlag & LowModeTests) {
10980         for(i=0; i<7; i++) {
10981            if(barco_p1[myindex][crt2crtc][i][0]) {
10982               SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,
10983                               barco_p1[myindex][crt2crtc][i][0],
10984                               barco_p1[myindex][crt2crtc][i][2],
10985                               barco_p1[myindex][crt2crtc][i][1]);
10986            }
10987         }
10988      }
10989      temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
10990      if(temp & 0x80) {
10991         temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x18);
10992         temp++;
10993         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);
10994      }
10995   }
10996 }
10997 
10998 static unsigned short
10999 GetOEMLCDPtr(struct SiS_Private *SiS_Pr, int Flag)
11000 {
11001   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
11002   unsigned short tempbx=0,romptr=0;
11003   static const unsigned char customtable300[] = {
11004         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
11005         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
11006   };
11007   static const unsigned char customtable630[] = {
11008         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
11009         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
11010   };
11011 
11012   if(SiS_Pr->ChipType == SIS_300) {
11013 
11014     tempbx = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0x0f;
11015     if(SiS_Pr->SiS_VBType & VB_SIS301) tempbx &= 0x07;
11016     tempbx -= 2;
11017     if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 4;
11018     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11019        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 3;
11020     }
11021     if(SiS_Pr->SiS_UseROM) {
11022        if(ROMAddr[0x235] & 0x80) {
11023           tempbx = SiS_Pr->SiS_LCDTypeInfo;
11024           if(Flag) {
11025              romptr = SISGETROMW(0x255);
11026              if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
11027              else       tempbx = customtable300[SiS_Pr->SiS_LCDTypeInfo];
11028              if(tempbx == 0xFF) return 0xFFFF;
11029           }
11030           tempbx <<= 1;
11031           if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
11032        }
11033     }
11034 
11035   } else {
11036 
11037     if(Flag) {
11038        if(SiS_Pr->SiS_UseROM) {
11039           romptr = SISGETROMW(0x255);
11040           if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
11041           else       tempbx = 0xff;
11042        } else {
11043           tempbx = customtable630[SiS_Pr->SiS_LCDTypeInfo];
11044        }
11045        if(tempbx == 0xFF) return 0xFFFF;
11046        tempbx <<= 2;
11047        if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
11048        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
11049        return tempbx;
11050     }
11051     tempbx = SiS_Pr->SiS_LCDTypeInfo << 2;
11052     if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
11053     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
11054 
11055   }
11056 
11057   return tempbx;
11058 }
11059 
11060 static void
11061 SetOEMLCDDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
11062 {
11063   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
11064   unsigned short index,temp,romptr=0;
11065 
11066   if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
11067 
11068   if(SiS_Pr->SiS_UseROM) {
11069      if(!(ROMAddr[0x237] & 0x01)) return;
11070      if(!(ROMAddr[0x237] & 0x02)) return;
11071      romptr = SISGETROMW(0x24b);
11072   }
11073 
11074   /* The Panel Compensation Delay should be set according to tables
11075    * here. Unfortunately, various BIOS versions don't care about
11076    * a uniform way using eg. ROM byte 0x220, but use different
11077    * hard coded delays (0x04, 0x20, 0x18) in SetGroup1().
11078    * Thus we don't set this if the user selected a custom pdc or if
11079    * we otherwise detected a valid pdc.
11080    */
11081   if(SiS_Pr->PDC != -1) return;
11082 
11083   temp = GetOEMLCDPtr(SiS_Pr, 0);
11084 
11085   if(SiS_Pr->UseCustomMode)
11086      index = 0;
11087   else
11088      index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
11089 
11090   if(SiS_Pr->ChipType != SIS_300) {
11091      if(romptr) {
11092         romptr += (temp * 2);
11093         romptr = SISGETROMW(romptr);
11094         romptr += index;
11095         temp = ROMAddr[romptr];
11096      } else {
11097         if(SiS_Pr->SiS_VBType & VB_SISVB) {
11098            temp = SiS300_OEMLCDDelay2[temp][index];
11099         } else {
11100            temp = SiS300_OEMLCDDelay3[temp][index];
11101         }
11102      }
11103   } else {
11104      if(SiS_Pr->SiS_UseROM && (ROMAddr[0x235] & 0x80)) {
11105         if(romptr) {
11106            romptr += (temp * 2);
11107            romptr = SISGETROMW(romptr);
11108            romptr += index;
11109            temp = ROMAddr[romptr];
11110         } else {
11111            temp = SiS300_OEMLCDDelay5[temp][index];
11112         }
11113      } else {
11114         if(SiS_Pr->SiS_UseROM) {
11115            romptr = ROMAddr[0x249] | (ROMAddr[0x24a] << 8);
11116            if(romptr) {
11117               romptr += (temp * 2);
11118               romptr = SISGETROMW(romptr);
11119               romptr += index;
11120               temp = ROMAddr[romptr];
11121            } else {
11122               temp = SiS300_OEMLCDDelay4[temp][index];
11123            }
11124         } else {
11125            temp = SiS300_OEMLCDDelay4[temp][index];
11126         }
11127      }
11128   }
11129   temp &= 0x3c;
11130   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);  /* index 0A D[6:4] */
11131 }
11132 
11133 static void
11134 SetOEMLCDData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11135 {
11136 #if 0  /* Unfinished; Data table missing */
11137   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
11138   unsigned short index,temp;
11139 
11140   if((SiS_Pr->SiS_UseROM) {
11141      if(!(ROMAddr[0x237] & 0x01)) return;
11142      if(!(ROMAddr[0x237] & 0x04)) return;
11143      /* No rom pointer in BIOS header! */
11144   }
11145 
11146   temp = GetOEMLCDPtr(SiS_Pr, 1);
11147   if(temp == 0xFFFF) return;
11148 
11149   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDHIndex;
11150   for(i=0x14, j=0; i<=0x17; i++, j++) {
11151       SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDHData[temp][index][j]);
11152   }
11153   SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1a, 0xf8, (SiS300_LCDHData[temp][index][j] & 0x07));
11154 
11155   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDVIndex;
11156   SiS_SetReg(SiS_SiS_Part1Port,0x18, SiS300_LCDVData[temp][index][0]);
11157   SiS_SetRegANDOR(SiS_SiS_Part1Port,0x19, 0xF0, SiS300_LCDVData[temp][index][1]);
11158   SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1A, 0xC7, (SiS300_LCDVData[temp][index][2] & 0x38));
11159   for(i=0x1b, j=3; i<=0x1d; i++, j++) {
11160       SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDVData[temp][index][j]);
11161   }
11162 #endif
11163 }
11164 
11165 static unsigned short
11166 GetOEMTVPtr(struct SiS_Private *SiS_Pr)
11167 {
11168   unsigned short index;
11169 
11170   index = 0;
11171   if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))  index += 4;
11172   if(SiS_Pr->SiS_VBType & VB_SISVB) {
11173      if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART)  index += 2;
11174      else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index += 3;
11175      else if(SiS_Pr->SiS_TVMode & TVSetPAL)   index += 1;
11176   } else {
11177      if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) index += 2;
11178      if(SiS_Pr->SiS_TVMode & TVSetPAL)        index += 1;
11179   }
11180   return index;
11181 }
11182 
11183 static void
11184 SetOEMTVDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11185 {
11186   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
11187   unsigned short index,temp,romptr=0;
11188 
11189   if(SiS_Pr->SiS_UseROM) {
11190      if(!(ROMAddr[0x238] & 0x01)) return;
11191      if(!(ROMAddr[0x238] & 0x02)) return;
11192      romptr = SISGETROMW(0x241);
11193   }
11194 
11195   temp = GetOEMTVPtr(SiS_Pr);
11196 
11197   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVDelayIndex;
11198 
11199   if(romptr) {
11200      romptr += (temp * 2);
11201      romptr = SISGETROMW(romptr);
11202      romptr += index;
11203      temp = ROMAddr[romptr];
11204   } else {
11205      if(SiS_Pr->SiS_VBType & VB_SISVB) {
11206         temp = SiS300_OEMTVDelay301[temp][index];
11207      } else {
11208         temp = SiS300_OEMTVDelayLVDS[temp][index];
11209      }
11210   }
11211   temp &= 0x3c;
11212   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);
11213 }
11214 
11215 static void
11216 SetOEMAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11217 {
11218   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
11219   unsigned short index,temp,romptr=0;
11220 
11221   if(SiS_Pr->SiS_UseROM) {
11222      if(!(ROMAddr[0x238] & 0x01)) return;
11223      if(!(ROMAddr[0x238] & 0x04)) return;
11224      romptr = SISGETROMW(0x243);
11225   }
11226 
11227   temp = GetOEMTVPtr(SiS_Pr);
11228 
11229   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVFlickerIndex;
11230 
11231   if(romptr) {
11232      romptr += (temp * 2);
11233      romptr = SISGETROMW(romptr);
11234      romptr += index;
11235      temp = ROMAddr[romptr];
11236   } else {
11237      temp = SiS300_OEMTVFlicker[temp][index];
11238   }
11239   temp &= 0x70;
11240   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8F,temp);
11241 }
11242 
11243 static void
11244 SetOEMPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
11245 {
11246   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
11247   unsigned short index,i,j,temp,romptr=0;
11248 
11249   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) return;
11250 
11251   if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetNTSCJ | TVSetPALM | TVSetPALN)) return;
11252 
11253   if(SiS_Pr->SiS_UseROM) {
11254      if(!(ROMAddr[0x238] & 0x01)) return;
11255      if(!(ROMAddr[0x238] & 0x08)) return;
11256      romptr = SISGETROMW(0x245);
11257   }
11258 
11259   temp = GetOEMTVPtr(SiS_Pr);
11260 
11261   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVPhaseIndex;
11262 
11263   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
11264      for(i=0x31, j=0; i<=0x34; i++, j++) {
11265         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase2[temp][index][j]);
11266      }
11267   } else {
11268      if(romptr) {
11269         romptr += (temp * 2);
11270         romptr = SISGETROMW(romptr);
11271         romptr += (index * 4);
11272         for(i=0x31, j=0; i<=0x34; i++, j++) {
11273            SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
11274         }
11275      } else {
11276         for(i=0x31, j=0; i<=0x34; i++, j++) {
11277            SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase1[temp][index][j]);
11278         }
11279      }
11280   }
11281 }
11282 
11283 static void
11284 SetOEMYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11285 {
11286   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
11287   unsigned short index,temp,i,j,romptr=0;
11288 
11289   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSCART | SetCRT2ToHiVision | SetCRT2ToYPbPr525750)) return;
11290 
11291   if(SiS_Pr->SiS_UseROM) {
11292      if(!(ROMAddr[0x238] & 0x01)) return;
11293      if(!(ROMAddr[0x238] & 0x10)) return;
11294      romptr = SISGETROMW(0x247);
11295   }
11296 
11297   temp = GetOEMTVPtr(SiS_Pr);
11298 
11299   if(SiS_Pr->SiS_TVMode & TVSetPALM)      temp = 8;
11300   else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 9;
11301   /* NTSCJ uses NTSC filters */
11302 
11303   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVYFilterIndex;
11304 
11305   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
11306       for(i=0x35, j=0; i<=0x38; i++, j++) {
11307         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
11308       }
11309       for(i=0x48; i<=0x4A; i++, j++) {
11310         SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
11311       }
11312   } else {
11313       if((romptr) && (!(SiS_Pr->SiS_TVMode & (TVSetPALM|TVSetPALN)))) {
11314          romptr += (temp * 2);
11315          romptr = SISGETROMW(romptr);
11316          romptr += (index * 4);
11317          for(i=0x35, j=0; i<=0x38; i++, j++) {
11318             SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
11319          }
11320       } else {
11321          for(i=0x35, j=0; i<=0x38; i++, j++) {
11322             SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter1[temp][index][j]);
11323          }
11324       }
11325   }
11326 }
11327 
11328 static unsigned short
11329 SiS_SearchVBModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo)
11330 {
11331    unsigned short ModeIdIndex;
11332    unsigned char  VGAINFO = SiS_Pr->SiS_VGAINFO;
11333 
11334    if(*ModeNo <= 5) *ModeNo |= 1;
11335 
11336    for(ModeIdIndex=0; ; ModeIdIndex++) {
11337       if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == *ModeNo) break;
11338       if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == 0xFF)    return 0;
11339    }
11340 
11341    if(*ModeNo != 0x07) {
11342       if(*ModeNo > 0x03) return ModeIdIndex;
11343       if(VGAINFO & 0x80) return ModeIdIndex;
11344       ModeIdIndex++;
11345    }
11346 
11347    if(VGAINFO & 0x10) ModeIdIndex++;   /* 400 lines */
11348                                        /* else 350 lines */
11349    return ModeIdIndex;
11350 }
11351 
11352 static void
11353 SiS_OEM300Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
11354                   unsigned short RefTableIndex)
11355 {
11356   unsigned short OEMModeIdIndex = 0;
11357 
11358   if(!SiS_Pr->UseCustomMode) {
11359      OEMModeIdIndex = SiS_SearchVBModeID(SiS_Pr,&ModeNo);
11360      if(!(OEMModeIdIndex)) return;
11361   }
11362 
11363   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
11364      SetOEMLCDDelay(SiS_Pr, ModeNo, OEMModeIdIndex);
11365      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
11366         SetOEMLCDData(SiS_Pr, ModeNo, OEMModeIdIndex);
11367      }
11368   }
11369   if(SiS_Pr->UseCustomMode) return;
11370   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
11371      SetOEMTVDelay(SiS_Pr, ModeNo,OEMModeIdIndex);
11372      if(SiS_Pr->SiS_VBType & VB_SISVB) {
11373         SetOEMAntiFlicker(SiS_Pr, ModeNo, OEMModeIdIndex);
11374         SetOEMPhaseIncr(SiS_Pr, ModeNo, OEMModeIdIndex);
11375         SetOEMYFilter(SiS_Pr, ModeNo, OEMModeIdIndex);
11376      }
11377   }
11378 }
11379 #endif
11380 

/* [<][>][^][v][top][bottom][index][help] */