2 * sisusb - usb kernel driver for SiS315(E) based USB2VGA dongles
4 * Display mode initializing code
6 * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
8 * If distributed as part of the Linux kernel, this code is licensed under the
11 * Otherwise, the following license terms apply:
13 * * Redistribution and use in source and binary forms, with or without
14 * * modification, are permitted provided that the following conditions
16 * * 1) Redistributions of source code must retain the above copyright
17 * * notice, this list of conditions and the following disclaimer.
18 * * 2) Redistributions in binary form must reproduce the above copyright
19 * * notice, this list of conditions and the following disclaimer in the
20 * * documentation and/or other materials provided with the distribution.
21 * * 3) The name of the author may not be used to endorse or promote products
22 * * derived from this software without specific prior written permission.
24 * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
25 * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26 * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27 * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
28 * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29 * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33 * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 * Author: Thomas Winischhofer <thomas@winischhofer.net>
39 #include <linux/module.h>
40 #include <linux/kernel.h>
41 #include <linux/errno.h>
42 #include <linux/poll.h>
43 #include <linux/init.h>
44 #include <linux/spinlock.h>
48 #ifdef INCL_SISUSB_CON
50 #include "sisusb_init.h"
52 /*********************************************/
53 /* POINTER INITIALIZATION */
54 /*********************************************/
56 static void SiSUSB_InitPtr(struct SiS_Private
*SiS_Pr
)
58 SiS_Pr
->SiS_ModeResInfo
= SiSUSB_ModeResInfo
;
59 SiS_Pr
->SiS_StandTable
= SiSUSB_StandTable
;
61 SiS_Pr
->SiS_SModeIDTable
= SiSUSB_SModeIDTable
;
62 SiS_Pr
->SiS_EModeIDTable
= SiSUSB_EModeIDTable
;
63 SiS_Pr
->SiS_RefIndex
= SiSUSB_RefIndex
;
64 SiS_Pr
->SiS_CRT1Table
= SiSUSB_CRT1Table
;
66 SiS_Pr
->SiS_VCLKData
= SiSUSB_VCLKData
;
69 /*********************************************/
70 /* HELPER: SetReg, GetReg */
71 /*********************************************/
74 SiS_SetReg(struct SiS_Private
*SiS_Pr
, unsigned long port
,
75 unsigned short index
, unsigned short data
)
77 sisusb_setidxreg(SiS_Pr
->sisusb
, port
, index
, data
);
81 SiS_SetRegByte(struct SiS_Private
*SiS_Pr
, unsigned long port
,
84 sisusb_setreg(SiS_Pr
->sisusb
, port
, data
);
88 SiS_GetReg(struct SiS_Private
*SiS_Pr
, unsigned long port
, unsigned short index
)
92 sisusb_getidxreg(SiS_Pr
->sisusb
, port
, index
, &data
);
98 SiS_GetRegByte(struct SiS_Private
*SiS_Pr
, unsigned long port
)
102 sisusb_getreg(SiS_Pr
->sisusb
, port
, &data
);
108 SiS_SetRegANDOR(struct SiS_Private
*SiS_Pr
, unsigned long port
,
109 unsigned short index
, unsigned short DataAND
,
110 unsigned short DataOR
)
112 sisusb_setidxregandor(SiS_Pr
->sisusb
, port
, index
, DataAND
, DataOR
);
116 SiS_SetRegAND(struct SiS_Private
*SiS_Pr
, unsigned long port
,
117 unsigned short index
, unsigned short DataAND
)
119 sisusb_setidxregand(SiS_Pr
->sisusb
, port
, index
, DataAND
);
123 SiS_SetRegOR(struct SiS_Private
*SiS_Pr
, unsigned long port
,
124 unsigned short index
, unsigned short DataOR
)
126 sisusb_setidxregor(SiS_Pr
->sisusb
, port
, index
, DataOR
);
129 /*********************************************/
130 /* HELPER: DisplayOn, DisplayOff */
131 /*********************************************/
133 static void SiS_DisplayOn(struct SiS_Private
*SiS_Pr
)
135 SiS_SetRegAND(SiS_Pr
, SiS_Pr
->SiS_P3c4
, 0x01, 0xDF);
138 /*********************************************/
139 /* HELPER: Init Port Addresses */
140 /*********************************************/
142 static void SiSUSBRegInit(struct SiS_Private
*SiS_Pr
, unsigned long BaseAddr
)
144 SiS_Pr
->SiS_P3c4
= BaseAddr
+ 0x14;
145 SiS_Pr
->SiS_P3d4
= BaseAddr
+ 0x24;
146 SiS_Pr
->SiS_P3c0
= BaseAddr
+ 0x10;
147 SiS_Pr
->SiS_P3ce
= BaseAddr
+ 0x1e;
148 SiS_Pr
->SiS_P3c2
= BaseAddr
+ 0x12;
149 SiS_Pr
->SiS_P3ca
= BaseAddr
+ 0x1a;
150 SiS_Pr
->SiS_P3c6
= BaseAddr
+ 0x16;
151 SiS_Pr
->SiS_P3c7
= BaseAddr
+ 0x17;
152 SiS_Pr
->SiS_P3c8
= BaseAddr
+ 0x18;
153 SiS_Pr
->SiS_P3c9
= BaseAddr
+ 0x19;
154 SiS_Pr
->SiS_P3cb
= BaseAddr
+ 0x1b;
155 SiS_Pr
->SiS_P3cc
= BaseAddr
+ 0x1c;
156 SiS_Pr
->SiS_P3cd
= BaseAddr
+ 0x1d;
157 SiS_Pr
->SiS_P3da
= BaseAddr
+ 0x2a;
158 SiS_Pr
->SiS_Part1Port
= BaseAddr
+ SIS_CRT2_PORT_04
;
161 /*********************************************/
162 /* HELPER: GetSysFlags */
163 /*********************************************/
165 static void SiS_GetSysFlags(struct SiS_Private
*SiS_Pr
)
167 SiS_Pr
->SiS_MyCR63
= 0x63;
170 /*********************************************/
171 /* HELPER: Init PCI & Engines */
172 /*********************************************/
174 static void SiSInitPCIetc(struct SiS_Private
*SiS_Pr
)
176 SiS_SetReg(SiS_Pr
, SiS_Pr
->SiS_P3c4
, 0x20, 0xa1);
177 /* - Enable 2D (0x40)
179 * - Enable 3D vertex command fetch (0x10)
180 * - Enable 3D command parser (0x08)
181 * - Enable 3D G/L transformation engine (0x80)
183 SiS_SetRegOR(SiS_Pr
, SiS_Pr
->SiS_P3c4
, 0x1E, 0xDA);
186 /*********************************************/
187 /* HELPER: SET SEGMENT REGISTERS */
188 /*********************************************/
190 static void SiS_SetSegRegLower(struct SiS_Private
*SiS_Pr
, unsigned short value
)
195 temp
= SiS_GetRegByte(SiS_Pr
, SiS_Pr
->SiS_P3cb
) & 0xf0;
196 temp
|= (value
>> 4);
197 SiS_SetRegByte(SiS_Pr
, SiS_Pr
->SiS_P3cb
, temp
);
198 temp
= SiS_GetRegByte(SiS_Pr
, SiS_Pr
->SiS_P3cd
) & 0xf0;
199 temp
|= (value
& 0x0f);
200 SiS_SetRegByte(SiS_Pr
, SiS_Pr
->SiS_P3cd
, temp
);
203 static void SiS_SetSegRegUpper(struct SiS_Private
*SiS_Pr
, unsigned short value
)
208 temp
= SiS_GetRegByte(SiS_Pr
, SiS_Pr
->SiS_P3cb
) & 0x0f;
209 temp
|= (value
& 0xf0);
210 SiS_SetRegByte(SiS_Pr
, SiS_Pr
->SiS_P3cb
, temp
);
211 temp
= SiS_GetRegByte(SiS_Pr
, SiS_Pr
->SiS_P3cd
) & 0x0f;
212 temp
|= (value
<< 4);
213 SiS_SetRegByte(SiS_Pr
, SiS_Pr
->SiS_P3cd
, temp
);
216 static void SiS_SetSegmentReg(struct SiS_Private
*SiS_Pr
, unsigned short value
)
218 SiS_SetSegRegLower(SiS_Pr
, value
);
219 SiS_SetSegRegUpper(SiS_Pr
, value
);
222 static void SiS_ResetSegmentReg(struct SiS_Private
*SiS_Pr
)
224 SiS_SetSegmentReg(SiS_Pr
, 0);
228 SiS_SetSegmentRegOver(struct SiS_Private
*SiS_Pr
, unsigned short value
)
230 unsigned short temp
= value
>> 8;
234 SiS_SetReg(SiS_Pr
, SiS_Pr
->SiS_P3c4
, 0x1d, temp
);
235 SiS_SetSegmentReg(SiS_Pr
, value
);
238 static void SiS_ResetSegmentRegOver(struct SiS_Private
*SiS_Pr
)
240 SiS_SetSegmentRegOver(SiS_Pr
, 0);
243 static void SiS_ResetSegmentRegisters(struct SiS_Private
*SiS_Pr
)
245 SiS_ResetSegmentReg(SiS_Pr
);
246 SiS_ResetSegmentRegOver(SiS_Pr
);
249 /*********************************************/
250 /* HELPER: SearchModeID */
251 /*********************************************/
254 SiS_SearchModeID(struct SiS_Private
*SiS_Pr
, unsigned short *ModeNo
,
255 unsigned short *ModeIdIndex
)
257 if ((*ModeNo
) <= 0x13) {
259 if ((*ModeNo
) != 0x03)
266 for (*ModeIdIndex
= 0;; (*ModeIdIndex
)++) {
268 if (SiS_Pr
->SiS_EModeIDTable
[*ModeIdIndex
].Ext_ModeID
==
272 if (SiS_Pr
->SiS_EModeIDTable
[*ModeIdIndex
].Ext_ModeID
==
282 /*********************************************/
283 /* HELPER: ENABLE CRT1 */
284 /*********************************************/
286 static void SiS_HandleCRT1(struct SiS_Private
*SiS_Pr
)
288 /* Enable CRT1 gating */
289 SiS_SetRegAND(SiS_Pr
, SiS_Pr
->SiS_P3d4
, SiS_Pr
->SiS_MyCR63
, 0xbf);
292 /*********************************************/
293 /* HELPER: GetColorDepth */
294 /*********************************************/
296 static unsigned short
297 SiS_GetColorDepth(struct SiS_Private
*SiS_Pr
, unsigned short ModeNo
,
298 unsigned short ModeIdIndex
)
300 static const unsigned short ColorDepth
[6] = { 1, 2, 4, 4, 6, 8 };
301 unsigned short modeflag
;
304 if (ModeNo
<= 0x13) {
305 modeflag
= SiS_Pr
->SiS_SModeIDTable
[ModeIdIndex
].St_ModeFlag
;
307 modeflag
= SiS_Pr
->SiS_EModeIDTable
[ModeIdIndex
].Ext_ModeFlag
;
310 index
= (modeflag
& ModeTypeMask
) - ModeEGA
;
313 return ColorDepth
[index
];
316 /*********************************************/
317 /* HELPER: GetOffset */
318 /*********************************************/
320 static unsigned short
321 SiS_GetOffset(struct SiS_Private
*SiS_Pr
, unsigned short ModeNo
,
322 unsigned short ModeIdIndex
, unsigned short rrti
)
324 unsigned short xres
, temp
, colordepth
, infoflag
;
326 infoflag
= SiS_Pr
->SiS_RefIndex
[rrti
].Ext_InfoFlag
;
327 xres
= SiS_Pr
->SiS_RefIndex
[rrti
].XRes
;
329 colordepth
= SiS_GetColorDepth(SiS_Pr
, ModeNo
, ModeIdIndex
);
333 if (infoflag
& InterlaceMode
)
339 temp
+= (colordepth
>> 1);
344 /*********************************************/
346 /*********************************************/
349 SiS_SetSeqRegs(struct SiS_Private
*SiS_Pr
, unsigned short StandTableIndex
)
351 unsigned char SRdata
;
354 SiS_SetReg(SiS_Pr
, SiS_Pr
->SiS_P3c4
, 0x00, 0x03);
356 SRdata
= SiS_Pr
->SiS_StandTable
[StandTableIndex
].SR
[0] | 0x20;
357 SiS_SetReg(SiS_Pr
, SiS_Pr
->SiS_P3c4
, 0x01, SRdata
);
359 for (i
= 2; i
<= 4; i
++) {
360 SRdata
= SiS_Pr
->SiS_StandTable
[StandTableIndex
].SR
[i
- 1];
361 SiS_SetReg(SiS_Pr
, SiS_Pr
->SiS_P3c4
, i
, SRdata
);
365 /*********************************************/
367 /*********************************************/
370 SiS_SetMiscRegs(struct SiS_Private
*SiS_Pr
, unsigned short StandTableIndex
)
372 unsigned char Miscdata
= SiS_Pr
->SiS_StandTable
[StandTableIndex
].MISC
;
374 SiS_SetRegByte(SiS_Pr
, SiS_Pr
->SiS_P3c2
, Miscdata
);
377 /*********************************************/
379 /*********************************************/
382 SiS_SetCRTCRegs(struct SiS_Private
*SiS_Pr
, unsigned short StandTableIndex
)
384 unsigned char CRTCdata
;
387 SiS_SetRegAND(SiS_Pr
, SiS_Pr
->SiS_P3d4
, 0x11, 0x7f);
389 for (i
= 0; i
<= 0x18; i
++) {
390 CRTCdata
= SiS_Pr
->SiS_StandTable
[StandTableIndex
].CRTC
[i
];
391 SiS_SetReg(SiS_Pr
, SiS_Pr
->SiS_P3d4
, i
, CRTCdata
);
395 /*********************************************/
397 /*********************************************/
400 SiS_SetATTRegs(struct SiS_Private
*SiS_Pr
, unsigned short StandTableIndex
)
402 unsigned char ARdata
;
405 for (i
= 0; i
<= 0x13; i
++) {
406 ARdata
= SiS_Pr
->SiS_StandTable
[StandTableIndex
].ATTR
[i
];
407 SiS_GetRegByte(SiS_Pr
, SiS_Pr
->SiS_P3da
);
408 SiS_SetRegByte(SiS_Pr
, SiS_Pr
->SiS_P3c0
, i
);
409 SiS_SetRegByte(SiS_Pr
, SiS_Pr
->SiS_P3c0
, ARdata
);
411 SiS_GetRegByte(SiS_Pr
, SiS_Pr
->SiS_P3da
);
412 SiS_SetRegByte(SiS_Pr
, SiS_Pr
->SiS_P3c0
, 0x14);
413 SiS_SetRegByte(SiS_Pr
, SiS_Pr
->SiS_P3c0
, 0x00);
415 SiS_GetRegByte(SiS_Pr
, SiS_Pr
->SiS_P3da
);
416 SiS_SetRegByte(SiS_Pr
, SiS_Pr
->SiS_P3c0
, 0x20);
417 SiS_GetRegByte(SiS_Pr
, SiS_Pr
->SiS_P3da
);
420 /*********************************************/
422 /*********************************************/
425 SiS_SetGRCRegs(struct SiS_Private
*SiS_Pr
, unsigned short StandTableIndex
)
427 unsigned char GRdata
;
430 for (i
= 0; i
<= 0x08; i
++) {
431 GRdata
= SiS_Pr
->SiS_StandTable
[StandTableIndex
].GRC
[i
];
432 SiS_SetReg(SiS_Pr
, SiS_Pr
->SiS_P3ce
, i
, GRdata
);
435 if (SiS_Pr
->SiS_ModeType
> ModeVGA
) {
436 /* 256 color disable */
437 SiS_SetRegAND(SiS_Pr
, SiS_Pr
->SiS_P3ce
, 0x05, 0xBF);
441 /*********************************************/
442 /* CLEAR EXTENDED REGISTERS */
443 /*********************************************/
445 static void SiS_ClearExt1Regs(struct SiS_Private
*SiS_Pr
, unsigned short ModeNo
)
449 for (i
= 0x0A; i
<= 0x0E; i
++) {
450 SiS_SetReg(SiS_Pr
, SiS_Pr
->SiS_P3c4
, i
, 0x00);
453 SiS_SetRegAND(SiS_Pr
, SiS_Pr
->SiS_P3c4
, 0x37, 0xFE);
456 /*********************************************/
458 /*********************************************/
460 static unsigned short
461 SiS_GetRatePtr(struct SiS_Private
*SiS_Pr
, unsigned short ModeNo
,
462 unsigned short ModeIdIndex
)
464 unsigned short rrti
, i
, index
, temp
;
469 index
= SiS_GetReg(SiS_Pr
, SiS_Pr
->SiS_P3d4
, 0x33) & 0x0F;
473 rrti
= SiS_Pr
->SiS_EModeIDTable
[ModeIdIndex
].REFindex
;
474 ModeNo
= SiS_Pr
->SiS_RefIndex
[rrti
].ModeID
;
478 if (SiS_Pr
->SiS_RefIndex
[rrti
+ i
].ModeID
!= ModeNo
)
482 SiS_Pr
->SiS_RefIndex
[rrti
+ i
].Ext_InfoFlag
& ModeTypeMask
;
483 if (temp
< SiS_Pr
->SiS_ModeType
)
488 } while (index
!= 0xFFFF);
495 /*********************************************/
497 /*********************************************/
499 static void SiS_SetCRT1Sync(struct SiS_Private
*SiS_Pr
, unsigned short rrti
)
501 unsigned short sync
= SiS_Pr
->SiS_RefIndex
[rrti
].Ext_InfoFlag
>> 8;
504 SiS_SetRegByte(SiS_Pr
, SiS_Pr
->SiS_P3c2
, sync
);
507 /*********************************************/
509 /*********************************************/
512 SiS_SetCRT1CRTC(struct SiS_Private
*SiS_Pr
, unsigned short ModeNo
,
513 unsigned short ModeIdIndex
, unsigned short rrti
)
516 unsigned short temp
, i
, j
, modeflag
;
518 SiS_SetRegAND(SiS_Pr
, SiS_Pr
->SiS_P3d4
, 0x11, 0x7f);
520 modeflag
= SiS_Pr
->SiS_EModeIDTable
[ModeIdIndex
].Ext_ModeFlag
;
522 index
= SiS_Pr
->SiS_RefIndex
[rrti
].Ext_CRT1CRTC
;
524 for (i
= 0, j
= 0; i
<= 7; i
++, j
++) {
525 SiS_SetReg(SiS_Pr
, SiS_Pr
->SiS_P3d4
, j
,
526 SiS_Pr
->SiS_CRT1Table
[index
].CR
[i
]);
528 for (j
= 0x10; i
<= 10; i
++, j
++) {
529 SiS_SetReg(SiS_Pr
, SiS_Pr
->SiS_P3d4
, j
,
530 SiS_Pr
->SiS_CRT1Table
[index
].CR
[i
]);
532 for (j
= 0x15; i
<= 12; i
++, j
++) {
533 SiS_SetReg(SiS_Pr
, SiS_Pr
->SiS_P3d4
, j
,
534 SiS_Pr
->SiS_CRT1Table
[index
].CR
[i
]);
536 for (j
= 0x0A; i
<= 15; i
++, j
++) {
537 SiS_SetReg(SiS_Pr
, SiS_Pr
->SiS_P3c4
, j
,
538 SiS_Pr
->SiS_CRT1Table
[index
].CR
[i
]);
541 temp
= SiS_Pr
->SiS_CRT1Table
[index
].CR
[16] & 0xE0;
542 SiS_SetReg(SiS_Pr
, SiS_Pr
->SiS_P3c4
, 0x0E, temp
);
544 temp
= ((SiS_Pr
->SiS_CRT1Table
[index
].CR
[16]) & 0x01) << 5;
545 if (modeflag
& DoubleScanMode
)
547 SiS_SetRegANDOR(SiS_Pr
, SiS_Pr
->SiS_P3d4
, 0x09, 0x5F, temp
);
549 if (SiS_Pr
->SiS_ModeType
> ModeVGA
)
550 SiS_SetReg(SiS_Pr
, SiS_Pr
->SiS_P3d4
, 0x14, 0x4F);
553 /*********************************************/
555 /*********************************************/
556 /* (partly overruled by SetPitch() in XF86) */
557 /*********************************************/
560 SiS_SetCRT1Offset(struct SiS_Private
*SiS_Pr
, unsigned short ModeNo
,
561 unsigned short ModeIdIndex
, unsigned short rrti
)
563 unsigned short du
= SiS_GetOffset(SiS_Pr
, ModeNo
, ModeIdIndex
, rrti
);
564 unsigned short infoflag
= SiS_Pr
->SiS_RefIndex
[rrti
].Ext_InfoFlag
;
567 temp
= (du
>> 8) & 0x0f;
568 SiS_SetRegANDOR(SiS_Pr
, SiS_Pr
->SiS_P3c4
, 0x0E, 0xF0, temp
);
570 SiS_SetReg(SiS_Pr
, SiS_Pr
->SiS_P3d4
, 0x13, (du
& 0xFF));
572 if (infoflag
& InterlaceMode
)
576 temp
= (du
>> 8) & 0xff;
580 SiS_SetReg(SiS_Pr
, SiS_Pr
->SiS_P3c4
, 0x10, temp
);
583 /*********************************************/
585 /*********************************************/
588 SiS_SetCRT1VCLK(struct SiS_Private
*SiS_Pr
, unsigned short ModeNo
,
591 unsigned short index
= SiS_Pr
->SiS_RefIndex
[rrti
].Ext_CRTVCLK
;
592 unsigned short clka
= SiS_Pr
->SiS_VCLKData
[index
].SR2B
;
593 unsigned short clkb
= SiS_Pr
->SiS_VCLKData
[index
].SR2C
;
595 SiS_SetRegAND(SiS_Pr
, SiS_Pr
->SiS_P3c4
, 0x31, 0xCF);
597 SiS_SetReg(SiS_Pr
, SiS_Pr
->SiS_P3c4
, 0x2B, clka
);
598 SiS_SetReg(SiS_Pr
, SiS_Pr
->SiS_P3c4
, 0x2C, clkb
);
599 SiS_SetReg(SiS_Pr
, SiS_Pr
->SiS_P3c4
, 0x2D, 0x01);
602 /*********************************************/
604 /*********************************************/
607 SiS_SetCRT1FIFO_310(struct SiS_Private
*SiS_Pr
, unsigned short ModeNo
,
610 unsigned short modeflag
= SiS_Pr
->SiS_EModeIDTable
[mi
].Ext_ModeFlag
;
612 /* disable auto-threshold */
613 SiS_SetRegAND(SiS_Pr
, SiS_Pr
->SiS_P3c4
, 0x3D, 0xFE);
615 SiS_SetReg(SiS_Pr
, SiS_Pr
->SiS_P3c4
, 0x08, 0xAE);
616 SiS_SetRegAND(SiS_Pr
, SiS_Pr
->SiS_P3c4
, 0x09, 0xF0);
621 if ((!(modeflag
& DoubleScanMode
)) || (!(modeflag
& HalfDCLK
))) {
622 SiS_SetReg(SiS_Pr
, SiS_Pr
->SiS_P3c4
, 0x08, 0x34);
623 SiS_SetRegOR(SiS_Pr
, SiS_Pr
->SiS_P3c4
, 0x3D, 0x01);
627 /*********************************************/
629 /*********************************************/
632 SiS_SetVCLKState(struct SiS_Private
*SiS_Pr
, unsigned short ModeNo
,
635 unsigned short data
= 0, VCLK
= 0, index
= 0;
638 index
= SiS_Pr
->SiS_RefIndex
[rrti
].Ext_CRTVCLK
;
639 VCLK
= SiS_Pr
->SiS_VCLKData
[index
].CLOCK
;
644 SiS_SetRegANDOR(SiS_Pr
, SiS_Pr
->SiS_P3c4
, 0x32, 0xf3, data
);
647 SiS_SetRegAND(SiS_Pr
, SiS_Pr
->SiS_P3c4
, 0x1f, 0xe7);
653 else if (VCLK
>= 160)
655 else if (VCLK
>= 135)
658 SiS_SetRegANDOR(SiS_Pr
, SiS_Pr
->SiS_P3c4
, 0x07, 0xF8, data
);
662 SiS_SetCRT1ModeRegs(struct SiS_Private
*SiS_Pr
, unsigned short ModeNo
,
663 unsigned short ModeIdIndex
, unsigned short rrti
)
665 unsigned short data
, infoflag
= 0, modeflag
;
668 modeflag
= SiS_Pr
->SiS_SModeIDTable
[ModeIdIndex
].St_ModeFlag
;
670 modeflag
= SiS_Pr
->SiS_EModeIDTable
[ModeIdIndex
].Ext_ModeFlag
;
671 infoflag
= SiS_Pr
->SiS_RefIndex
[rrti
].Ext_InfoFlag
;
675 SiS_SetRegAND(SiS_Pr
, SiS_Pr
->SiS_P3c4
, 0x1F, 0x3F);
679 if (SiS_Pr
->SiS_ModeType
> ModeEGA
) {
681 data
|= ((SiS_Pr
->SiS_ModeType
- ModeVGA
) << 2);
683 if (infoflag
& InterlaceMode
)
686 SiS_SetRegANDOR(SiS_Pr
, SiS_Pr
->SiS_P3c4
, 0x06, 0xC0, data
);
689 if (infoflag
& InterlaceMode
) {
690 /* data = (Hsync / 8) - ((Htotal / 8) / 2) + 3 */
692 (SiS_GetReg(SiS_Pr
, SiS_Pr
->SiS_P3d4
, 0x04) |
693 ((SiS_GetReg(SiS_Pr
, SiS_Pr
->SiS_P3c4
, 0x0b) & 0xc0) << 2))
696 (SiS_GetReg(SiS_Pr
, SiS_Pr
->SiS_P3d4
, 0x00) |
697 ((SiS_GetReg(SiS_Pr
, SiS_Pr
->SiS_P3c4
, 0x0b) & 0x03) << 8))
699 data
= hrs
- (hto
>> 1) + 3;
701 SiS_SetReg(SiS_Pr
, SiS_Pr
->SiS_P3d4
, 0x19, (data
& 0xFF));
702 SiS_SetRegANDOR(SiS_Pr
, SiS_Pr
->SiS_P3d4
, 0x1a, 0xFC, (data
>> 8));
704 if (modeflag
& HalfDCLK
)
705 SiS_SetRegOR(SiS_Pr
, SiS_Pr
->SiS_P3c4
, 0x01, 0x08);
708 if (modeflag
& LineCompareOff
)
710 SiS_SetRegANDOR(SiS_Pr
, SiS_Pr
->SiS_P3c4
, 0x0F, 0xB7, data
);
712 if ((SiS_Pr
->SiS_ModeType
== ModeEGA
) && (ModeNo
> 0x13))
713 SiS_SetRegOR(SiS_Pr
, SiS_Pr
->SiS_P3c4
, 0x0F, 0x40);
715 SiS_SetRegAND(SiS_Pr
, SiS_Pr
->SiS_P3c4
, 0x31, 0xfb);
718 if (SiS_Pr
->SiS_ModeType
!= ModeText
) {
720 if (SiS_Pr
->SiS_ModeType
!= ModeEGA
)
723 SiS_SetRegANDOR(SiS_Pr
, SiS_Pr
->SiS_P3c4
, 0x21, 0x1F, data
);
725 SiS_SetVCLKState(SiS_Pr
, ModeNo
, rrti
);
727 if (SiS_GetReg(SiS_Pr
, SiS_Pr
->SiS_P3d4
, 0x31) & 0x40)
728 SiS_SetReg(SiS_Pr
, SiS_Pr
->SiS_P3d4
, 0x52, 0x2c);
730 SiS_SetReg(SiS_Pr
, SiS_Pr
->SiS_P3d4
, 0x52, 0x6c);
733 /*********************************************/
735 /*********************************************/
738 SiS_WriteDAC(struct SiS_Private
*SiS_Pr
, unsigned long DACData
,
739 unsigned short shiftflag
, unsigned short dl
, unsigned short ah
,
740 unsigned short al
, unsigned short dh
)
742 unsigned short d1
, d2
, d3
;
760 SiS_SetRegByte(SiS_Pr
, DACData
, (d1
<< shiftflag
));
761 SiS_SetRegByte(SiS_Pr
, DACData
, (d2
<< shiftflag
));
762 SiS_SetRegByte(SiS_Pr
, DACData
, (d3
<< shiftflag
));
766 SiS_LoadDAC(struct SiS_Private
*SiS_Pr
, unsigned short ModeNo
,
769 unsigned short data
, data2
, time
, i
, j
, k
, m
, n
, o
;
770 unsigned short si
, di
, bx
, sf
;
771 unsigned long DACAddr
, DACData
;
772 const unsigned char *table
= NULL
;
775 data
= SiS_Pr
->SiS_SModeIDTable
[mi
].St_ModeFlag
;
777 data
= SiS_Pr
->SiS_EModeIDTable
[mi
].Ext_ModeFlag
;
784 else if (data
== 0x08)
786 else if (data
== 0x10)
794 DACAddr
= SiS_Pr
->SiS_P3c8
;
795 DACData
= SiS_Pr
->SiS_P3c9
;
797 SiS_SetRegByte(SiS_Pr
, SiS_Pr
->SiS_P3c6
, 0xFF);
799 SiS_SetRegByte(SiS_Pr
, DACAddr
, 0x00);
801 for (i
= 0; i
< j
; i
++) {
803 for (k
= 0; k
< 3; k
++) {
809 SiS_SetRegByte(SiS_Pr
, DACData
, (data2
<< sf
));
815 for (i
= 16; i
< 32; i
++) {
816 data
= table
[i
] << sf
;
817 for (k
= 0; k
< 3; k
++)
818 SiS_SetRegByte(SiS_Pr
, DACData
, data
);
821 for (m
= 0; m
< 9; m
++) {
824 for (n
= 0; n
< 3; n
++) {
825 for (o
= 0; o
< 5; o
++) {
826 SiS_WriteDAC(SiS_Pr
, DACData
, sf
, n
,
827 table
[di
], table
[bx
],
832 for (o
= 0; o
< 3; o
++) {
833 SiS_WriteDAC(SiS_Pr
, DACData
, sf
, n
,
834 table
[di
], table
[si
],
844 /*********************************************/
845 /* SET CRT1 REGISTER GROUP */
846 /*********************************************/
849 SiS_SetCRT1Group(struct SiS_Private
*SiS_Pr
, unsigned short ModeNo
,
850 unsigned short ModeIdIndex
)
852 unsigned short StandTableIndex
, rrti
;
854 SiS_Pr
->SiS_CRT1Mode
= ModeNo
;
861 SiS_ResetSegmentRegisters(SiS_Pr
);
862 SiS_SetSeqRegs(SiS_Pr
, StandTableIndex
);
863 SiS_SetMiscRegs(SiS_Pr
, StandTableIndex
);
864 SiS_SetCRTCRegs(SiS_Pr
, StandTableIndex
);
865 SiS_SetATTRegs(SiS_Pr
, StandTableIndex
);
866 SiS_SetGRCRegs(SiS_Pr
, StandTableIndex
);
867 SiS_ClearExt1Regs(SiS_Pr
, ModeNo
);
869 rrti
= SiS_GetRatePtr(SiS_Pr
, ModeNo
, ModeIdIndex
);
871 if (rrti
!= 0xFFFF) {
872 SiS_SetCRT1Sync(SiS_Pr
, rrti
);
873 SiS_SetCRT1CRTC(SiS_Pr
, ModeNo
, ModeIdIndex
, rrti
);
874 SiS_SetCRT1Offset(SiS_Pr
, ModeNo
, ModeIdIndex
, rrti
);
875 SiS_SetCRT1VCLK(SiS_Pr
, ModeNo
, rrti
);
878 SiS_SetCRT1FIFO_310(SiS_Pr
, ModeNo
, ModeIdIndex
);
880 SiS_SetCRT1ModeRegs(SiS_Pr
, ModeNo
, ModeIdIndex
, rrti
);
882 SiS_LoadDAC(SiS_Pr
, ModeNo
, ModeIdIndex
);
884 SiS_DisplayOn(SiS_Pr
);
887 /*********************************************/
889 /*********************************************/
891 int SiSUSBSetMode(struct SiS_Private
*SiS_Pr
, unsigned short ModeNo
)
893 unsigned short ModeIdIndex
;
894 unsigned long BaseAddr
= SiS_Pr
->IOAddress
;
896 SiSUSB_InitPtr(SiS_Pr
);
897 SiSUSBRegInit(SiS_Pr
, BaseAddr
);
898 SiS_GetSysFlags(SiS_Pr
);
900 if (!(SiS_SearchModeID(SiS_Pr
, &ModeNo
, &ModeIdIndex
)))
903 SiS_SetReg(SiS_Pr
, SiS_Pr
->SiS_P3c4
, 0x05, 0x86);
905 SiSInitPCIetc(SiS_Pr
);
909 SiS_Pr
->SiS_ModeType
=
910 SiS_Pr
->SiS_EModeIDTable
[ModeIdIndex
].Ext_ModeFlag
& ModeTypeMask
;
912 SiS_Pr
->SiS_SetFlag
= LowModeTests
;
914 /* Set mode on CRT1 */
915 SiS_SetCRT1Group(SiS_Pr
, ModeNo
, ModeIdIndex
);
917 SiS_HandleCRT1(SiS_Pr
);
919 SiS_DisplayOn(SiS_Pr
);
920 SiS_SetRegByte(SiS_Pr
, SiS_Pr
->SiS_P3c6
, 0xFF);
922 /* Store mode number */
923 SiS_SetReg(SiS_Pr
, SiS_Pr
->SiS_P3d4
, 0x34, ModeNo
);
928 int SiSUSBSetVESAMode(struct SiS_Private
*SiS_Pr
, unsigned short VModeNo
)
930 unsigned short ModeNo
= 0;
933 SiSUSB_InitPtr(SiS_Pr
);
935 if (VModeNo
== 0x03) {
944 if (SiS_Pr
->SiS_EModeIDTable
[i
].Ext_VESAID
== VModeNo
) {
945 ModeNo
= SiS_Pr
->SiS_EModeIDTable
[i
].Ext_ModeID
;
949 } while (SiS_Pr
->SiS_EModeIDTable
[i
++].Ext_ModeID
!= 0xff);
956 return SiSUSBSetMode(SiS_Pr
, ModeNo
);
959 #endif /* INCL_SISUSB_CON */