aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/sis
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/video/sis
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'drivers/video/sis')
-rw-r--r--drivers/video/sis/300vtbl.h1965
-rw-r--r--drivers/video/sis/310vtbl.h2754
-rw-r--r--drivers/video/sis/Makefile7
-rw-r--r--drivers/video/sis/init.c5318
-rw-r--r--drivers/video/sis/init.h2472
-rw-r--r--drivers/video/sis/init301.c12239
-rw-r--r--drivers/video/sis/init301.h410
-rw-r--r--drivers/video/sis/initdef.h671
-rw-r--r--drivers/video/sis/oem300.h859
-rw-r--r--drivers/video/sis/oem310.h449
-rw-r--r--drivers/video/sis/osdef.h131
-rw-r--r--drivers/video/sis/sis.h573
-rw-r--r--drivers/video/sis/sis_accel.c678
-rw-r--r--drivers/video/sis/sis_accel.h409
-rw-r--r--drivers/video/sis/sis_main.c6027
-rw-r--r--drivers/video/sis/sis_main.h955
-rw-r--r--drivers/video/sis/vgatypes.h242
-rw-r--r--drivers/video/sis/vstruct.h676
18 files changed, 36835 insertions, 0 deletions
diff --git a/drivers/video/sis/300vtbl.h b/drivers/video/sis/300vtbl.h
new file mode 100644
index 000000000000..b6d5c71b2563
--- /dev/null
+++ b/drivers/video/sis/300vtbl.h
@@ -0,0 +1,1965 @@
1/* $XFree86$ */
2/* $XdotOrg$ */
3/*
4 * Register settings for SiS 300 series
5 *
6 * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
7 *
8 * If distributed as part of the Linux kernel, the following license terms
9 * apply:
10 *
11 * * This program is free software; you can redistribute it and/or modify
12 * * it under the terms of the GNU General Public License as published by
13 * * the Free Software Foundation; either version 2 of the named License,
14 * * or any later version.
15 * *
16 * * This program is distributed in the hope that it will be useful,
17 * * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * * GNU General Public License for more details.
20 * *
21 * * You should have received a copy of the GNU General Public License
22 * * along with this program; if not, write to the Free Software
23 * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
24 *
25 * Otherwise, the following license terms apply:
26 *
27 * * Redistribution and use in source and binary forms, with or without
28 * * modification, are permitted provided that the following conditions
29 * * are met:
30 * * 1) Redistributions of source code must retain the above copyright
31 * * notice, this list of conditions and the following disclaimer.
32 * * 2) Redistributions in binary form must reproduce the above copyright
33 * * notice, this list of conditions and the following disclaimer in the
34 * * documentation and/or other materials provided with the distribution.
35 * * 3) The name of the author may not be used to endorse or promote products
36 * * derived from this software without specific prior written permission.
37 * *
38 * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
39 * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
40 * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
41 * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
42 * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
43 * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
44 * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
45 * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46 * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
47 * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48 *
49 * Author: Thomas Winischhofer <thomas@winischhofer.net>
50 *
51 */
52
53static const SiS_StStruct SiS300_SModeIDTable[] =
54{
55 {0x01,0x9208,0x01,0x00,0x00,0x00,0x00,0x00, 0},
56 {0x01,0x1210,0x14,0x01,0x01,0x00,0x00,0x00, 0},
57 {0x01,0x1010,0x17,0x02,0x02,0x00,0x00,0x00, 0},
58 {0x03,0x8208,0x03,0x00,0x00,0x00,0x00,0x00, 0},
59 {0x03,0x0210,0x16,0x01,0x01,0x00,0x00,0x00, 0},
60 {0x03,0x0010,0x18,0x02,0x02,0x00,0x00,0x00, 0},
61 {0x05,0x9209,0x05,0x00,0x00,0x00,0x00,0x00, 0},
62 {0x06,0x8209,0x06,0x00,0x00,0x00,0x00,0x00, 0},
63 {0x07,0x0000,0x07,0x03,0x03,0x00,0x00,0x00, 0},
64 {0x07,0x0000,0x19,0x02,0x02,0x00,0x00,0x00, 0},
65 {0x0d,0x920a,0x0d,0x00,0x00,0x00,0x00,0x00, 0},
66 {0x0e,0x820a,0x0e,0x00,0x00,0x00,0x00,0x00, 0},
67 {0x0f,0x0202,0x11,0x01,0x01,0x00,0x00,0x00, 0},
68 {0x10,0x0212,0x12,0x01,0x01,0x00,0x00,0x00, 0},
69 {0x11,0x0212,0x1a,0x04,0x04,0x00,0x00,0x00, 0},
70 {0x12,0x0212,0x1b,0x04,0x04,0x00,0x00,0x00, 0},
71 {0x13,0x021b,0x1c,0x00,0x00,0x00,0x00,0x00, 0},
72 {0x12,0x0010,0x18,0x02,0x02,0x00,0x00,0x00, 0},
73 {0x12,0x0210,0x18,0x01,0x01,0x00,0x00,0x00, 0},
74 {0xff, 0, 0, 0, 0, 0, 0, 0, 0}
75};
76
77static const SiS_ExtStruct SiS300_EModeIDTable[] =
78{
79 {0x6a,0x2212,0x0102,SIS_RI_800x600, 0x00,0x00,0x00,0x00,0x00,-1}, /* 800x600x? */
80 {0x2e,0x0a1b,0x0101,SIS_RI_640x480, 0x00,0x00,0x00,0x00,0x08,-1},
81 {0x2f,0x021b,0x0100,SIS_RI_640x400, 0x00,0x00,0x00,0x00,0x10,-1}, /* 640x400x8 */
82 {0x30,0x2a1b,0x0103,SIS_RI_800x600, 0x00,0x00,0x00,0x00,0x00,-1},
83 {0x31,0x4a1b,0x0000,SIS_RI_720x480, 0x00,0x00,0x00,0x00,0x11,-1}, /* 720x480x8 */
84 {0x32,0x6a1b,0x0000,SIS_RI_720x576, 0x00,0x00,0x00,0x00,0x12,-1}, /* 720x576x8 */
85 {0x33,0x4a1d,0x0000,SIS_RI_720x480, 0x00,0x00,0x00,0x00,0x11,-1}, /* 720x480x16 */
86 {0x34,0x6a1d,0x0000,SIS_RI_720x576, 0x00,0x00,0x00,0x00,0x12,-1}, /* 720x576x16 */
87 {0x35,0x4a1f,0x0000,SIS_RI_720x480, 0x00,0x00,0x00,0x00,0x11,-1}, /* 720x480x32 */
88 {0x36,0x6a1f,0x0000,SIS_RI_720x576, 0x00,0x00,0x00,0x00,0x12,-1}, /* 720x576x32 */
89 {0x37,0x0212,0x0104,SIS_RI_1024x768, 0x00,0x00,0x00,0x00,0x13,-1}, /* 1024x768x? */
90 {0x38,0x0a1b,0x0105,SIS_RI_1024x768, 0x00,0x00,0x00,0x00,0x13,-1}, /* 1024x768x8 */
91 {0x3a,0x0e3b,0x0107,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a,-1}, /* 1280x1024x8 */
92 {0x3c,0x063b,0x0130,SIS_RI_1600x1200,0x00,0x00,0x00,0x00,0x1e,-1},
93 {0x3d,0x067d,0x0131,SIS_RI_1600x1200,0x00,0x00,0x00,0x00,0x1e,-1},
94 {0x40,0x921c,0x010d,SIS_RI_320x200, 0x00,0x00,0x00,0x00,0x23,-1}, /* 320x200x15 */
95 {0x41,0x921d,0x010e,SIS_RI_320x200, 0x00,0x00,0x00,0x00,0x23,-1}, /* 320x200x16 */
96 {0x43,0x0a1c,0x0110,SIS_RI_640x480, 0x00,0x00,0x00,0x00,0x08,-1},
97 {0x44,0x0a1d,0x0111,SIS_RI_640x480, 0x00,0x00,0x00,0x00,0x08,-1},
98 {0x46,0x2a1c,0x0113,SIS_RI_800x600, 0x00,0x00,0x00,0x00,0x00,-1}, /* 800x600x15 */
99 {0x47,0x2a1d,0x0114,SIS_RI_800x600, 0x00,0x00,0x00,0x00,0x00,-1}, /* 800x600x16 */
100 {0x49,0x0a3c,0x0116,SIS_RI_1024x768, 0x00,0x00,0x00,0x00,0x13,-1},
101 {0x4a,0x0a3d,0x0117,SIS_RI_1024x768, 0x00,0x00,0x00,0x00,0x13,-1},
102 {0x4c,0x0e7c,0x0119,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a,-1},
103 {0x4d,0x0e7d,0x011a,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a,-1},
104 {0x50,0x921b,0x0132,SIS_RI_320x240, 0x00,0x00,0x00,0x00,0x24,-1}, /* 320x240x8 */
105 {0x51,0xb21b,0x0133,SIS_RI_400x300, 0x00,0x00,0x00,0x00,0x25,-1}, /* 400x300x8 */
106 {0x52,0x921b,0x0134,SIS_RI_512x384, 0x00,0x00,0x00,0x00,0x26,-1}, /* 512x384x8 */
107 {0x56,0x921d,0x0135,SIS_RI_320x240, 0x00,0x00,0x00,0x00,0x24,-1}, /* 320x240x16 */
108 {0x57,0xb21d,0x0136,SIS_RI_400x300, 0x00,0x00,0x00,0x00,0x25,-1}, /* 400x300x16 */
109 {0x58,0x921d,0x0137,SIS_RI_512x384, 0x00,0x00,0x00,0x00,0x26,-1}, /* 512x384x16 */
110 {0x59,0x921b,0x0138,SIS_RI_320x200, 0x00,0x00,0x00,0x00,0x23,-1}, /* 320x200x8 */
111 {0x5c,0x921f,0x0000,SIS_RI_512x384, 0x00,0x00,0x00,0x00,0x26,-1}, /* 512x384x32 */
112 {0x5d,0x021d,0x0139,SIS_RI_640x400, 0x00,0x00,0x00,0x00,0x10,-1}, /* 640x400x16 */
113 {0x5e,0x021f,0x0000,SIS_RI_640x400, 0x00,0x00,0x00,0x00,0x10,-1}, /* 640x400x32 */
114 {0x62,0x0a3f,0x013a,SIS_RI_640x480, 0x00,0x00,0x00,0x00,0x08,-1},
115 {0x63,0x2a3f,0x013b,SIS_RI_800x600, 0x00,0x00,0x00,0x00,0x00,-1}, /* 800x600x32 */
116 {0x64,0x0a7f,0x013c,SIS_RI_1024x768, 0x00,0x00,0x00,0x00,0x13,-1},
117 {0x65,0x0eff,0x013d,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a,-1},
118 {0x66,0x06ff,0x013e,SIS_RI_1600x1200,0x00,0x00,0x00,0x00,0x1e,-1},
119 {0x68,0x067b,0x013f,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x27,-1},
120 {0x69,0x06fd,0x0140,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x27,-1},
121 {0x6b,0x07ff,0x0000,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x27,-1},
122 {0x6c,0x067b,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x00,0x28,-1}, /* 2048x1536x8 - not in BIOS! */
123 {0x6d,0x06fd,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x00,0x28,-1}, /* 2048x1536x16 - not in BIOS! */
124 {0x70,0x6a1b,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x00,0x2d,-1}, /* 800x480x8 */
125 {0x71,0x4a1b,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x30,-1}, /* 1024x576x8 */
126 {0x74,0x4a1d,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x30,-1}, /* 1024x576x16 */
127 {0x75,0x0e3d,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x33,-1}, /* 1280x720x16 */
128 {0x76,0x6a1f,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x00,0x2d,-1}, /* 800x480x32 */
129 {0x77,0x4a3f,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x30,-1}, /* 1024x576x32 */
130 {0x78,0x0eff,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x33,-1}, /* 1280x720x32 */
131 {0x79,0x0e3b,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x33,-1}, /* 1280x720x8 */
132 {0x7a,0x6a1d,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x00,0x2d,-1}, /* 800x480x16 */
133 {0x7c,0x0a3b,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x00,0x29,-1}, /* 1280x960x8 */
134 {0x7d,0x0a7d,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x00,0x29,-1}, /* 1280x960x16 */
135 {0x7e,0x0aff,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x00,0x29,-1}, /* 1280x960x32 */
136 {0x20,0x4a1b,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x00,0x2b,-1}, /* 1024x600 */
137 {0x21,0x4a3d,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x00,0x2b,-1},
138 {0x22,0x4a7f,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x00,0x2b,-1},
139 {0x23,0x4a1b,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x00,0x2c,-1}, /* 1152x768 */
140 {0x24,0x4a3d,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x00,0x2c,-1},
141 {0x25,0x4a7f,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x00,0x2c,-1},
142 {0x29,0x4e1b,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x36,-1}, /* 1152x864 */
143 {0x2a,0x4e3d,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x36,-1},
144 {0x2b,0x4e7f,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x36,-1},
145 {0x39,0x6a1b,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x00,0x39,-1}, /* 848x480 */
146 {0x3b,0x6a3d,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x00,0x39,-1},
147 {0x3e,0x6a7f,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x00,0x39,-1},
148 {0x3f,0x6a1b,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x00,0x3b,-1}, /* 856x480 */
149 {0x42,0x6a3d,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x00,0x3b,-1},
150 {0x45,0x6a7f,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x00,0x3b,-1},
151 {0x48,0x6a3b,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x3d,-1}, /* 1360x768 */
152 {0x4b,0x6a7d,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x3d,-1},
153 {0x4e,0x6aff,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x3d,-1},
154 {0x4f,0x921f,0x0000,SIS_RI_320x200, 0x00,0x00,0x00,0x00,0x23,-1}, /* 320x200x32 */
155 {0x53,0x921f,0x0000,SIS_RI_320x240, 0x00,0x00,0x00,0x00,0x24,-1}, /* 320x240x32 */
156 {0x54,0xb21f,0x0000,SIS_RI_400x300, 0x00,0x00,0x00,0x00,0x25,-1}, /* 400x300x32 */
157 {0x55,0x2e3b,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x3e,-1}, /* 1280x768 */
158 {0x5a,0x2e7d,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x3e,-1},
159 {0x5b,0x2eff,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x3e,-1},
160 {0x5f,0x6a1b,0x0000,SIS_RI_768x576, 0x00,0x00,0x00,0x00,0x3f,-1}, /* 768x576x8 */
161 {0x60,0x6a1d,0x0000,SIS_RI_768x576, 0x00,0x00,0x00,0x00,0x3f,-1}, /* 768x576x16 */
162 {0x61,0x6a1f,0x0000,SIS_RI_768x576, 0x00,0x00,0x00,0x00,0x3f,-1}, /* 768x576x32 */
163 {0x67,0x6e3b,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x00,0x40,-1}, /* 1360x1024x8 (BARCO) */
164 {0x6f,0x6e7d,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x00,0x40,-1}, /* 1360x1024x16 (BARCO) */
165 {0x72,0x6eff,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x00,0x40,-1}, /* 1360x1024x32 (BARCO) */
166 {0xff,0x0000,0xffff,0, 0x00,0x00,0x00,0x00,0x00}
167};
168
169static const SiS_Ext2Struct SiS300_RefIndex[] =
170{
171 {0x085f,0x0d,0x03,0x05,0x05,0x6a, 800, 600, 0}, /* 00 */
172 {0x0467,0x0e,0x44,0x05,0x05,0x6a, 800, 600, 0}, /* 01 */
173 {0x0067,0x0f,0x07,0x48,0x05,0x6a, 800, 600, 0}, /* 02 - CRT1CRTC was 0x4f */
174 {0x0067,0x10,0x06,0x8b,0x05,0x6a, 800, 600, 0}, /* 03 */
175 {0x0147,0x11,0x08,0x00,0x05,0x6a, 800, 600, 0}, /* 04 */
176 {0x0147,0x12,0x0c,0x00,0x05,0x6a, 800, 600, 0}, /* 05 */
177 {0x0047,0x11,0x4e,0x00,0x05,0x6a, 800, 600, 0}, /* 06 - CRT1CRTC was 0x51 */
178 {0x0047,0x11,0x13,0x00,0x05,0x6a, 800, 600, 0}, /* 07 */
179 {0xc85f,0x05,0x00,0x04,0x04,0x2e, 640, 480, 0}, /* 08 */
180 {0xc067,0x06,0x02,0x04,0x04,0x2e, 640, 480, 0}, /* 09 */
181 {0xc067,0x07,0x02,0x47,0x04,0x2e, 640, 480, 0}, /* 0a */
182 {0xc067,0x08,0x03,0x8a,0x04,0x2e, 640, 480, 0}, /* 0b */
183 {0xc047,0x09,0x05,0x00,0x04,0x2e, 640, 480, 0}, /* 0c */
184 {0xc047,0x0a,0x08,0x00,0x04,0x2e, 640, 480, 0}, /* 0d */
185 {0xc047,0x0b,0x0a,0x00,0x04,0x2e, 640, 480, 0}, /* 0e */
186 {0xc047,0x0c,0x10,0x00,0x04,0x2e, 640, 480, 0}, /* 0f */
187 {0x487f,0x04,0x00,0x00,0x00,0x2f, 640, 400, 0}, /* 10 */
188 {0xc06f,0x31,0x01,0x06,0x13,0x31, 720, 480, 0}, /* 11 */
189 {0x006f,0x32,0x03,0x06,0x14,0x32, 720, 576, 0}, /* 12 */
190 {0x0187,0x15,0x05,0x00,0x06,0x37,1024, 768, 0}, /* 13 */
191 {0xc877,0x16,0x09,0x06,0x06,0x37,1024, 768, 0}, /* 14 */
192 {0xc067,0x17,0x0b,0x49,0x06,0x37,1024, 768, 0}, /* 15 - CRT1CRTC was 0x97 */
193 {0x0267,0x18,0x0d,0x00,0x06,0x37,1024, 768, 0}, /* 16 */
194 {0x0047,0x19,0x11,0x8c,0x06,0x37,1024, 768, 0}, /* 17 - CRT1CRTC was 0x59 */
195 {0x0047,0x1a,0x52,0x00,0x06,0x37,1024, 768, 0}, /* 18 */
196 {0x0007,0x1b,0x16,0x00,0x06,0x37,1024, 768, 0}, /* 19 - CRT1CRTC was 0x5b */
197 {0x0387,0x1c,0x4d,0x00,0x07,0x3a,1280,1024, 0}, /* 1a - CRT1CRTC was 0x5c */
198 {0x0077,0x1d,0x14,0x07,0x07,0x3a,1280,1024, 0}, /* 1b */
199 {0x0047,0x1e,0x17,0x00,0x07,0x3a,1280,1024, 0}, /* 1c */
200 {0x0007,0x1f,0x98,0x00,0x07,0x3a,1280,1024, 0}, /* 1d */
201 {0x0007,0x20,0x59,0x00,0x00,0x3c,1600,1200, 0}, /* 1e - CRT1CRTC was 0x60 */
202 {0x0007,0x21,0x5a,0x00,0x00,0x3c,1600,1200, 0}, /* 1f */
203 {0x0007,0x22,0x1b,0x00,0x00,0x3c,1600,1200, 0}, /* 20 */
204 {0x0007,0x23,0x1d,0x00,0x00,0x3c,1600,1200, 0}, /* 21 - CRT1CRTC was 0x63 */
205 {0x0007,0x24,0x1e,0x00,0x00,0x3c,1600,1200, 0}, /* 22 */
206 {0x407f,0x00,0x00,0x00,0x00,0x40, 320, 200, 0}, /* 23 */
207 {0xc07f,0x01,0x00,0x04,0x04,0x50, 320, 240, 0}, /* 24 */
208 {0x0077,0x02,0x04,0x05,0x05,0x51, 400, 300, 0}, /* 25 */
209 {0xc877,0x03,0x09,0x06,0x06,0x52, 512, 384, 0}, /* 26 */ /* was c077 */
210 {0x8207,0x25,0x1f,0x00,0x00,0x68,1920,1440, 0}, /* 27 */
211 {0x0007,0x26,0x20,0x00,0x00,0x6c,2048,1536, 0}, /* 28 */
212 {0x0067,0x27,0x14,0x08,0x0a,0x6e,1280, 960, 0}, /* 29 - 1280x960-60 */
213 {0x0027,0x45,0x3c,0x08,0x0a,0x6e,1280, 960, 0}, /* 2a - 1280x960-85 */
214 {0xc077,0x33,0x09,0x06,0x00,0x20,1024, 600, 0}, /* 2b */
215 {0xc077,0x34,0x0b,0x06,0x00,0x23,1152, 768, 0}, /* 2c */ /* VCLK 0x09 */
216 {0x0077,0x35,0x27,0x08,0x18,0x70, 800, 480, 0}, /* 2d */
217 {0x0047,0x36,0x37,0x08,0x18,0x70, 800, 480, 0}, /* 2e */
218 {0x0047,0x37,0x08,0x08,0x18,0x70, 800, 480, 0}, /* 2f */
219 {0x0077,0x38,0x09,0x09,0x19,0x71,1024, 576, 0}, /* 30 */
220 {0x0047,0x39,0x38,0x09,0x19,0x71,1024, 576, 0}, /* 31 */
221 {0x0047,0x3a,0x11,0x09,0x19,0x71,1024, 576, 0}, /* 32 */
222 {0x0077,0x3b,0x39,0x0a,0x0c,0x75,1280, 720, 0}, /* 33 */
223 {0x0047,0x3c,0x3a,0x0a,0x0c,0x75,1280, 720, 0}, /* 34 */
224 {0x0007,0x3d,0x3b,0x0a,0x0c,0x75,1280, 720, 0}, /* 35 */
225 {0x0067,0x49,0x35,0x06,0x1a,0x29,1152, 864, 0}, /* 36 1152x864-60Hz */
226 {0x0067,0x3e,0x34,0x06,0x1a,0x29,1152, 864, 0}, /* 37 1152x864-75Hz */
227 {0x0047,0x44,0x3a,0x06,0x1a,0x29,1152, 864, 0}, /* 38 1152x864-85Hz */
228 {0x00c7,0x3f,0x28,0x00,0x16,0x39, 848, 480, 0}, /* 39 848x480-38Hzi */
229 {0xc067,0x40,0x3d,0x0b,0x16,0x39, 848, 480, 0}, /* 3a 848x480-60Hz */
230 {0x00c7,0x41,0x28,0x00,0x17,0x3f, 856, 480, 0}, /* 3b 856x480-38Hzi */
231 {0xc047,0x42,0x28,0x00,0x17,0x3f, 856, 480, 0}, /* 3c 856x480-60Hz */
232 {0x0067,0x43,0x3e,0x0c,0x1b,0x48,1360, 768, 0}, /* 3d 1360x768-60Hz */
233 {0x0077,0x46,0x3f,0x08,0x08,0x55,1280, 768, 0}, /* 3e 1280x768-60Hz */
234 {0x006f,0x47,0x03,0x06,0x15,0x5f, 768, 576, 0}, /* 3f 768x576 */
235 {0x0027,0x48,0x13,0x08,0x00,0x67,1360,1024, 0}, /* 40 1360x1024-59Hz (BARCO1366 only) */
236 {0xffff, 0, 0, 0, 0, 0, 0, 0, 0}
237};
238
239static const SiS_VBModeStruct SiS300_VBModeIDTable[] =
240{
241 {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
242 {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01},
243 {0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x02},
244 {0x03,0x00,0x00,0x00,0x02,0x00,0x02,0x00},
245 {0x03,0x00,0x00,0x00,0x02,0x00,0x02,0x01},
246 {0x03,0x00,0x00,0x00,0x03,0x00,0x03,0x02},
247 {0x05,0x00,0x00,0x01,0x04,0x00,0x00,0x00},
248 {0x06,0x00,0x00,0x01,0x05,0x00,0x02,0x00},
249 {0x07,0x00,0x00,0x00,0x03,0x00,0x03,0x01},
250 {0x07,0x00,0x00,0x00,0x03,0x00,0x03,0x02},
251 {0x0d,0x00,0x00,0x01,0x04,0x00,0x00,0x00},
252 {0x0e,0x00,0x00,0x01,0x05,0x00,0x02,0x00},
253 {0x0f,0x00,0x00,0x01,0x05,0x00,0x02,0x01},
254 {0x10,0x00,0x00,0x01,0x05,0x00,0x02,0x01},
255 {0x11,0x00,0x00,0x01,0x05,0x00,0x02,0x03},
256 {0x12,0x00,0x00,0x01,0x05,0x00,0x02,0x03},
257 {0x13,0x00,0x00,0x01,0x04,0x00,0x04,0x00},
258 {0x6a,0x00,0x00,0x01,0x07,0x00,0x08,0x0a},
259 {0x2e,0x00,0x00,0x01,0x05,0x00,0x06,0x08},
260 {0x2f,0x00,0x00,0x01,0x05,0x00,0x06,0x06},
261 {0x30,0x00,0x00,0x01,0x07,0x00,0x08,0x0a},
262 {0x31,0x00,0x00,0x01,0x06,0x00,0x00,0x00},
263 {0x32,0x00,0x00,0x01,0x06,0x00,0x00,0x00},
264 {0x33,0x00,0x00,0x01,0x06,0x00,0x00,0x00},
265 {0x34,0x00,0x00,0x01,0x06,0x00,0x00,0x00},
266 {0x35,0x00,0x00,0x01,0x06,0x00,0x00,0x00},
267 {0x36,0x00,0x00,0x01,0x06,0x00,0x00,0x00},
268 {0x37,0x00,0x00,0x01,0x00,0x00,0x0a,0x0c},
269 {0x38,0x00,0x00,0x01,0x00,0x00,0x0a,0x0c},
270 {0x3a,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
271 {0x40,0x00,0x00,0x01,0x04,0x00,0x05,0x05},
272 {0x41,0x00,0x00,0x01,0x04,0x00,0x05,0x05},
273 {0x43,0x00,0x00,0x01,0x05,0x00,0x06,0x08},
274 {0x44,0x00,0x00,0x01,0x05,0x00,0x06,0x08},
275 {0x46,0x00,0x00,0x01,0x07,0x00,0x08,0x0a},
276 {0x47,0x00,0x00,0x01,0x07,0x00,0x08,0x0a},
277 {0x49,0x00,0x00,0x01,0x00,0x00,0x0a,0x0c},
278 {0x4a,0x00,0x00,0x01,0x00,0x00,0x0a,0x0c},
279 {0x4c,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
280 {0x4d,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
281 {0x4f,0x00,0x00,0x01,0x04,0x00,0x05,0x05},
282 {0x50,0x00,0x00,0x01,0x04,0x00,0x05,0x07},
283 {0x51,0x00,0x00,0x01,0x07,0x00,0x07,0x09},
284 {0x52,0x00,0x00,0x01,0x00,0x00,0x09,0x0b},
285 {0x53,0x00,0x00,0x01,0x04,0x00,0x05,0x07},
286 {0x54,0x00,0x00,0x01,0x07,0x00,0x07,0x09},
287 {0x56,0x00,0x00,0x01,0x04,0x00,0x05,0x07},
288 {0x57,0x00,0x00,0x01,0x07,0x00,0x07,0x09},
289 {0x58,0x00,0x00,0x01,0x00,0x00,0x09,0x0b},
290 {0x59,0x00,0x00,0x01,0x04,0x00,0x05,0x05},
291 {0x5c,0x00,0x00,0x01,0x00,0x00,0x09,0x0b},
292 {0x5d,0x00,0x00,0x01,0x05,0x00,0x06,0x06},
293 {0x5e,0x00,0x00,0x01,0x05,0x00,0x06,0x06},
294 {0x5f,0x00,0x00,0x01,0x06,0x00,0x00,0x00},
295 {0x60,0x00,0x00,0x01,0x06,0x00,0x00,0x00},
296 {0x61,0x00,0x00,0x01,0x06,0x00,0x00,0x00},
297 {0x62,0x00,0x00,0x01,0x05,0x00,0x06,0x08},
298 {0x63,0x00,0x00,0x01,0x07,0x00,0x08,0x0a},
299 {0x64,0x00,0x00,0x01,0x00,0x00,0x0a,0x0c},
300 {0x65,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
301 {0x6c,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
302 {0x6d,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
303 {0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
304};
305
306static const SiS_CRT1TableStruct SiS300_CRT1Table[] =
307{
308#if 1
309 {{0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f, /* 0x00 - 320x200 */
310 0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x00, /* HRE [4],[15] is invalid - but correcting it does not work */
311 0x00}},
312#endif
313#if 0
314 {{0x2d,0x27,0x27,0x91,0x2c,0x92,0xbf,0x1f, /* 0x00 - corrected 320x200-72 - does not work */
315 0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x04,
316 0x00}},
317#endif
318 {{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e, /* 0x01 */
319 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00, /* HRE [4],[15] is invalid - but correcting it does not work */
320 0x00}},
321#if 0
322 {{0x2d,0x27,0x27,0x91,0x2c,0x92,0x0b,0x3e, /* 0x01 - corrected 320x240-60 - does not work */
323 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x04,
324 0x00}},
325#endif
326 {{0x3d,0x31,0x31,0x81,0x37,0x1f,0x72,0xf0, /* 0x02 */
327 0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x05,
328 0x01}},
329#if 0
330 {{0x3d,0x31,0x31,0x81,0x37,0x1f,0x72,0xf0, /* 0x02 - corrected 400x300-60 */
331 0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x05,
332 0x01}},
333#endif
334 {{0x4f,0x3f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
335 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x01,
336 0x01}},
337 {{0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
338 0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x05,
339 0x00}},
340#if 0
341 {{0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e, /* 0x05 */
342 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05,
343 0x00}},
344#endif
345 {{0x5f,0x4f,0x4f,0x83,0x55,0x81,0x0b,0x3e, /* 0x05 - corrected 640x480-60 */
346 0xe9,0x8b,0xdf,0xe8,0x0c,0x00,0x00,0x05,
347 0x00}},
348#if 0
349 {{0x63,0x4f,0x50,0x86,0x56,0x9b,0x06,0x3e, /* 0x06 */
350 0xe8,0x8b,0xdf,0xe7,0xff,0x10,0x00,0x01,
351 0x00}},
352#endif
353 {{0x63,0x4f,0x4f,0x87,0x56,0x9b,0x06,0x3e, /* 0x06 - corrected 640x480-72 */
354 0xe8,0x8a,0xdf,0xe7,0x07,0x00,0x00,0x01,
355 0x00}},
356 {{0x64,0x4f,0x4f,0x88,0x55,0x9d,0xf2,0x1f,
357 0xe0,0x83,0xdf,0xdf,0xf3,0x10,0x00,0x01,
358 0x00}},
359 {{0x63,0x4f,0x4f,0x87,0x5a,0x81,0xfb,0x1f,
360 0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x05,
361 0x00}},
362#if 0
363 {{0x66,0x4f,0x4f,0x86,0x56,0x9e,0x03,0x3e, /* 0x09 */
364 0xe4,0x87,0xdf,0xdf,0x04,0x00,0x00,0x01,
365 0x00}},
366#endif
367 {{0x67,0x4f,0x4f,0x8b,0x57,0x83,0x10,0x3e, /* 0x09 - corrected 640x480-100 */
368 0xe7,0x8d,0xdf,0xe6,0x11,0x00,0x00,0x05,
369 0x00}},
370#if 0
371 {{0x6c,0x4f,0x4f,0x83,0x59,0x9e,0x00,0x3e, /* 0x0a */
372 0xe5,0x8d,0xdf,0xdf,0x01,0x00,0x00,0x01,
373 0x00}},
374#endif
375 {{0x67,0x4f,0x4f,0x8b,0x57,0x83,0x10,0x3e, /* 0x0a - corrected 640x480-120 */
376 0xe7,0x8d,0xdf,0xe6,0x11,0x00,0x00,0x05,
377 0x00}},
378 {{0x63,0x4f,0x4f,0x87,0x56,0x9d,0xfb,0x1f,
379 0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x01,
380 0x00}},
381 {{0x65,0x4f,0x4f,0x89,0x57,0x9f,0xfb,0x1f,
382 0xe6,0x8a,0xdf,0xdf,0xfc,0x10,0x00,0x01, /* Corrected VDE, VBE */
383 0x00}},
384 {{0x7b,0x63,0x63,0x9f,0x6a,0x93,0x6f,0xf0,
385 0x58,0x8a,0x57,0x57,0x70,0x20,0x00,0x05,
386 0x01}},
387 {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xf0,
388 0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x06,
389 0x01}},
390 {{0x7d,0x63,0x63,0x81,0x6e,0x1d,0x98,0xf0,
391 0x7c,0x82,0x57,0x57,0x99,0x00,0x00,0x06,
392 0x01}},
393 {{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xf0,
394 0x58,0x8b,0x57,0x57,0x70,0x20,0x00,0x06,
395 0x01}},
396 {{0x7e,0x63,0x63,0x82,0x6b,0x13,0x75,0xf0,
397 0x58,0x8b,0x57,0x57,0x76,0x20,0x00,0x06,
398 0x01}},
399 {{0x8c,0x63,0x63,0x87,0x72,0x16,0x7e,0xf0,
400 0x59,0x8d,0x57,0x57,0x7f,0x00,0x00,0x06,
401 0x01}},
402 {{0x7e,0x63,0x63,0x82,0x6c,0x14,0x75,0xe0,
403 0x58,0x0b,0x57,0x57,0x76,0x20,0x00,0x06,
404 0x01}},
405 {{0x7e,0x63,0x63,0x82,0x6c,0x14,0x75,0xe0, /* 0x14 */
406 0x58,0x0b,0x57,0x57,0x76,0x20,0x00,0x06,
407 0x01}},
408 {{0x99,0x7f,0x7f,0x9d,0x84,0x1a,0x96,0x1f,
409 0x7f,0x83,0x7f,0x7f,0x97,0x10,0x00,0x02,
410 0x00}},
411 {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,
412 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
413 0x01}},
414 {{0xa1,0x7f,0x7f,0x85,0x86,0x97,0x24,0xf5,
415 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
416 0x01}},
417 {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf5,
418 0x00,0x83,0xff,0xff,0x1f,0x10,0x00,0x02,
419 0x01}},
420 {{0xa7,0x7f,0x7f,0x8b,0x89,0x95,0x26,0xf5,
421 0x00,0x83,0xff,0xff,0x27,0x10,0x00,0x02,
422 0x01}},
423 {{0x9f,0x7f,0x7f,0x83,0x83,0x93,0x1e,0xf5, /* 0x1a */
424 0x00,0x84,0xff,0xff,0x1f,0x10,0x00,0x02,
425 0x01}},
426 {{0xa2,0x7f,0x7f,0x86,0x84,0x94,0x37,0xf5,
427 0x0b,0x82,0xff,0xff,0x38,0x10,0x00,0x02,
428 0x01}},
429 {{0xcf,0x9f,0x9f,0x93,0xb2,0x01,0x14,0xba,
430 0x00,0x83,0xff,0xff,0x15,0x00,0x00,0x03,
431 0x00}},
432 {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0x5a,
433 0x00,0x83,0xff,0xff,0x29,0x09,0x00,0x07,
434 0x01}},
435 {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0x5a, /* 0x1e */
436 0x00,0x83,0xff,0xff,0x29,0x09,0x00,0x07,
437 0x01}},
438 {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0x5a,
439 0x00,0x83,0xff,0xff,0x2f,0x09,0x00,0x07,
440 0x01}},
441 {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
442 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
443 0x00}},
444 {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
445 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
446 0x00}},
447 {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
448 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
449 0x00}},
450 {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
451 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
452 0x00}},
453 {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10, /* 36: 1600x1200x85Hz */
454 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
455 0x00}},
456 {{0x3f,0xef,0xef,0x83,0xfd,0x1a,0xda,0x1f, /* 37: 1920x1440x60Hz */
457 0xa0,0x84,0x9f,0x9f,0xdb,0x1f,0x01,0x01,
458 0x00}},
459 {{0x55,0xff,0xff,0x99,0x0d,0x0c,0x3e,0xba,
460 0x00,0x84,0xff,0xff,0x3f,0x0f,0x41,0x05,
461 0x00}},
462#if 0
463 {{0xdc,0x9f,0x9f,0x00,0xab,0x19,0xe6,0xef, /* 0x27: 1280x960-70 - invalid! */
464 0xc0,0xc3,0xbf,0xbf,0xe7,0x10,0x00,0x07,
465 0x01}},
466#endif
467 {{0xdc,0x9f,0x9f,0x80,0xaf,0x9d,0xe6,0xff, /* 0x27: 1280x960-60 - correct */
468 0xc0,0x83,0xbf,0xbf,0xe7,0x10,0x00,0x07,
469 0x01}},
470 {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xba, /* 0x28 */
471 0x27,0x8b,0xdf,0xdf,0x73,0x00,0x00,0x06,
472 0x01}},
473 {{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xba,
474 0x26,0x89,0xdf,0xdf,0x6f,0x00,0x00,0x06,
475 0x01}},
476 {{0x7f,0x63,0x63,0x82,0x6b,0x13,0x75,0xba,
477 0x29,0x8c,0xdf,0xdf,0x75,0x00,0x00,0x06,
478 0x01}},
479 {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf1,
480 0xaf,0x85,0x3f,0x3f,0x25,0x30,0x00,0x02,
481 0x01}},
482 {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf1,
483 0xad,0x81,0x3f,0x3f,0x1f,0x30,0x00,0x02,
484 0x01}},
485 {{0xa7,0x7f,0x7f,0x88,0x89,0x15,0x26,0xf1,
486 0xb1,0x85,0x3f,0x3f,0x27,0x30,0x00,0x02,
487 0x01}},
488 {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0xc4,
489 0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07,
490 0x01}},
491 {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0xd4,
492 0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07,
493 0x01}},
494 {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0xd4,
495 0x7d,0x81,0xcf,0xcf,0x2f,0x21,0x00,0x07,
496 0x01}},
497 {{0x6b,0x59,0x59,0x8f,0x5e,0x8c,0x0b,0x3e,
498 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05,
499 0x00}},
500 {{0x7b,0x59,0x63,0x9f,0x6a,0x93,0x6f,0xf0, /* 0x32 */
501 0x58,0x8a,0x3f,0x57,0x70,0x20,0x00,0x05,
502 0x01}},
503 {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x1e,0xf1, /* 0x33 - 1024x600 */
504 0xae,0x85,0x57,0x57,0x1f,0x30,0x00,0x02,
505 0x01}},
506 {{0xa3,0x8f,0x8f,0x97,0x96,0x97,0x24,0xf5, /* 0x34 - 1152x768 - corrected */
507 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
508 0x01}},
509 {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xba, /* 0x35 */
510 0x27,0x8b,0xdf,0xdf,0x73,0x00,0x00,0x06,
511 0x01}}, /* 0x35 */
512 {{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xba,
513 0x26,0x89,0xdf,0xdf,0x6f,0x00,0x00,0x06,
514 0x01}}, /* 0x36 */
515 {{0x7f,0x63,0x63,0x82,0x6b,0x13,0x75,0xba,
516 0x29,0x8c,0xdf,0xdf,0x75,0x00,0x00,0x06,
517 0x01}}, /* 0x37 */
518 {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf1,
519 0xaf,0x85,0x3f,0x3f,0x25,0x30,0x00,0x02,
520 0x01}}, /* 0x38 */
521 {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf1,
522 0xad,0x81,0x3f,0x3f,0x1f,0x30,0x00,0x02,
523 0x01}}, /* 0x39 */
524 {{0xa7,0x7f,0x7f,0x88,0x89,0x95,0x26,0xf1, /* 95 was 15 - illegal HBE! */
525 0xb1,0x85,0x3f,0x3f,0x27,0x30,0x00,0x02,
526 0x01}}, /* 0x3a */
527 {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0xc4,
528 0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07,
529 0x01}}, /* 0x3b */
530 {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0xd4,
531 0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07,
532 0x01}}, /* 0x3c */
533 {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0xd4,
534 0x7d,0x81,0xcf,0xcf,0x2f,0x21,0x00,0x07,
535 0x01}}, /* 0x3d */
536 {{0xc3,0x8f,0x8f,0x87,0x9b,0x0b,0x82,0xef, /* 1152x864-75 */
537 0x60,0x83,0x5f,0x5f,0x83,0x10,0x00,0x07,
538 0x01}}, /* 0x3e */
539 {{0x86,0x69,0x69,0x8A,0x74,0x06,0x8C,0x15, /* 848x480-38i */
540 0x4F,0x83,0xEF,0xEF,0x8D,0x30,0x00,0x02,
541 0x00}}, /* 0x3f */
542 {{0x83,0x69,0x69,0x87,0x6f,0x1d,0x03,0x3E, /* 848x480-60 */
543 0xE5,0x8d,0xDF,0xe4,0x04,0x00,0x00,0x06,
544 0x00}}, /* 0x40 */
545 {{0x86,0x6A,0x6A,0x8A,0x74,0x06,0x8C,0x15, /* 856x480-38i */
546 0x4F,0x83,0xEF,0xEF,0x8D,0x30,0x00,0x02,
547 0x00}}, /* 0x41 */
548 {{0x81,0x6A,0x6A,0x85,0x70,0x00,0x0F,0x3E, /* 856x480-60 */
549 0xEB,0x8E,0xDF,0xDF,0x10,0x00,0x00,0x02,
550 0x00}}, /* 0x42 */
551 {{0xdd,0xa9,0xa9,0x81,0xb4,0x97,0x26,0xfd, /* 1360x768-60 */
552 0x01,0x8d,0xff,0x00,0x27,0x10,0x00,0x03,
553 0x01}}, /* 0x43 */
554 {{0xd9,0x8f,0x8f,0x9d,0xba,0x0a,0x8a,0xff, /* 1152x864-84 */
555 0x60,0x8b,0x5f,0x5f,0x8b,0x10,0x00,0x03,
556 0x01}}, /* 0x44 */
557 {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0xf1,0xff, /* 1280x960-85 */
558 0xc0,0x83,0xbf,0xbf,0xf2,0x10,0x00,0x07,
559 0x01}}, /* 0x45 */
560 {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x20,0xf5, /* 1280x768-60 */
561 0x03,0x88,0xff,0xff,0x21,0x10,0x00,0x07,
562 0x01}}, /* 0x46 */
563 {{0x7b,0x5f,0x63,0x9f,0x6a,0x93,0x6f,0xf0, /* 768x576 */
564 0x58,0x8a,0x3f,0x57,0x70,0x20,0x00,0x05,
565 0x01}}, /* 0x47 */
566 {{0xce,0xa9,0xa9,0x92,0xb1,0x07,0x28,0x52, /* 1360x1024 (Barco iQ Pro R300) */
567 0x02,0x8e,0xff,0x00,0x29,0x0d,0x00,0x03,
568 0x00}}, /* 0x48 */
569 {{0xcd,0x8f,0x8f,0x91,0x9b,0x1b,0x7a,0xff, /* 1152x864-60 */
570 0x64,0x8c,0x5f,0x62,0x7b,0x10,0x00,0x07,
571 0x41}} /* 0x49 */
572};
573
574static const SiS_MCLKDataStruct SiS300_MCLKData_630[] =
575{
576 { 0x5a,0x64,0x80, 66},
577 { 0xb3,0x45,0x80, 83},
578 { 0x37,0x61,0x80,100},
579 { 0x37,0x22,0x80,133},
580 { 0x37,0x61,0x80,100},
581 { 0x37,0x61,0x80,100},
582 { 0x37,0x61,0x80,100},
583 { 0x37,0x61,0x80,100}
584};
585
586static const SiS_MCLKDataStruct SiS300_MCLKData_300[] =
587{
588 { 0x68,0x43,0x80,125},
589 { 0x68,0x43,0x80,125},
590 { 0x68,0x43,0x80,125},
591 { 0x37,0x61,0x80,100},
592 { 0x37,0x61,0x80,100},
593 { 0x37,0x61,0x80,100},
594 { 0x37,0x61,0x80,100},
595 { 0x37,0x61,0x80,100}
596};
597
598static SiS_VCLKDataStruct SiS300_VCLKData[] =
599{
600 { 0x1b,0xe1, 25}, /* 0x00 */
601 { 0x4e,0xe4, 28}, /* 0x01 */
602 { 0x57,0xe4, 32}, /* 0x02 */
603 { 0xc3,0xc8, 36}, /* 0x03 */
604 { 0x42,0xc3, 40}, /* 0x04 */
605 { 0x5d,0xc4, 45}, /* 0x05 */
606 { 0x52,0x65, 50}, /* 0x06 */
607 { 0x53,0x65, 50}, /* 0x07 */
608 { 0x6d,0x66, 56}, /* 0x08 */
609 { 0x5a,0x64, 65}, /* 0x09 */
610 { 0x46,0x44, 68}, /* 0x0a */
611 { 0x3e,0x43, 75}, /* 0x0b */
612 { 0x6d,0x46, 76}, /* 0x0c */ /* 800x600 | LVDS_2(CH), MITAC(CH); - 730, A901(301B): 0xb1,0x46, 76 */
613 { 0x41,0x43, 79}, /* 0x0d */
614 { 0x31,0x42, 79}, /* 0x0e */
615 { 0x46,0x25, 85}, /* 0x0f */
616 { 0x78,0x29, 87}, /* 0x10 */
617 { 0x62,0x44, 95}, /* 0x11 */
618 { 0x2b,0x22,105}, /* 0x12 */
619 { 0x49,0x24,106}, /* 0x13 */
620 { 0xc3,0x28,108}, /* 0x14 */
621 { 0x3c,0x23,109}, /* 0x15 */
622 { 0xf7,0x2c,132}, /* 0x16 */
623 { 0xd4,0x28,136}, /* 0x17 */
624 { 0x41,0x05,158}, /* 0x18 */
625 { 0x43,0x05,162}, /* 0x19 */
626 { 0xe1,0x0f,175}, /* 0x1a */
627 { 0xfc,0x12,189}, /* 0x1b */
628 { 0xde,0x26,194}, /* 0x1c */
629 { 0x54,0x05,203}, /* 0x1d */
630 { 0x3f,0x03,230}, /* 0x1e */
631 { 0x30,0x02,234}, /* 0x1f */
632 { 0x24,0x01,266}, /* 0x20 */
633 { 0x52,0x2a, 54}, /* 0x21 */ /* 301 TV */
634 { 0x52,0x6a, 27}, /* 0x22 */ /* 301 TV */
635 { 0x62,0x24, 70}, /* 0x23 */ /* 301 TV */
636 { 0x62,0x64, 70}, /* 0x24 */ /* 301 TV */
637 { 0xa8,0x4c, 30}, /* 0x25 */ /* 301 TV */
638 { 0x20,0x26, 33}, /* 0x26 */ /* 301 TV */
639 { 0x31,0xc2, 39}, /* 0x27 */
640 { 0xbf,0xc8, 35}, /* 0x28 */ /* 856x480 */
641 { 0x60,0x36, 30}, /* 0x29 */ /* CH/UNTSC TEXT | LVDS_2(CH) - 730, A901(301B), Mitac(CH): 0xe0, 0xb6, 30 */
642 { 0x40,0x4a, 28}, /* 0x2a */ /* CH-TV */
643 { 0x9f,0x46, 44}, /* 0x2b */ /* CH-TV */
644 { 0x97,0x2c, 26}, /* 0x2c */ /* CH-TV */
645 { 0x44,0xe4, 25}, /* 0x2d */ /* CH-TV */
646 { 0x7e,0x32, 47}, /* 0x2e */ /* CH-TV */
647 { 0x8a,0x24, 31}, /* 0x2f */ /* CH/PAL TEXT | LVDS_2(CH), Mitac(CH) - 730, A901(301B): 0x57, 0xe4, 31 */
648 { 0x97,0x2c, 26}, /* 0x30 */ /* CH-TV */
649 { 0xce,0x3c, 39}, /* 0x31 */ /* CH-TV */
650 { 0x52,0x4a, 36}, /* 0x32 */ /* CH/PAL 800x600 5/6 */
651 { 0x34,0x61, 95}, /* 0x33 */
652 { 0x78,0x27,108}, /* 0x34 */ /* Replacement for index 0x14 for 630 (?) */
653 { 0x70,0x28, 90}, /* 0x35 */ /* 1152x864@60 */
654 { 0x45,0x6b, 21}, /* 0x36 */ /* Chrontel SuperOverscan */
655 { 0x52,0xe2, 49}, /* 0x37 */ /* 16:9 modes */
656 { 0x2b,0x61, 78}, /* 0x38 */ /* 16:9 modes */
657 { 0x70,0x44,108}, /* 0x39 */ /* 16:9 modes */
658 { 0x54,0x42,135}, /* 0x3a */ /* 16:9 modes */
659 { 0x41,0x22,157}, /* 0x3b */ /* 16:9 modes */
660 { 0x52,0x07,149}, /* 0x3c */ /* 1280x960-85 */
661 { 0x62,0xc6, 34}, /* 0x3d */ /* 848x480-60 */
662 { 0x30,0x23, 88}, /* 0x3e */ /* 1360x768-60 */
663 { 0x70,0x29, 81}, /* 0x3f */ /* 1280x768-60 */
664 { 0x72,0x2a, 76}, /* 0x40 */ /* test for SiS730 --- LIMIT for table (&0x3f) */
665 { 0x15,0x21, 79}, /* 0x41 */ /* test for SiS730 */
666 { 0xa1,0x42,108}, /* 0x42 */ /* 1280x960 LCD */
667 { 0x37,0x61,100}, /* 0x43 */ /* 1280x960 LCD */
668 { 0xe3,0x9a,106}, /* 0x44 */ /* 1360x1024 - special for Barco iQ R300 */
669 { 0xe2,0x46,135}, /* 0x45 */ /* 1280x1024-75, better clock for VGA2 */
670 { 0x70,0x29, 81}, /* 0x46 */ /* unused */
671 { 0, 0, 0}, /* 0x47 custom (will be filled out) */
672 { 0xce,0x25,189} /* 0x48 */ /* Replacement for index 0x1b for 730 (and 540?) */
673};
674
675#ifdef LINUX_KERNEL
676static UCHAR SiS300_SR07 = 0x10;
677#endif
678
679static const DRAM4Type SiS300_SR15[8] =
680{
681 {0x01,0x09,0xa3,0x00},
682 {0x43,0x43,0x43,0x00},
683 {0x1e,0x1e,0x1e,0x00},
684 {0x2a,0x2a,0x2a,0x00},
685 {0x06,0x06,0x06,0x00},
686 {0x00,0x00,0x00,0x00},
687 {0x00,0x00,0x00,0x00},
688 {0x00,0x00,0x00,0x00}
689};
690
691#ifdef LINUX_KERNEL
692static UCHAR SiS300_SR1F = 0x00;
693static UCHAR SiS300_SR21 = 0x16;
694static UCHAR SiS300_SR22 = 0xb2;
695static UCHAR SiS300_SR23 = 0xf6;
696static UCHAR SiS300_SR24 = 0x0d;
697static UCHAR SiS300_SR25[] = {0x0,0x0};
698static UCHAR SiS300_SR31 = 0x00;
699static UCHAR SiS300_SR32 = 0x11;
700static UCHAR SiS300_SR33 = 0x00;
701static UCHAR SiS300_CRT2Data_1_2 = 0x40;
702static UCHAR SiS300_CRT2Data_4_D = 0x00;
703static UCHAR SiS300_CRT2Data_4_E = 0x00;
704static UCHAR SiS300_CRT2Data_4_10 = 0x80;
705
706static const USHORT SiS300_RGBSenseData = 0xd1;
707static const USHORT SiS300_VideoSenseData = 0xb3;
708static const USHORT SiS300_YCSenseData = 0xb9;
709static const USHORT SiS300_RGBSenseData2 = 0x0190;
710static const USHORT SiS300_VideoSenseData2 = 0x0174;
711static const USHORT SiS300_YCSenseData2 = 0x016b;
712
713static const DRAM4Type SiS300_CR40[5];
714
715static UCHAR SiS300_CR49[2];
716#endif
717
718static const SiS_PanelDelayTblStruct SiS300_PanelDelayTbl[] =
719{
720 {{0x05,0xaa}},
721 {{0x05,0x14}},
722 {{0x05,0x36}},
723 {{0x05,0x14}},
724 {{0x05,0x14}},
725 {{0x05,0x14}},
726 {{0x05,0x90}},
727 {{0x05,0x90}},
728 {{0x05,0x14}},
729 {{0x05,0x14}},
730 {{0x05,0x14}},
731 {{0x05,0x14}},
732 {{0x20,0x80}},
733 {{0x05,0x14}},
734 {{0x05,0x40}},
735 {{0x05,0x60}}
736};
737
738#if 0
739static const SiS_PanelDelayTblStruct SiS300_PanelDelayTblLVDS[] =
740{
741 {{0x05,0xaa}},
742 {{0x05,0x14}},
743 {{0x05,0x36}},
744 {{0x05,0x14}},
745 {{0x05,0x14}},
746 {{0x05,0x14}},
747 {{0x05,0x90}},
748 {{0x05,0x90}},
749 {{0x05,0x14}},
750 {{0x05,0x14}},
751 {{0x05,0x14}},
752 {{0x05,0x14}}, /* 2.07a (JVC): 14,96 */
753 {{0x05,0x28}}, /* 2.04.5c: 20, 80 - Clevo (2.04.2c): 05, 28 */
754 {{0x05,0x14}},
755 {{0x05,0x14}}, /* Some BIOSes: 05, 40 */
756 {{0x05,0x60}}
757};
758#endif
759
760/**************************************************************/
761/* SIS VIDEO BRIDGE ----------------------------------------- */
762/**************************************************************/
763
764static const SiS_LCDDataStruct SiS300_St2LCD1024x768Data[] =
765{
766 { 62, 25, 800, 546,1344, 806},
767 { 32, 15, 930, 546,1344, 806},
768 { 32, 15, 930, 546,1344, 806},
769 { 104, 45, 945, 496,1344, 806},
770 { 62, 25, 800, 546,1344, 806},
771 { 31, 18,1008, 624,1344, 806},
772 { 1, 1,1344, 806,1344, 806}
773};
774
775static const SiS_LCDDataStruct SiS300_ExtLCD1024x768Data[] =
776{
777 { 12, 5, 896, 512,1344, 806},
778 { 12, 5, 896, 510,1344, 806},
779 { 32, 15,1008, 505,1344, 806},
780 { 32, 15,1008, 514,1344, 806},
781 { 12, 5, 896, 500,1344, 806},
782 { 42, 25,1024, 625,1344, 806},
783 { 1, 1,1344, 806,1344, 806},
784 { 12, 5, 896, 500,1344, 806},
785 { 42, 25,1024, 625,1344, 806},
786 { 1, 1,1344, 806,1344, 806},
787 { 12, 5, 896, 500,1344, 806},
788 { 42, 25,1024, 625,1344, 806},
789 { 1, 1,1344, 806,1344, 806}
790};
791
792static const SiS_LCDDataStruct SiS300_St2LCD1280x1024Data[] =
793{
794 { 22, 5, 800, 510,1650,1088},
795 { 22, 5, 800, 510,1650,1088},
796 { 176, 45, 900, 510,1650,1088},
797 { 176, 45, 900, 510,1650,1088},
798 { 22, 5, 800, 510,1650,1088},
799 { 13, 5,1024, 675,1560,1152},
800 { 16, 9,1266, 804,1688,1072},
801 { 1, 1,1688,1066,1688,1066}
802};
803
804static const SiS_LCDDataStruct SiS300_ExtLCD1280x1024Data[] =
805{
806 { 211, 60,1024, 501,1688,1066},
807 { 211, 60,1024, 508,1688,1066},
808 { 211, 60,1024, 501,1688,1066},
809 { 211, 60,1024, 508,1688,1066},
810 { 211, 60,1024, 500,1688,1066},
811 { 211, 75,1024, 625,1688,1066},
812 { 211, 120,1280, 798,1688,1066},
813 { 1, 1,1688,1066,1688,1066}
814};
815
816static const SiS_Part2PortTblStruct SiS300_CRT2Part2_1024x768_1[] =
817{ /* VESA Timing */
818 {{0x21,0x12,0xbf,0xe4,0xc0,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}},
819 {{0x2c,0x12,0x9a,0xae,0x88,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}},
820 {{0x21,0x12,0xbf,0xe4,0xc0,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}},
821 {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
822 {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}},
823 {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}},
824 {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}}
825};
826
827static const SiS_Part2PortTblStruct SiS300_CRT2Part2_1024x768_2[] =
828{ /* Non-VESA */
829 {{0x28,0x12,0xa3,0xd0,0xaa,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
830 {{0x2c,0x12,0x9a,0xae,0x88,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
831 {{0x28,0x12,0xa3,0xd0,0xaa,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
832 {{0x2c,0x12,0x9a,0xae,0x88,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
833 {{0x28,0x13,0xe7,0x0b,0xe8,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
834 {{0x38,0x18,0x16,0x00,0x00,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
835 {{0x36,0x13,0x13,0x25,0xff,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}}
836};
837
838static const SiS_Part2PortTblStruct SiS300_CRT2Part2_1024x768_3[] =
839{
840 {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
841};
842
843static const SiS_Part2PortTblStruct SiS300_CRT2Part2_1280x1024_1[] =
844{
845 {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
846};
847
848static const SiS_Part2PortTblStruct SiS300_CRT2Part2_1280x1024_2[] =
849{
850 {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
851};
852
853static const SiS_Part2PortTblStruct SiS300_CRT2Part2_1280x1024_3[] =
854{
855 {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
856};
857
858/**************************************************************/
859/* LVDS/Chrontel -------------------------------------------- */
860/**************************************************************/
861
862static const SiS_LVDSDataStruct SiS300_CHTVUPALData[] =
863{
864 {1008, 625,1008, 625},
865 {1008, 625,1008, 625},
866 {1008, 625,1008, 625},
867 {1008, 625,1008, 625},
868 { 840, 750, 840, 750},
869 { 936, 836, 936, 836}
870};
871
872static const SiS_LVDSDataStruct SiS300_CHTVOPALData[] =
873{
874 {1008, 625,1008, 625},
875 {1008, 625,1008, 625},
876 {1008, 625,1008, 625},
877 {1008, 625,1008, 625},
878 { 840, 625, 840, 625},
879 { 960, 750, 960, 750}
880};
881
882static const SiS_LVDSDataStruct SiS300_CHTVSOPALData[] =
883{
884 {1008, 625,1008, 625},
885 {1008, 625,1008, 625},
886 {1008, 625,1008, 625},
887 {1008, 625,1008, 625},
888 { 840, 500, 840, 500},
889 { 944, 625, 944, 625}
890};
891
892
893static const SiS_LVDSDesStruct SiS300_PanelType00_1[] =
894{
895 { 1059, 626 }, /* 2.08 */
896 { 1059, 624 },
897 { 1059, 626 },
898 { 1059, 624 },
899 { 1059, 624 },
900 { 0, 627 },
901 { 0, 627 },
902 { 0, 0 },
903 { 0, 0 }
904#if 0
905 {0, 626},
906 {0, 624},
907 {0, 626},
908 {0, 624},
909 {0, 624},
910 {0, 627},
911 {0, 627},
912 {0, 0},
913 {0, 0}
914#endif
915};
916
917static const SiS_LVDSDesStruct SiS300_PanelType01_1[] =
918{
919 { 0, 0 }, /* 2.08 */
920 { 0, 0 },
921 { 0, 0 },
922 { 0, 0 },
923 { 0, 0 },
924 { 0, 0 },
925 { 0, 0 },
926 { 0, 0 },
927 { 0, 0 }
928#if 0
929 {1343, 798},
930 {1343, 794},
931 {1343, 798},
932 {1343, 794},
933 {1343, 0},
934 {1343, 0},
935 { 0, 805},
936 { 0, 794},
937 { 0, 0}
938#endif
939};
940
941static const SiS_LVDSDesStruct SiS300_PanelType02_1[] =
942{
943 { 1059, 626 }, /* 2.08 */
944 { 1059, 624 },
945 { 1059, 626 },
946 { 1059, 624 },
947 { 1059, 624 },
948 { 0, 627 },
949 { 0, 627 },
950 { 0, 0 },
951 { 0, 0 }
952#if 0
953 {0, 626},
954 {0, 624},
955 {0, 626},
956 {0, 624},
957 {0, 624},
958 {0, 627},
959 {0, 627},
960 {0, 0},
961 {0, 0}
962#endif
963};
964
965static const SiS_LVDSDesStruct SiS300_PanelType03_1[] =
966{
967 { 8, 436},
968 { 8, 440},
969 { 8, 436},
970 { 8, 440},
971 { 8, 512},
972 {1343, 798},
973 {1343, 794},
974 {1343, 798},
975 {1343, 794}
976};
977
978static const SiS_LVDSDesStruct SiS300_PanelType04_1[] = /* 1280x1024 */
979{
980 {1343, 798},
981 {1343, 794},
982 {1343, 798},
983 {1343, 794},
984 {1343, 0},
985 {1343, 0},
986 { 0, 805},
987 { 0, 794},
988 { 0, 0}
989};
990
991static const SiS_LVDSDesStruct SiS300_PanelType05_1[] =
992{
993 {1343, 798},
994 {1343, 794},
995 {1343, 798},
996 {1343, 794},
997 {1343, 0},
998 {1343, 0},
999 { 0, 805},
1000 { 0, 794},
1001 { 0, 0}
1002};
1003
1004static const SiS_LVDSDesStruct SiS300_PanelType06_1[] = /* Clevo Trumpion 1024x768 */
1005{
1006 {1343, 798},
1007 {1343, 794},
1008 {1343, 798},
1009 {1343, 794},
1010 {1343, 0},
1011 {1343, 0},
1012 { 0, 805},
1013 { 0, 794},
1014 { 0, 0}
1015};
1016
1017static const SiS_LVDSDesStruct SiS300_PanelType07_1[] =
1018{
1019 {1343, 798},
1020 {1343, 794},
1021 {1343, 798},
1022 {1343, 794},
1023 {1343, 0},
1024 {1343, 0},
1025 { 0, 805},
1026 { 0, 794},
1027 { 0, 0}
1028};
1029
1030static const SiS_LVDSDesStruct SiS300_PanelType08_1[] =
1031{
1032 {1059, 626},
1033 {1059, 624},
1034 {1059, 626},
1035 {1059, 624},
1036 {1059, 624},
1037 { 0, 627},
1038 { 0, 627},
1039 { 0, 0},
1040 { 0, 0}
1041};
1042
1043static const SiS_LVDSDesStruct SiS300_PanelType09_1[] =
1044{
1045 {1343, 798},
1046 {1343, 794},
1047 {1343, 798},
1048 {1343, 794},
1049 {1343, 0},
1050 {1343, 0},
1051 { 0, 805},
1052 { 0, 794},
1053 { 0, 0}
1054};
1055
1056static const SiS_LVDSDesStruct SiS300_PanelType0a_1[] =
1057{
1058 {1059, 626},
1059 {1059, 624},
1060 {1059, 626},
1061 {1059, 624},
1062 {1059, 624},
1063 { 0, 627},
1064 { 0, 627},
1065 { 0, 0},
1066 { 0, 0}
1067};
1068
1069static const SiS_LVDSDesStruct SiS300_PanelType0b_1[] =
1070{
1071 {1343, 0},
1072 {1343, 0},
1073 {1343, 0},
1074 {1343, 0},
1075 {1343, 0},
1076 {1343, 0},
1077 { 0, 799},
1078 { 0, 0},
1079 { 0, 0}
1080};
1081
1082static const SiS_LVDSDesStruct SiS300_PanelType0c_1[] =
1083{
1084 {1343, 798},
1085 {1343, 794},
1086 {1343, 798},
1087 {1343, 794},
1088 {1343, 0},
1089 {1343, 0},
1090 { 0, 805},
1091 { 0, 794},
1092 { 0, 0}
1093};
1094
1095static const SiS_LVDSDesStruct SiS300_PanelType0d_1[] =
1096{
1097 {1343, 798},
1098 {1343, 794},
1099 {1343, 798},
1100 {1343, 794},
1101 {1343, 0},
1102 {1343, 0},
1103 { 0, 805},
1104 { 0, 794},
1105 { 0, 0}
1106};
1107
1108static const SiS_LVDSDesStruct SiS300_PanelType0e_1[] =
1109{
1110 {1343, 798},
1111 {1343, 794},
1112 {1343, 798},
1113 {1343, 794},
1114 {1343, 0}, /* 640x480 */
1115 {1343, 0}, /* 800x600 */
1116 { 0, 805}, /* 1024x768 */
1117 { 0, 794}, /* 1280x1024 */
1118 { 0, 0} /* 1280x960 - not applicable */
1119};
1120
1121static const SiS_LVDSDesStruct SiS300_PanelType0f_1[] =
1122{
1123 {1343, 798},
1124 {1343, 794},
1125 {1343, 798},
1126 {1343, 794},
1127 {1343, 0},
1128 {1343, 0},
1129 { 0, 805},
1130 { 0, 794},
1131 { 0, 0}
1132};
1133
1134static const SiS_LVDSDesStruct SiS300_PanelType00_2[] =
1135{
1136 {976, 527},
1137 {976, 502},
1138 {976, 527},
1139 {976, 502},
1140 {976, 567},
1141 { 0, 627},
1142 { 0, 627},
1143 { 0, 0},
1144 { 0, 0}
1145};
1146
1147static const SiS_LVDSDesStruct SiS300_PanelType01_2[] =
1148{
1149 {1152, 622},
1150 {1152, 597},
1151 {1152, 622},
1152 {1152, 597},
1153 {1152, 662},
1154 {1232, 722},
1155 { 0, 805},
1156 { 0, 794},
1157 { 0, 0}
1158};
1159
1160static const SiS_LVDSDesStruct SiS300_PanelType02_2[] =
1161{
1162 {976, 527},
1163 {976, 502},
1164 {976, 527},
1165 {976, 502},
1166 {976, 567},
1167 { 0, 627},
1168 { 0, 627},
1169 { 0, 0},
1170 { 0, 0}
1171};
1172
1173static const SiS_LVDSDesStruct SiS300_PanelType03_2[] =
1174{
1175 {1152, 622},
1176 {1152, 597},
1177 {1152, 622},
1178 {1152, 597},
1179 {1152, 662},
1180 {1232, 722},
1181 { 0, 805},
1182 {1152, 622},
1183 {1152, 597}
1184};
1185
1186static const SiS_LVDSDesStruct SiS300_PanelType04_2[] =
1187{
1188 {1152, 622},
1189 {1152, 597},
1190 {1152, 622},
1191 {1152, 597},
1192 {1152, 662},
1193 {1232, 722},
1194 { 0, 805},
1195 { 0, 794},
1196 { 0, 0}
1197};
1198
1199static const SiS_LVDSDesStruct SiS300_PanelType05_2[] =
1200{
1201 {1152, 622},
1202 {1152, 597},
1203 {1152, 622},
1204 {1152, 597},
1205 {1152, 662},
1206 {1232, 722},
1207 { 0, 805},
1208 { 0, 794},
1209 { 0, 0}
1210};
1211
1212static const SiS_LVDSDesStruct SiS300_PanelType06_2[] =
1213{
1214 {1152, 622},
1215 {1152, 597},
1216 {1152, 622},
1217 {1152, 597},
1218 {1152, 662},
1219 {1232, 722},
1220 { 0, 805},
1221 { 0, 794},
1222 { 0, 0}
1223};
1224
1225static const SiS_LVDSDesStruct SiS300_PanelType07_2[] =
1226{
1227 {1152, 622},
1228 {1152, 597},
1229 {1152, 622},
1230 {1152, 597},
1231 {1152, 662},
1232 {1232, 722},
1233 { 0, 805},
1234 { 0, 794},
1235 { 0, 0}
1236};
1237
1238static const SiS_LVDSDesStruct SiS300_PanelType08_2[] =
1239{
1240 {976, 527},
1241 {976, 502},
1242 {976, 527},
1243 {976, 502},
1244 {976, 567},
1245 { 0, 627},
1246 { 0, 627},
1247 { 0, 0},
1248 { 0, 0}
1249};
1250
1251static const SiS_LVDSDesStruct SiS300_PanelType09_2[] =
1252{
1253 {1152, 622},
1254 {1152, 597},
1255 {1152, 622},
1256 {1152, 597},
1257 {1152, 662},
1258 {1232, 722},
1259 { 0, 805},
1260 { 0, 794},
1261 { 0, 0}
1262};
1263
1264static const SiS_LVDSDesStruct SiS300_PanelType0a_2[] =
1265{
1266 {976, 527},
1267 {976, 502},
1268 {976, 527},
1269 {976, 502},
1270 {976, 567},
1271 { 0, 627},
1272 { 0, 627},
1273 { 0, 0},
1274 { 0, 0}
1275};
1276
1277static const SiS_LVDSDesStruct SiS300_PanelType0b_2[] =
1278{
1279 { 1152, 700},
1280 { 1152, 675},
1281 { 1152, 700},
1282 { 1152, 675},
1283 { 1152, 740},
1284 { 1232, 799},
1285 { 0, 799},
1286 { 0, 0},
1287 { 0, 0}
1288};
1289
1290static const SiS_LVDSDesStruct SiS300_PanelType0c_2[] =
1291{
1292 {1152, 622},
1293 {1152, 597},
1294 {1152, 622},
1295 {1152, 597},
1296 {1152, 662},
1297 {1232, 722},
1298 { 0, 805},
1299 { 0, 794},
1300 { 0, 0}
1301};
1302
1303static const SiS_LVDSDesStruct SiS300_PanelType0d_2[] =
1304{
1305 {1152, 622},
1306 {1152, 597},
1307 {1152, 622},
1308 {1152, 597},
1309 {1152, 662},
1310 {1232, 722},
1311 { 0, 805},
1312 { 0, 794},
1313 { 0, 0}
1314};
1315
1316static const SiS_LVDSDesStruct SiS300_PanelType0e_2[] =
1317{
1318 {1152, 622},
1319 {1152, 597},
1320 {1152, 622},
1321 {1152, 597},
1322 {1152, 662},
1323 {1232, 722},
1324 { 0, 805},
1325 { 0, 794},
1326 { 0, 0}
1327};
1328
1329static const SiS_LVDSDesStruct SiS300_PanelType0f_2[] =
1330{
1331 {1152, 622},
1332 {1152, 597},
1333 {1152, 622},
1334 {1152, 597},
1335 {1152, 662},
1336 {1232, 722},
1337 { 0, 805},
1338 { 0, 794},
1339 { 0, 0}
1340};
1341
1342static const SiS_LVDSDesStruct SiS300_PanelTypeNS_1[]=
1343{
1344 { 0, 0},
1345 { 0, 0},
1346 { 0, 0},
1347 { 0, 0},
1348 { 0, 0},
1349 { 0, 0},
1350 { 0, 805},
1351 { 0, 0},
1352 { 0, 0},
1353 { 0, 0}
1354};
1355
1356static const SiS_LVDSDesStruct SiS300_PanelTypeNS_2[] =
1357{
1358 { 0 , 0},
1359 { 0 , 0},
1360 { 0 , 0},
1361 { 0 , 0},
1362 { 0 , 0},
1363 { 0 , 0},
1364 { 0 , 0},
1365 { 0 , 0},
1366 { 0 , 0},
1367 { 0 , 0}
1368};
1369
1370/* Custom data for Barco iQ R200/300/400 (BIOS 2.00.07) */
1371static const SiS_LVDSDesStruct SiS300_PanelType04_1a[] = /* 1280x1024 (1366x1024) */
1372{
1373 {1330, 798}, /* 320x200 */
1374 {1330, 794},
1375 {1330, 798},
1376 {1330, 794},
1377 {1330, 0}, /* 640x480 / 320x240 */
1378 {1343, 0}, /* 800x600 / 400x300 */
1379 { 0, 805}, /* 1024x768 / 512x384 */
1380 {1688,1066}, /* 1280x1024 */
1381 { 0, 0} /* 1360x1024 */
1382};
1383
1384static const SiS_LVDSDesStruct SiS300_PanelType04_2a[] =
1385{
1386 {1152, 622},
1387 {1152, 597},
1388 {1152, 622},
1389 {1152, 597},
1390 {1152, 662},
1391 {1232, 722},
1392 { 0, 805},
1393 {1688,1066},
1394 { 0, 0}
1395};
1396
1397/* Custom data for Barco iQ G200/300/400 (BIOS 2.00.07) */
1398static const SiS_LVDSDesStruct SiS300_PanelType04_1b[] = /* 1024x768 */
1399{
1400 {1330, 798}, /* 320x200 */
1401 {1330, 794},
1402 {1330, 798},
1403 {1330, 794},
1404 {1330, 0}, /* 640x480 / 320x240 */
1405 {1343, 0}, /* 800x600 / 400x300 */
1406 { 0, 805} /* 1024x768 / 512x384 */
1407};
1408
1409static const SiS_LVDSDesStruct SiS300_PanelType04_2b[] =
1410{
1411 {1152, 622},
1412 {1152, 597},
1413 {1152, 622},
1414 {1152, 597},
1415 {1152, 662},
1416 {1232, 722},
1417 { 0, 805}
1418};
1419
1420/* CRT1 CRTC for slave modes */
1421
1422static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT1800x600_1[] =
1423{
1424 {{0x65,0x4f,0x89,0x56,0x83,0xaf,0x1f,
1425 0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
1426 0x00 }},
1427 {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
1428 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
1429 0x00 }},
1430 {{0x65,0x4f,0x89,0x56,0x83,0xaf,0x1f,
1431 0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
1432 0x00 }},
1433 {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
1434 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
1435 0x00 }},
1436 {{0x65,0x4f,0x89,0x56,0x83,0x04,0x3e,
1437 0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
1438 0x00 }},
1439 {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
1440 0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
1441 0x01 }}
1442};
1443
1444static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT1800x600_1_H[] =
1445{
1446 {{0x30,0x27,0x94,0x2c,0x92,0xaf,0x1f,
1447 0x90,0x85,0x8f,0xab,0x30,0x00,0x04,
1448 0x00 }},
1449 {{0x30,0x27,0x94,0x2c,0x92,0x83,0x1f,
1450 0x5e,0x83,0x5d,0x79,0x10,0x00,0x04,
1451 0x00 }},
1452 {{0x30,0x27,0x94,0x2c,0x92,0xaf,0x1f,
1453 0x90,0x85,0x8f,0xab,0x30,0x00,0x04,
1454 0x00 }},
1455 {{0x30,0x27,0x94,0x2c,0x92,0x83,0x1f,
1456 0x5e,0x83,0x5d,0x79,0x10,0x00,0x04,
1457 0x00 }},
1458 {{0x30,0x27,0x94,0x2c,0x92,0x04,0x3e,
1459 0xe0,0x85,0xdf,0xfb,0x10,0x00,0x04,
1460 0x00 }},
1461 {{0x3d,0x31,0x81,0x37,0x1f,0x72,0xf0,
1462 0x58,0x8c,0x57,0x73,0x20,0x00,0x05,
1463 0x01 }}
1464};
1465
1466static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT11024x768_1[] =
1467{
1468 {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
1469 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
1470 0x00}},
1471 {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
1472 0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
1473 0x00}},
1474 {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
1475 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
1476 0x00}},
1477 {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
1478 0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
1479 0x00}},
1480 {{0x64,0x4f,0x88,0x54,0x9f,0x04,0x3e,
1481 0xe2,0x89,0xdf,0x05,0x00,0x00,0x01,
1482 0x00}},
1483 {{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0,
1484 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26,
1485 0x01}},
1486 {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
1487 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
1488 0x01}}
1489};
1490
1491static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT11024x768_1_H[] =
1492{
1493 {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
1494 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
1495 0x00 }},
1496 {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
1497 0x60,0x87,0x5D,0x83,0x10,0x00,0x44,
1498 0x00}},
1499 {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
1500 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
1501 0x00}},
1502 {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
1503 0x60,0x87,0x5D,0x83,0x10,0x00,0x44,
1504 0x00}},
1505 {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
1506 0xE2,0x89,0xdf,0x05,0x00,0x00,0x44,
1507 0x00}},
1508 {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
1509 0x5A,0x8F,0x57,0x7D,0x20,0x00,0x55,
1510 0x01}},
1511 {{0x4f,0x3F,0x93,0x45,0x0D,0x24,0xf5,
1512 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
1513 0x01 }}
1514
1515#if 0
1516 {{0x37,0x27,0x9B,0x2b,0x94,0xc4,0x1f,
1517 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
1518 0x00 }},
1519 {{0x37,0x27,0x9B,0x2b,0x94,0x97,0x1f,
1520 0x60,0x87,0x5D,0x83,0x01,0x00,0x44,
1521 0x00}},
1522 {{0x37,0x27,0x9B,0x2b,0x94,0xc4,0x1f,
1523 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
1524 0x00}},
1525 {{0x37,0x27,0x9B,0x2b,0x94,0x97,0x1f,
1526 0x60,0x87,0x5D,0x83,0x01,0x00,0x44,
1527 0x00}},
1528 {{0x37,0x27,0x9B,0x2b,0x94,0x04,0x3e,
1529 0xE2,0x89,0xDf,0x05,0x00,0x00,0x44,
1530 0x00}},
1531 {{0x41,0x31,0x85,0x35,0x1d,0x7c,0xf0,
1532 0x5A,0x8F,0x57,0x7D,0x20,0x00,0x55,
1533 0x01}},
1534 {{0x4f,0x3F,0x93,0x45,0x0D,0x24,0xf5,
1535 0x02,0x88,0xFf,0x25,0x10,0x00,0x01,
1536 0x01 }}
1537#endif
1538};
1539
1540static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT11280x1024_1[] =
1541{
1542 {{0x63,0x4f,0x87,0x54,0x9f,0xb4,0x1f,
1543 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
1544 0x00 }},
1545 {{0x63,0x4f,0x87,0x54,0x9f,0x82,0x1f,
1546 0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
1547 0x00 }},
1548 {{0x63,0x4f,0x87,0x54,0x9f,0xb4,0x1f,
1549 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
1550 0x00 }},
1551 {{0x63,0x4f,0x87,0x54,0x9f,0x82,0x1f,
1552 0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
1553 0x00 }},
1554 {{0x63,0x4f,0x87,0x54,0x9f,0x04,0x3e,
1555 0xe2,0x89,0xdf,0x05,0x00,0x00,0x01,
1556 0x00 }},
1557 {{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0,
1558 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26,
1559 0x01 }},
1560 {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
1561 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
1562 0x01 }}
1563};
1564
1565static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT11280x1024_1_H[] =
1566{
1567 {{0x2f,0x27,0x93,0x2b,0x90,0xb4,0x1f,
1568 0x92,0x89,0x8f,0xb5,0x30,0x00,0x04,
1569 0x00 }},
1570 {{0x2f,0x27,0x93,0x2b,0x90,0x82,0x1f,
1571 0x60,0x87,0x5d,0x83,0x10,0x00,0x04,
1572 0x00 }},
1573 {{0x2f,0x27,0x93,0x2b,0x90,0xb4,0x1f,
1574 0x92,0x89,0x8f,0xb5,0x30,0x00,0x04,
1575 0x00 }},
1576 {{0x2f,0x27,0x93,0x2b,0x90,0x82,0x1f,
1577 0x60,0x87,0x5d,0x83,0x10,0x00,0x04,
1578 0x00 }},
1579 {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
1580 0xe2,0x89,0xdf,0x05,0x00,0x00,0x04,
1581 0x00 }},
1582 {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
1583 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
1584 0x01 }},
1585 {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
1586 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
1587 0x01 }}
1588};
1589
1590static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT1800x600_2[] =
1591{
1592 {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
1593 0xf4,0x88,0x8f,0x73,0x20,0x00,0x06,
1594 0x00 }},
1595 {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
1596 0xdb,0x8f,0x5d,0x73,0x20,0x00,0x06,
1597 0x00 }},
1598 {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
1599 0xf4,0x88,0x8f,0x73,0x20,0x00,0x06,
1600 0x00 }},
1601 {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
1602 0xdb,0x8f,0x5d,0x73,0x20,0x00,0x06,
1603 0x00 }},
1604 {{0x7f,0x4f,0x83,0x62,0x12,0x72,0xba,
1605 0x1c,0x80,0xdf,0x73,0x00,0x00,0x06,
1606 0x00 }},
1607 {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
1608 0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
1609 0x01 }}
1610};
1611
1612static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT1800x600_2_H[] =
1613{
1614 {{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
1615 0xf4,0x88,0x8f,0x73,0x20,0x00,0x05,
1616 0x00 }},
1617 {{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
1618 0xdb,0x8f,0x5d,0x73,0x20,0x00,0x05,
1619 0x00 }},
1620 {{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
1621 0xf4,0x88,0x8f,0x73,0x20,0x00,0x05,
1622 0x00 }},
1623 {{0x3d,0x27,0x81,0x3a,0x1a,0x72,0x3e,
1624 0xdb,0x8f,0x5d,0x73,0x20,0x00,0x05,
1625 0x00 }},
1626 {{0x3d,0x27,0x81,0x32,0x1a,0x72,0xba,
1627 0x1c,0x80,0xdf,0x73,0x00,0x00,0x05,
1628 0x00 }},
1629 {{0x3d,0x31,0x81,0x37,0x1f,0x72,0xf0,
1630 0x58,0x8c,0x57,0x73,0x20,0x00,0x05,
1631 0x01 }}
1632};
1633
1634static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT11024x768_2[] =
1635{
1636 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1637 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
1638 0x00 }},
1639 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1640 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
1641 0x00 }},
1642 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1643 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
1644 0x00 }},
1645 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1646 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
1647 0x00 }},
1648 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1649 0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
1650 0x00 }},
1651 {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
1652 0xae,0x84,0x57,0x25,0x30,0x00,0x02,
1653 0x01 }},
1654 {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
1655 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
1656 0x01 }}
1657};
1658
1659static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT11024x768_2_H[] =
1660{
1661 {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
1662 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
1663 0x00 }},
1664 {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
1665 0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
1666 0x00 }},
1667 {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
1668 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
1669 0x00 }},
1670 {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
1671 0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
1672 0x00 }},
1673 {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
1674 0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
1675 0x00 }},
1676 {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
1677 0xae,0x84,0x57,0x25,0x30,0x00,0x01,
1678 0x01 }},
1679 {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
1680 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
1681 0x01 }}
1682};
1683
1684static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT11280x1024_2[] =
1685{
1686 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1687 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
1688 0x00 }},
1689 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1690 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
1691 0x00 }},
1692 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1693 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
1694 0x00 }},
1695 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1696 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
1697 0x00 }},
1698 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1699 0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
1700 0x00 }},
1701 {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
1702 0xae,0x84,0x57,0x25,0x30,0x00,0x02,
1703 0x01 }},
1704 {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
1705 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
1706 0x01 }}
1707};
1708
1709static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT11280x1024_2_H[] =
1710{
1711 {{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
1712 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
1713 0x00 }},
1714 {{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
1715 0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
1716 0x00 }},
1717 {{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
1718 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
1719 0x00 }},
1720 {{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
1721 0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
1722 0x00 }},
1723 {{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
1724 0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
1725 0x00 }},
1726 {{0x4f,0x31,0x93,0x3e,0x86,0x24,0xf1,
1727 0xae,0x84,0x57,0x25,0x30,0x00,0x01,
1728 0x01 }},
1729 {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
1730 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
1731 0x01}}
1732};
1733
1734static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT1XXXxXXX_1[] =
1735{
1736 {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
1737 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
1738 0x00}},
1739 {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
1740 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
1741 0x00}},
1742 {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
1743 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
1744 0x00}},
1745 {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
1746 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
1747 0x00}},
1748 {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
1749 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x05,
1750 0x00}},
1751 {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
1752 0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
1753 0x01}},
1754 {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
1755 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
1756 0x01}},
1757 {{0xce,0x9f,0x92,0xa8,0x14,0x28,0x5a,
1758 0x00,0x84,0xff,0x29,0x09,0x00,0x07,
1759 0x01}},
1760 {{0xce,0x9f,0x92,0xa9,0x17,0x24,0xf5,
1761 0x02,0x88,0xff,0x25,0x10,0x00,0x07,
1762 0x01}}
1763};
1764
1765static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT1XXXxXXX_1_H[] =
1766{
1767 {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
1768 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
1769 0x00}},
1770 {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
1771 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
1772 0x00}},
1773 {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
1774 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
1775 0x00}},
1776 {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
1777 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
1778 0x00}},
1779 {{0x38,0x27,0x9c,0x2c,0x80,0x0b,0x3e,
1780 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
1781 0x00}},
1782 {{0x4d,0x31,0x91,0x3b,0x03,0x72,0xf0,
1783 0x58,0x8c,0x57,0x73,0x20,0x00,0x01,
1784 0x01}},
1785 {{0x63,0x3f,0x87,0x4a,0x92,0x24,0xf5,
1786 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
1787 0x01}}
1788};
1789
1790
1791static const SiS_LVDSCRT1DataStruct SiS300_CHTVCRT1UNTSC[] =
1792{
1793 {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
1794 0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,
1795 0x00 }},
1796 {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
1797 0xd0,0x82,0x5d,0x57,0x00,0x00,0x01,
1798 0x00 }},
1799 {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
1800 0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,
1801 0x00 }},
1802 {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
1803 0xd0,0x82,0x5d,0x57,0x00,0x00,0x01,
1804 0x00 }},
1805 {{0x5d,0x4f,0x81,0x53,0x9c,0x56,0xba,
1806 0x18,0x84,0xdf,0x57,0x00,0x00,0x01,
1807 0x00 }},
1808 {{0x80,0x63,0x84,0x6c,0x17,0xec,0xf0,
1809 0x90,0x8c,0x57,0xed,0x20,0x00,0x06,
1810 0x01 }}
1811};
1812
1813static const SiS_LVDSCRT1DataStruct SiS300_CHTVCRT1ONTSC[] =
1814{
1815 {{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
1816 0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,
1817 0x00 }},
1818 {{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
1819 0xb0,0x8d,0x5d,0x0c,0x00,0x00,0x01,
1820 0x00 }},
1821 {{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
1822 0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,
1823 0x00 }},
1824 {{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
1825 0xb0,0x8d,0x5d,0x0c,0x00,0x00,0x01,
1826 0x00 }},
1827 {{0x5d,0x4f,0x81,0x56,0x9c,0x0b,0x3e,
1828 0xe8,0x84,0xdf,0x0c,0x00,0x00,0x01,
1829 0x00 }},
1830 {{0x7d,0x63,0x81,0x6a,0x16,0xba,0xf0,
1831 0x7f,0x86,0x57,0xbb,0x00,0x00,0x06,
1832 0x01 }}
1833};
1834
1835static const SiS_LVDSCRT1DataStruct SiS300_CHTVCRT1UPAL[] =
1836{
1837 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
1838 0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,
1839 0x00 }},
1840 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
1841 0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
1842 0x00 }},
1843 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
1844 0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,
1845 0x00 }},
1846 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
1847 0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
1848 0x00 }},
1849 {{0x64,0x4f,0x88,0x55,0x80,0xec,0xba,
1850 0x50,0x84,0xdf,0xed,0x00,0x00,0x05,
1851 0x00 }},
1852 {{0x70,0x63,0x94,0x68,0x8d,0x42,0xf1,
1853 0xc8,0x8c,0x57,0xe9,0x20,0x00,0x05,
1854 0x01 }}
1855};
1856
1857static const SiS_LVDSCRT1DataStruct SiS300_CHTVCRT1OPAL[] =
1858{
1859 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
1860 0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
1861 0x00 }},
1862 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
1863 0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
1864 0x00 }},
1865 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
1866 0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
1867 0x00 }},
1868 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
1869 0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
1870 0x00 }},
1871 {{0x64,0x4f,0x88,0x55,0x80,0x6f,0xba,
1872 0x20,0x83,0xdf,0x70,0x00,0x00,0x05,
1873 0x00 }},
1874 {{0x73,0x63,0x97,0x69,0x8e,0xec,0xf0,
1875 0x90,0x8c,0x57,0xed,0x20,0x00,0x05,
1876 0x01 }}
1877};
1878
1879static const SiS_LVDSCRT1DataStruct SiS300_CHTVCRT1SOPAL[] =
1880{
1881 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
1882 0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
1883 0x00 }},
1884 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
1885 0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
1886 0x00 }},
1887 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
1888 0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
1889 0x00 }},
1890 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
1891 0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
1892 0x00 }},
1893 {{0x64,0x4f,0x88,0x55,0x80,0x6f,0xba, /* TODO */
1894 0x20,0x83,0xdf,0x70,0x00,0x00,0x05,
1895 0x00 }},
1896 {{0x73,0x63,0x97,0x69,0x8e,0xec,0xf0, /* TODO */
1897 0x90,0x8c,0x57,0xed,0x20,0x00,0x05,
1898 0x01 }}
1899};
1900
1901static const SiS_CHTVRegDataStruct SiS300_CHTVReg_UNTSC[] =
1902{
1903 {{0x4a,0x94,0x00,0x48,0xfe,0,0,0,0,0,0,0,0,0,0,0}},
1904 {{0x4a,0x94,0x00,0x48,0xfe,0,0,0,0,0,0,0,0,0,0,0}},
1905 {{0x4a,0x94,0x00,0x48,0xfe,0,0,0,0,0,0,0,0,0,0,0}},
1906 {{0x4a,0x94,0x00,0x48,0xfe,0,0,0,0,0,0,0,0,0,0,0}},
1907 {{0x6a,0x6a,0x00,0x2d,0xfa,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 17: 640x480 NTSC 7/8 */
1908 {{0x8d,0xc4,0x00,0x3b,0xfb,0,0,0,0,0,0,0,0,0,0,0}} /* Mode 24: 800x600 NTSC 7/10 */
1909};
1910
1911static const SiS_CHTVRegDataStruct SiS300_CHTVReg_ONTSC[] =
1912{
1913 {{0x49,0x94,0x00,0x34,0xfe,0,0,0,0,0,0,0,0,0,0,0}},
1914 {{0x49,0x94,0x00,0x34,0xfe,0,0,0,0,0,0,0,0,0,0,0}},
1915 {{0x49,0x94,0x00,0x34,0xfe,0,0,0,0,0,0,0,0,0,0,0}},
1916 {{0x49,0x94,0x00,0x34,0xfe,0,0,0,0,0,0,0,0,0,0,0}},
1917 {{0x69,0x6a,0x00,0x1e,0xfd,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 16: 640x480 NTSC 1/1 */
1918 {{0x8c,0xb4,0x00,0x32,0xf9,0,0,0,0,0,0,0,0,0,0,0}} /* Mode 23: 800x600 NTSC 3/4 */
1919};
1920
1921static const SiS_CHTVRegDataStruct SiS300_CHTVReg_UPAL[] =
1922{
1923 {{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}},
1924 {{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}},
1925 {{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}},
1926 {{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}},
1927 {{0x63,0x94,0x01,0x50,0x30,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 15: 640x480 PAL 5/6 */
1928 {{0x84,0x64,0x01,0x4e,0x2f,0,0,0,0,0,0,0,0,0,0,0}} /* Mode 21: 800x600 PAL 3/4 */
1929
1930};
1931
1932static const SiS_CHTVRegDataStruct SiS300_CHTVReg_OPAL[] =
1933{
1934 {{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 9: 640x400 PAL 1/1 */
1935 {{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}},
1936 {{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}},
1937 {{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}},
1938 {{0x61,0x94,0x01,0x36,0x30,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 14: 640x480 PAL 1/1 */
1939 {{0x83,0x76,0x01,0x40,0x31,0,0,0,0,0,0,0,0,0,0,0}} /* Mode 20: 800x600 PAL 5/6 */
1940
1941};
1942
1943static const SiS_CHTVRegDataStruct SiS300_CHTVReg_SOPAL[] =
1944{
1945 {{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 9: 640x400 PAL 1/1 */
1946 {{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}},
1947 {{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}},
1948 {{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}},
1949 {{0x60,0x30,0x00,0x10,0x00,0,0,0,0,0,0,0,0,0,0,0}}, /* TW: Mode 13: 640x480 PAL 5/4 */
1950 {{0x81,0x50,0x00,0x1b,0x00,0,0,0,0,0,0,0,0,0,0,0}} /* TW: Mode 19: 800x600 PAL 1/1 */
1951};
1952
1953static const UCHAR SiS300_CHTVVCLKUNTSC[] = {0x29,0x29,0x29,0x29,0x2a,0x2e};
1954
1955static const UCHAR SiS300_CHTVVCLKONTSC[] = {0x2c,0x2c,0x2c,0x2c,0x2d,0x2b};
1956
1957static const UCHAR SiS300_CHTVVCLKSONTSC[] = {0x2c,0x2c,0x2c,0x2c,0x2d,0x2b};
1958
1959static const UCHAR SiS300_CHTVVCLKUPAL[] = {0x2f,0x2f,0x2f,0x2f,0x2f,0x31};
1960
1961static const UCHAR SiS300_CHTVVCLKOPAL[] = {0x2f,0x2f,0x2f,0x2f,0x30,0x32};
1962
1963static const UCHAR SiS300_CHTVVCLKSOPAL[] = {0x2f,0x2f,0x2f,0x2f,0x36,0x29};
1964
1965
diff --git a/drivers/video/sis/310vtbl.h b/drivers/video/sis/310vtbl.h
new file mode 100644
index 000000000000..2c71d048f7c4
--- /dev/null
+++ b/drivers/video/sis/310vtbl.h
@@ -0,0 +1,2754 @@
1/* $XFree86$ */
2/* $XdotOrg$ */
3/*
4 * Register settings for SiS 315/330 series
5 *
6 * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
7 *
8 * If distributed as part of the Linux kernel, the following license terms
9 * apply:
10 *
11 * * This program is free software; you can redistribute it and/or modify
12 * * it under the terms of the GNU General Public License as published by
13 * * the Free Software Foundation; either version 2 of the named License,
14 * * or any later version.
15 * *
16 * * This program is distributed in the hope that it will be useful,
17 * * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * * GNU General Public License for more details.
20 * *
21 * * You should have received a copy of the GNU General Public License
22 * * along with this program; if not, write to the Free Software
23 * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
24 *
25 * Otherwise, the following license terms apply:
26 *
27 * * Redistribution and use in source and binary forms, with or without
28 * * modification, are permitted provided that the following conditions
29 * * are met:
30 * * 1) Redistributions of source code must retain the above copyright
31 * * notice, this list of conditions and the following disclaimer.
32 * * 2) Redistributions in binary form must reproduce the above copyright
33 * * notice, this list of conditions and the following disclaimer in the
34 * * documentation and/or other materials provided with the distribution.
35 * * 3) The name of the author may not be used to endorse or promote products
36 * * derived from this software without specific prior written permission.
37 * *
38 * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
39 * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
40 * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
41 * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
42 * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
43 * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
44 * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
45 * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46 * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
47 * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48 *
49 * Author: Thomas Winischhofer <thomas@winischhofer.net>
50 *
51 */
52
53static const SiS_StStruct SiS310_SModeIDTable[]=
54{
55 {0x01,0x9208,0x01,0x00,0x00,0x00,0x01,0x00, 0x40},
56 {0x01,0x1210,0x14,0x01,0x01,0x00,0x01,0x00, 0x40},
57 {0x01,0x1010,0x17,0x02,0x02,0x00,0x01,0x01, 0x40},
58 {0x03,0x8208,0x03,0x00,0x00,0x00,0x01,0x02, 0x40},
59 {0x03,0x0210,0x16,0x01,0x01,0x00,0x01,0x02, 0x40},
60 {0x03,0x0010,0x18,0x02,0x02,0x00,0x01,0x03, 0x40},
61 {0x05,0x9209,0x05,0x00,0x00,0x00,0x00,0x04, 0x40},
62 {0x06,0x8209,0x06,0x00,0x00,0x00,0x00,0x05, 0x40},
63 {0x07,0x0000,0x07,0x03,0x03,0x00,0x01,0x03, 0x40},
64 {0x07,0x0000,0x19,0x02,0x02,0x00,0x01,0x03, 0x40},
65 {0x0d,0x920a,0x0d,0x00,0x00,0x00,0x00,0x04, 0x40},
66 {0x0e,0x820a,0x0e,0x00,0x00,0x00,0x00,0x05, 0x40},
67 {0x0f,0x0202,0x11,0x01,0x01,0x00,0x00,0x05, 0x40},
68 {0x10,0x0212,0x12,0x01,0x01,0x00,0x00,0x05, 0x40},
69 {0x11,0x0212,0x1a,0x04,0x04,0x00,0x00,0x05, 0x40},
70 {0x12,0x0212,0x1b,0x04,0x04,0x00,0x00,0x05, 0x40},
71 {0x13,0x021b,0x1c,0x00,0x00,0x00,0x00,0x04, 0x40},
72 {0x12,0x0010,0x18,0x02,0x02,0x00,0x00,0x05, 0x40},
73 {0x12,0x0210,0x18,0x01,0x01,0x00,0x00,0x05, 0x40},
74 {0xff,0x0000,0x00,0x00,0x00,0x00,0x00,0x00, 0x40}
75};
76
77static const SiS_ExtStruct SiS310_EModeIDTable[]=
78{
79 {0x6a,0x2212,0x0102,SIS_RI_800x600, 0x00,0x00,0x07,0x06,0x00, 3}, /* 800x600x? */
80 {0x2e,0x0a1b,0x0101,SIS_RI_640x480, 0x00,0x00,0x05,0x05,0x08, 2}, /* 640x480x8 */
81 {0x2f,0x0a1b,0x0100,SIS_RI_640x400, 0x00,0x00,0x05,0x05,0x10, 0}, /* 640x400x8 */
82 {0x30,0x2a1b,0x0103,SIS_RI_800x600, 0x00,0x00,0x07,0x06,0x00, 3}, /* 800x600x8 */
83 {0x31,0x4a1b,0x0000,SIS_RI_720x480, 0x00,0x00,0x06,0x06,0x11,-1}, /* 720x480x8 */
84 {0x32,0x4a1b,0x0000,SIS_RI_720x576, 0x00,0x00,0x06,0x06,0x12,-1}, /* 720x576x8 */
85 {0x33,0x4a1d,0x0000,SIS_RI_720x480, 0x00,0x00,0x06,0x06,0x11,-1}, /* 720x480x16 */
86 {0x34,0x6a1d,0x0000,SIS_RI_720x576, 0x00,0x00,0x06,0x06,0x12,-1}, /* 720x576x16 */
87 {0x35,0x4a1f,0x0000,SIS_RI_720x480, 0x00,0x00,0x06,0x06,0x11,-1}, /* 720x480x32 */
88 {0x36,0x6a1f,0x0000,SIS_RI_720x576, 0x00,0x00,0x06,0x06,0x12,-1}, /* 720x576x32 */
89 {0x37,0x0212,0x0104,SIS_RI_1024x768, 0x00,0x00,0x08,0x07,0x13, 4}, /* 1024x768x? */
90 {0x38,0x0a1b,0x0105,SIS_RI_1024x768, 0x00,0x00,0x08,0x07,0x13, 4}, /* 1024x768x8 */
91 {0x3a,0x0e3b,0x0107,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a, 8}, /* 1280x1024x8 */
92 {0x3c,0x0e3b,0x0130,SIS_RI_1600x1200,0x00,0x00,0x00,0x00,0x1e,10}, /* 1600x1200x8 */
93 {0x3d,0x0e7d,0x0131,SIS_RI_1600x1200,0x00,0x00,0x00,0x00,0x1e,10}, /* 1600x1200x16 */
94 {0x40,0x9a1c,0x010d,SIS_RI_320x200, 0x00,0x00,0x04,0x04,0x25, 0}, /* 320x200x15 */
95 {0x41,0x9a1d,0x010e,SIS_RI_320x200, 0x00,0x00,0x04,0x04,0x25, 0}, /* 320x200x16 */
96 {0x43,0x0a1c,0x0110,SIS_RI_640x480, 0x00,0x00,0x05,0x05,0x08, 2},
97 {0x44,0x0a1d,0x0111,SIS_RI_640x480, 0x00,0x00,0x05,0x05,0x08, 2}, /* 640x480x16 */
98 {0x46,0x2a1c,0x0113,SIS_RI_800x600, 0x00,0x00,0x07,0x06,0x00, 3},
99 {0x47,0x2a1d,0x0114,SIS_RI_800x600, 0x00,0x00,0x07,0x06,0x00, 3}, /* 800x600x16 */
100 {0x49,0x0a3c,0x0116,SIS_RI_1024x768, 0x00,0x00,0x00,0x07,0x13, 4},
101 {0x4a,0x0a3d,0x0117,SIS_RI_1024x768, 0x00,0x00,0x08,0x07,0x13, 4}, /* 1024x768x16 */
102 {0x4c,0x0e7c,0x0119,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a, 8},
103 {0x4d,0x0e7d,0x011a,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a, 8}, /* 1280x1024x16 */
104 {0x50,0x9a1b,0x0132,SIS_RI_320x240, 0x00,0x00,0x04,0x04,0x26, 2}, /* 320x240x8 */
105 {0x51,0xba1b,0x0133,SIS_RI_400x300, 0x00,0x00,0x07,0x07,0x27, 3}, /* 400x300x8 */
106 {0x52,0xba1b,0x0134,SIS_RI_512x384, 0x00,0x00,0x00,0x00,0x28, 4}, /* 512x384x8 */
107 {0x56,0x9a1d,0x0135,SIS_RI_320x240, 0x00,0x00,0x04,0x04,0x26, 2}, /* 320x240x16 */
108 {0x57,0xba1d,0x0136,SIS_RI_400x300, 0x00,0x00,0x07,0x07,0x27, 3}, /* 400x300x16 */
109 {0x58,0xba1d,0x0137,SIS_RI_512x384, 0x00,0x00,0x00,0x00,0x28, 4}, /* 512x384x16 */
110 {0x59,0x9a1b,0x0138,SIS_RI_320x200, 0x00,0x00,0x04,0x04,0x25, 0}, /* 320x200x8 */
111 {0x5a,0x021b,0x0138,SIS_RI_320x240, 0x00,0x00,0x00,0x00,0x3f, 2}, /* 320x240x8 fstn */
112 {0x5b,0x0a1d,0x0135,SIS_RI_320x240, 0x00,0x00,0x00,0x00,0x3f, 2}, /* 320x240x16 fstn */
113 {0x5c,0xba1f,0x0000,SIS_RI_512x384, 0x00,0x00,0x00,0x00,0x28, 4}, /* 512x384x32 */
114 {0x5d,0x0a1d,0x0139,SIS_RI_640x400, 0x00,0x00,0x05,0x07,0x10, 0},
115 {0x5e,0x0a1f,0x0000,SIS_RI_640x400, 0x00,0x00,0x05,0x07,0x10, 0}, /* 640x400x32 */
116 {0x62,0x0a3f,0x013a,SIS_RI_640x480, 0x00,0x00,0x05,0x05,0x08, 2}, /* 640x480x32 */
117 {0x63,0x2a3f,0x013b,SIS_RI_800x600, 0x00,0x00,0x07,0x06,0x00, 3}, /* 800x600x32 */
118 {0x64,0x0a7f,0x013c,SIS_RI_1024x768, 0x00,0x00,0x08,0x07,0x13, 4}, /* 1024x768x32 */
119 {0x65,0x0eff,0x013d,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a, 8}, /* 1280x1024x32 */
120 {0x66,0x0eff,0x013e,SIS_RI_1600x1200,0x00,0x00,0x00,0x00,0x1e,10}, /* 1600x1200x32 */
121 {0x68,0x067b,0x013f,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x29,-1}, /* 1920x1440x8 */
122 {0x69,0x06fd,0x0140,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x29,-1}, /* 1920x1440x16 */
123 {0x6b,0x07ff,0x0141,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x29,-1}, /* 1920x1440x32 */
124 {0x6c,0x067b,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x00,0x2f,-1}, /* 2048x1536x8 */
125 {0x6d,0x06fd,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x00,0x2f,-1}, /* 2048x1536x16 */
126 {0x6e,0x07ff,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x00,0x2f,-1}, /* 2048x1536x32 */
127 {0x70,0x6a1b,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x07,0x34,-1}, /* 800x480x8 */
128 {0x71,0x4a1b,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x37,-1}, /* 1024x576x8 */
129 {0x74,0x4a1d,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x37,-1}, /* 1024x576x16 */
130 {0x75,0x0a3d,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x3a, 5}, /* 1280x720x16 */
131 {0x76,0x6a1f,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x07,0x34,-1}, /* 800x480x32 */
132 {0x77,0x4a1f,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x37,-1}, /* 1024x576x32 */
133 {0x78,0x0a3f,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x3a, 5}, /* 1280x720x32 */
134 {0x79,0x0a3b,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x3a, 5}, /* 1280x720x8 */
135 {0x7a,0x6a1d,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x07,0x34,-1}, /* 800x480x16 */
136 {0x7c,0x0e3b,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x00,0x3d,-1}, /* 1280x960x8 */
137 {0x7d,0x0e7d,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x00,0x3d,-1}, /* 1280x960x16 */
138 {0x7e,0x0eff,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x00,0x3d,-1}, /* 1280x960x32 */
139 {0x23,0x0e3b,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x40, 6}, /* 1280x768x8 */
140 {0x24,0x0e7d,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x40, 6}, /* 1280x768x16 */
141 {0x25,0x0eff,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x40, 6}, /* 1280x768x32 */
142 {0x26,0x0e3b,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x00,0x41, 9}, /* 1400x1050x8 */
143 {0x27,0x0e7d,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x00,0x41, 9}, /* 1400x1050x16 */
144 {0x28,0x0eff,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x00,0x41, 9}, /* 1400x1050x32*/
145 {0x29,0x4e1b,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x43,-1}, /* 1152x864 */
146 {0x2a,0x4e3d,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x43,-1},
147 {0x2b,0x4e7f,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x43,-1},
148 {0x39,0x6a1b,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x00,0x46,-1}, /* 848x480 */
149 {0x3b,0x6a3d,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x00,0x46,-1},
150 {0x3e,0x6a7f,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x00,0x46,-1},
151 {0x3f,0x6a1b,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x00,0x48,-1}, /* 856x480 */
152 {0x42,0x6a3d,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x00,0x48,-1},
153 {0x45,0x6a7f,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x00,0x48,-1},
154 {0x48,0x6a3b,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x4a,-1}, /* 1360x768 */
155 {0x4b,0x6a7d,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x4a,-1},
156 {0x4e,0x6aff,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x4a,-1},
157 {0x4f,0x9a1f,0x0000,SIS_RI_320x200, 0x00,0x00,0x04,0x04,0x25, 0}, /* 320x200x32 */
158 {0x53,0x9a1f,0x0000,SIS_RI_320x240, 0x00,0x00,0x04,0x04,0x26, 2}, /* 320x240x32 */
159 {0x54,0xba1f,0x0000,SIS_RI_400x300, 0x00,0x00,0x07,0x07,0x27, 3}, /* 400x300x32 */
160 {0x5f,0x6a1b,0x0000,SIS_RI_768x576, 0x00,0x00,0x06,0x06,0x4b,-1}, /* 768x576 */
161 {0x60,0x6a1d,0x0000,SIS_RI_768x576, 0x00,0x00,0x06,0x06,0x4b,-1},
162 {0x61,0x6a3f,0x0000,SIS_RI_768x576, 0x00,0x00,0x06,0x06,0x4b,-1},
163 {0x14,0x0e3b,0x0000,SIS_RI_1280x800, 0x00,0x00,0x00,0x00,0x4c, 7}, /* 1280x800 */
164 {0x15,0x0e7d,0x0000,SIS_RI_1280x800, 0x00,0x00,0x00,0x00,0x4c, 7},
165 {0x16,0x0eff,0x0000,SIS_RI_1280x800, 0x00,0x00,0x00,0x00,0x4c, 7},
166 {0x17,0x0e3b,0x0000,SIS_RI_1680x1050,0x00,0x00,0x00,0x00,0x4d, 9}, /* 1680x1050 */
167 {0x18,0x0e7d,0x0000,SIS_RI_1680x1050,0x00,0x00,0x00,0x00,0x4d, 9},
168 {0x19,0x0eff,0x0000,SIS_RI_1680x1050,0x00,0x00,0x00,0x00,0x4d, 9},
169 {0x2c,0x267b,0x0000,SIS_RI_1920x1080,0x00,0x00,0x00,0x00,0x4e,-1}, /* 1920x1080(i) */
170 {0x2d,0x26fd,0x0000,SIS_RI_1920x1080,0x00,0x00,0x00,0x00,0x4e,-1},
171 {0x73,0x27ff,0x0000,SIS_RI_1920x1080,0x00,0x00,0x00,0x00,0x4e,-1},
172 {0x1d,0x6a1b,0x0000,SIS_RI_960x540, 0x00,0x00,0x00,0x00,0x4f,-1}, /* 960x540 */
173 {0x1e,0x6a3d,0x0000,SIS_RI_960x540, 0x00,0x00,0x00,0x00,0x4f,-1},
174 {0x1f,0x6a7f,0x0000,SIS_RI_960x540, 0x00,0x00,0x00,0x00,0x4f,-1},
175 {0x20,0x6a1b,0x0000,SIS_RI_960x600, 0x00,0x00,0x00,0x00,0x50,-1}, /* 960x600 */
176 {0x21,0x6a3d,0x0000,SIS_RI_960x600, 0x00,0x00,0x00,0x00,0x50,-1},
177 {0x22,0x6a7f,0x0000,SIS_RI_960x600, 0x00,0x00,0x00,0x00,0x50,-1},
178 {0xff,0x0000,0x0000,0, 0x00,0x00,0x00,0x00,0x00,-1}
179};
180
181static const SiS_Ext2Struct SiS310_RefIndex[]=
182{
183 {0x085f,0x0d,0x03,0x05,0x05,0x6a, 800, 600, 0x40}, /* 0x0 */
184 {0x0067,0x0e,0x04,0x05,0x05,0x6a, 800, 600, 0x40}, /* 0x1 */
185 {0x0067,0x0f,0x08,0x48,0x05,0x6a, 800, 600, 0x40}, /* 0x2 */
186 {0x0067,0x10,0x07,0x8b,0x05,0x6a, 800, 600, 0x40}, /* 0x3 */
187 {0x0047,0x11,0x0a,0x00,0x05,0x6a, 800, 600, 0x40}, /* 0x4 */
188 {0x0047,0x12,0x0d,0x00,0x05,0x6a, 800, 600, 0x40}, /* 0x5 */
189 {0x0047,0x13,0x13,0x00,0x05,0x6a, 800, 600, 0x20}, /* 0x6 */
190 {0x0107,0x14,0x1c,0x00,0x05,0x6a, 800, 600, 0x20}, /* 0x7 */
191 {0xc85f,0x05,0x00,0x04,0x04,0x2e, 640, 480, 0x40}, /* 0x8 */
192 {0xc067,0x06,0x02,0x04,0x04,0x2e, 640, 480, 0x40}, /* 0x9 */
193 {0xc067,0x07,0x02,0x47,0x04,0x2e, 640, 480, 0x40}, /* 0xa */
194 {0xc067,0x08,0x03,0x8a,0x04,0x2e, 640, 480, 0x40}, /* 0xb */
195 {0xc047,0x09,0x05,0x00,0x04,0x2e, 640, 480, 0x40}, /* 0xc */
196 {0xc047,0x0a,0x09,0x00,0x04,0x2e, 640, 480, 0x40}, /* 0xd */
197 {0xc047,0x0b,0x0e,0x00,0x04,0x2e, 640, 480, 0x40}, /* 0xe */
198 {0xc047,0x0c,0x15,0x00,0x04,0x2e, 640, 480, 0x40}, /* 0xf */
199 {0x487f,0x04,0x00,0x00,0x00,0x2f, 640, 400, 0x30}, /* 0x10 */
200 {0xc06f,0x3c,0x01,0x06,0x13,0x31, 720, 480, 0x30}, /* 0x11 */
201 {0x006f,0x3d,0x03,0x06,0x14,0x32, 720, 576, 0x30}, /* 0x12 */
202 {0x0087,0x15,0x06,0x00,0x06,0x37,1024, 768, 0x30}, /* 0x13 */
203 {0xc877,0x16,0x0b,0x06,0x06,0x37,1024, 768, 0x20}, /* 0x14 */
204 {0xc067,0x17,0x0f,0x49,0x06,0x37,1024, 768, 0x20}, /* 0x15 */
205 {0x0067,0x18,0x11,0x00,0x06,0x37,1024, 768, 0x20}, /* 0x16 */
206 {0x0047,0x19,0x16,0x8c,0x06,0x37,1024, 768, 0x20}, /* 0x17 */
207 {0x0107,0x1a,0x1b,0x00,0x06,0x37,1024, 768, 0x10}, /* 0x18 */
208 {0x0107,0x1b,0x1f,0x00,0x06,0x37,1024, 768, 0x10}, /* 0x19 */
209 {0x0087,0x1c,0x11,0x00,0x07,0x3a,1280,1024, 0x30}, /* 0x1a */
210 {0x0137,0x1d,0x19,0x07,0x07,0x3a,1280,1024, 0x00}, /* 0x1b */
211 {0x0107,0x1e,0x1e,0x00,0x07,0x3a,1280,1024, 0x00}, /* 0x1c */
212 {0x0207,0x1f,0x20,0x00,0x07,0x3a,1280,1024, 0x00}, /* 0x1d */
213 {0x0227,0x20,0x21,0x09,0x09,0x3c,1600,1200, 0x00}, /* 0x1e */
214 {0x0407,0x21,0x22,0x00,0x09,0x3c,1600,1200, 0x00}, /* 0x1f */
215 {0x0407,0x22,0x23,0x00,0x09,0x3c,1600,1200, 0x00}, /* 0x20 */
216 {0x0407,0x23,0x25,0x00,0x09,0x3c,1600,1200, 0x00}, /* 0x21 */
217 {0x0007,0x24,0x26,0x00,0x09,0x3c,1600,1200, 0x00}, /* 0x22 */
218 {0x0007,0x25,0x2c,0x00,0x09,0x3c,1600,1200, 0x00}, /* 0x23 */
219 {0x0007,0x26,0x34,0x00,0x09,0x3c,1600,1200, 0x00}, /* 0x24 */
220 {0x407f,0x00,0x00,0x00,0x00,0x40, 320, 200, 0x30}, /* 0x25 */
221 {0xc07f,0x01,0x00,0x04,0x04,0x50, 320, 240, 0x30}, /* 0x26 */
222 {0x007f,0x02,0x04,0x05,0x05,0x51, 400, 300, 0x30}, /* 0x27 */
223 {0xc077,0x03,0x0b,0x06,0x06,0x52, 512, 384, 0x30}, /* 0x28 */
224 {0x8007,0x27,0x27,0x00,0x00,0x68,1920,1440, 0x00}, /* 0x29 */
225 {0x4007,0x28,0x29,0x00,0x00,0x68,1920,1440, 0x00}, /* 0x2a */
226 {0x4007,0x29,0x2e,0x00,0x00,0x68,1920,1440, 0x00}, /* 0x2b */
227 {0x4007,0x2a,0x30,0x00,0x00,0x68,1920,1440, 0x00}, /* 0x2c */
228 {0x4007,0x2b,0x35,0x00,0x00,0x68,1920,1440, 0x00}, /* 0x2d */
229 {0x4005,0x2c,0x39,0x00,0x00,0x68,1920,1440, 0x00}, /* 0x2e */
230 {0x4007,0x2d,0x2b,0x00,0x00,0x6c,2048,1536, 0x00}, /* 0x2f */
231 {0x4007,0x2e,0x31,0x00,0x00,0x6c,2048,1536, 0x00}, /* 0x30 */
232 {0x4007,0x2f,0x33,0x00,0x00,0x6c,2048,1536, 0x00}, /* 0x31 */
233 {0x4007,0x30,0x37,0x00,0x00,0x6c,2048,1536, 0x00}, /* 0x32 */
234 {0x4005,0x31,0x38,0x00,0x00,0x6c,2048,1536, 0x00}, /* 0x33 */
235 {0x0077,0x32,0x40,0x08,0x18,0x70, 800, 480, 0x30}, /* 0x34 */
236 {0x0047,0x33,0x07,0x08,0x18,0x70, 800, 480, 0x30}, /* 0x35 */
237 {0x0047,0x34,0x0a,0x08,0x18,0x70, 800, 480, 0x30}, /* 0x36 */
238 {0x0077,0x35,0x0b,0x09,0x19,0x71,1024, 576, 0x30}, /* 0x37 */
239 {0x0047,0x36,0x11,0x09,0x19,0x71,1024, 576, 0x30}, /* 0x38 */
240 {0x0047,0x37,0x16,0x09,0x19,0x71,1024, 576, 0x30}, /* 0x39 */
241 {0x1137,0x38,0x19,0x0a,0x0c,0x75,1280, 720, 0x30}, /* 0x3a */
242 {0x1107,0x39,0x1e,0x0a,0x0c,0x75,1280, 720, 0x30}, /* 0x3b */
243 {0x1307,0x3a,0x20,0x0a,0x0c,0x75,1280, 720, 0x30}, /* 0x3c */
244 {0x0127,0x3b,0x19,0x08,0x0a,0x7c,1280, 960, 0x30}, /* 0x3d */
245 {0x0227,0x4c,0x59,0x08,0x0a,0x7c,1280, 960, 0x20}, /* 0x3e */
246 {0xc07f,0x4e,0x00,0x06,0x04,0x5a, 320, 240, 0x30}, /* 0x3f */ /* FSTN 320x240 */
247 {0x0077,0x42,0x5b,0x08,0x11,0x23,1280, 768, 0x30}, /* 0x40 */ /* 0x5b was 0x12 */
248 {0x0127,0x43,0x4d,0x08,0x0b,0x26,1400,1050, 0x30}, /* 0x41 */
249 {0x0207,0x4b,0x5a,0x08,0x0b,0x26,1400,1050, 0x30}, /* 0x42 1400x1050-75Hz */
250 {0x0127,0x54,0x6d,0x00,0x1a,0x29,1152, 864, 0x30}, /* 0x43 1152x864-60Hz */
251 {0x0127,0x44,0x19,0x00,0x1a,0x29,1152, 864, 0x30}, /* 0x44 1152x864-75Hz */
252 {0x0127,0x4a,0x1e,0x00,0x1a,0x29,1152, 864, 0x30}, /* 0x45 1152x864-85Hz */
253 {0x0087,0x45,0x57,0x00,0x16,0x39, 848, 480, 0x30}, /* 0x46 848x480-38Hzi */
254 {0xc067,0x46,0x55,0x0b,0x16,0x39, 848, 480, 0x30}, /* 0x47 848x480-60Hz */
255 {0x0087,0x47,0x57,0x00,0x17,0x3f, 856, 480, 0x30}, /* 0x48 856x480-38Hzi */
256 {0xc067,0x48,0x57,0x00,0x17,0x3f, 856, 480, 0x30}, /* 0x49 856x480-60Hz */
257 {0x0067,0x49,0x58,0x0c,0x1b,0x48,1360, 768, 0x30}, /* 0x4a 1360x768-60Hz */
258 {0x006f,0x4d,0x03,0x06,0x15,0x5f, 768, 576, 0x30}, /* 0x4b 768x576-56Hz */
259 {0x0067,0x4f,0x5c,0x08,0x0d,0x14,1280, 800, 0x30}, /* 0x4c 1280x800-60Hz */
260 {0x0067,0x50,0x5d,0x0c,0x0e,0x17,1680,1050, 0x30}, /* 0x4d 1680x1050-60Hz */
261 {0x0087,0x51,0x69,0x00,0x00,0x2c,1920,1080, 0x30}, /* 0x4e 1920x1080 60Hzi */
262 {0x0067,0x52,0x6a,0x00,0x1c,0x1d, 960, 540, 0x30}, /* 0x4f 960x540 60Hz */
263 {0x0077,0x53,0x6b,0x0b,0x1d,0x20, 960, 600, 0x30}, /* 0x50 960x600 60Hz */
264 {0xffff,0x00,0x00,0x00,0x00,0x00, 0, 0, 0}
265};
266
267#ifdef LINUX_XF86
268static const struct {
269 UCHAR Ext_ModeID; /* ModeID in new ROM */
270 UCHAR Ext_MyModeID; /* corresponding ModeID in my tables (0 = identical) */
271 USHORT Ext_VESAID; /* corresponding VESA ID in new ROM */
272} SiS_EModeIDTable661[] = {
273 { 0x6a, 0x00, 0x0102 },
274 { 0x1d, 0x20, 0x0000 },
275 { 0x1e, 0x21, 0x0000 },
276 { 0x1f, 0x22, 0x0000 },
277 { 0x20, 0x29, 0x0000 },
278 { 0x21, 0x2a, 0x0000 },
279 { 0x22, 0x2b, 0x0000 },
280 { 0x23, 0x00, 0x011c },
281 { 0x24, 0x00, 0x011d },
282 { 0x25, 0x00, 0x011e },
283 { 0x26, 0x00, 0x011f },
284 { 0x27, 0x00, 0x0120 },
285 { 0x28, 0x00, 0x0121 },
286 { 0x2a, 0x14, 0x013d },
287 { 0x2b, 0x15, 0x013e },
288 { 0x2c, 0x16, 0x013f },
289 { 0x2e, 0x00, 0x0101 },
290 { 0x2f, 0x00, 0x0100 },
291 { 0x30, 0x00, 0x0103 },
292 { 0x37, 0x00, 0x0104 },
293 { 0x38, 0x00, 0x0105 },
294 { 0x3a, 0x00, 0x0107 },
295 { 0x3c, 0x00, 0x0125 },
296 { 0x3d, 0x00, 0x0126 },
297 { 0x40, 0x00, 0x010d },
298 { 0x41, 0x00, 0x010e },
299 { 0x43, 0x00, 0x0110 },
300 { 0x44, 0x00, 0x0111 },
301 { 0x46, 0x00, 0x0113 },
302 { 0x47, 0x00, 0x0114 },
303 { 0x49, 0x00, 0x0116 },
304 { 0x4a, 0x00, 0x0117 },
305 { 0x4c, 0x00, 0x0119 },
306 { 0x4d, 0x00, 0x011a },
307 { 0x50, 0x00, 0x0127 },
308 { 0x51, 0x00, 0x0128 },
309 { 0x52, 0x00, 0x0129 },
310 { 0x56, 0x00, 0x012a },
311 { 0x57, 0x00, 0x012b },
312 { 0x58, 0x00, 0x012c },
313 { 0x59, 0x00, 0x012d },
314 { 0x5a, 0x17, 0x012e },
315 { 0x5b, 0x18, 0x012f },
316 { 0x5c, 0x19, 0x0130 },
317 { 0x5d, 0x00, 0x0131 },
318 { 0x62, 0x00, 0x0112 },
319 { 0x63, 0x00, 0x0115 },
320 { 0x64, 0x00, 0x0118 },
321 { 0x65, 0x00, 0x011b },
322 { 0x66, 0x00, 0x0132 },
323 { 0x75, 0x00, 0x013a },
324 { 0x78, 0x00, 0x013b },
325 { 0x79, 0x00, 0x013c },
326 { 0x7b, 0x7c, 0x0136 },
327 { 0x7c, 0x7d, 0x0137 },
328 { 0x7d, 0x7e, 0x0138 },
329 { 0xff, 0xff, 0xffff }
330};
331#endif
332
333static const SiS_CRT1TableStruct SiS310_CRT1Table[]=
334{
335 {{0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
336 0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x00,
337 0x00}}, /* 0x0 */
338 {{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e,
339 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00,
340 0x00}}, /* 0x1 */
341 {{0x3d,0x31,0x31,0x81,0x37,0x1f,0x72,0xf0,
342 0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x05,
343 0x01}}, /* 0x2 */
344 {{0x4f,0x3f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
345 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x01,
346 0x01}}, /* 0x3 */
347 {{0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
348 0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x05,
349 0x00}}, /* 0x4 */
350#if 0
351 {{0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,
352 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05,
353 0x00}}, /* 0x5 */
354#endif
355 {{0x5f,0x4f,0x4f,0x83,0x55,0x81,0x0b,0x3e, /* 0x05 - corrected 640x480-60 */
356 0xe9,0x8b,0xdf,0xe8,0x0c,0x00,0x00,0x05,
357 0x00}},
358#if 0
359 {{0x63,0x4f,0x50,0x86,0x56,0x9b,0x06,0x3e,
360 0xe8,0x8b,0xdf,0xe7,0xff,0x10,0x00,0x01,
361 0x00}}, /* 0x6 */
362#endif
363 {{0x63,0x4f,0x4f,0x87,0x56,0x9b,0x06,0x3e, /* 0x06 - corrected 640x480-72 */
364 0xe8,0x8a,0xdf,0xe7,0x07,0x00,0x00,0x01,
365 0x00}},
366 {{0x64,0x4f,0x4f,0x88,0x55,0x9d,0xf2,0x1f,
367 0xe0,0x83,0xdf,0xdf,0xf3,0x10,0x00,0x01,
368 0x00}}, /* 0x7 */
369 {{0x63,0x4f,0x4f,0x87,0x5a,0x81,0xfb,0x1f,
370 0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x05,
371 0x00}}, /* 0x8 */
372 {{0x65,0x4f,0x4f,0x89,0x58,0x80,0xfb,0x1f,
373 0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x05, /* Corrected VBE */
374 0x61}}, /* 0x9 */
375 {{0x65,0x4f,0x4f,0x89,0x58,0x80,0x01,0x3e,
376 0xe0,0x83,0xdf,0xdf,0x02,0x00,0x00,0x05,
377 0x61}}, /* 0xa */
378 {{0x67,0x4f,0x4f,0x8b,0x58,0x81,0x0d,0x3e,
379 0xe0,0x83,0xdf,0xdf,0x0e,0x00,0x00,0x05, /* Corrected VBE */
380 0x61}}, /* 0xb */
381 {{0x65,0x4f,0x4f,0x89,0x57,0x9f,0xfb,0x1f,
382 0xe6,0x8a,0xdf,0xdf,0xfc,0x10,0x00,0x01, /* Corrected VDE, VBE */
383 0x00}}, /* 0xc */
384 {{0x7b,0x63,0x63,0x9f,0x6a,0x93,0x6f,0xf0,
385 0x58,0x8a,0x57,0x57,0x70,0x20,0x00,0x05,
386 0x01}}, /* 0xd */
387 {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xf0,
388 0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x06,
389 0x01}}, /* 0xe */
390 {{0x7d,0x63,0x63,0x81,0x6e,0x1d,0x98,0xf0,
391 0x7c,0x82,0x57,0x57,0x99,0x00,0x00,0x06,
392 0x01}}, /* 0xf */
393 {{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xf0,
394 0x58,0x8b,0x57,0x57,0x70,0x20,0x00,0x06,
395 0x01}}, /* 0x10 */
396 {{0x7e,0x63,0x63,0x82,0x6b,0x13,0x75,0xf0,
397 0x58,0x8b,0x57,0x57,0x76,0x20,0x00,0x06,
398 0x01}}, /* 0x11 */
399 {{0x81,0x63,0x63,0x85,0x6d,0x18,0x7a,0xf0,
400 0x58,0x8b,0x57,0x57,0x7b,0x20,0x00,0x06,
401 0x61}}, /* 0x12 */
402 {{0x83,0x63,0x63,0x87,0x6e,0x19,0x81,0xf0,
403 0x58,0x8b,0x57,0x57,0x82,0x20,0x00,0x06,
404 0x61}}, /* 0x13 */
405 {{0x85,0x63,0x63,0x89,0x6f,0x1a,0x91,0xf0,
406 0x58,0x8b,0x57,0x57,0x92,0x20,0x00,0x06,
407 0x61}}, /* 0x14 */
408 {{0x99,0x7f,0x7f,0x9d,0x84,0x1a,0x96,0x1f,
409 0x7f,0x83,0x7f,0x7f,0x97,0x10,0x00,0x02,
410 0x00}}, /* 0x15 */
411 {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,
412 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
413 0x01}}, /* 0x16 */
414 {{0xa1,0x7f,0x7f,0x85,0x86,0x97,0x24,0xf5,
415 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
416 0x01}}, /* 0x17 */
417 {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf5,
418 0x00,0x83,0xff,0xff,0x1f,0x10,0x00,0x02,
419 0x01}}, /* 0x18 */
420 {{0xa7,0x7f,0x7f,0x8b,0x89,0x95,0x26,0xf5,
421 0x00,0x83,0xff,0xff,0x27,0x10,0x00,0x02,
422 0x01}}, /* 0x19 */
423 {{0xa9,0x7f,0x7f,0x8d,0x8c,0x9a,0x2c,0xf5,
424 0x00,0x83,0xff,0xff,0x2d,0x14,0x00,0x02,
425 0x62}}, /* 0x1a */
426 {{0xab,0x7f,0x7f,0x8f,0x8d,0x9b,0x35,0xf5,
427 0x00,0x83,0xff,0xff,0x36,0x14,0x00,0x02,
428 0x62}}, /* 0x1b */
429 {{0xcf,0x9f,0x9f,0x93,0xb2,0x01,0x14,0xba,
430 0x00,0x83,0xff,0xff,0x15,0x00,0x00,0x03,
431 0x00}}, /* 0x1c */
432 {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0x5a,
433 0x00,0x83,0xff,0xff,0x29,0x09,0x00,0x07,
434 0x01}}, /* 0x1d */
435 {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0x5a,
436 0x00,0x83,0xff,0xff,0x29,0x09,0x00,0x07,
437 0x01}}, /* 0x1e */
438 {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0x5a,
439 0x00,0x83,0xff,0xff,0x2f,0x09,0x00,0x07,
440 0x01}}, /* 0x1f */
441 {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
442 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
443 0x00}}, /* 0x20 */
444 {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
445 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
446 0x00}}, /* 0x21 @ 4084 */
447 {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
448 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
449 0x00}}, /* 0x22 */
450 {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
451 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
452 0x00}}, /* 0x23 */
453 {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
454 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
455 0x00}}, /* 0x24 */
456 {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
457 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
458 0x00}}, /* 0x25 */
459 {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
460 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
461 0x00}}, /* 0x26 */
462 {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
463 0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
464 0x00}}, /* 0x27 */
465 {{0x43,0xef,0xef,0x87,0x06,0x00,0xd4,0x1f,
466 0xa0,0x83,0x9f,0x9f,0xd5,0x1f,0x41,0x05,
467 0x63}}, /* 0x28 */
468 {{0x45,0xef,0xef,0x89,0x07,0x01,0xd9,0x1f,
469 0xa0,0x83,0x9f,0x9f,0xda,0x1f,0x41,0x05,
470 0x63}}, /* 0x29 */
471 {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
472 0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
473 0x00}}, /* 0x2a */
474 {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
475 0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
476 0x00}}, /* 0x2b */
477 {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
478 0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
479 0x00}}, /* 0x2c */
480 {{0x59,0xff,0xff,0x9d,0x17,0x13,0x33,0xba,
481 0x00,0x83,0xff,0xff,0x34,0x0f,0x41,0x05,
482 0x44}}, /* 0x2d */
483 {{0x5b,0xff,0xff,0x9f,0x18,0x14,0x38,0xba,
484 0x00,0x83,0xff,0xff,0x39,0x0f,0x41,0x05,
485 0x44}}, /* 0x2e */
486 {{0x5b,0xff,0xff,0x9f,0x18,0x14,0x3d,0xba,
487 0x00,0x83,0xff,0xff,0x3e,0x0f,0x41,0x05,
488 0x44}}, /* 0x2f */
489 {{0x5d,0xff,0xff,0x81,0x19,0x95,0x41,0xba,
490 0x00,0x84,0xff,0xff,0x42,0x0f,0x41,0x05,
491 0x44}}, /* 0x30 */
492 {{0x55,0xff,0xff,0x99,0x0d,0x0c,0x3e,0xba,
493 0x00,0x84,0xff,0xff,0x3f,0x0f,0x41,0x05,
494 0x00}}, /* 0x31 */
495 {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xba,
496 0x27,0x8b,0xdf,0xdf,0x73,0x00,0x00,0x06,
497 0x01}}, /* 0x32 */
498 {{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xba,
499 0x26,0x89,0xdf,0xdf,0x6f,0x00,0x00,0x06,
500 0x01}}, /* 0x33 */
501 {{0x7f,0x63,0x63,0x82,0x6b,0x13,0x75,0xba,
502 0x29,0x8c,0xdf,0xdf,0x75,0x00,0x00,0x06,
503 0x01}}, /* 0x34 */
504 {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf1,
505 0xaf,0x85,0x3f,0x3f,0x25,0x30,0x00,0x02,
506 0x01}}, /* 0x35 */
507 {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf1,
508 0xad,0x81,0x3f,0x3f,0x1f,0x30,0x00,0x02,
509 0x01}}, /* 0x36 */
510 {{0xa7,0x7f,0x7f,0x88,0x89,0x95,0x26,0xf1, /* 95 was 15 - illegal HBE! */
511 0xb1,0x85,0x3f,0x3f,0x27,0x30,0x00,0x02,
512 0x01}}, /* 0x37 */
513 {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0xc4,
514 0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07,
515 0x01}}, /* 0x38 */
516 {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0xd4,
517 0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07,
518 0x01}}, /* 0x39 */
519 {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0xd4,
520 0x7d,0x81,0xcf,0xcf,0x2f,0x21,0x00,0x07,
521 0x01}}, /* 0x3a */
522#if 0
523 {{0xdc,0x9f,0x9f,0x00,0xab,0x19,0xe6,0xef, /* 1280x960 - invalid */
524 0xc0,0xc3,0xbf,0xbf,0xe7,0x10,0x00,0x07,
525 0x01}}, /* 0x3b */
526#endif
527 {{0xdc,0x9f,0x9f,0x80,0xaf,0x9d,0xe6,0xff, /* 1280x960-60 - corrected */
528 0xc0,0x83,0xbf,0xbf,0xe7,0x10,0x00,0x07,
529 0x01}}, /* 0x3b */
530 {{0x6b,0x59,0x59,0x8f,0x5e,0x8c,0x0b,0x3e,
531 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05,
532 0x00}}, /* 0x3c */
533 {{0x7b,0x59,0x63,0x9f,0x6a,0x93,0x6f,0xf0,
534 0x58,0x8a,0x3f,0x57,0x70,0x20,0x00,0x05,
535 0x01}}, /* 0x3d */
536 {{0x86,0x6a,0x6a,0x8a,0x74,0x06,0x8c,0x15,
537 0x4f,0x83,0xef,0xef,0x8d,0x30,0x00,0x02,
538 0x00}}, /* 0x3e */
539 {{0x81,0x6a,0x6a,0x85,0x70,0x00,0x0f,0x3e,
540 0xeb,0x8e,0xdf,0xdf,0x10,0x00,0x00,0x02,
541 0x00}}, /* 0x3f */
542 {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x1e,0xf1,
543 0xae,0x85,0x57,0x57,0x1f,0x30,0x00,0x02,
544 0x01}}, /* 0x40 */
545 {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,
546 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
547 0x01}}, /* 0x41 */
548 {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x20,0xf5,
549 0x03,0x88,0xff,0xff,0x21,0x10,0x00,0x07,
550 0x01}}, /* 0x42 */
551 {{0xe6,0xae,0xae,0x8a,0xbd,0x90,0x3d,0x10,
552 0x1a,0x8d,0x19,0x19,0x3e,0x2f,0x00,0x03,
553 0x00}}, /* 0x43 */
554 {{0xc3,0x8f,0x8f,0x87,0x9b,0x0b,0x82,0xef, /* 1152x864-75 */
555 0x60,0x83,0x5f,0x5f,0x83,0x10,0x00,0x07,
556 0x01}}, /* 0x44 */
557 {{0x86,0x69,0x69,0x8A,0x74,0x06,0x8C,0x15, /* 848x480-38i */
558 0x4F,0x83,0xEF,0xEF,0x8D,0x30,0x00,0x02,
559 0x00}}, /* 0x45 */
560 {{0x83,0x69,0x69,0x87,0x6f,0x1d,0x03,0x3E, /* 848x480-60 */
561 0xE5,0x8d,0xDF,0xe4,0x04,0x00,0x00,0x06,
562 0x00}}, /* 0x46 */
563 {{0x86,0x6A,0x6A,0x8A,0x74,0x06,0x8C,0x15, /* 856x480-38i */
564 0x4F,0x83,0xEF,0xEF,0x8D,0x30,0x00,0x02,
565 0x00}}, /* 0x47 */
566 {{0x81,0x6A,0x6A,0x85,0x70,0x00,0x0F,0x3E, /* 856x480-60 */
567 0xEB,0x8E,0xDF,0xDF,0x10,0x00,0x00,0x02,
568 0x00}}, /* 0x48 */
569 {{0xdd,0xa9,0xa9,0x81,0xb4,0x97,0x26,0xfd, /* 1360x768-60 */
570 0x01,0x8d,0xff,0x00,0x27,0x10,0x00,0x03,
571 0x01}}, /* 0x49 */
572 {{0xd9,0x8f,0x8f,0x9d,0xba,0x0a,0x8a,0xff, /* 1152x864-84 */
573 0x60,0x8b,0x5f,0x5f,0x8b,0x10,0x00,0x03,
574 0x01}}, /* 0x4a */
575 {{0xea,0xae,0xae,0x8e,0xba,0x82,0x40,0x10, /* 1400x1050-75 */
576 0x1b,0x87,0x19,0x1a,0x41,0x0f,0x00,0x03,
577 0x00}}, /* 0x4b */
578 {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0xf1,0xff, /* 1280x960-85 */
579 0xc0,0x83,0xbf,0xbf,0xf2,0x10,0x00,0x07,
580 0x01}}, /* 0x4c */
581 {{0x7b,0x5f,0x63,0x9f,0x6a,0x93,0x6f,0xf0, /* 768x576 */
582 0x58,0x8a,0x3f,0x57,0x70,0x20,0x00,0x05,
583 0x01}}, /* 0x4d */
584 {{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e, /* FSTN 320x480, TEMP - possibly invalid */
585 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00,
586 0x00}}, /* 0x4e */
587 {{0xcd,0x9f,0x9f,0x91,0xab,0x1c,0x3a,0xff, /* 1280x800-60 */
588 0x20,0x83,0x1f,0x1f,0x3b,0x10,0x00,0x07,
589 0x21}}, /* 0x4f */
590 {{0x15,0xd1,0xd1,0x99,0xe2,0x19,0x3d,0x10, /* 1680x1050-60 */
591 0x1a,0x8d,0x19,0x19,0x3e,0x2f,0x01,0x0c,
592 0x20}}, /* 0x50 */
593 {{0x0e,0xef,0xef,0x92,0xfe,0x03,0x30,0xf0, /* 1920x1080-60i */
594 0x1e,0x83,0x1b,0x1c,0x31,0x00,0x01,0x00,
595 0x61}}, /* 0x51 */
596 {{0x85,0x77,0x77,0x89,0x7d,0x01,0x31,0xf0, /* 960x540-60 */
597 0x1e,0x84,0x1b,0x1c,0x32,0x00,0x00,0x02,
598 0x41}}, /* 0x52 */
599 {{0x87,0x77,0x77,0x8b,0x81,0x0b,0x68,0xf0, /* 960x600-60 */
600 0x5a,0x80,0x57,0x57,0x69,0x00,0x00,0x02,
601 0x01}}, /* 0x53 */
602 {{0xcd,0x8f,0x8f,0x91,0x9b,0x1b,0x7a,0xff, /* 1152x864-60 */
603 0x64,0x8c,0x5f,0x62,0x7b,0x10,0x00,0x07,
604 0x41}} /* 0x54 */
605};
606
607static const SiS_MCLKDataStruct SiS310_MCLKData_0_315[] =
608{
609 { 0x3b,0x22,0x01,143},
610 { 0x5c,0x23,0x01,166},
611 { 0x5c,0x23,0x01,166},
612 { 0x5c,0x23,0x01,166},
613 { 0x5c,0x23,0x01,166},
614 { 0x5c,0x23,0x01,166},
615 { 0x5c,0x23,0x01,166},
616 { 0x5c,0x23,0x01,166}
617};
618
619static const SiS_MCLKDataStruct SiS310_MCLKData_0_650[] =
620{
621 { 0x5a,0x64,0x82, 66},
622 { 0xb3,0x45,0x82, 83},
623 { 0x37,0x61,0x82,100},
624 { 0x37,0x22,0x82,133},
625 { 0x37,0x61,0x82,100},
626 { 0x37,0x22,0x82,133},
627 { 0x37,0x22,0x82,133},
628 { 0x37,0x22,0x82,133}
629};
630
631static const SiS_MCLKDataStruct SiS310_MCLKData_0_330[] =
632{
633 { 0x5c,0x23,0x01,166},
634 { 0x5c,0x23,0x01,166},
635 { 0x7c,0x08,0x01,200},
636 { 0x79,0x06,0x01,250},
637 { 0x7c,0x08,0x01,200},
638 { 0x7c,0x08,0x01,200},
639 { 0x7c,0x08,0x01,200},
640 { 0x79,0x06,0x01,250}
641};
642
643static const SiS_MCLKDataStruct SiS310_MCLKData_0_660[] =
644{
645 { 0x5c,0x23,0x82,166},
646 { 0x5c,0x23,0x82,166},
647 { 0x37,0x21,0x82,200},
648 { 0x37,0x22,0x82,133},
649 { 0x29,0x21,0x82,150},
650 { 0x5c,0x23,0x82,166},
651 { 0x65,0x23,0x82,183},
652 { 0x37,0x21,0x82,200}
653};
654
655static const SiS_MCLKDataStruct SiS310_MCLKData_0_760[] =
656{
657 { 0x37,0x22,0x82,133},
658 { 0x5c,0x23,0x82,166},
659 { 0x65,0x23,0x82,183},
660 { 0x7c,0x08,0x82,200},
661 { 0x29,0x21,0x82,150},
662 { 0x5c,0x23,0x82,166},
663 { 0x65,0x23,0x82,183},
664 { 0x37,0x21,0x82,200}
665};
666
667static const SiS_MCLKDataStruct SiS310_MCLKData_0_761[] =
668{
669 { 0x37,0x22,0x82,133}, /* Preliminary */
670 { 0x5c,0x23,0x82,166},
671 { 0x65,0x23,0x82,183},
672 { 0x7c,0x08,0x82,200},
673 { 0x29,0x21,0x82,150},
674 { 0x5c,0x23,0x82,166},
675 { 0x65,0x23,0x82,183},
676 { 0x37,0x21,0x82,200}
677};
678
679static const SiS_MCLKDataStruct SiS310_MCLKData_0_340[] =
680{
681 { 0x79,0x06,0x01,250},
682 { 0x7c,0x08,0x01,200},
683 { 0x7c,0x08,0x80,200},
684 { 0x79,0x06,0x80,250},
685 { 0x29,0x01,0x81,300},
686 { 0x29,0x01,0x81,300},
687 { 0x29,0x01,0x81,300},
688 { 0x29,0x01,0x81,300}
689};
690
691static const SiS_MCLKDataStruct SiS310_MCLKData_1[] = /* ECLK */
692{
693 { 0x29,0x21,0x82,150},
694 { 0x5c,0x23,0x82,166},
695 { 0x65,0x23,0x82,183},
696 { 0x37,0x21,0x82,200},
697 { 0x37,0x22,0x82,133},
698 { 0x37,0x22,0x82,133},
699 { 0x37,0x22,0x82,133},
700 { 0x37,0x22,0x82,133}
701};
702
703static const SiS_MCLKDataStruct SiS310_MCLKData_1_340[] =
704{
705 { 0x7c,0x08,0x01,200},
706 { 0x7c,0x08,0x01,200},
707 { 0x7c,0x08,0x80,200},
708 { 0x79,0x06,0x80,250},
709 { 0x29,0x01,0x81,300},
710 { 0x29,0x01,0x81,300},
711 { 0x29,0x01,0x81,300},
712 { 0x29,0x01,0x81,300}
713};
714
715static SiS_VCLKDataStruct SiS310_VCLKData[]=
716{
717 { 0x1b,0xe1, 25}, /* 0x00 */
718 { 0x4e,0xe4, 28}, /* 0x01 */
719 { 0x57,0xe4, 31}, /* 0x02 */
720 { 0xc3,0xc8, 36}, /* 0x03 */
721 { 0x42,0xe2, 40}, /* 0x04 */
722 { 0xfe,0xcd, 43}, /* 0x05 */
723 { 0x5d,0xc4, 44}, /* 0x06 */
724 { 0x52,0xe2, 49}, /* 0x07 */
725 { 0x53,0xe2, 50}, /* 0x08 */
726 { 0x74,0x67, 52}, /* 0x09 */
727 { 0x6d,0x66, 56}, /* 0x0a */
728 { 0x5a,0x64, 65}, /* 0x0b */ /* was 6c c3 - WRONG */
729 { 0x46,0x44, 67}, /* 0x0c */
730 { 0xb1,0x46, 68}, /* 0x0d */
731 { 0xd3,0x4a, 72}, /* 0x0e */
732 { 0x29,0x61, 75}, /* 0x0f */
733 { 0x6e,0x46, 76}, /* 0x10 */
734 { 0x2b,0x61, 78}, /* 0x11 */
735 { 0x31,0x42, 79}, /* 0x12 */
736 { 0xab,0x44, 83}, /* 0x13 */
737 { 0x46,0x25, 84}, /* 0x14 */
738 { 0x78,0x29, 86}, /* 0x15 */
739 { 0x62,0x44, 94}, /* 0x16 */
740 { 0x2b,0x41,104}, /* 0x17 */
741 { 0x3a,0x23,105}, /* 0x18 */
742 { 0x70,0x44,108}, /* 0x19 */
743 { 0x3c,0x23,109}, /* 0x1a */
744 { 0x5e,0x43,113}, /* 0x1b */
745 { 0xbc,0x44,116}, /* 0x1c */
746 { 0xe0,0x46,132}, /* 0x1d */
747 { 0x54,0x42,135}, /* 0x1e */
748 { 0xea,0x2a,139}, /* 0x1f */
749 { 0x41,0x22,157}, /* 0x20 */
750 { 0x70,0x24,162}, /* 0x21 */
751 { 0x30,0x21,175}, /* 0x22 */
752 { 0x4e,0x22,189}, /* 0x23 */
753 { 0xde,0x26,194}, /* 0x24 */
754 { 0x62,0x06,202}, /* 0x25 */
755 { 0x3f,0x03,229}, /* 0x26 */
756 { 0xb8,0x06,234}, /* 0x27 */
757 { 0x34,0x02,253}, /* 0x28 */
758 { 0x58,0x04,255}, /* 0x29 */
759 { 0x24,0x01,265}, /* 0x2a */
760 { 0x9b,0x02,267}, /* 0x2b */
761 { 0x70,0x05,270}, /* 0x2c */
762 { 0x25,0x01,272}, /* 0x2d */
763 { 0x9c,0x02,277}, /* 0x2e */
764 { 0x27,0x01,286}, /* 0x2f */
765 { 0x3c,0x02,291}, /* 0x30 */
766 { 0xef,0x0a,292}, /* 0x31 */
767 { 0xf6,0x0a,310}, /* 0x32 */
768 { 0x95,0x01,315}, /* 0x33 */
769 { 0xf0,0x09,324}, /* 0x34 */
770 { 0xfe,0x0a,331}, /* 0x35 */
771 { 0xf3,0x09,332}, /* 0x36 */
772 { 0xea,0x08,340}, /* 0x37 */
773 { 0xe8,0x07,376}, /* 0x38 */
774 { 0xde,0x06,389}, /* 0x39 */
775 { 0x52,0x2a, 54}, /* 0x3a 301 TV */
776 { 0x52,0x6a, 27}, /* 0x3b 301 TV */
777 { 0x62,0x24, 70}, /* 0x3c 301 TV */
778 { 0x62,0x64, 70}, /* 0x3d 301 TV */
779 { 0xa8,0x4c, 30}, /* 0x3e 301 TV */
780 { 0x20,0x26, 33}, /* 0x3f 301 TV */
781 { 0x31,0xc2, 39}, /* 0x40 */
782 { 0x60,0x36, 30}, /* 0x41 Chrontel */
783 { 0x40,0x4a, 28}, /* 0x42 Chrontel */
784 { 0x9f,0x46, 44}, /* 0x43 Chrontel */
785 { 0x97,0x2c, 26}, /* 0x44 */
786 { 0x44,0xe4, 25}, /* 0x45 Chrontel */
787 { 0x7e,0x32, 47}, /* 0x46 Chrontel */
788 { 0x8a,0x24, 31}, /* 0x47 Chrontel */
789 { 0x97,0x2c, 26}, /* 0x48 Chrontel */
790 { 0xce,0x3c, 39}, /* 0x49 */
791 { 0x52,0x4a, 36}, /* 0x4a Chrontel */
792 { 0x34,0x61, 95}, /* 0x4b */
793 { 0x78,0x27,108}, /* 0x4c - was 102 */
794 { 0x66,0x43,123}, /* 0x4d Modes 0x26-0x28 (1400x1050) */
795 { 0x41,0x4e, 21}, /* 0x4e */
796 { 0xa1,0x4a, 29}, /* 0x4f Chrontel */
797 { 0x19,0x42, 42}, /* 0x50 */
798 { 0x54,0x46, 58}, /* 0x51 Chrontel */
799 { 0x25,0x42, 61}, /* 0x52 */
800 { 0x44,0x44, 66}, /* 0x53 Chrontel */
801 { 0x3a,0x62, 70}, /* 0x54 Chrontel */
802 { 0x62,0xc6, 34}, /* 0x55 848x480-60 */
803 { 0x6a,0xc6, 37}, /* 0x56 848x480-75 - TEMP */
804 { 0xbf,0xc8, 35}, /* 0x57 856x480-38i,60 */
805 { 0x30,0x23, 88}, /* 0x58 1360x768-62 (is 60Hz!) */
806 { 0x52,0x07,149}, /* 0x59 1280x960-85 */
807 { 0x56,0x07,156}, /* 0x5a 1400x1050-75 */
808 { 0x70,0x29, 81}, /* 0x5b 1280x768 LCD */
809 { 0x45,0x25, 83}, /* 0x5c 1280x800 */
810 { 0x70,0x0a,147}, /* 0x5d 1680x1050 */
811 { 0x70,0x24,162}, /* 0x5e 1600x1200 */
812 { 0x5a,0x64, 65}, /* 0x5f 1280x720 - temp */
813 { 0x63,0x46, 68}, /* 0x60 1280x768_2 */
814 { 0x31,0x42, 79}, /* 0x61 1280x768_3 - temp */
815 { 0, 0, 0}, /* 0x62 - custom (will be filled out at run-time) */
816 { 0x5a,0x64, 65}, /* 0x63 1280x720 (LCD LVDS) */
817 { 0x70,0x28, 90}, /* 0x64 1152x864@60 */
818 { 0x41,0xc4, 32}, /* 0x65 848x480@60 */
819 { 0x5c,0xc6, 32}, /* 0x66 856x480@60 */
820 { 0x76,0xe7, 27}, /* 0x67 720x480@60 */
821 { 0x5f,0xc6, 33}, /* 0x68 720/768x576@60 */
822 { 0x52,0x27, 75}, /* 0x69 1920x1080i 60Hz interlaced */
823 { 0x7c,0x6b, 38}, /* 0x6a 960x540@60 */
824 { 0xe3,0x56, 41}, /* 0x6b 960x600@60 */
825 { 0x45,0x25, 83}, /* 0x6c 1280x800 */
826 { 0x70,0x28, 90} /* 0x6d 1152x864@60 */
827};
828
829static SiS_VBVCLKDataStruct SiS310_VBVCLKData[]=
830{
831 { 0x1b,0xe1, 25}, /* 0x00 */
832 { 0x4e,0xe4, 28}, /* 0x01 */
833 { 0x57,0xe4, 31}, /* 0x02 */
834 { 0xc3,0xc8, 36}, /* 0x03 */
835 { 0x42,0x47, 40}, /* 0x04 */
836 { 0xfe,0xcd, 43}, /* 0x05 */
837 { 0x5d,0xc4, 44}, /* 0x06 */
838 { 0x52,0x47, 49}, /* 0x07 */
839 { 0x53,0x47, 50}, /* 0x08 */
840 { 0x74,0x67, 52}, /* 0x09 */
841 { 0x6d,0x66, 56}, /* 0x0a */
842 { 0x35,0x62, 65}, /* 0x0b */ /* Was 0x5a,0x64 - 650/LVDS+301: 35,62 */
843 { 0x46,0x44, 67}, /* 0x0c */
844 { 0xb1,0x46, 68}, /* 0x0d */
845 { 0xd3,0x4a, 72}, /* 0x0e */
846 { 0x29,0x61, 75}, /* 0x0f */
847 { 0x6d,0x46, 75}, /* 0x10 */
848 { 0x41,0x43, 78}, /* 0x11 */
849 { 0x31,0x42, 79}, /* 0x12 */
850 { 0xab,0x44, 83}, /* 0x13 */
851 { 0x46,0x25, 84}, /* 0x14 */
852 { 0x78,0x29, 86}, /* 0x15 */
853 { 0x62,0x44, 94}, /* 0x16 */
854 { 0x2b,0x22,104}, /* 0x17 */
855 { 0x49,0x24,105}, /* 0x18 */
856 { 0xf8,0x2f,108}, /* 0x19 */ /* 1400x1050 LCD */
857 { 0x3c,0x23,109}, /* 0x1a */
858 { 0x5e,0x43,113}, /* 0x1b */
859 { 0xbc,0x44,116}, /* 0x1c */
860 { 0xe0,0x46,132}, /* 0x1d */
861#if 0
862 { 0xd4,0x28,135}, /* 0x1e */
863 { 0xea,0x2a,139}, /* 0x1f */
864 { 0x41,0x22,157}, /* 0x20 */
865 { 0x70,0x24,162}, /* 0x21 */
866#endif
867 { 0xe2,0x46,135}, /* 0x1e */ /* 1280x1024-75, better clock for VGA2 */
868 { 0xe5,0x46,139}, /* 0x1f */ /* 1024x768-120, better clock for VGA2 */
869 { 0x15,0x01,157}, /* 0x20 */ /* 1280x1024-85, better clock for VGA2 */
870 { 0x70,0x09,162}, /* 0x21 */ /* 1600x1200-60, better clock for VGA2 */
871 { 0x30,0x21,175}, /* 0x22 */
872 { 0x4e,0x22,189}, /* 0x23 */
873 { 0xde,0x26,194}, /* 0x24 */
874 { 0x70,0x07,202}, /* 0x25 */
875 { 0x3f,0x03,229}, /* 0x26 */
876 { 0xb8,0x06,234}, /* 0x27 */
877 { 0x34,0x02,253}, /* 0x28 */
878 { 0x58,0x04,255}, /* 0x29 */
879 { 0x24,0x01,265}, /* 0x2a */
880 { 0x9b,0x02,267}, /* 0x2b */
881 { 0x70,0x05,270}, /* 0x2c */
882 { 0x25,0x01,272}, /* 0x2d */
883 { 0x9c,0x02,277}, /* 0x2e */
884 { 0x27,0x01,286}, /* 0x2f */
885 { 0x3c,0x02,291}, /* 0x30 */
886 { 0xef,0x0a,292}, /* 0x31 */
887 { 0xf6,0x0a,310}, /* 0x32 */
888 { 0x95,0x01,315}, /* 0x33 */
889 { 0xf0,0x09,324}, /* 0x34 */
890 { 0xfe,0x0a,331}, /* 0x35 */
891 { 0xf3,0x09,332}, /* 0x36 */
892 { 0xea,0x08,340}, /* 0x37 */
893 { 0xe8,0x07,376}, /* 0x38 */
894 { 0xde,0x06,389}, /* 0x39 */
895 { 0x52,0x2a, 54}, /* 0x3a 301 TV - start */
896 { 0x52,0x6a, 27}, /* 0x3b 301 TV */
897 { 0x62,0x24, 70}, /* 0x3c 301 TV */
898 { 0x62,0x64, 70}, /* 0x3d 301 TV */
899 { 0xa8,0x4c, 30}, /* 0x3e 301 TV */
900 { 0x20,0x26, 33}, /* 0x3f 301 TV */
901 { 0x31,0xc2, 39}, /* 0x40 */
902 { 0x2e,0x48, 25}, /* 0x41 Replacement for LCD on 315 for index 0 */
903 { 0x24,0x46, 25}, /* 0x42 Replacement for LCD on 315 for modes 0x01, 0x03, 0x0f, 0x10, 0x12 */
904 { 0x26,0x64, 28}, /* 0x43 Replacement for LCD on 315 for index 1 */
905 { 0x37,0x64, 40}, /* 0x44 Replacement for LCD on 315 for index 4 */
906 { 0xa1,0x42,108}, /* 0x45 1280x960 LCD */
907 { 0x37,0x61,100}, /* 0x46 1280x960 LCD */
908 { 0x78,0x27,108}, /* 0x47 */
909 { 0x97,0x2c, 26}, /* 0x48 UNUSED */
910 { 0xce,0x3c, 39}, /* 0x49 UNUSED */
911 { 0x52,0x4a, 36}, /* 0x4a UNUSED */
912 { 0x34,0x61, 95}, /* 0x4b UNUSED */
913 { 0x78,0x27,108}, /* 0x4c UNUSED */
914 { 0x66,0x43,123}, /* 0x4d 1400x1050-60 */
915 { 0x41,0x4e, 21}, /* 0x4e UNUSED */
916 { 0xa1,0x4a, 29}, /* 0x4f UNUSED */
917 { 0x19,0x42, 42}, /* 0x50 UNUSED */
918 { 0x54,0x46, 58}, /* 0x51 UNUSED */
919 { 0x25,0x42, 61}, /* 0x52 UNUSED */
920 { 0x44,0x44, 66}, /* 0x53 UNUSED */
921 { 0x3a,0x62, 70}, /* 0x54 UNUSED */
922 { 0x62,0xc6, 34}, /* 0x55 848x480-60 */
923 { 0x6a,0xc6, 37}, /* 0x56 848x480-75 - TEMP, UNUSED */
924 { 0xbf,0xc8, 35}, /* 0x57 856x480-38i,60 */
925 { 0x30,0x23, 88}, /* 0x58 1360x768-62 (is 60Hz!) TEMP, UNUSED */
926 { 0x52,0x07,149}, /* 0x59 1280x960-85 */
927 { 0x56,0x07,156}, /* 0x5a 1400x1050-75 */
928 { 0x70,0x29, 81}, /* 0x5b 1280x768 LCD (TMDS) */
929 { 0xce,0x1e, 73}, /* 0x5c 1280x800_2 LCD (SiS LVDS) - (CRT1: 45 25 83) */
930 { 0xbe,0x44,121}, /* 0x5d 1680x1050 LCD */
931 { 0x70,0x24,162}, /* 0x5e 1600x1200 LCD */
932 { 0x52,0x27, 75}, /* 0x5f 1280x720 (TMDS + HDTV) (correct) */
933 { 0xc8,0x48, 77}, /* 0x60 1280x768_2 (SiS LVDS) */
934 { 0x31,0x42, 79}, /* 0x61 1280x768_3 (SiS LVDS) - temp */
935 { 0, 0, 0}, /* 0x62 - custom (will be filled out at run-time) */
936 { 0x9c,0x62, 69}, /* 0x63 1280x720 (SiS LVDS) */
937 { 0x70,0x28, 90}, /* 0x64 1152x864@60 */
938 { 0x41,0xc4, 32}, /* 0x65 848x480@60 */
939 { 0x5c,0xc6, 32}, /* 0x66 856x480@60 */
940 { 0x76,0xe7, 27}, /* 0x67 720x480@60 */
941 { 0x5f,0xc6, 33}, /* 0x68 720/768x576@60 */
942 { 0x52,0x27, 75}, /* 0x69 1920x1080i 60Hz interlaced (UNUSED) */
943 { 0x7c,0x6b, 38}, /* 0x6a 960x540@60 */
944 { 0xe3,0x56, 41}, /* 0x6b 960x600@60 */
945 { 0x9c,0x62, 69}, /* 0x6c 1280x800 (SiS TMDS) (special) */
946 { 0x70,0x28, 90} /* 0x6d 1152x864@60 */
947};
948
949static const DRAM4Type SiS310_SR15[8] = {
950 {0x00,0x04,0x60,0x60},
951 {0x0f,0x0f,0x0f,0x0f},
952 {0xba,0xba,0xba,0xba},
953 {0xa9,0xa9,0xac,0xac},
954 {0xa0,0xa0,0xa0,0xa8},
955 {0x00,0x00,0x02,0x02},
956 {0x30,0x30,0x40,0x40},
957 {0x00,0xa5,0xfb,0xf6}
958};
959
960#ifdef LINUX_KERNEL
961
962static UCHAR SiS310_SR07 = 0x18;
963
964static const DRAM4Type SiS310_CR40[5] = {
965 {0x77,0x77,0x33,0x33},
966 {0x77,0x77,0x33,0x33},
967 {0x00,0x00,0x00,0x00},
968 {0x5b,0x5b,0x03,0x03},
969 {0x00,0x00,0xf0,0xf8}
970};
971
972static UCHAR SiS310_CR49[] = {0xaa,0x88};
973static UCHAR SiS310_SR1F = 0x00;
974static UCHAR SiS310_SR21 = 0xa5;
975static UCHAR SiS310_SR22 = 0xfb;
976static UCHAR SiS310_SR23 = 0xf6;
977static UCHAR SiS310_SR24 = 0x0d;
978static UCHAR SiS310_SR25[] = {0x33,0x3};
979static UCHAR SiS310_SR31 = 0x00;
980static UCHAR SiS310_SR32 = 0x11;
981static UCHAR SiS310_SR33 = 0x00;
982static UCHAR SiS310_CRT2Data_1_2 = 0x00;
983static UCHAR SiS310_CRT2Data_4_D = 0x00;
984static UCHAR SiS310_CRT2Data_4_E = 0x00;
985static UCHAR SiS310_CRT2Data_4_10 = 0x80;
986static const USHORT SiS310_RGBSenseData = 0xd1;
987static const USHORT SiS310_VideoSenseData = 0xb9;
988static const USHORT SiS310_YCSenseData = 0xb3;
989static const USHORT SiS310_RGBSenseData2 = 0x0190;
990static const USHORT SiS310_VideoSenseData2 = 0x0174;
991static const USHORT SiS310_YCSenseData2 = 0x016b;
992#endif
993
994static const SiS_PanelDelayTblStruct SiS310_PanelDelayTbl[]=
995{
996 {{0x10,0x40}},
997 {{0x10,0x40}},
998 {{0x10,0x40}},
999 {{0x10,0x40}},
1000 {{0x10,0x40}},
1001 {{0x10,0x40}},
1002 {{0x10,0x40}},
1003 {{0x10,0x40}},
1004 {{0x10,0x40}},
1005 {{0x10,0x40}},
1006 {{0x10,0x40}},
1007 {{0x10,0x40}},
1008 {{0x10,0x40}},
1009 {{0x10,0x40}},
1010 {{0x10,0x40}},
1011 {{0x10,0x40}}
1012};
1013
1014static const SiS_PanelDelayTblStruct SiS310_PanelDelayTblLVDS[]=
1015{
1016 {{0x28,0xc8}},
1017 {{0x28,0xc8}},
1018 {{0x28,0xc8}},
1019 {{0x28,0xc8}},
1020 {{0x28,0xc8}},
1021 {{0x28,0xc8}},
1022 {{0x28,0xc8}},
1023 {{0x28,0xc8}},
1024 {{0x28,0xc8}},
1025 {{0x28,0xc8}},
1026 {{0x28,0xc8}},
1027 {{0x28,0xc8}},
1028 {{0x28,0xc8}},
1029 {{0x28,0xc8}},
1030 {{0x28,0xc8}},
1031 {{0x28,0xc8}}
1032};
1033
1034/**************************************************************/
1035/* SIS VIDEO BRIDGE ----------------------------------------- */
1036/**************************************************************/
1037
1038static const SiS_LCDDataStruct SiS310_St2LCD1024x768Data[] =
1039{
1040 { 62, 25, 800, 546,1344, 806},
1041 { 32, 15, 930, 546,1344, 806},
1042 { 62, 25, 800, 546,1344, 806},
1043 { 104, 45, 945, 496,1344, 806},
1044 { 62, 25, 800, 546,1344, 806},
1045 { 31, 18,1008, 624,1344, 806},
1046 { 1, 1,1344, 806,1344, 806}
1047};
1048
1049static const SiS_LCDDataStruct SiS310_ExtLCD1024x768Data[] =
1050{
1051 { 42, 25,1536, 419,1344, 806},
1052 { 48, 25,1536, 369,1344, 806},
1053 { 42, 25,1536, 419,1344, 806},
1054 { 48, 25,1536, 369,1344, 806},
1055 { 12, 5, 896, 500,1344, 806},
1056 { 42, 25,1024, 625,1344, 806},
1057 { 1, 1,1344, 806,1344, 806}
1058};
1059
1060static const SiS_LCDDataStruct SiS310_St2LCD1280x1024Data[] =
1061{
1062 { 22, 5, 800, 510,1650,1088},
1063 { 22, 5, 800, 510,1650,1088},
1064 { 176, 45, 900, 510,1650,1088},
1065 { 176, 45, 900, 510,1650,1088},
1066 { 22, 5, 800, 510,1650,1088},
1067 { 13, 5,1024, 675,1560,1152},
1068 { 16, 9,1266, 804,1688,1072},
1069 { 1, 1,1688,1066,1688,1066}
1070};
1071
1072static const SiS_LCDDataStruct SiS310_ExtLCD1280x1024Data[] =
1073{
1074 { 211, 60,1024, 501,1688,1066},
1075 { 211, 60,1024, 508,1688,1066},
1076 { 211, 60,1024, 501,1688,1066},
1077 { 211, 60,1024, 508,1688,1066},
1078 { 211, 60,1024, 500,1688,1066},
1079 { 211, 75,1024, 625,1688,1066},
1080 { 211, 120,1280, 798,1688,1066},
1081 { 1, 1,1688,1066,1688,1066}
1082};
1083
1084static const SiS_Part2PortTblStruct SiS310_CRT2Part2_1024x768_1[] =
1085{
1086 {{0x25,0x12,0xc9,0xdc,0xb6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
1087 {{0x2c,0x12,0x9a,0xae,0x88,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
1088 {{0x25,0x12,0xc9,0xdc,0xb6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
1089 {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
1090 {{0x38,0x13,0x16,0x0c,0xe6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
1091 {{0x38,0x18,0x16,0x00,0x00,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
1092 {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}
1093};
1094
1095/* *** LCDA *** */
1096
1097#if 0
1098static const SiS_LVDSDataStruct SiS_LCDA1600x1200Data_1[]=
1099{ /* Clevo, 651+301C */
1100 {1200, 450, 2048,1250},
1101 {1200, 400, 2048,1250},
1102 {1280, 450, 2048,1250},
1103 {1280, 400, 2048,1250},
1104 {1200, 530, 2048,1250},
1105 {1360, 650, 2048,1250},
1106 {1584, 818, 2048,1250},
1107 {1688,1066, 2048,1250},
1108 {1688,1066, 2048,1250},
1109#if 0
1110 {2048,1250, 2048,1250} /* this should be correct */
1111#endif
1112#if 1
1113 {2160,1250, 2048,1250} /* ? */
1114#endif
1115};
1116#endif
1117
1118/**************************************************************/
1119/* LVDS, CHRONTEL ------------------------------------------- */
1120/**************************************************************/
1121
1122static const SiS_LVDSDataStruct SiS310_CHTVUPALData[]=
1123{
1124 {1008, 625,1008, 625},
1125 {1008, 625,1008, 625},
1126 {1008, 625,1008, 625},
1127 {1008, 625,1008, 625},
1128 { 840, 625, 840, 625},
1129 { 960, 750, 960, 750},
1130 {1400,1000,1400,1000}
1131};
1132
1133static const SiS_LVDSDataStruct SiS310_CHTVOPALData[]=
1134{
1135 {1008, 625,1008, 625},
1136 {1008, 625,1008, 625},
1137 {1008, 625,1008, 625},
1138 {1008, 625,1008, 625},
1139 { 840, 625, 840, 625},
1140 { 944, 625, 944, 625},
1141 {1400, 875,1400, 875}
1142};
1143
1144static const SiS_LVDSDataStruct SiS310_CHTVUPALMData[]=
1145{
1146 { 840, 600, 840, 600},
1147 { 840, 600, 840, 600},
1148 { 840, 600, 840, 600},
1149 { 840, 600, 840, 600},
1150 { 784, 600, 784, 600},
1151 {1064, 750,1064, 750},
1152 {1160, 945,1160, 945}
1153};
1154
1155static const SiS_LVDSDataStruct SiS310_CHTVOPALMData[]=
1156{
1157 { 840, 525, 840, 525},
1158 { 840, 525, 840, 525},
1159 { 840, 525, 840, 525},
1160 { 840, 525, 840, 525},
1161 { 784, 525, 784, 525},
1162 {1040, 700,1040, 700},
1163 {1160, 840,1160, 840}
1164};
1165
1166static const SiS_LVDSDataStruct SiS310_CHTVUPALNData[]=
1167{
1168 {1008, 625,1008, 625},
1169 {1008, 625,1008, 625},
1170 {1008, 625,1008, 625},
1171 {1008, 625,1008, 625},
1172 { 840, 625, 840, 625},
1173 { 960, 750, 960, 750},
1174 {1400,1000,1400,1000}
1175};
1176
1177static const SiS_LVDSDataStruct SiS310_CHTVOPALNData[]=
1178{
1179 {1008, 625,1008, 625},
1180 {1008, 625,1008, 625},
1181 {1008, 625,1008, 625},
1182 {1008, 625,1008, 625},
1183 { 840, 625, 840, 625},
1184 { 944, 625, 944, 625},
1185 {1400, 875,1400, 875}
1186};
1187
1188static const SiS_LVDSDataStruct SiS310_CHTVSOPALData[]= /* (super overscan - no effect on 7019) */
1189{
1190 {1008, 625,1008, 625},
1191 {1008, 625,1008, 625},
1192 {1008, 625,1008, 625},
1193 {1008, 625,1008, 625},
1194 { 840, 625, 840, 625},
1195 { 944, 625, 944, 625},
1196 {1400, 875,1400, 875}
1197};
1198
1199
1200static const SiS_LVDSDesStruct SiS310_PanelType00_1[]= /* 800x600 */
1201{
1202 { 0, 0},
1203 { 0, 0},
1204 { 0, 0},
1205 { 0, 0},
1206 { 0, 0},
1207 { 0, 0},
1208 { 0, 0},
1209 { 0, 0},
1210 { 0, 0}
1211};
1212
1213static const SiS_LVDSDesStruct SiS310_PanelType01_1[]= /* 1024x768 */
1214{
1215 { 0, 0},
1216 { 0, 0},
1217 { 0, 0},
1218 { 0, 0},
1219 { 0, 0},
1220 { 0, 0},
1221 { 0, 805},
1222 { 0, 0},
1223 { 0, 0}
1224};
1225
1226static const SiS_LVDSDesStruct SiS310_PanelType02_1[]= /* 1280x1024 */
1227{
1228 { 0, 0},
1229 { 0, 0},
1230 { 0, 0},
1231 { 0, 0},
1232 { 0, 0},
1233 { 0, 0},
1234 { 0, 0},
1235 { 0, 1065},
1236 { 0, 0},
1237 { 0, 0}
1238};
1239
1240
1241static const SiS_LVDSDesStruct SiS310_PanelType03_1[]=
1242{
1243 { 0, 0},
1244 { 0, 0},
1245 { 0, 0},
1246 { 0, 0},
1247 { 0, 0},
1248 { 0, 0},
1249 { 0, 0},
1250 { 0, 0},
1251 { 0, 0}
1252};
1253
1254static const SiS_LVDSDesStruct SiS310_PanelType04_1[]=
1255{
1256 {1343, 798},
1257 {1343, 794},
1258 {1343, 798},
1259 {1343, 794},
1260 {1343, 0},
1261 {1343, 0},
1262 { 0, 805},
1263 { 0, 794},
1264 { 0, 0}
1265};
1266
1267static const SiS_LVDSDesStruct SiS310_PanelType05_1[]=
1268{
1269 {1343, 798},
1270 {1343, 794},
1271 {1343, 798},
1272 {1343, 794},
1273 {1343, 0},
1274 {1343, 0},
1275 { 0, 805},
1276 { 0, 794},
1277 { 0, 0}
1278};
1279
1280static const SiS_LVDSDesStruct SiS310_PanelType06_1[]=
1281{
1282 {1343, 798},
1283 {1343, 794},
1284 {1343, 798},
1285 {1343, 794},
1286 {1343, 0},
1287 {1343, 0},
1288 { 0, 805},
1289 { 0, 794},
1290 { 0, 0}
1291};
1292
1293static const SiS_LVDSDesStruct SiS310_PanelType07_1[]=
1294{
1295 {1343, 798},
1296 {1343, 794},
1297 {1343, 798},
1298 {1343, 794},
1299 {1343, 0},
1300 {1343, 0},
1301 { 0, 805},
1302 { 0, 794},
1303 { 0, 0}
1304};
1305
1306static const SiS_LVDSDesStruct SiS310_PanelType08_1[]= /* 1400x1050 */
1307{
1308 { 0, 0},
1309 { 0, 0},
1310 { 0, 0},
1311 { 0, 0},
1312 { 0, 0},
1313 { 0, 0},
1314 { 0, 0},
1315 { 0, 0},
1316 { 0, 0},
1317 { 0, 0},
1318 { 0, 0}
1319};
1320
1321static const SiS_LVDSDesStruct SiS310_PanelType09_1[]= /* 1280x768 */
1322{
1323 { 0, 0},
1324 { 0, 0},
1325 { 0, 0},
1326 { 0, 0},
1327 { 0, 0},
1328 { 0, 0},
1329 { 0, 0},
1330 { 0, 0},
1331 { 0, 0},
1332 { 0, 0},
1333 { 0, 0}
1334};
1335
1336static const SiS_LVDSDesStruct SiS310_PanelType0a_1[]= /* 1600x1200 */
1337{
1338 { 0, 0},
1339 { 0, 0},
1340 { 0, 0},
1341 { 0, 0},
1342 { 0, 0},
1343 { 0, 0},
1344 { 0, 0},
1345 { 0, 0},
1346 { 0, 0},
1347 { 0, 0},
1348 { 0, 0}
1349};
1350
1351static const SiS_LVDSDesStruct SiS310_PanelType0b_1[]= /* 640x480_2 */
1352{
1353 { 0, 524},
1354 { 0, 524},
1355 { 0, 524},
1356 { 0, 524},
1357 { 0, 524},
1358 { 0, 524},
1359 { 8, 524},
1360 { 0, 524}
1361};
1362
1363static const SiS_LVDSDesStruct SiS310_PanelType0c_1[]= /* 640x480_3 */
1364{
1365 { 0, 524},
1366 { 0, 524},
1367 { 0, 524},
1368 { 0, 524},
1369 { 0, 524},
1370 { 0, 524},
1371 { 8, 524},
1372 { 0, 524}
1373};
1374
1375static const SiS_LVDSDesStruct SiS310_PanelType0d_1[]=
1376{
1377 {1343, 798},
1378 {1343, 794},
1379 {1343, 798},
1380 {1343, 794},
1381 {1343, 0},
1382 {1343, 0},
1383 { 0, 805},
1384 { 0, 794},
1385 { 0, 0}
1386};
1387
1388static const SiS_LVDSDesStruct SiS310_PanelType0e_1[]=
1389{
1390 {1343, 798},
1391 {1343, 794},
1392 {1343, 798},
1393 {1343, 794},
1394 {1343, 0},
1395 {1343, 0},
1396 { 0, 805},
1397 { 0, 794},
1398 { 0, 0}
1399};
1400
1401static const SiS_LVDSDesStruct SiS310_PanelType0f_1[]=
1402{
1403 {1343, 798},
1404 {1343, 794},
1405 {1343, 798},
1406 {1343, 794},
1407 {1343, 0},
1408 {1343, 0},
1409 { 0, 805},
1410 { 0, 794},
1411 { 0, 0}
1412};
1413
1414static const SiS_LVDSDesStruct SiS310_PanelType00_2[]=
1415{
1416 {980, 528},
1417 {980, 503},
1418 {980, 528},
1419 {980, 503},
1420 {980, 568},
1421 { 0, 628},
1422 { 0, 0},
1423 { 0, 0},
1424 { 0, 0}
1425};
1426
1427static const SiS_LVDSDesStruct SiS310_PanelType01_2[]=
1428{
1429 {1152, 622},
1430 {1152, 597},
1431 {1152, 622},
1432 {1152, 597},
1433 {1152, 662},
1434 {1232, 722},
1435 { 0, 806},
1436 { 0, 0},
1437 { 0, 0}
1438};
1439
1440static const SiS_LVDSDesStruct SiS310_PanelType02_2[]=
1441{
1442 {1368, 754},
1443 {1368, 729},
1444 {1368, 754},
1445 {1368, 729},
1446 {1368, 794},
1447 {1448, 854},
1448 {1560, 938},
1449 { 0,1066},
1450 { 0, 0},
1451 { 0, 0},
1452 { 0, 0}
1453};
1454
1455static const SiS_LVDSDesStruct SiS310_PanelType03_2[]=
1456{
1457 { 0, 0},
1458 { 0, 0},
1459 { 0, 0},
1460 { 0, 0},
1461 { 0, 0},
1462 { 0, 0},
1463 { 0, 0}
1464};
1465
1466static const SiS_LVDSDesStruct SiS310_PanelType04_2[]=
1467{
1468 { 0, 0},
1469 { 0, 0},
1470 { 0, 0},
1471 { 0, 0},
1472 { 0, 0},
1473 { 0, 0},
1474 { 0, 0},
1475 { 0, 0},
1476 { 0, 0}
1477};
1478
1479static const SiS_LVDSDesStruct SiS310_PanelType05_2[]=
1480{
1481 {1152, 622},
1482 {1152, 597},
1483 {1152, 622},
1484 {1152, 597},
1485 {1152, 662},
1486 {1232, 722},
1487 { 0, 805},
1488 { 0, 794},
1489 { 0, 0}
1490};
1491
1492static const SiS_LVDSDesStruct SiS310_PanelType06_2[]=
1493{
1494 {1152, 622},
1495 {1152, 597},
1496 {1152, 622},
1497 {1152, 597},
1498 {1152, 662},
1499 {1232, 722},
1500 { 0, 805},
1501 { 0, 794},
1502 { 0, 0}
1503};
1504
1505static const SiS_LVDSDesStruct SiS310_PanelType07_2[]=
1506{
1507 {1152, 622},
1508 {1152, 597},
1509 {1152, 622},
1510 {1152, 597},
1511 {1152, 662},
1512 {1232, 722},
1513 { 0, 805},
1514 { 0, 794},
1515 { 0, 0}
1516};
1517
1518static const SiS_LVDSDesStruct SiS310_PanelType08_2[]= /* 1400x1050 */
1519{
1520 {1308, 741},
1521 {1308, 716},
1522 {1308, 741},
1523 {1308, 716},
1524 {1308, 781},
1525 {1388, 841},
1526 {1500, 925},
1527 {1628,1053},
1528 { 0,1065},
1529 { 0, 0},
1530 { 0, 0}
1531};
1532
1533static const SiS_LVDSDesStruct SiS310_PanelType09_2[]= /* 1280x768 */
1534{
1535 {1083, 622},
1536 {1083, 597},
1537 {1083, 622},
1538 {1083, 597},
1539 {1083, 662},
1540 {1163, 722},
1541 {1286, 805},
1542 { 0, 794},
1543 { 0, 0}
1544};
1545
1546static const SiS_LVDSDesStruct SiS310_PanelType0a_2[]= /* 1600x1200 */
1547{
1548 {1568, 920},
1549 {1568, 895},
1550 {1568, 920},
1551 {1568, 895},
1552 {1568, 960},
1553 {1648,1020},
1554 {1760,1104},
1555 {1888,1232},
1556 {1948,1245},
1557 { 0, 0}
1558#if 0
1559 {1568, 850},
1560 {1568, 825},
1561 {1568, 850},
1562 {1568, 825},
1563 {1568, 890},
1564 {1648, 950},
1565 {1760,1034},
1566 {1888,1162},
1567 {1948,1175},
1568 { 0, 0}
1569#endif
1570};
1571
1572static const SiS_LVDSDesStruct SiS310_PanelType0b_2[]= /* 640x480_2 */
1573{
1574 {1152, 622},
1575 {1152, 597},
1576 {1152, 622},
1577 {1152, 597},
1578 {1152, 662},
1579 {1232, 722},
1580 { 0, 805},
1581 { 0, 794},
1582 { 0, 0}
1583};
1584
1585static const SiS_LVDSDesStruct SiS310_PanelType0c_2[]= /* 640x480_3 */
1586{
1587 {1152, 622},
1588 {1152, 597},
1589 {1152, 622},
1590 {1152, 597},
1591 {1152, 662},
1592 {1232, 722},
1593 { 0, 805},
1594 { 0, 794},
1595 { 0, 0}
1596};
1597
1598static const SiS_LVDSDesStruct SiS310_PanelType0d_2[]=
1599{
1600 {1152, 622},
1601 {1152, 597},
1602 {1152, 622},
1603 {1152, 597},
1604 {1152, 662},
1605 {1232, 722},
1606 { 0, 805},
1607 { 0, 794},
1608 { 0, 0}
1609};
1610
1611static const SiS_LVDSDesStruct SiS310_PanelType0e_2[]=
1612{
1613 {1152, 622},
1614 {1152, 597},
1615 {1152, 622},
1616 {1152, 597},
1617 {1152, 662},
1618 {1232, 722},
1619 { 0, 805},
1620 { 0, 794},
1621 { 0, 0}
1622};
1623
1624static const SiS_LVDSDesStruct SiS310_PanelType0f_2[] =
1625{
1626 {1152, 622},
1627 {1152, 597},
1628 {1152, 622},
1629 {1152, 597},
1630 {1152, 662},
1631 {1232, 722},
1632 { 0, 805},
1633 { 0, 794},
1634 { 0, 0}
1635};
1636
1637static const SiS_LVDSDesStruct SiS310_PanelTypeNS_1[]=
1638{
1639 { 8, 0},
1640 { 8, 0},
1641 { 8, 0},
1642 { 8, 0},
1643 { 8, 0},
1644 { 0, 0},
1645 { 0, 0},
1646 { 0, 0},
1647 { 0, 806},
1648 { 0, 0}
1649};
1650
1651static const SiS_LVDSDesStruct SiS310_PanelTypeNS_2[] =
1652{
1653 { 0 , 0},
1654 { 0 , 0},
1655 { 0 , 0},
1656 { 0 , 0},
1657 { 0 , 0},
1658 { 0 , 0},
1659 { 0 , 0},
1660 { 0 , 0},
1661 { 0 , 0},
1662 { 0 , 0}
1663};
1664
1665/* CRT1 CRTC for SlaveModes and LCDA */
1666
1667static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_1[] =
1668{
1669 {{0x6b,0x4f,0x8f,0x55,0x85,0xaa,0x1f,
1670 0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
1671 0x00 }},
1672 {{0x6b,0x4f,0x8f,0x55,0x85,0x78,0x1f,
1673 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
1674 0x00 }},
1675 {{0x6b,0x4f,0x8f,0x55,0x85,0xaa,0x1f,
1676 0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
1677 0x00 }},
1678 {{0x6b,0x4f,0x8f,0x55,0x85,0x78,0x1f,
1679 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
1680 0x00 }},
1681 {{0x6b,0x4f,0x8f,0x55,0x85,0xfa,0x1f,
1682 0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
1683 0x00 }},
1684 {{0x7f,0x63,0x83,0x69,0x19,0x72,0xf0,
1685 0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
1686 0x01 }}
1687};
1688
1689static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_1_H[] =
1690{
1691 {{0x43,0x27,0x87,0x2d,0x1d,0xaa,0x1f,
1692 0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
1693 0x00 }},
1694 {{0x43,0x27,0x87,0x2d,0x1d,0x78,0x1f,
1695 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
1696 0x00 }},
1697 {{0x43,0x27,0x87,0x2d,0x1d,0xfa,0x1f,
1698 0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
1699 0x00 }},
1700 {{0x43,0x27,0x87,0x2d,0x1d,0x78,0x1f,
1701 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
1702 0x00 }},
1703 {{0x43,0x27,0x87,0x2d,0x1d,0xfa,0x1f,
1704 0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
1705 0x00 }},
1706 {{0x4d,0x31,0x91,0x37,0x07,0x72,0xf0,
1707 0x58,0x8d,0x57,0x73,0x20,0x00,0x01,
1708 0x01 }}
1709};
1710
1711static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_2[]=
1712{
1713 {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
1714 0xff,0x84,0x8f,0x73,0x00,0x00,0x06,
1715 0x00 }},
1716 {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
1717 0xe6,0x8b,0x5d,0x73,0x00,0x00,0x06,
1718 0x00 }},
1719 {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
1720 0xff,0x84,0x8f,0x73,0x00,0x00,0x06,
1721 0x00 }},
1722 {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
1723 0xe6,0x8b,0x5d,0x73,0x00,0x00,0x06,
1724 0x00 }},
1725 {{0x7f,0x4f,0x83,0x62,0x12,0x72,0xba,
1726 0x27,0x8c,0xdf,0x73,0x00,0x00,0x06,
1727 0x00 }},
1728 {{0x7f,0x63,0x83,0x69,0x19,0x72,0xf0,
1729 0x58,0x8d,0x57,0x73,0x20,0x00,0x06,
1730 0x01 }}
1731};
1732
1733static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_2_H[] =
1734{
1735 {{0x57,0x27,0x9b,0x3a,0x0a,0x72,0x3e,
1736 0xff,0x84,0x8f,0x73,0x00,0x00,0x01,
1737 0x00 }},
1738 {{0x57,0x27,0x9b,0x3a,0x0a,0x72,0x3e,
1739 0xd6,0x8b,0x5d,0x73,0x00,0x00,0x01,
1740 0x00 }},
1741 {{0x57,0x27,0x9b,0x3a,0x0a,0x72,0x3e,
1742 0xff,0x84,0x8f,0x73,0x00,0x00,0x01,
1743 0x00 }},
1744 {{0x57,0x27,0x9b,0x3a,0x0a,0x72,0x3e,
1745 0xd6,0x8b,0x5d,0x73,0x00,0x00,0x01,
1746 0x00 }},
1747 {{0x57,0x27,0x9b,0x3a,0x0a,0x72,0xba,
1748 0x27,0x8c,0xdf,0x73,0x00,0x00,0x01,
1749 0x00 }},
1750 {{0x4d,0x31,0x91,0x3a,0x0a,0x72,0xf0,
1751 0x63,0x88,0x57,0x73,0x00,0x00,0x01,
1752 0x01 }}
1753};
1754
1755static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_1[] =
1756{
1757 {{0x73,0x4f,0x97,0x53,0x84,0xb4,0x1f,
1758 0x92,0x89,0x8f,0xb5,0x30,0x00,0x05,
1759 0x00}},
1760 {{0x73,0x4f,0x97,0x53,0x84,0x82,0x1f,
1761 0x60,0x87,0x5d,0x83,0x10,0x00,0x05,
1762 0x00}},
1763 {{0x73,0x4f,0x97,0x53,0x84,0xb4,0x1f,
1764 0x92,0x89,0x8f,0xb5,0x30,0x00,0x05,
1765 0x00}},
1766 {{0x73,0x4f,0x97,0x53,0x84,0x82,0x1f,
1767 0x60,0x87,0x5d,0x83,0x10,0x00,0x05,
1768 0x00}},
1769 {{0x73,0x4f,0x97,0x53,0x84,0x04,0x3e,
1770 0xE2,0x89,0xDf,0x05,0x00,0x00,0x05,
1771 0x00}},
1772 {{0x87,0x63,0x8B,0x67,0x18,0x7c,0xf0,
1773 0x5A,0x81,0x57,0x7D,0x00,0x00,0x06,
1774 0x01}},
1775 {{0xA3,0x7f,0x87,0x83,0x94,0x24,0xf5,
1776 0x02,0x89,0xFf,0x25,0x10,0x00,0x02,
1777 0x01}}
1778};
1779
1780static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_1_H[] =
1781{
1782 {{0x4b,0x27,0x8f,0x2b,0x1c,0xb4,0x1f,
1783 0x92,0x89,0x8f,0xb5,0x30,0x00,0x05,
1784 0x00 }},
1785 {{0x4b,0x27,0x8f,0x2b,0x1c,0x82,0x1f,
1786 0x60,0x87,0x5D,0x83,0x01,0x00,0x05,
1787 0x00}},
1788 {{0x4b,0x27,0x8f,0x2b,0x1c,0xb4,0x1f,
1789 0x92,0x89,0x8f,0xb5,0x30,0x00,0x05,
1790 0x00}},
1791 {{0x4b,0x27,0x8f,0x2b,0x1c,0x82,0x1f,
1792 0x60,0x87,0x5D,0x83,0x01,0x00,0x05,
1793 0x00}},
1794 {{0x4b,0x27,0x8f,0x2b,0x1c,0x04,0x3e,
1795 0xE2,0x89,0xDf,0x05,0x00,0x00,0x05,
1796 0x00}},
1797 {{0x55,0x31,0x99,0x35,0x06,0x7c,0xf0,
1798 0x5A,0x81,0x57,0x7D,0x00,0x00,0x01,
1799 0x01}},
1800 {{0x63,0x3F,0x87,0x43,0x94,0x24,0xf5,
1801 0x02,0x89,0xFf,0x25,0x10,0x00,0x01,
1802 0x01 }}
1803};
1804
1805static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_2[] =
1806{
1807 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1808 0x57,0x8e,0x8f,0x25,0x30,0x00,0x06,
1809 0x00 }},
1810 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1811 0x3e,0x85,0x5d,0x25,0x10,0x00,0x06,
1812 0x00 }},
1813 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1814 0x57,0x8e,0x8f,0x25,0x30,0x00,0x06,
1815 0x00 }},
1816 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1817 0x3e,0x85,0x5d,0x25,0x10,0x00,0x06,
1818 0x01 }},
1819 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1820 0x7f,0x86,0xdf,0x25,0x10,0x00,0x06,
1821 0x00 }},
1822 {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
1823 0xbb,0x82,0x57,0x25,0x10,0x00,0x02,
1824 0x01 }},
1825 {{0xa3,0x7f,0x87,0x83,0x94,0x24,0xf5,
1826 0x02,0x89,0xff,0x25,0x10,0x00,0x02,
1827 0x01 }}
1828};
1829
1830static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_2_H[] =
1831{
1832 {{0x7b,0x27,0x9f,0x46,0x97,0x24,0xbb,
1833 0x57,0x8e,0x8f,0x25,0x30,0x00,0x01,
1834 0x00 }},
1835 {{0x7b,0x27,0x9f,0x46,0x97,0x24,0xbb,
1836 0x3e,0x85,0x5d,0x25,0x10,0x00,0x01,
1837 0x00 }},
1838 {{0x7b,0x27,0x9f,0x46,0x97,0x24,0xbb,
1839 0x57,0x8e,0x8f,0x25,0x30,0x00,0x01,
1840 0x00 }},
1841 {{0x7b,0x27,0x9f,0x46,0x97,0x24,0xbb,
1842 0x3e,0x85,0x5d,0x25,0x10,0x00,0x01,
1843 0x00 }},
1844 {{0x7b,0x27,0x9f,0x46,0x97,0x24,0xbb,
1845 0x7f,0x86,0xdf,0x25,0x10,0x00,0x01,
1846 0x00 }},
1847 {{0x71,0x31,0x95,0x46,0x97,0x24,0xf1,
1848 0xbb,0x82,0x57,0x25,0x10,0x00,0x01,
1849 0x01 }},
1850 {{0x63,0x3f,0x87,0x46,0x97,0x24,0xf5,
1851 0x0f,0x86,0xff,0x25,0x30,0x00,0x01,
1852 0x01 }}
1853};
1854
1855static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11280x1024_1[] =
1856{
1857 {{0x7e,0x4f,0x82,0x58,0x04,0xb8,0x1f,
1858 0x90,0x84,0x8f,0xb9,0x30,0x00,0x06,
1859 0x00}},
1860 {{0x7e,0x4f,0x82,0x58,0x04,0x86,0x1f,
1861 0x5e,0x82,0x5d,0x87,0x10,0x00,0x06,
1862 0x00}},
1863 {{0x7e,0x4f,0x82,0x58,0x04,0xb8,0x1f,
1864 0x90,0x84,0x8f,0xb9,0x30,0x00,0x06,
1865 0x00}},
1866 {{0x7e,0x4f,0x82,0x58,0x04,0x86,0x1f,
1867 0x5e,0x82,0x5d,0x87,0x10,0x00,0x06,
1868 0x00}},
1869 {{0x7e,0x4f,0x82,0x58,0x04,0x08,0x3e,
1870 0xe0,0x84,0xdf,0x09,0x00,0x00,0x06,
1871 0x00}},
1872 {{0x92,0x63,0x96,0x6c,0x18,0x80,0xf0,
1873 0x58,0x8c,0x57,0x81,0x20,0x00,0x06,
1874 0x01}},
1875 {{0xae,0x7f,0x92,0x88,0x94,0x28,0xf5,
1876 0x00,0x84,0xff,0x29,0x10,0x00,0x02,
1877 0x01}},
1878 {{0xce,0x9f,0x92,0xa8,0x14,0x28,0x5a,
1879 0x00,0x84,0xff,0x29,0x09,0x00,0x07,
1880 0x01}}
1881};
1882
1883static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11280x1024_1_H[] =
1884{
1885 {{0x56,0x27,0x9a,0x31,0x1c,0xb8,0x1f,
1886 0x90,0x84,0x8f,0xb9,0x30,0x00,0x05,
1887 0x00}},
1888 {{0x56,0x27,0x9a,0x31,0x1c,0x86,0x1f,
1889 0x5e,0x82,0x5d,0x87,0x10,0x00,0x05,
1890 0x00}},
1891 {{0x56,0x27,0x9a,0x31,0x1c,0xb8,0x1f,
1892 0x90,0x84,0x8f,0xb9,0x30,0x00,0x05,
1893 0x00}},
1894 {{0x56,0x27,0x9a,0x31,0x1c,0x86,0x1f,
1895 0x5e,0x82,0x5d,0x87,0x10,0x00,0x05,
1896 0x01}},
1897 {{0x56,0x27,0x9a,0x31,0x1c,0x08,0x3e,
1898 0xe0,0x84,0xdf,0x09,0x00,0x00,0x05,
1899 0x00}},
1900 {{0x60,0x31,0x84,0x3a,0x86,0x80,0xf0,
1901 0x58,0x8c,0x57,0x81,0x20,0x00,0x01,
1902 0x01}},
1903 {{0x6e,0x3f,0x92,0x48,0x94,0x28,0xf5,
1904 0x00,0x84,0xff,0x29,0x10,0x00,0x01,
1905 0x01}}
1906};
1907
1908static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11280x1024_2[] =
1909{
1910 {{0xce,0x72,0x91,0x81,0x8f,0x28,0x92,
1911 0xc8,0x8c,0x5d,0x5c,0x01,0x00,0x02,
1912 0x01}},
1913 {{0xce,0x72,0x91,0x81,0x8f,0x28,0x92,
1914 0xaf,0x83,0x44,0x43,0x21,0x00,0x02,
1915 0x01}},
1916 {{0xce,0x72,0x91,0x81,0x8f,0x28,0x92,
1917 0xc8,0x8c,0x5d,0x5c,0x01,0x00,0x02,
1918 0x01}},
1919 {{0xce,0x72,0x91,0x81,0x8f,0x28,0x92,
1920 0xaf,0x83,0x44,0x43,0x21,0x00,0x02,
1921 0x01}},
1922 {{0xce,0x72,0x91,0x81,0x8f,0x28,0x92,
1923 0xf0,0x84,0x85,0x84,0x11,0x00,0x02,
1924 0x01}},
1925 {{0xce,0x63,0x92,0x8b,0x19,0x28,0xd4,
1926 0x3f,0x83,0x57,0x29,0x01,0x00,0x03,
1927 0x01}},
1928 {{0xce,0x7f,0x92,0x99,0x07,0x28,0xd4,
1929 0x93,0x87,0xff,0x29,0x21,0x00,0x07,
1930 0x01}},
1931 {{0xce,0x9f,0x92,0xa8,0x14,0x28,0x5a,
1932 0x00,0x84,0xff,0x29,0x09,0x00,0x07,
1933 0x01}}
1934};
1935
1936static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11280x1024_2_H[] =
1937{
1938 {{0xa6,0x4a,0x89,0x59,0x07,0x28,0x92,
1939 0xc8,0x8c,0x5d,0x5c,0x01,0x00,0x06,
1940 0x01}},
1941 {{0xa6,0x4a,0x89,0x59,0x07,0x28,0x92,
1942 0xaf,0x83,0x44,0x43,0x21,0x00,0x06,
1943 0x01}},
1944 {{0xa6,0x4a,0x89,0x59,0x07,0x28,0x92,
1945 0xc8,0x8c,0x5d,0x5c,0x01,0x00,0x06,
1946 0x01}},
1947 {{0xa6,0x4a,0x89,0x59,0x07,0x28,0x92,
1948 0xfa,0x83,0x44,0x43,0x31,0x00,0x06,
1949 0x01}},
1950 {{0xa6,0x4a,0x89,0x59,0x07,0x28,0x92,
1951 0xf0,0x84,0x85,0x84,0x11,0x00,0x06,
1952 0x01}},
1953 {{0x9c,0x31,0x80,0x59,0x87,0x28,0xd4,
1954 0x3f,0x83,0x57,0x29,0x01,0x00,0x06,
1955 0x01}},
1956 {{0x8e,0x3f,0x92,0x59,0x07,0x28,0xd4,
1957 0x93,0x87,0xff,0x29,0x21,0x00,0x06,
1958 0x01}}
1959};
1960
1961static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11400x1050_1[] =
1962{
1963 {{0x6f,0x4f,0x93,0x54,0x82,0x9e,0x1f,
1964 0x8f,0x81,0x8f,0x9f,0x30,0x00,0x05,
1965 0x00}},
1966 {{0x6f,0x4f,0x93,0x54,0x82,0x6c,0x1f,
1967 0x5e,0x81,0x5d,0x6d,0x10,0x00,0x05,
1968 0x00}},
1969 {{0x6f,0x4f,0x93,0x54,0x82,0x9e,0x1f,
1970 0x90,0x83,0x8f,0x9f,0x30,0x00,0x05,
1971 0x00}},
1972 {{0x6f,0x4f,0x93,0x54,0x82,0x6c,0x1f,
1973 0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
1974 0x00}},
1975 {{0x6f,0x4f,0x93,0x54,0x82,0xee,0x1f,
1976 0xdf,0x82,0xdf,0xef,0x10,0x00,0x05,
1977 0x00}},
1978 {{0x83,0x63,0x87,0x68,0x16,0x66,0xf0,
1979 0x57,0x8e,0x57,0x67,0x20,0x00,0x06,
1980 0x01}},
1981 {{0x9f,0x7f,0x83,0x84,0x92,0x0e,0xf1,
1982 0xff,0x86,0xff,0x0f,0x10,0x00,0x02,
1983 0x01,}},
1984 {{0xbf,0x9f,0x83,0xa4,0x12,0x0e,0xde,
1985 0xff,0x86,0xff,0x0f,0x01,0x00,0x07,
1986 0x01}},
1987 {{0xce,0xae,0x92,0xb3,0x01,0x28,0x10,
1988 0x19,0x80,0x19,0x29,0x0f,0x00,0x03,
1989 0x00}}
1990#if 0
1991 {{0x6f,0x4f,0x93,0x54,0x82,0x9e,0x1f,
1992 0x93,0x86,0x8f,0x9f,0x30,0x00,0x05,
1993 0x00}},
1994 {{0x6f,0x4f,0x93,0x54,0x82,0x6c,0x1f,
1995 0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
1996 0x00}},
1997 {{0x6f,0x4f,0x93,0x54,0x82,0x9e,0x1f,
1998 0x93,0x86,0x8f,0x9f,0x30,0x00,0x05,
1999 0x00}},
2000 {{0x6f,0x4f,0x93,0x54,0x82,0x6c,0x1f,
2001 0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
2002 0x00}},
2003 {{0x6f,0x4f,0x93,0x54,0x82,0xee,0x1f,
2004 0xe2,0x86,0xdf,0xef,0x10,0x00,0x05,
2005 0x00}},
2006 {{0x83,0x63,0x87,0x68,0x16,0x66,0xf0,
2007 0x5a,0x8e,0x57,0x67,0x20,0x00,0x06,
2008 0x01}},
2009 {{0x9f,0x7f,0x83,0x84,0x92,0x0e,0xf5,
2010 0x02,0x86,0xff,0x0f,0x10,0x00,0x02,
2011 0x01}},
2012 {{0xbf,0x9f,0x83,0xa4,0x12,0x0e,0x5a,
2013 0x02,0x86,0xff,0x0f,0x09,0x00,0x07,
2014 0x01}},
2015 {{0xce,0xae,0x92,0xb3,0x01,0x28,0x10,
2016 0x1a,0x80,0x19,0x29,0x0f,0x00,0x03,
2017 0x00}}
2018#endif
2019};
2020
2021static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11400x1050_1_H[] =
2022{
2023 {{0x47,0x27,0x8b,0x2c,0x1a,0x9e,0x1f,
2024 0x8f,0x81,0x8f,0x9f,0x30,0x00,0x05,
2025 0x00}},
2026 {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
2027 0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
2028 0x00}},
2029 {{0x47,0x27,0x8b,0x30,0x1e,0x9e,0x1f,
2030 0x90,0x83,0x8f,0x9f,0x30,0x00,0x05,
2031 0x00}},
2032 {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
2033 0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
2034 0x00}},
2035 {{0x47,0x27,0x8b,0x2c,0x1a,0xee,0x1f,
2036 0xdf,0x86,0xdf,0xef,0x10,0x00,0x05,
2037 0x00}},
2038 {{0x51,0x31,0x95,0x36,0x04,0x66,0xf0,
2039 0x57,0x8e,0x57,0x67,0x20,0x00,0x01,
2040 0x01}},
2041 {{0x5f,0x3f,0x83,0x44,0x92,0x0e,0xf1,
2042 0xff,0x86,0xff,0x0f,0x10,0x00,0x01,
2043 0x01}},
2044 {{0x6f,0x4f,0x93,0x54,0x82,0x0e,0x5a,
2045 0x02,0x86,0xff,0x0f,0x09,0x00,0x05,
2046 0x01}},
2047 {{0x76,0x56,0x9a,0x5b,0x89,0x28,0x10,
2048 0x1c,0x80,0x19,0x29,0x0b,0x00,0x05,
2049 0x00}}
2050#if 0
2051 {{0x47,0x27,0x8b,0x2c,0x1a,0x9e,0x1f,
2052 0x93,0x86,0x8f,0x9f,0x30,0x00,0x05,
2053 0x00}},
2054 {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
2055 0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
2056 0x00}},
2057 {{0x47,0x27,0x8b,0x30,0x1e,0x9e,0x1f,
2058 0x92,0x86,0x8f,0x9f,0x30,0x00,0x05,
2059 0x00}},
2060 {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
2061 0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
2062 0x00}},
2063 {{0x47,0x27,0x8b,0x2c,0x1a,0xee,0x1f,
2064 0xe2,0x86,0xdf,0xef,0x10,0x00,0x05,
2065 0x00}},
2066 {{0x51,0x31,0x95,0x36,0x04,0x66,0xf0,
2067 0x5a,0x8e,0x57,0x67,0x20,0x00,0x01,
2068 0x01}},
2069 {{0x5f,0x3f,0x83,0x44,0x92,0x0e,0xf5,
2070 0x02,0x86,0xff,0x0f,0x10,0x00,0x01,
2071 0x01}},
2072 {{0x6f,0x4f,0x93,0x54,0x82,0x0e,0x5a,
2073 0x02,0x86,0xff,0x0f,0x09,0x00,0x05,
2074 0x01}},
2075 {{0x76,0x56,0x9a,0x5b,0x89,0x28,0x10,
2076 0x1c,0x80,0x19,0x29,0x0b,0x00,0x05,
2077 0x00}}
2078#endif
2079};
2080
2081static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11400x1050_2[] =
2082{
2083 {{0xce,0x72,0x91,0x84,0x92,0x28,0x92,
2084 0xd7,0x8b,0x5d,0x5c,0x21,0x00,0x02,
2085 0x01}},
2086 {{0xce,0x72,0x91,0x84,0x92,0x28,0x92,
2087 0xbe,0x82,0x44,0x43,0x01,0x00,0x02,
2088 0x01}},
2089 {{0xce,0x72,0x91,0x84,0x92,0x28,0x92,
2090 0xd7,0x8b,0x5d,0x5c,0x21,0x00,0x02,
2091 0x01}},
2092 {{0xce,0x72,0x91,0x84,0x92,0x28,0x92,
2093 0xbe,0x82,0x44,0x43,0x01,0x00,0x02,
2094 0x01}},
2095 {{0xce,0x72,0x91,0x84,0x92,0x28,0x92,
2096 0xff,0x83,0x85,0x84,0x11,0x00,0x02,
2097 0x01}},
2098 {{0xce,0x63,0x92,0x8e,0x1c,0x28,0xd4,
2099 0x3f,0x83,0x57,0x29,0x01,0x00,0x03,
2100 0x01}},
2101 {{0xce,0x7f,0x92,0x9c,0x0a,0x28,0xd4,
2102 0x93,0x87,0xff,0x29,0x21,0x00,0x07,
2103 0x01}},
2104 {{0xce,0x9f,0x92,0xac,0x1a,0x28,0x5a,
2105 0x13,0x87,0xff,0x29,0x29,0x00,0x07,
2106 0x01}},
2107 {{0xce,0xae,0x92,0xbc,0x0a,0x28,0x10,
2108 0x20,0x84,0x19,0x29,0x0f,0x00,0x03,
2109 0x00}}
2110#if 0
2111 {{0xce,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
2112 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x03,
2113 0x00}},
2114 {{0xce,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
2115 0xc2,0x86,0x5d,0x29,0x01,0x00,0x03,
2116 0x01}},
2117 {{0xce,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
2118 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x03,
2119 0x00}},
2120 {{0xce,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
2121 0xc2,0x86,0x5d,0x29,0x01,0x00,0x03,
2122 0x00}},
2123 {{0xce,0x4f,0x92,0x8c,0x1a,0x28,0x9e,
2124 0x03,0x87,0xdf,0x29,0x01,0x00,0x03,
2125 0x00}},
2126 {{0xce,0x63,0x92,0x96,0x04,0x28,0xd4,
2127 0x3f,0x83,0x57,0x29,0x01,0x00,0x07,
2128 0x01}},
2129 {{0xce,0x7f,0x92,0xa4,0x12,0x28,0xd4,
2130 0x93,0x87,0xff,0x29,0x21,0x00,0x07,
2131 0x01}},
2132 {{0xce,0x9f,0x92,0xb4,0x02,0x28,0x5a,
2133 0x13,0x87,0xff,0x29,0x29,0x00,0x03,
2134 0x01}},
2135 {{0xce,0xae,0x92,0xbc,0x0a,0x28,0x10,
2136 0x20,0x84,0x19,0x29,0x0f,0x00,0x03,
2137 0x00}}
2138#endif
2139};
2140
2141static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11400x1050_2_H[] =
2142{
2143 {{0xa6,0x4a,0x89,0x5c,0x0a,0x28,0x92,
2144 0xd7,0x8b,0x5d,0x5c,0x21,0x00,0x06,
2145 0x01}},
2146 {{0xa6,0x4a,0x89,0x5c,0x0a,0x28,0x92,
2147 0xbe,0x82,0x44,0x43,0x01,0x00,0x06,
2148 0x01}},
2149 {{0xa6,0x4a,0x89,0x5c,0x0a,0x28,0x92,
2150 0xd7,0x8b,0x5d,0x5c,0x21,0x00,0x06,
2151 0x01}},
2152 {{0xa6,0x4a,0x89,0x5c,0x0a,0x28,0x92,
2153 0xbe,0x82,0x44,0x43,0x01,0x00,0x06,
2154 0x01}},
2155 {{0xa6,0x4a,0x89,0x5c,0x0a,0x28,0x92,
2156 0xff,0x83,0x85,0x84,0x11,0x00,0x06,
2157 0x01}},
2158 {{0x9c,0x31,0x80,0x5c,0x8a,0x28,0xd4,
2159 0x3f,0x83,0x57,0x29,0x01,0x00,0x06,
2160 0x01}},
2161 {{0x8e,0x3f,0x92,0x5c,0x0a,0x28,0xd4,
2162 0x93,0x87,0xff,0x29,0x21,0x00,0x06,
2163 0x01}},
2164 {{0x7e,0x4f,0x82,0x5c,0x0a,0x28,0x5a,
2165 0x13,0x87,0xff,0x29,0x29,0x00,0x06,
2166 0x01}},
2167 {{0x76,0x56,0x9a,0x64,0x92,0x28,0x10,
2168 0x20,0x84,0x19,0x29,0x0f,0x00,0x05,
2169 0x00}}
2170#if 0
2171 {{0xa6,0x27,0x8a,0x64,0x92,0x28,0x9a,
2172 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x06,
2173 0x00}},
2174 {{0xa6,0x27,0x8a,0x64,0x92,0x28,0x9a,
2175 0xc2,0x86,0x5d,0x29,0x01,0x00,0x06,
2176 0x00}},
2177 {{0xa6,0x27,0x8a,0x64,0x92,0x28,0x9a,
2178 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x06,
2179 0x00}},
2180 {{0xa6,0x27,0x8a,0x64,0x92,0x28,0x9a,
2181 0xc2,0x86,0x5d,0x29,0x01,0x00,0x06,
2182 0x00}},
2183 {{0xa6,0x27,0x8a,0x64,0x92,0x28,0x9e,
2184 0x03,0x87,0xdf,0x29,0x01,0x00,0x06,
2185 0x00}},
2186 {{0x9c,0x31,0x80,0x64,0x92,0x28,0xd4,
2187 0x3f,0x83,0x57,0x29,0x01,0x00,0x06,
2188 0x01}},
2189 {{0x8e,0x3f,0x92,0x64,0x12,0x28,0xd4,
2190 0x93,0x87,0xff,0x29,0x21,0x00,0x06,
2191 0x01}},
2192 {{0x7e,0x4f,0x82,0x64,0x12,0x28,0x5a,
2193 0x13,0x87,0xff,0x29,0x29,0x00,0x06,
2194 0x01}},
2195 {{0x76,0x56,0x9a,0x64,0x92,0x28,0x10,
2196 0x20,0x84,0x19,0x29,0x0f,0x00,0x05,
2197 0x00}}
2198#endif
2199};
2200
2201static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11600x1200_1[] =
2202{
2203 {{0x83,0x4F,0x87,0x5B,0x13,0x06,0x3E,
2204 0xB3,0x86,0x8F,0x07,0x20,0x00,0x06,
2205 0x00}},
2206 {{0x83,0x4F,0x87,0x5B,0x13,0xD4,0x1F,
2207 0x81,0x84,0x5D,0xD5,0x10,0x00,0x06,
2208 0x00}},
2209 {{0x83,0x4F,0x87,0x5B,0x13,0x06,0x3E,
2210 0xB3,0x86,0x8F,0x07,0x20,0x00,0x06,
2211 0x00}},
2212 {{0x83,0x4F,0x87,0x5B,0x13,0xD4,0x1F,
2213 0x81,0x84,0x5D,0xD5,0x10,0x00,0x06,
2214 0x00}},
2215 {{0x83,0x4F,0x87,0x5B,0x13,0x56,0xBA,
2216 0x03,0x86,0xDF,0x57,0x00,0x00,0x06,
2217 0x00}},
2218 {{0x97,0x63,0x9B,0x6F,0x07,0xCE,0xF0,
2219 0x7B,0x8E,0x57,0xCF,0x20,0x00,0x02,
2220 0x01}},
2221 {{0xB3,0x7F,0x97,0x8B,0x83,0x76,0xF5,
2222 0x23,0x86,0xFF,0x77,0x10,0x00,0x06,
2223 0x01}},
2224 {{0xD3,0x9F,0x97,0xAB,0x03,0x76,0x5A,
2225 0x23,0x86,0xFF,0x77,0x09,0x00,0x03,
2226 0x01}},
2227 {{0xE2,0xAE,0x86,0xBA,0x92,0x90,0x10,
2228 0x3D,0x80,0x19,0x91,0x0F,0x00,0x03,
2229 0x00}},
2230 {{0xFB,0xC7,0x9F,0xD3,0x8B,0x26,0x11,
2231 0xD3,0x86,0xAF,0x27,0x3F,0x00,0x07,
2232 0x00}}
2233#if 0
2234 {{0x83,0x4f,0x87,0x51,0x09,0xc0,0x1f,
2235 0x90,0x84,0x8f,0xc1,0x30,0x00,0x06,
2236 0x00}},
2237 {{0x83,0x4f,0x87,0x51,0x09,0x8e,0x1f,
2238 0x5e,0x82,0x5d,0x8f,0x10,0x00,0x06,
2239 0x00}},
2240 {{0x83,0x4f,0x87,0x51,0x09,0xc0,0x1f,
2241 0x90,0x84,0x8f,0xc1,0x30,0x00,0x06,
2242 0x00}},
2243 {{0x83,0x4f,0x87,0x51,0x09,0x8e,0x1f,
2244 0x5e,0x82,0x5d,0x8f,0x10,0x00,0x06,
2245 0x00}},
2246 {{0x83,0x4f,0x87,0x51,0x09,0x10,0x3e,
2247 0xe0,0x84,0xdf,0x11,0x00,0x00,0x06,
2248 0x00}},
2249 {{0x97,0x63,0x9b,0x65,0x1d,0x88,0xf0,
2250 0x58,0x8c,0x57,0x89,0x20,0x00,0x06,
2251 0x01}},
2252 {{0xb3,0x7f,0x97,0x81,0x99,0x30,0xf5,
2253 0x00,0x84,0xff,0x31,0x10,0x00,0x02,
2254 0x01}},
2255 {{0xd3,0x9f,0x97,0xa1,0x19,0x30,0x5a,
2256 0x00,0x84,0xff,0x31,0x09,0x00,0x07,
2257 0x01}},
2258 {{0xe2,0xae,0x86,0xb0,0x88,0x4a,0x10,
2259 0x1a,0x8e,0x19,0x4b,0x2f,0x00,0x03,
2260 0x00}},
2261 {{0xfb,0xc7,0x9f,0xc9,0x81,0xe0,0x10,
2262 0xb0,0x84,0xaf,0xe1,0x2f,0x00,0x07,
2263 0x00}}
2264#endif
2265};
2266
2267static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11600x1200_1_H[] =
2268{
2269 {{0x5B,0x27,0x9F,0x33,0x0B,0x06,0x2E,
2270 0xB3,0x86,0x8F,0x07,0x20,0x00,0x01,
2271 0x00}},
2272 {{0x5B,0x27,0x9F,0x29,0x01,0x8E,0x1F,
2273 0x81,0x84,0x5D,0xD5,0x10,0x00,0x06,
2274 0x00}},
2275 {{0x5B,0x27,0x9F,0x33,0x0B,0x06,0x2E,
2276 0xB3,0x86,0x8F,0x07,0x20,0x00,0x01,
2277 0x00}},
2278 {{0x83,0x4F,0x87,0x5B,0x13,0xD4,0x1F,
2279 0x81,0x84,0x5D,0xD5,0x10,0x00,0x06,
2280 0x00}},
2281 {{0x5B,0x27,0x9F,0x33,0x0B,0x56,0xBA,
2282 0x03,0x86,0xDF,0x57,0x00,0x00,0x01,
2283 0x00}},
2284 {{0x65,0x31,0x89,0x3D,0x95,0xCE,0xF0,
2285 0x7B,0x8E,0x57,0xCF,0x20,0x00,0x01,
2286 0x01}},
2287 {{0x73,0x3F,0x97,0x4B,0x83,0x76,0xF5,
2288 0x23,0x86,0xFF,0x77,0x10,0x00,0x05,
2289 0x01}},
2290 {{0xD3,0x9F,0x97,0xAB,0x03,0x76,0x5A,
2291 0x23,0x86,0xFF,0x77,0x09,0x00,0x03,
2292 0x01}},
2293 {{0xE2,0xAE,0x86,0xBA,0x92,0x90,0x10,
2294 0x3D,0x80,0x19,0x91,0x0F,0x00,0x03,
2295 0x00}},
2296 {{0x97,0x63,0x9B,0x6F,0x07,0xE0,0x10,
2297 0xB0,0x84,0xAF,0xE1,0x2F,0x00,0x06,
2298 0x00}}
2299#if 0
2300 {{0x5b,0x27,0x9f,0x29,0x01,0xc0,0x1f,
2301 0x90,0x84,0x8f,0xc1,0x30,0x00,0x01,
2302 0x00}},
2303 {{0x5b,0x27,0x9f,0x29,0x01,0x8e,0x1f,
2304 0x5e,0x82,0x5d,0x8f,0x10,0x00,0x01,
2305 0x00}},
2306 {{0x5b,0x27,0x9f,0x29,0x01,0xc0,0x1f,
2307 0x90,0x84,0x8f,0xc1,0x30,0x00,0x01,
2308 0x00}},
2309 {{0x5b,0x27,0x9f,0x29,0x01,0x8e,0x1f,
2310 0x5e,0x82,0x5d,0x8f,0x10,0x00,0x01,
2311 0x00}},
2312 {{0x5b,0x27,0x9f,0x29,0x01,0x10,0x3e,
2313 0xe0,0x84,0xdf,0x11,0x00,0x00,0x01,
2314 0x00}},
2315 {{0x65,0x31,0x89,0x33,0x8b,0x88,0xf0,
2316 0x58,0x8c,0x57,0x89,0x20,0x00,0x01,
2317 0x01}},
2318 {{0x73,0x3f,0x97,0x41,0x99,0x30,0xf5,
2319 0x00,0x84,0xff,0x31,0x10,0x00,0x01,
2320 0x01}},
2321 {{0x83,0x4f,0x87,0x51,0x09,0x30,0x5a,
2322 0x00,0x84,0xff,0x31,0x09,0x00,0x06,
2323 0x01}},
2324 {{0x8a,0x56,0x8e,0x58,0x10,0x4a,0x10,
2325 0x1a,0x8e,0x19,0x4b,0x2f,0x00,0x06,
2326 0x00}},
2327 {{0x97,0x63,0x9b,0x65,0x1d,0xe0,0x10,
2328 0xb0,0x84,0xaf,0xe1,0x2f,0x00,0x06,
2329 0x00}}
2330#endif
2331};
2332
2333static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11600x1200_2[] =
2334{
2335 {{0xFB,0x87,0x86,0x97,0x0F,0x26,0x97,
2336 0x43,0x86,0xDB,0xDA,0x11,0x00,0x07,
2337 0x01}},
2338 {{0xFB,0x87,0x86,0x97,0x0F,0x26,0x97,
2339 0x2A,0x8D,0xC2,0xC1,0x11,0x00,0x07,
2340 0x01}},
2341 {{0xFB,0x87,0x86,0x97,0x0F,0x26,0x97,
2342 0x43,0x86,0xDB,0xDA,0x11,0x00,0x07,
2343 0x01}},
2344 {{0xFB,0x87,0x86,0x97,0x0F,0x26,0x97,
2345 0x2A,0x8D,0xC2,0xC1,0x11,0x00,0x07,
2346 0x01}},
2347 {{0xFB,0x87,0x86,0x97,0x0F,0x26,0x9F,
2348 0x6B,0x8E,0x03,0x02,0x01,0x00,0x07,
2349 0x01}},
2350 {{0xFB,0x63,0x9F,0xA1,0x99,0x26,0xD5,
2351 0xA7,0x8A,0xBF,0xBE,0x01,0x00,0x07,
2352 0x01}},
2353 {{0xFB,0x7F,0x9F,0xAF,0x87,0x26,0xDD,
2354 0xFB,0x8E,0x13,0x12,0x31,0x00,0x03,
2355 0x01}},
2356 {{0xFB,0x9F,0x9F,0xBF,0x97,0x26,0x5B,
2357 0x7B,0x8E,0xFF,0x27,0x39,0x00,0x03,
2358 0x01}},
2359 {{0xFB,0xAE,0x9F,0xC6,0x9E,0x26,0x11,
2360 0x88,0x8B,0x19,0x27,0x1F,0x00,0x03,
2361 0x00}},
2362 {{0xFB,0xC7,0x9F,0xD3,0x8B,0x26,0x11,
2363 0xD3,0x86,0xAF,0x27,0x3F,0x00,0x07,
2364 0x00}}
2365#if 0
2366 {{0xfb,0x88,0x87,0x90,0x08,0xe0,0x96,
2367 0x20,0x84,0xb9,0xb8,0x01,0x00,0x07,
2368 0x01}},
2369 {{0xfb,0x88,0x87,0x90,0x08,0xe0,0x96,
2370 0x07,0x8b,0xa0,0x9f,0x01,0x00,0x07,
2371 0x01}},
2372 {{0xfb,0x88,0x87,0x90,0x08,0xe0,0x96,
2373 0x20,0x84,0xb9,0xb8,0x01,0x00,0x07,
2374 0x01}},
2375 {{0xfb,0x88,0x87,0x90,0x08,0xe0,0x96,
2376 0x07,0x8b,0xa0,0x9f,0x01,0x00,0x07,
2377 0x01}},
2378 {{0xfb,0x88,0x87,0x90,0x08,0xe0,0x96,
2379 0x48,0x8c,0xe1,0xe0,0x11,0x00,0x07,
2380 0x01}},
2381 {{0xfb,0x63,0x9f,0x9a,0x92,0xe0,0xd4,
2382 0x9b,0x8f,0x9d,0x9c,0x21,0x00,0x07,
2383 0x01}},
2384 {{0xfb,0x7f,0x9f,0xa8,0x80,0xe0,0xd4,
2385 0xef,0x83,0xff,0xe1,0x21,0x00,0x03,
2386 0x01}},
2387 {{0xfb,0x9f,0x9f,0xb8,0x90,0xe0,0x5a,
2388 0x6f,0x83,0xff,0xe1,0x29,0x00,0x03,
2389 0x01}},
2390 {{0xfb,0xae,0x9f,0xbf,0x97,0xe0,0x10,
2391 0x7c,0x80,0x19,0xe1,0x0f,0x00,0x03,
2392 0x00}},
2393 {{0xfb,0xc7,0x9f,0xc9,0x84,0xe0,0x10,
2394 0xc7,0x8b,0xaf,0xe1,0x0f,0x00,0x07,
2395 0x00}}
2396#endif
2397};
2398
2399static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11600x1200_2_H[] =
2400{
2401 {{0xD3,0x5F,0x9E,0x6F,0x07,0x26,0x97,
2402 0x43,0x86,0xDB,0xDA,0x11,0x00,0x02,
2403 0x01}},
2404 {{0xD3,0x27,0x97,0x6F,0x07,0x26,0x97,
2405 0x6B,0x8E,0x83,0x82,0x01,0x00,0x03,
2406 0x01}},
2407 {{0xD3,0x5F,0x9E,0x6F,0x07,0x26,0x97,
2408 0x43,0x86,0xDB,0xDA,0x11,0x00,0x02,
2409 0x01}},
2410 {{0xD3,0x27,0x97,0x6F,0x07,0x26,0x97,
2411 0x07,0x8B,0xA0,0x9F,0x01,0x00,0x02,
2412 0x01}},
2413 {{0xD3,0x27,0x97,0x6F,0x07,0x26,0x97,
2414 0x6B,0x8E,0x83,0x82,0x01,0x00,0x03,
2415 0x01}},
2416 {{0xC9,0x31,0x8D,0x6F,0x07,0x26,0xD5,
2417 0xA7,0x8A,0xBF,0xBE,0x01,0x00,0x03,
2418 0x01}},
2419 {{0xBB,0x3F,0x9F,0x6F,0x87,0x26,0xDD,
2420 0xFB,0x8E,0x13,0x12,0x31,0x00,0x02,
2421 0x01}},
2422 {{0xAB,0x4F,0x8F,0x68,0x80,0xE0,0x5A,
2423 0x6F,0x83,0xFF,0xE1,0x29,0x00,0x02,
2424 0x01}},
2425 {{0xA3,0x56,0x87,0x67,0x9F,0xE0,0x10,
2426 0x7C,0x80,0x19,0xE1,0x0F,0x00,0x06,
2427 0x00}},
2428 {{0x97,0x63,0x9B,0x68,0x00,0xE0,0x10,
2429 0xC7,0x8B,0xAF,0xE1,0x0F,0x00,0x02,
2430 0x00}}
2431#if 0
2432 {{0xd3,0x60,0x9f,0x68,0x00,0xe0,0x96,
2433 0x20,0x84,0xb9,0xb8,0x01,0x00,0x02,
2434 0x01}},
2435 {{0xd3,0x60,0x9f,0x68,0x00,0xe0,0x96,
2436 0x07,0x8b,0xa0,0x9f,0x01,0x00,0x02,
2437 0x01}},
2438 {{0xd3,0x60,0x9f,0x68,0x00,0xe0,0x96,
2439 0x20,0x84,0xb9,0xb8,0x01,0x00,0x02,
2440 0x01}},
2441 {{0xd3,0x60,0x9f,0x68,0x00,0xe0,0x96,
2442 0x07,0x8b,0xa0,0x9f,0x01,0x00,0x02,
2443 0x01}},
2444 {{0xd3,0x60,0x9f,0x68,0x00,0xe0,0x96,
2445 0x48,0x8c,0xe1,0xe0,0x11,0x00,0x02,
2446 0x01}},
2447 {{0xc9,0x31,0x8d,0x68,0x00,0xe0,0xd4,
2448 0x9b,0x8f,0x9d,0x9c,0x21,0x00,0x03,
2449 0x01}},
2450 {{0xbb,0x3f,0x9f,0x68,0x80,0xe0,0xd4,
2451 0xef,0x83,0xff,0xe1,0x21,0x00,0x02,
2452 0x01}},
2453 {{0xab,0x4f,0x8f,0x68,0x80,0xe0,0x5a,
2454 0x6f,0x83,0xff,0xe1,0x29,0x00,0x02,
2455 0x01}},
2456 {{0xa3,0x56,0x87,0x67,0x9f,0xe0,0x10,
2457 0x7c,0x80,0x19,0xe1,0x0f,0x00,0x06,
2458 0x00}},
2459 {{0x97,0x63,0x9b,0x68,0x00,0xe0,0x10,
2460 0xc7,0x8b,0xaf,0xe1,0x0f,0x00,0x02,
2461 0x00}}
2462#endif
2463};
2464
2465static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT1XXXxXXX_1[] =
2466{
2467 {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
2468 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
2469 0x00}},
2470 {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
2471 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
2472 0x00}},
2473 {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
2474 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
2475 0x00}},
2476 {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
2477 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
2478 0x00}},
2479 {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
2480 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x05,
2481 0x00}},
2482 {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
2483 0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
2484 0x01}},
2485 {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
2486 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
2487 0x01}},
2488 {{0xce,0x9f,0x92,0xa8,0x14,0x28,0x5a,
2489 0x00,0x84,0xff,0x29,0x09,0x00,0x07,
2490 0x01}},
2491 {{0xce,0x9f,0x92,0xa9,0x17,0x24,0xf5,
2492 0x02,0x88,0xff,0x25,0x10,0x00,0x07,
2493 0x01}}
2494};
2495
2496static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT1XXXxXXX_1_H[] =
2497{
2498 {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
2499 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
2500 0x00}},
2501 {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
2502 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
2503 0x00}},
2504 {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
2505 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
2506 0x00}},
2507 {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
2508 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
2509 0x00}},
2510 {{0x38,0x27,0x9c,0x2c,0x80,0x0b,0x3e,
2511 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
2512 0x00}},
2513 {{0x4d,0x31,0x91,0x3b,0x03,0x72,0xf0,
2514 0x58,0x8c,0x57,0x73,0x20,0x00,0x01,
2515 0x01}},
2516 {{0x63,0x3f,0x87,0x4a,0x92,0x24,0xf5,
2517 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
2518 0x01}}
2519};
2520
2521
2522/* CRT1 CRTC for Chrontel TV slave modes */
2523
2524static const SiS_LVDSCRT1DataStruct SiS310_CHTVCRT1UNTSC[] =
2525{
2526 {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
2527 0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,
2528 0x00 }},
2529 {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
2530 0xd0,0x82,0x5d,0x57,0x00,0x00,0x01,
2531 0x00 }},
2532 {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
2533 0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,
2534 0x00 }},
2535 {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
2536 0xd0,0x82,0x5d,0x57,0x00,0x00,0x01,
2537 0x00 }},
2538 {{0x5d,0x4f,0x81,0x56,0x99,0x56,0xba,
2539 0x0a,0x84,0xdf,0x57,0x00,0x00,0x01,
2540 0x00 }},
2541 {{0x80,0x63,0x84,0x6d,0x0f,0xec,0xf0,
2542 0x7a,0x8f,0x57,0xed,0x20,0x00,0x06,
2543 0x01 }},
2544 {{0x8c,0x7f,0x90,0x86,0x09,0xaf,0xf5,
2545 0x36,0x88,0xff,0xb0,0x10,0x00,0x02,
2546 0x01}}
2547};
2548
2549static const SiS_LVDSCRT1DataStruct SiS310_CHTVCRT1ONTSC[] =
2550{
2551 {{0x63,0x4f,0x87,0x5a,0x9f,0x0b,0x3e,
2552 0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,
2553 0x00 }},
2554 {{0x63,0x4f,0x87,0x5a,0x9f,0x0b,0x3e,
2555 0xb0,0x8d,0x5d,0x0c,0x00,0x00,0x01,
2556 0x00 }},
2557 {{0x63,0x4f,0x87,0x5a,0x9f,0x0b,0x3e,
2558 0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,
2559 0x00 }},
2560 {{0x63,0x4f,0x87,0x5a,0x9f,0x0b,0x3e,
2561 0xb0,0x8d,0x5d,0x0c,0x00,0x00,0x01,
2562 0x00 }},
2563 {{0x5d,0x4f,0x81,0x58,0x9d,0x0b,0x3e,
2564 0xe8,0x84,0xdf,0x0c,0x00,0x00,0x01,
2565 0x00 }},
2566 {{0x7d,0x63,0x81,0x68,0x0e,0xba,0xf0,
2567 0x78,0x8a,0x57,0xbb,0x20,0x00,0x06,
2568 0x01 }},
2569 {{0x8c,0x7f,0x90,0x82,0x06,0x46,0xf5,
2570 0x15,0x88,0xff,0x47,0x70,0x00,0x02,
2571 0x01 }}
2572};
2573
2574static const SiS_LVDSCRT1DataStruct SiS310_CHTVCRT1UPAL[] =
2575{
2576 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
2577 0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,
2578 0x00 }},
2579 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
2580 0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
2581 0x00 }},
2582 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
2583 0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,
2584 0x00 }},
2585 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
2586 0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
2587 0x00 }},
2588 {{0x64,0x4f,0x88,0x5a,0x9f,0x6f,0xba,
2589 0x15,0x83,0xdf,0x70,0x00,0x00,0x01,
2590 0x00 }},
2591 {{0x73,0x63,0x97,0x69,0x8b,0xec,0xf0,
2592 0x90,0x8c,0x57,0xed,0x20,0x00,0x05,
2593 0x01 }},
2594 {{0xaa,0x7f,0x8e,0x8e,0x96,0xe6,0xf5,
2595 0x50,0x88,0xff,0xe7,0x10,0x00,0x02,
2596 0x01}}
2597};
2598
2599static const SiS_LVDSCRT1DataStruct SiS310_CHTVCRT1OPAL[] =
2600{
2601 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
2602 0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
2603 0x00 }},
2604 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
2605 0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
2606 0x00 }},
2607 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
2608 0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
2609 0x00 }},
2610 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
2611 0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
2612 0x00 }},
2613 {{0x64,0x4f,0x88,0x58,0x9d,0x6f,0xba,
2614 0x15,0x83,0xdf,0x70,0x00,0x00,0x01,
2615 0x00 }},
2616 {{0x71,0x63,0x95,0x69,0x8c,0x6f,0xf0,
2617 0x5a,0x8b,0x57,0x70,0x20,0x00,0x05,
2618 0x01 }},
2619 {{0xaa,0x7f,0x8e,0x8f,0x96,0x69,0xf5,
2620 0x28,0x88,0xff,0x6a,0x10,0x00,0x02,
2621 0x01 }}
2622};
2623
2624
2625static const SiS_CHTVRegDataStruct SiS310_CHTVReg_UNTSC[] =
2626{
2627 {{0x4a,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
2628 {{0x4a,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
2629 {{0x4a,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
2630 {{0x4a,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
2631 {{0x6a,0x77,0xbb,0x6e,0x84,0x2e,0x02,0x5a,0x04,0x00,0x80,0x20,0x7e,0x80,0x98,0x00}},
2632 {{0xcf,0x77,0xb7,0xc8,0x84,0x3b,0x02,0x5a,0x04,0x00,0x80,0x19,0x88,0x30,0x7f,0x00}},
2633 {{0xee,0x77,0xbb,0x66,0x87,0x32,0x01,0x5a,0x04,0x00,0x80,0x1b,0xd3,0xf2,0x36,0x00}}
2634}; /* WRONG: 0x02: should be 0xfx, because if CIVEnable is clear, this should be set;
2635 0x07: Blacklevel: NTSC/PAL-M: Should be 131 (0x83), and not 0x50/0x5a
2636 PAL/PAL-N: 110 (0x6e)
2637 NTSC-J: 102 (0x66)
2638 0x0c-0x0f: CIV is not default as in datasheet
2639 MISSING: 0x21: Should set D1 to ZERO (for NTSC, PAL-M) or ONE (PAL, NTSC-J)
2640 Most of this is wrong in all NTSC and PAL register arrays. But I won't correct
2641 it as long as it works. For NTSC-J, the blacklevel is corrected in init301.c;
2642 for PAL-M and PAL-N all above is corrected.
2643 */
2644
2645static const SiS_CHTVRegDataStruct SiS310_CHTVReg_ONTSC[] =
2646{
2647 {{0x49,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
2648 {{0x49,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
2649 {{0x49,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
2650 {{0x49,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
2651 {{0x69,0x77,0xbb,0x6e,0x84,0x1e,0x00,0x5a,0x04,0x00,0x80,0x25,0x1a,0x43,0x04,0x00}},
2652 {{0xce,0x77,0xb7,0xb6,0x83,0x2c,0x02,0x5a,0x04,0x00,0x80,0x1c,0x00,0x82,0x97,0x00}},
2653 {{0xed,0x77,0xbb,0x66,0x8c,0x21,0x02,0x5a,0x04,0x00,0x80,0x1f,0x9f,0xc1,0x0c,0x00}}
2654};
2655
2656static const SiS_CHTVRegDataStruct SiS310_CHTVReg_UPAL[] =
2657{
2658 {{0x41,0x7f,0xb7,0x34,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
2659 {{0x41,0x7f,0xb7,0x80,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
2660 {{0x41,0x7f,0xb7,0x34,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
2661 {{0x41,0x7f,0xb7,0x12,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
2662 {{0x61,0x7f,0xb7,0x99,0x84,0x35,0x04,0x5a,0x05,0x00,0x80,0x26,0x2a,0x55,0x5d,0x00}},
2663 {{0xc3,0x7f,0xb7,0x7a,0x84,0x40,0x02,0x5a,0x05,0x00,0x80,0x1f,0x84,0x3d,0x28,0x00}},
2664 {{0xe5,0x7f,0xb7,0x1d,0xa7,0x3e,0x04,0x5a,0x05,0x00,0x80,0x20,0x3e,0xe4,0x22,0x00}}
2665};
2666
2667static const SiS_CHTVRegDataStruct SiS310_CHTVReg_OPAL[] =
2668{
2669 {{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
2670 {{0x41,0x7f,0xb7,0x86,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
2671 {{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
2672 {{0x41,0x7f,0xb7,0x86,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
2673 {{0x61,0x7f,0xb7,0x99,0x84,0x35,0x04,0x5a,0x05,0x00,0x80,0x26,0x2a,0x55,0x5d,0x00}},
2674 {{0xc1,0x7f,0xb7,0x4d,0x8c,0x1e,0x31,0x5a,0x05,0x00,0x80,0x26,0x78,0x19,0x34,0x00}},
2675 {{0xe4,0x7f,0xb7,0x1e,0xaf,0x29,0x37,0x5a,0x05,0x00,0x80,0x25,0x8c,0xb2,0x2a,0x00}}
2676};
2677
2678static const SiS_CHTVRegDataStruct SiS310_CHTVReg_UPALM[] =
2679{
2680 {{0x52,0x77,0xbb,0x94,0x84,0x48,0xfe,0x83,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
2681 {{0x52,0x77,0xbb,0x94,0x84,0x48,0xfe,0x83,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
2682 {{0x52,0x77,0xbb,0x94,0x84,0x48,0xfe,0x83,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
2683 {{0x52,0x77,0xbb,0x94,0x84,0x48,0xfe,0x83,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
2684 {{0x72,0x77,0xfb,0x6e,0x84,0x2e,0x02,0x83,0x04,0x00,0x80,0x20,0x76,0xdb,0x6e,0x00}},
2685 {{0xd7,0x77,0xf7,0xc8,0x84,0x3b,0x02,0x83,0x04,0x00,0x80,0x19,0x84,0x0a,0xc7,0x00}},
2686 {{0xf6,0x77,0xfb,0x66,0x87,0x32,0x01,0x83,0x04,0x00,0x80,0x1b,0xdc,0xb0,0x8d,0x00}}
2687#if 0 /* Correct blacklevel and CFRB */
2688 {{0x72,0x77,0xbb,0x6e,0x84,0x2e,0x02,0x5a,0x04,0x00,0x80,0x20,0x76,0xdb,0x6e,0x00}},
2689 {{0xd7,0x77,0xb7,0xc8,0x84,0x3b,0x02,0x5a,0x04,0x00,0x80,0x19,0x84,0x0a,0xc7,0x00}},
2690 {{0xf6,0x77,0xbb,0x66,0x87,0x32,0x01,0x5a,0x04,0x00,0x80,0x1b,0xdc,0xb0,0x8d,0x00}}
2691#endif
2692};
2693
2694static const SiS_CHTVRegDataStruct SiS310_CHTVReg_OPALM[] =
2695{
2696 {{0x51,0x77,0xbb,0x7b,0x84,0x34,0x00,0x83,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
2697 {{0x51,0x77,0xbb,0x7b,0x84,0x34,0x00,0x83,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
2698 {{0x51,0x77,0xbb,0x7b,0x84,0x34,0x00,0x83,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
2699 {{0x51,0x77,0xbb,0x7b,0x84,0x34,0x00,0x83,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
2700 {{0x71,0x77,0xfb,0x6e,0x84,0x1e,0x00,0x83,0x04,0x00,0x80,0x25,0x1a,0x1f,0x59,0x00}},
2701 {{0xd6,0x77,0xf7,0xb6,0x83,0x2c,0x02,0x83,0x04,0x00,0x80,0x1b,0xf8,0x1f,0x82,0x00}},
2702 {{0xf5,0x77,0xfb,0x66,0x8c,0x21,0x02,0x83,0x04,0x00,0x80,0x1f,0x58,0x46,0x9f,0x00}}
2703#if 0 /* Correct blacklevel and CFRB */
2704 {{0x71,0x77,0xbb,0x6e,0x84,0x1e,0x00,0x5a,0x04,0x00,0x80,0x25,0x1a,0x1f,0x59,0x00}},
2705 {{0xd6,0x77,0xb7,0xb6,0x83,0x2c,0x02,0x5a,0x04,0x00,0x80,0x1b,0xf8,0x1f,0x82,0x00}},
2706 {{0xf5,0x77,0xbb,0x66,0x8c,0x21,0x02,0x5a,0x04,0x00,0x80,0x1f,0x58,0x46,0x9f,0x00}}
2707#endif
2708};
2709
2710static const SiS_CHTVRegDataStruct SiS310_CHTVReg_UPALN[] =
2711{
2712 {{0x41,0x7f,0xb7,0x34,0xad,0x50,0x34,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
2713 {{0x41,0x7f,0xb7,0x80,0x85,0x50,0x00,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
2714 {{0x41,0x7f,0xb7,0x34,0xad,0x50,0x34,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
2715 {{0x41,0x7f,0xb7,0x12,0x85,0x50,0x00,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
2716 {{0x61,0x7f,0xb7,0x99,0x84,0x35,0x04,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
2717 {{0xc3,0x7f,0xb7,0x7a,0x84,0x40,0x02,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
2718 {{0xe5,0x7f,0xb7,0x1d,0xa7,0x3e,0x04,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}}
2719#if 0 /* Correct blacklevel, CIV and CFRB */
2720 {{0x61,0x7f,0xb7,0x99,0x84,0x35,0x04,0x5a,0x05,0x00,0x80,0x1f,0x0d,0x54,0x5e,0x00}},
2721 {{0xc3,0x7f,0xb7,0x7a,0x84,0x40,0x02,0x5a,0x05,0x00,0x80,0x19,0x78,0xef,0x35,0x00}},
2722 {{0xe5,0x7f,0xb7,0x1d,0xa7,0x3e,0x04,0x5a,0x05,0x00,0x80,0x1a,0x33,0x3f,0x2f,0x00}}
2723#endif
2724};
2725
2726static const SiS_CHTVRegDataStruct SiS310_CHTVReg_OPALN[] =
2727{
2728 {{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
2729 {{0x41,0x7f,0xb7,0x86,0x85,0x50,0x00,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
2730 {{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
2731 {{0x41,0x7f,0xb7,0x86,0x85,0x50,0x00,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
2732 {{0x61,0x7f,0xb7,0x99,0x84,0x35,0x04,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
2733 {{0xc1,0x7f,0xb7,0x4d,0x8c,0x1e,0x31,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
2734 {{0xe4,0x7f,0xb7,0x1e,0xaf,0x29,0x37,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}}
2735#if 0 /* Correct blacklevel, CIV and CFRB */
2736 {{0x61,0x7f,0xb7,0x99,0x84,0x35,0x04,0x5a,0x05,0x00,0x80,0x1f,0x0d,0x54,0x5e,0x00}},
2737 {{0xc1,0x7f,0xb7,0x4d,0x8c,0x1e,0x31,0x5a,0x05,0x00,0x80,0x1f,0x15,0xc0,0x1e,0x00}},
2738 {{0xe4,0x7f,0xb7,0x1e,0xaf,0x29,0x37,0x5a,0x05,0x00,0x80,0x1d,0xf1,0x6c,0xcb,0x00}}
2739#endif
2740};
2741
2742static const UCHAR SiS310_CHTVVCLKUNTSC[] = {0x41,0x41,0x41,0x41,0x42,0x46,0x53};
2743static const UCHAR SiS310_CHTVVCLKONTSC[] = {0x48,0x48,0x48,0x48,0x45,0x43,0x51};
2744
2745static const UCHAR SiS310_CHTVVCLKUPAL[] = {0x47,0x47,0x47,0x47,0x48,0x4a,0x54};
2746static const UCHAR SiS310_CHTVVCLKOPAL[] = {0x47,0x47,0x47,0x47,0x48,0x4f,0x52};
2747
2748static const UCHAR SiS310_CHTVVCLKUPALM[] = {0x41,0x41,0x41,0x41,0x42,0x46,0x53};
2749static const UCHAR SiS310_CHTVVCLKOPALM[] = {0x48,0x48,0x48,0x48,0x45,0x43,0x51};
2750
2751static const UCHAR SiS310_CHTVVCLKUPALN[] = {0x47,0x47,0x47,0x47,0x48,0x4a,0x54};
2752static const UCHAR SiS310_CHTVVCLKOPALN[] = {0x47,0x47,0x47,0x47,0x48,0x4f,0x52};
2753
2754
diff --git a/drivers/video/sis/Makefile b/drivers/video/sis/Makefile
new file mode 100644
index 000000000000..aaed8c2b4a64
--- /dev/null
+++ b/drivers/video/sis/Makefile
@@ -0,0 +1,7 @@
1#
2# Makefile for the SiS framebuffer device driver
3#
4
5obj-$(CONFIG_FB_SIS) += sisfb.o
6
7sisfb-objs := sis_main.o sis_accel.o init.o init301.o
diff --git a/drivers/video/sis/init.c b/drivers/video/sis/init.c
new file mode 100644
index 000000000000..1994054d45ff
--- /dev/null
+++ b/drivers/video/sis/init.c
@@ -0,0 +1,5318 @@
1/* $XFree86$ */
2/* $XdotOrg$ */
3/*
4 * Mode initializing code (CRT1 section) for
5 * for SiS 300/305/540/630/730 and
6 * SiS 315/550/650/M650/651/661FX/M661FX/740/741(GX)/M741/330/660/M660/760/M760
7 * (Universal module for Linux kernel framebuffer and XFree86 4.x)
8 *
9 * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
10 *
11 * If distributed as part of the Linux kernel, the following license terms
12 * apply:
13 *
14 * * This program is free software; you can redistribute it and/or modify
15 * * it under the terms of the GNU General Public License as published by
16 * * the Free Software Foundation; either version 2 of the named License,
17 * * or any later version.
18 * *
19 * * This program is distributed in the hope that it will be useful,
20 * * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * * GNU General Public License for more details.
23 * *
24 * * You should have received a copy of the GNU General Public License
25 * * along with this program; if not, write to the Free Software
26 * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
27 *
28 * Otherwise, the following license terms apply:
29 *
30 * * Redistribution and use in source and binary forms, with or without
31 * * modification, are permitted provided that the following conditions
32 * * are met:
33 * * 1) Redistributions of source code must retain the above copyright
34 * * notice, this list of conditions and the following disclaimer.
35 * * 2) Redistributions in binary form must reproduce the above copyright
36 * * notice, this list of conditions and the following disclaimer in the
37 * * documentation and/or other materials provided with the distribution.
38 * * 3) The name of the author may not be used to endorse or promote products
39 * * derived from this software without specific prior written permission.
40 * *
41 * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
42 * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
43 * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
44 * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
45 * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46 * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
47 * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
48 * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
49 * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
50 * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51 *
52 * Author: Thomas Winischhofer <thomas@winischhofer.net>
53 *
54 * Formerly based on non-functional code-fragements for 300 series by SiS, Inc.
55 * Used by permission.
56 *
57 * TW says: This code looks awful, I know. But please don't do anything about
58 * this otherwise debugging will be hell.
59 * The code is extremely fragile as regards the different chipsets, different
60 * video bridges and combinations thereof. If anything is changed, extreme
61 * care has to be taken that that change doesn't break it for other chipsets,
62 * bridges or combinations thereof.
63 * All comments in this file are by me, regardless if they are marked TW or not.
64 *
65 */
66
67#include "init.h"
68
69#ifdef SIS300
70#include "300vtbl.h"
71#endif
72
73#ifdef SIS315H
74#include "310vtbl.h"
75#endif
76
77#if defined(ALLOC_PRAGMA)
78#pragma alloc_text(PAGE,SiSSetMode)
79#endif
80
81/*********************************************/
82/* POINTER INITIALIZATION */
83/*********************************************/
84
85#if defined(SIS300) || defined(SIS315H)
86static void
87InitCommonPointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
88{
89 SiS_Pr->SiS_StResInfo = SiS_StResInfo;
90 SiS_Pr->SiS_ModeResInfo = SiS_ModeResInfo;
91 SiS_Pr->SiS_StandTable = SiS_StandTable;
92
93 SiS_Pr->SiS_NTSCPhase = SiS_NTSCPhase;
94 SiS_Pr->SiS_PALPhase = SiS_PALPhase;
95 SiS_Pr->SiS_NTSCPhase2 = SiS_NTSCPhase2;
96 SiS_Pr->SiS_PALPhase2 = SiS_PALPhase2;
97 SiS_Pr->SiS_PALMPhase = SiS_PALMPhase;
98 SiS_Pr->SiS_PALNPhase = SiS_PALNPhase;
99 SiS_Pr->SiS_PALMPhase2 = SiS_PALMPhase2;
100 SiS_Pr->SiS_PALNPhase2 = SiS_PALNPhase2;
101 SiS_Pr->SiS_SpecialPhase = SiS_SpecialPhase;
102 SiS_Pr->SiS_SpecialPhaseM = SiS_SpecialPhaseM;
103 SiS_Pr->SiS_SpecialPhaseJ = SiS_SpecialPhaseJ;
104
105 SiS_Pr->SiS_NTSCTiming = SiS_NTSCTiming;
106 SiS_Pr->SiS_PALTiming = SiS_PALTiming;
107 SiS_Pr->SiS_HiTVSt1Timing = SiS_HiTVSt1Timing;
108 SiS_Pr->SiS_HiTVSt2Timing = SiS_HiTVSt2Timing;
109
110 SiS_Pr->SiS_HiTVExtTiming = SiS_HiTVExtTiming;
111 SiS_Pr->SiS_HiTVGroup3Data = SiS_HiTVGroup3Data;
112 SiS_Pr->SiS_HiTVGroup3Simu = SiS_HiTVGroup3Simu;
113#if 0
114 SiS_Pr->SiS_HiTVTextTiming = SiS_HiTVTextTiming;
115 SiS_Pr->SiS_HiTVGroup3Text = SiS_HiTVGroup3Text;
116#endif
117
118 SiS_Pr->SiS_StPALData = SiS_StPALData;
119 SiS_Pr->SiS_ExtPALData = SiS_ExtPALData;
120 SiS_Pr->SiS_StNTSCData = SiS_StNTSCData;
121 SiS_Pr->SiS_ExtNTSCData = SiS_ExtNTSCData;
122 SiS_Pr->SiS_St1HiTVData = SiS_StHiTVData;
123 SiS_Pr->SiS_St2HiTVData = SiS_St2HiTVData;
124 SiS_Pr->SiS_ExtHiTVData = SiS_ExtHiTVData;
125 SiS_Pr->SiS_St525iData = SiS_StNTSCData;
126 SiS_Pr->SiS_St525pData = SiS_St525pData;
127 SiS_Pr->SiS_St750pData = SiS_St750pData;
128 SiS_Pr->SiS_Ext525iData = SiS_ExtNTSCData;
129 SiS_Pr->SiS_Ext525pData = SiS_ExtNTSCData;
130 SiS_Pr->SiS_Ext750pData = SiS_Ext750pData;
131
132 SiS_Pr->pSiS_OutputSelect = &SiS_OutputSelect;
133 SiS_Pr->pSiS_SoftSetting = &SiS_SoftSetting;
134
135 SiS_Pr->SiS_LCD1280x720Data = SiS_LCD1280x720Data;
136 SiS_Pr->SiS_StLCD1280x768_2Data = SiS_StLCD1280x768_2Data;
137 SiS_Pr->SiS_ExtLCD1280x768_2Data = SiS_ExtLCD1280x768_2Data;
138 SiS_Pr->SiS_LCD1280x800Data = SiS_LCD1280x800Data;
139 SiS_Pr->SiS_LCD1280x800_2Data = SiS_LCD1280x800_2Data;
140 SiS_Pr->SiS_LCD1280x960Data = SiS_LCD1280x960Data;
141 SiS_Pr->SiS_StLCD1400x1050Data = SiS_StLCD1400x1050Data;
142 SiS_Pr->SiS_ExtLCD1400x1050Data = SiS_ExtLCD1400x1050Data;
143 SiS_Pr->SiS_LCD1680x1050Data = SiS_LCD1680x1050Data;
144 SiS_Pr->SiS_StLCD1600x1200Data = SiS_StLCD1600x1200Data;
145 SiS_Pr->SiS_ExtLCD1600x1200Data = SiS_ExtLCD1600x1200Data;
146 SiS_Pr->SiS_NoScaleData = SiS_NoScaleData;
147
148 SiS_Pr->SiS_LVDS320x480Data_1 = SiS_LVDS320x480Data_1;
149 SiS_Pr->SiS_LVDS800x600Data_1 = SiS_LVDS800x600Data_1;
150 SiS_Pr->SiS_LVDS800x600Data_2 = SiS_LVDS800x600Data_2;
151 SiS_Pr->SiS_LVDS1024x768Data_1 = SiS_LVDS1024x768Data_1;
152 SiS_Pr->SiS_LVDS1024x768Data_2 = SiS_LVDS1024x768Data_2;
153 SiS_Pr->SiS_LVDS1280x1024Data_1 = SiS_LVDS1280x1024Data_1;
154 SiS_Pr->SiS_LVDS1280x1024Data_2 = SiS_LVDS1280x1024Data_2;
155 SiS_Pr->SiS_LVDS1400x1050Data_1 = SiS_LVDS1400x1050Data_1;
156 SiS_Pr->SiS_LVDS1400x1050Data_2 = SiS_LVDS1400x1050Data_2;
157 SiS_Pr->SiS_LVDS1600x1200Data_1 = SiS_LVDS1600x1200Data_1;
158 SiS_Pr->SiS_LVDS1600x1200Data_2 = SiS_LVDS1600x1200Data_2;
159 SiS_Pr->SiS_LVDS1280x768Data_1 = SiS_LVDS1280x768Data_1;
160 SiS_Pr->SiS_LVDS1280x768Data_2 = SiS_LVDS1280x768Data_2;
161 SiS_Pr->SiS_LVDS1024x600Data_1 = SiS_LVDS1024x600Data_1;
162 SiS_Pr->SiS_LVDS1024x600Data_2 = SiS_LVDS1024x600Data_2;
163 SiS_Pr->SiS_LVDS1152x768Data_1 = SiS_LVDS1152x768Data_1;
164 SiS_Pr->SiS_LVDS1152x768Data_2 = SiS_LVDS1152x768Data_2;
165 SiS_Pr->SiS_LVDSXXXxXXXData_1 = SiS_LVDSXXXxXXXData_1;
166 SiS_Pr->SiS_LVDS1280x960Data_1 = SiS_LVDS1280x960Data_1;
167 SiS_Pr->SiS_LVDS1280x960Data_2 = SiS_LVDS1280x960Data_2;
168 SiS_Pr->SiS_LVDS640x480Data_1 = SiS_LVDS640x480Data_1;
169 SiS_Pr->SiS_LVDS1280x960Data_1 = SiS_LVDS1280x1024Data_1;
170 SiS_Pr->SiS_LVDS1280x960Data_2 = SiS_LVDS1280x1024Data_2;
171 SiS_Pr->SiS_LVDS640x480Data_1 = SiS_LVDS640x480Data_1;
172 SiS_Pr->SiS_LVDS640x480Data_2 = SiS_LVDS640x480Data_2;
173
174 SiS_Pr->SiS_LVDS848x480Data_1 = SiS_LVDS848x480Data_1;
175 SiS_Pr->SiS_LVDS848x480Data_2 = SiS_LVDS848x480Data_2;
176 SiS_Pr->SiS_LVDSBARCO1024Data_1 = SiS_LVDSBARCO1024Data_1;
177 SiS_Pr->SiS_LVDSBARCO1024Data_2 = SiS_LVDSBARCO1024Data_2;
178 SiS_Pr->SiS_LVDSBARCO1366Data_1 = SiS_LVDSBARCO1366Data_1;
179 SiS_Pr->SiS_LVDSBARCO1366Data_2 = SiS_LVDSBARCO1366Data_2;
180
181 SiS_Pr->SiS_LVDSCRT11280x768_1 = SiS_LVDSCRT11280x768_1;
182 SiS_Pr->SiS_LVDSCRT11024x600_1 = SiS_LVDSCRT11024x600_1;
183 SiS_Pr->SiS_LVDSCRT11152x768_1 = SiS_LVDSCRT11152x768_1;
184 SiS_Pr->SiS_LVDSCRT11280x768_1_H = SiS_LVDSCRT11280x768_1_H;
185 SiS_Pr->SiS_LVDSCRT11024x600_1_H = SiS_LVDSCRT11024x600_1_H;
186 SiS_Pr->SiS_LVDSCRT11152x768_1_H = SiS_LVDSCRT11152x768_1_H;
187 SiS_Pr->SiS_LVDSCRT11280x768_2 = SiS_LVDSCRT11280x768_2;
188 SiS_Pr->SiS_LVDSCRT11024x600_2 = SiS_LVDSCRT11024x600_2;
189 SiS_Pr->SiS_LVDSCRT11152x768_2 = SiS_LVDSCRT11152x768_2;
190 SiS_Pr->SiS_LVDSCRT11280x768_2_H = SiS_LVDSCRT11280x768_2_H;
191 SiS_Pr->SiS_LVDSCRT11024x600_2_H = SiS_LVDSCRT11024x600_2_H;
192 SiS_Pr->SiS_LVDSCRT11152x768_2_H = SiS_LVDSCRT11152x768_2_H;
193 SiS_Pr->SiS_LVDSCRT1320x480_1 = SiS_LVDSCRT1320x480_1;
194 SiS_Pr->SiS_LVDSCRT1640x480_1 = SiS_LVDSCRT1640x480_1;
195 SiS_Pr->SiS_LVDSCRT1640x480_1_H = SiS_LVDSCRT1640x480_1_H;
196 SiS_Pr->SiS_LVDSCRT1640x480_2 = SiS_LVDSCRT1640x480_2;
197 SiS_Pr->SiS_LVDSCRT1640x480_2_H = SiS_LVDSCRT1640x480_2_H;
198 SiS_Pr->SiS_LVDSCRT1640x480_3 = SiS_LVDSCRT1640x480_3;
199 SiS_Pr->SiS_LVDSCRT1640x480_3_H = SiS_LVDSCRT1640x480_3_H;
200
201 SiS_Pr->SiS_CHTVUNTSCData = SiS_CHTVUNTSCData;
202 SiS_Pr->SiS_CHTVONTSCData = SiS_CHTVONTSCData;
203
204 SiS_Pr->SiS_CHTVUNTSCDesData = SiS_CHTVUNTSCDesData;
205 SiS_Pr->SiS_CHTVONTSCDesData = SiS_CHTVONTSCDesData;
206 SiS_Pr->SiS_CHTVUPALDesData = SiS_CHTVUPALDesData;
207 SiS_Pr->SiS_CHTVOPALDesData = SiS_CHTVOPALDesData;
208
209 SiS_Pr->SiS_PanelMinLVDS = Panel_800x600; /* lowest value LVDS/LCDA */
210 SiS_Pr->SiS_PanelMin301 = Panel_1024x768; /* lowest value 301 */
211}
212#endif
213
214#ifdef SIS300
215static void
216InitTo300Pointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
217{
218 InitCommonPointer(SiS_Pr, HwInfo);
219
220 SiS_Pr->SiS_SModeIDTable = SiS300_SModeIDTable;
221 SiS_Pr->SiS_VBModeIDTable = SiS300_VBModeIDTable;
222 SiS_Pr->SiS_EModeIDTable = SiS300_EModeIDTable;
223 SiS_Pr->SiS_RefIndex = SiS300_RefIndex;
224 SiS_Pr->SiS_CRT1Table = SiS300_CRT1Table;
225 if(HwInfo->jChipType == SIS_300) {
226 SiS_Pr->SiS_MCLKData_0 = SiS300_MCLKData_300; /* 300 */
227 } else {
228 SiS_Pr->SiS_MCLKData_0 = SiS300_MCLKData_630; /* 630, 730 */
229 }
230 SiS_Pr->SiS_VCLKData = SiS300_VCLKData;
231 SiS_Pr->SiS_VBVCLKData = (SiS_VBVCLKDataStruct *)SiS300_VCLKData;
232
233 SiS_Pr->SiS_SR15 = SiS300_SR15;
234
235#ifdef LINUX_KERNEL
236 SiS_Pr->pSiS_SR07 = &SiS300_SR07;
237 SiS_Pr->SiS_CR40 = SiS300_CR40;
238 SiS_Pr->SiS_CR49 = SiS300_CR49;
239 SiS_Pr->pSiS_SR1F = &SiS300_SR1F;
240 SiS_Pr->pSiS_SR21 = &SiS300_SR21;
241 SiS_Pr->pSiS_SR22 = &SiS300_SR22;
242 SiS_Pr->pSiS_SR23 = &SiS300_SR23;
243 SiS_Pr->pSiS_SR24 = &SiS300_SR24;
244 SiS_Pr->SiS_SR25 = SiS300_SR25;
245 SiS_Pr->pSiS_SR31 = &SiS300_SR31;
246 SiS_Pr->pSiS_SR32 = &SiS300_SR32;
247 SiS_Pr->pSiS_SR33 = &SiS300_SR33;
248 SiS_Pr->pSiS_CRT2Data_1_2 = &SiS300_CRT2Data_1_2;
249 SiS_Pr->pSiS_CRT2Data_4_D = &SiS300_CRT2Data_4_D;
250 SiS_Pr->pSiS_CRT2Data_4_E = &SiS300_CRT2Data_4_E;
251 SiS_Pr->pSiS_CRT2Data_4_10 = &SiS300_CRT2Data_4_10;
252 SiS_Pr->pSiS_RGBSenseData = &SiS300_RGBSenseData;
253 SiS_Pr->pSiS_VideoSenseData = &SiS300_VideoSenseData;
254 SiS_Pr->pSiS_YCSenseData = &SiS300_YCSenseData;
255 SiS_Pr->pSiS_RGBSenseData2 = &SiS300_RGBSenseData2;
256 SiS_Pr->pSiS_VideoSenseData2 = &SiS300_VideoSenseData2;
257 SiS_Pr->pSiS_YCSenseData2 = &SiS300_YCSenseData2;
258#endif
259
260 SiS_Pr->SiS_PanelDelayTbl = SiS300_PanelDelayTbl;
261 SiS_Pr->SiS_PanelDelayTblLVDS = SiS300_PanelDelayTbl;
262
263 SiS_Pr->SiS_ExtLCD1024x768Data = SiS300_ExtLCD1024x768Data;
264 SiS_Pr->SiS_St2LCD1024x768Data = SiS300_St2LCD1024x768Data;
265 SiS_Pr->SiS_ExtLCD1280x1024Data = SiS300_ExtLCD1280x1024Data;
266 SiS_Pr->SiS_St2LCD1280x1024Data = SiS300_St2LCD1280x1024Data;
267
268 SiS_Pr->SiS_CRT2Part2_1024x768_1 = SiS300_CRT2Part2_1024x768_1;
269 SiS_Pr->SiS_CRT2Part2_1280x1024_1 = SiS300_CRT2Part2_1280x1024_1;
270 SiS_Pr->SiS_CRT2Part2_1024x768_2 = SiS300_CRT2Part2_1024x768_2;
271 SiS_Pr->SiS_CRT2Part2_1280x1024_2 = SiS300_CRT2Part2_1280x1024_2;
272 SiS_Pr->SiS_CRT2Part2_1024x768_3 = SiS300_CRT2Part2_1024x768_3;
273 SiS_Pr->SiS_CRT2Part2_1280x1024_3 = SiS300_CRT2Part2_1280x1024_3;
274
275 SiS_Pr->SiS_CHTVUPALData = SiS300_CHTVUPALData;
276 SiS_Pr->SiS_CHTVOPALData = SiS300_CHTVOPALData;
277 SiS_Pr->SiS_CHTVUPALMData = SiS_CHTVUNTSCData; /* not supported on 300 series */
278 SiS_Pr->SiS_CHTVOPALMData = SiS_CHTVONTSCData; /* not supported on 300 series */
279 SiS_Pr->SiS_CHTVUPALNData = SiS300_CHTVUPALData; /* not supported on 300 series */
280 SiS_Pr->SiS_CHTVOPALNData = SiS300_CHTVOPALData; /* not supported on 300 series */
281 SiS_Pr->SiS_CHTVSOPALData = SiS300_CHTVSOPALData;
282
283 SiS_Pr->SiS_PanelType00_1 = SiS300_PanelType00_1;
284 SiS_Pr->SiS_PanelType01_1 = SiS300_PanelType01_1;
285 SiS_Pr->SiS_PanelType02_1 = SiS300_PanelType02_1;
286 SiS_Pr->SiS_PanelType03_1 = SiS300_PanelType03_1;
287 SiS_Pr->SiS_PanelType04_1 = SiS300_PanelType04_1;
288 SiS_Pr->SiS_PanelType05_1 = SiS300_PanelType05_1;
289 SiS_Pr->SiS_PanelType06_1 = SiS300_PanelType06_1;
290 SiS_Pr->SiS_PanelType07_1 = SiS300_PanelType07_1;
291 SiS_Pr->SiS_PanelType08_1 = SiS300_PanelType08_1;
292 SiS_Pr->SiS_PanelType09_1 = SiS300_PanelType09_1;
293 SiS_Pr->SiS_PanelType0a_1 = SiS300_PanelType0a_1;
294 SiS_Pr->SiS_PanelType0b_1 = SiS300_PanelType0b_1;
295 SiS_Pr->SiS_PanelType0c_1 = SiS300_PanelType0c_1;
296 SiS_Pr->SiS_PanelType0d_1 = SiS300_PanelType0d_1;
297 SiS_Pr->SiS_PanelType0e_1 = SiS300_PanelType0e_1;
298 SiS_Pr->SiS_PanelType0f_1 = SiS300_PanelType0f_1;
299 SiS_Pr->SiS_PanelType00_2 = SiS300_PanelType00_2;
300 SiS_Pr->SiS_PanelType01_2 = SiS300_PanelType01_2;
301 SiS_Pr->SiS_PanelType02_2 = SiS300_PanelType02_2;
302 SiS_Pr->SiS_PanelType03_2 = SiS300_PanelType03_2;
303 SiS_Pr->SiS_PanelType04_2 = SiS300_PanelType04_2;
304 SiS_Pr->SiS_PanelType05_2 = SiS300_PanelType05_2;
305 SiS_Pr->SiS_PanelType06_2 = SiS300_PanelType06_2;
306 SiS_Pr->SiS_PanelType07_2 = SiS300_PanelType07_2;
307 SiS_Pr->SiS_PanelType08_2 = SiS300_PanelType08_2;
308 SiS_Pr->SiS_PanelType09_2 = SiS300_PanelType09_2;
309 SiS_Pr->SiS_PanelType0a_2 = SiS300_PanelType0a_2;
310 SiS_Pr->SiS_PanelType0b_2 = SiS300_PanelType0b_2;
311 SiS_Pr->SiS_PanelType0c_2 = SiS300_PanelType0c_2;
312 SiS_Pr->SiS_PanelType0d_2 = SiS300_PanelType0d_2;
313 SiS_Pr->SiS_PanelType0e_2 = SiS300_PanelType0e_2;
314 SiS_Pr->SiS_PanelType0f_2 = SiS300_PanelType0f_2;
315 SiS_Pr->SiS_PanelTypeNS_1 = SiS300_PanelTypeNS_1;
316 SiS_Pr->SiS_PanelTypeNS_2 = SiS300_PanelTypeNS_2;
317
318 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
319 SiS_Pr->SiS_PanelType04_1 = SiS300_PanelType04_1a;
320 SiS_Pr->SiS_PanelType04_2 = SiS300_PanelType04_2a;
321 }
322 if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
323 SiS_Pr->SiS_PanelType04_1 = SiS300_PanelType04_1b;
324 SiS_Pr->SiS_PanelType04_2 = SiS300_PanelType04_2b;
325 }
326
327 SiS_Pr->SiS_LVDSCRT1800x600_1 = SiS300_LVDSCRT1800x600_1;
328 SiS_Pr->SiS_LVDSCRT1800x600_1_H = SiS300_LVDSCRT1800x600_1_H;
329 SiS_Pr->SiS_LVDSCRT1800x600_2 = SiS300_LVDSCRT1800x600_2;
330 SiS_Pr->SiS_LVDSCRT1800x600_2_H = SiS300_LVDSCRT1800x600_2_H;
331 SiS_Pr->SiS_LVDSCRT11024x768_1 = SiS300_LVDSCRT11024x768_1;
332 SiS_Pr->SiS_LVDSCRT11024x768_1_H = SiS300_LVDSCRT11024x768_1_H;
333 SiS_Pr->SiS_LVDSCRT11024x768_2 = SiS300_LVDSCRT11024x768_2;
334 SiS_Pr->SiS_LVDSCRT11024x768_2_H = SiS300_LVDSCRT11024x768_2_H;
335 SiS_Pr->SiS_LVDSCRT11280x1024_1 = SiS300_LVDSCRT11280x1024_1;
336 SiS_Pr->SiS_LVDSCRT11280x1024_1_H = SiS300_LVDSCRT11280x1024_1_H;
337 SiS_Pr->SiS_LVDSCRT11280x1024_2 = SiS300_LVDSCRT11280x1024_2;
338 SiS_Pr->SiS_LVDSCRT11280x1024_2_H = SiS300_LVDSCRT11280x1024_2_H;
339 SiS_Pr->SiS_LVDSCRT1XXXxXXX_1 = SiS300_LVDSCRT1XXXxXXX_1;
340 SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H = SiS300_LVDSCRT1XXXxXXX_1_H;
341
342 SiS_Pr->SiS_CHTVCRT1UNTSC = SiS300_CHTVCRT1UNTSC;
343 SiS_Pr->SiS_CHTVCRT1ONTSC = SiS300_CHTVCRT1ONTSC;
344 SiS_Pr->SiS_CHTVCRT1UPAL = SiS300_CHTVCRT1UPAL;
345 SiS_Pr->SiS_CHTVCRT1OPAL = SiS300_CHTVCRT1OPAL;
346 SiS_Pr->SiS_CHTVCRT1SOPAL = SiS300_CHTVCRT1SOPAL;
347 SiS_Pr->SiS_CHTVReg_UNTSC = SiS300_CHTVReg_UNTSC;
348 SiS_Pr->SiS_CHTVReg_ONTSC = SiS300_CHTVReg_ONTSC;
349 SiS_Pr->SiS_CHTVReg_UPAL = SiS300_CHTVReg_UPAL;
350 SiS_Pr->SiS_CHTVReg_OPAL = SiS300_CHTVReg_OPAL;
351 SiS_Pr->SiS_CHTVReg_UPALM = SiS300_CHTVReg_UNTSC; /* not supported on 300 series */
352 SiS_Pr->SiS_CHTVReg_OPALM = SiS300_CHTVReg_ONTSC; /* not supported on 300 series */
353 SiS_Pr->SiS_CHTVReg_UPALN = SiS300_CHTVReg_UPAL; /* not supported on 300 series */
354 SiS_Pr->SiS_CHTVReg_OPALN = SiS300_CHTVReg_OPAL; /* not supported on 300 series */
355 SiS_Pr->SiS_CHTVReg_SOPAL = SiS300_CHTVReg_SOPAL;
356 SiS_Pr->SiS_CHTVVCLKUNTSC = SiS300_CHTVVCLKUNTSC;
357 SiS_Pr->SiS_CHTVVCLKONTSC = SiS300_CHTVVCLKONTSC;
358 SiS_Pr->SiS_CHTVVCLKUPAL = SiS300_CHTVVCLKUPAL;
359 SiS_Pr->SiS_CHTVVCLKOPAL = SiS300_CHTVVCLKOPAL;
360 SiS_Pr->SiS_CHTVVCLKUPALM = SiS300_CHTVVCLKUNTSC; /* not supported on 300 series */
361 SiS_Pr->SiS_CHTVVCLKOPALM = SiS300_CHTVVCLKONTSC; /* not supported on 300 series */
362 SiS_Pr->SiS_CHTVVCLKUPALN = SiS300_CHTVVCLKUPAL; /* not supported on 300 series */
363 SiS_Pr->SiS_CHTVVCLKOPALN = SiS300_CHTVVCLKOPAL; /* not supported on 300 series */
364 SiS_Pr->SiS_CHTVVCLKSOPAL = SiS300_CHTVVCLKSOPAL;
365}
366#endif
367
368#ifdef SIS315H
369static void
370InitTo310Pointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
371{
372 InitCommonPointer(SiS_Pr, HwInfo);
373
374 SiS_Pr->SiS_SModeIDTable = SiS310_SModeIDTable;
375 SiS_Pr->SiS_EModeIDTable = SiS310_EModeIDTable;
376 SiS_Pr->SiS_RefIndex = (SiS_Ext2Struct *)SiS310_RefIndex;
377 SiS_Pr->SiS_CRT1Table = SiS310_CRT1Table;
378 if(HwInfo->jChipType >= SIS_340) {
379 SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_340; /* 340 */
380 } else if(HwInfo->jChipType >= SIS_761) {
381 SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_761; /* 761 - preliminary */
382 } else if(HwInfo->jChipType >= SIS_760) {
383 SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_760; /* 760 */
384 } else if(HwInfo->jChipType >= SIS_661) {
385 SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_660; /* 661/741 */
386 } else if(HwInfo->jChipType == SIS_330) {
387 SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_330; /* 330 */
388 } else if(HwInfo->jChipType > SIS_315PRO) {
389 SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_650; /* 550, 650, 740 */
390 } else {
391 SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_315; /* 315 */
392 }
393 if(HwInfo->jChipType >= SIS_340) {
394 SiS_Pr->SiS_MCLKData_1 = SiS310_MCLKData_1_340;
395 } else {
396 SiS_Pr->SiS_MCLKData_1 = SiS310_MCLKData_1;
397 }
398 SiS_Pr->SiS_VCLKData = SiS310_VCLKData;
399 SiS_Pr->SiS_VBVCLKData = SiS310_VBVCLKData;
400
401 SiS_Pr->SiS_SR15 = SiS310_SR15;
402
403#ifdef LINUX_KERNEL
404 SiS_Pr->pSiS_SR07 = &SiS310_SR07;
405 SiS_Pr->SiS_CR40 = SiS310_CR40;
406 SiS_Pr->SiS_CR49 = SiS310_CR49;
407 SiS_Pr->pSiS_SR1F = &SiS310_SR1F;
408 SiS_Pr->pSiS_SR21 = &SiS310_SR21;
409 SiS_Pr->pSiS_SR22 = &SiS310_SR22;
410 SiS_Pr->pSiS_SR23 = &SiS310_SR23;
411 SiS_Pr->pSiS_SR24 = &SiS310_SR24;
412 SiS_Pr->SiS_SR25 = SiS310_SR25;
413 SiS_Pr->pSiS_SR31 = &SiS310_SR31;
414 SiS_Pr->pSiS_SR32 = &SiS310_SR32;
415 SiS_Pr->pSiS_SR33 = &SiS310_SR33;
416 SiS_Pr->pSiS_CRT2Data_1_2 = &SiS310_CRT2Data_1_2;
417 SiS_Pr->pSiS_CRT2Data_4_D = &SiS310_CRT2Data_4_D;
418 SiS_Pr->pSiS_CRT2Data_4_E = &SiS310_CRT2Data_4_E;
419 SiS_Pr->pSiS_CRT2Data_4_10 = &SiS310_CRT2Data_4_10;
420 SiS_Pr->pSiS_RGBSenseData = &SiS310_RGBSenseData;
421 SiS_Pr->pSiS_VideoSenseData = &SiS310_VideoSenseData;
422 SiS_Pr->pSiS_YCSenseData = &SiS310_YCSenseData;
423 SiS_Pr->pSiS_RGBSenseData2 = &SiS310_RGBSenseData2;
424 SiS_Pr->pSiS_VideoSenseData2 = &SiS310_VideoSenseData2;
425 SiS_Pr->pSiS_YCSenseData2 = &SiS310_YCSenseData2;
426#endif
427
428 SiS_Pr->SiS_PanelDelayTbl = SiS310_PanelDelayTbl;
429 SiS_Pr->SiS_PanelDelayTblLVDS = SiS310_PanelDelayTblLVDS;
430
431 SiS_Pr->SiS_St2LCD1024x768Data = SiS310_St2LCD1024x768Data;
432 SiS_Pr->SiS_ExtLCD1024x768Data = SiS310_ExtLCD1024x768Data;
433 SiS_Pr->SiS_St2LCD1280x1024Data = SiS310_St2LCD1280x1024Data;
434 SiS_Pr->SiS_ExtLCD1280x1024Data = SiS310_ExtLCD1280x1024Data;
435
436 SiS_Pr->SiS_CRT2Part2_1024x768_1 = SiS310_CRT2Part2_1024x768_1;
437
438 SiS_Pr->SiS_PanelType00_1 = SiS310_PanelType00_1;
439 SiS_Pr->SiS_PanelType01_1 = SiS310_PanelType01_1;
440 SiS_Pr->SiS_PanelType02_1 = SiS310_PanelType02_1;
441 SiS_Pr->SiS_PanelType03_1 = SiS310_PanelType03_1;
442 SiS_Pr->SiS_PanelType04_1 = SiS310_PanelType04_1;
443 SiS_Pr->SiS_PanelType05_1 = SiS310_PanelType05_1;
444 SiS_Pr->SiS_PanelType06_1 = SiS310_PanelType06_1;
445 SiS_Pr->SiS_PanelType07_1 = SiS310_PanelType07_1;
446 SiS_Pr->SiS_PanelType08_1 = SiS310_PanelType08_1;
447 SiS_Pr->SiS_PanelType09_1 = SiS310_PanelType09_1;
448 SiS_Pr->SiS_PanelType0a_1 = SiS310_PanelType0a_1;
449 SiS_Pr->SiS_PanelType0b_1 = SiS310_PanelType0b_1;
450 SiS_Pr->SiS_PanelType0c_1 = SiS310_PanelType0c_1;
451 SiS_Pr->SiS_PanelType0d_1 = SiS310_PanelType0d_1;
452 SiS_Pr->SiS_PanelType0e_1 = SiS310_PanelType0e_1;
453 SiS_Pr->SiS_PanelType0f_1 = SiS310_PanelType0f_1;
454 SiS_Pr->SiS_PanelType00_2 = SiS310_PanelType00_2;
455 SiS_Pr->SiS_PanelType01_2 = SiS310_PanelType01_2;
456 SiS_Pr->SiS_PanelType02_2 = SiS310_PanelType02_2;
457 SiS_Pr->SiS_PanelType03_2 = SiS310_PanelType03_2;
458 SiS_Pr->SiS_PanelType04_2 = SiS310_PanelType04_2;
459 SiS_Pr->SiS_PanelType05_2 = SiS310_PanelType05_2;
460 SiS_Pr->SiS_PanelType06_2 = SiS310_PanelType06_2;
461 SiS_Pr->SiS_PanelType07_2 = SiS310_PanelType07_2;
462 SiS_Pr->SiS_PanelType08_2 = SiS310_PanelType08_2;
463 SiS_Pr->SiS_PanelType09_2 = SiS310_PanelType09_2;
464 SiS_Pr->SiS_PanelType0a_2 = SiS310_PanelType0a_2;
465 SiS_Pr->SiS_PanelType0b_2 = SiS310_PanelType0b_2;
466 SiS_Pr->SiS_PanelType0c_2 = SiS310_PanelType0c_2;
467 SiS_Pr->SiS_PanelType0d_2 = SiS310_PanelType0d_2;
468 SiS_Pr->SiS_PanelType0e_2 = SiS310_PanelType0e_2;
469 SiS_Pr->SiS_PanelType0f_2 = SiS310_PanelType0f_2;
470 SiS_Pr->SiS_PanelTypeNS_1 = SiS310_PanelTypeNS_1;
471 SiS_Pr->SiS_PanelTypeNS_2 = SiS310_PanelTypeNS_2;
472
473 SiS_Pr->SiS_CHTVUPALData = SiS310_CHTVUPALData;
474 SiS_Pr->SiS_CHTVOPALData = SiS310_CHTVOPALData;
475 SiS_Pr->SiS_CHTVUPALMData = SiS310_CHTVUPALMData;
476 SiS_Pr->SiS_CHTVOPALMData = SiS310_CHTVOPALMData;
477 SiS_Pr->SiS_CHTVUPALNData = SiS310_CHTVUPALNData;
478 SiS_Pr->SiS_CHTVOPALNData = SiS310_CHTVOPALNData;
479 SiS_Pr->SiS_CHTVSOPALData = SiS310_CHTVSOPALData;
480
481 SiS_Pr->SiS_LVDSCRT1800x600_1 = SiS310_LVDSCRT1800x600_1;
482 SiS_Pr->SiS_LVDSCRT11024x768_1 = SiS310_LVDSCRT11024x768_1;
483 SiS_Pr->SiS_LVDSCRT11280x1024_1 = SiS310_LVDSCRT11280x1024_1;
484 SiS_Pr->SiS_LVDSCRT11400x1050_1 = SiS310_LVDSCRT11400x1050_1;
485 SiS_Pr->SiS_LVDSCRT11600x1200_1 = SiS310_LVDSCRT11600x1200_1;
486 SiS_Pr->SiS_LVDSCRT1800x600_1_H = SiS310_LVDSCRT1800x600_1_H;
487 SiS_Pr->SiS_LVDSCRT11024x768_1_H = SiS310_LVDSCRT11024x768_1_H;
488 SiS_Pr->SiS_LVDSCRT11280x1024_1_H = SiS310_LVDSCRT11280x1024_1_H;
489 SiS_Pr->SiS_LVDSCRT11400x1050_1_H = SiS310_LVDSCRT11400x1050_1_H;
490 SiS_Pr->SiS_LVDSCRT11600x1200_1_H = SiS310_LVDSCRT11600x1200_1_H;
491 SiS_Pr->SiS_LVDSCRT1800x600_2 = SiS310_LVDSCRT1800x600_2;
492 SiS_Pr->SiS_LVDSCRT11024x768_2 = SiS310_LVDSCRT11024x768_2;
493 SiS_Pr->SiS_LVDSCRT11280x1024_2 = SiS310_LVDSCRT11280x1024_2;
494 SiS_Pr->SiS_LVDSCRT11400x1050_2 = SiS310_LVDSCRT11400x1050_2;
495 SiS_Pr->SiS_LVDSCRT11600x1200_2 = SiS310_LVDSCRT11600x1200_2;
496 SiS_Pr->SiS_LVDSCRT1800x600_2_H = SiS310_LVDSCRT1800x600_2_H;
497 SiS_Pr->SiS_LVDSCRT11024x768_2_H = SiS310_LVDSCRT11024x768_2_H;
498 SiS_Pr->SiS_LVDSCRT11280x1024_2_H = SiS310_LVDSCRT11280x1024_2_H;
499 SiS_Pr->SiS_LVDSCRT11400x1050_2_H = SiS310_LVDSCRT11400x1050_2_H;
500 SiS_Pr->SiS_LVDSCRT11600x1200_2_H = SiS310_LVDSCRT11600x1200_2_H;
501 SiS_Pr->SiS_LVDSCRT1XXXxXXX_1 = SiS310_LVDSCRT1XXXxXXX_1;
502 SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H = SiS310_LVDSCRT1XXXxXXX_1_H;
503 SiS_Pr->SiS_CHTVCRT1UNTSC = SiS310_CHTVCRT1UNTSC;
504 SiS_Pr->SiS_CHTVCRT1ONTSC = SiS310_CHTVCRT1ONTSC;
505 SiS_Pr->SiS_CHTVCRT1UPAL = SiS310_CHTVCRT1UPAL;
506 SiS_Pr->SiS_CHTVCRT1OPAL = SiS310_CHTVCRT1OPAL;
507 SiS_Pr->SiS_CHTVCRT1SOPAL = SiS310_CHTVCRT1OPAL;
508
509 SiS_Pr->SiS_CHTVReg_UNTSC = SiS310_CHTVReg_UNTSC;
510 SiS_Pr->SiS_CHTVReg_ONTSC = SiS310_CHTVReg_ONTSC;
511 SiS_Pr->SiS_CHTVReg_UPAL = SiS310_CHTVReg_UPAL;
512 SiS_Pr->SiS_CHTVReg_OPAL = SiS310_CHTVReg_OPAL;
513 SiS_Pr->SiS_CHTVReg_UPALM = SiS310_CHTVReg_UPALM;
514 SiS_Pr->SiS_CHTVReg_OPALM = SiS310_CHTVReg_OPALM;
515 SiS_Pr->SiS_CHTVReg_UPALN = SiS310_CHTVReg_UPALN;
516 SiS_Pr->SiS_CHTVReg_OPALN = SiS310_CHTVReg_OPALN;
517 SiS_Pr->SiS_CHTVReg_SOPAL = SiS310_CHTVReg_OPAL;
518
519 SiS_Pr->SiS_CHTVVCLKUNTSC = SiS310_CHTVVCLKUNTSC;
520 SiS_Pr->SiS_CHTVVCLKONTSC = SiS310_CHTVVCLKONTSC;
521 SiS_Pr->SiS_CHTVVCLKUPAL = SiS310_CHTVVCLKUPAL;
522 SiS_Pr->SiS_CHTVVCLKOPAL = SiS310_CHTVVCLKOPAL;
523 SiS_Pr->SiS_CHTVVCLKUPALM = SiS310_CHTVVCLKUPALM;
524 SiS_Pr->SiS_CHTVVCLKOPALM = SiS310_CHTVVCLKOPALM;
525 SiS_Pr->SiS_CHTVVCLKUPALN = SiS310_CHTVVCLKUPALN;
526 SiS_Pr->SiS_CHTVVCLKOPALN = SiS310_CHTVVCLKOPALN;
527 SiS_Pr->SiS_CHTVVCLKSOPAL = SiS310_CHTVVCLKOPAL;
528}
529#endif
530
531static void
532SiSInitPtr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
533{
534 switch(HwInfo->jChipType) {
535#ifdef SIS315H
536 case SIS_315H:
537 case SIS_315:
538 case SIS_315PRO:
539 case SIS_550:
540 case SIS_650:
541 case SIS_740:
542 case SIS_330:
543 case SIS_661:
544 case SIS_741:
545 case SIS_660:
546 case SIS_760:
547 case SIS_761:
548 case SIS_340:
549 InitTo310Pointer(SiS_Pr, HwInfo);
550 break;
551#endif
552#ifdef SIS300
553 case SIS_300:
554 case SIS_540:
555 case SIS_630:
556 case SIS_730:
557 InitTo300Pointer(SiS_Pr, HwInfo);
558 break;
559#endif
560 default:
561 break;
562 }
563}
564
565/*********************************************/
566/* HELPER: Get ModeID */
567/*********************************************/
568
569#ifdef LINUX_XF86
570USHORT
571SiS_GetModeID(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay,
572 int Depth, BOOLEAN FSTN, int LCDwidth, int LCDheight)
573{
574 USHORT ModeIndex = 0;
575
576 switch(HDisplay)
577 {
578 case 320:
579 if(VDisplay == 200) ModeIndex = ModeIndex_320x200[Depth];
580 else if(VDisplay == 240) {
581 if(FSTN) ModeIndex = ModeIndex_320x240_FSTN[Depth];
582 else ModeIndex = ModeIndex_320x240[Depth];
583 }
584 break;
585 case 400:
586 if((!(VBFlags & CRT1_LCDA)) || ((LCDwidth >= 800) && (LCDwidth >= 600))) {
587 if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
588 }
589 break;
590 case 512:
591 if((!(VBFlags & CRT1_LCDA)) || ((LCDwidth >= 1024) && (LCDwidth >= 768))) {
592 if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
593 }
594 break;
595 case 640:
596 if(VDisplay == 480) ModeIndex = ModeIndex_640x480[Depth];
597 else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth];
598 break;
599 case 720:
600 if(VDisplay == 480) ModeIndex = ModeIndex_720x480[Depth];
601 else if(VDisplay == 576) ModeIndex = ModeIndex_720x576[Depth];
602 break;
603 case 768:
604 if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
605 break;
606 case 800:
607 if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
608 else if(VDisplay == 480) ModeIndex = ModeIndex_800x480[Depth];
609 break;
610 case 848:
611 if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth];
612 break;
613 case 856:
614 if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth];
615 break;
616 case 960:
617 if(VGAEngine == SIS_315_VGA) {
618 if(VDisplay == 540) ModeIndex = ModeIndex_960x540[Depth];
619 else if(VDisplay == 600) ModeIndex = ModeIndex_960x600[Depth];
620 }
621 break;
622 case 1024:
623 if(VDisplay == 576) ModeIndex = ModeIndex_1024x576[Depth];
624 else if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
625 else if(VGAEngine == SIS_300_VGA) {
626 if(VDisplay == 600) ModeIndex = ModeIndex_1024x600[Depth];
627 }
628 break;
629 case 1152:
630 if(VDisplay == 864) ModeIndex = ModeIndex_1152x864[Depth];
631 if(VGAEngine == SIS_300_VGA) {
632 if(VDisplay == 768) ModeIndex = ModeIndex_1152x768[Depth];
633 }
634 break;
635 case 1280:
636 switch(VDisplay) {
637 case 720:
638 ModeIndex = ModeIndex_1280x720[Depth];
639 break;
640 case 768:
641 if(VGAEngine == SIS_300_VGA) {
642 ModeIndex = ModeIndex_300_1280x768[Depth];
643 } else {
644 ModeIndex = ModeIndex_310_1280x768[Depth];
645 }
646 break;
647 case 800:
648 if(VGAEngine == SIS_315_VGA) {
649 ModeIndex = ModeIndex_1280x800[Depth];
650 }
651 break;
652 case 960:
653 ModeIndex = ModeIndex_1280x960[Depth];
654 break;
655 case 1024:
656 ModeIndex = ModeIndex_1280x1024[Depth];
657 break;
658 }
659 break;
660 case 1360:
661 if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth];
662 if(VGAEngine == SIS_300_VGA) {
663 if(VDisplay == 1024) ModeIndex = ModeIndex_300_1360x1024[Depth];
664 }
665 break;
666 case 1400:
667 if(VGAEngine == SIS_315_VGA) {
668 if(VDisplay == 1050) {
669 ModeIndex = ModeIndex_1400x1050[Depth];
670 }
671 }
672 break;
673 case 1600:
674 if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
675 break;
676 case 1680:
677 if(VGAEngine == SIS_315_VGA) {
678 if(VDisplay == 1050) ModeIndex = ModeIndex_1680x1050[Depth];
679 }
680 break;
681 case 1920:
682 if(VDisplay == 1440) ModeIndex = ModeIndex_1920x1440[Depth];
683 else if(VGAEngine == SIS_315_VGA) {
684 if(VDisplay == 1080) ModeIndex = ModeIndex_1920x1080[Depth];
685 }
686 break;
687 case 2048:
688 if(VDisplay == 1536) {
689 if(VGAEngine == SIS_300_VGA) {
690 ModeIndex = ModeIndex_300_2048x1536[Depth];
691 } else {
692 ModeIndex = ModeIndex_310_2048x1536[Depth];
693 }
694 }
695 break;
696 }
697
698 return(ModeIndex);
699}
700#endif
701
702USHORT
703SiS_GetModeID_LCD(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay,
704 int Depth, BOOLEAN FSTN, USHORT CustomT, int LCDwidth, int LCDheight)
705{
706 USHORT ModeIndex = 0;
707
708 if(VBFlags & (VB_LVDS | VB_30xBDH)) {
709
710 switch(HDisplay)
711 {
712 case 320:
713 if(CustomT != CUT_PANEL848) {
714 if(VDisplay == 200) ModeIndex = ModeIndex_320x200[Depth];
715 else if(VDisplay == 240) {
716 if(!FSTN) ModeIndex = ModeIndex_320x240[Depth];
717 else if(VGAEngine == SIS_315_VGA) {
718 ModeIndex = ModeIndex_320x240_FSTN[Depth];
719 }
720 }
721 }
722 break;
723 case 400:
724 if(CustomT != CUT_PANEL848) {
725 if(!((VGAEngine == SIS_300_VGA) && (VBFlags & VB_TRUMPION))) {
726 if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
727 }
728 }
729 break;
730 case 512:
731 if(CustomT != CUT_PANEL848) {
732 if(!((VGAEngine == SIS_300_VGA) && (VBFlags & VB_TRUMPION))) {
733 if(LCDwidth >= 1024 && LCDwidth != 1152 && LCDheight >= 768) {
734 if(VDisplay == 384) {
735 ModeIndex = ModeIndex_512x384[Depth];
736 }
737 }
738 }
739 }
740 break;
741 case 640:
742 if(VDisplay == 480) ModeIndex = ModeIndex_640x480[Depth];
743 else if(VDisplay == 400) {
744 if(CustomT != CUT_PANEL848) ModeIndex = ModeIndex_640x400[Depth];
745 }
746 break;
747 case 800:
748 if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
749 break;
750 case 848:
751 if(CustomT == CUT_PANEL848) {
752 if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth];
753 }
754 break;
755 case 1024:
756 if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
757 else if(VGAEngine == SIS_300_VGA) {
758 if((VDisplay == 600) && (LCDheight == 600)) {
759 ModeIndex = ModeIndex_1024x600[Depth];
760 }
761 }
762 break;
763 case 1152:
764 if(VGAEngine == SIS_300_VGA) {
765 if((VDisplay == 768) && (LCDheight == 768)) {
766 ModeIndex = ModeIndex_1152x768[Depth];
767 }
768 }
769 break;
770 case 1280:
771 if(VDisplay == 1024) ModeIndex = ModeIndex_1280x1024[Depth];
772 else if(VGAEngine == SIS_315_VGA) {
773 if((VDisplay == 768) && (LCDheight == 768)) {
774 ModeIndex = ModeIndex_310_1280x768[Depth];
775 }
776 }
777 break;
778 case 1360:
779 if(VGAEngine == SIS_300_VGA) {
780 if(CustomT == CUT_BARCO1366) {
781 if(VDisplay == 1024) ModeIndex = ModeIndex_300_1360x1024[Depth];
782 }
783 }
784 if(CustomT == CUT_PANEL848) {
785 if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth];
786 }
787 break;
788 case 1400:
789 if(VGAEngine == SIS_315_VGA) {
790 if(VDisplay == 1050) ModeIndex = ModeIndex_1400x1050[Depth];
791 }
792 break;
793 case 1600:
794 if(VGAEngine == SIS_315_VGA) {
795 if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
796 }
797 break;
798 }
799
800 } else if(VBFlags & VB_SISBRIDGE) {
801
802 switch(HDisplay)
803 {
804 case 320:
805 if(VDisplay == 200) ModeIndex = ModeIndex_320x200[Depth];
806 else if(VDisplay == 240) ModeIndex = ModeIndex_320x240[Depth];
807 break;
808 case 400:
809 if(LCDwidth >= 800 && LCDheight >= 600) {
810 if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
811 }
812 break;
813 case 512:
814 if(LCDwidth >= 1024 && LCDheight >= 768 && LCDwidth != 1152) {
815 if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
816 }
817 break;
818 case 640:
819 if(VDisplay == 480) ModeIndex = ModeIndex_640x480[Depth];
820 else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth];
821 break;
822 case 720:
823 if(VGAEngine == SIS_315_VGA) {
824 if(VDisplay == 480) ModeIndex = ModeIndex_720x480[Depth];
825 else if(VDisplay == 576) ModeIndex = ModeIndex_720x576[Depth];
826 }
827 break;
828 case 768:
829 if(VGAEngine == SIS_315_VGA) {
830 if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
831 }
832 break;
833 case 800:
834 if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
835 if(VGAEngine == SIS_315_VGA) {
836 if(VDisplay == 480) ModeIndex = ModeIndex_800x480[Depth];
837 }
838 break;
839 case 848:
840 if(VGAEngine == SIS_315_VGA) {
841 if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth];
842 }
843 break;
844 case 856:
845 if(VGAEngine == SIS_315_VGA) {
846 if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth];
847 }
848 break;
849 case 960:
850 if(VGAEngine == SIS_315_VGA) {
851 if(VDisplay == 540) ModeIndex = ModeIndex_960x540[Depth];
852 else if(VDisplay == 600) ModeIndex = ModeIndex_960x600[Depth];
853 }
854 break;
855 case 1024:
856 if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
857 if(VGAEngine == SIS_315_VGA) {
858 if(VDisplay == 576) ModeIndex = ModeIndex_1024x576[Depth];
859 }
860 break;
861 case 1152:
862 if(VGAEngine == SIS_315_VGA) {
863 if(VDisplay == 864) ModeIndex = ModeIndex_1152x864[Depth];
864 }
865 break;
866 case 1280:
867 switch(VDisplay) {
868 case 720:
869 ModeIndex = ModeIndex_1280x720[Depth];
870 case 768:
871 if(VGAEngine == SIS_300_VGA) {
872 ModeIndex = ModeIndex_300_1280x768[Depth];
873 } else {
874 ModeIndex = ModeIndex_310_1280x768[Depth];
875 }
876 break;
877 case 800:
878 if(VGAEngine == SIS_315_VGA) {
879 ModeIndex = ModeIndex_1280x800[Depth];
880 }
881 break;
882 case 960:
883 ModeIndex = ModeIndex_1280x960[Depth];
884 break;
885 case 1024:
886 ModeIndex = ModeIndex_1280x1024[Depth];
887 break;
888 }
889 break;
890 case 1360:
891 if(VGAEngine == SIS_315_VGA) {
892 if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth];
893 }
894 break;
895 case 1400:
896 if(VGAEngine == SIS_315_VGA) {
897 if(VBFlags & (VB_301C | VB_302LV | VB_302ELV)) {
898 if(VDisplay == 1050) ModeIndex = ModeIndex_1400x1050[Depth];
899 }
900 }
901 break;
902 case 1600:
903 if(VGAEngine == SIS_315_VGA) {
904 if(VBFlags & (VB_301C | VB_302LV | VB_302ELV)) {
905 if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
906 }
907 }
908 break;
909#ifndef VB_FORBID_CRT2LCD_OVER_1600
910 case 1680:
911 if(VGAEngine == SIS_315_VGA) {
912 if(VBFlags & (VB_301C | VB_302LV | VB_302ELV)) {
913 if(VDisplay == 1050) ModeIndex = ModeIndex_1680x1050[Depth];
914 }
915 }
916 break;
917#endif
918 }
919 }
920
921 return ModeIndex;
922}
923
924USHORT
925SiS_GetModeID_TV(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth)
926{
927 USHORT ModeIndex = 0;
928
929 if(VBFlags & VB_CHRONTEL) {
930
931 switch(HDisplay)
932 {
933 case 512:
934 if(VGAEngine == SIS_315_VGA) {
935 if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
936 }
937 break;
938 case 640:
939 if(VDisplay == 480) ModeIndex = ModeIndex_640x480[Depth];
940 else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth];
941 break;
942 case 800:
943 if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
944 break;
945 case 1024:
946 if(VGAEngine == SIS_315_VGA) {
947 if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
948 }
949 break;
950 }
951
952 } else if(VBFlags & VB_SISTVBRIDGE) {
953
954 switch(HDisplay)
955 {
956 case 320:
957 if(VDisplay == 200) ModeIndex = ModeIndex_320x200[Depth];
958 else if(VDisplay == 240) ModeIndex = ModeIndex_320x240[Depth];
959 break;
960 case 400:
961 if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
962 break;
963 case 512:
964 if( ((VBFlags & TV_YPBPR) && (VBFlags & (TV_YPBPR750P | TV_YPBPR1080I))) ||
965 (VBFlags & TV_HIVISION) ||
966 ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL)) ) {
967 if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
968 }
969 break;
970 case 640:
971 if(VDisplay == 480) ModeIndex = ModeIndex_640x480[Depth];
972 else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth];
973 break;
974 case 720:
975 if((!(VBFlags & TV_HIVISION)) && (!((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I)))) {
976 if(VDisplay == 480) {
977 ModeIndex = ModeIndex_720x480[Depth];
978 } else if(VDisplay == 576) {
979 if( ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR750P)) ||
980 ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL)) )
981 ModeIndex = ModeIndex_720x576[Depth];
982 }
983 }
984 break;
985 case 768:
986 if((!(VBFlags & TV_HIVISION)) && (!((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I)))) {
987 if( ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR750P)) ||
988 ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL)) ) {
989 if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
990 }
991 }
992 break;
993 case 800:
994 if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
995 else if(VDisplay == 480) {
996 if((VBFlags & TV_HIVISION) || ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I))) {
997 ModeIndex = ModeIndex_800x480[Depth];
998 }
999 }
1000 break;
1001 case 960:
1002 if(VGAEngine == SIS_315_VGA) {
1003 if(VDisplay == 600) {
1004 if((VBFlags & TV_HIVISION) || ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I))) {
1005 ModeIndex = ModeIndex_960x600[Depth];
1006 }
1007 }
1008 }
1009 break;
1010 case 1024:
1011 if(VDisplay == 768) {
1012 if(VBFlags & (VB_301B|VB_301C|VB_302B|VB_301LV|VB_302LV|VB_302ELV)) {
1013 ModeIndex = ModeIndex_1024x768[Depth];
1014 }
1015 } else if(VDisplay == 576) {
1016 if((VBFlags & TV_HIVISION) || ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I))) {
1017 ModeIndex = ModeIndex_1024x576[Depth];
1018 }
1019 }
1020 break;
1021 case 1280:
1022 if(VDisplay == 720) {
1023 if((VBFlags & TV_HIVISION) ||
1024 ((VBFlags & TV_YPBPR) && (VBFlags & (TV_YPBPR1080I | TV_YPBPR750P)))) {
1025 ModeIndex = ModeIndex_1280x720[Depth];
1026 }
1027 } else if(VDisplay == 1024) {
1028 if((VBFlags & TV_HIVISION) ||
1029 ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I))) {
1030 ModeIndex = ModeIndex_1280x1024[Depth];
1031 }
1032 }
1033 break;
1034 }
1035 }
1036 return ModeIndex;
1037}
1038
1039USHORT
1040SiS_GetModeID_VGA2(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth)
1041{
1042 USHORT ModeIndex = 0;
1043
1044 if(!(VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) return 0;
1045
1046 switch(HDisplay)
1047 {
1048 case 320:
1049 if(VDisplay == 200) ModeIndex = ModeIndex_320x200[Depth];
1050 else if(VDisplay == 240) ModeIndex = ModeIndex_320x240[Depth];
1051 break;
1052 case 400:
1053 if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
1054 break;
1055 case 512:
1056 if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
1057 break;
1058 case 640:
1059 if(VDisplay == 480) ModeIndex = ModeIndex_640x480[Depth];
1060 else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth];
1061 break;
1062 case 720:
1063 if(VDisplay == 480) ModeIndex = ModeIndex_720x480[Depth];
1064 else if(VDisplay == 576) ModeIndex = ModeIndex_720x576[Depth];
1065 break;
1066 case 768:
1067 if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
1068 break;
1069 case 800:
1070 if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
1071 else if(VDisplay == 480) ModeIndex = ModeIndex_800x480[Depth];
1072 break;
1073 case 848:
1074 if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth];
1075 break;
1076 case 856:
1077 if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth];
1078 break;
1079 case 960:
1080 if(VGAEngine == SIS_315_VGA) {
1081 if(VDisplay == 540) ModeIndex = ModeIndex_960x540[Depth];
1082 else if(VDisplay == 600) ModeIndex = ModeIndex_960x600[Depth];
1083 }
1084 break;
1085 case 1024:
1086 if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
1087 else if(VDisplay == 576) ModeIndex = ModeIndex_1024x576[Depth];
1088 break;
1089 case 1152:
1090 if(VDisplay == 864) ModeIndex = ModeIndex_1152x864[Depth];
1091 else if(VGAEngine == SIS_300_VGA) {
1092 if(VDisplay == 768) ModeIndex = ModeIndex_1152x768[Depth];
1093 }
1094 break;
1095 case 1280:
1096 if(VDisplay == 768) {
1097 if(VGAEngine == SIS_300_VGA) {
1098 ModeIndex = ModeIndex_300_1280x768[Depth];
1099 } else {
1100 ModeIndex = ModeIndex_310_1280x768[Depth];
1101 }
1102 } else if(VDisplay == 1024) ModeIndex = ModeIndex_1280x1024[Depth];
1103 else if(VDisplay == 720) ModeIndex = ModeIndex_1280x720[Depth];
1104 else if(VDisplay == 800) ModeIndex = ModeIndex_1280x800[Depth];
1105 else if(VDisplay == 960) ModeIndex = ModeIndex_1280x960[Depth];
1106 break;
1107 case 1360:
1108 if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth];
1109 break;
1110 case 1400:
1111 if(VGAEngine == SIS_315_VGA) {
1112 if(VDisplay == 1050) ModeIndex = ModeIndex_1400x1050[Depth];
1113 }
1114 break;
1115 case 1600:
1116 if(VGAEngine == SIS_315_VGA) {
1117 if(VBFlags & (VB_301B|VB_301C|VB_302B)) {
1118 if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
1119 }
1120 }
1121 break;
1122 case 1680:
1123 if(VGAEngine == SIS_315_VGA) {
1124 if(VBFlags & (VB_301B|VB_301C|VB_302B)) {
1125 if(VDisplay == 1050) ModeIndex = ModeIndex_1680x1050[Depth];
1126 }
1127 }
1128 break;
1129 }
1130
1131 return ModeIndex;
1132}
1133
1134
1135/*********************************************/
1136/* HELPER: SetReg, GetReg */
1137/*********************************************/
1138
1139void
1140SiS_SetReg(SISIOADDRESS port, USHORT index, USHORT data)
1141{
1142 OutPortByte(port,index);
1143 OutPortByte(port + 1,data);
1144}
1145
1146void
1147SiS_SetRegByte(SISIOADDRESS port, USHORT data)
1148{
1149 OutPortByte(port,data);
1150}
1151
1152void
1153SiS_SetRegShort(SISIOADDRESS port, USHORT data)
1154{
1155 OutPortWord(port,data);
1156}
1157
1158void
1159SiS_SetRegLong(SISIOADDRESS port, ULONG data)
1160{
1161 OutPortLong(port,data);
1162}
1163
1164UCHAR
1165SiS_GetReg(SISIOADDRESS port, USHORT index)
1166{
1167 OutPortByte(port,index);
1168 return(InPortByte(port + 1));
1169}
1170
1171UCHAR
1172SiS_GetRegByte(SISIOADDRESS port)
1173{
1174 return(InPortByte(port));
1175}
1176
1177USHORT
1178SiS_GetRegShort(SISIOADDRESS port)
1179{
1180 return(InPortWord(port));
1181}
1182
1183ULONG
1184SiS_GetRegLong(SISIOADDRESS port)
1185{
1186 return(InPortLong(port));
1187}
1188
1189void
1190SiS_SetRegANDOR(SISIOADDRESS Port,USHORT Index,USHORT DataAND,USHORT DataOR)
1191{
1192 USHORT temp;
1193
1194 temp = SiS_GetReg(Port,Index);
1195 temp = (temp & (DataAND)) | DataOR;
1196 SiS_SetReg(Port,Index,temp);
1197}
1198
1199void
1200SiS_SetRegAND(SISIOADDRESS Port,USHORT Index,USHORT DataAND)
1201{
1202 USHORT temp;
1203
1204 temp = SiS_GetReg(Port,Index);
1205 temp &= DataAND;
1206 SiS_SetReg(Port,Index,temp);
1207}
1208
1209void
1210SiS_SetRegOR(SISIOADDRESS Port,USHORT Index,USHORT DataOR)
1211{
1212 USHORT temp;
1213
1214 temp = SiS_GetReg(Port,Index);
1215 temp |= DataOR;
1216 SiS_SetReg(Port,Index,temp);
1217}
1218
1219/*********************************************/
1220/* HELPER: DisplayOn, DisplayOff */
1221/*********************************************/
1222
1223void
1224SiS_DisplayOn(SiS_Private *SiS_Pr)
1225{
1226 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x01,0xDF);
1227}
1228
1229void
1230SiS_DisplayOff(SiS_Private *SiS_Pr)
1231{
1232 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x01,0x20);
1233}
1234
1235
1236/*********************************************/
1237/* HELPER: Init Port Addresses */
1238/*********************************************/
1239
1240void
1241SiSRegInit(SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr)
1242{
1243 SiS_Pr->SiS_P3c4 = BaseAddr + 0x14;
1244 SiS_Pr->SiS_P3d4 = BaseAddr + 0x24;
1245 SiS_Pr->SiS_P3c0 = BaseAddr + 0x10;
1246 SiS_Pr->SiS_P3ce = BaseAddr + 0x1e;
1247 SiS_Pr->SiS_P3c2 = BaseAddr + 0x12;
1248 SiS_Pr->SiS_P3ca = BaseAddr + 0x1a;
1249 SiS_Pr->SiS_P3c6 = BaseAddr + 0x16;
1250 SiS_Pr->SiS_P3c7 = BaseAddr + 0x17;
1251 SiS_Pr->SiS_P3c8 = BaseAddr + 0x18;
1252 SiS_Pr->SiS_P3c9 = BaseAddr + 0x19;
1253 SiS_Pr->SiS_P3cb = BaseAddr + 0x1b;
1254 SiS_Pr->SiS_P3cd = BaseAddr + 0x1d;
1255 SiS_Pr->SiS_P3da = BaseAddr + 0x2a;
1256 SiS_Pr->SiS_Part1Port = BaseAddr + SIS_CRT2_PORT_04; /* Digital video interface registers (LCD) */
1257 SiS_Pr->SiS_Part2Port = BaseAddr + SIS_CRT2_PORT_10; /* 301 TV Encoder registers */
1258 SiS_Pr->SiS_Part3Port = BaseAddr + SIS_CRT2_PORT_12; /* 301 Macrovision registers */
1259 SiS_Pr->SiS_Part4Port = BaseAddr + SIS_CRT2_PORT_14; /* 301 VGA2 (and LCD) registers */
1260 SiS_Pr->SiS_Part5Port = BaseAddr + SIS_CRT2_PORT_14 + 2; /* 301 palette address port registers */
1261 SiS_Pr->SiS_DDC_Port = BaseAddr + 0x14; /* DDC Port ( = P3C4, SR11/0A) */
1262 SiS_Pr->SiS_VidCapt = BaseAddr + SIS_VIDEO_CAPTURE;
1263 SiS_Pr->SiS_VidPlay = BaseAddr + SIS_VIDEO_PLAYBACK;
1264}
1265
1266/*********************************************/
1267/* HELPER: GetSysFlags */
1268/*********************************************/
1269
1270static void
1271SiS_GetSysFlags(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
1272{
1273 unsigned char cr5f, temp1, temp2;
1274
1275 /* 661 and newer: NEVER write non-zero to SR11[7:4] */
1276 /* (SR11 is used for DDC and in enable/disablebridge) */
1277 SiS_Pr->SiS_SensibleSR11 = FALSE;
1278 SiS_Pr->SiS_MyCR63 = 0x63;
1279 if(HwInfo->jChipType >= SIS_330) {
1280 SiS_Pr->SiS_MyCR63 = 0x53;
1281 if(HwInfo->jChipType >= SIS_661) {
1282 SiS_Pr->SiS_SensibleSR11 = TRUE;
1283 }
1284 }
1285
1286 /* You should use the macros, not these flags directly */
1287
1288 SiS_Pr->SiS_SysFlags = 0;
1289 if(HwInfo->jChipType == SIS_650) {
1290 cr5f = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0;
1291 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x5c,0x07);
1292 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5c) & 0xf8;
1293 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x5c,0xf8);
1294 temp2 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5c) & 0xf8;
1295 if((!temp1) || (temp2)) {
1296 switch(cr5f) {
1297 case 0x80:
1298 case 0x90:
1299 case 0xc0:
1300 SiS_Pr->SiS_SysFlags |= SF_IsM650; break;
1301 case 0xa0:
1302 case 0xb0:
1303 case 0xe0:
1304 SiS_Pr->SiS_SysFlags |= SF_Is651; break;
1305 }
1306 } else {
1307 switch(cr5f) {
1308 case 0x90:
1309 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5c) & 0xf8;
1310 switch(temp1) {
1311 case 0x00: SiS_Pr->SiS_SysFlags |= SF_IsM652; break;
1312 case 0x40: SiS_Pr->SiS_SysFlags |= SF_IsM653; break;
1313 default: SiS_Pr->SiS_SysFlags |= SF_IsM650; break;
1314 }
1315 break;
1316 case 0xb0:
1317 SiS_Pr->SiS_SysFlags |= SF_Is652; break;
1318 default:
1319 SiS_Pr->SiS_SysFlags |= SF_IsM650; break;
1320 }
1321 }
1322 }
1323 if(HwInfo->jChipType == SIS_760) {
1324 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x78);
1325 if(temp1 & 0x30) SiS_Pr->SiS_SysFlags |= SF_760LFB;
1326 }
1327}
1328
1329/*********************************************/
1330/* HELPER: Init PCI & Engines */
1331/*********************************************/
1332
1333static void
1334SiSInitPCIetc(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
1335{
1336 switch(HwInfo->jChipType) {
1337 case SIS_300:
1338 case SIS_540:
1339 case SIS_630:
1340 case SIS_730:
1341 /* Set - PCI LINEAR ADDRESSING ENABLE (0x80)
1342 * - RELOCATED VGA IO (0x20)
1343 * - MMIO ENABLE (0x1)
1344 */
1345 SiS_SetReg(SiS_Pr->SiS_P3c4,0x20,0xa1);
1346 /* - Enable 2D (0x40)
1347 * - Enable 3D (0x02)
1348 * - Enable 3D Vertex command fetch (0x10) ?
1349 * - Enable 3D command parser (0x08) ?
1350 */
1351 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x5A);
1352 break;
1353 case SIS_315H:
1354 case SIS_315:
1355 case SIS_315PRO:
1356 case SIS_650:
1357 case SIS_740:
1358 case SIS_330:
1359 case SIS_661:
1360 case SIS_741:
1361 case SIS_660:
1362 case SIS_760:
1363 case SIS_761:
1364 case SIS_340:
1365 SiS_SetReg(SiS_Pr->SiS_P3c4,0x20,0xa1);
1366 /* - Enable 2D (0x40)
1367 * - Enable 3D (0x02)
1368 * - Enable 3D vertex command fetch (0x10)
1369 * - Enable 3D command parser (0x08)
1370 * - Enable 3D G/L transformation engine (0x80)
1371 */
1372 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0xDA);
1373 break;
1374 case SIS_550:
1375 SiS_SetReg(SiS_Pr->SiS_P3c4,0x20,0xa1);
1376 /* No 3D engine ! */
1377 /* - Enable 2D (0x40)
1378 */
1379 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x40);
1380 }
1381}
1382
1383/*********************************************/
1384/* HELPER: SetLVDSetc */
1385/*********************************************/
1386
1387void
1388SiSSetLVDSetc(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
1389{
1390 USHORT temp;
1391
1392 SiS_Pr->SiS_IF_DEF_LVDS = 0;
1393 SiS_Pr->SiS_IF_DEF_TRUMPION = 0;
1394 SiS_Pr->SiS_IF_DEF_CH70xx = 0;
1395 SiS_Pr->SiS_IF_DEF_DSTN = 0;
1396 SiS_Pr->SiS_IF_DEF_FSTN = 0;
1397 SiS_Pr->SiS_IF_DEF_CONEX = 0;
1398
1399 SiS_Pr->SiS_ChrontelInit = 0;
1400
1401 /* Check for SiS30x first */
1402 temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
1403 if((temp == 1) || (temp == 2)) return;
1404
1405 switch(HwInfo->jChipType) {
1406#ifdef SIS300
1407 case SIS_540:
1408 case SIS_630:
1409 case SIS_730:
1410 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
1411 temp = (temp & 0x0E) >> 1;
1412 if((temp >= 2) && (temp <= 5)) SiS_Pr->SiS_IF_DEF_LVDS = 1;
1413 if(temp == 3) SiS_Pr->SiS_IF_DEF_TRUMPION = 1;
1414 if((temp == 4) || (temp == 5)) {
1415 /* Save power status (and error check) - UNUSED */
1416 SiS_Pr->SiS_Backup70xx = SiS_GetCH700x(SiS_Pr, 0x0e);
1417 SiS_Pr->SiS_IF_DEF_CH70xx = 1;
1418 }
1419 break;
1420#endif
1421#ifdef SIS315H
1422 case SIS_550:
1423 case SIS_650:
1424 case SIS_740:
1425 case SIS_330:
1426 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
1427 temp = (temp & 0x0E) >> 1;
1428 if((temp >= 2) && (temp <= 3)) SiS_Pr->SiS_IF_DEF_LVDS = 1;
1429 if(temp == 3) SiS_Pr->SiS_IF_DEF_CH70xx = 2;
1430 break;
1431 case SIS_661:
1432 case SIS_741:
1433 case SIS_660:
1434 case SIS_760:
1435 case SIS_761:
1436 case SIS_340:
1437 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1438 temp = (temp & 0xe0) >> 5;
1439 if((temp >= 2) && (temp <= 3)) SiS_Pr->SiS_IF_DEF_LVDS = 1;
1440 if(temp == 3) SiS_Pr->SiS_IF_DEF_CH70xx = 2;
1441 if(temp == 4) SiS_Pr->SiS_IF_DEF_CONEX = 1; /* Not yet supported */
1442 break;
1443#endif
1444 default:
1445 break;
1446 }
1447}
1448
1449/*********************************************/
1450/* HELPER: Enable DSTN/FSTN */
1451/*********************************************/
1452
1453void
1454SiS_SetEnableDstn(SiS_Private *SiS_Pr, int enable)
1455{
1456 SiS_Pr->SiS_IF_DEF_DSTN = enable ? 1 : 0;
1457}
1458
1459void
1460SiS_SetEnableFstn(SiS_Private *SiS_Pr, int enable)
1461{
1462 SiS_Pr->SiS_IF_DEF_FSTN = enable ? 1 : 0;
1463}
1464
1465/*********************************************/
1466/* HELPER: Determine ROM usage */
1467/*********************************************/
1468
1469BOOLEAN
1470SiSDetermineROMLayout661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
1471{
1472 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
1473 USHORT romversoffs, romvmaj = 1, romvmin = 0;
1474
1475 if(HwInfo->jChipType >= SIS_761) {
1476 /* I very much assume 761 and 340 will use new layout */
1477 return TRUE;
1478 } else if(HwInfo->jChipType >= SIS_661) {
1479 if((ROMAddr[0x1a] == 'N') &&
1480 (ROMAddr[0x1b] == 'e') &&
1481 (ROMAddr[0x1c] == 'w') &&
1482 (ROMAddr[0x1d] == 'V')) {
1483 return TRUE;
1484 }
1485 romversoffs = ROMAddr[0x16] | (ROMAddr[0x17] << 8);
1486 if(romversoffs) {
1487 if((ROMAddr[romversoffs+1] == '.') || (ROMAddr[romversoffs+4] == '.')) {
1488 romvmaj = ROMAddr[romversoffs] - '0';
1489 romvmin = ((ROMAddr[romversoffs+2] -'0') * 10) + (ROMAddr[romversoffs+3] - '0');
1490 }
1491 }
1492 if((romvmaj != 0) || (romvmin >= 92)) {
1493 return TRUE;
1494 }
1495 } else if(IS_SIS650740) {
1496 if((ROMAddr[0x1a] == 'N') &&
1497 (ROMAddr[0x1b] == 'e') &&
1498 (ROMAddr[0x1c] == 'w') &&
1499 (ROMAddr[0x1d] == 'V')) {
1500 return TRUE;
1501 }
1502 }
1503 return FALSE;
1504}
1505
1506static void
1507SiSDetermineROMUsage(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
1508{
1509 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
1510 USHORT romptr = 0;
1511
1512 SiS_Pr->SiS_UseROM = FALSE;
1513 SiS_Pr->SiS_ROMNew = FALSE;
1514
1515 if((ROMAddr) && (HwInfo->UseROM)) {
1516 if(HwInfo->jChipType == SIS_300) {
1517 /* 300: We check if the code starts below 0x220 by
1518 * checking the jmp instruction at the beginning
1519 * of the BIOS image.
1520 */
1521 if((ROMAddr[3] == 0xe9) && ((ROMAddr[5] << 8) | ROMAddr[4]) > 0x21a)
1522 SiS_Pr->SiS_UseROM = TRUE;
1523 } else if(HwInfo->jChipType < SIS_315H) {
1524 /* Sony's VAIO BIOS 1.09 follows the standard, so perhaps
1525 * the others do as well
1526 */
1527 SiS_Pr->SiS_UseROM = TRUE;
1528 } else {
1529 /* 315/330 series stick to the standard(s) */
1530 SiS_Pr->SiS_UseROM = TRUE;
1531 if((SiS_Pr->SiS_ROMNew = SiSDetermineROMLayout661(SiS_Pr, HwInfo))) {
1532 SiS_Pr->SiS_EMIOffset = 14;
1533 SiS_Pr->SiS661LCD2TableSize = 36;
1534 /* Find out about LCD data table entry size */
1535 if((romptr = SISGETROMW(0x0102))) {
1536 if(ROMAddr[romptr + (32 * 16)] == 0xff)
1537 SiS_Pr->SiS661LCD2TableSize = 32;
1538 else if(ROMAddr[romptr + (34 * 16)] == 0xff)
1539 SiS_Pr->SiS661LCD2TableSize = 34;
1540 else if(ROMAddr[romptr + (36 * 16)] == 0xff) /* 0.94 */
1541 SiS_Pr->SiS661LCD2TableSize = 36;
1542 else if( (ROMAddr[romptr + (38 * 16)] == 0xff) || /* 2.00.00 - 2.02.00 */
1543 (ROMAddr[0x6F] & 0x01) ) { /* 2.03.00+ */
1544 SiS_Pr->SiS661LCD2TableSize = 38;
1545 SiS_Pr->SiS_EMIOffset = 16;
1546 }
1547 }
1548 }
1549 }
1550 }
1551}
1552
1553/*********************************************/
1554/* HELPER: SET SEGMENT REGISTERS */
1555/*********************************************/
1556
1557static void
1558SiS_SetSegRegLower(SiS_Private *SiS_Pr, USHORT value)
1559{
1560 USHORT temp;
1561
1562 value &= 0x00ff;
1563 temp = SiS_GetRegByte(SiS_Pr->SiS_P3cb) & 0xf0;
1564 temp |= (value >> 4);
1565 SiS_SetRegByte(SiS_Pr->SiS_P3cb, temp);
1566 temp = SiS_GetRegByte(SiS_Pr->SiS_P3cd) & 0xf0;
1567 temp |= (value & 0x0f);
1568 SiS_SetRegByte(SiS_Pr->SiS_P3cd, temp);
1569}
1570
1571static void
1572SiS_SetSegRegUpper(SiS_Private *SiS_Pr, USHORT value)
1573{
1574 USHORT temp;
1575
1576 value &= 0x00ff;
1577 temp = SiS_GetRegByte(SiS_Pr->SiS_P3cb) & 0x0f;
1578 temp |= (value & 0xf0);
1579 SiS_SetRegByte(SiS_Pr->SiS_P3cb, temp);
1580 temp = SiS_GetRegByte(SiS_Pr->SiS_P3cd) & 0x0f;
1581 temp |= (value << 4);
1582 SiS_SetRegByte(SiS_Pr->SiS_P3cd, temp);
1583}
1584
1585static void
1586SiS_SetSegmentReg(SiS_Private *SiS_Pr, USHORT value)
1587{
1588 SiS_SetSegRegLower(SiS_Pr, value);
1589 SiS_SetSegRegUpper(SiS_Pr, value);
1590}
1591
1592static void
1593SiS_ResetSegmentReg(SiS_Private *SiS_Pr)
1594{
1595 SiS_SetSegmentReg(SiS_Pr, 0);
1596}
1597
1598static void
1599SiS_SetSegmentRegOver(SiS_Private *SiS_Pr, USHORT value)
1600{
1601 USHORT temp = value >> 8;
1602
1603 temp &= 0x07;
1604 temp |= (temp << 4);
1605 SiS_SetReg(SiS_Pr->SiS_P3c4,0x1d,temp);
1606 SiS_SetSegmentReg(SiS_Pr, value);
1607}
1608
1609static void
1610SiS_ResetSegmentRegOver(SiS_Private *SiS_Pr)
1611{
1612 SiS_SetSegmentRegOver(SiS_Pr, 0);
1613}
1614
1615static void
1616SiS_ResetSegmentRegisters(SiS_Private *SiS_Pr,PSIS_HW_INFO HwInfo)
1617{
1618 if((IS_SIS65x) || (HwInfo->jChipType >= SIS_661)) {
1619 SiS_ResetSegmentReg(SiS_Pr);
1620 SiS_ResetSegmentRegOver(SiS_Pr);
1621 }
1622}
1623
1624/*********************************************/
1625/* HELPER: GetVBType */
1626/*********************************************/
1627
1628void
1629SiS_GetVBType(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
1630{
1631 USHORT flag=0, rev=0, nolcd=0, p4_0f, p4_25, p4_27;
1632
1633 SiS_Pr->SiS_VBType = 0;
1634
1635 if((SiS_Pr->SiS_IF_DEF_LVDS) || (SiS_Pr->SiS_IF_DEF_CONEX))
1636 return;
1637
1638 flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
1639
1640 if(flag > 3) return;
1641
1642 rev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01);
1643
1644 if(flag >= 2) {
1645 SiS_Pr->SiS_VBType = VB_SIS302B;
1646 } else if(flag == 1) {
1647 if(rev >= 0xC0) {
1648 SiS_Pr->SiS_VBType = VB_SIS301C;
1649 } else if(rev >= 0xB0) {
1650 SiS_Pr->SiS_VBType = VB_SIS301B;
1651 /* Check if 30xB DH version (no LCD support, use Panel Link instead) */
1652 nolcd = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x23);
1653 if(!(nolcd & 0x02)) SiS_Pr->SiS_VBType |= VB_NoLCD;
1654 } else {
1655 SiS_Pr->SiS_VBType = VB_SIS301;
1656 }
1657 }
1658 if(SiS_Pr->SiS_VBType & (VB_SIS301B | VB_SIS301C | VB_SIS302B)) {
1659 if(rev >= 0xE0) {
1660 flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x39);
1661 if(flag == 0xff) SiS_Pr->SiS_VBType = VB_SIS302LV;
1662 else SiS_Pr->SiS_VBType = VB_SIS301C; /* VB_SIS302ELV; */
1663 } else if(rev >= 0xD0) {
1664 SiS_Pr->SiS_VBType = VB_SIS301LV;
1665 }
1666 }
1667 if(SiS_Pr->SiS_VBType & (VB_301C | VB_301LV | VB_302LV | VB_302ELV)) {
1668 p4_0f = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x0f);
1669 p4_25 = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x25);
1670 p4_27 = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x27);
1671 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0x7f);
1672 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x25,0x08);
1673 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,0xfd);
1674 if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x08) {
1675 SiS_Pr->SiS_VBType |= VB_UMC;
1676 }
1677 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x27,p4_27);
1678 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x25,p4_25);
1679 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0f,p4_0f);
1680 }
1681}
1682
1683/*********************************************/
1684/* HELPER: Check RAM size */
1685/*********************************************/
1686
1687#ifdef LINUX_KERNEL
1688static BOOLEAN
1689SiS_CheckMemorySize(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
1690 USHORT ModeNo, USHORT ModeIdIndex)
1691{
1692 USHORT AdapterMemSize = HwInfo->ulVideoMemorySize / (1024*1024);
1693 USHORT memorysize,modeflag;
1694
1695 if(SiS_Pr->UseCustomMode) {
1696 modeflag = SiS_Pr->CModeFlag;
1697 } else {
1698 if(ModeNo <= 0x13) {
1699 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
1700 } else {
1701 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1702 }
1703 }
1704
1705 memorysize = modeflag & MemoryInfoFlag;
1706 memorysize >>= MemorySizeShift; /* Get required memory size */
1707 memorysize++;
1708
1709 if(AdapterMemSize < memorysize) return FALSE;
1710 return TRUE;
1711}
1712#endif
1713
1714/*********************************************/
1715/* HELPER: Get DRAM type */
1716/*********************************************/
1717
1718#ifdef SIS315H
1719static UCHAR
1720SiS_Get310DRAMType(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
1721{
1722 UCHAR data, temp;
1723
1724 if((*SiS_Pr->pSiS_SoftSetting) & SoftDRAMType) {
1725 data = (*SiS_Pr->pSiS_SoftSetting) & 0x03;
1726 } else {
1727 if(HwInfo->jChipType >= SIS_340) {
1728 /* TODO */
1729 data = 0;
1730 } if(HwInfo->jChipType >= SIS_661) {
1731 data = SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0x07;
1732 if(SiS_Pr->SiS_ROMNew) {
1733 data = ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0xc0) >> 6);
1734 }
1735 } else if(IS_SIS550650740) {
1736 data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x07;
1737 } else { /* 315, 330 */
1738 data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3a) & 0x03;
1739 if(HwInfo->jChipType == SIS_330) {
1740 if(data > 1) {
1741 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0x30;
1742 switch(temp) {
1743 case 0x00: data = 1; break;
1744 case 0x10: data = 3; break;
1745 case 0x20: data = 3; break;
1746 case 0x30: data = 2; break;
1747 }
1748 } else {
1749 data = 0;
1750 }
1751 }
1752 }
1753 }
1754
1755 return data;
1756}
1757
1758static USHORT
1759SiS_GetMCLK(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
1760{
1761 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
1762 USHORT index;
1763
1764 index = SiS_Get310DRAMType(SiS_Pr, HwInfo);
1765 if(HwInfo->jChipType >= SIS_661) {
1766 if(SiS_Pr->SiS_ROMNew) {
1767 return((USHORT)(SISGETROMW((0x90 + (index * 5) + 3))));
1768 }
1769 return(SiS_Pr->SiS_MCLKData_0[index].CLOCK);
1770 } else if(index >= 4) {
1771 index -= 4;
1772 return(SiS_Pr->SiS_MCLKData_1[index].CLOCK);
1773 } else {
1774 return(SiS_Pr->SiS_MCLKData_0[index].CLOCK);
1775 }
1776}
1777#endif
1778
1779/*********************************************/
1780/* HELPER: ClearBuffer */
1781/*********************************************/
1782
1783#ifdef LINUX_KERNEL
1784static void
1785SiS_ClearBuffer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
1786{
1787 UCHAR SISIOMEMTYPE *VideoMemoryAddress = HwInfo->pjVideoMemoryAddress;
1788 ULONG AdapterMemorySize = HwInfo->ulVideoMemorySize;
1789 USHORT SISIOMEMTYPE *pBuffer;
1790 int i;
1791
1792 if(SiS_Pr->SiS_ModeType >= ModeEGA) {
1793 if(ModeNo > 0x13) {
1794 SiS_SetMemory(VideoMemoryAddress, AdapterMemorySize, 0);
1795 } else {
1796 pBuffer = (USHORT SISIOMEMTYPE *)VideoMemoryAddress;
1797 for(i=0; i<0x4000; i++) writew(0x0000, &pBuffer[i]);
1798 }
1799 } else {
1800 if(SiS_Pr->SiS_ModeType < ModeCGA) {
1801 pBuffer = (USHORT SISIOMEMTYPE *)VideoMemoryAddress;
1802 for(i=0; i<0x4000; i++) writew(0x0720, &pBuffer[i]);
1803 } else {
1804 SiS_SetMemory(VideoMemoryAddress, 0x8000, 0);
1805 }
1806 }
1807}
1808#endif
1809
1810/*********************************************/
1811/* HELPER: SearchModeID */
1812/*********************************************/
1813
1814BOOLEAN
1815SiS_SearchModeID(SiS_Private *SiS_Pr, USHORT *ModeNo, USHORT *ModeIdIndex)
1816{
1817 UCHAR VGAINFO = SiS_Pr->SiS_VGAINFO;
1818
1819 if(*ModeNo <= 0x13) {
1820
1821 if((*ModeNo) <= 0x05) (*ModeNo) |= 0x01;
1822
1823 for(*ModeIdIndex = 0; ;(*ModeIdIndex)++) {
1824 if(SiS_Pr->SiS_SModeIDTable[*ModeIdIndex].St_ModeID == (*ModeNo)) break;
1825 if(SiS_Pr->SiS_SModeIDTable[*ModeIdIndex].St_ModeID == 0xFF) return FALSE;
1826 }
1827
1828 if(*ModeNo == 0x07) {
1829 if(VGAINFO & 0x10) (*ModeIdIndex)++; /* 400 lines */
1830 /* else 350 lines */
1831 }
1832 if(*ModeNo <= 0x03) {
1833 if(!(VGAINFO & 0x80)) (*ModeIdIndex)++;
1834 if(VGAINFO & 0x10) (*ModeIdIndex)++; /* 400 lines */
1835 /* else 350 lines */
1836 }
1837 /* else 200 lines */
1838
1839 } else {
1840
1841 for(*ModeIdIndex = 0; ;(*ModeIdIndex)++) {
1842 if(SiS_Pr->SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == (*ModeNo)) break;
1843 if(SiS_Pr->SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF) return FALSE;
1844 }
1845
1846 }
1847 return TRUE;
1848}
1849
1850/*********************************************/
1851/* HELPER: GetModePtr */
1852/*********************************************/
1853
1854UCHAR
1855SiS_GetModePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex)
1856{
1857 UCHAR index;
1858
1859 if(ModeNo <= 0x13) {
1860 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_StTableIndex;
1861 } else {
1862 if(SiS_Pr->SiS_ModeType <= ModeEGA) index = 0x1B;
1863 else index = 0x0F;
1864 }
1865 return index;
1866}
1867
1868/*********************************************/
1869/* HELPER: LowModeTests */
1870/*********************************************/
1871
1872static BOOLEAN
1873SiS_DoLowModeTest(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_INFO HwInfo)
1874{
1875 USHORT temp,temp1,temp2;
1876
1877 if((ModeNo != 0x03) && (ModeNo != 0x10) && (ModeNo != 0x12))
1878 return(TRUE);
1879 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x11);
1880 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x11,0x80);
1881 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x00);
1882 SiS_SetReg(SiS_Pr->SiS_P3d4,0x00,0x55);
1883 temp2 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x00);
1884 SiS_SetReg(SiS_Pr->SiS_P3d4,0x00,temp1);
1885 SiS_SetReg(SiS_Pr->SiS_P3d4,0x11,temp);
1886 if((HwInfo->jChipType >= SIS_315H) ||
1887 (HwInfo->jChipType == SIS_300)) {
1888 if(temp2 == 0x55) return(FALSE);
1889 else return(TRUE);
1890 } else {
1891 if(temp2 != 0x55) return(TRUE);
1892 else {
1893 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01);
1894 return(FALSE);
1895 }
1896 }
1897}
1898
1899static void
1900SiS_SetLowModeTest(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_INFO HwInfo)
1901{
1902 if(SiS_DoLowModeTest(SiS_Pr, ModeNo, HwInfo)) {
1903 SiS_Pr->SiS_SetFlag |= LowModeTests;
1904 }
1905}
1906
1907/*********************************************/
1908/* HELPER: ENABLE CRT1 */
1909/*********************************************/
1910
1911static void
1912SiS_SetupCR5x(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
1913{
1914 if(IS_SIS650) {
1915 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
1916 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
1917 if(IS_SIS651) SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x51,0x20);
1918 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
1919 }
1920 } else if(IS_SIS661741660760) {
1921 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x61,0xf7);
1922 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
1923 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
1924 if(!SiS_Pr->SiS_ROMNew) {
1925 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x3a,0xef);
1926 }
1927 }
1928}
1929
1930static void
1931SiS_HandleCRT1(SiS_Private *SiS_Pr)
1932{
1933 /* Enable CRT1 gating */
1934 SiS_SetRegAND(SiS_Pr->SiS_P3d4,SiS_Pr->SiS_MyCR63,0xbf);
1935#if 0
1936 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x15) & 0x01)) {
1937 if((SiS_GetReg(SiS_Pr->SiS_P3c4,0x15) & 0x0a) ||
1938 (SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x01)) {
1939 SiS_SetRegOR(SiS_Pr->SiS_P3d4,SiS_Pr->SiS_MyCR63,0x40);
1940 }
1941 }
1942#endif
1943}
1944
1945/*********************************************/
1946/* HELPER: GetColorDepth */
1947/*********************************************/
1948
1949USHORT
1950SiS_GetColorDepth(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex)
1951{
1952 USHORT ColorDepth[6] = { 1, 2, 4, 4, 6, 8};
1953 SHORT index;
1954 USHORT modeflag;
1955
1956 /* Do NOT check UseCustomMode, will skrew up FIFO */
1957 if(ModeNo == 0xfe) {
1958 modeflag = SiS_Pr->CModeFlag;
1959 } else {
1960 if(ModeNo <= 0x13)
1961 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
1962 else
1963 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1964 }
1965
1966 index = (modeflag & ModeTypeMask) - ModeEGA;
1967 if(index < 0) index = 0;
1968 return(ColorDepth[index]);
1969}
1970
1971/*********************************************/
1972/* HELPER: GetOffset */
1973/*********************************************/
1974
1975USHORT
1976SiS_GetOffset(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
1977 USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo)
1978{
1979 USHORT xres, temp, colordepth, infoflag;
1980
1981 if(SiS_Pr->UseCustomMode) {
1982 infoflag = SiS_Pr->CInfoFlag;
1983 xres = SiS_Pr->CHDisplay;
1984 } else {
1985 infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
1986 xres = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes;
1987 }
1988
1989 colordepth = SiS_GetColorDepth(SiS_Pr,ModeNo,ModeIdIndex);
1990
1991 temp = xres / 16;
1992 if(infoflag & InterlaceMode) temp <<= 1;
1993 temp *= colordepth;
1994 if(xres % 16) {
1995 colordepth >>= 1;
1996 temp += colordepth;
1997 }
1998
1999 return(temp);
2000}
2001
2002/*********************************************/
2003/* SEQ */
2004/*********************************************/
2005
2006static void
2007SiS_SetSeqRegs(SiS_Private *SiS_Pr, USHORT StandTableIndex, PSIS_HW_INFO HwInfo)
2008{
2009 UCHAR SRdata;
2010 USHORT i;
2011
2012 SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x03); /* Set SR0 */
2013
2014 SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[0];
2015
2016 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
2017 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
2018 SRdata |= 0x01;
2019 }
2020 if(HwInfo->jChipType >= SIS_661) {
2021 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
2022 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2023 SRdata |= 0x01; /* 8 dot clock */
2024 }
2025 }
2026 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2027 if(SiS_Pr->SiS_VBType & VB_NoLCD) {
2028 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2029 SRdata |= 0x01; /* 8 dot clock */
2030 }
2031 }
2032 }
2033 }
2034
2035 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2036 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
2037 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2038 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2039 SRdata |= 0x01; /* 8 dot clock */
2040 }
2041 }
2042 }
2043 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2044 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2045 SRdata |= 0x01; /* 8 dot clock */
2046 }
2047 }
2048 }
2049
2050 SRdata |= 0x20; /* screen off */
2051
2052 SiS_SetReg(SiS_Pr->SiS_P3c4,0x01,SRdata);
2053
2054 for(i = 2; i <= 4; i++) {
2055 SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[i-1];
2056 SiS_SetReg(SiS_Pr->SiS_P3c4,i,SRdata);
2057 }
2058}
2059
2060/*********************************************/
2061/* MISC */
2062/*********************************************/
2063
2064static void
2065SiS_SetMiscRegs(SiS_Private *SiS_Pr, USHORT StandTableIndex, PSIS_HW_INFO HwInfo)
2066{
2067 UCHAR Miscdata;
2068
2069 Miscdata = SiS_Pr->SiS_StandTable[StandTableIndex].MISC;
2070
2071 if(HwInfo->jChipType < SIS_661) {
2072 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
2073 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
2074 Miscdata |= 0x0C;
2075 }
2076 }
2077 }
2078
2079 SiS_SetRegByte(SiS_Pr->SiS_P3c2,Miscdata);
2080}
2081
2082/*********************************************/
2083/* CRTC */
2084/*********************************************/
2085
2086static void
2087SiS_SetCRTCRegs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
2088 USHORT StandTableIndex)
2089{
2090 UCHAR CRTCdata;
2091 USHORT i;
2092
2093 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f); /* Unlock CRTC */
2094
2095 for(i = 0; i <= 0x18; i++) {
2096 CRTCdata = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[i];
2097 SiS_SetReg(SiS_Pr->SiS_P3d4,i,CRTCdata); /* Set CRTC(3d4) */
2098 }
2099 if(HwInfo->jChipType >= SIS_661) {
2100 SiS_SetupCR5x(SiS_Pr, HwInfo);
2101 for(i = 0x13; i <= 0x14; i++) {
2102 CRTCdata = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[i];
2103 SiS_SetReg(SiS_Pr->SiS_P3d4,i,CRTCdata);
2104 }
2105 } else if( ( (HwInfo->jChipType == SIS_630) ||
2106 (HwInfo->jChipType == SIS_730) ) &&
2107 (HwInfo->jChipRevision >= 0x30) ) { /* for 630S0 */
2108 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2109 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
2110 SiS_SetReg(SiS_Pr->SiS_P3d4,0x18,0xFE);
2111 }
2112 }
2113 }
2114}
2115
2116/*********************************************/
2117/* ATT */
2118/*********************************************/
2119
2120static void
2121SiS_SetATTRegs(SiS_Private *SiS_Pr, USHORT StandTableIndex,
2122 PSIS_HW_INFO HwInfo)
2123{
2124 UCHAR ARdata;
2125 USHORT i;
2126
2127 for(i = 0; i <= 0x13; i++) {
2128 ARdata = SiS_Pr->SiS_StandTable[StandTableIndex].ATTR[i];
2129#if 0
2130 if((i <= 0x0f) || (i == 0x11)) {
2131 if(ds:489 & 0x08) {
2132 continue;
2133 }
2134 }
2135#endif
2136 if(i == 0x13) {
2137 /* Pixel shift. If screen on LCD or TV is shifted left or right,
2138 * this might be the cause.
2139 */
2140 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
2141 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) ARdata=0;
2142 }
2143 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2144 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
2145 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2146 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata=0;
2147 }
2148 }
2149 }
2150 if(HwInfo->jChipType >= SIS_661) {
2151 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD)) {
2152 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata=0;
2153 }
2154 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2155 if(HwInfo->jChipType >= SIS_315H) {
2156 if(IS_SIS550650740660) {
2157 /* 315, 330 don't do this */
2158 if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
2159 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata=0;
2160 } else {
2161 ARdata = 0;
2162 }
2163 }
2164 } else {
2165 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata=0;
2166 }
2167 }
2168 }
2169 SiS_GetRegByte(SiS_Pr->SiS_P3da); /* reset 3da */
2170 SiS_SetRegByte(SiS_Pr->SiS_P3c0,i); /* set index */
2171 SiS_SetRegByte(SiS_Pr->SiS_P3c0,ARdata); /* set data */
2172 }
2173 SiS_GetRegByte(SiS_Pr->SiS_P3da); /* reset 3da */
2174 SiS_SetRegByte(SiS_Pr->SiS_P3c0,0x14); /* set index */
2175 SiS_SetRegByte(SiS_Pr->SiS_P3c0,0x00); /* set data */
2176
2177 SiS_GetRegByte(SiS_Pr->SiS_P3da);
2178 SiS_SetRegByte(SiS_Pr->SiS_P3c0,0x20); /* Enable Attribute */
2179 SiS_GetRegByte(SiS_Pr->SiS_P3da);
2180}
2181
2182/*********************************************/
2183/* GRC */
2184/*********************************************/
2185
2186static void
2187SiS_SetGRCRegs(SiS_Private *SiS_Pr, USHORT StandTableIndex)
2188{
2189 UCHAR GRdata;
2190 USHORT i;
2191
2192 for(i = 0; i <= 0x08; i++) {
2193 GRdata = SiS_Pr->SiS_StandTable[StandTableIndex].GRC[i];
2194 SiS_SetReg(SiS_Pr->SiS_P3ce,i,GRdata);
2195 }
2196
2197 if(SiS_Pr->SiS_ModeType > ModeVGA) {
2198 /* 256 color disable */
2199 SiS_SetRegAND(SiS_Pr->SiS_P3ce,0x05,0xBF);
2200 }
2201}
2202
2203/*********************************************/
2204/* CLEAR EXTENDED REGISTERS */
2205/*********************************************/
2206
2207static void
2208SiS_ClearExt1Regs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
2209{
2210 USHORT i;
2211
2212 for(i = 0x0A; i <= 0x0E; i++) {
2213 SiS_SetReg(SiS_Pr->SiS_P3c4,i,0x00);
2214 }
2215
2216 if(HwInfo->jChipType >= SIS_315H) {
2217 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x37,0xFE);
2218 if(ModeNo <= 0x13) {
2219 if(ModeNo == 0x06 || ModeNo >= 0x0e) {
2220 SiS_SetReg(SiS_Pr->SiS_P3c4,0x0e,0x20);
2221 }
2222 }
2223 }
2224}
2225
2226/*********************************************/
2227/* RESET VCLK */
2228/*********************************************/
2229
2230static void
2231SiS_ResetCRT1VCLK(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
2232{
2233 if(HwInfo->jChipType >= SIS_315H) {
2234 if(HwInfo->jChipType < SIS_661) {
2235 if(SiS_Pr->SiS_IF_DEF_LVDS == 0) return;
2236 }
2237 } else {
2238 if((SiS_Pr->SiS_IF_DEF_LVDS == 0) &&
2239 (!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) ) {
2240 return;
2241 }
2242 }
2243
2244 if(HwInfo->jChipType >= SIS_315H) {
2245 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x31,0xCF,0x20);
2246 } else {
2247 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x20);
2248 }
2249 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VCLKData[1].SR2B);
2250 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VCLKData[1].SR2C);
2251 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x80);
2252 if(HwInfo->jChipType >= SIS_315H) {
2253 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x31,0xcf,0x10);
2254 } else {
2255 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x10);
2256 }
2257 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VCLKData[0].SR2B);
2258 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VCLKData[0].SR2C);
2259 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x80);
2260}
2261
2262/*********************************************/
2263/* SYNC */
2264/*********************************************/
2265
2266static void
2267SiS_SetCRT1Sync(SiS_Private *SiS_Pr, USHORT RefreshRateTableIndex)
2268{
2269 USHORT sync;
2270
2271 if(SiS_Pr->UseCustomMode) {
2272 sync = SiS_Pr->CInfoFlag >> 8;
2273 } else {
2274 sync = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag >> 8;
2275 }
2276
2277 sync &= 0xC0;
2278 sync |= 0x2f;
2279 SiS_SetRegByte(SiS_Pr->SiS_P3c2,sync);
2280}
2281
2282/*********************************************/
2283/* CRTC/2 */
2284/*********************************************/
2285
2286static void
2287SiS_SetCRT1CRTC(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2288 USHORT RefreshRateTableIndex,
2289 PSIS_HW_INFO HwInfo)
2290{
2291 UCHAR index;
2292 USHORT temp,i,j,modeflag;
2293
2294 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f); /* unlock cr0-7 */
2295
2296 if(SiS_Pr->UseCustomMode) {
2297
2298 modeflag = SiS_Pr->CModeFlag;
2299
2300 for(i=0,j=0;i<=7;i++,j++) {
2301 SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
2302 }
2303 for(j=0x10;i<=10;i++,j++) {
2304 SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
2305 }
2306 for(j=0x15;i<=12;i++,j++) {
2307 SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
2308 }
2309 for(j=0x0A;i<=15;i++,j++) {
2310 SiS_SetReg(SiS_Pr->SiS_P3c4,j,SiS_Pr->CCRT1CRTC[i]);
2311 }
2312
2313 temp = SiS_Pr->CCRT1CRTC[16] & 0xE0;
2314 SiS_SetReg(SiS_Pr->SiS_P3c4,0x0E,temp);
2315
2316 temp = (SiS_Pr->CCRT1CRTC[16] & 0x01) << 5;
2317 if(modeflag & DoubleScanMode) temp |= 0x80;
2318 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0x5F,temp);
2319
2320 } else {
2321
2322 if(ModeNo <= 0x13) {
2323 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2324 } else {
2325 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2326 }
2327
2328 index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
2329
2330 for(i=0,j=0;i<=7;i++,j++) {
2331 SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->SiS_CRT1Table[index].CR[i]);
2332 }
2333 for(j=0x10;i<=10;i++,j++) {
2334 SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->SiS_CRT1Table[index].CR[i]);
2335 }
2336 for(j=0x15;i<=12;i++,j++) {
2337 SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->SiS_CRT1Table[index].CR[i]);
2338 }
2339 for(j=0x0A;i<=15;i++,j++) {
2340 SiS_SetReg(SiS_Pr->SiS_P3c4,j,SiS_Pr->SiS_CRT1Table[index].CR[i]);
2341 }
2342
2343 temp = SiS_Pr->SiS_CRT1Table[index].CR[16] & 0xE0;
2344 SiS_SetReg(SiS_Pr->SiS_P3c4,0x0E,temp);
2345
2346 temp = ((SiS_Pr->SiS_CRT1Table[index].CR[16]) & 0x01) << 5;
2347 if(modeflag & DoubleScanMode) temp |= 0x80;
2348 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0x5F,temp);
2349
2350 }
2351
2352 if(SiS_Pr->SiS_ModeType > ModeVGA) SiS_SetReg(SiS_Pr->SiS_P3d4,0x14,0x4F);
2353}
2354
2355/*********************************************/
2356/* OFFSET & PITCH */
2357/*********************************************/
2358/* (partly overruled by SetPitch() in XF86) */
2359/*********************************************/
2360
2361static void
2362SiS_SetCRT1Offset(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2363 USHORT RefreshRateTableIndex,
2364 PSIS_HW_INFO HwInfo)
2365{
2366 USHORT temp, DisplayUnit, infoflag;
2367
2368 if(SiS_Pr->UseCustomMode) {
2369 infoflag = SiS_Pr->CInfoFlag;
2370 } else {
2371 infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
2372 }
2373
2374 DisplayUnit = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,
2375 RefreshRateTableIndex,HwInfo);
2376
2377 temp = (DisplayUnit >> 8) & 0x0f;
2378 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0xF0,temp);
2379
2380 temp = DisplayUnit & 0xFF;
2381 SiS_SetReg(SiS_Pr->SiS_P3d4,0x13,temp);
2382
2383 if(infoflag & InterlaceMode) DisplayUnit >>= 1;
2384
2385 DisplayUnit <<= 5;
2386 temp = (DisplayUnit & 0xff00) >> 8;
2387 if(DisplayUnit & 0xff) temp++;
2388 temp++;
2389 SiS_SetReg(SiS_Pr->SiS_P3c4,0x10,temp);
2390}
2391
2392/*********************************************/
2393/* VCLK */
2394/*********************************************/
2395
2396static void
2397SiS_SetCRT1VCLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2398 PSIS_HW_INFO HwInfo, USHORT RefreshRateTableIndex)
2399{
2400 USHORT index=0, clka, clkb;
2401
2402 if(SiS_Pr->UseCustomMode) {
2403 clka = SiS_Pr->CSR2B;
2404 clkb = SiS_Pr->CSR2C;
2405 } else {
2406 index = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
2407 if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2408 clka = SiS_Pr->SiS_VBVCLKData[index].Part4_A;
2409 clkb = SiS_Pr->SiS_VBVCLKData[index].Part4_B;
2410 } else {
2411 clka = SiS_Pr->SiS_VCLKData[index].SR2B;
2412 clkb = SiS_Pr->SiS_VCLKData[index].SR2C;
2413 }
2414 }
2415
2416 if(HwInfo->jChipType >= SIS_315H) {
2417 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x31,0xCF);
2418 } else {
2419 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x00);
2420 }
2421
2422 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2B,clka);
2423 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2C,clkb);
2424
2425 if(HwInfo->jChipType >= SIS_315H) {
2426 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x01);
2427 } else {
2428 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x80);
2429 }
2430}
2431
2432/*********************************************/
2433/* FIFO */
2434/*********************************************/
2435
2436#ifdef SIS300
2437static USHORT
2438SiS_DoCalcDelay(SiS_Private *SiS_Pr, USHORT MCLK, USHORT VCLK, USHORT colordepth, USHORT key)
2439{
2440 const UCHAR ThLowA[] = { 61, 3,52, 5,68, 7,100,11,
2441 43, 3,42, 5,54, 7, 78,11,
2442 34, 3,37, 5,47, 7, 67,11 };
2443
2444 const UCHAR ThLowB[] = { 81, 4,72, 6,88, 8,120,12,
2445 55, 4,54, 6,66, 8, 90,12,
2446 42, 4,45, 6,55, 8, 75,12 };
2447
2448 const UCHAR ThTiming[] = { 1, 2, 2, 3, 0, 1, 1, 2 };
2449
2450 USHORT tempah, tempal, tempcl, tempbx, temp;
2451 ULONG longtemp;
2452
2453 tempah = SiS_GetReg(SiS_Pr->SiS_P3c4,0x18);
2454 tempah &= 0x62;
2455 tempah >>= 1;
2456 tempal = tempah;
2457 tempah >>= 3;
2458 tempal |= tempah;
2459 tempal &= 0x07;
2460 tempcl = ThTiming[tempal];
2461 tempbx = SiS_GetReg(SiS_Pr->SiS_P3c4,0x16);
2462 tempbx >>= 6;
2463 tempah = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
2464 tempah >>= 4;
2465 tempah &= 0x0c;
2466 tempbx |= tempah;
2467 tempbx <<= 1;
2468 if(key == 0) {
2469 tempal = ThLowA[tempbx + 1];
2470 tempal *= tempcl;
2471 tempal += ThLowA[tempbx];
2472 } else {
2473 tempal = ThLowB[tempbx + 1];
2474 tempal *= tempcl;
2475 tempal += ThLowB[tempbx];
2476 }
2477 longtemp = tempal * VCLK * colordepth;
2478 temp = longtemp % (MCLK * 16);
2479 longtemp /= (MCLK * 16);
2480 if(temp) longtemp++;
2481 return((USHORT)longtemp);
2482}
2483
2484static USHORT
2485SiS_CalcDelay(SiS_Private *SiS_Pr, USHORT VCLK, USHORT colordepth, USHORT MCLK)
2486{
2487 USHORT tempax, tempbx;
2488
2489 tempbx = SiS_DoCalcDelay(SiS_Pr, MCLK, VCLK, colordepth, 0);
2490 tempax = SiS_DoCalcDelay(SiS_Pr, MCLK, VCLK, colordepth, 1);
2491 if(tempax < 4) tempax = 4;
2492 tempax -= 4;
2493 if(tempbx < tempax) tempbx = tempax;
2494 return(tempbx);
2495}
2496
2497static void
2498SiS_SetCRT1FIFO_300(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_INFO HwInfo,
2499 USHORT RefreshRateTableIndex)
2500{
2501 USHORT ThresholdLow = 0;
2502 USHORT index, VCLK, MCLK, colorth=0;
2503 USHORT tempah, temp;
2504
2505 if(ModeNo > 0x13) {
2506
2507 if(SiS_Pr->UseCustomMode) {
2508 VCLK = SiS_Pr->CSRClock;
2509 } else {
2510 index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
2511 index &= 0x3F;
2512 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; /* Get VCLK */
2513 }
2514
2515 switch (SiS_Pr->SiS_ModeType - ModeEGA) { /* Get half colordepth */
2516 case 0 : colorth = 1; break;
2517 case 1 : colorth = 1; break;
2518 case 2 : colorth = 2; break;
2519 case 3 : colorth = 2; break;
2520 case 4 : colorth = 3; break;
2521 case 5 : colorth = 4; break;
2522 }
2523
2524 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A);
2525 index &= 0x07;
2526 MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK; /* Get MCLK */
2527
2528 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
2529 tempah &= 0xc3;
2530 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x16,0x3c,tempah);
2531
2532 do {
2533 ThresholdLow = SiS_CalcDelay(SiS_Pr, VCLK, colorth, MCLK);
2534 ThresholdLow++;
2535 if(ThresholdLow < 0x13) break;
2536 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x16,0xfc);
2537 ThresholdLow = 0x13;
2538 tempah = SiS_GetReg(SiS_Pr->SiS_P3c4,0x16);
2539 tempah >>= 6;
2540 if(!(tempah)) break;
2541 tempah--;
2542 tempah <<= 6;
2543 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x16,0x3f,tempah);
2544 } while(0);
2545
2546 } else ThresholdLow = 2;
2547
2548 /* Write CRT/CPU threshold low, CRT/Engine threshold high */
2549 temp = (ThresholdLow << 4) | 0x0f;
2550 SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,temp);
2551
2552 temp = (ThresholdLow & 0x10) << 1;
2553 if(ModeNo > 0x13) temp |= 0x40;
2554 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0f,0x9f,temp);
2555
2556 /* What is this? */
2557 SiS_SetReg(SiS_Pr->SiS_P3c4,0x3B,0x09);
2558
2559 /* Write CRT/CPU threshold high */
2560 temp = ThresholdLow + 3;
2561 if(temp > 0x0f) temp = 0x0f;
2562 SiS_SetReg(SiS_Pr->SiS_P3c4,0x09,temp);
2563}
2564
2565static USHORT
2566SiS_CalcDelay2(SiS_Private *SiS_Pr, UCHAR key, PSIS_HW_INFO HwInfo)
2567{
2568 USHORT data,index;
2569 const UCHAR LatencyFactor[] = {
2570 97, 88, 86, 79, 77, 00, /*; 64 bit BQ=2 */
2571 00, 87, 85, 78, 76, 54, /*; 64 bit BQ=1 */
2572 97, 88, 86, 79, 77, 00, /*; 128 bit BQ=2 */
2573 00, 79, 77, 70, 68, 48, /*; 128 bit BQ=1 */
2574 80, 72, 69, 63, 61, 00, /*; 64 bit BQ=2 */
2575 00, 70, 68, 61, 59, 37, /*; 64 bit BQ=1 */
2576 86, 77, 75, 68, 66, 00, /*; 128 bit BQ=2 */
2577 00, 68, 66, 59, 57, 37 /*; 128 bit BQ=1 */
2578 };
2579 const UCHAR LatencyFactor730[] = {
2580 69, 63, 61,
2581 86, 79, 77,
2582 103, 96, 94,
2583 120,113,111,
2584 137,130,128, /* --- Table ends with this entry, data below */
2585 137,130,128, /* to avoid using illegal values */
2586 137,130,128,
2587 137,130,128,
2588 137,130,128,
2589 137,130,128,
2590 137,130,128,
2591 137,130,128,
2592 137,130,128,
2593 137,130,128,
2594 137,130,128,
2595 137,130,128,
2596 };
2597
2598 if(HwInfo->jChipType == SIS_730) {
2599 index = ((key & 0x0f) * 3) + ((key & 0xC0) >> 6);
2600 data = LatencyFactor730[index];
2601 } else {
2602 index = (key & 0xE0) >> 5;
2603 if(key & 0x10) index +=6;
2604 if(!(key & 0x01)) index += 24;
2605 data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
2606 if(data & 0x0080) index += 12;
2607 data = LatencyFactor[index];
2608 }
2609 return(data);
2610}
2611
2612static void
2613SiS_SetCRT1FIFO_630(SiS_Private *SiS_Pr, USHORT ModeNo,
2614 PSIS_HW_INFO HwInfo,
2615 USHORT RefreshRateTableIndex)
2616{
2617 USHORT i,index,data,VCLK,MCLK,colorth=0;
2618 ULONG B,eax,bl,data2;
2619 USHORT ThresholdLow=0;
2620 UCHAR FQBQData[]= {
2621 0x01,0x21,0x41,0x61,0x81,
2622 0x31,0x51,0x71,0x91,0xb1,
2623 0x00,0x20,0x40,0x60,0x80,
2624 0x30,0x50,0x70,0x90,0xb0,
2625 0xFF
2626 };
2627 UCHAR FQBQData730[]= {
2628 0x34,0x74,0xb4,
2629 0x23,0x63,0xa3,
2630 0x12,0x52,0x92,
2631 0x01,0x41,0x81,
2632 0x00,0x40,0x80,
2633 0xff
2634 };
2635
2636 i=0;
2637 if(ModeNo > 0x13) {
2638 if(SiS_Pr->UseCustomMode) {
2639 VCLK = SiS_Pr->CSRClock;
2640 } else {
2641 index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
2642 index &= 0x3F;
2643 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; /* Get VCLK */
2644 }
2645
2646 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A);
2647 index &= 0x07;
2648 MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK; /* Get MCLK */
2649
2650 data2 = SiS_Pr->SiS_ModeType - ModeEGA; /* Get half colordepth */
2651 switch (data2) {
2652 case 0 : colorth = 1; break;
2653 case 1 : colorth = 1; break;
2654 case 2 : colorth = 2; break;
2655 case 3 : colorth = 2; break;
2656 case 4 : colorth = 3; break;
2657 case 5 : colorth = 4; break;
2658 }
2659
2660 if(HwInfo->jChipType == SIS_730) {
2661
2662 do {
2663 B = SiS_CalcDelay2(SiS_Pr, FQBQData730[i], HwInfo) * VCLK * colorth;
2664 bl = B / (MCLK * 16);
2665
2666 if(B == bl * 16 * MCLK) {
2667 bl = bl + 1;
2668 } else {
2669 bl = bl + 2;
2670 }
2671
2672 if(bl > 0x13) {
2673 if(FQBQData730[i+1] == 0xFF) {
2674 ThresholdLow = 0x13;
2675 break;
2676 }
2677 i++;
2678 } else {
2679 ThresholdLow = bl;
2680 break;
2681 }
2682 } while(FQBQData730[i] != 0xFF);
2683
2684 } else {
2685
2686 do {
2687 B = SiS_CalcDelay2(SiS_Pr, FQBQData[i], HwInfo) * VCLK * colorth;
2688 bl = B / (MCLK * 16);
2689
2690 if(B == bl * 16 * MCLK) {
2691 bl = bl + 1;
2692 } else {
2693 bl = bl + 2;
2694 }
2695
2696 if(bl > 0x13) {
2697 if(FQBQData[i+1] == 0xFF) {
2698 ThresholdLow = 0x13;
2699 break;
2700 }
2701 i++;
2702 } else {
2703 ThresholdLow = bl;
2704 break;
2705 }
2706 } while(FQBQData[i] != 0xFF);
2707 }
2708 }
2709 else {
2710 if(HwInfo->jChipType == SIS_730) {
2711 } else {
2712 i = 9;
2713 }
2714 ThresholdLow = 0x02;
2715 }
2716
2717 /* Write foreground and background queue */
2718 if(HwInfo->jChipType == SIS_730) {
2719
2720 data2 = FQBQData730[i];
2721 data2 = (data2 & 0xC0) >> 5;
2722 data2 <<= 8;
2723
2724#ifdef LINUX_KERNEL
2725 SiS_SetRegLong(0xcf8,0x80000050);
2726 eax = SiS_GetRegLong(0xcfc);
2727 eax &= 0xfffff9ff;
2728 eax |= data2;
2729 SiS_SetRegLong(0xcfc,eax);
2730#else
2731 /* We use pci functions X offers. We use pcitag 0, because
2732 * we want to read/write to the host bridge (which is always
2733 * 00:00.0 on 630, 730 and 540), not the VGA device.
2734 */
2735 eax = pciReadLong(0x00000000, 0x50);
2736 eax &= 0xfffff9ff;
2737 eax |= data2;
2738 pciWriteLong(0x00000000, 0x50, eax);
2739#endif
2740
2741 /* Write GUI grant timer (PCI config 0xA3) */
2742 data2 = FQBQData730[i] << 8;
2743 data2 = (data2 & 0x0f00) | ((data2 & 0x3000) >> 8);
2744 data2 <<= 20;
2745
2746#ifdef LINUX_KERNEL
2747 SiS_SetRegLong(0xcf8,0x800000A0);
2748 eax = SiS_GetRegLong(0xcfc);
2749 eax &= 0x00ffffff;
2750 eax |= data2;
2751 SiS_SetRegLong(0xcfc,eax);
2752#else
2753 eax = pciReadLong(0x00000000, 0xA0);
2754 eax &= 0x00ffffff;
2755 eax |= data2;
2756 pciWriteLong(0x00000000, 0xA0, eax);
2757#endif
2758
2759 } else {
2760
2761 data2 = FQBQData[i];
2762 data2 = (data2 & 0xf0) >> 4;
2763 data2 <<= 24;
2764
2765#ifdef LINUX_KERNEL
2766 SiS_SetRegLong(0xcf8,0x80000050);
2767 eax = SiS_GetRegLong(0xcfc);
2768 eax &= 0xf0ffffff;
2769 eax |= data2;
2770 SiS_SetRegLong(0xcfc,eax);
2771#else
2772 eax = pciReadLong(0x00000000, 0x50);
2773 eax &= 0xf0ffffff;
2774 eax |= data2;
2775 pciWriteLong(0x00000000, 0x50, eax);
2776#endif
2777
2778 /* Write GUI grant timer (PCI config 0xA3) */
2779 data2 = FQBQData[i];
2780 data2 &= 0x0f;
2781 data2 <<= 24;
2782
2783#ifdef LINUX_KERNEL
2784 SiS_SetRegLong(0xcf8,0x800000A0);
2785 eax = SiS_GetRegLong(0xcfc);
2786 eax &= 0xf0ffffff;
2787 eax |= data2;
2788 SiS_SetRegLong(0xcfc,eax);
2789#else
2790 eax = pciReadLong(0x00000000, 0xA0);
2791 eax &= 0xf0ffffff;
2792 eax |= data2;
2793 pciWriteLong(0x00000000, 0xA0, eax);
2794#endif
2795
2796 }
2797
2798 /* Write CRT/CPU threshold low, CRT/Engine threshold high */
2799 data = ((ThresholdLow & 0x0f) << 4) | 0x0f;
2800 SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,data);
2801
2802 data = (ThresholdLow & 0x10) << 1;
2803 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xDF,data);
2804
2805 /* What is this? */
2806 SiS_SetReg(SiS_Pr->SiS_P3c4,0x3B,0x09);
2807
2808 /* Write CRT/CPU threshold high (gap = 3) */
2809 data = ThresholdLow + 3;
2810 if(data > 0x0f) data = 0x0f;
2811 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x09,0x80,data);
2812}
2813#endif
2814
2815#ifdef SIS315H
2816static void
2817SiS_SetCRT1FIFO_310(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2818 PSIS_HW_INFO HwInfo)
2819{
2820 USHORT modeflag;
2821
2822 /* disable auto-threshold */
2823 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x3D,0xFE);
2824
2825 if(SiS_Pr->UseCustomMode) {
2826 modeflag = SiS_Pr->CModeFlag;
2827 } else {
2828 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2829 }
2830
2831 SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0xAE);
2832 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x09,0xF0);
2833 if(ModeNo > 0x13) {
2834 if(HwInfo->jChipType >= SIS_661) {
2835 if(!(modeflag & HalfDCLK)) {
2836 SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0x34);
2837 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x3D,0x01);
2838 }
2839 } else {
2840 if((!(modeflag & DoubleScanMode)) || (!(modeflag & HalfDCLK))) {
2841 SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0x34);
2842 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x3D,0x01);
2843 }
2844 }
2845 }
2846}
2847#endif
2848
2849/*********************************************/
2850/* MODE REGISTERS */
2851/*********************************************/
2852
2853static void
2854SiS_SetVCLKState(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
2855 USHORT ModeNo, USHORT RefreshRateTableIndex,
2856 USHORT ModeIdIndex)
2857{
2858 USHORT data=0, VCLK=0, index=0;
2859
2860 if(ModeNo > 0x13) {
2861 if(SiS_Pr->UseCustomMode) {
2862 VCLK = SiS_Pr->CSRClock;
2863 } else {
2864 index = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,
2865 RefreshRateTableIndex,HwInfo);
2866 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
2867 }
2868 }
2869
2870 if(HwInfo->jChipType < SIS_315H) {
2871
2872 if(VCLK > 150) data |= 0x80;
2873 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0x7B,data);
2874
2875 data = 0x00;
2876 if(VCLK >= 150) data |= 0x08;
2877 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xF7,data);
2878
2879 } else {
2880
2881 if(VCLK >= 166) data |= 0x0c;
2882 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xf3,data);
2883
2884 if(VCLK >= 166) {
2885 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1f,0xe7);
2886 }
2887 }
2888
2889 /* DAC speed */
2890 if(HwInfo->jChipType >= SIS_661) {
2891
2892 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xE8,0x10);
2893
2894 } else {
2895
2896 data = 0x03;
2897 if((VCLK >= 135) && (VCLK < 160)) data = 0x02;
2898 else if((VCLK >= 160) && (VCLK < 260)) data = 0x01;
2899 else if(VCLK >= 260) data = 0x00;
2900
2901 if(HwInfo->jChipType == SIS_540) {
2902 if((VCLK == 203) || (VCLK < 234)) data = 0x02;
2903 }
2904
2905 if(HwInfo->jChipType < SIS_315H) {
2906 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xFC,data);
2907 } else {
2908 if(HwInfo->jChipType > SIS_315PRO) {
2909 if(ModeNo > 0x13) data &= 0xfc;
2910 }
2911 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xF8,data);
2912 }
2913
2914 }
2915}
2916
2917static void
2918SiS_SetCRT1ModeRegs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
2919 USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex)
2920{
2921 USHORT data,infoflag=0,modeflag;
2922 USHORT resindex,xres;
2923#ifdef SIS315H
2924 USHORT data2,data3;
2925 ULONG longdata;
2926 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
2927#endif
2928
2929 if(SiS_Pr->UseCustomMode) {
2930 modeflag = SiS_Pr->CModeFlag;
2931 infoflag = SiS_Pr->CInfoFlag;
2932 xres = SiS_Pr->CHDisplay;
2933 } else {
2934 resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex);
2935 if(ModeNo > 0x13) {
2936 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2937 infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
2938 xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
2939 } else {
2940 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2941 xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
2942 }
2943 }
2944
2945 /* Disable DPMS */
2946 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1F,0x3F);
2947
2948 data = 0;
2949 if(ModeNo > 0x13) {
2950 if(SiS_Pr->SiS_ModeType > ModeEGA) {
2951 data |= 0x02;
2952 data |= ((SiS_Pr->SiS_ModeType - ModeVGA) << 2);
2953 }
2954 if(infoflag & InterlaceMode) data |= 0x20;
2955 }
2956 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x06,0xC0,data);
2957
2958 if(HwInfo->jChipType != SIS_300) {
2959 data = 0;
2960 if(infoflag & InterlaceMode) {
2961 if(xres <= 800) data = 0x0020;
2962 else if(xres <= 1024) data = 0x0035;
2963 else data = 0x0048;
2964 }
2965 SiS_SetReg(SiS_Pr->SiS_P3d4,0x19,(data & 0xFF));
2966 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x1a,0xFC,(data >> 8));
2967 }
2968
2969 if(modeflag & HalfDCLK) {
2970 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x01,0x08);
2971 }
2972
2973 data = 0;
2974 if(modeflag & LineCompareOff) data = 0x08;
2975 if(HwInfo->jChipType == SIS_300) {
2976 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xF7,data);
2977 } else {
2978 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xB7,data);
2979 if(SiS_Pr->SiS_ModeType == ModeEGA) {
2980 if(ModeNo > 0x13) {
2981 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x0F,0x40);
2982 }
2983 }
2984 }
2985
2986 if(HwInfo->jChipType >= SIS_661) {
2987 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x31,0xfb);
2988 }
2989
2990#ifdef SIS315H
2991 if(HwInfo->jChipType == SIS_315PRO) {
2992
2993 data = SiS_Get310DRAMType(SiS_Pr, HwInfo);
2994 data = SiS_Pr->SiS_SR15[2][data];
2995 if(SiS_Pr->SiS_ModeType == ModeText) {
2996 data &= 0xc7;
2997 } else {
2998 data2 = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,
2999 RefreshRateTableIndex,HwInfo);
3000 data2 >>= 1;
3001 if(infoflag & InterlaceMode) data2 >>= 1;
3002 data3 = SiS_GetColorDepth(SiS_Pr,ModeNo,ModeIdIndex) >> 1;
3003 if(!data3) data3++;
3004 data2 /= data3;
3005 if(data2 >= 0x50) {
3006 data &= 0x0f;
3007 data |= 0x50;
3008 }
3009 }
3010 SiS_SetReg(SiS_Pr->SiS_P3c4,0x17,data);
3011
3012 } else if( (HwInfo->jChipType == SIS_330) ||
3013 ((HwInfo->jChipType == SIS_760) && (SiS_Pr->SiS_SysFlags & SF_760LFB))) {
3014
3015 data = SiS_Get310DRAMType(SiS_Pr, HwInfo);
3016 if(HwInfo->jChipType == SIS_330) {
3017 data = SiS_Pr->SiS_SR15[2][data];
3018 } else {
3019 if(SiS_Pr->SiS_ROMNew) data = ROMAddr[0xf6];
3020 else if(SiS_Pr->SiS_UseROM) data = ROMAddr[0x100 + data];
3021 else data = 0xba;
3022 }
3023 if(SiS_Pr->SiS_ModeType <= ModeEGA) {
3024 data &= 0xc7;
3025 } else {
3026 if(SiS_Pr->UseCustomMode) {
3027 data2 = SiS_Pr->CSRClock;
3028 } else {
3029 data2 = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,
3030 RefreshRateTableIndex,HwInfo);
3031 data2 = SiS_Pr->SiS_VCLKData[data2].CLOCK;
3032 }
3033
3034 data3 = SiS_GetColorDepth(SiS_Pr,ModeNo,ModeIdIndex) >> 1;
3035 if(data3) data2 *= data3;
3036
3037 longdata = SiS_GetMCLK(SiS_Pr, HwInfo) * 1024;
3038
3039 data2 = longdata / data2;
3040
3041 if(HwInfo->jChipType == SIS_330) {
3042 if(SiS_Pr->SiS_ModeType != Mode16Bpp) {
3043 if (data2 >= 0x19c) data = 0xba;
3044 else if(data2 >= 0x140) data = 0x7a;
3045 else if(data2 >= 0x101) data = 0x3a;
3046 else if(data2 >= 0xf5) data = 0x32;
3047 else if(data2 >= 0xe2) data = 0x2a;
3048 else if(data2 >= 0xc4) data = 0x22;
3049 else if(data2 >= 0xac) data = 0x1a;
3050 else if(data2 >= 0x9e) data = 0x12;
3051 else if(data2 >= 0x8e) data = 0x0a;
3052 else data = 0x02;
3053 } else {
3054 if(data2 >= 0x127) data = 0xba;
3055 else data = 0x7a;
3056 }
3057 } else { /* 760+LFB */
3058 if (data2 >= 0x190) data = 0xba;
3059 else if(data2 >= 0xff) data = 0x7a;
3060 else if(data2 >= 0xd3) data = 0x3a;
3061 else if(data2 >= 0xa9) data = 0x1a;
3062 else if(data2 >= 0x93) data = 0x0a;
3063 else data = 0x02;
3064 }
3065 }
3066 SiS_SetReg(SiS_Pr->SiS_P3c4,0x17,data);
3067 } else if(HwInfo->jChipType == SIS_340) {
3068 /* TODO */
3069 }
3070#endif
3071
3072 data = 0x60;
3073 if(SiS_Pr->SiS_ModeType != ModeText) {
3074 data ^= 0x60;
3075 if(SiS_Pr->SiS_ModeType != ModeEGA) {
3076 data ^= 0xA0;
3077 }
3078 }
3079 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x21,0x1F,data);
3080
3081 SiS_SetVCLKState(SiS_Pr, HwInfo, ModeNo, RefreshRateTableIndex, ModeIdIndex);
3082
3083#ifdef SIS315H
3084 if(HwInfo->jChipType >= SIS_315H) {
3085 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40) {
3086 SiS_SetReg(SiS_Pr->SiS_P3d4,0x52,0x2c);
3087 } else {
3088 SiS_SetReg(SiS_Pr->SiS_P3d4,0x52,0x6c);
3089 }
3090 }
3091#endif
3092}
3093
3094/*********************************************/
3095/* LOAD DAC */
3096/*********************************************/
3097
3098#if 0
3099static void
3100SiS_ClearDAC(SiS_Private *SiS_Pr, ULONG port)
3101{
3102 int i;
3103
3104 OutPortByte(port, 0);
3105 port++;
3106 for (i=0; i < (256 * 3); i++) {
3107 OutPortByte(port, 0);
3108 }
3109}
3110#endif
3111
3112static void
3113SiS_WriteDAC(SiS_Private *SiS_Pr, SISIOADDRESS DACData, USHORT shiftflag,
3114 USHORT dl, USHORT ah, USHORT al, USHORT dh)
3115{
3116 USHORT temp,bh,bl;
3117
3118 bh = ah;
3119 bl = al;
3120 if(dl != 0) {
3121 temp = bh;
3122 bh = dh;
3123 dh = temp;
3124 if(dl == 1) {
3125 temp = bl;
3126 bl = dh;
3127 dh = temp;
3128 } else {
3129 temp = bl;
3130 bl = bh;
3131 bh = temp;
3132 }
3133 }
3134 if(shiftflag) {
3135 dh <<= 2;
3136 bh <<= 2;
3137 bl <<= 2;
3138 }
3139 SiS_SetRegByte(DACData,(USHORT)dh);
3140 SiS_SetRegByte(DACData,(USHORT)bh);
3141 SiS_SetRegByte(DACData,(USHORT)bl);
3142}
3143
3144void
3145SiS_LoadDAC(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
3146 USHORT ModeNo, USHORT ModeIdIndex)
3147{
3148 USHORT data,data2;
3149 USHORT time,i,j,k,m,n,o;
3150 USHORT si,di,bx,dl,al,ah,dh;
3151 USHORT shiftflag;
3152 SISIOADDRESS DACAddr, DACData;
3153 const USHORT *table = NULL;
3154
3155 if(ModeNo <= 0x13) {
3156 data = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3157 } else {
3158 if(SiS_Pr->UseCustomMode) {
3159 data = SiS_Pr->CModeFlag;
3160 } else {
3161 data = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3162 }
3163 }
3164
3165 data &= DACInfoFlag;
3166 time = 64;
3167 if(data == 0x00) table = SiS_MDA_DAC;
3168 if(data == 0x08) table = SiS_CGA_DAC;
3169 if(data == 0x10) table = SiS_EGA_DAC;
3170 if(data == 0x18) {
3171 time = 256;
3172 table = SiS_VGA_DAC;
3173 }
3174 if(time == 256) j = 16;
3175 else j = time;
3176
3177 if( ( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && /* 301B-DH LCD */
3178 (SiS_Pr->SiS_VBType & VB_NoLCD) ) ||
3179 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) || /* LCDA */
3180 (!(SiS_Pr->SiS_SetFlag & ProgrammingCRT2)) ) { /* Programming CRT1 */
3181 DACAddr = SiS_Pr->SiS_P3c8;
3182 DACData = SiS_Pr->SiS_P3c9;
3183 shiftflag = 0;
3184 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF);
3185 } else {
3186 shiftflag = 1;
3187 DACAddr = SiS_Pr->SiS_Part5Port;
3188 DACData = SiS_Pr->SiS_Part5Port + 1;
3189 }
3190
3191 SiS_SetRegByte(DACAddr,0x00);
3192
3193 for(i=0; i<j; i++) {
3194 data = table[i];
3195 for(k=0; k<3; k++) {
3196 data2 = 0;
3197 if(data & 0x01) data2 = 0x2A;
3198 if(data & 0x02) data2 += 0x15;
3199 if(shiftflag) data2 <<= 2;
3200 SiS_SetRegByte(DACData, data2);
3201 data >>= 2;
3202 }
3203 }
3204
3205 if(time == 256) {
3206 for(i = 16; i < 32; i++) {
3207 data = table[i];
3208 if(shiftflag) data <<= 2;
3209 for(k = 0; k < 3; k++) SiS_SetRegByte(DACData, data);
3210 }
3211 si = 32;
3212 for(m = 0; m < 9; m++) {
3213 di = si;
3214 bx = si + 4;
3215 dl = 0;
3216 for(n = 0; n < 3; n++) {
3217 for(o = 0; o < 5; o++) {
3218 dh = table[si];
3219 ah = table[di];
3220 al = table[bx];
3221 si++;
3222 SiS_WriteDAC(SiS_Pr, DACData, shiftflag, dl, ah, al, dh);
3223 }
3224 si -= 2;
3225 for(o = 0; o < 3; o++) {
3226 dh = table[bx];
3227 ah = table[di];
3228 al = table[si];
3229 si--;
3230 SiS_WriteDAC(SiS_Pr, DACData, shiftflag, dl, ah, al, dh);
3231 }
3232 dl++;
3233 } /* for n < 3 */
3234 si += 5;
3235 } /* for m < 9 */
3236 }
3237}
3238
3239/*********************************************/
3240/* SET CRT1 REGISTER GROUP */
3241/*********************************************/
3242
3243static void
3244SiS_SetCRT1Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
3245 USHORT ModeNo, USHORT ModeIdIndex)
3246{
3247 USHORT StandTableIndex,RefreshRateTableIndex;
3248
3249 SiS_Pr->SiS_CRT1Mode = ModeNo;
3250 StandTableIndex = SiS_GetModePtr(SiS_Pr, ModeNo, ModeIdIndex);
3251 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
3252 if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchCRT2)) {
3253 SiS_DisableBridge(SiS_Pr, HwInfo);
3254 }
3255 }
3256
3257 SiS_ResetSegmentRegisters(SiS_Pr, HwInfo);
3258
3259 SiS_SetSeqRegs(SiS_Pr, StandTableIndex, HwInfo);
3260 SiS_SetMiscRegs(SiS_Pr, StandTableIndex, HwInfo);
3261 SiS_SetCRTCRegs(SiS_Pr, HwInfo, StandTableIndex);
3262 SiS_SetATTRegs(SiS_Pr, StandTableIndex, HwInfo);
3263 SiS_SetGRCRegs(SiS_Pr, StandTableIndex);
3264 SiS_ClearExt1Regs(SiS_Pr, HwInfo, ModeNo);
3265 SiS_ResetCRT1VCLK(SiS_Pr, HwInfo);
3266
3267 SiS_Pr->SiS_SelectCRT2Rate = 0;
3268 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
3269
3270#ifdef LINUX_XF86
3271 xf86DrvMsgVerb(0, X_PROBED, 4, "(init: VBType=0x%04x, VBInfo=0x%04x)\n",
3272 SiS_Pr->SiS_VBType, SiS_Pr->SiS_VBInfo);
3273#endif
3274
3275 if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) {
3276 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
3277 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
3278 }
3279 }
3280
3281 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
3282 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
3283 }
3284
3285 RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
3286
3287 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3288 SiS_Pr->SiS_SetFlag &= ~ProgrammingCRT2;
3289 }
3290
3291 if(RefreshRateTableIndex != 0xFFFF) {
3292 SiS_SetCRT1Sync(SiS_Pr, RefreshRateTableIndex);
3293 SiS_SetCRT1CRTC(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
3294 SiS_SetCRT1Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
3295 SiS_SetCRT1VCLK(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
3296 }
3297
3298#ifdef SIS300
3299 if(HwInfo->jChipType == SIS_300) {
3300 SiS_SetCRT1FIFO_300(SiS_Pr, ModeNo,HwInfo,RefreshRateTableIndex);
3301 } else if((HwInfo->jChipType == SIS_630) ||
3302 (HwInfo->jChipType == SIS_730) ||
3303 (HwInfo->jChipType == SIS_540)) {
3304 SiS_SetCRT1FIFO_630(SiS_Pr, ModeNo, HwInfo, RefreshRateTableIndex);
3305 }
3306#endif
3307#ifdef SIS315H
3308 if(HwInfo->jChipType >= SIS_315H) {
3309 SiS_SetCRT1FIFO_310(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
3310 }
3311#endif
3312
3313 SiS_SetCRT1ModeRegs(SiS_Pr, HwInfo, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3314
3315 SiS_LoadDAC(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
3316
3317#ifdef LINUX_KERNEL
3318 if(SiS_Pr->SiS_flag_clearbuffer) {
3319 SiS_ClearBuffer(SiS_Pr,HwInfo,ModeNo);
3320 }
3321#endif
3322
3323 if(!(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchCRT2 | SetCRT2ToLCDA))) {
3324 SiS_WaitRetrace1(SiS_Pr);
3325 SiS_DisplayOn(SiS_Pr);
3326 }
3327}
3328
3329/*********************************************/
3330/* HELPER: VIDEO BRIDGE PROG CLK */
3331/*********************************************/
3332
3333static void
3334SiS_ResetVB(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
3335{
3336 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
3337 USHORT temp;
3338
3339 /* VB programming clock */
3340 if(SiS_Pr->SiS_UseROM) {
3341 if(HwInfo->jChipType < SIS_330) {
3342 temp = ROMAddr[VB310Data_1_2_Offset] | 0x40;
3343 if(SiS_Pr->SiS_ROMNew) temp = ROMAddr[0x80] | 0x40;
3344 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp);
3345 } else if(HwInfo->jChipType >= SIS_661) {
3346 temp = ROMAddr[0x7e] | 0x40;
3347 if(SiS_Pr->SiS_ROMNew) temp = ROMAddr[0x80] | 0x40;
3348 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp);
3349 }
3350 }
3351}
3352
3353/*********************************************/
3354/* HELPER: SET VIDEO REGISTERS */
3355/*********************************************/
3356
3357static void
3358SiS_StrangeStuff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
3359{
3360 if((IS_SIS651) || (IS_SISM650)) {
3361 SiS_SetReg(SiS_Pr->SiS_VidCapt, 0x3f, 0x00); /* Fiddle with capture regs */
3362 SiS_SetReg(SiS_Pr->SiS_VidCapt, 0x00, 0x00);
3363 SiS_SetReg(SiS_Pr->SiS_VidPlay, 0x00, 0x86); /* (BIOS does NOT unlock) */
3364 SiS_SetRegAND(SiS_Pr->SiS_VidPlay, 0x30, 0xfe); /* Fiddle with video regs */
3365 SiS_SetRegAND(SiS_Pr->SiS_VidPlay, 0x3f, 0xef);
3366 }
3367 /* !!! This does not support modes < 0x13 !!! */
3368}
3369
3370/*********************************************/
3371/* XFree86: SET SCREEN PITCH */
3372/*********************************************/
3373
3374#ifdef LINUX_XF86
3375static void
3376SiS_SetPitchCRT1(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn)
3377{
3378 SISPtr pSiS = SISPTR(pScrn);
3379 UShort HDisplay = pSiS->scrnPitch >> 3;
3380
3381 SiS_SetReg(SiS_Pr->SiS_P3d4,0x13,(HDisplay & 0xFF));
3382 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0xF0,(HDisplay>>8));
3383}
3384
3385static void
3386SiS_SetPitchCRT2(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn)
3387{
3388 SISPtr pSiS = SISPTR(pScrn);
3389 UShort HDisplay = pSiS->scrnPitch2 >> 3;
3390
3391 /* Unlock CRT2 */
3392 if(pSiS->VGAEngine == SIS_315_VGA)
3393 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2F, 0x01);
3394 else
3395 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24, 0x01);
3396
3397 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(HDisplay & 0xFF));
3398 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0xF0,(HDisplay >> 8));
3399}
3400
3401static void
3402SiS_SetPitch(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn)
3403{
3404 SISPtr pSiS = SISPTR(pScrn);
3405 BOOLEAN isslavemode = FALSE;
3406
3407 if( (pSiS->VBFlags & VB_VIDEOBRIDGE) &&
3408 ( ((pSiS->VGAEngine == SIS_300_VGA) &&
3409 (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0xa0) == 0x20) ||
3410 ((pSiS->VGAEngine == SIS_315_VGA) &&
3411 (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x50) == 0x10) ) ) {
3412 isslavemode = TRUE;
3413 }
3414
3415 /* We need to set pitch for CRT1 if bridge is in slave mode, too */
3416 if((pSiS->VBFlags & DISPTYPE_DISP1) || (isslavemode)) {
3417 SiS_SetPitchCRT1(SiS_Pr, pScrn);
3418 }
3419 /* We must not set the pitch for CRT2 if bridge is in slave mode */
3420 if((pSiS->VBFlags & DISPTYPE_DISP2) && (!isslavemode)) {
3421 SiS_SetPitchCRT2(SiS_Pr, pScrn);
3422 }
3423}
3424#endif
3425
3426/*********************************************/
3427/* SiSSetMode() */
3428/*********************************************/
3429
3430#ifdef LINUX_XF86
3431/* We need pScrn for setting the pitch correctly */
3432BOOLEAN
3433SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,ScrnInfoPtr pScrn,USHORT ModeNo, BOOLEAN dosetpitch)
3434#else
3435BOOLEAN
3436SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,USHORT ModeNo)
3437#endif
3438{
3439 USHORT ModeIdIndex;
3440 SISIOADDRESS BaseAddr = HwInfo->ulIOAddress;
3441 unsigned char backupreg=0;
3442#ifdef LINUX_KERNEL
3443 USHORT KeepLockReg;
3444 ULONG temp;
3445
3446 SiS_Pr->UseCustomMode = FALSE;
3447 SiS_Pr->CRT1UsesCustomMode = FALSE;
3448#endif
3449
3450 if(SiS_Pr->UseCustomMode) {
3451 ModeNo = 0xfe;
3452 }
3453
3454 SiSInitPtr(SiS_Pr, HwInfo);
3455 SiSRegInit(SiS_Pr, BaseAddr);
3456 SiS_GetSysFlags(SiS_Pr, HwInfo);
3457
3458#if defined(LINUX_XF86) && (defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__))
3459 if(pScrn) SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
3460 else
3461#endif
3462 SiS_Pr->SiS_VGAINFO = 0x11;
3463
3464 SiSInitPCIetc(SiS_Pr, HwInfo);
3465 SiSSetLVDSetc(SiS_Pr, HwInfo);
3466 SiSDetermineROMUsage(SiS_Pr, HwInfo);
3467
3468 SiS_Pr->SiS_flag_clearbuffer = 0;
3469
3470 if(!SiS_Pr->UseCustomMode) {
3471#ifdef LINUX_KERNEL
3472 if(!(ModeNo & 0x80)) SiS_Pr->SiS_flag_clearbuffer = 1;
3473#endif
3474 ModeNo &= 0x7f;
3475 }
3476
3477#ifdef LINUX_KERNEL
3478 KeepLockReg = SiS_GetReg(SiS_Pr->SiS_P3c4,0x05);
3479#endif
3480 SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86);
3481
3482 SiS_UnLockCRT2(SiS_Pr, HwInfo);
3483
3484 if(!SiS_Pr->UseCustomMode) {
3485 if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return FALSE;
3486 } else {
3487 ModeIdIndex = 0;
3488 }
3489
3490 SiS_GetVBType(SiS_Pr, HwInfo);
3491
3492 /* Init/restore some VB registers */
3493
3494 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
3495 if(HwInfo->jChipType >= SIS_315H) {
3496 SiS_ResetVB(SiS_Pr, HwInfo);
3497 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x32,0x10);
3498 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x00,0x0c);
3499 backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
3500 } else {
3501 backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
3502 }
3503 }
3504
3505 /* Get VB information (connectors, connected devices) */
3506 SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, (SiS_Pr->UseCustomMode) ? 0 : 1);
3507 SiS_SetYPbPr(SiS_Pr, HwInfo);
3508 SiS_SetTVMode(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
3509 SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
3510 SiS_SetLowModeTest(SiS_Pr, ModeNo, HwInfo);
3511
3512#ifdef LINUX_KERNEL
3513 /* 3. Check memory size (Kernel framebuffer driver only) */
3514 temp = SiS_CheckMemorySize(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
3515 if(!temp) return(0);
3516#endif
3517
3518 if(HwInfo->jChipType >= SIS_315H) {
3519 SiS_SetupCR5x(SiS_Pr, HwInfo);
3520 }
3521
3522 if(SiS_Pr->UseCustomMode) {
3523 SiS_Pr->CRT1UsesCustomMode = TRUE;
3524 SiS_Pr->CSRClock_CRT1 = SiS_Pr->CSRClock;
3525 SiS_Pr->CModeFlag_CRT1 = SiS_Pr->CModeFlag;
3526 } else {
3527 SiS_Pr->CRT1UsesCustomMode = FALSE;
3528 }
3529
3530 /* Set mode on CRT1 */
3531 if( (SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SetCRT2ToLCDA)) ||
3532 (!(SiS_Pr->SiS_VBInfo & SwitchCRT2)) ) {
3533 SiS_SetCRT1Group(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
3534 }
3535
3536 /* Set mode on CRT2 */
3537 if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchCRT2 | SetCRT2ToLCDA)) {
3538 if( (SiS_Pr->SiS_VBType & VB_SISVB) ||
3539 (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
3540 (SiS_Pr->SiS_IF_DEF_CH70xx != 0) ||
3541 (SiS_Pr->SiS_IF_DEF_TRUMPION != 0) ) {
3542 SiS_SetCRT2Group(SiS_Pr, HwInfo, ModeNo);
3543 }
3544 }
3545
3546 SiS_HandleCRT1(SiS_Pr);
3547
3548 SiS_StrangeStuff(SiS_Pr, HwInfo);
3549
3550 SiS_DisplayOn(SiS_Pr);
3551 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF);
3552
3553 if(HwInfo->jChipType >= SIS_315H) {
3554 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
3555 if(!(SiS_IsDualEdge(SiS_Pr, HwInfo))) {
3556 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
3557 }
3558 }
3559 }
3560
3561 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
3562 if(HwInfo->jChipType >= SIS_315H) {
3563 if(!SiS_Pr->SiS_ROMNew) {
3564 if(SiS_IsVAMode(SiS_Pr,HwInfo)) {
3565 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01);
3566 } else {
3567 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x35,0xFE);
3568 }
3569 }
3570
3571 SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,backupreg);
3572
3573 if((IS_SIS650) && (SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & 0xfc)) {
3574 if((ModeNo == 0x03) || (ModeNo == 0x10)) {
3575 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x51,0x80);
3576 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x56,0x08);
3577 }
3578 }
3579
3580 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & SetCRT2ToLCD) {
3581 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
3582 }
3583 } else if((HwInfo->jChipType == SIS_630) ||
3584 (HwInfo->jChipType == SIS_730)) {
3585 SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,backupreg);
3586 }
3587 }
3588
3589#ifdef LINUX_XF86
3590 if(pScrn) {
3591 /* SetPitch: Adapt to virtual size & position */
3592 if((ModeNo > 0x13) && (dosetpitch)) {
3593 SiS_SetPitch(SiS_Pr, pScrn);
3594 }
3595
3596 /* Backup/Set ModeNo in BIOS scratch area */
3597 SiS_GetSetModeID(pScrn, ModeNo);
3598 }
3599#endif
3600
3601#ifdef LINUX_KERNEL /* We never lock registers in XF86 */
3602 if(KeepLockReg == 0xA1) SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86);
3603 else SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x00);
3604#endif
3605
3606 return TRUE;
3607}
3608
3609/*********************************************/
3610/* XFree86: SiSBIOSSetMode() */
3611/* for non-Dual-Head mode */
3612/*********************************************/
3613
3614#ifdef LINUX_XF86
3615BOOLEAN
3616SiSBIOSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
3617 DisplayModePtr mode, BOOLEAN IsCustom)
3618{
3619 SISPtr pSiS = SISPTR(pScrn);
3620 UShort ModeNo = 0;
3621
3622 SiS_Pr->UseCustomMode = FALSE;
3623
3624 if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
3625
3626 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting custom mode %dx%d\n",
3627 SiS_Pr->CHDisplay,
3628 (mode->Flags & V_INTERLACE ? SiS_Pr->CVDisplay * 2 :
3629 (mode->Flags & V_DBLSCAN ? SiS_Pr->CVDisplay / 2 :
3630 SiS_Pr->CVDisplay)));
3631
3632 } else {
3633
3634 /* Don't need vbflags here; checks done earlier */
3635 ModeNo = SiS_GetModeNumber(pScrn, mode, 0);
3636 if(!ModeNo) return FALSE;
3637
3638 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting standard mode 0x%x\n", ModeNo);
3639
3640 }
3641
3642 return(SiSSetMode(SiS_Pr, HwInfo, pScrn, ModeNo, TRUE));
3643}
3644
3645/*********************************************/
3646/* XFree86: SiSBIOSSetModeCRT2() */
3647/* for Dual-Head modes */
3648/*********************************************/
3649BOOLEAN
3650SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
3651 DisplayModePtr mode, BOOLEAN IsCustom)
3652{
3653 USHORT ModeIdIndex;
3654 SISIOADDRESS BaseAddr = HwInfo->ulIOAddress;
3655 UShort ModeNo = 0;
3656 unsigned char backupreg=0;
3657 SISPtr pSiS = SISPTR(pScrn);
3658#ifdef SISDUALHEAD
3659 SISEntPtr pSiSEnt = pSiS->entityPrivate;
3660#endif
3661
3662 SiS_Pr->UseCustomMode = FALSE;
3663
3664 /* Remember: Custom modes for CRT2 are ONLY supported
3665 * -) on the 30x/B/C, and
3666 * -) if CRT2 is LCD or VGA, or CRT1 is LCDA
3667 */
3668
3669 if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
3670
3671 ModeNo = 0xfe;
3672
3673 } else {
3674
3675 ModeNo = SiS_GetModeNumber(pScrn, mode, 0);
3676 if(!ModeNo) return FALSE;
3677
3678 }
3679
3680 SiSRegInit(SiS_Pr, BaseAddr);
3681 SiSInitPtr(SiS_Pr, HwInfo);
3682 SiS_GetSysFlags(SiS_Pr, HwInfo);
3683#if (defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__))
3684 SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
3685#else
3686 SiS_Pr->SiS_VGAINFO = 0x11;
3687#endif
3688 SiSInitPCIetc(SiS_Pr, HwInfo);
3689 SiSSetLVDSetc(SiS_Pr, HwInfo);
3690 SiSDetermineROMUsage(SiS_Pr, HwInfo);
3691
3692 /* Save mode info so we can set it from within SetMode for CRT1 */
3693#ifdef SISDUALHEAD
3694 if(pSiS->DualHeadMode) {
3695 pSiSEnt->CRT2ModeNo = ModeNo;
3696 pSiSEnt->CRT2DMode = mode;
3697 pSiSEnt->CRT2IsCustom = IsCustom;
3698 pSiSEnt->CRT2CR30 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
3699 pSiSEnt->CRT2CR31 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
3700 pSiSEnt->CRT2CR35 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
3701 pSiSEnt->CRT2CR38 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
3702#if 0
3703 /* We can't set CRT2 mode before CRT1 mode is set */
3704 if(pSiSEnt->CRT1ModeNo == -1) {
3705 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
3706 "Setting CRT2 mode delayed until after setting CRT1 mode\n");
3707 return TRUE;
3708 }
3709#endif
3710 pSiSEnt->CRT2ModeSet = TRUE;
3711 }
3712#endif
3713
3714 /* We don't clear the buffer in X */
3715 SiS_Pr->SiS_flag_clearbuffer=0;
3716
3717 if(SiS_Pr->UseCustomMode) {
3718
3719 USHORT temptemp = SiS_Pr->CVDisplay;
3720
3721 if(SiS_Pr->CModeFlag & DoubleScanMode) temptemp >>= 1;
3722 else if(SiS_Pr->CInfoFlag & InterlaceMode) temptemp <<= 1;
3723
3724 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
3725 "Setting custom mode %dx%d on CRT2\n",
3726 SiS_Pr->CHDisplay, temptemp);
3727
3728 } else {
3729
3730 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
3731 "Setting standard mode 0x%x on CRT2\n", ModeNo);
3732
3733 }
3734
3735 SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86);
3736
3737 SiS_UnLockCRT2(SiS_Pr, HwInfo);
3738
3739 if(!SiS_Pr->UseCustomMode) {
3740 if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return FALSE;
3741 } else {
3742 ModeIdIndex = 0;
3743 }
3744
3745 SiS_GetVBType(SiS_Pr, HwInfo);
3746
3747 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
3748 if(HwInfo->jChipType >= SIS_315H) {
3749 SiS_ResetVB(SiS_Pr, HwInfo);
3750 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x32,0x10);
3751 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x00,0x0c);
3752 backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
3753 } else {
3754 backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
3755 }
3756 }
3757
3758 /* Get VB information (connectors, connected devices) */
3759 if(!SiS_Pr->UseCustomMode) {
3760 SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, 1);
3761 } else {
3762 /* If this is a custom mode, we don't check the modeflag for CRT2Mode */
3763 SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, 0);
3764 }
3765 SiS_SetYPbPr(SiS_Pr, HwInfo);
3766 SiS_SetTVMode(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
3767 SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
3768 SiS_SetLowModeTest(SiS_Pr, ModeNo, HwInfo);
3769
3770 /* Set mode on CRT2 */
3771 if( (SiS_Pr->SiS_VBType & VB_SISVB) ||
3772 (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
3773 (SiS_Pr->SiS_IF_DEF_CH70xx != 0) ||
3774 (SiS_Pr->SiS_IF_DEF_TRUMPION != 0) ) {
3775 SiS_SetCRT2Group(SiS_Pr, HwInfo, ModeNo);
3776 }
3777
3778 SiS_StrangeStuff(SiS_Pr, HwInfo);
3779
3780 SiS_DisplayOn(SiS_Pr);
3781 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF);
3782
3783 if(HwInfo->jChipType >= SIS_315H) {
3784 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
3785 if(!(SiS_IsDualEdge(SiS_Pr, HwInfo))) {
3786 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
3787 }
3788 }
3789 }
3790
3791 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
3792 if(HwInfo->jChipType >= SIS_315H) {
3793 if(!SiS_Pr->SiS_ROMNew) {
3794 if(SiS_IsVAMode(SiS_Pr,HwInfo)) {
3795 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01);
3796 } else {
3797 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x35,0xFE);
3798 }
3799 }
3800
3801 SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,backupreg);
3802
3803 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & SetCRT2ToLCD) {
3804 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
3805 }
3806 } else if((HwInfo->jChipType == SIS_630) ||
3807 (HwInfo->jChipType == SIS_730)) {
3808 SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,backupreg);
3809 }
3810 }
3811
3812 /* SetPitch: Adapt to virtual size & position */
3813 SiS_SetPitchCRT2(SiS_Pr, pScrn);
3814
3815 return TRUE;
3816}
3817
3818/*********************************************/
3819/* XFree86: SiSBIOSSetModeCRT1() */
3820/* for Dual-Head modes */
3821/*********************************************/
3822
3823BOOLEAN
3824SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
3825 DisplayModePtr mode, BOOLEAN IsCustom)
3826{
3827 SISPtr pSiS = SISPTR(pScrn);
3828 SISIOADDRESS BaseAddr = HwInfo->ulIOAddress;
3829 USHORT ModeIdIndex, ModeNo=0;
3830 UCHAR backupreg=0;
3831#ifdef SISDUALHEAD
3832 SISEntPtr pSiSEnt = pSiS->entityPrivate;
3833 UCHAR backupcr30, backupcr31, backupcr38, backupcr35, backupp40d=0;
3834 BOOLEAN backupcustom;
3835#endif
3836
3837 SiS_Pr->UseCustomMode = FALSE;
3838
3839 if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
3840
3841 USHORT temptemp = SiS_Pr->CVDisplay;
3842
3843 if(SiS_Pr->CModeFlag & DoubleScanMode) temptemp >>= 1;
3844 else if(SiS_Pr->CInfoFlag & InterlaceMode) temptemp <<= 1;
3845
3846 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
3847 "Setting custom mode %dx%d on CRT1\n",
3848 SiS_Pr->CHDisplay, temptemp);
3849 ModeNo = 0xfe;
3850
3851 } else {
3852
3853 ModeNo = SiS_GetModeNumber(pScrn, mode, 0);
3854 if(!ModeNo) return FALSE;
3855
3856 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
3857 "Setting standard mode 0x%x on CRT1\n", ModeNo);
3858 }
3859
3860 SiSInitPtr(SiS_Pr, HwInfo);
3861 SiSRegInit(SiS_Pr, BaseAddr);
3862 SiS_GetSysFlags(SiS_Pr, HwInfo);
3863#if (defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__))
3864 SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
3865#else
3866 SiS_Pr->SiS_VGAINFO = 0x11;
3867#endif
3868 SiSInitPCIetc(SiS_Pr, HwInfo);
3869 SiSSetLVDSetc(SiS_Pr, HwInfo);
3870 SiSDetermineROMUsage(SiS_Pr, HwInfo);
3871
3872 /* We don't clear the buffer in X */
3873 SiS_Pr->SiS_flag_clearbuffer = 0;
3874
3875 SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86);
3876
3877 SiS_UnLockCRT2(SiS_Pr, HwInfo);
3878
3879 if(!SiS_Pr->UseCustomMode) {
3880 if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return FALSE;
3881 } else {
3882 ModeIdIndex = 0;
3883 }
3884
3885 /* Determine VBType */
3886 SiS_GetVBType(SiS_Pr, HwInfo);
3887
3888 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
3889 if(HwInfo->jChipType >= SIS_315H) {
3890 backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
3891 } else {
3892 backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
3893 }
3894 }
3895
3896 /* Get VB information (connectors, connected devices) */
3897 /* (We don't care if the current mode is a CRT2 mode) */
3898 SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, 0);
3899 SiS_SetYPbPr(SiS_Pr, HwInfo);
3900 SiS_SetTVMode(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
3901 SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
3902 SiS_SetLowModeTest(SiS_Pr, ModeNo, HwInfo);
3903
3904 if(HwInfo->jChipType >= SIS_315H) {
3905 SiS_SetupCR5x(SiS_Pr, HwInfo);
3906 }
3907
3908 /* Set mode on CRT1 */
3909 SiS_SetCRT1Group(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
3910 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
3911 SiS_SetCRT2Group(SiS_Pr, HwInfo, ModeNo);
3912 }
3913
3914 /* SetPitch: Adapt to virtual size & position */
3915 SiS_SetPitchCRT1(SiS_Pr, pScrn);
3916
3917#ifdef SISDUALHEAD
3918 if(pSiS->DualHeadMode) {
3919 pSiSEnt->CRT1ModeNo = ModeNo;
3920 pSiSEnt->CRT1DMode = mode;
3921 }
3922#endif
3923
3924 if(SiS_Pr->UseCustomMode) {
3925 SiS_Pr->CRT1UsesCustomMode = TRUE;
3926 SiS_Pr->CSRClock_CRT1 = SiS_Pr->CSRClock;
3927 SiS_Pr->CModeFlag_CRT1 = SiS_Pr->CModeFlag;
3928 } else {
3929 SiS_Pr->CRT1UsesCustomMode = FALSE;
3930 }
3931
3932 /* Reset CRT2 if changing mode on CRT1 */
3933#ifdef SISDUALHEAD
3934 if(pSiS->DualHeadMode) {
3935 if(pSiSEnt->CRT2ModeNo != -1) {
3936 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
3937 "(Re-)Setting mode for CRT2\n");
3938 backupcustom = SiS_Pr->UseCustomMode;
3939 backupcr30 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
3940 backupcr31 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
3941 backupcr35 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
3942 backupcr38 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
3943 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3944 /* Backup LUT-enable */
3945 if(pSiSEnt->CRT2ModeSet) {
3946 backupp40d = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x0d) & 0x08;
3947 }
3948 }
3949 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
3950 SiS_SetReg(SiS_Pr->SiS_P3d4,0x30,pSiSEnt->CRT2CR30);
3951 SiS_SetReg(SiS_Pr->SiS_P3d4,0x31,pSiSEnt->CRT2CR31);
3952 SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,pSiSEnt->CRT2CR35);
3953 SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,pSiSEnt->CRT2CR38);
3954 }
3955 SiSBIOSSetModeCRT2(SiS_Pr, HwInfo, pSiSEnt->pScrn_1,
3956 pSiSEnt->CRT2DMode, pSiSEnt->CRT2IsCustom);
3957 SiS_SetReg(SiS_Pr->SiS_P3d4,0x30,backupcr30);
3958 SiS_SetReg(SiS_Pr->SiS_P3d4,0x31,backupcr31);
3959 SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,backupcr35);
3960 SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,backupcr38);
3961 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3962 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0d, ~0x08, backupp40d);
3963 }
3964 SiS_Pr->UseCustomMode = backupcustom;
3965 }
3966 }
3967#endif
3968
3969 /* Warning: From here, the custom mode entries in SiS_Pr are
3970 * possibly overwritten
3971 */
3972
3973 SiS_HandleCRT1(SiS_Pr);
3974
3975 SiS_StrangeStuff(SiS_Pr, HwInfo);
3976
3977 SiS_DisplayOn(SiS_Pr);
3978 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF);
3979
3980 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
3981 if(HwInfo->jChipType >= SIS_315H) {
3982 SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,backupreg);
3983 } else if((HwInfo->jChipType == SIS_630) ||
3984 (HwInfo->jChipType == SIS_730)) {
3985 SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,backupreg);
3986 }
3987 }
3988
3989 /* Backup/Set ModeNo in BIOS scratch area */
3990 SiS_GetSetModeID(pScrn,ModeNo);
3991
3992 return TRUE;
3993}
3994#endif /* Linux_XF86 */
3995
3996
3997#ifdef LINUX_XF86
3998BOOLEAN
3999SiS_GetPanelID(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
4000{
4001 const USHORT PanelTypeTable300[16] = {
4002 0xc101, 0xc117, 0x0121, 0xc135, 0xc142, 0xc152, 0xc162, 0xc072,
4003 0xc181, 0xc192, 0xc1a1, 0xc1b6, 0xc1c2, 0xc0d2, 0xc1e2, 0xc1f2
4004 };
4005 const USHORT PanelTypeTable31030x[16] = {
4006 0xc102, 0xc112, 0x0122, 0xc132, 0xc142, 0xc152, 0xc169, 0xc179,
4007 0x0189, 0xc192, 0xc1a2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
4008 };
4009 const USHORT PanelTypeTable310LVDS[16] = {
4010 0xc111, 0xc122, 0xc133, 0xc144, 0xc155, 0xc166, 0xc177, 0xc188,
4011 0xc199, 0xc0aa, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
4012 };
4013 USHORT tempax,tempbx,temp;
4014
4015 if(HwInfo->jChipType < SIS_315H) {
4016
4017 tempax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x18);
4018 tempbx = tempax & 0x0F;
4019 if(!(tempax & 0x10)){
4020 if(SiS_Pr->SiS_IF_DEF_LVDS == 1){
4021 tempbx = 0;
4022 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x38);
4023 if(temp & 0x40) tempbx |= 0x08;
4024 if(temp & 0x20) tempbx |= 0x02;
4025 if(temp & 0x01) tempbx |= 0x01;
4026 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x39);
4027 if(temp & 0x80) tempbx |= 0x04;
4028 } else {
4029 return 0;
4030 }
4031 }
4032 tempbx = PanelTypeTable300[tempbx];
4033 tempbx |= LCDSync;
4034 temp = tempbx & 0x00FF;
4035 SiS_SetReg(SiS_Pr->SiS_P3d4,0x36,temp);
4036 temp = (tempbx & 0xFF00) >> 8;
4037 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x37,~(LCDSyncBit|LCDRGB18Bit),temp);
4038
4039 } else {
4040
4041 if(HwInfo->jChipType >= SIS_661) return 0;
4042
4043 tempax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1a);
4044 tempax &= 0x1e;
4045 tempax >>= 1;
4046 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
4047 if(tempax == 0) {
4048 /* TODO: Include HUGE detection routine
4049 (Probably not worth bothering)
4050 */
4051 return 0;
4052 }
4053 temp = tempax & 0xff;
4054 tempax--;
4055 tempbx = PanelTypeTable310LVDS[tempax];
4056 } else {
4057 tempbx = PanelTypeTable31030x[tempax];
4058 temp = tempbx & 0xff;
4059 }
4060 SiS_SetReg(SiS_Pr->SiS_P3d4,0x36,temp);
4061 tempbx = (tempbx & 0xff00) >> 8;
4062 temp = tempbx & 0xc1;
4063 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x37,~(LCDSyncBit|LCDRGB18Bit),temp);
4064 if(SiS_Pr->SiS_VBType & VB_SISVB) {
4065 temp = tempbx & 0x04;
4066 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x39,0xfb,temp);
4067 }
4068
4069 }
4070 return 1;
4071}
4072#endif
4073
4074#ifndef GETBITSTR
4075#define BITMASK(h,l) (((unsigned)(1U << ((h)-(l)+1))-1)<<(l))
4076#define GENMASK(mask) BITMASK(1?mask,0?mask)
4077#define GETBITS(var,mask) (((var) & GENMASK(mask)) >> (0?mask))
4078#define GETBITSTR(val,from,to) ((GETBITS(val,from)) << (0?to))
4079#endif
4080
4081static void
4082SiS_CalcCRRegisters(SiS_Private *SiS_Pr, int depth)
4083{
4084 SiS_Pr->CCRT1CRTC[0] = ((SiS_Pr->CHTotal >> 3) - 5) & 0xff; /* CR0 */
4085 SiS_Pr->CCRT1CRTC[1] = (SiS_Pr->CHDisplay >> 3) - 1; /* CR1 */
4086 SiS_Pr->CCRT1CRTC[2] = (SiS_Pr->CHBlankStart >> 3) - 1; /* CR2 */
4087 SiS_Pr->CCRT1CRTC[3] = (((SiS_Pr->CHBlankEnd >> 3) - 1) & 0x1F) | 0x80; /* CR3 */
4088 SiS_Pr->CCRT1CRTC[4] = (SiS_Pr->CHSyncStart >> 3) + 3; /* CR4 */
4089 SiS_Pr->CCRT1CRTC[5] = ((((SiS_Pr->CHBlankEnd >> 3) - 1) & 0x20) << 2) | /* CR5 */
4090 (((SiS_Pr->CHSyncEnd >> 3) + 3) & 0x1F);
4091
4092 SiS_Pr->CCRT1CRTC[6] = (SiS_Pr->CVTotal - 2) & 0xFF; /* CR6 */
4093 SiS_Pr->CCRT1CRTC[7] = (((SiS_Pr->CVTotal - 2) & 0x100) >> 8) /* CR7 */
4094 | (((SiS_Pr->CVDisplay - 1) & 0x100) >> 7)
4095 | ((SiS_Pr->CVSyncStart & 0x100) >> 6)
4096 | (((SiS_Pr->CVBlankStart - 1) & 0x100) >> 5)
4097 | 0x10
4098 | (((SiS_Pr->CVTotal - 2) & 0x200) >> 4)
4099 | (((SiS_Pr->CVDisplay - 1) & 0x200) >> 3)
4100 | ((SiS_Pr->CVSyncStart & 0x200) >> 2);
4101
4102 SiS_Pr->CCRT1CRTC[16] = ((((SiS_Pr->CVBlankStart - 1) & 0x200) >> 4) >> 5); /* CR9 */
4103
4104 if(depth != 8) {
4105 if(SiS_Pr->CHDisplay >= 1600) SiS_Pr->CCRT1CRTC[16] |= 0x60; /* SRE */
4106 else if(SiS_Pr->CHDisplay >= 640) SiS_Pr->CCRT1CRTC[16] |= 0x40;
4107 }
4108
4109#if 0
4110 if (mode->VScan >= 32)
4111 regp->CRTC[9] |= 0x1F;
4112 else if (mode->VScan > 1)
4113 regp->CRTC[9] |= mode->VScan - 1;
4114#endif
4115
4116 SiS_Pr->CCRT1CRTC[8] = (SiS_Pr->CVSyncStart ) & 0xFF; /* CR10 */
4117 SiS_Pr->CCRT1CRTC[9] = ((SiS_Pr->CVSyncEnd ) & 0x0F) | 0x80; /* CR11 */
4118 SiS_Pr->CCRT1CRTC[10] = (SiS_Pr->CVDisplay - 1) & 0xFF; /* CR12 */
4119 SiS_Pr->CCRT1CRTC[11] = (SiS_Pr->CVBlankStart - 1) & 0xFF; /* CR15 */
4120 SiS_Pr->CCRT1CRTC[12] = (SiS_Pr->CVBlankEnd - 1) & 0xFF; /* CR16 */
4121
4122 SiS_Pr->CCRT1CRTC[13] = /* SRA */
4123 GETBITSTR((SiS_Pr->CVTotal -2), 10:10, 0:0) |
4124 GETBITSTR((SiS_Pr->CVDisplay -1), 10:10, 1:1) |
4125 GETBITSTR((SiS_Pr->CVBlankStart-1), 10:10, 2:2) |
4126 GETBITSTR((SiS_Pr->CVSyncStart ), 10:10, 3:3) |
4127 GETBITSTR((SiS_Pr->CVBlankEnd -1), 8:8, 4:4) |
4128 GETBITSTR((SiS_Pr->CVSyncEnd ), 4:4, 5:5) ;
4129
4130 SiS_Pr->CCRT1CRTC[14] = /* SRB */
4131 GETBITSTR((SiS_Pr->CHTotal >> 3) - 5, 9:8, 1:0) |
4132 GETBITSTR((SiS_Pr->CHDisplay >> 3) - 1, 9:8, 3:2) |
4133 GETBITSTR((SiS_Pr->CHBlankStart >> 3) - 1, 9:8, 5:4) |
4134 GETBITSTR((SiS_Pr->CHSyncStart >> 3) + 3, 9:8, 7:6) ;
4135
4136
4137 SiS_Pr->CCRT1CRTC[15] = /* SRC */
4138 GETBITSTR((SiS_Pr->CHBlankEnd >> 3) - 1, 7:6, 1:0) |
4139 GETBITSTR((SiS_Pr->CHSyncEnd >> 3) + 3, 5:5, 2:2) ;
4140}
4141
4142void
4143SiS_CalcLCDACRT1Timing(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex)
4144{
4145 USHORT modeflag, tempax, tempbx, VGAHDE = SiS_Pr->SiS_VGAHDE;
4146 int i,j;
4147
4148 /* 1:1 data: use data set by setcrt1crtc() */
4149 if(SiS_Pr->SiS_LCDInfo & LCDPass11) return;
4150
4151 if(ModeNo <= 0x13) {
4152 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
4153 } else if(SiS_Pr->UseCustomMode) {
4154 modeflag = SiS_Pr->CModeFlag;
4155 } else {
4156 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
4157 }
4158
4159 if(modeflag & HalfDCLK) VGAHDE >>= 1;
4160
4161 SiS_Pr->CHDisplay = VGAHDE;
4162 SiS_Pr->CHBlankStart = VGAHDE;
4163
4164 SiS_Pr->CVDisplay = SiS_Pr->SiS_VGAVDE;
4165 SiS_Pr->CVBlankStart = SiS_Pr->SiS_VGAVDE;
4166
4167 tempbx = SiS_Pr->PanelHT - SiS_Pr->PanelXRes;
4168 tempax = SiS_Pr->SiS_VGAHDE; /* not /2 ! */
4169 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
4170 tempax = SiS_Pr->PanelXRes;
4171 }
4172 tempbx += tempax;
4173 if(modeflag & HalfDCLK) tempbx -= VGAHDE;
4174 SiS_Pr->CHTotal = SiS_Pr->CHBlankEnd = tempbx;
4175
4176 tempax = VGAHDE;
4177 tempbx = SiS_Pr->CHTotal;
4178 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
4179 tempbx = SiS_Pr->PanelXRes;
4180 if(modeflag & HalfDCLK) tempbx >>= 1;
4181 tempax += ((tempbx - tempax) >> 1);
4182 }
4183
4184 tempax += SiS_Pr->PanelHRS;
4185 SiS_Pr->CHSyncStart = tempax;
4186 tempax += SiS_Pr->PanelHRE;
4187 SiS_Pr->CHSyncEnd = tempax;
4188
4189 tempbx = SiS_Pr->PanelVT - SiS_Pr->PanelYRes;
4190 tempax = SiS_Pr->SiS_VGAVDE;
4191 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
4192 tempax = SiS_Pr->PanelYRes;
4193 }
4194 SiS_Pr->CVTotal = SiS_Pr->CVBlankEnd = tempbx + tempax;
4195
4196 tempax = SiS_Pr->SiS_VGAVDE;
4197 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
4198 tempax += (SiS_Pr->PanelYRes - tempax) >> 1;
4199 }
4200 tempax += SiS_Pr->PanelVRS;
4201 SiS_Pr->CVSyncStart = tempax;
4202 tempax += SiS_Pr->PanelVRE;
4203 SiS_Pr->CVSyncEnd = tempax;
4204
4205 SiS_CalcCRRegisters(SiS_Pr, 8);
4206 SiS_Pr->CCRT1CRTC[16] &= ~0xE0;
4207
4208 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
4209
4210 for(i=0,j=0;i<=7;i++,j++) {
4211 SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
4212 }
4213 for(j=0x10;i<=10;i++,j++) {
4214 SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
4215 }
4216 for(j=0x15;i<=12;i++,j++) {
4217 SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
4218 }
4219 for(j=0x0A;i<=15;i++,j++) {
4220 SiS_SetReg(SiS_Pr->SiS_P3c4,j,SiS_Pr->CCRT1CRTC[i]);
4221 }
4222
4223 tempax = SiS_Pr->CCRT1CRTC[16] & 0xE0;
4224 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1F,tempax);
4225
4226 tempax = (SiS_Pr->CCRT1CRTC[16] & 0x01) << 5;
4227 if(modeflag & DoubleScanMode) tempax |= 0x80;
4228 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0x5F,tempax);
4229
4230#ifdef TWDEBUG
4231 xf86DrvMsg(0, X_INFO, "%d %d %d %d %d %d %d %d (%d %d %d %d)\n",
4232 SiS_Pr->CHDisplay, SiS_Pr->CHSyncStart, SiS_Pr->CHSyncEnd, SiS_Pr->CHTotal,
4233 SiS_Pr->CVDisplay, SiS_Pr->CVSyncStart, SiS_Pr->CVSyncEnd, SiS_Pr->CVTotal,
4234 SiS_Pr->CHBlankStart, SiS_Pr->CHBlankEnd, SiS_Pr->CVBlankStart, SiS_Pr->CVBlankEnd);
4235
4236 xf86DrvMsg(0, X_INFO, " {{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
4237 SiS_Pr->CCRT1CRTC[0], SiS_Pr->CCRT1CRTC[1],
4238 SiS_Pr->CCRT1CRTC[2], SiS_Pr->CCRT1CRTC[3],
4239 SiS_Pr->CCRT1CRTC[4], SiS_Pr->CCRT1CRTC[5],
4240 SiS_Pr->CCRT1CRTC[6], SiS_Pr->CCRT1CRTC[7]);
4241 xf86DrvMsg(0, X_INFO, " 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
4242 SiS_Pr->CCRT1CRTC[8], SiS_Pr->CCRT1CRTC[9],
4243 SiS_Pr->CCRT1CRTC[10], SiS_Pr->CCRT1CRTC[11],
4244 SiS_Pr->CCRT1CRTC[12], SiS_Pr->CCRT1CRTC[13],
4245 SiS_Pr->CCRT1CRTC[14], SiS_Pr->CCRT1CRTC[15]);
4246 xf86DrvMsg(0, X_INFO, " 0x%02x}},\n", SiS_Pr->CCRT1CRTC[16]);
4247#endif
4248}
4249
4250#ifdef LINUX_XF86
4251
4252void
4253SiS_MakeClockRegs(ScrnInfoPtr pScrn, int clock, UCHAR *p2b, UCHAR *p2c)
4254{
4255 int out_n, out_dn, out_div, out_sbit, out_scale;
4256 unsigned int vclk[5];
4257
4258#define Midx 0
4259#define Nidx 1
4260#define VLDidx 2
4261#define Pidx 3
4262#define PSNidx 4
4263
4264 if(SiS_compute_vclk(clock, &out_n, &out_dn, &out_div, &out_sbit, &out_scale)) {
4265 (*p2b) = (out_div == 2) ? 0x80 : 0x00;
4266 (*p2b) |= ((out_n - 1) & 0x7f);
4267 (*p2c) = (out_dn - 1) & 0x1f;
4268 (*p2c) |= (((out_scale - 1) & 3) << 5);
4269 (*p2c) |= ((out_sbit & 0x01) << 7);
4270#ifdef TWDEBUG
4271 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clock %d: n %d dn %d div %d sb %d sc %d\n",
4272 clock, out_n, out_dn, out_div, out_sbit, out_scale);
4273#endif
4274 } else {
4275 SiSCalcClock(pScrn, clock, 2, vclk);
4276 (*p2b) = (vclk[VLDidx] == 2) ? 0x80 : 0x00;
4277 (*p2b) |= (vclk[Midx] - 1) & 0x7f;
4278 (*p2c) = (vclk[Nidx] - 1) & 0x1f;
4279 if(vclk[Pidx] <= 4) {
4280 /* postscale 1,2,3,4 */
4281 (*p2c) |= ((vclk[Pidx] - 1) & 3) << 5;
4282 } else {
4283 /* postscale 6,8 */
4284 (*p2c) |= (((vclk[Pidx] / 2) - 1) & 3) << 5;
4285 (*p2c) |= 0x80;
4286 }
4287#ifdef TWDEBUG
4288 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clock %d: n %d dn %d div %d sc %d\n",
4289 clock, vclk[Midx], vclk[Nidx], vclk[VLDidx], vclk[Pidx]);
4290#endif
4291 }
4292}
4293
4294#endif
4295
4296/* ================ XFREE86/X.ORG ================= */
4297
4298/* Helper functions */
4299
4300#ifdef LINUX_XF86
4301
4302USHORT
4303SiS_CheckBuildCustomMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int VBFlags)
4304{
4305 SISPtr pSiS = SISPTR(pScrn);
4306 int depth = pSiS->CurrentLayout.bitsPerPixel;
4307
4308 pSiS->SiS_Pr->CModeFlag = 0;
4309
4310 pSiS->SiS_Pr->CDClock = mode->Clock;
4311
4312 pSiS->SiS_Pr->CHDisplay = mode->HDisplay;
4313 pSiS->SiS_Pr->CHSyncStart = mode->HSyncStart;
4314 pSiS->SiS_Pr->CHSyncEnd = mode->HSyncEnd;
4315 pSiS->SiS_Pr->CHTotal = mode->HTotal;
4316
4317 pSiS->SiS_Pr->CVDisplay = mode->VDisplay;
4318 pSiS->SiS_Pr->CVSyncStart = mode->VSyncStart;
4319 pSiS->SiS_Pr->CVSyncEnd = mode->VSyncEnd;
4320 pSiS->SiS_Pr->CVTotal = mode->VTotal;
4321
4322 pSiS->SiS_Pr->CFlags = mode->Flags;
4323
4324 if(pSiS->SiS_Pr->CFlags & V_INTERLACE) {
4325 pSiS->SiS_Pr->CVDisplay >>= 1;
4326 pSiS->SiS_Pr->CVSyncStart >>= 1;
4327 pSiS->SiS_Pr->CVSyncEnd >>= 1;
4328 pSiS->SiS_Pr->CVTotal >>= 1;
4329 }
4330 if(pSiS->SiS_Pr->CFlags & V_DBLSCAN) {
4331 /* pSiS->SiS_Pr->CDClock <<= 1; */
4332 pSiS->SiS_Pr->CVDisplay <<= 1;
4333 pSiS->SiS_Pr->CVSyncStart <<= 1;
4334 pSiS->SiS_Pr->CVSyncEnd <<= 1;
4335 pSiS->SiS_Pr->CVTotal <<= 1;
4336 }
4337
4338 pSiS->SiS_Pr->CHBlankStart = pSiS->SiS_Pr->CHDisplay;
4339 pSiS->SiS_Pr->CHBlankEnd = pSiS->SiS_Pr->CHTotal;
4340 pSiS->SiS_Pr->CVBlankStart = pSiS->SiS_Pr->CVSyncStart - 1;
4341 pSiS->SiS_Pr->CVBlankEnd = pSiS->SiS_Pr->CVTotal;
4342
4343 SiS_MakeClockRegs(pScrn, pSiS->SiS_Pr->CDClock, &pSiS->SiS_Pr->CSR2B, &pSiS->SiS_Pr->CSR2C);
4344
4345 pSiS->SiS_Pr->CSRClock = (pSiS->SiS_Pr->CDClock / 1000) + 1;
4346
4347 SiS_CalcCRRegisters(pSiS->SiS_Pr, depth);
4348
4349 switch(depth) {
4350 case 8: pSiS->SiS_Pr->CModeFlag |= 0x223b; break;
4351 case 16: pSiS->SiS_Pr->CModeFlag |= 0x227d; break;
4352 case 32: pSiS->SiS_Pr->CModeFlag |= 0x22ff; break;
4353 default: return 0;
4354 }
4355
4356 if(pSiS->SiS_Pr->CFlags & V_DBLSCAN)
4357 pSiS->SiS_Pr->CModeFlag |= DoubleScanMode;
4358
4359 if((pSiS->SiS_Pr->CVDisplay >= 1024) ||
4360 (pSiS->SiS_Pr->CVTotal >= 1024) ||
4361 (pSiS->SiS_Pr->CHDisplay >= 1024))
4362 pSiS->SiS_Pr->CModeFlag |= LineCompareOff;
4363
4364 if(pSiS->SiS_Pr->CFlags & V_CLKDIV2)
4365 pSiS->SiS_Pr->CModeFlag |= HalfDCLK;
4366
4367 pSiS->SiS_Pr->CInfoFlag = 0x0007;
4368
4369 if(pSiS->SiS_Pr->CFlags & V_NHSYNC)
4370 pSiS->SiS_Pr->CInfoFlag |= 0x4000;
4371
4372 if(pSiS->SiS_Pr->CFlags & V_NVSYNC)
4373 pSiS->SiS_Pr->CInfoFlag |= 0x8000;
4374
4375 if(pSiS->SiS_Pr->CFlags & V_INTERLACE)
4376 pSiS->SiS_Pr->CInfoFlag |= InterlaceMode;
4377
4378 pSiS->SiS_Pr->UseCustomMode = TRUE;
4379#ifdef TWDEBUG
4380 xf86DrvMsg(0, X_INFO, "Custom mode %dx%d:\n",
4381 pSiS->SiS_Pr->CHDisplay,pSiS->SiS_Pr->CVDisplay);
4382 xf86DrvMsg(0, X_INFO, "Modeflag %04x, Infoflag %04x\n",
4383 pSiS->SiS_Pr->CModeFlag, pSiS->SiS_Pr->CInfoFlag);
4384 xf86DrvMsg(0, X_INFO, " {{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
4385 pSiS->SiS_Pr->CCRT1CRTC[0], pSiS->SiS_Pr->CCRT1CRTC[1],
4386 pSiS->SiS_Pr->CCRT1CRTC[2], pSiS->SiS_Pr->CCRT1CRTC[3],
4387 pSiS->SiS_Pr->CCRT1CRTC[4], pSiS->SiS_Pr->CCRT1CRTC[5],
4388 pSiS->SiS_Pr->CCRT1CRTC[6], pSiS->SiS_Pr->CCRT1CRTC[7]);
4389 xf86DrvMsg(0, X_INFO, " 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
4390 pSiS->SiS_Pr->CCRT1CRTC[8], pSiS->SiS_Pr->CCRT1CRTC[9],
4391 pSiS->SiS_Pr->CCRT1CRTC[10], pSiS->SiS_Pr->CCRT1CRTC[11],
4392 pSiS->SiS_Pr->CCRT1CRTC[12], pSiS->SiS_Pr->CCRT1CRTC[13],
4393 pSiS->SiS_Pr->CCRT1CRTC[14], pSiS->SiS_Pr->CCRT1CRTC[15]);
4394 xf86DrvMsg(0, X_INFO, " 0x%02x}},\n", pSiS->SiS_Pr->CCRT1CRTC[16]);
4395 xf86DrvMsg(0, X_INFO, "Clock: 0x%02x, 0x%02x, %d\n",
4396 pSiS->SiS_Pr->CSR2B, pSiS->SiS_Pr->CSR2C, pSiS->SiS_Pr->CSRClock);
4397#endif
4398 return 1;
4399}
4400
4401int
4402SiS_FindPanelFromDB(SISPtr pSiS, USHORT panelvendor, USHORT panelproduct, int *maxx, int *maxy, int *prefx, int *prefy)
4403{
4404 int i, j;
4405 BOOLEAN done = FALSE;
4406
4407 i = 0;
4408 while((!done) && (SiS_PlasmaTable[i].vendor) && panelvendor) {
4409 if(SiS_PlasmaTable[i].vendor == panelvendor) {
4410 for(j=0; j<SiS_PlasmaTable[i].productnum; j++) {
4411 if(SiS_PlasmaTable[i].product[j] == panelproduct) {
4412 if(SiS_PlasmaTable[i].maxx && SiS_PlasmaTable[i].maxy) {
4413 (*maxx) = (int)SiS_PlasmaTable[i].maxx;
4414 (*maxy) = (int)SiS_PlasmaTable[i].maxy;
4415 (*prefx) = (int)SiS_PlasmaTable[i].prefx;
4416 (*prefy) = (int)SiS_PlasmaTable[i].prefy;
4417 done = TRUE;
4418 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
4419 "Identified %s, correcting max X res %d, max Y res %d\n",
4420 SiS_PlasmaTable[i].plasmaname,
4421 SiS_PlasmaTable[i].maxx, SiS_PlasmaTable[i].maxy);
4422 break;
4423 }
4424 }
4425 }
4426 }
4427 i++;
4428 }
4429 return (done) ? 1 : 0;
4430}
4431
4432/* Build a list of supported modes:
4433 * Built-in modes for which we have all data are M_T_DEFAULT,
4434 * modes derived from DDC or database data are M_T_BUILTIN
4435 */
4436DisplayModePtr
4437SiSBuildBuiltInModeList(ScrnInfoPtr pScrn, BOOLEAN includelcdmodes, BOOLEAN isfordvi)
4438{
4439 SISPtr pSiS = SISPTR(pScrn);
4440 unsigned short VRE, VBE, VRS, VBS, VDE, VT;
4441 unsigned short HRE, HBE, HRS, HBS, HDE, HT;
4442 unsigned char sr_data, cr_data, cr_data2, cr_data3;
4443 unsigned char sr2b, sr2c;
4444 float num, denum, postscalar, divider;
4445 int A, B, C, D, E, F, temp, i, j, k, l, index, vclkindex;
4446 DisplayModePtr new = NULL, current = NULL, first = NULL;
4447 BOOLEAN done = FALSE;
4448#if 0
4449 DisplayModePtr backup = NULL;
4450#endif
4451
4452 pSiS->backupmodelist = NULL;
4453 pSiS->AddedPlasmaModes = FALSE;
4454
4455 /* Initialize our pointers */
4456 if(pSiS->VGAEngine == SIS_300_VGA) {
4457#ifdef SIS300
4458 InitTo300Pointer(pSiS->SiS_Pr, &pSiS->sishw_ext);
4459#else
4460 return NULL;
4461#endif
4462 } else if(pSiS->VGAEngine == SIS_315_VGA) {
4463#ifdef SIS315H
4464 InitTo310Pointer(pSiS->SiS_Pr, &pSiS->sishw_ext);
4465#else
4466 return NULL;
4467#endif
4468 } else return NULL;
4469
4470 i = 0;
4471 while(pSiS->SiS_Pr->SiS_RefIndex[i].Ext_InfoFlag != 0xFFFF) {
4472
4473 index = pSiS->SiS_Pr->SiS_RefIndex[i].Ext_CRT1CRTC;
4474
4475 /* 0x5a (320x240) is a pure FTSN mode, not DSTN! */
4476 if((!pSiS->FSTN) &&
4477 (pSiS->SiS_Pr->SiS_RefIndex[i].ModeID == 0x5a)) {
4478 i++;
4479 continue;
4480 }
4481 if((pSiS->FSTN) &&
4482 (pSiS->SiS_Pr->SiS_RefIndex[i].XRes == 320) &&
4483 (pSiS->SiS_Pr->SiS_RefIndex[i].YRes == 240) &&
4484 (pSiS->SiS_Pr->SiS_RefIndex[i].ModeID != 0x5a)) {
4485 i++;
4486 continue;
4487 }
4488
4489 if(!(new = xalloc(sizeof(DisplayModeRec)))) return first;
4490 memset(new, 0, sizeof(DisplayModeRec));
4491 if(!(new->name = xalloc(10))) {
4492 xfree(new);
4493 return first;
4494 }
4495 if(!first) first = new;
4496 if(current) {
4497 current->next = new;
4498 new->prev = current;
4499 }
4500
4501 current = new;
4502
4503 sprintf(current->name, "%dx%d", pSiS->SiS_Pr->SiS_RefIndex[i].XRes,
4504 pSiS->SiS_Pr->SiS_RefIndex[i].YRes);
4505
4506 current->status = MODE_OK;
4507
4508 current->type = M_T_DEFAULT;
4509
4510 vclkindex = pSiS->SiS_Pr->SiS_RefIndex[i].Ext_CRTVCLK;
4511 if(pSiS->VGAEngine == SIS_300_VGA) vclkindex &= 0x3F;
4512
4513 sr2b = pSiS->SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
4514 sr2c = pSiS->SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
4515
4516 divider = (sr2b & 0x80) ? 2.0 : 1.0;
4517 postscalar = (sr2c & 0x80) ?
4518 ( (((sr2c >> 5) & 0x03) == 0x02) ? 6.0 : 8.0) : (((sr2c >> 5) & 0x03) + 1.0);
4519 num = (sr2b & 0x7f) + 1.0;
4520 denum = (sr2c & 0x1f) + 1.0;
4521
4522#ifdef TWDEBUG
4523 xf86DrvMsg(0, X_INFO, "------------\n");
4524 xf86DrvMsg(0, X_INFO, "sr2b: %x sr2c %x div %f ps %f num %f denum %f\n",
4525 sr2b, sr2c, divider, postscalar, num, denum);
4526#endif
4527
4528 current->Clock = (int)(14318 * (divider / postscalar) * (num / denum));
4529
4530 sr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[14];
4531 /* inSISIDXREG(SISSR, 0x0b, sr_data); */
4532
4533 cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[0];
4534 /* inSISIDXREG(SISCR, 0x00, cr_data); */
4535
4536 /* Horizontal total */
4537 HT = (cr_data & 0xff) |
4538 ((unsigned short) (sr_data & 0x03) << 8);
4539 A = HT + 5;
4540
4541 cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[1];
4542 /* inSISIDXREG(SISCR, 0x01, cr_data); */
4543
4544 /* Horizontal display enable end */
4545 HDE = (cr_data & 0xff) |
4546 ((unsigned short) (sr_data & 0x0C) << 6);
4547 E = HDE + 1; /* 0x80 0x64 */
4548
4549 cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[4];
4550 /* inSISIDXREG(SISCR, 0x04, cr_data); */
4551
4552 /* Horizontal retrace (=sync) start */
4553 HRS = (cr_data & 0xff) |
4554 ((unsigned short) (sr_data & 0xC0) << 2);
4555 F = HRS - E - 3; /* 0x06 0x06 */
4556
4557 cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[2];
4558 /* inSISIDXREG(SISCR, 0x02, cr_data); */
4559
4560 /* Horizontal blank start */
4561 HBS = (cr_data & 0xff) |
4562 ((unsigned short) (sr_data & 0x30) << 4);
4563
4564 sr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[15];
4565 /* inSISIDXREG(SISSR, 0x0c, sr_data); */
4566
4567 cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[3];
4568 /* inSISIDXREG(SISCR, 0x03, cr_data); */
4569
4570 cr_data2 = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[5];
4571 /* inSISIDXREG(SISCR, 0x05, cr_data2); */
4572
4573 /* Horizontal blank end */
4574 HBE = (cr_data & 0x1f) |
4575 ((unsigned short) (cr_data2 & 0x80) >> 2) |
4576 ((unsigned short) (sr_data & 0x03) << 6);
4577
4578 /* Horizontal retrace (=sync) end */
4579 HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3);
4580
4581 temp = HBE - ((E - 1) & 255);
4582 B = (temp > 0) ? temp : (temp + 256);
4583
4584 temp = HRE - ((E + F + 3) & 63);
4585 C = (temp > 0) ? temp : (temp + 64); /* 0x0b 0x0b */
4586
4587 D = B - F - C;
4588
4589 if((pSiS->SiS_Pr->SiS_RefIndex[i].XRes == 320) &&
4590 ((pSiS->SiS_Pr->SiS_RefIndex[i].YRes == 200) ||
4591 (pSiS->SiS_Pr->SiS_RefIndex[i].YRes == 240))) {
4592
4593 /* Terrible hack, but correct CRTC data for
4594 * these modes only produces a black screen...
4595 * (HRE is 0, leading into a too large C and
4596 * a negative D. The CRT controller does not
4597 * seem to like correcting HRE to 50
4598 */
4599 current->HDisplay = 320;
4600 current->HSyncStart = 328;
4601 current->HSyncEnd = 376;
4602 current->HTotal = 400;
4603
4604 } else {
4605
4606 current->HDisplay = (E * 8);
4607 current->HSyncStart = (E * 8) + (F * 8);
4608 current->HSyncEnd = (E * 8) + (F * 8) + (C * 8);
4609 current->HTotal = (E * 8) + (F * 8) + (C * 8) + (D * 8);
4610
4611 }
4612
4613#ifdef TWDEBUG
4614 xf86DrvMsg(0, X_INFO,
4615 "H: A %d B %d C %d D %d E %d F %d HT %d HDE %d HRS %d HBS %d HBE %d HRE %d\n",
4616 A, B, C, D, E, F, HT, HDE, HRS, HBS, HBE, HRE);
4617#endif
4618
4619 sr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[13];
4620 /* inSISIDXREG(SISSR, 0x0A, sr_data); */
4621
4622 cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[6];
4623 /* inSISIDXREG(SISCR, 0x06, cr_data); */
4624
4625 cr_data2 = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[7];
4626 /* inSISIDXREG(SISCR, 0x07, cr_data2); */
4627
4628 /* Vertical total */
4629 VT = (cr_data & 0xFF) |
4630 ((unsigned short) (cr_data2 & 0x01) << 8) |
4631 ((unsigned short)(cr_data2 & 0x20) << 4) |
4632 ((unsigned short) (sr_data & 0x01) << 10);
4633 A = VT + 2;
4634
4635 cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[10];
4636 /* inSISIDXREG(SISCR, 0x12, cr_data); */
4637
4638 /* Vertical display enable end */
4639 VDE = (cr_data & 0xff) |
4640 ((unsigned short) (cr_data2 & 0x02) << 7) |
4641 ((unsigned short) (cr_data2 & 0x40) << 3) |
4642 ((unsigned short) (sr_data & 0x02) << 9);
4643 E = VDE + 1;
4644
4645 cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[8];
4646 /* inSISIDXREG(SISCR, 0x10, cr_data); */
4647
4648 /* Vertical retrace (=sync) start */
4649 VRS = (cr_data & 0xff) |
4650 ((unsigned short) (cr_data2 & 0x04) << 6) |
4651 ((unsigned short) (cr_data2 & 0x80) << 2) |
4652 ((unsigned short) (sr_data & 0x08) << 7);
4653 F = VRS + 1 - E;
4654
4655 cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[11];
4656 /* inSISIDXREG(SISCR, 0x15, cr_data); */
4657
4658 cr_data3 = (pSiS->SiS_Pr->SiS_CRT1Table[index].CR[16] & 0x01) << 5;
4659 /* inSISIDXREG(SISCR, 0x09, cr_data3); */
4660
4661 /* Vertical blank start */
4662 VBS = (cr_data & 0xff) |
4663 ((unsigned short) (cr_data2 & 0x08) << 5) |
4664 ((unsigned short) (cr_data3 & 0x20) << 4) |
4665 ((unsigned short) (sr_data & 0x04) << 8);
4666
4667 cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[12];
4668 /* inSISIDXREG(SISCR, 0x16, cr_data); */
4669
4670 /* Vertical blank end */
4671 VBE = (cr_data & 0xff) |
4672 ((unsigned short) (sr_data & 0x10) << 4);
4673 temp = VBE - ((E - 1) & 511);
4674 B = (temp > 0) ? temp : (temp + 512);
4675
4676 cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[9];
4677 /* inSISIDXREG(SISCR, 0x11, cr_data); */
4678
4679 /* Vertical retrace (=sync) end */
4680 VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1);
4681 temp = VRE - ((E + F - 1) & 31);
4682 C = (temp > 0) ? temp : (temp + 32);
4683
4684 D = B - F - C;
4685
4686 current->VDisplay = VDE + 1;
4687 current->VSyncStart = VRS + 1;
4688 current->VSyncEnd = ((VRS & ~0x1f) | VRE) + 1;
4689 if(VRE <= (VRS & 0x1f)) current->VSyncEnd += 32;
4690 current->VTotal = E + D + C + F;
4691
4692#if 0
4693 current->VDisplay = E;
4694 current->VSyncStart = E + D;
4695 current->VSyncEnd = E + D + C;
4696 current->VTotal = E + D + C + F;
4697#endif
4698
4699#ifdef TWDEBUG
4700 xf86DrvMsg(0, X_INFO,
4701 "V: A %d B %d C %d D %d E %d F %d VT %d VDE %d VRS %d VBS %d VBE %d VRE %d\n",
4702 A, B, C, D, E, F, VT, VDE, VRS, VBS, VBE, VRE);
4703#endif
4704
4705 if(pSiS->SiS_Pr->SiS_RefIndex[i].Ext_InfoFlag & 0x4000)
4706 current->Flags |= V_NHSYNC;
4707 else
4708 current->Flags |= V_PHSYNC;
4709
4710 if(pSiS->SiS_Pr->SiS_RefIndex[i].Ext_InfoFlag & 0x8000)
4711 current->Flags |= V_NVSYNC;
4712 else
4713 current->Flags |= V_PVSYNC;
4714
4715 if(pSiS->SiS_Pr->SiS_RefIndex[i].Ext_InfoFlag & 0x0080)
4716 current->Flags |= V_INTERLACE;
4717
4718 j = 0;
4719 while(pSiS->SiS_Pr->SiS_EModeIDTable[j].Ext_ModeID != 0xff) {
4720 if(pSiS->SiS_Pr->SiS_EModeIDTable[j].Ext_ModeID ==
4721 pSiS->SiS_Pr->SiS_RefIndex[i].ModeID) {
4722 if(pSiS->SiS_Pr->SiS_EModeIDTable[j].Ext_ModeFlag & DoubleScanMode) {
4723 current->Flags |= V_DBLSCAN;
4724 }
4725 break;
4726 }
4727 j++;
4728 }
4729
4730 if(current->Flags & V_INTERLACE) {
4731 current->VDisplay <<= 1;
4732 current->VSyncStart <<= 1;
4733 current->VSyncEnd <<= 1;
4734 current->VTotal <<= 1;
4735 current->VTotal |= 1;
4736 }
4737 if(current->Flags & V_DBLSCAN) {
4738 current->Clock >>= 1;
4739 current->VDisplay >>= 1;
4740 current->VSyncStart >>= 1;
4741 current->VSyncEnd >>= 1;
4742 current->VTotal >>= 1;
4743 }
4744
4745#ifdef TWDEBUG
4746 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
4747 "Built-in: %s %.2f %d %d %d %d %d %d %d %d\n",
4748 current->name, (float)current->Clock / 1000,
4749 current->HDisplay, current->HSyncStart, current->HSyncEnd, current->HTotal,
4750 current->VDisplay, current->VSyncStart, current->VSyncEnd, current->VTotal);
4751#else
4752 (void)VBS; (void)HBS; (void)A;
4753#endif
4754
4755 i++;
4756 }
4757
4758 /* Add non-standard LCD modes for panel's detailed timings */
4759
4760 if(!includelcdmodes) return first;
4761
4762 if(pSiS->SiS_Pr->CP_Vendor) {
4763 xf86DrvMsg(0, X_INFO, "Checking database for vendor %x, product %x\n",
4764 pSiS->SiS_Pr->CP_Vendor, pSiS->SiS_Pr->CP_Product);
4765 }
4766
4767 i = 0;
4768 while((!done) && (SiS_PlasmaTable[i].vendor) && (pSiS->SiS_Pr->CP_Vendor)) {
4769
4770 if(SiS_PlasmaTable[i].vendor == pSiS->SiS_Pr->CP_Vendor) {
4771
4772 for(j=0; j<SiS_PlasmaTable[i].productnum; j++) {
4773
4774 if(SiS_PlasmaTable[i].product[j] == pSiS->SiS_Pr->CP_Product) {
4775
4776 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
4777 "Identified %s panel, adding specific modes\n",
4778 SiS_PlasmaTable[i].plasmaname);
4779
4780 for(k=0; k<SiS_PlasmaTable[i].modenum; k++) {
4781
4782 if(isfordvi) {
4783 if(!(SiS_PlasmaTable[i].plasmamodes[k] & 0x80)) continue;
4784 } else {
4785 if(!(SiS_PlasmaTable[i].plasmamodes[k] & 0x40)) continue;
4786 }
4787
4788 l = SiS_PlasmaTable[i].plasmamodes[k] & 0x3f;
4789
4790 if(pSiS->VBFlags & (VB_301|VB_301B|VB_302B|VB_301LV)) {
4791 if(isfordvi) {
4792 if(SiS_PlasmaMode[l].VDisplay > 1024) continue;
4793 }
4794 }
4795
4796 if(!(new = xalloc(sizeof(DisplayModeRec)))) return first;
4797
4798 memset(new, 0, sizeof(DisplayModeRec));
4799 if(!(new->name = xalloc(12))) {
4800 xfree(new);
4801 return first;
4802 }
4803 if(!first) first = new;
4804 if(current) {
4805 current->next = new;
4806 new->prev = current;
4807 }
4808
4809 current = new;
4810
4811 pSiS->AddedPlasmaModes = TRUE;
4812
4813 strcpy(current->name, SiS_PlasmaMode[l].name);
4814 /* sprintf(current->name, "%dx%d", SiS_PlasmaMode[l].HDisplay,
4815 SiS_PlasmaMode[l].VDisplay); */
4816
4817 current->status = MODE_OK;
4818
4819 current->type = M_T_BUILTIN;
4820
4821 current->Clock = SiS_PlasmaMode[l].clock;
4822 current->SynthClock = current->Clock;
4823
4824 current->HDisplay = SiS_PlasmaMode[l].HDisplay;
4825 current->HSyncStart = current->HDisplay + SiS_PlasmaMode[l].HFrontPorch;
4826 current->HSyncEnd = current->HSyncStart + SiS_PlasmaMode[l].HSyncWidth;
4827 current->HTotal = SiS_PlasmaMode[l].HTotal;
4828
4829 current->VDisplay = SiS_PlasmaMode[l].VDisplay;
4830 current->VSyncStart = current->VDisplay + SiS_PlasmaMode[l].VFrontPorch;
4831 current->VSyncEnd = current->VSyncStart + SiS_PlasmaMode[l].VSyncWidth;
4832 current->VTotal = SiS_PlasmaMode[l].VTotal;
4833
4834 current->CrtcHDisplay = current->HDisplay;
4835 current->CrtcHBlankStart = current->HSyncStart;
4836 current->CrtcHSyncStart = current->HSyncStart;
4837 current->CrtcHSyncEnd = current->HSyncEnd;
4838 current->CrtcHBlankEnd = current->HSyncEnd;
4839 current->CrtcHTotal = current->HTotal;
4840
4841 current->CrtcVDisplay = current->VDisplay;
4842 current->CrtcVBlankStart = current->VSyncStart;
4843 current->CrtcVSyncStart = current->VSyncStart;
4844 current->CrtcVSyncEnd = current->VSyncEnd;
4845 current->CrtcVBlankEnd = current->VSyncEnd;
4846 current->CrtcVTotal = current->VTotal;
4847
4848 if(SiS_PlasmaMode[l].SyncFlags & SIS_PL_HSYNCP)
4849 current->Flags |= V_PHSYNC;
4850 else
4851 current->Flags |= V_NHSYNC;
4852
4853 if(SiS_PlasmaMode[l].SyncFlags & SIS_PL_VSYNCP)
4854 current->Flags |= V_PVSYNC;
4855 else
4856 current->Flags |= V_NVSYNC;
4857
4858 if(current->HDisplay > pSiS->LCDwidth)
4859 pSiS->LCDwidth = pSiS->SiS_Pr->CP_MaxX = current->HDisplay;
4860 if(current->VDisplay > pSiS->LCDheight)
4861 pSiS->LCDheight = pSiS->SiS_Pr->CP_MaxY = current->VDisplay;
4862
4863 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
4864 "\tAdding \"%s\" to list of built-in modes\n", current->name);
4865
4866 }
4867 done = TRUE;
4868 break;
4869 }
4870 }
4871 }
4872
4873 i++;
4874
4875 }
4876
4877 if(pSiS->SiS_Pr->CP_HaveCustomData) {
4878
4879 for(i=0; i<7; i++) {
4880
4881 if(pSiS->SiS_Pr->CP_DataValid[i]) {
4882
4883 if(!(new = xalloc(sizeof(DisplayModeRec)))) return first;
4884
4885 memset(new, 0, sizeof(DisplayModeRec));
4886 if(!(new->name = xalloc(10))) {
4887 xfree(new);
4888 return first;
4889 }
4890 if(!first) first = new;
4891 if(current) {
4892 current->next = new;
4893 new->prev = current;
4894 }
4895
4896 current = new;
4897
4898 sprintf(current->name, "%dx%d", pSiS->SiS_Pr->CP_HDisplay[i],
4899 pSiS->SiS_Pr->CP_VDisplay[i]);
4900
4901 current->status = MODE_OK;
4902
4903 current->type = M_T_BUILTIN;
4904
4905 current->Clock = pSiS->SiS_Pr->CP_Clock[i];
4906 current->SynthClock = current->Clock;
4907
4908 current->HDisplay = pSiS->SiS_Pr->CP_HDisplay[i];
4909 current->HSyncStart = pSiS->SiS_Pr->CP_HSyncStart[i];
4910 current->HSyncEnd = pSiS->SiS_Pr->CP_HSyncEnd[i];
4911 current->HTotal = pSiS->SiS_Pr->CP_HTotal[i];
4912
4913 current->VDisplay = pSiS->SiS_Pr->CP_VDisplay[i];
4914 current->VSyncStart = pSiS->SiS_Pr->CP_VSyncStart[i];
4915 current->VSyncEnd = pSiS->SiS_Pr->CP_VSyncEnd[i];
4916 current->VTotal = pSiS->SiS_Pr->CP_VTotal[i];
4917
4918 current->CrtcHDisplay = current->HDisplay;
4919 current->CrtcHBlankStart = pSiS->SiS_Pr->CP_HBlankStart[i];
4920 current->CrtcHSyncStart = current->HSyncStart;
4921 current->CrtcHSyncEnd = current->HSyncEnd;
4922 current->CrtcHBlankEnd = pSiS->SiS_Pr->CP_HBlankEnd[i];
4923 current->CrtcHTotal = current->HTotal;
4924
4925 current->CrtcVDisplay = current->VDisplay;
4926 current->CrtcVBlankStart = pSiS->SiS_Pr->CP_VBlankStart[i];
4927 current->CrtcVSyncStart = current->VSyncStart;
4928 current->CrtcVSyncEnd = current->VSyncEnd;
4929 current->CrtcVBlankEnd = pSiS->SiS_Pr->CP_VBlankEnd[i];
4930 current->CrtcVTotal = current->VTotal;
4931
4932 if(pSiS->SiS_Pr->CP_SyncValid[i]) {
4933 if(pSiS->SiS_Pr->CP_HSync_P[i])
4934 current->Flags |= V_PHSYNC;
4935 else
4936 current->Flags |= V_NHSYNC;
4937
4938 if(pSiS->SiS_Pr->CP_VSync_P[i])
4939 current->Flags |= V_PVSYNC;
4940 else
4941 current->Flags |= V_NVSYNC;
4942 } else {
4943 /* No sync data? Use positive sync... */
4944 current->Flags |= V_PHSYNC;
4945 current->Flags |= V_PVSYNC;
4946 }
4947 }
4948 }
4949 }
4950
4951 return first;
4952
4953}
4954
4955/* Translate a mode number into the VESA pendant */
4956int
4957SiSTranslateToVESA(ScrnInfoPtr pScrn, int modenumber)
4958{
4959 SISPtr pSiS = SISPTR(pScrn);
4960 int i = 0;
4961
4962 /* Initialize our pointers */
4963 if(pSiS->VGAEngine == SIS_300_VGA) {
4964#ifdef SIS300
4965 InitTo300Pointer(pSiS->SiS_Pr, &pSiS->sishw_ext);
4966#else
4967 return -1;
4968#endif
4969 } else if(pSiS->VGAEngine == SIS_315_VGA) {
4970#ifdef SIS315H
4971 InitTo310Pointer(pSiS->SiS_Pr, &pSiS->sishw_ext);
4972#else
4973 return -1;
4974#endif
4975 } else return -1;
4976
4977 if(modenumber <= 0x13) return modenumber;
4978
4979#ifdef SIS315H
4980 if(pSiS->ROM661New) {
4981 while(SiS_EModeIDTable661[i].Ext_ModeID != 0xff) {
4982 if(SiS_EModeIDTable661[i].Ext_ModeID == modenumber) {
4983 return (int)SiS_EModeIDTable661[i].Ext_VESAID;
4984 }
4985 i++;
4986 }
4987 } else {
4988#endif
4989 while(pSiS->SiS_Pr->SiS_EModeIDTable[i].Ext_ModeID != 0xff) {
4990 if(pSiS->SiS_Pr->SiS_EModeIDTable[i].Ext_ModeID == modenumber) {
4991 return (int)pSiS->SiS_Pr->SiS_EModeIDTable[i].Ext_VESAID;
4992 }
4993 i++;
4994 }
4995#ifdef SIS315H
4996 }
4997#endif
4998 return -1;
4999}
5000
5001/* Translate a new BIOS mode number into the driver's pendant */
5002int
5003SiSTranslateToOldMode(int modenumber)
5004{
5005#ifdef SIS315H
5006 int i = 0;
5007
5008 while(SiS_EModeIDTable661[i].Ext_ModeID != 0xff) {
5009 if(SiS_EModeIDTable661[i].Ext_ModeID == modenumber) {
5010 if(SiS_EModeIDTable661[i].Ext_MyModeID)
5011 return (int)SiS_EModeIDTable661[i].Ext_MyModeID;
5012 else
5013 return modenumber;
5014 }
5015 i++;
5016 }
5017#endif
5018 return modenumber;
5019}
5020
5021#endif /* Xfree86 */
5022
5023#ifdef LINUX_KERNEL
5024int
5025sisfb_mode_rate_to_dclock(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
5026 unsigned char modeno, unsigned char rateindex)
5027{
5028 USHORT ModeNo = modeno;
5029 USHORT ModeIdIndex = 0, ClockIndex = 0;
5030 USHORT RefreshRateTableIndex = 0;
5031 int Clock;
5032
5033 if(HwInfo->jChipType < SIS_315H) {
5034#ifdef SIS300
5035 InitTo300Pointer(SiS_Pr, HwInfo);
5036#else
5037 return 65 * 1000;
5038#endif
5039 } else {
5040#ifdef SIS315H
5041 InitTo310Pointer(SiS_Pr, HwInfo);
5042#else
5043 return 65 * 1000;
5044#endif
5045 }
5046
5047 if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) {;
5048 printk(KERN_ERR "Could not find mode %x\n", ModeNo);
5049 return 65 * 1000;
5050 }
5051
5052 RefreshRateTableIndex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
5053 RefreshRateTableIndex += (rateindex - 1);
5054 ClockIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
5055 if(HwInfo->jChipType < SIS_315H) {
5056 ClockIndex &= 0x3F;
5057 }
5058 Clock = SiS_Pr->SiS_VCLKData[ClockIndex].CLOCK * 1000;
5059
5060 return(Clock);
5061}
5062
5063BOOLEAN
5064sisfb_gettotalfrommode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
5065 unsigned char modeno, int *htotal, int *vtotal, unsigned char rateindex)
5066{
5067 USHORT ModeNo = modeno;
5068 USHORT ModeIdIndex = 0, CRT1Index = 0;
5069 USHORT RefreshRateTableIndex = 0;
5070 unsigned char sr_data, cr_data, cr_data2;
5071
5072 if(HwInfo->jChipType < SIS_315H) {
5073#ifdef SIS300
5074 InitTo300Pointer(SiS_Pr, HwInfo);
5075#else
5076 return FALSE;
5077#endif
5078 } else {
5079#ifdef SIS315H
5080 InitTo310Pointer(SiS_Pr, HwInfo);
5081#else
5082 return FALSE;
5083#endif
5084 }
5085
5086 if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return FALSE;
5087
5088 RefreshRateTableIndex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
5089 RefreshRateTableIndex += (rateindex - 1);
5090 CRT1Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
5091
5092 sr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
5093 cr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[0];
5094 *htotal = (((cr_data & 0xff) | ((unsigned short) (sr_data & 0x03) << 8)) + 5) * 8;
5095
5096 sr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
5097 cr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[6];
5098 cr_data2 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
5099 *vtotal = ((cr_data & 0xFF) |
5100 ((unsigned short)(cr_data2 & 0x01) << 8) |
5101 ((unsigned short)(cr_data2 & 0x20) << 4) |
5102 ((unsigned short)(sr_data & 0x01) << 10)) + 2;
5103
5104 if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & InterlaceMode)
5105 *vtotal *= 2;
5106
5107 return TRUE;
5108}
5109
5110int
5111sisfb_mode_rate_to_ddata(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
5112 unsigned char modeno, unsigned char rateindex,
5113 struct fb_var_screeninfo *var)
5114{
5115 USHORT ModeNo = modeno;
5116 USHORT ModeIdIndex = 0, index = 0;
5117 USHORT RefreshRateTableIndex = 0;
5118 unsigned short VRE, VBE, VRS, VBS, VDE, VT;
5119 unsigned short HRE, HBE, HRS, HBS, HDE, HT;
5120 unsigned char sr_data, cr_data, cr_data2, cr_data3;
5121 int A, B, C, D, E, F, temp, j;
5122
5123 if(HwInfo->jChipType < SIS_315H) {
5124#ifdef SIS300
5125 InitTo300Pointer(SiS_Pr, HwInfo);
5126#else
5127 return 0;
5128#endif
5129 } else {
5130#ifdef SIS315H
5131 InitTo310Pointer(SiS_Pr, HwInfo);
5132#else
5133 return 0;
5134#endif
5135 }
5136
5137 if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return 0;
5138
5139 RefreshRateTableIndex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
5140 RefreshRateTableIndex += (rateindex - 1);
5141 index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
5142
5143 sr_data = SiS_Pr->SiS_CRT1Table[index].CR[14];
5144
5145 cr_data = SiS_Pr->SiS_CRT1Table[index].CR[0];
5146
5147 /* Horizontal total */
5148 HT = (cr_data & 0xff) |
5149 ((unsigned short) (sr_data & 0x03) << 8);
5150 A = HT + 5;
5151
5152 cr_data = SiS_Pr->SiS_CRT1Table[index].CR[1];
5153
5154 /* Horizontal display enable end */
5155 HDE = (cr_data & 0xff) |
5156 ((unsigned short) (sr_data & 0x0C) << 6);
5157 E = HDE + 1;
5158
5159 cr_data = SiS_Pr->SiS_CRT1Table[index].CR[4];
5160
5161 /* Horizontal retrace (=sync) start */
5162 HRS = (cr_data & 0xff) |
5163 ((unsigned short) (sr_data & 0xC0) << 2);
5164 F = HRS - E - 3;
5165
5166 cr_data = SiS_Pr->SiS_CRT1Table[index].CR[2];
5167
5168 /* Horizontal blank start */
5169 HBS = (cr_data & 0xff) |
5170 ((unsigned short) (sr_data & 0x30) << 4);
5171
5172 sr_data = SiS_Pr->SiS_CRT1Table[index].CR[15];
5173
5174 cr_data = SiS_Pr->SiS_CRT1Table[index].CR[3];
5175
5176 cr_data2 = SiS_Pr->SiS_CRT1Table[index].CR[5];
5177
5178 /* Horizontal blank end */
5179 HBE = (cr_data & 0x1f) |
5180 ((unsigned short) (cr_data2 & 0x80) >> 2) |
5181 ((unsigned short) (sr_data & 0x03) << 6);
5182
5183 /* Horizontal retrace (=sync) end */
5184 HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3);
5185
5186 temp = HBE - ((E - 1) & 255);
5187 B = (temp > 0) ? temp : (temp + 256);
5188
5189 temp = HRE - ((E + F + 3) & 63);
5190 C = (temp > 0) ? temp : (temp + 64);
5191
5192 D = B - F - C;
5193
5194 if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes == 320) &&
5195 ((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].YRes == 200) ||
5196 (SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].YRes == 240))) {
5197
5198 /* Terrible hack, but the correct CRTC data for
5199 * these modes only produces a black screen...
5200 */
5201 var->left_margin = (400 - 376);
5202 var->right_margin = (328 - 320);
5203 var->hsync_len = (376 - 328);
5204
5205 } else {
5206
5207 var->left_margin = D * 8;
5208 var->right_margin = F * 8;
5209 var->hsync_len = C * 8;
5210
5211 }
5212
5213 sr_data = SiS_Pr->SiS_CRT1Table[index].CR[13];
5214
5215 cr_data = SiS_Pr->SiS_CRT1Table[index].CR[6];
5216
5217 cr_data2 = SiS_Pr->SiS_CRT1Table[index].CR[7];
5218
5219 /* Vertical total */
5220 VT = (cr_data & 0xFF) |
5221 ((unsigned short) (cr_data2 & 0x01) << 8) |
5222 ((unsigned short)(cr_data2 & 0x20) << 4) |
5223 ((unsigned short) (sr_data & 0x01) << 10);
5224 A = VT + 2;
5225
5226 cr_data = SiS_Pr->SiS_CRT1Table[index].CR[10];
5227
5228 /* Vertical display enable end */
5229 VDE = (cr_data & 0xff) |
5230 ((unsigned short) (cr_data2 & 0x02) << 7) |
5231 ((unsigned short) (cr_data2 & 0x40) << 3) |
5232 ((unsigned short) (sr_data & 0x02) << 9);
5233 E = VDE + 1;
5234
5235 cr_data = SiS_Pr->SiS_CRT1Table[index].CR[8];
5236
5237 /* Vertical retrace (=sync) start */
5238 VRS = (cr_data & 0xff) |
5239 ((unsigned short) (cr_data2 & 0x04) << 6) |
5240 ((unsigned short) (cr_data2 & 0x80) << 2) |
5241 ((unsigned short) (sr_data & 0x08) << 7);
5242 F = VRS + 1 - E;
5243
5244 cr_data = SiS_Pr->SiS_CRT1Table[index].CR[11];
5245
5246 cr_data3 = (SiS_Pr->SiS_CRT1Table[index].CR[16] & 0x01) << 5;
5247
5248 /* Vertical blank start */
5249 VBS = (cr_data & 0xff) |
5250 ((unsigned short) (cr_data2 & 0x08) << 5) |
5251 ((unsigned short) (cr_data3 & 0x20) << 4) |
5252 ((unsigned short) (sr_data & 0x04) << 8);
5253
5254 cr_data = SiS_Pr->SiS_CRT1Table[index].CR[12];
5255
5256 /* Vertical blank end */
5257 VBE = (cr_data & 0xff) |
5258 ((unsigned short) (sr_data & 0x10) << 4);
5259 temp = VBE - ((E - 1) & 511);
5260 B = (temp > 0) ? temp : (temp + 512);
5261
5262 cr_data = SiS_Pr->SiS_CRT1Table[index].CR[9];
5263
5264 /* Vertical retrace (=sync) end */
5265 VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1);
5266 temp = VRE - ((E + F - 1) & 31);
5267 C = (temp > 0) ? temp : (temp + 32);
5268
5269 D = B - F - C;
5270
5271 var->upper_margin = D;
5272 var->lower_margin = F;
5273 var->vsync_len = C;
5274
5275 if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x8000)
5276 var->sync &= ~FB_SYNC_VERT_HIGH_ACT;
5277 else
5278 var->sync |= FB_SYNC_VERT_HIGH_ACT;
5279
5280 if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x4000)
5281 var->sync &= ~FB_SYNC_HOR_HIGH_ACT;
5282 else
5283 var->sync |= FB_SYNC_HOR_HIGH_ACT;
5284
5285 var->vmode = FB_VMODE_NONINTERLACED;
5286 if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x0080)
5287 var->vmode = FB_VMODE_INTERLACED;
5288 else {
5289 j = 0;
5290 while(SiS_Pr->SiS_EModeIDTable[j].Ext_ModeID != 0xff) {
5291 if(SiS_Pr->SiS_EModeIDTable[j].Ext_ModeID ==
5292 SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].ModeID) {
5293 if(SiS_Pr->SiS_EModeIDTable[j].Ext_ModeFlag & DoubleScanMode) {
5294 var->vmode = FB_VMODE_DOUBLE;
5295 }
5296 break;
5297 }
5298 j++;
5299 }
5300 }
5301
5302 if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
5303#if 0 /* Do this? */
5304 var->upper_margin <<= 1;
5305 var->lower_margin <<= 1;
5306 var->vsync_len <<= 1;
5307#endif
5308 } else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
5309 var->upper_margin >>= 1;
5310 var->lower_margin >>= 1;
5311 var->vsync_len >>= 1;
5312 }
5313
5314 return 1;
5315}
5316
5317#endif
5318
diff --git a/drivers/video/sis/init.h b/drivers/video/sis/init.h
new file mode 100644
index 000000000000..35030d300431
--- /dev/null
+++ b/drivers/video/sis/init.h
@@ -0,0 +1,2472 @@
1/* $XFree86$ */
2/* $XdotOrg$ */
3/*
4 * Data and prototypes for init.c
5 *
6 * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
7 *
8 * If distributed as part of the Linux kernel, the following license terms
9 * apply:
10 *
11 * * This program is free software; you can redistribute it and/or modify
12 * * it under the terms of the GNU General Public License as published by
13 * * the Free Software Foundation; either version 2 of the named License,
14 * * or any later version.
15 * *
16 * * This program is distributed in the hope that it will be useful,
17 * * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * * GNU General Public License for more details.
20 * *
21 * * You should have received a copy of the GNU General Public License
22 * * along with this program; if not, write to the Free Software
23 * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
24 *
25 * Otherwise, the following license terms apply:
26 *
27 * * Redistribution and use in source and binary forms, with or without
28 * * modification, are permitted provided that the following conditions
29 * * are met:
30 * * 1) Redistributions of source code must retain the above copyright
31 * * notice, this list of conditions and the following disclaimer.
32 * * 2) Redistributions in binary form must reproduce the above copyright
33 * * notice, this list of conditions and the following disclaimer in the
34 * * documentation and/or other materials provided with the distribution.
35 * * 3) The name of the author may not be used to endorse or promote products
36 * * derived from this software without specific prior written permission.
37 * *
38 * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
39 * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
40 * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
41 * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
42 * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
43 * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
44 * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
45 * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46 * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
47 * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48 *
49 * Author: Thomas Winischhofer <thomas@winischhofer.net>
50 *
51 */
52
53#ifndef _INIT_
54#define _INIT_
55
56#include "osdef.h"
57#include "initdef.h"
58
59#ifdef LINUX_XF86
60#include "sis.h"
61#include "sis_regs.h"
62#endif
63
64#ifdef LINUX_KERNEL
65#include "vgatypes.h"
66#include "vstruct.h"
67#ifdef SIS_CP
68#undef SIS_CP
69#endif
70#include <linux/config.h>
71#include <linux/version.h>
72#include <linux/types.h>
73#include <asm/io.h>
74#include <linux/fb.h>
75#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
76#include <linux/sisfb.h>
77#else
78#include <video/sisfb.h>
79#endif
80#endif
81
82/* Mode numbers */
83static const USHORT ModeIndex_320x200[] = {0x59, 0x41, 0x00, 0x4f};
84static const USHORT ModeIndex_320x240[] = {0x50, 0x56, 0x00, 0x53};
85static const USHORT ModeIndex_320x240_FSTN[] = {0x5a, 0x5b, 0x00, 0x00}; /* FSTN */
86static const USHORT ModeIndex_400x300[] = {0x51, 0x57, 0x00, 0x54};
87static const USHORT ModeIndex_512x384[] = {0x52, 0x58, 0x00, 0x5c};
88static const USHORT ModeIndex_640x400[] = {0x2f, 0x5d, 0x00, 0x5e};
89static const USHORT ModeIndex_640x480[] = {0x2e, 0x44, 0x00, 0x62};
90static const USHORT ModeIndex_720x480[] = {0x31, 0x33, 0x00, 0x35};
91static const USHORT ModeIndex_720x576[] = {0x32, 0x34, 0x00, 0x36};
92static const USHORT ModeIndex_768x576[] = {0x5f, 0x60, 0x00, 0x61};
93static const USHORT ModeIndex_800x480[] = {0x70, 0x7a, 0x00, 0x76};
94static const USHORT ModeIndex_800x600[] = {0x30, 0x47, 0x00, 0x63};
95static const USHORT ModeIndex_848x480[] = {0x39, 0x3b, 0x00, 0x3e};
96static const USHORT ModeIndex_856x480[] = {0x3f, 0x42, 0x00, 0x45};
97static const USHORT ModeIndex_960x540[] = {0x1d, 0x1e, 0x00, 0x1f}; /* 315 series only */
98static const USHORT ModeIndex_960x600[] = {0x20, 0x21, 0x00, 0x22}; /* 315 series only */
99static const USHORT ModeIndex_1024x768[] = {0x38, 0x4a, 0x00, 0x64};
100static const USHORT ModeIndex_1024x576[] = {0x71, 0x74, 0x00, 0x77};
101static const USHORT ModeIndex_1024x600[] = {0x20, 0x21, 0x00, 0x22}; /* 300 series only */
102static const USHORT ModeIndex_1280x1024[] = {0x3a, 0x4d, 0x00, 0x65};
103static const USHORT ModeIndex_1280x960[] = {0x7c, 0x7d, 0x00, 0x7e};
104static const USHORT ModeIndex_1152x768[] = {0x23, 0x24, 0x00, 0x25}; /* 300 series only */
105static const USHORT ModeIndex_1152x864[] = {0x29, 0x2a, 0x00, 0x2b};
106static const USHORT ModeIndex_300_1280x768[] = {0x55, 0x5a, 0x00, 0x5b};
107static const USHORT ModeIndex_310_1280x768[] = {0x23, 0x24, 0x00, 0x25};
108static const USHORT ModeIndex_1280x720[] = {0x79, 0x75, 0x00, 0x78};
109static const USHORT ModeIndex_1280x800[] = {0x14, 0x15, 0x00, 0x16};
110static const USHORT ModeIndex_1360x768[] = {0x48, 0x4b, 0x00, 0x4e};
111static const USHORT ModeIndex_300_1360x1024[]= {0x67, 0x6f, 0x00, 0x72}; /* 300 series, BARCO only */
112static const USHORT ModeIndex_1400x1050[] = {0x26, 0x27, 0x00, 0x28}; /* 315 series only */
113static const USHORT ModeIndex_1680x1050[] = {0x17, 0x18, 0x00, 0x19}; /* 315 series only */
114static const USHORT ModeIndex_1600x1200[] = {0x3c, 0x3d, 0x00, 0x66};
115static const USHORT ModeIndex_1920x1080[] = {0x2c, 0x2d, 0x00, 0x73}; /* 315 series only */
116static const USHORT ModeIndex_1920x1440[] = {0x68, 0x69, 0x00, 0x6b};
117static const USHORT ModeIndex_300_2048x1536[]= {0x6c, 0x6d, 0x00, 0x00};
118static const USHORT ModeIndex_310_2048x1536[]= {0x6c, 0x6d, 0x00, 0x6e};
119
120static const USHORT SiS_DRAMType[17][5]={
121 {0x0C,0x0A,0x02,0x40,0x39},
122 {0x0D,0x0A,0x01,0x40,0x48},
123 {0x0C,0x09,0x02,0x20,0x35},
124 {0x0D,0x09,0x01,0x20,0x44},
125 {0x0C,0x08,0x02,0x10,0x31},
126 {0x0D,0x08,0x01,0x10,0x40},
127 {0x0C,0x0A,0x01,0x20,0x34},
128 {0x0C,0x09,0x01,0x08,0x32},
129 {0x0B,0x08,0x02,0x08,0x21},
130 {0x0C,0x08,0x01,0x08,0x30},
131 {0x0A,0x08,0x02,0x04,0x11},
132 {0x0B,0x0A,0x01,0x10,0x28},
133 {0x09,0x08,0x02,0x02,0x01},
134 {0x0B,0x09,0x01,0x08,0x24},
135 {0x0B,0x08,0x01,0x04,0x20},
136 {0x0A,0x08,0x01,0x02,0x10},
137 {0x09,0x08,0x01,0x01,0x00}
138};
139
140static const USHORT SiS_SDRDRAM_TYPE[13][5] =
141{
142 { 2,12, 9,64,0x35},
143 { 1,13, 9,64,0x44},
144 { 2,12, 8,32,0x31},
145 { 2,11, 9,32,0x25},
146 { 1,12, 9,32,0x34},
147 { 1,13, 8,32,0x40},
148 { 2,11, 8,16,0x21},
149 { 1,12, 8,16,0x30},
150 { 1,11, 9,16,0x24},
151 { 1,11, 8, 8,0x20},
152 { 2, 9, 8, 4,0x01},
153 { 1,10, 8, 4,0x10},
154 { 1, 9, 8, 2,0x00}
155};
156
157static const USHORT SiS_DDRDRAM_TYPE[4][5] =
158{
159 { 2,12, 9,64,0x35},
160 { 2,12, 8,32,0x31},
161 { 2,11, 8,16,0x21},
162 { 2, 9, 8, 4,0x01}
163};
164
165static const USHORT SiS_MDA_DAC[] =
166{
167 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
168 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
169 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
170 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,
171 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
172 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
173 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
174 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F
175};
176
177static const USHORT SiS_CGA_DAC[] =
178{
179 0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
180 0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
181 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F,
182 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F,
183 0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
184 0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
185 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F,
186 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F
187};
188
189static const USHORT SiS_EGA_DAC[] =
190{
191 0x00,0x10,0x04,0x14,0x01,0x11,0x05,0x15,
192 0x20,0x30,0x24,0x34,0x21,0x31,0x25,0x35,
193 0x08,0x18,0x0C,0x1C,0x09,0x19,0x0D,0x1D,
194 0x28,0x38,0x2C,0x3C,0x29,0x39,0x2D,0x3D,
195 0x02,0x12,0x06,0x16,0x03,0x13,0x07,0x17,
196 0x22,0x32,0x26,0x36,0x23,0x33,0x27,0x37,
197 0x0A,0x1A,0x0E,0x1E,0x0B,0x1B,0x0F,0x1F,
198 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F
199};
200
201static const USHORT SiS_VGA_DAC[] =
202{
203 0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
204 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F,
205 0x00,0x05,0x08,0x0B,0x0E,0x11,0x14,0x18,
206 0x1C,0x20,0x24,0x28,0x2D,0x32,0x38,0x3F,
207 0x00,0x10,0x1F,0x2F,0x3F,0x1F,0x27,0x2F,
208 0x37,0x3F,0x2D,0x31,0x36,0x3A,0x3F,0x00,
209 0x07,0x0E,0x15,0x1C,0x0E,0x11,0x15,0x18,
210 0x1C,0x14,0x16,0x18,0x1A,0x1C,0x00,0x04,
211 0x08,0x0C,0x10,0x08,0x0A,0x0C,0x0E,0x10,
212 0x0B,0x0C,0x0D,0x0F,0x10
213};
214
215static const SiS_StResInfoStruct SiS_StResInfo[]=
216{
217 { 640,400},
218 { 640,350},
219 { 720,400},
220 { 720,350},
221 { 640,480}
222};
223
224static const SiS_ModeResInfoStruct SiS_ModeResInfo[] =
225{
226 { 320, 200, 8, 8}, /* 0x00 */
227 { 320, 240, 8, 8}, /* 0x01 */
228 { 320, 400, 8, 8}, /* 0x02 */
229 { 400, 300, 8, 8}, /* 0x03 */
230 { 512, 384, 8, 8}, /* 0x04 */
231 { 640, 400, 8,16}, /* 0x05 */
232 { 640, 480, 8,16}, /* 0x06 */
233 { 800, 600, 8,16}, /* 0x07 */
234 { 1024, 768, 8,16}, /* 0x08 */
235 { 1280,1024, 8,16}, /* 0x09 */
236 { 1600,1200, 8,16}, /* 0x0a */
237 { 1920,1440, 8,16}, /* 0x0b */
238 { 2048,1536, 8,16}, /* 0x0c */
239 { 720, 480, 8,16}, /* 0x0d */
240 { 720, 576, 8,16}, /* 0x0e */
241 { 1280, 960, 8,16}, /* 0x0f */
242 { 800, 480, 8,16}, /* 0x10 */
243 { 1024, 576, 8,16}, /* 0x11 */
244 { 1280, 720, 8,16}, /* 0x12 */
245 { 856, 480, 8,16}, /* 0x13 */
246 { 1280, 768, 8,16}, /* 0x14 */
247 { 1400,1050, 8,16}, /* 0x15 */
248 { 1152, 864, 8,16}, /* 0x16 */
249 { 848, 480, 8,16}, /* 0x17 */
250 { 1360, 768, 8,16}, /* 0x18 */
251 { 1024, 600, 8,16}, /* 0x19 */
252 { 1152, 768, 8,16}, /* 0x1a */
253 { 768, 576, 8,16}, /* 0x1b */
254 { 1360,1024, 8,16}, /* 0x1c */
255 { 1680,1050, 8,16}, /* 0x1d */
256 { 1280, 800, 8,16}, /* 0x1e */
257 { 1920,1080, 8,16}, /* 0x1f */
258 { 960, 540, 8,16}, /* 0x20 */
259 { 960, 600, 8,16} /* 0x21 */
260};
261
262#if defined(SIS300) || defined(SIS315H)
263static const SiS_StandTableStruct SiS_StandTable[]=
264{
265/* 0x00: MD_0_200 */
266 {
267 0x28,0x18,0x08,0x0800,
268 {0x09,0x03,0x00,0x02},
269 0x63,
270 {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
271 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
272 0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
273 0xff},
274 {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
275 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
276 0x08,0x00,0x0f,0x00},
277 {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
278 0xff}
279 },
280/* 0x01: MD_1_200 */
281 {
282 0x28,0x18,0x08,0x0800,
283 {0x09,0x03,0x00,0x02},
284 0x63,
285 {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
286 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
287 0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
288 0xff},
289 {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
290 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
291 0x08,0x00,0x0f,0x00},
292 {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
293 0xff}
294 },
295/* 0x02: MD_2_200 */
296 {
297 0x50,0x18,0x08,0x1000,
298 {0x01,0x03,0x00,0x02},
299 0x63,
300 {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
301 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
302 0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
303 0xff},
304 {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
305 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
306 0x08,0x00,0x0f,0x00},
307 {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
308 0xff}
309 },
310/* 0x03: MD_3_200 - mode 0x03 - 0 */
311 {
312 0x50,0x18,0x08,0x1000,
313 {0x01,0x03,0x00,0x02},
314 0x63,
315 {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
316 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
317 0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
318 0xff},
319 {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
320 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
321 0x08,0x00,0x0f,0x00},
322 {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
323 0xff}
324 },
325/* 0x04: MD_4 */
326 {
327 0x28,0x18,0x08,0x4000,
328 {0x09,0x03,0x00,0x02},
329 0x63,
330 {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f, /* 0x2c is 2b for 300 */
331 0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
332 0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
333 0xff},
334 {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
335 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
336 0x01,0x00,0x03,0x00},
337 {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
338 0xff}
339 },
340/* 0x05: MD_5 */
341 {
342 0x28,0x18,0x08,0x4000,
343 {0x09,0x03,0x00,0x02},
344 0x63,
345 {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f, /* 0x2c is 2b for 300 */
346 0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
347 0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
348 0xff},
349 {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
350 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
351 0x01,0x00,0x03,0x00},
352 {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
353 0xff}
354 },
355/* 0x06: MD_6 */
356 {
357 0x50,0x18,0x08,0x4000,
358 {0x01,0x01,0x00,0x06},
359 0x63,
360 {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, /* 55,81 is 54,80 for 300 */
361 0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
362 0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xc2,
363 0xff},
364 {0x00,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
365 0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
366 0x01,0x00,0x01,0x00},
367 {0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x00,
368 0xff}
369 },
370/* 0x07: MD_7 */
371 {
372 0x50,0x18,0x0e,0x1000,
373 {0x00,0x03,0x00,0x03},
374 0xa6,
375 {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
376 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
377 0x83,0x85,0x5d,0x28,0x0d,0x63,0xba,0xa3,
378 0xff},
379 {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
380 0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
381 0x0e,0x00,0x0f,0x08},
382 {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
383 0xff}
384 },
385/* 0x08: MDA_DAC */
386 {
387 0x00,0x00,0x00,0x0000,
388 {0x00,0x00,0x00,0x15},
389 0x15,
390 {0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
391 0x15,0x15,0x15,0x15,0x15,0x15,0x3f,0x3f,
392 0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x00,
393 0x00},
394 {0x00,0x00,0x00,0x00,0x00,0x15,0x15,0x15,
395 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
396 0x15,0x15,0x15,0x15},
397 {0x15,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
398 0x3f}
399 },
400/* 0x09: CGA_DAC */
401 {
402 0x00,0x10,0x04,0x0114,
403 {0x11,0x09,0x15,0x00},
404 0x10,
405 {0x04,0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,
406 0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x2a,0x3a,
407 0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x10,
408 0x04},
409 {0x14,0x01,0x11,0x09,0x15,0x00,0x10,0x04,
410 0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,0x2e,
411 0x3e,0x2b,0x3b,0x2f},
412 {0x3f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
413 0x3f}
414 },
415/* 0x0a: EGA_DAC */
416 {
417 0x00,0x10,0x04,0x0114,
418 {0x11,0x05,0x15,0x20},
419 0x30,
420 {0x24,0x34,0x21,0x31,0x25,0x35,0x08,0x18,
421 0x0c,0x1c,0x09,0x19,0x0d,0x1d,0x28,0x38,
422 0x2c,0x3c,0x29,0x39,0x2d,0x3d,0x02,0x12,
423 0x06},
424 {0x16,0x03,0x13,0x07,0x17,0x22,0x32,0x26,
425 0x36,0x23,0x33,0x27,0x37,0x0a,0x1a,0x0e,
426 0x1e,0x0b,0x1b,0x0f},
427 {0x1f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
428 0x3f}
429 },
430/* 0x0b: VGA_DAC */
431 {
432 0x00,0x10,0x04,0x0114,
433 {0x11,0x09,0x15,0x2a},
434 0x3a,
435 {0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x05,
436 0x08,0x0b,0x0e,0x11,0x14,0x18,0x1c,0x20,
437 0x24,0x28,0x2d,0x32,0x38,0x3f,0x00,0x10,
438 0x1f},
439 {0x2f,0x3f,0x1f,0x27,0x2f,0x37,0x3f,0x2d,
440 0x31,0x36,0x3a,0x3f,0x00,0x07,0x0e,0x15,
441 0x1c,0x0e,0x11,0x15},
442 {0x18,0x1c,0x14,0x16,0x18,0x1a,0x1c,0x00,
443 0x04}
444 },
445/* 0x0c */
446 {
447 0x08,0x0c,0x10,0x0a08,
448 {0x0c,0x0e,0x10,0x0b},
449 0x0c,
450 {0x0d,0x0f,0x10,0x10,0x01,0x08,0x00,0x00,
451 0x00,0x00,0x01,0x00,0x02,0x02,0x01,0x00,
452 0x04,0x04,0x01,0x00,0x05,0x02,0x05,0x00,
453 0x06},
454 {0x01,0x06,0x05,0x06,0x00,0x08,0x01,0x08,
455 0x00,0x07,0x02,0x07,0x06,0x07,0x00,0x00,
456 0x00,0x00,0x00,0x00},
457 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
458 0x00}
459 },
460/* 0x0d: MD_D */
461 {
462 0x28,0x18,0x08,0x2000,
463 {0x09,0x0f,0x00,0x06},
464 0x63,
465 {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f, /* 2c is 2b for 300 */
466 0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
467 0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xe3,
468 0xff},
469 {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
470 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
471 0x01,0x00,0x0f,0x00},
472 {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
473 0xff}
474 },
475/* 0x0e: MD_E */
476 {
477 0x50,0x18,0x08,0x4000,
478 {0x01,0x0f,0x00,0x06},
479 0x63,
480 {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, /* 55,81 is 54,80 for 300 */
481 0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
482 0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xe3,
483 0xff},
484 {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
485 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
486 0x01,0x00,0x0f,0x00},
487 {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
488 0xff}
489 },
490/* 0x0f: ExtVGATable - modes > 0x13 */
491 {
492 0x00,0x00,0x00,0x0000,
493 {0x01,0x0f,0x00,0x0e},
494 0x23,
495 {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,
496 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
497 0xea,0x8c,0xdf,0x28,0x40,0xe7,0x04,0xa3,
498 0xff},
499 {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
500 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
501 0x01,0x00,0x00,0x00},
502 {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
503 0xff}
504 },
505/* 0x10: ROM_SAVEPTR - totally different for 300 */
506 {
507 0x9f,0x3b,0x00,0x00c0,
508 {0x00,0x00,0x00,0x00},
509 0x00,
510 {0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x3f,
511 0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
512 0x00,0x00,0x1a,0x00,0xac,0x3e,0x00,0xc0,
513 0x00},
514 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
515 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
516 0x00,0x00,0x00,0x00},
517 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
518 0x00}
519 },
520/* 0x11: MD_F */
521 {
522 0x50,0x18,0x0e,0x8000,
523 {0x01,0x0f,0x00,0x06},
524 0xa2,
525 {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, /* 55,81 is 54,80 on 300 */
526 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
527 0x82,0x84,0x5d,0x28,0x0f,0x63,0xba,0xe3, /* 82,84 is 83,85 on 300 */
528 0xff},
529 {0x00,0x08,0x00,0x00,0x18,0x18,0x00,0x00,
530 0x00,0x08,0x00,0x00,0x00,0x18,0x00,0x00,
531 0x0b,0x00,0x05,0x00},
532 {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x05,
533 0xff}
534 },
535/* 0x12: MD_10 */
536 {
537 0x50,0x18,0x0e,0x8000,
538 {0x01,0x0f,0x00,0x06},
539 0xa3,
540 {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, /* 55,81 is 54,80 on 300 */
541 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
542 0x82,0x84,0x5d,0x28,0x0f,0x63,0xba,0xe3, /* 82,84 is 83,85 on 300 */
543 0xff},
544 {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
545 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
546 0x01,0x00,0x0f,0x00},
547 {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
548 0xff}
549 },
550/* 0x13: MD_0_350 */
551 {
552 0x28,0x18,0x0e,0x0800,
553 {0x09,0x03,0x00,0x02},
554 0xa3,
555 {0x2d,0x27,0x28,0x90,0x2b,0xb1,0xbf,0x1f, /* b1 is a0 on 300 */
556 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
557 0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
558 0xff},
559 {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
560 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
561 0x08,0x00,0x0f,0x00},
562 {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
563 0xff}
564 },
565/* 0x14: MD_1_350 */
566 {
567 0x28,0x18,0x0e,0x0800,
568 {0x09,0x03,0x00,0x02},
569 0xa3,
570 {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
571 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
572 0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
573 0xff},
574 {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
575 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
576 0x08,0x00,0x0f,0x00},
577 {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
578 0xff}
579 },
580/* 0x15: MD_2_350 */
581 {
582 0x50,0x18,0x0e,0x1000,
583 {0x01,0x03,0x00,0x02},
584 0xa3,
585 {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
586 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
587 0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
588 0xff},
589 {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
590 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
591 0x08,0x00,0x0f,0x00},
592 {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
593 0xff}
594 },
595/* 0x16: MD_3_350 - mode 0x03 - 1 */
596 {
597 0x50,0x18,0x0e,0x1000,
598 {0x01,0x03,0x00,0x02},
599 0xa3,
600 {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
601 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
602 0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
603 0xff},
604 {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
605 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
606 0x08,0x00,0x0f,0x00},
607 {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
608 0xff}
609 },
610/* 0x17: MD_0_1_400 */
611 {
612 0x28,0x18,0x10,0x0800,
613 {0x08,0x03,0x00,0x02},
614 0x67,
615 {0x2d,0x27,0x28,0x90,0x2b,0xb1,0xbf,0x1f, /* b1 is a0 on 300 */
616 0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
617 0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
618 0xff},
619 {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
620 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
621 0x0c,0x00,0x0f,0x08},
622 {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
623 0xff}
624 },
625/* 0x18: MD_2_3_400 - mode 0x03 - 2 */
626 {
627 0x50,0x18,0x10,0x1000,
628 {0x00,0x03,0x00,0x02},
629 0x67,
630 {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
631 0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
632 0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
633 0xff},
634 {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
635 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
636 0x0c,0x00,0x0f,0x08},
637 {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
638 0xff}
639 },
640/* 0x19: MD_7_400 */
641 {
642 0x50,0x18,0x10,0x1000,
643 {0x00,0x03,0x00,0x02},
644 0x66,
645 {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
646 0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
647 0x9c,0x8e,0x8f,0x28,0x0f,0x96,0xb9,0xa3,
648 0xff},
649 {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
650 0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
651 0x0e,0x00,0x0f,0x08},
652 {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
653 0xff}
654 },
655/* 0x1a: MD_11 */
656 {
657 0x50,0x1d,0x10,0xa000,
658 {0x01,0x0f,0x00,0x06},
659 0xe3,
660 {0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e, /* 55,81 is 54,80 on 300 */
661 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
662 0xe9,0x8b,0xdf,0x28,0x00,0xe7,0x04,0xc3, /* e9,8b is ea,8c on 300 */
663 0xff},
664 {0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
665 0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
666 0x01,0x00,0x0f,0x00},
667 {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x01,
668 0xff}
669 },
670/* 0x1b: ExtEGATable - Modes <= 0x02 */
671 {
672 0x50,0x1d,0x10,0xa000,
673 {0x01,0x0f,0x00,0x06},
674 0xe3,
675 {0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e, /* 55,81 is 54,80 on 300 */
676 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
677 0xe9,0x8b,0xdf,0x28,0x00,0xe7,0x04,0xe3, /* e9,8b is ea,8c on 300 */
678 0xff},
679 {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
680 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
681 0x01,0x00,0x0f,0x00},
682 {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
683 0xff}
684 },
685/* 0x1c: MD_13 */
686 {
687 0x28,0x18,0x08,0x2000,
688 {0x01,0x0f,0x00,0x0e},
689 0x63,
690 {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, /* 55,81 is 54,80 on 300 */
691 0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,
692 0x9c,0x8e,0x8f,0x28,0x40,0x96,0xb9,0xa3,
693 0xff},
694 {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
695 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
696 0x41,0x00,0x0f,0x00},
697 {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
698 0xff}
699 }
700};
701#endif
702
703/**************************************************************/
704/* SIS VIDEO BRIDGE ----------------------------------------- */
705/**************************************************************/
706
707static const UCHAR SiS_SoftSetting = 0x30; /* RAM setting */
708
709static const UCHAR SiS_OutputSelect = 0x40;
710
711static const UCHAR SiS_NTSCTiming[] = {
712 0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c,
713 0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a,
714 0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x1b,
715 0x0c,0x50,0x00,0x97,0x00,0xda,0x4a,0x17,
716 0x7d,0x05,0x4b,0x00,0x00,0xe2,0x00,0x02,
717 0x03,0x0a,0x65,0x9d,0x08,0x92,0x8f,0x40,
718 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x50,
719 0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00
720};
721
722static const UCHAR SiS_PALTiming[] = {
723 0x19,0x52,0x35,0x6e,0x04,0x38,0x3d,0x70,
724 0x94,0x49,0x01,0x12,0x06,0x3e,0x35,0x6d,
725 0x06,0x14,0x3e,0x35,0x6d,0x00,0x45,0x2b,
726 0x70,0x50,0x00,0x9b,0x00,0xd9,0x5d,0x17,
727 0x7d,0x05,0x45,0x00,0x00,0xe8,0x00,0x02,
728 0x0d,0x00,0x68,0xb0,0x0b,0x92,0x8f,0x40,
729 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x63,
730 0x00,0x40,0x3e,0x00,0xe1,0x02,0x28,0x00
731};
732
733static const UCHAR SiS_HiTVExtTiming[] = {
734 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
735 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
736 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
737 0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13,
738 0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40,
739 0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40,
740 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d,
741 0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00
742};
743
744static const UCHAR SiS_HiTVSt1Timing[] = {
745 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
746 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
747 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
748 0x65,0x90,0x7b,0xa8,0x03,0xf0,0x87,0x03,
749 0x11,0x15,0x11,0xcf,0x10,0x11,0xcf,0x10,
750 0x35,0x35,0x3b,0x69,0x1d,0x92,0x0f,0x40,
751 0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x86,
752 0xaf,0x5d,0x0e,0x00,0xfc,0xff,0x2d,0x00
753};
754
755static const UCHAR SiS_HiTVSt2Timing[] = {
756 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
757 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
758 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
759 0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13,
760 0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40,
761 0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40,
762 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d,
763 0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00
764};
765
766#if 0
767static const UCHAR SiS_HiTVTextTiming[] = {
768 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
769 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
770 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
771 0x65,0x90,0xe7,0xbc,0x03,0x0c,0x97,0x03,
772 0x14,0x78,0x14,0x08,0x20,0x14,0x08,0x20,
773 0xc8,0xc8,0x3b,0xd2,0x26,0x92,0x0f,0x40,
774 0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x96,
775 0x72,0x5c,0x11,0x00,0xfc,0xff,0x32,0x00
776};
777#endif
778
779static const UCHAR SiS_HiTVGroup3Data[] = {
780 0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x5f,
781 0x05,0x21,0xb2,0xb2,0x55,0x77,0x2a,0xa6,
782 0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
783 0x8c,0x6e,0x60,0x2e,0x58,0x48,0x72,0x44,
784 0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
785 0x4f,0x7f,0x03,0xa8,0x7d,0x20,0x1a,0xa9,
786 0x14,0x05,0x03,0x7e,0x64,0x31,0x14,0x75,
787 0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
788};
789
790static const UCHAR SiS_HiTVGroup3Simu[] = {
791 0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x95,
792 0xdb,0x20,0xb8,0xb8,0x55,0x47,0x2a,0xa6,
793 0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
794 0x8c,0x6e,0x60,0x15,0x26,0xd3,0xe4,0x11,
795 0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
796 0x67,0x36,0x01,0x47,0x0e,0x10,0xbe,0xb4,
797 0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75,
798 0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
799};
800
801#if 0
802static const UCHAR SiS_HiTVGroup3Text[] = {
803 0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0xa7,
804 0xf5,0x20,0xce,0xce,0x55,0x47,0x2a,0xa6,
805 0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
806 0x8c,0x6e,0x60,0x18,0x2c,0x0c,0x20,0x22,
807 0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
808 0x93,0x3c,0x01,0x50,0x2f,0x10,0xf4,0xca,
809 0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75,
810 0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
811};
812#endif
813
814static const UCHAR SiS_NTSCPhase[] = {0x21,0xed,0xba,0x08};
815static const UCHAR SiS_PALPhase[] = {0x2a,0x05,0xe3,0x00};
816static const UCHAR SiS_PALMPhase[] = {0x21,0xE4,0x2E,0x9B};
817static const UCHAR SiS_PALNPhase[] = {0x21,0xF4,0x3E,0xBA};
818static const UCHAR SiS_NTSCPhase2[] = {0x21,0xF0,0x7B,0xD6};
819static const UCHAR SiS_PALPhase2[] = {0x2a,0x09,0x86,0xe9};
820static const UCHAR SiS_PALMPhase2[] = {0x21,0xE6,0xEF,0xA4};
821static const UCHAR SiS_PALNPhase2[] = {0x21,0xF6,0x94,0x46};
822static const UCHAR SiS_SpecialPhase[] = {0x1e,0x8c,0x5c,0x7a};
823static const UCHAR SiS_SpecialPhaseM[]= {0x1e,0x83,0x0a,0xe0};
824static const UCHAR SiS_SpecialPhaseJ[]= {0x25,0xd4,0xfd,0x5e};
825
826static const SiS_TVDataStruct SiS_StPALData[] =
827{
828 { 1, 1, 864, 525,1270, 400, 100, 0, 760,0xf4,0xff,0x1c,0x22},
829 { 1, 1, 864, 525,1270, 350, 100, 0, 760,0xf4,0xff,0x1c,0x22},
830 { 1, 1, 864, 525,1270, 400, 0, 0, 720,0xf1,0x04,0x1f,0x18},
831 { 1, 1, 864, 525,1270, 350, 0, 0, 720,0xf4,0x0b,0x1c,0x0a},
832 { 1, 1, 864, 525,1270, 480, 50, 0, 760,0xf4,0xff,0x1c,0x22},
833 { 1, 1, 864, 525,1270, 600, 50, 0, 0,0xf4,0xff,0x1c,0x22}
834};
835
836static const SiS_TVDataStruct SiS_ExtPALData[] =
837{
838 { 27, 10, 848, 448,1270, 530, 50, 0, 50,0xf4,0xff,0x1c,0x22}, /* 640x400, 320x200 */
839 { 108, 35, 848, 398,1270, 530, 50, 0, 50,0xf4,0xff,0x1c,0x22},
840 { 12, 5, 954, 448,1270, 530, 50, 0, 50,0xf1,0x04,0x1f,0x18},
841 { 9, 4, 960, 463,1644, 438, 50, 0, 50,0xf4,0x0b,0x1c,0x0a},
842 { 9, 4, 848, 528,1270, 530, 0, 0, 50,0xf5,0xfb,0x1b,0x2a}, /* 640x480, 320x240 */
843/*{ 36, 25,1060, 648,1316, 530, 438, 0, 438,0xeb,0x05,0x25,0x16},*//* 800x600, 400x300 */
844 { 36, 25,1060, 648,1270, 530, 438, 0, 438,0xeb,0x05,0x25,0x16}, /* 800x600, 400x300 - better */
845 { 3, 2,1080, 619,1270, 540, 438, 0, 438,0xf3,0x00,0x1d,0x20}, /* 720x576 */
846 { 1, 1,1170, 821,1270, 520, 686, 0, 686,0xF3,0x00,0x1D,0x20}, /* 1024x768 */
847 { 1, 1,1170, 821,1270, 520, 686, 0, 686,0xF3,0x00,0x1D,0x20}, /* 1024x768 (for NTSC equ) */
848 { 9, 4, 848, 528,1270, 530, 0, 0, 50,0xf5,0xfb,0x1b,0x2a} /* 720x480 test */
849};
850
851static const SiS_TVDataStruct SiS_StNTSCData[] =
852{
853 { 1, 1, 858, 525,1270, 400, 50, 0, 760,0xf1,0x04,0x1f,0x18},
854 { 1, 1, 858, 525,1270, 350, 50, 0, 640,0xf1,0x04,0x1f,0x18},
855 { 1, 1, 858, 525,1270, 400, 0, 0, 720,0xf1,0x04,0x1f,0x18},
856 { 1, 1, 858, 525,1270, 350, 0, 0, 720,0xf4,0x0b,0x1c,0x0a},
857 { 1, 1, 858, 525,1270, 480, 0, 0, 760,0xf1,0x04,0x1f,0x18}
858};
859
860static const SiS_TVDataStruct SiS_ExtNTSCData[] =
861{
862 { 143, 65, 858, 443,1270, 440, 171, 0, 171,0xf1,0x04,0x1f,0x18}, /* 640x400, 320x200 */
863 { 88, 35, 858, 393,1270, 440, 171, 0, 171,0xf1,0x04,0x1f,0x18},
864 { 143, 70, 924, 443,1270, 440, 92, 0, 92,0xf1,0x04,0x1f,0x18},
865 { 143, 70, 924, 393,1270, 440, 92, 0, 92,0xf4,0x0b,0x1c,0x0a},
866 { 143, 76, 836, 523,1270, 440, 224, 0, 0,0xf1,0x05,0x1f,0x16}, /* 640x480, 320x240 */
867 { 143, 120,1056, 643,1270, 440, 0, 128, 0,0xf4,0x10,0x1c,0x00}, /* 800x600, 400x300 */
868/*{ 2, 1, 858, 503,1270, 480, 0, 128, 0,0xee,0x0c,0x22,0x08},*/ /* 720x480 (old, from 650) */
869 { 143, 76, 836, 523,1270, 440, 0, 128, 0,0xee,0x0c,0x22,0x08}, /* 720x480 - BETTER (from 300 series) */
870/*{ 65, 64,1056, 791,1270, 480, 638, 0, 0,0xEE,0x0C,0x22,0x08} */ /* 1024x768 (525i) */
871 { 1, 1,1100, 811,1412, 440, 0, 128, 0,0xee,0x0c,0x22,0x08}, /* 1024x768 (525i) CORRECTED */
872 { 65, 64,1056, 791,1270, 480, 455, 0, 0,0x00,0x00,0x00,0x00} /* 1024x768 (525p) */
873};
874
875static const SiS_TVDataStruct SiS_StHiTVData[] = /* Slave + TVSimu */
876{
877 { 1, 1, 0x37c,0x233,0x2b2,0x320, 0, 0, 0, 0x00,0x00,0x00,0x00},
878 { 1, 1, 0x37c,0x233,0x2b2,0x2bc, 0, 0, 0, 0x00,0x00,0x00,0x00},
879 { 1, 1, 0x37c,0x233,0x2b2,0x320, 0, 0, 0, 0x00,0x00,0x00,0x00},
880 { 1, 1, 0x37c,0x233,0x2b2,0x2bc, 0, 0, 0, 0x00,0x00,0x00,0x00},
881 { 1, 1, 0x37c,0x233,0x2b2,0x3c0, 0, 0, 0, 0x00,0x00,0x00,0x00},
882 { 8, 5, 0x41a,0x2ab,0x670,0x3c0,0x150,128, 0, 0x00,0x00,0x00,0x00}
883};
884
885static const SiS_TVDataStruct SiS_St2HiTVData[] = /* Slave */
886{
887 { 3, 1, 0x348,0x1e3,0x670,0x3c0,0x032, 0, 0, 0x00,0x00,0x00,0x00},
888 { 1, 1, 0x37c,0x233,0x2b2,0x2bc, 0, 0, 0, 0x00,0x00,0x00,0x00},
889 { 3, 1, 0x348,0x1e3,0x670,0x3c0,0x032, 0, 0, 0x00,0x00,0x00,0x00},
890 { 1, 1, 0x37c,0x233,0x2b2,0x2bc, 0, 0, 0, 0x00,0x00,0x00,0x00},
891 { 5, 2, 0x348,0x233,0x670,0x3c0,0x08d,128, 0, 0x00,0x00,0x00,0x00},
892 { 8, 5, 0x41a,0x2ab,0x670,0x3c0,0x17c,128, 0, 0x00,0x00,0x00,0x00}
893};
894
895static const SiS_TVDataStruct SiS_ExtHiTVData[] =
896{
897 { 6, 1, 0x348,0x233,0x660,0x3c0, 0, 0, 0, 0x00,0x00,0x00,0x00},
898 { 3, 1, 0x3c0,0x233,0x660,0x3c0, 0, 0, 0, 0x00,0x00,0x00,0x00},
899 { 6, 1, 0x348,0x233,0x660,0x3c0, 0, 0, 0, 0x00,0x00,0x00,0x00},
900 { 3, 1, 0x3c0,0x233,0x660,0x3c0, 0, 0, 0, 0x00,0x00,0x00,0x00},
901 { 5, 1, 0x348,0x233,0x670,0x3c0,0x166,128, 0, 0x00,0x00,0x00,0x00}, /* 640x480 */
902 { 16, 5, 0x41a,0x2ab,0x670,0x3c0,0x143,128, 0, 0x00,0x00,0x00,0x00}, /* 800x600 */
903 { 25, 12, 0x4ec,0x353,0x670,0x3c0,0x032, 0, 0, 0x00,0x00,0x00,0x00}, /* 1024x768 */
904 { 5, 4, 0x627,0x464,0x670,0x3c0,0x128, 0, 0, 0x00,0x00,0x00,0x00}, /* 1280x1024 */
905 { 4, 1, 0x41a,0x233,0x60c,0x3c0,0x143,128, 0, 0x00,0x00,0x00,0x00}, /* 800x480 */
906 { 5, 2, 0x578,0x293,0x670,0x3c0,0x032, 0, 0, 0x00,0x00,0x00,0x00}, /* 1024x576 */
907 { 8, 5, 0x6d6,0x323,0x670,0x3c0,0x128, 0, 0, 0x00,0x00,0x00,0x00}, /* 1280x720 */
908 { 137, 32, 0x3d4,0x233,0x663,0x3bf,0x143, 0, 0, 0x00,0x00,0x00,0x00} /* 960x600 */
909};
910
911static const SiS_TVDataStruct SiS_St525pData[] =
912{
913 { 1, 1, 0x6b4,0x20d,0x4f6,0x190, 50, 0, 0x2f8, 0x00,0x00,0x00,0x00},
914 { 1, 1, 0x6b4,0x20d,0x4f6,0x15e, 50, 0, 0x280, 0x00,0x00,0x00,0x00},
915 { 1, 1, 0x6b4,0x20d,0x4f6,0x190, 50, 0, 0x2f8, 0x00,0x00,0x00,0x00},
916 { 1, 1, 0x6b4,0x20d,0x4f6,0x15e, 50, 0, 0x280, 0x00,0x00,0x00,0x00},
917 { 1, 1, 0x6b4,0x20d,0x4f6,0x1e0, 0, 0, 0x2f8, 0x00,0x00,0x00,0x00}
918};
919
920static const SiS_TVDataStruct SiS_St750pData[] =
921{
922 { 1, 1, 0x672,0x2ee,0x500,0x190, 50, 0, 0x2f8, 0x00,0x00,0x00,0x00},
923 { 1, 1, 0x672,0x2ee,0x500,0x15e, 50, 0, 0x280, 0x00,0x00,0x00,0x00},
924 { 1, 1, 0x672,0x2ee,0x500,0x190, 0, 0, 0x2d0, 0x00,0x00,0x00,0x00},
925 { 1, 1, 0x672,0x2ee,0x500,0x15e, 0, 0, 0x2d0, 0x00,0x00,0x00,0x00},
926 { 1, 1, 0x672,0x2ee,0x500,0x1e0, 0, 0, 0x2f8, 0x00,0x00,0x00,0x00}
927};
928
929static const SiS_TVDataStruct SiS_Ext750pData[] =
930{
931 { 143, 65, 0x35a,0x1bb,0x4f6,0x1b8,0x0ab, 0, 0x0ab, 0x00,0x00,0x00,0x00},
932 { 88, 35, 0x35a,0x189,0x4f6,0x1b8,0x0ab, 0, 0x0ab, 0x00,0x00,0x00,0x00},
933 { 18, 5, 0x339,0x1ae,0x500,0x2d0,0x05c, 0, 0x05c, 0x00,0x00,0x00,0x00},
934 { 143, 70, 0x39c,0x189,0x4f6,0x1b8,0x05c, 0, 0x05c, 0x00,0x00,0x00,0x00},
935 { 99, 32, 0x320,0x1fe,0x500,0x2d0, 50, 0, 0, 0x00,0x00,0x00,0x00}, /* 640x480 */
936 { 5, 4, 0x5d8,0x29e,0x500,0x2a8, 50, 0, 0, 0x00,0x00,0x00,0x00}, /* 800x600 */
937 { 99, 32, 0x320,0x1fe,0x500,0x2d0, 50, 0, 0, 0x00,0x00,0x00,0x00}, /* 720x480 test WORKS */
938 { 68, 64, 0x55f,0x346,0x500,0x2a8,0x27e, 0, 0, 0x00,0x00,0x00,0x00}, /* 1024x768 */
939 { 5, 2, 0x3a7,0x226,0x500,0x2a8, 0,128, 0, 0x00,0x00,0x00,0x00}, /* 720x576 */
940 { 25, 24, 0x5d8,0x2f3,0x460,0x2a8, 50, 0, 0, 0x00,0x00,0x00,0x00} /* 1280x720 WORKS */
941};
942
943static const SiS_LCDDataStruct SiS_LCD1280x720Data[] = /* 2.03.00 */
944{
945 { 44, 15, 864, 430, 1408, 806 }, /* 640x400 */
946 { 128, 35, 792, 385, 1408, 806 },
947 { 44, 15, 864, 430, 1408, 806 },
948 { 128, 35, 792, 385, 1408, 806 },
949 { 22, 9, 864, 516, 1408, 806 }, /* 640x480 */
950 { 8, 5, 1056, 655, 1408, 806 }, /* 800x600 */
951 { 0, 0, 0, 0, 0, 0 }, /* 1024x768 */
952 { 0, 0, 0, 0, 0, 0 }, /* 1280x1024 */
953 { 0, 0, 0, 0, 0, 0 },
954 { 0, 0, 0, 0, 0, 0 },
955 { 1, 1, 1408, 806, 1408, 806 } /* 1280x720 */
956};
957
958/* About 1280x768: For TMDS, Panel_1280x768 will only be set if
959 * the panel is a Fujitsu 7911 (VL-17WDX8) (with clock 81, 1688x802)
960 * Other TMDS panels of this resolution will be treated as custom.
961 * For LVDS, we know another type (_2).
962 * (Note: 1280x768_3 is now special for SiS301/NetVista
963 */
964
965static const SiS_LCDDataStruct SiS_StLCD1280x768_2Data[] = /* 2.03.00 */
966{
967 { 64, 21, 858, 434, 1408, 806 }, /* 640x400 */
968 { 32, 9, 858, 372, 1408, 806 },
969 { 64, 21, 858, 434, 1408, 806 },
970 { 32, 9, 858, 372, 1408, 806 },
971 { 143, 68, 1024, 527, 1408, 806 }, /* 640x480 */
972 { 64, 51, 1364, 663, 1408, 806 }, /* 800x600 */
973 { 88, 81, 1296, 806, 1408, 806 }, /* 1024x768 */
974 { 0, 0, 0, 0, 0, 0 },
975 { 1, 1, 1408, 806, 1408, 806 }, /* 1280x768 */
976 { 0, 0, 0, 0, 0, 0 },
977 { 16, 15, 1600, 750, 1600, 806 } /* 1280x720 - from Ext */
978};
979
980static const SiS_LCDDataStruct SiS_ExtLCD1280x768_2Data[] = /* 2.03.00 */
981{
982 { 16, 5, 960, 410, 1600, 806 }, /* 640x400 */
983 { 64, 21, 1152, 364, 1600, 806 },
984 { 16, 5, 960, 410, 1600, 806 },
985 { 64, 21, 1152, 364, 1600, 806 },
986 { 32, 13, 1040, 493, 1600, 806 }, /* 640x480 */
987 { 16, 9, 1152, 618, 1600, 806 }, /* 800x600 */
988 { 25, 21, 1344, 796, 1600, 806 }, /* 1024x768 */
989 { 0, 0, 0, 0, 0, 0 },
990 { 1, 1, 1600, 806, 1600, 806 }, /* 1280x768 */
991 { 0, 0, 0, 0, 0, 0 },
992 { 16, 15, 1600, 750, 1600, 806 } /* 1280x720 */
993};
994
995#if 0 /* Not used; _3 now reserved for NetVista (SiS301) */
996static const SiS_LCDDataStruct SiS_LCD1280x768_3Data[] =
997{
998 { 64, 25, 1056, 422, 1664, 798 }, /* 640x400 */
999 { 128, 39, 884, 396, 1408, 806 }, /* ,640 */
1000 { 64, 25, 1056, 422, 1664, 798 }, /* 640x400 */
1001 { 128, 39, 884, 396, 1408, 806 }, /* ,640 */
1002 { 32, 15, 1056, 513, 1408, 806 }, /* ,664 */ /* 640x480 */
1003 { 176, 125, 1280, 640, 1408, 806 }, /* ,768 */ /* 800x600 */
1004 { 64, 61, 1342, 806, 1408, 806 }, /* 1024x768 */
1005 { 0, 0, 0, 0, 0, 0 },
1006 { 1, 1, 1408, 806, 1408, 806 }, /* 1280x768 */
1007 { 0, 0, 0, 0, 0, 0 },
1008 { 16, 15, 1600, 750, 1600, 806 } /* 1280x720 from above */
1009};
1010#endif
1011
1012static const SiS_LCDDataStruct SiS_LCD1280x800Data[] = /* 0.93.12a (TMDS) */
1013{
1014 { 128, 51, 1122, 412, 1408, 816 }, /* 640x400 */
1015 { 128, 49, 1232, 361, 1408, 816 },
1016 { 128, 51, 1122, 412, 1408, 816 },
1017 { 128, 49, 1232, 361, 1408, 816 },
1018 { 8, 3, 880, 491, 1408, 816 }, /* 640x480 */
1019 { 11, 6, 1024, 612, 1408, 816 }, /* 800x600 */
1020 { 22, 21, 1400, 784, 1408, 816 }, /* 1024x768 */
1021 { 0, 0, 0, 0, 0, 0 }, /* 1280x1024 */
1022 { 1, 1, 1408, 816, 1408, 816 }, /* 1280x800 */
1023 { 0, 0, 0, 0, 0, 0 }, /* 1280x768 (patch index) */
1024 { 0, 0, 0, 0, 0, 0 } /* 1280x720 */
1025};
1026
1027static const SiS_LCDDataStruct SiS_LCD1280x800_2Data[] = /* 2.03.00 (LVDS) */
1028{
1029 { 97, 42, 1344, 409, 1552, 812 }, /* 640x400 */
1030 { 97, 35, 1280, 358, 1552, 812 },
1031 { 97, 42, 1344, 409, 1552, 812 },
1032 { 97, 35, 1280, 358, 1552, 812 },
1033 { 97, 39, 1040, 488, 1552, 812 }, /* 640x480 */
1034 { 194, 105, 1120, 608, 1552, 812 }, /* 800x600 */
1035 { 97, 84, 1400, 780, 1552, 812 }, /* 1024x768 */
1036 { 0, 0, 0, 0, 0, 0 }, /* 1280x1024 */
1037 { 1, 1, 1552, 812, 1552, 812 }, /* 1280x800 */
1038 { 97, 96, 1600, 780, 1552, 812 }, /* 1280x768 - patch index */
1039 { 97, 90, 1600, 730, 1552, 812 } /* 1280x720 */
1040};
1041
1042static const SiS_LCDDataStruct SiS_LCD1280x960Data[] =
1043{
1044 { 9, 2, 800, 500, 1800, 1000 },
1045 { 9, 2, 800, 500, 1800, 1000 },
1046 { 4, 1, 900, 500, 1800, 1000 },
1047 { 4, 1, 900, 500, 1800, 1000 },
1048 { 9, 2, 800, 500, 1800, 1000 },
1049 { 30, 11, 1056, 625, 1800, 1000 },
1050 { 5, 3, 1350, 800, 1800, 1000 },
1051 { 1, 1, 1576, 1050, 1576, 1050 },
1052 { 1, 1, 1800, 1000, 1800, 1000 }
1053};
1054
1055static const SiS_LCDDataStruct SiS_StLCD1400x1050Data[] =
1056{
1057 { 211, 100, 2100, 408, 1688, 1066 },
1058 { 211, 64, 1536, 358, 1688, 1066 },
1059 { 211, 100, 2100, 408, 1688, 1066 },
1060 { 211, 64, 1536, 358, 1688, 1066 },
1061 { 211, 48, 840, 488, 1688, 1066 },
1062 { 211, 72, 1008, 609, 1688, 1066 },
1063 { 211, 128, 1400, 776, 1688, 1066 },
1064 { 211, 205, 1680, 1041, 1688, 1066 },
1065 { 1, 1, 1688, 1066, 1688, 1066 }
1066};
1067
1068static const SiS_LCDDataStruct SiS_ExtLCD1400x1050Data[] =
1069{
1070/* { 211, 60, 1260, 410, 1688, 1066 }, 640x400 (6330) */
1071 { 211, 100, 2100, 408, 1688, 1066 }, /* 640x400 (6325) WORKS */
1072 { 211, 64, 1536, 358, 1688, 1066 },
1073 { 211, 100, 2100, 408, 1688, 1066 },
1074 { 211, 64, 1536, 358, 1688, 1066 },
1075/* { 211, 80, 1400, 490, 1688, 1066 }, 640x480 (6330) */
1076 { 211, 48, 840, 488, 1688, 1066 }, /* 640x480 (6325) WORKS */
1077/* { 211, 117, 1638, 613, 1688, 1066 }, 800x600 (6330) */
1078 { 211, 72, 1008, 609, 1688, 1066 }, /* 800x600 (6325) WORKS */
1079 { 211, 128, 1400, 776, 1688, 1066 }, /* 1024x768 */
1080 { 211, 205, 1680, 1041, 1688, 1066 }, /* 1280x1024 - not used (always unscaled) */
1081 { 1, 1, 1688, 1066, 1688, 1066 }, /* 1400x1050 */
1082 { 0, 0, 0, 0, 0, 0 }, /* kludge */
1083 { 211, 120, 1400, 730, 1688, 1066 } /* 1280x720 */
1084};
1085
1086static const SiS_LCDDataStruct SiS_LCD1680x1050Data[] =
1087{
1088 { 95, 24, 1260, 410, 1900, 1066 }, /* 0 640x400 */
1089 { 10, 3, 1710, 362, 1900, 1066 },
1090 { 95, 24, 1260, 410, 1900, 1066 },
1091 { 10, 3, 1710, 362, 1900, 1066 },
1092 { 95, 32, 1400, 490, 1900, 1066 }, /* 4 640x480 */
1093 { 95, 42, 1470, 610, 1900, 1066 }, /* 5 800x600 */
1094 { 95, 64, 1750, 784, 1900, 1066 }, /* 6 1024x768 */
1095 { 95, 94, 1900, 1055, 1900, 1066 }, /* 7 1280x1024 */
1096 { 41, 31, 1900, 806, 1900, 1066 }, /* 8 1280x768 */
1097 { 95, 69, 1800, 817, 1900, 1066 }, /* 9 1280x800 patch index */
1098 { 13, 9, 1900, 739, 1900, 1066 }, /* 10 1280x720 */
1099 { 95, 94, 1880, 1066, 1900, 1066 }, /* 11 1400x1050 patch index */
1100 { 1, 1, 1900, 1066, 1900, 1066 } /* 12 1680x1050 */
1101};
1102
1103static const SiS_LCDDataStruct SiS_StLCD1600x1200Data[] =
1104{
1105 {27, 4, 800, 500, 2160, 1250 },
1106 {27, 4, 800, 500, 2160, 1250 },
1107 { 6, 1, 900, 500, 2160, 1250 },
1108 { 6, 1, 900, 500, 2160, 1250 },
1109 {27, 1, 800, 500, 2160, 1250 },
1110 { 4, 1,1080, 625, 2160, 1250 },
1111 { 5, 2,1350, 800, 2160, 1250 },
1112 {135,88,1600,1100, 2160, 1250 },
1113 {72, 49,1680,1092, 2160, 1250 },
1114 { 1, 1,2160,1250, 2160, 1250 }
1115};
1116
1117static const SiS_LCDDataStruct SiS_ExtLCD1600x1200Data[] =
1118{
1119 {72,11, 990, 422, 2160, 1250 }, /* 640x400 (6330) WORKS */
1120/* {27, 4, 800, 500, 2160, 1250 }, 640x400 (6235) */
1121 {27, 4, 800, 500, 2160, 1250 },
1122 { 6, 1, 900, 500, 2160, 1250 },
1123 { 6, 1, 900, 500, 2160, 1250 },
1124 {45, 8, 960, 505, 2160, 1250 }, /* 640x480 (6330) WORKS */
1125/* {27, 1, 800, 500, 2160, 1250 }, 640x480 (6325) */
1126 { 4, 1,1080, 625, 2160, 1250 },
1127 { 5, 2,1350, 800, 2160, 1250 },
1128 {27,16,1500,1064, 2160, 1250 }, /* 1280x1024 */
1129 {72,49,1680,1092, 2160, 1250 }, /* 1400x1050 (6330, was not supported on 6325) */
1130 { 1, 1,2160,1250, 2160, 1250 }
1131};
1132
1133static const SiS_LCDDataStruct SiS_NoScaleData[] =
1134{
1135 { 1, 1, 800, 449, 800, 449 }, /* 0x00: 320x200, 640x400 */
1136 { 1, 1, 800, 449, 800, 449 },
1137 { 1, 1, 900, 449, 900, 449 },
1138 { 1, 1, 900, 449, 900, 449 },
1139 { 1, 1, 800, 525, 800, 525 }, /* 0x04: 320x240, 640x480 */
1140 { 1, 1,1056, 628,1056, 628 }, /* 0x05: 400x300, 800x600 */
1141 { 1, 1,1344, 806,1344, 806 }, /* 0x06: 512x384, 1024x768 */
1142 { 1, 1,1688,1066,1688,1066 }, /* 0x07: 1280x1024 */
1143 { 1, 1,1688, 802,1688, 802 }, /* 0x08: 1280x768: Fujitsu, TMDS only */
1144 { 1, 1,2160,1250,2160,1250 }, /* 0x09: 1600x1200 */
1145 { 1, 1,1800,1000,1800,1000 }, /* 0x0a: 1280x960 */
1146 { 1, 1,1688,1066,1688,1066 }, /* 0x0b: 1400x1050 */
1147 { 1, 1,1650, 750,1650, 750 }, /* 0x0c: 1280x720 (TMDS, projector) */
1148 { 1, 1,1552, 812,1552, 812 }, /* 0x0d: 1280x800_2 (LVDS) (was: 1408,816/ 1656,841) */
1149 { 1, 1,1900,1066,1900,1066 }, /* 0x0e: 1680x1050 (LVDS) */
1150 { 1, 1,1660, 806,1660, 806 }, /* 0x0f: 1280x768_2 (LVDS) */
1151 { 1, 1,1664, 798,1664, 798 }, /* 0x10: 1280x768_3 (NetVista SiS 301) - TODO */
1152 { 1, 1,1688, 802,1688, 802 }, /* 0x11: 1280x768 (TMDS Fujitsu) */
1153 { 1, 1,1408, 806,1408, 806 }, /* 0x12: 1280x720 (LVDS) */
1154 { 1, 1, 896, 497, 896, 497 }, /* 0x13: 720x480 */
1155 { 1, 1, 912, 597, 912, 597 }, /* 0x14: 720x576 */
1156 { 1, 1, 912, 597, 912, 597 }, /* 0x15: 768x576 */
1157 { 1, 1,1056, 497,1056, 497 }, /* 0x16: 848x480 */
1158 { 1, 1,1064, 497,1064, 497 }, /* 0x17: 856x480 */
1159 { 1, 1,1056, 497,1056, 497 }, /* 0x18: 800x480 */
1160 { 1, 1,1328, 739,1328, 739 }, /* 0x19: 1024x576 */
1161 { 1, 1,1680, 892,1680, 892 }, /* 0x1a: 1152x864 */
1162 { 1, 1,1808, 808,1808, 808 }, /* 0x1b: 1360x768 */
1163 { 1, 1,1104, 563,1104, 563 }, /* 0x1c: 960x540 */
1164 { 1, 1,1120, 618,1120, 618 }, /* 0x1d: 960x600 */
1165 { 1, 1,1408, 816,1408, 816 } /* 0x1f: 1280x800 (TMDS special) */
1166};
1167
1168/**************************************************************/
1169/* LVDS ----------------------------------------------------- */
1170/**************************************************************/
1171
1172static const SiS_LVDSDataStruct SiS_LVDS320x480Data_1[]=
1173{
1174 { 848, 433, 400, 525},
1175 { 848, 389, 400, 525},
1176 { 848, 433, 400, 525},
1177 { 848, 389, 400, 525},
1178 { 848, 518, 400, 525},
1179 {1056, 628, 400, 525},
1180 { 400, 525, 400, 525},
1181 { 800, 449,1000, 644},
1182 { 800, 525,1000, 635}
1183};
1184
1185static const SiS_LVDSDataStruct SiS_LVDS640x480Data_1[]=
1186{
1187 { 800, 445, 800, 525}, /* 800, 449, 800, 449 */
1188 { 800, 395, 800, 525},
1189 { 800, 445, 800, 525},
1190 { 800, 395, 800, 525},
1191 { 800, 525, 800, 525},
1192 { 800, 525, 800, 525}, /* pseudo */
1193 { 800, 525, 800, 525} /* pseudo */
1194};
1195
1196/* FSTN 320x240 */
1197static const SiS_LVDSDataStruct SiS_LVDS640x480Data_2[]=
1198{
1199 { 800, 445, 800, 525},
1200 { 800, 395, 800, 525},
1201 { 800, 445, 800, 525},
1202 { 800, 395, 800, 525},
1203 { 800, 525, 800, 525},
1204 { 800, 525, 800, 525}, /* pseudo */
1205 { 800, 525, 800, 525} /* pseudo */
1206};
1207
1208static const SiS_LVDSDataStruct SiS_LVDS800x600Data_1[]=
1209{
1210 { 848, 433,1060, 629},
1211 { 848, 389,1060, 629},
1212 { 848, 433,1060, 629},
1213 { 848, 389,1060, 629},
1214 { 848, 518,1060, 629},
1215 {1056, 628,1056, 628},
1216 {1056, 628,1056, 628}
1217};
1218
1219static const SiS_LVDSDataStruct SiS_LVDS800x600Data_2[]=
1220{
1221 {1056, 628,1056, 628}
1222};
1223
1224static const SiS_LVDSDataStruct SiS_LVDS1024x768Data_1[]=
1225{
1226 { 840, 438,1344, 806},
1227 { 840, 409,1344, 806},
1228 { 840, 438,1344, 806},
1229 { 840, 409,1344, 806},
1230 { 840, 518,1344, 806}, /* 640x480 */
1231 {1050, 638,1344, 806}, /* 800x600 */
1232 {1344, 806,1344, 806}, /* 1024x768 */
1233};
1234
1235static const SiS_LVDSDataStruct SiS_LVDS1024x768Data_2[]=
1236{
1237 {1344, 806,1344, 806}
1238};
1239
1240static const SiS_LVDSDataStruct SiS_LVDS1280x1024Data_1[]=
1241{
1242 {1048, 442,1688,1066},
1243 {1048, 392,1688,1066},
1244 {1048, 442,1688,1066},
1245 {1048, 392,1688,1066},
1246 {1048, 522,1688,1066},
1247 {1208, 642,1688,1066},
1248 {1432, 810,1688,1066},
1249 {1688,1066,1688,1066}
1250};
1251
1252static const SiS_LVDSDataStruct SiS_LVDS1280x1024Data_2[]=
1253{
1254 {1688,1066,1688,1066}
1255};
1256
1257static const SiS_LVDSDataStruct SiS_LVDS1400x1050Data_1[]=
1258{
1259 { 928, 416, 1688,1066},
1260 { 928, 366, 1688,1066},
1261 { 928, 416, 1688,1066},
1262 { 928, 366, 1688,1066},
1263 { 928, 496, 1688,1066},
1264 {1088, 616, 1688,1066},
1265 {1312, 784, 1688,1066},
1266 {1568,1040, 1688,1066},
1267 {1688,1066, 1688,1066}
1268};
1269
1270static const SiS_LVDSDataStruct SiS_LVDS1400x1050Data_2[]=
1271{
1272 {1688,1066, 1688,1066}
1273};
1274
1275static const SiS_LVDSDataStruct SiS_LVDS1600x1200Data_1[]=
1276{
1277 {1088, 520, 2048,1320},
1278 {1088, 470, 2048,1320},
1279 {1088, 520, 2048,1320},
1280 {1088, 470, 2048,1320},
1281 {1088, 600, 2048,1320},
1282 {1248, 720, 2048,1320},
1283 {1472, 888, 2048,1320},
1284 {1728,1144, 2048,1320},
1285 {1848,1170, 2048,1320},
1286 {2048,1320, 2048,1320}
1287};
1288
1289static const SiS_LVDSDataStruct SiS_LVDS1600x1200Data_2[]=
1290{
1291 {2048,1320, 2048,1320}
1292};
1293
1294static const SiS_LVDSDataStruct SiS_LVDS1280x960Data_1[]=
1295{
1296 { 840, 438,1344, 806},
1297 { 840, 409,1344, 806},
1298 { 840, 438,1344, 806},
1299 { 840, 409,1344, 806},
1300 { 840, 518,1344, 806},
1301 {1050, 638,1344, 806},
1302 {1344, 806,1344, 806},
1303 { 800, 449,1280, 801},
1304 { 800, 525,1280, 813}
1305};
1306
1307static const SiS_LVDSDataStruct SiS_LVDS1280x960Data_2[]=
1308{
1309 {1344, 806,1344, 806}
1310};
1311
1312static const SiS_LVDSDataStruct SiS_LVDS1280x768Data_1[]=
1313{
1314 { 768, 438, 1408, 806},
1315 { 768, 388, 1408, 806},
1316 { 768, 438, 1408, 806},
1317 { 768, 388, 1408, 806},
1318 { 768, 518, 1408, 806},
1319 { 928, 638, 1408, 806},
1320 {1152, 806, 1408, 806},
1321 {1408, 806, 1408, 806},
1322 {1408, 806, 1408, 806}
1323};
1324
1325static const SiS_LVDSDataStruct SiS_LVDS1280x768Data_2[]=
1326{
1327 {1408, 806, 1408, 806}
1328};
1329
1330static const SiS_LVDSDataStruct SiS_LVDS1024x600Data_1[] =
1331{
1332 { 840, 604,1344, 800},
1333 { 840, 560,1344, 800},
1334 { 840, 604,1344, 800},
1335 { 840, 560,1344, 800},
1336 { 840, 689,1344, 800},
1337 {1050, 800,1344, 800},
1338 {1344, 800,1344, 800}
1339};
1340
1341static const SiS_LVDSDataStruct SiS_LVDS1024x600Data_2[] =
1342{
1343 {1344, 800,1344, 800}
1344};
1345
1346static const SiS_LVDSDataStruct SiS_LVDS1152x768Data_1[] =
1347{
1348 { 840, 438,1344, 806},
1349 { 840, 409,1344, 806},
1350 { 840, 438,1344, 806},
1351 { 840, 409,1344, 806},
1352 { 840, 518,1344, 806},
1353 {1050, 638,1344, 806},
1354 {1344, 806,1344, 806}
1355};
1356
1357static const SiS_LVDSDataStruct SiS_LVDS1152x768Data_2[] =
1358{
1359 {1344, 806,1344, 806}
1360};
1361
1362/* Pass 1:1 data */
1363static const SiS_LVDSDataStruct SiS_LVDSXXXxXXXData_1[]=
1364{
1365 { 800, 449, 800, 449},
1366 { 800, 449, 800, 449},
1367 { 900, 449, 900, 449},
1368 { 900, 449, 900, 449},
1369 { 800, 525, 800, 525}, /* 640x480 */
1370 {1056, 628, 1056, 628}, /* 800x600 */
1371 {1344, 806, 1344, 806}, /* 1024x768 */
1372 {1688,1066, 1688,1066}, /* 1280x1024 */ /* INSERTED */
1373 {1688, 806, 1688, 806}, /* 1280x768 */
1374};
1375
1376/* Custom data for Barco iQ R series */
1377static const SiS_LVDSDataStruct SiS_LVDSBARCO1366Data_1[]=
1378{
1379 { 832, 438,1331, 806},
1380 { 832, 388,1331, 806},
1381 { 832, 438,1331, 806},
1382 { 832, 388,1331, 806},
1383 { 832, 518,1331, 806},
1384 {1050, 638,1344, 806},
1385 {1344, 806,1344, 806},
1386 {1688,1066,1688,1066},
1387 {1688,1066,1688,1066} /* 1360x1024 */
1388};
1389
1390/* Custom data for Barco iQ R series */
1391static const SiS_LVDSDataStruct SiS_LVDSBARCO1366Data_2[]=
1392{
1393 {1344, 806,1344, 806},
1394 {1344, 806,1344, 806},
1395 {1344, 806,1344, 806},
1396 {1344, 806,1344, 806},
1397 {1344, 806,1344, 806},
1398 {1344, 806,1344, 806},
1399 {1344, 806,1344, 806},
1400 {1688,1066,1688,1066},
1401 {1688,1066,1688,1066} /* 1360x1024 */
1402};
1403
1404/* Custom data for Barco iQ G series */
1405static const SiS_LVDSDataStruct SiS_LVDSBARCO1024Data_1[]=
1406{
1407 { 832, 438,1331, 806},
1408 { 832, 409,1331, 806},
1409 { 832, 438,1331, 806},
1410 { 832, 409,1331, 806},
1411 { 832, 518,1331, 806}, /* 640x480 */
1412 {1050, 638,1344, 806}, /* 800x600 */
1413 {1344, 806,1344, 806}, /* 1024x768 */
1414};
1415
1416/* Custom data for Barco iQ G series */
1417static const SiS_LVDSDataStruct SiS_LVDSBARCO1024Data_2[]=
1418{
1419 {1344, 806,1344, 806}
1420};
1421
1422/* Custom data for 848x480 parallel panel */
1423static const SiS_LVDSDataStruct SiS_LVDS848x480Data_1[]=
1424{
1425 { 0, 0, 0, 0},
1426 { 0, 0, 0, 0},
1427 { 0, 0, 0, 0},
1428 { 0, 0, 0, 0},
1429 {1088, 525,1088, 525}, /* 640x480 TODO */
1430 {1088, 525,1088, 525}, /* 800x600 TODO */
1431 {1088, 525,1088, 525}, /* 1024x768 TODO */
1432 { 0, 0, 0, 0},
1433 { 0, 0, 0, 0},
1434 { 0, 0, 0, 0},
1435 { 0, 0, 0, 0},
1436 {1088, 525,1088, 525}, /* 848x480 */
1437 {1088, 525,1088, 525} /* 1360x768 TODO */
1438};
1439
1440/* Custom data for 848x480 parallel panel */
1441static const SiS_LVDSDataStruct SiS_LVDS848x480Data_2[]=
1442{
1443 { 0, 0, 0, 0},
1444 { 0, 0, 0, 0},
1445 { 0, 0, 0, 0},
1446 { 0, 0, 0, 0},
1447 {1088, 525,1088, 525}, /* 640x480 */
1448 {1088, 525,1088, 525}, /* 800x600 */
1449 {1088, 525,1088, 525}, /* 1024x768 */
1450 { 0, 0, 0, 0},
1451 { 0, 0, 0, 0},
1452 { 0, 0, 0, 0},
1453 { 0, 0, 0, 0},
1454 {1088, 525,1088, 525}, /* 848x480 */
1455 {1088, 525,1088, 525} /* 1360x768 TODO */
1456};
1457
1458static const SiS_LVDSDataStruct SiS_CHTVUNTSCData[]=
1459{
1460 { 840, 600, 840, 600},
1461 { 840, 600, 840, 600},
1462 { 840, 600, 840, 600},
1463 { 840, 600, 840, 600},
1464 { 784, 600, 784, 600},
1465 {1064, 750,1064, 750},
1466 {1160, 945,1160, 945}
1467};
1468
1469static const SiS_LVDSDataStruct SiS_CHTVONTSCData[]=
1470{
1471 { 840, 525, 840, 525},
1472 { 840, 525, 840, 525},
1473 { 840, 525, 840, 525},
1474 { 840, 525, 840, 525},
1475 { 784, 525, 784, 525},
1476 {1040, 700,1040, 700},
1477 {1160, 840,1160, 840}
1478};
1479
1480/* Chrontel TV Skew */
1481
1482static const SiS_LVDSDesStruct SiS_CHTVUNTSCDesData[]=
1483{
1484 { 0, 0},
1485 { 0, 0},
1486 { 0, 0},
1487 { 0, 0},
1488 { 0, 0},
1489 { 0, 0},
1490 { 0, 0}
1491};
1492
1493static const SiS_LVDSDesStruct SiS_CHTVONTSCDesData[]=
1494{
1495 { 0, 0},
1496 { 0, 0},
1497 { 0, 0},
1498 { 0, 0},
1499 { 0, 0},
1500 { 0, 0},
1501 { 0, 0}
1502};
1503
1504static const SiS_LVDSDesStruct SiS_CHTVUPALDesData[]=
1505{
1506 {256, 0},
1507 {256, 0},
1508 {256, 0},
1509 {256, 0},
1510 { 0, 0},
1511 { 0, 0},
1512 { 0, 0}
1513};
1514
1515static const SiS_LVDSDesStruct SiS_CHTVOPALDesData[]=
1516{
1517 {256, 0},
1518 {256, 0},
1519 {256, 0},
1520 {256, 0},
1521 { 0, 0},
1522 { 0, 0},
1523 { 0, 0}
1524};
1525
1526/* CRT1 CRTC data for slave modes */
1527
1528static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1320x480_1[] =
1529{
1530 {{0x65,0x4f,0x89,0x56,0x83,0xaa,0x1f,
1531 0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
1532 0x00 }},
1533 {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
1534 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
1535 0x00 }},
1536 {{0x65,0x4f,0x89,0x54,0x9f,0xc4,0x1f,
1537 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
1538 0x00 }},
1539 {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
1540 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
1541 0x00 }},
1542 {{0x65,0x4f,0x89,0x56,0x83,0x04,0x3e,
1543 0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
1544 0x00 }},
1545 {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
1546 0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
1547 0x01 }},
1548 {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e,
1549 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
1550 0x00 }}
1551};
1552
1553static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1640x480_1[] =
1554{
1555 {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
1556 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
1557 0x00}},
1558 {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
1559 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
1560 0x00}},
1561 {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
1562 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
1563 0x00}},
1564 {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
1565 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
1566 0x00}},
1567 {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
1568 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
1569 0x00}},
1570 {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
1571 0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
1572 0x01}}
1573};
1574
1575static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1640x480_1_H[] =
1576{
1577 {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
1578 0x9c,0x8e,0x96,0xb9,0x00,0x00,0x00,
1579 0x00}},
1580 {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
1581 0x83,0x85,0x63,0xba,0x00,0x00,0x00,
1582 0x00}},
1583 {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
1584 0x9c,0x8e,0x96,0xb9,0x00,0x00,0x00,
1585 0x00}},
1586 {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
1587 0x83,0x85,0x63,0xba,0x00,0x00,0x00,
1588 0x00}},
1589 {{0x2d,0x28,0x90,0x2c,0x80,0x0b,0x3e,
1590 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
1591 0x00}}
1592};
1593
1594static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1640x480_2[] =
1595{
1596 {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
1597 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
1598 0x00}},
1599 {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
1600 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
1601 0x00}},
1602 {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
1603 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
1604 0x00}},
1605 {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
1606 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
1607 0x00}},
1608 {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
1609 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
1610 0x00}},
1611 {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
1612 0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
1613 0x01}},
1614 {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e,
1615 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
1616 0x00}}
1617};
1618
1619static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1640x480_2_H[] =
1620{
1621 {{0x65,0x4f,0x89,0x56,0x83,0xaa,0x1f,
1622 0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
1623 0x00}},
1624 {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
1625 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
1626 0x00}},
1627 {{0x65,0x4f,0x89,0x54,0x9f,0xc4,0x1f,
1628 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
1629 0x00}},
1630 {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
1631 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
1632 0x00}},
1633 {{0x65,0x4f,0x89,0x56,0x83,0x04,0x3e,
1634 0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
1635 0x00}},
1636 {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
1637 0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
1638 0x01}},
1639 {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e,
1640 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
1641 0x00}}
1642};
1643
1644static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1640x480_3[] =
1645{
1646 {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
1647 0xe9,0x8b,0xdf,0x04,0x00,0x00,0x05,
1648 0x00}},
1649 {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
1650 0xe9,0x8b,0xdf,0x04,0x00,0x00,0x05,
1651 0x00}},
1652 {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
1653 0xe9,0x8b,0xdf,0x04,0x00,0x00,0x05,
1654 0x00}},
1655 {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
1656 0xe9,0x8b,0xdf,0x04,0x00,0x00,0x05,
1657 0x00}},
1658 {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
1659 0xe9,0x8b,0xdf,0x04,0x00,0x00,0x05,
1660 0x00}},
1661 {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
1662 0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
1663 0x01}},
1664 {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e,
1665 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
1666 0x00}}
1667};
1668
1669static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1640x480_3_H[] =
1670{
1671 {{0x65,0x4f,0x89,0x56,0x83,0xaa,0x1f,
1672 0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
1673 0x00}},
1674 {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
1675 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
1676 0x00}},
1677 {{0x65,0x4f,0x89,0x54,0x9f,0xc4,0x1f,
1678 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
1679 0x00}},
1680 {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
1681 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
1682 0x00}},
1683 {{0x65,0x4f,0x89,0x56,0x83,0x04,0x3e,
1684 0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
1685 0x00}},
1686 {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
1687 0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
1688 0x01}},
1689 {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e,
1690 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
1691 0x00}}
1692};
1693
1694static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11024x600_1[] =
1695{
1696 {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e,
1697 0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01,
1698 0x00}},
1699 {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e,
1700 0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01,
1701 0x00}},
1702 {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e,
1703 0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01,
1704 0x00}},
1705 {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e,
1706 0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01,
1707 0x00}},
1708 {{0x64,0x4f,0x88,0x54,0x9f,0xaf,0xba,
1709 0x3b,0x82,0xdf,0xb0,0x00,0x00,0x01,
1710 0x00}},
1711 {{0x7e,0x63,0x82,0x68,0x15,0x1e,0xf1,
1712 0xae,0x85,0x57,0x1f,0x30,0x00,0x26,
1713 0x01}},
1714 {{0xa3,0x7f,0x87,0x86,0x97,0x1e,0xf1,
1715 0xae,0x85,0x57,0x1f,0x30,0x00,0x02,
1716 0x01}}
1717};
1718
1719static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11024x600_1_H[] =
1720{
1721 {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
1722 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
1723 0x00}},
1724 {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
1725 0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
1726 0x00}},
1727 {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
1728 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
1729 0x00}},
1730 {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
1731 0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
1732 0x00}},
1733 {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
1734 0xe2,0x89,0xdf,0x05,0x00,0x00,0x44,
1735 0x00}},
1736 {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
1737 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
1738 0x01}},
1739 {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
1740 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
1741 0x01}}
1742};
1743
1744static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11024x600_2[] =
1745{
1746 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1747 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
1748 0x00}},
1749 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1750 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
1751 0x00}},
1752 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1753 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
1754 0x00}},
1755 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1756 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
1757 0x00}},
1758 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1759 0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
1760 0x00}},
1761 {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
1762 0xae,0x84,0x57,0x25,0x30,0x00,0x02,
1763 0x01}},
1764 {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
1765 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
1766 0x01}}
1767};
1768
1769static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11024x600_2_H[] =
1770{
1771 {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
1772 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
1773 0x00}},
1774 {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
1775 0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
1776 0x00}},
1777 {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
1778 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
1779 0x00}},
1780 {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
1781 0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
1782 0x00}},
1783 {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
1784 0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
1785 0x00}},
1786 {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
1787 0xae,0x84,0x57,0x25,0x30,0x00,0x01,
1788 0x01}},
1789 {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
1790 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
1791 0x01}}
1792};
1793
1794static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11152x768_1[] =
1795{
1796 {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
1797 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
1798 0x00}},
1799 {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
1800 0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
1801 0x00}},
1802 {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
1803 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
1804 0x00}},
1805 {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
1806 0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
1807 0x00}},
1808 {{0x64,0x4f,0x88,0x54,0x9f,0x04,0x3e,
1809 0xe2,0x89,0xdf,0x05,0x00,0x00,0x01,
1810 0x00}},
1811 {{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0,
1812 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26,
1813 0x01}},
1814 {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
1815 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
1816 0x01}}
1817};
1818
1819static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11152x768_1_H[] =
1820{
1821 {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
1822 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
1823 0x00}},
1824 {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
1825 0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
1826 0x00}},
1827 {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
1828 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
1829 0x00}},
1830 {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
1831 0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
1832 0x00}},
1833 {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
1834 0xe2,0x89,0xdf,0x05,0x00,0x00,0x44,
1835 0x00}},
1836 {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
1837 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
1838 0x01}},
1839 {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
1840 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
1841 0x01}}
1842};
1843
1844static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11152x768_2[] =
1845{
1846 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1847 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
1848 0x00}},
1849 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1850 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
1851 0x00}},
1852 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1853 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
1854 0x00}},
1855 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1856 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
1857 0x00}},
1858 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1859 0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
1860 0x00}},
1861 {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
1862 0xae,0x84,0x57,0x25,0x30,0x00,0x02,
1863 0x01}},
1864 {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
1865 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
1866 0x01}}
1867};
1868
1869static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11152x768_2_H[] =
1870{
1871 {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
1872 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
1873 0x00}},
1874 {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
1875 0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
1876 0x00}},
1877 {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
1878 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
1879 0x00}},
1880 {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
1881 0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
1882 0x00}},
1883 {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
1884 0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
1885 0x00}},
1886 {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
1887 0xae,0x84,0x57,0x25,0x30,0x00,0x01,
1888 0x01}},
1889 {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
1890 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
1891 0x01}}
1892};
1893
1894static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11280x768_1[] =
1895{
1896 {{0x5b,0x4f,0x9f,0x55,0x19,0xb4,0x1f,
1897 0x9c,0x8e,0x8f,0xb5,0x10,0x00,0x01,
1898 0x00}},
1899 {{0x5b,0x4f,0x9f,0x55,0x19,0x82,0x1f,
1900 0x6a,0x8c,0x5d,0x83,0x30,0x00,0x01,
1901 0x00}},
1902 {{0x5b,0x4f,0x9f,0x55,0x19,0xb4,0x1f,
1903 0x9c,0x8e,0x8f,0xb5,0x10,0x00,0x01,
1904 0x00}},
1905 {{0x5b,0x4f,0x9f,0x55,0x19,0x82,0x1f,
1906 0x6a,0x8c,0x5d,0x83,0x30,0x00,0x01,
1907 0x00}},
1908 {{0x5b,0x4f,0x9f,0x55,0x19,0x04,0x3e,
1909 0xec,0x8e,0xdf,0x05,0x20,0x00,0x01,
1910 0x00}},
1911 {{0x6f,0x63,0x93,0x69,0x8d,0x7c,0xf0,
1912 0x64,0x86,0x57,0x7d,0x20,0x00,0x05,
1913 0x01}},
1914 {{0x8b,0x7f,0x8f,0x85,0x09,0x24,0xf5,
1915 0x0c,0x8e,0xff,0x25,0x30,0x00,0x02,
1916 0x01}},
1917 {{0xab,0x9f,0x8f,0xa5,0x89,0x24,0xf5,
1918 0x0c,0x8e,0xff,0x25,0x30,0x00,0x06,
1919 0x01}},
1920 {{0xab,0x9f,0x8f,0xa5,0x89,0x24,0xf5,
1921 0x0c,0x8e,0xff,0x25,0x30,0x00,0x06,
1922 0x01}}
1923};
1924
1925static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11280x768_1_H[] =
1926{
1927 {{0x47,0x27,0x8b,0x2c,0x1a,0x9e,0x1f,
1928 0x93,0x86,0x8f,0x9f,0x30,0x00,0x05,
1929 0x00}},
1930 {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
1931 0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
1932 0x00}},
1933 {{0x47,0x27,0x8b,0x30,0x1e,0x9e,0x1f,
1934 0x92,0x86,0x8f,0x9f,0x30,0x00,0x05,
1935 0x00}},
1936 {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
1937 0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
1938 0x00}},
1939 {{0x47,0x27,0x8b,0x2c,0x1a,0xee,0x1f,
1940 0xe2,0x86,0xdf,0xef,0x10,0x00,0x05,
1941 0x00}},
1942 {{0x51,0x31,0x95,0x36,0x04,0x66,0xf0,
1943 0x5a,0x8e,0x57,0x67,0x20,0x00,0x01,
1944 0x01}},
1945 {{0x5f,0x3f,0x83,0x44,0x92,0x0e,0xf5,
1946 0x02,0x86,0xff,0x0f,0x10,0x00,0x01,
1947 0x01}},
1948 {{0x6f,0x4f,0x93,0x54,0x82,0x0e,0x5a,
1949 0x02,0x86,0xff,0x0f,0x09,0x00,0x05,
1950 0x01}},
1951 {{0x6f,0x4f,0x93,0x54,0x82,0x0e,0x5a,
1952 0x02,0x86,0xff,0x0f,0x09,0x00,0x05,
1953 0x01}}
1954};
1955
1956static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11280x768_2[] =
1957{
1958 {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
1959 0x54,0x86,0xdb,0xda,0x00,0x00,0x02,
1960 0x00}},
1961 {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
1962 0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x02,
1963 0x00}},
1964 {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
1965 0x54,0x86,0xdb,0xda,0x00,0x00,0x02,
1966 0x00}},
1967 {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
1968 0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x02,
1969 0x00}},
1970 {{0xab,0x60,0x9f,0x80,0x04,0x24,0xb3,
1971 0x7c,0x8e,0x03,0x02,0x10,0x00,0x02,
1972 0x01}},
1973 {{0xab,0x63,0x8f,0x8a,0x8e,0x24,0xf1,
1974 0xb6,0x88,0x57,0x25,0x10,0x00,0x02,
1975 0x01}},
1976 {{0xab,0x7f,0x8f,0x98,0x9c,0x24,0xf5,
1977 0x0a,0x8c,0xff,0x25,0x30,0x00,0x02,
1978 0x01}},
1979 {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
1980 0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
1981 0x01}},
1982 {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
1983 0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
1984 0x01}}
1985};
1986
1987static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11280x768_2_H[] =
1988{
1989 {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
1990 0x54,0x86,0xdb,0xda,0x00,0x00,0x01,
1991 0x00}},
1992 {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
1993 0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x01,
1994 0x00}},
1995 {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
1996 0x54,0x86,0xdb,0xda,0x00,0x00,0x01,
1997 0x00}},
1998 {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
1999 0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x01,
2000 0x00}},
2001 {{0x83,0x38,0x97,0x58,0x9c,0x24,0xb3,
2002 0x7c,0x8e,0x03,0x02,0x10,0x00,0x01,
2003 0x01}},
2004 {{0x79,0x31,0x9d,0x58,0x9c,0x24,0xf1,
2005 0xb6,0x88,0x57,0x25,0x10,0x00,0x01,
2006 0x01}},
2007 {{0x6b,0x3f,0x8f,0x58,0x9c,0x24,0xf5,
2008 0x0a,0x8c,0xff,0x25,0x30,0x00,0x01,
2009 0x01}},
2010 {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
2011 0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
2012 0x01}},
2013 {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
2014 0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
2015 0x01}}
2016};
2017
2018/**************************************************************/
2019/* COMMON --------------------------------------------------- */
2020/**************************************************************/
2021
2022#ifdef LINUX_XF86
2023
2024#define SIS_PL_HSYNCP 0x01
2025#define SIS_PL_HSYNCN 0x02
2026#define SIS_PL_VSYNCP 0x04
2027#define SIS_PL_VSYNCN 0x08
2028#define SIS_PL_DVI 0x80
2029
2030typedef struct _SiS_PlasmaModes
2031{
2032 const char *name;
2033 ULONG clock;
2034 USHORT HDisplay, HTotal, HFrontPorch, HSyncWidth;
2035 USHORT VDisplay, VTotal, VFrontPorch, VSyncWidth;
2036 UCHAR SyncFlags;
2037} SiS_PlasmaModes;
2038
2039typedef struct _SiS_PlasmaTables
2040{
2041 USHORT vendor;
2042 UCHAR productnum;
2043 USHORT product[5];
2044 const char *DDCnames[5];
2045 const char *plasmaname;
2046 USHORT maxx,maxy;
2047 USHORT prefx, prefy;
2048 UCHAR modenum;
2049 UCHAR plasmamodes[20]; /* | 0x80 = DVI-capable, | 0x40 = analog */
2050} SiS_PlasmaTables;
2051
2052static const SiS_PlasmaModes SiS_PlasmaMode[] = {
2053 { "640x400", /* 00: IBM 400@70 */
2054 25175,
2055 640, 800, 17, 64,
2056 400, 449, 13, 2,
2057 SIS_PL_HSYNCN | SIS_PL_VSYNCN },
2058 { "640x480", /* 01: VESA 480@72 */
2059 31500,
2060 640, 832, 24, 40,
2061 480, 520, 9, 3,
2062 SIS_PL_HSYNCN | SIS_PL_VSYNCN },
2063 { "800x600", /* 02: VESA 600@72 */
2064 50000,
2065 800, 1040, 56, 120,
2066 600, 666, 37, 6,
2067 SIS_PL_HSYNCP | SIS_PL_VSYNCP },
2068 { "864x480", /* 03: Cereb wide 1 */
2069 42526,
2070 864, 1134, 22, 86,
2071 480, 500, 1, 3,
2072 SIS_PL_HSYNCP | SIS_PL_VSYNCN },
2073 { "848x480", /* 04: VESA wide (NEC1) */
2074 33750,
2075 848, 1088, 16, 112,
2076 480, 517, 6, 8,
2077 SIS_PL_HSYNCP | SIS_PL_VSYNCP },
2078 { "1024x576", /* 05: VESA wide (NEC2) */
2079 47250,
2080 1024, 1320, 16, 144,
2081 576, 596, 2, 4,
2082 SIS_PL_HSYNCP | SIS_PL_VSYNCP },
2083 { "1280x720", /* 06: VESA wide (NEC3) */
2084 76500,
2085 1280, 1696, 48, 176,
2086 720, 750, 4, 8,
2087 SIS_PL_HSYNCP | SIS_PL_VSYNCP },
2088 { "1360x765", /* 07: VESA wide (NEC4) */
2089 85500,
2090 1360, 1792, 64, 176,
2091 765, 795, 4, 8,
2092 SIS_PL_HSYNCP | SIS_PL_VSYNCP },
2093 { "1024x600", /* 08: CEREB wide 2 */
2094 51200,
2095 1024, 1352, 51, 164,
2096 600, 628, 1, 4,
2097 SIS_PL_HSYNCN | SIS_PL_VSYNCP },
2098 { "1024x768", /* 09: VESA 768@75 */
2099 78750,
2100 1024, 1312, 16, 96,
2101 768, 800, 1, 3,
2102 SIS_PL_HSYNCP | SIS_PL_VSYNCP },
2103 { "1152x864", /* 10: VESA 1152x864@75 */
2104 108000,
2105 1152, 1600, 64, 128,
2106 864, 900, 1, 3,
2107 SIS_PL_HSYNCP | SIS_PL_VSYNCP },
2108 { "1280x1024", /* 11: VESA 1024@60 */
2109 108000,
2110 1280, 1688, 48, 112,
2111 1024, 1066, 1, 3,
2112 SIS_PL_HSYNCP | SIS_PL_VSYNCP },
2113 { "1280x768", /* 12: W_XGA */
2114 81000,
2115 1280, 1688, 48, 112,
2116 768, 802, 3, 6,
2117 SIS_PL_HSYNCP | SIS_PL_VSYNCN },
2118 { "1280x768", /* 13: I/O Data W_XGA@56Hz */
2119 76064,
2120 1280, 1688, 48, 112,
2121 768, 802, 2, 3,
2122 SIS_PL_HSYNCP | SIS_PL_VSYNCP },
2123 { "1376x768", /* 14: I/O Wide XGA */
2124 87340,
2125 1376, 1808, 32, 128,
2126 768, 806, 3, 6,
2127 SIS_PL_HSYNCN | SIS_PL_VSYNCP },
2128 { "1280x960", /* 15: VESA 960@60 */
2129 108000,
2130 1280, 1800, 96, 112,
2131 960, 1000, 1, 3,
2132 SIS_PL_HSYNCP | SIS_PL_VSYNCP },
2133 { "1400x1050", /* 16: VESA 1050@60Hz */
2134 108000,
2135 1400, 1688, 48, 112,
2136 1050, 1066, 1, 3,
2137 SIS_PL_HSYNCN | SIS_PL_VSYNCN },
2138 { "1360x768", /* 17: VESA wide (NEC4/2) */
2139 85500,
2140 1360, 1792, 64, 112,
2141 765, 795, 3, 6,
2142 SIS_PL_HSYNCP | SIS_PL_VSYNCP },
2143 { "800x600", /* 18: VESA 600@56 */
2144 36000,
2145 800, 1024, 24, 2,
2146 600, 625, 1, 2,
2147 SIS_PL_HSYNCP | SIS_PL_VSYNCP },
2148 { "1072x600", /* 19: Panasonic 1072x600 (sync?) */
2149 54100,
2150 1072, 1424, 48, 176,
2151 600, 628, 16, 1,
2152 SIS_PL_HSYNCP | SIS_PL_VSYNCP },
2153 { "848x480", /* 20: Panasonic 848x480 (sync?) */
2154 33070, /* is 852x480, but we can't use 852 */
2155 848, 1068, 20, 40, /* differs from DDC data, better centered */
2156 480, 516, 3, 5, /* won't work assumingly, because data is % 8 */
2157 SIS_PL_HSYNCN | SIS_PL_VSYNCN },
2158 { "1280x720", /* 21: WIDE720(60) (aka "750p") (Panasonic) */
2159 74300,
2160 1280, 1650,110, 40,
2161 720, 750, 5, 5,
2162 SIS_PL_HSYNCP | SIS_PL_VSYNCP },
2163 { "1280x768", /* 22: 1280x768@56.5 (Panasonic) */
2164 76200, /* (According to manual not supported for HDMI; but works) */
2165 1280, 1680, 16, 24,
2166 768, 802, 2, 5,
2167 SIS_PL_HSYNCP | SIS_PL_VSYNCP },
2168 { "1280x720@50", /* 23: WIDE720(50) (aka "750p") (Panasonic) */
2169 74300, /* Panasonic states 45.0kHz. Not possible. This one works (with some overscan) */
2170 1280, 1980,400, 80,
2171 720, 750, 1, 2,
2172 SIS_PL_HSYNCP | SIS_PL_VSYNCP },
2173 { "720x480", /* 24: 720x480 (aka "525p" and "480p") (Panasonic) */
2174 27000,
2175 720, 856, 40, 32,
2176 480, 525, 1, 3,
2177 SIS_PL_HSYNCP | SIS_PL_VSYNCP },
2178 { "720x576", /* 25: 720x576 (aka "625p"and "576p") (Panasonic) */
2179 27500,
2180 720, 864, 16, 64,
2181 576, 625, 5, 6,
2182 SIS_PL_HSYNCP | SIS_PL_VSYNCP },
2183 { "1280x720@50", /* 26: WIDE720(50) (aka "750p") (Generic) */
2184 74300,
2185 1280, 1980,400, 80,
2186 720, 750, 5, 5,
2187 SIS_PL_HSYNCP | SIS_PL_VSYNCP },
2188};
2189
2190/*
219127.00 720 755 791 858 480 480 484 525
219227.50 720 732 795 864 576 581 587 625
2193*/
2194
2195static const SiS_PlasmaTables SiS_PlasmaTable[] = {
2196#if 0 /* Product IDs missing */
2197 { 0x38a3, 4,
2198 { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
2199 { "", "", "", "", "" },
2200 "NEC PlasmaSync 42VP4/42VP4D/42VP4G/42VP4DG",
2201 0, 0,
2202 0, 0,
2203 11, /* All DVI, except 0, 7, 13 */
2204 { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 7|0x40, 9|0xc0,10|0xc0,11|0xc0,13|0x40,14|0xc0,
2205 17|0xc0, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
2206 },
2207#endif
2208#if 0 /* Product IDs missing */
2209 { 0x38a3, 3,
2210 { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
2211 { "", "", "", "", "" },
2212 "NEC PlasmaSync 42PD1/50PD1/50PD2",
2213 0, 0,
2214 0, 0,
2215 5, /* DVI entirely unknown */
2216 { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 9|0xc0, 0 , 0 , 0 , 0 , 0 ,
2217 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
2218 },
2219 { 0x38a3, 1,
2220 { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
2221 { "", "", "", "", "" },
2222 "NEC PlasmaSync 42PD3",
2223 0, 0,
2224 0, 0,
2225 10, /* DVI entirely unknown */
2226 { 0|0x40, 1|0xc0, 2|0xc0, 3|0xc0, 4|0xc0, 5|0xc0, 6|0xc0, 7|0x40, 8|0xc0, 9|0xc0,
2227 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
2228 },
2229 { 0x38a3, 2,
2230 { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
2231 { "", "", "", "", "" },
2232 "NEC PlasmaSync 42VM3/61XM1",
2233 0, 0,
2234 0, 0,
2235 11, /* DVI entirely unknown */
2236 { 0|0x40, 1|0xc0, 2|0xc0, 3|0xc0, 4|0xc0, 5|0xc0, 6|0xc0, 8|0xc0, 9|0xc0,11|0xc0,
2237 17|0xc0, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
2238 },
2239 { 0x38a3, 2,
2240 { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
2241 { "", "", "", "", "" },
2242 "NEC PlasmaSync 42MP1/42MP2",
2243 0, 0,
2244 0, 0,
2245 6, /* DVI entirely unknown */
2246 { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 9|0xc0,11|0xc0, 0 , 0 , 0 , 0 ,
2247 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
2248 },
2249 { 0x38a3, 1,
2250 { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
2251 { "", "", "", "", "" },
2252 "NEC PlasmaSync 50MP1",
2253 0, 0,
2254 0, 0,
2255 10, /* DVI entirely unknown */
2256 { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 7|0x40, 9|0xc0,10|0xc0,11|0xc0,13|0x40,14|0xc0,
2257 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
2258 },
2259#endif
2260 { 0x38a3, 4,
2261 { 0xa482, 0xa483, 0x0000, 0x0000, 0x0000 },
2262 { "PX-42VM", "", "", "", "" },
2263 "NEC PlasmaSync 42MP3/42MP4/50MP2/61MP1",
2264 0, 0,
2265 0, 0,
2266 11, /* All DVI except 0, 7, 13, 17 */
2267 { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 7|0x40, 9|0xc0,10|0xc0,11|0xc0,13|0x40,14|0xc0,
2268 17|0x40, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
2269 },
2270#if 0 /* Product IDs missing */
2271 { 0x38a3, 1,
2272 { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
2273 { "", "", "", "", "" },
2274 "NEC PlasmaSync 3300W",
2275 0, 0,
2276 0, 0,
2277 3,
2278 { 0|0x40, 1|0xc0,18|0xc0, 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
2279 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
2280 },
2281 { 0x38a3, 1,
2282 { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
2283 { "", "", "", "", "" },
2284 "NEC PlasmaSync 4200W",
2285 4, /* DVI entirely unknown */
2286 { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 0 , 0 , 0 , 0 , 0 , 0 ,
2287 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
2288 },
2289 { 0x38a3, 1,
2290 { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
2291 { "", "", "", "", "" },
2292 "NEC PlasmaSync 4210W",
2293 0, 0,
2294 0, 0,
2295 6, /* DVI entirely unknown */
2296 { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 9|0xc0,11|0xc0, 0 , 0 , 0 , 0 ,
2297 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
2298 },
2299 { 0x38a3, 1,
2300 { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
2301 { "", "", "", "", "" },
2302 "NEC PlasmaSync 5000W",
2303 0, 0,
2304 0, 0,
2305 7, /* DVI entirely unknown */
2306 { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 7|0x40, 9|0xc0,11|0xc0, 0 , 0 , 0 ,
2307 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
2308 },
2309#endif
2310 { 0x412f, 2,
2311 { 0x000c, 0x000b, 0x0000, 0x0000, 0x0000 },
2312 { "", "", "", "", "" },
2313 "Pioneer 503CMX/PDA-5002",
2314 0, 0,
2315 0, 0,
2316 6, /* DVI unknown */
2317 { 1|0xc0, 2|0xc0, 9|0xc0,11|0xc0,12|0xc0,15|0xc0, 0 , 0 , 0 , 0 ,
2318 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
2319 },
2320 { 0x34a9, 1,
2321 { 0xa00e, 0x0000, 0x0000, 0x0000, 0x0000 },
2322 { "", "", "", "", "" },
2323 "Panasonic TH-42",
2324 0, 0,
2325 0, 0,
2326 5, /* No DVI output */
2327 { 1|0x40, 2|0x40, 4|0x40, 9|0x40,15|0x40, 0 , 0 , 0 , 0 , 0 ,
2328 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
2329 },
2330 { 0x34a9, 1,
2331 { 0xa005, 0x0000, 0x0000, 0x0000, 0x0000 },
2332 { "TH-42PW*4", "", "", "", "" },
2333 "Panasonic TH-42PW5",
2334 0, 0,
2335 0, 0,
2336 1, /* No special modes otherwise; no DVI. */
2337 {20|0x40,19|0x40, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
2338 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
2339 },
2340 { 0x4c2e, 1,
2341 { 0x9b05, 0x0000, 0x0000, 0x0000, 0x0000 },
2342 { "PLV-Z2", "", "", "", "" },
2343 "Sanyo PLV-Z2 (non HDCP-mode)", /* HDCP mode would be id 9b06, but not needed */
2344 1280, 768, /* as it then advertises correct size */
2345 1280, 720,
2346 1, /* 1280x720, no special modes otherwise */
2347 {21|0xc0, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
2348 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
2349 },
2350 { 0x34a9, 1,
2351 { 0xd034, 0x0000, 0x0000, 0x0000, 0x0000 },
2352 { "AE500U (DVI-D)", "", "", "", "" },
2353 "Panasonic AE500U",
2354 1280, 768,
2355 1280, 720,
2356 1, /* 1280x720, no special modes otherwise */
2357 {21|0xc0, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
2358 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
2359 },
2360 { 0x34a9, 1,
2361 { 0xd043, 0x0000, 0x0000, 0x0000, 0x0000 },
2362 { "AE700U (HDMI)", "", "", "", "" },
2363 "Panasonic AE700U",
2364 1360, 768,
2365 1280, 720,
2366 6, /* 1280x720/60, 1280x720/50, 1280x768@56(digital/analog), 720x480, 720x576 */
2367 {21|0xc0,23|0xc0,22|0x80,13|0x40,24|0x80,25|0x80, 0 , 0 , 0 , 0 ,
2368 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
2369 },
2370 { 0x0000 }
2371};
2372#endif
2373
2374#ifdef LINUX_XF86
2375USHORT SiS_GetModeID(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay,
2376 int Depth, BOOLEAN FSTN, int LCDwith, int LCDheight);
2377#endif
2378USHORT SiS_GetModeID_LCD(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth, BOOLEAN FSTN,
2379 USHORT CustomT, int LCDwith, int LCDheight);
2380USHORT SiS_GetModeID_TV(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth);
2381USHORT SiS_GetModeID_VGA2(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth);
2382
2383void SiS_SetReg(SISIOADDRESS port, USHORT index, USHORT data);
2384void SiS_SetRegByte(SISIOADDRESS port, USHORT data);
2385void SiS_SetRegShort(SISIOADDRESS port, USHORT data);
2386void SiS_SetRegLong(SISIOADDRESS port, ULONG data);
2387UCHAR SiS_GetReg(SISIOADDRESS port, USHORT index);
2388UCHAR SiS_GetRegByte(SISIOADDRESS port);
2389USHORT SiS_GetRegShort(SISIOADDRESS port);
2390ULONG SiS_GetRegLong(SISIOADDRESS port);
2391void SiS_SetRegANDOR(SISIOADDRESS Port, USHORT Index, USHORT DataAND, USHORT DataOR);
2392void SiS_SetRegAND(SISIOADDRESS Port,USHORT Index, USHORT DataAND);
2393void SiS_SetRegOR(SISIOADDRESS Port,USHORT Index, USHORT DataOR);
2394void SiS_DisplayOn(SiS_Private *SiS_Pr);
2395void SiS_DisplayOff(SiS_Private *SiS_Pr);
2396void SiSRegInit(SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr);
2397void SiSSetLVDSetc(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
2398BOOLEAN SiSDetermineROMLayout661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
2399void SiS_SetEnableDstn(SiS_Private *SiS_Pr, int enable);
2400void SiS_SetEnableFstn(SiS_Private *SiS_Pr, int enable);
2401void SiS_GetVBType(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
2402BOOLEAN SiS_SearchModeID(SiS_Private *SiS_Pr, USHORT *ModeNo, USHORT *ModeIdIndex);
2403UCHAR SiS_GetModePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex);
2404USHORT SiS_GetColorDepth(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex);
2405USHORT SiS_GetOffset(SiS_Private *SiS_Pr,USHORT ModeNo, USHORT ModeIdIndex,
2406 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo);
2407void SiS_LoadDAC(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo, USHORT ModeIdIndex);
2408void SiS_CalcLCDACRT1Timing(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex);
2409
2410#ifdef LINUX_XF86
2411BOOLEAN SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,ScrnInfoPtr pScrn,USHORT ModeNo, BOOLEAN dosetpitch);
2412BOOLEAN SiSBIOSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
2413 DisplayModePtr mode, BOOLEAN IsCustom);
2414BOOLEAN SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
2415 DisplayModePtr mode, BOOLEAN IsCustom);
2416BOOLEAN SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
2417 DisplayModePtr mode, BOOLEAN IsCustom);
2418int SiSTranslateToVESA(ScrnInfoPtr pScrn, int modenumber);
2419int SiSTranslateToOldMode(int modenumber);
2420BOOLEAN SiS_GetPanelID(SiS_Private *SiS_Pr, PSIS_HW_INFO);
2421USHORT SiS_CheckBuildCustomMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int VBFlags);
2422DisplayModePtr SiSBuildBuiltInModeList(ScrnInfoPtr pScrn, BOOLEAN includelcdmodes, BOOLEAN isfordvi);
2423int SiS_FindPanelFromDB(SISPtr pSiS, USHORT panelvendor, USHORT panelproduct, int *maxx, int *maxy, int *prefx, int *prefy);
2424void SiS_MakeClockRegs(ScrnInfoPtr pScrn, int clock, UCHAR *p2b, UCHAR *p2c);
2425#else
2426BOOLEAN SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,USHORT ModeNo);
2427#endif
2428
2429#ifdef LINUX_KERNEL
2430int sisfb_mode_rate_to_dclock(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
2431 UCHAR modeno, UCHAR rateindex);
2432int sisfb_mode_rate_to_ddata(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
2433 UCHAR modeno, UCHAR rateindex,
2434 struct fb_var_screeninfo *var);
2435BOOLEAN sisfb_gettotalfrommode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
2436 UCHAR modeno, int *htotal, int *vtotal, UCHAR rateindex);
2437#endif
2438
2439/* init301.c: */
2440extern void SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2441 PSIS_HW_INFO HwInfo, int chkcrt2mode);
2442extern void SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2443 PSIS_HW_INFO HwInfo);
2444extern void SiS_SetYPbPr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
2445extern void SiS_SetTVMode(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, PSIS_HW_INFO HwInfo);
2446extern void SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
2447extern void SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
2448extern void SiS_DisableBridge(SiS_Private *, PSIS_HW_INFO);
2449extern BOOLEAN SiS_SetCRT2Group(SiS_Private *, PSIS_HW_INFO, USHORT);
2450extern USHORT SiS_GetRatePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2451 PSIS_HW_INFO HwInfo);
2452extern void SiS_WaitRetrace1(SiS_Private *SiS_Pr);
2453extern USHORT SiS_GetResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex);
2454extern USHORT SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempax);
2455extern USHORT SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2456 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo);
2457extern BOOLEAN SiS_IsVAMode(SiS_Private *, PSIS_HW_INFO);
2458extern BOOLEAN SiS_IsDualEdge(SiS_Private *, PSIS_HW_INFO);
2459
2460#ifdef LINUX_XF86
2461/* From other sis driver modules: */
2462extern int SiS_compute_vclk(int Clock, int *out_n, int *out_dn, int *out_div,
2463 int *out_sbit, int *out_scale);
2464extern void SiSCalcClock(ScrnInfoPtr pScrn, int clock, int max_VLD, unsigned int *vclk);
2465
2466extern UCHAR SiS_GetSetBIOSScratch(ScrnInfoPtr pScrn, USHORT offset, UCHAR value);
2467extern UCHAR SiS_GetSetModeID(ScrnInfoPtr pScrn, UCHAR id);
2468extern USHORT SiS_GetModeNumber(ScrnInfoPtr pScrn, DisplayModePtr mode, ULONG VBFlags);
2469#endif
2470
2471#endif
2472
diff --git a/drivers/video/sis/init301.c b/drivers/video/sis/init301.c
new file mode 100644
index 000000000000..2bc5b8097910
--- /dev/null
+++ b/drivers/video/sis/init301.c
@@ -0,0 +1,12239 @@
1/* $XFree86$ */
2/* $XdotOrg$ */
3/*
4 * Mode initializing code (CRT2 section)
5 * for SiS 300/305/540/630/730 and
6 * SiS 315/550/650/M650/651/661FX/M661xX/740/741(GX)/M741/330/660/M660/760/M760
7 * (Universal module for Linux kernel framebuffer and XFree86/X.org 4.x)
8 *
9 * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
10 *
11 * If distributed as part of the Linux kernel, the following license terms
12 * apply:
13 *
14 * * This program is free software; you can redistribute it and/or modify
15 * * it under the terms of the GNU General Public License as published by
16 * * the Free Software Foundation; either version 2 of the named License,
17 * * or any later version.
18 * *
19 * * This program is distributed in the hope that it will be useful,
20 * * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * * GNU General Public License for more details.
23 * *
24 * * You should have received a copy of the GNU General Public License
25 * * along with this program; if not, write to the Free Software
26 * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
27 *
28 * Otherwise, the following license terms apply:
29 *
30 * * Redistribution and use in source and binary forms, with or without
31 * * modification, are permitted provided that the following conditions
32 * * are met:
33 * * 1) Redistributions of source code must retain the above copyright
34 * * notice, this list of conditions and the following disclaimer.
35 * * 2) Redistributions in binary form must reproduce the above copyright
36 * * notice, this list of conditions and the following disclaimer in the
37 * * documentation and/or other materials provided with the distribution.
38 * * 3) The name of the author may not be used to endorse or promote products
39 * * derived from this software without specific prior written permission.
40 * *
41 * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
42 * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
43 * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
44 * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
45 * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46 * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
47 * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
48 * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
49 * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
50 * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51 *
52 * Author: Thomas Winischhofer <thomas@winischhofer.net>
53 *
54 * Formerly based on non-functional code-fragements for 300 series by SiS, Inc.
55 * Used by permission.
56 *
57 * TW says: This code looks awful, I know. But please don't do anything about
58 * this otherwise debugging will be hell.
59 * The code is extremely fragile as regards the different chipsets, different
60 * video bridges and combinations thereof. If anything is changed, extreme
61 * care has to be taken that that change doesn't break it for other chipsets,
62 * bridges or combinations thereof.
63 * All comments in this file are by me, regardless if marked TW or not.
64 *
65 */
66
67#if 1
68#define SET_EMI /* 302LV/ELV: Set EMI values */
69#endif
70
71#define COMPAL_HACK /* Needed for Compal 1400x1050 (EMI) */
72#define COMPAQ_HACK /* Needed for Inventec/Compaq 1280x1024 (EMI) */
73#define ASUS_HACK /* Needed for Asus A2H 1024x768 (EMI) */
74
75#include "init301.h"
76
77#ifdef SIS300
78#include "oem300.h"
79#endif
80
81#ifdef SIS315H
82#include "oem310.h"
83#endif
84
85#define SiS_I2CDELAY 1000
86#define SiS_I2CDELAYSHORT 150
87
88static USHORT SiS_GetBIOSLCDResInfo(SiS_Private *SiS_Pr);
89
90/*********************************************/
91/* HELPER: Lock/Unlock CRT2 */
92/*********************************************/
93
94void
95SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
96{
97 if(HwInfo->jChipType >= SIS_315H)
98 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
99 else
100 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
101}
102
103void
104SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
105{
106 if(HwInfo->jChipType >= SIS_315H)
107 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
108 else
109 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
110}
111
112/*********************************************/
113/* HELPER: Write SR11 */
114/*********************************************/
115
116static void
117SiS_SetRegSR11ANDOR(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT DataAND, USHORT DataOR)
118{
119 if(HwInfo->jChipType >= SIS_661) {
120 DataAND &= 0x0f;
121 DataOR &= 0x0f;
122 }
123 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,DataAND,DataOR);
124}
125
126/*********************************************/
127/* HELPER: Get Pointer to LCD structure */
128/*********************************************/
129
130#ifdef SIS315H
131static UCHAR *
132GetLCDStructPtr661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
133{
134 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
135 UCHAR *myptr = NULL;
136 USHORT romindex = 0, reg = 0, idx = 0;
137
138 /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
139 * due to the variaty of panels the BIOS doesn't know about.
140 * Exception: If the BIOS has better knowledge (such as in case
141 * of machines with a 301C and a panel that does not support DDC)
142 * use the BIOS data as well.
143 */
144
145 if((SiS_Pr->SiS_ROMNew) &&
146 ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) || (!SiS_Pr->PanelSelfDetected))) {
147
148 if(HwInfo->jChipType < SIS_661) reg = 0x3c;
149 else reg = 0x7d;
150
151 idx = (SiS_GetReg(SiS_Pr->SiS_P3d4,reg) & 0x1f) * 26;
152
153 if(idx < (8*26)) {
154 myptr = (UCHAR *)&SiS_LCDStruct661[idx];
155 }
156 romindex = SISGETROMW(0x100);
157 if(romindex) {
158 romindex += idx;
159 myptr = &ROMAddr[romindex];
160 }
161 }
162 return myptr;
163}
164
165static USHORT
166GetLCDStructPtr661_2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
167{
168 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
169 USHORT romptr = 0;
170
171 /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
172 * due to the variaty of panels the BIOS doesn't know about.
173 * Exception: If the BIOS has better knowledge (such as in case
174 * of machines with a 301C and a panel that does not support DDC)
175 * use the BIOS data as well.
176 */
177
178 if((SiS_Pr->SiS_ROMNew) &&
179 ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) || (!SiS_Pr->PanelSelfDetected))) {
180 romptr = SISGETROMW(0x102);
181 romptr += ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) * SiS_Pr->SiS661LCD2TableSize);
182 }
183
184 return(romptr);
185}
186#endif
187
188/*********************************************/
189/* Adjust Rate for CRT2 */
190/*********************************************/
191
192static BOOLEAN
193SiS_AdjustCRT2Rate(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
194 USHORT RRTI, USHORT *i, PSIS_HW_INFO HwInfo)
195{
196 USHORT checkmask=0,modeid,infoflag;
197
198 modeid = SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID;
199
200 if(SiS_Pr->SiS_VBType & VB_SISVB) {
201
202 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
203
204 checkmask |= SupportRAMDAC2;
205 if(HwInfo->jChipType >= SIS_315H) {
206 checkmask |= SupportRAMDAC2_135;
207 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
208 checkmask |= SupportRAMDAC2_162;
209 if(SiS_Pr->SiS_VBType & VB_SIS301C) {
210 checkmask |= SupportRAMDAC2_202;
211 }
212 }
213 }
214
215 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
216
217 checkmask |= SupportLCD;
218 if(HwInfo->jChipType >= SIS_315H) {
219 if(SiS_Pr->SiS_VBType & VB_SISVB) {
220 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
221 if(modeid == 0x2e) checkmask |= Support64048060Hz;
222 }
223 }
224 }
225
226 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
227
228 checkmask |= SupportHiVision;
229
230 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750|SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
231
232 checkmask |= SupportTV;
233 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
234 checkmask |= SupportTV1024;
235 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
236 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
237 checkmask |= SupportYPbPr750p;
238 }
239 }
240 }
241
242 }
243
244 } else { /* LVDS */
245
246 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
247 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
248 checkmask |= SupportCHTV;
249 }
250 }
251
252 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
253 checkmask |= SupportLCD;
254 }
255
256 }
257
258 /* Look backwards in table for matching CRT2 mode */
259 for(; SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID == modeid; (*i)--) {
260 infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
261 if(infoflag & checkmask) return TRUE;
262 if((*i) == 0) break;
263 }
264
265 /* Look through the whole mode-section of the table from the beginning
266 * for a matching CRT2 mode if no mode was found yet.
267 */
268 for((*i) = 0; ; (*i)++) {
269 if(SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID != modeid) break;
270 infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
271 if(infoflag & checkmask) return TRUE;
272 }
273 return FALSE;
274}
275
276/*********************************************/
277/* Get rate index */
278/*********************************************/
279
280USHORT
281SiS_GetRatePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
282 PSIS_HW_INFO HwInfo)
283{
284 SHORT LCDRefreshIndex[] = { 0x00, 0x00, 0x01, 0x01,
285 0x01, 0x01, 0x01, 0x01,
286 0x01, 0x01, 0x01, 0x01,
287 0x01, 0x01, 0x01, 0x01,
288 0x00, 0x00, 0x00, 0x00 };
289 USHORT RRTI,i,backup_i;
290 USHORT modeflag,index,temp,backupindex;
291
292 /* Do NOT check for UseCustomMode here, will skrew up FIFO */
293 if(ModeNo == 0xfe) return 0;
294
295 if(ModeNo <= 0x13) {
296 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
297 } else {
298 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
299 }
300
301 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
302 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
303 if(modeflag & HalfDCLK) return 0;
304 }
305 }
306
307 if(ModeNo < 0x14) return 0xFFFF;
308
309 index = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x33) >> SiS_Pr->SiS_SelectCRT2Rate) & 0x0F;
310 backupindex = index;
311
312 if(index > 0) index--;
313
314 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
315 if(SiS_Pr->SiS_VBType & VB_SISVB) {
316 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
317 if(SiS_Pr->SiS_VBType & VB_NoLCD) index = 0;
318 else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index = backupindex = 0;
319 }
320 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
321 if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) {
322 temp = LCDRefreshIndex[SiS_GetBIOSLCDResInfo(SiS_Pr)];
323 if(index > temp) index = temp;
324 }
325 }
326 } else {
327 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) index = 0;
328 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
329 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) index = 0;
330 }
331 }
332 }
333
334 RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
335 ModeNo = SiS_Pr->SiS_RefIndex[RRTI].ModeID;
336
337 if(HwInfo->jChipType >= SIS_315H) {
338 if(!(SiS_Pr->SiS_VBInfo & DriverMode)) {
339 if( (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x105) ||
340 (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x107) ) {
341 if(backupindex <= 1) RRTI++;
342 }
343 }
344 }
345
346 i = 0;
347 do {
348 if(SiS_Pr->SiS_RefIndex[RRTI + i].ModeID != ModeNo) break;
349 temp = SiS_Pr->SiS_RefIndex[RRTI + i].Ext_InfoFlag;
350 temp &= ModeTypeMask;
351 if(temp < SiS_Pr->SiS_ModeType) break;
352 i++;
353 index--;
354 } while(index != 0xFFFF);
355
356 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
357 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
358 temp = SiS_Pr->SiS_RefIndex[RRTI + i - 1].Ext_InfoFlag;
359 if(temp & InterlaceMode) i++;
360 }
361 }
362
363 i--;
364
365 if((SiS_Pr->SiS_SetFlag & ProgrammingCRT2) && (!(SiS_Pr->SiS_VBInfo & DisableCRT2Display))) {
366 backup_i = i;
367 if(!(SiS_AdjustCRT2Rate(SiS_Pr, ModeNo, ModeIdIndex, RRTI, &i, HwInfo))) {
368 i = backup_i;
369 }
370 }
371
372 return(RRTI + i);
373}
374
375/*********************************************/
376/* STORE CRT2 INFO in CR34 */
377/*********************************************/
378
379static void
380SiS_SaveCRT2Info(SiS_Private *SiS_Pr, USHORT ModeNo)
381{
382 USHORT temp1,temp2;
383
384 /* Store CRT1 ModeNo in CR34 */
385 SiS_SetReg(SiS_Pr->SiS_P3d4,0x34,ModeNo);
386 temp1 = (SiS_Pr->SiS_VBInfo & SetInSlaveMode) >> 8;
387 temp2 = ~(SetInSlaveMode >> 8);
388 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x31,temp2,temp1);
389}
390
391/*********************************************/
392/* HELPER: GET SOME DATA FROM BIOS ROM */
393/*********************************************/
394
395#ifdef SIS300
396static BOOLEAN
397SiS_CR36BIOSWord23b(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
398{
399 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
400 USHORT temp,temp1;
401
402 if(SiS_Pr->SiS_UseROM) {
403 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
404 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
405 temp1 = SISGETROMW(0x23b);
406 if(temp1 & temp) return TRUE;
407 }
408 }
409 return FALSE;
410}
411
412static BOOLEAN
413SiS_CR36BIOSWord23d(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
414{
415 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
416 USHORT temp,temp1;
417
418 if(SiS_Pr->SiS_UseROM) {
419 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
420 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
421 temp1 = SISGETROMW(0x23d);
422 if(temp1 & temp) return TRUE;
423 }
424 }
425 return FALSE;
426}
427#endif
428
429/*********************************************/
430/* HELPER: DELAY FUNCTIONS */
431/*********************************************/
432
433void
434SiS_DDC2Delay(SiS_Private *SiS_Pr, USHORT delaytime)
435{
436 USHORT i, j;
437
438 for(i=0; i<delaytime; i++) {
439 j += SiS_GetReg(SiS_Pr->SiS_P3c4,0x05);
440 }
441}
442
443#if defined(SIS300) || defined(SIS315H)
444static void
445SiS_GenericDelay(SiS_Private *SiS_Pr, USHORT delay)
446{
447 USHORT temp,flag;
448
449 flag = SiS_GetRegByte(0x61) & 0x10;
450
451 while(delay) {
452 temp = SiS_GetRegByte(0x61) & 0x10;
453 if(temp == flag) continue;
454 flag = temp;
455 delay--;
456 }
457}
458#endif
459
460#ifdef SIS315H
461static void
462SiS_LongDelay(SiS_Private *SiS_Pr, USHORT delay)
463{
464 while(delay--) {
465 SiS_GenericDelay(SiS_Pr,0x19df);
466 }
467}
468#endif
469
470#if defined(SIS300) || defined(SIS315H)
471static void
472SiS_ShortDelay(SiS_Private *SiS_Pr, USHORT delay)
473{
474 while(delay--) {
475 SiS_GenericDelay(SiS_Pr,0x42);
476 }
477}
478#endif
479
480static void
481SiS_PanelDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT DelayTime)
482{
483#if defined(SIS300) || defined(SIS315H)
484 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
485 USHORT PanelID, DelayIndex, Delay=0;
486#endif
487
488 if(HwInfo->jChipType < SIS_315H) {
489
490#ifdef SIS300
491
492 PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
493 if(SiS_Pr->SiS_VBType & VB_SISVB) {
494 if(SiS_Pr->SiS_VBType & VB_SIS301) PanelID &= 0xf7;
495 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x10)) PanelID = 0x12;
496 }
497 DelayIndex = PanelID >> 4;
498 if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) {
499 Delay = 3;
500 } else {
501 if(DelayTime >= 2) DelayTime -= 2;
502 if(!(DelayTime & 0x01)) {
503 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
504 } else {
505 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
506 }
507 if(SiS_Pr->SiS_UseROM) {
508 if(ROMAddr[0x220] & 0x40) {
509 if(!(DelayTime & 0x01)) Delay = (USHORT)ROMAddr[0x225];
510 else Delay = (USHORT)ROMAddr[0x226];
511 }
512 }
513 }
514 SiS_ShortDelay(SiS_Pr, Delay);
515
516#endif /* SIS300 */
517
518 } else {
519
520#ifdef SIS315H
521
522 if((HwInfo->jChipType >= SIS_661) ||
523 (HwInfo->jChipType <= SIS_315PRO) ||
524 (HwInfo->jChipType == SIS_330) ||
525 (SiS_Pr->SiS_ROMNew)) {
526
527 if(!(DelayTime & 0x01)) {
528 SiS_DDC2Delay(SiS_Pr, 0x1000);
529 } else {
530 SiS_DDC2Delay(SiS_Pr, 0x4000);
531 }
532
533 } else if((SiS_Pr->SiS_IF_DEF_LVDS == 1) /* ||
534 (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
535 (SiS_Pr->SiS_CustomT == CUT_CLEVO1400) */ ) { /* 315 series, LVDS; Special */
536
537 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
538 PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
539 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1400) {
540 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1b) & 0x10)) PanelID = 0x12;
541 }
542 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
543 DelayIndex = PanelID & 0x0f;
544 } else {
545 DelayIndex = PanelID >> 4;
546 }
547 if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) {
548 Delay = 3;
549 } else {
550 if(DelayTime >= 2) DelayTime -= 2;
551 if(!(DelayTime & 0x01)) {
552 Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[0];
553 } else {
554 Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[1];
555 }
556 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
557 if(ROMAddr[0x13c] & 0x40) {
558 if(!(DelayTime & 0x01)) {
559 Delay = (USHORT)ROMAddr[0x17e];
560 } else {
561 Delay = (USHORT)ROMAddr[0x17f];
562 }
563 }
564 }
565 }
566 SiS_ShortDelay(SiS_Pr, Delay);
567 }
568
569 } else if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 315 series, all bridges */
570
571 DelayIndex = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
572 if(!(DelayTime & 0x01)) {
573 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
574 } else {
575 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
576 }
577 Delay <<= 8;
578 SiS_DDC2Delay(SiS_Pr, Delay);
579
580 }
581
582#endif /* SIS315H */
583
584 }
585}
586
587#ifdef SIS315H
588static void
589SiS_PanelDelayLoop(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
590 USHORT DelayTime, USHORT DelayLoop)
591{
592 int i;
593 for(i=0; i<DelayLoop; i++) {
594 SiS_PanelDelay(SiS_Pr, HwInfo, DelayTime);
595 }
596}
597#endif
598
599/*********************************************/
600/* HELPER: WAIT-FOR-RETRACE FUNCTIONS */
601/*********************************************/
602
603void
604SiS_WaitRetrace1(SiS_Private *SiS_Pr)
605{
606 USHORT watchdog;
607
608 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
609 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80)) return;
610
611 watchdog = 65535;
612 while((SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
613 watchdog = 65535;
614 while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
615}
616
617#if defined(SIS300) || defined(SIS315H)
618static void
619SiS_WaitRetrace2(SiS_Private *SiS_Pr, USHORT reg)
620{
621 USHORT watchdog;
622
623 watchdog = 65535;
624 while((SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02) && --watchdog);
625 watchdog = 65535;
626 while((!(SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02)) && --watchdog);
627}
628#endif
629
630static void
631SiS_WaitVBRetrace(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
632{
633 if(HwInfo->jChipType < SIS_315H) {
634#ifdef SIS300
635 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
636 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return;
637 }
638 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x80)) {
639 SiS_WaitRetrace1(SiS_Pr);
640 } else {
641 SiS_WaitRetrace2(SiS_Pr, 0x25);
642 }
643#endif
644 } else {
645#ifdef SIS315H
646 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) {
647 SiS_WaitRetrace1(SiS_Pr);
648 } else {
649 SiS_WaitRetrace2(SiS_Pr, 0x30);
650 }
651#endif
652 }
653}
654
655static void
656SiS_VBWait(SiS_Private *SiS_Pr)
657{
658 USHORT tempal,temp,i,j;
659
660 temp = 0;
661 for(i=0; i<3; i++) {
662 for(j=0; j<100; j++) {
663 tempal = SiS_GetRegByte(SiS_Pr->SiS_P3da);
664 if(temp & 0x01) {
665 if((tempal & 0x08)) continue;
666 else break;
667 } else {
668 if(!(tempal & 0x08)) continue;
669 else break;
670 }
671 }
672 temp ^= 0x01;
673 }
674}
675
676static void
677SiS_VBLongWait(SiS_Private *SiS_Pr)
678{
679 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
680 SiS_VBWait(SiS_Pr);
681 } else {
682 SiS_WaitRetrace1(SiS_Pr);
683 }
684}
685
686/*********************************************/
687/* HELPER: MISC */
688/*********************************************/
689
690#ifdef SIS300
691static BOOLEAN
692SiS_Is301B(SiS_Private *SiS_Pr)
693{
694 if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01) >= 0xb0) return TRUE;
695 return FALSE;
696}
697#endif
698
699static BOOLEAN
700SiS_CRT2IsLCD(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
701{
702 USHORT flag;
703
704 if(HwInfo->jChipType == SIS_730) {
705 flag = SiS_GetReg(SiS_Pr->SiS_P3c4,0x13);
706 if(flag & 0x20) return TRUE;
707 }
708 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
709 if(flag & 0x20) return TRUE;
710 return FALSE;
711}
712
713BOOLEAN
714SiS_IsDualEdge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
715{
716#ifdef SIS315H
717 USHORT flag;
718
719 if(HwInfo->jChipType >= SIS_315H) {
720 if((HwInfo->jChipType != SIS_650) || (SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) {
721 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
722 if(flag & EnableDualEdge) return TRUE;
723 }
724 }
725#endif
726 return FALSE;
727}
728
729BOOLEAN
730SiS_IsVAMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
731{
732#ifdef SIS315H
733 USHORT flag;
734
735 if(HwInfo->jChipType >= SIS_315H) {
736 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
737 if((flag & EnableDualEdge) && (flag & SetToLCDA)) return TRUE;
738 }
739#endif
740 return FALSE;
741}
742
743#ifdef SIS315H
744static BOOLEAN
745SiS_IsVAorLCD(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
746{
747 if(SiS_IsVAMode(SiS_Pr,HwInfo)) return TRUE;
748 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) return TRUE;
749 return FALSE;
750}
751#endif
752
753static BOOLEAN
754SiS_IsDualLink(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
755{
756#ifdef SIS315H
757 if(HwInfo->jChipType >= SIS_315H) {
758 if((SiS_CRT2IsLCD(SiS_Pr, HwInfo)) ||
759 (SiS_IsVAMode(SiS_Pr, HwInfo))) {
760 if(SiS_Pr->SiS_LCDInfo & LCDDualLink) return TRUE;
761 }
762 }
763#endif
764 return FALSE;
765}
766
767#ifdef SIS315H
768static BOOLEAN
769SiS_TVEnabled(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
770{
771 if((SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) != 0x0c) return TRUE;
772 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS301LV302LV)) {
773 if(SiS_GetReg(SiS_Pr->SiS_Part2Port,0x4d) & 0x10) return TRUE;
774 }
775 return FALSE;
776}
777#endif
778
779#ifdef SIS315H
780static BOOLEAN
781SiS_LCDAEnabled(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
782{
783 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) return TRUE;
784 return FALSE;
785}
786#endif
787
788#ifdef SIS315H
789static BOOLEAN
790SiS_WeHaveBacklightCtrl(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
791{
792 if((HwInfo->jChipType >= SIS_315H) && (HwInfo->jChipType < SIS_661)) {
793 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0x10) return TRUE;
794 }
795 return FALSE;
796}
797#endif
798
799#ifdef SIS315H
800static BOOLEAN
801SiS_IsNotM650orLater(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
802{
803 USHORT flag;
804
805 if(HwInfo->jChipType == SIS_650) {
806 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f);
807 flag &= 0xF0;
808 /* Check for revision != A0 only */
809 if((flag == 0xe0) || (flag == 0xc0) ||
810 (flag == 0xb0) || (flag == 0x90)) return FALSE;
811 } else if(HwInfo->jChipType >= SIS_661) return FALSE;
812 return TRUE;
813}
814#endif
815
816#ifdef SIS315H
817static BOOLEAN
818SiS_IsYPbPr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
819{
820 USHORT flag;
821
822 if(HwInfo->jChipType >= SIS_315H) {
823 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
824 if(flag & EnableCHYPbPr) return TRUE; /* = YPrPb = 0x08 */
825 }
826 return FALSE;
827}
828#endif
829
830#ifdef SIS315H
831static BOOLEAN
832SiS_IsChScart(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
833{
834 USHORT flag;
835
836 if(HwInfo->jChipType >= SIS_315H) {
837 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
838 if(flag & EnableCHScart) return TRUE; /* = Scart = 0x04 */
839 }
840 return FALSE;
841}
842#endif
843
844#ifdef SIS315H
845static BOOLEAN
846SiS_IsTVOrYPbPrOrScart(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
847{
848 USHORT flag;
849
850 if(HwInfo->jChipType >= SIS_315H) {
851 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
852 if(flag & SetCRT2ToTV) return TRUE;
853 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
854 if(flag & EnableCHYPbPr) return TRUE; /* = YPrPb = 0x08 */
855 if(flag & EnableCHScart) return TRUE; /* = Scart = 0x04 - TW */
856 } else {
857 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
858 if(flag & SetCRT2ToTV) return TRUE;
859 }
860 return FALSE;
861}
862#endif
863
864#ifdef SIS315H
865static BOOLEAN
866SiS_IsLCDOrLCDA(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
867{
868 USHORT flag;
869
870 if(HwInfo->jChipType >= SIS_315H) {
871 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
872 if(flag & SetCRT2ToLCD) return TRUE;
873 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
874 if(flag & SetToLCDA) return TRUE;
875 } else {
876 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
877 if(flag & SetCRT2ToLCD) return TRUE;
878 }
879 return FALSE;
880}
881#endif
882
883static BOOLEAN
884SiS_BridgeIsOn(SiS_Private *SiS_Pr)
885{
886 USHORT flag;
887
888 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
889 return TRUE;
890 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
891 flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
892 if((flag == 1) || (flag == 2)) return TRUE;
893 }
894 return FALSE;
895}
896
897static BOOLEAN
898SiS_BridgeIsEnabled(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
899{
900 USHORT flag;
901
902 if(SiS_BridgeIsOn(SiS_Pr)) {
903 flag = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
904 if(HwInfo->jChipType < SIS_315H) {
905 flag &= 0xa0;
906 if((flag == 0x80) || (flag == 0x20)) return TRUE;
907 } else {
908 flag &= 0x50;
909 if((flag == 0x40) || (flag == 0x10)) return TRUE;
910 }
911 }
912 return FALSE;
913}
914
915static BOOLEAN
916SiS_BridgeInSlavemode(SiS_Private *SiS_Pr)
917{
918 USHORT flag1;
919
920 flag1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
921 if(flag1 & (SetInSlaveMode >> 8)) return TRUE;
922 return FALSE;
923}
924
925/*********************************************/
926/* GET VIDEO BRIDGE CONFIG INFO */
927/*********************************************/
928
929/* Setup general purpose IO for Chrontel communication */
930void
931SiS_SetChrontelGPIO(SiS_Private *SiS_Pr, USHORT myvbinfo)
932{
933 unsigned long acpibase;
934 unsigned short temp;
935
936 if(!(SiS_Pr->SiS_ChSW)) return;
937
938#ifdef LINUX_KERNEL
939 SiS_SetRegLong(0xcf8,0x80000874); /* get ACPI base */
940 acpibase = SiS_GetRegLong(0xcfc);
941#else
942 acpibase = pciReadLong(0x00000800, 0x74);
943#endif
944 acpibase &= 0xFFFF;
945 temp = SiS_GetRegShort((USHORT)(acpibase + 0x3c)); /* ACPI register 0x3c: GP Event 1 I/O mode select */
946 temp &= 0xFEFF;
947 SiS_SetRegShort((USHORT)(acpibase + 0x3c), temp);
948 temp = SiS_GetRegShort((USHORT)(acpibase + 0x3c));
949 temp = SiS_GetRegShort((USHORT)(acpibase + 0x3a)); /* ACPI register 0x3a: GP Pin Level (low/high) */
950 temp &= 0xFEFF;
951 if(!(myvbinfo & SetCRT2ToTV)) temp |= 0x0100;
952 SiS_SetRegShort((USHORT)(acpibase + 0x3a), temp);
953 temp = SiS_GetRegShort((USHORT)(acpibase + 0x3a));
954}
955
956void
957SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
958 PSIS_HW_INFO HwInfo, int checkcrt2mode)
959{
960 USHORT tempax,tempbx,temp;
961 USHORT modeflag, resinfo=0;
962
963 if(ModeNo <= 0x13) {
964 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
965 } else if(SiS_Pr->UseCustomMode) {
966 modeflag = SiS_Pr->CModeFlag;
967 } else {
968 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
969 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
970 }
971
972 SiS_Pr->SiS_SetFlag = 0;
973
974 SiS_Pr->SiS_ModeType = modeflag & ModeTypeMask;
975
976 tempbx = 0;
977 if(SiS_BridgeIsOn(SiS_Pr)) {
978 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
979#if 0
980 if(HwInfo->jChipType < SIS_661) {
981 /* NO - YPbPr not set yet ! */
982 if(SiS_Pr->SiS_YPbPr & <all ypbpr except 525i>) {
983 temp &= (SetCRT2ToHiVision | SwitchCRT2 | SetSimuScanMode); /* 0x83 */
984 temp |= SetCRT2ToHiVision; /* 0x80 */
985 }
986 if(SiS_Pr->SiS_YPbPr & <ypbpr525i>) {
987 temp &= (SetCRT2ToHiVision | SwitchCRT2 | SetSimuScanMode); /* 0x83 */
988 temp |= SetCRT2ToSVIDEO; /* 0x08 */
989 }
990 }
991#endif
992 tempbx |= temp;
993 tempax = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) << 8;
994 tempax &= (DriverMode | LoadDACFlag | SetNotSimuMode | SetPALTV);
995 tempbx |= tempax;
996
997#ifdef SIS315H
998 if(HwInfo->jChipType >= SIS_315H) {
999 if(SiS_Pr->SiS_VBType & VB_SISLCDA) {
1000 if(ModeNo == 0x03) {
1001 /* Mode 0x03 is never in driver mode */
1002 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf);
1003 }
1004 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8))) {
1005 /* Reset LCDA setting if not driver mode */
1006 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
1007 }
1008 if(IS_SIS650) {
1009 if(SiS_Pr->SiS_UseLCDA) {
1010 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) {
1011 if((ModeNo <= 0x13) || (!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) {
1012 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA));
1013 }
1014 }
1015 }
1016 }
1017 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1018 if((temp & (EnableDualEdge | SetToLCDA)) == (EnableDualEdge | SetToLCDA)) {
1019 tempbx |= SetCRT2ToLCDA;
1020 }
1021 }
1022
1023 if(SiS_Pr->SiS_VBType & (VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)) {
1024 tempbx &= ~(SetCRT2ToRAMDAC);
1025 }
1026
1027 if(HwInfo->jChipType >= SIS_661) {
1028 tempbx &= ~(SetCRT2ToYPbPr525750 | SetCRT2ToHiVision);
1029 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1030 if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1031 if(temp & 0x04) {
1032 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
1033 if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
1034 else tempbx |= SetCRT2ToYPbPr525750;
1035 }
1036 } else if(SiS_Pr->SiS_VBType & VB_SISHIVISION) {
1037 if(temp & 0x04) {
1038 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
1039 if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
1040 }
1041 }
1042 }
1043
1044 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1045 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1046 if(temp & SetToLCDA) {
1047 tempbx |= SetCRT2ToLCDA;
1048 }
1049 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1050 if(temp & EnableCHYPbPr) {
1051 tempbx |= SetCRT2ToCHYPbPr;
1052 }
1053 }
1054 }
1055 }
1056
1057#endif /* SIS315H */
1058
1059 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1060 temp = SetCRT2ToSVIDEO |
1061 SetCRT2ToAVIDEO |
1062 SetCRT2ToSCART |
1063 SetCRT2ToLCDA |
1064 SetCRT2ToLCD |
1065 SetCRT2ToRAMDAC |
1066 SetCRT2ToHiVision |
1067 SetCRT2ToYPbPr525750;
1068 } else {
1069 if(HwInfo->jChipType >= SIS_315H) {
1070 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1071 temp = SetCRT2ToAVIDEO |
1072 SetCRT2ToSVIDEO |
1073 SetCRT2ToSCART |
1074 SetCRT2ToLCDA |
1075 SetCRT2ToLCD |
1076 SetCRT2ToCHYPbPr;
1077 } else {
1078 temp = SetCRT2ToLCDA |
1079 SetCRT2ToLCD;
1080 }
1081 } else {
1082 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1083 temp = SetCRT2ToTV | SetCRT2ToLCD;
1084 } else {
1085 temp = SetCRT2ToLCD;
1086 }
1087 }
1088 }
1089
1090 if(!(tempbx & temp)) {
1091 tempax = DisableCRT2Display;
1092 tempbx = 0;
1093 }
1094
1095 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1096 USHORT clearmask = ( DriverMode |
1097 DisableCRT2Display |
1098 LoadDACFlag |
1099 SetNotSimuMode |
1100 SetInSlaveMode |
1101 SetPALTV |
1102 SwitchCRT2 |
1103 SetSimuScanMode );
1104 if(tempbx & SetCRT2ToLCDA) tempbx &= (clearmask | SetCRT2ToLCDA);
1105 if(tempbx & SetCRT2ToRAMDAC) tempbx &= (clearmask | SetCRT2ToRAMDAC);
1106 if(tempbx & SetCRT2ToLCD) tempbx &= (clearmask | SetCRT2ToLCD);
1107 if(tempbx & SetCRT2ToSCART) tempbx &= (clearmask | SetCRT2ToSCART);
1108 if(tempbx & SetCRT2ToHiVision) tempbx &= (clearmask | SetCRT2ToHiVision);
1109 if(tempbx & SetCRT2ToYPbPr525750) tempbx &= (clearmask | SetCRT2ToYPbPr525750);
1110 } else {
1111 if(HwInfo->jChipType >= SIS_315H) {
1112 if(tempbx & SetCRT2ToLCDA) {
1113 tempbx &= (0xFF00|SwitchCRT2|SetSimuScanMode);
1114 }
1115 }
1116 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1117 if(tempbx & SetCRT2ToTV) {
1118 tempbx &= (0xFF00|SetCRT2ToTV|SwitchCRT2|SetSimuScanMode);
1119 }
1120 }
1121 if(tempbx & SetCRT2ToLCD) {
1122 tempbx &= (0xFF00|SetCRT2ToLCD|SwitchCRT2|SetSimuScanMode);
1123 }
1124 if(HwInfo->jChipType >= SIS_315H) {
1125 if(tempbx & SetCRT2ToLCDA) {
1126 tempbx |= SetCRT2ToLCD;
1127 }
1128 }
1129 }
1130
1131 if(tempax & DisableCRT2Display) {
1132 if(!(tempbx & (SwitchCRT2 | SetSimuScanMode))) {
1133 tempbx = SetSimuScanMode | DisableCRT2Display;
1134 }
1135 }
1136
1137 if(!(tempbx & DriverMode)) tempbx |= SetSimuScanMode;
1138
1139 /* LVDS/CHRONTEL (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */
1140 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
1141 if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
1142 ((SiS_Pr->SiS_VBType & VB_NoLCD) && (tempbx & SetCRT2ToLCD)) ) {
1143 modeflag &= (~CRT2Mode);
1144 }
1145 }
1146
1147 if(!(tempbx & SetSimuScanMode)) {
1148 if(tempbx & SwitchCRT2) {
1149 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1150 if( (HwInfo->jChipType >= SIS_315H) &&
1151 (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) ) {
1152 if(resinfo != SIS_RI_1600x1200) {
1153 tempbx |= SetSimuScanMode;
1154 }
1155 } else {
1156 tempbx |= SetSimuScanMode;
1157 }
1158 }
1159 } else {
1160 if(SiS_BridgeIsEnabled(SiS_Pr,HwInfo)) {
1161 if(!(tempbx & DriverMode)) {
1162 if(SiS_BridgeInSlavemode(SiS_Pr)) {
1163 tempbx |= SetSimuScanMode;
1164 }
1165 }
1166 }
1167 }
1168 }
1169
1170 if(!(tempbx & DisableCRT2Display)) {
1171 if(tempbx & DriverMode) {
1172 if(tempbx & SetSimuScanMode) {
1173 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1174 if( (HwInfo->jChipType >= SIS_315H) &&
1175 (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) ) {
1176 if(resinfo != SIS_RI_1600x1200) {
1177 tempbx |= SetInSlaveMode;
1178 }
1179 } else {
1180 tempbx |= SetInSlaveMode;
1181 }
1182 }
1183 }
1184 } else {
1185 tempbx |= SetInSlaveMode;
1186 }
1187 }
1188
1189 }
1190
1191 SiS_Pr->SiS_VBInfo = tempbx;
1192
1193 if(HwInfo->jChipType == SIS_630) {
1194 SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo);
1195 }
1196
1197#ifdef TWDEBUG
1198#ifdef LINUX_KERNEL
1199 printk(KERN_DEBUG "sisfb: (VBInfo= 0x%04x, SetFlag=0x%04x)\n",
1200 SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
1201#endif
1202#ifdef LINUX_XF86
1203 xf86DrvMsgVerb(0, X_PROBED, 3, "(init301: VBInfo=0x%04x, SetFlag=0x%04x)\n",
1204 SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
1205#endif
1206#endif
1207}
1208
1209/*********************************************/
1210/* DETERMINE YPbPr MODE */
1211/*********************************************/
1212
1213void
1214SiS_SetYPbPr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
1215{
1216
1217 UCHAR temp;
1218
1219 /* Note: This variable is only used on 30xLV systems.
1220 * CR38 has a different meaning on LVDS/CH7019 systems.
1221 * On 661 and later, these bits moved to CR35.
1222 *
1223 * On 301, 301B, only HiVision 1080i is supported.
1224 * On 30xLV, 301C, only YPbPr 1080i is supported.
1225 */
1226
1227 SiS_Pr->SiS_YPbPr = 0;
1228 if(HwInfo->jChipType >= SIS_661) return;
1229
1230 if(SiS_Pr->SiS_VBType) {
1231 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1232 SiS_Pr->SiS_YPbPr = YPbPrHiVision;
1233 }
1234 }
1235
1236 if(HwInfo->jChipType >= SIS_315H) {
1237 if(SiS_Pr->SiS_VBType & (VB_SIS301LV302LV | VB_SIS301C)) {
1238 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1239 if(temp & 0x08) {
1240 switch((temp >> 4)) {
1241 case 0x00: SiS_Pr->SiS_YPbPr = YPbPr525i; break;
1242 case 0x01: SiS_Pr->SiS_YPbPr = YPbPr525p; break;
1243 case 0x02: SiS_Pr->SiS_YPbPr = YPbPr750p; break;
1244 case 0x03: SiS_Pr->SiS_YPbPr = YPbPrHiVision; break;
1245 }
1246 }
1247 }
1248 }
1249
1250}
1251
1252/*********************************************/
1253/* DETERMINE TVMode flag */
1254/*********************************************/
1255
1256void
1257SiS_SetTVMode(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, PSIS_HW_INFO HwInfo)
1258{
1259 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
1260 USHORT temp, temp1, resinfo = 0, romindex = 0;
1261 UCHAR OutputSelect = *SiS_Pr->pSiS_OutputSelect;
1262
1263 SiS_Pr->SiS_TVMode = 0;
1264
1265 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
1266 if(SiS_Pr->UseCustomMode) return;
1267
1268 if(ModeNo > 0x13) {
1269 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1270 }
1271
1272 if(HwInfo->jChipType < SIS_661) {
1273
1274 if(SiS_Pr->SiS_VBInfo & SetPALTV) SiS_Pr->SiS_TVMode |= TVSetPAL;
1275
1276 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1277 temp = 0;
1278 if((HwInfo->jChipType == SIS_630) ||
1279 (HwInfo->jChipType == SIS_730)) {
1280 temp = 0x35;
1281 romindex = 0xfe;
1282 } else if(HwInfo->jChipType >= SIS_315H) {
1283 temp = 0x38;
1284 romindex = 0xf3;
1285 if(HwInfo->jChipType >= SIS_330) romindex = 0x11b;
1286 }
1287 if(temp) {
1288 if(romindex && SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
1289 OutputSelect = ROMAddr[romindex];
1290 if(!(OutputSelect & EnablePALMN)) {
1291 SiS_SetRegAND(SiS_Pr->SiS_P3d4,temp,0x3F);
1292 }
1293 }
1294 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,temp);
1295 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1296 if(temp1 & EnablePALM) { /* 0x40 */
1297 SiS_Pr->SiS_TVMode |= TVSetPALM;
1298 SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1299 } else if(temp1 & EnablePALN) { /* 0x80 */
1300 SiS_Pr->SiS_TVMode |= TVSetPALN;
1301 }
1302 } else {
1303 if(temp1 & EnableNTSCJ) { /* 0x40 */
1304 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1305 }
1306 }
1307 }
1308 /* Translate HiVision/YPbPr to our new flags */
1309 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1310 if(SiS_Pr->SiS_YPbPr == YPbPr750p) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1311 else if(SiS_Pr->SiS_YPbPr == YPbPr525p) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1312 else if(SiS_Pr->SiS_YPbPr == YPbPrHiVision) SiS_Pr->SiS_TVMode |= TVSetHiVision;
1313 else SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1314 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p | TVSetYPbPr525i)) {
1315 SiS_Pr->SiS_VBInfo &= ~SetCRT2ToHiVision;
1316 SiS_Pr->SiS_VBInfo |= SetCRT2ToYPbPr525750;
1317 } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
1318 SiS_Pr->SiS_TVMode |= TVSetPAL;
1319 }
1320 }
1321 } else if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1322 if(SiS_Pr->SiS_CHOverScan) {
1323 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
1324 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1325 if((temp & TVOverScan) || (SiS_Pr->SiS_CHOverScan == 1)) {
1326 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1327 }
1328 } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1329 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79);
1330 if((temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1)) {
1331 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1332 }
1333 }
1334 if(SiS_Pr->SiS_CHSOverScan) {
1335 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1336 }
1337 }
1338 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1339 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1340 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1341 if(temp & EnablePALM) SiS_Pr->SiS_TVMode |= TVSetPALM;
1342 else if(temp & EnablePALN) SiS_Pr->SiS_TVMode |= TVSetPALN;
1343 } else {
1344 if(temp & EnableNTSCJ) {
1345 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1346 }
1347 }
1348 }
1349 }
1350
1351 } else { /* 661 and later */
1352
1353 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1354 if(temp1 & 0x01) {
1355 SiS_Pr->SiS_TVMode |= TVSetPAL;
1356 if(temp1 & 0x08) {
1357 SiS_Pr->SiS_TVMode |= TVSetPALN;
1358 } else if(temp1 & 0x04) {
1359 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1360 SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1361 }
1362 SiS_Pr->SiS_TVMode |= TVSetPALM;
1363 }
1364 } else {
1365 if(temp1 & 0x02) {
1366 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1367 }
1368 }
1369 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1370 if(SiS_Pr->SiS_CHOverScan) {
1371 if((temp1 & 0x10) || (SiS_Pr->SiS_CHOverScan == 1)) {
1372 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1373 }
1374 }
1375 }
1376 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1377 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1378 temp1 &= 0xe0;
1379 if(temp1 == 0x00) SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1380 else if(temp1 == 0x20) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1381 else if(temp1 == 0x40) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1382 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1383 SiS_Pr->SiS_TVMode |= (TVSetHiVision | TVSetPAL);
1384 }
1385 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750 | SetCRT2ToHiVision)) {
1386 if(resinfo == SIS_RI_800x480 || resinfo == SIS_RI_1024x576 || resinfo == SIS_RI_1280x720) {
1387 SiS_Pr->SiS_TVMode |= TVAspect169;
1388 } else {
1389 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x39);
1390 if(temp1 & 0x02) {
1391 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetHiVision)) {
1392 SiS_Pr->SiS_TVMode |= TVAspect169;
1393 } else {
1394 SiS_Pr->SiS_TVMode |= TVAspect43LB;
1395 }
1396 } else {
1397 SiS_Pr->SiS_TVMode |= TVAspect43;
1398 }
1399 }
1400 }
1401 }
1402 }
1403
1404 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) SiS_Pr->SiS_TVMode |= TVSetPAL;
1405
1406 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1407
1408 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1409 SiS_Pr->SiS_TVMode |= TVSetPAL;
1410 SiS_Pr->SiS_TVMode &= ~(TVSetPALM | TVSetPALN | TVSetNTSCJ);
1411 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1412 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525i | TVSetYPbPr525p | TVSetYPbPr750p)) {
1413 SiS_Pr->SiS_TVMode &= ~(TVSetPAL | TVSetNTSCJ | TVSetPALM | TVSetPALN);
1414 }
1415 }
1416
1417 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
1418 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
1419 SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
1420 }
1421 }
1422
1423 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
1424 /* BIOS sets TVNTSC1024 without checking 525p here. Wrong? */
1425 if(!(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr525p | TVSetYPbPr750p))) {
1426 if(resinfo == SIS_RI_1024x768) {
1427 SiS_Pr->SiS_TVMode |= TVSetNTSC1024;
1428 }
1429 }
1430 }
1431
1432 SiS_Pr->SiS_TVMode |= TVRPLLDIV2XO;
1433 if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) &&
1434 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
1435 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1436 } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
1437 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1438 } else if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
1439 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
1440 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1441 }
1442 }
1443
1444 }
1445
1446 SiS_Pr->SiS_VBInfo &= ~SetPALTV;
1447
1448#ifdef TWDEBUG
1449 xf86DrvMsg(0, X_INFO, "(init301: TVMode %x, VBInfo %x)\n", SiS_Pr->SiS_TVMode, SiS_Pr->SiS_VBInfo);
1450#endif
1451}
1452
1453/*********************************************/
1454/* GET LCD INFO */
1455/*********************************************/
1456
1457static USHORT
1458SiS_GetBIOSLCDResInfo(SiS_Private *SiS_Pr)
1459{
1460 USHORT temp = SiS_Pr->SiS_LCDResInfo;
1461 /* Translate my LCDResInfo to BIOS value */
1462 if(temp == Panel_1280x768_2) temp = Panel_1280x768;
1463 if(temp == Panel_1280x800_2) temp = Panel_1280x800;
1464 return temp;
1465}
1466
1467static void
1468SiS_GetLCDInfoBIOS(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
1469{
1470#ifdef SIS315H
1471 UCHAR *ROMAddr;
1472 USHORT temp;
1473
1474#ifdef TWDEBUG
1475 xf86DrvMsg(0, X_INFO, "Paneldata driver: [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n",
1476 SiS_Pr->PanelHT, SiS_Pr->PanelVT,
1477 SiS_Pr->PanelHRS, SiS_Pr->PanelHRE,
1478 SiS_Pr->PanelVRS, SiS_Pr->PanelVRE,
1479 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK,
1480 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A,
1481 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B);
1482#endif
1483
1484 if((ROMAddr = GetLCDStructPtr661(SiS_Pr, HwInfo))) {
1485 if((temp = SISGETROMW(6)) != SiS_Pr->PanelHT) {
1486 SiS_Pr->SiS_NeedRomModeData = TRUE;
1487 SiS_Pr->PanelHT = temp;
1488 }
1489 if((temp = SISGETROMW(8)) != SiS_Pr->PanelVT) {
1490 SiS_Pr->SiS_NeedRomModeData = TRUE;
1491 SiS_Pr->PanelVT = temp;
1492 }
1493 SiS_Pr->PanelHRS = SISGETROMW(10);
1494 SiS_Pr->PanelHRE = SISGETROMW(12);
1495 SiS_Pr->PanelVRS = SISGETROMW(14);
1496 SiS_Pr->PanelVRE = SISGETROMW(16);
1497 SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
1498 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].CLOCK =
1499 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].CLOCK = (USHORT)((UCHAR)ROMAddr[18]);
1500 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2B =
1501 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_A = ROMAddr[19];
1502 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2C =
1503 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_B = ROMAddr[20];
1504
1505#ifdef TWDEBUG
1506 xf86DrvMsg(0, X_INFO, "Paneldata BIOS: [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n",
1507 SiS_Pr->PanelHT, SiS_Pr->PanelVT,
1508 SiS_Pr->PanelHRS, SiS_Pr->PanelHRE,
1509 SiS_Pr->PanelVRS, SiS_Pr->PanelVRE,
1510 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK,
1511 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A,
1512 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B);
1513#endif
1514
1515 }
1516#endif
1517}
1518
1519static void
1520SiS_CheckScaling(SiS_Private *SiS_Pr, USHORT resinfo, const UCHAR *nonscalingmodes)
1521{
1522 int i = 0;
1523 while(nonscalingmodes[i] != 0xff) {
1524 if(nonscalingmodes[i++] == resinfo) {
1525 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ||
1526 (SiS_Pr->UsePanelScaler == -1)) {
1527 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1528 }
1529 break;
1530 }
1531 }
1532}
1533
1534void
1535SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
1536 PSIS_HW_INFO HwInfo)
1537{
1538#ifdef SIS300
1539 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
1540 const unsigned char SiS300SeriesLCDRes[] =
1541 { 0, 1, 2, 3, 7, 4, 5, 8,
1542 0, 0, 10, 0, 0, 0, 0, 15 };
1543#endif
1544#ifdef SIS315H
1545 UCHAR *myptr = NULL;
1546#endif
1547 USHORT temp,modeflag,resinfo=0,modexres=0,modeyres=0;
1548 BOOLEAN panelcanscale = FALSE;
1549
1550 SiS_Pr->SiS_LCDResInfo = 0;
1551 SiS_Pr->SiS_LCDTypeInfo = 0;
1552 SiS_Pr->SiS_LCDInfo = 0;
1553 SiS_Pr->PanelHRS = 999; /* HSync start */
1554 SiS_Pr->PanelHRE = 999; /* HSync end */
1555 SiS_Pr->PanelVRS = 999; /* VSync start */
1556 SiS_Pr->PanelVRE = 999; /* VSync end */
1557 SiS_Pr->SiS_NeedRomModeData = FALSE;
1558
1559 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return;
1560
1561 if(ModeNo <= 0x13) {
1562 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
1563 } else if(SiS_Pr->UseCustomMode) {
1564 modeflag = SiS_Pr->CModeFlag;
1565 } else {
1566 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1567 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1568 modexres = SiS_Pr->SiS_ModeResInfo[resinfo].HTotal;
1569 modeyres = SiS_Pr->SiS_ModeResInfo[resinfo].VTotal;
1570 }
1571
1572 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
1573
1574 /* For broken BIOSes: Assume 1024x768 */
1575 if(temp == 0) temp = 0x02;
1576
1577 if((HwInfo->jChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
1578 SiS_Pr->SiS_LCDTypeInfo = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x7c) >> 2;
1579 } else if((HwInfo->jChipType < SIS_315H) || (HwInfo->jChipType >= SIS_661)) {
1580 SiS_Pr->SiS_LCDTypeInfo = temp >> 4;
1581 } else {
1582 SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1;
1583 }
1584 temp &= 0x0f;
1585#ifdef SIS300
1586 if(HwInfo->jChipType < SIS_315H) {
1587 /* Very old BIOSes only know 7 sizes (NetVista 2179, 1.01g) */
1588 if(SiS_Pr->SiS_VBType & VB_SIS301) {
1589 if(temp < 0x0f) temp &= 0x07;
1590 }
1591 /* Translate 300 series LCDRes to 315 series for unified usage */
1592 temp = SiS300SeriesLCDRes[temp];
1593 }
1594#endif
1595
1596 /* Translate to our internal types */
1597 if(HwInfo->jChipType == SIS_550) {
1598 if(temp == Panel310_640x480_2) temp = Panel_640x480_2;
1599 if(temp == Panel310_640x480_3) temp = Panel_640x480_3;
1600 }
1601
1602 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { /* SiS LVDS */
1603 if(temp == Panel310_1280x768) {
1604 temp = Panel_1280x768_2;
1605 }
1606 if(SiS_Pr->SiS_ROMNew) {
1607 if(temp == Panel661_1280x800) {
1608 temp = Panel_1280x800_2;
1609 }
1610 }
1611 }
1612
1613 SiS_Pr->SiS_LCDResInfo = temp;
1614
1615 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1616 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
1617 SiS_Pr->SiS_LCDResInfo = Panel_Barco1366;
1618 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
1619 SiS_Pr->SiS_LCDResInfo = Panel_848x480;
1620 }
1621 }
1622
1623 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1624 if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)
1625 SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMin301;
1626 } else {
1627 if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMinLVDS)
1628 SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS;
1629 }
1630
1631 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
1632 SiS_Pr->SiS_LCDInfo = temp & ~0x000e;
1633 /* Need temp below! */
1634
1635 /* These can't scale no matter what */
1636 switch(SiS_Pr->SiS_LCDResInfo) {
1637 case Panel_1280x960:
1638 SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1639 }
1640
1641 panelcanscale = (SiS_Pr->SiS_LCDInfo & DontExpandLCD) ? TRUE : FALSE;
1642
1643 if(!SiS_Pr->UsePanelScaler) SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1644 else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1645
1646 /* Dual link, Pass 1:1 BIOS default, etc. */
1647#ifdef SIS315H
1648 if(HwInfo->jChipType >= SIS_661) {
1649 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1650 if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1651 }
1652 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
1653 if(SiS_Pr->SiS_ROMNew) {
1654 if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1655 } else if((myptr = GetLCDStructPtr661(SiS_Pr, HwInfo))) {
1656 if(myptr[2] & 0x01) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1657 }
1658 }
1659 } else if(HwInfo->jChipType >= SIS_315H) {
1660 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1661 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1662 }
1663 if((SiS_Pr->SiS_ROMNew) && (!(SiS_Pr->PanelSelfDetected))) {
1664 SiS_Pr->SiS_LCDInfo &= ~(LCDRGB18Bit);
1665 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1666 if(temp & 0x01) SiS_Pr->SiS_LCDInfo |= LCDRGB18Bit;
1667 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
1668 if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1669 }
1670 } else if(!(SiS_Pr->SiS_ROMNew)) {
1671 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
1672 if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) &&
1673 (SiS_Pr->SiS_LCDResInfo == Panel_1024x768)) {
1674 SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1675 }
1676 if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
1677 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
1678 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
1679 (SiS_Pr->SiS_LCDResInfo == Panel_1680x1050)) {
1680 SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1681 }
1682 }
1683 }
1684 }
1685#endif
1686
1687 /* Pass 1:1 */
1688 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
1689 /* Always center screen on LVDS (if scaling is disabled) */
1690 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1691 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
1692 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
1693 /* Always center screen on SiS LVDS (if scaling is disabled) */
1694 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1695 } else {
1696 /* By default, pass 1:1 on SiS TMDS (if scaling is supported) */
1697 if(panelcanscale) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1698 if(SiS_Pr->CenterScreen == 1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1699 }
1700 }
1701
1702 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1703 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1704
1705 switch(SiS_Pr->SiS_LCDResInfo) {
1706 case Panel_320x480: SiS_Pr->PanelXRes = 320; SiS_Pr->PanelYRes = 480;
1707 SiS_Pr->PanelHT = 400; SiS_Pr->PanelVT = 525;
1708 SiS_Pr->PanelVCLKIdx300 = VCLK28;
1709 SiS_Pr->PanelVCLKIdx315 = VCLK28;
1710 break;
1711 case Panel_640x480_2:
1712 case Panel_640x480_3: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
1713 SiS_Pr->PanelVRS = 24; SiS_Pr->PanelVRE = 3;
1714 SiS_Pr->PanelVCLKIdx300 = VCLK28;
1715 SiS_Pr->PanelVCLKIdx315 = VCLK28;
1716 break;
1717 case Panel_640x480: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
1718 SiS_Pr->PanelVRE = 3;
1719 SiS_Pr->PanelVCLKIdx300 = VCLK28;
1720 SiS_Pr->PanelVCLKIdx315 = VCLK28;
1721 break;
1722 case Panel_800x600: SiS_Pr->PanelXRes = 800; SiS_Pr->PanelYRes = 600;
1723 SiS_Pr->PanelHT = 1056; SiS_Pr->PanelVT = 628;
1724 SiS_Pr->PanelHRS = 40; SiS_Pr->PanelHRE = 128;
1725 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 4;
1726 SiS_Pr->PanelVCLKIdx300 = VCLK40;
1727 SiS_Pr->PanelVCLKIdx315 = VCLK40;
1728 break;
1729 case Panel_1024x600: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 600;
1730 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 800;
1731 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
1732 SiS_Pr->PanelVRS = 2 /* 88 */ ; SiS_Pr->PanelVRE = 6;
1733 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1734 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1735 break;
1736 case Panel_1024x768: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768;
1737 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1738 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
1739 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1740 if(HwInfo->jChipType < SIS_315H) {
1741 SiS_Pr->PanelHRS = 23;
1742 SiS_Pr->PanelVRE = 5;
1743 }
1744 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1745 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1746 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1747 break;
1748 case Panel_1152x768: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 768;
1749 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1750 SiS_Pr->PanelHRS = 24;
1751 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1752 if(HwInfo->jChipType < SIS_315H) {
1753 SiS_Pr->PanelHRS = 23;
1754 SiS_Pr->PanelVRE = 5;
1755 }
1756 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1757 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1758 break;
1759 case Panel_1152x864: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 864;
1760 break;
1761 case Panel_1280x720: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 720;
1762 SiS_Pr->PanelHT = 1650; SiS_Pr->PanelVT = 750;
1763 SiS_Pr->PanelHRS = 110; SiS_Pr->PanelHRE = 40;
1764 SiS_Pr->PanelVRS = 5; SiS_Pr->PanelVRE = 5;
1765 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x720;
1766 /* Data above for TMDS (projector); get from BIOS for LVDS */
1767 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1768 break;
1769 case Panel_1280x768: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768;
1770 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1771 SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 806;
1772 SiS_Pr->PanelVCLKIdx300 = VCLK81_300; /* ? */
1773 SiS_Pr->PanelVCLKIdx315 = VCLK81_315; /* ? */
1774 } else {
1775 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 802;
1776 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRS = 112;
1777 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1778 SiS_Pr->PanelVCLKIdx300 = VCLK81_300;
1779 SiS_Pr->PanelVCLKIdx315 = VCLK81_315;
1780 }
1781 break;
1782 case Panel_1280x768_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768;
1783 SiS_Pr->PanelHT = 1660; SiS_Pr->PanelVT = 806;
1784 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1785 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1786 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_2;
1787 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1788 break;
1789 case Panel_1280x800: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800;
1790 SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 816;
1791 SiS_Pr->PanelHRS = 21; SiS_Pr->PanelHRE = 24;
1792 SiS_Pr->PanelVRS = 4; SiS_Pr->PanelVRE = 3;
1793 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315;
1794 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1795 break;
1796 case Panel_1280x800_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800;
1797 SiS_Pr->PanelHT = 1552; SiS_Pr->PanelVT = 812;
1798 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1799 SiS_Pr->PanelVRS = 4; SiS_Pr->PanelVRE = 3;
1800 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315_2;
1801 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1802 break;
1803 case Panel_1280x960: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 960;
1804 SiS_Pr->PanelHT = 1800; SiS_Pr->PanelVT = 1000;
1805 SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
1806 SiS_Pr->PanelVCLKIdx315 = VCLK108_3_315;
1807 if(resinfo == SIS_RI_1280x1024) {
1808 SiS_Pr->PanelVCLKIdx300 = VCLK100_300;
1809 SiS_Pr->PanelVCLKIdx315 = VCLK100_315;
1810 }
1811 break;
1812 case Panel_1280x1024: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024;
1813 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1814 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1815 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1816 SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
1817 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1818 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1819 break;
1820 case Panel_1400x1050: SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050;
1821 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1822 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112; /* HRE OK for LVDS, not for LCDA */
1823 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1824 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1825 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1826 break;
1827 case Panel_1600x1200: SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200;
1828 SiS_Pr->PanelHT = 2160; SiS_Pr->PanelVT = 1250;
1829 SiS_Pr->PanelHRS = 64; SiS_Pr->PanelHRE = 192;
1830 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1831 SiS_Pr->PanelVCLKIdx315 = VCLK162_315;
1832 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1833 break;
1834 case Panel_1680x1050: SiS_Pr->PanelXRes = 1680; SiS_Pr->PanelYRes = 1050;
1835 SiS_Pr->PanelHT = 1900; SiS_Pr->PanelVT = 1066;
1836 SiS_Pr->PanelHRS = 26; SiS_Pr->PanelHRE = 76;
1837 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1838 SiS_Pr->PanelVCLKIdx315 = VCLK121_315;
1839 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
1840 break;
1841 case Panel_Barco1366: SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024;
1842 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1843 break;
1844 case Panel_848x480: SiS_Pr->PanelXRes = 848; SiS_Pr->PanelYRes = 480;
1845 SiS_Pr->PanelHT = 1088; SiS_Pr->PanelVT = 525;
1846 break;
1847 case Panel_Custom: SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX;
1848 SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY;
1849 SiS_Pr->PanelHT = SiS_Pr->CHTotal;
1850 SiS_Pr->PanelVT = SiS_Pr->CVTotal;
1851 if(SiS_Pr->CP_PreferredIndex != -1) {
1852 SiS_Pr->PanelXRes = SiS_Pr->CP_HDisplay[SiS_Pr->CP_PreferredIndex];
1853 SiS_Pr->PanelYRes = SiS_Pr->CP_VDisplay[SiS_Pr->CP_PreferredIndex];
1854 SiS_Pr->PanelHT = SiS_Pr->CP_HTotal[SiS_Pr->CP_PreferredIndex];
1855 SiS_Pr->PanelVT = SiS_Pr->CP_VTotal[SiS_Pr->CP_PreferredIndex];
1856 SiS_Pr->PanelHRS = SiS_Pr->CP_HSyncStart[SiS_Pr->CP_PreferredIndex];
1857 SiS_Pr->PanelHRE = SiS_Pr->CP_HSyncEnd[SiS_Pr->CP_PreferredIndex];
1858 SiS_Pr->PanelVRS = SiS_Pr->CP_VSyncStart[SiS_Pr->CP_PreferredIndex];
1859 SiS_Pr->PanelVRE = SiS_Pr->CP_VSyncEnd[SiS_Pr->CP_PreferredIndex];
1860 SiS_Pr->PanelHRS -= SiS_Pr->PanelXRes;
1861 SiS_Pr->PanelHRE -= SiS_Pr->PanelHRS;
1862 SiS_Pr->PanelVRS -= SiS_Pr->PanelYRes;
1863 SiS_Pr->PanelVRE -= SiS_Pr->PanelVRS;
1864 if(SiS_Pr->CP_PrefClock) {
1865 int idx;
1866 SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
1867 SiS_Pr->PanelVCLKIdx300 = VCLK_CUSTOM_300;
1868 if(HwInfo->jChipType < SIS_315H) idx = VCLK_CUSTOM_300;
1869 else idx = VCLK_CUSTOM_315;
1870 SiS_Pr->SiS_VCLKData[idx].CLOCK =
1871 SiS_Pr->SiS_VBVCLKData[idx].CLOCK = SiS_Pr->CP_PrefClock;
1872 SiS_Pr->SiS_VCLKData[idx].SR2B =
1873 SiS_Pr->SiS_VBVCLKData[idx].Part4_A = SiS_Pr->CP_PrefSR2B;
1874 SiS_Pr->SiS_VCLKData[idx].SR2C =
1875 SiS_Pr->SiS_VBVCLKData[idx].Part4_B = SiS_Pr->CP_PrefSR2C;
1876 }
1877 }
1878 break;
1879 default: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768;
1880 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1881 break;
1882 }
1883
1884 /* Special cases */
1885 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
1886 (SiS_Pr->SiS_IF_DEF_DSTN) ||
1887 (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
1888 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
1889 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ) {
1890 SiS_Pr->PanelHRS = 999;
1891 SiS_Pr->PanelHRE = 999;
1892 }
1893
1894 if( (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
1895 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
1896 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ) {
1897 SiS_Pr->PanelVRS = 999;
1898 SiS_Pr->PanelVRE = 999;
1899 }
1900
1901 /* DontExpand overrule */
1902 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
1903
1904 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (modeflag & NoSupportLCDScale)) {
1905 /* No scaling for this mode on any panel (LCD=CRT2)*/
1906 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1907 }
1908
1909 switch(SiS_Pr->SiS_LCDResInfo) {
1910
1911 case Panel_Custom:
1912 case Panel_1152x864:
1913 case Panel_1280x768: /* TMDS only */
1914 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1915 break;
1916
1917 case Panel_800x600: {
1918 static const UCHAR nonscalingmodes[] = {
1919 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, 0xff
1920 };
1921 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1922 break;
1923 }
1924 case Panel_1024x768: {
1925 static const UCHAR nonscalingmodes[] = {
1926 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1927 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1928 0xff
1929 };
1930 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1931 break;
1932 }
1933 case Panel_1280x720: {
1934 static const UCHAR nonscalingmodes[] = {
1935 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1936 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1937 0xff
1938 };
1939 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1940 if(SiS_Pr->PanelHT == 1650) {
1941 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1942 }
1943 break;
1944 }
1945 case Panel_1280x768_2: { /* LVDS only */
1946 static const UCHAR nonscalingmodes[] = {
1947 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1948 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1949 SIS_RI_1152x768,0xff
1950 };
1951 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1952 switch(resinfo) {
1953 case SIS_RI_1280x720: if(SiS_Pr->UsePanelScaler == -1) {
1954 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1955 }
1956 break;
1957 }
1958 break;
1959 }
1960 case Panel_1280x800: { /* SiS TMDS special (Averatec 6200 series) */
1961 static const UCHAR nonscalingmodes[] = {
1962 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1963 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1964 SIS_RI_1152x768,SIS_RI_1280x720,SIS_RI_1280x768,0xff
1965 };
1966 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1967 break;
1968 }
1969 case Panel_1280x800_2: { /* SiS LVDS */
1970 static const UCHAR nonscalingmodes[] = {
1971 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1972 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1973 SIS_RI_1152x768,0xff
1974 };
1975 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1976 switch(resinfo) {
1977 case SIS_RI_1280x720:
1978 case SIS_RI_1280x768: if(SiS_Pr->UsePanelScaler == -1) {
1979 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1980 }
1981 break;
1982 }
1983 break;
1984 }
1985 case Panel_1280x960: {
1986 static const UCHAR nonscalingmodes[] = {
1987 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1988 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1989 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
1990 0xff
1991 };
1992 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1993 break;
1994 }
1995 case Panel_1280x1024: {
1996 static const UCHAR nonscalingmodes[] = {
1997 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1998 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1999 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2000 SIS_RI_1280x960,0xff
2001 };
2002 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2003 break;
2004 }
2005 case Panel_1400x1050: {
2006 static const UCHAR nonscalingmodes[] = {
2007 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2008 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2009 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x768,SIS_RI_1280x800,SIS_RI_1280x960,
2010 0xff
2011 };
2012 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2013 switch(resinfo) {
2014 case SIS_RI_1280x720: if(SiS_Pr->UsePanelScaler == -1) {
2015 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2016 }
2017 break;
2018 case SIS_RI_1280x1024: SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2019 break;
2020 }
2021 break;
2022 }
2023 case Panel_1600x1200: {
2024 static const UCHAR nonscalingmodes[] = {
2025 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2026 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2027 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2028 SIS_RI_1280x960,SIS_RI_1360x768,SIS_RI_1360x1024,0xff
2029 };
2030 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2031 break;
2032 }
2033 case Panel_1680x1050: {
2034 static const UCHAR nonscalingmodes[] = {
2035 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2036 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2037 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x960,SIS_RI_1360x768,SIS_RI_1360x1024,
2038 0xff
2039 };
2040 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2041 break;
2042 }
2043 }
2044 }
2045
2046 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2047 if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
2048 SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20; /* neg h/v sync, RGB24(D0 = 0) */
2049 }
2050 }
2051
2052#ifdef SIS300
2053 if(HwInfo->jChipType < SIS_315H) {
2054 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2055 if(SiS_Pr->SiS_UseROM) {
2056 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
2057 if(!(ROMAddr[0x235] & 0x02)) {
2058 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2059 }
2060 }
2061 }
2062 } else if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
2063 if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
2064 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2065 }
2066 }
2067 }
2068#endif
2069
2070 /* Special cases */
2071
2072 if(modexres == SiS_Pr->PanelXRes && modeyres == SiS_Pr->PanelYRes) {
2073 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2074 }
2075
2076 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
2077 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2078 }
2079
2080 switch(SiS_Pr->SiS_LCDResInfo) {
2081 case Panel_640x480:
2082 SiS_Pr->SiS_LCDInfo |= LCDPass11;
2083 break;
2084 case Panel_1280x800:
2085 /* Don't pass 1:1 by default (TMDS special) */
2086 if(SiS_Pr->CenterScreen == -1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2087 break;
2088 case Panel_1280x960:
2089 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2090 break;
2091 case Panel_Custom:
2092 if((!SiS_Pr->CP_PrefClock) ||
2093 (modexres > SiS_Pr->PanelXRes) || (modeyres > SiS_Pr->PanelYRes)) {
2094 SiS_Pr->SiS_LCDInfo |= LCDPass11;
2095 }
2096 break;
2097 }
2098
2099 if(SiS_Pr->UseCustomMode) {
2100 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2101 }
2102
2103 /* (In)validate LCDPass11 flag */
2104 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2105 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
2106 }
2107
2108 /* LVDS DDA */
2109 if(!((HwInfo->jChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
2110
2111 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
2112 if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
2113 if(ModeNo == 0x12) {
2114 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
2115 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2116 }
2117 } else if(ModeNo > 0x13) {
2118 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
2119 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2120 if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) {
2121 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2122 }
2123 }
2124 }
2125 }
2126 }
2127 }
2128
2129 if(modeflag & HalfDCLK) {
2130 if(SiS_Pr->SiS_IF_DEF_TRUMPION == 1) {
2131 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2132 } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
2133 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2134 } else if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) {
2135 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2136 } else if(ModeNo > 0x13) {
2137 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
2138 if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2139 } else if(SiS_Pr->SiS_LCDResInfo == Panel_800x600) {
2140 if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2141 }
2142 }
2143 }
2144
2145 }
2146
2147 /* VESA timing */
2148 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2149 if(SiS_Pr->SiS_VBInfo & SetNotSimuMode) {
2150 SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2151 }
2152 } else {
2153 SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2154 }
2155
2156#ifdef LINUX_KERNEL
2157#ifdef TWDEBUG
2158 printk(KERN_DEBUG "sisfb: (LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n",
2159 SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo);
2160#endif
2161#endif
2162#ifdef LINUX_XF86
2163 xf86DrvMsgVerb(0, X_PROBED, 4,
2164 "(init301: LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x SetFlag=0x%04x)\n",
2165 SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo, SiS_Pr->SiS_SetFlag);
2166#endif
2167}
2168
2169/*********************************************/
2170/* GET VCLK */
2171/*********************************************/
2172
2173USHORT
2174SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2175 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
2176{
2177 USHORT CRT2Index,VCLKIndex=0,VCLKIndexGEN=0;
2178 USHORT modeflag,resinfo,tempbx;
2179 const UCHAR *CHTVVCLKPtr = NULL;
2180
2181 if(ModeNo <= 0x13) {
2182 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2183 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
2184 CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2185 VCLKIndexGEN = (SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)) >> 2) & 0x03;
2186 } else {
2187 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2188 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2189 CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2190 VCLKIndexGEN = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
2191 if(HwInfo->jChipType < SIS_315H) VCLKIndexGEN &= 0x3f;
2192 }
2193
2194 if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 30x/B/LV */
2195
2196 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2197
2198 CRT2Index >>= 6;
2199 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /* LCD */
2200
2201 if(HwInfo->jChipType < SIS_315H) {
2202 VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2203 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2204 VCLKIndex = VCLKIndexGEN;
2205 }
2206 } else {
2207 VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2208 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2209 switch(resinfo) {
2210 /* Only those whose IndexGEN doesn't match VBVCLK array */
2211 case SIS_RI_1280x720: VCLKIndex = VCLK_1280x720; break;
2212 case SIS_RI_720x480: VCLKIndex = VCLK_720x480; break;
2213 case SIS_RI_720x576: VCLKIndex = VCLK_720x576; break;
2214 case SIS_RI_768x576: VCLKIndex = VCLK_768x576; break;
2215 case SIS_RI_848x480: VCLKIndex = VCLK_848x480; break;
2216 case SIS_RI_856x480: VCLKIndex = VCLK_856x480; break;
2217 case SIS_RI_800x480: VCLKIndex = VCLK_800x480; break;
2218 case SIS_RI_1024x576: VCLKIndex = VCLK_1024x576; break;
2219 case SIS_RI_1152x864: VCLKIndex = VCLK_1152x864; break;
2220 case SIS_RI_1360x768: VCLKIndex = VCLK_1360x768; break;
2221 default: VCLKIndex = VCLKIndexGEN;
2222 }
2223
2224 if(ModeNo <= 0x13) {
2225 if(HwInfo->jChipType <= SIS_315PRO) {
2226 if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
2227 } else {
2228 if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x00;
2229 }
2230 }
2231 if(HwInfo->jChipType <= SIS_315PRO) {
2232 if(VCLKIndex == 0) VCLKIndex = 0x41;
2233 if(VCLKIndex == 1) VCLKIndex = 0x43;
2234 if(VCLKIndex == 4) VCLKIndex = 0x44;
2235 }
2236 }
2237 }
2238
2239 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* TV */
2240
2241 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
2242 if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = HiTVVCLKDIV2;
2243 else VCLKIndex = HiTVVCLK;
2244 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
2245 if(modeflag & Charx8Dot) VCLKIndex = HiTVSimuVCLK;
2246 else VCLKIndex = HiTVTextVCLK;
2247 }
2248 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) VCLKIndex = YPbPr750pVCLK;
2249 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) VCLKIndex = TVVCLKDIV2;
2250 else if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = TVVCLKDIV2;
2251 else VCLKIndex = TVVCLK;
2252
2253 if(HwInfo->jChipType < SIS_315H) VCLKIndex += TVCLKBASE_300;
2254 else VCLKIndex += TVCLKBASE_315;
2255
2256 } else { /* VGA2 */
2257
2258 VCLKIndex = VCLKIndexGEN;
2259 if(HwInfo->jChipType < SIS_315H) {
2260 if(ModeNo > 0x13) {
2261 if( (HwInfo->jChipType == SIS_630) &&
2262 (HwInfo->jChipRevision >= 0x30)) {
2263 if(VCLKIndex == 0x14) VCLKIndex = 0x34;
2264 }
2265 /* Better VGA2 clock for 1280x1024@75 */
2266 if(VCLKIndex == 0x17) VCLKIndex = 0x45;
2267 }
2268 }
2269 }
2270
2271 } else { /* If not programming CRT2 */
2272
2273 VCLKIndex = VCLKIndexGEN;
2274 if(HwInfo->jChipType < SIS_315H) {
2275 if(ModeNo > 0x13) {
2276 if( (HwInfo->jChipType != SIS_630) &&
2277 (HwInfo->jChipType != SIS_300) ) {
2278 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2279 }
2280 }
2281 }
2282 }
2283
2284 } else { /* LVDS */
2285
2286 VCLKIndex = CRT2Index;
2287
2288 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2289
2290 if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
2291
2292 VCLKIndex &= 0x1f;
2293 tempbx = 0;
2294 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2295 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2296 tempbx += 2;
2297 if(SiS_Pr->SiS_ModeType > ModeVGA) {
2298 if(SiS_Pr->SiS_CHSOverScan) tempbx = 8;
2299 }
2300 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
2301 tempbx = 4;
2302 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2303 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
2304 tempbx = 6;
2305 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2306 }
2307 }
2308 switch(tempbx) {
2309 case 0: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUNTSC; break;
2310 case 1: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKONTSC; break;
2311 case 2: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPAL; break;
2312 case 3: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break;
2313 case 4: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALM; break;
2314 case 5: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALM; break;
2315 case 6: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALN; break;
2316 case 7: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALN; break;
2317 case 8: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKSOPAL; break;
2318 default: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break;
2319 }
2320 VCLKIndex = CHTVVCLKPtr[VCLKIndex];
2321
2322 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2323
2324 if(HwInfo->jChipType < SIS_315H) {
2325 VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2326 } else {
2327 VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2328 }
2329
2330 /* Special Timing: Barco iQ Pro R series */
2331 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) VCLKIndex = 0x44;
2332
2333 /* Special Timing: 848x480 parallel lvds */
2334 if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
2335 if(HwInfo->jChipType < SIS_315H) {
2336 VCLKIndex = VCLK34_300;
2337 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2338 } else {
2339 VCLKIndex = VCLK34_315;
2340 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2341 }
2342 }
2343
2344 } else {
2345
2346 VCLKIndex = VCLKIndexGEN;
2347 if(HwInfo->jChipType < SIS_315H) {
2348 if(ModeNo > 0x13) {
2349 if( (HwInfo->jChipType == SIS_630) &&
2350 (HwInfo->jChipRevision >= 0x30) ) {
2351 if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
2352 }
2353 }
2354 }
2355 }
2356
2357 } else { /* if not programming CRT2 */
2358
2359 VCLKIndex = VCLKIndexGEN;
2360 if(HwInfo->jChipType < SIS_315H) {
2361 if(ModeNo > 0x13) {
2362 if( (HwInfo->jChipType != SIS_630) &&
2363 (HwInfo->jChipType != SIS_300) ) {
2364 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2365 }
2366#if 0
2367 if(HwInfo->jChipType == SIS_730) {
2368 if(VCLKIndex == 0x0b) VCLKIndex = 0x40; /* 1024x768-70 */
2369 if(VCLKIndex == 0x0d) VCLKIndex = 0x41; /* 1024x768-75 */
2370 }
2371#endif
2372 }
2373 }
2374
2375 }
2376
2377 }
2378
2379#ifdef TWDEBUG
2380 xf86DrvMsg(0, X_INFO, "VCLKIndex %d (0x%x)\n", VCLKIndex, VCLKIndex);
2381#endif
2382
2383 return(VCLKIndex);
2384}
2385
2386/*********************************************/
2387/* SET CRT2 MODE TYPE REGISTERS */
2388/*********************************************/
2389
2390static void
2391SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2392 PSIS_HW_INFO HwInfo)
2393{
2394 USHORT i,j,modeflag;
2395 USHORT tempcl,tempah=0;
2396#if defined(SIS300) || defined(SIS315H)
2397 USHORT tempbl;
2398#endif
2399#ifdef SIS315H
2400 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
2401 USHORT tempah2, tempbl2;
2402#endif
2403
2404 if(ModeNo <= 0x13) {
2405 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2406 } else if(SiS_Pr->UseCustomMode) {
2407 modeflag = SiS_Pr->CModeFlag;
2408 } else {
2409 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2410 }
2411
2412 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
2413
2414 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40);
2415 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2E,0xF7);
2416
2417 } else {
2418
2419 for(i=0,j=4; i<3; i++,j++) SiS_SetReg(SiS_Pr->SiS_Part1Port,j,0);
2420 if(HwInfo->jChipType >= SIS_315H) {
2421 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0x7F);
2422 }
2423
2424 tempcl = SiS_Pr->SiS_ModeType;
2425
2426 if(HwInfo->jChipType < SIS_315H) {
2427
2428#ifdef SIS300 /* ---- 300 series ---- */
2429
2430 /* For 301BDH: (with LCD via LVDS) */
2431 if(SiS_Pr->SiS_VBType & VB_NoLCD) {
2432 tempbl = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32);
2433 tempbl &= 0xef;
2434 tempbl |= 0x02;
2435 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2436 tempbl |= 0x10;
2437 tempbl &= 0xfd;
2438 }
2439 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,tempbl);
2440 }
2441
2442 if(ModeNo > 0x13) {
2443 tempcl -= ModeVGA;
2444 if((tempcl > 0) || (tempcl == 0)) { /* tempcl is USHORT -> always true! */
2445 tempah = ((0x10 >> tempcl) | 0x80);
2446 }
2447 } else tempah = 0x80;
2448
2449 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0xA0;
2450
2451#endif /* SIS300 */
2452
2453 } else {
2454
2455#ifdef SIS315H /* ------- 315/330 series ------ */
2456
2457 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
2458 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
2459 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x08);
2460 }
2461 }
2462
2463 if(ModeNo > 0x13) {
2464 tempcl -= ModeVGA;
2465 if((tempcl > 0) || (tempcl == 0)) { /* tempcl is USHORT -> always true! */
2466 tempah = (0x08 >> tempcl);
2467 if (tempah == 0) tempah = 1;
2468 tempah |= 0x40;
2469 }
2470 } else tempah = 0x40;
2471
2472 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50;
2473
2474#endif /* SIS315H */
2475
2476 }
2477
2478 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2479
2480 if(HwInfo->jChipType < SIS_315H) {
2481 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2482 } else {
2483 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2484 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2485 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
2486 if(IS_SIS740) {
2487 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2488 } else {
2489 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2490 }
2491 }
2492 }
2493
2494 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2495
2496 tempah = 0x01;
2497 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
2498 tempah |= 0x02;
2499 }
2500 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2501 tempah ^= 0x05;
2502 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
2503 tempah ^= 0x01;
2504 }
2505 }
2506
2507 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2508
2509 if(HwInfo->jChipType < SIS_315H) {
2510
2511 tempah = (tempah << 5) & 0xFF;
2512 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2513 tempah = (tempah >> 5) & 0xFF;
2514
2515 } else {
2516
2517 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF8,tempah);
2518
2519 }
2520
2521 if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
2522 tempah |= 0x10;
2523 }
2524
2525 tempah |= 0x80;
2526 if(SiS_Pr->SiS_VBType & VB_SIS301) {
2527 if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah &= ~0x80;
2528 }
2529
2530 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2531 if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p))) {
2532 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2533 tempah |= 0x20;
2534 }
2535 }
2536 }
2537
2538 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah);
2539
2540 tempah = 0x80;
2541 if(SiS_Pr->SiS_VBType & VB_SIS301) {
2542 if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah = 0;
2543 }
2544
2545 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempah |= 0x40;
2546
2547 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2548 if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) {
2549 tempah |= 0x40;
2550 }
2551 }
2552
2553 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0C,tempah);
2554
2555 } else { /* LVDS */
2556
2557 if(HwInfo->jChipType >= SIS_315H) {
2558
2559#ifdef SIS315H
2560 /* LVDS can only be slave in 8bpp modes */
2561 tempah = 0x80;
2562 if((modeflag & CRT2Mode) && (SiS_Pr->SiS_ModeType > ModeVGA)) {
2563 if(SiS_Pr->SiS_VBInfo & DriverMode) {
2564 tempah |= 0x02;
2565 }
2566 }
2567
2568 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
2569 tempah |= 0x02;
2570 }
2571
2572 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2573 tempah ^= 0x01;
2574 }
2575
2576 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
2577 tempah = 1;
2578 }
2579
2580 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah);
2581#endif
2582
2583 } else {
2584
2585#ifdef SIS300
2586 tempah = 0;
2587 if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
2588 tempah |= 0x02;
2589 }
2590 tempah <<= 5;
2591
2592 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2593
2594 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2595#endif
2596
2597 }
2598
2599 }
2600
2601 } /* LCDA */
2602
2603 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2604
2605 if(HwInfo->jChipType >= SIS_315H) {
2606
2607#ifdef SIS315H
2608 unsigned char bridgerev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01);
2609
2610 /* The following is nearly unpreditable and varies from machine
2611 * to machine. Especially the 301DH seems to be a real trouble
2612 * maker. Some BIOSes simply set the registers (like in the
2613 * NoLCD-if-statements here), some set them according to the
2614 * LCDA stuff. It is very likely that some machines are not
2615 * treated correctly in the following, very case-orientated
2616 * code. What do I do then...?
2617 */
2618
2619 /* 740 variants match for 30xB, 301B-DH, 30xLV */
2620
2621 if(!(IS_SIS740)) {
2622 tempah = 0x04; /* For all bridges */
2623 tempbl = 0xfb;
2624 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2625 tempah = 0x00;
2626 if(SiS_IsDualEdge(SiS_Pr, HwInfo)) {
2627 tempbl = 0xff;
2628 }
2629 }
2630 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2631 }
2632
2633 /* The following two are responsible for eventually wrong colors
2634 * in TV output. The DH (VB_NoLCD) conditions are unknown; the
2635 * b0 was found in some 651 machine (Pim; P4_23=0xe5); the b1 version
2636 * in a 650 box (Jake). What is the criteria?
2637 */
2638
2639 if((IS_SIS740) || (HwInfo->jChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
2640 tempah = 0x30;
2641 tempbl = 0xc0;
2642 if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2643 ((SiS_Pr->SiS_ROMNew) && (!(ROMAddr[0x5b] & 0x04)))) {
2644 tempah = 0x00;
2645 tempbl = 0x00;
2646 }
2647 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,tempah);
2648 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,tempbl);
2649 } else if(SiS_Pr->SiS_VBType & VB_SIS301) {
2650 /* Fixes "TV-blue-bug" on 315+301 */
2651 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xcf); /* For 301 */
2652 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2653 } else if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
2654 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30); /* For 30xLV */
2655 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);
2656 } else if((SiS_Pr->SiS_VBType & VB_NoLCD) && (bridgerev == 0xb0)) {
2657 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30); /* For 30xB-DH rev b0 (or "DH on 651"?) */
2658 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);
2659 } else {
2660 tempah = 0x30; tempah2 = 0xc0; /* For 30xB (and 301BDH rev b1) */
2661 tempbl = 0xcf; tempbl2 = 0x3f;
2662 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2663 tempah = tempah2 = 0x00;
2664 if(SiS_IsDualEdge(SiS_Pr, HwInfo)) {
2665 tempbl = tempbl2 = 0xff;
2666 }
2667 }
2668 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2669 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2670 }
2671
2672 if(IS_SIS740) {
2673 tempah = 0x80;
2674 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x00;
2675 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,0x7f,tempah);
2676 } else {
2677 tempah = 0x00;
2678 tempbl = 0x7f;
2679 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2680 tempbl = 0xff;
2681 if(!(SiS_IsDualEdge(SiS_Pr, HwInfo))) tempah = 0x80;
2682 }
2683 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
2684 }
2685
2686#endif /* SIS315H */
2687
2688 } else if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
2689
2690#ifdef SIS300
2691 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2692
2693 if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2694 ((SiS_Pr->SiS_VBType & VB_NoLCD) &&
2695 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD))) {
2696 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x23,0x7F);
2697 } else {
2698 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x23,0x80);
2699 }
2700#endif
2701
2702 }
2703
2704 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
2705 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x0D,0x80);
2706 if(SiS_Pr->SiS_VBType & VB_SIS301C) {
2707 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3A,0xC0);
2708 }
2709 }
2710
2711 } else { /* LVDS */
2712
2713#ifdef SIS315H
2714 if(HwInfo->jChipType >= SIS_315H) {
2715
2716 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
2717
2718 tempah = 0x04;
2719 tempbl = 0xfb;
2720 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2721 tempah = 0x00;
2722 if(SiS_IsDualEdge(SiS_Pr, HwInfo)) tempbl = 0xff;
2723 }
2724 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2725
2726 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
2727 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
2728 }
2729
2730 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
2731
2732 } else if(HwInfo->jChipType == SIS_550) {
2733
2734 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
2735 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
2736
2737 }
2738
2739 }
2740#endif
2741
2742 }
2743
2744}
2745
2746/*********************************************/
2747/* GET RESOLUTION DATA */
2748/*********************************************/
2749
2750USHORT
2751SiS_GetResInfo(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex)
2752{
2753 if(ModeNo <= 0x13) return((USHORT)SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo);
2754 else return((USHORT)SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO);
2755}
2756
2757static void
2758SiS_GetCRT2ResInfo(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
2759 PSIS_HW_INFO HwInfo)
2760{
2761 USHORT xres,yres,modeflag=0,resindex;
2762
2763 if(SiS_Pr->UseCustomMode) {
2764 xres = SiS_Pr->CHDisplay;
2765 if(SiS_Pr->CModeFlag & HalfDCLK) xres *= 2;
2766 SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
2767 yres = SiS_Pr->CVDisplay;
2768 if(SiS_Pr->CModeFlag & DoubleScanMode) yres *= 2;
2769 SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
2770 return;
2771 }
2772
2773 resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex);
2774
2775 if(ModeNo <= 0x13) {
2776 xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
2777 yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
2778 } else {
2779 xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
2780 yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
2781 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2782 }
2783
2784 if(!SiS_Pr->SiS_IF_DEF_DSTN && !SiS_Pr->SiS_IF_DEF_FSTN) {
2785
2786 if((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
2787 if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
2788 if(yres == 350) yres = 400;
2789 }
2790 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
2791 if(ModeNo == 0x12) yres = 400;
2792 }
2793 }
2794
2795 if(modeflag & HalfDCLK) xres *= 2;
2796 if(modeflag & DoubleScanMode) yres *= 2;
2797
2798 }
2799
2800 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
2801
2802#if 0
2803 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCDA | SetCRT2ToLCD | SetCRT2ToHiVision)) {
2804 if(xres == 720) xres = 640;
2805 }
2806#endif
2807
2808 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2809 switch(SiS_Pr->SiS_LCDResInfo) {
2810 case Panel_1024x768:
2811 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
2812 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2813 if(yres == 350) yres = 357;
2814 if(yres == 400) yres = 420;
2815 if(yres == 480) yres = 525;
2816 }
2817 }
2818 break;
2819 case Panel_1280x1024:
2820 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2821 /* BIOS bug - does this regardless of scaling */
2822 if(yres == 400) yres = 405;
2823 }
2824 if(yres == 350) yres = 360;
2825 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
2826 if(yres == 360) yres = 375;
2827 }
2828 break;
2829 case Panel_1600x1200:
2830 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
2831 if(yres == 1024) yres = 1056;
2832 }
2833 break;
2834 }
2835 }
2836
2837 } else {
2838
2839 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2840 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVision)) {
2841 if(xres == 720) xres = 640;
2842 }
2843 } else if(xres == 720) xres = 640;
2844
2845 if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
2846 yres = 400;
2847 if(HwInfo->jChipType >= SIS_315H) {
2848 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
2849 } else {
2850 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
2851 }
2852 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) yres = 480;
2853 }
2854
2855 }
2856 SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
2857 SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
2858}
2859
2860/*********************************************/
2861/* GET CRT2 TIMING DATA */
2862/*********************************************/
2863
2864static BOOLEAN
2865SiS_GetLVDSCRT1Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2866 USHORT RefreshRateTableIndex, USHORT *ResIndex,
2867 USHORT *DisplayType)
2868 {
2869 USHORT modeflag=0;
2870
2871 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2872 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2873 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return FALSE;
2874 }
2875 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
2876 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return FALSE;
2877 } else
2878 return FALSE;
2879
2880 if(ModeNo <= 0x13) {
2881 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2882 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2883 } else {
2884 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2885 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2886 }
2887
2888 (*ResIndex) &= 0x3F;
2889
2890 if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
2891 (*DisplayType) = 18;
2892 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
2893 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2894 (*DisplayType) += 2;
2895 if(SiS_Pr->SiS_ModeType > ModeVGA) {
2896 if(SiS_Pr->SiS_CHSOverScan) (*DisplayType) = 99;
2897 }
2898 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
2899 (*DisplayType) = 18; /* PALM uses NTSC data */
2900 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
2901 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
2902 (*DisplayType) = 20; /* PALN uses PAL data */
2903 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
2904 }
2905 }
2906 } else {
2907 switch(SiS_Pr->SiS_LCDResInfo) {
2908 case Panel_640x480: (*DisplayType) = 50; break;
2909 case Panel_640x480_2: (*DisplayType) = 52; break;
2910 case Panel_640x480_3: (*DisplayType) = 54; break;
2911 case Panel_800x600: (*DisplayType) = 0; break;
2912 case Panel_1024x600: (*DisplayType) = 23; break;
2913 case Panel_1024x768: (*DisplayType) = 4; break;
2914 case Panel_1152x768: (*DisplayType) = 27; break;
2915 case Panel_1280x768: (*DisplayType) = 40; break;
2916 case Panel_1280x1024: (*DisplayType) = 8; break;
2917 case Panel_1400x1050: (*DisplayType) = 14; break;
2918 case Panel_1600x1200: (*DisplayType) = 36; break;
2919 default: return FALSE;
2920 }
2921
2922 if(modeflag & HalfDCLK) (*DisplayType)++;
2923
2924 switch(SiS_Pr->SiS_LCDResInfo) {
2925 case Panel_640x480:
2926 case Panel_640x480_2:
2927 case Panel_640x480_3:
2928 break;
2929 default:
2930 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) (*DisplayType) += 2;
2931 }
2932
2933 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
2934 (*DisplayType) = 12;
2935 if(modeflag & HalfDCLK) (*DisplayType)++;
2936 }
2937 }
2938
2939#if 0
2940 if(SiS_Pr->SiS_IF_DEF_FSTN) {
2941 if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel320x480){
2942 (*DisplayType) = 22;
2943 }
2944 }
2945#endif
2946
2947 return TRUE;
2948}
2949
2950static void
2951SiS_GetCRT2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
2952 USHORT RefreshRateTableIndex,USHORT *CRT2Index,USHORT *ResIndex,
2953 PSIS_HW_INFO HwInfo)
2954{
2955 USHORT tempbx=0,tempal=0,resinfo=0;
2956
2957 if(ModeNo <= 0x13) {
2958 tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2959 } else {
2960 tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2961 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2962 }
2963
2964 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_IF_DEF_LVDS == 0)) {
2965
2966 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { /* LCD */
2967
2968 tempbx = SiS_Pr->SiS_LCDResInfo;
2969 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 32;
2970
2971 if(SiS_Pr->SiS_LCDResInfo == Panel_1680x1050) {
2972 if (resinfo == SIS_RI_1280x800) tempal = 9;
2973 else if(resinfo == SIS_RI_1400x1050) tempal = 11;
2974 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x800) ||
2975 (SiS_Pr->SiS_LCDResInfo == Panel_1280x800_2)) {
2976 if (resinfo == SIS_RI_1280x768) tempal = 9;
2977 }
2978
2979 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
2980 /* Pass 1:1 only (center-screen handled outside) */
2981 /* This is never called for the panel's native resolution */
2982 /* since Pass1:1 will not be set in this case */
2983 tempbx = 100;
2984 if(ModeNo >= 0x13) {
2985 tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
2986 }
2987 }
2988
2989#ifdef SIS315H
2990 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
2991 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
2992 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2993 tempbx = 200;
2994 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
2995 }
2996 }
2997 }
2998#endif
2999
3000 } else { /* TV */
3001
3002 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
3003 /* if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_TVMode &= (~TVSetTVSimuMode); */
3004 tempbx = 2;
3005 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
3006 tempbx = 13;
3007 if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) tempbx = 14;
3008 }
3009 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3010 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempbx = 7;
3011 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempbx = 6;
3012 else tempbx = 5;
3013 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5;
3014 } else {
3015 if(SiS_Pr->SiS_TVMode & TVSetPAL) tempbx = 3;
3016 else tempbx = 4;
3017 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5;
3018 }
3019
3020 }
3021
3022 tempal &= 0x3F;
3023
3024 if(ModeNo > 0x13) {
3025 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) {
3026 if(tempal == 6) tempal = 7;
3027 if((resinfo == SIS_RI_720x480) ||
3028 (resinfo == SIS_RI_720x576) ||
3029 (resinfo == SIS_RI_768x576)) {
3030 tempal = 6;
3031 if(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetPALN)) {
3032 if(resinfo == SIS_RI_720x480) tempal = 9;
3033 }
3034 }
3035 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3036 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
3037 if(resinfo == SIS_RI_1024x768) tempal = 8;
3038 }
3039 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
3040 if((resinfo == SIS_RI_720x576) ||
3041 (resinfo == SIS_RI_768x576)) {
3042 tempal = 8;
3043 }
3044 if(resinfo == SIS_RI_1280x720) tempal = 9;
3045 }
3046 }
3047 }
3048 }
3049
3050 *CRT2Index = tempbx;
3051 *ResIndex = tempal;
3052
3053 } else { /* LVDS, 301B-DH (if running on LCD) */
3054
3055 tempbx = 0;
3056 if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
3057
3058 tempbx = 10;
3059 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
3060 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
3061 tempbx += 2;
3062 if(SiS_Pr->SiS_ModeType > ModeVGA) {
3063 if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
3064 }
3065 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
3066 tempbx = 90;
3067 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
3068 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
3069 tempbx = 92;
3070 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
3071 }
3072 }
3073
3074 } else {
3075
3076 switch(SiS_Pr->SiS_LCDResInfo) {
3077 case Panel_640x480: tempbx = 6; break;
3078 case Panel_640x480_2:
3079 case Panel_640x480_3: tempbx = 30; break;
3080 case Panel_800x600: tempbx = 0; break;
3081 case Panel_1024x600: tempbx = 15; break;
3082 case Panel_1024x768: tempbx = 2; break;
3083 case Panel_1152x768: tempbx = 17; break;
3084 case Panel_1280x768: tempbx = 18; break;
3085 case Panel_1280x1024: tempbx = 4; break;
3086 case Panel_1400x1050: tempbx = 8; break;
3087 case Panel_1600x1200: tempbx = 21; break;
3088 case Panel_Barco1366: tempbx = 80; break;
3089 }
3090
3091 switch(SiS_Pr->SiS_LCDResInfo) {
3092 case Panel_640x480:
3093 case Panel_640x480_2:
3094 case Panel_640x480_3:
3095 break;
3096 default:
3097 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3098 }
3099
3100 if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempbx = 7;
3101
3102 if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
3103 tempbx = 82;
3104 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3105 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
3106 tempbx = 84;
3107 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3108 }
3109
3110 if((SiS_Pr->SiS_CustomT != CUT_BARCO1366) &&
3111 (SiS_Pr->SiS_CustomT != CUT_PANEL848)) {
3112 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) &&
3113 (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
3114 tempal = 0;
3115 }
3116 }
3117
3118 }
3119
3120 (*CRT2Index) = tempbx;
3121 (*ResIndex) = tempal & 0x1F;
3122 }
3123}
3124
3125static void
3126SiS_GetRAMDAC2DATA(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
3127 USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo)
3128{
3129 USHORT tempax=0,tempbx=0;
3130 USHORT temp1=0,modeflag=0,tempcx=0;
3131 USHORT index;
3132
3133 SiS_Pr->SiS_RVBHCMAX = 1;
3134 SiS_Pr->SiS_RVBHCFACT = 1;
3135
3136 if(ModeNo <= 0x13) {
3137
3138 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3139 index = SiS_GetModePtr(SiS_Pr,ModeNo,ModeIdIndex);
3140
3141 tempax = SiS_Pr->SiS_StandTable[index].CRTC[0];
3142 tempbx = SiS_Pr->SiS_StandTable[index].CRTC[6];
3143 temp1 = SiS_Pr->SiS_StandTable[index].CRTC[7];
3144
3145 } else {
3146
3147 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3148 index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
3149
3150 tempax = SiS_Pr->SiS_CRT1Table[index].CR[0];
3151 tempax |= (SiS_Pr->SiS_CRT1Table[index].CR[14] << 8);
3152 tempax &= 0x03FF;
3153 tempbx = SiS_Pr->SiS_CRT1Table[index].CR[6];
3154 tempcx = SiS_Pr->SiS_CRT1Table[index].CR[13] << 8;
3155 tempcx &= 0x0100;
3156 tempcx <<= 2;
3157 tempbx |= tempcx;
3158 temp1 = SiS_Pr->SiS_CRT1Table[index].CR[7];
3159
3160 }
3161
3162 if(temp1 & 0x01) tempbx |= 0x0100;
3163 if(temp1 & 0x20) tempbx |= 0x0200;
3164
3165 tempax += 5;
3166
3167 /* Charx8Dot is no more used (and assumed), so we set it */
3168 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
3169 modeflag |= Charx8Dot;
3170 }
3171
3172 if(modeflag & Charx8Dot) tempax *= 8;
3173 else tempax *= 9;
3174
3175 if(modeflag & HalfDCLK) tempax <<= 1;
3176
3177 tempbx++;
3178
3179 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3180 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = tempbx;
3181}
3182
3183static void
3184SiS_GetCRT2DataLVDS(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
3185 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
3186{
3187 USHORT CRT2Index, ResIndex;
3188 const SiS_LVDSDataStruct *LVDSData = NULL;
3189
3190 SiS_GetCRT2ResInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
3191
3192 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3193 SiS_Pr->SiS_RVBHCMAX = 1;
3194 SiS_Pr->SiS_RVBHCFACT = 1;
3195 SiS_Pr->SiS_NewFlickerMode = 0;
3196 SiS_Pr->SiS_RVBHRS = 50;
3197 SiS_Pr->SiS_RY1COE = 0;
3198 SiS_Pr->SiS_RY2COE = 0;
3199 SiS_Pr->SiS_RY3COE = 0;
3200 SiS_Pr->SiS_RY4COE = 0;
3201 }
3202
3203 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3204
3205#ifdef SIS315H
3206 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3207 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
3208 if(SiS_Pr->UseCustomMode) {
3209 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->CHTotal;
3210 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3211 } else {
3212 if(ModeNo < 0x13) {
3213 ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3214 } else {
3215 ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
3216 }
3217 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAHT;
3218 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAVT;
3219 SiS_Pr->SiS_HT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDHT;
3220 SiS_Pr->SiS_VT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDVT;
3221 }
3222 } else {
3223 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3224 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3225 }
3226 } else {
3227 /* This handles custom modes and custom panels */
3228 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3229 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3230 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3231 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3232 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT - (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE);
3233 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT - (SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE);
3234 }
3235
3236 SiS_CalcLCDACRT1Timing(SiS_Pr,ModeNo,ModeIdIndex);
3237
3238#endif
3239
3240 } else {
3241
3242 /* 301BDH needs LVDS Data */
3243 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3244 SiS_Pr->SiS_IF_DEF_LVDS = 1;
3245 }
3246
3247 SiS_GetCRT2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
3248 &CRT2Index, &ResIndex, HwInfo);
3249
3250 /* 301BDH needs LVDS Data */
3251 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3252 SiS_Pr->SiS_IF_DEF_LVDS = 0;
3253 }
3254
3255 switch (CRT2Index) {
3256 case 0: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1; break;
3257 case 1: LVDSData = SiS_Pr->SiS_LVDS800x600Data_2; break;
3258 case 2: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break;
3259 case 3: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_2; break;
3260 case 4: LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_1; break;
3261 case 5: LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_2; break;
3262 case 6: LVDSData = SiS_Pr->SiS_LVDS640x480Data_1; break;
3263 case 7: LVDSData = SiS_Pr->SiS_LVDSXXXxXXXData_1; break;
3264 case 8: LVDSData = SiS_Pr->SiS_LVDS1400x1050Data_1; break;
3265 case 9: LVDSData = SiS_Pr->SiS_LVDS1400x1050Data_2; break;
3266 case 10: LVDSData = SiS_Pr->SiS_CHTVUNTSCData; break;
3267 case 11: LVDSData = SiS_Pr->SiS_CHTVONTSCData; break;
3268 case 12: LVDSData = SiS_Pr->SiS_CHTVUPALData; break;
3269 case 13: LVDSData = SiS_Pr->SiS_CHTVOPALData; break;
3270 case 14: LVDSData = SiS_Pr->SiS_LVDS320x480Data_1; break;
3271 case 15: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1; break;
3272 case 16: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_2; break;
3273 case 17: LVDSData = SiS_Pr->SiS_LVDS1152x768Data_1; break;
3274 case 18: LVDSData = SiS_Pr->SiS_LVDS1152x768Data_2; break;
3275 case 19: LVDSData = SiS_Pr->SiS_LVDS1280x768Data_1; break;
3276 case 20: LVDSData = SiS_Pr->SiS_LVDS1280x768Data_2; break;
3277 case 21: LVDSData = SiS_Pr->SiS_LVDS1600x1200Data_1; break;
3278 case 22: LVDSData = SiS_Pr->SiS_LVDS1600x1200Data_2; break;
3279 case 30: LVDSData = SiS_Pr->SiS_LVDS640x480Data_2; break;
3280 case 80: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1; break;
3281 case 81: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2; break;
3282 case 82: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1; break;
3283 case 83: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_2; break;
3284 case 84: LVDSData = SiS_Pr->SiS_LVDS848x480Data_1; break;
3285 case 85: LVDSData = SiS_Pr->SiS_LVDS848x480Data_2; break;
3286 case 90: LVDSData = SiS_Pr->SiS_CHTVUPALMData; break;
3287 case 91: LVDSData = SiS_Pr->SiS_CHTVOPALMData; break;
3288 case 92: LVDSData = SiS_Pr->SiS_CHTVUPALNData; break;
3289 case 93: LVDSData = SiS_Pr->SiS_CHTVOPALNData; break;
3290 case 99: LVDSData = SiS_Pr->SiS_CHTVSOPALData; break; /* Super Overscan */
3291 default: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break;
3292 }
3293
3294 SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT;
3295 SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT;
3296 SiS_Pr->SiS_HT = (LVDSData+ResIndex)->LCDHT;
3297 SiS_Pr->SiS_VT = (LVDSData+ResIndex)->LCDVT;
3298
3299 if(!(SiS_Pr->SiS_VBType & VB_SISVB)) {
3300 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
3301 if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
3302 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3303 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3304 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3305 if(ResIndex < 0x08) {
3306 SiS_Pr->SiS_HDE = 1280;
3307 SiS_Pr->SiS_VDE = 1024;
3308 }
3309 }
3310 }
3311 }
3312 }
3313 }
3314}
3315
3316static void
3317SiS_GetCRT2Data301(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
3318 USHORT RefreshRateTableIndex,
3319 PSIS_HW_INFO HwInfo)
3320{
3321 UCHAR *ROMAddr = NULL;
3322 USHORT tempax,tempbx,modeflag,romptr=0;
3323 USHORT resinfo,CRT2Index,ResIndex;
3324 const SiS_LCDDataStruct *LCDPtr = NULL;
3325 const SiS_TVDataStruct *TVPtr = NULL;
3326#ifdef SIS315H
3327 SHORT resinfo661;
3328#endif
3329
3330 if(ModeNo <= 0x13) {
3331 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3332 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
3333 } else if(SiS_Pr->UseCustomMode) {
3334 modeflag = SiS_Pr->CModeFlag;
3335 resinfo = 0;
3336 } else {
3337 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3338 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
3339#ifdef SIS315H
3340 resinfo661 = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].ROMMODEIDX661;
3341 if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
3342 (SiS_Pr->SiS_SetFlag & LCDVESATiming) &&
3343 (resinfo661 >= 0) &&
3344 (SiS_Pr->SiS_NeedRomModeData) ) {
3345 if((ROMAddr = GetLCDStructPtr661(SiS_Pr, HwInfo))) {
3346 if((romptr = (SISGETROMW(21)))) {
3347 romptr += (resinfo661 * 10);
3348 ROMAddr = HwInfo->pjVirtualRomBase;
3349 }
3350 }
3351 }
3352#endif
3353 }
3354
3355 SiS_Pr->SiS_NewFlickerMode = 0;
3356 SiS_Pr->SiS_RVBHRS = 50;
3357 SiS_Pr->SiS_RY1COE = 0;
3358 SiS_Pr->SiS_RY2COE = 0;
3359 SiS_Pr->SiS_RY3COE = 0;
3360 SiS_Pr->SiS_RY4COE = 0;
3361
3362 SiS_GetCRT2ResInfo(SiS_Pr,ModeNo,ModeIdIndex,HwInfo);
3363
3364 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC){
3365
3366 if(SiS_Pr->UseCustomMode) {
3367
3368 SiS_Pr->SiS_RVBHCMAX = 1;
3369 SiS_Pr->SiS_RVBHCFACT = 1;
3370 SiS_Pr->SiS_VGAHT = SiS_Pr->CHTotal;
3371 SiS_Pr->SiS_VGAVT = SiS_Pr->CVTotal;
3372 SiS_Pr->SiS_HT = SiS_Pr->CHTotal;
3373 SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3374 SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE;
3375 SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE;
3376
3377 } else {
3378
3379 SiS_GetRAMDAC2DATA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
3380
3381 }
3382
3383 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
3384
3385 SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3386 &CRT2Index,&ResIndex,HwInfo);
3387
3388 switch(CRT2Index) {
3389 case 2: TVPtr = SiS_Pr->SiS_ExtHiTVData; break;
3390 case 3: TVPtr = SiS_Pr->SiS_ExtPALData; break;
3391 case 4: TVPtr = SiS_Pr->SiS_ExtNTSCData; break;
3392 case 5: TVPtr = SiS_Pr->SiS_Ext525iData; break;
3393 case 6: TVPtr = SiS_Pr->SiS_Ext525pData; break;
3394 case 7: TVPtr = SiS_Pr->SiS_Ext750pData; break;
3395 case 8: TVPtr = SiS_Pr->SiS_StPALData; break;
3396 case 9: TVPtr = SiS_Pr->SiS_StNTSCData; break;
3397 case 10: TVPtr = SiS_Pr->SiS_St525iData; break;
3398 case 11: TVPtr = SiS_Pr->SiS_St525pData; break;
3399 case 12: TVPtr = SiS_Pr->SiS_St750pData; break;
3400 case 13: TVPtr = SiS_Pr->SiS_St1HiTVData; break;
3401 case 14: TVPtr = SiS_Pr->SiS_St2HiTVData; break;
3402 default: TVPtr = SiS_Pr->SiS_StPALData; break;
3403 }
3404
3405 SiS_Pr->SiS_RVBHCMAX = (TVPtr+ResIndex)->RVBHCMAX;
3406 SiS_Pr->SiS_RVBHCFACT = (TVPtr+ResIndex)->RVBHCFACT;
3407 SiS_Pr->SiS_VGAHT = (TVPtr+ResIndex)->VGAHT;
3408 SiS_Pr->SiS_VGAVT = (TVPtr+ResIndex)->VGAVT;
3409 SiS_Pr->SiS_HDE = (TVPtr+ResIndex)->TVHDE;
3410 SiS_Pr->SiS_VDE = (TVPtr+ResIndex)->TVVDE;
3411 SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->RVBHRS;
3412 SiS_Pr->SiS_NewFlickerMode = (TVPtr+ResIndex)->FlickerMode;
3413 if(modeflag & HalfDCLK) {
3414 SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->HALFRVBHRS;
3415 }
3416
3417 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
3418
3419 if((resinfo == SIS_RI_1024x768) ||
3420 (resinfo == SIS_RI_1280x1024) ||
3421 (resinfo == SIS_RI_1280x720)) {
3422 SiS_Pr->SiS_NewFlickerMode = 0x40;
3423 }
3424
3425 if(SiS_Pr->SiS_VGAVDE == 350) SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
3426
3427 SiS_Pr->SiS_HT = ExtHiTVHT;
3428 SiS_Pr->SiS_VT = ExtHiTVVT;
3429 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
3430 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
3431 SiS_Pr->SiS_HT = StHiTVHT;
3432 SiS_Pr->SiS_VT = StHiTVVT;
3433#if 0
3434 if(!(modeflag & Charx8Dot)) {
3435 SiS_Pr->SiS_HT = StHiTextTVHT;
3436 SiS_Pr->SiS_VT = StHiTextTVVT;
3437 }
3438#endif
3439 }
3440 }
3441
3442 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3443
3444 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
3445 SiS_Pr->SiS_HT = 1650;
3446 SiS_Pr->SiS_VT = 750;
3447 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
3448 SiS_Pr->SiS_HT = NTSCHT;
3449 SiS_Pr->SiS_VT = NTSCVT;
3450 } else {
3451 SiS_Pr->SiS_HT = NTSCHT;
3452 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3453 SiS_Pr->SiS_VT = NTSCVT;
3454 }
3455
3456 } else {
3457
3458 SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
3459 SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
3460 SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
3461 SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
3462
3463 if(modeflag & HalfDCLK) {
3464 SiS_Pr->SiS_RY1COE = 0x00;
3465 SiS_Pr->SiS_RY2COE = 0xf4;
3466 SiS_Pr->SiS_RY3COE = 0x10;
3467 SiS_Pr->SiS_RY4COE = 0x38;
3468 }
3469
3470 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
3471 SiS_Pr->SiS_HT = NTSCHT;
3472 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3473 SiS_Pr->SiS_VT = NTSCVT;
3474 } else {
3475 SiS_Pr->SiS_HT = PALHT;
3476 SiS_Pr->SiS_VT = PALVT;
3477 }
3478
3479 }
3480
3481 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3482
3483 SiS_Pr->SiS_RVBHCMAX = 1;
3484 SiS_Pr->SiS_RVBHCFACT = 1;
3485
3486 if(SiS_Pr->UseCustomMode) {
3487
3488 SiS_Pr->SiS_VGAHT = SiS_Pr->CHTotal;
3489 SiS_Pr->SiS_VGAVT = SiS_Pr->CVTotal;
3490 SiS_Pr->SiS_HT = SiS_Pr->CHTotal;
3491 SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3492 SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE;
3493 SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE;
3494
3495 } else {
3496
3497 BOOLEAN gotit = FALSE;
3498
3499 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
3500
3501 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
3502 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
3503 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3504 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3505 gotit = TRUE;
3506
3507 } else if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) && (romptr) && (ROMAddr) ) {
3508
3509#ifdef SIS315H
3510 SiS_Pr->SiS_RVBHCMAX = ROMAddr[romptr];
3511 SiS_Pr->SiS_RVBHCFACT = ROMAddr[romptr+1];
3512 SiS_Pr->SiS_VGAHT = ROMAddr[romptr+2] | ((ROMAddr[romptr+3] & 0x0f) << 8);
3513 SiS_Pr->SiS_VGAVT = ROMAddr[romptr+4] | ((ROMAddr[romptr+3] & 0xf0) << 4);
3514 SiS_Pr->SiS_HT = ROMAddr[romptr+5] | ((ROMAddr[romptr+6] & 0x0f) << 8);
3515 SiS_Pr->SiS_VT = ROMAddr[romptr+7] | ((ROMAddr[romptr+6] & 0xf0) << 4);
3516 if(SiS_Pr->SiS_VGAHT) gotit = TRUE;
3517 else {
3518 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
3519 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
3520 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
3521 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
3522 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3523 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3524 gotit = TRUE;
3525 }
3526#endif
3527
3528 }
3529
3530 if(!gotit) {
3531
3532 SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3533 &CRT2Index,&ResIndex,HwInfo);
3534
3535 switch(CRT2Index) {
3536 case Panel_1024x768 : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break;
3537 case Panel_1024x768 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data; break;
3538 case Panel_1280x720 :
3539 case Panel_1280x720 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x720Data; break;
3540 case Panel_1280x768_2 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x768_2Data; break;
3541 case Panel_1280x768_2+ 32: LCDPtr = SiS_Pr->SiS_StLCD1280x768_2Data; break;
3542 case Panel_1280x800 :
3543 case Panel_1280x800 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x800Data; break;
3544 case Panel_1280x800_2 :
3545 case Panel_1280x800_2+ 32: LCDPtr = SiS_Pr->SiS_LCD1280x800_2Data; break;
3546 case Panel_1280x960 :
3547 case Panel_1280x960 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x960Data; break;
3548 case Panel_1280x1024 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data; break;
3549 case Panel_1280x1024 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
3550 case Panel_1400x1050 : LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data; break;
3551 case Panel_1400x1050 + 32: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data; break;
3552 case Panel_1600x1200 : LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data; break;
3553 case Panel_1600x1200 + 32: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data; break;
3554 case Panel_1680x1050 :
3555 case Panel_1680x1050 + 32: LCDPtr = SiS_Pr->SiS_LCD1680x1050Data; break;
3556 case 100 : LCDPtr = SiS_Pr->SiS_NoScaleData; break;
3557#ifdef SIS315H
3558 case 200 : LCDPtr = SiS310_ExtCompaq1280x1024Data; break;
3559 case 201 : LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
3560#endif
3561 default : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break;
3562 }
3563
3564#ifdef TWDEBUG
3565 xf86DrvMsg(0, X_INFO, "GetCRT2Data: Index %d ResIndex %d\n", CRT2Index, ResIndex);
3566#endif
3567
3568 SiS_Pr->SiS_RVBHCMAX = (LCDPtr+ResIndex)->RVBHCMAX;
3569 SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
3570 SiS_Pr->SiS_VGAHT = (LCDPtr+ResIndex)->VGAHT;
3571 SiS_Pr->SiS_VGAVT = (LCDPtr+ResIndex)->VGAVT;
3572 SiS_Pr->SiS_HT = (LCDPtr+ResIndex)->LCDHT;
3573 SiS_Pr->SiS_VT = (LCDPtr+ResIndex)->LCDVT;
3574
3575 }
3576
3577 tempax = SiS_Pr->PanelXRes;
3578 tempbx = SiS_Pr->PanelYRes;
3579
3580 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3581 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
3582 if(HwInfo->jChipType < SIS_315H) {
3583 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3584 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3585 }
3586 } else {
3587 if (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
3588 else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
3589 else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
3590 else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
3591 else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3592 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3593 }
3594 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960) {
3595 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 700;
3596 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 800;
3597 else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
3598 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
3599 if (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
3600 else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
3601 else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
3602 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) {
3603 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
3604 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 875;
3605 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 1000;
3606 }
3607 }
3608
3609 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3610 tempax = SiS_Pr->SiS_VGAHDE;
3611 tempbx = SiS_Pr->SiS_VGAVDE;
3612 }
3613
3614 SiS_Pr->SiS_HDE = tempax;
3615 SiS_Pr->SiS_VDE = tempbx;
3616 }
3617 }
3618}
3619
3620static void
3621SiS_GetCRT2Data(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
3622 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
3623{
3624
3625 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3626
3627 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
3628 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
3629 } else {
3630 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3631 /* Need LVDS Data for LCD on 301B-DH */
3632 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
3633 } else {
3634 SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
3635 }
3636 }
3637
3638 } else {
3639
3640 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
3641
3642 }
3643}
3644
3645/*********************************************/
3646/* GET LVDS DES (SKEW) DATA */
3647/*********************************************/
3648
3649static void
3650SiS_GetLVDSDesPtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
3651 USHORT RefreshRateTableIndex, USHORT *PanelIndex,
3652 USHORT *ResIndex, PSIS_HW_INFO HwInfo)
3653{
3654 USHORT modeflag;
3655
3656 if(ModeNo <= 0x13) {
3657 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3658 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3659 } else {
3660 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3661 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
3662 }
3663
3664 (*ResIndex) &= 0x1F;
3665 (*PanelIndex) = 0;
3666
3667 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
3668 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
3669 (*PanelIndex) = 50;
3670 if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) (*PanelIndex) += 2;
3671 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*PanelIndex) += 1;
3672 /* Nothing special needed for SOverscan */
3673 /* PALM uses NTSC data, PALN uses PAL data */
3674 }
3675 }
3676
3677 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3678 *PanelIndex = SiS_Pr->SiS_LCDTypeInfo;
3679 if(HwInfo->jChipType >= SIS_661) {
3680 /* As long as we don's use the BIOS tables, we
3681 * need to convert the TypeInfo as for 315 series
3682 */
3683 (*PanelIndex) = SiS_Pr->SiS_LCDResInfo - 1;
3684 }
3685 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3686 (*PanelIndex) += 16;
3687 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
3688 (*PanelIndex) = 32;
3689 if(modeflag & HalfDCLK) (*PanelIndex)++;
3690 }
3691 }
3692 }
3693
3694 if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
3695 if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) {
3696 (*ResIndex) = 7;
3697 if(HwInfo->jChipType < SIS_315H) {
3698 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) (*ResIndex)++;
3699 }
3700 }
3701 }
3702}
3703
3704static void
3705SiS_GetLVDSDesData(SiS_Private *SiS_Pr, USHORT ModeNo,USHORT ModeIdIndex,
3706 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
3707{
3708 USHORT modeflag;
3709 USHORT PanelIndex,ResIndex;
3710 const SiS_LVDSDesStruct *PanelDesPtr = NULL;
3711
3712 SiS_Pr->SiS_LCDHDES = 0;
3713 SiS_Pr->SiS_LCDVDES = 0;
3714
3715 if( (SiS_Pr->UseCustomMode) ||
3716 (SiS_Pr->SiS_LCDResInfo == Panel_Custom) ||
3717 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
3718 ((SiS_Pr->SiS_VBType & VB_SISVB) &&
3719 (SiS_Pr->SiS_LCDInfo & DontExpandLCD) &&
3720 (SiS_Pr->SiS_LCDInfo & LCDPass11)) ) {
3721 return;
3722 }
3723
3724 if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3725
3726#ifdef SIS315H
3727 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3728 /* non-pass 1:1 only, see above */
3729 if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
3730 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
3731 }
3732 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
3733 SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
3734 }
3735 }
3736 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3737 switch(SiS_Pr->SiS_CustomT) {
3738 case CUT_UNIWILL1024:
3739 case CUT_UNIWILL10242:
3740 case CUT_CLEVO1400:
3741 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3742 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3743 }
3744 break;
3745 }
3746 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
3747 if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
3748 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3749 }
3750 }
3751 }
3752#endif
3753
3754 } else {
3755
3756 SiS_GetLVDSDesPtr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
3757 &PanelIndex, &ResIndex, HwInfo);
3758
3759 switch(PanelIndex) {
3760 case 0: PanelDesPtr = SiS_Pr->SiS_PanelType00_1; break; /* --- */
3761 case 1: PanelDesPtr = SiS_Pr->SiS_PanelType01_1; break;
3762 case 2: PanelDesPtr = SiS_Pr->SiS_PanelType02_1; break;
3763 case 3: PanelDesPtr = SiS_Pr->SiS_PanelType03_1; break;
3764 case 4: PanelDesPtr = SiS_Pr->SiS_PanelType04_1; break;
3765 case 5: PanelDesPtr = SiS_Pr->SiS_PanelType05_1; break;
3766 case 6: PanelDesPtr = SiS_Pr->SiS_PanelType06_1; break;
3767 case 7: PanelDesPtr = SiS_Pr->SiS_PanelType07_1; break;
3768 case 8: PanelDesPtr = SiS_Pr->SiS_PanelType08_1; break;
3769 case 9: PanelDesPtr = SiS_Pr->SiS_PanelType09_1; break;
3770 case 10: PanelDesPtr = SiS_Pr->SiS_PanelType0a_1; break;
3771 case 11: PanelDesPtr = SiS_Pr->SiS_PanelType0b_1; break;
3772 case 12: PanelDesPtr = SiS_Pr->SiS_PanelType0c_1; break;
3773 case 13: PanelDesPtr = SiS_Pr->SiS_PanelType0d_1; break;
3774 case 14: PanelDesPtr = SiS_Pr->SiS_PanelType0e_1; break;
3775 case 15: PanelDesPtr = SiS_Pr->SiS_PanelType0f_1; break;
3776 case 16: PanelDesPtr = SiS_Pr->SiS_PanelType00_2; break; /* --- */
3777 case 17: PanelDesPtr = SiS_Pr->SiS_PanelType01_2; break;
3778 case 18: PanelDesPtr = SiS_Pr->SiS_PanelType02_2; break;
3779 case 19: PanelDesPtr = SiS_Pr->SiS_PanelType03_2; break;
3780 case 20: PanelDesPtr = SiS_Pr->SiS_PanelType04_2; break;
3781 case 21: PanelDesPtr = SiS_Pr->SiS_PanelType05_2; break;
3782 case 22: PanelDesPtr = SiS_Pr->SiS_PanelType06_2; break;
3783 case 23: PanelDesPtr = SiS_Pr->SiS_PanelType07_2; break;
3784 case 24: PanelDesPtr = SiS_Pr->SiS_PanelType08_2; break;
3785 case 25: PanelDesPtr = SiS_Pr->SiS_PanelType09_2; break;
3786 case 26: PanelDesPtr = SiS_Pr->SiS_PanelType0a_2; break;
3787 case 27: PanelDesPtr = SiS_Pr->SiS_PanelType0b_2; break;
3788 case 28: PanelDesPtr = SiS_Pr->SiS_PanelType0c_2; break;
3789 case 29: PanelDesPtr = SiS_Pr->SiS_PanelType0d_2; break;
3790 case 30: PanelDesPtr = SiS_Pr->SiS_PanelType0e_2; break;
3791 case 31: PanelDesPtr = SiS_Pr->SiS_PanelType0f_2; break;
3792 case 32: PanelDesPtr = SiS_Pr->SiS_PanelTypeNS_1; break; /* pass 1:1 */
3793 case 33: PanelDesPtr = SiS_Pr->SiS_PanelTypeNS_2; break;
3794 case 50: PanelDesPtr = SiS_Pr->SiS_CHTVUNTSCDesData; break; /* TV */
3795 case 51: PanelDesPtr = SiS_Pr->SiS_CHTVONTSCDesData; break;
3796 case 52: PanelDesPtr = SiS_Pr->SiS_CHTVUPALDesData; break;
3797 case 53: PanelDesPtr = SiS_Pr->SiS_CHTVOPALDesData; break;
3798 default: return;
3799 }
3800
3801 SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
3802 SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;
3803
3804 if((ModeNo <= 0x13) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
3805 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3806 if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3807 if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 632;
3808 } else if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) {
3809 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
3810 if(SiS_Pr->SiS_LCDResInfo >= Panel_1024x768) {
3811 if(HwInfo->jChipType < SIS_315H) {
3812 if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320;
3813 } else {
3814 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) SiS_Pr->SiS_LCDHDES = 480;
3815 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 804;
3816 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 704;
3817 if(!(modeflag & HalfDCLK)) {
3818 SiS_Pr->SiS_LCDHDES = 320;
3819 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 632;
3820 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 542;
3821 }
3822 }
3823 }
3824 }
3825 }
3826 }
3827 }
3828}
3829
3830/*********************************************/
3831/* DISABLE VIDEO BRIDGE */
3832/*********************************************/
3833
3834/* NEVER use any variables (VBInfo), this will be called
3835 * from outside the context of modeswitch!
3836 * MUST call getVBType before calling this
3837 */
3838void
3839SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
3840{
3841#ifdef SIS315H
3842 USHORT tempah,pushax=0,modenum;
3843#endif
3844 USHORT temp=0;
3845
3846 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3847
3848 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { /* ===== For 30xB/LV ===== */
3849
3850 if(HwInfo->jChipType < SIS_315H) {
3851
3852#ifdef SIS300 /* 300 series */
3853
3854 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
3855 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3856 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
3857 } else {
3858 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
3859 }
3860 SiS_PanelDelay(SiS_Pr, HwInfo, 3);
3861 }
3862 if(SiS_Is301B(SiS_Pr)) {
3863 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);
3864 SiS_ShortDelay(SiS_Pr,1);
3865 }
3866 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
3867 SiS_DisplayOff(SiS_Pr);
3868 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3869 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
3870 SiS_UnLockCRT2(SiS_Pr,HwInfo);
3871 if(!(SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
3872 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
3873 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
3874 }
3875 if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ||
3876 (!(SiS_CR36BIOSWord23d(SiS_Pr, HwInfo))) ) {
3877 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
3878 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3879 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
3880 } else {
3881 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
3882 }
3883 }
3884
3885#endif /* SIS300 */
3886
3887 } else {
3888
3889#ifdef SIS315H /* 315 series */
3890
3891 BOOLEAN custom1 = ((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
3892 (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) ? TRUE : FALSE;
3893
3894 modenum = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34) & 0x7f;
3895
3896 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3897
3898#ifdef SET_EMI
3899 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
3900 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
3901 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
3902 }
3903 }
3904#endif
3905 if( (modenum <= 0x13) ||
3906 (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
3907 (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ) {
3908 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
3909 if(custom1) SiS_PanelDelay(SiS_Pr, HwInfo, 3);
3910 }
3911
3912 if(!custom1) {
3913 SiS_DDC2Delay(SiS_Pr,0xff00);
3914 SiS_DDC2Delay(SiS_Pr,0xe000);
3915 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
3916 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
3917 if(IS_SIS740) {
3918 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
3919 }
3920 SiS_PanelDelay(SiS_Pr, HwInfo, 3);
3921 }
3922
3923 }
3924
3925 if(!(SiS_IsNotM650orLater(SiS_Pr, HwInfo))) {
3926 if(HwInfo->jChipType < SIS_340) {
3927 tempah = 0xef;
3928 if(SiS_IsVAMode(SiS_Pr,HwInfo)) tempah = 0xf7;
3929 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
3930 }
3931 }
3932
3933 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3934 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,~0x10);
3935 }
3936
3937 tempah = 0x3f;
3938 if(SiS_IsDualEdge(SiS_Pr,HwInfo)) {
3939 tempah = 0x7f;
3940 if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) tempah = 0xbf;
3941 }
3942 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
3943
3944 if((SiS_IsVAMode(SiS_Pr,HwInfo)) ||
3945 ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && (modenum <= 0x13))) {
3946
3947 SiS_DisplayOff(SiS_Pr);
3948 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3949 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
3950 }
3951 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3952 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
3953
3954 }
3955
3956 if((!(SiS_IsVAMode(SiS_Pr,HwInfo))) ||
3957 ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && (modenum <= 0x13))) {
3958
3959 if(!(SiS_IsDualEdge(SiS_Pr,HwInfo))) {
3960 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
3961 SiS_DisplayOff(SiS_Pr);
3962 }
3963 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
3964
3965 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3966 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
3967 }
3968
3969 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3970 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
3971 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
3972 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
3973 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
3974
3975 }
3976
3977 if(SiS_IsNotM650orLater(SiS_Pr,HwInfo)) {
3978 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
3979 }
3980
3981 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
3982
3983 if(!custom1) {
3984
3985 if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
3986 if(!(SiS_CRT2IsLCD(SiS_Pr,HwInfo))) {
3987 if(!(SiS_IsDualEdge(SiS_Pr,HwInfo))) {
3988 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
3989 }
3990 }
3991 }
3992
3993 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
3994
3995 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
3996 if(SiS_IsVAorLCD(SiS_Pr, HwInfo)) {
3997 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 20);
3998 }
3999 }
4000
4001 } else {
4002
4003 if((SiS_IsVAMode(SiS_Pr,HwInfo)) ||
4004 (!(SiS_IsDualEdge(SiS_Pr,HwInfo)))) {
4005 if((!(SiS_WeHaveBacklightCtrl(SiS_Pr, HwInfo))) ||
4006 (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo)))) {
4007 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
4008 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
4009 SiS_PanelDelay(SiS_Pr, HwInfo, 4);
4010 }
4011 }
4012
4013 }
4014 }
4015
4016#endif /* SIS315H */
4017
4018 }
4019
4020 } else { /* ============ For 301 ================ */
4021
4022 if(HwInfo->jChipType < SIS_315H) {
4023#ifdef SIS300
4024 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
4025 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
4026 SiS_PanelDelay(SiS_Pr, HwInfo, 3);
4027 }
4028#endif
4029 }
4030
4031 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF); /* disable VB */
4032 SiS_DisplayOff(SiS_Pr);
4033
4034 if(HwInfo->jChipType >= SIS_315H) {
4035 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4036 }
4037
4038 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); /* disable lock mode */
4039
4040 if(HwInfo->jChipType >= SIS_315H) {
4041 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
4042 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
4043 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4044 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
4045 } else {
4046#ifdef SIS300
4047 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); /* disable CRT2 */
4048 if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ||
4049 (!(SiS_CR36BIOSWord23d(SiS_Pr,HwInfo))) ) {
4050 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
4051 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
4052 }
4053#endif
4054 }
4055
4056 }
4057
4058 } else { /* ============ For LVDS =============*/
4059
4060 if(HwInfo->jChipType < SIS_315H) {
4061
4062#ifdef SIS300 /* 300 series */
4063
4064 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4065 SiS_SetCH700x(SiS_Pr,0x090E);
4066 }
4067
4068 if(HwInfo->jChipType == SIS_730) {
4069 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4070 SiS_WaitVBRetrace(SiS_Pr,HwInfo);
4071 }
4072 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
4073 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
4074 SiS_PanelDelay(SiS_Pr, HwInfo, 3);
4075 }
4076 } else {
4077 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4078 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4079 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
4080 SiS_WaitVBRetrace(SiS_Pr,HwInfo);
4081 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {
4082 SiS_DisplayOff(SiS_Pr);
4083 }
4084 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
4085 SiS_PanelDelay(SiS_Pr, HwInfo, 3);
4086 }
4087 }
4088 }
4089 }
4090
4091 SiS_DisplayOff(SiS_Pr);
4092
4093 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4094
4095 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4096 SiS_UnLockCRT2(SiS_Pr,HwInfo);
4097 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
4098 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
4099
4100 if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ||
4101 (!(SiS_CR36BIOSWord23d(SiS_Pr,HwInfo))) ) {
4102 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
4103 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
4104 }
4105
4106#endif /* SIS300 */
4107
4108 } else {
4109
4110#ifdef SIS315H /* 315 series */
4111
4112 if(!(SiS_IsNotM650orLater(SiS_Pr,HwInfo))) {
4113 if(HwInfo->jChipType < SIS_340) {
4114 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,~0x18);
4115 }
4116 }
4117
4118 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4119
4120 if(HwInfo->jChipType == SIS_740) {
4121 temp = SiS_GetCH701x(SiS_Pr,0x61);
4122 if(temp < 1) {
4123 SiS_SetCH701x(SiS_Pr,0xac76);
4124 SiS_SetCH701x(SiS_Pr,0x0066);
4125 }
4126
4127 if( (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
4128 (SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo)) ) {
4129 SiS_SetCH701x(SiS_Pr,0x3e49);
4130 }
4131 }
4132
4133 if( (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
4134 (SiS_IsVAMode(SiS_Pr,HwInfo)) ) {
4135 SiS_Chrontel701xBLOff(SiS_Pr);
4136 SiS_Chrontel701xOff(SiS_Pr,HwInfo);
4137 }
4138
4139 if(HwInfo->jChipType != SIS_740) {
4140 if( (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
4141 (SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo)) ) {
4142 SiS_SetCH701x(SiS_Pr,0x0149);
4143 }
4144 }
4145
4146 }
4147
4148 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4149 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
4150 SiS_PanelDelay(SiS_Pr, HwInfo, 3);
4151 }
4152
4153 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4154 (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
4155 (!(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo))) ) {
4156 SiS_DisplayOff(SiS_Pr);
4157 }
4158
4159 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4160 (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
4161 (!(SiS_IsVAMode(SiS_Pr,HwInfo))) ) {
4162 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4163 }
4164
4165 if(HwInfo->jChipType == SIS_740) {
4166 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4167 }
4168
4169 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4170
4171 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4172 (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
4173 (!(SiS_IsVAMode(SiS_Pr,HwInfo))) ) {
4174 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4175 }
4176
4177 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4178 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4179 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4180 if(HwInfo->jChipType == SIS_550) {
4181 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xbf);
4182 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xef);
4183 }
4184 }
4185 } else {
4186 if(HwInfo->jChipType == SIS_740) {
4187 if(SiS_IsLCDOrLCDA(SiS_Pr,HwInfo)) {
4188 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4189 }
4190 } else if(SiS_IsVAMode(SiS_Pr,HwInfo)) {
4191 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4192 }
4193 }
4194
4195 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4196 if(SiS_IsDualEdge(SiS_Pr,HwInfo)) {
4197 /* SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff); */
4198 } else {
4199 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
4200 }
4201 }
4202
4203 SiS_UnLockCRT2(SiS_Pr,HwInfo);
4204
4205 if(HwInfo->jChipType == SIS_550) {
4206 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); /* DirectDVD PAL?*/
4207 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); /* VB clock / 4 ? */
4208 } else if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4209 (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
4210 (!(SiS_IsVAMode(SiS_Pr,HwInfo))) ) {
4211 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4212 }
4213
4214 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4215 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4216 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4217 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
4218 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
4219 }
4220 }
4221 }
4222
4223#endif /* SIS315H */
4224
4225 } /* 315 series */
4226
4227 } /* LVDS */
4228
4229}
4230
4231/*********************************************/
4232/* ENABLE VIDEO BRIDGE */
4233/*********************************************/
4234
4235/* NEVER use any variables (VBInfo), this will be called
4236 * from outside the context of a mode switch!
4237 * MUST call getVBType before calling this
4238 */
4239void
4240SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
4241{
4242 USHORT temp=0,tempah;
4243#ifdef SIS315H
4244 USHORT temp1,pushax=0;
4245 BOOLEAN delaylong = FALSE;
4246#endif
4247
4248 if(SiS_Pr->SiS_VBType & VB_SISVB) {
4249
4250 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { /* ====== For 301B et al ====== */
4251
4252 if(HwInfo->jChipType < SIS_315H) {
4253
4254#ifdef SIS300 /* 300 series */
4255
4256 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4257 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4258 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4259 } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
4260 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
4261 }
4262 if(SiS_Pr->SiS_VBType & (VB_SIS301LV302LV | VB_NoLCD)) {
4263 if(!(SiS_CR36BIOSWord23d(SiS_Pr, HwInfo))) {
4264 SiS_PanelDelay(SiS_Pr, HwInfo, 0);
4265 }
4266 }
4267 }
4268
4269 if((SiS_Pr->SiS_VBType & VB_NoLCD) &&
4270 (SiS_CRT2IsLCD(SiS_Pr, HwInfo))) {
4271
4272 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* Enable CRT2 */
4273 SiS_DisplayOn(SiS_Pr);
4274 SiS_UnLockCRT2(SiS_Pr,HwInfo);
4275 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4276 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4277 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4278 } else {
4279 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4280 }
4281 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4282 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4283 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
4284 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4285 }
4286 SiS_WaitVBRetrace(SiS_Pr,HwInfo);
4287 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00);
4288 }
4289 }
4290
4291 } else {
4292
4293 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
4294 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4295 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4296 if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4297 }
4298 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4299 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4300 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */
4301 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
4302 SiS_DisplayOn(SiS_Pr);
4303 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4304 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4305 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4306 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
4307 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4308 }
4309 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4310 }
4311 }
4312 }
4313
4314 }
4315
4316
4317#endif /* SIS300 */
4318
4319 } else {
4320
4321#ifdef SIS315H /* 315 series */
4322
4323#ifdef SET_EMI
4324 UCHAR r30=0, r31=0, r32=0, r33=0, cr36=0;
4325 /* USHORT emidelay=0; */
4326#endif
4327
4328 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4329 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef);
4330#ifdef SET_EMI
4331 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
4332 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4333 }
4334#endif
4335 }
4336
4337 if(!(SiS_IsNotM650orLater(SiS_Pr, HwInfo))) {
4338 if(HwInfo->jChipType < SIS_340) {
4339 tempah = 0x10;
4340 if(SiS_LCDAEnabled(SiS_Pr, HwInfo)) {
4341 if(SiS_TVEnabled(SiS_Pr, HwInfo)) tempah = 0x18;
4342 else tempah = 0x08;
4343 }
4344 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah);
4345 }
4346 }
4347
4348 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4349
4350 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
4351 SiS_DisplayOff(SiS_Pr);
4352 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
4353 if(IS_SIS740) {
4354 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
4355 }
4356
4357 if(SiS_IsVAorLCD(SiS_Pr, HwInfo)) {
4358 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
4359 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 2);
4360 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4361 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 2);
4362 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
4363 SiS_GenericDelay(SiS_Pr, 0x4500);
4364 }
4365 }
4366 }
4367
4368 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {
4369 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10);
4370 delaylong = TRUE;
4371 }
4372
4373 }
4374
4375 if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
4376
4377 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
4378 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4379 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4380 if(!(tempah & SetCRT2ToRAMDAC)) {
4381 if(!(SiS_LCDAEnabled(SiS_Pr, HwInfo))) temp |= 0x20;
4382 }
4383 }
4384 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4385
4386 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
4387
4388 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4389 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4390
4391 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4392 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
4393 }
4394
4395 } else {
4396
4397 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20);
4398
4399 }
4400
4401 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
4402 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4403
4404 tempah = 0xc0;
4405 if(SiS_IsDualEdge(SiS_Pr, HwInfo)) {
4406 tempah = 0x80;
4407 if(!(SiS_IsVAMode(SiS_Pr, HwInfo))) tempah = 0x40;
4408 }
4409 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4410
4411 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
4412
4413 SiS_PanelDelay(SiS_Pr, HwInfo, 2);
4414
4415 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10);
4416 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4417
4418 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
4419#ifdef SET_EMI
4420 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
4421 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4422 SiS_GenericDelay(SiS_Pr, 0x500);
4423 }
4424#endif
4425 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
4426
4427 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
4428#ifdef SET_EMI
4429 cr36 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
4430
4431 if(SiS_Pr->SiS_ROMNew) {
4432 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
4433 USHORT romptr = GetLCDStructPtr661_2(SiS_Pr, HwInfo);
4434 if(romptr) {
4435 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4436 SiS_Pr->EMI_30 = 0;
4437 SiS_Pr->EMI_31 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 0];
4438 SiS_Pr->EMI_32 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 1];
4439 SiS_Pr->EMI_33 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 2];
4440 if(ROMAddr[romptr + 1] & 0x10) SiS_Pr->EMI_30 = 0x40;
4441 /* emidelay = SISGETROMW((romptr + 0x22)); */
4442 SiS_Pr->HaveEMI = SiS_Pr->HaveEMILCD = SiS_Pr->OverruleEMI = TRUE;
4443 }
4444 }
4445
4446 /* (P4_30|0x40) */
4447 /* Compal 1400x1050: 0x05, 0x60, 0x00 YES (1.10.7w; CR36=69) */
4448 /* Compal 1400x1050: 0x0d, 0x70, 0x40 YES (1.10.7x; CR36=69) */
4449 /* Acer 1280x1024: 0x12, 0xd0, 0x6b NO (1.10.9k; CR36=73) */
4450 /* Compaq 1280x1024: 0x0d, 0x70, 0x6b YES (1.12.04b; CR36=03) */
4451 /* Clevo 1024x768: 0x05, 0x60, 0x33 NO (1.10.8e; CR36=12, DL!) */
4452 /* Clevo 1024x768: 0x0d, 0x70, 0x40 (if type == 3) YES (1.10.8y; CR36=?2) */
4453 /* Clevo 1024x768: 0x05, 0x60, 0x33 (if type != 3) YES (1.10.8y; CR36=?2) */
4454 /* Asus 1024x768: ? ? (1.10.8o; CR36=?2) */
4455 /* Asus 1024x768: 0x08, 0x10, 0x3c (problematic) YES (1.10.8q; CR36=22) */
4456
4457 if(SiS_Pr->HaveEMI) {
4458 r30 = SiS_Pr->EMI_30; r31 = SiS_Pr->EMI_31;
4459 r32 = SiS_Pr->EMI_32; r33 = SiS_Pr->EMI_33;
4460 } else {
4461 r30 = 0;
4462 }
4463
4464 /* EMI_30 is read at driver start; however, the BIOS sets this
4465 * (if it is used) only if the LCD is in use. In case we caught
4466 * the machine while on TV output, this bit is not set and we
4467 * don't know if it should be set - hence our detection is wrong.
4468 * Work-around this here:
4469 */
4470
4471 if((!SiS_Pr->HaveEMI) || (!SiS_Pr->HaveEMILCD)) {
4472 switch((cr36 & 0x0f)) {
4473 case 2:
4474 r30 |= 0x40;
4475 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) r30 &= ~0x40;
4476 if(!SiS_Pr->HaveEMI) {
4477 r31 = 0x05; r32 = 0x60; r33 = 0x33;
4478 if((cr36 & 0xf0) == 0x30) {
4479 r31 = 0x0d; r32 = 0x70; r33 = 0x40;
4480 }
4481 }
4482 break;
4483 case 3: /* 1280x1024 */
4484 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) r30 |= 0x40;
4485 if(!SiS_Pr->HaveEMI) {
4486 r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4487 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4488 r31 = 0x0d; r32 = 0x70; r33 = 0x6b;
4489 }
4490 }
4491 break;
4492 case 9: /* 1400x1050 */
4493 r30 |= 0x40;
4494 if(!SiS_Pr->HaveEMI) {
4495 r31 = 0x05; r32 = 0x60; r33 = 0x00;
4496 if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4497 r31 = 0x0d; r32 = 0x70; r33 = 0x40; /* BIOS values */
4498 }
4499 }
4500 break;
4501 case 11: /* 1600x1200 - unknown */
4502 r30 |= 0x40;
4503 if(!SiS_Pr->HaveEMI) {
4504 r31 = 0x05; r32 = 0x60; r33 = 0x00;
4505 }
4506 }
4507 }
4508
4509 /* BIOS values don't work so well sometimes */
4510 if(!SiS_Pr->OverruleEMI) {
4511#ifdef COMPAL_HACK
4512 if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4513 if((cr36 & 0x0f) == 0x09) {
4514 r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x00;
4515 }
4516 }
4517#endif
4518#ifdef COMPAQ_HACK
4519 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4520 if((cr36 & 0x0f) == 0x03) {
4521 r30 = 0x20; r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4522 }
4523 }
4524#endif
4525#ifdef ASUS_HACK
4526 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4527 if((cr36 & 0x0f) == 0x02) {
4528 /* r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 2 */
4529 /* r30 = 0x20; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 3 */
4530 /* r30 = 0x60; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 4 */
4531 /* r30 = 0x20; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 5 */
4532 }
4533 }
4534#endif
4535 }
4536
4537 if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) {
4538 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4539 SiS_GenericDelay(SiS_Pr, 0x500);
4540 }
4541 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,r31);
4542 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,r32);
4543 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x33,r33);
4544#endif /* SET_EMI */
4545
4546 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
4547
4548#ifdef SET_EMI
4549 if( (SiS_LCDAEnabled(SiS_Pr, HwInfo)) ||
4550 (SiS_CRT2IsLCD(SiS_Pr, HwInfo)) ) {
4551 if(r30 & 0x40) {
4552 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 5);
4553 if(delaylong) {
4554 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 5);
4555 delaylong = FALSE;
4556 }
4557 SiS_WaitVBRetrace(SiS_Pr,HwInfo);
4558 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4559 SiS_GenericDelay(SiS_Pr, 0x500);
4560 }
4561 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40); /* Enable */
4562 }
4563 }
4564#endif
4565 }
4566 }
4567
4568 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4569 if(SiS_IsVAorLCD(SiS_Pr, HwInfo)) {
4570 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10);
4571 if(delaylong) {
4572 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10);
4573 }
4574 SiS_WaitVBRetrace(SiS_Pr,HwInfo);
4575 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
4576 SiS_GenericDelay(SiS_Pr, 0x500);
4577 }
4578 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4579 }
4580 }
4581
4582 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4583 SiS_DisplayOn(SiS_Pr);
4584 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xff);
4585
4586 }
4587
4588 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4589 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4590 }
4591
4592#endif /* SIS315H */
4593
4594 }
4595
4596 } else { /* ============ For 301 ================ */
4597
4598 if(HwInfo->jChipType < SIS_315H) {
4599 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4600 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
4601 SiS_PanelDelay(SiS_Pr, HwInfo, 0);
4602 }
4603 }
4604
4605 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
4606 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4607 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4608 if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4609 }
4610 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4611
4612 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
4613
4614 if(HwInfo->jChipType >= SIS_315H) {
4615 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4616 if(!(temp & 0x80)) {
4617 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80); /* BVBDOENABLE=1 */
4618 }
4619 }
4620
4621 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */
4622
4623 SiS_VBLongWait(SiS_Pr);
4624 SiS_DisplayOn(SiS_Pr);
4625 if(HwInfo->jChipType >= SIS_315H) {
4626 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4627 }
4628 SiS_VBLongWait(SiS_Pr);
4629
4630 if(HwInfo->jChipType < SIS_315H) {
4631 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4632 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4633 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00);
4634 }
4635 }
4636
4637 }
4638
4639 } else { /* =================== For LVDS ================== */
4640
4641 if(HwInfo->jChipType < SIS_315H) {
4642
4643#ifdef SIS300 /* 300 series */
4644
4645 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4646 if(HwInfo->jChipType == SIS_730) {
4647 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4648 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4649 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4650 }
4651 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
4652 if(!(SiS_CR36BIOSWord23d(SiS_Pr,HwInfo))) {
4653 SiS_PanelDelay(SiS_Pr, HwInfo, 0);
4654 }
4655 }
4656
4657 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4658 SiS_DisplayOn(SiS_Pr);
4659 SiS_UnLockCRT2(SiS_Pr,HwInfo);
4660 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4661 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4662 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4663 } else {
4664 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4665 }
4666
4667 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4668 if(!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) {
4669 SiS_WaitVBRetrace(SiS_Pr, HwInfo);
4670 SiS_SetCH700x(SiS_Pr,0x0B0E);
4671 }
4672 }
4673
4674 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4675 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4676 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4677 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
4678 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4679 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4680 }
4681 SiS_WaitVBRetrace(SiS_Pr, HwInfo);
4682 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00);
4683 }
4684 }
4685 }
4686
4687#endif /* SIS300 */
4688
4689 } else {
4690
4691#ifdef SIS315H /* 315 series */
4692
4693 if(!(SiS_IsNotM650orLater(SiS_Pr,HwInfo))) {
4694 if(HwInfo->jChipType < SIS_340) {
4695 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x18);
4696 }
4697 }
4698
4699 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4700 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4701 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
4702 SiS_PanelDelay(SiS_Pr, HwInfo, 0);
4703 }
4704 }
4705
4706 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4707 SiS_UnLockCRT2(SiS_Pr,HwInfo);
4708
4709 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4710
4711 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4712 temp = SiS_GetCH701x(SiS_Pr,0x66);
4713 temp &= 0x20;
4714 SiS_Chrontel701xBLOff(SiS_Pr);
4715 }
4716
4717 if(HwInfo->jChipType != SIS_550) {
4718 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4719 }
4720
4721 if(HwInfo->jChipType == SIS_740) {
4722 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4723 if(SiS_IsLCDOrLCDA(SiS_Pr, HwInfo)) {
4724 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4725 }
4726 }
4727 }
4728
4729 temp1 = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4730 if(!(temp1 & 0x80)) {
4731 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
4732 }
4733
4734 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4735 if(temp) {
4736 SiS_Chrontel701xBLOn(SiS_Pr, HwInfo);
4737 }
4738 }
4739
4740 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4741 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4742 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4743 if(HwInfo->jChipType == SIS_550) {
4744 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x40);
4745 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x10);
4746 }
4747 }
4748 } else if(SiS_IsVAMode(SiS_Pr,HwInfo)) {
4749 if(HwInfo->jChipType != SIS_740) {
4750 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4751 }
4752 }
4753
4754 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4755 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4756 }
4757
4758 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4759 if(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo)) {
4760 SiS_Chrontel701xOn(SiS_Pr,HwInfo);
4761 }
4762 if( (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
4763 (SiS_IsLCDOrLCDA(SiS_Pr,HwInfo)) ) {
4764 SiS_ChrontelDoSomething1(SiS_Pr,HwInfo);
4765 }
4766 }
4767
4768 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4769 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4770 if( (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
4771 (SiS_IsLCDOrLCDA(SiS_Pr,HwInfo)) ) {
4772 SiS_Chrontel701xBLOn(SiS_Pr, HwInfo);
4773 SiS_ChrontelInitTVVSync(SiS_Pr,HwInfo);
4774 }
4775 }
4776 } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4777 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
4778 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
4779 SiS_PanelDelay(SiS_Pr, HwInfo, 1);
4780 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00);
4781 }
4782 }
4783 }
4784
4785#endif /* SIS315H */
4786
4787 } /* 310 series */
4788
4789 } /* LVDS */
4790
4791}
4792
4793/*********************************************/
4794/* SET PART 1 REGISTER GROUP */
4795/*********************************************/
4796
4797/* Set CRT2 OFFSET / PITCH */
4798static void
4799SiS_SetCRT2Offset(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
4800 USHORT RRTI, PSIS_HW_INFO HwInfo)
4801{
4802 USHORT offset;
4803 UCHAR temp;
4804
4805 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return;
4806
4807 offset = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,RRTI,HwInfo);
4808
4809 if((SiS_Pr->SiS_LCDResInfo == Panel_640x480_2) ||
4810 (SiS_Pr->SiS_LCDResInfo == Panel_640x480_3)) {
4811 offset >>= 1;
4812 }
4813
4814 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(offset & 0xFF));
4815 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,(offset >> 8));
4816 temp = (UCHAR)(((offset >> 3) & 0xFF) + 1);
4817 if(offset % 8) temp++;
4818 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,temp);
4819}
4820
4821/* Set CRT2 sync and PanelLink mode */
4822static void
4823SiS_SetCRT2Sync(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT RefreshRateTableIndex,
4824 PSIS_HW_INFO HwInfo)
4825{
4826 USHORT tempah=0,tempbl,infoflag;
4827
4828 tempbl = 0xC0;
4829
4830 if(SiS_Pr->UseCustomMode) {
4831 infoflag = SiS_Pr->CInfoFlag;
4832 } else {
4833 infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
4834 }
4835
4836 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { /* LVDS */
4837
4838 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
4839 tempah = 0;
4840 } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) {
4841 tempah = SiS_Pr->SiS_LCDInfo;
4842 } else tempah = infoflag >> 8;
4843 tempah &= 0xC0;
4844 tempah |= 0x20;
4845 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4846 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4847 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
4848 (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
4849 tempah |= 0xf0;
4850 }
4851 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
4852 (SiS_Pr->SiS_IF_DEF_DSTN) ||
4853 (SiS_Pr->SiS_IF_DEF_TRUMPION) ||
4854 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ) {
4855 tempah |= 0x30;
4856 }
4857 }
4858 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
4859 if(HwInfo->jChipType >= SIS_315H) {
4860 tempah >>= 3;
4861 tempah &= 0x18;
4862 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xE7,tempah);
4863 /* Don't care about 12/18/24 bit mode - TV is via VGA, not PL */
4864 } else {
4865 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,0xe0);
4866 }
4867 } else {
4868 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4869 }
4870
4871 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
4872
4873 if(HwInfo->jChipType < SIS_315H) {
4874
4875#ifdef SIS300 /* ---- 300 series --- */
4876
4877 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { /* 630 - 301B(-DH) */
4878
4879 tempah = infoflag >> 8;
4880 tempbl = 0;
4881 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4882 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4883 tempah = SiS_Pr->SiS_LCDInfo;
4884 tempbl = (tempah >> 6) & 0x03;
4885 }
4886 }
4887 tempah &= 0xC0;
4888 tempah |= 0x20;
4889 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4890 tempah |= 0xc0;
4891 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4892 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
4893 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
4894 }
4895
4896 } else { /* 630 - 301 */
4897
4898 tempah = infoflag >> 8;
4899 tempah &= 0xC0;
4900 tempah |= 0x20;
4901 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4902 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4903
4904 }
4905
4906#endif /* SIS300 */
4907
4908 } else {
4909
4910#ifdef SIS315H /* ------- 315 series ------ */
4911
4912 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { /* 315 - LVDS */
4913
4914 tempbl = 0;
4915 if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
4916 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
4917 tempah = infoflag >> 8;
4918 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4919 tempbl = ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6);
4920 }
4921 } else if((SiS_Pr->SiS_CustomT == CUT_CLEVO1400) &&
4922 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)) {
4923 tempah = infoflag >> 8;
4924 tempbl = 0x03;
4925 } else {
4926 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
4927 tempbl = (tempah >> 6) & 0x03;
4928 tempbl |= 0x08;
4929 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempbl |= 0x04;
4930 }
4931 tempah &= 0xC0;
4932 tempah |= 0x20;
4933 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4934 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) tempah |= 0xc0;
4935 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4936 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
4937 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4938 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
4939 }
4940 }
4941
4942 } else { /* 315 - TMDS */
4943
4944 tempah = tempbl = infoflag >> 8;
4945 if(!SiS_Pr->UseCustomMode) {
4946 tempbl = 0;
4947 if((SiS_Pr->SiS_VBType & VB_SIS301C) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
4948 if(ModeNo <= 0x13) {
4949 tempah = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
4950 }
4951 }
4952 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
4953 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
4954 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4955 tempah = SiS_Pr->SiS_LCDInfo;
4956 tempbl = (tempah >> 6) & 0x03;
4957 }
4958 }
4959 }
4960 }
4961 tempah &= 0xC0;
4962 tempah |= 0x20;
4963 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4964 if(SiS_Pr->SiS_VBType & VB_NoLCD) {
4965 /* Imitate BIOS bug */
4966 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempah |= 0xc0;
4967 }
4968 if((SiS_Pr->SiS_VBType & VB_SIS301C) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
4969 tempah >>= 3;
4970 tempah &= 0x18;
4971 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xe7,tempah);
4972 } else {
4973 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4974 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
4975 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4976 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
4977 }
4978 }
4979 }
4980
4981 }
4982#endif /* SIS315H */
4983 }
4984 }
4985}
4986
4987/* Set CRT2 FIFO on 300/630/730 */
4988#ifdef SIS300
4989static void
4990SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,USHORT ModeNo,
4991 PSIS_HW_INFO HwInfo)
4992{
4993 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
4994 USHORT temp,index;
4995 USHORT modeidindex,refreshratetableindex;
4996 USHORT VCLK=0,MCLK,colorth=0,data2=0;
4997 USHORT tempal, tempah, tempbx, tempcl, tempax;
4998 USHORT CRT1ModeNo,CRT2ModeNo;
4999 USHORT SelectRate_backup;
5000 ULONG data,eax;
5001 const UCHAR LatencyFactor[] = {
5002 97, 88, 86, 79, 77, 00, /*; 64 bit BQ=2 */
5003 00, 87, 85, 78, 76, 54, /*; 64 bit BQ=1 */
5004 97, 88, 86, 79, 77, 00, /*; 128 bit BQ=2 */
5005 00, 79, 77, 70, 68, 48, /*; 128 bit BQ=1 */
5006 80, 72, 69, 63, 61, 00, /*; 64 bit BQ=2 */
5007 00, 70, 68, 61, 59, 37, /*; 64 bit BQ=1 */
5008 86, 77, 75, 68, 66, 00, /*; 128 bit BQ=2 */
5009 00, 68, 66, 59, 57, 37 /*; 128 bit BQ=1 */
5010 };
5011 const UCHAR LatencyFactor730[] = {
5012 69, 63, 61,
5013 86, 79, 77,
5014 103, 96, 94,
5015 120,113,111,
5016 137,130,128, /* <-- last entry, data below */
5017 137,130,128, /* to avoid using illegal values */
5018 137,130,128,
5019 137,130,128,
5020 137,130,128,
5021 137,130,128,
5022 137,130,128,
5023 137,130,128,
5024 137,130,128,
5025 137,130,128,
5026 137,130,128,
5027 137,130,128,
5028 };
5029 const UCHAR ThLowB[] = {
5030 81, 4, 72, 6, 88, 8,120,12,
5031 55, 4, 54, 6, 66, 8, 90,12,
5032 42, 4, 45, 6, 55, 8, 75,12
5033 };
5034 const UCHAR ThTiming[] = {
5035 1, 2, 2, 3, 0, 1, 1, 2
5036 };
5037
5038 SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;
5039
5040 if(!SiS_Pr->CRT1UsesCustomMode) {
5041
5042 CRT1ModeNo = SiS_Pr->SiS_CRT1Mode; /* get CRT1 ModeNo */
5043 SiS_SearchModeID(SiS_Pr, &CRT1ModeNo, &modeidindex);
5044 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
5045 SiS_Pr->SiS_SelectCRT2Rate = 0;
5046 refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT1ModeNo, modeidindex, HwInfo);
5047
5048 if(CRT1ModeNo >= 0x13) {
5049 index = SiS_Pr->SiS_RefIndex[refreshratetableindex].Ext_CRTVCLK;
5050 index &= 0x3F;
5051 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; /* Get VCLK */
5052
5053 colorth = SiS_GetColorDepth(SiS_Pr,CRT1ModeNo,modeidindex); /* Get colordepth */
5054 colorth >>= 1;
5055 if(!colorth) colorth++;
5056 }
5057
5058 } else {
5059
5060 CRT1ModeNo = 0xfe;
5061 VCLK = SiS_Pr->CSRClock_CRT1; /* Get VCLK */
5062 data2 = (SiS_Pr->CModeFlag_CRT1 & ModeTypeMask) - 2;
5063 switch(data2) { /* Get color depth */
5064 case 0 : colorth = 1; break;
5065 case 1 : colorth = 1; break;
5066 case 2 : colorth = 2; break;
5067 case 3 : colorth = 2; break;
5068 case 4 : colorth = 3; break;
5069 case 5 : colorth = 4; break;
5070 default: colorth = 2;
5071 }
5072
5073 }
5074
5075 if(CRT1ModeNo >= 0x13) {
5076 if(HwInfo->jChipType == SIS_300) {
5077 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A);
5078 } else {
5079 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A);
5080 }
5081 index &= 0x07;
5082 MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK; /* Get MCLK */
5083
5084 data2 = (colorth * VCLK) / MCLK;
5085
5086 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
5087 temp = ((temp & 0x00FF) >> 6) << 1;
5088 if(temp == 0) temp = 1;
5089 temp <<= 2;
5090 temp &= 0xff;
5091
5092 data2 = temp - data2;
5093
5094 if((28 * 16) % data2) {
5095 data2 = (28 * 16) / data2;
5096 data2++;
5097 } else {
5098 data2 = (28 * 16) / data2;
5099 }
5100
5101 if(HwInfo->jChipType == SIS_300) {
5102
5103 tempah = SiS_GetReg(SiS_Pr->SiS_P3c4,0x18);
5104 tempah &= 0x62;
5105 tempah >>= 1;
5106 tempal = tempah;
5107 tempah >>= 3;
5108 tempal |= tempah;
5109 tempal &= 0x07;
5110 tempcl = ThTiming[tempal];
5111 tempbx = SiS_GetReg(SiS_Pr->SiS_P3c4,0x16);
5112 tempbx >>= 6;
5113 tempah = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
5114 tempah >>= 4;
5115 tempah &= 0x0c;
5116 tempbx |= tempah;
5117 tempbx <<= 1;
5118 tempal = ThLowB[tempbx + 1];
5119 tempal *= tempcl;
5120 tempal += ThLowB[tempbx];
5121 data = tempal;
5122
5123 } else if(HwInfo->jChipType == SIS_730) {
5124
5125#ifdef LINUX_KERNEL
5126 SiS_SetRegLong(0xcf8,0x80000050);
5127 eax = SiS_GetRegLong(0xcfc);
5128#else
5129 eax = pciReadLong(0x00000000, 0x50);
5130#endif
5131 tempal = (USHORT)(eax >> 8);
5132 tempal &= 0x06;
5133 tempal <<= 5;
5134
5135#ifdef LINUX_KERNEL
5136 SiS_SetRegLong(0xcf8,0x800000A0);
5137 eax = SiS_GetRegLong(0xcfc);
5138#else
5139 eax = pciReadLong(0x00000000, 0xA0);
5140#endif
5141 temp = (USHORT)(eax >> 28);
5142 temp &= 0x0F;
5143 tempal |= temp;
5144
5145 tempbx = tempal; /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */
5146 tempbx = 0; /* -- do it like the BIOS anyway... */
5147 tempax = tempbx;
5148 tempbx &= 0xc0;
5149 tempbx >>= 6;
5150 tempax &= 0x0f;
5151 tempax *= 3;
5152 tempbx += tempax;
5153
5154 data = LatencyFactor730[tempbx];
5155 data += 15;
5156 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
5157 if(!(temp & 0x80)) data += 5;
5158
5159 } else {
5160
5161 index = 0;
5162 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
5163 if(temp & 0x0080) index += 12;
5164
5165#ifdef LINUX_KERNEL
5166 SiS_SetRegLong(0xcf8,0x800000A0);
5167 eax = SiS_GetRegLong(0xcfc);
5168#else
5169 /* We use pci functions X offers. We use tag 0, because
5170 * we want to read/write to the host bridge (which is always
5171 * 00:00.0 on 630, 730 and 540), not the VGA device.
5172 */
5173 eax = pciReadLong(0x00000000, 0xA0);
5174#endif
5175 temp = (USHORT)(eax >> 24);
5176 if(!(temp&0x01)) index += 24;
5177
5178#ifdef LINUX_KERNEL
5179 SiS_SetRegLong(0xcf8,0x80000050);
5180 eax = SiS_GetRegLong(0xcfc);
5181#else
5182 eax = pciReadLong(0x00000000, 0x50);
5183#endif
5184 temp=(USHORT)(eax >> 24);
5185 if(temp & 0x01) index += 6;
5186
5187 temp = (temp & 0x0F) >> 1;
5188 index += temp;
5189
5190 data = LatencyFactor[index];
5191 data += 15;
5192 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
5193 if(!(temp & 0x80)) data += 5;
5194 }
5195
5196 data += data2; /* CRT1 Request Period */
5197
5198 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5199 SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5200
5201 if(!SiS_Pr->UseCustomMode) {
5202
5203 CRT2ModeNo = ModeNo;
5204 SiS_SearchModeID(SiS_Pr, &CRT2ModeNo, &modeidindex);
5205
5206 refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT2ModeNo, modeidindex, HwInfo);
5207
5208 index = SiS_GetVCLK2Ptr(SiS_Pr,CRT2ModeNo,modeidindex,
5209 refreshratetableindex,HwInfo);
5210 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; /* Get VCLK */
5211
5212 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
5213 if(SiS_Pr->SiS_UseROM) {
5214 if(ROMAddr[0x220] & 0x01) {
5215 VCLK = ROMAddr[0x229] | (ROMAddr[0x22a] << 8);
5216 }
5217 }
5218 }
5219
5220 } else {
5221
5222 CRT2ModeNo = 0xfe;
5223 VCLK = SiS_Pr->CSRClock; /* Get VCLK */
5224
5225 }
5226
5227 colorth = SiS_GetColorDepth(SiS_Pr,CRT2ModeNo,modeidindex); /* Get colordepth */
5228 colorth >>= 1;
5229 if(!colorth) colorth++;
5230
5231 data = data * VCLK * colorth;
5232 if(data % (MCLK << 4)) {
5233 data = data / (MCLK << 4);
5234 data++;
5235 } else {
5236 data = data / (MCLK << 4);
5237 }
5238
5239 if(data <= 6) data = 6;
5240 if(data > 0x14) data = 0x14;
5241
5242 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x01);
5243 if(HwInfo->jChipType == SIS_300) {
5244 if(data <= 0x0f) temp = (temp & (~0x1F)) | 0x13;
5245 else temp = (temp & (~0x1F)) | 0x16;
5246 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
5247 temp = (temp & (~0x1F)) | 0x13;
5248 }
5249 } else {
5250 if( ( (HwInfo->jChipType == SIS_630) ||
5251 (HwInfo->jChipType == SIS_730) ) &&
5252 (HwInfo->jChipRevision >= 0x30) ) /* 630s or 730(s?) */
5253 {
5254 temp = (temp & (~0x1F)) | 0x1b;
5255 } else {
5256 temp = (temp & (~0x1F)) | 0x16;
5257 }
5258 }
5259 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0xe0,temp);
5260
5261 if( (HwInfo->jChipType == SIS_630) &&
5262 (HwInfo->jChipRevision >= 0x30) ) /* 630s, NOT 730 */
5263 {
5264 if(data > 0x13) data = 0x13;
5265 }
5266 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,0xe0,data);
5267
5268 } else { /* If mode <= 0x13, we just restore everything */
5269
5270 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5271 SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5272
5273 }
5274}
5275#endif
5276
5277/* Set CRT2 FIFO on 315/330 series */
5278#ifdef SIS315H
5279static void
5280SiS_SetCRT2FIFO_310(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
5281{
5282 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3B);
5283 if( (HwInfo->jChipType == SIS_760) &&
5284 (SiS_Pr->SiS_SysFlags & SF_760LFB) &&
5285 (SiS_Pr->SiS_ModeType == Mode32Bpp) &&
5286 (SiS_Pr->SiS_VGAHDE >= 1280) &&
5287 (SiS_Pr->SiS_VGAVDE >= 1024) ) {
5288 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x03);
5289 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3b);
5290 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5291 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x01);
5292 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
5293 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,0x6e);
5294 } else {
5295 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3f,0x04);
5296 }
5297
5298}
5299#endif
5300
5301static USHORT
5302SiS_GetVGAHT2(SiS_Private *SiS_Pr)
5303{
5304 ULONG tempax,tempbx;
5305
5306 tempbx = (SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) * SiS_Pr->SiS_RVBHCMAX;
5307 tempax = (SiS_Pr->SiS_VT - SiS_Pr->SiS_VDE) * SiS_Pr->SiS_RVBHCFACT;
5308 tempax = (tempax * SiS_Pr->SiS_HT) / tempbx;
5309 return((USHORT)tempax);
5310}
5311
5312/* Set Part 1 / SiS bridge slave mode */
5313static void
5314SiS_SetGroup1_301(SiS_Private *SiS_Pr, USHORT ModeNo,USHORT ModeIdIndex,
5315 PSIS_HW_INFO HwInfo,USHORT RefreshRateTableIndex)
5316{
5317 USHORT push1,push2;
5318 USHORT tempax,tempbx,tempcx,temp;
5319 USHORT resinfo,modeflag,xres=0;
5320 unsigned char p1_7, p1_8;
5321
5322 if(ModeNo <= 0x13) {
5323 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5324 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
5325 } else if(SiS_Pr->UseCustomMode) {
5326 modeflag = SiS_Pr->CModeFlag;
5327 resinfo = 0;
5328 xres = SiS_Pr->CHDisplay;
5329 } else {
5330 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5331 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
5332 xres = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes;
5333 }
5334
5335 /* The following is only done if bridge is in slave mode: */
5336
5337 if((HwInfo->jChipType >= SIS_661) && (ModeNo > 0x13)) {
5338 if(xres >= 1600) {
5339 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x31,0x04);
5340 }
5341 }
5342
5343 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0xff); /* set MAX HT */
5344
5345 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) modeflag |= Charx8Dot;
5346
5347 if(modeflag & Charx8Dot) tempcx = 0x08;
5348 else tempcx = 0x09;
5349
5350 tempax = SiS_Pr->SiS_VGAHDE; /* 0x04 Horizontal Display End */
5351 if(modeflag & HalfDCLK) tempax >>= 1;
5352 tempax = ((tempax / tempcx) - 1) & 0xff;
5353 tempbx = tempax;
5354
5355 temp = tempax;
5356 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,temp);
5357
5358 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5359 if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
5360 temp += 2;
5361 }
5362 }
5363 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
5364 if(resinfo == SIS_RI_800x600) temp -= 2;
5365 }
5366 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x05,temp); /* 0x05 Horizontal Display Start */
5367
5368 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x06,0x03); /* 0x06 Horizontal Blank end */
5369
5370 tempax = 0xFFFF;
5371 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempax = SiS_GetVGAHT2(SiS_Pr);
5372 if(tempax >= SiS_Pr->SiS_VGAHT) tempax = SiS_Pr->SiS_VGAHT;
5373 if(modeflag & HalfDCLK) tempax >>= 1;
5374 tempax = (tempax / tempcx) - 5;
5375 tempcx = tempax;
5376
5377 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
5378 temp = tempcx - 1;
5379 if(!(modeflag & HalfDCLK)) {
5380 temp -= 6;
5381 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
5382 temp -= 2;
5383 if(ModeNo > 0x13) temp -= 10;
5384 }
5385 }
5386 } else {
5387 tempcx = (tempcx + tempbx) >> 1;
5388 temp = (tempcx & 0x00FF) + 2;
5389 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5390 temp--;
5391 if(!(modeflag & HalfDCLK)) {
5392 if((modeflag & Charx8Dot)) {
5393 temp += 4;
5394 if(SiS_Pr->SiS_VGAHDE >= 800) temp -= 6;
5395 if(HwInfo->jChipType >= SIS_315H) {
5396 if(SiS_Pr->SiS_VGAHDE == 800) temp += 2;
5397 }
5398 }
5399 }
5400 } else {
5401 if(!(modeflag & HalfDCLK)) {
5402 temp -= 4;
5403 if((SiS_Pr->SiS_LCDResInfo != Panel_1280x960) &&
5404 (SiS_Pr->SiS_LCDResInfo != Panel_1600x1200)) {
5405 if(SiS_Pr->SiS_VGAHDE >= 800) {
5406 temp -= 7;
5407 if(HwInfo->jChipType < SIS_315H) {
5408 if(SiS_Pr->SiS_ModeType == ModeEGA) {
5409 if(SiS_Pr->SiS_VGAVDE == 1024) {
5410 temp += 15;
5411 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024)
5412 temp += 7;
5413 }
5414 }
5415 }
5416 if(SiS_Pr->SiS_LCDResInfo != Panel_1400x1050) {
5417 if(SiS_Pr->SiS_VGAHDE >= 1280) {
5418 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) temp += 28;
5419 }
5420 }
5421 }
5422 }
5423 }
5424 }
5425 }
5426
5427 p1_7 = temp;
5428 p1_8 = 0x00;
5429
5430 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5431 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
5432 if(ModeNo <= 0x01) {
5433 p1_7 = 0x2a;
5434 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) p1_8 = 0x61;
5435 else p1_8 = 0x41;
5436 } else if(SiS_Pr->SiS_ModeType == ModeText) {
5437 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) p1_7 = 0x54;
5438 else p1_7 = 0x55;
5439 p1_8 = 0x00;
5440 } else if(ModeNo <= 0x13) {
5441 if(modeflag & HalfDCLK) {
5442 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
5443 p1_7 = 0x30;
5444 p1_8 = 0x03;
5445 } else {
5446 p1_7 = 0x2f;
5447 p1_8 = 0x02;
5448 }
5449 } else {
5450 p1_7 = 0x5b;
5451 p1_8 = 0x03;
5452 }
5453 } else if( ((HwInfo->jChipType >= SIS_315H) &&
5454 ((ModeNo == 0x50) || (ModeNo == 0x56) || (ModeNo == 0x53))) ||
5455 ((HwInfo->jChipType < SIS_315H) &&
5456 (resinfo == SIS_RI_320x200 || resinfo == SIS_RI_320x240)) ) {
5457 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
5458 p1_7 = 0x30,
5459 p1_8 = 0x03;
5460 } else {
5461 p1_7 = 0x2f;
5462 p1_8 = 0x03;
5463 }
5464 }
5465 }
5466 }
5467
5468 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
5469 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p)) {
5470 p1_7 = 0x63;
5471 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) p1_7 = 0x55;
5472 }
5473 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
5474 if(!(modeflag & HalfDCLK)) {
5475 p1_7 = 0xb2;
5476 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
5477 p1_7 = 0xab;
5478 }
5479 }
5480 } else {
5481 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
5482 if(modeflag & HalfDCLK) p1_7 = 0x30;
5483 }
5484 }
5485 }
5486
5487 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,p1_7); /* 0x07 Horizontal Retrace Start */
5488 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,p1_8); /* 0x08 Horizontal Retrace End */
5489
5490 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x03); /* 0x18 SR08 (FIFO Threshold?) */
5491
5492 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x19,0xF0);
5493
5494 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,0xFF); /* 0x09 Set Max VT */
5495
5496 tempcx = 0x121;
5497 tempbx = SiS_Pr->SiS_VGAVDE; /* 0x0E Vertical Display End */
5498 if (tempbx == 357) tempbx = 350;
5499 else if(tempbx == 360) tempbx = 350;
5500 else if(tempbx == 375) tempbx = 350;
5501 else if(tempbx == 405) tempbx = 400;
5502 else if(tempbx == 420) tempbx = 400;
5503 else if(tempbx == 525) tempbx = 480;
5504 push2 = tempbx;
5505 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5506 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5507 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
5508 if (tempbx == 350) tempbx += 5;
5509 else if(tempbx == 480) tempbx += 5;
5510 }
5511 }
5512 }
5513 tempbx -= 2;
5514 temp = tempbx & 0x00FF;
5515 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,temp); /* 0x10 vertical Blank Start */
5516
5517 tempbx = push2;
5518 tempbx--;
5519 temp = tempbx & 0x00FF;
5520#if 0
5521 /* Missing code from 630/301B 2.04.5a and 650/302LV 1.10.6s (calles int 2f) */
5522 if(xxx()) {
5523 if(temp == 0xdf) temp = 0xda;
5524 }
5525#endif
5526 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp);
5527
5528 temp = 0;
5529 if(modeflag & DoubleScanMode) temp |= 0x80;
5530 if(HwInfo->jChipType >= SIS_661) {
5531 if(tempbx & 0x0200) temp |= 0x20;
5532 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x0B,0x5F,temp);
5533 if(tempbx & 0x0100) tempcx |= 0x000a;
5534 if(tempbx & 0x0400) tempcx |= 0x1200;
5535 } else {
5536 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,temp);
5537 if(tempbx & 0x0100) tempcx |= 0x0002;
5538 if(tempbx & 0x0400) tempcx |= 0x0600;
5539 }
5540
5541 if(tempbx & 0x0200) tempcx |= 0x0040;
5542
5543 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,0x00); /* 0x11 Vertical Blank End */
5544
5545 tempax = (SiS_Pr->SiS_VGAVT - tempbx) >> 2;
5546
5547 if((ModeNo > 0x13) || (HwInfo->jChipType < SIS_315H)) {
5548 if(resinfo != SIS_RI_1280x1024) {
5549 tempbx += (tempax << 1);
5550 }
5551 } else if(HwInfo->jChipType >= SIS_315H) {
5552 if(SiS_Pr->SiS_LCDResInfo != Panel_1400x1050) {
5553 tempbx += (tempax << 1);
5554 }
5555 }
5556
5557 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
5558 tempbx -= 10;
5559 } else {
5560 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
5561 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
5562 tempbx += 40;
5563 if(HwInfo->jChipType >= SIS_315H) {
5564 if(SiS_Pr->SiS_VGAHDE == 800) tempbx += 10;
5565 }
5566 }
5567 }
5568 }
5569 tempax >>= 2;
5570 tempax++;
5571 tempax += tempbx;
5572 push1 = tempax;
5573 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
5574 if(tempbx <= 513) {
5575 if(tempax >= 513) tempbx = 513;
5576 }
5577 }
5578 temp = tempbx & 0x00FF;
5579 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp); /* 0x0C Vertical Retrace Start */
5580
5581 tempbx--;
5582 temp = tempbx & 0x00FF;
5583 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,temp);
5584
5585 if(tempbx & 0x0100) tempcx |= 0x0008;
5586
5587 if(tempbx & 0x0200) {
5588 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x0B,0x20);
5589 }
5590 tempbx++;
5591
5592 if(tempbx & 0x0100) tempcx |= 0x0004;
5593 if(tempbx & 0x0200) tempcx |= 0x0080;
5594 if(tempbx & 0x0400) {
5595 if(HwInfo->jChipType >= SIS_661) tempcx |= 0x0800;
5596 else if(SiS_Pr->SiS_VBType & VB_SIS301) tempcx |= 0x0800;
5597 else tempcx |= 0x0C00;
5598 }
5599
5600 tempbx = push1;
5601 temp = tempbx & 0x000F;
5602 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,temp); /* 0x0D vertical Retrace End */
5603
5604 if(tempbx & 0x0010) tempcx |= 0x2000;
5605
5606 temp = tempcx & 0x00FF;
5607 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp); /* 0x0A CR07 */
5608
5609 temp = (tempcx & 0xFF00) >> 8;
5610 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp); /* 0x17 SR0A */
5611
5612 tempax = modeflag;
5613 temp = (tempax & 0xFF00) >> 8;
5614 temp = (temp >> 1) & 0x09;
5615 if(!(SiS_Pr->SiS_VBType & VB_SIS301)) temp |= 0x01; /* Always 8 dotclock */
5616 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* 0x16 SR01 */
5617
5618 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,0x00); /* 0x0F CR14 */
5619
5620 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,0x00); /* 0x12 CR17 */
5621
5622 temp = 0x00;
5623 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5624 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
5625 temp = 0x80;
5626 }
5627 }
5628 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* 0x1A SR0E */
5629
5630 temp = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
5631 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);
5632}
5633
5634/* Setup panel link
5635 * This is used for LVDS, LCDA and Chrontel TV output
5636 * 300/LVDS+TV, 300/301B-DH, 315/LVDS+TV, 315/LCDA
5637 */
5638static void
5639SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
5640 PSIS_HW_INFO HwInfo, USHORT RefreshRateTableIndex)
5641{
5642 USHORT modeflag,resinfo;
5643 USHORT push2,tempax,tempbx,tempcx,temp;
5644 ULONG tempeax=0,tempebx,tempecx,tempvcfact=0;
5645 BOOLEAN islvds = FALSE, issis = FALSE, chkdclkfirst = FALSE;
5646#ifdef SIS300
5647 USHORT crt2crtc;
5648#endif
5649#ifdef SIS315H
5650 USHORT pushcx;
5651#endif
5652
5653 if(ModeNo <= 0x13) {
5654 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5655 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
5656#ifdef SIS300
5657 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
5658#endif
5659 } else if(SiS_Pr->UseCustomMode) {
5660 modeflag = SiS_Pr->CModeFlag;
5661 resinfo = 0;
5662#ifdef SIS300
5663 crt2crtc = 0;
5664#endif
5665 } else {
5666 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5667 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
5668#ifdef SIS300
5669 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
5670#endif
5671 }
5672
5673 /* is lvds if really LVDS, or 301B-DH with external LVDS transmitter */
5674 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
5675 islvds = TRUE;
5676 }
5677
5678 /* is really sis if sis bridge, but not 301B-DH */
5679 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
5680 issis = TRUE;
5681 }
5682
5683 if((HwInfo->jChipType >= SIS_315H) && (islvds) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA))) {
5684 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
5685 chkdclkfirst = TRUE;
5686 }
5687 }
5688
5689#ifdef SIS315H
5690 if((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
5691 if(IS_SIS330) {
5692 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5693 } else if(IS_SIS740) {
5694 if(islvds) {
5695 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5696 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x03);
5697 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5698 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5699 }
5700 } else {
5701 if(islvds) {
5702 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
5703 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x00);
5704 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5705 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2D,0x0f);
5706 if(SiS_Pr->SiS_VBType & VB_SIS301C) {
5707 if((SiS_Pr->SiS_LCDResInfo == Panel_1024x768) ||
5708 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
5709 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x20);
5710 }
5711 }
5712 }
5713 }
5714 }
5715#endif
5716
5717 /* Horizontal */
5718
5719 tempax = SiS_Pr->SiS_LCDHDES;
5720 if(islvds) {
5721 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5722 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
5723 if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) &&
5724 (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
5725 tempax -= 8;
5726 }
5727 }
5728 }
5729 }
5730
5731 temp = (tempax & 0x0007);
5732 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* BPLHDESKEW[2:0] */
5733 temp = (tempax >> 3) & 0x00FF;
5734 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* BPLHDESKEW[10:3] */
5735
5736 tempbx = SiS_Pr->SiS_HDE;
5737 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5738 if((SiS_Pr->SiS_LCDResInfo == Panel_640x480_2) ||
5739 (SiS_Pr->SiS_LCDResInfo == Panel_640x480_3)) {
5740 tempbx >>= 1;
5741 }
5742 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5743 tempbx = SiS_Pr->PanelXRes;
5744 }
5745 }
5746
5747 tempax += tempbx;
5748 if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;
5749
5750 temp = tempax;
5751 if(temp & 0x07) temp += 8;
5752 temp >>= 3;
5753 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp); /* BPLHDEE */
5754
5755 tempcx = (SiS_Pr->SiS_HT - tempbx) >> 2;
5756
5757 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5758 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5759 if(SiS_Pr->PanelHRS != 999) tempcx = SiS_Pr->PanelHRS;
5760 }
5761 }
5762
5763 tempcx += tempax;
5764 if(tempcx >= SiS_Pr->SiS_HT) tempcx -= SiS_Pr->SiS_HT;
5765
5766 temp = (tempcx >> 3) & 0x00FF;
5767 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5768 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5769 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5770 switch(ModeNo) {
5771 case 0x04:
5772 case 0x05:
5773 case 0x0d: temp = 0x56; break;
5774 case 0x10: temp = 0x60; break;
5775 case 0x13: temp = 0x5f; break;
5776 case 0x40:
5777 case 0x41:
5778 case 0x4f:
5779 case 0x43:
5780 case 0x44:
5781 case 0x62:
5782 case 0x56:
5783 case 0x53:
5784 case 0x5d:
5785 case 0x5e: temp = 0x54; break;
5786 }
5787 }
5788 }
5789 }
5790 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,temp); /* BPLHRS */
5791
5792 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5793 temp += 2;
5794 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5795 temp += 8;
5796 if(SiS_Pr->PanelHRE != 999) {
5797 temp = tempcx + SiS_Pr->PanelHRE;
5798 if(temp >= SiS_Pr->SiS_HT) temp -= SiS_Pr->SiS_HT;
5799 temp >>= 3;
5800 }
5801 }
5802 } else {
5803 temp += 10;
5804 }
5805
5806 temp &= 0x1F;
5807 temp |= ((tempcx & 0x07) << 5);
5808#if 0
5809 if(SiS_Pr->SiS_IF_DEF_FSTN) temp = 0x20; /* WRONG? BIOS loads cl, not ah */
5810#endif
5811 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,temp); /* BPLHRE */
5812
5813 /* Vertical */
5814
5815 tempax = SiS_Pr->SiS_VGAVDE;
5816 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5817 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5818 tempax = SiS_Pr->PanelYRes;
5819 }
5820 }
5821
5822 tempbx = SiS_Pr->SiS_LCDVDES + tempax;
5823 if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5824
5825 push2 = tempbx;
5826
5827 tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE;
5828 if(HwInfo->jChipType < SIS_315H) {
5829 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5830 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5831 tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->PanelYRes;
5832 }
5833 }
5834 }
5835 if(islvds) tempcx >>= 1;
5836 else tempcx >>= 2;
5837
5838 if( (SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
5839 (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) &&
5840 (SiS_Pr->PanelVRS != 999) ) {
5841 tempcx = SiS_Pr->PanelVRS;
5842 tempbx += tempcx;
5843 if(issis) tempbx++;
5844 } else {
5845 tempbx += tempcx;
5846 if(HwInfo->jChipType < SIS_315H) tempbx++;
5847 else if(issis) tempbx++;
5848 }
5849
5850 if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT; /* BPLVRS */
5851
5852 temp = tempbx & 0x00FF;
5853 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5854 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5855 if(ModeNo == 0x10) temp = 0xa9;
5856 }
5857 }
5858 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);
5859
5860 tempcx >>= 3;
5861 tempcx++;
5862
5863 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5864 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5865 if(SiS_Pr->PanelVRE != 999) tempcx = SiS_Pr->PanelVRE;
5866 }
5867 }
5868
5869 tempcx += tempbx;
5870 temp = tempcx & 0x000F;
5871 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp); /* BPLVRE */
5872
5873 temp = ((tempbx >> 8) & 0x07) << 3;
5874 if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
5875 if(SiS_Pr->SiS_HDE != 640) {
5876 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
5877 }
5878 } else if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
5879 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) temp |= 0x40;
5880 tempbx = 0x87;
5881 if((HwInfo->jChipType >= SIS_315H) ||
5882 (HwInfo->jChipRevision >= 0x30)) {
5883 tempbx = 0x07;
5884 if((SiS_Pr->SiS_IF_DEF_CH70xx == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
5885 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x03) temp |= 0x80;
5886 }
5887 /* Chrontel 701x operates in 24bit mode (8-8-8, 2x12bit mutliplexed) via VGA2 */
5888 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5889 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5890 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x10) temp |= 0x80;
5891 } else {
5892 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80;
5893 }
5894 }
5895 }
5896 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,tempbx,temp);
5897
5898 tempbx = push2; /* BPLVDEE */
5899
5900 tempcx = SiS_Pr->SiS_LCDVDES; /* BPLVDES */
5901
5902 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5903 switch(SiS_Pr->SiS_LCDResInfo) {
5904 case Panel_640x480:
5905 tempbx = SiS_Pr->SiS_VGAVDE - 1;
5906 tempcx = SiS_Pr->SiS_VGAVDE;
5907 break;
5908 case Panel_800x600:
5909 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5910 if(resinfo == SIS_RI_800x600) tempcx++;
5911 }
5912 break;
5913 case Panel_1024x600:
5914 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5915 if(resinfo == SIS_RI_1024x600) tempcx++;
5916 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
5917 if(resinfo == SIS_RI_800x600) tempcx++;
5918 }
5919 }
5920 break;
5921 case Panel_1024x768:
5922 if(HwInfo->jChipType < SIS_315H) {
5923 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5924 if(resinfo == SIS_RI_1024x768) tempcx++;
5925 }
5926 }
5927 break;
5928 }
5929 }
5930
5931 temp = ((tempbx >> 8) & 0x07) << 3;
5932 temp = temp | ((tempcx >> 8) & 0x07);
5933 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1D,temp);
5934 /* if(SiS_Pr->SiS_IF_DEF_FSTN) tempbx++; */
5935 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1C,tempbx);
5936 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1B,tempcx);
5937
5938 /* Vertical scaling */
5939
5940 if(HwInfo->jChipType < SIS_315H) {
5941
5942#ifdef SIS300 /* 300 series */
5943 tempeax = SiS_Pr->SiS_VGAVDE << 6;
5944 temp = (tempeax % (ULONG)SiS_Pr->SiS_VDE);
5945 tempeax = tempeax / (ULONG)SiS_Pr->SiS_VDE;
5946 if(temp) tempeax++;
5947
5948 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) tempeax = 0x3F;
5949
5950 temp = (USHORT)(tempeax & 0x00FF);
5951 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,temp); /* BPLVCFACT */
5952 tempvcfact = temp;
5953#endif /* SIS300 */
5954
5955 } else {
5956
5957#ifdef SIS315H /* 315 series */
5958 tempeax = SiS_Pr->SiS_VGAVDE << 18;
5959 tempebx = SiS_Pr->SiS_VDE;
5960 temp = (tempeax % tempebx);
5961 tempeax = tempeax / tempebx;
5962 if(temp) tempeax++;
5963 tempvcfact = tempeax;
5964
5965 temp = (USHORT)(tempeax & 0x00FF);
5966 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,temp);
5967 temp = (USHORT)((tempeax & 0x00FF00) >> 8);
5968 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,temp);
5969 temp = (USHORT)((tempeax & 0x00030000) >> 16);
5970 if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
5971 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,temp);
5972
5973 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV)) {
5974 temp = (USHORT)(tempeax & 0x00FF);
5975 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3c,temp);
5976 temp = (USHORT)((tempeax & 0x00FF00) >> 8);
5977 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3b,temp);
5978 temp = (USHORT)(((tempeax & 0x00030000) >> 16) << 6);
5979 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0x3f,temp);
5980 temp = 0;
5981 if(SiS_Pr->SiS_VDE != SiS_Pr->SiS_VGAVDE) temp |= 0x08;
5982 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x30,0xf3,temp);
5983 }
5984#endif
5985
5986 }
5987
5988 /* Horizontal scaling */
5989
5990 tempeax = SiS_Pr->SiS_VGAHDE; /* 1f = ( (VGAHDE * 65536) / ( (VGAHDE * 65536) / HDE ) ) - 1*/
5991 if(chkdclkfirst) {
5992 if(modeflag & HalfDCLK) tempeax >>= 1;
5993 }
5994 tempebx = tempeax << 16;
5995 if(SiS_Pr->SiS_HDE == tempeax) {
5996 tempecx = 0xFFFF;
5997 } else {
5998 tempecx = tempebx / SiS_Pr->SiS_HDE;
5999 if(HwInfo->jChipType >= SIS_315H) {
6000 if(tempebx % SiS_Pr->SiS_HDE) tempecx++;
6001 }
6002 }
6003
6004 if(HwInfo->jChipType >= SIS_315H) {
6005 tempeax = (tempebx / tempecx) - 1;
6006 } else {
6007 tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1;
6008 }
6009 tempecx = (tempecx << 16) | (tempeax & 0xFFFF);
6010 temp = (USHORT)(tempecx & 0x00FF);
6011 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1F,temp);
6012
6013 if(HwInfo->jChipType >= SIS_315H) {
6014 tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
6015 tempbx = (USHORT)(tempeax & 0xFFFF);
6016 } else {
6017 tempeax = SiS_Pr->SiS_VGAVDE << 6;
6018 tempbx = tempvcfact & 0x3f;
6019 if(tempbx == 0) tempbx = 64;
6020 tempeax /= tempbx;
6021 tempbx = (USHORT)(tempeax & 0xFFFF);
6022 }
6023 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tempbx--;
6024 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
6025 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) tempbx = 1;
6026 else if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) tempbx = 1;
6027 }
6028
6029 temp = ((tempbx >> 8) & 0x07) << 3;
6030 temp = temp | ((tempecx >> 8) & 0x07);
6031 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x20,temp);
6032 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x21,tempbx);
6033
6034 tempecx >>= 16; /* BPLHCFACT */
6035 if(!chkdclkfirst) {
6036 if(modeflag & HalfDCLK) tempecx >>= 1;
6037 }
6038 temp = (USHORT)((tempecx & 0xFF00) >> 8);
6039 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x22,temp);
6040 temp = (USHORT)(tempecx & 0x00FF);
6041 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp);
6042
6043#ifdef SIS315H
6044 if(HwInfo->jChipType >= SIS_315H) {
6045 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
6046 if((islvds) || (SiS_Pr->SiS_VBInfo & VB_SIS301LV302LV)) {
6047 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x20);
6048 }
6049 } else {
6050 if(islvds) {
6051 if(HwInfo->jChipType == SIS_740) {
6052 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
6053 } else {
6054 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x23);
6055 }
6056 }
6057 }
6058 }
6059#endif
6060
6061#ifdef SIS300
6062 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
6063 int i;
6064 UCHAR TrumpMode13[4] = { 0x01, 0x10, 0x2c, 0x00 };
6065 UCHAR TrumpMode10_1[4] = { 0x01, 0x10, 0x27, 0x00 };
6066 UCHAR TrumpMode10_2[4] = { 0x01, 0x16, 0x10, 0x00 };
6067
6068 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xbf);
6069 for(i=0; i<5; i++) {
6070 SiS_SetTrumpionBlock(SiS_Pr, &SiS300_TrumpionData[crt2crtc][0]);
6071 }
6072 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6073 if(ModeNo == 0x13) {
6074 for(i=0; i<4; i++) {
6075 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode13[0]);
6076 }
6077 } else if(ModeNo == 0x10) {
6078 for(i=0; i<4; i++) {
6079 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_1[0]);
6080 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_2[0]);
6081 }
6082 }
6083 }
6084 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
6085 }
6086#endif
6087
6088#ifdef SIS315H
6089 if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
6090 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x25,0x00);
6091 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x26,0x00);
6092 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x27,0x00);
6093 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x28,0x87);
6094 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x29,0x5A);
6095 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2A,0x4B);
6096 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x07,0x03);
6097 tempax = SiS_Pr->SiS_HDE; /* Blps = lcdhdee(lcdhdes+HDE) + 64 */
6098 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
6099 SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1;
6100 tempax += 64;
6101 temp = tempax & 0x00FF;
6102 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,temp);
6103 temp = ((tempax & 0xFF00) >> 8) << 3;
6104 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp);
6105 tempax += 32; /* Blpe=lBlps+32 */
6106 temp = tempax & 0x00FF;
6107 if(SiS_Pr->SiS_IF_DEF_FSTN) temp = 0;
6108 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,temp);
6109 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3A,0x00); /* Bflml=0 */
6110 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x007,0x00);
6111
6112 tempax = SiS_Pr->SiS_VDE;
6113 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
6114 SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1;
6115 tempax >>= 1;
6116 temp = tempax & 0x00FF;
6117 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3B,temp);
6118 temp = ((tempax & 0xFF00) >> 8) << 3;
6119 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);
6120
6121 tempeax = SiS_Pr->SiS_HDE;
6122 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
6123 SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempeax >>= 1;
6124 tempeax <<= 2; /* BDxFIFOSTOP = (HDE*4)/128 */
6125 tempebx = 128;
6126 temp = (USHORT)(tempeax % tempebx);
6127 tempeax = tempeax / tempebx;
6128 if(temp) tempeax++;
6129 temp = (USHORT)(tempeax & 0x003F);
6130 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x45,~0x0FF,temp);
6131 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3F,0x00); /* BDxWadrst0 */
6132 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3E,0x00);
6133 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3D,0x10);
6134 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x040,0x00);
6135
6136 tempax = SiS_Pr->SiS_HDE;
6137 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
6138 SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1;
6139 tempax >>= 4; /* BDxWadroff = HDE*4/8/8 */
6140 pushcx = tempax;
6141 temp = tempax & 0x00FF;
6142 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,temp);
6143 temp = ((tempax & 0xFF00) >> 8) << 3;
6144 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x0F8,temp);
6145
6146 tempax = SiS_Pr->SiS_VDE; /* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
6147 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
6148 SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1;
6149 tempeax = (tempax * pushcx);
6150 tempebx = 0x00100000 + tempeax;
6151 temp = (USHORT)tempebx & 0x000000FF;
6152 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,temp);
6153 temp = (USHORT)((tempebx & 0x0000FF00) >> 8);
6154 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,temp);
6155 temp = (USHORT)((tempebx & 0x00FF0000) >> 16);
6156 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,temp);
6157 temp = (USHORT)(((tempebx & 0x01000000) >> 24) << 7);
6158 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x080,temp);
6159
6160 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x03);
6161 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0x50);
6162 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,0x00);
6163 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x01);
6164 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0x38);
6165
6166 if(SiS_Pr->SiS_IF_DEF_FSTN) {
6167 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2b,0x02);
6168 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2c,0x00);
6169 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x00);
6170 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,0x0c);
6171 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,0x00);
6172 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,0x00);
6173 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,0x80);
6174 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,0xA0);
6175 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3a,0x00);
6176 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3b,0xf0);
6177 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3c,0x00);
6178 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3d,0x10);
6179 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3e,0x00);
6180 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3f,0x00);
6181 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,0x10);
6182 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,0x25);
6183 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,0x80);
6184 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,0x14);
6185 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x44,0x03);
6186 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,0x0a);
6187 }
6188 }
6189#endif /* SIS315H */
6190}
6191
6192/* Set Part 1 */
6193static void
6194SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
6195 PSIS_HW_INFO HwInfo, USHORT RefreshRateTableIndex)
6196{
6197#if defined(SIS300) || defined(SIS315H)
6198 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
6199#endif
6200 USHORT temp=0, tempax=0, tempbx=0, tempcx=0, bridgeadd=0;
6201 USHORT pushbx=0, CRT1Index=0, modeflag, resinfo=0;
6202#ifdef SIS315H
6203 USHORT tempbl=0;
6204#endif
6205
6206 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
6207 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
6208 return;
6209 }
6210
6211 if(ModeNo <= 0x13) {
6212 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6213 } else if(SiS_Pr->UseCustomMode) {
6214 modeflag = SiS_Pr->CModeFlag;
6215 } else {
6216 CRT1Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
6217 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
6218 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6219 }
6220
6221 SiS_SetCRT2Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
6222
6223 if( ! ((HwInfo->jChipType >= SIS_315H) &&
6224 (SiS_Pr->SiS_IF_DEF_LVDS == 1) &&
6225 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
6226
6227 if(HwInfo->jChipType < SIS_315H ) {
6228#ifdef SIS300
6229 SiS_SetCRT2FIFO_300(SiS_Pr, ModeNo, HwInfo);
6230#endif
6231 } else {
6232#ifdef SIS315H
6233 SiS_SetCRT2FIFO_310(SiS_Pr, HwInfo);
6234#endif
6235 }
6236
6237 /* 1. Horizontal setup */
6238
6239 if(HwInfo->jChipType < SIS_315H ) {
6240
6241#ifdef SIS300 /* ------------- 300 series --------------*/
6242
6243 temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
6244 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp); /* CRT2 Horizontal Total */
6245
6246 temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
6247 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp); /* CRT2 Horizontal Total Overflow [7:4] */
6248
6249 temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */
6250 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp); /* CRT2 Horizontal Display Enable End */
6251
6252 pushbx = SiS_Pr->SiS_VGAHDE + 12; /* bx BTVGA2HRS 0x0B,0x0C */
6253 tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2;
6254 tempbx = pushbx + tempcx;
6255 tempcx <<= 1;
6256 tempcx += tempbx;
6257
6258 bridgeadd = 12;
6259
6260#endif /* SIS300 */
6261
6262 } else {
6263
6264#ifdef SIS315H /* ------------------- 315/330 series --------------- */
6265
6266 tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HT 0x08,0x09 */
6267 if(modeflag & HalfDCLK) {
6268 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6269 tempcx >>= 1;
6270 } else {
6271 tempax = SiS_Pr->SiS_VGAHDE >> 1;
6272 tempcx = SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE + tempax;
6273 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
6274 tempcx = SiS_Pr->SiS_HT - tempax;
6275 }
6276 }
6277 }
6278 tempcx--;
6279 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,tempcx); /* CRT2 Horizontal Total */
6280 temp = (tempcx >> 4) & 0xF0;
6281 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp); /* CRT2 Horizontal Total Overflow [7:4] */
6282
6283 tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HDEE 0x0A,0x0C */
6284 tempbx = SiS_Pr->SiS_VGAHDE;
6285 tempcx -= tempbx;
6286 tempcx >>= 2;
6287 if(modeflag & HalfDCLK) {
6288 tempbx >>= 1;
6289 tempcx >>= 1;
6290 }
6291 tempbx += 16;
6292
6293 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,tempbx); /* CRT2 Horizontal Display Enable End */
6294
6295 pushbx = tempbx;
6296 tempcx >>= 1;
6297 tempbx += tempcx;
6298 tempcx += tempbx;
6299
6300 bridgeadd = 16;
6301
6302 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6303 if(HwInfo->jChipType >= SIS_661) {
6304 if((SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
6305 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
6306 if(resinfo == SIS_RI_1280x1024) {
6307 tempcx = (tempcx & 0xff00) | 0x30;
6308 } else if(resinfo == SIS_RI_1600x1200) {
6309 tempcx = (tempcx & 0xff00) | 0xff;
6310 }
6311 }
6312 }
6313 }
6314
6315#endif /* SIS315H */
6316
6317 } /* 315/330 series */
6318
6319 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6320
6321 if(SiS_Pr->UseCustomMode) {
6322 tempbx = SiS_Pr->CHSyncStart + bridgeadd;
6323 tempcx = SiS_Pr->CHSyncEnd + bridgeadd;
6324 tempax = SiS_Pr->SiS_VGAHT;
6325 if(modeflag & HalfDCLK) tempax >>= 1;
6326 tempax--;
6327 if(tempcx > tempax) tempcx = tempax;
6328 }
6329
6330 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6331 unsigned char cr4, cr14, cr5, cr15;
6332 if(SiS_Pr->UseCustomMode) {
6333 cr4 = SiS_Pr->CCRT1CRTC[4];
6334 cr14 = SiS_Pr->CCRT1CRTC[14];
6335 cr5 = SiS_Pr->CCRT1CRTC[5];
6336 cr15 = SiS_Pr->CCRT1CRTC[15];
6337 } else {
6338 cr4 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
6339 cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
6340 cr5 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
6341 cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
6342 }
6343 tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3; /* (VGAHRS-3)*8 */
6344 tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3; /* (VGAHRE-3)*8 */
6345 tempcx &= 0x00FF;
6346 tempcx |= (tempbx & 0xFF00);
6347 tempbx += bridgeadd;
6348 tempcx += bridgeadd;
6349 tempax = SiS_Pr->SiS_VGAHT;
6350 if(modeflag & HalfDCLK) tempax >>= 1;
6351 tempax--;
6352 if(tempcx > tempax) tempcx = tempax;
6353 }
6354
6355 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6356 tempbx = 1040;
6357 tempcx = 1044; /* HWCursor bug! */
6358 }
6359
6360 }
6361
6362 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,tempbx); /* CRT2 Horizontal Retrace Start */
6363
6364 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,tempcx); /* CRT2 Horizontal Retrace End */
6365
6366 temp = ((tempbx >> 8) & 0x0F) | ((pushbx >> 4) & 0xF0);
6367 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp); /* Overflow */
6368
6369 /* 2. Vertical setup */
6370
6371 tempcx = SiS_Pr->SiS_VGAVT - 1;
6372 temp = tempcx & 0x00FF;
6373
6374 if(HwInfo->jChipType < SIS_661) {
6375 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6376 if(HwInfo->jChipType < SIS_315H) {
6377 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6378 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
6379 temp--;
6380 }
6381 }
6382 } else {
6383 temp--;
6384 }
6385 } else if(HwInfo->jChipType >= SIS_315H) {
6386 temp--;
6387 }
6388 }
6389 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp); /* CRT2 Vertical Total */
6390
6391 tempbx = SiS_Pr->SiS_VGAVDE - 1;
6392 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,tempbx); /* CRT2 Vertical Display Enable End */
6393
6394 temp = ((tempbx >> 5) & 0x38) | ((tempcx >> 8) & 0x07);
6395 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,temp); /* Overflow */
6396
6397 if((HwInfo->jChipType >= SIS_315H) && (HwInfo->jChipType < SIS_661)) {
6398 tempbx++;
6399 tempax = tempbx;
6400 tempcx++;
6401 tempcx -= tempax;
6402 tempcx >>= 2;
6403 tempbx += tempcx;
6404 if(tempcx < 4) tempcx = 4;
6405 tempcx >>= 2;
6406 tempcx += tempbx;
6407 tempcx++;
6408 } else {
6409 tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1; /* BTVGA2VRS 0x10,0x11 */
6410 tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1; /* BTVGA2VRE 0x11 */
6411 }
6412
6413 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6414 if(SiS_Pr->UseCustomMode) {
6415 tempbx = SiS_Pr->CVSyncStart;
6416 tempcx = SiS_Pr->CVSyncEnd;
6417 }
6418 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6419 unsigned char cr8, cr7, cr13;
6420 if(SiS_Pr->UseCustomMode) {
6421 cr8 = SiS_Pr->CCRT1CRTC[8];
6422 cr7 = SiS_Pr->CCRT1CRTC[7];
6423 cr13 = SiS_Pr->CCRT1CRTC[13];
6424 tempcx = SiS_Pr->CCRT1CRTC[9];
6425 } else {
6426 cr8 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8];
6427 cr7 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
6428 cr13 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
6429 tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
6430 }
6431 tempbx = cr8;
6432 if(cr7 & 0x04) tempbx |= 0x0100;
6433 if(cr7 & 0x80) tempbx |= 0x0200;
6434 if(cr13 & 0x08) tempbx |= 0x0400;
6435 }
6436 }
6437 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,tempbx); /* CRT2 Vertical Retrace Start */
6438
6439 temp = ((tempbx >> 4) & 0x70) | (tempcx & 0x0F);
6440 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,temp); /* CRT2 Vert. Retrace End; Overflow */
6441
6442 /* 3. Panel delay compensation */
6443
6444 if(HwInfo->jChipType < SIS_315H) {
6445
6446#ifdef SIS300 /* ---------- 300 series -------------- */
6447
6448 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6449 temp = 0x20;
6450 if(HwInfo->jChipType == SIS_300) {
6451 temp = 0x10;
6452 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) temp = 0x2c;
6453 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6454 }
6455 if(SiS_Pr->SiS_VBType & VB_SIS301) {
6456 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
6457 }
6458 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960) temp = 0x24;
6459 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) temp = 0x2c;
6460 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x08;
6461 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6462 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) temp = 0x2c;
6463 else temp = 0x20;
6464 }
6465 if(SiS_Pr->SiS_UseROM) {
6466 if(ROMAddr[0x220] & 0x80) {
6467 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision)
6468 temp = ROMAddr[0x221];
6469 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)
6470 temp = ROMAddr[0x222];
6471 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)
6472 temp = ROMAddr[0x223];
6473 else
6474 temp = ROMAddr[0x224];
6475 temp &= 0x3c;
6476 }
6477 }
6478 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6479 if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC & 0x3c;
6480 }
6481
6482 } else {
6483 temp = 0x20;
6484 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
6485 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) temp = 0x04;
6486 }
6487 if(SiS_Pr->SiS_UseROM) {
6488 if(ROMAddr[0x220] & 0x80) {
6489 temp = ROMAddr[0x220] & 0x3c;
6490 }
6491 }
6492 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6493 if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC & 0x3c;
6494 }
6495 }
6496
6497 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
6498
6499#endif /* SIS300 */
6500
6501 } else {
6502
6503#ifdef SIS315H /* --------------- 315/330 series ---------------*/
6504
6505 if(HwInfo->jChipType < SIS_661) {
6506
6507 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6508
6509 if(HwInfo->jChipType == SIS_740) temp = 0x03;
6510 else temp = 0x00;
6511
6512 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x0a;
6513 tempbl = 0xF0;
6514 if(HwInfo->jChipType == SIS_650) {
6515 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6516 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F;
6517 }
6518 }
6519
6520 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) {
6521 temp = 0x08;
6522 tempbl = 0;
6523 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
6524 if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0;
6525 }
6526 }
6527
6528 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp); /* Panel Link Delay Compensation */
6529 }
6530
6531 } /* < 661 */
6532
6533 tempax = 0;
6534 if(modeflag & DoubleScanMode) tempax |= 0x80;
6535 if(modeflag & HalfDCLK) tempax |= 0x40;
6536 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax);
6537
6538#endif /* SIS315H */
6539
6540 }
6541
6542 } /* Slavemode */
6543
6544 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6545 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
6546 /* For 301BDH with LCD, we set up the Panel Link */
6547 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
6548 } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6549 SiS_SetGroup1_301(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
6550 }
6551 } else {
6552 if(HwInfo->jChipType < SIS_315H) {
6553 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
6554 } else {
6555 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6556 if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
6557 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex, HwInfo,RefreshRateTableIndex);
6558 }
6559 } else {
6560 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex, HwInfo,RefreshRateTableIndex);
6561 }
6562 }
6563 }
6564}
6565
6566/*********************************************/
6567/* SET PART 2 REGISTER GROUP */
6568/*********************************************/
6569
6570#ifdef SIS315H
6571static UCHAR *
6572SiS_GetGroup2CLVXPtr(SiS_Private *SiS_Pr, int tabletype, PSIS_HW_INFO HwInfo)
6573{
6574 const UCHAR *tableptr = NULL;
6575 USHORT a, b, p = 0;
6576
6577 a = SiS_Pr->SiS_VGAHDE;
6578 b = SiS_Pr->SiS_HDE;
6579 if(tabletype) {
6580 a = SiS_Pr->SiS_VGAVDE;
6581 b = SiS_Pr->SiS_VDE;
6582 }
6583
6584 if(a < b) {
6585 tableptr = SiS_Part2CLVX_1;
6586 } else if(a == b) {
6587 tableptr = SiS_Part2CLVX_2;
6588 } else {
6589 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6590 tableptr = SiS_Part2CLVX_4;
6591 } else {
6592 tableptr = SiS_Part2CLVX_3;
6593 }
6594 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6595 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) tableptr = SiS_Part2CLVX_3;
6596 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tableptr = SiS_Part2CLVX_3;
6597 else tableptr = SiS_Part2CLVX_5;
6598 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6599 tableptr = SiS_Part2CLVX_6;
6600 }
6601 do {
6602 if((tableptr[p] | tableptr[p+1] << 8) == a) break;
6603 p += 0x42;
6604 } while((tableptr[p] | tableptr[p+1] << 8) != 0xffff);
6605 if((tableptr[p] | tableptr[p+1] << 8) == 0xffff) p -= 0x42;
6606 }
6607 p += 2;
6608 return((UCHAR *)&tableptr[p]);
6609}
6610
6611static void
6612SiS_SetGroup2_C_ELV(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
6613 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
6614{
6615 UCHAR *tableptr;
6616 int i, j;
6617 UCHAR temp;
6618
6619 if(!(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV))) return;
6620
6621 tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 0, HwInfo);
6622 for(i = 0x80, j = 0; i <= 0xbf; i++, j++) {
6623 SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6624 }
6625 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6626 tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 1, HwInfo);
6627 for(i = 0xc0, j = 0; i <= 0xff; i++, j++) {
6628 SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6629 }
6630 }
6631 temp = 0x10;
6632 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp |= 0x04;
6633 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xeb,temp);
6634}
6635
6636static BOOLEAN
6637SiS_GetCRT2Part2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
6638 USHORT RefreshRateTableIndex,USHORT *CRT2Index,
6639 USHORT *ResIndex,PSIS_HW_INFO HwInfo)
6640{
6641
6642 if(HwInfo->jChipType < SIS_315H) return FALSE;
6643
6644 if(ModeNo <= 0x13)
6645 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6646 else
6647 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6648
6649 (*ResIndex) &= 0x3f;
6650 (*CRT2Index) = 0;
6651
6652 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6653 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6654 (*CRT2Index) = 200;
6655 }
6656 }
6657
6658 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
6659 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6660 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) (*CRT2Index) = 206;
6661 }
6662 }
6663 return(((*CRT2Index) != 0));
6664}
6665#endif
6666
6667#ifdef SIS300
6668static void
6669SiS_Group2LCDSpecial(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo, USHORT crt2crtc)
6670{
6671 USHORT tempcx;
6672 const UCHAR atable[] = {
6673 0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,
6674 0xab,0x87,0xab,0x9e,0xe7,0x02,0x02
6675 };
6676
6677 if(!SiS_Pr->UseCustomMode) {
6678 if( ( ( (HwInfo->jChipType == SIS_630) ||
6679 (HwInfo->jChipType == SIS_730) ) &&
6680 (HwInfo->jChipRevision > 2) ) &&
6681 (SiS_Pr->SiS_LCDResInfo == Panel_1024x768) &&
6682 (!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) &&
6683 (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
6684 if(ModeNo == 0x13) {
6685 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xB9);
6686 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0xCC);
6687 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xA6);
6688 } else {
6689 if((crt2crtc & 0x3F) == 4) {
6690 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x2B);
6691 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x13);
6692 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xE5);
6693 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0x08);
6694 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xE2);
6695 }
6696 }
6697 }
6698
6699 if(HwInfo->jChipType < SIS_315H) {
6700 if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
6701 crt2crtc &= 0x1f;
6702 tempcx = 0;
6703 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6704 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6705 tempcx += 7;
6706 }
6707 }
6708 tempcx += crt2crtc;
6709 if(crt2crtc >= 4) {
6710 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xff);
6711 }
6712
6713 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6714 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6715 if(crt2crtc == 4) {
6716 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x28);
6717 }
6718 }
6719 }
6720 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x18);
6721 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
6722 }
6723 }
6724 }
6725}
6726
6727/* For ECS A907. Highly preliminary. */
6728static void
6729SiS_Set300Part2Regs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
6730 USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
6731 USHORT ModeNo)
6732{
6733 USHORT crt2crtc, resindex;
6734 int i,j;
6735 const SiS_Part2PortTblStruct *CRT2Part2Ptr = NULL;
6736
6737 if(HwInfo->jChipType != SIS_300) return;
6738 if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) return;
6739 if(SiS_Pr->UseCustomMode) return;
6740
6741 if(ModeNo <= 0x13) {
6742 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6743 } else {
6744 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6745 }
6746
6747 resindex = crt2crtc & 0x3F;
6748 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6749 else CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2;
6750
6751 /* The BIOS code (1.16.51,56) is obviously a fragment! */
6752 if(ModeNo > 0x13) {
6753 CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
6754 resindex = 4;
6755 }
6756
6757 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
6758 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
6759 for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
6760 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6761 }
6762 for(j = 0x1c; j <= 0x1d; i++, j++ ) {
6763 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6764 }
6765 for(j = 0x1f; j <= 0x21; i++, j++ ) {
6766 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6767 }
6768 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
6769 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
6770}
6771#endif
6772
6773static void
6774SiS_SetTVSpecial(SiS_Private *SiS_Pr, USHORT ModeNo)
6775{
6776 if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) return;
6777 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) return;
6778 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) return;
6779
6780 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
6781 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6782 const UCHAR specialtv[] = {
6783 0xa7,0x07,0xf2,0x6e,0x17,0x8b,0x73,0x53,
6784 0x13,0x40,0x34,0xf4,0x63,0xbb,0xcc,0x7a,
6785 0x58,0xe4,0x73,0xda,0x13
6786 };
6787 int i, j;
6788 for(i = 0x1c, j = 0; i <= 0x30; i++, j++) {
6789 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,specialtv[j]);
6790 }
6791 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,0x72);
6792 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750)) {
6793 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6794 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14);
6795 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1b);
6796 } else {
6797 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14); /* 15 */
6798 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1a); /* 1b */
6799 }
6800 }
6801 }
6802 } else {
6803 if((ModeNo == 0x38) || (ModeNo == 0x4a) || (ModeNo == 0x64) ||
6804 (ModeNo == 0x52) || (ModeNo == 0x58) || (ModeNo == 0x5c)) {
6805 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b); /* 21 */
6806 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54); /* 5a */
6807 } else {
6808 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1a); /* 21 */
6809 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x53); /* 5a */
6810 }
6811 }
6812}
6813
6814static void
6815SiS_SetGroup2_Tail(SiS_Private *SiS_Pr, USHORT ModeNo)
6816{
6817 USHORT temp;
6818
6819 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6820 if(SiS_Pr->SiS_VGAVDE == 525) {
6821 temp = 0xc3;
6822 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6823 temp++;
6824 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp += 2;
6825 }
6826 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6827 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xb3);
6828 } else if(SiS_Pr->SiS_VGAVDE == 420) {
6829 temp = 0x4d;
6830 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6831 temp++;
6832 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp++;
6833 }
6834 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6835 }
6836 }
6837
6838 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6839 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
6840 if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
6841 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x1a,0x03);
6842 /* Not always for LV, see SetGrp2 */
6843 }
6844 temp = 1;
6845 if(ModeNo <= 0x13) temp = 3;
6846 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0b,temp);
6847 }
6848#if 0
6849 /* 651+301C, for 1280x768 - do I really need that? */
6850 if((SiS_Pr->SiS_PanelXRes == 1280) && (SiS_Pr->SiS_PanelYRes == 768)) {
6851 if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) {
6852 if(((SiS_Pr->SiS_HDE == 640) && (SiS_Pr->SiS_VDE == 480)) ||
6853 ((SiS_Pr->SiS_HDE == 320) && (SiS_Pr->SiS_VDE == 240))) {
6854 SiS_SetReg(SiS_Part2Port,0x01,0x2b);
6855 SiS_SetReg(SiS_Part2Port,0x02,0x13);
6856 SiS_SetReg(SiS_Part2Port,0x04,0xe5);
6857 SiS_SetReg(SiS_Part2Port,0x05,0x08);
6858 SiS_SetReg(SiS_Part2Port,0x06,0xe2);
6859 SiS_SetReg(SiS_Part2Port,0x1c,0x21);
6860 SiS_SetReg(SiS_Part2Port,0x1d,0x45);
6861 SiS_SetReg(SiS_Part2Port,0x1f,0x0b);
6862 SiS_SetReg(SiS_Part2Port,0x20,0x00);
6863 SiS_SetReg(SiS_Part2Port,0x21,0xa9);
6864 SiS_SetReg(SiS_Part2Port,0x23,0x0b);
6865 SiS_SetReg(SiS_Part2Port,0x25,0x04);
6866 }
6867 }
6868 }
6869#endif
6870 }
6871}
6872
6873static void
6874SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
6875 PSIS_HW_INFO HwInfo)
6876{
6877 USHORT i, j, tempax, tempbx, tempcx, tempch, tempcl, temp;
6878 USHORT push2, modeflag, crt2crtc, bridgeoffset;
6879 ULONG longtemp;
6880 const UCHAR *PhasePoint;
6881 const UCHAR *TimingPoint;
6882#ifdef SIS315H
6883 USHORT resindex, CRT2Index;
6884 const SiS_Part2PortTblStruct *CRT2Part2Ptr = NULL;
6885
6886 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
6887#endif
6888
6889 if(ModeNo <= 0x13) {
6890 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
6891 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
6892 } else if(SiS_Pr->UseCustomMode) {
6893 modeflag = SiS_Pr->CModeFlag;
6894 crt2crtc = 0;
6895 } else {
6896 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6897 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
6898 }
6899
6900 temp = 0;
6901 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO)) temp |= 0x08;
6902 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO)) temp |= 0x04;
6903 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) temp |= 0x02;
6904 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp |= 0x01;
6905
6906 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) temp |= 0x10;
6907
6908 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x00,temp);
6909
6910 PhasePoint = SiS_Pr->SiS_PALPhase;
6911 TimingPoint = SiS_Pr->SiS_PALTiming;
6912
6913 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6914
6915 TimingPoint = SiS_Pr->SiS_HiTVExtTiming;
6916 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6917 TimingPoint = SiS_Pr->SiS_HiTVSt2Timing;
6918 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
6919 TimingPoint = SiS_Pr->SiS_HiTVSt1Timing;
6920#if 0
6921 if(!(modeflag & Charx8Dot)) TimingPoint = SiS_Pr->SiS_HiTVTextTiming;
6922#endif
6923 }
6924 }
6925
6926 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6927
6928 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) TimingPoint = &SiS_YPbPrTable[2][0];
6929 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) TimingPoint = &SiS_YPbPrTable[1][0];
6930 else TimingPoint = &SiS_YPbPrTable[0][0];
6931
6932 PhasePoint = SiS_Pr->SiS_NTSCPhase;
6933
6934 } else if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6935
6936 if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
6937 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6938 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6939 PhasePoint = SiS_Pr->SiS_PALPhase2;
6940 }
6941
6942 } else {
6943
6944 TimingPoint = SiS_Pr->SiS_NTSCTiming;
6945 PhasePoint = SiS_Pr->SiS_NTSCPhase;
6946 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
6947 PhasePoint = SiS_Pr->SiS_PALPhase;
6948 }
6949
6950 if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
6951 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6952 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6953 PhasePoint = SiS_Pr->SiS_NTSCPhase2;
6954 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
6955 PhasePoint = SiS_Pr->SiS_PALPhase2;
6956 }
6957 }
6958
6959 }
6960
6961 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6962 PhasePoint = SiS_Pr->SiS_PALMPhase;
6963 if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
6964 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6965 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6966 PhasePoint = SiS_Pr->SiS_PALMPhase2;
6967 }
6968 }
6969
6970 if(SiS_Pr->SiS_TVMode & TVSetPALN) {
6971 PhasePoint = SiS_Pr->SiS_PALNPhase;
6972 if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
6973 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6974 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6975 PhasePoint = SiS_Pr->SiS_PALNPhase2;
6976 }
6977 }
6978
6979 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6980 PhasePoint = SiS_Pr->SiS_SpecialPhase;
6981 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6982 PhasePoint = SiS_Pr->SiS_SpecialPhaseM;
6983 } else if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
6984 PhasePoint = SiS_Pr->SiS_SpecialPhaseJ;
6985 }
6986 }
6987
6988 for(i=0x31, j=0; i<=0x34; i++, j++) {
6989 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,PhasePoint[j]);
6990 }
6991
6992 for(i=0x01, j=0; i<=0x2D; i++, j++) {
6993 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
6994 }
6995 for(i=0x39; i<=0x45; i++, j++) {
6996 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
6997 }
6998
6999 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7000 if(SiS_Pr->SiS_ModeType != ModeText) {
7001 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
7002 }
7003 }
7004
7005 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x0A,SiS_Pr->SiS_NewFlickerMode);
7006
7007 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x35,SiS_Pr->SiS_RY1COE);
7008 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x36,SiS_Pr->SiS_RY2COE);
7009 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x37,SiS_Pr->SiS_RY3COE);
7010 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x38,SiS_Pr->SiS_RY4COE);
7011
7012 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempax = 950;
7013 else if(SiS_Pr->SiS_TVMode & TVSetPAL) tempax = 520;
7014 else tempax = 440; /* NTSC, YPbPr 525, 750 */
7015
7016 if( ( (!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) && (SiS_Pr->SiS_VDE <= tempax) ) ||
7017 ( (SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) &&
7018 ((SiS_Pr->SiS_VGAHDE == 1024) || (SiS_Pr->SiS_VDE <= tempax)) ) ) {
7019
7020 tempax -= SiS_Pr->SiS_VDE;
7021 tempax >>= 2;
7022 tempax &= 0x00ff;
7023
7024 temp = tempax + (USHORT)TimingPoint[0];
7025 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
7026
7027 temp = tempax + (USHORT)TimingPoint[1];
7028 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
7029
7030 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) && (SiS_Pr->SiS_VGAHDE >= 1024)) {
7031 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7032 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b); /* 19 */
7033 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54); /* 52 */
7034 } else {
7035 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x17);
7036 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1d);
7037 }
7038 }
7039
7040 }
7041
7042 tempcx = SiS_Pr->SiS_HT;
7043 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempcx >>= 1;
7044 tempcx--;
7045 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) tempcx--;
7046 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1B,tempcx);
7047 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0xF0,((tempcx >> 8) & 0x0f));
7048
7049 tempcx = SiS_Pr->SiS_HT >> 1;
7050 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempcx >>= 1;
7051 tempcx += 7;
7052 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
7053 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,((tempcx << 4) & 0xf0));
7054
7055 tempbx = TimingPoint[j] | (TimingPoint[j+1] << 8);
7056 tempbx += tempcx;
7057 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x24,tempbx);
7058 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0F,((tempbx >> 4) & 0xf0));
7059
7060 tempbx += 8;
7061 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7062 tempbx -= 4;
7063 tempcx = tempbx;
7064 }
7065 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x29,0x0F,((tempbx << 4) & 0xf0));
7066
7067 j += 2;
7068 tempcx += (TimingPoint[j] | (TimingPoint[j+1] << 8));
7069 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x27,tempcx);
7070 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x28,0x0F,((tempcx >> 4) & 0xf0));
7071
7072 tempcx += 8;
7073 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
7074 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2A,0x0F,((tempcx << 4) & 0xf0));
7075
7076 tempcx = SiS_Pr->SiS_HT >> 1;
7077 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempcx >>= 1;
7078 j += 2;
7079 tempcx -= (TimingPoint[j] | ((TimingPoint[j+1]) << 8));
7080 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2D,0x0F,((tempcx << 4) & 0xf0));
7081
7082 tempcx -= 11;
7083 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
7084 tempcx = SiS_GetVGAHT2(SiS_Pr) - 1;
7085 }
7086 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2E,tempcx);
7087
7088 tempbx = SiS_Pr->SiS_VDE;
7089 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7090 if(SiS_Pr->SiS_VGAVDE == 360) tempbx = 746;
7091 if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 746;
7092 if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 853;
7093 } else if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
7094 (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p))) ) {
7095 tempbx >>= 1;
7096 if(HwInfo->jChipType >= SIS_315H) {
7097 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
7098 if((ModeNo <= 0x13) && (crt2crtc == 1)) tempbx++;
7099 } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7100 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
7101 if(crt2crtc == 4) tempbx++;
7102 }
7103 }
7104 }
7105 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7106 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7107 if((ModeNo == 0x2f) || (ModeNo == 0x5d) || (ModeNo == 0x5e)) tempbx++;
7108 }
7109 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
7110 if(ModeNo == 0x03) tempbx++; /* From 1.10.7w - doesn't make sense */
7111 }
7112 }
7113 }
7114 tempbx -= 2;
7115 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2F,tempbx);
7116
7117 temp = (tempcx >> 8) & 0x0F;
7118 temp |= ((tempbx >> 2) & 0xC0);
7119 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
7120 temp |= 0x10;
7121 if(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO) temp |= 0x20;
7122 }
7123 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,temp);
7124
7125 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302LV | VB_SIS302ELV)) {
7126 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xdf,((tempbx & 0x0400) >> 5));
7127 }
7128
7129#if 0
7130 /* TEST qqqq */
7131 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7132 for(i=0x01, j=0; i<=0x2D; i++, j++) {
7133 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
7134 }
7135 for(i=0x39; i<=0x45; i++, j++) {
7136 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
7137 }
7138 }
7139#endif
7140
7141 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
7142 tempbx = SiS_Pr->SiS_VDE;
7143 if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
7144 (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) ) {
7145 tempbx >>= 1;
7146 }
7147 tempbx -= 3;
7148 temp = ((tempbx >> 3) & 0x60) | 0x18;
7149 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x46,temp);
7150 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x47,tempbx);
7151
7152 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302LV | VB_SIS302ELV)) {
7153 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xbf,((tempbx & 0x0400) >> 4));
7154 }
7155 }
7156
7157 tempbx = 0;
7158 if(!(modeflag & HalfDCLK)) {
7159 if(SiS_Pr->SiS_VGAHDE >= SiS_Pr->SiS_HDE) {
7160 tempax = 0;
7161 tempbx |= 0x20;
7162 }
7163 }
7164
7165 tempch = tempcl = 0x01;
7166 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7167 if(SiS_Pr->SiS_VGAHDE >= 1024) {
7168 if((!(modeflag & HalfDCLK)) || (HwInfo->jChipType < SIS_315H)) {
7169 tempch = 0x19;
7170 tempcl = 0x20;
7171 if(SiS_Pr->SiS_VGAHDE >= 1280) {
7172 tempch = 0x14;
7173 tempbx &= ~0x20;
7174 }
7175 }
7176 }
7177 }
7178
7179 if(!(tempbx & 0x20)) {
7180 if(modeflag & HalfDCLK) tempcl <<= 1;
7181 longtemp = ((SiS_Pr->SiS_VGAHDE * tempch) / tempcl) << 13;
7182 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) longtemp <<= 3;
7183 tempax = longtemp / SiS_Pr->SiS_HDE;
7184 if(longtemp % SiS_Pr->SiS_HDE) tempax++;
7185 tempbx |= ((tempax >> 8) & 0x1F);
7186 tempcx = tempax >> 13;
7187 }
7188
7189 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,tempax);
7190 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,tempbx);
7191
7192 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
7193
7194 tempcx &= 0x07;
7195 if(tempbx & 0x20) tempcx = 0;
7196 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xF8,tempcx);
7197
7198 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7199 tempbx = 0x0382;
7200 tempcx = 0x007e;
7201 } else {
7202 tempbx = 0x0369;
7203 tempcx = 0x0061;
7204 }
7205 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4B,tempbx);
7206 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4C,tempcx);
7207 temp = (tempcx & 0x0300) >> 6;
7208 temp |= ((tempbx >> 8) & 0x03);
7209 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7210 temp |= 0x10;
7211 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp |= 0x20;
7212 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp |= 0x40;
7213 }
7214 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4D,temp);
7215
7216 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7217 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,(temp - 3));
7218
7219 SiS_SetTVSpecial(SiS_Pr, ModeNo);
7220
7221 if(SiS_Pr->SiS_VBType & VB_SIS301C) {
7222 temp = 0;
7223 if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
7224 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xf7,temp);
7225 }
7226
7227 }
7228
7229 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7230 if(!(SiS_Pr->SiS_TVMode & TVSetNTSC1024)) {
7231 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
7232 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,(temp - 1));
7233 }
7234 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF);
7235 }
7236
7237 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7238 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
7239 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,0x00);
7240 }
7241 }
7242
7243 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) return;
7244
7245 /* From here: Part2 LCD setup */
7246
7247 tempbx = SiS_Pr->SiS_HDE;
7248 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
7249 tempbx--; /* RHACTE = HDE - 1 */
7250 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2C,tempbx);
7251 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,((tempbx >> 4) & 0xf0));
7252
7253 temp = 0x01;
7254 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7255 if(SiS_Pr->SiS_ModeType == ModeEGA) {
7256 if(SiS_Pr->SiS_VGAHDE >= 1024) {
7257 temp = 0x02;
7258 if(HwInfo->jChipType >= SIS_315H) {
7259 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7260 temp = 0x01;
7261 }
7262 }
7263 }
7264 }
7265 }
7266 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,temp);
7267
7268 tempbx = SiS_Pr->SiS_VDE - 1;
7269 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x03,tempbx);
7270 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0C,0xF8,((tempbx >> 8) & 0x07));
7271
7272 tempcx = SiS_Pr->SiS_VT - 1;
7273 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x19,tempcx);
7274 temp = (tempcx >> 3) & 0xE0;
7275 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
7276 /* Enable dithering; only do this for 32bpp mode */
7277 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
7278 temp |= 0x10;
7279 }
7280 }
7281 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1A,0x0f,temp);
7282
7283 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x09,0xF0);
7284 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x0A,0xF0);
7285
7286 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB);
7287 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF);
7288
7289#ifdef SIS315H
7290 if(SiS_GetCRT2Part2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7291 &CRT2Index, &resindex, HwInfo)) {
7292 switch(CRT2Index) {
7293 case 200: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1; break;
7294 case 206: CRT2Part2Ptr = SiS310_CRT2Part2_Asus1024x768_3; break;
7295 default: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_3; break;
7296 }
7297
7298 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
7299 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
7300 for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
7301 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7302 }
7303 for(j = 0x1c; j <= 0x1d; i++, j++ ) {
7304 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7305 }
7306 for(j = 0x1f; j <= 0x21; i++, j++ ) {
7307 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
7308 }
7309 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
7310 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
7311
7312 SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7313
7314
7315 } else {
7316#endif
7317
7318 /* Checked for 1024x768, 1280x1024, 1400x1050, 1600x1200 */
7319 /* Clevo dual-link 1024x768 */
7320 /* Compaq 1280x1024 has HT 1696 sometimes (calculation OK, if given HT is correct) */
7321 /* Acer: OK, but uses different setting for VESA timing at 640/800/1024 and 640x400 */
7322
7323 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7324 if((SiS_Pr->SiS_LCDInfo & LCDPass11) || (SiS_Pr->PanelYRes == SiS_Pr->SiS_VDE)) {
7325 tempbx = SiS_Pr->SiS_VDE - 1;
7326 tempcx = SiS_Pr->SiS_VT - 1;
7327 } else {
7328 tempbx = SiS_Pr->SiS_VDE + ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7329 tempcx = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
7330 }
7331 } else {
7332 tempbx = SiS_Pr->PanelYRes;
7333 tempcx = SiS_Pr->SiS_VT;
7334 tempax = 1;
7335 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7336 tempax = SiS_Pr->PanelYRes;
7337 /* if(SiS_Pr->SiS_VGAVDE == 525) tempax += 0x3c; */ /* 651+301C */
7338 if(SiS_Pr->PanelYRes < SiS_Pr->SiS_VDE) {
7339 tempax = tempcx = 0;
7340 } else {
7341 tempax -= SiS_Pr->SiS_VDE;
7342 }
7343 tempax >>= 1;
7344 }
7345 tempcx -= tempax; /* lcdvdes */
7346 tempbx -= tempax; /* lcdvdee */
7347 }
7348
7349 /* Non-expanding: lcdvdes = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */
7350
7351#ifdef TWDEBUG
7352 xf86DrvMsg(0, X_INFO, "lcdvdes 0x%x lcdvdee 0x%x\n", tempcx, tempbx);
7353#endif
7354
7355 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,tempcx); /* lcdvdes */
7356 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,tempbx); /* lcdvdee */
7357
7358 temp = (tempbx >> 5) & 0x38;
7359 temp |= ((tempcx >> 8) & 0x07);
7360 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
7361
7362 tempax = SiS_Pr->SiS_VDE;
7363 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7364 tempax = SiS_Pr->PanelYRes;
7365 }
7366 tempcx = (SiS_Pr->SiS_VT - tempax) >> 4;
7367 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7368 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7369 tempcx = (SiS_Pr->SiS_VT - tempax) / 10;
7370 }
7371 }
7372
7373 tempbx = ((SiS_Pr->SiS_VT + SiS_Pr->SiS_VDE) >> 1) - 1;
7374 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7375 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
7376 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { /* ? */
7377 tempax = SiS_Pr->SiS_VT - SiS_Pr->PanelYRes;
7378 if(tempax % 4) { tempax >>= 2; tempax++; }
7379 else { tempax >>= 2; }
7380 tempbx -= (tempax - 1);
7381 } else {
7382 tempbx -= 10;
7383 if(tempbx <= SiS_Pr->SiS_VDE) tempbx = SiS_Pr->SiS_VDE + 1;
7384 }
7385 }
7386 }
7387 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
7388 tempbx++;
7389 if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (crt2crtc == 6)) {
7390 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7391 tempbx = 770;
7392 tempcx = 3;
7393 }
7394 }
7395 }
7396
7397 /* non-expanding: lcdvrs = ((VT + VDE) / 2) - 10 */
7398
7399 if(SiS_Pr->UseCustomMode) {
7400 tempbx = SiS_Pr->CVSyncStart;
7401 }
7402
7403#ifdef TWDEBUG
7404 xf86DrvMsg(0, X_INFO, "lcdvrs 0x%x\n", tempbx);
7405#endif
7406
7407 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,tempbx); /* lcdvrs */
7408
7409 temp = (tempbx >> 4) & 0xF0;
7410 tempbx += (tempcx + 1);
7411 temp |= (tempbx & 0x0F);
7412
7413 if(SiS_Pr->UseCustomMode) {
7414 temp &= 0xf0;
7415 temp |= (SiS_Pr->CVSyncEnd & 0x0f);
7416 }
7417
7418#ifdef TWDEBUG
7419 xf86DrvMsg(0, X_INFO, "lcdvre[3:0] 0x%x\n", (temp & 0x0f));
7420#endif
7421
7422 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
7423
7424#ifdef SIS300
7425 SiS_Group2LCDSpecial(SiS_Pr, HwInfo, ModeNo, crt2crtc);
7426#endif
7427
7428 bridgeoffset = 7;
7429 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) bridgeoffset += 2;
7430 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV)) bridgeoffset++;
7431 if(SiS_IsDualLink(SiS_Pr, HwInfo)) bridgeoffset++;
7432
7433 temp = 0;
7434 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7435 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7436 temp = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7437 if(SiS_IsDualLink(SiS_Pr, HwInfo)) temp >>= 1;
7438 }
7439 }
7440 temp += bridgeoffset;
7441 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1F,temp); /* lcdhdes */
7442 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0F,((temp >> 4) & 0xf0));
7443
7444 tempcx = SiS_Pr->SiS_HT;
7445 tempax = tempbx = SiS_Pr->SiS_HDE;
7446 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7447 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7448 tempax = SiS_Pr->PanelXRes;
7449 tempbx = SiS_Pr->PanelXRes - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7450 }
7451 }
7452 if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
7453 tempcx >>= 1;
7454 tempbx >>= 1;
7455 tempax >>= 1;
7456 }
7457
7458#ifdef TWDEBUG
7459 xf86DrvMsg(0, X_INFO, "lcdhdee 0x%x\n", tempbx);
7460#endif
7461
7462 tempbx += bridgeoffset;
7463
7464 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,tempbx); /* lcdhdee */
7465 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0xF0,((tempbx >> 8) & 0x0f));
7466
7467 tempcx = (tempcx - tempax) >> 2;
7468
7469 tempbx += tempcx;
7470 push2 = tempbx;
7471
7472 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
7473 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
7474 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
7475 if(SiS_Pr->SiS_HDE == 1280) tempbx = (tempbx & 0xff00) | 0x47;
7476 }
7477 }
7478 }
7479
7480 if(SiS_Pr->UseCustomMode) {
7481 tempbx = SiS_Pr->CHSyncStart;
7482 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
7483 tempbx += bridgeoffset;
7484 }
7485
7486#ifdef TWDEBUG
7487 xf86DrvMsg(0, X_INFO, "lcdhrs 0x%x\n", tempbx);
7488#endif
7489
7490 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1C,tempbx); /* lcdhrs */
7491 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,((tempbx >> 4) & 0xf0));
7492
7493 tempbx = push2;
7494
7495 tempcx <<= 1;
7496 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7497 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) tempcx >>= 2;
7498 }
7499 tempbx += tempcx;
7500
7501 if(SiS_Pr->UseCustomMode) {
7502 tempbx = SiS_Pr->CHSyncEnd;
7503 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
7504 tempbx += bridgeoffset;
7505 }
7506
7507#ifdef TWDEBUG
7508 xf86DrvMsg(0, X_INFO, "lcdhre 0x%x\n", tempbx);
7509#endif
7510
7511 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,tempbx); /* lcdhre */
7512
7513 SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7514
7515#ifdef SIS300
7516 SiS_Set300Part2Regs(SiS_Pr, HwInfo, ModeIdIndex, RefreshRateTableIndex, ModeNo);
7517#endif
7518#ifdef SIS315H
7519 } /* CRT2-LCD from table */
7520#endif
7521}
7522
7523/*********************************************/
7524/* SET PART 3 REGISTER GROUP */
7525/*********************************************/
7526
7527static void
7528SiS_SetGroup3(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7529 PSIS_HW_INFO HwInfo)
7530{
7531 USHORT i;
7532 const UCHAR *tempdi;
7533
7534 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
7535
7536#ifndef SIS_CP
7537 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x00,0x00);
7538#else
7539 SIS_CP_INIT301_CP
7540#endif
7541
7542 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7543 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7544 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7545 } else {
7546 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xF5);
7547 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xB7);
7548 }
7549
7550 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
7551 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
7552 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
7553 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x3D,0xA8);
7554 }
7555
7556 tempdi = NULL;
7557 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7558 tempdi = SiS_Pr->SiS_HiTVGroup3Data;
7559 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
7560 tempdi = SiS_Pr->SiS_HiTVGroup3Simu;
7561 }
7562 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7563 if(!(SiS_Pr->SiS_TVMode & TVSetYPbPr525i)) {
7564 tempdi = SiS_HiTVGroup3_1;
7565 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempdi = SiS_HiTVGroup3_2;
7566 }
7567 }
7568 if(tempdi) {
7569 for(i=0; i<=0x3E; i++) {
7570 SiS_SetReg(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
7571 }
7572 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV)) {
7573 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
7574 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x28,0x3f);
7575 }
7576 }
7577 }
7578
7579#ifdef SIS_CP
7580 SIS_CP_INIT301_CP2
7581#endif
7582}
7583
7584/*********************************************/
7585/* SET PART 4 REGISTER GROUP */
7586/*********************************************/
7587
7588#ifdef SIS315H
7589static void
7590SiS_ShiftXPos(SiS_Private *SiS_Pr, int shift)
7591{
7592 USHORT temp, temp1, temp2;
7593
7594 temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x1f);
7595 temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x20);
7596 temp = (USHORT)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7597 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,temp);
7598 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0f,((temp >> 4) & 0xf0));
7599 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x2b) & 0x0f;
7600 temp = (USHORT)((int)(temp) + shift);
7601 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2b,0xf0,(temp & 0x0f));
7602 temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7603 temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x42);
7604 temp = (USHORT)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7605 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,temp);
7606 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x42,0x0f,((temp >> 4) & 0xf0));
7607}
7608
7609static void
7610SiS_SetGroup4_C_ELV(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
7611 USHORT ModeNo, USHORT ModeIdIndex)
7612{
7613 USHORT temp, temp1, resinfo = 0;
7614
7615 if(!(SiS_Pr->SiS_VBType & VB_SIS301C)) return;
7616 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToHiVision | SetCRT2ToYPbPr525750))) return;
7617
7618 if(ModeNo > 0x13) {
7619 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
7620 }
7621
7622 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3a,0x08);
7623 temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x3a);
7624 if(!(temp & 0x01)) {
7625 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3a,0xdf);
7626 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xfc);
7627 if((HwInfo->jChipType < SIS_661) && (!(SiS_Pr->SiS_ROMNew))) {
7628 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xf8);
7629 }
7630 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0xfb);
7631 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp = 0x0000;
7632 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp = 0x0002;
7633 else if(SiS_Pr->SiS_TVMode & TVSetHiVision) temp = 0x0400;
7634 else temp = 0x0402;
7635 if((HwInfo->jChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
7636 temp1 = 0;
7637 if(SiS_Pr->SiS_TVMode & TVAspect43) temp1 = 4;
7638 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0f,0xfb,temp1);
7639 if(SiS_Pr->SiS_TVMode & TVAspect43LB) temp |= 0x01;
7640 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0x7c,(temp & 0xff));
7641 } else {
7642 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x3b) & 0x03;
7643 if(temp1 == 0x01) temp |= 0x01;
7644 if(temp1 == 0x03) temp |= 0x04; /* ? why not 0x10? */
7645 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xf8,(temp & 0xff));
7646 }
7647 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7648 if(ModeNo > 0x13) {
7649 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3b,0xfd);
7650 }
7651
7652 if(HwInfo->jChipType >= SIS_661) { /* ? */
7653 if(SiS_Pr->SiS_TVMode & TVAspect43) {
7654 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
7655 if(resinfo == SIS_RI_1024x768) {
7656 SiS_ShiftXPos(SiS_Pr, 97);
7657 } else {
7658 SiS_ShiftXPos(SiS_Pr, 111);
7659 }
7660 } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
7661 SiS_ShiftXPos(SiS_Pr, 136);
7662 }
7663 }
7664 }
7665 }
7666}
7667#endif
7668
7669static void
7670SiS_SetCRT2VCLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7671 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
7672{
7673 USHORT vclkindex;
7674 USHORT temp, reg1, reg2;
7675
7676 if(SiS_Pr->UseCustomMode) {
7677 reg1 = SiS_Pr->CSR2B;
7678 reg2 = SiS_Pr->CSR2C;
7679 } else {
7680 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7681 HwInfo);
7682 reg1 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
7683 reg2 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
7684 }
7685
7686 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
7687 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
7688 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x57);
7689 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,0x46);
7690 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1f,0xf6);
7691 } else {
7692 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7693 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7694 }
7695 } else {
7696 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x01);
7697 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
7698 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
7699 }
7700 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x12,0x00);
7701 temp = 0x08;
7702 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) temp |= 0x20;
7703 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,temp);
7704}
7705
7706static void
7707SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7708 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
7709{
7710 USHORT tempax,tempcx,tempbx,modeflag,temp,resinfo;
7711 ULONG tempebx,tempeax,templong;
7712
7713 if(ModeNo <= 0x13) {
7714 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7715 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
7716 } else if(SiS_Pr->UseCustomMode) {
7717 modeflag = SiS_Pr->CModeFlag;
7718 resinfo = 0;
7719 } else {
7720 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7721 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
7722 }
7723
7724 if(HwInfo->jChipType >= SIS_315H) {
7725 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
7726 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7727 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7728 }
7729 }
7730 }
7731
7732 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302LV)) {
7733 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7734 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x10,0x9f);
7735 }
7736 }
7737
7738 if(HwInfo->jChipType >= SIS_315H) {
7739 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7740 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
7741 if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
7742 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
7743 } else {
7744 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,~0x20);
7745 }
7746
7747 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
7748 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
7749#ifdef SET_EMI
7750 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
7751#endif
7752 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
7753 }
7754 }
7755 return;
7756 }
7757 }
7758
7759 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x13,SiS_Pr->SiS_RVBHCFACT);
7760
7761 tempbx = SiS_Pr->SiS_RVBHCMAX;
7762 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x14,tempbx);
7763
7764 temp = (tempbx >> 1) & 0x80;
7765
7766 tempcx = SiS_Pr->SiS_VGAHT - 1;
7767 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x16,tempcx);
7768
7769 temp |= ((tempcx >> 5) & 0x78);
7770
7771 tempcx = SiS_Pr->SiS_VGAVT - 1;
7772 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempcx -= 5;
7773 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x17,tempcx);
7774
7775 temp |= ((tempcx >> 8) & 0x07);
7776 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x15,temp);
7777
7778 tempbx = SiS_Pr->SiS_VGAHDE;
7779 if(modeflag & HalfDCLK) tempbx >>= 1;
7780 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
7781
7782 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7783 temp = 0;
7784 if(tempbx > 800) temp = 0x60;
7785 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7786 temp = 0;
7787 if(tempbx == 1024) temp = 0xA0;
7788 else if(tempbx > 1024) temp = 0xC0;
7789 } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
7790 temp = 0;
7791 if(tempbx >= 1280) temp = 0x40;
7792 else if(tempbx >= 1024) temp = 0x20;
7793 } else {
7794 temp = 0x80;
7795 if(tempbx >= 1024) temp = 0xA0;
7796 }
7797
7798 if(SiS_Pr->SiS_VBType & VB_SIS301) {
7799 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) temp |= 0x0A;
7800 }
7801
7802 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0E,0x10,temp);
7803
7804 tempeax = SiS_Pr->SiS_VGAVDE;
7805 tempebx = SiS_Pr->SiS_VDE;
7806 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7807 if(!(temp & 0xE0)) tempebx >>=1;
7808 }
7809
7810 tempcx = SiS_Pr->SiS_RVBHRS;
7811 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x18,tempcx);
7812 tempcx >>= 8;
7813 tempcx |= 0x40;
7814
7815 if(tempeax <= tempebx) {
7816 tempcx ^= 0x40;
7817 } else {
7818 tempeax -= tempebx;
7819 }
7820
7821 tempeax *= (256 * 1024);
7822 templong = tempeax % tempebx;
7823 tempeax /= tempebx;
7824 if(templong) tempeax++;
7825
7826 temp = (USHORT)(tempeax & 0x000000FF);
7827 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1B,temp);
7828 temp = (USHORT)((tempeax & 0x0000FF00) >> 8);
7829 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1A,temp);
7830 temp = (USHORT)((tempeax >> 12) & 0x70); /* sic! */
7831 temp |= (tempcx & 0x4F);
7832 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x19,temp);
7833
7834 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
7835
7836 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1C,0x28);
7837
7838 /* Calc Linebuffer max address and set/clear decimode */
7839 tempbx = 0;
7840 if(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p)) tempbx = 0x08;
7841 tempax = SiS_Pr->SiS_VGAHDE;
7842 if(modeflag & HalfDCLK) tempax >>= 1;
7843 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempax >>= 1;
7844 if(tempax > 800) {
7845 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7846 tempax -= 800;
7847 } else { /* 651+301C: Only if TVNoHiviNoYPbPr */
7848 tempbx = 0x08;
7849 if(tempax == 1024) tempax *= 25;
7850 else tempax *= 20;
7851 temp = tempax % 32;
7852 tempax /= 32;
7853 if(temp) tempax++;
7854 tempax++;
7855 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) ||
7856 (SiS_Pr->SiS_TVMode & TVSetYPbPr525i)) {
7857 if(resinfo == SIS_RI_1024x768) {
7858 /* Otherwise white line at right edge */
7859 tempax = (tempax & 0xff00) | 0x20;
7860 }
7861 }
7862 }
7863 }
7864 tempax--;
7865 temp = ((tempax >> 4) & 0x30) | tempbx;
7866 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1D,tempax);
7867 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1E,temp);
7868
7869 temp = 0x0036; tempbx = 0xD0;
7870 if((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
7871 temp = 0x0026; tempbx = 0xC0; /* See En/DisableBridge() */
7872 }
7873 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7874 if(!(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetHiVision | TVSetYPbPr750p | TVSetYPbPr525p))) {
7875 temp |= 0x01;
7876 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
7877 if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
7878 temp &= ~0x01;
7879 }
7880 }
7881 }
7882 }
7883 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,tempbx,temp);
7884
7885 tempbx = SiS_Pr->SiS_HT >> 1;
7886 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
7887 tempbx -= 2;
7888 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x22,tempbx);
7889 temp = (tempbx >> 5) & 0x38;
7890 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp);
7891
7892 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
7893 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7894 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7895 /* LCD-too-dark-error-source, see FinalizeLCD() */
7896 }
7897 if(HwInfo->jChipType >= SIS_315H) {
7898 if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
7899 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
7900 } else {
7901 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,~0x20);
7902 }
7903 }
7904 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
7905 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
7906#ifdef SET_EMI
7907 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
7908#endif
7909 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
7910 }
7911 }
7912
7913 } /* 301B */
7914
7915 SiS_SetCRT2VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
7916}
7917
7918/*********************************************/
7919/* SET PART 5 REGISTER GROUP */
7920/*********************************************/
7921
7922static void
7923SiS_SetGroup5(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7924 PSIS_HW_INFO HwInfo)
7925{
7926
7927 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
7928
7929 if(SiS_Pr->SiS_ModeType == ModeVGA) {
7930 if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))) {
7931 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
7932 SiS_LoadDAC(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
7933 }
7934 }
7935}
7936
7937/*********************************************/
7938/* MODIFY CRT1 GROUP FOR SLAVE MODE */
7939/*********************************************/
7940
7941static void
7942SiS_ModCRT1CRTC(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7943 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
7944{
7945 USHORT tempah,i,modeflag,j;
7946 USHORT ResIndex,DisplayType;
7947 const SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr=NULL;
7948
7949 if(ModeNo <= 0x13) modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7950 else modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7951
7952 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
7953 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
7954 (SiS_Pr->SiS_CustomT == CUT_PANEL848))
7955 return;
7956
7957 if(!(SiS_GetLVDSCRT1Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7958 &ResIndex, &DisplayType))) {
7959 return;
7960 }
7961
7962 if(HwInfo->jChipType < SIS_315H) {
7963 if(SiS_Pr->SiS_SetFlag & SetDOSMode) return;
7964 }
7965
7966 switch(DisplayType) {
7967 case 0 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1; break;
7968 case 1 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1_H; break;
7969 case 2 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2; break;
7970 case 3 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2_H; break;
7971 case 4 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1; break;
7972 case 5 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1_H; break;
7973 case 6 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2; break;
7974 case 7 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2_H; break;
7975 case 8 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1; break;
7976 case 9 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1_H; break;
7977 case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2; break;
7978 case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2_H; break;
7979 case 12: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1; break;
7980 case 13: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H; break;
7981 case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_1; break;
7982 case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_1_H; break;
7983 case 16: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_2; break;
7984 case 17: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_2_H; break;
7985 case 18: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC; break;
7986 case 19: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC; break;
7987 case 20: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL; break;
7988 case 21: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL; break;
7989 case 22: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x480_1; break; /* FSTN */
7990 case 23: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1; break;
7991 case 24: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1_H; break;
7992 case 25: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2; break;
7993 case 26: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2_H; break;
7994 case 27: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_1; break;
7995 case 28: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_1_H; break;
7996 case 29: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_2; break;
7997 case 30: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_2_H; break;
7998 case 36: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_1; break;
7999 case 37: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_1_H; break;
8000 case 38: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_2; break;
8001 case 39: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_2_H; break;
8002 case 40: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_1; break;
8003 case 41: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_1_H; break;
8004 case 42: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_2; break;
8005 case 43: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_2_H; break;
8006 case 50: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1; break;
8007 case 51: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1_H; break;
8008 case 52: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_2; break;
8009 case 53: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_2_H; break;
8010 case 54: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_3; break;
8011 case 55: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_3_H; break;
8012 case 99: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1SOPAL; break;
8013 default: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1; break;
8014 }
8015
8016 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
8017
8018 tempah = (LVDSCRT1Ptr + ResIndex)->CR[0];
8019 SiS_SetReg(SiS_Pr->SiS_P3d4,0x00,tempah);
8020
8021 for(i=0x02,j=1;i<=0x05;i++,j++){
8022 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
8023 SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
8024 }
8025 for(i=0x06,j=5;i<=0x07;i++,j++){
8026 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
8027 SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
8028 }
8029 for(i=0x10,j=7;i<=0x11;i++,j++){
8030 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
8031 SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
8032 }
8033 for(i=0x15,j=9;i<=0x16;i++,j++){
8034 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
8035 SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
8036 }
8037 for(i=0x0A,j=11;i<=0x0C;i++,j++){
8038 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
8039 SiS_SetReg(SiS_Pr->SiS_P3c4,i,tempah);
8040 }
8041
8042 tempah = (LVDSCRT1Ptr + ResIndex)->CR[14];
8043 tempah &= 0xE0;
8044 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);
8045
8046 tempah = (LVDSCRT1Ptr + ResIndex)->CR[14];
8047 tempah &= 0x01;
8048 tempah <<= 5;
8049 if(modeflag & DoubleScanMode) tempah |= 0x080;
8050 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
8051}
8052
8053/*********************************************/
8054/* SET CRT2 ECLK */
8055/*********************************************/
8056
8057static void
8058SiS_SetCRT2ECLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
8059 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
8060{
8061 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
8062 USHORT clkbase, vclkindex=0;
8063 UCHAR sr2b, sr2c;
8064
8065 if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) || (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
8066 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
8067 if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK & 0x3f) == 2) {
8068 RefreshRateTableIndex--;
8069 }
8070 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
8071 RefreshRateTableIndex, HwInfo);
8072 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
8073 } else {
8074 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
8075 RefreshRateTableIndex, HwInfo);
8076 }
8077
8078 sr2b = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
8079 sr2c = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
8080
8081 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
8082 if(SiS_Pr->SiS_UseROM) {
8083 if(ROMAddr[0x220] & 0x01) {
8084 sr2b = ROMAddr[0x227];
8085 sr2c = ROMAddr[0x228];
8086 }
8087 }
8088 }
8089
8090 clkbase = 0x02B;
8091 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
8092 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
8093 clkbase += 3;
8094 }
8095 }
8096
8097 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x20);
8098 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
8099 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
8100 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x10);
8101 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
8102 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
8103 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x00);
8104 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
8105 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
8106}
8107
8108/*********************************************/
8109/* SET UP CHRONTEL CHIPS */
8110/*********************************************/
8111
8112static void
8113SiS_SetCHTVReg(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
8114 USHORT RefreshRateTableIndex)
8115{
8116#if defined(SIS300) || defined(SIS315H)
8117 USHORT temp, tempbx;
8118#endif
8119 USHORT tempcl;
8120 USHORT TVType, resindex;
8121 const SiS_CHTVRegDataStruct *CHTVRegData = NULL;
8122
8123 if(ModeNo <= 0x13)
8124 tempcl = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
8125 else
8126 tempcl = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
8127
8128 TVType = 0;
8129 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
8130 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
8131 TVType += 2;
8132 if(SiS_Pr->SiS_ModeType > ModeVGA) {
8133 if(SiS_Pr->SiS_CHSOverScan) TVType = 8;
8134 }
8135 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
8136 TVType = 4;
8137 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
8138 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
8139 TVType = 6;
8140 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
8141 }
8142 }
8143 switch(TVType) {
8144 case 0: CHTVRegData = SiS_Pr->SiS_CHTVReg_UNTSC; break;
8145 case 1: CHTVRegData = SiS_Pr->SiS_CHTVReg_ONTSC; break;
8146 case 2: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPAL; break;
8147 case 3: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break;
8148 case 4: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALM; break;
8149 case 5: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALM; break;
8150 case 6: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALN; break;
8151 case 7: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALN; break;
8152 case 8: CHTVRegData = SiS_Pr->SiS_CHTVReg_SOPAL; break;
8153 default: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break;
8154 }
8155 resindex = tempcl & 0x3F;
8156
8157 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
8158
8159#ifdef SIS300
8160
8161 /* Chrontel 7005 - I assume that it does not come with a 315 series chip */
8162
8163 /* We don't support modes >800x600 */
8164 if (resindex > 5) return;
8165
8166 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
8167 SiS_SetCH700x(SiS_Pr,0x4304); /* 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
8168 SiS_SetCH700x(SiS_Pr,0x6909); /* Black level for PAL (105)*/
8169 } else {
8170 SiS_SetCH700x(SiS_Pr,0x0304); /* upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
8171 SiS_SetCH700x(SiS_Pr,0x7109); /* Black level for NTSC (113)*/
8172 }
8173
8174 temp = CHTVRegData[resindex].Reg[0];
8175 tempbx=((temp&0x00FF)<<8)|0x00; /* Mode register */
8176 SiS_SetCH700x(SiS_Pr,tempbx);
8177 temp = CHTVRegData[resindex].Reg[1];
8178 tempbx=((temp&0x00FF)<<8)|0x07; /* Start active video register */
8179 SiS_SetCH700x(SiS_Pr,tempbx);
8180 temp = CHTVRegData[resindex].Reg[2];
8181 tempbx=((temp&0x00FF)<<8)|0x08; /* Position overflow register */
8182 SiS_SetCH700x(SiS_Pr,tempbx);
8183 temp = CHTVRegData[resindex].Reg[3];
8184 tempbx=((temp&0x00FF)<<8)|0x0A; /* Horiz Position register */
8185 SiS_SetCH700x(SiS_Pr,tempbx);
8186 temp = CHTVRegData[resindex].Reg[4];
8187 tempbx=((temp&0x00FF)<<8)|0x0B; /* Vertical Position register */
8188 SiS_SetCH700x(SiS_Pr,tempbx);
8189
8190 /* Set minimum flicker filter for Luma channel (SR1-0=00),
8191 minimum text enhancement (S3-2=10),
8192 maximum flicker filter for Chroma channel (S5-4=10)
8193 =00101000=0x28 (When reading, S1-0->S3-2, and S3-2->S1-0!)
8194 */
8195 SiS_SetCH700x(SiS_Pr,0x2801);
8196
8197 /* Set video bandwidth
8198 High bandwith Luma composite video filter(S0=1)
8199 low bandwith Luma S-video filter (S2-1=00)
8200 disable peak filter in S-video channel (S3=0)
8201 high bandwidth Chroma Filter (S5-4=11)
8202 =00110001=0x31
8203 */
8204 SiS_SetCH700x(SiS_Pr,0xb103); /* old: 3103 */
8205
8206 /* Register 0x3D does not exist in non-macrovision register map
8207 (Maybe this is a macrovision register?)
8208 */
8209#ifndef SIS_CP
8210 SiS_SetCH70xx(SiS_Pr,0x003D);
8211#endif
8212
8213 /* Register 0x10 only contains 1 writable bit (S0) for sensing,
8214 all other bits a read-only. Macrovision?
8215 */
8216 SiS_SetCH70xxANDOR(SiS_Pr,0x0010,0x1F);
8217
8218 /* Register 0x11 only contains 3 writable bits (S0-S2) for
8219 contrast enhancement (set to 010 -> gain 1 Yout = 17/16*(Yin-30) )
8220 */
8221 SiS_SetCH70xxANDOR(SiS_Pr,0x0211,0xF8);
8222
8223 /* Clear DSEN
8224 */
8225 SiS_SetCH70xxANDOR(SiS_Pr,0x001C,0xEF);
8226
8227 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) { /* ---- NTSC ---- */
8228 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) {
8229 if(resindex == 0x04) { /* 640x480 overscan: Mode 16 */
8230 SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off */
8231 SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE); /* ACIV on, no need to set FSCI */
8232 } else if(resindex == 0x05) { /* 800x600 overscan: Mode 23 */
8233 SiS_SetCH70xxANDOR(SiS_Pr,0x0118,0xF0); /* 0x18-0x1f: FSCI 469,762,048 */
8234 SiS_SetCH70xxANDOR(SiS_Pr,0x0C19,0xF0);
8235 SiS_SetCH70xxANDOR(SiS_Pr,0x001A,0xF0);
8236 SiS_SetCH70xxANDOR(SiS_Pr,0x001B,0xF0);
8237 SiS_SetCH70xxANDOR(SiS_Pr,0x001C,0xF0);
8238 SiS_SetCH70xxANDOR(SiS_Pr,0x001D,0xF0);
8239 SiS_SetCH70xxANDOR(SiS_Pr,0x001E,0xF0);
8240 SiS_SetCH70xxANDOR(SiS_Pr,0x001F,0xF0);
8241 SiS_SetCH70xxANDOR(SiS_Pr,0x0120,0xEF); /* Loop filter on for mode 23 */
8242 SiS_SetCH70xxANDOR(SiS_Pr,0x0021,0xFE); /* ACIV off, need to set FSCI */
8243 }
8244 } else {
8245 if(resindex == 0x04) { /* ----- 640x480 underscan; Mode 17 */
8246 SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off */
8247 SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);
8248 } else if(resindex == 0x05) { /* ----- 800x600 underscan: Mode 24 */
8249#if 0
8250 SiS_SetCH70xxANDOR(SiS_Pr,0x0118,0xF0); /* (FSCI was 0x1f1c71c7 - this is for mode 22) */
8251 SiS_SetCH70xxANDOR(SiS_Pr,0x0919,0xF0); /* FSCI for mode 24 is 428,554,851 */
8252 SiS_SetCH70xxANDOR(SiS_Pr,0x081A,0xF0); /* 198b3a63 */
8253 SiS_SetCH70xxANDOR(SiS_Pr,0x0b1B,0xF0);
8254 SiS_SetCH70xxANDOR(SiS_Pr,0x041C,0xF0);
8255 SiS_SetCH70xxANDOR(SiS_Pr,0x011D,0xF0);
8256 SiS_SetCH70xxANDOR(SiS_Pr,0x061E,0xF0);
8257 SiS_SetCH70xxANDOR(SiS_Pr,0x051F,0xF0);
8258 SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off for mode 24 */
8259 SiS_SetCH70xxANDOR(SiS_Pr,0x0021,0xFE); /* ACIV off, need to set FSCI */
8260#endif /* All alternatives wrong (datasheet wrong?), don't use FSCI */
8261 SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off */
8262 SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);
8263 }
8264 }
8265 } else { /* ---- PAL ---- */
8266 /* We don't play around with FSCI in PAL mode */
8267 if(resindex == 0x04) {
8268 SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off */
8269 SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE); /* ACIV on */
8270 } else {
8271 SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off */
8272 SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE); /* ACIV on */
8273 }
8274 }
8275
8276#endif /* 300 */
8277
8278 } else {
8279
8280 /* Chrontel 7019 - assumed that it does not come with a 300 series chip */
8281
8282#ifdef SIS315H
8283
8284 /* We don't support modes >1024x768 */
8285 if (resindex > 6) return;
8286
8287 temp = CHTVRegData[resindex].Reg[0];
8288 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
8289 temp |= 0x10;
8290 }
8291 tempbx=((temp & 0x00FF) << 8) | 0x00;
8292 SiS_SetCH701x(SiS_Pr,tempbx);
8293
8294 temp = CHTVRegData[resindex].Reg[1];
8295 tempbx=((temp & 0x00FF) << 8) | 0x01;
8296 SiS_SetCH701x(SiS_Pr,tempbx);
8297
8298 temp = CHTVRegData[resindex].Reg[2];
8299 tempbx=((temp & 0x00FF) << 8) | 0x02;
8300 SiS_SetCH701x(SiS_Pr,tempbx);
8301
8302 temp = CHTVRegData[resindex].Reg[3];
8303 tempbx=((temp & 0x00FF) << 8) | 0x04;
8304 SiS_SetCH701x(SiS_Pr,tempbx);
8305
8306 temp = CHTVRegData[resindex].Reg[4];
8307 tempbx=((temp & 0x00FF) << 8) | 0x03;
8308 SiS_SetCH701x(SiS_Pr,tempbx);
8309
8310 temp = CHTVRegData[resindex].Reg[5];
8311 tempbx=((temp & 0x00FF) << 8) | 0x05;
8312 SiS_SetCH701x(SiS_Pr,tempbx);
8313
8314 temp = CHTVRegData[resindex].Reg[6];
8315 tempbx=((temp & 0x00FF) << 8) | 0x06;
8316 SiS_SetCH701x(SiS_Pr,tempbx);
8317
8318 temp = CHTVRegData[resindex].Reg[7];
8319 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
8320 temp = 0x66;
8321 }
8322 tempbx=((temp & 0x00FF) << 8) | 0x07;
8323 SiS_SetCH701x(SiS_Pr,tempbx);
8324
8325 temp = CHTVRegData[resindex].Reg[8];
8326 tempbx=((temp & 0x00FF) << 8) | 0x08;
8327 SiS_SetCH701x(SiS_Pr,tempbx);
8328
8329 temp = CHTVRegData[resindex].Reg[9];
8330 tempbx=((temp & 0x00FF) << 8) | 0x15;
8331 SiS_SetCH701x(SiS_Pr,tempbx);
8332
8333 temp = CHTVRegData[resindex].Reg[10];
8334 tempbx=((temp & 0x00FF) << 8) | 0x1f;
8335 SiS_SetCH701x(SiS_Pr,tempbx);
8336
8337 temp = CHTVRegData[resindex].Reg[11];
8338 tempbx=((temp & 0x00FF) << 8) | 0x0c;
8339 SiS_SetCH701x(SiS_Pr,tempbx);
8340
8341 temp = CHTVRegData[resindex].Reg[12];
8342 tempbx=((temp & 0x00FF) << 8) | 0x0d;
8343 SiS_SetCH701x(SiS_Pr,tempbx);
8344
8345 temp = CHTVRegData[resindex].Reg[13];
8346 tempbx=((temp & 0x00FF) << 8) | 0x0e;
8347 SiS_SetCH701x(SiS_Pr,tempbx);
8348
8349 temp = CHTVRegData[resindex].Reg[14];
8350 tempbx=((temp & 0x00FF) << 8) | 0x0f;
8351 SiS_SetCH701x(SiS_Pr,tempbx);
8352
8353 temp = CHTVRegData[resindex].Reg[15];
8354 tempbx=((temp & 0x00FF) << 8) | 0x10;
8355 SiS_SetCH701x(SiS_Pr,tempbx);
8356
8357 temp = SiS_GetCH701x(SiS_Pr,0x21) & ~0x02;
8358 /* D1 should be set for PAL, PAL-N and NTSC-J,
8359 but I won't do that for PAL unless somebody
8360 tells me to do so. Since the BIOS uses
8361 non-default CIV values and blacklevels,
8362 this might be compensated anyway.
8363 */
8364 if(SiS_Pr->SiS_TVMode & (TVSetPALN | TVSetNTSCJ)) temp |= 0x02;
8365 SiS_SetCH701x(SiS_Pr,((temp << 8) | 0x21));
8366
8367#endif /* 315 */
8368
8369 }
8370
8371#ifdef SIS_CP
8372 SIS_CP_INIT301_CP3
8373#endif
8374
8375}
8376
8377void
8378SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8379{
8380 USHORT temp;
8381
8382 /* Enable Chrontel 7019 LCD panel backlight */
8383 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8384 if(HwInfo->jChipType == SIS_740) {
8385 SiS_SetCH701x(SiS_Pr,0x6566);
8386 } else {
8387 temp = SiS_GetCH701x(SiS_Pr,0x66);
8388 temp |= 0x20;
8389 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
8390 }
8391 }
8392}
8393
8394void
8395SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr)
8396{
8397 USHORT temp;
8398
8399 /* Disable Chrontel 7019 LCD panel backlight */
8400 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8401 temp = SiS_GetCH701x(SiS_Pr,0x66);
8402 temp &= 0xDF;
8403 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
8404 }
8405}
8406
8407#ifdef SIS315H /* ----------- 315 series only ---------- */
8408
8409static void
8410SiS_ChrontelPowerSequencing(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8411{
8412 UCHAR regtable[] = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
8413 UCHAR table1024_740[] = { 0x01, 0x02, 0x01, 0x01, 0x01 };
8414 UCHAR table1400_740[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 };
8415 UCHAR asus1024_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8416 UCHAR asus1400_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8417 UCHAR table1024_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8418 UCHAR table1400_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8419 UCHAR *tableptr = NULL;
8420 int i;
8421
8422 /* Set up Power up/down timing */
8423
8424 if(HwInfo->jChipType == SIS_740) {
8425 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8426 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1024_740;
8427 else tableptr = table1024_740;
8428 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8429 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8430 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8431 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1400_740;
8432 else tableptr = table1400_740;
8433 } else return;
8434 } else {
8435 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8436 tableptr = table1024_650;
8437 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8438 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8439 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8440 tableptr = table1400_650;
8441 } else return;
8442 }
8443
8444 for(i=0; i<5; i++) {
8445 SiS_SetCH701x(SiS_Pr,(tableptr[i] << 8) | regtable[i]);
8446 }
8447}
8448
8449static void
8450SiS_SetCH701xForLCD(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8451{
8452 UCHAR regtable[] = { 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
8453 0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66 };
8454 UCHAR table1024_740[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8455 0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44 };
8456 UCHAR table1280_740[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8457 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 };
8458 UCHAR table1400_740[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8459 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 };
8460 UCHAR table1600_740[] = { 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8461 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44 };
8462 UCHAR table1024_650[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8463 0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02 };
8464 UCHAR table1280_650[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8465 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02 };
8466 UCHAR table1400_650[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xef,
8467 0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02 };
8468 UCHAR table1600_650[] = { 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8469 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a };
8470 UCHAR *tableptr = NULL;
8471 USHORT tempbh;
8472 int i;
8473
8474 if(HwInfo->jChipType == SIS_740) {
8475 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tableptr = table1024_740;
8476 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_740;
8477 else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_740;
8478 else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_740;
8479 else return;
8480 } else {
8481 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tableptr = table1024_650;
8482 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_650;
8483 else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_650;
8484 else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_650;
8485 else return;
8486 }
8487
8488 tempbh = SiS_GetCH701x(SiS_Pr,0x74);
8489 if((tempbh == 0xf6) || (tempbh == 0xc7)) {
8490 tempbh = SiS_GetCH701x(SiS_Pr,0x73);
8491 if(tempbh == 0xc8) {
8492 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) return;
8493 } else if(tempbh == 0xdb) {
8494 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) return;
8495 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) return;
8496 } else if(tempbh == 0xde) {
8497 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) return;
8498 }
8499 }
8500
8501 if(HwInfo->jChipType == SIS_740) tempbh = 0x0d;
8502 else tempbh = 0x0c;
8503
8504 for(i = 0; i < tempbh; i++) {
8505 SiS_SetCH701x(SiS_Pr,(tableptr[i] << 8) | regtable[i]);
8506 }
8507 SiS_ChrontelPowerSequencing(SiS_Pr,HwInfo);
8508 tempbh = SiS_GetCH701x(SiS_Pr,0x1e);
8509 tempbh |= 0xc0;
8510 SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x1e);
8511
8512 if(HwInfo->jChipType == SIS_740) {
8513 tempbh = SiS_GetCH701x(SiS_Pr,0x1c);
8514 tempbh &= 0xfb;
8515 SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x1c);
8516 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8517 tempbh = SiS_GetCH701x(SiS_Pr,0x64);
8518 tempbh |= 0x40;
8519 SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x64);
8520 tempbh = SiS_GetCH701x(SiS_Pr,0x03);
8521 tempbh &= 0x3f;
8522 SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x03);
8523 }
8524}
8525
8526static void
8527SiS_ChrontelResetVSync(SiS_Private *SiS_Pr)
8528{
8529 unsigned char temp, temp1;
8530
8531 temp1 = SiS_GetCH701x(SiS_Pr,0x49);
8532 SiS_SetCH701x(SiS_Pr,0x3e49);
8533 temp = SiS_GetCH701x(SiS_Pr,0x47);
8534 temp &= 0x7f; /* Use external VSYNC */
8535 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
8536 SiS_LongDelay(SiS_Pr,3);
8537 temp = SiS_GetCH701x(SiS_Pr,0x47);
8538 temp |= 0x80; /* Use internal VSYNC */
8539 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
8540 SiS_SetCH701x(SiS_Pr,(temp1 << 8) | 0x49);
8541}
8542
8543static void
8544SiS_Chrontel701xOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8545{
8546 USHORT temp;
8547
8548 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8549 if(HwInfo->jChipType == SIS_740) {
8550 temp = SiS_GetCH701x(SiS_Pr,0x1c);
8551 temp |= 0x04; /* Invert XCLK phase */
8552 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c);
8553 }
8554 if(SiS_IsYPbPr(SiS_Pr, HwInfo)) {
8555 temp = SiS_GetCH701x(SiS_Pr,0x01);
8556 temp &= 0x3f;
8557 temp |= 0x80; /* Enable YPrPb (HDTV) */
8558 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x01);
8559 }
8560 if(SiS_IsChScart(SiS_Pr, HwInfo)) {
8561 temp = SiS_GetCH701x(SiS_Pr,0x01);
8562 temp &= 0x3f;
8563 temp |= 0xc0; /* Enable SCART + CVBS */
8564 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x01);
8565 }
8566 if(HwInfo->jChipType == SIS_740) {
8567 SiS_ChrontelResetVSync(SiS_Pr);
8568 SiS_SetCH701x(SiS_Pr,0x2049); /* Enable TV path */
8569 } else {
8570 SiS_SetCH701x(SiS_Pr,0x2049); /* Enable TV path */
8571 temp = SiS_GetCH701x(SiS_Pr,0x49);
8572 if(SiS_IsYPbPr(SiS_Pr,HwInfo)) {
8573 temp = SiS_GetCH701x(SiS_Pr,0x73);
8574 temp |= 0x60;
8575 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x73);
8576 }
8577 temp = SiS_GetCH701x(SiS_Pr,0x47);
8578 temp &= 0x7f;
8579 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
8580 SiS_LongDelay(SiS_Pr,2);
8581 temp = SiS_GetCH701x(SiS_Pr,0x47);
8582 temp |= 0x80;
8583 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
8584 }
8585 }
8586}
8587
8588static void
8589SiS_Chrontel701xOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8590{
8591 USHORT temp;
8592
8593 /* Complete power down of LVDS */
8594 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8595 if(HwInfo->jChipType == SIS_740) {
8596 SiS_LongDelay(SiS_Pr,1);
8597 SiS_GenericDelay(SiS_Pr,0x16ff);
8598 SiS_SetCH701x(SiS_Pr,0xac76);
8599 SiS_SetCH701x(SiS_Pr,0x0066);
8600 } else {
8601 SiS_LongDelay(SiS_Pr,2);
8602 temp = SiS_GetCH701x(SiS_Pr,0x76);
8603 temp &= 0xfc;
8604 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
8605 SiS_SetCH701x(SiS_Pr,0x0066);
8606 }
8607 }
8608}
8609
8610static void
8611SiS_ChrontelResetDB(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8612{
8613 USHORT temp;
8614
8615 if(HwInfo->jChipType == SIS_740) {
8616
8617 temp = SiS_GetCH701x(SiS_Pr,0x4a); /* Version ID */
8618 temp &= 0x01;
8619 if(!temp) {
8620
8621 if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo)) {
8622 temp = SiS_GetCH701x(SiS_Pr,0x49);
8623 SiS_SetCH701x(SiS_Pr,0x3e49);
8624 }
8625 /* Reset Chrontel 7019 datapath */
8626 SiS_SetCH701x(SiS_Pr,0x1048);
8627 SiS_LongDelay(SiS_Pr,1);
8628 SiS_SetCH701x(SiS_Pr,0x1848);
8629
8630 if(SiS_WeHaveBacklightCtrl(SiS_Pr, HwInfo)) {
8631 SiS_ChrontelResetVSync(SiS_Pr);
8632 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x49);
8633 }
8634
8635 } else {
8636
8637 /* Clear/set/clear GPIO */
8638 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8639 temp &= 0xef;
8640 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
8641 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8642 temp |= 0x10;
8643 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
8644 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8645 temp &= 0xef;
8646 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
8647 temp = SiS_GetCH701x(SiS_Pr,0x61);
8648 if(!temp) {
8649 SiS_SetCH701xForLCD(SiS_Pr, HwInfo);
8650 }
8651 }
8652
8653 } else { /* 650 */
8654 /* Reset Chrontel 7019 datapath */
8655 SiS_SetCH701x(SiS_Pr,0x1048);
8656 SiS_LongDelay(SiS_Pr,1);
8657 SiS_SetCH701x(SiS_Pr,0x1848);
8658 }
8659}
8660
8661static void
8662SiS_ChrontelInitTVVSync(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8663{
8664 USHORT temp;
8665
8666 if(HwInfo->jChipType == SIS_740) {
8667
8668 if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo)) {
8669 SiS_ChrontelResetVSync(SiS_Pr);
8670 }
8671
8672 } else {
8673
8674 SiS_SetCH701x(SiS_Pr,0xaf76); /* Power up LVDS block */
8675 temp = SiS_GetCH701x(SiS_Pr,0x49);
8676 temp &= 1;
8677 if(temp != 1) { /* TV block powered? (0 = yes, 1 = no) */
8678 temp = SiS_GetCH701x(SiS_Pr,0x47);
8679 temp &= 0x70;
8680 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47); /* enable VSYNC */
8681 SiS_LongDelay(SiS_Pr,3);
8682 temp = SiS_GetCH701x(SiS_Pr,0x47);
8683 temp |= 0x80;
8684 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47); /* disable VSYNC */
8685 }
8686
8687 }
8688}
8689
8690static void
8691SiS_ChrontelDoSomething3(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_INFO HwInfo)
8692{
8693 USHORT temp,temp1;
8694
8695 if(HwInfo->jChipType == SIS_740) {
8696
8697 temp = SiS_GetCH701x(SiS_Pr,0x61);
8698 if(temp < 1) {
8699 temp++;
8700 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61);
8701 }
8702 SiS_SetCH701x(SiS_Pr,0x4566); /* Panel power on */
8703 SiS_SetCH701x(SiS_Pr,0xaf76); /* All power on */
8704 SiS_LongDelay(SiS_Pr,1);
8705 SiS_GenericDelay(SiS_Pr,0x16ff);
8706
8707 } else { /* 650 */
8708
8709 temp1 = 0;
8710 temp = SiS_GetCH701x(SiS_Pr,0x61);
8711 if(temp < 2) {
8712 temp++;
8713 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61);
8714 temp1 = 1;
8715 }
8716 SiS_SetCH701x(SiS_Pr,0xac76);
8717 temp = SiS_GetCH701x(SiS_Pr,0x66);
8718 temp |= 0x5f;
8719 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
8720 if(ModeNo > 0x13) {
8721 if(SiS_WeHaveBacklightCtrl(SiS_Pr, HwInfo)) {
8722 SiS_GenericDelay(SiS_Pr,0x3ff);
8723 } else {
8724 SiS_GenericDelay(SiS_Pr,0x2ff);
8725 }
8726 } else {
8727 if(!temp1)
8728 SiS_GenericDelay(SiS_Pr,0x2ff);
8729 }
8730 temp = SiS_GetCH701x(SiS_Pr,0x76);
8731 temp |= 0x03;
8732 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
8733 temp = SiS_GetCH701x(SiS_Pr,0x66);
8734 temp &= 0x7f;
8735 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
8736 SiS_LongDelay(SiS_Pr,1);
8737
8738 }
8739}
8740
8741static void
8742SiS_ChrontelDoSomething2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8743{
8744 USHORT temp,tempcl,tempch;
8745
8746 SiS_LongDelay(SiS_Pr, 1);
8747 tempcl = 3;
8748 tempch = 0;
8749
8750 do {
8751 temp = SiS_GetCH701x(SiS_Pr,0x66);
8752 temp &= 0x04; /* PLL stable? -> bail out */
8753 if(temp == 0x04) break;
8754
8755 if(HwInfo->jChipType == SIS_740) {
8756 /* Power down LVDS output, PLL normal operation */
8757 SiS_SetCH701x(SiS_Pr,0xac76);
8758 }
8759
8760 SiS_SetCH701xForLCD(SiS_Pr,HwInfo);
8761
8762 if(tempcl == 0) {
8763 if(tempch == 3) break;
8764 SiS_ChrontelResetDB(SiS_Pr,HwInfo);
8765 tempcl = 3;
8766 tempch++;
8767 }
8768 tempcl--;
8769 temp = SiS_GetCH701x(SiS_Pr,0x76);
8770 temp &= 0xfb; /* Reset PLL */
8771 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
8772 SiS_LongDelay(SiS_Pr,2);
8773 temp = SiS_GetCH701x(SiS_Pr,0x76);
8774 temp |= 0x04; /* PLL normal operation */
8775 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
8776 if(HwInfo->jChipType == SIS_740) {
8777 SiS_SetCH701x(SiS_Pr,0xe078); /* PLL loop filter */
8778 } else {
8779 SiS_SetCH701x(SiS_Pr,0x6078);
8780 }
8781 SiS_LongDelay(SiS_Pr,2);
8782 } while(0);
8783
8784 SiS_SetCH701x(SiS_Pr,0x0077); /* MV? */
8785}
8786
8787static void
8788SiS_ChrontelDoSomething1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8789{
8790 USHORT temp;
8791
8792 temp = SiS_GetCH701x(SiS_Pr,0x03);
8793 temp |= 0x80; /* Set datapath 1 to TV */
8794 temp &= 0xbf; /* Set datapath 2 to LVDS */
8795 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x03);
8796
8797 if(HwInfo->jChipType == SIS_740) {
8798
8799 temp = SiS_GetCH701x(SiS_Pr,0x1c);
8800 temp &= 0xfb; /* Normal XCLK phase */
8801 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c);
8802
8803 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8804
8805 temp = SiS_GetCH701x(SiS_Pr,0x64);
8806 temp |= 0x40; /* ? Bit not defined */
8807 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x64);
8808
8809 temp = SiS_GetCH701x(SiS_Pr,0x03);
8810 temp &= 0x3f; /* D1 input to both LVDS and TV */
8811 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x03);
8812
8813 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) {
8814 SiS_SetCH701x(SiS_Pr,0x4063); /* LVDS off */
8815 SiS_LongDelay(SiS_Pr, 1);
8816 SiS_SetCH701x(SiS_Pr,0x0063); /* LVDS on */
8817 SiS_ChrontelResetDB(SiS_Pr, HwInfo);
8818 SiS_ChrontelDoSomething2(SiS_Pr, HwInfo);
8819 SiS_ChrontelDoSomething3(SiS_Pr, 0, HwInfo);
8820 } else {
8821 temp = SiS_GetCH701x(SiS_Pr,0x66);
8822 if(temp != 0x45) {
8823 SiS_ChrontelResetDB(SiS_Pr, HwInfo);
8824 SiS_ChrontelDoSomething2(SiS_Pr, HwInfo);
8825 SiS_ChrontelDoSomething3(SiS_Pr, 0, HwInfo);
8826 }
8827 }
8828
8829 } else { /* 650 */
8830
8831 SiS_ChrontelResetDB(SiS_Pr,HwInfo);
8832 SiS_ChrontelDoSomething2(SiS_Pr,HwInfo);
8833 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34);
8834 SiS_ChrontelDoSomething3(SiS_Pr,temp,HwInfo);
8835 SiS_SetCH701x(SiS_Pr,0xaf76); /* All power on, LVDS normal operation */
8836
8837 }
8838
8839}
8840#endif /* 315 series */
8841
8842/*********************************************/
8843/* MAIN: SET CRT2 REGISTER GROUP */
8844/*********************************************/
8845
8846BOOLEAN
8847SiS_SetCRT2Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
8848{
8849#ifdef SIS300
8850 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
8851#endif
8852 USHORT ModeIdIndex, RefreshRateTableIndex;
8853#if 0
8854 USHORT temp;
8855#endif
8856
8857 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
8858
8859 if(!SiS_Pr->UseCustomMode) {
8860 SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex);
8861 } else {
8862 ModeIdIndex = 0;
8863 }
8864
8865 /* Used for shifting CR33 */
8866 SiS_Pr->SiS_SelectCRT2Rate = 4;
8867
8868 SiS_UnLockCRT2(SiS_Pr, HwInfo);
8869
8870 RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
8871
8872 SiS_SaveCRT2Info(SiS_Pr,ModeNo);
8873
8874 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8875 SiS_DisableBridge(SiS_Pr,HwInfo);
8876 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (HwInfo->jChipType == SIS_730)) {
8877 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,0x80);
8878 }
8879 SiS_SetCRT2ModeRegs(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
8880 }
8881
8882 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
8883 SiS_LockCRT2(SiS_Pr, HwInfo);
8884 SiS_DisplayOn(SiS_Pr);
8885 return TRUE;
8886 }
8887
8888 SiS_GetCRT2Data(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
8889
8890 /* Set up Panel Link for LVDS and LCDA */
8891 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
8892 if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
8893 ((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ||
8894 ((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) ) {
8895 SiS_GetLVDSDesData(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
8896 }
8897
8898#ifdef LINUX_XF86
8899#ifdef TWDEBUG
8900 xf86DrvMsg(0, X_INFO, "(init301: LCDHDES 0x%03x LCDVDES 0x%03x)\n", SiS_Pr->SiS_LCDHDES, SiS_Pr->SiS_LCDVDES);
8901 xf86DrvMsg(0, X_INFO, "(init301: HDE 0x%03x VDE 0x%03x)\n", SiS_Pr->SiS_HDE, SiS_Pr->SiS_VDE);
8902 xf86DrvMsg(0, X_INFO, "(init301: VGAHDE 0x%03x VGAVDE 0x%03x)\n", SiS_Pr->SiS_VGAHDE, SiS_Pr->SiS_VGAVDE);
8903 xf86DrvMsg(0, X_INFO, "(init301: HT 0x%03x VT 0x%03x)\n", SiS_Pr->SiS_HT, SiS_Pr->SiS_VT);
8904 xf86DrvMsg(0, X_INFO, "(init301: VGAHT 0x%03x VGAVT 0x%03x)\n", SiS_Pr->SiS_VGAHT, SiS_Pr->SiS_VGAVT);
8905#endif
8906#endif
8907
8908 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8909 SiS_SetGroup1(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
8910 }
8911
8912 if(SiS_Pr->SiS_VBType & VB_SISVB) {
8913
8914 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8915
8916 SiS_SetGroup2(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
8917#ifdef SIS315H
8918 SiS_SetGroup2_C_ELV(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
8919#endif
8920 SiS_SetGroup3(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
8921 SiS_SetGroup4(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
8922#ifdef SIS315H
8923 SiS_SetGroup4_C_ELV(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
8924#endif
8925 SiS_SetGroup5(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
8926
8927 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex, HwInfo);
8928
8929 /* For 301BDH (Panel link initialization): */
8930 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
8931 if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) {
8932 if(!((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10)))) {
8933 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
8934 SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,
8935 RefreshRateTableIndex,HwInfo);
8936 }
8937 }
8938 }
8939 SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,
8940 RefreshRateTableIndex,HwInfo);
8941 }
8942 }
8943
8944 } else {
8945
8946 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex, HwInfo);
8947
8948 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
8949 SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwInfo);
8950 }
8951
8952 SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwInfo);
8953
8954 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8955 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
8956 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
8957 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8958#ifdef SIS315H
8959 SiS_SetCH701xForLCD(SiS_Pr,HwInfo);
8960#endif
8961 }
8962 }
8963 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8964 SiS_SetCHTVReg(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8965 }
8966 }
8967 }
8968
8969 }
8970
8971#ifdef SIS300
8972 if(HwInfo->jChipType < SIS_315H) {
8973 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8974 if(SiS_Pr->SiS_UseOEM) {
8975 if((SiS_Pr->SiS_UseROM) && (SiS_Pr->SiS_UseOEM == -1)) {
8976 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
8977 SiS_OEM300Setting(SiS_Pr,HwInfo,ModeNo,ModeIdIndex,
8978 RefreshRateTableIndex);
8979 }
8980 } else {
8981 SiS_OEM300Setting(SiS_Pr,HwInfo,ModeNo,ModeIdIndex,
8982 RefreshRateTableIndex);
8983 }
8984 }
8985 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
8986 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
8987 (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
8988 SetOEMLCDData2(SiS_Pr, HwInfo, ModeNo, ModeIdIndex,RefreshRateTableIndex);
8989 }
8990 SiS_DisplayOn(SiS_Pr);
8991 }
8992 }
8993 }
8994#endif
8995
8996#ifdef SIS315H
8997 if(HwInfo->jChipType >= SIS_315H) {
8998 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8999 if(HwInfo->jChipType < SIS_661) {
9000 SiS_FinalizeLCD(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
9001 SiS_OEM310Setting(SiS_Pr, HwInfo, ModeNo, ModeIdIndex, RefreshRateTableIndex);
9002 } else {
9003 SiS_OEM661Setting(SiS_Pr, HwInfo, ModeNo, ModeIdIndex, RefreshRateTableIndex);
9004 }
9005 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40);
9006 }
9007 }
9008#endif
9009
9010 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
9011 SiS_EnableBridge(SiS_Pr, HwInfo);
9012 }
9013
9014 SiS_DisplayOn(SiS_Pr);
9015
9016 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
9017 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
9018 /* Disable LCD panel when using TV */
9019 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFF,0x0C);
9020 } else {
9021 /* Disable TV when using LCD */
9022 SiS_SetCH70xxANDOR(SiS_Pr,0x010E,0xF8);
9023 }
9024 }
9025
9026 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
9027 SiS_LockCRT2(SiS_Pr,HwInfo);
9028 }
9029
9030 return TRUE;
9031}
9032
9033
9034/*********************************************/
9035/* ENABLE/DISABLE LCD BACKLIGHT (SIS) */
9036/*********************************************/
9037
9038void
9039SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
9040{
9041 /* Switch on LCD backlight on SiS30xLV */
9042 SiS_DDC2Delay(SiS_Pr,0xff00);
9043 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
9044 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
9045 SiS_WaitVBRetrace(SiS_Pr,HwInfo);
9046 }
9047 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x01)) {
9048 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
9049 }
9050}
9051
9052void
9053SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
9054{
9055 /* Switch off LCD backlight on SiS30xLV */
9056 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
9057 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
9058 SiS_DDC2Delay(SiS_Pr,0xe000);
9059}
9060
9061/*********************************************/
9062/* DDC RELATED FUNCTIONS */
9063/*********************************************/
9064
9065static void
9066SiS_SetupDDCN(SiS_Private *SiS_Pr)
9067{
9068 SiS_Pr->SiS_DDC_NData = ~SiS_Pr->SiS_DDC_Data;
9069 SiS_Pr->SiS_DDC_NClk = ~SiS_Pr->SiS_DDC_Clk;
9070 if((SiS_Pr->SiS_DDC_Index == 0x11) && (SiS_Pr->SiS_SensibleSR11)) {
9071 SiS_Pr->SiS_DDC_NData &= 0x0f;
9072 SiS_Pr->SiS_DDC_NClk &= 0x0f;
9073 }
9074}
9075
9076#ifdef SIS300
9077static UCHAR *
9078SiS_SetTrumpBlockLoop(SiS_Private *SiS_Pr, UCHAR *dataptr)
9079{
9080 int i, j, num;
9081 USHORT tempah,temp;
9082 UCHAR *mydataptr;
9083
9084 for(i=0; i<20; i++) { /* Do 20 attempts to write */
9085 mydataptr = dataptr;
9086 num = *mydataptr++;
9087 if(!num) return mydataptr;
9088 if(i) {
9089 SiS_SetStop(SiS_Pr);
9090 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT*2);
9091 }
9092 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
9093 tempah = SiS_Pr->SiS_DDC_DeviceAddr;
9094 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write DAB (S0=0=write) */
9095 if(temp) continue; /* (ERROR: no ack) */
9096 tempah = *mydataptr++;
9097 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write register number */
9098 if(temp) continue; /* (ERROR: no ack) */
9099 for(j=0; j<num; j++) {
9100 tempah = *mydataptr++;
9101 temp = SiS_WriteDDC2Data(SiS_Pr,tempah);/* Write DAB (S0=0=write) */
9102 if(temp) break;
9103 }
9104 if(temp) continue;
9105 if(SiS_SetStop(SiS_Pr)) continue;
9106 return mydataptr;
9107 }
9108 return NULL;
9109}
9110
9111static BOOLEAN
9112SiS_SetTrumpionBlock(SiS_Private *SiS_Pr, UCHAR *dataptr)
9113{
9114 SiS_Pr->SiS_DDC_DeviceAddr = 0xF0; /* DAB (Device Address Byte) */
9115 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9116 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
9117 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
9118 SiS_SetupDDCN(SiS_Pr);
9119
9120 SiS_SetSwitchDDC2(SiS_Pr);
9121
9122 while(*dataptr) {
9123 dataptr = SiS_SetTrumpBlockLoop(SiS_Pr, dataptr);
9124 if(!dataptr) return FALSE;
9125 }
9126#ifdef TWDEBUG
9127 xf86DrvMsg(0, X_INFO, "Trumpion block success\n");
9128#endif
9129 return TRUE;
9130}
9131#endif
9132
9133/* The Chrontel 700x is connected to the 630/730 via
9134 * the 630/730's DDC/I2C port.
9135 *
9136 * On 630(S)T chipset, the index changed from 0x11 to
9137 * 0x0a, possibly for working around the DDC problems
9138 */
9139
9140static BOOLEAN
9141SiS_SetChReg(SiS_Private *SiS_Pr, USHORT tempbx, USHORT myor)
9142{
9143 USHORT tempah,temp,i;
9144
9145 for(i=0; i<20; i++) { /* Do 20 attempts to write */
9146 if(i) {
9147 SiS_SetStop(SiS_Pr);
9148 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9149 }
9150 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
9151 tempah = SiS_Pr->SiS_DDC_DeviceAddr;
9152 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write DAB (S0=0=write) */
9153 if(temp) continue; /* (ERROR: no ack) */
9154 tempah = tempbx & 0x00FF; /* Write RAB */
9155 tempah |= myor; /* (700x: set bit 7, see datasheet) */
9156 temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
9157 if(temp) continue; /* (ERROR: no ack) */
9158 tempah = (tempbx & 0xFF00) >> 8;
9159 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write data */
9160 if(temp) continue; /* (ERROR: no ack) */
9161 if(SiS_SetStop(SiS_Pr)) continue; /* Set stop condition */
9162 SiS_Pr->SiS_ChrontelInit = 1;
9163 return TRUE;
9164 }
9165 return FALSE;
9166}
9167
9168#if 0
9169#ifdef SIS300
9170/* Write Trumpion register */
9171static void
9172SiS_SetTrumpReg(SiS_Private *SiS_Pr, USHORT tempbx)
9173{
9174 SiS_Pr->SiS_DDC_DeviceAddr = 0xF0; /* DAB (Device Address Byte) */
9175 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9176 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
9177 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
9178 SiS_SetupDDCN(SiS_Pr);
9179 SiS_SetChReg(SiS_Pr, tempbx, 0);
9180}
9181#endif
9182#endif
9183
9184/* Write to Chrontel 700x */
9185/* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
9186void
9187SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempbx)
9188{
9189 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */
9190
9191 if(!(SiS_Pr->SiS_ChrontelInit)) {
9192 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9193 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
9194 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
9195 SiS_SetupDDCN(SiS_Pr);
9196 }
9197
9198 if( (!(SiS_SetChReg(SiS_Pr, tempbx, 0x80))) &&
9199 (!(SiS_Pr->SiS_ChrontelInit)) ) {
9200 SiS_Pr->SiS_DDC_Index = 0x0a; /* Bit 7 = SC; Bit 6 = SD */
9201 SiS_Pr->SiS_DDC_Data = 0x80; /* Bitmask in IndexReg for Data */
9202 SiS_Pr->SiS_DDC_Clk = 0x40; /* Bitmask in IndexReg for Clk */
9203 SiS_SetupDDCN(SiS_Pr);
9204
9205 SiS_SetChReg(SiS_Pr, tempbx, 0x80);
9206 }
9207}
9208
9209/* Write to Chrontel 701x */
9210/* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
9211void
9212SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempbx)
9213{
9214 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9215 SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */
9216 SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */
9217 SiS_SetupDDCN(SiS_Pr);
9218 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */
9219 SiS_SetChReg(SiS_Pr, tempbx, 0);
9220}
9221
9222void
9223SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
9224{
9225 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
9226 SiS_SetCH700x(SiS_Pr,tempbx);
9227 else
9228 SiS_SetCH701x(SiS_Pr,tempbx);
9229}
9230
9231static USHORT
9232SiS_GetChReg(SiS_Private *SiS_Pr, USHORT myor)
9233{
9234 USHORT tempah,temp,i;
9235
9236 for(i=0; i<20; i++) { /* Do 20 attempts to read */
9237 if(i) {
9238 SiS_SetStop(SiS_Pr);
9239 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9240 }
9241 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
9242 tempah = SiS_Pr->SiS_DDC_DeviceAddr;
9243 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write DAB (S0=0=write) */
9244 if(temp) continue; /* (ERROR: no ack) */
9245 tempah = SiS_Pr->SiS_DDC_ReadAddr | myor; /* Write RAB (700x: | 0x80) */
9246 temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
9247 if(temp) continue; /* (ERROR: no ack) */
9248 if (SiS_SetStart(SiS_Pr)) continue; /* Re-start */
9249 tempah = SiS_Pr->SiS_DDC_DeviceAddr | 0x01;/* DAB | 0x01 = Read */
9250 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* DAB (S0=1=read) */
9251 if(temp) continue; /* (ERROR: no ack) */
9252 tempah = SiS_ReadDDC2Data(SiS_Pr,tempah); /* Read byte */
9253 if(SiS_SetStop(SiS_Pr)) continue; /* Stop condition */
9254 SiS_Pr->SiS_ChrontelInit = 1;
9255 return(tempah);
9256 }
9257 return 0xFFFF;
9258}
9259
9260#if 0
9261#ifdef SIS300
9262/* Read from Trumpion */
9263static USHORT
9264SiS_GetTrumpReg(SiS_Private *SiS_Pr, USHORT tempbx)
9265{
9266 SiS_Pr->SiS_DDC_DeviceAddr = 0xF0; /* DAB */
9267 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9268 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
9269 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
9270 SiS_SetupDDCN(SiS_Pr);
9271 SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9272 return(SiS_GetChReg(SiS_Pr,0));
9273}
9274#endif
9275#endif
9276
9277/* Read from Chrontel 700x */
9278/* Parameter is [Register no (S7-S0)] */
9279USHORT
9280SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempbx)
9281{
9282 USHORT result;
9283
9284 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */
9285
9286 if(!(SiS_Pr->SiS_ChrontelInit)) {
9287 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9288 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
9289 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
9290 SiS_SetupDDCN(SiS_Pr);
9291 }
9292
9293 SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9294
9295 if( ((result = SiS_GetChReg(SiS_Pr,0x80)) == 0xFFFF) &&
9296 (!SiS_Pr->SiS_ChrontelInit) ) {
9297
9298 SiS_Pr->SiS_DDC_Index = 0x0a;
9299 SiS_Pr->SiS_DDC_Data = 0x80;
9300 SiS_Pr->SiS_DDC_Clk = 0x40;
9301 SiS_SetupDDCN(SiS_Pr);
9302
9303 result = SiS_GetChReg(SiS_Pr,0x80);
9304 }
9305 return(result);
9306}
9307
9308/* Read from Chrontel 701x */
9309/* Parameter is [Register no (S7-S0)] */
9310USHORT
9311SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempbx)
9312{
9313 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9314 SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */
9315 SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */
9316 SiS_SetupDDCN(SiS_Pr);
9317 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */
9318
9319 SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9320
9321 return(SiS_GetChReg(SiS_Pr,0));
9322}
9323
9324/* Read from Chrontel 70xx */
9325/* Parameter is [Register no (S7-S0)] */
9326USHORT
9327SiS_GetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
9328{
9329 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
9330 return(SiS_GetCH700x(SiS_Pr, tempbx));
9331 else
9332 return(SiS_GetCH701x(SiS_Pr, tempbx));
9333}
9334
9335/* Our own DDC functions */
9336static USHORT
9337SiS_InitDDCRegs(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
9338 USHORT adaptnum, USHORT DDCdatatype, BOOLEAN checkcr32)
9339{
9340 unsigned char ddcdtype[] = { 0xa0, 0xa0, 0xa0, 0xa2, 0xa6 };
9341 unsigned char flag, cr32;
9342 USHORT temp = 0, myadaptnum = adaptnum;
9343
9344 if(adaptnum != 0) {
9345 if(!(VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) return 0xFFFF;
9346 if((VBFlags & VB_30xBDH) && (adaptnum == 1)) return 0xFFFF;
9347 }
9348
9349 /* adapternum for SiS bridges: 0 = CRT1, 1 = LCD, 2 = VGA2 */
9350
9351 SiS_Pr->SiS_ChrontelInit = 0; /* force re-detection! */
9352
9353 SiS_Pr->SiS_DDC_SecAddr = 0;
9354 SiS_Pr->SiS_DDC_DeviceAddr = ddcdtype[DDCdatatype];
9355 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_P3c4;
9356 SiS_Pr->SiS_DDC_Index = 0x11;
9357 flag = 0xff;
9358
9359 cr32 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x32);
9360
9361#if 0
9362 if(VBFlags & VB_SISBRIDGE) {
9363 if(myadaptnum == 0) {
9364 if(!(cr32 & 0x20)) {
9365 myadaptnum = 2;
9366 if(!(cr32 & 0x10)) {
9367 myadaptnum = 1;
9368 if(!(cr32 & 0x08)) {
9369 myadaptnum = 0;
9370 }
9371 }
9372 }
9373 }
9374 }
9375#endif
9376
9377 if(VGAEngine == SIS_300_VGA) { /* 300 series */
9378
9379 if(myadaptnum != 0) {
9380 flag = 0;
9381 if(VBFlags & VB_SISBRIDGE) {
9382 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9383 SiS_Pr->SiS_DDC_Index = 0x0f;
9384 }
9385 }
9386
9387 if(!(VBFlags & VB_301)) {
9388 if((cr32 & 0x80) && (checkcr32)) {
9389 if(myadaptnum >= 1) {
9390 if(!(cr32 & 0x08)) {
9391 myadaptnum = 1;
9392 if(!(cr32 & 0x10)) return 0xFFFF;
9393 }
9394 }
9395 }
9396 }
9397
9398 temp = 4 - (myadaptnum * 2);
9399 if(flag) temp = 0;
9400
9401 } else { /* 315/330 series */
9402
9403 /* here we simplify: 0 = CRT1, 1 = CRT2 (VGA, LCD) */
9404
9405 if(VBFlags & VB_SISBRIDGE) {
9406 if(myadaptnum == 2) {
9407 myadaptnum = 1;
9408 }
9409 }
9410
9411 if(myadaptnum == 1) {
9412 flag = 0;
9413 if(VBFlags & VB_SISBRIDGE) {
9414 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9415 SiS_Pr->SiS_DDC_Index = 0x0f;
9416 }
9417 }
9418
9419 if((cr32 & 0x80) && (checkcr32)) {
9420 if(myadaptnum >= 1) {
9421 if(!(cr32 & 0x08)) {
9422 myadaptnum = 1;
9423 if(!(cr32 & 0x10)) return 0xFFFF;
9424 }
9425 }
9426 }
9427
9428 temp = myadaptnum;
9429 if(myadaptnum == 1) {
9430 temp = 0;
9431 if(VBFlags & VB_LVDS) flag = 0xff;
9432 }
9433
9434 if(flag) temp = 0;
9435 }
9436
9437 SiS_Pr->SiS_DDC_Data = 0x02 << temp;
9438 SiS_Pr->SiS_DDC_Clk = 0x01 << temp;
9439
9440 SiS_SetupDDCN(SiS_Pr);
9441
9442#ifdef TWDEBUG
9443 xf86DrvMsg(0, X_INFO, "DDC Port %x Index %x Shift %d\n",
9444 SiS_Pr->SiS_DDC_Port, SiS_Pr->SiS_DDC_Index, temp);
9445#endif
9446
9447 return 0;
9448}
9449
9450static USHORT
9451SiS_WriteDABDDC(SiS_Private *SiS_Pr)
9452{
9453 if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9454 if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr)) {
9455 return 0xFFFF;
9456 }
9457 if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_SecAddr)) {
9458 return 0xFFFF;
9459 }
9460 return(0);
9461}
9462
9463static USHORT
9464SiS_PrepareReadDDC(SiS_Private *SiS_Pr)
9465{
9466 if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9467 if(SiS_WriteDDC2Data(SiS_Pr, (SiS_Pr->SiS_DDC_DeviceAddr | 0x01))) {
9468 return 0xFFFF;
9469 }
9470 return(0);
9471}
9472
9473static USHORT
9474SiS_PrepareDDC(SiS_Private *SiS_Pr)
9475{
9476 if(SiS_WriteDABDDC(SiS_Pr)) SiS_WriteDABDDC(SiS_Pr);
9477 if(SiS_PrepareReadDDC(SiS_Pr)) return(SiS_PrepareReadDDC(SiS_Pr));
9478 return(0);
9479}
9480
9481static void
9482SiS_SendACK(SiS_Private *SiS_Pr, USHORT yesno)
9483{
9484 SiS_SetSCLKLow(SiS_Pr);
9485 if(yesno) {
9486 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9487 SiS_Pr->SiS_DDC_Index,
9488 SiS_Pr->SiS_DDC_NData,
9489 SiS_Pr->SiS_DDC_Data);
9490 } else {
9491 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9492 SiS_Pr->SiS_DDC_Index,
9493 SiS_Pr->SiS_DDC_NData,
9494 0);
9495 }
9496 SiS_SetSCLKHigh(SiS_Pr);
9497}
9498
9499static USHORT
9500SiS_DoProbeDDC(SiS_Private *SiS_Pr)
9501{
9502 unsigned char mask, value;
9503 USHORT temp, ret=0;
9504 BOOLEAN failed = FALSE;
9505
9506 SiS_SetSwitchDDC2(SiS_Pr);
9507 if(SiS_PrepareDDC(SiS_Pr)) {
9508 SiS_SetStop(SiS_Pr);
9509#ifdef TWDEBUG
9510 xf86DrvMsg(0, X_INFO, "Probe: Prepare failed\n");
9511#endif
9512 return(0xFFFF);
9513 }
9514 mask = 0xf0;
9515 value = 0x20;
9516 if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9517 temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
9518 SiS_SendACK(SiS_Pr, 0);
9519 if(temp == 0) {
9520 mask = 0xff;
9521 value = 0xff;
9522 } else {
9523 failed = TRUE;
9524 ret = 0xFFFF;
9525#ifdef TWDEBUG
9526 xf86DrvMsg(0, X_INFO, "Probe: Read 1 failed\n");
9527#endif
9528 }
9529 }
9530 if(failed == FALSE) {
9531 temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
9532 SiS_SendACK(SiS_Pr, 1);
9533 temp &= mask;
9534 if(temp == value) ret = 0;
9535 else {
9536 ret = 0xFFFF;
9537#ifdef TWDEBUG
9538 xf86DrvMsg(0, X_INFO, "Probe: Read 2 failed\n");
9539#endif
9540 if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9541 if(temp == 0x30) ret = 0;
9542 }
9543 }
9544 }
9545 SiS_SetStop(SiS_Pr);
9546 return(ret);
9547}
9548
9549static USHORT
9550SiS_ProbeDDC(SiS_Private *SiS_Pr)
9551{
9552 USHORT flag;
9553
9554 flag = 0x180;
9555 SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
9556 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x02;
9557 SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;
9558 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x08;
9559 SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;
9560 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x10;
9561 if(!(flag & 0x1a)) flag = 0;
9562 return(flag);
9563}
9564
9565static USHORT
9566SiS_ReadDDC(SiS_Private *SiS_Pr, USHORT DDCdatatype, unsigned char *buffer)
9567{
9568 USHORT flag, length, i;
9569 unsigned char chksum,gotcha;
9570
9571 if(DDCdatatype > 4) return 0xFFFF;
9572
9573 flag = 0;
9574 SiS_SetSwitchDDC2(SiS_Pr);
9575 if(!(SiS_PrepareDDC(SiS_Pr))) {
9576 length = 127;
9577 if(DDCdatatype != 1) length = 255;
9578 chksum = 0;
9579 gotcha = 0;
9580 for(i=0; i<length; i++) {
9581 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
9582 chksum += buffer[i];
9583 gotcha |= buffer[i];
9584 SiS_SendACK(SiS_Pr, 0);
9585 }
9586 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
9587 chksum += buffer[i];
9588 SiS_SendACK(SiS_Pr, 1);
9589 if(gotcha) flag = (USHORT)chksum;
9590 else flag = 0xFFFF;
9591 } else {
9592 flag = 0xFFFF;
9593 }
9594 SiS_SetStop(SiS_Pr);
9595 return(flag);
9596}
9597
9598/* Our private DDC functions
9599
9600 It complies somewhat with the corresponding VESA function
9601 in arguments and return values.
9602
9603 Since this is probably called before the mode is changed,
9604 we use our pre-detected pSiS-values instead of SiS_Pr as
9605 regards chipset and video bridge type.
9606
9607 Arguments:
9608 adaptnum: 0=CRT1(analog), 1=CRT2/LCD(digital), 2=CRT2/VGA2(analog)
9609 CRT2 DDC is only supported on SiS301, 301B, 301C, 302B.
9610 LCDA is CRT1, but DDC is read from CRT2 port.
9611 DDCdatatype: 0=Probe, 1=EDID, 2=EDID+VDIF, 3=EDID V2 (P&D), 4=EDID V2 (FPDI-2)
9612 buffer: ptr to 256 data bytes which will be filled with read data.
9613
9614 Returns 0xFFFF if error, otherwise
9615 if DDCdatatype > 0: Returns 0 if reading OK (included a correct checksum)
9616 if DDCdatatype = 0: Returns supported DDC modes
9617
9618 */
9619USHORT
9620SiS_HandleDDC(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
9621 USHORT adaptnum, USHORT DDCdatatype, unsigned char *buffer)
9622{
9623 unsigned char sr1f,cr17=1;
9624 USHORT result;
9625
9626 if(adaptnum > 2) return 0xFFFF;
9627 if(DDCdatatype > 4) return 0xFFFF;
9628 if((!(VBFlags & VB_VIDEOBRIDGE)) && (adaptnum > 0)) return 0xFFFF;
9629 if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, FALSE) == 0xFFFF) return 0xFFFF;
9630
9631 sr1f = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f);
9632 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1f,0x3f,0x04);
9633 if(VGAEngine == SIS_300_VGA) {
9634 cr17 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80;
9635 if(!cr17) {
9636 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x17,0x80);
9637 SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x01);
9638 SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x03);
9639 }
9640 }
9641 if((sr1f) || (!cr17)) {
9642 SiS_WaitRetrace1(SiS_Pr);
9643 SiS_WaitRetrace1(SiS_Pr);
9644 SiS_WaitRetrace1(SiS_Pr);
9645 SiS_WaitRetrace1(SiS_Pr);
9646 }
9647
9648 if(DDCdatatype == 0) {
9649 result = SiS_ProbeDDC(SiS_Pr);
9650 } else {
9651 result = SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer);
9652 if((!result) && (DDCdatatype == 1)) {
9653 if((buffer[0] == 0x00) && (buffer[1] == 0xff) &&
9654 (buffer[2] == 0xff) && (buffer[3] == 0xff) &&
9655 (buffer[4] == 0xff) && (buffer[5] == 0xff) &&
9656 (buffer[6] == 0xff) && (buffer[7] == 0x00) &&
9657 (buffer[0x12] == 1)) {
9658 if(adaptnum == 1) {
9659 if(!(buffer[0x14] & 0x80)) result = 0xFFFE;
9660 } else {
9661 if(buffer[0x14] & 0x80) result = 0xFFFE;
9662 }
9663 }
9664 }
9665 }
9666 SiS_SetReg(SiS_Pr->SiS_P3c4,0x1f,sr1f);
9667 if(VGAEngine == SIS_300_VGA) {
9668 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x17,0x7f,cr17);
9669 }
9670 return result;
9671}
9672
9673#ifdef LINUX_XF86
9674
9675static BOOLEAN
9676checkedid1(unsigned char *buffer)
9677{
9678 /* Check header */
9679 if((buffer[0] != 0x00) ||
9680 (buffer[1] != 0xff) ||
9681 (buffer[2] != 0xff) ||
9682 (buffer[3] != 0xff) ||
9683 (buffer[4] != 0xff) ||
9684 (buffer[5] != 0xff) ||
9685 (buffer[6] != 0xff) ||
9686 (buffer[7] != 0x00))
9687 return FALSE;
9688
9689 /* Check EDID version and revision */
9690 if((buffer[0x12] != 1) || (buffer[0x13] > 4)) return FALSE;
9691
9692 /* Check week of manufacture for sanity */
9693 if(buffer[0x10] > 53) return FALSE;
9694
9695 /* Check year of manufacture for sanity */
9696 if(buffer[0x11] > 40) return FALSE;
9697
9698 return TRUE;
9699}
9700
9701static BOOLEAN
9702checkedid2(unsigned char *buffer)
9703{
9704 USHORT year = buffer[6] | (buffer[7] << 8);
9705
9706 /* Check EDID version */
9707 if((buffer[0] & 0xf0) != 0x20) return FALSE;
9708
9709 /* Check week of manufacture for sanity */
9710 if(buffer[5] > 53) return FALSE;
9711
9712 /* Check year of manufacture for sanity */
9713 if((year != 0) && ((year < 1990) || (year > 2030))) return FALSE;
9714
9715 return TRUE;
9716}
9717
9718/* Sense the LCD parameters (CR36, CR37) via DDC */
9719/* SiS30x(B) only */
9720USHORT
9721SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS)
9722{
9723 USHORT DDCdatatype, paneltype, flag, xres=0, yres=0;
9724 USHORT index, myindex, lumsize, numcodes, panelvendor, panelproduct;
9725 int maxx=0, maxy=0, prefx=0, prefy=0;
9726 unsigned char cr37=0, seekcode;
9727 BOOLEAN checkexpand = FALSE;
9728 BOOLEAN havesync = FALSE;
9729 BOOLEAN indb = FALSE;
9730 int retry, i;
9731 unsigned char buffer[256];
9732
9733 for(i=0; i<7; i++) SiS_Pr->CP_DataValid[i] = FALSE;
9734 SiS_Pr->CP_HaveCustomData = FALSE;
9735 SiS_Pr->CP_MaxX = SiS_Pr->CP_MaxY = SiS_Pr->CP_MaxClock = 0;
9736 SiS_Pr->CP_PreferredX = SiS_Pr->CP_PreferredY = 0;
9737 SiS_Pr->CP_PreferredIndex = -1;
9738 SiS_Pr->CP_PrefClock = 0;
9739 SiS_Pr->PanelSelfDetected = FALSE;
9740
9741 if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) return 0;
9742 if(pSiS->VBFlags & VB_30xBDH) return 0;
9743
9744 if(SiS_InitDDCRegs(SiS_Pr, pSiS->VBFlags, pSiS->VGAEngine, 1, 0, FALSE) == 0xFFFF) return 0;
9745
9746 SiS_Pr->SiS_DDC_SecAddr = 0x00;
9747
9748 /* Probe supported DA's */
9749 flag = SiS_ProbeDDC(SiS_Pr);
9750#ifdef TWDEBUG
9751 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO,
9752 "CRT2 DDC capabilities 0x%x\n", flag);
9753#endif
9754 if(flag & 0x10) {
9755 SiS_Pr->SiS_DDC_DeviceAddr = 0xa6; /* EDID V2 (FP) */
9756 DDCdatatype = 4;
9757 } else if(flag & 0x08) {
9758 SiS_Pr->SiS_DDC_DeviceAddr = 0xa2; /* EDID V2 (P&D-D Monitor) */
9759 DDCdatatype = 3;
9760 } else if(flag & 0x02) {
9761 SiS_Pr->SiS_DDC_DeviceAddr = 0xa0; /* EDID V1 */
9762 DDCdatatype = 1;
9763 } else return 0; /* no DDC support (or no device attached) */
9764
9765 /* Read the entire EDID */
9766 retry = 2;
9767 do {
9768 if(SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer)) {
9769 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9770 "CRT2: DDC read failed (attempt %d), %s\n",
9771 (3-retry), (retry == 1) ? "giving up" : "retrying");
9772 retry--;
9773 if(retry == 0) return 0xFFFF;
9774 } else break;
9775 } while(1);
9776
9777#ifdef TWDEBUG
9778 for(i=0; i<256; i+=16) {
9779 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9780 "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
9781 buffer[i], buffer[i+1], buffer[i+2], buffer[i+3],
9782 buffer[i+4], buffer[i+5], buffer[i+6], buffer[i+7],
9783 buffer[i+8], buffer[i+9], buffer[i+10], buffer[i+11],
9784 buffer[i+12], buffer[i+13], buffer[i+14], buffer[i+15]);
9785 }
9786#endif
9787
9788 /* Analyze EDID and retrieve LCD panel information */
9789 paneltype = 0;
9790 switch(DDCdatatype) {
9791 case 1: /* Analyze EDID V1 */
9792 /* Catch a few clear cases: */
9793 if(!(checkedid1(buffer))) {
9794 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9795 "LCD sense: EDID corrupt\n");
9796 return 0;
9797 }
9798
9799 if(!(buffer[0x14] & 0x80)) {
9800 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9801 "LCD sense: Attached display expects analog input (0x%02x)\n",
9802 buffer[0x14]);
9803 return 0;
9804 }
9805
9806 if((buffer[0x18] & 0x18) != 0x08) {
9807 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9808 "LCD sense: Warning: Attached display is not of RGB but of %s type (0x%02x)\n",
9809 ((buffer[0x18] & 0x18) == 0x00) ? "monochrome/greyscale" :
9810 ( ((buffer[0x18] & 0x18) == 0x10) ? "non-RGB multicolor" :
9811 "undefined"),
9812 buffer[0x18]);
9813 }
9814
9815 /* Now analyze the first Detailed Timing Block and see
9816 * if the preferred timing mode is stored there. If so,
9817 * check if this is a standard panel for which we already
9818 * know the timing.
9819 */
9820
9821 paneltype = Panel_Custom;
9822 checkexpand = FALSE;
9823
9824 panelvendor = buffer[9] | (buffer[8] << 8);
9825 panelproduct = buffer[10] | (buffer[11] << 8);
9826
9827 /* Overrule bogus preferred modes from database */
9828 if((indb = SiS_FindPanelFromDB(pSiS, panelvendor, panelproduct, &maxx, &maxy, &prefx, &prefy))) {
9829 if(prefx) SiS_Pr->CP_PreferredX = xres = prefx;
9830 if(prefy) SiS_Pr->CP_PreferredY = yres = prefy;
9831 }
9832
9833 if(buffer[0x18] & 0x02) {
9834
9835 USHORT pclk = (buffer[0x36] | (buffer[0x37] << 8));
9836 USHORT phb = (buffer[0x39] | ((buffer[0x3a] & 0x0f) << 8));
9837 USHORT pvb = (buffer[0x3c] | ((buffer[0x3d] & 0x0f) << 8));
9838
9839 if(!xres) SiS_Pr->CP_PreferredX = xres = buffer[0x38] | ((buffer[0x3a] & 0xf0) << 4);
9840 if(!yres) SiS_Pr->CP_PreferredY = yres = buffer[0x3b] | ((buffer[0x3d] & 0xf0) << 4);
9841
9842 switch(xres) {
9843#if 0 /* Treat as custom */
9844 case 800:
9845 if(yres == 600) {
9846 paneltype = Panel_800x600;
9847 checkexpand = TRUE;
9848 }
9849 break;
9850#endif
9851 case 1024:
9852 if(yres == 768) {
9853 paneltype = Panel_1024x768;
9854 checkexpand = TRUE;
9855 }
9856 break;
9857 case 1280:
9858 if(yres == 1024) {
9859 paneltype = Panel_1280x1024;
9860 checkexpand = TRUE;
9861 } else if(yres == 960) {
9862 if(pSiS->VGAEngine == SIS_300_VGA) {
9863 paneltype = Panel300_1280x960;
9864 } else {
9865 paneltype = Panel310_1280x960;
9866 }
9867 } else if(yres == 768) {
9868 if( (pclk == 8100) &&
9869 (phb == (1688 - 1280)) &&
9870 (pvb == (802 - 768)) ) {
9871 paneltype = Panel_1280x768;
9872 checkexpand = FALSE;
9873 cr37 |= 0x10;
9874 }
9875 } else if(yres == 800) {
9876 if( (pclk == 6900) &&
9877 (phb == (1408 - 1280)) &&
9878 (pvb == (816 - 800)) ) {
9879 paneltype = Panel_1280x800;
9880 }
9881 }
9882 break;
9883 case 1400:
9884 if(pSiS->VGAEngine == SIS_315_VGA) {
9885 if(yres == 1050) {
9886 paneltype = Panel310_1400x1050;
9887 checkexpand = TRUE;
9888 }
9889 }
9890 break;
9891 case 1600:
9892 if(pSiS->VGAEngine == SIS_315_VGA) {
9893 if(pSiS->VBFlags & VB_301C) {
9894 if(yres == 1200) {
9895 paneltype = Panel310_1600x1200;
9896 checkexpand = TRUE;
9897 }
9898 }
9899 }
9900 break;
9901 }
9902
9903 /* Save sync: This is used if "Pass 1:1" is off; in this case
9904 * we always use the panel's native mode = this "preferred mode"
9905 * we just have been analysing. Hence, we also need its sync.
9906 */
9907 if((buffer[0x47] & 0x18) == 0x18) {
9908 cr37 |= ((((buffer[0x47] & 0x06) ^ 0x06) << 5) | 0x20);
9909 havesync = TRUE;
9910 } else {
9911 /* What now? There is no digital separate output timing... */
9912 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
9913 "LCD sense: Unable to retrieve Sync polarity information\n");
9914 cr37 |= 0xc0; /* Default */
9915 }
9916
9917 }
9918
9919 /* Check against our database; eg. Sanyo Z2 projector reports
9920 * 1024x768 as preferred mode, although it supports 1280x720
9921 * natively in non-HDCP mode. Treat such wrongly reporting
9922 * panels as custom and fixup actual maximum resolutions.
9923 */
9924 if(paneltype != Panel_Custom) {
9925 if(indb) {
9926 paneltype = Panel_Custom;
9927 SiS_Pr->CP_MaxX = maxx;
9928 SiS_Pr->CP_MaxY = maxy;
9929 /* Leave preferred unchanged (MUST contain a valid mode!) */
9930 }
9931 }
9932
9933 /* If we still don't know what panel this is, we take it
9934 * as a custom panel and derive the timing data from the
9935 * detailed timing blocks
9936 */
9937 if(paneltype == Panel_Custom) {
9938
9939 int i, temp, base = 0x36;
9940 unsigned long estpack;
9941 const unsigned short estx[] = {
9942 720, 720, 640, 640, 640, 640, 800, 800,
9943 800, 800, 832,1024,1024,1024,1024,1280,
9944 1152
9945 };
9946 const unsigned short esty[] = {
9947 400, 400, 480, 480, 480, 480, 600, 600,
9948 600, 600, 624, 768, 768, 768, 768,1024,
9949 870
9950 };
9951 const int estclk[] = {
9952 0, 0, 25100, 0, 31500, 31500, 36100, 40000,
9953 50100, 49500, 0, 0, 65100, 75200, 78700,135200,
9954 0
9955 };
9956
9957 paneltype = 0;
9958 SiS_Pr->CP_Supports64048075 = TRUE;
9959
9960 /* Find the maximum resolution */
9961
9962 /* 1. From Established timings */
9963 estpack = (buffer[0x23] << 9) | (buffer[0x24] << 1) | ((buffer[0x25] >> 7) & 0x01);
9964 for(i=16; i>=0; i--) {
9965 if(estpack & (1 << i)) {
9966 if(estx[16 - i] > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = estx[16 - i];
9967 if(esty[16 - i] > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = esty[16 - i];
9968 if(estclk[16 - i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = estclk[16 - i];
9969 }
9970 }
9971
9972 /* By default we drive the LCD at 75Hz in 640x480 mode; if
9973 * the panel does not provide this mode, use 60hz
9974 */
9975 if(!(buffer[0x23] & 0x04)) SiS_Pr->CP_Supports64048075 = FALSE;
9976
9977 /* 2. From Standard Timings */
9978 for(i=0x26; i < 0x36; i+=2) {
9979 if((buffer[i] != 0x01) && (buffer[i+1] != 0x01)) {
9980 temp = (buffer[i] + 31) * 8;
9981 if(temp > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = temp;
9982 switch((buffer[i+1] & 0xc0) >> 6) {
9983 case 0x03: temp = temp * 9 / 16; break;
9984 case 0x02: temp = temp * 4 / 5; break;
9985 case 0x01: temp = temp * 3 / 4; break;
9986 }
9987 if(temp > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = temp;
9988 }
9989 }
9990
9991 /* Now extract the Detailed Timings and convert them into modes */
9992
9993 for(i = 0; i < 4; i++, base += 18) {
9994
9995 /* Is this a detailed timing block or a monitor descriptor? */
9996 if(buffer[base] || buffer[base+1] || buffer[base+2]) {
9997
9998 xres = buffer[base+2] | ((buffer[base+4] & 0xf0) << 4);
9999 yres = buffer[base+5] | ((buffer[base+7] & 0xf0) << 4);
10000
10001 SiS_Pr->CP_HDisplay[i] = xres;
10002 SiS_Pr->CP_HSyncStart[i] = xres + (buffer[base+8] | ((buffer[base+11] & 0xc0) << 2));
10003 SiS_Pr->CP_HSyncEnd[i] = SiS_Pr->CP_HSyncStart[i] + (buffer[base+9] | ((buffer[base+11] & 0x30) << 4));
10004 SiS_Pr->CP_HTotal[i] = xres + (buffer[base+3] | ((buffer[base+4] & 0x0f) << 8));
10005 SiS_Pr->CP_HBlankStart[i] = xres + 1;
10006 SiS_Pr->CP_HBlankEnd[i] = SiS_Pr->CP_HTotal[i];
10007
10008 SiS_Pr->CP_VDisplay[i] = yres;
10009 SiS_Pr->CP_VSyncStart[i] = yres + (((buffer[base+10] & 0xf0) >> 4) | ((buffer[base+11] & 0x0c) << 2));
10010 SiS_Pr->CP_VSyncEnd[i] = SiS_Pr->CP_VSyncStart[i] + ((buffer[base+10] & 0x0f) | ((buffer[base+11] & 0x03) << 4));
10011 SiS_Pr->CP_VTotal[i] = yres + (buffer[base+6] | ((buffer[base+7] & 0x0f) << 8));
10012 SiS_Pr->CP_VBlankStart[i] = yres + 1;
10013 SiS_Pr->CP_VBlankEnd[i] = SiS_Pr->CP_VTotal[i];
10014
10015 SiS_Pr->CP_Clock[i] = (buffer[base] | (buffer[base+1] << 8)) * 10;
10016
10017 SiS_Pr->CP_DataValid[i] = TRUE;
10018
10019 /* Sort out invalid timings, interlace and too high clocks */
10020 if((SiS_Pr->CP_HDisplay[i] & 7) ||
10021 (SiS_Pr->CP_HDisplay[i] > SiS_Pr->CP_HSyncStart[i]) ||
10022 (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HSyncEnd[i]) ||
10023 (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HTotal[i]) ||
10024 (SiS_Pr->CP_HSyncStart[i] >= SiS_Pr->CP_HSyncEnd[i]) ||
10025 (SiS_Pr->CP_HSyncStart[i] > SiS_Pr->CP_HTotal[i]) ||
10026 (SiS_Pr->CP_HSyncEnd[i] > SiS_Pr->CP_HTotal[i]) ||
10027 (SiS_Pr->CP_VDisplay[i] > SiS_Pr->CP_VSyncStart[i]) ||
10028 (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VSyncEnd[i]) ||
10029 (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VTotal[i]) ||
10030 (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VSyncEnd[i]) ||
10031 (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VTotal[i]) ||
10032 (SiS_Pr->CP_VSyncEnd[i] > SiS_Pr->CP_VTotal[i]) ||
10033 (((pSiS->VBFlags & VB_301C) && (SiS_Pr->CP_Clock[i] > 162500)) ||
10034 ((!(pSiS->VBFlags & VB_301C)) &&
10035 ((SiS_Pr->CP_Clock[i] > 108200) || (SiS_Pr->CP_VDisplay[i] > 1024) ||
10036 (SiS_Pr->CP_HDisplay[i] > 1600)))) ||
10037 (buffer[base+17] & 0x80)) {
10038
10039 SiS_Pr->CP_DataValid[i] = FALSE;
10040
10041 } else {
10042
10043 SiS_Pr->CP_HaveCustomData = TRUE;
10044
10045 if(xres > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = xres;
10046 if(yres > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = yres;
10047 if(SiS_Pr->CP_Clock[i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = SiS_Pr->CP_Clock[i];
10048
10049 if((SiS_Pr->CP_PreferredX == xres) && (SiS_Pr->CP_PreferredY == yres)) {
10050 SiS_Pr->CP_PreferredIndex = i;
10051 SiS_MakeClockRegs(pSiS->pScrn, SiS_Pr->CP_Clock[i], &SiS_Pr->CP_PrefSR2B, &SiS_Pr->CP_PrefSR2C);
10052 SiS_Pr->CP_PrefClock = (SiS_Pr->CP_Clock[i] / 1000) + 1;
10053 }
10054
10055 /* Extract the sync polarisation information. This only works
10056 * if the Flags indicate a digital separate output.
10057 */
10058 if((buffer[base+17] & 0x18) == 0x18) {
10059 SiS_Pr->CP_HSync_P[i] = (buffer[base+17] & 0x02) ? TRUE : FALSE;
10060 SiS_Pr->CP_VSync_P[i] = (buffer[base+17] & 0x04) ? TRUE : FALSE;
10061 SiS_Pr->CP_SyncValid[i] = TRUE;
10062 if((i == SiS_Pr->CP_PreferredIndex) && (!havesync)) {
10063 cr37 |= ((((buffer[base+17] & 0x06) ^ 0x06) << 5) | 0x20);
10064 havesync = TRUE;
10065 }
10066 } else {
10067 SiS_Pr->CP_SyncValid[i] = FALSE;
10068 }
10069
10070 }
10071
10072 } else if((!buffer[base]) && (!buffer[base+1]) && (!buffer[base+2]) && (!buffer[base+4])) {
10073
10074 /* Maximum pixclock from Monitor Range Limits */
10075 if((buffer[base+3] == 0xfd) && (buffer[base+9] != 0xff)) {
10076 int maxclk = buffer[base+9] * 10;
10077 /* More than 170 is not supported anyway */
10078 if(maxclk <= 170) SiS_Pr->CP_MaxClock = maxclk * 1000;
10079 }
10080
10081 }
10082
10083 }
10084
10085 if(SiS_Pr->CP_MaxX && SiS_Pr->CP_MaxY) {
10086 paneltype = Panel_Custom;
10087 checkexpand = FALSE;
10088 cr37 |= 0x10;
10089 SiS_Pr->CP_Vendor = panelvendor;
10090 SiS_Pr->CP_Product = panelproduct;
10091 }
10092
10093 }
10094
10095 if(paneltype && checkexpand) {
10096 /* If any of the Established low-res modes is supported, the
10097 * panel can scale automatically. For 800x600 panels, we only
10098 * check the even lower ones.
10099 */
10100 if(paneltype == Panel_800x600) {
10101 if(buffer[0x23] & 0xfc) cr37 |= 0x10;
10102 } else {
10103 if(buffer[0x23]) cr37 |= 0x10;
10104 }
10105 }
10106
10107 break;
10108
10109 case 3: /* Analyze EDID V2 */
10110 case 4:
10111 index = 0;
10112
10113 if(!(checkedid2(buffer))) {
10114 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10115 "LCD sense: EDID corrupt\n");
10116 return 0;
10117 }
10118
10119 if((buffer[0x41] & 0x0f) == 0x03) {
10120 index = 0x42 + 3;
10121 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10122 "LCD sense: Display supports TMDS input on primary interface\n");
10123 } else if((buffer[0x41] & 0xf0) == 0x30) {
10124 index = 0x46 + 3;
10125 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10126 "LCD sense: Display supports TMDS input on secondary interface\n");
10127 } else {
10128 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10129 "LCD sense: Display does not support TMDS video interface (0x%02x)\n",
10130 buffer[0x41]);
10131 return 0;
10132 }
10133
10134 SiS_Pr->CP_Vendor = panelvendor = buffer[2] | (buffer[1] << 8);
10135 SiS_Pr->CP_Product = panelproduct = buffer[3] | (buffer[4] << 8);
10136
10137 paneltype = Panel_Custom;
10138 SiS_Pr->CP_MaxX = SiS_Pr->CP_PreferredX = xres = buffer[0x76] | (buffer[0x77] << 8);
10139 SiS_Pr->CP_MaxY = SiS_Pr->CP_PreferredY = yres = buffer[0x78] | (buffer[0x79] << 8);
10140
10141 switch(xres) {
10142#if 0
10143 case 800:
10144 if(yres == 600) {
10145 paneltype = Panel_800x600;
10146 checkexpand = TRUE;
10147 }
10148 break;
10149#endif
10150 case 1024:
10151 if(yres == 768) {
10152 paneltype = Panel_1024x768;
10153 checkexpand = TRUE;
10154 }
10155 break;
10156 case 1280:
10157 if(yres == 960) {
10158 if(pSiS->VGAEngine == SIS_315_VGA) {
10159 paneltype = Panel310_1280x960;
10160 } else {
10161 paneltype = Panel300_1280x960;
10162 }
10163 } else if(yres == 1024) {
10164 paneltype = Panel_1280x1024;
10165 checkexpand = TRUE;
10166 }
10167 /* 1280x768 treated as custom here */
10168 break;
10169 case 1400:
10170 if(pSiS->VGAEngine == SIS_315_VGA) {
10171 if(yres == 1050) {
10172 paneltype = Panel310_1400x1050;
10173 checkexpand = TRUE;
10174 }
10175 }
10176 break;
10177 case 1600:
10178 if(pSiS->VGAEngine == SIS_315_VGA) {
10179 if(pSiS->VBFlags & VB_301C) {
10180 if(yres == 1200) {
10181 paneltype = Panel310_1600x1200;
10182 checkexpand = TRUE;
10183 }
10184 }
10185 }
10186 break;
10187 }
10188
10189 /* Determine if RGB18 or RGB24 */
10190 if(index) {
10191 if((buffer[index] == 0x20) || (buffer[index] == 0x34)) {
10192 cr37 |= 0x01;
10193 }
10194 }
10195
10196 if(checkexpand) {
10197 /* TODO - for now, we let the panel scale */
10198 cr37 |= 0x10;
10199 }
10200
10201 /* Now seek 4-Byte Timing codes and extract sync pol info */
10202 index = 0x80;
10203 if(buffer[0x7e] & 0x20) { /* skip Luminance Table (if provided) */
10204 lumsize = buffer[0x80] & 0x1f;
10205 if(buffer[0x80] & 0x80) lumsize *= 3;
10206 lumsize++; /* luminance header byte */
10207 index += lumsize;
10208 }
10209#if 0 /* "pixel rate" = pixel clock? */
10210 if(buffer[0x7e] & 0x1c) {
10211 for(i=0; i<((buffer[0x7e] & 0x1c) >> 2); i++) {
10212 if(buffer[index + (i*8) + 6] && (buffer[index + (i*8) + 7] & 0x0f)) {
10213 int clk = (buffer[index + (i*8) + 6] | ((buffer[index + (i*8) + 7] & 0x0f) << 4)) * 1000;
10214 if(clk > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = clk;
10215 }
10216 }
10217 }
10218#endif
10219 index += (((buffer[0x7e] & 0x1c) >> 2) * 8); /* skip Frequency Ranges */
10220 if(buffer[0x7e] & 0x03) {
10221 for(i=0; i<(buffer[0x7e] & 0x03); i++) {
10222 if((buffer[index + (i*27) + 9]) || (buffer[index + (i*27) + 10])) {
10223 int clk = ((buffer[index + (i*27) + 9]) | ((buffer[index + (i*27) + 9]) << 8)) * 10;
10224 if(clk > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = clk;
10225 }
10226 }
10227 }
10228 index += ((buffer[0x7e] & 0x03) * 27); /* skip Detailed Range Limits */
10229 numcodes = (buffer[0x7f] & 0xf8) >> 3;
10230 if(numcodes) {
10231 myindex = index;
10232 seekcode = (xres - 256) / 16;
10233 for(i=0; i<numcodes; i++) {
10234 if(buffer[myindex] == seekcode) break;
10235 myindex += 4;
10236 }
10237 if(buffer[myindex] == seekcode) {
10238 cr37 |= ((((buffer[myindex + 1] & 0x0c) ^ 0x0c) << 4) | 0x20);
10239 havesync = TRUE;
10240 } else {
10241 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
10242 "LCD sense: Unable to retrieve Sync polarity information\n");
10243 }
10244 } else {
10245 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
10246 "LCD sense: Unable to retrieve Sync polarity information\n");
10247 }
10248
10249 /* Check against our database; Eg. Sanyo projector reports
10250 * 1024x768 in non-HDPC mode, although it supports 1280x720.
10251 * Treat such wrongly reporting panels as custom.
10252 */
10253 if(paneltype != Panel_Custom) {
10254 int maxx, maxy, prefx, prefy;
10255 if((SiS_FindPanelFromDB(pSiS, panelvendor, panelproduct, &maxx, &maxy, &prefx, &prefy))) {
10256 paneltype = Panel_Custom;
10257 SiS_Pr->CP_MaxX = maxx;
10258 SiS_Pr->CP_MaxY = maxy;
10259 cr37 |= 0x10;
10260 /* Leave preferred unchanged (MUST be a valid mode!) */
10261 }
10262 }
10263
10264 /* Now seek the detailed timing descriptions for custom panels */
10265 if(paneltype == Panel_Custom) {
10266
10267 SiS_Pr->CP_Supports64048075 = TRUE;
10268
10269 index += (numcodes * 4);
10270 numcodes = buffer[0x7f] & 0x07;
10271 for(i=0; i<numcodes; i++, index += 18) {
10272 xres = buffer[index+2] | ((buffer[index+4] & 0xf0) << 4);
10273 yres = buffer[index+5] | ((buffer[index+7] & 0xf0) << 4);
10274
10275 SiS_Pr->CP_HDisplay[i] = xres;
10276 SiS_Pr->CP_HSyncStart[i] = xres + (buffer[index+8] | ((buffer[index+11] & 0xc0) << 2));
10277 SiS_Pr->CP_HSyncEnd[i] = SiS_Pr->CP_HSyncStart[i] + (buffer[index+9] | ((buffer[index+11] & 0x30) << 4));
10278 SiS_Pr->CP_HTotal[i] = xres + (buffer[index+3] | ((buffer[index+4] & 0x0f) << 8));
10279 SiS_Pr->CP_HBlankStart[i] = xres + 1;
10280 SiS_Pr->CP_HBlankEnd[i] = SiS_Pr->CP_HTotal[i];
10281
10282 SiS_Pr->CP_VDisplay[i] = yres;
10283 SiS_Pr->CP_VSyncStart[i] = yres + (((buffer[index+10] & 0xf0) >> 4) | ((buffer[index+11] & 0x0c) << 2));
10284 SiS_Pr->CP_VSyncEnd[i] = SiS_Pr->CP_VSyncStart[i] + ((buffer[index+10] & 0x0f) | ((buffer[index+11] & 0x03) << 4));
10285 SiS_Pr->CP_VTotal[i] = yres + (buffer[index+6] | ((buffer[index+7] & 0x0f) << 8));
10286 SiS_Pr->CP_VBlankStart[i] = yres + 1;
10287 SiS_Pr->CP_VBlankEnd[i] = SiS_Pr->CP_VTotal[i];
10288
10289 SiS_Pr->CP_Clock[i] = (buffer[index] | (buffer[index+1] << 8)) * 10;
10290
10291 SiS_Pr->CP_DataValid[i] = TRUE;
10292
10293 if((SiS_Pr->CP_HDisplay[i] & 7) ||
10294 (SiS_Pr->CP_HDisplay[i] > SiS_Pr->CP_HSyncStart[i]) ||
10295 (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HSyncEnd[i]) ||
10296 (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HTotal[i]) ||
10297 (SiS_Pr->CP_HSyncStart[i] >= SiS_Pr->CP_HSyncEnd[i]) ||
10298 (SiS_Pr->CP_HSyncStart[i] > SiS_Pr->CP_HTotal[i]) ||
10299 (SiS_Pr->CP_HSyncEnd[i] > SiS_Pr->CP_HTotal[i]) ||
10300 (SiS_Pr->CP_VDisplay[i] > SiS_Pr->CP_VSyncStart[i]) ||
10301 (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VSyncEnd[i]) ||
10302 (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VTotal[i]) ||
10303 (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VSyncEnd[i]) ||
10304 (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VTotal[i]) ||
10305 (SiS_Pr->CP_VSyncEnd[i] > SiS_Pr->CP_VTotal[i]) ||
10306 (((pSiS->VBFlags & VB_301C) && (SiS_Pr->CP_Clock[i] > 162500)) ||
10307 ((!(pSiS->VBFlags & VB_301C)) &&
10308 ((SiS_Pr->CP_Clock[i] > 108200) || (SiS_Pr->CP_VDisplay[i] > 1024)))) ||
10309 (buffer[index + 17] & 0x80)) {
10310
10311 SiS_Pr->CP_DataValid[i] = FALSE;
10312
10313 } else {
10314
10315 SiS_Pr->CP_HaveCustomData = TRUE;
10316
10317 if(SiS_Pr->CP_Clock[i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = SiS_Pr->CP_Clock[i];
10318
10319 if((SiS_Pr->CP_PreferredX == xres) && (SiS_Pr->CP_PreferredY == yres)) {
10320 SiS_Pr->CP_PreferredIndex = i;
10321 SiS_MakeClockRegs(pSiS->pScrn, SiS_Pr->CP_Clock[i], &SiS_Pr->CP_PrefSR2B, &SiS_Pr->CP_PrefSR2C);
10322 SiS_Pr->CP_PrefClock = (SiS_Pr->CP_Clock[i] / 1000) + 1;
10323 if(!havesync) {
10324 cr37 |= ((((buffer[index + 17] & 0x06) ^ 0x06) << 5) | 0x20);
10325 havesync = TRUE;
10326 }
10327 }
10328
10329 SiS_Pr->CP_HSync_P[i] = (buffer[index + 17] & 0x02) ? TRUE : FALSE;
10330 SiS_Pr->CP_VSync_P[i] = (buffer[index + 17] & 0x04) ? TRUE : FALSE;
10331 SiS_Pr->CP_SyncValid[i] = TRUE;
10332
10333 }
10334 }
10335
10336 cr37 |= 0x10;
10337
10338 }
10339
10340 break;
10341
10342 }
10343
10344 /* 1280x960 panels are always RGB24, unable to scale and use
10345 * high active sync polarity
10346 */
10347 if(pSiS->VGAEngine == SIS_315_VGA) {
10348 if(paneltype == Panel310_1280x960) cr37 &= 0x0e;
10349 } else {
10350 if(paneltype == Panel300_1280x960) cr37 &= 0x0e;
10351 }
10352
10353 for(i = 0; i < 7; i++) {
10354 if(SiS_Pr->CP_DataValid[i]) {
10355 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10356 "Non-standard LCD/DVI-D timing data no. %d:\n", i);
10357 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10358 " HDisplay %d HSync %d HSyncEnd %d HTotal %d\n",
10359 SiS_Pr->CP_HDisplay[i], SiS_Pr->CP_HSyncStart[i],
10360 SiS_Pr->CP_HSyncEnd[i], SiS_Pr->CP_HTotal[i]);
10361 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10362 " VDisplay %d VSync %d VSyncEnd %d VTotal %d\n",
10363 SiS_Pr->CP_VDisplay[i], SiS_Pr->CP_VSyncStart[i],
10364 SiS_Pr->CP_VSyncEnd[i], SiS_Pr->CP_VTotal[i]);
10365 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10366 " Pixel clock: %3.3fMhz\n", (float)SiS_Pr->CP_Clock[i] / 1000);
10367 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO,
10368 " To use this, add \"%dx%d\" to the list of Modes in the Screen section\n",
10369 SiS_Pr->CP_HDisplay[i],
10370 SiS_Pr->CP_VDisplay[i]);
10371 }
10372 }
10373
10374 if(paneltype) {
10375 if(!SiS_Pr->CP_PreferredX) SiS_Pr->CP_PreferredX = SiS_Pr->CP_MaxX;
10376 if(!SiS_Pr->CP_PreferredY) SiS_Pr->CP_PreferredY = SiS_Pr->CP_MaxY;
10377 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x32,0x08);
10378 SiS_SetReg(SiS_Pr->SiS_P3d4,0x36,paneltype);
10379 cr37 &= 0xf1;
10380 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x37,0x0c,cr37);
10381 SiS_Pr->PanelSelfDetected = TRUE;
10382#ifdef TWDEBUG
10383 xf86DrvMsgVerb(pSiS->pScrn->scrnIndex, X_PROBED, 3,
10384 "LCD sense: [DDC LCD results: 0x%02x, 0x%02x]\n", paneltype, cr37);
10385#endif
10386 } else {
10387 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x32,~0x08);
10388 SiS_SetReg(SiS_Pr->SiS_P3d4,0x36,0x00);
10389 }
10390 return 0;
10391}
10392
10393USHORT
10394SiS_SenseVGA2DDC(SiS_Private *SiS_Pr, SISPtr pSiS)
10395{
10396 USHORT DDCdatatype,flag;
10397 BOOLEAN foundcrt = FALSE;
10398 int retry;
10399 unsigned char buffer[256];
10400
10401 if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) return 0;
10402
10403 if(SiS_InitDDCRegs(SiS_Pr, pSiS->VBFlags, pSiS->VGAEngine, 2, 0, FALSE) == 0xFFFF) return 0;
10404
10405 SiS_Pr->SiS_DDC_SecAddr = 0x00;
10406
10407 /* Probe supported DA's */
10408 flag = SiS_ProbeDDC(SiS_Pr);
10409 if(flag & 0x10) {
10410 SiS_Pr->SiS_DDC_DeviceAddr = 0xa6; /* EDID V2 (FP) */
10411 DDCdatatype = 4;
10412 } else if(flag & 0x08) {
10413 SiS_Pr->SiS_DDC_DeviceAddr = 0xa2; /* EDID V2 (P&D-D Monitor) */
10414 DDCdatatype = 3;
10415 } else if(flag & 0x02) {
10416 SiS_Pr->SiS_DDC_DeviceAddr = 0xa0; /* EDID V1 */
10417 DDCdatatype = 1;
10418 } else {
10419 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10420 "VGA2 sense: Do DDC answer\n");
10421 return 0; /* no DDC support (or no device attached) */
10422 }
10423
10424 /* Read the entire EDID */
10425 retry = 2;
10426 do {
10427 if(SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer)) {
10428 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10429 "VGA2 sense: DDC read failed (attempt %d), %s\n",
10430 (3-retry), (retry == 1) ? "giving up" : "retrying");
10431 retry--;
10432 if(retry == 0) return 0xFFFF;
10433 } else break;
10434 } while(1);
10435
10436 /* Analyze EDID. We don't have many chances to
10437 * distinguish a flat panel from a CRT...
10438 */
10439 switch(DDCdatatype) {
10440 case 1:
10441 if(!(checkedid1(buffer))) {
10442 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_ERROR,
10443 "VGA2 sense: EDID corrupt\n");
10444 return 0;
10445 }
10446 if(buffer[0x14] & 0x80) { /* Display uses digital input */
10447 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_ERROR,
10448 "VGA2 sense: Attached display expects digital input\n");
10449 return 0;
10450 }
10451 SiS_Pr->CP_Vendor = buffer[9] | (buffer[8] << 8);
10452 SiS_Pr->CP_Product = buffer[10] | (buffer[11] << 8);
10453 foundcrt = TRUE;
10454 break;
10455 case 3:
10456 case 4:
10457 if(!(checkedid2(buffer))) {
10458 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_ERROR,
10459 "VGA2 sense: EDID corrupt\n");
10460 return 0;
10461 }
10462 if( ((buffer[0x41] & 0x0f) != 0x01) && /* Display does not support analog input */
10463 ((buffer[0x41] & 0x0f) != 0x02) &&
10464 ((buffer[0x41] & 0xf0) != 0x10) &&
10465 ((buffer[0x41] & 0xf0) != 0x20) ) {
10466 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_ERROR,
10467 "VGA2 sense: Attached display does not support analog input (0x%02x)\n",
10468 buffer[0x41]);
10469 return 0;
10470 }
10471 SiS_Pr->CP_Vendor = buffer[2] | (buffer[1] << 8);
10472 SiS_Pr->CP_Product = buffer[3] | (buffer[4] << 8);
10473 foundcrt = TRUE;
10474 break;
10475 }
10476
10477 if(foundcrt) {
10478 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x32,0x10);
10479 }
10480 return(0);
10481}
10482
10483#endif
10484
10485void
10486SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, USHORT tempax,USHORT tempbh)
10487{
10488 USHORT tempbl;
10489
10490 tempbl = SiS_GetCH70xx(SiS_Pr,(tempax & 0x00FF));
10491 tempbl = (((tempbl & tempbh) << 8) | tempax);
10492 SiS_SetCH70xx(SiS_Pr,tempbl);
10493}
10494
10495/* Generic I2C functions for Chrontel & DDC --------- */
10496
10497static void
10498SiS_SetSwitchDDC2(SiS_Private *SiS_Pr)
10499{
10500 SiS_SetSCLKHigh(SiS_Pr);
10501 SiS_WaitRetrace1(SiS_Pr);
10502
10503 SiS_SetSCLKLow(SiS_Pr);
10504 SiS_WaitRetrace1(SiS_Pr);
10505}
10506
10507USHORT
10508SiS_ReadDDC1Bit(SiS_Private *SiS_Pr)
10509{
10510 SiS_WaitRetrace1(SiS_Pr);
10511 return((SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x02) >> 1);
10512}
10513
10514/* Set I2C start condition */
10515/* This is done by a SD high-to-low transition while SC is high */
10516static USHORT
10517SiS_SetStart(SiS_Private *SiS_Pr)
10518{
10519 if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */
10520 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10521 SiS_Pr->SiS_DDC_Index,
10522 SiS_Pr->SiS_DDC_NData,
10523 SiS_Pr->SiS_DDC_Data); /* SD->high */
10524 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */
10525 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10526 SiS_Pr->SiS_DDC_Index,
10527 SiS_Pr->SiS_DDC_NData,
10528 0x00); /* SD->low = start condition */
10529 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->low) */
10530 return 0;
10531}
10532
10533/* Set I2C stop condition */
10534/* This is done by a SD low-to-high transition while SC is high */
10535static USHORT
10536SiS_SetStop(SiS_Private *SiS_Pr)
10537{
10538 if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */
10539 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10540 SiS_Pr->SiS_DDC_Index,
10541 SiS_Pr->SiS_DDC_NData,
10542 0x00); /* SD->low */
10543 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */
10544 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10545 SiS_Pr->SiS_DDC_Index,
10546 SiS_Pr->SiS_DDC_NData,
10547 SiS_Pr->SiS_DDC_Data); /* SD->high = stop condition */
10548 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->high) */
10549 return 0;
10550}
10551
10552/* Write 8 bits of data */
10553static USHORT
10554SiS_WriteDDC2Data(SiS_Private *SiS_Pr, USHORT tempax)
10555{
10556 USHORT i,flag,temp;
10557
10558 flag = 0x80;
10559 for(i=0; i<8; i++) {
10560 SiS_SetSCLKLow(SiS_Pr); /* SC->low */
10561 if(tempax & flag) {
10562 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10563 SiS_Pr->SiS_DDC_Index,
10564 SiS_Pr->SiS_DDC_NData,
10565 SiS_Pr->SiS_DDC_Data); /* Write bit (1) to SD */
10566 } else {
10567 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10568 SiS_Pr->SiS_DDC_Index,
10569 SiS_Pr->SiS_DDC_NData,
10570 0x00); /* Write bit (0) to SD */
10571 }
10572 SiS_SetSCLKHigh(SiS_Pr); /* SC->high */
10573 flag >>= 1;
10574 }
10575 temp = SiS_CheckACK(SiS_Pr); /* Check acknowledge */
10576 return(temp);
10577}
10578
10579static USHORT
10580SiS_ReadDDC2Data(SiS_Private *SiS_Pr, USHORT tempax)
10581{
10582 USHORT i,temp,getdata;
10583
10584 getdata=0;
10585 for(i=0; i<8; i++) {
10586 getdata <<= 1;
10587 SiS_SetSCLKLow(SiS_Pr);
10588 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10589 SiS_Pr->SiS_DDC_Index,
10590 SiS_Pr->SiS_DDC_NData,
10591 SiS_Pr->SiS_DDC_Data);
10592 SiS_SetSCLKHigh(SiS_Pr);
10593 temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
10594 if(temp & SiS_Pr->SiS_DDC_Data) getdata |= 0x01;
10595 }
10596 return(getdata);
10597}
10598
10599static USHORT
10600SiS_SetSCLKLow(SiS_Private *SiS_Pr)
10601{
10602 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10603 SiS_Pr->SiS_DDC_Index,
10604 SiS_Pr->SiS_DDC_NClk,
10605 0x00); /* SetSCLKLow() */
10606 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
10607 return 0;
10608}
10609
10610static USHORT
10611SiS_SetSCLKHigh(SiS_Private *SiS_Pr)
10612{
10613 USHORT temp, watchdog=1000;
10614
10615 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10616 SiS_Pr->SiS_DDC_Index,
10617 SiS_Pr->SiS_DDC_NClk,
10618 SiS_Pr->SiS_DDC_Clk); /* SetSCLKHigh() */
10619 do {
10620 temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
10621 } while((!(temp & SiS_Pr->SiS_DDC_Clk)) && --watchdog);
10622 if (!watchdog) {
10623#ifdef TWDEBUG
10624 xf86DrvMsg(0, X_INFO, "SetClkHigh failed\n");
10625#endif
10626 return 0xFFFF;
10627 }
10628 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
10629 return 0;
10630}
10631
10632/* Check I2C acknowledge */
10633/* Returns 0 if ack ok, non-0 if ack not ok */
10634static USHORT
10635SiS_CheckACK(SiS_Private *SiS_Pr)
10636{
10637 USHORT tempah;
10638
10639 SiS_SetSCLKLow(SiS_Pr); /* (SC->low) */
10640 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10641 SiS_Pr->SiS_DDC_Index,
10642 SiS_Pr->SiS_DDC_NData,
10643 SiS_Pr->SiS_DDC_Data); /* (SD->high) */
10644 SiS_SetSCLKHigh(SiS_Pr); /* SC->high = clock impulse for ack */
10645 tempah = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); /* Read SD */
10646 SiS_SetSCLKLow(SiS_Pr); /* SC->low = end of clock impulse */
10647 if(tempah & SiS_Pr->SiS_DDC_Data) return(1); /* Ack OK if bit = 0 */
10648 else return(0);
10649}
10650
10651/* End of I2C functions ----------------------- */
10652
10653
10654/* =============== SiS 315/330 O.E.M. ================= */
10655
10656#ifdef SIS315H
10657
10658static USHORT
10659GetRAMDACromptr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
10660{
10661 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
10662 USHORT romptr;
10663
10664 if(HwInfo->jChipType < SIS_330) {
10665 romptr = SISGETROMW(0x128);
10666 if(SiS_Pr->SiS_VBType & VB_SIS301B302B)
10667 romptr = SISGETROMW(0x12a);
10668 } else {
10669 romptr = SISGETROMW(0x1a8);
10670 if(SiS_Pr->SiS_VBType & VB_SIS301B302B)
10671 romptr = SISGETROMW(0x1aa);
10672 }
10673 return(romptr);
10674}
10675
10676static USHORT
10677GetLCDromptr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
10678{
10679 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
10680 USHORT romptr;
10681
10682 if(HwInfo->jChipType < SIS_330) {
10683 romptr = SISGETROMW(0x120);
10684 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
10685 romptr = SISGETROMW(0x122);
10686 } else {
10687 romptr = SISGETROMW(0x1a0);
10688 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
10689 romptr = SISGETROMW(0x1a2);
10690 }
10691 return(romptr);
10692}
10693
10694static USHORT
10695GetTVromptr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
10696{
10697 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
10698 USHORT romptr;
10699
10700 if(HwInfo->jChipType < SIS_330) {
10701 romptr = SISGETROMW(0x114);
10702 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
10703 romptr = SISGETROMW(0x11a);
10704 } else {
10705 romptr = SISGETROMW(0x194);
10706 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
10707 romptr = SISGETROMW(0x19a);
10708 }
10709 return(romptr);
10710}
10711
10712static USHORT
10713GetLCDPtrIndexBIOS(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
10714{
10715 USHORT index;
10716
10717 if((IS_SIS650) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
10718 if(!(SiS_IsNotM650orLater(SiS_Pr, HwInfo))) {
10719 if((index = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0)) {
10720 index >>= 4;
10721 index *= 3;
10722 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
10723 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
10724 return index;
10725 }
10726 }
10727 }
10728
10729 index = SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F;
10730 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) index -= 5;
10731 else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 6;
10732 index--;
10733 index *= 3;
10734 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
10735 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
10736 return index;
10737}
10738
10739static USHORT
10740GetLCDPtrIndex(SiS_Private *SiS_Pr)
10741{
10742 USHORT index;
10743
10744 index = ((SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F) - 1) * 3;
10745 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
10746 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
10747 return index;
10748}
10749
10750static USHORT
10751GetTVPtrIndex(SiS_Private *SiS_Pr)
10752{
10753 USHORT index;
10754
10755 index = 0;
10756 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
10757 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index = 2;
10758
10759 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) index = 0;
10760
10761 index <<= 1;
10762
10763 if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) &&
10764 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
10765 index++;
10766 }
10767
10768 return index;
10769}
10770
10771static ULONG
10772GetOEMTVPtr661_2_GEN(SiS_Private *SiS_Pr, int addme)
10773{
10774 USHORT index = 0, temp = 0;
10775
10776 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
10777 if(SiS_Pr->SiS_TVMode & TVSetPALM) index = 2;
10778 if(SiS_Pr->SiS_TVMode & TVSetPALN) index = 3;
10779 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 6;
10780 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
10781 index = 4;
10782 if(SiS_Pr->SiS_TVMode & TVSetPALM) index++;
10783 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 7;
10784 }
10785
10786 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
10787 if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
10788 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
10789 index += addme;
10790 temp++;
10791 }
10792 temp += 0x0100;
10793 }
10794 return(ULONG)(index | (temp << 16));
10795}
10796
10797static ULONG
10798GetOEMTVPtr661_2_OLD(SiS_Private *SiS_Pr)
10799{
10800 return(GetOEMTVPtr661_2_GEN(SiS_Pr, 8));
10801}
10802
10803#if 0
10804static ULONG
10805GetOEMTVPtr661_2_NEW(SiS_Private *SiS_Pr)
10806{
10807 return(GetOEMTVPtr661_2_GEN(SiS_Pr, 6));
10808}
10809#endif
10810
10811static int
10812GetOEMTVPtr661(SiS_Private *SiS_Pr)
10813{
10814 int index = 0;
10815
10816 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 2;
10817 if(SiS_Pr->SiS_ROMNew) {
10818 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 4;
10819 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 6;
10820 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 8;
10821 if(SiS_Pr->SiS_TVMode & TVSetHiVision) index = 10;
10822 } else {
10823 if(SiS_Pr->SiS_TVMode & TVSetHiVision) index = 4;
10824 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 6;
10825 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 8;
10826 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 10;
10827 }
10828
10829 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) index++;
10830
10831 return index;
10832}
10833
10834static void
10835SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
10836{
10837 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
10838 USHORT delay=0,index,myindex,temp,romptr=0;
10839 BOOLEAN dochiptest = TRUE;
10840
10841 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10842 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x20,0xbf);
10843 } else {
10844 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x35,0x7f);
10845 }
10846
10847 /* Find delay (from ROM, internal tables, PCI subsystem) */
10848
10849 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) { /* ------------ VGA */
10850
10851 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10852 romptr = GetRAMDACromptr(SiS_Pr, HwInfo);
10853 }
10854 if(romptr) delay = ROMAddr[romptr];
10855 else {
10856 delay = 0x04;
10857 if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
10858 if(IS_SIS650) {
10859 delay = 0x0a;
10860 } else if(IS_SIS740) {
10861 delay = 0x00;
10862 } else if(HwInfo->jChipType < SIS_330) {
10863 delay = 0x0c;
10864 } else {
10865 delay = 0x0c;
10866 }
10867 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
10868 delay = 0x00;
10869 }
10870 }
10871
10872 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD|SetCRT2ToLCDA)) { /* ---------- LCD/LCDA */
10873
10874 BOOLEAN gotitfrompci = FALSE;
10875
10876 /* Could we detect a PDC for LCD or did we get a user-defined? If yes, use it */
10877
10878 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
10879 if(SiS_Pr->PDC != -1) {
10880 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((SiS_Pr->PDC >> 1) & 0x0f));
10881 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((SiS_Pr->PDC & 0x01) << 7));
10882 return;
10883 }
10884 } else {
10885 if(SiS_Pr->PDCA != -1) {
10886 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((SiS_Pr->PDCA << 3) & 0xf0));
10887 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((SiS_Pr->PDCA & 0x01) << 6));
10888 return;
10889 }
10890 }
10891
10892 /* Custom Panel? */
10893
10894 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) {
10895 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
10896 delay = 0x00;
10897 if((SiS_Pr->PanelXRes <= 1280) && (SiS_Pr->PanelYRes <= 1024)) {
10898 delay = 0x20;
10899 }
10900 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,delay);
10901 } else {
10902 delay = 0x0c;
10903 if(SiS_Pr->SiS_VBType & VB_SIS301C) delay = 0x03;
10904 else if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
10905 if(IS_SIS740) delay = 0x01;
10906 else delay = 0x03;
10907 }
10908 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,delay);
10909 }
10910 return;
10911 }
10912
10913 /* This is a piece of typical SiS crap: They code the OEM LCD
10914 * delay into the code, at no defined place in the BIOS.
10915 * We now have to start doing a PCI subsystem check here.
10916 */
10917
10918 switch(SiS_Pr->SiS_CustomT) {
10919 case CUT_COMPAQ1280:
10920 case CUT_COMPAQ12802:
10921 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
10922 gotitfrompci = TRUE;
10923 dochiptest = FALSE;
10924 delay = 0x03;
10925 }
10926 break;
10927 case CUT_CLEVO1400:
10928 case CUT_CLEVO14002:
10929 gotitfrompci = TRUE;
10930 dochiptest = FALSE;
10931 delay = 0x02;
10932 break;
10933 case CUT_CLEVO1024:
10934 case CUT_CLEVO10242:
10935 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
10936 gotitfrompci = TRUE;
10937 dochiptest = FALSE;
10938 delay = 0x33;
10939 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
10940 delay &= 0x0f;
10941 }
10942 break;
10943 }
10944
10945 /* Could we find it through the PCI ID? If no, use ROM or table */
10946
10947 if(!gotitfrompci) {
10948
10949 index = GetLCDPtrIndexBIOS(SiS_Pr, HwInfo);
10950 myindex = GetLCDPtrIndex(SiS_Pr);
10951
10952 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
10953
10954 if(SiS_IsNotM650orLater(SiS_Pr, HwInfo)) {
10955
10956 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10957 /* Always use the second pointer on 650; some BIOSes */
10958 /* still carry old 301 data at the first location */
10959 /* romptr = SISGETROMW(0x120); */
10960 /* if(SiS_Pr->SiS_VBType & VB_SIS302LV) */
10961 romptr = SISGETROMW(0x122);
10962 if(!romptr) return;
10963 delay = ROMAddr[(romptr + index)];
10964 } else {
10965 delay = SiS310_LCDDelayCompensation_650301LV[myindex];
10966 }
10967
10968 } else {
10969
10970 delay = SiS310_LCDDelayCompensation_651301LV[myindex];
10971 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV))
10972 delay = SiS310_LCDDelayCompensation_651302LV[myindex];
10973
10974 }
10975
10976 } else if(SiS_Pr->SiS_UseROM &&
10977 (!(SiS_Pr->SiS_ROMNew)) &&
10978 (SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) &&
10979 (SiS_Pr->SiS_LCDResInfo != Panel_1280x768) &&
10980 (SiS_Pr->SiS_LCDResInfo != Panel_1280x960)) {
10981
10982 /* Data for 1280x1024 wrong in 301B BIOS */
10983 romptr = GetLCDromptr(SiS_Pr, HwInfo);
10984 if(!romptr) return;
10985 delay = ROMAddr[(romptr + index)];
10986
10987 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
10988
10989 if(IS_SIS740) delay = 0x03;
10990 else delay = 0x00;
10991
10992 } else {
10993
10994 delay = SiS310_LCDDelayCompensation_301[myindex];
10995 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
10996 if(IS_SIS740) delay = 0x01;
10997 else if(HwInfo->jChipType <= SIS_315PRO) delay = SiS310_LCDDelayCompensation_3xx301LV[myindex];
10998 else delay = SiS310_LCDDelayCompensation_650301LV[myindex];
10999 } else if(SiS_Pr->SiS_VBType & VB_SIS301C) {
11000 if(IS_SIS740) delay = 0x01; /* ? */
11001 else delay = 0x03;
11002 } else if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
11003 if(IS_SIS740) delay = 0x01;
11004 else delay = SiS310_LCDDelayCompensation_3xx301B[myindex];
11005 }
11006
11007 }
11008
11009 } /* got it from PCI */
11010
11011 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
11012 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,((delay << 4) & 0xf0));
11013 dochiptest = FALSE;
11014 }
11015
11016 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* ------------ TV */
11017
11018 index = GetTVPtrIndex(SiS_Pr);
11019
11020 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
11021
11022 if(SiS_IsNotM650orLater(SiS_Pr,HwInfo)) {
11023
11024 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
11025 /* Always use the second pointer on 650; some BIOSes */
11026 /* still carry old 301 data at the first location */
11027 /* romptr = SISGETROMW(0x114); */
11028 /* if(SiS_Pr->SiS_VBType & VB_SIS302LV) */
11029 romptr = SISGETROMW(0x11a);
11030 if(!romptr) return;
11031 delay = ROMAddr[romptr + index];
11032
11033 } else {
11034
11035 delay = SiS310_TVDelayCompensation_301B[index];
11036
11037 }
11038
11039 } else {
11040
11041 switch(SiS_Pr->SiS_CustomT) {
11042 case CUT_COMPAQ1280:
11043 case CUT_COMPAQ12802:
11044 case CUT_CLEVO1400:
11045 case CUT_CLEVO14002:
11046 delay = 0x02;
11047 dochiptest = FALSE;
11048 break;
11049 case CUT_CLEVO1024:
11050 case CUT_CLEVO10242:
11051 delay = 0x03;
11052 dochiptest = FALSE;
11053 break;
11054 default:
11055 delay = SiS310_TVDelayCompensation_651301LV[index];
11056 if(SiS_Pr->SiS_VBType & VB_SIS302LV) {
11057 delay = SiS310_TVDelayCompensation_651302LV[index];
11058 }
11059 }
11060 }
11061
11062 } else if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
11063
11064 romptr = GetTVromptr(SiS_Pr, HwInfo);
11065 if(!romptr) return;
11066 delay = ROMAddr[romptr + index];
11067
11068 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
11069
11070 delay = SiS310_TVDelayCompensation_LVDS[index];
11071
11072 } else {
11073
11074 delay = SiS310_TVDelayCompensation_301[index];
11075 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
11076 if(IS_SIS740) {
11077 delay = SiS310_TVDelayCompensation_740301B[index];
11078 /* LV: use 301 data? BIOS bug? */
11079 } else {
11080 delay = SiS310_TVDelayCompensation_301B[index];
11081 if(SiS_Pr->SiS_VBType & VB_SIS301C) delay = 0x02;
11082 }
11083 }
11084
11085 }
11086
11087 if(SiS_LCDAEnabled(SiS_Pr, HwInfo)) {
11088 delay &= 0x0f;
11089 dochiptest = FALSE;
11090 }
11091
11092 } else return;
11093
11094 /* Write delay */
11095
11096 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11097
11098 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && dochiptest) {
11099
11100 temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0) >> 4;
11101 if(temp == 8) { /* 1400x1050 BIOS (COMPAL) */
11102 delay &= 0x0f;
11103 delay |= 0xb0;
11104 } else if(temp == 6) {
11105 delay &= 0x0f;
11106 delay |= 0xc0;
11107 } else if(temp > 7) { /* 1280x1024 BIOS (which one?) */
11108 delay = 0x35;
11109 }
11110 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
11111
11112 } else {
11113
11114 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
11115
11116 }
11117
11118 } else { /* LVDS */
11119
11120 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
11121 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
11122 } else {
11123 if(IS_SIS650 && (SiS_Pr->SiS_IF_DEF_CH70xx != 0)) {
11124 delay <<= 4;
11125 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,delay);
11126 } else {
11127 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
11128 }
11129 }
11130
11131 }
11132
11133}
11134
11135static void
11136SetAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11137 USHORT ModeNo,USHORT ModeIdIndex)
11138{
11139 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11140 USHORT index,temp,temp1,romptr=0;
11141
11142 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p|TVSetYPbPr525p)) return;
11143
11144 if(ModeNo<=0x13)
11145 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex;
11146 else
11147 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex;
11148
11149 temp = GetTVPtrIndex(SiS_Pr);
11150 temp >>= 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
11151 temp1 = temp;
11152
11153 if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
11154 if(HwInfo->jChipType >= SIS_661) {
11155 temp1 = GetOEMTVPtr661(SiS_Pr);
11156 temp1 >>= 1;
11157 romptr = SISGETROMW(0x260);
11158 if(HwInfo->jChipType >= SIS_760) {
11159 romptr = SISGETROMW(0x360);
11160 }
11161 } else if(HwInfo->jChipType >= SIS_330) {
11162 romptr = SISGETROMW(0x192);
11163 } else {
11164 romptr = SISGETROMW(0x112);
11165 }
11166 }
11167
11168 if(romptr) {
11169 temp1 <<= 1;
11170 temp = ROMAddr[romptr + temp1 + index];
11171 } else {
11172 temp = SiS310_TVAntiFlick1[temp][index];
11173 }
11174 temp <<= 4;
11175
11176 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8f,temp); /* index 0A D[6:4] */
11177}
11178
11179static void
11180SetEdgeEnhance(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11181 USHORT ModeNo,USHORT ModeIdIndex)
11182{
11183 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11184 USHORT index,temp,temp1,romptr=0;
11185
11186 temp = temp1 = GetTVPtrIndex(SiS_Pr) >> 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
11187
11188 if(ModeNo <= 0x13)
11189 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;
11190 else
11191 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;
11192
11193 if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
11194 if(HwInfo->jChipType >= SIS_661) {
11195 romptr = SISGETROMW(0x26c);
11196 if(HwInfo->jChipType >= SIS_760) {
11197 romptr = SISGETROMW(0x36c);
11198 }
11199 temp1 = GetOEMTVPtr661(SiS_Pr);
11200 temp1 >>= 1;
11201 } else if(HwInfo->jChipType >= SIS_330) {
11202 romptr = SISGETROMW(0x1a4);
11203 } else {
11204 romptr = SISGETROMW(0x124);
11205 }
11206 }
11207
11208 if(romptr) {
11209 temp1 <<= 1;
11210 temp = ROMAddr[romptr + temp1 + index];
11211 } else {
11212 temp = SiS310_TVEdge1[temp][index];
11213 }
11214 temp <<= 5;
11215 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x3A,0x1F,temp); /* index 0A D[7:5] */
11216}
11217
11218static void
11219SetYFilter(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11220 USHORT ModeNo,USHORT ModeIdIndex)
11221{
11222 USHORT index, temp, i, j;
11223
11224 if(ModeNo <= 0x13) {
11225 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
11226 } else {
11227 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
11228 }
11229
11230 temp = GetTVPtrIndex(SiS_Pr) >> 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
11231
11232 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp = 1; /* NTSC-J uses PAL */
11233 else if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 3; /* PAL-M */
11234 else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 4; /* PAL-N */
11235 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp = 1; /* HiVision uses PAL */
11236
11237 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
11238 for(i=0x35, j=0; i<=0x38; i++, j++) {
11239 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
11240 }
11241 for(i=0x48; i<=0x4A; i++, j++) {
11242 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
11243 }
11244 } else {
11245 for(i=0x35, j=0; i<=0x38; i++, j++) {
11246 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter1[temp][index][j]);
11247 }
11248 }
11249}
11250
11251static void
11252SetPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11253 USHORT ModeNo,USHORT ModeIdIndex)
11254{
11255 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11256 USHORT index,temp,i,j,resinfo,romptr=0;
11257 ULONG lindex;
11258
11259 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
11260
11261 /* NTSC-J data not in BIOS, and already set in SetGroup2 */
11262 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) return;
11263
11264 if((HwInfo->jChipType >= SIS_661) || SiS_Pr->SiS_ROMNew) {
11265 lindex = GetOEMTVPtr661_2_OLD(SiS_Pr) & 0xffff;
11266 lindex <<= 2;
11267 for(j=0, i=0x31; i<=0x34; i++, j++) {
11268 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS661_TVPhase[lindex + j]);
11269 }
11270 return;
11271 }
11272
11273 /* PAL-M, PAL-N not in BIOS, and already set in SetGroup2 */
11274 if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) return;
11275
11276 if(ModeNo<=0x13) {
11277 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
11278 } else {
11279 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
11280 }
11281
11282 temp = GetTVPtrIndex(SiS_Pr);
11283 /* 0: NTSC Graphics, 1: NTSC Text, 2: PAL Graphics,
11284 * 3: PAL Text, 4: HiTV Graphics 5: HiTV Text
11285 */
11286 if(SiS_Pr->SiS_UseROM) {
11287 romptr = SISGETROMW(0x116);
11288 if(HwInfo->jChipType >= SIS_330) {
11289 romptr = SISGETROMW(0x196);
11290 }
11291 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
11292 romptr = SISGETROMW(0x11c);
11293 if(HwInfo->jChipType >= SIS_330) {
11294 romptr = SISGETROMW(0x19c);
11295 }
11296 if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode))) {
11297 romptr = SISGETROMW(0x116);
11298 if(HwInfo->jChipType >= SIS_330) {
11299 romptr = SISGETROMW(0x196);
11300 }
11301 }
11302 }
11303 }
11304 if(romptr) {
11305 romptr += (temp << 2);
11306 for(j=0, i=0x31; i<=0x34; i++, j++) {
11307 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
11308 }
11309 } else {
11310 index = temp % 2;
11311 temp >>= 1; /* 0:NTSC, 1:PAL, 2:HiTV */
11312 for(j=0, i=0x31; i<=0x34; i++, j++) {
11313 if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV))
11314 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
11315 else if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || (SiS_Pr->SiS_TVMode & TVSetTVSimuMode))
11316 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr2[temp][index][j]);
11317 else
11318 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
11319 }
11320 }
11321
11322 if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision))) {
11323 if((!(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetYPbPr525p | TVSetYPbPr750p))) && (ModeNo > 0x13)) {
11324 if((resinfo == SIS_RI_640x480) ||
11325 (resinfo == SIS_RI_800x600)) {
11326 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x21);
11327 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0xf0);
11328 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xf5);
11329 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7f);
11330 } else if(resinfo == SIS_RI_1024x768) {
11331 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x1e);
11332 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0x8b);
11333 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xfb);
11334 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7b);
11335 }
11336 }
11337 }
11338}
11339
11340static void
11341SetDelayComp661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo,
11342 USHORT ModeIdIndex, USHORT RTI)
11343{
11344 USHORT delay = 0, romptr = 0, index, lcdpdcindex;
11345 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11346
11347 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToRAMDAC)))
11348 return;
11349
11350 /* 1. New ROM: VGA2 and LCD/LCDA-Pass1:1 */
11351 /* (If a custom mode is used, Pass1:1 is always set; hence we do this:) */
11352
11353 if(SiS_Pr->SiS_ROMNew) {
11354 if((SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) ||
11355 ((SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
11356 (SiS_Pr->SiS_LCDInfo & LCDPass11))) {
11357 index = 25;
11358 if(SiS_Pr->UseCustomMode) {
11359 index = SiS_Pr->CSRClock;
11360 } else if(ModeNo > 0x13) {
11361 index = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RTI,HwInfo);
11362 index = SiS_Pr->SiS_VCLKData[index].CLOCK;
11363 }
11364 if(index < 25) index = 25;
11365 index = ((index / 25) - 1) << 1;
11366 if((ROMAddr[0x5b] & 0x80) || (SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD))) {
11367 index++;
11368 }
11369 romptr = SISGETROMW(0x104);
11370 delay = ROMAddr[romptr + index];
11371 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD)) {
11372 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
11373 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
11374 } else {
11375 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
11376 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
11377 }
11378 return;
11379 }
11380 }
11381
11382 /* 2. Old ROM: VGA2 and LCD/LCDA-Pass 1:1 */
11383
11384 if(SiS_Pr->UseCustomMode) delay = 0x04;
11385 else if(ModeNo <= 0x13) delay = 0x04;
11386 else delay = (SiS_Pr->SiS_RefIndex[RTI].Ext_PDC >> 4);
11387 delay |= (delay << 8);
11388
11389 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
11390
11391 /* 3. TV */
11392
11393 index = GetOEMTVPtr661(SiS_Pr);
11394 if(SiS_Pr->SiS_ROMNew) {
11395 romptr = SISGETROMW(0x106);
11396 if(SiS_Pr->SiS_VBType & VB_UMC) romptr += 12;
11397 delay = ROMAddr[romptr + index];
11398 } else {
11399 delay = 0x04;
11400 if(index > 3) delay = 0;
11401 }
11402
11403 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11404
11405 /* 4. LCD, LCDA (for new ROM only LV and non-Pass 1:1) */
11406
11407 if( (SiS_Pr->SiS_LCDResInfo != Panel_Custom) &&
11408 ((romptr = GetLCDStructPtr661_2(SiS_Pr, HwInfo))) ) {
11409
11410 lcdpdcindex = (SiS_Pr->SiS_VBType & VB_UMC) ? 14 : 12;
11411
11412 /* For LVDS (and sometimes TMDS), the BIOS must know about the correct value */
11413 delay = ROMAddr[romptr + lcdpdcindex + 1]; /* LCD */
11414 delay |= (ROMAddr[romptr + lcdpdcindex] << 8); /* LCDA */
11415
11416 } else {
11417
11418 /* TMDS: Set our own, since BIOS has no idea */
11419 /* (This is done on >=661 only, since <661 is calling this only for LVDS) */
11420 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
11421 switch(SiS_Pr->SiS_LCDResInfo) {
11422 case Panel_1024x768: delay = 0x0008; break;
11423 case Panel_1280x720: delay = 0x0004; break;
11424 case Panel_1280x768:
11425 case Panel_1280x768_2:delay = 0x0004; break;
11426 case Panel_1280x800:
11427 case Panel_1280x800_2:delay = 0x0004; break; /* Verified for 1280x800 */
11428 case Panel_1280x1024: delay = 0x1e04; break;
11429 case Panel_1400x1050: delay = 0x0004; break;
11430 case Panel_1600x1200: delay = 0x0400; break;
11431 case Panel_1680x1050: delay = 0x0e04; break;
11432 default:
11433 if((SiS_Pr->PanelXRes <= 1024) && (SiS_Pr->PanelYRes <= 768)) {
11434 delay = 0x0008;
11435 } else if((SiS_Pr->PanelXRes == 1280) && (SiS_Pr->PanelYRes == 1024)) {
11436 delay = 0x1e04;
11437 } else if((SiS_Pr->PanelXRes <= 1400) && (SiS_Pr->PanelYRes <= 1050)) {
11438 delay = 0x0004;
11439 } else if((SiS_Pr->PanelXRes <= 1600) && (SiS_Pr->PanelYRes <= 1200)) {
11440 delay = 0x0400;
11441 } else
11442 delay = 0x0e04;
11443 break;
11444 }
11445 }
11446
11447 /* Override by detected or user-set values */
11448 /* (but only if, for some reason, we can't read value from BIOS) */
11449 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->PDC != -1)) {
11450 delay = SiS_Pr->PDC & 0x1f;
11451 }
11452 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) && (SiS_Pr->PDCA != -1)) {
11453 delay = (SiS_Pr->PDCA & 0x1f) << 8;
11454 }
11455
11456 }
11457
11458 }
11459
11460 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
11461 delay >>= 8;
11462 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
11463 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
11464 } else {
11465 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
11466 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
11467 }
11468}
11469
11470static void
11471SetCRT2SyncDither661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo, USHORT RTI)
11472{
11473 USHORT infoflag;
11474 UCHAR temp;
11475
11476 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11477
11478 if(ModeNo <= 0x13) {
11479 infoflag = SiS_GetRegByte(SiS_Pr->SiS_P3ca+2);
11480 } else if(SiS_Pr->UseCustomMode) {
11481 infoflag = SiS_Pr->CInfoFlag;
11482 } else {
11483 infoflag = SiS_Pr->SiS_RefIndex[RTI].Ext_InfoFlag;
11484 }
11485
11486 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
11487 infoflag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37); /* No longer check D5 */
11488 }
11489
11490 infoflag &= 0xc0;
11491
11492 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
11493 temp = (infoflag >> 6) | 0x0c;
11494 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
11495 temp ^= 0x04;
11496 if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x10;
11497 }
11498 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xe0,temp);
11499 } else {
11500 temp = 0x30;
11501 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) temp = 0x20;
11502 temp |= infoflag;
11503 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0f,temp);
11504 temp = 0;
11505 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
11506 if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x80;
11507 }
11508 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0x7f,temp);
11509 }
11510
11511 }
11512}
11513
11514static void
11515SetPanelParms661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
11516{
11517 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11518 USHORT romptr, temp1, temp2;
11519
11520 if(SiS_Pr->SiS_VBType & (VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV)) {
11521 if(SiS_Pr->LVDSHL != -1) {
11522 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
11523 }
11524 }
11525
11526 if(SiS_Pr->SiS_ROMNew) {
11527
11528 if((romptr = GetLCDStructPtr661_2(SiS_Pr, HwInfo))) {
11529 if(SiS_Pr->SiS_VBType & (VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV)) {
11530 temp1 = (ROMAddr[romptr] & 0x03) | 0x0c;
11531 temp2 = 0xfc;
11532 if(SiS_Pr->LVDSHL != -1) {
11533 temp1 &= 0xfc;
11534 temp2 = 0xf3;
11535 }
11536 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,temp2,temp1);
11537 }
11538 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
11539 temp1 = (ROMAddr[romptr + 1] & 0x80) >> 1;
11540 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0d,0xbf,temp1);
11541 }
11542 }
11543
11544 }
11545}
11546
11547static void
11548SiS_OEM310Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11549 USHORT ModeNo,USHORT ModeIdIndex,USHORT RRTI)
11550{
11551 if((SiS_Pr->SiS_ROMNew) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
11552 SetDelayComp661(SiS_Pr,HwInfo,ModeNo,ModeIdIndex,RRTI);
11553 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11554 SetCRT2SyncDither661(SiS_Pr,HwInfo,ModeNo,RRTI);
11555 SetPanelParms661(SiS_Pr,HwInfo);
11556 }
11557 } else {
11558 SetDelayComp(SiS_Pr,HwInfo,ModeNo);
11559 }
11560
11561 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
11562 SetAntiFlicker(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11563 SetPhaseIncr(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11564 SetYFilter(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11565 if(SiS_Pr->SiS_VBType & VB_SIS301) {
11566 SetEdgeEnhance(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11567 }
11568 }
11569}
11570
11571static void
11572SiS_OEM661Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11573 USHORT ModeNo,USHORT ModeIdIndex, USHORT RRTI)
11574{
11575 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11576
11577 SetDelayComp661(SiS_Pr,HwInfo,ModeNo,ModeIdIndex,RRTI);
11578
11579 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11580 SetCRT2SyncDither661(SiS_Pr,HwInfo,ModeNo,RRTI);
11581 SetPanelParms661(SiS_Pr,HwInfo);
11582 }
11583
11584 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
11585 SetPhaseIncr(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11586 SetYFilter(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11587 SetAntiFlicker(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11588 if(SiS_Pr->SiS_VBType & VB_SIS301) {
11589 SetEdgeEnhance(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
11590 }
11591 }
11592 }
11593}
11594
11595/* FinalizeLCD
11596 * This finalizes some CRT2 registers for the very panel used.
11597 * If we have a backup if these registers, we use it; otherwise
11598 * we set the register according to most BIOSes. However, this
11599 * function looks quite different in every BIOS, so you better
11600 * pray that we have a backup...
11601 */
11602static void
11603SiS_FinalizeLCD(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
11604 PSIS_HW_INFO HwInfo)
11605{
11606 USHORT tempcl,tempch,tempbl,tempbh,tempbx,tempax,temp;
11607 USHORT resinfo,modeflag;
11608
11609 if(!(SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) return;
11610 if(SiS_Pr->SiS_ROMNew) return;
11611
11612 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11613 if(SiS_Pr->LVDSHL != -1) {
11614 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
11615 }
11616 }
11617
11618 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
11619 if(SiS_Pr->UseCustomMode) return;
11620
11621 switch(SiS_Pr->SiS_CustomT) {
11622 case CUT_COMPAQ1280:
11623 case CUT_COMPAQ12802:
11624 case CUT_CLEVO1400:
11625 case CUT_CLEVO14002:
11626 return;
11627 }
11628
11629 if(ModeNo <= 0x13) {
11630 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
11631 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
11632 } else {
11633 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
11634 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
11635 }
11636
11637 if(IS_SIS650) {
11638 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4, 0x5f) & 0xf0)) {
11639 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
11640 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x02);
11641 } else {
11642 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
11643 }
11644 }
11645 }
11646
11647 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
11648 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11649 /* Maybe all panels? */
11650 if(SiS_Pr->LVDSHL == -1) {
11651 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
11652 }
11653 return;
11654 }
11655 }
11656
11657 if(SiS_Pr->SiS_CustomT == CUT_CLEVO10242) {
11658 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11659 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11660 if(SiS_Pr->LVDSHL == -1) {
11661 /* Maybe all panels? */
11662 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
11663 }
11664 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
11665 tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
11666 if(tempch == 3) {
11667 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
11668 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
11669 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
11670 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
11671 }
11672 }
11673 return;
11674 }
11675 }
11676 }
11677
11678 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11679 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11680 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
11681 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
11682#ifdef SET_EMI
11683 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
11684#endif
11685 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
11686 }
11687 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
11688 if(SiS_Pr->LVDSHL == -1) {
11689 /* Maybe ACER only? */
11690 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
11691 }
11692 }
11693 tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
11694 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
11695 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
11696 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1f,0x76);
11697 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11698 if(tempch == 0x03) {
11699 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
11700 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
11701 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
11702 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
11703 }
11704 if((SiS_Pr->Backup == TRUE) && (SiS_Pr->Backup_Mode == ModeNo)) {
11705 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,SiS_Pr->Backup_14);
11706 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,SiS_Pr->Backup_15);
11707 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,SiS_Pr->Backup_16);
11708 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,SiS_Pr->Backup_17);
11709 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,SiS_Pr->Backup_18);
11710 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,SiS_Pr->Backup_19);
11711 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,SiS_Pr->Backup_1a);
11712 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,SiS_Pr->Backup_1b);
11713 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,SiS_Pr->Backup_1c);
11714 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,SiS_Pr->Backup_1d);
11715 } else if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { /* 1.10.8w */
11716 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x90);
11717 if(ModeNo <= 0x13) {
11718 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x11);
11719 if((resinfo == 0) || (resinfo == 2)) return;
11720 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x18);
11721 if((resinfo == 1) || (resinfo == 3)) return;
11722 }
11723 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
11724 if((ModeNo > 0x13) && (resinfo == SIS_RI_1024x768)) {
11725 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02); /* 1.10.7u */
11726#if 0
11727 tempbx = 806; /* 0x326 */ /* other older BIOSes */
11728 tempbx--;
11729 temp = tempbx & 0xff;
11730 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);
11731 temp = (tempbx >> 8) & 0x03;
11732 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1d,0xf8,temp);
11733#endif
11734 }
11735 } else if(ModeNo <= 0x13) {
11736 if(ModeNo <= 1) {
11737 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x70);
11738 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xff);
11739 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
11740 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
11741 }
11742 if(!(modeflag & HalfDCLK)) {
11743 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x20);
11744 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,0x1a);
11745 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,0x28);
11746 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,0x00);
11747 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x4c);
11748 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
11749 if(ModeNo == 0x12) {
11750 switch(tempch) {
11751 case 0:
11752 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
11753 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
11754 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,0x10);
11755 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
11756 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x48);
11757 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
11758 break;
11759 case 2:
11760 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
11761 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
11762 break;
11763 case 3:
11764 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
11765 break;
11766 }
11767 }
11768 }
11769 }
11770 }
11771 } else {
11772 tempcl = tempbh = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
11773 tempcl &= 0x0f;
11774 tempbh &= 0x70;
11775 tempbh >>= 4;
11776 tempbl = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x04);
11777 tempbx = (tempbh << 8) | tempbl;
11778 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11779 if((resinfo == SIS_RI_1024x768) || (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD))) {
11780 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
11781 tempbx = 770;
11782 } else {
11783 if(tempbx > 770) tempbx = 770;
11784 if(SiS_Pr->SiS_VGAVDE < 600) {
11785 tempax = 768 - SiS_Pr->SiS_VGAVDE;
11786 tempax >>= 4; /* 1.10.7w; 1.10.6s: 3; */
11787 if(SiS_Pr->SiS_VGAVDE <= 480) tempax >>= 4; /* 1.10.7w; 1.10.6s: < 480; >>=1; */
11788 tempbx -= tempax;
11789 }
11790 }
11791 } else return;
11792 }
11793 temp = tempbx & 0xff;
11794 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,temp);
11795 temp = ((tempbx & 0xff00) >> 4) | tempcl;
11796 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,temp);
11797 }
11798 }
11799}
11800
11801#endif
11802
11803/* ================= SiS 300 O.E.M. ================== */
11804
11805#ifdef SIS300
11806
11807static void
11808SetOEMLCDData2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11809 USHORT ModeNo,USHORT ModeIdIndex, USHORT RefTabIndex)
11810{
11811 USHORT crt2crtc=0, modeflag, myindex=0;
11812 UCHAR temp;
11813 int i;
11814
11815 if(ModeNo <= 0x13) {
11816 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
11817 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
11818 } else {
11819 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
11820 crt2crtc = SiS_Pr->SiS_RefIndex[RefTabIndex].Ext_CRT2CRTC;
11821 }
11822
11823 crt2crtc &= 0x3f;
11824
11825 if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
11826 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xdf);
11827 }
11828
11829 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
11830 if(modeflag & HalfDCLK) myindex = 1;
11831
11832 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
11833 for(i=0; i<7; i++) {
11834 if(barco_p1[myindex][crt2crtc][i][0]) {
11835 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,
11836 barco_p1[myindex][crt2crtc][i][0],
11837 barco_p1[myindex][crt2crtc][i][2],
11838 barco_p1[myindex][crt2crtc][i][1]);
11839 }
11840 }
11841 }
11842 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
11843 if(temp & 0x80) {
11844 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x18);
11845 temp++;
11846 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);
11847 }
11848 }
11849}
11850
11851static USHORT
11852GetOEMLCDPtr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, int Flag)
11853{
11854 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11855 USHORT tempbx=0,romptr=0;
11856 UCHAR customtable300[] = {
11857 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
11858 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
11859 };
11860 UCHAR customtable630[] = {
11861 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
11862 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
11863 };
11864
11865 if(HwInfo->jChipType == SIS_300) {
11866
11867 tempbx = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0x0f;
11868 if(SiS_Pr->SiS_VBType & VB_SIS301) tempbx &= 0x07;
11869 tempbx -= 2;
11870 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 4;
11871 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11872 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 3;
11873 }
11874 if(SiS_Pr->SiS_UseROM) {
11875 if(ROMAddr[0x235] & 0x80) {
11876 tempbx = SiS_Pr->SiS_LCDTypeInfo;
11877 if(Flag) {
11878 romptr = SISGETROMW(0x255);
11879 if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
11880 else tempbx = customtable300[SiS_Pr->SiS_LCDTypeInfo];
11881 if(tempbx == 0xFF) return 0xFFFF;
11882 }
11883 tempbx <<= 1;
11884 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
11885 }
11886 }
11887
11888 } else {
11889
11890 if(Flag) {
11891 if(SiS_Pr->SiS_UseROM) {
11892 romptr = SISGETROMW(0x255);
11893 if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
11894 else tempbx = 0xff;
11895 } else {
11896 tempbx = customtable630[SiS_Pr->SiS_LCDTypeInfo];
11897 }
11898 if(tempbx == 0xFF) return 0xFFFF;
11899 tempbx <<= 2;
11900 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
11901 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
11902 return tempbx;
11903 }
11904 tempbx = SiS_Pr->SiS_LCDTypeInfo << 2;
11905 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
11906 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
11907
11908 }
11909
11910 return tempbx;
11911}
11912
11913static void
11914SetOEMLCDDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11915 USHORT ModeNo,USHORT ModeIdIndex)
11916{
11917 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11918 USHORT index,temp,romptr=0;
11919
11920 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
11921
11922 if(SiS_Pr->SiS_UseROM) {
11923 if(!(ROMAddr[0x237] & 0x01)) return;
11924 if(!(ROMAddr[0x237] & 0x02)) return;
11925 romptr = SISGETROMW(0x24b);
11926 }
11927
11928 /* The Panel Compensation Delay should be set according to tables
11929 * here. Unfortunately, various BIOS versions don't case about
11930 * a uniform way using eg. ROM byte 0x220, but use different
11931 * hard coded delays (0x04, 0x20, 0x18) in SetGroup1().
11932 * Thus we don't set this if the user select a custom pdc or if
11933 * we otherwise detected a valid pdc.
11934 */
11935 if(SiS_Pr->PDC != -1) return;
11936
11937 temp = GetOEMLCDPtr(SiS_Pr,HwInfo, 0);
11938
11939 if(SiS_Pr->UseCustomMode)
11940 index = 0;
11941 else
11942 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
11943
11944 if(HwInfo->jChipType != SIS_300) {
11945 if(romptr) {
11946 romptr += (temp * 2);
11947 romptr = SISGETROMW(romptr);
11948 romptr += index;
11949 temp = ROMAddr[romptr];
11950 } else {
11951 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11952 temp = SiS300_OEMLCDDelay2[temp][index];
11953 } else {
11954 temp = SiS300_OEMLCDDelay3[temp][index];
11955 }
11956 }
11957 } else {
11958 if(SiS_Pr->SiS_UseROM && (ROMAddr[0x235] & 0x80)) {
11959 if(romptr) {
11960 romptr += (temp * 2);
11961 romptr = SISGETROMW(romptr);
11962 romptr += index;
11963 temp = ROMAddr[romptr];
11964 } else {
11965 temp = SiS300_OEMLCDDelay5[temp][index];
11966 }
11967 } else {
11968 if(SiS_Pr->SiS_UseROM) {
11969 romptr = ROMAddr[0x249] | (ROMAddr[0x24a] << 8);
11970 if(romptr) {
11971 romptr += (temp * 2);
11972 romptr = SISGETROMW(romptr);
11973 romptr += index;
11974 temp = ROMAddr[romptr];
11975 } else {
11976 temp = SiS300_OEMLCDDelay4[temp][index];
11977 }
11978 } else {
11979 temp = SiS300_OEMLCDDelay4[temp][index];
11980 }
11981 }
11982 }
11983 temp &= 0x3c;
11984 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* index 0A D[6:4] */
11985}
11986
11987static void
11988SetOEMLCDData(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11989 USHORT ModeNo,USHORT ModeIdIndex)
11990{
11991#if 0 /* Unfinished; Data table missing */
11992 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
11993 USHORT index,temp;
11994
11995 if((SiS_Pr->SiS_UseROM) {
11996 if(!(ROMAddr[0x237] & 0x01)) return;
11997 if(!(ROMAddr[0x237] & 0x04)) return;
11998 /* No rom pointer in BIOS header! */
11999 }
12000
12001 temp = GetOEMLCDPtr(SiS_Pr,HwInfo, 1);
12002 if(temp = 0xFFFF) return;
12003
12004 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDHIndex;
12005 for(i=0x14, j=0; i<=0x17; i++, j++) {
12006 SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDHData[temp][index][j]);
12007 }
12008 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1a, 0xf8, (SiS300_LCDHData[temp][index][j] & 0x07));
12009
12010 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDVIndex;
12011 SiS_SetReg(SiS_SiS_Part1Port,0x18, SiS300_LCDVData[temp][index][0]);
12012 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x19, 0xF0, SiS300_LCDVData[temp][index][1]);
12013 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1A, 0xC7, (SiS300_LCDVData[temp][index][2] & 0x38));
12014 for(i=0x1b, j=3; i<=0x1d; i++, j++) {
12015 SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDVData[temp][index][j]);
12016 }
12017#endif
12018}
12019
12020static USHORT
12021GetOEMTVPtr(SiS_Private *SiS_Pr)
12022{
12023 USHORT index;
12024
12025 index = 0;
12026 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) index += 4;
12027 if(SiS_Pr->SiS_VBType & VB_SISVB) {
12028 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) index += 2;
12029 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index += 3;
12030 else if(SiS_Pr->SiS_TVMode & TVSetPAL) index += 1;
12031 } else {
12032 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) index += 2;
12033 if(SiS_Pr->SiS_TVMode & TVSetPAL) index += 1;
12034 }
12035 return index;
12036}
12037
12038static void
12039SetOEMTVDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
12040 USHORT ModeNo,USHORT ModeIdIndex)
12041{
12042 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
12043 USHORT index,temp,romptr=0;
12044
12045 if(SiS_Pr->SiS_UseROM) {
12046 if(!(ROMAddr[0x238] & 0x01)) return;
12047 if(!(ROMAddr[0x238] & 0x02)) return;
12048 romptr = SISGETROMW(0x241);
12049 }
12050
12051 temp = GetOEMTVPtr(SiS_Pr);
12052
12053 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVDelayIndex;
12054
12055 if(romptr) {
12056 romptr += (temp * 2);
12057 romptr = SISGETROMW(romptr);
12058 romptr += index;
12059 temp = ROMAddr[romptr];
12060 } else {
12061 if(SiS_Pr->SiS_VBType & VB_SISVB) {
12062 temp = SiS300_OEMTVDelay301[temp][index];
12063 } else {
12064 temp = SiS300_OEMTVDelayLVDS[temp][index];
12065 }
12066 }
12067 temp &= 0x3c;
12068 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);
12069}
12070
12071static void
12072SetOEMAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
12073 USHORT ModeNo, USHORT ModeIdIndex)
12074{
12075 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
12076 USHORT index,temp,romptr=0;
12077
12078 if(SiS_Pr->SiS_UseROM) {
12079 if(!(ROMAddr[0x238] & 0x01)) return;
12080 if(!(ROMAddr[0x238] & 0x04)) return;
12081 romptr = SISGETROMW(0x243);
12082 }
12083
12084 temp = GetOEMTVPtr(SiS_Pr);
12085
12086 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVFlickerIndex;
12087
12088 if(romptr) {
12089 romptr += (temp * 2);
12090 romptr = SISGETROMW(romptr);
12091 romptr += index;
12092 temp = ROMAddr[romptr];
12093 } else {
12094 temp = SiS300_OEMTVFlicker[temp][index];
12095 }
12096 temp &= 0x70;
12097 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8F,temp);
12098}
12099
12100static void
12101SetOEMPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
12102 USHORT ModeNo,USHORT ModeIdIndex)
12103{
12104 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
12105 USHORT index,i,j,temp,romptr=0;
12106
12107 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) return;
12108
12109 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetNTSCJ | TVSetPALM | TVSetPALN)) return;
12110
12111 if(SiS_Pr->SiS_UseROM) {
12112 if(!(ROMAddr[0x238] & 0x01)) return;
12113 if(!(ROMAddr[0x238] & 0x08)) return;
12114 romptr = SISGETROMW(0x245);
12115 }
12116
12117 temp = GetOEMTVPtr(SiS_Pr);
12118
12119 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVPhaseIndex;
12120
12121 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
12122 for(i=0x31, j=0; i<=0x34; i++, j++) {
12123 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase2[temp][index][j]);
12124 }
12125 } else {
12126 if(romptr) {
12127 romptr += (temp * 2);
12128 romptr = SISGETROMW(romptr);
12129 romptr += (index * 4);
12130 for(i=0x31, j=0; i<=0x34; i++, j++) {
12131 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
12132 }
12133 } else {
12134 for(i=0x31, j=0; i<=0x34; i++, j++) {
12135 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase1[temp][index][j]);
12136 }
12137 }
12138 }
12139}
12140
12141static void
12142SetOEMYFilter(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
12143 USHORT ModeNo,USHORT ModeIdIndex)
12144{
12145 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
12146 USHORT index,temp,i,j,romptr=0;
12147
12148 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSCART | SetCRT2ToHiVision | SetCRT2ToYPbPr525750)) return;
12149
12150 if(SiS_Pr->SiS_UseROM) {
12151 if(!(ROMAddr[0x238] & 0x01)) return;
12152 if(!(ROMAddr[0x238] & 0x10)) return;
12153 romptr = SISGETROMW(0x247);
12154 }
12155
12156 temp = GetOEMTVPtr(SiS_Pr);
12157
12158 if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
12159 else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 9;
12160 /* NTSCJ uses NTSC filters */
12161
12162 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVYFilterIndex;
12163
12164 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
12165 for(i=0x35, j=0; i<=0x38; i++, j++) {
12166 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
12167 }
12168 for(i=0x48; i<=0x4A; i++, j++) {
12169 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
12170 }
12171 } else {
12172 if((romptr) && (!(SiS_Pr->SiS_TVMode & (TVSetPALM|TVSetPALN)))) {
12173 romptr += (temp * 2);
12174 romptr = SISGETROMW(romptr);
12175 romptr += (index * 4);
12176 for(i=0x35, j=0; i<=0x38; i++, j++) {
12177 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
12178 }
12179 } else {
12180 for(i=0x35, j=0; i<=0x38; i++, j++) {
12181 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter1[temp][index][j]);
12182 }
12183 }
12184 }
12185}
12186
12187static USHORT
12188SiS_SearchVBModeID(SiS_Private *SiS_Pr, USHORT *ModeNo)
12189{
12190 USHORT ModeIdIndex;
12191 UCHAR VGAINFO = SiS_Pr->SiS_VGAINFO;
12192
12193 if(*ModeNo <= 5) *ModeNo |= 1;
12194
12195 for(ModeIdIndex=0; ; ModeIdIndex++) {
12196 if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == *ModeNo) break;
12197 if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == 0xFF) return 0;
12198 }
12199
12200 if(*ModeNo != 0x07) {
12201 if(*ModeNo > 0x03) return ModeIdIndex;
12202 if(VGAINFO & 0x80) return ModeIdIndex;
12203 ModeIdIndex++;
12204 }
12205
12206 if(VGAINFO & 0x10) ModeIdIndex++; /* 400 lines */
12207 /* else 350 lines */
12208 return ModeIdIndex;
12209}
12210
12211static void
12212SiS_OEM300Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
12213 USHORT ModeNo, USHORT ModeIdIndex, USHORT RefTableIndex)
12214{
12215 USHORT OEMModeIdIndex=0;
12216
12217 if(!SiS_Pr->UseCustomMode) {
12218 OEMModeIdIndex = SiS_SearchVBModeID(SiS_Pr,&ModeNo);
12219 if(!(OEMModeIdIndex)) return;
12220 }
12221
12222 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
12223 SetOEMLCDDelay(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
12224 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
12225 SetOEMLCDData(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
12226 }
12227 }
12228 if(SiS_Pr->UseCustomMode) return;
12229 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
12230 SetOEMTVDelay(SiS_Pr, HwInfo, ModeNo,OEMModeIdIndex);
12231 if(SiS_Pr->SiS_VBType & VB_SISVB) {
12232 SetOEMAntiFlicker(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
12233 SetOEMPhaseIncr(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
12234 SetOEMYFilter(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
12235 }
12236 }
12237}
12238#endif
12239
diff --git a/drivers/video/sis/init301.h b/drivers/video/sis/init301.h
new file mode 100644
index 000000000000..f05aebc994b4
--- /dev/null
+++ b/drivers/video/sis/init301.h
@@ -0,0 +1,410 @@
1/* $XFree86$ */
2/* $XdotOrg$ */
3/*
4 * Data and prototypes for init301.c
5 *
6 * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
7 *
8 * If distributed as part of the Linux kernel, the following license terms
9 * apply:
10 *
11 * * This program is free software; you can redistribute it and/or modify
12 * * it under the terms of the GNU General Public License as published by
13 * * the Free Software Foundation; either version 2 of the named License,
14 * * or any later version.
15 * *
16 * * This program is distributed in the hope that it will be useful,
17 * * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * * GNU General Public License for more details.
20 * *
21 * * You should have received a copy of the GNU General Public License
22 * * along with this program; if not, write to the Free Software
23 * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
24 *
25 * Otherwise, the following license terms apply:
26 *
27 * * Redistribution and use in source and binary forms, with or without
28 * * modification, are permitted provided that the following conditions
29 * * are met:
30 * * 1) Redistributions of source code must retain the above copyright
31 * * notice, this list of conditions and the following disclaimer.
32 * * 2) Redistributions in binary form must reproduce the above copyright
33 * * notice, this list of conditions and the following disclaimer in the
34 * * documentation and/or other materials provided with the distribution.
35 * * 3) The name of the author may not be used to endorse or promote products
36 * * derived from this software without specific prior written permission.
37 * *
38 * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
39 * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
40 * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
41 * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
42 * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
43 * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
44 * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
45 * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46 * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
47 * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48 *
49 * Author: Thomas Winischhofer <thomas@winischhofer.net>
50 *
51 */
52
53#ifndef _INIT301_
54#define _INIT301_
55
56#include "osdef.h"
57#include "initdef.h"
58
59#ifdef LINUX_XF86
60#include "sis.h"
61#include "sis_regs.h"
62#endif
63
64#ifdef LINUX_KERNEL
65#include "vgatypes.h"
66#include "vstruct.h"
67#ifdef SIS_CP
68#undef SIS_CP
69#endif
70#include <linux/config.h>
71#include <linux/version.h>
72#include <asm/io.h>
73#include <linux/types.h>
74#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
75#include <linux/sisfb.h>
76#else
77#include <video/sisfb.h>
78#endif
79#endif
80
81static const UCHAR SiS_YPbPrTable[3][64] = {
82 {
83 0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c,
84 0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a,
85 0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x1b,
86 0x0c,0x50,0x00,0x97,0x00,0xda,0x4a,0x17,
87 0x7d,0x05,0x4b,0x00,0x00,0xe2,0x00,0x02,
88 0x03,0x0a,0x65,0x9d /*0x8d*/,0x08,0x92,0x8f,0x40,
89 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x53 /*0x50*/,
90 0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00
91 },
92 {
93 0x1d,0x11,0x06,0x09,0x0b,0x0c,0x0c,0x0c,
94 0x98,0x0a,0x01,0x0d,0x06,0x0d,0x04,0x0a,
95 0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x3f,
96 0x0c,0x50,0xb2,0x9f,0x16,0x59,0x4c /*0x4f*/,0x13,
97 0xad,0x11,0xad,0x1d,0x40,0x8a,0x3d,0xb8,
98 0x51,0x5e,0x60,0x57 /*0x49*/,0x7b /*0x7d*/,0x92,0x0f,0x40,
99 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x4b,
100 0x43,0x41,0x11,0x00,0xfc,0xff,0x32,0x00
101 },
102 {
103#if 1
104 0x13,0x1d,0xe8,0x09,0x09,0xed,0x0c,0x0c,
105 0x98,0x0a,0x01,0x0c,0x06,0x0d,0x04,0x0a,
106 0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x3f,
107 0xed,0x50,0x70,0x9f,0x16,0x59,0x21 /*0x2b*/,0x13,
108 0x27,0x0b,0x27,0xfc,0x30,0x27,0x1c,0xb0,
109 0x4b,0x4b,0x65 /*0x6f*/,0x2f,0x63,0x92,0x0f,0x40,
110 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x27,
111 0x00,0x40,0x11,0x00,0xfc,0xff,0x32,0x00
112#endif
113#if 0
114 0x2a,0x14,0xe8,0x09,0x09,0xed,0x0c,0x0c, /* TEST (0.93) - BAD */
115 0x98,0x0a,0x01,0x0c,0x06,0x0d,0x04,0x0a,
116 0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x3f,
117 0xed,0x50,0x70,0x9e,0x16,0x57,0x6c,0x13,
118 0x27,0x0b,0x27,0xfb,0x30,0x27,0x15,0xb0,
119 0x3b,0xdb,0x61,0x24,0x78,0x92,0x0f,0xff,
120 0xff,0xff,0xff,0xff,0xff,0xff,0x14,0x6f,
121 0x00,0x52,0xbb,0x00,0xd5,0xf7,0xa2,0x00
122#endif
123 }
124};
125
126static const UCHAR SiS_HiTVGroup3_1[] = {
127 0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x13,
128 0xb1, 0x41, 0x62, 0x62, 0xff, 0xf4, 0x45, 0xa6,
129 0x25, 0x2f, 0x67, 0xf6, 0xbf, 0xff, 0x8e, 0x20,
130 0xac, 0xda, 0x60, 0xfe, 0x6a, 0x9a, 0x06, 0x10,
131 0xd1, 0x04, 0x18, 0x0a, 0xff, 0x80, 0x00, 0x80,
132 0x3b, 0x77, 0x00, 0xef, 0xe0, 0x10, 0xb0, 0xe0,
133 0x10, 0x4f, 0x0f, 0x0f, 0x05, 0x0f, 0x08, 0x6e,
134 0x1a, 0x1f, 0x25, 0x2a, 0x4c, 0xaa, 0x01
135};
136
137static const UCHAR SiS_HiTVGroup3_2[] = {
138 0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x7a,
139 0x54, 0x41, 0xe7, 0xe7, 0xff, 0xf4, 0x45, 0xa6,
140 0x25, 0x2f, 0x67, 0xf6, 0xbf, 0xff, 0x8e, 0x20,
141 0xac, 0x6a, 0x60, 0x2b, 0x52, 0xcd, 0x61, 0x10,
142 0x51, 0x04, 0x18, 0x0a, 0x1f, 0x80, 0x00, 0x80,
143 0xff, 0xa4, 0x04, 0x2b, 0x94, 0x21, 0x72, 0x94,
144 0x26, 0x05, 0x01, 0x0f, 0xed, 0x0f, 0x0a, 0x64,
145 0x18, 0x1d, 0x23, 0x28, 0x4c, 0xaa, 0x01
146};
147
148/* 301C / 302ELV extended Part2 TV registers (4 tap scaler) */
149
150static const UCHAR SiS_Part2CLVX_1[] = {
151 0x00,0x00,
152 0x00,0x20,0x00,0x00,0x7F,0x20,0x02,0x7F,0x7D,0x20,0x04,0x7F,0x7D,0x1F,0x06,0x7E,
153 0x7C,0x1D,0x09,0x7E,0x7C,0x1B,0x0B,0x7E,0x7C,0x19,0x0E,0x7D,0x7C,0x17,0x11,0x7C,
154 0x7C,0x14,0x14,0x7C,0x7C,0x11,0x17,0x7C,0x7D,0x0E,0x19,0x7C,0x7E,0x0B,0x1B,0x7C,
155 0x7E,0x09,0x1D,0x7C,0x7F,0x06,0x1F,0x7C,0x7F,0x04,0x20,0x7D,0x00,0x02,0x20,0x7E
156};
157
158static const UCHAR SiS_Part2CLVX_2[] = {
159 0x00,0x00,
160 0x00,0x20,0x00,0x00,0x7F,0x20,0x02,0x7F,0x7D,0x20,0x04,0x7F,0x7D,0x1F,0x06,0x7E,
161 0x7C,0x1D,0x09,0x7E,0x7C,0x1B,0x0B,0x7E,0x7C,0x19,0x0E,0x7D,0x7C,0x17,0x11,0x7C,
162 0x7C,0x14,0x14,0x7C,0x7C,0x11,0x17,0x7C,0x7D,0x0E,0x19,0x7C,0x7E,0x0B,0x1B,0x7C,
163 0x7E,0x09,0x1D,0x7C,0x7F,0x06,0x1F,0x7C,0x7F,0x04,0x20,0x7D,0x00,0x02,0x20,0x7E
164};
165
166static const UCHAR SiS_Part2CLVX_3[] = { /* NTSC, 525i, 525p */
167 0xE0,0x01,
168 0x04,0x1A,0x04,0x7E,0x03,0x1A,0x06,0x7D,0x01,0x1A,0x08,0x7D,0x00,0x19,0x0A,0x7D,
169 0x7F,0x19,0x0C,0x7C,0x7E,0x18,0x0E,0x7C,0x7E,0x17,0x10,0x7B,0x7D,0x15,0x12,0x7C,
170 0x7D,0x13,0x13,0x7D,0x7C,0x12,0x15,0x7D,0x7C,0x10,0x17,0x7D,0x7C,0x0E,0x18,0x7E,
171 0x7D,0x0C,0x19,0x7E,0x7D,0x0A,0x19,0x00,0x7D,0x08,0x1A,0x01,0x7E,0x06,0x1A,0x02,
172 0x58,0x02,
173 0x07,0x14,0x07,0x7E,0x06,0x14,0x09,0x7D,0x05,0x14,0x0A,0x7D,0x04,0x13,0x0B,0x7E,
174 0x03,0x13,0x0C,0x7E,0x02,0x12,0x0D,0x7F,0x01,0x12,0x0E,0x7F,0x01,0x11,0x0F,0x7F,
175 0x00,0x10,0x10,0x00,0x7F,0x0F,0x11,0x01,0x7F,0x0E,0x12,0x01,0x7E,0x0D,0x12,0x03,
176 0x7E,0x0C,0x13,0x03,0x7E,0x0B,0x13,0x04,0x7E,0x0A,0x14,0x04,0x7D,0x09,0x14,0x06,
177 0x00,0x03,
178 0x09,0x0F,0x09,0x7F,0x08,0x0F,0x09,0x00,0x07,0x0F,0x0A,0x00,0x06,0x0F,0x0A,0x01,
179 0x06,0x0E,0x0B,0x01,0x05,0x0E,0x0B,0x02,0x04,0x0E,0x0C,0x02,0x04,0x0D,0x0C,0x03,
180 0x03,0x0D,0x0D,0x03,0x02,0x0C,0x0D,0x05,0x02,0x0C,0x0E,0x04,0x01,0x0B,0x0E,0x06,
181 0x01,0x0B,0x0E,0x06,0x00,0x0A,0x0F,0x07,0x00,0x0A,0x0F,0x07,0x00,0x09,0x0F,0x08,
182 0xFF,0xFF
183};
184
185static const UCHAR SiS_Part2CLVX_4[] = { /* PAL */
186 0x58,0x02,
187 0x05,0x19,0x05,0x7D,0x03,0x19,0x06,0x7E,0x02,0x19,0x08,0x7D,0x01,0x18,0x0A,0x7D,
188 0x00,0x18,0x0C,0x7C,0x7F,0x17,0x0E,0x7C,0x7E,0x16,0x0F,0x7D,0x7E,0x14,0x11,0x7D,
189 0x7D,0x13,0x13,0x7D,0x7D,0x11,0x14,0x7E,0x7D,0x0F,0x16,0x7E,0x7D,0x0E,0x17,0x7E,
190 0x7D,0x0C,0x18,0x7F,0x7D,0x0A,0x18,0x01,0x7D,0x08,0x19,0x02,0x7D,0x06,0x19,0x04,
191 0x00,0x03,
192 0x08,0x12,0x08,0x7E,0x07,0x12,0x09,0x7E,0x06,0x12,0x0A,0x7E,0x05,0x11,0x0B,0x7F,
193 0x04,0x11,0x0C,0x7F,0x03,0x11,0x0C,0x00,0x03,0x10,0x0D,0x00,0x02,0x0F,0x0E,0x01,
194 0x01,0x0F,0x0F,0x01,0x01,0x0E,0x0F,0x02,0x00,0x0D,0x10,0x03,0x7F,0x0C,0x11,0x04,
195 0x7F,0x0C,0x11,0x04,0x7F,0x0B,0x11,0x05,0x7E,0x0A,0x12,0x06,0x7E,0x09,0x12,0x07,
196 0x40,0x02,
197 0x04,0x1A,0x04,0x7E,0x02,0x1B,0x05,0x7E,0x01,0x1A,0x07,0x7E,0x00,0x1A,0x09,0x7D,
198 0x7F,0x19,0x0B,0x7D,0x7E,0x18,0x0D,0x7D,0x7D,0x17,0x10,0x7C,0x7D,0x15,0x12,0x7C,
199 0x7C,0x14,0x14,0x7C,0x7C,0x12,0x15,0x7D,0x7C,0x10,0x17,0x7D,0x7C,0x0D,0x18,0x7F,
200 0x7D,0x0B,0x19,0x7F,0x7D,0x09,0x1A,0x00,0x7D,0x07,0x1A,0x02,0x7E,0x05,0x1B,0x02,
201 0xFF,0xFF
202};
203
204static const UCHAR SiS_Part2CLVX_5[] = { /* 750p */
205 0x00,0x03,
206 0x05,0x19,0x05,0x7D,0x03,0x19,0x06,0x7E,0x02,0x19,0x08,0x7D,0x01,0x18,0x0A,0x7D,
207 0x00,0x18,0x0C,0x7C,0x7F,0x17,0x0E,0x7C,0x7E,0x16,0x0F,0x7D,0x7E,0x14,0x11,0x7D,
208 0x7D,0x13,0x13,0x7D,0x7D,0x11,0x14,0x7E,0x7D,0x0F,0x16,0x7E,0x7D,0x0E,0x17,0x7E,
209 0x7D,0x0C,0x18,0x7F,0x7D,0x0A,0x18,0x01,0x7D,0x08,0x19,0x02,0x7D,0x06,0x19,0x04,
210 0xFF,0xFF
211};
212
213static const UCHAR SiS_Part2CLVX_6[] = { /* 1080i */
214 0x00,0x04,
215 0x04,0x1A,0x04,0x7E,0x02,0x1B,0x05,0x7E,0x01,0x1A,0x07,0x7E,0x00,0x1A,0x09,0x7D,
216 0x7F,0x19,0x0B,0x7D,0x7E,0x18,0x0D,0x7D,0x7D,0x17,0x10,0x7C,0x7D,0x15,0x12,0x7C,
217 0x7C,0x14,0x14,0x7C,0x7C,0x12,0x15,0x7D,0x7C,0x10,0x17,0x7D,0x7C,0x0D,0x18,0x7F,
218 0x7D,0x0B,0x19,0x7F,0x7D,0x09,0x1A,0x00,0x7D,0x07,0x1A,0x02,0x7E,0x05,0x1B,0x02,
219 0xFF,0xFF,
220};
221
222#ifdef SIS315H
223/* 661 et al LCD data structure (2.03.00) */
224static const UCHAR SiS_LCDStruct661[] = {
225 /* 1024x768 */
226/* type|CR37| HDE | VDE | HT | VT | hss | hse */
227 0x02,0xC0,0x00,0x04,0x00,0x03,0x40,0x05,0x26,0x03,0x10,0x00,0x88,
228 0x00,0x02,0x00,0x06,0x00,0x41,0x5A,0x64,0x00,0x00,0x00,0x00,0x04,
229 /* | vss | vse |clck| clock |CRT2DataP|CRT2DataP|idx */
230 /* VESA non-VESA noscale */
231 /* 1280x1024 */
232 0x03,0xC0,0x00,0x05,0x00,0x04,0x98,0x06,0x2A,0x04,0x30,0x00,0x70,
233 0x00,0x01,0x00,0x03,0x00,0x6C,0xF8,0x2F,0x00,0x00,0x00,0x00,0x08,
234 /* 1400x1050 */
235 0x09,0x20,0x78,0x05,0x1A,0x04,0x98,0x06,0x2A,0x04,0x18,0x00,0x38,
236 0x00,0x01,0x00,0x03,0x00,0x6C,0xF8,0x2F,0x00,0x00,0x00,0x00,0x09,
237 /* 1600x1200 */
238 0x0B,0xE0,0x40,0x06,0xB0,0x04,0x70,0x08,0xE2,0x04,0x40,0x00,0xC0,
239 0x00,0x01,0x00,0x03,0x00,0xA2,0x70,0x24,0x00,0x00,0x00,0x00,0x0A,
240 /* 1280x768 (_2) */
241 0x0A,0xE0,0x00,0x05,0x00,0x03,0x7C,0x06,0x26,0x03,0x30,0x00,0x70,
242 0x00,0x03,0x00,0x06,0x00,0x4D,0xC8,0x48,0x00,0x00,0x00,0x00,0x06,
243 /* 1280x720 */
244 0x0E,0xE0,0x00,0x05,0xD0,0x02,0x80,0x05,0x26,0x03,0x10,0x00,0x20,
245 0x00,0x01,0x00,0x06,0x00,0x45,0x9C,0x62,0x00,0x00,0x00,0x00,0x05,
246 /* 1280x800 (_2) */
247 0x0C,0xE0,0x00,0x05,0x20,0x03,0x10,0x06,0x2C,0x03,0x30,0x00,0x70,
248 0x00,0x04,0x00,0x03,0x00,0x49,0xCE,0x1E,0x00,0x00,0x00,0x00,0x09,
249 /* 1680x1050 */
250 0x0D,0xE0,0x90,0x06,0x1A,0x04,0x6C,0x07,0x2A,0x04,0x1A,0x00,0x4C,
251 0x00,0x03,0x00,0x06,0x00,0x79,0xBE,0x44,0x00,0x00,0x00,0x00,0x06,
252};
253#endif
254
255#ifdef SIS300
256static UCHAR SiS300_TrumpionData[7][80] = {
257 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
258 0x20,0x03,0x0B,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x10,0x00,0x00,0x04,0x23,
259 0x00,0x00,0x03,0x28,0x03,0x10,0x05,0x08,0x40,0x10,0x00,0x10,0x04,0x23,0x00,0x23,
260 0x03,0x11,0x60,0xBC,0x01,0xFF,0x03,0xFF,0x19,0x01,0x00,0x05,0x09,0x04,0x04,0x05,
261 0x04,0x0C,0x09,0x05,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5A,0x01,0xBE,0x01,0x00 },
262 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x27,0x00,0x80,0x02,
263 0x20,0x03,0x07,0x00,0x5E,0x01,0x0D,0x02,0x60,0x0C,0x30,0x11,0x00,0x00,0x04,0x23,
264 0x00,0x00,0x03,0x80,0x03,0x28,0x06,0x08,0x40,0x11,0x00,0x11,0x04,0x23,0x00,0x23,
265 0x03,0x11,0x60,0x90,0x01,0xFF,0x0F,0xF4,0x19,0x01,0x00,0x05,0x01,0x00,0x04,0x05,
266 0x04,0x0C,0x02,0x01,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEC,0x57,0x01,0xBE,0x01,0x00 },
267 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x8A,0x00,0xD8,0x02,
268 0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,
269 0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,
270 0x03,0x11,0x60,0xD9,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,
271 0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x59,0x01,0xBE,0x01,0x00 },
272 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x72,0x00,0xD8,0x02,
273 0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,
274 0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,
275 0x03,0x11,0x60,0xDA,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,
276 0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
277 { 0x02,0x0A,0x02,0x00,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
278 0x20,0x03,0x16,0x00,0xE0,0x01,0x0D,0x02,0x60,0x0C,0x30,0x98,0x00,0x00,0x04,0x23,
279 0x00,0x01,0x03,0x45,0x03,0x48,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x23,0x00,0x23,
280 0x03,0x11,0x60,0xF4,0x01,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x05,0x01,0x00,0x05,0x05,
281 0x04,0x0C,0x08,0x05,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5B,0x01,0xBE,0x01,0x00 },
282 { 0x02,0x0A,0x02,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0xBF,0x00,0x20,0x03,
283 0x20,0x04,0x0D,0x00,0x58,0x02,0x71,0x02,0x80,0x0C,0x30,0x9A,0x00,0xFA,0x03,0x1D,
284 0x00,0x01,0x03,0x22,0x03,0x28,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x1D,0x00,0x1D,
285 0x03,0x11,0x60,0x39,0x03,0x40,0x05,0xF4,0x18,0x07,0x02,0x06,0x04,0x01,0x06,0x0B,
286 0x02,0x0A,0x20,0x19,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5B,0x01,0xBE,0x01,0x00 },
287 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0xEF,0x00,0x00,0x04,
288 0x40,0x05,0x13,0x00,0x00,0x03,0x26,0x03,0x88,0x0C,0x30,0x90,0x00,0x00,0x04,0x23,
289 0x00,0x01,0x03,0x24,0x03,0x28,0x06,0x08,0x40,0x90,0x00,0x90,0x04,0x23,0x00,0x23,
290 0x03,0x11,0x60,0x40,0x05,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x08,0x01,0x00,0x08,0x01,
291 0x00,0x08,0x01,0x01,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5B,0x01,0xBE,0x01,0x00 }
292};
293#endif
294
295void SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
296void SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
297void SiS_EnableCRT2(SiS_Private *SiS_Pr);
298USHORT SiS_GetRatePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, PSIS_HW_INFO HwInfo);
299void SiS_WaitRetrace1(SiS_Private *SiS_Pr);
300BOOLEAN SiS_IsDualEdge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
301BOOLEAN SiS_IsVAMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
302void SiS_SetChrontelGPIO(SiS_Private *SiS_Pr, USHORT myvbinfo);
303void SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo,
304 USHORT ModeIdIndex, PSIS_HW_INFO HwInfo,
305 int checkcrt2mode);
306void SiS_SetYPbPr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
307void SiS_SetTVMode(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, PSIS_HW_INFO HwInfo);
308void SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, PSIS_HW_INFO HwInfo);
309USHORT SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
310 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo);
311USHORT SiS_GetResInfo(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex);
312void SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
313void SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
314BOOLEAN SiS_SetCRT2Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo);
315void SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
316void SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
317
318void SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempax);
319USHORT SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempax);
320void SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempax);
321USHORT SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempax);
322void SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempax);
323USHORT SiS_GetCH70xx(SiS_Private *SiS_Pr, USHORT tempax);
324void SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, USHORT tempax,USHORT tempbh);
325#ifdef SIS315H
326static void SiS_Chrontel701xOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
327static void SiS_Chrontel701xOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
328static void SiS_ChrontelInitTVVSync(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
329static void SiS_ChrontelDoSomething1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
330void SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
331void SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr);
332#endif /* 315 */
333
334#ifdef SIS300
335#if 0
336static void SiS_SetTrumpReg(SiS_Private *SiS_Pr, USHORT tempbx);
337static USHORT SiS_GetTrumpReg(SiS_Private *SiS_Pr, USHORT tempbx);
338#endif
339static BOOLEAN SiS_SetTrumpionBlock(SiS_Private *SiS_Pr, UCHAR *dataptr);
340#endif
341
342void SiS_DDC2Delay(SiS_Private *SiS_Pr, USHORT delaytime);
343USHORT SiS_ReadDDC1Bit(SiS_Private *SiS_Pr);
344USHORT SiS_HandleDDC(SiS_Private *SiS_Pr, ULONG VBFlags, int VGAEngine,
345 USHORT adaptnum, USHORT DDCdatatype, UCHAR *buffer);
346#ifdef LINUX_XF86
347USHORT SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS);
348USHORT SiS_SenseVGA2DDC(SiS_Private *SiS_Pr, SISPtr pSiS);
349#endif
350
351static void SiS_SetSwitchDDC2(SiS_Private *SiS_Pr);
352static USHORT SiS_SetStart(SiS_Private *SiS_Pr);
353static USHORT SiS_SetStop(SiS_Private *SiS_Pr);
354static USHORT SiS_SetSCLKLow(SiS_Private *SiS_Pr);
355static USHORT SiS_SetSCLKHigh(SiS_Private *SiS_Pr);
356static USHORT SiS_ReadDDC2Data(SiS_Private *SiS_Pr, USHORT tempax);
357static USHORT SiS_WriteDDC2Data(SiS_Private *SiS_Pr, USHORT tempax);
358static USHORT SiS_CheckACK(SiS_Private *SiS_Pr);
359static USHORT SiS_InitDDCRegs(SiS_Private *SiS_Pr, ULONG VBFlags, int VGAEngine,
360 USHORT adaptnum, USHORT DDCdatatype, BOOLEAN checkcr32);
361static USHORT SiS_WriteDABDDC(SiS_Private *SiS_Pr);
362static USHORT SiS_PrepareReadDDC(SiS_Private *SiS_Pr);
363static USHORT SiS_PrepareDDC(SiS_Private *SiS_Pr);
364static void SiS_SendACK(SiS_Private *SiS_Pr, USHORT yesno);
365static USHORT SiS_DoProbeDDC(SiS_Private *SiS_Pr);
366static USHORT SiS_ProbeDDC(SiS_Private *SiS_Pr);
367static USHORT SiS_ReadDDC(SiS_Private *SiS_Pr, USHORT DDCdatatype, UCHAR *buffer);
368
369#ifdef SIS315H
370static void SiS_OEM310Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
371 USHORT ModeNo,USHORT ModeIdIndex, USHORT RRTI);
372static void SiS_OEM661Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
373 USHORT ModeNo,USHORT ModeIdIndex, USHORT RRTI);
374static void SiS_FinalizeLCD(SiS_Private *, USHORT, USHORT, PSIS_HW_INFO);
375#endif
376#ifdef SIS300
377static void SiS_OEM300Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
378 USHORT ModeNo, USHORT ModeIdIndex, USHORT RefTabindex);
379static void SetOEMLCDData2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
380 USHORT ModeNo, USHORT ModeIdIndex,USHORT RefTableIndex);
381#endif
382
383extern void SiS_SetReg(SISIOADDRESS, USHORT, USHORT);
384extern void SiS_SetRegByte(SISIOADDRESS, USHORT);
385extern void SiS_SetRegShort(SISIOADDRESS, USHORT);
386extern void SiS_SetRegLong(SISIOADDRESS, ULONG);
387extern UCHAR SiS_GetReg(SISIOADDRESS, USHORT);
388extern UCHAR SiS_GetRegByte(SISIOADDRESS);
389extern USHORT SiS_GetRegShort(SISIOADDRESS);
390extern ULONG SiS_GetRegLong(SISIOADDRESS);
391extern void SiS_SetRegANDOR(SISIOADDRESS, USHORT, USHORT, USHORT);
392extern void SiS_SetRegOR(SISIOADDRESS, USHORT, USHORT);
393extern void SiS_SetRegAND(SISIOADDRESS, USHORT, USHORT);
394extern void SiS_DisplayOff(SiS_Private *SiS_Pr);
395extern void SiS_DisplayOn(SiS_Private *SiS_Pr);
396extern BOOLEAN SiS_SearchModeID(SiS_Private *, USHORT *, USHORT *);
397extern UCHAR SiS_GetModePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex);
398extern USHORT SiS_GetColorDepth(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex);
399extern USHORT SiS_GetOffset(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
400 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo);
401extern void SiS_LoadDAC(SiS_Private *SiS_Pr, PSIS_HW_INFO, USHORT ModeNo,
402 USHORT ModeIdIndex);
403extern void SiS_CalcLCDACRT1Timing(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex);
404#ifdef LINUX_XF86
405extern void SiS_MakeClockRegs(ScrnInfoPtr pScrn, int clock, UCHAR *p2b, UCHAR *p2c);
406extern int SiS_FindPanelFromDB(SISPtr pSiS, USHORT panelvendor, USHORT panelproduct,
407 int *maxx, int *maxy, int *prefx, int *prefy);
408#endif
409
410#endif
diff --git a/drivers/video/sis/initdef.h b/drivers/video/sis/initdef.h
new file mode 100644
index 000000000000..55a82d6dc4cf
--- /dev/null
+++ b/drivers/video/sis/initdef.h
@@ -0,0 +1,671 @@
1/* $XFree86$ */
2/* $XdotOrg$ */
3/*
4 * Global definitions for init.c and init301.c
5 *
6 * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
7 *
8 * If distributed as part of the Linux kernel, the following license terms
9 * apply:
10 *
11 * * This program is free software; you can redistribute it and/or modify
12 * * it under the terms of the GNU General Public License as published by
13 * * the Free Software Foundation; either version 2 of the named License,
14 * * or any later version.
15 * *
16 * * This program is distributed in the hope that it will be useful,
17 * * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * * GNU General Public License for more details.
20 * *
21 * * You should have received a copy of the GNU General Public License
22 * * along with this program; if not, write to the Free Software
23 * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
24 *
25 * Otherwise, the following license terms apply:
26 *
27 * * Redistribution and use in source and binary forms, with or without
28 * * modification, are permitted provided that the following conditions
29 * * are met:
30 * * 1) Redistributions of source code must retain the above copyright
31 * * notice, this list of conditions and the following disclaimer.
32 * * 2) Redistributions in binary form must reproduce the above copyright
33 * * notice, this list of conditions and the following disclaimer in the
34 * * documentation and/or other materials provided with the distribution.
35 * * 3) The name of the author may not be used to endorse or promote products
36 * * derived from this software without specific prior written permission.
37 * *
38 * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
39 * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
40 * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
41 * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
42 * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
43 * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
44 * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
45 * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46 * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
47 * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48 *
49 * Author: Thomas Winischhofer <thomas@winischhofer.net>
50 *
51 */
52
53#ifndef _INITDEF_
54#define _INITDEF_
55
56#define IS_SIS330 (HwInfo->jChipType == SIS_330)
57#define IS_SIS550 (HwInfo->jChipType == SIS_550)
58#define IS_SIS650 (HwInfo->jChipType == SIS_650) /* All versions, incl 651, M65x */
59#define IS_SIS740 (HwInfo->jChipType == SIS_740)
60#define IS_SIS651 (SiS_Pr->SiS_SysFlags & (SF_Is651 | SF_Is652))
61#define IS_SISM650 (SiS_Pr->SiS_SysFlags & (SF_IsM650 | SF_IsM652 | SF_IsM653))
62#define IS_SIS65x (IS_SIS651 || IS_SISM650) /* Only special versions of 65x */
63#define IS_SIS661 (HwInfo->jChipType == SIS_661)
64#define IS_SIS741 (HwInfo->jChipType == SIS_741)
65#define IS_SIS660 (HwInfo->jChipType == SIS_660)
66#define IS_SIS760 (HwInfo->jChipType == SIS_760)
67#define IS_SIS661741660760 (IS_SIS661 || IS_SIS741 || IS_SIS660 || IS_SIS760)
68#define IS_SIS650740 ((HwInfo->jChipType >= SIS_650) && (HwInfo->jChipType < SIS_330))
69#define IS_SIS550650740 (IS_SIS550 || IS_SIS650740)
70#define IS_SIS650740660 (IS_SIS650 || IS_SIS740 || IS_SIS661741660760)
71#define IS_SIS550650740660 (IS_SIS550 || IS_SIS650740660)
72
73#define SISGETROMW(x) (ROMAddr[(x)] | (ROMAddr[(x)+1] << 8))
74
75/* SiS_VBType */
76#define VB_SIS301 0x0001
77#define VB_SIS301B 0x0002
78#define VB_SIS302B 0x0004
79#define VB_SIS301LV 0x0008
80#define VB_SIS302LV 0x0010
81#define VB_SIS302ELV 0x0020
82#define VB_SIS301C 0x0040
83#define VB_UMC 0x4000
84#define VB_NoLCD 0x8000
85#define VB_SIS301BLV302BLV (VB_SIS301B|VB_SIS301C|VB_SIS302B|VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)
86#define VB_SIS301B302B (VB_SIS301B|VB_SIS301C|VB_SIS302B)
87#define VB_SIS301LV302LV (VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)
88#define VB_SISVB (VB_SIS301 | VB_SIS301BLV302BLV)
89#define VB_SISTMDS (VB_SIS301 | VB_SIS301B302B)
90#define VB_SISLVDS VB_SIS301LV302LV
91#define VB_SISLCDA (VB_SIS302B|VB_SIS301C|VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)
92#define VB_SISYPBPR (VB_SIS301C|VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)
93#define VB_SISHIVISION (VB_SIS301|VB_SIS301B|VB_SIS302B)
94
95/* VBInfo */
96#define SetSimuScanMode 0x0001 /* CR 30 */
97#define SwitchCRT2 0x0002
98#define SetCRT2ToAVIDEO 0x0004
99#define SetCRT2ToSVIDEO 0x0008
100#define SetCRT2ToSCART 0x0010
101#define SetCRT2ToLCD 0x0020
102#define SetCRT2ToRAMDAC 0x0040
103#define SetCRT2ToHiVision 0x0080 /* for SiS bridge */
104#define SetCRT2ToCHYPbPr SetCRT2ToHiVision /* for Chrontel */
105#define SetNTSCTV 0x0000 /* CR 31 */
106#define SetPALTV 0x0100 /* Deprecated here, now in TVMode */
107#define SetInSlaveMode 0x0200
108#define SetNotSimuMode 0x0400
109#define SetNotSimuTVMode SetNotSimuMode
110#define SetDispDevSwitch 0x0800
111#define SetCRT2ToYPbPr525750 0x0800
112#define LoadDACFlag 0x1000
113#define DisableCRT2Display 0x2000
114#define DriverMode 0x4000
115#define HotKeySwitch 0x8000
116#define SetCRT2ToLCDA 0x8000
117
118/* v-- Needs change in sis_vga.c if changed (GPIO) --v */
119#define SetCRT2ToTV (SetCRT2ToYPbPr525750|SetCRT2ToHiVision|SetCRT2ToSCART|SetCRT2ToSVIDEO|SetCRT2ToAVIDEO)
120#define SetCRT2ToTVNoYPbPrHiVision (SetCRT2ToSCART | SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)
121#define SetCRT2ToTVNoHiVision (SetCRT2ToYPbPr525750 | SetCRT2ToSCART | SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)
122
123/* SiS_ModeType */
124#define ModeText 0x00
125#define ModeCGA 0x01
126#define ModeEGA 0x02
127#define ModeVGA 0x03
128#define Mode15Bpp 0x04
129#define Mode16Bpp 0x05
130#define Mode24Bpp 0x06
131#define Mode32Bpp 0x07
132
133#define ModeTypeMask 0x07
134#define IsTextMode 0x07
135
136#define DACInfoFlag 0x0018
137#define MemoryInfoFlag 0x01E0
138#define MemorySizeShift 5
139
140/* modeflag */
141#define Charx8Dot 0x0200
142#define LineCompareOff 0x0400
143#define CRT2Mode 0x0800
144#define HalfDCLK 0x1000
145#define NoSupportSimuTV 0x2000
146#define NoSupportLCDScale 0x4000 /* SiS bridge: No scaling possible (no matter what panel) */
147#define DoubleScanMode 0x8000
148
149/* Infoflag */
150#define SupportTV 0x0008
151#define SupportTV1024 0x0800
152#define SupportCHTV 0x0800
153#define Support64048060Hz 0x0800 /* Special for 640x480 LCD */
154#define SupportHiVision 0x0010
155#define SupportYPbPr750p 0x1000
156#define SupportLCD 0x0020
157#define SupportRAMDAC2 0x0040 /* All (<= 100Mhz) */
158#define SupportRAMDAC2_135 0x0100 /* All except DH (<= 135Mhz) */
159#define SupportRAMDAC2_162 0x0200 /* B, C (<= 162Mhz) */
160#define SupportRAMDAC2_202 0x0400 /* C (<= 202Mhz) */
161#define InterlaceMode 0x0080
162#define SyncPP 0x0000
163#define SyncPN 0x4000
164#define SyncNP 0x8000
165#define SyncNN 0xc000
166
167/* SetFlag */
168#define ProgrammingCRT2 0x0001
169#define LowModeTests 0x0002
170/* #define TVSimuMode 0x0002 - deprecated */
171/* #define RPLLDIV2XO 0x0004 - deprecated */
172#define LCDVESATiming 0x0008
173#define EnableLVDSDDA 0x0010
174#define SetDispDevSwitchFlag 0x0020
175#define CheckWinDos 0x0040
176#define SetDOSMode 0x0080
177
178/* TVMode flag */
179#define TVSetPAL 0x0001
180#define TVSetNTSCJ 0x0002
181#define TVSetPALM 0x0004
182#define TVSetPALN 0x0008
183#define TVSetCHOverScan 0x0010
184#define TVSetYPbPr525i 0x0020 /* new 0x10 */
185#define TVSetYPbPr525p 0x0040 /* new 0x20 */
186#define TVSetYPbPr750p 0x0080 /* new 0x40 */
187#define TVSetHiVision 0x0100 /* new 0x80; = 1080i, software-wise identical */
188#define TVSetTVSimuMode 0x0200 /* new 0x200, prev. 0x800 */
189#define TVRPLLDIV2XO 0x0400 /* prev 0x1000 */
190#define TVSetNTSC1024 0x0800 /* new 0x100, prev. 0x2000 */
191#define TVAspect43 0x2000
192#define TVAspect169 0x4000
193#define TVAspect43LB 0x8000
194
195/* YPbPr flag (>=315, <661; converted to TVMode) */
196#define YPbPr525p 0x0001
197#define YPbPr750p 0x0002
198#define YPbPr525i 0x0004
199#define YPbPrHiVision 0x0008
200#define YPbPrModeMask (YPbPr750p | YPbPr525p | YPbPr525i | YPbPrHiVision)
201
202/* SysFlags (to identify special versions) */
203#define SF_Is651 0x0001
204#define SF_IsM650 0x0002
205#define SF_Is652 0x0004
206#define SF_IsM652 0x0008
207#define SF_IsM653 0x0010
208#define SF_IsM661 0x0020
209#define SF_IsM741 0x0040
210#define SF_IsM760 0x0080
211#define SF_760LFB 0x8000 /* 760: We have LFB */
212
213/* CR32 (Newer 630, and 315 series)
214
215 [0] VB connected with CVBS
216 [1] VB connected with SVHS
217 [2] VB connected with SCART
218 [3] VB connected with LCD
219 [4] VB connected with CRT2 (secondary VGA)
220 [5] CRT1 monitor is connected
221 [6] VB connected with Hi-Vision TV
222 [7] <= 330: VB connected with DVI combo connector
223 >= 661: VB connected to YPbPr
224*/
225
226/* CR35 (300 series only) */
227#define TVOverScan 0x10
228#define TVOverScanShift 4
229
230/* CR35 (661 series only)
231
232 [0] 1 = PAL, 0 = NTSC
233 [1] 1 = NTSC-J (if D0 = 0)
234 [2] 1 = PALM (if D0 = 1)
235 [3] 1 = PALN (if D0 = 1)
236 [4] 1 = Overscan (Chrontel only)
237 [7:5] (only if D2 in CR38 is set)
238 000 525i
239 001 525p
240 010 750p
241 011 1080i (or HiVision on 301, 301B)
242
243 These bits are being translated to TVMode flag.
244
245*/
246
247/*
248 CR37
249
250 [0] Set 24/18 bit (0/1) RGB to LVDS/TMDS transmitter (set by BIOS)
251 [3:1] External chip
252 300 series:
253 001 SiS301 (never seen)
254 010 LVDS
255 011 LVDS + Tumpion Zurac
256 100 LVDS + Chrontel 7005
257 110 Chrontel 7005
258 315/330 series
259 001 SiS30x (never seen)
260 010 LVDS
261 011 LVDS + Chrontel 7019
262 660 series [2:1] only:
263 reserved (now in CR38)
264 All other combinations reserved
265 [3] 661 only: Pass 1:1 data
266 [4] LVDS: 0: Panel Link expands / 1: Panel Link does not expand
267 30x: 0: Bridge scales / 1: Bridge does not scale = Panel scales (if possible)
268 [5] LCD polarity select
269 0: VESA DMT Standard
270 1: EDID 2.x defined
271 [6] LCD horizontal polarity select
272 0: High active
273 1: Low active
274 [7] LCD vertical polarity select
275 0: High active
276 1: Low active
277*/
278
279/* CR37: LCDInfo */
280#define LCDRGB18Bit 0x0001
281#define LCDNonExpanding 0x0010
282#define LCDSync 0x0020
283#define LCDPass11 0x0100 /* 0: center screen, 1: Pass 1:1 data */
284#define LCDDualLink 0x0200
285
286#define DontExpandLCD LCDNonExpanding
287#define LCDNonExpandingShift 4
288#define DontExpandLCDShift LCDNonExpandingShift
289#define LCDSyncBit 0x00e0
290#define LCDSyncShift 6
291
292/* CR38 (315 series) */
293#define EnableDualEdge 0x01
294#define SetToLCDA 0x02 /* LCD channel A (301C/302B/30x(E)LV and 650+LVDS only) */
295#define EnableCHScart 0x04 /* Scart on Ch7019 (unofficial definition - TW) */
296#define EnableCHYPbPr 0x08 /* YPbPr on Ch7019 (480i HDTV); only on 650/Ch7019 systems */
297#define EnableSiSYPbPr 0x08 /* Enable YPbPr mode (30xLV/301C only) */
298#define EnableYPbPr525i 0x00 /* Enable 525i YPbPr mode (30xLV/301C only) (mask 0x30) */
299#define EnableYPbPr525p 0x10 /* Enable 525p YPbPr mode (30xLV/301C only) (mask 0x30) */
300#define EnableYPbPr750p 0x20 /* Enable 750p YPbPr mode (30xLV/301C only) (mask 0x30) */
301#define EnableYPbPr1080i 0x30 /* Enable 1080i YPbPr mode (30xLV/301C only) (mask 0x30) */
302#define EnablePALM 0x40 /* 1 = Set PALM */
303#define EnablePALN 0x80 /* 1 = Set PALN */
304#define EnableNTSCJ EnablePALM /* Not BIOS */
305
306/* CR38 (661 and later)
307 D[7:5] 000 No VB
308 001 301 series VB
309 010 LVDS
310 011 Chrontel 7019
311 100 Conexant
312 D2 Enable YPbPr output (see CR35)
313 D[1:0] LCDA (like before)
314*/
315
316#define EnablePALMN 0x40 /* Romflag: 1 = Allow PALM/PALN */
317
318/* CR39 (650 only) */
319#define LCDPass1_1 0x01 /* 0: center screen, 1: pass 1:1 data output */
320#define Enable302LV_DualLink 0x04 /* 302LV only; enable dual link */
321
322/* CR39 (661 and later)
323 D[1:0] YPbPr Aspect Ratio
324 00 4:3 letterbox
325 01 4:3
326 10 16:9
327 11 4:3
328*/
329
330/* CR3B (651+301C)
331 D[1:0] YPbPr Aspect Ratio
332 ?
333*/
334
335/* CR79 (315/330 series only; not 661 and later)
336 [3-0] Notify driver
337 0001 Mode Switch event (set by BIOS)
338 0010 Epansion On/Off event
339 0011 TV UnderScan/OverScan event
340 0100 Set Brightness event
341 0101 Set Contrast event
342 0110 Set Mute event
343 0111 Set Volume Up/Down event
344 [4] Enable Backlight Control by BIOS/driver
345 (set by driver; set means that the BIOS should
346 not touch the backlight registers because eg.
347 the driver already switched off the backlight)
348 [5] PAL/NTSC (set by BIOS)
349 [6] Expansion On/Off (set by BIOS; copied to CR32[4])
350 [7] TV UnderScan/OverScan (set by BIOS)
351*/
352
353/* LCDResInfo */
354#define Panel300_800x600 0x01 /* CR36 */
355#define Panel300_1024x768 0x02
356#define Panel300_1280x1024 0x03
357#define Panel300_1280x960 0x04
358#define Panel300_640x480 0x05
359#define Panel300_1024x600 0x06
360#define Panel300_1152x768 0x07
361#define Panel300_1280x768 0x0a
362#define Panel300_320x480 0x0e /* fstn - This is fake, can be any */
363#define Panel300_Custom 0x0f
364#define Panel300_Barco1366 0x10
365
366#define Panel310_800x600 0x01
367#define Panel310_1024x768 0x02
368#define Panel310_1280x1024 0x03
369#define Panel310_640x480 0x04
370#define Panel310_1024x600 0x05
371#define Panel310_1152x864 0x06
372#define Panel310_1280x960 0x07
373#define Panel310_1152x768 0x08 /* LVDS only */
374#define Panel310_1400x1050 0x09
375#define Panel310_1280x768 0x0a
376#define Panel310_1600x1200 0x0b
377#define Panel310_640x480_2 0x0c
378#define Panel310_640x480_3 0x0d
379#define Panel310_320x480 0x0e /* fstn - TW: This is fake, can be any */
380#define Panel310_Custom 0x0f
381
382#define Panel661_800x600 0x01
383#define Panel661_1024x768 0x02
384#define Panel661_1280x1024 0x03
385#define Panel661_640x480 0x04
386#define Panel661_1024x600 0x05
387#define Panel661_1152x864 0x06
388#define Panel661_1280x960 0x07
389#define Panel661_1152x768 0x08
390#define Panel661_1400x1050 0x09
391#define Panel661_1280x768 0x0a
392#define Panel661_1600x1200 0x0b
393#define Panel661_1280x800 0x0c
394#define Panel661_1680x1050 0x0d
395#define Panel661_1280x720 0x0e
396#define Panel661_Custom 0x0f
397
398#define Panel_800x600 0x01 /* Unified values */
399#define Panel_1024x768 0x02 /* MUST match BIOS values from 0-e */
400#define Panel_1280x1024 0x03
401#define Panel_640x480 0x04
402#define Panel_1024x600 0x05
403#define Panel_1152x864 0x06
404#define Panel_1280x960 0x07
405#define Panel_1152x768 0x08 /* LVDS only */
406#define Panel_1400x1050 0x09
407#define Panel_1280x768 0x0a /* 30xB/C and LVDS only (BIOS: all) */
408#define Panel_1600x1200 0x0b
409#define Panel_1280x800 0x0c /* 661etc (TMDS) */
410#define Panel_1680x1050 0x0d /* 661etc */
411#define Panel_1280x720 0x0e /* 661etc */
412#define Panel_Custom 0x0f /* MUST BE 0x0f (for DVI DDC detection) */
413#define Panel_320x480 0x10 /* SiS 550 fstn - TW: This is fake, can be any */
414#define Panel_Barco1366 0x11
415#define Panel_848x480 0x12
416#define Panel_640x480_2 0x13 /* SiS 550 */
417#define Panel_640x480_3 0x14 /* SiS 550 */
418#define Panel_1280x768_2 0x15 /* 30xLV */
419#define Panel_1280x768_3 0x16 /* (unused) */
420#define Panel_1280x800_2 0x17 /* 30xLV */
421
422/* Index in ModeResInfo table */
423#define SIS_RI_320x200 0
424#define SIS_RI_320x240 1
425#define SIS_RI_320x400 2
426#define SIS_RI_400x300 3
427#define SIS_RI_512x384 4
428#define SIS_RI_640x400 5
429#define SIS_RI_640x480 6
430#define SIS_RI_800x600 7
431#define SIS_RI_1024x768 8
432#define SIS_RI_1280x1024 9
433#define SIS_RI_1600x1200 10
434#define SIS_RI_1920x1440 11
435#define SIS_RI_2048x1536 12
436#define SIS_RI_720x480 13
437#define SIS_RI_720x576 14
438#define SIS_RI_1280x960 15
439#define SIS_RI_800x480 16
440#define SIS_RI_1024x576 17
441#define SIS_RI_1280x720 18
442#define SIS_RI_856x480 19
443#define SIS_RI_1280x768 20
444#define SIS_RI_1400x1050 21
445#define SIS_RI_1152x864 22 /* Up to here SiS conforming */
446#define SIS_RI_848x480 23
447#define SIS_RI_1360x768 24
448#define SIS_RI_1024x600 25
449#define SIS_RI_1152x768 26
450#define SIS_RI_768x576 27
451#define SIS_RI_1360x1024 28
452#define SIS_RI_1680x1050 29
453#define SIS_RI_1280x800 30
454#define SIS_RI_1920x1080 31
455#define SIS_RI_960x540 32
456#define SIS_RI_960x600 33
457
458/* CR5F */
459#define IsM650 0x80
460
461/* Timing data */
462#define NTSCHT 1716
463#define NTSC2HT 1920
464#define NTSCVT 525
465#define PALHT 1728
466#define PALVT 625
467#define StHiTVHT 892
468#define StHiTVVT 1126
469#define StHiTextTVHT 1000
470#define StHiTextTVVT 1126
471#define ExtHiTVHT 2100
472#define ExtHiTVVT 1125
473
474/* Indices in (VB)VCLKData tables */
475
476#define VCLK28 0x00 /* Index in VCLKData table (300 and 315) */
477#define VCLK40 0x04 /* Index in VCLKData table (300 and 315) */
478#define VCLK65_300 0x09 /* Index in VCLKData table (300) */
479#define VCLK108_2_300 0x14 /* Index in VCLKData table (300) */
480#define VCLK81_300 0x3f /* Index in VCLKData table (300) */
481#define VCLK108_3_300 0x42 /* Index in VCLKData table (300) */
482#define VCLK100_300 0x43 /* Index in VCLKData table (300) */
483#define VCLK34_300 0x3d /* Index in VCLKData table (300) */
484#define VCLK_CUSTOM_300 0x47
485#define VCLK65_315 0x0b /* Index in (VB)VCLKData table (315) */
486#define VCLK108_2_315 0x19 /* Index in (VB)VCLKData table (315) */
487#define VCLK81_315 0x5b /* Index in (VB)VCLKData table (315) */
488#define VCLK162_315 0x5e /* Index in (VB)VCLKData table (315) */
489#define VCLK108_3_315 0x45 /* Index in VBVCLKData table (315) */
490#define VCLK100_315 0x46 /* Index in VBVCLKData table (315) */
491#define VCLK34_315 0x55
492#define VCLK68_315 0x0d
493#define VCLK_1280x800_315_2 0x5c /* Index in VBVCLKData table (315) */
494#define VCLK121_315 0x5d /* Index in VBVCLKData table (315) */
495#define VCLK_1280x720 0x5f
496#define VCLK_1280x768_2 0x60
497#define VCLK_1280x768_3 0x61 /* (unused?) */
498#define VCLK_CUSTOM_315 0x62
499#define VCLK_1280x720_2 0x63
500#define VCLK_720x480 0x67
501#define VCLK_720x576 0x68
502#define VCLK_768x576 0x68
503#define VCLK_848x480 0x65
504#define VCLK_856x480 0x66
505#define VCLK_800x480 0x65
506#define VCLK_1024x576 0x51
507#define VCLK_1152x864 0x64
508#define VCLK_1360x768 0x58
509#define VCLK_1280x800_315 0x6c
510
511#define TVCLKBASE_300 0x21 /* Indices on TV clocks in VCLKData table (300) */
512#define TVCLKBASE_315 0x3a /* Indices on TV clocks in (VB)VCLKData table (315) */
513#define TVVCLKDIV2 0x00 /* Index relative to TVCLKBASE */
514#define TVVCLK 0x01 /* Index relative to TVCLKBASE */
515#define HiTVVCLKDIV2 0x02 /* Index relative to TVCLKBASE */
516#define HiTVVCLK 0x03 /* Index relative to TVCLKBASE */
517#define HiTVSimuVCLK 0x04 /* Index relative to TVCLKBASE */
518#define HiTVTextVCLK 0x05 /* Index relative to TVCLKBASE */
519#define YPbPr750pVCLK 0x25 /* Index relative to TVCLKBASE; was 0x0f NOT relative */
520
521/* ------------------------------ */
522
523#define SetSCARTOutput 0x01
524
525#define HotPlugFunction 0x08
526
527#define StStructSize 0x06
528
529#define SIS_VIDEO_CAPTURE 0x00 - 0x30
530#define SIS_VIDEO_PLAYBACK 0x02 - 0x30
531#define SIS_CRT2_PORT_04 0x04 - 0x30
532#define SIS_CRT2_PORT_10 0x10 - 0x30
533#define SIS_CRT2_PORT_12 0x12 - 0x30
534#define SIS_CRT2_PORT_14 0x14 - 0x30
535
536#define ADR_CRT2PtrData 0x20E
537#define offset_Zurac 0x210 /* TW: Trumpion Zurac data pointer */
538#define ADR_LVDSDesPtrData 0x212
539#define ADR_LVDSCRT1DataPtr 0x214
540#define ADR_CHTVVCLKPtr 0x216
541#define ADR_CHTVRegDataPtr 0x218
542
543#define LCDDataLen 8
544#define HiTVDataLen 12
545#define TVDataLen 16
546
547#define LVDSDataLen 6
548#define LVDSDesDataLen 3
549#define ActiveNonExpanding 0x40
550#define ActiveNonExpandingShift 6
551#define ActivePAL 0x20
552#define ActivePALShift 5
553#define ModeSwitchStatus 0x0F
554#define SoftTVType 0x40
555#define SoftSettingAddr 0x52
556#define ModeSettingAddr 0x53
557
558#define _PanelType00 0x00
559#define _PanelType01 0x08
560#define _PanelType02 0x10
561#define _PanelType03 0x18
562#define _PanelType04 0x20
563#define _PanelType05 0x28
564#define _PanelType06 0x30
565#define _PanelType07 0x38
566#define _PanelType08 0x40
567#define _PanelType09 0x48
568#define _PanelType0A 0x50
569#define _PanelType0B 0x58
570#define _PanelType0C 0x60
571#define _PanelType0D 0x68
572#define _PanelType0E 0x70
573#define _PanelType0F 0x78
574
575#define PRIMARY_VGA 0 /* 1: SiS is primary vga 0:SiS is secondary vga */
576
577#define BIOSIDCodeAddr 0x235 /* Offsets to ptrs in BIOS image */
578#define OEMUtilIDCodeAddr 0x237
579#define VBModeIDTableAddr 0x239
580#define OEMTVPtrAddr 0x241
581#define PhaseTableAddr 0x243
582#define NTSCFilterTableAddr 0x245
583#define PALFilterTableAddr 0x247
584#define OEMLCDPtr_1Addr 0x249
585#define OEMLCDPtr_2Addr 0x24B
586#define LCDHPosTable_1Addr 0x24D
587#define LCDHPosTable_2Addr 0x24F
588#define LCDVPosTable_1Addr 0x251
589#define LCDVPosTable_2Addr 0x253
590#define OEMLCDPIDTableAddr 0x255
591
592#define VBModeStructSize 5
593#define PhaseTableSize 4
594#define FilterTableSize 4
595#define LCDHPosTableSize 7
596#define LCDVPosTableSize 5
597#define OEMLVDSPIDTableSize 4
598#define LVDSHPosTableSize 4
599#define LVDSVPosTableSize 6
600
601#define VB_ModeID 0
602#define VB_TVTableIndex 1
603#define VB_LCDTableIndex 2
604#define VB_LCDHIndex 3
605#define VB_LCDVIndex 4
606
607#define OEMLCDEnable 0x0001
608#define OEMLCDDelayEnable 0x0002
609#define OEMLCDPOSEnable 0x0004
610#define OEMTVEnable 0x0100
611#define OEMTVDelayEnable 0x0200
612#define OEMTVFlickerEnable 0x0400
613#define OEMTVPhaseEnable 0x0800
614#define OEMTVFilterEnable 0x1000
615
616#define OEMLCDPanelIDSupport 0x0080
617
618/*
619 =============================================================
620 for 315 series (old data layout)
621 =============================================================
622*/
623#define SoftDRAMType 0x80
624#define SoftSetting_OFFSET 0x52
625#define SR07_OFFSET 0x7C
626#define SR15_OFFSET 0x7D
627#define SR16_OFFSET 0x81
628#define SR17_OFFSET 0x85
629#define SR19_OFFSET 0x8D
630#define SR1F_OFFSET 0x99
631#define SR21_OFFSET 0x9A
632#define SR22_OFFSET 0x9B
633#define SR23_OFFSET 0x9C
634#define SR24_OFFSET 0x9D
635#define SR25_OFFSET 0x9E
636#define SR31_OFFSET 0x9F
637#define SR32_OFFSET 0xA0
638#define SR33_OFFSET 0xA1
639
640#define CR40_OFFSET 0xA2
641#define SR25_1_OFFSET 0xF6
642#define CR49_OFFSET 0xF7
643
644#define VB310Data_1_2_Offset 0xB6
645#define VB310Data_4_D_Offset 0xB7
646#define VB310Data_4_E_Offset 0xB8
647#define VB310Data_4_10_Offset 0xBB
648
649#define RGBSenseDataOffset 0xBD
650#define YCSenseDataOffset 0xBF
651#define VideoSenseDataOffset 0xC1
652#define OutputSelectOffset 0xF3
653
654#define ECLK_MCLK_DISTANCE 0x14
655#define VBIOSTablePointerStart 0x100
656#define StandTablePtrOffset VBIOSTablePointerStart+0x02
657#define EModeIDTablePtrOffset VBIOSTablePointerStart+0x04
658#define CRT1TablePtrOffset VBIOSTablePointerStart+0x06
659#define ScreenOffsetPtrOffset VBIOSTablePointerStart+0x08
660#define VCLKDataPtrOffset VBIOSTablePointerStart+0x0A
661#define MCLKDataPtrOffset VBIOSTablePointerStart+0x0E
662#define CRT2PtrDataPtrOffset VBIOSTablePointerStart+0x10
663#define TVAntiFlickPtrOffset VBIOSTablePointerStart+0x12
664#define TVDelayPtr1Offset VBIOSTablePointerStart+0x14
665#define TVPhaseIncrPtr1Offset VBIOSTablePointerStart+0x16
666#define TVYFilterPtr1Offset VBIOSTablePointerStart+0x18
667#define LCDDelayPtr1Offset VBIOSTablePointerStart+0x20
668#define TVEdgePtr1Offset VBIOSTablePointerStart+0x24
669#define CRT2Delay1Offset VBIOSTablePointerStart+0x28
670
671#endif
diff --git a/drivers/video/sis/oem300.h b/drivers/video/sis/oem300.h
new file mode 100644
index 000000000000..b1358b750f53
--- /dev/null
+++ b/drivers/video/sis/oem300.h
@@ -0,0 +1,859 @@
1/* $XFree86$ */
2/* $XdotOrg$ */
3/*
4 * OEM Data for 300 series
5 *
6 * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
7 *
8 * If distributed as part of the Linux kernel, the following license terms
9 * apply:
10 *
11 * * This program is free software; you can redistribute it and/or modify
12 * * it under the terms of the GNU General Public License as published by
13 * * the Free Software Foundation; either version 2 of the named License,
14 * * or any later version.
15 * *
16 * * This program is distributed in the hope that it will be useful,
17 * * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * * GNU General Public License for more details.
20 * *
21 * * You should have received a copy of the GNU General Public License
22 * * along with this program; if not, write to the Free Software
23 * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
24 *
25 * Otherwise, the following license terms apply:
26 *
27 * * Redistribution and use in source and binary forms, with or without
28 * * modification, are permitted provided that the following conditions
29 * * are met:
30 * * 1) Redistributions of source code must retain the above copyright
31 * * notice, this list of conditions and the following disclaimer.
32 * * 2) Redistributions in binary form must reproduce the above copyright
33 * * notice, this list of conditions and the following disclaimer in the
34 * * documentation and/or other materials provided with the distribution.
35 * * 3) The name of the author may not be used to endorse or promote products
36 * * derived from this software without specific prior written permission.
37 * *
38 * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
39 * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
40 * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
41 * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
42 * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
43 * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
44 * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
45 * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46 * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
47 * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48 *
49 * Author: Thomas Winischhofer <thomas@winischhofer.net>
50 *
51 */
52
53static const UCHAR SiS300_OEMTVDelay301[8][4] =
54{
55 {0x08,0x08,0x08,0x08},
56 {0x08,0x08,0x08,0x08},
57 {0x08,0x08,0x08,0x08},
58 {0x2c,0x2c,0x2c,0x2c},
59 {0x08,0x08,0x08,0x08},
60 {0x08,0x08,0x08,0x08},
61 {0x08,0x08,0x08,0x08},
62 {0x20,0x20,0x20,0x20}
63};
64
65static const UCHAR SiS300_OEMTVDelayLVDS[8][4] =
66{
67 {0x20,0x20,0x20,0x20},
68 {0x20,0x20,0x20,0x20},
69 {0x20,0x20,0x20,0x20},
70 {0x20,0x20,0x20,0x20},
71 {0x20,0x20,0x20,0x20},
72 {0x20,0x20,0x20,0x20},
73 {0x20,0x20,0x20,0x20},
74 {0x20,0x20,0x20,0x20}
75};
76
77static const UCHAR SiS300_OEMTVFlicker[8][4] =
78{
79 {0x00,0x00,0x00,0x00},
80 {0x00,0x00,0x00,0x00},
81 {0x00,0x00,0x00,0x00},
82 {0x00,0x00,0x00,0x00},
83 {0x00,0x00,0x00,0x00},
84 {0x00,0x00,0x00,0x00},
85 {0x00,0x00,0x00,0x00},
86 {0x00,0x00,0x00,0x00}
87};
88
89#if 0 /* TW: Not used */
90static const UCHAR SiS300_OEMLCDDelay1[12][4]={
91 {0x2c,0x2c,0x2c,0x2c},
92 {0x20,0x20,0x20,0x20},
93 {0x20,0x20,0x20,0x20},
94 {0x2c,0x2c,0x2c,0x2c},
95 {0x2c,0x2c,0x2c,0x2c},
96 {0x20,0x20,0x20,0x20},
97 {0x20,0x20,0x20,0x20},
98 {0x24,0x24,0x24,0x24},
99 {0x24,0x24,0x24,0x24},
100 {0x20,0x20,0x20,0x20},
101 {0x20,0x20,0x20,0x20},
102 {0x24,0x24,0x24,0x24}
103};
104#endif
105
106/* From 630/301B BIOS */
107static const UCHAR SiS300_OEMLCDDelay2[64][4] = /* for 301/301b/302b/301LV/302LV */
108{
109 {0x20,0x20,0x20,0x20},
110 {0x20,0x20,0x20,0x20},
111 {0x20,0x20,0x20,0x20},
112 {0x20,0x20,0x20,0x20},
113 {0x20,0x20,0x20,0x20},
114 {0x20,0x20,0x20,0x20},
115 {0x20,0x20,0x20,0x20},
116 {0x20,0x20,0x20,0x20},
117 {0x20,0x20,0x20,0x20},
118 {0x20,0x20,0x20,0x20},
119 {0x20,0x20,0x20,0x20},
120 {0x20,0x20,0x20,0x20},
121 {0x20,0x20,0x20,0x20},
122 {0x20,0x20,0x20,0x20},
123 {0x20,0x20,0x20,0x20},
124 {0x20,0x20,0x20,0x20},
125 {0x20,0x20,0x20,0x20},
126 {0x20,0x20,0x20,0x20},
127 {0x20,0x20,0x20,0x20},
128 {0x20,0x20,0x20,0x20},
129 {0x20,0x20,0x20,0x20},
130 {0x20,0x20,0x20,0x20},
131 {0x20,0x20,0x20,0x20},
132 {0x20,0x20,0x20,0x20},
133 {0x20,0x20,0x20,0x20},
134 {0x20,0x20,0x20,0x20},
135 {0x20,0x20,0x20,0x20},
136 {0x20,0x20,0x20,0x20},
137 {0x20,0x20,0x20,0x20},
138 {0x20,0x20,0x20,0x20},
139 {0x20,0x20,0x20,0x20},
140 {0x20,0x20,0x20,0x20},
141 {0x20,0x20,0x20,0x20},
142 {0x20,0x20,0x20,0x20},
143 {0x20,0x20,0x20,0x20},
144 {0x20,0x20,0x20,0x20},
145 {0x20,0x20,0x20,0x20},
146 {0x20,0x20,0x20,0x20},
147 {0x20,0x20,0x20,0x20},
148 {0x20,0x20,0x20,0x20},
149 {0x20,0x20,0x20,0x20},
150 {0x20,0x20,0x20,0x20},
151 {0x20,0x20,0x20,0x20},
152 {0x20,0x20,0x20,0x20},
153 {0x20,0x20,0x20,0x20},
154 {0x20,0x20,0x20,0x20},
155 {0x20,0x20,0x20,0x20},
156 {0x20,0x20,0x20,0x20},
157 {0x20,0x20,0x20,0x20},
158 {0x20,0x20,0x20,0x20},
159 {0x20,0x20,0x20,0x20},
160 {0x20,0x20,0x20,0x20},
161 {0x20,0x20,0x20,0x20},
162 {0x20,0x20,0x20,0x20},
163 {0x20,0x20,0x20,0x20},
164 {0x20,0x20,0x20,0x20},
165 {0x20,0x20,0x20,0x20},
166 {0x20,0x20,0x20,0x20},
167 {0x20,0x20,0x20,0x20},
168 {0x20,0x20,0x20,0x20},
169 {0x20,0x20,0x20,0x20},
170 {0x20,0x20,0x20,0x20},
171 {0x20,0x20,0x20,0x20},
172 {0x20,0x20,0x20,0x20}
173};
174
175/* From 300/301LV BIOS */
176static const UCHAR SiS300_OEMLCDDelay4[12][4] =
177{
178 {0x2c,0x2c,0x2c,0x2c},
179 {0x20,0x20,0x20,0x20},
180 {0x20,0x20,0x20,0x20},
181 {0x2c,0x2c,0x2c,0x2c},
182 {0x2c,0x2c,0x2c,0x2c},
183 {0x20,0x20,0x20,0x20},
184 {0x20,0x20,0x20,0x20},
185 {0x24,0x24,0x24,0x24},
186 {0x24,0x24,0x24,0x24},
187 {0x20,0x20,0x20,0x20},
188 {0x20,0x20,0x20,0x20},
189 {0x24,0x24,0x24,0x24}
190};
191
192/* From 300/301LV BIOS */
193static const UCHAR SiS300_OEMLCDDelay5[32][4] =
194{
195 {0x20,0x20,0x20,0x20},
196 {0x20,0x20,0x20,0x20},
197 {0x20,0x20,0x20,0x20},
198 {0x20,0x20,0x20,0x20},
199 {0x20,0x20,0x20,0x20},
200 {0x20,0x20,0x20,0x20},
201 {0x20,0x20,0x20,0x20},
202 {0x20,0x20,0x20,0x20},
203 {0x20,0x20,0x20,0x20},
204 {0x20,0x20,0x20,0x20},
205 {0x20,0x20,0x20,0x20},
206 {0x20,0x20,0x20,0x20},
207 {0x20,0x20,0x20,0x20},
208 {0x20,0x20,0x20,0x20},
209 {0x20,0x20,0x20,0x20},
210 {0x20,0x20,0x20,0x20},
211 {0x20,0x20,0x20,0x20},
212 {0x20,0x20,0x20,0x20},
213 {0x20,0x20,0x20,0x20},
214 {0x20,0x20,0x20,0x20},
215 {0x20,0x20,0x20,0x20},
216 {0x20,0x20,0x20,0x20},
217 {0x20,0x20,0x20,0x20},
218 {0x20,0x20,0x20,0x20},
219 {0x20,0x20,0x20,0x20},
220 {0x20,0x20,0x20,0x20},
221 {0x20,0x20,0x20,0x20},
222 {0x20,0x20,0x20,0x20},
223 {0x20,0x20,0x20,0x20},
224 {0x20,0x20,0x20,0x20},
225 {0x20,0x20,0x20,0x20},
226 {0x20,0x20,0x20,0x20},
227};
228
229/* Added for LVDS */
230static const UCHAR SiS300_OEMLCDDelay3[64][4] = { /* For LVDS */
231 {0x20,0x20,0x20,0x20},
232 {0x20,0x20,0x20,0x20},
233 {0x20,0x20,0x20,0x20},
234 {0x20,0x20,0x20,0x20},
235 {0x20,0x20,0x20,0x20},
236 {0x20,0x20,0x20,0x20},
237 {0x20,0x20,0x20,0x20},
238 {0x20,0x20,0x20,0x20},
239 {0x20,0x20,0x20,0x20},
240 {0x20,0x20,0x20,0x20},
241 {0x20,0x20,0x20,0x20},
242 {0x20,0x20,0x20,0x20},
243 {0x20,0x20,0x20,0x20},
244 {0x20,0x20,0x20,0x20},
245 {0x20,0x20,0x20,0x20},
246 {0x20,0x20,0x20,0x20},
247 {0x20,0x20,0x20,0x20},
248 {0x20,0x20,0x20,0x20},
249 {0x20,0x20,0x20,0x20},
250 {0x20,0x20,0x20,0x20},
251 {0x20,0x20,0x20,0x20},
252 {0x20,0x20,0x20,0x20},
253 {0x20,0x20,0x20,0x20},
254 {0x20,0x20,0x20,0x20},
255 {0x20,0x20,0x20,0x20},
256 {0x20,0x20,0x20,0x20},
257 {0x20,0x20,0x20,0x20},
258 {0x20,0x20,0x20,0x20},
259 {0x20,0x20,0x20,0x20},
260 {0x20,0x20,0x20,0x20},
261 {0x20,0x20,0x20,0x20},
262 {0x20,0x20,0x20,0x20},
263 {0x20,0x20,0x20,0x20},
264 {0x20,0x20,0x20,0x20},
265 {0x20,0x20,0x20,0x20},
266 {0x20,0x20,0x20,0x20},
267 {0x20,0x20,0x20,0x20},
268 {0x20,0x20,0x20,0x20},
269 {0x20,0x20,0x20,0x20},
270 {0x20,0x20,0x20,0x20},
271 {0x20,0x20,0x20,0x20},
272 {0x20,0x20,0x20,0x20},
273 {0x20,0x20,0x20,0x20},
274 {0x20,0x20,0x20,0x20},
275 {0x20,0x20,0x20,0x20},
276 {0x20,0x20,0x20,0x20},
277 {0x20,0x20,0x20,0x20},
278 {0x20,0x20,0x20,0x20},
279 {0x20,0x20,0x20,0x20},
280 {0x20,0x20,0x20,0x20},
281 {0x20,0x20,0x20,0x20},
282 {0x20,0x20,0x20,0x20},
283 {0x20,0x20,0x20,0x20},
284 {0x20,0x20,0x20,0x20},
285 {0x20,0x20,0x20,0x20},
286 {0x20,0x20,0x20,0x20},
287 {0x20,0x20,0x20,0x20},
288 {0x20,0x20,0x20,0x20},
289 {0x20,0x20,0x20,0x20},
290 {0x20,0x20,0x20,0x20},
291 {0x20,0x20,0x20,0x20},
292 {0x20,0x20,0x20,0x20},
293 {0x20,0x20,0x20,0x20},
294 {0x20,0x20,0x20,0x20}
295};
296
297static const UCHAR SiS300_Phase1[8][5][4] =
298{
299 {
300 {0x21,0xed,0x00,0x08},
301 {0x21,0xed,0x8a,0x08},
302 {0x21,0xed,0x8a,0x08},
303 {0x21,0xed,0x8a,0x08},
304 {0x21,0xed,0x8a,0x08}
305 },
306 {
307 {0x2a,0x05,0xd3,0x00},
308 {0x2a,0x05,0xd3,0x00},
309 {0x2a,0x05,0xd3,0x00},
310 {0x2a,0x05,0xd3,0x00},
311 {0x2a,0x05,0xd3,0x00}
312 },
313 {
314 {0x2a,0x05,0xd3,0x00},
315 {0x2a,0x05,0xd3,0x00},
316 {0x2a,0x05,0xd3,0x00},
317 {0x2a,0x05,0xd3,0x00},
318 {0x2a,0x05,0xd3,0x00}
319 },
320 {
321 {0x2a,0x05,0xd3,0x00},
322 {0x2a,0x05,0xd3,0x00},
323 {0x2a,0x05,0xd3,0x00},
324 {0x2a,0x05,0xd3,0x00},
325 {0x2a,0x05,0xd3,0x00}
326 },
327 {
328 {0x21,0xed,0x00,0x08},
329 {0x21,0xed,0x8a,0x08},
330 {0x21,0xed,0x8a,0x08},
331 {0x21,0xed,0x8a,0x08},
332 {0x21,0xed,0x8a,0x08}
333 },
334 {
335 {0x2a,0x05,0xd3,0x00},
336 {0x2a,0x05,0xd3,0x00},
337 {0x2a,0x05,0xd3,0x00},
338 {0x2a,0x05,0xd3,0x00},
339 {0x2a,0x05,0xd3,0x00}
340 },
341 {
342 {0x2a,0x05,0xd3,0x00},
343 {0x2a,0x05,0xd3,0x00},
344 {0x2a,0x05,0xd3,0x00},
345 {0x2a,0x05,0xd3,0x00},
346 {0x2a,0x05,0xd3,0x00}
347 },
348 {
349 {0x2a,0x05,0xd3,0x00},
350 {0x2a,0x05,0xd3,0x00},
351 {0x2a,0x05,0xd3,0x00},
352 {0x2a,0x05,0xd3,0x00},
353 {0x2a,0x05,0xd3,0x00}
354 }
355};
356
357
358static const UCHAR SiS300_Phase2[8][5][4] =
359{
360 {
361 {0x21,0xed,0x00,0x08},
362 {0x21,0xed,0x8a,0x08},
363 {0x21,0xed,0x8a,0x08},
364 {0x21,0xed,0x8a,0x08},
365 {0x21,0xed,0x8a,0x08}
366 },
367 {
368 {0x2a,0x05,0xd3,0x00},
369 {0x2a,0x05,0xd3,0x00},
370 {0x2a,0x05,0xd3,0x00},
371 {0x2a,0x05,0xd3,0x00},
372 {0x2a,0x05,0xd3,0x00}
373 },
374 {
375 {0x2a,0x05,0xd3,0x00},
376 {0x2a,0x05,0xd3,0x00},
377 {0x2a,0x05,0xd3,0x00},
378 {0x2a,0x05,0xd3,0x00},
379 {0x2a,0x05,0xd3,0x00}
380 },
381 {
382 {0x2a,0x05,0xd3,0x00},
383 {0x2a,0x05,0xd3,0x00},
384 {0x2a,0x05,0xd3,0x00},
385 {0x2a,0x05,0xd3,0x00},
386 {0x2a,0x05,0xd3,0x00}
387 },
388 {
389 {0x21,0xed,0x00,0x08},
390 {0x21,0xed,0x8a,0x08},
391 {0x21,0xed,0x8a,0x08},
392 {0x21,0xed,0x8a,0x08},
393 {0x21,0xed,0x8a,0x08}
394 },
395 {
396 {0x2a,0x05,0xd3,0x00},
397 {0x2a,0x05,0xd3,0x00},
398 {0x2a,0x05,0xd3,0x00},
399 {0x2a,0x05,0xd3,0x00},
400 {0x2a,0x05,0xd3,0x00}
401 },
402 {
403 {0x2a,0x05,0xd3,0x00},
404 {0x2a,0x05,0xd3,0x00},
405 {0x2a,0x05,0xd3,0x00},
406 {0x2a,0x05,0xd3,0x00},
407 {0x2a,0x05,0xd3,0x00}
408 },
409 {
410 {0x2a,0x05,0xd3,0x00},
411 {0x2a,0x05,0xd3,0x00},
412 {0x2a,0x05,0xd3,0x00},
413 {0x2a,0x05,0xd3,0x00},
414 {0x2a,0x05,0xd3,0x00}
415 }
416};
417
418static const UCHAR SiS300_Filter1[10][16][4] =
419{
420 {
421 {0x00,0xf4,0x10,0x38},
422 {0x00,0xf4,0x10,0x38},
423 {0xeb,0x04,0x10,0x18},
424 {0xf7,0x06,0x19,0x14},
425 {0x00,0xf4,0x10,0x38},
426 {0xeb,0x04,0x25,0x18},
427 {0xeb,0x04,0x25,0x18},
428 {0xeb,0x15,0x25,0xf6},
429 {0xeb,0x04,0x25,0x18},
430 {0xeb,0x04,0x25,0x18},
431 {0xeb,0x04,0x25,0x18},
432 {0xeb,0x04,0x25,0x18},
433 {0xeb,0x04,0x25,0x18},
434 {0xeb,0x04,0x25,0x18},
435 {0xeb,0x04,0x25,0x18},
436 {0xeb,0x04,0x25,0x18}
437 },
438 {
439 {0x00,0xf4,0x10,0x38},
440 {0x00,0xf4,0x10,0x38},
441 {0xf1,0xf7,0x10,0x32},
442 {0xf3,0x00,0x1d,0x20},
443 {0x00,0xf4,0x10,0x38},
444 {0xf1,0xf7,0x1f,0x32},
445 {0xf1,0xf7,0x1f,0x32},
446 {0xfc,0xfb,0x14,0x2a},
447 {0xf1,0xf7,0x1f,0x32},
448 {0xf1,0xf7,0x1f,0x32},
449 {0xf1,0xf7,0x1f,0x32},
450 {0xf1,0xf7,0x1f,0x32},
451 {0xf1,0xf7,0x1f,0x32},
452 {0xf1,0xf7,0x1f,0x32},
453 {0xf1,0xf7,0x1f,0x32},
454 {0xf1,0xf7,0x1f,0x32}
455 },
456 {
457 {0x00,0xf4,0x10,0x38},
458 {0x00,0xf4,0x10,0x38},
459 {0xf1,0xf7,0x10,0x32},
460 {0xf3,0x00,0x1d,0x20},
461 {0x00,0xf4,0x10,0x38},
462 {0xf1,0xf7,0x1f,0x32},
463 {0xf1,0xf7,0x1f,0x32},
464 {0xfc,0xfb,0x14,0x2a},
465 {0xf1,0xf7,0x1f,0x32},
466 {0xf1,0xf7,0x1f,0x32},
467 {0xf1,0xf7,0x1f,0x32},
468 {0xf1,0xf7,0x1f,0x32},
469 {0xf1,0xf7,0x1f,0x32},
470 {0xf1,0xf7,0x1f,0x32},
471 {0xf1,0xf7,0x1f,0x32},
472 {0xf1,0xf7,0x1f,0x32}
473 },
474 {
475 {0x00,0xf4,0x10,0x38},
476 {0x00,0xf4,0x10,0x38},
477 {0xf1,0xf7,0x10,0x32},
478 {0xf3,0x00,0x1d,0x20},
479 {0x00,0xf4,0x10,0x38},
480 {0xf1,0xf7,0x1f,0x32},
481 {0xf1,0xf7,0x1f,0x32},
482 {0xfc,0xfb,0x14,0x2a},
483 {0xf1,0xf7,0x1f,0x32},
484 {0xf1,0xf7,0x1f,0x32},
485 {0xf1,0xf7,0x1f,0x32},
486 {0xf1,0xf7,0x1f,0x32},
487 {0xf1,0xf7,0x1f,0x32},
488 {0xf1,0xf7,0x1f,0x32},
489 {0xf1,0xf7,0x1f,0x32},
490 {0xf1,0xf7,0x1f,0x32}
491 },
492 {
493 {0x00,0xf4,0x10,0x38},
494 {0x00,0xf4,0x10,0x38},
495 {0xeb,0x04,0x10,0x18},
496 {0xf7,0x06,0x19,0x14},
497 {0x00,0xf4,0x10,0x38},
498 {0xeb,0x04,0x25,0x18},
499 {0xeb,0x04,0x25,0x18},
500 {0xeb,0x15,0x25,0xf6},
501 {0xeb,0x04,0x25,0x18},
502 {0xeb,0x04,0x25,0x18},
503 {0xeb,0x04,0x25,0x18},
504 {0xeb,0x04,0x25,0x18},
505 {0xeb,0x04,0x25,0x18},
506 {0xeb,0x04,0x25,0x18},
507 {0xeb,0x04,0x25,0x18},
508 {0xeb,0x04,0x25,0x18}
509 },
510 {
511 {0x00,0xf4,0x10,0x38},
512 {0x00,0xf4,0x10,0x38},
513 {0xf1,0xf7,0x10,0x32},
514 {0xf3,0x00,0x1d,0x20},
515 {0x00,0xf4,0x10,0x38},
516 {0xf1,0xf7,0x1f,0x32},
517 {0xf1,0xf7,0x1f,0x32},
518 {0xfc,0xfb,0x14,0x2a},
519 {0xf1,0xf7,0x1f,0x32},
520 {0xf1,0xf7,0x1f,0x32},
521 {0xf1,0xf7,0x1f,0x32},
522 {0xf1,0xf7,0x1f,0x32},
523 {0xf1,0xf7,0x1f,0x32},
524 {0xf1,0xf7,0x1f,0x32},
525 {0xf1,0xf7,0x1f,0x32},
526 {0xf1,0xf7,0x1f,0x32}
527 },
528 {
529 {0x00,0xf4,0x10,0x38},
530 {0x00,0xf4,0x10,0x38},
531 {0xf1,0xf7,0x10,0x32},
532 {0xf3,0x00,0x1d,0x20},
533 {0x00,0xf4,0x10,0x38},
534 {0xf1,0xf7,0x1f,0x32},
535 {0xf1,0xf7,0x1f,0x32},
536 {0xfc,0xfb,0x14,0x2a},
537 {0xf1,0xf7,0x1f,0x32},
538 {0xf1,0xf7,0x1f,0x32},
539 {0xf1,0xf7,0x1f,0x32},
540 {0xf1,0xf7,0x1f,0x32},
541 {0xf1,0xf7,0x1f,0x32},
542 {0xf1,0xf7,0x1f,0x32},
543 {0xf1,0xf7,0x1f,0x32},
544 {0xf1,0xf7,0x1f,0x32}
545 },
546 {
547 {0x00,0xf4,0x10,0x38},
548 {0x00,0xf4,0x10,0x38},
549 {0xf1,0xf7,0x10,0x32},
550 {0xf3,0x00,0x1d,0x20},
551 {0x00,0xf4,0x10,0x38},
552 {0xf1,0xf7,0x1f,0x32},
553 {0xf1,0xf7,0x1f,0x32},
554 {0xfc,0xfb,0x14,0x2a},
555 {0xf1,0xf7,0x1f,0x32},
556 {0xf1,0xf7,0x1f,0x32},
557 {0xf1,0xf7,0x1f,0x32},
558 {0xf1,0xf7,0x1f,0x32},
559 {0xf1,0xf7,0x1f,0x32},
560 {0xf1,0xf7,0x1f,0x32},
561 {0xf1,0xf7,0x1f,0x32},
562 {0xf1,0xf7,0x1f,0x32}
563 },
564 {
565 {0x00,0xf4,0x10,0x38},
566 {0x00,0xf4,0x10,0x38},
567 {0xeb,0x04,0x10,0x18},
568 {0xf7,0x06,0x19,0x14},
569 {0x00,0xf4,0x10,0x38},
570 {0xeb,0x04,0x25,0x18},
571 {0xeb,0x04,0x25,0x18},
572 {0xeb,0x15,0x25,0xf6},
573 {0xeb,0x04,0x25,0x18},
574 {0xeb,0x04,0x25,0x18},
575 {0xeb,0x04,0x25,0x18},
576 {0xeb,0x04,0x25,0x18},
577 {0xeb,0x04,0x25,0x18},
578 {0xeb,0x04,0x25,0x18},
579 {0xeb,0x04,0x25,0x18},
580 {0xeb,0x04,0x25,0x18}
581 },
582 {
583 {0x00,0xf4,0x10,0x38},
584 {0x00,0xf4,0x10,0x38},
585 {0xeb,0x04,0x10,0x18},
586 {0xf7,0x06,0x19,0x14},
587 {0x00,0xf4,0x10,0x38},
588 {0xeb,0x04,0x25,0x18},
589 {0xeb,0x04,0x25,0x18},
590 {0xeb,0x15,0x25,0xf6},
591 {0xeb,0x04,0x25,0x18},
592 {0xeb,0x04,0x25,0x18},
593 {0xeb,0x04,0x25,0x18},
594 {0xeb,0x04,0x25,0x18},
595 {0xeb,0x04,0x25,0x18},
596 {0xeb,0x04,0x25,0x18},
597 {0xeb,0x04,0x25,0x18},
598 {0xeb,0x04,0x25,0x18}
599 },
600};
601
602static const UCHAR SiS300_Filter2[10][9][7] =
603{
604 {
605 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
606 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
607 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
608 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
609 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
610 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
611 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
612 {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
613 {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
614 },
615 {
616 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
617 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
618 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
619 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
620 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
621 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
622 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
623 {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
624 {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
625 },
626 {
627 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
628 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
629 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
630 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
631 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
632 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
633 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
634 {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
635 {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
636 },
637 {
638 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
639 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
640 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
641 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
642 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
643 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
644 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
645 {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
646 {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
647 },
648 {
649 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
650 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
651 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
652 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
653 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
654 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
655 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
656 {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
657 {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
658 },
659 {
660 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
661 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
662 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
663 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
664 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
665 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
666 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
667 {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
668 {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
669 },
670 {
671 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
672 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
673 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
674 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
675 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
676 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
677 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
678 {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
679 {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
680 },
681 {
682 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
683 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
684 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
685 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
686 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
687 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
688 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
689 {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
690 {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
691 },
692 {
693 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
694 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
695 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
696 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
697 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
698 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
699 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
700 {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
701 {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
702 },
703 {
704 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
705 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
706 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
707 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
708 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
709 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
710 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
711 {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
712 {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
713 }
714};
715
716/* Custom data for Barco iQ Pro R300 */
717static const UCHAR barco_p1[2][9][7][3] = {
718 {
719 { { 0x16, 0xcf, 0x00 },
720 { 0x18, 0x00, 0x00 },
721 { 0x1a, 0xe7, 0x00 },
722 { 0x1b, 0x26, 0x00 },
723 { 0x1c, 0xff, 0x00 },
724 { 0x1d, 0x1c, 0x00 },
725 { 0x1e, 0x19, 0x00 }
726 },
727 {
728 { 0x16, 0xcf, 0x00 },
729 { 0x18, 0x00, 0x00 },
730 { 0x1a, 0xe7, 0x00 },
731 { 0x1b, 0x1e, 0x00 },
732 { 0x1c, 0xff, 0x00 },
733 { 0x1d, 0x1c, 0x00 },
734 { 0x1e, 0x16, 0x00 }
735 },
736 {
737 { 0x16, 0xcf, 0x00 },
738 { 0x1a, 0xe7, 0x00 },
739 { 0x1b, 0x26, 0x00 },
740 { 0x1c, 0xff, 0x00 },
741 { 0x1d, 0x1c, 0x00 },
742 { 0x1e, 0x19, 0x00 },
743 { 0, 0, 0 }
744 },
745 {
746 { 0, 0, 0 }
747 },
748 {
749 { 0x16, 0xcf, 0x00 },
750 { 0x1a, 0xe7, 0x00 },
751 { 0x1b, 0x26, 0x00 },
752 { 0x1c, 0xff, 0x00 },
753 { 0x1d, 0x1c, 0x00 },
754 { 0x1e, 0x1e, 0x00 },
755 { 0, 0, 0 }
756 },
757 {
758 { 0x16, 0xd1, 0x00 },
759 { 0x18, 0x00, 0x00 },
760 { 0x1a, 0xe7, 0x00 },
761 { 0x1b, 0x11, 0x00 },
762 { 0x1c, 0xff, 0x00 },
763 { 0x1d, 0x1c, 0x00 },
764 { 0x1e, 0x26, 0x00 }
765 },
766 {
767 { 0x16, 0xd1, 0x00 },
768 { 0x1a, 0xe7, 0x00 },
769 { 0x1b, 0x26, 0x00 },
770 { 0x1c, 0xff, 0x00 },
771 { 0x1d, 0x1c, 0x00 },
772 { 0x1e, 0x30, 0x00 },
773 { 0, 0, 0 }
774 },
775 {
776 { 0x16, 0x00, 0x00 },
777 { 0x17, 0xa0, 0x00 },
778 { 0x1a, 0xa0, 0x00 },
779 { 0x1b, 0x2a, 0x00 },
780 { 0x1c, 0xff, 0x00 },
781 { 0x1d, 0x1c, 0x00 },
782 { 0, 0, 0 }
783 },
784 {
785 { 0x16, 0x00, 0x00 },
786 { 0x17, 0xaa, 0x00 },
787 { 0x1a, 0xa0, 0x00 },
788 { 0x1b, 0x2a, 0x00 },
789 { 0x1c, 0xff, 0x00 },
790 { 0x1d, 0x1c, 0x00 },
791 { 0, 0, 0 }
792 }
793 },
794 {
795 {
796 { 0x16, 0xcf, 0x00 },
797 { 0x18, 0x00, 0x00 },
798 { 0x1a, 0xe7, 0x00 },
799 { 0x1b, 0x26, 0x00 },
800 { 0x1c, 0xff, 0x00 },
801 { 0x1d, 0x1c, 0x00 },
802 { 0x1e, 0x19, 0x00 }
803 },
804 {
805 { 0, 0, 0 }
806 },
807 {
808 { 0x16, 0xcf, 0x00 },
809 { 0x18, 0x00, 0x00 },
810 { 0x1a, 0xe7, 0x00 },
811 { 0x1b, 0x26, 0x00 },
812 { 0x1c, 0xff, 0x00 },
813 { 0x1d, 0x1c, 0x00 },
814 { 0x1e, 0x19, 0x00 },
815 },
816 {
817 { 0, 0, 0 }
818 },
819 {
820 { 0x16, 0xcf, 0x00 },
821 { 0x18, 0x00, 0x00 },
822 { 0x1a, 0xe7, 0x00 },
823 { 0x1b, 0x26, 0x00 },
824 { 0x1c, 0xff, 0x00 },
825 { 0x1d, 0x1c, 0x00 },
826 { 0x1e, 0x1e, 0x00 }
827 },
828 {
829 { 0x16, 0xd1, 0x00 },
830 { 0x18, 0x00, 0x00 },
831 { 0x1a, 0xe6, 0x00 },
832 { 0x1b, 0x11, 0x00 },
833 { 0x1c, 0xff, 0x00 },
834 { 0x1d, 0x1c, 0x00 },
835 { 0x1e, 0x26, 0x00 }
836 },
837 {
838 { 0x18, 0x00, 0x00 },
839 { 0x1a, 0xe0, 0x00 },
840 { 0x1b, 0x26, 0x00 },
841 { 0x1c, 0xff, 0x00 },
842 { 0x1d, 0x1c, 0x00 },
843 { 0x1e, 0x30, 0x00 },
844 { 0, 0, 0 }
845 },
846 {
847 { 0, 0, 0 }
848 },
849 {
850 { 0, 0, 0 }
851 }
852 }
853};
854
855
856
857
858
859
diff --git a/drivers/video/sis/oem310.h b/drivers/video/sis/oem310.h
new file mode 100644
index 000000000000..2b7db916b7e7
--- /dev/null
+++ b/drivers/video/sis/oem310.h
@@ -0,0 +1,449 @@
1/* $XFree86$ */
2/* $XdotOrg$ */
3/*
4 * OEM Data for 315/330 series
5 *
6 * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
7 *
8 * If distributed as part of the Linux kernel, the following license terms
9 * apply:
10 *
11 * * This program is free software; you can redistribute it and/or modify
12 * * it under the terms of the GNU General Public License as published by
13 * * the Free Software Foundation; either version 2 of the named License,
14 * * or any later version.
15 * *
16 * * This program is distributed in the hope that it will be useful,
17 * * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * * GNU General Public License for more details.
20 * *
21 * * You should have received a copy of the GNU General Public License
22 * * along with this program; if not, write to the Free Software
23 * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
24 *
25 * Otherwise, the following license terms apply:
26 *
27 * * Redistribution and use in source and binary forms, with or without
28 * * modification, are permitted provided that the following conditions
29 * * are met:
30 * * 1) Redistributions of source code must retain the above copyright
31 * * notice, this list of conditions and the following disclaimer.
32 * * 2) Redistributions in binary form must reproduce the above copyright
33 * * notice, this list of conditions and the following disclaimer in the
34 * * documentation and/or other materials provided with the distribution.
35 * * 3) The name of the author may not be used to endorse or promote products
36 * * derived from this software without specific prior written permission.
37 * *
38 * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
39 * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
40 * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
41 * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
42 * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
43 * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
44 * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
45 * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46 * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
47 * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48 *
49 * Author: Thomas Winischhofer <thomas@winischhofer.net>
50 *
51 */
52
53static const UCHAR SiS310_LCDDelayCompensation_301[] = /* 301 */
54{
55 0x00,0x00,0x00, /* 800x600 */
56 0x0b,0x0b,0x0b, /* 1024x768 */
57 0x08,0x08,0x08, /* 1280x1024 */
58 0x00,0x00,0x00, /* 640x480 (unknown) */
59 0x00,0x00,0x00, /* 1024x600 (unknown) */
60 0x00,0x00,0x00, /* 1152x864 (unknown) */
61 0x08,0x08,0x08, /* 1280x960 (guessed) */
62 0x00,0x00,0x00, /* 1152x768 (unknown) */
63 0x08,0x08,0x08, /* 1400x1050 */
64 0x08,0x08,0x08, /* 1280x768 (guessed) */
65 0x00,0x00,0x00, /* 1600x1200 */
66 0x00,0x00,0x00, /* 320x480 (unknown) */
67 0x00,0x00,0x00,
68 0x00,0x00,0x00,
69 0x00,0x00,0x00
70};
71
72/* This is contained in 650+301B BIOSes, but it is wrong - so we don't use it */
73static const UCHAR SiS310_LCDDelayCompensation_650301LV[] = /* 650 + 30xLV */
74{
75 0x01,0x01,0x01, /* 800x600 */
76 0x01,0x01,0x01, /* 1024x768 */
77 0x01,0x01,0x01, /* 1280x1024 */
78 0x01,0x01,0x01, /* 640x480 (unknown) */
79 0x01,0x01,0x01, /* 1024x600 (unknown) */
80 0x01,0x01,0x01, /* 1152x864 (unknown) */
81 0x01,0x01,0x01, /* 1280x960 (guessed) */
82 0x01,0x01,0x01, /* 1152x768 (unknown) */
83 0x01,0x01,0x01, /* 1400x1050 */
84 0x01,0x01,0x01, /* 1280x768 (guessed) */
85 0x01,0x01,0x01, /* 1600x1200 */
86 0x02,0x02,0x02,
87 0x02,0x02,0x02,
88 0x02,0x02,0x02,
89 0x02,0x02,0x02
90};
91
92static const UCHAR SiS310_LCDDelayCompensation_651301LV[] = /* M650/651 301LV */
93{
94 0x33,0x33,0x33, /* 800x600 (guessed) - new: PanelType, not PanelRes ! */
95 0x33,0x33,0x33, /* 1024x768 */
96 0x33,0x33,0x33, /* 1280x1024 */
97 0x33,0x33,0x33, /* 640x480 (unknown) */
98 0x33,0x33,0x33, /* 1024x600 (unknown) */
99 0x33,0x33,0x33, /* 1152x864 (unknown) */
100 0x33,0x33,0x33, /* 1280x960 (guessed) */
101 0x33,0x33,0x33, /* 1152x768 (unknown) */
102 0x33,0x33,0x33, /* 1400x1050 */
103 0x33,0x33,0x33, /* 1280x768 (guessed) */
104 0x33,0x33,0x33, /* 1600x1200 */
105 0x33,0x33,0x33,
106 0x33,0x33,0x33,
107 0x33,0x33,0x33,
108 0x33,0x33,0x33
109};
110
111static const UCHAR SiS310_LCDDelayCompensation_651302LV[] = /* M650/651 302LV */
112{
113 0x33,0x33,0x33, /* 800x600 (guessed) */
114 0x33,0x33,0x33, /* 1024x768 */
115 0x33,0x33,0x33, /* 1280x1024 */
116 0x33,0x33,0x33, /* 640x480 (unknown) */
117 0x33,0x33,0x33, /* 1024x600 (unknown) */
118 0x33,0x33,0x33, /* 1152x864 (unknown) */
119 0x33,0x33,0x33, /* 1280x960 (guessed) */
120 0x33,0x33,0x33, /* 1152x768 (unknown) */
121 0x33,0x33,0x33, /* 1400x1050 */
122 0x33,0x33,0x33, /* 1280x768 (guessed) */
123 0x33,0x33,0x33, /* 1600x1200 */
124 0x33,0x33,0x33,
125 0x33,0x33,0x33,
126 0x33,0x33,0x33,
127 0x33,0x33,0x33
128};
129
130static const UCHAR SiS310_LCDDelayCompensation_3xx301B[] = /* 30xB */
131{
132 0x01,0x01,0x01, /* 800x600 */
133 0x0C,0x0C,0x0C, /* 1024x768 */
134 0x0C,0x0C,0x0C, /* 1280x1024 */
135 0x08,0x08,0x08, /* 640x480 */
136 0x0C,0x0C,0x0C, /* 1024x600 (guessed) */
137 0x0C,0x0C,0x0C, /* 1152x864 (guessed) */
138 0x0C,0x0C,0x0C, /* 1280x960 (guessed) */
139 0x0C,0x0C,0x0C, /* 1152x768 (guessed) */
140 0x0C,0x0C,0x0C, /* 1400x1050 (guessed) */
141 0x0C,0x0C,0x0C, /* 1280x768 (guessed) */
142 0x0C,0x0C,0x0C, /* 1600x1200 (guessed) */
143 0x02,0x02,0x02,
144 0x02,0x02,0x02,
145 0x02,0x02,0x02,
146 0x02,0x02,0x02
147};
148
149static const UCHAR SiS310_LCDDelayCompensation_3xx301LV[] = /* 315+30xLV */
150{
151 0x01,0x01,0x01, /* 800x600 */
152 0x04,0x04,0x04, /* 1024x768 (A531/BIOS 1.14.05f: 4 - works with 6 */
153 0x0C,0x0C,0x0C, /* 1280x1024 */
154 0x08,0x08,0x08, /* 640x480 */
155 0x0C,0x0C,0x0C, /* 1024x600 (guessed) */
156 0x0C,0x0C,0x0C, /* 1152x864 (guessed) */
157 0x0C,0x0C,0x0C, /* 1280x960 (guessed) */
158 0x0C,0x0C,0x0C, /* 1152x768 (guessed) */
159 0x0C,0x0C,0x0C, /* 1400x1050 (guessed) */
160 0x0C,0x0C,0x0C, /* 1280x768 (guessed) */
161 0x0C,0x0C,0x0C, /* 1600x1200 (guessed) */
162 0x02,0x02,0x02,
163 0x02,0x02,0x02,
164 0x02,0x02,0x02,
165 0x02,0x02,0x02
166};
167
168static const UCHAR SiS310_TVDelayCompensation_301[] = /* 301 */
169{
170 0x02,0x02, /* NTSC Enhanced, Standard */
171 0x02,0x02, /* PAL */
172 0x08,0x0b /* HiVision */
173};
174
175static const UCHAR SiS310_TVDelayCompensation_301B[] = /* 30xB, 30xLV */
176{
177 0x03,0x03,
178 0x03,0x03,
179 0x03,0x03
180};
181
182static const UCHAR SiS310_TVDelayCompensation_740301B[] = /* 740 + 30xB (30xLV?) */
183{
184 0x05,0x05,
185 0x05,0x05,
186 0x05,0x05
187};
188
189static const UCHAR SiS310_TVDelayCompensation_651301LV[] = /* M650, 651, 301LV */
190{
191 0x33,0x33,
192 0x33,0x33,
193 0x33,0x33
194};
195
196static const UCHAR SiS310_TVDelayCompensation_651302LV[] = /* M650, 651, 302LV */
197{
198 0x33,0x33,
199 0x33,0x33,
200 0x33,0x33
201};
202
203static const UCHAR SiS_TVDelay661_301[] = /* 661, 301 */
204{
205 0x44,0x44,
206 0x44,0x44,
207 0x00,0x00,
208 0x44,0x44,
209 0x44,0x44,
210 0x44,0x44
211};
212
213static const UCHAR SiS_TVDelay661_301B[] = /* 661, 301B et al */
214{
215 0x44,0x44,
216 0x44,0x44,
217 0x00,0x00,
218 0x44,0x44,
219 0x44,0x44,
220 0x44,0x44
221};
222
223static const UCHAR SiS310_TVDelayCompensation_LVDS[] = /* LVDS */
224{
225 0x0a,0x0a,
226 0x0a,0x0a,
227 0x0a,0x0a
228};
229
230static const UCHAR SiS310_TVAntiFlick1[6][2] =
231{
232 {0x4,0x0},
233 {0x4,0x8},
234 {0x0,0x0},
235 {0x0,0x0},
236 {0x0,0x0},
237 {0x0,0x0}
238};
239
240static const UCHAR SiS310_TVEdge1[6][2] =
241{
242 {0x0,0x4},
243 {0x0,0x4},
244 {0x0,0x0},
245 {0x0,0x0},
246 {0x0,0x0},
247 {0x0,0x0}
248};
249
250static const UCHAR SiS310_TVYFilter1[5][8][4] =
251{
252 {
253 {0x00,0xf4,0x10,0x38}, /* NTSC */
254 {0x00,0xf4,0x10,0x38},
255 {0xeb,0x04,0x25,0x18},
256 {0xf1,0x04,0x1f,0x18},
257 {0x00,0xf4,0x10,0x38},
258 {0xeb,0x04,0x25,0x18},
259 {0xee,0x0c,0x22,0x08},
260 {0xeb,0x15,0x25,0xf6}
261 },
262 {
263 {0x00,0xf4,0x10,0x38}, /* PAL */
264 {0x00,0xf4,0x10,0x38},
265 {0xf1,0xf7,0x1f,0x32},
266 {0xf3,0x00,0x1d,0x20},
267 {0x00,0xf4,0x10,0x38},
268 {0xf1,0xf7,0x1f,0x32},
269 {0xf3,0x00,0x1d,0x20},
270 {0xfc,0xfb,0x14,0x2a}
271 },
272 {
273 {0x00,0x00,0x00,0x00}, /* HiVision */
274 {0x00,0xf4,0x10,0x38},
275 {0x00,0xf4,0x10,0x38},
276 {0xeb,0x04,0x25,0x18},
277 {0xf7,0x06,0x19,0x14},
278 {0x00,0xf4,0x10,0x38},
279 {0xeb,0x04,0x25,0x18},
280 {0xee,0x0c,0x22,0x08}
281 },
282 {
283 {0x00,0xf4,0x10,0x38}, /* PAL-M */
284 {0x00,0xf4,0x10,0x38},
285 {0xeb,0x04,0x10,0x18},
286 {0xf7,0x06,0x19,0x14},
287 {0x00,0xf4,0x10,0x38},
288 {0xeb,0x04,0x25,0x18},
289 {0xeb,0x04,0x25,0x18},
290 {0xeb,0x15,0x25,0xf6}
291 },
292 {
293 {0x00,0xf4,0x10,0x38}, /* PAL-N */
294 {0x00,0xf4,0x10,0x38},
295 {0xeb,0x04,0x10,0x18},
296 {0xf7,0x06,0x19,0x14},
297 {0x00,0xf4,0x10,0x38},
298 {0xeb,0x04,0x25,0x18},
299 {0xeb,0x04,0x25,0x18},
300 {0xeb,0x15,0x25,0xf6}
301 }
302};
303
304static const UCHAR SiS310_TVYFilter2[5][9][7] =
305{
306 {
307 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, /* NTSC */
308 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
309 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
310 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
311 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
312 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
313 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
314 {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
315 {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
316 },
317 {
318 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, /* PAL */
319 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
320 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
321 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
322 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
323 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
324 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
325 {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
326 {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
327 },
328 {
329 {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22}, /* HiVision */
330 {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22},
331 {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22},
332 {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22},
333 {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22},
334 {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22},
335 {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22},
336 {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22},
337 {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22}
338 },
339 {
340 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, /* PAL-M */
341 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
342 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
343 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
344 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
345 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
346 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
347 {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
348 {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
349 },
350 {
351 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, /* PAL-N */
352 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
353 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
354 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
355 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
356 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
357 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
358 {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
359 {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
360 }
361};
362
363static const UCHAR SiS310_TVPhaseIncr1[3][2][4] =
364{
365 {
366 {0x21,0xed,0xba,0x08},
367 {0x21,0xed,0xba,0x08}
368 },
369 {
370 {0x2a,0x05,0xe3,0x00},
371 {0x2a,0x05,0xe3,0x00}
372 },
373 {
374 {0x2a,0x05,0xd3,0x00},
375 {0x2a,0x05,0xd3,0x00}
376 }
377};
378
379static const UCHAR SiS310_TVPhaseIncr2[3][2][4] =
380{
381 {
382 {0x21,0xf0,0x7b,0xd6},
383 {0x21,0xf0,0x7b,0xd6}
384 },
385 {
386 {0x2a,0x0a,0x41,0xe9},
387 {0x2a,0x0a,0x41,0xe9}
388 },
389 {
390 {0x2a,0x05,0xd3,0x00},
391 {0x2a,0x05,0xd3,0x00}
392 }
393};
394
395static const UCHAR SiS661_TVPhase[] = {
396 0x21,0xED,0xBA,0x08,
397 0x2A,0x05,0xE3,0x00,
398 0x21,0xE4,0x2E,0x9B,
399 0x21,0xF4,0x3E,0xBA,
400 0x1E,0x8B,0xA2,0xA7,
401 0x1E,0x83,0x0A,0xE0,
402 0x00,0x00,0x00,0x00,
403 0x00,0x00,0x00,0x00,
404 0x21,0xF0,0x7B,0xD6,
405 0x2A,0x09,0x86,0xE9,
406 0x21,0xE6,0xEF,0xA4,
407 0x21,0xF6,0x94,0x46,
408 0x1E,0x8B,0xA2,0xA7,
409 0x1E,0x83,0x0A,0xE0,
410 0x00,0x00,0x00,0x00,
411 0x00,0x00,0x00,0x00
412};
413
414/**************************************************************/
415/* CUSTOM TIMING DATA --------------------------------------- */
416/**************************************************************/
417
418/* Inventec / Compaq Presario 3045US, 3017 */
419
420static const SiS_LCDDataStruct SiS310_ExtCompaq1280x1024Data[] =
421{
422 { 211, 60,1024, 501,1688,1066},
423 { 211, 60,1024, 508,1688,1066},
424 { 211, 60,1024, 501,1688,1066},
425 { 211, 60,1024, 508,1688,1066},
426 { 32, 15,1696, 501,1696,1066},
427 { 212, 75,1024, 621,1696,1066},
428 { 4, 3,1696, 810,1696,1066},
429 { 1, 1,1696,1066,1696,1066}
430};
431
432/* Asus A2xxxH _2 */
433
434static const SiS_Part2PortTblStruct SiS310_CRT2Part2_Asus1024x768_3[] =
435{
436 {{0x25,0x13,0xc9,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
437 {{0x2c,0x13,0x9a,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
438 {{0x25,0x13,0xc9,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
439 {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
440 {{0x38,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
441 {{0x38,0x13,0x16,0x25,0xff,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
442 {{0x36,0x13,0x13,0x25,0xff,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
443 {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
444 {{0x25,0x13,0xc9,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}
445};
446
447
448
449
diff --git a/drivers/video/sis/osdef.h b/drivers/video/sis/osdef.h
new file mode 100644
index 000000000000..15939b057713
--- /dev/null
+++ b/drivers/video/sis/osdef.h
@@ -0,0 +1,131 @@
1/* $XFree86$ */
2/* $XdotOrg$ */
3/*
4 * OS depending defines
5 *
6 * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
7 *
8 * If distributed as part of the Linux kernel, the following license terms
9 * apply:
10 *
11 * * This program is free software; you can redistribute it and/or modify
12 * * it under the terms of the GNU General Public License as published by
13 * * the Free Software Foundation; either version 2 of the named License,
14 * * or any later version.
15 * *
16 * * This program is distributed in the hope that it will be useful,
17 * * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * * GNU General Public License for more details.
20 * *
21 * * You should have received a copy of the GNU General Public License
22 * * along with this program; if not, write to the Free Software
23 * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
24 *
25 * Otherwise, the following license terms apply:
26 *
27 * * Redistribution and use in source and binary forms, with or without
28 * * modification, are permitted provided that the following conditions
29 * * are met:
30 * * 1) Redistributions of source code must retain the above copyright
31 * * notice, this list of conditions and the following disclaimer.
32 * * 2) Redistributions in binary form must reproduce the above copyright
33 * * notice, this list of conditions and the following disclaimer in the
34 * * documentation and/or other materials provided with the distribution.
35 * * 3) The name of the author may not be used to endorse or promote products
36 * * derived from this software without specific prior written permission.
37 * *
38 * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
39 * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
40 * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
41 * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
42 * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
43 * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
44 * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
45 * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46 * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
47 * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48 *
49 * Author: Thomas Winischhofer <thomas@winischhofer.net>
50 * Silicon Integrated Systems, Inc. (used by permission)
51 *
52 */
53
54#ifndef _SIS_OSDEF_H_
55#define _SIS_OSDEF_H_
56
57/* The choices are: */
58#define LINUX_KERNEL /* Linux kernel framebuffer */
59/* #define LINUX_XF86 */ /* XFree86/X.org */
60
61#ifdef OutPortByte
62#undef OutPortByte
63#endif
64
65#ifdef OutPortWord
66#undef OutPortWord
67#endif
68
69#ifdef OutPortLong
70#undef OutPortLong
71#endif
72
73#ifdef InPortByte
74#undef InPortByte
75#endif
76
77#ifdef InPortWord
78#undef InPortWord
79#endif
80
81#ifdef InPortLong
82#undef InPortLong
83#endif
84
85/**********************************************************************/
86/* LINUX KERNEL */
87/**********************************************************************/
88
89#ifdef LINUX_KERNEL
90#include <linux/config.h>
91
92#ifdef CONFIG_FB_SIS_300
93#define SIS300
94#endif
95
96#ifdef CONFIG_FB_SIS_315
97#define SIS315H
98#endif
99
100#if !defined(SIS300) && !defined(SIS315H)
101#warning Neither CONFIG_FB_SIS_300 nor CONFIG_FB_SIS_315 is set
102#warning sisfb will not work!
103#endif
104
105#define OutPortByte(p,v) outb((u8)(v),(SISIOADDRESS)(p))
106#define OutPortWord(p,v) outw((u16)(v),(SISIOADDRESS)(p))
107#define OutPortLong(p,v) outl((u32)(v),(SISIOADDRESS)(p))
108#define InPortByte(p) inb((SISIOADDRESS)(p))
109#define InPortWord(p) inw((SISIOADDRESS)(p))
110#define InPortLong(p) inl((SISIOADDRESS)(p))
111#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset_io(MemoryAddress, value, MemorySize)
112#endif
113
114/**********************************************************************/
115/* XFree86/X.org */
116/**********************************************************************/
117
118#ifdef LINUX_XF86
119#define SIS300
120#define SIS315H
121
122#define OutPortByte(p,v) outSISREG((IOADDRESS)(p),(CARD8)(v))
123#define OutPortWord(p,v) outSISREGW((IOADDRESS)(p),(CARD16)(v))
124#define OutPortLong(p,v) outSISREGL((IOADDRESS)(p),(CARD32)(v))
125#define InPortByte(p) inSISREG((IOADDRESS)(p))
126#define InPortWord(p) inSISREGW((IOADDRESS)(p))
127#define InPortLong(p) inSISREGL((IOADDRESS)(p))
128#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize)
129#endif
130
131#endif /* _OSDEF_H_ */
diff --git a/drivers/video/sis/sis.h b/drivers/video/sis/sis.h
new file mode 100644
index 000000000000..d0103c162e43
--- /dev/null
+++ b/drivers/video/sis/sis.h
@@ -0,0 +1,573 @@
1/*
2 * SiS 300/630/730/540/315/550/[M]650/651/[M]661[FM]X/740/[M]741[GX]/330/[M]760[GX]
3 * frame buffer driver for Linux kernels >=2.4.14 and >=2.6.3
4 *
5 * Copyright (C) 2001-2004 Thomas Winischhofer, Vienna, Austria.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the named License,
10 * or any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
20 */
21
22#ifndef _SIS_H
23#define _SIS_H
24
25#include <linux/config.h>
26#include <linux/version.h>
27
28#include "osdef.h"
29#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
30#include <video/sisfb.h>
31#else
32#include <linux/sisfb.h>
33#endif
34
35#include "vgatypes.h"
36#include "vstruct.h"
37
38#define VER_MAJOR 1
39#define VER_MINOR 7
40#define VER_LEVEL 17
41
42#undef SIS_CONFIG_COMPAT
43
44#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
45#include <linux/spinlock.h>
46#ifdef CONFIG_COMPAT
47#include <linux/ioctl32.h>
48#define SIS_CONFIG_COMPAT
49#endif
50#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,19)
51#ifdef __x86_64__
52/* Shouldn't we check for CONFIG_IA32_EMULATION here? */
53#include <asm/ioctl32.h>
54#define SIS_CONFIG_COMPAT
55#endif
56#endif
57
58#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)
59#define SIS_IOTYPE1 void __iomem
60#define SIS_IOTYPE2 __iomem
61#define SISINITSTATIC static
62#else
63#define SIS_IOTYPE1 unsigned char
64#define SIS_IOTYPE2
65#define SISINITSTATIC
66#endif
67
68#undef SISFBDEBUG
69
70#ifdef SISFBDEBUG
71#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
72#define TWDEBUG(x) printk(KERN_INFO x "\n");
73#else
74#define DPRINTK(fmt, args...)
75#define TWDEBUG(x)
76#endif
77
78#define SISFAIL(x) do { printk(x "\n"); return -EINVAL; } while(0)
79
80/* To be included in pci_ids.h */
81#ifndef PCI_DEVICE_ID_SI_650_VGA
82#define PCI_DEVICE_ID_SI_650_VGA 0x6325
83#endif
84#ifndef PCI_DEVICE_ID_SI_650
85#define PCI_DEVICE_ID_SI_650 0x0650
86#endif
87#ifndef PCI_DEVICE_ID_SI_651
88#define PCI_DEVICE_ID_SI_651 0x0651
89#endif
90#ifndef PCI_DEVICE_ID_SI_740
91#define PCI_DEVICE_ID_SI_740 0x0740
92#endif
93#ifndef PCI_DEVICE_ID_SI_330
94#define PCI_DEVICE_ID_SI_330 0x0330
95#endif
96#ifndef PCI_DEVICE_ID_SI_660_VGA
97#define PCI_DEVICE_ID_SI_660_VGA 0x6330
98#endif
99#ifndef PCI_DEVICE_ID_SI_661
100#define PCI_DEVICE_ID_SI_661 0x0661
101#endif
102#ifndef PCI_DEVICE_ID_SI_741
103#define PCI_DEVICE_ID_SI_741 0x0741
104#endif
105#ifndef PCI_DEVICE_ID_SI_660
106#define PCI_DEVICE_ID_SI_660 0x0660
107#endif
108#ifndef PCI_DEVICE_ID_SI_760
109#define PCI_DEVICE_ID_SI_760 0x0760
110#endif
111
112/* To be included in fb.h */
113#ifndef FB_ACCEL_SIS_GLAMOUR_2
114#define FB_ACCEL_SIS_GLAMOUR_2 40 /* SiS 315, 65x, 740, 661, 741 */
115#endif
116#ifndef FB_ACCEL_SIS_XABRE
117#define FB_ACCEL_SIS_XABRE 41 /* SiS 330 ("Xabre"), 760 */
118#endif
119
120#define MAX_ROM_SCAN 0x10000
121
122/* ivideo->caps */
123#define HW_CURSOR_CAP 0x80
124#define TURBO_QUEUE_CAP 0x40
125#define AGP_CMD_QUEUE_CAP 0x20
126#define VM_CMD_QUEUE_CAP 0x10
127#define MMIO_CMD_QUEUE_CAP 0x08
128
129/* For 300 series */
130#define TURBO_QUEUE_AREA_SIZE 0x80000 /* 512K */
131#define HW_CURSOR_AREA_SIZE_300 0x1000 /* 4K */
132
133/* For 315/Xabre series */
134#define COMMAND_QUEUE_AREA_SIZE 0x80000 /* 512K */
135#define COMMAND_QUEUE_THRESHOLD 0x1F
136#define HW_CURSOR_AREA_SIZE_315 0x4000 /* 16K */
137
138#define SIS_OH_ALLOC_SIZE 4000
139#define SENTINEL 0x7fffffff
140
141#define SEQ_ADR 0x14
142#define SEQ_DATA 0x15
143#define DAC_ADR 0x18
144#define DAC_DATA 0x19
145#define CRTC_ADR 0x24
146#define CRTC_DATA 0x25
147#define DAC2_ADR (0x16-0x30)
148#define DAC2_DATA (0x17-0x30)
149#define VB_PART1_ADR (0x04-0x30)
150#define VB_PART1_DATA (0x05-0x30)
151#define VB_PART2_ADR (0x10-0x30)
152#define VB_PART2_DATA (0x11-0x30)
153#define VB_PART3_ADR (0x12-0x30)
154#define VB_PART3_DATA (0x13-0x30)
155#define VB_PART4_ADR (0x14-0x30)
156#define VB_PART4_DATA (0x15-0x30)
157
158#define SISSR ivideo->SiS_Pr.SiS_P3c4
159#define SISCR ivideo->SiS_Pr.SiS_P3d4
160#define SISDACA ivideo->SiS_Pr.SiS_P3c8
161#define SISDACD ivideo->SiS_Pr.SiS_P3c9
162#define SISPART1 ivideo->SiS_Pr.SiS_Part1Port
163#define SISPART2 ivideo->SiS_Pr.SiS_Part2Port
164#define SISPART3 ivideo->SiS_Pr.SiS_Part3Port
165#define SISPART4 ivideo->SiS_Pr.SiS_Part4Port
166#define SISPART5 ivideo->SiS_Pr.SiS_Part5Port
167#define SISDAC2A SISPART5
168#define SISDAC2D (SISPART5 + 1)
169#define SISMISCR (ivideo->SiS_Pr.RelIO + 0x1c)
170#define SISMISCW ivideo->SiS_Pr.SiS_P3c2
171#define SISINPSTAT (ivideo->SiS_Pr.RelIO + 0x2a)
172#define SISPEL ivideo->SiS_Pr.SiS_P3c6
173
174#define IND_SIS_PASSWORD 0x05 /* SRs */
175#define IND_SIS_COLOR_MODE 0x06
176#define IND_SIS_RAMDAC_CONTROL 0x07
177#define IND_SIS_DRAM_SIZE 0x14
178#define IND_SIS_MODULE_ENABLE 0x1E
179#define IND_SIS_PCI_ADDRESS_SET 0x20
180#define IND_SIS_TURBOQUEUE_ADR 0x26
181#define IND_SIS_TURBOQUEUE_SET 0x27
182#define IND_SIS_POWER_ON_TRAP 0x38
183#define IND_SIS_POWER_ON_TRAP2 0x39
184#define IND_SIS_CMDQUEUE_SET 0x26
185#define IND_SIS_CMDQUEUE_THRESHOLD 0x27
186
187#define IND_SIS_AGP_IO_PAD 0x48
188
189#define SIS_CRT2_WENABLE_300 0x24 /* Part1 */
190#define SIS_CRT2_WENABLE_315 0x2F
191
192#define SIS_PASSWORD 0x86 /* SR05 */
193
194#define SIS_INTERLACED_MODE 0x20 /* SR06 */
195#define SIS_8BPP_COLOR_MODE 0x0
196#define SIS_15BPP_COLOR_MODE 0x1
197#define SIS_16BPP_COLOR_MODE 0x2
198#define SIS_32BPP_COLOR_MODE 0x4
199
200#define SIS_ENABLE_2D 0x40 /* SR1E */
201
202#define SIS_MEM_MAP_IO_ENABLE 0x01 /* SR20 */
203#define SIS_PCI_ADDR_ENABLE 0x80
204
205#define SIS_AGP_CMDQUEUE_ENABLE 0x80 /* 315/330 series SR26 */
206#define SIS_VRAM_CMDQUEUE_ENABLE 0x40
207#define SIS_MMIO_CMD_ENABLE 0x20
208#define SIS_CMD_QUEUE_SIZE_512k 0x00
209#define SIS_CMD_QUEUE_SIZE_1M 0x04
210#define SIS_CMD_QUEUE_SIZE_2M 0x08
211#define SIS_CMD_QUEUE_SIZE_4M 0x0C
212#define SIS_CMD_QUEUE_RESET 0x01
213#define SIS_CMD_AUTO_CORR 0x02
214
215#define SIS_SIMULTANEOUS_VIEW_ENABLE 0x01 /* CR30 */
216#define SIS_MODE_SELECT_CRT2 0x02
217#define SIS_VB_OUTPUT_COMPOSITE 0x04
218#define SIS_VB_OUTPUT_SVIDEO 0x08
219#define SIS_VB_OUTPUT_SCART 0x10
220#define SIS_VB_OUTPUT_LCD 0x20
221#define SIS_VB_OUTPUT_CRT2 0x40
222#define SIS_VB_OUTPUT_HIVISION 0x80
223
224#define SIS_VB_OUTPUT_DISABLE 0x20 /* CR31 */
225#define SIS_DRIVER_MODE 0x40
226
227#define SIS_VB_COMPOSITE 0x01 /* CR32 */
228#define SIS_VB_SVIDEO 0x02
229#define SIS_VB_SCART 0x04
230#define SIS_VB_LCD 0x08
231#define SIS_VB_CRT2 0x10
232#define SIS_CRT1 0x20
233#define SIS_VB_HIVISION 0x40
234#define SIS_VB_YPBPR 0x80
235#define SIS_VB_TV (SIS_VB_COMPOSITE | SIS_VB_SVIDEO | \
236 SIS_VB_SCART | SIS_VB_HIVISION | SIS_VB_YPBPR)
237
238#define SIS_EXTERNAL_CHIP_MASK 0x0E /* CR37 (< SiS 660) */
239#define SIS_EXTERNAL_CHIP_SIS301 0x01 /* in CR37 << 1 ! */
240#define SIS_EXTERNAL_CHIP_LVDS 0x02
241#define SIS_EXTERNAL_CHIP_TRUMPION 0x03
242#define SIS_EXTERNAL_CHIP_LVDS_CHRONTEL 0x04
243#define SIS_EXTERNAL_CHIP_CHRONTEL 0x05
244#define SIS310_EXTERNAL_CHIP_LVDS 0x02
245#define SIS310_EXTERNAL_CHIP_LVDS_CHRONTEL 0x03
246
247#define SIS_AGP_2X 0x20 /* CR48 */
248
249#define HW_DEVICE_EXTENSION SIS_HW_INFO
250#define PHW_DEVICE_EXTENSION PSIS_HW_INFO
251
252/* I/O port access macros */
253#define inSISREG(base) inb(base)
254
255#define outSISREG(base,val) outb(val,base)
256
257#define orSISREG(base,val) \
258 do { \
259 u8 __Temp = inSISREG(base); \
260 outSISREG(base, __Temp | (val)); \
261 } while (0)
262
263#define andSISREG(base,val) \
264 do { \
265 u8 __Temp = inSISREG(base); \
266 outSISREG(base, __Temp & (val)); \
267 } while (0)
268
269#define inSISIDXREG(base,idx,var) \
270 do { \
271 outSISREG(base, idx); \
272 var = inSISREG((base)+1); \
273 } while (0)
274
275#define outSISIDXREG(base,idx,val) \
276 do { \
277 outSISREG(base, idx); \
278 outSISREG((base)+1, val); \
279 } while (0)
280
281#define orSISIDXREG(base,idx,val) \
282 do { \
283 u8 __Temp; \
284 outSISREG(base, idx); \
285 __Temp = inSISREG((base)+1) | (val); \
286 outSISREG((base)+1, __Temp); \
287 } while (0)
288
289#define andSISIDXREG(base,idx,and) \
290 do { \
291 u8 __Temp; \
292 outSISREG(base, idx); \
293 __Temp = inSISREG((base)+1) & (and); \
294 outSISREG((base)+1, __Temp); \
295 } while (0)
296
297#define setSISIDXREG(base,idx,and,or) \
298 do { \
299 u8 __Temp; \
300 outSISREG(base, idx); \
301 __Temp = (inSISREG((base)+1) & (and)) | (or); \
302 outSISREG((base)+1, __Temp); \
303 } while (0)
304
305/* MMIO access macros */
306#define MMIO_IN8(base, offset) readb((base+offset))
307#define MMIO_IN16(base, offset) readw((base+offset))
308#define MMIO_IN32(base, offset) readl((base+offset))
309
310#define MMIO_OUT8(base, offset, val) writeb(((u8)(val)), (base+offset))
311#define MMIO_OUT16(base, offset, val) writew(((u16)(val)), (base+offset))
312#define MMIO_OUT32(base, offset, val) writel(((u32)(val)), (base+offset))
313
314/* Queue control MMIO registers */
315#define Q_BASE_ADDR 0x85C0 /* Base address of software queue */
316#define Q_WRITE_PTR 0x85C4 /* Current write pointer */
317#define Q_READ_PTR 0x85C8 /* Current read pointer */
318#define Q_STATUS 0x85CC /* queue status */
319
320#define MMIO_QUEUE_PHYBASE Q_BASE_ADDR
321#define MMIO_QUEUE_WRITEPORT Q_WRITE_PTR
322#define MMIO_QUEUE_READPORT Q_READ_PTR
323
324#ifndef FB_BLANK_UNBLANK
325#define FB_BLANK_UNBLANK 0
326#endif
327#ifndef FB_BLANK_NORMAL
328#define FB_BLANK_NORMAL 1
329#endif
330#ifndef FB_BLANK_VSYNC_SUSPEND
331#define FB_BLANK_VSYNC_SUSPEND 2
332#endif
333#ifndef FB_BLANK_HSYNC_SUSPEND
334#define FB_BLANK_HSYNC_SUSPEND 3
335#endif
336#ifndef FB_BLANK_POWERDOWN
337#define FB_BLANK_POWERDOWN 4
338#endif
339
340enum _SIS_LCD_TYPE {
341 LCD_INVALID = 0,
342 LCD_800x600,
343 LCD_1024x768,
344 LCD_1280x1024,
345 LCD_1280x960,
346 LCD_640x480,
347 LCD_1600x1200,
348 LCD_1920x1440,
349 LCD_2048x1536,
350 LCD_320x480, /* FSTN */
351 LCD_1400x1050,
352 LCD_1152x864,
353 LCD_1152x768,
354 LCD_1280x768,
355 LCD_1024x600,
356 LCD_640x480_2, /* DSTN */
357 LCD_640x480_3, /* DSTN */
358 LCD_848x480,
359 LCD_1280x800,
360 LCD_1680x1050,
361 LCD_1280x720,
362 LCD_CUSTOM,
363 LCD_UNKNOWN
364};
365
366enum _SIS_CMDTYPE {
367 MMIO_CMD = 0,
368 AGP_CMD_QUEUE,
369 VM_CMD_QUEUE,
370};
371typedef unsigned int SIS_CMDTYPE;
372
373/* Our "par" */
374struct sis_video_info {
375 int cardnumber;
376 struct fb_info *memyselfandi;
377
378 SIS_HW_INFO sishw_ext;
379 SiS_Private SiS_Pr;
380
381 sisfb_info sisfbinfo; /* For ioctl SISFB_GET_INFO */
382
383 struct fb_var_screeninfo default_var;
384
385#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
386 struct fb_fix_screeninfo sisfb_fix;
387 u32 pseudo_palette[17];
388#endif
389
390#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
391 struct display sis_disp;
392 struct display_switch sisfb_sw;
393 struct {
394 u16 red, green, blue, pad;
395 } sis_palette[256];
396 union {
397#ifdef FBCON_HAS_CFB16
398 u16 cfb16[16];
399#endif
400#ifdef FBCON_HAS_CFB32
401 u32 cfb32[16];
402#endif
403 } sis_fbcon_cmap;
404#endif
405
406 struct sisfb_monitor {
407 u16 hmin;
408 u16 hmax;
409 u16 vmin;
410 u16 vmax;
411 u32 dclockmax;
412 u8 feature;
413 BOOLEAN datavalid;
414 } sisfb_thismonitor;
415
416 int chip_id;
417 char myid[40];
418
419 struct pci_dev *nbridge;
420
421 int mni; /* Mode number index */
422
423#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
424 int currcon;
425#endif
426
427 unsigned long video_size;
428 unsigned long video_base;
429 unsigned long mmio_size;
430 unsigned long mmio_base;
431 unsigned long vga_base;
432
433 SIS_IOTYPE1 *video_vbase;
434 SIS_IOTYPE1 *mmio_vbase;
435
436 unsigned char *bios_abase;
437
438 int mtrr;
439
440 u32 sisfb_mem;
441
442 u32 sisfb_parm_mem;
443 int sisfb_accel;
444 int sisfb_ypan;
445 int sisfb_max;
446 int sisfb_userom;
447 int sisfb_useoem;
448 int sisfb_mode_idx;
449 int sisfb_parm_rate;
450 int sisfb_crt1off;
451 int sisfb_forcecrt1;
452 int sisfb_crt2type;
453 int sisfb_crt2flags;
454 int sisfb_dstn;
455 int sisfb_fstn;
456 int sisfb_tvplug;
457 int sisfb_tvstd;
458 int sisfb_filter;
459 int sisfb_nocrt2rate;
460#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
461 int sisfb_inverse;
462#endif
463
464 u32 heapstart; /* offset */
465 SIS_IOTYPE1 *sisfb_heap_start; /* address */
466 SIS_IOTYPE1 *sisfb_heap_end; /* address */
467 u32 sisfb_heap_size;
468 int havenoheap;
469#if 0
470 SIS_HEAP sisfb_heap;
471#endif
472
473
474 int video_bpp;
475 int video_cmap_len;
476 int video_width;
477 int video_height;
478 unsigned int refresh_rate;
479
480 unsigned int chip;
481 u8 revision_id;
482
483 int video_linelength; /* real pitch */
484 int scrnpitchCRT1; /* pitch regarding interlace */
485
486 u16 DstColor; /* For 2d acceleration */
487 u32 SiS310_AccelDepth;
488 u32 CommandReg;
489 int cmdqueuelength;
490
491 spinlock_t lockaccel; /* Do not use outside of kernel! */
492
493 unsigned int pcibus;
494 unsigned int pcislot;
495 unsigned int pcifunc;
496
497 int accel;
498
499 u16 subsysvendor;
500 u16 subsysdevice;
501
502 u32 vbflags; /* Replacing deprecated stuff from above */
503 u32 currentvbflags;
504
505 int lcdxres, lcdyres;
506 int lcddefmodeidx, tvdefmodeidx, defmodeidx;
507 u32 CRT2LCDType; /* defined in "SIS_LCD_TYPE" */
508
509 int current_bpp;
510 int current_width;
511 int current_height;
512 int current_htotal;
513 int current_vtotal;
514 int current_linelength;
515 __u32 current_pixclock;
516 int current_refresh_rate;
517
518 u8 mode_no;
519 u8 rate_idx;
520 int modechanged;
521 unsigned char modeprechange;
522
523#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
524 u8 sisfb_lastrates[128];
525#endif
526
527 int newrom;
528 int registered;
529 int warncount;
530
531 int sisvga_engine;
532 int hwcursor_size;
533 int CRT2_write_enable;
534 u8 caps;
535
536 u8 detectedpdc;
537 u8 detectedpdca;
538 u8 detectedlcda;
539
540 SIS_IOTYPE1 *hwcursor_vbase;
541
542 int chronteltype;
543 int tvxpos, tvypos;
544 u8 p2_1f,p2_20,p2_2b,p2_42,p2_43,p2_01,p2_02;
545 int tvx, tvy;
546
547 u8 sisfblocked;
548
549 struct sis_video_info *next;
550};
551
552typedef struct _SIS_OH {
553 struct _SIS_OH *poh_next;
554 struct _SIS_OH *poh_prev;
555 u32 offset;
556 u32 size;
557} SIS_OH;
558
559typedef struct _SIS_OHALLOC {
560 struct _SIS_OHALLOC *poha_next;
561 SIS_OH aoh[1];
562} SIS_OHALLOC;
563
564typedef struct _SIS_HEAP {
565 SIS_OH oh_free;
566 SIS_OH oh_used;
567 SIS_OH *poh_freelist;
568 SIS_OHALLOC *poha_chain;
569 u32 max_freesize;
570 struct sis_video_info *vinfo;
571} SIS_HEAP;
572
573#endif
diff --git a/drivers/video/sis/sis_accel.c b/drivers/video/sis/sis_accel.c
new file mode 100644
index 000000000000..30e90a553e80
--- /dev/null
+++ b/drivers/video/sis/sis_accel.c
@@ -0,0 +1,678 @@
1/*
2 * SiS 300/630/730/540/315/550/65x/74x/330/760 frame buffer driver
3 * for Linux kernels 2.4.x and 2.6.x
4 *
5 * 2D acceleration part
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the named License,
10 * or any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
20 *
21 * Based on the XFree86/X.org driver which is
22 * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
23 *
24 * Author: Thomas Winischhofer <thomas@winischhofer.net>
25 * (see http://www.winischhofer.net/
26 * for more information and updates)
27 */
28
29#include <linux/config.h>
30#include <linux/version.h>
31#include <linux/module.h>
32#include <linux/kernel.h>
33#include <linux/errno.h>
34#include <linux/fb.h>
35#include <linux/console.h>
36#include <linux/selection.h>
37#include <linux/ioport.h>
38#include <linux/capability.h>
39#include <linux/fs.h>
40#include <linux/types.h>
41
42#include <asm/io.h>
43
44#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
45#include <video/fbcon.h>
46#include <video/fbcon-cfb8.h>
47#include <video/fbcon-cfb16.h>
48#include <video/fbcon-cfb24.h>
49#include <video/fbcon-cfb32.h>
50#endif
51
52#include "sis.h"
53#include "sis_accel.h"
54
55static const u8 sisALUConv[] =
56{
57 0x00, /* dest = 0; 0, GXclear, 0 */
58 0x88, /* dest &= src; DSa, GXand, 0x1 */
59 0x44, /* dest = src & ~dest; SDna, GXandReverse, 0x2 */
60 0xCC, /* dest = src; S, GXcopy, 0x3 */
61 0x22, /* dest &= ~src; DSna, GXandInverted, 0x4 */
62 0xAA, /* dest = dest; D, GXnoop, 0x5 */
63 0x66, /* dest = ^src; DSx, GXxor, 0x6 */
64 0xEE, /* dest |= src; DSo, GXor, 0x7 */
65 0x11, /* dest = ~src & ~dest; DSon, GXnor, 0x8 */
66 0x99, /* dest ^= ~src ; DSxn, GXequiv, 0x9 */
67 0x55, /* dest = ~dest; Dn, GXInvert, 0xA */
68 0xDD, /* dest = src|~dest ; SDno, GXorReverse, 0xB */
69 0x33, /* dest = ~src; Sn, GXcopyInverted, 0xC */
70 0xBB, /* dest |= ~src; DSno, GXorInverted, 0xD */
71 0x77, /* dest = ~src|~dest; DSan, GXnand, 0xE */
72 0xFF, /* dest = 0xFF; 1, GXset, 0xF */
73};
74/* same ROP but with Pattern as Source */
75static const u8 sisPatALUConv[] =
76{
77 0x00, /* dest = 0; 0, GXclear, 0 */
78 0xA0, /* dest &= src; DPa, GXand, 0x1 */
79 0x50, /* dest = src & ~dest; PDna, GXandReverse, 0x2 */
80 0xF0, /* dest = src; P, GXcopy, 0x3 */
81 0x0A, /* dest &= ~src; DPna, GXandInverted, 0x4 */
82 0xAA, /* dest = dest; D, GXnoop, 0x5 */
83 0x5A, /* dest = ^src; DPx, GXxor, 0x6 */
84 0xFA, /* dest |= src; DPo, GXor, 0x7 */
85 0x05, /* dest = ~src & ~dest; DPon, GXnor, 0x8 */
86 0xA5, /* dest ^= ~src ; DPxn, GXequiv, 0x9 */
87 0x55, /* dest = ~dest; Dn, GXInvert, 0xA */
88 0xF5, /* dest = src|~dest ; PDno, GXorReverse, 0xB */
89 0x0F, /* dest = ~src; Pn, GXcopyInverted, 0xC */
90 0xAF, /* dest |= ~src; DPno, GXorInverted, 0xD */
91 0x5F, /* dest = ~src|~dest; DPan, GXnand, 0xE */
92 0xFF, /* dest = 0xFF; 1, GXset, 0xF */
93};
94
95#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,34)
96static const int myrops[] = {
97 3, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3
98};
99#endif
100
101/* 300 series ----------------------------------------------------- */
102#ifdef CONFIG_FB_SIS_300
103static void
104SiS300Sync(struct sis_video_info *ivideo)
105{
106 SiS300Idle
107}
108
109static void
110SiS300SetupForScreenToScreenCopy(struct sis_video_info *ivideo, int xdir, int ydir,
111 int rop, int trans_color)
112{
113 SiS300SetupDSTColorDepth(ivideo->DstColor);
114 SiS300SetupSRCPitch(ivideo->video_linelength)
115 SiS300SetupDSTRect(ivideo->video_linelength, 0xffff)
116
117 if(trans_color != -1) {
118 SiS300SetupROP(0x0A)
119 SiS300SetupSRCTrans(trans_color)
120 SiS300SetupCMDFlag(TRANSPARENT_BITBLT)
121 } else {
122 SiS300SetupROP(sisALUConv[rop])
123 }
124 if(xdir > 0) {
125 SiS300SetupCMDFlag(X_INC)
126 }
127 if(ydir > 0) {
128 SiS300SetupCMDFlag(Y_INC)
129 }
130}
131
132static void
133SiS300SubsequentScreenToScreenCopy(struct sis_video_info *ivideo, int src_x,
134 int src_y, int dst_x, int dst_y, int width, int height)
135{
136 u32 srcbase = 0, dstbase = 0;
137
138 if(src_y >= 2048) {
139 srcbase = ivideo->video_linelength * src_y;
140 src_y = 0;
141 }
142 if(dst_y >= 2048) {
143 dstbase = ivideo->video_linelength * dst_y;
144 dst_y = 0;
145 }
146
147 SiS300SetupSRCBase(srcbase);
148 SiS300SetupDSTBase(dstbase);
149
150 if(!(ivideo->CommandReg & X_INC)) {
151 src_x += width-1;
152 dst_x += width-1;
153 }
154 if(!(ivideo->CommandReg & Y_INC)) {
155 src_y += height-1;
156 dst_y += height-1;
157 }
158 SiS300SetupRect(width, height)
159 SiS300SetupSRCXY(src_x, src_y)
160 SiS300SetupDSTXY(dst_x, dst_y)
161 SiS300DoCMD
162}
163
164static void
165SiS300SetupForSolidFill(struct sis_video_info *ivideo, u32 color, int rop)
166{
167 SiS300SetupPATFG(color)
168 SiS300SetupDSTRect(ivideo->video_linelength, 0xffff)
169 SiS300SetupDSTColorDepth(ivideo->DstColor);
170 SiS300SetupROP(sisPatALUConv[rop])
171 SiS300SetupCMDFlag(PATFG)
172}
173
174static void
175SiS300SubsequentSolidFillRect(struct sis_video_info *ivideo, int x, int y, int w, int h)
176{
177 u32 dstbase = 0;
178
179 if(y >= 2048) {
180 dstbase = ivideo->video_linelength * y;
181 y = 0;
182 }
183 SiS300SetupDSTBase(dstbase)
184 SiS300SetupDSTXY(x,y)
185 SiS300SetupRect(w,h)
186 SiS300SetupCMDFlag(X_INC | Y_INC | BITBLT)
187 SiS300DoCMD
188}
189#endif
190
191/* 315/330 series ------------------------------------------------- */
192
193#ifdef CONFIG_FB_SIS_315
194static void
195SiS310Sync(struct sis_video_info *ivideo)
196{
197 SiS310Idle
198}
199
200static void
201SiS310SetupForScreenToScreenCopy(struct sis_video_info *ivideo, int rop, int trans_color)
202{
203 SiS310SetupDSTColorDepth(ivideo->DstColor);
204 SiS310SetupSRCPitch(ivideo->video_linelength)
205 SiS310SetupDSTRect(ivideo->video_linelength, 0xffff)
206 if(trans_color != -1) {
207 SiS310SetupROP(0x0A)
208 SiS310SetupSRCTrans(trans_color)
209 SiS310SetupCMDFlag(TRANSPARENT_BITBLT)
210 } else {
211 SiS310SetupROP(sisALUConv[rop])
212 /* Set command - not needed, both 0 */
213 /* SiSSetupCMDFlag(BITBLT | SRCVIDEO) */
214 }
215 SiS310SetupCMDFlag(ivideo->SiS310_AccelDepth)
216 /* The 315 series is smart enough to know the direction */
217}
218
219static void
220SiS310SubsequentScreenToScreenCopy(struct sis_video_info *ivideo, int src_x, int src_y,
221 int dst_x, int dst_y, int width, int height)
222{
223 u32 srcbase = 0, dstbase = 0;
224 int mymin = min(src_y, dst_y);
225 int mymax = max(src_y, dst_y);
226
227 /* Although the chip knows the direction to use
228 * if the source and destination areas overlap,
229 * that logic fails if we fiddle with the bitmap
230 * addresses. Therefore, we check if the source
231 * and destination blitting areas overlap and
232 * adapt the bitmap addresses synchronously
233 * if the coordinates exceed the valid range.
234 * The the areas do not overlap, we do our
235 * normal check.
236 */
237 if((mymax - mymin) < height) {
238 if((src_y >= 2048) || (dst_y >= 2048)) {
239 srcbase = ivideo->video_linelength * mymin;
240 dstbase = ivideo->video_linelength * mymin;
241 src_y -= mymin;
242 dst_y -= mymin;
243 }
244 } else {
245 if(src_y >= 2048) {
246 srcbase = ivideo->video_linelength * src_y;
247 src_y = 0;
248 }
249 if(dst_y >= 2048) {
250 dstbase = ivideo->video_linelength * dst_y;
251 dst_y = 0;
252 }
253 }
254
255 SiS310SetupSRCBase(srcbase);
256 SiS310SetupDSTBase(dstbase);
257 SiS310SetupRect(width, height)
258 SiS310SetupSRCXY(src_x, src_y)
259 SiS310SetupDSTXY(dst_x, dst_y)
260 SiS310DoCMD
261}
262
263static void
264SiS310SetupForSolidFill(struct sis_video_info *ivideo, u32 color, int rop)
265{
266 SiS310SetupPATFG(color)
267 SiS310SetupDSTRect(ivideo->video_linelength, 0xffff)
268 SiS310SetupDSTColorDepth(ivideo->DstColor);
269 SiS310SetupROP(sisPatALUConv[rop])
270 SiS310SetupCMDFlag(PATFG | ivideo->SiS310_AccelDepth)
271}
272
273static void
274SiS310SubsequentSolidFillRect(struct sis_video_info *ivideo, int x, int y, int w, int h)
275{
276 u32 dstbase = 0;
277
278 if(y >= 2048) {
279 dstbase = ivideo->video_linelength * y;
280 y = 0;
281 }
282 SiS310SetupDSTBase(dstbase)
283 SiS310SetupDSTXY(x,y)
284 SiS310SetupRect(w,h)
285 SiS310SetupCMDFlag(BITBLT)
286 SiS310DoCMD
287}
288#endif
289
290/* --------------------------------------------------------------------- */
291
292/* The exported routines */
293
294int sisfb_initaccel(struct sis_video_info *ivideo)
295{
296#ifdef SISFB_USE_SPINLOCKS
297 spin_lock_init(&ivideo->lockaccel);
298#endif
299 return(0);
300}
301
302void sisfb_syncaccel(struct sis_video_info *ivideo)
303{
304 if(ivideo->sisvga_engine == SIS_300_VGA) {
305#ifdef CONFIG_FB_SIS_300
306 SiS300Sync(ivideo);
307#endif
308 } else {
309#ifdef CONFIG_FB_SIS_315
310 SiS310Sync(ivideo);
311#endif
312 }
313}
314
315#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) /* --------------- 2.5 --------------- */
316
317int fbcon_sis_sync(struct fb_info *info)
318{
319 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
320 CRITFLAGS
321
322 if(!ivideo->accel)
323 return 0;
324
325 if(ivideo->sisvga_engine == SIS_300_VGA) {
326#ifdef CONFIG_FB_SIS_300
327 SiS300Sync(ivideo);
328#endif
329 } else {
330#ifdef CONFIG_FB_SIS_315
331 SiS310Sync(ivideo);
332#endif
333 }
334 CRITEND
335 return 0;
336}
337
338void fbcon_sis_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
339{
340 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
341 u32 col = 0;
342 u32 vxres = info->var.xres_virtual;
343 u32 vyres = info->var.yres_virtual;
344 int width, height;
345 CRITFLAGS
346
347 if(info->state != FBINFO_STATE_RUNNING) {
348 return;
349 }
350
351 if(!ivideo->accel) {
352 cfb_fillrect(info, rect);
353 return;
354 }
355
356 if(!rect->width || !rect->height || rect->dx >= vxres || rect->dy >= vyres) {
357 return;
358 }
359
360 /* Clipping */
361 width = ((rect->dx + rect->width) > vxres) ? (vxres - rect->dx) : rect->width;
362 height = ((rect->dy + rect->height) > vyres) ? (vyres - rect->dy) : rect->height;
363
364 switch(info->var.bits_per_pixel) {
365 case 8: col = rect->color;
366 break;
367 case 16:
368 case 32: col = ((u32 *)(info->pseudo_palette))[rect->color];
369 break;
370 }
371
372 if(ivideo->sisvga_engine == SIS_300_VGA) {
373#ifdef CONFIG_FB_SIS_300
374 CRITBEGIN
375 SiS300SetupForSolidFill(ivideo, col, myrops[rect->rop]);
376 SiS300SubsequentSolidFillRect(ivideo, rect->dx, rect->dy, width, height);
377 CRITEND
378 SiS300Sync(ivideo);
379#endif
380 } else {
381#ifdef CONFIG_FB_SIS_315
382 CRITBEGIN
383 SiS310SetupForSolidFill(ivideo, col, myrops[rect->rop]);
384 SiS310SubsequentSolidFillRect(ivideo, rect->dx, rect->dy, width, height);
385 CRITEND
386 SiS310Sync(ivideo);
387#endif
388 }
389
390}
391
392void fbcon_sis_copyarea(struct fb_info *info, const struct fb_copyarea *area)
393{
394 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
395 u32 vxres = info->var.xres_virtual;
396 u32 vyres = info->var.yres_virtual;
397 int width = area->width;
398 int height = area->height;
399 CRITFLAGS
400
401 if(info->state != FBINFO_STATE_RUNNING) {
402 return;
403 }
404
405 if(!ivideo->accel) {
406 cfb_copyarea(info, area);
407 return;
408 }
409
410 if(!width || !height ||
411 area->sx >= vxres || area->sy >= vyres ||
412 area->dx >= vxres || area->dy >= vyres) {
413 return;
414 }
415
416 /* Clipping */
417 if((area->sx + width) > vxres) width = vxres - area->sx;
418 if((area->dx + width) > vxres) width = vxres - area->dx;
419 if((area->sy + height) > vyres) height = vyres - area->sy;
420 if((area->dy + height) > vyres) height = vyres - area->dy;
421
422 if(ivideo->sisvga_engine == SIS_300_VGA) {
423#ifdef CONFIG_FB_SIS_300
424 int xdir, ydir;
425
426 if(area->sx < area->dx) xdir = 0;
427 else xdir = 1;
428 if(area->sy < area->dy) ydir = 0;
429 else ydir = 1;
430
431 CRITBEGIN
432 SiS300SetupForScreenToScreenCopy(ivideo, xdir, ydir, 3, -1);
433 SiS300SubsequentScreenToScreenCopy(ivideo, area->sx, area->sy, area->dx, area->dy,
434 width, height);
435 CRITEND
436 SiS300Sync(ivideo);
437#endif
438 } else {
439#ifdef CONFIG_FB_SIS_315
440 CRITBEGIN
441 SiS310SetupForScreenToScreenCopy(ivideo, 3, -1);
442 SiS310SubsequentScreenToScreenCopy(ivideo, area->sx, area->sy, area->dx, area->dy,
443 width, height);
444 CRITEND
445 SiS310Sync(ivideo);
446#endif
447 }
448}
449
450#endif
451
452#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* -------------- 2.4 --------------- */
453
454void fbcon_sis_bmove(struct display *p, int srcy, int srcx,
455 int dsty, int dstx, int height, int width)
456{
457 struct sis_video_info *ivideo = (struct sis_video_info *)p->fb_info->par;
458
459 CRITFLAGS
460
461 if(!ivideo->accel) {
462 switch(ivideo->video_bpp) {
463 case 8:
464#ifdef FBCON_HAS_CFB8
465 fbcon_cfb8_bmove(p, srcy, srcx, dsty, dstx, height, width);
466#endif
467 break;
468 case 16:
469#ifdef FBCON_HAS_CFB16
470 fbcon_cfb16_bmove(p, srcy, srcx, dsty, dstx, height, width);
471#endif
472 break;
473 case 32:
474#ifdef FBCON_HAS_CFB32
475 fbcon_cfb32_bmove(p, srcy, srcx, dsty, dstx, height, width);
476#endif
477 break;
478 }
479 return;
480 }
481
482 srcx *= fontwidth(p);
483 srcy *= fontheight(p);
484 dstx *= fontwidth(p);
485 dsty *= fontheight(p);
486 width *= fontwidth(p);
487 height *= fontheight(p);
488
489 if(ivideo->sisvga_engine == SIS_300_VGA) {
490#ifdef CONFIG_FB_SIS_300
491 int xdir, ydir;
492
493 if(srcx < dstx) xdir = 0;
494 else xdir = 1;
495 if(srcy < dsty) ydir = 0;
496 else ydir = 1;
497
498 CRITBEGIN
499 SiS300SetupForScreenToScreenCopy(ivideo, xdir, ydir, 3, -1);
500 SiS300SubsequentScreenToScreenCopy(ivideo, srcx, srcy, dstx, dsty, width, height);
501 CRITEND
502 SiS300Sync(ivideo);
503#endif
504 } else {
505#ifdef CONFIG_FB_SIS_315
506 CRITBEGIN
507 SiS310SetupForScreenToScreenCopy(ivideo, 3, -1);
508 SiS310SubsequentScreenToScreenCopy(ivideo, srcx, srcy, dstx, dsty, width, height);
509 CRITEND
510 SiS310Sync(ivideo);
511#endif
512 }
513}
514
515static void fbcon_sis_clear(struct vc_data *conp, struct display *p,
516 int srcy, int srcx, int height, int width, int color)
517{
518 struct sis_video_info *ivideo = (struct sis_video_info *)p->fb_info->par;
519 CRITFLAGS
520
521 srcx *= fontwidth(p);
522 srcy *= fontheight(p);
523 width *= fontwidth(p);
524 height *= fontheight(p);
525
526 if(ivideo->sisvga_engine == SIS_300_VGA) {
527#ifdef CONFIG_FB_SIS_300
528 CRITBEGIN
529 SiS300SetupForSolidFill(ivideo, color, 3);
530 SiS300SubsequentSolidFillRect(ivideo, srcx, srcy, width, height);
531 CRITEND
532 SiS300Sync(ivideo);
533#endif
534 } else {
535#ifdef CONFIG_FB_SIS_315
536 CRITBEGIN
537 SiS310SetupForSolidFill(ivideo, color, 3);
538 SiS310SubsequentSolidFillRect(ivideo, srcx, srcy, width, height);
539 CRITEND
540 SiS310Sync(ivideo);
541#endif
542 }
543}
544
545void fbcon_sis_clear8(struct vc_data *conp, struct display *p,
546 int srcy, int srcx, int height, int width)
547{
548 struct sis_video_info *ivideo = (struct sis_video_info *)p->fb_info->par;
549 u32 bgx;
550
551 if(!ivideo->accel) {
552#ifdef FBCON_HAS_CFB8
553 fbcon_cfb8_clear(conp, p, srcy, srcx, height, width);
554#endif
555 return;
556 }
557
558 bgx = attr_bgcol_ec(p, conp);
559 fbcon_sis_clear(conp, p, srcy, srcx, height, width, bgx);
560}
561
562void fbcon_sis_clear16(struct vc_data *conp, struct display *p,
563 int srcy, int srcx, int height, int width)
564{
565 struct sis_video_info *ivideo = (struct sis_video_info *)p->fb_info->par;
566 u32 bgx;
567
568 if(!ivideo->accel) {
569#ifdef FBCON_HAS_CFB16
570 fbcon_cfb16_clear(conp, p, srcy, srcx, height, width);
571#endif
572 return;
573 }
574
575 bgx = ((u_int16_t*)p->dispsw_data)[attr_bgcol_ec(p, conp)];
576 fbcon_sis_clear(conp, p, srcy, srcx, height, width, bgx);
577}
578
579void fbcon_sis_clear32(struct vc_data *conp, struct display *p,
580 int srcy, int srcx, int height, int width)
581{
582 struct sis_video_info *ivideo = (struct sis_video_info *)p->fb_info->par;
583 u32 bgx;
584
585 if(!ivideo->accel) {
586#ifdef FBCON_HAS_CFB32
587 fbcon_cfb32_clear(conp, p, srcy, srcx, height, width);
588#endif
589 return;
590 }
591
592 bgx = ((u_int32_t*)p->dispsw_data)[attr_bgcol_ec(p, conp)];
593 fbcon_sis_clear(conp, p, srcy, srcx, height, width, bgx);
594}
595
596void fbcon_sis_revc(struct display *p, int srcx, int srcy)
597{
598 struct sis_video_info *ivideo = (struct sis_video_info *)p->fb_info->par;
599 CRITFLAGS
600
601 if(!ivideo->accel) {
602 switch(ivideo->video_bpp) {
603 case 16:
604#ifdef FBCON_HAS_CFB16
605 fbcon_cfb16_revc(p, srcx, srcy);
606#endif
607 break;
608 case 32:
609#ifdef FBCON_HAS_CFB32
610 fbcon_cfb32_revc(p, srcx, srcy);
611#endif
612 break;
613 }
614 return;
615 }
616
617 srcx *= fontwidth(p);
618 srcy *= fontheight(p);
619
620 if(ivideo->sisvga_engine == SIS_300_VGA) {
621#ifdef CONFIG_FB_SIS_300
622 CRITBEGIN
623 SiS300SetupForSolidFill(ivideo, 0, 0x0a);
624 SiS300SubsequentSolidFillRect(ivideo, srcx, srcy, fontwidth(p), fontheight(p));
625 CRITEND
626 SiS300Sync(ivideo);
627#endif
628 } else {
629#ifdef CONFIG_FB_SIS_315
630 CRITBEGIN
631 SiS310SetupForSolidFill(ivideo, 0, 0x0a);
632 SiS310SubsequentSolidFillRect(ivideo, srcx, srcy, fontwidth(p), fontheight(p));
633 CRITEND
634 SiS310Sync(ivideo);
635#endif
636 }
637}
638
639#ifdef FBCON_HAS_CFB8
640struct display_switch fbcon_sis8 = {
641 .setup = fbcon_cfb8_setup,
642 .bmove = fbcon_sis_bmove,
643 .clear = fbcon_sis_clear8,
644 .putc = fbcon_cfb8_putc,
645 .putcs = fbcon_cfb8_putcs,
646 .revc = fbcon_cfb8_revc,
647 .clear_margins = fbcon_cfb8_clear_margins,
648 .fontwidthmask = FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
649};
650#endif
651#ifdef FBCON_HAS_CFB16
652struct display_switch fbcon_sis16 = {
653 .setup = fbcon_cfb16_setup,
654 .bmove = fbcon_sis_bmove,
655 .clear = fbcon_sis_clear16,
656 .putc = fbcon_cfb16_putc,
657 .putcs = fbcon_cfb16_putcs,
658 .revc = fbcon_sis_revc,
659 .clear_margins = fbcon_cfb16_clear_margins,
660 .fontwidthmask = FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
661};
662#endif
663#ifdef FBCON_HAS_CFB32
664struct display_switch fbcon_sis32 = {
665 .setup = fbcon_cfb32_setup,
666 .bmove = fbcon_sis_bmove,
667 .clear = fbcon_sis_clear32,
668 .putc = fbcon_cfb32_putc,
669 .putcs = fbcon_cfb32_putcs,
670 .revc = fbcon_sis_revc,
671 .clear_margins = fbcon_cfb32_clear_margins,
672 .fontwidthmask = FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
673};
674#endif
675
676#endif /* KERNEL VERSION */
677
678
diff --git a/drivers/video/sis/sis_accel.h b/drivers/video/sis/sis_accel.h
new file mode 100644
index 000000000000..bb28f331d60d
--- /dev/null
+++ b/drivers/video/sis/sis_accel.h
@@ -0,0 +1,409 @@
1/*
2 * SiS 300/630/730/540/315/550/650/740 frame buffer driver
3 * for Linux kernels 2.4.x and 2.5.x
4 *
5 * 2D acceleration part
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the named License,
10 * or any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
20 *
21 * Based on the X driver's sis300_accel.h which is
22 * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
23 * and sis310_accel.h which is
24 * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
25 *
26 * Author: Thomas Winischhofer <thomas@winischhofer.net>:
27 * (see http://www.winischhofer.net/
28 * for more information and updates)
29 */
30
31#ifndef _SISFB_ACCEL_H
32#define _SISFB_ACCEL_H
33
34/* Guard accelerator accesses with spin_lock_irqsave? Works well without. */
35#undef SISFB_USE_SPINLOCKS
36
37#ifdef SISFB_USE_SPINLOCKS
38#include <linux/spinlock.h>
39#define CRITBEGIN spin_lock_irqsave(&ivideo->lockaccel, critflags);
40#define CRITEND spin_unlock_irqrestore(&ivideo->lockaccel, critflags);
41#define CRITFLAGS unsigned long critflags;
42#else
43#define CRITBEGIN
44#define CRITEND
45#define CRITFLAGS
46#endif
47
48/* Definitions for the SIS engine communication. */
49
50#define PATREGSIZE 384 /* Pattern register size. 384 bytes @ 0x8300 */
51#define BR(x) (0x8200 | (x) << 2)
52#define PBR(x) (0x8300 | (x) << 2)
53
54/* SiS300 engine commands */
55#define BITBLT 0x00000000 /* Blit */
56#define COLOREXP 0x00000001 /* Color expand */
57#define ENCOLOREXP 0x00000002 /* Enhanced color expand */
58#define MULTIPLE_SCANLINE 0x00000003 /* ? */
59#define LINE 0x00000004 /* Draw line */
60#define TRAPAZOID_FILL 0x00000005 /* Fill trapezoid */
61#define TRANSPARENT_BITBLT 0x00000006 /* Transparent Blit */
62
63/* Additional engine commands for 315 */
64#define ALPHA_BLEND 0x00000007 /* Alpha blend ? */
65#define A3D_FUNCTION 0x00000008 /* 3D command ? */
66#define CLEAR_Z_BUFFER 0x00000009 /* ? */
67#define GRADIENT_FILL 0x0000000A /* Gradient fill */
68
69/* source select */
70#define SRCVIDEO 0x00000000 /* source is video RAM */
71#define SRCSYSTEM 0x00000010 /* source is system memory */
72#define SRCCPUBLITBUF SRCSYSTEM /* source is CPU-driven BitBuffer (for color expand) */
73#define SRCAGP 0x00000020 /* source is AGP memory (?) */
74
75/* Pattern flags */
76#define PATFG 0x00000000 /* foreground color */
77#define PATPATREG 0x00000040 /* pattern in pattern buffer (0x8300) */
78#define PATMONO 0x00000080 /* mono pattern */
79
80/* blitting direction (300 series only) */
81#define X_INC 0x00010000
82#define X_DEC 0x00000000
83#define Y_INC 0x00020000
84#define Y_DEC 0x00000000
85
86/* Clipping flags */
87#define NOCLIP 0x00000000
88#define NOMERGECLIP 0x04000000
89#define CLIPENABLE 0x00040000
90#define CLIPWITHOUTMERGE 0x04040000
91
92/* Transparency */
93#define OPAQUE 0x00000000
94#define TRANSPARENT 0x00100000
95
96/* ? */
97#define DSTAGP 0x02000000
98#define DSTVIDEO 0x02000000
99
100/* Subfunctions for Color/Enhanced Color Expansion (315 only) */
101#define COLOR_TO_MONO 0x00100000
102#define AA_TEXT 0x00200000
103
104/* Some general registers for 315 series */
105#define SRC_ADDR 0x8200
106#define SRC_PITCH 0x8204
107#define AGP_BASE 0x8206 /* color-depth dependent value */
108#define SRC_Y 0x8208
109#define SRC_X 0x820A
110#define DST_Y 0x820C
111#define DST_X 0x820E
112#define DST_ADDR 0x8210
113#define DST_PITCH 0x8214
114#define DST_HEIGHT 0x8216
115#define RECT_WIDTH 0x8218
116#define RECT_HEIGHT 0x821A
117#define PAT_FGCOLOR 0x821C
118#define PAT_BGCOLOR 0x8220
119#define SRC_FGCOLOR 0x8224
120#define SRC_BGCOLOR 0x8228
121#define MONO_MASK 0x822C
122#define LEFT_CLIP 0x8234
123#define TOP_CLIP 0x8236
124#define RIGHT_CLIP 0x8238
125#define BOTTOM_CLIP 0x823A
126#define COMMAND_READY 0x823C
127#define FIRE_TRIGGER 0x8240
128
129#define PATTERN_REG 0x8300 /* 384 bytes pattern buffer */
130
131/* Transparent bitblit registers */
132#define TRANS_DST_KEY_HIGH PAT_FGCOLOR
133#define TRANS_DST_KEY_LOW PAT_BGCOLOR
134#define TRANS_SRC_KEY_HIGH SRC_FGCOLOR
135#define TRANS_SRC_KEY_LOW SRC_BGCOLOR
136
137/* Store queue length in par */
138#define CmdQueLen ivideo->cmdqueuelength
139
140/* ------------- SiS 300 series -------------- */
141
142/* BR(16) (0x8240):
143
144 bit 31 2D engine: 1 is idle,
145 bit 30 3D engine: 1 is idle,
146 bit 29 Command queue: 1 is empty
147 bits 28:24: Current CPU driven BitBlt buffer stage bit[4:0]
148 bits 15:0: Current command queue length
149
150*/
151
152#define SiS300Idle \
153 { \
154 while((MMIO_IN16(ivideo->mmio_vbase, BR(16)+2) & 0xE000) != 0xE000){}; \
155 while((MMIO_IN16(ivideo->mmio_vbase, BR(16)+2) & 0xE000) != 0xE000){}; \
156 while((MMIO_IN16(ivideo->mmio_vbase, BR(16)+2) & 0xE000) != 0xE000){}; \
157 CmdQueLen = MMIO_IN16(ivideo->mmio_vbase, 0x8240); \
158 }
159/* (do three times, because 2D engine seems quite unsure about whether or not it's idle) */
160
161#define SiS300SetupSRCBase(base) \
162 if(CmdQueLen <= 0) SiS300Idle;\
163 MMIO_OUT32(ivideo->mmio_vbase, BR(0), base);\
164 CmdQueLen--;
165
166#define SiS300SetupSRCPitch(pitch) \
167 if(CmdQueLen <= 0) SiS300Idle;\
168 MMIO_OUT16(ivideo->mmio_vbase, BR(1), pitch);\
169 CmdQueLen--;
170
171#define SiS300SetupSRCXY(x,y) \
172 if(CmdQueLen <= 0) SiS300Idle;\
173 MMIO_OUT32(ivideo->mmio_vbase, BR(2), (x)<<16 | (y) );\
174 CmdQueLen--;
175
176#define SiS300SetupDSTBase(base) \
177 if(CmdQueLen <= 0) SiS300Idle;\
178 MMIO_OUT32(ivideo->mmio_vbase, BR(4), base);\
179 CmdQueLen--;
180
181#define SiS300SetupDSTXY(x,y) \
182 if(CmdQueLen <= 0) SiS300Idle;\
183 MMIO_OUT32(ivideo->mmio_vbase, BR(3), (x)<<16 | (y) );\
184 CmdQueLen--;
185
186#define SiS300SetupDSTRect(x,y) \
187 if(CmdQueLen <= 0) SiS300Idle;\
188 MMIO_OUT32(ivideo->mmio_vbase, BR(5), (y)<<16 | (x) );\
189 CmdQueLen--;
190
191#define SiS300SetupDSTColorDepth(bpp) \
192 if(CmdQueLen <= 0) SiS300Idle;\
193 MMIO_OUT16(ivideo->mmio_vbase, BR(1)+2, bpp);\
194 CmdQueLen--;
195
196#define SiS300SetupRect(w,h) \
197 if(CmdQueLen <= 0) SiS300Idle;\
198 MMIO_OUT32(ivideo->mmio_vbase, BR(6), (h)<<16 | (w) );\
199 CmdQueLen--;
200
201#define SiS300SetupPATFG(color) \
202 if(CmdQueLen <= 0) SiS300Idle;\
203 MMIO_OUT32(ivideo->mmio_vbase, BR(7), color);\
204 CmdQueLen--;
205
206#define SiS300SetupPATBG(color) \
207 if(CmdQueLen <= 0) SiS300Idle;\
208 MMIO_OUT32(ivideo->mmio_vbase, BR(8), color);\
209 CmdQueLen--;
210
211#define SiS300SetupSRCFG(color) \
212 if(CmdQueLen <= 0) SiS300Idle;\
213 MMIO_OUT32(ivideo->mmio_vbase, BR(9), color);\
214 CmdQueLen--;
215
216#define SiS300SetupSRCBG(color) \
217 if(CmdQueLen <= 0) SiS300Idle;\
218 MMIO_OUT32(ivideo->mmio_vbase, BR(10), color);\
219 CmdQueLen--;
220
221/* 0x8224 src colorkey high */
222/* 0x8228 src colorkey low */
223/* 0x821c dest colorkey high */
224/* 0x8220 dest colorkey low */
225#define SiS300SetupSRCTrans(color) \
226 if(CmdQueLen <= 1) SiS300Idle;\
227 MMIO_OUT32(ivideo->mmio_vbase, 0x8224, color);\
228 MMIO_OUT32(ivideo->mmio_vbase, 0x8228, color);\
229 CmdQueLen -= 2;
230
231#define SiS300SetupDSTTrans(color) \
232 if(CmdQueLen <= 1) SiS300Idle;\
233 MMIO_OUT32(ivideo->mmio_vbase, 0x821C, color); \
234 MMIO_OUT32(ivideo->mmio_vbase, 0x8220, color); \
235 CmdQueLen -= 2;
236
237#define SiS300SetupMONOPAT(p0,p1) \
238 if(CmdQueLen <= 1) SiS300Idle;\
239 MMIO_OUT32(ivideo->mmio_vbase, BR(11), p0);\
240 MMIO_OUT32(ivideo->mmio_vbase, BR(12), p1);\
241 CmdQueLen -= 2;
242
243#define SiS300SetupClipLT(left,top) \
244 if(CmdQueLen <= 0) SiS300Idle;\
245 MMIO_OUT32(ivideo->mmio_vbase, BR(13), ((left) & 0xFFFF) | (top)<<16 );\
246 CmdQueLen--;
247
248#define SiS300SetupClipRB(right,bottom) \
249 if(CmdQueLen <= 0) SiS300Idle;\
250 MMIO_OUT32(ivideo->mmio_vbase, BR(14), ((right) & 0xFFFF) | (bottom)<<16 );\
251 CmdQueLen--;
252
253/* General */
254#define SiS300SetupROP(rop) \
255 ivideo->CommandReg = (rop) << 8;
256
257#define SiS300SetupCMDFlag(flags) \
258 ivideo->CommandReg |= (flags);
259
260#define SiS300DoCMD \
261 if(CmdQueLen <= 1) SiS300Idle;\
262 MMIO_OUT32(ivideo->mmio_vbase, BR(15), ivideo->CommandReg); \
263 MMIO_OUT32(ivideo->mmio_vbase, BR(16), 0);\
264 CmdQueLen -= 2;
265
266/* -------------- SiS 315/330 series --------------- */
267
268/* Q_STATUS:
269 bit 31 = 1: All engines idle and all queues empty
270 bit 30 = 1: Hardware Queue (=HW CQ, 2D queue, 3D queue) empty
271 bit 29 = 1: 2D engine is idle
272 bit 28 = 1: 3D engine is idle
273 bit 27 = 1: HW command queue empty
274 bit 26 = 1: 2D queue empty
275 bit 25 = 1: 3D queue empty
276 bit 24 = 1: SW command queue empty
277 bits 23:16: 2D counter 3
278 bits 15:8: 2D counter 2
279 bits 7:0: 2D counter 1
280*/
281
282#define SiS310Idle \
283 { \
284 while( (MMIO_IN16(ivideo->mmio_vbase, Q_STATUS+2) & 0x8000) != 0x8000){}; \
285 while( (MMIO_IN16(ivideo->mmio_vbase, Q_STATUS+2) & 0x8000) != 0x8000){}; \
286 CmdQueLen = 0; \
287 }
288
289#define SiS310SetupSRCBase(base) \
290 if(CmdQueLen <= 0) SiS310Idle;\
291 MMIO_OUT32(ivideo->mmio_vbase, SRC_ADDR, base);\
292 CmdQueLen--;
293
294#define SiS310SetupSRCPitch(pitch) \
295 if(CmdQueLen <= 0) SiS310Idle;\
296 MMIO_OUT16(ivideo->mmio_vbase, SRC_PITCH, pitch);\
297 CmdQueLen--;
298
299#define SiS310SetupSRCXY(x,y) \
300 if(CmdQueLen <= 0) SiS310Idle;\
301 MMIO_OUT32(ivideo->mmio_vbase, SRC_Y, (x)<<16 | (y) );\
302 CmdQueLen--;
303
304#define SiS310SetupDSTBase(base) \
305 if(CmdQueLen <= 0) SiS310Idle;\
306 MMIO_OUT32(ivideo->mmio_vbase, DST_ADDR, base);\
307 CmdQueLen--;
308
309#define SiS310SetupDSTXY(x,y) \
310 if(CmdQueLen <= 0) SiS310Idle;\
311 MMIO_OUT32(ivideo->mmio_vbase, DST_Y, (x)<<16 | (y) );\
312 CmdQueLen--;
313
314#define SiS310SetupDSTRect(x,y) \
315 if(CmdQueLen <= 0) SiS310Idle;\
316 MMIO_OUT32(ivideo->mmio_vbase, DST_PITCH, (y)<<16 | (x) );\
317 CmdQueLen--;
318
319#define SiS310SetupDSTColorDepth(bpp) \
320 if(CmdQueLen <= 0) SiS310Idle;\
321 MMIO_OUT16(ivideo->mmio_vbase, AGP_BASE, bpp);\
322 CmdQueLen--;
323
324#define SiS310SetupRect(w,h) \
325 if(CmdQueLen <= 0) SiS310Idle;\
326 MMIO_OUT32(ivideo->mmio_vbase, RECT_WIDTH, (h)<<16 | (w) );\
327 CmdQueLen--;
328
329#define SiS310SetupPATFG(color) \
330 if(CmdQueLen <= 0) SiS310Idle;\
331 MMIO_OUT32(ivideo->mmio_vbase, PAT_FGCOLOR, color);\
332 CmdQueLen--;
333
334#define SiS310SetupPATBG(color) \
335 if(CmdQueLen <= 0) SiS310Idle;\
336 MMIO_OUT32(ivideo->mmio_vbase, PAT_BGCOLOR, color);\
337 CmdQueLen--;
338
339#define SiS310SetupSRCFG(color) \
340 if(CmdQueLen <= 0) SiS310Idle;\
341 MMIO_OUT32(ivideo->mmio_vbase, SRC_FGCOLOR, color);\
342 CmdQueLen--;
343
344#define SiS310SetupSRCBG(color) \
345 if(CmdQueLen <= 0) SiS310Idle;\
346 MMIO_OUT32(ivideo->mmio_vbase, SRC_BGCOLOR, color);\
347 CmdQueLen--;
348
349#define SiS310SetupSRCTrans(color) \
350 if(CmdQueLen <= 1) SiS310Idle;\
351 MMIO_OUT32(ivideo->mmio_vbase, TRANS_SRC_KEY_HIGH, color);\
352 MMIO_OUT32(ivideo->mmio_vbase, TRANS_SRC_KEY_LOW, color);\
353 CmdQueLen -= 2;
354
355#define SiS310SetupDSTTrans(color) \
356 if(CmdQueLen <= 1) SiS310Idle;\
357 MMIO_OUT32(ivideo->mmio_vbase, TRANS_DST_KEY_HIGH, color); \
358 MMIO_OUT32(ivideo->mmio_vbase, TRANS_DST_KEY_LOW, color); \
359 CmdQueLen -= 2;
360
361#define SiS310SetupMONOPAT(p0,p1) \
362 if(CmdQueLen <= 1) SiS310Idle;\
363 MMIO_OUT32(ivideo->mmio_vbase, MONO_MASK, p0);\
364 MMIO_OUT32(ivideo->mmio_vbase, MONO_MASK+4, p1);\
365 CmdQueLen -= 2;
366
367#define SiS310SetupClipLT(left,top) \
368 if(CmdQueLen <= 0) SiS310Idle;\
369 MMIO_OUT32(ivideo->mmio_vbase, LEFT_CLIP, ((left) & 0xFFFF) | (top)<<16 );\
370 CmdQueLen--;
371
372#define SiS310SetupClipRB(right,bottom) \
373 if(CmdQueLen <= 0) SiS310Idle;\
374 MMIO_OUT32(ivideo->mmio_vbase, RIGHT_CLIP, ((right) & 0xFFFF) | (bottom)<<16 );\
375 CmdQueLen--;
376
377#define SiS310SetupROP(rop) \
378 ivideo->CommandReg = (rop) << 8;
379
380#define SiS310SetupCMDFlag(flags) \
381 ivideo->CommandReg |= (flags);
382
383#define SiS310DoCMD \
384 if(CmdQueLen <= 1) SiS310Idle;\
385 MMIO_OUT32(ivideo->mmio_vbase, COMMAND_READY, ivideo->CommandReg); \
386 MMIO_OUT32(ivideo->mmio_vbase, FIRE_TRIGGER, 0); \
387 CmdQueLen -= 2;
388
389
390int sisfb_initaccel(struct sis_video_info *ivideo);
391void sisfb_syncaccel(struct sis_video_info *ivideo);
392
393#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,33)
394void fbcon_sis_bmove(struct display *p, int srcy, int srcx, int dsty,
395 int dstx, int height, int width);
396void fbcon_sis_revc(struct display *p, int srcy, int srcx);
397void fbcon_sis_clear8(struct vc_data *conp, struct display *p, int srcy,
398 int srcx, int height, int width);
399void fbcon_sis_clear16(struct vc_data *conp, struct display *p, int srcy,
400 int srcx, int height, int width);
401void fbcon_sis_clear32(struct vc_data *conp, struct display *p, int srcy,
402 int srcx, int height, int width);
403#endif
404#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,34)
405void fbcon_sis_fillrect(struct fb_info *info, const struct fb_fillrect *rect);
406void fbcon_sis_copyarea(struct fb_info *info, const struct fb_copyarea *area);
407#endif
408
409#endif
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
new file mode 100644
index 000000000000..b773c98f6513
--- /dev/null
+++ b/drivers/video/sis/sis_main.c
@@ -0,0 +1,6027 @@
1/*
2 * SiS 300/305/540/630(S)/730(S)
3 * SiS 315(H/PRO)/55x/(M)65x/(M)661(F/M)X/740/741(GX)/330/(M)760
4 * frame buffer driver for Linux kernels >= 2.4.14 and >=2.6.3
5 *
6 * Copyright (C) 2001-2004 Thomas Winischhofer, Vienna, Austria.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the named License,
11 * or any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
21 *
22 * Author: Thomas Winischhofer <thomas@winischhofer.net>
23 *
24 * Author of (practically wiped) code base:
25 * SiS (www.sis.com)
26 * Copyright (C) 1999 Silicon Integrated Systems, Inc.
27 *
28 * See http://www.winischhofer.net/ for more information and updates
29 *
30 * Originally based on the VBE 2.0 compliant graphic boards framebuffer driver,
31 * which is (c) 1998 Gerd Knorr <kraxel@goldbach.in-berlin.de>
32 *
33 */
34
35#include <linux/config.h>
36#include <linux/version.h>
37#include <linux/module.h>
38#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
39#include <linux/moduleparam.h>
40#endif
41#include <linux/kernel.h>
42#include <linux/smp_lock.h>
43#include <linux/spinlock.h>
44#include <linux/errno.h>
45#include <linux/string.h>
46#include <linux/mm.h>
47#include <linux/tty.h>
48#include <linux/slab.h>
49#include <linux/delay.h>
50#include <linux/fb.h>
51#include <linux/console.h>
52#include <linux/selection.h>
53#include <linux/smp_lock.h>
54#include <linux/ioport.h>
55#include <linux/init.h>
56#include <linux/pci.h>
57#include <linux/vmalloc.h>
58#include <linux/vt_kern.h>
59#include <linux/capability.h>
60#include <linux/fs.h>
61#include <linux/types.h>
62#include <asm/uaccess.h>
63#include <asm/io.h>
64#ifdef CONFIG_MTRR
65#include <asm/mtrr.h>
66#endif
67
68#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
69#include <video/fbcon.h>
70#include <video/fbcon-cfb8.h>
71#include <video/fbcon-cfb16.h>
72#include <video/fbcon-cfb24.h>
73#include <video/fbcon-cfb32.h>
74#endif
75
76#include "sis.h"
77#include "sis_main.h"
78
79#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
80#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,3)
81#error "This version of sisfb requires at least 2.6.3"
82#endif
83#endif
84
85#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
86#ifdef FBCON_HAS_CFB8
87extern struct display_switch fbcon_sis8;
88#endif
89#ifdef FBCON_HAS_CFB16
90extern struct display_switch fbcon_sis16;
91#endif
92#ifdef FBCON_HAS_CFB32
93extern struct display_switch fbcon_sis32;
94#endif
95#endif
96
97/* ------------------ Internal helper routines ----------------- */
98
99static void __init
100sisfb_setdefaultparms(void)
101{
102 sisfb_off = 0;
103 sisfb_parm_mem = 0;
104 sisfb_accel = -1;
105 sisfb_ypan = -1;
106 sisfb_max = -1;
107 sisfb_userom = -1;
108 sisfb_useoem = -1;
109#ifdef MODULE
110 /* Module: "None" for 2.4, default mode for 2.5+ */
111#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
112 sisfb_mode_idx = -1;
113#else
114 sisfb_mode_idx = MODE_INDEX_NONE;
115#endif
116#else
117 /* Static: Default mode */
118 sisfb_mode_idx = -1;
119#endif
120 sisfb_parm_rate = -1;
121 sisfb_crt1off = 0;
122 sisfb_forcecrt1 = -1;
123 sisfb_crt2type = -1;
124 sisfb_crt2flags = 0;
125 sisfb_pdc = 0xff;
126 sisfb_pdca = 0xff;
127 sisfb_scalelcd = -1;
128 sisfb_specialtiming = CUT_NONE;
129 sisfb_lvdshl = -1;
130 sisfb_dstn = 0;
131 sisfb_fstn = 0;
132 sisfb_tvplug = -1;
133 sisfb_tvstd = -1;
134 sisfb_tvxposoffset = 0;
135 sisfb_tvyposoffset = 0;
136 sisfb_filter = -1;
137 sisfb_nocrt2rate = 0;
138#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
139 sisfb_inverse = 0;
140 sisfb_fontname[0] = 0;
141#endif
142#if !defined(__i386__) && !defined(__x86_64__)
143 sisfb_resetcard = 0;
144 sisfb_videoram = 0;
145#endif
146}
147
148static void __devinit
149sisfb_search_vesamode(unsigned int vesamode, BOOLEAN quiet)
150{
151 int i = 0, j = 0;
152
153 /* BEWARE: We don't know the hardware specs yet and there is no ivideo */
154
155 if(vesamode == 0) {
156#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
157 sisfb_mode_idx = MODE_INDEX_NONE;
158#else
159 if(!quiet) {
160 printk(KERN_ERR "sisfb: Invalid mode. Using default.\n");
161 }
162 sisfb_mode_idx = DEFAULT_MODE;
163#endif
164 return;
165 }
166
167 vesamode &= 0x1dff; /* Clean VESA mode number from other flags */
168
169 while(sisbios_mode[i++].mode_no[0] != 0) {
170 if( (sisbios_mode[i-1].vesa_mode_no_1 == vesamode) ||
171 (sisbios_mode[i-1].vesa_mode_no_2 == vesamode) ) {
172 if(sisfb_fstn) {
173 if(sisbios_mode[i-1].mode_no[1] == 0x50 ||
174 sisbios_mode[i-1].mode_no[1] == 0x56 ||
175 sisbios_mode[i-1].mode_no[1] == 0x53) continue;
176 } else {
177 if(sisbios_mode[i-1].mode_no[1] == 0x5a ||
178 sisbios_mode[i-1].mode_no[1] == 0x5b) continue;
179 }
180 sisfb_mode_idx = i - 1;
181 j = 1;
182 break;
183 }
184 }
185 if((!j) && !quiet) printk(KERN_ERR "sisfb: Invalid VESA mode 0x%x'\n", vesamode);
186}
187
188static void
189sisfb_search_mode(char *name, BOOLEAN quiet)
190{
191 int i = 0;
192 unsigned int j = 0, xres = 0, yres = 0, depth = 0, rate = 0;
193 char strbuf[16], strbuf1[20];
194 char *nameptr = name;
195
196 /* BEWARE: We don't know the hardware specs yet and there is no ivideo */
197
198 if(name == NULL) {
199 if(!quiet) {
200 printk(KERN_ERR "sisfb: Internal error, using default mode.\n");
201 }
202 sisfb_mode_idx = DEFAULT_MODE;
203 return;
204 }
205
206#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
207 if(!strnicmp(name, sisbios_mode[MODE_INDEX_NONE].name, strlen(name))) {
208 if(!quiet) {
209 printk(KERN_ERR "sisfb: Mode 'none' not supported anymore. Using default.\n");
210 }
211 sisfb_mode_idx = DEFAULT_MODE;
212 return;
213 }
214#endif
215 if(strlen(name) <= 19) {
216 strcpy(strbuf1, name);
217 for(i=0; i<strlen(strbuf1); i++) {
218 if(strbuf1[i] < '0' || strbuf1[i] > '9') strbuf1[i] = ' ';
219 }
220
221 /* This does some fuzzy mode naming detection */
222 if(sscanf(strbuf1, "%u %u %u %u", &xres, &yres, &depth, &rate) == 4) {
223 if((rate <= 32) || (depth > 32)) {
224 j = rate; rate = depth; depth = j;
225 }
226 sprintf(strbuf, "%ux%ux%u", xres, yres, depth);
227 nameptr = strbuf;
228 sisfb_parm_rate = rate;
229 } else if(sscanf(strbuf1, "%u %u %u", &xres, &yres, &depth) == 3) {
230 sprintf(strbuf, "%ux%ux%u", xres, yres, depth);
231 nameptr = strbuf;
232 } else {
233 xres = 0;
234 if((sscanf(strbuf1, "%u %u", &xres, &yres) == 2) && (xres != 0)) {
235 sprintf(strbuf, "%ux%ux8", xres, yres);
236 nameptr = strbuf;
237 } else {
238 sisfb_search_vesamode(simple_strtoul(name, NULL, 0), quiet);
239 return;
240 }
241 }
242 }
243
244 i = 0; j = 0;
245 while(sisbios_mode[i].mode_no[0] != 0) {
246 if(!strnicmp(nameptr, sisbios_mode[i++].name, strlen(nameptr))) {
247 if(sisfb_fstn) {
248 if(sisbios_mode[i-1].mode_no[1] == 0x50 ||
249 sisbios_mode[i-1].mode_no[1] == 0x56 ||
250 sisbios_mode[i-1].mode_no[1] == 0x53) continue;
251 } else {
252 if(sisbios_mode[i-1].mode_no[1] == 0x5a ||
253 sisbios_mode[i-1].mode_no[1] == 0x5b) continue;
254 }
255 sisfb_mode_idx = i - 1;
256 j = 1;
257 break;
258 }
259 }
260 if((!j) && !quiet) printk(KERN_ERR "sisfb: Invalid mode '%s'\n", nameptr);
261}
262
263#ifndef MODULE
264static void __devinit
265sisfb_get_vga_mode_from_kernel(void)
266{
267#if (defined(__i386__) || defined(__x86_64__)) && defined(CONFIG_VIDEO_SELECT)
268 char mymode[32];
269 int mydepth = screen_info.lfb_depth;
270
271 if(screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB) return;
272
273 if( (screen_info.lfb_width >= 320) && (screen_info.lfb_width <= 2048) &&
274 (screen_info.lfb_height >= 200) && (screen_info.lfb_height <= 1536) &&
275 (mydepth >= 8) && (mydepth <= 32) ) {
276
277 if(mydepth == 24) mydepth = 32;
278
279 sprintf(mymode, "%ux%ux%u", screen_info.lfb_width,
280 screen_info.lfb_height,
281 mydepth);
282
283 printk(KERN_DEBUG "sisfb: Using vga mode %s pre-set by kernel as default\n", mymode);
284
285 sisfb_search_mode(mymode, TRUE);
286 }
287#endif
288 return;
289}
290#endif
291
292static void __init
293sisfb_search_crt2type(const char *name)
294{
295 int i = 0;
296
297 /* BEWARE: We don't know the hardware specs yet and there is no ivideo */
298
299 if(name == NULL) return;
300
301 while(sis_crt2type[i].type_no != -1) {
302 if(!strnicmp(name, sis_crt2type[i].name, strlen(sis_crt2type[i].name))) {
303 sisfb_crt2type = sis_crt2type[i].type_no;
304 sisfb_tvplug = sis_crt2type[i].tvplug_no;
305 sisfb_crt2flags = sis_crt2type[i].flags;
306 break;
307 }
308 i++;
309 }
310
311 sisfb_dstn = (sisfb_crt2flags & FL_550_DSTN) ? 1 : 0;
312 sisfb_fstn = (sisfb_crt2flags & FL_550_FSTN) ? 1 : 0;
313
314 if(sisfb_crt2type < 0) {
315 printk(KERN_ERR "sisfb: Invalid CRT2 type: %s\n", name);
316 }
317}
318
319static void __init
320sisfb_search_tvstd(const char *name)
321{
322 int i = 0;
323
324 /* BEWARE: We don't know the hardware specs yet and there is no ivideo */
325
326 if(name == NULL) return;
327
328 while(sis_tvtype[i].type_no != -1) {
329 if(!strnicmp(name, sis_tvtype[i].name, strlen(sis_tvtype[i].name))) {
330 sisfb_tvstd = sis_tvtype[i].type_no;
331 break;
332 }
333 i++;
334 }
335}
336
337static void __init
338sisfb_search_specialtiming(const char *name)
339{
340 int i = 0;
341 BOOLEAN found = FALSE;
342
343 /* BEWARE: We don't know the hardware specs yet and there is no ivideo */
344
345 if(name == NULL) return;
346
347 if(!strnicmp(name, "none", 4)) {
348 sisfb_specialtiming = CUT_FORCENONE;
349 printk(KERN_DEBUG "sisfb: Special timing disabled\n");
350 } else {
351 while(mycustomttable[i].chipID != 0) {
352 if(!strnicmp(name,mycustomttable[i].optionName, strlen(mycustomttable[i].optionName))) {
353 sisfb_specialtiming = mycustomttable[i].SpecialID;
354 found = TRUE;
355 printk(KERN_INFO "sisfb: Special timing for %s %s forced (\"%s\")\n",
356 mycustomttable[i].vendorName, mycustomttable[i].cardName,
357 mycustomttable[i].optionName);
358 break;
359 }
360 i++;
361 }
362 if(!found) {
363 printk(KERN_WARNING "sisfb: Invalid SpecialTiming parameter, valid are:");
364 printk(KERN_WARNING "\t\"none\" (to disable special timings)\n");
365 i = 0;
366 while(mycustomttable[i].chipID != 0) {
367 printk(KERN_WARNING "\t\"%s\" (for %s %s)\n",
368 mycustomttable[i].optionName,
369 mycustomttable[i].vendorName,
370 mycustomttable[i].cardName);
371 i++;
372 }
373 }
374 }
375}
376
377static BOOLEAN __devinit
378sisfb_interpret_edid(struct sisfb_monitor *monitor, u8 *buffer)
379{
380 int i, j, xres, yres, refresh, index;
381 u32 emodes;
382
383 if(buffer[0] != 0x00 || buffer[1] != 0xff ||
384 buffer[2] != 0xff || buffer[3] != 0xff ||
385 buffer[4] != 0xff || buffer[5] != 0xff ||
386 buffer[6] != 0xff || buffer[7] != 0x00) {
387 printk(KERN_DEBUG "sisfb: Bad EDID header\n");
388 return FALSE;
389 }
390
391 if(buffer[0x12] != 0x01) {
392 printk(KERN_INFO "sisfb: EDID version %d not supported\n",
393 buffer[0x12]);
394 return FALSE;
395 }
396
397 monitor->feature = buffer[0x18];
398
399 if(!buffer[0x14] & 0x80) {
400 if(!(buffer[0x14] & 0x08)) {
401 printk(KERN_INFO "sisfb: WARNING: Monitor does not support separate syncs\n");
402 }
403 }
404
405 if(buffer[0x13] >= 0x01) {
406 /* EDID V1 rev 1 and 2: Search for monitor descriptor
407 * to extract ranges
408 */
409 j = 0x36;
410 for(i=0; i<4; i++) {
411 if(buffer[j] == 0x00 && buffer[j + 1] == 0x00 &&
412 buffer[j + 2] == 0x00 && buffer[j + 3] == 0xfd &&
413 buffer[j + 4] == 0x00) {
414 monitor->hmin = buffer[j + 7];
415 monitor->hmax = buffer[j + 8];
416 monitor->vmin = buffer[j + 5];
417 monitor->vmax = buffer[j + 6];
418 monitor->dclockmax = buffer[j + 9] * 10 * 1000;
419 monitor->datavalid = TRUE;
420 break;
421 }
422 j += 18;
423 }
424 }
425
426 if(!monitor->datavalid) {
427 /* Otherwise: Get a range from the list of supported
428 * Estabished Timings. This is not entirely accurate,
429 * because fixed frequency monitors are not supported
430 * that way.
431 */
432 monitor->hmin = 65535; monitor->hmax = 0;
433 monitor->vmin = 65535; monitor->vmax = 0;
434 monitor->dclockmax = 0;
435 emodes = buffer[0x23] | (buffer[0x24] << 8) | (buffer[0x25] << 16);
436 for(i = 0; i < 13; i++) {
437 if(emodes & sisfb_ddcsmodes[i].mask) {
438 if(monitor->hmin > sisfb_ddcsmodes[i].h) monitor->hmin = sisfb_ddcsmodes[i].h;
439 if(monitor->hmax < sisfb_ddcsmodes[i].h) monitor->hmax = sisfb_ddcsmodes[i].h + 1;
440 if(monitor->vmin > sisfb_ddcsmodes[i].v) monitor->vmin = sisfb_ddcsmodes[i].v;
441 if(monitor->vmax < sisfb_ddcsmodes[i].v) monitor->vmax = sisfb_ddcsmodes[i].v;
442 if(monitor->dclockmax < sisfb_ddcsmodes[i].d) monitor->dclockmax = sisfb_ddcsmodes[i].d;
443 }
444 }
445 index = 0x26;
446 for(i = 0; i < 8; i++) {
447 xres = (buffer[index] + 31) * 8;
448 switch(buffer[index + 1] & 0xc0) {
449 case 0xc0: yres = (xres * 9) / 16; break;
450 case 0x80: yres = (xres * 4) / 5; break;
451 case 0x40: yres = (xres * 3) / 4; break;
452 default: yres = xres; break;
453 }
454 refresh = (buffer[index + 1] & 0x3f) + 60;
455 if((xres >= 640) && (yres >= 480)) {
456 for(j = 0; j < 8; j++) {
457 if((xres == sisfb_ddcfmodes[j].x) &&
458 (yres == sisfb_ddcfmodes[j].y) &&
459 (refresh == sisfb_ddcfmodes[j].v)) {
460 if(monitor->hmin > sisfb_ddcfmodes[j].h) monitor->hmin = sisfb_ddcfmodes[j].h;
461 if(monitor->hmax < sisfb_ddcfmodes[j].h) monitor->hmax = sisfb_ddcfmodes[j].h + 1;
462 if(monitor->vmin > sisfb_ddcsmodes[j].v) monitor->vmin = sisfb_ddcsmodes[j].v;
463 if(monitor->vmax < sisfb_ddcsmodes[j].v) monitor->vmax = sisfb_ddcsmodes[j].v;
464 if(monitor->dclockmax < sisfb_ddcsmodes[j].d) monitor->dclockmax = sisfb_ddcsmodes[i].d;
465 }
466 }
467 }
468 index += 2;
469 }
470 if((monitor->hmin <= monitor->hmax) && (monitor->vmin <= monitor->vmax)) {
471 monitor->datavalid = TRUE;
472 }
473 }
474
475 return(monitor->datavalid);
476}
477
478static void __devinit
479sisfb_handle_ddc(struct sis_video_info *ivideo, struct sisfb_monitor *monitor, int crtno)
480{
481 USHORT temp, i, realcrtno = crtno;
482 u8 buffer[256];
483
484 monitor->datavalid = FALSE;
485
486 if(crtno) {
487 if(ivideo->vbflags & CRT2_LCD) realcrtno = 1;
488 else if(ivideo->vbflags & CRT2_VGA) realcrtno = 2;
489 else return;
490 }
491
492 if((ivideo->sisfb_crt1off) && (!crtno)) return;
493
494 temp = SiS_HandleDDC(&ivideo->SiS_Pr, ivideo->vbflags, ivideo->sisvga_engine,
495 realcrtno, 0, &buffer[0]);
496 if((!temp) || (temp == 0xffff)) {
497 printk(KERN_INFO "sisfb: CRT%d DDC probing failed\n", crtno + 1);
498 return;
499 } else {
500 printk(KERN_INFO "sisfb: CRT%d DDC supported\n", crtno + 1);
501 printk(KERN_INFO "sisfb: CRT%d DDC level: %s%s%s%s\n",
502 crtno + 1,
503 (temp & 0x1a) ? "" : "[none of the supported]",
504 (temp & 0x02) ? "2 " : "",
505 (temp & 0x08) ? "D&P" : "",
506 (temp & 0x10) ? "FPDI-2" : "");
507 if(temp & 0x02) {
508 i = 3; /* Number of retrys */
509 do {
510 temp = SiS_HandleDDC(&ivideo->SiS_Pr, ivideo->vbflags, ivideo->sisvga_engine,
511 realcrtno, 1, &buffer[0]);
512 } while((temp) && i--);
513 if(!temp) {
514 if(sisfb_interpret_edid(monitor, &buffer[0])) {
515 printk(KERN_INFO "sisfb: Monitor range H %d-%dKHz, V %d-%dHz, Max. dotclock %dMHz\n",
516 monitor->hmin, monitor->hmax, monitor->vmin, monitor->vmax,
517 monitor->dclockmax / 1000);
518 } else {
519 printk(KERN_INFO "sisfb: CRT%d DDC EDID corrupt\n", crtno + 1);
520 }
521 } else {
522 printk(KERN_INFO "sisfb: CRT%d DDC reading failed\n", crtno + 1);
523 }
524 } else {
525 printk(KERN_INFO "sisfb: VESA D&P and FPDI-2 not supported yet\n");
526 }
527 }
528}
529
530static BOOLEAN
531sisfb_verify_rate(struct sis_video_info *ivideo, struct sisfb_monitor *monitor,
532 int mode_idx, int rate_idx, int rate)
533{
534 int htotal, vtotal;
535 unsigned int dclock, hsync;
536
537 if(!monitor->datavalid) return TRUE;
538
539 if(mode_idx < 0) return FALSE;
540
541 /* Skip for 320x200, 320x240, 640x400 */
542 switch(sisbios_mode[mode_idx].mode_no[ivideo->mni]) {
543 case 0x59:
544 case 0x41:
545 case 0x4f:
546 case 0x50:
547 case 0x56:
548 case 0x53:
549 case 0x2f:
550 case 0x5d:
551 case 0x5e:
552 return TRUE;
553#ifdef CONFIG_FB_SIS_315
554 case 0x5a:
555 case 0x5b:
556 if(ivideo->sisvga_engine == SIS_315_VGA) return TRUE;
557#endif
558 }
559
560 if(rate < (monitor->vmin - 1)) return FALSE;
561 if(rate > (monitor->vmax + 1)) return FALSE;
562
563 if(sisfb_gettotalfrommode(&ivideo->SiS_Pr, &ivideo->sishw_ext,
564 sisbios_mode[mode_idx].mode_no[ivideo->mni],
565 &htotal, &vtotal, rate_idx)) {
566 dclock = (htotal * vtotal * rate) / 1000;
567 if(dclock > (monitor->dclockmax + 1000)) return FALSE;
568 hsync = dclock / htotal;
569 if(hsync < (monitor->hmin - 1)) return FALSE;
570 if(hsync > (monitor->hmax + 1)) return FALSE;
571 } else {
572 return FALSE;
573 }
574 return TRUE;
575}
576
577static int
578sisfb_validate_mode(struct sis_video_info *ivideo, int myindex, u32 vbflags)
579{
580 u16 xres=0, yres, myres;
581
582#ifdef CONFIG_FB_SIS_300
583 if(ivideo->sisvga_engine == SIS_300_VGA) {
584 if(!(sisbios_mode[myindex].chipset & MD_SIS300)) return(-1);
585 }
586#endif
587#ifdef CONFIG_FB_SIS_315
588 if(ivideo->sisvga_engine == SIS_315_VGA) {
589 if(!(sisbios_mode[myindex].chipset & MD_SIS315)) return(-1);
590 }
591#endif
592
593 myres = sisbios_mode[myindex].yres;
594
595 switch(vbflags & VB_DISPTYPE_DISP2) {
596
597 case CRT2_LCD:
598
599 xres = ivideo->lcdxres; yres = ivideo->lcdyres;
600
601 if(ivideo->SiS_Pr.SiS_CustomT != CUT_PANEL848) {
602 if(sisbios_mode[myindex].xres > xres) return(-1);
603 if(myres > yres) return(-1);
604 }
605
606 if(vbflags & (VB_LVDS | VB_30xBDH)) {
607 if(sisbios_mode[myindex].xres == 320) {
608 if((myres == 240) || (myres == 480)) {
609 if(!ivideo->sisfb_fstn) {
610 if(sisbios_mode[myindex].mode_no[1] == 0x5a ||
611 sisbios_mode[myindex].mode_no[1] == 0x5b)
612 return(-1);
613 } else {
614 if(sisbios_mode[myindex].mode_no[1] == 0x50 ||
615 sisbios_mode[myindex].mode_no[1] == 0x56 ||
616 sisbios_mode[myindex].mode_no[1] == 0x53)
617 return(-1);
618 }
619 }
620 }
621 }
622
623 if(SiS_GetModeID_LCD(ivideo->sisvga_engine, vbflags, sisbios_mode[myindex].xres,
624 sisbios_mode[myindex].yres, 0, ivideo->sisfb_fstn,
625 ivideo->SiS_Pr.SiS_CustomT, xres, yres) < 0x14) {
626 return(-1);
627 }
628 break;
629
630 case CRT2_TV:
631 if(SiS_GetModeID_TV(ivideo->sisvga_engine, vbflags, sisbios_mode[myindex].xres,
632 sisbios_mode[myindex].yres, 0) < 0x14) {
633 return(-1);
634 }
635 break;
636
637 case CRT2_VGA:
638 if(SiS_GetModeID_VGA2(ivideo->sisvga_engine, vbflags, sisbios_mode[myindex].xres,
639 sisbios_mode[myindex].yres, 0) < 0x14) {
640 return(-1);
641 }
642 break;
643 }
644
645 return(myindex);
646}
647
648static u8
649sisfb_search_refresh_rate(struct sis_video_info *ivideo, unsigned int rate, int mode_idx)
650{
651 u16 xres, yres;
652 int i = 0;
653
654 xres = sisbios_mode[mode_idx].xres;
655 yres = sisbios_mode[mode_idx].yres;
656
657 ivideo->rate_idx = 0;
658 while((sisfb_vrate[i].idx != 0) && (sisfb_vrate[i].xres <= xres)) {
659 if((sisfb_vrate[i].xres == xres) && (sisfb_vrate[i].yres == yres)) {
660 if(sisfb_vrate[i].refresh == rate) {
661 ivideo->rate_idx = sisfb_vrate[i].idx;
662 break;
663 } else if(sisfb_vrate[i].refresh > rate) {
664 if((sisfb_vrate[i].refresh - rate) <= 3) {
665 DPRINTK("sisfb: Adjusting rate from %d up to %d\n",
666 rate, sisfb_vrate[i].refresh);
667 ivideo->rate_idx = sisfb_vrate[i].idx;
668 ivideo->refresh_rate = sisfb_vrate[i].refresh;
669 } else if(((rate - sisfb_vrate[i-1].refresh) <= 2)
670 && (sisfb_vrate[i].idx != 1)) {
671 DPRINTK("sisfb: Adjusting rate from %d down to %d\n",
672 rate, sisfb_vrate[i-1].refresh);
673 ivideo->rate_idx = sisfb_vrate[i-1].idx;
674 ivideo->refresh_rate = sisfb_vrate[i-1].refresh;
675 }
676 break;
677 } else if((rate - sisfb_vrate[i].refresh) <= 2) {
678 DPRINTK("sisfb: Adjusting rate from %d down to %d\n",
679 rate, sisfb_vrate[i].refresh);
680 ivideo->rate_idx = sisfb_vrate[i].idx;
681 break;
682 }
683 }
684 i++;
685 }
686 if(ivideo->rate_idx > 0) {
687 return ivideo->rate_idx;
688 } else {
689 printk(KERN_INFO "sisfb: Unsupported rate %d for %dx%d\n",
690 rate, xres, yres);
691 return 0;
692 }
693}
694
695static BOOLEAN
696sisfb_bridgeisslave(struct sis_video_info *ivideo)
697{
698 unsigned char P1_00;
699
700 if(!(ivideo->vbflags & VB_VIDEOBRIDGE)) return FALSE;
701
702 inSISIDXREG(SISPART1,0x00,P1_00);
703 if( ((ivideo->sisvga_engine == SIS_300_VGA) && (P1_00 & 0xa0) == 0x20) ||
704 ((ivideo->sisvga_engine == SIS_315_VGA) && (P1_00 & 0x50) == 0x10) ) {
705 return TRUE;
706 } else {
707 return FALSE;
708 }
709}
710
711static BOOLEAN
712sisfballowretracecrt1(struct sis_video_info *ivideo)
713{
714 u8 temp;
715
716 inSISIDXREG(SISCR,0x17,temp);
717 if(!(temp & 0x80)) return FALSE;
718
719 inSISIDXREG(SISSR,0x1f,temp);
720 if(temp & 0xc0) return FALSE;
721
722 return TRUE;
723}
724
725static BOOLEAN
726sisfbcheckvretracecrt1(struct sis_video_info *ivideo)
727{
728 if(!sisfballowretracecrt1(ivideo)) return FALSE;
729
730 if(inSISREG(SISINPSTAT) & 0x08) return TRUE;
731 else return FALSE;
732}
733
734static void
735sisfbwaitretracecrt1(struct sis_video_info *ivideo)
736{
737 int watchdog;
738
739 if(!sisfballowretracecrt1(ivideo)) return;
740
741 watchdog = 65536;
742 while((!(inSISREG(SISINPSTAT) & 0x08)) && --watchdog);
743 watchdog = 65536;
744 while((inSISREG(SISINPSTAT) & 0x08) && --watchdog);
745}
746
747static BOOLEAN
748sisfbcheckvretracecrt2(struct sis_video_info *ivideo)
749{
750 unsigned char temp, reg;
751
752 switch(ivideo->sisvga_engine) {
753 case SIS_300_VGA: reg = 0x25; break;
754 case SIS_315_VGA: reg = 0x30; break;
755 default: return FALSE;
756 }
757
758 inSISIDXREG(SISPART1, reg, temp);
759 if(temp & 0x02) return TRUE;
760 else return FALSE;
761}
762
763static BOOLEAN
764sisfb_CheckVBRetrace(struct sis_video_info *ivideo)
765{
766 if(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {
767 if(sisfb_bridgeisslave(ivideo)) {
768 return(sisfbcheckvretracecrt1(ivideo));
769 } else {
770 return(sisfbcheckvretracecrt2(ivideo));
771 }
772 }
773 return(sisfbcheckvretracecrt1(ivideo));
774}
775
776static u32
777sisfb_setupvbblankflags(struct sis_video_info *ivideo, u32 *vcount, u32 *hcount)
778{
779 u8 idx, reg1, reg2, reg3, reg4;
780 u32 ret = 0;
781
782 (*vcount) = (*hcount) = 0;
783
784 if((ivideo->currentvbflags & VB_DISPTYPE_DISP2) && (!(sisfb_bridgeisslave(ivideo)))) {
785 ret |= (FB_VBLANK_HAVE_VSYNC |
786 FB_VBLANK_HAVE_HBLANK |
787 FB_VBLANK_HAVE_VBLANK |
788 FB_VBLANK_HAVE_VCOUNT |
789 FB_VBLANK_HAVE_HCOUNT);
790 switch(ivideo->sisvga_engine) {
791 case SIS_300_VGA: idx = 0x25; break;
792 default:
793 case SIS_315_VGA: idx = 0x30; break;
794 }
795 inSISIDXREG(SISPART1,(idx+0),reg1); /* 30 */
796 inSISIDXREG(SISPART1,(idx+1),reg2); /* 31 */
797 inSISIDXREG(SISPART1,(idx+2),reg3); /* 32 */
798 inSISIDXREG(SISPART1,(idx+3),reg4); /* 33 */
799 if(reg1 & 0x01) ret |= FB_VBLANK_VBLANKING;
800 if(reg1 & 0x02) ret |= FB_VBLANK_VSYNCING;
801 if(reg4 & 0x80) ret |= FB_VBLANK_HBLANKING;
802 (*vcount) = reg3 | ((reg4 & 0x70) << 4);
803 (*hcount) = reg2 | ((reg4 & 0x0f) << 8);
804 } else if(sisfballowretracecrt1(ivideo)) {
805 ret |= (FB_VBLANK_HAVE_VSYNC |
806 FB_VBLANK_HAVE_VBLANK |
807 FB_VBLANK_HAVE_VCOUNT |
808 FB_VBLANK_HAVE_HCOUNT);
809 reg1 = inSISREG(SISINPSTAT);
810 if(reg1 & 0x08) ret |= FB_VBLANK_VSYNCING;
811 if(reg1 & 0x01) ret |= FB_VBLANK_VBLANKING;
812 inSISIDXREG(SISCR,0x20,reg1);
813 inSISIDXREG(SISCR,0x1b,reg1);
814 inSISIDXREG(SISCR,0x1c,reg2);
815 inSISIDXREG(SISCR,0x1d,reg3);
816 (*vcount) = reg2 | ((reg3 & 0x07) << 8);
817 (*hcount) = (reg1 | ((reg3 & 0x10) << 4)) << 3;
818 }
819 return ret;
820}
821
822static int
823sisfb_myblank(struct sis_video_info *ivideo, int blank)
824{
825 u8 sr01, sr11, sr1f, cr63=0, p2_0, p1_13;
826 BOOLEAN backlight = TRUE;
827
828 switch(blank) {
829 case FB_BLANK_UNBLANK: /* on */
830 sr01 = 0x00;
831 sr11 = 0x00;
832 sr1f = 0x00;
833 cr63 = 0x00;
834 p2_0 = 0x20;
835 p1_13 = 0x00;
836 backlight = TRUE;
837 break;
838 case FB_BLANK_NORMAL: /* blank */
839 sr01 = 0x20;
840 sr11 = 0x00;
841 sr1f = 0x00;
842 cr63 = 0x00;
843 p2_0 = 0x20;
844 p1_13 = 0x00;
845 backlight = TRUE;
846 break;
847 case FB_BLANK_VSYNC_SUSPEND: /* no vsync */
848 sr01 = 0x20;
849 sr11 = 0x08;
850 sr1f = 0x80;
851 cr63 = 0x40;
852 p2_0 = 0x40;
853 p1_13 = 0x80;
854 backlight = FALSE;
855 break;
856 case FB_BLANK_HSYNC_SUSPEND: /* no hsync */
857 sr01 = 0x20;
858 sr11 = 0x08;
859 sr1f = 0x40;
860 cr63 = 0x40;
861 p2_0 = 0x80;
862 p1_13 = 0x40;
863 backlight = FALSE;
864 break;
865 case FB_BLANK_POWERDOWN: /* off */
866 sr01 = 0x20;
867 sr11 = 0x08;
868 sr1f = 0xc0;
869 cr63 = 0x40;
870 p2_0 = 0xc0;
871 p1_13 = 0xc0;
872 backlight = FALSE;
873 break;
874 default:
875 return 1;
876 }
877
878 if(ivideo->currentvbflags & VB_DISPTYPE_CRT1) {
879
880 if( (!ivideo->sisfb_thismonitor.datavalid) ||
881 ((ivideo->sisfb_thismonitor.datavalid) &&
882 (ivideo->sisfb_thismonitor.feature & 0xe0))) {
883
884 if(ivideo->sisvga_engine == SIS_315_VGA) {
885 setSISIDXREG(SISCR, ivideo->SiS_Pr.SiS_MyCR63, 0xbf, cr63);
886 }
887
888 if(!(sisfb_bridgeisslave(ivideo))) {
889 setSISIDXREG(SISSR, 0x01, ~0x20, sr01);
890 setSISIDXREG(SISSR, 0x1f, 0x3f, sr1f);
891 }
892 }
893
894 }
895
896 if(ivideo->currentvbflags & CRT2_LCD) {
897
898 if(ivideo->vbflags & (VB_301LV|VB_302LV|VB_302ELV)) {
899 if(backlight) {
900 SiS_SiS30xBLOn(&ivideo->SiS_Pr, &ivideo->sishw_ext);
901 } else {
902 SiS_SiS30xBLOff(&ivideo->SiS_Pr, &ivideo->sishw_ext);
903 }
904 } else if(ivideo->sisvga_engine == SIS_315_VGA) {
905 if(ivideo->vbflags & VB_CHRONTEL) {
906 if(backlight) {
907 SiS_Chrontel701xBLOn(&ivideo->SiS_Pr,&ivideo->sishw_ext);
908 } else {
909 SiS_Chrontel701xBLOff(&ivideo->SiS_Pr);
910 }
911 }
912 }
913
914 if(((ivideo->sisvga_engine == SIS_300_VGA) &&
915 (ivideo->vbflags & (VB_301|VB_30xBDH|VB_LVDS))) ||
916 ((ivideo->sisvga_engine == SIS_315_VGA) &&
917 ((ivideo->vbflags & (VB_LVDS | VB_CHRONTEL)) == VB_LVDS))) {
918 setSISIDXREG(SISSR, 0x11, ~0x0c, sr11);
919 }
920
921 if(ivideo->sisvga_engine == SIS_300_VGA) {
922 if((ivideo->vbflags & (VB_301B|VB_301C|VB_302B)) &&
923 (!(ivideo->vbflags & VB_30xBDH))) {
924 setSISIDXREG(SISPART1, 0x13, 0x3f, p1_13);
925 }
926 } else if(ivideo->sisvga_engine == SIS_315_VGA) {
927 if((ivideo->vbflags & (VB_301B|VB_301C|VB_302B)) &&
928 (!(ivideo->vbflags & VB_30xBDH))) {
929 setSISIDXREG(SISPART2, 0x00, 0x1f, p2_0);
930 }
931 }
932
933 } else if(ivideo->currentvbflags & CRT2_VGA) {
934
935 if(ivideo->vbflags & (VB_301B|VB_301C|VB_302B)) {
936 setSISIDXREG(SISPART2, 0x00, 0x1f, p2_0);
937 }
938
939 }
940
941 return(0);
942}
943
944/* ----------- FBDev related routines for all series ----------- */
945
946static int
947sisfb_get_cmap_len(const struct fb_var_screeninfo *var)
948{
949 return (var->bits_per_pixel == 8) ? 256 : 16;
950}
951
952static void
953sisfb_set_vparms(struct sis_video_info *ivideo)
954{
955 switch(ivideo->video_bpp) {
956 case 8:
957 ivideo->DstColor = 0x0000;
958 ivideo->SiS310_AccelDepth = 0x00000000;
959 ivideo->video_cmap_len = 256;
960 break;
961 case 16:
962 ivideo->DstColor = 0x8000;
963 ivideo->SiS310_AccelDepth = 0x00010000;
964 ivideo->video_cmap_len = 16;
965 break;
966 case 32:
967 ivideo->DstColor = 0xC000;
968 ivideo->SiS310_AccelDepth = 0x00020000;
969 ivideo->video_cmap_len = 16;
970 break;
971 default:
972 ivideo->video_cmap_len = 16;
973 printk(KERN_ERR "sisfb: Unsupported depth %d", ivideo->video_bpp);
974 ivideo->accel = 0;
975 break;
976 }
977}
978
979static int
980sisfb_calc_maxyres(struct sis_video_info *ivideo, struct fb_var_screeninfo *var)
981{
982 int maxyres = ivideo->heapstart / (var->xres_virtual * (var->bits_per_pixel >> 3));
983
984 if(maxyres > 32767) maxyres = 32767;
985
986 return maxyres;
987}
988
989static void
990sisfb_calc_pitch(struct sis_video_info *ivideo, struct fb_var_screeninfo *var)
991{
992 ivideo->video_linelength = var->xres_virtual * (var->bits_per_pixel >> 3);
993 ivideo->scrnpitchCRT1 = ivideo->video_linelength;
994 if(!(ivideo->currentvbflags & CRT1_LCDA)) {
995 if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
996 ivideo->scrnpitchCRT1 <<= 1;
997 }
998 }
999
1000}
1001
1002static void
1003sisfb_set_pitch(struct sis_video_info *ivideo)
1004{
1005 BOOLEAN isslavemode = FALSE;
1006 unsigned short HDisplay1 = ivideo->scrnpitchCRT1 >> 3;
1007 unsigned short HDisplay2 = ivideo->video_linelength >> 3;
1008
1009 if(sisfb_bridgeisslave(ivideo)) isslavemode = TRUE;
1010
1011 /* We need to set pitch for CRT1 if bridge is in slave mode, too */
1012 if((ivideo->currentvbflags & VB_DISPTYPE_DISP1) || (isslavemode)) {
1013 outSISIDXREG(SISCR,0x13,(HDisplay1 & 0xFF));
1014 setSISIDXREG(SISSR,0x0E,0xF0,(HDisplay1 >> 8));
1015 }
1016
1017 /* We must not set the pitch for CRT2 if bridge is in slave mode */
1018 if((ivideo->currentvbflags & VB_DISPTYPE_DISP2) && (!isslavemode)) {
1019 orSISIDXREG(SISPART1,ivideo->CRT2_write_enable,0x01);
1020 outSISIDXREG(SISPART1,0x07,(HDisplay2 & 0xFF));
1021 setSISIDXREG(SISPART1,0x09,0xF0,(HDisplay2 >> 8));
1022 }
1023}
1024
1025static void
1026sisfb_bpp_to_var(struct sis_video_info *ivideo, struct fb_var_screeninfo *var)
1027{
1028 ivideo->video_cmap_len = sisfb_get_cmap_len(var);
1029
1030 switch(var->bits_per_pixel) {
1031 case 8:
1032 var->red.offset = var->green.offset = var->blue.offset = 0;
1033 var->red.length = var->green.length = var->blue.length = 6;
1034 break;
1035 case 16:
1036 var->red.offset = 11;
1037 var->red.length = 5;
1038 var->green.offset = 5;
1039 var->green.length = 6;
1040 var->blue.offset = 0;
1041 var->blue.length = 5;
1042 var->transp.offset = 0;
1043 var->transp.length = 0;
1044 break;
1045 case 32:
1046 var->red.offset = 16;
1047 var->red.length = 8;
1048 var->green.offset = 8;
1049 var->green.length = 8;
1050 var->blue.offset = 0;
1051 var->blue.length = 8;
1052 var->transp.offset = 24;
1053 var->transp.length = 8;
1054 break;
1055 }
1056}
1057
1058static int
1059sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive, struct fb_info *info)
1060{
1061 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
1062 unsigned int htotal = 0, vtotal = 0;
1063 unsigned int drate = 0, hrate = 0;
1064 int found_mode = 0;
1065 int old_mode;
1066 u32 pixclock;
1067
1068 htotal = var->left_margin + var->xres + var->right_margin + var->hsync_len;
1069
1070 vtotal = var->upper_margin + var->lower_margin + var->vsync_len;
1071
1072 pixclock = var->pixclock;
1073
1074 if((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) {
1075 vtotal += var->yres;
1076 vtotal <<= 1;
1077 } else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
1078 vtotal += var->yres;
1079 vtotal <<= 2;
1080 } else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1081 vtotal += var->yres;
1082 vtotal <<= 1;
1083 } else vtotal += var->yres;
1084
1085 if(!(htotal) || !(vtotal)) {
1086 DPRINTK("sisfb: Invalid 'var' information\n");
1087 return -EINVAL;
1088 }
1089
1090 if(pixclock && htotal && vtotal) {
1091 drate = 1000000000 / pixclock;
1092 hrate = (drate * 1000) / htotal;
1093 ivideo->refresh_rate = (unsigned int) (hrate * 2 / vtotal);
1094 } else {
1095 ivideo->refresh_rate = 60;
1096 }
1097
1098 old_mode = ivideo->sisfb_mode_idx;
1099 ivideo->sisfb_mode_idx = 0;
1100
1101 while( (sisbios_mode[ivideo->sisfb_mode_idx].mode_no[0] != 0) &&
1102 (sisbios_mode[ivideo->sisfb_mode_idx].xres <= var->xres) ) {
1103 if( (sisbios_mode[ivideo->sisfb_mode_idx].xres == var->xres) &&
1104 (sisbios_mode[ivideo->sisfb_mode_idx].yres == var->yres) &&
1105 (sisbios_mode[ivideo->sisfb_mode_idx].bpp == var->bits_per_pixel)) {
1106 ivideo->mode_no = sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni];
1107 found_mode = 1;
1108 break;
1109 }
1110 ivideo->sisfb_mode_idx++;
1111 }
1112
1113 if(found_mode) {
1114 ivideo->sisfb_mode_idx = sisfb_validate_mode(ivideo,
1115 ivideo->sisfb_mode_idx, ivideo->currentvbflags);
1116 } else {
1117 ivideo->sisfb_mode_idx = -1;
1118 }
1119
1120 if(ivideo->sisfb_mode_idx < 0) {
1121 printk(KERN_ERR "sisfb: Mode %dx%dx%d not supported\n", var->xres,
1122 var->yres, var->bits_per_pixel);
1123 ivideo->sisfb_mode_idx = old_mode;
1124 return -EINVAL;
1125 }
1126
1127 if(sisfb_search_refresh_rate(ivideo, ivideo->refresh_rate, ivideo->sisfb_mode_idx) == 0) {
1128 ivideo->rate_idx = sisbios_mode[ivideo->sisfb_mode_idx].rate_idx;
1129 ivideo->refresh_rate = 60;
1130 }
1131
1132#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
1133 if(ivideo->sisfb_thismonitor.datavalid) {
1134 if(!sisfb_verify_rate(ivideo, &ivideo->sisfb_thismonitor, ivideo->sisfb_mode_idx,
1135 ivideo->rate_idx, ivideo->refresh_rate)) {
1136 printk(KERN_INFO "sisfb: WARNING: Refresh rate exceeds monitor specs!\n");
1137 }
1138 }
1139#endif
1140
1141#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
1142 if(((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) && isactive) {
1143#else
1144 if(isactive) {
1145#endif
1146 sisfb_pre_setmode(ivideo);
1147
1148 if(SiSSetMode(&ivideo->SiS_Pr, &ivideo->sishw_ext, ivideo->mode_no) == 0) {
1149 printk(KERN_ERR "sisfb: Setting mode[0x%x] failed\n", ivideo->mode_no);
1150 return -EINVAL;
1151 }
1152
1153 outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
1154
1155 sisfb_post_setmode(ivideo);
1156
1157 ivideo->video_bpp = sisbios_mode[ivideo->sisfb_mode_idx].bpp;
1158 ivideo->video_width = sisbios_mode[ivideo->sisfb_mode_idx].xres;
1159 ivideo->video_height = sisbios_mode[ivideo->sisfb_mode_idx].yres;
1160
1161 sisfb_calc_pitch(ivideo, var);
1162 sisfb_set_pitch(ivideo);
1163
1164 ivideo->accel = 0;
1165#if defined(FBINFO_HWACCEL_DISABLED) && defined(FBINFO_HWACCEL_XPAN)
1166#ifdef STUPID_ACCELF_TEXT_SHIT
1167 if(var->accel_flags & FB_ACCELF_TEXT) {
1168 info->flags &= ~FBINFO_HWACCEL_DISABLED;
1169 } else {
1170 info->flags |= FBINFO_HWACCEL_DISABLED;
1171 }
1172#endif
1173 if(!(info->flags & FBINFO_HWACCEL_DISABLED)) ivideo->accel = -1;
1174#else
1175 if(var->accel_flags & FB_ACCELF_TEXT) ivideo->accel = -1;
1176#endif
1177
1178 sisfb_set_vparms(ivideo);
1179
1180 ivideo->current_width = ivideo->video_width;
1181 ivideo->current_height = ivideo->video_height;
1182 ivideo->current_bpp = ivideo->video_bpp;
1183 ivideo->current_htotal = htotal;
1184 ivideo->current_vtotal = vtotal;
1185 ivideo->current_linelength = ivideo->video_linelength;
1186 ivideo->current_pixclock = var->pixclock;
1187 ivideo->current_refresh_rate = ivideo->refresh_rate;
1188#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
1189 ivideo->sisfb_lastrates[ivideo->mode_no] = ivideo->refresh_rate;
1190#endif
1191 }
1192
1193 return 0;
1194}
1195
1196static int
1197sisfb_pan_var(struct sis_video_info *ivideo, struct fb_var_screeninfo *var)
1198{
1199 unsigned int base;
1200
1201 if(var->xoffset > (var->xres_virtual - var->xres)) {
1202 return -EINVAL;
1203 }
1204 if(var->yoffset > (var->yres_virtual - var->yres)) {
1205 return -EINVAL;
1206 }
1207
1208 base = (var->yoffset * var->xres_virtual) + var->xoffset;
1209
1210 /* calculate base bpp dep. */
1211 switch(var->bits_per_pixel) {
1212 case 32:
1213 break;
1214 case 16:
1215 base >>= 1;
1216 break;
1217 case 8:
1218 default:
1219 base >>= 2;
1220 break;
1221 }
1222
1223 outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
1224
1225 outSISIDXREG(SISCR, 0x0D, base & 0xFF);
1226 outSISIDXREG(SISCR, 0x0C, (base >> 8) & 0xFF);
1227 outSISIDXREG(SISSR, 0x0D, (base >> 16) & 0xFF);
1228 if(ivideo->sisvga_engine == SIS_315_VGA) {
1229 setSISIDXREG(SISSR, 0x37, 0xFE, (base >> 24) & 0x01);
1230 }
1231 if(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {
1232 orSISIDXREG(SISPART1, ivideo->CRT2_write_enable, 0x01);
1233 outSISIDXREG(SISPART1, 0x06, (base & 0xFF));
1234 outSISIDXREG(SISPART1, 0x05, ((base >> 8) & 0xFF));
1235 outSISIDXREG(SISPART1, 0x04, ((base >> 16) & 0xFF));
1236 if(ivideo->sisvga_engine == SIS_315_VGA) {
1237 setSISIDXREG(SISPART1, 0x02, 0x7F, ((base >> 24) & 0x01) << 7);
1238 }
1239 }
1240 return 0;
1241}
1242
1243/* ------------ FBDev related routines for 2.4 series ----------- */
1244
1245#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
1246
1247static void
1248sisfb_crtc_to_var(struct sis_video_info *ivideo, struct fb_var_screeninfo *var)
1249{
1250 u16 VRE, VBE, VRS, VBS, VDE, VT;
1251 u16 HRE, HBE, HRS, HBS, HDE, HT;
1252 u8 sr_data, cr_data, cr_data2, cr_data3, mr_data;
1253 int A, B, C, D, E, F, temp;
1254 unsigned int hrate, drate, maxyres;
1255
1256 inSISIDXREG(SISSR, IND_SIS_COLOR_MODE, sr_data);
1257
1258 if(sr_data & SIS_INTERLACED_MODE)
1259 var->vmode = FB_VMODE_INTERLACED;
1260 else
1261 var->vmode = FB_VMODE_NONINTERLACED;
1262
1263 switch((sr_data & 0x1C) >> 2) {
1264 case SIS_8BPP_COLOR_MODE:
1265 var->bits_per_pixel = 8;
1266 break;
1267 case SIS_16BPP_COLOR_MODE:
1268 var->bits_per_pixel = 16;
1269 break;
1270 case SIS_32BPP_COLOR_MODE:
1271 var->bits_per_pixel = 32;
1272 break;
1273 }
1274
1275 sisfb_bpp_to_var(ivideo, var);
1276
1277 inSISIDXREG(SISSR, 0x0A, sr_data);
1278 inSISIDXREG(SISCR, 0x06, cr_data);
1279 inSISIDXREG(SISCR, 0x07, cr_data2);
1280
1281 VT = (cr_data & 0xFF) |
1282 ((u16) (cr_data2 & 0x01) << 8) |
1283 ((u16) (cr_data2 & 0x20) << 4) |
1284 ((u16) (sr_data & 0x01) << 10);
1285 A = VT + 2;
1286
1287 inSISIDXREG(SISCR, 0x12, cr_data);
1288
1289 VDE = (cr_data & 0xff) |
1290 ((u16) (cr_data2 & 0x02) << 7) |
1291 ((u16) (cr_data2 & 0x40) << 3) |
1292 ((u16) (sr_data & 0x02) << 9);
1293 E = VDE + 1;
1294
1295 inSISIDXREG(SISCR, 0x10, cr_data);
1296
1297 VRS = (cr_data & 0xff) |
1298 ((u16) (cr_data2 & 0x04) << 6) |
1299 ((u16) (cr_data2 & 0x80) << 2) |
1300 ((u16) (sr_data & 0x08) << 7);
1301 F = VRS + 1 - E;
1302
1303 inSISIDXREG(SISCR, 0x15, cr_data);
1304 inSISIDXREG(SISCR, 0x09, cr_data3);
1305
1306 if(cr_data3 & 0x80) var->vmode = FB_VMODE_DOUBLE;
1307
1308 VBS = (cr_data & 0xff) |
1309 ((u16) (cr_data2 & 0x08) << 5) |
1310 ((u16) (cr_data3 & 0x20) << 4) |
1311 ((u16) (sr_data & 0x04) << 8);
1312
1313 inSISIDXREG(SISCR, 0x16, cr_data);
1314
1315 VBE = (cr_data & 0xff) | ((u16) (sr_data & 0x10) << 4);
1316 temp = VBE - ((E - 1) & 511);
1317 B = (temp > 0) ? temp : (temp + 512);
1318
1319 inSISIDXREG(SISCR, 0x11, cr_data);
1320
1321 VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1);
1322 temp = VRE - ((E + F - 1) & 31);
1323 C = (temp > 0) ? temp : (temp + 32);
1324
1325 D = B - F - C;
1326
1327 var->yres = E;
1328 var->upper_margin = D;
1329 var->lower_margin = F;
1330 var->vsync_len = C;
1331
1332 if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1333 var->yres <<= 1;
1334 var->upper_margin <<= 1;
1335 var->lower_margin <<= 1;
1336 var->vsync_len <<= 1;
1337 } else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
1338 var->yres >>= 1;
1339 var->upper_margin >>= 1;
1340 var->lower_margin >>= 1;
1341 var->vsync_len >>= 1;
1342 }
1343
1344 inSISIDXREG(SISSR, 0x0b, sr_data);
1345 inSISIDXREG(SISCR, 0x00, cr_data);
1346
1347 HT = (cr_data & 0xff) | ((u16) (sr_data & 0x03) << 8);
1348 A = HT + 5;
1349
1350 inSISIDXREG(SISCR, 0x01, cr_data);
1351
1352 HDE = (cr_data & 0xff) | ((u16) (sr_data & 0x0C) << 6);
1353 E = HDE + 1;
1354
1355 inSISIDXREG(SISCR, 0x04, cr_data);
1356
1357 HRS = (cr_data & 0xff) | ((u16) (sr_data & 0xC0) << 2);
1358 F = HRS - E - 3;
1359
1360 inSISIDXREG(SISCR, 0x02, cr_data);
1361
1362 HBS = (cr_data & 0xff) | ((u16) (sr_data & 0x30) << 4);
1363
1364 inSISIDXREG(SISSR, 0x0c, sr_data);
1365 inSISIDXREG(SISCR, 0x03, cr_data);
1366 inSISIDXREG(SISCR, 0x05, cr_data2);
1367
1368 HBE = (cr_data & 0x1f) |
1369 ((u16) (cr_data2 & 0x80) >> 2) |
1370 ((u16) (sr_data & 0x03) << 6);
1371 HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3);
1372
1373 temp = HBE - ((E - 1) & 255);
1374 B = (temp > 0) ? temp : (temp + 256);
1375
1376 temp = HRE - ((E + F + 3) & 63);
1377 C = (temp > 0) ? temp : (temp + 64);
1378
1379 D = B - F - C;
1380
1381 var->xres = E * 8;
1382 if(var->xres_virtual < var->xres) {
1383 var->xres_virtual = var->xres;
1384 }
1385
1386 if((var->xres == 320) &&
1387 (var->yres == 200 || var->yres == 240)) {
1388 /* Terrible hack, but the correct CRTC data for
1389 * these modes only produces a black screen...
1390 */
1391 var->left_margin = (400 - 376);
1392 var->right_margin = (328 - 320);
1393 var->hsync_len = (376 - 328);
1394 } else {
1395 var->left_margin = D * 8;
1396 var->right_margin = F * 8;
1397 var->hsync_len = C * 8;
1398 }
1399 var->activate = FB_ACTIVATE_NOW;
1400
1401 var->sync = 0;
1402
1403 mr_data = inSISREG(SISMISCR);
1404 if(mr_data & 0x80)
1405 var->sync &= ~FB_SYNC_VERT_HIGH_ACT;
1406 else
1407 var->sync |= FB_SYNC_VERT_HIGH_ACT;
1408
1409 if(mr_data & 0x40)
1410 var->sync &= ~FB_SYNC_HOR_HIGH_ACT;
1411 else
1412 var->sync |= FB_SYNC_HOR_HIGH_ACT;
1413
1414 VT += 2;
1415 VT <<= 1;
1416 HT = (HT + 5) * 8;
1417
1418 if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1419 VT <<= 1;
1420 }
1421 hrate = ivideo->refresh_rate * VT / 2;
1422 drate = (hrate * HT) / 1000;
1423 var->pixclock = (u32) (1000000000 / drate);
1424
1425 if(ivideo->sisfb_ypan) {
1426 maxyres = sisfb_calc_maxyres(ivideo, var);
1427 if(ivideo->sisfb_max) {
1428 var->yres_virtual = maxyres;
1429 } else {
1430 if(var->yres_virtual > maxyres) {
1431 var->yres_virtual = maxyres;
1432 }
1433 }
1434 if(var->yres_virtual <= var->yres) {
1435 var->yres_virtual = var->yres;
1436 }
1437 } else {
1438 var->yres_virtual = var->yres;
1439 }
1440
1441}
1442
1443static int
1444sis_getcolreg(unsigned regno, unsigned *red, unsigned *green, unsigned *blue,
1445 unsigned *transp, struct fb_info *info)
1446{
1447 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
1448
1449 if(regno >= ivideo->video_cmap_len) return 1;
1450
1451 *red = ivideo->sis_palette[regno].red;
1452 *green = ivideo->sis_palette[regno].green;
1453 *blue = ivideo->sis_palette[regno].blue;
1454 *transp = 0;
1455
1456 return 0;
1457}
1458
1459static int
1460sisfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
1461 unsigned transp, struct fb_info *info)
1462{
1463 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
1464
1465 if(regno >= ivideo->video_cmap_len) return 1;
1466
1467 ivideo->sis_palette[regno].red = red;
1468 ivideo->sis_palette[regno].green = green;
1469 ivideo->sis_palette[regno].blue = blue;
1470
1471 switch(ivideo->video_bpp) {
1472#ifdef FBCON_HAS_CFB8
1473 case 8:
1474 outSISREG(SISDACA, regno);
1475 outSISREG(SISDACD, (red >> 10));
1476 outSISREG(SISDACD, (green >> 10));
1477 outSISREG(SISDACD, (blue >> 10));
1478 if(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {
1479 outSISREG(SISDAC2A, regno);
1480 outSISREG(SISDAC2D, (red >> 8));
1481 outSISREG(SISDAC2D, (green >> 8));
1482 outSISREG(SISDAC2D, (blue >> 8));
1483 }
1484 break;
1485#endif
1486#ifdef FBCON_HAS_CFB16
1487 case 16:
1488 ivideo->sis_fbcon_cmap.cfb16[regno] =
1489 ((red & 0xf800)) | ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11);
1490 break;
1491#endif
1492#ifdef FBCON_HAS_CFB32
1493 case 32:
1494 red >>= 8;
1495 green >>= 8;
1496 blue >>= 8;
1497 ivideo->sis_fbcon_cmap.cfb32[regno] = (red << 16) | (green << 8) | (blue);
1498 break;
1499#endif
1500 }
1501
1502 return 0;
1503}
1504
1505static void
1506sisfb_set_disp(int con, struct fb_var_screeninfo *var, struct fb_info *info)
1507{
1508 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
1509 struct display *display;
1510 struct display_switch *sw;
1511 struct fb_fix_screeninfo fix;
1512 long flags;
1513
1514 display = (con >= 0) ? &fb_display[con] : &ivideo->sis_disp;
1515
1516 sisfb_get_fix(&fix, con, info);
1517
1518 display->var = *var;
1519 display->screen_base = (char *)ivideo->video_vbase;
1520 display->visual = fix.visual;
1521 display->type = fix.type;
1522 display->type_aux = fix.type_aux;
1523 display->ypanstep = fix.ypanstep;
1524 display->ywrapstep = fix.ywrapstep;
1525 display->line_length = fix.line_length;
1526 display->can_soft_blank = 1;
1527 display->inverse = ivideo->sisfb_inverse;
1528 display->next_line = fix.line_length;
1529
1530 save_flags(flags);
1531
1532 switch(ivideo->video_bpp) {
1533#ifdef FBCON_HAS_CFB8
1534 case 8: sw = ivideo->accel ? &fbcon_sis8 : &fbcon_cfb8;
1535 break;
1536#endif
1537#ifdef FBCON_HAS_CFB16
1538 case 16:sw = ivideo->accel ? &fbcon_sis16 : &fbcon_cfb16;
1539 display->dispsw_data = &ivideo->sis_fbcon_cmap.cfb16;
1540 break;
1541#endif
1542#ifdef FBCON_HAS_CFB32
1543 case 32:sw = ivideo->accel ? &fbcon_sis32 : &fbcon_cfb32;
1544 display->dispsw_data = &ivideo->sis_fbcon_cmap.cfb32;
1545 break;
1546#endif
1547 default:sw = &fbcon_dummy;
1548 break;
1549 }
1550 memcpy(&ivideo->sisfb_sw, sw, sizeof(*sw));
1551 display->dispsw = &ivideo->sisfb_sw;
1552
1553 restore_flags(flags);
1554
1555 if(ivideo->sisfb_ypan) {
1556 /* display->scrollmode = 0; */
1557 } else {
1558 display->scrollmode = SCROLL_YREDRAW;
1559 ivideo->sisfb_sw.bmove = fbcon_redraw_bmove;
1560 }
1561}
1562
1563static void
1564sisfb_do_install_cmap(int con, struct fb_info *info)
1565{
1566 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
1567
1568 if(con != ivideo->currcon) return;
1569
1570 if(fb_display[con].cmap.len) {
1571 fb_set_cmap(&fb_display[con].cmap, 1, sisfb_setcolreg, info);
1572 } else {
1573 int size = sisfb_get_cmap_len(&fb_display[con].var);
1574 fb_set_cmap(fb_default_cmap(size), 1, sisfb_setcolreg, info);
1575 }
1576}
1577
1578static int
1579sisfb_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
1580{
1581 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
1582
1583 if(con == -1) {
1584 memcpy(var, &ivideo->default_var, sizeof(struct fb_var_screeninfo));
1585 } else {
1586 *var = fb_display[con].var;
1587 }
1588
1589 if(ivideo->sisfb_fstn) {
1590 if(var->xres == 320 && var->yres == 480) var->yres = 240;
1591 }
1592
1593 return 0;
1594}
1595
1596static int
1597sisfb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
1598{
1599 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
1600 int err;
1601
1602 fb_display[con].var.activate = FB_ACTIVATE_NOW;
1603
1604 if(sisfb_do_set_var(var, con == ivideo->currcon, info)) {
1605 sisfb_crtc_to_var(ivideo, var);
1606 return -EINVAL;
1607 }
1608
1609 sisfb_crtc_to_var(ivideo, var);
1610
1611 sisfb_set_disp(con, var, info);
1612
1613 if(info->changevar) {
1614 (*info->changevar)(con);
1615 }
1616
1617 if((err = fb_alloc_cmap(&fb_display[con].cmap, 0, 0))) {
1618 return err;
1619 }
1620
1621 sisfb_do_install_cmap(con, info);
1622
1623#if 0 /* Why was this called here? */
1624 unsigned int cols, rows;
1625 cols = sisbios_mode[ivideo->sisfb_mode_idx].cols;
1626 rows = sisbios_mode[ivideo->sisfb_mode_idx].rows;
1627 vc_resize_con(rows, cols, fb_display[con].conp->vc_num);
1628#endif
1629 return 0;
1630}
1631
1632static int
1633sisfb_get_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info)
1634{
1635 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
1636 struct display *display;
1637
1638 display = (con >= 0) ? &fb_display[con] : &ivideo->sis_disp;
1639
1640 if(con == ivideo->currcon) {
1641
1642 return fb_get_cmap(cmap, kspc, sis_getcolreg, info);
1643
1644 } else if(display->cmap.len) {
1645
1646 fb_copy_cmap(&display->cmap, cmap, kspc ? 0 : 2);
1647
1648 } else {
1649
1650 int size = sisfb_get_cmap_len(&display->var);
1651 fb_copy_cmap(fb_default_cmap(size), cmap, kspc ? 0 : 2);
1652
1653 }
1654
1655 return 0;
1656}
1657
1658static int
1659sisfb_set_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info)
1660{
1661 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
1662 struct display *display;
1663 int err, size;
1664
1665 display = (con >= 0) ? &fb_display[con] : &ivideo->sis_disp;
1666
1667 size = sisfb_get_cmap_len(&display->var);
1668 if(display->cmap.len != size) {
1669 err = fb_alloc_cmap(&display->cmap, size, 0);
1670 if(err) return err;
1671 }
1672
1673 if(con == ivideo->currcon) {
1674 return fb_set_cmap(cmap, kspc, sisfb_setcolreg, info);
1675 } else {
1676 fb_copy_cmap(cmap, &display->cmap, kspc ? 0 : 1);
1677 }
1678
1679 return 0;
1680}
1681
1682static int
1683sisfb_pan_display(struct fb_var_screeninfo *var, int con, struct fb_info* info)
1684{
1685 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
1686 int err;
1687
1688 if(var->vmode & FB_VMODE_YWRAP) return -EINVAL;
1689
1690 if((var->xoffset+fb_display[con].var.xres > fb_display[con].var.xres_virtual) ||
1691 (var->yoffset+fb_display[con].var.yres > fb_display[con].var.yres_virtual)) {
1692 return -EINVAL;
1693 }
1694
1695 if(con == ivideo->currcon) {
1696 if((err = sisfb_pan_var(ivideo, var)) < 0) return err;
1697 }
1698
1699 fb_display[con].var.xoffset = var->xoffset;
1700 fb_display[con].var.yoffset = var->yoffset;
1701
1702 return 0;
1703}
1704
1705static int
1706sisfb_update_var(int con, struct fb_info *info)
1707{
1708 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
1709
1710 return(sisfb_pan_var(ivideo, &fb_display[con].var));
1711}
1712
1713static int
1714sisfb_switch(int con, struct fb_info *info)
1715{
1716 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
1717 int cols, rows;
1718
1719 if(fb_display[ivideo->currcon].cmap.len) {
1720 fb_get_cmap(&fb_display[ivideo->currcon].cmap, 1, sis_getcolreg, info);
1721 }
1722
1723 fb_display[con].var.activate = FB_ACTIVATE_NOW;
1724
1725 if(!memcmp(&fb_display[con].var, &fb_display[ivideo->currcon].var,
1726 sizeof(struct fb_var_screeninfo))) {
1727 ivideo->currcon = con;
1728 return 1;
1729 }
1730
1731 ivideo->currcon = con;
1732
1733 sisfb_do_set_var(&fb_display[con].var, 1, info);
1734
1735 sisfb_set_disp(con, &fb_display[con].var, info);
1736
1737 sisfb_do_install_cmap(con, info);
1738
1739 cols = sisbios_mode[ivideo->sisfb_mode_idx].cols;
1740 rows = sisbios_mode[ivideo->sisfb_mode_idx].rows;
1741 vc_resize_con(rows, cols, fb_display[con].conp->vc_num);
1742
1743 sisfb_update_var(con, info);
1744
1745 return 1;
1746}
1747
1748static void
1749sisfb_blank(int blank, struct fb_info *info)
1750{
1751 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
1752
1753 sisfb_myblank(ivideo, blank);
1754}
1755#endif
1756
1757/* ------------ FBDev related routines for 2.6 series ----------- */
1758
1759#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
1760
1761static int
1762sisfb_open(struct fb_info *info, int user)
1763{
1764 return 0;
1765}
1766
1767static int
1768sisfb_release(struct fb_info *info, int user)
1769{
1770 return 0;
1771}
1772
1773static int
1774sisfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
1775 unsigned transp, struct fb_info *info)
1776{
1777 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
1778
1779 if(regno >= sisfb_get_cmap_len(&info->var)) return 1;
1780
1781 switch(info->var.bits_per_pixel) {
1782 case 8:
1783 outSISREG(SISDACA, regno);
1784 outSISREG(SISDACD, (red >> 10));
1785 outSISREG(SISDACD, (green >> 10));
1786 outSISREG(SISDACD, (blue >> 10));
1787 if(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {
1788 outSISREG(SISDAC2A, regno);
1789 outSISREG(SISDAC2D, (red >> 8));
1790 outSISREG(SISDAC2D, (green >> 8));
1791 outSISREG(SISDAC2D, (blue >> 8));
1792 }
1793 break;
1794 case 16:
1795 ((u32 *)(info->pseudo_palette))[regno] =
1796 ((red & 0xf800)) | ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11);
1797 break;
1798 case 32:
1799 red >>= 8;
1800 green >>= 8;
1801 blue >>= 8;
1802 ((u32 *)(info->pseudo_palette))[regno] =
1803 (red << 16) | (green << 8) | (blue);
1804 break;
1805 }
1806 return 0;
1807}
1808
1809static int
1810sisfb_set_par(struct fb_info *info)
1811{
1812 int err;
1813
1814 if((err = sisfb_do_set_var(&info->var, 1, info))) {
1815 return err;
1816 }
1817#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
1818 sisfb_get_fix(&info->fix, info->currcon, info);
1819#else
1820 sisfb_get_fix(&info->fix, -1, info);
1821#endif
1822 return 0;
1823}
1824
1825static int
1826sisfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
1827{
1828 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
1829 unsigned int htotal = 0, vtotal = 0, myrateindex = 0;
1830 unsigned int drate = 0, hrate = 0, maxyres;
1831 int found_mode = 0;
1832 int refresh_rate, search_idx;
1833 BOOLEAN recalc_clock = FALSE;
1834 u32 pixclock;
1835
1836 htotal = var->left_margin + var->xres + var->right_margin + var->hsync_len;
1837
1838 vtotal = var->upper_margin + var->lower_margin + var->vsync_len;
1839
1840 pixclock = var->pixclock;
1841
1842 if((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) {
1843 vtotal += var->yres;
1844 vtotal <<= 1;
1845 } else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
1846 vtotal += var->yres;
1847 vtotal <<= 2;
1848 } else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1849 vtotal += var->yres;
1850 vtotal <<= 1;
1851 } else vtotal += var->yres;
1852
1853 if(!(htotal) || !(vtotal)) {
1854 SISFAIL("sisfb: no valid timing data");
1855 }
1856
1857 search_idx = 0;
1858 while( (sisbios_mode[search_idx].mode_no[0] != 0) &&
1859 (sisbios_mode[search_idx].xres <= var->xres) ) {
1860 if( (sisbios_mode[search_idx].xres == var->xres) &&
1861 (sisbios_mode[search_idx].yres == var->yres) &&
1862 (sisbios_mode[search_idx].bpp == var->bits_per_pixel)) {
1863 if(sisfb_validate_mode(ivideo, search_idx, ivideo->currentvbflags) > 0) {
1864 found_mode = 1;
1865 break;
1866 }
1867 }
1868 search_idx++;
1869 }
1870
1871 if(!found_mode) {
1872 search_idx = 0;
1873 while(sisbios_mode[search_idx].mode_no[0] != 0) {
1874 if( (var->xres <= sisbios_mode[search_idx].xres) &&
1875 (var->yres <= sisbios_mode[search_idx].yres) &&
1876 (var->bits_per_pixel == sisbios_mode[search_idx].bpp) ) {
1877 if(sisfb_validate_mode(ivideo,search_idx, ivideo->currentvbflags) > 0) {
1878 found_mode = 1;
1879 break;
1880 }
1881 }
1882 search_idx++;
1883 }
1884 if(found_mode) {
1885 printk(KERN_DEBUG "sisfb: Adapted from %dx%dx%d to %dx%dx%d\n",
1886 var->xres, var->yres, var->bits_per_pixel,
1887 sisbios_mode[search_idx].xres,
1888 sisbios_mode[search_idx].yres,
1889 var->bits_per_pixel);
1890 var->xres = sisbios_mode[search_idx].xres;
1891 var->yres = sisbios_mode[search_idx].yres;
1892
1893
1894 } else {
1895 printk(KERN_ERR "sisfb: Failed to find supported mode near %dx%dx%d\n",
1896 var->xres, var->yres, var->bits_per_pixel);
1897 return -EINVAL;
1898 }
1899 }
1900
1901 if( ((ivideo->vbflags & VB_LVDS) || /* Slave modes on LVDS and 301B-DH */
1902 ((ivideo->vbflags & VB_30xBDH) && (ivideo->currentvbflags & CRT2_LCD))) &&
1903 (var->bits_per_pixel == 8) ) {
1904 refresh_rate = 60;
1905 recalc_clock = TRUE;
1906 } else if( (ivideo->current_htotal == htotal) && /* x=x & y=y & c=c -> assume depth change */
1907 (ivideo->current_vtotal == vtotal) &&
1908 (ivideo->current_pixclock == pixclock) ) {
1909 drate = 1000000000 / pixclock;
1910 hrate = (drate * 1000) / htotal;
1911 refresh_rate = (unsigned int) (hrate * 2 / vtotal);
1912 } else if( ( (ivideo->current_htotal != htotal) || /* x!=x | y!=y & c=c -> invalid pixclock */
1913 (ivideo->current_vtotal != vtotal) ) &&
1914 (ivideo->current_pixclock == var->pixclock) ) {
1915 if(ivideo->sisfb_lastrates[sisbios_mode[search_idx].mode_no[ivideo->mni]]) {
1916 refresh_rate = ivideo->sisfb_lastrates[sisbios_mode[search_idx].mode_no[ivideo->mni]];
1917 } else if(ivideo->sisfb_parm_rate != -1) {
1918 /* Sic, sisfb_parm_rate - want to know originally desired rate here */
1919 refresh_rate = ivideo->sisfb_parm_rate;
1920 } else {
1921 refresh_rate = 60;
1922 }
1923 recalc_clock = TRUE;
1924 } else if((pixclock) && (htotal) && (vtotal)) {
1925 drate = 1000000000 / pixclock;
1926 hrate = (drate * 1000) / htotal;
1927 refresh_rate = (unsigned int) (hrate * 2 / vtotal);
1928 } else if(ivideo->current_refresh_rate) {
1929 refresh_rate = ivideo->current_refresh_rate;
1930 recalc_clock = TRUE;
1931 } else {
1932 refresh_rate = 60;
1933 recalc_clock = TRUE;
1934 }
1935
1936 myrateindex = sisfb_search_refresh_rate(ivideo, refresh_rate, search_idx);
1937
1938 /* Eventually recalculate timing and clock */
1939 if(recalc_clock) {
1940 if(!myrateindex) myrateindex = sisbios_mode[search_idx].rate_idx;
1941 var->pixclock = (u32) (1000000000 / sisfb_mode_rate_to_dclock(&ivideo->SiS_Pr,
1942 &ivideo->sishw_ext,
1943 sisbios_mode[search_idx].mode_no[ivideo->mni],
1944 myrateindex));
1945 sisfb_mode_rate_to_ddata(&ivideo->SiS_Pr, &ivideo->sishw_ext,
1946 sisbios_mode[search_idx].mode_no[ivideo->mni], myrateindex, var);
1947 if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
1948 var->pixclock <<= 1;
1949 }
1950 }
1951
1952 if(ivideo->sisfb_thismonitor.datavalid) {
1953 if(!sisfb_verify_rate(ivideo, &ivideo->sisfb_thismonitor, search_idx,
1954 myrateindex, refresh_rate)) {
1955 printk(KERN_INFO "sisfb: WARNING: Refresh rate exceeds monitor specs!\n");
1956 }
1957 }
1958
1959 /* Adapt RGB settings */
1960 sisfb_bpp_to_var(ivideo, var);
1961
1962 /* Sanity check for offsets */
1963 if(var->xoffset < 0) var->xoffset = 0;
1964 if(var->yoffset < 0) var->yoffset = 0;
1965
1966 if(var->xres > var->xres_virtual) {
1967 var->xres_virtual = var->xres;
1968 }
1969
1970 if(ivideo->sisfb_ypan) {
1971 maxyres = sisfb_calc_maxyres(ivideo, var);
1972 if(ivideo->sisfb_max) {
1973 var->yres_virtual = maxyres;
1974 } else {
1975 if(var->yres_virtual > maxyres) {
1976 var->yres_virtual = maxyres;
1977 }
1978 }
1979 if(var->yres_virtual <= var->yres) {
1980 var->yres_virtual = var->yres;
1981 }
1982 } else {
1983 if(var->yres != var->yres_virtual) {
1984 var->yres_virtual = var->yres;
1985 }
1986 var->xoffset = 0;
1987 var->yoffset = 0;
1988 }
1989
1990 /* Truncate offsets to maximum if too high */
1991 if(var->xoffset > var->xres_virtual - var->xres) {
1992 var->xoffset = var->xres_virtual - var->xres - 1;
1993 }
1994
1995 if(var->yoffset > var->yres_virtual - var->yres) {
1996 var->yoffset = var->yres_virtual - var->yres - 1;
1997 }
1998
1999 /* Set everything else to 0 */
2000 var->red.msb_right =
2001 var->green.msb_right =
2002 var->blue.msb_right =
2003 var->transp.offset =
2004 var->transp.length =
2005 var->transp.msb_right = 0;
2006
2007 return 0;
2008}
2009
2010static int
2011sisfb_pan_display(struct fb_var_screeninfo *var, struct fb_info* info)
2012{
2013 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
2014 int err;
2015
2016 if(var->xoffset > (var->xres_virtual - var->xres)) {
2017 return -EINVAL;
2018 }
2019 if(var->yoffset > (var->yres_virtual - var->yres)) {
2020 return -EINVAL;
2021 }
2022
2023 if(var->vmode & FB_VMODE_YWRAP) return -EINVAL;
2024
2025 if(var->xoffset + info->var.xres > info->var.xres_virtual ||
2026 var->yoffset + info->var.yres > info->var.yres_virtual) {
2027 return -EINVAL;
2028 }
2029
2030 if((err = sisfb_pan_var(ivideo, var)) < 0) return err;
2031
2032 info->var.xoffset = var->xoffset;
2033 info->var.yoffset = var->yoffset;
2034
2035 return 0;
2036}
2037
2038static int
2039sisfb_blank(int blank, struct fb_info *info)
2040{
2041 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
2042
2043 return(sisfb_myblank(ivideo, blank));
2044}
2045
2046#endif
2047
2048/* ----------- FBDev related routines for all series ---------- */
2049
2050static int
2051sisfb_ioctl(struct inode *inode, struct file *file,
2052 unsigned int cmd, unsigned long arg,
2053#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
2054 int con,
2055#endif
2056 struct fb_info *info)
2057{
2058 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
2059 struct sis_memreq sismemreq;
2060 struct fb_vblank sisvbblank;
2061 sisfb_info x;
2062 u32 gpu32 = 0;
2063#ifndef __user
2064#define __user
2065#endif
2066 u32 __user *argp = (u32 __user *)arg;
2067
2068 switch (cmd) {
2069 case FBIO_ALLOC:
2070 if(!capable(CAP_SYS_RAWIO)) {
2071 return -EPERM;
2072 }
2073 if(copy_from_user(&sismemreq, (void __user *)arg, sizeof(sismemreq))) {
2074 return -EFAULT;
2075 }
2076 sis_malloc(&sismemreq);
2077 if(copy_to_user((void __user *)arg, &sismemreq, sizeof(sismemreq))) {
2078 sis_free((u32)sismemreq.offset);
2079 return -EFAULT;
2080 }
2081 break;
2082
2083 case FBIO_FREE:
2084 if(!capable(CAP_SYS_RAWIO)) {
2085 return -EPERM;
2086 }
2087 if(get_user(gpu32, argp)) {
2088 return -EFAULT;
2089 }
2090 sis_free(gpu32);
2091 break;
2092
2093 case FBIOGET_VBLANK:
2094 sisvbblank.count = 0;
2095 sisvbblank.flags = sisfb_setupvbblankflags(ivideo, &sisvbblank.vcount, &sisvbblank.hcount);
2096 if(copy_to_user((void __user *)arg, &sisvbblank, sizeof(sisvbblank))) {
2097 return -EFAULT;
2098 }
2099 break;
2100
2101 case SISFB_GET_INFO_SIZE:
2102 return put_user(sizeof(sisfb_info), argp);
2103
2104 case SISFB_GET_INFO_OLD:
2105 if(ivideo->warncount++ < 50) {
2106 printk(KERN_INFO "sisfb: Deprecated ioctl call received - update your application!\n");
2107 }
2108 case SISFB_GET_INFO: /* For communication with X driver */
2109 x.sisfb_id = SISFB_ID;
2110 x.sisfb_version = VER_MAJOR;
2111 x.sisfb_revision = VER_MINOR;
2112 x.sisfb_patchlevel = VER_LEVEL;
2113 x.chip_id = ivideo->chip_id;
2114 x.memory = ivideo->video_size / 1024;
2115 x.heapstart = ivideo->heapstart / 1024;
2116 if(ivideo->modechanged) {
2117 x.fbvidmode = ivideo->mode_no;
2118 } else {
2119 x.fbvidmode = ivideo->modeprechange;
2120 }
2121 x.sisfb_caps = ivideo->caps;
2122 x.sisfb_tqlen = 512; /* yet fixed */
2123 x.sisfb_pcibus = ivideo->pcibus;
2124 x.sisfb_pcislot = ivideo->pcislot;
2125 x.sisfb_pcifunc = ivideo->pcifunc;
2126 x.sisfb_lcdpdc = ivideo->detectedpdc;
2127 x.sisfb_lcdpdca = ivideo->detectedpdca;
2128 x.sisfb_lcda = ivideo->detectedlcda;
2129 x.sisfb_vbflags = ivideo->vbflags;
2130 x.sisfb_currentvbflags = ivideo->currentvbflags;
2131 x.sisfb_scalelcd = ivideo->SiS_Pr.UsePanelScaler;
2132 x.sisfb_specialtiming = ivideo->SiS_Pr.SiS_CustomT;
2133 x.sisfb_haveemi = ivideo->SiS_Pr.HaveEMI ? 1 : 0;
2134 x.sisfb_haveemilcd = ivideo->SiS_Pr.HaveEMILCD ? 1 : 0;
2135 x.sisfb_emi30 = ivideo->SiS_Pr.EMI_30;
2136 x.sisfb_emi31 = ivideo->SiS_Pr.EMI_31;
2137 x.sisfb_emi32 = ivideo->SiS_Pr.EMI_32;
2138 x.sisfb_emi33 = ivideo->SiS_Pr.EMI_33;
2139 x.sisfb_tvxpos = (u16)(ivideo->tvxpos + 32);
2140 x.sisfb_tvypos = (u16)(ivideo->tvypos + 32);
2141
2142 if(copy_to_user((void __user *)arg, &x, sizeof(x))) {
2143 return -EFAULT;
2144 }
2145 break;
2146
2147 case SISFB_GET_VBRSTATUS_OLD:
2148 if(ivideo->warncount++ < 50) {
2149 printk(KERN_INFO "sisfb: Deprecated ioctl call received - update your application!\n");
2150 }
2151 case SISFB_GET_VBRSTATUS:
2152 if(sisfb_CheckVBRetrace(ivideo)) {
2153 return put_user((u32)1, argp);
2154 } else {
2155 return put_user((u32)0, argp);
2156 }
2157
2158 case SISFB_GET_AUTOMAXIMIZE_OLD:
2159 if(ivideo->warncount++ < 50) {
2160 printk(KERN_INFO "sisfb: Deprecated ioctl call received - update your application!\n");
2161 }
2162 case SISFB_GET_AUTOMAXIMIZE:
2163 if(ivideo->sisfb_max) return put_user((u32)1, argp);
2164 else return put_user((u32)0, argp);
2165
2166 case SISFB_SET_AUTOMAXIMIZE_OLD:
2167 if(ivideo->warncount++ < 50) {
2168 printk(KERN_INFO "sisfb: Deprecated ioctl call received - update your application!\n");
2169 }
2170 case SISFB_SET_AUTOMAXIMIZE:
2171 if(copy_from_user(&gpu32, argp, sizeof(gpu32))) {
2172 return -EFAULT;
2173 }
2174 ivideo->sisfb_max = (gpu32) ? 1 : 0;
2175 break;
2176
2177 case SISFB_SET_TVPOSOFFSET:
2178 if(copy_from_user(&gpu32, argp, sizeof(gpu32))) {
2179 return -EFAULT;
2180 }
2181 sisfb_set_TVxposoffset(ivideo, ((int)(gpu32 >> 16)) - 32);
2182 sisfb_set_TVyposoffset(ivideo, ((int)(gpu32 & 0xffff)) - 32);
2183 break;
2184
2185 case SISFB_GET_TVPOSOFFSET:
2186 return put_user((u32)(((ivideo->tvxpos+32)<<16)|((ivideo->tvypos+32)&0xffff)),
2187 argp);
2188
2189 case SISFB_SET_LOCK:
2190 if(copy_from_user(&gpu32, argp, sizeof(gpu32))) {
2191 return -EFAULT;
2192 }
2193 ivideo->sisfblocked = (gpu32) ? 1 : 0;
2194 break;
2195
2196 default:
2197 return -ENOIOCTLCMD;
2198 }
2199 return 0;
2200}
2201
2202#ifdef CONFIG_COMPAT
2203static long sisfb_compat_ioctl(struct file *f, unsigned cmd, unsigned long arg, struct fb_info *info)
2204{
2205 int ret;
2206 lock_kernel();
2207 ret = sisfb_ioctl(NULL, f, cmd, arg, info);
2208 unlock_kernel();
2209 return ret;
2210}
2211#endif
2212
2213static int
2214sisfb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info)
2215{
2216 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
2217
2218 memset(fix, 0, sizeof(struct fb_fix_screeninfo));
2219
2220 strcpy(fix->id, ivideo->myid);
2221
2222 fix->smem_start = ivideo->video_base;
2223 fix->smem_len = ivideo->sisfb_mem;
2224 fix->type = FB_TYPE_PACKED_PIXELS;
2225 fix->type_aux = 0;
2226 fix->visual = (ivideo->video_bpp == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
2227 fix->xpanstep = 1;
2228 fix->ypanstep = (ivideo->sisfb_ypan) ? 1 : 0;
2229 fix->ywrapstep = 0;
2230 fix->line_length = ivideo->video_linelength;
2231 fix->mmio_start = ivideo->mmio_base;
2232 fix->mmio_len = ivideo->mmio_size;
2233 if(ivideo->sisvga_engine == SIS_300_VGA) {
2234 fix->accel = FB_ACCEL_SIS_GLAMOUR;
2235 } else if((ivideo->chip == SIS_330) || (ivideo->chip == SIS_760)) {
2236 fix->accel = FB_ACCEL_SIS_XABRE;
2237 } else {
2238 fix->accel = FB_ACCEL_SIS_GLAMOUR_2;
2239 }
2240
2241 return 0;
2242}
2243
2244/* ---------------- fb_ops structures ----------------- */
2245
2246#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
2247static struct fb_ops sisfb_ops = {
2248 .owner = THIS_MODULE,
2249 .fb_get_fix = sisfb_get_fix,
2250 .fb_get_var = sisfb_get_var,
2251 .fb_set_var = sisfb_set_var,
2252 .fb_get_cmap = sisfb_get_cmap,
2253 .fb_set_cmap = sisfb_set_cmap,
2254 .fb_pan_display = sisfb_pan_display,
2255 .fb_ioctl = sisfb_ioctl
2256};
2257#endif
2258
2259#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
2260static struct fb_ops sisfb_ops = {
2261 .owner = THIS_MODULE,
2262 .fb_open = sisfb_open,
2263 .fb_release = sisfb_release,
2264 .fb_check_var = sisfb_check_var,
2265 .fb_set_par = sisfb_set_par,
2266 .fb_setcolreg = sisfb_setcolreg,
2267 .fb_pan_display = sisfb_pan_display,
2268 .fb_blank = sisfb_blank,
2269 .fb_fillrect = fbcon_sis_fillrect,
2270 .fb_copyarea = fbcon_sis_copyarea,
2271 .fb_imageblit = cfb_imageblit,
2272 .fb_cursor = soft_cursor,
2273 .fb_sync = fbcon_sis_sync,
2274 .fb_ioctl = sisfb_ioctl,
2275#ifdef CONFIG_COMPAT
2276 .fb_compat_ioctl = sisfb_compat_ioctl,
2277#endif
2278};
2279#endif
2280
2281/* ---------------- Chip generation dependent routines ---------------- */
2282
2283static struct pci_dev * sisfb_get_northbridge(int basechipid)
2284{
2285 struct pci_dev *pdev = NULL;
2286 int nbridgenum, nbridgeidx, i;
2287 const unsigned short nbridgeids[] = {
2288 PCI_DEVICE_ID_SI_540, /* for SiS 540 VGA */
2289 PCI_DEVICE_ID_SI_630, /* for SiS 630/730 VGA */
2290 PCI_DEVICE_ID_SI_730,
2291 PCI_DEVICE_ID_SI_550, /* for SiS 550 VGA */
2292 PCI_DEVICE_ID_SI_650, /* for SiS 650/651/740 VGA */
2293 PCI_DEVICE_ID_SI_651,
2294 PCI_DEVICE_ID_SI_740,
2295 PCI_DEVICE_ID_SI_661, /* for SiS 661/741/660/760 VGA */
2296 PCI_DEVICE_ID_SI_741,
2297 PCI_DEVICE_ID_SI_660,
2298 PCI_DEVICE_ID_SI_760
2299 };
2300
2301 switch(basechipid) {
2302#ifdef CONFIG_FB_SIS_300
2303 case SIS_540: nbridgeidx = 0; nbridgenum = 1; break;
2304 case SIS_630: nbridgeidx = 1; nbridgenum = 2; break;
2305#endif
2306#ifdef CONFIG_FB_SIS_315
2307 case SIS_550: nbridgeidx = 3; nbridgenum = 1; break;
2308 case SIS_650: nbridgeidx = 4; nbridgenum = 3; break;
2309 case SIS_660: nbridgeidx = 7; nbridgenum = 4; break;
2310#endif
2311 default: return NULL;
2312 }
2313 for(i = 0; i < nbridgenum; i++) {
2314 if((pdev = pci_find_device(PCI_VENDOR_ID_SI, nbridgeids[nbridgeidx+i], NULL))) break;
2315 }
2316 return pdev;
2317}
2318
2319static int __devinit sisfb_get_dram_size(struct sis_video_info *ivideo)
2320{
2321#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
2322 u8 reg;
2323#endif
2324
2325 ivideo->video_size = 0;
2326
2327 switch(ivideo->chip) {
2328#ifdef CONFIG_FB_SIS_300
2329 case SIS_300:
2330 inSISIDXREG(SISSR, 0x14, reg);
2331 ivideo->video_size = ((reg & 0x3F) + 1) << 20;
2332 break;
2333 case SIS_540:
2334 case SIS_630:
2335 case SIS_730:
2336 if(!ivideo->nbridge) return -1;
2337 pci_read_config_byte(ivideo->nbridge, 0x63, &reg);
2338 ivideo->video_size = 1 << (((reg & 0x70) >> 4) + 21);
2339 break;
2340#endif
2341#ifdef CONFIG_FB_SIS_315
2342 case SIS_315H:
2343 case SIS_315PRO:
2344 case SIS_315:
2345 inSISIDXREG(SISSR, 0x14, reg);
2346 ivideo->video_size = (1 << ((reg & 0xf0) >> 4)) << 20;
2347 switch((reg >> 2) & 0x03) {
2348 case 0x01:
2349 case 0x03:
2350 ivideo->video_size <<= 1;
2351 break;
2352 case 0x02:
2353 ivideo->video_size += (ivideo->video_size/2);
2354 }
2355 break;
2356 case SIS_330:
2357 inSISIDXREG(SISSR, 0x14, reg);
2358 ivideo->video_size = (1 << ((reg & 0xf0) >> 4)) << 20;
2359 if(reg & 0x0c) ivideo->video_size <<= 1;
2360 break;
2361 case SIS_550:
2362 case SIS_650:
2363 case SIS_740:
2364 inSISIDXREG(SISSR, 0x14, reg);
2365 ivideo->video_size = (((reg & 0x3f) + 1) << 2) << 20;
2366 break;
2367 case SIS_661:
2368 case SIS_741:
2369 inSISIDXREG(SISCR, 0x79, reg);
2370 ivideo->video_size = (1 << ((reg & 0xf0) >> 4)) << 20;
2371 break;
2372 case SIS_660:
2373 case SIS_760:
2374 inSISIDXREG(SISCR, 0x79, reg);
2375 reg = (reg & 0xf0) >> 4;
2376 if(reg) ivideo->video_size = (1 << reg) << 20;
2377 inSISIDXREG(SISCR, 0x78, reg);
2378 reg &= 0x30;
2379 if(reg) {
2380 if(reg == 0x10) ivideo->video_size += (32 << 20);
2381 else ivideo->video_size += (64 << 20);
2382 }
2383 break;
2384#endif
2385 default:
2386 return -1;
2387 }
2388 return 0;
2389}
2390
2391/* -------------- video bridge device detection --------------- */
2392
2393static void __devinit sisfb_detect_VB_connect(struct sis_video_info *ivideo)
2394{
2395 u8 cr32, temp;
2396
2397#ifdef CONFIG_FB_SIS_300
2398 if(ivideo->sisvga_engine == SIS_300_VGA) {
2399 inSISIDXREG(SISSR, 0x17, temp);
2400 if((temp & 0x0F) && (ivideo->chip != SIS_300)) {
2401 /* PAL/NTSC is stored on SR16 on such machines */
2402 if(!(ivideo->vbflags & (TV_PAL | TV_NTSC | TV_PALM | TV_PALN))) {
2403 inSISIDXREG(SISSR, 0x16, temp);
2404 if(temp & 0x20)
2405 ivideo->vbflags |= TV_PAL;
2406 else
2407 ivideo->vbflags |= TV_NTSC;
2408 }
2409 }
2410 }
2411#endif
2412
2413 inSISIDXREG(SISCR, 0x32, cr32);
2414
2415 if(cr32 & SIS_CRT1) {
2416 ivideo->sisfb_crt1off = 0;
2417 } else {
2418 ivideo->sisfb_crt1off = (cr32 & 0xDF) ? 1 : 0;
2419 }
2420
2421 ivideo->vbflags &= ~(CRT2_TV | CRT2_LCD | CRT2_VGA);
2422
2423 if(cr32 & SIS_VB_TV) ivideo->vbflags |= CRT2_TV;
2424 if(cr32 & SIS_VB_LCD) ivideo->vbflags |= CRT2_LCD;
2425 if(cr32 & SIS_VB_CRT2) ivideo->vbflags |= CRT2_VGA;
2426
2427 /* Check given parms for hardware compatibility.
2428 * (Cannot do this in the search_xx routines since we don't
2429 * know what hardware we are running on then)
2430 */
2431
2432 if(ivideo->chip != SIS_550) {
2433 ivideo->sisfb_dstn = ivideo->sisfb_fstn = 0;
2434 }
2435
2436 if(ivideo->sisfb_tvplug != -1) {
2437 if( (ivideo->sisvga_engine != SIS_315_VGA) ||
2438 (!(ivideo->vbflags & (VB_301C|VB_301LV|VB_302LV))) ) {
2439 if(ivideo->sisfb_tvplug & TV_YPBPR) {
2440 ivideo->sisfb_tvplug = -1;
2441 printk(KERN_ERR "sisfb: YPbPr not supported\n");
2442 }
2443 }
2444 }
2445 if(ivideo->sisfb_tvplug != -1) {
2446 if( (ivideo->sisvga_engine != SIS_315_VGA) ||
2447 (!(ivideo->vbflags & (VB_301|VB_301B|VB_302B))) ) {
2448 if(ivideo->sisfb_tvplug & TV_HIVISION) {
2449 ivideo->sisfb_tvplug = -1;
2450 printk(KERN_ERR "sisfb: HiVision not supported\n");
2451 }
2452 }
2453 }
2454 if(ivideo->sisfb_tvstd != -1) {
2455 if( (!(ivideo->vbflags & VB_SISBRIDGE)) &&
2456 (!((ivideo->sisvga_engine == SIS_315_VGA) && (ivideo->vbflags & VB_CHRONTEL))) ) {
2457 if(ivideo->sisfb_tvstd & (TV_PALN | TV_PALN | TV_NTSCJ)) {
2458 ivideo->sisfb_tvstd = -1;
2459 printk(KERN_ERR "sisfb: PALM/PALN/NTSCJ not supported\n");
2460 }
2461 }
2462 }
2463
2464 /* Detect/set TV plug & type */
2465 if(ivideo->sisfb_tvplug != -1) {
2466 ivideo->vbflags |= ivideo->sisfb_tvplug;
2467 } else {
2468 if(cr32 & SIS_VB_YPBPR) ivideo->vbflags |= (TV_YPBPR|TV_YPBPR525I); /* default: 480i */
2469 else if(cr32 & SIS_VB_HIVISION) ivideo->vbflags |= TV_HIVISION;
2470 else if(cr32 & SIS_VB_SCART) ivideo->vbflags |= TV_SCART;
2471 else {
2472 if(cr32 & SIS_VB_SVIDEO) ivideo->vbflags |= TV_SVIDEO;
2473 if(cr32 & SIS_VB_COMPOSITE) ivideo->vbflags |= TV_AVIDEO;
2474 }
2475 }
2476
2477 if(!(ivideo->vbflags & (TV_YPBPR | TV_HIVISION))) {
2478 if(ivideo->sisfb_tvstd != -1) {
2479 ivideo->vbflags &= ~(TV_NTSC | TV_PAL | TV_PALM | TV_PALN | TV_NTSCJ);
2480 ivideo->vbflags |= ivideo->sisfb_tvstd;
2481 }
2482 if(ivideo->vbflags & TV_SCART) {
2483 ivideo->vbflags &= ~(TV_NTSC | TV_PALM | TV_PALN | TV_NTSCJ);
2484 ivideo->vbflags |= TV_PAL;
2485 }
2486 if(!(ivideo->vbflags & (TV_PAL | TV_NTSC | TV_PALM | TV_PALN | TV_NTSCJ))) {
2487 if(ivideo->sisvga_engine == SIS_300_VGA) {
2488 inSISIDXREG(SISSR, 0x38, temp);
2489 if(temp & 0x01) ivideo->vbflags |= TV_PAL;
2490 else ivideo->vbflags |= TV_NTSC;
2491 } else if((ivideo->chip <= SIS_315PRO) || (ivideo->chip >= SIS_330)) {
2492 inSISIDXREG(SISSR, 0x38, temp);
2493 if(temp & 0x01) ivideo->vbflags |= TV_PAL;
2494 else ivideo->vbflags |= TV_NTSC;
2495 } else {
2496 inSISIDXREG(SISCR, 0x79, temp);
2497 if(temp & 0x20) ivideo->vbflags |= TV_PAL;
2498 else ivideo->vbflags |= TV_NTSC;
2499 }
2500 }
2501 }
2502
2503 /* Copy forceCRT1 option to CRT1off if option is given */
2504 if(ivideo->sisfb_forcecrt1 != -1) {
2505 ivideo->sisfb_crt1off = (ivideo->sisfb_forcecrt1) ? 0 : 1;
2506 }
2507}
2508
2509static void __devinit sisfb_get_VB_type(struct sis_video_info *ivideo)
2510{
2511 char stdstr[] = "sisfb: Detected";
2512 char bridgestr[] = "video bridge";
2513 u8 vb_chipid;
2514 u8 reg;
2515
2516 inSISIDXREG(SISPART4, 0x00, vb_chipid);
2517 switch(vb_chipid) {
2518 case 0x01:
2519 inSISIDXREG(SISPART4, 0x01, reg);
2520 if(reg < 0xb0) {
2521 ivideo->vbflags |= VB_301;
2522 printk(KERN_INFO "%s SiS301 %s\n", stdstr, bridgestr);
2523 } else if(reg < 0xc0) {
2524 ivideo->vbflags |= VB_301B;
2525 inSISIDXREG(SISPART4,0x23,reg);
2526 if(!(reg & 0x02)) {
2527 ivideo->vbflags |= VB_30xBDH;
2528 printk(KERN_INFO "%s SiS301B-DH %s\n", stdstr, bridgestr);
2529 } else {
2530 printk(KERN_INFO "%s SiS301B %s\n", stdstr, bridgestr);
2531 }
2532 } else if(reg < 0xd0) {
2533 ivideo->vbflags |= VB_301C;
2534 printk(KERN_INFO "%s SiS301C %s\n", stdstr, bridgestr);
2535 } else if(reg < 0xe0) {
2536 ivideo->vbflags |= VB_301LV;
2537 printk(KERN_INFO "%s SiS301LV %s\n", stdstr, bridgestr);
2538 } else if(reg <= 0xe1) {
2539 inSISIDXREG(SISPART4,0x39,reg);
2540 if(reg == 0xff) {
2541 ivideo->vbflags |= VB_302LV;
2542 printk(KERN_INFO "%s SiS302LV %s\n", stdstr, bridgestr);
2543 } else {
2544 ivideo->vbflags |= VB_301C;
2545 printk(KERN_INFO "%s SiS301C(P4) %s\n", stdstr, bridgestr);
2546#if 0
2547 ivideo->vbflags |= VB_302ELV;
2548 printk(KERN_INFO "%s SiS302ELV %s\n", stdstr, bridgestr);
2549#endif
2550 }
2551 }
2552 break;
2553 case 0x02:
2554 ivideo->vbflags |= VB_302B;
2555 printk(KERN_INFO "%s SiS302B %s\n", stdstr, bridgestr);
2556 break;
2557 }
2558
2559 if((!(ivideo->vbflags & VB_VIDEOBRIDGE)) && (ivideo->chip != SIS_300)) {
2560 inSISIDXREG(SISCR, 0x37, reg);
2561 reg &= SIS_EXTERNAL_CHIP_MASK;
2562 reg >>= 1;
2563 if(ivideo->sisvga_engine == SIS_300_VGA) {
2564#ifdef CONFIG_FB_SIS_300
2565 switch(reg) {
2566 case SIS_EXTERNAL_CHIP_LVDS:
2567 ivideo->vbflags |= VB_LVDS;
2568 break;
2569 case SIS_EXTERNAL_CHIP_TRUMPION:
2570 ivideo->vbflags |= VB_TRUMPION;
2571 break;
2572 case SIS_EXTERNAL_CHIP_CHRONTEL:
2573 ivideo->vbflags |= VB_CHRONTEL;
2574 break;
2575 case SIS_EXTERNAL_CHIP_LVDS_CHRONTEL:
2576 ivideo->vbflags |= (VB_LVDS | VB_CHRONTEL);
2577 break;
2578 }
2579 if(ivideo->vbflags & VB_CHRONTEL) ivideo->chronteltype = 1;
2580#endif
2581 } else if(ivideo->chip < SIS_661) {
2582#ifdef CONFIG_FB_SIS_315
2583 switch (reg) {
2584 case SIS310_EXTERNAL_CHIP_LVDS:
2585 ivideo->vbflags |= VB_LVDS;
2586 break;
2587 case SIS310_EXTERNAL_CHIP_LVDS_CHRONTEL:
2588 ivideo->vbflags |= (VB_LVDS | VB_CHRONTEL);
2589 break;
2590 }
2591 if(ivideo->vbflags & VB_CHRONTEL) ivideo->chronteltype = 2;
2592#endif
2593 } else if(ivideo->chip >= SIS_661) {
2594#ifdef CONFIG_FB_SIS_315
2595 inSISIDXREG(SISCR, 0x38, reg);
2596 reg >>= 5;
2597 switch(reg) {
2598 case 0x02:
2599 ivideo->vbflags |= VB_LVDS;
2600 break;
2601 case 0x03:
2602 ivideo->vbflags |= (VB_LVDS | VB_CHRONTEL);
2603 break;
2604 case 0x04:
2605 ivideo->vbflags |= (VB_LVDS | VB_CONEXANT);
2606 break;
2607 }
2608 if(ivideo->vbflags & VB_CHRONTEL) ivideo->chronteltype = 2;
2609#endif
2610 }
2611 if(ivideo->vbflags & VB_LVDS) {
2612 printk(KERN_INFO "%s LVDS transmitter\n", stdstr);
2613 }
2614 if(ivideo->vbflags & VB_TRUMPION) {
2615 printk(KERN_INFO "%s Trumpion Zurac LCD scaler\n", stdstr);
2616 }
2617 if(ivideo->vbflags & VB_CHRONTEL) {
2618 printk(KERN_INFO "%s Chrontel TV encoder\n", stdstr);
2619 }
2620 if(ivideo->vbflags & VB_CONEXANT) {
2621 printk(KERN_INFO "%s Conexant external device\n", stdstr);
2622 }
2623 }
2624
2625 if(ivideo->vbflags & VB_SISBRIDGE) {
2626 SiS_Sense30x(ivideo);
2627 } else if(ivideo->vbflags & VB_CHRONTEL) {
2628 SiS_SenseCh(ivideo);
2629 }
2630}
2631
2632/* ------------------ Sensing routines ------------------ */
2633
2634static BOOLEAN __devinit sisfb_test_DDC1(struct sis_video_info *ivideo)
2635{
2636 unsigned short old;
2637 int count = 48;
2638
2639 old = SiS_ReadDDC1Bit(&ivideo->SiS_Pr);
2640 do {
2641 if(old != SiS_ReadDDC1Bit(&ivideo->SiS_Pr)) break;
2642 } while(count--);
2643 return (count == -1) ? FALSE : TRUE;
2644}
2645
2646static void __devinit sisfb_sense_crt1(struct sis_video_info *ivideo)
2647{
2648 BOOLEAN mustwait = FALSE;
2649 u8 sr1F, cr17;
2650#ifdef CONFIG_FB_SIS_315
2651 u8 cr63=0;
2652#endif
2653 u16 temp = 0xffff;
2654 int i;
2655
2656 inSISIDXREG(SISSR,0x1F,sr1F);
2657 orSISIDXREG(SISSR,0x1F,0x04);
2658 andSISIDXREG(SISSR,0x1F,0x3F);
2659 if(sr1F & 0xc0) mustwait = TRUE;
2660
2661#ifdef CONFIG_FB_SIS_315
2662 if(ivideo->sisvga_engine == SIS_315_VGA) {
2663 inSISIDXREG(SISCR,ivideo->SiS_Pr.SiS_MyCR63,cr63);
2664 cr63 &= 0x40;
2665 andSISIDXREG(SISCR,ivideo->SiS_Pr.SiS_MyCR63,0xBF);
2666 }
2667#endif
2668
2669 inSISIDXREG(SISCR,0x17,cr17);
2670 cr17 &= 0x80;
2671 if(!cr17) {
2672 orSISIDXREG(SISCR,0x17,0x80);
2673 mustwait = TRUE;
2674 outSISIDXREG(SISSR, 0x00, 0x01);
2675 outSISIDXREG(SISSR, 0x00, 0x03);
2676 }
2677
2678 if(mustwait) {
2679 for(i=0; i < 10; i++) sisfbwaitretracecrt1(ivideo);
2680 }
2681
2682#ifdef CONFIG_FB_SIS_315
2683 if(ivideo->chip >= SIS_330) {
2684 andSISIDXREG(SISCR,0x32,~0x20);
2685 if(ivideo->chip >= SIS_340) {
2686 outSISIDXREG(SISCR, 0x57, 0x4a);
2687 } else {
2688 outSISIDXREG(SISCR, 0x57, 0x5f);
2689 }
2690 orSISIDXREG(SISCR, 0x53, 0x02);
2691 while((inSISREG(SISINPSTAT)) & 0x01) break;
2692 while(!((inSISREG(SISINPSTAT)) & 0x01)) break;
2693 if((inSISREG(SISMISCW)) & 0x10) temp = 1;
2694 andSISIDXREG(SISCR, 0x53, 0xfd);
2695 andSISIDXREG(SISCR, 0x57, 0x00);
2696 }
2697#endif
2698
2699 if(temp == 0xffff) {
2700 i = 3;
2701 do {
2702 temp = SiS_HandleDDC(&ivideo->SiS_Pr, ivideo->vbflags, ivideo->sisvga_engine, 0, 0, NULL);
2703 } while(((temp == 0) || (temp == 0xffff)) && i--);
2704
2705 if((temp == 0) || (temp == 0xffff)) {
2706 if(sisfb_test_DDC1(ivideo)) temp = 1;
2707 }
2708 }
2709
2710 if((temp) && (temp != 0xffff)) {
2711 orSISIDXREG(SISCR,0x32,0x20);
2712 }
2713
2714#ifdef CONFIG_FB_SIS_315
2715 if(ivideo->sisvga_engine == SIS_315_VGA) {
2716 setSISIDXREG(SISCR,ivideo->SiS_Pr.SiS_MyCR63,0xBF,cr63);
2717 }
2718#endif
2719
2720 setSISIDXREG(SISCR,0x17,0x7F,cr17);
2721
2722 outSISIDXREG(SISSR,0x1F,sr1F);
2723}
2724
2725/* Determine and detect attached devices on SiS30x */
2726static int __devinit SISDoSense(struct sis_video_info *ivideo, u16 type, u16 test)
2727{
2728 int temp, mytest, result, i, j;
2729
2730 for(j = 0; j < 10; j++) {
2731 result = 0;
2732 for(i = 0; i < 3; i++) {
2733 mytest = test;
2734 outSISIDXREG(SISPART4,0x11,(type & 0x00ff));
2735 temp = (type >> 8) | (mytest & 0x00ff);
2736 setSISIDXREG(SISPART4,0x10,0xe0,temp);
2737 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x1500);
2738 mytest >>= 8;
2739 mytest &= 0x7f;
2740 inSISIDXREG(SISPART4,0x03,temp);
2741 temp ^= 0x0e;
2742 temp &= mytest;
2743 if(temp == mytest) result++;
2744#if 1
2745 outSISIDXREG(SISPART4,0x11,0x00);
2746 andSISIDXREG(SISPART4,0x10,0xe0);
2747 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x1000);
2748#endif
2749 }
2750 if((result == 0) || (result >= 2)) break;
2751 }
2752 return(result);
2753}
2754
2755static void __devinit SiS_Sense30x(struct sis_video_info *ivideo)
2756{
2757 u8 backupP4_0d,backupP2_00,backupP2_4d,backupSR_1e,biosflag=0;
2758 u16 svhs=0, svhs_c=0;
2759 u16 cvbs=0, cvbs_c=0;
2760 u16 vga2=0, vga2_c=0;
2761 int myflag, result;
2762 char stdstr[] = "sisfb: Detected";
2763 char tvstr[] = "TV connected to";
2764
2765 if(ivideo->vbflags & VB_301) {
2766 svhs = 0x00b9; cvbs = 0x00b3; vga2 = 0x00d1;
2767 inSISIDXREG(SISPART4,0x01,myflag);
2768 if(myflag & 0x04) {
2769 svhs = 0x00dd; cvbs = 0x00ee; vga2 = 0x00fd;
2770 }
2771 } else if(ivideo->vbflags & (VB_301B | VB_302B)) {
2772 svhs = 0x016b; cvbs = 0x0174; vga2 = 0x0190;
2773 } else if(ivideo->vbflags & (VB_301LV | VB_302LV)) {
2774 svhs = 0x0200; cvbs = 0x0100;
2775 } else if(ivideo->vbflags & (VB_301C | VB_302ELV)) {
2776 svhs = 0x016b; cvbs = 0x0110; vga2 = 0x0190;
2777 } else return;
2778
2779 vga2_c = 0x0e08; svhs_c = 0x0404; cvbs_c = 0x0804;
2780 if(ivideo->vbflags & (VB_301LV|VB_302LV|VB_302ELV)) {
2781 svhs_c = 0x0408; cvbs_c = 0x0808;
2782 }
2783 biosflag = 2;
2784
2785 if(ivideo->chip == SIS_300) {
2786 inSISIDXREG(SISSR,0x3b,myflag);
2787 if(!(myflag & 0x01)) vga2 = vga2_c = 0;
2788 }
2789
2790 inSISIDXREG(SISSR,0x1e,backupSR_1e);
2791 orSISIDXREG(SISSR,0x1e,0x20);
2792
2793 inSISIDXREG(SISPART4,0x0d,backupP4_0d);
2794 if(ivideo->vbflags & VB_301C) {
2795 setSISIDXREG(SISPART4,0x0d,~0x07,0x01);
2796 } else {
2797 orSISIDXREG(SISPART4,0x0d,0x04);
2798 }
2799 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x2000);
2800
2801 inSISIDXREG(SISPART2,0x00,backupP2_00);
2802 outSISIDXREG(SISPART2,0x00,((backupP2_00 | 0x1c) & 0xfc));
2803
2804 inSISIDXREG(SISPART2,0x4d,backupP2_4d);
2805 if(ivideo->vbflags & (VB_301C|VB_301LV|VB_302LV|VB_302ELV)) {
2806 outSISIDXREG(SISPART2,0x4d,(backupP2_4d & ~0x10));
2807 }
2808
2809 if(!(ivideo->vbflags & VB_301C)) {
2810 SISDoSense(ivideo, 0, 0);
2811 }
2812
2813 andSISIDXREG(SISCR, 0x32, ~0x14);
2814
2815 if(vga2_c || vga2) {
2816 if(SISDoSense(ivideo, vga2, vga2_c)) {
2817 if(biosflag & 0x01) {
2818 printk(KERN_INFO "%s %s SCART output\n", stdstr, tvstr);
2819 orSISIDXREG(SISCR, 0x32, 0x04);
2820 } else {
2821 printk(KERN_INFO "%s secondary VGA connection\n", stdstr);
2822 orSISIDXREG(SISCR, 0x32, 0x10);
2823 }
2824 }
2825 }
2826
2827 andSISIDXREG(SISCR, 0x32, 0x3f);
2828
2829 if(ivideo->vbflags & VB_301C) {
2830 orSISIDXREG(SISPART4,0x0d,0x04);
2831 }
2832
2833 if((ivideo->sisvga_engine == SIS_315_VGA) &&
2834 (ivideo->vbflags & (VB_301C|VB_301LV|VB_302LV|VB_302ELV))) {
2835 outSISIDXREG(SISPART2,0x4d,(backupP2_4d | 0x10));
2836 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x2000);
2837 if((result = SISDoSense(ivideo, svhs, 0x0604))) {
2838 if((result = SISDoSense(ivideo, cvbs, 0x0804))) {
2839 printk(KERN_INFO "%s %s YPbPr component output\n", stdstr, tvstr);
2840 orSISIDXREG(SISCR,0x32,0x80);
2841 }
2842 }
2843 outSISIDXREG(SISPART2,0x4d,backupP2_4d);
2844 }
2845
2846 andSISIDXREG(SISCR, 0x32, ~0x03);
2847
2848 if(!(ivideo->vbflags & TV_YPBPR)) {
2849 if((result = SISDoSense(ivideo, svhs, svhs_c))) {
2850 printk(KERN_INFO "%s %s SVIDEO output\n", stdstr, tvstr);
2851 orSISIDXREG(SISCR, 0x32, 0x02);
2852 }
2853 if((biosflag & 0x02) || (!result)) {
2854 if(SISDoSense(ivideo, cvbs, cvbs_c)) {
2855 printk(KERN_INFO "%s %s COMPOSITE output\n", stdstr, tvstr);
2856 orSISIDXREG(SISCR, 0x32, 0x01);
2857 }
2858 }
2859 }
2860
2861 SISDoSense(ivideo, 0, 0);
2862
2863 outSISIDXREG(SISPART2,0x00,backupP2_00);
2864 outSISIDXREG(SISPART4,0x0d,backupP4_0d);
2865 outSISIDXREG(SISSR,0x1e,backupSR_1e);
2866
2867 if(ivideo->vbflags & VB_301C) {
2868 inSISIDXREG(SISPART2,0x00,biosflag);
2869 if(biosflag & 0x20) {
2870 for(myflag = 2; myflag > 0; myflag--) {
2871 biosflag ^= 0x20;
2872 outSISIDXREG(SISPART2,0x00,biosflag);
2873 }
2874 }
2875 }
2876
2877 outSISIDXREG(SISPART2,0x00,backupP2_00);
2878}
2879
2880/* Determine and detect attached TV's on Chrontel */
2881static void __devinit SiS_SenseCh(struct sis_video_info *ivideo)
2882{
2883#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
2884 u8 temp1, temp2;
2885 char stdstr[] = "sisfb: Chrontel: Detected TV connected to";
2886#endif
2887#ifdef CONFIG_FB_SIS_300
2888 unsigned char test[3];
2889 int i;
2890#endif
2891
2892 if(ivideo->chip < SIS_315H) {
2893
2894#ifdef CONFIG_FB_SIS_300
2895 ivideo->SiS_Pr.SiS_IF_DEF_CH70xx = 1; /* Chrontel 700x */
2896 SiS_SetChrontelGPIO(&ivideo->SiS_Pr, 0x9c); /* Set general purpose IO for Chrontel communication */
2897 SiS_DDC2Delay(&ivideo->SiS_Pr, 1000);
2898 temp1 = SiS_GetCH700x(&ivideo->SiS_Pr, 0x25);
2899 /* See Chrontel TB31 for explanation */
2900 temp2 = SiS_GetCH700x(&ivideo->SiS_Pr, 0x0e);
2901 if(((temp2 & 0x07) == 0x01) || (temp2 & 0x04)) {
2902 SiS_SetCH700x(&ivideo->SiS_Pr, 0x0b0e);
2903 SiS_DDC2Delay(&ivideo->SiS_Pr, 300);
2904 }
2905 temp2 = SiS_GetCH700x(&ivideo->SiS_Pr, 0x25);
2906 if(temp2 != temp1) temp1 = temp2;
2907
2908 if((temp1 >= 0x22) && (temp1 <= 0x50)) {
2909 /* Read power status */
2910 temp1 = SiS_GetCH700x(&ivideo->SiS_Pr, 0x0e);
2911 if((temp1 & 0x03) != 0x03) {
2912 /* Power all outputs */
2913 SiS_SetCH700x(&ivideo->SiS_Pr, 0x0B0E);
2914 SiS_DDC2Delay(&ivideo->SiS_Pr, 300);
2915 }
2916 /* Sense connected TV devices */
2917 for(i = 0; i < 3; i++) {
2918 SiS_SetCH700x(&ivideo->SiS_Pr, 0x0110);
2919 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96);
2920 SiS_SetCH700x(&ivideo->SiS_Pr, 0x0010);
2921 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96);
2922 temp1 = SiS_GetCH700x(&ivideo->SiS_Pr, 0x10);
2923 if(!(temp1 & 0x08)) test[i] = 0x02;
2924 else if(!(temp1 & 0x02)) test[i] = 0x01;
2925 else test[i] = 0;
2926 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96);
2927 }
2928
2929 if(test[0] == test[1]) temp1 = test[0];
2930 else if(test[0] == test[2]) temp1 = test[0];
2931 else if(test[1] == test[2]) temp1 = test[1];
2932 else {
2933 printk(KERN_INFO
2934 "sisfb: TV detection unreliable - test results varied\n");
2935 temp1 = test[2];
2936 }
2937 if(temp1 == 0x02) {
2938 printk(KERN_INFO "%s SVIDEO output\n", stdstr);
2939 ivideo->vbflags |= TV_SVIDEO;
2940 orSISIDXREG(SISCR, 0x32, 0x02);
2941 andSISIDXREG(SISCR, 0x32, ~0x05);
2942 } else if (temp1 == 0x01) {
2943 printk(KERN_INFO "%s CVBS output\n", stdstr);
2944 ivideo->vbflags |= TV_AVIDEO;
2945 orSISIDXREG(SISCR, 0x32, 0x01);
2946 andSISIDXREG(SISCR, 0x32, ~0x06);
2947 } else {
2948 SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, 0x010E,0xF8);
2949 andSISIDXREG(SISCR, 0x32, ~0x07);
2950 }
2951 } else if(temp1 == 0) {
2952 SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, 0x010E,0xF8);
2953 andSISIDXREG(SISCR, 0x32, ~0x07);
2954 }
2955 /* Set general purpose IO for Chrontel communication */
2956 SiS_SetChrontelGPIO(&ivideo->SiS_Pr, 0x00);
2957#endif
2958
2959 } else {
2960
2961#ifdef CONFIG_FB_SIS_315
2962 ivideo->SiS_Pr.SiS_IF_DEF_CH70xx = 2; /* Chrontel 7019 */
2963 temp1 = SiS_GetCH701x(&ivideo->SiS_Pr, 0x49);
2964 SiS_SetCH701x(&ivideo->SiS_Pr, 0x2049);
2965 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96);
2966 temp2 = SiS_GetCH701x(&ivideo->SiS_Pr, 0x20);
2967 temp2 |= 0x01;
2968 SiS_SetCH701x(&ivideo->SiS_Pr, (temp2 << 8) | 0x20);
2969 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96);
2970 temp2 ^= 0x01;
2971 SiS_SetCH701x(&ivideo->SiS_Pr, (temp2 << 8) | 0x20);
2972 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96);
2973 temp2 = SiS_GetCH701x(&ivideo->SiS_Pr, 0x20);
2974 SiS_SetCH701x(&ivideo->SiS_Pr, (temp1 << 8) | 0x49);
2975 temp1 = 0;
2976 if(temp2 & 0x02) temp1 |= 0x01;
2977 if(temp2 & 0x10) temp1 |= 0x01;
2978 if(temp2 & 0x04) temp1 |= 0x02;
2979 if( (temp1 & 0x01) && (temp1 & 0x02) ) temp1 = 0x04;
2980 switch(temp1) {
2981 case 0x01:
2982 printk(KERN_INFO "%s CVBS output\n", stdstr);
2983 ivideo->vbflags |= TV_AVIDEO;
2984 orSISIDXREG(SISCR, 0x32, 0x01);
2985 andSISIDXREG(SISCR, 0x32, ~0x06);
2986 break;
2987 case 0x02:
2988 printk(KERN_INFO "%s SVIDEO output\n", stdstr);
2989 ivideo->vbflags |= TV_SVIDEO;
2990 orSISIDXREG(SISCR, 0x32, 0x02);
2991 andSISIDXREG(SISCR, 0x32, ~0x05);
2992 break;
2993 case 0x04:
2994 printk(KERN_INFO "%s SCART output\n", stdstr);
2995 orSISIDXREG(SISCR, 0x32, 0x04);
2996 andSISIDXREG(SISCR, 0x32, ~0x03);
2997 break;
2998 default:
2999 andSISIDXREG(SISCR, 0x32, ~0x07);
3000 }
3001#endif
3002 }
3003}
3004
3005/* ------------------------ Heap routines -------------------------- */
3006
3007static u32 __devinit
3008sisfb_getheapstart(struct sis_video_info *ivideo)
3009{
3010 u32 ret = ivideo->sisfb_parm_mem * 1024;
3011 u32 max = ivideo->video_size - ivideo->hwcursor_size;
3012 u32 def;
3013
3014 /* Calculate heap start = end of memory for console
3015 *
3016 * CCCCCCCCDDDDDDDDDDDDDDDDDDDDDDDDDDDDHHHHQQQQQQQQQQ
3017 * C = console, D = heap, H = HWCursor, Q = cmd-queue
3018 *
3019 * Basically given by "mem" parameter
3020 *
3021 * maximum = videosize - cmd_queue - hwcursor
3022 * (results in a heap of size 0)
3023 * default = SiS 300: depends on videosize
3024 * SiS 315/330: 32k below max
3025 */
3026
3027 if(ivideo->sisvga_engine == SIS_300_VGA) {
3028 max -= TURBO_QUEUE_AREA_SIZE;
3029 if(ivideo->video_size > 0x1000000) {
3030 def = 0xc00000;
3031 } else if(ivideo->video_size > 0x800000) {
3032 def = 0x800000;
3033 } else {
3034 def = 0x400000;
3035 }
3036 } else {
3037 max -= COMMAND_QUEUE_AREA_SIZE;
3038 def = max - 0x8000;
3039 }
3040
3041 if((!ret) || (ret > max) || (ivideo->cardnumber != 0)) {
3042 ret = def;
3043 }
3044
3045 return ret;
3046}
3047
3048static int __devinit
3049sisfb_heap_init(struct sis_video_info *ivideo)
3050{
3051 SIS_OH *poh;
3052
3053 ivideo->heapstart = ivideo->sisfb_mem = sisfb_getheapstart(ivideo);
3054
3055 ivideo->sisfb_heap_start = ivideo->video_vbase + ivideo->heapstart;
3056 ivideo->sisfb_heap_end = ivideo->video_vbase + ivideo->video_size;
3057
3058 /* Initialize command queue (We use MMIO only) */
3059
3060#ifdef CONFIG_FB_SIS_315
3061 if(ivideo->sisvga_engine == SIS_315_VGA) {
3062 u32 tempq = 0;
3063 u8 temp = 0;
3064
3065 ivideo->sisfb_heap_end -= COMMAND_QUEUE_AREA_SIZE;
3066
3067 outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD);
3068 outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_SET, SIS_CMD_QUEUE_RESET);
3069
3070 tempq = MMIO_IN32(ivideo->mmio_vbase, MMIO_QUEUE_READPORT);
3071 MMIO_OUT32(ivideo->mmio_vbase, MMIO_QUEUE_WRITEPORT, tempq);
3072
3073 temp = SIS_CMD_QUEUE_SIZE_512k;
3074 temp |= (SIS_MMIO_CMD_ENABLE | SIS_CMD_AUTO_CORR);
3075 outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_SET, temp);
3076
3077 tempq = (u32)(ivideo->video_size - COMMAND_QUEUE_AREA_SIZE);
3078 MMIO_OUT32(ivideo->mmio_vbase, MMIO_QUEUE_PHYBASE, tempq);
3079
3080 ivideo->caps |= MMIO_CMD_QUEUE_CAP;
3081 }
3082#endif
3083
3084#ifdef CONFIG_FB_SIS_300
3085 if(ivideo->sisvga_engine == SIS_300_VGA) {
3086 unsigned long tqueue_pos;
3087 u8 tq_state;
3088
3089 ivideo->sisfb_heap_end -= TURBO_QUEUE_AREA_SIZE;
3090
3091 tqueue_pos = (ivideo->video_size - TURBO_QUEUE_AREA_SIZE) / (64 * 1024);
3092
3093 inSISIDXREG(SISSR, IND_SIS_TURBOQUEUE_SET, tq_state);
3094 tq_state |= 0xf0;
3095 tq_state &= 0xfc;
3096 tq_state |= (u8)(tqueue_pos >> 8);
3097 outSISIDXREG(SISSR, IND_SIS_TURBOQUEUE_SET, tq_state);
3098
3099 outSISIDXREG(SISSR, IND_SIS_TURBOQUEUE_ADR, (u8)(tqueue_pos & 0xff));
3100
3101 ivideo->caps |= TURBO_QUEUE_CAP;
3102 }
3103#endif
3104
3105 /* Reserve memory for the HWCursor */
3106 ivideo->sisfb_heap_end -= ivideo->hwcursor_size;
3107 ivideo->hwcursor_vbase = ivideo->sisfb_heap_end;
3108 ivideo->caps |= HW_CURSOR_CAP;
3109
3110 ivideo->sisfb_heap_size = ivideo->sisfb_heap_end - ivideo->sisfb_heap_start;
3111
3112 if(ivideo->cardnumber == 0) {
3113
3114 printk(KERN_INFO "sisfb: Memory heap starting at %dK, size %dK\n",
3115 (int)(ivideo->heapstart / 1024), (int)(ivideo->sisfb_heap_size / 1024));
3116
3117 sisfb_heap.vinfo = ivideo;
3118
3119 sisfb_heap.poha_chain = NULL;
3120 sisfb_heap.poh_freelist = NULL;
3121
3122 poh = sisfb_poh_new_node();
3123 if(poh == NULL) return 1;
3124
3125 poh->poh_next = &sisfb_heap.oh_free;
3126 poh->poh_prev = &sisfb_heap.oh_free;
3127 poh->size = ivideo->sisfb_heap_size;
3128 poh->offset = ivideo->heapstart;
3129
3130 sisfb_heap.oh_free.poh_next = poh;
3131 sisfb_heap.oh_free.poh_prev = poh;
3132 sisfb_heap.oh_free.size = 0;
3133 sisfb_heap.max_freesize = poh->size;
3134
3135 sisfb_heap.oh_used.poh_next = &sisfb_heap.oh_used;
3136 sisfb_heap.oh_used.poh_prev = &sisfb_heap.oh_used;
3137 sisfb_heap.oh_used.size = SENTINEL;
3138
3139 } else {
3140
3141 printk(KERN_INFO "Skipped heap initialization for secondary cards\n");
3142
3143 }
3144
3145 return 0;
3146}
3147
3148static SIS_OH *
3149sisfb_poh_new_node(void)
3150{
3151 int i;
3152 unsigned long cOhs;
3153 SIS_OHALLOC *poha;
3154 SIS_OH *poh;
3155
3156 if(sisfb_heap.poh_freelist == NULL) {
3157 poha = kmalloc(SIS_OH_ALLOC_SIZE, GFP_KERNEL);
3158 if(!poha) return NULL;
3159
3160 poha->poha_next = sisfb_heap.poha_chain;
3161 sisfb_heap.poha_chain = poha;
3162
3163 cOhs = (SIS_OH_ALLOC_SIZE - sizeof(SIS_OHALLOC)) / sizeof(SIS_OH) + 1;
3164
3165 poh = &poha->aoh[0];
3166 for(i = cOhs - 1; i != 0; i--) {
3167 poh->poh_next = poh + 1;
3168 poh = poh + 1;
3169 }
3170
3171 poh->poh_next = NULL;
3172 sisfb_heap.poh_freelist = &poha->aoh[0];
3173 }
3174
3175 poh = sisfb_heap.poh_freelist;
3176 sisfb_heap.poh_freelist = poh->poh_next;
3177
3178 return (poh);
3179}
3180
3181static SIS_OH *
3182sisfb_poh_allocate(u32 size)
3183{
3184 SIS_OH *pohThis;
3185 SIS_OH *pohRoot;
3186 int bAllocated = 0;
3187
3188 if(size > sisfb_heap.max_freesize) {
3189 DPRINTK("sisfb: Can't allocate %dk video memory\n",
3190 (unsigned int) size / 1024);
3191 return (NULL);
3192 }
3193
3194 pohThis = sisfb_heap.oh_free.poh_next;
3195
3196 while(pohThis != &sisfb_heap.oh_free) {
3197 if (size <= pohThis->size) {
3198 bAllocated = 1;
3199 break;
3200 }
3201 pohThis = pohThis->poh_next;
3202 }
3203
3204 if(!bAllocated) {
3205 DPRINTK("sisfb: Can't allocate %dk video memory\n",
3206 (unsigned int) size / 1024);
3207 return (NULL);
3208 }
3209
3210 if(size == pohThis->size) {
3211 pohRoot = pohThis;
3212 sisfb_delete_node(pohThis);
3213 } else {
3214 pohRoot = sisfb_poh_new_node();
3215
3216 if(pohRoot == NULL) {
3217 return (NULL);
3218 }
3219
3220 pohRoot->offset = pohThis->offset;
3221 pohRoot->size = size;
3222
3223 pohThis->offset += size;
3224 pohThis->size -= size;
3225 }
3226
3227 sisfb_heap.max_freesize -= size;
3228
3229 pohThis = &sisfb_heap.oh_used;
3230 sisfb_insert_node(pohThis, pohRoot);
3231
3232 return (pohRoot);
3233}
3234
3235static void
3236sisfb_delete_node(SIS_OH *poh)
3237{
3238 SIS_OH *poh_prev;
3239 SIS_OH *poh_next;
3240
3241 poh_prev = poh->poh_prev;
3242 poh_next = poh->poh_next;
3243
3244 poh_prev->poh_next = poh_next;
3245 poh_next->poh_prev = poh_prev;
3246}
3247
3248static void
3249sisfb_insert_node(SIS_OH *pohList, SIS_OH *poh)
3250{
3251 SIS_OH *pohTemp;
3252
3253 pohTemp = pohList->poh_next;
3254
3255 pohList->poh_next = poh;
3256 pohTemp->poh_prev = poh;
3257
3258 poh->poh_prev = pohList;
3259 poh->poh_next = pohTemp;
3260}
3261
3262static SIS_OH *
3263sisfb_poh_free(u32 base)
3264{
3265 SIS_OH *pohThis;
3266 SIS_OH *poh_freed;
3267 SIS_OH *poh_prev;
3268 SIS_OH *poh_next;
3269 u32 ulUpper;
3270 u32 ulLower;
3271 int foundNode = 0;
3272
3273 poh_freed = sisfb_heap.oh_used.poh_next;
3274
3275 while(poh_freed != &sisfb_heap.oh_used) {
3276 if(poh_freed->offset == base) {
3277 foundNode = 1;
3278 break;
3279 }
3280
3281 poh_freed = poh_freed->poh_next;
3282 }
3283
3284 if(!foundNode) return(NULL);
3285
3286 sisfb_heap.max_freesize += poh_freed->size;
3287
3288 poh_prev = poh_next = NULL;
3289 ulUpper = poh_freed->offset + poh_freed->size;
3290 ulLower = poh_freed->offset;
3291
3292 pohThis = sisfb_heap.oh_free.poh_next;
3293
3294 while(pohThis != &sisfb_heap.oh_free) {
3295 if(pohThis->offset == ulUpper) {
3296 poh_next = pohThis;
3297 } else if((pohThis->offset + pohThis->size) == ulLower) {
3298 poh_prev = pohThis;
3299 }
3300 pohThis = pohThis->poh_next;
3301 }
3302
3303 sisfb_delete_node(poh_freed);
3304
3305 if(poh_prev && poh_next) {
3306 poh_prev->size += (poh_freed->size + poh_next->size);
3307 sisfb_delete_node(poh_next);
3308 sisfb_free_node(poh_freed);
3309 sisfb_free_node(poh_next);
3310 return(poh_prev);
3311 }
3312
3313 if(poh_prev) {
3314 poh_prev->size += poh_freed->size;
3315 sisfb_free_node(poh_freed);
3316 return(poh_prev);
3317 }
3318
3319 if(poh_next) {
3320 poh_next->size += poh_freed->size;
3321 poh_next->offset = poh_freed->offset;
3322 sisfb_free_node(poh_freed);
3323 return(poh_next);
3324 }
3325
3326 sisfb_insert_node(&sisfb_heap.oh_free, poh_freed);
3327
3328 return(poh_freed);
3329}
3330
3331static void
3332sisfb_free_node(SIS_OH *poh)
3333{
3334 if(poh == NULL) return;
3335
3336 poh->poh_next = sisfb_heap.poh_freelist;
3337 sisfb_heap.poh_freelist = poh;
3338}
3339
3340void
3341sis_malloc(struct sis_memreq *req)
3342{
3343 struct sis_video_info *ivideo = sisfb_heap.vinfo;
3344 SIS_OH *poh = NULL;
3345
3346 if((ivideo) && (!ivideo->havenoheap)) {
3347 poh = sisfb_poh_allocate((u32)req->size);
3348 }
3349
3350 if(poh == NULL) {
3351 req->offset = req->size = 0;
3352 DPRINTK("sisfb: Video RAM allocation failed\n");
3353 } else {
3354 req->offset = poh->offset;
3355 req->size = poh->size;
3356 DPRINTK("sisfb: Video RAM allocation succeeded: 0x%lx\n",
3357 (poh->offset + ivideo->video_vbase));
3358 }
3359}
3360
3361/* sis_free: u32 because "base" is offset inside video ram, can never be >4GB */
3362
3363void
3364sis_free(u32 base)
3365{
3366 struct sis_video_info *ivideo = sisfb_heap.vinfo;
3367 SIS_OH *poh;
3368
3369 if((!ivideo) || (ivideo->havenoheap)) return;
3370
3371 poh = sisfb_poh_free((u32)base);
3372
3373 if(poh == NULL) {
3374 DPRINTK("sisfb: sisfb_poh_free() failed at base 0x%x\n",
3375 (unsigned int) base);
3376 }
3377}
3378
3379/* --------------------- SetMode routines ------------------------- */
3380
3381static void
3382sisfb_pre_setmode(struct sis_video_info *ivideo)
3383{
3384 u8 cr30 = 0, cr31 = 0, cr33 = 0, cr35 = 0, cr38 = 0;
3385 int tvregnum = 0;
3386
3387 ivideo->currentvbflags &= (VB_VIDEOBRIDGE | VB_DISPTYPE_DISP2);
3388
3389 inSISIDXREG(SISCR, 0x31, cr31);
3390 cr31 &= ~0x60;
3391 cr31 |= 0x04;
3392
3393 cr33 = ivideo->rate_idx & 0x0F;
3394
3395#ifdef CONFIG_FB_SIS_315
3396 if(ivideo->sisvga_engine == SIS_315_VGA) {
3397 if(ivideo->chip >= SIS_661) {
3398 inSISIDXREG(SISCR, 0x38, cr38);
3399 cr38 &= ~0x07; /* Clear LCDA/DualEdge and YPbPr bits */
3400 } else {
3401 tvregnum = 0x38;
3402 inSISIDXREG(SISCR, tvregnum, cr38);
3403 cr38 &= ~0x3b; /* Clear LCDA/DualEdge and YPbPr bits */
3404 }
3405 }
3406#endif
3407#ifdef CONFIG_FB_SIS_300
3408 if(ivideo->sisvga_engine == SIS_300_VGA) {
3409 tvregnum = 0x35;
3410 inSISIDXREG(SISCR, tvregnum, cr38);
3411 }
3412#endif
3413
3414 SiS_SetEnableDstn(&ivideo->SiS_Pr, FALSE);
3415 SiS_SetEnableFstn(&ivideo->SiS_Pr, FALSE);
3416
3417 switch(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {
3418
3419 case CRT2_TV:
3420 cr38 &= ~0xc0; /* Clear PAL-M / PAL-N bits */
3421 if((ivideo->vbflags & TV_YPBPR) && (ivideo->vbflags & (VB_301C|VB_301LV|VB_302LV))) {
3422#ifdef CONFIG_FB_SIS_315
3423 if(ivideo->chip >= SIS_661) {
3424 cr38 |= 0x04;
3425 if(ivideo->vbflags & TV_YPBPR525P) cr35 |= 0x20;
3426 else if(ivideo->vbflags & TV_YPBPR750P) cr35 |= 0x40;
3427 else if(ivideo->vbflags & TV_YPBPR1080I) cr35 |= 0x60;
3428 cr30 |= SIS_SIMULTANEOUS_VIEW_ENABLE;
3429 cr35 &= ~0x01;
3430 ivideo->currentvbflags |= (TV_YPBPR | (ivideo->vbflags & TV_YPBPRALL));
3431 } else if(ivideo->sisvga_engine == SIS_315_VGA) {
3432 cr30 |= (0x80 | SIS_SIMULTANEOUS_VIEW_ENABLE);
3433 cr38 |= 0x08;
3434 if(ivideo->vbflags & TV_YPBPR525P) cr38 |= 0x10;
3435 else if(ivideo->vbflags & TV_YPBPR750P) cr38 |= 0x20;
3436 else if(ivideo->vbflags & TV_YPBPR1080I) cr38 |= 0x30;
3437 cr31 &= ~0x01;
3438 ivideo->currentvbflags |= (TV_YPBPR | (ivideo->vbflags & TV_YPBPRALL));
3439 }
3440#endif
3441 } else if((ivideo->vbflags & TV_HIVISION) && (ivideo->vbflags & (VB_301|VB_301B|VB_302B))) {
3442 if(ivideo->chip >= SIS_661) {
3443 cr38 |= 0x04;
3444 cr35 |= 0x60;
3445 } else {
3446 cr30 |= 0x80;
3447 }
3448 cr30 |= SIS_SIMULTANEOUS_VIEW_ENABLE;
3449 cr31 |= 0x01;
3450 cr35 |= 0x01;
3451 ivideo->currentvbflags |= TV_HIVISION;
3452 } else if(ivideo->vbflags & TV_SCART) {
3453 cr30 = (SIS_VB_OUTPUT_SCART | SIS_SIMULTANEOUS_VIEW_ENABLE);
3454 cr31 |= 0x01;
3455 cr35 |= 0x01;
3456 ivideo->currentvbflags |= TV_SCART;
3457 } else {
3458 if(ivideo->vbflags & TV_SVIDEO) {
3459 cr30 = (SIS_VB_OUTPUT_SVIDEO | SIS_SIMULTANEOUS_VIEW_ENABLE);
3460 ivideo->currentvbflags |= TV_SVIDEO;
3461 }
3462 if(ivideo->vbflags & TV_AVIDEO) {
3463 cr30 = (SIS_VB_OUTPUT_COMPOSITE | SIS_SIMULTANEOUS_VIEW_ENABLE);
3464 ivideo->currentvbflags |= TV_AVIDEO;
3465 }
3466 }
3467 cr31 |= SIS_DRIVER_MODE;
3468
3469 if(ivideo->vbflags & (TV_AVIDEO|TV_SVIDEO)) {
3470 if(ivideo->vbflags & TV_PAL) {
3471 cr31 |= 0x01; cr35 |= 0x01;
3472 ivideo->currentvbflags |= TV_PAL;
3473 if(ivideo->vbflags & TV_PALM) {
3474 cr38 |= 0x40; cr35 |= 0x04;
3475 ivideo->currentvbflags |= TV_PALM;
3476 } else if(ivideo->vbflags & TV_PALN) {
3477 cr38 |= 0x80; cr35 |= 0x08;
3478 ivideo->currentvbflags |= TV_PALN;
3479 }
3480 } else {
3481 cr31 &= ~0x01; cr35 &= ~0x01;
3482 ivideo->currentvbflags |= TV_NTSC;
3483 if(ivideo->vbflags & TV_NTSCJ) {
3484 cr38 |= 0x40; cr35 |= 0x02;
3485 ivideo->currentvbflags |= TV_NTSCJ;
3486 }
3487 }
3488 }
3489 break;
3490
3491 case CRT2_LCD:
3492 cr30 = (SIS_VB_OUTPUT_LCD | SIS_SIMULTANEOUS_VIEW_ENABLE);
3493 cr31 |= SIS_DRIVER_MODE;
3494 SiS_SetEnableDstn(&ivideo->SiS_Pr, ivideo->sisfb_dstn);
3495 SiS_SetEnableFstn(&ivideo->SiS_Pr, ivideo->sisfb_fstn);
3496 break;
3497
3498 case CRT2_VGA:
3499 cr30 = (SIS_VB_OUTPUT_CRT2 | SIS_SIMULTANEOUS_VIEW_ENABLE);
3500 cr31 |= SIS_DRIVER_MODE;
3501 if(ivideo->sisfb_nocrt2rate) {
3502 cr33 |= (sisbios_mode[ivideo->sisfb_mode_idx].rate_idx << 4);
3503 } else {
3504 cr33 |= ((ivideo->rate_idx & 0x0F) << 4);
3505 }
3506 break;
3507
3508 default: /* disable CRT2 */
3509 cr30 = 0x00;
3510 cr31 |= (SIS_DRIVER_MODE | SIS_VB_OUTPUT_DISABLE);
3511 }
3512
3513 outSISIDXREG(SISCR, 0x30, cr30);
3514 outSISIDXREG(SISCR, 0x33, cr33);
3515
3516 if(ivideo->chip >= SIS_661) {
3517#ifdef CONFIG_FB_SIS_315
3518 cr31 &= ~0x01; /* Clear PAL flag (now in CR35) */
3519 setSISIDXREG(SISCR, 0x35, ~0x10, cr35); /* Leave overscan bit alone */
3520 cr38 &= 0x07; /* Use only LCDA and HiVision/YPbPr bits */
3521 setSISIDXREG(SISCR, 0x38, 0xf8, cr38);
3522#endif
3523 } else if(ivideo->chip != SIS_300) {
3524 outSISIDXREG(SISCR, tvregnum, cr38);
3525 }
3526 outSISIDXREG(SISCR, 0x31, cr31);
3527
3528 if(ivideo->accel) sisfb_syncaccel(ivideo);
3529
3530 ivideo->SiS_Pr.SiS_UseOEM = ivideo->sisfb_useoem;
3531}
3532
3533/* Fix SR11 for 661 and later */
3534#ifdef CONFIG_FB_SIS_315
3535static void
3536sisfb_fixup_SR11(struct sis_video_info *ivideo)
3537{
3538 u8 tmpreg;
3539
3540 if(ivideo->chip >= SIS_661) {
3541 inSISIDXREG(SISSR,0x11,tmpreg);
3542 if(tmpreg & 0x20) {
3543 inSISIDXREG(SISSR,0x3e,tmpreg);
3544 tmpreg = (tmpreg + 1) & 0xff;
3545 outSISIDXREG(SISSR,0x3e,tmpreg);
3546 inSISIDXREG(SISSR,0x11,tmpreg);
3547 }
3548 if(tmpreg & 0xf0) {
3549 andSISIDXREG(SISSR,0x11,0x0f);
3550 }
3551 }
3552}
3553#endif
3554
3555static void sisfb_set_TVxposoffset(struct sis_video_info *ivideo, int val)
3556{
3557 if(val > 32) val = 32;
3558 if(val < -32) val = -32;
3559 ivideo->tvxpos = val;
3560
3561 if(ivideo->sisfblocked) return;
3562 if(!ivideo->modechanged) return;
3563
3564 if(ivideo->currentvbflags & CRT2_TV) {
3565
3566 if(ivideo->vbflags & VB_CHRONTEL) {
3567
3568 int x = ivideo->tvx;
3569
3570 switch(ivideo->chronteltype) {
3571 case 1:
3572 x += val;
3573 if(x < 0) x = 0;
3574 outSISIDXREG(SISSR,0x05,0x86);
3575 SiS_SetCH700x(&ivideo->SiS_Pr, (((x & 0xff) << 8) | 0x0a));
3576 SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, (((x & 0x0100) << 1) | 0x08),0xFD);
3577 break;
3578 case 2:
3579 /* Not supported by hardware */
3580 break;
3581 }
3582
3583 } else if(ivideo->vbflags & VB_SISBRIDGE) {
3584
3585 u8 p2_1f,p2_20,p2_2b,p2_42,p2_43;
3586 unsigned short temp;
3587
3588 p2_1f = ivideo->p2_1f;
3589 p2_20 = ivideo->p2_20;
3590 p2_2b = ivideo->p2_2b;
3591 p2_42 = ivideo->p2_42;
3592 p2_43 = ivideo->p2_43;
3593
3594 temp = p2_1f | ((p2_20 & 0xf0) << 4);
3595 temp += (val * 2);
3596 p2_1f = temp & 0xff;
3597 p2_20 = (temp & 0xf00) >> 4;
3598 p2_2b = ((p2_2b & 0x0f) + (val * 2)) & 0x0f;
3599 temp = p2_43 | ((p2_42 & 0xf0) << 4);
3600 temp += (val * 2);
3601 p2_43 = temp & 0xff;
3602 p2_42 = (temp & 0xf00) >> 4;
3603 outSISIDXREG(SISPART2,0x1f,p2_1f);
3604 setSISIDXREG(SISPART2,0x20,0x0F,p2_20);
3605 setSISIDXREG(SISPART2,0x2b,0xF0,p2_2b);
3606 setSISIDXREG(SISPART2,0x42,0x0F,p2_42);
3607 outSISIDXREG(SISPART2,0x43,p2_43);
3608 }
3609 }
3610}
3611
3612static void sisfb_set_TVyposoffset(struct sis_video_info *ivideo, int val)
3613{
3614 if(val > 32) val = 32;
3615 if(val < -32) val = -32;
3616 ivideo->tvypos = val;
3617
3618 if(ivideo->sisfblocked) return;
3619 if(!ivideo->modechanged) return;
3620
3621 if(ivideo->currentvbflags & CRT2_TV) {
3622
3623 if(ivideo->vbflags & VB_CHRONTEL) {
3624
3625 int y = ivideo->tvy;
3626
3627 switch(ivideo->chronteltype) {
3628 case 1:
3629 y -= val;
3630 if(y < 0) y = 0;
3631 outSISIDXREG(SISSR,0x05,0x86);
3632 SiS_SetCH700x(&ivideo->SiS_Pr, (((y & 0xff) << 8) | 0x0b));
3633 SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, ((y & 0x0100) | 0x08),0xFE);
3634 break;
3635 case 2:
3636 /* Not supported by hardware */
3637 break;
3638 }
3639
3640 } else if(ivideo->vbflags & VB_SISBRIDGE) {
3641
3642 char p2_01, p2_02;
3643 val /= 2;
3644 p2_01 = ivideo->p2_01;
3645 p2_02 = ivideo->p2_02;
3646
3647 p2_01 += val;
3648 p2_02 += val;
3649 while((p2_01 <= 0) || (p2_02 <= 0)) {
3650 p2_01 += 2;
3651 p2_02 += 2;
3652 }
3653 outSISIDXREG(SISPART2,0x01,p2_01);
3654 outSISIDXREG(SISPART2,0x02,p2_02);
3655 }
3656 }
3657}
3658
3659static void
3660sisfb_post_setmode(struct sis_video_info *ivideo)
3661{
3662 BOOLEAN crt1isoff = FALSE;
3663 BOOLEAN doit = TRUE;
3664#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
3665 u8 reg;
3666#endif
3667#ifdef CONFIG_FB_SIS_315
3668 u8 reg1;
3669#endif
3670
3671 outSISIDXREG(SISSR,0x05,0x86);
3672
3673#ifdef CONFIG_FB_SIS_315
3674 sisfb_fixup_SR11(ivideo);
3675#endif
3676
3677 /* Now we actually HAVE changed the display mode */
3678 ivideo->modechanged = 1;
3679
3680 /* We can't switch off CRT1 if bridge is in slave mode */
3681 if(ivideo->vbflags & VB_VIDEOBRIDGE) {
3682 if(sisfb_bridgeisslave(ivideo)) doit = FALSE;
3683 } else ivideo->sisfb_crt1off = 0;
3684
3685#ifdef CONFIG_FB_SIS_300
3686 if(ivideo->sisvga_engine == SIS_300_VGA) {
3687 if((ivideo->sisfb_crt1off) && (doit)) {
3688 crt1isoff = TRUE;
3689 reg = 0x00;
3690 } else {
3691 crt1isoff = FALSE;
3692 reg = 0x80;
3693 }
3694 setSISIDXREG(SISCR, 0x17, 0x7f, reg);
3695 }
3696#endif
3697#ifdef CONFIG_FB_SIS_315
3698 if(ivideo->sisvga_engine == SIS_315_VGA) {
3699 if((ivideo->sisfb_crt1off) && (doit)) {
3700 crt1isoff = TRUE;
3701 reg = 0x40;
3702 reg1 = 0xc0;
3703 } else {
3704 crt1isoff = FALSE;
3705 reg = 0x00;
3706 reg1 = 0x00;
3707
3708 }
3709 setSISIDXREG(SISCR, ivideo->SiS_Pr.SiS_MyCR63, ~0x40, reg);
3710 setSISIDXREG(SISSR, 0x1f, ~0xc0, reg1);
3711 }
3712#endif
3713
3714 if(crt1isoff) {
3715 ivideo->currentvbflags &= ~VB_DISPTYPE_CRT1;
3716 ivideo->currentvbflags |= VB_SINGLE_MODE;
3717 } else {
3718 ivideo->currentvbflags |= VB_DISPTYPE_CRT1;
3719 if(ivideo->currentvbflags & VB_DISPTYPE_CRT2) {
3720 ivideo->currentvbflags |= VB_MIRROR_MODE;
3721 } else {
3722 ivideo->currentvbflags |= VB_SINGLE_MODE;
3723 }
3724 }
3725
3726 andSISIDXREG(SISSR, IND_SIS_RAMDAC_CONTROL, ~0x04);
3727
3728 if(ivideo->currentvbflags & CRT2_TV) {
3729 if(ivideo->vbflags & VB_SISBRIDGE) {
3730 inSISIDXREG(SISPART2,0x1f,ivideo->p2_1f);
3731 inSISIDXREG(SISPART2,0x20,ivideo->p2_20);
3732 inSISIDXREG(SISPART2,0x2b,ivideo->p2_2b);
3733 inSISIDXREG(SISPART2,0x42,ivideo->p2_42);
3734 inSISIDXREG(SISPART2,0x43,ivideo->p2_43);
3735 inSISIDXREG(SISPART2,0x01,ivideo->p2_01);
3736 inSISIDXREG(SISPART2,0x02,ivideo->p2_02);
3737 } else if(ivideo->vbflags & VB_CHRONTEL) {
3738 if(ivideo->chronteltype == 1) {
3739 ivideo->tvx = SiS_GetCH700x(&ivideo->SiS_Pr, 0x0a);
3740 ivideo->tvx |= (((SiS_GetCH700x(&ivideo->SiS_Pr, 0x08) & 0x02) >> 1) << 8);
3741 ivideo->tvy = SiS_GetCH700x(&ivideo->SiS_Pr, 0x0b);
3742 ivideo->tvy |= ((SiS_GetCH700x(&ivideo->SiS_Pr, 0x08) & 0x01) << 8);
3743 }
3744 }
3745 }
3746
3747 if(ivideo->tvxpos) {
3748 sisfb_set_TVxposoffset(ivideo, ivideo->tvxpos);
3749 }
3750 if(ivideo->tvypos) {
3751 sisfb_set_TVyposoffset(ivideo, ivideo->tvypos);
3752 }
3753
3754 if((ivideo->currentvbflags & CRT2_TV) && (ivideo->vbflags & VB_301)) { /* Set filter for SiS301 */
3755
3756 unsigned char filter_tb = 0;
3757
3758 switch (ivideo->video_width) {
3759 case 320:
3760 filter_tb = (ivideo->vbflags & TV_NTSC) ? 4 : 12;
3761 break;
3762 case 640:
3763 filter_tb = (ivideo->vbflags & TV_NTSC) ? 5 : 13;
3764 break;
3765 case 720:
3766 filter_tb = (ivideo->vbflags & TV_NTSC) ? 6 : 14;
3767 break;
3768 case 400:
3769 case 800:
3770 filter_tb = (ivideo->vbflags & TV_NTSC) ? 7 : 15;
3771 break;
3772 default:
3773 ivideo->sisfb_filter = -1;
3774 break;
3775 }
3776
3777 orSISIDXREG(SISPART1, ivideo->CRT2_write_enable, 0x01);
3778
3779 if(ivideo->vbflags & TV_NTSC) {
3780
3781 andSISIDXREG(SISPART2, 0x3a, 0x1f);
3782
3783 if (ivideo->vbflags & TV_SVIDEO) {
3784
3785 andSISIDXREG(SISPART2, 0x30, 0xdf);
3786
3787 } else if (ivideo->vbflags & TV_AVIDEO) {
3788
3789 orSISIDXREG(SISPART2, 0x30, 0x20);
3790
3791 switch (ivideo->video_width) {
3792 case 640:
3793 outSISIDXREG(SISPART2, 0x35, 0xEB);
3794 outSISIDXREG(SISPART2, 0x36, 0x04);
3795 outSISIDXREG(SISPART2, 0x37, 0x25);
3796 outSISIDXREG(SISPART2, 0x38, 0x18);
3797 break;
3798 case 720:
3799 outSISIDXREG(SISPART2, 0x35, 0xEE);
3800 outSISIDXREG(SISPART2, 0x36, 0x0C);
3801 outSISIDXREG(SISPART2, 0x37, 0x22);
3802 outSISIDXREG(SISPART2, 0x38, 0x08);
3803 break;
3804 case 400:
3805 case 800:
3806 outSISIDXREG(SISPART2, 0x35, 0xEB);
3807 outSISIDXREG(SISPART2, 0x36, 0x15);
3808 outSISIDXREG(SISPART2, 0x37, 0x25);
3809 outSISIDXREG(SISPART2, 0x38, 0xF6);
3810 break;
3811 }
3812 }
3813
3814 } else if(ivideo->vbflags & TV_PAL) {
3815
3816 andSISIDXREG(SISPART2, 0x3A, 0x1F);
3817
3818 if (ivideo->vbflags & TV_SVIDEO) {
3819
3820 andSISIDXREG(SISPART2, 0x30, 0xDF);
3821
3822 } else if (ivideo->vbflags & TV_AVIDEO) {
3823
3824 orSISIDXREG(SISPART2, 0x30, 0x20);
3825
3826 switch (ivideo->video_width) {
3827 case 640:
3828 outSISIDXREG(SISPART2, 0x35, 0xF1);
3829 outSISIDXREG(SISPART2, 0x36, 0xF7);
3830 outSISIDXREG(SISPART2, 0x37, 0x1F);
3831 outSISIDXREG(SISPART2, 0x38, 0x32);
3832 break;
3833 case 720:
3834 outSISIDXREG(SISPART2, 0x35, 0xF3);
3835 outSISIDXREG(SISPART2, 0x36, 0x00);
3836 outSISIDXREG(SISPART2, 0x37, 0x1D);
3837 outSISIDXREG(SISPART2, 0x38, 0x20);
3838 break;
3839 case 400:
3840 case 800:
3841 outSISIDXREG(SISPART2, 0x35, 0xFC);
3842 outSISIDXREG(SISPART2, 0x36, 0xFB);
3843 outSISIDXREG(SISPART2, 0x37, 0x14);
3844 outSISIDXREG(SISPART2, 0x38, 0x2A);
3845 break;
3846 }
3847 }
3848 }
3849
3850 if((ivideo->sisfb_filter >= 0) && (ivideo->sisfb_filter <= 7)) {
3851 outSISIDXREG(SISPART2,0x35,(sis_TV_filter[filter_tb].filter[ivideo->sisfb_filter][0]));
3852 outSISIDXREG(SISPART2,0x36,(sis_TV_filter[filter_tb].filter[ivideo->sisfb_filter][1]));
3853 outSISIDXREG(SISPART2,0x37,(sis_TV_filter[filter_tb].filter[ivideo->sisfb_filter][2]));
3854 outSISIDXREG(SISPART2,0x38,(sis_TV_filter[filter_tb].filter[ivideo->sisfb_filter][3]));
3855 }
3856
3857 }
3858}
3859
3860#ifndef MODULE
3861SISINITSTATIC int __init sisfb_setup(char *options)
3862{
3863 char *this_opt;
3864
3865 sisfb_setdefaultparms();
3866
3867 printk(KERN_DEBUG "sisfb: Options %s\n", options);
3868
3869 if(!options || !(*options)) {
3870 return 0;
3871 }
3872
3873 while((this_opt = strsep(&options, ",")) != NULL) {
3874
3875 if(!(*this_opt)) continue;
3876
3877 if(!strnicmp(this_opt, "off", 3)) {
3878 sisfb_off = 1;
3879 } else if(!strnicmp(this_opt, "forcecrt2type:", 14)) {
3880 /* Need to check crt2 type first for fstn/dstn */
3881 sisfb_search_crt2type(this_opt + 14);
3882 } else if(!strnicmp(this_opt, "tvmode:",7)) {
3883 sisfb_search_tvstd(this_opt + 7);
3884 } else if(!strnicmp(this_opt, "tvstandard:",11)) {
3885 sisfb_search_tvstd(this_opt + 7);
3886 } else if(!strnicmp(this_opt, "mode:", 5)) {
3887 sisfb_search_mode(this_opt + 5, FALSE);
3888 } else if(!strnicmp(this_opt, "vesa:", 5)) {
3889 sisfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0), FALSE);
3890#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
3891 } else if(!strnicmp(this_opt, "inverse", 7)) {
3892 sisfb_inverse = 1;
3893 /* fb_invert_cmaps(); */
3894 } else if(!strnicmp(this_opt, "font:", 5)) {
3895 if(strlen(this_opt + 5) < 40) {
3896 strncpy(sisfb_fontname, this_opt + 5, sizeof(sisfb_fontname) - 1);
3897 sisfb_fontname[sizeof(sisfb_fontname) - 1] = '\0';
3898 }
3899#endif
3900 } else if(!strnicmp(this_opt, "rate:", 5)) {
3901 sisfb_parm_rate = simple_strtoul(this_opt + 5, NULL, 0);
3902 } else if(!strnicmp(this_opt, "filter:", 7)) {
3903 sisfb_filter = (int)simple_strtoul(this_opt + 7, NULL, 0);
3904 } else if(!strnicmp(this_opt, "forcecrt1:", 10)) {
3905 sisfb_forcecrt1 = (int)simple_strtoul(this_opt + 10, NULL, 0);
3906 } else if(!strnicmp(this_opt, "mem:",4)) {
3907 sisfb_parm_mem = simple_strtoul(this_opt + 4, NULL, 0);
3908 } else if(!strnicmp(this_opt, "pdc:", 4)) {
3909 sisfb_pdc = simple_strtoul(this_opt + 4, NULL, 0);
3910 } else if(!strnicmp(this_opt, "pdc1:", 5)) {
3911 sisfb_pdca = simple_strtoul(this_opt + 5, NULL, 0);
3912 } else if(!strnicmp(this_opt, "noaccel", 7)) {
3913 sisfb_accel = 0;
3914 } else if(!strnicmp(this_opt, "accel", 5)) {
3915 sisfb_accel = -1;
3916 } else if(!strnicmp(this_opt, "noypan", 6)) {
3917 sisfb_ypan = 0;
3918 } else if(!strnicmp(this_opt, "ypan", 4)) {
3919 sisfb_ypan = -1;
3920 } else if(!strnicmp(this_opt, "nomax", 5)) {
3921 sisfb_max = 0;
3922 } else if(!strnicmp(this_opt, "max", 3)) {
3923 sisfb_max = -1;
3924 } else if(!strnicmp(this_opt, "userom:", 7)) {
3925 sisfb_userom = (int)simple_strtoul(this_opt + 7, NULL, 0);
3926 } else if(!strnicmp(this_opt, "useoem:", 7)) {
3927 sisfb_useoem = (int)simple_strtoul(this_opt + 7, NULL, 0);
3928 } else if(!strnicmp(this_opt, "nocrt2rate", 10)) {
3929 sisfb_nocrt2rate = 1;
3930 } else if(!strnicmp(this_opt, "scalelcd:", 9)) {
3931 unsigned long temp = 2;
3932 temp = simple_strtoul(this_opt + 9, NULL, 0);
3933 if((temp == 0) || (temp == 1)) {
3934 sisfb_scalelcd = temp ^ 1;
3935 }
3936 } else if(!strnicmp(this_opt, "tvxposoffset:", 13)) {
3937 int temp = 0;
3938 temp = (int)simple_strtol(this_opt + 13, NULL, 0);
3939 if((temp >= -32) && (temp <= 32)) {
3940 sisfb_tvxposoffset = temp;
3941 }
3942 } else if(!strnicmp(this_opt, "tvyposoffset:", 13)) {
3943 int temp = 0;
3944 temp = (int)simple_strtol(this_opt + 13, NULL, 0);
3945 if((temp >= -32) && (temp <= 32)) {
3946 sisfb_tvyposoffset = temp;
3947 }
3948 } else if(!strnicmp(this_opt, "specialtiming:", 14)) {
3949 sisfb_search_specialtiming(this_opt + 14);
3950 } else if(!strnicmp(this_opt, "lvdshl:", 7)) {
3951 int temp = 4;
3952 temp = simple_strtoul(this_opt + 7, NULL, 0);
3953 if((temp >= 0) && (temp <= 3)) {
3954 sisfb_lvdshl = temp;
3955 }
3956 } else if(this_opt[0] >= '0' && this_opt[0] <= '9') {
3957 sisfb_search_mode(this_opt, TRUE);
3958#if !defined(__i386__) && !defined(__x86_64__)
3959 } else if(!strnicmp(this_opt, "resetcard", 9)) {
3960 sisfb_resetcard = 1;
3961 } else if(!strnicmp(this_opt, "videoram:", 9)) {
3962 sisfb_videoram = simple_strtoul(this_opt + 9, NULL, 0);
3963#endif
3964 } else {
3965 printk(KERN_INFO "sisfb: Invalid option %s\n", this_opt);
3966 }
3967
3968 }
3969
3970
3971
3972 return 0;
3973}
3974#endif
3975
3976static UCHAR * __devinit sis_find_rom(struct pci_dev *pdev)
3977{
3978 struct sis_video_info *ivideo = pci_get_drvdata(pdev);
3979 USHORT pciid;
3980 int romptr;
3981 UCHAR *myrombase;
3982 u32 temp;
3983 SIS_IOTYPE1 *rom_base, *rom;
3984
3985 if(!(myrombase = vmalloc(65536))) return NULL;
3986
3987#if defined(__i386__) || defined(__x86_64__)
3988
3989 for(temp = 0x000c0000; temp < 0x000f0000; temp += 0x00001000) {
3990
3991 rom_base = ioremap(temp, 0x10000);
3992 if(!rom_base) continue;
3993
3994 if((readb(rom_base) != 0x55) || (readb(rom_base + 1) != 0xaa)) {
3995 iounmap(rom_base);
3996 continue;
3997 }
3998
3999 romptr = (unsigned short)(readb(rom_base + 0x18) | (readb(rom_base + 0x19) << 8));
4000 if(romptr > (0x10000 - 8)) {
4001 iounmap(rom_base);
4002 continue;
4003 }
4004
4005 rom = rom_base + romptr;
4006
4007 if((readb(rom) != 'P') || (readb(rom + 1) != 'C') ||
4008 (readb(rom + 2) != 'I') || (readb(rom + 3) != 'R')) {
4009 iounmap(rom_base);
4010 continue;
4011 }
4012
4013 pciid = readb(rom + 4) | (readb(rom + 5) << 8);
4014 if(pciid != 0x1039) {
4015 iounmap(rom_base);
4016 continue;
4017 }
4018
4019 pciid = readb(rom + 6) | (readb(rom + 7) << 8);
4020 if(pciid == ivideo->chip_id) {
4021 memcpy_fromio(myrombase, rom_base, 65536);
4022 iounmap(rom_base);
4023 return myrombase;
4024 }
4025
4026 iounmap(rom_base);
4027 }
4028
4029#else
4030
4031 pci_read_config_dword(pdev, PCI_ROM_ADDRESS, &temp);
4032 pci_write_config_dword(pdev, PCI_ROM_ADDRESS,
4033 (ivideo->video_base & PCI_ROM_ADDRESS_MASK) | PCI_ROM_ADDRESS_ENABLE);
4034
4035 rom_base = ioremap(ivideo->video_base, 65536);
4036 if(rom_base) {
4037 if((readb(rom_base) == 0x55) && (readb(rom_base + 1) == 0xaa)) {
4038 romptr = (u16)(readb(rom_base + 0x18) | (readb(rom_base + 0x19) << 8));
4039 if(romptr <= (0x10000 - 8)) {
4040 rom = rom_base + romptr;
4041 if((readb(rom) == 'P') && (readb(rom + 1) == 'C') &&
4042 (readb(rom + 2) == 'I') && (readb(rom + 3) == 'R')) {
4043 pciid = readb(rom + 4) | (readb(rom + 5) << 8);
4044 if(pciid == 0x1039) {
4045 pciid = readb(rom + 6) | (readb(rom + 7) << 8);
4046 if(pciid == ivideo->chip_id) {
4047 memcpy_fromio(myrombase, rom_base, 65536);
4048 iounmap(rom_base);
4049 pci_write_config_dword(pdev, PCI_ROM_ADDRESS, temp);
4050 return myrombase;
4051 }
4052 }
4053 }
4054 }
4055 }
4056 iounmap(rom_base);
4057 }
4058 pci_write_config_dword(pdev, PCI_ROM_ADDRESS, temp);
4059
4060#endif
4061
4062 vfree(myrombase);
4063 return NULL;
4064}
4065
4066#ifdef CONFIG_FB_SIS_300
4067static int __devinit
4068sisfb_chkbuswidth300(struct pci_dev *pdev, SIS_IOTYPE1 *FBAddress)
4069{
4070 struct sis_video_info *ivideo = pci_get_drvdata(pdev);
4071 int i, j;
4072 USHORT temp;
4073 UCHAR reg;
4074
4075 andSISIDXREG(SISSR,0x15,0xFB);
4076 orSISIDXREG(SISSR,0x15,0x04);
4077 outSISIDXREG(SISSR,0x13,0x00);
4078 outSISIDXREG(SISSR,0x14,0xBF);
4079
4080 for(i=0; i<2; i++) {
4081 temp = 0x1234;
4082 for(j=0; j<4; j++) {
4083 writew(temp, FBAddress);
4084 if(readw(FBAddress) == temp) break;
4085 orSISIDXREG(SISSR,0x3c,0x01);
4086 inSISIDXREG(SISSR,0x05,reg);
4087 inSISIDXREG(SISSR,0x05,reg);
4088 andSISIDXREG(SISSR,0x3c,0xfe);
4089 inSISIDXREG(SISSR,0x05,reg);
4090 inSISIDXREG(SISSR,0x05,reg);
4091 temp++;
4092 }
4093 }
4094
4095 writel(0x01234567L, FBAddress);
4096 writel(0x456789ABL, (FBAddress+4));
4097 writel(0x89ABCDEFL, (FBAddress+8));
4098 writel(0xCDEF0123L, (FBAddress+12));
4099 inSISIDXREG(SISSR,0x3b,reg);
4100 if(reg & 0x01) {
4101 if(readl((FBAddress+12)) == 0xCDEF0123L) return(4); /* Channel A 128bit */
4102 }
4103 if(readl((FBAddress+4)) == 0x456789ABL) return(2); /* Channel B 64bit */
4104 return(1); /* 32bit */
4105}
4106
4107static void __devinit
4108sisfb_setramsize300(struct pci_dev *pdev)
4109{
4110 struct sis_video_info *ivideo = pci_get_drvdata(pdev);
4111 SIS_IOTYPE1 *FBAddr = ivideo->video_vbase;
4112 SIS_IOTYPE1 *Addr;
4113 USHORT sr13, sr14=0, buswidth, Done, data, TotalCapacity, PhysicalAdrOtherPage=0;
4114 int PseudoRankCapacity, PseudoTotalCapacity, PseudoAdrPinCount;
4115 int RankCapacity, AdrPinCount, BankNumHigh, BankNumMid, MB2Bank;
4116 int PageCapacity, PhysicalAdrHigh, PhysicalAdrHalfPage, i, j, k;
4117 const USHORT SiS_DRAMType[17][5] = {
4118 {0x0C,0x0A,0x02,0x40,0x39},
4119 {0x0D,0x0A,0x01,0x40,0x48},
4120 {0x0C,0x09,0x02,0x20,0x35},
4121 {0x0D,0x09,0x01,0x20,0x44},
4122 {0x0C,0x08,0x02,0x10,0x31},
4123 {0x0D,0x08,0x01,0x10,0x40},
4124 {0x0C,0x0A,0x01,0x20,0x34},
4125 {0x0C,0x09,0x01,0x08,0x32},
4126 {0x0B,0x08,0x02,0x08,0x21},
4127 {0x0C,0x08,0x01,0x08,0x30},
4128 {0x0A,0x08,0x02,0x04,0x11},
4129 {0x0B,0x0A,0x01,0x10,0x28},
4130 {0x09,0x08,0x02,0x02,0x01},
4131 {0x0B,0x09,0x01,0x08,0x24},
4132 {0x0B,0x08,0x01,0x04,0x20},
4133 {0x0A,0x08,0x01,0x02,0x10},
4134 {0x09,0x08,0x01,0x01,0x00}
4135 };
4136
4137 buswidth = sisfb_chkbuswidth300(pdev, FBAddr);
4138
4139 MB2Bank = 16;
4140 Done = 0;
4141 for(i = 6; i >= 0; i--) {
4142 if(Done) break;
4143 PseudoRankCapacity = 1 << i;
4144 for(j = 4; j >= 1; j--) {
4145 if(Done) break;
4146 PseudoTotalCapacity = PseudoRankCapacity * j;
4147 PseudoAdrPinCount = 15 - j;
4148 if(PseudoTotalCapacity <= 64) {
4149 for(k = 0; k <= 16; k++) {
4150 if(Done) break;
4151 RankCapacity = buswidth * SiS_DRAMType[k][3];
4152 AdrPinCount = SiS_DRAMType[k][2] + SiS_DRAMType[k][0];
4153 if(RankCapacity == PseudoRankCapacity)
4154 if(AdrPinCount <= PseudoAdrPinCount) {
4155 if(j == 3) { /* Rank No */
4156 BankNumHigh = RankCapacity * MB2Bank * 3 - 1;
4157 BankNumMid = RankCapacity * MB2Bank * 1 - 1;
4158 } else {
4159 BankNumHigh = RankCapacity * MB2Bank * j - 1;
4160 BankNumMid = RankCapacity * MB2Bank * j / 2 - 1;
4161 }
4162 PageCapacity = (1 << SiS_DRAMType[k][1]) * buswidth * 4;
4163 PhysicalAdrHigh = BankNumHigh;
4164 PhysicalAdrHalfPage = (PageCapacity / 2 + PhysicalAdrHigh) % PageCapacity;
4165 PhysicalAdrOtherPage = PageCapacity * SiS_DRAMType[k][2] + PhysicalAdrHigh;
4166 /* Write data */
4167 andSISIDXREG(SISSR,0x15,0xFB); /* Test */
4168 orSISIDXREG(SISSR,0x15,0x04); /* Test */
4169 TotalCapacity = SiS_DRAMType[k][3] * buswidth;
4170 sr13 = SiS_DRAMType[k][4];
4171 if(buswidth == 4) sr14 = (TotalCapacity - 1) | 0x80;
4172 if(buswidth == 2) sr14 = (TotalCapacity - 1) | 0x40;
4173 if(buswidth == 1) sr14 = (TotalCapacity - 1) | 0x00;
4174 outSISIDXREG(SISSR,0x13,sr13);
4175 outSISIDXREG(SISSR,0x14,sr14);
4176 Addr = FBAddr + BankNumHigh * 64 * 1024 + PhysicalAdrHigh;
4177 /* *((USHORT *)(Addr)) = (USHORT)PhysicalAdrHigh; */
4178 writew(((USHORT)PhysicalAdrHigh), Addr);
4179 Addr = FBAddr + BankNumMid * 64 * 1024 + PhysicalAdrHigh;
4180 /* *((USHORT *)(Addr)) = (USHORT)BankNumMid; */
4181 writew(((USHORT)BankNumMid), Addr);
4182 Addr = FBAddr + BankNumHigh * 64 * 1024 + PhysicalAdrHalfPage;
4183 /* *((USHORT *)(Addr)) = (USHORT)PhysicalAdrHalfPage; */
4184 writew(((USHORT)PhysicalAdrHalfPage), Addr);
4185 Addr = FBAddr + BankNumHigh * 64 * 1024 + PhysicalAdrOtherPage;
4186 /* *((USHORT *)(Addr)) = PhysicalAdrOtherPage; */
4187 writew(((USHORT)PhysicalAdrOtherPage), Addr);
4188 /* Read data */
4189 Addr = FBAddr + BankNumHigh * 64 * 1024 + PhysicalAdrHigh;
4190 data = readw(Addr); /* *((USHORT *)(Addr)); */
4191 if(data == PhysicalAdrHigh) Done = 1;
4192 } /* if */
4193 } /* for k */
4194 } /* if */
4195 } /* for j */
4196 } /* for i */
4197}
4198
4199static void __devinit sisfb_post_sis300(struct pci_dev *pdev)
4200{
4201 struct sis_video_info *ivideo = pci_get_drvdata(pdev);
4202 u8 reg, v1, v2, v3, v4, v5, v6, v7, v8;
4203 u16 index, rindex, memtype = 0;
4204
4205 outSISIDXREG(SISSR,0x05,0x86);
4206
4207 if(ivideo->sishw_ext.UseROM) {
4208 if(ivideo->sishw_ext.pjVirtualRomBase[0x52] & 0x80) {
4209 memtype = ivideo->sishw_ext.pjVirtualRomBase[0x52];
4210 } else {
4211 inSISIDXREG(SISSR,0x3a,memtype);
4212 }
4213 memtype &= 0x07;
4214 }
4215
4216 if(ivideo->revision_id <= 0x13) {
4217 v1 = 0x44; v2 = 0x42; v3 = 0x80;
4218 v4 = 0x44; v5 = 0x42; v6 = 0x80;
4219 } else {
4220 v1 = 0x68; v2 = 0x43; v3 = 0x80; /* Assume 125Mhz MCLK */
4221 v4 = 0x68; v5 = 0x43; v6 = 0x80; /* Assume 125Mhz ECLK */
4222 if(ivideo->sishw_ext.UseROM) {
4223 index = memtype * 5;
4224 rindex = index + 0x54;
4225 v1 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
4226 v2 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
4227 v3 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
4228 rindex = index + 0x7c;
4229 v4 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
4230 v5 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
4231 v6 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
4232 }
4233 }
4234 outSISIDXREG(SISSR,0x28,v1);
4235 outSISIDXREG(SISSR,0x29,v2);
4236 outSISIDXREG(SISSR,0x2a,v3);
4237 outSISIDXREG(SISSR,0x2e,v4);
4238 outSISIDXREG(SISSR,0x2f,v5);
4239 outSISIDXREG(SISSR,0x30,v6);
4240 v1 = 0x10;
4241 if(ivideo->sishw_ext.UseROM) v1 = ivideo->sishw_ext.pjVirtualRomBase[0xa4];
4242 outSISIDXREG(SISSR,0x07,v1); /* DAC speed */
4243 outSISIDXREG(SISSR,0x11,0x0f); /* DDC, power save */
4244 v1 = 0x01; v2 = 0x43; v3 = 0x1e; v4 = 0x2a;
4245 v5 = 0x06; v6 = 0x00; v7 = 0x00; v8 = 0x00;
4246 if(ivideo->sishw_ext.UseROM) {
4247 memtype += 0xa5;
4248 v1 = ivideo->sishw_ext.pjVirtualRomBase[memtype];
4249 v2 = ivideo->sishw_ext.pjVirtualRomBase[memtype + 8];
4250 v3 = ivideo->sishw_ext.pjVirtualRomBase[memtype + 16];
4251 v4 = ivideo->sishw_ext.pjVirtualRomBase[memtype + 24];
4252 v5 = ivideo->sishw_ext.pjVirtualRomBase[memtype + 32];
4253 v6 = ivideo->sishw_ext.pjVirtualRomBase[memtype + 40];
4254 v7 = ivideo->sishw_ext.pjVirtualRomBase[memtype + 48];
4255 v8 = ivideo->sishw_ext.pjVirtualRomBase[memtype + 56];
4256 }
4257 if(ivideo->revision_id >= 0x80) v3 &= 0xfd;
4258 outSISIDXREG(SISSR,0x15,v1); /* Ram type (assuming 0, BIOS 0xa5 step 8) */
4259 outSISIDXREG(SISSR,0x16,v2);
4260 outSISIDXREG(SISSR,0x17,v3);
4261 outSISIDXREG(SISSR,0x18,v4);
4262 outSISIDXREG(SISSR,0x19,v5);
4263 outSISIDXREG(SISSR,0x1a,v6);
4264 outSISIDXREG(SISSR,0x1b,v7);
4265 outSISIDXREG(SISSR,0x1c,v8); /* ---- */
4266 andSISIDXREG(SISSR,0x15,0xfb);
4267 orSISIDXREG(SISSR,0x15,0x04);
4268 if(ivideo->sishw_ext.UseROM) {
4269 if(ivideo->sishw_ext.pjVirtualRomBase[0x53] & 0x02) {
4270 orSISIDXREG(SISSR,0x19,0x20);
4271 }
4272 }
4273 v1 = 0x04; /* DAC pedestal (BIOS 0xe5) */
4274 if(ivideo->revision_id >= 0x80) v1 |= 0x01;
4275 outSISIDXREG(SISSR,0x1f,v1);
4276 outSISIDXREG(SISSR,0x20,0xa0); /* linear & relocated io */
4277 v1 = 0xf6; v2 = 0x0d; v3 = 0x00;
4278 if(ivideo->sishw_ext.UseROM) {
4279 v1 = ivideo->sishw_ext.pjVirtualRomBase[0xe8];
4280 v2 = ivideo->sishw_ext.pjVirtualRomBase[0xe9];
4281 v3 = ivideo->sishw_ext.pjVirtualRomBase[0xea];
4282 }
4283 outSISIDXREG(SISSR,0x23,v1);
4284 outSISIDXREG(SISSR,0x24,v2);
4285 outSISIDXREG(SISSR,0x25,v3);
4286 outSISIDXREG(SISSR,0x21,0x84);
4287 outSISIDXREG(SISSR,0x22,0x00);
4288 outSISIDXREG(SISCR,0x37,0x00);
4289 orSISIDXREG(SISPART1,0x24,0x01); /* unlock crt2 */
4290 outSISIDXREG(SISPART1,0x00,0x00);
4291 v1 = 0x40; v2 = 0x11;
4292 if(ivideo->sishw_ext.UseROM) {
4293 v1 = ivideo->sishw_ext.pjVirtualRomBase[0xec];
4294 v2 = ivideo->sishw_ext.pjVirtualRomBase[0xeb];
4295 }
4296 outSISIDXREG(SISPART1,0x02,v1);
4297 if(ivideo->revision_id >= 0x80) v2 &= ~0x01;
4298 inSISIDXREG(SISPART4,0x00,reg);
4299 if((reg == 1) || (reg == 2)) {
4300 outSISIDXREG(SISCR,0x37,0x02);
4301 outSISIDXREG(SISPART2,0x00,0x1c);
4302 v4 = 0x00; v5 = 0x00; v6 = 0x10;
4303 if(ivideo->sishw_ext.UseROM) {
4304 v4 = ivideo->sishw_ext.pjVirtualRomBase[0xf5];
4305 v5 = ivideo->sishw_ext.pjVirtualRomBase[0xf6];
4306 v6 = ivideo->sishw_ext.pjVirtualRomBase[0xf7];
4307 }
4308 outSISIDXREG(SISPART4,0x0d,v4);
4309 outSISIDXREG(SISPART4,0x0e,v5);
4310 outSISIDXREG(SISPART4,0x10,v6);
4311 outSISIDXREG(SISPART4,0x0f,0x3f);
4312 inSISIDXREG(SISPART4,0x01,reg);
4313 if(reg >= 0xb0) {
4314 inSISIDXREG(SISPART4,0x23,reg);
4315 reg &= 0x20;
4316 reg <<= 1;
4317 outSISIDXREG(SISPART4,0x23,reg);
4318 }
4319 } else {
4320 v2 &= ~0x10;
4321 }
4322 outSISIDXREG(SISSR,0x32,v2);
4323 andSISIDXREG(SISPART1,0x24,0xfe); /* Lock CRT2 */
4324 inSISIDXREG(SISSR,0x16,reg);
4325 reg &= 0xc3;
4326 outSISIDXREG(SISCR,0x35,reg);
4327 outSISIDXREG(SISCR,0x83,0x00);
4328#if !defined(__i386__) && !defined(__x86_64__)
4329 if(sisfb_videoram) {
4330 outSISIDXREG(SISSR,0x13,0x28); /* ? */
4331 reg = ((sisfb_videoram >> 10) - 1) | 0x40;
4332 outSISIDXREG(SISSR,0x14,reg);
4333 } else {
4334#endif
4335 /* Need to map max FB size for finding out about RAM size */
4336 ivideo->video_vbase = ioremap(ivideo->video_base, 0x4000000);
4337 if(ivideo->video_vbase) {
4338 sisfb_setramsize300(pdev);
4339 iounmap(ivideo->video_vbase);
4340 } else {
4341 printk(KERN_DEBUG "sisfb: Failed to map memory for size detection, assuming 8MB\n");
4342 outSISIDXREG(SISSR,0x13,0x28); /* ? */
4343 outSISIDXREG(SISSR,0x14,0x47); /* 8MB, 64bit default */
4344 }
4345#if !defined(__i386__) && !defined(__x86_64__)
4346 }
4347#endif
4348 if(ivideo->sishw_ext.UseROM) {
4349 v1 = ivideo->sishw_ext.pjVirtualRomBase[0xe6];
4350 v2 = ivideo->sishw_ext.pjVirtualRomBase[0xe7];
4351 } else {
4352 inSISIDXREG(SISSR,0x3a,reg);
4353 if((reg & 0x30) == 0x30) {
4354 v1 = 0x04; /* PCI */
4355 v2 = 0x92;
4356 } else {
4357 v1 = 0x14; /* AGP */
4358 v2 = 0xb2;
4359 }
4360 }
4361 outSISIDXREG(SISSR,0x21,v1);
4362 outSISIDXREG(SISSR,0x22,v2);
4363}
4364#endif
4365
4366#ifdef CONFIG_FB_SIS_315
4367static void __devinit sisfb_post_sis315330(struct pci_dev *pdev)
4368{
4369#ifdef YET_TO_BE_DONE
4370 struct sis_video_info *ivideo = pci_get_drvdata(pdev);
4371 u8 reg, v1, v2, v3, v4, v5, v6, v7, v8;
4372 u16 index, rindex, memtype = 0;
4373 u32 reg1_32, reg2_32, reg3_32;
4374 int i;
4375
4376 /* Unlock */
4377 /* outSISIDXREG(0x3c4,0x05,0x86); */
4378 outSISIDXREG(SISSR,0x05,0x86);
4379
4380 /* Enable relocated i/o ports */
4381 /* setSISIDXREG(0x3c4,0x20,~0x10,0x20); */
4382 setSISIDXREG(SISSR,0x20,~0x10,0x20);
4383
4384 /* Clear regs */
4385 for(i = 0; i < 0x22; i++) {
4386 outSISIDXREG(SISSR,(0x06 + i),0x00);
4387 }
4388 v1 = 0x0d;
4389 if( is 330) v1 = 0x0b;
4390 for(i = 0; i < v1; i++) {
4391 outSISIDXREG(SISSR,(0x31 + i),0x00);
4392 }
4393 for(i = 0; i < 0x10; i++) {
4394 outSISIDXREG(SISCR,(0x30 + i),0x00);
4395 }
4396
4397 /* Reset clocks */
4398 reg = inSISREG(SISMISCR);
4399 outSISIDXREG(SISSR,0x28,0x81);
4400 outSISIDXREG(SISSR,0x2A,0x00);
4401 outSISIDXREG(SISSR,0x29,0xE1);
4402 outSISREG(SISMISCW,(reg | 0x0c));
4403 outSISIDXREG(SISSR,0x2B,0x81);
4404 outSISIDXREG(SISSR,0x2D,0x00);
4405 outSISIDXREG(SISSR,0x2C,0xE1);
4406 outSISIDXREG(SISSR,0x2E,0x81);
4407 outSISIDXREG(SISSR,0x30,0x00);
4408 outSISIDXREG(SISSR,0x2F,0xE1);
4409 SiS_DDC2Delay(....);
4410 outSISREG(SISMISCW,reg);
4411
4412 /* Get memory type */
4413 if(ivideo->sishw_ext.UseROM) {
4414 if(ivideo->sishw_ext.pjVirtualRomBase[0x52] & 0x80)) {
4415 memtype = ivideo->sishw_ext.pjVirtualRomBase[0x52];
4416 } else {
4417 inSISIDXREG(SISSR,0x3a,memtype);
4418 }
4419 memtype &= 0x03;
4420 if( is 330 ) {
4421 if(memtype <= 1) memtype = 0;
4422 else {
4423 inSISIDXREG(SISCR,0x5F,reg);
4424 reg &= 0x30;
4425 switch(reg) {
4426 case 0x00: memtype = 1; break;
4427 case 0x10: memtype = 3; break;
4428 case 0x20: memtype = 3; break;
4429 default: memtype = 2;
4430 }
4431 }
4432 }
4433 }
4434
4435 /* Set clocks */
4436 v1 = 0x3b; v2 = 0x22; v3 = 0x01; /* Assume 143Mhz MCLK */
4437 v4 = 0x5c; v5 = 0x23; v6 = 0x01; /* Assume 166Mhz ECLK */
4438 if(ivideo->sishw_ext.UseROM) {
4439 index = memtype * 5;
4440 rindex = index + 0x54;
4441 v1 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
4442 v2 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
4443 v3 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
4444 rindex = index + 0x68;
4445 v4 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
4446 v5 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
4447 v6 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
4448 }
4449 outSISIDXREG(SISSR,0x28,v1);
4450 outSISIDXREG(SISSR,0x29,v2);
4451 outSISIDXREG(SISSR,0x2a,v3);
4452 if( is 330 ) {
4453 inSISIDXREG(SISSR,0x3a,reg);
4454 reg &= 0x03;
4455 if(reg >= 2) {
4456 ...
4457 }
4458 }
4459 outSISIDXREG(SISSR,0x2e,v4);
4460 outSISIDXREG(SISSR,0x2f,v5);
4461 outSISIDXREG(SISSR,0x30,v6);
4462
4463 /* End of comp with 330 */
4464
4465 v1 = 0x18;
4466 if(ivideo->sishw_ext.UseROM) v1 = ivideo->sishw_ext.pjVirtualRomBase[0x7c];
4467 outSISIDXREG(SISSR,0x07,v1);
4468 outSISIDXREG(SISSR,0x11,0x0f);
4469
4470 v1 = 0x00; v2 = 0x0f; v3 = 0xba; v4 = 0xa9;
4471 v5 = 0xa0; v6 = 0x00; v7 = 0x30;
4472 if(ivideo->sishw_ext.UseROM) {
4473 index = memtype + 0x7d;
4474 v1 = ivideo->sishw_ext.pjVirtualRomBase[index];
4475 v2 = ivideo->sishw_ext.pjVirtualRomBase[index + 4];
4476 v3 = ivideo->sishw_ext.pjVirtualRomBase[index + 8];
4477 v4 = ivideo->sishw_ext.pjVirtualRomBase[index + 12];
4478 v5 = ivideo->sishw_ext.pjVirtualRomBase[index + 16];
4479 v6 = ivideo->sishw_ext.pjVirtualRomBase[index + 20];
4480 v7 = ivideo->sishw_ext.pjVirtualRomBase[index + 24];
4481 }
4482 outSISIDXREG(SISSR,0x15,v1); /* Ram type (assuming 0, BIOS 0x7d step 4) */
4483 outSISIDXREG(SISSR,0x16,v2);
4484 outSISIDXREG(SISSR,0x17,v3);
4485 outSISIDXREG(SISSR,0x18,v4);
4486 outSISIDXREG(SISSR,0x19,v5);
4487 outSISIDXREG(SISSR,0x1a,v6);
4488 outSISIDXREG(SISSR,0x1b,v7);
4489 outSISIDXREG(SISSR,0x1c,v8); /* ---- */
4490
4491 v1 = 0x77; v2 = 0x77; v3 = 0x00; v4 = 0x5b; v5 = 0x00;
4492 if(ivideo->sishw_ext.UseROM) {
4493 index = memtype + 0xa2;
4494 v1 = ivideo->sishw_ext.pjVirtualRomBase[index];
4495 v2 = ivideo->sishw_ext.pjVirtualRomBase[index + 4];
4496 v3 = ivideo->sishw_ext.pjVirtualRomBase[index + 8];
4497 v4 = ivideo->sishw_ext.pjVirtualRomBase[index + 12];
4498 v5 = ivideo->sishw_ext.pjVirtualRomBase[index + 16];
4499 }
4500 outSISIDXREG(SISCR,0x40,v1);
4501 outSISIDXREG(SISCR,0x41,v2);
4502 outSISIDXREG(SISCR,0x42,v3);
4503 outSISIDXREG(SISCR,0x43,v4);
4504 outSISIDXREG(SISCR,0x44,v5);
4505
4506 if( is 330 ) {
4507
4508 v1 = 0x;
4509 if(ivideo->sishw_ext.UseROM) {
4510 v1 = ivideo->sishw_ext.pjVirtualRomBase[0xBA];
4511 }
4512 outSISIDXREG(SISCR,0x59,v1);
4513
4514 v1 = 0x; v2 = 0x; v3 = 0x; v4 = 0x;
4515 v5 = 0x; v6 = 0x; v7 = 0x; v8 = 0x;
4516 if(ivideo->sishw_ext.UseROM) {
4517 index = memtype + 0xbe;
4518 v1 = ivideo->sishw_ext.pjVirtualRomBase[index];
4519 v2 = ivideo->sishw_ext.pjVirtualRomBase[index + 4];
4520 v3 = ivideo->sishw_ext.pjVirtualRomBase[index + 8];
4521 v4 = ivideo->sishw_ext.pjVirtualRomBase[index + 12];
4522 v5 = ivideo->sishw_ext.pjVirtualRomBase[index + 16];
4523 v6 = ivideo->sishw_ext.pjVirtualRomBase[index + 20];
4524 v7 = ivideo->sishw_ext.pjVirtualRomBase[index + 24];
4525 v8 = ivideo->sishw_ext.pjVirtualRomBase[index + 28];
4526 }
4527 outSISIDXREG(SISCR,0x68,v1);
4528 outSISIDXREG(SISCR,0x69,v2);
4529 outSISIDXREG(SISCR,0x6a,v3);
4530 outSISIDXREG(SISCR,0x6b,v4);
4531 outSISIDXREG(SISCR,0x6c,v5);
4532 outSISIDXREG(SISCR,0x6d,v6);
4533 outSISIDXREG(SISCR,0x6e,v7);
4534 outSISIDXREG(SISCR,0x6f,v8);
4535
4536 v1 = 0x20;
4537 inSISIDXREG(SISSR,0x3b,reg);
4538
4539 if(!(reg & 0x04)) {
4540 inSISIDXREG(SISCR,0x5F,reg);
4541 reg &= 0x30;
4542 if(reg) v1 = 0x23;
4543 }
4544 outSISIDXREG(SISCR,0x48,v1);
4545 outSISIDXREG(SISCR,0x4c,0x20);
4546
4547 xx= xxx();
4548 if(xx >= 1) {
4549 v1 = 0x;
4550 if(ivideo->sishw_ext.UseROM) {
4551 v1 = ivideo->sishw_ext.pjVirtualRomBase[0xBA];
4552 }
4553 outSISIDXREG(SISCR,0x59,v1);
4554 }
4555
4556
4557
4558 } else {
4559
4560 outSISIDXREG(SISCR,0x48,0x23);
4561
4562 andSISIDXREG(SISSR,0x16,0x0f);
4563 if(memtype <= 1) {
4564 orSISIDXREG(SISSR,0x16,0x80);
4565 } else {
4566 v1 = 0x0f;
4567 if(ivideo->sishw_ext.UseROM) {
4568 v1 = ivideo->sishw_ext.pjVirtualRomBase[0x81 + memtype];
4569 }
4570 if(!(v1 & 0x10)) v2 = 0xc0;
4571 else v2 = 0xd0;
4572 orSISIDXREG(SISSR,0x16,v2);
4573 andSISIDXREG(SISSR,0x16,0x0f);
4574 if(!(v1 & 0x10)) v2 = 0x80;
4575 else v2 = 0xA0;
4576 orSISIDXREG(SISSR,0x16,v2);
4577 }
4578
4579 if(memtype >= 2) {
4580 const u8 sr3cseq1[] = { 0xc0,0xe0,0xf0,0xe0,0xf0,0xa0,0xb0,0xa0,0xb0,0x90,0xd0 };
4581 const u8 sr3cseq2[] = { 0xc0,0xa0,0xb0,0xa0,0xb0,0xe0,0xf0,0xa0,0xb0,0x90,0xd0 };
4582 for(i = 0; i < 11; i++) {
4583 outSISIDXREG(SISSR,0x3c,sr3cseq1[i]);
4584 }
4585 outSISIDXREG(SISSR,0x3d,0x00);
4586 outSISIDXREG(SISSR,0x3d,0x04);
4587 SiS_DDC2Delay(0x200);
4588 v1 = inSISIDXREG(SISCR,0xEC);
4589 v2 = inSISIDXREG(SISCR,0xED);
4590 reg1_32 = (v2 << 8) | v1;
4591 outSISIDXREG(SISSR,0x3D,0x00);
4592 for(i = 0; i < 11; i++) {
4593 outSISIDXREG(SISSR,0x3c,sr3cseq2[i]);
4594 }
4595 outSISIDXREG(SISSR,0x3d,0x00);
4596 outSISIDXREG(SISSR,0x3d,0x04);
4597 SiS_DDC2Delay(0x200);
4598 v1 = inSISIDXREG(SISCR,0xEC);
4599 v2 = inSISIDXREG(SISCR,0xED);
4600 reg2_32 = (v2 << 8) | v1;
4601 outSISIDXREG(SISSR,0x3D,0x00);
4602 reg3_32 = reg2_32 << 1;
4603 reg2_32 >>= 1;
4604 reg3_32 += reg2_32;
4605 v1 = 0x40;
4606 if(reg3_32 > reg1_32) v1 = 0x10;
4607 outSISIDXREG(SISCR,0x59,v1);
4608 }
4609
4610 }
4611
4612 v1 = 0x00;
4613 if(ivideo->sishw_ext.UseROM) {
4614 v1 = ivideo->sishw_ext.pjVirtualRomBase[0x99];
4615 }
4616 outSISIDXREG(SISSR,0x1f,v1);
4617
4618 outSISIDXREG(SISSR,0x20,0x20);
4619
4620 v1 = 0xf6; v2 = 0x0d; v3 = 0x33;
4621 if(ivideo->sishw_ext.UseROM) {
4622 v1 = ivideo->sishw_ext.pjVirtualRomBase[0x9c];
4623 v2 = ivideo->sishw_ext.pjVirtualRomBase[0x9d];
4624 v3 = ivideo->sishw_ext.pjVirtualRomBase[0x9e];
4625 }
4626 outSISIDXREG(SISSR,0x23,v1);
4627 outSISIDXREG(SISSR,0x24,v2);
4628 outSISIDXREG(SISSR,0x25,v3);
4629
4630 outSISIDXREG(SISSR,0x21,0x84);
4631 outSISIDXREG(SISSR,0x22,0x00);
4632 outSISIDXREG(SISSR,0x27,0x1f);
4633
4634 v1 = 0x00; v2 = 0x00;
4635 if(ivideo->sishw_ext.UseROM) {
4636 v1 = ivideo->sishw_ext.pjVirtualRomBase[0x9F];
4637 v2 = ivideo->sishw_ext.pjVirtualRomBase[0xA1];
4638 }
4639 outSISIDXREG(SISSR,0x31,v1);
4640 outSISIDXREG(SISSR,0x33,v2);
4641
4642 v1 = 0x11;
4643 if(ivideo->sishw_ext.UseROM) {
4644 v1 = ivideo->sishw_ext.pjVirtualRomBase[0xA0];
4645 }
4646 v2 = inSISIDXREG(SISPART4,0x00);
4647 if((v2 != 1) && (v2 != 2)) v1 &= 0xef;
4648 outSISIDXREG(SISSR,0x32,v1);
4649
4650 /* AGP */
4651 pci_read_config_long(pdev, 0x50, &reg1_32);
4652 reg1_32 >>= 20;
4653 reg1_32 &= 0x0f;
4654 if(reg1_32 == 1) {
4655 v1 = 0xAA; v2 = 0x33;
4656 if(ivideo->sishw_ext.UseROM) {
4657 v1 = ivideo->sishw_ext.pjVirtualRomBase[0xF7];
4658 v2 = ivideo->sishw_ext.pjVirtualRomBase[0x9E];
4659 }
4660 } else {
4661 v1 = 0x88; v2 = 0x03;
4662 if(ivideo->sishw_ext.UseROM) {
4663 v1 = ivideo->sishw_ext.pjVirtualRomBase[0xF8];
4664 v2 = ivideo->sishw_ext.pjVirtualRomBase[0xF6];
4665 }
4666 }
4667 outSISIDXREG(SISCR,0x49,v1);
4668 outSISIDXREG(SISSR,0x25,v2);
4669
4670 v1 = inSISIDXREG(SISPART4,0x00);
4671 if((v1 == 1) || (v1 == 2)) {
4672 orSISIDXREG(SISPART1,0x2F,0x01); /* Unlock CRT2 */
4673 outSISIDXREG(SISPART1,0x00,0x00);
4674 v1 = 0x00;
4675 if(ivideo->sishw_ext.UseROM) {
4676 v1 = ivideo->sishw_ext.pjVirtualRomBase[0xb6];
4677 }
4678 outSISIDXREG(SISPART1,0x02,v1);
4679 outSISIDXREG(SISPART1,0x2E,0x08);
4680 outSISIDXREG(SISPART2,0x00,0x1c);
4681 v1 = 0x40; v2 = 0x00; v3 = 0x80;
4682 if(ivideo->sishw_ext.UseROM) {
4683 v1 = ivideo->sishw_ext.pjVirtualRomBase[0xb7];
4684 v2 = ivideo->sishw_ext.pjVirtualRomBase[0xb8];
4685 v3 = ivideo->sishw_ext.pjVirtualRomBase[0xbb];
4686 }
4687 outSISIDXREG(SISPART4,0x0d,v1);
4688 outSISIDXREG(SISPART4,0x0e,v2);
4689 outSISIDXREG(SISPART4,0x10,v3);
4690 outSISIDXREG(SISPART4,0x0F,0x3F);
4691
4692 inSISIDXREG(SISPART4,0x01,reg);
4693 if(reg >= 0xb0) {
4694 inSISIDXREG(SISPART4,0x23,reg);
4695 reg &= 0x20;
4696 reg <<= 1;
4697 outSISIDXREG(SISPART4,0x23,reg);
4698 }
4699 }
4700 outSISIDXREG(SISCR,0x37,0x02); /* Why? */
4701
4702 outSISIDXREG(SISCR,0x83,0x00);
4703 outSISIDXREG(SISCR,0x90,0x00);
4704 andSISIDXREG(SISSR,0x5B,0xDF);
4705 outSISIDXREG(SISVID,0x00,0x86);
4706 outSISIDXREG(SISVID,0x32,0x00);
4707 outSISIDXREG(SISVID,0x30,0x00);
4708 outSISIDXREG(SISVID,0x32,0x01);
4709 outSISIDXREG(SISVID,0x30,0x00);
4710 orSISIDXREG(SISCR,0x63,0x80);
4711 /* End of Init1 */
4712
4713 /* Set Mode 0x2e */
4714
4715 /* Ramsize */
4716 orSISIDXREG(SISSR,0x16,0x0f);
4717 orSISIDXREG(SISSR,0x18,0xA9);
4718 orSISIDXREG(SISSR,0x19,0xA0);
4719 orSISIDXREG(SISSR,0x1B,0x30);
4720 andSISIDXREG(SISSR,0x17,0xF8);
4721 orSISIDXREG(SISSR,0x19,0x03);
4722 andSIDIDXREG(SISSR,0x13,0x00);
4723
4724 /* Need to map max FB size for finding out about RAM size */
4725 ivideo->video_vbase = ioremap(ivideo->video_base, 0x4000000);
4726 if(ivideo->video_vbase) {
4727 /* Find out about bus width */
4728 if(memtype <= 1) {
4729 outSISIDXREG(SISSR,0x14,0x02);
4730 andSISIDXREG(SISSR,0x16,0x0F);
4731 orSISIDXREG(SISSR,0x16,0x80);
4732
4733 ...
4734
4735 } else {
4736
4737 ...
4738
4739 }
4740
4741 /* Find out about size */
4742
4743
4744 iounmap(ivideo->video_vbase);
4745 } else {
4746 printk(KERN_DEBUG "sisfb: Failed to map memory for size detection, assuming 8MB\n");
4747 outSISIDXREG(SISSR,0x14,0x??); /* 8MB, 64bit default */
4748 }
4749
4750 /* AGP (Missing: Checks for VIA and AMD hosts) */
4751 v1 = 0xA5; v2 = 0xFB;
4752 if(ivideo->sishw_ext.UseROM) {
4753 v1 = ivideo->sishw_ext.pjVirtualRomBase[0x9A];
4754 v2 = ivideo->sishw_ext.pjVirtualRomBase[0x9B];
4755 }
4756 outSISIDXREG(SISSR,0x21,v1);
4757 outSISIDXREG(SISSR,0x22,v2);
4758
4759#endif
4760 return;
4761}
4762#endif
4763
4764
4765int __devinit sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
4766{
4767 struct sisfb_chip_info *chipinfo = &sisfb_chip_info[ent->driver_data];
4768 struct sis_video_info *ivideo = NULL;
4769 struct fb_info *sis_fb_info = NULL;
4770 u16 reg16;
4771 u8 reg;
4772 int sisvga_enabled = 0, i;
4773
4774 if(sisfb_off) return -ENXIO;
4775
4776#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,3))
4777 sis_fb_info = framebuffer_alloc(sizeof(*ivideo), &pdev->dev);
4778 if(!sis_fb_info) return -ENOMEM;
4779#else
4780 sis_fb_info = kmalloc(sizeof(*sis_fb_info) + sizeof(*ivideo), GFP_KERNEL);
4781 if(!sis_fb_info) return -ENOMEM;
4782 memset(sis_fb_info, 0, sizeof(*sis_fb_info) + sizeof(*ivideo));
4783 sis_fb_info->par = ((char *)sis_fb_info + sizeof(*sis_fb_info));
4784#endif
4785
4786 ivideo = (struct sis_video_info *)sis_fb_info->par;
4787 ivideo->memyselfandi = sis_fb_info;
4788
4789 if(card_list == NULL) {
4790 ivideo->cardnumber = 0;
4791 } else {
4792 struct sis_video_info *countvideo = card_list;
4793 ivideo->cardnumber = 1;
4794 while((countvideo = countvideo->next) != NULL) ivideo->cardnumber++;
4795 }
4796
4797 strncpy(ivideo->myid, chipinfo->chip_name, 30);
4798
4799 ivideo->warncount = 0;
4800 ivideo->chip_id = pdev->device;
4801 pci_read_config_byte(pdev, PCI_REVISION_ID, &ivideo->revision_id);
4802 ivideo->sishw_ext.jChipRevision = ivideo->revision_id;
4803 pci_read_config_word(pdev, PCI_COMMAND, &reg16);
4804 sisvga_enabled = reg16 & 0x01;
4805 ivideo->pcibus = pdev->bus->number;
4806 ivideo->pcislot = PCI_SLOT(pdev->devfn);
4807 ivideo->pcifunc = PCI_FUNC(pdev->devfn);
4808 ivideo->subsysvendor = pdev->subsystem_vendor;
4809 ivideo->subsysdevice = pdev->subsystem_device;
4810
4811#ifndef MODULE
4812 if(sisfb_mode_idx == -1) {
4813 sisfb_get_vga_mode_from_kernel();
4814 }
4815#endif
4816
4817 ivideo->chip = chipinfo->chip;
4818 ivideo->sisvga_engine = chipinfo->vgaengine;
4819 ivideo->hwcursor_size = chipinfo->hwcursor_size;
4820 ivideo->CRT2_write_enable = chipinfo->CRT2_write_enable;
4821 ivideo->mni = chipinfo->mni;
4822
4823 ivideo->detectedpdc = 0xff;
4824 ivideo->detectedpdca = 0xff;
4825 ivideo->detectedlcda = 0xff;
4826
4827 ivideo->sisfb_thismonitor.datavalid = FALSE;
4828
4829 ivideo->sisfb_parm_mem = sisfb_parm_mem;
4830 ivideo->sisfb_accel = sisfb_accel;
4831 ivideo->sisfb_ypan = sisfb_ypan;
4832 ivideo->sisfb_max = sisfb_max;
4833 ivideo->sisfb_userom = sisfb_userom;
4834 ivideo->sisfb_useoem = sisfb_useoem;
4835 ivideo->sisfb_mode_idx = sisfb_mode_idx;
4836 ivideo->sisfb_parm_rate = sisfb_parm_rate;
4837 ivideo->sisfb_crt1off = sisfb_crt1off;
4838 ivideo->sisfb_forcecrt1 = sisfb_forcecrt1;
4839 ivideo->sisfb_crt2type = sisfb_crt2type;
4840 ivideo->sisfb_crt2flags = sisfb_crt2flags;
4841 /* pdc(a), scalelcd, special timing, lvdshl handled below */
4842 ivideo->sisfb_dstn = sisfb_dstn;
4843 ivideo->sisfb_fstn = sisfb_fstn;
4844 ivideo->sisfb_tvplug = sisfb_tvplug;
4845 ivideo->sisfb_tvstd = sisfb_tvstd;
4846 ivideo->tvxpos = sisfb_tvxposoffset;
4847 ivideo->tvypos = sisfb_tvyposoffset;
4848 ivideo->sisfb_filter = sisfb_filter;
4849 ivideo->sisfb_nocrt2rate = sisfb_nocrt2rate;
4850#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
4851 ivideo->sisfb_inverse = sisfb_inverse;
4852#endif
4853
4854 ivideo->refresh_rate = 0;
4855 if(ivideo->sisfb_parm_rate != -1) {
4856 ivideo->refresh_rate = ivideo->sisfb_parm_rate;
4857 }
4858
4859 ivideo->SiS_Pr.UsePanelScaler = sisfb_scalelcd;
4860 ivideo->SiS_Pr.CenterScreen = -1;
4861 ivideo->SiS_Pr.SiS_CustomT = sisfb_specialtiming;
4862 ivideo->SiS_Pr.LVDSHL = sisfb_lvdshl;
4863
4864 ivideo->SiS_Pr.SiS_Backup70xx = 0xff;
4865 ivideo->SiS_Pr.SiS_CHOverScan = -1;
4866 ivideo->SiS_Pr.SiS_ChSW = FALSE;
4867 ivideo->SiS_Pr.SiS_UseLCDA = FALSE;
4868 ivideo->SiS_Pr.HaveEMI = FALSE;
4869 ivideo->SiS_Pr.HaveEMILCD = FALSE;
4870 ivideo->SiS_Pr.OverruleEMI = FALSE;
4871 ivideo->SiS_Pr.SiS_SensibleSR11 = FALSE;
4872 ivideo->SiS_Pr.SiS_MyCR63 = 0x63;
4873 ivideo->SiS_Pr.PDC = -1;
4874 ivideo->SiS_Pr.PDCA = -1;
4875#ifdef CONFIG_FB_SIS_315
4876 if(ivideo->chip >= SIS_330) {
4877 ivideo->SiS_Pr.SiS_MyCR63 = 0x53;
4878 if(ivideo->chip >= SIS_661) {
4879 ivideo->SiS_Pr.SiS_SensibleSR11 = TRUE;
4880 }
4881 }
4882#endif
4883
4884 memcpy(&ivideo->default_var, &my_default_var, sizeof(my_default_var));
4885
4886 pci_set_drvdata(pdev, ivideo);
4887
4888 /* Patch special cases */
4889 if((ivideo->nbridge = sisfb_get_northbridge(ivideo->chip))) {
4890 switch(ivideo->nbridge->device) {
4891#ifdef CONFIG_FB_SIS_300
4892 case PCI_DEVICE_ID_SI_730:
4893 ivideo->chip = SIS_730;
4894 strcpy(ivideo->myid, "SiS 730");
4895 break;
4896#endif
4897#ifdef CONFIG_FB_SIS_315
4898 case PCI_DEVICE_ID_SI_651:
4899 /* ivideo->chip is ok */
4900 strcpy(ivideo->myid, "SiS 651");
4901 break;
4902 case PCI_DEVICE_ID_SI_740:
4903 ivideo->chip = SIS_740;
4904 strcpy(ivideo->myid, "SiS 740");
4905 break;
4906 case PCI_DEVICE_ID_SI_661:
4907 ivideo->chip = SIS_661;
4908 strcpy(ivideo->myid, "SiS 661");
4909 break;
4910 case PCI_DEVICE_ID_SI_741:
4911 ivideo->chip = SIS_741;
4912 strcpy(ivideo->myid, "SiS 741");
4913 break;
4914 case PCI_DEVICE_ID_SI_760:
4915 ivideo->chip = SIS_760;
4916 strcpy(ivideo->myid, "SiS 760");
4917 break;
4918#endif
4919 }
4920 }
4921
4922#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
4923 strcpy(sis_fb_info->modename, ivideo->myid);
4924#endif
4925
4926 ivideo->sishw_ext.jChipType = ivideo->chip;
4927
4928#ifdef CONFIG_FB_SIS_315
4929 if((ivideo->sishw_ext.jChipType == SIS_315PRO) ||
4930 (ivideo->sishw_ext.jChipType == SIS_315)) {
4931 ivideo->sishw_ext.jChipType = SIS_315H;
4932 }
4933#endif
4934
4935 ivideo->video_base = pci_resource_start(pdev, 0);
4936 ivideo->mmio_base = pci_resource_start(pdev, 1);
4937 ivideo->mmio_size = pci_resource_len(pdev, 1);
4938 ivideo->SiS_Pr.RelIO = pci_resource_start(pdev, 2) + 0x30;
4939 ivideo->sishw_ext.ulIOAddress = ivideo->vga_base = ivideo->SiS_Pr.RelIO;
4940
4941 if(!sisvga_enabled) {
4942 if(pci_enable_device(pdev)) {
4943 pci_set_drvdata(pdev, NULL);
4944 kfree(sis_fb_info);
4945 return -EIO;
4946 }
4947 }
4948
4949 SiSRegInit(&ivideo->SiS_Pr, ivideo->sishw_ext.ulIOAddress);
4950
4951#ifdef CONFIG_FB_SIS_300
4952 /* Find PCI systems for Chrontel/GPIO communication setup */
4953 if(ivideo->chip == SIS_630) {
4954 i=0;
4955 do {
4956 if(mychswtable[i].subsysVendor == ivideo->subsysvendor &&
4957 mychswtable[i].subsysCard == ivideo->subsysdevice) {
4958 ivideo->SiS_Pr.SiS_ChSW = TRUE;
4959 printk(KERN_DEBUG "sisfb: Identified [%s %s] requiring Chrontel/GPIO setup\n",
4960 mychswtable[i].vendorName, mychswtable[i].cardName);
4961 break;
4962 }
4963 i++;
4964 } while(mychswtable[i].subsysVendor != 0);
4965 }
4966#endif
4967
4968 outSISIDXREG(SISSR, 0x05, 0x86);
4969
4970 if( (!sisvga_enabled)
4971#if !defined(__i386__) && !defined(__x86_64__)
4972 || (sisfb_resetcard)
4973#endif
4974 ) {
4975 for(i = 0x30; i <= 0x3f; i++) {
4976 outSISIDXREG(SISCR,i,0x00);
4977 }
4978 }
4979
4980 /* Find out about current video mode */
4981 ivideo->modeprechange = 0x03;
4982 inSISIDXREG(SISCR,0x34,reg);
4983 if(reg & 0x7f) {
4984 ivideo->modeprechange = reg & 0x7f;
4985 } else if(sisvga_enabled) {
4986#if defined(__i386__) || defined(__x86_64__)
4987 unsigned char SIS_IOTYPE2 *tt = ioremap(0, 0x1000);
4988 if(tt) {
4989 ivideo->modeprechange = readb(tt + 0x449);
4990 iounmap(tt);
4991 }
4992#endif
4993 }
4994
4995#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
4996#ifdef MODULE
4997 if((reg & 0x80) && (reg != 0xff)) {
4998 if((sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni]) != 0xFF) {
4999 printk(KERN_INFO "sisfb: Cannot initialize display mode, X server is active\n");
5000 pci_set_drvdata(pdev, NULL);
5001 kfree(sis_fb_info);
5002 return -EBUSY;
5003 }
5004 }
5005#endif
5006#endif
5007
5008 ivideo->sishw_ext.bIntegratedMMEnabled = TRUE;
5009#ifdef CONFIG_FB_SIS_300
5010 if(ivideo->sisvga_engine == SIS_300_VGA) {
5011 if(ivideo->chip != SIS_300) {
5012 inSISIDXREG(SISSR, 0x1a, reg);
5013 if(!(reg & 0x10)) {
5014 ivideo->sishw_ext.bIntegratedMMEnabled = FALSE;
5015 }
5016 }
5017 }
5018#endif
5019
5020 ivideo->bios_abase = NULL;
5021 if(ivideo->sisfb_userom) {
5022 ivideo->sishw_ext.pjVirtualRomBase = sis_find_rom(pdev);
5023 ivideo->bios_abase = ivideo->sishw_ext.pjVirtualRomBase;
5024 if(ivideo->sishw_ext.pjVirtualRomBase) {
5025 printk(KERN_INFO "sisfb: Video ROM found and copied\n");
5026 ivideo->sishw_ext.UseROM = TRUE;
5027 } else {
5028 ivideo->sishw_ext.UseROM = FALSE;
5029 printk(KERN_INFO "sisfb: Video ROM not found\n");
5030 }
5031 } else {
5032 ivideo->sishw_ext.pjVirtualRomBase = NULL;
5033 ivideo->sishw_ext.UseROM = FALSE;
5034 printk(KERN_INFO "sisfb: Video ROM usage disabled\n");
5035 }
5036
5037 /* Find systems for special custom timing */
5038 if(ivideo->SiS_Pr.SiS_CustomT == CUT_NONE) {
5039 int j;
5040 unsigned char *biosver = NULL;
5041 unsigned char *biosdate = NULL;
5042 BOOLEAN footprint;
5043 u32 chksum = 0;
5044
5045 if(ivideo->sishw_ext.UseROM) {
5046 biosver = ivideo->sishw_ext.pjVirtualRomBase + 0x06;
5047 biosdate = ivideo->sishw_ext.pjVirtualRomBase + 0x2c;
5048 for(i=0; i<32768; i++) chksum += ivideo->sishw_ext.pjVirtualRomBase[i];
5049 }
5050
5051 i=0;
5052 do {
5053 if( (mycustomttable[i].chipID == ivideo->chip) &&
5054 ((!strlen(mycustomttable[i].biosversion)) ||
5055 (ivideo->sishw_ext.UseROM &&
5056 (!strncmp(mycustomttable[i].biosversion, biosver, strlen(mycustomttable[i].biosversion))))) &&
5057 ((!strlen(mycustomttable[i].biosdate)) ||
5058 (ivideo->sishw_ext.UseROM &&
5059 (!strncmp(mycustomttable[i].biosdate, biosdate, strlen(mycustomttable[i].biosdate))))) &&
5060 ((!mycustomttable[i].bioschksum) ||
5061 (ivideo->sishw_ext.UseROM &&
5062 (mycustomttable[i].bioschksum == chksum))) &&
5063 (mycustomttable[i].pcisubsysvendor == ivideo->subsysvendor) &&
5064 (mycustomttable[i].pcisubsyscard == ivideo->subsysdevice) ) {
5065 footprint = TRUE;
5066 for(j = 0; j < 5; j++) {
5067 if(mycustomttable[i].biosFootprintAddr[j]) {
5068 if(ivideo->sishw_ext.UseROM) {
5069 if(ivideo->sishw_ext.pjVirtualRomBase[mycustomttable[i].biosFootprintAddr[j]] !=
5070 mycustomttable[i].biosFootprintData[j]) {
5071 footprint = FALSE;
5072 }
5073 } else footprint = FALSE;
5074 }
5075 }
5076 if(footprint) {
5077 ivideo->SiS_Pr.SiS_CustomT = mycustomttable[i].SpecialID;
5078 printk(KERN_DEBUG "sisfb: Identified [%s %s], special timing applies\n",
5079 mycustomttable[i].vendorName,
5080 mycustomttable[i].cardName);
5081 printk(KERN_DEBUG "sisfb: [specialtiming parameter name: %s]\n",
5082 mycustomttable[i].optionName);
5083 break;
5084 }
5085 }
5086 i++;
5087 } while(mycustomttable[i].chipID);
5088 }
5089
5090#ifdef CONFIG_FB_SIS_300
5091 if(ivideo->sisvga_engine == SIS_300_VGA) {
5092 if( (!sisvga_enabled)
5093#if !defined(__i386__) && !defined(__x86_64__)
5094 || (sisfb_resetcard)
5095#endif
5096 ) {
5097 if(ivideo->chip == SIS_300) {
5098 sisfb_post_sis300(pdev);
5099 }
5100 }
5101 }
5102#endif
5103
5104#ifdef CONFIG_FB_SIS_315
5105 if(ivideo->sisvga_engine == SIS_315_VGA) {
5106 if( (!sisvga_enabled)
5107#if !defined(__i386__) && !defined(__x86_64__)
5108 || (sisfb_resetcard)
5109#endif
5110 ) {
5111 if((ivideo->chip == SIS_315H) ||
5112 (ivideo->chip == SIS_315) ||
5113 (ivideo->chip == SIS_315PRO) ||
5114 (ivideo->chip == SIS_330)) {
5115 sisfb_post_sis315330(pdev);
5116 }
5117 }
5118 }
5119#endif
5120
5121 if(sisfb_get_dram_size(ivideo)) {
5122 printk(KERN_INFO "sisfb: Fatal error: Unable to determine RAM size.\n");
5123 if(ivideo->bios_abase) vfree(ivideo->bios_abase);
5124 pci_set_drvdata(pdev, NULL);
5125 kfree(sis_fb_info);
5126 return -ENODEV;
5127 }
5128
5129 if((ivideo->sisfb_mode_idx < 0) ||
5130 ((sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni]) != 0xFF)) {
5131 /* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE */
5132 orSISIDXREG(SISSR, IND_SIS_PCI_ADDRESS_SET, (SIS_PCI_ADDR_ENABLE | SIS_MEM_MAP_IO_ENABLE));
5133 /* Enable 2D accelerator engine */
5134 orSISIDXREG(SISSR, IND_SIS_MODULE_ENABLE, SIS_ENABLE_2D);
5135 }
5136
5137 if(sisfb_pdc != 0xff) {
5138 if(ivideo->sisvga_engine == SIS_300_VGA) sisfb_pdc &= 0x3c;
5139 else sisfb_pdc &= 0x1f;
5140 ivideo->SiS_Pr.PDC = sisfb_pdc;
5141 }
5142#ifdef CONFIG_FB_SIS_315
5143 if(ivideo->sisvga_engine == SIS_315_VGA) {
5144 if(sisfb_pdca != 0xff) ivideo->SiS_Pr.PDCA = sisfb_pdca & 0x1f;
5145 }
5146#endif
5147
5148 if(!request_mem_region(ivideo->video_base, ivideo->video_size, "sisfb FB")) {
5149 printk(KERN_ERR "sisfb: Fatal error: Unable to reserve frame buffer memory\n");
5150 printk(KERN_ERR "sisfb: Is there another framebuffer driver active?\n");
5151 if(ivideo->bios_abase) vfree(ivideo->bios_abase);
5152 pci_set_drvdata(pdev, NULL);
5153 kfree(sis_fb_info);
5154 return -ENODEV;
5155 }
5156
5157 if(!request_mem_region(ivideo->mmio_base, ivideo->mmio_size, "sisfb MMIO")) {
5158 printk(KERN_ERR "sisfb: Fatal error: Unable to reserve MMIO region\n");
5159 release_mem_region(ivideo->video_base, ivideo->video_size);
5160 if(ivideo->bios_abase) vfree(ivideo->bios_abase);
5161 pci_set_drvdata(pdev, NULL);
5162 kfree(sis_fb_info);
5163 return -ENODEV;
5164 }
5165
5166 ivideo->video_vbase = ioremap(ivideo->video_base, ivideo->video_size);
5167 ivideo->sishw_ext.pjVideoMemoryAddress = ivideo->video_vbase;
5168 if(!ivideo->video_vbase) {
5169 printk(KERN_ERR "sisfb: Fatal error: Unable to map frame buffer memory\n");
5170 release_mem_region(ivideo->video_base, ivideo->video_size);
5171 release_mem_region(ivideo->mmio_base, ivideo->mmio_size);
5172 if(ivideo->bios_abase) vfree(ivideo->bios_abase);
5173 pci_set_drvdata(pdev, NULL);
5174 kfree(sis_fb_info);
5175 return -ENODEV;
5176 }
5177
5178 ivideo->mmio_vbase = ioremap(ivideo->mmio_base, ivideo->mmio_size);
5179 if(!ivideo->mmio_vbase) {
5180 printk(KERN_ERR "sisfb: Fatal error: Unable to map MMIO region\n");
5181 iounmap(ivideo->video_vbase);
5182 release_mem_region(ivideo->video_base, ivideo->video_size);
5183 release_mem_region(ivideo->mmio_base, ivideo->mmio_size);
5184 if(ivideo->bios_abase) vfree(ivideo->bios_abase);
5185 pci_set_drvdata(pdev, NULL);
5186 kfree(sis_fb_info);
5187 return -ENODEV;
5188 }
5189
5190 printk(KERN_INFO "sisfb: Framebuffer at 0x%lx, mapped to 0x%lx, size %ldk\n",
5191 ivideo->video_base, (ULONG)ivideo->video_vbase, ivideo->video_size / 1024);
5192
5193 printk(KERN_INFO "sisfb: MMIO at 0x%lx, mapped to 0x%lx, size %ldk\n",
5194 ivideo->mmio_base, (ULONG)ivideo->mmio_vbase, ivideo->mmio_size / 1024);
5195
5196 if((ivideo->havenoheap = sisfb_heap_init(ivideo))) {
5197 printk(KERN_WARNING "sisfb: Failed to initialize offscreen memory heap\n");
5198 }
5199
5200 /* Used for clearing the screen only, therefore respect our mem limit */
5201 ivideo->sishw_ext.ulVideoMemorySize = ivideo->sisfb_mem;
5202
5203 ivideo->mtrr = 0;
5204
5205 ivideo->vbflags = 0;
5206 ivideo->lcddefmodeidx = DEFAULT_LCDMODE;
5207 ivideo->tvdefmodeidx = DEFAULT_TVMODE;
5208 ivideo->defmodeidx = DEFAULT_MODE;
5209
5210 ivideo->newrom = SiSDetermineROMLayout661(&ivideo->SiS_Pr, &ivideo->sishw_ext);
5211
5212 if((ivideo->sisfb_mode_idx < 0) ||
5213 ((sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni]) != 0xFF)) {
5214
5215 sisfb_sense_crt1(ivideo);
5216
5217 sisfb_get_VB_type(ivideo);
5218
5219 if(ivideo->vbflags & VB_VIDEOBRIDGE) {
5220 sisfb_detect_VB_connect(ivideo);
5221 }
5222
5223 ivideo->currentvbflags = ivideo->vbflags & (VB_VIDEOBRIDGE | TV_STANDARD);
5224
5225 if(ivideo->vbflags & VB_VIDEOBRIDGE) {
5226 if(ivideo->sisfb_crt2type != -1) {
5227 if((ivideo->sisfb_crt2type == CRT2_LCD) && (ivideo->vbflags & CRT2_LCD)) {
5228 ivideo->currentvbflags |= CRT2_LCD;
5229 } else if(ivideo->sisfb_crt2type != CRT2_LCD) {
5230 ivideo->currentvbflags |= ivideo->sisfb_crt2type;
5231 }
5232 } else {
5233 /* Chrontel 700x TV detection often unreliable, therefore use a
5234 * different default order on such machines
5235 */
5236 if((ivideo->sisvga_engine == SIS_300_VGA) && (ivideo->vbflags & VB_CHRONTEL)) {
5237 if(ivideo->vbflags & CRT2_LCD) ivideo->currentvbflags |= CRT2_LCD;
5238 else if(ivideo->vbflags & CRT2_TV) ivideo->currentvbflags |= CRT2_TV;
5239 else if(ivideo->vbflags & CRT2_VGA) ivideo->currentvbflags |= CRT2_VGA;
5240 } else {
5241 if(ivideo->vbflags & CRT2_TV) ivideo->currentvbflags |= CRT2_TV;
5242 else if(ivideo->vbflags & CRT2_LCD) ivideo->currentvbflags |= CRT2_LCD;
5243 else if(ivideo->vbflags & CRT2_VGA) ivideo->currentvbflags |= CRT2_VGA;
5244 }
5245 }
5246 }
5247
5248 if(ivideo->vbflags & CRT2_LCD) {
5249 inSISIDXREG(SISCR, 0x36, reg);
5250 reg &= 0x0f;
5251 if(ivideo->sisvga_engine == SIS_300_VGA) {
5252 ivideo->CRT2LCDType = sis300paneltype[reg];
5253 } else if(ivideo->chip >= SIS_661) {
5254 ivideo->CRT2LCDType = sis661paneltype[reg];
5255 } else {
5256 ivideo->CRT2LCDType = sis310paneltype[reg];
5257 if((ivideo->chip == SIS_550) && (sisfb_fstn)) {
5258 if((ivideo->CRT2LCDType != LCD_640x480_2) &&
5259 (ivideo->CRT2LCDType != LCD_640x480_3)) {
5260 ivideo->CRT2LCDType = LCD_320x480;
5261 }
5262 }
5263 }
5264 if(ivideo->CRT2LCDType == LCD_UNKNOWN) {
5265 /* For broken BIOSes: Assume 1024x768, RGB18 */
5266 ivideo->CRT2LCDType = LCD_1024x768;
5267 setSISIDXREG(SISCR,0x36,0xf0,0x02);
5268 setSISIDXREG(SISCR,0x37,0xee,0x01);
5269 printk(KERN_DEBUG "sisfb: Invalid panel ID (%02x), assuming 1024x768, RGB18\n", reg);
5270 }
5271 for(i = 0; i < SIS_LCD_NUMBER; i++) {
5272 if(ivideo->CRT2LCDType == sis_lcd_data[i].lcdtype) {
5273 ivideo->lcdxres = sis_lcd_data[i].xres;
5274 ivideo->lcdyres = sis_lcd_data[i].yres;
5275 ivideo->lcddefmodeidx = sis_lcd_data[i].default_mode_idx;
5276 break;
5277 }
5278 }
5279 if(ivideo->SiS_Pr.SiS_CustomT == CUT_BARCO1366) {
5280 ivideo->lcdxres = 1360; ivideo->lcdyres = 1024; ivideo->lcddefmodeidx = 99;
5281 } else if(ivideo->SiS_Pr.SiS_CustomT == CUT_PANEL848) {
5282 ivideo->lcdxres = 848; ivideo->lcdyres = 480; ivideo->lcddefmodeidx = 47;
5283 }
5284 printk(KERN_DEBUG "sisfb: Detected %dx%d flat panel\n",
5285 ivideo->lcdxres, ivideo->lcdyres);
5286 }
5287
5288#ifdef CONFIG_FB_SIS_300
5289 /* Save the current PanelDelayCompensation if the LCD is currently used */
5290 if(ivideo->sisvga_engine == SIS_300_VGA) {
5291 if(ivideo->vbflags & (VB_LVDS | VB_30xBDH)) {
5292 int tmp;
5293 inSISIDXREG(SISCR,0x30,tmp);
5294 if(tmp & 0x20) {
5295 /* Currently on LCD? If yes, read current pdc */
5296 inSISIDXREG(SISPART1,0x13,ivideo->detectedpdc);
5297 ivideo->detectedpdc &= 0x3c;
5298 if(ivideo->SiS_Pr.PDC == -1) {
5299 /* Let option override detection */
5300 ivideo->SiS_Pr.PDC = ivideo->detectedpdc;
5301 }
5302 printk(KERN_INFO "sisfb: Detected LCD PDC 0x%02x\n",
5303 ivideo->detectedpdc);
5304 }
5305 if((ivideo->SiS_Pr.PDC != -1) && (ivideo->SiS_Pr.PDC != ivideo->detectedpdc)) {
5306 printk(KERN_INFO "sisfb: Using LCD PDC 0x%02x\n",
5307 ivideo->SiS_Pr.PDC);
5308 }
5309 }
5310 }
5311#endif
5312
5313#ifdef CONFIG_FB_SIS_315
5314 if(ivideo->sisvga_engine == SIS_315_VGA) {
5315
5316 /* Try to find about LCDA */
5317 if(ivideo->vbflags & (VB_301C | VB_302B | VB_301LV | VB_302LV | VB_302ELV)) {
5318 int tmp;
5319 inSISIDXREG(SISPART1,0x13,tmp);
5320 if(tmp & 0x04) {
5321 ivideo->SiS_Pr.SiS_UseLCDA = TRUE;
5322 ivideo->detectedlcda = 0x03;
5323 }
5324 }
5325
5326 /* Save PDC */
5327 if(ivideo->vbflags & (VB_301LV | VB_302LV | VB_302ELV)) {
5328 int tmp;
5329 inSISIDXREG(SISCR,0x30,tmp);
5330 if((tmp & 0x20) || (ivideo->detectedlcda != 0xff)) {
5331 /* Currently on LCD? If yes, read current pdc */
5332 u8 pdc;
5333 inSISIDXREG(SISPART1,0x2D,pdc);
5334 ivideo->detectedpdc = (pdc & 0x0f) << 1;
5335 ivideo->detectedpdca = (pdc & 0xf0) >> 3;
5336 inSISIDXREG(SISPART1,0x35,pdc);
5337 ivideo->detectedpdc |= ((pdc >> 7) & 0x01);
5338 inSISIDXREG(SISPART1,0x20,pdc);
5339 ivideo->detectedpdca |= ((pdc >> 6) & 0x01);
5340 if(ivideo->newrom) {
5341 /* New ROM invalidates other PDC resp. */
5342 if(ivideo->detectedlcda != 0xff) {
5343 ivideo->detectedpdc = 0xff;
5344 } else {
5345 ivideo->detectedpdca = 0xff;
5346 }
5347 }
5348 if(ivideo->SiS_Pr.PDC == -1) {
5349 if(ivideo->detectedpdc != 0xff) {
5350 ivideo->SiS_Pr.PDC = ivideo->detectedpdc;
5351 }
5352 }
5353 if(ivideo->SiS_Pr.PDCA == -1) {
5354 if(ivideo->detectedpdca != 0xff) {
5355 ivideo->SiS_Pr.PDCA = ivideo->detectedpdca;
5356 }
5357 }
5358 if(ivideo->detectedpdc != 0xff) {
5359 printk(KERN_INFO
5360 "sisfb: Detected LCD PDC 0x%02x (for LCD=CRT2)\n",
5361 ivideo->detectedpdc);
5362 }
5363 if(ivideo->detectedpdca != 0xff) {
5364 printk(KERN_INFO
5365 "sisfb: Detected LCD PDC1 0x%02x (for LCD=CRT1)\n",
5366 ivideo->detectedpdca);
5367 }
5368 }
5369
5370 /* Save EMI */
5371 if(ivideo->vbflags & (VB_302LV | VB_302ELV)) {
5372 inSISIDXREG(SISPART4,0x30,ivideo->SiS_Pr.EMI_30);
5373 inSISIDXREG(SISPART4,0x31,ivideo->SiS_Pr.EMI_31);
5374 inSISIDXREG(SISPART4,0x32,ivideo->SiS_Pr.EMI_32);
5375 inSISIDXREG(SISPART4,0x33,ivideo->SiS_Pr.EMI_33);
5376 ivideo->SiS_Pr.HaveEMI = TRUE;
5377 if((tmp & 0x20) || (ivideo->detectedlcda != 0xff)) {
5378 ivideo->SiS_Pr.HaveEMILCD = TRUE;
5379 }
5380 }
5381 }
5382
5383 /* Let user override detected PDCs (all bridges) */
5384 if(ivideo->vbflags & (VB_301B | VB_301C | VB_301LV | VB_302LV | VB_302ELV)) {
5385 if((ivideo->SiS_Pr.PDC != -1) && (ivideo->SiS_Pr.PDC != ivideo->detectedpdc)) {
5386 printk(KERN_INFO "sisfb: Using LCD PDC 0x%02x (for LCD=CRT2)\n",
5387 ivideo->SiS_Pr.PDC);
5388 }
5389 if((ivideo->SiS_Pr.PDCA != -1) && (ivideo->SiS_Pr.PDCA != ivideo->detectedpdca)) {
5390 printk(KERN_INFO "sisfb: Using LCD PDC1 0x%02x (for LCD=CRT1)\n",
5391 ivideo->SiS_Pr.PDCA);
5392 }
5393 }
5394
5395 }
5396#endif
5397
5398 if(!ivideo->sisfb_crt1off) {
5399 sisfb_handle_ddc(ivideo, &ivideo->sisfb_thismonitor, 0);
5400 } else {
5401 if((ivideo->vbflags & (VB_301|VB_301B|VB_301C|VB_302B)) &&
5402 (ivideo->vbflags & (CRT2_VGA | CRT2_LCD))) {
5403 sisfb_handle_ddc(ivideo, &ivideo->sisfb_thismonitor, 1);
5404 }
5405 }
5406
5407 if(ivideo->sisfb_mode_idx >= 0) {
5408 int bu = ivideo->sisfb_mode_idx;
5409 ivideo->sisfb_mode_idx = sisfb_validate_mode(ivideo,
5410 ivideo->sisfb_mode_idx, ivideo->currentvbflags);
5411 if(bu != ivideo->sisfb_mode_idx) {
5412 printk(KERN_ERR "Mode %dx%dx%d failed validation\n",
5413 sisbios_mode[bu].xres,
5414 sisbios_mode[bu].yres,
5415 sisbios_mode[bu].bpp);
5416 }
5417 }
5418
5419 if(ivideo->sisfb_mode_idx < 0) {
5420 switch(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {
5421 case CRT2_LCD:
5422 ivideo->sisfb_mode_idx = ivideo->lcddefmodeidx;
5423 break;
5424 case CRT2_TV:
5425 ivideo->sisfb_mode_idx = ivideo->tvdefmodeidx;
5426 break;
5427 default:
5428 ivideo->sisfb_mode_idx = ivideo->defmodeidx;
5429 break;
5430 }
5431 }
5432
5433 ivideo->mode_no = sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni];
5434
5435 if(ivideo->refresh_rate != 0) {
5436 sisfb_search_refresh_rate(ivideo, ivideo->refresh_rate, ivideo->sisfb_mode_idx);
5437 }
5438
5439 if(ivideo->rate_idx == 0) {
5440 ivideo->rate_idx = sisbios_mode[ivideo->sisfb_mode_idx].rate_idx;
5441 ivideo->refresh_rate = 60;
5442 }
5443
5444 if(ivideo->sisfb_thismonitor.datavalid) {
5445 if(!sisfb_verify_rate(ivideo, &ivideo->sisfb_thismonitor, ivideo->sisfb_mode_idx,
5446 ivideo->rate_idx, ivideo->refresh_rate)) {
5447 printk(KERN_INFO "sisfb: WARNING: Refresh rate exceeds monitor specs!\n");
5448 }
5449 }
5450
5451 ivideo->video_bpp = sisbios_mode[ivideo->sisfb_mode_idx].bpp;
5452 ivideo->video_width = sisbios_mode[ivideo->sisfb_mode_idx].xres;
5453 ivideo->video_height = sisbios_mode[ivideo->sisfb_mode_idx].yres;
5454
5455 sisfb_set_vparms(ivideo);
5456
5457#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
5458
5459 /* ---------------- For 2.4: Now switch the mode ------------------ */
5460
5461 printk(KERN_INFO "sisfb: Mode is %dx%dx%d (%dHz)\n",
5462 ivideo->video_width, ivideo->video_height, ivideo->video_bpp,
5463 ivideo->refresh_rate);
5464
5465 sisfb_pre_setmode(ivideo);
5466
5467 if(SiSSetMode(&ivideo->SiS_Pr, &ivideo->sishw_ext, ivideo->mode_no) == 0) {
5468 printk(KERN_ERR "sisfb: Fatal error: Setting mode[0x%x] failed\n",
5469 ivideo->mode_no);
5470 iounmap(ivideo->video_vbase);
5471 iounmap(ivideo->mmio_vbase);
5472 release_mem_region(ivideo->video_base, ivideo->video_size);
5473 release_mem_region(ivideo->mmio_base, ivideo->mmio_size);
5474 if(ivideo->bios_abase) vfree(ivideo->bios_abase);
5475 pci_set_drvdata(pdev, NULL);
5476 kfree(sis_fb_info);
5477 return -EINVAL;
5478 }
5479
5480 outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
5481
5482 sisfb_post_setmode(ivideo);
5483
5484 /* Maximize regardless of sisfb_max at startup */
5485 ivideo->default_var.yres_virtual = 32767;
5486
5487 /* Force reset of x virtual in crtc_to_var */
5488 ivideo->default_var.xres_virtual = 0;
5489
5490 sisfb_crtc_to_var(ivideo, &ivideo->default_var);
5491
5492 sisfb_calc_pitch(ivideo, &ivideo->default_var);
5493 sisfb_set_pitch(ivideo);
5494
5495 ivideo->accel = 0;
5496 if(ivideo->sisfb_accel) {
5497 ivideo->accel = -1;
5498 ivideo->default_var.accel_flags |= FB_ACCELF_TEXT;
5499 }
5500 sisfb_initaccel(ivideo);
5501
5502 sis_fb_info->node = -1;
5503 sis_fb_info->flags = FBINFO_FLAG_DEFAULT;
5504 sis_fb_info->fbops = &sisfb_ops;
5505 sis_fb_info->disp = &ivideo->sis_disp;
5506 sis_fb_info->blank = &sisfb_blank;
5507 sis_fb_info->switch_con = &sisfb_switch;
5508 sis_fb_info->updatevar = &sisfb_update_var;
5509 sis_fb_info->changevar = NULL;
5510 strcpy(sis_fb_info->fontname, sisfb_fontname);
5511
5512 sisfb_set_disp(-1, &ivideo->default_var, sis_fb_info);
5513
5514#else /* --------- For 2.6: Setup a somewhat sane default var ------------ */
5515
5516 printk(KERN_INFO "sisfb: Default mode is %dx%dx%d (%dHz)\n",
5517 ivideo->video_width, ivideo->video_height, ivideo->video_bpp,
5518 ivideo->refresh_rate);
5519
5520 ivideo->default_var.xres = ivideo->default_var.xres_virtual = ivideo->video_width;
5521 ivideo->default_var.yres = ivideo->default_var.yres_virtual = ivideo->video_height;
5522 ivideo->default_var.bits_per_pixel = ivideo->video_bpp;
5523
5524 sisfb_bpp_to_var(ivideo, &ivideo->default_var);
5525
5526 ivideo->default_var.pixclock = (u32) (1000000000 /
5527 sisfb_mode_rate_to_dclock(&ivideo->SiS_Pr, &ivideo->sishw_ext,
5528 ivideo->mode_no, ivideo->rate_idx));
5529
5530 if(sisfb_mode_rate_to_ddata(&ivideo->SiS_Pr, &ivideo->sishw_ext,
5531 ivideo->mode_no, ivideo->rate_idx, &ivideo->default_var)) {
5532 if((ivideo->default_var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
5533 ivideo->default_var.pixclock <<= 1;
5534 }
5535 }
5536
5537 if(ivideo->sisfb_ypan) {
5538 /* Maximize regardless of sisfb_max at startup */
5539 ivideo->default_var.yres_virtual = sisfb_calc_maxyres(ivideo, &ivideo->default_var);
5540 if(ivideo->default_var.yres_virtual < ivideo->default_var.yres) {
5541 ivideo->default_var.yres_virtual = ivideo->default_var.yres;
5542 }
5543 }
5544
5545 sisfb_calc_pitch(ivideo, &ivideo->default_var);
5546
5547 ivideo->accel = 0;
5548 if(ivideo->sisfb_accel) {
5549 ivideo->accel = -1;
5550#ifdef STUPID_ACCELF_TEXT_SHIT
5551 ivideo->default_var.accel_flags |= FB_ACCELF_TEXT;
5552#endif
5553 }
5554 sisfb_initaccel(ivideo);
5555
5556#if defined(FBINFO_HWACCEL_DISABLED) && defined(FBINFO_HWACCEL_XPAN)
5557 sis_fb_info->flags = FBINFO_DEFAULT |
5558 FBINFO_HWACCEL_YPAN |
5559 FBINFO_HWACCEL_XPAN |
5560 FBINFO_HWACCEL_COPYAREA |
5561 FBINFO_HWACCEL_FILLRECT |
5562 ((ivideo->accel) ? 0 : FBINFO_HWACCEL_DISABLED);
5563#else
5564 sis_fb_info->flags = FBINFO_FLAG_DEFAULT;
5565#endif
5566 sis_fb_info->var = ivideo->default_var;
5567 sis_fb_info->fix = ivideo->sisfb_fix;
5568 sis_fb_info->screen_base = ivideo->video_vbase;
5569 sis_fb_info->fbops = &sisfb_ops;
5570
5571 sisfb_get_fix(&sis_fb_info->fix, -1, sis_fb_info);
5572 sis_fb_info->pseudo_palette = ivideo->pseudo_palette;
5573
5574 fb_alloc_cmap(&sis_fb_info->cmap, 256 , 0);
5575#endif /* 2.6 */
5576
5577 printk(KERN_DEBUG "sisfb: Initial vbflags 0x%lx\n", (unsigned long)ivideo->vbflags);
5578
5579#ifdef CONFIG_MTRR
5580 ivideo->mtrr = mtrr_add(ivideo->video_base, ivideo->video_size,
5581 MTRR_TYPE_WRCOMB, 1);
5582 if(!ivideo->mtrr) {
5583 printk(KERN_DEBUG "sisfb: Failed to add MTRRs\n");
5584 }
5585#endif
5586
5587#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
5588 vc_resize_con(1, 1, 0);
5589#endif
5590
5591 if(register_framebuffer(sis_fb_info) < 0) {
5592 printk(KERN_ERR "sisfb: Fatal error: Failed to register framebuffer\n");
5593 iounmap(ivideo->video_vbase);
5594 iounmap(ivideo->mmio_vbase);
5595 release_mem_region(ivideo->video_base, ivideo->video_size);
5596 release_mem_region(ivideo->mmio_base, ivideo->mmio_size);
5597 if(ivideo->bios_abase) vfree(ivideo->bios_abase);
5598 pci_set_drvdata(pdev, NULL);
5599 kfree(sis_fb_info);
5600 return -EINVAL;
5601 }
5602
5603 ivideo->registered = 1;
5604
5605 /* Enlist us */
5606 ivideo->next = card_list;
5607 card_list = ivideo;
5608
5609 printk(KERN_INFO "sisfb: 2D acceleration is %s, y-panning %s\n",
5610 ivideo->sisfb_accel ? "enabled" : "disabled",
5611 ivideo->sisfb_ypan ?
5612 (ivideo->sisfb_max ? "enabled (auto-max)" : "enabled (no auto-max)") : "disabled");
5613
5614
5615 printk(KERN_INFO "fb%d: %s frame buffer device, Version %d.%d.%d\n",
5616#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
5617 GET_FB_IDX(sis_fb_info->node),
5618#else
5619 sis_fb_info->node,
5620#endif
5621 ivideo->myid, VER_MAJOR, VER_MINOR, VER_LEVEL);
5622
5623 printk(KERN_INFO "sisfb: (C) 2001-2004 Thomas Winischhofer.\n");
5624
5625 } /* if mode = "none" */
5626
5627 return 0;
5628}
5629
5630/*****************************************************/
5631/* PCI DEVICE HANDLING */
5632/*****************************************************/
5633
5634static void __devexit sisfb_remove(struct pci_dev *pdev)
5635{
5636 struct sis_video_info *ivideo = pci_get_drvdata(pdev);
5637 struct fb_info *sis_fb_info = ivideo->memyselfandi;
5638 int registered = ivideo->registered;
5639
5640 /* Unmap */
5641 iounmap(ivideo->video_vbase);
5642 iounmap(ivideo->mmio_vbase);
5643 vfree(ivideo->bios_abase);
5644
5645 /* Release mem regions */
5646 release_mem_region(ivideo->video_base, ivideo->video_size);
5647 release_mem_region(ivideo->mmio_base, ivideo->mmio_size);
5648
5649#ifdef CONFIG_MTRR
5650 /* Release MTRR region */
5651 if(ivideo->mtrr) {
5652 mtrr_del(ivideo->mtrr, ivideo->video_base, ivideo->video_size);
5653 }
5654#endif
5655
5656 /* Unregister the framebuffer */
5657 if(ivideo->registered) {
5658 unregister_framebuffer(sis_fb_info);
5659#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,3))
5660 framebuffer_release(sis_fb_info);
5661#else
5662 kfree(sis_fb_info);
5663#endif
5664 }
5665
5666 pci_set_drvdata(pdev, NULL);
5667
5668 /* TODO: Restore the initial mode
5669 * This sounds easy but is as good as impossible
5670 * on many machines with SiS chip and video bridge
5671 * since text modes are always set up differently
5672 * from machine to machine. Depends on the type
5673 * of integration between chipset and bridge.
5674 */
5675 if(registered) {
5676 printk(KERN_INFO "sisfb: Restoring of text mode not supported yet\n");
5677 }
5678};
5679
5680static struct pci_driver sisfb_driver = {
5681 .name = "sisfb",
5682 .id_table = sisfb_pci_table,
5683 .probe = sisfb_probe,
5684 .remove = __devexit_p(sisfb_remove)
5685};
5686
5687SISINITSTATIC int __init sisfb_init(void)
5688{
5689#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)
5690#ifndef MODULE
5691 char *options = NULL;
5692
5693 if(fb_get_options("sisfb", &options))
5694 return -ENODEV;
5695 sisfb_setup(options);
5696#endif
5697#endif
5698 return(pci_register_driver(&sisfb_driver));
5699}
5700
5701#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)
5702#ifndef MODULE
5703module_init(sisfb_init);
5704#endif
5705#endif
5706
5707/*****************************************************/
5708/* MODULE */
5709/*****************************************************/
5710
5711#ifdef MODULE
5712
5713static char *mode = NULL;
5714static int vesa = -1;
5715static unsigned int rate = 0;
5716static unsigned int crt1off = 1;
5717static unsigned int mem = 0;
5718static char *forcecrt2type = NULL;
5719static int forcecrt1 = -1;
5720static int pdc = -1;
5721static int pdc1 = -1;
5722static int noaccel = -1;
5723static int noypan = -1;
5724static int nomax = -1;
5725#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
5726static int inverse = 0;
5727#endif
5728static int userom = -1;
5729static int useoem = -1;
5730static char *tvstandard = NULL;
5731static int nocrt2rate = 0;
5732static int scalelcd = -1;
5733static char *specialtiming = NULL;
5734static int lvdshl = -1;
5735static int tvxposoffset = 0, tvyposoffset = 0;
5736static int filter = -1;
5737#if !defined(__i386__) && !defined(__x86_64__)
5738static int resetcard = 0;
5739static int videoram = 0;
5740#endif
5741
5742MODULE_DESCRIPTION("SiS 300/540/630/730/315/550/65x/661/74x/330/760 framebuffer device driver");
5743MODULE_LICENSE("GPL");
5744MODULE_AUTHOR("Thomas Winischhofer <thomas@winischhofer.net>, Others");
5745
5746#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
5747MODULE_PARM(mem, "i");
5748MODULE_PARM(noaccel, "i");
5749MODULE_PARM(noypan, "i");
5750MODULE_PARM(nomax, "i");
5751MODULE_PARM(userom, "i");
5752MODULE_PARM(useoem, "i");
5753MODULE_PARM(mode, "s");
5754MODULE_PARM(vesa, "i");
5755MODULE_PARM(rate, "i");
5756MODULE_PARM(forcecrt1, "i");
5757MODULE_PARM(forcecrt2type, "s");
5758MODULE_PARM(scalelcd, "i");
5759MODULE_PARM(pdc, "i");
5760MODULE_PARM(pdc1, "i");
5761MODULE_PARM(specialtiming, "s");
5762MODULE_PARM(lvdshl, "i");
5763MODULE_PARM(tvstandard, "s");
5764MODULE_PARM(tvxposoffset, "i");
5765MODULE_PARM(tvyposoffset, "i");
5766MODULE_PARM(filter, "i");
5767MODULE_PARM(nocrt2rate, "i");
5768MODULE_PARM(inverse, "i");
5769#if !defined(__i386__) && !defined(__x86_64__)
5770MODULE_PARM(resetcard, "i");
5771MODULE_PARM(videoram, "i");
5772#endif
5773#endif
5774
5775#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
5776module_param(mem, int, 0);
5777module_param(noaccel, int, 0);
5778module_param(noypan, int, 0);
5779module_param(nomax, int, 0);
5780module_param(userom, int, 0);
5781module_param(useoem, int, 0);
5782module_param(mode, charp, 0);
5783module_param(vesa, int, 0);
5784module_param(rate, int, 0);
5785module_param(forcecrt1, int, 0);
5786module_param(forcecrt2type, charp, 0);
5787module_param(scalelcd, int, 0);
5788module_param(pdc, int, 0);
5789module_param(pdc1, int, 0);
5790module_param(specialtiming, charp, 0);
5791module_param(lvdshl, int, 0);
5792module_param(tvstandard, charp, 0);
5793module_param(tvxposoffset, int, 0);
5794module_param(tvyposoffset, int, 0);
5795module_param(filter, int, 0);
5796module_param(nocrt2rate, int, 0);
5797#if !defined(__i386__) && !defined(__x86_64__)
5798module_param(resetcard, int, 0);
5799module_param(videoram, int, 0);
5800#endif
5801#endif
5802
5803MODULE_PARM_DESC(mem,
5804 "\nDetermines the beginning of the video memory heap in KB. This heap is used\n"
5805 "for video RAM management for eg. DRM/DRI. On 300 series, the default depends\n"
5806 "on the amount of video RAM available. If 8MB of video RAM or less is available,\n"
5807 "the heap starts at 4096KB, if between 8 and 16MB are available at 8192KB,\n"
5808 "otherwise at 12288KB. On 315 and Xabre series, the heap size is 32KB by default.\n"
5809 "The value is to be specified without 'KB' and must match the MaxXFBMem setting\n"
5810 "for XFree86 4.x/X.org 6.7 and later.\n");
5811
5812MODULE_PARM_DESC(noaccel,
5813 "\nIf set to anything other than 0, 2D acceleration will be disabled.\n"
5814 "(default: 0)\n");
5815
5816MODULE_PARM_DESC(noypan,
5817 "\nIf set to anything other than 0, y-panning will be disabled and scrolling\n"
5818 "will be performed by redrawing the screen. (default: 0)\n");
5819
5820MODULE_PARM_DESC(nomax,
5821 "\nIf y-panning is enabled, sisfb will by default use the entire available video\n"
5822 "memory for the virtual screen in order to optimize scrolling performance. If\n"
5823 "this is set to anything other than 0, sisfb will not do this and thereby \n"
5824 "enable the user to positively specify a virtual Y size of the screen using\n"
5825 "fbset. (default: 0)\n");
5826
5827#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
5828MODULE_PARM_DESC(mode,
5829 "\nSelects the desired display mode in the format [X]x[Y]x[Depth], eg.\n"
5830 "1024x768x16. Other formats supported include XxY-Depth and\n"
5831 "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
5832 "number, it will be interpreted as a VESA mode number. (default: none if\n"
5833 "sisfb is a module; this leaves the console untouched and the driver will\n"
5834 "only do the video memory management for eg. DRM/DRI; 800x600x8 if sisfb\n"
5835 "is in the kernel)\n");
5836MODULE_PARM_DESC(vesa,
5837 "\nSelects the desired display mode by VESA defined mode number, eg. 0x117\n"
5838 "(default: 0x0000 if sisfb is a module; this leaves the console untouched\n"
5839 "and the driver will only do the video memory management for eg. DRM/DRI;\n"
5840 "0x0103 if sisfb is in the kernel)\n");
5841#endif
5842
5843#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
5844MODULE_PARM_DESC(mode,
5845 "\nSelects the desired default display mode in the format XxYxDepth,\n"
5846 "eg. 1024x768x16. Other formats supported include XxY-Depth and\n"
5847 "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
5848 "number, it will be interpreted as a VESA mode number. (default: 800x600x8)\n");
5849
5850MODULE_PARM_DESC(vesa,
5851 "\nSelects the desired default display mode by VESA defined mode number, eg.\n"
5852 "0x117 (default: 0x0103)\n");
5853#endif
5854
5855MODULE_PARM_DESC(rate,
5856 "\nSelects the desired vertical refresh rate for CRT1 (external VGA) in Hz.\n"
5857 "If the mode is specified in the format XxY-Depth@Rate, this parameter\n"
5858 "will be ignored (default: 60)\n");
5859
5860MODULE_PARM_DESC(forcecrt1,
5861 "\nNormally, the driver autodetects whether or not CRT1 (external VGA) is \n"
5862 "connected. With this option, the detection can be overridden (1=CRT1 ON,\n"
5863 "0=CRT1 OFF) (default: [autodetected])\n");
5864
5865MODULE_PARM_DESC(forcecrt2type,
5866 "\nIf this option is omitted, the driver autodetects CRT2 output devices, such as\n"
5867 "LCD, TV or secondary VGA. With this option, this autodetection can be\n"
5868 "overridden. Possible parameters are LCD, TV, VGA or NONE. NONE disables CRT2.\n"
5869 "On systems with a SiS video bridge, parameters SVIDEO, COMPOSITE or SCART can\n"
5870 "be used instead of TV to override the TV detection. Furthermore, on systems\n"
5871 "with a SiS video bridge, SVIDEO+COMPOSITE, HIVISION, YPBPR480I, YPBPR480P,\n"
5872 "YPBPR720P and YPBPR1080I are understood. However, whether or not these work\n"
5873 "depends on the very hardware in use. (default: [autodetected])\n");
5874
5875MODULE_PARM_DESC(scalelcd,
5876 "\nSetting this to 1 will force the driver to scale the LCD image to the panel's\n"
5877 "native resolution. Setting it to 0 will disable scaling; LVDS panels will\n"
5878 "show black bars around the image, TMDS panels will probably do the scaling\n"
5879 "themselves. Default: 1 on LVDS panels, 0 on TMDS panels\n");
5880
5881MODULE_PARM_DESC(pdc,
5882 "\nThis is for manually selecting the LCD panel delay compensation. The driver\n"
5883 "should detect this correctly in most cases; however, sometimes this is not\n"
5884 "possible. If you see 'small waves' on the LCD, try setting this to 4, 32 or 24\n"
5885 "on a 300 series chipset; 6 on a 315 series chipset. If the problem persists,\n"
5886 "try other values (on 300 series: between 4 and 60 in steps of 4; on 315 series:\n"
5887 "any value from 0 to 31). (default: autodetected, if LCD is active during start)\n");
5888
5889#ifdef CONFIG_FB_SIS_315
5890MODULE_PARM_DESC(pdc1,
5891 "\nThis is same as pdc, but for LCD-via CRT1. Hence, this is for the 315/330\n"
5892 "series only. (default: autodetected if LCD is in LCD-via-CRT1 mode during\n"
5893 "startup) - Note: currently, this has no effect because LCD-via-CRT1 is not\n"
5894 "implemented yet.\n");
5895#endif
5896
5897MODULE_PARM_DESC(specialtiming,
5898 "\nPlease refer to documentation for more information on this option.\n");
5899
5900MODULE_PARM_DESC(lvdshl,
5901 "\nPlease refer to documentation for more information on this option.\n");
5902
5903MODULE_PARM_DESC(tvstandard,
5904 "\nThis allows overriding the BIOS default for the TV standard. Valid choices are\n"
5905 "pal, ntsc, palm and paln. (default: [auto; pal or ntsc only])\n");
5906
5907MODULE_PARM_DESC(tvxposoffset,
5908 "\nRelocate TV output horizontally. Possible parameters: -32 through 32.\n"
5909 "Default: 0\n");
5910
5911MODULE_PARM_DESC(tvyposoffset,
5912 "\nRelocate TV output vertically. Possible parameters: -32 through 32.\n"
5913 "Default: 0\n");
5914
5915MODULE_PARM_DESC(filter,
5916 "\nSelects TV flicker filter type (only for systems with a SiS301 video bridge).\n"
5917 "(Possible values 0-7, default: [no filter])\n");
5918
5919MODULE_PARM_DESC(nocrt2rate,
5920 "\nSetting this to 1 will force the driver to use the default refresh rate for\n"
5921 "CRT2 if CRT2 type is VGA. (default: 0, use same rate as CRT1)\n");
5922
5923#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
5924MODULE_PARM_DESC(inverse,
5925 "\nSetting this to anything but 0 should invert the display colors, but this\n"
5926 "does not seem to work. (default: 0)\n");
5927#endif
5928
5929#if !defined(__i386__) && !defined(__x86_64__)
5930#ifdef CONFIG_FB_SIS_300
5931MODULE_PARM_DESC(resetcard,
5932 "\nSet this to 1 in order to reset (POST) the card on non-x86 machines where\n"
5933 "the BIOS did not POST the card (only supported for SiS 300/305 currently).\n"
5934 "Default: 0\n");
5935
5936MODULE_PARM_DESC(videoram,
5937 "\nSet this to the amount of video RAM (in kilobyte) the card has. Required on\n"
5938 "some non-x86 architectures where the memory auto detection fails. Only\n"
5939 "relevant if resetcard is set, too. Default: [auto-detect]\n");
5940#endif
5941#endif
5942
5943int __devinit sisfb_init_module(void)
5944{
5945 sisfb_setdefaultparms();
5946
5947 if(rate) sisfb_parm_rate = rate;
5948
5949 if((scalelcd == 0) || (scalelcd == 1)) {
5950 sisfb_scalelcd = scalelcd ^ 1;
5951 }
5952
5953 /* Need to check crt2 type first for fstn/dstn */
5954
5955 if(forcecrt2type)
5956 sisfb_search_crt2type(forcecrt2type);
5957
5958 if(tvstandard)
5959 sisfb_search_tvstd(tvstandard);
5960
5961 if(mode)
5962 sisfb_search_mode(mode, FALSE);
5963 else if(vesa != -1)
5964 sisfb_search_vesamode(vesa, FALSE);
5965
5966 sisfb_crt1off = (crt1off == 0) ? 1 : 0;
5967
5968 sisfb_forcecrt1 = forcecrt1;
5969 if(forcecrt1 == 1) sisfb_crt1off = 0;
5970 else if(forcecrt1 == 0) sisfb_crt1off = 1;
5971
5972 if(noaccel == 1) sisfb_accel = 0;
5973 else if(noaccel == 0) sisfb_accel = 1;
5974
5975 if(noypan == 1) sisfb_ypan = 0;
5976 else if(noypan == 0) sisfb_ypan = 1;
5977
5978 if(nomax == 1) sisfb_max = 0;
5979 else if(nomax == 0) sisfb_max = 1;
5980
5981#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
5982 if(inverse) sisfb_inverse = 1;
5983#endif
5984
5985 if(mem) sisfb_parm_mem = mem;
5986
5987 if(userom != -1) sisfb_userom = userom;
5988 if(useoem != -1) sisfb_useoem = useoem;
5989
5990 if(pdc != -1) sisfb_pdc = (pdc & 0x7f);
5991 if(pdc1 != -1) sisfb_pdca = (pdc1 & 0x1f);
5992
5993 sisfb_nocrt2rate = nocrt2rate;
5994
5995 if(specialtiming)
5996 sisfb_search_specialtiming(specialtiming);
5997
5998 if((lvdshl >= 0) && (lvdshl <= 3)) sisfb_lvdshl = lvdshl;
5999
6000 if(filter != -1) sisfb_filter = filter;
6001
6002 sisfb_tvxposoffset = tvxposoffset;
6003 sisfb_tvyposoffset = tvyposoffset;
6004
6005#if !defined(__i386__) && !defined(__x86_64__)
6006 sisfb_resetcard = (resetcard) ? 1 : 0;
6007 if(videoram) sisfb_videoram = videoram;
6008#endif
6009
6010 return(sisfb_init());
6011}
6012
6013static void __exit sisfb_remove_module(void)
6014{
6015 pci_unregister_driver(&sisfb_driver);
6016 printk(KERN_DEBUG "sisfb: Module unloaded\n");
6017}
6018
6019module_init(sisfb_init_module);
6020module_exit(sisfb_remove_module);
6021
6022#endif /* /MODULE */
6023
6024EXPORT_SYMBOL(sis_malloc);
6025EXPORT_SYMBOL(sis_free);
6026
6027
diff --git a/drivers/video/sis/sis_main.h b/drivers/video/sis/sis_main.h
new file mode 100644
index 000000000000..a6678a7aff35
--- /dev/null
+++ b/drivers/video/sis/sis_main.h
@@ -0,0 +1,955 @@
1/*
2 * SiS 300/305/540/630(S)/730(S)
3 * SiS 315(H/PRO)/55x/(M)65x/(M)661(F/M)X/740/741(GX)/330/(M)760
4 * frame buffer driver for Linux kernels >=2.4.14 and >=2.6.3
5 *
6 * Copyright (C) 2001-2004 Thomas Winischhofer, Vienna, Austria.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the named License,
11 * or any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
21 */
22
23#ifndef _SISFB_MAIN
24#define _SISFB_MAIN
25
26#include <linux/spinlock.h>
27
28#include "vstruct.h"
29#include "sis.h"
30
31#define MODE_INDEX_NONE 0 /* index for mode=none */
32
33/* Fbcon stuff */
34static struct fb_var_screeninfo my_default_var = {
35 .xres = 0,
36 .yres = 0,
37 .xres_virtual = 0,
38 .yres_virtual = 0,
39 .xoffset = 0,
40 .yoffset = 0,
41 .bits_per_pixel = 0,
42 .grayscale = 0,
43 .red = {0, 8, 0},
44 .green = {0, 8, 0},
45 .blue = {0, 8, 0},
46 .transp = {0, 0, 0},
47 .nonstd = 0,
48 .activate = FB_ACTIVATE_NOW,
49 .height = -1,
50 .width = -1,
51 .accel_flags = 0,
52 .pixclock = 0,
53 .left_margin = 0,
54 .right_margin = 0,
55 .upper_margin = 0,
56 .lower_margin = 0,
57 .hsync_len = 0,
58 .vsync_len = 0,
59 .sync = 0,
60 .vmode = FB_VMODE_NONINTERLACED,
61};
62
63/* Boot-time parameters */
64static int sisfb_off = 0;
65static int sisfb_parm_mem = 0;
66static int sisfb_accel = -1;
67static int sisfb_ypan = -1;
68static int sisfb_max = -1;
69static int sisfb_userom = 1;
70static int sisfb_useoem = -1;
71#ifdef MODULE
72#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
73static int sisfb_mode_idx = -1;
74#else
75static int sisfb_mode_idx = MODE_INDEX_NONE; /* Don't use a mode by default if we are a module */
76#endif
77#else
78static int sisfb_mode_idx = -1; /* Use a default mode if we are inside the kernel */
79#endif
80static int sisfb_parm_rate = -1;
81static int sisfb_crt1off = 0;
82static int sisfb_forcecrt1 = -1;
83static int sisfb_crt2type = -1; /* CRT2 type (for overriding autodetection) */
84static int sisfb_crt2flags = 0;
85static int sisfb_pdc = 0xff;
86static int sisfb_pdca = 0xff;
87static int sisfb_scalelcd = -1;
88static int sisfb_specialtiming = CUT_NONE;
89static int sisfb_lvdshl = -1;
90static int sisfb_dstn = 0;
91static int sisfb_fstn = 0;
92static int sisfb_tvplug = -1; /* Tv plug type (for overriding autodetection) */
93static int sisfb_tvstd = -1;
94static int sisfb_tvxposoffset = 0;
95static int sisfb_tvyposoffset = 0;
96static int sisfb_filter = -1;
97static int sisfb_nocrt2rate = 0;
98#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
99static int sisfb_inverse = 0;
100static char sisfb_fontname[40];
101#endif
102#if !defined(__i386__) && !defined(__x86_64__)
103static int sisfb_resetcard = 0;
104static int sisfb_videoram = 0;
105#endif
106
107/* List of supported chips */
108static struct sisfb_chip_info {
109 int chip;
110 int vgaengine;
111 int mni;
112 int hwcursor_size;
113 int CRT2_write_enable;
114 const char *chip_name;
115} sisfb_chip_info[] __devinitdata = {
116 { SIS_300, SIS_300_VGA, 0, HW_CURSOR_AREA_SIZE_300 * 2, SIS_CRT2_WENABLE_300, "SiS 300/305" },
117 { SIS_540, SIS_300_VGA, 0, HW_CURSOR_AREA_SIZE_300 * 2, SIS_CRT2_WENABLE_300, "SiS 540" },
118 { SIS_630, SIS_300_VGA, 0, HW_CURSOR_AREA_SIZE_300 * 2, SIS_CRT2_WENABLE_300, "SiS 630" },
119 { SIS_315H, SIS_315_VGA, 1, HW_CURSOR_AREA_SIZE_315 * 4, SIS_CRT2_WENABLE_315, "SiS 315H" },
120 { SIS_315, SIS_315_VGA, 1, HW_CURSOR_AREA_SIZE_315 * 4, SIS_CRT2_WENABLE_315, "SiS 315" },
121 { SIS_315PRO, SIS_315_VGA, 1, HW_CURSOR_AREA_SIZE_315 * 4, SIS_CRT2_WENABLE_315, "SiS 315PRO" },
122 { SIS_550, SIS_315_VGA, 1, HW_CURSOR_AREA_SIZE_315 * 4, SIS_CRT2_WENABLE_315, "SiS 55x" },
123 { SIS_650, SIS_315_VGA, 1, HW_CURSOR_AREA_SIZE_315 * 4, SIS_CRT2_WENABLE_315, "SiS 650" },
124 { SIS_330, SIS_315_VGA, 1, HW_CURSOR_AREA_SIZE_315 * 4, SIS_CRT2_WENABLE_315, "SiS 330" },
125 { SIS_660, SIS_315_VGA, 1, HW_CURSOR_AREA_SIZE_315 * 4, SIS_CRT2_WENABLE_315, "SiS 660" },
126};
127
128static struct pci_device_id __devinitdata sisfb_pci_table[] = {
129#ifdef CONFIG_FB_SIS_300
130 { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
131 { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_540_VGA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
132 { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_630_VGA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2},
133#endif
134#ifdef CONFIG_FB_SIS_315
135 { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_315H, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3},
136 { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_315, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4},
137 { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_315PRO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5},
138 { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_550_VGA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6},
139 { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_650_VGA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 7},
140 { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_330, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8},
141 { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_660_VGA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 9},
142#endif
143 { 0 }
144};
145
146MODULE_DEVICE_TABLE(pci, sisfb_pci_table);
147
148static struct sis_video_info *card_list = NULL;
149
150/* TODO: This is not handled card-wise because the DRM
151 does not refer to a unique fb when calling sis_alloc
152 or sis_free. Therefore, this is handled globally for
153 now (hoping that nobody is crazy enough to run two
154 SiS cards at the same time).
155 */
156static SIS_HEAP sisfb_heap;
157
158#define MD_SIS300 1
159#define MD_SIS315 2
160
161/* Mode table */
162static const struct _sisbios_mode {
163 char name[15];
164 u8 mode_no[2];
165 u16 vesa_mode_no_1; /* "SiS defined" VESA mode number */
166 u16 vesa_mode_no_2; /* Real VESA mode numbers */
167 u16 xres;
168 u16 yres;
169 u16 bpp;
170 u16 rate_idx;
171 u16 cols;
172 u16 rows;
173 u8 chipset;
174} sisbios_mode[] = {
175/*0*/ {"none", {0xff,0xff}, 0x0000, 0x0000, 0, 0, 0, 0, 0, 0, MD_SIS300|MD_SIS315},
176 {"320x200x8", {0x59,0x59}, 0x0138, 0x0000, 320, 200, 8, 1, 40, 12, MD_SIS300|MD_SIS315},
177 {"320x200x16", {0x41,0x41}, 0x010e, 0x0000, 320, 200, 16, 1, 40, 12, MD_SIS300|MD_SIS315},
178 {"320x200x24", {0x4f,0x4f}, 0x0000, 0x0000, 320, 200, 32, 1, 40, 12, MD_SIS300|MD_SIS315}, /* That's for people who mix up color- and fb depth */
179 {"320x200x32", {0x4f,0x4f}, 0x0000, 0x0000, 320, 200, 32, 1, 40, 12, MD_SIS300|MD_SIS315},
180 {"320x240x8", {0x50,0x50}, 0x0132, 0x0000, 320, 240, 8, 1, 40, 15, MD_SIS300|MD_SIS315},
181 {"320x240x16", {0x56,0x56}, 0x0135, 0x0000, 320, 240, 16, 1, 40, 15, MD_SIS300|MD_SIS315},
182 {"320x240x24", {0x53,0x53}, 0x0000, 0x0000, 320, 240, 32, 1, 40, 15, MD_SIS300|MD_SIS315},
183 {"320x240x32", {0x53,0x53}, 0x0000, 0x0000, 320, 240, 32, 1, 40, 15, MD_SIS300|MD_SIS315},
184 {"320x240x8", {0x5a,0x5a}, 0x0132, 0x0000, 320, 480, 8, 1, 40, 30, MD_SIS315}, /* FSTN */
185/*10*/ {"320x240x16", {0x5b,0x5b}, 0x0135, 0x0000, 320, 480, 16, 1, 40, 30, MD_SIS315}, /* FSTN */
186 {"400x300x8", {0x51,0x51}, 0x0133, 0x0000, 400, 300, 8, 1, 50, 18, MD_SIS300|MD_SIS315},
187 {"400x300x16", {0x57,0x57}, 0x0136, 0x0000, 400, 300, 16, 1, 50, 18, MD_SIS300|MD_SIS315},
188 {"400x300x24", {0x54,0x54}, 0x0000, 0x0000, 400, 300, 32, 1, 50, 18, MD_SIS300|MD_SIS315},
189 {"400x300x32", {0x54,0x54}, 0x0000, 0x0000, 400, 300, 32, 1, 50, 18, MD_SIS300|MD_SIS315},
190 {"512x384x8", {0x52,0x52}, 0x0000, 0x0000, 512, 384, 8, 1, 64, 24, MD_SIS300|MD_SIS315},
191 {"512x384x16", {0x58,0x58}, 0x0000, 0x0000, 512, 384, 16, 1, 64, 24, MD_SIS300|MD_SIS315},
192 {"512x384x24", {0x5c,0x5c}, 0x0000, 0x0000, 512, 384, 32, 1, 64, 24, MD_SIS300|MD_SIS315},
193 {"512x384x32", {0x5c,0x5c}, 0x0000, 0x0000, 512, 384, 32, 1, 64, 24, MD_SIS300|MD_SIS315},
194 {"640x400x8", {0x2f,0x2f}, 0x0000, 0x0000, 640, 400, 8, 1, 80, 25, MD_SIS300|MD_SIS315},
195/*20*/ {"640x400x16", {0x5d,0x5d}, 0x0000, 0x0000, 640, 400, 16, 1, 80, 25, MD_SIS300|MD_SIS315},
196 {"640x400x24", {0x5e,0x5e}, 0x0000, 0x0000, 640, 400, 32, 1, 80, 25, MD_SIS300|MD_SIS315},
197 {"640x400x32", {0x5e,0x5e}, 0x0000, 0x0000, 640, 400, 32, 1, 80, 25, MD_SIS300|MD_SIS315},
198 {"640x480x8", {0x2e,0x2e}, 0x0101, 0x0101, 640, 480, 8, 1, 80, 30, MD_SIS300|MD_SIS315},
199 {"640x480x16", {0x44,0x44}, 0x0111, 0x0111, 640, 480, 16, 1, 80, 30, MD_SIS300|MD_SIS315},
200 {"640x480x24", {0x62,0x62}, 0x013a, 0x0112, 640, 480, 32, 1, 80, 30, MD_SIS300|MD_SIS315},
201 {"640x480x32", {0x62,0x62}, 0x013a, 0x0112, 640, 480, 32, 1, 80, 30, MD_SIS300|MD_SIS315},
202 {"720x480x8", {0x31,0x31}, 0x0000, 0x0000, 720, 480, 8, 1, 90, 30, MD_SIS300|MD_SIS315},
203 {"720x480x16", {0x33,0x33}, 0x0000, 0x0000, 720, 480, 16, 1, 90, 30, MD_SIS300|MD_SIS315},
204 {"720x480x24", {0x35,0x35}, 0x0000, 0x0000, 720, 480, 32, 1, 90, 30, MD_SIS300|MD_SIS315},
205/*30*/ {"720x480x32", {0x35,0x35}, 0x0000, 0x0000, 720, 480, 32, 1, 90, 30, MD_SIS300|MD_SIS315},
206 {"720x576x8", {0x32,0x32}, 0x0000, 0x0000, 720, 576, 8, 1, 90, 36, MD_SIS300|MD_SIS315},
207 {"720x576x16", {0x34,0x34}, 0x0000, 0x0000, 720, 576, 16, 1, 90, 36, MD_SIS300|MD_SIS315},
208 {"720x576x24", {0x36,0x36}, 0x0000, 0x0000, 720, 576, 32, 1, 90, 36, MD_SIS300|MD_SIS315},
209 {"720x576x32", {0x36,0x36}, 0x0000, 0x0000, 720, 576, 32, 1, 90, 36, MD_SIS300|MD_SIS315},
210 {"768x576x8", {0x5f,0x5f}, 0x0000, 0x0000, 768, 576, 8, 1, 96, 36, MD_SIS300|MD_SIS315},
211 {"768x576x16", {0x60,0x60}, 0x0000, 0x0000, 768, 576, 16, 1, 96, 36, MD_SIS300|MD_SIS315},
212 {"768x576x24", {0x61,0x61}, 0x0000, 0x0000, 768, 576, 32, 1, 96, 36, MD_SIS300|MD_SIS315},
213 {"768x576x32", {0x61,0x61}, 0x0000, 0x0000, 768, 576, 32, 1, 96, 36, MD_SIS300|MD_SIS315},
214 {"800x480x8", {0x70,0x70}, 0x0000, 0x0000, 800, 480, 8, 1, 100, 30, MD_SIS300|MD_SIS315},
215/*40*/ {"800x480x16", {0x7a,0x7a}, 0x0000, 0x0000, 800, 480, 16, 1, 100, 30, MD_SIS300|MD_SIS315},
216 {"800x480x24", {0x76,0x76}, 0x0000, 0x0000, 800, 480, 32, 1, 100, 30, MD_SIS300|MD_SIS315},
217 {"800x480x32", {0x76,0x76}, 0x0000, 0x0000, 800, 480, 32, 1, 100, 30, MD_SIS300|MD_SIS315},
218#define DEFAULT_MODE 43 /* index for 800x600x8 */
219#define DEFAULT_LCDMODE 43 /* index for 800x600x8 */
220#define DEFAULT_TVMODE 43 /* index for 800x600x8 */
221 {"800x600x8", {0x30,0x30}, 0x0103, 0x0103, 800, 600, 8, 2, 100, 37, MD_SIS300|MD_SIS315},
222 {"800x600x16", {0x47,0x47}, 0x0114, 0x0114, 800, 600, 16, 2, 100, 37, MD_SIS300|MD_SIS315},
223 {"800x600x24", {0x63,0x63}, 0x013b, 0x0115, 800, 600, 32, 2, 100, 37, MD_SIS300|MD_SIS315},
224 {"800x600x32", {0x63,0x63}, 0x013b, 0x0115, 800, 600, 32, 2, 100, 37, MD_SIS300|MD_SIS315},
225 {"848x480x8", {0x39,0x39}, 0x0000, 0x0000, 848, 480, 8, 2, 106, 30, MD_SIS300|MD_SIS315},
226 {"848x480x16", {0x3b,0x3b}, 0x0000, 0x0000, 848, 480, 16, 2, 106, 30, MD_SIS300|MD_SIS315},
227 {"848x480x24", {0x3e,0x3e}, 0x0000, 0x0000, 848, 480, 32, 2, 106, 30, MD_SIS300|MD_SIS315},
228/*50*/ {"848x480x32", {0x3e,0x3e}, 0x0000, 0x0000, 848, 480, 32, 2, 106, 30, MD_SIS300|MD_SIS315},
229 {"856x480x8", {0x3f,0x3f}, 0x0000, 0x0000, 856, 480, 8, 2, 107, 30, MD_SIS300|MD_SIS315},
230 {"856x480x16", {0x42,0x42}, 0x0000, 0x0000, 856, 480, 16, 2, 107, 30, MD_SIS300|MD_SIS315},
231 {"856x480x24", {0x45,0x45}, 0x0000, 0x0000, 856, 480, 32, 2, 107, 30, MD_SIS300|MD_SIS315},
232 {"856x480x32", {0x45,0x45}, 0x0000, 0x0000, 856, 480, 32, 2, 107, 30, MD_SIS300|MD_SIS315},
233 {"960x540x8", {0x1d,0x1d}, 0x0000, 0x0000, 960, 540, 8, 1, 120, 33, MD_SIS315},
234 {"960x540x16", {0x1e,0x1e}, 0x0000, 0x0000, 960, 540, 16, 1, 120, 33, MD_SIS315},
235 {"960x540x24", {0x1f,0x1f}, 0x0000, 0x0000, 960, 540, 32, 1, 120, 33, MD_SIS315},
236 {"960x540x32", {0x1f,0x1f}, 0x0000, 0x0000, 960, 540, 32, 1, 120, 33, MD_SIS315},
237 {"960x600x8", {0x20,0x20}, 0x0000, 0x0000, 960, 600, 8, 1, 120, 37, MD_SIS315},
238/*60*/ {"960x600x16", {0x21,0x21}, 0x0000, 0x0000, 960, 600, 16, 1, 120, 37, MD_SIS315},
239 {"960x600x24", {0x22,0x22}, 0x0000, 0x0000, 960, 600, 32, 1, 120, 37, MD_SIS315},
240 {"960x600x32", {0x22,0x22}, 0x0000, 0x0000, 960, 600, 32, 1, 120, 37, MD_SIS315},
241 {"1024x576x8", {0x71,0x71}, 0x0000, 0x0000, 1024, 576, 8, 1, 128, 36, MD_SIS300|MD_SIS315},
242 {"1024x576x16", {0x74,0x74}, 0x0000, 0x0000, 1024, 576, 16, 1, 128, 36, MD_SIS300|MD_SIS315},
243 {"1024x576x24", {0x77,0x77}, 0x0000, 0x0000, 1024, 576, 32, 1, 128, 36, MD_SIS300|MD_SIS315},
244 {"1024x576x32", {0x77,0x77}, 0x0000, 0x0000, 1024, 576, 32, 1, 128, 36, MD_SIS300|MD_SIS315},
245 {"1024x600x8", {0x20,0x20}, 0x0000, 0x0000, 1024, 600, 8, 1, 128, 37, MD_SIS300 },
246 {"1024x600x16", {0x21,0x21}, 0x0000, 0x0000, 1024, 600, 16, 1, 128, 37, MD_SIS300 },
247 {"1024x600x24", {0x22,0x22}, 0x0000, 0x0000, 1024, 600, 32, 1, 128, 37, MD_SIS300 },
248/*70*/ {"1024x600x32", {0x22,0x22}, 0x0000, 0x0000, 1024, 600, 32, 1, 128, 37, MD_SIS300 },
249 {"1024x768x8", {0x38,0x38}, 0x0105, 0x0105, 1024, 768, 8, 2, 128, 48, MD_SIS300|MD_SIS315},
250 {"1024x768x16", {0x4a,0x4a}, 0x0117, 0x0117, 1024, 768, 16, 2, 128, 48, MD_SIS300|MD_SIS315},
251 {"1024x768x24", {0x64,0x64}, 0x013c, 0x0118, 1024, 768, 32, 2, 128, 48, MD_SIS300|MD_SIS315},
252 {"1024x768x32", {0x64,0x64}, 0x013c, 0x0118, 1024, 768, 32, 2, 128, 48, MD_SIS300|MD_SIS315},
253 {"1152x768x8", {0x23,0x23}, 0x0000, 0x0000, 1152, 768, 8, 1, 144, 48, MD_SIS300 },
254 {"1152x768x16", {0x24,0x24}, 0x0000, 0x0000, 1152, 768, 16, 1, 144, 48, MD_SIS300 },
255 {"1152x768x24", {0x25,0x25}, 0x0000, 0x0000, 1152, 768, 32, 1, 144, 48, MD_SIS300 },
256 {"1152x768x32", {0x25,0x25}, 0x0000, 0x0000, 1152, 768, 32, 1, 144, 48, MD_SIS300 },
257 {"1152x864x8", {0x29,0x29}, 0x0000, 0x0000, 1152, 864, 8, 1, 144, 54, MD_SIS300|MD_SIS315},
258/*80*/ {"1152x864x16", {0x2a,0x2a}, 0x0000, 0x0000, 1152, 864, 16, 1, 144, 54, MD_SIS300|MD_SIS315},
259 {"1152x864x24", {0x2b,0x2b}, 0x0000, 0x0000, 1152, 864, 32, 1, 144, 54, MD_SIS300|MD_SIS315},
260 {"1152x864x32", {0x2b,0x2b}, 0x0000, 0x0000, 1152, 864, 32, 1, 144, 54, MD_SIS300|MD_SIS315},
261 {"1280x720x8", {0x79,0x79}, 0x0000, 0x0000, 1280, 720, 8, 1, 160, 45, MD_SIS300|MD_SIS315},
262 {"1280x720x16", {0x75,0x75}, 0x0000, 0x0000, 1280, 720, 16, 1, 160, 45, MD_SIS300|MD_SIS315},
263 {"1280x720x24", {0x78,0x78}, 0x0000, 0x0000, 1280, 720, 32, 1, 160, 45, MD_SIS300|MD_SIS315},
264 {"1280x720x32", {0x78,0x78}, 0x0000, 0x0000, 1280, 720, 32, 1, 160, 45, MD_SIS300|MD_SIS315},
265 {"1280x768x8", {0x55,0x23}, 0x0000, 0x0000, 1280, 768, 8, 1, 160, 48, MD_SIS300|MD_SIS315},
266 {"1280x768x16", {0x5a,0x24}, 0x0000, 0x0000, 1280, 768, 16, 1, 160, 48, MD_SIS300|MD_SIS315},
267 {"1280x768x24", {0x5b,0x25}, 0x0000, 0x0000, 1280, 768, 32, 1, 160, 48, MD_SIS300|MD_SIS315},
268/*90*/ {"1280x768x32", {0x5b,0x25}, 0x0000, 0x0000, 1280, 768, 32, 1, 160, 48, MD_SIS300|MD_SIS315},
269 {"1280x800x8", {0x14,0x14}, 0x0000, 0x0000, 1280, 800, 8, 1, 160, 50, MD_SIS315},
270 {"1280x800x16", {0x15,0x15}, 0x0000, 0x0000, 1280, 800, 16, 1, 160, 50, MD_SIS315},
271 {"1280x800x24", {0x16,0x16}, 0x0000, 0x0000, 1280, 800, 32, 1, 160, 50, MD_SIS315},
272 {"1280x800x32", {0x16,0x16}, 0x0000, 0x0000, 1280, 800, 32, 1, 160, 50, MD_SIS315},
273 {"1280x960x8", {0x7c,0x7c}, 0x0000, 0x0000, 1280, 960, 8, 1, 160, 60, MD_SIS300|MD_SIS315},
274 {"1280x960x16", {0x7d,0x7d}, 0x0000, 0x0000, 1280, 960, 16, 1, 160, 60, MD_SIS300|MD_SIS315},
275 {"1280x960x24", {0x7e,0x7e}, 0x0000, 0x0000, 1280, 960, 32, 1, 160, 60, MD_SIS300|MD_SIS315},
276 {"1280x960x32", {0x7e,0x7e}, 0x0000, 0x0000, 1280, 960, 32, 1, 160, 60, MD_SIS300|MD_SIS315},
277 {"1280x1024x8", {0x3a,0x3a}, 0x0107, 0x0107, 1280, 1024, 8, 2, 160, 64, MD_SIS300|MD_SIS315},
278/*100*/ {"1280x1024x16", {0x4d,0x4d}, 0x011a, 0x011a, 1280, 1024, 16, 2, 160, 64, MD_SIS300|MD_SIS315},
279 {"1280x1024x24", {0x65,0x65}, 0x013d, 0x011b, 1280, 1024, 32, 2, 160, 64, MD_SIS300|MD_SIS315},
280 {"1280x1024x32", {0x65,0x65}, 0x013d, 0x011b, 1280, 1024, 32, 2, 160, 64, MD_SIS300|MD_SIS315},
281 {"1360x768x8", {0x48,0x48}, 0x0000, 0x0000, 1360, 768, 8, 1, 170, 48, MD_SIS300|MD_SIS315},
282 {"1360x768x16", {0x4b,0x4b}, 0x0000, 0x0000, 1360, 768, 16, 1, 170, 48, MD_SIS300|MD_SIS315},
283 {"1360x768x24", {0x4e,0x4e}, 0x0000, 0x0000, 1360, 768, 32, 1, 170, 48, MD_SIS300|MD_SIS315},
284 {"1360x768x32", {0x4e,0x4e}, 0x0000, 0x0000, 1360, 768, 32, 1, 170, 48, MD_SIS300|MD_SIS315},
285 {"1360x1024x8", {0x67,0x67}, 0x0000, 0x0000, 1360, 1024, 8, 1, 170, 64, MD_SIS300 },
286 {"1360x1024x16", {0x6f,0x6f}, 0x0000, 0x0000, 1360, 1024, 16, 1, 170, 64, MD_SIS300 },
287 {"1360x1024x24", {0x72,0x72}, 0x0000, 0x0000, 1360, 1024, 32, 1, 170, 64, MD_SIS300 },
288/*110*/ {"1360x1024x32", {0x72,0x72}, 0x0000, 0x0000, 1360, 1024, 32, 1, 170, 64, MD_SIS300 },
289 {"1400x1050x8", {0x26,0x26}, 0x0000, 0x0000, 1400, 1050, 8, 1, 175, 65, MD_SIS315},
290 {"1400x1050x16", {0x27,0x27}, 0x0000, 0x0000, 1400, 1050, 16, 1, 175, 65, MD_SIS315},
291 {"1400x1050x24", {0x28,0x28}, 0x0000, 0x0000, 1400, 1050, 32, 1, 175, 65, MD_SIS315},
292 {"1400x1050x32", {0x28,0x28}, 0x0000, 0x0000, 1400, 1050, 32, 1, 175, 65, MD_SIS315},
293 {"1600x1200x8", {0x3c,0x3c}, 0x0130, 0x011c, 1600, 1200, 8, 1, 200, 75, MD_SIS300|MD_SIS315},
294 {"1600x1200x16", {0x3d,0x3d}, 0x0131, 0x011e, 1600, 1200, 16, 1, 200, 75, MD_SIS300|MD_SIS315},
295 {"1600x1200x24", {0x66,0x66}, 0x013e, 0x011f, 1600, 1200, 32, 1, 200, 75, MD_SIS300|MD_SIS315},
296 {"1600x1200x32", {0x66,0x66}, 0x013e, 0x011f, 1600, 1200, 32, 1, 200, 75, MD_SIS300|MD_SIS315},
297 {"1680x1050x8", {0x17,0x17}, 0x0000, 0x0000, 1680, 1050, 8, 1, 210, 65, MD_SIS315},
298/*120*/ {"1680x1050x16", {0x18,0x18}, 0x0000, 0x0000, 1680, 1050, 16, 1, 210, 65, MD_SIS315},
299 {"1680x1050x24", {0x19,0x19}, 0x0000, 0x0000, 1680, 1050, 32, 1, 210, 65, MD_SIS315},
300 {"1680x1050x32", {0x19,0x19}, 0x0000, 0x0000, 1680, 1050, 32, 1, 210, 65, MD_SIS315},
301 {"1920x1080x8", {0x2c,0x2c}, 0x0000, 0x0000, 1920, 1080, 8, 1, 240, 67, MD_SIS315},
302 {"1920x1080x16", {0x2d,0x2d}, 0x0000, 0x0000, 1920, 1080, 16, 1, 240, 67, MD_SIS315},
303 {"1920x1080x24", {0x73,0x73}, 0x0000, 0x0000, 1920, 1080, 32, 1, 240, 67, MD_SIS315},
304 {"1920x1080x32", {0x73,0x73}, 0x0000, 0x0000, 1920, 1080, 32, 1, 240, 67, MD_SIS315},
305 {"1920x1440x8", {0x68,0x68}, 0x013f, 0x0000, 1920, 1440, 8, 1, 240, 75, MD_SIS300|MD_SIS315},
306 {"1920x1440x16", {0x69,0x69}, 0x0140, 0x0000, 1920, 1440, 16, 1, 240, 75, MD_SIS300|MD_SIS315},
307 {"1920x1440x24", {0x6b,0x6b}, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, MD_SIS300|MD_SIS315},
308/*130*/ {"1920x1440x32", {0x6b,0x6b}, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, MD_SIS300|MD_SIS315},
309 {"2048x1536x8", {0x6c,0x6c}, 0x0000, 0x0000, 2048, 1536, 8, 1, 256, 96, MD_SIS315},
310 {"2048x1536x16", {0x6d,0x6d}, 0x0000, 0x0000, 2048, 1536, 16, 1, 256, 96, MD_SIS315},
311 {"2048x1536x24", {0x6e,0x6e}, 0x0000, 0x0000, 2048, 1536, 32, 1, 256, 96, MD_SIS315},
312 {"2048x1536x32", {0x6e,0x6e}, 0x0000, 0x0000, 2048, 1536, 32, 1, 256, 96, MD_SIS315},
313 {"\0", {0x00,0x00}, 0, 0, 0, 0, 0, 0, 0}
314};
315
316#define SIS_LCD_NUMBER 17
317static const struct _sis_lcd_data {
318 u32 lcdtype;
319 u16 xres;
320 u16 yres;
321 u8 default_mode_idx;
322} sis_lcd_data[] = {
323 { LCD_640x480, 640, 480, 23 },
324 { LCD_800x600, 800, 600, 43 },
325 { LCD_1024x600, 1024, 600, 67 },
326 { LCD_1024x768, 1024, 768, 71 },
327 { LCD_1152x768, 1152, 768, 75 },
328 { LCD_1152x864, 1152, 864, 79 },
329 { LCD_1280x720, 1280, 720, 83 },
330 { LCD_1280x768, 1280, 768, 87 },
331 { LCD_1280x800, 1280, 800, 91 },
332 { LCD_1280x960, 1280, 960, 95 },
333 { LCD_1280x1024, 1280, 1024, 99 },
334 { LCD_1400x1050, 1400, 1050, 111 },
335 { LCD_1680x1050, 1680, 1050, 119 },
336 { LCD_1600x1200, 1600, 1200, 115 },
337 { LCD_640x480_2, 640, 480, 23 },
338 { LCD_640x480_3, 640, 480, 23 },
339 { LCD_320x480, 320, 480, 9 },
340};
341
342/* CR36 evaluation */
343static const USHORT sis300paneltype[] =
344 { LCD_UNKNOWN, LCD_800x600, LCD_1024x768, LCD_1280x1024,
345 LCD_1280x960, LCD_640x480, LCD_1024x600, LCD_1152x768,
346 LCD_UNKNOWN, LCD_UNKNOWN, LCD_UNKNOWN, LCD_UNKNOWN,
347 LCD_UNKNOWN, LCD_UNKNOWN, LCD_UNKNOWN, LCD_UNKNOWN };
348
349static const USHORT sis310paneltype[] =
350 { LCD_UNKNOWN, LCD_800x600, LCD_1024x768, LCD_1280x1024,
351 LCD_640x480, LCD_1024x600, LCD_1152x864, LCD_1280x960,
352 LCD_1152x768, LCD_1400x1050, LCD_1280x768, LCD_1600x1200,
353 LCD_640x480_2, LCD_640x480_3, LCD_UNKNOWN, LCD_UNKNOWN };
354
355static const USHORT sis661paneltype[] =
356 { LCD_UNKNOWN, LCD_800x600, LCD_1024x768, LCD_1280x1024,
357 LCD_640x480, LCD_1024x600, LCD_1152x864, LCD_1280x960,
358 LCD_1152x768, LCD_1400x1050, LCD_1280x768, LCD_1600x1200,
359 LCD_1280x800, LCD_1680x1050, LCD_1280x720, LCD_UNKNOWN };
360
361#define FL_550_DSTN 0x01
362#define FL_550_FSTN 0x02
363#define FL_300 0x04
364#define FL_315 0x08
365
366static struct _sis_crt2type {
367 char name[32];
368 u32 type_no;
369 u32 tvplug_no;
370 u16 flags;
371} sis_crt2type[] __initdata = {
372 {"NONE", 0, -1, FL_300|FL_315},
373 {"LCD", CRT2_LCD, -1, FL_300|FL_315},
374 {"TV", CRT2_TV, -1, FL_300|FL_315},
375 {"VGA", CRT2_VGA, -1, FL_300|FL_315},
376 {"SVIDEO", CRT2_TV, TV_SVIDEO, FL_300|FL_315},
377 {"COMPOSITE", CRT2_TV, TV_AVIDEO, FL_300|FL_315},
378 {"CVBS", CRT2_TV, TV_AVIDEO, FL_300|FL_315},
379 {"SVIDEO+COMPOSITE", CRT2_TV, TV_AVIDEO|TV_SVIDEO, FL_300|FL_315},
380 {"COMPOSITE+SVIDEO", CRT2_TV, TV_AVIDEO|TV_SVIDEO, FL_300|FL_315},
381 {"SVIDEO+CVBS", CRT2_TV, TV_AVIDEO|TV_SVIDEO, FL_300|FL_315},
382 {"CVBS+SVIDEO", CRT2_TV, TV_AVIDEO|TV_SVIDEO, FL_300|FL_315},
383 {"SCART", CRT2_TV, TV_SCART, FL_300|FL_315},
384 {"HIVISION", CRT2_TV, TV_HIVISION, FL_315},
385 {"YPBPR480I", CRT2_TV, TV_YPBPR|TV_YPBPR525I, FL_315},
386 {"YPBPR480P", CRT2_TV, TV_YPBPR|TV_YPBPR525P, FL_315},
387 {"YPBPR720P", CRT2_TV, TV_YPBPR|TV_YPBPR750P, FL_315},
388 {"YPBPR1080I", CRT2_TV, TV_YPBPR|TV_YPBPR1080I, FL_315},
389 {"DSTN", CRT2_LCD, -1, FL_315|FL_550_DSTN},
390 {"FSTN", CRT2_LCD, -1, FL_315|FL_550_FSTN},
391 {"\0", -1, -1, 0}
392};
393
394/* TV standard */
395static struct _sis_tvtype {
396 char name[6];
397 u32 type_no;
398} sis_tvtype[] __initdata = {
399 {"PAL", TV_PAL},
400 {"NTSC", TV_NTSC},
401 {"PALM", TV_PAL|TV_PALM},
402 {"PALN", TV_PAL|TV_PALN},
403 {"NTSCJ", TV_NTSC|TV_NTSCJ},
404 {"\0", -1}
405};
406
407static const struct _sis_vrate {
408 u16 idx;
409 u16 xres;
410 u16 yres;
411 u16 refresh;
412 BOOLEAN SiS730valid32bpp;
413} sisfb_vrate[] = {
414 {1, 320, 200, 70, TRUE},
415 {1, 320, 240, 60, TRUE},
416 {1, 320, 480, 60, TRUE},
417 {1, 400, 300, 60, TRUE},
418 {1, 512, 384, 60, TRUE},
419 {1, 640, 400, 72, TRUE},
420 {1, 640, 480, 60, TRUE}, {2, 640, 480, 72, TRUE}, {3, 640, 480, 75, TRUE},
421 {4, 640, 480, 85, TRUE}, {5, 640, 480, 100, TRUE}, {6, 640, 480, 120, TRUE},
422 {7, 640, 480, 160, TRUE}, {8, 640, 480, 200, TRUE},
423 {1, 720, 480, 60, TRUE},
424 {1, 720, 576, 58, TRUE},
425 {1, 768, 576, 58, TRUE},
426 {1, 800, 480, 60, TRUE}, {2, 800, 480, 75, TRUE}, {3, 800, 480, 85, TRUE},
427 {1, 800, 600, 56, TRUE}, {2, 800, 600, 60, TRUE}, {3, 800, 600, 72, TRUE},
428 {4, 800, 600, 75, TRUE}, {5, 800, 600, 85, TRUE}, {6, 800, 600, 105, TRUE},
429 {7, 800, 600, 120, TRUE}, {8, 800, 600, 160, TRUE},
430 {1, 848, 480, 39, TRUE}, {2, 848, 480, 60, TRUE},
431 {1, 856, 480, 39, TRUE}, {2, 856, 480, 60, TRUE},
432 {1, 960, 540, 60, TRUE},
433 {1, 960, 600, 60, TRUE},
434 {1, 1024, 576, 60, TRUE}, {2, 1024, 576, 75, TRUE}, {3, 1024, 576, 85, TRUE},
435 {1, 1024, 600, 60, TRUE},
436 {1, 1024, 768, 43, TRUE}, {2, 1024, 768, 60, TRUE}, {3, 1024, 768, 70, FALSE},
437 {4, 1024, 768, 75, FALSE}, {5, 1024, 768, 85, TRUE}, {6, 1024, 768, 100, TRUE},
438 {7, 1024, 768, 120, TRUE},
439 {1, 1152, 768, 60, TRUE},
440 {1, 1152, 864, 60, TRUE}, {1, 1152, 864, 75, TRUE}, {2, 1152, 864, 84, TRUE},
441 {1, 1280, 720, 60, TRUE}, {2, 1280, 720, 75, TRUE}, {3, 1280, 720, 85, TRUE},
442 {1, 1280, 768, 60, TRUE},
443 {1, 1280, 800, 60, TRUE},
444 {1, 1280, 960, 60, TRUE}, {2, 1280, 960, 85, TRUE},
445 {1, 1280, 1024, 43, TRUE}, {2, 1280, 1024, 60, TRUE}, {3, 1280, 1024, 75, TRUE},
446 {4, 1280, 1024, 85, TRUE},
447 {1, 1360, 768, 60, TRUE},
448 {1, 1360, 1024, 59, TRUE},
449 {1, 1400, 1050, 60, TRUE}, {2, 1400, 1050, 75, TRUE},
450 {1, 1600, 1200, 60, TRUE}, {2, 1600, 1200, 65, TRUE}, {3, 1600, 1200, 70, TRUE},
451 {4, 1600, 1200, 75, TRUE}, {5, 1600, 1200, 85, TRUE}, {6, 1600, 1200, 100, TRUE},
452 {7, 1600, 1200, 120, TRUE},
453 {1, 1680, 1050, 60, TRUE},
454 {1, 1920, 1080, 30, TRUE},
455 {1, 1920, 1440, 60, TRUE}, {2, 1920, 1440, 65, TRUE}, {3, 1920, 1440, 70, TRUE},
456 {4, 1920, 1440, 75, TRUE}, {5, 1920, 1440, 85, TRUE}, {6, 1920, 1440, 100, TRUE},
457 {1, 2048, 1536, 60, TRUE}, {2, 2048, 1536, 65, TRUE}, {3, 2048, 1536, 70, TRUE},
458 {4, 2048, 1536, 75, TRUE}, {5, 2048, 1536, 85, TRUE},
459 {0, 0, 0, 0, FALSE}
460};
461
462static const struct _sisfbddcsmodes {
463 u32 mask;
464 u16 h;
465 u16 v;
466 u32 d;
467} sisfb_ddcsmodes[] = {
468 { 0x10000, 67, 75, 108000},
469 { 0x08000, 48, 72, 50000},
470 { 0x04000, 46, 75, 49500},
471 { 0x01000, 35, 43, 44900},
472 { 0x00800, 48, 60, 65000},
473 { 0x00400, 56, 70, 75000},
474 { 0x00200, 60, 75, 78800},
475 { 0x00100, 80, 75, 135000},
476 { 0x00020, 31, 60, 25200},
477 { 0x00008, 38, 72, 31500},
478 { 0x00004, 37, 75, 31500},
479 { 0x00002, 35, 56, 36000},
480 { 0x00001, 38, 60, 40000}
481};
482
483static const struct _sisfbddcfmodes {
484 u16 x;
485 u16 y;
486 u16 v;
487 u16 h;
488 u32 d;
489} sisfb_ddcfmodes[] = {
490 { 1280, 1024, 85, 92, 157500},
491 { 1600, 1200, 60, 75, 162000},
492 { 1600, 1200, 65, 82, 175500},
493 { 1600, 1200, 70, 88, 189000},
494 { 1600, 1200, 75, 94, 202500},
495 { 1600, 1200, 85, 107,229500},
496 { 1920, 1440, 60, 90, 234000},
497 { 1920, 1440, 75, 113,297000}
498};
499
500#ifdef CONFIG_FB_SIS_300
501static struct _chswtable {
502 u16 subsysVendor;
503 u16 subsysCard;
504 char *vendorName;
505 char *cardName;
506} mychswtable[] __devinitdata = {
507 { 0x1631, 0x1002, "Mitachi", "0x1002" },
508 { 0x1071, 0x7521, "Mitac" , "7521P" },
509 { 0, 0, "" , "" }
510};
511#endif
512
513static struct _customttable {
514 u16 chipID;
515 char *biosversion;
516 char *biosdate;
517 u32 bioschksum;
518 u16 biosFootprintAddr[5];
519 u8 biosFootprintData[5];
520 u16 pcisubsysvendor;
521 u16 pcisubsyscard;
522 char *vendorName;
523 char *cardName;
524 u32 SpecialID;
525 char *optionName;
526} mycustomttable[] __devinitdata = {
527 { SIS_630, "2.00.07", "09/27/2002-13:38:25",
528 0x3240A8,
529 { 0x220, 0x227, 0x228, 0x229, 0x0ee },
530 { 0x01, 0xe3, 0x9a, 0x6a, 0xef },
531 0x1039, 0x6300,
532 "Barco", "iQ R200L/300/400", CUT_BARCO1366, "BARCO_1366"
533 },
534 { SIS_630, "2.00.07", "09/27/2002-13:38:25",
535 0x323FBD,
536 { 0x220, 0x227, 0x228, 0x229, 0x0ee },
537 { 0x00, 0x5a, 0x64, 0x41, 0xef },
538 0x1039, 0x6300,
539 "Barco", "iQ G200L/300/400/500", CUT_BARCO1024, "BARCO_1024"
540 },
541 { SIS_650, "", "",
542 0,
543 { 0, 0, 0, 0, 0 },
544 { 0, 0, 0, 0, 0 },
545 0x0e11, 0x083c,
546 "Inventec (Compaq)", "3017cl/3045US", CUT_COMPAQ12802, "COMPAQ_1280"
547 },
548 { SIS_650, "", "",
549 0,
550 { 0x00c, 0, 0, 0, 0 },
551 { 'e' , 0, 0, 0, 0 },
552 0x1558, 0x0287,
553 "Clevo", "L285/L287 (Version 1)", CUT_CLEVO1024, "CLEVO_L28X_1"
554 },
555 { SIS_650, "", "",
556 0,
557 { 0x00c, 0, 0, 0, 0 },
558 { 'y' , 0, 0, 0, 0 },
559 0x1558, 0x0287,
560 "Clevo", "L285/L287 (Version 2)", CUT_CLEVO10242, "CLEVO_L28X_2"
561 },
562 { SIS_650, "", "",
563 0,
564 { 0, 0, 0, 0, 0 },
565 { 0, 0, 0, 0, 0 },
566 0x1558, 0x0400, /* possibly 401 and 402 as well; not panelsize specific (?) */
567 "Clevo", "D400S/D410S/D400H/D410H", CUT_CLEVO1400, "CLEVO_D4X0"
568 },
569 { SIS_650, "", "",
570 0, /* Shift LCD in LCD-via-CRT1 mode */
571 { 0, 0, 0, 0, 0 },
572 { 0, 0, 0, 0, 0 },
573 0x1558, 0x2263,
574 "Clevo", "D22ES/D27ES", CUT_UNIWILL1024, "CLEVO_D2X0ES"
575 },
576 { SIS_650, "", "",
577 0, /* Shift LCD in LCD-via-CRT1 mode */
578 { 0, 0, 0, 0, 0 },
579 { 0, 0, 0, 0, 0 },
580 0x1734, 0x101f,
581 "Uniwill", "N243S9", CUT_UNIWILL1024, "UNIWILL_N243S9"
582 },
583 { SIS_650, "", "",
584 0, /* Shift LCD in LCD-via-CRT1 mode */
585 { 0, 0, 0, 0, 0 },
586 { 0, 0, 0, 0, 0 },
587 0x1584, 0x5103,
588 "Uniwill", "N35BS1", CUT_UNIWILL10242, "UNIWILL_N35BS1"
589 },
590 { SIS_650, "1.09.2c", "", /* Other versions, too? */
591 0, /* Shift LCD in LCD-via-CRT1 mode */
592 { 0, 0, 0, 0, 0 },
593 { 0, 0, 0, 0, 0 },
594 0x1019, 0x0f05,
595 "ECS", "A928", CUT_UNIWILL1024, "ECS_A928"
596 },
597 { SIS_740, "1.11.27a", "",
598 0,
599 { 0, 0, 0, 0, 0 },
600 { 0, 0, 0, 0, 0 },
601 0x1043, 0x1612,
602 "Asus", "L3000D/L3500D", CUT_ASUSL3000D, "ASUS_L3X00"
603 },
604 { SIS_650, "1.10.9k", "",
605 0,
606 { 0, 0, 0, 0, 0 },
607 { 0, 0, 0, 0, 0 },
608 0x1025, 0x0028,
609 "Acer", "Aspire 1700", CUT_ACER1280, "ACER_ASPIRE1700"
610 },
611 { SIS_650, "1.10.7w", "",
612 0,
613 { 0, 0, 0, 0, 0 },
614 { 0, 0, 0, 0, 0 },
615 0x14c0, 0x0012,
616 "Compal", "??? (V1)", CUT_COMPAL1400_1, "COMPAL_1400_1"
617 },
618 { SIS_650, "1.10.7x", "",
619 0,
620 { 0, 0, 0, 0, 0 },
621 { 0, 0, 0, 0, 0 },
622 0x14c0, 0x0012,
623 "Compal", "??? (V2)", CUT_COMPAL1400_2, "COMPAL_1400_2"
624 },
625 { SIS_650, "1.10.8o", "",
626 0, /* For EMI (unknown) */
627 { 0, 0, 0, 0, 0 },
628 { 0, 0, 0, 0, 0 },
629 0x1043, 0x1612,
630 "Asus", "A2H (V1)", CUT_ASUSA2H_1, "ASUS_A2H_1"
631 },
632 { SIS_650, "1.10.8q", "",
633 0, /* For EMI */
634 { 0, 0, 0, 0, 0 },
635 { 0, 0, 0, 0, 0 },
636 0x1043, 0x1612,
637 "Asus", "A2H (V2)", CUT_ASUSA2H_2, "ASUS_A2H_2"
638 },
639 { 4321, "", "", /* never autodetected */
640 0,
641 { 0, 0, 0, 0, 0 },
642 { 0, 0, 0, 0, 0 },
643 0, 0,
644 "Generic", "LVDS/Parallel 848x480", CUT_PANEL848, "PANEL848x480"
645 },
646 { 0, "", "",
647 0,
648 { 0, 0, 0, 0 },
649 { 0, 0, 0, 0 },
650 0, 0,
651 "", "", CUT_NONE, ""
652 }
653};
654
655static const struct _sis_TV_filter {
656 u8 filter[9][4];
657} sis_TV_filter[] = {
658 { {{0x00,0x00,0x00,0x40}, /* NTSCFilter_0 */
659 {0x00,0xE0,0x10,0x60},
660 {0x00,0xEE,0x10,0x44},
661 {0x00,0xF4,0x10,0x38},
662 {0xF8,0xF4,0x18,0x38},
663 {0xFC,0xFB,0x14,0x2A},
664 {0x00,0x00,0x10,0x20},
665 {0x00,0x04,0x10,0x18},
666 {0xFF,0xFF,0xFF,0xFF} }},
667 { {{0x00,0x00,0x00,0x40}, /* NTSCFilter_1 */
668 {0x00,0xE0,0x10,0x60},
669 {0x00,0xEE,0x10,0x44},
670 {0x00,0xF4,0x10,0x38},
671 {0xF8,0xF4,0x18,0x38},
672 {0xFC,0xFB,0x14,0x2A},
673 {0x00,0x00,0x10,0x20},
674 {0x00,0x04,0x10,0x18},
675 {0xFF,0xFF,0xFF,0xFF} }},
676 { {{0x00,0x00,0x00,0x40}, /* NTSCFilter_2 */
677 {0xF5,0xEE,0x1B,0x44},
678 {0xF8,0xF4,0x18,0x38},
679 {0xEB,0x04,0x25,0x18},
680 {0xF1,0x05,0x1F,0x16},
681 {0xF6,0x06,0x1A,0x14},
682 {0xFA,0x06,0x16,0x14},
683 {0x00,0x04,0x10,0x18},
684 {0xFF,0xFF,0xFF,0xFF} }},
685 { {{0x00,0x00,0x00,0x40}, /* NTSCFilter_3 */
686 {0xF1,0x04,0x1F,0x18},
687 {0xEE,0x0D,0x22,0x06},
688 {0xF7,0x06,0x19,0x14},
689 {0xF4,0x0B,0x1C,0x0A},
690 {0xFA,0x07,0x16,0x12},
691 {0xF9,0x0A,0x17,0x0C},
692 {0x00,0x07,0x10,0x12},
693 {0xFF,0xFF,0xFF,0xFF} }},
694 { {{0x00,0x00,0x00,0x40}, /* NTSCFilter_4 - 320 */
695 {0x00,0xE0,0x10,0x60},
696 {0x00,0xEE,0x10,0x44},
697 {0x00,0xF4,0x10,0x38},
698 {0xF8,0xF4,0x18,0x38},
699 {0xFC,0xFB,0x14,0x2A},
700 {0x00,0x00,0x10,0x20},
701 {0x00,0x04,0x10,0x18},
702 {0xFF,0xFF,0xFF,0xFF} }},
703 { {{0x00,0x00,0x00,0x40}, /* NTSCFilter_5 - 640 */
704 {0xF5,0xEE,0x1B,0x44},
705 {0xF8,0xF4,0x18,0x38},
706 {0xEB,0x04,0x25,0x18},
707 {0xF1,0x05,0x1F,0x16},
708 {0xF6,0x06,0x1A,0x14},
709 {0xFA,0x06,0x16,0x14},
710 {0x00,0x04,0x10,0x18},
711 {0xFF,0xFF,0xFF,0xFF} }},
712 { {{0x00,0x00,0x00,0x40}, /* NTSCFilter_6 - 720 */
713 {0xEB,0x04,0x25,0x18},
714 {0xE7,0x0E,0x29,0x04},
715 {0xEE,0x0C,0x22,0x08},
716 {0xF6,0x0B,0x1A,0x0A},
717 {0xF9,0x0A,0x17,0x0C},
718 {0xFC,0x0A,0x14,0x0C},
719 {0x00,0x08,0x10,0x10},
720 {0xFF,0xFF,0xFF,0xFF} }},
721 { {{0x00,0x00,0x00,0x40}, /* NTSCFilter_7 - 800 */
722 {0xEC,0x02,0x24,0x1C},
723 {0xF2,0x04,0x1E,0x18},
724 {0xEB,0x15,0x25,0xF6},
725 {0xF4,0x10,0x1C,0x00},
726 {0xF8,0x0F,0x18,0x02},
727 {0x00,0x04,0x10,0x18},
728 {0x01,0x06,0x0F,0x14},
729 {0xFF,0xFF,0xFF,0xFF} }},
730 { {{0x00,0x00,0x00,0x40}, /* PALFilter_0 */
731 {0x00,0xE0,0x10,0x60},
732 {0x00,0xEE,0x10,0x44},
733 {0x00,0xF4,0x10,0x38},
734 {0xF8,0xF4,0x18,0x38},
735 {0xFC,0xFB,0x14,0x2A},
736 {0x00,0x00,0x10,0x20},
737 {0x00,0x04,0x10,0x18},
738 {0xFF,0xFF,0xFF,0xFF} }},
739 { {{0x00,0x00,0x00,0x40}, /* PALFilter_1 */
740 {0x00,0xE0,0x10,0x60},
741 {0x00,0xEE,0x10,0x44},
742 {0x00,0xF4,0x10,0x38},
743 {0xF8,0xF4,0x18,0x38},
744 {0xFC,0xFB,0x14,0x2A},
745 {0x00,0x00,0x10,0x20},
746 {0x00,0x04,0x10,0x18},
747 {0xFF,0xFF,0xFF,0xFF} }},
748 { {{0x00,0x00,0x00,0x40}, /* PALFilter_2 */
749 {0xF5,0xEE,0x1B,0x44},
750 {0xF8,0xF4,0x18,0x38},
751 {0xF1,0xF7,0x01,0x32},
752 {0xF5,0xFB,0x1B,0x2A},
753 {0xF9,0xFF,0x17,0x22},
754 {0xFB,0x01,0x15,0x1E},
755 {0x00,0x04,0x10,0x18},
756 {0xFF,0xFF,0xFF,0xFF} }},
757 { {{0x00,0x00,0x00,0x40}, /* PALFilter_3 */
758 {0xF5,0xFB,0x1B,0x2A},
759 {0xEE,0xFE,0x22,0x24},
760 {0xF3,0x00,0x1D,0x20},
761 {0xF9,0x03,0x17,0x1A},
762 {0xFB,0x02,0x14,0x1E},
763 {0xFB,0x04,0x15,0x18},
764 {0x00,0x06,0x10,0x14},
765 {0xFF,0xFF,0xFF,0xFF} }},
766 { {{0x00,0x00,0x00,0x40}, /* PALFilter_4 - 320 */
767 {0x00,0xE0,0x10,0x60},
768 {0x00,0xEE,0x10,0x44},
769 {0x00,0xF4,0x10,0x38},
770 {0xF8,0xF4,0x18,0x38},
771 {0xFC,0xFB,0x14,0x2A},
772 {0x00,0x00,0x10,0x20},
773 {0x00,0x04,0x10,0x18},
774 {0xFF,0xFF,0xFF,0xFF} }},
775 { {{0x00,0x00,0x00,0x40}, /* PALFilter_5 - 640 */
776 {0xF5,0xEE,0x1B,0x44},
777 {0xF8,0xF4,0x18,0x38},
778 {0xF1,0xF7,0x1F,0x32},
779 {0xF5,0xFB,0x1B,0x2A},
780 {0xF9,0xFF,0x17,0x22},
781 {0xFB,0x01,0x15,0x1E},
782 {0x00,0x04,0x10,0x18},
783 {0xFF,0xFF,0xFF,0xFF} }},
784 { {{0x00,0x00,0x00,0x40}, /* PALFilter_6 - 720 */
785 {0xF5,0xEE,0x1B,0x2A},
786 {0xEE,0xFE,0x22,0x24},
787 {0xF3,0x00,0x1D,0x20},
788 {0xF9,0x03,0x17,0x1A},
789 {0xFB,0x02,0x14,0x1E},
790 {0xFB,0x04,0x15,0x18},
791 {0x00,0x06,0x10,0x14},
792 {0xFF,0xFF,0xFF,0xFF} }},
793 { {{0x00,0x00,0x00,0x40}, /* PALFilter_7 - 800 */
794 {0xF5,0xEE,0x1B,0x44},
795 {0xF8,0xF4,0x18,0x38},
796 {0xFC,0xFB,0x14,0x2A},
797 {0xEB,0x05,0x25,0x16},
798 {0xF1,0x05,0x1F,0x16},
799 {0xFA,0x07,0x16,0x12},
800 {0x00,0x07,0x10,0x12},
801 {0xFF,0xFF,0xFF,0xFF} }}
802};
803
804/* ---------------------- Prototypes ------------------------- */
805
806/* Interface used by the world */
807#ifndef MODULE
808SISINITSTATIC int sisfb_setup(char *options);
809#endif
810
811/* Interface to the low level console driver */
812SISINITSTATIC int sisfb_init(void);
813
814
815/* fbdev routines */
816static int sisfb_get_fix(struct fb_fix_screeninfo *fix, int con,
817 struct fb_info *info);
818
819#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
820static int sisfb_get_fix(struct fb_fix_screeninfo *fix,
821 int con,
822 struct fb_info *info);
823static int sisfb_get_var(struct fb_var_screeninfo *var,
824 int con,
825 struct fb_info *info);
826static int sisfb_set_var(struct fb_var_screeninfo *var,
827 int con,
828 struct fb_info *info);
829static void sisfb_crtc_to_var(struct sis_video_info *ivideo,
830 struct fb_var_screeninfo *var);
831static int sisfb_get_cmap(struct fb_cmap *cmap,
832 int kspc,
833 int con,
834 struct fb_info *info);
835static int sisfb_set_cmap(struct fb_cmap *cmap,
836 int kspc,
837 int con,
838 struct fb_info *info);
839static int sisfb_update_var(int con,
840 struct fb_info *info);
841static int sisfb_switch(int con,
842 struct fb_info *info);
843static void sisfb_blank(int blank,
844 struct fb_info *info);
845static void sisfb_set_disp(int con,
846 struct fb_var_screeninfo *var,
847 struct fb_info *info);
848static int sis_getcolreg(unsigned regno, unsigned *red, unsigned *green,
849 unsigned *blue, unsigned *transp,
850 struct fb_info *fb_info);
851static void sisfb_do_install_cmap(int con,
852 struct fb_info *info);
853static int sisfb_ioctl(struct inode *inode, struct file *file,
854 unsigned int cmd, unsigned long arg, int con,
855 struct fb_info *info);
856#endif
857
858#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
859static int sisfb_ioctl(struct inode *inode, struct file *file,
860 unsigned int cmd, unsigned long arg,
861 struct fb_info *info);
862static int sisfb_set_par(struct fb_info *info);
863static int sisfb_blank(int blank,
864 struct fb_info *info);
865extern void fbcon_sis_fillrect(struct fb_info *info,
866 const struct fb_fillrect *rect);
867extern void fbcon_sis_copyarea(struct fb_info *info,
868 const struct fb_copyarea *area);
869extern int fbcon_sis_sync(struct fb_info *info);
870#endif
871
872/* Internal 2D accelerator functions */
873extern int sisfb_initaccel(struct sis_video_info *ivideo);
874extern void sisfb_syncaccel(struct sis_video_info *ivideo);
875
876/* Internal general routines */
877static void sisfb_search_mode(char *name, BOOLEAN quiet);
878static int sisfb_validate_mode(struct sis_video_info *ivideo, int modeindex, u32 vbflags);
879static u8 sisfb_search_refresh_rate(struct sis_video_info *ivideo, unsigned int rate,
880 int index);
881static int sisfb_setcolreg(unsigned regno, unsigned red, unsigned green,
882 unsigned blue, unsigned transp,
883 struct fb_info *fb_info);
884static int sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
885 struct fb_info *info);
886static void sisfb_pre_setmode(struct sis_video_info *ivideo);
887static void sisfb_post_setmode(struct sis_video_info *ivideo);
888static BOOLEAN sisfb_CheckVBRetrace(struct sis_video_info *ivideo);
889static BOOLEAN sisfbcheckvretracecrt2(struct sis_video_info *ivideo);
890static BOOLEAN sisfbcheckvretracecrt1(struct sis_video_info *ivideo);
891static BOOLEAN sisfb_bridgeisslave(struct sis_video_info *ivideo);
892static void sisfb_detect_VB_connect(struct sis_video_info *ivideo);
893static void sisfb_get_VB_type(struct sis_video_info *ivideo);
894static void sisfb_set_TVxposoffset(struct sis_video_info *ivideo, int val);
895static void sisfb_set_TVyposoffset(struct sis_video_info *ivideo, int val);
896
897/* SiS-specific exported functions */
898void sis_malloc(struct sis_memreq *req);
899void sis_free(u32 base);
900
901/* Internal heap routines */
902static int sisfb_heap_init(struct sis_video_info *ivideo);
903static SIS_OH *sisfb_poh_new_node(void);
904static SIS_OH *sisfb_poh_allocate(u32 size);
905static void sisfb_delete_node(SIS_OH *poh);
906static void sisfb_insert_node(SIS_OH *pohList, SIS_OH *poh);
907static SIS_OH *sisfb_poh_free(u32 base);
908static void sisfb_free_node(SIS_OH *poh);
909
910/* Sensing routines */
911static void SiS_Sense30x(struct sis_video_info *ivideo);
912static void SiS_SenseCh(struct sis_video_info *ivideo);
913
914/* Routines from init.c/init301.c */
915extern USHORT SiS_GetModeID_LCD(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth,
916 BOOLEAN FSTN, USHORT CustomT, int LCDwith, int LCDheight);
917extern USHORT SiS_GetModeID_TV(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth);
918extern USHORT SiS_GetModeID_VGA2(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth);
919
920extern void SiSRegInit(SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr);
921extern BOOLEAN SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwDeviceInfo, USHORT ModeNo);
922extern void SiS_SetEnableDstn(SiS_Private *SiS_Pr, int enable);
923extern void SiS_SetEnableFstn(SiS_Private *SiS_Pr, int enable);
924
925extern BOOLEAN SiSDetermineROMLayout661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
926
927extern BOOLEAN sisfb_gettotalfrommode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwDeviceExtension,
928 unsigned char modeno, int *htotal, int *vtotal, unsigned char rateindex);
929#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
930extern int sisfb_mode_rate_to_dclock(SiS_Private *SiS_Pr,
931 PSIS_HW_INFO HwDeviceExtension,
932 unsigned char modeno, unsigned char rateindex);
933extern int sisfb_mode_rate_to_ddata(SiS_Private *SiS_Pr, PSIS_HW_INFO HwDeviceExtension,
934 unsigned char modeno, unsigned char rateindex,
935 struct fb_var_screeninfo *var);
936#endif
937
938/* Chrontel TV, DDC and DPMS functions */
939extern USHORT SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempbx);
940extern void SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempbx);
941extern USHORT SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempbx);
942extern void SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempbx);
943extern void SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, USHORT tempax,USHORT tempbh);
944extern void SiS_DDC2Delay(SiS_Private *SiS_Pr, USHORT delaytime);
945extern void SiS_SetChrontelGPIO(SiS_Private *SiS_Pr, USHORT myvbinfo);
946extern USHORT SiS_HandleDDC(SiS_Private *SiS_Pr, ULONG VBFlags, int VGAEngine,
947 USHORT adaptnum, USHORT DDCdatatype, unsigned char *buffer);
948extern USHORT SiS_ReadDDC1Bit(SiS_Private *SiS_Pr);
949extern void SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwDeviceInfo);
950extern void SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr);
951extern void SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwDeviceInfo);
952extern void SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwDeviceInfo);
953#endif
954
955
diff --git a/drivers/video/sis/vgatypes.h b/drivers/video/sis/vgatypes.h
new file mode 100644
index 000000000000..507bba1a71b5
--- /dev/null
+++ b/drivers/video/sis/vgatypes.h
@@ -0,0 +1,242 @@
1/* $XFree86$ */
2/* $XdotOrg$ */
3/*
4 * General type definitions for universal mode switching modules
5 *
6 * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
7 *
8 * If distributed as part of the Linux kernel, the following license terms
9 * apply:
10 *
11 * * This program is free software; you can redistribute it and/or modify
12 * * it under the terms of the GNU General Public License as published by
13 * * the Free Software Foundation; either version 2 of the named License,
14 * * or any later version.
15 * *
16 * * This program is distributed in the hope that it will be useful,
17 * * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * * GNU General Public License for more details.
20 * *
21 * * You should have received a copy of the GNU General Public License
22 * * along with this program; if not, write to the Free Software
23 * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
24 *
25 * Otherwise, the following license terms apply:
26 *
27 * * Redistribution and use in source and binary forms, with or without
28 * * modification, are permitted provided that the following conditions
29 * * are met:
30 * * 1) Redistributions of source code must retain the above copyright
31 * * notice, this list of conditions and the following disclaimer.
32 * * 2) Redistributions in binary form must reproduce the above copyright
33 * * notice, this list of conditions and the following disclaimer in the
34 * * documentation and/or other materials provided with the distribution.
35 * * 3) The name of the author may not be used to endorse or promote products
36 * * derived from this software without specific prior written permission.
37 * *
38 * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
39 * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
40 * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
41 * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
42 * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
43 * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
44 * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
45 * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46 * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
47 * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48 *
49 * Author: Thomas Winischhofer <thomas@winischhofer.net>
50 *
51 */
52
53#ifndef _VGATYPES_
54#define _VGATYPES_
55
56#ifdef LINUX_KERNEL /* We don't want the X driver to depend on kernel source */
57#include <linux/ioctl.h>
58#include <linux/version.h>
59#endif
60
61#ifndef FALSE
62#define FALSE 0
63#endif
64
65#ifndef TRUE
66#define TRUE 1
67#endif
68
69#ifndef NULL
70#define NULL 0
71#endif
72
73#ifndef CHAR
74typedef char CHAR;
75#endif
76
77#ifndef SHORT
78typedef short SHORT;
79#endif
80
81#ifndef LONG
82typedef long LONG;
83#endif
84
85#ifndef UCHAR
86typedef unsigned char UCHAR;
87#endif
88
89#ifndef USHORT
90typedef unsigned short USHORT;
91#endif
92
93#ifndef ULONG
94typedef unsigned long ULONG;
95#endif
96
97#ifndef BOOLEAN
98typedef unsigned char BOOLEAN;
99#endif
100
101#define SISIOMEMTYPE
102
103#ifdef LINUX_KERNEL
104typedef unsigned long SISIOADDRESS;
105#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)
106#include <linux/types.h> /* Need __iomem */
107#undef SISIOMEMTYPE
108#define SISIOMEMTYPE __iomem
109#endif
110#endif
111
112#ifdef LINUX_XF86
113#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,0,0,0)
114typedef unsigned long IOADDRESS;
115typedef unsigned long SISIOADDRESS;
116#else
117typedef IOADDRESS SISIOADDRESS;
118#endif
119#endif
120
121enum _SIS_CHIP_TYPE {
122 SIS_VGALegacy = 0,
123 SIS_530,
124 SIS_OLD,
125 SIS_300,
126 SIS_630,
127 SIS_730,
128 SIS_540,
129 SIS_315H, /* SiS 310 */
130 SIS_315,
131 SIS_315PRO,
132 SIS_550,
133 SIS_650,
134 SIS_740,
135 SIS_330,
136 SIS_661,
137 SIS_741,
138 SIS_660,
139 SIS_760,
140 SIS_761,
141 SIS_340,
142 MAX_SIS_CHIP
143};
144
145#ifndef SIS_HW_INFO
146typedef struct _SIS_HW_INFO SIS_HW_INFO, *PSIS_HW_INFO;
147
148struct _SIS_HW_INFO
149{
150#ifdef LINUX_XF86
151 PCITAG PciTag; /* PCI Tag */
152#endif
153
154 UCHAR *pjVirtualRomBase; /* ROM image */
155
156 BOOLEAN UseROM; /* Use the ROM image if provided */
157
158#ifdef LINUX_KERNEL
159 UCHAR SISIOMEMTYPE *pjVideoMemoryAddress;
160 /* base virtual memory address */
161 /* of Linear VGA memory */
162
163 ULONG ulVideoMemorySize; /* size, in bytes, of the memory on the board */
164#endif
165
166 SISIOADDRESS ulIOAddress; /* base I/O address of VGA ports (0x3B0; relocated) */
167
168 UCHAR jChipType; /* Used to Identify SiS Graphics Chip */
169 /* defined in the enum "SIS_CHIP_TYPE" (above or sisfb.h) */
170
171 UCHAR jChipRevision; /* Used to Identify SiS Graphics Chip Revision */
172
173 BOOLEAN bIntegratedMMEnabled;/* supporting integration MM enable */
174};
175#endif
176
177/* Addtional IOCTLs for communication sisfb <> X driver */
178/* If changing this, sisfb.h must also be changed (for sisfb) */
179
180#ifdef LINUX_XF86 /* We don't want the X driver to depend on the kernel source */
181
182/* ioctl for identifying and giving some info (esp. memory heap start) */
183#define SISFB_GET_INFO_SIZE 0x8004f300
184#define SISFB_GET_INFO 0x8000f301 /* Must be patched with result from ..._SIZE at D[29:16] */
185/* deprecated ioctl number (for older versions of sisfb) */
186#define SISFB_GET_INFO_OLD 0x80046ef8
187
188/* ioctls for tv parameters (position) */
189#define SISFB_SET_TVPOSOFFSET 0x4004f304
190
191/* lock sisfb from register access */
192#define SISFB_SET_LOCK 0x4004f306
193
194/* Structure argument for SISFB_GET_INFO ioctl */
195typedef struct _SISFB_INFO sisfb_info, *psisfb_info;
196
197struct _SISFB_INFO {
198 CARD32 sisfb_id; /* for identifying sisfb */
199#ifndef SISFB_ID
200#define SISFB_ID 0x53495346 /* Identify myself with 'SISF' */
201#endif
202 CARD32 chip_id; /* PCI ID of detected chip */
203 CARD32 memory; /* video memory in KB which sisfb manages */
204 CARD32 heapstart; /* heap start (= sisfb "mem" argument) in KB */
205 CARD8 fbvidmode; /* current sisfb mode */
206
207 CARD8 sisfb_version;
208 CARD8 sisfb_revision;
209 CARD8 sisfb_patchlevel;
210
211 CARD8 sisfb_caps; /* sisfb's capabilities */
212
213 CARD32 sisfb_tqlen; /* turbo queue length (in KB) */
214
215 CARD32 sisfb_pcibus; /* The card's PCI ID */
216 CARD32 sisfb_pcislot;
217 CARD32 sisfb_pcifunc;
218
219 CARD8 sisfb_lcdpdc;
220
221 CARD8 sisfb_lcda;
222
223 CARD32 sisfb_vbflags;
224 CARD32 sisfb_currentvbflags;
225
226 CARD32 sisfb_scalelcd;
227 CARD32 sisfb_specialtiming;
228
229 CARD8 sisfb_haveemi;
230 CARD8 sisfb_emi30,sisfb_emi31,sisfb_emi32,sisfb_emi33;
231 CARD8 sisfb_haveemilcd;
232
233 CARD8 sisfb_lcdpdca;
234
235 CARD16 sisfb_tvxpos, sisfb_tvypos; /* Warning: Values + 32 ! */
236
237 CARD8 reserved[208]; /* for future use */
238};
239#endif
240
241#endif
242
diff --git a/drivers/video/sis/vstruct.h b/drivers/video/sis/vstruct.h
new file mode 100644
index 000000000000..d4d55c98bce6
--- /dev/null
+++ b/drivers/video/sis/vstruct.h
@@ -0,0 +1,676 @@
1/* $XFree86$ */
2/* $XdotOrg$ */
3/*
4 * General structure definitions for universal mode switching modules
5 *
6 * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
7 *
8 * If distributed as part of the Linux kernel, the following license terms
9 * apply:
10 *
11 * * This program is free software; you can redistribute it and/or modify
12 * * it under the terms of the GNU General Public License as published by
13 * * the Free Software Foundation; either version 2 of the named License,
14 * * or any later version.
15 * *
16 * * This program is distributed in the hope that it will be useful,
17 * * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * * GNU General Public License for more details.
20 * *
21 * * You should have received a copy of the GNU General Public License
22 * * along with this program; if not, write to the Free Software
23 * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
24 *
25 * Otherwise, the following license terms apply:
26 *
27 * * Redistribution and use in source and binary forms, with or without
28 * * modification, are permitted provided that the following conditions
29 * * are met:
30 * * 1) Redistributions of source code must retain the above copyright
31 * * notice, this list of conditions and the following disclaimer.
32 * * 2) Redistributions in binary form must reproduce the above copyright
33 * * notice, this list of conditions and the following disclaimer in the
34 * * documentation and/or other materials provided with the distribution.
35 * * 3) The name of the author may not be used to endorse or promote products
36 * * derived from this software without specific prior written permission.
37 * *
38 * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
39 * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
40 * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
41 * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
42 * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
43 * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
44 * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
45 * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46 * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
47 * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48 *
49 * Author: Thomas Winischhofer <thomas@winischhofer.net>
50 *
51 */
52
53#ifndef _VSTRUCT_
54#define _VSTRUCT_
55
56typedef struct _SiS_PanelDelayTblStruct
57{
58 UCHAR timer[2];
59} SiS_PanelDelayTblStruct;
60
61typedef struct _SiS_LCDDataStruct
62{
63 USHORT RVBHCMAX;
64 USHORT RVBHCFACT;
65 USHORT VGAHT;
66 USHORT VGAVT;
67 USHORT LCDHT;
68 USHORT LCDVT;
69} SiS_LCDDataStruct;
70
71typedef struct _SiS_TVDataStruct
72{
73 USHORT RVBHCMAX;
74 USHORT RVBHCFACT;
75 USHORT VGAHT;
76 USHORT VGAVT;
77 USHORT TVHDE;
78 USHORT TVVDE;
79 USHORT RVBHRS;
80 UCHAR FlickerMode;
81 USHORT HALFRVBHRS;
82 UCHAR RY1COE;
83 UCHAR RY2COE;
84 UCHAR RY3COE;
85 UCHAR RY4COE;
86} SiS_TVDataStruct;
87
88typedef struct _SiS_LVDSDataStruct
89{
90 USHORT VGAHT;
91 USHORT VGAVT;
92 USHORT LCDHT;
93 USHORT LCDVT;
94} SiS_LVDSDataStruct;
95
96typedef struct _SiS_LVDSDesStruct
97{
98 USHORT LCDHDES;
99 USHORT LCDVDES;
100} SiS_LVDSDesStruct;
101
102typedef struct _SiS_LVDSCRT1DataStruct
103{
104 UCHAR CR[15];
105} SiS_LVDSCRT1DataStruct;
106
107typedef struct _SiS_LCDACRT1DataStruct
108{
109 UCHAR CR[17];
110} SiS_LCDACRT1DataStruct;
111
112typedef struct _SiS_CHTVRegDataStruct
113{
114 UCHAR Reg[16];
115} SiS_CHTVRegDataStruct;
116
117typedef struct _SiS_StStruct
118{
119 UCHAR St_ModeID;
120 USHORT St_ModeFlag;
121 UCHAR St_StTableIndex;
122 UCHAR St_CRT2CRTC;
123 UCHAR St_ResInfo;
124 UCHAR VB_StTVFlickerIndex;
125 UCHAR VB_StTVEdgeIndex;
126 UCHAR VB_StTVYFilterIndex;
127 UCHAR St_PDC;
128} SiS_StStruct;
129
130typedef struct _SiS_VBModeStruct
131{
132 UCHAR ModeID;
133 UCHAR VB_TVDelayIndex;
134 UCHAR VB_TVFlickerIndex;
135 UCHAR VB_TVPhaseIndex;
136 UCHAR VB_TVYFilterIndex;
137 UCHAR VB_LCDDelayIndex;
138 UCHAR _VB_LCDHIndex;
139 UCHAR _VB_LCDVIndex;
140} SiS_VBModeStruct;
141
142typedef struct _SiS_StandTableStruct
143{
144 UCHAR CRT_COLS;
145 UCHAR ROWS;
146 UCHAR CHAR_HEIGHT;
147 USHORT CRT_LEN;
148 UCHAR SR[4];
149 UCHAR MISC;
150 UCHAR CRTC[0x19];
151 UCHAR ATTR[0x14];
152 UCHAR GRC[9];
153} SiS_StandTableStruct;
154
155typedef struct _SiS_ExtStruct
156{
157 UCHAR Ext_ModeID;
158 USHORT Ext_ModeFlag;
159 USHORT Ext_VESAID;
160 UCHAR Ext_RESINFO;
161 UCHAR VB_ExtTVFlickerIndex;
162 UCHAR VB_ExtTVEdgeIndex;
163 UCHAR VB_ExtTVYFilterIndex;
164 UCHAR VB_ExtTVYFilterIndexROM661;
165 UCHAR REFindex;
166 CHAR ROMMODEIDX661;
167} SiS_ExtStruct;
168
169typedef struct _SiS_Ext2Struct
170{
171 USHORT Ext_InfoFlag;
172 UCHAR Ext_CRT1CRTC;
173 UCHAR Ext_CRTVCLK;
174 UCHAR Ext_CRT2CRTC;
175 UCHAR Ext_CRT2CRTC_NS;
176 UCHAR ModeID;
177 USHORT XRes;
178 USHORT YRes;
179 UCHAR Ext_PDC;
180} SiS_Ext2Struct;
181
182typedef struct _SiS_Part2PortTblStruct
183{
184 UCHAR CR[12];
185} SiS_Part2PortTblStruct;
186
187typedef struct _SiS_CRT1TableStruct
188{
189 UCHAR CR[17];
190} SiS_CRT1TableStruct;
191
192typedef struct _SiS_MCLKDataStruct
193{
194 UCHAR SR28,SR29,SR2A;
195 USHORT CLOCK;
196} SiS_MCLKDataStruct;
197
198typedef struct _SiS_VCLKDataStruct
199{
200 UCHAR SR2B,SR2C;
201 USHORT CLOCK;
202} SiS_VCLKDataStruct;
203
204typedef struct _SiS_VBVCLKDataStruct
205{
206 UCHAR Part4_A,Part4_B;
207 USHORT CLOCK;
208} SiS_VBVCLKDataStruct;
209
210typedef struct _SiS_StResInfoStruct
211{
212 USHORT HTotal;
213 USHORT VTotal;
214} SiS_StResInfoStruct;
215
216typedef struct _SiS_ModeResInfoStruct
217{
218 USHORT HTotal;
219 USHORT VTotal;
220 UCHAR XChar;
221 UCHAR YChar;
222} SiS_ModeResInfoStruct;
223
224
225
226typedef UCHAR DRAM4Type[4];
227
228/* Defines for SiS_CustomT */
229/* Never change these for sisfb compatibility */
230#define CUT_NONE 0
231#define CUT_FORCENONE 1
232#define CUT_BARCO1366 2
233#define CUT_BARCO1024 3
234#define CUT_COMPAQ1280 4
235#define CUT_COMPAQ12802 5
236#define CUT_PANEL848 6
237#define CUT_CLEVO1024 7
238#define CUT_CLEVO10242 8
239#define CUT_CLEVO1400 9
240#define CUT_CLEVO14002 10
241#define CUT_UNIWILL1024 11
242#define CUT_ASUSL3000D 12
243#define CUT_UNIWILL10242 13
244#define CUT_ACER1280 14
245#define CUT_COMPAL1400_1 15
246#define CUT_COMPAL1400_2 16
247#define CUT_ASUSA2H_1 17
248#define CUT_ASUSA2H_2 18
249
250typedef struct _SiS_Private
251{
252#ifdef LINUX_KERNEL
253 SISIOADDRESS RelIO;
254#endif
255 SISIOADDRESS SiS_P3c4;
256 SISIOADDRESS SiS_P3d4;
257 SISIOADDRESS SiS_P3c0;
258 SISIOADDRESS SiS_P3ce;
259 SISIOADDRESS SiS_P3c2;
260 SISIOADDRESS SiS_P3ca;
261 SISIOADDRESS SiS_P3c6;
262 SISIOADDRESS SiS_P3c7;
263 SISIOADDRESS SiS_P3c8;
264 SISIOADDRESS SiS_P3c9;
265 SISIOADDRESS SiS_P3cb;
266 SISIOADDRESS SiS_P3cd;
267 SISIOADDRESS SiS_P3da;
268 SISIOADDRESS SiS_Part1Port;
269 SISIOADDRESS SiS_Part2Port;
270 SISIOADDRESS SiS_Part3Port;
271 SISIOADDRESS SiS_Part4Port;
272 SISIOADDRESS SiS_Part5Port;
273 SISIOADDRESS SiS_VidCapt;
274 SISIOADDRESS SiS_VidPlay;
275 USHORT SiS_IF_DEF_LVDS;
276 USHORT SiS_IF_DEF_CH70xx;
277 USHORT SiS_IF_DEF_CONEX;
278 USHORT SiS_IF_DEF_TRUMPION;
279 USHORT SiS_IF_DEF_DSTN;
280 USHORT SiS_IF_DEF_FSTN;
281 USHORT SiS_SysFlags;
282 UCHAR SiS_VGAINFO;
283#ifdef LINUX_XF86
284 USHORT SiS_CP1, SiS_CP2, SiS_CP3, SiS_CP4;
285#endif
286 BOOLEAN SiS_UseROM;
287 BOOLEAN SiS_ROMNew;
288 BOOLEAN SiS_NeedRomModeData;
289 BOOLEAN PanelSelfDetected;
290 int SiS_CHOverScan;
291 BOOLEAN SiS_CHSOverScan;
292 BOOLEAN SiS_ChSW;
293 BOOLEAN SiS_UseLCDA;
294 int SiS_UseOEM;
295 ULONG SiS_CustomT;
296 USHORT SiS_Backup70xx;
297 BOOLEAN HaveEMI;
298 BOOLEAN HaveEMILCD;
299 BOOLEAN OverruleEMI;
300 UCHAR EMI_30,EMI_31,EMI_32,EMI_33;
301 USHORT SiS_EMIOffset;
302 SHORT PDC, PDCA;
303 UCHAR SiS_MyCR63;
304 USHORT SiS_CRT1Mode;
305 USHORT SiS_flag_clearbuffer;
306 int SiS_RAMType;
307 UCHAR SiS_ChannelAB;
308 UCHAR SiS_DataBusWidth;
309 USHORT SiS_ModeType;
310 USHORT SiS_VBInfo;
311 USHORT SiS_TVMode;
312 USHORT SiS_LCDResInfo;
313 USHORT SiS_LCDTypeInfo;
314 USHORT SiS_LCDInfo;
315 USHORT SiS_LCDInfo661;
316 USHORT SiS_VBType;
317 USHORT SiS_VBExtInfo;
318 USHORT SiS_YPbPr;
319 USHORT SiS_SelectCRT2Rate;
320 USHORT SiS_SetFlag;
321 USHORT SiS_RVBHCFACT;
322 USHORT SiS_RVBHCMAX;
323 USHORT SiS_RVBHRS;
324 USHORT SiS_VGAVT;
325 USHORT SiS_VGAHT;
326 USHORT SiS_VT;
327 USHORT SiS_HT;
328 USHORT SiS_VGAVDE;
329 USHORT SiS_VGAHDE;
330 USHORT SiS_VDE;
331 USHORT SiS_HDE;
332 USHORT SiS_NewFlickerMode;
333 USHORT SiS_RY1COE;
334 USHORT SiS_RY2COE;
335 USHORT SiS_RY3COE;
336 USHORT SiS_RY4COE;
337 USHORT SiS_LCDHDES;
338 USHORT SiS_LCDVDES;
339 USHORT SiS_DDC_Port;
340 USHORT SiS_DDC_Index;
341 USHORT SiS_DDC_Data;
342 USHORT SiS_DDC_NData;
343 USHORT SiS_DDC_Clk;
344 USHORT SiS_DDC_NClk;
345 USHORT SiS_DDC_DeviceAddr;
346 USHORT SiS_DDC_ReadAddr;
347 USHORT SiS_DDC_SecAddr;
348 USHORT SiS_ChrontelInit;
349 BOOLEAN SiS_SensibleSR11;
350 USHORT SiS661LCD2TableSize;
351
352 USHORT SiS_PanelMinLVDS;
353 USHORT SiS_PanelMin301;
354
355 const SiS_StStruct *SiS_SModeIDTable;
356 const SiS_StandTableStruct *SiS_StandTable;
357 const SiS_ExtStruct *SiS_EModeIDTable;
358 const SiS_Ext2Struct *SiS_RefIndex;
359 const SiS_VBModeStruct *SiS_VBModeIDTable;
360 const SiS_CRT1TableStruct *SiS_CRT1Table;
361 const SiS_MCLKDataStruct *SiS_MCLKData_0;
362 const SiS_MCLKDataStruct *SiS_MCLKData_1;
363 SiS_VCLKDataStruct *SiS_VCLKData;
364 SiS_VBVCLKDataStruct *SiS_VBVCLKData;
365 const SiS_StResInfoStruct *SiS_StResInfo;
366 const SiS_ModeResInfoStruct *SiS_ModeResInfo;
367
368 const UCHAR *pSiS_OutputSelect;
369 const UCHAR *pSiS_SoftSetting;
370
371 const DRAM4Type *SiS_SR15; /* pointer : point to array */
372#ifdef LINUX_KERNEL
373 UCHAR *pSiS_SR07;
374 const DRAM4Type *SiS_CR40; /* pointer : point to array */
375 UCHAR *SiS_CR49;
376 UCHAR *SiS_SR25;
377 UCHAR *pSiS_SR1F;
378 UCHAR *pSiS_SR21;
379 UCHAR *pSiS_SR22;
380 UCHAR *pSiS_SR23;
381 UCHAR *pSiS_SR24;
382 UCHAR *pSiS_SR31;
383 UCHAR *pSiS_SR32;
384 UCHAR *pSiS_SR33;
385 UCHAR *pSiS_CRT2Data_1_2;
386 UCHAR *pSiS_CRT2Data_4_D;
387 UCHAR *pSiS_CRT2Data_4_E;
388 UCHAR *pSiS_CRT2Data_4_10;
389 const USHORT *pSiS_RGBSenseData;
390 const USHORT *pSiS_VideoSenseData;
391 const USHORT *pSiS_YCSenseData;
392 const USHORT *pSiS_RGBSenseData2;
393 const USHORT *pSiS_VideoSenseData2;
394 const USHORT *pSiS_YCSenseData2;
395#endif
396
397 const SiS_PanelDelayTblStruct *SiS_PanelDelayTbl;
398 const SiS_PanelDelayTblStruct *SiS_PanelDelayTblLVDS;
399
400 /* SiS bridge */
401
402 const UCHAR *SiS_NTSCPhase;
403 const UCHAR *SiS_PALPhase;
404 const UCHAR *SiS_NTSCPhase2;
405 const UCHAR *SiS_PALPhase2;
406 const UCHAR *SiS_PALMPhase;
407 const UCHAR *SiS_PALNPhase;
408 const UCHAR *SiS_PALMPhase2;
409 const UCHAR *SiS_PALNPhase2;
410 const UCHAR *SiS_SpecialPhase;
411 const UCHAR *SiS_SpecialPhaseM;
412 const UCHAR *SiS_SpecialPhaseJ;
413 const SiS_LCDDataStruct *SiS_ExtLCD1024x768Data;
414 const SiS_LCDDataStruct *SiS_St2LCD1024x768Data;
415 const SiS_LCDDataStruct *SiS_LCD1280x720Data;
416 const SiS_LCDDataStruct *SiS_StLCD1280x768_2Data;
417 const SiS_LCDDataStruct *SiS_ExtLCD1280x768_2Data;
418 const SiS_LCDDataStruct *SiS_LCD1280x800Data;
419 const SiS_LCDDataStruct *SiS_LCD1280x800_2Data;
420 const SiS_LCDDataStruct *SiS_LCD1280x960Data;
421 const SiS_LCDDataStruct *SiS_ExtLCD1280x1024Data;
422 const SiS_LCDDataStruct *SiS_St2LCD1280x1024Data;
423 const SiS_LCDDataStruct *SiS_StLCD1400x1050Data;
424 const SiS_LCDDataStruct *SiS_ExtLCD1400x1050Data;
425 const SiS_LCDDataStruct *SiS_StLCD1600x1200Data;
426 const SiS_LCDDataStruct *SiS_ExtLCD1600x1200Data;
427 const SiS_LCDDataStruct *SiS_LCD1680x1050Data;
428 const SiS_LCDDataStruct *SiS_NoScaleData;
429 const SiS_TVDataStruct *SiS_StPALData;
430 const SiS_TVDataStruct *SiS_ExtPALData;
431 const SiS_TVDataStruct *SiS_StNTSCData;
432 const SiS_TVDataStruct *SiS_ExtNTSCData;
433 const SiS_TVDataStruct *SiS_St1HiTVData;
434 const SiS_TVDataStruct *SiS_St2HiTVData;
435 const SiS_TVDataStruct *SiS_ExtHiTVData;
436 const SiS_TVDataStruct *SiS_St525iData;
437 const SiS_TVDataStruct *SiS_St525pData;
438 const SiS_TVDataStruct *SiS_St750pData;
439 const SiS_TVDataStruct *SiS_Ext525iData;
440 const SiS_TVDataStruct *SiS_Ext525pData;
441 const SiS_TVDataStruct *SiS_Ext750pData;
442 const UCHAR *SiS_NTSCTiming;
443 const UCHAR *SiS_PALTiming;
444 const UCHAR *SiS_HiTVExtTiming;
445 const UCHAR *SiS_HiTVSt1Timing;
446 const UCHAR *SiS_HiTVSt2Timing;
447 const UCHAR *SiS_HiTVGroup3Data;
448 const UCHAR *SiS_HiTVGroup3Simu;
449#if 0
450 const UCHAR *SiS_HiTVTextTiming;
451 const UCHAR *SiS_HiTVGroup3Text;
452#endif
453
454 const SiS_Part2PortTblStruct *SiS_CRT2Part2_1024x768_1;
455 const SiS_Part2PortTblStruct *SiS_CRT2Part2_1280x1024_1;
456 const SiS_Part2PortTblStruct *SiS_CRT2Part2_1024x768_2;
457 const SiS_Part2PortTblStruct *SiS_CRT2Part2_1280x1024_2;
458 const SiS_Part2PortTblStruct *SiS_CRT2Part2_1024x768_3;
459 const SiS_Part2PortTblStruct *SiS_CRT2Part2_1280x1024_3;
460
461 /* LVDS, Chrontel */
462
463 const SiS_LVDSDataStruct *SiS_LVDS800x600Data_1;
464 const SiS_LVDSDataStruct *SiS_LVDS800x600Data_2;
465 const SiS_LVDSDataStruct *SiS_LVDS1024x768Data_1;
466 const SiS_LVDSDataStruct *SiS_LVDS1024x768Data_2;
467 const SiS_LVDSDataStruct *SiS_LVDS1280x1024Data_1;
468 const SiS_LVDSDataStruct *SiS_LVDS1280x1024Data_2;
469 const SiS_LVDSDataStruct *SiS_LVDS1280x960Data_1;
470 const SiS_LVDSDataStruct *SiS_LVDS1280x960Data_2;
471 const SiS_LVDSDataStruct *SiS_LVDS1400x1050Data_1;
472 const SiS_LVDSDataStruct *SiS_LVDS1400x1050Data_2;
473 const SiS_LVDSDataStruct *SiS_LVDS1600x1200Data_1;
474 const SiS_LVDSDataStruct *SiS_LVDS1600x1200Data_2;
475 const SiS_LVDSDataStruct *SiS_LVDS1280x768Data_1;
476 const SiS_LVDSDataStruct *SiS_LVDS1280x768Data_2;
477 const SiS_LVDSDataStruct *SiS_LVDS1024x600Data_1;
478 const SiS_LVDSDataStruct *SiS_LVDS1024x600Data_2;
479 const SiS_LVDSDataStruct *SiS_LVDS1152x768Data_1;
480 const SiS_LVDSDataStruct *SiS_LVDS1152x768Data_2;
481 const SiS_LVDSDataStruct *SiS_LVDS640x480Data_1;
482 const SiS_LVDSDataStruct *SiS_LVDS640x480Data_2;
483 const SiS_LVDSDataStruct *SiS_LVDS320x480Data_1;
484 const SiS_LVDSDataStruct *SiS_LVDSXXXxXXXData_1;
485 const SiS_LVDSDataStruct *SiS_LVDSBARCO1366Data_1;
486 const SiS_LVDSDataStruct *SiS_LVDSBARCO1366Data_2;
487 const SiS_LVDSDataStruct *SiS_LVDSBARCO1024Data_1;
488 const SiS_LVDSDataStruct *SiS_LVDSBARCO1024Data_2;
489 const SiS_LVDSDataStruct *SiS_LVDS848x480Data_1;
490 const SiS_LVDSDataStruct *SiS_LVDS848x480Data_2;
491 const SiS_LVDSDataStruct *SiS_CHTVUNTSCData;
492 const SiS_LVDSDataStruct *SiS_CHTVONTSCData;
493 const SiS_LVDSDataStruct *SiS_CHTVUPALData;
494 const SiS_LVDSDataStruct *SiS_CHTVOPALData;
495 const SiS_LVDSDataStruct *SiS_CHTVUPALMData;
496 const SiS_LVDSDataStruct *SiS_CHTVOPALMData;
497 const SiS_LVDSDataStruct *SiS_CHTVUPALNData;
498 const SiS_LVDSDataStruct *SiS_CHTVOPALNData;
499 const SiS_LVDSDataStruct *SiS_CHTVSOPALData;
500
501 const SiS_LVDSDesStruct *SiS_PanelType00_1;
502 const SiS_LVDSDesStruct *SiS_PanelType01_1;
503 const SiS_LVDSDesStruct *SiS_PanelType02_1;
504 const SiS_LVDSDesStruct *SiS_PanelType03_1;
505 const SiS_LVDSDesStruct *SiS_PanelType04_1;
506 const SiS_LVDSDesStruct *SiS_PanelType05_1;
507 const SiS_LVDSDesStruct *SiS_PanelType06_1;
508 const SiS_LVDSDesStruct *SiS_PanelType07_1;
509 const SiS_LVDSDesStruct *SiS_PanelType08_1;
510 const SiS_LVDSDesStruct *SiS_PanelType09_1;
511 const SiS_LVDSDesStruct *SiS_PanelType0a_1;
512 const SiS_LVDSDesStruct *SiS_PanelType0b_1;
513 const SiS_LVDSDesStruct *SiS_PanelType0c_1;
514 const SiS_LVDSDesStruct *SiS_PanelType0d_1;
515 const SiS_LVDSDesStruct *SiS_PanelType0e_1;
516 const SiS_LVDSDesStruct *SiS_PanelType0f_1;
517 const SiS_LVDSDesStruct *SiS_PanelTypeNS_1;
518 const SiS_LVDSDesStruct *SiS_PanelType00_2;
519 const SiS_LVDSDesStruct *SiS_PanelType01_2;
520 const SiS_LVDSDesStruct *SiS_PanelType02_2;
521 const SiS_LVDSDesStruct *SiS_PanelType03_2;
522 const SiS_LVDSDesStruct *SiS_PanelType04_2;
523 const SiS_LVDSDesStruct *SiS_PanelType05_2;
524 const SiS_LVDSDesStruct *SiS_PanelType06_2;
525 const SiS_LVDSDesStruct *SiS_PanelType07_2;
526 const SiS_LVDSDesStruct *SiS_PanelType08_2;
527 const SiS_LVDSDesStruct *SiS_PanelType09_2;
528 const SiS_LVDSDesStruct *SiS_PanelType0a_2;
529 const SiS_LVDSDesStruct *SiS_PanelType0b_2;
530 const SiS_LVDSDesStruct *SiS_PanelType0c_2;
531 const SiS_LVDSDesStruct *SiS_PanelType0d_2;
532 const SiS_LVDSDesStruct *SiS_PanelType0e_2;
533 const SiS_LVDSDesStruct *SiS_PanelType0f_2;
534 const SiS_LVDSDesStruct *SiS_PanelTypeNS_2;
535 const SiS_LVDSDesStruct *SiS_CHTVUNTSCDesData;
536 const SiS_LVDSDesStruct *SiS_CHTVONTSCDesData;
537 const SiS_LVDSDesStruct *SiS_CHTVUPALDesData;
538 const SiS_LVDSDesStruct *SiS_CHTVOPALDesData;
539
540 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1800x600_1;
541 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11024x768_1;
542 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11280x1024_1;
543 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11400x1050_1;
544 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11280x768_1;
545 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11024x600_1;
546 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11152x768_1;
547 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11600x1200_1;
548 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1800x600_1_H;
549 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11024x768_1_H;
550 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11280x1024_1_H;
551 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11400x1050_1_H;
552 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11280x768_1_H;
553 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11024x600_1_H;
554 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11152x768_1_H;
555 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11600x1200_1_H;
556 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1800x600_2;
557 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11024x768_2;
558 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11280x1024_2;
559 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11400x1050_2;
560 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11280x768_2;
561 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11024x600_2;
562 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11152x768_2;
563 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11600x1200_2;
564 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1800x600_2_H;
565 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11024x768_2_H;
566 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11280x1024_2_H;
567 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11400x1050_2_H;
568 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11280x768_2_H;
569 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11024x600_2_H;
570 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11152x768_2_H;
571 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11600x1200_2_H;
572 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1XXXxXXX_1;
573 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1XXXxXXX_1_H;
574 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1640x480_1;
575 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1640x480_1_H;
576 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1640x480_2;
577 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1640x480_2_H;
578 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1640x480_3;
579 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1640x480_3_H;
580 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1320x480_1;
581 const SiS_LVDSCRT1DataStruct *SiS_CHTVCRT1UNTSC;
582 const SiS_LVDSCRT1DataStruct *SiS_CHTVCRT1ONTSC;
583 const SiS_LVDSCRT1DataStruct *SiS_CHTVCRT1UPAL;
584 const SiS_LVDSCRT1DataStruct *SiS_CHTVCRT1OPAL;
585 const SiS_LVDSCRT1DataStruct *SiS_CHTVCRT1SOPAL;
586
587 const SiS_CHTVRegDataStruct *SiS_CHTVReg_UNTSC;
588 const SiS_CHTVRegDataStruct *SiS_CHTVReg_ONTSC;
589 const SiS_CHTVRegDataStruct *SiS_CHTVReg_UPAL;
590 const SiS_CHTVRegDataStruct *SiS_CHTVReg_OPAL;
591 const SiS_CHTVRegDataStruct *SiS_CHTVReg_UPALM;
592 const SiS_CHTVRegDataStruct *SiS_CHTVReg_OPALM;
593 const SiS_CHTVRegDataStruct *SiS_CHTVReg_UPALN;
594 const SiS_CHTVRegDataStruct *SiS_CHTVReg_OPALN;
595 const SiS_CHTVRegDataStruct *SiS_CHTVReg_SOPAL;
596
597 const UCHAR *SiS_CHTVVCLKUNTSC;
598 const UCHAR *SiS_CHTVVCLKONTSC;
599 const UCHAR *SiS_CHTVVCLKUPAL;
600 const UCHAR *SiS_CHTVVCLKOPAL;
601 const UCHAR *SiS_CHTVVCLKUPALM;
602 const UCHAR *SiS_CHTVVCLKOPALM;
603 const UCHAR *SiS_CHTVVCLKUPALN;
604 const UCHAR *SiS_CHTVVCLKOPALN;
605 const UCHAR *SiS_CHTVVCLKSOPAL;
606
607 USHORT PanelXRes, PanelHT;
608 USHORT PanelYRes, PanelVT;
609 USHORT PanelHRS, PanelHRE;
610 USHORT PanelVRS, PanelVRE;
611 USHORT PanelVCLKIdx300;
612 USHORT PanelVCLKIdx315;
613
614 BOOLEAN UseCustomMode;
615 BOOLEAN CRT1UsesCustomMode;
616 USHORT CHDisplay;
617 USHORT CHSyncStart;
618 USHORT CHSyncEnd;
619 USHORT CHTotal;
620 USHORT CHBlankStart;
621 USHORT CHBlankEnd;
622 USHORT CVDisplay;
623 USHORT CVSyncStart;
624 USHORT CVSyncEnd;
625 USHORT CVTotal;
626 USHORT CVBlankStart;
627 USHORT CVBlankEnd;
628 ULONG CDClock;
629 ULONG CFlags;
630 UCHAR CCRT1CRTC[17];
631 UCHAR CSR2B;
632 UCHAR CSR2C;
633 USHORT CSRClock;
634 USHORT CSRClock_CRT1;
635 USHORT CModeFlag;
636 USHORT CModeFlag_CRT1;
637 USHORT CInfoFlag;
638
639 int LVDSHL;
640
641 BOOLEAN Backup;
642 UCHAR Backup_Mode;
643 UCHAR Backup_14;
644 UCHAR Backup_15;
645 UCHAR Backup_16;
646 UCHAR Backup_17;
647 UCHAR Backup_18;
648 UCHAR Backup_19;
649 UCHAR Backup_1a;
650 UCHAR Backup_1b;
651 UCHAR Backup_1c;
652 UCHAR Backup_1d;
653
654 int UsePanelScaler;
655 int CenterScreen;
656
657 USHORT CP_Vendor, CP_Product;
658 BOOLEAN CP_HaveCustomData;
659 int CP_PreferredX, CP_PreferredY, CP_PreferredIndex;
660 int CP_MaxX, CP_MaxY, CP_MaxClock;
661 UCHAR CP_PrefSR2B, CP_PrefSR2C;
662 USHORT CP_PrefClock;
663 BOOLEAN CP_Supports64048075;
664 int CP_HDisplay[7], CP_VDisplay[7]; /* For Custom LCD panel dimensions */
665 int CP_HTotal[7], CP_VTotal[7];
666 int CP_HSyncStart[7], CP_VSyncStart[7];
667 int CP_HSyncEnd[7], CP_VSyncEnd[7];
668 int CP_HBlankStart[7], CP_VBlankStart[7];
669 int CP_HBlankEnd[7], CP_VBlankEnd[7];
670 int CP_Clock[7];
671 BOOLEAN CP_DataValid[7];
672 BOOLEAN CP_HSync_P[7], CP_VSync_P[7], CP_SyncValid[7];
673} SiS_Private;
674
675#endif
676