0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040 #include <linux/module.h>
0041 #include <linux/kernel.h>
0042 #include <linux/errno.h>
0043 #include <linux/poll.h>
0044 #include <linux/spinlock.h>
0045
0046 #include "sisusb.h"
0047 #include "sisusb_init.h"
0048 #include "sisusb_tables.h"
0049
0050
0051
0052
0053
0054 static void SiSUSB_InitPtr(struct SiS_Private *SiS_Pr)
0055 {
0056 SiS_Pr->SiS_ModeResInfo = SiSUSB_ModeResInfo;
0057 SiS_Pr->SiS_StandTable = SiSUSB_StandTable;
0058
0059 SiS_Pr->SiS_SModeIDTable = SiSUSB_SModeIDTable;
0060 SiS_Pr->SiS_EModeIDTable = SiSUSB_EModeIDTable;
0061 SiS_Pr->SiS_RefIndex = SiSUSB_RefIndex;
0062 SiS_Pr->SiS_CRT1Table = SiSUSB_CRT1Table;
0063
0064 SiS_Pr->SiS_VCLKData = SiSUSB_VCLKData;
0065 }
0066
0067
0068
0069
0070
0071 static void
0072 SiS_SetReg(struct SiS_Private *SiS_Pr, unsigned long port,
0073 unsigned short index, unsigned short data)
0074 {
0075 sisusb_setidxreg(SiS_Pr->sisusb, port, index, data);
0076 }
0077
0078 static void
0079 SiS_SetRegByte(struct SiS_Private *SiS_Pr, unsigned long port,
0080 unsigned short data)
0081 {
0082 sisusb_setreg(SiS_Pr->sisusb, port, data);
0083 }
0084
0085 static unsigned char
0086 SiS_GetReg(struct SiS_Private *SiS_Pr, unsigned long port, unsigned short index)
0087 {
0088 u8 data;
0089
0090 sisusb_getidxreg(SiS_Pr->sisusb, port, index, &data);
0091
0092 return data;
0093 }
0094
0095 static unsigned char
0096 SiS_GetRegByte(struct SiS_Private *SiS_Pr, unsigned long port)
0097 {
0098 u8 data;
0099
0100 sisusb_getreg(SiS_Pr->sisusb, port, &data);
0101
0102 return data;
0103 }
0104
0105 static void
0106 SiS_SetRegANDOR(struct SiS_Private *SiS_Pr, unsigned long port,
0107 unsigned short index, unsigned short DataAND,
0108 unsigned short DataOR)
0109 {
0110 sisusb_setidxregandor(SiS_Pr->sisusb, port, index, DataAND, DataOR);
0111 }
0112
0113 static void
0114 SiS_SetRegAND(struct SiS_Private *SiS_Pr, unsigned long port,
0115 unsigned short index, unsigned short DataAND)
0116 {
0117 sisusb_setidxregand(SiS_Pr->sisusb, port, index, DataAND);
0118 }
0119
0120 static void
0121 SiS_SetRegOR(struct SiS_Private *SiS_Pr, unsigned long port,
0122 unsigned short index, unsigned short DataOR)
0123 {
0124 sisusb_setidxregor(SiS_Pr->sisusb, port, index, DataOR);
0125 }
0126
0127
0128
0129
0130
0131 static void SiS_DisplayOn(struct SiS_Private *SiS_Pr)
0132 {
0133 SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3c4, 0x01, 0xDF);
0134 }
0135
0136
0137
0138
0139
0140 static void SiSUSBRegInit(struct SiS_Private *SiS_Pr, unsigned long BaseAddr)
0141 {
0142 SiS_Pr->SiS_P3c4 = BaseAddr + 0x14;
0143 SiS_Pr->SiS_P3d4 = BaseAddr + 0x24;
0144 SiS_Pr->SiS_P3c0 = BaseAddr + 0x10;
0145 SiS_Pr->SiS_P3ce = BaseAddr + 0x1e;
0146 SiS_Pr->SiS_P3c2 = BaseAddr + 0x12;
0147 SiS_Pr->SiS_P3ca = BaseAddr + 0x1a;
0148 SiS_Pr->SiS_P3c6 = BaseAddr + 0x16;
0149 SiS_Pr->SiS_P3c7 = BaseAddr + 0x17;
0150 SiS_Pr->SiS_P3c8 = BaseAddr + 0x18;
0151 SiS_Pr->SiS_P3c9 = BaseAddr + 0x19;
0152 SiS_Pr->SiS_P3cb = BaseAddr + 0x1b;
0153 SiS_Pr->SiS_P3cc = BaseAddr + 0x1c;
0154 SiS_Pr->SiS_P3cd = BaseAddr + 0x1d;
0155 SiS_Pr->SiS_P3da = BaseAddr + 0x2a;
0156 SiS_Pr->SiS_Part1Port = BaseAddr + SIS_CRT2_PORT_04;
0157 }
0158
0159
0160
0161
0162
0163 static void SiS_GetSysFlags(struct SiS_Private *SiS_Pr)
0164 {
0165 SiS_Pr->SiS_MyCR63 = 0x63;
0166 }
0167
0168
0169
0170
0171
0172 static void SiSInitPCIetc(struct SiS_Private *SiS_Pr)
0173 {
0174 SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x20, 0xa1);
0175
0176
0177
0178
0179
0180
0181 SiS_SetRegOR(SiS_Pr, SiS_Pr->SiS_P3c4, 0x1E, 0xDA);
0182 }
0183
0184
0185
0186
0187
0188 static void SiS_SetSegRegLower(struct SiS_Private *SiS_Pr, unsigned short value)
0189 {
0190 unsigned short temp;
0191
0192 value &= 0x00ff;
0193 temp = SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3cb) & 0xf0;
0194 temp |= (value >> 4);
0195 SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3cb, temp);
0196 temp = SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3cd) & 0xf0;
0197 temp |= (value & 0x0f);
0198 SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3cd, temp);
0199 }
0200
0201 static void SiS_SetSegRegUpper(struct SiS_Private *SiS_Pr, unsigned short value)
0202 {
0203 unsigned short temp;
0204
0205 value &= 0x00ff;
0206 temp = SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3cb) & 0x0f;
0207 temp |= (value & 0xf0);
0208 SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3cb, temp);
0209 temp = SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3cd) & 0x0f;
0210 temp |= (value << 4);
0211 SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3cd, temp);
0212 }
0213
0214 static void SiS_SetSegmentReg(struct SiS_Private *SiS_Pr, unsigned short value)
0215 {
0216 SiS_SetSegRegLower(SiS_Pr, value);
0217 SiS_SetSegRegUpper(SiS_Pr, value);
0218 }
0219
0220 static void SiS_ResetSegmentReg(struct SiS_Private *SiS_Pr)
0221 {
0222 SiS_SetSegmentReg(SiS_Pr, 0);
0223 }
0224
0225 static void
0226 SiS_SetSegmentRegOver(struct SiS_Private *SiS_Pr, unsigned short value)
0227 {
0228 unsigned short temp = value >> 8;
0229
0230 temp &= 0x07;
0231 temp |= (temp << 4);
0232 SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x1d, temp);
0233 SiS_SetSegmentReg(SiS_Pr, value);
0234 }
0235
0236 static void SiS_ResetSegmentRegOver(struct SiS_Private *SiS_Pr)
0237 {
0238 SiS_SetSegmentRegOver(SiS_Pr, 0);
0239 }
0240
0241 static void SiS_ResetSegmentRegisters(struct SiS_Private *SiS_Pr)
0242 {
0243 SiS_ResetSegmentReg(SiS_Pr);
0244 SiS_ResetSegmentRegOver(SiS_Pr);
0245 }
0246
0247
0248
0249
0250
0251 static int
0252 SiS_SearchModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo,
0253 unsigned short *ModeIdIndex)
0254 {
0255 if ((*ModeNo) <= 0x13) {
0256
0257 if ((*ModeNo) != 0x03)
0258 return 0;
0259
0260 (*ModeIdIndex) = 0;
0261
0262 } else {
0263
0264 for (*ModeIdIndex = 0;; (*ModeIdIndex)++) {
0265
0266 if (SiS_Pr->SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID ==
0267 (*ModeNo))
0268 break;
0269
0270 if (SiS_Pr->SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID ==
0271 0xFF)
0272 return 0;
0273 }
0274
0275 }
0276
0277 return 1;
0278 }
0279
0280
0281
0282
0283
0284 static void SiS_HandleCRT1(struct SiS_Private *SiS_Pr)
0285 {
0286
0287 SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3d4, SiS_Pr->SiS_MyCR63, 0xbf);
0288 }
0289
0290
0291
0292
0293
0294 static unsigned short
0295 SiS_GetColorDepth(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
0296 unsigned short ModeIdIndex)
0297 {
0298 static const unsigned short ColorDepth[6] = { 1, 2, 4, 4, 6, 8 };
0299 unsigned short modeflag;
0300 short index;
0301
0302 if (ModeNo <= 0x13) {
0303 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
0304 } else {
0305 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
0306 }
0307
0308 index = (modeflag & ModeTypeMask) - ModeEGA;
0309 if (index < 0)
0310 index = 0;
0311 return ColorDepth[index];
0312 }
0313
0314
0315
0316
0317
0318 static unsigned short
0319 SiS_GetOffset(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
0320 unsigned short ModeIdIndex, unsigned short rrti)
0321 {
0322 unsigned short xres, temp, colordepth, infoflag;
0323
0324 infoflag = SiS_Pr->SiS_RefIndex[rrti].Ext_InfoFlag;
0325 xres = SiS_Pr->SiS_RefIndex[rrti].XRes;
0326
0327 colordepth = SiS_GetColorDepth(SiS_Pr, ModeNo, ModeIdIndex);
0328
0329 temp = xres / 16;
0330
0331 if (infoflag & InterlaceMode)
0332 temp <<= 1;
0333
0334 temp *= colordepth;
0335
0336 if (xres % 16)
0337 temp += (colordepth >> 1);
0338
0339 return temp;
0340 }
0341
0342
0343
0344
0345
0346 static void
0347 SiS_SetSeqRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex)
0348 {
0349 unsigned char SRdata;
0350 int i;
0351
0352 SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x00, 0x03);
0353
0354 SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[0] | 0x20;
0355 SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x01, SRdata);
0356
0357 for (i = 2; i <= 4; i++) {
0358 SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[i - 1];
0359 SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, i, SRdata);
0360 }
0361 }
0362
0363
0364
0365
0366
0367 static void
0368 SiS_SetMiscRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex)
0369 {
0370 unsigned char Miscdata = SiS_Pr->SiS_StandTable[StandTableIndex].MISC;
0371
0372 SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c2, Miscdata);
0373 }
0374
0375
0376
0377
0378
0379 static void
0380 SiS_SetCRTCRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex)
0381 {
0382 unsigned char CRTCdata;
0383 unsigned short i;
0384
0385 SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3d4, 0x11, 0x7f);
0386
0387 for (i = 0; i <= 0x18; i++) {
0388 CRTCdata = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[i];
0389 SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, i, CRTCdata);
0390 }
0391 }
0392
0393
0394
0395
0396
0397 static void
0398 SiS_SetATTRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex)
0399 {
0400 unsigned char ARdata;
0401 unsigned short i;
0402
0403 for (i = 0; i <= 0x13; i++) {
0404 ARdata = SiS_Pr->SiS_StandTable[StandTableIndex].ATTR[i];
0405 SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3da);
0406 SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c0, i);
0407 SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c0, ARdata);
0408 }
0409 SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3da);
0410 SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c0, 0x14);
0411 SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c0, 0x00);
0412
0413 SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3da);
0414 SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c0, 0x20);
0415 SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3da);
0416 }
0417
0418
0419
0420
0421
0422 static void
0423 SiS_SetGRCRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex)
0424 {
0425 unsigned char GRdata;
0426 unsigned short i;
0427
0428 for (i = 0; i <= 0x08; i++) {
0429 GRdata = SiS_Pr->SiS_StandTable[StandTableIndex].GRC[i];
0430 SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3ce, i, GRdata);
0431 }
0432
0433 if (SiS_Pr->SiS_ModeType > ModeVGA) {
0434
0435 SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3ce, 0x05, 0xBF);
0436 }
0437 }
0438
0439
0440
0441
0442
0443 static void SiS_ClearExt1Regs(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
0444 {
0445 int i;
0446
0447 for (i = 0x0A; i <= 0x0E; i++) {
0448 SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, i, 0x00);
0449 }
0450
0451 SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3c4, 0x37, 0xFE);
0452 }
0453
0454
0455
0456
0457
0458 static unsigned short
0459 SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
0460 unsigned short ModeIdIndex)
0461 {
0462 unsigned short rrti, i, index, temp;
0463
0464 if (ModeNo <= 0x13)
0465 return 0xFFFF;
0466
0467 index = SiS_GetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x33) & 0x0F;
0468 if (index > 0)
0469 index--;
0470
0471 rrti = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
0472 ModeNo = SiS_Pr->SiS_RefIndex[rrti].ModeID;
0473
0474 i = 0;
0475 do {
0476 if (SiS_Pr->SiS_RefIndex[rrti + i].ModeID != ModeNo)
0477 break;
0478
0479 temp =
0480 SiS_Pr->SiS_RefIndex[rrti + i].Ext_InfoFlag & ModeTypeMask;
0481 if (temp < SiS_Pr->SiS_ModeType)
0482 break;
0483
0484 i++;
0485 index--;
0486 } while (index != 0xFFFF);
0487
0488 i--;
0489
0490 return (rrti + i);
0491 }
0492
0493
0494
0495
0496
0497 static void SiS_SetCRT1Sync(struct SiS_Private *SiS_Pr, unsigned short rrti)
0498 {
0499 unsigned short sync = SiS_Pr->SiS_RefIndex[rrti].Ext_InfoFlag >> 8;
0500 sync &= 0xC0;
0501 sync |= 0x2f;
0502 SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c2, sync);
0503 }
0504
0505
0506
0507
0508
0509 static void
0510 SiS_SetCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
0511 unsigned short ModeIdIndex, unsigned short rrti)
0512 {
0513 unsigned char index;
0514 unsigned short temp, i, j, modeflag;
0515
0516 SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3d4, 0x11, 0x7f);
0517
0518 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
0519
0520 index = SiS_Pr->SiS_RefIndex[rrti].Ext_CRT1CRTC;
0521
0522 for (i = 0, j = 0; i <= 7; i++, j++) {
0523 SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, j,
0524 SiS_Pr->SiS_CRT1Table[index].CR[i]);
0525 }
0526 for (j = 0x10; i <= 10; i++, j++) {
0527 SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, j,
0528 SiS_Pr->SiS_CRT1Table[index].CR[i]);
0529 }
0530 for (j = 0x15; i <= 12; i++, j++) {
0531 SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, j,
0532 SiS_Pr->SiS_CRT1Table[index].CR[i]);
0533 }
0534 for (j = 0x0A; i <= 15; i++, j++) {
0535 SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, j,
0536 SiS_Pr->SiS_CRT1Table[index].CR[i]);
0537 }
0538
0539 temp = SiS_Pr->SiS_CRT1Table[index].CR[16] & 0xE0;
0540 SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x0E, temp);
0541
0542 temp = ((SiS_Pr->SiS_CRT1Table[index].CR[16]) & 0x01) << 5;
0543 if (modeflag & DoubleScanMode)
0544 temp |= 0x80;
0545 SiS_SetRegANDOR(SiS_Pr, SiS_Pr->SiS_P3d4, 0x09, 0x5F, temp);
0546
0547 if (SiS_Pr->SiS_ModeType > ModeVGA)
0548 SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x14, 0x4F);
0549 }
0550
0551
0552
0553
0554
0555
0556
0557 static void
0558 SiS_SetCRT1Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
0559 unsigned short ModeIdIndex, unsigned short rrti)
0560 {
0561 unsigned short du = SiS_GetOffset(SiS_Pr, ModeNo, ModeIdIndex, rrti);
0562 unsigned short infoflag = SiS_Pr->SiS_RefIndex[rrti].Ext_InfoFlag;
0563 unsigned short temp;
0564
0565 temp = (du >> 8) & 0x0f;
0566 SiS_SetRegANDOR(SiS_Pr, SiS_Pr->SiS_P3c4, 0x0E, 0xF0, temp);
0567
0568 SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x13, (du & 0xFF));
0569
0570 if (infoflag & InterlaceMode)
0571 du >>= 1;
0572
0573 du <<= 5;
0574 temp = (du >> 8) & 0xff;
0575 if (du & 0xff)
0576 temp++;
0577 temp++;
0578 SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x10, temp);
0579 }
0580
0581
0582
0583
0584
0585 static void
0586 SiS_SetCRT1VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
0587 unsigned short rrti)
0588 {
0589 unsigned short index = SiS_Pr->SiS_RefIndex[rrti].Ext_CRTVCLK;
0590 unsigned short clka = SiS_Pr->SiS_VCLKData[index].SR2B;
0591 unsigned short clkb = SiS_Pr->SiS_VCLKData[index].SR2C;
0592
0593 SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3c4, 0x31, 0xCF);
0594
0595 SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x2B, clka);
0596 SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x2C, clkb);
0597 SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x2D, 0x01);
0598 }
0599
0600
0601
0602
0603
0604 static void
0605 SiS_SetCRT1FIFO_310(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
0606 unsigned short mi)
0607 {
0608 unsigned short modeflag = SiS_Pr->SiS_EModeIDTable[mi].Ext_ModeFlag;
0609
0610
0611 SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3c4, 0x3D, 0xFE);
0612
0613 SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x08, 0xAE);
0614 SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3c4, 0x09, 0xF0);
0615
0616 if (ModeNo <= 0x13)
0617 return;
0618
0619 if ((!(modeflag & DoubleScanMode)) || (!(modeflag & HalfDCLK))) {
0620 SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x08, 0x34);
0621 SiS_SetRegOR(SiS_Pr, SiS_Pr->SiS_P3c4, 0x3D, 0x01);
0622 }
0623 }
0624
0625
0626
0627
0628
0629 static void
0630 SiS_SetVCLKState(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
0631 unsigned short rrti)
0632 {
0633 unsigned short data = 0, VCLK = 0, index = 0;
0634
0635 if (ModeNo > 0x13) {
0636 index = SiS_Pr->SiS_RefIndex[rrti].Ext_CRTVCLK;
0637 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
0638 }
0639
0640 if (VCLK >= 166)
0641 data |= 0x0c;
0642 SiS_SetRegANDOR(SiS_Pr, SiS_Pr->SiS_P3c4, 0x32, 0xf3, data);
0643
0644 if (VCLK >= 166)
0645 SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3c4, 0x1f, 0xe7);
0646
0647
0648 data = 0x03;
0649 if (VCLK >= 260)
0650 data = 0x00;
0651 else if (VCLK >= 160)
0652 data = 0x01;
0653 else if (VCLK >= 135)
0654 data = 0x02;
0655
0656 SiS_SetRegANDOR(SiS_Pr, SiS_Pr->SiS_P3c4, 0x07, 0xF8, data);
0657 }
0658
0659 static void
0660 SiS_SetCRT1ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
0661 unsigned short ModeIdIndex, unsigned short rrti)
0662 {
0663 unsigned short data, infoflag = 0, modeflag;
0664
0665 if (ModeNo <= 0x13)
0666 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
0667 else {
0668 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
0669 infoflag = SiS_Pr->SiS_RefIndex[rrti].Ext_InfoFlag;
0670 }
0671
0672
0673 SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3c4, 0x1F, 0x3F);
0674
0675 data = 0;
0676 if (ModeNo > 0x13) {
0677 if (SiS_Pr->SiS_ModeType > ModeEGA) {
0678 data |= 0x02;
0679 data |= ((SiS_Pr->SiS_ModeType - ModeVGA) << 2);
0680 }
0681 if (infoflag & InterlaceMode)
0682 data |= 0x20;
0683 }
0684 SiS_SetRegANDOR(SiS_Pr, SiS_Pr->SiS_P3c4, 0x06, 0xC0, data);
0685
0686 data = 0;
0687 if (infoflag & InterlaceMode) {
0688
0689 unsigned short hrs =
0690 (SiS_GetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x04) |
0691 ((SiS_GetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x0b) & 0xc0) << 2))
0692 - 3;
0693 unsigned short hto =
0694 (SiS_GetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x00) |
0695 ((SiS_GetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x0b) & 0x03) << 8))
0696 + 5;
0697 data = hrs - (hto >> 1) + 3;
0698 }
0699 SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x19, (data & 0xFF));
0700 SiS_SetRegANDOR(SiS_Pr, SiS_Pr->SiS_P3d4, 0x1a, 0xFC, (data >> 8));
0701
0702 if (modeflag & HalfDCLK)
0703 SiS_SetRegOR(SiS_Pr, SiS_Pr->SiS_P3c4, 0x01, 0x08);
0704
0705 data = 0;
0706 if (modeflag & LineCompareOff)
0707 data = 0x08;
0708 SiS_SetRegANDOR(SiS_Pr, SiS_Pr->SiS_P3c4, 0x0F, 0xB7, data);
0709
0710 if ((SiS_Pr->SiS_ModeType == ModeEGA) && (ModeNo > 0x13))
0711 SiS_SetRegOR(SiS_Pr, SiS_Pr->SiS_P3c4, 0x0F, 0x40);
0712
0713 SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3c4, 0x31, 0xfb);
0714
0715 data = 0x60;
0716 if (SiS_Pr->SiS_ModeType != ModeText) {
0717 data ^= 0x60;
0718 if (SiS_Pr->SiS_ModeType != ModeEGA)
0719 data ^= 0xA0;
0720 }
0721 SiS_SetRegANDOR(SiS_Pr, SiS_Pr->SiS_P3c4, 0x21, 0x1F, data);
0722
0723 SiS_SetVCLKState(SiS_Pr, ModeNo, rrti);
0724
0725 if (SiS_GetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x31) & 0x40)
0726 SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x52, 0x2c);
0727 else
0728 SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x52, 0x6c);
0729 }
0730
0731
0732
0733
0734
0735 static void
0736 SiS_WriteDAC(struct SiS_Private *SiS_Pr, unsigned long DACData,
0737 unsigned short shiftflag, unsigned short dl, unsigned short ah,
0738 unsigned short al, unsigned short dh)
0739 {
0740 unsigned short d1, d2, d3;
0741
0742 switch (dl) {
0743 case 0:
0744 d1 = dh;
0745 d2 = ah;
0746 d3 = al;
0747 break;
0748 case 1:
0749 d1 = ah;
0750 d2 = al;
0751 d3 = dh;
0752 break;
0753 default:
0754 d1 = al;
0755 d2 = dh;
0756 d3 = ah;
0757 }
0758 SiS_SetRegByte(SiS_Pr, DACData, (d1 << shiftflag));
0759 SiS_SetRegByte(SiS_Pr, DACData, (d2 << shiftflag));
0760 SiS_SetRegByte(SiS_Pr, DACData, (d3 << shiftflag));
0761 }
0762
0763 static void
0764 SiS_LoadDAC(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
0765 unsigned short mi)
0766 {
0767 unsigned short data, data2, time, i, j, k, m, n, o;
0768 unsigned short si, di, bx, sf;
0769 unsigned long DACAddr, DACData;
0770 const unsigned char *table = NULL;
0771
0772 if (ModeNo < 0x13)
0773 data = SiS_Pr->SiS_SModeIDTable[mi].St_ModeFlag;
0774 else
0775 data = SiS_Pr->SiS_EModeIDTable[mi].Ext_ModeFlag;
0776
0777 data &= DACInfoFlag;
0778
0779 j = time = 64;
0780 if (data == 0x00)
0781 table = SiS_MDA_DAC;
0782 else if (data == 0x08)
0783 table = SiS_CGA_DAC;
0784 else if (data == 0x10)
0785 table = SiS_EGA_DAC;
0786 else {
0787 j = 16;
0788 time = 256;
0789 table = SiS_VGA_DAC;
0790 }
0791
0792 DACAddr = SiS_Pr->SiS_P3c8;
0793 DACData = SiS_Pr->SiS_P3c9;
0794 sf = 0;
0795 SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c6, 0xFF);
0796
0797 SiS_SetRegByte(SiS_Pr, DACAddr, 0x00);
0798
0799 for (i = 0; i < j; i++) {
0800 data = table[i];
0801 for (k = 0; k < 3; k++) {
0802 data2 = 0;
0803 if (data & 0x01)
0804 data2 += 0x2A;
0805 if (data & 0x02)
0806 data2 += 0x15;
0807 SiS_SetRegByte(SiS_Pr, DACData, (data2 << sf));
0808 data >>= 2;
0809 }
0810 }
0811
0812 if (time == 256) {
0813 for (i = 16; i < 32; i++) {
0814 data = table[i] << sf;
0815 for (k = 0; k < 3; k++)
0816 SiS_SetRegByte(SiS_Pr, DACData, data);
0817 }
0818 si = 32;
0819 for (m = 0; m < 9; m++) {
0820 di = si;
0821 bx = si + 4;
0822 for (n = 0; n < 3; n++) {
0823 for (o = 0; o < 5; o++) {
0824 SiS_WriteDAC(SiS_Pr, DACData, sf, n,
0825 table[di], table[bx],
0826 table[si]);
0827 si++;
0828 }
0829 si -= 2;
0830 for (o = 0; o < 3; o++) {
0831 SiS_WriteDAC(SiS_Pr, DACData, sf, n,
0832 table[di], table[si],
0833 table[bx]);
0834 si--;
0835 }
0836 }
0837 si += 5;
0838 }
0839 }
0840 }
0841
0842
0843
0844
0845
0846 static void
0847 SiS_SetCRT1Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
0848 unsigned short ModeIdIndex)
0849 {
0850 unsigned short StandTableIndex, rrti;
0851
0852 SiS_Pr->SiS_CRT1Mode = ModeNo;
0853
0854 if (ModeNo <= 0x13)
0855 StandTableIndex = 0;
0856 else
0857 StandTableIndex = 1;
0858
0859 SiS_ResetSegmentRegisters(SiS_Pr);
0860 SiS_SetSeqRegs(SiS_Pr, StandTableIndex);
0861 SiS_SetMiscRegs(SiS_Pr, StandTableIndex);
0862 SiS_SetCRTCRegs(SiS_Pr, StandTableIndex);
0863 SiS_SetATTRegs(SiS_Pr, StandTableIndex);
0864 SiS_SetGRCRegs(SiS_Pr, StandTableIndex);
0865 SiS_ClearExt1Regs(SiS_Pr, ModeNo);
0866
0867 rrti = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex);
0868
0869 if (rrti != 0xFFFF) {
0870 SiS_SetCRT1Sync(SiS_Pr, rrti);
0871 SiS_SetCRT1CRTC(SiS_Pr, ModeNo, ModeIdIndex, rrti);
0872 SiS_SetCRT1Offset(SiS_Pr, ModeNo, ModeIdIndex, rrti);
0873 SiS_SetCRT1VCLK(SiS_Pr, ModeNo, rrti);
0874 }
0875
0876 SiS_SetCRT1FIFO_310(SiS_Pr, ModeNo, ModeIdIndex);
0877
0878 SiS_SetCRT1ModeRegs(SiS_Pr, ModeNo, ModeIdIndex, rrti);
0879
0880 SiS_LoadDAC(SiS_Pr, ModeNo, ModeIdIndex);
0881
0882 SiS_DisplayOn(SiS_Pr);
0883 }
0884
0885
0886
0887
0888
0889 int SiSUSBSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
0890 {
0891 unsigned short ModeIdIndex;
0892 unsigned long BaseAddr = SiS_Pr->IOAddress;
0893
0894 SiSUSB_InitPtr(SiS_Pr);
0895 SiSUSBRegInit(SiS_Pr, BaseAddr);
0896 SiS_GetSysFlags(SiS_Pr);
0897
0898 if (!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex)))
0899 return 0;
0900
0901 SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x05, 0x86);
0902
0903 SiSInitPCIetc(SiS_Pr);
0904
0905 ModeNo &= 0x7f;
0906
0907 SiS_Pr->SiS_ModeType =
0908 SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag & ModeTypeMask;
0909
0910 SiS_Pr->SiS_SetFlag = LowModeTests;
0911
0912
0913 SiS_SetCRT1Group(SiS_Pr, ModeNo, ModeIdIndex);
0914
0915 SiS_HandleCRT1(SiS_Pr);
0916
0917 SiS_DisplayOn(SiS_Pr);
0918 SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c6, 0xFF);
0919
0920
0921 SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x34, ModeNo);
0922
0923 return 1;
0924 }
0925
0926 int SiSUSBSetVESAMode(struct SiS_Private *SiS_Pr, unsigned short VModeNo)
0927 {
0928 unsigned short ModeNo = 0;
0929 int i;
0930
0931 SiSUSB_InitPtr(SiS_Pr);
0932
0933 if (VModeNo == 0x03) {
0934
0935 ModeNo = 0x03;
0936
0937 } else {
0938
0939 i = 0;
0940 do {
0941
0942 if (SiS_Pr->SiS_EModeIDTable[i].Ext_VESAID == VModeNo) {
0943 ModeNo = SiS_Pr->SiS_EModeIDTable[i].Ext_ModeID;
0944 break;
0945 }
0946
0947 } while (SiS_Pr->SiS_EModeIDTable[i++].Ext_ModeID != 0xff);
0948
0949 }
0950
0951 if (!ModeNo)
0952 return 0;
0953
0954 return SiSUSBSetMode(SiS_Pr, ModeNo);
0955 }