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)
9 * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
11 * If distributed as part of the Linux kernel, the following license terms
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.
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.
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
28 * Otherwise, the following license terms apply:
30 * * Redistribution and use in source and binary forms, with or without
31 * * modification, are permitted provided that the following conditions
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.
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.
52 * Author: Thomas Winischhofer <thomas@winischhofer.net>
54 * Formerly based on non-functional code-fragements for 300 series by SiS, Inc.
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.
77 #if defined(ALLOC_PRAGMA)
78 #pragma alloc_text(PAGE,SiSSetMode)
81 /*********************************************/
82 /* POINTER INITIALIZATION */
83 /*********************************************/
85 #if defined(SIS300) || defined(SIS315H)
87 InitCommonPointer(SiS_Private
*SiS_Pr
, PSIS_HW_INFO HwInfo
)
89 SiS_Pr
->SiS_StResInfo
= SiS_StResInfo
;
90 SiS_Pr
->SiS_ModeResInfo
= SiS_ModeResInfo
;
91 SiS_Pr
->SiS_StandTable
= SiS_StandTable
;
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
;
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
;
110 SiS_Pr
->SiS_HiTVExtTiming
= SiS_HiTVExtTiming
;
111 SiS_Pr
->SiS_HiTVGroup3Data
= SiS_HiTVGroup3Data
;
112 SiS_Pr
->SiS_HiTVGroup3Simu
= SiS_HiTVGroup3Simu
;
114 SiS_Pr
->SiS_HiTVTextTiming
= SiS_HiTVTextTiming
;
115 SiS_Pr
->SiS_HiTVGroup3Text
= SiS_HiTVGroup3Text
;
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
;
132 SiS_Pr
->pSiS_OutputSelect
= &SiS_OutputSelect
;
133 SiS_Pr
->pSiS_SoftSetting
= &SiS_SoftSetting
;
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
;
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
;
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
;
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
;
201 SiS_Pr
->SiS_CHTVUNTSCData
= SiS_CHTVUNTSCData
;
202 SiS_Pr
->SiS_CHTVONTSCData
= SiS_CHTVONTSCData
;
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
;
209 SiS_Pr
->SiS_PanelMinLVDS
= Panel_800x600
; /* lowest value LVDS/LCDA */
210 SiS_Pr
->SiS_PanelMin301
= Panel_1024x768
; /* lowest value 301 */
216 InitTo300Pointer(SiS_Private
*SiS_Pr
, PSIS_HW_INFO HwInfo
)
218 InitCommonPointer(SiS_Pr
, HwInfo
);
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 */
228 SiS_Pr
->SiS_MCLKData_0
= SiS300_MCLKData_630
; /* 630, 730 */
230 SiS_Pr
->SiS_VCLKData
= SiS300_VCLKData
;
231 SiS_Pr
->SiS_VBVCLKData
= (SiS_VBVCLKDataStruct
*)SiS300_VCLKData
;
233 SiS_Pr
->SiS_SR15
= SiS300_SR15
;
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
;
260 SiS_Pr
->SiS_PanelDelayTbl
= SiS300_PanelDelayTbl
;
261 SiS_Pr
->SiS_PanelDelayTblLVDS
= SiS300_PanelDelayTbl
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
370 InitTo310Pointer(SiS_Private
*SiS_Pr
, PSIS_HW_INFO HwInfo
)
372 InitCommonPointer(SiS_Pr
, HwInfo
);
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 */
391 SiS_Pr
->SiS_MCLKData_0
= SiS310_MCLKData_0_315
; /* 315 */
393 if(HwInfo
->jChipType
>= SIS_340
) {
394 SiS_Pr
->SiS_MCLKData_1
= SiS310_MCLKData_1_340
;
396 SiS_Pr
->SiS_MCLKData_1
= SiS310_MCLKData_1
;
398 SiS_Pr
->SiS_VCLKData
= SiS310_VCLKData
;
399 SiS_Pr
->SiS_VBVCLKData
= SiS310_VBVCLKData
;
401 SiS_Pr
->SiS_SR15
= SiS310_SR15
;
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
;
428 SiS_Pr
->SiS_PanelDelayTbl
= SiS310_PanelDelayTbl
;
429 SiS_Pr
->SiS_PanelDelayTblLVDS
= SiS310_PanelDelayTblLVDS
;
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
;
436 SiS_Pr
->SiS_CRT2Part2_1024x768_1
= SiS310_CRT2Part2_1024x768_1
;
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
;
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
;
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
;
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
;
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
;
532 SiSInitPtr(SiS_Private
*SiS_Pr
, PSIS_HW_INFO HwInfo
)
534 switch(HwInfo
->jChipType
) {
549 InitTo310Pointer(SiS_Pr
, HwInfo
);
557 InitTo300Pointer(SiS_Pr
, HwInfo
);
565 /*********************************************/
566 /* HELPER: Get ModeID */
567 /*********************************************/
571 SiS_GetModeID(int VGAEngine
, ULONG VBFlags
, int HDisplay
, int VDisplay
,
572 int Depth
, BOOLEAN FSTN
, int LCDwidth
, int LCDheight
)
574 USHORT ModeIndex
= 0;
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
];
586 if((!(VBFlags
& CRT1_LCDA
)) || ((LCDwidth
>= 800) && (LCDwidth
>= 600))) {
587 if(VDisplay
== 300) ModeIndex
= ModeIndex_400x300
[Depth
];
591 if((!(VBFlags
& CRT1_LCDA
)) || ((LCDwidth
>= 1024) && (LCDwidth
>= 768))) {
592 if(VDisplay
== 384) ModeIndex
= ModeIndex_512x384
[Depth
];
596 if(VDisplay
== 480) ModeIndex
= ModeIndex_640x480
[Depth
];
597 else if(VDisplay
== 400) ModeIndex
= ModeIndex_640x400
[Depth
];
600 if(VDisplay
== 480) ModeIndex
= ModeIndex_720x480
[Depth
];
601 else if(VDisplay
== 576) ModeIndex
= ModeIndex_720x576
[Depth
];
604 if(VDisplay
== 576) ModeIndex
= ModeIndex_768x576
[Depth
];
607 if(VDisplay
== 600) ModeIndex
= ModeIndex_800x600
[Depth
];
608 else if(VDisplay
== 480) ModeIndex
= ModeIndex_800x480
[Depth
];
611 if(VDisplay
== 480) ModeIndex
= ModeIndex_848x480
[Depth
];
614 if(VDisplay
== 480) ModeIndex
= ModeIndex_856x480
[Depth
];
617 if(VGAEngine
== SIS_315_VGA
) {
618 if(VDisplay
== 540) ModeIndex
= ModeIndex_960x540
[Depth
];
619 else if(VDisplay
== 600) ModeIndex
= ModeIndex_960x600
[Depth
];
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
];
630 if(VDisplay
== 864) ModeIndex
= ModeIndex_1152x864
[Depth
];
631 if(VGAEngine
== SIS_300_VGA
) {
632 if(VDisplay
== 768) ModeIndex
= ModeIndex_1152x768
[Depth
];
638 ModeIndex
= ModeIndex_1280x720
[Depth
];
641 if(VGAEngine
== SIS_300_VGA
) {
642 ModeIndex
= ModeIndex_300_1280x768
[Depth
];
644 ModeIndex
= ModeIndex_310_1280x768
[Depth
];
648 if(VGAEngine
== SIS_315_VGA
) {
649 ModeIndex
= ModeIndex_1280x800
[Depth
];
653 ModeIndex
= ModeIndex_1280x960
[Depth
];
656 ModeIndex
= ModeIndex_1280x1024
[Depth
];
661 if(VDisplay
== 768) ModeIndex
= ModeIndex_1360x768
[Depth
];
662 if(VGAEngine
== SIS_300_VGA
) {
663 if(VDisplay
== 1024) ModeIndex
= ModeIndex_300_1360x1024
[Depth
];
667 if(VGAEngine
== SIS_315_VGA
) {
668 if(VDisplay
== 1050) {
669 ModeIndex
= ModeIndex_1400x1050
[Depth
];
674 if(VDisplay
== 1200) ModeIndex
= ModeIndex_1600x1200
[Depth
];
677 if(VGAEngine
== SIS_315_VGA
) {
678 if(VDisplay
== 1050) ModeIndex
= ModeIndex_1680x1050
[Depth
];
682 if(VDisplay
== 1440) ModeIndex
= ModeIndex_1920x1440
[Depth
];
683 else if(VGAEngine
== SIS_315_VGA
) {
684 if(VDisplay
== 1080) ModeIndex
= ModeIndex_1920x1080
[Depth
];
688 if(VDisplay
== 1536) {
689 if(VGAEngine
== SIS_300_VGA
) {
690 ModeIndex
= ModeIndex_300_2048x1536
[Depth
];
692 ModeIndex
= ModeIndex_310_2048x1536
[Depth
];
703 SiS_GetModeID_LCD(int VGAEngine
, ULONG VBFlags
, int HDisplay
, int VDisplay
,
704 int Depth
, BOOLEAN FSTN
, USHORT CustomT
, int LCDwidth
, int LCDheight
)
706 USHORT ModeIndex
= 0;
708 if(VBFlags
& (VB_LVDS
| VB_30xBDH
)) {
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
];
724 if(CustomT
!= CUT_PANEL848
) {
725 if(!((VGAEngine
== SIS_300_VGA
) && (VBFlags
& VB_TRUMPION
))) {
726 if(VDisplay
== 300) ModeIndex
= ModeIndex_400x300
[Depth
];
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
];
742 if(VDisplay
== 480) ModeIndex
= ModeIndex_640x480
[Depth
];
743 else if(VDisplay
== 400) {
744 if(CustomT
!= CUT_PANEL848
) ModeIndex
= ModeIndex_640x400
[Depth
];
748 if(VDisplay
== 600) ModeIndex
= ModeIndex_800x600
[Depth
];
751 if(CustomT
== CUT_PANEL848
) {
752 if(VDisplay
== 480) ModeIndex
= ModeIndex_848x480
[Depth
];
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
];
764 if(VGAEngine
== SIS_300_VGA
) {
765 if((VDisplay
== 768) && (LCDheight
== 768)) {
766 ModeIndex
= ModeIndex_1152x768
[Depth
];
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
];
779 if(VGAEngine
== SIS_300_VGA
) {
780 if(CustomT
== CUT_BARCO1366
) {
781 if(VDisplay
== 1024) ModeIndex
= ModeIndex_300_1360x1024
[Depth
];
784 if(CustomT
== CUT_PANEL848
) {
785 if(VDisplay
== 768) ModeIndex
= ModeIndex_1360x768
[Depth
];
789 if(VGAEngine
== SIS_315_VGA
) {
790 if(VDisplay
== 1050) ModeIndex
= ModeIndex_1400x1050
[Depth
];
794 if(VGAEngine
== SIS_315_VGA
) {
795 if(VDisplay
== 1200) ModeIndex
= ModeIndex_1600x1200
[Depth
];
800 } else if(VBFlags
& VB_SISBRIDGE
) {
805 if(VDisplay
== 200) ModeIndex
= ModeIndex_320x200
[Depth
];
806 else if(VDisplay
== 240) ModeIndex
= ModeIndex_320x240
[Depth
];
809 if(LCDwidth
>= 800 && LCDheight
>= 600) {
810 if(VDisplay
== 300) ModeIndex
= ModeIndex_400x300
[Depth
];
814 if(LCDwidth
>= 1024 && LCDheight
>= 768 && LCDwidth
!= 1152) {
815 if(VDisplay
== 384) ModeIndex
= ModeIndex_512x384
[Depth
];
819 if(VDisplay
== 480) ModeIndex
= ModeIndex_640x480
[Depth
];
820 else if(VDisplay
== 400) ModeIndex
= ModeIndex_640x400
[Depth
];
823 if(VGAEngine
== SIS_315_VGA
) {
824 if(VDisplay
== 480) ModeIndex
= ModeIndex_720x480
[Depth
];
825 else if(VDisplay
== 576) ModeIndex
= ModeIndex_720x576
[Depth
];
829 if(VGAEngine
== SIS_315_VGA
) {
830 if(VDisplay
== 576) ModeIndex
= ModeIndex_768x576
[Depth
];
834 if(VDisplay
== 600) ModeIndex
= ModeIndex_800x600
[Depth
];
835 if(VGAEngine
== SIS_315_VGA
) {
836 if(VDisplay
== 480) ModeIndex
= ModeIndex_800x480
[Depth
];
840 if(VGAEngine
== SIS_315_VGA
) {
841 if(VDisplay
== 480) ModeIndex
= ModeIndex_848x480
[Depth
];
845 if(VGAEngine
== SIS_315_VGA
) {
846 if(VDisplay
== 480) ModeIndex
= ModeIndex_856x480
[Depth
];
850 if(VGAEngine
== SIS_315_VGA
) {
851 if(VDisplay
== 540) ModeIndex
= ModeIndex_960x540
[Depth
];
852 else if(VDisplay
== 600) ModeIndex
= ModeIndex_960x600
[Depth
];
856 if(VDisplay
== 768) ModeIndex
= ModeIndex_1024x768
[Depth
];
857 if(VGAEngine
== SIS_315_VGA
) {
858 if(VDisplay
== 576) ModeIndex
= ModeIndex_1024x576
[Depth
];
862 if(VGAEngine
== SIS_315_VGA
) {
863 if(VDisplay
== 864) ModeIndex
= ModeIndex_1152x864
[Depth
];
869 ModeIndex
= ModeIndex_1280x720
[Depth
];
871 if(VGAEngine
== SIS_300_VGA
) {
872 ModeIndex
= ModeIndex_300_1280x768
[Depth
];
874 ModeIndex
= ModeIndex_310_1280x768
[Depth
];
878 if(VGAEngine
== SIS_315_VGA
) {
879 ModeIndex
= ModeIndex_1280x800
[Depth
];
883 ModeIndex
= ModeIndex_1280x960
[Depth
];
886 ModeIndex
= ModeIndex_1280x1024
[Depth
];
891 if(VGAEngine
== SIS_315_VGA
) {
892 if(VDisplay
== 768) ModeIndex
= ModeIndex_1360x768
[Depth
];
896 if(VGAEngine
== SIS_315_VGA
) {
897 if(VBFlags
& (VB_301C
| VB_302LV
| VB_302ELV
)) {
898 if(VDisplay
== 1050) ModeIndex
= ModeIndex_1400x1050
[Depth
];
903 if(VGAEngine
== SIS_315_VGA
) {
904 if(VBFlags
& (VB_301C
| VB_302LV
| VB_302ELV
)) {
905 if(VDisplay
== 1200) ModeIndex
= ModeIndex_1600x1200
[Depth
];
909 #ifndef VB_FORBID_CRT2LCD_OVER_1600
911 if(VGAEngine
== SIS_315_VGA
) {
912 if(VBFlags
& (VB_301C
| VB_302LV
| VB_302ELV
)) {
913 if(VDisplay
== 1050) ModeIndex
= ModeIndex_1680x1050
[Depth
];
925 SiS_GetModeID_TV(int VGAEngine
, ULONG VBFlags
, int HDisplay
, int VDisplay
, int Depth
)
927 USHORT ModeIndex
= 0;
929 if(VBFlags
& VB_CHRONTEL
) {
934 if(VGAEngine
== SIS_315_VGA
) {
935 if(VDisplay
== 384) ModeIndex
= ModeIndex_512x384
[Depth
];
939 if(VDisplay
== 480) ModeIndex
= ModeIndex_640x480
[Depth
];
940 else if(VDisplay
== 400) ModeIndex
= ModeIndex_640x400
[Depth
];
943 if(VDisplay
== 600) ModeIndex
= ModeIndex_800x600
[Depth
];
946 if(VGAEngine
== SIS_315_VGA
) {
947 if(VDisplay
== 768) ModeIndex
= ModeIndex_1024x768
[Depth
];
952 } else if(VBFlags
& VB_SISTVBRIDGE
) {
957 if(VDisplay
== 200) ModeIndex
= ModeIndex_320x200
[Depth
];
958 else if(VDisplay
== 240) ModeIndex
= ModeIndex_320x240
[Depth
];
961 if(VDisplay
== 300) ModeIndex
= ModeIndex_400x300
[Depth
];
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
];
971 if(VDisplay
== 480) ModeIndex
= ModeIndex_640x480
[Depth
];
972 else if(VDisplay
== 400) ModeIndex
= ModeIndex_640x400
[Depth
];
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
];
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
];
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
];
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
];
1011 if(VDisplay
== 768) {
1012 if(VBFlags
& (VB_301B
|VB_301C
|VB_302B
|VB_301LV
|VB_302LV
|VB_302ELV
)) {
1013 ModeIndex
= ModeIndex_1024x768
[Depth
];
1015 } else if(VDisplay
== 576) {
1016 if((VBFlags
& TV_HIVISION
) || ((VBFlags
& TV_YPBPR
) && (VBFlags
& TV_YPBPR1080I
))) {
1017 ModeIndex
= ModeIndex_1024x576
[Depth
];
1022 if(VDisplay
== 720) {
1023 if((VBFlags
& TV_HIVISION
) ||
1024 ((VBFlags
& TV_YPBPR
) && (VBFlags
& (TV_YPBPR1080I
| TV_YPBPR750P
)))) {
1025 ModeIndex
= ModeIndex_1280x720
[Depth
];
1027 } else if(VDisplay
== 1024) {
1028 if((VBFlags
& TV_HIVISION
) ||
1029 ((VBFlags
& TV_YPBPR
) && (VBFlags
& TV_YPBPR1080I
))) {
1030 ModeIndex
= ModeIndex_1280x1024
[Depth
];
1040 SiS_GetModeID_VGA2(int VGAEngine
, ULONG VBFlags
, int HDisplay
, int VDisplay
, int Depth
)
1042 USHORT ModeIndex
= 0;
1044 if(!(VBFlags
& (VB_301
|VB_301B
|VB_301C
|VB_302B
))) return 0;
1049 if(VDisplay
== 200) ModeIndex
= ModeIndex_320x200
[Depth
];
1050 else if(VDisplay
== 240) ModeIndex
= ModeIndex_320x240
[Depth
];
1053 if(VDisplay
== 300) ModeIndex
= ModeIndex_400x300
[Depth
];
1056 if(VDisplay
== 384) ModeIndex
= ModeIndex_512x384
[Depth
];
1059 if(VDisplay
== 480) ModeIndex
= ModeIndex_640x480
[Depth
];
1060 else if(VDisplay
== 400) ModeIndex
= ModeIndex_640x400
[Depth
];
1063 if(VDisplay
== 480) ModeIndex
= ModeIndex_720x480
[Depth
];
1064 else if(VDisplay
== 576) ModeIndex
= ModeIndex_720x576
[Depth
];
1067 if(VDisplay
== 576) ModeIndex
= ModeIndex_768x576
[Depth
];
1070 if(VDisplay
== 600) ModeIndex
= ModeIndex_800x600
[Depth
];
1071 else if(VDisplay
== 480) ModeIndex
= ModeIndex_800x480
[Depth
];
1074 if(VDisplay
== 480) ModeIndex
= ModeIndex_848x480
[Depth
];
1077 if(VDisplay
== 480) ModeIndex
= ModeIndex_856x480
[Depth
];
1080 if(VGAEngine
== SIS_315_VGA
) {
1081 if(VDisplay
== 540) ModeIndex
= ModeIndex_960x540
[Depth
];
1082 else if(VDisplay
== 600) ModeIndex
= ModeIndex_960x600
[Depth
];
1086 if(VDisplay
== 768) ModeIndex
= ModeIndex_1024x768
[Depth
];
1087 else if(VDisplay
== 576) ModeIndex
= ModeIndex_1024x576
[Depth
];
1090 if(VDisplay
== 864) ModeIndex
= ModeIndex_1152x864
[Depth
];
1091 else if(VGAEngine
== SIS_300_VGA
) {
1092 if(VDisplay
== 768) ModeIndex
= ModeIndex_1152x768
[Depth
];
1096 if(VDisplay
== 768) {
1097 if(VGAEngine
== SIS_300_VGA
) {
1098 ModeIndex
= ModeIndex_300_1280x768
[Depth
];
1100 ModeIndex
= ModeIndex_310_1280x768
[Depth
];
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
];
1108 if(VDisplay
== 768) ModeIndex
= ModeIndex_1360x768
[Depth
];
1111 if(VGAEngine
== SIS_315_VGA
) {
1112 if(VDisplay
== 1050) ModeIndex
= ModeIndex_1400x1050
[Depth
];
1116 if(VGAEngine
== SIS_315_VGA
) {
1117 if(VBFlags
& (VB_301B
|VB_301C
|VB_302B
)) {
1118 if(VDisplay
== 1200) ModeIndex
= ModeIndex_1600x1200
[Depth
];
1123 if(VGAEngine
== SIS_315_VGA
) {
1124 if(VBFlags
& (VB_301B
|VB_301C
|VB_302B
)) {
1125 if(VDisplay
== 1050) ModeIndex
= ModeIndex_1680x1050
[Depth
];
1135 /*********************************************/
1136 /* HELPER: SetReg, GetReg */
1137 /*********************************************/
1140 SiS_SetReg(SISIOADDRESS port
, USHORT index
, USHORT data
)
1142 OutPortByte(port
,index
);
1143 OutPortByte(port
+ 1,data
);
1147 SiS_SetRegByte(SISIOADDRESS port
, USHORT data
)
1149 OutPortByte(port
,data
);
1153 SiS_SetRegShort(SISIOADDRESS port
, USHORT data
)
1155 OutPortWord(port
,data
);
1159 SiS_SetRegLong(SISIOADDRESS port
, ULONG data
)
1161 OutPortLong(port
,data
);
1165 SiS_GetReg(SISIOADDRESS port
, USHORT index
)
1167 OutPortByte(port
,index
);
1168 return(InPortByte(port
+ 1));
1172 SiS_GetRegByte(SISIOADDRESS port
)
1174 return(InPortByte(port
));
1178 SiS_GetRegShort(SISIOADDRESS port
)
1180 return(InPortWord(port
));
1184 SiS_GetRegLong(SISIOADDRESS port
)
1186 return(InPortLong(port
));
1190 SiS_SetRegANDOR(SISIOADDRESS Port
,USHORT Index
,USHORT DataAND
,USHORT DataOR
)
1194 temp
= SiS_GetReg(Port
,Index
);
1195 temp
= (temp
& (DataAND
)) | DataOR
;
1196 SiS_SetReg(Port
,Index
,temp
);
1200 SiS_SetRegAND(SISIOADDRESS Port
,USHORT Index
,USHORT DataAND
)
1204 temp
= SiS_GetReg(Port
,Index
);
1206 SiS_SetReg(Port
,Index
,temp
);
1210 SiS_SetRegOR(SISIOADDRESS Port
,USHORT Index
,USHORT DataOR
)
1214 temp
= SiS_GetReg(Port
,Index
);
1216 SiS_SetReg(Port
,Index
,temp
);
1219 /*********************************************/
1220 /* HELPER: DisplayOn, DisplayOff */
1221 /*********************************************/
1224 SiS_DisplayOn(SiS_Private
*SiS_Pr
)
1226 SiS_SetRegAND(SiS_Pr
->SiS_P3c4
,0x01,0xDF);
1230 SiS_DisplayOff(SiS_Private
*SiS_Pr
)
1232 SiS_SetRegOR(SiS_Pr
->SiS_P3c4
,0x01,0x20);
1236 /*********************************************/
1237 /* HELPER: Init Port Addresses */
1238 /*********************************************/
1241 SiSRegInit(SiS_Private
*SiS_Pr
, SISIOADDRESS BaseAddr
)
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
;
1266 /*********************************************/
1267 /* HELPER: GetSysFlags */
1268 /*********************************************/
1271 SiS_GetSysFlags(SiS_Private
*SiS_Pr
, PSIS_HW_INFO HwInfo
)
1273 unsigned char cr5f
, temp1
, temp2
;
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
;
1286 /* You should use the macros, not these flags directly */
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
)) {
1300 SiS_Pr
->SiS_SysFlags
|= SF_IsM650
; break;
1304 SiS_Pr
->SiS_SysFlags
|= SF_Is651
; break;
1309 temp1
= SiS_GetReg(SiS_Pr
->SiS_P3d4
,0x5c) & 0xf8;
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;
1317 SiS_Pr
->SiS_SysFlags
|= SF_Is652
; break;
1319 SiS_Pr
->SiS_SysFlags
|= SF_IsM650
; break;
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
;
1329 /*********************************************/
1330 /* HELPER: Init PCI & Engines */
1331 /*********************************************/
1334 SiSInitPCIetc(SiS_Private
*SiS_Pr
, PSIS_HW_INFO HwInfo
)
1336 switch(HwInfo
->jChipType
) {
1341 /* Set - PCI LINEAR ADDRESSING ENABLE (0x80)
1342 * - RELOCATED VGA IO (0x20)
1343 * - MMIO ENABLE (0x1)
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) ?
1351 SiS_SetRegOR(SiS_Pr
->SiS_P3c4
,0x1E,0x5A);
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)
1372 SiS_SetRegOR(SiS_Pr
->SiS_P3c4
,0x1E,0xDA);
1375 SiS_SetReg(SiS_Pr
->SiS_P3c4
,0x20,0xa1);
1376 /* No 3D engine ! */
1377 /* - Enable 2D (0x40)
1379 SiS_SetRegOR(SiS_Pr
->SiS_P3c4
,0x1E,0x40);
1383 /*********************************************/
1384 /* HELPER: SetLVDSetc */
1385 /*********************************************/
1388 SiSSetLVDSetc(SiS_Private
*SiS_Pr
, PSIS_HW_INFO HwInfo
)
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;
1399 SiS_Pr
->SiS_ChrontelInit
= 0;
1401 /* Check for SiS30x first */
1402 temp
= SiS_GetReg(SiS_Pr
->SiS_Part4Port
,0x00);
1403 if((temp
== 1) || (temp
== 2)) return;
1405 switch(HwInfo
->jChipType
) {
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;
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;
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 */
1449 /*********************************************/
1450 /* HELPER: Enable DSTN/FSTN */
1451 /*********************************************/
1454 SiS_SetEnableDstn(SiS_Private
*SiS_Pr
, int enable
)
1456 SiS_Pr
->SiS_IF_DEF_DSTN
= enable
? 1 : 0;
1460 SiS_SetEnableFstn(SiS_Private
*SiS_Pr
, int enable
)
1462 SiS_Pr
->SiS_IF_DEF_FSTN
= enable
? 1 : 0;
1465 /*********************************************/
1466 /* HELPER: Determine ROM usage */
1467 /*********************************************/
1470 SiSDetermineROMLayout661(SiS_Private
*SiS_Pr
, PSIS_HW_INFO HwInfo
)
1472 UCHAR
*ROMAddr
= HwInfo
->pjVirtualRomBase
;
1473 USHORT romversoffs
, romvmaj
= 1, romvmin
= 0;
1475 if(HwInfo
->jChipType
>= SIS_761
) {
1476 /* I very much assume 761 and 340 will use new layout */
1478 } else if(HwInfo
->jChipType
>= SIS_661
) {
1479 if((ROMAddr
[0x1a] == 'N') &&
1480 (ROMAddr
[0x1b] == 'e') &&
1481 (ROMAddr
[0x1c] == 'w') &&
1482 (ROMAddr
[0x1d] == 'V')) {
1485 romversoffs
= ROMAddr
[0x16] | (ROMAddr
[0x17] << 8);
1487 if((ROMAddr
[romversoffs
+1] == '.') || (ROMAddr
[romversoffs
+4] == '.')) {
1488 romvmaj
= ROMAddr
[romversoffs
] - '0';
1489 romvmin
= ((ROMAddr
[romversoffs
+2] -'0') * 10) + (ROMAddr
[romversoffs
+3] - '0');
1492 if((romvmaj
!= 0) || (romvmin
>= 92)) {
1495 } else if(IS_SIS650740
) {
1496 if((ROMAddr
[0x1a] == 'N') &&
1497 (ROMAddr
[0x1b] == 'e') &&
1498 (ROMAddr
[0x1c] == 'w') &&
1499 (ROMAddr
[0x1d] == 'V')) {
1507 SiSDetermineROMUsage(SiS_Private
*SiS_Pr
, PSIS_HW_INFO HwInfo
)
1509 UCHAR
*ROMAddr
= HwInfo
->pjVirtualRomBase
;
1512 SiS_Pr
->SiS_UseROM
= FALSE
;
1513 SiS_Pr
->SiS_ROMNew
= FALSE
;
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.
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
1527 SiS_Pr
->SiS_UseROM
= TRUE
;
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;
1553 /*********************************************/
1554 /* HELPER: SET SEGMENT REGISTERS */
1555 /*********************************************/
1558 SiS_SetSegRegLower(SiS_Private
*SiS_Pr
, USHORT value
)
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
);
1572 SiS_SetSegRegUpper(SiS_Private
*SiS_Pr
, USHORT value
)
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
);
1586 SiS_SetSegmentReg(SiS_Private
*SiS_Pr
, USHORT value
)
1588 SiS_SetSegRegLower(SiS_Pr
, value
);
1589 SiS_SetSegRegUpper(SiS_Pr
, value
);
1593 SiS_ResetSegmentReg(SiS_Private
*SiS_Pr
)
1595 SiS_SetSegmentReg(SiS_Pr
, 0);
1599 SiS_SetSegmentRegOver(SiS_Private
*SiS_Pr
, USHORT value
)
1601 USHORT temp
= value
>> 8;
1604 temp
|= (temp
<< 4);
1605 SiS_SetReg(SiS_Pr
->SiS_P3c4
,0x1d,temp
);
1606 SiS_SetSegmentReg(SiS_Pr
, value
);
1610 SiS_ResetSegmentRegOver(SiS_Private
*SiS_Pr
)
1612 SiS_SetSegmentRegOver(SiS_Pr
, 0);
1616 SiS_ResetSegmentRegisters(SiS_Private
*SiS_Pr
,PSIS_HW_INFO HwInfo
)
1618 if((IS_SIS65x
) || (HwInfo
->jChipType
>= SIS_661
)) {
1619 SiS_ResetSegmentReg(SiS_Pr
);
1620 SiS_ResetSegmentRegOver(SiS_Pr
);
1624 /*********************************************/
1625 /* HELPER: GetVBType */
1626 /*********************************************/
1629 SiS_GetVBType(SiS_Private
*SiS_Pr
, PSIS_HW_INFO HwInfo
)
1631 USHORT flag
=0, rev
=0, nolcd
=0, p4_0f
, p4_25
, p4_27
;
1633 SiS_Pr
->SiS_VBType
= 0;
1635 if((SiS_Pr
->SiS_IF_DEF_LVDS
) || (SiS_Pr
->SiS_IF_DEF_CONEX
))
1638 flag
= SiS_GetReg(SiS_Pr
->SiS_Part4Port
,0x00);
1640 if(flag
> 3) return;
1642 rev
= SiS_GetReg(SiS_Pr
->SiS_Part4Port
,0x01);
1645 SiS_Pr
->SiS_VBType
= VB_SIS302B
;
1646 } else if(flag
== 1) {
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
;
1655 SiS_Pr
->SiS_VBType
= VB_SIS301
;
1658 if(SiS_Pr
->SiS_VBType
& (VB_SIS301B
| VB_SIS301C
| VB_SIS302B
)) {
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
;
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
;
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
);
1683 /*********************************************/
1684 /* HELPER: Check RAM size */
1685 /*********************************************/
1689 SiS_CheckMemorySize(SiS_Private
*SiS_Pr
, PSIS_HW_INFO HwInfo
,
1690 USHORT ModeNo
, USHORT ModeIdIndex
)
1692 USHORT AdapterMemSize
= HwInfo
->ulVideoMemorySize
/ (1024*1024);
1693 USHORT memorysize
,modeflag
;
1695 if(SiS_Pr
->UseCustomMode
) {
1696 modeflag
= SiS_Pr
->CModeFlag
;
1698 if(ModeNo
<= 0x13) {
1699 modeflag
= SiS_Pr
->SiS_SModeIDTable
[ModeIdIndex
].St_ModeFlag
;
1701 modeflag
= SiS_Pr
->SiS_EModeIDTable
[ModeIdIndex
].Ext_ModeFlag
;
1705 memorysize
= modeflag
& MemoryInfoFlag
;
1706 memorysize
>>= MemorySizeShift
; /* Get required memory size */
1709 if(AdapterMemSize
< memorysize
) return FALSE
;
1714 /*********************************************/
1715 /* HELPER: Get DRAM type */
1716 /*********************************************/
1720 SiS_Get310DRAMType(SiS_Private
*SiS_Pr
, PSIS_HW_INFO HwInfo
)
1724 if((*SiS_Pr
->pSiS_SoftSetting
) & SoftDRAMType
) {
1725 data
= (*SiS_Pr
->pSiS_SoftSetting
) & 0x03;
1727 if(HwInfo
->jChipType
>= SIS_340
) {
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);
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
) {
1741 temp
= SiS_GetReg(SiS_Pr
->SiS_P3d4
,0x5f) & 0x30;
1743 case 0x00: data
= 1; break;
1744 case 0x10: data
= 3; break;
1745 case 0x20: data
= 3; break;
1746 case 0x30: data
= 2; break;
1759 SiS_GetMCLK(SiS_Private
*SiS_Pr
, PSIS_HW_INFO HwInfo
)
1761 UCHAR
*ROMAddr
= HwInfo
->pjVirtualRomBase
;
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))));
1769 return(SiS_Pr
->SiS_MCLKData_0
[index
].CLOCK
);
1770 } else if(index
>= 4) {
1772 return(SiS_Pr
->SiS_MCLKData_1
[index
].CLOCK
);
1774 return(SiS_Pr
->SiS_MCLKData_0
[index
].CLOCK
);
1779 /*********************************************/
1780 /* HELPER: ClearBuffer */
1781 /*********************************************/
1785 SiS_ClearBuffer(SiS_Private
*SiS_Pr
, PSIS_HW_INFO HwInfo
, USHORT ModeNo
)
1787 UCHAR SISIOMEMTYPE
*VideoMemoryAddress
= HwInfo
->pjVideoMemoryAddress
;
1788 ULONG AdapterMemorySize
= HwInfo
->ulVideoMemorySize
;
1789 USHORT SISIOMEMTYPE
*pBuffer
;
1792 if(SiS_Pr
->SiS_ModeType
>= ModeEGA
) {
1794 SiS_SetMemory(VideoMemoryAddress
, AdapterMemorySize
, 0);
1796 pBuffer
= (USHORT SISIOMEMTYPE
*)VideoMemoryAddress
;
1797 for(i
=0; i
<0x4000; i
++) writew(0x0000, &pBuffer
[i
]);
1800 if(SiS_Pr
->SiS_ModeType
< ModeCGA
) {
1801 pBuffer
= (USHORT SISIOMEMTYPE
*)VideoMemoryAddress
;
1802 for(i
=0; i
<0x4000; i
++) writew(0x0720, &pBuffer
[i
]);
1804 SiS_SetMemory(VideoMemoryAddress
, 0x8000, 0);
1810 /*********************************************/
1811 /* HELPER: SearchModeID */
1812 /*********************************************/
1815 SiS_SearchModeID(SiS_Private
*SiS_Pr
, USHORT
*ModeNo
, USHORT
*ModeIdIndex
)
1817 UCHAR VGAINFO
= SiS_Pr
->SiS_VGAINFO
;
1819 if(*ModeNo
<= 0x13) {
1821 if((*ModeNo
) <= 0x05) (*ModeNo
) |= 0x01;
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
;
1828 if(*ModeNo
== 0x07) {
1829 if(VGAINFO
& 0x10) (*ModeIdIndex
)++; /* 400 lines */
1830 /* else 350 lines */
1832 if(*ModeNo
<= 0x03) {
1833 if(!(VGAINFO
& 0x80)) (*ModeIdIndex
)++;
1834 if(VGAINFO
& 0x10) (*ModeIdIndex
)++; /* 400 lines */
1835 /* else 350 lines */
1837 /* else 200 lines */
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
;
1850 /*********************************************/
1851 /* HELPER: GetModePtr */
1852 /*********************************************/
1855 SiS_GetModePtr(SiS_Private
*SiS_Pr
, USHORT ModeNo
, USHORT ModeIdIndex
)
1859 if(ModeNo
<= 0x13) {
1860 index
= SiS_Pr
->SiS_SModeIDTable
[ModeIdIndex
].St_StTableIndex
;
1862 if(SiS_Pr
->SiS_ModeType
<= ModeEGA
) index
= 0x1B;
1868 /*********************************************/
1869 /* HELPER: LowModeTests */
1870 /*********************************************/
1873 SiS_DoLowModeTest(SiS_Private
*SiS_Pr
, USHORT ModeNo
, PSIS_HW_INFO HwInfo
)
1875 USHORT temp
,temp1
,temp2
;
1877 if((ModeNo
!= 0x03) && (ModeNo
!= 0x10) && (ModeNo
!= 0x12))
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
);
1891 if(temp2
!= 0x55) return(TRUE
);
1893 SiS_SetRegOR(SiS_Pr
->SiS_P3d4
,0x35,0x01);
1900 SiS_SetLowModeTest(SiS_Private
*SiS_Pr
, USHORT ModeNo
, PSIS_HW_INFO HwInfo
)
1902 if(SiS_DoLowModeTest(SiS_Pr
, ModeNo
, HwInfo
)) {
1903 SiS_Pr
->SiS_SetFlag
|= LowModeTests
;
1907 /*********************************************/
1908 /* HELPER: ENABLE CRT1 */
1909 /*********************************************/
1912 SiS_SetupCR5x(SiS_Private
*SiS_Pr
, PSIS_HW_INFO HwInfo
)
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);
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);
1931 SiS_HandleCRT1(SiS_Private
*SiS_Pr
)
1933 /* Enable CRT1 gating */
1934 SiS_SetRegAND(SiS_Pr
->SiS_P3d4
,SiS_Pr
->SiS_MyCR63
,0xbf);
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);
1945 /*********************************************/
1946 /* HELPER: GetColorDepth */
1947 /*********************************************/
1950 SiS_GetColorDepth(SiS_Private
*SiS_Pr
, USHORT ModeNo
, USHORT ModeIdIndex
)
1952 USHORT ColorDepth
[6] = { 1, 2, 4, 4, 6, 8};
1956 /* Do NOT check UseCustomMode, will skrew up FIFO */
1957 if(ModeNo
== 0xfe) {
1958 modeflag
= SiS_Pr
->CModeFlag
;
1961 modeflag
= SiS_Pr
->SiS_SModeIDTable
[ModeIdIndex
].St_ModeFlag
;
1963 modeflag
= SiS_Pr
->SiS_EModeIDTable
[ModeIdIndex
].Ext_ModeFlag
;
1966 index
= (modeflag
& ModeTypeMask
) - ModeEGA
;
1967 if(index
< 0) index
= 0;
1968 return(ColorDepth
[index
]);
1971 /*********************************************/
1972 /* HELPER: GetOffset */
1973 /*********************************************/
1976 SiS_GetOffset(SiS_Private
*SiS_Pr
,USHORT ModeNo
,USHORT ModeIdIndex
,
1977 USHORT RefreshRateTableIndex
,PSIS_HW_INFO HwInfo
)
1979 USHORT xres
, temp
, colordepth
, infoflag
;
1981 if(SiS_Pr
->UseCustomMode
) {
1982 infoflag
= SiS_Pr
->CInfoFlag
;
1983 xres
= SiS_Pr
->CHDisplay
;
1985 infoflag
= SiS_Pr
->SiS_RefIndex
[RefreshRateTableIndex
].Ext_InfoFlag
;
1986 xres
= SiS_Pr
->SiS_RefIndex
[RefreshRateTableIndex
].XRes
;
1989 colordepth
= SiS_GetColorDepth(SiS_Pr
,ModeNo
,ModeIdIndex
);
1992 if(infoflag
& InterlaceMode
) temp
<<= 1;
2002 /*********************************************/
2004 /*********************************************/
2007 SiS_SetSeqRegs(SiS_Private
*SiS_Pr
, USHORT StandTableIndex
, PSIS_HW_INFO HwInfo
)
2012 SiS_SetReg(SiS_Pr
->SiS_P3c4
,0x00,0x03); /* Set SR0 */
2014 SRdata
= SiS_Pr
->SiS_StandTable
[StandTableIndex
].SR
[0];
2016 if(SiS_Pr
->SiS_VBType
& VB_SIS301BLV302BLV
) {
2017 if(SiS_Pr
->SiS_VBInfo
& SetCRT2ToLCDA
) {
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 */
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 */
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 */
2043 if(SiS_Pr
->SiS_VBInfo
& SetCRT2ToLCD
) {
2044 if(SiS_Pr
->SiS_VBInfo
& SetInSlaveMode
) {
2045 SRdata
|= 0x01; /* 8 dot clock */
2050 SRdata
|= 0x20; /* screen off */
2052 SiS_SetReg(SiS_Pr
->SiS_P3c4
,0x01,SRdata
);
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
);
2060 /*********************************************/
2062 /*********************************************/
2065 SiS_SetMiscRegs(SiS_Private
*SiS_Pr
, USHORT StandTableIndex
, PSIS_HW_INFO HwInfo
)
2069 Miscdata
= SiS_Pr
->SiS_StandTable
[StandTableIndex
].MISC
;
2071 if(HwInfo
->jChipType
< SIS_661
) {
2072 if(SiS_Pr
->SiS_VBType
& VB_SIS301BLV302BLV
) {
2073 if(SiS_Pr
->SiS_VBInfo
& SetCRT2ToLCDA
) {
2079 SiS_SetRegByte(SiS_Pr
->SiS_P3c2
,Miscdata
);
2082 /*********************************************/
2084 /*********************************************/
2087 SiS_SetCRTCRegs(SiS_Private
*SiS_Pr
, PSIS_HW_INFO HwInfo
,
2088 USHORT StandTableIndex
)
2093 SiS_SetRegAND(SiS_Pr
->SiS_P3d4
,0x11,0x7f); /* Unlock CRTC */
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) */
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
);
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);
2116 /*********************************************/
2118 /*********************************************/
2121 SiS_SetATTRegs(SiS_Private
*SiS_Pr
, USHORT StandTableIndex
,
2122 PSIS_HW_INFO HwInfo
)
2127 for(i
= 0; i
<= 0x13; i
++) {
2128 ARdata
= SiS_Pr
->SiS_StandTable
[StandTableIndex
].ATTR
[i
];
2130 if((i
<= 0x0f) || (i
== 0x11)) {
2137 /* Pixel shift. If screen on LCD or TV is shifted left or right,
2138 * this might be the cause.
2140 if(SiS_Pr
->SiS_VBType
& VB_SIS301BLV302BLV
) {
2141 if(SiS_Pr
->SiS_VBInfo
& SetCRT2ToLCDA
) ARdata
=0;
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;
2150 if(HwInfo
->jChipType
>= SIS_661
) {
2151 if(SiS_Pr
->SiS_VBInfo
& (SetCRT2ToTV
| SetCRT2ToLCD
)) {
2152 if(SiS_Pr
->SiS_VBInfo
& SetInSlaveMode
) ARdata
=0;
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;
2165 if(SiS_Pr
->SiS_VBInfo
& SetInSlaveMode
) ARdata
=0;
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 */
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 */
2177 SiS_GetRegByte(SiS_Pr
->SiS_P3da
);
2178 SiS_SetRegByte(SiS_Pr
->SiS_P3c0
,0x20); /* Enable Attribute */
2179 SiS_GetRegByte(SiS_Pr
->SiS_P3da
);
2182 /*********************************************/
2184 /*********************************************/
2187 SiS_SetGRCRegs(SiS_Private
*SiS_Pr
, USHORT StandTableIndex
)
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
);
2197 if(SiS_Pr
->SiS_ModeType
> ModeVGA
) {
2198 /* 256 color disable */
2199 SiS_SetRegAND(SiS_Pr
->SiS_P3ce
,0x05,0xBF);
2203 /*********************************************/
2204 /* CLEAR EXTENDED REGISTERS */
2205 /*********************************************/
2208 SiS_ClearExt1Regs(SiS_Private
*SiS_Pr
, PSIS_HW_INFO HwInfo
, USHORT ModeNo
)
2212 for(i
= 0x0A; i
<= 0x0E; i
++) {
2213 SiS_SetReg(SiS_Pr
->SiS_P3c4
,i
,0x00);
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);
2226 /*********************************************/
2228 /*********************************************/
2231 SiS_ResetCRT1VCLK(SiS_Private
*SiS_Pr
, PSIS_HW_INFO HwInfo
)
2233 if(HwInfo
->jChipType
>= SIS_315H
) {
2234 if(HwInfo
->jChipType
< SIS_661
) {
2235 if(SiS_Pr
->SiS_IF_DEF_LVDS
== 0) return;
2238 if((SiS_Pr
->SiS_IF_DEF_LVDS
== 0) &&
2239 (!(SiS_Pr
->SiS_VBType
& VB_SIS301BLV302BLV
)) ) {
2244 if(HwInfo
->jChipType
>= SIS_315H
) {
2245 SiS_SetRegANDOR(SiS_Pr
->SiS_P3c4
,0x31,0xCF,0x20);
2247 SiS_SetReg(SiS_Pr
->SiS_P3c4
,0x31,0x20);
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);
2255 SiS_SetReg(SiS_Pr
->SiS_P3c4
,0x31,0x10);
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);
2262 /*********************************************/
2264 /*********************************************/
2267 SiS_SetCRT1Sync(SiS_Private
*SiS_Pr
, USHORT RefreshRateTableIndex
)
2271 if(SiS_Pr
->UseCustomMode
) {
2272 sync
= SiS_Pr
->CInfoFlag
>> 8;
2274 sync
= SiS_Pr
->SiS_RefIndex
[RefreshRateTableIndex
].Ext_InfoFlag
>> 8;
2279 SiS_SetRegByte(SiS_Pr
->SiS_P3c2
,sync
);
2282 /*********************************************/
2284 /*********************************************/
2287 SiS_SetCRT1CRTC(SiS_Private
*SiS_Pr
, USHORT ModeNo
, USHORT ModeIdIndex
,
2288 USHORT RefreshRateTableIndex
,
2289 PSIS_HW_INFO HwInfo
)
2292 USHORT temp
,i
,j
,modeflag
;
2294 SiS_SetRegAND(SiS_Pr
->SiS_P3d4
,0x11,0x7f); /* unlock cr0-7 */
2296 if(SiS_Pr
->UseCustomMode
) {
2298 modeflag
= SiS_Pr
->CModeFlag
;
2300 for(i
=0,j
=0;i
<=7;i
++,j
++) {
2301 SiS_SetReg(SiS_Pr
->SiS_P3d4
,j
,SiS_Pr
->CCRT1CRTC
[i
]);
2303 for(j
=0x10;i
<=10;i
++,j
++) {
2304 SiS_SetReg(SiS_Pr
->SiS_P3d4
,j
,SiS_Pr
->CCRT1CRTC
[i
]);
2306 for(j
=0x15;i
<=12;i
++,j
++) {
2307 SiS_SetReg(SiS_Pr
->SiS_P3d4
,j
,SiS_Pr
->CCRT1CRTC
[i
]);
2309 for(j
=0x0A;i
<=15;i
++,j
++) {
2310 SiS_SetReg(SiS_Pr
->SiS_P3c4
,j
,SiS_Pr
->CCRT1CRTC
[i
]);
2313 temp
= SiS_Pr
->CCRT1CRTC
[16] & 0xE0;
2314 SiS_SetReg(SiS_Pr
->SiS_P3c4
,0x0E,temp
);
2316 temp
= (SiS_Pr
->CCRT1CRTC
[16] & 0x01) << 5;
2317 if(modeflag
& DoubleScanMode
) temp
|= 0x80;
2318 SiS_SetRegANDOR(SiS_Pr
->SiS_P3d4
,0x09,0x5F,temp
);
2322 if(ModeNo
<= 0x13) {
2323 modeflag
= SiS_Pr
->SiS_SModeIDTable
[ModeIdIndex
].St_ModeFlag
;
2325 modeflag
= SiS_Pr
->SiS_EModeIDTable
[ModeIdIndex
].Ext_ModeFlag
;
2328 index
= SiS_Pr
->SiS_RefIndex
[RefreshRateTableIndex
].Ext_CRT1CRTC
;
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
]);
2333 for(j
=0x10;i
<=10;i
++,j
++) {
2334 SiS_SetReg(SiS_Pr
->SiS_P3d4
,j
,SiS_Pr
->SiS_CRT1Table
[index
].CR
[i
]);
2336 for(j
=0x15;i
<=12;i
++,j
++) {
2337 SiS_SetReg(SiS_Pr
->SiS_P3d4
,j
,SiS_Pr
->SiS_CRT1Table
[index
].CR
[i
]);
2339 for(j
=0x0A;i
<=15;i
++,j
++) {
2340 SiS_SetReg(SiS_Pr
->SiS_P3c4
,j
,SiS_Pr
->SiS_CRT1Table
[index
].CR
[i
]);
2343 temp
= SiS_Pr
->SiS_CRT1Table
[index
].CR
[16] & 0xE0;
2344 SiS_SetReg(SiS_Pr
->SiS_P3c4
,0x0E,temp
);
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
);
2352 if(SiS_Pr
->SiS_ModeType
> ModeVGA
) SiS_SetReg(SiS_Pr
->SiS_P3d4
,0x14,0x4F);
2355 /*********************************************/
2356 /* OFFSET & PITCH */
2357 /*********************************************/
2358 /* (partly overruled by SetPitch() in XF86) */
2359 /*********************************************/
2362 SiS_SetCRT1Offset(SiS_Private
*SiS_Pr
, USHORT ModeNo
, USHORT ModeIdIndex
,
2363 USHORT RefreshRateTableIndex
,
2364 PSIS_HW_INFO HwInfo
)
2366 USHORT temp
, DisplayUnit
, infoflag
;
2368 if(SiS_Pr
->UseCustomMode
) {
2369 infoflag
= SiS_Pr
->CInfoFlag
;
2371 infoflag
= SiS_Pr
->SiS_RefIndex
[RefreshRateTableIndex
].Ext_InfoFlag
;
2374 DisplayUnit
= SiS_GetOffset(SiS_Pr
,ModeNo
,ModeIdIndex
,
2375 RefreshRateTableIndex
,HwInfo
);
2377 temp
= (DisplayUnit
>> 8) & 0x0f;
2378 SiS_SetRegANDOR(SiS_Pr
->SiS_P3c4
,0x0E,0xF0,temp
);
2380 temp
= DisplayUnit
& 0xFF;
2381 SiS_SetReg(SiS_Pr
->SiS_P3d4
,0x13,temp
);
2383 if(infoflag
& InterlaceMode
) DisplayUnit
>>= 1;
2386 temp
= (DisplayUnit
& 0xff00) >> 8;
2387 if(DisplayUnit
& 0xff) temp
++;
2389 SiS_SetReg(SiS_Pr
->SiS_P3c4
,0x10,temp
);
2392 /*********************************************/
2394 /*********************************************/
2397 SiS_SetCRT1VCLK(SiS_Private
*SiS_Pr
, USHORT ModeNo
, USHORT ModeIdIndex
,
2398 PSIS_HW_INFO HwInfo
, USHORT RefreshRateTableIndex
)
2400 USHORT index
=0, clka
, clkb
;
2402 if(SiS_Pr
->UseCustomMode
) {
2403 clka
= SiS_Pr
->CSR2B
;
2404 clkb
= SiS_Pr
->CSR2C
;
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
;
2411 clka
= SiS_Pr
->SiS_VCLKData
[index
].SR2B
;
2412 clkb
= SiS_Pr
->SiS_VCLKData
[index
].SR2C
;
2416 if(HwInfo
->jChipType
>= SIS_315H
) {
2417 SiS_SetRegAND(SiS_Pr
->SiS_P3c4
,0x31,0xCF);
2419 SiS_SetReg(SiS_Pr
->SiS_P3c4
,0x31,0x00);
2422 SiS_SetReg(SiS_Pr
->SiS_P3c4
,0x2B,clka
);
2423 SiS_SetReg(SiS_Pr
->SiS_P3c4
,0x2C,clkb
);
2425 if(HwInfo
->jChipType
>= SIS_315H
) {
2426 SiS_SetReg(SiS_Pr
->SiS_P3c4
,0x2D,0x01);
2428 SiS_SetReg(SiS_Pr
->SiS_P3c4
,0x2D,0x80);
2432 /*********************************************/
2434 /*********************************************/
2438 SiS_DoCalcDelay(SiS_Private
*SiS_Pr
, USHORT MCLK
, USHORT VCLK
, USHORT colordepth
, USHORT key
)
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 };
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 };
2448 const UCHAR ThTiming
[] = { 1, 2, 2, 3, 0, 1, 1, 2 };
2450 USHORT tempah
, tempal
, tempcl
, tempbx
, temp
;
2453 tempah
= SiS_GetReg(SiS_Pr
->SiS_P3c4
,0x18);
2460 tempcl
= ThTiming
[tempal
];
2461 tempbx
= SiS_GetReg(SiS_Pr
->SiS_P3c4
,0x16);
2463 tempah
= SiS_GetReg(SiS_Pr
->SiS_P3c4
,0x14);
2469 tempal
= ThLowA
[tempbx
+ 1];
2471 tempal
+= ThLowA
[tempbx
];
2473 tempal
= ThLowB
[tempbx
+ 1];
2475 tempal
+= ThLowB
[tempbx
];
2477 longtemp
= tempal
* VCLK
* colordepth
;
2478 temp
= longtemp
% (MCLK
* 16);
2479 longtemp
/= (MCLK
* 16);
2480 if(temp
) longtemp
++;
2481 return((USHORT
)longtemp
);
2485 SiS_CalcDelay(SiS_Private
*SiS_Pr
, USHORT VCLK
, USHORT colordepth
, USHORT MCLK
)
2487 USHORT tempax
, tempbx
;
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;
2493 if(tempbx
< tempax
) tempbx
= tempax
;
2498 SiS_SetCRT1FIFO_300(SiS_Private
*SiS_Pr
, USHORT ModeNo
, PSIS_HW_INFO HwInfo
,
2499 USHORT RefreshRateTableIndex
)
2501 USHORT ThresholdLow
= 0;
2502 USHORT index
, VCLK
, MCLK
, colorth
=0;
2503 USHORT tempah
, temp
;
2507 if(SiS_Pr
->UseCustomMode
) {
2508 VCLK
= SiS_Pr
->CSRClock
;
2510 index
= SiS_Pr
->SiS_RefIndex
[RefreshRateTableIndex
].Ext_CRTVCLK
;
2512 VCLK
= SiS_Pr
->SiS_VCLKData
[index
].CLOCK
; /* Get VCLK */
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;
2524 index
= SiS_GetReg(SiS_Pr
->SiS_P3c4
,0x3A);
2526 MCLK
= SiS_Pr
->SiS_MCLKData_0
[index
].CLOCK
; /* Get MCLK */
2528 tempah
= SiS_GetReg(SiS_Pr
->SiS_P3d4
,0x35);
2530 SiS_SetRegANDOR(SiS_Pr
->SiS_P3c4
,0x16,0x3c,tempah
);
2533 ThresholdLow
= SiS_CalcDelay(SiS_Pr
, VCLK
, colorth
, MCLK
);
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);
2540 if(!(tempah
)) break;
2543 SiS_SetRegANDOR(SiS_Pr
->SiS_P3c4
,0x16,0x3f,tempah
);
2546 } else ThresholdLow
= 2;
2548 /* Write CRT/CPU threshold low, CRT/Engine threshold high */
2549 temp
= (ThresholdLow
<< 4) | 0x0f;
2550 SiS_SetReg(SiS_Pr
->SiS_P3c4
,0x08,temp
);
2552 temp
= (ThresholdLow
& 0x10) << 1;
2553 if(ModeNo
> 0x13) temp
|= 0x40;
2554 SiS_SetRegANDOR(SiS_Pr
->SiS_P3c4
,0x0f,0x9f,temp
);
2557 SiS_SetReg(SiS_Pr
->SiS_P3c4
,0x3B,0x09);
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
);
2566 SiS_CalcDelay2(SiS_Private
*SiS_Pr
, UCHAR key
, PSIS_HW_INFO HwInfo
)
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 */
2579 const UCHAR LatencyFactor730
[] = {
2584 137,130,128, /* --- Table ends with this entry, data below */
2585 137,130,128, /* to avoid using illegal values */
2598 if(HwInfo
->jChipType
== SIS_730
) {
2599 index
= ((key
& 0x0f) * 3) + ((key
& 0xC0) >> 6);
2600 data
= LatencyFactor730
[index
];
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
];
2613 SiS_SetCRT1FIFO_630(SiS_Private
*SiS_Pr
, USHORT ModeNo
,
2614 PSIS_HW_INFO HwInfo
,
2615 USHORT RefreshRateTableIndex
)
2617 USHORT i
,index
,data
,VCLK
,MCLK
,colorth
=0;
2618 ULONG B
,eax
,bl
,data2
;
2619 USHORT ThresholdLow
=0;
2621 0x01,0x21,0x41,0x61,0x81,
2622 0x31,0x51,0x71,0x91,0xb1,
2623 0x00,0x20,0x40,0x60,0x80,
2624 0x30,0x50,0x70,0x90,0xb0,
2627 UCHAR FQBQData730
[]= {
2638 if(SiS_Pr
->UseCustomMode
) {
2639 VCLK
= SiS_Pr
->CSRClock
;
2641 index
= SiS_Pr
->SiS_RefIndex
[RefreshRateTableIndex
].Ext_CRTVCLK
;
2643 VCLK
= SiS_Pr
->SiS_VCLKData
[index
].CLOCK
; /* Get VCLK */
2646 index
= SiS_GetReg(SiS_Pr
->SiS_P3c4
,0x1A);
2648 MCLK
= SiS_Pr
->SiS_MCLKData_0
[index
].CLOCK
; /* Get MCLK */
2650 data2
= SiS_Pr
->SiS_ModeType
- ModeEGA
; /* Get half colordepth */
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;
2660 if(HwInfo
->jChipType
== SIS_730
) {
2663 B
= SiS_CalcDelay2(SiS_Pr
, FQBQData730
[i
], HwInfo
) * VCLK
* colorth
;
2664 bl
= B
/ (MCLK
* 16);
2666 if(B
== bl
* 16 * MCLK
) {
2673 if(FQBQData730
[i
+1] == 0xFF) {
2674 ThresholdLow
= 0x13;
2682 } while(FQBQData730
[i
] != 0xFF);
2687 B
= SiS_CalcDelay2(SiS_Pr
, FQBQData
[i
], HwInfo
) * VCLK
* colorth
;
2688 bl
= B
/ (MCLK
* 16);
2690 if(B
== bl
* 16 * MCLK
) {
2697 if(FQBQData
[i
+1] == 0xFF) {
2698 ThresholdLow
= 0x13;
2706 } while(FQBQData
[i
] != 0xFF);
2710 if(HwInfo
->jChipType
== SIS_730
) {
2714 ThresholdLow
= 0x02;
2717 /* Write foreground and background queue */
2718 if(HwInfo
->jChipType
== SIS_730
) {
2720 data2
= FQBQData730
[i
];
2721 data2
= (data2
& 0xC0) >> 5;
2725 SiS_SetRegLong(0xcf8,0x80000050);
2726 eax
= SiS_GetRegLong(0xcfc);
2729 SiS_SetRegLong(0xcfc,eax
);
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.
2735 eax
= pciReadLong(0x00000000, 0x50);
2738 pciWriteLong(0x00000000, 0x50, eax
);
2741 /* Write GUI grant timer (PCI config 0xA3) */
2742 data2
= FQBQData730
[i
] << 8;
2743 data2
= (data2
& 0x0f00) | ((data2
& 0x3000) >> 8);
2747 SiS_SetRegLong(0xcf8,0x800000A0);
2748 eax
= SiS_GetRegLong(0xcfc);
2751 SiS_SetRegLong(0xcfc,eax
);
2753 eax
= pciReadLong(0x00000000, 0xA0);
2756 pciWriteLong(0x00000000, 0xA0, eax
);
2761 data2
= FQBQData
[i
];
2762 data2
= (data2
& 0xf0) >> 4;
2766 SiS_SetRegLong(0xcf8,0x80000050);
2767 eax
= SiS_GetRegLong(0xcfc);
2770 SiS_SetRegLong(0xcfc,eax
);
2772 eax
= pciReadLong(0x00000000, 0x50);
2775 pciWriteLong(0x00000000, 0x50, eax
);
2778 /* Write GUI grant timer (PCI config 0xA3) */
2779 data2
= FQBQData
[i
];
2784 SiS_SetRegLong(0xcf8,0x800000A0);
2785 eax
= SiS_GetRegLong(0xcfc);
2788 SiS_SetRegLong(0xcfc,eax
);
2790 eax
= pciReadLong(0x00000000, 0xA0);
2793 pciWriteLong(0x00000000, 0xA0, eax
);
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
);
2802 data
= (ThresholdLow
& 0x10) << 1;
2803 SiS_SetRegANDOR(SiS_Pr
->SiS_P3c4
,0x0F,0xDF,data
);
2806 SiS_SetReg(SiS_Pr
->SiS_P3c4
,0x3B,0x09);
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
);
2817 SiS_SetCRT1FIFO_310(SiS_Private
*SiS_Pr
, USHORT ModeNo
, USHORT ModeIdIndex
,
2818 PSIS_HW_INFO HwInfo
)
2822 /* disable auto-threshold */
2823 SiS_SetRegAND(SiS_Pr
->SiS_P3c4
,0x3D,0xFE);
2825 if(SiS_Pr
->UseCustomMode
) {
2826 modeflag
= SiS_Pr
->CModeFlag
;
2828 modeflag
= SiS_Pr
->SiS_EModeIDTable
[ModeIdIndex
].Ext_ModeFlag
;
2831 SiS_SetReg(SiS_Pr
->SiS_P3c4
,0x08,0xAE);
2832 SiS_SetRegAND(SiS_Pr
->SiS_P3c4
,0x09,0xF0);
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);
2840 if((!(modeflag
& DoubleScanMode
)) || (!(modeflag
& HalfDCLK
))) {
2841 SiS_SetReg(SiS_Pr
->SiS_P3c4
,0x08,0x34);
2842 SiS_SetRegOR(SiS_Pr
->SiS_P3c4
,0x3D,0x01);
2849 /*********************************************/
2850 /* MODE REGISTERS */
2851 /*********************************************/
2854 SiS_SetVCLKState(SiS_Private
*SiS_Pr
, PSIS_HW_INFO HwInfo
,
2855 USHORT ModeNo
, USHORT RefreshRateTableIndex
,
2858 USHORT data
=0, VCLK
=0, index
=0;
2861 if(SiS_Pr
->UseCustomMode
) {
2862 VCLK
= SiS_Pr
->CSRClock
;
2864 index
= SiS_GetVCLK2Ptr(SiS_Pr
,ModeNo
,ModeIdIndex
,
2865 RefreshRateTableIndex
,HwInfo
);
2866 VCLK
= SiS_Pr
->SiS_VCLKData
[index
].CLOCK
;
2870 if(HwInfo
->jChipType
< SIS_315H
) {
2872 if(VCLK
> 150) data
|= 0x80;
2873 SiS_SetRegANDOR(SiS_Pr
->SiS_P3c4
,0x07,0x7B,data
);
2876 if(VCLK
>= 150) data
|= 0x08;
2877 SiS_SetRegANDOR(SiS_Pr
->SiS_P3c4
,0x32,0xF7,data
);
2881 if(VCLK
>= 166) data
|= 0x0c;
2882 SiS_SetRegANDOR(SiS_Pr
->SiS_P3c4
,0x32,0xf3,data
);
2885 SiS_SetRegAND(SiS_Pr
->SiS_P3c4
,0x1f,0xe7);
2890 if(HwInfo
->jChipType
>= SIS_661
) {
2892 SiS_SetRegANDOR(SiS_Pr
->SiS_P3c4
,0x07,0xE8,0x10);
2897 if((VCLK
>= 135) && (VCLK
< 160)) data
= 0x02;
2898 else if((VCLK
>= 160) && (VCLK
< 260)) data
= 0x01;
2899 else if(VCLK
>= 260) data
= 0x00;
2901 if(HwInfo
->jChipType
== SIS_540
) {
2902 if((VCLK
== 203) || (VCLK
< 234)) data
= 0x02;
2905 if(HwInfo
->jChipType
< SIS_315H
) {
2906 SiS_SetRegANDOR(SiS_Pr
->SiS_P3c4
,0x07,0xFC,data
);
2908 if(HwInfo
->jChipType
> SIS_315PRO
) {
2909 if(ModeNo
> 0x13) data
&= 0xfc;
2911 SiS_SetRegANDOR(SiS_Pr
->SiS_P3c4
,0x07,0xF8,data
);
2918 SiS_SetCRT1ModeRegs(SiS_Private
*SiS_Pr
, PSIS_HW_INFO HwInfo
,
2919 USHORT ModeNo
,USHORT ModeIdIndex
,USHORT RefreshRateTableIndex
)
2921 USHORT data
,infoflag
=0,modeflag
;
2922 USHORT resindex
,xres
;
2926 UCHAR
*ROMAddr
= HwInfo
->pjVirtualRomBase
;
2929 if(SiS_Pr
->UseCustomMode
) {
2930 modeflag
= SiS_Pr
->CModeFlag
;
2931 infoflag
= SiS_Pr
->CInfoFlag
;
2932 xres
= SiS_Pr
->CHDisplay
;
2934 resindex
= SiS_GetResInfo(SiS_Pr
,ModeNo
,ModeIdIndex
);
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
;
2940 modeflag
= SiS_Pr
->SiS_SModeIDTable
[ModeIdIndex
].St_ModeFlag
;
2941 xres
= SiS_Pr
->SiS_StResInfo
[resindex
].HTotal
;
2946 SiS_SetRegAND(SiS_Pr
->SiS_P3c4
,0x1F,0x3F);
2950 if(SiS_Pr
->SiS_ModeType
> ModeEGA
) {
2952 data
|= ((SiS_Pr
->SiS_ModeType
- ModeVGA
) << 2);
2954 if(infoflag
& InterlaceMode
) data
|= 0x20;
2956 SiS_SetRegANDOR(SiS_Pr
->SiS_P3c4
,0x06,0xC0,data
);
2958 if(HwInfo
->jChipType
!= SIS_300
) {
2960 if(infoflag
& InterlaceMode
) {
2961 if(xres
<= 800) data
= 0x0020;
2962 else if(xres
<= 1024) data
= 0x0035;
2965 SiS_SetReg(SiS_Pr
->SiS_P3d4
,0x19,(data
& 0xFF));
2966 SiS_SetRegANDOR(SiS_Pr
->SiS_P3d4
,0x1a,0xFC,(data
>> 8));
2969 if(modeflag
& HalfDCLK
) {
2970 SiS_SetRegOR(SiS_Pr
->SiS_P3c4
,0x01,0x08);
2974 if(modeflag
& LineCompareOff
) data
= 0x08;
2975 if(HwInfo
->jChipType
== SIS_300
) {
2976 SiS_SetRegANDOR(SiS_Pr
->SiS_P3c4
,0x0F,0xF7,data
);
2978 SiS_SetRegANDOR(SiS_Pr
->SiS_P3c4
,0x0F,0xB7,data
);
2979 if(SiS_Pr
->SiS_ModeType
== ModeEGA
) {
2981 SiS_SetRegOR(SiS_Pr
->SiS_P3c4
,0x0F,0x40);
2986 if(HwInfo
->jChipType
>= SIS_661
) {
2987 SiS_SetRegAND(SiS_Pr
->SiS_P3c4
,0x31,0xfb);
2991 if(HwInfo
->jChipType
== SIS_315PRO
) {
2993 data
= SiS_Get310DRAMType(SiS_Pr
, HwInfo
);
2994 data
= SiS_Pr
->SiS_SR15
[2][data
];
2995 if(SiS_Pr
->SiS_ModeType
== ModeText
) {
2998 data2
= SiS_GetOffset(SiS_Pr
,ModeNo
,ModeIdIndex
,
2999 RefreshRateTableIndex
,HwInfo
);
3001 if(infoflag
& InterlaceMode
) data2
>>= 1;
3002 data3
= SiS_GetColorDepth(SiS_Pr
,ModeNo
,ModeIdIndex
) >> 1;
3010 SiS_SetReg(SiS_Pr
->SiS_P3c4
,0x17,data
);
3012 } else if( (HwInfo
->jChipType
== SIS_330
) ||
3013 ((HwInfo
->jChipType
== SIS_760
) && (SiS_Pr
->SiS_SysFlags
& SF_760LFB
))) {
3015 data
= SiS_Get310DRAMType(SiS_Pr
, HwInfo
);
3016 if(HwInfo
->jChipType
== SIS_330
) {
3017 data
= SiS_Pr
->SiS_SR15
[2][data
];
3019 if(SiS_Pr
->SiS_ROMNew
) data
= ROMAddr
[0xf6];
3020 else if(SiS_Pr
->SiS_UseROM
) data
= ROMAddr
[0x100 + data
];
3023 if(SiS_Pr
->SiS_ModeType
<= ModeEGA
) {
3026 if(SiS_Pr
->UseCustomMode
) {
3027 data2
= SiS_Pr
->CSRClock
;
3029 data2
= SiS_GetVCLK2Ptr(SiS_Pr
,ModeNo
,ModeIdIndex
,
3030 RefreshRateTableIndex
,HwInfo
);
3031 data2
= SiS_Pr
->SiS_VCLKData
[data2
].CLOCK
;
3034 data3
= SiS_GetColorDepth(SiS_Pr
,ModeNo
,ModeIdIndex
) >> 1;
3035 if(data3
) data2
*= data3
;
3037 longdata
= SiS_GetMCLK(SiS_Pr
, HwInfo
) * 1024;
3039 data2
= longdata
/ data2
;
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;
3054 if(data2
>= 0x127) data
= 0xba;
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;
3066 SiS_SetReg(SiS_Pr
->SiS_P3c4
,0x17,data
);
3067 } else if(HwInfo
->jChipType
== SIS_340
) {
3073 if(SiS_Pr
->SiS_ModeType
!= ModeText
) {
3075 if(SiS_Pr
->SiS_ModeType
!= ModeEGA
) {
3079 SiS_SetRegANDOR(SiS_Pr
->SiS_P3c4
,0x21,0x1F,data
);
3081 SiS_SetVCLKState(SiS_Pr
, HwInfo
, ModeNo
, RefreshRateTableIndex
, ModeIdIndex
);
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);
3088 SiS_SetReg(SiS_Pr
->SiS_P3d4
,0x52,0x6c);
3094 /*********************************************/
3096 /*********************************************/
3100 SiS_ClearDAC(SiS_Private
*SiS_Pr
, ULONG port
)
3104 OutPortByte(port
, 0);
3106 for (i
=0; i
< (256 * 3); i
++) {
3107 OutPortByte(port
, 0);
3113 SiS_WriteDAC(SiS_Private
*SiS_Pr
, SISIOADDRESS DACData
, USHORT shiftflag
,
3114 USHORT dl
, USHORT ah
, USHORT al
, USHORT dh
)
3139 SiS_SetRegByte(DACData
,(USHORT
)dh
);
3140 SiS_SetRegByte(DACData
,(USHORT
)bh
);
3141 SiS_SetRegByte(DACData
,(USHORT
)bl
);
3145 SiS_LoadDAC(SiS_Private
*SiS_Pr
, PSIS_HW_INFO HwInfo
,
3146 USHORT ModeNo
, USHORT ModeIdIndex
)
3149 USHORT time
,i
,j
,k
,m
,n
,o
;
3150 USHORT si
,di
,bx
,dl
,al
,ah
,dh
;
3152 SISIOADDRESS DACAddr
, DACData
;
3153 const USHORT
*table
= NULL
;
3155 if(ModeNo
<= 0x13) {
3156 data
= SiS_Pr
->SiS_SModeIDTable
[ModeIdIndex
].St_ModeFlag
;
3158 if(SiS_Pr
->UseCustomMode
) {
3159 data
= SiS_Pr
->CModeFlag
;
3161 data
= SiS_Pr
->SiS_EModeIDTable
[ModeIdIndex
].Ext_ModeFlag
;
3165 data
&= DACInfoFlag
;
3167 if(data
== 0x00) table
= SiS_MDA_DAC
;
3168 if(data
== 0x08) table
= SiS_CGA_DAC
;
3169 if(data
== 0x10) table
= SiS_EGA_DAC
;
3172 table
= SiS_VGA_DAC
;
3174 if(time
== 256) j
= 16;
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
;
3184 SiS_SetRegByte(SiS_Pr
->SiS_P3c6
,0xFF);
3187 DACAddr
= SiS_Pr
->SiS_Part5Port
;
3188 DACData
= SiS_Pr
->SiS_Part5Port
+ 1;
3191 SiS_SetRegByte(DACAddr
,0x00);
3193 for(i
=0; i
<j
; i
++) {
3195 for(k
=0; k
<3; k
++) {
3197 if(data
& 0x01) data2
= 0x2A;
3198 if(data
& 0x02) data2
+= 0x15;
3199 if(shiftflag
) data2
<<= 2;
3200 SiS_SetRegByte(DACData
, data2
);
3206 for(i
= 16; i
< 32; i
++) {
3208 if(shiftflag
) data
<<= 2;
3209 for(k
= 0; k
< 3; k
++) SiS_SetRegByte(DACData
, data
);
3212 for(m
= 0; m
< 9; m
++) {
3216 for(n
= 0; n
< 3; n
++) {
3217 for(o
= 0; o
< 5; o
++) {
3222 SiS_WriteDAC(SiS_Pr
, DACData
, shiftflag
, dl
, ah
, al
, dh
);
3225 for(o
= 0; o
< 3; o
++) {
3230 SiS_WriteDAC(SiS_Pr
, DACData
, shiftflag
, dl
, ah
, al
, dh
);
3239 /*********************************************/
3240 /* SET CRT1 REGISTER GROUP */
3241 /*********************************************/
3244 SiS_SetCRT1Group(SiS_Private
*SiS_Pr
, PSIS_HW_INFO HwInfo
,
3245 USHORT ModeNo
, USHORT ModeIdIndex
)
3247 USHORT StandTableIndex
,RefreshRateTableIndex
;
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
);
3257 SiS_ResetSegmentRegisters(SiS_Pr
, HwInfo
);
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
);
3267 SiS_Pr
->SiS_SelectCRT2Rate
= 0;
3268 SiS_Pr
->SiS_SetFlag
&= (~ProgrammingCRT2
);
3271 xf86DrvMsgVerb(0, X_PROBED
, 4, "(init: VBType=0x%04x, VBInfo=0x%04x)\n",
3272 SiS_Pr
->SiS_VBType
, SiS_Pr
->SiS_VBInfo
);
3275 if(SiS_Pr
->SiS_VBInfo
& SetSimuScanMode
) {
3276 if(SiS_Pr
->SiS_VBInfo
& SetInSlaveMode
) {
3277 SiS_Pr
->SiS_SetFlag
|= ProgrammingCRT2
;
3281 if(SiS_Pr
->SiS_VBInfo
& SetCRT2ToLCDA
) {
3282 SiS_Pr
->SiS_SetFlag
|= ProgrammingCRT2
;
3285 RefreshRateTableIndex
= SiS_GetRatePtr(SiS_Pr
, ModeNo
, ModeIdIndex
, HwInfo
);
3287 if(!(SiS_Pr
->SiS_VBInfo
& SetCRT2ToLCDA
)) {
3288 SiS_Pr
->SiS_SetFlag
&= ~ProgrammingCRT2
;
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
);
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
);
3308 if(HwInfo
->jChipType
>= SIS_315H
) {
3309 SiS_SetCRT1FIFO_310(SiS_Pr
, ModeNo
, ModeIdIndex
, HwInfo
);
3313 SiS_SetCRT1ModeRegs(SiS_Pr
, HwInfo
, ModeNo
, ModeIdIndex
, RefreshRateTableIndex
);
3315 SiS_LoadDAC(SiS_Pr
, HwInfo
, ModeNo
, ModeIdIndex
);
3318 if(SiS_Pr
->SiS_flag_clearbuffer
) {
3319 SiS_ClearBuffer(SiS_Pr
,HwInfo
,ModeNo
);
3323 if(!(SiS_Pr
->SiS_VBInfo
& (SetSimuScanMode
| SwitchCRT2
| SetCRT2ToLCDA
))) {
3324 SiS_WaitRetrace1(SiS_Pr
);
3325 SiS_DisplayOn(SiS_Pr
);
3329 /*********************************************/
3330 /* HELPER: VIDEO BRIDGE PROG CLK */
3331 /*********************************************/
3334 SiS_ResetVB(SiS_Private
*SiS_Pr
, PSIS_HW_INFO HwInfo
)
3336 UCHAR
*ROMAddr
= HwInfo
->pjVirtualRomBase
;
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
);
3353 /*********************************************/
3354 /* HELPER: SET VIDEO REGISTERS */
3355 /*********************************************/
3358 SiS_StrangeStuff(SiS_Private
*SiS_Pr
, PSIS_HW_INFO HwInfo
)
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);
3367 /* !!! This does not support modes < 0x13 !!! */
3370 /*********************************************/
3371 /* XFree86: SET SCREEN PITCH */
3372 /*********************************************/
3376 SiS_SetPitchCRT1(SiS_Private
*SiS_Pr
, ScrnInfoPtr pScrn
)
3378 SISPtr pSiS
= SISPTR(pScrn
);
3379 UShort HDisplay
= pSiS
->scrnPitch
>> 3;
3381 SiS_SetReg(SiS_Pr
->SiS_P3d4
,0x13,(HDisplay
& 0xFF));
3382 SiS_SetRegANDOR(SiS_Pr
->SiS_P3c4
,0x0E,0xF0,(HDisplay
>>8));
3386 SiS_SetPitchCRT2(SiS_Private
*SiS_Pr
, ScrnInfoPtr pScrn
)
3388 SISPtr pSiS
= SISPTR(pScrn
);
3389 UShort HDisplay
= pSiS
->scrnPitch2
>> 3;
3392 if(pSiS
->VGAEngine
== SIS_315_VGA
)
3393 SiS_SetRegOR(SiS_Pr
->SiS_Part1Port
,0x2F, 0x01);
3395 SiS_SetRegOR(SiS_Pr
->SiS_Part1Port
,0x24, 0x01);
3397 SiS_SetReg(SiS_Pr
->SiS_Part1Port
,0x07,(HDisplay
& 0xFF));
3398 SiS_SetRegANDOR(SiS_Pr
->SiS_Part1Port
,0x09,0xF0,(HDisplay
>> 8));
3402 SiS_SetPitch(SiS_Private
*SiS_Pr
, ScrnInfoPtr pScrn
)
3404 SISPtr pSiS
= SISPTR(pScrn
);
3405 BOOLEAN isslavemode
= FALSE
;
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) ) ) {
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
);
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
);
3426 /*********************************************/
3428 /*********************************************/
3431 /* We need pScrn for setting the pitch correctly */
3433 SiSSetMode(SiS_Private
*SiS_Pr
, PSIS_HW_INFO HwInfo
,ScrnInfoPtr pScrn
,USHORT ModeNo
, BOOLEAN dosetpitch
)
3436 SiSSetMode(SiS_Private
*SiS_Pr
, PSIS_HW_INFO HwInfo
,USHORT ModeNo
)
3440 SISIOADDRESS BaseAddr
= HwInfo
->ulIOAddress
;
3441 unsigned char backupreg
=0;
3446 SiS_Pr
->UseCustomMode
= FALSE
;
3447 SiS_Pr
->CRT1UsesCustomMode
= FALSE
;
3450 if(SiS_Pr
->UseCustomMode
) {
3454 SiSInitPtr(SiS_Pr
, HwInfo
);
3455 SiSRegInit(SiS_Pr
, BaseAddr
);
3456 SiS_GetSysFlags(SiS_Pr
, HwInfo
);
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);
3462 SiS_Pr
->SiS_VGAINFO
= 0x11;
3464 SiSInitPCIetc(SiS_Pr
, HwInfo
);
3465 SiSSetLVDSetc(SiS_Pr
, HwInfo
);
3466 SiSDetermineROMUsage(SiS_Pr
, HwInfo
);
3468 SiS_Pr
->SiS_flag_clearbuffer
= 0;
3470 if(!SiS_Pr
->UseCustomMode
) {
3472 if(!(ModeNo
& 0x80)) SiS_Pr
->SiS_flag_clearbuffer
= 1;
3478 KeepLockReg
= SiS_GetReg(SiS_Pr
->SiS_P3c4
,0x05);
3480 SiS_SetReg(SiS_Pr
->SiS_P3c4
,0x05,0x86);
3482 SiS_UnLockCRT2(SiS_Pr
, HwInfo
);
3484 if(!SiS_Pr
->UseCustomMode
) {
3485 if(!(SiS_SearchModeID(SiS_Pr
, &ModeNo
, &ModeIdIndex
))) return FALSE
;
3490 SiS_GetVBType(SiS_Pr
, HwInfo
);
3492 /* Init/restore some VB registers */
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);
3501 backupreg
= SiS_GetReg(SiS_Pr
->SiS_P3d4
,0x35);
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
);
3513 /* 3. Check memory size (Kernel framebuffer driver only) */
3514 temp
= SiS_CheckMemorySize(SiS_Pr
, HwInfo
, ModeNo
, ModeIdIndex
);
3515 if(!temp
) return(0);
3518 if(HwInfo
->jChipType
>= SIS_315H
) {
3519 SiS_SetupCR5x(SiS_Pr
, HwInfo
);
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
;
3527 SiS_Pr
->CRT1UsesCustomMode
= FALSE
;
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
);
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
);
3546 SiS_HandleCRT1(SiS_Pr
);
3548 SiS_StrangeStuff(SiS_Pr
, HwInfo
);
3550 SiS_DisplayOn(SiS_Pr
);
3551 SiS_SetRegByte(SiS_Pr
->SiS_P3c6
,0xFF);
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);
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);
3567 SiS_SetRegAND(SiS_Pr
->SiS_P3d4
,0x35,0xFE);
3571 SiS_SetReg(SiS_Pr
->SiS_P3d4
,0x38,backupreg
);
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);
3580 if(SiS_GetReg(SiS_Pr
->SiS_P3d4
,0x30) & SetCRT2ToLCD
) {
3581 SiS_SetRegAND(SiS_Pr
->SiS_P3d4
,0x38,0xfc);
3583 } else if((HwInfo
->jChipType
== SIS_630
) ||
3584 (HwInfo
->jChipType
== SIS_730
)) {
3585 SiS_SetReg(SiS_Pr
->SiS_P3d4
,0x35,backupreg
);
3591 /* SetPitch: Adapt to virtual size & position */
3592 if((ModeNo
> 0x13) && (dosetpitch
)) {
3593 SiS_SetPitch(SiS_Pr
, pScrn
);
3596 /* Backup/Set ModeNo in BIOS scratch area */
3597 SiS_GetSetModeID(pScrn
, ModeNo
);
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);
3609 /*********************************************/
3610 /* XFree86: SiSBIOSSetMode() */
3611 /* for non-Dual-Head mode */
3612 /*********************************************/
3616 SiSBIOSSetMode(SiS_Private
*SiS_Pr
, PSIS_HW_INFO HwInfo
, ScrnInfoPtr pScrn
,
3617 DisplayModePtr mode
, BOOLEAN IsCustom
)
3619 SISPtr pSiS
= SISPTR(pScrn
);
3622 SiS_Pr
->UseCustomMode
= FALSE
;
3624 if((IsCustom
) && (SiS_CheckBuildCustomMode(pScrn
, mode
, pSiS
->VBFlags
))) {
3626 xf86DrvMsgVerb(pScrn
->scrnIndex
, X_INFO
, 3, "Setting custom mode %dx%d\n",
3628 (mode
->Flags
& V_INTERLACE
? SiS_Pr
->CVDisplay
* 2 :
3629 (mode
->Flags
& V_DBLSCAN
? SiS_Pr
->CVDisplay
/ 2 :
3630 SiS_Pr
->CVDisplay
)));
3634 /* Don't need vbflags here; checks done earlier */
3635 ModeNo
= SiS_GetModeNumber(pScrn
, mode
, 0);
3636 if(!ModeNo
) return FALSE
;
3638 xf86DrvMsgVerb(pScrn
->scrnIndex
, X_INFO
, 3, "Setting standard mode 0x%x\n", ModeNo
);
3642 return(SiSSetMode(SiS_Pr
, HwInfo
, pScrn
, ModeNo
, TRUE
));
3645 /*********************************************/
3646 /* XFree86: SiSBIOSSetModeCRT2() */
3647 /* for Dual-Head modes */
3648 /*********************************************/
3650 SiSBIOSSetModeCRT2(SiS_Private
*SiS_Pr
, PSIS_HW_INFO HwInfo
, ScrnInfoPtr pScrn
,
3651 DisplayModePtr mode
, BOOLEAN IsCustom
)
3654 SISIOADDRESS BaseAddr
= HwInfo
->ulIOAddress
;
3656 unsigned char backupreg
=0;
3657 SISPtr pSiS
= SISPTR(pScrn
);
3659 SISEntPtr pSiSEnt
= pSiS
->entityPrivate
;
3662 SiS_Pr
->UseCustomMode
= FALSE
;
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
3669 if((IsCustom
) && (SiS_CheckBuildCustomMode(pScrn
, mode
, pSiS
->VBFlags
))) {
3675 ModeNo
= SiS_GetModeNumber(pScrn
, mode
, 0);
3676 if(!ModeNo
) return FALSE
;
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);
3686 SiS_Pr
->SiS_VGAINFO
= 0x11;
3688 SiSInitPCIetc(SiS_Pr
, HwInfo
);
3689 SiSSetLVDSetc(SiS_Pr
, HwInfo
);
3690 SiSDetermineROMUsage(SiS_Pr
, HwInfo
);
3692 /* Save mode info so we can set it from within SetMode for CRT1 */
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);
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");
3710 pSiSEnt
->CRT2ModeSet
= TRUE
;
3714 /* We don't clear the buffer in X */
3715 SiS_Pr
->SiS_flag_clearbuffer
=0;
3717 if(SiS_Pr
->UseCustomMode
) {
3719 USHORT temptemp
= SiS_Pr
->CVDisplay
;
3721 if(SiS_Pr
->CModeFlag
& DoubleScanMode
) temptemp
>>= 1;
3722 else if(SiS_Pr
->CInfoFlag
& InterlaceMode
) temptemp
<<= 1;
3724 xf86DrvMsgVerb(pScrn
->scrnIndex
, X_INFO
, 3,
3725 "Setting custom mode %dx%d on CRT2\n",
3726 SiS_Pr
->CHDisplay
, temptemp
);
3730 xf86DrvMsgVerb(pScrn
->scrnIndex
, X_INFO
, 3,
3731 "Setting standard mode 0x%x on CRT2\n", ModeNo
);
3735 SiS_SetReg(SiS_Pr
->SiS_P3c4
,0x05,0x86);
3737 SiS_UnLockCRT2(SiS_Pr
, HwInfo
);
3739 if(!SiS_Pr
->UseCustomMode
) {
3740 if(!(SiS_SearchModeID(SiS_Pr
, &ModeNo
, &ModeIdIndex
))) return FALSE
;
3745 SiS_GetVBType(SiS_Pr
, HwInfo
);
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);
3754 backupreg
= SiS_GetReg(SiS_Pr
->SiS_P3d4
,0x35);
3758 /* Get VB information (connectors, connected devices) */
3759 if(!SiS_Pr
->UseCustomMode
) {
3760 SiS_GetVBInfo(SiS_Pr
, ModeNo
, ModeIdIndex
, HwInfo
, 1);
3762 /* If this is a custom mode, we don't check the modeflag for CRT2Mode */
3763 SiS_GetVBInfo(SiS_Pr
, ModeNo
, ModeIdIndex
, HwInfo
, 0);
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
);
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
);
3778 SiS_StrangeStuff(SiS_Pr
, HwInfo
);
3780 SiS_DisplayOn(SiS_Pr
);
3781 SiS_SetRegByte(SiS_Pr
->SiS_P3c6
,0xFF);
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);
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);
3797 SiS_SetRegAND(SiS_Pr
->SiS_P3d4
,0x35,0xFE);
3801 SiS_SetReg(SiS_Pr
->SiS_P3d4
,0x38,backupreg
);
3803 if(SiS_GetReg(SiS_Pr
->SiS_P3d4
,0x30) & SetCRT2ToLCD
) {
3804 SiS_SetRegAND(SiS_Pr
->SiS_P3d4
,0x38,0xfc);
3806 } else if((HwInfo
->jChipType
== SIS_630
) ||
3807 (HwInfo
->jChipType
== SIS_730
)) {
3808 SiS_SetReg(SiS_Pr
->SiS_P3d4
,0x35,backupreg
);
3812 /* SetPitch: Adapt to virtual size & position */
3813 SiS_SetPitchCRT2(SiS_Pr
, pScrn
);
3818 /*********************************************/
3819 /* XFree86: SiSBIOSSetModeCRT1() */
3820 /* for Dual-Head modes */
3821 /*********************************************/
3824 SiSBIOSSetModeCRT1(SiS_Private
*SiS_Pr
, PSIS_HW_INFO HwInfo
, ScrnInfoPtr pScrn
,
3825 DisplayModePtr mode
, BOOLEAN IsCustom
)
3827 SISPtr pSiS
= SISPTR(pScrn
);
3828 SISIOADDRESS BaseAddr
= HwInfo
->ulIOAddress
;
3829 USHORT ModeIdIndex
, ModeNo
=0;
3832 SISEntPtr pSiSEnt
= pSiS
->entityPrivate
;
3833 UCHAR backupcr30
, backupcr31
, backupcr38
, backupcr35
, backupp40d
=0;
3834 BOOLEAN backupcustom
;
3837 SiS_Pr
->UseCustomMode
= FALSE
;
3839 if((IsCustom
) && (SiS_CheckBuildCustomMode(pScrn
, mode
, pSiS
->VBFlags
))) {
3841 USHORT temptemp
= SiS_Pr
->CVDisplay
;
3843 if(SiS_Pr
->CModeFlag
& DoubleScanMode
) temptemp
>>= 1;
3844 else if(SiS_Pr
->CInfoFlag
& InterlaceMode
) temptemp
<<= 1;
3846 xf86DrvMsgVerb(pScrn
->scrnIndex
, X_INFO
, 3,
3847 "Setting custom mode %dx%d on CRT1\n",
3848 SiS_Pr
->CHDisplay
, temptemp
);
3853 ModeNo
= SiS_GetModeNumber(pScrn
, mode
, 0);
3854 if(!ModeNo
) return FALSE
;
3856 xf86DrvMsgVerb(pScrn
->scrnIndex
, X_INFO
, 3,
3857 "Setting standard mode 0x%x on CRT1\n", ModeNo
);
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);
3866 SiS_Pr
->SiS_VGAINFO
= 0x11;
3868 SiSInitPCIetc(SiS_Pr
, HwInfo
);
3869 SiSSetLVDSetc(SiS_Pr
, HwInfo
);
3870 SiSDetermineROMUsage(SiS_Pr
, HwInfo
);
3872 /* We don't clear the buffer in X */
3873 SiS_Pr
->SiS_flag_clearbuffer
= 0;
3875 SiS_SetReg(SiS_Pr
->SiS_P3c4
,0x05,0x86);
3877 SiS_UnLockCRT2(SiS_Pr
, HwInfo
);
3879 if(!SiS_Pr
->UseCustomMode
) {
3880 if(!(SiS_SearchModeID(SiS_Pr
, &ModeNo
, &ModeIdIndex
))) return FALSE
;
3885 /* Determine VBType */
3886 SiS_GetVBType(SiS_Pr
, HwInfo
);
3888 if(SiS_Pr
->SiS_VBType
& VB_SIS301BLV302BLV
) {
3889 if(HwInfo
->jChipType
>= SIS_315H
) {
3890 backupreg
= SiS_GetReg(SiS_Pr
->SiS_P3d4
,0x38);
3892 backupreg
= SiS_GetReg(SiS_Pr
->SiS_P3d4
,0x35);
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
);
3904 if(HwInfo
->jChipType
>= SIS_315H
) {
3905 SiS_SetupCR5x(SiS_Pr
, HwInfo
);
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
);
3914 /* SetPitch: Adapt to virtual size & position */
3915 SiS_SetPitchCRT1(SiS_Pr
, pScrn
);
3918 if(pSiS
->DualHeadMode
) {
3919 pSiSEnt
->CRT1ModeNo
= ModeNo
;
3920 pSiSEnt
->CRT1DMode
= mode
;
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
;
3929 SiS_Pr
->CRT1UsesCustomMode
= FALSE
;
3932 /* Reset CRT2 if changing mode on CRT1 */
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;
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
);
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
);
3964 SiS_Pr
->UseCustomMode
= backupcustom
;
3969 /* Warning: From here, the custom mode entries in SiS_Pr are
3970 * possibly overwritten
3973 SiS_HandleCRT1(SiS_Pr
);
3975 SiS_StrangeStuff(SiS_Pr
, HwInfo
);
3977 SiS_DisplayOn(SiS_Pr
);
3978 SiS_SetRegByte(SiS_Pr
->SiS_P3c6
,0xFF);
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
);
3989 /* Backup/Set ModeNo in BIOS scratch area */
3990 SiS_GetSetModeID(pScrn
,ModeNo
);
3994 #endif /* Linux_XF86 */
3999 SiS_GetPanelID(SiS_Private
*SiS_Pr
, PSIS_HW_INFO HwInfo
)
4001 const USHORT PanelTypeTable300
[16] = {
4002 0xc101, 0xc117, 0x0121, 0xc135, 0xc142, 0xc152, 0xc162, 0xc072,
4003 0xc181, 0xc192, 0xc1a1, 0xc1b6, 0xc1c2, 0xc0d2, 0xc1e2, 0xc1f2
4005 const USHORT PanelTypeTable31030x
[16] = {
4006 0xc102, 0xc112, 0x0122, 0xc132, 0xc142, 0xc152, 0xc169, 0xc179,
4007 0x0189, 0xc192, 0xc1a2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
4009 const USHORT PanelTypeTable310LVDS
[16] = {
4010 0xc111, 0xc122, 0xc133, 0xc144, 0xc155, 0xc166, 0xc177, 0xc188,
4011 0xc199, 0xc0aa, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
4013 USHORT tempax
,tempbx
,temp
;
4015 if(HwInfo
->jChipType
< SIS_315H
) {
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){
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;
4032 tempbx
= PanelTypeTable300
[tempbx
];
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
);
4041 if(HwInfo
->jChipType
>= SIS_661
) return 0;
4043 tempax
= SiS_GetReg(SiS_Pr
->SiS_P3c4
,0x1a);
4046 if(SiS_Pr
->SiS_IF_DEF_LVDS
== 1) {
4048 /* TODO: Include HUGE detection routine
4049 (Probably not worth bothering)
4053 temp
= tempax
& 0xff;
4055 tempbx
= PanelTypeTable310LVDS
[tempax
];
4057 tempbx
= PanelTypeTable31030x
[tempax
];
4058 temp
= tempbx
& 0xff;
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
);
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))
4082 SiS_CalcCRRegisters(SiS_Private
*SiS_Pr
, int depth
)
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);
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)
4098 | (((SiS_Pr
->CVTotal
- 2) & 0x200) >> 4)
4099 | (((SiS_Pr
->CVDisplay
- 1) & 0x200) >> 3)
4100 | ((SiS_Pr
->CVSyncStart
& 0x200) >> 2);
4102 SiS_Pr
->CCRT1CRTC
[16] = ((((SiS_Pr
->CVBlankStart
- 1) & 0x200) >> 4) >> 5); /* CR9 */
4105 if(SiS_Pr
->CHDisplay
>= 1600) SiS_Pr
->CCRT1CRTC
[16] |= 0x60; /* SRE */
4106 else if(SiS_Pr
->CHDisplay
>= 640) SiS_Pr
->CCRT1CRTC
[16] |= 0x40;
4110 if (mode
->VScan
>= 32)
4111 regp
->CRTC
[9] |= 0x1F;
4112 else if (mode
->VScan
> 1)
4113 regp
->CRTC
[9] |= mode
->VScan
- 1;
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 */
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) ;
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) ;
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) ;
4143 SiS_CalcLCDACRT1Timing(SiS_Private
*SiS_Pr
,USHORT ModeNo
,USHORT ModeIdIndex
)
4145 USHORT modeflag
, tempax
, tempbx
, VGAHDE
= SiS_Pr
->SiS_VGAHDE
;
4148 /* 1:1 data: use data set by setcrt1crtc() */
4149 if(SiS_Pr
->SiS_LCDInfo
& LCDPass11
) return;
4151 if(ModeNo
<= 0x13) {
4152 modeflag
= SiS_Pr
->SiS_SModeIDTable
[ModeIdIndex
].St_ModeFlag
;
4153 } else if(SiS_Pr
->UseCustomMode
) {
4154 modeflag
= SiS_Pr
->CModeFlag
;
4156 modeflag
= SiS_Pr
->SiS_EModeIDTable
[ModeIdIndex
].Ext_ModeFlag
;
4159 if(modeflag
& HalfDCLK
) VGAHDE
>>= 1;
4161 SiS_Pr
->CHDisplay
= VGAHDE
;
4162 SiS_Pr
->CHBlankStart
= VGAHDE
;
4164 SiS_Pr
->CVDisplay
= SiS_Pr
->SiS_VGAVDE
;
4165 SiS_Pr
->CVBlankStart
= SiS_Pr
->SiS_VGAVDE
;
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
;
4173 if(modeflag
& HalfDCLK
) tempbx
-= VGAHDE
;
4174 SiS_Pr
->CHTotal
= SiS_Pr
->CHBlankEnd
= tempbx
;
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);
4184 tempax
+= SiS_Pr
->PanelHRS
;
4185 SiS_Pr
->CHSyncStart
= tempax
;
4186 tempax
+= SiS_Pr
->PanelHRE
;
4187 SiS_Pr
->CHSyncEnd
= tempax
;
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
;
4194 SiS_Pr
->CVTotal
= SiS_Pr
->CVBlankEnd
= tempbx
+ tempax
;
4196 tempax
= SiS_Pr
->SiS_VGAVDE
;
4197 if(SiS_Pr
->SiS_LCDInfo
& DontExpandLCD
) {
4198 tempax
+= (SiS_Pr
->PanelYRes
- tempax
) >> 1;
4200 tempax
+= SiS_Pr
->PanelVRS
;
4201 SiS_Pr
->CVSyncStart
= tempax
;
4202 tempax
+= SiS_Pr
->PanelVRE
;
4203 SiS_Pr
->CVSyncEnd
= tempax
;
4205 SiS_CalcCRRegisters(SiS_Pr
, 8);
4206 SiS_Pr
->CCRT1CRTC
[16] &= ~0xE0;
4208 SiS_SetRegAND(SiS_Pr
->SiS_P3d4
,0x11,0x7f);
4210 for(i
=0,j
=0;i
<=7;i
++,j
++) {
4211 SiS_SetReg(SiS_Pr
->SiS_P3d4
,j
,SiS_Pr
->CCRT1CRTC
[i
]);
4213 for(j
=0x10;i
<=10;i
++,j
++) {
4214 SiS_SetReg(SiS_Pr
->SiS_P3d4
,j
,SiS_Pr
->CCRT1CRTC
[i
]);
4216 for(j
=0x15;i
<=12;i
++,j
++) {
4217 SiS_SetReg(SiS_Pr
->SiS_P3d4
,j
,SiS_Pr
->CCRT1CRTC
[i
]);
4219 for(j
=0x0A;i
<=15;i
++,j
++) {
4220 SiS_SetReg(SiS_Pr
->SiS_P3c4
,j
,SiS_Pr
->CCRT1CRTC
[i
]);
4223 tempax
= SiS_Pr
->CCRT1CRTC
[16] & 0xE0;
4224 SiS_SetRegANDOR(SiS_Pr
->SiS_P3c4
,0x0E,0x1F,tempax
);
4226 tempax
= (SiS_Pr
->CCRT1CRTC
[16] & 0x01) << 5;
4227 if(modeflag
& DoubleScanMode
) tempax
|= 0x80;
4228 SiS_SetRegANDOR(SiS_Pr
->SiS_P3d4
,0x09,0x5F,tempax
);
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
);
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]);
4253 SiS_MakeClockRegs(ScrnInfoPtr pScrn
, int clock
, UCHAR
*p2b
, UCHAR
*p2c
)
4255 int out_n
, out_dn
, out_div
, out_sbit
, out_scale
;
4256 unsigned int vclk
[5];
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);
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
);
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;
4284 (*p2c
) |= (((vclk
[Pidx
] / 2) - 1) & 3) << 5;
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
]);
4296 /* ================ XFREE86/X.ORG ================= */
4298 /* Helper functions */
4303 SiS_CheckBuildCustomMode(ScrnInfoPtr pScrn
, DisplayModePtr mode
, int VBFlags
)
4305 SISPtr pSiS
= SISPTR(pScrn
);
4306 int depth
= pSiS
->CurrentLayout
.bitsPerPixel
;
4308 pSiS
->SiS_Pr
->CModeFlag
= 0;
4310 pSiS
->SiS_Pr
->CDClock
= mode
->Clock
;
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
;
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
;
4322 pSiS
->SiS_Pr
->CFlags
= mode
->Flags
;
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;
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;
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
;
4343 SiS_MakeClockRegs(pScrn
, pSiS
->SiS_Pr
->CDClock
, &pSiS
->SiS_Pr
->CSR2B
, &pSiS
->SiS_Pr
->CSR2C
);
4345 pSiS
->SiS_Pr
->CSRClock
= (pSiS
->SiS_Pr
->CDClock
/ 1000) + 1;
4347 SiS_CalcCRRegisters(pSiS
->SiS_Pr
, 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;
4356 if(pSiS
->SiS_Pr
->CFlags
& V_DBLSCAN
)
4357 pSiS
->SiS_Pr
->CModeFlag
|= DoubleScanMode
;
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
;
4364 if(pSiS
->SiS_Pr
->CFlags
& V_CLKDIV2
)
4365 pSiS
->SiS_Pr
->CModeFlag
|= HalfDCLK
;
4367 pSiS
->SiS_Pr
->CInfoFlag
= 0x0007;
4369 if(pSiS
->SiS_Pr
->CFlags
& V_NHSYNC
)
4370 pSiS
->SiS_Pr
->CInfoFlag
|= 0x4000;
4372 if(pSiS
->SiS_Pr
->CFlags
& V_NVSYNC
)
4373 pSiS
->SiS_Pr
->CInfoFlag
|= 0x8000;
4375 if(pSiS
->SiS_Pr
->CFlags
& V_INTERLACE
)
4376 pSiS
->SiS_Pr
->CInfoFlag
|= InterlaceMode
;
4378 pSiS
->SiS_Pr
->UseCustomMode
= TRUE
;
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
);
4402 SiS_FindPanelFromDB(SISPtr pSiS
, USHORT panelvendor
, USHORT panelproduct
, int *maxx
, int *maxy
, int *prefx
, int *prefy
)
4405 BOOLEAN done
= FALSE
;
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
;
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
);
4429 return (done
) ? 1 : 0;
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
4437 SiSBuildBuiltInModeList(ScrnInfoPtr pScrn
, BOOLEAN includelcdmodes
, BOOLEAN isfordvi
)
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
;
4449 DisplayModePtr backup
= NULL
;
4452 pSiS
->backupmodelist
= NULL
;
4453 pSiS
->AddedPlasmaModes
= FALSE
;
4455 /* Initialize our pointers */
4456 if(pSiS
->VGAEngine
== SIS_300_VGA
) {
4458 InitTo300Pointer(pSiS
->SiS_Pr
, &pSiS
->sishw_ext
);
4462 } else if(pSiS
->VGAEngine
== SIS_315_VGA
) {
4464 InitTo310Pointer(pSiS
->SiS_Pr
, &pSiS
->sishw_ext
);
4471 while(pSiS
->SiS_Pr
->SiS_RefIndex
[i
].Ext_InfoFlag
!= 0xFFFF) {
4473 index
= pSiS
->SiS_Pr
->SiS_RefIndex
[i
].Ext_CRT1CRTC
;
4475 /* 0x5a (320x240) is a pure FTSN mode, not DSTN! */
4477 (pSiS
->SiS_Pr
->SiS_RefIndex
[i
].ModeID
== 0x5a)) {
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)) {
4489 if(!(new = xalloc(sizeof(DisplayModeRec
)))) return first
;
4490 memset(new, 0, sizeof(DisplayModeRec
));
4491 if(!(new->name
= xalloc(10))) {
4495 if(!first
) first
= new;
4497 current
->next
= new;
4498 new->prev
= current
;
4503 sprintf(current
->name
, "%dx%d", pSiS
->SiS_Pr
->SiS_RefIndex
[i
].XRes
,
4504 pSiS
->SiS_Pr
->SiS_RefIndex
[i
].YRes
);
4506 current
->status
= MODE_OK
;
4508 current
->type
= M_T_DEFAULT
;
4510 vclkindex
= pSiS
->SiS_Pr
->SiS_RefIndex
[i
].Ext_CRTVCLK
;
4511 if(pSiS
->VGAEngine
== SIS_300_VGA
) vclkindex
&= 0x3F;
4513 sr2b
= pSiS
->SiS_Pr
->SiS_VCLKData
[vclkindex
].SR2B
;
4514 sr2c
= pSiS
->SiS_Pr
->SiS_VCLKData
[vclkindex
].SR2C
;
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;
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
);
4528 current
->Clock
= (int)(14318 * (divider
/ postscalar
) * (num
/ denum
));
4530 sr_data
= pSiS
->SiS_Pr
->SiS_CRT1Table
[index
].CR
[14];
4531 /* inSISIDXREG(SISSR, 0x0b, sr_data); */
4533 cr_data
= pSiS
->SiS_Pr
->SiS_CRT1Table
[index
].CR
[0];
4534 /* inSISIDXREG(SISCR, 0x00, cr_data); */
4536 /* Horizontal total */
4537 HT
= (cr_data
& 0xff) |
4538 ((unsigned short) (sr_data
& 0x03) << 8);
4541 cr_data
= pSiS
->SiS_Pr
->SiS_CRT1Table
[index
].CR
[1];
4542 /* inSISIDXREG(SISCR, 0x01, cr_data); */
4544 /* Horizontal display enable end */
4545 HDE
= (cr_data
& 0xff) |
4546 ((unsigned short) (sr_data
& 0x0C) << 6);
4547 E
= HDE
+ 1; /* 0x80 0x64 */
4549 cr_data
= pSiS
->SiS_Pr
->SiS_CRT1Table
[index
].CR
[4];
4550 /* inSISIDXREG(SISCR, 0x04, cr_data); */
4552 /* Horizontal retrace (=sync) start */
4553 HRS
= (cr_data
& 0xff) |
4554 ((unsigned short) (sr_data
& 0xC0) << 2);
4555 F
= HRS
- E
- 3; /* 0x06 0x06 */
4557 cr_data
= pSiS
->SiS_Pr
->SiS_CRT1Table
[index
].CR
[2];
4558 /* inSISIDXREG(SISCR, 0x02, cr_data); */
4560 /* Horizontal blank start */
4561 HBS
= (cr_data
& 0xff) |
4562 ((unsigned short) (sr_data
& 0x30) << 4);
4564 sr_data
= pSiS
->SiS_Pr
->SiS_CRT1Table
[index
].CR
[15];
4565 /* inSISIDXREG(SISSR, 0x0c, sr_data); */
4567 cr_data
= pSiS
->SiS_Pr
->SiS_CRT1Table
[index
].CR
[3];
4568 /* inSISIDXREG(SISCR, 0x03, cr_data); */
4570 cr_data2
= pSiS
->SiS_Pr
->SiS_CRT1Table
[index
].CR
[5];
4571 /* inSISIDXREG(SISCR, 0x05, cr_data2); */
4573 /* Horizontal blank end */
4574 HBE
= (cr_data
& 0x1f) |
4575 ((unsigned short) (cr_data2
& 0x80) >> 2) |
4576 ((unsigned short) (sr_data
& 0x03) << 6);
4578 /* Horizontal retrace (=sync) end */
4579 HRE
= (cr_data2
& 0x1f) | ((sr_data
& 0x04) << 3);
4581 temp
= HBE
- ((E
- 1) & 255);
4582 B
= (temp
> 0) ? temp
: (temp
+ 256);
4584 temp
= HRE
- ((E
+ F
+ 3) & 63);
4585 C
= (temp
> 0) ? temp
: (temp
+ 64); /* 0x0b 0x0b */
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))) {
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
4599 current
->HDisplay
= 320;
4600 current
->HSyncStart
= 328;
4601 current
->HSyncEnd
= 376;
4602 current
->HTotal
= 400;
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);
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
);
4619 sr_data
= pSiS
->SiS_Pr
->SiS_CRT1Table
[index
].CR
[13];
4620 /* inSISIDXREG(SISSR, 0x0A, sr_data); */
4622 cr_data
= pSiS
->SiS_Pr
->SiS_CRT1Table
[index
].CR
[6];
4623 /* inSISIDXREG(SISCR, 0x06, cr_data); */
4625 cr_data2
= pSiS
->SiS_Pr
->SiS_CRT1Table
[index
].CR
[7];
4626 /* inSISIDXREG(SISCR, 0x07, cr_data2); */
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);
4635 cr_data
= pSiS
->SiS_Pr
->SiS_CRT1Table
[index
].CR
[10];
4636 /* inSISIDXREG(SISCR, 0x12, cr_data); */
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);
4645 cr_data
= pSiS
->SiS_Pr
->SiS_CRT1Table
[index
].CR
[8];
4646 /* inSISIDXREG(SISCR, 0x10, cr_data); */
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);
4655 cr_data
= pSiS
->SiS_Pr
->SiS_CRT1Table
[index
].CR
[11];
4656 /* inSISIDXREG(SISCR, 0x15, cr_data); */
4658 cr_data3
= (pSiS
->SiS_Pr
->SiS_CRT1Table
[index
].CR
[16] & 0x01) << 5;
4659 /* inSISIDXREG(SISCR, 0x09, cr_data3); */
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);
4667 cr_data
= pSiS
->SiS_Pr
->SiS_CRT1Table
[index
].CR
[12];
4668 /* inSISIDXREG(SISCR, 0x16, cr_data); */
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);
4676 cr_data
= pSiS
->SiS_Pr
->SiS_CRT1Table
[index
].CR
[9];
4677 /* inSISIDXREG(SISCR, 0x11, cr_data); */
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);
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
;
4693 current
->VDisplay
= E
;
4694 current
->VSyncStart
= E
+ D
;
4695 current
->VSyncEnd
= E
+ D
+ C
;
4696 current
->VTotal
= E
+ D
+ C
+ F
;
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
);
4705 if(pSiS
->SiS_Pr
->SiS_RefIndex
[i
].Ext_InfoFlag
& 0x4000)
4706 current
->Flags
|= V_NHSYNC
;
4708 current
->Flags
|= V_PHSYNC
;
4710 if(pSiS
->SiS_Pr
->SiS_RefIndex
[i
].Ext_InfoFlag
& 0x8000)
4711 current
->Flags
|= V_NVSYNC
;
4713 current
->Flags
|= V_PVSYNC
;
4715 if(pSiS
->SiS_Pr
->SiS_RefIndex
[i
].Ext_InfoFlag
& 0x0080)
4716 current
->Flags
|= V_INTERLACE
;
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
;
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;
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;
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
);
4752 (void)VBS
; (void)HBS
; (void)A
;
4758 /* Add non-standard LCD modes for panel's detailed timings */
4760 if(!includelcdmodes
) return first
;
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
);
4768 while((!done
) && (SiS_PlasmaTable
[i
].vendor
) && (pSiS
->SiS_Pr
->CP_Vendor
)) {
4770 if(SiS_PlasmaTable
[i
].vendor
== pSiS
->SiS_Pr
->CP_Vendor
) {
4772 for(j
=0; j
<SiS_PlasmaTable
[i
].productnum
; j
++) {
4774 if(SiS_PlasmaTable
[i
].product
[j
] == pSiS
->SiS_Pr
->CP_Product
) {
4776 xf86DrvMsg(pScrn
->scrnIndex
, X_PROBED
,
4777 "Identified %s panel, adding specific modes\n",
4778 SiS_PlasmaTable
[i
].plasmaname
);
4780 for(k
=0; k
<SiS_PlasmaTable
[i
].modenum
; k
++) {
4783 if(!(SiS_PlasmaTable
[i
].plasmamodes
[k
] & 0x80)) continue;
4785 if(!(SiS_PlasmaTable
[i
].plasmamodes
[k
] & 0x40)) continue;
4788 l
= SiS_PlasmaTable
[i
].plasmamodes
[k
] & 0x3f;
4790 if(pSiS
->VBFlags
& (VB_301
|VB_301B
|VB_302B
|VB_301LV
)) {
4792 if(SiS_PlasmaMode
[l
].VDisplay
> 1024) continue;
4796 if(!(new = xalloc(sizeof(DisplayModeRec
)))) return first
;
4798 memset(new, 0, sizeof(DisplayModeRec
));
4799 if(!(new->name
= xalloc(12))) {
4803 if(!first
) first
= new;
4805 current
->next
= new;
4806 new->prev
= current
;
4811 pSiS
->AddedPlasmaModes
= TRUE
;
4813 strcpy(current
->name
, SiS_PlasmaMode
[l
].name
);
4814 /* sprintf(current->name, "%dx%d", SiS_PlasmaMode[l].HDisplay,
4815 SiS_PlasmaMode[l].VDisplay); */
4817 current
->status
= MODE_OK
;
4819 current
->type
= M_T_BUILTIN
;
4821 current
->Clock
= SiS_PlasmaMode
[l
].clock
;
4822 current
->SynthClock
= current
->Clock
;
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
;
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
;
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
;
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
;
4848 if(SiS_PlasmaMode
[l
].SyncFlags
& SIS_PL_HSYNCP
)
4849 current
->Flags
|= V_PHSYNC
;
4851 current
->Flags
|= V_NHSYNC
;
4853 if(SiS_PlasmaMode
[l
].SyncFlags
& SIS_PL_VSYNCP
)
4854 current
->Flags
|= V_PVSYNC
;
4856 current
->Flags
|= V_NVSYNC
;
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
;
4863 xf86DrvMsg(pScrn
->scrnIndex
, X_PROBED
,
4864 "\tAdding \"%s\" to list of built-in modes\n", current
->name
);
4877 if(pSiS
->SiS_Pr
->CP_HaveCustomData
) {
4879 for(i
=0; i
<7; i
++) {
4881 if(pSiS
->SiS_Pr
->CP_DataValid
[i
]) {
4883 if(!(new = xalloc(sizeof(DisplayModeRec
)))) return first
;
4885 memset(new, 0, sizeof(DisplayModeRec
));
4886 if(!(new->name
= xalloc(10))) {
4890 if(!first
) first
= new;
4892 current
->next
= new;
4893 new->prev
= current
;
4898 sprintf(current
->name
, "%dx%d", pSiS
->SiS_Pr
->CP_HDisplay
[i
],
4899 pSiS
->SiS_Pr
->CP_VDisplay
[i
]);
4901 current
->status
= MODE_OK
;
4903 current
->type
= M_T_BUILTIN
;
4905 current
->Clock
= pSiS
->SiS_Pr
->CP_Clock
[i
];
4906 current
->SynthClock
= current
->Clock
;
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
];
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
];
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
;
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
;
4932 if(pSiS
->SiS_Pr
->CP_SyncValid
[i
]) {
4933 if(pSiS
->SiS_Pr
->CP_HSync_P
[i
])
4934 current
->Flags
|= V_PHSYNC
;
4936 current
->Flags
|= V_NHSYNC
;
4938 if(pSiS
->SiS_Pr
->CP_VSync_P
[i
])
4939 current
->Flags
|= V_PVSYNC
;
4941 current
->Flags
|= V_NVSYNC
;
4943 /* No sync data? Use positive sync... */
4944 current
->Flags
|= V_PHSYNC
;
4945 current
->Flags
|= V_PVSYNC
;
4955 /* Translate a mode number into the VESA pendant */
4957 SiSTranslateToVESA(ScrnInfoPtr pScrn
, int modenumber
)
4959 SISPtr pSiS
= SISPTR(pScrn
);
4962 /* Initialize our pointers */
4963 if(pSiS
->VGAEngine
== SIS_300_VGA
) {
4965 InitTo300Pointer(pSiS
->SiS_Pr
, &pSiS
->sishw_ext
);
4969 } else if(pSiS
->VGAEngine
== SIS_315_VGA
) {
4971 InitTo310Pointer(pSiS
->SiS_Pr
, &pSiS
->sishw_ext
);
4977 if(modenumber
<= 0x13) return modenumber
;
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
;
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
;
5001 /* Translate a new BIOS mode number into the driver's pendant */
5003 SiSTranslateToOldMode(int modenumber
)
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
;
5021 #endif /* Xfree86 */
5025 sisfb_mode_rate_to_dclock(SiS_Private
*SiS_Pr
, PSIS_HW_INFO HwInfo
,
5026 unsigned char modeno
, unsigned char rateindex
)
5028 USHORT ModeNo
= modeno
;
5029 USHORT ModeIdIndex
= 0, ClockIndex
= 0;
5030 USHORT RefreshRateTableIndex
= 0;
5033 if(HwInfo
->jChipType
< SIS_315H
) {
5035 InitTo300Pointer(SiS_Pr
, HwInfo
);
5041 InitTo310Pointer(SiS_Pr
, HwInfo
);
5047 if(!(SiS_SearchModeID(SiS_Pr
, &ModeNo
, &ModeIdIndex
))) {;
5048 printk(KERN_ERR
"Could not find mode %x\n", ModeNo
);
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
) {
5058 Clock
= SiS_Pr
->SiS_VCLKData
[ClockIndex
].CLOCK
* 1000;
5064 sisfb_gettotalfrommode(SiS_Private
*SiS_Pr
, PSIS_HW_INFO HwInfo
,
5065 unsigned char modeno
, int *htotal
, int *vtotal
, unsigned char rateindex
)
5067 USHORT ModeNo
= modeno
;
5068 USHORT ModeIdIndex
= 0, CRT1Index
= 0;
5069 USHORT RefreshRateTableIndex
= 0;
5070 unsigned char sr_data
, cr_data
, cr_data2
;
5072 if(HwInfo
->jChipType
< SIS_315H
) {
5074 InitTo300Pointer(SiS_Pr
, HwInfo
);
5080 InitTo310Pointer(SiS_Pr
, HwInfo
);
5086 if(!(SiS_SearchModeID(SiS_Pr
, &ModeNo
, &ModeIdIndex
))) return FALSE
;
5088 RefreshRateTableIndex
= SiS_Pr
->SiS_EModeIDTable
[ModeIdIndex
].REFindex
;
5089 RefreshRateTableIndex
+= (rateindex
- 1);
5090 CRT1Index
= SiS_Pr
->SiS_RefIndex
[RefreshRateTableIndex
].Ext_CRT1CRTC
;
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;
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;
5104 if(SiS_Pr
->SiS_RefIndex
[RefreshRateTableIndex
].Ext_InfoFlag
& InterlaceMode
)
5111 sisfb_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
)
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
;
5123 if(HwInfo
->jChipType
< SIS_315H
) {
5125 InitTo300Pointer(SiS_Pr
, HwInfo
);
5131 InitTo310Pointer(SiS_Pr
, HwInfo
);
5137 if(!(SiS_SearchModeID(SiS_Pr
, &ModeNo
, &ModeIdIndex
))) return 0;
5139 RefreshRateTableIndex
= SiS_Pr
->SiS_EModeIDTable
[ModeIdIndex
].REFindex
;
5140 RefreshRateTableIndex
+= (rateindex
- 1);
5141 index
= SiS_Pr
->SiS_RefIndex
[RefreshRateTableIndex
].Ext_CRT1CRTC
;
5143 sr_data
= SiS_Pr
->SiS_CRT1Table
[index
].CR
[14];
5145 cr_data
= SiS_Pr
->SiS_CRT1Table
[index
].CR
[0];
5147 /* Horizontal total */
5148 HT
= (cr_data
& 0xff) |
5149 ((unsigned short) (sr_data
& 0x03) << 8);
5152 cr_data
= SiS_Pr
->SiS_CRT1Table
[index
].CR
[1];
5154 /* Horizontal display enable end */
5155 HDE
= (cr_data
& 0xff) |
5156 ((unsigned short) (sr_data
& 0x0C) << 6);
5159 cr_data
= SiS_Pr
->SiS_CRT1Table
[index
].CR
[4];
5161 /* Horizontal retrace (=sync) start */
5162 HRS
= (cr_data
& 0xff) |
5163 ((unsigned short) (sr_data
& 0xC0) << 2);
5166 cr_data
= SiS_Pr
->SiS_CRT1Table
[index
].CR
[2];
5168 /* Horizontal blank start */
5169 HBS
= (cr_data
& 0xff) |
5170 ((unsigned short) (sr_data
& 0x30) << 4);
5172 sr_data
= SiS_Pr
->SiS_CRT1Table
[index
].CR
[15];
5174 cr_data
= SiS_Pr
->SiS_CRT1Table
[index
].CR
[3];
5176 cr_data2
= SiS_Pr
->SiS_CRT1Table
[index
].CR
[5];
5178 /* Horizontal blank end */
5179 HBE
= (cr_data
& 0x1f) |
5180 ((unsigned short) (cr_data2
& 0x80) >> 2) |
5181 ((unsigned short) (sr_data
& 0x03) << 6);
5183 /* Horizontal retrace (=sync) end */
5184 HRE
= (cr_data2
& 0x1f) | ((sr_data
& 0x04) << 3);
5186 temp
= HBE
- ((E
- 1) & 255);
5187 B
= (temp
> 0) ? temp
: (temp
+ 256);
5189 temp
= HRE
- ((E
+ F
+ 3) & 63);
5190 C
= (temp
> 0) ? temp
: (temp
+ 64);
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))) {
5198 /* Terrible hack, but the correct CRTC data for
5199 * these modes only produces a black screen...
5201 var
->left_margin
= (400 - 376);
5202 var
->right_margin
= (328 - 320);
5203 var
->hsync_len
= (376 - 328);
5207 var
->left_margin
= D
* 8;
5208 var
->right_margin
= F
* 8;
5209 var
->hsync_len
= C
* 8;
5213 sr_data
= SiS_Pr
->SiS_CRT1Table
[index
].CR
[13];
5215 cr_data
= SiS_Pr
->SiS_CRT1Table
[index
].CR
[6];
5217 cr_data2
= SiS_Pr
->SiS_CRT1Table
[index
].CR
[7];
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);
5226 cr_data
= SiS_Pr
->SiS_CRT1Table
[index
].CR
[10];
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);
5235 cr_data
= SiS_Pr
->SiS_CRT1Table
[index
].CR
[8];
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);
5244 cr_data
= SiS_Pr
->SiS_CRT1Table
[index
].CR
[11];
5246 cr_data3
= (SiS_Pr
->SiS_CRT1Table
[index
].CR
[16] & 0x01) << 5;
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);
5254 cr_data
= SiS_Pr
->SiS_CRT1Table
[index
].CR
[12];
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);
5262 cr_data
= SiS_Pr
->SiS_CRT1Table
[index
].CR
[9];
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);
5271 var
->upper_margin
= D
;
5272 var
->lower_margin
= F
;
5275 if(SiS_Pr
->SiS_RefIndex
[RefreshRateTableIndex
].Ext_InfoFlag
& 0x8000)
5276 var
->sync
&= ~FB_SYNC_VERT_HIGH_ACT
;
5278 var
->sync
|= FB_SYNC_VERT_HIGH_ACT
;
5280 if(SiS_Pr
->SiS_RefIndex
[RefreshRateTableIndex
].Ext_InfoFlag
& 0x4000)
5281 var
->sync
&= ~FB_SYNC_HOR_HIGH_ACT
;
5283 var
->sync
|= FB_SYNC_HOR_HIGH_ACT
;
5285 var
->vmode
= FB_VMODE_NONINTERLACED
;
5286 if(SiS_Pr
->SiS_RefIndex
[RefreshRateTableIndex
].Ext_InfoFlag
& 0x0080)
5287 var
->vmode
= FB_VMODE_INTERLACED
;
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
;
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;
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;