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  #ifdef CONFIG_FB_SIS_315
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  /* 661 et al LCD data structure (2.03.00) */
249  static const unsigned char SiS_LCDStruct661[] = {
250      /* 1024x768 */
251  /*  type|CR37|   HDE   |   VDE   |    HT   |    VT   |   hss    | hse   */
252      0x02,0xC0,0x00,0x04,0x00,0x03,0x40,0x05,0x26,0x03,0x10,0x00,0x88,
253      0x00,0x02,0x00,0x06,0x00,0x41,0x5A,0x64,0x00,0x00,0x00,0x00,0x04,
254      /*  | vss     |    vse  |clck|  clock  |CRT2DataP|CRT2DataP|idx     */
255      /*					      VESA    non-VESA  noscale */
256      /* 1280x1024 */
257      0x03,0xC0,0x00,0x05,0x00,0x04,0x98,0x06,0x2A,0x04,0x30,0x00,0x70,
258      0x00,0x01,0x00,0x03,0x00,0x6C,0xF8,0x2F,0x00,0x00,0x00,0x00,0x08,
259      /* 1400x1050 */
260      0x09,0x20,0x78,0x05,0x1A,0x04,0x98,0x06,0x2A,0x04,0x18,0x00,0x38,
261      0x00,0x01,0x00,0x03,0x00,0x6C,0xF8,0x2F,0x00,0x00,0x00,0x00,0x09,
262      /* 1600x1200 */
263      0x0B,0xE0,0x40,0x06,0xB0,0x04,0x70,0x08,0xE2,0x04,0x40,0x00,0xC0,
264      0x00,0x01,0x00,0x03,0x00,0xA2,0x70,0x24,0x00,0x00,0x00,0x00,0x0A,
265      /* 1280x768 (_2) */
266      0x0A,0xE0,0x00,0x05,0x00,0x03,0x7C,0x06,0x26,0x03,0x30,0x00,0x70,
267      0x00,0x03,0x00,0x06,0x00,0x4D,0xC8,0x48,0x00,0x00,0x00,0x00,0x06,
268      /* 1280x720 */
269      0x0E,0xE0,0x00,0x05,0xD0,0x02,0x80,0x05,0x26,0x03,0x10,0x00,0x20,
270      0x00,0x01,0x00,0x06,0x00,0x45,0x9C,0x62,0x00,0x00,0x00,0x00,0x05,
271      /* 1280x800 (_2) */
272      0x0C,0xE0,0x00,0x05,0x20,0x03,0x10,0x06,0x2C,0x03,0x30,0x00,0x70,
273      0x00,0x04,0x00,0x03,0x00,0x49,0xCE,0x1E,0x00,0x00,0x00,0x00,0x09,
274      /* 1680x1050 */
275      0x0D,0xE0,0x90,0x06,0x1A,0x04,0x6C,0x07,0x2A,0x04,0x1A,0x00,0x4C,
276      0x00,0x03,0x00,0x06,0x00,0x79,0xBE,0x44,0x00,0x00,0x00,0x00,0x06,
277      /* 1280x800_3 */
278      0x0C,0xE0,0x00,0x05,0x20,0x03,0xAA,0x05,0x2E,0x03,0x30,0x00,0x50,
279      0x00,0x04,0x00,0x03,0x00,0x47,0xA9,0x10,0x00,0x00,0x00,0x00,0x07,
280      /* 800x600 */
281      0x01,0xC0,0x20,0x03,0x58,0x02,0x20,0x04,0x74,0x02,0x2A,0x00,0x80,
282      0x00,0x06,0x00,0x04,0x00,0x28,0x63,0x4B,0x00,0x00,0x00,0x00,0x00,
283      /* 1280x854 */
284      0x08,0xE0,0x00,0x05,0x56,0x03,0x80,0x06,0x5d,0x03,0x10,0x00,0x70,
285      0x00,0x01,0x00,0x03,0x00,0x54,0x75,0x13,0x00,0x00,0x00,0x00,0x08
286  };
287  #endif
288  
289  #ifdef CONFIG_FB_SIS_300
290  static unsigned char SiS300_TrumpionData[14][80] = {
291    { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
292      0x20,0x03,0x0B,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x10,0x00,0x00,0x04,0x23,
293      0x00,0x00,0x03,0x28,0x03,0x10,0x05,0x08,0x40,0x10,0x00,0x10,0x04,0x23,0x00,0x23,
294      0x03,0x11,0x60,0xBC,0x01,0xFF,0x03,0xFF,0x19,0x01,0x00,0x05,0x09,0x04,0x04,0x05,
295      0x04,0x0C,0x09,0x05,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5A,0x01,0xBE,0x01,0x00 },
296    { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x27,0x00,0x80,0x02,
297      0x20,0x03,0x07,0x00,0x5E,0x01,0x0D,0x02,0x60,0x0C,0x30,0x11,0x00,0x00,0x04,0x23,
298      0x00,0x00,0x03,0x80,0x03,0x28,0x06,0x08,0x40,0x11,0x00,0x11,0x04,0x23,0x00,0x23,
299      0x03,0x11,0x60,0x90,0x01,0xFF,0x0F,0xF4,0x19,0x01,0x00,0x05,0x01,0x00,0x04,0x05,
300      0x04,0x0C,0x02,0x01,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEC,0x57,0x01,0xBE,0x01,0x00 },
301    { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x8A,0x00,0xD8,0x02,
302      0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,
303      0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,
304      0x03,0x11,0x60,0xD9,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,
305      0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x59,0x01,0xBE,0x01,0x00 },
306    { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x72,0x00,0xD8,0x02,
307      0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,
308      0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,
309      0x03,0x11,0x60,0xDA,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,
310      0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
311    { 0x02,0x0A,0x02,0x00,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
312      0x20,0x03,0x16,0x00,0xE0,0x01,0x0D,0x02,0x60,0x0C,0x30,0x98,0x00,0x00,0x04,0x23,
313      0x00,0x01,0x03,0x45,0x03,0x48,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x23,0x00,0x23,
314      0x03,0x11,0x60,0xF4,0x01,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x05,0x01,0x00,0x05,0x05,
315      0x04,0x0C,0x08,0x05,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5B,0x01,0xBE,0x01,0x00 },
316    { 0x02,0x0A,0x02,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0xBF,0x00,0x20,0x03,
317      0x20,0x04,0x0D,0x00,0x58,0x02,0x71,0x02,0x80,0x0C,0x30,0x9A,0x00,0xFA,0x03,0x1D,
318      0x00,0x01,0x03,0x22,0x03,0x28,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x1D,0x00,0x1D,
319      0x03,0x11,0x60,0x39,0x03,0x40,0x05,0xF4,0x18,0x07,0x02,0x06,0x04,0x01,0x06,0x0B,
320      0x02,0x0A,0x20,0x19,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5B,0x01,0xBE,0x01,0x00 },
321    { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0xEF,0x00,0x00,0x04,
322      0x40,0x05,0x13,0x00,0x00,0x03,0x26,0x03,0x88,0x0C,0x30,0x90,0x00,0x00,0x04,0x23,
323      0x00,0x01,0x03,0x24,0x03,0x28,0x06,0x08,0x40,0x90,0x00,0x90,0x04,0x23,0x00,0x23,
324      0x03,0x11,0x60,0x40,0x05,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x08,0x01,0x00,0x08,0x01,
325      0x00,0x08,0x01,0x01,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5B,0x01,0xBE,0x01,0x00 },
326    /* variant 2 */
327    { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
328      0x20,0x03,0x15,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x18,0x00,0x00,0x04,0x23,
329      0x00,0x01,0x03,0x44,0x03,0x28,0x06,0x08,0x40,0x18,0x00,0x18,0x04,0x23,0x00,0x23,
330      0x03,0x11,0x60,0xA6,0x01,0xFF,0x03,0xFF,0x19,0x01,0x00,0x05,0x13,0x04,0x04,0x05,
331      0x04,0x0C,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
332    { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
333      0x20,0x03,0x15,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x18,0x00,0x00,0x04,0x23,
334      0x00,0x01,0x03,0x44,0x03,0x28,0x06,0x08,0x40,0x18,0x00,0x18,0x04,0x23,0x00,0x23,
335      0x03,0x11,0x60,0xA6,0x01,0xFF,0x03,0xFF,0x19,0x01,0x00,0x05,0x13,0x04,0x04,0x05,
336      0x04,0x0C,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
337    { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x8A,0x00,0xD8,0x02,
338      0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,
339      0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,
340      0x03,0x11,0x60,0xDA,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,
341      0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
342    { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x72,0x00,0xD8,0x02,
343      0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,
344      0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,
345      0x03,0x11,0x60,0xDA,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,
346      0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
347    { 0x02,0x0A,0x02,0x00,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
348      0x20,0x03,0x16,0x00,0xE0,0x01,0x0D,0x02,0x60,0x0C,0x30,0x98,0x00,0x00,0x04,0x23,
349      0x00,0x01,0x03,0x45,0x03,0x48,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x23,0x00,0x23,
350      0x03,0x11,0x60,0xF4,0x01,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x05,0x01,0x00,0x05,0x05,
351      0x04,0x0C,0x08,0x05,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEA,0x58,0x01,0xBE,0x01,0x00 },
352    { 0x02,0x0A,0x02,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0xBF,0x00,0x20,0x03,
353      0x20,0x04,0x0D,0x00,0x58,0x02,0x71,0x02,0x80,0x0C,0x30,0x9A,0x00,0xFA,0x03,0x1D,
354      0x00,0x01,0x03,0x22,0x03,0x28,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x1D,0x00,0x1D,
355      0x03,0x11,0x60,0x39,0x03,0x40,0x05,0xF4,0x18,0x07,0x02,0x06,0x04,0x01,0x06,0x0B,
356      0x02,0x0A,0x20,0x19,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEA,0x58,0x01,0xBE,0x01,0x00 },
357    { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0xEF,0x00,0x00,0x04,
358      0x40,0x05,0x13,0x00,0x00,0x03,0x26,0x03,0x88,0x0C,0x30,0x90,0x00,0x00,0x04,0x23,
359      0x00,0x01,0x03,0x24,0x03,0x28,0x06,0x08,0x40,0x90,0x00,0x90,0x04,0x23,0x00,0x23,
360      0x03,0x11,0x60,0x40,0x05,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x08,0x01,0x00,0x08,0x01,
361      0x00,0x08,0x01,0x01,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEA,0x58,0x01,0xBE,0x01,0x00 }
362  };
363  #endif
364  
365  #ifdef CONFIG_FB_SIS_315
366  static void	SiS_Chrontel701xOn(struct SiS_Private *SiS_Pr);
367  static void	SiS_Chrontel701xOff(struct SiS_Private *SiS_Pr);
368  static void	SiS_ChrontelInitTVVSync(struct SiS_Private *SiS_Pr);
369  static void	SiS_ChrontelDoSomething1(struct SiS_Private *SiS_Pr);
370  #endif /* 315 */
371  
372  #ifdef CONFIG_FB_SIS_300
373  static  bool	SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr);
374  #endif
375  
376  static unsigned short	SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags,
377  				int VGAEngine, unsigned short adaptnum, unsigned short DDCdatatype,
378  				bool checkcr32, unsigned int VBFlags2);
379  static unsigned short	SiS_ProbeDDC(struct SiS_Private *SiS_Pr);
380  static unsigned short	SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype,
381  				unsigned char *buffer);
382  static void		SiS_SetSwitchDDC2(struct SiS_Private *SiS_Pr);
383  static unsigned short	SiS_SetStart(struct SiS_Private *SiS_Pr);
384  static unsigned short	SiS_SetStop(struct SiS_Private *SiS_Pr);
385  static unsigned short	SiS_SetSCLKLow(struct SiS_Private *SiS_Pr);
386  static unsigned short	SiS_SetSCLKHigh(struct SiS_Private *SiS_Pr);
387  static unsigned short	SiS_ReadDDC2Data(struct SiS_Private *SiS_Pr);
388  static unsigned short	SiS_WriteDDC2Data(struct SiS_Private *SiS_Pr, unsigned short tempax);
389  static unsigned short	SiS_CheckACK(struct SiS_Private *SiS_Pr);
390  static unsigned short	SiS_WriteDABDDC(struct SiS_Private *SiS_Pr);
391  static unsigned short	SiS_PrepareReadDDC(struct SiS_Private *SiS_Pr);
392  static unsigned short	SiS_PrepareDDC(struct SiS_Private *SiS_Pr);
393  static void		SiS_SendACK(struct SiS_Private *SiS_Pr, unsigned short yesno);
394  static unsigned short	SiS_DoProbeDDC(struct SiS_Private *SiS_Pr);
395  
396  #ifdef CONFIG_FB_SIS_300
397  static void		SiS_OEM300Setting(struct SiS_Private *SiS_Pr,
398  				unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefTabindex);
399  static void		SetOEMLCDData2(struct SiS_Private *SiS_Pr,
400  				unsigned short ModeNo, unsigned short ModeIdIndex,unsigned short RefTableIndex);
401  #endif
402  #ifdef CONFIG_FB_SIS_315
403  static void		SiS_OEM310Setting(struct SiS_Private *SiS_Pr,
404  				unsigned short ModeNo,unsigned short ModeIdIndex, unsigned short RRTI);
405  static void		SiS_OEM661Setting(struct SiS_Private *SiS_Pr,
406  				unsigned short ModeNo,unsigned short ModeIdIndex, unsigned short RRTI);
407  static void		SiS_FinalizeLCD(struct SiS_Private *, unsigned short, unsigned short);
408  #endif
409  
410  static unsigned short	SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr);
411  static void		SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);
412  
413  /*********************************************/
414  /*         HELPER: Lock/Unlock CRT2          */
415  /*********************************************/
416  
417  void
SiS_UnLockCRT2(struct SiS_Private * SiS_Pr)418  SiS_UnLockCRT2(struct SiS_Private *SiS_Pr)
419  {
420     if(SiS_Pr->ChipType == XGI_20)
421        return;
422     else if(SiS_Pr->ChipType >= SIS_315H)
423        SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
424     else
425        SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
426  }
427  
428  static
429  void
SiS_LockCRT2(struct SiS_Private * SiS_Pr)430  SiS_LockCRT2(struct SiS_Private *SiS_Pr)
431  {
432     if(SiS_Pr->ChipType == XGI_20)
433        return;
434     else if(SiS_Pr->ChipType >= SIS_315H)
435        SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
436     else
437        SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
438  }
439  
440  /*********************************************/
441  /*            HELPER: Write SR11             */
442  /*********************************************/
443  
444  static void
SiS_SetRegSR11ANDOR(struct SiS_Private * SiS_Pr,unsigned short DataAND,unsigned short DataOR)445  SiS_SetRegSR11ANDOR(struct SiS_Private *SiS_Pr, unsigned short DataAND, unsigned short DataOR)
446  {
447     if(SiS_Pr->ChipType >= SIS_661) {
448        DataAND &= 0x0f;
449        DataOR  &= 0x0f;
450     }
451     SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,DataAND,DataOR);
452  }
453  
454  /*********************************************/
455  /*    HELPER: Get Pointer to LCD structure   */
456  /*********************************************/
457  
458  #ifdef CONFIG_FB_SIS_315
459  static unsigned char *
GetLCDStructPtr661(struct SiS_Private * SiS_Pr)460  GetLCDStructPtr661(struct SiS_Private *SiS_Pr)
461  {
462     unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
463     unsigned char  *myptr = NULL;
464     unsigned short romindex = 0, reg = 0, idx = 0;
465  
466     /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
467      * due to the variaty of panels the BIOS doesn't know about.
468      * Exception: If the BIOS has better knowledge (such as in case
469      * of machines with a 301C and a panel that does not support DDC)
470      * use the BIOS data as well.
471      */
472  
473     if((SiS_Pr->SiS_ROMNew) &&
474        ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) {
475  
476        if(SiS_Pr->ChipType < SIS_661) reg = 0x3c;
477        else                           reg = 0x7d;
478  
479        idx = (SiS_GetReg(SiS_Pr->SiS_P3d4,reg) & 0x1f) * 26;
480  
481        if(idx < (8*26)) {
482           myptr = (unsigned char *)&SiS_LCDStruct661[idx];
483        }
484        romindex = SISGETROMW(0x100);
485        if(romindex) {
486           romindex += idx;
487           myptr = &ROMAddr[romindex];
488        }
489     }
490     return myptr;
491  }
492  
493  static unsigned short
GetLCDStructPtr661_2(struct SiS_Private * SiS_Pr)494  GetLCDStructPtr661_2(struct SiS_Private *SiS_Pr)
495  {
496     unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
497     unsigned short romptr = 0;
498  
499     /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
500      * due to the variaty of panels the BIOS doesn't know about.
501      * Exception: If the BIOS has better knowledge (such as in case
502      * of machines with a 301C and a panel that does not support DDC)
503      * use the BIOS data as well.
504      */
505  
506     if((SiS_Pr->SiS_ROMNew) &&
507        ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) {
508        romptr = SISGETROMW(0x102);
509        romptr += ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) * SiS_Pr->SiS661LCD2TableSize);
510     }
511  
512     return romptr;
513  }
514  #endif
515  
516  /*********************************************/
517  /*           Adjust Rate for CRT2            */
518  /*********************************************/
519  
520  static bool
SiS_AdjustCRT2Rate(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RRTI,unsigned short * i)521  SiS_AdjustCRT2Rate(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
522  		unsigned short RRTI, unsigned short *i)
523  {
524     unsigned short checkmask=0, modeid, infoflag;
525  
526     modeid = SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID;
527  
528     if(SiS_Pr->SiS_VBType & VB_SISVB) {
529  
530        if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
531  
532  	 checkmask |= SupportRAMDAC2;
533  	 if(SiS_Pr->ChipType >= SIS_315H) {
534  	    checkmask |= SupportRAMDAC2_135;
535  	    if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
536  	       checkmask |= SupportRAMDAC2_162;
537  	       if(SiS_Pr->SiS_VBType & VB_SISRAMDAC202) {
538  		  checkmask |= SupportRAMDAC2_202;
539  	       }
540  	    }
541  	 }
542  
543        } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
544  
545  	 checkmask |= SupportLCD;
546  	 if(SiS_Pr->ChipType >= SIS_315H) {
547  	    if(SiS_Pr->SiS_VBType & VB_SISVB) {
548  	       if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
549  	          if(modeid == 0x2e) checkmask |= Support64048060Hz;
550  	       }
551  	    }
552  	 }
553  
554        } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
555  
556  	 checkmask |= SupportHiVision;
557  
558        } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750|SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
559  
560  	 checkmask |= SupportTV;
561  	 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
562  	    checkmask |= SupportTV1024;
563  	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
564  	       if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
565  	          checkmask |= SupportYPbPr750p;
566  	       }
567  	    }
568  	 }
569  
570        }
571  
572     } else {	/* LVDS */
573  
574        if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
575  	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
576  	    checkmask |= SupportCHTV;
577  	 }
578        }
579  
580        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
581  	 checkmask |= SupportLCD;
582        }
583  
584     }
585  
586     /* Look backwards in table for matching CRT2 mode */
587     for(; SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID == modeid; (*i)--) {
588        infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
589        if(infoflag & checkmask) return true;
590        if((*i) == 0) break;
591     }
592  
593     /* Look through the whole mode-section of the table from the beginning
594      * for a matching CRT2 mode if no mode was found yet.
595      */
596     for((*i) = 0; ; (*i)++) {
597        if(SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID != modeid) break;
598        infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
599        if(infoflag & checkmask) return true;
600     }
601     return false;
602  }
603  
604  /*********************************************/
605  /*              Get rate index               */
606  /*********************************************/
607  
608  unsigned short
SiS_GetRatePtr(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)609  SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
610  {
611     unsigned short RRTI,i,backup_i;
612     unsigned short modeflag,index,temp,backupindex;
613     static const unsigned short LCDRefreshIndex[] = {
614  		0x00, 0x00, 0x01, 0x01,
615  		0x01, 0x01, 0x01, 0x01,
616  		0x01, 0x01, 0x01, 0x01,
617  		0x01, 0x01, 0x01, 0x01,
618  		0x00, 0x00, 0x00, 0x00
619     };
620  
621     /* Do NOT check for UseCustomMode here, will skrew up FIFO */
622     if(ModeNo == 0xfe) return 0;
623  
624     if(ModeNo <= 0x13) {
625        modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
626     } else {
627        modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
628     }
629  
630     if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
631        if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
632  	 if(modeflag & HalfDCLK) return 0;
633        }
634     }
635  
636     if(ModeNo < 0x14) return 0xFFFF;
637  
638     index = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x33) >> SiS_Pr->SiS_SelectCRT2Rate) & 0x0F;
639     backupindex = index;
640  
641     if(index > 0) index--;
642  
643     if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
644        if(SiS_Pr->SiS_VBType & VB_SISVB) {
645  	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
646  	    if(SiS_Pr->SiS_VBType & VB_NoLCD)		 index = 0;
647  	    else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index = backupindex = 0;
648  	 }
649  	 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
650  	    if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) {
651  	       temp = LCDRefreshIndex[SiS_GetBIOSLCDResInfo(SiS_Pr)];
652  	       if(index > temp) index = temp;
653  	    }
654  	 }
655        } else {
656  	 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) index = 0;
657  	 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
658  	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) index = 0;
659  	 }
660        }
661     }
662  
663     RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
664     ModeNo = SiS_Pr->SiS_RefIndex[RRTI].ModeID;
665  
666     if(SiS_Pr->ChipType >= SIS_315H) {
667        if(!(SiS_Pr->SiS_VBInfo & DriverMode)) {
668  	 if( (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x105) ||
669  	     (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x107) ) {
670  	    if(backupindex <= 1) RRTI++;
671  	 }
672        }
673     }
674  
675     i = 0;
676     do {
677        if(SiS_Pr->SiS_RefIndex[RRTI + i].ModeID != ModeNo) break;
678        temp = SiS_Pr->SiS_RefIndex[RRTI + i].Ext_InfoFlag;
679        temp &= ModeTypeMask;
680        if(temp < SiS_Pr->SiS_ModeType) break;
681        i++;
682        index--;
683     } while(index != 0xFFFF);
684  
685     if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
686        if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
687  	 temp = SiS_Pr->SiS_RefIndex[RRTI + i - 1].Ext_InfoFlag;
688  	 if(temp & InterlaceMode) i++;
689        }
690     }
691  
692     i--;
693  
694     if((SiS_Pr->SiS_SetFlag & ProgrammingCRT2) && (!(SiS_Pr->SiS_VBInfo & DisableCRT2Display))) {
695        backup_i = i;
696        if(!(SiS_AdjustCRT2Rate(SiS_Pr, ModeNo, ModeIdIndex, RRTI, &i))) {
697  	 i = backup_i;
698        }
699     }
700  
701     return (RRTI + i);
702  }
703  
704  /*********************************************/
705  /*            STORE CRT2 INFO in CR34        */
706  /*********************************************/
707  
708  static void
SiS_SaveCRT2Info(struct SiS_Private * SiS_Pr,unsigned short ModeNo)709  SiS_SaveCRT2Info(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
710  {
711     unsigned short temp1, temp2;
712  
713     /* Store CRT1 ModeNo in CR34 */
714     SiS_SetReg(SiS_Pr->SiS_P3d4,0x34,ModeNo);
715     temp1 = (SiS_Pr->SiS_VBInfo & SetInSlaveMode) >> 8;
716     temp2 = ~(SetInSlaveMode >> 8);
717     SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x31,temp2,temp1);
718  }
719  
720  /*********************************************/
721  /*    HELPER: GET SOME DATA FROM BIOS ROM    */
722  /*********************************************/
723  
724  #ifdef CONFIG_FB_SIS_300
725  static bool
SiS_CR36BIOSWord23b(struct SiS_Private * SiS_Pr)726  SiS_CR36BIOSWord23b(struct SiS_Private *SiS_Pr)
727  {
728     unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
729     unsigned short temp,temp1;
730  
731     if(SiS_Pr->SiS_UseROM) {
732        if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
733  	 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
734  	 temp1 = SISGETROMW(0x23b);
735  	 if(temp1 & temp) return true;
736        }
737     }
738     return false;
739  }
740  
741  static bool
SiS_CR36BIOSWord23d(struct SiS_Private * SiS_Pr)742  SiS_CR36BIOSWord23d(struct SiS_Private *SiS_Pr)
743  {
744     unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
745     unsigned short temp,temp1;
746  
747     if(SiS_Pr->SiS_UseROM) {
748        if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
749  	 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
750  	 temp1 = SISGETROMW(0x23d);
751  	 if(temp1 & temp) return true;
752        }
753     }
754     return false;
755  }
756  #endif
757  
758  /*********************************************/
759  /*          HELPER: DELAY FUNCTIONS          */
760  /*********************************************/
761  
762  void
SiS_DDC2Delay(struct SiS_Private * SiS_Pr,unsigned int delaytime)763  SiS_DDC2Delay(struct SiS_Private *SiS_Pr, unsigned int delaytime)
764  {
765     while (delaytime-- > 0)
766        SiS_GetReg(SiS_Pr->SiS_P3c4, 0x05);
767  }
768  
769  #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
770  static void
SiS_GenericDelay(struct SiS_Private * SiS_Pr,unsigned short delay)771  SiS_GenericDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
772  {
773     SiS_DDC2Delay(SiS_Pr, delay * 36);
774  }
775  #endif
776  
777  #ifdef CONFIG_FB_SIS_315
778  static void
SiS_LongDelay(struct SiS_Private * SiS_Pr,unsigned short delay)779  SiS_LongDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
780  {
781     while(delay--) {
782        SiS_GenericDelay(SiS_Pr, 6623);
783     }
784  }
785  #endif
786  
787  #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
788  static void
SiS_ShortDelay(struct SiS_Private * SiS_Pr,unsigned short delay)789  SiS_ShortDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
790  {
791     while(delay--) {
792        SiS_GenericDelay(SiS_Pr, 66);
793     }
794  }
795  #endif
796  
797  static void
SiS_PanelDelay(struct SiS_Private * SiS_Pr,unsigned short DelayTime)798  SiS_PanelDelay(struct SiS_Private *SiS_Pr, unsigned short DelayTime)
799  {
800  #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
801     unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
802     unsigned short PanelID, DelayIndex, Delay=0;
803  #endif
804  
805     if(SiS_Pr->ChipType < SIS_315H) {
806  
807  #ifdef CONFIG_FB_SIS_300
808  
809        PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
810        if(SiS_Pr->SiS_VBType & VB_SISVB) {
811  	 if(SiS_Pr->SiS_VBType & VB_SIS301) PanelID &= 0xf7;
812  	 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x10)) PanelID = 0x12;
813        }
814        DelayIndex = PanelID >> 4;
815        if((DelayTime >= 2) && ((PanelID & 0x0f) == 1))  {
816  	 Delay = 3;
817        } else {
818  	 if(DelayTime >= 2) DelayTime -= 2;
819  	 if(!(DelayTime & 0x01)) {
820  	    Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
821  	 } else {
822  	    Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
823  	 }
824  	 if(SiS_Pr->SiS_UseROM) {
825  	    if(ROMAddr[0x220] & 0x40) {
826  	       if(!(DelayTime & 0x01)) Delay = (unsigned short)ROMAddr[0x225];
827  	       else 	    	       Delay = (unsigned short)ROMAddr[0x226];
828  	    }
829  	 }
830        }
831        SiS_ShortDelay(SiS_Pr, Delay);
832  
833  #endif  /* CONFIG_FB_SIS_300 */
834  
835     } else {
836  
837  #ifdef CONFIG_FB_SIS_315
838  
839        if((SiS_Pr->ChipType >= SIS_661)    ||
840  	 (SiS_Pr->ChipType <= SIS_315PRO) ||
841  	 (SiS_Pr->ChipType == SIS_330)    ||
842  	 (SiS_Pr->SiS_ROMNew)) {
843  
844  	 if(!(DelayTime & 0x01)) {
845  	    SiS_DDC2Delay(SiS_Pr, 0x1000);
846  	 } else {
847  	    SiS_DDC2Delay(SiS_Pr, 0x4000);
848  	 }
849  
850        } else if (SiS_Pr->SiS_IF_DEF_LVDS == 1) {			/* 315 series, LVDS; Special */
851  
852  	 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
853  	    PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
854  	    if(SiS_Pr->SiS_CustomT == CUT_CLEVO1400) {
855  	       if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1b) & 0x10)) PanelID = 0x12;
856  	    }
857  	    if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
858  	       DelayIndex = PanelID & 0x0f;
859  	    } else {
860  	       DelayIndex = PanelID >> 4;
861  	    }
862  	    if((DelayTime >= 2) && ((PanelID & 0x0f) == 1))  {
863  	       Delay = 3;
864  	    } else {
865  	       if(DelayTime >= 2) DelayTime -= 2;
866  	       if(!(DelayTime & 0x01)) {
867  		  Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[0];
868  		} else {
869  		  Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[1];
870  	       }
871  	       if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
872  		  if(ROMAddr[0x13c] & 0x40) {
873  		     if(!(DelayTime & 0x01)) {
874  			Delay = (unsigned short)ROMAddr[0x17e];
875  		     } else {
876  			Delay = (unsigned short)ROMAddr[0x17f];
877  		     }
878  		  }
879  	       }
880  	    }
881  	    SiS_ShortDelay(SiS_Pr, Delay);
882  	 }
883  
884        } else if(SiS_Pr->SiS_VBType & VB_SISVB) {			/* 315 series, all bridges */
885  
886  	 DelayIndex = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
887  	 if(!(DelayTime & 0x01)) {
888  	    Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
889  	 } else {
890  	    Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
891  	 }
892  	 Delay <<= 8;
893  	 SiS_DDC2Delay(SiS_Pr, Delay);
894  
895        }
896  
897  #endif /* CONFIG_FB_SIS_315 */
898  
899     }
900  }
901  
902  #ifdef CONFIG_FB_SIS_315
903  static void
SiS_PanelDelayLoop(struct SiS_Private * SiS_Pr,unsigned short DelayTime,unsigned short DelayLoop)904  SiS_PanelDelayLoop(struct SiS_Private *SiS_Pr, unsigned short DelayTime, unsigned short DelayLoop)
905  {
906     int i;
907     for(i = 0; i < DelayLoop; i++) {
908        SiS_PanelDelay(SiS_Pr, DelayTime);
909     }
910  }
911  #endif
912  
913  /*********************************************/
914  /*    HELPER: WAIT-FOR-RETRACE FUNCTIONS     */
915  /*********************************************/
916  
917  void
SiS_WaitRetrace1(struct SiS_Private * SiS_Pr)918  SiS_WaitRetrace1(struct SiS_Private *SiS_Pr)
919  {
920     unsigned short watchdog;
921  
922     if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
923     if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80)) return;
924  
925     watchdog = 65535;
926     while((SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
927     watchdog = 65535;
928     while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
929  }
930  
931  #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
932  static void
SiS_WaitRetrace2(struct SiS_Private * SiS_Pr,unsigned short reg)933  SiS_WaitRetrace2(struct SiS_Private *SiS_Pr, unsigned short reg)
934  {
935     unsigned short watchdog;
936  
937     watchdog = 65535;
938     while((SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02) && --watchdog);
939     watchdog = 65535;
940     while((!(SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02)) && --watchdog);
941  }
942  #endif
943  
944  static void
SiS_WaitVBRetrace(struct SiS_Private * SiS_Pr)945  SiS_WaitVBRetrace(struct SiS_Private *SiS_Pr)
946  {
947     if(SiS_Pr->ChipType < SIS_315H) {
948  #ifdef CONFIG_FB_SIS_300
949        if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
950  	 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return;
951        }
952        if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x80)) {
953  	 SiS_WaitRetrace1(SiS_Pr);
954        } else {
955  	 SiS_WaitRetrace2(SiS_Pr, 0x25);
956        }
957  #endif
958     } else {
959  #ifdef CONFIG_FB_SIS_315
960        if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) {
961  	 SiS_WaitRetrace1(SiS_Pr);
962        } else {
963  	 SiS_WaitRetrace2(SiS_Pr, 0x30);
964        }
965  #endif
966     }
967  }
968  
969  static void
SiS_VBWait(struct SiS_Private * SiS_Pr)970  SiS_VBWait(struct SiS_Private *SiS_Pr)
971  {
972     unsigned short tempal,temp,i,j;
973  
974     temp = 0;
975     for(i = 0; i < 3; i++) {
976       for(j = 0; j < 100; j++) {
977          tempal = SiS_GetRegByte(SiS_Pr->SiS_P3da);
978          if(temp & 0x01) {
979  	   if((tempal & 0x08))  continue;
980  	   else break;
981          } else {
982  	   if(!(tempal & 0x08)) continue;
983  	   else break;
984          }
985       }
986       temp ^= 0x01;
987     }
988  }
989  
990  static void
SiS_VBLongWait(struct SiS_Private * SiS_Pr)991  SiS_VBLongWait(struct SiS_Private *SiS_Pr)
992  {
993     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
994        SiS_VBWait(SiS_Pr);
995     } else {
996        SiS_WaitRetrace1(SiS_Pr);
997     }
998  }
999  
1000  /*********************************************/
1001  /*               HELPER: MISC                */
1002  /*********************************************/
1003  
1004  #ifdef CONFIG_FB_SIS_300
1005  static bool
SiS_Is301B(struct SiS_Private * SiS_Pr)1006  SiS_Is301B(struct SiS_Private *SiS_Pr)
1007  {
1008     if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01) >= 0xb0) return true;
1009     return false;
1010  }
1011  #endif
1012  
1013  static bool
SiS_CRT2IsLCD(struct SiS_Private * SiS_Pr)1014  SiS_CRT2IsLCD(struct SiS_Private *SiS_Pr)
1015  {
1016     if(SiS_Pr->ChipType == SIS_730) {
1017        if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x20) return true;
1018     }
1019     if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & 0x20) return true;
1020     return false;
1021  }
1022  
1023  bool
SiS_IsDualEdge(struct SiS_Private * SiS_Pr)1024  SiS_IsDualEdge(struct SiS_Private *SiS_Pr)
1025  {
1026  #ifdef CONFIG_FB_SIS_315
1027     if(SiS_Pr->ChipType >= SIS_315H) {
1028        if((SiS_Pr->ChipType != SIS_650) || (SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) {
1029  	 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableDualEdge) return true;
1030        }
1031     }
1032  #endif
1033     return false;
1034  }
1035  
1036  bool
SiS_IsVAMode(struct SiS_Private * SiS_Pr)1037  SiS_IsVAMode(struct SiS_Private *SiS_Pr)
1038  {
1039  #ifdef CONFIG_FB_SIS_315
1040     unsigned short flag;
1041  
1042     if(SiS_Pr->ChipType >= SIS_315H) {
1043        flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1044        if((flag & EnableDualEdge) && (flag & SetToLCDA)) return true;
1045     }
1046  #endif
1047     return false;
1048  }
1049  
1050  #ifdef CONFIG_FB_SIS_315
1051  static bool
SiS_IsVAorLCD(struct SiS_Private * SiS_Pr)1052  SiS_IsVAorLCD(struct SiS_Private *SiS_Pr)
1053  {
1054     if(SiS_IsVAMode(SiS_Pr))  return true;
1055     if(SiS_CRT2IsLCD(SiS_Pr)) return true;
1056     return false;
1057  }
1058  #endif
1059  
1060  static bool
SiS_IsDualLink(struct SiS_Private * SiS_Pr)1061  SiS_IsDualLink(struct SiS_Private *SiS_Pr)
1062  {
1063  #ifdef CONFIG_FB_SIS_315
1064     if(SiS_Pr->ChipType >= SIS_315H) {
1065        if((SiS_CRT2IsLCD(SiS_Pr)) ||
1066           (SiS_IsVAMode(SiS_Pr))) {
1067  	 if(SiS_Pr->SiS_LCDInfo & LCDDualLink) return true;
1068        }
1069     }
1070  #endif
1071     return false;
1072  }
1073  
1074  #ifdef CONFIG_FB_SIS_315
1075  static bool
SiS_TVEnabled(struct SiS_Private * SiS_Pr)1076  SiS_TVEnabled(struct SiS_Private *SiS_Pr)
1077  {
1078     if((SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) != 0x0c) return true;
1079     if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1080        if(SiS_GetReg(SiS_Pr->SiS_Part2Port,0x4d) & 0x10) return true;
1081     }
1082     return false;
1083  }
1084  #endif
1085  
1086  #ifdef CONFIG_FB_SIS_315
1087  static bool
SiS_LCDAEnabled(struct SiS_Private * SiS_Pr)1088  SiS_LCDAEnabled(struct SiS_Private *SiS_Pr)
1089  {
1090     if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) return true;
1091     return false;
1092  }
1093  #endif
1094  
1095  #ifdef CONFIG_FB_SIS_315
1096  static bool
SiS_WeHaveBacklightCtrl(struct SiS_Private * SiS_Pr)1097  SiS_WeHaveBacklightCtrl(struct SiS_Private *SiS_Pr)
1098  {
1099     if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
1100        if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0x10) return true;
1101     }
1102     return false;
1103  }
1104  #endif
1105  
1106  #ifdef CONFIG_FB_SIS_315
1107  static bool
SiS_IsNotM650orLater(struct SiS_Private * SiS_Pr)1108  SiS_IsNotM650orLater(struct SiS_Private *SiS_Pr)
1109  {
1110     unsigned short flag;
1111  
1112     if(SiS_Pr->ChipType == SIS_650) {
1113        flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0;
1114        /* Check for revision != A0 only */
1115        if((flag == 0xe0) || (flag == 0xc0) ||
1116           (flag == 0xb0) || (flag == 0x90)) return false;
1117     } else if(SiS_Pr->ChipType >= SIS_661) return false;
1118     return true;
1119  }
1120  #endif
1121  
1122  #ifdef CONFIG_FB_SIS_315
1123  static bool
SiS_IsYPbPr(struct SiS_Private * SiS_Pr)1124  SiS_IsYPbPr(struct SiS_Private *SiS_Pr)
1125  {
1126     if(SiS_Pr->ChipType >= SIS_315H) {
1127        /* YPrPb = 0x08 */
1128        if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHYPbPr) return true;
1129     }
1130     return false;
1131  }
1132  #endif
1133  
1134  #ifdef CONFIG_FB_SIS_315
1135  static bool
SiS_IsChScart(struct SiS_Private * SiS_Pr)1136  SiS_IsChScart(struct SiS_Private *SiS_Pr)
1137  {
1138     if(SiS_Pr->ChipType >= SIS_315H) {
1139        /* Scart = 0x04 */
1140        if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHScart) return true;
1141     }
1142     return false;
1143  }
1144  #endif
1145  
1146  #ifdef CONFIG_FB_SIS_315
1147  static bool
SiS_IsTVOrYPbPrOrScart(struct SiS_Private * SiS_Pr)1148  SiS_IsTVOrYPbPrOrScart(struct SiS_Private *SiS_Pr)
1149  {
1150     unsigned short flag;
1151  
1152     if(SiS_Pr->ChipType >= SIS_315H) {
1153        flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
1154        if(flag & SetCRT2ToTV)        return true;
1155        flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1156        if(flag & EnableCHYPbPr)      return true;  /* = YPrPb = 0x08 */
1157        if(flag & EnableCHScart)      return true;  /* = Scart = 0x04 - TW */
1158     } else {
1159        flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
1160        if(flag & SetCRT2ToTV)        return true;
1161     }
1162     return false;
1163  }
1164  #endif
1165  
1166  #ifdef CONFIG_FB_SIS_315
1167  static bool
SiS_IsLCDOrLCDA(struct SiS_Private * SiS_Pr)1168  SiS_IsLCDOrLCDA(struct SiS_Private *SiS_Pr)
1169  {
1170     unsigned short flag;
1171  
1172     if(SiS_Pr->ChipType >= SIS_315H) {
1173        flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
1174        if(flag & SetCRT2ToLCD) return true;
1175        flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1176        if(flag & SetToLCDA)    return true;
1177     } else {
1178        flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
1179        if(flag & SetCRT2ToLCD) return true;
1180     }
1181     return false;
1182  }
1183  #endif
1184  
1185  static bool
SiS_HaveBridge(struct SiS_Private * SiS_Pr)1186  SiS_HaveBridge(struct SiS_Private *SiS_Pr)
1187  {
1188     unsigned short flag;
1189  
1190     if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1191        return true;
1192     } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
1193        flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
1194        if((flag == 1) || (flag == 2)) return true;
1195     }
1196     return false;
1197  }
1198  
1199  static bool
SiS_BridgeIsEnabled(struct SiS_Private * SiS_Pr)1200  SiS_BridgeIsEnabled(struct SiS_Private *SiS_Pr)
1201  {
1202     unsigned short flag;
1203  
1204     if(SiS_HaveBridge(SiS_Pr)) {
1205        flag = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
1206        if(SiS_Pr->ChipType < SIS_315H) {
1207  	flag &= 0xa0;
1208  	if((flag == 0x80) || (flag == 0x20)) return true;
1209        } else {
1210  	flag &= 0x50;
1211  	if((flag == 0x40) || (flag == 0x10)) return true;
1212        }
1213     }
1214     return false;
1215  }
1216  
1217  static bool
SiS_BridgeInSlavemode(struct SiS_Private * SiS_Pr)1218  SiS_BridgeInSlavemode(struct SiS_Private *SiS_Pr)
1219  {
1220     unsigned short flag1;
1221  
1222     flag1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
1223     if(flag1 & (SetInSlaveMode >> 8)) return true;
1224     return false;
1225  }
1226  
1227  /*********************************************/
1228  /*       GET VIDEO BRIDGE CONFIG INFO        */
1229  /*********************************************/
1230  
1231  /* Setup general purpose IO for Chrontel communication */
1232  #ifdef CONFIG_FB_SIS_300
1233  void
SiS_SetChrontelGPIO(struct SiS_Private * SiS_Pr,unsigned short myvbinfo)1234  SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo)
1235  {
1236     unsigned int   acpibase;
1237     unsigned short temp;
1238  
1239     if(!(SiS_Pr->SiS_ChSW)) return;
1240  
1241     acpibase = sisfb_read_lpc_pci_dword(SiS_Pr, 0x74);
1242     acpibase &= 0xFFFF;
1243     if(!acpibase) return;
1244     temp = SiS_GetRegShort((acpibase + 0x3c));	/* ACPI register 0x3c: GP Event 1 I/O mode select */
1245     temp &= 0xFEFF;
1246     SiS_SetRegShort((acpibase + 0x3c), temp);
1247     temp = SiS_GetRegShort((acpibase + 0x3c));
1248     temp = SiS_GetRegShort((acpibase + 0x3a));	/* ACPI register 0x3a: GP Pin Level (low/high) */
1249     temp &= 0xFEFF;
1250     if(!(myvbinfo & SetCRT2ToTV)) temp |= 0x0100;
1251     SiS_SetRegShort((acpibase + 0x3a), temp);
1252     temp = SiS_GetRegShort((acpibase + 0x3a));
1253  }
1254  #endif
1255  
1256  void
SiS_GetVBInfo(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,int checkcrt2mode)1257  SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
1258  		unsigned short ModeIdIndex, int checkcrt2mode)
1259  {
1260     unsigned short tempax, tempbx, temp;
1261     unsigned short modeflag, resinfo = 0;
1262  
1263     SiS_Pr->SiS_SetFlag = 0;
1264  
1265     modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
1266  
1267     SiS_Pr->SiS_ModeType = modeflag & ModeTypeMask;
1268  
1269     if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
1270        resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1271     }
1272  
1273     tempbx = 0;
1274  
1275     if(SiS_HaveBridge(SiS_Pr)) {
1276  
1277  	temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
1278  	tempbx |= temp;
1279  	tempax = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) << 8;
1280  	tempax &= (DriverMode | LoadDACFlag | SetNotSimuMode | SetPALTV);
1281  	tempbx |= tempax;
1282  
1283  #ifdef CONFIG_FB_SIS_315
1284  	if(SiS_Pr->ChipType >= SIS_315H) {
1285  	   if(SiS_Pr->SiS_VBType & VB_SISLCDA) {
1286  	      if(ModeNo == 0x03) {
1287  		 /* Mode 0x03 is never in driver mode */
1288  		 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf);
1289  	      }
1290  	      if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8))) {
1291  		 /* Reset LCDA setting if not driver mode */
1292  		 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
1293  	      }
1294  	      if(IS_SIS650) {
1295  		 if(SiS_Pr->SiS_UseLCDA) {
1296  		    if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) {
1297  		       if((ModeNo <= 0x13) || (!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) {
1298  			  SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA));
1299  		       }
1300  		    }
1301  		 }
1302  	      }
1303  	      temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1304  	      if((temp & (EnableDualEdge | SetToLCDA)) == (EnableDualEdge | SetToLCDA)) {
1305  		 tempbx |= SetCRT2ToLCDA;
1306  	      }
1307  	   }
1308  
1309  	   if(SiS_Pr->ChipType >= SIS_661) { /* New CR layout */
1310  	      tempbx &= ~(SetCRT2ToYPbPr525750 | SetCRT2ToHiVision);
1311  	      if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & 0x04) {
1312  		 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
1313  		 if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
1314  		 else if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1315  		    tempbx |= SetCRT2ToYPbPr525750;
1316  		 }
1317  	      }
1318  	   }
1319  
1320  	   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1321  	      temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1322  	      if(temp & SetToLCDA) {
1323  		 tempbx |= SetCRT2ToLCDA;
1324  	      }
1325  	      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1326  		 if(temp & EnableCHYPbPr) {
1327  		    tempbx |= SetCRT2ToCHYPbPr;
1328  		 }
1329  	      }
1330  	   }
1331  	}
1332  
1333  #endif  /* CONFIG_FB_SIS_315 */
1334  
1335          if(!(SiS_Pr->SiS_VBType & VB_SISVGA2)) {
1336  	   tempbx &= ~(SetCRT2ToRAMDAC);
1337  	}
1338  
1339  	if(SiS_Pr->SiS_VBType & VB_SISVB) {
1340  	   temp = SetCRT2ToSVIDEO   |
1341  		  SetCRT2ToAVIDEO   |
1342  		  SetCRT2ToSCART    |
1343  		  SetCRT2ToLCDA     |
1344  		  SetCRT2ToLCD      |
1345  		  SetCRT2ToRAMDAC   |
1346  		  SetCRT2ToHiVision |
1347  		  SetCRT2ToYPbPr525750;
1348  	} else {
1349  	   if(SiS_Pr->ChipType >= SIS_315H) {
1350  	      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1351  		 temp = SetCRT2ToAVIDEO |
1352  		        SetCRT2ToSVIDEO |
1353  		        SetCRT2ToSCART  |
1354  		        SetCRT2ToLCDA   |
1355  		        SetCRT2ToLCD    |
1356  		        SetCRT2ToCHYPbPr;
1357  	      } else {
1358  		 temp = SetCRT2ToLCDA   |
1359  		        SetCRT2ToLCD;
1360  	      }
1361  	   } else {
1362  	      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1363  		 temp = SetCRT2ToTV | SetCRT2ToLCD;
1364  	      } else {
1365  		 temp = SetCRT2ToLCD;
1366  	      }
1367  	   }
1368  	}
1369  
1370  	if(!(tempbx & temp)) {
1371  	   tempax = DisableCRT2Display;
1372  	   tempbx = 0;
1373  	}
1374  
1375  	if(SiS_Pr->SiS_VBType & VB_SISVB) {
1376  
1377  	   unsigned short clearmask = ( DriverMode |
1378  				DisableCRT2Display |
1379  				LoadDACFlag 	   |
1380  				SetNotSimuMode 	   |
1381  				SetInSlaveMode 	   |
1382  				SetPALTV 	   |
1383  				SwitchCRT2	   |
1384  				SetSimuScanMode );
1385  
1386  	   if(tempbx & SetCRT2ToLCDA)        tempbx &= (clearmask | SetCRT2ToLCDA);
1387  	   if(tempbx & SetCRT2ToRAMDAC)      tempbx &= (clearmask | SetCRT2ToRAMDAC);
1388  	   if(tempbx & SetCRT2ToLCD)         tempbx &= (clearmask | SetCRT2ToLCD);
1389  	   if(tempbx & SetCRT2ToSCART)       tempbx &= (clearmask | SetCRT2ToSCART);
1390  	   if(tempbx & SetCRT2ToHiVision)    tempbx &= (clearmask | SetCRT2ToHiVision);
1391  	   if(tempbx & SetCRT2ToYPbPr525750) tempbx &= (clearmask | SetCRT2ToYPbPr525750);
1392  
1393  	} else {
1394  
1395  	   if(SiS_Pr->ChipType >= SIS_315H) {
1396  	      if(tempbx & SetCRT2ToLCDA) {
1397  		 tempbx &= (0xFF00|SwitchCRT2|SetSimuScanMode);
1398  	      }
1399  	   }
1400  	   if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1401  	      if(tempbx & SetCRT2ToTV) {
1402  		 tempbx &= (0xFF00|SetCRT2ToTV|SwitchCRT2|SetSimuScanMode);
1403  	      }
1404  	   }
1405  	   if(tempbx & SetCRT2ToLCD) {
1406  	      tempbx &= (0xFF00|SetCRT2ToLCD|SwitchCRT2|SetSimuScanMode);
1407  	   }
1408  	   if(SiS_Pr->ChipType >= SIS_315H) {
1409  	      if(tempbx & SetCRT2ToLCDA) {
1410  	         tempbx |= SetCRT2ToLCD;
1411  	      }
1412  	   }
1413  
1414  	}
1415  
1416  	if(tempax & DisableCRT2Display) {
1417  	   if(!(tempbx & (SwitchCRT2 | SetSimuScanMode))) {
1418  	      tempbx = SetSimuScanMode | DisableCRT2Display;
1419  	   }
1420  	}
1421  
1422  	if(!(tempbx & DriverMode)) tempbx |= SetSimuScanMode;
1423  
1424  	/* LVDS/CHRONTEL (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */
1425  	if(SiS_Pr->SiS_ModeType <= ModeVGA) {
1426  	   if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
1427  	       ((SiS_Pr->SiS_VBType & VB_NoLCD) && (tempbx & SetCRT2ToLCD)) ) {
1428  	      modeflag &= (~CRT2Mode);
1429  	   }
1430  	}
1431  
1432  	if(!(tempbx & SetSimuScanMode)) {
1433  	   if(tempbx & SwitchCRT2) {
1434  	      if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1435  		 if(resinfo != SIS_RI_1600x1200) {
1436  		    tempbx |= SetSimuScanMode;
1437  		 }
1438                }
1439  	   } else {
1440  	      if(SiS_BridgeIsEnabled(SiS_Pr)) {
1441  		 if(!(tempbx & DriverMode)) {
1442  		    if(SiS_BridgeInSlavemode(SiS_Pr)) {
1443  		       tempbx |= SetSimuScanMode;
1444  		    }
1445  		 }
1446  	      }
1447  	   }
1448  	}
1449  
1450  	if(!(tempbx & DisableCRT2Display)) {
1451  	   if(tempbx & DriverMode) {
1452  	      if(tempbx & SetSimuScanMode) {
1453  		 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1454  		    if(resinfo != SIS_RI_1600x1200) {
1455  		       tempbx |= SetInSlaveMode;
1456  		    }
1457  		 }
1458  	      }
1459  	   } else {
1460  	      tempbx |= SetInSlaveMode;
1461  	   }
1462  	}
1463  
1464     }
1465  
1466     SiS_Pr->SiS_VBInfo = tempbx;
1467  
1468  #ifdef CONFIG_FB_SIS_300
1469     if(SiS_Pr->ChipType == SIS_630) {
1470        SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo);
1471     }
1472  #endif
1473  
1474  #if 0
1475     printk(KERN_DEBUG "sisfb: (init301: VBInfo= 0x%04x, SetFlag=0x%04x)\n",
1476        SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
1477  #endif
1478  }
1479  
1480  /*********************************************/
1481  /*           DETERMINE YPbPr MODE            */
1482  /*********************************************/
1483  
1484  void
SiS_SetYPbPr(struct SiS_Private * SiS_Pr)1485  SiS_SetYPbPr(struct SiS_Private *SiS_Pr)
1486  {
1487  
1488     unsigned char temp;
1489  
1490     /* Note: This variable is only used on 30xLV systems.
1491      * CR38 has a different meaning on LVDS/CH7019 systems.
1492      * On 661 and later, these bits moved to CR35.
1493      *
1494      * On 301, 301B, only HiVision 1080i is supported.
1495      * On 30xLV, 301C, only YPbPr 1080i is supported.
1496      */
1497  
1498     SiS_Pr->SiS_YPbPr = 0;
1499     if(SiS_Pr->ChipType >= SIS_661) return;
1500  
1501     if(SiS_Pr->SiS_VBType) {
1502        if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1503  	 SiS_Pr->SiS_YPbPr = YPbPrHiVision;
1504        }
1505     }
1506  
1507     if(SiS_Pr->ChipType >= SIS_315H) {
1508        if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1509  	 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1510  	 if(temp & 0x08) {
1511  	    switch((temp >> 4)) {
1512  	    case 0x00: SiS_Pr->SiS_YPbPr = YPbPr525i;     break;
1513  	    case 0x01: SiS_Pr->SiS_YPbPr = YPbPr525p;     break;
1514  	    case 0x02: SiS_Pr->SiS_YPbPr = YPbPr750p;     break;
1515  	    case 0x03: SiS_Pr->SiS_YPbPr = YPbPrHiVision; break;
1516  	    }
1517  	 }
1518        }
1519     }
1520  
1521  }
1522  
1523  /*********************************************/
1524  /*           DETERMINE TVMode flag           */
1525  /*********************************************/
1526  
1527  void
SiS_SetTVMode(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)1528  SiS_SetTVMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
1529  {
1530     unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
1531     unsigned short temp, temp1, resinfo = 0, romindex = 0;
1532     unsigned char  OutputSelect = *SiS_Pr->pSiS_OutputSelect;
1533  
1534     SiS_Pr->SiS_TVMode = 0;
1535  
1536     if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
1537     if(SiS_Pr->UseCustomMode) return;
1538  
1539     if(ModeNo > 0x13) {
1540        resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1541     }
1542  
1543     if(SiS_Pr->ChipType < SIS_661) {
1544  
1545        if(SiS_Pr->SiS_VBInfo & SetPALTV) SiS_Pr->SiS_TVMode |= TVSetPAL;
1546  
1547        if(SiS_Pr->SiS_VBType & VB_SISVB) {
1548  	 temp = 0;
1549  	 if((SiS_Pr->ChipType == SIS_630) ||
1550  	    (SiS_Pr->ChipType == SIS_730)) {
1551  	    temp = 0x35;
1552  	    romindex = 0xfe;
1553  	 } else if(SiS_Pr->ChipType >= SIS_315H) {
1554  	    temp = 0x38;
1555  	    if(SiS_Pr->ChipType < XGI_20) {
1556  	       romindex = 0xf3;
1557  	       if(SiS_Pr->ChipType >= SIS_330) romindex = 0x11b;
1558  	    }
1559  	 }
1560  	 if(temp) {
1561  	    if(romindex && SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
1562  	       OutputSelect = ROMAddr[romindex];
1563  	       if(!(OutputSelect & EnablePALMN)) {
1564  		  SiS_SetRegAND(SiS_Pr->SiS_P3d4,temp,0x3F);
1565  	       }
1566  	    }
1567  	    temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,temp);
1568  	    if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1569  	       if(temp1 & EnablePALM) {		/* 0x40 */
1570  		  SiS_Pr->SiS_TVMode |= TVSetPALM;
1571  		  SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1572  	       } else if(temp1 & EnablePALN) {	/* 0x80 */
1573  		  SiS_Pr->SiS_TVMode |= TVSetPALN;
1574  	       }
1575  	    } else {
1576  	       if(temp1 & EnableNTSCJ) {	/* 0x40 */
1577  		  SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1578  	       }
1579  	    }
1580  	 }
1581  	 /* Translate HiVision/YPbPr to our new flags */
1582  	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1583  	    if(SiS_Pr->SiS_YPbPr == YPbPr750p)          SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1584  	    else if(SiS_Pr->SiS_YPbPr == YPbPr525p)     SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1585  	    else if(SiS_Pr->SiS_YPbPr == YPbPrHiVision) SiS_Pr->SiS_TVMode |= TVSetHiVision;
1586  	    else				        SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1587  	    if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p | TVSetYPbPr525i)) {
1588  	       SiS_Pr->SiS_VBInfo &= ~SetCRT2ToHiVision;
1589  	       SiS_Pr->SiS_VBInfo |= SetCRT2ToYPbPr525750;
1590  	    } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
1591  	       SiS_Pr->SiS_TVMode |= TVSetPAL;
1592  	    }
1593  	 }
1594        } else if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1595  	 if(SiS_Pr->SiS_CHOverScan) {
1596  	    if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
1597  	       temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1598  	       if((temp & TVOverScan) || (SiS_Pr->SiS_CHOverScan == 1)) {
1599  		  SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1600  	       }
1601  	    } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1602  	       temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79);
1603  	       if((temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1)) {
1604  		  SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1605  	       }
1606  	    }
1607  	    if(SiS_Pr->SiS_CHSOverScan) {
1608  	       SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1609  	    }
1610  	 }
1611  	 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1612  	    temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1613  	    if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1614  	       if(temp & EnablePALM)      SiS_Pr->SiS_TVMode |= TVSetPALM;
1615  	       else if(temp & EnablePALN) SiS_Pr->SiS_TVMode |= TVSetPALN;
1616  	    } else {
1617  	       if(temp & EnableNTSCJ) {
1618  		  SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1619  	       }
1620  	    }
1621  	 }
1622        }
1623  
1624     } else {  /* 661 and later */
1625  
1626        temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1627        if(temp1 & 0x01) {
1628  	 SiS_Pr->SiS_TVMode |= TVSetPAL;
1629  	 if(temp1 & 0x08) {
1630  	    SiS_Pr->SiS_TVMode |= TVSetPALN;
1631  	 } else if(temp1 & 0x04) {
1632  	    if(SiS_Pr->SiS_VBType & VB_SISVB) {
1633  	       SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1634  	    }
1635  	    SiS_Pr->SiS_TVMode |= TVSetPALM;
1636  	 }
1637        } else {
1638  	 if(temp1 & 0x02) {
1639  	    SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1640  	 }
1641        }
1642        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1643  	 if(SiS_Pr->SiS_CHOverScan) {
1644  	    if((temp1 & 0x10) || (SiS_Pr->SiS_CHOverScan == 1)) {
1645  	       SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1646  	    }
1647  	 }
1648        }
1649        if(SiS_Pr->SiS_VBType & VB_SISVB) {
1650  	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1651  	    temp1 &= 0xe0;
1652  	    if(temp1 == 0x00)      SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1653  	    else if(temp1 == 0x20) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1654  	    else if(temp1 == 0x40) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1655  	 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1656  	    SiS_Pr->SiS_TVMode |= (TVSetHiVision | TVSetPAL);
1657  	 }
1658  	 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750 | SetCRT2ToHiVision)) {
1659  	    if(resinfo == SIS_RI_800x480 || resinfo == SIS_RI_1024x576 || resinfo == SIS_RI_1280x720) {
1660  	       SiS_Pr->SiS_TVMode |= TVAspect169;
1661  	    } else {
1662  	       temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x39);
1663  	       if(temp1 & 0x02) {
1664  		  if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetHiVision)) {
1665  		     SiS_Pr->SiS_TVMode |= TVAspect169;
1666  		  } else {
1667  		     SiS_Pr->SiS_TVMode |= TVAspect43LB;
1668  		  }
1669  	       } else {
1670  		  SiS_Pr->SiS_TVMode |= TVAspect43;
1671  	       }
1672  	    }
1673  	 }
1674        }
1675     }
1676  
1677     if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) SiS_Pr->SiS_TVMode |= TVSetPAL;
1678  
1679     if(SiS_Pr->SiS_VBType & VB_SISVB) {
1680  
1681        if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1682  	 SiS_Pr->SiS_TVMode |= TVSetPAL;
1683  	 SiS_Pr->SiS_TVMode &= ~(TVSetPALM | TVSetPALN | TVSetNTSCJ);
1684        } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1685  	 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525i | TVSetYPbPr525p | TVSetYPbPr750p)) {
1686  	    SiS_Pr->SiS_TVMode &= ~(TVSetPAL | TVSetNTSCJ | TVSetPALM | TVSetPALN);
1687  	 }
1688        }
1689  
1690        if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
1691  	 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
1692  	    SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
1693  	 }
1694        }
1695  
1696        if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
1697  	 if(resinfo == SIS_RI_1024x768) {
1698  	    if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
1699  	       SiS_Pr->SiS_TVMode |= TVSet525p1024;
1700  	    } else if(!(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p))) {
1701  	       SiS_Pr->SiS_TVMode |= TVSetNTSC1024;
1702  	    }
1703  	 }
1704        }
1705  
1706        SiS_Pr->SiS_TVMode |= TVRPLLDIV2XO;
1707        if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) &&
1708  	 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
1709  	 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1710        } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
1711  	 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1712        } else if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) {
1713  	 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
1714  	    SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1715  	 }
1716        }
1717  
1718     }
1719  
1720     SiS_Pr->SiS_VBInfo &= ~SetPALTV;
1721  }
1722  
1723  /*********************************************/
1724  /*               GET LCD INFO                */
1725  /*********************************************/
1726  
1727  static unsigned short
SiS_GetBIOSLCDResInfo(struct SiS_Private * SiS_Pr)1728  SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr)
1729  {
1730     unsigned short temp = SiS_Pr->SiS_LCDResInfo;
1731     /* Translate my LCDResInfo to BIOS value */
1732     switch(temp) {
1733     case Panel_1280x768_2: temp = Panel_1280x768;    break;
1734     case Panel_1280x800_2: temp = Panel_1280x800;    break;
1735     case Panel_1280x854:   temp = Panel661_1280x854; break;
1736     }
1737     return temp;
1738  }
1739  
1740  static void
SiS_GetLCDInfoBIOS(struct SiS_Private * SiS_Pr)1741  SiS_GetLCDInfoBIOS(struct SiS_Private *SiS_Pr)
1742  {
1743  #ifdef CONFIG_FB_SIS_315
1744     unsigned char  *ROMAddr;
1745     unsigned short temp;
1746  
1747     if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
1748        if((temp = SISGETROMW(6)) != SiS_Pr->PanelHT) {
1749  	 SiS_Pr->SiS_NeedRomModeData = true;
1750  	 SiS_Pr->PanelHT  = temp;
1751        }
1752        if((temp = SISGETROMW(8)) != SiS_Pr->PanelVT) {
1753  	 SiS_Pr->SiS_NeedRomModeData = true;
1754  	 SiS_Pr->PanelVT  = temp;
1755        }
1756        SiS_Pr->PanelHRS = SISGETROMW(10);
1757        SiS_Pr->PanelHRE = SISGETROMW(12);
1758        SiS_Pr->PanelVRS = SISGETROMW(14);
1759        SiS_Pr->PanelVRE = SISGETROMW(16);
1760        SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
1761        SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].CLOCK =
1762  	 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].CLOCK = (unsigned short)((unsigned char)ROMAddr[18]);
1763        SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2B =
1764  	 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_A = ROMAddr[19];
1765        SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2C =
1766  	 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_B = ROMAddr[20];
1767  
1768     }
1769  #endif
1770  }
1771  
1772  static void
SiS_CheckScaling(struct SiS_Private * SiS_Pr,unsigned short resinfo,const unsigned char * nonscalingmodes)1773  SiS_CheckScaling(struct SiS_Private *SiS_Pr, unsigned short resinfo,
1774  			const unsigned char *nonscalingmodes)
1775  {
1776     int i = 0;
1777     while(nonscalingmodes[i] != 0xff) {
1778        if(nonscalingmodes[i++] == resinfo) {
1779  	 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ||
1780  	    (SiS_Pr->UsePanelScaler == -1)) {
1781  	    SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1782  	 }
1783  	 break;
1784        }
1785     }
1786  }
1787  
1788  void
SiS_GetLCDResInfo(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)1789  SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
1790  {
1791    unsigned short temp,modeflag,resinfo=0,modexres=0,modeyres=0;
1792    bool panelcanscale = false;
1793  #ifdef CONFIG_FB_SIS_300
1794    unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
1795    static const unsigned char SiS300SeriesLCDRes[] =
1796            { 0,  1,  2,  3,  7,  4,  5,  8,
1797  	    0,  0, 10,  0,  0,  0,  0, 15 };
1798  #endif
1799  #ifdef CONFIG_FB_SIS_315
1800    unsigned char   *myptr = NULL;
1801  #endif
1802  
1803    SiS_Pr->SiS_LCDResInfo  = 0;
1804    SiS_Pr->SiS_LCDTypeInfo = 0;
1805    SiS_Pr->SiS_LCDInfo     = 0;
1806    SiS_Pr->PanelHRS        = 999; /* HSync start */
1807    SiS_Pr->PanelHRE        = 999; /* HSync end */
1808    SiS_Pr->PanelVRS        = 999; /* VSync start */
1809    SiS_Pr->PanelVRE        = 999; /* VSync end */
1810    SiS_Pr->SiS_NeedRomModeData = false;
1811  
1812    /* Alternative 1600x1200@60 timing for 1600x1200 LCDA */
1813    SiS_Pr->Alternate1600x1200 = false;
1814  
1815    if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return;
1816  
1817    modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
1818  
1819    if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
1820       resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1821       modexres = SiS_Pr->SiS_ModeResInfo[resinfo].HTotal;
1822       modeyres = SiS_Pr->SiS_ModeResInfo[resinfo].VTotal;
1823    }
1824  
1825    temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
1826  
1827    /* For broken BIOSes: Assume 1024x768 */
1828    if(temp == 0) temp = 0x02;
1829  
1830    if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
1831       SiS_Pr->SiS_LCDTypeInfo = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x7c) >> 2;
1832    } else if((SiS_Pr->ChipType < SIS_315H) || (SiS_Pr->ChipType >= SIS_661)) {
1833       SiS_Pr->SiS_LCDTypeInfo = temp >> 4;
1834    } else {
1835       SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1;
1836    }
1837    temp &= 0x0f;
1838  #ifdef CONFIG_FB_SIS_300
1839    if(SiS_Pr->ChipType < SIS_315H) {
1840       /* Very old BIOSes only know 7 sizes (NetVista 2179, 1.01g) */
1841       if(SiS_Pr->SiS_VBType & VB_SIS301) {
1842          if(temp < 0x0f) temp &= 0x07;
1843       }
1844       /* Translate 300 series LCDRes to 315 series for unified usage */
1845       temp = SiS300SeriesLCDRes[temp];
1846    }
1847  #endif
1848  
1849    /* Translate to our internal types */
1850  #ifdef CONFIG_FB_SIS_315
1851    if(SiS_Pr->ChipType == SIS_550) {
1852       if     (temp == Panel310_1152x768)  temp = Panel_320x240_2; /* Verified working */
1853       else if(temp == Panel310_320x240_2) temp = Panel_320x240_2;
1854       else if(temp == Panel310_320x240_3) temp = Panel_320x240_3;
1855    } else if(SiS_Pr->ChipType >= SIS_661) {
1856       if(temp == Panel661_1280x854)       temp = Panel_1280x854;
1857    }
1858  #endif
1859  
1860    if(SiS_Pr->SiS_VBType & VB_SISLVDS) {		/* SiS LVDS */
1861       if(temp == Panel310_1280x768) {
1862          temp = Panel_1280x768_2;
1863       }
1864       if(SiS_Pr->SiS_ROMNew) {
1865  	if(temp == Panel661_1280x800) {
1866  	   temp = Panel_1280x800_2;
1867  	}
1868       }
1869    }
1870  
1871    SiS_Pr->SiS_LCDResInfo = temp;
1872  
1873  #ifdef CONFIG_FB_SIS_300
1874    if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1875       if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
1876  	SiS_Pr->SiS_LCDResInfo = Panel_Barco1366;
1877       } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
1878  	SiS_Pr->SiS_LCDResInfo = Panel_848x480;
1879       } else if(SiS_Pr->SiS_CustomT == CUT_PANEL856) {
1880  	SiS_Pr->SiS_LCDResInfo = Panel_856x480;
1881       }
1882    }
1883  #endif
1884  
1885    if(SiS_Pr->SiS_VBType & VB_SISVB) {
1886       if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)
1887  	SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMin301;
1888    } else {
1889       if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMinLVDS)
1890  	SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS;
1891    }
1892  
1893    temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
1894    SiS_Pr->SiS_LCDInfo = temp & ~0x000e;
1895    /* Need temp below! */
1896  
1897    /* These must/can't scale no matter what */
1898    switch(SiS_Pr->SiS_LCDResInfo) {
1899    case Panel_320x240_1:
1900    case Panel_320x240_2:
1901    case Panel_320x240_3:
1902    case Panel_1280x960:
1903        SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1904        break;
1905    case Panel_640x480:
1906        SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1907    }
1908  
1909    panelcanscale = (bool)(SiS_Pr->SiS_LCDInfo & DontExpandLCD);
1910  
1911    if(!SiS_Pr->UsePanelScaler)          SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1912    else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1913  
1914    /* Dual link, Pass 1:1 BIOS default, etc. */
1915  #ifdef CONFIG_FB_SIS_315
1916    if(SiS_Pr->ChipType >= SIS_661) {
1917       if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1918  	if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1919       }
1920       if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1921  	if(SiS_Pr->SiS_ROMNew) {
1922  	   if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1923  	} else if((myptr = GetLCDStructPtr661(SiS_Pr))) {
1924  	   if(myptr[2] & 0x01) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1925  	}
1926       }
1927    } else if(SiS_Pr->ChipType >= SIS_315H) {
1928       if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1929  	if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1930       }
1931       if((SiS_Pr->SiS_ROMNew) && (!(SiS_Pr->PanelSelfDetected))) {
1932  	SiS_Pr->SiS_LCDInfo &= ~(LCDRGB18Bit);
1933  	temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1934  	if(temp & 0x01) SiS_Pr->SiS_LCDInfo |= LCDRGB18Bit;
1935  	if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1936  	   if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1937  	}
1938       } else if(!(SiS_Pr->SiS_ROMNew)) {
1939  	if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1940  	   if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) &&
1941  	      (SiS_Pr->SiS_LCDResInfo == Panel_1024x768)) {
1942  	      SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1943  	   }
1944  	   if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
1945  	      (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
1946  	      (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
1947  	      (SiS_Pr->SiS_LCDResInfo == Panel_1680x1050)) {
1948  	      SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1949  	   }
1950  	}
1951       }
1952    }
1953  #endif
1954  
1955    /* Pass 1:1 */
1956    if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
1957       /* Always center screen on LVDS (if scaling is disabled) */
1958       SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1959    } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
1960       if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
1961  	/* Always center screen on SiS LVDS (if scaling is disabled) */
1962  	SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1963       } else {
1964  	/* By default, pass 1:1 on SiS TMDS (if scaling is supported) */
1965  	if(panelcanscale)             SiS_Pr->SiS_LCDInfo |= LCDPass11;
1966  	if(SiS_Pr->CenterScreen == 1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1967       }
1968    }
1969  
1970    SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1971    SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1972  
1973    switch(SiS_Pr->SiS_LCDResInfo) {
1974       case Panel_320x240_1:
1975       case Panel_320x240_2:
1976       case Panel_320x240_3:  SiS_Pr->PanelXRes =  640; SiS_Pr->PanelYRes =  480;
1977  			    SiS_Pr->PanelVRS  =   24; SiS_Pr->PanelVRE  =    3;
1978  			    SiS_Pr->PanelVCLKIdx300 = VCLK28;
1979  			    SiS_Pr->PanelVCLKIdx315 = VCLK28;
1980  			    break;
1981       case Panel_640x480:    SiS_Pr->PanelXRes =  640; SiS_Pr->PanelYRes =  480;
1982  						      SiS_Pr->PanelVRE  =    3;
1983  			    SiS_Pr->PanelVCLKIdx300 = VCLK28;
1984  			    SiS_Pr->PanelVCLKIdx315 = VCLK28;
1985  			    break;
1986       case Panel_800x600:    SiS_Pr->PanelXRes =  800; SiS_Pr->PanelYRes =  600;
1987       			    SiS_Pr->PanelHT   = 1056; SiS_Pr->PanelVT   =  628;
1988  			    SiS_Pr->PanelHRS  =   40; SiS_Pr->PanelHRE  =  128;
1989  			    SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    4;
1990  			    SiS_Pr->PanelVCLKIdx300 = VCLK40;
1991  			    SiS_Pr->PanelVCLKIdx315 = VCLK40;
1992  			    break;
1993       case Panel_1024x600:   SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  600;
1994  			    SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  800;
1995  			    SiS_Pr->PanelHRS  =   24; SiS_Pr->PanelHRE  =  136;
1996  			    SiS_Pr->PanelVRS  =    2 /* 88 */ ; SiS_Pr->PanelVRE  =    6;
1997  			    SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1998  			    SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1999  			    break;
2000       case Panel_1024x768:   SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  768;
2001  			    SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  806;
2002  			    SiS_Pr->PanelHRS  =   24; SiS_Pr->PanelHRE  =  136;
2003  			    SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
2004  			    if(SiS_Pr->ChipType < SIS_315H) {
2005  			       SiS_Pr->PanelHRS = 23;
2006  						      SiS_Pr->PanelVRE  =    5;
2007  			    }
2008  			    SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
2009  			    SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
2010  			    SiS_GetLCDInfoBIOS(SiS_Pr);
2011  			    break;
2012       case Panel_1152x768:   SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes =  768;
2013  			    SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  806;
2014  			    SiS_Pr->PanelHRS  =   24; SiS_Pr->PanelHRE  =  136;
2015  			    SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
2016  			    if(SiS_Pr->ChipType < SIS_315H) {
2017  			       SiS_Pr->PanelHRS = 23;
2018  						      SiS_Pr->PanelVRE  =    5;
2019  			    }
2020  			    SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
2021  			    SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
2022  			    break;
2023       case Panel_1152x864:   SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes =  864;
2024  			    break;
2025       case Panel_1280x720:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  720;
2026  			    SiS_Pr->PanelHT   = 1650; SiS_Pr->PanelVT   =  750;
2027  			    SiS_Pr->PanelHRS  =  110; SiS_Pr->PanelHRE  =   40;
2028  			    SiS_Pr->PanelVRS  =    5; SiS_Pr->PanelVRE  =    5;
2029  			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x720;
2030  			    /* Data above for TMDS (projector); get from BIOS for LVDS */
2031  			    SiS_GetLCDInfoBIOS(SiS_Pr);
2032  			    break;
2033       case Panel_1280x768:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  768;
2034  			    if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2035  			       SiS_Pr->PanelHT   = 1408; SiS_Pr->PanelVT   =  806;
2036  			       SiS_Pr->PanelVCLKIdx300 = VCLK81_300; /* ? */
2037  			       SiS_Pr->PanelVCLKIdx315 = VCLK81_315; /* ? */
2038  			    } else {
2039  			       SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   =  802;
2040  			       SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112;
2041  			       SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
2042  			       SiS_Pr->PanelVCLKIdx300 = VCLK81_300;
2043  			       SiS_Pr->PanelVCLKIdx315 = VCLK81_315;
2044  			    }
2045  			    break;
2046       case Panel_1280x768_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  768;
2047  			    SiS_Pr->PanelHT   = 1660; SiS_Pr->PanelVT   =  806;
2048  			    SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112;
2049  			    SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
2050  			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_2;
2051  			    SiS_GetLCDInfoBIOS(SiS_Pr);
2052  			    break;
2053       case Panel_1280x800:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  800;
2054  			    SiS_Pr->PanelHT   = 1408; SiS_Pr->PanelVT   =  816;
2055  			    SiS_Pr->PanelHRS   =  21; SiS_Pr->PanelHRE  =   24;
2056  			    SiS_Pr->PanelVRS   =   4; SiS_Pr->PanelVRE  =    3;
2057  			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315;
2058  			    SiS_GetLCDInfoBIOS(SiS_Pr);
2059  			    break;
2060       case Panel_1280x800_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  800;
2061  			    SiS_Pr->PanelHT   = 1552; SiS_Pr->PanelVT   =  812;
2062  			    SiS_Pr->PanelHRS   =  48; SiS_Pr->PanelHRE  =  112;
2063  			    SiS_Pr->PanelVRS   =   4; SiS_Pr->PanelVRE  =    3;
2064  			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315_2;
2065  			    SiS_GetLCDInfoBIOS(SiS_Pr);
2066  			    break;
2067       case Panel_1280x854:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  854;
2068  			    SiS_Pr->PanelHT   = 1664; SiS_Pr->PanelVT   =  861;
2069  			    SiS_Pr->PanelHRS   =  16; SiS_Pr->PanelHRE  =  112;
2070  			    SiS_Pr->PanelVRS   =   1; SiS_Pr->PanelVRE  =    3;
2071  			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x854;
2072  			    SiS_GetLCDInfoBIOS(SiS_Pr);
2073  			    break;
2074       case Panel_1280x960:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  960;
2075  			    SiS_Pr->PanelHT   = 1800; SiS_Pr->PanelVT   = 1000;
2076  			    SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
2077  			    SiS_Pr->PanelVCLKIdx315 = VCLK108_3_315;
2078  			    if(resinfo == SIS_RI_1280x1024) {
2079  			       SiS_Pr->PanelVCLKIdx300 = VCLK100_300;
2080  			       SiS_Pr->PanelVCLKIdx315 = VCLK100_315;
2081  			    }
2082  			    break;
2083       case Panel_1280x1024:  SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024;
2084  			    SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   = 1066;
2085  			    SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112;
2086  			    SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    3;
2087  			    SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
2088  			    SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
2089  			    SiS_GetLCDInfoBIOS(SiS_Pr);
2090  			    break;
2091       case Panel_1400x1050:  SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050;
2092  			    SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   = 1066;
2093  			    SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112;
2094  			    SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    3;
2095  			    SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
2096  			    SiS_GetLCDInfoBIOS(SiS_Pr);
2097  			    break;
2098       case Panel_1600x1200:  SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200;
2099  			    SiS_Pr->PanelHT   = 2160; SiS_Pr->PanelVT   = 1250;
2100  			    SiS_Pr->PanelHRS  =   64; SiS_Pr->PanelHRE  =  192;
2101  			    SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    3;
2102  			    SiS_Pr->PanelVCLKIdx315 = VCLK162_315;
2103  			    if(SiS_Pr->SiS_VBType & VB_SISTMDSLCDA) {
2104  			       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
2105  				  SiS_Pr->PanelHT  = 1760; SiS_Pr->PanelVT  = 1235;
2106  				  SiS_Pr->PanelHRS =   48; SiS_Pr->PanelHRE =   32;
2107  				  SiS_Pr->PanelVRS =    2; SiS_Pr->PanelVRE =    4;
2108  				  SiS_Pr->PanelVCLKIdx315 = VCLK130_315;
2109  				  SiS_Pr->Alternate1600x1200 = true;
2110  			       }
2111  			    } else if(SiS_Pr->SiS_IF_DEF_LVDS) {
2112  			       SiS_Pr->PanelHT  = 2048; SiS_Pr->PanelVT  = 1320;
2113  			       SiS_Pr->PanelHRS = SiS_Pr->PanelHRE = 999;
2114  			       SiS_Pr->PanelVRS = SiS_Pr->PanelVRE = 999;
2115  			    }
2116  			    SiS_GetLCDInfoBIOS(SiS_Pr);
2117  			    break;
2118       case Panel_1680x1050:  SiS_Pr->PanelXRes = 1680; SiS_Pr->PanelYRes = 1050;
2119  			    SiS_Pr->PanelHT   = 1900; SiS_Pr->PanelVT   = 1066;
2120  			    SiS_Pr->PanelHRS  =   26; SiS_Pr->PanelHRE  =   76;
2121  			    SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
2122  			    SiS_Pr->PanelVCLKIdx315 = VCLK121_315;
2123  			    SiS_GetLCDInfoBIOS(SiS_Pr);
2124  			    break;
2125       case Panel_Barco1366:  SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024;
2126  			    SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   = 1066;
2127  			    break;
2128       case Panel_848x480:    SiS_Pr->PanelXRes =  848; SiS_Pr->PanelYRes =  480;
2129  			    SiS_Pr->PanelHT   = 1088; SiS_Pr->PanelVT   =  525;
2130  			    break;
2131       case Panel_856x480:    SiS_Pr->PanelXRes =  856; SiS_Pr->PanelYRes =  480;
2132  			    SiS_Pr->PanelHT   = 1088; SiS_Pr->PanelVT   =  525;
2133  			    break;
2134       case Panel_Custom:     SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX;
2135  			    SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY;
2136  			    SiS_Pr->PanelHT   = SiS_Pr->CHTotal;
2137  			    SiS_Pr->PanelVT   = SiS_Pr->CVTotal;
2138  			    if(SiS_Pr->CP_PreferredIndex != -1) {
2139  			       SiS_Pr->PanelXRes = SiS_Pr->CP_HDisplay[SiS_Pr->CP_PreferredIndex];
2140  			       SiS_Pr->PanelYRes = SiS_Pr->CP_VDisplay[SiS_Pr->CP_PreferredIndex];
2141  			       SiS_Pr->PanelHT   = SiS_Pr->CP_HTotal[SiS_Pr->CP_PreferredIndex];
2142  			       SiS_Pr->PanelVT   = SiS_Pr->CP_VTotal[SiS_Pr->CP_PreferredIndex];
2143  			       SiS_Pr->PanelHRS  = SiS_Pr->CP_HSyncStart[SiS_Pr->CP_PreferredIndex];
2144  			       SiS_Pr->PanelHRE  = SiS_Pr->CP_HSyncEnd[SiS_Pr->CP_PreferredIndex];
2145  			       SiS_Pr->PanelVRS  = SiS_Pr->CP_VSyncStart[SiS_Pr->CP_PreferredIndex];
2146  			       SiS_Pr->PanelVRE  = SiS_Pr->CP_VSyncEnd[SiS_Pr->CP_PreferredIndex];
2147  			       SiS_Pr->PanelHRS -= SiS_Pr->PanelXRes;
2148  			       SiS_Pr->PanelHRE -= SiS_Pr->PanelHRS;
2149  			       SiS_Pr->PanelVRS -= SiS_Pr->PanelYRes;
2150  			       SiS_Pr->PanelVRE -= SiS_Pr->PanelVRS;
2151  			       if(SiS_Pr->CP_PrefClock) {
2152  				  int idx;
2153  				  SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
2154  				  SiS_Pr->PanelVCLKIdx300 = VCLK_CUSTOM_300;
2155  				  if(SiS_Pr->ChipType < SIS_315H) idx = VCLK_CUSTOM_300;
2156  				  else				   idx = VCLK_CUSTOM_315;
2157  				  SiS_Pr->SiS_VCLKData[idx].CLOCK =
2158  				     SiS_Pr->SiS_VBVCLKData[idx].CLOCK = SiS_Pr->CP_PrefClock;
2159  				  SiS_Pr->SiS_VCLKData[idx].SR2B =
2160  				     SiS_Pr->SiS_VBVCLKData[idx].Part4_A = SiS_Pr->CP_PrefSR2B;
2161  				  SiS_Pr->SiS_VCLKData[idx].SR2C =
2162  				     SiS_Pr->SiS_VBVCLKData[idx].Part4_B = SiS_Pr->CP_PrefSR2C;
2163  			       }
2164  			    }
2165  			    break;
2166       default:		    SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  768;
2167  			    SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  806;
2168  			    break;
2169    }
2170  
2171    /* Special cases */
2172    if( (SiS_Pr->SiS_IF_DEF_FSTN)              ||
2173        (SiS_Pr->SiS_IF_DEF_DSTN)              ||
2174        (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
2175        (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
2176        (SiS_Pr->SiS_CustomT == CUT_PANEL848)  ||
2177        (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
2178       SiS_Pr->PanelHRS = 999;
2179       SiS_Pr->PanelHRE = 999;
2180    }
2181  
2182    if( (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
2183        (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
2184        (SiS_Pr->SiS_CustomT == CUT_PANEL848)  ||
2185        (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
2186       SiS_Pr->PanelVRS = 999;
2187       SiS_Pr->PanelVRE = 999;
2188    }
2189  
2190    /* DontExpand overrule */
2191    if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
2192  
2193       if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (modeflag & NoSupportLCDScale)) {
2194  	/* No scaling for this mode on any panel (LCD=CRT2)*/
2195  	SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2196       }
2197  
2198       switch(SiS_Pr->SiS_LCDResInfo) {
2199  
2200       case Panel_Custom:
2201       case Panel_1152x864:
2202       case Panel_1280x768:	/* TMDS only */
2203  	SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2204  	break;
2205  
2206       case Panel_800x600: {
2207  	static const unsigned char nonscalingmodes[] = {
2208  	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, 0xff
2209  	};
2210  	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2211  	break;
2212       }
2213       case Panel_1024x768: {
2214  	static const unsigned char nonscalingmodes[] = {
2215  	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2216  	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2217  	   0xff
2218  	};
2219  	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2220  	break;
2221       }
2222       case Panel_1280x720: {
2223  	static const unsigned char nonscalingmodes[] = {
2224  	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2225  	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2226  	   0xff
2227  	};
2228  	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2229  	if(SiS_Pr->PanelHT == 1650) {
2230  	   SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2231  	}
2232  	break;
2233       }
2234       case Panel_1280x768_2: {  /* LVDS only */
2235  	static const unsigned char nonscalingmodes[] = {
2236  	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2237  	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2238  	   SIS_RI_1152x768,0xff
2239  	};
2240  	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2241  	switch(resinfo) {
2242  	case SIS_RI_1280x720:  if(SiS_Pr->UsePanelScaler == -1) {
2243  				  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2244  			       }
2245  			       break;
2246  	}
2247  	break;
2248       }
2249       case Panel_1280x800: {  	/* SiS TMDS special (Averatec 6200 series) */
2250  	static const unsigned char nonscalingmodes[] = {
2251  	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2252  	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2253  	   SIS_RI_1152x768,SIS_RI_1280x720,SIS_RI_1280x768,0xff
2254  	};
2255  	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2256  	break;
2257       }
2258       case Panel_1280x800_2:  { 	/* SiS LVDS */
2259  	static const unsigned char nonscalingmodes[] = {
2260  	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2261  	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2262  	   SIS_RI_1152x768,0xff
2263  	};
2264  	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2265  	switch(resinfo) {
2266  	case SIS_RI_1280x720:
2267  	case SIS_RI_1280x768:  if(SiS_Pr->UsePanelScaler == -1) {
2268  				  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2269  			       }
2270  			       break;
2271  	}
2272  	break;
2273       }
2274       case Panel_1280x854: {  	/* SiS LVDS */
2275  	static const unsigned char nonscalingmodes[] = {
2276  	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2277  	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2278  	   SIS_RI_1152x768,0xff
2279  	};
2280  	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2281  	switch(resinfo) {
2282  	case SIS_RI_1280x720:
2283  	case SIS_RI_1280x768:
2284  	case SIS_RI_1280x800:  if(SiS_Pr->UsePanelScaler == -1) {
2285  				  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2286  			       }
2287  			       break;
2288  	}
2289  	break;
2290       }
2291       case Panel_1280x960: {
2292  	static const unsigned char nonscalingmodes[] = {
2293  	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2294  	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2295  	   SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2296  	   SIS_RI_1280x854,0xff
2297  	};
2298  	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2299  	break;
2300       }
2301       case Panel_1280x1024: {
2302  	static const unsigned char nonscalingmodes[] = {
2303  	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2304  	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2305  	   SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2306  	   SIS_RI_1280x854,SIS_RI_1280x960,0xff
2307  	};
2308  	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2309  	break;
2310       }
2311       case Panel_1400x1050: {
2312  	static const unsigned char nonscalingmodes[] = {
2313  	     SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2314  	     SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2315  	     SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x768,SIS_RI_1280x800,SIS_RI_1280x854,
2316  	     SIS_RI_1280x960,0xff
2317  	};
2318  	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2319  	switch(resinfo) {
2320  	case SIS_RI_1280x720:  if(SiS_Pr->UsePanelScaler == -1) {
2321  				  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2322  			       }
2323  			       break;
2324  	case SIS_RI_1280x1024: SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2325  			       break;
2326  	}
2327  	break;
2328       }
2329       case Panel_1600x1200: {
2330  	static const unsigned char nonscalingmodes[] = {
2331  	     SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2332  	     SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2333  	     SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2334  	     SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,SIS_RI_1360x1024,0xff
2335  	};
2336  	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2337  	break;
2338       }
2339       case Panel_1680x1050: {
2340  	static const unsigned char nonscalingmodes[] = {
2341  	     SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2342  	     SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2343  	     SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,
2344  	     SIS_RI_1360x1024,0xff
2345  	};
2346  	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2347  	break;
2348       }
2349       }
2350    }
2351  
2352  #ifdef CONFIG_FB_SIS_300
2353    if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2354       if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
2355  	SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20;   /* neg h/v sync, RGB24(D0 = 0) */
2356       }
2357    }
2358  
2359    if(SiS_Pr->ChipType < SIS_315H) {
2360       if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2361  	if(SiS_Pr->SiS_UseROM) {
2362  	   if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
2363  	      if(!(ROMAddr[0x235] & 0x02)) {
2364  		 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2365  	      }
2366  	   }
2367  	}
2368       } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2369  	if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
2370  	   SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2371  	}
2372       }
2373    }
2374  #endif
2375  
2376    /* Special cases */
2377  
2378    if(modexres == SiS_Pr->PanelXRes && modeyres == SiS_Pr->PanelYRes) {
2379       SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2380    }
2381  
2382    if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
2383       SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2384    }
2385  
2386    switch(SiS_Pr->SiS_LCDResInfo) {
2387    case Panel_640x480:
2388       SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2389       break;
2390    case Panel_1280x800:
2391       /* Don't pass 1:1 by default (TMDS special) */
2392       if(SiS_Pr->CenterScreen == -1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2393       break;
2394    case Panel_1280x960:
2395       SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2396       break;
2397    case Panel_Custom:
2398       if((!SiS_Pr->CP_PrefClock) ||
2399          (modexres > SiS_Pr->PanelXRes) || (modeyres > SiS_Pr->PanelYRes)) {
2400          SiS_Pr->SiS_LCDInfo |= LCDPass11;
2401       }
2402       break;
2403    }
2404  
2405    if((SiS_Pr->UseCustomMode) || (SiS_Pr->SiS_CustomT == CUT_UNKNOWNLCD)) {
2406       SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2407    }
2408  
2409    /* (In)validate LCDPass11 flag */
2410    if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2411       SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2412    }
2413  
2414    /* LVDS DDA */
2415    if(!((SiS_Pr->ChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
2416  
2417       if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
2418  	if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
2419  	   if(ModeNo == 0x12) {
2420  	      if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
2421  		 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2422  	      }
2423  	   } else if(ModeNo > 0x13) {
2424  	      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
2425  		 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2426  		    if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) {
2427  		       SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2428  		    }
2429  		 }
2430  	      }
2431  	   }
2432  	}
2433       }
2434  
2435       if(modeflag & HalfDCLK) {
2436  	if(SiS_Pr->SiS_IF_DEF_TRUMPION == 1) {
2437  	   SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2438  	} else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
2439  	   SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2440  	} else if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) {
2441  	   SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2442  	} else if(ModeNo > 0x13) {
2443  	   if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
2444  	      if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2445  	   } else if(SiS_Pr->SiS_LCDResInfo == Panel_800x600) {
2446  	      if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2447  	   }
2448  	}
2449       }
2450  
2451    }
2452  
2453    /* VESA timing */
2454    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2455       if(SiS_Pr->SiS_VBInfo & SetNotSimuMode) {
2456  	SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2457       }
2458    } else {
2459       SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2460    }
2461  
2462  #if 0
2463    printk(KERN_DEBUG "sisfb: (LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n",
2464  	SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo);
2465  #endif
2466  }
2467  
2468  /*********************************************/
2469  /*                 GET VCLK                  */
2470  /*********************************************/
2471  
2472  unsigned short
SiS_GetVCLK2Ptr(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)2473  SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
2474  		unsigned short RefreshRateTableIndex)
2475  {
2476    unsigned short CRT2Index, VCLKIndex = 0, VCLKIndexGEN = 0, VCLKIndexGENCRT = 0;
2477    unsigned short resinfo, tempbx;
2478    const unsigned char *CHTVVCLKPtr = NULL;
2479  
2480    if(ModeNo <= 0x13) {
2481       resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
2482       CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2483       VCLKIndexGEN = (SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)) >> 2) & 0x03;
2484       VCLKIndexGENCRT = VCLKIndexGEN;
2485    } else {
2486       resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2487       CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2488       VCLKIndexGEN = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
2489       VCLKIndexGENCRT = SiS_GetRefCRTVCLK(SiS_Pr, RefreshRateTableIndex,
2490  		(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) ? SiS_Pr->SiS_UseWideCRT2 : SiS_Pr->SiS_UseWide);
2491    }
2492  
2493    if(SiS_Pr->SiS_VBType & VB_SISVB) {    /* 30x/B/LV */
2494  
2495       if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2496  
2497  	CRT2Index >>= 6;
2498  	if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {      	/*  LCD */
2499  
2500  	   if(SiS_Pr->ChipType < SIS_315H) {
2501  	      VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2502  	      if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2503  		 VCLKIndex = VCLKIndexGEN;
2504  	      }
2505  	   } else {
2506  	      VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2507  	      if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2508  		 switch(resinfo) {
2509  		 /* Correct those whose IndexGEN doesn't match VBVCLK array */
2510  		 case SIS_RI_720x480:  VCLKIndex = VCLK_720x480;  break;
2511  		 case SIS_RI_720x576:  VCLKIndex = VCLK_720x576;  break;
2512  		 case SIS_RI_768x576:  VCLKIndex = VCLK_768x576;  break;
2513  		 case SIS_RI_848x480:  VCLKIndex = VCLK_848x480;  break;
2514  		 case SIS_RI_856x480:  VCLKIndex = VCLK_856x480;  break;
2515  		 case SIS_RI_800x480:  VCLKIndex = VCLK_800x480;  break;
2516  		 case SIS_RI_1024x576: VCLKIndex = VCLK_1024x576; break;
2517  		 case SIS_RI_1152x864: VCLKIndex = VCLK_1152x864; break;
2518  		 case SIS_RI_1280x720: VCLKIndex = VCLK_1280x720; break;
2519  		 case SIS_RI_1360x768: VCLKIndex = VCLK_1360x768; break;
2520  		 default:              VCLKIndex = VCLKIndexGEN;
2521  		 }
2522  
2523  		 if(ModeNo <= 0x13) {
2524  		    if(SiS_Pr->ChipType <= SIS_315PRO) {
2525  		       if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
2526  		    } else {
2527  		       if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x00;
2528  		    }
2529  		 }
2530  		 if(SiS_Pr->ChipType <= SIS_315PRO) {
2531  		    if(VCLKIndex == 0) VCLKIndex = 0x41;
2532  		    if(VCLKIndex == 1) VCLKIndex = 0x43;
2533  		    if(VCLKIndex == 4) VCLKIndex = 0x44;
2534  		 }
2535  	      }
2536  	   }
2537  
2538  	} else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {                 	/*  TV */
2539  
2540  	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
2541  	      if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) 	   VCLKIndex = HiTVVCLKDIV2;
2542  	      else                                  	   VCLKIndex = HiTVVCLK;
2543  	      if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)     VCLKIndex = HiTVSimuVCLK;
2544  	   } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)  VCLKIndex = YPbPr750pVCLK;
2545  	   else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)    VCLKIndex = TVVCLKDIV2;
2546  	   else if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO)      VCLKIndex = TVVCLKDIV2;
2547  	   else						   VCLKIndex = TVVCLK;
2548  
2549  	   if(SiS_Pr->ChipType < SIS_315H) VCLKIndex += TVCLKBASE_300;
2550  	   else				   VCLKIndex += TVCLKBASE_315;
2551  
2552  	} else {							/* VGA2 */
2553  
2554  	   VCLKIndex = VCLKIndexGENCRT;
2555  	   if(SiS_Pr->ChipType < SIS_315H) {
2556  	      if(ModeNo > 0x13) {
2557  		 if( (SiS_Pr->ChipType == SIS_630) &&
2558  		     (SiS_Pr->ChipRevision >= 0x30)) {
2559  		    if(VCLKIndex == 0x14) VCLKIndex = 0x34;
2560  		 }
2561  		 /* Better VGA2 clock for 1280x1024@75 */
2562  		 if(VCLKIndex == 0x17) VCLKIndex = 0x45;
2563  	      }
2564  	   }
2565  	}
2566  
2567       } else {   /* If not programming CRT2 */
2568  
2569  	VCLKIndex = VCLKIndexGENCRT;
2570  	if(SiS_Pr->ChipType < SIS_315H) {
2571  	   if(ModeNo > 0x13) {
2572  	      if( (SiS_Pr->ChipType != SIS_630) &&
2573  		  (SiS_Pr->ChipType != SIS_300) ) {
2574  		 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2575  	      }
2576  	   }
2577  	}
2578       }
2579  
2580    } else {       /*   LVDS  */
2581  
2582       VCLKIndex = CRT2Index;
2583  
2584       if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2585  
2586  	if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
2587  
2588  	   VCLKIndex &= 0x1f;
2589  	   tempbx = 0;
2590  	   if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2591  	   if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2592  	      tempbx += 2;
2593  	      if(SiS_Pr->SiS_ModeType > ModeVGA) {
2594  		 if(SiS_Pr->SiS_CHSOverScan) tempbx = 8;
2595  	      }
2596  	      if(SiS_Pr->SiS_TVMode & TVSetPALM) {
2597  		 tempbx = 4;
2598  		 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2599  	      } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
2600  		 tempbx = 6;
2601  		 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2602  	      }
2603  	   }
2604  	   switch(tempbx) {
2605  	     case  0: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUNTSC;  break;
2606  	     case  1: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKONTSC;  break;
2607  	     case  2: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPAL;   break;
2608  	     case  3: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL;   break;
2609  	     case  4: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALM;  break;
2610  	     case  5: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALM;  break;
2611  	     case  6: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALN;  break;
2612  	     case  7: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALN;  break;
2613  	     case  8: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKSOPAL;  break;
2614  	     default: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL;   break;
2615  	   }
2616  	   VCLKIndex = CHTVVCLKPtr[VCLKIndex];
2617  
2618  	} else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2619  
2620  	   if(SiS_Pr->ChipType < SIS_315H) {
2621  	      VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2622  	   } else {
2623  	      VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2624  	   }
2625  
2626  #ifdef CONFIG_FB_SIS_300
2627  	   /* Special Timing: Barco iQ Pro R series */
2628  	   if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) VCLKIndex = 0x44;
2629  
2630  	   /* Special Timing: 848x480 and 856x480 parallel lvds panels */
2631  	   if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
2632  	      if(SiS_Pr->ChipType < SIS_315H) {
2633  		 VCLKIndex = VCLK34_300;
2634  		 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2635  	      } else {
2636  		 VCLKIndex = VCLK34_315;
2637  		 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2638  	      }
2639  	   }
2640  #endif
2641  
2642  	} else {
2643  
2644  	   VCLKIndex = VCLKIndexGENCRT;
2645  	   if(SiS_Pr->ChipType < SIS_315H) {
2646  	      if(ModeNo > 0x13) {
2647  		 if( (SiS_Pr->ChipType == SIS_630) &&
2648  		     (SiS_Pr->ChipRevision >= 0x30) ) {
2649  		    if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
2650  		 }
2651  	      }
2652  	   }
2653  	}
2654  
2655       } else {  /* if not programming CRT2 */
2656  
2657  	VCLKIndex = VCLKIndexGENCRT;
2658  	if(SiS_Pr->ChipType < SIS_315H) {
2659  	   if(ModeNo > 0x13) {
2660  	      if( (SiS_Pr->ChipType != SIS_630) &&
2661  		  (SiS_Pr->ChipType != SIS_300) ) {
2662  		 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2663  	      }
2664  #if 0
2665  	      if(SiS_Pr->ChipType == SIS_730) {
2666  		 if(VCLKIndex == 0x0b) VCLKIndex = 0x40;   /* 1024x768-70 */
2667  		 if(VCLKIndex == 0x0d) VCLKIndex = 0x41;   /* 1024x768-75 */
2668  	      }
2669  #endif
2670  	   }
2671          }
2672  
2673       }
2674  
2675    }
2676  
2677    return VCLKIndex;
2678  }
2679  
2680  /*********************************************/
2681  /*        SET CRT2 MODE TYPE REGISTERS       */
2682  /*********************************************/
2683  
2684  static void
SiS_SetCRT2ModeRegs(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)2685  SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2686  {
2687    unsigned short i, j, modeflag, tempah=0;
2688    short tempcl;
2689  #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
2690    unsigned short tempbl;
2691  #endif
2692  #ifdef CONFIG_FB_SIS_315
2693    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
2694    unsigned short tempah2, tempbl2;
2695  #endif
2696  
2697    modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
2698  
2699    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
2700  
2701       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40);
2702       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2E,0xF7);
2703  
2704    } else {
2705  
2706       for(i=0,j=4; i<3; i++,j++) SiS_SetReg(SiS_Pr->SiS_Part1Port,j,0);
2707       if(SiS_Pr->ChipType >= SIS_315H) {
2708          SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0x7F);
2709       }
2710  
2711       tempcl = SiS_Pr->SiS_ModeType;
2712  
2713       if(SiS_Pr->ChipType < SIS_315H) {
2714  
2715  #ifdef CONFIG_FB_SIS_300    /* ---- 300 series ---- */
2716  
2717  	/* For 301BDH: (with LCD via LVDS) */
2718  	if(SiS_Pr->SiS_VBType & VB_NoLCD) {
2719  	   tempbl = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32);
2720  	   tempbl &= 0xef;
2721  	   tempbl |= 0x02;
2722  	   if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2723  	      tempbl |= 0x10;
2724  	      tempbl &= 0xfd;
2725  	   }
2726  	   SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,tempbl);
2727  	}
2728  
2729  	if(ModeNo > 0x13) {
2730  	   tempcl -= ModeVGA;
2731  	   if(tempcl >= 0) {
2732  	      tempah = ((0x10 >> tempcl) | 0x80);
2733  	   }
2734  	} else tempah = 0x80;
2735  
2736  	if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)  tempah ^= 0xA0;
2737  
2738  #endif  /* CONFIG_FB_SIS_300 */
2739  
2740       } else {
2741  
2742  #ifdef CONFIG_FB_SIS_315    /* ------- 315/330 series ------ */
2743  
2744  	if(ModeNo > 0x13) {
2745  	   tempcl -= ModeVGA;
2746  	   if(tempcl >= 0) {
2747  	      tempah = (0x08 >> tempcl);
2748  	      if (tempah == 0) tempah = 1;
2749  	      tempah |= 0x40;
2750  	   }
2751  	} else tempah = 0x40;
2752  
2753  	if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50;
2754  
2755  #endif  /* CONFIG_FB_SIS_315 */
2756  
2757       }
2758  
2759       if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2760  
2761       if(SiS_Pr->ChipType < SIS_315H) {
2762  	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2763       } else {
2764  #ifdef CONFIG_FB_SIS_315
2765  	if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2766  	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2767  	} else if(SiS_Pr->SiS_VBType & VB_SISVB) {
2768  	   if(IS_SIS740) {
2769  	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2770  	   } else {
2771  	      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2772  	   }
2773  	}
2774  #endif
2775       }
2776  
2777       if(SiS_Pr->SiS_VBType & VB_SISVB) {
2778  
2779  	tempah = 0x01;
2780  	if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
2781  	   tempah |= 0x02;
2782  	}
2783  	if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2784  	   tempah ^= 0x05;
2785  	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
2786  	      tempah ^= 0x01;
2787  	   }
2788  	}
2789  
2790  	if(SiS_Pr->ChipType < SIS_315H) {
2791  
2792  	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display)  tempah = 0;
2793  
2794  	   tempah = (tempah << 5) & 0xFF;
2795  	   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2796  	   tempah = (tempah >> 5) & 0xFF;
2797  
2798  	} else {
2799  
2800  	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display)  tempah = 0x08;
2801  	   else if(!(SiS_IsDualEdge(SiS_Pr)))           tempah |= 0x08;
2802  	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF0,tempah);
2803  	   tempah &= ~0x08;
2804  
2805  	}
2806  
2807  	if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
2808  	   tempah |= 0x10;
2809  	}
2810  
2811  	tempah |= 0x80;
2812  	if(SiS_Pr->SiS_VBType & VB_SIS301) {
2813  	   if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah &= ~0x80;
2814  	}
2815  
2816  	if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2817  	   if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p))) {
2818  	      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2819  		 tempah |= 0x20;
2820  	      }
2821  	   }
2822  	}
2823  
2824  	SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah);
2825  
2826  	tempah = 0x80;
2827  	if(SiS_Pr->SiS_VBType & VB_SIS301) {
2828  	   if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah = 0;
2829  	}
2830  
2831  	if(SiS_IsDualLink(SiS_Pr)) tempah |= 0x40;
2832  
2833  	if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2834  	   if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) {
2835  	      tempah |= 0x40;
2836  	   }
2837  	}
2838  
2839  	SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0C,tempah);
2840  
2841       } else {  /* LVDS */
2842  
2843  	if(SiS_Pr->ChipType >= SIS_315H) {
2844  
2845  #ifdef CONFIG_FB_SIS_315
2846  	   /* LVDS can only be slave in 8bpp modes */
2847  	   tempah = 0x80;
2848  	   if((modeflag & CRT2Mode) && (SiS_Pr->SiS_ModeType > ModeVGA)) {
2849  	      if(SiS_Pr->SiS_VBInfo & DriverMode) {
2850  	         tempah |= 0x02;
2851  	      }
2852  	   }
2853  
2854  	   if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))  tempah |= 0x02;
2855  
2856  	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)        tempah ^= 0x01;
2857  
2858  	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 1;
2859  
2860  	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah);
2861  #endif
2862  
2863  	} else {
2864  
2865  #ifdef CONFIG_FB_SIS_300
2866  	   tempah = 0;
2867  	   if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
2868  	      tempah |= 0x02;
2869  	   }
2870  	   tempah <<= 5;
2871  
2872  	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2873  
2874  	   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2875  #endif
2876  
2877  	}
2878  
2879       }
2880  
2881    }  /* LCDA */
2882  
2883    if(SiS_Pr->SiS_VBType & VB_SISVB) {
2884  
2885       if(SiS_Pr->ChipType >= SIS_315H) {
2886  
2887  #ifdef CONFIG_FB_SIS_315
2888  	/* unsigned char bridgerev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01); */
2889  
2890  	/* The following is nearly unpreditable and varies from machine
2891  	 * to machine. Especially the 301DH seems to be a real trouble
2892  	 * maker. Some BIOSes simply set the registers (like in the
2893  	 * NoLCD-if-statements here), some set them according to the
2894  	 * LCDA stuff. It is very likely that some machines are not
2895  	 * treated correctly in the following, very case-orientated
2896  	 * code. What do I do then...?
2897  	 */
2898  
2899  	/* 740 variants match for 30xB, 301B-DH, 30xLV */
2900  
2901  	if(!(IS_SIS740)) {
2902  	   tempah = 0x04;						   /* For all bridges */
2903  	   tempbl = 0xfb;
2904  	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2905  	      tempah = 0x00;
2906  	      if(SiS_IsDualEdge(SiS_Pr)) {
2907  	         tempbl = 0xff;
2908  	      }
2909  	   }
2910  	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2911  	}
2912  
2913  	/* The following two are responsible for eventually wrong colors
2914  	 * in TV output. The DH (VB_NoLCD) conditions are unknown; the
2915  	 * b0 was found in some 651 machine (Pim; P4_23=0xe5); the b1 version
2916  	 * in a 650 box (Jake). What is the criteria?
2917  	 * Addendum: Another combination 651+301B-DH(b1) (Rapo) needs same
2918  	 * treatment like the 651+301B-DH(b0) case. Seems more to be the
2919  	 * chipset than the bridge revision.
2920  	 */
2921  
2922  	if((IS_SIS740) || (SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
2923  	   tempah = 0x30;
2924  	   tempbl = 0xc0;
2925  	   if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2926  	      ((SiS_Pr->SiS_ROMNew) && (!(ROMAddr[0x5b] & 0x04)))) {
2927  	      tempah = 0x00;
2928  	      tempbl = 0x00;
2929  	   }
2930  	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,tempah);
2931  	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,tempbl);
2932  	} else if(SiS_Pr->SiS_VBType & VB_SIS301) {
2933  	   /* Fixes "TV-blue-bug" on 315+301 */
2934  	   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xcf);	/* For 301   */
2935  	   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2936  	} else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
2937  	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);	/* For 30xLV */
2938  	   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);
2939  	} else if(SiS_Pr->SiS_VBType & VB_NoLCD) {		/* For 301B-DH */
2940  	   tempah = 0x30; tempah2 = 0xc0;
2941  	   tempbl = 0xcf; tempbl2 = 0x3f;
2942  	   if(SiS_Pr->SiS_TVBlue == 0) {
2943  	         tempah = tempah2 = 0x00;
2944  	   } else if(SiS_Pr->SiS_TVBlue == -1) {
2945  	      /* Set on 651/M650, clear on 315/650 */
2946  	      if(!(IS_SIS65x)) /* (bridgerev != 0xb0) */ {
2947  	         tempah = tempah2 = 0x00;
2948  	      }
2949  	   }
2950  	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2951  	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2952  	} else {
2953  	   tempah = 0x30; tempah2 = 0xc0;		       /* For 30xB, 301C */
2954  	   tempbl = 0xcf; tempbl2 = 0x3f;
2955  	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2956  	      tempah = tempah2 = 0x00;
2957  	      if(SiS_IsDualEdge(SiS_Pr)) {
2958  		 tempbl = tempbl2 = 0xff;
2959  	      }
2960  	   }
2961  	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2962  	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2963  	}
2964  
2965  	if(IS_SIS740) {
2966  	   tempah = 0x80;
2967  	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x00;
2968  	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,0x7f,tempah);
2969  	} else {
2970  	   tempah = 0x00;
2971  	   tempbl = 0x7f;
2972  	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2973  	      tempbl = 0xff;
2974  	      if(!(SiS_IsDualEdge(SiS_Pr))) tempah = 0x80;
2975  	   }
2976  	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
2977  	}
2978  
2979  #endif /* CONFIG_FB_SIS_315 */
2980  
2981       } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2982  
2983  #ifdef CONFIG_FB_SIS_300
2984  	SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2985  
2986  	if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2987  	   ((SiS_Pr->SiS_VBType & VB_NoLCD) &&
2988  	    (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD))) {
2989  	   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x23,0x7F);
2990  	} else {
2991  	   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x23,0x80);
2992  	}
2993  #endif
2994  
2995       }
2996  
2997       if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2998  	SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x0D,0x80);
2999  	if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
3000  	   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3A,0xC0);
3001          }
3002       }
3003  
3004    } else {  /* LVDS */
3005  
3006  #ifdef CONFIG_FB_SIS_315
3007       if(SiS_Pr->ChipType >= SIS_315H) {
3008  
3009  	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
3010  
3011  	   tempah = 0x04;
3012  	   tempbl = 0xfb;
3013  	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3014  	      tempah = 0x00;
3015  	      if(SiS_IsDualEdge(SiS_Pr)) tempbl = 0xff;
3016  	   }
3017  	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
3018  
3019  	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
3020  	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
3021  	   }
3022  
3023  	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
3024  
3025  	} else if(SiS_Pr->ChipType == SIS_550) {
3026  
3027  	   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
3028  	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
3029  
3030  	}
3031  
3032       }
3033  #endif
3034  
3035    }
3036  
3037  }
3038  
3039  /*********************************************/
3040  /*            GET RESOLUTION DATA            */
3041  /*********************************************/
3042  
3043  unsigned short
SiS_GetResInfo(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)3044  SiS_GetResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
3045  {
3046     if(ModeNo <= 0x13)
3047        return ((unsigned short)SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo);
3048     else
3049        return ((unsigned short)SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO);
3050  }
3051  
3052  static void
SiS_GetCRT2ResInfo(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)3053  SiS_GetCRT2ResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
3054  {
3055     unsigned short xres, yres, modeflag=0, resindex;
3056  
3057     if(SiS_Pr->UseCustomMode) {
3058        xres = SiS_Pr->CHDisplay;
3059        if(SiS_Pr->CModeFlag & HalfDCLK) xres <<= 1;
3060        SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
3061        /* DoubleScanMode-check done in CheckCalcCustomMode()! */
3062        SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = SiS_Pr->CVDisplay;
3063        return;
3064     }
3065  
3066     resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex);
3067  
3068     if(ModeNo <= 0x13) {
3069        xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
3070        yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
3071     } else {
3072        xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
3073        yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
3074        modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3075     }
3076  
3077     if(!SiS_Pr->SiS_IF_DEF_DSTN && !SiS_Pr->SiS_IF_DEF_FSTN) {
3078  
3079        if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
3080  	 if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
3081  	    if(yres == 350) yres = 400;
3082  	 }
3083  	 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
3084  	    if(ModeNo == 0x12) yres = 400;
3085  	 }
3086        }
3087  
3088        if(modeflag & HalfDCLK)       xres <<= 1;
3089        if(modeflag & DoubleScanMode) yres <<= 1;
3090  
3091     }
3092  
3093     if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
3094  
3095        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3096  	 switch(SiS_Pr->SiS_LCDResInfo) {
3097  	   case Panel_1024x768:
3098  	      if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
3099  		 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
3100  		    if(yres == 350) yres = 357;
3101  		    if(yres == 400) yres = 420;
3102  		    if(yres == 480) yres = 525;
3103  		 }
3104  	      }
3105  	      break;
3106  	   case Panel_1280x1024:
3107  	      if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
3108  		 /* BIOS bug - does this regardless of scaling */
3109  		 if(yres == 400) yres = 405;
3110  	      }
3111  	      if(yres == 350) yres = 360;
3112  	      if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
3113  		 if(yres == 360) yres = 375;
3114  	      }
3115  	      break;
3116  	   case Panel_1600x1200:
3117  	      if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
3118  		 if(yres == 1024) yres = 1056;
3119  	      }
3120  	      break;
3121  	 }
3122        }
3123  
3124     } else {
3125  
3126        if(SiS_Pr->SiS_VBType & VB_SISVB) {
3127  	 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVision)) {
3128  	    if(xres == 720) xres = 640;
3129  	 }
3130        } else if(xres == 720) xres = 640;
3131  
3132        if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
3133  	 yres = 400;
3134  	 if(SiS_Pr->ChipType >= SIS_315H) {
3135  	    if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
3136  	 } else {
3137  	    if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
3138  	 }
3139  	 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) yres = 480;
3140        }
3141  
3142     }
3143     SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
3144     SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
3145  }
3146  
3147  /*********************************************/
3148  /*           GET CRT2 TIMING DATA            */
3149  /*********************************************/
3150  
3151  static void
SiS_GetCRT2Ptr(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex,unsigned short * CRT2Index,unsigned short * ResIndex)3152  SiS_GetCRT2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3153  	       unsigned short RefreshRateTableIndex, unsigned short *CRT2Index,
3154  	       unsigned short *ResIndex)
3155  {
3156    unsigned short tempbx=0, tempal=0, resinfo=0;
3157  
3158    if(ModeNo <= 0x13) {
3159       tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3160    } else {
3161       tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
3162       resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
3163    }
3164  
3165    if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_IF_DEF_LVDS == 0)) {
3166  
3167       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {                            /* LCD */
3168  
3169  	tempbx = SiS_Pr->SiS_LCDResInfo;
3170  	if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 32;
3171  
3172  	/* patch index */
3173  	if(SiS_Pr->SiS_LCDResInfo == Panel_1680x1050) {
3174  	   if     (resinfo == SIS_RI_1280x800)  tempal =  9;
3175  	   else if(resinfo == SIS_RI_1400x1050) tempal = 11;
3176  	} else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x800) ||
3177  		  (SiS_Pr->SiS_LCDResInfo == Panel_1280x800_2) ||
3178  		  (SiS_Pr->SiS_LCDResInfo == Panel_1280x854)) {
3179  	   if     (resinfo == SIS_RI_1280x768)  tempal =  9;
3180  	}
3181  
3182  	if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3183  	   /* Pass 1:1 only (center-screen handled outside) */
3184  	   /* This is never called for the panel's native resolution */
3185  	   /* since Pass1:1 will not be set in this case */
3186  	   tempbx = 100;
3187  	   if(ModeNo >= 0x13) {
3188  	      tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
3189  	   }
3190  	}
3191  
3192  #ifdef CONFIG_FB_SIS_315
3193  	if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
3194  	   if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
3195  	      if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
3196  		 tempbx = 200;
3197  		 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
3198  	      }
3199  	   }
3200  	}
3201  #endif
3202  
3203       } else {						  	/* TV */
3204  
3205  	if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
3206  	   /* if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_TVMode &= (~TVSetTVSimuMode); */
3207  	   tempbx = 2;
3208  	   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
3209  	      tempbx = 13;
3210  	      if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) tempbx = 14;
3211  	   }
3212  	} else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3213  	   if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)	tempbx = 7;
3214  	   else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)	tempbx = 6;
3215  	   else						tempbx = 5;
3216  	   if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)	tempbx += 5;
3217  	} else {
3218  	   if(SiS_Pr->SiS_TVMode & TVSetPAL)		tempbx = 3;
3219  	   else						tempbx = 4;
3220  	   if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)	tempbx += 5;
3221  	}
3222  
3223       }
3224  
3225       tempal &= 0x3F;
3226  
3227       if(ModeNo > 0x13) {
3228          if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) {
3229  	   switch(resinfo) {
3230  	   case SIS_RI_720x480:
3231  	      tempal = 6;
3232  	      if(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetPALN))	tempal = 9;
3233  	      break;
3234  	   case SIS_RI_720x576:
3235  	   case SIS_RI_768x576:
3236  	   case SIS_RI_1024x576: /* Not in NTSC or YPBPR mode (except 1080i)! */
3237  	      tempal = 6;
3238  	      if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3239  		 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)	tempal = 8;
3240  	      }
3241  	      break;
3242  	   case SIS_RI_800x480:
3243  	      tempal = 4;
3244  	      break;
3245  	   case SIS_RI_512x384:
3246  	   case SIS_RI_1024x768:
3247  	      tempal = 7;
3248  	      if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3249  		 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)	tempal = 8;
3250  	      }
3251  	      break;
3252  	   case SIS_RI_1280x720:
3253  	      if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3254  		 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)	tempal = 9;
3255  	      }
3256  	      break;
3257  	   }
3258  	}
3259       }
3260  
3261       *CRT2Index = tempbx;
3262       *ResIndex = tempal;
3263  
3264    } else {   /* LVDS, 301B-DH (if running on LCD) */
3265  
3266       tempbx = 0;
3267       if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
3268  
3269  	tempbx = 90;
3270  	if(SiS_Pr->SiS_TVMode & TVSetPAL) {
3271  	   tempbx = 92;
3272  	   if(SiS_Pr->SiS_ModeType > ModeVGA) {
3273  	      if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
3274  	   }
3275  	   if(SiS_Pr->SiS_TVMode & TVSetPALM)      tempbx = 94;
3276  	   else if(SiS_Pr->SiS_TVMode & TVSetPALN) tempbx = 96;
3277  	}
3278  	if(tempbx != 99) {
3279  	   if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx++;
3280  	}
3281  
3282       } else {
3283  
3284  	switch(SiS_Pr->SiS_LCDResInfo) {
3285  	case Panel_640x480:   tempbx = 12; break;
3286  	case Panel_320x240_1: tempbx = 10; break;
3287  	case Panel_320x240_2:
3288  	case Panel_320x240_3: tempbx = 14; break;
3289  	case Panel_800x600:   tempbx = 16; break;
3290  	case Panel_1024x600:  tempbx = 18; break;
3291  	case Panel_1152x768:
3292  	case Panel_1024x768:  tempbx = 20; break;
3293  	case Panel_1280x768:  tempbx = 22; break;
3294  	case Panel_1280x1024: tempbx = 24; break;
3295  	case Panel_1400x1050: tempbx = 26; break;
3296  	case Panel_1600x1200: tempbx = 28; break;
3297  #ifdef CONFIG_FB_SIS_300
3298  	case Panel_Barco1366: tempbx = 80; break;
3299  #endif
3300  	}
3301  
3302  	switch(SiS_Pr->SiS_LCDResInfo) {
3303  	case Panel_320x240_1:
3304  	case Panel_320x240_2:
3305  	case Panel_320x240_3:
3306  	case Panel_640x480:
3307  	   break;
3308  	default:
3309  	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3310  	}
3311  
3312  	if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempbx = 30;
3313  
3314  #ifdef CONFIG_FB_SIS_300
3315  	if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
3316  	   tempbx = 82;
3317  	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3318  	} else if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
3319  	   tempbx = 84;
3320  	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3321  	}
3322  #endif
3323  
3324       }
3325  
3326       (*CRT2Index) = tempbx;
3327       (*ResIndex) = tempal & 0x1F;
3328    }
3329  }
3330  
3331  static void
SiS_GetRAMDAC2DATA(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)3332  SiS_GetRAMDAC2DATA(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3333  		unsigned short RefreshRateTableIndex)
3334  {
3335    unsigned short tempax=0, tempbx=0, index, dotclock;
3336    unsigned short temp1=0, modeflag=0, tempcx=0;
3337  
3338    SiS_Pr->SiS_RVBHCMAX  = 1;
3339    SiS_Pr->SiS_RVBHCFACT = 1;
3340  
3341    if(ModeNo <= 0x13) {
3342  
3343       modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3344       index = SiS_GetModePtr(SiS_Pr,ModeNo,ModeIdIndex);
3345  
3346       tempax = SiS_Pr->SiS_StandTable[index].CRTC[0];
3347       tempbx = SiS_Pr->SiS_StandTable[index].CRTC[6];
3348       temp1 = SiS_Pr->SiS_StandTable[index].CRTC[7];
3349  
3350       dotclock = (modeflag & Charx8Dot) ? 8 : 9;
3351  
3352    } else {
3353  
3354       modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3355       index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);
3356  
3357       tempax = SiS_Pr->SiS_CRT1Table[index].CR[0];
3358       tempax |= (SiS_Pr->SiS_CRT1Table[index].CR[14] << 8);
3359       tempax &= 0x03FF;
3360       tempbx = SiS_Pr->SiS_CRT1Table[index].CR[6];
3361       tempcx = SiS_Pr->SiS_CRT1Table[index].CR[13] << 8;
3362       tempcx &= 0x0100;
3363       tempcx <<= 2;
3364       tempbx |= tempcx;
3365       temp1  = SiS_Pr->SiS_CRT1Table[index].CR[7];
3366  
3367       dotclock = 8;
3368  
3369    }
3370  
3371    if(temp1 & 0x01) tempbx |= 0x0100;
3372    if(temp1 & 0x20) tempbx |= 0x0200;
3373  
3374    tempax += 5;
3375    tempax *= dotclock;
3376    if(modeflag & HalfDCLK) tempax <<= 1;
3377  
3378    tempbx++;
3379  
3380    SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3381    SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = tempbx;
3382  }
3383  
3384  static void
SiS_CalcPanelLinkTiming(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)3385  SiS_CalcPanelLinkTiming(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
3386  		unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex)
3387  {
3388     unsigned short ResIndex;
3389  
3390     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3391        if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
3392  	 if(SiS_Pr->UseCustomMode) {
3393  	    ResIndex = SiS_Pr->CHTotal;
3394  	    if(SiS_Pr->CModeFlag & HalfDCLK) ResIndex <<= 1;
3395  	    SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = ResIndex;
3396  	    SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3397  	 } else {
3398  	    if(ModeNo < 0x13) {
3399  	       ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3400  	    } else {
3401  	       ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
3402  	    }
3403  	    if(ResIndex == 0x09) {
3404  	       if(SiS_Pr->Alternate1600x1200)        ResIndex = 0x20; /* 1600x1200 LCDA */
3405  	       else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) ResIndex = 0x21; /* 1600x1200 LVDS */
3406  	    }
3407  	    SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAHT;
3408  	    SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAVT;
3409  	    SiS_Pr->SiS_HT    = SiS_Pr->SiS_NoScaleData[ResIndex].LCDHT;
3410  	    SiS_Pr->SiS_VT    = SiS_Pr->SiS_NoScaleData[ResIndex].LCDVT;
3411  	 }
3412        } else {
3413  	 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3414  	 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3415        }
3416     } else {
3417        /* This handles custom modes and custom panels */
3418        SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3419        SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3420        SiS_Pr->SiS_HT  = SiS_Pr->PanelHT;
3421        SiS_Pr->SiS_VT  = SiS_Pr->PanelVT;
3422        SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT - (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE);
3423        SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT - (SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE);
3424     }
3425  }
3426  
3427  static void
SiS_GetCRT2DataLVDS(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)3428  SiS_GetCRT2DataLVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3429                      unsigned short RefreshRateTableIndex)
3430  {
3431     unsigned short CRT2Index, ResIndex, backup;
3432     const struct SiS_LVDSData *LVDSData = NULL;
3433  
3434     SiS_GetCRT2ResInfo(SiS_Pr, ModeNo, ModeIdIndex);
3435  
3436     if(SiS_Pr->SiS_VBType & VB_SISVB) {
3437        SiS_Pr->SiS_RVBHCMAX  = 1;
3438        SiS_Pr->SiS_RVBHCFACT = 1;
3439        SiS_Pr->SiS_NewFlickerMode = 0;
3440        SiS_Pr->SiS_RVBHRS = 50;
3441        SiS_Pr->SiS_RY1COE = 0;
3442        SiS_Pr->SiS_RY2COE = 0;
3443        SiS_Pr->SiS_RY3COE = 0;
3444        SiS_Pr->SiS_RY4COE = 0;
3445        SiS_Pr->SiS_RVBHRS2 = 0;
3446     }
3447  
3448     if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3449  
3450  #ifdef CONFIG_FB_SIS_315
3451        SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3452        SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
3453  #endif
3454  
3455     } else {
3456  
3457        /* 301BDH needs LVDS Data */
3458        backup = SiS_Pr->SiS_IF_DEF_LVDS;
3459        if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3460  	 SiS_Pr->SiS_IF_DEF_LVDS = 1;
3461        }
3462  
3463        SiS_GetCRT2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
3464                       		            &CRT2Index, &ResIndex);
3465  
3466        SiS_Pr->SiS_IF_DEF_LVDS = backup;
3467  
3468        switch(CRT2Index) {
3469  	 case 10: LVDSData = SiS_Pr->SiS_LVDS320x240Data_1;    break;
3470  	 case 14: LVDSData = SiS_Pr->SiS_LVDS320x240Data_2;    break;
3471  	 case 12: LVDSData = SiS_Pr->SiS_LVDS640x480Data_1;    break;
3472  	 case 16: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1;    break;
3473  	 case 18: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1;   break;
3474  	 case 20: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1;   break;
3475  #ifdef CONFIG_FB_SIS_300
3476  	 case 80: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1;  break;
3477  	 case 81: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2;  break;
3478  	 case 82: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1;  break;
3479  	 case 84: LVDSData = SiS_Pr->SiS_LVDS848x480Data_1;    break;
3480  	 case 85: LVDSData = SiS_Pr->SiS_LVDS848x480Data_2;    break;
3481  #endif
3482  	 case 90: LVDSData = SiS_Pr->SiS_CHTVUNTSCData;        break;
3483  	 case 91: LVDSData = SiS_Pr->SiS_CHTVONTSCData;        break;
3484  	 case 92: LVDSData = SiS_Pr->SiS_CHTVUPALData;         break;
3485  	 case 93: LVDSData = SiS_Pr->SiS_CHTVOPALData;         break;
3486  	 case 94: LVDSData = SiS_Pr->SiS_CHTVUPALMData;        break;
3487  	 case 95: LVDSData = SiS_Pr->SiS_CHTVOPALMData;        break;
3488  	 case 96: LVDSData = SiS_Pr->SiS_CHTVUPALNData;        break;
3489  	 case 97: LVDSData = SiS_Pr->SiS_CHTVOPALNData;        break;
3490  	 case 99: LVDSData = SiS_Pr->SiS_CHTVSOPALData;	       break;
3491        }
3492  
3493        if(LVDSData) {
3494  	 SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT;
3495  	 SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT;
3496  	 SiS_Pr->SiS_HT    = (LVDSData+ResIndex)->LCDHT;
3497  	 SiS_Pr->SiS_VT    = (LVDSData+ResIndex)->LCDVT;
3498        } else {
3499  	 SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3500        }
3501  
3502        if( (!(SiS_Pr->SiS_VBType & VB_SISVB)) &&
3503  	  (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
3504  	  (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) ) {
3505  	 if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ||
3506  	     (SiS_Pr->SiS_SetFlag & SetDOSMode) ) {
3507  	    SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3508              SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3509  #ifdef CONFIG_FB_SIS_300
3510  	    if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3511  	       if(ResIndex < 0x08) {
3512  		  SiS_Pr->SiS_HDE = 1280;
3513  		  SiS_Pr->SiS_VDE = 1024;
3514  	       }
3515  	    }
3516  #endif
3517           }
3518        }
3519     }
3520  }
3521  
3522  static void
SiS_GetCRT2Data301(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)3523  SiS_GetCRT2Data301(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3524  		unsigned short RefreshRateTableIndex)
3525  {
3526    unsigned char  *ROMAddr = NULL;
3527    unsigned short tempax, tempbx, modeflag, romptr=0;
3528    unsigned short resinfo, CRT2Index, ResIndex;
3529    const struct SiS_LCDData *LCDPtr = NULL;
3530    const struct SiS_TVData  *TVPtr  = NULL;
3531  #ifdef CONFIG_FB_SIS_315
3532    short resinfo661;
3533  #endif
3534  
3535    if(ModeNo <= 0x13) {
3536       modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3537       resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
3538    } else if(SiS_Pr->UseCustomMode) {
3539       modeflag = SiS_Pr->CModeFlag;
3540       resinfo = 0;
3541    } else {
3542       modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3543       resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
3544  #ifdef CONFIG_FB_SIS_315
3545       resinfo661 = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].ROMMODEIDX661;
3546       if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)   &&
3547  	 (SiS_Pr->SiS_SetFlag & LCDVESATiming) &&
3548  	 (resinfo661 >= 0)                     &&
3549  	 (SiS_Pr->SiS_NeedRomModeData) ) {
3550  	if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
3551  	   if((romptr = (SISGETROMW(21)))) {
3552  	      romptr += (resinfo661 * 10);
3553  	      ROMAddr = SiS_Pr->VirtualRomBase;
3554  	   }
3555  	}
3556       }
3557  #endif
3558    }
3559  
3560    SiS_Pr->SiS_NewFlickerMode = 0;
3561    SiS_Pr->SiS_RVBHRS = 50;
3562    SiS_Pr->SiS_RY1COE = 0;
3563    SiS_Pr->SiS_RY2COE = 0;
3564    SiS_Pr->SiS_RY3COE = 0;
3565    SiS_Pr->SiS_RY4COE = 0;
3566    SiS_Pr->SiS_RVBHRS2 = 0;
3567  
3568    SiS_GetCRT2ResInfo(SiS_Pr,ModeNo,ModeIdIndex);
3569  
3570    if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
3571  
3572       if(SiS_Pr->UseCustomMode) {
3573  
3574  	SiS_Pr->SiS_RVBHCMAX  = 1;
3575  	SiS_Pr->SiS_RVBHCFACT = 1;
3576  	SiS_Pr->SiS_HDE       = SiS_Pr->SiS_VGAHDE;
3577  	SiS_Pr->SiS_VDE       = SiS_Pr->SiS_VGAVDE;
3578  
3579  	tempax = SiS_Pr->CHTotal;
3580  	if(modeflag & HalfDCLK) tempax <<= 1;
3581  	SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3582  	SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3583  
3584       } else {
3585  
3586  	SiS_GetRAMDAC2DATA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3587  
3588       }
3589  
3590    } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
3591  
3592       SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3593  		    &CRT2Index,&ResIndex);
3594  
3595       switch(CRT2Index) {
3596  	case  2: TVPtr = SiS_Pr->SiS_ExtHiTVData;   break;
3597  	case  3: TVPtr = SiS_Pr->SiS_ExtPALData;    break;
3598  	case  4: TVPtr = SiS_Pr->SiS_ExtNTSCData;   break;
3599  	case  5: TVPtr = SiS_Pr->SiS_Ext525iData;   break;
3600  	case  6: TVPtr = SiS_Pr->SiS_Ext525pData;   break;
3601  	case  7: TVPtr = SiS_Pr->SiS_Ext750pData;   break;
3602  	case  8: TVPtr = SiS_Pr->SiS_StPALData;     break;
3603  	case  9: TVPtr = SiS_Pr->SiS_StNTSCData;    break;
3604  	case 10: TVPtr = SiS_Pr->SiS_St525iData;    break;
3605  	case 11: TVPtr = SiS_Pr->SiS_St525pData;    break;
3606  	case 12: TVPtr = SiS_Pr->SiS_St750pData;    break;
3607  	case 13: TVPtr = SiS_Pr->SiS_St1HiTVData;   break;
3608  	case 14: TVPtr = SiS_Pr->SiS_St2HiTVData;   break;
3609  	default: TVPtr = SiS_Pr->SiS_StPALData;     break;
3610       }
3611  
3612       SiS_Pr->SiS_RVBHCMAX  = (TVPtr+ResIndex)->RVBHCMAX;
3613       SiS_Pr->SiS_RVBHCFACT = (TVPtr+ResIndex)->RVBHCFACT;
3614       SiS_Pr->SiS_VGAHT     = (TVPtr+ResIndex)->VGAHT;
3615       SiS_Pr->SiS_VGAVT     = (TVPtr+ResIndex)->VGAVT;
3616       SiS_Pr->SiS_HDE       = (TVPtr+ResIndex)->TVHDE;
3617       SiS_Pr->SiS_VDE       = (TVPtr+ResIndex)->TVVDE;
3618       SiS_Pr->SiS_RVBHRS2   = (TVPtr+ResIndex)->RVBHRS2 & 0x0fff;
3619       if(modeflag & HalfDCLK) {
3620  	SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->HALFRVBHRS;
3621  	if(SiS_Pr->SiS_RVBHRS2) {
3622  	   SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
3623  	   tempax = ((TVPtr+ResIndex)->RVBHRS2 >> 12) & 0x07;
3624  	   if((TVPtr+ResIndex)->RVBHRS2 & 0x8000) SiS_Pr->SiS_RVBHRS2 -= tempax;
3625  	   else                                   SiS_Pr->SiS_RVBHRS2 += tempax;
3626  	}
3627       } else {
3628  	SiS_Pr->SiS_RVBHRS    = (TVPtr+ResIndex)->RVBHRS;
3629       }
3630       SiS_Pr->SiS_NewFlickerMode = ((TVPtr+ResIndex)->FlickerMode) << 7;
3631  
3632       if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
3633  
3634  	if((resinfo == SIS_RI_960x600)   ||
3635  	   (resinfo == SIS_RI_1024x768)  ||
3636  	   (resinfo == SIS_RI_1280x1024) ||
3637  	   (resinfo == SIS_RI_1280x720)) {
3638  	   SiS_Pr->SiS_NewFlickerMode = 0x40;
3639  	}
3640  
3641  	if(SiS_Pr->SiS_VGAVDE == 350) SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
3642  
3643  	SiS_Pr->SiS_HT = ExtHiTVHT;
3644  	SiS_Pr->SiS_VT = ExtHiTVVT;
3645  	if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
3646  	   if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
3647  	      SiS_Pr->SiS_HT = StHiTVHT;
3648  	      SiS_Pr->SiS_VT = StHiTVVT;
3649  	   }
3650  	}
3651  
3652       } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3653  
3654  	if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
3655  	   SiS_Pr->SiS_HT = 1650;
3656  	   SiS_Pr->SiS_VT = 750;
3657  	} else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
3658  	   SiS_Pr->SiS_HT = NTSCHT;
3659  	   if(SiS_Pr->SiS_TVMode & TVSet525p1024) SiS_Pr->SiS_HT = NTSC2HT;
3660  	   SiS_Pr->SiS_VT = NTSCVT;
3661  	} else {
3662  	   SiS_Pr->SiS_HT = NTSCHT;
3663  	   if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3664  	   SiS_Pr->SiS_VT = NTSCVT;
3665  	}
3666  
3667       } else {
3668  
3669  	SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
3670  	SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
3671  	SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
3672  	SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
3673  
3674  	if(modeflag & HalfDCLK) {
3675  	   SiS_Pr->SiS_RY1COE = 0x00;
3676  	   SiS_Pr->SiS_RY2COE = 0xf4;
3677  	   SiS_Pr->SiS_RY3COE = 0x10;
3678  	   SiS_Pr->SiS_RY4COE = 0x38;
3679  	}
3680  
3681  	if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
3682  	   SiS_Pr->SiS_HT = NTSCHT;
3683  	   if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3684  	   SiS_Pr->SiS_VT = NTSCVT;
3685  	} else {
3686  	   SiS_Pr->SiS_HT = PALHT;
3687  	   SiS_Pr->SiS_VT = PALVT;
3688  	}
3689  
3690       }
3691  
3692    } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3693  
3694       SiS_Pr->SiS_RVBHCMAX  = 1;
3695       SiS_Pr->SiS_RVBHCFACT = 1;
3696  
3697       if(SiS_Pr->UseCustomMode) {
3698  
3699  	SiS_Pr->SiS_HDE   = SiS_Pr->SiS_VGAHDE;
3700  	SiS_Pr->SiS_VDE   = SiS_Pr->SiS_VGAVDE;
3701  
3702  	tempax = SiS_Pr->CHTotal;
3703  	if(modeflag & HalfDCLK) tempax <<= 1;
3704  	SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3705  	SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3706  
3707       } else {
3708  
3709  	bool gotit = false;
3710  
3711  	if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
3712  
3713  	   SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
3714  	   SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
3715  	   SiS_Pr->SiS_HT    = SiS_Pr->PanelHT;
3716  	   SiS_Pr->SiS_VT    = SiS_Pr->PanelVT;
3717  	   gotit = true;
3718  
3719  	} else if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) && (romptr) && (ROMAddr) ) {
3720  
3721  #ifdef CONFIG_FB_SIS_315
3722  	   SiS_Pr->SiS_RVBHCMAX  = ROMAddr[romptr];
3723  	   SiS_Pr->SiS_RVBHCFACT = ROMAddr[romptr+1];
3724  	   SiS_Pr->SiS_VGAHT     = ROMAddr[romptr+2] | ((ROMAddr[romptr+3] & 0x0f) << 8);
3725  	   SiS_Pr->SiS_VGAVT     = (ROMAddr[romptr+4] << 4) | ((ROMAddr[romptr+3] & 0xf0) >> 4);
3726  	   SiS_Pr->SiS_HT        = ROMAddr[romptr+5] | ((ROMAddr[romptr+6] & 0x0f) << 8);
3727  	   SiS_Pr->SiS_VT        = (ROMAddr[romptr+7] << 4) | ((ROMAddr[romptr+6] & 0xf0) >> 4);
3728  	   SiS_Pr->SiS_RVBHRS2   = ROMAddr[romptr+8] | ((ROMAddr[romptr+9] & 0x0f) << 8);
3729  	   if((SiS_Pr->SiS_RVBHRS2) && (modeflag & HalfDCLK)) {
3730  	      SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
3731  	      tempax = (ROMAddr[romptr+9] >> 4) & 0x07;
3732  	      if(ROMAddr[romptr+9] & 0x80) SiS_Pr->SiS_RVBHRS2 -= tempax;
3733  	      else                         SiS_Pr->SiS_RVBHRS2 += tempax;
3734  	   }
3735  	   if(SiS_Pr->SiS_VGAHT) gotit = true;
3736  	   else {
3737  	      SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
3738  	      SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
3739  	      SiS_Pr->SiS_RVBHCMAX  = 1;
3740  	      SiS_Pr->SiS_RVBHCFACT = 1;
3741  	      SiS_Pr->SiS_VGAHT   = SiS_Pr->PanelHT;
3742  	      SiS_Pr->SiS_VGAVT   = SiS_Pr->PanelVT;
3743  	      SiS_Pr->SiS_HT      = SiS_Pr->PanelHT;
3744  	      SiS_Pr->SiS_VT      = SiS_Pr->PanelVT;
3745  	      SiS_Pr->SiS_RVBHRS2 = 0;
3746  	      gotit = true;
3747  	   }
3748  #endif
3749  
3750  	}
3751  
3752  	if(!gotit) {
3753  
3754  	   SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3755  			  &CRT2Index,&ResIndex);
3756  
3757  	   switch(CRT2Index) {
3758  	      case Panel_1024x768      : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;   break;
3759  	      case Panel_1024x768  + 32: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data;   break;
3760  	      case Panel_1280x720      :
3761  	      case Panel_1280x720  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x720Data;      break;
3762  	      case Panel_1280x768_2    : LCDPtr = SiS_Pr->SiS_ExtLCD1280x768_2Data; break;
3763  	      case Panel_1280x768_2+ 32: LCDPtr = SiS_Pr->SiS_StLCD1280x768_2Data;  break;
3764  	      case Panel_1280x800      :
3765  	      case Panel_1280x800  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x800Data;      break;
3766  	      case Panel_1280x800_2    :
3767  	      case Panel_1280x800_2+ 32: LCDPtr = SiS_Pr->SiS_LCD1280x800_2Data;    break;
3768  	      case Panel_1280x854      :
3769  	      case Panel_1280x854  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x854Data;      break;
3770  	      case Panel_1280x960      :
3771  	      case Panel_1280x960  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x960Data;      break;
3772  	      case Panel_1280x1024     : LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data;  break;
3773  	      case Panel_1280x1024 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data;  break;
3774  	      case Panel_1400x1050     : LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data;  break;
3775  	      case Panel_1400x1050 + 32: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data;   break;
3776  	      case Panel_1600x1200     : LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data;  break;
3777  	      case Panel_1600x1200 + 32: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data;   break;
3778  	      case Panel_1680x1050     :
3779  	      case Panel_1680x1050 + 32: LCDPtr = SiS_Pr->SiS_LCD1680x1050Data;     break;
3780  	      case 100		       : LCDPtr = SiS_Pr->SiS_NoScaleData;	    break;
3781  #ifdef CONFIG_FB_SIS_315
3782  	      case 200                 : LCDPtr = SiS310_ExtCompaq1280x1024Data;    break;
3783  	      case 201                 : LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data;  break;
3784  #endif
3785  	      default                  : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;   break;
3786  	   }
3787  
3788  	   SiS_Pr->SiS_RVBHCMAX  = (LCDPtr+ResIndex)->RVBHCMAX;
3789  	   SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
3790  	   SiS_Pr->SiS_VGAHT     = (LCDPtr+ResIndex)->VGAHT;
3791  	   SiS_Pr->SiS_VGAVT     = (LCDPtr+ResIndex)->VGAVT;
3792  	   SiS_Pr->SiS_HT        = (LCDPtr+ResIndex)->LCDHT;
3793  	   SiS_Pr->SiS_VT        = (LCDPtr+ResIndex)->LCDVT;
3794  
3795          }
3796  
3797  	tempax = SiS_Pr->PanelXRes;
3798  	tempbx = SiS_Pr->PanelYRes;
3799  
3800  	switch(SiS_Pr->SiS_LCDResInfo) {
3801  	case Panel_1024x768:
3802  	   if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
3803  	      if(SiS_Pr->ChipType < SIS_315H) {
3804  		 if     (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3805  		 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3806  	      }
3807  	   } else {
3808  	      if     (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
3809  	      else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
3810  	      else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
3811  	      else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
3812  	      else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3813  	      else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3814  	   }
3815  	   break;
3816  	case Panel_1280x960:
3817  	   if     (SiS_Pr->SiS_VGAVDE == 350)  tempbx = 700;
3818  	   else if(SiS_Pr->SiS_VGAVDE == 400)  tempbx = 800;
3819  	   else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
3820  	   break;
3821  	case Panel_1280x1024:
3822  	   if     (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
3823  	   else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
3824  	   else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
3825  	   break;
3826  	case Panel_1600x1200:
3827  	   if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
3828  	      if     (SiS_Pr->SiS_VGAVDE == 350)  tempbx = 875;
3829  	      else if(SiS_Pr->SiS_VGAVDE == 400)  tempbx = 1000;
3830  	   }
3831  	   break;
3832  	}
3833  
3834  	if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3835  	   tempax = SiS_Pr->SiS_VGAHDE;
3836  	   tempbx = SiS_Pr->SiS_VGAVDE;
3837  	}
3838  
3839  	SiS_Pr->SiS_HDE = tempax;
3840  	SiS_Pr->SiS_VDE = tempbx;
3841       }
3842    }
3843  }
3844  
3845  static void
SiS_GetCRT2Data(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)3846  SiS_GetCRT2Data(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3847                  unsigned short RefreshRateTableIndex)
3848  {
3849  
3850     if(SiS_Pr->SiS_VBType & VB_SISVB) {
3851  
3852        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
3853           SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3854        } else {
3855  	 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3856  	    /* Need LVDS Data for LCD on 301B-DH */
3857  	    SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3858  	 } else {
3859  	    SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3860  	 }
3861        }
3862  
3863     } else {
3864  
3865        SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3866  
3867     }
3868  }
3869  
3870  /*********************************************/
3871  /*         GET LVDS DES (SKEW) DATA          */
3872  /*********************************************/
3873  
3874  static const struct SiS_LVDSDes *
SiS_GetLVDSDesPtr(struct SiS_Private * SiS_Pr)3875  SiS_GetLVDSDesPtr(struct SiS_Private *SiS_Pr)
3876  {
3877     const struct SiS_LVDSDes *PanelDesPtr = NULL;
3878  
3879  #ifdef CONFIG_FB_SIS_300
3880     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3881  
3882        if(SiS_Pr->ChipType < SIS_315H) {
3883  	 if(SiS_Pr->SiS_LCDTypeInfo == 4) {
3884  	    if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3885  	       PanelDesPtr = SiS_Pr->SiS_PanelType04_1a;
3886  	       if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3887  		  PanelDesPtr = SiS_Pr->SiS_PanelType04_2a;
3888  	       }
3889              } else if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
3890  	       PanelDesPtr = SiS_Pr->SiS_PanelType04_1b;
3891  	       if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3892  		  PanelDesPtr = SiS_Pr->SiS_PanelType04_2b;
3893  	       }
3894  	    }
3895  	 }
3896        }
3897     }
3898  #endif
3899     return PanelDesPtr;
3900  }
3901  
3902  static void
SiS_GetLVDSDesData(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)3903  SiS_GetLVDSDesData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3904                     unsigned short RefreshRateTableIndex)
3905  {
3906    unsigned short modeflag, ResIndex;
3907    const struct SiS_LVDSDes *PanelDesPtr = NULL;
3908  
3909    SiS_Pr->SiS_LCDHDES = 0;
3910    SiS_Pr->SiS_LCDVDES = 0;
3911  
3912    /* Some special cases */
3913    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3914  
3915       /* Trumpion */
3916       if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
3917  	if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3918  	   if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3919  	      SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3920  	   }
3921  	}
3922  	return;
3923       }
3924  
3925       /* 640x480 on LVDS */
3926       if(SiS_Pr->ChipType < SIS_315H) {
3927  	if(SiS_Pr->SiS_LCDResInfo == Panel_640x480 && SiS_Pr->SiS_LCDTypeInfo == 3) {
3928  	   SiS_Pr->SiS_LCDHDES = 8;
3929  	   if     (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
3930  	   else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
3931  	   else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
3932  	   return;
3933  	}
3934       }
3935  
3936    } /* LCD */
3937  
3938    if( (SiS_Pr->UseCustomMode) 		         ||
3939        (SiS_Pr->SiS_LCDResInfo == Panel_Custom)   ||
3940        (SiS_Pr->SiS_CustomT == CUT_PANEL848)      ||
3941        (SiS_Pr->SiS_CustomT == CUT_PANEL856)      ||
3942        (SiS_Pr->SiS_LCDInfo & LCDPass11) ) {
3943       return;
3944    }
3945  
3946    if(ModeNo <= 0x13) ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3947    else               ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
3948  
3949    if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3950  
3951  #ifdef CONFIG_FB_SIS_315
3952       if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3953  	/* non-pass 1:1 only, see above */
3954  	if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
3955  	   SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
3956  	}
3957  	if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
3958  	   SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
3959  	}
3960       }
3961       if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3962  	switch(SiS_Pr->SiS_CustomT) {
3963  	case CUT_UNIWILL1024:
3964  	case CUT_UNIWILL10242:
3965  	case CUT_CLEVO1400:
3966  	   if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3967  	      SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3968  	   }
3969  	   break;
3970  	}
3971  	switch(SiS_Pr->SiS_LCDResInfo) {
3972  	case Panel_1280x1024:
3973  	   if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
3974  	      SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3975  	   }
3976  	   break;
3977  	case Panel_1280x800:	/* Verified for Averatec 6240 */
3978  	case Panel_1280x800_2:	/* Verified for Asus A4L */
3979  	case Panel_1280x854:    /* Not verified yet FIXME */
3980  	   SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3981  	   break;
3982  	}
3983       }
3984  #endif
3985  
3986    } else {
3987  
3988       if((SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
3989  
3990  	if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
3991  	   if(ResIndex <= 3) SiS_Pr->SiS_LCDHDES = 256;
3992  	}
3993  
3994       } else if((PanelDesPtr = SiS_GetLVDSDesPtr(SiS_Pr))) {
3995  
3996  	SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
3997  	SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;
3998  
3999       } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
4000  
4001  	if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
4002  	   SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
4003  	}
4004  	if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
4005  	   SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
4006  	} else {
4007  	   if(SiS_Pr->ChipType < SIS_315H) {
4008  	      SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
4009  	   } else {
4010  	      switch(SiS_Pr->SiS_LCDResInfo) {
4011  	      case Panel_800x600:
4012  	      case Panel_1024x768:
4013  	      case Panel_1280x1024:
4014  		 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
4015  		 break;
4016  	      case Panel_1400x1050:
4017  		 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
4018  		 break;
4019  	      }
4020  	   }
4021  	}
4022  
4023       } else {
4024  
4025          if(SiS_Pr->ChipType < SIS_315H) {
4026  #ifdef CONFIG_FB_SIS_300
4027  	   switch(SiS_Pr->SiS_LCDResInfo) {
4028  	   case Panel_800x600:
4029  	      if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
4030  		 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
4031  	      } else {
4032  		 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT + 3;
4033  		 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
4034  		 if(SiS_Pr->SiS_VGAVDE == 400) SiS_Pr->SiS_LCDVDES -= 2;
4035  		 else                          SiS_Pr->SiS_LCDVDES -= 4;
4036  	      }
4037  	      break;
4038  	   case Panel_1024x768:
4039  	      if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
4040  		 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
4041  	      } else {
4042  		 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
4043  		 if(SiS_Pr->SiS_VGAVDE <= 400) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 8;
4044  		 if(SiS_Pr->SiS_VGAVDE <= 350) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 12;
4045  	      }
4046  	      break;
4047  	   case Panel_1024x600:
4048  	   default:
4049  	      if( (SiS_Pr->SiS_VGAHDE == SiS_Pr->PanelXRes) &&
4050  		  (SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) ) {
4051  		 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
4052  	      } else {
4053  		 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
4054  	      }
4055  	      break;
4056  	   }
4057  
4058  	   switch(SiS_Pr->SiS_LCDTypeInfo) {
4059  	   case 1:
4060  	      SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
4061  	      break;
4062  	   case 3: /* 640x480 only? */
4063  	      SiS_Pr->SiS_LCDHDES = 8;
4064  	      if     (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
4065  	      else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
4066  	      else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
4067  	      break;
4068  	   }
4069  #endif
4070          } else {
4071  #ifdef CONFIG_FB_SIS_315
4072  	   switch(SiS_Pr->SiS_LCDResInfo) {
4073  	   case Panel_1024x768:
4074  	   case Panel_1280x1024:
4075  	      if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
4076  	         SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
4077  	      }
4078  	      break;
4079  	   case Panel_320x240_1:
4080  	   case Panel_320x240_2:
4081  	   case Panel_320x240_3:
4082  	      SiS_Pr->SiS_LCDVDES = 524;
4083  	      break;
4084  	   }
4085  #endif
4086  	}
4087       }
4088  
4089       if((ModeNo <= 0x13) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
4090  	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
4091  	if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
4092  	   if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 632;
4093  	} else if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) {
4094  	   if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
4095  	      if(SiS_Pr->SiS_LCDResInfo >= Panel_1024x768) {
4096  	         if(SiS_Pr->ChipType < SIS_315H) {
4097  	            if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320;
4098  	         } else {
4099  #ifdef CONFIG_FB_SIS_315
4100  		    if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)  SiS_Pr->SiS_LCDHDES = 480;
4101  		    if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 804;
4102  		    if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 704;
4103  		    if(!(modeflag & HalfDCLK)) {
4104  		       SiS_Pr->SiS_LCDHDES = 320;
4105  		       if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 632;
4106  		       if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 542;
4107          	    }
4108  #endif
4109  		 }
4110  	      }
4111  	   }
4112  	}
4113       }
4114    }
4115  }
4116  
4117  /*********************************************/
4118  /*           DISABLE VIDEO BRIDGE            */
4119  /*********************************************/
4120  
4121  #ifdef CONFIG_FB_SIS_315
4122  static int
SiS_HandlePWD(struct SiS_Private * SiS_Pr)4123  SiS_HandlePWD(struct SiS_Private *SiS_Pr)
4124  {
4125     int ret = 0;
4126  #ifdef SET_PWD
4127     unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
4128     unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
4129     unsigned char  drivermode = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40;
4130     unsigned short temp;
4131  
4132     if( (SiS_Pr->SiS_VBType & VB_SISPWD) &&
4133         (romptr)				&&
4134         (SiS_Pr->SiS_PWDOffset) ) {
4135        SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2b,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 0]);
4136        SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2c,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 1]);
4137        SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2d,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 2]);
4138        SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2e,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 3]);
4139        SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2f,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 4]);
4140        temp = 0x00;
4141        if((ROMAddr[romptr + 2] & (0x06 << 1)) && !drivermode) {
4142           temp = 0x80;
4143  	 ret = 1;
4144        }
4145        SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x27,0x7f,temp);
4146     }
4147  #endif
4148     return ret;
4149  }
4150  #endif
4151  
4152  /* NEVER use any variables (VBInfo), this will be called
4153   * from outside the context of modeswitch!
4154   * MUST call getVBType before calling this
4155   */
4156  void
SiS_DisableBridge(struct SiS_Private * SiS_Pr)4157  SiS_DisableBridge(struct SiS_Private *SiS_Pr)
4158  {
4159  #ifdef CONFIG_FB_SIS_315
4160    unsigned short tempah, pushax=0, modenum;
4161  #endif
4162    unsigned short temp=0;
4163  
4164    if(SiS_Pr->SiS_VBType & VB_SISVB) {
4165  
4166       if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {		/* ===== For 30xB/C/LV ===== */
4167  
4168  	if(SiS_Pr->ChipType < SIS_315H) {
4169  
4170  #ifdef CONFIG_FB_SIS_300	   /* 300 series */
4171  
4172  	   if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4173  	      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4174  		 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
4175  	      } else {
4176  		 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4177  	      }
4178  	      SiS_PanelDelay(SiS_Pr, 3);
4179  	   }
4180  	   if(SiS_Is301B(SiS_Pr)) {
4181  	      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);
4182  	      SiS_ShortDelay(SiS_Pr,1);
4183  	   }
4184  	   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
4185  	   SiS_DisplayOff(SiS_Pr);
4186  	   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4187  	   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4188  	   SiS_UnLockCRT2(SiS_Pr);
4189  	   if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) {
4190  	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
4191  	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
4192  	   }
4193  	   if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4194  	       (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4195  	      SiS_PanelDelay(SiS_Pr, 2);
4196  	      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4197  	         SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
4198  	      } else {
4199  		 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4200  	      }
4201  	   }
4202  
4203  #endif  /* CONFIG_FB_SIS_300 */
4204  
4205          } else {
4206  
4207  #ifdef CONFIG_FB_SIS_315	   /* 315 series */
4208  
4209  	   int didpwd = 0;
4210  	   bool custom1 = (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
4211  	                  (SiS_Pr->SiS_CustomT == CUT_CLEVO1400);
4212  
4213  	   modenum = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34) & 0x7f;
4214  
4215  	   if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4216  
4217  #ifdef SET_EMI
4218  	      if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4219  		 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
4220  		    SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4221  		 }
4222  	      }
4223  #endif
4224  
4225  	      didpwd = SiS_HandlePWD(SiS_Pr);
4226  
4227  	      if( (modenum <= 0x13)           ||
4228  		  (SiS_IsVAMode(SiS_Pr))      ||
4229  		  (!(SiS_IsDualEdge(SiS_Pr))) ) {
4230  		 if(!didpwd) {
4231  		    SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfe);
4232  		    if(custom1) SiS_PanelDelay(SiS_Pr, 3);
4233  		 } else {
4234  		    SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfc);
4235  		 }
4236  	      }
4237  
4238  	      if(!custom1) {
4239  		 SiS_DDC2Delay(SiS_Pr,0xff00);
4240  		 SiS_DDC2Delay(SiS_Pr,0xe000);
4241  		 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
4242  		 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
4243  		 if(IS_SIS740) {
4244  		    SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
4245  		 }
4246  	         SiS_PanelDelay(SiS_Pr, 3);
4247  	      }
4248  
4249  	   }
4250  
4251  	   if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4252  	      /* if(SiS_Pr->ChipType < SIS_340) {*/
4253  		 tempah = 0xef;
4254  		 if(SiS_IsVAMode(SiS_Pr)) tempah = 0xf7;
4255  		 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
4256  	      /*}*/
4257  	   }
4258  
4259  	   if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4260  	      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,~0x10);
4261  	   }
4262  
4263  	   tempah = 0x3f;
4264  	   if(SiS_IsDualEdge(SiS_Pr)) {
4265  	      tempah = 0x7f;
4266  	      if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0xbf;
4267  	   }
4268  	   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4269  
4270  	   if((SiS_IsVAMode(SiS_Pr)) ||
4271  	      ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
4272  
4273  	      SiS_DisplayOff(SiS_Pr);
4274  	      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4275  		 SiS_PanelDelay(SiS_Pr, 2);
4276  	      }
4277  	      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4278  	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
4279  
4280  	   }
4281  
4282  	   if((!(SiS_IsVAMode(SiS_Pr))) ||
4283  	      ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
4284  
4285  	      if(!(SiS_IsDualEdge(SiS_Pr))) {
4286  		 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
4287  		 SiS_DisplayOff(SiS_Pr);
4288  	      }
4289  	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4290  
4291  	      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4292  		 SiS_PanelDelay(SiS_Pr, 2);
4293  	      }
4294  
4295  	      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4296  	      temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
4297  	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
4298  	      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4299  	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
4300  
4301  	   }
4302  
4303  	   if(SiS_IsNotM650orLater(SiS_Pr)) {
4304  	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4305  	   }
4306  
4307  	   if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4308  
4309  	      if( (!(SiS_IsVAMode(SiS_Pr)))  &&
4310  		  (!(SiS_CRT2IsLCD(SiS_Pr))) &&
4311  		  (!(SiS_IsDualEdge(SiS_Pr))) ) {
4312  
4313  		 if(custom1) SiS_PanelDelay(SiS_Pr, 2);
4314  		 if(!didpwd) {
4315  		    SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
4316  		 }
4317  		 if(custom1) SiS_PanelDelay(SiS_Pr, 4);
4318  	      }
4319  
4320  	      if(!custom1) {
4321  		 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4322  		 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4323  		    if(SiS_IsVAorLCD(SiS_Pr)) {
4324  		       SiS_PanelDelayLoop(SiS_Pr, 3, 20);
4325  		    }
4326  		 }
4327  	      }
4328  
4329  	   }
4330  
4331  #endif /* CONFIG_FB_SIS_315 */
4332  
4333  	}
4334  
4335       } else {     /* ============ For 301 ================ */
4336  
4337          if(SiS_Pr->ChipType < SIS_315H) {
4338  #ifdef CONFIG_FB_SIS_300
4339  	   if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4340  	      SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4341  	      SiS_PanelDelay(SiS_Pr, 3);
4342  	   }
4343  #endif
4344  	}
4345  
4346  	SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);           /* disable VB */
4347  	SiS_DisplayOff(SiS_Pr);
4348  
4349  	if(SiS_Pr->ChipType >= SIS_315H) {
4350  	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4351  	}
4352  
4353  	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);                /* disable lock mode */
4354  
4355  	if(SiS_Pr->ChipType >= SIS_315H) {
4356  	    temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
4357  	    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
4358  	    SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4359  	    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
4360  	} else {
4361  #ifdef CONFIG_FB_SIS_300
4362  	    SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);            /* disable CRT2 */
4363  	    if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4364  		(!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4365  		SiS_PanelDelay(SiS_Pr, 2);
4366  		SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4367  	    }
4368  #endif
4369  	}
4370  
4371        }
4372  
4373    } else {     /* ============ For LVDS =============*/
4374  
4375      if(SiS_Pr->ChipType < SIS_315H) {
4376  
4377  #ifdef CONFIG_FB_SIS_300	/* 300 series */
4378  
4379  	if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4380  	   SiS_SetCH700x(SiS_Pr,0x0E,0x09);
4381  	}
4382  
4383  	if(SiS_Pr->ChipType == SIS_730) {
4384  	   if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4385  	      SiS_WaitVBRetrace(SiS_Pr);
4386  	   }
4387  	   if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4388  	      SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4389  	      SiS_PanelDelay(SiS_Pr, 3);
4390  	   }
4391  	} else {
4392  	   if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4393  	      if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4394  		 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4395  		    SiS_WaitVBRetrace(SiS_Pr);
4396  		    if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {
4397  		       SiS_DisplayOff(SiS_Pr);
4398  		    }
4399  		    SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4400  		    SiS_PanelDelay(SiS_Pr, 3);
4401  		 }
4402  	      }
4403  	   }
4404  	}
4405  
4406  	SiS_DisplayOff(SiS_Pr);
4407  
4408  	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4409  
4410  	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4411  	SiS_UnLockCRT2(SiS_Pr);
4412  	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
4413  	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
4414  
4415  	if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4416  	    (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4417  	   SiS_PanelDelay(SiS_Pr, 2);
4418  	   SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4419  	}
4420  
4421  #endif  /* CONFIG_FB_SIS_300 */
4422  
4423      } else {
4424  
4425  #ifdef CONFIG_FB_SIS_315	/* 315 series */
4426  
4427  	if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4428  	   /*if(SiS_Pr->ChipType < SIS_340) { */ /* XGI needs this */
4429  	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,~0x18);
4430  	   /* } */
4431  	}
4432  
4433  	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4434  
4435  	   if(SiS_Pr->ChipType == SIS_740) {
4436  	      temp = SiS_GetCH701x(SiS_Pr,0x61);
4437  	      if(temp < 1) {
4438  		 SiS_SetCH701x(SiS_Pr,0x76,0xac);
4439  		 SiS_SetCH701x(SiS_Pr,0x66,0x00);
4440  	      }
4441  
4442  	      if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4443  		  (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
4444  		 SiS_SetCH701x(SiS_Pr,0x49,0x3e);
4445  	      }
4446  	   }
4447  
4448  	   if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4449  	       (SiS_IsVAMode(SiS_Pr)) ) {
4450  	      SiS_Chrontel701xBLOff(SiS_Pr);
4451  	      SiS_Chrontel701xOff(SiS_Pr);
4452  	   }
4453  
4454  	   if(SiS_Pr->ChipType != SIS_740) {
4455  	      if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4456  		  (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
4457  		 SiS_SetCH701x(SiS_Pr,0x49,0x01);
4458  	      }
4459  	   }
4460  
4461  	}
4462  
4463  	if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4464  	   SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4465  	   SiS_PanelDelay(SiS_Pr, 3);
4466  	}
4467  
4468  	if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
4469  	    (!(SiS_IsDualEdge(SiS_Pr))) ||
4470  	    (!(SiS_IsTVOrYPbPrOrScart(SiS_Pr))) ) {
4471  	   SiS_DisplayOff(SiS_Pr);
4472  	}
4473  
4474  	if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
4475  	    (!(SiS_IsDualEdge(SiS_Pr))) ||
4476  	    (!(SiS_IsVAMode(SiS_Pr))) ) {
4477  	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4478  	}
4479  
4480  	if(SiS_Pr->ChipType == SIS_740) {
4481  	   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4482  	}
4483  
4484  	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4485  
4486  	if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
4487  	    (!(SiS_IsDualEdge(SiS_Pr))) ||
4488  	    (!(SiS_IsVAMode(SiS_Pr))) ) {
4489  	   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4490  	}
4491  
4492  	if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4493  	   if(SiS_CRT2IsLCD(SiS_Pr)) {
4494  	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4495  	      if(SiS_Pr->ChipType == SIS_550) {
4496  		 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xbf);
4497  		 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xef);
4498  	      }
4499  	   }
4500  	} else {
4501  	   if(SiS_Pr->ChipType == SIS_740) {
4502  	      if(SiS_IsLCDOrLCDA(SiS_Pr)) {
4503  		 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4504  	      }
4505  	   } else if(SiS_IsVAMode(SiS_Pr)) {
4506  	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4507  	   }
4508  	}
4509  
4510  	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4511  	   if(SiS_IsDualEdge(SiS_Pr)) {
4512  	      /* SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff); */
4513  	   } else {
4514  	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
4515  	   }
4516  	}
4517  
4518  	SiS_UnLockCRT2(SiS_Pr);
4519  
4520  	if(SiS_Pr->ChipType == SIS_550) {
4521  	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); /* DirectDVD PAL?*/
4522  	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); /* VB clock / 4 ? */
4523  	} else if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
4524  		   (!(SiS_IsDualEdge(SiS_Pr))) ||
4525  		   (!(SiS_IsVAMode(SiS_Pr))) ) {
4526  	   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4527  	}
4528  
4529          if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4530  	   if(SiS_CRT2IsLCD(SiS_Pr)) {
4531  	      if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4532  		 SiS_PanelDelay(SiS_Pr, 2);
4533  		 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4534  	      }
4535  	   }
4536          }
4537  
4538  #endif  /* CONFIG_FB_SIS_315 */
4539  
4540      }  /* 315 series */
4541  
4542    }  /* LVDS */
4543  
4544  }
4545  
4546  /*********************************************/
4547  /*            ENABLE VIDEO BRIDGE            */
4548  /*********************************************/
4549  
4550  /* NEVER use any variables (VBInfo), this will be called
4551   * from outside the context of a mode switch!
4552   * MUST call getVBType before calling this
4553   */
4554  static
4555  void
SiS_EnableBridge(struct SiS_Private * SiS_Pr)4556  SiS_EnableBridge(struct SiS_Private *SiS_Pr)
4557  {
4558    unsigned short temp=0, tempah;
4559  #ifdef CONFIG_FB_SIS_315
4560    unsigned short temp1, pushax=0;
4561    bool delaylong = false;
4562  #endif
4563  
4564    if(SiS_Pr->SiS_VBType & VB_SISVB) {
4565  
4566      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {		/* ====== For 301B et al  ====== */
4567  
4568        if(SiS_Pr->ChipType < SIS_315H) {
4569  
4570  #ifdef CONFIG_FB_SIS_300     /* 300 series */
4571  
4572  	 if(SiS_CRT2IsLCD(SiS_Pr)) {
4573  	    if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4574  	       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4575  	    } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
4576  	       SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4577  	    }
4578  	    if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_NoLCD)) {
4579  	       if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
4580  		  SiS_PanelDelay(SiS_Pr, 0);
4581  	       }
4582  	    }
4583  	 }
4584  
4585  	 if((SiS_Pr->SiS_VBType & VB_NoLCD) &&
4586  	    (SiS_CRT2IsLCD(SiS_Pr))) {
4587  
4588  	    SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);   		/* Enable CRT2 */
4589  	    SiS_DisplayOn(SiS_Pr);
4590  	    SiS_UnLockCRT2(SiS_Pr);
4591  	    SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4592  	    if(SiS_BridgeInSlavemode(SiS_Pr)) {
4593  	       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4594  	    } else {
4595  	       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4596  	    }
4597  	    if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4598  	       if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4599  		  if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4600  		     SiS_PanelDelay(SiS_Pr, 1);
4601  		  }
4602  		  SiS_WaitVBRetrace(SiS_Pr);
4603  		  SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4604  	       }
4605  	    }
4606  
4607  	 } else {
4608  
4609  	    temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;             /* lock mode */
4610  	    if(SiS_BridgeInSlavemode(SiS_Pr)) {
4611  	       tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4612  	       if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4613  	    }
4614  	    SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4615  	    SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4616  	    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20);        /* enable VB processor */
4617  	    SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
4618  	    SiS_DisplayOn(SiS_Pr);
4619  	    if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4620  	       if(SiS_CRT2IsLCD(SiS_Pr)) {
4621  		  if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4622  		     if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4623  		        SiS_PanelDelay(SiS_Pr, 1);
4624  		     }
4625  		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4626  		  }
4627  	       }
4628  	    }
4629  
4630  	 }
4631  
4632  
4633  #endif /* CONFIG_FB_SIS_300 */
4634  
4635        } else {
4636  
4637  #ifdef CONFIG_FB_SIS_315    /* 315 series */
4638  
4639  #ifdef SET_EMI
4640  	 unsigned char   r30=0, r31=0, r32=0, r33=0, cr36=0;
4641  	 int didpwd = 0;
4642  	 /* unsigned short  emidelay=0; */
4643  #endif
4644  
4645  	 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4646  	    SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef);
4647  #ifdef SET_EMI
4648  	    if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4649  	       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4650  	    }
4651  #endif
4652  	 }
4653  
4654  	 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4655  	    /*if(SiS_Pr->ChipType < SIS_340) { */
4656  	       tempah = 0x10;
4657  	       if(SiS_LCDAEnabled(SiS_Pr)) {
4658  		  if(SiS_TVEnabled(SiS_Pr)) tempah = 0x18;
4659  		  else			    tempah = 0x08;
4660  	       }
4661  	       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah);
4662  	    /*}*/
4663  	 }
4664  
4665  	 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4666  
4667  	    SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
4668  	    SiS_DisplayOff(SiS_Pr);
4669  	    pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
4670  	    if(IS_SIS740) {
4671  	       SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
4672  	    }
4673  
4674  	    didpwd = SiS_HandlePWD(SiS_Pr);
4675  
4676  	    if(SiS_IsVAorLCD(SiS_Pr)) {
4677  	       if(!didpwd) {
4678  		  if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
4679  		     SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4680  		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4681  		     SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4682  		     if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4683  		        SiS_GenericDelay(SiS_Pr, 17664);
4684  		     }
4685  		  }
4686  	       } else {
4687  		  SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4688  		  if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4689  		     SiS_GenericDelay(SiS_Pr, 17664);
4690  		  }
4691  	       }
4692  	    }
4693  
4694  	    if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {
4695  	       SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4696  	       delaylong = true;
4697  	    }
4698  
4699  	 }
4700  
4701  	 if(!(SiS_IsVAMode(SiS_Pr))) {
4702  
4703  	    temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
4704  	    if(SiS_BridgeInSlavemode(SiS_Pr)) {
4705  	       tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4706  	       if(!(tempah & SetCRT2ToRAMDAC)) {
4707  		  if(!(SiS_LCDAEnabled(SiS_Pr))) temp |= 0x20;
4708  	       }
4709  	    }
4710  	    SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4711  
4712  	    SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                   /* enable CRT2 */
4713  
4714  	    SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4715  	    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4716  
4717  	    if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4718  	       SiS_PanelDelay(SiS_Pr, 2);
4719  	    }
4720  
4721  	 } else {
4722  
4723  	    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20);
4724  
4725  	 }
4726  
4727  	 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
4728  	 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4729  
4730  	 if(SiS_Pr->SiS_VBType & VB_SISPOWER) {
4731  	    if( (SiS_LCDAEnabled(SiS_Pr)) ||
4732  	        (SiS_CRT2IsLCD(SiS_Pr)) ) {
4733  	       /* Enable "LVDS PLL power on" (even on 301C) */
4734  	       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);
4735  	       /* Enable "LVDS Driver Power on" (even on 301C) */
4736  	       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x7f);
4737  	    }
4738  	 }
4739  
4740  	 tempah = 0xc0;
4741  	 if(SiS_IsDualEdge(SiS_Pr)) {
4742  	    tempah = 0x80;
4743  	    if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0x40;
4744  	 }
4745  	 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4746  
4747  	 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4748  
4749  	    SiS_PanelDelay(SiS_Pr, 2);
4750  
4751  	    SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10);
4752  	    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4753  
4754  	    if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
4755  #ifdef SET_EMI
4756  	       if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4757  		  SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4758  		  SiS_GenericDelay(SiS_Pr, 2048);
4759  	       }
4760  #endif
4761  	       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
4762  
4763  	       if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4764  #ifdef SET_EMI
4765  		  cr36 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
4766  
4767  		  if(SiS_Pr->SiS_ROMNew) {
4768  		     unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
4769  		     unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
4770  		     if(romptr) {
4771  			SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4772  			SiS_Pr->EMI_30 = 0;
4773  			SiS_Pr->EMI_31 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 0];
4774  			SiS_Pr->EMI_32 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 1];
4775  			SiS_Pr->EMI_33 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 2];
4776  			if(ROMAddr[romptr + 1] & 0x10) SiS_Pr->EMI_30 = 0x40;
4777  			/* emidelay = SISGETROMW((romptr + 0x22)); */
4778  			SiS_Pr->HaveEMI = SiS_Pr->HaveEMILCD = SiS_Pr->OverruleEMI = true;
4779  		     }
4780  		  }
4781  
4782  		  /*                                              (P4_30|0x40)  */
4783  		  /* Compal 1400x1050: 0x05, 0x60, 0x00                YES  (1.10.7w;  CR36=69)      */
4784  		  /* Compal 1400x1050: 0x0d, 0x70, 0x40                YES  (1.10.7x;  CR36=69)      */
4785  		  /* Acer   1280x1024: 0x12, 0xd0, 0x6b                NO   (1.10.9k;  CR36=73)      */
4786  		  /* Compaq 1280x1024: 0x0d, 0x70, 0x6b                YES  (1.12.04b; CR36=03)      */
4787  		  /* Clevo   1024x768: 0x05, 0x60, 0x33                NO   (1.10.8e;  CR36=12, DL!) */
4788  		  /* Clevo   1024x768: 0x0d, 0x70, 0x40 (if type == 3) YES  (1.10.8y;  CR36=?2)      */
4789  		  /* Clevo   1024x768: 0x05, 0x60, 0x33 (if type != 3) YES  (1.10.8y;  CR36=?2)      */
4790  		  /* Asus    1024x768: ?                                ?   (1.10.8o;  CR36=?2)      */
4791  		  /* Asus    1024x768: 0x08, 0x10, 0x3c (problematic)  YES  (1.10.8q;  CR36=22)      */
4792  
4793  		  if(SiS_Pr->HaveEMI) {
4794  		     r30 = SiS_Pr->EMI_30; r31 = SiS_Pr->EMI_31;
4795  		     r32 = SiS_Pr->EMI_32; r33 = SiS_Pr->EMI_33;
4796  		  } else {
4797  		     r30 = 0;
4798  		  }
4799  
4800  		  /* EMI_30 is read at driver start; however, the BIOS sets this
4801  		   * (if it is used) only if the LCD is in use. In case we caught
4802  		   * the machine while on TV output, this bit is not set and we
4803  		   * don't know if it should be set - hence our detection is wrong.
4804  		   * Work-around this here:
4805  		   */
4806  
4807  		  if((!SiS_Pr->HaveEMI) || (!SiS_Pr->HaveEMILCD)) {
4808  		     switch((cr36 & 0x0f)) {
4809  		     case 2:
4810  			r30 |= 0x40;
4811  			if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) r30 &= ~0x40;
4812  			if(!SiS_Pr->HaveEMI) {
4813  			   r31 = 0x05; r32 = 0x60; r33 = 0x33;
4814  			   if((cr36 & 0xf0) == 0x30) {
4815  			      r31 = 0x0d; r32 = 0x70; r33 = 0x40;
4816  			   }
4817  			}
4818  			break;
4819  		     case 3:  /* 1280x1024 */
4820  			if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) r30 |= 0x40;
4821  			if(!SiS_Pr->HaveEMI) {
4822  			   r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4823  			   if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4824  			      r31 = 0x0d; r32 = 0x70; r33 = 0x6b;
4825  			   }
4826  			}
4827  			break;
4828  		     case 9:  /* 1400x1050 */
4829  			r30 |= 0x40;
4830  			if(!SiS_Pr->HaveEMI) {
4831  			   r31 = 0x05; r32 = 0x60; r33 = 0x00;
4832  			   if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4833  			      r31 = 0x0d; r32 = 0x70; r33 = 0x40;  /* BIOS values */
4834  			   }
4835  			}
4836  			break;
4837  		     case 11: /* 1600x1200 - unknown */
4838  			r30 |= 0x40;
4839  			if(!SiS_Pr->HaveEMI) {
4840  			   r31 = 0x05; r32 = 0x60; r33 = 0x00;
4841  			}
4842  		     }
4843                    }
4844  
4845  		  /* BIOS values don't work so well sometimes */
4846  		  if(!SiS_Pr->OverruleEMI) {
4847  #ifdef COMPAL_HACK
4848  		     if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4849  			if((cr36 & 0x0f) == 0x09) {
4850  			   r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x00;
4851  			}
4852   		     }
4853  #endif
4854  #ifdef COMPAQ_HACK
4855  		     if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4856  			if((cr36 & 0x0f) == 0x03) {
4857  			   r30 = 0x20; r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4858  			}
4859  		     }
4860  #endif
4861  #ifdef ASUS_HACK
4862  		     if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4863  			if((cr36 & 0x0f) == 0x02) {
4864  			   /* r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x33;  */   /* rev 2 */
4865  			   /* r30 = 0x20; r31 = 0x05; r32 = 0x60; r33 = 0x33;  */   /* rev 3 */
4866  			   /* r30 = 0x60; r31 = 0x0d; r32 = 0x70; r33 = 0x40;  */   /* rev 4 */
4867  			   /* r30 = 0x20; r31 = 0x0d; r32 = 0x70; r33 = 0x40;  */   /* rev 5 */
4868  			}
4869  		     }
4870  #endif
4871  		  }
4872  
4873  		  if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) {
4874  		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4875  		     SiS_GenericDelay(SiS_Pr, 2048);
4876  		  }
4877  		  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,r31);
4878  		  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,r32);
4879  		  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x33,r33);
4880  #endif	/* SET_EMI */
4881  
4882  		  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
4883  
4884  #ifdef SET_EMI
4885  		  if( (SiS_LCDAEnabled(SiS_Pr)) ||
4886  		      (SiS_CRT2IsLCD(SiS_Pr)) ) {
4887  		     if(r30 & 0x40) {
4888  			/*SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x2a,0x80);*/
4889  			SiS_PanelDelayLoop(SiS_Pr, 3, 5);
4890  			if(delaylong) {
4891  			   SiS_PanelDelayLoop(SiS_Pr, 3, 5);
4892  			   delaylong = false;
4893  			}
4894  			SiS_WaitVBRetrace(SiS_Pr);
4895  			SiS_WaitVBRetrace(SiS_Pr);
4896  			if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4897  			   SiS_GenericDelay(SiS_Pr, 1280);
4898  			}
4899  			SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40);   /* Enable */
4900  			/*SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);*/
4901  		     }
4902  		  }
4903  #endif
4904  	       }
4905  	    }
4906  
4907  	    if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4908  	       if(SiS_IsVAorLCD(SiS_Pr)) {
4909  		  SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4910  		  if(delaylong) {
4911  		     SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4912  		  }
4913  		  SiS_WaitVBRetrace(SiS_Pr);
4914  		  if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4915  		     SiS_GenericDelay(SiS_Pr, 2048);
4916  		     SiS_WaitVBRetrace(SiS_Pr);
4917  		  }
4918  		  if(!didpwd) {
4919  		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4920  		  } else {
4921  		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x03);
4922  		  }
4923  	       }
4924  	    }
4925  
4926  	    SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4927  	    SiS_DisplayOn(SiS_Pr);
4928  	    SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xff);
4929  
4930  	 }
4931  
4932  	 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4933  	    SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4934  	 }
4935  
4936  #endif /* CONFIG_FB_SIS_315 */
4937  
4938        }
4939  
4940      } else {	/* ============  For 301 ================ */
4941  
4942         if(SiS_Pr->ChipType < SIS_315H) {
4943  	  if(SiS_CRT2IsLCD(SiS_Pr)) {
4944  	     SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4945  	     SiS_PanelDelay(SiS_Pr, 0);
4946  	  }
4947         }
4948  
4949         temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;          /* lock mode */
4950         if(SiS_BridgeInSlavemode(SiS_Pr)) {
4951  	  tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4952  	  if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4953         }
4954         SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4955  
4956         SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                  /* enable CRT2 */
4957  
4958         if(SiS_Pr->ChipType >= SIS_315H) {
4959  	  temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4960  	  if(!(temp & 0x80)) {
4961  	     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);         /* BVBDOENABLE=1 */
4962  	  }
4963         }
4964  
4965         SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20);     /* enable VB processor */
4966  
4967         SiS_VBLongWait(SiS_Pr);
4968         SiS_DisplayOn(SiS_Pr);
4969         if(SiS_Pr->ChipType >= SIS_315H) {
4970  	  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4971         }
4972         SiS_VBLongWait(SiS_Pr);
4973  
4974         if(SiS_Pr->ChipType < SIS_315H) {
4975  	  if(SiS_CRT2IsLCD(SiS_Pr)) {
4976  	     SiS_PanelDelay(SiS_Pr, 1);
4977  	     SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4978  	  }
4979         }
4980  
4981      }
4982  
4983    } else {   /* =================== For LVDS ================== */
4984  
4985      if(SiS_Pr->ChipType < SIS_315H) {
4986  
4987  #ifdef CONFIG_FB_SIS_300    /* 300 series */
4988  
4989         if(SiS_CRT2IsLCD(SiS_Pr)) {
4990  	  if(SiS_Pr->ChipType == SIS_730) {
4991  	     SiS_PanelDelay(SiS_Pr, 1);
4992  	     SiS_PanelDelay(SiS_Pr, 1);
4993  	     SiS_PanelDelay(SiS_Pr, 1);
4994  	  }
4995  	  SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4996  	  if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
4997  	     SiS_PanelDelay(SiS_Pr, 0);
4998  	  }
4999         }
5000  
5001         SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
5002         SiS_DisplayOn(SiS_Pr);
5003         SiS_UnLockCRT2(SiS_Pr);
5004         SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
5005         if(SiS_BridgeInSlavemode(SiS_Pr)) {
5006  	  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
5007         } else {
5008  	  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
5009         }
5010  
5011         if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
5012  	  if(!(SiS_CRT2IsLCD(SiS_Pr))) {
5013  	     SiS_WaitVBRetrace(SiS_Pr);
5014  	     SiS_SetCH700x(SiS_Pr,0x0E,0x0B);
5015  	  }
5016         }
5017  
5018         if(SiS_CRT2IsLCD(SiS_Pr)) {
5019  	  if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
5020  	     if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
5021  		if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
5022  		   SiS_PanelDelay(SiS_Pr, 1);
5023  		   SiS_PanelDelay(SiS_Pr, 1);
5024  		}
5025  		SiS_WaitVBRetrace(SiS_Pr);
5026  		SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
5027  	     }
5028  	  }
5029         }
5030  
5031  #endif  /* CONFIG_FB_SIS_300 */
5032  
5033      } else {
5034  
5035  #ifdef CONFIG_FB_SIS_315    /* 315 series */
5036  
5037         if(!(SiS_IsNotM650orLater(SiS_Pr))) {
5038  	  /*if(SiS_Pr->ChipType < SIS_340) {*/  /* XGI needs this */
5039  	     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x18);
5040  	  /*}*/
5041         }
5042  
5043         if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
5044  	  if(SiS_CRT2IsLCD(SiS_Pr)) {
5045  	     SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
5046  	     SiS_PanelDelay(SiS_Pr, 0);
5047  	  }
5048         }
5049  
5050         SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
5051         SiS_UnLockCRT2(SiS_Pr);
5052  
5053         SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
5054  
5055         if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
5056  	  temp = SiS_GetCH701x(SiS_Pr,0x66);
5057  	  temp &= 0x20;
5058  	  SiS_Chrontel701xBLOff(SiS_Pr);
5059         }
5060  
5061         if(SiS_Pr->ChipType != SIS_550) {
5062  	  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
5063         }
5064  
5065         if(SiS_Pr->ChipType == SIS_740) {
5066  	  if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
5067  	     if(SiS_IsLCDOrLCDA(SiS_Pr)) {
5068  		SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
5069  	     }
5070  	  }
5071         }
5072  
5073         temp1 = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
5074         if(!(temp1 & 0x80)) {
5075  	  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
5076         }
5077  
5078         if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
5079  	  if(temp) {
5080  	     SiS_Chrontel701xBLOn(SiS_Pr);
5081  	  }
5082         }
5083  
5084         if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
5085  	  if(SiS_CRT2IsLCD(SiS_Pr)) {
5086  	     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
5087  	     if(SiS_Pr->ChipType == SIS_550) {
5088  		SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x40);
5089  		SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x10);
5090  	     }
5091  	  }
5092         } else if(SiS_IsVAMode(SiS_Pr)) {
5093  	  if(SiS_Pr->ChipType != SIS_740) {
5094  	     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
5095  	  }
5096         }
5097  
5098         if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
5099  	  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
5100         }
5101  
5102         if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
5103  	  if(SiS_IsTVOrYPbPrOrScart(SiS_Pr)) {
5104  	     SiS_Chrontel701xOn(SiS_Pr);
5105  	  }
5106  	  if( (SiS_IsVAMode(SiS_Pr)) ||
5107  	      (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
5108  	     SiS_ChrontelDoSomething1(SiS_Pr);
5109  	  }
5110         }
5111  
5112         if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
5113  	  if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
5114  	     if( (SiS_IsVAMode(SiS_Pr)) ||
5115  		 (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
5116  		SiS_Chrontel701xBLOn(SiS_Pr);
5117  		SiS_ChrontelInitTVVSync(SiS_Pr);
5118  	     }
5119  	  }
5120         } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
5121  	  if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
5122  	     if(SiS_CRT2IsLCD(SiS_Pr)) {
5123  		SiS_PanelDelay(SiS_Pr, 1);
5124  		SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
5125  	     }
5126  	  }
5127         }
5128  
5129  #endif  /* CONFIG_FB_SIS_315 */
5130  
5131      } /* 310 series */
5132  
5133    }  /* LVDS */
5134  
5135  }
5136  
5137  /*********************************************/
5138  /*         SET PART 1 REGISTER GROUP         */
5139  /*********************************************/
5140  
5141  /* Set CRT2 OFFSET / PITCH */
5142  static void
SiS_SetCRT2Offset(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RRTI)5143  SiS_SetCRT2Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
5144  		unsigned short RRTI)
5145  {
5146     unsigned short offset;
5147     unsigned char  temp;
5148  
5149     if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return;
5150  
5151     offset = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,RRTI);
5152  
5153     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(offset & 0xFF));
5154     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,(offset >> 8));
5155  
5156     temp = (unsigned char)(((offset >> 3) & 0xFF) + 1);
5157     if(offset & 0x07) temp++;
5158     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,temp);
5159  }
5160  
5161  /* Set CRT2 sync and PanelLink mode */
5162  static void
SiS_SetCRT2Sync(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short RefreshRateTableIndex)5163  SiS_SetCRT2Sync(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RefreshRateTableIndex)
5164  {
5165     unsigned short tempah=0, tempbl, infoflag;
5166  
5167     tempbl = 0xC0;
5168  
5169     if(SiS_Pr->UseCustomMode) {
5170        infoflag = SiS_Pr->CInfoFlag;
5171     } else {
5172        infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
5173     }
5174  
5175     if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {					/* LVDS */
5176  
5177        if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5178  	 tempah = 0;
5179        } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) {
5180  	 tempah = SiS_Pr->SiS_LCDInfo;
5181        } else tempah = infoflag >> 8;
5182        tempah &= 0xC0;
5183        tempah |= 0x20;
5184        if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5185        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5186  	 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
5187  	    (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
5188  	    tempah |= 0xf0;
5189  	 }
5190  	 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
5191  	     (SiS_Pr->SiS_IF_DEF_DSTN) ||
5192  	     (SiS_Pr->SiS_IF_DEF_TRUMPION) ||
5193  	     (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
5194  	     (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
5195  	    tempah |= 0x30;
5196  	 }
5197  	 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
5198  	     (SiS_Pr->SiS_IF_DEF_DSTN) ) {
5199  	    tempah &= ~0xc0;
5200  	 }
5201        }
5202        if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5203  	 if(SiS_Pr->ChipType >= SIS_315H) {
5204  	    tempah >>= 3;
5205  	    tempah &= 0x18;
5206  	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xE7,tempah);
5207  	    /* Don't care about 12/18/24 bit mode - TV is via VGA, not PL */
5208  	 } else {
5209  	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,0xe0);
5210  	 }
5211        } else {
5212  	 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5213        }
5214  
5215     } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5216  
5217        if(SiS_Pr->ChipType < SIS_315H) {
5218  
5219  #ifdef CONFIG_FB_SIS_300  /* ---- 300 series --- */
5220  
5221  	 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {			/* 630 - 301B(-DH) */
5222  
5223  	    tempah = infoflag >> 8;
5224  	    tempbl = 0;
5225  	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5226  	       if(SiS_Pr->SiS_LCDInfo & LCDSync) {
5227  		  tempah = SiS_Pr->SiS_LCDInfo;
5228  		  tempbl = (tempah >> 6) & 0x03;
5229  	       }
5230  	    }
5231  	    tempah &= 0xC0;
5232  	    tempah |= 0x20;
5233  	    if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5234  	    tempah |= 0xc0;
5235  	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5236  	    if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
5237  	       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
5238  	    }
5239  
5240  	 } else {							/* 630 - 301 */
5241  
5242  	    tempah = ((infoflag >> 8) & 0xc0) | 0x20;
5243  	    if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5244  	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5245  
5246  	 }
5247  
5248  #endif /* CONFIG_FB_SIS_300 */
5249  
5250        } else {
5251  
5252  #ifdef CONFIG_FB_SIS_315  /* ------- 315 series ------ */
5253  
5254  	 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {	  		/* 315 - LVDS */
5255  
5256  	    tempbl = 0;
5257  	    if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
5258  	       (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
5259  	       tempah = infoflag >> 8;
5260  	       if(SiS_Pr->SiS_LCDInfo & LCDSync) {
5261  		 tempbl = ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6);
5262  	       }
5263  	    } else if((SiS_Pr->SiS_CustomT == CUT_CLEVO1400)  &&
5264  		      (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)) {
5265  	       tempah = infoflag >> 8;
5266  	       tempbl = 0x03;
5267  	    } else {
5268  	       tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
5269  	       tempbl = (tempah >> 6) & 0x03;
5270  	       tempbl |= 0x08;
5271  	       if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempbl |= 0x04;
5272  	    }
5273  	    tempah &= 0xC0;
5274  	    tempah |= 0x20;
5275  	    if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5276  	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)   tempah |= 0xc0;
5277  	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5278  	    if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
5279  	       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5280  		  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
5281  	       }
5282  	    }
5283  
5284  	 } else {							/* 315 - TMDS */
5285  
5286  	    tempah = tempbl = infoflag >> 8;
5287  	    if(!SiS_Pr->UseCustomMode) {
5288  	       tempbl = 0;
5289  	       if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
5290  		  if(ModeNo <= 0x13) {
5291  		     tempah = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
5292  		  }
5293  	       }
5294  	       if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5295  		  if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5296  		    if(SiS_Pr->SiS_LCDInfo & LCDSync) {
5297  		       tempah = SiS_Pr->SiS_LCDInfo;
5298  		       tempbl = (tempah >> 6) & 0x03;
5299  		    }
5300  		  }
5301  	       }
5302  	    }
5303  	    tempah &= 0xC0;
5304  	    tempah |= 0x20;
5305  	    if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5306  	    if(SiS_Pr->SiS_VBType & VB_NoLCD) {
5307  	       /* Imitate BIOS bug */
5308  	       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)  tempah |= 0xc0;
5309  	    }
5310  	    if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
5311  	       tempah >>= 3;
5312  	       tempah &= 0x18;
5313  	       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xe7,tempah);
5314  	    } else {
5315  	       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5316  	       if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
5317  		  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5318  		     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
5319  		  }
5320  	       }
5321  	    }
5322  
5323           }
5324  #endif  /* CONFIG_FB_SIS_315 */
5325        }
5326     }
5327  }
5328  
5329  /* Set CRT2 FIFO on 300/540/630/730 */
5330  #ifdef CONFIG_FB_SIS_300
5331  static void
SiS_SetCRT2FIFO_300(struct SiS_Private * SiS_Pr,unsigned short ModeNo)5332  SiS_SetCRT2FIFO_300(struct SiS_Private *SiS_Pr,unsigned short ModeNo)
5333  {
5334    unsigned char  *ROMAddr  = SiS_Pr->VirtualRomBase;
5335    unsigned short temp, index, modeidindex, refreshratetableindex;
5336    unsigned short VCLK = 0, MCLK, colorth = 0, data2 = 0;
5337    unsigned short tempbx, tempcl, CRT1ModeNo, CRT2ModeNo, SelectRate_backup;
5338    unsigned int   data, pci50, pciA0;
5339    static const unsigned char colortharray[] = {
5340    	1, 1, 2, 2, 3, 4
5341    };
5342  
5343    SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;
5344  
5345    if(!SiS_Pr->CRT1UsesCustomMode) {
5346  
5347       CRT1ModeNo = SiS_Pr->SiS_CRT1Mode;                                 /* get CRT1 ModeNo */
5348       SiS_SearchModeID(SiS_Pr, &CRT1ModeNo, &modeidindex);
5349       SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
5350       SiS_Pr->SiS_SelectCRT2Rate = 0;
5351       refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT1ModeNo, modeidindex);
5352  
5353       if(CRT1ModeNo >= 0x13) {
5354          /* Get VCLK */
5355  	index = SiS_GetRefCRTVCLK(SiS_Pr, refreshratetableindex, SiS_Pr->SiS_UseWide);
5356  	VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
5357  
5358  	/* Get colordepth */
5359  	colorth = SiS_GetColorDepth(SiS_Pr,CRT1ModeNo,modeidindex) >> 1;
5360  	if(!colorth) colorth++;
5361       }
5362  
5363    } else {
5364  
5365       CRT1ModeNo = 0xfe;
5366  
5367       /* Get VCLK */
5368       VCLK = SiS_Pr->CSRClock_CRT1;
5369  
5370       /* Get color depth */
5371       colorth = colortharray[((SiS_Pr->CModeFlag_CRT1 & ModeTypeMask) - 2)];
5372  
5373    }
5374  
5375    if(CRT1ModeNo >= 0x13) {
5376       /* Get MCLK */
5377       if(SiS_Pr->ChipType == SIS_300) {
5378          index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A);
5379       } else {
5380          index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A);
5381       }
5382       index &= 0x07;
5383       MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;
5384  
5385       temp = ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) >> 6) & 0x03) << 1;
5386       if(!temp) temp++;
5387       temp <<= 2;
5388  
5389       data2 = temp - ((colorth * VCLK) / MCLK);
5390  
5391       temp = (28 * 16) % data2;
5392       data2 = (28 * 16) / data2;
5393       if(temp) data2++;
5394  
5395       if(SiS_Pr->ChipType == SIS_300) {
5396  
5397  	SiS_GetFIFOThresholdIndex300(SiS_Pr, &tempbx, &tempcl);
5398  	data = SiS_GetFIFOThresholdB300(tempbx, tempcl);
5399  
5400       } else {
5401  
5402  	pci50 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0x50);
5403  	pciA0 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0xa0);
5404  
5405          if(SiS_Pr->ChipType == SIS_730) {
5406  
5407  	   index = (unsigned short)(((pciA0 >> 28) & 0x0f) * 3);
5408  	   index += (unsigned short)(((pci50 >> 9)) & 0x03);
5409  
5410  	   /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */
5411  	   index = 0;  /* -- do it like the BIOS anyway... */
5412  
5413  	} else {
5414  
5415  	   pci50 >>= 24;
5416  	   pciA0 >>= 24;
5417  
5418  	   index = (pci50 >> 1) & 0x07;
5419  
5420  	   if(pci50 & 0x01)    index += 6;
5421  	   if(!(pciA0 & 0x01)) index += 24;
5422  
5423  	   if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80) index += 12;
5424  
5425  	}
5426  
5427  	data = SiS_GetLatencyFactor630(SiS_Pr, index) + 15;
5428  	if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80)) data += 5;
5429  
5430       }
5431  
5432       data += data2;						/* CRT1 Request Period */
5433  
5434       SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5435       SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5436  
5437       if(!SiS_Pr->UseCustomMode) {
5438  
5439  	CRT2ModeNo = ModeNo;
5440  	SiS_SearchModeID(SiS_Pr, &CRT2ModeNo, &modeidindex);
5441  
5442  	refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT2ModeNo, modeidindex);
5443  
5444  	/* Get VCLK  */
5445  	index = SiS_GetVCLK2Ptr(SiS_Pr, CRT2ModeNo, modeidindex, refreshratetableindex);
5446  	VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
5447  
5448  	if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
5449  	   if(SiS_Pr->SiS_UseROM) {
5450  	      if(ROMAddr[0x220] & 0x01) {
5451  		 VCLK = ROMAddr[0x229] | (ROMAddr[0x22a] << 8);
5452  	      }
5453             }
5454          }
5455  
5456       } else {
5457  
5458  	/* Get VCLK */
5459  	CRT2ModeNo = 0xfe;
5460  	VCLK = SiS_Pr->CSRClock;
5461  
5462       }
5463  
5464       /* Get colordepth */
5465       colorth = SiS_GetColorDepth(SiS_Pr,CRT2ModeNo,modeidindex) >> 1;
5466       if(!colorth) colorth++;
5467  
5468       data = data * VCLK * colorth;
5469       temp = data % (MCLK << 4);
5470       data = data / (MCLK << 4);
5471       if(temp) data++;
5472  
5473       if(data < 6) data = 6;
5474       else if(data > 0x14) data = 0x14;
5475  
5476       if(SiS_Pr->ChipType == SIS_300) {
5477          temp = 0x16;
5478  	if((data <= 0x0f) || (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024))
5479  	   temp = 0x13;
5480       } else {
5481          temp = 0x16;
5482  	if(( (SiS_Pr->ChipType == SIS_630) ||
5483  	     (SiS_Pr->ChipType == SIS_730) )  &&
5484  	   (SiS_Pr->ChipRevision >= 0x30))
5485  	   temp = 0x1b;
5486       }
5487       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0xe0,temp);
5488  
5489       if((SiS_Pr->ChipType == SIS_630) &&
5490  	(SiS_Pr->ChipRevision >= 0x30)) {
5491  	if(data > 0x13) data = 0x13;
5492       }
5493       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,0xe0,data);
5494  
5495    } else {  /* If mode <= 0x13, we just restore everything */
5496  
5497       SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5498       SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5499  
5500    }
5501  }
5502  #endif
5503  
5504  /* Set CRT2 FIFO on 315/330 series */
5505  #ifdef CONFIG_FB_SIS_315
5506  static void
SiS_SetCRT2FIFO_310(struct SiS_Private * SiS_Pr)5507  SiS_SetCRT2FIFO_310(struct SiS_Private *SiS_Pr)
5508  {
5509    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3B);
5510    if( (SiS_Pr->ChipType == SIS_760)      &&
5511        (SiS_Pr->SiS_SysFlags & SF_760LFB)  &&
5512        (SiS_Pr->SiS_ModeType == Mode32Bpp) &&
5513        (SiS_Pr->SiS_VGAHDE >= 1280)	  &&
5514        (SiS_Pr->SiS_VGAVDE >= 1024) ) {
5515       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x03);
5516       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3b);
5517       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5518       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x01);
5519       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5520       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,0x6e);
5521    } else {
5522       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3f,0x04);
5523    }
5524  
5525  }
5526  #endif
5527  
5528  static unsigned short
SiS_GetVGAHT2(struct SiS_Private * SiS_Pr)5529  SiS_GetVGAHT2(struct SiS_Private *SiS_Pr)
5530  {
5531    unsigned int tempax,tempbx;
5532  
5533    tempbx = (SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) * SiS_Pr->SiS_RVBHCMAX;
5534    tempax = (SiS_Pr->SiS_VT - SiS_Pr->SiS_VDE) * SiS_Pr->SiS_RVBHCFACT;
5535    tempax = (tempax * SiS_Pr->SiS_HT) / tempbx;
5536    return (unsigned short)tempax;
5537  }
5538  
5539  /* Set Part 1 / SiS bridge slave mode */
5540  static void
SiS_SetGroup1_301(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)5541  SiS_SetGroup1_301(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,
5542                    unsigned short RefreshRateTableIndex)
5543  {
5544    unsigned short temp, modeflag, i, j, xres=0, VGAVDE;
5545    static const unsigned short CRTranslation[] = {
5546         /* CR0   CR1   CR2   CR3   CR4   CR5   CR6   CR7   */
5547  	  0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
5548         /* CR8   CR9   SR0A  SR0B  SR0C  SR0D  SR0E  CR0F  */
5549  	  0x00, 0x0b, 0x17, 0x18, 0x19, 0x00, 0x1a, 0x00,
5550         /* CR10  CR11  CR12  CR13  CR14  CR15  CR16  CR17  */
5551  	  0x0c, 0x0d, 0x0e, 0x00, 0x0f, 0x10, 0x11, 0x00
5552    };
5553  
5554    if(ModeNo <= 0x13) {
5555       modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5556    } else if(SiS_Pr->UseCustomMode) {
5557       modeflag = SiS_Pr->CModeFlag;
5558       xres = SiS_Pr->CHDisplay;
5559    } else {
5560       modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5561       xres = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes;
5562    }
5563  
5564    /* The following is only done if bridge is in slave mode: */
5565  
5566    if(SiS_Pr->ChipType >= SIS_315H) {
5567       if(xres >= 1600) {  /* BIOS: == 1600 */
5568          SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x31,0x04);
5569       }
5570    }
5571  
5572    SiS_Pr->CHTotal = 8224;  /* Max HT, 0x2020, results in 0x3ff in registers */
5573  
5574    SiS_Pr->CHDisplay = SiS_Pr->SiS_VGAHDE;
5575    if(modeflag & HalfDCLK) SiS_Pr->CHDisplay >>= 1;
5576  
5577    SiS_Pr->CHBlankStart = SiS_Pr->CHDisplay;
5578    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5579       SiS_Pr->CHBlankStart += 16;
5580    }
5581  
5582    SiS_Pr->CHBlankEnd = 32;
5583    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5584       if(xres == 1600) SiS_Pr->CHBlankEnd += 80;
5585    }
5586  
5587    temp = SiS_Pr->SiS_VGAHT - 96;
5588    if(!(modeflag & HalfDCLK)) temp -= 32;
5589    if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
5590       temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x04);
5591       temp |= ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x0b) & 0xc0) << 2);
5592       temp -= 3;
5593       temp <<= 3;
5594    } else {
5595       if(SiS_Pr->SiS_RVBHRS2) temp = SiS_Pr->SiS_RVBHRS2;
5596    }
5597    SiS_Pr->CHSyncStart = temp;
5598  
5599    SiS_Pr->CHSyncEnd = 0xffe8; 	/* results in 0x2000 in registers */
5600  
5601    SiS_Pr->CVTotal = 2049;  	/* Max VT, 0x0801, results in 0x7ff in registers */
5602  
5603    VGAVDE = SiS_Pr->SiS_VGAVDE;
5604    if     (VGAVDE ==  357) VGAVDE =  350;
5605    else if(VGAVDE ==  360) VGAVDE =  350;
5606    else if(VGAVDE ==  375) VGAVDE =  350;
5607    else if(VGAVDE ==  405) VGAVDE =  400;
5608    else if(VGAVDE ==  420) VGAVDE =  400;
5609    else if(VGAVDE ==  525) VGAVDE =  480;
5610    else if(VGAVDE == 1056) VGAVDE = 1024;
5611    SiS_Pr->CVDisplay = VGAVDE;
5612  
5613    SiS_Pr->CVBlankStart = SiS_Pr->CVDisplay;
5614  
5615    SiS_Pr->CVBlankEnd = 1;
5616    if(ModeNo == 0x3c) SiS_Pr->CVBlankEnd = 226;
5617  
5618    temp = (SiS_Pr->SiS_VGAVT - VGAVDE) >> 1;
5619    SiS_Pr->CVSyncStart = VGAVDE + temp;
5620  
5621    temp >>= 3;
5622    SiS_Pr->CVSyncEnd = SiS_Pr->CVSyncStart + temp;
5623  
5624    SiS_CalcCRRegisters(SiS_Pr, 0);
5625    SiS_Pr->CCRT1CRTC[16] &= ~0xE0;
5626  
5627    for(i = 0; i <= 7; i++) {
5628       SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[i]);
5629    }
5630    for(i = 0x10, j = 8; i <= 0x12; i++, j++) {
5631       SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5632    }
5633    for(i = 0x15, j = 11; i <= 0x16; i++, j++) {
5634       SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5635    }
5636    for(i = 0x0a, j = 13; i <= 0x0c; i++, j++) {
5637       SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5638    }
5639  
5640    temp = SiS_Pr->CCRT1CRTC[16] & 0xE0;
5641    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x0E],0x1F,temp);
5642  
5643    temp = (SiS_Pr->CCRT1CRTC[16] & 0x01) << 5;
5644    if(modeflag & DoubleScanMode) temp |= 0x80;
5645    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x09],0x5F,temp);
5646  
5647    temp = 0;
5648    temp |= (SiS_GetReg(SiS_Pr->SiS_P3c4,0x01) & 0x01);
5649    if(modeflag & HalfDCLK) temp |= 0x08;
5650    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp);              	/* SR01: HalfDCLK[3], 8/9 div dotclock[0] */
5651  
5652    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,0x00);              	/* CR14: (text mode: underline location) */
5653    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,0x00);              	/* CR17: n/a */
5654  
5655    temp = 0;
5656    if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5657       temp = (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) << 7;
5658    }
5659    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp);                	/* SR0E, dither[7] */
5660  
5661    temp = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
5662    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);			/* ? */
5663  }
5664  
5665  /* Setup panel link
5666   * This is used for LVDS, LCDA and Chrontel TV output
5667   * 300/LVDS+TV, 300/301B-DH, 315/LVDS+TV, 315/LCDA
5668   */
5669  static void
SiS_SetGroup1_LVDS(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)5670  SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
5671  		unsigned short RefreshRateTableIndex)
5672  {
5673    unsigned short modeflag, resinfo = 0;
5674    unsigned short push2, tempax, tempbx, tempcx, temp;
5675    unsigned int   tempeax = 0, tempebx, tempecx, tempvcfact = 0;
5676    bool islvds = false, issis  = false, chkdclkfirst = false;
5677  #ifdef CONFIG_FB_SIS_300
5678    unsigned short crt2crtc = 0;
5679  #endif
5680  #ifdef CONFIG_FB_SIS_315
5681    unsigned short pushcx;
5682  #endif
5683  
5684    if(ModeNo <= 0x13) {
5685       modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5686       resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
5687  #ifdef CONFIG_FB_SIS_300
5688       crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
5689  #endif
5690    } else if(SiS_Pr->UseCustomMode) {
5691       modeflag = SiS_Pr->CModeFlag;
5692    } else {
5693       modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5694       resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
5695  #ifdef CONFIG_FB_SIS_300
5696       crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
5697  #endif
5698    }
5699  
5700    /* is lvds if really LVDS, or 301B-DH with external LVDS transmitter */
5701    if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
5702       islvds = true;
5703    }
5704  
5705    /* is really sis if sis bridge, but not 301B-DH */
5706    if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
5707       issis = true;
5708    }
5709  
5710    if((SiS_Pr->ChipType >= SIS_315H) && (islvds) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA))) {
5711       if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
5712          chkdclkfirst = true;
5713       }
5714    }
5715  
5716  #ifdef CONFIG_FB_SIS_315
5717    if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
5718       if(IS_SIS330) {
5719          SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5720       } else if(IS_SIS740) {
5721          if(islvds) {
5722             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5723  	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x03);
5724          } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5725             SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5726          }
5727       } else {
5728          if(islvds) {
5729             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5730  	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x00);
5731          } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5732             SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2D,0x0f);
5733  	   if(SiS_Pr->SiS_VBType & VB_SIS30xC) {
5734  	      if((SiS_Pr->SiS_LCDResInfo == Panel_1024x768) ||
5735  	         (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
5736  	         SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x20);
5737  	      }
5738  	   }
5739          }
5740       }
5741    }
5742  #endif
5743  
5744    /* Horizontal */
5745  
5746    tempax = SiS_Pr->SiS_LCDHDES;
5747    if(islvds) {
5748       if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5749  	if(!SiS_Pr->SiS_IF_DEF_FSTN && !SiS_Pr->SiS_IF_DEF_DSTN) {
5750  	   if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) &&
5751  	      (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
5752  	      tempax -= 8;
5753  	   }
5754  	}
5755       }
5756    }
5757  
5758    temp = (tempax & 0x0007);
5759    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp);			/* BPLHDESKEW[2:0]   */
5760    temp = (tempax >> 3) & 0x00FF;
5761    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp);			/* BPLHDESKEW[10:3]  */
5762  
5763    tempbx = SiS_Pr->SiS_HDE;
5764    if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5765       if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5766          tempbx = SiS_Pr->PanelXRes;
5767       }
5768       if((SiS_Pr->SiS_LCDResInfo == Panel_320x240_1) ||
5769          (SiS_Pr->SiS_LCDResInfo == Panel_320x240_2) ||
5770          (SiS_Pr->SiS_LCDResInfo == Panel_320x240_3)) {
5771          tempbx >>= 1;
5772       }
5773    }
5774  
5775    tempax += tempbx;
5776    if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;
5777  
5778    temp = tempax;
5779    if(temp & 0x07) temp += 8;
5780    temp >>= 3;
5781    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp);			/* BPLHDEE  */
5782  
5783    tempcx = (SiS_Pr->SiS_HT - tempbx) >> 2;
5784  
5785    if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5786       if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5787          if(SiS_Pr->PanelHRS != 999) tempcx = SiS_Pr->PanelHRS;
5788       }
5789    }
5790  
5791    tempcx += tempax;
5792    if(tempcx >= SiS_Pr->SiS_HT) tempcx -= SiS_Pr->SiS_HT;
5793  
5794    temp = (tempcx >> 3) & 0x00FF;
5795    if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5796       if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5797  	if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5798  	   switch(ModeNo) {
5799  	   case 0x04:
5800  	   case 0x05:
5801  	   case 0x0d: temp = 0x56; break;
5802  	   case 0x10: temp = 0x60; break;
5803  	   case 0x13: temp = 0x5f; break;
5804  	   case 0x40:
5805  	   case 0x41:
5806  	   case 0x4f:
5807  	   case 0x43:
5808  	   case 0x44:
5809  	   case 0x62:
5810  	   case 0x56:
5811  	   case 0x53:
5812  	   case 0x5d:
5813  	   case 0x5e: temp = 0x54; break;
5814  	   }
5815  	}
5816       }
5817    }
5818    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,temp);			/* BPLHRS */
5819  
5820    if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5821       temp += 2;
5822       if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5823  	temp += 8;
5824  	if(SiS_Pr->PanelHRE != 999) {
5825  	   temp = tempcx + SiS_Pr->PanelHRE;
5826  	   if(temp >= SiS_Pr->SiS_HT) temp -= SiS_Pr->SiS_HT;
5827  	   temp >>= 3;
5828  	}
5829       }
5830    } else {
5831       temp += 10;
5832    }
5833  
5834    temp &= 0x1F;
5835    temp |= ((tempcx & 0x07) << 5);
5836    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,temp);			/* BPLHRE */
5837  
5838    /* Vertical */
5839  
5840    tempax = SiS_Pr->SiS_VGAVDE;
5841    if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5842       if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5843  	tempax = SiS_Pr->PanelYRes;
5844       }
5845    }
5846  
5847    tempbx = SiS_Pr->SiS_LCDVDES + tempax;
5848    if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5849  
5850    push2 = tempbx;
5851  
5852    tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE;
5853    if(SiS_Pr->ChipType < SIS_315H) {
5854       if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5855  	if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5856  	   tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->PanelYRes;
5857  	}
5858       }
5859    }
5860    if(islvds) tempcx >>= 1;
5861    else       tempcx >>= 2;
5862  
5863    if( (SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
5864        (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) 		    &&
5865        (SiS_Pr->PanelVRS != 999) ) {
5866       tempcx = SiS_Pr->PanelVRS;
5867       tempbx += tempcx;
5868       if(issis) tempbx++;
5869    } else {
5870       tempbx += tempcx;
5871       if(SiS_Pr->ChipType < SIS_315H) tempbx++;
5872       else if(issis)                   tempbx++;
5873    }
5874  
5875    if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5876  
5877    temp = tempbx & 0x00FF;
5878    if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5879       if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5880  	if(ModeNo == 0x10) temp = 0xa9;
5881       }
5882    }
5883    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);			/* BPLVRS */
5884  
5885    tempcx >>= 3;
5886    tempcx++;
5887  
5888    if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5889       if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5890          if(SiS_Pr->PanelVRE != 999) tempcx = SiS_Pr->PanelVRE;
5891       }
5892    }
5893  
5894    tempcx += tempbx;
5895    temp = tempcx & 0x000F;
5896    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp);	/* BPLVRE  */
5897  
5898    temp = ((tempbx >> 8) & 0x07) << 3;
5899    if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
5900       if(SiS_Pr->SiS_HDE != 640) {
5901          if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE)  temp |= 0x40;
5902       }
5903    } else if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
5904    if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA)          temp |= 0x40;
5905    tempbx = 0x87;
5906    if((SiS_Pr->ChipType >= SIS_315H) ||
5907       (SiS_Pr->ChipRevision >= 0x30)) {
5908       tempbx = 0x07;
5909       if((SiS_Pr->SiS_IF_DEF_CH70xx == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
5910  	if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x03)    temp |= 0x80;
5911       }
5912       /* Chrontel 701x operates in 24bit mode (8-8-8, 2x12bit multiplexed) via VGA2 */
5913       if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5914  	if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5915  	   if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x10)      temp |= 0x80;
5916  	} else {
5917  	   if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80;
5918  	}
5919       }
5920    }
5921    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,tempbx,temp);
5922  
5923    tempbx = push2;						/* BPLVDEE */
5924  
5925    tempcx = SiS_Pr->SiS_LCDVDES;					/* BPLVDES */
5926  
5927    if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5928       switch(SiS_Pr->SiS_LCDResInfo) {
5929       case Panel_640x480:
5930  	tempbx = SiS_Pr->SiS_VGAVDE - 1;
5931  	tempcx = SiS_Pr->SiS_VGAVDE;
5932  	break;
5933       case Panel_800x600:
5934  	if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5935  	   if(resinfo == SIS_RI_800x600) tempcx++;
5936  	}
5937  	break;
5938       case Panel_1024x600:
5939  	if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5940  	   if(resinfo == SIS_RI_1024x600) tempcx++;
5941  	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
5942  	      if(resinfo == SIS_RI_800x600) tempcx++;
5943  	   }
5944  	}
5945  	break;
5946       case Panel_1024x768:
5947  	if(SiS_Pr->ChipType < SIS_315H) {
5948  	   if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5949  	      if(resinfo == SIS_RI_1024x768) tempcx++;
5950  	   }
5951  	}
5952  	break;
5953       }
5954    }
5955  
5956    temp = ((tempbx >> 8) & 0x07) << 3;
5957    temp |= ((tempcx >> 8) & 0x07);
5958    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1D,temp);
5959    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1C,tempbx);
5960    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1B,tempcx);
5961  
5962    /* Vertical scaling */
5963  
5964    if(SiS_Pr->ChipType < SIS_315H) {
5965  
5966  #ifdef CONFIG_FB_SIS_300      /* 300 series */
5967       tempeax = SiS_Pr->SiS_VGAVDE << 6;
5968       temp = (tempeax % (unsigned int)SiS_Pr->SiS_VDE);
5969       tempeax = tempeax / (unsigned int)SiS_Pr->SiS_VDE;
5970       if(temp) tempeax++;
5971  
5972       if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) tempeax = 0x3F;
5973  
5974       temp = (unsigned short)(tempeax & 0x00FF);
5975       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,temp);      	/* BPLVCFACT */
5976       tempvcfact = temp;
5977  #endif /* CONFIG_FB_SIS_300 */
5978  
5979    } else {
5980  
5981  #ifdef CONFIG_FB_SIS_315  /* 315 series */
5982       tempeax = SiS_Pr->SiS_VGAVDE << 18;
5983       tempebx = SiS_Pr->SiS_VDE;
5984       temp = (tempeax % tempebx);
5985       tempeax = tempeax / tempebx;
5986       if(temp) tempeax++;
5987       tempvcfact = tempeax;
5988  
5989       temp = (unsigned short)(tempeax & 0x00FF);
5990       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,temp);
5991       temp = (unsigned short)((tempeax & 0x00FF00) >> 8);
5992       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,temp);
5993       temp = (unsigned short)((tempeax & 0x00030000) >> 16);
5994       if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
5995       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,temp);
5996  
5997       if(SiS_Pr->SiS_VBType & VB_SISPART4SCALER) {
5998          temp = (unsigned short)(tempeax & 0x00FF);
5999          SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3c,temp);
6000          temp = (unsigned short)((tempeax & 0x00FF00) >> 8);
6001          SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3b,temp);
6002          temp = (unsigned short)(((tempeax & 0x00030000) >> 16) << 6);
6003          SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0x3f,temp);
6004          temp = 0;
6005          if(SiS_Pr->SiS_VDE != SiS_Pr->SiS_VGAVDE) temp |= 0x08;
6006          SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x30,0xf3,temp);
6007       }
6008  #endif
6009  
6010    }
6011  
6012    /* Horizontal scaling */
6013  
6014    tempeax = SiS_Pr->SiS_VGAHDE;		/* 1f = ( (VGAHDE * 65536) / ( (VGAHDE * 65536) / HDE ) ) - 1*/
6015    if(chkdclkfirst) {
6016       if(modeflag & HalfDCLK) tempeax >>= 1;
6017    }
6018    tempebx = tempeax << 16;
6019    if(SiS_Pr->SiS_HDE == tempeax) {
6020       tempecx = 0xFFFF;
6021    } else {
6022       tempecx = tempebx / SiS_Pr->SiS_HDE;
6023       if(SiS_Pr->ChipType >= SIS_315H) {
6024          if(tempebx % SiS_Pr->SiS_HDE) tempecx++;
6025       }
6026    }
6027  
6028    if(SiS_Pr->ChipType >= SIS_315H) {
6029       tempeax = (tempebx / tempecx) - 1;
6030    } else {
6031       tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1;
6032    }
6033    tempecx = (tempecx << 16) | (tempeax & 0xFFFF);
6034    temp = (unsigned short)(tempecx & 0x00FF);
6035    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1F,temp);
6036  
6037    if(SiS_Pr->ChipType >= SIS_315H) {
6038       tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
6039       tempbx = (unsigned short)(tempeax & 0xFFFF);
6040    } else {
6041       tempeax = SiS_Pr->SiS_VGAVDE << 6;
6042       tempbx = tempvcfact & 0x3f;
6043       if(tempbx == 0) tempbx = 64;
6044       tempeax /= tempbx;
6045       tempbx = (unsigned short)(tempeax & 0xFFFF);
6046    }
6047    if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tempbx--;
6048    if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
6049       if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) tempbx = 1;
6050       else if(SiS_Pr->SiS_LCDResInfo != Panel_640x480)             tempbx = 1;
6051    }
6052  
6053    temp = ((tempbx >> 8) & 0x07) << 3;
6054    temp = temp | ((tempecx >> 8) & 0x07);
6055    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x20,temp);
6056    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x21,tempbx);
6057  
6058    tempecx >>= 16;						/* BPLHCFACT  */
6059    if(!chkdclkfirst) {
6060       if(modeflag & HalfDCLK) tempecx >>= 1;
6061    }
6062    temp = (unsigned short)((tempecx & 0xFF00) >> 8);
6063    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x22,temp);
6064    temp = (unsigned short)(tempecx & 0x00FF);
6065    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp);
6066  
6067  #ifdef CONFIG_FB_SIS_315
6068    if(SiS_Pr->ChipType >= SIS_315H) {
6069       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
6070          if((islvds) || (SiS_Pr->SiS_VBInfo & VB_SISLVDS)) {
6071             SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x20);
6072  	}
6073       } else {
6074          if(islvds) {
6075             if(SiS_Pr->ChipType == SIS_740) {
6076                SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
6077             } else {
6078  	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x23);
6079             }
6080          }
6081       }
6082    }
6083  #endif
6084  
6085  #ifdef CONFIG_FB_SIS_300
6086    if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
6087       unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
6088       unsigned char *trumpdata;
6089       int   i, j = crt2crtc;
6090       unsigned char TrumpMode13[4]   = { 0x01, 0x10, 0x2c, 0x00 };
6091       unsigned char TrumpMode10_1[4] = { 0x01, 0x10, 0x27, 0x00 };
6092       unsigned char TrumpMode10_2[4] = { 0x01, 0x16, 0x10, 0x00 };
6093  
6094       if(SiS_Pr->SiS_UseROM) {
6095  	trumpdata = &ROMAddr[0x8001 + (j * 80)];
6096       } else {
6097  	if(SiS_Pr->SiS_LCDTypeInfo == 0x0e) j += 7;
6098  	trumpdata = &SiS300_TrumpionData[j][0];
6099       }
6100  
6101       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xbf);
6102       for(i=0; i<5; i++) {
6103  	SiS_SetTrumpionBlock(SiS_Pr, trumpdata);
6104       }
6105       if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6106  	if(ModeNo == 0x13) {
6107  	   for(i=0; i<4; i++) {
6108  	      SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode13[0]);
6109  	   }
6110  	} else if(ModeNo == 0x10) {
6111  	   for(i=0; i<4; i++) {
6112  	      SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_1[0]);
6113  	      SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_2[0]);
6114  	   }
6115  	}
6116       }
6117       SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
6118    }
6119  #endif
6120  
6121  #ifdef CONFIG_FB_SIS_315
6122    if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
6123       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x25,0x00);
6124       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x26,0x00);
6125       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x27,0x00);
6126       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x28,0x87);
6127       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x29,0x5A);
6128       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2A,0x4B);
6129       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x07,0x03);
6130       tempax = SiS_Pr->SiS_HDE;					/* Blps = lcdhdee(lcdhdes+HDE) + 64 */
6131       if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
6132          SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
6133          SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
6134       tempax += 64;
6135       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,tempax & 0xff);
6136       temp = (tempax >> 8) << 3;
6137       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp);
6138       tempax += 32;						/* Blpe = lBlps+32 */
6139       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,tempax & 0xff);
6140       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3A,0x00);		/* Bflml = 0 */
6141       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x007);
6142  
6143       tempax = SiS_Pr->SiS_VDE;
6144       if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
6145          SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
6146          SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
6147       tempax >>= 1;
6148       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3B,tempax & 0xff);
6149       temp = (tempax >> 8) << 3;
6150       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);
6151  
6152       tempeax = SiS_Pr->SiS_HDE;
6153       if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
6154          SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
6155          SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempeax >>= 1;
6156       tempeax <<= 2;			 			/* BDxFIFOSTOP = (HDE*4)/128 */
6157       temp = tempeax & 0x7f;
6158       tempeax >>= 7;
6159       if(temp) tempeax++;
6160       temp = tempeax & 0x3f;
6161       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,temp);
6162       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3F,0x00);		/* BDxWadrst0 */
6163       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3E,0x00);
6164       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3D,0x10);
6165       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x040);
6166  
6167       tempax = SiS_Pr->SiS_HDE;
6168       if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
6169          SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
6170          SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
6171       tempax >>= 4;						/* BDxWadroff = HDE*4/8/8 */
6172       pushcx = tempax;
6173       temp = tempax & 0x00FF;
6174       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,temp);
6175       temp = ((tempax & 0xFF00) >> 8) << 3;
6176       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port, 0x44, 0x07, temp);
6177  
6178       tempax = SiS_Pr->SiS_VDE;				 	/* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
6179       if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
6180          SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
6181          SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
6182       tempeax = tempax * pushcx;
6183       temp = tempeax & 0xFF;
6184       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,temp);
6185       temp = (tempeax & 0xFF00) >> 8;
6186       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,temp);
6187       temp = ((tempeax & 0xFF0000) >> 16) | 0x10;
6188       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,temp);
6189       temp = ((tempeax & 0x01000000) >> 24) << 7;
6190       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port, 0x3C, 0x7F, temp);
6191  
6192       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x03);
6193       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0x50);
6194       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,0x00);
6195       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x01);
6196       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0x38);
6197  
6198       if(SiS_Pr->SiS_IF_DEF_FSTN) {
6199          SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2b,0x02);
6200          SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2c,0x00);
6201          SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x00);
6202          SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,0x0c);
6203          SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,0x00);
6204          SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,0x00);
6205          SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,0x80);
6206          SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,0xA0);
6207          SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3a,0x00);
6208          SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3b,0xf0);
6209          SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3c,0x00);
6210          SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3d,0x10);
6211          SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3e,0x00);
6212          SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3f,0x00);
6213          SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,0x10);
6214          SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,0x25);
6215          SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,0x80);
6216          SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,0x14);
6217          SiS_SetReg(SiS_Pr->SiS_Part1Port,0x44,0x03);
6218          SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,0x0a);
6219       }
6220    }
6221  #endif  /* CONFIG_FB_SIS_315 */
6222  }
6223  
6224  /* Set Part 1 */
6225  static void
SiS_SetGroup1(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)6226  SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6227  		unsigned short RefreshRateTableIndex)
6228  {
6229  #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
6230    unsigned char   *ROMAddr = SiS_Pr->VirtualRomBase;
6231  #endif
6232    unsigned short  temp=0, tempax=0, tempbx=0, tempcx=0, bridgeadd=0;
6233    unsigned short  pushbx=0, CRT1Index=0, modeflag, resinfo=0;
6234  #ifdef CONFIG_FB_SIS_315
6235    unsigned short  tempbl=0;
6236  #endif
6237  
6238    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
6239       SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6240       return;
6241    }
6242  
6243    if(ModeNo <= 0x13) {
6244       modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6245    } else if(SiS_Pr->UseCustomMode) {
6246       modeflag = SiS_Pr->CModeFlag;
6247    } else {
6248       CRT1Index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);
6249       resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
6250       modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6251    }
6252  
6253    SiS_SetCRT2Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6254  
6255    if( ! ((SiS_Pr->ChipType >= SIS_315H) &&
6256           (SiS_Pr->SiS_IF_DEF_LVDS == 1) &&
6257           (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
6258  
6259       if(SiS_Pr->ChipType < SIS_315H ) {
6260  #ifdef CONFIG_FB_SIS_300
6261  	SiS_SetCRT2FIFO_300(SiS_Pr, ModeNo);
6262  #endif
6263       } else {
6264  #ifdef CONFIG_FB_SIS_315
6265  	SiS_SetCRT2FIFO_310(SiS_Pr);
6266  #endif
6267       }
6268  
6269       /* 1. Horizontal setup */
6270  
6271       if(SiS_Pr->ChipType < SIS_315H ) {
6272  
6273  #ifdef CONFIG_FB_SIS_300   /* ------------- 300 series --------------*/
6274  
6275  	temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF;   		  /* BTVGA2HT 0x08,0x09 */
6276  	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp);              /* CRT2 Horizontal Total */
6277  
6278  	temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
6279  	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp);    /* CRT2 Horizontal Total Overflow [7:4] */
6280  
6281  	temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF;                 /* BTVGA2HDEE 0x0A,0x0C */
6282  	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp);              /* CRT2 Horizontal Display Enable End */
6283  
6284  	pushbx = SiS_Pr->SiS_VGAHDE + 12;                         /* bx  BTVGA2HRS 0x0B,0x0C */
6285  	tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2;
6286  	tempbx = pushbx + tempcx;
6287  	tempcx <<= 1;
6288  	tempcx += tempbx;
6289  
6290  	bridgeadd = 12;
6291  
6292  #endif /* CONFIG_FB_SIS_300 */
6293  
6294       } else {
6295  
6296  #ifdef CONFIG_FB_SIS_315  /* ------------------- 315/330 series --------------- */
6297  
6298  	tempcx = SiS_Pr->SiS_VGAHT;				  /* BTVGA2HT 0x08,0x09 */
6299  	if(modeflag & HalfDCLK) {
6300  	   if(SiS_Pr->SiS_VBType & VB_SISVB) {
6301  	      tempcx >>= 1;
6302  	   } else {
6303  	      tempax = SiS_Pr->SiS_VGAHDE >> 1;
6304  	      tempcx = SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE + tempax;
6305  	      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
6306  	         tempcx = SiS_Pr->SiS_HT - tempax;
6307  	      }
6308  	   }
6309  	}
6310  	tempcx--;
6311  	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,tempcx);            /* CRT2 Horizontal Total */
6312  	temp = (tempcx >> 4) & 0xF0;
6313  	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp);    /* CRT2 Horizontal Total Overflow [7:4] */
6314  
6315  	tempcx = SiS_Pr->SiS_VGAHT;				  /* BTVGA2HDEE 0x0A,0x0C */
6316  	tempbx = SiS_Pr->SiS_VGAHDE;
6317  	tempcx -= tempbx;
6318  	tempcx >>= 2;
6319  	if(modeflag & HalfDCLK) {
6320  	   tempbx >>= 1;
6321  	   tempcx >>= 1;
6322  	}
6323  	tempbx += 16;
6324  
6325  	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,tempbx);            /* CRT2 Horizontal Display Enable End */
6326  
6327  	pushbx = tempbx;
6328  	tempcx >>= 1;
6329  	tempbx += tempcx;
6330  	tempcx += tempbx;
6331  
6332  	bridgeadd = 16;
6333  
6334  	if(SiS_Pr->SiS_VBType & VB_SISVB) {
6335  	   if(SiS_Pr->ChipType >= SIS_661) {
6336  	      if((SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
6337  		 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
6338  		 if(resinfo == SIS_RI_1280x1024) {
6339  		    tempcx = (tempcx & 0xff00) | 0x30;
6340  		 } else if(resinfo == SIS_RI_1600x1200) {
6341  		    tempcx = (tempcx & 0xff00) | 0xff;
6342  		 }
6343  	      }
6344  	   }
6345          }
6346  
6347  #endif  /* CONFIG_FB_SIS_315 */
6348  
6349       }  /* 315/330 series */
6350  
6351       if(SiS_Pr->SiS_VBType & VB_SISVB) {
6352  
6353  	if(SiS_Pr->UseCustomMode) {
6354  	   tempbx = SiS_Pr->CHSyncStart + bridgeadd;
6355  	   tempcx = SiS_Pr->CHSyncEnd + bridgeadd;
6356  	   tempax = SiS_Pr->SiS_VGAHT;
6357  	   if(modeflag & HalfDCLK) tempax >>= 1;
6358  	   tempax--;
6359  	   if(tempcx > tempax) tempcx = tempax;
6360  	}
6361  
6362  	if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6363  	   unsigned char cr4, cr14, cr5, cr15;
6364  	   if(SiS_Pr->UseCustomMode) {
6365  	      cr4  = SiS_Pr->CCRT1CRTC[4];
6366  	      cr14 = SiS_Pr->CCRT1CRTC[14];
6367  	      cr5  = SiS_Pr->CCRT1CRTC[5];
6368  	      cr15 = SiS_Pr->CCRT1CRTC[15];
6369  	   } else {
6370  	      cr4  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
6371  	      cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
6372  	      cr5  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
6373  	      cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
6374  	   }
6375  	   tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3; 		    /* (VGAHRS-3)*8 */
6376  	   tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3;   /* (VGAHRE-3)*8 */
6377  	   tempcx &= 0x00FF;
6378  	   tempcx |= (tempbx & 0xFF00);
6379  	   tempbx += bridgeadd;
6380  	   tempcx += bridgeadd;
6381  	   tempax = SiS_Pr->SiS_VGAHT;
6382  	   if(modeflag & HalfDCLK) tempax >>= 1;
6383  	   tempax--;
6384  	   if(tempcx > tempax) tempcx = tempax;
6385  	}
6386  
6387  	if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {
6388  	   tempbx = 1040;
6389  	   tempcx = 1044;   /* HWCursor bug! */
6390  	}
6391  
6392       }
6393  
6394       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,tempbx);            	  /* CRT2 Horizontal Retrace Start */
6395  
6396       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,tempcx);               /* CRT2 Horizontal Retrace End */
6397  
6398       temp = ((tempbx >> 8) & 0x0F) | ((pushbx >> 4) & 0xF0);
6399       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp);		  /* Overflow */
6400  
6401       /* 2. Vertical setup */
6402  
6403       tempcx = SiS_Pr->SiS_VGAVT - 1;
6404       temp = tempcx & 0x00FF;
6405  
6406       if(SiS_Pr->ChipType < SIS_661) {
6407          if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6408  	   if(SiS_Pr->ChipType < SIS_315H) {
6409  	      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6410  	         if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
6411  	            temp--;
6412  	         }
6413  	      }
6414  	   } else {
6415  	      temp--;
6416  	   }
6417  	} else if(SiS_Pr->ChipType >= SIS_315H) {
6418  	   temp--;
6419  	}
6420       }
6421       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp);                 /* CRT2 Vertical Total */
6422  
6423       tempbx = SiS_Pr->SiS_VGAVDE - 1;
6424       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,tempbx);               /* CRT2 Vertical Display Enable End */
6425  
6426       temp = ((tempbx >> 5) & 0x38) | ((tempcx >> 8) & 0x07);
6427       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,temp);                 /* Overflow */
6428  
6429       if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
6430  	tempbx++;
6431  	tempax = tempbx;
6432  	tempcx++;
6433  	tempcx -= tempax;
6434  	tempcx >>= 2;
6435  	tempbx += tempcx;
6436  	if(tempcx < 4) tempcx = 4;
6437  	tempcx >>= 2;
6438  	tempcx += tempbx;
6439  	tempcx++;
6440       } else {
6441  	tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1;                 /*  BTVGA2VRS     0x10,0x11   */
6442  	tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1;  /*  BTVGA2VRE     0x11        */
6443       }
6444  
6445       if(SiS_Pr->SiS_VBType & VB_SISVB) {
6446  	if(SiS_Pr->UseCustomMode) {
6447  	   tempbx = SiS_Pr->CVSyncStart;
6448  	   tempcx = SiS_Pr->CVSyncEnd;
6449  	}
6450  	if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6451  	   unsigned char cr8, cr7, cr13;
6452  	   if(SiS_Pr->UseCustomMode) {
6453  	      cr8    = SiS_Pr->CCRT1CRTC[8];
6454  	      cr7    = SiS_Pr->CCRT1CRTC[7];
6455  	      cr13   = SiS_Pr->CCRT1CRTC[13];
6456  	      tempcx = SiS_Pr->CCRT1CRTC[9];
6457  	   } else {
6458  	      cr8    = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8];
6459  	      cr7    = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
6460  	      cr13   = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
6461  	      tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
6462  	   }
6463  	   tempbx = cr8;
6464  	   if(cr7  & 0x04) tempbx |= 0x0100;
6465  	   if(cr7  & 0x80) tempbx |= 0x0200;
6466  	   if(cr13 & 0x08) tempbx |= 0x0400;
6467  	}
6468       }
6469       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,tempbx);               /* CRT2 Vertical Retrace Start */
6470  
6471       temp = ((tempbx >> 4) & 0x70) | (tempcx & 0x0F);
6472       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,temp);                 /* CRT2 Vert. Retrace End; Overflow */
6473  
6474       /* 3. Panel delay compensation */
6475  
6476       if(SiS_Pr->ChipType < SIS_315H) {
6477  
6478  #ifdef CONFIG_FB_SIS_300  /* ---------- 300 series -------------- */
6479  
6480  	if(SiS_Pr->SiS_VBType & VB_SISVB) {
6481  	   temp = 0x20;
6482  	   if(SiS_Pr->ChipType == SIS_300) {
6483  	      temp = 0x10;
6484  	      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)  temp = 0x2c;
6485  	      if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6486  	   }
6487  	   if(SiS_Pr->SiS_VBType & VB_SIS301) {
6488  	      if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6489  	   }
6490  	   if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960)     temp = 0x24;
6491  	   if(SiS_Pr->SiS_LCDResInfo == Panel_Custom)       temp = 0x2c;
6492  	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) 	    temp = 0x08;
6493  	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6494  	      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) 	    temp = 0x2c;
6495  	      else 					    temp = 0x20;
6496  	   }
6497  	   if(SiS_Pr->SiS_UseROM) {
6498  	      if(ROMAddr[0x220] & 0x80) {
6499  		 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision)
6500  		    temp = ROMAddr[0x221];
6501  		 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)
6502  		    temp = ROMAddr[0x222];
6503  		 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)
6504  		    temp = ROMAddr[0x223];
6505  		 else
6506  		    temp = ROMAddr[0x224];
6507  	      }
6508  	   }
6509  	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6510  	      if(SiS_Pr->PDC != -1)  temp = SiS_Pr->PDC;
6511  	   }
6512  
6513  	} else {
6514  	   temp = 0x20;
6515  	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
6516  	      if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) temp = 0x04;
6517  	   }
6518  	   if(SiS_Pr->SiS_UseROM) {
6519  	      if(ROMAddr[0x220] & 0x80) {
6520  	         temp = ROMAddr[0x220];
6521  	      }
6522  	   }
6523  	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6524  	      if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC;
6525  	   }
6526  	}
6527  
6528  	temp &= 0x3c;
6529  
6530  	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);   /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
6531  
6532  #endif  /* CONFIG_FB_SIS_300 */
6533  
6534       } else {
6535  
6536  #ifdef CONFIG_FB_SIS_315   /* --------------- 315/330 series ---------------*/
6537  
6538  	if(SiS_Pr->ChipType < SIS_661) {
6539  
6540  	   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6541  
6542  	      if(SiS_Pr->ChipType == SIS_740) temp = 0x03;
6543  	      else 		              temp = 0x00;
6544  
6545  	      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x0a;
6546  	      tempbl = 0xF0;
6547  	      if(SiS_Pr->ChipType == SIS_650) {
6548  		 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6549  		    if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F;
6550  		 }
6551  	      }
6552  
6553  	      if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) {
6554  		 temp = 0x08;
6555  		 tempbl = 0;
6556  		 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
6557  		    if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0;
6558  		 }
6559  	      }
6560  
6561  	      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp);	    /* Panel Link Delay Compensation */
6562  	   }
6563  
6564  	} /* < 661 */
6565  
6566  	tempax = 0;
6567  	if(modeflag & DoubleScanMode) tempax |= 0x80;
6568  	if(modeflag & HalfDCLK)       tempax |= 0x40;
6569  	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax);
6570  
6571  #endif  /* CONFIG_FB_SIS_315 */
6572  
6573       }
6574  
6575    }  /* Slavemode */
6576  
6577    if(SiS_Pr->SiS_VBType & VB_SISVB) {
6578       if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
6579  	/* For 301BDH with LCD, we set up the Panel Link */
6580  	SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6581       } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6582  	SiS_SetGroup1_301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6583       }
6584    } else {
6585       if(SiS_Pr->ChipType < SIS_315H) {
6586  	SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6587       } else {
6588  	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6589  	   if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
6590  	      SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex);
6591  	   }
6592  	} else {
6593  	   SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex);
6594  	}
6595       }
6596    }
6597  }
6598  
6599  /*********************************************/
6600  /*         SET PART 2 REGISTER GROUP         */
6601  /*********************************************/
6602  
6603  #ifdef CONFIG_FB_SIS_315
6604  static unsigned char *
SiS_GetGroup2CLVXPtr(struct SiS_Private * SiS_Pr,int tabletype)6605  SiS_GetGroup2CLVXPtr(struct SiS_Private *SiS_Pr, int tabletype)
6606  {
6607     const unsigned char *tableptr = NULL;
6608     unsigned short      a, b, p = 0;
6609  
6610     a = SiS_Pr->SiS_VGAHDE;
6611     b = SiS_Pr->SiS_HDE;
6612     if(tabletype) {
6613        a = SiS_Pr->SiS_VGAVDE;
6614        b = SiS_Pr->SiS_VDE;
6615     }
6616  
6617     if(a < b) {
6618        tableptr = SiS_Part2CLVX_1;
6619     } else if(a == b) {
6620        tableptr = SiS_Part2CLVX_2;
6621     } else {
6622        if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6623  	 tableptr = SiS_Part2CLVX_4;
6624        } else {
6625  	 tableptr = SiS_Part2CLVX_3;
6626        }
6627        if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6628  	 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) 	tableptr = SiS_Part2CLVX_3;
6629  	 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) 	tableptr = SiS_Part2CLVX_3;
6630  	 else 				         	tableptr = SiS_Part2CLVX_5;
6631        } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6632  	 tableptr = SiS_Part2CLVX_6;
6633        }
6634        do {
6635  	 if((tableptr[p] | tableptr[p+1] << 8) == a) break;
6636  	 p += 0x42;
6637        } while((tableptr[p] | tableptr[p+1] << 8) != 0xffff);
6638        if((tableptr[p] | tableptr[p+1] << 8) == 0xffff) p -= 0x42;
6639     }
6640     p += 2;
6641     return ((unsigned char *)&tableptr[p]);
6642  }
6643  
6644  static void
SiS_SetGroup2_C_ELV(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)6645  SiS_SetGroup2_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6646  	      	    unsigned short RefreshRateTableIndex)
6647  {
6648     unsigned char *tableptr;
6649     unsigned char temp;
6650     int i, j;
6651  
6652     if(!(SiS_Pr->SiS_VBType & VB_SISTAP4SCALER)) return;
6653  
6654     tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 0);
6655     for(i = 0x80, j = 0; i <= 0xbf; i++, j++) {
6656        SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6657     }
6658     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6659        tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 1);
6660        for(i = 0xc0, j = 0; i <= 0xff; i++, j++) {
6661           SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6662        }
6663     }
6664     temp = 0x10;
6665     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp |= 0x04;
6666     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xeb,temp);
6667  }
6668  
6669  static bool
SiS_GetCRT2Part2Ptr(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex,unsigned short * CRT2Index,unsigned short * ResIndex)6670  SiS_GetCRT2Part2Ptr(struct SiS_Private *SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,
6671  		    unsigned short RefreshRateTableIndex,unsigned short *CRT2Index,
6672  		    unsigned short *ResIndex)
6673  {
6674  
6675    if(SiS_Pr->ChipType < SIS_315H) return false;
6676  
6677    if(ModeNo <= 0x13)
6678       (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6679    else
6680       (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6681  
6682    (*ResIndex) &= 0x3f;
6683    (*CRT2Index) = 0;
6684  
6685    if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6686       if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6687          (*CRT2Index) = 200;
6688       }
6689    }
6690  
6691    if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
6692       if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6693          if(SiS_Pr->SiS_SetFlag & LCDVESATiming) (*CRT2Index) = 206;
6694       }
6695    }
6696    return (((*CRT2Index) != 0));
6697  }
6698  #endif
6699  
6700  #ifdef CONFIG_FB_SIS_300
6701  static void
SiS_Group2LCDSpecial(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short crt2crtc)6702  SiS_Group2LCDSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short crt2crtc)
6703  {
6704     unsigned short tempcx;
6705     static const unsigned char atable[] = {
6706         0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,
6707         0xab,0x87,0xab,0x9e,0xe7,0x02,0x02
6708     };
6709  
6710     if(!SiS_Pr->UseCustomMode) {
6711        if( ( ( (SiS_Pr->ChipType == SIS_630) ||
6712  	      (SiS_Pr->ChipType == SIS_730) ) &&
6713  	    (SiS_Pr->ChipRevision > 2) )  &&
6714  	  (SiS_Pr->SiS_LCDResInfo == Panel_1024x768) &&
6715  	  (!(SiS_Pr->SiS_SetFlag & LCDVESATiming))  &&
6716  	  (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
6717  	 if(ModeNo == 0x13) {
6718  	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xB9);
6719  	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0xCC);
6720  	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xA6);
6721  	 } else if((crt2crtc & 0x3F) == 4) {
6722  	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x2B);
6723  	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x13);
6724  	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xE5);
6725  	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0x08);
6726  	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xE2);
6727  	 }
6728        }
6729  
6730        if(SiS_Pr->ChipType < SIS_315H) {
6731  	 if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
6732  	    crt2crtc &= 0x1f;
6733  	    tempcx = 0;
6734  	    if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6735  	       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6736  		  tempcx += 7;
6737  	       }
6738  	    }
6739  	    tempcx += crt2crtc;
6740  	    if(crt2crtc >= 4) {
6741  	       SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xff);
6742  	    }
6743  
6744  	    if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6745  	       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6746  		  if(crt2crtc == 4) {
6747  		     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x28);
6748  		  }
6749  	       }
6750  	    }
6751  	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x18);
6752  	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
6753  	 }
6754        }
6755     }
6756  }
6757  
6758  /* For ECS A907. Highly preliminary. */
6759  static void
SiS_Set300Part2Regs(struct SiS_Private * SiS_Pr,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex,unsigned short ModeNo)6760  SiS_Set300Part2Regs(struct SiS_Private *SiS_Pr, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex,
6761  		    unsigned short ModeNo)
6762  {
6763    const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
6764    unsigned short crt2crtc, resindex;
6765    int i, j;
6766  
6767    if(SiS_Pr->ChipType != SIS_300) return;
6768    if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;
6769    if(SiS_Pr->UseCustomMode) return;
6770  
6771    if(ModeNo <= 0x13) {
6772       crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6773    } else {
6774       crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6775    }
6776  
6777    resindex = crt2crtc & 0x3F;
6778    if(SiS_Pr->SiS_SetFlag & LCDVESATiming) CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6779    else                                    CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2;
6780  
6781    /* The BIOS code (1.16.51,56) is obviously a fragment! */
6782    if(ModeNo > 0x13) {
6783       CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6784       resindex = 4;
6785    }
6786  
6787    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
6788    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
6789    for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
6790       SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6791    }
6792    for(j = 0x1c; j <= 0x1d; i++, j++ ) {
6793       SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6794    }
6795    for(j = 0x1f; j <= 0x21; i++, j++ ) {
6796       SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6797    }
6798    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
6799    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
6800  }
6801  #endif
6802  
6803  static void
SiS_SetTVSpecial(struct SiS_Private * SiS_Pr,unsigned short ModeNo)6804  SiS_SetTVSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
6805  {
6806    if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;
6807    if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) return;
6808    if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) return;
6809  
6810    if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
6811       if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6812          static const unsigned char specialtv[] = {
6813  		0xa7,0x07,0xf2,0x6e,0x17,0x8b,0x73,0x53,
6814  		0x13,0x40,0x34,0xf4,0x63,0xbb,0xcc,0x7a,
6815  		0x58,0xe4,0x73,0xda,0x13
6816  	};
6817  	int i, j;
6818  	for(i = 0x1c, j = 0; i <= 0x30; i++, j++) {
6819  	   SiS_SetReg(SiS_Pr->SiS_Part2Port,i,specialtv[j]);
6820  	}
6821  	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,0x72);
6822  	if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750)) {
6823  	   if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6824  	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14);
6825  	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1b);
6826  	   } else {
6827  	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14);  /* 15 */
6828  	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1a);  /* 1b */
6829  	   }
6830  	}
6831       }
6832    } else {
6833       if((ModeNo == 0x38) || (ModeNo == 0x4a) || (ModeNo == 0x64) ||
6834          (ModeNo == 0x52) || (ModeNo == 0x58) || (ModeNo == 0x5c)) {
6835          SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b);  /* 21 */
6836          SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54);  /* 5a */
6837       } else {
6838          SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1a);  /* 21 */
6839          SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x53);  /* 5a */
6840       }
6841    }
6842  }
6843  
6844  static void
SiS_SetGroup2_Tail(struct SiS_Private * SiS_Pr,unsigned short ModeNo)6845  SiS_SetGroup2_Tail(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
6846  {
6847    unsigned short temp;
6848  
6849    if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6850       if(SiS_Pr->SiS_VGAVDE == 525) {
6851  	temp = 0xc3;
6852  	if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6853  	   temp++;
6854  	   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp += 2;
6855  	}
6856  	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6857  	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xb3);
6858       } else if(SiS_Pr->SiS_VGAVDE == 420) {
6859  	temp = 0x4d;
6860  	if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6861  	   temp++;
6862  	   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp++;
6863  	}
6864  	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6865       }
6866    }
6867  
6868    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6869       if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
6870  	if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
6871  	   SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x1a,0x03);
6872  	   /* Not always for LV, see SetGrp2 */
6873  	}
6874  	temp = 1;
6875  	if(ModeNo <= 0x13) temp = 3;
6876  	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0b,temp);
6877       }
6878  #if 0
6879       /* 651+301C, for 1280x768 - do I really need that? */
6880       if((SiS_Pr->SiS_PanelXRes == 1280) && (SiS_Pr->SiS_PanelYRes == 768)) {
6881          if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) {
6882  	   if(((SiS_Pr->SiS_HDE == 640) && (SiS_Pr->SiS_VDE == 480)) ||
6883  	      ((SiS_Pr->SiS_HDE == 320) && (SiS_Pr->SiS_VDE == 240))) {
6884  	      SiS_SetReg(SiS_Part2Port,0x01,0x2b);
6885  	      SiS_SetReg(SiS_Part2Port,0x02,0x13);
6886  	      SiS_SetReg(SiS_Part2Port,0x04,0xe5);
6887  	      SiS_SetReg(SiS_Part2Port,0x05,0x08);
6888  	      SiS_SetReg(SiS_Part2Port,0x06,0xe2);
6889  	      SiS_SetReg(SiS_Part2Port,0x1c,0x21);
6890  	      SiS_SetReg(SiS_Part2Port,0x1d,0x45);
6891  	      SiS_SetReg(SiS_Part2Port,0x1f,0x0b);
6892  	      SiS_SetReg(SiS_Part2Port,0x20,0x00);
6893  	      SiS_SetReg(SiS_Part2Port,0x21,0xa9);
6894  	      SiS_SetReg(SiS_Part2Port,0x23,0x0b);
6895  	      SiS_SetReg(SiS_Part2Port,0x25,0x04);
6896  	   }
6897  	}
6898       }
6899  #endif
6900    }
6901  }
6902  
6903  static void
SiS_SetGroup2(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)6904  SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6905  		unsigned short RefreshRateTableIndex)
6906  {
6907    unsigned short i, j, tempax, tempbx, tempcx, tempch, tempcl, temp;
6908    unsigned short push2, modeflag, crt2crtc, bridgeoffset;
6909    unsigned int   longtemp, PhaseIndex;
6910    bool           newtvphase;
6911    const unsigned char *TimingPoint;
6912  #ifdef CONFIG_FB_SIS_315
6913    unsigned short resindex, CRT2Index;
6914    const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
6915  
6916    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
6917  #endif
6918  
6919    if(ModeNo <= 0x13) {
6920       modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6921       crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6922    } else if(SiS_Pr->UseCustomMode) {
6923       modeflag = SiS_Pr->CModeFlag;
6924       crt2crtc = 0;
6925    } else {
6926       modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6927       crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6928    }
6929  
6930    temp = 0;
6931    if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO)) temp |= 0x08;
6932    if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO)) temp |= 0x04;
6933    if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART)     temp |= 0x02;
6934    if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)  temp |= 0x01;
6935  
6936    if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) 	      temp |= 0x10;
6937  
6938    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x00,temp);
6939  
6940    PhaseIndex  = 0x01; /* SiS_PALPhase */
6941    TimingPoint = SiS_Pr->SiS_PALTiming;
6942  
6943    newtvphase = false;
6944    if( (SiS_Pr->SiS_VBType & VB_SIS30xBLV) &&
6945        ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6946  	(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6947       newtvphase = true;
6948    }
6949  
6950    if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6951  
6952       TimingPoint = SiS_Pr->SiS_HiTVExtTiming;
6953       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6954          TimingPoint = SiS_Pr->SiS_HiTVSt2Timing;
6955          if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
6956  	   TimingPoint = SiS_Pr->SiS_HiTVSt1Timing;
6957          }
6958       }
6959  
6960    } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6961  
6962       i = 0;
6963       if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)      i = 2;
6964       else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) i = 1;
6965  
6966       TimingPoint = &SiS_YPbPrTable[i][0];
6967  
6968       PhaseIndex = 0x00; /* SiS_NTSCPhase */
6969  
6970    } else if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6971  
6972       if(newtvphase) PhaseIndex = 0x09; /* SiS_PALPhase2 */
6973  
6974    } else {
6975  
6976       TimingPoint = SiS_Pr->SiS_NTSCTiming;
6977       PhaseIndex  = (SiS_Pr->SiS_TVMode & TVSetNTSCJ) ? 0x01 : 0x00;	/* SiS_PALPhase : SiS_NTSCPhase */
6978       if(newtvphase) PhaseIndex += 8;					/* SiS_PALPhase2 : SiS_NTSCPhase2 */
6979  
6980    }
6981  
6982    if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) {
6983       PhaseIndex = (SiS_Pr->SiS_TVMode & TVSetPALM) ? 0x02 : 0x03;	/* SiS_PALMPhase : SiS_PALNPhase */
6984       if(newtvphase) PhaseIndex += 8;					/* SiS_PALMPhase2 : SiS_PALNPhase2 */
6985    }
6986  
6987    if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6988       if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6989          PhaseIndex = 0x05; /* SiS_SpecialPhaseM */
6990       } else if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
6991          PhaseIndex = 0x11; /* SiS_SpecialPhaseJ */
6992       } else {
6993          PhaseIndex = 0x10; /* SiS_SpecialPhase */
6994       }
6995    }
6996  
6997    for(i = 0x31, j = 0; i <= 0x34; i++, j++) {
6998       SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[(PhaseIndex * 4) + j]);
6999    }
7000  
7001    for(i = 0x01, j = 0; i <= 0x2D; i++, j++) {
7002       SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
7003    }
7004    for(i = 0x39; i <= 0x45; i++, j++) {
7005       SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
7006    }
7007  
7008    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7009       if(SiS_Pr->SiS_ModeType != ModeText) {
7010          SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
7011       }
7012    }
7013  
7014    SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x0A,SiS_Pr->SiS_NewFlickerMode);
7015  
7016    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x35,SiS_Pr->SiS_RY1COE);
7017    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x36,SiS_Pr->SiS_RY2COE);
7018    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x37,SiS_Pr->SiS_RY3COE);
7019    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x38,SiS_Pr->SiS_RY4COE);
7020  
7021    if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)	tempax = 950;
7022    else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)  tempax = 680;
7023    else if(SiS_Pr->SiS_TVMode & TVSetPAL)	tempax = 520;
7024    else						tempax = 440; /* NTSC, YPbPr 525 */
7025  
7026    if( ((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) && (SiS_Pr->SiS_VDE <= tempax)) ||
7027        ( (SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) &&
7028          ((SiS_Pr->SiS_VGAHDE == 1024) || (SiS_Pr->SiS_VDE <= tempax)) ) ) {
7029  
7030       tempax -= SiS_Pr->SiS_VDE;
7031       tempax >>= 1;
7032       if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) {
7033          tempax >>= 1;
7034       }
7035       tempax &= 0x00ff;
7036  
7037       temp = tempax + (unsigned short)TimingPoint[0];
7038       SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
7039  
7040       temp = tempax + (unsigned short)TimingPoint[1];
7041       SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
7042  
7043       if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) && (SiS_Pr->SiS_VGAHDE >= 1024)) {
7044          if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7045             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b);
7046             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54);
7047          } else {
7048             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x17);
7049             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1d);
7050          }
7051       }
7052  
7053    }
7054  
7055    tempcx = SiS_Pr->SiS_HT;
7056    if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
7057    tempcx--;
7058    if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) tempcx--;
7059    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1B,tempcx);
7060    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0xF0,((tempcx >> 8) & 0x0f));
7061  
7062    tempcx = SiS_Pr->SiS_HT >> 1;
7063    if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
7064    tempcx += 7;
7065    if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
7066    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,((tempcx << 4) & 0xf0));
7067  
7068    tempbx = TimingPoint[j] | (TimingPoint[j+1] << 8);
7069    tempbx += tempcx;
7070    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x24,tempbx);
7071    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0F,((tempbx >> 4) & 0xf0));
7072  
7073    tempbx += 8;
7074    if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7075       tempbx -= 4;
7076       tempcx = tempbx;
7077    }
7078    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x29,0x0F,((tempbx << 4) & 0xf0));
7079  
7080    j += 2;
7081    tempcx += (TimingPoint[j] | (TimingPoint[j+1] << 8));
7082    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x27,tempcx);
7083    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x28,0x0F,((tempcx >> 4) & 0xf0));
7084  
7085    tempcx += 8;
7086    if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
7087    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2A,0x0F,((tempcx << 4) & 0xf0));
7088  
7089    tempcx = SiS_Pr->SiS_HT >> 1;
7090    if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
7091    j += 2;
7092    tempcx -= (TimingPoint[j] | ((TimingPoint[j+1]) << 8));
7093    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2D,0x0F,((tempcx << 4) & 0xf0));
7094  
7095    tempcx -= 11;
7096    if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
7097       tempcx = SiS_GetVGAHT2(SiS_Pr) - 1;
7098    }
7099    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2E,tempcx);
7100  
7101    tempbx = SiS_Pr->SiS_VDE;
7102    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7103       if(SiS_Pr->SiS_VGAVDE == 360) tempbx = 746;
7104       if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 746;
7105       if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 853;
7106    } else if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
7107               (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p))) ) {
7108       tempbx >>= 1;
7109       if(SiS_Pr->ChipType >= SIS_315H) {
7110          if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
7111  	   if((ModeNo <= 0x13) && (crt2crtc == 1)) tempbx++;
7112  	} else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7113  	   if(SiS_Pr->SiS_ModeType <= ModeVGA) {
7114  	      if(crt2crtc == 4) tempbx++;
7115  	   }
7116  	}
7117       }
7118       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7119          if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7120  	   if((ModeNo == 0x2f) || (ModeNo == 0x5d) || (ModeNo == 0x5e)) tempbx++;
7121  	}
7122  	if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
7123  	   if(ModeNo == 0x03) tempbx++; /* From 1.10.7w - doesn't make sense */
7124          }
7125       }
7126    }
7127    tempbx -= 2;
7128    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2F,tempbx);
7129  
7130    temp = (tempcx >> 8) & 0x0F;
7131    temp |= ((tempbx >> 2) & 0xC0);
7132    if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
7133       temp |= 0x10;
7134       if(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO) temp |= 0x20;
7135    }
7136    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,temp);
7137  
7138    if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {
7139       SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xdf,((tempbx & 0x0400) >> 5));
7140    }
7141  
7142    if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7143       tempbx = SiS_Pr->SiS_VDE;
7144       if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
7145           (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) ) {
7146          tempbx >>= 1;
7147       }
7148       tempbx -= 3;
7149       temp = ((tempbx >> 3) & 0x60) | 0x18;
7150       SiS_SetReg(SiS_Pr->SiS_Part2Port,0x46,temp);
7151       SiS_SetReg(SiS_Pr->SiS_Part2Port,0x47,tempbx);
7152  
7153       if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {
7154  	SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xbf,((tempbx & 0x0400) >> 4));
7155       }
7156    }
7157  
7158    tempbx = 0;
7159    if(!(modeflag & HalfDCLK)) {
7160       if(SiS_Pr->SiS_VGAHDE >= SiS_Pr->SiS_HDE) {
7161          tempax = 0;
7162          tempbx |= 0x20;
7163       }
7164    }
7165  
7166    tempch = tempcl = 0x01;
7167    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7168       if(SiS_Pr->SiS_VGAHDE >= 960) {
7169          if((!(modeflag & HalfDCLK)) || (SiS_Pr->ChipType < SIS_315H)) {
7170  	   tempcl = 0x20;
7171  	   if(SiS_Pr->SiS_VGAHDE >= 1280) {
7172                tempch = 20;
7173                tempbx &= ~0x20;
7174             } else {
7175  	      tempch = 25; /* OK */
7176  	   }
7177          }
7178       }
7179    }
7180  
7181    if(!(tempbx & 0x20)) {
7182       if(modeflag & HalfDCLK) tempcl <<= 1;
7183       longtemp = ((SiS_Pr->SiS_VGAHDE * tempch) / tempcl) << 13;
7184       if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) longtemp <<= 3;
7185       tempax = longtemp / SiS_Pr->SiS_HDE;
7186       if(longtemp % SiS_Pr->SiS_HDE) tempax++;
7187       tempbx |= ((tempax >> 8) & 0x1F);
7188       tempcx = tempax >> 13;
7189    }
7190  
7191    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,tempax);
7192    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,tempbx);
7193  
7194    if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7195  
7196       tempcx &= 0x07;
7197       if(tempbx & 0x20) tempcx = 0;
7198       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xF8,tempcx);
7199  
7200       if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7201          tempbx = 0x0382;
7202          tempcx = 0x007e;
7203       } else {
7204          tempbx = 0x0369;
7205          tempcx = 0x0061;
7206       }
7207       SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4B,tempbx);
7208       SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4C,tempcx);
7209       temp = (tempcx & 0x0300) >> 6;
7210       temp |= ((tempbx >> 8) & 0x03);
7211       if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7212          temp |= 0x10;
7213  	if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)      temp |= 0x20;
7214  	else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp |= 0x40;
7215       }
7216       SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4D,temp);
7217  
7218       temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7219       SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,(temp - 3));
7220  
7221       SiS_SetTVSpecial(SiS_Pr, ModeNo);
7222  
7223       if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
7224          temp = 0;
7225          if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
7226          SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xf7,temp);
7227       }
7228  
7229    }
7230  
7231    if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7232       if(!(SiS_Pr->SiS_TVMode & TVSetNTSC1024)) {
7233          temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
7234          SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,(temp - 1));
7235       }
7236       SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF);
7237    }
7238  
7239    if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7240       if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
7241          SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,0x00);
7242       }
7243    }
7244  
7245    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) return;
7246  
7247    /* From here: Part2 LCD setup */
7248  
7249    tempbx = SiS_Pr->SiS_HDE;
7250    if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7251    tempbx--;			         	/* RHACTE = HDE - 1 */
7252    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2C,tempbx);
7253    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,((tempbx >> 4) & 0xf0));
7254  
7255    temp = 0x01;
7256    if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7257       if(SiS_Pr->SiS_ModeType == ModeEGA) {
7258          if(SiS_Pr->SiS_VGAHDE >= 1024) {
7259             temp = 0x02;
7260             if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7261                temp = 0x01;
7262  	   }
7263          }
7264       }
7265    }
7266    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,temp);
7267  
7268    tempbx = SiS_Pr->SiS_VDE - 1;
7269    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x03,tempbx);
7270    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0C,0xF8,((tempbx >> 8) & 0x07));
7271  
7272    tempcx = SiS_Pr->SiS_VT - 1;
7273    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x19,tempcx);
7274    temp = (tempcx >> 3) & 0xE0;
7275    if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
7276       /* Enable dithering; only do this for 32bpp mode */
7277       if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
7278          temp |= 0x10;
7279       }
7280    }
7281    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1A,0x0f,temp);
7282  
7283    SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x09,0xF0);
7284    SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x0A,0xF0);
7285  
7286    SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB);
7287    SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF);
7288  
7289  #ifdef CONFIG_FB_SIS_315
7290    if(SiS_GetCRT2Part2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7291                            			&CRT2Index, &resindex)) {
7292        switch(CRT2Index) {
7293          case 206: CRT2Part2Ptr = SiS310_CRT2Part2_Asus1024x768_3;    break;
7294  	default:
7295          case 200: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;   break;
7296        }
7297  
7298        SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
7299        SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
7300        for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
7301          SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7302        }
7303        for(j = 0x1c; j <= 0x1d; i++, j++ ) {
7304          SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7305        }
7306        for(j = 0x1f; j <= 0x21; i++, j++ ) {
7307          SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7308        }
7309        SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
7310        SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
7311  
7312        SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7313  
7314    } else {
7315  #endif
7316  
7317      /* Checked for 1024x768, 1280x1024, 1400x1050, 1600x1200 */
7318      /*             Clevo dual-link 1024x768 */
7319      /* 		   Compaq 1280x1024 has HT 1696 sometimes (calculation OK, if given HT is correct)  */
7320      /*		   Acer: OK, but uses different setting for VESA timing at 640/800/1024 and 640x400 */
7321  
7322      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7323         if((SiS_Pr->SiS_LCDInfo & LCDPass11) || (SiS_Pr->PanelYRes == SiS_Pr->SiS_VDE)) {
7324            tempbx = SiS_Pr->SiS_VDE - 1;
7325            tempcx = SiS_Pr->SiS_VT - 1;
7326         } else {
7327            tempbx = SiS_Pr->SiS_VDE + ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7328  	  tempcx = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7329         }
7330      } else {
7331         tempbx = SiS_Pr->PanelYRes;
7332         tempcx = SiS_Pr->SiS_VT;
7333         tempax = 1;
7334         if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7335            tempax = SiS_Pr->PanelYRes;
7336  	  /* if(SiS_Pr->SiS_VGAVDE == 525) tempax += 0x3c;   */  /* 651+301C */
7337            if(SiS_Pr->PanelYRes < SiS_Pr->SiS_VDE) {
7338               tempax = tempcx = 0;
7339            } else {
7340               tempax -= SiS_Pr->SiS_VDE;
7341            }
7342            tempax >>= 1;
7343         }
7344         tempcx -= tempax; /* lcdvdes */
7345         tempbx -= tempax; /* lcdvdee */
7346      }
7347  
7348      /* Non-expanding: lcdvdes = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */
7349  
7350      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,tempcx);	/* lcdvdes  */
7351      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,tempbx);	/* lcdvdee  */
7352  
7353      temp = (tempbx >> 5) & 0x38;
7354      temp |= ((tempcx >> 8) & 0x07);
7355      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
7356  
7357      tempax = SiS_Pr->SiS_VDE;
7358      if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7359         tempax = SiS_Pr->PanelYRes;
7360      }
7361      tempcx = (SiS_Pr->SiS_VT - tempax) >> 4;
7362      if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7363         if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7364  	  tempcx = (SiS_Pr->SiS_VT - tempax) / 10;
7365         }
7366      }
7367  
7368      tempbx = ((SiS_Pr->SiS_VT + SiS_Pr->SiS_VDE) >> 1) - 1;
7369      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7370         if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7371            if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { /* ? */
7372               tempax = SiS_Pr->SiS_VT - SiS_Pr->PanelYRes;
7373  	     if(tempax % 4) { tempax >>= 2; tempax++; }
7374  	     else           { tempax >>= 2;           }
7375               tempbx -= (tempax - 1);
7376  	  } else {
7377  	     tempbx -= 10;
7378  	     if(tempbx <= SiS_Pr->SiS_VDE) tempbx = SiS_Pr->SiS_VDE + 1;
7379  	  }
7380         }
7381      }
7382      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
7383         tempbx++;
7384         if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (crt2crtc == 6)) {
7385            if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7386  	     tempbx = 770;
7387  	     tempcx = 3;
7388  	  }
7389         }
7390      }
7391  
7392      /* non-expanding: lcdvrs = ((VT + VDE) / 2) - 10 */
7393  
7394      if(SiS_Pr->UseCustomMode) {
7395         tempbx = SiS_Pr->CVSyncStart;
7396      }
7397  
7398      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,tempbx);	    /* lcdvrs */
7399  
7400      temp = (tempbx >> 4) & 0xF0;
7401      tempbx += (tempcx + 1);
7402      temp |= (tempbx & 0x0F);
7403  
7404      if(SiS_Pr->UseCustomMode) {
7405         temp &= 0xf0;
7406         temp |= (SiS_Pr->CVSyncEnd & 0x0f);
7407      }
7408  
7409      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
7410  
7411  #ifdef CONFIG_FB_SIS_300
7412      SiS_Group2LCDSpecial(SiS_Pr, ModeNo, crt2crtc);
7413  #endif
7414  
7415      bridgeoffset = 7;
7416      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)	bridgeoffset += 2;
7417      if(SiS_Pr->SiS_VBType & VB_SIS30xCLV)	bridgeoffset += 2; /* OK for Averatec 1280x800 (301C) */
7418      if(SiS_IsDualLink(SiS_Pr))			bridgeoffset++;
7419      else if(SiS_Pr->SiS_VBType & VB_SIS302LV)	bridgeoffset++;    /* OK for Asus A4L 1280x800 */
7420      /* Higher bridgeoffset shifts to the LEFT */
7421  
7422      temp = 0;
7423      if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7424         if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7425  	  temp = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7426  	  if(SiS_IsDualLink(SiS_Pr)) temp >>= 1;
7427         }
7428      }
7429      temp += bridgeoffset;
7430      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1F,temp);  	     /* lcdhdes */
7431      SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0F,((temp >> 4) & 0xf0));
7432  
7433      tempcx = SiS_Pr->SiS_HT;
7434      tempax = tempbx = SiS_Pr->SiS_HDE;
7435      if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7436         if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7437            tempax = SiS_Pr->PanelXRes;
7438            tempbx = SiS_Pr->PanelXRes - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7439         }
7440      }
7441      if(SiS_IsDualLink(SiS_Pr)) {
7442         tempcx >>= 1;
7443         tempbx >>= 1;
7444         tempax >>= 1;
7445      }
7446  
7447      tempbx += bridgeoffset;
7448  
7449      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,tempbx);	    /* lcdhdee */
7450      SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0xF0,((tempbx >> 8) & 0x0f));
7451  
7452      tempcx = (tempcx - tempax) >> 2;
7453  
7454      tempbx += tempcx;
7455      push2 = tempbx;
7456  
7457      if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7458         if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7459            if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
7460               if(SiS_Pr->SiS_HDE == 1280) tempbx = (tempbx & 0xff00) | 0x47;
7461  	  }
7462         }
7463      }
7464  
7465      if(SiS_Pr->UseCustomMode) {
7466         tempbx = SiS_Pr->CHSyncStart;
7467         if(modeflag & HalfDCLK) tempbx <<= 1;
7468         if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7469         tempbx += bridgeoffset;
7470      }
7471  
7472      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1C,tempbx);	    /* lcdhrs */
7473      SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,((tempbx >> 4) & 0xf0));
7474  
7475      tempbx = push2;
7476  
7477      tempcx <<= 1;
7478      if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7479         if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) tempcx >>= 2;
7480      }
7481      tempbx += tempcx;
7482  
7483      if(SiS_Pr->UseCustomMode) {
7484         tempbx = SiS_Pr->CHSyncEnd;
7485         if(modeflag & HalfDCLK) tempbx <<= 1;
7486         if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7487         tempbx += bridgeoffset;
7488      }
7489  
7490      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,tempbx);	    /* lcdhre */
7491  
7492      SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7493  
7494  #ifdef CONFIG_FB_SIS_300
7495      SiS_Set300Part2Regs(SiS_Pr, ModeIdIndex, RefreshRateTableIndex, ModeNo);
7496  #endif
7497  #ifdef CONFIG_FB_SIS_315
7498    } /* CRT2-LCD from table */
7499  #endif
7500  }
7501  
7502  /*********************************************/
7503  /*         SET PART 3 REGISTER GROUP         */
7504  /*********************************************/
7505  
7506  static void
SiS_SetGroup3(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)7507  SiS_SetGroup3(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7508  {
7509    unsigned short i;
7510    const unsigned char *tempdi;
7511  
7512    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
7513  
7514  #ifndef SIS_CP
7515    SiS_SetReg(SiS_Pr->SiS_Part3Port,0x00,0x00);
7516  #else
7517    SIS_CP_INIT301_CP
7518  #endif
7519  
7520    if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7521       SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7522       SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7523    } else {
7524       SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xF5);
7525       SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xB7);
7526    }
7527  
7528    if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7529       SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7530       SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7531       SiS_SetReg(SiS_Pr->SiS_Part3Port,0x3D,0xA8);
7532    }
7533  
7534    tempdi = NULL;
7535    if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7536       tempdi = SiS_Pr->SiS_HiTVGroup3Data;
7537       if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
7538          tempdi = SiS_Pr->SiS_HiTVGroup3Simu;
7539       }
7540    } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7541       if(!(SiS_Pr->SiS_TVMode & TVSetYPbPr525i)) {
7542          tempdi = SiS_HiTVGroup3_1;
7543          if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempdi = SiS_HiTVGroup3_2;
7544       }
7545    }
7546    if(tempdi) {
7547       for(i=0; i<=0x3E; i++) {
7548          SiS_SetReg(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
7549       }
7550       if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
7551  	if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
7552  	   SiS_SetReg(SiS_Pr->SiS_Part3Port,0x28,0x3f);
7553  	}
7554       }
7555    }
7556  
7557  #ifdef SIS_CP
7558    SIS_CP_INIT301_CP2
7559  #endif
7560  }
7561  
7562  /*********************************************/
7563  /*         SET PART 4 REGISTER GROUP         */
7564  /*********************************************/
7565  
7566  #ifdef CONFIG_FB_SIS_315
7567  #if 0
7568  static void
7569  SiS_ShiftXPos(struct SiS_Private *SiS_Pr, int shift)
7570  {
7571     unsigned short temp, temp1, temp2;
7572  
7573     temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x1f);
7574     temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x20);
7575     temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7576     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,temp);
7577     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0f,((temp >> 4) & 0xf0));
7578     temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x2b) & 0x0f;
7579     temp = (unsigned short)((int)(temp) + shift);
7580     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2b,0xf0,(temp & 0x0f));
7581     temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7582     temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x42);
7583     temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7584     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,temp);
7585     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x42,0x0f,((temp >> 4) & 0xf0));
7586  }
7587  #endif
7588  
7589  static void
SiS_SetGroup4_C_ELV(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)7590  SiS_SetGroup4_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7591  {
7592     unsigned short temp, temp1;
7593     unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
7594  
7595     if(!(SiS_Pr->SiS_VBType & VB_SIS30xCLV)) return;
7596     if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToHiVision | SetCRT2ToYPbPr525750))) return;
7597  
7598     if(SiS_Pr->ChipType >= XGI_20) return;
7599  
7600     if((SiS_Pr->ChipType >= SIS_661) && (SiS_Pr->SiS_ROMNew)) {
7601        if(!(ROMAddr[0x61] & 0x04)) return;
7602     }
7603  
7604     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3a,0x08);
7605     temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x3a);
7606     if(!(temp & 0x01)) {
7607        SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3a,0xdf);
7608        SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xfc);
7609        if((SiS_Pr->ChipType < SIS_661) && (!(SiS_Pr->SiS_ROMNew))) {
7610           SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xf8);
7611        }
7612        SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0xfb);
7613        if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)      temp = 0x0000;
7614        else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp = 0x0002;
7615        else if(SiS_Pr->SiS_TVMode & TVSetHiVision)  temp = 0x0400;
7616        else					   temp = 0x0402;
7617        if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
7618           temp1 = 0;
7619  	 if(SiS_Pr->SiS_TVMode & TVAspect43) temp1 = 4;
7620  	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0f,0xfb,temp1);
7621  	 if(SiS_Pr->SiS_TVMode & TVAspect43LB) temp |= 0x01;
7622  	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0x7c,(temp & 0xff));
7623  	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7624  	 if(ModeNo > 0x13) {
7625              SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x39,0xfd);
7626           }
7627        } else {
7628           temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x3b) & 0x03;
7629  	 if(temp1 == 0x01) temp |= 0x01;
7630  	 if(temp1 == 0x03) temp |= 0x04;  /* ? why not 0x10? */
7631  	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xf8,(temp & 0xff));
7632  	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7633  	 if(ModeNo > 0x13) {
7634              SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3b,0xfd);
7635           }
7636        }
7637  
7638  #if 0
7639        if(SiS_Pr->ChipType >= SIS_661) { 		/* ? */
7640           if(SiS_Pr->SiS_TVMode & TVAspect43) {
7641              if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
7642  	       if(resinfo == SIS_RI_1024x768) {
7643  	          SiS_ShiftXPos(SiS_Pr, 97);
7644  	       } else {
7645  	          SiS_ShiftXPos(SiS_Pr, 111);
7646  	       }
7647  	    } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
7648  	       SiS_ShiftXPos(SiS_Pr, 136);
7649  	    }
7650           }
7651        }
7652  #endif
7653  
7654     }
7655  
7656  }
7657  #endif
7658  
7659  static void
SiS_SetCRT2VCLK(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)7660  SiS_SetCRT2VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7661                   unsigned short RefreshRateTableIndex)
7662  {
7663    unsigned short vclkindex, temp, reg1, reg2;
7664  
7665    if(SiS_Pr->UseCustomMode) {
7666       reg1 = SiS_Pr->CSR2B;
7667       reg2 = SiS_Pr->CSR2C;
7668    } else {
7669       vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
7670       reg1 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
7671       reg2 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
7672    }
7673  
7674    if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7675       if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {
7676          SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x57);
7677   	SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,0x46);
7678  	SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1f,0xf6);
7679       } else {
7680          SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7681          SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7682       }
7683    } else {
7684       SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x01);
7685       SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7686       SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7687    }
7688    SiS_SetReg(SiS_Pr->SiS_Part4Port,0x12,0x00);
7689    temp = 0x08;
7690    if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) temp |= 0x20;
7691    SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,temp);
7692  }
7693  
7694  static void
SiS_SetDualLinkEtc(struct SiS_Private * SiS_Pr)7695  SiS_SetDualLinkEtc(struct SiS_Private *SiS_Pr)
7696  {
7697    if(SiS_Pr->ChipType >= SIS_315H) {
7698       if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
7699  	if((SiS_CRT2IsLCD(SiS_Pr)) ||
7700  	   (SiS_IsVAMode(SiS_Pr))) {
7701  	   if(SiS_Pr->SiS_LCDInfo & LCDDualLink) {
7702  	      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
7703  	   } else {
7704  	      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,~0x20);
7705  	   }
7706  	}
7707       }
7708    }
7709    if(SiS_Pr->SiS_VBType & VB_SISEMI) {
7710       SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
7711  #ifdef SET_EMI
7712       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
7713  #endif
7714       SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
7715    }
7716  }
7717  
7718  static void
SiS_SetGroup4(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)7719  SiS_SetGroup4(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7720  		unsigned short RefreshRateTableIndex)
7721  {
7722    unsigned short tempax, tempcx, tempbx, modeflag, temp, resinfo;
7723    unsigned int   tempebx, tempeax, templong;
7724  
7725    if(ModeNo <= 0x13) {
7726       modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7727       resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
7728    } else if(SiS_Pr->UseCustomMode) {
7729       modeflag = SiS_Pr->CModeFlag;
7730       resinfo = 0;
7731    } else {
7732       modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7733       resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
7734    }
7735  
7736    if(SiS_Pr->ChipType >= SIS_315H) {
7737       if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
7738  	if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7739  	   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7740  	}
7741       }
7742    }
7743  
7744    if(SiS_Pr->SiS_VBType & (VB_SIS30xCLV | VB_SIS302LV)) {
7745       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7746  	SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x10,0x9f);
7747       }
7748    }
7749  
7750    if(SiS_Pr->ChipType >= SIS_315H) {
7751       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7752  	SiS_SetDualLinkEtc(SiS_Pr);
7753  	return;
7754       }
7755    }
7756  
7757    SiS_SetReg(SiS_Pr->SiS_Part4Port,0x13,SiS_Pr->SiS_RVBHCFACT);
7758  
7759    tempbx = SiS_Pr->SiS_RVBHCMAX;
7760    SiS_SetReg(SiS_Pr->SiS_Part4Port,0x14,tempbx);
7761  
7762    temp = (tempbx >> 1) & 0x80;
7763  
7764    tempcx = SiS_Pr->SiS_VGAHT - 1;
7765    SiS_SetReg(SiS_Pr->SiS_Part4Port,0x16,tempcx);
7766  
7767    temp |= ((tempcx >> 5) & 0x78);
7768  
7769    tempcx = SiS_Pr->SiS_VGAVT - 1;
7770    if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempcx -= 5;
7771    SiS_SetReg(SiS_Pr->SiS_Part4Port,0x17,tempcx);
7772  
7773    temp |= ((tempcx >> 8) & 0x07);
7774    SiS_SetReg(SiS_Pr->SiS_Part4Port,0x15,temp);
7775  
7776    tempbx = SiS_Pr->SiS_VGAHDE;
7777    if(modeflag & HalfDCLK)    tempbx >>= 1;
7778    if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7779  
7780    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7781       temp = 0;
7782       if(tempbx > 800)        temp = 0x60;
7783    } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7784       temp = 0;
7785       if(tempbx > 1024)       temp = 0xC0;
7786       else if(tempbx >= 960)  temp = 0xA0;
7787    } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
7788       temp = 0;
7789       if(tempbx >= 1280)      temp = 0x40;
7790       else if(tempbx >= 1024) temp = 0x20;
7791    } else {
7792       temp = 0x80;
7793       if(tempbx >= 1024)      temp = 0xA0;
7794    }
7795  
7796    temp |= SiS_Pr->Init_P4_0E;
7797  
7798    if(SiS_Pr->SiS_VBType & VB_SIS301) {
7799       if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
7800          temp &= 0xf0;
7801          temp |= 0x0A;
7802       }
7803    }
7804  
7805    SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0E,0x10,temp);
7806  
7807    tempeax = SiS_Pr->SiS_VGAVDE;
7808    tempebx = SiS_Pr->SiS_VDE;
7809    if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7810       if(!(temp & 0xE0)) tempebx >>=1;
7811    }
7812  
7813    tempcx = SiS_Pr->SiS_RVBHRS;
7814    SiS_SetReg(SiS_Pr->SiS_Part4Port,0x18,tempcx);
7815    tempcx >>= 8;
7816    tempcx |= 0x40;
7817  
7818    if(tempeax <= tempebx) {
7819       tempcx ^= 0x40;
7820    } else {
7821       tempeax -= tempebx;
7822    }
7823  
7824    tempeax *= (256 * 1024);
7825    templong = tempeax % tempebx;
7826    tempeax /= tempebx;
7827    if(templong) tempeax++;
7828  
7829    temp = (unsigned short)(tempeax & 0x000000FF);
7830    SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1B,temp);
7831    temp = (unsigned short)((tempeax & 0x0000FF00) >> 8);
7832    SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1A,temp);
7833    temp = (unsigned short)((tempeax >> 12) & 0x70); /* sic! */
7834    temp |= (tempcx & 0x4F);
7835    SiS_SetReg(SiS_Pr->SiS_Part4Port,0x19,temp);
7836  
7837    if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7838  
7839       SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1C,0x28);
7840  
7841       /* Calc Linebuffer max address and set/clear decimode */
7842       tempbx = 0;
7843       if(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p)) tempbx = 0x08;
7844       tempax = SiS_Pr->SiS_VGAHDE;
7845       if(modeflag & HalfDCLK)    tempax >>= 1;
7846       if(SiS_IsDualLink(SiS_Pr)) tempax >>= 1;
7847       if(tempax > 800) {
7848          if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7849  	   tempax -= 800;
7850  	} else {
7851  	   tempbx = 0x08;
7852  	   if(tempax == 960)	   tempax *= 25; /* Correct */
7853             else if(tempax == 1024) tempax *= 25;
7854             else			   tempax *= 20;
7855  	   temp = tempax % 32;
7856  	   tempax /= 32;
7857  	   if(temp) tempax++;
7858  	   tempax++;
7859  	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7860  	      if(resinfo == SIS_RI_1024x768 ||
7861  	         resinfo == SIS_RI_1024x576 ||
7862  		 resinfo == SIS_RI_1280x1024 ||
7863  		 resinfo == SIS_RI_1280x720) {
7864  	         /* Otherwise white line or garbage at right edge */
7865  	         tempax = (tempax & 0xff00) | 0x20;
7866  	      }
7867  	   }
7868  	}
7869       }
7870       tempax--;
7871       temp = ((tempax >> 4) & 0x30) | tempbx;
7872       SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1D,tempax);
7873       SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1E,temp);
7874  
7875       temp = 0x0036; tempbx = 0xD0;
7876       if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
7877  	temp = 0x0026; tempbx = 0xC0; /* See En/DisableBridge() */
7878       }
7879       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7880          if(!(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetHiVision | TVSetYPbPr750p | TVSetYPbPr525p))) {
7881  	   temp |= 0x01;
7882  	   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7883  	      if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
7884    	         temp &= ~0x01;
7885  	      }
7886  	   }
7887  	}
7888       }
7889       SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,tempbx,temp);
7890  
7891       tempbx = SiS_Pr->SiS_HT >> 1;
7892       if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7893       tempbx -= 2;
7894       SiS_SetReg(SiS_Pr->SiS_Part4Port,0x22,tempbx);
7895       temp = (tempbx >> 5) & 0x38;
7896       SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp);
7897  
7898       if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
7899  	if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7900             SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7901  	   /* LCD-too-dark-error-source, see FinalizeLCD() */
7902  	}
7903       }
7904  
7905       SiS_SetDualLinkEtc(SiS_Pr);
7906  
7907    }  /* 301B */
7908  
7909    SiS_SetCRT2VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
7910  }
7911  
7912  /*********************************************/
7913  /*         SET PART 5 REGISTER GROUP         */
7914  /*********************************************/
7915  
7916  static void
SiS_SetGroup5(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)7917  SiS_SetGroup5(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7918  {
7919  
7920    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)  return;
7921  
7922    if(SiS_Pr->SiS_ModeType == ModeVGA) {
7923       if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))) {
7924          SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
7925          SiS_LoadDAC(SiS_Pr, ModeNo, ModeIdIndex);
7926       }
7927    }
7928  }
7929  
7930  /*********************************************/
7931  /*     MODIFY CRT1 GROUP FOR SLAVE MODE      */
7932  /*********************************************/
7933  
7934  static bool
SiS_GetLVDSCRT1Ptr(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex,unsigned short * ResIndex,unsigned short * DisplayType)7935  SiS_GetLVDSCRT1Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7936  		   unsigned short RefreshRateTableIndex, unsigned short *ResIndex,
7937  		   unsigned short *DisplayType)
7938   {
7939    unsigned short modeflag = 0;
7940    bool checkhd = true;
7941  
7942    /* Pass 1:1 not supported here */
7943  
7944    if(ModeNo <= 0x13) {
7945       modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7946       (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
7947    } else {
7948       modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7949       (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
7950    }
7951  
7952    (*ResIndex) &= 0x3F;
7953  
7954    if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
7955  
7956       (*DisplayType) = 80;
7957       if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
7958        	(*DisplayType) = 82;
7959  	if(SiS_Pr->SiS_ModeType > ModeVGA) {
7960  	   if(SiS_Pr->SiS_CHSOverScan) (*DisplayType) = 84;
7961  	}
7962       }
7963       if((*DisplayType) != 84) {
7964          if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
7965       }
7966  
7967    } else {
7968  
7969       (*DisplayType = 0);
7970       switch(SiS_Pr->SiS_LCDResInfo) {
7971       case Panel_320x240_1: (*DisplayType) = 50;
7972  			   checkhd = false;
7973  			   break;
7974       case Panel_320x240_2: (*DisplayType) = 14;
7975  			   break;
7976       case Panel_320x240_3: (*DisplayType) = 18;
7977  			   break;
7978       case Panel_640x480:   (*DisplayType) = 10;
7979  			   break;
7980       case Panel_1024x600:  (*DisplayType) = 26;
7981  			   break;
7982       default: return true;
7983       }
7984  
7985       if(checkhd) {
7986          if(modeflag & HalfDCLK) (*DisplayType)++;
7987       }
7988  
7989       if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
7990          if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) (*DisplayType) += 2;
7991       }
7992  
7993    }
7994  
7995    return true;
7996  }
7997  
7998  static void
SiS_ModCRT1CRTC(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)7999  SiS_ModCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
8000                  unsigned short RefreshRateTableIndex)
8001  {
8002    unsigned short tempah, i, modeflag, j, ResIndex, DisplayType;
8003    const struct SiS_LVDSCRT1Data *LVDSCRT1Ptr=NULL;
8004    static const unsigned short CRIdx[] = {
8005  	0x00, 0x02, 0x03, 0x04, 0x05, 0x06,
8006  	0x07, 0x10, 0x11, 0x15, 0x16
8007    };
8008  
8009    if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
8010       (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
8011       (SiS_Pr->SiS_CustomT == CUT_PANEL848)  ||
8012       (SiS_Pr->SiS_CustomT == CUT_PANEL856) )
8013       return;
8014  
8015    if(SiS_Pr->SiS_IF_DEF_LVDS) {
8016       if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
8017          if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;
8018       }
8019    } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
8020       if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;
8021    } else return;
8022  
8023    if(SiS_Pr->SiS_LCDInfo & LCDPass11) return;
8024  
8025    if(SiS_Pr->ChipType < SIS_315H) {
8026       if(SiS_Pr->SiS_SetFlag & SetDOSMode) return;
8027    }
8028  
8029    if(!(SiS_GetLVDSCRT1Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
8030                            &ResIndex, &DisplayType))) {
8031       return;
8032    }
8033  
8034    switch(DisplayType) {
8035      case 50: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_1;           break; /* xSTN */
8036      case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2;           break; /* xSTN */
8037      case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2_H;         break; /* xSTN */
8038      case 18: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3;           break; /* xSTN */
8039      case 19: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3_H;         break; /* xSTN */
8040      case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1;           break;
8041      case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1_H;         break;
8042  #if 0 /* Works better with calculated numbers */
8043      case 26: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1;          break;
8044      case 27: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1_H;        break;
8045      case 28: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2;          break;
8046      case 29: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2_H;        break;
8047  #endif
8048      case 80: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC;               break;
8049      case 81: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC;               break;
8050      case 82: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL;                break;
8051      case 83: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL;                break;
8052      case 84: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1SOPAL;               break;
8053    }
8054  
8055    if(LVDSCRT1Ptr) {
8056  
8057       SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
8058  
8059       for(i = 0; i <= 10; i++) {
8060          tempah = (LVDSCRT1Ptr + ResIndex)->CR[i];
8061          SiS_SetReg(SiS_Pr->SiS_P3d4,CRIdx[i],tempah);
8062       }
8063  
8064       for(i = 0x0A, j = 11; i <= 0x0C; i++, j++) {
8065          tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
8066          SiS_SetReg(SiS_Pr->SiS_P3c4,i,tempah);
8067       }
8068  
8069       tempah = (LVDSCRT1Ptr + ResIndex)->CR[14] & 0xE0;
8070       SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);
8071  
8072       if(ModeNo <= 0x13) modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
8073       else               modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
8074  
8075       tempah = ((LVDSCRT1Ptr + ResIndex)->CR[14] & 0x01) << 5;
8076       if(modeflag & DoubleScanMode) tempah |= 0x80;
8077       SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
8078  
8079    } else {
8080  
8081       SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
8082  
8083    }
8084  }
8085  
8086  /*********************************************/
8087  /*              SET CRT2 ECLK                */
8088  /*********************************************/
8089  
8090  static void
SiS_SetCRT2ECLK(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)8091  SiS_SetCRT2ECLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
8092             unsigned short RefreshRateTableIndex)
8093  {
8094    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
8095    unsigned short clkbase, vclkindex = 0;
8096    unsigned char  sr2b, sr2c;
8097  
8098    if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
8099       SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
8100       if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK == 2) {
8101  	RefreshRateTableIndex--;
8102       }
8103       vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
8104                                      RefreshRateTableIndex);
8105       SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
8106    } else {
8107       vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
8108                                      RefreshRateTableIndex);
8109    }
8110  
8111    sr2b = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
8112    sr2c = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
8113  
8114    if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
8115       if(SiS_Pr->SiS_UseROM) {
8116  	if(ROMAddr[0x220] & 0x01) {
8117  	   sr2b = ROMAddr[0x227];
8118  	   sr2c = ROMAddr[0x228];
8119  	}
8120       }
8121    }
8122  
8123    clkbase = 0x02B;
8124    if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
8125       if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
8126  	clkbase += 3;
8127       }
8128    }
8129  
8130    SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x20);
8131    SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
8132    SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
8133    SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x10);
8134    SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
8135    SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
8136    SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x00);
8137    SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
8138    SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
8139  }
8140  
8141  /*********************************************/
8142  /*           SET UP CHRONTEL CHIPS           */
8143  /*********************************************/
8144  
8145  static void
SiS_SetCHTVReg(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefreshRateTableIndex)8146  SiS_SetCHTVReg(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
8147                 unsigned short RefreshRateTableIndex)
8148  {
8149     unsigned short TVType, resindex;
8150     const struct SiS_CHTVRegData *CHTVRegData = NULL;
8151  
8152     if(ModeNo <= 0x13)
8153        resindex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
8154     else
8155        resindex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
8156  
8157     resindex &= 0x3F;
8158  
8159     TVType = 0;
8160     if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
8161     if(SiS_Pr->SiS_TVMode & TVSetPAL) {
8162        TVType += 2;
8163        if(SiS_Pr->SiS_ModeType > ModeVGA) {
8164  	 if(SiS_Pr->SiS_CHSOverScan) TVType = 8;
8165        }
8166        if(SiS_Pr->SiS_TVMode & TVSetPALM) {
8167  	 TVType = 4;
8168  	 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
8169        } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
8170  	 TVType = 6;
8171  	 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
8172        }
8173     }
8174  
8175     switch(TVType) {
8176        case  0: CHTVRegData = SiS_Pr->SiS_CHTVReg_UNTSC; break;
8177        case  1: CHTVRegData = SiS_Pr->SiS_CHTVReg_ONTSC; break;
8178        case  2: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPAL;  break;
8179        case  3: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL;  break;
8180        case  4: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALM; break;
8181        case  5: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALM; break;
8182        case  6: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALN; break;
8183        case  7: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALN; break;
8184        case  8: CHTVRegData = SiS_Pr->SiS_CHTVReg_SOPAL; break;
8185        default: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL;  break;
8186     }
8187  
8188  
8189     if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
8190  
8191  #ifdef CONFIG_FB_SIS_300
8192  
8193        /* Chrontel 7005 - I assume that it does not come with a 315 series chip */
8194  
8195        /* We don't support modes >800x600 */
8196        if (resindex > 5) return;
8197  
8198        if(SiS_Pr->SiS_TVMode & TVSetPAL) {
8199  	 SiS_SetCH700x(SiS_Pr,0x04,0x43);  /* 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
8200  	 SiS_SetCH700x(SiS_Pr,0x09,0x69);  /* Black level for PAL (105)*/
8201        } else {
8202  	 SiS_SetCH700x(SiS_Pr,0x04,0x03);   /* upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
8203  	 SiS_SetCH700x(SiS_Pr,0x09,0x71);   /* Black level for NTSC (113)*/
8204        }
8205  
8206        SiS_SetCH700x(SiS_Pr,0x00,CHTVRegData[resindex].Reg[0]);	/* Mode register */
8207        SiS_SetCH700x(SiS_Pr,0x07,CHTVRegData[resindex].Reg[1]);	/* Start active video register */
8208        SiS_SetCH700x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[2]);	/* Position overflow register */
8209        SiS_SetCH700x(SiS_Pr,0x0a,CHTVRegData[resindex].Reg[3]);	/* Horiz Position register */
8210        SiS_SetCH700x(SiS_Pr,0x0b,CHTVRegData[resindex].Reg[4]);	/* Vertical Position register */
8211  
8212        /* Set minimum flicker filter for Luma channel (SR1-0=00),
8213                  minimum text enhancement (S3-2=10),
8214     	        maximum flicker filter for Chroma channel (S5-4=10)
8215  	        =00101000=0x28 (When reading, S1-0->S3-2, and S3-2->S1-0!)
8216         */
8217        SiS_SetCH700x(SiS_Pr,0x01,0x28);
8218  
8219        /* Set video bandwidth
8220              High bandwidth Luma composite video filter(S0=1)
8221              low bandwidth Luma S-video filter (S2-1=00)
8222  	    disable peak filter in S-video channel (S3=0)
8223  	    high bandwidth Chroma Filter (S5-4=11)
8224  	    =00110001=0x31
8225        */
8226        SiS_SetCH700x(SiS_Pr,0x03,0xb1);       /* old: 3103 */
8227  
8228        /* Register 0x3D does not exist in non-macrovision register map
8229              (Maybe this is a macrovision register?)
8230         */
8231  #ifndef SIS_CP
8232        SiS_SetCH70xx(SiS_Pr,0x3d,0x00);
8233  #endif
8234  
8235        /* Register 0x10 only contains 1 writable bit (S0) for sensing,
8236               all other bits a read-only. Macrovision?
8237         */
8238        SiS_SetCH70xxANDOR(SiS_Pr,0x10,0x00,0x1F);
8239  
8240        /* Register 0x11 only contains 3 writable bits (S0-S2) for
8241               contrast enhancement (set to 010 -> gain 1 Yout = 17/16*(Yin-30) )
8242         */
8243        SiS_SetCH70xxANDOR(SiS_Pr,0x11,0x02,0xF8);
8244  
8245        /* Clear DSEN
8246         */
8247        SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xEF);
8248  
8249        if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {		/* ---- NTSC ---- */
8250           if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) {
8251              if(resindex == 0x04) {   			/* 640x480 overscan: Mode 16 */
8252        	       SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);	/* loop filter off */
8253                 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);	/* ACIV on, no need to set FSCI */
8254              } else if(resindex == 0x05) {    		/* 800x600 overscan: Mode 23 */
8255                 SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0);	/* 0x18-0x1f: FSCI 469,762,048 */
8256                 SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x0C,0xF0);
8257                 SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x00,0xF0);
8258                 SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x00,0xF0);
8259                 SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xF0);
8260                 SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x00,0xF0);
8261                 SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x00,0xF0);
8262                 SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x00,0xF0);
8263                 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x01,0xEF);	/* Loop filter on for mode 23 */
8264                 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE);	/* ACIV off, need to set FSCI */
8265              }
8266           } else {
8267              if(resindex == 0x04) {     			/* ----- 640x480 underscan; Mode 17 */
8268                 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);	/* loop filter off */
8269                 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);
8270              } else if(resindex == 0x05) {   		/* ----- 800x600 underscan: Mode 24 */
8271  #if 0
8272                 SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0);	/* (FSCI was 0x1f1c71c7 - this is for mode 22) */
8273                 SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x09,0xF0);	/* FSCI for mode 24 is 428,554,851 */
8274                 SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x08,0xF0);       /* 198b3a63 */
8275                 SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x0b,0xF0);
8276                 SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x04,0xF0);
8277                 SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x01,0xF0);
8278                 SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x06,0xF0);
8279                 SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x05,0xF0);
8280                 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);	/* loop filter off for mode 24 */
8281                 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE);	* ACIV off, need to set FSCI */
8282  #endif         /* All alternatives wrong (datasheet wrong?), don't use FSCI */
8283  	       SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);	 /* loop filter off */
8284                 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);
8285              }
8286           }
8287        } else {						/* ---- PAL ---- */
8288  	/* We don't play around with FSCI in PAL mode */
8289  	SiS_SetCH70xxANDOR(SiS_Pr, 0x20, 0x00, 0xEF);	/* loop filter off */
8290  	SiS_SetCH70xxANDOR(SiS_Pr, 0x21, 0x01, 0xFE);	/* ACIV on */
8291        }
8292  
8293  #endif  /* 300 */
8294  
8295     } else {
8296  
8297        /* Chrontel 7019 - assumed that it does not come with a 300 series chip */
8298  
8299  #ifdef CONFIG_FB_SIS_315
8300  
8301        unsigned short temp;
8302  
8303        /* We don't support modes >1024x768 */
8304        if (resindex > 6) return;
8305  
8306        temp = CHTVRegData[resindex].Reg[0];
8307        if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp |= 0x10;
8308        SiS_SetCH701x(SiS_Pr,0x00,temp);
8309  
8310        SiS_SetCH701x(SiS_Pr,0x01,CHTVRegData[resindex].Reg[1]);
8311        SiS_SetCH701x(SiS_Pr,0x02,CHTVRegData[resindex].Reg[2]);
8312        SiS_SetCH701x(SiS_Pr,0x04,CHTVRegData[resindex].Reg[3]);
8313        SiS_SetCH701x(SiS_Pr,0x03,CHTVRegData[resindex].Reg[4]);
8314        SiS_SetCH701x(SiS_Pr,0x05,CHTVRegData[resindex].Reg[5]);
8315        SiS_SetCH701x(SiS_Pr,0x06,CHTVRegData[resindex].Reg[6]);
8316  
8317        temp = CHTVRegData[resindex].Reg[7];
8318        if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp = 0x66;
8319        SiS_SetCH701x(SiS_Pr,0x07,temp);
8320  
8321        SiS_SetCH701x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[8]);
8322        SiS_SetCH701x(SiS_Pr,0x15,CHTVRegData[resindex].Reg[9]);
8323        SiS_SetCH701x(SiS_Pr,0x1f,CHTVRegData[resindex].Reg[10]);
8324        SiS_SetCH701x(SiS_Pr,0x0c,CHTVRegData[resindex].Reg[11]);
8325        SiS_SetCH701x(SiS_Pr,0x0d,CHTVRegData[resindex].Reg[12]);
8326        SiS_SetCH701x(SiS_Pr,0x0e,CHTVRegData[resindex].Reg[13]);
8327        SiS_SetCH701x(SiS_Pr,0x0f,CHTVRegData[resindex].Reg[14]);
8328        SiS_SetCH701x(SiS_Pr,0x10,CHTVRegData[resindex].Reg[15]);
8329  
8330        temp = SiS_GetCH701x(SiS_Pr,0x21) & ~0x02;
8331        /* D1 should be set for PAL, PAL-N and NTSC-J,
8332           but I won't do that for PAL unless somebody
8333  	 tells me to do so. Since the BIOS uses
8334  	 non-default CIV values and blacklevels,
8335  	 this might be compensated anyway.
8336         */
8337        if(SiS_Pr->SiS_TVMode & (TVSetPALN | TVSetNTSCJ)) temp |= 0x02;
8338        SiS_SetCH701x(SiS_Pr,0x21,temp);
8339  
8340  #endif	/* 315 */
8341  
8342     }
8343  
8344  #ifdef SIS_CP
8345     SIS_CP_INIT301_CP3
8346  #endif
8347  
8348  }
8349  
8350  #ifdef CONFIG_FB_SIS_315  /* ----------- 315 series only ---------- */
8351  
8352  void
SiS_Chrontel701xBLOn(struct SiS_Private * SiS_Pr)8353  SiS_Chrontel701xBLOn(struct SiS_Private *SiS_Pr)
8354  {
8355     unsigned short temp;
8356  
8357     /* Enable Chrontel 7019 LCD panel backlight */
8358     if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8359        if(SiS_Pr->ChipType == SIS_740) {
8360  	 SiS_SetCH701x(SiS_Pr,0x66,0x65);
8361        } else {
8362  	 temp = SiS_GetCH701x(SiS_Pr,0x66);
8363  	 temp |= 0x20;
8364  	 SiS_SetCH701x(SiS_Pr,0x66,temp);
8365        }
8366     }
8367  }
8368  
8369  void
SiS_Chrontel701xBLOff(struct SiS_Private * SiS_Pr)8370  SiS_Chrontel701xBLOff(struct SiS_Private *SiS_Pr)
8371  {
8372     unsigned short temp;
8373  
8374     /* Disable Chrontel 7019 LCD panel backlight */
8375     if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8376        temp = SiS_GetCH701x(SiS_Pr,0x66);
8377        temp &= 0xDF;
8378        SiS_SetCH701x(SiS_Pr,0x66,temp);
8379     }
8380  }
8381  
8382  static void
SiS_ChrontelPowerSequencing(struct SiS_Private * SiS_Pr)8383  SiS_ChrontelPowerSequencing(struct SiS_Private *SiS_Pr)
8384  {
8385    static const unsigned char regtable[]      = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
8386    static const unsigned char table1024_740[] = { 0x01, 0x02, 0x01, 0x01, 0x01 };
8387    static const unsigned char table1400_740[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 };
8388    static const unsigned char asus1024_740[]  = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8389    static const unsigned char asus1400_740[]  = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8390    static const unsigned char table1024_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8391    static const unsigned char table1400_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8392    const unsigned char *tableptr = NULL;
8393    int i;
8394  
8395    /* Set up Power up/down timing */
8396  
8397    if(SiS_Pr->ChipType == SIS_740) {
8398       if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8399  	if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1024_740;
8400  	else    			          tableptr = table1024_740;
8401       } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8402  	       (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8403  	       (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8404  	if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1400_740;
8405          else					  tableptr = table1400_740;
8406       } else return;
8407    } else {
8408       if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8409  	tableptr = table1024_650;
8410       } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8411  	       (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8412  	       (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8413  	tableptr = table1400_650;
8414       } else return;
8415    }
8416  
8417    for(i=0; i<5; i++) {
8418       SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]);
8419    }
8420  }
8421  
8422  static void
SiS_SetCH701xForLCD(struct SiS_Private * SiS_Pr)8423  SiS_SetCH701xForLCD(struct SiS_Private *SiS_Pr)
8424  {
8425    const unsigned char *tableptr = NULL;
8426    unsigned short tempbh;
8427    int i;
8428    static const unsigned char regtable[] = {
8429  		0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
8430  		0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66
8431    };
8432    static const unsigned char table1024_740[] = {
8433  		0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8434  		0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44
8435    };
8436    static const unsigned char table1280_740[] = {
8437  		0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8438  		0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44
8439    };
8440    static const unsigned char table1400_740[] = {
8441  		0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8442  		0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44
8443    };
8444    static const unsigned char table1600_740[] = {
8445  		0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8446  		0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44
8447    };
8448    static const unsigned char table1024_650[] = {
8449  		0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8450  		0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02
8451    };
8452    static const unsigned char table1280_650[] = {
8453  		0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8454  		0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02
8455    };
8456    static const unsigned char table1400_650[] = {
8457  		0x60, 0x03, 0x11, 0x00, 0x40, 0xef,
8458  		0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02
8459    };
8460    static const unsigned char table1600_650[] = {
8461  		0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8462  		0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a
8463    };
8464  
8465    if(SiS_Pr->ChipType == SIS_740) {
8466       if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)       tableptr = table1024_740;
8467       else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_740;
8468       else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_740;
8469       else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_740;
8470       else return;
8471    } else {
8472       if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)       tableptr = table1024_650;
8473       else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_650;
8474       else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_650;
8475       else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_650;
8476       else return;
8477    }
8478  
8479    tempbh = SiS_GetCH701x(SiS_Pr,0x74);
8480    if((tempbh == 0xf6) || (tempbh == 0xc7)) {
8481       tempbh = SiS_GetCH701x(SiS_Pr,0x73);
8482       if(tempbh == 0xc8) {
8483          if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) return;
8484       } else if(tempbh == 0xdb) {
8485          if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) return;
8486  	if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) return;
8487       } else if(tempbh == 0xde) {
8488          if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) return;
8489       }
8490    }
8491  
8492    if(SiS_Pr->ChipType == SIS_740) tempbh = 0x0d;
8493    else     			  tempbh = 0x0c;
8494  
8495    for(i = 0; i < tempbh; i++) {
8496       SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]);
8497    }
8498    SiS_ChrontelPowerSequencing(SiS_Pr);
8499    tempbh = SiS_GetCH701x(SiS_Pr,0x1e);
8500    tempbh |= 0xc0;
8501    SiS_SetCH701x(SiS_Pr,0x1e,tempbh);
8502  
8503    if(SiS_Pr->ChipType == SIS_740) {
8504       tempbh = SiS_GetCH701x(SiS_Pr,0x1c);
8505       tempbh &= 0xfb;
8506       SiS_SetCH701x(SiS_Pr,0x1c,tempbh);
8507       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8508       tempbh = SiS_GetCH701x(SiS_Pr,0x64);
8509       tempbh |= 0x40;
8510       SiS_SetCH701x(SiS_Pr,0x64,tempbh);
8511       tempbh = SiS_GetCH701x(SiS_Pr,0x03);
8512       tempbh &= 0x3f;
8513       SiS_SetCH701x(SiS_Pr,0x03,tempbh);
8514    }
8515  }
8516  
8517  static void
SiS_ChrontelResetVSync(struct SiS_Private * SiS_Pr)8518  SiS_ChrontelResetVSync(struct SiS_Private *SiS_Pr)
8519  {
8520    unsigned char temp, temp1;
8521  
8522    temp1 = SiS_GetCH701x(SiS_Pr,0x49);
8523    SiS_SetCH701x(SiS_Pr,0x49,0x3e);
8524    temp = SiS_GetCH701x(SiS_Pr,0x47);
8525    temp &= 0x7f;	/* Use external VSYNC */
8526    SiS_SetCH701x(SiS_Pr,0x47,temp);
8527    SiS_LongDelay(SiS_Pr, 3);
8528    temp = SiS_GetCH701x(SiS_Pr,0x47);
8529    temp |= 0x80;	/* Use internal VSYNC */
8530    SiS_SetCH701x(SiS_Pr,0x47,temp);
8531    SiS_SetCH701x(SiS_Pr,0x49,temp1);
8532  }
8533  
8534  static void
SiS_Chrontel701xOn(struct SiS_Private * SiS_Pr)8535  SiS_Chrontel701xOn(struct SiS_Private *SiS_Pr)
8536  {
8537    unsigned short temp;
8538  
8539    if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8540       if(SiS_Pr->ChipType == SIS_740) {
8541          temp = SiS_GetCH701x(SiS_Pr,0x1c);
8542          temp |= 0x04;	/* Invert XCLK phase */
8543          SiS_SetCH701x(SiS_Pr,0x1c,temp);
8544       }
8545       if(SiS_IsYPbPr(SiS_Pr)) {
8546          temp = SiS_GetCH701x(SiS_Pr,0x01);
8547  	temp &= 0x3f;
8548  	temp |= 0x80;	/* Enable YPrPb (HDTV) */
8549  	SiS_SetCH701x(SiS_Pr,0x01,temp);
8550       }
8551       if(SiS_IsChScart(SiS_Pr)) {
8552          temp = SiS_GetCH701x(SiS_Pr,0x01);
8553  	temp &= 0x3f;
8554  	temp |= 0xc0;	/* Enable SCART + CVBS */
8555  	SiS_SetCH701x(SiS_Pr,0x01,temp);
8556       }
8557       if(SiS_Pr->ChipType == SIS_740) {
8558          SiS_ChrontelResetVSync(SiS_Pr);
8559          SiS_SetCH701x(SiS_Pr,0x49,0x20);   /* Enable TV path */
8560       } else {
8561          SiS_SetCH701x(SiS_Pr,0x49,0x20);   /* Enable TV path */
8562          temp = SiS_GetCH701x(SiS_Pr,0x49);
8563          if(SiS_IsYPbPr(SiS_Pr)) {
8564             temp = SiS_GetCH701x(SiS_Pr,0x73);
8565  	   temp |= 0x60;
8566  	   SiS_SetCH701x(SiS_Pr,0x73,temp);
8567          }
8568          temp = SiS_GetCH701x(SiS_Pr,0x47);
8569          temp &= 0x7f;
8570          SiS_SetCH701x(SiS_Pr,0x47,temp);
8571          SiS_LongDelay(SiS_Pr, 2);
8572          temp = SiS_GetCH701x(SiS_Pr,0x47);
8573          temp |= 0x80;
8574          SiS_SetCH701x(SiS_Pr,0x47,temp);
8575       }
8576    }
8577  }
8578  
8579  static void
SiS_Chrontel701xOff(struct SiS_Private * SiS_Pr)8580  SiS_Chrontel701xOff(struct SiS_Private *SiS_Pr)
8581  {
8582    unsigned short temp;
8583  
8584    /* Complete power down of LVDS */
8585    if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8586       if(SiS_Pr->ChipType == SIS_740) {
8587          SiS_LongDelay(SiS_Pr, 1);
8588  	SiS_GenericDelay(SiS_Pr, 5887);
8589  	SiS_SetCH701x(SiS_Pr,0x76,0xac);
8590  	SiS_SetCH701x(SiS_Pr,0x66,0x00);
8591       } else {
8592          SiS_LongDelay(SiS_Pr, 2);
8593  	temp = SiS_GetCH701x(SiS_Pr,0x76);
8594  	temp &= 0xfc;
8595  	SiS_SetCH701x(SiS_Pr,0x76,temp);
8596  	SiS_SetCH701x(SiS_Pr,0x66,0x00);
8597       }
8598    }
8599  }
8600  
8601  static void
SiS_ChrontelResetDB(struct SiS_Private * SiS_Pr)8602  SiS_ChrontelResetDB(struct SiS_Private *SiS_Pr)
8603  {
8604       unsigned short temp;
8605  
8606       if(SiS_Pr->ChipType == SIS_740) {
8607  
8608          temp = SiS_GetCH701x(SiS_Pr,0x4a);  /* Version ID */
8609          temp &= 0x01;
8610          if(!temp) {
8611  
8612             if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8613  	      temp = SiS_GetCH701x(SiS_Pr,0x49);
8614  	      SiS_SetCH701x(SiS_Pr,0x49,0x3e);
8615  	   }
8616  
8617  	   /* Reset Chrontel 7019 datapath */
8618             SiS_SetCH701x(SiS_Pr,0x48,0x10);
8619             SiS_LongDelay(SiS_Pr, 1);
8620             SiS_SetCH701x(SiS_Pr,0x48,0x18);
8621  
8622  	   if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8623  	      SiS_ChrontelResetVSync(SiS_Pr);
8624  	      SiS_SetCH701x(SiS_Pr,0x49,temp);
8625  	   }
8626  
8627          } else {
8628  
8629  	   /* Clear/set/clear GPIO */
8630             temp = SiS_GetCH701x(SiS_Pr,0x5c);
8631  	   temp &= 0xef;
8632  	   SiS_SetCH701x(SiS_Pr,0x5c,temp);
8633  	   temp = SiS_GetCH701x(SiS_Pr,0x5c);
8634  	   temp |= 0x10;
8635  	   SiS_SetCH701x(SiS_Pr,0x5c,temp);
8636  	   temp = SiS_GetCH701x(SiS_Pr,0x5c);
8637  	   temp &= 0xef;
8638  	   SiS_SetCH701x(SiS_Pr,0x5c,temp);
8639  	   temp = SiS_GetCH701x(SiS_Pr,0x61);
8640  	   if(!temp) {
8641  	      SiS_SetCH701xForLCD(SiS_Pr);
8642  	   }
8643          }
8644  
8645       } else { /* 650 */
8646          /* Reset Chrontel 7019 datapath */
8647          SiS_SetCH701x(SiS_Pr,0x48,0x10);
8648          SiS_LongDelay(SiS_Pr, 1);
8649          SiS_SetCH701x(SiS_Pr,0x48,0x18);
8650       }
8651  }
8652  
8653  static void
SiS_ChrontelInitTVVSync(struct SiS_Private * SiS_Pr)8654  SiS_ChrontelInitTVVSync(struct SiS_Private *SiS_Pr)
8655  {
8656       unsigned short temp;
8657  
8658       if(SiS_Pr->ChipType == SIS_740) {
8659  
8660          if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8661             SiS_ChrontelResetVSync(SiS_Pr);
8662          }
8663  
8664       } else {
8665  
8666          SiS_SetCH701x(SiS_Pr,0x76,0xaf);  /* Power up LVDS block */
8667          temp = SiS_GetCH701x(SiS_Pr,0x49);
8668          temp &= 1;
8669          if(temp != 1) {  /* TV block powered? (0 = yes, 1 = no) */
8670  	   temp = SiS_GetCH701x(SiS_Pr,0x47);
8671  	   temp &= 0x70;
8672  	   SiS_SetCH701x(SiS_Pr,0x47,temp);  /* enable VSYNC */
8673  	   SiS_LongDelay(SiS_Pr, 3);
8674  	   temp = SiS_GetCH701x(SiS_Pr,0x47);
8675  	   temp |= 0x80;
8676  	   SiS_SetCH701x(SiS_Pr,0x47,temp);  /* disable VSYNC */
8677          }
8678  
8679       }
8680  }
8681  
8682  static void
SiS_ChrontelDoSomething3(struct SiS_Private * SiS_Pr,unsigned short ModeNo)8683  SiS_ChrontelDoSomething3(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
8684  {
8685       unsigned short temp,temp1;
8686  
8687       if(SiS_Pr->ChipType == SIS_740) {
8688  
8689          temp = SiS_GetCH701x(SiS_Pr,0x61);
8690          if(temp < 1) {
8691             temp++;
8692  	   SiS_SetCH701x(SiS_Pr,0x61,temp);
8693          }
8694          SiS_SetCH701x(SiS_Pr,0x66,0x45);  /* Panel power on */
8695          SiS_SetCH701x(SiS_Pr,0x76,0xaf);  /* All power on */
8696          SiS_LongDelay(SiS_Pr, 1);
8697          SiS_GenericDelay(SiS_Pr, 5887);
8698  
8699       } else {  /* 650 */
8700  
8701          temp1 = 0;
8702          temp = SiS_GetCH701x(SiS_Pr,0x61);
8703          if(temp < 2) {
8704             temp++;
8705  	   SiS_SetCH701x(SiS_Pr,0x61,temp);
8706  	   temp1 = 1;
8707          }
8708          SiS_SetCH701x(SiS_Pr,0x76,0xac);
8709          temp = SiS_GetCH701x(SiS_Pr,0x66);
8710          temp |= 0x5f;
8711          SiS_SetCH701x(SiS_Pr,0x66,temp);
8712          if(ModeNo > 0x13) {
8713             if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8714  	      SiS_GenericDelay(SiS_Pr, 1023);
8715  	   } else {
8716  	      SiS_GenericDelay(SiS_Pr, 767);
8717  	   }
8718          } else {
8719             if(!temp1)
8720  	      SiS_GenericDelay(SiS_Pr, 767);
8721          }
8722          temp = SiS_GetCH701x(SiS_Pr,0x76);
8723          temp |= 0x03;
8724          SiS_SetCH701x(SiS_Pr,0x76,temp);
8725          temp = SiS_GetCH701x(SiS_Pr,0x66);
8726          temp &= 0x7f;
8727          SiS_SetCH701x(SiS_Pr,0x66,temp);
8728          SiS_LongDelay(SiS_Pr, 1);
8729  
8730       }
8731  }
8732  
8733  static void
SiS_ChrontelDoSomething2(struct SiS_Private * SiS_Pr)8734  SiS_ChrontelDoSomething2(struct SiS_Private *SiS_Pr)
8735  {
8736       unsigned short temp;
8737  
8738       SiS_LongDelay(SiS_Pr, 1);
8739  
8740       do {
8741         temp = SiS_GetCH701x(SiS_Pr,0x66);
8742         temp &= 0x04;  /* PLL stable? -> bail out */
8743         if(temp == 0x04) break;
8744  
8745         if(SiS_Pr->ChipType == SIS_740) {
8746            /* Power down LVDS output, PLL normal operation */
8747            SiS_SetCH701x(SiS_Pr,0x76,0xac);
8748         }
8749  
8750         SiS_SetCH701xForLCD(SiS_Pr);
8751  
8752         temp = SiS_GetCH701x(SiS_Pr,0x76);
8753         temp &= 0xfb;  /* Reset PLL */
8754         SiS_SetCH701x(SiS_Pr,0x76,temp);
8755         SiS_LongDelay(SiS_Pr, 2);
8756         temp = SiS_GetCH701x(SiS_Pr,0x76);
8757         temp |= 0x04;  /* PLL normal operation */
8758         SiS_SetCH701x(SiS_Pr,0x76,temp);
8759         if(SiS_Pr->ChipType == SIS_740) {
8760            SiS_SetCH701x(SiS_Pr,0x78,0xe0);	/* PLL loop filter */
8761         } else {
8762            SiS_SetCH701x(SiS_Pr,0x78,0x60);
8763         }
8764         SiS_LongDelay(SiS_Pr, 2);
8765      } while(0);
8766  
8767      SiS_SetCH701x(SiS_Pr,0x77,0x00);  /* MV? */
8768  }
8769  
8770  static void
SiS_ChrontelDoSomething1(struct SiS_Private * SiS_Pr)8771  SiS_ChrontelDoSomething1(struct SiS_Private *SiS_Pr)
8772  {
8773       unsigned short temp;
8774  
8775       temp = SiS_GetCH701x(SiS_Pr,0x03);
8776       temp |= 0x80;	/* Set datapath 1 to TV   */
8777       temp &= 0xbf;	/* Set datapath 2 to LVDS */
8778       SiS_SetCH701x(SiS_Pr,0x03,temp);
8779  
8780       if(SiS_Pr->ChipType == SIS_740) {
8781  
8782          temp = SiS_GetCH701x(SiS_Pr,0x1c);
8783          temp &= 0xfb;	/* Normal XCLK phase */
8784          SiS_SetCH701x(SiS_Pr,0x1c,temp);
8785  
8786          SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8787  
8788          temp = SiS_GetCH701x(SiS_Pr,0x64);
8789          temp |= 0x40;	/* ? Bit not defined */
8790          SiS_SetCH701x(SiS_Pr,0x64,temp);
8791  
8792          temp = SiS_GetCH701x(SiS_Pr,0x03);
8793          temp &= 0x3f;	/* D1 input to both LVDS and TV */
8794          SiS_SetCH701x(SiS_Pr,0x03,temp);
8795  
8796  	if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) {
8797  	   SiS_SetCH701x(SiS_Pr,0x63,0x40); /* LVDS off */
8798  	   SiS_LongDelay(SiS_Pr, 1);
8799  	   SiS_SetCH701x(SiS_Pr,0x63,0x00); /* LVDS on */
8800  	   SiS_ChrontelResetDB(SiS_Pr);
8801  	   SiS_ChrontelDoSomething2(SiS_Pr);
8802  	   SiS_ChrontelDoSomething3(SiS_Pr, 0);
8803  	} else {
8804             temp = SiS_GetCH701x(SiS_Pr,0x66);
8805             if(temp != 0x45) {
8806                SiS_ChrontelResetDB(SiS_Pr);
8807                SiS_ChrontelDoSomething2(SiS_Pr);
8808                SiS_ChrontelDoSomething3(SiS_Pr, 0);
8809             }
8810  	}
8811  
8812       } else { /* 650 */
8813  
8814          SiS_ChrontelResetDB(SiS_Pr);
8815          SiS_ChrontelDoSomething2(SiS_Pr);
8816          temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34);
8817          SiS_ChrontelDoSomething3(SiS_Pr,temp);
8818          SiS_SetCH701x(SiS_Pr,0x76,0xaf);  /* All power on, LVDS normal operation */
8819  
8820       }
8821  
8822  }
8823  #endif  /* 315 series  */
8824  
8825  /*********************************************/
8826  /*      MAIN: SET CRT2 REGISTER GROUP        */
8827  /*********************************************/
8828  
8829  bool
SiS_SetCRT2Group(struct SiS_Private * SiS_Pr,unsigned short ModeNo)8830  SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
8831  {
8832  #ifdef CONFIG_FB_SIS_300
8833     unsigned char  *ROMAddr  = SiS_Pr->VirtualRomBase;
8834  #endif
8835     unsigned short ModeIdIndex, RefreshRateTableIndex;
8836  
8837     SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
8838  
8839     if(!SiS_Pr->UseCustomMode) {
8840        SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex);
8841     } else {
8842        ModeIdIndex = 0;
8843     }
8844  
8845     /* Used for shifting CR33 */
8846     SiS_Pr->SiS_SelectCRT2Rate = 4;
8847  
8848     SiS_UnLockCRT2(SiS_Pr);
8849  
8850     RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex);
8851  
8852     SiS_SaveCRT2Info(SiS_Pr,ModeNo);
8853  
8854     if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8855        SiS_DisableBridge(SiS_Pr);
8856        if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->ChipType == SIS_730)) {
8857           SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,0x80);
8858        }
8859        SiS_SetCRT2ModeRegs(SiS_Pr, ModeNo, ModeIdIndex);
8860     }
8861  
8862     if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
8863        SiS_LockCRT2(SiS_Pr);
8864        SiS_DisplayOn(SiS_Pr);
8865        return true;
8866     }
8867  
8868     SiS_GetCRT2Data(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8869  
8870     /* Set up Panel Link for LVDS and LCDA */
8871     SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
8872     if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
8873         ((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ||
8874         ((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS30xBLV)) ) {
8875        SiS_GetLVDSDesData(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8876     }
8877  
8878     if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8879        SiS_SetGroup1(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8880     }
8881  
8882     if(SiS_Pr->SiS_VBType & VB_SISVB) {
8883  
8884        if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8885  
8886  	 SiS_SetGroup2(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8887  #ifdef CONFIG_FB_SIS_315
8888  	 SiS_SetGroup2_C_ELV(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8889  #endif
8890  	 SiS_SetGroup3(SiS_Pr, ModeNo, ModeIdIndex);
8891  	 SiS_SetGroup4(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8892  #ifdef CONFIG_FB_SIS_315
8893  	 SiS_SetGroup4_C_ELV(SiS_Pr, ModeNo, ModeIdIndex);
8894  #endif
8895  	 SiS_SetGroup5(SiS_Pr, ModeNo, ModeIdIndex);
8896  
8897  	 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex);
8898  
8899  	 /* For 301BDH (Panel link initialization): */
8900  	 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
8901  
8902  	    if(!((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10)))) {
8903  	       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
8904  		  SiS_ModCRT1CRTC(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8905  	       }
8906              }
8907  	    SiS_SetCRT2ECLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8908  	 }
8909        }
8910  
8911     } else {
8912  
8913        SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex);
8914  
8915        SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8916  
8917        SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8918  
8919        if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8920  	 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
8921  	    if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
8922  	       if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8923  #ifdef CONFIG_FB_SIS_315
8924  		  SiS_SetCH701xForLCD(SiS_Pr);
8925  #endif
8926  	       }
8927  	    }
8928  	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8929  	       SiS_SetCHTVReg(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8930  	    }
8931  	 }
8932        }
8933  
8934     }
8935  
8936  #ifdef CONFIG_FB_SIS_300
8937     if(SiS_Pr->ChipType < SIS_315H) {
8938        if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8939  	 if(SiS_Pr->SiS_UseOEM) {
8940  	    if((SiS_Pr->SiS_UseROM) && (SiS_Pr->SiS_UseOEM == -1)) {
8941  	       if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
8942  		  SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8943  	       }
8944  	    } else {
8945  	       SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8946  	    }
8947  	 }
8948  	 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
8949  	    if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
8950  	       (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
8951  	       SetOEMLCDData2(SiS_Pr, ModeNo, ModeIdIndex,RefreshRateTableIndex);
8952  	    }
8953  	    SiS_DisplayOn(SiS_Pr);
8954           }
8955        }
8956     }
8957  #endif
8958  
8959  #ifdef CONFIG_FB_SIS_315
8960     if(SiS_Pr->ChipType >= SIS_315H) {
8961        if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8962  	 if(SiS_Pr->ChipType < SIS_661) {
8963  	    SiS_FinalizeLCD(SiS_Pr, ModeNo, ModeIdIndex);
8964  	    SiS_OEM310Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8965  	 } else {
8966  	    SiS_OEM661Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8967  	 }
8968  	 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40);
8969        }
8970     }
8971  #endif
8972  
8973     if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8974        SiS_EnableBridge(SiS_Pr);
8975     }
8976  
8977     SiS_DisplayOn(SiS_Pr);
8978  
8979     if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
8980        if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8981  	 /* Disable LCD panel when using TV */
8982  	 SiS_SetRegSR11ANDOR(SiS_Pr,0xFF,0x0C);
8983        } else {
8984  	 /* Disable TV when using LCD */
8985  	 SiS_SetCH70xxANDOR(SiS_Pr,0x0e,0x01,0xf8);
8986        }
8987     }
8988  
8989     if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8990        SiS_LockCRT2(SiS_Pr);
8991     }
8992  
8993     return true;
8994  }
8995  
8996  
8997  /*********************************************/
8998  /*     ENABLE/DISABLE LCD BACKLIGHT (SIS)    */
8999  /*********************************************/
9000  
9001  void
SiS_SiS30xBLOn(struct SiS_Private * SiS_Pr)9002  SiS_SiS30xBLOn(struct SiS_Private *SiS_Pr)
9003  {
9004    /* Switch on LCD backlight on SiS30xLV */
9005    SiS_DDC2Delay(SiS_Pr,0xff00);
9006    if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
9007       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
9008       SiS_WaitVBRetrace(SiS_Pr);
9009    }
9010    if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x01)) {
9011       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
9012    }
9013  }
9014  
9015  void
SiS_SiS30xBLOff(struct SiS_Private * SiS_Pr)9016  SiS_SiS30xBLOff(struct SiS_Private *SiS_Pr)
9017  {
9018    /* Switch off LCD backlight on SiS30xLV */
9019    SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
9020    SiS_DDC2Delay(SiS_Pr,0xff00);
9021  }
9022  
9023  /*********************************************/
9024  /*          DDC RELATED FUNCTIONS            */
9025  /*********************************************/
9026  
9027  static void
SiS_SetupDDCN(struct SiS_Private * SiS_Pr)9028  SiS_SetupDDCN(struct SiS_Private *SiS_Pr)
9029  {
9030    SiS_Pr->SiS_DDC_NData = ~SiS_Pr->SiS_DDC_Data;
9031    SiS_Pr->SiS_DDC_NClk  = ~SiS_Pr->SiS_DDC_Clk;
9032    if((SiS_Pr->SiS_DDC_Index == 0x11) && (SiS_Pr->SiS_SensibleSR11)) {
9033       SiS_Pr->SiS_DDC_NData &= 0x0f;
9034       SiS_Pr->SiS_DDC_NClk  &= 0x0f;
9035    }
9036  }
9037  
9038  #ifdef CONFIG_FB_SIS_300
9039  static unsigned char *
SiS_SetTrumpBlockLoop(struct SiS_Private * SiS_Pr,unsigned char * dataptr)9040  SiS_SetTrumpBlockLoop(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
9041  {
9042    int i, j, num;
9043    unsigned short tempah,temp;
9044    unsigned char *mydataptr;
9045  
9046    for(i=0; i<20; i++) {				/* Do 20 attempts to write */
9047       mydataptr = dataptr;
9048       num = *mydataptr++;
9049       if(!num) return mydataptr;
9050       if(i) {
9051          SiS_SetStop(SiS_Pr);
9052  	SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 2);
9053       }
9054       if(SiS_SetStart(SiS_Pr)) continue;		/* Set start condition */
9055       tempah = SiS_Pr->SiS_DDC_DeviceAddr;
9056       temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write DAB (S0=0=write) */
9057       if(temp) continue;				/*    (ERROR: no ack) */
9058       tempah = *mydataptr++;
9059       temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write register number */
9060       if(temp) continue;				/*    (ERROR: no ack) */
9061       for(j=0; j<num; j++) {
9062          tempah = *mydataptr++;
9063          temp = SiS_WriteDDC2Data(SiS_Pr,tempah);/* Write DAB (S0=0=write) */
9064  	if(temp) break;
9065       }
9066       if(temp) continue;
9067       if(SiS_SetStop(SiS_Pr)) continue;
9068       return mydataptr;
9069    }
9070    return NULL;
9071  }
9072  
9073  static bool
SiS_SetTrumpionBlock(struct SiS_Private * SiS_Pr,unsigned char * dataptr)9074  SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
9075  {
9076    SiS_Pr->SiS_DDC_DeviceAddr = 0xF0;  		/* DAB (Device Address Byte) */
9077    SiS_Pr->SiS_DDC_Index = 0x11;			/* Bit 0 = SC;  Bit 1 = SD */
9078    SiS_Pr->SiS_DDC_Data  = 0x02;			/* Bitmask in IndexReg for Data */
9079    SiS_Pr->SiS_DDC_Clk   = 0x01;			/* Bitmask in IndexReg for Clk */
9080    SiS_SetupDDCN(SiS_Pr);
9081  
9082    SiS_SetSwitchDDC2(SiS_Pr);
9083  
9084    while(*dataptr) {
9085       dataptr = SiS_SetTrumpBlockLoop(SiS_Pr, dataptr);
9086       if(!dataptr) return false;
9087    }
9088    return true;
9089  }
9090  #endif
9091  
9092  /* The Chrontel 700x is connected to the 630/730 via
9093   * the 630/730's DDC/I2C port.
9094   *
9095   * On 630(S)T chipset, the index changed from 0x11 to
9096   * 0x0a, possibly for working around the DDC problems
9097   */
9098  
9099  static bool
SiS_SetChReg(struct SiS_Private * SiS_Pr,unsigned short reg,unsigned char val,unsigned short myor)9100  SiS_SetChReg(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val, unsigned short myor)
9101  {
9102    unsigned short temp, i;
9103  
9104    for(i=0; i<20; i++) {				/* Do 20 attempts to write */
9105       if(i) {
9106  	SiS_SetStop(SiS_Pr);
9107  	SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4);
9108       }
9109       if(SiS_SetStart(SiS_Pr)) continue;					/* Set start condition */
9110       temp = SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr);	/* Write DAB (S0=0=write) */
9111       if(temp) continue;							/*    (ERROR: no ack) */
9112       temp = SiS_WriteDDC2Data(SiS_Pr, (reg | myor));			/* Write RAB (700x: set bit 7, see datasheet) */
9113       if(temp) continue;							/*    (ERROR: no ack) */
9114       temp = SiS_WriteDDC2Data(SiS_Pr, val);				/* Write data */
9115       if(temp) continue;							/*    (ERROR: no ack) */
9116       if(SiS_SetStop(SiS_Pr)) continue;					/* Set stop condition */
9117       SiS_Pr->SiS_ChrontelInit = 1;
9118       return true;
9119    }
9120    return false;
9121  }
9122  
9123  /* Write to Chrontel 700x */
9124  void
SiS_SetCH700x(struct SiS_Private * SiS_Pr,unsigned short reg,unsigned char val)9125  SiS_SetCH700x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
9126  {
9127    SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;  		/* DAB (Device Address Byte) */
9128  
9129    SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9130  
9131    if(!(SiS_Pr->SiS_ChrontelInit)) {
9132       SiS_Pr->SiS_DDC_Index = 0x11;		/* Bit 0 = SC;  Bit 1 = SD */
9133       SiS_Pr->SiS_DDC_Data  = 0x02;		/* Bitmask in IndexReg for Data */
9134       SiS_Pr->SiS_DDC_Clk   = 0x01;		/* Bitmask in IndexReg for Clk */
9135       SiS_SetupDDCN(SiS_Pr);
9136    }
9137  
9138    if( (!(SiS_SetChReg(SiS_Pr, reg, val, 0x80))) &&
9139        (!(SiS_Pr->SiS_ChrontelInit)) ) {
9140       SiS_Pr->SiS_DDC_Index = 0x0a;
9141       SiS_Pr->SiS_DDC_Data  = 0x80;
9142       SiS_Pr->SiS_DDC_Clk   = 0x40;
9143       SiS_SetupDDCN(SiS_Pr);
9144  
9145       SiS_SetChReg(SiS_Pr, reg, val, 0x80);
9146    }
9147  }
9148  
9149  /* Write to Chrontel 701x */
9150  /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
9151  void
SiS_SetCH701x(struct SiS_Private * SiS_Pr,unsigned short reg,unsigned char val)9152  SiS_SetCH701x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
9153  {
9154    SiS_Pr->SiS_DDC_Index = 0x11;			/* Bit 0 = SC;  Bit 1 = SD */
9155    SiS_Pr->SiS_DDC_Data  = 0x08;			/* Bitmask in IndexReg for Data */
9156    SiS_Pr->SiS_DDC_Clk   = 0x04;			/* Bitmask in IndexReg for Clk */
9157    SiS_SetupDDCN(SiS_Pr);
9158    SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;		/* DAB (Device Address Byte) */
9159    SiS_SetChReg(SiS_Pr, reg, val, 0);
9160  }
9161  
9162  static
9163  void
SiS_SetCH70xx(struct SiS_Private * SiS_Pr,unsigned short reg,unsigned char val)9164  SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
9165  {
9166    if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
9167       SiS_SetCH700x(SiS_Pr, reg, val);
9168    else
9169       SiS_SetCH701x(SiS_Pr, reg, val);
9170  }
9171  
9172  static unsigned short
SiS_GetChReg(struct SiS_Private * SiS_Pr,unsigned short myor)9173  SiS_GetChReg(struct SiS_Private *SiS_Pr, unsigned short myor)
9174  {
9175    unsigned short tempah, temp, i;
9176  
9177    for(i=0; i<20; i++) {				/* Do 20 attempts to read */
9178       if(i) {
9179  	SiS_SetStop(SiS_Pr);
9180  	SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4);
9181       }
9182       if(SiS_SetStart(SiS_Pr)) continue;					/* Set start condition */
9183       temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr);	/* Write DAB (S0=0=write) */
9184       if(temp) continue;							/*        (ERROR: no ack) */
9185       temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_ReadAddr | myor);	/* Write RAB (700x: | 0x80) */
9186       if(temp) continue;							/*        (ERROR: no ack) */
9187       if (SiS_SetStart(SiS_Pr)) continue;				/* Re-start */
9188       temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr | 0x01);/* DAB (S0=1=read) */
9189       if(temp) continue;							/*        (ERROR: no ack) */
9190       tempah = SiS_ReadDDC2Data(SiS_Pr);					/* Read byte */
9191       if(SiS_SetStop(SiS_Pr)) continue;					/* Stop condition */
9192       SiS_Pr->SiS_ChrontelInit = 1;
9193       return tempah;
9194    }
9195    return 0xFFFF;
9196  }
9197  
9198  /* Read from Chrontel 700x */
9199  /* Parameter is [Register no (S7-S0)] */
9200  unsigned short
SiS_GetCH700x(struct SiS_Private * SiS_Pr,unsigned short tempbx)9201  SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short tempbx)
9202  {
9203    unsigned short result;
9204  
9205    SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;		/* DAB */
9206  
9207    SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9208  
9209    if(!(SiS_Pr->SiS_ChrontelInit)) {
9210       SiS_Pr->SiS_DDC_Index = 0x11;		/* Bit 0 = SC;  Bit 1 = SD */
9211       SiS_Pr->SiS_DDC_Data  = 0x02;		/* Bitmask in IndexReg for Data */
9212       SiS_Pr->SiS_DDC_Clk   = 0x01;		/* Bitmask in IndexReg for Clk */
9213       SiS_SetupDDCN(SiS_Pr);
9214    }
9215  
9216    SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9217  
9218    if( ((result = SiS_GetChReg(SiS_Pr,0x80)) == 0xFFFF) &&
9219        (!SiS_Pr->SiS_ChrontelInit) ) {
9220  
9221       SiS_Pr->SiS_DDC_Index = 0x0a;
9222       SiS_Pr->SiS_DDC_Data  = 0x80;
9223       SiS_Pr->SiS_DDC_Clk   = 0x40;
9224       SiS_SetupDDCN(SiS_Pr);
9225  
9226       result = SiS_GetChReg(SiS_Pr,0x80);
9227    }
9228    return result;
9229  }
9230  
9231  /* Read from Chrontel 701x */
9232  /* Parameter is [Register no (S7-S0)] */
9233  unsigned short
SiS_GetCH701x(struct SiS_Private * SiS_Pr,unsigned short tempbx)9234  SiS_GetCH701x(struct SiS_Private *SiS_Pr, unsigned short tempbx)
9235  {
9236    SiS_Pr->SiS_DDC_Index = 0x11;			/* Bit 0 = SC;  Bit 1 = SD */
9237    SiS_Pr->SiS_DDC_Data  = 0x08;			/* Bitmask in IndexReg for Data */
9238    SiS_Pr->SiS_DDC_Clk   = 0x04;			/* Bitmask in IndexReg for Clk */
9239    SiS_SetupDDCN(SiS_Pr);
9240    SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;		/* DAB */
9241  
9242    SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9243  
9244    return SiS_GetChReg(SiS_Pr,0);
9245  }
9246  
9247  /* Read from Chrontel 70xx */
9248  /* Parameter is [Register no (S7-S0)] */
9249  static
9250  unsigned short
SiS_GetCH70xx(struct SiS_Private * SiS_Pr,unsigned short tempbx)9251  SiS_GetCH70xx(struct SiS_Private *SiS_Pr, unsigned short tempbx)
9252  {
9253    if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
9254       return SiS_GetCH700x(SiS_Pr, tempbx);
9255    else
9256       return SiS_GetCH701x(SiS_Pr, tempbx);
9257  }
9258  
9259  void
SiS_SetCH70xxANDOR(struct SiS_Private * SiS_Pr,unsigned short reg,unsigned char myor,unsigned short myand)9260  SiS_SetCH70xxANDOR(struct SiS_Private *SiS_Pr, unsigned short reg,
9261  		unsigned char myor, unsigned short myand)
9262  {
9263    unsigned short tempbl;
9264  
9265    tempbl = (SiS_GetCH70xx(SiS_Pr, (reg & 0xFF)) & myand) | myor;
9266    SiS_SetCH70xx(SiS_Pr, reg, tempbl);
9267  }
9268  
9269  /* Our own DDC functions */
9270  static
9271  unsigned short
SiS_InitDDCRegs(struct SiS_Private * SiS_Pr,unsigned int VBFlags,int VGAEngine,unsigned short adaptnum,unsigned short DDCdatatype,bool checkcr32,unsigned int VBFlags2)9272  SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
9273                  unsigned short adaptnum, unsigned short DDCdatatype, bool checkcr32,
9274  		unsigned int VBFlags2)
9275  {
9276       unsigned char ddcdtype[] = { 0xa0, 0xa0, 0xa0, 0xa2, 0xa6 };
9277       unsigned char flag, cr32;
9278       unsigned short        temp = 0, myadaptnum = adaptnum;
9279  
9280       if(adaptnum != 0) {
9281  	if(!(VBFlags2 & VB2_SISTMDSBRIDGE)) return 0xFFFF;
9282  	if((VBFlags2 & VB2_30xBDH) && (adaptnum == 1)) return 0xFFFF;
9283       }
9284  
9285       /* adapternum for SiS bridges: 0 = CRT1, 1 = LCD, 2 = VGA2 */
9286  
9287       SiS_Pr->SiS_ChrontelInit = 0;   /* force re-detection! */
9288  
9289       SiS_Pr->SiS_DDC_SecAddr = 0;
9290       SiS_Pr->SiS_DDC_DeviceAddr = ddcdtype[DDCdatatype];
9291       SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_P3c4;
9292       SiS_Pr->SiS_DDC_Index = 0x11;
9293       flag = 0xff;
9294  
9295       cr32 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x32);
9296  
9297  #if 0
9298       if(VBFlags2 & VB2_SISBRIDGE) {
9299  	if(myadaptnum == 0) {
9300  	   if(!(cr32 & 0x20)) {
9301  	      myadaptnum = 2;
9302  	      if(!(cr32 & 0x10)) {
9303  	         myadaptnum = 1;
9304  		 if(!(cr32 & 0x08)) {
9305  		    myadaptnum = 0;
9306  		 }
9307  	      }
9308  	   }
9309          }
9310       }
9311  #endif
9312  
9313       if(VGAEngine == SIS_300_VGA) {		/* 300 series */
9314  
9315          if(myadaptnum != 0) {
9316  	   flag = 0;
9317  	   if(VBFlags2 & VB2_SISBRIDGE) {
9318  	      SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9319                SiS_Pr->SiS_DDC_Index = 0x0f;
9320  	   }
9321          }
9322  
9323  	if(!(VBFlags2 & VB2_301)) {
9324  	   if((cr32 & 0x80) && (checkcr32)) {
9325                if(myadaptnum >= 1) {
9326  	         if(!(cr32 & 0x08)) {
9327  		     myadaptnum = 1;
9328  		     if(!(cr32 & 0x10)) return 0xFFFF;
9329                   }
9330  	      }
9331  	   }
9332  	}
9333  
9334  	temp = 4 - (myadaptnum * 2);
9335  	if(flag) temp = 0;
9336  
9337       } else {						/* 315/330 series */
9338  
9339  	/* here we simplify: 0 = CRT1, 1 = CRT2 (VGA, LCD) */
9340  
9341  	if(VBFlags2 & VB2_SISBRIDGE) {
9342  	   if(myadaptnum == 2) {
9343  	      myadaptnum = 1;
9344  	   }
9345  	}
9346  
9347          if(myadaptnum == 1) {
9348  	   flag = 0;
9349  	   if(VBFlags2 & VB2_SISBRIDGE) {
9350  	      SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9351                SiS_Pr->SiS_DDC_Index = 0x0f;
9352  	   }
9353          }
9354  
9355          if((cr32 & 0x80) && (checkcr32)) {
9356             if(myadaptnum >= 1) {
9357  	      if(!(cr32 & 0x08)) {
9358  	         myadaptnum = 1;
9359  		 if(!(cr32 & 0x10)) return 0xFFFF;
9360  	      }
9361  	   }
9362          }
9363  
9364          temp = myadaptnum;
9365          if(myadaptnum == 1) {
9366             temp = 0;
9367  	   if(VBFlags2 & VB2_LVDS) flag = 0xff;
9368          }
9369  
9370  	if(flag) temp = 0;
9371      }
9372  
9373      SiS_Pr->SiS_DDC_Data = 0x02 << temp;
9374      SiS_Pr->SiS_DDC_Clk  = 0x01 << temp;
9375  
9376      SiS_SetupDDCN(SiS_Pr);
9377  
9378      return 0;
9379  }
9380  
9381  static unsigned short
SiS_WriteDABDDC(struct SiS_Private * SiS_Pr)9382  SiS_WriteDABDDC(struct SiS_Private *SiS_Pr)
9383  {
9384     if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9385     if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr)) {
9386        return 0xFFFF;
9387     }
9388     if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_SecAddr)) {
9389        return 0xFFFF;
9390     }
9391     return 0;
9392  }
9393  
9394  static unsigned short
SiS_PrepareReadDDC(struct SiS_Private * SiS_Pr)9395  SiS_PrepareReadDDC(struct SiS_Private *SiS_Pr)
9396  {
9397     if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9398     if(SiS_WriteDDC2Data(SiS_Pr, (SiS_Pr->SiS_DDC_DeviceAddr | 0x01))) {
9399        return 0xFFFF;
9400     }
9401     return 0;
9402  }
9403  
9404  static unsigned short
SiS_PrepareDDC(struct SiS_Private * SiS_Pr)9405  SiS_PrepareDDC(struct SiS_Private *SiS_Pr)
9406  {
9407     if(SiS_WriteDABDDC(SiS_Pr)) SiS_WriteDABDDC(SiS_Pr);
9408     if(SiS_PrepareReadDDC(SiS_Pr)) return (SiS_PrepareReadDDC(SiS_Pr));
9409     return 0;
9410  }
9411  
9412  static void
SiS_SendACK(struct SiS_Private * SiS_Pr,unsigned short yesno)9413  SiS_SendACK(struct SiS_Private *SiS_Pr, unsigned short yesno)
9414  {
9415     SiS_SetSCLKLow(SiS_Pr);
9416     if(yesno) {
9417        SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9418  		      SiS_Pr->SiS_DDC_Index,
9419  		      SiS_Pr->SiS_DDC_NData,
9420  		      SiS_Pr->SiS_DDC_Data);
9421     } else {
9422        SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9423  		      SiS_Pr->SiS_DDC_Index,
9424  		      SiS_Pr->SiS_DDC_NData,
9425  		      0);
9426     }
9427     SiS_SetSCLKHigh(SiS_Pr);
9428  }
9429  
9430  static unsigned short
SiS_DoProbeDDC(struct SiS_Private * SiS_Pr)9431  SiS_DoProbeDDC(struct SiS_Private *SiS_Pr)
9432  {
9433      unsigned char mask, value;
9434      unsigned short  temp, ret=0;
9435      bool failed = false;
9436  
9437      SiS_SetSwitchDDC2(SiS_Pr);
9438      if(SiS_PrepareDDC(SiS_Pr)) {
9439           SiS_SetStop(SiS_Pr);
9440           return 0xFFFF;
9441      }
9442      mask = 0xf0;
9443      value = 0x20;
9444      if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9445         temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9446         SiS_SendACK(SiS_Pr, 0);
9447         if(temp == 0) {
9448             mask = 0xff;
9449  	   value = 0xff;
9450         } else {
9451             failed = true;
9452  	   ret = 0xFFFF;
9453         }
9454      }
9455      if(!failed) {
9456         temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9457         SiS_SendACK(SiS_Pr, 1);
9458         temp &= mask;
9459         if(temp == value) ret = 0;
9460         else {
9461            ret = 0xFFFF;
9462            if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9463               if(temp == 0x30) ret = 0;
9464            }
9465         }
9466      }
9467      SiS_SetStop(SiS_Pr);
9468      return ret;
9469  }
9470  
9471  static
9472  unsigned short
SiS_ProbeDDC(struct SiS_Private * SiS_Pr)9473  SiS_ProbeDDC(struct SiS_Private *SiS_Pr)
9474  {
9475     unsigned short flag;
9476  
9477     flag = 0x180;
9478     SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
9479     if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x02;
9480     SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;
9481     if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x08;
9482     SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;
9483     if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x10;
9484     if(!(flag & 0x1a)) flag = 0;
9485     return flag;
9486  }
9487  
9488  static
9489  unsigned short
SiS_ReadDDC(struct SiS_Private * SiS_Pr,unsigned short DDCdatatype,unsigned char * buffer)9490  SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype, unsigned char *buffer)
9491  {
9492     unsigned short flag, length, i;
9493     unsigned char chksum,gotcha;
9494  
9495     if(DDCdatatype > 4) return 0xFFFF;
9496  
9497     flag = 0;
9498     SiS_SetSwitchDDC2(SiS_Pr);
9499     if(!(SiS_PrepareDDC(SiS_Pr))) {
9500        length = 127;
9501        if(DDCdatatype != 1) length = 255;
9502        chksum = 0;
9503        gotcha = 0;
9504        for(i=0; i<length; i++) {
9505  	 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9506  	 chksum += buffer[i];
9507  	 gotcha |= buffer[i];
9508  	 SiS_SendACK(SiS_Pr, 0);
9509        }
9510        buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9511        chksum += buffer[i];
9512        SiS_SendACK(SiS_Pr, 1);
9513        if(gotcha) flag = (unsigned short)chksum;
9514        else flag = 0xFFFF;
9515     } else {
9516        flag = 0xFFFF;
9517     }
9518     SiS_SetStop(SiS_Pr);
9519     return flag;
9520  }
9521  
9522  /* Our private DDC functions
9523  
9524     It complies somewhat with the corresponding VESA function
9525     in arguments and return values.
9526  
9527     Since this is probably called before the mode is changed,
9528     we use our pre-detected pSiS-values instead of SiS_Pr as
9529     regards chipset and video bridge type.
9530  
9531     Arguments:
9532         adaptnum: 0=CRT1(analog), 1=CRT2/LCD(digital), 2=CRT2/VGA2(analog)
9533                   CRT2 DDC is only supported on SiS301, 301B, 301C, 302B.
9534  		 LCDA is CRT1, but DDC is read from CRT2 port.
9535         DDCdatatype: 0=Probe, 1=EDID, 2=EDID+VDIF, 3=EDID V2 (P&D), 4=EDID V2 (FPDI-2)
9536         buffer: ptr to 256 data bytes which will be filled with read data.
9537  
9538     Returns 0xFFFF if error, otherwise
9539         if DDCdatatype > 0:  Returns 0 if reading OK (included a correct checksum)
9540         if DDCdatatype = 0:  Returns supported DDC modes
9541  
9542   */
9543  unsigned short
SiS_HandleDDC(struct SiS_Private * SiS_Pr,unsigned int VBFlags,int VGAEngine,unsigned short adaptnum,unsigned short DDCdatatype,unsigned char * buffer,unsigned int VBFlags2)9544  SiS_HandleDDC(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
9545                unsigned short adaptnum, unsigned short DDCdatatype, unsigned char *buffer,
9546  	      unsigned int VBFlags2)
9547  {
9548     unsigned char  sr1f, cr17=1;
9549     unsigned short result;
9550  
9551     if(adaptnum > 2)
9552        return 0xFFFF;
9553  
9554     if(DDCdatatype > 4)
9555        return 0xFFFF;
9556  
9557     if((!(VBFlags2 & VB2_VIDEOBRIDGE)) && (adaptnum > 0))
9558        return 0xFFFF;
9559  
9560     if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, false, VBFlags2) == 0xFFFF)
9561        return 0xFFFF;
9562  
9563     sr1f = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f);
9564     SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1f,0x3f,0x04);
9565     if(VGAEngine == SIS_300_VGA) {
9566        cr17 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80;
9567        if(!cr17) {
9568           SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x17,0x80);
9569           SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x01);
9570           SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x03);
9571        }
9572     }
9573     if((sr1f) || (!cr17)) {
9574        SiS_WaitRetrace1(SiS_Pr);
9575        SiS_WaitRetrace1(SiS_Pr);
9576        SiS_WaitRetrace1(SiS_Pr);
9577        SiS_WaitRetrace1(SiS_Pr);
9578     }
9579  
9580     if(DDCdatatype == 0) {
9581        result = SiS_ProbeDDC(SiS_Pr);
9582     } else {
9583        result = SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer);
9584        if((!result) && (DDCdatatype == 1)) {
9585           if((buffer[0] == 0x00) && (buffer[1] == 0xff) &&
9586  	    (buffer[2] == 0xff) && (buffer[3] == 0xff) &&
9587  	    (buffer[4] == 0xff) && (buffer[5] == 0xff) &&
9588  	    (buffer[6] == 0xff) && (buffer[7] == 0x00) &&
9589  	    (buffer[0x12] == 1)) {
9590  	    if(!SiS_Pr->DDCPortMixup) {
9591  	       if(adaptnum == 1) {
9592  	          if(!(buffer[0x14] & 0x80)) result = 0xFFFE;
9593  	       } else {
9594  	          if(buffer[0x14] & 0x80)    result = 0xFFFE;
9595  	       }
9596  	    }
9597  	 }
9598        }
9599     }
9600     SiS_SetReg(SiS_Pr->SiS_P3c4,0x1f,sr1f);
9601     if(VGAEngine == SIS_300_VGA) {
9602        SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x17,0x7f,cr17);
9603     }
9604     return result;
9605  }
9606  
9607  /* Generic I2C functions for Chrontel & DDC --------- */
9608  
9609  static void
SiS_SetSwitchDDC2(struct SiS_Private * SiS_Pr)9610  SiS_SetSwitchDDC2(struct SiS_Private *SiS_Pr)
9611  {
9612    SiS_SetSCLKHigh(SiS_Pr);
9613    SiS_WaitRetrace1(SiS_Pr);
9614  
9615    SiS_SetSCLKLow(SiS_Pr);
9616    SiS_WaitRetrace1(SiS_Pr);
9617  }
9618  
9619  unsigned short
SiS_ReadDDC1Bit(struct SiS_Private * SiS_Pr)9620  SiS_ReadDDC1Bit(struct SiS_Private *SiS_Pr)
9621  {
9622     SiS_WaitRetrace1(SiS_Pr);
9623     return ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x02) >> 1);
9624  }
9625  
9626  /* Set I2C start condition */
9627  /* This is done by a SD high-to-low transition while SC is high */
9628  static unsigned short
SiS_SetStart(struct SiS_Private * SiS_Pr)9629  SiS_SetStart(struct SiS_Private *SiS_Pr)
9630  {
9631    if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;			/* (SC->low)  */
9632    SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9633  		  SiS_Pr->SiS_DDC_Index,
9634  		  SiS_Pr->SiS_DDC_NData,
9635  		  SiS_Pr->SiS_DDC_Data);        		/* SD->high */
9636    if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			/* SC->high */
9637    SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9638  		  SiS_Pr->SiS_DDC_Index,
9639  		  SiS_Pr->SiS_DDC_NData,
9640  		  0x00);					/* SD->low = start condition */
9641    if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			/* (SC->low) */
9642    return 0;
9643  }
9644  
9645  /* Set I2C stop condition */
9646  /* This is done by a SD low-to-high transition while SC is high */
9647  static unsigned short
SiS_SetStop(struct SiS_Private * SiS_Pr)9648  SiS_SetStop(struct SiS_Private *SiS_Pr)
9649  {
9650    if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;			/* (SC->low) */
9651    SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9652  		  SiS_Pr->SiS_DDC_Index,
9653  		  SiS_Pr->SiS_DDC_NData,
9654  		  0x00);					/* SD->low   */
9655    if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			/* SC->high  */
9656    SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9657  		  SiS_Pr->SiS_DDC_Index,
9658  		  SiS_Pr->SiS_DDC_NData,
9659  		  SiS_Pr->SiS_DDC_Data);			/* SD->high = stop condition */
9660    if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			/* (SC->high) */
9661    return 0;
9662  }
9663  
9664  /* Write 8 bits of data */
9665  static unsigned short
SiS_WriteDDC2Data(struct SiS_Private * SiS_Pr,unsigned short tempax)9666  SiS_WriteDDC2Data(struct SiS_Private *SiS_Pr, unsigned short tempax)
9667  {
9668    unsigned short i,flag,temp;
9669  
9670    flag = 0x80;
9671    for(i = 0; i < 8; i++) {
9672      SiS_SetSCLKLow(SiS_Pr);					/* SC->low */
9673      if(tempax & flag) {
9674        SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9675  		      SiS_Pr->SiS_DDC_Index,
9676  		      SiS_Pr->SiS_DDC_NData,
9677  		      SiS_Pr->SiS_DDC_Data);			/* Write bit (1) to SD */
9678      } else {
9679        SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9680  		      SiS_Pr->SiS_DDC_Index,
9681  		      SiS_Pr->SiS_DDC_NData,
9682  		      0x00);					/* Write bit (0) to SD */
9683      }
9684      SiS_SetSCLKHigh(SiS_Pr);					/* SC->high */
9685      flag >>= 1;
9686    }
9687    temp = SiS_CheckACK(SiS_Pr);					/* Check acknowledge */
9688    return temp;
9689  }
9690  
9691  static unsigned short
SiS_ReadDDC2Data(struct SiS_Private * SiS_Pr)9692  SiS_ReadDDC2Data(struct SiS_Private *SiS_Pr)
9693  {
9694    unsigned short i, temp, getdata;
9695  
9696    getdata = 0;
9697    for(i = 0; i < 8; i++) {
9698      getdata <<= 1;
9699      SiS_SetSCLKLow(SiS_Pr);
9700      SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9701  		    SiS_Pr->SiS_DDC_Index,
9702  		    SiS_Pr->SiS_DDC_NData,
9703  		    SiS_Pr->SiS_DDC_Data);
9704      SiS_SetSCLKHigh(SiS_Pr);
9705      temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
9706      if(temp & SiS_Pr->SiS_DDC_Data) getdata |= 0x01;
9707    }
9708    return getdata;
9709  }
9710  
9711  static unsigned short
SiS_SetSCLKLow(struct SiS_Private * SiS_Pr)9712  SiS_SetSCLKLow(struct SiS_Private *SiS_Pr)
9713  {
9714    SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9715  		  SiS_Pr->SiS_DDC_Index,
9716  		  SiS_Pr->SiS_DDC_NClk,
9717  		  0x00);					/* SetSCLKLow()  */
9718    SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9719    return 0;
9720  }
9721  
9722  static unsigned short
SiS_SetSCLKHigh(struct SiS_Private * SiS_Pr)9723  SiS_SetSCLKHigh(struct SiS_Private *SiS_Pr)
9724  {
9725    unsigned short temp, watchdog=1000;
9726  
9727    SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9728  		  SiS_Pr->SiS_DDC_Index,
9729  		  SiS_Pr->SiS_DDC_NClk,
9730  		  SiS_Pr->SiS_DDC_Clk);  			/* SetSCLKHigh()  */
9731    do {
9732      temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
9733    } while((!(temp & SiS_Pr->SiS_DDC_Clk)) && --watchdog);
9734    if (!watchdog) {
9735    	return 0xFFFF;
9736    }
9737    SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9738    return 0;
9739  }
9740  
9741  /* Check I2C acknowledge */
9742  /* Returns 0 if ack ok, non-0 if ack not ok */
9743  static unsigned short
SiS_CheckACK(struct SiS_Private * SiS_Pr)9744  SiS_CheckACK(struct SiS_Private *SiS_Pr)
9745  {
9746    unsigned short tempah;
9747  
9748    SiS_SetSCLKLow(SiS_Pr);				           /* (SC->low) */
9749    SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9750  		  SiS_Pr->SiS_DDC_Index,
9751  		  SiS_Pr->SiS_DDC_NData,
9752  		  SiS_Pr->SiS_DDC_Data);			   /* (SD->high) */
9753    SiS_SetSCLKHigh(SiS_Pr);				           /* SC->high = clock impulse for ack */
9754    tempah = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); /* Read SD */
9755    SiS_SetSCLKLow(SiS_Pr);				           /* SC->low = end of clock impulse */
9756    if(tempah & SiS_Pr->SiS_DDC_Data) return 1;			   /* Ack OK if bit = 0 */
9757    return 0;
9758  }
9759  
9760  /* End of I2C functions ----------------------- */
9761  
9762  
9763  /* =============== SiS 315/330 O.E.M. ================= */
9764  
9765  #ifdef CONFIG_FB_SIS_315
9766  
9767  static unsigned short
GetRAMDACromptr(struct SiS_Private * SiS_Pr)9768  GetRAMDACromptr(struct SiS_Private *SiS_Pr)
9769  {
9770    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
9771    unsigned short romptr;
9772  
9773    if(SiS_Pr->ChipType < SIS_330) {
9774       romptr = SISGETROMW(0x128);
9775       if(SiS_Pr->SiS_VBType & VB_SIS30xB)
9776          romptr = SISGETROMW(0x12a);
9777    } else {
9778       romptr = SISGETROMW(0x1a8);
9779       if(SiS_Pr->SiS_VBType & VB_SIS30xB)
9780          romptr = SISGETROMW(0x1aa);
9781    }
9782    return romptr;
9783  }
9784  
9785  static unsigned short
GetLCDromptr(struct SiS_Private * SiS_Pr)9786  GetLCDromptr(struct SiS_Private *SiS_Pr)
9787  {
9788    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
9789    unsigned short romptr;
9790  
9791    if(SiS_Pr->ChipType < SIS_330) {
9792       romptr = SISGETROMW(0x120);
9793       if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9794          romptr = SISGETROMW(0x122);
9795    } else {
9796       romptr = SISGETROMW(0x1a0);
9797       if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9798          romptr = SISGETROMW(0x1a2);
9799    }
9800    return romptr;
9801  }
9802  
9803  static unsigned short
GetTVromptr(struct SiS_Private * SiS_Pr)9804  GetTVromptr(struct SiS_Private *SiS_Pr)
9805  {
9806    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
9807    unsigned short romptr;
9808  
9809    if(SiS_Pr->ChipType < SIS_330) {
9810       romptr = SISGETROMW(0x114);
9811       if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9812          romptr = SISGETROMW(0x11a);
9813    } else {
9814       romptr = SISGETROMW(0x194);
9815       if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9816          romptr = SISGETROMW(0x19a);
9817    }
9818    return romptr;
9819  }
9820  
9821  static unsigned short
GetLCDPtrIndexBIOS(struct SiS_Private * SiS_Pr)9822  GetLCDPtrIndexBIOS(struct SiS_Private *SiS_Pr)
9823  {
9824    unsigned short index;
9825  
9826    if((IS_SIS650) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
9827       if(!(SiS_IsNotM650orLater(SiS_Pr))) {
9828          if((index = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0)) {
9829  	   index >>= 4;
9830  	   index *= 3;
9831  	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9832             else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9833             return index;
9834  	}
9835       }
9836    }
9837  
9838    index = SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F;
9839    if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)      index -= 5;
9840    if(SiS_Pr->SiS_VBType & VB_SIS301C) {  /* 1.15.20 and later (not VB specific) */
9841       if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 5;
9842       if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768) index -= 5;
9843    } else {
9844       if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 6;
9845    }
9846    index--;
9847    index *= 3;
9848    if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9849    else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9850    return index;
9851  }
9852  
9853  static unsigned short
GetLCDPtrIndex(struct SiS_Private * SiS_Pr)9854  GetLCDPtrIndex(struct SiS_Private *SiS_Pr)
9855  {
9856    unsigned short index;
9857  
9858    index = ((SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F) - 1) * 3;
9859    if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)         index += 2;
9860    else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9861    return index;
9862  }
9863  
9864  static unsigned short
GetTVPtrIndex(struct SiS_Private * SiS_Pr)9865  GetTVPtrIndex(struct SiS_Private *SiS_Pr)
9866  {
9867    unsigned short index;
9868  
9869    index = 0;
9870    if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
9871    if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index = 2;
9872  
9873    if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) index = 0;
9874  
9875    index <<= 1;
9876  
9877    if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) &&
9878       (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
9879       index++;
9880    }
9881  
9882    return index;
9883  }
9884  
9885  static unsigned int
GetOEMTVPtr661_2_GEN(struct SiS_Private * SiS_Pr,int addme)9886  GetOEMTVPtr661_2_GEN(struct SiS_Private *SiS_Pr, int addme)
9887  {
9888     unsigned short index = 0, temp = 0;
9889  
9890     if(SiS_Pr->SiS_TVMode & TVSetPAL)   index = 1;
9891     if(SiS_Pr->SiS_TVMode & TVSetPALM)  index = 2;
9892     if(SiS_Pr->SiS_TVMode & TVSetPALN)  index = 3;
9893     if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 6;
9894     if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
9895        index = 4;
9896        if(SiS_Pr->SiS_TVMode & TVSetPALM)  index++;
9897        if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 7;
9898     }
9899  
9900     if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
9901        if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
9902           (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
9903  	 index += addme;
9904  	 temp++;
9905        }
9906        temp += 0x0100;
9907     }
9908     return (unsigned int)(index | (temp << 16));
9909  }
9910  
9911  static unsigned int
GetOEMTVPtr661_2_OLD(struct SiS_Private * SiS_Pr)9912  GetOEMTVPtr661_2_OLD(struct SiS_Private *SiS_Pr)
9913  {
9914     return (GetOEMTVPtr661_2_GEN(SiS_Pr, 8));
9915  }
9916  
9917  #if 0
9918  static unsigned int
9919  GetOEMTVPtr661_2_NEW(struct SiS_Private *SiS_Pr)
9920  {
9921     return (GetOEMTVPtr661_2_GEN(SiS_Pr, 6));
9922  }
9923  #endif
9924  
9925  static int
GetOEMTVPtr661(struct SiS_Private * SiS_Pr)9926  GetOEMTVPtr661(struct SiS_Private *SiS_Pr)
9927  {
9928     int index = 0;
9929  
9930     if(SiS_Pr->SiS_TVMode & TVSetPAL)          index = 2;
9931     if(SiS_Pr->SiS_ROMNew) {
9932        if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 4;
9933        if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 6;
9934        if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 8;
9935        if(SiS_Pr->SiS_TVMode & TVSetHiVision)  index = 10;
9936     } else {
9937        if(SiS_Pr->SiS_TVMode & TVSetHiVision)  index = 4;
9938        if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 6;
9939        if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 8;
9940        if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 10;
9941     }
9942  
9943     if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) index++;
9944  
9945     return index;
9946  }
9947  
9948  static void
SetDelayComp(struct SiS_Private * SiS_Pr,unsigned short ModeNo)9949  SetDelayComp(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
9950  {
9951    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
9952    unsigned short delay=0,index,myindex,temp,romptr=0;
9953    bool dochiptest = true;
9954  
9955    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
9956       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x20,0xbf);
9957    } else {
9958       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x35,0x7f);
9959    }
9960  
9961    /* Find delay (from ROM, internal tables, PCI subsystem) */
9962  
9963    if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {			/* ------------ VGA */
9964  
9965       if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
9966          romptr = GetRAMDACromptr(SiS_Pr);
9967       }
9968       if(romptr) delay = ROMAddr[romptr];
9969       else {
9970          delay = 0x04;
9971          if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
9972  	   if(IS_SIS650) {
9973  	      delay = 0x0a;
9974  	   } else if(IS_SIS740) {
9975  	      delay = 0x00;
9976  	   } else {
9977  	      delay = 0x0c;
9978  	   }
9979  	} else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
9980             delay = 0x00;
9981  	}
9982       }
9983  
9984    } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD|SetCRT2ToLCDA)) {  /* ----------	LCD/LCDA */
9985  
9986       bool gotitfrompci = false;
9987  
9988       /* Could we detect a PDC for LCD or did we get a user-defined? If yes, use it */
9989  
9990       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
9991  	if(SiS_Pr->PDC != -1) {
9992             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((SiS_Pr->PDC >> 1) & 0x0f));
9993  	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((SiS_Pr->PDC & 0x01) << 7));
9994  	   return;
9995  	}
9996       } else {
9997  	if(SiS_Pr->PDCA != -1) {
9998  	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((SiS_Pr->PDCA << 3) & 0xf0));
9999  	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((SiS_Pr->PDCA & 0x01) << 6));
10000  	   return;
10001  	}
10002       }
10003  
10004       /* Custom Panel? */
10005  
10006       if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) {
10007          if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10008  	   delay = 0x00;
10009  	   if((SiS_Pr->PanelXRes <= 1280) && (SiS_Pr->PanelYRes <= 1024)) {
10010  	      delay = 0x20;
10011  	   }
10012  	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,delay);
10013  	} else {
10014  	   delay = 0x0c;
10015  	   if(SiS_Pr->SiS_VBType & VB_SIS301C) {
10016  	      delay = 0x03;
10017  	      if((SiS_Pr->PanelXRes > 1280) && (SiS_Pr->PanelYRes > 1024)) {
10018  	         delay = 0x00;
10019  	      }
10020  	   } else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10021  	      if(IS_SIS740) delay = 0x01;
10022  	      else          delay = 0x03;
10023  	   }
10024  	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,delay);
10025  	}
10026          return;
10027       }
10028  
10029       /* This is a piece of typical SiS crap: They code the OEM LCD
10030        * delay into the code, at no defined place in the BIOS.
10031        * We now have to start doing a PCI subsystem check here.
10032        */
10033  
10034       switch(SiS_Pr->SiS_CustomT) {
10035       case CUT_COMPAQ1280:
10036       case CUT_COMPAQ12802:
10037  	if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
10038  	   gotitfrompci = true;
10039  	   dochiptest = false;
10040  	   delay = 0x03;
10041  	}
10042  	break;
10043       case CUT_CLEVO1400:
10044       case CUT_CLEVO14002:
10045  	gotitfrompci = true;
10046  	dochiptest = false;
10047  	delay = 0x02;
10048  	break;
10049       case CUT_CLEVO1024:
10050       case CUT_CLEVO10242:
10051          if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10052  	   gotitfrompci = true;
10053  	   dochiptest = false;
10054  	   delay = 0x33;
10055  	   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
10056  	   delay &= 0x0f;
10057  	}
10058  	break;
10059       }
10060  
10061       /* Could we find it through the PCI ID? If no, use ROM or table */
10062  
10063       if(!gotitfrompci) {
10064  
10065          index = GetLCDPtrIndexBIOS(SiS_Pr);
10066          myindex = GetLCDPtrIndex(SiS_Pr);
10067  
10068          if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
10069  
10070             if(SiS_IsNotM650orLater(SiS_Pr)) {
10071  
10072                if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10073  	         /* Always use the second pointer on 650; some BIOSes */
10074                   /* still carry old 301 data at the first location    */
10075  	         /* romptr = SISGETROMW(0x120);                       */
10076  	         /* if(SiS_Pr->SiS_VBType & VB_SIS302LV)              */
10077  	         romptr = SISGETROMW(0x122);
10078  	         if(!romptr) return;
10079  	         delay = ROMAddr[(romptr + index)];
10080  	      } else {
10081                   delay = SiS310_LCDDelayCompensation_650301LV[myindex];
10082  	      }
10083  
10084            } else {
10085  
10086               delay = SiS310_LCDDelayCompensation_651301LV[myindex];
10087  	     if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV))
10088  	        delay = SiS310_LCDDelayCompensation_651302LV[myindex];
10089  
10090            }
10091  
10092          } else if(SiS_Pr->SiS_UseROM 			      &&
10093  		  (!(SiS_Pr->SiS_ROMNew))		      &&
10094  	          (SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) &&
10095  		  (SiS_Pr->SiS_LCDResInfo != Panel_1280x768)  &&
10096  		  (SiS_Pr->SiS_LCDResInfo != Panel_1280x960)  &&
10097  		  (SiS_Pr->SiS_LCDResInfo != Panel_1600x1200)  &&
10098  		  ((romptr = GetLCDromptr(SiS_Pr)))) {
10099  
10100  	   /* Data for 1280x1024 wrong in 301B BIOS */
10101  	   /* Data for 1600x1200 wrong in 301C BIOS */
10102  	   delay = ROMAddr[(romptr + index)];
10103  
10104          } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
10105  
10106  	   if(IS_SIS740) delay = 0x03;
10107  	   else          delay = 0x00;
10108  
10109  	} else {
10110  
10111             delay = SiS310_LCDDelayCompensation_301[myindex];
10112  	   if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10113  	      if(IS_SIS740) delay = 0x01;
10114  	      else if(SiS_Pr->ChipType <= SIS_315PRO) delay = SiS310_LCDDelayCompensation_3xx301LV[myindex];
10115  	      else          delay = SiS310_LCDDelayCompensation_650301LV[myindex];
10116  	   } else if(SiS_Pr->SiS_VBType & VB_SIS301C) {
10117  	      if(IS_SIS740) delay = 0x01;  /* ? */
10118  	      else          delay = 0x03;
10119  	      if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) delay = 0x00; /* experience */
10120  	   } else if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
10121  	      if(IS_SIS740) delay = 0x01;
10122  	      else          delay = SiS310_LCDDelayCompensation_3xx301B[myindex];
10123  	   }
10124  
10125          }
10126  
10127       }  /* got it from PCI */
10128  
10129       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10130  	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,((delay << 4) & 0xf0));
10131  	dochiptest = false;
10132       }
10133  
10134    } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {			/* ------------ TV */
10135  
10136       index = GetTVPtrIndex(SiS_Pr);
10137  
10138       if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
10139  
10140          if(SiS_IsNotM650orLater(SiS_Pr)) {
10141  
10142             if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10143  	      /* Always use the second pointer on 650; some BIOSes */
10144                /* still carry old 301 data at the first location    */
10145                /* romptr = SISGETROMW(0x114);			   */
10146  	      /* if(SiS_Pr->SiS_VBType & VB_SIS302LV)              */
10147  	      romptr = SISGETROMW(0x11a);
10148  	      if(!romptr) return;
10149  	      delay = ROMAddr[romptr + index];
10150  
10151  	   } else {
10152  
10153  	      delay = SiS310_TVDelayCompensation_301B[index];
10154  
10155  	   }
10156  
10157          } else {
10158  
10159             switch(SiS_Pr->SiS_CustomT) {
10160  	   case CUT_COMPAQ1280:
10161  	   case CUT_COMPAQ12802:
10162  	   case CUT_CLEVO1400:
10163  	   case CUT_CLEVO14002:
10164  	      delay = 0x02;
10165  	      dochiptest = false;
10166  	      break;
10167  	   case CUT_CLEVO1024:
10168  	   case CUT_CLEVO10242:
10169  	      delay = 0x03;
10170  	      dochiptest = false;
10171     	      break;
10172  	   default:
10173                delay = SiS310_TVDelayCompensation_651301LV[index];
10174  	      if(SiS_Pr->SiS_VBType & VB_SIS302LV) {
10175  	         delay = SiS310_TVDelayCompensation_651302LV[index];
10176  	      }
10177  	   }
10178          }
10179  
10180       } else if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10181  
10182          romptr = GetTVromptr(SiS_Pr);
10183  	if(!romptr) return;
10184  	delay = ROMAddr[romptr + index];
10185  
10186       } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
10187  
10188          delay = SiS310_TVDelayCompensation_LVDS[index];
10189  
10190       } else {
10191  
10192  	delay = SiS310_TVDelayCompensation_301[index];
10193          if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10194  	   if(IS_SIS740) {
10195  	      delay = SiS310_TVDelayCompensation_740301B[index];
10196  	      /* LV: use 301 data? BIOS bug? */
10197  	   } else {
10198                delay = SiS310_TVDelayCompensation_301B[index];
10199  	      if(SiS_Pr->SiS_VBType & VB_SIS301C) delay = 0x02;
10200  	   }
10201  	}
10202  
10203       }
10204  
10205       if(SiS_LCDAEnabled(SiS_Pr)) {
10206  	delay &= 0x0f;
10207  	dochiptest = false;
10208       }
10209  
10210    } else return;
10211  
10212    /* Write delay */
10213  
10214    if(SiS_Pr->SiS_VBType & VB_SISVB) {
10215  
10216       if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS) && dochiptest) {
10217  
10218          temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0) >> 4;
10219          if(temp == 8) {		/* 1400x1050 BIOS (COMPAL) */
10220  	   delay &= 0x0f;
10221  	   delay |= 0xb0;
10222          } else if(temp == 6) {
10223             delay &= 0x0f;
10224  	   delay |= 0xc0;
10225          } else if(temp > 7) {	/* 1280x1024 BIOS (which one?) */
10226  	   delay = 0x35;
10227          }
10228          SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
10229  
10230       } else {
10231  
10232          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
10233  
10234       }
10235  
10236    } else {  /* LVDS */
10237  
10238       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10239          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
10240       } else {
10241          if(IS_SIS650 && (SiS_Pr->SiS_IF_DEF_CH70xx != 0)) {
10242             delay <<= 4;
10243             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,delay);
10244          } else {
10245             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
10246          }
10247       }
10248  
10249    }
10250  
10251  }
10252  
10253  static void
SetAntiFlicker(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)10254  SetAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10255  {
10256    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
10257    unsigned short index,temp,temp1,romptr=0;
10258  
10259    if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p|TVSetYPbPr525p)) return;
10260  
10261    if(ModeNo<=0x13)
10262       index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex;
10263    else
10264       index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex;
10265  
10266    temp = GetTVPtrIndex(SiS_Pr);
10267    temp >>= 1;  	  /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10268    temp1 = temp;
10269  
10270    if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
10271       if(SiS_Pr->ChipType >= SIS_661) {
10272          temp1 = GetOEMTVPtr661(SiS_Pr);
10273          temp1 >>= 1;
10274          romptr = SISGETROMW(0x260);
10275          if(SiS_Pr->ChipType >= SIS_760) {
10276  	   romptr = SISGETROMW(0x360);
10277  	}
10278       } else if(SiS_Pr->ChipType >= SIS_330) {
10279          romptr = SISGETROMW(0x192);
10280       } else {
10281          romptr = SISGETROMW(0x112);
10282       }
10283    }
10284  
10285    if(romptr) {
10286       temp1 <<= 1;
10287       temp = ROMAddr[romptr + temp1 + index];
10288    } else {
10289       temp = SiS310_TVAntiFlick1[temp][index];
10290    }
10291    temp <<= 4;
10292  
10293    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8f,temp);  /* index 0A D[6:4] */
10294  }
10295  
10296  static void
SetEdgeEnhance(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)10297  SetEdgeEnhance(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10298  {
10299    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
10300    unsigned short index,temp,temp1,romptr=0;
10301  
10302    temp = temp1 = GetTVPtrIndex(SiS_Pr) >> 1; 	/* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10303  
10304    if(ModeNo <= 0x13)
10305       index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;
10306    else
10307       index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;
10308  
10309    if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
10310       if(SiS_Pr->ChipType >= SIS_661) {
10311          romptr = SISGETROMW(0x26c);
10312          if(SiS_Pr->ChipType >= SIS_760) {
10313  	   romptr = SISGETROMW(0x36c);
10314  	}
10315  	temp1 = GetOEMTVPtr661(SiS_Pr);
10316          temp1 >>= 1;
10317       } else if(SiS_Pr->ChipType >= SIS_330) {
10318          romptr = SISGETROMW(0x1a4);
10319       } else {
10320          romptr = SISGETROMW(0x124);
10321       }
10322    }
10323  
10324    if(romptr) {
10325       temp1 <<= 1;
10326       temp = ROMAddr[romptr + temp1 + index];
10327    } else {
10328       temp = SiS310_TVEdge1[temp][index];
10329    }
10330    temp <<= 5;
10331    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x3A,0x1F,temp);  /* index 0A D[7:5] */
10332  }
10333  
10334  static void
SetYFilter(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)10335  SetYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10336  {
10337    unsigned short index, temp, i, j;
10338  
10339    if(ModeNo <= 0x13) {
10340       index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
10341    } else {
10342       index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
10343    }
10344  
10345    temp = GetTVPtrIndex(SiS_Pr) >> 1;  /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10346  
10347    if(SiS_Pr->SiS_TVMode & TVSetNTSCJ)	     temp = 1;  /* NTSC-J uses PAL */
10348    else if(SiS_Pr->SiS_TVMode & TVSetPALM)    temp = 3;  /* PAL-M */
10349    else if(SiS_Pr->SiS_TVMode & TVSetPALN)    temp = 4;  /* PAL-N */
10350    if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp = 1;  /* HiVision uses PAL */
10351  
10352    if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10353       for(i=0x35, j=0; i<=0x38; i++, j++) {
10354          SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
10355       }
10356       for(i=0x48; i<=0x4A; i++, j++) {
10357          SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
10358       }
10359    } else {
10360       for(i=0x35, j=0; i<=0x38; i++, j++) {
10361          SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter1[temp][index][j]);
10362       }
10363    }
10364  }
10365  
10366  static void
SetPhaseIncr(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)10367  SetPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10368  {
10369    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
10370    unsigned short index,temp,i,j,resinfo,romptr=0;
10371    unsigned int  lindex;
10372  
10373    if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
10374  
10375    /* NTSC-J data not in BIOS, and already set in SetGroup2 */
10376    if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) return;
10377  
10378    if((SiS_Pr->ChipType >= SIS_661) || SiS_Pr->SiS_ROMNew) {
10379       lindex = GetOEMTVPtr661_2_OLD(SiS_Pr) & 0xffff;
10380       lindex <<= 2;
10381       for(j=0, i=0x31; i<=0x34; i++, j++) {
10382          SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[lindex + j]);
10383       }
10384       return;
10385    }
10386  
10387    /* PAL-M, PAL-N not in BIOS, and already set in SetGroup2 */
10388    if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) return;
10389  
10390    if(ModeNo<=0x13) {
10391       resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
10392    } else {
10393       resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
10394    }
10395  
10396    temp = GetTVPtrIndex(SiS_Pr);
10397    /* 0: NTSC Graphics, 1: NTSC Text,    2: PAL Graphics,
10398     * 3: PAL Text,      4: HiTV Graphics 5: HiTV Text
10399     */
10400    if(SiS_Pr->SiS_UseROM) {
10401       romptr = SISGETROMW(0x116);
10402       if(SiS_Pr->ChipType >= SIS_330) {
10403          romptr = SISGETROMW(0x196);
10404       }
10405       if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10406          romptr = SISGETROMW(0x11c);
10407  	if(SiS_Pr->ChipType >= SIS_330) {
10408  	   romptr = SISGETROMW(0x19c);
10409  	}
10410  	if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode))) {
10411  	   romptr = SISGETROMW(0x116);
10412  	   if(SiS_Pr->ChipType >= SIS_330) {
10413                romptr = SISGETROMW(0x196);
10414             }
10415  	}
10416       }
10417    }
10418    if(romptr) {
10419       romptr += (temp << 2);
10420       for(j=0, i=0x31; i<=0x34; i++, j++) {
10421          SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
10422       }
10423    } else {
10424       index = temp % 2;
10425       temp >>= 1;          /* 0:NTSC, 1:PAL, 2:HiTV */
10426       for(j=0, i=0x31; i<=0x34; i++, j++) {
10427          if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV))
10428  	   SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
10429          else if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || (SiS_Pr->SiS_TVMode & TVSetTVSimuMode))
10430             SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr2[temp][index][j]);
10431          else
10432             SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
10433       }
10434    }
10435  
10436    if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision))) {
10437       if((!(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetYPbPr525p | TVSetYPbPr750p))) && (ModeNo > 0x13)) {
10438          if((resinfo == SIS_RI_640x480) ||
10439  	   (resinfo == SIS_RI_800x600)) {
10440  	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x21);
10441  	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0xf0);
10442  	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xf5);
10443  	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7f);
10444  	} else if(resinfo == SIS_RI_1024x768) {
10445  	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x1e);
10446  	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0x8b);
10447  	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xfb);
10448  	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7b);
10449  	}
10450       }
10451    }
10452  }
10453  
10454  static void
SetDelayComp661(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RTI)10455  SetDelayComp661(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
10456                  unsigned short ModeIdIndex, unsigned short RTI)
10457  {
10458     unsigned short delay = 0, romptr = 0, index, lcdpdcindex;
10459     unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
10460  
10461     if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToRAMDAC)))
10462        return;
10463  
10464     /* 1. New ROM: VGA2 and LCD/LCDA-Pass1:1 */
10465     /* (If a custom mode is used, Pass1:1 is always set; hence we do this:) */
10466  
10467     if(SiS_Pr->SiS_ROMNew) {
10468        if((SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) 			||
10469           ((SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
10470  	  (SiS_Pr->SiS_LCDInfo & LCDPass11))) {
10471           index = 25;
10472           if(SiS_Pr->UseCustomMode) {
10473  	    index = SiS_Pr->CSRClock;
10474           } else if(ModeNo > 0x13) {
10475              index = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RTI);
10476              index = SiS_Pr->SiS_VCLKData[index].CLOCK;
10477           }
10478  	 if(index < 25) index = 25;
10479           index = ((index / 25) - 1) << 1;
10480           if((ROMAddr[0x5b] & 0x80) || (SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD))) {
10481  	    index++;
10482  	 }
10483  	 romptr = SISGETROMW(0x104);
10484           delay = ROMAddr[romptr + index];
10485           if(SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD)) {
10486              SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
10487              SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
10488           } else {
10489              SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
10490  	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
10491           }
10492           return;
10493        }
10494     }
10495  
10496     /* 2. Old ROM: VGA2 and LCD/LCDA-Pass 1:1 */
10497  
10498     if(SiS_Pr->UseCustomMode) delay = 0x04;
10499     else if(ModeNo <= 0x13)   delay = 0x04;
10500     else                      delay = (SiS_Pr->SiS_RefIndex[RTI].Ext_PDC >> 4);
10501     delay |= (delay << 8);
10502  
10503     if(SiS_Pr->ChipType >= XGI_20) {
10504  
10505        delay = 0x0606;
10506        if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10507  
10508  	 delay = 0x0404;
10509           if(SiS_Pr->SiS_XGIROM) {
10510  	     index = GetTVPtrIndex(SiS_Pr);
10511  	     if((romptr = SISGETROMW(0x35e))) {
10512  	        delay = (ROMAddr[romptr + index] & 0x0f) << 1;
10513  		delay |= (delay << 8);
10514  	     }
10515  	 }
10516  
10517  	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
10518  	    if(SiS_Pr->ChipType == XGI_40 && SiS_Pr->ChipRevision == 0x02) {
10519  	       delay -= 0x0404;
10520  	    }
10521  	 }
10522        }
10523  
10524     } else if(SiS_Pr->ChipType >= SIS_340) {
10525  
10526        delay = 0x0606;
10527        if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10528           delay = 0x0404;
10529        }
10530        /* TODO (eventually) */
10531  
10532     } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10533  
10534        /* 3. TV */
10535  
10536        index = GetOEMTVPtr661(SiS_Pr);
10537        if(SiS_Pr->SiS_ROMNew) {
10538           romptr = SISGETROMW(0x106);
10539  	 if(SiS_Pr->SiS_VBType & VB_UMC) romptr += 12;
10540           delay = ROMAddr[romptr + index];
10541        } else {
10542           delay = 0x04;
10543  	 if(index > 3) delay = 0;
10544        }
10545  
10546     } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10547  
10548        /* 4. LCD, LCDA (for new ROM only LV and non-Pass 1:1) */
10549  
10550        if( (SiS_Pr->SiS_LCDResInfo != Panel_Custom) &&
10551            ((romptr = GetLCDStructPtr661_2(SiS_Pr))) ) {
10552  
10553  	 lcdpdcindex = (SiS_Pr->SiS_VBType & VB_UMC) ? 14 : 12;
10554  
10555  	 /* For LVDS (and sometimes TMDS), the BIOS must know about the correct value */
10556  	 delay = ROMAddr[romptr + lcdpdcindex + 1];	/* LCD  */
10557  	 delay |= (ROMAddr[romptr + lcdpdcindex] << 8);	/* LCDA */
10558  
10559        } else {
10560  
10561           /* TMDS: Set our own, since BIOS has no idea */
10562  	 /* (This is done on >=661 only, since <661 is calling this only for LVDS) */
10563           if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
10564  	    switch(SiS_Pr->SiS_LCDResInfo) {
10565  	    case Panel_1024x768:  delay = 0x0008; break;
10566  	    case Panel_1280x720:  delay = 0x0004; break;
10567  	    case Panel_1280x768:
10568  	    case Panel_1280x768_2:delay = 0x0004; break;
10569  	    case Panel_1280x800:
10570  	    case Panel_1280x800_2:delay = 0x0004; break; /* Verified for 1280x800 */
10571  	    case Panel_1280x854:  delay = 0x0004; break; /* FIXME */
10572  	    case Panel_1280x1024: delay = 0x1e04; break;
10573  	    case Panel_1400x1050: delay = 0x0004; break;
10574  	    case Panel_1600x1200: delay = 0x0400; break;
10575  	    case Panel_1680x1050: delay = 0x0e04; break;
10576  	    default:
10577                 if((SiS_Pr->PanelXRes <= 1024) && (SiS_Pr->PanelYRes <= 768)) {
10578  	          delay = 0x0008;
10579  	       } else if((SiS_Pr->PanelXRes == 1280) && (SiS_Pr->PanelYRes == 1024)) {
10580  	          delay = 0x1e04;
10581                 } else if((SiS_Pr->PanelXRes <= 1400) && (SiS_Pr->PanelYRes <= 1050)) {
10582  	          delay = 0x0004;
10583  	       } else if((SiS_Pr->PanelXRes <= 1600) && (SiS_Pr->PanelYRes <= 1200)) {
10584  	          delay = 0x0400;
10585                 } else
10586  	          delay = 0x0e04;
10587  	       break;
10588  	    }
10589           }
10590  
10591  	 /* Override by detected or user-set values */
10592  	 /* (but only if, for some reason, we can't read value from BIOS) */
10593           if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->PDC != -1)) {
10594              delay = SiS_Pr->PDC & 0x1f;
10595           }
10596           if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) && (SiS_Pr->PDCA != -1)) {
10597              delay = (SiS_Pr->PDCA & 0x1f) << 8;
10598           }
10599  
10600        }
10601  
10602     }
10603  
10604     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10605        delay >>= 8;
10606        SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
10607        SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
10608     } else {
10609        SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
10610        SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
10611     }
10612  }
10613  
10614  static void
SetCRT2SyncDither661(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short RTI)10615  SetCRT2SyncDither661(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RTI)
10616  {
10617     unsigned short infoflag;
10618     unsigned char  temp;
10619  
10620     if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10621  
10622        if(ModeNo <= 0x13) {
10623           infoflag = SiS_GetRegByte(SiS_Pr->SiS_P3ca+2);
10624        } else if(SiS_Pr->UseCustomMode) {
10625           infoflag = SiS_Pr->CInfoFlag;
10626        } else {
10627           infoflag = SiS_Pr->SiS_RefIndex[RTI].Ext_InfoFlag;
10628        }
10629  
10630        if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
10631           infoflag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37); /* No longer check D5 */
10632        }
10633  
10634        infoflag &= 0xc0;
10635  
10636        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
10637           temp = (infoflag >> 6) | 0x0c;
10638           if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
10639  	    temp ^= 0x04;
10640  	    if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x10;
10641  	 }
10642           SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xe0,temp);
10643        } else {
10644           temp = 0x30;
10645           if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) temp = 0x20;
10646           temp |= infoflag;
10647           SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0f,temp);
10648           temp = 0;
10649           if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
10650  	    if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x80;
10651  	 }
10652           SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0x7f,temp);
10653        }
10654  
10655     }
10656  }
10657  
10658  static void
SetPanelParms661(struct SiS_Private * SiS_Pr)10659  SetPanelParms661(struct SiS_Private *SiS_Pr)
10660  {
10661     unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
10662     unsigned short romptr, temp1, temp2;
10663  
10664     if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_SIS30xC)) {
10665        SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x24,0x0f);
10666     }
10667  
10668     if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10669        if(SiS_Pr->LVDSHL != -1) {
10670           SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
10671        }
10672     }
10673  
10674     if(SiS_Pr->SiS_ROMNew) {
10675  
10676        if((romptr = GetLCDStructPtr661_2(SiS_Pr))) {
10677           if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10678              temp1 = (ROMAddr[romptr] & 0x03) | 0x0c;
10679  	    temp2 = 0xfc;
10680  	    if(SiS_Pr->LVDSHL != -1) {
10681  	      temp1 &= 0xfc;
10682  	      temp2 = 0xf3;
10683  	    }
10684  	    SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,temp2,temp1);
10685           }
10686  	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
10687              temp1 = (ROMAddr[romptr + 1] & 0x80) >> 1;
10688              SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0d,0xbf,temp1);
10689  	 }
10690        }
10691  
10692     }
10693  }
10694  
10695  static void
SiS_OEM310Setting(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RRTI)10696  SiS_OEM310Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RRTI)
10697  {
10698     if((SiS_Pr->SiS_ROMNew) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
10699        SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
10700        if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10701           SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI);
10702           SetPanelParms661(SiS_Pr);
10703        }
10704     } else {
10705        SetDelayComp(SiS_Pr,ModeNo);
10706     }
10707  
10708     if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
10709        SetAntiFlicker(SiS_Pr,ModeNo,ModeIdIndex);
10710        SetPhaseIncr(SiS_Pr,ModeNo,ModeIdIndex);
10711        SetYFilter(SiS_Pr,ModeNo,ModeIdIndex);
10712        if(SiS_Pr->SiS_VBType & VB_SIS301) {
10713           SetEdgeEnhance(SiS_Pr,ModeNo,ModeIdIndex);
10714        }
10715     }
10716  }
10717  
10718  static void
SiS_OEM661Setting(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RRTI)10719  SiS_OEM661Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
10720  			unsigned short ModeIdIndex, unsigned short RRTI)
10721  {
10722     if(SiS_Pr->SiS_VBType & VB_SISVB) {
10723  
10724        SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
10725  
10726        if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10727           SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI);
10728           SetPanelParms661(SiS_Pr);
10729        }
10730  
10731        if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10732           SetPhaseIncr(SiS_Pr, ModeNo, ModeIdIndex);
10733           SetYFilter(SiS_Pr, ModeNo, ModeIdIndex);
10734           SetAntiFlicker(SiS_Pr, ModeNo, ModeIdIndex);
10735           if(SiS_Pr->SiS_VBType & VB_SIS301) {
10736              SetEdgeEnhance(SiS_Pr, ModeNo, ModeIdIndex);
10737           }
10738        }
10739     }
10740  }
10741  
10742  /* FinalizeLCD
10743   * This finalizes some CRT2 registers for the very panel used.
10744   * If we have a backup if these registers, we use it; otherwise
10745   * we set the register according to most BIOSes. However, this
10746   * function looks quite different in every BIOS, so you better
10747   * pray that we have a backup...
10748   */
10749  static void
SiS_FinalizeLCD(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)10750  SiS_FinalizeLCD(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10751  {
10752    unsigned short tempcl,tempch,tempbl,tempbh,tempbx,tempax,temp;
10753    unsigned short resinfo,modeflag;
10754  
10755    if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) return;
10756    if(SiS_Pr->SiS_ROMNew) return;
10757  
10758    if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10759       if(SiS_Pr->LVDSHL != -1) {
10760          SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
10761       }
10762    }
10763  
10764    if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
10765    if(SiS_Pr->UseCustomMode) return;
10766  
10767    switch(SiS_Pr->SiS_CustomT) {
10768    case CUT_COMPAQ1280:
10769    case CUT_COMPAQ12802:
10770    case CUT_CLEVO1400:
10771    case CUT_CLEVO14002:
10772       return;
10773    }
10774  
10775    if(ModeNo <= 0x13) {
10776       resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
10777       modeflag =  SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
10778    } else {
10779       resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
10780       modeflag =  SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
10781    }
10782  
10783    if(IS_SIS650) {
10784       if(!(SiS_GetReg(SiS_Pr->SiS_P3d4, 0x5f) & 0xf0)) {
10785          if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
10786  	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x02);
10787  	} else {
10788             SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
10789  	}
10790       }
10791    }
10792  
10793    if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
10794       if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10795          /* Maybe all panels? */
10796          if(SiS_Pr->LVDSHL == -1) {
10797             SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10798  	}
10799  	return;
10800       }
10801    }
10802  
10803    if(SiS_Pr->SiS_CustomT == CUT_CLEVO10242) {
10804       if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10805          if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10806  	   if(SiS_Pr->LVDSHL == -1) {
10807  	      /* Maybe all panels? */
10808                SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10809  	   }
10810  	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10811  	      tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
10812  	      if(tempch == 3) {
10813  	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10814  	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
10815  	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
10816  	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
10817  	      }
10818  	   }
10819  	   return;
10820  	}
10821       }
10822    }
10823  
10824    if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10825       if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10826  	if(SiS_Pr->SiS_VBType & VB_SISEMI) {
10827  	   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
10828  #ifdef SET_EMI
10829  	   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
10830  #endif
10831  	   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
10832  	}
10833       } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
10834          if(SiS_Pr->LVDSHL == -1) {
10835             /* Maybe ACER only? */
10836             SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10837  	}
10838       }
10839       tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
10840       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10841  	if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
10842  	   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1f,0x76);
10843  	} else if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10844  	   if(tempch == 0x03) {
10845  	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10846  	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
10847  	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
10848  	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
10849  	   }
10850  	   if(SiS_Pr->Backup && (SiS_Pr->Backup_Mode == ModeNo)) {
10851  	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,SiS_Pr->Backup_14);
10852  	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,SiS_Pr->Backup_15);
10853  	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,SiS_Pr->Backup_16);
10854  	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,SiS_Pr->Backup_17);
10855  	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,SiS_Pr->Backup_18);
10856  	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,SiS_Pr->Backup_19);
10857  	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,SiS_Pr->Backup_1a);
10858  	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,SiS_Pr->Backup_1b);
10859  	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,SiS_Pr->Backup_1c);
10860  	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,SiS_Pr->Backup_1d);
10861  	   } else if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {	/* 1.10.8w */
10862  	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x90);
10863  	      if(ModeNo <= 0x13) {
10864  	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x11);
10865  		 if((resinfo == 0) || (resinfo == 2)) return;
10866  		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x18);
10867  		 if((resinfo == 1) || (resinfo == 3)) return;
10868  	      }
10869  	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10870  	      if((ModeNo > 0x13) && (resinfo == SIS_RI_1024x768)) {
10871  	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);  /* 1.10.7u */
10872  #if 0
10873  	         tempbx = 806;  /* 0x326 */			 /* other older BIOSes */
10874  		 tempbx--;
10875  		 temp = tempbx & 0xff;
10876  		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);
10877  		 temp = (tempbx >> 8) & 0x03;
10878  		 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1d,0xf8,temp);
10879  #endif
10880  	      }
10881  	   } else if(ModeNo <= 0x13) {
10882  	      if(ModeNo <= 1) {
10883  		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x70);
10884  		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xff);
10885  		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
10886  		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
10887  	      }
10888  	      if(!(modeflag & HalfDCLK)) {
10889  		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x20);
10890  		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,0x1a);
10891  		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,0x28);
10892  		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,0x00);
10893  		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x4c);
10894  		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
10895  		 if(ModeNo == 0x12) {
10896  		    switch(tempch) {
10897  		       case 0:
10898  			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
10899  			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
10900  			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,0x10);
10901  			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
10902  			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x48);
10903  			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
10904  			  break;
10905  		       case 2:
10906  			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
10907  			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
10908  			  break;
10909  		       case 3:
10910  			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
10911  			  break;
10912  		    }
10913  		 }
10914  	      }
10915  	   }
10916  	}
10917       } else {
10918          tempcl = tempbh = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
10919  	tempcl &= 0x0f;
10920  	tempbh &= 0x70;
10921  	tempbh >>= 4;
10922  	tempbl = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x04);
10923  	tempbx = (tempbh << 8) | tempbl;
10924  	if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10925  	   if((resinfo == SIS_RI_1024x768) || (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD))) {
10926  	      if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
10927  	      	 tempbx = 770;
10928  	      } else {
10929  	         if(tempbx > 770) tempbx = 770;
10930  		 if(SiS_Pr->SiS_VGAVDE < 600) {
10931  		    tempax = 768 - SiS_Pr->SiS_VGAVDE;
10932  		    tempax >>= 4;  				 /* 1.10.7w; 1.10.6s: 3;  */
10933  		    if(SiS_Pr->SiS_VGAVDE <= 480)  tempax >>= 4; /* 1.10.7w; 1.10.6s: < 480; >>=1; */
10934  		    tempbx -= tempax;
10935  		 }
10936  	      }
10937  	   } else return;
10938  	}
10939  	temp = tempbx & 0xff;
10940  	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,temp);
10941  	temp = ((tempbx & 0xff00) >> 4) | tempcl;
10942  	SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,temp);
10943       }
10944    }
10945  }
10946  
10947  #endif
10948  
10949  /*  =================  SiS 300 O.E.M. ================== */
10950  
10951  #ifdef CONFIG_FB_SIS_300
10952  
10953  static void
SetOEMLCDData2(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefTabIndex)10954  SetOEMLCDData2(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,
10955  		unsigned short RefTabIndex)
10956  {
10957    unsigned short crt2crtc=0, modeflag, myindex=0;
10958    unsigned char  temp;
10959    int i;
10960  
10961    if(ModeNo <= 0x13) {
10962       modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
10963       crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
10964    } else {
10965       modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
10966       crt2crtc = SiS_Pr->SiS_RefIndex[RefTabIndex].Ext_CRT2CRTC;
10967    }
10968  
10969    crt2crtc &= 0x3f;
10970  
10971    if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
10972       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xdf);
10973    }
10974  
10975    if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
10976       if(modeflag & HalfDCLK) myindex = 1;
10977  
10978       if(SiS_Pr->SiS_SetFlag & LowModeTests) {
10979          for(i=0; i<7; i++) {
10980             if(barco_p1[myindex][crt2crtc][i][0]) {
10981  	      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,
10982  	                      barco_p1[myindex][crt2crtc][i][0],
10983  	   	   	      barco_p1[myindex][crt2crtc][i][2],
10984  			      barco_p1[myindex][crt2crtc][i][1]);
10985  	   }
10986          }
10987       }
10988       temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
10989       if(temp & 0x80) {
10990          temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x18);
10991          temp++;
10992          SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);
10993       }
10994    }
10995  }
10996  
10997  static unsigned short
GetOEMLCDPtr(struct SiS_Private * SiS_Pr,int Flag)10998  GetOEMLCDPtr(struct SiS_Private *SiS_Pr, int Flag)
10999  {
11000    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
11001    unsigned short tempbx=0,romptr=0;
11002    static const unsigned char customtable300[] = {
11003  	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
11004  	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
11005    };
11006    static const unsigned char customtable630[] = {
11007  	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
11008  	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
11009    };
11010  
11011    if(SiS_Pr->ChipType == SIS_300) {
11012  
11013      tempbx = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0x0f;
11014      if(SiS_Pr->SiS_VBType & VB_SIS301) tempbx &= 0x07;
11015      tempbx -= 2;
11016      if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 4;
11017      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11018         if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 3;
11019      }
11020      if(SiS_Pr->SiS_UseROM) {
11021         if(ROMAddr[0x235] & 0x80) {
11022            tempbx = SiS_Pr->SiS_LCDTypeInfo;
11023            if(Flag) {
11024  	     romptr = SISGETROMW(0x255);
11025  	     if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
11026  	     else       tempbx = customtable300[SiS_Pr->SiS_LCDTypeInfo];
11027               if(tempbx == 0xFF) return 0xFFFF;
11028            }
11029  	  tempbx <<= 1;
11030  	  if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
11031         }
11032      }
11033  
11034    } else {
11035  
11036      if(Flag) {
11037         if(SiS_Pr->SiS_UseROM) {
11038            romptr = SISGETROMW(0x255);
11039  	  if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
11040  	  else 	     tempbx = 0xff;
11041         } else {
11042            tempbx = customtable630[SiS_Pr->SiS_LCDTypeInfo];
11043         }
11044         if(tempbx == 0xFF) return 0xFFFF;
11045         tempbx <<= 2;
11046         if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
11047         if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
11048         return tempbx;
11049      }
11050      tempbx = SiS_Pr->SiS_LCDTypeInfo << 2;
11051      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
11052      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
11053  
11054    }
11055  
11056    return tempbx;
11057  }
11058  
11059  static void
SetOEMLCDDelay(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)11060  SetOEMLCDDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
11061  {
11062    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
11063    unsigned short index,temp,romptr=0;
11064  
11065    if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
11066  
11067    if(SiS_Pr->SiS_UseROM) {
11068       if(!(ROMAddr[0x237] & 0x01)) return;
11069       if(!(ROMAddr[0x237] & 0x02)) return;
11070       romptr = SISGETROMW(0x24b);
11071    }
11072  
11073    /* The Panel Compensation Delay should be set according to tables
11074     * here. Unfortunately, various BIOS versions don't care about
11075     * a uniform way using eg. ROM byte 0x220, but use different
11076     * hard coded delays (0x04, 0x20, 0x18) in SetGroup1().
11077     * Thus we don't set this if the user selected a custom pdc or if
11078     * we otherwise detected a valid pdc.
11079     */
11080    if(SiS_Pr->PDC != -1) return;
11081  
11082    temp = GetOEMLCDPtr(SiS_Pr, 0);
11083  
11084    if(SiS_Pr->UseCustomMode)
11085       index = 0;
11086    else
11087       index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
11088  
11089    if(SiS_Pr->ChipType != SIS_300) {
11090       if(romptr) {
11091  	romptr += (temp * 2);
11092  	romptr = SISGETROMW(romptr);
11093  	romptr += index;
11094  	temp = ROMAddr[romptr];
11095       } else {
11096  	if(SiS_Pr->SiS_VBType & VB_SISVB) {
11097      	   temp = SiS300_OEMLCDDelay2[temp][index];
11098  	} else {
11099             temp = SiS300_OEMLCDDelay3[temp][index];
11100          }
11101       }
11102    } else {
11103       if(SiS_Pr->SiS_UseROM && (ROMAddr[0x235] & 0x80)) {
11104  	if(romptr) {
11105  	   romptr += (temp * 2);
11106  	   romptr = SISGETROMW(romptr);
11107  	   romptr += index;
11108  	   temp = ROMAddr[romptr];
11109  	} else {
11110  	   temp = SiS300_OEMLCDDelay5[temp][index];
11111  	}
11112       } else {
11113          if(SiS_Pr->SiS_UseROM) {
11114  	   romptr = ROMAddr[0x249] | (ROMAddr[0x24a] << 8);
11115  	   if(romptr) {
11116  	      romptr += (temp * 2);
11117  	      romptr = SISGETROMW(romptr);
11118  	      romptr += index;
11119  	      temp = ROMAddr[romptr];
11120  	   } else {
11121  	      temp = SiS300_OEMLCDDelay4[temp][index];
11122  	   }
11123  	} else {
11124  	   temp = SiS300_OEMLCDDelay4[temp][index];
11125  	}
11126       }
11127    }
11128    temp &= 0x3c;
11129    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);  /* index 0A D[6:4] */
11130  }
11131  
11132  static void
SetOEMLCDData(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)11133  SetOEMLCDData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11134  {
11135  #if 0  /* Unfinished; Data table missing */
11136    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
11137    unsigned short index,temp;
11138  
11139    if((SiS_Pr->SiS_UseROM) {
11140       if(!(ROMAddr[0x237] & 0x01)) return;
11141       if(!(ROMAddr[0x237] & 0x04)) return;
11142       /* No rom pointer in BIOS header! */
11143    }
11144  
11145    temp = GetOEMLCDPtr(SiS_Pr, 1);
11146    if(temp == 0xFFFF) return;
11147  
11148    index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDHIndex;
11149    for(i=0x14, j=0; i<=0x17; i++, j++) {
11150        SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDHData[temp][index][j]);
11151    }
11152    SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1a, 0xf8, (SiS300_LCDHData[temp][index][j] & 0x07));
11153  
11154    index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDVIndex;
11155    SiS_SetReg(SiS_SiS_Part1Port,0x18, SiS300_LCDVData[temp][index][0]);
11156    SiS_SetRegANDOR(SiS_SiS_Part1Port,0x19, 0xF0, SiS300_LCDVData[temp][index][1]);
11157    SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1A, 0xC7, (SiS300_LCDVData[temp][index][2] & 0x38));
11158    for(i=0x1b, j=3; i<=0x1d; i++, j++) {
11159        SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDVData[temp][index][j]);
11160    }
11161  #endif
11162  }
11163  
11164  static unsigned short
GetOEMTVPtr(struct SiS_Private * SiS_Pr)11165  GetOEMTVPtr(struct SiS_Private *SiS_Pr)
11166  {
11167    unsigned short index;
11168  
11169    index = 0;
11170    if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))  index += 4;
11171    if(SiS_Pr->SiS_VBType & VB_SISVB) {
11172       if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART)  index += 2;
11173       else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index += 3;
11174       else if(SiS_Pr->SiS_TVMode & TVSetPAL)   index += 1;
11175    } else {
11176       if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) index += 2;
11177       if(SiS_Pr->SiS_TVMode & TVSetPAL)        index += 1;
11178    }
11179    return index;
11180  }
11181  
11182  static void
SetOEMTVDelay(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)11183  SetOEMTVDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11184  {
11185    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
11186    unsigned short index,temp,romptr=0;
11187  
11188    if(SiS_Pr->SiS_UseROM) {
11189       if(!(ROMAddr[0x238] & 0x01)) return;
11190       if(!(ROMAddr[0x238] & 0x02)) return;
11191       romptr = SISGETROMW(0x241);
11192    }
11193  
11194    temp = GetOEMTVPtr(SiS_Pr);
11195  
11196    index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVDelayIndex;
11197  
11198    if(romptr) {
11199       romptr += (temp * 2);
11200       romptr = SISGETROMW(romptr);
11201       romptr += index;
11202       temp = ROMAddr[romptr];
11203    } else {
11204       if(SiS_Pr->SiS_VBType & VB_SISVB) {
11205          temp = SiS300_OEMTVDelay301[temp][index];
11206       } else {
11207          temp = SiS300_OEMTVDelayLVDS[temp][index];
11208       }
11209    }
11210    temp &= 0x3c;
11211    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);
11212  }
11213  
11214  static void
SetOEMAntiFlicker(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)11215  SetOEMAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11216  {
11217    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
11218    unsigned short index,temp,romptr=0;
11219  
11220    if(SiS_Pr->SiS_UseROM) {
11221       if(!(ROMAddr[0x238] & 0x01)) return;
11222       if(!(ROMAddr[0x238] & 0x04)) return;
11223       romptr = SISGETROMW(0x243);
11224    }
11225  
11226    temp = GetOEMTVPtr(SiS_Pr);
11227  
11228    index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVFlickerIndex;
11229  
11230    if(romptr) {
11231       romptr += (temp * 2);
11232       romptr = SISGETROMW(romptr);
11233       romptr += index;
11234       temp = ROMAddr[romptr];
11235    } else {
11236       temp = SiS300_OEMTVFlicker[temp][index];
11237    }
11238    temp &= 0x70;
11239    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8F,temp);
11240  }
11241  
11242  static void
SetOEMPhaseIncr(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)11243  SetOEMPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
11244  {
11245    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
11246    unsigned short index,i,j,temp,romptr=0;
11247  
11248    if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) return;
11249  
11250    if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetNTSCJ | TVSetPALM | TVSetPALN)) return;
11251  
11252    if(SiS_Pr->SiS_UseROM) {
11253       if(!(ROMAddr[0x238] & 0x01)) return;
11254       if(!(ROMAddr[0x238] & 0x08)) return;
11255       romptr = SISGETROMW(0x245);
11256    }
11257  
11258    temp = GetOEMTVPtr(SiS_Pr);
11259  
11260    index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVPhaseIndex;
11261  
11262    if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
11263       for(i=0x31, j=0; i<=0x34; i++, j++) {
11264          SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase2[temp][index][j]);
11265       }
11266    } else {
11267       if(romptr) {
11268          romptr += (temp * 2);
11269  	romptr = SISGETROMW(romptr);
11270  	romptr += (index * 4);
11271          for(i=0x31, j=0; i<=0x34; i++, j++) {
11272  	   SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
11273  	}
11274       } else {
11275          for(i=0x31, j=0; i<=0x34; i++, j++) {
11276             SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase1[temp][index][j]);
11277  	}
11278       }
11279    }
11280  }
11281  
11282  static void
SetOEMYFilter(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex)11283  SetOEMYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11284  {
11285    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
11286    unsigned short index,temp,i,j,romptr=0;
11287  
11288    if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSCART | SetCRT2ToHiVision | SetCRT2ToYPbPr525750)) return;
11289  
11290    if(SiS_Pr->SiS_UseROM) {
11291       if(!(ROMAddr[0x238] & 0x01)) return;
11292       if(!(ROMAddr[0x238] & 0x10)) return;
11293       romptr = SISGETROMW(0x247);
11294    }
11295  
11296    temp = GetOEMTVPtr(SiS_Pr);
11297  
11298    if(SiS_Pr->SiS_TVMode & TVSetPALM)      temp = 8;
11299    else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 9;
11300    /* NTSCJ uses NTSC filters */
11301  
11302    index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVYFilterIndex;
11303  
11304    if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
11305        for(i=0x35, j=0; i<=0x38; i++, j++) {
11306         	SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
11307        }
11308        for(i=0x48; i<=0x4A; i++, j++) {
11309       	SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
11310        }
11311    } else {
11312        if((romptr) && (!(SiS_Pr->SiS_TVMode & (TVSetPALM|TVSetPALN)))) {
11313           romptr += (temp * 2);
11314  	 romptr = SISGETROMW(romptr);
11315  	 romptr += (index * 4);
11316  	 for(i=0x35, j=0; i<=0x38; i++, j++) {
11317         	    SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
11318           }
11319        } else {
11320           for(i=0x35, j=0; i<=0x38; i++, j++) {
11321         	    SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter1[temp][index][j]);
11322           }
11323        }
11324    }
11325  }
11326  
11327  static unsigned short
SiS_SearchVBModeID(struct SiS_Private * SiS_Pr,unsigned short * ModeNo)11328  SiS_SearchVBModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo)
11329  {
11330     unsigned short ModeIdIndex;
11331     unsigned char  VGAINFO = SiS_Pr->SiS_VGAINFO;
11332  
11333     if(*ModeNo <= 5) *ModeNo |= 1;
11334  
11335     for(ModeIdIndex=0; ; ModeIdIndex++) {
11336        if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == *ModeNo) break;
11337        if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == 0xFF)    return 0;
11338     }
11339  
11340     if(*ModeNo != 0x07) {
11341        if(*ModeNo > 0x03) return ModeIdIndex;
11342        if(VGAINFO & 0x80) return ModeIdIndex;
11343        ModeIdIndex++;
11344     }
11345  
11346     if(VGAINFO & 0x10) ModeIdIndex++;   /* 400 lines */
11347  	                               /* else 350 lines */
11348     return ModeIdIndex;
11349  }
11350  
11351  static void
SiS_OEM300Setting(struct SiS_Private * SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,unsigned short RefTableIndex)11352  SiS_OEM300Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
11353  		  unsigned short RefTableIndex)
11354  {
11355    unsigned short OEMModeIdIndex = 0;
11356  
11357    if(!SiS_Pr->UseCustomMode) {
11358       OEMModeIdIndex = SiS_SearchVBModeID(SiS_Pr,&ModeNo);
11359       if(!(OEMModeIdIndex)) return;
11360    }
11361  
11362    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
11363       SetOEMLCDDelay(SiS_Pr, ModeNo, OEMModeIdIndex);
11364       if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
11365          SetOEMLCDData(SiS_Pr, ModeNo, OEMModeIdIndex);
11366       }
11367    }
11368    if(SiS_Pr->UseCustomMode) return;
11369    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
11370       SetOEMTVDelay(SiS_Pr, ModeNo,OEMModeIdIndex);
11371       if(SiS_Pr->SiS_VBType & VB_SISVB) {
11372          SetOEMAntiFlicker(SiS_Pr, ModeNo, OEMModeIdIndex);
11373      	SetOEMPhaseIncr(SiS_Pr, ModeNo, OEMModeIdIndex);
11374         	SetOEMYFilter(SiS_Pr, ModeNo, OEMModeIdIndex);
11375       }
11376    }
11377  }
11378  #endif
11379  
11380