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
85static 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
130static 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
152static 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
163static 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
176static 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
184static 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
192static 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
211static 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
230static 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
239static const unsigned char SiS_Part2CLVX_6[] = { /* 1080i */
240 0x00,0x04,
241 0x04,0x1A,0x04,0x7E,0x02,0x1B,0x05,0x7E,0x01,0x1A,0x07,0x7E,0x00,0x1A,0x09,0x7D,
242 0x7F,0x19,0x0B,0x7D,0x7E,0x18,0x0D,0x7D,0x7D,0x17,0x10,0x7C,0x7D,0x15,0x12,0x7C,
243 0x7C,0x14,0x14,0x7C,0x7C,0x12,0x15,0x7D,0x7C,0x10,0x17,0x7D,0x7C,0x0D,0x18,0x7F,
244 0x7D,0x0B,0x19,0x7F,0x7D,0x09,0x1A,0x00,0x7D,0x07,0x1A,0x02,0x7E,0x05,0x1B,0x02,
245 0xFF,0xFF,
246};
247
248#ifdef CONFIG_FB_SIS_315
249/* 661 et al LCD data structure (2.03.00) */
250static const unsigned char SiS_LCDStruct661[] = {
251 /* 1024x768 */
252/* type|CR37| HDE | VDE | HT | VT | hss | hse */
253 0x02,0xC0,0x00,0x04,0x00,0x03,0x40,0x05,0x26,0x03,0x10,0x00,0x88,
254 0x00,0x02,0x00,0x06,0x00,0x41,0x5A,0x64,0x00,0x00,0x00,0x00,0x04,
255 /* | vss | vse |clck| clock |CRT2DataP|CRT2DataP|idx */
256 /* VESA non-VESA noscale */
257 /* 1280x1024 */
258 0x03,0xC0,0x00,0x05,0x00,0x04,0x98,0x06,0x2A,0x04,0x30,0x00,0x70,
259 0x00,0x01,0x00,0x03,0x00,0x6C,0xF8,0x2F,0x00,0x00,0x00,0x00,0x08,
260 /* 1400x1050 */
261 0x09,0x20,0x78,0x05,0x1A,0x04,0x98,0x06,0x2A,0x04,0x18,0x00,0x38,
262 0x00,0x01,0x00,0x03,0x00,0x6C,0xF8,0x2F,0x00,0x00,0x00,0x00,0x09,
263 /* 1600x1200 */
264 0x0B,0xE0,0x40,0x06,0xB0,0x04,0x70,0x08,0xE2,0x04,0x40,0x00,0xC0,
265 0x00,0x01,0x00,0x03,0x00,0xA2,0x70,0x24,0x00,0x00,0x00,0x00,0x0A,
266 /* 1280x768 (_2) */
267 0x0A,0xE0,0x00,0x05,0x00,0x03,0x7C,0x06,0x26,0x03,0x30,0x00,0x70,
268 0x00,0x03,0x00,0x06,0x00,0x4D,0xC8,0x48,0x00,0x00,0x00,0x00,0x06,
269 /* 1280x720 */
270 0x0E,0xE0,0x00,0x05,0xD0,0x02,0x80,0x05,0x26,0x03,0x10,0x00,0x20,
271 0x00,0x01,0x00,0x06,0x00,0x45,0x9C,0x62,0x00,0x00,0x00,0x00,0x05,
272 /* 1280x800 (_2) */
273 0x0C,0xE0,0x00,0x05,0x20,0x03,0x10,0x06,0x2C,0x03,0x30,0x00,0x70,
274 0x00,0x04,0x00,0x03,0x00,0x49,0xCE,0x1E,0x00,0x00,0x00,0x00,0x09,
275 /* 1680x1050 */
276 0x0D,0xE0,0x90,0x06,0x1A,0x04,0x6C,0x07,0x2A,0x04,0x1A,0x00,0x4C,
277 0x00,0x03,0x00,0x06,0x00,0x79,0xBE,0x44,0x00,0x00,0x00,0x00,0x06,
278 /* 1280x800_3 */
279 0x0C,0xE0,0x00,0x05,0x20,0x03,0xAA,0x05,0x2E,0x03,0x30,0x00,0x50,
280 0x00,0x04,0x00,0x03,0x00,0x47,0xA9,0x10,0x00,0x00,0x00,0x00,0x07,
281 /* 800x600 */
282 0x01,0xC0,0x20,0x03,0x58,0x02,0x20,0x04,0x74,0x02,0x2A,0x00,0x80,
283 0x00,0x06,0x00,0x04,0x00,0x28,0x63,0x4B,0x00,0x00,0x00,0x00,0x00,
284 /* 1280x854 */
285 0x08,0xE0,0x00,0x05,0x56,0x03,0x80,0x06,0x5d,0x03,0x10,0x00,0x70,
286 0x00,0x01,0x00,0x03,0x00,0x54,0x75,0x13,0x00,0x00,0x00,0x00,0x08
287};
288#endif
289
290#ifdef CONFIG_FB_SIS_300
291static unsigned char SiS300_TrumpionData[14][80] = {
292 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
293 0x20,0x03,0x0B,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x10,0x00,0x00,0x04,0x23,
294 0x00,0x00,0x03,0x28,0x03,0x10,0x05,0x08,0x40,0x10,0x00,0x10,0x04,0x23,0x00,0x23,
295 0x03,0x11,0x60,0xBC,0x01,0xFF,0x03,0xFF,0x19,0x01,0x00,0x05,0x09,0x04,0x04,0x05,
296 0x04,0x0C,0x09,0x05,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5A,0x01,0xBE,0x01,0x00 },
297 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x27,0x00,0x80,0x02,
298 0x20,0x03,0x07,0x00,0x5E,0x01,0x0D,0x02,0x60,0x0C,0x30,0x11,0x00,0x00,0x04,0x23,
299 0x00,0x00,0x03,0x80,0x03,0x28,0x06,0x08,0x40,0x11,0x00,0x11,0x04,0x23,0x00,0x23,
300 0x03,0x11,0x60,0x90,0x01,0xFF,0x0F,0xF4,0x19,0x01,0x00,0x05,0x01,0x00,0x04,0x05,
301 0x04,0x0C,0x02,0x01,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEC,0x57,0x01,0xBE,0x01,0x00 },
302 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x8A,0x00,0xD8,0x02,
303 0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,
304 0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,
305 0x03,0x11,0x60,0xD9,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,
306 0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x59,0x01,0xBE,0x01,0x00 },
307 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x72,0x00,0xD8,0x02,
308 0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,
309 0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,
310 0x03,0x11,0x60,0xDA,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,
311 0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
312 { 0x02,0x0A,0x02,0x00,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
313 0x20,0x03,0x16,0x00,0xE0,0x01,0x0D,0x02,0x60,0x0C,0x30,0x98,0x00,0x00,0x04,0x23,
314 0x00,0x01,0x03,0x45,0x03,0x48,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x23,0x00,0x23,
315 0x03,0x11,0x60,0xF4,0x01,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x05,0x01,0x00,0x05,0x05,
316 0x04,0x0C,0x08,0x05,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5B,0x01,0xBE,0x01,0x00 },
317 { 0x02,0x0A,0x02,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0xBF,0x00,0x20,0x03,
318 0x20,0x04,0x0D,0x00,0x58,0x02,0x71,0x02,0x80,0x0C,0x30,0x9A,0x00,0xFA,0x03,0x1D,
319 0x00,0x01,0x03,0x22,0x03,0x28,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x1D,0x00,0x1D,
320 0x03,0x11,0x60,0x39,0x03,0x40,0x05,0xF4,0x18,0x07,0x02,0x06,0x04,0x01,0x06,0x0B,
321 0x02,0x0A,0x20,0x19,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5B,0x01,0xBE,0x01,0x00 },
322 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0xEF,0x00,0x00,0x04,
323 0x40,0x05,0x13,0x00,0x00,0x03,0x26,0x03,0x88,0x0C,0x30,0x90,0x00,0x00,0x04,0x23,
324 0x00,0x01,0x03,0x24,0x03,0x28,0x06,0x08,0x40,0x90,0x00,0x90,0x04,0x23,0x00,0x23,
325 0x03,0x11,0x60,0x40,0x05,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x08,0x01,0x00,0x08,0x01,
326 0x00,0x08,0x01,0x01,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5B,0x01,0xBE,0x01,0x00 },
327 /* variant 2 */
328 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
329 0x20,0x03,0x15,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x18,0x00,0x00,0x04,0x23,
330 0x00,0x01,0x03,0x44,0x03,0x28,0x06,0x08,0x40,0x18,0x00,0x18,0x04,0x23,0x00,0x23,
331 0x03,0x11,0x60,0xA6,0x01,0xFF,0x03,0xFF,0x19,0x01,0x00,0x05,0x13,0x04,0x04,0x05,
332 0x04,0x0C,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
333 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
334 0x20,0x03,0x15,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x18,0x00,0x00,0x04,0x23,
335 0x00,0x01,0x03,0x44,0x03,0x28,0x06,0x08,0x40,0x18,0x00,0x18,0x04,0x23,0x00,0x23,
336 0x03,0x11,0x60,0xA6,0x01,0xFF,0x03,0xFF,0x19,0x01,0x00,0x05,0x13,0x04,0x04,0x05,
337 0x04,0x0C,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
338 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x8A,0x00,0xD8,0x02,
339 0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,
340 0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,
341 0x03,0x11,0x60,0xDA,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,
342 0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
343 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x72,0x00,0xD8,0x02,
344 0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,
345 0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,
346 0x03,0x11,0x60,0xDA,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,
347 0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
348 { 0x02,0x0A,0x02,0x00,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
349 0x20,0x03,0x16,0x00,0xE0,0x01,0x0D,0x02,0x60,0x0C,0x30,0x98,0x00,0x00,0x04,0x23,
350 0x00,0x01,0x03,0x45,0x03,0x48,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x23,0x00,0x23,
351 0x03,0x11,0x60,0xF4,0x01,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x05,0x01,0x00,0x05,0x05,
352 0x04,0x0C,0x08,0x05,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEA,0x58,0x01,0xBE,0x01,0x00 },
353 { 0x02,0x0A,0x02,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0xBF,0x00,0x20,0x03,
354 0x20,0x04,0x0D,0x00,0x58,0x02,0x71,0x02,0x80,0x0C,0x30,0x9A,0x00,0xFA,0x03,0x1D,
355 0x00,0x01,0x03,0x22,0x03,0x28,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x1D,0x00,0x1D,
356 0x03,0x11,0x60,0x39,0x03,0x40,0x05,0xF4,0x18,0x07,0x02,0x06,0x04,0x01,0x06,0x0B,
357 0x02,0x0A,0x20,0x19,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEA,0x58,0x01,0xBE,0x01,0x00 },
358 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0xEF,0x00,0x00,0x04,
359 0x40,0x05,0x13,0x00,0x00,0x03,0x26,0x03,0x88,0x0C,0x30,0x90,0x00,0x00,0x04,0x23,
360 0x00,0x01,0x03,0x24,0x03,0x28,0x06,0x08,0x40,0x90,0x00,0x90,0x04,0x23,0x00,0x23,
361 0x03,0x11,0x60,0x40,0x05,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x08,0x01,0x00,0x08,0x01,
362 0x00,0x08,0x01,0x01,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEA,0x58,0x01,0xBE,0x01,0x00 }
363};
364#endif
365
366#ifdef CONFIG_FB_SIS_315
367static void SiS_Chrontel701xOn(struct SiS_Private *SiS_Pr);
368static void SiS_Chrontel701xOff(struct SiS_Private *SiS_Pr);
369static void SiS_ChrontelInitTVVSync(struct SiS_Private *SiS_Pr);
370static void SiS_ChrontelDoSomething1(struct SiS_Private *SiS_Pr);
371#endif /* 315 */
372
373#ifdef CONFIG_FB_SIS_300
374static bool SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr);
375#endif
376
377static unsigned short SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags,
378 int VGAEngine, unsigned short adaptnum, unsigned short DDCdatatype,
379 bool checkcr32, unsigned int VBFlags2);
380static unsigned short SiS_ProbeDDC(struct SiS_Private *SiS_Pr);
381static unsigned short SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype,
382 unsigned char *buffer);
383static void SiS_SetSwitchDDC2(struct SiS_Private *SiS_Pr);
384static unsigned short SiS_SetStart(struct SiS_Private *SiS_Pr);
385static unsigned short SiS_SetStop(struct SiS_Private *SiS_Pr);
386static unsigned short SiS_SetSCLKLow(struct SiS_Private *SiS_Pr);
387static unsigned short SiS_SetSCLKHigh(struct SiS_Private *SiS_Pr);
388static unsigned short SiS_ReadDDC2Data(struct SiS_Private *SiS_Pr);
389static unsigned short SiS_WriteDDC2Data(struct SiS_Private *SiS_Pr, unsigned short tempax);
390static unsigned short SiS_CheckACK(struct SiS_Private *SiS_Pr);
391static unsigned short SiS_WriteDABDDC(struct SiS_Private *SiS_Pr);
392static unsigned short SiS_PrepareReadDDC(struct SiS_Private *SiS_Pr);
393static unsigned short SiS_PrepareDDC(struct SiS_Private *SiS_Pr);
394static void SiS_SendACK(struct SiS_Private *SiS_Pr, unsigned short yesno);
395static unsigned short SiS_DoProbeDDC(struct SiS_Private *SiS_Pr);
396
397#ifdef CONFIG_FB_SIS_300
398static void SiS_OEM300Setting(struct SiS_Private *SiS_Pr,
399 unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefTabindex);
400static void SetOEMLCDData2(struct SiS_Private *SiS_Pr,
401 unsigned short ModeNo, unsigned short ModeIdIndex,unsigned short RefTableIndex);
402#endif
403#ifdef CONFIG_FB_SIS_315
404static void SiS_OEM310Setting(struct SiS_Private *SiS_Pr,
405 unsigned short ModeNo,unsigned short ModeIdIndex, unsigned short RRTI);
406static void SiS_OEM661Setting(struct SiS_Private *SiS_Pr,
407 unsigned short ModeNo,unsigned short ModeIdIndex, unsigned short RRTI);
408static void SiS_FinalizeLCD(struct SiS_Private *, unsigned short, unsigned short);
409#endif
410
411static unsigned short SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr);
412static void SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);
413
414/*********************************************/
415/* HELPER: Lock/Unlock CRT2 */
416/*********************************************/
417
418void
419SiS_UnLockCRT2(struct SiS_Private *SiS_Pr)
420{
421 if(SiS_Pr->ChipType == XGI_20)
422 return;
423 else if(SiS_Pr->ChipType >= SIS_315H)
424 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
425 else
426 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
427}
428
429static
430void
431SiS_LockCRT2(struct SiS_Private *SiS_Pr)
432{
433 if(SiS_Pr->ChipType == XGI_20)
434 return;
435 else if(SiS_Pr->ChipType >= SIS_315H)
436 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
437 else
438 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
439}
440
441/*********************************************/
442/* HELPER: Write SR11 */
443/*********************************************/
444
445static void
446SiS_SetRegSR11ANDOR(struct SiS_Private *SiS_Pr, unsigned short DataAND, unsigned short DataOR)
447{
448 if(SiS_Pr->ChipType >= SIS_661) {
449 DataAND &= 0x0f;
450 DataOR &= 0x0f;
451 }
452 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,DataAND,DataOR);
453}
454
455/*********************************************/
456/* HELPER: Get Pointer to LCD structure */
457/*********************************************/
458
459#ifdef CONFIG_FB_SIS_315
460static unsigned char *
461GetLCDStructPtr661(struct SiS_Private *SiS_Pr)
462{
463 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
464 unsigned char *myptr = NULL;
465 unsigned short romindex = 0, reg = 0, idx = 0;
466
467 /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
468 * due to the variaty of panels the BIOS doesn't know about.
469 * Exception: If the BIOS has better knowledge (such as in case
470 * of machines with a 301C and a panel that does not support DDC)
471 * use the BIOS data as well.
472 */
473
474 if((SiS_Pr->SiS_ROMNew) &&
475 ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) {
476
477 if(SiS_Pr->ChipType < SIS_661) reg = 0x3c;
478 else reg = 0x7d;
479
480 idx = (SiS_GetReg(SiS_Pr->SiS_P3d4,reg) & 0x1f) * 26;
481
482 if(idx < (8*26)) {
483 myptr = (unsigned char *)&SiS_LCDStruct661[idx];
484 }
485 romindex = SISGETROMW(0x100);
486 if(romindex) {
487 romindex += idx;
488 myptr = &ROMAddr[romindex];
489 }
490 }
491 return myptr;
492}
493
494static unsigned short
495GetLCDStructPtr661_2(struct SiS_Private *SiS_Pr)
496{
497 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
498 unsigned short romptr = 0;
499
500 /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
501 * due to the variaty of panels the BIOS doesn't know about.
502 * Exception: If the BIOS has better knowledge (such as in case
503 * of machines with a 301C and a panel that does not support DDC)
504 * use the BIOS data as well.
505 */
506
507 if((SiS_Pr->SiS_ROMNew) &&
508 ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) {
509 romptr = SISGETROMW(0x102);
510 romptr += ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) * SiS_Pr->SiS661LCD2TableSize);
511 }
512
513 return romptr;
514}
515#endif
516
517/*********************************************/
518/* Adjust Rate for CRT2 */
519/*********************************************/
520
521static bool
522SiS_AdjustCRT2Rate(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
523 unsigned short RRTI, unsigned short *i)
524{
525 unsigned short checkmask=0, modeid, infoflag;
526
527 modeid = SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID;
528
529 if(SiS_Pr->SiS_VBType & VB_SISVB) {
530
531 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
532
533 checkmask |= SupportRAMDAC2;
534 if(SiS_Pr->ChipType >= SIS_315H) {
535 checkmask |= SupportRAMDAC2_135;
536 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
537 checkmask |= SupportRAMDAC2_162;
538 if(SiS_Pr->SiS_VBType & VB_SISRAMDAC202) {
539 checkmask |= SupportRAMDAC2_202;
540 }
541 }
542 }
543
544 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
545
546 checkmask |= SupportLCD;
547 if(SiS_Pr->ChipType >= SIS_315H) {
548 if(SiS_Pr->SiS_VBType & VB_SISVB) {
549 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
550 if(modeid == 0x2e) checkmask |= Support64048060Hz;
551 }
552 }
553 }
554
555 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
556
557 checkmask |= SupportHiVision;
558
559 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750|SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
560
561 checkmask |= SupportTV;
562 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
563 checkmask |= SupportTV1024;
564 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
565 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
566 checkmask |= SupportYPbPr750p;
567 }
568 }
569 }
570
571 }
572
573 } else { /* LVDS */
574
575 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
576 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
577 checkmask |= SupportCHTV;
578 }
579 }
580
581 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
582 checkmask |= SupportLCD;
583 }
584
585 }
586
587 /* Look backwards in table for matching CRT2 mode */
588 for(; SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID == modeid; (*i)--) {
589 infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
590 if(infoflag & checkmask) return true;
591 if((*i) == 0) break;
592 }
593
594 /* Look through the whole mode-section of the table from the beginning
595 * for a matching CRT2 mode if no mode was found yet.
596 */
597 for((*i) = 0; ; (*i)++) {
598 if(SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID != modeid) break;
599 infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
600 if(infoflag & checkmask) return true;
601 }
602 return false;
603}
604
605/*********************************************/
606/* Get rate index */
607/*********************************************/
608
609unsigned short
610SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
611{
612 unsigned short RRTI,i,backup_i;
613 unsigned short modeflag,index,temp,backupindex;
614 static const unsigned short LCDRefreshIndex[] = {
615 0x00, 0x00, 0x01, 0x01,
616 0x01, 0x01, 0x01, 0x01,
617 0x01, 0x01, 0x01, 0x01,
618 0x01, 0x01, 0x01, 0x01,
619 0x00, 0x00, 0x00, 0x00
620 };
621
622 /* Do NOT check for UseCustomMode here, will skrew up FIFO */
623 if(ModeNo == 0xfe) return 0;
624
625 if(ModeNo <= 0x13) {
626 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
627 } else {
628 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
629 }
630
631 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
632 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
633 if(modeflag & HalfDCLK) return 0;
634 }
635 }
636
637 if(ModeNo < 0x14) return 0xFFFF;
638
639 index = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x33) >> SiS_Pr->SiS_SelectCRT2Rate) & 0x0F;
640 backupindex = index;
641
642 if(index > 0) index--;
643
644 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
645 if(SiS_Pr->SiS_VBType & VB_SISVB) {
646 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
647 if(SiS_Pr->SiS_VBType & VB_NoLCD) index = 0;
648 else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index = backupindex = 0;
649 }
650 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
651 if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) {
652 temp = LCDRefreshIndex[SiS_GetBIOSLCDResInfo(SiS_Pr)];
653 if(index > temp) index = temp;
654 }
655 }
656 } else {
657 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) index = 0;
658 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
659 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) index = 0;
660 }
661 }
662 }
663
664 RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
665 ModeNo = SiS_Pr->SiS_RefIndex[RRTI].ModeID;
666
667 if(SiS_Pr->ChipType >= SIS_315H) {
668 if(!(SiS_Pr->SiS_VBInfo & DriverMode)) {
669 if( (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x105) ||
670 (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x107) ) {
671 if(backupindex <= 1) RRTI++;
672 }
673 }
674 }
675
676 i = 0;
677 do {
678 if(SiS_Pr->SiS_RefIndex[RRTI + i].ModeID != ModeNo) break;
679 temp = SiS_Pr->SiS_RefIndex[RRTI + i].Ext_InfoFlag;
680 temp &= ModeTypeMask;
681 if(temp < SiS_Pr->SiS_ModeType) break;
682 i++;
683 index--;
684 } while(index != 0xFFFF);
685
686 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
687 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
688 temp = SiS_Pr->SiS_RefIndex[RRTI + i - 1].Ext_InfoFlag;
689 if(temp & InterlaceMode) i++;
690 }
691 }
692
693 i--;
694
695 if((SiS_Pr->SiS_SetFlag & ProgrammingCRT2) && (!(SiS_Pr->SiS_VBInfo & DisableCRT2Display))) {
696 backup_i = i;
697 if(!(SiS_AdjustCRT2Rate(SiS_Pr, ModeNo, ModeIdIndex, RRTI, i: &i))) {
698 i = backup_i;
699 }
700 }
701
702 return (RRTI + i);
703}
704
705/*********************************************/
706/* STORE CRT2 INFO in CR34 */
707/*********************************************/
708
709static void
710SiS_SaveCRT2Info(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
711{
712 unsigned short temp1, temp2;
713
714 /* Store CRT1 ModeNo in CR34 */
715 SiS_SetReg(SiS_Pr->SiS_P3d4,0x34,ModeNo);
716 temp1 = (SiS_Pr->SiS_VBInfo & SetInSlaveMode) >> 8;
717 temp2 = ~(SetInSlaveMode >> 8);
718 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x31,temp2,temp1);
719}
720
721/*********************************************/
722/* HELPER: GET SOME DATA FROM BIOS ROM */
723/*********************************************/
724
725#ifdef CONFIG_FB_SIS_300
726static bool
727SiS_CR36BIOSWord23b(struct SiS_Private *SiS_Pr)
728{
729 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
730 unsigned short temp,temp1;
731
732 if(SiS_Pr->SiS_UseROM) {
733 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
734 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
735 temp1 = SISGETROMW(0x23b);
736 if(temp1 & temp) return true;
737 }
738 }
739 return false;
740}
741
742static bool
743SiS_CR36BIOSWord23d(struct SiS_Private *SiS_Pr)
744{
745 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
746 unsigned short temp,temp1;
747
748 if(SiS_Pr->SiS_UseROM) {
749 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
750 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
751 temp1 = SISGETROMW(0x23d);
752 if(temp1 & temp) return true;
753 }
754 }
755 return false;
756}
757#endif
758
759/*********************************************/
760/* HELPER: DELAY FUNCTIONS */
761/*********************************************/
762
763void
764SiS_DDC2Delay(struct SiS_Private *SiS_Pr, unsigned int delaytime)
765{
766 while (delaytime-- > 0)
767 SiS_GetReg(SiS_Pr->SiS_P3c4, 0x05);
768}
769
770#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
771static void
772SiS_GenericDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
773{
774 SiS_DDC2Delay(SiS_Pr, delaytime: delay * 36);
775}
776#endif
777
778#ifdef CONFIG_FB_SIS_315
779static void
780SiS_LongDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
781{
782 while(delay--) {
783 SiS_GenericDelay(SiS_Pr, delay: 6623);
784 }
785}
786#endif
787
788#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
789static void
790SiS_ShortDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
791{
792 while(delay--) {
793 SiS_GenericDelay(SiS_Pr, delay: 66);
794 }
795}
796#endif
797
798static void
799SiS_PanelDelay(struct SiS_Private *SiS_Pr, unsigned short DelayTime)
800{
801#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
802 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
803 unsigned short PanelID, DelayIndex, Delay=0;
804#endif
805
806 if(SiS_Pr->ChipType < SIS_315H) {
807
808#ifdef CONFIG_FB_SIS_300
809
810 PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
811 if(SiS_Pr->SiS_VBType & VB_SISVB) {
812 if(SiS_Pr->SiS_VBType & VB_SIS301) PanelID &= 0xf7;
813 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x10)) PanelID = 0x12;
814 }
815 DelayIndex = PanelID >> 4;
816 if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) {
817 Delay = 3;
818 } else {
819 if(DelayTime >= 2) DelayTime -= 2;
820 if(!(DelayTime & 0x01)) {
821 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
822 } else {
823 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
824 }
825 if(SiS_Pr->SiS_UseROM) {
826 if(ROMAddr[0x220] & 0x40) {
827 if(!(DelayTime & 0x01)) Delay = (unsigned short)ROMAddr[0x225];
828 else Delay = (unsigned short)ROMAddr[0x226];
829 }
830 }
831 }
832 SiS_ShortDelay(SiS_Pr, delay: Delay);
833
834#endif /* CONFIG_FB_SIS_300 */
835
836 } else {
837
838#ifdef CONFIG_FB_SIS_315
839
840 if((SiS_Pr->ChipType >= SIS_661) ||
841 (SiS_Pr->ChipType <= SIS_315PRO) ||
842 (SiS_Pr->ChipType == SIS_330) ||
843 (SiS_Pr->SiS_ROMNew)) {
844
845 if(!(DelayTime & 0x01)) {
846 SiS_DDC2Delay(SiS_Pr, delaytime: 0x1000);
847 } else {
848 SiS_DDC2Delay(SiS_Pr, delaytime: 0x4000);
849 }
850
851 } else if (SiS_Pr->SiS_IF_DEF_LVDS == 1) { /* 315 series, LVDS; Special */
852
853 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
854 PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
855 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1400) {
856 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1b) & 0x10)) PanelID = 0x12;
857 }
858 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
859 DelayIndex = PanelID & 0x0f;
860 } else {
861 DelayIndex = PanelID >> 4;
862 }
863 if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) {
864 Delay = 3;
865 } else {
866 if(DelayTime >= 2) DelayTime -= 2;
867 if(!(DelayTime & 0x01)) {
868 Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[0];
869 } else {
870 Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[1];
871 }
872 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
873 if(ROMAddr[0x13c] & 0x40) {
874 if(!(DelayTime & 0x01)) {
875 Delay = (unsigned short)ROMAddr[0x17e];
876 } else {
877 Delay = (unsigned short)ROMAddr[0x17f];
878 }
879 }
880 }
881 }
882 SiS_ShortDelay(SiS_Pr, delay: Delay);
883 }
884
885 } else if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 315 series, all bridges */
886
887 DelayIndex = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
888 if(!(DelayTime & 0x01)) {
889 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
890 } else {
891 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
892 }
893 Delay <<= 8;
894 SiS_DDC2Delay(SiS_Pr, delaytime: Delay);
895
896 }
897
898#endif /* CONFIG_FB_SIS_315 */
899
900 }
901}
902
903#ifdef CONFIG_FB_SIS_315
904static void
905SiS_PanelDelayLoop(struct SiS_Private *SiS_Pr, unsigned short DelayTime, unsigned short DelayLoop)
906{
907 int i;
908 for(i = 0; i < DelayLoop; i++) {
909 SiS_PanelDelay(SiS_Pr, DelayTime);
910 }
911}
912#endif
913
914/*********************************************/
915/* HELPER: WAIT-FOR-RETRACE FUNCTIONS */
916/*********************************************/
917
918void
919SiS_WaitRetrace1(struct SiS_Private *SiS_Pr)
920{
921 unsigned short watchdog;
922
923 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
924 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80)) return;
925
926 watchdog = 65535;
927 while((SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
928 watchdog = 65535;
929 while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
930}
931
932#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
933static void
934SiS_WaitRetrace2(struct SiS_Private *SiS_Pr, unsigned short reg)
935{
936 unsigned short watchdog;
937
938 watchdog = 65535;
939 while((SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02) && --watchdog);
940 watchdog = 65535;
941 while((!(SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02)) && --watchdog);
942}
943#endif
944
945static void
946SiS_WaitVBRetrace(struct SiS_Private *SiS_Pr)
947{
948 if(SiS_Pr->ChipType < SIS_315H) {
949#ifdef CONFIG_FB_SIS_300
950 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
951 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return;
952 }
953 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x80)) {
954 SiS_WaitRetrace1(SiS_Pr);
955 } else {
956 SiS_WaitRetrace2(SiS_Pr, reg: 0x25);
957 }
958#endif
959 } else {
960#ifdef CONFIG_FB_SIS_315
961 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) {
962 SiS_WaitRetrace1(SiS_Pr);
963 } else {
964 SiS_WaitRetrace2(SiS_Pr, reg: 0x30);
965 }
966#endif
967 }
968}
969
970static void
971SiS_VBWait(struct SiS_Private *SiS_Pr)
972{
973 unsigned short tempal,temp,i,j;
974
975 temp = 0;
976 for(i = 0; i < 3; i++) {
977 for(j = 0; j < 100; j++) {
978 tempal = SiS_GetRegByte(SiS_Pr->SiS_P3da);
979 if(temp & 0x01) {
980 if((tempal & 0x08)) continue;
981 else break;
982 } else {
983 if(!(tempal & 0x08)) continue;
984 else break;
985 }
986 }
987 temp ^= 0x01;
988 }
989}
990
991static void
992SiS_VBLongWait(struct SiS_Private *SiS_Pr)
993{
994 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
995 SiS_VBWait(SiS_Pr);
996 } else {
997 SiS_WaitRetrace1(SiS_Pr);
998 }
999}
1000
1001/*********************************************/
1002/* HELPER: MISC */
1003/*********************************************/
1004
1005#ifdef CONFIG_FB_SIS_300
1006static bool
1007SiS_Is301B(struct SiS_Private *SiS_Pr)
1008{
1009 if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01) >= 0xb0) return true;
1010 return false;
1011}
1012#endif
1013
1014static bool
1015SiS_CRT2IsLCD(struct SiS_Private *SiS_Pr)
1016{
1017 if(SiS_Pr->ChipType == SIS_730) {
1018 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x20) return true;
1019 }
1020 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & 0x20) return true;
1021 return false;
1022}
1023
1024bool
1025SiS_IsDualEdge(struct SiS_Private *SiS_Pr)
1026{
1027#ifdef CONFIG_FB_SIS_315
1028 if(SiS_Pr->ChipType >= SIS_315H) {
1029 if((SiS_Pr->ChipType != SIS_650) || (SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) {
1030 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableDualEdge) return true;
1031 }
1032 }
1033#endif
1034 return false;
1035}
1036
1037bool
1038SiS_IsVAMode(struct SiS_Private *SiS_Pr)
1039{
1040#ifdef CONFIG_FB_SIS_315
1041 unsigned short flag;
1042
1043 if(SiS_Pr->ChipType >= SIS_315H) {
1044 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1045 if((flag & EnableDualEdge) && (flag & SetToLCDA)) return true;
1046 }
1047#endif
1048 return false;
1049}
1050
1051#ifdef CONFIG_FB_SIS_315
1052static bool
1053SiS_IsVAorLCD(struct SiS_Private *SiS_Pr)
1054{
1055 if(SiS_IsVAMode(SiS_Pr)) return true;
1056 if(SiS_CRT2IsLCD(SiS_Pr)) return true;
1057 return false;
1058}
1059#endif
1060
1061static bool
1062SiS_IsDualLink(struct SiS_Private *SiS_Pr)
1063{
1064#ifdef CONFIG_FB_SIS_315
1065 if(SiS_Pr->ChipType >= SIS_315H) {
1066 if((SiS_CRT2IsLCD(SiS_Pr)) ||
1067 (SiS_IsVAMode(SiS_Pr))) {
1068 if(SiS_Pr->SiS_LCDInfo & LCDDualLink) return true;
1069 }
1070 }
1071#endif
1072 return false;
1073}
1074
1075#ifdef CONFIG_FB_SIS_315
1076static bool
1077SiS_TVEnabled(struct SiS_Private *SiS_Pr)
1078{
1079 if((SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) != 0x0c) return true;
1080 if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1081 if(SiS_GetReg(SiS_Pr->SiS_Part2Port,0x4d) & 0x10) return true;
1082 }
1083 return false;
1084}
1085#endif
1086
1087#ifdef CONFIG_FB_SIS_315
1088static bool
1089SiS_LCDAEnabled(struct SiS_Private *SiS_Pr)
1090{
1091 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) return true;
1092 return false;
1093}
1094#endif
1095
1096#ifdef CONFIG_FB_SIS_315
1097static bool
1098SiS_WeHaveBacklightCtrl(struct SiS_Private *SiS_Pr)
1099{
1100 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
1101 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0x10) return true;
1102 }
1103 return false;
1104}
1105#endif
1106
1107#ifdef CONFIG_FB_SIS_315
1108static bool
1109SiS_IsNotM650orLater(struct SiS_Private *SiS_Pr)
1110{
1111 unsigned short flag;
1112
1113 if(SiS_Pr->ChipType == SIS_650) {
1114 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0;
1115 /* Check for revision != A0 only */
1116 if((flag == 0xe0) || (flag == 0xc0) ||
1117 (flag == 0xb0) || (flag == 0x90)) return false;
1118 } else if(SiS_Pr->ChipType >= SIS_661) return false;
1119 return true;
1120}
1121#endif
1122
1123#ifdef CONFIG_FB_SIS_315
1124static bool
1125SiS_IsYPbPr(struct SiS_Private *SiS_Pr)
1126{
1127 if(SiS_Pr->ChipType >= SIS_315H) {
1128 /* YPrPb = 0x08 */
1129 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHYPbPr) return true;
1130 }
1131 return false;
1132}
1133#endif
1134
1135#ifdef CONFIG_FB_SIS_315
1136static bool
1137SiS_IsChScart(struct SiS_Private *SiS_Pr)
1138{
1139 if(SiS_Pr->ChipType >= SIS_315H) {
1140 /* Scart = 0x04 */
1141 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHScart) return true;
1142 }
1143 return false;
1144}
1145#endif
1146
1147#ifdef CONFIG_FB_SIS_315
1148static bool
1149SiS_IsTVOrYPbPrOrScart(struct SiS_Private *SiS_Pr)
1150{
1151 unsigned short flag;
1152
1153 if(SiS_Pr->ChipType >= SIS_315H) {
1154 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
1155 if(flag & SetCRT2ToTV) return true;
1156 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1157 if(flag & EnableCHYPbPr) return true; /* = YPrPb = 0x08 */
1158 if(flag & EnableCHScart) return true; /* = Scart = 0x04 - TW */
1159 } else {
1160 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
1161 if(flag & SetCRT2ToTV) return true;
1162 }
1163 return false;
1164}
1165#endif
1166
1167#ifdef CONFIG_FB_SIS_315
1168static bool
1169SiS_IsLCDOrLCDA(struct SiS_Private *SiS_Pr)
1170{
1171 unsigned short flag;
1172
1173 if(SiS_Pr->ChipType >= SIS_315H) {
1174 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
1175 if(flag & SetCRT2ToLCD) return true;
1176 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1177 if(flag & SetToLCDA) return true;
1178 } else {
1179 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
1180 if(flag & SetCRT2ToLCD) return true;
1181 }
1182 return false;
1183}
1184#endif
1185
1186static bool
1187SiS_HaveBridge(struct SiS_Private *SiS_Pr)
1188{
1189 unsigned short flag;
1190
1191 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1192 return true;
1193 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
1194 flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
1195 if((flag == 1) || (flag == 2)) return true;
1196 }
1197 return false;
1198}
1199
1200static bool
1201SiS_BridgeIsEnabled(struct SiS_Private *SiS_Pr)
1202{
1203 unsigned short flag;
1204
1205 if(SiS_HaveBridge(SiS_Pr)) {
1206 flag = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
1207 if(SiS_Pr->ChipType < SIS_315H) {
1208 flag &= 0xa0;
1209 if((flag == 0x80) || (flag == 0x20)) return true;
1210 } else {
1211 flag &= 0x50;
1212 if((flag == 0x40) || (flag == 0x10)) return true;
1213 }
1214 }
1215 return false;
1216}
1217
1218static bool
1219SiS_BridgeInSlavemode(struct SiS_Private *SiS_Pr)
1220{
1221 unsigned short flag1;
1222
1223 flag1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
1224 if(flag1 & (SetInSlaveMode >> 8)) return true;
1225 return false;
1226}
1227
1228/*********************************************/
1229/* GET VIDEO BRIDGE CONFIG INFO */
1230/*********************************************/
1231
1232/* Setup general purpose IO for Chrontel communication */
1233#ifdef CONFIG_FB_SIS_300
1234void
1235SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo)
1236{
1237 unsigned int acpibase;
1238 unsigned short temp;
1239
1240 if(!(SiS_Pr->SiS_ChSW)) return;
1241
1242 acpibase = sisfb_read_lpc_pci_dword(SiS_Pr, reg: 0x74);
1243 acpibase &= 0xFFFF;
1244 if(!acpibase) return;
1245 temp = SiS_GetRegShort((acpibase + 0x3c)); /* ACPI register 0x3c: GP Event 1 I/O mode select */
1246 temp &= 0xFEFF;
1247 SiS_SetRegShort((acpibase + 0x3c), temp);
1248 temp = SiS_GetRegShort((acpibase + 0x3c));
1249 temp = SiS_GetRegShort((acpibase + 0x3a)); /* ACPI register 0x3a: GP Pin Level (low/high) */
1250 temp &= 0xFEFF;
1251 if(!(myvbinfo & SetCRT2ToTV)) temp |= 0x0100;
1252 SiS_SetRegShort((acpibase + 0x3a), temp);
1253 temp = SiS_GetRegShort((acpibase + 0x3a));
1254}
1255#endif
1256
1257void
1258SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
1259 unsigned short ModeIdIndex, int checkcrt2mode)
1260{
1261 unsigned short tempax, tempbx, temp;
1262 unsigned short modeflag, resinfo = 0;
1263
1264 SiS_Pr->SiS_SetFlag = 0;
1265
1266 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
1267
1268 SiS_Pr->SiS_ModeType = modeflag & ModeTypeMask;
1269
1270 if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
1271 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1272 }
1273
1274 tempbx = 0;
1275
1276 if(SiS_HaveBridge(SiS_Pr)) {
1277
1278 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
1279 tempbx |= temp;
1280 tempax = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) << 8;
1281 tempax &= (DriverMode | LoadDACFlag | SetNotSimuMode | SetPALTV);
1282 tempbx |= tempax;
1283
1284#ifdef CONFIG_FB_SIS_315
1285 if(SiS_Pr->ChipType >= SIS_315H) {
1286 if(SiS_Pr->SiS_VBType & VB_SISLCDA) {
1287 if(ModeNo == 0x03) {
1288 /* Mode 0x03 is never in driver mode */
1289 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf);
1290 }
1291 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8))) {
1292 /* Reset LCDA setting if not driver mode */
1293 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
1294 }
1295 if(IS_SIS650) {
1296 if(SiS_Pr->SiS_UseLCDA) {
1297 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) {
1298 if((ModeNo <= 0x13) || (!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) {
1299 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA));
1300 }
1301 }
1302 }
1303 }
1304 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1305 if((temp & (EnableDualEdge | SetToLCDA)) == (EnableDualEdge | SetToLCDA)) {
1306 tempbx |= SetCRT2ToLCDA;
1307 }
1308 }
1309
1310 if(SiS_Pr->ChipType >= SIS_661) { /* New CR layout */
1311 tempbx &= ~(SetCRT2ToYPbPr525750 | SetCRT2ToHiVision);
1312 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & 0x04) {
1313 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
1314 if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
1315 else if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1316 tempbx |= SetCRT2ToYPbPr525750;
1317 }
1318 }
1319 }
1320
1321 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1322 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1323 if(temp & SetToLCDA) {
1324 tempbx |= SetCRT2ToLCDA;
1325 }
1326 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1327 if(temp & EnableCHYPbPr) {
1328 tempbx |= SetCRT2ToCHYPbPr;
1329 }
1330 }
1331 }
1332 }
1333
1334#endif /* CONFIG_FB_SIS_315 */
1335
1336 if(!(SiS_Pr->SiS_VBType & VB_SISVGA2)) {
1337 tempbx &= ~(SetCRT2ToRAMDAC);
1338 }
1339
1340 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1341 temp = SetCRT2ToSVIDEO |
1342 SetCRT2ToAVIDEO |
1343 SetCRT2ToSCART |
1344 SetCRT2ToLCDA |
1345 SetCRT2ToLCD |
1346 SetCRT2ToRAMDAC |
1347 SetCRT2ToHiVision |
1348 SetCRT2ToYPbPr525750;
1349 } else {
1350 if(SiS_Pr->ChipType >= SIS_315H) {
1351 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1352 temp = SetCRT2ToAVIDEO |
1353 SetCRT2ToSVIDEO |
1354 SetCRT2ToSCART |
1355 SetCRT2ToLCDA |
1356 SetCRT2ToLCD |
1357 SetCRT2ToCHYPbPr;
1358 } else {
1359 temp = SetCRT2ToLCDA |
1360 SetCRT2ToLCD;
1361 }
1362 } else {
1363 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1364 temp = SetCRT2ToTV | SetCRT2ToLCD;
1365 } else {
1366 temp = SetCRT2ToLCD;
1367 }
1368 }
1369 }
1370
1371 if(!(tempbx & temp)) {
1372 tempax = DisableCRT2Display;
1373 tempbx = 0;
1374 }
1375
1376 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1377
1378 unsigned short clearmask = ( DriverMode |
1379 DisableCRT2Display |
1380 LoadDACFlag |
1381 SetNotSimuMode |
1382 SetInSlaveMode |
1383 SetPALTV |
1384 SwitchCRT2 |
1385 SetSimuScanMode );
1386
1387 if(tempbx & SetCRT2ToLCDA) tempbx &= (clearmask | SetCRT2ToLCDA);
1388 if(tempbx & SetCRT2ToRAMDAC) tempbx &= (clearmask | SetCRT2ToRAMDAC);
1389 if(tempbx & SetCRT2ToLCD) tempbx &= (clearmask | SetCRT2ToLCD);
1390 if(tempbx & SetCRT2ToSCART) tempbx &= (clearmask | SetCRT2ToSCART);
1391 if(tempbx & SetCRT2ToHiVision) tempbx &= (clearmask | SetCRT2ToHiVision);
1392 if(tempbx & SetCRT2ToYPbPr525750) tempbx &= (clearmask | SetCRT2ToYPbPr525750);
1393
1394 } else {
1395
1396 if(SiS_Pr->ChipType >= SIS_315H) {
1397 if(tempbx & SetCRT2ToLCDA) {
1398 tempbx &= (0xFF00|SwitchCRT2|SetSimuScanMode);
1399 }
1400 }
1401 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1402 if(tempbx & SetCRT2ToTV) {
1403 tempbx &= (0xFF00|SetCRT2ToTV|SwitchCRT2|SetSimuScanMode);
1404 }
1405 }
1406 if(tempbx & SetCRT2ToLCD) {
1407 tempbx &= (0xFF00|SetCRT2ToLCD|SwitchCRT2|SetSimuScanMode);
1408 }
1409 if(SiS_Pr->ChipType >= SIS_315H) {
1410 if(tempbx & SetCRT2ToLCDA) {
1411 tempbx |= SetCRT2ToLCD;
1412 }
1413 }
1414
1415 }
1416
1417 if(tempax & DisableCRT2Display) {
1418 if(!(tempbx & (SwitchCRT2 | SetSimuScanMode))) {
1419 tempbx = SetSimuScanMode | DisableCRT2Display;
1420 }
1421 }
1422
1423 if(!(tempbx & DriverMode)) tempbx |= SetSimuScanMode;
1424
1425 /* LVDS/CHRONTEL (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */
1426 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
1427 if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
1428 ((SiS_Pr->SiS_VBType & VB_NoLCD) && (tempbx & SetCRT2ToLCD)) ) {
1429 modeflag &= (~CRT2Mode);
1430 }
1431 }
1432
1433 if(!(tempbx & SetSimuScanMode)) {
1434 if(tempbx & SwitchCRT2) {
1435 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1436 if(resinfo != SIS_RI_1600x1200) {
1437 tempbx |= SetSimuScanMode;
1438 }
1439 }
1440 } else {
1441 if(SiS_BridgeIsEnabled(SiS_Pr)) {
1442 if(!(tempbx & DriverMode)) {
1443 if(SiS_BridgeInSlavemode(SiS_Pr)) {
1444 tempbx |= SetSimuScanMode;
1445 }
1446 }
1447 }
1448 }
1449 }
1450
1451 if(!(tempbx & DisableCRT2Display)) {
1452 if(tempbx & DriverMode) {
1453 if(tempbx & SetSimuScanMode) {
1454 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1455 if(resinfo != SIS_RI_1600x1200) {
1456 tempbx |= SetInSlaveMode;
1457 }
1458 }
1459 }
1460 } else {
1461 tempbx |= SetInSlaveMode;
1462 }
1463 }
1464
1465 }
1466
1467 SiS_Pr->SiS_VBInfo = tempbx;
1468
1469#ifdef CONFIG_FB_SIS_300
1470 if(SiS_Pr->ChipType == SIS_630) {
1471 SiS_SetChrontelGPIO(SiS_Pr, myvbinfo: SiS_Pr->SiS_VBInfo);
1472 }
1473#endif
1474
1475#if 0
1476 printk(KERN_DEBUG "sisfb: (init301: VBInfo= 0x%04x, SetFlag=0x%04x)\n",
1477 SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
1478#endif
1479}
1480
1481/*********************************************/
1482/* DETERMINE YPbPr MODE */
1483/*********************************************/
1484
1485void
1486SiS_SetYPbPr(struct SiS_Private *SiS_Pr)
1487{
1488
1489 unsigned char temp;
1490
1491 /* Note: This variable is only used on 30xLV systems.
1492 * CR38 has a different meaning on LVDS/CH7019 systems.
1493 * On 661 and later, these bits moved to CR35.
1494 *
1495 * On 301, 301B, only HiVision 1080i is supported.
1496 * On 30xLV, 301C, only YPbPr 1080i is supported.
1497 */
1498
1499 SiS_Pr->SiS_YPbPr = 0;
1500 if(SiS_Pr->ChipType >= SIS_661) return;
1501
1502 if(SiS_Pr->SiS_VBType) {
1503 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1504 SiS_Pr->SiS_YPbPr = YPbPrHiVision;
1505 }
1506 }
1507
1508 if(SiS_Pr->ChipType >= SIS_315H) {
1509 if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1510 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1511 if(temp & 0x08) {
1512 switch((temp >> 4)) {
1513 case 0x00: SiS_Pr->SiS_YPbPr = YPbPr525i; break;
1514 case 0x01: SiS_Pr->SiS_YPbPr = YPbPr525p; break;
1515 case 0x02: SiS_Pr->SiS_YPbPr = YPbPr750p; break;
1516 case 0x03: SiS_Pr->SiS_YPbPr = YPbPrHiVision; break;
1517 }
1518 }
1519 }
1520 }
1521
1522}
1523
1524/*********************************************/
1525/* DETERMINE TVMode flag */
1526/*********************************************/
1527
1528void
1529SiS_SetTVMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
1530{
1531 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
1532 unsigned short temp, temp1, resinfo = 0, romindex = 0;
1533 unsigned char OutputSelect = *SiS_Pr->pSiS_OutputSelect;
1534
1535 SiS_Pr->SiS_TVMode = 0;
1536
1537 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
1538 if(SiS_Pr->UseCustomMode) return;
1539
1540 if(ModeNo > 0x13) {
1541 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1542 }
1543
1544 if(SiS_Pr->ChipType < SIS_661) {
1545
1546 if(SiS_Pr->SiS_VBInfo & SetPALTV) SiS_Pr->SiS_TVMode |= TVSetPAL;
1547
1548 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1549 temp = 0;
1550 if((SiS_Pr->ChipType == SIS_630) ||
1551 (SiS_Pr->ChipType == SIS_730)) {
1552 temp = 0x35;
1553 romindex = 0xfe;
1554 } else if(SiS_Pr->ChipType >= SIS_315H) {
1555 temp = 0x38;
1556 if(SiS_Pr->ChipType < XGI_20) {
1557 romindex = 0xf3;
1558 if(SiS_Pr->ChipType >= SIS_330) romindex = 0x11b;
1559 }
1560 }
1561 if(temp) {
1562 if(romindex && SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
1563 OutputSelect = ROMAddr[romindex];
1564 if(!(OutputSelect & EnablePALMN)) {
1565 SiS_SetRegAND(SiS_Pr->SiS_P3d4,temp,0x3F);
1566 }
1567 }
1568 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,temp);
1569 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1570 if(temp1 & EnablePALM) { /* 0x40 */
1571 SiS_Pr->SiS_TVMode |= TVSetPALM;
1572 SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1573 } else if(temp1 & EnablePALN) { /* 0x80 */
1574 SiS_Pr->SiS_TVMode |= TVSetPALN;
1575 }
1576 } else {
1577 if(temp1 & EnableNTSCJ) { /* 0x40 */
1578 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1579 }
1580 }
1581 }
1582 /* Translate HiVision/YPbPr to our new flags */
1583 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1584 if(SiS_Pr->SiS_YPbPr == YPbPr750p) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1585 else if(SiS_Pr->SiS_YPbPr == YPbPr525p) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1586 else if(SiS_Pr->SiS_YPbPr == YPbPrHiVision) SiS_Pr->SiS_TVMode |= TVSetHiVision;
1587 else SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1588 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p | TVSetYPbPr525i)) {
1589 SiS_Pr->SiS_VBInfo &= ~SetCRT2ToHiVision;
1590 SiS_Pr->SiS_VBInfo |= SetCRT2ToYPbPr525750;
1591 } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
1592 SiS_Pr->SiS_TVMode |= TVSetPAL;
1593 }
1594 }
1595 } else if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1596 if(SiS_Pr->SiS_CHOverScan) {
1597 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
1598 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1599 if((temp & TVOverScan) || (SiS_Pr->SiS_CHOverScan == 1)) {
1600 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1601 }
1602 } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1603 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79);
1604 if((temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1)) {
1605 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1606 }
1607 }
1608 if(SiS_Pr->SiS_CHSOverScan) {
1609 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1610 }
1611 }
1612 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1613 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1614 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1615 if(temp & EnablePALM) SiS_Pr->SiS_TVMode |= TVSetPALM;
1616 else if(temp & EnablePALN) SiS_Pr->SiS_TVMode |= TVSetPALN;
1617 } else {
1618 if(temp & EnableNTSCJ) {
1619 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1620 }
1621 }
1622 }
1623 }
1624
1625 } else { /* 661 and later */
1626
1627 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1628 if(temp1 & 0x01) {
1629 SiS_Pr->SiS_TVMode |= TVSetPAL;
1630 if(temp1 & 0x08) {
1631 SiS_Pr->SiS_TVMode |= TVSetPALN;
1632 } else if(temp1 & 0x04) {
1633 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1634 SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1635 }
1636 SiS_Pr->SiS_TVMode |= TVSetPALM;
1637 }
1638 } else {
1639 if(temp1 & 0x02) {
1640 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1641 }
1642 }
1643 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1644 if(SiS_Pr->SiS_CHOverScan) {
1645 if((temp1 & 0x10) || (SiS_Pr->SiS_CHOverScan == 1)) {
1646 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1647 }
1648 }
1649 }
1650 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1651 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1652 temp1 &= 0xe0;
1653 if(temp1 == 0x00) SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1654 else if(temp1 == 0x20) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1655 else if(temp1 == 0x40) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1656 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1657 SiS_Pr->SiS_TVMode |= (TVSetHiVision | TVSetPAL);
1658 }
1659 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750 | SetCRT2ToHiVision)) {
1660 if(resinfo == SIS_RI_800x480 || resinfo == SIS_RI_1024x576 || resinfo == SIS_RI_1280x720) {
1661 SiS_Pr->SiS_TVMode |= TVAspect169;
1662 } else {
1663 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x39);
1664 if(temp1 & 0x02) {
1665 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetHiVision)) {
1666 SiS_Pr->SiS_TVMode |= TVAspect169;
1667 } else {
1668 SiS_Pr->SiS_TVMode |= TVAspect43LB;
1669 }
1670 } else {
1671 SiS_Pr->SiS_TVMode |= TVAspect43;
1672 }
1673 }
1674 }
1675 }
1676 }
1677
1678 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) SiS_Pr->SiS_TVMode |= TVSetPAL;
1679
1680 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1681
1682 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1683 SiS_Pr->SiS_TVMode |= TVSetPAL;
1684 SiS_Pr->SiS_TVMode &= ~(TVSetPALM | TVSetPALN | TVSetNTSCJ);
1685 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1686 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525i | TVSetYPbPr525p | TVSetYPbPr750p)) {
1687 SiS_Pr->SiS_TVMode &= ~(TVSetPAL | TVSetNTSCJ | TVSetPALM | TVSetPALN);
1688 }
1689 }
1690
1691 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
1692 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
1693 SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
1694 }
1695 }
1696
1697 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
1698 if(resinfo == SIS_RI_1024x768) {
1699 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
1700 SiS_Pr->SiS_TVMode |= TVSet525p1024;
1701 } else if(!(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p))) {
1702 SiS_Pr->SiS_TVMode |= TVSetNTSC1024;
1703 }
1704 }
1705 }
1706
1707 SiS_Pr->SiS_TVMode |= TVRPLLDIV2XO;
1708 if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) &&
1709 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
1710 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1711 } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
1712 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1713 } else if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) {
1714 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
1715 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1716 }
1717 }
1718
1719 }
1720
1721 SiS_Pr->SiS_VBInfo &= ~SetPALTV;
1722}
1723
1724/*********************************************/
1725/* GET LCD INFO */
1726/*********************************************/
1727
1728static unsigned short
1729SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr)
1730{
1731 unsigned short temp = SiS_Pr->SiS_LCDResInfo;
1732 /* Translate my LCDResInfo to BIOS value */
1733 switch(temp) {
1734 case Panel_1280x768_2: temp = Panel_1280x768; break;
1735 case Panel_1280x800_2: temp = Panel_1280x800; break;
1736 case Panel_1280x854: temp = Panel661_1280x854; break;
1737 }
1738 return temp;
1739}
1740
1741static void
1742SiS_GetLCDInfoBIOS(struct SiS_Private *SiS_Pr)
1743{
1744#ifdef CONFIG_FB_SIS_315
1745 unsigned char *ROMAddr;
1746 unsigned short temp;
1747
1748 if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
1749 if((temp = SISGETROMW(6)) != SiS_Pr->PanelHT) {
1750 SiS_Pr->SiS_NeedRomModeData = true;
1751 SiS_Pr->PanelHT = temp;
1752 }
1753 if((temp = SISGETROMW(8)) != SiS_Pr->PanelVT) {
1754 SiS_Pr->SiS_NeedRomModeData = true;
1755 SiS_Pr->PanelVT = temp;
1756 }
1757 SiS_Pr->PanelHRS = SISGETROMW(10);
1758 SiS_Pr->PanelHRE = SISGETROMW(12);
1759 SiS_Pr->PanelVRS = SISGETROMW(14);
1760 SiS_Pr->PanelVRE = SISGETROMW(16);
1761 SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
1762 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].CLOCK =
1763 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].CLOCK = (unsigned short)((unsigned char)ROMAddr[18]);
1764 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2B =
1765 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_A = ROMAddr[19];
1766 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2C =
1767 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_B = ROMAddr[20];
1768
1769 }
1770#endif
1771}
1772
1773static void
1774SiS_CheckScaling(struct SiS_Private *SiS_Pr, unsigned short resinfo,
1775 const unsigned char *nonscalingmodes)
1776{
1777 int i = 0;
1778 while(nonscalingmodes[i] != 0xff) {
1779 if(nonscalingmodes[i++] == resinfo) {
1780 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ||
1781 (SiS_Pr->UsePanelScaler == -1)) {
1782 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1783 }
1784 break;
1785 }
1786 }
1787}
1788
1789void
1790SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
1791{
1792 unsigned short temp,modeflag,resinfo=0,modexres=0,modeyres=0;
1793 bool panelcanscale = false;
1794#ifdef CONFIG_FB_SIS_300
1795 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
1796 static const unsigned char SiS300SeriesLCDRes[] =
1797 { 0, 1, 2, 3, 7, 4, 5, 8,
1798 0, 0, 10, 0, 0, 0, 0, 15 };
1799#endif
1800#ifdef CONFIG_FB_SIS_315
1801 unsigned char *myptr = NULL;
1802#endif
1803
1804 SiS_Pr->SiS_LCDResInfo = 0;
1805 SiS_Pr->SiS_LCDTypeInfo = 0;
1806 SiS_Pr->SiS_LCDInfo = 0;
1807 SiS_Pr->PanelHRS = 999; /* HSync start */
1808 SiS_Pr->PanelHRE = 999; /* HSync end */
1809 SiS_Pr->PanelVRS = 999; /* VSync start */
1810 SiS_Pr->PanelVRE = 999; /* VSync end */
1811 SiS_Pr->SiS_NeedRomModeData = false;
1812
1813 /* Alternative 1600x1200@60 timing for 1600x1200 LCDA */
1814 SiS_Pr->Alternate1600x1200 = false;
1815
1816 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return;
1817
1818 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
1819
1820 if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
1821 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1822 modexres = SiS_Pr->SiS_ModeResInfo[resinfo].HTotal;
1823 modeyres = SiS_Pr->SiS_ModeResInfo[resinfo].VTotal;
1824 }
1825
1826 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
1827
1828 /* For broken BIOSes: Assume 1024x768 */
1829 if(temp == 0) temp = 0x02;
1830
1831 if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
1832 SiS_Pr->SiS_LCDTypeInfo = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x7c) >> 2;
1833 } else if((SiS_Pr->ChipType < SIS_315H) || (SiS_Pr->ChipType >= SIS_661)) {
1834 SiS_Pr->SiS_LCDTypeInfo = temp >> 4;
1835 } else {
1836 SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1;
1837 }
1838 temp &= 0x0f;
1839#ifdef CONFIG_FB_SIS_300
1840 if(SiS_Pr->ChipType < SIS_315H) {
1841 /* Very old BIOSes only know 7 sizes (NetVista 2179, 1.01g) */
1842 if(SiS_Pr->SiS_VBType & VB_SIS301) {
1843 if(temp < 0x0f) temp &= 0x07;
1844 }
1845 /* Translate 300 series LCDRes to 315 series for unified usage */
1846 temp = SiS300SeriesLCDRes[temp];
1847 }
1848#endif
1849
1850 /* Translate to our internal types */
1851#ifdef CONFIG_FB_SIS_315
1852 if(SiS_Pr->ChipType == SIS_550) {
1853 if (temp == Panel310_1152x768) temp = Panel_320x240_2; /* Verified working */
1854 else if(temp == Panel310_320x240_2) temp = Panel_320x240_2;
1855 else if(temp == Panel310_320x240_3) temp = Panel_320x240_3;
1856 } else if(SiS_Pr->ChipType >= SIS_661) {
1857 if(temp == Panel661_1280x854) temp = Panel_1280x854;
1858 }
1859#endif
1860
1861 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { /* SiS LVDS */
1862 if(temp == Panel310_1280x768) {
1863 temp = Panel_1280x768_2;
1864 }
1865 if(SiS_Pr->SiS_ROMNew) {
1866 if(temp == Panel661_1280x800) {
1867 temp = Panel_1280x800_2;
1868 }
1869 }
1870 }
1871
1872 SiS_Pr->SiS_LCDResInfo = temp;
1873
1874#ifdef CONFIG_FB_SIS_300
1875 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1876 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
1877 SiS_Pr->SiS_LCDResInfo = Panel_Barco1366;
1878 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
1879 SiS_Pr->SiS_LCDResInfo = Panel_848x480;
1880 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL856) {
1881 SiS_Pr->SiS_LCDResInfo = Panel_856x480;
1882 }
1883 }
1884#endif
1885
1886 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1887 if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)
1888 SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMin301;
1889 } else {
1890 if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMinLVDS)
1891 SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS;
1892 }
1893
1894 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
1895 SiS_Pr->SiS_LCDInfo = temp & ~0x000e;
1896 /* Need temp below! */
1897
1898 /* These must/can't scale no matter what */
1899 switch(SiS_Pr->SiS_LCDResInfo) {
1900 case Panel_320x240_1:
1901 case Panel_320x240_2:
1902 case Panel_320x240_3:
1903 case Panel_1280x960:
1904 SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1905 break;
1906 case Panel_640x480:
1907 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1908 }
1909
1910 panelcanscale = (bool)(SiS_Pr->SiS_LCDInfo & DontExpandLCD);
1911
1912 if(!SiS_Pr->UsePanelScaler) SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1913 else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1914
1915 /* Dual link, Pass 1:1 BIOS default, etc. */
1916#ifdef CONFIG_FB_SIS_315
1917 if(SiS_Pr->ChipType >= SIS_661) {
1918 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1919 if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1920 }
1921 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1922 if(SiS_Pr->SiS_ROMNew) {
1923 if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1924 } else if((myptr = GetLCDStructPtr661(SiS_Pr))) {
1925 if(myptr[2] & 0x01) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1926 }
1927 }
1928 } else if(SiS_Pr->ChipType >= SIS_315H) {
1929 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1930 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1931 }
1932 if((SiS_Pr->SiS_ROMNew) && (!(SiS_Pr->PanelSelfDetected))) {
1933 SiS_Pr->SiS_LCDInfo &= ~(LCDRGB18Bit);
1934 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1935 if(temp & 0x01) SiS_Pr->SiS_LCDInfo |= LCDRGB18Bit;
1936 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1937 if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1938 }
1939 } else if(!(SiS_Pr->SiS_ROMNew)) {
1940 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1941 if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) &&
1942 (SiS_Pr->SiS_LCDResInfo == Panel_1024x768)) {
1943 SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1944 }
1945 if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
1946 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
1947 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
1948 (SiS_Pr->SiS_LCDResInfo == Panel_1680x1050)) {
1949 SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1950 }
1951 }
1952 }
1953 }
1954#endif
1955
1956 /* Pass 1:1 */
1957 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
1958 /* Always center screen on LVDS (if scaling is disabled) */
1959 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1960 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
1961 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
1962 /* Always center screen on SiS LVDS (if scaling is disabled) */
1963 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1964 } else {
1965 /* By default, pass 1:1 on SiS TMDS (if scaling is supported) */
1966 if(panelcanscale) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1967 if(SiS_Pr->CenterScreen == 1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1968 }
1969 }
1970
1971 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1972 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1973
1974 switch(SiS_Pr->SiS_LCDResInfo) {
1975 case Panel_320x240_1:
1976 case Panel_320x240_2:
1977 case Panel_320x240_3: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
1978 SiS_Pr->PanelVRS = 24; SiS_Pr->PanelVRE = 3;
1979 SiS_Pr->PanelVCLKIdx300 = VCLK28;
1980 SiS_Pr->PanelVCLKIdx315 = VCLK28;
1981 break;
1982 case Panel_640x480: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
1983 SiS_Pr->PanelVRE = 3;
1984 SiS_Pr->PanelVCLKIdx300 = VCLK28;
1985 SiS_Pr->PanelVCLKIdx315 = VCLK28;
1986 break;
1987 case Panel_800x600: SiS_Pr->PanelXRes = 800; SiS_Pr->PanelYRes = 600;
1988 SiS_Pr->PanelHT = 1056; SiS_Pr->PanelVT = 628;
1989 SiS_Pr->PanelHRS = 40; SiS_Pr->PanelHRE = 128;
1990 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 4;
1991 SiS_Pr->PanelVCLKIdx300 = VCLK40;
1992 SiS_Pr->PanelVCLKIdx315 = VCLK40;
1993 break;
1994 case Panel_1024x600: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 600;
1995 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 800;
1996 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
1997 SiS_Pr->PanelVRS = 2 /* 88 */ ; SiS_Pr->PanelVRE = 6;
1998 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1999 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
2000 break;
2001 case Panel_1024x768: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768;
2002 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
2003 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
2004 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
2005 if(SiS_Pr->ChipType < SIS_315H) {
2006 SiS_Pr->PanelHRS = 23;
2007 SiS_Pr->PanelVRE = 5;
2008 }
2009 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
2010 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
2011 SiS_GetLCDInfoBIOS(SiS_Pr);
2012 break;
2013 case Panel_1152x768: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 768;
2014 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
2015 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
2016 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
2017 if(SiS_Pr->ChipType < SIS_315H) {
2018 SiS_Pr->PanelHRS = 23;
2019 SiS_Pr->PanelVRE = 5;
2020 }
2021 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
2022 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
2023 break;
2024 case Panel_1152x864: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 864;
2025 break;
2026 case Panel_1280x720: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 720;
2027 SiS_Pr->PanelHT = 1650; SiS_Pr->PanelVT = 750;
2028 SiS_Pr->PanelHRS = 110; SiS_Pr->PanelHRE = 40;
2029 SiS_Pr->PanelVRS = 5; SiS_Pr->PanelVRE = 5;
2030 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x720;
2031 /* Data above for TMDS (projector); get from BIOS for LVDS */
2032 SiS_GetLCDInfoBIOS(SiS_Pr);
2033 break;
2034 case Panel_1280x768: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768;
2035 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2036 SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 806;
2037 SiS_Pr->PanelVCLKIdx300 = VCLK81_300; /* ? */
2038 SiS_Pr->PanelVCLKIdx315 = VCLK81_315; /* ? */
2039 } else {
2040 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 802;
2041 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
2042 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
2043 SiS_Pr->PanelVCLKIdx300 = VCLK81_300;
2044 SiS_Pr->PanelVCLKIdx315 = VCLK81_315;
2045 }
2046 break;
2047 case Panel_1280x768_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768;
2048 SiS_Pr->PanelHT = 1660; SiS_Pr->PanelVT = 806;
2049 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
2050 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
2051 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_2;
2052 SiS_GetLCDInfoBIOS(SiS_Pr);
2053 break;
2054 case Panel_1280x800: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800;
2055 SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 816;
2056 SiS_Pr->PanelHRS = 21; SiS_Pr->PanelHRE = 24;
2057 SiS_Pr->PanelVRS = 4; SiS_Pr->PanelVRE = 3;
2058 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315;
2059 SiS_GetLCDInfoBIOS(SiS_Pr);
2060 break;
2061 case Panel_1280x800_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800;
2062 SiS_Pr->PanelHT = 1552; SiS_Pr->PanelVT = 812;
2063 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
2064 SiS_Pr->PanelVRS = 4; SiS_Pr->PanelVRE = 3;
2065 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315_2;
2066 SiS_GetLCDInfoBIOS(SiS_Pr);
2067 break;
2068 case Panel_1280x854: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 854;
2069 SiS_Pr->PanelHT = 1664; SiS_Pr->PanelVT = 861;
2070 SiS_Pr->PanelHRS = 16; SiS_Pr->PanelHRE = 112;
2071 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
2072 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x854;
2073 SiS_GetLCDInfoBIOS(SiS_Pr);
2074 break;
2075 case Panel_1280x960: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 960;
2076 SiS_Pr->PanelHT = 1800; SiS_Pr->PanelVT = 1000;
2077 SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
2078 SiS_Pr->PanelVCLKIdx315 = VCLK108_3_315;
2079 if(resinfo == SIS_RI_1280x1024) {
2080 SiS_Pr->PanelVCLKIdx300 = VCLK100_300;
2081 SiS_Pr->PanelVCLKIdx315 = VCLK100_315;
2082 }
2083 break;
2084 case Panel_1280x1024: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024;
2085 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
2086 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
2087 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
2088 SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
2089 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
2090 SiS_GetLCDInfoBIOS(SiS_Pr);
2091 break;
2092 case Panel_1400x1050: SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050;
2093 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
2094 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
2095 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
2096 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
2097 SiS_GetLCDInfoBIOS(SiS_Pr);
2098 break;
2099 case Panel_1600x1200: SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200;
2100 SiS_Pr->PanelHT = 2160; SiS_Pr->PanelVT = 1250;
2101 SiS_Pr->PanelHRS = 64; SiS_Pr->PanelHRE = 192;
2102 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
2103 SiS_Pr->PanelVCLKIdx315 = VCLK162_315;
2104 if(SiS_Pr->SiS_VBType & VB_SISTMDSLCDA) {
2105 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
2106 SiS_Pr->PanelHT = 1760; SiS_Pr->PanelVT = 1235;
2107 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 32;
2108 SiS_Pr->PanelVRS = 2; SiS_Pr->PanelVRE = 4;
2109 SiS_Pr->PanelVCLKIdx315 = VCLK130_315;
2110 SiS_Pr->Alternate1600x1200 = true;
2111 }
2112 } else if(SiS_Pr->SiS_IF_DEF_LVDS) {
2113 SiS_Pr->PanelHT = 2048; SiS_Pr->PanelVT = 1320;
2114 SiS_Pr->PanelHRS = SiS_Pr->PanelHRE = 999;
2115 SiS_Pr->PanelVRS = SiS_Pr->PanelVRE = 999;
2116 }
2117 SiS_GetLCDInfoBIOS(SiS_Pr);
2118 break;
2119 case Panel_1680x1050: SiS_Pr->PanelXRes = 1680; SiS_Pr->PanelYRes = 1050;
2120 SiS_Pr->PanelHT = 1900; SiS_Pr->PanelVT = 1066;
2121 SiS_Pr->PanelHRS = 26; SiS_Pr->PanelHRE = 76;
2122 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
2123 SiS_Pr->PanelVCLKIdx315 = VCLK121_315;
2124 SiS_GetLCDInfoBIOS(SiS_Pr);
2125 break;
2126 case Panel_Barco1366: SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024;
2127 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
2128 break;
2129 case Panel_848x480: SiS_Pr->PanelXRes = 848; SiS_Pr->PanelYRes = 480;
2130 SiS_Pr->PanelHT = 1088; SiS_Pr->PanelVT = 525;
2131 break;
2132 case Panel_856x480: SiS_Pr->PanelXRes = 856; SiS_Pr->PanelYRes = 480;
2133 SiS_Pr->PanelHT = 1088; SiS_Pr->PanelVT = 525;
2134 break;
2135 case Panel_Custom: SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX;
2136 SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY;
2137 SiS_Pr->PanelHT = SiS_Pr->CHTotal;
2138 SiS_Pr->PanelVT = SiS_Pr->CVTotal;
2139 if(SiS_Pr->CP_PreferredIndex != -1) {
2140 SiS_Pr->PanelXRes = SiS_Pr->CP_HDisplay[SiS_Pr->CP_PreferredIndex];
2141 SiS_Pr->PanelYRes = SiS_Pr->CP_VDisplay[SiS_Pr->CP_PreferredIndex];
2142 SiS_Pr->PanelHT = SiS_Pr->CP_HTotal[SiS_Pr->CP_PreferredIndex];
2143 SiS_Pr->PanelVT = SiS_Pr->CP_VTotal[SiS_Pr->CP_PreferredIndex];
2144 SiS_Pr->PanelHRS = SiS_Pr->CP_HSyncStart[SiS_Pr->CP_PreferredIndex];
2145 SiS_Pr->PanelHRE = SiS_Pr->CP_HSyncEnd[SiS_Pr->CP_PreferredIndex];
2146 SiS_Pr->PanelVRS = SiS_Pr->CP_VSyncStart[SiS_Pr->CP_PreferredIndex];
2147 SiS_Pr->PanelVRE = SiS_Pr->CP_VSyncEnd[SiS_Pr->CP_PreferredIndex];
2148 SiS_Pr->PanelHRS -= SiS_Pr->PanelXRes;
2149 SiS_Pr->PanelHRE -= SiS_Pr->PanelHRS;
2150 SiS_Pr->PanelVRS -= SiS_Pr->PanelYRes;
2151 SiS_Pr->PanelVRE -= SiS_Pr->PanelVRS;
2152 if(SiS_Pr->CP_PrefClock) {
2153 int idx;
2154 SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
2155 SiS_Pr->PanelVCLKIdx300 = VCLK_CUSTOM_300;
2156 if(SiS_Pr->ChipType < SIS_315H) idx = VCLK_CUSTOM_300;
2157 else idx = VCLK_CUSTOM_315;
2158 SiS_Pr->SiS_VCLKData[idx].CLOCK =
2159 SiS_Pr->SiS_VBVCLKData[idx].CLOCK = SiS_Pr->CP_PrefClock;
2160 SiS_Pr->SiS_VCLKData[idx].SR2B =
2161 SiS_Pr->SiS_VBVCLKData[idx].Part4_A = SiS_Pr->CP_PrefSR2B;
2162 SiS_Pr->SiS_VCLKData[idx].SR2C =
2163 SiS_Pr->SiS_VBVCLKData[idx].Part4_B = SiS_Pr->CP_PrefSR2C;
2164 }
2165 }
2166 break;
2167 default: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768;
2168 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
2169 break;
2170 }
2171
2172 /* Special cases */
2173 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
2174 (SiS_Pr->SiS_IF_DEF_DSTN) ||
2175 (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
2176 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
2177 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
2178 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
2179 SiS_Pr->PanelHRS = 999;
2180 SiS_Pr->PanelHRE = 999;
2181 }
2182
2183 if( (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
2184 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
2185 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
2186 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
2187 SiS_Pr->PanelVRS = 999;
2188 SiS_Pr->PanelVRE = 999;
2189 }
2190
2191 /* DontExpand overrule */
2192 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
2193
2194 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (modeflag & NoSupportLCDScale)) {
2195 /* No scaling for this mode on any panel (LCD=CRT2)*/
2196 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2197 }
2198
2199 switch(SiS_Pr->SiS_LCDResInfo) {
2200
2201 case Panel_Custom:
2202 case Panel_1152x864:
2203 case Panel_1280x768: /* TMDS only */
2204 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2205 break;
2206
2207 case Panel_800x600: {
2208 static const unsigned char nonscalingmodes[] = {
2209 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, 0xff
2210 };
2211 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2212 break;
2213 }
2214 case Panel_1024x768: {
2215 static const unsigned char nonscalingmodes[] = {
2216 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2217 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2218 0xff
2219 };
2220 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2221 break;
2222 }
2223 case Panel_1280x720: {
2224 static const unsigned char nonscalingmodes[] = {
2225 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2226 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2227 0xff
2228 };
2229 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2230 if(SiS_Pr->PanelHT == 1650) {
2231 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2232 }
2233 break;
2234 }
2235 case Panel_1280x768_2: { /* LVDS only */
2236 static const unsigned char nonscalingmodes[] = {
2237 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2238 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2239 SIS_RI_1152x768,0xff
2240 };
2241 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2242 switch(resinfo) {
2243 case SIS_RI_1280x720: if(SiS_Pr->UsePanelScaler == -1) {
2244 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2245 }
2246 break;
2247 }
2248 break;
2249 }
2250 case Panel_1280x800: { /* SiS TMDS special (Averatec 6200 series) */
2251 static const unsigned char nonscalingmodes[] = {
2252 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2253 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2254 SIS_RI_1152x768,SIS_RI_1280x720,SIS_RI_1280x768,0xff
2255 };
2256 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2257 break;
2258 }
2259 case Panel_1280x800_2: { /* SiS LVDS */
2260 static const unsigned char nonscalingmodes[] = {
2261 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2262 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2263 SIS_RI_1152x768,0xff
2264 };
2265 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2266 switch(resinfo) {
2267 case SIS_RI_1280x720:
2268 case SIS_RI_1280x768: if(SiS_Pr->UsePanelScaler == -1) {
2269 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2270 }
2271 break;
2272 }
2273 break;
2274 }
2275 case Panel_1280x854: { /* SiS LVDS */
2276 static const unsigned char nonscalingmodes[] = {
2277 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2278 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2279 SIS_RI_1152x768,0xff
2280 };
2281 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2282 switch(resinfo) {
2283 case SIS_RI_1280x720:
2284 case SIS_RI_1280x768:
2285 case SIS_RI_1280x800: if(SiS_Pr->UsePanelScaler == -1) {
2286 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2287 }
2288 break;
2289 }
2290 break;
2291 }
2292 case Panel_1280x960: {
2293 static const unsigned char nonscalingmodes[] = {
2294 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2295 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2296 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2297 SIS_RI_1280x854,0xff
2298 };
2299 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2300 break;
2301 }
2302 case Panel_1280x1024: {
2303 static const unsigned char nonscalingmodes[] = {
2304 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2305 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2306 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2307 SIS_RI_1280x854,SIS_RI_1280x960,0xff
2308 };
2309 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2310 break;
2311 }
2312 case Panel_1400x1050: {
2313 static const unsigned char nonscalingmodes[] = {
2314 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2315 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2316 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x768,SIS_RI_1280x800,SIS_RI_1280x854,
2317 SIS_RI_1280x960,0xff
2318 };
2319 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2320 switch(resinfo) {
2321 case SIS_RI_1280x720: if(SiS_Pr->UsePanelScaler == -1) {
2322 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2323 }
2324 break;
2325 case SIS_RI_1280x1024: SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2326 break;
2327 }
2328 break;
2329 }
2330 case Panel_1600x1200: {
2331 static const unsigned char nonscalingmodes[] = {
2332 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2333 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2334 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2335 SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,SIS_RI_1360x1024,0xff
2336 };
2337 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2338 break;
2339 }
2340 case Panel_1680x1050: {
2341 static const unsigned char nonscalingmodes[] = {
2342 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2343 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2344 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,
2345 SIS_RI_1360x1024,0xff
2346 };
2347 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2348 break;
2349 }
2350 }
2351 }
2352
2353#ifdef CONFIG_FB_SIS_300
2354 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2355 if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
2356 SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20; /* neg h/v sync, RGB24(D0 = 0) */
2357 }
2358 }
2359
2360 if(SiS_Pr->ChipType < SIS_315H) {
2361 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2362 if(SiS_Pr->SiS_UseROM) {
2363 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
2364 if(!(ROMAddr[0x235] & 0x02)) {
2365 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2366 }
2367 }
2368 }
2369 } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2370 if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
2371 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2372 }
2373 }
2374 }
2375#endif
2376
2377 /* Special cases */
2378
2379 if(modexres == SiS_Pr->PanelXRes && modeyres == SiS_Pr->PanelYRes) {
2380 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2381 }
2382
2383 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
2384 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2385 }
2386
2387 switch(SiS_Pr->SiS_LCDResInfo) {
2388 case Panel_640x480:
2389 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2390 break;
2391 case Panel_1280x800:
2392 /* Don't pass 1:1 by default (TMDS special) */
2393 if(SiS_Pr->CenterScreen == -1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2394 break;
2395 case Panel_1280x960:
2396 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2397 break;
2398 case Panel_Custom:
2399 if((!SiS_Pr->CP_PrefClock) ||
2400 (modexres > SiS_Pr->PanelXRes) || (modeyres > SiS_Pr->PanelYRes)) {
2401 SiS_Pr->SiS_LCDInfo |= LCDPass11;
2402 }
2403 break;
2404 }
2405
2406 if((SiS_Pr->UseCustomMode) || (SiS_Pr->SiS_CustomT == CUT_UNKNOWNLCD)) {
2407 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2408 }
2409
2410 /* (In)validate LCDPass11 flag */
2411 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2412 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2413 }
2414
2415 /* LVDS DDA */
2416 if(!((SiS_Pr->ChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
2417
2418 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
2419 if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
2420 if(ModeNo == 0x12) {
2421 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
2422 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2423 }
2424 } else if(ModeNo > 0x13) {
2425 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
2426 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2427 if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) {
2428 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2429 }
2430 }
2431 }
2432 }
2433 }
2434 }
2435
2436 if(modeflag & HalfDCLK) {
2437 if(SiS_Pr->SiS_IF_DEF_TRUMPION == 1) {
2438 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2439 } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
2440 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2441 } else if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) {
2442 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2443 } else if(ModeNo > 0x13) {
2444 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
2445 if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2446 } else if(SiS_Pr->SiS_LCDResInfo == Panel_800x600) {
2447 if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2448 }
2449 }
2450 }
2451
2452 }
2453
2454 /* VESA timing */
2455 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2456 if(SiS_Pr->SiS_VBInfo & SetNotSimuMode) {
2457 SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2458 }
2459 } else {
2460 SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2461 }
2462
2463#if 0
2464 printk(KERN_DEBUG "sisfb: (LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n",
2465 SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo);
2466#endif
2467}
2468
2469/*********************************************/
2470/* GET VCLK */
2471/*********************************************/
2472
2473unsigned short
2474SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
2475 unsigned short RefreshRateTableIndex)
2476{
2477 unsigned short CRT2Index, VCLKIndex = 0, VCLKIndexGEN = 0, VCLKIndexGENCRT = 0;
2478 unsigned short resinfo, tempbx;
2479 const unsigned char *CHTVVCLKPtr = NULL;
2480
2481 if(ModeNo <= 0x13) {
2482 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
2483 CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2484 VCLKIndexGEN = (SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)) >> 2) & 0x03;
2485 VCLKIndexGENCRT = VCLKIndexGEN;
2486 } else {
2487 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2488 CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2489 VCLKIndexGEN = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
2490 VCLKIndexGENCRT = SiS_GetRefCRTVCLK(SiS_Pr, Index: RefreshRateTableIndex,
2491 UseWide: (SiS_Pr->SiS_SetFlag & ProgrammingCRT2) ? SiS_Pr->SiS_UseWideCRT2 : SiS_Pr->SiS_UseWide);
2492 }
2493
2494 if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 30x/B/LV */
2495
2496 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2497
2498 CRT2Index >>= 6;
2499 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /* LCD */
2500
2501 if(SiS_Pr->ChipType < SIS_315H) {
2502 VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2503 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2504 VCLKIndex = VCLKIndexGEN;
2505 }
2506 } else {
2507 VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2508 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2509 switch(resinfo) {
2510 /* Correct those whose IndexGEN doesn't match VBVCLK array */
2511 case SIS_RI_720x480: VCLKIndex = VCLK_720x480; break;
2512 case SIS_RI_720x576: VCLKIndex = VCLK_720x576; break;
2513 case SIS_RI_768x576: VCLKIndex = VCLK_768x576; break;
2514 case SIS_RI_848x480: VCLKIndex = VCLK_848x480; break;
2515 case SIS_RI_856x480: VCLKIndex = VCLK_856x480; break;
2516 case SIS_RI_800x480: VCLKIndex = VCLK_800x480; break;
2517 case SIS_RI_1024x576: VCLKIndex = VCLK_1024x576; break;
2518 case SIS_RI_1152x864: VCLKIndex = VCLK_1152x864; break;
2519 case SIS_RI_1280x720: VCLKIndex = VCLK_1280x720; break;
2520 case SIS_RI_1360x768: VCLKIndex = VCLK_1360x768; break;
2521 default: VCLKIndex = VCLKIndexGEN;
2522 }
2523
2524 if(ModeNo <= 0x13) {
2525 if(SiS_Pr->ChipType <= SIS_315PRO) {
2526 if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
2527 } else {
2528 if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x00;
2529 }
2530 }
2531 if(SiS_Pr->ChipType <= SIS_315PRO) {
2532 if(VCLKIndex == 0) VCLKIndex = 0x41;
2533 if(VCLKIndex == 1) VCLKIndex = 0x43;
2534 if(VCLKIndex == 4) VCLKIndex = 0x44;
2535 }
2536 }
2537 }
2538
2539 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* TV */
2540
2541 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
2542 if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = HiTVVCLKDIV2;
2543 else VCLKIndex = HiTVVCLK;
2544 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) VCLKIndex = HiTVSimuVCLK;
2545 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) VCLKIndex = YPbPr750pVCLK;
2546 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) VCLKIndex = TVVCLKDIV2;
2547 else if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = TVVCLKDIV2;
2548 else VCLKIndex = TVVCLK;
2549
2550 if(SiS_Pr->ChipType < SIS_315H) VCLKIndex += TVCLKBASE_300;
2551 else VCLKIndex += TVCLKBASE_315;
2552
2553 } else { /* VGA2 */
2554
2555 VCLKIndex = VCLKIndexGENCRT;
2556 if(SiS_Pr->ChipType < SIS_315H) {
2557 if(ModeNo > 0x13) {
2558 if( (SiS_Pr->ChipType == SIS_630) &&
2559 (SiS_Pr->ChipRevision >= 0x30)) {
2560 if(VCLKIndex == 0x14) VCLKIndex = 0x34;
2561 }
2562 /* Better VGA2 clock for 1280x1024@75 */
2563 if(VCLKIndex == 0x17) VCLKIndex = 0x45;
2564 }
2565 }
2566 }
2567
2568 } else { /* If not programming CRT2 */
2569
2570 VCLKIndex = VCLKIndexGENCRT;
2571 if(SiS_Pr->ChipType < SIS_315H) {
2572 if(ModeNo > 0x13) {
2573 if( (SiS_Pr->ChipType != SIS_630) &&
2574 (SiS_Pr->ChipType != SIS_300) ) {
2575 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2576 }
2577 }
2578 }
2579 }
2580
2581 } else { /* LVDS */
2582
2583 VCLKIndex = CRT2Index;
2584
2585 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2586
2587 if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
2588
2589 VCLKIndex &= 0x1f;
2590 tempbx = 0;
2591 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2592 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2593 tempbx += 2;
2594 if(SiS_Pr->SiS_ModeType > ModeVGA) {
2595 if(SiS_Pr->SiS_CHSOverScan) tempbx = 8;
2596 }
2597 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
2598 tempbx = 4;
2599 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2600 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
2601 tempbx = 6;
2602 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2603 }
2604 }
2605 switch(tempbx) {
2606 case 0: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUNTSC; break;
2607 case 1: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKONTSC; break;
2608 case 2: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPAL; break;
2609 case 3: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break;
2610 case 4: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALM; break;
2611 case 5: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALM; break;
2612 case 6: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALN; break;
2613 case 7: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALN; break;
2614 case 8: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKSOPAL; break;
2615 default: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break;
2616 }
2617 VCLKIndex = CHTVVCLKPtr[VCLKIndex];
2618
2619 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2620
2621 if(SiS_Pr->ChipType < SIS_315H) {
2622 VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2623 } else {
2624 VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2625 }
2626
2627#ifdef CONFIG_FB_SIS_300
2628 /* Special Timing: Barco iQ Pro R series */
2629 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) VCLKIndex = 0x44;
2630
2631 /* Special Timing: 848x480 and 856x480 parallel lvds panels */
2632 if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
2633 if(SiS_Pr->ChipType < SIS_315H) {
2634 VCLKIndex = VCLK34_300;
2635 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2636 } else {
2637 VCLKIndex = VCLK34_315;
2638 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2639 }
2640 }
2641#endif
2642
2643 } else {
2644
2645 VCLKIndex = VCLKIndexGENCRT;
2646 if(SiS_Pr->ChipType < SIS_315H) {
2647 if(ModeNo > 0x13) {
2648 if( (SiS_Pr->ChipType == SIS_630) &&
2649 (SiS_Pr->ChipRevision >= 0x30) ) {
2650 if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
2651 }
2652 }
2653 }
2654 }
2655
2656 } else { /* if not programming CRT2 */
2657
2658 VCLKIndex = VCLKIndexGENCRT;
2659 if(SiS_Pr->ChipType < SIS_315H) {
2660 if(ModeNo > 0x13) {
2661 if( (SiS_Pr->ChipType != SIS_630) &&
2662 (SiS_Pr->ChipType != SIS_300) ) {
2663 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2664 }
2665#if 0
2666 if(SiS_Pr->ChipType == SIS_730) {
2667 if(VCLKIndex == 0x0b) VCLKIndex = 0x40; /* 1024x768-70 */
2668 if(VCLKIndex == 0x0d) VCLKIndex = 0x41; /* 1024x768-75 */
2669 }
2670#endif
2671 }
2672 }
2673
2674 }
2675
2676 }
2677
2678 return VCLKIndex;
2679}
2680
2681/*********************************************/
2682/* SET CRT2 MODE TYPE REGISTERS */
2683/*********************************************/
2684
2685static void
2686SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2687{
2688 unsigned short i, j, modeflag, tempah=0;
2689 short tempcl;
2690#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
2691 unsigned short tempbl;
2692#endif
2693#ifdef CONFIG_FB_SIS_315
2694 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
2695 unsigned short tempah2, tempbl2;
2696#endif
2697
2698 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
2699
2700 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
2701
2702 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40);
2703 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2E,0xF7);
2704
2705 } else {
2706
2707 for(i=0,j=4; i<3; i++,j++) SiS_SetReg(SiS_Pr->SiS_Part1Port,j,0);
2708 if(SiS_Pr->ChipType >= SIS_315H) {
2709 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0x7F);
2710 }
2711
2712 tempcl = SiS_Pr->SiS_ModeType;
2713
2714 if(SiS_Pr->ChipType < SIS_315H) {
2715
2716#ifdef CONFIG_FB_SIS_300 /* ---- 300 series ---- */
2717
2718 /* For 301BDH: (with LCD via LVDS) */
2719 if(SiS_Pr->SiS_VBType & VB_NoLCD) {
2720 tempbl = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32);
2721 tempbl &= 0xef;
2722 tempbl |= 0x02;
2723 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2724 tempbl |= 0x10;
2725 tempbl &= 0xfd;
2726 }
2727 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,tempbl);
2728 }
2729
2730 if(ModeNo > 0x13) {
2731 tempcl -= ModeVGA;
2732 if(tempcl >= 0) {
2733 tempah = ((0x10 >> tempcl) | 0x80);
2734 }
2735 } else tempah = 0x80;
2736
2737 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0xA0;
2738
2739#endif /* CONFIG_FB_SIS_300 */
2740
2741 } else {
2742
2743#ifdef CONFIG_FB_SIS_315 /* ------- 315/330 series ------ */
2744
2745 if(ModeNo > 0x13) {
2746 tempcl -= ModeVGA;
2747 if(tempcl >= 0) {
2748 tempah = (0x08 >> tempcl);
2749 if (tempah == 0) tempah = 1;
2750 tempah |= 0x40;
2751 }
2752 } else tempah = 0x40;
2753
2754 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50;
2755
2756#endif /* CONFIG_FB_SIS_315 */
2757
2758 }
2759
2760 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2761
2762 if(SiS_Pr->ChipType < SIS_315H) {
2763 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2764 } else {
2765#ifdef CONFIG_FB_SIS_315
2766 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2767 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2768 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
2769 if(IS_SIS740) {
2770 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2771 } else {
2772 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2773 }
2774 }
2775#endif
2776 }
2777
2778 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2779
2780 tempah = 0x01;
2781 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
2782 tempah |= 0x02;
2783 }
2784 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2785 tempah ^= 0x05;
2786 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
2787 tempah ^= 0x01;
2788 }
2789 }
2790
2791 if(SiS_Pr->ChipType < SIS_315H) {
2792
2793 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2794
2795 tempah = (tempah << 5) & 0xFF;
2796 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2797 tempah = (tempah >> 5) & 0xFF;
2798
2799 } else {
2800
2801 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x08;
2802 else if(!(SiS_IsDualEdge(SiS_Pr))) tempah |= 0x08;
2803 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF0,tempah);
2804 tempah &= ~0x08;
2805
2806 }
2807
2808 if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
2809 tempah |= 0x10;
2810 }
2811
2812 tempah |= 0x80;
2813 if(SiS_Pr->SiS_VBType & VB_SIS301) {
2814 if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah &= ~0x80;
2815 }
2816
2817 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2818 if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p))) {
2819 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2820 tempah |= 0x20;
2821 }
2822 }
2823 }
2824
2825 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah);
2826
2827 tempah = 0x80;
2828 if(SiS_Pr->SiS_VBType & VB_SIS301) {
2829 if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah = 0;
2830 }
2831
2832 if(SiS_IsDualLink(SiS_Pr)) tempah |= 0x40;
2833
2834 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2835 if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) {
2836 tempah |= 0x40;
2837 }
2838 }
2839
2840 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0C,tempah);
2841
2842 } else { /* LVDS */
2843
2844 if(SiS_Pr->ChipType >= SIS_315H) {
2845
2846#ifdef CONFIG_FB_SIS_315
2847 /* LVDS can only be slave in 8bpp modes */
2848 tempah = 0x80;
2849 if((modeflag & CRT2Mode) && (SiS_Pr->SiS_ModeType > ModeVGA)) {
2850 if(SiS_Pr->SiS_VBInfo & DriverMode) {
2851 tempah |= 0x02;
2852 }
2853 }
2854
2855 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) tempah |= 0x02;
2856
2857 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempah ^= 0x01;
2858
2859 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 1;
2860
2861 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah);
2862#endif
2863
2864 } else {
2865
2866#ifdef CONFIG_FB_SIS_300
2867 tempah = 0;
2868 if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
2869 tempah |= 0x02;
2870 }
2871 tempah <<= 5;
2872
2873 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2874
2875 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2876#endif
2877
2878 }
2879
2880 }
2881
2882 } /* LCDA */
2883
2884 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2885
2886 if(SiS_Pr->ChipType >= SIS_315H) {
2887
2888#ifdef CONFIG_FB_SIS_315
2889 /* unsigned char bridgerev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01); */
2890
2891 /* The following is nearly unpreditable and varies from machine
2892 * to machine. Especially the 301DH seems to be a real trouble
2893 * maker. Some BIOSes simply set the registers (like in the
2894 * NoLCD-if-statements here), some set them according to the
2895 * LCDA stuff. It is very likely that some machines are not
2896 * treated correctly in the following, very case-orientated
2897 * code. What do I do then...?
2898 */
2899
2900 /* 740 variants match for 30xB, 301B-DH, 30xLV */
2901
2902 if(!(IS_SIS740)) {
2903 tempah = 0x04; /* For all bridges */
2904 tempbl = 0xfb;
2905 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2906 tempah = 0x00;
2907 if(SiS_IsDualEdge(SiS_Pr)) {
2908 tempbl = 0xff;
2909 }
2910 }
2911 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2912 }
2913
2914 /* The following two are responsible for eventually wrong colors
2915 * in TV output. The DH (VB_NoLCD) conditions are unknown; the
2916 * b0 was found in some 651 machine (Pim; P4_23=0xe5); the b1 version
2917 * in a 650 box (Jake). What is the criteria?
2918 * Addendum: Another combination 651+301B-DH(b1) (Rapo) needs same
2919 * treatment like the 651+301B-DH(b0) case. Seems more to be the
2920 * chipset than the bridge revision.
2921 */
2922
2923 if((IS_SIS740) || (SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
2924 tempah = 0x30;
2925 tempbl = 0xc0;
2926 if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2927 ((SiS_Pr->SiS_ROMNew) && (!(ROMAddr[0x5b] & 0x04)))) {
2928 tempah = 0x00;
2929 tempbl = 0x00;
2930 }
2931 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,tempah);
2932 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,tempbl);
2933 } else if(SiS_Pr->SiS_VBType & VB_SIS301) {
2934 /* Fixes "TV-blue-bug" on 315+301 */
2935 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xcf); /* For 301 */
2936 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2937 } else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
2938 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30); /* For 30xLV */
2939 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);
2940 } else if(SiS_Pr->SiS_VBType & VB_NoLCD) { /* For 301B-DH */
2941 tempah = 0x30; tempah2 = 0xc0;
2942 tempbl = 0xcf; tempbl2 = 0x3f;
2943 if(SiS_Pr->SiS_TVBlue == 0) {
2944 tempah = tempah2 = 0x00;
2945 } else if(SiS_Pr->SiS_TVBlue == -1) {
2946 /* Set on 651/M650, clear on 315/650 */
2947 if(!(IS_SIS65x)) /* (bridgerev != 0xb0) */ {
2948 tempah = tempah2 = 0x00;
2949 }
2950 }
2951 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2952 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2953 } else {
2954 tempah = 0x30; tempah2 = 0xc0; /* For 30xB, 301C */
2955 tempbl = 0xcf; tempbl2 = 0x3f;
2956 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2957 tempah = tempah2 = 0x00;
2958 if(SiS_IsDualEdge(SiS_Pr)) {
2959 tempbl = tempbl2 = 0xff;
2960 }
2961 }
2962 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2963 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2964 }
2965
2966 if(IS_SIS740) {
2967 tempah = 0x80;
2968 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x00;
2969 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,0x7f,tempah);
2970 } else {
2971 tempah = 0x00;
2972 tempbl = 0x7f;
2973 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2974 tempbl = 0xff;
2975 if(!(SiS_IsDualEdge(SiS_Pr))) tempah = 0x80;
2976 }
2977 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
2978 }
2979
2980#endif /* CONFIG_FB_SIS_315 */
2981
2982 } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2983
2984#ifdef CONFIG_FB_SIS_300
2985 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2986
2987 if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2988 ((SiS_Pr->SiS_VBType & VB_NoLCD) &&
2989 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD))) {
2990 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x23,0x7F);
2991 } else {
2992 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x23,0x80);
2993 }
2994#endif
2995
2996 }
2997
2998 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2999 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x0D,0x80);
3000 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
3001 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3A,0xC0);
3002 }
3003 }
3004
3005 } else { /* LVDS */
3006
3007#ifdef CONFIG_FB_SIS_315
3008 if(SiS_Pr->ChipType >= SIS_315H) {
3009
3010 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
3011
3012 tempah = 0x04;
3013 tempbl = 0xfb;
3014 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3015 tempah = 0x00;
3016 if(SiS_IsDualEdge(SiS_Pr)) tempbl = 0xff;
3017 }
3018 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
3019
3020 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
3021 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
3022 }
3023
3024 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
3025
3026 } else if(SiS_Pr->ChipType == SIS_550) {
3027
3028 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
3029 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
3030
3031 }
3032
3033 }
3034#endif
3035
3036 }
3037
3038}
3039
3040/*********************************************/
3041/* GET RESOLUTION DATA */
3042/*********************************************/
3043
3044unsigned short
3045SiS_GetResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
3046{
3047 if(ModeNo <= 0x13)
3048 return ((unsigned short)SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo);
3049 else
3050 return ((unsigned short)SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO);
3051}
3052
3053static void
3054SiS_GetCRT2ResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
3055{
3056 unsigned short xres, yres, modeflag=0, resindex;
3057
3058 if(SiS_Pr->UseCustomMode) {
3059 xres = SiS_Pr->CHDisplay;
3060 if(SiS_Pr->CModeFlag & HalfDCLK) xres <<= 1;
3061 SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
3062 /* DoubleScanMode-check done in CheckCalcCustomMode()! */
3063 SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = SiS_Pr->CVDisplay;
3064 return;
3065 }
3066
3067 resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex);
3068
3069 if(ModeNo <= 0x13) {
3070 xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
3071 yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
3072 } else {
3073 xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
3074 yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
3075 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3076 }
3077
3078 if(!SiS_Pr->SiS_IF_DEF_DSTN && !SiS_Pr->SiS_IF_DEF_FSTN) {
3079
3080 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
3081 if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
3082 if(yres == 350) yres = 400;
3083 }
3084 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
3085 if(ModeNo == 0x12) yres = 400;
3086 }
3087 }
3088
3089 if(modeflag & HalfDCLK) xres <<= 1;
3090 if(modeflag & DoubleScanMode) yres <<= 1;
3091
3092 }
3093
3094 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
3095
3096 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3097 switch(SiS_Pr->SiS_LCDResInfo) {
3098 case Panel_1024x768:
3099 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
3100 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
3101 if(yres == 350) yres = 357;
3102 if(yres == 400) yres = 420;
3103 if(yres == 480) yres = 525;
3104 }
3105 }
3106 break;
3107 case Panel_1280x1024:
3108 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
3109 /* BIOS bug - does this regardless of scaling */
3110 if(yres == 400) yres = 405;
3111 }
3112 if(yres == 350) yres = 360;
3113 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
3114 if(yres == 360) yres = 375;
3115 }
3116 break;
3117 case Panel_1600x1200:
3118 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
3119 if(yres == 1024) yres = 1056;
3120 }
3121 break;
3122 }
3123 }
3124
3125 } else {
3126
3127 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3128 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVision)) {
3129 if(xres == 720) xres = 640;
3130 }
3131 } else if(xres == 720) xres = 640;
3132
3133 if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
3134 yres = 400;
3135 if(SiS_Pr->ChipType >= SIS_315H) {
3136 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
3137 } else {
3138 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
3139 }
3140 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) yres = 480;
3141 }
3142
3143 }
3144 SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
3145 SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
3146}
3147
3148/*********************************************/
3149/* GET CRT2 TIMING DATA */
3150/*********************************************/
3151
3152static void
3153SiS_GetCRT2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3154 unsigned short RefreshRateTableIndex, unsigned short *CRT2Index,
3155 unsigned short *ResIndex)
3156{
3157 unsigned short tempbx=0, tempal=0, resinfo=0;
3158
3159 if(ModeNo <= 0x13) {
3160 tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3161 } else {
3162 tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
3163 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
3164 }
3165
3166 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_IF_DEF_LVDS == 0)) {
3167
3168 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { /* LCD */
3169
3170 tempbx = SiS_Pr->SiS_LCDResInfo;
3171 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 32;
3172
3173 /* patch index */
3174 if(SiS_Pr->SiS_LCDResInfo == Panel_1680x1050) {
3175 if (resinfo == SIS_RI_1280x800) tempal = 9;
3176 else if(resinfo == SIS_RI_1400x1050) tempal = 11;
3177 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x800) ||
3178 (SiS_Pr->SiS_LCDResInfo == Panel_1280x800_2) ||
3179 (SiS_Pr->SiS_LCDResInfo == Panel_1280x854)) {
3180 if (resinfo == SIS_RI_1280x768) tempal = 9;
3181 }
3182
3183 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3184 /* Pass 1:1 only (center-screen handled outside) */
3185 /* This is never called for the panel's native resolution */
3186 /* since Pass1:1 will not be set in this case */
3187 tempbx = 100;
3188 if(ModeNo >= 0x13) {
3189 tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
3190 }
3191 }
3192
3193#ifdef CONFIG_FB_SIS_315
3194 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
3195 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
3196 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
3197 tempbx = 200;
3198 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
3199 }
3200 }
3201 }
3202#endif
3203
3204 } else { /* TV */
3205
3206 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
3207 /* if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_TVMode &= (~TVSetTVSimuMode); */
3208 tempbx = 2;
3209 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
3210 tempbx = 13;
3211 if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) tempbx = 14;
3212 }
3213 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3214 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempbx = 7;
3215 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempbx = 6;
3216 else tempbx = 5;
3217 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5;
3218 } else {
3219 if(SiS_Pr->SiS_TVMode & TVSetPAL) tempbx = 3;
3220 else tempbx = 4;
3221 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5;
3222 }
3223
3224 }
3225
3226 tempal &= 0x3F;
3227
3228 if(ModeNo > 0x13) {
3229 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) {
3230 switch(resinfo) {
3231 case SIS_RI_720x480:
3232 tempal = 6;
3233 if(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetPALN)) tempal = 9;
3234 break;
3235 case SIS_RI_720x576:
3236 case SIS_RI_768x576:
3237 case SIS_RI_1024x576: /* Not in NTSC or YPBPR mode (except 1080i)! */
3238 tempal = 6;
3239 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3240 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempal = 8;
3241 }
3242 break;
3243 case SIS_RI_800x480:
3244 tempal = 4;
3245 break;
3246 case SIS_RI_512x384:
3247 case SIS_RI_1024x768:
3248 tempal = 7;
3249 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3250 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempal = 8;
3251 }
3252 break;
3253 case SIS_RI_1280x720:
3254 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3255 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempal = 9;
3256 }
3257 break;
3258 }
3259 }
3260 }
3261
3262 *CRT2Index = tempbx;
3263 *ResIndex = tempal;
3264
3265 } else { /* LVDS, 301B-DH (if running on LCD) */
3266
3267 tempbx = 0;
3268 if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
3269
3270 tempbx = 90;
3271 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
3272 tempbx = 92;
3273 if(SiS_Pr->SiS_ModeType > ModeVGA) {
3274 if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
3275 }
3276 if(SiS_Pr->SiS_TVMode & TVSetPALM) tempbx = 94;
3277 else if(SiS_Pr->SiS_TVMode & TVSetPALN) tempbx = 96;
3278 }
3279 if(tempbx != 99) {
3280 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx++;
3281 }
3282
3283 } else {
3284
3285 switch(SiS_Pr->SiS_LCDResInfo) {
3286 case Panel_640x480: tempbx = 12; break;
3287 case Panel_320x240_1: tempbx = 10; break;
3288 case Panel_320x240_2:
3289 case Panel_320x240_3: tempbx = 14; break;
3290 case Panel_800x600: tempbx = 16; break;
3291 case Panel_1024x600: tempbx = 18; break;
3292 case Panel_1152x768:
3293 case Panel_1024x768: tempbx = 20; break;
3294 case Panel_1280x768: tempbx = 22; break;
3295 case Panel_1280x1024: tempbx = 24; break;
3296 case Panel_1400x1050: tempbx = 26; break;
3297 case Panel_1600x1200: tempbx = 28; break;
3298#ifdef CONFIG_FB_SIS_300
3299 case Panel_Barco1366: tempbx = 80; break;
3300#endif
3301 }
3302
3303 switch(SiS_Pr->SiS_LCDResInfo) {
3304 case Panel_320x240_1:
3305 case Panel_320x240_2:
3306 case Panel_320x240_3:
3307 case Panel_640x480:
3308 break;
3309 default:
3310 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3311 }
3312
3313 if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempbx = 30;
3314
3315#ifdef CONFIG_FB_SIS_300
3316 if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
3317 tempbx = 82;
3318 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3319 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
3320 tempbx = 84;
3321 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3322 }
3323#endif
3324
3325 }
3326
3327 (*CRT2Index) = tempbx;
3328 (*ResIndex) = tempal & 0x1F;
3329 }
3330}
3331
3332static void
3333SiS_GetRAMDAC2DATA(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3334 unsigned short RefreshRateTableIndex)
3335{
3336 unsigned short tempax=0, tempbx=0, index, dotclock;
3337 unsigned short temp1=0, modeflag=0, tempcx=0;
3338
3339 SiS_Pr->SiS_RVBHCMAX = 1;
3340 SiS_Pr->SiS_RVBHCFACT = 1;
3341
3342 if(ModeNo <= 0x13) {
3343
3344 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3345 index = SiS_GetModePtr(SiS_Pr,ModeNo,ModeIdIndex);
3346
3347 tempax = SiS_Pr->SiS_StandTable[index].CRTC[0];
3348 tempbx = SiS_Pr->SiS_StandTable[index].CRTC[6];
3349 temp1 = SiS_Pr->SiS_StandTable[index].CRTC[7];
3350
3351 dotclock = (modeflag & Charx8Dot) ? 8 : 9;
3352
3353 } else {
3354
3355 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3356 index = SiS_GetRefCRT1CRTC(SiS_Pr, Index: RefreshRateTableIndex, UseWide: SiS_Pr->SiS_UseWideCRT2);
3357
3358 tempax = SiS_Pr->SiS_CRT1Table[index].CR[0];
3359 tempax |= (SiS_Pr->SiS_CRT1Table[index].CR[14] << 8);
3360 tempax &= 0x03FF;
3361 tempbx = SiS_Pr->SiS_CRT1Table[index].CR[6];
3362 tempcx = SiS_Pr->SiS_CRT1Table[index].CR[13] << 8;
3363 tempcx &= 0x0100;
3364 tempcx <<= 2;
3365 tempbx |= tempcx;
3366 temp1 = SiS_Pr->SiS_CRT1Table[index].CR[7];
3367
3368 dotclock = 8;
3369
3370 }
3371
3372 if(temp1 & 0x01) tempbx |= 0x0100;
3373 if(temp1 & 0x20) tempbx |= 0x0200;
3374
3375 tempax += 5;
3376 tempax *= dotclock;
3377 if(modeflag & HalfDCLK) tempax <<= 1;
3378
3379 tempbx++;
3380
3381 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3382 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = tempbx;
3383}
3384
3385static void
3386SiS_CalcPanelLinkTiming(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
3387 unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex)
3388{
3389 unsigned short ResIndex;
3390
3391 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3392 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
3393 if(SiS_Pr->UseCustomMode) {
3394 ResIndex = SiS_Pr->CHTotal;
3395 if(SiS_Pr->CModeFlag & HalfDCLK) ResIndex <<= 1;
3396 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = ResIndex;
3397 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3398 } else {
3399 if(ModeNo < 0x13) {
3400 ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3401 } else {
3402 ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
3403 }
3404 if(ResIndex == 0x09) {
3405 if(SiS_Pr->Alternate1600x1200) ResIndex = 0x20; /* 1600x1200 LCDA */
3406 else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) ResIndex = 0x21; /* 1600x1200 LVDS */
3407 }
3408 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAHT;
3409 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAVT;
3410 SiS_Pr->SiS_HT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDHT;
3411 SiS_Pr->SiS_VT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDVT;
3412 }
3413 } else {
3414 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3415 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3416 }
3417 } else {
3418 /* This handles custom modes and custom panels */
3419 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3420 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3421 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3422 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3423 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT - (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE);
3424 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT - (SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE);
3425 }
3426}
3427
3428static void
3429SiS_GetCRT2DataLVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3430 unsigned short RefreshRateTableIndex)
3431{
3432 unsigned short CRT2Index, ResIndex, backup;
3433 const struct SiS_LVDSData *LVDSData = NULL;
3434
3435 SiS_GetCRT2ResInfo(SiS_Pr, ModeNo, ModeIdIndex);
3436
3437 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3438 SiS_Pr->SiS_RVBHCMAX = 1;
3439 SiS_Pr->SiS_RVBHCFACT = 1;
3440 SiS_Pr->SiS_NewFlickerMode = 0;
3441 SiS_Pr->SiS_RVBHRS = 50;
3442 SiS_Pr->SiS_RY1COE = 0;
3443 SiS_Pr->SiS_RY2COE = 0;
3444 SiS_Pr->SiS_RY3COE = 0;
3445 SiS_Pr->SiS_RY4COE = 0;
3446 SiS_Pr->SiS_RVBHRS2 = 0;
3447 }
3448
3449 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3450
3451#ifdef CONFIG_FB_SIS_315
3452 SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3453 SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
3454#endif
3455
3456 } else {
3457
3458 /* 301BDH needs LVDS Data */
3459 backup = SiS_Pr->SiS_IF_DEF_LVDS;
3460 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3461 SiS_Pr->SiS_IF_DEF_LVDS = 1;
3462 }
3463
3464 SiS_GetCRT2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
3465 CRT2Index: &CRT2Index, ResIndex: &ResIndex);
3466
3467 SiS_Pr->SiS_IF_DEF_LVDS = backup;
3468
3469 switch(CRT2Index) {
3470 case 10: LVDSData = SiS_Pr->SiS_LVDS320x240Data_1; break;
3471 case 14: LVDSData = SiS_Pr->SiS_LVDS320x240Data_2; break;
3472 case 12: LVDSData = SiS_Pr->SiS_LVDS640x480Data_1; break;
3473 case 16: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1; break;
3474 case 18: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1; break;
3475 case 20: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break;
3476#ifdef CONFIG_FB_SIS_300
3477 case 80: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1; break;
3478 case 81: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2; break;
3479 case 82: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1; break;
3480 case 84: LVDSData = SiS_Pr->SiS_LVDS848x480Data_1; break;
3481 case 85: LVDSData = SiS_Pr->SiS_LVDS848x480Data_2; break;
3482#endif
3483 case 90: LVDSData = SiS_Pr->SiS_CHTVUNTSCData; break;
3484 case 91: LVDSData = SiS_Pr->SiS_CHTVONTSCData; break;
3485 case 92: LVDSData = SiS_Pr->SiS_CHTVUPALData; break;
3486 case 93: LVDSData = SiS_Pr->SiS_CHTVOPALData; break;
3487 case 94: LVDSData = SiS_Pr->SiS_CHTVUPALMData; break;
3488 case 95: LVDSData = SiS_Pr->SiS_CHTVOPALMData; break;
3489 case 96: LVDSData = SiS_Pr->SiS_CHTVUPALNData; break;
3490 case 97: LVDSData = SiS_Pr->SiS_CHTVOPALNData; break;
3491 case 99: LVDSData = SiS_Pr->SiS_CHTVSOPALData; break;
3492 }
3493
3494 if(LVDSData) {
3495 SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT;
3496 SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT;
3497 SiS_Pr->SiS_HT = (LVDSData+ResIndex)->LCDHT;
3498 SiS_Pr->SiS_VT = (LVDSData+ResIndex)->LCDVT;
3499 } else {
3500 SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3501 }
3502
3503 if( (!(SiS_Pr->SiS_VBType & VB_SISVB)) &&
3504 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
3505 (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) ) {
3506 if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ||
3507 (SiS_Pr->SiS_SetFlag & SetDOSMode) ) {
3508 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3509 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3510#ifdef CONFIG_FB_SIS_300
3511 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3512 if(ResIndex < 0x08) {
3513 SiS_Pr->SiS_HDE = 1280;
3514 SiS_Pr->SiS_VDE = 1024;
3515 }
3516 }
3517#endif
3518 }
3519 }
3520 }
3521}
3522
3523static void
3524SiS_GetCRT2Data301(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3525 unsigned short RefreshRateTableIndex)
3526{
3527 unsigned char *ROMAddr = NULL;
3528 unsigned short tempax, tempbx, modeflag, romptr=0;
3529 unsigned short resinfo, CRT2Index, ResIndex;
3530 const struct SiS_LCDData *LCDPtr = NULL;
3531 const struct SiS_TVData *TVPtr = NULL;
3532#ifdef CONFIG_FB_SIS_315
3533 short resinfo661;
3534#endif
3535
3536 if(ModeNo <= 0x13) {
3537 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3538 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
3539 } else if(SiS_Pr->UseCustomMode) {
3540 modeflag = SiS_Pr->CModeFlag;
3541 resinfo = 0;
3542 } else {
3543 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3544 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
3545#ifdef CONFIG_FB_SIS_315
3546 resinfo661 = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].ROMMODEIDX661;
3547 if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
3548 (SiS_Pr->SiS_SetFlag & LCDVESATiming) &&
3549 (resinfo661 >= 0) &&
3550 (SiS_Pr->SiS_NeedRomModeData) ) {
3551 if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
3552 if((romptr = (SISGETROMW(21)))) {
3553 romptr += (resinfo661 * 10);
3554 ROMAddr = SiS_Pr->VirtualRomBase;
3555 }
3556 }
3557 }
3558#endif
3559 }
3560
3561 SiS_Pr->SiS_NewFlickerMode = 0;
3562 SiS_Pr->SiS_RVBHRS = 50;
3563 SiS_Pr->SiS_RY1COE = 0;
3564 SiS_Pr->SiS_RY2COE = 0;
3565 SiS_Pr->SiS_RY3COE = 0;
3566 SiS_Pr->SiS_RY4COE = 0;
3567 SiS_Pr->SiS_RVBHRS2 = 0;
3568
3569 SiS_GetCRT2ResInfo(SiS_Pr,ModeNo,ModeIdIndex);
3570
3571 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
3572
3573 if(SiS_Pr->UseCustomMode) {
3574
3575 SiS_Pr->SiS_RVBHCMAX = 1;
3576 SiS_Pr->SiS_RVBHCFACT = 1;
3577 SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE;
3578 SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE;
3579
3580 tempax = SiS_Pr->CHTotal;
3581 if(modeflag & HalfDCLK) tempax <<= 1;
3582 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3583 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3584
3585 } else {
3586
3587 SiS_GetRAMDAC2DATA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3588
3589 }
3590
3591 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
3592
3593 SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3594 CRT2Index: &CRT2Index,ResIndex: &ResIndex);
3595
3596 switch(CRT2Index) {
3597 case 2: TVPtr = SiS_Pr->SiS_ExtHiTVData; break;
3598 case 3: TVPtr = SiS_Pr->SiS_ExtPALData; break;
3599 case 4: TVPtr = SiS_Pr->SiS_ExtNTSCData; break;
3600 case 5: TVPtr = SiS_Pr->SiS_Ext525iData; break;
3601 case 6: TVPtr = SiS_Pr->SiS_Ext525pData; break;
3602 case 7: TVPtr = SiS_Pr->SiS_Ext750pData; break;
3603 case 8: TVPtr = SiS_Pr->SiS_StPALData; break;
3604 case 9: TVPtr = SiS_Pr->SiS_StNTSCData; break;
3605 case 10: TVPtr = SiS_Pr->SiS_St525iData; break;
3606 case 11: TVPtr = SiS_Pr->SiS_St525pData; break;
3607 case 12: TVPtr = SiS_Pr->SiS_St750pData; break;
3608 case 13: TVPtr = SiS_Pr->SiS_St1HiTVData; break;
3609 case 14: TVPtr = SiS_Pr->SiS_St2HiTVData; break;
3610 default: TVPtr = SiS_Pr->SiS_StPALData; break;
3611 }
3612
3613 SiS_Pr->SiS_RVBHCMAX = (TVPtr+ResIndex)->RVBHCMAX;
3614 SiS_Pr->SiS_RVBHCFACT = (TVPtr+ResIndex)->RVBHCFACT;
3615 SiS_Pr->SiS_VGAHT = (TVPtr+ResIndex)->VGAHT;
3616 SiS_Pr->SiS_VGAVT = (TVPtr+ResIndex)->VGAVT;
3617 SiS_Pr->SiS_HDE = (TVPtr+ResIndex)->TVHDE;
3618 SiS_Pr->SiS_VDE = (TVPtr+ResIndex)->TVVDE;
3619 SiS_Pr->SiS_RVBHRS2 = (TVPtr+ResIndex)->RVBHRS2 & 0x0fff;
3620 if(modeflag & HalfDCLK) {
3621 SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->HALFRVBHRS;
3622 if(SiS_Pr->SiS_RVBHRS2) {
3623 SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
3624 tempax = ((TVPtr+ResIndex)->RVBHRS2 >> 12) & 0x07;
3625 if((TVPtr+ResIndex)->RVBHRS2 & 0x8000) SiS_Pr->SiS_RVBHRS2 -= tempax;
3626 else SiS_Pr->SiS_RVBHRS2 += tempax;
3627 }
3628 } else {
3629 SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->RVBHRS;
3630 }
3631 SiS_Pr->SiS_NewFlickerMode = ((TVPtr+ResIndex)->FlickerMode) << 7;
3632
3633 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
3634
3635 if((resinfo == SIS_RI_960x600) ||
3636 (resinfo == SIS_RI_1024x768) ||
3637 (resinfo == SIS_RI_1280x1024) ||
3638 (resinfo == SIS_RI_1280x720)) {
3639 SiS_Pr->SiS_NewFlickerMode = 0x40;
3640 }
3641
3642 if(SiS_Pr->SiS_VGAVDE == 350) SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
3643
3644 SiS_Pr->SiS_HT = ExtHiTVHT;
3645 SiS_Pr->SiS_VT = ExtHiTVVT;
3646 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
3647 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
3648 SiS_Pr->SiS_HT = StHiTVHT;
3649 SiS_Pr->SiS_VT = StHiTVVT;
3650 }
3651 }
3652
3653 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3654
3655 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
3656 SiS_Pr->SiS_HT = 1650;
3657 SiS_Pr->SiS_VT = 750;
3658 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
3659 SiS_Pr->SiS_HT = NTSCHT;
3660 if(SiS_Pr->SiS_TVMode & TVSet525p1024) SiS_Pr->SiS_HT = NTSC2HT;
3661 SiS_Pr->SiS_VT = NTSCVT;
3662 } else {
3663 SiS_Pr->SiS_HT = NTSCHT;
3664 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3665 SiS_Pr->SiS_VT = NTSCVT;
3666 }
3667
3668 } else {
3669
3670 SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
3671 SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
3672 SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
3673 SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
3674
3675 if(modeflag & HalfDCLK) {
3676 SiS_Pr->SiS_RY1COE = 0x00;
3677 SiS_Pr->SiS_RY2COE = 0xf4;
3678 SiS_Pr->SiS_RY3COE = 0x10;
3679 SiS_Pr->SiS_RY4COE = 0x38;
3680 }
3681
3682 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
3683 SiS_Pr->SiS_HT = NTSCHT;
3684 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3685 SiS_Pr->SiS_VT = NTSCVT;
3686 } else {
3687 SiS_Pr->SiS_HT = PALHT;
3688 SiS_Pr->SiS_VT = PALVT;
3689 }
3690
3691 }
3692
3693 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3694
3695 SiS_Pr->SiS_RVBHCMAX = 1;
3696 SiS_Pr->SiS_RVBHCFACT = 1;
3697
3698 if(SiS_Pr->UseCustomMode) {
3699
3700 SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE;
3701 SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE;
3702
3703 tempax = SiS_Pr->CHTotal;
3704 if(modeflag & HalfDCLK) tempax <<= 1;
3705 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3706 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3707
3708 } else {
3709
3710 bool gotit = false;
3711
3712 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
3713
3714 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
3715 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
3716 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3717 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3718 gotit = true;
3719
3720 } else if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) && (romptr) && (ROMAddr) ) {
3721
3722#ifdef CONFIG_FB_SIS_315
3723 SiS_Pr->SiS_RVBHCMAX = ROMAddr[romptr];
3724 SiS_Pr->SiS_RVBHCFACT = ROMAddr[romptr+1];
3725 SiS_Pr->SiS_VGAHT = ROMAddr[romptr+2] | ((ROMAddr[romptr+3] & 0x0f) << 8);
3726 SiS_Pr->SiS_VGAVT = (ROMAddr[romptr+4] << 4) | ((ROMAddr[romptr+3] & 0xf0) >> 4);
3727 SiS_Pr->SiS_HT = ROMAddr[romptr+5] | ((ROMAddr[romptr+6] & 0x0f) << 8);
3728 SiS_Pr->SiS_VT = (ROMAddr[romptr+7] << 4) | ((ROMAddr[romptr+6] & 0xf0) >> 4);
3729 SiS_Pr->SiS_RVBHRS2 = ROMAddr[romptr+8] | ((ROMAddr[romptr+9] & 0x0f) << 8);
3730 if((SiS_Pr->SiS_RVBHRS2) && (modeflag & HalfDCLK)) {
3731 SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
3732 tempax = (ROMAddr[romptr+9] >> 4) & 0x07;
3733 if(ROMAddr[romptr+9] & 0x80) SiS_Pr->SiS_RVBHRS2 -= tempax;
3734 else SiS_Pr->SiS_RVBHRS2 += tempax;
3735 }
3736 if(SiS_Pr->SiS_VGAHT) gotit = true;
3737 else {
3738 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
3739 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
3740 SiS_Pr->SiS_RVBHCMAX = 1;
3741 SiS_Pr->SiS_RVBHCFACT = 1;
3742 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
3743 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
3744 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3745 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3746 SiS_Pr->SiS_RVBHRS2 = 0;
3747 gotit = true;
3748 }
3749#endif
3750
3751 }
3752
3753 if(!gotit) {
3754
3755 SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3756 CRT2Index: &CRT2Index,ResIndex: &ResIndex);
3757
3758 switch(CRT2Index) {
3759 case Panel_1024x768 : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break;
3760 case Panel_1024x768 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data; break;
3761 case Panel_1280x720 :
3762 case Panel_1280x720 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x720Data; break;
3763 case Panel_1280x768_2 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x768_2Data; break;
3764 case Panel_1280x768_2+ 32: LCDPtr = SiS_Pr->SiS_StLCD1280x768_2Data; break;
3765 case Panel_1280x800 :
3766 case Panel_1280x800 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x800Data; break;
3767 case Panel_1280x800_2 :
3768 case Panel_1280x800_2+ 32: LCDPtr = SiS_Pr->SiS_LCD1280x800_2Data; break;
3769 case Panel_1280x854 :
3770 case Panel_1280x854 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x854Data; break;
3771 case Panel_1280x960 :
3772 case Panel_1280x960 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x960Data; break;
3773 case Panel_1280x1024 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data; break;
3774 case Panel_1280x1024 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
3775 case Panel_1400x1050 : LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data; break;
3776 case Panel_1400x1050 + 32: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data; break;
3777 case Panel_1600x1200 : LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data; break;
3778 case Panel_1600x1200 + 32: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data; break;
3779 case Panel_1680x1050 :
3780 case Panel_1680x1050 + 32: LCDPtr = SiS_Pr->SiS_LCD1680x1050Data; break;
3781 case 100 : LCDPtr = SiS_Pr->SiS_NoScaleData; break;
3782#ifdef CONFIG_FB_SIS_315
3783 case 200 : LCDPtr = SiS310_ExtCompaq1280x1024Data; break;
3784 case 201 : LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
3785#endif
3786 default : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break;
3787 }
3788
3789 SiS_Pr->SiS_RVBHCMAX = (LCDPtr+ResIndex)->RVBHCMAX;
3790 SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
3791 SiS_Pr->SiS_VGAHT = (LCDPtr+ResIndex)->VGAHT;
3792 SiS_Pr->SiS_VGAVT = (LCDPtr+ResIndex)->VGAVT;
3793 SiS_Pr->SiS_HT = (LCDPtr+ResIndex)->LCDHT;
3794 SiS_Pr->SiS_VT = (LCDPtr+ResIndex)->LCDVT;
3795
3796 }
3797
3798 tempax = SiS_Pr->PanelXRes;
3799 tempbx = SiS_Pr->PanelYRes;
3800
3801 switch(SiS_Pr->SiS_LCDResInfo) {
3802 case Panel_1024x768:
3803 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
3804 if(SiS_Pr->ChipType < SIS_315H) {
3805 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3806 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3807 }
3808 } else {
3809 if (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
3810 else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
3811 else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
3812 else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
3813 else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3814 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3815 }
3816 break;
3817 case Panel_1280x960:
3818 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 700;
3819 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 800;
3820 else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
3821 break;
3822 case Panel_1280x1024:
3823 if (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
3824 else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
3825 else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
3826 break;
3827 case Panel_1600x1200:
3828 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
3829 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 875;
3830 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 1000;
3831 }
3832 break;
3833 }
3834
3835 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3836 tempax = SiS_Pr->SiS_VGAHDE;
3837 tempbx = SiS_Pr->SiS_VGAVDE;
3838 }
3839
3840 SiS_Pr->SiS_HDE = tempax;
3841 SiS_Pr->SiS_VDE = tempbx;
3842 }
3843 }
3844}
3845
3846static void
3847SiS_GetCRT2Data(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3848 unsigned short RefreshRateTableIndex)
3849{
3850
3851 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3852
3853 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
3854 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3855 } else {
3856 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3857 /* Need LVDS Data for LCD on 301B-DH */
3858 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3859 } else {
3860 SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3861 }
3862 }
3863
3864 } else {
3865
3866 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3867
3868 }
3869}
3870
3871/*********************************************/
3872/* GET LVDS DES (SKEW) DATA */
3873/*********************************************/
3874
3875static const struct SiS_LVDSDes *
3876SiS_GetLVDSDesPtr(struct SiS_Private *SiS_Pr)
3877{
3878 const struct SiS_LVDSDes *PanelDesPtr = NULL;
3879
3880#ifdef CONFIG_FB_SIS_300
3881 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3882
3883 if(SiS_Pr->ChipType < SIS_315H) {
3884 if(SiS_Pr->SiS_LCDTypeInfo == 4) {
3885 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3886 PanelDesPtr = SiS_Pr->SiS_PanelType04_1a;
3887 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3888 PanelDesPtr = SiS_Pr->SiS_PanelType04_2a;
3889 }
3890 } else if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
3891 PanelDesPtr = SiS_Pr->SiS_PanelType04_1b;
3892 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3893 PanelDesPtr = SiS_Pr->SiS_PanelType04_2b;
3894 }
3895 }
3896 }
3897 }
3898 }
3899#endif
3900 return PanelDesPtr;
3901}
3902
3903static void
3904SiS_GetLVDSDesData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3905 unsigned short RefreshRateTableIndex)
3906{
3907 unsigned short modeflag, ResIndex;
3908 const struct SiS_LVDSDes *PanelDesPtr = NULL;
3909
3910 SiS_Pr->SiS_LCDHDES = 0;
3911 SiS_Pr->SiS_LCDVDES = 0;
3912
3913 /* Some special cases */
3914 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3915
3916 /* Trumpion */
3917 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
3918 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3919 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3920 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3921 }
3922 }
3923 return;
3924 }
3925
3926 /* 640x480 on LVDS */
3927 if(SiS_Pr->ChipType < SIS_315H) {
3928 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480 && SiS_Pr->SiS_LCDTypeInfo == 3) {
3929 SiS_Pr->SiS_LCDHDES = 8;
3930 if (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
3931 else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
3932 else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
3933 return;
3934 }
3935 }
3936
3937 } /* LCD */
3938
3939 if( (SiS_Pr->UseCustomMode) ||
3940 (SiS_Pr->SiS_LCDResInfo == Panel_Custom) ||
3941 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
3942 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ||
3943 (SiS_Pr->SiS_LCDInfo & LCDPass11) ) {
3944 return;
3945 }
3946
3947 if(ModeNo <= 0x13) ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3948 else ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
3949
3950 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3951
3952#ifdef CONFIG_FB_SIS_315
3953 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3954 /* non-pass 1:1 only, see above */
3955 if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
3956 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
3957 }
3958 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
3959 SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
3960 }
3961 }
3962 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3963 switch(SiS_Pr->SiS_CustomT) {
3964 case CUT_UNIWILL1024:
3965 case CUT_UNIWILL10242:
3966 case CUT_CLEVO1400:
3967 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3968 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3969 }
3970 break;
3971 }
3972 switch(SiS_Pr->SiS_LCDResInfo) {
3973 case Panel_1280x1024:
3974 if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
3975 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3976 }
3977 break;
3978 case Panel_1280x800: /* Verified for Averatec 6240 */
3979 case Panel_1280x800_2: /* Verified for Asus A4L */
3980 case Panel_1280x854: /* Not verified yet FIXME */
3981 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3982 break;
3983 }
3984 }
3985#endif
3986
3987 } else {
3988
3989 if((SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
3990
3991 if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
3992 if(ResIndex <= 3) SiS_Pr->SiS_LCDHDES = 256;
3993 }
3994
3995 } else if((PanelDesPtr = SiS_GetLVDSDesPtr(SiS_Pr))) {
3996
3997 SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
3998 SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;
3999
4000 } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
4001
4002 if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
4003 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
4004 }
4005 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
4006 SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
4007 } else {
4008 if(SiS_Pr->ChipType < SIS_315H) {
4009 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
4010 } else {
4011 switch(SiS_Pr->SiS_LCDResInfo) {
4012 case Panel_800x600:
4013 case Panel_1024x768:
4014 case Panel_1280x1024:
4015 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
4016 break;
4017 case Panel_1400x1050:
4018 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
4019 break;
4020 }
4021 }
4022 }
4023
4024 } else {
4025
4026 if(SiS_Pr->ChipType < SIS_315H) {
4027#ifdef CONFIG_FB_SIS_300
4028 switch(SiS_Pr->SiS_LCDResInfo) {
4029 case Panel_800x600:
4030 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
4031 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
4032 } else {
4033 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT + 3;
4034 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
4035 if(SiS_Pr->SiS_VGAVDE == 400) SiS_Pr->SiS_LCDVDES -= 2;
4036 else SiS_Pr->SiS_LCDVDES -= 4;
4037 }
4038 break;
4039 case Panel_1024x768:
4040 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
4041 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
4042 } else {
4043 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
4044 if(SiS_Pr->SiS_VGAVDE <= 400) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 8;
4045 if(SiS_Pr->SiS_VGAVDE <= 350) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 12;
4046 }
4047 break;
4048 case Panel_1024x600:
4049 default:
4050 if( (SiS_Pr->SiS_VGAHDE == SiS_Pr->PanelXRes) &&
4051 (SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) ) {
4052 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
4053 } else {
4054 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
4055 }
4056 break;
4057 }
4058
4059 switch(SiS_Pr->SiS_LCDTypeInfo) {
4060 case 1:
4061 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
4062 break;
4063 case 3: /* 640x480 only? */
4064 SiS_Pr->SiS_LCDHDES = 8;
4065 if (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
4066 else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
4067 else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
4068 break;
4069 }
4070#endif
4071 } else {
4072#ifdef CONFIG_FB_SIS_315
4073 switch(SiS_Pr->SiS_LCDResInfo) {
4074 case Panel_1024x768:
4075 case Panel_1280x1024:
4076 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
4077 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
4078 }
4079 break;
4080 case Panel_320x240_1:
4081 case Panel_320x240_2:
4082 case Panel_320x240_3:
4083 SiS_Pr->SiS_LCDVDES = 524;
4084 break;
4085 }
4086#endif
4087 }
4088 }
4089
4090 if((ModeNo <= 0x13) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
4091 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
4092 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
4093 if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 632;
4094 } else if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) {
4095 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
4096 if(SiS_Pr->SiS_LCDResInfo >= Panel_1024x768) {
4097 if(SiS_Pr->ChipType < SIS_315H) {
4098 if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320;
4099 } else {
4100#ifdef CONFIG_FB_SIS_315
4101 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) SiS_Pr->SiS_LCDHDES = 480;
4102 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 804;
4103 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 704;
4104 if(!(modeflag & HalfDCLK)) {
4105 SiS_Pr->SiS_LCDHDES = 320;
4106 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 632;
4107 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 542;
4108 }
4109#endif
4110 }
4111 }
4112 }
4113 }
4114 }
4115 }
4116}
4117
4118/*********************************************/
4119/* DISABLE VIDEO BRIDGE */
4120/*********************************************/
4121
4122#ifdef CONFIG_FB_SIS_315
4123static int
4124SiS_HandlePWD(struct SiS_Private *SiS_Pr)
4125{
4126 int ret = 0;
4127#ifdef SET_PWD
4128 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
4129 unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
4130 unsigned char drivermode = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40;
4131 unsigned short temp;
4132
4133 if( (SiS_Pr->SiS_VBType & VB_SISPWD) &&
4134 (romptr) &&
4135 (SiS_Pr->SiS_PWDOffset) ) {
4136 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2b,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 0]);
4137 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2c,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 1]);
4138 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2d,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 2]);
4139 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2e,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 3]);
4140 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2f,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 4]);
4141 temp = 0x00;
4142 if((ROMAddr[romptr + 2] & (0x06 << 1)) && !drivermode) {
4143 temp = 0x80;
4144 ret = 1;
4145 }
4146 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x27,0x7f,temp);
4147 }
4148#endif
4149 return ret;
4150}
4151#endif
4152
4153/* NEVER use any variables (VBInfo), this will be called
4154 * from outside the context of modeswitch!
4155 * MUST call getVBType before calling this
4156 */
4157void
4158SiS_DisableBridge(struct SiS_Private *SiS_Pr)
4159{
4160#ifdef CONFIG_FB_SIS_315
4161 unsigned short tempah, pushax=0, modenum;
4162#endif
4163 unsigned short temp=0;
4164
4165 if(SiS_Pr->SiS_VBType & VB_SISVB) {
4166
4167 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* ===== For 30xB/C/LV ===== */
4168
4169 if(SiS_Pr->ChipType < SIS_315H) {
4170
4171#ifdef CONFIG_FB_SIS_300 /* 300 series */
4172
4173 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4174 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4175 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
4176 } else {
4177 SiS_SetRegSR11ANDOR(SiS_Pr,DataAND: 0xF7,DataOR: 0x08);
4178 }
4179 SiS_PanelDelay(SiS_Pr, DelayTime: 3);
4180 }
4181 if(SiS_Is301B(SiS_Pr)) {
4182 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);
4183 SiS_ShortDelay(SiS_Pr,delay: 1);
4184 }
4185 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
4186 SiS_DisplayOff(SiS_Pr);
4187 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4188 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4189 SiS_UnLockCRT2(SiS_Pr);
4190 if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) {
4191 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
4192 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
4193 }
4194 if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4195 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4196 SiS_PanelDelay(SiS_Pr, DelayTime: 2);
4197 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4198 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
4199 } else {
4200 SiS_SetRegSR11ANDOR(SiS_Pr,DataAND: 0xFB,DataOR: 0x04);
4201 }
4202 }
4203
4204#endif /* CONFIG_FB_SIS_300 */
4205
4206 } else {
4207
4208#ifdef CONFIG_FB_SIS_315 /* 315 series */
4209
4210 int didpwd = 0;
4211 bool custom1 = (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
4212 (SiS_Pr->SiS_CustomT == CUT_CLEVO1400);
4213
4214 modenum = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34) & 0x7f;
4215
4216 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4217
4218#ifdef SET_EMI
4219 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4220 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
4221 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4222 }
4223 }
4224#endif
4225
4226 didpwd = SiS_HandlePWD(SiS_Pr);
4227
4228 if( (modenum <= 0x13) ||
4229 (SiS_IsVAMode(SiS_Pr)) ||
4230 (!(SiS_IsDualEdge(SiS_Pr))) ) {
4231 if(!didpwd) {
4232 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfe);
4233 if(custom1) SiS_PanelDelay(SiS_Pr, DelayTime: 3);
4234 } else {
4235 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfc);
4236 }
4237 }
4238
4239 if(!custom1) {
4240 SiS_DDC2Delay(SiS_Pr,delaytime: 0xff00);
4241 SiS_DDC2Delay(SiS_Pr,delaytime: 0xe000);
4242 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
4243 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
4244 if(IS_SIS740) {
4245 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
4246 }
4247 SiS_PanelDelay(SiS_Pr, DelayTime: 3);
4248 }
4249
4250 }
4251
4252 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4253 /* if(SiS_Pr->ChipType < SIS_340) {*/
4254 tempah = 0xef;
4255 if(SiS_IsVAMode(SiS_Pr)) tempah = 0xf7;
4256 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
4257 /*}*/
4258 }
4259
4260 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4261 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,~0x10);
4262 }
4263
4264 tempah = 0x3f;
4265 if(SiS_IsDualEdge(SiS_Pr)) {
4266 tempah = 0x7f;
4267 if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0xbf;
4268 }
4269 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4270
4271 if((SiS_IsVAMode(SiS_Pr)) ||
4272 ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
4273
4274 SiS_DisplayOff(SiS_Pr);
4275 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4276 SiS_PanelDelay(SiS_Pr, DelayTime: 2);
4277 }
4278 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4279 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
4280
4281 }
4282
4283 if((!(SiS_IsVAMode(SiS_Pr))) ||
4284 ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
4285
4286 if(!(SiS_IsDualEdge(SiS_Pr))) {
4287 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
4288 SiS_DisplayOff(SiS_Pr);
4289 }
4290 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4291
4292 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4293 SiS_PanelDelay(SiS_Pr, DelayTime: 2);
4294 }
4295
4296 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4297 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
4298 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
4299 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4300 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
4301
4302 }
4303
4304 if(SiS_IsNotM650orLater(SiS_Pr)) {
4305 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4306 }
4307
4308 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4309
4310 if( (!(SiS_IsVAMode(SiS_Pr))) &&
4311 (!(SiS_CRT2IsLCD(SiS_Pr))) &&
4312 (!(SiS_IsDualEdge(SiS_Pr))) ) {
4313
4314 if(custom1) SiS_PanelDelay(SiS_Pr, DelayTime: 2);
4315 if(!didpwd) {
4316 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
4317 }
4318 if(custom1) SiS_PanelDelay(SiS_Pr, DelayTime: 4);
4319 }
4320
4321 if(!custom1) {
4322 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4323 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4324 if(SiS_IsVAorLCD(SiS_Pr)) {
4325 SiS_PanelDelayLoop(SiS_Pr, DelayTime: 3, DelayLoop: 20);
4326 }
4327 }
4328 }
4329
4330 }
4331
4332#endif /* CONFIG_FB_SIS_315 */
4333
4334 }
4335
4336 } else { /* ============ For 301 ================ */
4337
4338 if(SiS_Pr->ChipType < SIS_315H) {
4339#ifdef CONFIG_FB_SIS_300
4340 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4341 SiS_SetRegSR11ANDOR(SiS_Pr,DataAND: 0xF7,DataOR: 0x08);
4342 SiS_PanelDelay(SiS_Pr, DelayTime: 3);
4343 }
4344#endif
4345 }
4346
4347 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF); /* disable VB */
4348 SiS_DisplayOff(SiS_Pr);
4349
4350 if(SiS_Pr->ChipType >= SIS_315H) {
4351 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4352 }
4353
4354 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); /* disable lock mode */
4355
4356 if(SiS_Pr->ChipType >= SIS_315H) {
4357 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
4358 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
4359 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4360 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
4361 } else {
4362#ifdef CONFIG_FB_SIS_300
4363 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); /* disable CRT2 */
4364 if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4365 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4366 SiS_PanelDelay(SiS_Pr, DelayTime: 2);
4367 SiS_SetRegSR11ANDOR(SiS_Pr,DataAND: 0xFB,DataOR: 0x04);
4368 }
4369#endif
4370 }
4371
4372 }
4373
4374 } else { /* ============ For LVDS =============*/
4375
4376 if(SiS_Pr->ChipType < SIS_315H) {
4377
4378#ifdef CONFIG_FB_SIS_300 /* 300 series */
4379
4380 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4381 SiS_SetCH700x(SiS_Pr,reg: 0x0E,val: 0x09);
4382 }
4383
4384 if(SiS_Pr->ChipType == SIS_730) {
4385 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4386 SiS_WaitVBRetrace(SiS_Pr);
4387 }
4388 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4389 SiS_SetRegSR11ANDOR(SiS_Pr,DataAND: 0xF7,DataOR: 0x08);
4390 SiS_PanelDelay(SiS_Pr, DelayTime: 3);
4391 }
4392 } else {
4393 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4394 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4395 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4396 SiS_WaitVBRetrace(SiS_Pr);
4397 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {
4398 SiS_DisplayOff(SiS_Pr);
4399 }
4400 SiS_SetRegSR11ANDOR(SiS_Pr,DataAND: 0xF7,DataOR: 0x08);
4401 SiS_PanelDelay(SiS_Pr, DelayTime: 3);
4402 }
4403 }
4404 }
4405 }
4406
4407 SiS_DisplayOff(SiS_Pr);
4408
4409 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4410
4411 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4412 SiS_UnLockCRT2(SiS_Pr);
4413 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
4414 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
4415
4416 if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4417 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4418 SiS_PanelDelay(SiS_Pr, DelayTime: 2);
4419 SiS_SetRegSR11ANDOR(SiS_Pr,DataAND: 0xFB,DataOR: 0x04);
4420 }
4421
4422#endif /* CONFIG_FB_SIS_300 */
4423
4424 } else {
4425
4426#ifdef CONFIG_FB_SIS_315 /* 315 series */
4427
4428 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4429 /*if(SiS_Pr->ChipType < SIS_340) { */ /* XGI needs this */
4430 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,~0x18);
4431 /* } */
4432 }
4433
4434 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4435
4436 if(SiS_Pr->ChipType == SIS_740) {
4437 temp = SiS_GetCH701x(SiS_Pr,tempax: 0x61);
4438 if(temp < 1) {
4439 SiS_SetCH701x(SiS_Pr,reg: 0x76,val: 0xac);
4440 SiS_SetCH701x(SiS_Pr,reg: 0x66,val: 0x00);
4441 }
4442
4443 if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4444 (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
4445 SiS_SetCH701x(SiS_Pr,reg: 0x49,val: 0x3e);
4446 }
4447 }
4448
4449 if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4450 (SiS_IsVAMode(SiS_Pr)) ) {
4451 SiS_Chrontel701xBLOff(SiS_Pr);
4452 SiS_Chrontel701xOff(SiS_Pr);
4453 }
4454
4455 if(SiS_Pr->ChipType != SIS_740) {
4456 if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4457 (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
4458 SiS_SetCH701x(SiS_Pr,reg: 0x49,val: 0x01);
4459 }
4460 }
4461
4462 }
4463
4464 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4465 SiS_SetRegSR11ANDOR(SiS_Pr,DataAND: 0xF7,DataOR: 0x08);
4466 SiS_PanelDelay(SiS_Pr, DelayTime: 3);
4467 }
4468
4469 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4470 (!(SiS_IsDualEdge(SiS_Pr))) ||
4471 (!(SiS_IsTVOrYPbPrOrScart(SiS_Pr))) ) {
4472 SiS_DisplayOff(SiS_Pr);
4473 }
4474
4475 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4476 (!(SiS_IsDualEdge(SiS_Pr))) ||
4477 (!(SiS_IsVAMode(SiS_Pr))) ) {
4478 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4479 }
4480
4481 if(SiS_Pr->ChipType == SIS_740) {
4482 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4483 }
4484
4485 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4486
4487 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4488 (!(SiS_IsDualEdge(SiS_Pr))) ||
4489 (!(SiS_IsVAMode(SiS_Pr))) ) {
4490 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4491 }
4492
4493 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4494 if(SiS_CRT2IsLCD(SiS_Pr)) {
4495 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4496 if(SiS_Pr->ChipType == SIS_550) {
4497 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xbf);
4498 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xef);
4499 }
4500 }
4501 } else {
4502 if(SiS_Pr->ChipType == SIS_740) {
4503 if(SiS_IsLCDOrLCDA(SiS_Pr)) {
4504 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4505 }
4506 } else if(SiS_IsVAMode(SiS_Pr)) {
4507 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4508 }
4509 }
4510
4511 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4512 if(SiS_IsDualEdge(SiS_Pr)) {
4513 /* SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff); */
4514 } else {
4515 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
4516 }
4517 }
4518
4519 SiS_UnLockCRT2(SiS_Pr);
4520
4521 if(SiS_Pr->ChipType == SIS_550) {
4522 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); /* DirectDVD PAL?*/
4523 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); /* VB clock / 4 ? */
4524 } else if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4525 (!(SiS_IsDualEdge(SiS_Pr))) ||
4526 (!(SiS_IsVAMode(SiS_Pr))) ) {
4527 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4528 }
4529
4530 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4531 if(SiS_CRT2IsLCD(SiS_Pr)) {
4532 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4533 SiS_PanelDelay(SiS_Pr, DelayTime: 2);
4534 SiS_SetRegSR11ANDOR(SiS_Pr,DataAND: 0xFB,DataOR: 0x04);
4535 }
4536 }
4537 }
4538
4539#endif /* CONFIG_FB_SIS_315 */
4540
4541 } /* 315 series */
4542
4543 } /* LVDS */
4544
4545}
4546
4547/*********************************************/
4548/* ENABLE VIDEO BRIDGE */
4549/*********************************************/
4550
4551/* NEVER use any variables (VBInfo), this will be called
4552 * from outside the context of a mode switch!
4553 * MUST call getVBType before calling this
4554 */
4555static
4556void
4557SiS_EnableBridge(struct SiS_Private *SiS_Pr)
4558{
4559 unsigned short temp=0, tempah;
4560#ifdef CONFIG_FB_SIS_315
4561 unsigned short temp1, pushax=0;
4562 bool delaylong = false;
4563#endif
4564
4565 if(SiS_Pr->SiS_VBType & VB_SISVB) {
4566
4567 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* ====== For 301B et al ====== */
4568
4569 if(SiS_Pr->ChipType < SIS_315H) {
4570
4571#ifdef CONFIG_FB_SIS_300 /* 300 series */
4572
4573 if(SiS_CRT2IsLCD(SiS_Pr)) {
4574 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4575 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4576 } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
4577 SiS_SetRegSR11ANDOR(SiS_Pr,DataAND: 0xFB,DataOR: 0x00);
4578 }
4579 if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_NoLCD)) {
4580 if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
4581 SiS_PanelDelay(SiS_Pr, DelayTime: 0);
4582 }
4583 }
4584 }
4585
4586 if((SiS_Pr->SiS_VBType & VB_NoLCD) &&
4587 (SiS_CRT2IsLCD(SiS_Pr))) {
4588
4589 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* Enable CRT2 */
4590 SiS_DisplayOn(SiS_Pr);
4591 SiS_UnLockCRT2(SiS_Pr);
4592 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4593 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4594 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4595 } else {
4596 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4597 }
4598 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4599 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4600 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4601 SiS_PanelDelay(SiS_Pr, DelayTime: 1);
4602 }
4603 SiS_WaitVBRetrace(SiS_Pr);
4604 SiS_SetRegSR11ANDOR(SiS_Pr,DataAND: 0xF7,DataOR: 0x00);
4605 }
4606 }
4607
4608 } else {
4609
4610 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
4611 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4612 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4613 if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4614 }
4615 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4616 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4617 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */
4618 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
4619 SiS_DisplayOn(SiS_Pr);
4620 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4621 if(SiS_CRT2IsLCD(SiS_Pr)) {
4622 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4623 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4624 SiS_PanelDelay(SiS_Pr, DelayTime: 1);
4625 }
4626 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4627 }
4628 }
4629 }
4630
4631 }
4632
4633
4634#endif /* CONFIG_FB_SIS_300 */
4635
4636 } else {
4637
4638#ifdef CONFIG_FB_SIS_315 /* 315 series */
4639
4640#ifdef SET_EMI
4641 unsigned char r30=0, r31=0, r32=0, r33=0, cr36=0;
4642 int didpwd = 0;
4643 /* unsigned short emidelay=0; */
4644#endif
4645
4646 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4647 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef);
4648#ifdef SET_EMI
4649 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4650 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4651 }
4652#endif
4653 }
4654
4655 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4656 /*if(SiS_Pr->ChipType < SIS_340) { */
4657 tempah = 0x10;
4658 if(SiS_LCDAEnabled(SiS_Pr)) {
4659 if(SiS_TVEnabled(SiS_Pr)) tempah = 0x18;
4660 else tempah = 0x08;
4661 }
4662 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah);
4663 /*}*/
4664 }
4665
4666 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4667
4668 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
4669 SiS_DisplayOff(SiS_Pr);
4670 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
4671 if(IS_SIS740) {
4672 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
4673 }
4674
4675 didpwd = SiS_HandlePWD(SiS_Pr);
4676
4677 if(SiS_IsVAorLCD(SiS_Pr)) {
4678 if(!didpwd) {
4679 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
4680 SiS_PanelDelayLoop(SiS_Pr, DelayTime: 3, DelayLoop: 2);
4681 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4682 SiS_PanelDelayLoop(SiS_Pr, DelayTime: 3, DelayLoop: 2);
4683 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4684 SiS_GenericDelay(SiS_Pr, delay: 17664);
4685 }
4686 }
4687 } else {
4688 SiS_PanelDelayLoop(SiS_Pr, DelayTime: 3, DelayLoop: 2);
4689 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4690 SiS_GenericDelay(SiS_Pr, delay: 17664);
4691 }
4692 }
4693 }
4694
4695 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {
4696 SiS_PanelDelayLoop(SiS_Pr, DelayTime: 3, DelayLoop: 10);
4697 delaylong = true;
4698 }
4699
4700 }
4701
4702 if(!(SiS_IsVAMode(SiS_Pr))) {
4703
4704 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
4705 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4706 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4707 if(!(tempah & SetCRT2ToRAMDAC)) {
4708 if(!(SiS_LCDAEnabled(SiS_Pr))) temp |= 0x20;
4709 }
4710 }
4711 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4712
4713 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
4714
4715 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4716 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4717
4718 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4719 SiS_PanelDelay(SiS_Pr, DelayTime: 2);
4720 }
4721
4722 } else {
4723
4724 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20);
4725
4726 }
4727
4728 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
4729 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4730
4731 if(SiS_Pr->SiS_VBType & VB_SISPOWER) {
4732 if( (SiS_LCDAEnabled(SiS_Pr)) ||
4733 (SiS_CRT2IsLCD(SiS_Pr)) ) {
4734 /* Enable "LVDS PLL power on" (even on 301C) */
4735 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);
4736 /* Enable "LVDS Driver Power on" (even on 301C) */
4737 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x7f);
4738 }
4739 }
4740
4741 tempah = 0xc0;
4742 if(SiS_IsDualEdge(SiS_Pr)) {
4743 tempah = 0x80;
4744 if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0x40;
4745 }
4746 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4747
4748 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4749
4750 SiS_PanelDelay(SiS_Pr, DelayTime: 2);
4751
4752 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10);
4753 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4754
4755 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
4756#ifdef SET_EMI
4757 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4758 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4759 SiS_GenericDelay(SiS_Pr, delay: 2048);
4760 }
4761#endif
4762 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
4763
4764 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4765#ifdef SET_EMI
4766 cr36 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
4767
4768 if(SiS_Pr->SiS_ROMNew) {
4769 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
4770 unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
4771 if(romptr) {
4772 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4773 SiS_Pr->EMI_30 = 0;
4774 SiS_Pr->EMI_31 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 0];
4775 SiS_Pr->EMI_32 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 1];
4776 SiS_Pr->EMI_33 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 2];
4777 if(ROMAddr[romptr + 1] & 0x10) SiS_Pr->EMI_30 = 0x40;
4778 /* emidelay = SISGETROMW((romptr + 0x22)); */
4779 SiS_Pr->HaveEMI = SiS_Pr->HaveEMILCD = SiS_Pr->OverruleEMI = true;
4780 }
4781 }
4782
4783 /* (P4_30|0x40) */
4784 /* Compal 1400x1050: 0x05, 0x60, 0x00 YES (1.10.7w; CR36=69) */
4785 /* Compal 1400x1050: 0x0d, 0x70, 0x40 YES (1.10.7x; CR36=69) */
4786 /* Acer 1280x1024: 0x12, 0xd0, 0x6b NO (1.10.9k; CR36=73) */
4787 /* Compaq 1280x1024: 0x0d, 0x70, 0x6b YES (1.12.04b; CR36=03) */
4788 /* Clevo 1024x768: 0x05, 0x60, 0x33 NO (1.10.8e; CR36=12, DL!) */
4789 /* Clevo 1024x768: 0x0d, 0x70, 0x40 (if type == 3) YES (1.10.8y; CR36=?2) */
4790 /* Clevo 1024x768: 0x05, 0x60, 0x33 (if type != 3) YES (1.10.8y; CR36=?2) */
4791 /* Asus 1024x768: ? ? (1.10.8o; CR36=?2) */
4792 /* Asus 1024x768: 0x08, 0x10, 0x3c (problematic) YES (1.10.8q; CR36=22) */
4793
4794 if(SiS_Pr->HaveEMI) {
4795 r30 = SiS_Pr->EMI_30; r31 = SiS_Pr->EMI_31;
4796 r32 = SiS_Pr->EMI_32; r33 = SiS_Pr->EMI_33;
4797 } else {
4798 r30 = 0;
4799 }
4800
4801 /* EMI_30 is read at driver start; however, the BIOS sets this
4802 * (if it is used) only if the LCD is in use. In case we caught
4803 * the machine while on TV output, this bit is not set and we
4804 * don't know if it should be set - hence our detection is wrong.
4805 * Work-around this here:
4806 */
4807
4808 if((!SiS_Pr->HaveEMI) || (!SiS_Pr->HaveEMILCD)) {
4809 switch((cr36 & 0x0f)) {
4810 case 2:
4811 r30 |= 0x40;
4812 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) r30 &= ~0x40;
4813 if(!SiS_Pr->HaveEMI) {
4814 r31 = 0x05; r32 = 0x60; r33 = 0x33;
4815 if((cr36 & 0xf0) == 0x30) {
4816 r31 = 0x0d; r32 = 0x70; r33 = 0x40;
4817 }
4818 }
4819 break;
4820 case 3: /* 1280x1024 */
4821 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) r30 |= 0x40;
4822 if(!SiS_Pr->HaveEMI) {
4823 r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4824 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4825 r31 = 0x0d; r32 = 0x70; r33 = 0x6b;
4826 }
4827 }
4828 break;
4829 case 9: /* 1400x1050 */
4830 r30 |= 0x40;
4831 if(!SiS_Pr->HaveEMI) {
4832 r31 = 0x05; r32 = 0x60; r33 = 0x00;
4833 if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4834 r31 = 0x0d; r32 = 0x70; r33 = 0x40; /* BIOS values */
4835 }
4836 }
4837 break;
4838 case 11: /* 1600x1200 - unknown */
4839 r30 |= 0x40;
4840 if(!SiS_Pr->HaveEMI) {
4841 r31 = 0x05; r32 = 0x60; r33 = 0x00;
4842 }
4843 }
4844 }
4845
4846 /* BIOS values don't work so well sometimes */
4847 if(!SiS_Pr->OverruleEMI) {
4848#ifdef COMPAL_HACK
4849 if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4850 if((cr36 & 0x0f) == 0x09) {
4851 r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x00;
4852 }
4853 }
4854#endif
4855#ifdef COMPAQ_HACK
4856 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4857 if((cr36 & 0x0f) == 0x03) {
4858 r30 = 0x20; r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4859 }
4860 }
4861#endif
4862#ifdef ASUS_HACK
4863 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4864 if((cr36 & 0x0f) == 0x02) {
4865 /* r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 2 */
4866 /* r30 = 0x20; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 3 */
4867 /* r30 = 0x60; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 4 */
4868 /* r30 = 0x20; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 5 */
4869 }
4870 }
4871#endif
4872 }
4873
4874 if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) {
4875 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4876 SiS_GenericDelay(SiS_Pr, delay: 2048);
4877 }
4878 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,r31);
4879 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,r32);
4880 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x33,r33);
4881#endif /* SET_EMI */
4882
4883 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
4884
4885#ifdef SET_EMI
4886 if( (SiS_LCDAEnabled(SiS_Pr)) ||
4887 (SiS_CRT2IsLCD(SiS_Pr)) ) {
4888 if(r30 & 0x40) {
4889 /*SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x2a,0x80);*/
4890 SiS_PanelDelayLoop(SiS_Pr, DelayTime: 3, DelayLoop: 5);
4891 if(delaylong) {
4892 SiS_PanelDelayLoop(SiS_Pr, DelayTime: 3, DelayLoop: 5);
4893 delaylong = false;
4894 }
4895 SiS_WaitVBRetrace(SiS_Pr);
4896 SiS_WaitVBRetrace(SiS_Pr);
4897 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4898 SiS_GenericDelay(SiS_Pr, delay: 1280);
4899 }
4900 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40); /* Enable */
4901 /*SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);*/
4902 }
4903 }
4904#endif
4905 }
4906 }
4907
4908 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4909 if(SiS_IsVAorLCD(SiS_Pr)) {
4910 SiS_PanelDelayLoop(SiS_Pr, DelayTime: 3, DelayLoop: 10);
4911 if(delaylong) {
4912 SiS_PanelDelayLoop(SiS_Pr, DelayTime: 3, DelayLoop: 10);
4913 }
4914 SiS_WaitVBRetrace(SiS_Pr);
4915 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4916 SiS_GenericDelay(SiS_Pr, delay: 2048);
4917 SiS_WaitVBRetrace(SiS_Pr);
4918 }
4919 if(!didpwd) {
4920 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4921 } else {
4922 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x03);
4923 }
4924 }
4925 }
4926
4927 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4928 SiS_DisplayOn(SiS_Pr);
4929 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xff);
4930
4931 }
4932
4933 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4934 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4935 }
4936
4937#endif /* CONFIG_FB_SIS_315 */
4938
4939 }
4940
4941 } else { /* ============ For 301 ================ */
4942
4943 if(SiS_Pr->ChipType < SIS_315H) {
4944 if(SiS_CRT2IsLCD(SiS_Pr)) {
4945 SiS_SetRegSR11ANDOR(SiS_Pr,DataAND: 0xFB,DataOR: 0x00);
4946 SiS_PanelDelay(SiS_Pr, DelayTime: 0);
4947 }
4948 }
4949
4950 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
4951 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4952 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4953 if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4954 }
4955 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4956
4957 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
4958
4959 if(SiS_Pr->ChipType >= SIS_315H) {
4960 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4961 if(!(temp & 0x80)) {
4962 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80); /* BVBDOENABLE=1 */
4963 }
4964 }
4965
4966 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */
4967
4968 SiS_VBLongWait(SiS_Pr);
4969 SiS_DisplayOn(SiS_Pr);
4970 if(SiS_Pr->ChipType >= SIS_315H) {
4971 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4972 }
4973 SiS_VBLongWait(SiS_Pr);
4974
4975 if(SiS_Pr->ChipType < SIS_315H) {
4976 if(SiS_CRT2IsLCD(SiS_Pr)) {
4977 SiS_PanelDelay(SiS_Pr, DelayTime: 1);
4978 SiS_SetRegSR11ANDOR(SiS_Pr,DataAND: 0xF7,DataOR: 0x00);
4979 }
4980 }
4981
4982 }
4983
4984 } else { /* =================== For LVDS ================== */
4985
4986 if(SiS_Pr->ChipType < SIS_315H) {
4987
4988#ifdef CONFIG_FB_SIS_300 /* 300 series */
4989
4990 if(SiS_CRT2IsLCD(SiS_Pr)) {
4991 if(SiS_Pr->ChipType == SIS_730) {
4992 SiS_PanelDelay(SiS_Pr, DelayTime: 1);
4993 SiS_PanelDelay(SiS_Pr, DelayTime: 1);
4994 SiS_PanelDelay(SiS_Pr, DelayTime: 1);
4995 }
4996 SiS_SetRegSR11ANDOR(SiS_Pr,DataAND: 0xFB,DataOR: 0x00);
4997 if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
4998 SiS_PanelDelay(SiS_Pr, DelayTime: 0);
4999 }
5000 }
5001
5002 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
5003 SiS_DisplayOn(SiS_Pr);
5004 SiS_UnLockCRT2(SiS_Pr);
5005 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
5006 if(SiS_BridgeInSlavemode(SiS_Pr)) {
5007 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
5008 } else {
5009 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
5010 }
5011
5012 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
5013 if(!(SiS_CRT2IsLCD(SiS_Pr))) {
5014 SiS_WaitVBRetrace(SiS_Pr);
5015 SiS_SetCH700x(SiS_Pr,reg: 0x0E,val: 0x0B);
5016 }
5017 }
5018
5019 if(SiS_CRT2IsLCD(SiS_Pr)) {
5020 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
5021 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
5022 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
5023 SiS_PanelDelay(SiS_Pr, DelayTime: 1);
5024 SiS_PanelDelay(SiS_Pr, DelayTime: 1);
5025 }
5026 SiS_WaitVBRetrace(SiS_Pr);
5027 SiS_SetRegSR11ANDOR(SiS_Pr,DataAND: 0xF7,DataOR: 0x00);
5028 }
5029 }
5030 }
5031
5032#endif /* CONFIG_FB_SIS_300 */
5033
5034 } else {
5035
5036#ifdef CONFIG_FB_SIS_315 /* 315 series */
5037
5038 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
5039 /*if(SiS_Pr->ChipType < SIS_340) {*/ /* XGI needs this */
5040 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x18);
5041 /*}*/
5042 }
5043
5044 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
5045 if(SiS_CRT2IsLCD(SiS_Pr)) {
5046 SiS_SetRegSR11ANDOR(SiS_Pr,DataAND: 0xFB,DataOR: 0x00);
5047 SiS_PanelDelay(SiS_Pr, DelayTime: 0);
5048 }
5049 }
5050
5051 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
5052 SiS_UnLockCRT2(SiS_Pr);
5053
5054 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
5055
5056 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
5057 temp = SiS_GetCH701x(SiS_Pr,tempax: 0x66);
5058 temp &= 0x20;
5059 SiS_Chrontel701xBLOff(SiS_Pr);
5060 }
5061
5062 if(SiS_Pr->ChipType != SIS_550) {
5063 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
5064 }
5065
5066 if(SiS_Pr->ChipType == SIS_740) {
5067 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
5068 if(SiS_IsLCDOrLCDA(SiS_Pr)) {
5069 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
5070 }
5071 }
5072 }
5073
5074 temp1 = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
5075 if(!(temp1 & 0x80)) {
5076 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
5077 }
5078
5079 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
5080 if(temp) {
5081 SiS_Chrontel701xBLOn(SiS_Pr);
5082 }
5083 }
5084
5085 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
5086 if(SiS_CRT2IsLCD(SiS_Pr)) {
5087 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
5088 if(SiS_Pr->ChipType == SIS_550) {
5089 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x40);
5090 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x10);
5091 }
5092 }
5093 } else if(SiS_IsVAMode(SiS_Pr)) {
5094 if(SiS_Pr->ChipType != SIS_740) {
5095 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
5096 }
5097 }
5098
5099 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
5100 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
5101 }
5102
5103 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
5104 if(SiS_IsTVOrYPbPrOrScart(SiS_Pr)) {
5105 SiS_Chrontel701xOn(SiS_Pr);
5106 }
5107 if( (SiS_IsVAMode(SiS_Pr)) ||
5108 (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
5109 SiS_ChrontelDoSomething1(SiS_Pr);
5110 }
5111 }
5112
5113 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
5114 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
5115 if( (SiS_IsVAMode(SiS_Pr)) ||
5116 (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
5117 SiS_Chrontel701xBLOn(SiS_Pr);
5118 SiS_ChrontelInitTVVSync(SiS_Pr);
5119 }
5120 }
5121 } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
5122 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
5123 if(SiS_CRT2IsLCD(SiS_Pr)) {
5124 SiS_PanelDelay(SiS_Pr, DelayTime: 1);
5125 SiS_SetRegSR11ANDOR(SiS_Pr,DataAND: 0xF7,DataOR: 0x00);
5126 }
5127 }
5128 }
5129
5130#endif /* CONFIG_FB_SIS_315 */
5131
5132 } /* 310 series */
5133
5134 } /* LVDS */
5135
5136}
5137
5138/*********************************************/
5139/* SET PART 1 REGISTER GROUP */
5140/*********************************************/
5141
5142/* Set CRT2 OFFSET / PITCH */
5143static void
5144SiS_SetCRT2Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
5145 unsigned short RRTI)
5146{
5147 unsigned short offset;
5148 unsigned char temp;
5149
5150 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return;
5151
5152 offset = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex: RRTI);
5153
5154 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(offset & 0xFF));
5155 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,(offset >> 8));
5156
5157 temp = (unsigned char)(((offset >> 3) & 0xFF) + 1);
5158 if(offset & 0x07) temp++;
5159 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,temp);
5160}
5161
5162/* Set CRT2 sync and PanelLink mode */
5163static void
5164SiS_SetCRT2Sync(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RefreshRateTableIndex)
5165{
5166 unsigned short tempah=0, tempbl, infoflag;
5167
5168 tempbl = 0xC0;
5169
5170 if(SiS_Pr->UseCustomMode) {
5171 infoflag = SiS_Pr->CInfoFlag;
5172 } else {
5173 infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
5174 }
5175
5176 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { /* LVDS */
5177
5178 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5179 tempah = 0;
5180 } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) {
5181 tempah = SiS_Pr->SiS_LCDInfo;
5182 } else tempah = infoflag >> 8;
5183 tempah &= 0xC0;
5184 tempah |= 0x20;
5185 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5186 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5187 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
5188 (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
5189 tempah |= 0xf0;
5190 }
5191 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
5192 (SiS_Pr->SiS_IF_DEF_DSTN) ||
5193 (SiS_Pr->SiS_IF_DEF_TRUMPION) ||
5194 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
5195 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
5196 tempah |= 0x30;
5197 }
5198 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
5199 (SiS_Pr->SiS_IF_DEF_DSTN) ) {
5200 tempah &= ~0xc0;
5201 }
5202 }
5203 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5204 if(SiS_Pr->ChipType >= SIS_315H) {
5205 tempah >>= 3;
5206 tempah &= 0x18;
5207 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xE7,tempah);
5208 /* Don't care about 12/18/24 bit mode - TV is via VGA, not PL */
5209 } else {
5210 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,0xe0);
5211 }
5212 } else {
5213 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5214 }
5215
5216 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5217
5218 if(SiS_Pr->ChipType < SIS_315H) {
5219
5220#ifdef CONFIG_FB_SIS_300 /* ---- 300 series --- */
5221
5222 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* 630 - 301B(-DH) */
5223
5224 tempah = infoflag >> 8;
5225 tempbl = 0;
5226 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5227 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
5228 tempah = SiS_Pr->SiS_LCDInfo;
5229 tempbl = (tempah >> 6) & 0x03;
5230 }
5231 }
5232 tempah &= 0xC0;
5233 tempah |= 0x20;
5234 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5235 tempah |= 0xc0;
5236 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5237 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
5238 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
5239 }
5240
5241 } else { /* 630 - 301 */
5242
5243 tempah = ((infoflag >> 8) & 0xc0) | 0x20;
5244 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5245 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5246
5247 }
5248
5249#endif /* CONFIG_FB_SIS_300 */
5250
5251 } else {
5252
5253#ifdef CONFIG_FB_SIS_315 /* ------- 315 series ------ */
5254
5255 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { /* 315 - LVDS */
5256
5257 tempbl = 0;
5258 if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
5259 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
5260 tempah = infoflag >> 8;
5261 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
5262 tempbl = ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6);
5263 }
5264 } else if((SiS_Pr->SiS_CustomT == CUT_CLEVO1400) &&
5265 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)) {
5266 tempah = infoflag >> 8;
5267 tempbl = 0x03;
5268 } else {
5269 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
5270 tempbl = (tempah >> 6) & 0x03;
5271 tempbl |= 0x08;
5272 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempbl |= 0x04;
5273 }
5274 tempah &= 0xC0;
5275 tempah |= 0x20;
5276 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5277 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) tempah |= 0xc0;
5278 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5279 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
5280 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5281 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
5282 }
5283 }
5284
5285 } else { /* 315 - TMDS */
5286
5287 tempah = tempbl = infoflag >> 8;
5288 if(!SiS_Pr->UseCustomMode) {
5289 tempbl = 0;
5290 if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
5291 if(ModeNo <= 0x13) {
5292 tempah = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
5293 }
5294 }
5295 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5296 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5297 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
5298 tempah = SiS_Pr->SiS_LCDInfo;
5299 tempbl = (tempah >> 6) & 0x03;
5300 }
5301 }
5302 }
5303 }
5304 tempah &= 0xC0;
5305 tempah |= 0x20;
5306 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
5307 if(SiS_Pr->SiS_VBType & VB_NoLCD) {
5308 /* Imitate BIOS bug */
5309 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempah |= 0xc0;
5310 }
5311 if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
5312 tempah >>= 3;
5313 tempah &= 0x18;
5314 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xe7,tempah);
5315 } else {
5316 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
5317 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
5318 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5319 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
5320 }
5321 }
5322 }
5323
5324 }
5325#endif /* CONFIG_FB_SIS_315 */
5326 }
5327 }
5328}
5329
5330/* Set CRT2 FIFO on 300/540/630/730 */
5331#ifdef CONFIG_FB_SIS_300
5332static void
5333SiS_SetCRT2FIFO_300(struct SiS_Private *SiS_Pr,unsigned short ModeNo)
5334{
5335 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
5336 unsigned short temp, index, modeidindex, refreshratetableindex;
5337 unsigned short VCLK = 0, MCLK, colorth = 0, data2 = 0;
5338 unsigned short tempbx, tempcl, CRT1ModeNo, CRT2ModeNo, SelectRate_backup;
5339 unsigned int data, pci50, pciA0;
5340 static const unsigned char colortharray[] = {
5341 1, 1, 2, 2, 3, 4
5342 };
5343
5344 SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;
5345
5346 if(!SiS_Pr->CRT1UsesCustomMode) {
5347
5348 CRT1ModeNo = SiS_Pr->SiS_CRT1Mode; /* get CRT1 ModeNo */
5349 SiS_SearchModeID(SiS_Pr, &CRT1ModeNo, &modeidindex);
5350 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
5351 SiS_Pr->SiS_SelectCRT2Rate = 0;
5352 refreshratetableindex = SiS_GetRatePtr(SiS_Pr, ModeNo: CRT1ModeNo, ModeIdIndex: modeidindex);
5353
5354 if(CRT1ModeNo >= 0x13) {
5355 /* Get VCLK */
5356 index = SiS_GetRefCRTVCLK(SiS_Pr, Index: refreshratetableindex, UseWide: SiS_Pr->SiS_UseWide);
5357 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
5358
5359 /* Get colordepth */
5360 colorth = SiS_GetColorDepth(SiS_Pr,ModeNo: CRT1ModeNo,ModeIdIndex: modeidindex) >> 1;
5361 if(!colorth) colorth++;
5362 }
5363
5364 } else {
5365
5366 CRT1ModeNo = 0xfe;
5367
5368 /* Get VCLK */
5369 VCLK = SiS_Pr->CSRClock_CRT1;
5370
5371 /* Get color depth */
5372 colorth = colortharray[((SiS_Pr->CModeFlag_CRT1 & ModeTypeMask) - 2)];
5373
5374 }
5375
5376 if(CRT1ModeNo >= 0x13) {
5377 /* Get MCLK */
5378 if(SiS_Pr->ChipType == SIS_300) {
5379 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A);
5380 } else {
5381 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A);
5382 }
5383 index &= 0x07;
5384 MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;
5385
5386 temp = ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) >> 6) & 0x03) << 1;
5387 if(!temp) temp++;
5388 temp <<= 2;
5389
5390 data2 = temp - ((colorth * VCLK) / MCLK);
5391
5392 temp = (28 * 16) % data2;
5393 data2 = (28 * 16) / data2;
5394 if(temp) data2++;
5395
5396 if(SiS_Pr->ChipType == SIS_300) {
5397
5398 SiS_GetFIFOThresholdIndex300(SiS_Pr, tempbx: &tempbx, tempcl: &tempcl);
5399 data = SiS_GetFIFOThresholdB300(tempbx, tempcl);
5400
5401 } else {
5402
5403 pci50 = sisfb_read_nbridge_pci_dword(SiS_Pr, reg: 0x50);
5404 pciA0 = sisfb_read_nbridge_pci_dword(SiS_Pr, reg: 0xa0);
5405
5406 if(SiS_Pr->ChipType == SIS_730) {
5407
5408 index = (unsigned short)(((pciA0 >> 28) & 0x0f) * 3);
5409 index += (unsigned short)(((pci50 >> 9)) & 0x03);
5410
5411 /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */
5412 index = 0; /* -- do it like the BIOS anyway... */
5413
5414 } else {
5415
5416 pci50 >>= 24;
5417 pciA0 >>= 24;
5418
5419 index = (pci50 >> 1) & 0x07;
5420
5421 if(pci50 & 0x01) index += 6;
5422 if(!(pciA0 & 0x01)) index += 24;
5423
5424 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80) index += 12;
5425
5426 }
5427
5428 data = SiS_GetLatencyFactor630(SiS_Pr, index) + 15;
5429 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80)) data += 5;
5430
5431 }
5432
5433 data += data2; /* CRT1 Request Period */
5434
5435 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5436 SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5437
5438 if(!SiS_Pr->UseCustomMode) {
5439
5440 CRT2ModeNo = ModeNo;
5441 SiS_SearchModeID(SiS_Pr, &CRT2ModeNo, &modeidindex);
5442
5443 refreshratetableindex = SiS_GetRatePtr(SiS_Pr, ModeNo: CRT2ModeNo, ModeIdIndex: modeidindex);
5444
5445 /* Get VCLK */
5446 index = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo: CRT2ModeNo, ModeIdIndex: modeidindex, RefreshRateTableIndex: refreshratetableindex);
5447 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
5448
5449 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
5450 if(SiS_Pr->SiS_UseROM) {
5451 if(ROMAddr[0x220] & 0x01) {
5452 VCLK = ROMAddr[0x229] | (ROMAddr[0x22a] << 8);
5453 }
5454 }
5455 }
5456
5457 } else {
5458
5459 /* Get VCLK */
5460 CRT2ModeNo = 0xfe;
5461 VCLK = SiS_Pr->CSRClock;
5462
5463 }
5464
5465 /* Get colordepth */
5466 colorth = SiS_GetColorDepth(SiS_Pr,ModeNo: CRT2ModeNo,ModeIdIndex: modeidindex) >> 1;
5467 if(!colorth) colorth++;
5468
5469 data = data * VCLK * colorth;
5470 temp = data % (MCLK << 4);
5471 data = data / (MCLK << 4);
5472 if(temp) data++;
5473
5474 if(data < 6) data = 6;
5475 else if(data > 0x14) data = 0x14;
5476
5477 if(SiS_Pr->ChipType == SIS_300) {
5478 temp = 0x16;
5479 if((data <= 0x0f) || (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024))
5480 temp = 0x13;
5481 } else {
5482 temp = 0x16;
5483 if(( (SiS_Pr->ChipType == SIS_630) ||
5484 (SiS_Pr->ChipType == SIS_730) ) &&
5485 (SiS_Pr->ChipRevision >= 0x30))
5486 temp = 0x1b;
5487 }
5488 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0xe0,temp);
5489
5490 if((SiS_Pr->ChipType == SIS_630) &&
5491 (SiS_Pr->ChipRevision >= 0x30)) {
5492 if(data > 0x13) data = 0x13;
5493 }
5494 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,0xe0,data);
5495
5496 } else { /* If mode <= 0x13, we just restore everything */
5497
5498 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5499 SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5500
5501 }
5502}
5503#endif
5504
5505/* Set CRT2 FIFO on 315/330 series */
5506#ifdef CONFIG_FB_SIS_315
5507static void
5508SiS_SetCRT2FIFO_310(struct SiS_Private *SiS_Pr)
5509{
5510 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3B);
5511 if( (SiS_Pr->ChipType == SIS_760) &&
5512 (SiS_Pr->SiS_SysFlags & SF_760LFB) &&
5513 (SiS_Pr->SiS_ModeType == Mode32Bpp) &&
5514 (SiS_Pr->SiS_VGAHDE >= 1280) &&
5515 (SiS_Pr->SiS_VGAVDE >= 1024) ) {
5516 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x03);
5517 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3b);
5518 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5519 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x01);
5520 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5521 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,0x6e);
5522 } else {
5523 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3f,0x04);
5524 }
5525
5526}
5527#endif
5528
5529static unsigned short
5530SiS_GetVGAHT2(struct SiS_Private *SiS_Pr)
5531{
5532 unsigned int tempax,tempbx;
5533
5534 tempbx = (SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) * SiS_Pr->SiS_RVBHCMAX;
5535 tempax = (SiS_Pr->SiS_VT - SiS_Pr->SiS_VDE) * SiS_Pr->SiS_RVBHCFACT;
5536 tempax = (tempax * SiS_Pr->SiS_HT) / tempbx;
5537 return (unsigned short)tempax;
5538}
5539
5540/* Set Part 1 / SiS bridge slave mode */
5541static void
5542SiS_SetGroup1_301(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,
5543 unsigned short RefreshRateTableIndex)
5544{
5545 unsigned short temp, modeflag, i, j, xres=0, VGAVDE;
5546 static const unsigned short CRTranslation[] = {
5547 /* CR0 CR1 CR2 CR3 CR4 CR5 CR6 CR7 */
5548 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
5549 /* CR8 CR9 SR0A SR0B SR0C SR0D SR0E CR0F */
5550 0x00, 0x0b, 0x17, 0x18, 0x19, 0x00, 0x1a, 0x00,
5551 /* CR10 CR11 CR12 CR13 CR14 CR15 CR16 CR17 */
5552 0x0c, 0x0d, 0x0e, 0x00, 0x0f, 0x10, 0x11, 0x00
5553 };
5554
5555 if(ModeNo <= 0x13) {
5556 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5557 } else if(SiS_Pr->UseCustomMode) {
5558 modeflag = SiS_Pr->CModeFlag;
5559 xres = SiS_Pr->CHDisplay;
5560 } else {
5561 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5562 xres = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes;
5563 }
5564
5565 /* The following is only done if bridge is in slave mode: */
5566
5567 if(SiS_Pr->ChipType >= SIS_315H) {
5568 if(xres >= 1600) { /* BIOS: == 1600 */
5569 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x31,0x04);
5570 }
5571 }
5572
5573 SiS_Pr->CHTotal = 8224; /* Max HT, 0x2020, results in 0x3ff in registers */
5574
5575 SiS_Pr->CHDisplay = SiS_Pr->SiS_VGAHDE;
5576 if(modeflag & HalfDCLK) SiS_Pr->CHDisplay >>= 1;
5577
5578 SiS_Pr->CHBlankStart = SiS_Pr->CHDisplay;
5579 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5580 SiS_Pr->CHBlankStart += 16;
5581 }
5582
5583 SiS_Pr->CHBlankEnd = 32;
5584 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5585 if(xres == 1600) SiS_Pr->CHBlankEnd += 80;
5586 }
5587
5588 temp = SiS_Pr->SiS_VGAHT - 96;
5589 if(!(modeflag & HalfDCLK)) temp -= 32;
5590 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
5591 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x04);
5592 temp |= ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x0b) & 0xc0) << 2);
5593 temp -= 3;
5594 temp <<= 3;
5595 } else {
5596 if(SiS_Pr->SiS_RVBHRS2) temp = SiS_Pr->SiS_RVBHRS2;
5597 }
5598 SiS_Pr->CHSyncStart = temp;
5599
5600 SiS_Pr->CHSyncEnd = 0xffe8; /* results in 0x2000 in registers */
5601
5602 SiS_Pr->CVTotal = 2049; /* Max VT, 0x0801, results in 0x7ff in registers */
5603
5604 VGAVDE = SiS_Pr->SiS_VGAVDE;
5605 if (VGAVDE == 357) VGAVDE = 350;
5606 else if(VGAVDE == 360) VGAVDE = 350;
5607 else if(VGAVDE == 375) VGAVDE = 350;
5608 else if(VGAVDE == 405) VGAVDE = 400;
5609 else if(VGAVDE == 420) VGAVDE = 400;
5610 else if(VGAVDE == 525) VGAVDE = 480;
5611 else if(VGAVDE == 1056) VGAVDE = 1024;
5612 SiS_Pr->CVDisplay = VGAVDE;
5613
5614 SiS_Pr->CVBlankStart = SiS_Pr->CVDisplay;
5615
5616 SiS_Pr->CVBlankEnd = 1;
5617 if(ModeNo == 0x3c) SiS_Pr->CVBlankEnd = 226;
5618
5619 temp = (SiS_Pr->SiS_VGAVT - VGAVDE) >> 1;
5620 SiS_Pr->CVSyncStart = VGAVDE + temp;
5621
5622 temp >>= 3;
5623 SiS_Pr->CVSyncEnd = SiS_Pr->CVSyncStart + temp;
5624
5625 SiS_CalcCRRegisters(SiS_Pr, depth: 0);
5626 SiS_Pr->CCRT1CRTC[16] &= ~0xE0;
5627
5628 for(i = 0; i <= 7; i++) {
5629 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[i]);
5630 }
5631 for(i = 0x10, j = 8; i <= 0x12; i++, j++) {
5632 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5633 }
5634 for(i = 0x15, j = 11; i <= 0x16; i++, j++) {
5635 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5636 }
5637 for(i = 0x0a, j = 13; i <= 0x0c; i++, j++) {
5638 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5639 }
5640
5641 temp = SiS_Pr->CCRT1CRTC[16] & 0xE0;
5642 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x0E],0x1F,temp);
5643
5644 temp = (SiS_Pr->CCRT1CRTC[16] & 0x01) << 5;
5645 if(modeflag & DoubleScanMode) temp |= 0x80;
5646 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x09],0x5F,temp);
5647
5648 temp = 0;
5649 temp |= (SiS_GetReg(SiS_Pr->SiS_P3c4,0x01) & 0x01);
5650 if(modeflag & HalfDCLK) temp |= 0x08;
5651 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* SR01: HalfDCLK[3], 8/9 div dotclock[0] */
5652
5653 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,0x00); /* CR14: (text mode: underline location) */
5654 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,0x00); /* CR17: n/a */
5655
5656 temp = 0;
5657 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5658 temp = (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) << 7;
5659 }
5660 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* SR0E, dither[7] */
5661
5662 temp = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
5663 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp); /* ? */
5664}
5665
5666/* Setup panel link
5667 * This is used for LVDS, LCDA and Chrontel TV output
5668 * 300/LVDS+TV, 300/301B-DH, 315/LVDS+TV, 315/LCDA
5669 */
5670static void
5671SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
5672 unsigned short RefreshRateTableIndex)
5673{
5674 unsigned short modeflag, resinfo = 0;
5675 unsigned short push2, tempax, tempbx, tempcx, temp;
5676 unsigned int tempeax = 0, tempebx, tempecx, tempvcfact = 0;
5677 bool islvds = false, issis = false, chkdclkfirst = false;
5678#ifdef CONFIG_FB_SIS_300
5679 unsigned short crt2crtc = 0;
5680#endif
5681#ifdef CONFIG_FB_SIS_315
5682 unsigned short pushcx;
5683#endif
5684
5685 if(ModeNo <= 0x13) {
5686 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5687 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
5688#ifdef CONFIG_FB_SIS_300
5689 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
5690#endif
5691 } else if(SiS_Pr->UseCustomMode) {
5692 modeflag = SiS_Pr->CModeFlag;
5693 } else {
5694 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5695 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
5696#ifdef CONFIG_FB_SIS_300
5697 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
5698#endif
5699 }
5700
5701 /* is lvds if really LVDS, or 301B-DH with external LVDS transmitter */
5702 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
5703 islvds = true;
5704 }
5705
5706 /* is really sis if sis bridge, but not 301B-DH */
5707 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
5708 issis = true;
5709 }
5710
5711 if((SiS_Pr->ChipType >= SIS_315H) && (islvds) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA))) {
5712 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
5713 chkdclkfirst = true;
5714 }
5715 }
5716
5717#ifdef CONFIG_FB_SIS_315
5718 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
5719 if(IS_SIS330) {
5720 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5721 } else if(IS_SIS740) {
5722 if(islvds) {
5723 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5724 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x03);
5725 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5726 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5727 }
5728 } else {
5729 if(islvds) {
5730 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5731 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x00);
5732 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5733 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2D,0x0f);
5734 if(SiS_Pr->SiS_VBType & VB_SIS30xC) {
5735 if((SiS_Pr->SiS_LCDResInfo == Panel_1024x768) ||
5736 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
5737 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x20);
5738 }
5739 }
5740 }
5741 }
5742 }
5743#endif
5744
5745 /* Horizontal */
5746
5747 tempax = SiS_Pr->SiS_LCDHDES;
5748 if(islvds) {
5749 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5750 if(!SiS_Pr->SiS_IF_DEF_FSTN && !SiS_Pr->SiS_IF_DEF_DSTN) {
5751 if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) &&
5752 (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
5753 tempax -= 8;
5754 }
5755 }
5756 }
5757 }
5758
5759 temp = (tempax & 0x0007);
5760 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* BPLHDESKEW[2:0] */
5761 temp = (tempax >> 3) & 0x00FF;
5762 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* BPLHDESKEW[10:3] */
5763
5764 tempbx = SiS_Pr->SiS_HDE;
5765 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5766 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5767 tempbx = SiS_Pr->PanelXRes;
5768 }
5769 if((SiS_Pr->SiS_LCDResInfo == Panel_320x240_1) ||
5770 (SiS_Pr->SiS_LCDResInfo == Panel_320x240_2) ||
5771 (SiS_Pr->SiS_LCDResInfo == Panel_320x240_3)) {
5772 tempbx >>= 1;
5773 }
5774 }
5775
5776 tempax += tempbx;
5777 if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;
5778
5779 temp = tempax;
5780 if(temp & 0x07) temp += 8;
5781 temp >>= 3;
5782 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp); /* BPLHDEE */
5783
5784 tempcx = (SiS_Pr->SiS_HT - tempbx) >> 2;
5785
5786 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5787 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5788 if(SiS_Pr->PanelHRS != 999) tempcx = SiS_Pr->PanelHRS;
5789 }
5790 }
5791
5792 tempcx += tempax;
5793 if(tempcx >= SiS_Pr->SiS_HT) tempcx -= SiS_Pr->SiS_HT;
5794
5795 temp = (tempcx >> 3) & 0x00FF;
5796 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5797 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5798 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5799 switch(ModeNo) {
5800 case 0x04:
5801 case 0x05:
5802 case 0x0d: temp = 0x56; break;
5803 case 0x10: temp = 0x60; break;
5804 case 0x13: temp = 0x5f; break;
5805 case 0x40:
5806 case 0x41:
5807 case 0x4f:
5808 case 0x43:
5809 case 0x44:
5810 case 0x62:
5811 case 0x56:
5812 case 0x53:
5813 case 0x5d:
5814 case 0x5e: temp = 0x54; break;
5815 }
5816 }
5817 }
5818 }
5819 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,temp); /* BPLHRS */
5820
5821 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5822 temp += 2;
5823 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5824 temp += 8;
5825 if(SiS_Pr->PanelHRE != 999) {
5826 temp = tempcx + SiS_Pr->PanelHRE;
5827 if(temp >= SiS_Pr->SiS_HT) temp -= SiS_Pr->SiS_HT;
5828 temp >>= 3;
5829 }
5830 }
5831 } else {
5832 temp += 10;
5833 }
5834
5835 temp &= 0x1F;
5836 temp |= ((tempcx & 0x07) << 5);
5837 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,temp); /* BPLHRE */
5838
5839 /* Vertical */
5840
5841 tempax = SiS_Pr->SiS_VGAVDE;
5842 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5843 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5844 tempax = SiS_Pr->PanelYRes;
5845 }
5846 }
5847
5848 tempbx = SiS_Pr->SiS_LCDVDES + tempax;
5849 if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5850
5851 push2 = tempbx;
5852
5853 tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE;
5854 if(SiS_Pr->ChipType < SIS_315H) {
5855 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5856 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5857 tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->PanelYRes;
5858 }
5859 }
5860 }
5861 if(islvds) tempcx >>= 1;
5862 else tempcx >>= 2;
5863
5864 if( (SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
5865 (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) &&
5866 (SiS_Pr->PanelVRS != 999) ) {
5867 tempcx = SiS_Pr->PanelVRS;
5868 tempbx += tempcx;
5869 if(issis) tempbx++;
5870 } else {
5871 tempbx += tempcx;
5872 if(SiS_Pr->ChipType < SIS_315H) tempbx++;
5873 else if(issis) tempbx++;
5874 }
5875
5876 if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5877
5878 temp = tempbx & 0x00FF;
5879 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5880 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5881 if(ModeNo == 0x10) temp = 0xa9;
5882 }
5883 }
5884 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp); /* BPLVRS */
5885
5886 tempcx >>= 3;
5887 tempcx++;
5888
5889 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5890 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5891 if(SiS_Pr->PanelVRE != 999) tempcx = SiS_Pr->PanelVRE;
5892 }
5893 }
5894
5895 tempcx += tempbx;
5896 temp = tempcx & 0x000F;
5897 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp); /* BPLVRE */
5898
5899 temp = ((tempbx >> 8) & 0x07) << 3;
5900 if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
5901 if(SiS_Pr->SiS_HDE != 640) {
5902 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
5903 }
5904 } else if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
5905 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) temp |= 0x40;
5906 tempbx = 0x87;
5907 if((SiS_Pr->ChipType >= SIS_315H) ||
5908 (SiS_Pr->ChipRevision >= 0x30)) {
5909 tempbx = 0x07;
5910 if((SiS_Pr->SiS_IF_DEF_CH70xx == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
5911 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x03) temp |= 0x80;
5912 }
5913 /* Chrontel 701x operates in 24bit mode (8-8-8, 2x12bit multiplexed) via VGA2 */
5914 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5915 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5916 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x10) temp |= 0x80;
5917 } else {
5918 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80;
5919 }
5920 }
5921 }
5922 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,tempbx,temp);
5923
5924 tempbx = push2; /* BPLVDEE */
5925
5926 tempcx = SiS_Pr->SiS_LCDVDES; /* BPLVDES */
5927
5928 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5929 switch(SiS_Pr->SiS_LCDResInfo) {
5930 case Panel_640x480:
5931 tempbx = SiS_Pr->SiS_VGAVDE - 1;
5932 tempcx = SiS_Pr->SiS_VGAVDE;
5933 break;
5934 case Panel_800x600:
5935 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5936 if(resinfo == SIS_RI_800x600) tempcx++;
5937 }
5938 break;
5939 case Panel_1024x600:
5940 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5941 if(resinfo == SIS_RI_1024x600) tempcx++;
5942 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
5943 if(resinfo == SIS_RI_800x600) tempcx++;
5944 }
5945 }
5946 break;
5947 case Panel_1024x768:
5948 if(SiS_Pr->ChipType < SIS_315H) {
5949 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5950 if(resinfo == SIS_RI_1024x768) tempcx++;
5951 }
5952 }
5953 break;
5954 }
5955 }
5956
5957 temp = ((tempbx >> 8) & 0x07) << 3;
5958 temp |= ((tempcx >> 8) & 0x07);
5959 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1D,temp);
5960 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1C,tempbx);
5961 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1B,tempcx);
5962
5963 /* Vertical scaling */
5964
5965 if(SiS_Pr->ChipType < SIS_315H) {
5966
5967#ifdef CONFIG_FB_SIS_300 /* 300 series */
5968 tempeax = SiS_Pr->SiS_VGAVDE << 6;
5969 temp = (tempeax % (unsigned int)SiS_Pr->SiS_VDE);
5970 tempeax = tempeax / (unsigned int)SiS_Pr->SiS_VDE;
5971 if(temp) tempeax++;
5972
5973 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) tempeax = 0x3F;
5974
5975 temp = (unsigned short)(tempeax & 0x00FF);
5976 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,temp); /* BPLVCFACT */
5977 tempvcfact = temp;
5978#endif /* CONFIG_FB_SIS_300 */
5979
5980 } else {
5981
5982#ifdef CONFIG_FB_SIS_315 /* 315 series */
5983 tempeax = SiS_Pr->SiS_VGAVDE << 18;
5984 tempebx = SiS_Pr->SiS_VDE;
5985 temp = (tempeax % tempebx);
5986 tempeax = tempeax / tempebx;
5987 if(temp) tempeax++;
5988 tempvcfact = tempeax;
5989
5990 temp = (unsigned short)(tempeax & 0x00FF);
5991 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,temp);
5992 temp = (unsigned short)((tempeax & 0x00FF00) >> 8);
5993 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,temp);
5994 temp = (unsigned short)((tempeax & 0x00030000) >> 16);
5995 if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
5996 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,temp);
5997
5998 if(SiS_Pr->SiS_VBType & VB_SISPART4SCALER) {
5999 temp = (unsigned short)(tempeax & 0x00FF);
6000 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3c,temp);
6001 temp = (unsigned short)((tempeax & 0x00FF00) >> 8);
6002 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3b,temp);
6003 temp = (unsigned short)(((tempeax & 0x00030000) >> 16) << 6);
6004 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0x3f,temp);
6005 temp = 0;
6006 if(SiS_Pr->SiS_VDE != SiS_Pr->SiS_VGAVDE) temp |= 0x08;
6007 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x30,0xf3,temp);
6008 }
6009#endif
6010
6011 }
6012
6013 /* Horizontal scaling */
6014
6015 tempeax = SiS_Pr->SiS_VGAHDE; /* 1f = ( (VGAHDE * 65536) / ( (VGAHDE * 65536) / HDE ) ) - 1*/
6016 if(chkdclkfirst) {
6017 if(modeflag & HalfDCLK) tempeax >>= 1;
6018 }
6019 tempebx = tempeax << 16;
6020 if(SiS_Pr->SiS_HDE == tempeax) {
6021 tempecx = 0xFFFF;
6022 } else {
6023 tempecx = tempebx / SiS_Pr->SiS_HDE;
6024 if(SiS_Pr->ChipType >= SIS_315H) {
6025 if(tempebx % SiS_Pr->SiS_HDE) tempecx++;
6026 }
6027 }
6028
6029 if(SiS_Pr->ChipType >= SIS_315H) {
6030 tempeax = (tempebx / tempecx) - 1;
6031 } else {
6032 tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1;
6033 }
6034 tempecx = (tempecx << 16) | (tempeax & 0xFFFF);
6035 temp = (unsigned short)(tempecx & 0x00FF);
6036 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1F,temp);
6037
6038 if(SiS_Pr->ChipType >= SIS_315H) {
6039 tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
6040 tempbx = (unsigned short)(tempeax & 0xFFFF);
6041 } else {
6042 tempeax = SiS_Pr->SiS_VGAVDE << 6;
6043 tempbx = tempvcfact & 0x3f;
6044 if(tempbx == 0) tempbx = 64;
6045 tempeax /= tempbx;
6046 tempbx = (unsigned short)(tempeax & 0xFFFF);
6047 }
6048 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tempbx--;
6049 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
6050 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) tempbx = 1;
6051 else if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) tempbx = 1;
6052 }
6053
6054 temp = ((tempbx >> 8) & 0x07) << 3;
6055 temp = temp | ((tempecx >> 8) & 0x07);
6056 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x20,temp);
6057 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x21,tempbx);
6058
6059 tempecx >>= 16; /* BPLHCFACT */
6060 if(!chkdclkfirst) {
6061 if(modeflag & HalfDCLK) tempecx >>= 1;
6062 }
6063 temp = (unsigned short)((tempecx & 0xFF00) >> 8);
6064 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x22,temp);
6065 temp = (unsigned short)(tempecx & 0x00FF);
6066 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp);
6067
6068#ifdef CONFIG_FB_SIS_315
6069 if(SiS_Pr->ChipType >= SIS_315H) {
6070 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
6071 if((islvds) || (SiS_Pr->SiS_VBInfo & VB_SISLVDS)) {
6072 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x20);
6073 }
6074 } else {
6075 if(islvds) {
6076 if(SiS_Pr->ChipType == SIS_740) {
6077 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
6078 } else {
6079 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x23);
6080 }
6081 }
6082 }
6083 }
6084#endif
6085
6086#ifdef CONFIG_FB_SIS_300
6087 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
6088 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
6089 unsigned char *trumpdata;
6090 int i, j = crt2crtc;
6091 unsigned char TrumpMode13[4] = { 0x01, 0x10, 0x2c, 0x00 };
6092 unsigned char TrumpMode10_1[4] = { 0x01, 0x10, 0x27, 0x00 };
6093 unsigned char TrumpMode10_2[4] = { 0x01, 0x16, 0x10, 0x00 };
6094
6095 if(SiS_Pr->SiS_UseROM) {
6096 trumpdata = &ROMAddr[0x8001 + (j * 80)];
6097 } else {
6098 if(SiS_Pr->SiS_LCDTypeInfo == 0x0e) j += 7;
6099 trumpdata = &SiS300_TrumpionData[j][0];
6100 }
6101
6102 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xbf);
6103 for(i=0; i<5; i++) {
6104 SiS_SetTrumpionBlock(SiS_Pr, dataptr: trumpdata);
6105 }
6106 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6107 if(ModeNo == 0x13) {
6108 for(i=0; i<4; i++) {
6109 SiS_SetTrumpionBlock(SiS_Pr, dataptr: &TrumpMode13[0]);
6110 }
6111 } else if(ModeNo == 0x10) {
6112 for(i=0; i<4; i++) {
6113 SiS_SetTrumpionBlock(SiS_Pr, dataptr: &TrumpMode10_1[0]);
6114 SiS_SetTrumpionBlock(SiS_Pr, dataptr: &TrumpMode10_2[0]);
6115 }
6116 }
6117 }
6118 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
6119 }
6120#endif
6121
6122#ifdef CONFIG_FB_SIS_315
6123 if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
6124 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x25,0x00);
6125 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x26,0x00);
6126 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x27,0x00);
6127 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x28,0x87);
6128 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x29,0x5A);
6129 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2A,0x4B);
6130 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x07,0x03);
6131 tempax = SiS_Pr->SiS_HDE; /* Blps = lcdhdee(lcdhdes+HDE) + 64 */
6132 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
6133 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
6134 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
6135 tempax += 64;
6136 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,tempax & 0xff);
6137 temp = (tempax >> 8) << 3;
6138 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp);
6139 tempax += 32; /* Blpe = lBlps+32 */
6140 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,tempax & 0xff);
6141 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3A,0x00); /* Bflml = 0 */
6142 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x007);
6143
6144 tempax = SiS_Pr->SiS_VDE;
6145 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
6146 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
6147 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
6148 tempax >>= 1;
6149 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3B,tempax & 0xff);
6150 temp = (tempax >> 8) << 3;
6151 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);
6152
6153 tempeax = SiS_Pr->SiS_HDE;
6154 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
6155 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
6156 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempeax >>= 1;
6157 tempeax <<= 2; /* BDxFIFOSTOP = (HDE*4)/128 */
6158 temp = tempeax & 0x7f;
6159 tempeax >>= 7;
6160 if(temp) tempeax++;
6161 temp = tempeax & 0x3f;
6162 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,temp);
6163 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3F,0x00); /* BDxWadrst0 */
6164 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3E,0x00);
6165 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3D,0x10);
6166 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x040);
6167
6168 tempax = SiS_Pr->SiS_HDE;
6169 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
6170 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
6171 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
6172 tempax >>= 4; /* BDxWadroff = HDE*4/8/8 */
6173 pushcx = tempax;
6174 temp = tempax & 0x00FF;
6175 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,temp);
6176 temp = ((tempax & 0xFF00) >> 8) << 3;
6177 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port, 0x44, 0x07, temp);
6178
6179 tempax = SiS_Pr->SiS_VDE; /* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
6180 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
6181 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
6182 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
6183 tempeax = tempax * pushcx;
6184 temp = tempeax & 0xFF;
6185 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,temp);
6186 temp = (tempeax & 0xFF00) >> 8;
6187 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,temp);
6188 temp = ((tempeax & 0xFF0000) >> 16) | 0x10;
6189 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,temp);
6190 temp = ((tempeax & 0x01000000) >> 24) << 7;
6191 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port, 0x3C, 0x7F, temp);
6192
6193 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x03);
6194 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0x50);
6195 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,0x00);
6196 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x01);
6197 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0x38);
6198
6199 if(SiS_Pr->SiS_IF_DEF_FSTN) {
6200 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2b,0x02);
6201 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2c,0x00);
6202 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x00);
6203 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,0x0c);
6204 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,0x00);
6205 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,0x00);
6206 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,0x80);
6207 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,0xA0);
6208 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3a,0x00);
6209 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3b,0xf0);
6210 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3c,0x00);
6211 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3d,0x10);
6212 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3e,0x00);
6213 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3f,0x00);
6214 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,0x10);
6215 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,0x25);
6216 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,0x80);
6217 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,0x14);
6218 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x44,0x03);
6219 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,0x0a);
6220 }
6221 }
6222#endif /* CONFIG_FB_SIS_315 */
6223}
6224
6225/* Set Part 1 */
6226static void
6227SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6228 unsigned short RefreshRateTableIndex)
6229{
6230#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
6231 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
6232#endif
6233 unsigned short temp=0, tempax=0, tempbx=0, tempcx=0, bridgeadd=0;
6234 unsigned short pushbx=0, CRT1Index=0, modeflag, resinfo=0;
6235#ifdef CONFIG_FB_SIS_315
6236 unsigned short tempbl=0;
6237#endif
6238
6239 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
6240 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6241 return;
6242 }
6243
6244 if(ModeNo <= 0x13) {
6245 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6246 } else if(SiS_Pr->UseCustomMode) {
6247 modeflag = SiS_Pr->CModeFlag;
6248 } else {
6249 CRT1Index = SiS_GetRefCRT1CRTC(SiS_Pr, Index: RefreshRateTableIndex, UseWide: SiS_Pr->SiS_UseWideCRT2);
6250 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
6251 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6252 }
6253
6254 SiS_SetCRT2Offset(SiS_Pr, ModeNo, ModeIdIndex, RRTI: RefreshRateTableIndex);
6255
6256 if( ! ((SiS_Pr->ChipType >= SIS_315H) &&
6257 (SiS_Pr->SiS_IF_DEF_LVDS == 1) &&
6258 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
6259
6260 if(SiS_Pr->ChipType < SIS_315H ) {
6261#ifdef CONFIG_FB_SIS_300
6262 SiS_SetCRT2FIFO_300(SiS_Pr, ModeNo);
6263#endif
6264 } else {
6265#ifdef CONFIG_FB_SIS_315
6266 SiS_SetCRT2FIFO_310(SiS_Pr);
6267#endif
6268 }
6269
6270 /* 1. Horizontal setup */
6271
6272 if(SiS_Pr->ChipType < SIS_315H ) {
6273
6274#ifdef CONFIG_FB_SIS_300 /* ------------- 300 series --------------*/
6275
6276 temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
6277 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp); /* CRT2 Horizontal Total */
6278
6279 temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
6280 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp); /* CRT2 Horizontal Total Overflow [7:4] */
6281
6282 temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */
6283 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp); /* CRT2 Horizontal Display Enable End */
6284
6285 pushbx = SiS_Pr->SiS_VGAHDE + 12; /* bx BTVGA2HRS 0x0B,0x0C */
6286 tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2;
6287 tempbx = pushbx + tempcx;
6288 tempcx <<= 1;
6289 tempcx += tempbx;
6290
6291 bridgeadd = 12;
6292
6293#endif /* CONFIG_FB_SIS_300 */
6294
6295 } else {
6296
6297#ifdef CONFIG_FB_SIS_315 /* ------------------- 315/330 series --------------- */
6298
6299 tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HT 0x08,0x09 */
6300 if(modeflag & HalfDCLK) {
6301 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6302 tempcx >>= 1;
6303 } else {
6304 tempax = SiS_Pr->SiS_VGAHDE >> 1;
6305 tempcx = SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE + tempax;
6306 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
6307 tempcx = SiS_Pr->SiS_HT - tempax;
6308 }
6309 }
6310 }
6311 tempcx--;
6312 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,tempcx); /* CRT2 Horizontal Total */
6313 temp = (tempcx >> 4) & 0xF0;
6314 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp); /* CRT2 Horizontal Total Overflow [7:4] */
6315
6316 tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HDEE 0x0A,0x0C */
6317 tempbx = SiS_Pr->SiS_VGAHDE;
6318 tempcx -= tempbx;
6319 tempcx >>= 2;
6320 if(modeflag & HalfDCLK) {
6321 tempbx >>= 1;
6322 tempcx >>= 1;
6323 }
6324 tempbx += 16;
6325
6326 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,tempbx); /* CRT2 Horizontal Display Enable End */
6327
6328 pushbx = tempbx;
6329 tempcx >>= 1;
6330 tempbx += tempcx;
6331 tempcx += tempbx;
6332
6333 bridgeadd = 16;
6334
6335 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6336 if(SiS_Pr->ChipType >= SIS_661) {
6337 if((SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
6338 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
6339 if(resinfo == SIS_RI_1280x1024) {
6340 tempcx = (tempcx & 0xff00) | 0x30;
6341 } else if(resinfo == SIS_RI_1600x1200) {
6342 tempcx = (tempcx & 0xff00) | 0xff;
6343 }
6344 }
6345 }
6346 }
6347
6348#endif /* CONFIG_FB_SIS_315 */
6349
6350 } /* 315/330 series */
6351
6352 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6353
6354 if(SiS_Pr->UseCustomMode) {
6355 tempbx = SiS_Pr->CHSyncStart + bridgeadd;
6356 tempcx = SiS_Pr->CHSyncEnd + bridgeadd;
6357 tempax = SiS_Pr->SiS_VGAHT;
6358 if(modeflag & HalfDCLK) tempax >>= 1;
6359 tempax--;
6360 if(tempcx > tempax) tempcx = tempax;
6361 }
6362
6363 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6364 unsigned char cr4, cr14, cr5, cr15;
6365 if(SiS_Pr->UseCustomMode) {
6366 cr4 = SiS_Pr->CCRT1CRTC[4];
6367 cr14 = SiS_Pr->CCRT1CRTC[14];
6368 cr5 = SiS_Pr->CCRT1CRTC[5];
6369 cr15 = SiS_Pr->CCRT1CRTC[15];
6370 } else {
6371 cr4 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
6372 cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
6373 cr5 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
6374 cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
6375 }
6376 tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3; /* (VGAHRS-3)*8 */
6377 tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3; /* (VGAHRE-3)*8 */
6378 tempcx &= 0x00FF;
6379 tempcx |= (tempbx & 0xFF00);
6380 tempbx += bridgeadd;
6381 tempcx += bridgeadd;
6382 tempax = SiS_Pr->SiS_VGAHT;
6383 if(modeflag & HalfDCLK) tempax >>= 1;
6384 tempax--;
6385 if(tempcx > tempax) tempcx = tempax;
6386 }
6387
6388 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {
6389 tempbx = 1040;
6390 tempcx = 1044; /* HWCursor bug! */
6391 }
6392
6393 }
6394
6395 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,tempbx); /* CRT2 Horizontal Retrace Start */
6396
6397 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,tempcx); /* CRT2 Horizontal Retrace End */
6398
6399 temp = ((tempbx >> 8) & 0x0F) | ((pushbx >> 4) & 0xF0);
6400 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp); /* Overflow */
6401
6402 /* 2. Vertical setup */
6403
6404 tempcx = SiS_Pr->SiS_VGAVT - 1;
6405 temp = tempcx & 0x00FF;
6406
6407 if(SiS_Pr->ChipType < SIS_661) {
6408 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6409 if(SiS_Pr->ChipType < SIS_315H) {
6410 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6411 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
6412 temp--;
6413 }
6414 }
6415 } else {
6416 temp--;
6417 }
6418 } else if(SiS_Pr->ChipType >= SIS_315H) {
6419 temp--;
6420 }
6421 }
6422 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp); /* CRT2 Vertical Total */
6423
6424 tempbx = SiS_Pr->SiS_VGAVDE - 1;
6425 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,tempbx); /* CRT2 Vertical Display Enable End */
6426
6427 temp = ((tempbx >> 5) & 0x38) | ((tempcx >> 8) & 0x07);
6428 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,temp); /* Overflow */
6429
6430 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
6431 tempbx++;
6432 tempax = tempbx;
6433 tempcx++;
6434 tempcx -= tempax;
6435 tempcx >>= 2;
6436 tempbx += tempcx;
6437 if(tempcx < 4) tempcx = 4;
6438 tempcx >>= 2;
6439 tempcx += tempbx;
6440 tempcx++;
6441 } else {
6442 tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1; /* BTVGA2VRS 0x10,0x11 */
6443 tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1; /* BTVGA2VRE 0x11 */
6444 }
6445
6446 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6447 if(SiS_Pr->UseCustomMode) {
6448 tempbx = SiS_Pr->CVSyncStart;
6449 tempcx = SiS_Pr->CVSyncEnd;
6450 }
6451 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6452 unsigned char cr8, cr7, cr13;
6453 if(SiS_Pr->UseCustomMode) {
6454 cr8 = SiS_Pr->CCRT1CRTC[8];
6455 cr7 = SiS_Pr->CCRT1CRTC[7];
6456 cr13 = SiS_Pr->CCRT1CRTC[13];
6457 tempcx = SiS_Pr->CCRT1CRTC[9];
6458 } else {
6459 cr8 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8];
6460 cr7 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
6461 cr13 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
6462 tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
6463 }
6464 tempbx = cr8;
6465 if(cr7 & 0x04) tempbx |= 0x0100;
6466 if(cr7 & 0x80) tempbx |= 0x0200;
6467 if(cr13 & 0x08) tempbx |= 0x0400;
6468 }
6469 }
6470 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,tempbx); /* CRT2 Vertical Retrace Start */
6471
6472 temp = ((tempbx >> 4) & 0x70) | (tempcx & 0x0F);
6473 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,temp); /* CRT2 Vert. Retrace End; Overflow */
6474
6475 /* 3. Panel delay compensation */
6476
6477 if(SiS_Pr->ChipType < SIS_315H) {
6478
6479#ifdef CONFIG_FB_SIS_300 /* ---------- 300 series -------------- */
6480
6481 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6482 temp = 0x20;
6483 if(SiS_Pr->ChipType == SIS_300) {
6484 temp = 0x10;
6485 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) temp = 0x2c;
6486 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6487 }
6488 if(SiS_Pr->SiS_VBType & VB_SIS301) {
6489 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6490 }
6491 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960) temp = 0x24;
6492 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) temp = 0x2c;
6493 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x08;
6494 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6495 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) temp = 0x2c;
6496 else temp = 0x20;
6497 }
6498 if(SiS_Pr->SiS_UseROM) {
6499 if(ROMAddr[0x220] & 0x80) {
6500 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision)
6501 temp = ROMAddr[0x221];
6502 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)
6503 temp = ROMAddr[0x222];
6504 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)
6505 temp = ROMAddr[0x223];
6506 else
6507 temp = ROMAddr[0x224];
6508 }
6509 }
6510 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6511 if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC;
6512 }
6513
6514 } else {
6515 temp = 0x20;
6516 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
6517 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) temp = 0x04;
6518 }
6519 if(SiS_Pr->SiS_UseROM) {
6520 if(ROMAddr[0x220] & 0x80) {
6521 temp = ROMAddr[0x220];
6522 }
6523 }
6524 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6525 if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC;
6526 }
6527 }
6528
6529 temp &= 0x3c;
6530
6531 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
6532
6533#endif /* CONFIG_FB_SIS_300 */
6534
6535 } else {
6536
6537#ifdef CONFIG_FB_SIS_315 /* --------------- 315/330 series ---------------*/
6538
6539 if(SiS_Pr->ChipType < SIS_661) {
6540
6541 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6542
6543 if(SiS_Pr->ChipType == SIS_740) temp = 0x03;
6544 else temp = 0x00;
6545
6546 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x0a;
6547 tempbl = 0xF0;
6548 if(SiS_Pr->ChipType == SIS_650) {
6549 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6550 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F;
6551 }
6552 }
6553
6554 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) {
6555 temp = 0x08;
6556 tempbl = 0;
6557 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
6558 if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0;
6559 }
6560 }
6561
6562 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp); /* Panel Link Delay Compensation */
6563 }
6564
6565 } /* < 661 */
6566
6567 tempax = 0;
6568 if(modeflag & DoubleScanMode) tempax |= 0x80;
6569 if(modeflag & HalfDCLK) tempax |= 0x40;
6570 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax);
6571
6572#endif /* CONFIG_FB_SIS_315 */
6573
6574 }
6575
6576 } /* Slavemode */
6577
6578 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6579 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
6580 /* For 301BDH with LCD, we set up the Panel Link */
6581 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6582 } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6583 SiS_SetGroup1_301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6584 }
6585 } else {
6586 if(SiS_Pr->ChipType < SIS_315H) {
6587 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6588 } else {
6589 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6590 if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
6591 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex);
6592 }
6593 } else {
6594 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex);
6595 }
6596 }
6597 }
6598}
6599
6600/*********************************************/
6601/* SET PART 2 REGISTER GROUP */
6602/*********************************************/
6603
6604#ifdef CONFIG_FB_SIS_315
6605static unsigned char *
6606SiS_GetGroup2CLVXPtr(struct SiS_Private *SiS_Pr, int tabletype)
6607{
6608 const unsigned char *tableptr = NULL;
6609 unsigned short a, b, p = 0;
6610
6611 a = SiS_Pr->SiS_VGAHDE;
6612 b = SiS_Pr->SiS_HDE;
6613 if(tabletype) {
6614 a = SiS_Pr->SiS_VGAVDE;
6615 b = SiS_Pr->SiS_VDE;
6616 }
6617
6618 if(a < b) {
6619 tableptr = SiS_Part2CLVX_1;
6620 } else if(a == b) {
6621 tableptr = SiS_Part2CLVX_2;
6622 } else {
6623 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6624 tableptr = SiS_Part2CLVX_4;
6625 } else {
6626 tableptr = SiS_Part2CLVX_3;
6627 }
6628 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6629 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) tableptr = SiS_Part2CLVX_3;
6630 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tableptr = SiS_Part2CLVX_3;
6631 else tableptr = SiS_Part2CLVX_5;
6632 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6633 tableptr = SiS_Part2CLVX_6;
6634 }
6635 do {
6636 if((tableptr[p] | tableptr[p+1] << 8) == a) break;
6637 p += 0x42;
6638 } while((tableptr[p] | tableptr[p+1] << 8) != 0xffff);
6639 if((tableptr[p] | tableptr[p+1] << 8) == 0xffff) p -= 0x42;
6640 }
6641 p += 2;
6642 return ((unsigned char *)&tableptr[p]);
6643}
6644
6645static void
6646SiS_SetGroup2_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6647 unsigned short RefreshRateTableIndex)
6648{
6649 unsigned char *tableptr;
6650 unsigned char temp;
6651 int i, j;
6652
6653 if(!(SiS_Pr->SiS_VBType & VB_SISTAP4SCALER)) return;
6654
6655 tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, tabletype: 0);
6656 for(i = 0x80, j = 0; i <= 0xbf; i++, j++) {
6657 SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6658 }
6659 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6660 tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, tabletype: 1);
6661 for(i = 0xc0, j = 0; i <= 0xff; i++, j++) {
6662 SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6663 }
6664 }
6665 temp = 0x10;
6666 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp |= 0x04;
6667 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xeb,temp);
6668}
6669
6670static bool
6671SiS_GetCRT2Part2Ptr(struct SiS_Private *SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,
6672 unsigned short RefreshRateTableIndex,unsigned short *CRT2Index,
6673 unsigned short *ResIndex)
6674{
6675
6676 if(SiS_Pr->ChipType < SIS_315H) return false;
6677
6678 if(ModeNo <= 0x13)
6679 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6680 else
6681 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6682
6683 (*ResIndex) &= 0x3f;
6684 (*CRT2Index) = 0;
6685
6686 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6687 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6688 (*CRT2Index) = 200;
6689 }
6690 }
6691
6692 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
6693 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6694 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) (*CRT2Index) = 206;
6695 }
6696 }
6697 return (((*CRT2Index) != 0));
6698}
6699#endif
6700
6701#ifdef CONFIG_FB_SIS_300
6702static void
6703SiS_Group2LCDSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short crt2crtc)
6704{
6705 unsigned short tempcx;
6706 static const unsigned char atable[] = {
6707 0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,
6708 0xab,0x87,0xab,0x9e,0xe7,0x02,0x02
6709 };
6710
6711 if(!SiS_Pr->UseCustomMode) {
6712 if( ( ( (SiS_Pr->ChipType == SIS_630) ||
6713 (SiS_Pr->ChipType == SIS_730) ) &&
6714 (SiS_Pr->ChipRevision > 2) ) &&
6715 (SiS_Pr->SiS_LCDResInfo == Panel_1024x768) &&
6716 (!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) &&
6717 (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
6718 if(ModeNo == 0x13) {
6719 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xB9);
6720 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0xCC);
6721 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xA6);
6722 } else if((crt2crtc & 0x3F) == 4) {
6723 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x2B);
6724 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x13);
6725 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xE5);
6726 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0x08);
6727 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xE2);
6728 }
6729 }
6730
6731 if(SiS_Pr->ChipType < SIS_315H) {
6732 if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
6733 crt2crtc &= 0x1f;
6734 tempcx = 0;
6735 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6736 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6737 tempcx += 7;
6738 }
6739 }
6740 tempcx += crt2crtc;
6741 if(crt2crtc >= 4) {
6742 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xff);
6743 }
6744
6745 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6746 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6747 if(crt2crtc == 4) {
6748 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x28);
6749 }
6750 }
6751 }
6752 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x18);
6753 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
6754 }
6755 }
6756 }
6757}
6758
6759/* For ECS A907. Highly preliminary. */
6760static void
6761SiS_Set300Part2Regs(struct SiS_Private *SiS_Pr, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex,
6762 unsigned short ModeNo)
6763{
6764 const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
6765 unsigned short crt2crtc, resindex;
6766 int i, j;
6767
6768 if(SiS_Pr->ChipType != SIS_300) return;
6769 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;
6770 if(SiS_Pr->UseCustomMode) return;
6771
6772 if(ModeNo <= 0x13) {
6773 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6774 } else {
6775 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6776 }
6777
6778 resindex = crt2crtc & 0x3F;
6779 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6780 else CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2;
6781
6782 /* The BIOS code (1.16.51,56) is obviously a fragment! */
6783 if(ModeNo > 0x13) {
6784 CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6785 resindex = 4;
6786 }
6787
6788 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
6789 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
6790 for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
6791 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6792 }
6793 for(j = 0x1c; j <= 0x1d; i++, j++ ) {
6794 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6795 }
6796 for(j = 0x1f; j <= 0x21; i++, j++ ) {
6797 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6798 }
6799 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
6800 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
6801}
6802#endif
6803
6804static void
6805SiS_SetTVSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
6806{
6807 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;
6808 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) return;
6809 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) return;
6810
6811 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
6812 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6813 static const unsigned char specialtv[] = {
6814 0xa7,0x07,0xf2,0x6e,0x17,0x8b,0x73,0x53,
6815 0x13,0x40,0x34,0xf4,0x63,0xbb,0xcc,0x7a,
6816 0x58,0xe4,0x73,0xda,0x13
6817 };
6818 int i, j;
6819 for(i = 0x1c, j = 0; i <= 0x30; i++, j++) {
6820 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,specialtv[j]);
6821 }
6822 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,0x72);
6823 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750)) {
6824 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6825 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14);
6826 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1b);
6827 } else {
6828 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14); /* 15 */
6829 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1a); /* 1b */
6830 }
6831 }
6832 }
6833 } else {
6834 if((ModeNo == 0x38) || (ModeNo == 0x4a) || (ModeNo == 0x64) ||
6835 (ModeNo == 0x52) || (ModeNo == 0x58) || (ModeNo == 0x5c)) {
6836 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b); /* 21 */
6837 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54); /* 5a */
6838 } else {
6839 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1a); /* 21 */
6840 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x53); /* 5a */
6841 }
6842 }
6843}
6844
6845static void
6846SiS_SetGroup2_Tail(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
6847{
6848 unsigned short temp;
6849
6850 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6851 if(SiS_Pr->SiS_VGAVDE == 525) {
6852 temp = 0xc3;
6853 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6854 temp++;
6855 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp += 2;
6856 }
6857 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6858 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xb3);
6859 } else if(SiS_Pr->SiS_VGAVDE == 420) {
6860 temp = 0x4d;
6861 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6862 temp++;
6863 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp++;
6864 }
6865 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6866 }
6867 }
6868
6869 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6870 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
6871 if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
6872 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x1a,0x03);
6873 /* Not always for LV, see SetGrp2 */
6874 }
6875 temp = 1;
6876 if(ModeNo <= 0x13) temp = 3;
6877 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0b,temp);
6878 }
6879#if 0
6880 /* 651+301C, for 1280x768 - do I really need that? */
6881 if((SiS_Pr->SiS_PanelXRes == 1280) && (SiS_Pr->SiS_PanelYRes == 768)) {
6882 if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) {
6883 if(((SiS_Pr->SiS_HDE == 640) && (SiS_Pr->SiS_VDE == 480)) ||
6884 ((SiS_Pr->SiS_HDE == 320) && (SiS_Pr->SiS_VDE == 240))) {
6885 SiS_SetReg(SiS_Part2Port,0x01,0x2b);
6886 SiS_SetReg(SiS_Part2Port,0x02,0x13);
6887 SiS_SetReg(SiS_Part2Port,0x04,0xe5);
6888 SiS_SetReg(SiS_Part2Port,0x05,0x08);
6889 SiS_SetReg(SiS_Part2Port,0x06,0xe2);
6890 SiS_SetReg(SiS_Part2Port,0x1c,0x21);
6891 SiS_SetReg(SiS_Part2Port,0x1d,0x45);
6892 SiS_SetReg(SiS_Part2Port,0x1f,0x0b);
6893 SiS_SetReg(SiS_Part2Port,0x20,0x00);
6894 SiS_SetReg(SiS_Part2Port,0x21,0xa9);
6895 SiS_SetReg(SiS_Part2Port,0x23,0x0b);
6896 SiS_SetReg(SiS_Part2Port,0x25,0x04);
6897 }
6898 }
6899 }
6900#endif
6901 }
6902}
6903
6904static void
6905SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6906 unsigned short RefreshRateTableIndex)
6907{
6908 unsigned short i, j, tempax, tempbx, tempcx, tempch, tempcl, temp;
6909 unsigned short push2, modeflag, crt2crtc, bridgeoffset;
6910 unsigned int longtemp, PhaseIndex;
6911 bool newtvphase;
6912 const unsigned char *TimingPoint;
6913#ifdef CONFIG_FB_SIS_315
6914 unsigned short resindex, CRT2Index;
6915 const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
6916
6917 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
6918#endif
6919
6920 if(ModeNo <= 0x13) {
6921 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6922 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6923 } else if(SiS_Pr->UseCustomMode) {
6924 modeflag = SiS_Pr->CModeFlag;
6925 crt2crtc = 0;
6926 } else {
6927 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6928 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6929 }
6930
6931 temp = 0;
6932 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO)) temp |= 0x08;
6933 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO)) temp |= 0x04;
6934 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) temp |= 0x02;
6935 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp |= 0x01;
6936
6937 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) temp |= 0x10;
6938
6939 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x00,temp);
6940
6941 PhaseIndex = 0x01; /* SiS_PALPhase */
6942 TimingPoint = SiS_Pr->SiS_PALTiming;
6943
6944 newtvphase = false;
6945 if( (SiS_Pr->SiS_VBType & VB_SIS30xBLV) &&
6946 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6947 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6948 newtvphase = true;
6949 }
6950
6951 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6952
6953 TimingPoint = SiS_Pr->SiS_HiTVExtTiming;
6954 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6955 TimingPoint = SiS_Pr->SiS_HiTVSt2Timing;
6956 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
6957 TimingPoint = SiS_Pr->SiS_HiTVSt1Timing;
6958 }
6959 }
6960
6961 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6962
6963 i = 0;
6964 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) i = 2;
6965 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) i = 1;
6966
6967 TimingPoint = &SiS_YPbPrTable[i][0];
6968
6969 PhaseIndex = 0x00; /* SiS_NTSCPhase */
6970
6971 } else if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6972
6973 if(newtvphase) PhaseIndex = 0x09; /* SiS_PALPhase2 */
6974
6975 } else {
6976
6977 TimingPoint = SiS_Pr->SiS_NTSCTiming;
6978 PhaseIndex = (SiS_Pr->SiS_TVMode & TVSetNTSCJ) ? 0x01 : 0x00; /* SiS_PALPhase : SiS_NTSCPhase */
6979 if(newtvphase) PhaseIndex += 8; /* SiS_PALPhase2 : SiS_NTSCPhase2 */
6980
6981 }
6982
6983 if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) {
6984 PhaseIndex = (SiS_Pr->SiS_TVMode & TVSetPALM) ? 0x02 : 0x03; /* SiS_PALMPhase : SiS_PALNPhase */
6985 if(newtvphase) PhaseIndex += 8; /* SiS_PALMPhase2 : SiS_PALNPhase2 */
6986 }
6987
6988 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6989 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6990 PhaseIndex = 0x05; /* SiS_SpecialPhaseM */
6991 } else if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
6992 PhaseIndex = 0x11; /* SiS_SpecialPhaseJ */
6993 } else {
6994 PhaseIndex = 0x10; /* SiS_SpecialPhase */
6995 }
6996 }
6997
6998 for(i = 0x31, j = 0; i <= 0x34; i++, j++) {
6999 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[(PhaseIndex * 4) + j]);
7000 }
7001
7002 for(i = 0x01, j = 0; i <= 0x2D; i++, j++) {
7003 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
7004 }
7005 for(i = 0x39; i <= 0x45; i++, j++) {
7006 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
7007 }
7008
7009 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7010 if(SiS_Pr->SiS_ModeType != ModeText) {
7011 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
7012 }
7013 }
7014
7015 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x0A,SiS_Pr->SiS_NewFlickerMode);
7016
7017 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x35,SiS_Pr->SiS_RY1COE);
7018 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x36,SiS_Pr->SiS_RY2COE);
7019 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x37,SiS_Pr->SiS_RY3COE);
7020 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x38,SiS_Pr->SiS_RY4COE);
7021
7022 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempax = 950;
7023 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempax = 680;
7024 else if(SiS_Pr->SiS_TVMode & TVSetPAL) tempax = 520;
7025 else tempax = 440; /* NTSC, YPbPr 525 */
7026
7027 if( ((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) && (SiS_Pr->SiS_VDE <= tempax)) ||
7028 ( (SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) &&
7029 ((SiS_Pr->SiS_VGAHDE == 1024) || (SiS_Pr->SiS_VDE <= tempax)) ) ) {
7030
7031 tempax -= SiS_Pr->SiS_VDE;
7032 tempax >>= 1;
7033 if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) {
7034 tempax >>= 1;
7035 }
7036 tempax &= 0x00ff;
7037
7038 temp = tempax + (unsigned short)TimingPoint[0];
7039 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
7040
7041 temp = tempax + (unsigned short)TimingPoint[1];
7042 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
7043
7044 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) && (SiS_Pr->SiS_VGAHDE >= 1024)) {
7045 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7046 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b);
7047 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54);
7048 } else {
7049 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x17);
7050 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1d);
7051 }
7052 }
7053
7054 }
7055
7056 tempcx = SiS_Pr->SiS_HT;
7057 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
7058 tempcx--;
7059 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) tempcx--;
7060 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1B,tempcx);
7061 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0xF0,((tempcx >> 8) & 0x0f));
7062
7063 tempcx = SiS_Pr->SiS_HT >> 1;
7064 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
7065 tempcx += 7;
7066 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
7067 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,((tempcx << 4) & 0xf0));
7068
7069 tempbx = TimingPoint[j] | (TimingPoint[j+1] << 8);
7070 tempbx += tempcx;
7071 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x24,tempbx);
7072 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0F,((tempbx >> 4) & 0xf0));
7073
7074 tempbx += 8;
7075 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7076 tempbx -= 4;
7077 tempcx = tempbx;
7078 }
7079 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x29,0x0F,((tempbx << 4) & 0xf0));
7080
7081 j += 2;
7082 tempcx += (TimingPoint[j] | (TimingPoint[j+1] << 8));
7083 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x27,tempcx);
7084 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x28,0x0F,((tempcx >> 4) & 0xf0));
7085
7086 tempcx += 8;
7087 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
7088 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2A,0x0F,((tempcx << 4) & 0xf0));
7089
7090 tempcx = SiS_Pr->SiS_HT >> 1;
7091 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
7092 j += 2;
7093 tempcx -= (TimingPoint[j] | ((TimingPoint[j+1]) << 8));
7094 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2D,0x0F,((tempcx << 4) & 0xf0));
7095
7096 tempcx -= 11;
7097 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
7098 tempcx = SiS_GetVGAHT2(SiS_Pr) - 1;
7099 }
7100 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2E,tempcx);
7101
7102 tempbx = SiS_Pr->SiS_VDE;
7103 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7104 if(SiS_Pr->SiS_VGAVDE == 360) tempbx = 746;
7105 if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 746;
7106 if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 853;
7107 } else if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
7108 (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p))) ) {
7109 tempbx >>= 1;
7110 if(SiS_Pr->ChipType >= SIS_315H) {
7111 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
7112 if((ModeNo <= 0x13) && (crt2crtc == 1)) tempbx++;
7113 } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7114 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
7115 if(crt2crtc == 4) tempbx++;
7116 }
7117 }
7118 }
7119 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7120 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7121 if((ModeNo == 0x2f) || (ModeNo == 0x5d) || (ModeNo == 0x5e)) tempbx++;
7122 }
7123 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
7124 if(ModeNo == 0x03) tempbx++; /* From 1.10.7w - doesn't make sense */
7125 }
7126 }
7127 }
7128 tempbx -= 2;
7129 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2F,tempbx);
7130
7131 temp = (tempcx >> 8) & 0x0F;
7132 temp |= ((tempbx >> 2) & 0xC0);
7133 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
7134 temp |= 0x10;
7135 if(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO) temp |= 0x20;
7136 }
7137 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,temp);
7138
7139 if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {
7140 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xdf,((tempbx & 0x0400) >> 5));
7141 }
7142
7143 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7144 tempbx = SiS_Pr->SiS_VDE;
7145 if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
7146 (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) ) {
7147 tempbx >>= 1;
7148 }
7149 tempbx -= 3;
7150 temp = ((tempbx >> 3) & 0x60) | 0x18;
7151 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x46,temp);
7152 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x47,tempbx);
7153
7154 if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {
7155 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xbf,((tempbx & 0x0400) >> 4));
7156 }
7157 }
7158
7159 tempbx = 0;
7160 if(!(modeflag & HalfDCLK)) {
7161 if(SiS_Pr->SiS_VGAHDE >= SiS_Pr->SiS_HDE) {
7162 tempax = 0;
7163 tempbx |= 0x20;
7164 }
7165 }
7166
7167 tempch = tempcl = 0x01;
7168 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7169 if(SiS_Pr->SiS_VGAHDE >= 960) {
7170 if((!(modeflag & HalfDCLK)) || (SiS_Pr->ChipType < SIS_315H)) {
7171 tempcl = 0x20;
7172 if(SiS_Pr->SiS_VGAHDE >= 1280) {
7173 tempch = 20;
7174 tempbx &= ~0x20;
7175 } else {
7176 tempch = 25; /* OK */
7177 }
7178 }
7179 }
7180 }
7181
7182 if(!(tempbx & 0x20)) {
7183 if(modeflag & HalfDCLK) tempcl <<= 1;
7184 longtemp = ((SiS_Pr->SiS_VGAHDE * tempch) / tempcl) << 13;
7185 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) longtemp <<= 3;
7186 tempax = longtemp / SiS_Pr->SiS_HDE;
7187 if(longtemp % SiS_Pr->SiS_HDE) tempax++;
7188 tempbx |= ((tempax >> 8) & 0x1F);
7189 tempcx = tempax >> 13;
7190 }
7191
7192 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,tempax);
7193 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,tempbx);
7194
7195 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7196
7197 tempcx &= 0x07;
7198 if(tempbx & 0x20) tempcx = 0;
7199 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xF8,tempcx);
7200
7201 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7202 tempbx = 0x0382;
7203 tempcx = 0x007e;
7204 } else {
7205 tempbx = 0x0369;
7206 tempcx = 0x0061;
7207 }
7208 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4B,tempbx);
7209 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4C,tempcx);
7210 temp = (tempcx & 0x0300) >> 6;
7211 temp |= ((tempbx >> 8) & 0x03);
7212 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7213 temp |= 0x10;
7214 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp |= 0x20;
7215 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp |= 0x40;
7216 }
7217 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4D,temp);
7218
7219 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7220 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,(temp - 3));
7221
7222 SiS_SetTVSpecial(SiS_Pr, ModeNo);
7223
7224 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
7225 temp = 0;
7226 if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
7227 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xf7,temp);
7228 }
7229
7230 }
7231
7232 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7233 if(!(SiS_Pr->SiS_TVMode & TVSetNTSC1024)) {
7234 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
7235 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,(temp - 1));
7236 }
7237 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF);
7238 }
7239
7240 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7241 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
7242 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,0x00);
7243 }
7244 }
7245
7246 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) return;
7247
7248 /* From here: Part2 LCD setup */
7249
7250 tempbx = SiS_Pr->SiS_HDE;
7251 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7252 tempbx--; /* RHACTE = HDE - 1 */
7253 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2C,tempbx);
7254 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,((tempbx >> 4) & 0xf0));
7255
7256 temp = 0x01;
7257 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7258 if(SiS_Pr->SiS_ModeType == ModeEGA) {
7259 if(SiS_Pr->SiS_VGAHDE >= 1024) {
7260 temp = 0x02;
7261 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7262 temp = 0x01;
7263 }
7264 }
7265 }
7266 }
7267 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,temp);
7268
7269 tempbx = SiS_Pr->SiS_VDE - 1;
7270 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x03,tempbx);
7271 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0C,0xF8,((tempbx >> 8) & 0x07));
7272
7273 tempcx = SiS_Pr->SiS_VT - 1;
7274 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x19,tempcx);
7275 temp = (tempcx >> 3) & 0xE0;
7276 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
7277 /* Enable dithering; only do this for 32bpp mode */
7278 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
7279 temp |= 0x10;
7280 }
7281 }
7282 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1A,0x0f,temp);
7283
7284 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x09,0xF0);
7285 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x0A,0xF0);
7286
7287 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB);
7288 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF);
7289
7290#ifdef CONFIG_FB_SIS_315
7291 if(SiS_GetCRT2Part2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7292 CRT2Index: &CRT2Index, ResIndex: &resindex)) {
7293 switch(CRT2Index) {
7294 case 206: CRT2Part2Ptr = SiS310_CRT2Part2_Asus1024x768_3; break;
7295 default:
7296 case 200: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1; break;
7297 }
7298
7299 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
7300 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
7301 for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
7302 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7303 }
7304 for(j = 0x1c; j <= 0x1d; i++, j++ ) {
7305 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7306 }
7307 for(j = 0x1f; j <= 0x21; i++, j++ ) {
7308 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7309 }
7310 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
7311 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
7312
7313 SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7314
7315 } else {
7316#endif
7317
7318 /* Checked for 1024x768, 1280x1024, 1400x1050, 1600x1200 */
7319 /* Clevo dual-link 1024x768 */
7320 /* Compaq 1280x1024 has HT 1696 sometimes (calculation OK, if given HT is correct) */
7321 /* Acer: OK, but uses different setting for VESA timing at 640/800/1024 and 640x400 */
7322
7323 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7324 if((SiS_Pr->SiS_LCDInfo & LCDPass11) || (SiS_Pr->PanelYRes == SiS_Pr->SiS_VDE)) {
7325 tempbx = SiS_Pr->SiS_VDE - 1;
7326 tempcx = SiS_Pr->SiS_VT - 1;
7327 } else {
7328 tempbx = SiS_Pr->SiS_VDE + ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7329 tempcx = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7330 }
7331 } else {
7332 tempbx = SiS_Pr->PanelYRes;
7333 tempcx = SiS_Pr->SiS_VT;
7334 tempax = 1;
7335 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7336 tempax = SiS_Pr->PanelYRes;
7337 /* if(SiS_Pr->SiS_VGAVDE == 525) tempax += 0x3c; */ /* 651+301C */
7338 if(SiS_Pr->PanelYRes < SiS_Pr->SiS_VDE) {
7339 tempax = tempcx = 0;
7340 } else {
7341 tempax -= SiS_Pr->SiS_VDE;
7342 }
7343 tempax >>= 1;
7344 }
7345 tempcx -= tempax; /* lcdvdes */
7346 tempbx -= tempax; /* lcdvdee */
7347 }
7348
7349 /* Non-expanding: lcdvdes = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */
7350
7351 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,tempcx); /* lcdvdes */
7352 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,tempbx); /* lcdvdee */
7353
7354 temp = (tempbx >> 5) & 0x38;
7355 temp |= ((tempcx >> 8) & 0x07);
7356 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
7357
7358 tempax = SiS_Pr->SiS_VDE;
7359 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7360 tempax = SiS_Pr->PanelYRes;
7361 }
7362 tempcx = (SiS_Pr->SiS_VT - tempax) >> 4;
7363 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7364 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7365 tempcx = (SiS_Pr->SiS_VT - tempax) / 10;
7366 }
7367 }
7368
7369 tempbx = ((SiS_Pr->SiS_VT + SiS_Pr->SiS_VDE) >> 1) - 1;
7370 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7371 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7372 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { /* ? */
7373 tempax = SiS_Pr->SiS_VT - SiS_Pr->PanelYRes;
7374 if(tempax % 4) { tempax >>= 2; tempax++; }
7375 else { tempax >>= 2; }
7376 tempbx -= (tempax - 1);
7377 } else {
7378 tempbx -= 10;
7379 if(tempbx <= SiS_Pr->SiS_VDE) tempbx = SiS_Pr->SiS_VDE + 1;
7380 }
7381 }
7382 }
7383 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
7384 tempbx++;
7385 if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (crt2crtc == 6)) {
7386 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7387 tempbx = 770;
7388 tempcx = 3;
7389 }
7390 }
7391 }
7392
7393 /* non-expanding: lcdvrs = ((VT + VDE) / 2) - 10 */
7394
7395 if(SiS_Pr->UseCustomMode) {
7396 tempbx = SiS_Pr->CVSyncStart;
7397 }
7398
7399 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,tempbx); /* lcdvrs */
7400
7401 temp = (tempbx >> 4) & 0xF0;
7402 tempbx += (tempcx + 1);
7403 temp |= (tempbx & 0x0F);
7404
7405 if(SiS_Pr->UseCustomMode) {
7406 temp &= 0xf0;
7407 temp |= (SiS_Pr->CVSyncEnd & 0x0f);
7408 }
7409
7410 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
7411
7412#ifdef CONFIG_FB_SIS_300
7413 SiS_Group2LCDSpecial(SiS_Pr, ModeNo, crt2crtc);
7414#endif
7415
7416 bridgeoffset = 7;
7417 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) bridgeoffset += 2;
7418 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) bridgeoffset += 2; /* OK for Averatec 1280x800 (301C) */
7419 if(SiS_IsDualLink(SiS_Pr)) bridgeoffset++;
7420 else if(SiS_Pr->SiS_VBType & VB_SIS302LV) bridgeoffset++; /* OK for Asus A4L 1280x800 */
7421 /* Higher bridgeoffset shifts to the LEFT */
7422
7423 temp = 0;
7424 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7425 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7426 temp = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7427 if(SiS_IsDualLink(SiS_Pr)) temp >>= 1;
7428 }
7429 }
7430 temp += bridgeoffset;
7431 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1F,temp); /* lcdhdes */
7432 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0F,((temp >> 4) & 0xf0));
7433
7434 tempcx = SiS_Pr->SiS_HT;
7435 tempax = tempbx = SiS_Pr->SiS_HDE;
7436 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7437 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7438 tempax = SiS_Pr->PanelXRes;
7439 tempbx = SiS_Pr->PanelXRes - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7440 }
7441 }
7442 if(SiS_IsDualLink(SiS_Pr)) {
7443 tempcx >>= 1;
7444 tempbx >>= 1;
7445 tempax >>= 1;
7446 }
7447
7448 tempbx += bridgeoffset;
7449
7450 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,tempbx); /* lcdhdee */
7451 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0xF0,((tempbx >> 8) & 0x0f));
7452
7453 tempcx = (tempcx - tempax) >> 2;
7454
7455 tempbx += tempcx;
7456 push2 = tempbx;
7457
7458 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7459 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7460 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
7461 if(SiS_Pr->SiS_HDE == 1280) tempbx = (tempbx & 0xff00) | 0x47;
7462 }
7463 }
7464 }
7465
7466 if(SiS_Pr->UseCustomMode) {
7467 tempbx = SiS_Pr->CHSyncStart;
7468 if(modeflag & HalfDCLK) tempbx <<= 1;
7469 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7470 tempbx += bridgeoffset;
7471 }
7472
7473 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1C,tempbx); /* lcdhrs */
7474 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,((tempbx >> 4) & 0xf0));
7475
7476 tempbx = push2;
7477
7478 tempcx <<= 1;
7479 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7480 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) tempcx >>= 2;
7481 }
7482 tempbx += tempcx;
7483
7484 if(SiS_Pr->UseCustomMode) {
7485 tempbx = SiS_Pr->CHSyncEnd;
7486 if(modeflag & HalfDCLK) tempbx <<= 1;
7487 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7488 tempbx += bridgeoffset;
7489 }
7490
7491 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,tempbx); /* lcdhre */
7492
7493 SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7494
7495#ifdef CONFIG_FB_SIS_300
7496 SiS_Set300Part2Regs(SiS_Pr, ModeIdIndex, RefreshRateTableIndex, ModeNo);
7497#endif
7498#ifdef CONFIG_FB_SIS_315
7499 } /* CRT2-LCD from table */
7500#endif
7501}
7502
7503/*********************************************/
7504/* SET PART 3 REGISTER GROUP */
7505/*********************************************/
7506
7507static void
7508SiS_SetGroup3(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7509{
7510 unsigned short i;
7511 const unsigned char *tempdi;
7512
7513 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
7514
7515#ifndef SIS_CP
7516 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x00,0x00);
7517#else
7518 SIS_CP_INIT301_CP
7519#endif
7520
7521 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7522 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7523 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7524 } else {
7525 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xF5);
7526 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xB7);
7527 }
7528
7529 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7530 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7531 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7532 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x3D,0xA8);
7533 }
7534
7535 tempdi = NULL;
7536 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7537 tempdi = SiS_Pr->SiS_HiTVGroup3Data;
7538 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
7539 tempdi = SiS_Pr->SiS_HiTVGroup3Simu;
7540 }
7541 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7542 if(!(SiS_Pr->SiS_TVMode & TVSetYPbPr525i)) {
7543 tempdi = SiS_HiTVGroup3_1;
7544 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempdi = SiS_HiTVGroup3_2;
7545 }
7546 }
7547 if(tempdi) {
7548 for(i=0; i<=0x3E; i++) {
7549 SiS_SetReg(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
7550 }
7551 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
7552 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
7553 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x28,0x3f);
7554 }
7555 }
7556 }
7557
7558#ifdef SIS_CP
7559 SIS_CP_INIT301_CP2
7560#endif
7561}
7562
7563/*********************************************/
7564/* SET PART 4 REGISTER GROUP */
7565/*********************************************/
7566
7567#ifdef CONFIG_FB_SIS_315
7568#if 0
7569static void
7570SiS_ShiftXPos(struct SiS_Private *SiS_Pr, int shift)
7571{
7572 unsigned short temp, temp1, temp2;
7573
7574 temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x1f);
7575 temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x20);
7576 temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7577 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,temp);
7578 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0f,((temp >> 4) & 0xf0));
7579 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x2b) & 0x0f;
7580 temp = (unsigned short)((int)(temp) + shift);
7581 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2b,0xf0,(temp & 0x0f));
7582 temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7583 temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x42);
7584 temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7585 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,temp);
7586 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x42,0x0f,((temp >> 4) & 0xf0));
7587}
7588#endif
7589
7590static void
7591SiS_SetGroup4_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7592{
7593 unsigned short temp, temp1;
7594 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
7595
7596 if(!(SiS_Pr->SiS_VBType & VB_SIS30xCLV)) return;
7597 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToHiVision | SetCRT2ToYPbPr525750))) return;
7598
7599 if(SiS_Pr->ChipType >= XGI_20) return;
7600
7601 if((SiS_Pr->ChipType >= SIS_661) && (SiS_Pr->SiS_ROMNew)) {
7602 if(!(ROMAddr[0x61] & 0x04)) return;
7603 }
7604
7605 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3a,0x08);
7606 temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x3a);
7607 if(!(temp & 0x01)) {
7608 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3a,0xdf);
7609 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xfc);
7610 if((SiS_Pr->ChipType < SIS_661) && (!(SiS_Pr->SiS_ROMNew))) {
7611 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xf8);
7612 }
7613 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0xfb);
7614 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp = 0x0000;
7615 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp = 0x0002;
7616 else if(SiS_Pr->SiS_TVMode & TVSetHiVision) temp = 0x0400;
7617 else temp = 0x0402;
7618 if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
7619 temp1 = 0;
7620 if(SiS_Pr->SiS_TVMode & TVAspect43) temp1 = 4;
7621 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0f,0xfb,temp1);
7622 if(SiS_Pr->SiS_TVMode & TVAspect43LB) temp |= 0x01;
7623 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0x7c,(temp & 0xff));
7624 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7625 if(ModeNo > 0x13) {
7626 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x39,0xfd);
7627 }
7628 } else {
7629 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x3b) & 0x03;
7630 if(temp1 == 0x01) temp |= 0x01;
7631 if(temp1 == 0x03) temp |= 0x04; /* ? why not 0x10? */
7632 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xf8,(temp & 0xff));
7633 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7634 if(ModeNo > 0x13) {
7635 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3b,0xfd);
7636 }
7637 }
7638
7639#if 0
7640 if(SiS_Pr->ChipType >= SIS_661) { /* ? */
7641 if(SiS_Pr->SiS_TVMode & TVAspect43) {
7642 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
7643 if(resinfo == SIS_RI_1024x768) {
7644 SiS_ShiftXPos(SiS_Pr, 97);
7645 } else {
7646 SiS_ShiftXPos(SiS_Pr, 111);
7647 }
7648 } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
7649 SiS_ShiftXPos(SiS_Pr, 136);
7650 }
7651 }
7652 }
7653#endif
7654
7655 }
7656
7657}
7658#endif
7659
7660static void
7661SiS_SetCRT2VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7662 unsigned short RefreshRateTableIndex)
7663{
7664 unsigned short vclkindex, temp, reg1, reg2;
7665
7666 if(SiS_Pr->UseCustomMode) {
7667 reg1 = SiS_Pr->CSR2B;
7668 reg2 = SiS_Pr->CSR2C;
7669 } else {
7670 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
7671 reg1 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
7672 reg2 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
7673 }
7674
7675 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7676 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {
7677 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x57);
7678 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,0x46);
7679 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1f,0xf6);
7680 } else {
7681 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7682 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7683 }
7684 } else {
7685 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x01);
7686 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7687 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7688 }
7689 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x12,0x00);
7690 temp = 0x08;
7691 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) temp |= 0x20;
7692 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,temp);
7693}
7694
7695static void
7696SiS_SetDualLinkEtc(struct SiS_Private *SiS_Pr)
7697{
7698 if(SiS_Pr->ChipType >= SIS_315H) {
7699 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
7700 if((SiS_CRT2IsLCD(SiS_Pr)) ||
7701 (SiS_IsVAMode(SiS_Pr))) {
7702 if(SiS_Pr->SiS_LCDInfo & LCDDualLink) {
7703 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
7704 } else {
7705 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,~0x20);
7706 }
7707 }
7708 }
7709 }
7710 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
7711 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
7712#ifdef SET_EMI
7713 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
7714#endif
7715 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
7716 }
7717}
7718
7719static void
7720SiS_SetGroup4(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7721 unsigned short RefreshRateTableIndex)
7722{
7723 unsigned short tempax, tempcx, tempbx, modeflag, temp, resinfo;
7724 unsigned int tempebx, tempeax, templong;
7725
7726 if(ModeNo <= 0x13) {
7727 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7728 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
7729 } else if(SiS_Pr->UseCustomMode) {
7730 modeflag = SiS_Pr->CModeFlag;
7731 resinfo = 0;
7732 } else {
7733 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7734 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
7735 }
7736
7737 if(SiS_Pr->ChipType >= SIS_315H) {
7738 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
7739 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7740 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7741 }
7742 }
7743 }
7744
7745 if(SiS_Pr->SiS_VBType & (VB_SIS30xCLV | VB_SIS302LV)) {
7746 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7747 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x10,0x9f);
7748 }
7749 }
7750
7751 if(SiS_Pr->ChipType >= SIS_315H) {
7752 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7753 SiS_SetDualLinkEtc(SiS_Pr);
7754 return;
7755 }
7756 }
7757
7758 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x13,SiS_Pr->SiS_RVBHCFACT);
7759
7760 tempbx = SiS_Pr->SiS_RVBHCMAX;
7761 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x14,tempbx);
7762
7763 temp = (tempbx >> 1) & 0x80;
7764
7765 tempcx = SiS_Pr->SiS_VGAHT - 1;
7766 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x16,tempcx);
7767
7768 temp |= ((tempcx >> 5) & 0x78);
7769
7770 tempcx = SiS_Pr->SiS_VGAVT - 1;
7771 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempcx -= 5;
7772 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x17,tempcx);
7773
7774 temp |= ((tempcx >> 8) & 0x07);
7775 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x15,temp);
7776
7777 tempbx = SiS_Pr->SiS_VGAHDE;
7778 if(modeflag & HalfDCLK) tempbx >>= 1;
7779 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7780
7781 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7782 temp = 0;
7783 if(tempbx > 800) temp = 0x60;
7784 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7785 temp = 0;
7786 if(tempbx > 1024) temp = 0xC0;
7787 else if(tempbx >= 960) temp = 0xA0;
7788 } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
7789 temp = 0;
7790 if(tempbx >= 1280) temp = 0x40;
7791 else if(tempbx >= 1024) temp = 0x20;
7792 } else {
7793 temp = 0x80;
7794 if(tempbx >= 1024) temp = 0xA0;
7795 }
7796
7797 temp |= SiS_Pr->Init_P4_0E;
7798
7799 if(SiS_Pr->SiS_VBType & VB_SIS301) {
7800 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
7801 temp &= 0xf0;
7802 temp |= 0x0A;
7803 }
7804 }
7805
7806 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0E,0x10,temp);
7807
7808 tempeax = SiS_Pr->SiS_VGAVDE;
7809 tempebx = SiS_Pr->SiS_VDE;
7810 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7811 if(!(temp & 0xE0)) tempebx >>=1;
7812 }
7813
7814 tempcx = SiS_Pr->SiS_RVBHRS;
7815 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x18,tempcx);
7816 tempcx >>= 8;
7817 tempcx |= 0x40;
7818
7819 if(tempeax <= tempebx) {
7820 tempcx ^= 0x40;
7821 } else {
7822 tempeax -= tempebx;
7823 }
7824
7825 tempeax *= (256 * 1024);
7826 templong = tempeax % tempebx;
7827 tempeax /= tempebx;
7828 if(templong) tempeax++;
7829
7830 temp = (unsigned short)(tempeax & 0x000000FF);
7831 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1B,temp);
7832 temp = (unsigned short)((tempeax & 0x0000FF00) >> 8);
7833 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1A,temp);
7834 temp = (unsigned short)((tempeax >> 12) & 0x70); /* sic! */
7835 temp |= (tempcx & 0x4F);
7836 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x19,temp);
7837
7838 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7839
7840 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1C,0x28);
7841
7842 /* Calc Linebuffer max address and set/clear decimode */
7843 tempbx = 0;
7844 if(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p)) tempbx = 0x08;
7845 tempax = SiS_Pr->SiS_VGAHDE;
7846 if(modeflag & HalfDCLK) tempax >>= 1;
7847 if(SiS_IsDualLink(SiS_Pr)) tempax >>= 1;
7848 if(tempax > 800) {
7849 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7850 tempax -= 800;
7851 } else {
7852 tempbx = 0x08;
7853 if(tempax == 960) tempax *= 25; /* Correct */
7854 else if(tempax == 1024) tempax *= 25;
7855 else tempax *= 20;
7856 temp = tempax % 32;
7857 tempax /= 32;
7858 if(temp) tempax++;
7859 tempax++;
7860 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7861 if(resinfo == SIS_RI_1024x768 ||
7862 resinfo == SIS_RI_1024x576 ||
7863 resinfo == SIS_RI_1280x1024 ||
7864 resinfo == SIS_RI_1280x720) {
7865 /* Otherwise white line or garbage at right edge */
7866 tempax = (tempax & 0xff00) | 0x20;
7867 }
7868 }
7869 }
7870 }
7871 tempax--;
7872 temp = ((tempax >> 4) & 0x30) | tempbx;
7873 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1D,tempax);
7874 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1E,temp);
7875
7876 temp = 0x0036; tempbx = 0xD0;
7877 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
7878 temp = 0x0026; tempbx = 0xC0; /* See En/DisableBridge() */
7879 }
7880 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7881 if(!(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetHiVision | TVSetYPbPr750p | TVSetYPbPr525p))) {
7882 temp |= 0x01;
7883 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7884 if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
7885 temp &= ~0x01;
7886 }
7887 }
7888 }
7889 }
7890 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,tempbx,temp);
7891
7892 tempbx = SiS_Pr->SiS_HT >> 1;
7893 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7894 tempbx -= 2;
7895 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x22,tempbx);
7896 temp = (tempbx >> 5) & 0x38;
7897 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp);
7898
7899 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
7900 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7901 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7902 /* LCD-too-dark-error-source, see FinalizeLCD() */
7903 }
7904 }
7905
7906 SiS_SetDualLinkEtc(SiS_Pr);
7907
7908 } /* 301B */
7909
7910 SiS_SetCRT2VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
7911}
7912
7913/*********************************************/
7914/* SET PART 5 REGISTER GROUP */
7915/*********************************************/
7916
7917static void
7918SiS_SetGroup5(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7919{
7920
7921 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
7922
7923 if(SiS_Pr->SiS_ModeType == ModeVGA) {
7924 if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))) {
7925 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
7926 SiS_LoadDAC(SiS_Pr, ModeNo, ModeIdIndex);
7927 }
7928 }
7929}
7930
7931/*********************************************/
7932/* MODIFY CRT1 GROUP FOR SLAVE MODE */
7933/*********************************************/
7934
7935static bool
7936SiS_GetLVDSCRT1Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7937 unsigned short RefreshRateTableIndex, unsigned short *ResIndex,
7938 unsigned short *DisplayType)
7939 {
7940 unsigned short modeflag = 0;
7941 bool checkhd = true;
7942
7943 /* Pass 1:1 not supported here */
7944
7945 if(ModeNo <= 0x13) {
7946 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7947 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
7948 } else {
7949 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7950 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
7951 }
7952
7953 (*ResIndex) &= 0x3F;
7954
7955 if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
7956
7957 (*DisplayType) = 80;
7958 if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
7959 (*DisplayType) = 82;
7960 if(SiS_Pr->SiS_ModeType > ModeVGA) {
7961 if(SiS_Pr->SiS_CHSOverScan) (*DisplayType) = 84;
7962 }
7963 }
7964 if((*DisplayType) != 84) {
7965 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
7966 }
7967
7968 } else {
7969
7970 (*DisplayType = 0);
7971 switch(SiS_Pr->SiS_LCDResInfo) {
7972 case Panel_320x240_1: (*DisplayType) = 50;
7973 checkhd = false;
7974 break;
7975 case Panel_320x240_2: (*DisplayType) = 14;
7976 break;
7977 case Panel_320x240_3: (*DisplayType) = 18;
7978 break;
7979 case Panel_640x480: (*DisplayType) = 10;
7980 break;
7981 case Panel_1024x600: (*DisplayType) = 26;
7982 break;
7983 default: return true;
7984 }
7985
7986 if(checkhd) {
7987 if(modeflag & HalfDCLK) (*DisplayType)++;
7988 }
7989
7990 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
7991 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) (*DisplayType) += 2;
7992 }
7993
7994 }
7995
7996 return true;
7997}
7998
7999static void
8000SiS_ModCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
8001 unsigned short RefreshRateTableIndex)
8002{
8003 unsigned short tempah, i, modeflag, j, ResIndex, DisplayType;
8004 const struct SiS_LVDSCRT1Data *LVDSCRT1Ptr=NULL;
8005 static const unsigned short CRIdx[] = {
8006 0x00, 0x02, 0x03, 0x04, 0x05, 0x06,
8007 0x07, 0x10, 0x11, 0x15, 0x16
8008 };
8009
8010 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
8011 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
8012 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
8013 (SiS_Pr->SiS_CustomT == CUT_PANEL856) )
8014 return;
8015
8016 if(SiS_Pr->SiS_IF_DEF_LVDS) {
8017 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
8018 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;
8019 }
8020 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
8021 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;
8022 } else return;
8023
8024 if(SiS_Pr->SiS_LCDInfo & LCDPass11) return;
8025
8026 if(SiS_Pr->ChipType < SIS_315H) {
8027 if(SiS_Pr->SiS_SetFlag & SetDOSMode) return;
8028 }
8029
8030 if(!(SiS_GetLVDSCRT1Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
8031 ResIndex: &ResIndex, DisplayType: &DisplayType))) {
8032 return;
8033 }
8034
8035 switch(DisplayType) {
8036 case 50: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_1; break; /* xSTN */
8037 case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2; break; /* xSTN */
8038 case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2_H; break; /* xSTN */
8039 case 18: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3; break; /* xSTN */
8040 case 19: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3_H; break; /* xSTN */
8041 case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1; break;
8042 case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1_H; break;
8043#if 0 /* Works better with calculated numbers */
8044 case 26: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1; break;
8045 case 27: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1_H; break;
8046 case 28: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2; break;
8047 case 29: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2_H; break;
8048#endif
8049 case 80: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC; break;
8050 case 81: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC; break;
8051 case 82: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL; break;
8052 case 83: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL; break;
8053 case 84: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1SOPAL; break;
8054 }
8055
8056 if(LVDSCRT1Ptr) {
8057
8058 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
8059
8060 for(i = 0; i <= 10; i++) {
8061 tempah = (LVDSCRT1Ptr + ResIndex)->CR[i];
8062 SiS_SetReg(SiS_Pr->SiS_P3d4,CRIdx[i],tempah);
8063 }
8064
8065 for(i = 0x0A, j = 11; i <= 0x0C; i++, j++) {
8066 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
8067 SiS_SetReg(SiS_Pr->SiS_P3c4,i,tempah);
8068 }
8069
8070 tempah = (LVDSCRT1Ptr + ResIndex)->CR[14] & 0xE0;
8071 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);
8072
8073 if(ModeNo <= 0x13) modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
8074 else modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
8075
8076 tempah = ((LVDSCRT1Ptr + ResIndex)->CR[14] & 0x01) << 5;
8077 if(modeflag & DoubleScanMode) tempah |= 0x80;
8078 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
8079
8080 } else {
8081
8082 SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
8083
8084 }
8085}
8086
8087/*********************************************/
8088/* SET CRT2 ECLK */
8089/*********************************************/
8090
8091static void
8092SiS_SetCRT2ECLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
8093 unsigned short RefreshRateTableIndex)
8094{
8095 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
8096 unsigned short clkbase, vclkindex = 0;
8097 unsigned char sr2b, sr2c;
8098
8099 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
8100 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
8101 if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK == 2) {
8102 RefreshRateTableIndex--;
8103 }
8104 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
8105 RefreshRateTableIndex);
8106 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
8107 } else {
8108 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
8109 RefreshRateTableIndex);
8110 }
8111
8112 sr2b = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
8113 sr2c = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
8114
8115 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
8116 if(SiS_Pr->SiS_UseROM) {
8117 if(ROMAddr[0x220] & 0x01) {
8118 sr2b = ROMAddr[0x227];
8119 sr2c = ROMAddr[0x228];
8120 }
8121 }
8122 }
8123
8124 clkbase = 0x02B;
8125 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
8126 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
8127 clkbase += 3;
8128 }
8129 }
8130
8131 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x20);
8132 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
8133 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
8134 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x10);
8135 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
8136 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
8137 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x00);
8138 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
8139 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
8140}
8141
8142/*********************************************/
8143/* SET UP CHRONTEL CHIPS */
8144/*********************************************/
8145
8146static void
8147SiS_SetCHTVReg(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
8148 unsigned short RefreshRateTableIndex)
8149{
8150 unsigned short TVType, resindex;
8151 const struct SiS_CHTVRegData *CHTVRegData = NULL;
8152
8153 if(ModeNo <= 0x13)
8154 resindex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
8155 else
8156 resindex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
8157
8158 resindex &= 0x3F;
8159
8160 TVType = 0;
8161 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
8162 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
8163 TVType += 2;
8164 if(SiS_Pr->SiS_ModeType > ModeVGA) {
8165 if(SiS_Pr->SiS_CHSOverScan) TVType = 8;
8166 }
8167 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
8168 TVType = 4;
8169 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
8170 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
8171 TVType = 6;
8172 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
8173 }
8174 }
8175
8176 switch(TVType) {
8177 case 0: CHTVRegData = SiS_Pr->SiS_CHTVReg_UNTSC; break;
8178 case 1: CHTVRegData = SiS_Pr->SiS_CHTVReg_ONTSC; break;
8179 case 2: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPAL; break;
8180 case 3: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break;
8181 case 4: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALM; break;
8182 case 5: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALM; break;
8183 case 6: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALN; break;
8184 case 7: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALN; break;
8185 case 8: CHTVRegData = SiS_Pr->SiS_CHTVReg_SOPAL; break;
8186 default: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break;
8187 }
8188
8189
8190 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
8191
8192#ifdef CONFIG_FB_SIS_300
8193
8194 /* Chrontel 7005 - I assume that it does not come with a 315 series chip */
8195
8196 /* We don't support modes >800x600 */
8197 if (resindex > 5) return;
8198
8199 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
8200 SiS_SetCH700x(SiS_Pr,reg: 0x04,val: 0x43); /* 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
8201 SiS_SetCH700x(SiS_Pr,reg: 0x09,val: 0x69); /* Black level for PAL (105)*/
8202 } else {
8203 SiS_SetCH700x(SiS_Pr,reg: 0x04,val: 0x03); /* upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
8204 SiS_SetCH700x(SiS_Pr,reg: 0x09,val: 0x71); /* Black level for NTSC (113)*/
8205 }
8206
8207 SiS_SetCH700x(SiS_Pr,reg: 0x00,val: CHTVRegData[resindex].Reg[0]); /* Mode register */
8208 SiS_SetCH700x(SiS_Pr,reg: 0x07,val: CHTVRegData[resindex].Reg[1]); /* Start active video register */
8209 SiS_SetCH700x(SiS_Pr,reg: 0x08,val: CHTVRegData[resindex].Reg[2]); /* Position overflow register */
8210 SiS_SetCH700x(SiS_Pr,reg: 0x0a,val: CHTVRegData[resindex].Reg[3]); /* Horiz Position register */
8211 SiS_SetCH700x(SiS_Pr,reg: 0x0b,val: CHTVRegData[resindex].Reg[4]); /* Vertical Position register */
8212
8213 /* Set minimum flicker filter for Luma channel (SR1-0=00),
8214 minimum text enhancement (S3-2=10),
8215 maximum flicker filter for Chroma channel (S5-4=10)
8216 =00101000=0x28 (When reading, S1-0->S3-2, and S3-2->S1-0!)
8217 */
8218 SiS_SetCH700x(SiS_Pr,reg: 0x01,val: 0x28);
8219
8220 /* Set video bandwidth
8221 High bandwidth Luma composite video filter(S0=1)
8222 low bandwidth Luma S-video filter (S2-1=00)
8223 disable peak filter in S-video channel (S3=0)
8224 high bandwidth Chroma Filter (S5-4=11)
8225 =00110001=0x31
8226 */
8227 SiS_SetCH700x(SiS_Pr,reg: 0x03,val: 0xb1); /* old: 3103 */
8228
8229 /* Register 0x3D does not exist in non-macrovision register map
8230 (Maybe this is a macrovision register?)
8231 */
8232#ifndef SIS_CP
8233 SiS_SetCH70xx(SiS_Pr,reg: 0x3d,val: 0x00);
8234#endif
8235
8236 /* Register 0x10 only contains 1 writable bit (S0) for sensing,
8237 all other bits a read-only. Macrovision?
8238 */
8239 SiS_SetCH70xxANDOR(SiS_Pr,reg: 0x10,orval: 0x00,andval: 0x1F);
8240
8241 /* Register 0x11 only contains 3 writable bits (S0-S2) for
8242 contrast enhancement (set to 010 -> gain 1 Yout = 17/16*(Yin-30) )
8243 */
8244 SiS_SetCH70xxANDOR(SiS_Pr,reg: 0x11,orval: 0x02,andval: 0xF8);
8245
8246 /* Clear DSEN
8247 */
8248 SiS_SetCH70xxANDOR(SiS_Pr,reg: 0x1c,orval: 0x00,andval: 0xEF);
8249
8250 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) { /* ---- NTSC ---- */
8251 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) {
8252 if(resindex == 0x04) { /* 640x480 overscan: Mode 16 */
8253 SiS_SetCH70xxANDOR(SiS_Pr,reg: 0x20,orval: 0x00,andval: 0xEF); /* loop filter off */
8254 SiS_SetCH70xxANDOR(SiS_Pr,reg: 0x21,orval: 0x01,andval: 0xFE); /* ACIV on, no need to set FSCI */
8255 } else if(resindex == 0x05) { /* 800x600 overscan: Mode 23 */
8256 SiS_SetCH70xxANDOR(SiS_Pr,reg: 0x18,orval: 0x01,andval: 0xF0); /* 0x18-0x1f: FSCI 469,762,048 */
8257 SiS_SetCH70xxANDOR(SiS_Pr,reg: 0x19,orval: 0x0C,andval: 0xF0);
8258 SiS_SetCH70xxANDOR(SiS_Pr,reg: 0x1a,orval: 0x00,andval: 0xF0);
8259 SiS_SetCH70xxANDOR(SiS_Pr,reg: 0x1b,orval: 0x00,andval: 0xF0);
8260 SiS_SetCH70xxANDOR(SiS_Pr,reg: 0x1c,orval: 0x00,andval: 0xF0);
8261 SiS_SetCH70xxANDOR(SiS_Pr,reg: 0x1d,orval: 0x00,andval: 0xF0);
8262 SiS_SetCH70xxANDOR(SiS_Pr,reg: 0x1e,orval: 0x00,andval: 0xF0);
8263 SiS_SetCH70xxANDOR(SiS_Pr,reg: 0x1f,orval: 0x00,andval: 0xF0);
8264 SiS_SetCH70xxANDOR(SiS_Pr,reg: 0x20,orval: 0x01,andval: 0xEF); /* Loop filter on for mode 23 */
8265 SiS_SetCH70xxANDOR(SiS_Pr,reg: 0x21,orval: 0x00,andval: 0xFE); /* ACIV off, need to set FSCI */
8266 }
8267 } else {
8268 if(resindex == 0x04) { /* ----- 640x480 underscan; Mode 17 */
8269 SiS_SetCH70xxANDOR(SiS_Pr,reg: 0x20,orval: 0x00,andval: 0xEF); /* loop filter off */
8270 SiS_SetCH70xxANDOR(SiS_Pr,reg: 0x21,orval: 0x01,andval: 0xFE);
8271 } else if(resindex == 0x05) { /* ----- 800x600 underscan: Mode 24 */
8272#if 0
8273 SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0); /* (FSCI was 0x1f1c71c7 - this is for mode 22) */
8274 SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x09,0xF0); /* FSCI for mode 24 is 428,554,851 */
8275 SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x08,0xF0); /* 198b3a63 */
8276 SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x0b,0xF0);
8277 SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x04,0xF0);
8278 SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x01,0xF0);
8279 SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x06,0xF0);
8280 SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x05,0xF0);
8281 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off for mode 24 */
8282 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE); * ACIV off, need to set FSCI */
8283#endif /* All alternatives wrong (datasheet wrong?), don't use FSCI */
8284 SiS_SetCH70xxANDOR(SiS_Pr,reg: 0x20,orval: 0x00,andval: 0xEF); /* loop filter off */
8285 SiS_SetCH70xxANDOR(SiS_Pr,reg: 0x21,orval: 0x01,andval: 0xFE);
8286 }
8287 }
8288 } else { /* ---- PAL ---- */
8289 /* We don't play around with FSCI in PAL mode */
8290 SiS_SetCH70xxANDOR(SiS_Pr, reg: 0x20, orval: 0x00, andval: 0xEF); /* loop filter off */
8291 SiS_SetCH70xxANDOR(SiS_Pr, reg: 0x21, orval: 0x01, andval: 0xFE); /* ACIV on */
8292 }
8293
8294#endif /* 300 */
8295
8296 } else {
8297
8298 /* Chrontel 7019 - assumed that it does not come with a 300 series chip */
8299
8300#ifdef CONFIG_FB_SIS_315
8301
8302 unsigned short temp;
8303
8304 /* We don't support modes >1024x768 */
8305 if (resindex > 6) return;
8306
8307 temp = CHTVRegData[resindex].Reg[0];
8308 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp |= 0x10;
8309 SiS_SetCH701x(SiS_Pr,reg: 0x00,val: temp);
8310
8311 SiS_SetCH701x(SiS_Pr,reg: 0x01,val: CHTVRegData[resindex].Reg[1]);
8312 SiS_SetCH701x(SiS_Pr,reg: 0x02,val: CHTVRegData[resindex].Reg[2]);
8313 SiS_SetCH701x(SiS_Pr,reg: 0x04,val: CHTVRegData[resindex].Reg[3]);
8314 SiS_SetCH701x(SiS_Pr,reg: 0x03,val: CHTVRegData[resindex].Reg[4]);
8315 SiS_SetCH701x(SiS_Pr,reg: 0x05,val: CHTVRegData[resindex].Reg[5]);
8316 SiS_SetCH701x(SiS_Pr,reg: 0x06,val: CHTVRegData[resindex].Reg[6]);
8317
8318 temp = CHTVRegData[resindex].Reg[7];
8319 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp = 0x66;
8320 SiS_SetCH701x(SiS_Pr,reg: 0x07,val: temp);
8321
8322 SiS_SetCH701x(SiS_Pr,reg: 0x08,val: CHTVRegData[resindex].Reg[8]);
8323 SiS_SetCH701x(SiS_Pr,reg: 0x15,val: CHTVRegData[resindex].Reg[9]);
8324 SiS_SetCH701x(SiS_Pr,reg: 0x1f,val: CHTVRegData[resindex].Reg[10]);
8325 SiS_SetCH701x(SiS_Pr,reg: 0x0c,val: CHTVRegData[resindex].Reg[11]);
8326 SiS_SetCH701x(SiS_Pr,reg: 0x0d,val: CHTVRegData[resindex].Reg[12]);
8327 SiS_SetCH701x(SiS_Pr,reg: 0x0e,val: CHTVRegData[resindex].Reg[13]);
8328 SiS_SetCH701x(SiS_Pr,reg: 0x0f,val: CHTVRegData[resindex].Reg[14]);
8329 SiS_SetCH701x(SiS_Pr,reg: 0x10,val: CHTVRegData[resindex].Reg[15]);
8330
8331 temp = SiS_GetCH701x(SiS_Pr,tempax: 0x21) & ~0x02;
8332 /* D1 should be set for PAL, PAL-N and NTSC-J,
8333 but I won't do that for PAL unless somebody
8334 tells me to do so. Since the BIOS uses
8335 non-default CIV values and blacklevels,
8336 this might be compensated anyway.
8337 */
8338 if(SiS_Pr->SiS_TVMode & (TVSetPALN | TVSetNTSCJ)) temp |= 0x02;
8339 SiS_SetCH701x(SiS_Pr,reg: 0x21,val: temp);
8340
8341#endif /* 315 */
8342
8343 }
8344
8345#ifdef SIS_CP
8346 SIS_CP_INIT301_CP3
8347#endif
8348
8349}
8350
8351#ifdef CONFIG_FB_SIS_315 /* ----------- 315 series only ---------- */
8352
8353void
8354SiS_Chrontel701xBLOn(struct SiS_Private *SiS_Pr)
8355{
8356 unsigned short temp;
8357
8358 /* Enable Chrontel 7019 LCD panel backlight */
8359 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8360 if(SiS_Pr->ChipType == SIS_740) {
8361 SiS_SetCH701x(SiS_Pr,reg: 0x66,val: 0x65);
8362 } else {
8363 temp = SiS_GetCH701x(SiS_Pr,tempax: 0x66);
8364 temp |= 0x20;
8365 SiS_SetCH701x(SiS_Pr,reg: 0x66,val: temp);
8366 }
8367 }
8368}
8369
8370void
8371SiS_Chrontel701xBLOff(struct SiS_Private *SiS_Pr)
8372{
8373 unsigned short temp;
8374
8375 /* Disable Chrontel 7019 LCD panel backlight */
8376 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8377 temp = SiS_GetCH701x(SiS_Pr,tempax: 0x66);
8378 temp &= 0xDF;
8379 SiS_SetCH701x(SiS_Pr,reg: 0x66,val: temp);
8380 }
8381}
8382
8383static void
8384SiS_ChrontelPowerSequencing(struct SiS_Private *SiS_Pr)
8385{
8386 static const unsigned char regtable[] = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
8387 static const unsigned char table1024_740[] = { 0x01, 0x02, 0x01, 0x01, 0x01 };
8388 static const unsigned char table1400_740[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 };
8389 static const unsigned char asus1024_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8390 static const unsigned char asus1400_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8391 static const unsigned char table1024_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8392 static const unsigned char table1400_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8393 const unsigned char *tableptr = NULL;
8394 int i;
8395
8396 /* Set up Power up/down timing */
8397
8398 if(SiS_Pr->ChipType == SIS_740) {
8399 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8400 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1024_740;
8401 else tableptr = table1024_740;
8402 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8403 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8404 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8405 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1400_740;
8406 else tableptr = table1400_740;
8407 } else return;
8408 } else {
8409 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8410 tableptr = table1024_650;
8411 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8412 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8413 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8414 tableptr = table1400_650;
8415 } else return;
8416 }
8417
8418 for(i=0; i<5; i++) {
8419 SiS_SetCH701x(SiS_Pr, reg: regtable[i], val: tableptr[i]);
8420 }
8421}
8422
8423static void
8424SiS_SetCH701xForLCD(struct SiS_Private *SiS_Pr)
8425{
8426 const unsigned char *tableptr = NULL;
8427 unsigned short tempbh;
8428 int i;
8429 static const unsigned char regtable[] = {
8430 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
8431 0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66
8432 };
8433 static const unsigned char table1024_740[] = {
8434 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8435 0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44
8436 };
8437 static const unsigned char table1280_740[] = {
8438 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8439 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44
8440 };
8441 static const unsigned char table1400_740[] = {
8442 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8443 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44
8444 };
8445 static const unsigned char table1600_740[] = {
8446 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8447 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44
8448 };
8449 static const unsigned char table1024_650[] = {
8450 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8451 0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02
8452 };
8453 static const unsigned char table1280_650[] = {
8454 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8455 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02
8456 };
8457 static const unsigned char table1400_650[] = {
8458 0x60, 0x03, 0x11, 0x00, 0x40, 0xef,
8459 0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02
8460 };
8461 static const unsigned char table1600_650[] = {
8462 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8463 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a
8464 };
8465
8466 if(SiS_Pr->ChipType == SIS_740) {
8467 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tableptr = table1024_740;
8468 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_740;
8469 else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_740;
8470 else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_740;
8471 else return;
8472 } else {
8473 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tableptr = table1024_650;
8474 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_650;
8475 else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_650;
8476 else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_650;
8477 else return;
8478 }
8479
8480 tempbh = SiS_GetCH701x(SiS_Pr,tempax: 0x74);
8481 if((tempbh == 0xf6) || (tempbh == 0xc7)) {
8482 tempbh = SiS_GetCH701x(SiS_Pr,tempax: 0x73);
8483 if(tempbh == 0xc8) {
8484 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) return;
8485 } else if(tempbh == 0xdb) {
8486 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) return;
8487 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) return;
8488 } else if(tempbh == 0xde) {
8489 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) return;
8490 }
8491 }
8492
8493 if(SiS_Pr->ChipType == SIS_740) tempbh = 0x0d;
8494 else tempbh = 0x0c;
8495
8496 for(i = 0; i < tempbh; i++) {
8497 SiS_SetCH701x(SiS_Pr, reg: regtable[i], val: tableptr[i]);
8498 }
8499 SiS_ChrontelPowerSequencing(SiS_Pr);
8500 tempbh = SiS_GetCH701x(SiS_Pr,tempax: 0x1e);
8501 tempbh |= 0xc0;
8502 SiS_SetCH701x(SiS_Pr,reg: 0x1e,val: tempbh);
8503
8504 if(SiS_Pr->ChipType == SIS_740) {
8505 tempbh = SiS_GetCH701x(SiS_Pr,tempax: 0x1c);
8506 tempbh &= 0xfb;
8507 SiS_SetCH701x(SiS_Pr,reg: 0x1c,val: tempbh);
8508 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8509 tempbh = SiS_GetCH701x(SiS_Pr,tempax: 0x64);
8510 tempbh |= 0x40;
8511 SiS_SetCH701x(SiS_Pr,reg: 0x64,val: tempbh);
8512 tempbh = SiS_GetCH701x(SiS_Pr,tempax: 0x03);
8513 tempbh &= 0x3f;
8514 SiS_SetCH701x(SiS_Pr,reg: 0x03,val: tempbh);
8515 }
8516}
8517
8518static void
8519SiS_ChrontelResetVSync(struct SiS_Private *SiS_Pr)
8520{
8521 unsigned char temp, temp1;
8522
8523 temp1 = SiS_GetCH701x(SiS_Pr,tempax: 0x49);
8524 SiS_SetCH701x(SiS_Pr,reg: 0x49,val: 0x3e);
8525 temp = SiS_GetCH701x(SiS_Pr,tempax: 0x47);
8526 temp &= 0x7f; /* Use external VSYNC */
8527 SiS_SetCH701x(SiS_Pr,reg: 0x47,val: temp);
8528 SiS_LongDelay(SiS_Pr, delay: 3);
8529 temp = SiS_GetCH701x(SiS_Pr,tempax: 0x47);
8530 temp |= 0x80; /* Use internal VSYNC */
8531 SiS_SetCH701x(SiS_Pr,reg: 0x47,val: temp);
8532 SiS_SetCH701x(SiS_Pr,reg: 0x49,val: temp1);
8533}
8534
8535static void
8536SiS_Chrontel701xOn(struct SiS_Private *SiS_Pr)
8537{
8538 unsigned short temp;
8539
8540 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8541 if(SiS_Pr->ChipType == SIS_740) {
8542 temp = SiS_GetCH701x(SiS_Pr,tempax: 0x1c);
8543 temp |= 0x04; /* Invert XCLK phase */
8544 SiS_SetCH701x(SiS_Pr,reg: 0x1c,val: temp);
8545 }
8546 if(SiS_IsYPbPr(SiS_Pr)) {
8547 temp = SiS_GetCH701x(SiS_Pr,tempax: 0x01);
8548 temp &= 0x3f;
8549 temp |= 0x80; /* Enable YPrPb (HDTV) */
8550 SiS_SetCH701x(SiS_Pr,reg: 0x01,val: temp);
8551 }
8552 if(SiS_IsChScart(SiS_Pr)) {
8553 temp = SiS_GetCH701x(SiS_Pr,tempax: 0x01);
8554 temp &= 0x3f;
8555 temp |= 0xc0; /* Enable SCART + CVBS */
8556 SiS_SetCH701x(SiS_Pr,reg: 0x01,val: temp);
8557 }
8558 if(SiS_Pr->ChipType == SIS_740) {
8559 SiS_ChrontelResetVSync(SiS_Pr);
8560 SiS_SetCH701x(SiS_Pr,reg: 0x49,val: 0x20); /* Enable TV path */
8561 } else {
8562 SiS_SetCH701x(SiS_Pr,reg: 0x49,val: 0x20); /* Enable TV path */
8563 temp = SiS_GetCH701x(SiS_Pr,tempax: 0x49);
8564 if(SiS_IsYPbPr(SiS_Pr)) {
8565 temp = SiS_GetCH701x(SiS_Pr,tempax: 0x73);
8566 temp |= 0x60;
8567 SiS_SetCH701x(SiS_Pr,reg: 0x73,val: temp);
8568 }
8569 temp = SiS_GetCH701x(SiS_Pr,tempax: 0x47);
8570 temp &= 0x7f;
8571 SiS_SetCH701x(SiS_Pr,reg: 0x47,val: temp);
8572 SiS_LongDelay(SiS_Pr, delay: 2);
8573 temp = SiS_GetCH701x(SiS_Pr,tempax: 0x47);
8574 temp |= 0x80;
8575 SiS_SetCH701x(SiS_Pr,reg: 0x47,val: temp);
8576 }
8577 }
8578}
8579
8580static void
8581SiS_Chrontel701xOff(struct SiS_Private *SiS_Pr)
8582{
8583 unsigned short temp;
8584
8585 /* Complete power down of LVDS */
8586 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8587 if(SiS_Pr->ChipType == SIS_740) {
8588 SiS_LongDelay(SiS_Pr, delay: 1);
8589 SiS_GenericDelay(SiS_Pr, delay: 5887);
8590 SiS_SetCH701x(SiS_Pr,reg: 0x76,val: 0xac);
8591 SiS_SetCH701x(SiS_Pr,reg: 0x66,val: 0x00);
8592 } else {
8593 SiS_LongDelay(SiS_Pr, delay: 2);
8594 temp = SiS_GetCH701x(SiS_Pr,tempax: 0x76);
8595 temp &= 0xfc;
8596 SiS_SetCH701x(SiS_Pr,reg: 0x76,val: temp);
8597 SiS_SetCH701x(SiS_Pr,reg: 0x66,val: 0x00);
8598 }
8599 }
8600}
8601
8602static void
8603SiS_ChrontelResetDB(struct SiS_Private *SiS_Pr)
8604{
8605 unsigned short temp;
8606
8607 if(SiS_Pr->ChipType == SIS_740) {
8608
8609 temp = SiS_GetCH701x(SiS_Pr,tempax: 0x4a); /* Version ID */
8610 temp &= 0x01;
8611 if(!temp) {
8612
8613 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8614 temp = SiS_GetCH701x(SiS_Pr,tempax: 0x49);
8615 SiS_SetCH701x(SiS_Pr,reg: 0x49,val: 0x3e);
8616 }
8617
8618 /* Reset Chrontel 7019 datapath */
8619 SiS_SetCH701x(SiS_Pr,reg: 0x48,val: 0x10);
8620 SiS_LongDelay(SiS_Pr, delay: 1);
8621 SiS_SetCH701x(SiS_Pr,reg: 0x48,val: 0x18);
8622
8623 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8624 SiS_ChrontelResetVSync(SiS_Pr);
8625 SiS_SetCH701x(SiS_Pr,reg: 0x49,val: temp);
8626 }
8627
8628 } else {
8629
8630 /* Clear/set/clear GPIO */
8631 temp = SiS_GetCH701x(SiS_Pr,tempax: 0x5c);
8632 temp &= 0xef;
8633 SiS_SetCH701x(SiS_Pr,reg: 0x5c,val: temp);
8634 temp = SiS_GetCH701x(SiS_Pr,tempax: 0x5c);
8635 temp |= 0x10;
8636 SiS_SetCH701x(SiS_Pr,reg: 0x5c,val: temp);
8637 temp = SiS_GetCH701x(SiS_Pr,tempax: 0x5c);
8638 temp &= 0xef;
8639 SiS_SetCH701x(SiS_Pr,reg: 0x5c,val: temp);
8640 temp = SiS_GetCH701x(SiS_Pr,tempax: 0x61);
8641 if(!temp) {
8642 SiS_SetCH701xForLCD(SiS_Pr);
8643 }
8644 }
8645
8646 } else { /* 650 */
8647 /* Reset Chrontel 7019 datapath */
8648 SiS_SetCH701x(SiS_Pr,reg: 0x48,val: 0x10);
8649 SiS_LongDelay(SiS_Pr, delay: 1);
8650 SiS_SetCH701x(SiS_Pr,reg: 0x48,val: 0x18);
8651 }
8652}
8653
8654static void
8655SiS_ChrontelInitTVVSync(struct SiS_Private *SiS_Pr)
8656{
8657 unsigned short temp;
8658
8659 if(SiS_Pr->ChipType == SIS_740) {
8660
8661 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8662 SiS_ChrontelResetVSync(SiS_Pr);
8663 }
8664
8665 } else {
8666
8667 SiS_SetCH701x(SiS_Pr,reg: 0x76,val: 0xaf); /* Power up LVDS block */
8668 temp = SiS_GetCH701x(SiS_Pr,tempax: 0x49);
8669 temp &= 1;
8670 if(temp != 1) { /* TV block powered? (0 = yes, 1 = no) */
8671 temp = SiS_GetCH701x(SiS_Pr,tempax: 0x47);
8672 temp &= 0x70;
8673 SiS_SetCH701x(SiS_Pr,reg: 0x47,val: temp); /* enable VSYNC */
8674 SiS_LongDelay(SiS_Pr, delay: 3);
8675 temp = SiS_GetCH701x(SiS_Pr,tempax: 0x47);
8676 temp |= 0x80;
8677 SiS_SetCH701x(SiS_Pr,reg: 0x47,val: temp); /* disable VSYNC */
8678 }
8679
8680 }
8681}
8682
8683static void
8684SiS_ChrontelDoSomething3(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
8685{
8686 unsigned short temp,temp1;
8687
8688 if(SiS_Pr->ChipType == SIS_740) {
8689
8690 temp = SiS_GetCH701x(SiS_Pr,tempax: 0x61);
8691 if(temp < 1) {
8692 temp++;
8693 SiS_SetCH701x(SiS_Pr,reg: 0x61,val: temp);
8694 }
8695 SiS_SetCH701x(SiS_Pr,reg: 0x66,val: 0x45); /* Panel power on */
8696 SiS_SetCH701x(SiS_Pr,reg: 0x76,val: 0xaf); /* All power on */
8697 SiS_LongDelay(SiS_Pr, delay: 1);
8698 SiS_GenericDelay(SiS_Pr, delay: 5887);
8699
8700 } else { /* 650 */
8701
8702 temp1 = 0;
8703 temp = SiS_GetCH701x(SiS_Pr,tempax: 0x61);
8704 if(temp < 2) {
8705 temp++;
8706 SiS_SetCH701x(SiS_Pr,reg: 0x61,val: temp);
8707 temp1 = 1;
8708 }
8709 SiS_SetCH701x(SiS_Pr,reg: 0x76,val: 0xac);
8710 temp = SiS_GetCH701x(SiS_Pr,tempax: 0x66);
8711 temp |= 0x5f;
8712 SiS_SetCH701x(SiS_Pr,reg: 0x66,val: temp);
8713 if(ModeNo > 0x13) {
8714 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8715 SiS_GenericDelay(SiS_Pr, delay: 1023);
8716 } else {
8717 SiS_GenericDelay(SiS_Pr, delay: 767);
8718 }
8719 } else {
8720 if(!temp1)
8721 SiS_GenericDelay(SiS_Pr, delay: 767);
8722 }
8723 temp = SiS_GetCH701x(SiS_Pr,tempax: 0x76);
8724 temp |= 0x03;
8725 SiS_SetCH701x(SiS_Pr,reg: 0x76,val: temp);
8726 temp = SiS_GetCH701x(SiS_Pr,tempax: 0x66);
8727 temp &= 0x7f;
8728 SiS_SetCH701x(SiS_Pr,reg: 0x66,val: temp);
8729 SiS_LongDelay(SiS_Pr, delay: 1);
8730
8731 }
8732}
8733
8734static void
8735SiS_ChrontelDoSomething2(struct SiS_Private *SiS_Pr)
8736{
8737 unsigned short temp;
8738
8739 SiS_LongDelay(SiS_Pr, delay: 1);
8740
8741 do {
8742 temp = SiS_GetCH701x(SiS_Pr,tempax: 0x66);
8743 temp &= 0x04; /* PLL stable? -> bail out */
8744 if(temp == 0x04) break;
8745
8746 if(SiS_Pr->ChipType == SIS_740) {
8747 /* Power down LVDS output, PLL normal operation */
8748 SiS_SetCH701x(SiS_Pr,reg: 0x76,val: 0xac);
8749 }
8750
8751 SiS_SetCH701xForLCD(SiS_Pr);
8752
8753 temp = SiS_GetCH701x(SiS_Pr,tempax: 0x76);
8754 temp &= 0xfb; /* Reset PLL */
8755 SiS_SetCH701x(SiS_Pr,reg: 0x76,val: temp);
8756 SiS_LongDelay(SiS_Pr, delay: 2);
8757 temp = SiS_GetCH701x(SiS_Pr,tempax: 0x76);
8758 temp |= 0x04; /* PLL normal operation */
8759 SiS_SetCH701x(SiS_Pr,reg: 0x76,val: temp);
8760 if(SiS_Pr->ChipType == SIS_740) {
8761 SiS_SetCH701x(SiS_Pr,reg: 0x78,val: 0xe0); /* PLL loop filter */
8762 } else {
8763 SiS_SetCH701x(SiS_Pr,reg: 0x78,val: 0x60);
8764 }
8765 SiS_LongDelay(SiS_Pr, delay: 2);
8766 } while(0);
8767
8768 SiS_SetCH701x(SiS_Pr,reg: 0x77,val: 0x00); /* MV? */
8769}
8770
8771static void
8772SiS_ChrontelDoSomething1(struct SiS_Private *SiS_Pr)
8773{
8774 unsigned short temp;
8775
8776 temp = SiS_GetCH701x(SiS_Pr,tempax: 0x03);
8777 temp |= 0x80; /* Set datapath 1 to TV */
8778 temp &= 0xbf; /* Set datapath 2 to LVDS */
8779 SiS_SetCH701x(SiS_Pr,reg: 0x03,val: temp);
8780
8781 if(SiS_Pr->ChipType == SIS_740) {
8782
8783 temp = SiS_GetCH701x(SiS_Pr,tempax: 0x1c);
8784 temp &= 0xfb; /* Normal XCLK phase */
8785 SiS_SetCH701x(SiS_Pr,reg: 0x1c,val: temp);
8786
8787 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8788
8789 temp = SiS_GetCH701x(SiS_Pr,tempax: 0x64);
8790 temp |= 0x40; /* ? Bit not defined */
8791 SiS_SetCH701x(SiS_Pr,reg: 0x64,val: temp);
8792
8793 temp = SiS_GetCH701x(SiS_Pr,tempax: 0x03);
8794 temp &= 0x3f; /* D1 input to both LVDS and TV */
8795 SiS_SetCH701x(SiS_Pr,reg: 0x03,val: temp);
8796
8797 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) {
8798 SiS_SetCH701x(SiS_Pr,reg: 0x63,val: 0x40); /* LVDS off */
8799 SiS_LongDelay(SiS_Pr, delay: 1);
8800 SiS_SetCH701x(SiS_Pr,reg: 0x63,val: 0x00); /* LVDS on */
8801 SiS_ChrontelResetDB(SiS_Pr);
8802 SiS_ChrontelDoSomething2(SiS_Pr);
8803 SiS_ChrontelDoSomething3(SiS_Pr, ModeNo: 0);
8804 } else {
8805 temp = SiS_GetCH701x(SiS_Pr,tempax: 0x66);
8806 if(temp != 0x45) {
8807 SiS_ChrontelResetDB(SiS_Pr);
8808 SiS_ChrontelDoSomething2(SiS_Pr);
8809 SiS_ChrontelDoSomething3(SiS_Pr, ModeNo: 0);
8810 }
8811 }
8812
8813 } else { /* 650 */
8814
8815 SiS_ChrontelResetDB(SiS_Pr);
8816 SiS_ChrontelDoSomething2(SiS_Pr);
8817 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34);
8818 SiS_ChrontelDoSomething3(SiS_Pr,ModeNo: temp);
8819 SiS_SetCH701x(SiS_Pr,reg: 0x76,val: 0xaf); /* All power on, LVDS normal operation */
8820
8821 }
8822
8823}
8824#endif /* 315 series */
8825
8826/*********************************************/
8827/* MAIN: SET CRT2 REGISTER GROUP */
8828/*********************************************/
8829
8830bool
8831SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
8832{
8833#ifdef CONFIG_FB_SIS_300
8834 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
8835#endif
8836 unsigned short ModeIdIndex, RefreshRateTableIndex;
8837
8838 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
8839
8840 if(!SiS_Pr->UseCustomMode) {
8841 SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex);
8842 } else {
8843 ModeIdIndex = 0;
8844 }
8845
8846 /* Used for shifting CR33 */
8847 SiS_Pr->SiS_SelectCRT2Rate = 4;
8848
8849 SiS_UnLockCRT2(SiS_Pr);
8850
8851 RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex);
8852
8853 SiS_SaveCRT2Info(SiS_Pr,ModeNo);
8854
8855 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8856 SiS_DisableBridge(SiS_Pr);
8857 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->ChipType == SIS_730)) {
8858 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,0x80);
8859 }
8860 SiS_SetCRT2ModeRegs(SiS_Pr, ModeNo, ModeIdIndex);
8861 }
8862
8863 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
8864 SiS_LockCRT2(SiS_Pr);
8865 SiS_DisplayOn(SiS_Pr);
8866 return true;
8867 }
8868
8869 SiS_GetCRT2Data(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8870
8871 /* Set up Panel Link for LVDS and LCDA */
8872 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
8873 if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
8874 ((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ||
8875 ((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS30xBLV)) ) {
8876 SiS_GetLVDSDesData(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8877 }
8878
8879 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8880 SiS_SetGroup1(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8881 }
8882
8883 if(SiS_Pr->SiS_VBType & VB_SISVB) {
8884
8885 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8886
8887 SiS_SetGroup2(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8888#ifdef CONFIG_FB_SIS_315
8889 SiS_SetGroup2_C_ELV(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8890#endif
8891 SiS_SetGroup3(SiS_Pr, ModeNo, ModeIdIndex);
8892 SiS_SetGroup4(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8893#ifdef CONFIG_FB_SIS_315
8894 SiS_SetGroup4_C_ELV(SiS_Pr, ModeNo, ModeIdIndex);
8895#endif
8896 SiS_SetGroup5(SiS_Pr, ModeNo, ModeIdIndex);
8897
8898 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex);
8899
8900 /* For 301BDH (Panel link initialization): */
8901 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
8902
8903 if(!((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10)))) {
8904 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
8905 SiS_ModCRT1CRTC(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8906 }
8907 }
8908 SiS_SetCRT2ECLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8909 }
8910 }
8911
8912 } else {
8913
8914 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex);
8915
8916 SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8917
8918 SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8919
8920 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8921 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
8922 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
8923 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8924#ifdef CONFIG_FB_SIS_315
8925 SiS_SetCH701xForLCD(SiS_Pr);
8926#endif
8927 }
8928 }
8929 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8930 SiS_SetCHTVReg(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8931 }
8932 }
8933 }
8934
8935 }
8936
8937#ifdef CONFIG_FB_SIS_300
8938 if(SiS_Pr->ChipType < SIS_315H) {
8939 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8940 if(SiS_Pr->SiS_UseOEM) {
8941 if((SiS_Pr->SiS_UseROM) && (SiS_Pr->SiS_UseOEM == -1)) {
8942 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
8943 SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefTabindex: RefreshRateTableIndex);
8944 }
8945 } else {
8946 SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefTabindex: RefreshRateTableIndex);
8947 }
8948 }
8949 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
8950 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
8951 (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
8952 SetOEMLCDData2(SiS_Pr, ModeNo, ModeIdIndex,RefTableIndex: RefreshRateTableIndex);
8953 }
8954 SiS_DisplayOn(SiS_Pr);
8955 }
8956 }
8957 }
8958#endif
8959
8960#ifdef CONFIG_FB_SIS_315
8961 if(SiS_Pr->ChipType >= SIS_315H) {
8962 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8963 if(SiS_Pr->ChipType < SIS_661) {
8964 SiS_FinalizeLCD(SiS_Pr, ModeNo, ModeIdIndex);
8965 SiS_OEM310Setting(SiS_Pr, ModeNo, ModeIdIndex, RRTI: RefreshRateTableIndex);
8966 } else {
8967 SiS_OEM661Setting(SiS_Pr, ModeNo, ModeIdIndex, RRTI: RefreshRateTableIndex);
8968 }
8969 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40);
8970 }
8971 }
8972#endif
8973
8974 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8975 SiS_EnableBridge(SiS_Pr);
8976 }
8977
8978 SiS_DisplayOn(SiS_Pr);
8979
8980 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
8981 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8982 /* Disable LCD panel when using TV */
8983 SiS_SetRegSR11ANDOR(SiS_Pr,DataAND: 0xFF,DataOR: 0x0C);
8984 } else {
8985 /* Disable TV when using LCD */
8986 SiS_SetCH70xxANDOR(SiS_Pr,reg: 0x0e,orval: 0x01,andval: 0xf8);
8987 }
8988 }
8989
8990 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8991 SiS_LockCRT2(SiS_Pr);
8992 }
8993
8994 return true;
8995}
8996
8997
8998/*********************************************/
8999/* ENABLE/DISABLE LCD BACKLIGHT (SIS) */
9000/*********************************************/
9001
9002void
9003SiS_SiS30xBLOn(struct SiS_Private *SiS_Pr)
9004{
9005 /* Switch on LCD backlight on SiS30xLV */
9006 SiS_DDC2Delay(SiS_Pr,delaytime: 0xff00);
9007 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
9008 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
9009 SiS_WaitVBRetrace(SiS_Pr);
9010 }
9011 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x01)) {
9012 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
9013 }
9014}
9015
9016void
9017SiS_SiS30xBLOff(struct SiS_Private *SiS_Pr)
9018{
9019 /* Switch off LCD backlight on SiS30xLV */
9020 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
9021 SiS_DDC2Delay(SiS_Pr,delaytime: 0xff00);
9022}
9023
9024/*********************************************/
9025/* DDC RELATED FUNCTIONS */
9026/*********************************************/
9027
9028static void
9029SiS_SetupDDCN(struct SiS_Private *SiS_Pr)
9030{
9031 SiS_Pr->SiS_DDC_NData = ~SiS_Pr->SiS_DDC_Data;
9032 SiS_Pr->SiS_DDC_NClk = ~SiS_Pr->SiS_DDC_Clk;
9033 if((SiS_Pr->SiS_DDC_Index == 0x11) && (SiS_Pr->SiS_SensibleSR11)) {
9034 SiS_Pr->SiS_DDC_NData &= 0x0f;
9035 SiS_Pr->SiS_DDC_NClk &= 0x0f;
9036 }
9037}
9038
9039#ifdef CONFIG_FB_SIS_300
9040static unsigned char *
9041SiS_SetTrumpBlockLoop(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
9042{
9043 int i, j, num;
9044 unsigned short tempah,temp;
9045 unsigned char *mydataptr;
9046
9047 for(i=0; i<20; i++) { /* Do 20 attempts to write */
9048 mydataptr = dataptr;
9049 num = *mydataptr++;
9050 if(!num) return mydataptr;
9051 if(i) {
9052 SiS_SetStop(SiS_Pr);
9053 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 2);
9054 }
9055 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
9056 tempah = SiS_Pr->SiS_DDC_DeviceAddr;
9057 temp = SiS_WriteDDC2Data(SiS_Pr,tempax: tempah); /* Write DAB (S0=0=write) */
9058 if(temp) continue; /* (ERROR: no ack) */
9059 tempah = *mydataptr++;
9060 temp = SiS_WriteDDC2Data(SiS_Pr,tempax: tempah); /* Write register number */
9061 if(temp) continue; /* (ERROR: no ack) */
9062 for(j=0; j<num; j++) {
9063 tempah = *mydataptr++;
9064 temp = SiS_WriteDDC2Data(SiS_Pr,tempax: tempah);/* Write DAB (S0=0=write) */
9065 if(temp) break;
9066 }
9067 if(temp) continue;
9068 if(SiS_SetStop(SiS_Pr)) continue;
9069 return mydataptr;
9070 }
9071 return NULL;
9072}
9073
9074static bool
9075SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
9076{
9077 SiS_Pr->SiS_DDC_DeviceAddr = 0xF0; /* DAB (Device Address Byte) */
9078 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9079 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
9080 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
9081 SiS_SetupDDCN(SiS_Pr);
9082
9083 SiS_SetSwitchDDC2(SiS_Pr);
9084
9085 while(*dataptr) {
9086 dataptr = SiS_SetTrumpBlockLoop(SiS_Pr, dataptr);
9087 if(!dataptr) return false;
9088 }
9089 return true;
9090}
9091#endif
9092
9093/* The Chrontel 700x is connected to the 630/730 via
9094 * the 630/730's DDC/I2C port.
9095 *
9096 * On 630(S)T chipset, the index changed from 0x11 to
9097 * 0x0a, possibly for working around the DDC problems
9098 */
9099
9100static bool
9101SiS_SetChReg(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val, unsigned short myor)
9102{
9103 unsigned short temp, i;
9104
9105 for(i=0; i<20; i++) { /* Do 20 attempts to write */
9106 if(i) {
9107 SiS_SetStop(SiS_Pr);
9108 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4);
9109 }
9110 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
9111 temp = SiS_WriteDDC2Data(SiS_Pr, tempax: SiS_Pr->SiS_DDC_DeviceAddr); /* Write DAB (S0=0=write) */
9112 if(temp) continue; /* (ERROR: no ack) */
9113 temp = SiS_WriteDDC2Data(SiS_Pr, tempax: (reg | myor)); /* Write RAB (700x: set bit 7, see datasheet) */
9114 if(temp) continue; /* (ERROR: no ack) */
9115 temp = SiS_WriteDDC2Data(SiS_Pr, tempax: val); /* Write data */
9116 if(temp) continue; /* (ERROR: no ack) */
9117 if(SiS_SetStop(SiS_Pr)) continue; /* Set stop condition */
9118 SiS_Pr->SiS_ChrontelInit = 1;
9119 return true;
9120 }
9121 return false;
9122}
9123
9124/* Write to Chrontel 700x */
9125void
9126SiS_SetCH700x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
9127{
9128 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */
9129
9130 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9131
9132 if(!(SiS_Pr->SiS_ChrontelInit)) {
9133 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9134 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
9135 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
9136 SiS_SetupDDCN(SiS_Pr);
9137 }
9138
9139 if( (!(SiS_SetChReg(SiS_Pr, reg, val, myor: 0x80))) &&
9140 (!(SiS_Pr->SiS_ChrontelInit)) ) {
9141 SiS_Pr->SiS_DDC_Index = 0x0a;
9142 SiS_Pr->SiS_DDC_Data = 0x80;
9143 SiS_Pr->SiS_DDC_Clk = 0x40;
9144 SiS_SetupDDCN(SiS_Pr);
9145
9146 SiS_SetChReg(SiS_Pr, reg, val, myor: 0x80);
9147 }
9148}
9149
9150/* Write to Chrontel 701x */
9151/* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
9152void
9153SiS_SetCH701x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
9154{
9155 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9156 SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */
9157 SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */
9158 SiS_SetupDDCN(SiS_Pr);
9159 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */
9160 SiS_SetChReg(SiS_Pr, reg, val, myor: 0);
9161}
9162
9163static
9164void
9165SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
9166{
9167 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
9168 SiS_SetCH700x(SiS_Pr, reg, val);
9169 else
9170 SiS_SetCH701x(SiS_Pr, reg, val);
9171}
9172
9173static unsigned short
9174SiS_GetChReg(struct SiS_Private *SiS_Pr, unsigned short myor)
9175{
9176 unsigned short tempah, temp, i;
9177
9178 for(i=0; i<20; i++) { /* Do 20 attempts to read */
9179 if(i) {
9180 SiS_SetStop(SiS_Pr);
9181 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4);
9182 }
9183 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
9184 temp = SiS_WriteDDC2Data(SiS_Pr,tempax: SiS_Pr->SiS_DDC_DeviceAddr); /* Write DAB (S0=0=write) */
9185 if(temp) continue; /* (ERROR: no ack) */
9186 temp = SiS_WriteDDC2Data(SiS_Pr,tempax: SiS_Pr->SiS_DDC_ReadAddr | myor); /* Write RAB (700x: | 0x80) */
9187 if(temp) continue; /* (ERROR: no ack) */
9188 if (SiS_SetStart(SiS_Pr)) continue; /* Re-start */
9189 temp = SiS_WriteDDC2Data(SiS_Pr,tempax: SiS_Pr->SiS_DDC_DeviceAddr | 0x01);/* DAB (S0=1=read) */
9190 if(temp) continue; /* (ERROR: no ack) */
9191 tempah = SiS_ReadDDC2Data(SiS_Pr); /* Read byte */
9192 if(SiS_SetStop(SiS_Pr)) continue; /* Stop condition */
9193 SiS_Pr->SiS_ChrontelInit = 1;
9194 return tempah;
9195 }
9196 return 0xFFFF;
9197}
9198
9199/* Read from Chrontel 700x */
9200/* Parameter is [Register no (S7-S0)] */
9201unsigned short
9202SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short tempbx)
9203{
9204 unsigned short result;
9205
9206 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */
9207
9208 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9209
9210 if(!(SiS_Pr->SiS_ChrontelInit)) {
9211 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9212 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
9213 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
9214 SiS_SetupDDCN(SiS_Pr);
9215 }
9216
9217 SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9218
9219 if( ((result = SiS_GetChReg(SiS_Pr,myor: 0x80)) == 0xFFFF) &&
9220 (!SiS_Pr->SiS_ChrontelInit) ) {
9221
9222 SiS_Pr->SiS_DDC_Index = 0x0a;
9223 SiS_Pr->SiS_DDC_Data = 0x80;
9224 SiS_Pr->SiS_DDC_Clk = 0x40;
9225 SiS_SetupDDCN(SiS_Pr);
9226
9227 result = SiS_GetChReg(SiS_Pr,myor: 0x80);
9228 }
9229 return result;
9230}
9231
9232/* Read from Chrontel 701x */
9233/* Parameter is [Register no (S7-S0)] */
9234unsigned short
9235SiS_GetCH701x(struct SiS_Private *SiS_Pr, unsigned short tempbx)
9236{
9237 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9238 SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */
9239 SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */
9240 SiS_SetupDDCN(SiS_Pr);
9241 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */
9242
9243 SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9244
9245 return SiS_GetChReg(SiS_Pr,myor: 0);
9246}
9247
9248/* Read from Chrontel 70xx */
9249/* Parameter is [Register no (S7-S0)] */
9250static
9251unsigned short
9252SiS_GetCH70xx(struct SiS_Private *SiS_Pr, unsigned short tempbx)
9253{
9254 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
9255 return SiS_GetCH700x(SiS_Pr, tempbx);
9256 else
9257 return SiS_GetCH701x(SiS_Pr, tempbx);
9258}
9259
9260void
9261SiS_SetCH70xxANDOR(struct SiS_Private *SiS_Pr, unsigned short reg,
9262 unsigned char myor, unsigned short myand)
9263{
9264 unsigned short tempbl;
9265
9266 tempbl = (SiS_GetCH70xx(SiS_Pr, tempbx: (reg & 0xFF)) & myand) | myor;
9267 SiS_SetCH70xx(SiS_Pr, reg, val: tempbl);
9268}
9269
9270/* Our own DDC functions */
9271static
9272unsigned short
9273SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
9274 unsigned short adaptnum, unsigned short DDCdatatype, bool checkcr32,
9275 unsigned int VBFlags2)
9276{
9277 unsigned char ddcdtype[] = { 0xa0, 0xa0, 0xa0, 0xa2, 0xa6 };
9278 unsigned char flag, cr32;
9279 unsigned short temp = 0, myadaptnum = adaptnum;
9280
9281 if(adaptnum != 0) {
9282 if(!(VBFlags2 & VB2_SISTMDSBRIDGE)) return 0xFFFF;
9283 if((VBFlags2 & VB2_30xBDH) && (adaptnum == 1)) return 0xFFFF;
9284 }
9285
9286 /* adapternum for SiS bridges: 0 = CRT1, 1 = LCD, 2 = VGA2 */
9287
9288 SiS_Pr->SiS_ChrontelInit = 0; /* force re-detection! */
9289
9290 SiS_Pr->SiS_DDC_SecAddr = 0;
9291 SiS_Pr->SiS_DDC_DeviceAddr = ddcdtype[DDCdatatype];
9292 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_P3c4;
9293 SiS_Pr->SiS_DDC_Index = 0x11;
9294 flag = 0xff;
9295
9296 cr32 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x32);
9297
9298#if 0
9299 if(VBFlags2 & VB2_SISBRIDGE) {
9300 if(myadaptnum == 0) {
9301 if(!(cr32 & 0x20)) {
9302 myadaptnum = 2;
9303 if(!(cr32 & 0x10)) {
9304 myadaptnum = 1;
9305 if(!(cr32 & 0x08)) {
9306 myadaptnum = 0;
9307 }
9308 }
9309 }
9310 }
9311 }
9312#endif
9313
9314 if(VGAEngine == SIS_300_VGA) { /* 300 series */
9315
9316 if(myadaptnum != 0) {
9317 flag = 0;
9318 if(VBFlags2 & VB2_SISBRIDGE) {
9319 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9320 SiS_Pr->SiS_DDC_Index = 0x0f;
9321 }
9322 }
9323
9324 if(!(VBFlags2 & VB2_301)) {
9325 if((cr32 & 0x80) && (checkcr32)) {
9326 if(myadaptnum >= 1) {
9327 if(!(cr32 & 0x08)) {
9328 myadaptnum = 1;
9329 if(!(cr32 & 0x10)) return 0xFFFF;
9330 }
9331 }
9332 }
9333 }
9334
9335 temp = 4 - (myadaptnum * 2);
9336 if(flag) temp = 0;
9337
9338 } else { /* 315/330 series */
9339
9340 /* here we simplify: 0 = CRT1, 1 = CRT2 (VGA, LCD) */
9341
9342 if(VBFlags2 & VB2_SISBRIDGE) {
9343 if(myadaptnum == 2) {
9344 myadaptnum = 1;
9345 }
9346 }
9347
9348 if(myadaptnum == 1) {
9349 flag = 0;
9350 if(VBFlags2 & VB2_SISBRIDGE) {
9351 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9352 SiS_Pr->SiS_DDC_Index = 0x0f;
9353 }
9354 }
9355
9356 if((cr32 & 0x80) && (checkcr32)) {
9357 if(myadaptnum >= 1) {
9358 if(!(cr32 & 0x08)) {
9359 myadaptnum = 1;
9360 if(!(cr32 & 0x10)) return 0xFFFF;
9361 }
9362 }
9363 }
9364
9365 temp = myadaptnum;
9366 if(myadaptnum == 1) {
9367 temp = 0;
9368 if(VBFlags2 & VB2_LVDS) flag = 0xff;
9369 }
9370
9371 if(flag) temp = 0;
9372 }
9373
9374 SiS_Pr->SiS_DDC_Data = 0x02 << temp;
9375 SiS_Pr->SiS_DDC_Clk = 0x01 << temp;
9376
9377 SiS_SetupDDCN(SiS_Pr);
9378
9379 return 0;
9380}
9381
9382static unsigned short
9383SiS_WriteDABDDC(struct SiS_Private *SiS_Pr)
9384{
9385 if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9386 if(SiS_WriteDDC2Data(SiS_Pr, tempax: SiS_Pr->SiS_DDC_DeviceAddr)) {
9387 return 0xFFFF;
9388 }
9389 if(SiS_WriteDDC2Data(SiS_Pr, tempax: SiS_Pr->SiS_DDC_SecAddr)) {
9390 return 0xFFFF;
9391 }
9392 return 0;
9393}
9394
9395static unsigned short
9396SiS_PrepareReadDDC(struct SiS_Private *SiS_Pr)
9397{
9398 if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9399 if(SiS_WriteDDC2Data(SiS_Pr, tempax: (SiS_Pr->SiS_DDC_DeviceAddr | 0x01))) {
9400 return 0xFFFF;
9401 }
9402 return 0;
9403}
9404
9405static unsigned short
9406SiS_PrepareDDC(struct SiS_Private *SiS_Pr)
9407{
9408 if(SiS_WriteDABDDC(SiS_Pr)) SiS_WriteDABDDC(SiS_Pr);
9409 if(SiS_PrepareReadDDC(SiS_Pr)) return (SiS_PrepareReadDDC(SiS_Pr));
9410 return 0;
9411}
9412
9413static void
9414SiS_SendACK(struct SiS_Private *SiS_Pr, unsigned short yesno)
9415{
9416 SiS_SetSCLKLow(SiS_Pr);
9417 if(yesno) {
9418 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9419 SiS_Pr->SiS_DDC_Index,
9420 SiS_Pr->SiS_DDC_NData,
9421 SiS_Pr->SiS_DDC_Data);
9422 } else {
9423 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9424 SiS_Pr->SiS_DDC_Index,
9425 SiS_Pr->SiS_DDC_NData,
9426 0);
9427 }
9428 SiS_SetSCLKHigh(SiS_Pr);
9429}
9430
9431static unsigned short
9432SiS_DoProbeDDC(struct SiS_Private *SiS_Pr)
9433{
9434 unsigned char mask, value;
9435 unsigned short temp, ret=0;
9436 bool failed = false;
9437
9438 SiS_SetSwitchDDC2(SiS_Pr);
9439 if(SiS_PrepareDDC(SiS_Pr)) {
9440 SiS_SetStop(SiS_Pr);
9441 return 0xFFFF;
9442 }
9443 mask = 0xf0;
9444 value = 0x20;
9445 if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9446 temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9447 SiS_SendACK(SiS_Pr, yesno: 0);
9448 if(temp == 0) {
9449 mask = 0xff;
9450 value = 0xff;
9451 } else {
9452 failed = true;
9453 ret = 0xFFFF;
9454 }
9455 }
9456 if(!failed) {
9457 temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9458 SiS_SendACK(SiS_Pr, yesno: 1);
9459 temp &= mask;
9460 if(temp == value) ret = 0;
9461 else {
9462 ret = 0xFFFF;
9463 if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9464 if(temp == 0x30) ret = 0;
9465 }
9466 }
9467 }
9468 SiS_SetStop(SiS_Pr);
9469 return ret;
9470}
9471
9472static
9473unsigned short
9474SiS_ProbeDDC(struct SiS_Private *SiS_Pr)
9475{
9476 unsigned short flag;
9477
9478 flag = 0x180;
9479 SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
9480 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x02;
9481 SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;
9482 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x08;
9483 SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;
9484 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x10;
9485 if(!(flag & 0x1a)) flag = 0;
9486 return flag;
9487}
9488
9489static
9490unsigned short
9491SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype, unsigned char *buffer)
9492{
9493 unsigned short flag, length, i;
9494 unsigned char chksum,gotcha;
9495
9496 if(DDCdatatype > 4) return 0xFFFF;
9497
9498 flag = 0;
9499 SiS_SetSwitchDDC2(SiS_Pr);
9500 if(!(SiS_PrepareDDC(SiS_Pr))) {
9501 length = 127;
9502 if(DDCdatatype != 1) length = 255;
9503 chksum = 0;
9504 gotcha = 0;
9505 for(i=0; i<length; i++) {
9506 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9507 chksum += buffer[i];
9508 gotcha |= buffer[i];
9509 SiS_SendACK(SiS_Pr, yesno: 0);
9510 }
9511 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9512 chksum += buffer[i];
9513 SiS_SendACK(SiS_Pr, yesno: 1);
9514 if(gotcha) flag = (unsigned short)chksum;
9515 else flag = 0xFFFF;
9516 } else {
9517 flag = 0xFFFF;
9518 }
9519 SiS_SetStop(SiS_Pr);
9520 return flag;
9521}
9522
9523/* Our private DDC functions
9524
9525 It complies somewhat with the corresponding VESA function
9526 in arguments and return values.
9527
9528 Since this is probably called before the mode is changed,
9529 we use our pre-detected pSiS-values instead of SiS_Pr as
9530 regards chipset and video bridge type.
9531
9532 Arguments:
9533 adaptnum: 0=CRT1(analog), 1=CRT2/LCD(digital), 2=CRT2/VGA2(analog)
9534 CRT2 DDC is only supported on SiS301, 301B, 301C, 302B.
9535 LCDA is CRT1, but DDC is read from CRT2 port.
9536 DDCdatatype: 0=Probe, 1=EDID, 2=EDID+VDIF, 3=EDID V2 (P&D), 4=EDID V2 (FPDI-2)
9537 buffer: ptr to 256 data bytes which will be filled with read data.
9538
9539 Returns 0xFFFF if error, otherwise
9540 if DDCdatatype > 0: Returns 0 if reading OK (included a correct checksum)
9541 if DDCdatatype = 0: Returns supported DDC modes
9542
9543 */
9544unsigned short
9545SiS_HandleDDC(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
9546 unsigned short adaptnum, unsigned short DDCdatatype, unsigned char *buffer,
9547 unsigned int VBFlags2)
9548{
9549 unsigned char sr1f, cr17=1;
9550 unsigned short result;
9551
9552 if(adaptnum > 2)
9553 return 0xFFFF;
9554
9555 if(DDCdatatype > 4)
9556 return 0xFFFF;
9557
9558 if((!(VBFlags2 & VB2_VIDEOBRIDGE)) && (adaptnum > 0))
9559 return 0xFFFF;
9560
9561 if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, checkcr32: false, VBFlags2) == 0xFFFF)
9562 return 0xFFFF;
9563
9564 sr1f = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f);
9565 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1f,0x3f,0x04);
9566 if(VGAEngine == SIS_300_VGA) {
9567 cr17 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80;
9568 if(!cr17) {
9569 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x17,0x80);
9570 SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x01);
9571 SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x03);
9572 }
9573 }
9574 if((sr1f) || (!cr17)) {
9575 SiS_WaitRetrace1(SiS_Pr);
9576 SiS_WaitRetrace1(SiS_Pr);
9577 SiS_WaitRetrace1(SiS_Pr);
9578 SiS_WaitRetrace1(SiS_Pr);
9579 }
9580
9581 if(DDCdatatype == 0) {
9582 result = SiS_ProbeDDC(SiS_Pr);
9583 } else {
9584 result = SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer);
9585 if((!result) && (DDCdatatype == 1)) {
9586 if((buffer[0] == 0x00) && (buffer[1] == 0xff) &&
9587 (buffer[2] == 0xff) && (buffer[3] == 0xff) &&
9588 (buffer[4] == 0xff) && (buffer[5] == 0xff) &&
9589 (buffer[6] == 0xff) && (buffer[7] == 0x00) &&
9590 (buffer[0x12] == 1)) {
9591 if(!SiS_Pr->DDCPortMixup) {
9592 if(adaptnum == 1) {
9593 if(!(buffer[0x14] & 0x80)) result = 0xFFFE;
9594 } else {
9595 if(buffer[0x14] & 0x80) result = 0xFFFE;
9596 }
9597 }
9598 }
9599 }
9600 }
9601 SiS_SetReg(SiS_Pr->SiS_P3c4,0x1f,sr1f);
9602 if(VGAEngine == SIS_300_VGA) {
9603 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x17,0x7f,cr17);
9604 }
9605 return result;
9606}
9607
9608/* Generic I2C functions for Chrontel & DDC --------- */
9609
9610static void
9611SiS_SetSwitchDDC2(struct SiS_Private *SiS_Pr)
9612{
9613 SiS_SetSCLKHigh(SiS_Pr);
9614 SiS_WaitRetrace1(SiS_Pr);
9615
9616 SiS_SetSCLKLow(SiS_Pr);
9617 SiS_WaitRetrace1(SiS_Pr);
9618}
9619
9620unsigned short
9621SiS_ReadDDC1Bit(struct SiS_Private *SiS_Pr)
9622{
9623 SiS_WaitRetrace1(SiS_Pr);
9624 return ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x02) >> 1);
9625}
9626
9627/* Set I2C start condition */
9628/* This is done by a SD high-to-low transition while SC is high */
9629static unsigned short
9630SiS_SetStart(struct SiS_Private *SiS_Pr)
9631{
9632 if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */
9633 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9634 SiS_Pr->SiS_DDC_Index,
9635 SiS_Pr->SiS_DDC_NData,
9636 SiS_Pr->SiS_DDC_Data); /* SD->high */
9637 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */
9638 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9639 SiS_Pr->SiS_DDC_Index,
9640 SiS_Pr->SiS_DDC_NData,
9641 0x00); /* SD->low = start condition */
9642 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->low) */
9643 return 0;
9644}
9645
9646/* Set I2C stop condition */
9647/* This is done by a SD low-to-high transition while SC is high */
9648static unsigned short
9649SiS_SetStop(struct SiS_Private *SiS_Pr)
9650{
9651 if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */
9652 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9653 SiS_Pr->SiS_DDC_Index,
9654 SiS_Pr->SiS_DDC_NData,
9655 0x00); /* SD->low */
9656 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */
9657 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9658 SiS_Pr->SiS_DDC_Index,
9659 SiS_Pr->SiS_DDC_NData,
9660 SiS_Pr->SiS_DDC_Data); /* SD->high = stop condition */
9661 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->high) */
9662 return 0;
9663}
9664
9665/* Write 8 bits of data */
9666static unsigned short
9667SiS_WriteDDC2Data(struct SiS_Private *SiS_Pr, unsigned short tempax)
9668{
9669 unsigned short i,flag,temp;
9670
9671 flag = 0x80;
9672 for(i = 0; i < 8; i++) {
9673 SiS_SetSCLKLow(SiS_Pr); /* SC->low */
9674 if(tempax & flag) {
9675 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9676 SiS_Pr->SiS_DDC_Index,
9677 SiS_Pr->SiS_DDC_NData,
9678 SiS_Pr->SiS_DDC_Data); /* Write bit (1) to SD */
9679 } else {
9680 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9681 SiS_Pr->SiS_DDC_Index,
9682 SiS_Pr->SiS_DDC_NData,
9683 0x00); /* Write bit (0) to SD */
9684 }
9685 SiS_SetSCLKHigh(SiS_Pr); /* SC->high */
9686 flag >>= 1;
9687 }
9688 temp = SiS_CheckACK(SiS_Pr); /* Check acknowledge */
9689 return temp;
9690}
9691
9692static unsigned short
9693SiS_ReadDDC2Data(struct SiS_Private *SiS_Pr)
9694{
9695 unsigned short i, temp, getdata;
9696
9697 getdata = 0;
9698 for(i = 0; i < 8; i++) {
9699 getdata <<= 1;
9700 SiS_SetSCLKLow(SiS_Pr);
9701 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9702 SiS_Pr->SiS_DDC_Index,
9703 SiS_Pr->SiS_DDC_NData,
9704 SiS_Pr->SiS_DDC_Data);
9705 SiS_SetSCLKHigh(SiS_Pr);
9706 temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
9707 if(temp & SiS_Pr->SiS_DDC_Data) getdata |= 0x01;
9708 }
9709 return getdata;
9710}
9711
9712static unsigned short
9713SiS_SetSCLKLow(struct SiS_Private *SiS_Pr)
9714{
9715 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9716 SiS_Pr->SiS_DDC_Index,
9717 SiS_Pr->SiS_DDC_NClk,
9718 0x00); /* SetSCLKLow() */
9719 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9720 return 0;
9721}
9722
9723static unsigned short
9724SiS_SetSCLKHigh(struct SiS_Private *SiS_Pr)
9725{
9726 unsigned short temp, watchdog=1000;
9727
9728 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9729 SiS_Pr->SiS_DDC_Index,
9730 SiS_Pr->SiS_DDC_NClk,
9731 SiS_Pr->SiS_DDC_Clk); /* SetSCLKHigh() */
9732 do {
9733 temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
9734 } while((!(temp & SiS_Pr->SiS_DDC_Clk)) && --watchdog);
9735 if (!watchdog) {
9736 return 0xFFFF;
9737 }
9738 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9739 return 0;
9740}
9741
9742/* Check I2C acknowledge */
9743/* Returns 0 if ack ok, non-0 if ack not ok */
9744static unsigned short
9745SiS_CheckACK(struct SiS_Private *SiS_Pr)
9746{
9747 unsigned short tempah;
9748
9749 SiS_SetSCLKLow(SiS_Pr); /* (SC->low) */
9750 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9751 SiS_Pr->SiS_DDC_Index,
9752 SiS_Pr->SiS_DDC_NData,
9753 SiS_Pr->SiS_DDC_Data); /* (SD->high) */
9754 SiS_SetSCLKHigh(SiS_Pr); /* SC->high = clock impulse for ack */
9755 tempah = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); /* Read SD */
9756 SiS_SetSCLKLow(SiS_Pr); /* SC->low = end of clock impulse */
9757 if(tempah & SiS_Pr->SiS_DDC_Data) return 1; /* Ack OK if bit = 0 */
9758 return 0;
9759}
9760
9761/* End of I2C functions ----------------------- */
9762
9763
9764/* =============== SiS 315/330 O.E.M. ================= */
9765
9766#ifdef CONFIG_FB_SIS_315
9767
9768static unsigned short
9769GetRAMDACromptr(struct SiS_Private *SiS_Pr)
9770{
9771 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9772 unsigned short romptr;
9773
9774 if(SiS_Pr->ChipType < SIS_330) {
9775 romptr = SISGETROMW(0x128);
9776 if(SiS_Pr->SiS_VBType & VB_SIS30xB)
9777 romptr = SISGETROMW(0x12a);
9778 } else {
9779 romptr = SISGETROMW(0x1a8);
9780 if(SiS_Pr->SiS_VBType & VB_SIS30xB)
9781 romptr = SISGETROMW(0x1aa);
9782 }
9783 return romptr;
9784}
9785
9786static unsigned short
9787GetLCDromptr(struct SiS_Private *SiS_Pr)
9788{
9789 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9790 unsigned short romptr;
9791
9792 if(SiS_Pr->ChipType < SIS_330) {
9793 romptr = SISGETROMW(0x120);
9794 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9795 romptr = SISGETROMW(0x122);
9796 } else {
9797 romptr = SISGETROMW(0x1a0);
9798 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9799 romptr = SISGETROMW(0x1a2);
9800 }
9801 return romptr;
9802}
9803
9804static unsigned short
9805GetTVromptr(struct SiS_Private *SiS_Pr)
9806{
9807 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9808 unsigned short romptr;
9809
9810 if(SiS_Pr->ChipType < SIS_330) {
9811 romptr = SISGETROMW(0x114);
9812 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9813 romptr = SISGETROMW(0x11a);
9814 } else {
9815 romptr = SISGETROMW(0x194);
9816 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
9817 romptr = SISGETROMW(0x19a);
9818 }
9819 return romptr;
9820}
9821
9822static unsigned short
9823GetLCDPtrIndexBIOS(struct SiS_Private *SiS_Pr)
9824{
9825 unsigned short index;
9826
9827 if((IS_SIS650) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
9828 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
9829 if((index = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0)) {
9830 index >>= 4;
9831 index *= 3;
9832 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9833 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9834 return index;
9835 }
9836 }
9837 }
9838
9839 index = SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F;
9840 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) index -= 5;
9841 if(SiS_Pr->SiS_VBType & VB_SIS301C) { /* 1.15.20 and later (not VB specific) */
9842 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 5;
9843 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768) index -= 5;
9844 } else {
9845 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 6;
9846 }
9847 index--;
9848 index *= 3;
9849 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9850 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9851 return index;
9852}
9853
9854static unsigned short
9855GetLCDPtrIndex(struct SiS_Private *SiS_Pr)
9856{
9857 unsigned short index;
9858
9859 index = ((SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F) - 1) * 3;
9860 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
9861 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
9862 return index;
9863}
9864
9865static unsigned short
9866GetTVPtrIndex(struct SiS_Private *SiS_Pr)
9867{
9868 unsigned short index;
9869
9870 index = 0;
9871 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
9872 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index = 2;
9873
9874 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) index = 0;
9875
9876 index <<= 1;
9877
9878 if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) &&
9879 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
9880 index++;
9881 }
9882
9883 return index;
9884}
9885
9886static unsigned int
9887GetOEMTVPtr661_2_GEN(struct SiS_Private *SiS_Pr, int addme)
9888{
9889 unsigned short index = 0, temp = 0;
9890
9891 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
9892 if(SiS_Pr->SiS_TVMode & TVSetPALM) index = 2;
9893 if(SiS_Pr->SiS_TVMode & TVSetPALN) index = 3;
9894 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 6;
9895 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
9896 index = 4;
9897 if(SiS_Pr->SiS_TVMode & TVSetPALM) index++;
9898 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 7;
9899 }
9900
9901 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
9902 if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
9903 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
9904 index += addme;
9905 temp++;
9906 }
9907 temp += 0x0100;
9908 }
9909 return (unsigned int)(index | (temp << 16));
9910}
9911
9912static unsigned int
9913GetOEMTVPtr661_2_OLD(struct SiS_Private *SiS_Pr)
9914{
9915 return (GetOEMTVPtr661_2_GEN(SiS_Pr, addme: 8));
9916}
9917
9918#if 0
9919static unsigned int
9920GetOEMTVPtr661_2_NEW(struct SiS_Private *SiS_Pr)
9921{
9922 return (GetOEMTVPtr661_2_GEN(SiS_Pr, 6));
9923}
9924#endif
9925
9926static int
9927GetOEMTVPtr661(struct SiS_Private *SiS_Pr)
9928{
9929 int index = 0;
9930
9931 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 2;
9932 if(SiS_Pr->SiS_ROMNew) {
9933 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 4;
9934 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 6;
9935 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 8;
9936 if(SiS_Pr->SiS_TVMode & TVSetHiVision) index = 10;
9937 } else {
9938 if(SiS_Pr->SiS_TVMode & TVSetHiVision) index = 4;
9939 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 6;
9940 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 8;
9941 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 10;
9942 }
9943
9944 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) index++;
9945
9946 return index;
9947}
9948
9949static void
9950SetDelayComp(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
9951{
9952 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
9953 unsigned short delay=0,index,myindex,temp,romptr=0;
9954 bool dochiptest = true;
9955
9956 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
9957 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x20,0xbf);
9958 } else {
9959 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x35,0x7f);
9960 }
9961
9962 /* Find delay (from ROM, internal tables, PCI subsystem) */
9963
9964 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) { /* ------------ VGA */
9965
9966 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
9967 romptr = GetRAMDACromptr(SiS_Pr);
9968 }
9969 if(romptr) delay = ROMAddr[romptr];
9970 else {
9971 delay = 0x04;
9972 if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
9973 if(IS_SIS650) {
9974 delay = 0x0a;
9975 } else if(IS_SIS740) {
9976 delay = 0x00;
9977 } else {
9978 delay = 0x0c;
9979 }
9980 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
9981 delay = 0x00;
9982 }
9983 }
9984
9985 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD|SetCRT2ToLCDA)) { /* ---------- LCD/LCDA */
9986
9987 bool gotitfrompci = false;
9988
9989 /* Could we detect a PDC for LCD or did we get a user-defined? If yes, use it */
9990
9991 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
9992 if(SiS_Pr->PDC != -1) {
9993 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((SiS_Pr->PDC >> 1) & 0x0f));
9994 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((SiS_Pr->PDC & 0x01) << 7));
9995 return;
9996 }
9997 } else {
9998 if(SiS_Pr->PDCA != -1) {
9999 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((SiS_Pr->PDCA << 3) & 0xf0));
10000 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((SiS_Pr->PDCA & 0x01) << 6));
10001 return;
10002 }
10003 }
10004
10005 /* Custom Panel? */
10006
10007 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) {
10008 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10009 delay = 0x00;
10010 if((SiS_Pr->PanelXRes <= 1280) && (SiS_Pr->PanelYRes <= 1024)) {
10011 delay = 0x20;
10012 }
10013 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,delay);
10014 } else {
10015 delay = 0x0c;
10016 if(SiS_Pr->SiS_VBType & VB_SIS301C) {
10017 delay = 0x03;
10018 if((SiS_Pr->PanelXRes > 1280) && (SiS_Pr->PanelYRes > 1024)) {
10019 delay = 0x00;
10020 }
10021 } else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10022 if(IS_SIS740) delay = 0x01;
10023 else delay = 0x03;
10024 }
10025 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,delay);
10026 }
10027 return;
10028 }
10029
10030 /* This is a piece of typical SiS crap: They code the OEM LCD
10031 * delay into the code, at no defined place in the BIOS.
10032 * We now have to start doing a PCI subsystem check here.
10033 */
10034
10035 switch(SiS_Pr->SiS_CustomT) {
10036 case CUT_COMPAQ1280:
10037 case CUT_COMPAQ12802:
10038 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
10039 gotitfrompci = true;
10040 dochiptest = false;
10041 delay = 0x03;
10042 }
10043 break;
10044 case CUT_CLEVO1400:
10045 case CUT_CLEVO14002:
10046 gotitfrompci = true;
10047 dochiptest = false;
10048 delay = 0x02;
10049 break;
10050 case CUT_CLEVO1024:
10051 case CUT_CLEVO10242:
10052 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10053 gotitfrompci = true;
10054 dochiptest = false;
10055 delay = 0x33;
10056 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
10057 delay &= 0x0f;
10058 }
10059 break;
10060 }
10061
10062 /* Could we find it through the PCI ID? If no, use ROM or table */
10063
10064 if(!gotitfrompci) {
10065
10066 index = GetLCDPtrIndexBIOS(SiS_Pr);
10067 myindex = GetLCDPtrIndex(SiS_Pr);
10068
10069 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
10070
10071 if(SiS_IsNotM650orLater(SiS_Pr)) {
10072
10073 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10074 /* Always use the second pointer on 650; some BIOSes */
10075 /* still carry old 301 data at the first location */
10076 /* romptr = SISGETROMW(0x120); */
10077 /* if(SiS_Pr->SiS_VBType & VB_SIS302LV) */
10078 romptr = SISGETROMW(0x122);
10079 if(!romptr) return;
10080 delay = ROMAddr[(romptr + index)];
10081 } else {
10082 delay = SiS310_LCDDelayCompensation_650301LV[myindex];
10083 }
10084
10085 } else {
10086
10087 delay = SiS310_LCDDelayCompensation_651301LV[myindex];
10088 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV))
10089 delay = SiS310_LCDDelayCompensation_651302LV[myindex];
10090
10091 }
10092
10093 } else if(SiS_Pr->SiS_UseROM &&
10094 (!(SiS_Pr->SiS_ROMNew)) &&
10095 (SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) &&
10096 (SiS_Pr->SiS_LCDResInfo != Panel_1280x768) &&
10097 (SiS_Pr->SiS_LCDResInfo != Panel_1280x960) &&
10098 (SiS_Pr->SiS_LCDResInfo != Panel_1600x1200) &&
10099 ((romptr = GetLCDromptr(SiS_Pr)))) {
10100
10101 /* Data for 1280x1024 wrong in 301B BIOS */
10102 /* Data for 1600x1200 wrong in 301C BIOS */
10103 delay = ROMAddr[(romptr + index)];
10104
10105 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
10106
10107 if(IS_SIS740) delay = 0x03;
10108 else delay = 0x00;
10109
10110 } else {
10111
10112 delay = SiS310_LCDDelayCompensation_301[myindex];
10113 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10114 if(IS_SIS740) delay = 0x01;
10115 else if(SiS_Pr->ChipType <= SIS_315PRO) delay = SiS310_LCDDelayCompensation_3xx301LV[myindex];
10116 else delay = SiS310_LCDDelayCompensation_650301LV[myindex];
10117 } else if(SiS_Pr->SiS_VBType & VB_SIS301C) {
10118 if(IS_SIS740) delay = 0x01; /* ? */
10119 else delay = 0x03;
10120 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) delay = 0x00; /* experience */
10121 } else if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
10122 if(IS_SIS740) delay = 0x01;
10123 else delay = SiS310_LCDDelayCompensation_3xx301B[myindex];
10124 }
10125
10126 }
10127
10128 } /* got it from PCI */
10129
10130 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10131 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,((delay << 4) & 0xf0));
10132 dochiptest = false;
10133 }
10134
10135 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* ------------ TV */
10136
10137 index = GetTVPtrIndex(SiS_Pr);
10138
10139 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
10140
10141 if(SiS_IsNotM650orLater(SiS_Pr)) {
10142
10143 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10144 /* Always use the second pointer on 650; some BIOSes */
10145 /* still carry old 301 data at the first location */
10146 /* romptr = SISGETROMW(0x114); */
10147 /* if(SiS_Pr->SiS_VBType & VB_SIS302LV) */
10148 romptr = SISGETROMW(0x11a);
10149 if(!romptr) return;
10150 delay = ROMAddr[romptr + index];
10151
10152 } else {
10153
10154 delay = SiS310_TVDelayCompensation_301B[index];
10155
10156 }
10157
10158 } else {
10159
10160 switch(SiS_Pr->SiS_CustomT) {
10161 case CUT_COMPAQ1280:
10162 case CUT_COMPAQ12802:
10163 case CUT_CLEVO1400:
10164 case CUT_CLEVO14002:
10165 delay = 0x02;
10166 dochiptest = false;
10167 break;
10168 case CUT_CLEVO1024:
10169 case CUT_CLEVO10242:
10170 delay = 0x03;
10171 dochiptest = false;
10172 break;
10173 default:
10174 delay = SiS310_TVDelayCompensation_651301LV[index];
10175 if(SiS_Pr->SiS_VBType & VB_SIS302LV) {
10176 delay = SiS310_TVDelayCompensation_651302LV[index];
10177 }
10178 }
10179 }
10180
10181 } else if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10182
10183 romptr = GetTVromptr(SiS_Pr);
10184 if(!romptr) return;
10185 delay = ROMAddr[romptr + index];
10186
10187 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
10188
10189 delay = SiS310_TVDelayCompensation_LVDS[index];
10190
10191 } else {
10192
10193 delay = SiS310_TVDelayCompensation_301[index];
10194 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10195 if(IS_SIS740) {
10196 delay = SiS310_TVDelayCompensation_740301B[index];
10197 /* LV: use 301 data? BIOS bug? */
10198 } else {
10199 delay = SiS310_TVDelayCompensation_301B[index];
10200 if(SiS_Pr->SiS_VBType & VB_SIS301C) delay = 0x02;
10201 }
10202 }
10203
10204 }
10205
10206 if(SiS_LCDAEnabled(SiS_Pr)) {
10207 delay &= 0x0f;
10208 dochiptest = false;
10209 }
10210
10211 } else return;
10212
10213 /* Write delay */
10214
10215 if(SiS_Pr->SiS_VBType & VB_SISVB) {
10216
10217 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS) && dochiptest) {
10218
10219 temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0) >> 4;
10220 if(temp == 8) { /* 1400x1050 BIOS (COMPAL) */
10221 delay &= 0x0f;
10222 delay |= 0xb0;
10223 } else if(temp == 6) {
10224 delay &= 0x0f;
10225 delay |= 0xc0;
10226 } else if(temp > 7) { /* 1280x1024 BIOS (which one?) */
10227 delay = 0x35;
10228 }
10229 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
10230
10231 } else {
10232
10233 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
10234
10235 }
10236
10237 } else { /* LVDS */
10238
10239 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10240 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
10241 } else {
10242 if(IS_SIS650 && (SiS_Pr->SiS_IF_DEF_CH70xx != 0)) {
10243 delay <<= 4;
10244 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,delay);
10245 } else {
10246 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
10247 }
10248 }
10249
10250 }
10251
10252}
10253
10254static void
10255SetAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10256{
10257 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10258 unsigned short index,temp,temp1,romptr=0;
10259
10260 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p|TVSetYPbPr525p)) return;
10261
10262 if(ModeNo<=0x13)
10263 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex;
10264 else
10265 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex;
10266
10267 temp = GetTVPtrIndex(SiS_Pr);
10268 temp >>= 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10269 temp1 = temp;
10270
10271 if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
10272 if(SiS_Pr->ChipType >= SIS_661) {
10273 temp1 = GetOEMTVPtr661(SiS_Pr);
10274 temp1 >>= 1;
10275 romptr = SISGETROMW(0x260);
10276 if(SiS_Pr->ChipType >= SIS_760) {
10277 romptr = SISGETROMW(0x360);
10278 }
10279 } else if(SiS_Pr->ChipType >= SIS_330) {
10280 romptr = SISGETROMW(0x192);
10281 } else {
10282 romptr = SISGETROMW(0x112);
10283 }
10284 }
10285
10286 if(romptr) {
10287 temp1 <<= 1;
10288 temp = ROMAddr[romptr + temp1 + index];
10289 } else {
10290 temp = SiS310_TVAntiFlick1[temp][index];
10291 }
10292 temp <<= 4;
10293
10294 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8f,temp); /* index 0A D[6:4] */
10295}
10296
10297static void
10298SetEdgeEnhance(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10299{
10300 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10301 unsigned short index,temp,temp1,romptr=0;
10302
10303 temp = temp1 = GetTVPtrIndex(SiS_Pr) >> 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10304
10305 if(ModeNo <= 0x13)
10306 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;
10307 else
10308 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;
10309
10310 if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
10311 if(SiS_Pr->ChipType >= SIS_661) {
10312 romptr = SISGETROMW(0x26c);
10313 if(SiS_Pr->ChipType >= SIS_760) {
10314 romptr = SISGETROMW(0x36c);
10315 }
10316 temp1 = GetOEMTVPtr661(SiS_Pr);
10317 temp1 >>= 1;
10318 } else if(SiS_Pr->ChipType >= SIS_330) {
10319 romptr = SISGETROMW(0x1a4);
10320 } else {
10321 romptr = SISGETROMW(0x124);
10322 }
10323 }
10324
10325 if(romptr) {
10326 temp1 <<= 1;
10327 temp = ROMAddr[romptr + temp1 + index];
10328 } else {
10329 temp = SiS310_TVEdge1[temp][index];
10330 }
10331 temp <<= 5;
10332 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x3A,0x1F,temp); /* index 0A D[7:5] */
10333}
10334
10335static void
10336SetYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
10337{
10338 unsigned short index, temp, i, j;
10339
10340 if(ModeNo <= 0x13) {
10341 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
10342 } else {
10343 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
10344 }
10345
10346 temp = GetTVPtrIndex(SiS_Pr) >> 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
10347
10348 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp = 1; /* NTSC-J uses PAL */
10349 else if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 3; /* PAL-M */
10350 else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 4; /* PAL-N */
10351 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp = 1; /* HiVision uses PAL */
10352
10353 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10354 for(i=0x35, j=0; i<=0x38; i++, j++) {
10355 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
10356 }
10357 for(i=0x48; i<=0x4A; i++, j++) {
10358 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
10359 }
10360 } else {
10361 for(i=0x35, j=0; i<=0x38; i++, j++) {
10362 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter1[temp][index][j]);
10363 }
10364 }
10365}
10366
10367static void
10368SetPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10369{
10370 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10371 unsigned short index,temp,i,j,resinfo,romptr=0;
10372 unsigned int lindex;
10373
10374 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
10375
10376 /* NTSC-J data not in BIOS, and already set in SetGroup2 */
10377 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) return;
10378
10379 if((SiS_Pr->ChipType >= SIS_661) || SiS_Pr->SiS_ROMNew) {
10380 lindex = GetOEMTVPtr661_2_OLD(SiS_Pr) & 0xffff;
10381 lindex <<= 2;
10382 for(j=0, i=0x31; i<=0x34; i++, j++) {
10383 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[lindex + j]);
10384 }
10385 return;
10386 }
10387
10388 /* PAL-M, PAL-N not in BIOS, and already set in SetGroup2 */
10389 if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) return;
10390
10391 if(ModeNo<=0x13) {
10392 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
10393 } else {
10394 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
10395 }
10396
10397 temp = GetTVPtrIndex(SiS_Pr);
10398 /* 0: NTSC Graphics, 1: NTSC Text, 2: PAL Graphics,
10399 * 3: PAL Text, 4: HiTV Graphics 5: HiTV Text
10400 */
10401 if(SiS_Pr->SiS_UseROM) {
10402 romptr = SISGETROMW(0x116);
10403 if(SiS_Pr->ChipType >= SIS_330) {
10404 romptr = SISGETROMW(0x196);
10405 }
10406 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10407 romptr = SISGETROMW(0x11c);
10408 if(SiS_Pr->ChipType >= SIS_330) {
10409 romptr = SISGETROMW(0x19c);
10410 }
10411 if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode))) {
10412 romptr = SISGETROMW(0x116);
10413 if(SiS_Pr->ChipType >= SIS_330) {
10414 romptr = SISGETROMW(0x196);
10415 }
10416 }
10417 }
10418 }
10419 if(romptr) {
10420 romptr += (temp << 2);
10421 for(j=0, i=0x31; i<=0x34; i++, j++) {
10422 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
10423 }
10424 } else {
10425 index = temp % 2;
10426 temp >>= 1; /* 0:NTSC, 1:PAL, 2:HiTV */
10427 for(j=0, i=0x31; i<=0x34; i++, j++) {
10428 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV))
10429 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
10430 else if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || (SiS_Pr->SiS_TVMode & TVSetTVSimuMode))
10431 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr2[temp][index][j]);
10432 else
10433 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
10434 }
10435 }
10436
10437 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision))) {
10438 if((!(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetYPbPr525p | TVSetYPbPr750p))) && (ModeNo > 0x13)) {
10439 if((resinfo == SIS_RI_640x480) ||
10440 (resinfo == SIS_RI_800x600)) {
10441 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x21);
10442 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0xf0);
10443 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xf5);
10444 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7f);
10445 } else if(resinfo == SIS_RI_1024x768) {
10446 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x1e);
10447 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0x8b);
10448 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xfb);
10449 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7b);
10450 }
10451 }
10452 }
10453}
10454
10455static void
10456SetDelayComp661(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
10457 unsigned short ModeIdIndex, unsigned short RTI)
10458{
10459 unsigned short delay = 0, romptr = 0, index, lcdpdcindex;
10460 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10461
10462 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToRAMDAC)))
10463 return;
10464
10465 /* 1. New ROM: VGA2 and LCD/LCDA-Pass1:1 */
10466 /* (If a custom mode is used, Pass1:1 is always set; hence we do this:) */
10467
10468 if(SiS_Pr->SiS_ROMNew) {
10469 if((SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) ||
10470 ((SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
10471 (SiS_Pr->SiS_LCDInfo & LCDPass11))) {
10472 index = 25;
10473 if(SiS_Pr->UseCustomMode) {
10474 index = SiS_Pr->CSRClock;
10475 } else if(ModeNo > 0x13) {
10476 index = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex: RTI);
10477 index = SiS_Pr->SiS_VCLKData[index].CLOCK;
10478 }
10479 if(index < 25) index = 25;
10480 index = ((index / 25) - 1) << 1;
10481 if((ROMAddr[0x5b] & 0x80) || (SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD))) {
10482 index++;
10483 }
10484 romptr = SISGETROMW(0x104);
10485 delay = ROMAddr[romptr + index];
10486 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD)) {
10487 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
10488 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
10489 } else {
10490 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
10491 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
10492 }
10493 return;
10494 }
10495 }
10496
10497 /* 2. Old ROM: VGA2 and LCD/LCDA-Pass 1:1 */
10498
10499 if(SiS_Pr->UseCustomMode) delay = 0x04;
10500 else if(ModeNo <= 0x13) delay = 0x04;
10501 else delay = (SiS_Pr->SiS_RefIndex[RTI].Ext_PDC >> 4);
10502 delay |= (delay << 8);
10503
10504 if(SiS_Pr->ChipType >= XGI_20) {
10505
10506 delay = 0x0606;
10507 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10508
10509 delay = 0x0404;
10510 if(SiS_Pr->SiS_XGIROM) {
10511 index = GetTVPtrIndex(SiS_Pr);
10512 if((romptr = SISGETROMW(0x35e))) {
10513 delay = (ROMAddr[romptr + index] & 0x0f) << 1;
10514 delay |= (delay << 8);
10515 }
10516 }
10517
10518 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
10519 if(SiS_Pr->ChipType == XGI_40 && SiS_Pr->ChipRevision == 0x02) {
10520 delay -= 0x0404;
10521 }
10522 }
10523 }
10524
10525 } else if(SiS_Pr->ChipType >= SIS_340) {
10526
10527 delay = 0x0606;
10528 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10529 delay = 0x0404;
10530 }
10531 /* TODO (eventually) */
10532
10533 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10534
10535 /* 3. TV */
10536
10537 index = GetOEMTVPtr661(SiS_Pr);
10538 if(SiS_Pr->SiS_ROMNew) {
10539 romptr = SISGETROMW(0x106);
10540 if(SiS_Pr->SiS_VBType & VB_UMC) romptr += 12;
10541 delay = ROMAddr[romptr + index];
10542 } else {
10543 delay = 0x04;
10544 if(index > 3) delay = 0;
10545 }
10546
10547 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10548
10549 /* 4. LCD, LCDA (for new ROM only LV and non-Pass 1:1) */
10550
10551 if( (SiS_Pr->SiS_LCDResInfo != Panel_Custom) &&
10552 ((romptr = GetLCDStructPtr661_2(SiS_Pr))) ) {
10553
10554 lcdpdcindex = (SiS_Pr->SiS_VBType & VB_UMC) ? 14 : 12;
10555
10556 /* For LVDS (and sometimes TMDS), the BIOS must know about the correct value */
10557 delay = ROMAddr[romptr + lcdpdcindex + 1]; /* LCD */
10558 delay |= (ROMAddr[romptr + lcdpdcindex] << 8); /* LCDA */
10559
10560 } else {
10561
10562 /* TMDS: Set our own, since BIOS has no idea */
10563 /* (This is done on >=661 only, since <661 is calling this only for LVDS) */
10564 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
10565 switch(SiS_Pr->SiS_LCDResInfo) {
10566 case Panel_1024x768: delay = 0x0008; break;
10567 case Panel_1280x720: delay = 0x0004; break;
10568 case Panel_1280x768:
10569 case Panel_1280x768_2:delay = 0x0004; break;
10570 case Panel_1280x800:
10571 case Panel_1280x800_2:delay = 0x0004; break; /* Verified for 1280x800 */
10572 case Panel_1280x854: delay = 0x0004; break; /* FIXME */
10573 case Panel_1280x1024: delay = 0x1e04; break;
10574 case Panel_1400x1050: delay = 0x0004; break;
10575 case Panel_1600x1200: delay = 0x0400; break;
10576 case Panel_1680x1050: delay = 0x0e04; break;
10577 default:
10578 if((SiS_Pr->PanelXRes <= 1024) && (SiS_Pr->PanelYRes <= 768)) {
10579 delay = 0x0008;
10580 } else if((SiS_Pr->PanelXRes == 1280) && (SiS_Pr->PanelYRes == 1024)) {
10581 delay = 0x1e04;
10582 } else if((SiS_Pr->PanelXRes <= 1400) && (SiS_Pr->PanelYRes <= 1050)) {
10583 delay = 0x0004;
10584 } else if((SiS_Pr->PanelXRes <= 1600) && (SiS_Pr->PanelYRes <= 1200)) {
10585 delay = 0x0400;
10586 } else
10587 delay = 0x0e04;
10588 break;
10589 }
10590 }
10591
10592 /* Override by detected or user-set values */
10593 /* (but only if, for some reason, we can't read value from BIOS) */
10594 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->PDC != -1)) {
10595 delay = SiS_Pr->PDC & 0x1f;
10596 }
10597 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) && (SiS_Pr->PDCA != -1)) {
10598 delay = (SiS_Pr->PDCA & 0x1f) << 8;
10599 }
10600
10601 }
10602
10603 }
10604
10605 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10606 delay >>= 8;
10607 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
10608 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
10609 } else {
10610 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
10611 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
10612 }
10613}
10614
10615static void
10616SetCRT2SyncDither661(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RTI)
10617{
10618 unsigned short infoflag;
10619 unsigned char temp;
10620
10621 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10622
10623 if(ModeNo <= 0x13) {
10624 infoflag = SiS_GetRegByte(SiS_Pr->SiS_P3ca+2);
10625 } else if(SiS_Pr->UseCustomMode) {
10626 infoflag = SiS_Pr->CInfoFlag;
10627 } else {
10628 infoflag = SiS_Pr->SiS_RefIndex[RTI].Ext_InfoFlag;
10629 }
10630
10631 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
10632 infoflag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37); /* No longer check D5 */
10633 }
10634
10635 infoflag &= 0xc0;
10636
10637 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
10638 temp = (infoflag >> 6) | 0x0c;
10639 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
10640 temp ^= 0x04;
10641 if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x10;
10642 }
10643 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xe0,temp);
10644 } else {
10645 temp = 0x30;
10646 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) temp = 0x20;
10647 temp |= infoflag;
10648 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0f,temp);
10649 temp = 0;
10650 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
10651 if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x80;
10652 }
10653 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0x7f,temp);
10654 }
10655
10656 }
10657}
10658
10659static void
10660SetPanelParms661(struct SiS_Private *SiS_Pr)
10661{
10662 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10663 unsigned short romptr, temp1, temp2;
10664
10665 if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_SIS30xC)) {
10666 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x24,0x0f);
10667 }
10668
10669 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10670 if(SiS_Pr->LVDSHL != -1) {
10671 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
10672 }
10673 }
10674
10675 if(SiS_Pr->SiS_ROMNew) {
10676
10677 if((romptr = GetLCDStructPtr661_2(SiS_Pr))) {
10678 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10679 temp1 = (ROMAddr[romptr] & 0x03) | 0x0c;
10680 temp2 = 0xfc;
10681 if(SiS_Pr->LVDSHL != -1) {
10682 temp1 &= 0xfc;
10683 temp2 = 0xf3;
10684 }
10685 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,temp2,temp1);
10686 }
10687 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
10688 temp1 = (ROMAddr[romptr + 1] & 0x80) >> 1;
10689 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0d,0xbf,temp1);
10690 }
10691 }
10692
10693 }
10694}
10695
10696static void
10697SiS_OEM310Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RRTI)
10698{
10699 if((SiS_Pr->SiS_ROMNew) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
10700 SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RTI: RRTI);
10701 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10702 SetCRT2SyncDither661(SiS_Pr, ModeNo, RTI: RRTI);
10703 SetPanelParms661(SiS_Pr);
10704 }
10705 } else {
10706 SetDelayComp(SiS_Pr,ModeNo);
10707 }
10708
10709 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
10710 SetAntiFlicker(SiS_Pr,ModeNo,ModeIdIndex);
10711 SetPhaseIncr(SiS_Pr,ModeNo,ModeIdIndex);
10712 SetYFilter(SiS_Pr,ModeNo,ModeIdIndex);
10713 if(SiS_Pr->SiS_VBType & VB_SIS301) {
10714 SetEdgeEnhance(SiS_Pr,ModeNo,ModeIdIndex);
10715 }
10716 }
10717}
10718
10719static void
10720SiS_OEM661Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
10721 unsigned short ModeIdIndex, unsigned short RRTI)
10722{
10723 if(SiS_Pr->SiS_VBType & VB_SISVB) {
10724
10725 SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RTI: RRTI);
10726
10727 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10728 SetCRT2SyncDither661(SiS_Pr, ModeNo, RTI: RRTI);
10729 SetPanelParms661(SiS_Pr);
10730 }
10731
10732 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10733 SetPhaseIncr(SiS_Pr, ModeNo, ModeIdIndex);
10734 SetYFilter(SiS_Pr, ModeNo, ModeIdIndex);
10735 SetAntiFlicker(SiS_Pr, ModeNo, ModeIdIndex);
10736 if(SiS_Pr->SiS_VBType & VB_SIS301) {
10737 SetEdgeEnhance(SiS_Pr, ModeNo, ModeIdIndex);
10738 }
10739 }
10740 }
10741}
10742
10743/* FinalizeLCD
10744 * This finalizes some CRT2 registers for the very panel used.
10745 * If we have a backup if these registers, we use it; otherwise
10746 * we set the register according to most BIOSes. However, this
10747 * function looks quite different in every BIOS, so you better
10748 * pray that we have a backup...
10749 */
10750static void
10751SiS_FinalizeLCD(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
10752{
10753 unsigned short tempcl,tempch,tempbl,tempbh,tempbx,tempax,temp;
10754 unsigned short resinfo,modeflag;
10755
10756 if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) return;
10757 if(SiS_Pr->SiS_ROMNew) return;
10758
10759 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10760 if(SiS_Pr->LVDSHL != -1) {
10761 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
10762 }
10763 }
10764
10765 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
10766 if(SiS_Pr->UseCustomMode) return;
10767
10768 switch(SiS_Pr->SiS_CustomT) {
10769 case CUT_COMPAQ1280:
10770 case CUT_COMPAQ12802:
10771 case CUT_CLEVO1400:
10772 case CUT_CLEVO14002:
10773 return;
10774 }
10775
10776 if(ModeNo <= 0x13) {
10777 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
10778 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
10779 } else {
10780 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
10781 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
10782 }
10783
10784 if(IS_SIS650) {
10785 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4, 0x5f) & 0xf0)) {
10786 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
10787 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x02);
10788 } else {
10789 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
10790 }
10791 }
10792 }
10793
10794 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
10795 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10796 /* Maybe all panels? */
10797 if(SiS_Pr->LVDSHL == -1) {
10798 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10799 }
10800 return;
10801 }
10802 }
10803
10804 if(SiS_Pr->SiS_CustomT == CUT_CLEVO10242) {
10805 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10806 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10807 if(SiS_Pr->LVDSHL == -1) {
10808 /* Maybe all panels? */
10809 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10810 }
10811 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10812 tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
10813 if(tempch == 3) {
10814 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10815 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
10816 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
10817 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
10818 }
10819 }
10820 return;
10821 }
10822 }
10823 }
10824
10825 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
10826 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10827 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
10828 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
10829#ifdef SET_EMI
10830 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
10831#endif
10832 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
10833 }
10834 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
10835 if(SiS_Pr->LVDSHL == -1) {
10836 /* Maybe ACER only? */
10837 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
10838 }
10839 }
10840 tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
10841 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10842 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
10843 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1f,0x76);
10844 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10845 if(tempch == 0x03) {
10846 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10847 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
10848 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
10849 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
10850 }
10851 if(SiS_Pr->Backup && (SiS_Pr->Backup_Mode == ModeNo)) {
10852 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,SiS_Pr->Backup_14);
10853 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,SiS_Pr->Backup_15);
10854 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,SiS_Pr->Backup_16);
10855 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,SiS_Pr->Backup_17);
10856 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,SiS_Pr->Backup_18);
10857 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,SiS_Pr->Backup_19);
10858 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,SiS_Pr->Backup_1a);
10859 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,SiS_Pr->Backup_1b);
10860 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,SiS_Pr->Backup_1c);
10861 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,SiS_Pr->Backup_1d);
10862 } else if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { /* 1.10.8w */
10863 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x90);
10864 if(ModeNo <= 0x13) {
10865 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x11);
10866 if((resinfo == 0) || (resinfo == 2)) return;
10867 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x18);
10868 if((resinfo == 1) || (resinfo == 3)) return;
10869 }
10870 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
10871 if((ModeNo > 0x13) && (resinfo == SIS_RI_1024x768)) {
10872 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02); /* 1.10.7u */
10873#if 0
10874 tempbx = 806; /* 0x326 */ /* other older BIOSes */
10875 tempbx--;
10876 temp = tempbx & 0xff;
10877 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);
10878 temp = (tempbx >> 8) & 0x03;
10879 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1d,0xf8,temp);
10880#endif
10881 }
10882 } else if(ModeNo <= 0x13) {
10883 if(ModeNo <= 1) {
10884 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x70);
10885 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xff);
10886 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
10887 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
10888 }
10889 if(!(modeflag & HalfDCLK)) {
10890 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x20);
10891 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,0x1a);
10892 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,0x28);
10893 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,0x00);
10894 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x4c);
10895 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
10896 if(ModeNo == 0x12) {
10897 switch(tempch) {
10898 case 0:
10899 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
10900 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
10901 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,0x10);
10902 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
10903 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x48);
10904 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
10905 break;
10906 case 2:
10907 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
10908 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
10909 break;
10910 case 3:
10911 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
10912 break;
10913 }
10914 }
10915 }
10916 }
10917 }
10918 } else {
10919 tempcl = tempbh = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
10920 tempcl &= 0x0f;
10921 tempbh &= 0x70;
10922 tempbh >>= 4;
10923 tempbl = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x04);
10924 tempbx = (tempbh << 8) | tempbl;
10925 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10926 if((resinfo == SIS_RI_1024x768) || (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD))) {
10927 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
10928 tempbx = 770;
10929 } else {
10930 if(tempbx > 770) tempbx = 770;
10931 if(SiS_Pr->SiS_VGAVDE < 600) {
10932 tempax = 768 - SiS_Pr->SiS_VGAVDE;
10933 tempax >>= 4; /* 1.10.7w; 1.10.6s: 3; */
10934 if(SiS_Pr->SiS_VGAVDE <= 480) tempax >>= 4; /* 1.10.7w; 1.10.6s: < 480; >>=1; */
10935 tempbx -= tempax;
10936 }
10937 }
10938 } else return;
10939 }
10940 temp = tempbx & 0xff;
10941 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,temp);
10942 temp = ((tempbx & 0xff00) >> 4) | tempcl;
10943 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,temp);
10944 }
10945 }
10946}
10947
10948#endif
10949
10950/* ================= SiS 300 O.E.M. ================== */
10951
10952#ifdef CONFIG_FB_SIS_300
10953
10954static void
10955SetOEMLCDData2(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,
10956 unsigned short RefTabIndex)
10957{
10958 unsigned short crt2crtc=0, modeflag, myindex=0;
10959 unsigned char temp;
10960 int i;
10961
10962 if(ModeNo <= 0x13) {
10963 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
10964 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
10965 } else {
10966 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
10967 crt2crtc = SiS_Pr->SiS_RefIndex[RefTabIndex].Ext_CRT2CRTC;
10968 }
10969
10970 crt2crtc &= 0x3f;
10971
10972 if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
10973 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xdf);
10974 }
10975
10976 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
10977 if(modeflag & HalfDCLK) myindex = 1;
10978
10979 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
10980 for(i=0; i<7; i++) {
10981 if(barco_p1[myindex][crt2crtc][i][0]) {
10982 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,
10983 barco_p1[myindex][crt2crtc][i][0],
10984 barco_p1[myindex][crt2crtc][i][2],
10985 barco_p1[myindex][crt2crtc][i][1]);
10986 }
10987 }
10988 }
10989 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
10990 if(temp & 0x80) {
10991 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x18);
10992 temp++;
10993 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);
10994 }
10995 }
10996}
10997
10998static unsigned short
10999GetOEMLCDPtr(struct SiS_Private *SiS_Pr, int Flag)
11000{
11001 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11002 unsigned short tempbx=0,romptr=0;
11003 static const unsigned char customtable300[] = {
11004 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
11005 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
11006 };
11007 static const unsigned char customtable630[] = {
11008 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
11009 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
11010 };
11011
11012 if(SiS_Pr->ChipType == SIS_300) {
11013
11014 tempbx = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0x0f;
11015 if(SiS_Pr->SiS_VBType & VB_SIS301) tempbx &= 0x07;
11016 tempbx -= 2;
11017 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 4;
11018 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11019 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 3;
11020 }
11021 if(SiS_Pr->SiS_UseROM) {
11022 if(ROMAddr[0x235] & 0x80) {
11023 tempbx = SiS_Pr->SiS_LCDTypeInfo;
11024 if(Flag) {
11025 romptr = SISGETROMW(0x255);
11026 if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
11027 else tempbx = customtable300[SiS_Pr->SiS_LCDTypeInfo];
11028 if(tempbx == 0xFF) return 0xFFFF;
11029 }
11030 tempbx <<= 1;
11031 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
11032 }
11033 }
11034
11035 } else {
11036
11037 if(Flag) {
11038 if(SiS_Pr->SiS_UseROM) {
11039 romptr = SISGETROMW(0x255);
11040 if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
11041 else tempbx = 0xff;
11042 } else {
11043 tempbx = customtable630[SiS_Pr->SiS_LCDTypeInfo];
11044 }
11045 if(tempbx == 0xFF) return 0xFFFF;
11046 tempbx <<= 2;
11047 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
11048 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
11049 return tempbx;
11050 }
11051 tempbx = SiS_Pr->SiS_LCDTypeInfo << 2;
11052 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
11053 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
11054
11055 }
11056
11057 return tempbx;
11058}
11059
11060static void
11061SetOEMLCDDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
11062{
11063 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11064 unsigned short index,temp,romptr=0;
11065
11066 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
11067
11068 if(SiS_Pr->SiS_UseROM) {
11069 if(!(ROMAddr[0x237] & 0x01)) return;
11070 if(!(ROMAddr[0x237] & 0x02)) return;
11071 romptr = SISGETROMW(0x24b);
11072 }
11073
11074 /* The Panel Compensation Delay should be set according to tables
11075 * here. Unfortunately, various BIOS versions don't care about
11076 * a uniform way using eg. ROM byte 0x220, but use different
11077 * hard coded delays (0x04, 0x20, 0x18) in SetGroup1().
11078 * Thus we don't set this if the user selected a custom pdc or if
11079 * we otherwise detected a valid pdc.
11080 */
11081 if(SiS_Pr->PDC != -1) return;
11082
11083 temp = GetOEMLCDPtr(SiS_Pr, Flag: 0);
11084
11085 if(SiS_Pr->UseCustomMode)
11086 index = 0;
11087 else
11088 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
11089
11090 if(SiS_Pr->ChipType != SIS_300) {
11091 if(romptr) {
11092 romptr += (temp * 2);
11093 romptr = SISGETROMW(romptr);
11094 romptr += index;
11095 temp = ROMAddr[romptr];
11096 } else {
11097 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11098 temp = SiS300_OEMLCDDelay2[temp][index];
11099 } else {
11100 temp = SiS300_OEMLCDDelay3[temp][index];
11101 }
11102 }
11103 } else {
11104 if(SiS_Pr->SiS_UseROM && (ROMAddr[0x235] & 0x80)) {
11105 if(romptr) {
11106 romptr += (temp * 2);
11107 romptr = SISGETROMW(romptr);
11108 romptr += index;
11109 temp = ROMAddr[romptr];
11110 } else {
11111 temp = SiS300_OEMLCDDelay5[temp][index];
11112 }
11113 } else {
11114 if(SiS_Pr->SiS_UseROM) {
11115 romptr = ROMAddr[0x249] | (ROMAddr[0x24a] << 8);
11116 if(romptr) {
11117 romptr += (temp * 2);
11118 romptr = SISGETROMW(romptr);
11119 romptr += index;
11120 temp = ROMAddr[romptr];
11121 } else {
11122 temp = SiS300_OEMLCDDelay4[temp][index];
11123 }
11124 } else {
11125 temp = SiS300_OEMLCDDelay4[temp][index];
11126 }
11127 }
11128 }
11129 temp &= 0x3c;
11130 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* index 0A D[6:4] */
11131}
11132
11133static void
11134SetOEMLCDData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11135{
11136#if 0 /* Unfinished; Data table missing */
11137 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11138 unsigned short index,temp;
11139
11140 if((SiS_Pr->SiS_UseROM) {
11141 if(!(ROMAddr[0x237] & 0x01)) return;
11142 if(!(ROMAddr[0x237] & 0x04)) return;
11143 /* No rom pointer in BIOS header! */
11144 }
11145
11146 temp = GetOEMLCDPtr(SiS_Pr, 1);
11147 if(temp == 0xFFFF) return;
11148
11149 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDHIndex;
11150 for(i=0x14, j=0; i<=0x17; i++, j++) {
11151 SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDHData[temp][index][j]);
11152 }
11153 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1a, 0xf8, (SiS300_LCDHData[temp][index][j] & 0x07));
11154
11155 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDVIndex;
11156 SiS_SetReg(SiS_SiS_Part1Port,0x18, SiS300_LCDVData[temp][index][0]);
11157 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x19, 0xF0, SiS300_LCDVData[temp][index][1]);
11158 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1A, 0xC7, (SiS300_LCDVData[temp][index][2] & 0x38));
11159 for(i=0x1b, j=3; i<=0x1d; i++, j++) {
11160 SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDVData[temp][index][j]);
11161 }
11162#endif
11163}
11164
11165static unsigned short
11166GetOEMTVPtr(struct SiS_Private *SiS_Pr)
11167{
11168 unsigned short index;
11169
11170 index = 0;
11171 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) index += 4;
11172 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11173 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) index += 2;
11174 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index += 3;
11175 else if(SiS_Pr->SiS_TVMode & TVSetPAL) index += 1;
11176 } else {
11177 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) index += 2;
11178 if(SiS_Pr->SiS_TVMode & TVSetPAL) index += 1;
11179 }
11180 return index;
11181}
11182
11183static void
11184SetOEMTVDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11185{
11186 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11187 unsigned short index,temp,romptr=0;
11188
11189 if(SiS_Pr->SiS_UseROM) {
11190 if(!(ROMAddr[0x238] & 0x01)) return;
11191 if(!(ROMAddr[0x238] & 0x02)) return;
11192 romptr = SISGETROMW(0x241);
11193 }
11194
11195 temp = GetOEMTVPtr(SiS_Pr);
11196
11197 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVDelayIndex;
11198
11199 if(romptr) {
11200 romptr += (temp * 2);
11201 romptr = SISGETROMW(romptr);
11202 romptr += index;
11203 temp = ROMAddr[romptr];
11204 } else {
11205 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11206 temp = SiS300_OEMTVDelay301[temp][index];
11207 } else {
11208 temp = SiS300_OEMTVDelayLVDS[temp][index];
11209 }
11210 }
11211 temp &= 0x3c;
11212 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);
11213}
11214
11215static void
11216SetOEMAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11217{
11218 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11219 unsigned short index,temp,romptr=0;
11220
11221 if(SiS_Pr->SiS_UseROM) {
11222 if(!(ROMAddr[0x238] & 0x01)) return;
11223 if(!(ROMAddr[0x238] & 0x04)) return;
11224 romptr = SISGETROMW(0x243);
11225 }
11226
11227 temp = GetOEMTVPtr(SiS_Pr);
11228
11229 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVFlickerIndex;
11230
11231 if(romptr) {
11232 romptr += (temp * 2);
11233 romptr = SISGETROMW(romptr);
11234 romptr += index;
11235 temp = ROMAddr[romptr];
11236 } else {
11237 temp = SiS300_OEMTVFlicker[temp][index];
11238 }
11239 temp &= 0x70;
11240 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8F,temp);
11241}
11242
11243static void
11244SetOEMPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
11245{
11246 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11247 unsigned short index,i,j,temp,romptr=0;
11248
11249 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) return;
11250
11251 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetNTSCJ | TVSetPALM | TVSetPALN)) return;
11252
11253 if(SiS_Pr->SiS_UseROM) {
11254 if(!(ROMAddr[0x238] & 0x01)) return;
11255 if(!(ROMAddr[0x238] & 0x08)) return;
11256 romptr = SISGETROMW(0x245);
11257 }
11258
11259 temp = GetOEMTVPtr(SiS_Pr);
11260
11261 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVPhaseIndex;
11262
11263 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
11264 for(i=0x31, j=0; i<=0x34; i++, j++) {
11265 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase2[temp][index][j]);
11266 }
11267 } else {
11268 if(romptr) {
11269 romptr += (temp * 2);
11270 romptr = SISGETROMW(romptr);
11271 romptr += (index * 4);
11272 for(i=0x31, j=0; i<=0x34; i++, j++) {
11273 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
11274 }
11275 } else {
11276 for(i=0x31, j=0; i<=0x34; i++, j++) {
11277 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase1[temp][index][j]);
11278 }
11279 }
11280 }
11281}
11282
11283static void
11284SetOEMYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11285{
11286 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11287 unsigned short index,temp,i,j,romptr=0;
11288
11289 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSCART | SetCRT2ToHiVision | SetCRT2ToYPbPr525750)) return;
11290
11291 if(SiS_Pr->SiS_UseROM) {
11292 if(!(ROMAddr[0x238] & 0x01)) return;
11293 if(!(ROMAddr[0x238] & 0x10)) return;
11294 romptr = SISGETROMW(0x247);
11295 }
11296
11297 temp = GetOEMTVPtr(SiS_Pr);
11298
11299 if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
11300 else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 9;
11301 /* NTSCJ uses NTSC filters */
11302
11303 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVYFilterIndex;
11304
11305 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
11306 for(i=0x35, j=0; i<=0x38; i++, j++) {
11307 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
11308 }
11309 for(i=0x48; i<=0x4A; i++, j++) {
11310 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
11311 }
11312 } else {
11313 if((romptr) && (!(SiS_Pr->SiS_TVMode & (TVSetPALM|TVSetPALN)))) {
11314 romptr += (temp * 2);
11315 romptr = SISGETROMW(romptr);
11316 romptr += (index * 4);
11317 for(i=0x35, j=0; i<=0x38; i++, j++) {
11318 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
11319 }
11320 } else {
11321 for(i=0x35, j=0; i<=0x38; i++, j++) {
11322 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter1[temp][index][j]);
11323 }
11324 }
11325 }
11326}
11327
11328static unsigned short
11329SiS_SearchVBModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo)
11330{
11331 unsigned short ModeIdIndex;
11332 unsigned char VGAINFO = SiS_Pr->SiS_VGAINFO;
11333
11334 if(*ModeNo <= 5) *ModeNo |= 1;
11335
11336 for(ModeIdIndex=0; ; ModeIdIndex++) {
11337 if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == *ModeNo) break;
11338 if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == 0xFF) return 0;
11339 }
11340
11341 if(*ModeNo != 0x07) {
11342 if(*ModeNo > 0x03) return ModeIdIndex;
11343 if(VGAINFO & 0x80) return ModeIdIndex;
11344 ModeIdIndex++;
11345 }
11346
11347 if(VGAINFO & 0x10) ModeIdIndex++; /* 400 lines */
11348 /* else 350 lines */
11349 return ModeIdIndex;
11350}
11351
11352static void
11353SiS_OEM300Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
11354 unsigned short RefTableIndex)
11355{
11356 unsigned short OEMModeIdIndex = 0;
11357
11358 if(!SiS_Pr->UseCustomMode) {
11359 OEMModeIdIndex = SiS_SearchVBModeID(SiS_Pr,ModeNo: &ModeNo);
11360 if(!(OEMModeIdIndex)) return;
11361 }
11362
11363 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
11364 SetOEMLCDDelay(SiS_Pr, ModeNo, ModeIdIndex: OEMModeIdIndex);
11365 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
11366 SetOEMLCDData(SiS_Pr, ModeNo, ModeIdIndex: OEMModeIdIndex);
11367 }
11368 }
11369 if(SiS_Pr->UseCustomMode) return;
11370 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
11371 SetOEMTVDelay(SiS_Pr, ModeNo,ModeIdIndex: OEMModeIdIndex);
11372 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11373 SetOEMAntiFlicker(SiS_Pr, ModeNo, ModeIdIndex: OEMModeIdIndex);
11374 SetOEMPhaseIncr(SiS_Pr, ModeNo, ModeIdIndex: OEMModeIdIndex);
11375 SetOEMYFilter(SiS_Pr, ModeNo, ModeIdIndex: OEMModeIdIndex);
11376 }
11377 }
11378}
11379#endif
11380
11381

source code of linux/drivers/video/fbdev/sis/init301.c