| Start/ | End/ | |||
| True | False | - | Line | Source |
| 1 | /* | |||
| 2 | * sisusb - usb kernel driver for SiS315(E) based USB2VGA dongles | |||
| 3 | * | |||
| 4 | * Display mode initializing code | |||
| 5 | * | |||
| 6 | * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria | |||
| 7 | * | |||
| 8 | * If distributed as part of the Linux kernel, this code is licensed under the | |||
| 9 | * terms of the GPL v2. | |||
| 10 | * | |||
| 11 | * Otherwise, the following license terms apply: | |||
| 12 | * | |||
| 13 | * * Redistribution and use in source and binary forms, with or without | |||
| 14 | * * modification, are permitted provided that the following conditions | |||
| 15 | * * are met: | |||
| 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. | |||
| 23 | * * | |||
| 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. | |||
| 34 | * | |||
| 35 | * Author: Thomas Winischhofer <thomas@winischhofer.net> | |||
| 36 | * | |||
| 37 | */ | |||
| 38 | ||||
| 39 | #include <linux/config.h> | |||
| 40 | #include <linux/module.h> | |||
| 41 | #include <linux/kernel.h> | |||
| 42 | #include <linux/errno.h> | |||
| 43 | #include <linux/poll.h> | |||
| 44 | #include <linux/init.h> | |||
| 45 | #include <linux/slab.h> | |||
| 46 | #include <linux/spinlock.h> | |||
| 47 | #include <linux/kref.h> | |||
| 48 | ||||
| 49 | #include "sisusb.h" | |||
| 50 | ||||
| 51 | #ifdef INCL_SISUSB_CON | |||
| 52 | ||||
| 53 | #include "sisusb_init.h" | |||
| 54 | ||||
| 55 | /*********************************************/ | |||
| 56 | /* POINTER INITIALIZATION */ | |||
| 57 | /*********************************************/ | |||
| 58 | ||||
| 59 | static void | |||
| 60 | SiSUSB_InitPtr(struct SiS_Private *SiS_Pr) | |||
| 61 | { | |||
| 62 | SiS_Pr->SiS_ModeResInfo = SiSUSB_ModeResInfo; | |||
| 63 | SiS_Pr->SiS_StandTable = SiSUSB_StandTable; | |||
| 64 | ||||
| 65 | SiS_Pr->SiS_SModeIDTable = SiSUSB_SModeIDTable; | |||
| 66 | SiS_Pr->SiS_EModeIDTable = SiSUSB_EModeIDTable; | |||
| 67 | SiS_Pr->SiS_RefIndex = SiSUSB_RefIndex; | |||
| 68 | SiS_Pr->SiS_CRT1Table = SiSUSB_CRT1Table; | |||
| 69 | ||||
| 70 | SiS_Pr->SiS_VCLKData = SiSUSB_VCLKData; | |||
| 71 | } | |||
| 72 | ||||
| 73 | /*********************************************/ | |||
| 74 | /* HELPER: Get ModeID */ | |||
| 75 | /*********************************************/ | |||
| 76 | ||||
| 77 | unsigned short | |||
| 78 | SiSUSB_GetModeID(int HDisplay, int VDisplay, int Depth) | |||
| 79 | { | |||
| 80 | unsigned short ModeIndex = 0; | |||
| 81 | ||||
| 82 | switch (HDisplay) | |||
| 83 | { | |||
| 84 | case 320: | |||
| 85 | if (VDisplay == 200) | |||
| 86 | ModeIndex = ModeIndex_320x200[Depth]; | |||
| 87 | else if (VDisplay == 240) | |||
| 88 | ModeIndex = ModeIndex_320x240[Depth]; | |||
| 89 | break; | |||
| 90 | case 400: | |||
| 91 | if (VDisplay == 300) | |||
| 92 | ModeIndex = ModeIndex_400x300[Depth]; | |||
| 93 | break; | |||
| 94 | case 512: | |||
| 95 | if (VDisplay == 384) | |||
| 96 | ModeIndex = ModeIndex_512x384[Depth]; | |||
| 97 | break; | |||
| 98 | case 640: | |||
| 99 | if (VDisplay == 480) | |||
| 100 | ModeIndex = ModeIndex_640x480[Depth]; | |||
| 101 | else if (VDisplay == 400) | |||
| 102 | ModeIndex = ModeIndex_640x400[Depth]; | |||
| 103 | break; | |||
| 104 | case 720: | |||
| 105 | if (VDisplay == 480) | |||
| 106 | ModeIndex = ModeIndex_720x480[Depth]; | |||
| 107 | else if (VDisplay == 576) | |||
| 108 | ModeIndex = ModeIndex_720x576[Depth]; | |||
| 109 | break; | |||
| 110 | case 768: | |||
| 111 | if (VDisplay == 576) | |||
| 112 | ModeIndex = ModeIndex_768x576[Depth]; | |||
| 113 | break; | |||
| 114 | case 800: | |||
| 115 | if (VDisplay == 600) | |||
| 116 | ModeIndex = ModeIndex_800x600[Depth]; | |||
| 117 | else if (VDisplay == 480) | |||
| 118 | ModeIndex = ModeIndex_800x480[Depth]; | |||
| 119 | break; | |||
| 120 | case 848: | |||
| 121 | if (VDisplay == 480) | |||
| 122 | ModeIndex = ModeIndex_848x480[Depth]; | |||
| 123 | break; | |||
| 124 | case 856: | |||
| 125 | if (VDisplay == 480) | |||
| 126 | ModeIndex = ModeIndex_856x480[Depth]; | |||
| 127 | break; | |||
| 128 | case 960: | |||
| 129 | if (VDisplay == 540) | |||
| 130 | ModeIndex = ModeIndex_960x540[Depth]; | |||
| 131 | else if (VDisplay == 600) | |||
| 132 | ModeIndex = ModeIndex_960x600[Depth]; | |||
| 133 | break; | |||
| 134 | case 1024: | |||
| 135 | if (VDisplay == 576) | |||
| 136 | ModeIndex = ModeIndex_1024x576[Depth]; | |||
| 137 | else if (VDisplay == 768) | |||
| 138 | ModeIndex = ModeIndex_1024x768[Depth]; | |||
| 139 | break; | |||
| 140 | case 1152: | |||
| 141 | if (VDisplay == 864) | |||
| 142 | ModeIndex = ModeIndex_1152x864[Depth]; | |||
| 143 | break; | |||
| 144 | case 1280: | |||
| 145 | switch (VDisplay) { | |||
| 146 | case 720: | |||
| 147 | ModeIndex = ModeIndex_1280x720[Depth]; | |||
| 148 | break; | |||
| 149 | case 768: | |||
| 150 | ModeIndex = ModeIndex_1280x768[Depth]; | |||
| 151 | break; | |||
| 152 | case 1024: | |||
| 153 | ModeIndex = ModeIndex_1280x1024[Depth]; | |||
| 154 | break; | |||
| 155 | } | |||
| 156 | } | |||
| 157 | ||||
| 158 | return ModeIndex; | |||
| 159 | } | |||
| 160 | ||||
| 161 | /*********************************************/ | |||
| 162 | /* HELPER: SetReg, GetReg */ | |||
| 163 | /*********************************************/ | |||
| 164 | ||||
| 165 | static void | |||
| 166 | SiS_SetReg(struct SiS_Private *SiS_Pr, unsigned long port, | |||
| 167 | unsigned short index, unsigned short data) | |||
| 168 | { | |||
| 169 | sisusb_setidxreg(SiS_Pr->sisusb, port, index, data); | |||
| 170 | } | |||
| 171 | ||||
| 172 | static void | |||
| 173 | SiS_SetRegByte(struct SiS_Private *SiS_Pr, unsigned long port, | |||
| 174 | unsigned short data) | |||
| 175 | { | |||
| 176 | sisusb_setreg(SiS_Pr->sisusb, port, data); | |||
| 177 | } | |||
| 178 | ||||
| 179 | static unsigned char | |||
| 180 | SiS_GetReg(struct SiS_Private *SiS_Pr, unsigned long port, | |||
| 181 | unsigned short index) | |||
| 182 | { | |||
| 183 | u8 data; | |||
| 184 | ||||
| 185 | sisusb_getidxreg(SiS_Pr->sisusb, port, index, &data); | |||
| 186 | ||||
| 187 | return data; | |||
| 188 | } | |||
| 189 | ||||
| 190 | static unsigned char | |||
| 191 | SiS_GetRegByte(struct SiS_Private *SiS_Pr, unsigned long port) | |||
| 192 | { | |||
| 193 | u8 data; | |||
| 194 | ||||
| 195 | sisusb_getreg(SiS_Pr->sisusb, port, &data); | |||
| 196 | ||||
| 197 | return data; | |||
| 198 | } | |||
| 199 | ||||
| 200 | static void | |||
| 201 | SiS_SetRegANDOR(struct SiS_Private *SiS_Pr, unsigned long port, | |||
| 202 | unsigned short index, unsigned short DataAND, | |||
| 203 | unsigned short DataOR) | |||
| 204 | { | |||
| 205 | sisusb_setidxregandor(SiS_Pr->sisusb, port, index, DataAND, DataOR); | |||
| 206 | } | |||
| 207 | ||||
| 208 | static void | |||
| 209 | SiS_SetRegAND(struct SiS_Private *SiS_Pr, unsigned long port, | |||
| 210 | unsigned short index, unsigned short DataAND) | |||
| 211 | { | |||
| 212 | sisusb_setidxregand(SiS_Pr->sisusb, port, index, DataAND); | |||
| 213 | } | |||
| 214 | ||||
| 215 | static void | |||
| 216 | SiS_SetRegOR(struct SiS_Private *SiS_Pr,unsigned long port, | |||
| 217 | unsigned short index, unsigned short DataOR) | |||
| 218 | { | |||
| 219 | sisusb_setidxregor(SiS_Pr->sisusb, port, index, DataOR); | |||
| 220 | } | |||
| 221 | ||||
| 222 | /*********************************************/ | |||
| 223 | /* HELPER: DisplayOn, DisplayOff */ | |||
| 224 | /*********************************************/ | |||
| 225 | ||||
| 226 | static void | |||
| 227 | SiS_DisplayOn(struct SiS_Private *SiS_Pr) | |||
| 228 | { | |||
| 229 | SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3c4, 0x01, 0xDF); | |||
| 230 | } | |||
| 231 | ||||
| 232 | /*********************************************/ | |||
| 233 | /* HELPER: Init Port Addresses */ | |||
| 234 | /*********************************************/ | |||
| 235 | ||||
| 236 | void | |||
| 237 | SiSUSBRegInit(struct SiS_Private *SiS_Pr, unsigned long BaseAddr) | |||
| 238 | { | |||
| 239 | SiS_Pr->SiS_P3c4 = BaseAddr + 0x14; | |||
| 240 | SiS_Pr->SiS_P3d4 = BaseAddr + 0x24; | |||
| 241 | SiS_Pr->SiS_P3c0 = BaseAddr + 0x10; | |||
| 242 | SiS_Pr->SiS_P3ce = BaseAddr + 0x1e; | |||
| 243 | SiS_Pr->SiS_P3c2 = BaseAddr + 0x12; | |||
| 244 | SiS_Pr->SiS_P3ca = BaseAddr + 0x1a; | |||
| 245 | SiS_Pr->SiS_P3c6 = BaseAddr + 0x16; | |||
| 246 | SiS_Pr->SiS_P3c7 = BaseAddr + 0x17; | |||
| 247 | SiS_Pr->SiS_P3c8 = BaseAddr + 0x18; | |||
| 248 | SiS_Pr->SiS_P3c9 = BaseAddr + 0x19; | |||
| 249 | SiS_Pr->SiS_P3cb = BaseAddr + 0x1b; | |||
| 250 | SiS_Pr->SiS_P3cc = BaseAddr + 0x1c; | |||
| 251 | SiS_Pr->SiS_P3cd = BaseAddr + 0x1d; | |||
| 252 | SiS_Pr->SiS_P3da = BaseAddr + 0x2a; | |||
| 253 | SiS_Pr->SiS_Part1Port = BaseAddr + SIS_CRT2_PORT_04; | |||
| 254 | } | |||
| 255 | ||||
| 256 | /*********************************************/ | |||
| 257 | /* HELPER: GetSysFlags */ | |||
| 258 | /*********************************************/ | |||
| 259 | ||||
| 260 | static void | |||
| 261 | SiS_GetSysFlags(struct SiS_Private *SiS_Pr) | |||
| 262 | { | |||
| 263 | SiS_Pr->SiS_MyCR63 = 0x63; | |||
| 264 | } | |||
| 265 | ||||
| 266 | /*********************************************/ | |||
| 267 | /* HELPER: Init PCI & Engines */ | |||
| 268 | /*********************************************/ | |||
| 269 | ||||
| 270 | static void | |||
| 271 | SiSInitPCIetc(struct SiS_Private *SiS_Pr) | |||
| 272 | { | |||
| 273 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x20, 0xa1); | |||
| 274 | /* - Enable 2D (0x40) | |||
| 275 | * - Enable 3D (0x02) | |||
| 276 | * - Enable 3D vertex command fetch (0x10) | |||
| 277 | * - Enable 3D command parser (0x08) | |||
| 278 | * - Enable 3D G/L transformation engine (0x80) | |||
| 279 | */ | |||
| 280 | SiS_SetRegOR(SiS_Pr, SiS_Pr->SiS_P3c4, 0x1E, 0xDA); | |||
| 281 | } | |||
| 282 | ||||
| 283 | /*********************************************/ | |||
| 284 | /* HELPER: SET SEGMENT REGISTERS */ | |||
| 285 | /*********************************************/ | |||
| 286 | ||||
| 287 | static void | |||
| 288 | SiS_SetSegRegLower(struct SiS_Private *SiS_Pr, unsigned short value) | |||
| 289 | { | |||
| 290 | unsigned short temp; | |||
| 291 | ||||
| 292 | value &= 0x00ff; | |||
| 293 | temp = SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3cb) & 0xf0; | |||
| 294 | temp |= (value >> 4); | |||
| 295 | SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3cb, temp); | |||
| 296 | temp = SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3cd) & 0xf0; | |||
| 297 | temp |= (value & 0x0f); | |||
| 298 | SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3cd, temp); | |||
| 299 | } | |||
| 300 | ||||
| 301 | static void | |||
| 302 | SiS_SetSegRegUpper(struct SiS_Private *SiS_Pr, unsigned short value) | |||
| 303 | { | |||
| 304 | unsigned short temp; | |||
| 305 | ||||
| 306 | value &= 0x00ff; | |||
| 307 | temp = SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3cb) & 0x0f; | |||
| 308 | temp |= (value & 0xf0); | |||
| 309 | SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3cb, temp); | |||
| 310 | temp = SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3cd) & 0x0f; | |||
| 311 | temp |= (value << 4); | |||
| 312 | SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3cd, temp); | |||
| 313 | } | |||
| 314 | ||||
| 315 | static void | |||
| 316 | SiS_SetSegmentReg(struct SiS_Private *SiS_Pr, unsigned short value) | |||
| 317 | { | |||
| 318 | SiS_SetSegRegLower(SiS_Pr, value); | |||
| 319 | SiS_SetSegRegUpper(SiS_Pr, value); | |||
| 320 | } | |||
| 321 | ||||
| 322 | static void | |||
| 323 | SiS_ResetSegmentReg(struct SiS_Private *SiS_Pr) | |||
| 324 | { | |||
| 325 | SiS_SetSegmentReg(SiS_Pr, 0); | |||
| 326 | } | |||
| 327 | ||||
| 328 | static void | |||
| 329 | SiS_SetSegmentRegOver(struct SiS_Private *SiS_Pr, unsigned short value) | |||
| 330 | { | |||
| 331 | unsigned short temp = value >> 8; | |||
| 332 | ||||
| 333 | temp &= 0x07; | |||
| 334 | temp |= (temp << 4); | |||
| 335 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x1d, temp); | |||
| 336 | SiS_SetSegmentReg(SiS_Pr, value); | |||
| 337 | } | |||
| 338 | ||||
| 339 | static void | |||
| 340 | SiS_ResetSegmentRegOver(struct SiS_Private *SiS_Pr) | |||
| 341 | { | |||
| 342 | SiS_SetSegmentRegOver(SiS_Pr, 0); | |||
| 343 | } | |||
| 344 | ||||
| 345 | static void | |||
| 346 | SiS_ResetSegmentRegisters(struct SiS_Private *SiS_Pr) | |||
| 347 | { | |||
| 348 | SiS_ResetSegmentReg(SiS_Pr); | |||
| 349 | SiS_ResetSegmentRegOver(SiS_Pr); | |||
| 350 | } | |||
| 351 | ||||
| 352 | /*********************************************/ | |||
| 353 | /* HELPER: SearchModeID */ | |||
| 354 | /*********************************************/ | |||
| 355 | ||||
| 356 | static int | |||
| 357 | SiS_SearchModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo, | |||
| 358 | unsigned short *ModeIdIndex) | |||
| 359 | { | |||
| 360 | if ((*ModeNo) <= 0x13) { | |||
| 361 | ||||
| 362 | if ((*ModeNo) != 0x03) | |||
| 363 | return 0; | |||
| 364 | ||||
| 365 | (*ModeIdIndex) = 0; | |||
| 366 | ||||
| 367 | } else { | |||
| 368 | ||||
| 369 | for(*ModeIdIndex = 0; ;(*ModeIdIndex)++) { | |||
| 370 | ||||
| 371 | if (SiS_Pr->SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == (*ModeNo)) | |||
| 372 | break; | |||
| 373 | ||||
| 374 | if (SiS_Pr->SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF) | |||
| 375 | return 0; | |||
| 376 | } | |||
| 377 | ||||
| 378 | } | |||
| 379 | ||||
| 380 | return 1; | |||
| 381 | } | |||
| 382 | ||||
| 383 | /*********************************************/ | |||
| 384 | /* HELPER: ENABLE CRT1 */ | |||
| 385 | /*********************************************/ | |||
| 386 | ||||
| 387 | static void | |||
| 388 | SiS_HandleCRT1(struct SiS_Private *SiS_Pr) | |||
| 389 | { | |||
| 390 | /* Enable CRT1 gating */ | |||
| 391 | SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3d4, SiS_Pr->SiS_MyCR63, 0xbf); | |||
| 392 | } | |||
| 393 | ||||
| 394 | /*********************************************/ | |||
| 395 | /* HELPER: GetColorDepth */ | |||
| 396 | /*********************************************/ | |||
| 397 | ||||
| 398 | static unsigned short | |||
| 399 | SiS_GetColorDepth(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
| 400 | unsigned short ModeIdIndex) | |||
| 401 | { | |||
| 402 | static const unsigned short ColorDepth[6] = { 1, 2, 4, 4, 6, 8}; | |||
| 403 | unsigned short modeflag; | |||
| 404 | short index; | |||
| 405 | ||||
| 406 | if (ModeNo <= 0x13) { | |||
| 407 | modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; | |||
| 408 | } else { | |||
| 409 | modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; | |||
| 410 | } | |||
| 411 | ||||
| 412 | index = (modeflag & ModeTypeMask) - ModeEGA; | |||
| 413 | if (index < 0) index = 0; | |||
| 414 | return ColorDepth[index]; | |||
| 415 | } | |||
| 416 | ||||
| 417 | /*********************************************/ | |||
| 418 | /* HELPER: GetOffset */ | |||
| 419 | /*********************************************/ | |||
| 420 | ||||
| 421 | static unsigned short | |||
| 422 | SiS_GetOffset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
| 423 | unsigned short ModeIdIndex, unsigned short rrti) | |||
| 424 | { | |||
| 425 | unsigned short xres, temp, colordepth, infoflag; | |||
| 426 | ||||
| 427 | infoflag = SiS_Pr->SiS_RefIndex[rrti].Ext_InfoFlag; | |||
| 428 | xres = SiS_Pr->SiS_RefIndex[rrti].XRes; | |||
| 429 | ||||
| 430 | colordepth = SiS_GetColorDepth(SiS_Pr, ModeNo, ModeIdIndex); | |||
| 431 | ||||
| 432 | temp = xres / 16; | |||
| 433 | ||||
| 434 | if (infoflag & InterlaceMode) | |||
| 435 | temp <<= 1; | |||
| 436 | ||||
| 437 | temp *= colordepth; | |||
| 438 | ||||
| 439 | if (xres % 16) | |||
| 440 | temp += (colordepth >> 1); | |||
| 441 | ||||
| 442 | return temp; | |||
| 443 | } | |||
| 444 | ||||
| 445 | /*********************************************/ | |||
| 446 | /* SEQ */ | |||
| 447 | /*********************************************/ | |||
| 448 | ||||
| 449 | static void | |||
| 450 | SiS_SetSeqRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex) | |||
| 451 | { | |||
| 452 | unsigned char SRdata; | |||
| 453 | int i; | |||
| 454 | ||||
| 455 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x00, 0x03); | |||
| 456 | ||||
| 457 | SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[0] | 0x20; | |||
| 458 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x01, SRdata); | |||
| 459 | ||||
| 460 | for(i = 2; i <= 4; i++) { | |||
| 461 | SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[i-1]; | |||
| 462 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, i, SRdata); | |||
| 463 | } | |||
| 464 | } | |||
| 465 | ||||
| 466 | /*********************************************/ | |||
| 467 | /* MISC */ | |||
| 468 | /*********************************************/ | |||
| 469 | ||||
| 470 | static void | |||
| 471 | SiS_SetMiscRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex) | |||
| 472 | { | |||
| 473 | unsigned char Miscdata = SiS_Pr->SiS_StandTable[StandTableIndex].MISC; | |||
| 474 | ||||
| 475 | SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c2, Miscdata); | |||
| 476 | } | |||
| 477 | ||||
| 478 | /*********************************************/ | |||
| 479 | /* CRTC */ | |||
| 480 | /*********************************************/ | |||
| 481 | ||||
| 482 | static void | |||
| 483 | SiS_SetCRTCRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex) | |||
| 484 | { | |||
| 485 | unsigned char CRTCdata; | |||
| 486 | unsigned short i; | |||
| 487 | ||||
| 488 | SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3d4, 0x11, 0x7f); | |||
| 489 | ||||
| 490 | for(i = 0; i <= 0x18; i++) { | |||
| 491 | CRTCdata = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[i]; | |||
| 492 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, i, CRTCdata); | |||
| 493 | } | |||
| 494 | } | |||
| 495 | ||||
| 496 | /*********************************************/ | |||
| 497 | /* ATT */ | |||
| 498 | /*********************************************/ | |||
| 499 | ||||
| 500 | static void | |||
| 501 | SiS_SetATTRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex) | |||
| 502 | { | |||
| 503 | unsigned char ARdata; | |||
| 504 | unsigned short i; | |||
| 505 | ||||
| 506 | for(i = 0; i <= 0x13; i++) { | |||
| 507 | ARdata = SiS_Pr->SiS_StandTable[StandTableIndex].ATTR[i]; | |||
| 508 | SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3da); | |||
| 509 | SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c0, i); | |||
| 510 | SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c0, ARdata); | |||
| 511 | } | |||
| 512 | SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3da); | |||
| 513 | SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c0, 0x14); | |||
| 514 | SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c0, 0x00); | |||
| 515 | ||||
| 516 | SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3da); | |||
| 517 | SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c0, 0x20); | |||
| 518 | SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3da); | |||
| 519 | } | |||
| 520 | ||||
| 521 | /*********************************************/ | |||
| 522 | /* GRC */ | |||
| 523 | /*********************************************/ | |||
| 524 | ||||
| 525 | static void | |||
| 526 | SiS_SetGRCRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex) | |||
| 527 | { | |||
| 528 | unsigned char GRdata; | |||
| 529 | unsigned short i; | |||
| 530 | ||||
| 531 | for(i = 0; i <= 0x08; i++) { | |||
| 532 | GRdata = SiS_Pr->SiS_StandTable[StandTableIndex].GRC[i]; | |||
| 533 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3ce, i, GRdata); | |||
| 534 | } | |||
| 535 | ||||
| 536 | if (SiS_Pr->SiS_ModeType > ModeVGA) { | |||
| 537 | /* 256 color disable */ | |||
| 538 | SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3ce, 0x05, 0xBF); | |||
| 539 | } | |||
| 540 | } | |||
| 541 | ||||
| 542 | /*********************************************/ | |||
| 543 | /* CLEAR EXTENDED REGISTERS */ | |||
| 544 | /*********************************************/ | |||
| 545 | ||||
| 546 | static void | |||
| 547 | SiS_ClearExt1Regs(struct SiS_Private *SiS_Pr, unsigned short ModeNo) | |||
| 548 | { | |||
| 549 | int i; | |||
| 550 | ||||
| 551 | for(i = 0x0A; i <= 0x0E; i++) { | |||
| 552 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, i, 0x00); | |||
| 553 | } | |||
| 554 | ||||
| 555 | SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3c4, 0x37, 0xFE); | |||
| 556 | } | |||
| 557 | ||||
| 558 | /*********************************************/ | |||
| 559 | /* Get rate index */ | |||
| 560 | /*********************************************/ | |||
| 561 | ||||
| 562 | static unsigned short | |||
| 563 | SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
| 564 | unsigned short ModeIdIndex) | |||
| 565 | { | |||
| 566 | unsigned short rrti, i, index, temp; | |||
| 567 | ||||
| 568 | if (ModeNo <= 0x13) | |||
| 569 | return 0xFFFF; | |||
| 570 | ||||
| 571 | index = SiS_GetReg(SiS_Pr,SiS_Pr->SiS_P3d4, 0x33) & 0x0F; | |||
| 572 | if (index > 0) index--; | |||
| 573 | ||||
| 574 | rrti = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex; | |||
| 575 | ModeNo = SiS_Pr->SiS_RefIndex[rrti].ModeID; | |||
| 576 | ||||
| 577 | i = 0; | |||
| 578 | do { | |||
| 579 | if (SiS_Pr->SiS_RefIndex[rrti + i].ModeID != ModeNo) | |||
| 580 | break; | |||
| 581 | ||||
| 582 | temp = SiS_Pr->SiS_RefIndex[rrti + i].Ext_InfoFlag & ModeTypeMask; | |||
| 583 | if (temp < SiS_Pr->SiS_ModeType) | |||
| 584 | break; | |||
| 585 | ||||
| 586 | i++; | |||
| 587 | index--; | |||
| 588 | } while(index != 0xFFFF); | |||
| 589 | ||||
| 590 | i--; | |||
| 591 | ||||
| 592 | return (rrti + i); | |||
| 593 | } | |||
| 594 | ||||
| 595 | /*********************************************/ | |||
| 596 | /* SYNC */ | |||
| 597 | /*********************************************/ | |||
| 598 | ||||
| 599 | static void | |||
| 600 | SiS_SetCRT1Sync(struct SiS_Private *SiS_Pr, unsigned short rrti) | |||
| 601 | { | |||
| 602 | unsigned short sync = SiS_Pr->SiS_RefIndex[rrti].Ext_InfoFlag >> 8; | |||
| 603 | sync &= 0xC0; | |||
| 604 | sync |= 0x2f; | |||
| 605 | SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c2, sync); | |||
| 606 | } | |||
| 607 | ||||
| 608 | /*********************************************/ | |||
| 609 | /* CRTC/2 */ | |||
| 610 | /*********************************************/ | |||
| 611 | ||||
| 612 | static void | |||
| 613 | SiS_SetCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
| 614 | unsigned short ModeIdIndex, unsigned short rrti) | |||
| 615 | { | |||
| 616 | unsigned char index; | |||
| 617 | unsigned short temp, i, j, modeflag; | |||
| 618 | ||||
| 619 | SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3d4,0x11,0x7f); | |||
| 620 | ||||
| 621 | modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; | |||
| 622 | ||||
| 623 | index = SiS_Pr->SiS_RefIndex[rrti].Ext_CRT1CRTC; | |||
| 624 | ||||
| 625 | for(i = 0,j = 0; i <= 7; i++, j++) { | |||
| 626 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, j, | |||
| 627 | SiS_Pr->SiS_CRT1Table[index].CR[i]); | |||
| 628 | } | |||
| 629 | for(j = 0x10; i <= 10; i++, j++) { | |||
| 630 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, j, | |||
| 631 | SiS_Pr->S | |||